理解Android的刷机和Rooting

相对于IOS,Andorid系统的最大优势是它的开放性,但这种开放性是一把双刃剑,它在给用户更多选择的同时,也让恶意软件有了更多的作恶途径。理解Android的运行机制,不仅能帮助我们更好的使用Android,也能保护我们不受坏软件的欺负。以下是我对刷机和Rooting的理解,以记录为主,有不对的地方欢迎指出。

一台安卓手机主要有3个独立的软件系统:bootloader,Android主系统,recovery系统。

开机时,bootloader最先启动,并可选择加载Android还是recovery系统。可以理解为PC的BIOS。

Android主系统是最复杂的部分,它又分成boot,linux内核,Dalvik/ART支撑起来的App运行环境和各种App。

recovery系统主要用于Android主系统的升级,故障修复恢复出厂设置等。有点类似Windows下的安全模式,但和安全模式不同,recovery是个安装在单独分区上的独立系统,能在Andorid主系统没有运行的情况下独立运行,所以可以修改主系统上的任何文件。

因为系统运行时不能修改自身的一些核心部件,所以Android要升级系统一般有两种方式:

  1. 在bootloader模式下,通过fastboot工具直接写手机的flash芯片,这种方式功能最为强大,不仅能修改Android或recovery的系统文件,甚至还能给flash芯片重新分区,格式化等都不在话下。缺点是功能比较raw,不理解文件系统,要单独修改某个文件会比较麻烦。
  2. 在recovery模式下,mount主系统分区,进行文件读写。第三方工具刷机和OTA系统升级都是用这种方式。AOSP(安卓原生代码)自带的recovery系统是个功能非常简单的系统,除了配合OTA升级,基本没有其他功能。所以产生了第三方recovery系统,最著名的是TWRP,另外CyanogenMod的recovery系统功能相对完善,也自成一派。

所以,安卓刷机有以下几种类型:

  1. 正常的系统升级(OTA)。安卓系统检测到有新的版本,下载新版本到本地flash,提示用户重启手机后进入recovery系统,解压新版本文件,覆盖到原系统分区,重启手机,进入新系统。
  2. fastboot升级,以flash分区为单位,升级boot,recovery等各个部件。如fastboot flash recovery twrp.img fastboot flash boot boot.img
  3. 刷recovery系统(如TWRP),然后通过recovery系统随意刷任何第三方Rom,或者修改一些系统关键文件,如Xposed会替换掉安卓核心进程Zygote,SuperSu会修改BootImage。

第三种方式的自由度是最高的,但受制与厂商的具体实现,无论是recovery系统还是bootloader都可能会对安卓系统包进行签名验证,拒绝安装非原厂系统。因为Rocovery系统本身可以在bootloader下刷,所以要破解手机刷第三方Rom的关键是bootloader是否被锁了。这方面,Google亲儿子Nexus系列是最方便的,一行命令fastboot oem lock即可解锁bootloader,其他开发者友好的厂商如一加手机也支持该方法, Sony的Xperia需要邮件验证提供解锁码,小米也可申请解锁权限,但需mi帐号绑定,并有一些限制。而另外一些手机则需要等待破解漏洞。

Rooting

上面讲的都是刷机,而Rooting是指获取系统的最高权限。Android和普通Linux系统一样,有普通用户和root用户(用户ID为0),不一样的是Android系统为每个App生成了一个用户,从而更好的隔离各个App的权限。同时Android也引入了SeLinux,除了根据UID来检查权限外,App的行为还需符合SeLinux设定的规则,如普通App都属于untrusted_app分组,权限相对较小。可以用adb shell logcat|grep audit 命令查看SeLinux消息,任何违反SeLinux规则的操作都会被记录下来,并会根据Selinux的状态决定是否阻止该操作。SeLinux有两种状态:enforce和permissive分别对应打开和关闭。可通过getenforce查看和setenforce(需root权限)设置。

获取Root权限有两种情况:

  1. 获取一个root shell。
  2. 管理App的root权限申请。

第一种情况相对简单,adb工具有一个adb root 命令,用于打开一个root shell。但如果你直接使用会提示adbd cannot run as root in production builds ,这时你需要修改Android系统的ro.debuggable属性为1,让系统认为自己在调试开发模式。但ro.debuggable无法通过setprop工具设置。有两种方法:

  1. 通过setpropex工具直接修改init内存的方式修改ro.debuggable属性。
  2. 修改boot image中设置ro.debuggable属性的配置文件,重新打包后用fastboot工具更新boot。

这两种方法都比较复杂,所以就有了一个第三方工具adbd Insecure,(ps:它的作者也是SuperSu的作者Chainfire)。这个工具的原理是用一个修改过的adbd替换掉原有adbd,从而跳过ro.debuggable属性检查(我猜:)。

顺便说一下adb这个工具,adb由三部分组成:

  1. adb客户端,也就是我们输入adb命令调用的那个,运行在调试电脑上。
  2. adb服务端,负责和手机通信,提供数据链路的抽象,adb客户端无需考虑是通过USB线缆,还是TCP协议等其他方式和手机交互,也运行在调试电脑上。
  3. adbd服务进程。运行在手机端,代表Android系统和adb客户端交互。包括提供shell给用户,所以我们要获取root权限的shell需要先过它这一关。

当然还有一种获取root shell的方式是,用adb shell 命令开启一个普通权限的shell后,执行su(刷SuperSu后,会安装到系统路径)命令,提权到root用户。但这样有个缺点,adb push adb pull这些命令的权限都不是root,拷贝文件会非常不方便。

SuperSu的主要作用是提供第三方App的Root权限管理,具体就是,第三方App想使用root权限时,SuperSu弹出一个对话框,由用户确认是否给予root权限。以此提供一个相对安全的环境。

值得一提的是,SuperSu是一个闭源软件,作为一个开源系统上的最高权限软件,这简直有点不可思议,所以XDA上发起了一个SuperSu开源替代项目。

至于国内各大厂商推出的一键Root软件,基本都是利用了Android系统的提权漏洞,安全存疑,不建议使用,并且随着Android系统的完善这种漏洞会越来越少。

相关链接

How-To SU

TWRP

http://cygery.com/wordpress/2014/06/29/android-l-selinux-root-apps/

http://trendblog.net/guide-to-android-rooting-custom-roms-apps/

https://download.chainfire.eu/supersu

http://wiki.cyanogenmod.org/w/Devices

http://developer.sonymobile.com/unlockbootloader

https://wiki.cyanogenmod.org/w/Doc:_fastboot_intro

https://www.kingoapp.com/help/fastboot-mode.htm

https://wiki.cyanogenmod.org/w/All_About_Recovery_Images