Comment exécuter un exécutable au démarrage et le garder en marche? -- root-access domaine et linux domaine et scripts domaine et services domaine et init.d domain android en relation problème

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



3
vote

problème

français

J'ai une version exécutable à partir d'un programme ndk-build . Je veux l'exécuter sur un appareil Android enraciné. Quelle est la possibilité que Android tue mon exécutable?

Utilisation adb shell , je suis capable d'exécuter mon exécutable en utilisant les commandes suivantes:

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

Mon exigence est d'exécuter cet exécutable sur le démarrage de l'appareil.

J'ai essayé de suivre:

  1. écriture ./executable dans init.rc .
    • sur redémarrage init.rc réinitialiser à son contenu d'origine. J'ai compris que Magisque fait cela.
  2. Commandes d'écriture dans /system/etc/init/bootstat.rc
    • ./executable
    • service custom /system/executable
    • on boot ./system/dhandler/diag_revealer

Aucune de la chose ci-dessus ne fonctionne.

langue Anglaise

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.

              
 
 

Liste de réponses

6
 
vote
vote
Meilleure réponse
 

Quelle est la possibilité que Android tue mon exécutable?

Les processus natifs privilégiés ne sont généralement pas tués par Android, sauf si elles ne peuvent pas gérer une erreur survenue à l'intérieur, telle que certaines ressources système non disponibles ou la permission refusée à cause de SELINUX, etc. pour libérer la mémoire, Android ne tue que des processus. Dans son cadre, c'est-à-dire exécuté sous zygote . Pour gérer les ressources pour les processus natifs, Android utilise cgroups .

Les processus sont tués lorsqu'ils reçoivent des signaux de noyau ou d'autres programmes d'espace d'utilisateur (par exemple avec 9988777662 commande) ( 1 , 2 ) . Le noyau est le système d'exploitation réel, qui ne nous est pas visible mais qui gère tout ce que nous faisons avec le périphérique. Un développeur peut programmer son code comment réagir à un signal spécifique s'il est reçu ou ignorez complètement celui-ci ( 3 ) . Sauf sigkill . Ce qui ne peut pas être traité par programme, aucun avertissement de noyau, pas de période de grâce pour sortir en toute sécurité, juste être terminé immédiatement. Mais le noyau ne vous dérangera pas de votre présence à moins qu'il ne soit pas court sur des ressources matérielles ou vous commencez à se conduire mal. C'est pourquoi la programmation est importante.

Les programmes peuvent envoyer des signaux (y compris la tuerie), qui sont transmis par le noyau, régis par UID ( 4 ) . Toutefois, init Le tout premier processus de l'espace d'utilisateurs a commencé par le noyau est le cher, le noyau n'envoie jamais signaux dangereux à init . Et si cela se produit pour une raison quelconque, le noyau fait de la panique et redémarre ( 5 ) .

Résumation de lignes ci-dessus, il est possible d'éviter d'être tué (amap) de manière programmatique ou d'utilisation de certains astuces de script < / a> @ alecxs a mentionné. Mais si vous voulez vous assurer que votre processus devrait redémarrer s'il est tué, définissez un 9988777665 Service.

sur redémarrage init.rc réinitialiser à son contenu d'origine. J'ai compris que Magisque fait cela.

Non, Magisk n'a pas fait cela. rootfs est un système de fichiers temporaire (pas persistant comme sur /system ou /data ) qui se dégage sur chaque redémarrage. Contenu du répertoire racine ( cgroups0 ) est extrait d'une autre partition nommée cgroups1 qui contient 99887776612 et cgroups3 (bien que les choses ont changé avec System-as-racine ). Donc, vous ne pouvez pas changer de cgroups4 de manière permanente que si vous extrayez, modifiez, reconquérir et reflash cgroups5 .

Mais pour définir un nouveau service init, modifier cgroups6 n'est pas nécessaire. Android analyse tous cgroups7 Fichiers de 99887776618 Répertoires situés sous cgroups9 et kill0 ( 6 ) . Vous pouvez donc créer votre propre fichier 99887776621 .

note: afin d'obtenir de vrais privilèges root et de gérer SELINUX, toutes les options données ci-dessous d sur magisque. Voir Cette réponse pour plus de détails.

script init.d

Vous pouvez utiliser traditionnel 99887776622 -Inter une fonctionnalité de magisque pour démarrer un processus au démarrage. Créer un script kill3 :

kill4

* kill5 est coque pseudo-signal .
*'s init.rc26 (à partir de 99887776627 ) est la buggy, meilleure utilisation 99887776628 applet.

Placez l'exécutable sous kill9 et définissez les autorisations:

init0

Vous pouvez également placer un script sous init1 mais c'est exécuté un peu plus tôt. Assurez-vous que les chemins de système de fichiers (et autres ressources requises, le cas échéant) sont disponibles à ce stade.

Programme d'exécution d'INIT

Une autre solution consiste à exécuter directement le binaire d'INIT. Créer init2 fichier:

init3

Définir les autorisations:

init4

Et c'est tout! Disparez le périphérique de redémarrage des modifications à prendre effet.

Cependant, c'est une exécution d'une fois, ne sera pas redémarré. Il existe également des fonctions de script shell non disponibles dans init5 fichiers. Par exemple, vous ne pouvez pas rediriger stdout / stardr vers un fichier, cela doit être traité par programme exécutable lui-même. Nous pouvons donc essayer de faire usage des deux; shell script et init6 fichier:

Service Init

au lieu d'exécuter directement binaire du fichier 99887776637 , exécutez un script shell. Créer un script init8 :

init9

Créer init0 Service:

init1

Définir des autorisations sur init2 , 99887776643 et init4 comme indiqué ci-dessus et redémarrez.

Autres paramètres ( 7 ) tel que 99887776645 , 99887776646, 99887776647 sont requis si vous souhaitez exécuter le service comme non privilégié utilisateur. Accorder privilèges les moins requis est l'approche recommandée du point de vue de la sécurité. Voir Cette réponse Pour plus de détails sur les capacités et SELINUX.

init8 continuera sur le service de redémarrage toutes les 5 secondes (par défaut) si elle est tuée. Vous pouvez arrêter le service avec init9 . Remplacer init0 avec 99887776651 pour recommencer.
Pour voir ce qui se passe avec le service: init2 .

lié :

  • Comment exécuter un service d'init Android avec SuperUser Selinux context?
  • Comment exécuter un script en arrière-plan à partir de 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?
 
 
 
 

Questions connexes

4  Comment créer des scripts de démarrage à l'aide du dossier Init.D?  ( How to create start up scripts using the init d folder ) 
in Cette répond à une question que j'ai posée il y a quelque temps, il a dit qu'il est possible d'avoir un script exécuté chaque démarrage. J'ai créé un f...

1  Carte SD Automount Ext2 sur Huawei U8350 (Android 2.2.2)  ( Automount ext2 sd card on huawei u8350 android 2 2 2 ) 
sur le Huawei U8350 (Android 2.2.2) Les scripts init semblent tous figurent dans la partition racine - qui est en réalité un disque RAM (InitiRAMFS), de sorte...

0  Sur un accès terminal d'application Termux, où dois-je mettre mon propre service Runnit pour commencer le redémarrage du téléphone?  ( On a termux app terminal access where should i put my own runnit service to star ) 
J'ai écrit un service simple comme celui-ci: http://smarden.org/Runit/ runscripts.html # apache2 $ cat start_node_exporter #!/data/data/com.termux/files...

3  Comment exécuter un exécutable au démarrage et le garder en marche?  ( How to run an executable on boot and keep it running ) 
J'ai une version exécutable à partir d'un programme ndk-build . Je veux l'exécuter sur un appareil Android enraciné. Quelle est la possibilité que Android tu...

2  monter dans /data/local/userinit.sh ne fonctionne pas  ( Mount in data local userinit sh is not working ) 
Je veux mapper / sdcard / dcim sur / stockage / sdcard1 / DCIM Utilisation de cm 12.1 sur un I9100 J'ai écrit ces quelques lignes à /data/local/userinit.sh...

0  Est-il possible de démarrer une boucle infinie dans init.d?  ( Is it possible to start an infinite loop within init d ) 
J'aimerais créer un script init.d pour contrôler le ventilateur de mon Odroid Xu3 sous Lollipop 5.1.1, Cyanogenmod 12.1. Je fais déjà un sur Linux qui fonct...

3  init.d ne se fait pas exécuter  ( Init d doesnt get executed ) 
J'utilise Samsung S2 et une ROM personnalisée, une carte SD externe est montée sur / EMMC, mais je veux qu'il monte sur / mnt / sdcard / external_sd, comment ...

0  Supprimer le script dans init.d  ( Remove the script in init d ) 
Je veux flasher Tweaktyle de mon appareil Android 4.4.2 enraciné. Mais auparavant, je dois supprimer tous les scripts in init.d. J'ai essayé d'utiliser univer...

1  init.rc ne démarre pas mon service lors de l'événement Terminé de démarrage  ( Init rc doesnt start my service on boot completed event ) 
J'ai ajouté l'extrait suivant à la fin de /system/core/rootdir/init.rc fichier. on property:dev.bootcomplete=1 start bootcomplete_handler service bo...

2  SELINUX Empêche ma commande init.rc EXEC d'exécuter  ( Selinux prevents my init rc exec command to execute ) 
J'ai ajouté une commande 9988777660 à la fin de init.rc fichier. on property:dev.bootcomplete=1 exec u:r:shell:s0 shell shell -- /system/bin/am sta...




© 2022 www.demandez.top All Rights Reserved. Questions et réponses Accueil Tous les droits sont réservés