Как запустить исполняемый файл на загрузке и продолжать работать? -- root-access поле с участием linux поле с участием scripts поле с участием services поле с участием init.d пол android Связанный проблема

How to run an executable on boot and keep it running?


3
vote

проблема

русский

У меня есть исполняемая сборка из ndk-build программы. Я хочу запустить его на укоретенном устройстве Android. Сколько стоит вероятность того, что Android убьет мой исполняемый файл?

Использование <код> adb shell , я могу выполнить свой исполняемый файл, используя следующие команды:

 <код> adb push executable /sdcard adb shell device:/ $ su device:/ # cd /system device:/system # mount -o rw,remount /system device:/system # mv /sdcard/executable . device:/system # ./executable   

Мое требование - запускать этот исполняемый файл на загрузочном устройстве.

Я пробовал следуя:

  1. Написать <код> ./executable в <код> init.rc .
      .
    • на перезагрузке <код> init.rc сброс на исходное содержимое. Я разобрался, что магистр сделал это.
  2. запись команд в /system/etc/init/bootstat.rc
      .
    • <код> ./executable
    • <код> service custom /system/executable
    • <код> on boot <Код> ./system/dhandler/diag_revealer

Ни одно из вышеперечисленного не работает.

Английский оригинал

I have an executable build from a ndk-build program. I want to run it on a rooted Android device. How much is the possibility that Android will kill my executable?

Using adb shell, I am able to execute my executable using following commands:

adb push executable /sdcard adb shell device:/ $ su device:/ # cd /system device:/system # mount -o rw,remount /system device:/system # mv /sdcard/executable . device:/system # ./executable 

My requirement is to run this executable on device boot.

I have tried following:

  1. Write ./executable in init.rc.
    • On reboot init.rc reset to its original contents. I figured out that Magisk done this.
  2. Write commands in /system/etc/init/bootstat.rc
    • ./executable
    • service custom /system/executable
    • on boot ./system/dhandler/diag_revealer

None of the above thing is working.

              
 
 

Список ответов

6
 
vote
vote
Лучший ответ
 

Сколько стоит вероятность того, что Android убьет мой исполняемый файл?

Привилегированные нативные процессы обычно не убивают Android, за исключением случаев, если они не могут обрабатывать ошибку, возникаю внутри, например, некоторые системные ресурсы, которые недоступны, или разрешение запрещено из-за SELinux и т. Д. Для освобождения памяти, Android убивает только процессы в рамках IE работает под <код> zygote . Для управления ресурсами для собственных процессов Android использует <код> cgroups .

Процессы погибают, когда они получают сигналы от ядра или других программ пользователей (например, с 9988777662 Command) ( 1 , 2 ) . Ядро является фактической операционной системой, не видимой нам, но обрабатывая все, что мы делаем с устройством. Разработчик может запрограммировать свой код, как реагировать на определенный сигнал, если он получен, или полностью игнорировать его ( 3 ) . Кроме sigkill . Что не может быть обработано программой, отсутствие предупреждения от ядра, нет льготного периода, чтобы безопасно выйти, просто прекращается немедленно. Но ядро ​​не возражает против вашего присутствия, если он не будет коротким на оборудованные ресурсы или вы начнете плохо себя вести. Вот почему программирование важно.

Программы могут отправлять друг другу сигналы (включая убийство), которые пересылаются ядром, управляемым UID ( 4 ) . Тем не менее, <Код> init Самый первый процесс в пользовательском пространстве, созданном ядром, является дорогим, ядром никогда не пересылает сигналы DASVICE init . И если это произойдет по какой-то причине, ядро ​​получает панику и перезагрузиться ( 5 ) .

Суммируя вышеперечисленные линии, можно не избежать убийства (AMAP) программно или использовать некоторые Скрипты / a> Как @ упомянул Alecxs . Но если вы хотите убедиться, что ваш процесс будет перезапущен, если будет убит, определить Android <код> init SERVICE.

на перезагрузке <код> init.rc Сброс на его исходное содержимое. Я выяснил, что Magisisk сделал это.

Нет, магистр не сделал этого. Android rootfs - это временная файловая система (не постоянная, как на <код> /system или <код> /data ), который очищается на каждой перезагрузке. Содержимое корневого каталога (<код> cgroups0 ) извлекаются из другого раздела с именем <код> cgroups1 , который содержит <код> cgroups2 и <код> cgroups3 (хотя вещи Изменились с Система As-root ). Таким образом, вы не можете изменить <код> cgroups4 постоянно, если вы не извлеките, измените, перепаковывают и перепроверьте <код> cgroups5 .

Но чтобы определить новую службу init, модификацию <код> cgroups6 не нужен. Android разбирается все <код> cgroups7 файлов из <код> cgroups8 каталоги, расположенные под cgroups9 и <код> kill0 ( 6 ) . Таким образом, вы можете создать свой собственный <код> kill1 файл.


Примечание: для получения реальных корневых привилегий и для решения SELinux, все варианты, приведенные ниже, зависят от магистра. Смотрите Это ответа для деталей.

Сценарий init.d

Вы можете использовать традиционный <код> kill2 -подобной особенностью MAGISK, чтобы начать процесс на загрузке. Создать скрипт <код> kill3 :

 <код> kill4  

* <код> kill5 - это оболочка Pseud-сигнал .
* android <код> kill6 (из <код> kill7 ) - это багги, лучше использовать <код> kill8 апплет.

Поместите исполняемый файл в <Код> kill9 и установка Разрешения:

 <код> init0  

Вы также можете разместить SCR PT под <Код> init1 Но это выполняется немного ранее. Убедитесь, что пути файловых систем (и другие необходимые ресурсы, если таковые имеются) доступны на этом этапе.

Выполнить программу из init

Другой способ - напрямую выполнить двоичный двоичный от init. Создать <код> init2 Файл:

 <код> init3  

Установка Разрешения:

 <код> init4  

И это все! Перезагрузите устройство для изменений в силу.

Однако это однократное исполнение, не будет перезапущено. Также есть некоторые функции сценариев оболочки, недоступные в init5 файлов. Например, вы не можете перенаправить STDOUT / STDERR в файл, это должно быть обработано самой исполняемой программой. Таким образом, мы можем попытаться использовать обоими; Скрипт оболочки и <код> init6 Файл:

init Service

вместо непосредственного выполнения двоичного файла из <код> init7 файла, выполните скрипт оболочки. Создать сценарий <код> init8 :

 <код> init9  

Создать <Код> init0 Сервис:

 <код> init1  

Установленные разрешения на <Код> init2 , <код> init3 и <код> init4 Как указано выше и перезагрузка.

Другие параметры ( 7 ) , например <код> init5 , <код> init6 , <код> init7 необходимы, если вы хотите запустить службу как невиленную Пользователь. Предоставление наименее необходимые привилегии - рекомендуемый подход от точки зрения безопасности. Смотрите Это ответа для более подробной информации о возможностях и SELinux.

<Код> init8 будет продолжать перезапустить обслуживание каждые 5 секунд (по умолчанию), если он будет убит. Вы можете остановить услугу <код> init9 . Заменить <код> init0 с <код> init1 , чтобы начать снова.
Чтобы увидеть, что происходит с сервисом: <Код> init2 .

связано :

    .
  • Как запустить службу Android Init Service с контекстом Superuser Selinux?
  • Как запустить скрипт в фоновом режиме от adb shell?

 

How much is the possibility that Android will kill my executable?

Privileged native processes usually don't get killed by Android except if they can't handle an error occurred inside, such as some system resource not available or permission denied because of SELinux etc. To free up memory, Android only kills processes within its framework i.e. running under zygote. To manage resources for native processes, Android uses cgroups.

Processes are killed when they receive SIGNALS from kernel or other userspace programs (e.g. with kill command) (1, 2). Kernel is the actual operating system, not visible to us but handling everything we do with device. A developer can program his code how to react to a specific signal if received, or completely ignore it (3). Except SIGKILL. Which can't be handled by program, no warning from kernel, no grace period to exit safely, just being terminated immediately. But kernel won't mind your presence unless he gets short on hardware resources or you start misbehaving. That's why programming is important.

Programs can send each other signals (including KILL), which are forwarded by kernel, governed by UID (4). However, init the very first process in userspace started by kernel is the dear one, kernel never forwards dangerous signals to init. And if this happens for some reason, kernel gets panic and reboots (5).

Summarizing above lines, it is possible to avoid being killed (AMAP) programmatically or using some scripting tricks as @alecxs has mentioned. But if you want to make sure that your process should restart if gets killed, define an Android init service.

On reboot init.rc reset to its original contents. I figured out that Magisk done this.

No, Magisk didn't do this. Android's rootfs is a temporary filesystem (not a persistent one like on /system or /data) that gets cleared on every reboot. Contents of root directory (/) are extracted from another partition named boot which contains kernel and ramdisk (though things have changed with system-as-root). So you can't change init.rc permanently unless you extract, modify, repack and reflash boot.img.

But to define a new init service, modifying init.rc isn't necessary. Android parses all .rc files from /etc/init directories located under /system and /vendor (6). So you can create your own .rc file.


NOTE: In order to get real root privileges and to deal with SELinux, all of the options given below depend on Magisk. See this answer for details.

INIT.D SCRIPT

You can use traditional init.d-like feature of Magisk to start a process on boot. Create script /data/adb/service.d/custom.sh:

#!/system/bin/sh  # write log file if executable throws something at stdout/sterr exec >>/data/media/0/executable.log 2>&1  # run script in background to avoid blocking boot chain [ -n "$BG" ] || { BG=Y "$0" & exit; }  # try to ignore signals as much as possible for i in $(seq 64); do trap '' "$i"; done  # execute script whenever exits e.g. when executable gets killed trap "sleep 5; exec $0" EXIT  # avoid multiple instances e.g. if script killed but executable is running pkill -9 -x /system/bin/executable  # execute the binary, should run in foreground, otherwise get in loop echo "$(date): Starting program..." /system/bin/executable  # program is killed, won't reach here if script is killed echo "$(date): Re-executing script..." 

* EXIT is shell's pseudo-signal.
* Android's /system/bin/pkill (from toybox) is buggy, better use busybox applet.

Place the executable under /system/bin and set permissions:

~# chown 0.0 /system/bin/executable /data/adb/service.d/custom.sh ~# chmod 0755 /system/bin/executable /data/adb/service.d/custom.sh 

You can also place script under /data/adb/post-fs-data.d/ but that's executed a bit earlier. Be sure that filesystem paths (and other required resources if any) are available at that stage.

EXECUTE PROGRAM FROM INIT

Another way is to directly execute the binary from init. Create custom.rc file:

#/etc/init/custom.rc  # execute the binary when boot is completed on property:sys.boot_completed=1     exec_background u:r:magisk:s0 -- /system/bin/executable 

Set permissions:

~# chown 0.0 /etc/init/custom.rc ~# chmod 0644 /etc/init/custom.rc ~# chcon u:object_r:system_file:s0 /etc/init/custom.rc 

And that's all! Restart device for changes to take effect.

However it's a one time execution, won't be restarted. Also there are some shell scripting features not available in .rc files. For instance you can't redirect stdout/stderr to a file, this has to be handled by executable program itself. So we can try to make use of both; shell script and .rc file:

INIT SERVICE

Instead of directly executing binary from .rc file, execute a shell script. Create script /system/bin/custom.sh:

#!/system/bin/sh  # write log file if executable throws something at stdout/sterr exec >>/data/media/0/executable.log 2>&1  # execute the binary, should run in foreground, otherwise get in loop echo "$(date): Starting program..." exec /system/bin/executable 

Create init service:

#/etc/init/custom.rc  # define service, use executable here if script not needed service custom /system/bin/custom.sh      # don't start unless explicitly asked to     disabled      # only execute once, don't restart if exited     # don't add if you want to restart service when killed     #oneshot      # run with unrestricted SELinux context to avoid avc denials     # it's required if SELinux is enforcing and service needs access     # to some system resources not allowed by default sepolicy     seclabel u:r:magisk:s0  # start the service when boot is completed on property:sys.boot_completed=1     start custom 

Set permissions on executable, custom.sh and custom.rc as stated above and restart.

Other parameters (7) such as user, group, capabilities are required if you want to run the service as non-privileged user. Granting least required privileges is the recommended approach from security's perspective. See this answer for more details on capabilities and SELinux.

init will keep on restarting service every 5 seconds (by-default) if it gets killed. You can stop the service with setprop ctl.stop custom. Replace stop with start to start again.
To see what happens with service: dmesg | grep init: | tail.

RELATED:

  • How to run an Android init service with superuser SELinux context?
  • How to run a script in background from adb shell?
 
 
 
 

Связанный проблема

3  init.d не выполняется  ( Init d doesnt get executed ) 
Я использую Samsung S2 и пользовательский ROM, внешняя SD-карта установлена ​​на / emmc, но я хочу, чтобы подключить к / mnt / sdcard / external_sd, как я мог...

4  Как создать сценарии запуска, используя папку init.d?  ( How to create start up scripts using the init d folder ) 
в это Ответ на вопрос, который я задал время назад, он сказал, что можно выполнить скрипт каждая загрузка. Я создал файл (без расширения), который содержи...

0  Можно ли запустить бесконечную петлю в Init.D?  ( Is it possible to start an infinite loop within init d ) 
Я хотел бы создать скрипт init.D для управления вентилятором моего одобрения xu3 под на палочком на палочке 5.1.1, цианогенмод 12.1. Я уже сделаю один на Li...

1  init.rc не запускает мой сервис на загрузке завершенного события  ( Init rc doesnt start my service on boot completed event ) 
Я добавил следующий фрагмент до конца <код> /system/core/rootdir/init.rc файла. <код> on property:dev.bootcomplete=1 start bootcomplete_handler servic...

0  Снимите скрипт в init.d  ( Remove the script in init d ) 
Я хочу прошить TweakDrypt на мой укорененный Android 4.4.2 устройства. Но раньше я должен удалить все скрипты в init.d. Я пытался использовать Universal init....

2  Гора в /дата/Local/userinit.sh не работает  ( Mount in data local userinit sh is not working ) 
Я хочу карту / sdcard / dcim to / comaste / sdcard1 / dcim Используя CM 12.1 на I9100 Я написал эти несколько строк в <Код> /data/local/userinit.sh : <код...

1  Automount Ext2 SD-карта на Huawei U8350 (Android 2.2.2)  ( Automount ext2 sd card on huawei u8350 android 2 2 2 ) 
на Huawei U8350 (Android 2.2.2) Скрипты init все, кажется, в корневом разделу, который на самом деле представляет собой RAM-диск (initramfs), поэтому любые из...

2  SELinux предотвращает команду my init.rc exec для выполнения  ( Selinux prevents my init rc exec command to execute ) 
Я добавил <код> exec команды в конце <код> init.rc файла. <код> on property:dev.bootcomplete=1 exec u:r:shell:s0 shell shell -- /system/bin/am start -...

3  Как запустить исполняемый файл на загрузке и продолжать работать?  ( How to run an executable on boot and keep it running ) 
У меня есть исполняемая сборка из ndk-build программы. Я хочу запустить его на укоретенном устройстве Android. Сколько стоит вероятность того, что Android у...

0  На приложении Termux Termux Access Access, где я должен поставить свой собственный сервис Runnit, чтобы начать перезагрузить телефон?  ( On a termux app terminal access where should i put my own runnit service to star ) 
Я написал простую услугу, подобную этой: http://smarden.org/runit/ Runscripts.html # apache2 <код> $ cat start_node_exporter #!/data/data/com.termux/file...