写这篇文章前,首先要感谢 Simon_fu ,他的两篇关于 root 权限的文章对于个人工做起到了很是大的帮助,这篇文章能够说是对他的文章的一个补充。 Simon_fu 的文章能够参考以下两个网页:android
通常来讲, Android 下的应用程序能够“直接”获得的最大的权限为 system ,可是若是咱们须要在程序中执行某些须要 root 权限的命令,如 ifconfig 等,就须要 root 权限了。按照 Simon 的文章中提到的,应用程序有如下两种办法临时得到 root 权限:函数
1) 实现一个 init 实现一个 Service ,来帮助 Android 应用程序执行 root 权限的命令。url
2) 实现一个虚拟设备,这个设备帮助 Android 应用程序执行 root 权限的命令。spa
第二种办法我这里没有尝试,暂时也不会。这里讲讲我在实现第一种办法的过程和遇到的一些问题。.net
1. 将咱们要执行的命令写成脚本,或者可执行程序。命令行
下面是个人脚本 ifconfig_test.sh :unix
# ! /system/bin/shorm
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 权限。