Всем привет.
Нужно было получить температуру камня. Рекомендовалось WMI или DMI,
С WMI ничего не вышло — нет ничего по Win32_Fan. Попробовал через DMI — ничего
тоже не вышло, хотя много чего интересного получил. Если кому нужно — можно взять
и довести до ума.
Это кусок кода для чтения памяти по указанному физическому адресу.
Исходный код не мой — я использовал нарытый и немножко его модифицировал.
/*****************************************************************************/
#define InitializeObjectAttributes(p,n,a,r,s) { \
(p)->Length = sizeof( OBJECT_ATTRIBUTES ); \
(p)->RootDirectory = r; \
(p)->Attributes = a; \
(p)->ObjectName = n; \
(p)->SecurityDescriptor = s; \
(p)->SecurityQualityOfService = NULL; \
}
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING;
typedef UNICODE_STRING *PUNICODE_STRING;
typedef struct _OBJECT_ATTRIBUTES {
ULONG Length;
HANDLE RootDirectory;
PUNICODE_STRING ObjectName;
ULONG Attributes;
PVOID SecurityDescriptor; // Points to type SECURITY_DESCRIPTOR
PVOID SecurityQualityOfService; // Points to type SECURITY_QUALITY_OF_SERVICE
} OBJECT_ATTRIBUTES;
typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES;
typedef LARGE_INTEGER PHYSICAL_ADDRESS, *PPHYSICAL_ADDRESS; // windbgkd
typedef DWORD NTSTATUS;
typedef NTSTATUS (__stdcall *__NtUnmapViewOfSection)(
IN HANDLE ProcessHandle,
IN PVOID BaseAddress
);
typedef NTSTATUS (__stdcall *__NtOpenSection)(
OUT PHANDLE SectionHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes
);
typedef NTSTATUS (__stdcall *__NtMapViewOfSection)(
IN HANDLE SectionHandle,
IN HANDLE ProcessHandle,
IN OUT PVOID *BaseAddress,
IN ULONG ZeroBits,
IN ULONG CommitSize,
IN OUT PLARGE_INTEGER SectionOffset, /* optional */
IN OUT PULONG ViewSize,
IN DWORD InheritDisposition,
IN ULONG AllocationType,
IN ULONG Protect
);
typedef VOID (__stdcall *__RtlInitUnicodeString)(
IN OUT PUNICODE_STRING DestinationString,
IN PCWSTR SourceString
);
typedef ULONG (__stdcall *__RtlNtStatusToDosError) (
IN NTSTATUS Status
);
void ReadBIOSRegion (DWORD dwAddress, DWORD dwSize, LPVOID pDestAddress)
{
HANDLE hSectionHandle = (HANDLE) -1;;
PDWORD pAddress = (PDWORD) (LPVOID) dwAddress;
DWORD dwLength = ((dwSize + 0x0FFF) / 0x1000) * 0x1000;
LPBYTE pVirtualAddress = NULL;
PHYSICAL_ADDRESS ViewBase = { 0 };
UNICODE_STRING szPhysmemString;
OBJECT_ATTRIBUTES oaAttributes;
HINSTANCE hDLL = GetModuleHandle ("ntdll.dll");
__NtOpenSection NtOpenSection = (__NtOpenSection) GetProcAddress (hDLL, "NtOpenSection");
__NtMapViewOfSection NtMapViewOfSection = (__NtMapViewOfSection) GetProcAddress (hDLL, "NtMapViewOfSection");
__NtUnmapViewOfSection NtUnmapViewOfSection = (__NtUnmapViewOfSection) GetProcAddress (hDLL, "NtUnmapViewOfSection");
__RtlInitUnicodeString RtlInitUnicodeString = (__RtlInitUnicodeString) GetProcAddress (hDLL, "RtlInitUnicodeString");
__RtlNtStatusToDosError RtlNtStatusToDosError = (__RtlNtStatusToDosError) GetProcAddress (hDLL, "RtlNtStatusToDosError");
RtlInitUnicodeString( &szPhysmemString, L"\\device\\physicalmemory" );
InitializeObjectAttributes( &oaAttributes, &szPhysmemString,0x00000040L, NULL, NULL );
NtOpenSection( &hSectionHandle, SECTION_MAP_READ, &oaAttributes );
ViewBase.QuadPart = (ULONGLONG) (pAddress);
ViewBase.QuadPart = (ULONGLONG) (((DWORD) pAddress) & 0xFFFFF000);
INT ntStatus = NtMapViewOfSection
(
hSectionHandle,
(HANDLE) -1,
(PVOID*) &pVirtualAddress,
0L,
dwLength,
&ViewBase,
&dwLength,
1,
0,
PAGE_READONLY
);
DWORD xxx = RtlNtStatusToDosError (ntStatus);
CopyMemory (pDestAddress, (pVirtualAddress + (dwAddress % 0x1000)), dwSize);
NtUnmapViewOfSection((HANDLE)-1,pVirtualAddress);
CloseHandle(hSectionHandle);
} // ReadBIOSRegion
А теперь собственно попытка получения и разбора DMI
#include <pshpack1.h>
struct TSMBIOSStructureTableEntryPoint
{
CHAR sAnchor [4]; // _SM_
BYTE bEPSCheckSum;
BYTE bEPSLength;
BYTE bMajor;
BYTE bMinor;
WORD wMaxStructSize;
BYTE bRevision;
BYTE FormatterArea [5];
CHAR sImAnchor [5]; // _DMI_
BYTE bImCheckSum;
WORD wTableLength;
DWORD dwTableAddress;
WORD nNumber;
BYTE bBCDRevision;
}; // TSMBIOSStructureTableEntryPoint
struct TSMBIOSStructureEntryHeader
{
BYTE nType;
BYTE nLength;
WORD hHandle;
}; // TSMBIOSStructureEntryHeader
#include <poppack.h>
int main ()
{
BYTE BIOS [0x10000] = { 0 };
ReadBIOSRegion (0xF0000, 0x10000, BIOS);
LPBYTE pSearchSignature = BIOS;
while (memcmp (pSearchSignature, "\x5F\x53\x4D\x5F", 4) != 0)
{
pSearchSignature += 16;
if (pSearchSignature > (BIOS + sizeof (BIOS)))
{
printf ("Signature not found!\n");
return 1;
}
}
TSMBIOSStructureTableEntryPoint Table = { 0 };
CopyMemory (&Table, pSearchSignature, sizeof (Table));
if (Table. wTableLength > sizeof (BIOS))
{
printf ("DMI info is too large!\n");
return 2;
}
ReadBIOSRegion (Table. dwTableAddress, Table. wTableLength, BIOS);
TSMBIOSStructureEntryHeader* pEntry = (TSMBIOSStructureEntryHeader*) BIOS;
for (int i = 0; i < Table. nNumber; i ++)
{
LPSTR p = ((LPSTR) pEntry) + pEntry -> nLength;
// В зависимости от nType можно делать любой разбор
// Я просто искал датчик температуры (nType == 34)...
// Не нашёл... :(
printf ("%2d: %d [%d]\n", i, pEntry -> nType, pEntry -> nLength);
if (*p)
{
while (*p)
{
printf (" '%s'\n", p);
p += strlen (p) + 1;
}
p ++;
}
else
p += 2;
pEntry = (TSMBIOSStructureEntryHeader*) p;
}
return 0;
} // main
Нашлась ошибочка в коде:
Вместо строки:
DWORD dwLength = ((dwSize + 0x0FFF) / 0x1000) * 0x1000;
нужно написать:
DWORD dwLength = ((dwSize + 0x0FFF + (dwAddress % 0x1000)) / 0x1000) * 0x1000;
Остальное, вроде, работает....