问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

Android解锁与root:原理与实现方法详解

创作时间:
作者:
@小白创作中心

Android解锁与root:原理与实现方法详解

引用
CSDN
1.
https://blog.csdn.net/csdnMomBOOM/article/details/136439509

Android设备的解锁与root是许多技术爱好者关注的话题。本文将深入探讨Android设备的解锁机制和root权限的获取方法,帮助读者更好地理解Android系统的底层运作原理。但需要注意的是,不当的操作可能会导致设备损坏或安全风险,请谨慎操作。

一、Android解锁

1.1 解锁的含义

Android设备解锁BootLoader(简称解BL锁)是刷机的前提条件。一旦某个设备无法解锁BL,通常就无法进行刷机操作。

1.2 什么是 BootLoader

Bootloader是负责启动计算机的软件。计算机开机时,会执行一个相对较小的程序来初始化内存、外设等启动后续操作系统必备的资源,并最终启动用户所使用的操作系统(如Windows、Android等)。这个程序就是BootLoader。

操作系统负责管理设备的硬件资源;而BootLoader是用来启动操作系统的。BootLoader的核心功能是确保启动一个可信的操作系统。当设备的操作系统出现问题时,BootLoader还可以引导启动另外一个正常的可信系统来执行恢复,因此,BootLoader的另一个重要功能是恢复系统。

1.3 BootLoader启动流程

以高通设备为例,我们来看一下BootLoader的启动流程:

1.3.1 PBL (Primary Boot Loader)

按下电源键启动手机时,CPU上电后开始运行。最开始运行的代码是CPU芯片厂商提供的,写死在某个只读存储上,这段代码一旦出厂便不可更改,我们通常称之为BootROM或PBL(Primary Boot Loader)。PBL的主要功能是上电自检并启动下一个组件SBL。

1.3.2 SBL(Secondary Boot Loader)

SBL主要初始化一些硬件环境(如DDR、clocks和USB等)和代码安全环境(TrustZone),最重要的还是验证并加载下一个组件——ABL(Android Boot Loader,也叫aboot)。与PBL不同,SBL程序一般存放在eMMC上,这个地方是可以被修改的,因此它可以被刷写和升级。正因如此,SBL还承载着最底层的恢复设备的重任;我们常说的高通9008模式(全称Emergency Download Mode)就运行在这里。9008模式本质上就是强制刷写设备的eMMC存储,因此不论你上层操作系统或者应用软件被破坏成什么样,除非硬件损坏,基本上都可以救回来。

为啥要整个SBL,直接PBL一把干完不行吗?实际上,PBL是芯片相关的,芯片无法预知到它用什么外设,因此这两个阶段被解耦了。

1.3.3 ABL(Android Boot Loader)

SBL执行完之后会验证并加载ABL,ABL的主要功能是从设备验证并加载bootimg然后启动Linux Kernel进而启动用户操作系统,根据选择的不同,可能会进入到Android系统或者Recovery模式。ABL还有一个很重要的功能,它提供了一个fastboot协议,用户可以用PC通过USB连接设备,通过这个fastboot协议控制设备;我们通常所说的「线刷」,小米的兔子界面以及我们通过命令行工具fastboot刷机实际上就是运行在ABL下。正因ABL功能比较复杂,它内部其实运行着一个mini的操作系统,这个操作系统就是lk(Little Kernel),Trusty TEE可信执行环境下的操作系统也是基于lk的。

1.3.4 Linux Kernel

ABL启动Linux Kernel之后,内核最终会进入用户态执行init,init进而启动ueventd、watchdogd、surfaceflinger以及zygote等;zygote启动之后forksystem_server并启动各种binder服务,系统核心binder服务启动之后会启动Launcher桌面,这样整个系统就启动完毕了。

1.4 BootLoader恢复功能

从上述BootLoader启动过程,我们可以很清楚地知道,BootLoader的恢复功能体现在SBL阶段的恢复模式以及ABL阶段的fastboot线刷模式。实际上,在我们手机底层软件出现问题之后,不论是自己救砖还是去售后,基本都是用的这两种模式。

1.5 BootLoader验证可信系统

上面我们多次提到了验证并加载。BootLoader的各个启动过程串起来就是一个启动链,这个启动链的各个阶段在进行过渡和跳转的时候是需要进行验证的。也就是说,上一阶段在启动下一阶段的时候,会验证下一阶段的代码是否可信;只有在验证通过的情况下,整个启动过程才会继续进行。在计算里面,这个验证的过程实际上就是比对数字签名。

如果BootLoader的每一个阶段都严格验证数字签名,在代码逻辑都正确的情况下,用户是无法通过BootLoader去加载一个修改过的第三方系统的(也就是无法刷机)。

解锁BootLoader实际上就是让BootLoader启动链上某些阶段的签名验证不生效。如果让BootROM不验证SBL,那我们就可以任意加载XBL从而接管接下来的操作流程如TEE、lk、Linux Kernel;如果让SBL不验证ABL,那我们就可以任意加载ABL从而接管lk和Linux Kernel;如果让ABL不验证boot.img,我们就可以控制Linux Kernel。在现实场景中,人们最需要的就是刷入自定义boot.img,毕竟这是用户能接触到的最上层系统Android的一部分。修改TEE和LK理论上不是不可以,但是修改这部分人们感知不强,并且通常这部分组件并不开源,也让很多人无从下手。因此实际上,我们通常所说的解锁BootLoader特指让ABL(aboot)在加载bootimage时不进行验证。

某些设备厂商提供了解锁功能,实际上就是通过某种方式关闭了ABL中对bootimage的加载验证。

小问题:镜像远大于内存的情况下,如何计算镜像的数字签名呢

1.6 BootLoader确保信任根受信

想办法篡改这个签名,那不是就可以解锁了?比如我们可以这样操作:把bootimage修改并用自己的签名,然后把ABL中存放签名的地方暴力改成我们的签名;这样ABL在校验签名的时候就会通过。但问题是,如果我们要修改ABL中存放签名的地方,势必要修改ABL,那么SBL在加载ABL的时候就会验证签名不通过;这样的话,我们继续修改SBL,然后把PBL中存签名的地方改掉?看起来或许可以。实际上,整个启动链之所以能保障安全,是因为它的信任传递机制——正因为第一个角色可信,第二个角色才可信,并一步步向下传递。如果有办法破坏掉启动链的第一个角色,那就破坏了整个信任链。所以,在BootLoader启动过程中,PBL(BootROM)所持有的签名是所有安全的基石,也即信任根(Root of Trust)。在BootLoader中,有两个机制确保信任根受信:

  1. BootROM的代码存放在只读存储器中,一旦出厂不可更改。
  2. 下一阶段的可信数字签名存放在独有的硬件设备之中(eFuse,一次性可编程存储器),一旦写入就会被破坏(三星设备解锁之后会「熔断」指的就是类似特性)。

因此,如果所有的组件都按照理想情况下工作,我们就无法更改BootROM所持有的信任根,进而无法破坏启动过程中的信任链,也就无法解锁设备。

当然,一切建立在所有的代码都正常工作的条件下。一旦某个阶段的代码有漏洞,那我们就有希望突破信任链,进而强制解锁设备。

事实上,这种漏洞并非天方夜谭。iOS上著名的checkmate漏洞就是BootROM中的代码存在问题,通过这个漏洞人们可以越狱设备。

如果设备提供商偷懒,并没有完整地实现整个安全启动链,那也是可能强制解锁的。比如老的华为设备,其解锁码存放在proinfo分区下,这个分区是可以被刷写的;因此你可以拿别的设备的解锁码和proinfo分区刷入直接通过验证。还有,曾经的vivo对bootimage的验证并不严格,用户自定义一个fastboot就可以直接解锁。

总体来说,如果想绕过限制强制解锁,基本上只有非常规手段

小问题:解了BootLoader锁的Android手机,如果不慎丢失,里面的个人隐私资料会被轻易获取吗?

二、Android root

通常来说,我们给手机解锁Bootloader就是为了获取Root权限。

2.1 root是最高权限

在类Unix系统中,root是在所有模式(单用户或多用户)下对所有文件和程序拥有所有权利或许可的用户的名称。

现代操作系统(本文主要讨论Android系统,下同)一般都是多用户的,那个名为root的用户所拥有的权限就是root权限

在类Unix系统中,一切皆文件。而这些文件通常以一个分层的树形结构在文件系统中呈现,每一个文件都有一个父目录,而那个最顶层的父目录被称之为根目录(root directory);root用户之所以被称之为root,大概是因为它是唯一能修改root directory的用户。

因为root用户拥有最高权限,因此它也通常被称之为超级用户(superuser);在类Unix系统中,每一个用户都有一个ID,root用户的ID是0,从传统意义上讲,uid为0就是root用户,也就拥有最高权限。

2.2 最高权限具体指的哪些?

手机是由多个零部件组成的,比如说,CPU、内存、闪存、各种硬件设备(如相机,屏幕、传感器等),所谓最高权限,就是对所有这些设备的控制权。

对于CPU来说,现在的CPU芯片一般都有不同的特权等级,这些不同的等级可以执行不同的指令。

经典x86处理器的Ring0~Ring3:

AArch64构架来说,CPU有四个特权等级,EL0~EL3:

在不考虑Secure World的情况下,EL0就是通常所谓的用户空间,应用程序一般运行在EL0级别,操作系统(Linux内核及驱动)运行在EL1,EL2上运行的则是虚拟化相关程序,EL3则运行管理Secure World和Normal Wrold的Secure Monitor。

从严格意义上来说,既然root权限意味着最高权限,这应该代表着它可以在EL0~EL3中的任意level上执行任意的CPU指令。然而,当前的各种root实现并非如此,它们一般能在EL0上执行任意指令,在某些情况下可以在EL1上执行任意指令;更高的特权等级就不行了。因为root用户是操作系统的概念,因此root权限顶多是操作系统中的最高权限;在类Unix系统中,它仅能触及EL1也就不算奇怪了。

对于内存、闪存以及各种外设来说,它们一般由操作系统内核和驱动来管理,而内核和驱动运行的指令通常位于EL1,因此,root权限意味着对所有的硬件(不包括TEE相关硬件)和外设拥有完全的控制权。

总结一下就是,root权限所拥有的最高权限,是我们的用户操作系统能管理的所有权限,包括各种硬件和外设以及一部分CPU指令的执行权限。

2.3 实现 root 的各种方法

实现root的方式整体上可以分为两种:

  1. 解锁Bootloader,通过修改Android系统的某一部分实现root。
  2. 通过某些系统漏洞提取,进而获取root权限。

解锁Bootloader实际上就允许我们刷入第三方或者被修改过的操作系统;如果我们可以解锁Bootloader,那么理论上讲我们就可以任意修改其操作系统,而root权限只不过是操作系统的某种机制,因此获取root权限自然不在话下。而这种修改方式常见的如下:

  1. 通过直接刷入第三方系统实现;在这个第三方系统中,系统自带root权限。
  2. 通过修改原系统的init实现;因为init进程是Linux系统的第一个进程,因此它实际上就以root身份执行的;通过修改init也可以实现root访问;Magisk就是通过代理init实现的root权限。
  3. 通过自定义内核实现;因为root权限实际上是内核操控的,因此自定义内核然后刷入自然可以获取root权限。

如果我们不能解锁Bootloader,那么可以通过系统漏洞来提权,进而拥有root权限。在远古时代(特别是Android 6.0以前),各种一键root满天飞,比如kingroot、360一键root,他们本质上都是通过系统漏洞来获取特殊权限;然而,随着Android系统的演进,这种通过漏洞提权获取root的方式已经很难出现在普通的大众视野里面了。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号