程序通過調用GetSystemInfo得到CPU內核數目的目的,起初想在進程內Hook GetSystemInfo 這個API來達到效果,但是這樣HOOK還得向進程注入一個DLL,比較麻煩。后來得知GetSystemInfo 這個函數內部調用內核NtQuerySystemInformation來達到效果的。於是想直接Hook 內核NtQuerySystemInformation來達到效果。
HOOK的過程還算順利,我是判斷參數為SystemBasicInformation的時候就直接修改NtQuerySystemInformation返回的CPU數目來達到這個目的。
但是,實際測試發現,並不能達到修改CPU數目的效果。調試了兩三個小時無果,最后在網上查發現問題所在。
In 32-bit Windows, the structure is filled exactly the same for all three information classes. The x64 builds treat SystemEmulationBasicInformation differently. This allows WOW64.DLL, executing 64-bit code in a 32-bit process, to get basic information that’s suited to the 32-bit caller.
於是修改HOOK函數條件為SystemEmulationBasicInformation 時總算解決了這個問題。
最終Hook函數代碼如下:
NTSTATUS __fastcall FakeNtQuerySystemInformation( IN SYSTEM_INFORMATION_CLASS SystemInformationClass, OUT PVOID SystemInformation, IN ULONG SystemInformationLength, OUT PULONG ReturnLength ) { if ((SystemBasicInformation == SystemInformationClass || SystemEmulationBasicInformation == SystemInformationClass) && gGetProcessImageFileName != 0 && g_config_processor_count > 0) { PCHAR pImageName = gGetProcessImageFileName(PsGetCurrentProcess()); if (NULL != pImageName) { CHAR buffer[100]; strncpy(buffer, pImageName,100); int len = strlen(buffer); for (int i = 0; i < len && i < 100; i++) buffer[i] = (char)tolower((int)buffer[i]); if (strstr(buffer, "aaa") != NULL) { memset(SystemInformation, 0, SystemInformationLength); DbgPrint("[FakeCpuCount]FakeNtQuerySystemInformation pid: %s \n", pImageName); NTSTATUS status = NtQuerySystemInformation(SystemInformationClass, SystemInformation, SystemInformationLength, ReturnLength); if (SystemInformationClass == SystemEmulationBasicInformation) { if (NT_SUCCESS(status)) { (*(BYTE*)((ULONGLONG)SystemInformation + 0x38)) = (BYTE)g_config_processor_count; } } else { if (NT_SUCCESS(status)) { (*(BYTE*)((ULONGLONG)SystemInformation + 0x38)) = (BYTE)g_config_processor_count; } } return status; } } } return NtQuerySystemInformation(SystemInformationClass, SystemInformation, SystemInformationLength, ReturnLength); }