收藏私塾在线
 

欢迎您来到私塾在线网!   

请登录! 

免费注册 

交流首页 » 移动编程 »Android手机Root授权原理细节全解析(分段落版本)  XML
发表人 内容
fengzhizi
[头像]

交流经验:
总积分:380
级别:普通会员
注册时间: 2011-11-07
文章: 11
离线

Android手机Root授权原理细节全解析(分段落版本)
首先关于Root的方式,这里不做详解,可以有很多漏洞,比如利用uid溢出后归为0,得到Root权限,然后操作文件系统等。
 
手机Root后,最重要的是,给手机安装了su程序和superuser apk。 su一般被安装在/system/xbin 或者 /system/bin 下面,su文件的权限如下:
 
# ls su -l 
ls su -l 
-rwsr-sr-x    1 root     root         26336 Aug  1  2008 su
 
这里可以看到,su的Owner和Group分别为Root,Root。 Other用户具有exeute权限,另外,su设置了suid和sgid,这个非常重要,后面会详述,这个使得Su进程可以提升自身的EUID。
 
我们这里以RootExplorer为例,看是如何申请和提升权限的:
 
首先,ps一下,可以看到root explorer的信息,这里第一列是UID,更加准确的,应该是EUID。
app_73    1143  103   301620 39944 ffffffff 400194c4 S com.speedsoftware.rootexp 
lorer
 
这里可以看到,Root Explorer的EUID=10073(App Base是从10000开始的)
 
然后,Root Explorer通过Runtime方式,使用shell 命令行运行了“su”, 所以,会有一个Root Explorer启动的sh:
 
app_73    1159  1143  764    376   c003e454 4001cf94 S /system/bin/sh
 
default情况下,进程的UID是继承的,这里sh的PPID是1143,说明是RootExplorer启动的。
 
RootExplorer通过类似下面的代码运行“su”:

p = Runtime.getRuntime().exec("su");    

所以,1159  PID的sh会启动su,这里需要注意的是,su进程的Real UID是10073,因为继承自parent,但是,其EUID却提升为了ROOT,这就是由于SUID被设置的原因。 由于su进程的EUID是ROOT,所以导致了su可以做很多高权限的事情。

su会通过:

sprintf(sysCmd, "am start -a android.intent.action.MAIN -n com.koushikdutta.superuser/com.koushikdutta.superuser.SuperuserRequestActivity --ei uid %d --ei pid %d > /dev/null", g_puid, ppid);
  if (system(sysCmd))
   return executionFailure("am.");

启动SuperUser Request Activity来询问用户是否授权当前应用,如果否的话,则su将return 结束, 否则su会继续运行。

得到用户许可后(通过sqlite和SuperUser Request Activity交流用户许可),su会将自己的Real UID也设置为ROOT:

 if(setgid(0) || setuid(0)) 
  return permissionDenied();

由于su的EUID是ROOT,所以su有权限执行以上代码,执行完后su进程的Real UID,effective UID都变成了ROOT。 这里为什么要同时提升Real UID的权限,后面会说明。

然后,su会启动一个额外的sh来运行用户的指令:

char *exec_args[argc + 1];
 exec_args[argc] = NULL;
 exec_args[0] = "sh";
 int i;
 for (i = 1; i < argc; i++)
 
  exec_args[i] = argv[i];

 
 execv("/system/bin/sh", exec_args);
 return executionFailure("sh");


 这里非常关键的代码是execv! 这里没有使用fork,而是直接使用execv,这将导致不会创建新的进程运行sh image,而是直接在当前su的进程空间load并执行sh image。 所以,return executionFailure("sh"); 正常情况下是永远不会被执行的,执行完execv后,就开始直接sh的代码了。

这里可以看到,由于复用su当前进程来运行sh,使得sh运行的进程的EUID,Real UID都是ROOT,那么,任何操作都可以执行了。 如果不提升Real UID为Root的话,那么只要sh运行中通过启动外部程序的方式来完成操作的话,就会出现权限问题,因为新启动的进程只会继承父进程的Real UID,而不是EUID,那么新起的进程的Real UID=EUID= parent RealUID != ROOT,那么某些操作可能有问题。 所以,su把自己的Real UID也提升为ROOT后,则不管启动后的任何代后的子进程执行操作,都是以ROOT的权限运行。

RootExplorer通过得到sh流后,就可以通过该流执行任何shell指令了:

  • try    
  •    // Preform su to get root privledges   
  •    p = Runtime.getRuntime().exec("su");    
  •   
  •    // Attempt to write a file to a root-only   
  •    DataOutputStream os = new DataOutputStream(p.getOutputStream());   
  •    os.writeBytes("echo \"Do I have root?\" >/system/sd/temporary.txt\n");   
  •   
  •    // Close the terminal   
  •    os.writeBytes("exit\n");   
  •    os.flush();   

     

    通过ps也可以明显看到su变成了sh,如下,

    app_73    1143  103   301620 39944 ffffffff 400194c4 S com.speedsoftware.rootexp
    lorer
    app_73    1159  1143  764    376   c003e454 4001cf94 S /system/bin/sh
    root      1161  1159  772    388   c012e760 4007c578 S sh

    这里的PID=1161的进程其实是su(可以通过打log验证),当执行execv("/system/bin/sh", exec_args);后,进程名就变成了sh。当然进程EUID不变,仍然是ROOT。

    通过cat 进程的proc信息,我们也可以看到其实RootExplorer自身的UID或者权限根本没有被提升(这是和linux上执行su不一样的地方),

    root@android  :/proc/1143 # cat status
    cat status
    Name:   re.rootexplorer
    State:  S (sleeping)
    Tgid:   1143
    Pid:    1143
    PPid:   103
    TracerPid:      0
    Uid:    10073(Real)   10073(Effecttive)   10073(saved)   10073
    Gid:    10073   10073   10073   10073

    而su演变成的sh,却是具有所有的ROOT UID:

    root@android  :/proc/1161 # cat status
    cat status
    Name:   sh
    State:  S (sleeping)
    Tgid:   1161
    Pid:    1161
    PPid:   1159
    TracerPid:      0
    Uid:    0       0       0       0
    Gid:    0       0       0       0

     

    总结: Android中App授权获取Root权限,其实不是App自身的权限提升了,而是通过具有ROOT权限的sh流来执行shell命令


推广链接
精品视频课程推荐

独家Android4就业经典视频教程
从零开始,循序渐进掌握Android的核心开发知识;理解Android应用的运行过程、理解Intent和IntentFilter、 掌握资源和国际化、理解Android的进程和线程、理解Task和会退栈、理解Activity在屏幕旋转时的生命周期、 理解Handler的原理以及开发应用、掌握三种Service的写法、理解Broadcast的原理......

Android4项目实战--五子棋视频教程
多种布局的综合使用、ImageButton的改进使用、AutoCompleteTextView的应用、显示多项的ListView、基本的人工智能的实现,基于启发式搜索算法、SharedPreferences和Sqlite的应用、自定义View的实现和应用等

Hibernate4实战-独家视频教程
ORMapping的原理、1+N次问题、版本并发控制、开发的反模式、Open Session In View模式、抓取策略、集合性能、Hibernate运行原理、开发的最佳实践

freevoice(局域网对讲机)——Android4项目实战视频教程
实现通过Wifi来在局域网内相互传递信息和语音通话的功能;学习Service;Broadcast Receiver;SharedPreference;SQLite;语音录制、播放、传输等;网络开发:wifi处理、UDP编程、TCP编程;多种设计模式的应用 等等

 
交流首页 » 移动编程
前往:   

关于我们 | 联系我们 | 用户协议 | 私塾在线服务协议 | 版权声明 | 隐私保护

版权所有 Copyright(C)2009-2012 私塾在线学习网