在博文《Android程序的安全系统》中提到两种让root权限的办法。本文将会以一个例子实现来演示怎样让一个Android应用程序获得root权限。
问题
现在遇到的问题是想在Java应用程序中动态mount一个NFS的系统,但是执行mount命令必须要要root权限才可以。一般情况下,在Android的Java层是不能获得root权限的。
思路
在博文《Android程序的安全系统》中提到两种思路:
1、实现一个init实现一个Service,来帮助Android应用程序执行root权限的命令。
2、实现一个虚拟设备,这个设备帮助Android应用程序执行root权限的命令。
本文将会选择第一种来解决Android应用程序mount NFS文件系统的问题。
Init.rc Service
在Android系统init.rc中定义很多Service,具体定义格式可以参考《Android Platform Developer’s Guide》中的“Android Init Language”。Init.rc中定义的Service将会被Init进程创建,这样将可以获得root权限。
现在问题是Android应用程序怎样启动让init进程知道我们想运行那个进程呢?答案是设置系统属性“ctl.start”,把 “ctl.start”设置为你要运行的Service,假设为“xxx”,Android系统将会帮你运行“ctl.start”系统属性中指定的 Service。那么运行结果init进程将会将会写入命名为“init.svc.+Service名称”的属性中,也就是“init.svc.xxx” 属性,应用程序可以参考查阅这个值来确定Service执行的情况。想更深入了解Android property系统可以参考博文《(翻译)Android属性系统》。
Android property权限
难道Android属性“ctl.start”是所有进程都可以设置的吗?那世界不就乱套了,谁都可以可以执行init.rc中Service了,查看 property_service.c中的源码,设置Android系统属性的函数为handle_property_set_fd:
1: void handle_property_set_fd(int fd)
2: {
3: ......
4: switch(msg.cmd) {
5: case PROP_MSG_SETPROP:
6: msg.name[PROP_NAME_MAX-1] = 0;
7: msg.value[PROP_VALUE_MAX-1] = 0;
8:
9: if(memcmp(msg.name,"ctl.",4) == 0) {
10: if (check_control_perms(msg.value, cr.uid, cr.gid)) {
11: handle_control_message((char*) msg.name + 4, (char*) msg.value);
12: } else {
13: ERROR("sys_prop: Unable to %s service ctl [%s] uid: %d pid:%d\n",
14: msg.name + 4, msg.value, cr.uid, cr.pid);
15: }
16: }
17: ......
18: }
19: }
从源码中我们发现如果设置“ctl.”开头的Android系统property,将会调用check_control_perms函数来检查调用者的权限,其定义如下:
1: static int check_control_perms(const char *name, int uid, int gid) {
2: int i;
3: if (uid == AID_SYSTEM || uid == AID_ROOT)
4: return 1;
5:
6: /* Search the ACL */
7: for (i = 0; control_perms[i].service; i++) {
8: if (strcmp(control_perms[i].service, name) == 0) {
9: if ((uid && control_perms[i].uid == uid) ||
10: (gid && control_perms[i].gid == gid)) {
11: return 1;
12: }
13: }
14: }
15: return 0;
16: }
我们发现root权限和system权限的应用程序将会授权修改“ctl.”开头的Android系统属性。否则将会检查control_perms全局变量中的定义权限和Service。
如果想更深入的了解Android Init进程和Android Property的权限控制,请参考《Android Permission》。
实例
通过上面的介绍我们基本已经有思路了,下面以上面提出的mount nfs文件系统为例说明:
1、首先定义一个执行mount的脚本,我把它位于/system/etc/mount_nfs.sh,定义如下:
1: #!/system/bin/sh
2:
3: /system/bin/busybox mount -o rw,nolock -t nfs 192.168.1.6:/nfs_srv /data/mnt
不要忘了把它加上可执行权限。
2、在init.rc中加入一个Service定义,定义如下:
1: service mount_nfs /system/etc/mount_nfs.sh
2: oneshot
3: disabled
3、让自己的应用程序获得system权限,博文《Android程序的安全系统》中提到了怎样获得system权限,请参考,这里就不赘述了。
4、在自己应用程序中设置System系统属性“ctl.start”为“mount_nfs”,这样Android系统将会帮我们运行mount_nfs系统属性了。这里需要强调的是不能够调用System.getProperty, 这个函数只是修改JVM中的系统属性。而不能修改Android的系统属性。可以调用 android.os.SystemProperties(Android 2.1 Eclair系统可以调用这个API),如果你的Android版本不能调用这个类,只能通过JNI,调用C/C++层的API property_get和property_set函数了。如果想详细了解请参考《(翻译)Android属性系统》。代码如下:
1: SystemProperties.set("ctl.start", "mount_nfs");
5、最后在自己应用程序中,读取“init.svc.mount_nfs”Android系统Property,检查执行结果。代码如下:
1: while(true)
2: {
3: mount_rt = SystemProperties.get("init.svc.mount_nfs", "");
4: if(mount_rt != null && mount_rt.equals("stopped"))
5: {
6: return true;
7: }
8:
9: try
10: {
11: Thread.sleep(1000);
12: }catch(Exception ex){
13: Log.e(TAG, "Exception: " + ex.getMessage());
14: }
15: }
init进程维护一个service的队列,所以我们需要轮训来查询service的执行结果。
通过上面的这些步骤,Android应用程序就能够调用init.rc中定义的Service了。这样你的Android应用程序也就获得了root权限。
总结
通过上文可以看出,在Android获得root权限还是需要一些前提的,比如:
1、必须是Android系统开发人员,否则你无法修改init.rc等文件。 2、你的应用程序必须要获得system权限。
这样可以防止root权限被应用程序无限制的使用,最终危及Android系统安全。
分享到:
相关推荐
修改源码让APP获取root权限可以执行su命令的git diff记录
- **如何检测设备是否已被root**:可以通过检查某些root标志文件(如`/system/app/Superuser.apk`)是否存在来判断设备是否已获取root权限。 - **root权限的风险**:虽然root权限可以带来更多的自由度和功能,但同时...
Android APK 获取 Root 权限方法总结 Android APK 获取 Root 权限是一个复杂的技术难题,许多开发者和用户都遇到过这个问题。那么,如何使 Android APK 获取 Root 权限呢?今天,我们将总结一些常见的方法来获取 ...
主要是针对P版开发adb root和app root权限,资源基于MTK方案。
全志H3-android app获取系统root权限集成说明,亲测可用,经测试在H3/H6/Amlogic S905D/S905X3平台也可以,附带一个测试demo
Android系统默认是以安全为优先,不允许应用无限制地执行shell命令,但通过获取Root权限,我们可以实现这个目标。本文将详细讲解如何在Android中为APP授权并执行Shell命令。 首先,我们需要理解Android权限系统。在...
标题"android应用获得执行root权限动作__socket_service"表明我们要讨论如何在Android应用中通过Socket服务来实现root权限的获取。这种方式通常涉及到创建一个在系统层面运行的服务,该服务具有root权限,并通过...
1. **安全风险**:获取ROOT权限会使手机更容易受到恶意软件的攻击,因为黑客可以利用ROOT权限获取敏感信息。 2. **保修问题**:大多数厂商和运营商不支持ROOT设备,一旦设备出现问题,可能失去官方保修。 3. **...
Android应用源码获取root权限静默安装是一个获取root权限后,不弹出系统安装界面,直接进行安装的的源码。代码只有一个MainActivity,看起来相对比较容易,代码中重要部分都已加入详细的注释,方便大家阅读。不过...
总结一下,这个压缩包提供的是关于Android设备root权限获取的开发资源,特别是与Superuser应用相关的源代码。开发者可以通过这个资源来学习如何在Android应用中集成root功能,理解root权限的管理和控制机制,甚至...
这个"android root 权限测试app"可能是为了帮助开发者或者高级用户检测设备是否已经获取root权限,并可能包含了一些测试功能来验证权限的有效性。 首先,我们来看"resource apk"。在Android应用开发中,资源APK...
然而,这种严格的权限管理有时会阻碍开发者或用户运行需要超级用户权限(root权限)的应用程序。本文将详细介绍在全志R311平台上,针对Android 8.1系统如何使APP能够获取到`su`权限。 首先,了解SELinux的基本概念...
Root权限允许用户获取Android系统的最高权限,可以修改系统文件和设置,因此可以实现更深层次的静默更新。然而,这种方式存在风险,因为Root权限可能导致系统不稳定,甚至让设备更容易受到恶意软件的攻击。 为了在...
本文将详细介绍如何为Android手机获取root权限以及如何实现关机和重启功能。 首先,获取root权限是一个复杂的过程,涉及到对Android系统的内核层进行修改。通常,这需要使用专门的工具或服务,如SuperSU、Magisk等...
本文将深入探讨如何实现Android OTG USB与串口通信的示例,特别是如何在不获取root权限的情况下进行操作。我们将讨论关键概念、步骤以及所需的组件。 首先,了解Android OTG USB技术。OTG是一种使Android设备能够...
cp /mnt/sda/sda1/system/app/kinguser.apk /system/app cp /mnt/sda/sda1/system/etc/install-recovery.sh /system/etc cp /mnt/sda/sda1/system/xbin/ksud /system/xbin cp /mnt/sda/sda1/system/xbin/ku.sud /...
ROOT权限是指在Android设备上获得最高管理员权限的能力。通常情况下,Android系统对用户和应用程序做了严格的限制,不允许它们访问系统的关键部分或执行可能损害系统的操作。然而,通过ROOT设备,用户可以获得这些...
在Android系统中,修改系统文件访问权限涉及到对操作系统底层的深度理解,这通常需要root权限。以下是关于这个主题的详细知识点: 1. **init.rc**:这是Android系统启动时执行的第一个脚本,位于系统的system/core/...