怎样使Android应用程序获得root权限

       写这篇文章前,首先要感谢 Simon_fu ,他的两篇关于 root 权限的文章对于我的工作起到了很大的帮助,这篇文章能够说是对他的文章的一个补充。 Simon_fu 的文章能够參考例如以下两个网页:

Android程序的安全系统

Android应用程序获得 root权限

 

       一般来说, Android 下的应用程序能够“直接”得到的最大的权限为 system ,可是假设我们须要在程序中运行某些须要 root 权限的命令,如 ifconfig 等,就须要 root 权限了。依照 Simon 的文章中提到的,应用程序有下面两种办法暂时获得 root 权限:

1)        实现一个 init 实现一个 Service ,来帮助 Android 应用程序运行 root 权限的命令。

2)        实现一个虚拟设备,这个设备帮助 Android 应用程序运行 root 权限的命令。

 

另外一种办法我这里没有尝试,临时也不会。这里讲讲我在实现第一种办法的过程和遇到的一些问题。

 

1.       将我们要运行的命令写成脚本,或者可运行程序。

以下是我的脚本 ifconfig_test.sh

# /system/bin/sh

ifconfig

       注意: 脚本的第一行必须为 # /system/bin/sh ,否则无法运行,通过 dmesg 能够查看到信息内容为 cannot execve ./ifconfig_test.sh: Exec format error

 

也能够採用 C/C++ 编写须要运行的命令或者程序,并在编译 image 的时候编译成可运行程序。

 

2.       init.rc 中注冊 service

Android 中的 service 须要在 init.rc 中注冊, Init.rc 中定义的 Service 将会被 init 进程创建,这样将能够获得 root 权限。当得到对应的通知(通过属性设置)后, init 进程会启动该 service

本文中注冊的内容例如以下:

service ifconfig_test /system/etc/ifconfig_test.sh

oneshot

disabled

       当中, oneshot 表示程序退出后不再又一次启动, disabled 表示不在系统启动时启动。

 

注意: 这里 service name 不能超过 16 个字符。我之前的 service name 因为定义的比較长, 18 个字符,设置属性通知 service 启动后查看 dmesg 能够看到提示: init: no such service 。查看 /system/core/init/parser.c 的源码,在 parse_service->valid_name 函数中能够看到例如以下内容: if (strlen(name) > 16) { return 0; } ,证明 service 的名字的确不能超过 16 个字符。

 

3.       Android 应用程序提升为 system 权限

既然应用程序能够通过启动 service 获得 root 权限,那么岂不是非常不安全。 Android 考虑到了这点,规定仅仅有 system 权限的应用程序才干设置属性,通知 service 启动。关于提升 system 权限的文章网上已有非常多,这里就不再细说,能够參考例如以下两篇文章:

http://blog.csdn.net/liujian885/archive/2010/03/22/5404834.aspx

http://labs.chinamobile.com/mblog/532767_73183

 

4.       在应用程序中加入属性设置代码

前面已经提到,对于 Android 来说,应用程序通知 init 启动 service 是通过设置系统属性来完毕的,详细为设置 System 系统属性 “ctl.start” “ifconfig_test” ,这样 Android 系统将会帮我们执行 ifconfig_test 这个 service 了。

对该系统属性的设置有三种方法,分别相应三种不同的应用程序:  

1)  Java 代码

  Android 在 Java 库中提供 System.getProperty 和 System.setProperty 方法, Java 程序能够通过他们来设置和获得属性。代码例如以下:

SystemProperties.set("ctl.start", "ifconfig_test");

上面的代码是通知 Android 运行 ifconfig_test service ,假设须要查询当前 service 运行的状态,如是否运行完成,能够通过例如以下代码查询:

ret = SystemProperties.get("init.svc. ifconfig_test ", "");

if(ret != null && ret.equals("stopped"))

  {

      return true;

  }

        2)  JNI 代码

当编写 NDK 的程序时,能够使用 property_get property_set 这两个 API 来获得和设置属性。使用这两个 API 必需要包括头文件 cutils/properties.h 和链接 libcutil 库。

 

3)  Shell 脚本

Android 提供了命令行 setprop getprop 来设置和获取属性,他们能够在脚本中被使用。

 

因为我的程序是在 JNI 中调用脚本,脚本中又运行 ifconfig ,因此我将设置属性的部分放在了脚本中完毕,代码例如以下:

setprop ctl.start ifconfig_test

 

#wait for the service until it stops

ret=1

while [ $ret -ne 0 ]

do

       getprop | grep "$ENABLE_MAPPER_SRV" | grep stopped

       ret=$?

done

       通过上面 4 个步骤, Android 应用程序就获得了 root 权限,更详细的说,是在运行我们须要运行的命令时暂时获得了 root 权限。

 

原文地址:https://www.cnblogs.com/mfrbuaa/p/4359468.html