一、概述

本文介绍了android中获取root权限的方法以及原理,让大家对android玩家中常说的“越狱”有一个更深层次的认识。

二、Root的介绍

1.Root的目的

可以让我们拥有掌控手机系统的权限,比如删除一些system/app下面的无用软件,更换开关机铃声和动画,拦截状态栏弹出的广告等。

2.Root的原理介绍

谷歌的android系统管理员用户就叫做root,该帐户拥有整个系统至高无上的权利,它可以访问和修改你手机几乎所有的文件,只有root才具备最高级别的管理权限。我们root手机的过程也就是获得手机最高使用权限的过程。同时为了防止不良软件也取得root用户的权限,当我们在root的过程中,还会给系统装一个程序,用来作为运行提示,由用户来决定,是否给予最高权限。这个程序的名字叫做Superuser.apk。当某些程序执行su指令想取得系统最高权限的时候,Superuser就会自动启动,拦截该动作并作出询问,当用户认为该程序可以安全使用的时候,那么我们就选择允许,否则,可以禁止该程序继续取得最高权限。Root的过程其实就是把su文件放到/system/bin/ Superuser.apk放到system/app下面,还需要设置/system/bin/su可以让任意用户可运行,有set uidset gid的权限。即要在android机器上运行命令:adb shell chmod 4755 /system/bin/su。而通常,厂商是不会允许我们随便这么去做的,我们就需要利用操作系统的各种漏洞,来完成这个过程。

特别说明:我们烧机中的Eng版本并没有Root权限

3.Root的方法

Root的原理我们了解到,root过程分三步:

[plain] view plain copy
  1. a.adbpushsu/system/bin
  2. b.adbpushSuperUser.apk/system/app
  3. c.adbshellchmod4755/system/bin/su

若系统是eng版的,做到以上三步,那么我们Root就大功告成,但实际是不行的。为什么呢?原因有三:

1user版的/system路径是只读权限,不能简单写入

2chmod需要Root权才能运行(死循环了)

3、有些系统在启动时会自动将su4755权限设成755,甚至直接删除su

那么针对这种情况,我们怎么办呢?非常简单:烧一个eng版本的boot.img就行了

可以用展讯的烧录工具,或者用fastboot模式从sd卡烧一个boot.img文件即可

至此,我们Root就成功了,可以用R.E(Root Explorer)在根目录创建和删除文件。

三、深入理解Root机制

其流程是:

[plain] view plain copy
  1. 1.Su被用户调用
  2. 2.Su创建了一个socket监听
  3. 3.Su向Superuser发送了一个广播,说是有一个程序要请求root
  4. 4.Su等待socket数据接收。有超时处理。
  5. 5.Superuser界面收到广播后,弹出一个对话框,询问用户
  6. 6.Superuser向传来的数据中的socket写回用户应答结果。
  7. 7.Su根据socket得到的结果处理应该不应该继续执行
  8. 8.完成提权管理

superuser.apk这个程序是root成功后,专门用来管理root权限使用的,防止被恶意程序滥用。

源码地址:http://superuser.googlecode.com/svn/trunk

我们有两点疑问:

1. superuser是怎么知道谁想用root权限?

2. superuser是如何把用户的选择告诉su程序的?

superusersu程序是如何通讯的,他们俩位于不通的时空,一个在java虚拟中,一个在linux的真实进程中。

superuser共有两个activity: SuperuserActivitySuperuserRequestActivity,其中SuperuserActivity主要是用来管理白名单的,就是记住哪个程序已经被允许使用root权限了,省的每次用时都问用户。

SuperuserRequestActivity就是用来询问用户目前有个程序想使用root权限,是否允许,是否一直允许,即放入白名单。

这个白名单比较关键,是一个sqlite数据库文件,位置:

/data/data/com.koushikdutta.superuser/databases/superuser.sqlite

上文说过,root的本质就是往/system/bin/下放一个su文件,不检查调用者权限的su文件。普通程序可以调用该su来运行root权限的命令。superuser.apk中就自带了一个这样的su程序。一开始superuser会检测/system/bin/su是否存在:

[plain] view plain copy
  1. Filesu=newFile("/system/bin/su");
  2. //检测su文件是否存在,如果不存在则直接返回
  3. if(!su.exists()){
  4. Toasttoast=Toast.makeText(this,"Unabletofind/system/bin/su.",Toast.LENGTH_LONG);
  5. toast.show();
  6. return;
  7. }
  8. //如果大小一样,则认为su文件正确,直接返回了事。
  9. if(su.length()==suStream.available())
  10. {
  11. suStream.close();
  12. return;//
  13. }
  14. //如果检测到/system/bin/su文件存在,但是不对头,则把自带的su先写到"/data/data/com.koushikdutta.superuser/su"
  15. //再写到/system/bin/su。
  16. byte[]bytes=newbyte[suStream.available()];
  17. DataInputStreamdis=newDataInputStream(suStream);
  18. dis.readFully(bytes);
  19. FileOutputStreamsuOutStream=newFileOutputStream("/data/data/com.koushikdutta.superuser/su");
  20. suOutStream.write(bytes);
  21. suOutStream.close();
  22. Processprocess=Runtime.getRuntime().exec("su");
  23. DataOutputStreamos=newDataOutputStream(process.getOutputStream());
  24. os.writeBytes("mount-oremount,rw/dev/block/mtdblock3/system\n");
  25. os.writeBytes("busyboxcp/data/data/com.koushikdutta.superuser/su/system/bin/su\n");
  26. os.writeBytes("busyboxchown0:0/system/bin/su\n");
  27. os.writeBytes("chmod4755/system/bin/su\n");
  28. os.writeBytes("exit\n");
  29. os.flush();

有进程使用root权限,superuser是怎么知道的呢,关键是句:

[plain] view plain copy
  1. sprintf(sysCmd,"amstart-aandroid.intent.action.MAIN
  2. -ncom.koushikdutta.superuser/com.koushikdutta.superuser.SuperuserRequestActivity
  3. --eiuid%d--eipid%d>/dev/null",g_puid,ppid);
  4. if(system(sysCmd))
  5. returnexecutionFailure("am.");

原理是am命令,am的用法:

[plain] view plain copy
  1. usage:am[subcommand][options]
  2. startanActivity:amstart[-D][-W]<INTENT>
  3. -D:enabledebugging
  4. -W:waitforlaunchtocomplete
  5. startaService:amstartservice<INTENT>
  6. sendabroadcastIntent:ambroadcast<INTENT>
  7. startanInstrumentation:aminstrument[flags]<COMPONENT>
  8. -r:printrawresults(otherwisedecodeREPORT_KEY_STREAMRESULT)
  9. -e<NAME><VALUE>:setargument<NAME>to<VALUE>
  10. -p<FILE>:writeprofilingdatato<FILE>
  11. -w:waitforinstrumentationtofinishbeforereturning
  12. startprofiling:amprofile<PROCESS>start<FILE>
  13. stopprofiling:amprofile<PROCESS>stop
  14. <INTENT>specificationsincludetheseflags:
  15. [-a<ACTION>][-d<DATA_URI>][-t<MIME_TYPE>]
  16. [-c<CATEGORY>[-c<CATEGORY>]...]
  17. [-e|--es<EXTRA_KEY><EXTRA_STRING_VALUE>...]
  18. [--esn<EXTRA_KEY>...]
  19. [--ez<EXTRA_KEY><EXTRA_BOOLEAN_VALUE>...]
  20. [-e|--ei<EXTRA_KEY><EXTRA_INT_VALUE>...]
  21. [-n<COMPONENT>][-f<FLAGS>]
  22. [--grant-read-uri-permission][--grant-write-uri-permission]
  23. [--debug-log-resolution]
  24. [--activity-brought-to-front][--activity-clear-top]
  25. [--activity-clear-when-task-reset][--activity-exclude-from-recents]
  26. [--activity-launched-from-history][--activity-multiple-task]
  27. [--activity-no-animation][--activity-no-history]
  28. [--activity-no-user-action][--activity-previous-is-top]
  29. [--activity-reorder-to-front][--activity-reset-task-if-needed]
  30. [--activity-single-top]
  31. [--receiver-registered-only][--receiver-replace-pending]
  32. [<URI>]<spanstyle="font-family:Calibri;font-size:14px;"></span>

还有个疑点,就是su怎么知道用户是允许root权限还是反对呢?原来是上面提到的白名单起来作用,superuser把用户的选择放入:

/data/data/com.koushikdutta.superuser/databases/superuser.sqlite数据库中,然后su进程再去读该数据库来判断是否允许。

[plain] view plain copy
  1. staticintcheckWhitelist()
  2. {
  3. sqlite3*db;
  4. intrc=sqlite3_open_v2(DBPATH,&db,SQLITE_OPEN_READWRITE,NULL);
  5. if(!rc)
  6. {
  7. char*errorMessage;
  8. charquery[1024];
  9. sprintf(query,"select*fromwhitelistwhere_id=%dlimit1;",g_puid);
  10. structwhitelistCallInfocallInfo;
  11. callInfo.count=0;
  12. callInfo.db=db;
  13. rc=sqlite3_exec(db,query,whitelistCallback,&callInfo,&errorMessage);
  14. if(rc!=SQLITE_OK)
  15. {
  16. sqlite3_close(db);
  17. return0;
  18. }
  19. sqlite3_close(db);
  20. returncallInfo.count;
  21. }
  22. sqlite3_close(db);
  23. return0;
  24. }

四、资源文件的获取

从上文的源码地址获取源代码,替换系统的system/extras/su/下面的su.cAndroid.mk文件,使用编译命令./mk td28 u adr system/extras/su/编译成功后会生成out/target/product/hsdroid/system/xbin/su文件,而Superuser.apk就是普通的apk文件,都在源码地址里面可以下载,下载后倒入到eclipse即可直接运行。

五、总结

在阅读完本文后,可以站在专业的角度了解root的真正原理,以及有用户有需求时我们可以帮助其快速的解决问题。

更多相关文章

  1. Google称Android新漏洞对用户影响不大
  2. Android权限系统
  3. Android Uri获取资源文件(多种方式)
  4. 编译android 之后生成的 img 文件介绍
  5. android操作sdcard中的多媒体文件(一)——音乐列表的制作
  6. android 操作sdcard中的多媒体文件(一)——音乐列表的制作
  7. Android Zip文件解压缩代码
  8. Android中多媒体文件、文档以及各类文件的获取
  9. Android 超简单的录制屏幕视频及生成GIF文件的方法

随机推荐

  1. Android(安卓)Studio 如果修改LogCat的颜
  2. Android(安卓)中Crash时如何获取异常信息
  3. android应用程序线程的监控
  4. Android一键分享——原生分享图片
  5. Android开源游戏引擎之Angle(一)——概述
  6. 无需Root也能使用Xposed!
  7. 转:Android中自定义SeekBar的背景颜色,进度
  8. Android如何让你的第三方库可以compile的
  9. Android(安卓)多渠道打包(二)--动态多渠道资
  10. Android判断用户的网络类型(2/3/4G、wifi