BCD详细测试说明

2021年12月03日 技术资料 2660 views 0

一、BCD简介
BCD全称Boot Configuration Data(引导配置数据),了解BCD之前,需要先大体了解一下windows系统启动过程:


BIOS-->MBR-->DPT-->DBR-->BootMgr-->BCD-->Winload.exe(bootmgfw.efi)-->内核加载-->整个windows系统

 Ctrl + F 可以快速搜索关键词

说明:
1.BCD是一种用于启动时的配置数据固件独立数据库,存储包含启动配置参数,控制操作系统的启动方式等(具体组成可以参考“BCD对应注册表成员分析”);

2.BCD是由EFI\Microsoft\Boot\bootmgr.efi调用;

3.PMC的GPT版本其实就是替换了EFI\Microsoft\Boot\bootmgfw.efi系统引导文件,那么BCD是先于PMC执行的。

 

二、BCD对应注册表成员分析
(以下分析乃结合网上资源与观察现象总结而来,并非官方结论)

1.BCD内容对应于注册表HKEY_LOCAL_MACHINE\BCD00000000下的所有键值,Description为总描述,里面有四个键值,分别为:GuidCache,KeyName,System,TreatAsSystem,这四个键值了解即可;

2.重点了解HKEY_LOCAL_MACHINE\BCD00000000\Objects项,其下包含若干子键,每个子键功能各不一样,每个子键包含Description和Elements,Description为描述,了解即可,Elements详细说明该子键功能与作用;

3.HKEY_LOCAL_MACHINE\BCD00000000\Objects下面的键值大体列举如下:

Startup Interrupt Menu、ME Configuration Menu、IDER BOOT CDROM、Boot Menu、Diagnostic Splash Screen、Windows Boot Manager、Windows Memory Test、Setup、IDER BOOT Floppy、Rescue and Recovery、USB CD、USB FDD、ATAPI CD0、ATA HDD0、ATA HDD1、ATA HDD2、USB HDD、PCI LAN、Windows Resume Application、Windows 8.1、Windows Recovery Environment、Windows Recovery;

通过以上键值,可以初步了解BCD的组成及作用,其详细结构参见4;

4.HKEY_LOCAL_MACHINE\BCD00000000\Objects\Elements里面包含若干子键,每个键值对应固定且唯一的功能,举例如下:


typedef enum BcdBootMgrElementTypes {
  BcdBootMgrObjectList_DisplayOrder        = 0x24000001,  //BCD对象应该显示的顺序
  BcdBootMgrObjectList_BootSequence       = 0x24000002,  //启动顺序
  BcdBootMgrObject_DefaultObject           = 0x23000003,  //默认启动选项
  BcdBootMgrInteger_Timeout               = 0x25000004,  //启动选择菜单显示时间
  BcdBootMgrBoolean_AttemptResume         = 0x26000005,  //尝试重启系统
  BcdBootMgrObject_ResumeObject           = 0x23000006,  //重启对象
  BcdBootMgrObjectList_ToolsDisplayOrde      = 0x24000010,  //启动管理器工具显示列表
  BcdBootMgrBoolean_DisplayBootMenu       = 0x26000020,  //显示启动菜单
  BcdBootMgrBoolean_NoErrorDisplay          = 0x26000021,  //是否显示错误
  BcdBootMgrDevice_BcdDevice                = 0x21000022,  //启动设备
  BcdBootMgrString_BcdFilePath                = 0x22000023,  //启动文件路径
  BcdBootMgrBoolean_ProcessCustomActionsFirst  = 0x26000028,  //是否处理自定义引导
  BcdBootMgrIntegerList_CustomActionsList        = 0x27000030,  //自定义启动列表
  BcdBootMgrBoolean_PersistBootSequence        = 0x26000031  //多启动判断
} BcdBootMgrElementTypes;

 


typedef enum BcdDeviceObjectElementTypes {
  BcdDeviceInteger_RamdiskImageOffset            = 0x35000001,  //RAM磁盘映像偏移
  BcdDeviceInteger_TftpClientPort                = 0x35000002,  //TFTP客户端口
  BcdDeviceInteger_SdiDevice                     = 0x31000003,  //SDI设备
  BcdDeviceInteger_SdiPath                       = 0x32000004,  //SDI设备路径
  BcdDeviceInteger_RamdiskImageLength            = 0x35000005,  //RAM磁盘映像长度
  BcdDeviceBoolean_RamdiskExportAsCd             = 0x36000006,  //磁盘映像作为CD
  BcdDeviceInteger_RamdiskTftpBlockSize          = 0x36000007,  //TFTP磁盘块大小
  BcdDeviceInteger_RamdiskTftpWindowSize         = 0x36000008,  //TFTP磁盘窗口大小
  BcdDeviceBoolean_RamdiskMulticastEnabled       = 0x36000009,  //启动或禁用多播RAM文件
  BcdDeviceBoolean_RamdiskMulticastTftpFallback  = 0x3600000A,  //允许TFTP多播失败
  BcdDeviceBoolean_RamdiskTftpVarWindow          = 0x3600000B  //启动或禁用TFTP窗口变量
} BcdDeviceObjectElementTypes;


 

typedef enum BcdLibrary_DebuggerType {
  DebuggerSerial  = 0,             //串口调试
  Debugger1394    = 1,           //1394调试
  DebuggerUsb     = 2,           //USB调试
  DebuggerNet     = 3            //网络调试
} BcdLibrary_DebuggerType;

 

typedef enum BcdLibrary_SafeBoot {
  SafemodeMinimal   = 0,         //通过指定注册表键值加载驱动或者服务
  SafemodeNetwork   = 1,         //通过指定注册表键值加载驱动或者服务
  SafemodeDsRepair  = 2          //启动系统进入修复模式
} BcdLibrary_SafeBoot;

 

typedef enum BcdLibraryElementTypes {
  BcdLibraryDevice_ApplicationDevice                  = 0x11000001,  //系统启动程序设备
  BcdLibraryString_ApplicationPath                    = 0x12000002,  //启动程序路径
  BcdLibraryString_Description                        = 0x12000004,  //程序名称
  BcdLibraryString_PreferredLocale                    = 0x12000005,  //首选区域设置
  BcdLibraryObjectList_InheritedObjects               = 0x14000006,  //当前对象应该继承的元素
  BcdLibraryInteger_TruncatePhysicalMemory            = 0x15000007,  //引导程序最大物理内存
  BcdLibraryObjectList_RecoverySequence               = 0x14000008,  //引导程序顺序
  BcdLibraryBoolean_AutoRecoveryEnabled               = 0x16000009,  //是否自动恢复
  BcdLibraryIntegerList_BadMemoryList                 = 0x1700000a,  //系统错误记忆列表
  BcdLibraryBoolean_AllowBadMemoryAccess              = 0x1600000b,  //是否使用错误内存
  BcdLibraryInteger_FirstMegabytePolicy               = 0x1500000c,  //首字节内存如何使用
  BcdLibraryInteger_RelocatePhysicalMemory            = 0x1500000D,  //重新分配物理内存
  BcdLibraryInteger_AvoidLowPhysicalMemory            = 0x1500000E,  //指定最小物理内存
  BcdLibraryBoolean_DebuggerEnabled                   = 0x16000010,  //DEBUG启动
  BcdLibraryInteger_DebuggerType                      = 0x15000011,  //DEBUG类型
  BcdLibraryInteger_SerialDebuggerPortAddress         = 0x15000012,  //I/O端口DEBUG地址
  BcdLibraryInteger_SerialDebuggerPort                = 0x15000013,  //DEBUG端口号
  BcdLibraryInteger_SerialDebuggerBaudRate            = 0x15000014,  //波特率调试
  BcdLibraryInteger_1394DebuggerChannel               = 0x15000015,  //1394调试
  BcdLibraryString_UsbDebuggerTargetName              = 0x12000016,  //USB调试
  BcdLibraryBoolean_DebuggerIgnoreUsermodeExceptions  = 0x16000017,  //是否忽略用户异常调试
  BcdLibraryInteger_DebuggerStartPolicy               = 0x15000018,  //调试启动协议状态
  BcdLibraryString_DebuggerBusParameters              = 0x12000019,  //定义调试设备的功能等
  BcdLibraryInteger_DebuggerNetHostIP                 = 0x1500001A,  //定义调试IP地址
  BcdLibraryInteger_DebuggerNetPort                   = 0x1500001B,  //定义调试端口
  BcdLibraryBoolean_DebuggerNetDhcp                   = 0x1600001C,  //定义调试DHCP
  BcdLibraryString_DebuggerNetKey                     = 0x1200001D,  //定义调试网络密匙
  BcdLibraryBoolean_EmsEnabled                        = 0x16000020,  //启动EMS
  BcdLibraryInteger_EmsPort                           = 0x15000022,  //CMOS端口的EMS定向
  BcdLibraryInteger_EmsBaudRate                       = 0x15000023,  //EMS波特率重定向
  BcdLibraryString_LoadOptionsString                  = 0x12000030,  //加载选项字符串
  BcdLibraryBoolean_DisplayAdvancedOptions            = 0x16000040,  //显示高级菜单F8
  BcdLibraryBoolean_DisplayOptionsEdit                = 0x16000041,  //显示引导选项编辑器
  BcdLibraryDevice_BsdLogDevice                       = 0x11000043,  //允许相关日志
  BcdLibraryString_BsdLogPath                         = 0x12000044,  //日志路径
  BcdLibraryBoolean_GraphicsModeDisabled              = 0x16000046,  //图形模式
  BcdLibraryInteger_ConfigAccessPolicy                = 0x15000047,  //PCI配置访问策略
  BcdLibraryBoolean_DisableIntegrityChecks            = 0x16000048,  //完整性检查
  BcdLibraryBoolean_AllowPrereleaseSignatures         = 0x16000049,  //支持测试代码证书
  BcdLibraryString_FontPath                           = 0x1200004A,  //字体路径
  BcdLibraryInteger_SiPolicy                          = 0x1500004B,  //元素数据格式
  BcdLibraryInteger_FveBandId                         = 0x1500004C,  //元素格式
  BcdLibraryBoolean_ConsoleExtendedInput              = 0x16000050,  //控制扩展输入
  BcdLibraryInteger_GraphicsResolution                = 0x15000052,  //制定图形分辨率
  BcdLibraryBoolean_RestartOnFailure                  = 0x16000053,  //显示错误重启
  BcdLibraryBoolean_GraphicsForceHighestMode          = 0x16000054,  //最高分辨率
  BcdLibraryBoolean_IsolatedExecutionContext          = 0x16000060,  //区别win7和win8
  BcdLibraryBoolean_BootUxDisable                     = 0x1600006C,  //禁用logo
  BcdLibraryBoolean_BootShutdownDisabled              = 0x16000074,  //禁用1m关闭策略
  BcdLibraryIntegerList_AllowedInMemorySettings       = 0x17000077,  //是否启用内存设置
  BcdLibraryBoolean_ForceFipsCrypto                   = 0x16000079  //FIPS加密检查
} BcdLibraryElementTypes;

 

typedef enum BcdMemDiagElementTypes {
  BcdMemDiagInteger_PassCount     = 0x25000001,  //当前测试内存页数量
  BcdMemDiagInteger_FailureCount  = 0x25000003  //错误页数量
} BcdMemDiagElementTypes;

 

typedef enum BcdOSLoader_NxPolicy {
  NxPolicyOptIn      = 0,               //不可执行的页面保护,默认关闭
  NxPolicyOptOut     = 1,               //不可执行的页面保护
  NxPolicyAlwaysOff  = 2,               //关闭不可执行页面保护
  NxPolicyAlwaysOn   = 3               //开启不可执行页面保护
} BcdOSLoader_NxPolicy;

 

typedef enum BcdOSLoader_PAEPolicy {
  PaePolicyDefault       = 0,             //内存大于4G开启PAE
  PaePolicyForceEnable   = 1,             //始终开启PAE
  PaePolicyForceDisable  = 2              //始终关闭PAE
} BcdOSLoader_PAEPolicy;

 

typedef enum BcdOSLoaderElementTypes {
  BcdOSLoaderDevice_OSDevice                        = 0x21000001,  //OS设备
  BcdOSLoaderString_SystemRoot                      = 0x22000002,  //系统文件路径
  BcdOSLoaderObject_AssociatedResumeObject          = 0x23000003,  //重启程序相关
  BcdOSLoaderBoolean_DetectKernelAndHal             = 0x26000010,  //表明系统加载程序
  BcdOSLoaderString_KernelPath                      = 0x22000011,  //内核路径
  BcdOSLoaderString_HalPath                         = 0x22000012,  //HAL路径
  BcdOSLoaderString_DbgTransportPath                = 0x22000013,  //传输DLL加载
  BcdOSLoaderInteger_NxPolicy                       = 0x25000020,  //不可执行页面协议
  BcdOSLoaderInteger_PAEPolicy                      = 0x25000021,  //PAE协议
  BcdOSLoaderBoolean_WinPEMode                      = 0x26000022,  //windows预安装模式
  BcdOSLoaderBoolean_DisableCrashAutoReboot         = 0x26000024,  //系统不能自启时奔溃
  BcdOSLoaderBoolean_UseLastGoodSettings            = 0x26000025,  //最后一次正确设置
  BcdOSLoaderBoolean_AllowPrereleaseSignatures      = 0x26000027,  //是否支持测试签名
  BcdOSLoaderBoolean_NoLowMemory                    = 0x26000030,  //是否使用第一个内存
  BcdOSLoaderInteger_RemoveMemory                   = 0x25000031,  //忽略系统内存数量
  BcdOSLoaderInteger_IncreaseUserVa                 = 0x25000032,  //内存地址空间变量
  BcdOSLoaderBoolean_UseVgaDriver                   = 0x26000040,  //VGA驱动程序
  BcdOSLoaderBoolean_DisableBootDisplay             = 0x26000041,  //不显示启动图形界面
  BcdOSLoaderBoolean_DisableVesaBios                = 0x26000042,  //是否避免VESA冲突
  BcdOSLoaderBoolean_DisableVgaMode                 = 0x26000043,  //禁用VGA模式
  BcdOSLoaderInteger_ClusterModeAddressing          = 0x25000050,  //指定寻址模式
  BcdOSLoaderBoolean_UsePhysicalDestination         = 0x26000051,  //是否启动APIC寻址模式
  BcdOSLoaderInteger_RestrictApicCluster            = 0x25000052,  //APIC集群最大数量
  BcdOSLoaderBoolean_UseLegacyApicMode              = 0x26000054,  //使用Legacy APIC模式
  BcdOSLoaderInteger_X2ApicPolicy                   = 0x25000055,  //扩展APIC模式
  BcdOSLoaderBoolean_UseBootProcessorOnly           = 0x26000060,  //OS是否初始化
  BcdOSLoaderInteger_NumberOfProcessors             = 0x25000061,  //最大处理器数量
  BcdOSLoaderBoolean_ForceMaximumProcessors         = 0x26000062,  //OS是否使用全部处理器
  BcdOSLoaderBoolean_ProcessorConfigurationFlags    = 0x25000063,  //处理器特定标志
  BcdOSLoaderBoolean_MaximizeGroupsCreated          = 0x26000064,  //最大处理器组
  BcdOSLoaderBoolean_ForceGroupAwareness            = 0x26000065,  //确定组使用不当
  BcdOSLoaderInteger_GroupSize                      = 0x25000066,  //处理器组大小
  BcdOSLoaderInteger_UseFirmwarePciSettings         = 0x26000070,  //是否使用I\O和IRQ
  BcdOSLoaderInteger_MsiPolicy                      = 0x25000071,  //MSI协议
  BcdOSLoaderInteger_SafeBoot                       = 0x25000080,  //安全启动
  BcdOSLoaderBoolean_SafeBootAlternateShell         = 0x26000081,  //指定安全启动shell
  BcdOSLoaderBoolean_BootLogInitialization          = 0x26000090,  //启动日志初始化
  BcdOSLoaderBoolean_VerboseObjectLoadMode          = 0x26000091,  //显示系统详细信息
  BcdOSLoaderBoolean_KernelDebuggerEnabled          = 0x260000a0,  //内核调试开启
  BcdOSLoaderBoolean_DebuggerHalBreakpoint          = 0x260000a1,  //是否调用HAL调试
  BcdOSLoaderBoolean_UsePlatformClock               = 0x260000A2,  //使用平台时钟
  BcdOSLoaderBoolean_ForceLegacyPlatform            = 0x260000A3,  //使用Legacy平台
  BcdOSLoaderInteger_TscSyncPolicy                  = 0x250000A6,  //TSC同步控制策略
  BcdOSLoaderBoolean_EmsEnabled                     = 0x260000b0,  //开启EMS
  BcdOSLoaderInteger_DriverLoadFailurePolicy        = 0x250000c1,  //驱动加载失败协议
  BcdOSLoaderInteger_BootMenuPolicy                 = 0x250000C2,  //启动菜单协议
  BcdOSLoaderBoolean_AdvancedOptionsOneTime         = 0x260000C3,  //F8相关
  BcdOSLoaderInteger_BootStatusPolicy               = 0x250000E0,  //启动状态协议
  BcdOSLoaderBoolean_DisableElamDrivers             = 0x260000E1,  //由F8使用
  BcdOSLoaderInteger_HypervisorLaunchType           = 0x250000F0,  //控制管理程序启动
  BcdOSLoaderBoolean_HypervisorDebuggerEnabled      = 0x260000F2,  //控制管理程序调试
  BcdOSLoaderInteger_HypervisorDebuggerType         = 0x250000F3,  //控制管理调试类型
  BcdOSLoaderInteger_HypervisorDebuggerPortNumber   = 0x250000F4,  //串口调试
  BcdOSLoaderInteger_HypervisorDebuggerBaudrate     = 0x250000F5,  //波特率调试
  BcdOSLoaderInteger_HypervisorDebugger1394Channel  = 0x250000F6,  //1394调试
  BcdOSLoaderInteger_BootUxPolicy                   = 0x250000F7,  //该值被禁用
  BcdOSLoaderString_HypervisorDebuggerBusParams     = 0x220000F9,  //定义PCI设备
  BcdOSLoaderInteger_HypervisorNumProc              = 0x250000FA,  //指定逻辑处理器总数
  BcdOSLoaderInteger_HypervisorRootProcPerNode      = 0x250000FB,  //指定虚拟处理器
  BcdOSLoaderBoolean_HypervisorUseLargeVTlb         = 0x260000FC,  //增加TLB大小
  BcdOSLoaderInteger_HypervisorDebuggerNetHostIp    = 0x250000FD,  //定义IPV4调试
  BcdOSLoaderInteger_HypervisorDebuggerNetHostPort  = 0x250000FE,  //定义UDP调试
  BcdOSLoaderInteger_TpmBootEntropyPolicy           = 0x25000100,  //确定TPM协议
  BcdOSLoaderString_HypervisorDebuggerNetKey        = 0x22000110,  //网络密匙
  BcdOSLoaderBoolean_HypervisorDebuggerNetDhcp      = 0x26000114,  //DHCP调试
  BcdOSLoaderInteger_HypervisorIommuPolicy          = 0x25000115,  //IOMMU协议
  BcdOSLoaderInteger_XSaveDisable                   = 0x2500012b  //禁用XSAVE功能
} BcdOSLoaderElementTypes;

 

typedef enum _BcdResumeElementTypes {
  Reserved1                            = 0x21000001,  //保留
  Reserved2                            = 0x22000002,  //保留
  BcdResumeBoolean_UseCustomSettings   = 0x26000003,  //用户自定义设置
  BcdResumeDevice_AssociatedOsDevice   = 0x21000005,  //制定休眠OS
  BcdResumeBoolean_DebugOptionEnabled  = 0x26000006,  //内核调试开启
  BcdResumeInteger_BootMenuPolicy      = 0x25000008  //制定启动菜单协议
} BcdResumeElementTypes;

 

三、BCD和注册表间的相关操作

1.BCD内容对应于注册表HKEY_LOCAL_MACHINE\BCD00000000下的所有键值;

2.win8下修改HKEY_LOCAL_MACHINE\BCD00000000\Objects的权限,便可以对其下的键值作任何修改,包括删除;

3.win8需使用管理员权限打开CMD命令框,执行bcdedit命令可以修改BCD内容;

4.使用注册表的导入导出功能,可以将二进制BCD文件转化为可读写的文本文件(转化后的文本文件只标识了BCD的一部分内容,并非全部),注意,导入导出的时候,需要选中注册表的HKEY_LOCAL_MACHINE\BCD00000000键值,否则操作失败;

5.执行不同操作(包括安装PMC,执行保存恢复等操作),重启导出BCD文件,通过转化后,对比前后变化,发现只有时间上的变化,但由于转化的文件只是一部分,所以无法说明问题;

6.在执行一些操作后,BCD文件会变大(win8原BCD文件为40K,而变大后的文件可能为48K、72K、80K等),转化后的文本文件无法显示其变化部分,但是注册表BCD00000000\Objects里的键值会发生变化(暂未找到变化规律);若将变大后的文件,替换为原来的40K大小的文件,系统依然可以启动,且不会出现修复等现象;

7.若手动修改注册表键值,则发现BCD也跟着变化,说明注册表对BCD的影响是即时的.。

 

遗留:由于还无法确定哪些操作会导致BCD文件变化,所以无法进一步定位PMC哪些地方影响BCD。

 

小结:虽然BCD先于PMC运行,但由于保存恢复操作会恢复注册表,注册表会修改BCD文件,而BCD文件被修改,会影响系统启动;所以不排除PMC的相关操作会影响BCD,进而影响系统启动。

 

四、PMC针对BCD测试代码
针对BCD变化情况,在保存恢复以及变更保护的时候,对BCD文件作相应的备份与恢复,备份文件如下(3个):

1.ESP\Microsoft\Boot\BCDINSTALL    (安装时BCD备份)
2.ESP\Microsoft\Boot\BCDPOINT1     (变更保护时BCD备份)
3.ESP\Microsoft\Boot\BCDPOINT2     (创建快速备份点时BCD备份)

👍好活当赏🧧