我在博文《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: void handle_property_set_fd(int fd)
   2: {
   3:     ......
   4:     switch(msg.cmd) {
   5:     case PROP_MSG_SETPROP:
   6:         msg.name[PROP_NAME_MAX-1] = 0;
   7:         msg.value[PROP_VALUE_MAX-1] = 0;
   8:  
   9:         if(memcmp(msg.name,"ctl.",4) == 0) {
  10:             if (check_control_perms(msg.value, cr.uid, cr.gid)) {
  11:                 handle_control_message((char*) msg.name + 4, (char*) msg.value);
  12:             } else {
  13:                 ERROR("sys_prop: Unable to %s service ctl [%s] uid: %d pid:%d\n",
  14:                         msg.name + 4, msg.value, cr.uid, cr.pid);
  15:             }
  16:         }
  17:         ......
  18:     }
  19: }

从源码中我们发现如果设置“ctl.”开头的Android系统property,将会调用check_control_perms函数来检查调用者的权限,其定义如下:

   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[i].service; i++) {
   8:         if (strcmp(control_perms[i].service, name) == 0) {
   9:             if ((uid && control_perms[i].uid == uid) ||
  10:                 (gid && control_perms[i].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: 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属性系统》。代码如下:

   1: SystemProperties.set("ctl.start", "mount_nfs");

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

   1: while(true)
   2: {
   3:     mount_rt = SystemProperties.get("init.svc.mount_nfs", "");
   4:     if(mount_rt != null && mount_rt.equals("stopped"))
   5:     {
   6:         return true;
   7:     }
   8:     
   9:     try
  10:     {
  11:         Thread.sleep(1000);
  12:     }catch(Exception ex){
  13:         Log.e(TAG, "Exception: " + ex.getMessage());
  14:     }
  15: }

init进程维护一个service的队列,所以我们需要轮训来查询service的执行结果。

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

总结

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

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

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

希望本文对你能有所帮助,如果有错误之处敬请指正。

原文

转载于:https://www.cnblogs.com/xiaoxiaoboke/archive/2012/02/13/2349711.html

Android应用程序获得root权限相关推荐

  1. android应用程序永久获取root权限方法,怎么使Android应用程序获得root权限

    一般来说, Android 下的应用程序可以逗直接地得到的最大的权限为 system ,但是如果我们需要在程序中执行某些需要 root 权限的命令,如 ifconfig 等,就需要 root 权限了. ...

  2. Android应用程序获得root权限 基于NVidia平台Android应用修改cpu频率

    问题和目标       有时候希望在java应用程序中来使用root权限,如修改/system权限,亦或者如题. 思路和原理       这里介绍2种我已经实现的方法,但是建议使用第2种,因为第2种适 ...

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

    写这篇文章前,首先要感谢Simon_fu,他的两篇关于root权限的文章对于我的工作起到了非常大的帮助,这篇文章可以说是对他的文章的一个补充.Simon_fu的文章可以参考如下两个网页: Androi ...

  4. Android应用程序获取ROOT权限的方法

    android中如何通过代码检测是否有root权限? public class MainActivity extends Activity { @Override     protected void ...

  5. android superuser.apk 管理root权限原理分析

    原文出处:http://blog.163.com/szs121@126/blog/static/109056781201223111390835/ 使用android 手机很多情况下需要root权限, ...

  6. 再谈Linux修改应用程序获得root权限

    我之前写过一篇关于怎样就可以使你的应用程序获得root权限运行,那个对于一些测试程序或小工程的程序时比较实用,但如果你的工程文件多达几十个甚至上百,那么这种方法就不太适用了. 在Ubuntu下面,我选 ...

  7. 看我如何利用Mac官方AppStore中的应用程序获取root权限

    一.前言 在本篇文章中,"Objective by the Sea"的演讲者Csaba Fitzl撰写了一篇有趣的方法,通过官方Mac AppStore中的应用程序来获取root权 ...

  8. Android程序获取root权限问题的最终解决与分析

          为了方便给出上一篇上一篇地址:  http://blog.csdn.net/up1up2up3/article/details/7380651,调了几天这个root权限获取问题终于搞定了, ...

  9. 如何使Android应用程序获取系统权限来修改系统时间

    在 android 的API中有提供 SystemClock.setCurrentTimeMillis()函数来修改系统时间,可惜无论你怎么调用这个函数都是没用的,无论模拟器还是真机,在logcat中 ...

最新文章

  1. Multisim 12.0 笔记
  2. python编写爬虫的步骤-如何编写python脚本?教你做简单的爬虫,适合初学者
  3. 重装系统后不重装matlab的解决办法
  4. 关于JQ的点击事件在微信手机端无响应的解决方案
  5. 阅读“CodeIgniter中国》文档首页》常规主题》安全”之抄录
  6. pythonelectron桌面开发案例_electron vue桌面应用入门实例
  7. python——学习笔记2
  8. NYOJ2括号配对问题
  9. 今天,Python信息量很大!
  10. MySQL 创建索引
  11. C++ 输入有空格一行的接收
  12. DTP动态协商——trunk配置、如何关闭域名解析、光接口无法up的原因详解(附图)
  13. mysql properties文件路径_读取web项目properties文件路径 解决tomcat服务器找不到properties路径问题...
  14. 【工业4.0】什么是工业4.0,这篇文章讲得明明白白!
  15. 计算机设置成一个网络,同一个路由器上的电脑怎么设置成局域网连网打 – 手机爱问...
  16. .net快速创建PDF文档 by c#
  17. Nginx中常用的指令配置详解
  18. 利用线程池单线程下载网页信息
  19. 这封“领导痛批95后下属”的邮件,句句扎心!
  20. java中分解json数据,java解析JSON数据详解

热门文章

  1. 网上复制代码需谨慎,莫名其妙报错看这里!
  2. C# 控件置于最顶层、最底层
  3. Kubernetes集群监控方案
  4. ubuntu下安装nginx时依赖库zlib,pcre,openssl安装方法
  5. 为Apache动态增加模块
  6. JAVA通信系列三:Netty入门总结
  7. jQuery 1.4 版本的十五个新特性-转载
  8. 2. VS使用---HelloWorld
  9. MongoDB复制集(Replication Sets)介绍
  10. 时间一天一天过去,很快;时间如果过的慢,更是没有意思