3,880
社区成员




#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <tchar.h>
#define INITGUID
#include <windows.h>
#include <wmistr.h>
LONG WINAPI WmiOpenBlock(
const GUID *DataBlockGuid, // __in
ULONG DesiredAccess, // __in
PVOID *DataBlockObject // __inout
);
typedef LONG (WINAPI *PFN_WMI_OPEN_BLOCK)(LPCGUID, ULONG, PVOID *);
LONG WINAPI WmiQueryAllDataA(
PVOID DataBlockObject, // __in
ULONG *InOutBufferSize, // __inout
PVOID OutBuffer // __out_opt
);
typedef LONG (WINAPI *PFN_WMI_QUERY_ALL_DATAA)(PVOID, PULONG, PVOID);
LONG WINAPI WmiQueryAllDataW(
PVOID DataBlockObject, // __in
ULONG *InOutBufferSize, // __inout
PVOID OutBuffer // __out_opt
);
typedef LONG (WINAPI *PFN_WMI_QUERY_ALL_DATAW)(PVOID, PULONG, PVOID);
#ifndef UNICODE
#define WmiQueryAllData WmiQueryAllDataA
#else
#define WmiQueryAllData WmiQueryAllDataW
#endif
LONG WINAPI WmiCloseBlock(
PVOID DataBlockObject // __in
);
typedef LONG (WINAPI *PFN_WMI_CLOSE_BLOCK)(PVOID);
/*
* wmidata.h
*/
DEFINE_GUID(MSSmBios_RawSMBiosTables_GUID, 0x8f680850,0xa584,0x11d1,0xbf,0x38,0x00,0xa0,0xc9,0x06,0x29,0x10);
#define MSSmBios_RawSMBiosTables_Used20CallingMethod_SIZE sizeof(BOOLEAN)
#define MSSmBios_RawSMBiosTables_Used20CallingMethod_ID 1
#define MSSmBios_RawSMBiosTables_SmbiosMajorVersion_SIZE sizeof(UCHAR)
#define MSSmBios_RawSMBiosTables_SmbiosMajorVersion_ID 2
#define MSSmBios_RawSMBiosTables_SmbiosMinorVersion_SIZE sizeof(UCHAR)
#define MSSmBios_RawSMBiosTables_SmbiosMinorVersion_ID 3
#define MSSmBios_RawSMBiosTables_DmiRevision_SIZE sizeof(UCHAR)
#define MSSmBios_RawSMBiosTables_DmiRevision_ID 4
#define MSSmBios_RawSMBiosTables_Size_SIZE sizeof(ULONG)
#define MSSmBios_RawSMBiosTables_Size_ID 5
#define MSSmBios_RawSMBiosTables_SMBiosData_ID 6
typedef struct _MSSmBios_RawSMBiosTables {
BOOLEAN Used20CallingMethod;
UCHAR SmbiosMajorVersion;
UCHAR SmbiosMinorVersion;
UCHAR DmiRevision;
ULONG Size;
UCHAR SMBiosData[];
} MSSmBios_RawSMBiosTables, *PMSSmBios_RawSMBiosTables;
/*
* main
*/
int main(int argc, char *argv[])
{
HMODULE hinstDLL = LoadLibrary(_T("advapi32.dll"));
if (hinstDLL != NULL) {
PFN_WMI_OPEN_BLOCK pfnWmiOpenBlock = (PFN_WMI_OPEN_BLOCK)GetProcAddress(hinstDLL, "WmiOpenBlock");
#ifndef UNICODE
PFN_WMI_QUERY_ALL_DATAA pfnWmiQueryAllData = (PFN_WMI_QUERY_ALL_DATAA)GetProcAddress(hinstDLL, "WmiQueryAllDataA");
#else
PFN_WMI_QUERY_ALL_DATAW pfnWmiQueryAllData = (PFN_WMI_QUERY_ALL_DATAW)GetProcAddress(hinstDLL, "WmiQueryAllDataW");
#endif
PFN_WMI_CLOSE_BLOCK pfnWmiCloseBlock = (PFN_WMI_CLOSE_BLOCK)GetProcAddress(hinstDLL, "WmiCloseBlock");
if (pfnWmiOpenBlock != NULL && pfnWmiQueryAllData != NULL && pfnWmiCloseBlock != NULL) {
LPVOID *lpBlock = NULL;
LONG lResult = pfnWmiOpenBlock(&MSSmBios_RawSMBiosTables_GUID, WMIGUID_QUERY, (void **)&lpBlock);
if (lResult == ERROR_SUCCESS) {
DWORD dwSize = 0;
pfnWmiQueryAllData(lpBlock, &dwSize, NULL);
WNODE_ALL_DATA *wmiSMBiosInfo = (WNODE_ALL_DATA *)LocalAlloc(LPTR, dwSize);
if (wmiSMBiosInfo != NULL) {
lResult = pfnWmiQueryAllData(lpBlock, &dwSize, wmiSMBiosInfo);
if (lResult == ERROR_SUCCESS) {
MSSmBios_RawSMBiosTables *lpSMBios = (MSSmBios_RawSMBiosTables *)((BYTE *)wmiSMBiosInfo + wmiSMBiosInfo->DataBlockOffset);
printf( "Used20CallingMethod: %u\n"
"SmbiosMajorVersion: %u\n"
"SmbiosMinorVersion: %u\n"
"DmiRevision: %u\n"
"Size: %u\n"
"\n",
lpSMBios->Used20CallingMethod,
lpSMBios->SmbiosMajorVersion,
lpSMBios->SmbiosMinorVersion,
lpSMBios->DmiRevision,
lpSMBios->Size );
// 写入 SMBIOS 数据到文件
HANDLE hFile = CreateFile(_T("smbios.bin"), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile != INVALID_HANDLE_VALUE) {
DWORD dwBytesWritten = 0;
WriteFile(hFile, lpSMBios->SMBiosData, lpSMBios->Size, &dwBytesWritten, NULL);
CloseHandle(hFile);
}
}
LocalFree(wmiSMBiosInfo);
}
pfnWmiCloseBlock(lpBlock);
}
}
FreeLibrary(hinstDLL);
}
return 0;
}
#pragma pack(1)
/// @brief SMBIOS EPS表结构
struct S_SM_EPS
{
BYTE SMKey[4]; ///< 固定是"_SM_"
BYTE CheckSum; ///< 检验和
BYTE EPSSize; ///< EPS表的长度
BYTE MajorVersion; ///< SMBIOS主版本
BYTE MinorVersion; ///< SMBIOS次版本
BYTE Other[22];
};
#pragma pack()
/// @brief 查找EPS(Entry Point Structure)表地址
///
/// @return 成功返回地址, 失败返回(0)
DWORD FindEPSAddress()
{
const DWORD StartAddress = 0x000F0000; // EPS表所在的物理内存起始地址
const DWORD EndAddress = 0x000FFFFF; // EPS表所在的物理内存结束地址
BYTE _SM_[4] = {0};
BYTE _DMI_[5] = {0};
DWORD count = 0;
for (DWORD address = StartAddress; address < EndAddress; address++)
{
count = ReadPhysicalMemory(address, _SM_, 4, 1);
if (count != 4)
continue;
if (_SM_[0] != '_' || _SM_[1] != 'S' || _SM_[2] != 'M' || _SM_[3] != '_')
continue;
count = ReadPhysicalMemory(address + 16, _DMI_, 5, 1);
if (count != 5)
continue;
if (_DMI_[0] != '_' || _DMI_[1] != 'D' || _DMI_[2] != 'M' || _DMI_[3] != 'I' || _DMI_[4] != '_')
continue;
return address;
}
return 0;
}
bool FillSMBiosEPS(DWORD address, S_SM_EPS* pEPS)
{
DWORD count = ReadPhysicalMemory(address, (PBYTE)pEPS, sizeof(S_SM_EPS), 1);
if (count != sizeof(S_SM_EPS))
{
return false;
}
return true;
}
int main()
{
DWORD address = FindEPSAddress();
if (address != 0)
{
printf("Find EPS Address Success\n");
}
S_SM_EPS eps;
bool bRet = FillSMBiosEPS(address, &eps);
if (bRet)
{
printf("Fill SMBios Success\n");
}
system("pause");
return 0;
}
SMBIOS内容的解析需要你自己做
以上代码需要用到ReadPhysicalMemory方法
ReadPhysicalMemory在WinRing0中(重新编译,开启读写物理内存)
你也可以使用其他库来进行读取物理内存