zoukankan      html  css  js  c++  java
  • 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, "asktao") != NULL) {
    				memset(SystemInformation, 0, SystemInformationLength);
    				DbgPrint("[FakeCpuCount]FakeNtQuerySystemInformation pid: %s 
    ", 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);
    }
    

      

     

  • 相关阅读:
    u-boot启动流程分析(1)_平台相关部分
    Linux文件系统简介
    PHP将部分内容替换成星号
    自制jQuery焦点图切换简易插件
    一次解决页面特效问题的排查记录
    自制jQuery标签插件
    一套后台管理html模版
    自制jquery可编辑的下拉框
    注册页面的一些记录
    CSS选择器的一些记录
  • 原文地址:https://www.cnblogs.com/zhangdongsheng/p/13416104.html
Copyright © 2011-2022 走看看