我正在爲Windows系統實現SMBIOS讀取功能。由於API級別不同,有幾種方法可以支持:NtOpenSection(L「\ Device \ PhysicalMemory」)返回STATUS_OBJECT_NAME_NOT_FOUND
- 無故障
GetSystemFirmwareTable('RSMB')
可用於Windows Server 2003和更高版本; - hardcore
NtOpenSection(L"\\Device\\PhysicalMemory")
適用於Windows XP之前和之後的傳統系統; L"Win32_ComputerSystemProduct"
中重要的WMI數據通過繁瑣的COM自動化調用作爲後備路徑。
方法1和3都已經實現了,但我堅持\設備\ PhysicalMemory,爲NtOpenSection
始終得到0xC0000034(STATUS_OBJECT_NAME_NOT_FOUND) - 絕對是ZwOpenSection
文檔中的可能的結果代碼的一個也沒有。當然,我知道從Windows Server 2003sp1以及Windows XP-64開始,禁止訪問此部分,因此我在普通的Windows XP-32系統上嘗試了這一點 - 結果與第例如,Windows 7-64。我也知道即使在傳統系統上也可能需要管理員權限,但互聯網上遇到此問題的人員報告了此類情況的更多相關錯誤代碼,如0xC0000022(STATUS_ACCESS_DENIED)和0xC0000005(STATUS_ACCESS_VIOLATION)。
我的方法是基於戴爾的Libsmbios庫,我假定它正在工作。
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;
我認爲這可能是可以調試這一點,但原生API似乎是透明的,像OllyDbg的調試器:執行立即返回一次SYSENTER指令接收控制。所以我不知道爲什麼Windows找不到這個對象。我還嘗試更改節名稱,因爲在線示例中有幾個變體,但總是生成0xC0000033(STATUS_OBJECT_NAME_INVALID)。
如果要調試到內核模式,你需要一個內核調試器,如[WinDbg中或KD(https://msdn.microsoft.com/en-us/library/windows/hardware/ff551063.aspx )。 – IInspectable
也許嘗試WinObj(可從Microsoft網站獲得)來仔細檢查該部分是否存在?並嘗試進程監視器(同上),看它是否將捕捉到的NtOpenSection請求,以防它被重定向出於某種原因。 –
@HarryJohnston關於Sysinternals的好處,但是這個工具實際上什麼都沒有顯示:我用'Sleep(2000)'包圍了'NtOpenSection()',並且進程監視器僅記錄當時發生的4個配置文件事件;不排除來自* System *模塊的事件也沒有幫助。 –