BCD 文件内容的解读

观察环境:Windows 10 专业版 20H2

概述

BCD 是 Windows 引导信息的记录载体文件,无论是 UEFI 模式还是 BIOS 模式,都会用到。

如果是 BIOS 模式引导,BCD 文件位于引导分区(引导分区有可能和系统分区为同一个分区)的 \Boot 目录下;如果是 UEFI 模式引导,BCD 文件位于 ESP 分区的 EFI\Microsoft 目录(也许是其某子目录)下。

BCD 文件的操作,除了官方的 bcdedit.exe 之外,常用的还有 GUI 工具 EasyBCD。在 PE 环境下,由于缺乏 .net framework 环境,EasyBCD 无法执行。

细节

BCD 文件是一个可以被注册表服务加载的配置单元文件。事实上在正常的系统中,注册表中的 BCD00000000 就是它。在 PE 环境下,也可以将之加载到 HKLM 下,将加载点命名为,比如 HAHAHA。之后就可以近距离观察它的组织结构。

在顶级路径下,有两个 key,名字分别为 DescriptionObjects。光看名字,前者就不会是重点。其下有四个 value。GuidCache 的类型是 REG_BINARY,作用未知;KeyNameREG_SZ 类型,值为 BCD00000000。剩余两个都是 REG_DWORD 类型,SystemTreatAsSystem,值都为 1

Objects 下,是一系列 GUID 形式的 key,各个 key 的组织结构都相当一致。每个 key 下,又各有两个 key,一个是 Description,但只包含一个 REG_DWORD 类型的名为 Type 的 value。另一个是 Elements,包括一组形式为 8 位 16 进制数字的 key,每个 key 包括一个名为 Element 的 value,**但是**,这个 value 的类型并不完全相同。

事实上,Elements 下的 key,其名字均为预定义好的配置项 ID,从而其下的 Element value 的数据类型也是预先就确定了的。

Objects 下的 key 之间可以有继承关系,这里的继承,也就是被继承的 key 下所有的 value 都可以算作继承者 key 的一部分,也可以看作是一种包含关系。存储继承关系的 value 名字为 14000006,可以存在不止一个被继承者。这些 key 在存储中的原始形式是 GUID,但是,在使用 BCD 文件的官方编辑工具 bcdedit.exe 进行编辑时,有若干 key 是具有公开的别名的,例如 {default}{bootmgr} 这样的形式,还有 {current},从后者来看这种别名是一种关联映射,可以改变指向的,而非完全都是固定的匹配对。据观察,bootmgr 的 GUID 在两台不同的设备上均为 {9dea862c-5cdd-4e70-acc1-f32b344d4795}{globalsettings} 均为 {7ea2e1ac-2e61-4728-aaa3-896d9d0a9f0e}{bootloadersettings} 均为 {6efb52bf-1766-41db-a6b3-0ee5eff72bd7},而 {current} 则各不相同。

使用命令 bcdedit.exe /enum 可以枚举该命令以某种方式判定出的需要展示给使用者的条目(或者称为项,后文可能会混用“条目”和“项”),以及每个条目下的若干值。当你指定 /v 参数时,则条目的 ID 就会以 GUID 的本来面目呈现,否则,就会显示为别名的形式。如果仅希望查看指定条目下的值,在 /enum 后跟上其 ID 即可。如 bcdedit.exe /enum {current}。以下为在一台设备上的输出实例:

bcdedit.exe 列出的值,都是有名字的,例如 devicepath 这样的,这是因为它们都是预定义好的。预定义的含义,可以参考微软官方文档透露出来的信息:https://docs.microsoft.com/zh-cn/previous-versions/windows/desktop/bcd/bcd-enumerations。注意到 URL 中存在“先前版本”字样,但事实上在最新的文档中心内没有找对对应的内容。

如果要修改这些值,则可以使用 bcdedit.exe/set 命令。如 bcdedit.exe /set {current} path \WINDOWS\system32\winload.efi。进一步地,由于你可能参考前述 URL,已经知道 path 这个 value 的名字是 BcdLibraryElementTypes 枚举类型中的 BcdLibraryString_ApplicationPath,其对应的数值是十六进制的 12000002,那么,在注册表编辑器里找到这个 key,然后直接修改它下面的 Element 值的内容,是完全可行的。

特别需要提出的是,bcdedit.exe 支持对指定 BCD 文件的离线编辑,只要加 /store filename 的参数指定即可。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注