gbl_root_canoe隐藏BL状态原理分析

admin 2026-06-12 04:59:56 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 该文档分析了高通骁龙8Gen5平台通过gblrootcanoe工具隐藏Bootloader解锁状态的技术原理。核心方法包括修改ABL二进制中的efisp分区名为nulls以阻断原始加载链,提取并修补LinuxLoader.efi文件,通过二进制补丁强制AVB验证逻辑返回锁定状态,并修改内核启动参数。该方案利用GBL校验漏洞在启动早期实现假回锁,绕过TEE及Android完整性检测,同时保留刷写能力。 综合评分: 85 文章分类: 漏洞分析,二进制安全,移动安全,终端安全,逆向分析


cover_image

gbl_root_canoe隐藏BL状态原理分析

原创

非虫 非虫

软件安全与逆向分析

2026年6月11日 18:31 湖北

在小说阅读器读本章

去阅读

gbl_root_canoe隐藏BL状态原理分析

高通骁龙8Gen5(内部代号 Sun/Canoe)平台的Android设备获取Root权限需要先解锁Bootloader(BL)。解锁BL后,TEE(Trusted Execution Environment)会将设备永久标记为不可信状态,导致银行类应用、支付应用及完整性检测机制(SafetyNet/Play Integrity)识别到设备已解锁而拒绝运行。

gbl_root_canoe实现BL解锁与TEE状态隐藏、在获得Root权限的前提下,利用GBL(Generic Bootloader)加载机制中的一个行为漏洞,将经过精准二进制修补的ABL(Android Bootloader,即高通UEFI启动应用)注入efisp分区,使设备在启动链的早期就切换到「假回锁」状态,让TEE、内核及Android框架层均认为BL处于已锁状态,从而绕过完整性检测,同时保留通过SuperFastboot进行刷写的能力。


高通ABL启动链基础

在骁龙8Gen5平台上,设备上电后的启动顺序大致如下:

PBL(片上只读)
  └──> XBL / SBL(一次性可编程,高度受保护)
         └──> ABL(efisp 分区,UEFI 应用层)
                └──> Linux Kernel

ABL是整个链条中唯一同时满足「可被刷写替换」与「可访问 Verified Boot 决策逻辑」两个条件的组件。高通将 ABL 以 UEFI Firmware Volume(FV)格式打包,内部包含若干 PE32 格式的 EFI 应用,其中最核心的是LinuxLoader.efi,负责执行 AVB(Android Verified Boot)校验、决定 BootState,并最终引导内核。

ABL的验证由 GBL 负责。GBL 会从 efisp 分区读取并校验 ABL。这里存在一个关键行为:GBL 读取的分区名是通过一个可写的 UTF-16 字符串 "efisp" 指定的。这个字符串位于 ABL 二进制的数据段,可以在 PC 端修改——这就是本方案漏洞利用的起点。


efisp分区名替换

patch_abl_gbl是整个方案中最简洁的一步:

int32_tpatch_abl_gbl(char* buffer, int32_t size) {
char target[]      = { 'e',0, 'f',0, 'i',0, 's',0, 'p',0 };
char replacement[] = { 'n',0, 'u',0, 'l',0, 'l',0, 's',0 };
int32_t target_len = sizeof(target);
for&nbsp;(int32_t&nbsp;i =&nbsp;0; i < size - target_len; ++i) {
if&nbsp;(memcmp(buffer + i, target, target_len) ==&nbsp;0) {
memcpy(buffer + i, replacement, target_len);
return0;
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; }
return-1;
}

这段代码在ABL二进制中扫描 UTF-16 编码的字符串"efisp",将其就地替换为"nulls"

作用:修补后的ABL被刷入efisp分区。当这个被修改过的 ABL 在运行时试图按照原来的逻辑从 efisp 分区加载「下一个 EFI」时,它会因找不到名为"nulls" 的分区而静默跳过,从而阻止原始 ABL被递归再次加载,避免了加载链的无限循环。

这一补丁之所以可行,根本原因在于GBL对ABL的完整性校验发生在加载阶段,而不是在ABL运行期间对其自身数据段进行持续校验。一旦GBL完成校验并将控制权移交给被修改的 ABL,后者就能自由运行,包括引导一个与原始执行路径完全不同的自定义EFI载荷。


ABL 二进制的提取:从镜像到 PE32

在对ABL进行修补之前,需要从abl.img(或运行中设备的 abl_a/abl_b 分区)中提取出可操作的 PE32 二进制。这项工作由extractfv完成。

extractfv 实现了一个递归多层扫描器,逻辑如下:

abl.img(原始 flash 镜像)
&nbsp; └── deep_scan()
&nbsp; &nbsp; &nbsp; &nbsp; ├── 扫描 MZ 头 → 提取 PE32 文件
&nbsp; &nbsp; &nbsp; &nbsp; ├── 扫描 BMP 图片(可选)
&nbsp; &nbsp; &nbsp; &nbsp; ├── 扫描 LZMA 压缩块(0x5D 0x00 0x00 魔数)→ 解压后递归 deep_scan()
&nbsp; &nbsp; &nbsp; &nbsp; └── 扫描 EFI Firmware Volume(_FVH 签名)→ 递归进入 FV 解析

其中最关键的是 FV 解析路径。高通 ABL 将核心 LinuxLoader.efi 封装在一个标准 UEFI Firmware Volume 内,该 FV 内部包含若干 FFS(Firmware File System)文件,PE32 节(EFI_SECTION_PE32)可能直接存在,也可能经过 LZMA 压缩封装在 EFI_SECTION_COMPRESSION 中。

extractfv 能够处理所有这些变体:

  • try_lzma_decompress()

    :使用 liblzma 解压 LZMA 压缩块

  • calc_pe_real_size()

    :通过解析 PE 头部的节表精确计算真实文件大小,避免提取多余数据

  • parse_pe_info()

    :识别 ARM64 架构与 EFI_APP/EFI_DRIVER 子系统,用于过滤

默认模式下,extractfv 提取最大的 PE32 文件,输出为 LinuxLoader.efi,这就是后续 ABL 修补的输入。


修补AVB验证绕过

提取出LinuxLoader.efi后,patch_abl工具对其进行一系列精确的二进制修补。所有修补逻辑都在 PatchBuffer()中协调执行,目标是VerifiedBoot.c中的LoadImageAndAuthVB2 函数的编译产物。

整个修补分为以下几个层次。

启动状态锚点定位(补丁3)

int16_t&nbsp;Original[] = {
-1,&nbsp;0x00,&nbsp;0x00,&nbsp;0x34,&nbsp;0x28,&nbsp;0x00,&nbsp;0x80,&nbsp;0x52,
0x06,&nbsp;0x00,&nbsp;0x00,&nbsp;0x14,&nbsp;0xE8,&nbsp;-1,&nbsp;0x40,&nbsp;0xF9,
0x08,&nbsp;0x01,&nbsp;0x40,&nbsp;0x39,&nbsp;0x1F,&nbsp;0x01,&nbsp;0x00,&nbsp;0x71,
0xE8,&nbsp;0x07,&nbsp;0x9F,&nbsp;0x1A,&nbsp;0x08,&nbsp;0x79,&nbsp;0x1F,&nbsp;0x53
};

这是一个包含 8 条 ARM64 指令的字节序列,对应源码中以下逻辑的编译产物:

// VerifiedBoot.c 约 1887 行
if&nbsp;(AllowVerificationError) {
&nbsp; &nbsp; BootState = ORANGE; &nbsp;// CBZ + MOVZ&nbsp;#0x28
}&nbsp;else&nbsp;{
&nbsp; &nbsp; BootState = GREEN; &nbsp;&nbsp;// B + (其他赋值)
}

模式中的 -1 表示该字节是通配符(随编译版本变化的寄存器编号)。匹配到这个模式后:

  1. 从第一个字节的低 5 位提取锁状态寄存器编号(lock_register_num
  2. 记录该模式在文件中的偏移(anchor_offset
  3. 对匹配到的 CBZ Wn, <label> 指令进行修补:将其目标寄存器替换为 WZR(寄存器 31,零寄存器),使分支永远不成立,从而跳过 ORANGE 路径

这一步是后续所有数据流追踪的基础锚点。

反向数据流追踪(补丁4)

定位到锚点后,find_ldrB_instructio_reverse 从锚点地址向前反向扫描,追踪 lock_register_num 寄存器值的来源:

// 从锚点向前追踪,最多 8 次寄存器-栈溢出弹跳
while&nbsp;(now_offset >=&nbsp;0) {
&nbsp; &nbsp; DecodedInst d = decode_at(buffer, now_offset);

if&nbsp;(d.type == INST_PACIASP)&nbsp;break;&nbsp;// 遇到函数边界,停止

// 处理 64 位栈溢出:LDR Xt,[SP,#imm] → 追踪对应的 STR
if&nbsp;(d.type == INST_LDR_X_IMM && d.rn ==&nbsp;31&nbsp;&& d.rt == current_target) { ... }

// 处理字节级栈溢出:LDRB Wt,[SP,#imm] → 追踪对应的 STRB
if&nbsp;(d.type == INST_LDRB_IMM && d.rn ==&nbsp;31&nbsp;&& d.rt == current_target) { ... }

// 找到真正的数据来源:LDRB Wt,[Xn,#off](从全局变量加载)
if&nbsp;(d.type == INST_LDRB_IMM && d.rt == current_target && d.rn !=&nbsp;31) {
// 找到了!触发 source_callback
&nbsp; &nbsp; }
}

找到源头 LDRB Wt, [Xn,&nbsp;#off](即 AllowVerificationError = IsUnlocked())后,source_callback 将其改写为:

write_instr(buffer, now_offset, encode_movz_w(current_target,&nbsp;1));
// 原: LDRB Wt, [Xn,&nbsp;#off] &nbsp; ← 读取 IsUnlocked() 返回值
// 改: MOV Wt,&nbsp;#1&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;← 硬编码 AllowVerificationError = TRUE

这一修改的深层含义:AllowVerificationError = TRUE 不仅跳过了 AVB 校验失败时的拒绝启动逻辑,还阻止了 UpdateRollbackIndex 标志被置位。由于回滚版本更新(TZ_UPDATE_ROLLBACK_VERSION)和 TZ 软熔断(TZ_BLOW_SW_FUSE_ID)都只在 UpdateRollbackIndex == TRUE 时执行,这一补丁同时防止了 TZ 对设备的永久性标记。

正向数据流追踪(补丁5)

找到源头后,track_forward_patch_strb 从该源指令向后正向扫描,追踪寄存器值的消费点。追踪引擎使用 LocSet 数据结构维护一个「活跃数据位置集合」,处理寄存器间拷贝、32/64 位栈溢出与重载:

// LocSet 追踪的操作类型:
// - LOC_REG: &nbsp; 当前在某个寄存器中
// - LOC_STK64: 已溢出到栈上(64 位)
// - LOC_STK8: &nbsp;已溢出到栈上(8 位)

// 当发现 STRB Wt, [Xn,&nbsp;#imm],且 Wt 在 LocSet 中时:
write_instr(buffer, off, strb_with_reg(d.raw,&nbsp;31));
// 原: STRB Wt, [Xbase,&nbsp;#off] &nbsp; ← 写入 Data.IsUnlocked = AllowVerificationError
// 改: STRB WZR, [Xbase,&nbsp;#off] &nbsp;← 强制写入 0

Data.IsUnlocked 是 KMRotAndBootState 结构体的成员,该结构体通过 KeyMasterSetRotAndBootState() 传递给 TEE。TEE 用 IsUnlocked 的值参与 ROT(Root of Trust)摘要计算:

RotDigest = SHA256(PublicKey || IsUnlocked)

如果IsUnlocked = 1 到达 TEE,TEE 的 ROT 与出厂预期不符,会拒绝释放 FBE(File-Based Encryption)数据加密密钥,导致用户数据完全不可访问。补丁 5 强制写入 0,确保 TEE 收到的 ROT 信息与未解锁状态一致,数据分区正常解密。

cmdline状态字符串修补(补丁2)

int32_tpatch_adrl_unlocked_to_locked(char* buffer,&nbsp;int32_t&nbsp;size,&nbsp;uint64_t&nbsp;load_base)&nbsp;{
// 在二进制中定位 ADRP+ADD 指令对序列
// 第一对加载 "unlocked" 字符串地址
// 第二对加载 "locked" 字符串地址
// 第三对加载 "androidboot.vbmeta.device_state" 字符串(确认上下文)

// 将第一对 ADRP+ADD 的目标寄存器改为第二对的寄存器
// 效果:两者都指向 "locked"
uint32_t&nbsp;new_adrp = adrp_with_rd(b0.raw, xa);
uint32_t&nbsp;new_add &nbsp;= add_with_reg(b1.raw, xa);
&nbsp; &nbsp; write_instr(buffer, i, &nbsp; &nbsp; new_adrp);
&nbsp; &nbsp; write_instr(buffer, i +&nbsp;4, new_add);
}

这一补丁修改内核启动参数中 androidboot.vbmeta.device_state 的值,从 unlocked 改为 locked。Android 框架层(如 Google Play Services、SafetyNet/Play Integrity)通过读取这个属性判断 BL 状态,如果不修改该字符串,即便 TEE 认为设备已锁,Android 层面仍会探测到解锁状态,银行类应用等将无法运行。

定位方式完全依赖编译器保留的字符串:通过 ADRP+ADD 指令对(高通 AARCH64 ABI 下加载页对齐全局地址的标准方式)来找到加载目标字符串的代码位置,无需知道任何固定偏移。


OPPO/OnePlus警告屏去除定制补丁

针对OPPO/一加设备,patch_warning负责去除开机时的「橙色状态」警告界面:

boolpatch_warning(char* buffer,&nbsp;int32_t&nbsp;size,&nbsp;int32_t&nbsp;global_var_offset)&nbsp;{
// 1. 通过字符串 "Orange State\n" 定位警告代码
int32_t&nbsp;warn_off = find_warning_offset(buffer, size,&nbsp;0);

// 2. 向上搜索控制是否显示警告的 CBZ 指令
for&nbsp;(int32_t&nbsp;i = warn_off -&nbsp;4; i >= max_search_range; i -=&nbsp;4) {
if&nbsp;(d.type == INST_CBZ_W) {
// 3. 反向追踪该 CBZ 的判断值来源
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; find_ldrB_instructio_reverse(buffer, size, i, d.rt, &offset, empty_source_callback);

// 4. 确认来源是锁状态全局变量(与前面记录的 global_var_offset 匹配)
if&nbsp;(offset != global_var_offset)&nbsp;continue;

// 5. 将 CBZ Wt 改为 CBZ WZR(永远不成立,跳过警告显示)
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; write_instr(buffer, i, change_rt(&d,&nbsp;31));
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; }
}

关键点在于第4步的确认:只对来源是「锁状态全局变量」的 CBZ 进行修改,不盲目 NOP 掉所有 CBZ,从而避免破坏其他功能逻辑。


ARM64 指令引擎

上述所有修补逻辑都依赖一个轻量级的ARM64指令解码与编码引擎,支持 20+ 种指令类型:

| 指令类别 | 覆盖类型 | | — | — | | 内存访问 | LDRB/STRB(立即数/前索引/后索引)、LDR/STR(32/64 位) | | 寄存器操作 | MOV X/W、MOVZ W | | 地址计算 | ADRP、ADD X(含 LSL#12) | | 条件分支 | CBZ/CBNZ(32/64 位)、B.cond | | 无条件跳转 | B、BL | | 特殊指令 | PACIASP(函数边界标记)、NOP、RET |

所有指令使用统一的 DecodedInst 结构表示,解码采用优先级表(priority table)驱动,避免编码空间重叠带来的歧义。编码辅助函数支持原地修改:

uint32_tadrp_with_rd(uint32_t&nbsp;raw,&nbsp;uint8_t&nbsp;new_rd); &nbsp;// 替换 ADRP 的目标寄存器
uint32_tadd_with_reg(uint32_t&nbsp;raw,&nbsp;uint8_t&nbsp;new_reg); &nbsp;// 替换 ADD 的 Rd 和 Rn
uint32_tstrb_with_reg(uint32_t&nbsp;raw,&nbsp;uint8_t&nbsp;new_rt); &nbsp;// 替换 STRB 的 Rt
uint32_tencode_movz_w(uint8_t&nbsp;rd,&nbsp;uint16_t&nbsp;imm16); &nbsp; &nbsp;// 构造 MOVZ Wd,&nbsp;#imm16
uint32_tchange_rt(DecodedInst* inst,&nbsp;uint8_t&nbsp;new_rt);&nbsp;// 通用 Rt 替换
uint32_tchange_to_b(uint32_t&nbsp;raw); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// CBZ/CBNZ 转为无条件 B

自定义SuperFastboot

修补后的ABL在efisp分区加载自身时不再递归加载原始efisp,而是执行项目自带的 LinuxLoader.efi(即 SuperFastboot 载荷)。

ELF注入机制

elf_inject工具将修补后的 ABL.efi 嵌入 loader.elf(SuperFastboot 的未链接 ELF 二进制)中:

// loader.elf 中预留了一个占位符节区
__attribute__((section(".abl_placeholder"), used))
unsignedint&nbsp;dist_ABL_efi_len =&nbsp;16;
__attribute__((section(".abl_placeholder"), used))
unsignedchar&nbsp;dist_ABL_efi[] =&nbsp;"ABL_PLACEHOLDER!";

elf_inject 扫描 ELF 的节表,找到包含 "ABL_PLACEHOLDER!" 的节区,将其替换为实际的 ABL.efi 数据,同时正确更新节大小、程序头(Phdr)的 FileSiz/MemSiz 字段以及节表偏移(e_shoff),确保输出的 ELF 结构合法。

运行时启动逻辑

LinuxLoader.efiLinuxLoaderEntry 启动入口实现了以下决策树:

LinuxLoaderEntry()
&nbsp; ├── ReadAllowUnlockValue() → 检测 OEM Unlock 开关
&nbsp; │ &nbsp; &nbsp; └── 若未开启(或读取失败)→ 直接加载内嵌的 ABL.efi,普通启动
&nbsp; ├── WaitForVolumeDownKey(3000ms) → 等待音量减键
&nbsp; │ &nbsp; &nbsp; ├── 按下音量减 → 进入 SuperFastboot 模式
&nbsp; │ &nbsp; &nbsp; ├── 按下音量加 → 进入 Recovery(扩展功能)
&nbsp; │ &nbsp; &nbsp; └── 超时无输入 → 加载内嵌 ABL.efi,普通启动
&nbsp; └── FastbootInitialize() → 启动 Fastboot 服务

BootEfiImage() 通过标准的 gBS->LoadImage() + gBS->StartImage() UEFI 调用链式启动内嵌的 ABL.efi。这意味着整个引导链实际上是:

GBL → 修补后的 ABL(SuperFastboot 壳)
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;└──[用户无操作]──> 原始 ABL.efi(内嵌于壳中,继续正常引导)
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;└──[按音量减]────> Fastboot 服务(SuperFastboot 模式)

SuperFastboot 的关键能力

SuperFastboot 基于高通 QcomModulePkg 的 FastbootLib,在假回锁状态下提供了原生 Fastboot 所不具备的能力:

  • fastboot flashing unlock

    unlock_critical:BL 解锁操作,不触发数据清除

  • fastboot flashing lock

    :重新锁定 BL,触发数据清除

  • fastboot flash <partition> <file>

    :全分区刷写

  • fastboot boot xxx.efi

    :临时启动任意 EFI 文件(无需刷写)

fastboot flashing unlock 不触发数据清除的原因:高通 ABL 在处理解锁命令时会检查当前 BootState。由于此时 ABL 已被修补(BootState=GREEN,IsUnlocked=0),设备表现为已锁状态,执行解锁操作时不满足触发数据清除的条件判断,因此跳过了清除流程。


工具链与构建流程

整个方案由多个独立工具组成,通过 make 驱动的构建系统统一编排:

gbl_root_canoe/
├── submodules/
│ &nbsp; ├── ablfvextractor/ &nbsp; extractfv — ABL 固件卷解包工具(C,依赖 liblzma)
│ &nbsp; ├── patcher/ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;patch_abl — ABL 二进制修补工具(C,无依赖)
│ &nbsp; ├── elflinker/ &nbsp; &nbsp; &nbsp; &nbsp;elf_inject — ELF 载荷注入工具(C)
│ &nbsp; └── uefi/edk2/ &nbsp; &nbsp; &nbsp; &nbsp;LinuxLoader.efi — SuperFastboot 载荷(UEFI/EDK2)
└── targets/
&nbsp; &nbsp; ├── toolkit_linux/ &nbsp; &nbsp;Linux PC 工具包构建目标
&nbsp; &nbsp; ├── toolkit_windows/ &nbsp;Windows PC 工具包构建目标(MinGW 交叉编译)
&nbsp; &nbsp; └── magisk_module/ &nbsp; &nbsp;Magisk 模块构建目标(Android NDK 交叉编译)

使用方法

在PC电脑上依次执行:

1. extractfv abl.img -o ./build/
&nbsp; &nbsp; &nbsp; &nbsp; → 提取 LinuxLoader.efi(ABL 核心 PE32)

2. patch_abl LinuxLoader.efi ABL.efi
&nbsp; &nbsp; &nbsp; &nbsp; → 执行所有补丁,输出修补后的 ABL.efi

3. elf_inject loader.elf ABL.efi ABL_with_superfastboot.efi
&nbsp; &nbsp; &nbsp; &nbsp; → 将修补后的 ABL 嵌入 SuperFastboot 壳,输出最终文件

4. fastboot flash efisp ABL_with_superfastboot.efi
&nbsp; &nbsp; &nbsp; &nbsp; → 刷入 efisp 分区

Magisk模块版本将以上步骤封装为设备端脚本,在已Root的设备上通过Root管理器(KernelSU/Magisk/APatch)直接执行,免去PC操作。


整体效果

方案在几个层面保证了跨设备、跨 ABL 版本的鲁棒性:

字符串锚定而非地址硬编码 所有代码位置均通过编译器保留的字符串常量("unlocked""locked""androidboot.vbmeta.device_state""Orange State\n""Your device has been unlocked")动态定位。字符串在 ABL 重编译后地址会变化,但内容不会变化,ADRP+ADD 寻址模式也不会变化。

指令模式匹配而非固定字节序列 启动状态锚点(Original[])使用带通配符的模式而非精确字节序列,通配符覆盖随编译器寄存器分配变化的字段(低 5 位寄存器编号),只匹配控制流结构固定的部分。

数据流追踪适应编译器优化 补丁 4/5 的反向/正向追踪引擎能够跟踪寄存器值经过多层栈溢出(STR Xt,[SP,#imm]/LDR Xt,[SP,#imm])和字节溢出(STRB Wt,[SP,#imm]/LDRB Wt,[SP,#imm])之后的最终位置,最多支持 8 次「弹跳」,应对编译器激进优化下的寄存器重用和溢出重排。

函数边界保护 所有追踪都以 PACIASP(ARM 指针认证指令,同时也是高通 ABL 中标记函数入口的约定)作为硬性停止条件,防止追踪越过函数边界误改其他函数的代码。

分级失败处理 补丁分为「关键」(失败则中止并返回 false)、「重要但非关键」(失败打印警告继续)、「可选」(失败静默忽略)三个级别。这确保了在 cmdline 字符串补丁失败的 ABL 版本上,设备仍能正常启动,只是状态字符串暴露,不会因补丁失败导致砖机。

经过以上所有补丁和载荷注入后,设备的状态:

| 项目 | 状态 | | — | — | | TEE BootState | GREEN(已锁,TEE 正常释放 FBE 密钥) | | androidboot.vbmeta.device_state | locked | | 用户数据 | 完整可访问 | | SafetyNet / Play Integrity | 基础级别通过(取决于设备其他因素) | | Fastboot 能力 | 完整,含解锁/锁定/刷写/临时启动 | | OTA 兼容性 | 需 OTA 前降级 ABL 版本,或模块脚本自动处理 | | BL 解锁状态 | 维持未解锁(物理意义上),或可通过 SuperFastboot 二次解锁 |

本方案的本质是:在 GBL 校验之后、内核启动之前的 UEFI 空间内,通过精确的二进制修补让 ABL 的安全状态决策输出与未解锁状态保持一致,从而在不触碰 xBL 及 TEE 的前提下,实现了对 AVB 和设备状态上报机制的完全控制。

当然,这种补丁方式已经有了更优雅的升级版本,基于GBL启动链Hook技术勾住每一个需要补丁的地方,动态补丁兼容性更好。

具体细节与使用方法点击阅读原文下载:高通8Gen5的gbl解锁隐藏技术实现原理分析.pdf


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:软件安全与逆向分析 非虫 非虫《gblrootcanoe隐藏BL状态原理分析》

评论:0   参与:  0