杭州华育LOGO

学员作品 学员心得技术园地 潮人地 Android(安卓)培训 杭州电脑(计算机)培训 杭州网络营销培训 杭州JAVA培训
返回首页
当前位置: 主页 > 学员天地 > 技术园地 >

如何使Android应用程序获得root权限

时间:2012-03-19 20:50来源:互联网 作者:佚名 点击:
如何使Android应用程序获得root权限 我在博文《Android程序的安全系统》中提到两种让root权限的办法。最近在网上发现很多朋友转载那篇文章,但是对那篇文章中提到的第一种方法怎样实现,不是很明白。本文将会以一个例子实现来演示怎样让一个Androi

    如何使Android应用程序获得root权限

       我在博文《Android程序的安全系统》中提到两种让root权限的办法。较近在网上发现很多朋友转载那篇文章,但是对那篇文章中提到的第一种方法怎样实现,不是很明白。本文将会以一个例子实现来演示怎样让一个Android应用程序获得root权限。

问题
    我遇到的问题是我想在Java应用程序中动态mount一个NFS的系统,但是执行mount命令必须要要root权限才可以。一般情况下,在Android的Java层是不能获得root权限的。

思路
   我在博文《Android程序的安全系统》中提到两种思路:

1、实现一个init实现一个Service,来帮助Android应用程序执行root权限的命令。
2、实现一个虚拟设备,这个设备帮助Android应用程序执行root权限的命令。

   本文将会选择第一种来解决Android应用程序mount NFS文件系统的问题。

Init.rc Service
   在Android系统init.rc中定义很多Service,具体定义格式可以参考《Android Platform Developer’s Guide》中的“Android Init Language”。Init.rc中定义的Service将会被Init进程创建,这样将可以获得root权限。

   现在问题是Android应用程序怎样启动让init进程知道我们想运行那个进程呢?答案是设置系统属性“ctl.start”,把“ctl.start”设置为你要运行的Service,假设为“xxx”,Android系统将会帮你运行“ctl.start”系统属性中指定的Service。那么运行结果init进程将会将会写入命名为“init.svc.+Service名称”的属性中,也就是“init.svc.xxx”属性,应用程序可以参考查阅这个值来确定Service执行的情况。想更深入了解Android property系统可以参考博文《(翻译)Android属性系统》。

Android property权限
    难道Android属性“ctl.start”是所有进程都可以设置的吗?那世界不就乱套了,谁都可以可以执行init.rc中Service了,查看property_service.c中的源码,设置Android系统属性的函数为handle_property_set_fd:
 

 

 

  1. static int check_control_perms(const char *name, int uid, int gid) {
     
  2.      int i;
     
  3.      if (uid == AID_SYSTEM || uid == AID_ROOT)
     
  4.         return 1;
     

  5.  
  6.                 /* Search the ACL */
     
  7.                 for (i = 0; control_perms.service; i++) {
     
  8.                          if (strcmp(control_perms.service, name) == 0) {
     
  9.                                  if ((uid && control_perms.uid == uid) ||
     
  10.                                          (gid && control_perms.gid == gid)) {
     
  11.                                         return 1;
     
  12.                                 }
     
  13.                         }
     
  14.                 }
     
  15.     return 0;
     
  16. }
复制代码
复制代码
我们发现root权限和system权限的应用程序将会授权修改“ctl.”开头的Android系统属性。否则将会检查control_perms全局变量中的定义权限和Service。

    如果想更深入的了解Android Init进程和Android Property的权限控制,请参考《Android Permission》。

实例
    通过上面的介绍我们基本已经有思路了,下面以上面提出的mount nfs文件系统为例说明:

1、首先定义一个执行mount的脚本,我把它位于/system/etc/mount_nfs.sh,定义如下:

 

 

 

 

  1. #!/system/bin/sh
     

  2.  
  3. /system/bin/busybox mount -o rw,nolock -t nfs 192.168.1.6:/nfs_srv /data/mnt
复制代码

复制代码
不要忘了把它加上可执行权限。

2、在init.rc中加入一个Service定义,定义如下:

 

  1. void handle_property_set_fd(int fd){
     
  2. ......
     
  3. switch(msg.cmd) {
     
  4.         case PROP_MSG_SETPROP:
     
  5.         msg.name[PROP_NAME_MAX-1] = 0;
     
  6.         msg.value[PROP_VALUE_MAX-1] = 0;
     

  7.  
  8.         if(memcmp(msg.name,"ctl.",4) == 0) {
     
  9.              if (check_control_perms(msg.value, cr.uid, cr.gid)) {
     
  10.                  handle_control_message((char*) msg.name + 4, (char*) msg.value);
     
  11.             } else {
     
  12.                  ERROR("sys_prop: Unable to %s service ctl [%s] uid: %d pid:%d\n",
     
  13.                          msg.name + 4, msg.value, cr.uid, cr.pid);
     
  14.              }
     
  15.          }
     
  16.     ......
     
  17.     }
     
  18. }
复制代码
 

 

  1. service mount_nfs /system/etc/mount_nfs.sh
     
  2. oneshot
     
  3. disabled
复制代码

3、让自己的应用程序获得system权限,博文《Android程序的安全系统》中提到了怎样获得system权限,请参考,这里就不赘述了。

4、在自己应用程序中设置System系统属性“ctl.start”为“mount_nfs”,这样Android系统将会帮我们运行mount_nfs系统属性了。这里需要强调的是不能够调用System.getProperty,这个函数只是修改JVM中的系统属性。而不能修改Android的系统属性。可以调用android.os.SystemProperties(Android 2.1 Eclair系统可以调用这个API),如果你的Android版本不能调用这个类,只能通过JNI,调用C/C++层的API property_get和property_set函数了。如果想详细了解请参考《(翻译)Android属性系统》。代码如下:
  • SystemProperties.set("ctl.start", "mount_nfs");

    5、较后在自己应用程序中,读取“init.svc.mount_nfs”Android系统Property,检查执行结果。代码如下:

 

  1. while(true){
     
  2.         mount_rt = SystemProperties.get("init.svc.mount_nfs", "");
     
  3.         if(mount_rt != null && mount_rt.equals("stopped")){
     
  4.        return true;
     
  5.         }
     

  6.  
  7.     try{
     
  8.          Thread.sleep(1000);
     
  9.     }catch(Exception ex){
     
  10.          Log.e(TAG, "Exception: " + ex.getMessage());
     
  11.     }
复制代码
init进程维护一个service的队列,所以我们需要轮训来查询service的执行结果。

    通过上面的这些步骤,Android应用程序就能够调用init.rc中定义的Service了。这样你的Android应用程序也就获得了root权限。

总结
   通过上文可以看出,在Android获得root权限还是需要一些前提的,比如:

1、必须是Android系统开发人员,否则你无法修改init.rc等文件。 2、你的应用程序必须要获得system权限。

    这样可以防止root权限被应用程序无限制的使用,较终危及Android系统安全。

 
(责任编辑:杭州华育 ;杭州java培训,网络营销培训,杭州计算机培训,it培训,详询客服报名咨询
分享到:
顶一下
(8)
100%
踩一下
(0)
0%
------分隔线----------------------------
提交报名信息

2018年杭州将加大力度经济转型,吸纳更多的技术人才落户杭州,软件人才需求量更是大幅提升,针对目前杭州IT行业人才需求“井喷”现象,华育软件杭州实训基地与杭州155家IT名企合作,建立人才培养与输送关系,启动“Eduask国家高端IT紧缺人才培养工程”。6月针对杭州地区18-28岁大中专生待业青年发放68个技能实训名额(应届大中专毕业生优先),经短期专业岗前实训后推荐进入企业,起薪4500-8000元,五险一金。

姓名: * 性别:
学历: 电话: *
所在地: *
您目前状况:
留言:
*