如何在启动时运行可执行文件并将其保持运行? -- root-access 领域 和 linux 领域 和 scripts 领域 和 services 领域 和 init.d 领域 android 相关 的问题

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


3
vote

问题

中文

我有一个来自 ndk-build 程序的可执行构建。我想在rooted 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 重置为其原始内容。我想到了这个Magisk完成了这一点。
  2. 在/ ettc/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只会杀死进程在其框架内,即在 zygote 下运行。要管理本机进程的资源,Android使用 cgroups

当它们接收来自内核或其他用户佩勤程序的信号时杀死进程(例如,使用 kill 命令) 1 , 2 )。内核是实际的操作系统,对我们来说不可见,但处理我们用设备所做的一切。开发人员可以编程他的代码,如果收到,或完全忽略它。除 sigkill 之外。哪些不能通过计划处理,没有内核的警告,没有安全地退出宽限期,立即终止。但是内核不会介意你的存在,除非他在硬件资源短缺或开始行为不端。这就是为什么编程很重要。

程序可以通过uid ( 4 )。但是, init 内核启动的用户空间中的第一个进程是亲爱的,内核永远不会将危险信号转发到 init 。如果出于某种原因发生这种情况,内核会得到恐慌并重新启动( 5 。

总结在上面的行中,可以避免以编程方式或使用一些脚本技巧< / a> @ alecxs 已提到。但是如果您想确保您的进程应重新启动,如果被杀死,则定义Android Abcdefghijklmnabcdefghijklmn5 服务。

在重新启动中 init.rc 重置为其原始内容。我想到了Magisk完成了这一点。

否,magisk没有这样做。 Android的 rootfs 是一个临时文件系统(不是一个持久的文件,而不是 /system /data )在每一个重新启动时清除。根目录的内容( abcdefghijklmn10 )都是从名为 abcdefghijklmn11 的另一个分区中提取,其中包含 cgroups2 cgroups3 (虽然事情已更改 systo root )。因此,您无法永久更改<代码> ABCDefghijklmnaBCDEFGHIJKLMN14 除非您提取,修改,重新包装和刷新<代码> ABCDEFGHIJKLMNABCDEFGHIJKLMN15 。

但要定义一个新的Init服务,修改 cgroups6 不是必需的。 Android解析所有 cgroups7 文件来自 cgroups8 目录位于 abcdefghijklmn19 kill0 ( 6 )。所以你可以创建自己的 kill1 文件。


注意: 为了获得真正的root权限并处理selinux,下面给出的所有选项都依赖于Magisk。查看此答案详细信息。

init.d脚本

您可以使用传统 kill2 - magisk的功能,以启动启动过程。 创建脚本 kill3

  kill4 / code> 

* kill5 是shell的伪信号。
* android的 kill6 (来自 kill7 )是buggy,更好地使用 kill8 applet。

将可执行文件放在 kill9 并设置权限:

  init0  

您还可以在 init1 中放置脚本,但这是一点初步执行。确保在该阶段可用文件系统路径(以及其他需要的资源)。

从init

执行程序

另一种方法是直接从init执行二进制。创建 init2 文件:

  init3  

设置权限:

  init4  

,这就是全部!重新启动设备以进行更改以生效。

但是它是一次执行一次,不会重新启动。此外, init5 文件中还有一些shell脚本功能。例如,您无法将stdout / stderr重定向到文件,这必须由可执行程序本身处理。所以我们可以尝试利用两者; shell脚本和 init6 文件:

init服务

而不是直接从 init7 文件中执行二进制文件,而不是执行shell脚本。创建脚本 init8

  init9  

create init0 服务:

  init1  

设置 init2 init3 init4 ,如上所述并重新启动。

其他参数 7 ) init5 init6 init7,如果要将该服务运行为非特权,则是必需的用户。授予 最不需要的权限 是安全的角度的推荐方法。请参阅此答案有关功能和selinux的更多详细信息。

init8 如果被杀死,每5秒(默认情况下)将继续重新启动服务。您可以使用 init9 停止服务。替换 init0 使用 init1 重新开始。
要查看服务会发生什么: init2

相关

  • 如何使用superuser selinux上下文运行Android Init服务?
  • 如何在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?
 
 
 
 

相关问题

1  如何通过ROM安装恢复持续存在?  ( How to make a recovery persist through rom installations ) 
作为恢复安装是非常常见的 ROM安装,但有可能防止恢复 在这样的过程中被改变? 如果是的话,这样做是否有任何潜在的问题? ...

0  如何在双SIM手机中启用请勿打扰1个SIM?  ( How to enable do not disturb for 1 sim only in a dual sim phone ) 
我有一个rooted onlyplus 2运行lineageos 14最新。 如何为我的个人SIM卡启用请勿打扰功能,而不为我的工作SIM卡启用它?具体而言,如果可能,我希望能够在优先模式下在优先模式下进行个人SIM,这允许主演/最令人欣慰的联系人静止响铃。 我计划很快升级到LineaGeos 15,但如果它是一个先...

0  如何检查是否有人在手机上进行了数据恢复?  ( How to check if somebody had done a data recovery on my phone ) 
所以我最近借给我父亲的手机。他爆发了它的展示,将它带到服务中心进行维修,所有人都不知疲倦。我有点吓坏了,因为只有几个月前,我有各种各样的裸体照片,我的女朋友保存在它的<强硬>内存。即使我在将它们移交到父亲之前删除了它们,我也很确定他们可以使用适当的软件恢复。有没有办法检查这样的尝试是否是? 型号:三星Galaxy...

0  如何扎根三星Galaxy CH @ T B5330?  ( How can i root a samsung galaxy cht b5330 ) 
我可以找到没有工作(但是一个不工作,一个基于非常旧的Android版本)根包(也是CyanogenMod支持的自定义ROM)对于我的Android智能手机(Samsung Galaxy Ch @在B-5330),但我需要它拼命地。我有一般的Java编程和Linux管理技能。我可以自己做诀窍吗?根ROMS作者如何做到这...

0  充电时电源电源,但仅当电池电量大于20%时  ( Power on when charging but only when battery level is greater than 20 ) 
我最近试图将平板电脑适合我的车,我遇到了一个问题醒来了 不使用电源按钮。 我的解决方案是在充电时启动设备,但是 我注意到,当电池电量为0%时,设备靴子然后立即关闭。 我使用这个adb选项来触发此行为: fastboot oem off-mode-charge 0 但是,这使得这款手机在没有检查电池水平...

2  更换/系统/ bin / toolbox。我如何恢复?  ( Replaced system bin toolbox how to i revert that ) 
我将原始/系统/ bin / toolbox"重命名为" toolbox_alt"。 我用一个应该工作的文件替换了文件/系统/ bin / toolbox,但根本不起作用。 我的FileManagers和最终端的昏迷停止了工作,我显然丢失了root访问权限。 我有一个三星Galaxy Note 3(N9005)(国际...

0  build.prop修改了。但没有更新系统(例如,在设置中的平板电脑)  ( Build prop modifies okay but not updates in system e g about tablet in settin ) 
我在VirtualBox上运行Android-x86 4.4。一切都很好。 但是,当我用其他制造商或模型修改build.prop(使用es文件资源管理器或buildprop编辑器)并保存它。重新启动后任何发生。关于平板电脑存储旧信息。 似乎是Android缓存此信息某个信息。 任何想法?如何强制android从b...

2  卡在启动动画上  ( Stuck on boot animation ) 
最近我在智能手机上安装了Miui v5 rom。 当我重新启动我的智能手机时,它卡在MI Boot动画徽标上。 问题是什么? 请帮帮我。 ...

1  root - 如何删除其中一个超级用户应用程序?  ( Root how to remove one of the superuser app ) 
我一个月前我扎根了我的手机,昨天下载了超级女士应用程序。 但是,当我使用app supersu时,它没有运行,它表示我需要更新文件。我无法更新它。 我该怎么办?如何删除超级用户? ...

9  访问logcat是否需要root?  ( Does access to logcat need root ) 
我的设备已经植根了,这就是我要问的原因。 您是否需要root来监视手机上的logcat流?如果我从手机上的终端内运行logcat命令,那会工作吗? ...

0  无法建立与服务器Google Play的可靠连接?  ( Cant establish a reliable connection to the server google play ) 
好的,所以我有三星galaxy s3我一周前扎根它,它的工作完美无瑕,后来我打开了Google Play它说没有连接。我尝试了所有的方法,如设置日期和时间清洁数据和缓存,但没有什么orked最后一个选择我剩下的是出厂重置我做到了,但在重新启动它时没有任何工作,当我试图登录它时,我试图在提示无法建立一个可靠的连接时。现...

0  我可以复制分区图像,修改,然后将其恢复到Android手机?  ( Can i copy a partition image modify and then restore it back to android phone ) 
我已经开始让我的脏手进入自定义的Android ROM。我有一个没有特定的TWRP恢复的rooted Android设备。我有一个问题是,可以从Android手机,下一步,修改它,并最终使用Linux PC将其恢复到Android手机中的分区图像?谢谢所有人! ...

1  HTC上的Xposed Installer One M8  ( Xposed installer on htc one m8 ) 
我扎根了我的htc一个m8运行android 4.4.3(使用此方法)。这个过程变得很好,我没有任何打嗝。我扎根手机的主要原因之一是我想利用 appops ,在这场前面非常不成功。 我已经安装了 xposed framework安装程序(这是正确版本为Android 4.4.3),但是当我加载应用程序时,我遇到错误:...

0  根据电池状态自动关闭Android手机的开关  ( Auto turn off switch for android phone according to battery status ) 
根据电池的Barfing状态寻找具有移动和自动关闭移动充电器的电动电源的任何开关。在一夜之间充电会很大的帮助。如果在完全充电后遇到警报,甚至更好,就像我可以在烹饪时收取手机,而不必担心在完全充电后关闭。 ...

1  如何在rooted android设备上使用亮粉?  ( How to use glase on a rooted android device ) 
如何在设备上使用Magisk rooted的设备上使用Tap和Glase (以前是 seqr )来使用Tap和Pay ...




© 2021 it.wenda123.org All Rights Reserved. 问答之家 版权所有


Licensed under cc by-sa 3.0 with attribution required.