Magisk root 原理分析之二 :Android Verified Boot (AVB)

mac2026-08-05  38

1. Android Verified Boot (AVB) 或称 Verified Boot 2.0 简介

官方解释:验证用户设备上运行的软件完整性。它通常从设备固件的只读部分开始,该部分加载代码并仅在通过密码验证代码是授权的并且没有任何已知的安全漏洞之后才执行代码。

AVB 2.0 引入一个新的分区:vbmeta.img(verified boot metadata),其包含分区的哈希, 下面是通过avbtool解析出的信息

Magisk$ ./avbtool info_image --image vbmeta.img Minimum libavb version: 1.0 Header Block: 256 bytes Authentication Block: 576 bytes Auxiliary Block: 3776 bytes Algorithm: SHA256_RSA4096 Rollback Index: 0 Flags: 0 Release String: 'avbtool 1.1.0' Descriptors: Chain Partition descriptor: Partition Name: system Rollback Index Location: 1 Public key (sha1): cdbb77177f731920bbe0a0f94f84d9038ae0617d Chain Partition descriptor: Partition Name: vm-linux Rollback Index Location: 11 Public key (sha1): 1b75d7e33ff1ad3f71c2bd9b164595cc599088b6 Hashtree descriptor: Version of dm-verity: 1 Image Size: 990666752 bytes Tree Offset: 990666752 Tree Size: 7806976 bytes Data Block Size: 4096 bytes Hash Block Size: 4096 bytes FEC num roots: 2 FEC offset: 998473728 FEC size: 7897088 bytes Hash Algorithm: sha1 Partition Name: vendor Salt: ...............................

其将所需校验的内容在编译时就计算好,打包到这个分区,启动过程中 BootLoader 只需要校验 vbmeta.img,就能确认 vbmeta 内的数据是否可信。再用 vbmeta 中的数据去比对 boot.img,dtbo,system.img,vendor.img

2. 校验流程

vbmeta分区中的VBMeta结构是通过加密签名,在启动阶段其会检查签名验证vbmeta分区是否可信,从而信任boot、system、vendor分区的哈希值,其中boot、dtbo等较小分区直接存储的是的哈希值,以及其他较大分区的是以哈希树的方式存储,VBMeta中只存放哈希树的根哈希。

校验vbmeta可信后,对于boot、dtbo分区,将整个镜像加载到内存中,直接计算其相应的哈希值与vameta中的值进行比较,如无法验证通过将无法继续启动

对于system、vendor这种很大的分区,直接将其加载进内存进行哈希校验,是耗时且很不换算,其采用哈希树的方式进行校验,其验证会在加载数据进内存的过程中持续进行,系统在运行时计算哈希树的根哈希,并于vameta中的根哈希进行比较,如果在某个时间点计算出的根哈希值与预期根哈希值不一致,系统便不会使用相应数据,而且 Android 会出现错误。这个校验是采用dm-verity实现

3. 启动流程

在启动时首先会检查设备启动状态,设备状态用于指明能够以多大的自由度将软件刷写到设备上,以及是否强制执行验证。设备状态为 LOCKED 和 UNLOCKED。状态为 LOCKED 的设备禁止您将新软件刷写到设备上,而状态为 UNLOCKED 的设备允许您进行修改。这也是为什么root前需要对设备进行解锁。

当设备开机后,引导加载程序会先检查设备状态是 LOCKED 还是 UNLOCKED。如果设备状态为 UNLOCKED,引导加载程序会向用户显示警告,然后继续启动,即使加载的操作系统校验不通过也是如此。

验证启动问题分为以下几类:

绿色:设备已LOCKED且未使用可由用户设置的信任根

黄色:针对设有自定义信任根的已锁定设备的警告屏幕

橙色:针对未锁定设备的警告屏幕

红色 (EIO):针对 dm-verity 损坏的警告屏幕

红色(未找到操作系统):未找到有效的操作系统

详细流程

在lk阶段其会检查设备的启动状态,即判断是否处于lock状态,如果处于lock状态,如果校验失败系统将无法启动,如果处于unlock状态即使校验出错也会继续启动,这里解锁就是fastboot flashing unlock

确定设备的启动状态后,LK阶段会通过vbmeta里数据校验boot、dtbo等,下面这段就是debug机器的串口log

avb_slot_verify.c:481: DEBUG: Loading vbmeta struct from partition 'vbmeta'. Partition found: vbmeta Partition found: recovery avb_slot_verify.c:476: DEBUG: Loading vbmeta struct in footer from partition 'recovery'. Partition found: recovery avb_footer.c:41: ERROR: Footer magic is incorrect. avb_slot_verify.c:453: DEBUG: vbmeta_system: No footer detected. avb_slot_verify.c:481: DEBUG: Loading vbmeta struct from partition 'vbmeta_system'. avb_slot_verify.c:181: DEBUG: boot: Loading entire partition. Partition found: boot avb_slot_verify.c:240: DEBUG: boot: success: Image verification completed avb_slot_verify.c:181: DEBUG: dtbo: Loading entire partition. Partition found: dtbo avb_slot_verify.c:240: DEBUG: dtbo: success: Image verification completed State: Unlocked, AvbSlotVerify returned OK, continue boot DateSupport: 1 VB2: Authenticate complete! boot state is: green VB2: boot state: green(0) //这里由于设备未解锁,所以传入值是green

通过command line 将状态传递给kernel,这里即verifiedbootstate,同时其也传递了vbmeta中的其他信息

#cat proc/cmdline androidboot.verifiedbootstate=green androidboot.keymaster=1 androidboot.vbmeta.device=PARTUUID=ff3da... androidboot.vbmeta.avb_version=1.0 androidboot.vbmeta.device_state=locked androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=9024 androidboot.vbmeta.digest=f1abae9.... androidboot.veritymode=disabled

在内核启动后, init在校验时首先会读取传入的verifiedbootstate判断设备状态,这块处理流程比较复杂,只是粗略的看下,以后需要再深入研究

---------- https://android.googlesource.com/platform/system/core/+/refs/heads/master/fs_mgr/libfs_avb/util.cpp ---------- bool IsDeviceUnlocked() { std::string verified_boot_state; if (fs_mgr_get_boot_config("verifiedbootstate", &verified_boot_state)) { return verified_boot_state == "orange"; } return false; } ----------- https://android.googlesource.com/platform/system/core/+/refs/heads/master/fs_mgr/fs_mgr_boot_config.cpp ----------- // Tries to get the boot config value in device tree, properties and // kernel cmdline (in that order). Returns 'true' if successfully // found, 'false' otherwise. bool fs_mgr_get_boot_config(const std::string& key, std::string* out_val) { FS_MGR_CHECK(out_val != nullptr); // firstly, check the device tree if (is_dt_compatible()) { std::string file_name = get_android_dt_dir() + "/" + key; if (android::base::ReadFileToString(file_name, out_val)) { if (!out_val->empty()) { out_val->pop_back(); // Trims the trailing '\0' out. return true; } } } // next, check if we have "ro.boot" property already *out_val = android::base::GetProperty("ro.boot." + key, ""); if (!out_val->empty()) { return true; } // finally, fallback to kernel cmdline, properties may not be ready yet if (fs_mgr_get_boot_config_from_kernel_cmdline(key, out_val)) { return true; } return false; } #启动阶段init log init: [libfs_avb]Returning avb_handle with status: Success init: [libfs_avb]: Error verifying vbmeta image: OK_NOT_SIGNED init: [libfs_avb]: allow verification error is not allowed init: [libfs_avb]Failed to load vbmeta: /dev/block/dm-0 init: Failed to load offline vbmeta for /system init: Fallback to built-in hashtree for /system init: [libfs_avb]Built verity table:.....

安卓启动后也可以通过属性看到设备状态

#getprop [ro.boot.vbmeta.avb_version]: [1.0] [ro.boot.vbmeta.device_state]: [locked] [ro.boot.vbmeta.digest]: [f1abae...] [ro.boot.vbmeta.hash_alg]: [sha256] [ro.boot.vbmeta.size]: [9024] [ro.boot.verifiedbootstate]: [green] [ro.boot.veritymode]: [disabled]

如有错误,欢迎指正,探讨

参考链接:

Android Verified Boot (AVB)

Android Verified Boot 2.0

Android Verified Boot 2.0 最新安卓P AVB詳解

verified boot

最新回复(0)