如何在C语言中枚举Boot Entries且避免程序崩溃?
问题分析与解决
你的代码存在两个核心问题,直接导致程序崩溃:
1. 缓冲区类型错误
你声明了PBOOT_ENTRY_LIST* BootEntries(二级指针),但NtEnumerateBootEntries要求的第一个参数是PBOOT_ENTRY_LIST(一级指针,指向BOOT_ENTRY_LIST结构体的缓冲区)。错误的指针类型会让函数写入错误的内存地址,后续访问时触发非法内存访问。
2. 启动项数量计算错误
sizeof(BootEntries) / sizeof(PBOOT_ENTRY_LIST*)计算的是指针本身的大小除以指针类型的大小,在32/64位系统中结果都是1,完全无法得到真实的启动项数量。正确做法是读取BOOT_ENTRY_LIST结构体自带的Count字段,该字段由NtEnumerateBootEntries填充,记录了实际启动项总数。
修正后的代码
ULONG BufferLength; NTSTATUS NtStatus = NtEnumerateBootEntries(NULL, &BufferLength); if (NtStatus != STATUS_BUFFER_TOO_SMALL) { NtStatusErrorExit("NtEnumerateBootEntries", NtStatus); } // 修正:使用一级指针匹配函数参数要求 PBOOT_ENTRY_LIST BootEntries = (PBOOT_ENTRY_LIST)malloc(BufferLength); if (!BootEntries) { /* 处理内存分配失败逻辑 */ } NtStatus = NtEnumerateBootEntries(BootEntries, &BufferLength); if (NT_ERROR(NtStatus)) { free(BootEntries); // 分配成功后需释放内存 NtStatusErrorExit("NtEnumerateBootEntries", NtStatus); } // 修正:从结构体Count字段获取真实启动项数量 int NumBootEntries = BootEntries->Count; printf("Number of Boot Entries: %i\n", NumBootEntries); // 修正:访问结构体中的BootEntry数组 for (int i = 0; i < NumBootEntries; i++) { BOOT_ENTRY BootEntry = BootEntries->BootEntry[i]; printf("Boot Entry ID: %lu\n", BootEntry.Id); } // 释放分配的缓冲区,避免内存泄漏 free(BootEntries);
额外注意事项
- 内存分配后必须检查是否成功,防止空指针访问。
NtEnumerateBootEntries是未公开系统函数,不同Windows版本的结构体定义可能存在差异,需确保BOOT_ENTRY_LIST和BOOT_ENTRY的定义与目标系统匹配,示例定义如下:typedef struct _BOOT_ENTRY { ULONG Id; WCHAR Name[256]; // 其他字段根据系统版本补充 } BOOT_ENTRY, *PBOOT_ENTRY; typedef struct _BOOT_ENTRY_LIST { ULONG Count; BOOT_ENTRY BootEntry[ANYSIZE_ARRAY]; } BOOT_ENTRY_LIST, *PBOOT_ENTRY_LIST;
内容的提问来源于stack exchange,提问作者Hantalyte
相关产品推荐
相关产品推荐

