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

时间:2022-06-20 15:05:06


Normal
0

7.8 磅
0
2

false
false
false

MicrosoftInternetExplorer4


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

Normal
0

7.8 磅
0
2

false
false
false

MicrosoftInternetExplorer4


#

/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

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

Normal
0

7.8 磅
0
2

false
false
false

MicrosoftInternetExplorer4


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
权限。