口才与演讲软件:[转]Android程序的安全系统--以root权限进行操作
来源:百度文库 编辑:中财网 时间:2024/04/29 15:06:26
Android程序的安全系统
- 发布于: 2010 六月 30
- 目录: 嵌入式, 技术
- 评论: 19 条评论
最近在移植Android过程中遇到了Android程序(apk)权限的问题。最近也对这方面进行了一些了解,在此和大家分享。
Android框架是基于Linux内核构建,所以Android安全系统也是基于Linux的安全架构建立的。在Linux安全系统中,用户和组起着重要的作用,Linux中所有的资源给不同的用户和用户组设置了不同的访问属性。如果你对Linux下面用户和组的概念不熟悉,请先补习一下Linux基础知识。
在Android系统中,系统为每一个应用程序(apk)创建了一个用户和组。这个用户和组都是受限用户,不能访问系统的数据,只能访问自己的文件和目录,当然它也不能访问其他应用程序的数据。这样设计可以尽可能地保护应用程序的私有数据,增强系统的安全性和健壮性。
但是有一些应用程序是需要访问一些系统资源的。比如Setting程序,他就需要访问wiffi,在系统中创建删除文件等等操作。怎样做到这一点儿呢?Android通过一定途径可以获得system权限。获得system用户权限,需要以下步骤:
1. 在应用程序的AndroidManifest.xml中的manifest节点中加入android:sharedUserId="android.uid.system"这个属性。
2. 修改Android.mk文件,加入LOCAL_CERTIFICATE := platform这一行
3. 使用mm命令来编译,生成的apk就有修改系统时间的权限了。
一般情况下system用户权限就已经够用了,system用户可以在系统中创建和删除文件,访问设备等等。但是有些情况下system权限还是不够的。比如:设置网卡IP地址,ifconfig命令是需要root权限的。我可以很肯定的说,在Android下面应用程序是没有可能拿到root权限的。但是如果我的应用程序需要root权限怎么办呢?只能想办法绕般过去。就以我的问题为例,设置网卡IP地址,root权限下面命令为:
ifconfig eth0 192.168.1.188
在普通用户或者system用户权限下面这条命令是不起作用的,但是不会返回失败和异常,这个我个人认为是Android的bug。那么怎样实现这个功能呢?我想出了两个办法。
1、系统启动的时候init进程创建一个后台进程,该进程处于root用户权限下面。用来监听系统中应用程序的请求(可以用socket实现),并代其完成。这样应用程序就可以执行root用户权限的任务了。
2、实现一个虚拟的设备,该设备的功能就是在内核态帮应用程序执行相应的命令。Linux内核态没有权限的问题了。肯定可以执行成功。
我解决设置网卡IP地址问题时,选择是后者。相对来说设计比较简单。
如果你到网上去搜一下,你会发现很多文章说怎样让Android应用程序获得root权限。如果你不想浪费时间就不要相信他们,因为那些途径是根本不可能获得root权限的。
我的后续博文《Android应用程序获得root权限》讲解让应用程序(APK)通过第一种方法获得root权限的方法,请关注。
标签:android, application, porting
你可以通过RSS 2.0 来跟踪本文的所有评论。 你可以对本文发表评论,或者对本文进行评分,或者从你的网站 引用 本文。
相关文章
COMMENTS
19 条评论
2010-10-25 14:14:51
请教博主,“实现一个虚拟的设备,该设备的功能就是在内核态帮应用程序执行相应的命令。Linux内核态没有权限的问题了。肯定可以执行成功。“这个怎么做呢,能否给个例子。比如我想在APK中执行一个df命令,取得一些硬盘相关的数据,该怎么做呢,谢谢!
[回复]
Simon_fu 回复:
十月 25th, 2010 at 15:11不好意思,代码我那不出来~!不能给你例子。
但是在kernal中实现一个设备驱动,这个设备接受字符串命令,然后帮你调用上层命令,应该是一个比较easy的问题阿~!
如果你是作应用程序的开发人员,你需要驱动开发人员帮忙实现这个设备。[回复]
请教博主 回复:
十月 25th, 2010 at 15:14谢谢^_^
[回复]
匿名 回复:
十二月 23rd, 2010 at 17:041、系统启动的时候init进程创建一个后台进程,该进程处于root用户权限下面。用来监听系统中应用程序的请求(可以用socket实现),并代其完成。这样应用程序就可以执行root用户权限的任务了。
请教博主:能做个例子吗?我无从下手[回复]
Simon_fu 回复:
十二月 24th, 2010 at 14:47呵呵~!
这个小程序我就不提供了,你可以在init.rc中启动这个进程。
这个后台进程就是root权限的。[回复]
2010-12-30 21:53:21
2、实现一个虚拟的设备,该设备的功能就是在内核态帮应用程序执行相应的命令。Linux内核态没有权限的问题了。肯定可以执行成功。
》》楼主的这个解决方案我有功过,但前提是还是需要root权限与系统内核支持动态加载。现在我有个问题想请教一下楼主,我想获取系统的设备文件,如cpu的信息,那么我们只需要读取/proc/stat 而想获取屏幕截图的话就要读取/dev/graphics/fb0, 现在我不想通过Native去做,那么我是想在java中直接读取该硬件信息。发现/proc/stat是可以直接读出来的,而/dev/graphics/fb0不行。后来发现是权限问题,
/proc/sta r–r–r–
/dev/graphics/fb0 rw-rw—-
那么我要读取/dev/graphics/fb0只能修改其权限了。
模拟器上自然没有问题,但是真机上在没有root权限的情况下该怎么做呢,希望楼主赐教。
以下是写在activity的demo.
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(“/dev/graphics/fb0″)), 1000);
String load = reader.readLine();
System.out.println(load);1. 在应用程序的AndroidManifest.xml中的manifest节点中加入android:sharedUserId=”android.uid.system”这个属性。
2. 修改Android.mk文件,加入LOCAL_CERTIFICATE := platform这一行
3. 使用mm命令来编译,生成的apk就有修改系统时间的权限了。
》》1.我懂,2,3是什么意思啊?2.Android.mk 用jni的时候才会用到啊,普通的apk是用不到。3,mm编译是什么啊?一下子问了这么多问题,楼主见笑了。。
[回复]
Simon_fu 回复:
十二月 31st, 2010 at 09:171、我说的实现一个虚拟设备确实是需要动态加载的,在开机的时候,直接插入到内核中就可以了。
2、如果你在Java中通过JNI调用的Native来操作设备也不可能获得root权限的,Native的权限和你的Java APK的权限一样,还是不能操作fb0。需要操作fb0,要么是所有者或者所有组,要么root。你查看一下fb0所有者是不是system,如果是,可以让APK获得system权限,这样就可以访问fb0了。如果不是,你只能通过开机的时候,init初始化脚本中,修改fb0的所有者或者属性了。这样可以确保你的fb0可以被访问了。所有的前提都是你要能够修改系统中的init脚本。
3、关于LOCAL_CERTIFICATE的问题,你可以参考一下:http://blog.csdn.net/liujian885/archive/2010/03/22/5404834.aspx
4、你执行一下:. build/envsetup.sh这个脚本之后,Android将会为你准备好一些工具,比如:mm、mmm等等,你可以通过help查看。具体请参考:http://mmmyddd.freeshell.net/wiki/android/build.html 的“2.2 模块编译“。
4、你说的JNI的时候采用到Android.mk是因为你用Eclipse开发APK。如果你在Android SDK源码开发APK,就必须要写Android.mk了。[回复]
fanfq 回复:
十二月 31st, 2010 at 10:19今天一上班就查看楼主是否回复,感谢楼主的及时回复,问题解释的也很清楚,在此小弟表示感谢。我也会尝试用你的解决方案来处理我现在所遇到的问题。
[回复]
2010-12-30 22:03:59
问题补充,在模拟器中本来就有root权限的,为什么apk还是得不到root权限呢?
[回复]
Simon_fu 回复:
十二月 31st, 2010 at 09:19Android框架定义成这样的,你在生成APK的时候已经告诉Android框架你的权限是什么了,人家会根据你的声明来给你相应的权限。获得system权限方法,就是向Android声明你的权限。
[回复]
fanfq 回复:
十二月 31st, 2010 at 10:21感谢博主的及时回复,祝博主天天开心,呵呵。
[回复]
2011-05-08 13:42:29
博主,你好,我想问一下你说的第一种方法,底层socket应该写在源码的什么地方。我只写底层socket和应用层socket能否通信,谢谢。
[回复]
Simon_fu 回复:
五月 8th, 2011 at 16:56当然可以了啊!你service监听本机的某个端口。应用层客户端连接本机(127.0.0.1)这个端口,即可通讯!
这条路我已经走过了!只需要把service加到init.rc中,后台运行就可以了。[回复]
2011-05-08 17:16:40
哦,太谢谢博主了。我也是想将service加入到init.rc中,但我却不知道将这个socket(services)代码写到什么地方,不知道能否指点,谢谢博主啊。
[回复]
Simon_fu 回复:
五月 9th, 2011 at 15:02这个不是问题阿!随便找个地方(根据你的项目要求),写一个Android.mk文件,编译到项目中去就行了啊!你可以参考init程序的Android.mk文件来写。
[回复]
2011-05-27 18:50:25
你好,我通过上层java调用ifconfig eth0 192.168.1.188,即通过jni调用c的system,便是还是不行,如果上层要设置ip的话,那么要怎么处理?
[回复]
2011-07-20 17:58:37
Hello, Simon
按照你的方法(获得system用户权限三个步骤),编译生成的apk不能安装,提示如下:
07-20 14:54:14.327: ERROR/PackageManager(86): Package org.android.simulateinput has no signatures that match those in shared user android.uid.system; ignoring!
请问这个是什么原因?
我编译的环境是android2.1版本下编译的
机器是:没有root过的moto手机,
固件版本 2.1-update1 by kiss771925[回复]
Simon_fu 回复:
九月 14th, 2011 at 14:03system权限的apk不能用adb install来安装的,需要用adb push到相应的目录下,然后重启。
[回复]
2011-09-16 16:34:19
1. 在应用程序的AndroidManifest.xml中的manifest节点中加入android:sharedUserId=”android.uid.system”这个属性。
2. 修改Android.mk文件,加入LOCAL_CERTIFICATE := platform这一行
3. 使用mm命令来编译,生成的apk就有修改系统时间的权限了。
请教下博主,如果我自己写的程序想访问并修改setting中的secure表里面的设置,其实就似乎setting这个程序所访问的内容,采用以上三个步骤就可以实现吗? 最近也是因为权限的问题很头大。谢谢解惑了[回复]