在本地生成禁用校验的 vbmeta 镜像

您所在的位置:网站首页 fastboot怎么停止 在本地生成禁用校验的 vbmeta 镜像

在本地生成禁用校验的 vbmeta 镜像

2024-07-15 13:44| 来源: 网络整理| 查看: 265

前言 调查 实践 前言

vbmeta 分区是 Android AVB 机制的重要组成部分,其中包含了设备上部分分区的校验信息。有时候出于调试需要,我们需要修改设备上一些分区的内容,此时为了能使设备顺利启动,我们还需要额外禁用 vbmeta 分区中的校验。众所周知,我们可以通过执行 fastboot --disable-verity --disable-verification flash vbmeta vbmeta.img 来刷入一个 vbmeta 镜像,并同时禁用这个镜像中的校验。但是,fastboot 并不会修改原镜像,也没有提供导出这个禁用了校验的镜像的能力。那么有没有什么办法能够从原镜像获得禁用了校验的镜像呢?

调查

首先,可以看看 fastboot 是怎么做的:

system/core/fastboot/fastboot.cpp

static void rewrite_vbmeta_buffer(struct fastboot_buffer* buf, bool vbmeta_in_boot) { // Buffer needs to be at least the size of the VBMeta struct which // is 256 bytes. if (buf->sz < 256) { return; } std::string data; if (!android::base::ReadFdToString(buf->fd, &data)) { die("Failed reading from vbmeta"); } uint64_t vbmeta_offset = 0; if (vbmeta_in_boot) { // Tries to locate top-level vbmeta from boot.img footer. uint64_t footer_offset = buf->sz - AVB_FOOTER_SIZE; if (0 != data.compare(footer_offset, AVB_FOOTER_MAGIC_LEN, AVB_FOOTER_MAGIC)) { die("Failed to find AVB_FOOTER at offset: %" PRId64, footer_offset); } const AvbFooter* footer = reinterpret_cast(data.c_str() + footer_offset); vbmeta_offset = be64toh(footer->vbmeta_offset); } // Ensures there is AVB_MAGIC at vbmeta_offset. if (0 != data.compare(vbmeta_offset, AVB_MAGIC_LEN, AVB_MAGIC)) { die("Failed to find AVB_MAGIC at offset: %" PRId64, vbmeta_offset); } fprintf(stderr, "Rewriting vbmeta struct at offset: %" PRId64 "\n", vbmeta_offset); // There's a 32-bit big endian |flags| field at offset 120 where // bit 0 corresponds to disable-verity and bit 1 corresponds to // disable-verification. // // See external/avb/libavb/avb_vbmeta_image.h for the layout of // the VBMeta struct. uint64_t flags_offset = 123 + vbmeta_offset; if (g_disable_verity) { data[flags_offset] |= 0x01; } if (g_disable_verification) { data[flags_offset] |= 0x02; } unique_fd fd(make_temporary_fd("vbmeta rewriting")); if (!android::base::WriteStringToFd(data, fd)) { die("Failed writing to modified vbmeta"); } buf->fd = std::move(fd); lseek(buf->fd.get(), 0, SEEK_SET); }

可以很简单的发现,fastboot 在刷入镜像前在缓冲区中对镜像的第 123 字节的最后两位进行了置 1 操作,其中 --disable-verity 对应第 123 字节的最后一位, --disable-verification 则对应第 123 字节的倒数第二位。

不妨进一步看看:

external/avb/libavb/avb_vbmeta_image.h

typedef struct AvbVBMetaImageHeader { ...... /* 120: Flags from the AvbVBMetaImageFlags enumeration. This must be * set to zero if the vbmeta image is not a top-level image. */ uint32_t flags; ...... } AVB_ATTR_PACKED AvbVBMetaImageHeader;

可以看到,vbmeta 镜像从第 120 字节开始存储的是一个名为 flags 的大端 32 位无符号类型整数,也就是说这个整数的覆盖范围是第 120 到 123 字节。上面的修改实际上正好修改了这个整数的最低两位。

那么,除了上面提到的两个“禁用校验”位,这个 flags 中其它的位有什么含义吗?

external/avb/libavb/avb_vbmeta_image.h

/* Flags for the vbmeta image. * * AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED: If this flag is set, * hashtree image verification will be disabled. * * AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED: If this flag is set, * verification will be disabled and descriptors will not be parsed. */ typedef enum { AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED = (1


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3