64位操作系统Hook内核函数NtQuerySystemInformation遇到的坑
程序通过调用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); }
本博客注有“转”字样的为转载文章,其余为本人原创文章,转载请务必注明出处或保存此段。c++/lua/windows逆向交流群:69148232