我正在为Windows系统实现SMBIOS读取功能。由于API级别不同,有几种方法可以支持:
GetSystemFirmwareTable('RSMB');NtOpenSection(L"\\Device\\PhysicalMemory");L"Win32_ComputerSystemProduct"路径中必需的WMI数据通过繁琐的COM自动化调用作为后盾。方法1和方法3已经实现,但是我只能使用\Device\PhysicalMemory,因为NtOpenSection总是产生0xC0000034 (STATUS_OBJECT_NAME_NOT_FOUND) --这肯定不是ZwOpenSection文档中可能的结果代码之一。当然,我知道从WindowsServer2003sp1或者WindowsXP-64开始就禁止访问这个部分,所以我在一个普通的Windows 32系统上进行了尝试--例如,结果和Windows 7-64没有什么不同。我还知道,即使是在遗留系统上,也可能需要管理员权限,但面临此问题的internets上的人报告了更多此类场景的相关错误代码,如0xC0000022 (STATUS_ACCESS_DENIED)和0xC0000005 (STATUS_ACCESS_VIOLATION)。
我的方法是基于戴尔的利伯斯库,我认为这是可行的。
UNICODE_STRING wsMemoryDevice;
OBJECT_ATTRIBUTES oObjAttrs;
HANDLE hMemory;
NTSTATUS ordStatus;
RtlInitUnicodeString(&wsMemoryDevice, L"\\Device\\PhysicalMemory");
InitializeObjectAttributes(&oObjAttrs, &wsMemoryDevice,
OBJ_CASE_INSENSITIVE, NULL, NULL);
ordStatus = NtOpenSection(&hMemory, SECTION_MAP_READ, &oObjAttrs);
if (!NT_SUCCESS(ordStatus)) goto Finish;我认为可以调试这一点,但是对于OllyDbg这样的调试器来说,原生API似乎是透明的:一旦SYSENTER指令接收到控制,执行就会立即返回。所以我不知道为什么Windows找不到这个对象。我还试图更改节名,因为在在线示例中有几个变体,但这总是产生0xC0000033 (STATUS_OBJECT_NAME_INVALID)。
发布于 2015-05-07 16:51:59
最后,我发现了导致这种奇怪行为的原因--多亏了你们,各位,确认了我的代码片段(这是一个实际的摘录,而不是一个伪造的示例)确实有效。问题是,我最初没有安装Windows DDK (我现在已经安装了,但仍然不能以Windows SDK自动集成的方式将其与Visual集成),因此需要手工编写定义。特别是,当我意识到InitializeObjectAttributes实际上是一个预处理宏而不是一个Win32函数时,我也将RtlInitUnicodeString定义为宏,因为它的效果甚至更简单。但是,我没有注意到UNICODE_STRING.Length和.MaximumLength实际上是用于内容大小和缓冲区大小,而不是长度,即字节数 e 211而不是E 112字符E 213的数量。因此,我的宏将字段设置为其期望值的一半,从而使Windows只看到L"\\Device\\PhysicalMemory"字符串的前半部分,结果非常明显。
https://stackoverflow.com/questions/29683015
复制相似问题