首页 > 代码库 > Android Root原理和流程分析

Android Root原理和流程分析


预备知识

android手机的内部存储设备分RAM和ROM,RAM是运行内存,掉电就会失去所有内容;ROM中的内容掉电后也不会丢失。

比如一台手机的规格参数里写着“2G RAM,16G ROM”。理论上,RAM越大,系统运行越流畅。像大型的3D游戏,运行时需要约300M的内存,那么在内存2G的手机上就可以流畅的运行,在512M内存的手机上几乎跑不起来,跑起来也会卡死。我们可以在“设置-管理应用程序-正在运行”中看到手机目前剩余的RAM,一般2GRAM的手机显示可用RAM只有1G多点,因为Android系统本身的运行也会消耗一定内存。RAM存取速度很快,但价格昂贵,所以手机里的RAM不会特别大。

Rom的大小与手机卡不卡几乎没什么关系,可以把它当成一张内置的SD卡(它事实上也确实就是一张内置的SD卡)。它上面的内容分成两大块:系统数据,用户文件(也就是我们的照片、歌曲、视频等等)。系统数据只占据比较小的一部分,大概不到1G,剩下的就由用户随意的放照片、视频等。我们使用MTP(媒体连接模式)将手机连接电脑时,可以在电脑上看到多出来的Phone盘符,在里面可以查看我们自己的文件。如果16G的ROM,连到电脑上就会发现没有这么大,原因就是有一部分放了系统数据。

内存中的系统数据分区是非常重要的——可以说整个Android系统都在上面。

那么系统分区里到底存放了哪些内容呢?粗略的讲,包括以下内容:

/system

/boot

/cache

/data

/recovery

/misc

其中/system就是android系统,里面存放了所有的系统应用、支持这些应用运行的framework、系统工具等等。如果把它删了,你就进不来android系统了,也没法打电话发短信了,更不能玩游戏了,因为Android系统已经从你的手机上消失了。

/data就是用户数据(注意与上面的用户文件是不同的),你的短信、通话记录、联系人等;你用浏览器时浏览的网页、输入的用户名密码、保存的设置,都是你的用户数据。如果把它删了,你的手机就相当于“恢复出厂设置”,你的短信、你装的应用等统统不见了。

/boot主管手机的正常启动。比如你按开机键会先见到开机动画,然后顺利的进入android系统;你开机时按住音量键和开机键会进入recovery,这些都是/boot来控制的。不要以为这是无关紧要的工作,开机前android系统是磁盘上的0和1,开机后它变成了一个可以运行的系统,这都是/boot的功劳。

/cache就是系统当前的缓存,你浏览的网页正处在第15行的位置,你玩的游戏正停留在这个画面上,都是/cache来记录的。

/recovery平时一般用不到,它是一个小型的手机系统,就像android系统一样。它的作用是可以刷入新的rom,进行系统更新,备份用户数据等。(具体功能可以安装一个clockworkmod看看)

android启动时会执行/boot下的代码,将android系统从磁盘上读出来,挂载到/system目录下。注意这里的/system与前文中说的磁盘上的/system分区不是一个概念:/system分区是存储设备中的数据,是0和1。而/system目录是文件系统中的目录。/system目录是/system分区的挂载点。

挂载完成后,就可以通过/system目录访问到/system分区,并对其进行读写操作(需要root权限)。

Root原理与流程

那么,什么是root权限?怎样才算root?

表现上:su文件在/system/xbin文件夹下,并具有rwsr-sr-x权限,就说明手机获得了root权限。

实际上:在*nix系统(android的内核是linux系统)下,一切皆文件。如磁盘、媒体、输入输出……等等。像磁盘,就是/dev下的一些文件;进程,也是通过/proc下的各种文件来描述的。在一切皆文件的*nix系统中,对所有文件随意操作的自由,就是最大限度的自由。这种自由,就叫“root”权限。

可见,root权限的自由非常大,如果被恶意利用,会使整个系统处于危险之中(你的短信、联系人,你的账号密码,你的照片视频等等)。所以手机厂商和android系统都不会主动开放root授权的。要获取root权限只能通过非正常手段。

所以现有的获取root权限的方法思路其实只有一个,就是利用漏洞,破坏规则:

1.        利用android源码中的漏洞来进行提权(比如RAGEAGAINSTTHECAGE漏洞,通过大量创建子进程让adbd进程降级失败,从而获取root权限)

2.        先刷入自定义的recovery,然后利用修改过的recovery将su刷入/system分区

3.        从SD卡进行boot,从而修改/system分区(只有少部分机型有此功能)

利用源码的漏洞,有几个有名的案例。比如RageAgainstTheCage漏洞,有人把它称为setuid提权漏洞。代码通过将adbd后台服务子进程耗尽迫使adbd重启,adbd在重启的时候具有root权限,正常情况下这时adbd会调用setuid将权限降到shell,但是由于rageagainstthecage让adbd的僵尸进程充斥着整个系统,这时候setuid会调用失败,最后adbd就被保留了root权限运行,从而完成root提权。

详见:http://blog.sina.com.cn/s/blog_da6ccaf60101g86r.html

不过这种方式root的成功率已经非常低了,因为随着android系统的升级,漏洞也在一个一个的被堵上。利用这种方式root的工具大多是手机上的“一键root”apk

第二种方式也是现在root成功率很高的一种方式,是通过pc端工具,连接手机进行root。pc端工具会根据机型选择对应的修改后的recovery(其中认同度最高的是ClockWorkMod的recovery),通过cat或dd命令将其刷入recovery对应的硬件地址。

命令如下:

adb push stockrecovery.img /sbin/

adb shell "dd if=/sbin/stockrecovery.imgof=/dev/block/platform/mmci-omap-hs.1/by-name/recovery"

adb reboot

recovery其实是一个小型的手机系统,也是linux内核的。也就是说,可以理解为手机上装了双系统,一个是android系统,一个是recovery。如果android系统被毁了(比如删了rom中的/system分区),手机还是可以进入recovery的。

通过recovery怎样获取root权限呢?原理很简单,进入recovery后,/system分区就变成了rom中的一个硬件盘块,对它当然可以自由修改。我们把su放到/system/xbin文件夹下,赋予rwsr-sr-x权限,基本就大功告成了。

那怎么放过去呢?

具体操作参见:http://blog.csdn.net/happy_6678/article/details/7242594

脚本语言Edify的详细介绍参见:http://blog.csdn.net/tody_guo/article/details/7948083

就这样简单几步就完成了:

ui_print("Mounting system...");

run_program("/sbin/busybox", "mount","/system");

ui_print("Deleting old files...");

delete("/system/bin/su","/system/xbin/su","/system/app/Superuser.apk");

ui_print("Copying files...");

package_extract_dir("system", "/system");

ui_print("Fixing permissions...");

set_perm(0, 0, 06755, "/system/bin/su");

ui_print("Symlinking...");

symlink("/system/bin/su", "/system/xbin/su");

ui_print("Unmounting system...");

run_program("/sbin/busybox", "umount","/system");

至于第三种方式,一般只有非常少的机型支持从SD卡boot来进行root或刷机,这里就简单介绍一下这种情况root的思路:因为是从SD卡boot,所以SD卡上会有对应的boot.img。修改这里的boot.img,就可以达到我们的目的。

boot.img解压后是这个样子的:


其中init.**.rc就是启动的脚本,它负责把android系统从/system分区挂载到/system目录下,并修改其权限为ro(只读)。这里我们注意到,init脚本运行时,是拥有修改/system目录的权限的。

如果我们修改这里的init脚本,在/system的权限变成ro之前,将su放到/system/xbin目录下并修改权限,root权限就获取了。

修改init脚本也并不难,init脚本使用的是AIL(Android InitLanguage),它的详细介绍参见:http://blog.csdn.net/nokiaguy/article/details/9109491

修改完init脚本,再重新打回boot.img,放到SD卡从SD卡启动,就大功告成了。

Bootloader加锁

Bootloader的定义:Bootloader是嵌入式系统在加电后执行的第一段代码,在它完成CPU和相关硬件的初始化之后,再将操作系统映像或固化的嵌入式应用程序装在到内存中然后跳转到操作系统所在的空间,启动操作系统运行。

Bootloader的加锁: “加锁”的BootLoader是指BootLoader在加载操作系统映像或其它重要固件之前,会先对其进行签名校验,签名不符的话就中止启动流程。

所以root和刷机之前需要先对BootLoader进行解锁。

 

Android Root原理和流程分析