写这篇文章前,首先要感谢 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 权限。

更多相关文章

  1. 解开Android应用程序组件Activity的"singleTask"之谜(1)
  2. Android 系统权限之SuperSU 模拟器root
  3. Android中View自定义XML属性详解以及R.attr与R.styleable的区别
  4. Android EditText inputType与numeric属性设置以及输入是只显示
  5. Android属性动画ValueAnimator源码简单分析
  6. android mainfest 属性详解

随机推荐

  1. activity的xml详解
  2. Android Webview 和Javascript交互,实现An
  3. Android插件配置-Android Extension介绍
  4. android 重力感应初步认识
  5. Android调用输入法软键盘,返回输入的内容
  6. android中使用afinal一行代码显示网络图
  7. Android文件系统保护——dmverity
  8. Camera Flash的获得权限
  9. 2.5.3 使用alertDialog创建自定义对话框
  10. Android 已发行多年,移动 App 已经趋近饱