From 6012ef307f9908919c12e57d94869d87c134366f Mon Sep 17 00:00:00 2001 From: SamsungSHC <164715881+SamsungSHC@users.noreply.github.com> Date: Wed, 26 Aug 2026 17:12:51 +0800 Subject: [PATCH 1/2] Enhance HalpOriginalPerformanceCounter detection logic Added additional pattern search for HalpOriginalPerformanceCounter in Windows 11 build 29648. --- InfinityHookPro/hook.cpp | 331 ++++++++++++++++++++------------------- 1 file changed, 171 insertions(+), 160 deletions(-) diff --git a/InfinityHookPro/hook.cpp b/InfinityHookPro/hook.cpp index eb5b861..857b1f3 100644 --- a/InfinityHookPro/hook.cpp +++ b/InfinityHookPro/hook.cpp @@ -30,12 +30,12 @@ namespace KHook FHvlGetQpcBias m_OriginalHvlGetQpcBias = nullptr; CLIENT_ID m_ClientId = { 0 }; - // 修改跟踪设置 + // 淇敼璺熻釜璁剧疆 NTSTATUS EventTraceControl(ETWP_TRACE_TYPE nType) { const unsigned long nTag = 'VMON'; - // 申请结构体空间 + // 鐢宠缁撴瀯浣撶┖闂 CKCL_TRACE_PROPERTIES* pProperty = (CKCL_TRACE_PROPERTIES*)ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, nTag); if (!pProperty) { @@ -43,7 +43,7 @@ namespace KHook return STATUS_MEMORY_NOT_ALLOCATED; } - // 申请保存名称的空间 + // 鐢宠淇濆瓨鍚嶇О鐨勭┖闂 wchar_t* szProviderName = (wchar_t*)ExAllocatePoolWithTag(NonPagedPool, 256 * sizeof(wchar_t), nTag); if (!szProviderName) { @@ -52,18 +52,18 @@ namespace KHook return STATUS_MEMORY_NOT_ALLOCATED; } - // 清空内存 + // 娓呯┖鍐呭瓨 RtlZeroMemory(pProperty, PAGE_SIZE); RtlZeroMemory(szProviderName, 256 * sizeof(wchar_t)); - // 名称赋值 + // 鍚嶇О璧嬪 RtlCopyMemory(szProviderName, L"Circular Kernel Context Logger", sizeof(L"Circular Kernel Context Logger")); RtlInitUnicodeString(&pProperty->ProviderName, (const wchar_t*)szProviderName); - // 唯一标识符 + // 鍞竴鏍囪瘑绗 GUID guidCkclSession = { 0x54dea73a, 0xed1f, 0x42a4, { 0xaf, 0x71, 0x3e, 0x63, 0xd0, 0x56, 0xf1, 0x74 } }; - // 结构体填充 + // 缁撴瀯浣撳~鍏 pProperty->Wnode.BufferSize = PAGE_SIZE; pProperty->Wnode.Flags = WNODE_FLAG_TRACED_GUID; pProperty->Wnode.Guid = guidCkclSession; @@ -73,53 +73,53 @@ namespace KHook pProperty->MaximumBuffers = 2; pProperty->LogFileMode = EVENT_TRACE_BUFFERING_MODE; - // 执行操作 + // 鎵ц鎿嶄綔 unsigned long nLength = 0; if (nType == ETWP_TRACE_TYPE::EtwpUpdateTrace) pProperty->EnableFlags = EVENT_TRACE_FLAG_SYSTEMCALL; NTSTATUS ntStatus = NtTraceControl(nType, pProperty, PAGE_SIZE, pProperty, PAGE_SIZE, &nLength); - // 释放内存空间 + // 閲婃斁鍐呭瓨绌洪棿 ExFreePoolWithTag(szProviderName, nTag); ExFreePoolWithTag(pProperty, nTag); return ntStatus; } - // 我们的替换函数,针对的是从Win7到Win10 1909的系统 + // 鎴戜滑鐨勬浛鎹㈠嚱鏁,閽堝鐨勬槸浠嶹in7鍒癢in10 1909鐨勭郴缁 unsigned long long SelfGetCpuClock() { - // 放过内核模式的调用 + // 鏀捐繃鍐呮牳妯″紡鐨勮皟鐢 if (ExGetPreviousMode() == KernelMode) return __rdtsc(); - // 拿到当前线程 + // 鎷垮埌褰撳墠绾跨▼ PKTHREAD pCurrentThread = (PKTHREAD)__readgsqword(0x188); - // 不同版本不同偏移 + // 涓嶅悓鐗堟湰涓嶅悓鍋忕Щ unsigned int nCallIndex = 0; if (m_BuildNumber <= 7601) nCallIndex = *(unsigned int*)((unsigned long long)pCurrentThread + 0x1f8); else nCallIndex = *(unsigned int*)((unsigned long long)pCurrentThread + 0x80); - // 拿到当前栈底和栈顶 + // 鎷垮埌褰撳墠鏍堝簳鍜屾爤椤 void** pStackMax = (void**)__readgsqword(0x1a8); void** pStackFrame = (void**)_AddressOfReturnAddress(); - // 开始查找当前栈中的ssdt调用 + // 寮濮嬫煡鎵惧綋鍓嶆爤涓殑ssdt璋冪敤 for (void** pStackCurrent = pStackMax; pStackCurrent > pStackFrame; --pStackCurrent) { - /* 函数 PerfInfoLogSysCallEntry逆向 - Win11 23606 以前 栈中ssdt调用特征, 分别是 + /* 鍑芥暟 PerfInfoLogSysCallEntry閫嗗悜 + Win11 23606 浠ュ墠 鏍堜腑ssdt璋冪敤鐗瑰緛, 鍒嗗埆鏄 mov r9d, 0F33h mov [rsp+48h+var_20], 501802h - Win11 23606 及以后 栈中ssdt调用特征, 分别是 + Win11 23606 鍙婁互鍚 鏍堜腑ssdt璋冪敤鐗瑰緛, 鍒嗗埆鏄 mov r9d, 0F33h mov[rsp + 58h + var_30], 601802h */ -#define INFINITYHOOK_MAGIC_501802 ((unsigned long)0x501802) //Win11 23606 以前系统特征码 -#define INFINITYHOOK_MAGIC_601802 ((unsigned long)0x601802) //Win11 23606 及以后系统的特征码 +#define INFINITYHOOK_MAGIC_501802 ((unsigned long)0x501802) //Win11 23606 浠ュ墠绯荤粺鐗瑰緛鐮 +#define INFINITYHOOK_MAGIC_601802 ((unsigned long)0x601802) //Win11 23606 鍙婁互鍚庣郴缁熺殑鐗瑰緛鐮 #define INFINITYHOOK_MAGIC_F33 ((unsigned short)0xF33) - // 第一个特征值检查 + // 绗竴涓壒寰佸兼鏌 unsigned long* pValue1 = (unsigned long*)pStackCurrent; if ((*pValue1 != INFINITYHOOK_MAGIC_501802) && (*pValue1 != INFINITYHOOK_MAGIC_601802)) @@ -127,52 +127,52 @@ namespace KHook continue; } - // 这里为什么减?配合寻找第二个特征值啊 + // 杩欓噷涓轰粈涔堝噺?閰嶅悎瀵绘壘绗簩涓壒寰佸煎晩 --pStackCurrent; - // 第二个特征值检查 + // 绗簩涓壒寰佸兼鏌 unsigned short* pValue2 = (unsigned short*)pStackCurrent; if (*pValue2 != INFINITYHOOK_MAGIC_F33) { continue; } - // 特征值匹配成功,再倒过来查找 + // 鐗瑰緛鍊煎尮閰嶆垚鍔,鍐嶅掕繃鏉ユ煡鎵 for (; pStackCurrent < pStackMax; ++pStackCurrent) { - // 检查是否在ssdt表内 + // 妫鏌ユ槸鍚﹀湪ssdt琛ㄥ唴 unsigned long long* pllValue = (unsigned long long*)pStackCurrent; if (!(PAGE_ALIGN(*pllValue) >= m_SystemCallTable && PAGE_ALIGN(*pllValue) < (void*)((unsigned long long)m_SystemCallTable + (PAGE_SIZE * 2)))) continue; - // 现在已经确定是ssdt函数调用了 - // 这里是找到KiSystemServiceExit + // 鐜板湪宸茬粡纭畾鏄痵sdt鍑芥暟璋冪敤浜 + // 杩欓噷鏄壘鍒癒iSystemServiceExit void** pSystemCallFunction = &pStackCurrent[9]; - // 调用回调函数 + // 璋冪敤鍥炶皟鍑芥暟 if (m_InfinityCallback) m_InfinityCallback(nCallIndex, pSystemCallFunction); - // 跳出循环 + // 璺冲嚭寰幆 break; } - // 跳出循环 + // 璺冲嚭寰幆 break; } - // 调用原函数 + // 璋冪敤鍘熷嚱鏁 return __rdtsc(); } - // 我们的替换函数,针对的是Win 1919往上的系统 + // 鎴戜滑鐨勬浛鎹㈠嚱鏁,閽堝鐨勬槸Win 1919寰涓婄殑绯荤粺 EXTERN_C __int64 FakeHvlGetQpcBias() { - // 我们的过滤函数 + // 鎴戜滑鐨勮繃婊ゅ嚱鏁 SelfGetCpuClock(); - // 这里是真正HvlGetQpcBias做的事情 - //物理机上 HvlpReferenceTscPage指针值为空 + // 杩欓噷鏄湡姝vlGetQpcBias鍋氱殑浜嬫儏 + //鐗╃悊鏈轰笂 HvlpReferenceTscPage鎸囬拡鍊间负绌 if (*((unsigned long long*)m_HvlpReferenceTscPage) != 0) { return *((unsigned long long*)(*((unsigned long long*)m_HvlpReferenceTscPage)) + 3); @@ -180,59 +180,59 @@ namespace KHook return 0; } - // 检测例程 + // 妫娴嬩緥绋 void DetectThreadRoutine(void*) { while (m_DetectThreadStatus) { - // 线程常用休眠 + // 绾跨▼甯哥敤浼戠湢 KUtils::Sleep(1000); - // GetCpuClock还是一个函数指针 + // GetCpuClock杩樻槸涓涓嚱鏁版寚閽 if (m_BuildNumber <= 18363) { if (MmIsAddressValid(m_GetCpuClock) && MmIsAddressValid(*m_GetCpuClock)) { - // 值不一样,必须重新挂钩 + // 鍊间笉涓鏍,蹇呴』閲嶆柊鎸傞挬 if (SelfGetCpuClock != *m_GetCpuClock) { DbgPrintEx(0, 0, "[%s] fix 0x%p 0x%p \n", __FUNCTION__, m_GetCpuClock, MmIsAddressValid(m_GetCpuClock) ? *m_GetCpuClock : 0); if (Initialize(m_InfinityCallback)) Start(); } } - else Initialize(m_InfinityCallback); // GetCpuClock无效后要重新获取 + else Initialize(m_InfinityCallback); // GetCpuClock鏃犳晥鍚庤閲嶆柊鑾峰彇 } LARGE_INTEGER li = KeQueryPerformanceCounter(NULL); //DbgPrintEx(0, 0, "[%s] Tick Count %lld \n", __FUNCTION__, li.QuadPart); } PsTerminateSystemThread(STATUS_SUCCESS); } -#define HALP_PERFORMANCE_COUNTER_TYPE_OFFSET (0xE4) //HalpPerformanceCounter类型值偏移,该值在物理机器中为5,虚拟机中 Win11 22621 以上为7, 以下为 8 -#define HALP_PERFORMANCE_COUNTER_BASE_RATE_OFFSET (0xC0) //HalpPerformanceCounter基本速度倍率地址 虚拟机中为值为 0x989680=10000000, 物理机中为约2000000000 -#define HALP_PERFORMANCE_COUNTER_TYPE_PHYSICAL_MACHINE (0x5) //物理机中HalpPerformanceCounter的类型 -#define HALP_PERFORMANCE_COUNTER_BASE_RATE (10000000i64) //基本速度 +#define HALP_PERFORMANCE_COUNTER_TYPE_OFFSET (0xE4) //HalpPerformanceCounter绫诲瀷鍊煎亸绉伙紝璇ュ煎湪鐗╃悊鏈哄櫒涓负5锛岃櫄鎷熸満涓 Win11 22621 浠ヤ笂涓7, 浠ヤ笅涓 8 +#define HALP_PERFORMANCE_COUNTER_BASE_RATE_OFFSET (0xC0) //HalpPerformanceCounter鍩烘湰閫熷害鍊嶇巼鍦板潃 铏氭嫙鏈轰腑涓哄间负 0x989680=10000000锛 鐗╃悊鏈轰腑涓虹害2000000000 +#define HALP_PERFORMANCE_COUNTER_TYPE_PHYSICAL_MACHINE (0x5) //鐗╃悊鏈轰腑HalpPerformanceCounter鐨勭被鍨 +#define HALP_PERFORMANCE_COUNTER_BASE_RATE (10000000i64) //鍩烘湰閫熷害 bool Initialize(InfinityCallbackPtr pCallback) { if (!m_DetectThreadStatus) return false; - // 回调函数指针检查 + // 鍥炶皟鍑芥暟鎸囬拡妫鏌 DbgPrintEx(0, 0, "[%s] ssdt call back ptr is 0x%p \n", __FUNCTION__, pCallback); if (!MmIsAddressValid(pCallback)) return false; else m_InfinityCallback = pCallback; - // 先尝试挂钩 + // 鍏堝皾璇曟寕閽 if (!NT_SUCCESS(EventTraceControl(EtwpUpdateTrace))) { - // 无法开启CKCL + // 鏃犳硶寮鍚疌KCL if (!NT_SUCCESS(EventTraceControl(EtwpStartTrace))) { DbgPrintEx(0, 0, "[%s] start ckcl fail \n", __FUNCTION__); return false; } - // 再次尝试挂钩 + // 鍐嶆灏濊瘯鎸傞挬 if (!NT_SUCCESS(EventTraceControl(EtwpUpdateTrace))) { DbgPrintEx(0, 0, "[%s] syscall ckcl fail \n", __FUNCTION__); @@ -240,18 +240,18 @@ namespace KHook } } - // 获取系统版本号 + // 鑾峰彇绯荤粺鐗堟湰鍙 m_BuildNumber = KUtils::GetSystemBuildNumber(); DbgPrintEx(0, 0, "[%s] build number is %ld \n", __FUNCTION__, m_BuildNumber); if (!m_BuildNumber) return false; - // 获取系统基址 + // 鑾峰彇绯荤粺鍩哄潃 unsigned long long ntoskrnl = KUtils::GetModuleAddress("ntoskrnl.exe", nullptr); DbgPrintEx(0, 0, "[%s] ntoskrnl address is 0x%llX \n", __FUNCTION__, ntoskrnl); if (!ntoskrnl) return false; - // 这里不同系统不同位置 - // https://github.com/FiYHer/InfinityHookPro/issues/17 win10 21h2.2130 安装 KB5018410 补丁后需要使用新的特征码 + // 杩欓噷涓嶅悓绯荤粺涓嶅悓浣嶇疆 + // https://github.com/FiYHer/InfinityHookPro/issues/17 win10 21h2.2130 瀹夎 KB5018410 琛ヤ竵鍚庨渶瑕佷娇鐢ㄦ柊鐨勭壒寰佺爜 unsigned long long EtwpDebuggerData = KUtils::FindPatternImage(ntoskrnl, "\x00\x00\x2c\x08\x04\x38\x0c", "??xxxxx", ".text"); if (!EtwpDebuggerData) EtwpDebuggerData = KUtils::FindPatternImage(ntoskrnl, "\x00\x00\x2c\x08\x04\x38\x0c", "??xxxxx", ".data"); if (!EtwpDebuggerData) EtwpDebuggerData = KUtils::FindPatternImage(ntoskrnl, "\x00\x00\x2c\x08\x04\x38\x0c", "??xxxxx", ".rdata"); @@ -259,36 +259,36 @@ namespace KHook if (!EtwpDebuggerData) return false; m_EtwpDebuggerData = (void*)EtwpDebuggerData; - // 这里暂时不知道怎么定位,偏移0x10在全部系统都一样 + // 杩欓噷鏆傛椂涓嶇煡閬撴庝箞瀹氫綅,鍋忕Щ0x10鍦ㄥ叏閮ㄧ郴缁熼兘涓鏍 m_EtwpDebuggerDataSilo = *(void***)((unsigned long long)m_EtwpDebuggerData + 0x10); DbgPrintEx(0, 0, "[%s] etwp debugger data silo is 0x%p \n", __FUNCTION__, m_EtwpDebuggerDataSilo); if (!m_EtwpDebuggerDataSilo) return false; - // 这里也不知道怎么定位,偏移0x2在全部系统都哦一样 + // 杩欓噷涔熶笉鐭ラ亾鎬庝箞瀹氫綅,鍋忕Щ0x2鍦ㄥ叏閮ㄧ郴缁熼兘鍝︿竴鏍 m_CkclWmiLoggerContext = m_EtwpDebuggerDataSilo[0x2]; DbgPrintEx(0, 0, "[%s] ckcl wmi logger context is 0x%p \n", __FUNCTION__, m_CkclWmiLoggerContext); if (!m_CkclWmiLoggerContext) return false; - /* Win7系统测试,m_GetCpuClock该值会改变几次,先阶段使用线程检测后修复 - * 靠,Win11的偏移变成了0x18,看漏的害我调试这么久 -_- - * 这里总结一下,Win7和Win11都是偏移0x18,其它的是0x28 + /* Win7绯荤粺娴嬭瘯,m_GetCpuClock璇ュ间細鏀瑰彉鍑犳,鍏堥樁娈典娇鐢ㄧ嚎绋嬫娴嬪悗淇 + * 闈,Win11鐨勫亸绉诲彉鎴愪簡0x18,鐪嬫紡鐨勫鎴戣皟璇曡繖涔堜箙 -_- + * 杩欓噷鎬荤粨涓涓,Win7鍜學in11閮芥槸鍋忕Щ0x18,鍏跺畠鐨勬槸0x28 */ - if (m_BuildNumber <= 7601 || m_BuildNumber >= 22000) m_GetCpuClock = (void**)((unsigned long long)m_CkclWmiLoggerContext + 0x18); // Win7版本以及更旧, Win11也是 - else m_GetCpuClock = (void**)((unsigned long long)m_CkclWmiLoggerContext + 0x28); // Win8 -> Win10全系统 + if (m_BuildNumber <= 7601 || m_BuildNumber >= 22000) m_GetCpuClock = (void**)((unsigned long long)m_CkclWmiLoggerContext + 0x18); // Win7鐗堟湰浠ュ強鏇存棫, Win11涔熸槸 + else m_GetCpuClock = (void**)((unsigned long long)m_CkclWmiLoggerContext + 0x28); // Win8 -> Win10鍏ㄧ郴缁 if (!MmIsAddressValid(m_GetCpuClock)) return false; DbgPrintEx(0, 0, "[%s] get cpu clock is 0x%p \n", __FUNCTION__, *m_GetCpuClock); - // 拿到ssdt指针 + // 鎷垮埌ssdt鎸囬拡 m_SystemCallTable = PAGE_ALIGN(KUtils::GetSyscallEntry(ntoskrnl)); DbgPrintEx(0, 0, "[%s] syscall table is 0x%p \n", __FUNCTION__, m_SystemCallTable); if (!m_SystemCallTable) return false; - if (m_BuildNumber > 18363) // 即版本1909 + if (m_BuildNumber > 18363) // 鍗崇増鏈1909 { - /* HvlGetQpcBias函数内部需要用到这个结构 - * 所以我们手动定位这个结构 + /* HvlGetQpcBias鍑芥暟鍐呴儴闇瑕佺敤鍒拌繖涓粨鏋 + * 鎵浠ユ垜浠墜鍔ㄥ畾浣嶈繖涓粨鏋 */ - // 特征码为 Win10 18363 至 Win11 22631全平台通用 + // 鐗瑰緛鐮佷负 Win10 18363 鑷 Win11 22631鍏ㄥ钩鍙伴氱敤 unsigned long long addressHvlpReferenceTscPage = KUtils::FindPatternImage(ntoskrnl, "\x48\x8b\x05\x00\x00\x00\x00\x48\x8b\x40\x00\x48\x8b\x0d\x00\x00\x00\x00\x48\xf7\xe2", "xxx????xxx?xxx????xxx"); @@ -300,22 +300,22 @@ namespace KHook m_HvlpReferenceTscPage = reinterpret_cast(reinterpret_cast(addressHvlpReferenceTscPage) + 7 + *reinterpret_cast(reinterpret_cast(addressHvlpReferenceTscPage) + 3)); DbgPrintEx(0, 0, "[%s] HvlpReferenceTscPage is 0x%llX \n", __FUNCTION__, m_HvlpReferenceTscPage); if (!m_HvlpReferenceTscPage) return false; - //-----------------------------------HvlpReferenceTscPage的原始值---------------------------- - //-----------------------------虚拟机------------------物理机----------------------- - //Win10 20H2 有 空 - //Win10 21H1 有 空 - //Win10 21H2 有 空 - //Win10 22H2 有 空 - //Win11 22000 有 空 - //Win11 22621 有 空 - //Win11 22631 有 空 + //-----------------------------------HvlpReferenceTscPage鐨勫師濮嬪---------------------------- + //-----------------------------铏氭嫙鏈------------------鐗╃悊鏈----------------------- + //Win10 20H2 鏈 绌 + //Win10 21H1 鏈 绌 + //Win10 21H2 鏈 绌 + //Win10 22H2 鏈 绌 + //Win11 22000 鏈 绌 + //Win11 22621 鏈 绌 + //Win11 22631 鏈 绌 DbgPrintEx(0, 0, "[%s] HvlpReferenceTscPage Value Is 0x%llX \n", __FUNCTION__, *reinterpret_cast(m_HvlpReferenceTscPage)); //if (*reinterpret_cast(m_HvlpReferenceTscPage) == 0) return false; - /* 这里我们查找到HvlGetQpcBias的指针 - * 详细介绍可以看https://www.freebuf.com/articles/system/278857.html + /* 杩欓噷鎴戜滑鏌ユ壘鍒癏vlGetQpcBias鐨勬寚閽 + * 璇︾粏浠嬬粛鍙互鐪媓ttps://www.freebuf.com/articles/system/278857.html */ - //在函数 HalpTimerQueryHostPerformanceCounter 中 + //鍦ㄥ嚱鏁 HalpTimerQueryHostPerformanceCounter 涓 //__int64 __fastcall HalpTimerQueryHostPerformanceCounter(_QWORD * a1) //{ // __int64 v2; // rbx @@ -332,13 +332,13 @@ namespace KHook // return 0i64; //} unsigned long long addressHvlGetQpcBias = 0; - //HalpTimerQueryHostPerformanceCounter中查找 HvlGetQpcBias 物理机 虚拟机 HvlGetQpcBias 值都为0 + //HalpTimerQueryHostPerformanceCounter涓煡鎵 HvlGetQpcBias 鐗╃悊鏈 铏氭嫙鏈 HvlGetQpcBias 鍊奸兘涓0 addressHvlGetQpcBias = KUtils::FindPatternImage(ntoskrnl, - "\x48\x8b\x05\x00\x00\x00\x00\x48\x85\xc0\x74\x00\x48\x83\x3d\x00\x00\x00\x00\x00\x74", // Win10 22H2以前 以及 Win11 22621以前 + "\x48\x8b\x05\x00\x00\x00\x00\x48\x85\xc0\x74\x00\x48\x83\x3d\x00\x00\x00\x00\x00\x74", // Win10 22H2浠ュ墠 浠ュ強 Win11 22621浠ュ墠 "xxx????xxxx?xxx?????x"); if (!addressHvlGetQpcBias) { - //该特征码全都有,但上个特征码在Win10 22H2 以及 Win11 22621以上没有,再搜索这个时就已经是 Win10 22H2 以及 Win11 22621以上版本 + //璇ョ壒寰佺爜鍏ㄩ兘鏈夛紝浣嗕笂涓壒寰佺爜鍦╓in10 22H2 浠ュ強 Win11 22621浠ヤ笂娌℃湁锛屽啀鎼滅储杩欎釜鏃跺氨宸茬粡鏄 Win10 22H2 浠ュ強 Win11 22621浠ヤ笂鐗堟湰 addressHvlGetQpcBias = KUtils::FindPatternImage(ntoskrnl, "\x48\x8b\x05\x00\x00\x00\x00\xe8\x00\x00\x00\x00\x48\x03\xd8\x48\x89\x1f", "xxx????x????xxxxxx"); @@ -351,27 +351,27 @@ namespace KHook m_HvlGetQpcBias = reinterpret_cast(reinterpret_cast(addressHvlGetQpcBias) + 7 + *reinterpret_cast(reinterpret_cast(addressHvlGetQpcBias) + 3)); DbgPrintEx(0, 0, "[%s] HvlGetQpcBias Is 0x%llX \n", __FUNCTION__, m_HvlGetQpcBias); if (!m_HvlGetQpcBias) return false; - //-----------------------------------HvlGetQpcBias的原始值---------------------------- - //-----------------------------虚拟机------------------物理机----------------------- - //Win10 20H2 空 空 - //Win10 21H1 空 空 - //Win10 21H2 空 空 - //Win10 22H2 空 空 - //Win11 22000 空 空 - //Win11 22621 空 空 - //Win11 22631 空 空 + //-----------------------------------HvlGetQpcBias鐨勫師濮嬪---------------------------- + //-----------------------------铏氭嫙鏈------------------鐗╃悊鏈----------------------- + //Win10 20H2 绌 绌 + //Win10 21H1 绌 绌 + //Win10 21H2 绌 绌 + //Win10 22H2 绌 绌 + //Win11 22000 绌 绌 + //Win11 22621 绌 绌 + //Win11 22631 绌 绌 DbgPrintEx(0, 0, "[%s] HvlGetQpcBias Value Is 0x%llX \n", __FUNCTION__, *(unsigned long long*)m_HvlGetQpcBias); - //HalpTimerQueryHostPerformanceCounter中查找 HvlGetReferenceTimeUsingTscPagePtr - //物理机 HvlGetReferenceTimeUsingTscPagePtr 值为0 + //HalpTimerQueryHostPerformanceCounter涓煡鎵 HvlGetReferenceTimeUsingTscPagePtr + //鐗╃悊鏈 HvlGetReferenceTimeUsingTscPagePtr 鍊间负0 unsigned long long addressHvlpGetReferenceTimeUsingTscPage = KUtils::FindPatternImage(ntoskrnl, - "\x48\x8b\x05\x00\x00\x00\x00\x48\x85\xc0\x74\x00\x33\xc9\xe8\x00\x00\x00\x00\x48\x8b\xd8", //Win10 22H2 和 Win11 22621及以上 + "\x48\x8b\x05\x00\x00\x00\x00\x48\x85\xc0\x74\x00\x33\xc9\xe8\x00\x00\x00\x00\x48\x8b\xd8", //Win10 22H2 鍜 Win11 22621鍙婁互涓 "xxx????xxxx?xxx????xxx"); if (!addressHvlpGetReferenceTimeUsingTscPage) { - //该特征码全平台都有,但上个特征码在 Win10 22H2以前, 以及 Win11 22621 以前没有,再搜索这个时就已经是 Win10 21H1、21H2、 以及 Win11 22000版本了 + //璇ョ壒寰佺爜鍏ㄥ钩鍙伴兘鏈夛紝浣嗕笂涓壒寰佺爜鍦 Win10 22H2浠ュ墠锛 浠ュ強 Win11 22621 浠ュ墠娌℃湁锛屽啀鎼滅储杩欎釜鏃跺氨宸茬粡鏄 Win10 21H1銆21H2銆 浠ュ強 Win11 22000鐗堟湰浜 addressHvlpGetReferenceTimeUsingTscPage = KUtils::FindPatternImage(ntoskrnl, "\x48\x8b\x05\x00\x00\x00\x00\xE8\x00\x00\x00\x00\x48\x03\xd8", "xxx????x????xxx"); @@ -386,21 +386,21 @@ namespace KHook *(int*)((char*)(addressHvlpGetReferenceTimeUsingTscPage)+3)); DbgPrintEx(0, 0, "[%s] HvlGetReferenceTimeUsingTscPage Is 0x%llX \n", __FUNCTION__, m_HvlpGetReferenceTimeUsingTscPage); if (!m_HvlpGetReferenceTimeUsingTscPage) return false; - //-----------------------HvlpGetReferenceTimeUsingTscPage的原始值---------------- - //--------------------------------------虚拟机---------------------------------------------------物理机----------------------- - //Win10 20H2 nt!HvlGetReferenceTimeUsingTscPage 空 - //Win10 21H1 nt!HvlGetReferenceTimeUsingTscPage 空 - //Win10 21H2 nt!HvlGetReferenceTimeUsingTscPage 空 - //Win10 22H2 nt!HvlGetReferenceTimeUsingTscPage 空 - //Win11 22000 nt!HvlGetReferenceTimeUsingTscPage 空 - //Win11 22621 nt!HvlGetReferenceTimeUsingTscPage 空 - //Win11 22631 nt!HvlGetReferenceTimeUsingTscPage 空 + //-----------------------HvlpGetReferenceTimeUsingTscPage鐨勫師濮嬪---------------- + //--------------------------------------铏氭嫙鏈---------------------------------------------------鐗╃悊鏈----------------------- + //Win10 20H2 nt!HvlGetReferenceTimeUsingTscPage 绌 + //Win10 21H1 nt!HvlGetReferenceTimeUsingTscPage 绌 + //Win10 21H2 nt!HvlGetReferenceTimeUsingTscPage 绌 + //Win10 22H2 nt!HvlGetReferenceTimeUsingTscPage 绌 + //Win11 22000 nt!HvlGetReferenceTimeUsingTscPage 绌 + //Win11 22621 nt!HvlGetReferenceTimeUsingTscPage 绌 + //Win11 22631 nt!HvlGetReferenceTimeUsingTscPage 绌 DbgPrintEx(0, 0, "[%s] HvlGetReferenceTimeUsingTscPage Value Is 0x%llX \n", __FUNCTION__, *reinterpret_cast(m_HvlpGetReferenceTimeUsingTscPage)); - //HalpTimerQueryHostPerformanceCounter中搜索HalpPerformanceCounter + //HalpTimerQueryHostPerformanceCounter涓悳绱alpPerformanceCounter unsigned long long addressHalpPerformanceCounter = KUtils::FindPatternImage(ntoskrnl, - "\x48\x8b\x05\x00\x00\x00\x00\x48\x8b\xf9\x48\x85\xc0\x74\x00\x83\xb8", //特征码全平台一样 + "\x48\x8b\x05\x00\x00\x00\x00\x48\x8b\xf9\x48\x85\xc0\x74\x00\x83\xb8", //鐗瑰緛鐮佸叏骞冲彴涓鏍 "xxx????xxxxxxx?xx"); if (!addressHalpPerformanceCounter) { @@ -414,43 +414,54 @@ namespace KHook DbgPrintEx(0, 0, "[%s] HalpPerformanceCounter Value is 0x%llX \n", __FUNCTION__, *reinterpret_cast(m_HalpPerformanceCounter)); - //在 KiUpdateTime中搜索HalpOriginalPerformanceCounter,Win10 21H1 至 Win11 22631 通用 + //鍦 KiUpdateTime涓悳绱alpOriginalPerformanceCounter锛學in10 21H1 鑷 Win11 22631 閫氱敤 unsigned long long addressHalpOriginalPerformanceCounter = KUtils::FindPatternImage(ntoskrnl, "\x48\x8b\x05\x00\x00\x00\x00\x48\x3b\x00\x0f\x85\x00\x00\x00\x00\xA0", "xxx????xx?xx????x"); if (!addressHalpOriginalPerformanceCounter) { - //Win11 23606 之后,在 KeQueryPerformanceCounter 中搜索HalpOriginalPerformanceCounter + //Win11 23606 涔嬪悗,鍦 KeQueryPerformanceCounter 涓悳绱alpOriginalPerformanceCounter addressHalpOriginalPerformanceCounter = KUtils::FindPatternImage(ntoskrnl, "\x48\x8b\x0d\x00\x00\x00\x00\x4c\x00\x00\x00\x00\x48\x3b\xf1", "xxx????x????xxx"); - if (!addressHalpOriginalPerformanceCounter) + + } + if (!addressHalpOriginalPerformanceCounter) + { + //鍦╓in11 29648 鍙嶆眹缂栧緱鍒扮殑鐗瑰緛鐮 + addressHalpOriginalPerformanceCounter = KUtils::FindPatternImage(ntoskrnl, + "\x48\xF7\xE2\x4C\x03\xDA\x48\x8B\x05\x00\x00\x00\x00\x48\x3B\xF0", + "xxxxxxxxx????xxx"); + if (addressHalpOriginalPerformanceCounter) { - DbgPrintEx(0, 0, "[%s] Find HalpOriginalPerformanceCounter Failed! \n", __FUNCTION__); - return false; + addressHalpOriginalPerformanceCounter += 6; } + if (!addressHalpOriginalPerformanceCounter) + { + DbgPrintEx(0, 0, "[%s] Find HalpOriginalPerformanceCounter Failed! \n", __FUNCTION__); + return false; + } } - m_HalpOriginalPerformanceCounter = reinterpret_cast (reinterpret_cast(addressHalpOriginalPerformanceCounter) + 7 + *reinterpret_cast(reinterpret_cast(addressHalpOriginalPerformanceCounter) + 3)); DbgPrintEx(0, 0, "[%s] HalpOriginalPerformanceCounter Is 0x%llX \n", __FUNCTION__, m_HalpOriginalPerformanceCounter); if (!m_HalpOriginalPerformanceCounter) return false; DbgPrintEx(0, 0, "[%s] HalpOriginalPerformanceCounter Value Is 0x%llX \n", __FUNCTION__, *reinterpret_cast(m_HalpOriginalPerformanceCounter)); - //HalpPerformanceCounter中类型的指针,后面进行修改时使用 + //HalpPerformanceCounter涓被鍨嬬殑鎸囬拡锛屽悗闈㈣繘琛屼慨鏀规椂浣跨敤 m_HalpPerformanceCounterType = (ULONG*)((ULONG_PTR)(*(PVOID*)m_HalpPerformanceCounter) + HALP_PERFORMANCE_COUNTER_TYPE_OFFSET); if (!m_HalpPerformanceCounterType) { DbgPrintEx(0, 0, "[%s] m_HalpPerformanceCounterType Is Null! \n", __FUNCTION__); return false; } - //判断在物理机上时才进行后边的操作 + //鍒ゆ柇鍦ㄧ墿鐞嗘満涓婃椂鎵嶈繘琛屽悗杈圭殑鎿嶄綔 if (*m_HalpPerformanceCounterType == HALP_PERFORMANCE_COUNTER_TYPE_PHYSICAL_MACHINE) { - //搜索HalpTimerQueryHostPerformanceCounter中判断的Type值,其实也可以直接判断系统版本 - //参考HalpTimerQueryHostPerformanceCounter中 *(_DWORD *)(HalpPerformanceCounter + 0xE4) != 7 , - //Win11 22000 及以下值为8 22621 以上为7 - //利用前边搜索的 addressHalpPerformanceCounter,以下注释为Win11 22621 HalpTimerQueryHostPerformanceCounter 的 IDA逆向代码 + //鎼滅储HalpTimerQueryHostPerformanceCounter涓垽鏂殑Type鍊硷紝鍏跺疄涔熷彲浠ョ洿鎺ュ垽鏂郴缁熺増鏈 + //鍙傝僅alpTimerQueryHostPerformanceCounter涓 *(_DWORD *)(HalpPerformanceCounter + 0xE4) != 7 , + //Win11 22000 鍙婁互涓嬪间负8 22621 浠ヤ笂涓7 + //鍒╃敤鍓嶈竟鎼滅储鐨 addressHalpPerformanceCounter,浠ヤ笅娉ㄩ噴涓篧in11 22621 HalpTimerQueryHostPerformanceCounter 鐨 IDA閫嗗悜浠g爜 //.text : 0000000140520A1A 48 8B 05 8F 36 74 00 mov rax, cs : HalpPerformanceCounter //.text : 0000000140520A21 48 8B F9 mov rdi, rcx //.text : 0000000140520A24 48 85 C0 test rax, rax @@ -459,9 +470,9 @@ namespace KHook m_VmHalpPerformanceCounterType = *(reinterpret_cast(addressHalpPerformanceCounter) + 21); DbgPrintEx(0, 0, "[%s] HalpPerformanceCounterType In Virtual Machine Value is 0x%x \n", __FUNCTION__, m_VmHalpPerformanceCounterType); - //分配一个同HalpPerformanceCounter一样的空间,用来替换HalpOriginalPerformanceCounter, - //替换的数据中Type为 5, 倍数为基准的 10000000, - //ntoskrnl中的原逻辑为 HalpOriginalPerformanceCounter = HalpPerformanceCounter + //鍒嗛厤涓涓悓HalpPerformanceCounter涓鏍风殑绌洪棿锛岀敤鏉ユ浛鎹alpOriginalPerformanceCounter锛 + //鏇挎崲鐨勬暟鎹腑Type涓 5, 鍊嶆暟涓哄熀鍑嗙殑 10000000, + //ntoskrnl涓殑鍘熼昏緫涓 HalpOriginalPerformanceCounter = HalpPerformanceCounter m_HalpOriginalPerformanceCounterCopy = (ULONGLONG)ExAllocatePoolWithTag(NonPagedPool, 0xFF, 'freP'); if (!m_HalpOriginalPerformanceCounterCopy) { @@ -469,12 +480,12 @@ namespace KHook return false; } RtlZeroMemory((PVOID)m_HalpOriginalPerformanceCounterCopy, 0xFF); - //设置基本速度, + //璁剧疆鍩烘湰閫熷害锛 *(PULONGLONG)(m_HalpOriginalPerformanceCounterCopy + HALP_PERFORMANCE_COUNTER_BASE_RATE_OFFSET) = HALP_PERFORMANCE_COUNTER_BASE_RATE; *(PULONG)(m_HalpOriginalPerformanceCounterCopy + HALP_PERFORMANCE_COUNTER_TYPE_OFFSET) = HALP_PERFORMANCE_COUNTER_TYPE_PHYSICAL_MACHINE; - DbgPrintEx(0, 0, "[%s] m_HalpOriginalPerformanceCounterCopy:0x%llX \n", __FUNCTION__, m_HalpOriginalPerformanceCounterCopy); + DbgPrintEx(0, 0, "[%s] m_HalpOriginalPerformanceCounterCopy锛0x%llX \n", __FUNCTION__, m_HalpOriginalPerformanceCounterCopy); - // KUSER_SHARED_DATA的QpcBias字段,在从系统从睡眠状态恢复正常状态后停止时,系统时间修正时使用 + // KUSER_SHARED_DATA鐨凲pcBias瀛楁锛屽湪浠庣郴缁熶粠鐫$湢鐘舵佹仮澶嶆甯哥姸鎬佸悗鍋滄鏃讹紝绯荤粺鏃堕棿淇鏃朵娇鐢 PLONGLONG pQpcPointer = (PLONGLONG)0xFFFFF780000003B8; m_QpcMdl = IoAllocateMdl(pQpcPointer, 8, false, false, NULL); if (!m_QpcMdl) @@ -505,28 +516,28 @@ namespace KHook { if (!m_InfinityCallback) return false; - // 无效指针 + // 鏃犳晥鎸囬拡 if (!MmIsAddressValid(m_GetCpuClock)) { DbgPrintEx(0, 0, "[%s] get cpu clock vaild \n", __FUNCTION__); return false; } - /* 这里我们区分一下系统版本 - * 从Win7到Win10 1909,m_GetCpuClock是一个函数,往后的版本是一个数值了 - * 大于3抛异常 - * 等于3用rdtsc - * 等于2用off_140C00A30 - * 等于1用KeQueryPerformanceCounter - * 等于0用RtlGetSystemTimePrecise - * 我们的做法参考网址https://www.freebuf.com/articles/system/278857.html - * 我们这里在2身上做文章 + /* 杩欓噷鎴戜滑鍖哄垎涓涓嬬郴缁熺増鏈 + * 浠嶹in7鍒癢in10 1909,m_GetCpuClock鏄竴涓嚱鏁,寰鍚庣殑鐗堟湰鏄竴涓暟鍊间簡 + * 澶т簬3鎶涘紓甯 + * 绛変簬3鐢╮dtsc + * 绛変簬2鐢╫ff_140C00A30 + * 绛変簬1鐢↘eQueryPerformanceCounter + * 绛変簬0鐢≧tlGetSystemTimePrecise + * 鎴戜滑鐨勫仛娉曞弬鑰冪綉鍧https://www.freebuf.com/articles/system/278857.html + * 鎴戜滑杩欓噷鍦2韬笂鍋氭枃绔 */ - // 保存GetCpuClock原始值,退出时好恢复 + // 淇濆瓨GetCpuClock鍘熷鍊,閫鍑烘椂濂芥仮澶 m_OriginalGetCpuClock = (unsigned long long)(*m_GetCpuClock); if (m_BuildNumber <= 18363) { - // 直接修改函数指针 + // 鐩存帴淇敼鍑芥暟鎸囬拡 DbgPrintEx(0, 0, "[%s] GetCpuClock Is 0x%p\n", __FUNCTION__, *m_GetCpuClock); *m_GetCpuClock = SelfGetCpuClock; DbgPrintEx(0, 0, "[%s] Update GetCpuClock Is 0x%p\n", __FUNCTION__, *m_GetCpuClock); @@ -534,24 +545,24 @@ namespace KHook else { - /* 这里我们设置为2, 这样子才能调用off_140C00A30函数 - * 其实该指针就是HalpTimerQueryHostPerformanceCounter函数 - * 该函数里面又有两个函数指针,第一个就是HvlGetQpcBias,就是我们的目标 + /* 杩欓噷鎴戜滑璁剧疆涓2, 杩欐牱瀛愭墠鑳借皟鐢╫ff_140C00A30鍑芥暟 + * 鍏跺疄璇ユ寚閽堝氨鏄疕alpTimerQueryHostPerformanceCounter鍑芥暟 + * 璇ュ嚱鏁伴噷闈㈠張鏈変袱涓嚱鏁版寚閽,绗竴涓氨鏄疕vlGetQpcBias,灏辨槸鎴戜滑鐨勭洰鏍 */ *m_GetCpuClock = (void*)2; DbgPrintEx(0, 0, "[%s] Update GetCpuClock Is %p \n", __FUNCTION__, *m_GetCpuClock); - // 保存旧HvlGetQpcBias地址,方便后面清理的时候复原环境 + // 淇濆瓨鏃vlGetQpcBias鍦板潃,鏂逛究鍚庨潰娓呯悊鐨勬椂鍊欏鍘熺幆澧 m_OriginalHvlGetQpcBias = (HvlGetQpcBiasPtr)(*((unsigned long long*)m_HvlGetQpcBias)); - //物理机HvlpGetReferenceTimeUsingTscPage为空,在虚拟机上指向HvlGetReferenceTimeUsingTscPage函数, - //故在值为空时进行修改,但改为HvlGetReferenceTimeUsingTscPage后蓝屏,尝试改为NtYieldExecution但未导出,改ZwYieldExecution后导致重入错误, - //经实验改为一个没有参数的函数,函数返回 __rdtsc + //鐗╃悊鏈篐vlpGetReferenceTimeUsingTscPage涓虹┖锛屽湪铏氭嫙鏈轰笂鎸囧悜HvlGetReferenceTimeUsingTscPage鍑芥暟锛 + //鏁呭湪鍊间负绌烘椂杩涜淇敼锛屼絾鏀逛负HvlGetReferenceTimeUsingTscPage鍚庤摑灞忥紝灏濊瘯鏀逛负NtYieldExecution浣嗘湭瀵煎嚭锛屾敼ZwYieldExecution鍚庡鑷撮噸鍏ラ敊璇紝 + //缁忓疄楠屾敼涓轰竴涓病鏈夊弬鏁扮殑鍑芥暟,鍑芥暟杩斿洖 __rdtsc if (m_HvlpGetReferenceTimeUsingTscPage) { - //不能使用原来的HvlGetReferenceTimeUsingTscPage,在 HvlpGetReferenceTimeUsingTscPage 值为空时,函数里的有数据结构未初始化 + //涓嶈兘浣跨敤鍘熸潵鐨凥vlGetReferenceTimeUsingTscPage锛屽湪 HvlpGetReferenceTimeUsingTscPage 鍊间负绌烘椂锛屽嚱鏁伴噷鐨勬湁鏁版嵁缁撴瀯鏈垵濮嬪寲 m_OriginalHvlpGetReferenceTimeUsingTscPage = *((unsigned long long*)m_HvlpGetReferenceTimeUsingTscPage); - if (m_OriginalHvlpGetReferenceTimeUsingTscPage == 0) //只在HvlpGetReferenceTimeUsingTscPage值为空时才设置,其它保持原始不变 + if (m_OriginalHvlpGetReferenceTimeUsingTscPage == 0) //鍙湪HvlpGetReferenceTimeUsingTscPage鍊间负绌烘椂鎵嶈缃紝鍏跺畠淇濇寔鍘熷涓嶅彉 { *((unsigned long long*)m_HvlpGetReferenceTimeUsingTscPage) = (ULONGLONG)FakeGetReferenceTimeUsingTscPage; DbgPrintEx(0, 0, "[%s] Update HvlpGetReferenceTimeUsingTscPage Value : %p \n", __FUNCTION__, (PVOID)FakeGetReferenceTimeUsingTscPage); @@ -560,25 +571,25 @@ namespace KHook } - //这个是性能计数器的类型 在虚拟机上为 7或者8 物理机上为 5 参见 HalpTimerSelectRoles 中的 HalpTimerFindIdealPerformanceCounterSource + //杩欎釜鏄ц兘璁℃暟鍣ㄧ殑绫诲瀷 鍦ㄨ櫄鎷熸満涓婁负 7鎴栬8 鐗╃悊鏈轰笂涓 5 鍙傝 HalpTimerSelectRoles 涓殑 HalpTimerFindIdealPerformanceCounterSource m_OriginalHalpPerformanceCounterType = *m_HalpPerformanceCounterType; DbgPrintEx(0, 0, "[%s] Original HalpPerformanceCounterType Value : %d\n", __FUNCTION__, m_OriginalHalpPerformanceCounterType); - if (*m_HalpPerformanceCounterType == HALP_PERFORMANCE_COUNTER_TYPE_PHYSICAL_MACHINE) //只在物理机的情况下进行修改 + if (*m_HalpPerformanceCounterType == HALP_PERFORMANCE_COUNTER_TYPE_PHYSICAL_MACHINE) //鍙湪鐗╃悊鏈虹殑鎯呭喌涓嬭繘琛屼慨鏀 { - //更改 HalpOriginalPerformanceCounter,原值为 m_HalpPerformanceCounter的值 + //鏇存敼 HalpOriginalPerformanceCounter锛屽師鍊间负 m_HalpPerformanceCounter鐨勫 *(unsigned long long*)m_HalpOriginalPerformanceCounter = m_HalpOriginalPerformanceCounterCopy; DbgPrintEx(0, 0, "[%s] Update HalpOriginalPerformanceCounter Value: %llX\n", __FUNCTION__, m_HalpOriginalPerformanceCounterCopy); LARGE_INTEGER li = KeQueryPerformanceCounter(NULL); DbgPrintEx(0, 0, "[%s] Tick Count %lld \n", __FUNCTION__, li.QuadPart); - //需要把性能计数器类型改为虚拟机环境下的判断值,调整逻辑 参见 HalpTimerSelectRoles 中的 HalpTimerFindIdealPerformanceCounterSource - *m_HalpPerformanceCounterType = m_VmHalpPerformanceCounterType; //改为虚拟机环境中的类型,7或者8 + //闇瑕佹妸鎬ц兘璁℃暟鍣ㄧ被鍨嬫敼涓鸿櫄鎷熸満鐜涓嬬殑鍒ゆ柇鍊硷紝璋冩暣閫昏緫 鍙傝 HalpTimerSelectRoles 涓殑 HalpTimerFindIdealPerformanceCounterSource + *m_HalpPerformanceCounterType = m_VmHalpPerformanceCounterType; //鏀逛负铏氭嫙鏈虹幆澧冧腑鐨勭被鍨嬶紝7鎴栬8 DbgPrintEx(0, 0, "[%s] Update HalpPerformanceCounterType Value : %d\n", __FUNCTION__, m_VmHalpPerformanceCounterType); li = KeQueryPerformanceCounter(NULL); DbgPrintEx(0, 0, "[%s] Tick Count %lld \n", __FUNCTION__, li.QuadPart); } - // 设置钩子 + // 璁剧疆閽╁瓙 *((unsigned long long*)m_HvlGetQpcBias) = (unsigned long long)FakeHvlGetQpcBias; DbgPrintEx(0, 0, "[%s] Update HvlGetQpcBias Value is %p \n", __FUNCTION__, FakeHvlGetQpcBias); @@ -610,7 +621,7 @@ namespace KHook bool Stop() { - // 停止检测线程 + // 鍋滄妫娴嬬嚎绋 m_DetectThreadStatus = false; bool bResult = NT_SUCCESS(EventTraceControl(EtwpStopTrace)) && NT_SUCCESS(EventTraceControl(EtwpStartTrace)); @@ -620,8 +631,8 @@ namespace KHook { DbgPrintEx(0, 0, "[%s] Wait For Detect Thread Termination \n", __FUNCTION__); KeWaitForSingleObject(m_DetectThreadObject, Executive, KernelMode, false, NULL); - //Win7 7600 系统为 ObDereferenceObject, Win7 7601及以上为ObfDereferenceObject - //采用MmGetSystemRoutineAddress动态获取相应的函数地址,解决在Win7 7600上不能加载驱动问题 + //Win7 7600 绯荤粺涓 ObDereferenceObject, Win7 7601鍙婁互涓婁负ObfDereferenceObject + //閲囩敤MmGetSystemRoutineAddress鍔ㄦ佽幏鍙栫浉搴旂殑鍑芥暟鍦板潃锛岃В鍐冲湪Win7 7600涓婁笉鑳藉姞杞介┍鍔ㄩ棶棰 UNICODE_STRING usObfDereferenceObject = RTL_CONSTANT_STRING(L"ObfDereferenceObject"); ObfDereferenceObjectPtr fnObfDereferenceObject = (ObfDereferenceObjectPtr)MmGetSystemRoutineAddress(&usObfDereferenceObject); if (fnObfDereferenceObject) @@ -645,16 +656,16 @@ namespace KHook /*ObDereferenceObject(m_DetectThreadObject);*/ DbgPrintEx(0, 0, "[%s] Detect Thread Terminated \n", __FUNCTION__); } - //m_GetCpuClock值还原要在线程停止之后,否则可能还原后又被线程里的逻辑改为我们的函数了 + //m_GetCpuClock鍊艰繕鍘熻鍦ㄧ嚎绋嬪仠姝箣鍚庯紝鍚﹀垯鍙兘杩樺師鍚庡張琚嚎绋嬮噷鐨勯昏緫鏀逛负鎴戜滑鐨勫嚱鏁颁簡 *m_GetCpuClock = (void*)m_OriginalGetCpuClock; DbgPrintEx(0, 0, "[%s] Restore GetCpuClock is %p \n", __FUNCTION__, *m_GetCpuClock); - // Win10 1909以上系统需要恢复环境 + // Win10 1909浠ヤ笂绯荤粺闇瑕佹仮澶嶇幆澧 if (m_BuildNumber > 18363) { if (m_HvlpGetReferenceTimeUsingTscPage) { - //还原 HvlpGetReferenceTimeUsingTscPage的值为m_OriginalHvlpGetReferenceTimeUsingTscPage,也即 0 + //杩樺師 HvlpGetReferenceTimeUsingTscPage鐨勫间负m_OriginalHvlpGetReferenceTimeUsingTscPage锛屼篃鍗 0 if (m_OriginalHvlpGetReferenceTimeUsingTscPage == 0) { *((unsigned long long*)m_HvlpGetReferenceTimeUsingTscPage) = m_OriginalHvlpGetReferenceTimeUsingTscPage; @@ -662,20 +673,20 @@ namespace KHook } } - //只在物理机上进行以下还原 + //鍙湪鐗╃悊鏈轰笂杩涜浠ヤ笅杩樺師 if (m_OriginalHalpPerformanceCounterType == HALP_PERFORMANCE_COUNTER_TYPE_PHYSICAL_MACHINE) { LARGE_INTEGER liBegin = KeQueryPerformanceCounter(NULL); DbgPrintEx(0, 0, "[%s] Tick Count Before Restore %lld \n", __FUNCTION__, liBegin.QuadPart); - //还原 顺序保持下面的顺序 + //杩樺師 椤哄簭淇濇寔涓嬮潰鐨勯『搴 *m_HalpPerformanceCounterType = m_OriginalHalpPerformanceCounterType; - //不能还原m_HalpOriginalPerformanceCounter为原始的值 m_HalpPerformanceCounter, - //而需要保留m_HalpOriginalPerformanceCounter为m_HalpOriginalPerformanceCounterCopy的值 - //否则还原后计数器时间返回会比之前小很多导致死锁 + //涓嶈兘杩樺師m_HalpOriginalPerformanceCounter涓哄師濮嬬殑鍊 m_HalpPerformanceCounter, + //鑰岄渶瑕佷繚鐣檓_HalpOriginalPerformanceCounter涓簃_HalpOriginalPerformanceCounterCopy鐨勫 + //鍚﹀垯杩樺師鍚庤鏁板櫒鏃堕棿杩斿洖浼氭瘮涔嬪墠灏忓緢澶氬鑷存閿 //*(unsigned long long*)m_HalpOriginalPerformanceCounter = m_HalpPerformanceCounter; LARGE_INTEGER liEndFix = KeQueryPerformanceCounter(NULL); - //修正睡眠之后恢复正常停止时时间错误导致系统假死问题 + //淇鐫$湢涔嬪悗鎭㈠姝e父鍋滄鏃舵椂闂撮敊璇鑷寸郴缁熷亣姝婚棶棰 if (liEndFix.QuadPart - liBegin.QuadPart > HALP_PERFORMANCE_COUNTER_BASE_RATE) { LONGLONG llQpcValue = *m_QpcPointer; From ca555e834fd647906b3411c18f71d575b0a7856c Mon Sep 17 00:00:00 2001 From: SamsungSHC <164715881+SamsungSHC@users.noreply.github.com> Date: Wed, 26 Aug 2026 17:36:23 +0800 Subject: [PATCH 2/2] diff --- InfinityHookPro/hook.cpp | 1296 +++++++++++++++++++------------------- 1 file changed, 648 insertions(+), 648 deletions(-) diff --git a/InfinityHookPro/hook.cpp b/InfinityHookPro/hook.cpp index 857b1f3..90f4ea9 100644 --- a/InfinityHookPro/hook.cpp +++ b/InfinityHookPro/hook.cpp @@ -4,720 +4,720 @@ namespace KHook { - InfinityCallbackPtr m_InfinityCallback = nullptr; - unsigned long m_BuildNumber = 0; - void* m_SystemCallTable = nullptr; - bool m_DetectThreadStatus = true; - void* m_EtwpDebuggerData = nullptr; - void* m_CkclWmiLoggerContext = nullptr; - void** m_EtwpDebuggerDataSilo = nullptr; - void** m_GetCpuClock = nullptr; - PETHREAD m_DetectThreadObject = NULL; - PLONGLONG m_QpcPointer = NULL; - PMDL m_QpcMdl = NULL; - unsigned long long m_OriginalGetCpuClock = 0; - unsigned long long m_HvlpReferenceTscPage = 0; - unsigned long long m_HvlGetQpcBias = 0; - unsigned long long m_HvlpGetReferenceTimeUsingTscPage = 0; - unsigned long long m_HalpPerformanceCounter = 0; - unsigned long long m_HalpOriginalPerformanceCounter = 0; - unsigned long long m_HalpOriginalPerformanceCounterCopy = 0; - unsigned long* m_HalpPerformanceCounterType = 0; - unsigned char m_VmHalpPerformanceCounterType = 0; - unsigned long m_OriginalHalpPerformanceCounterType = 0; - unsigned long long m_OriginalHvlpGetReferenceTimeUsingTscPage = 0; - typedef __int64 (*FHvlGetQpcBias)(); - FHvlGetQpcBias m_OriginalHvlGetQpcBias = nullptr; - CLIENT_ID m_ClientId = { 0 }; - - // 淇敼璺熻釜璁剧疆 - NTSTATUS EventTraceControl(ETWP_TRACE_TYPE nType) + InfinityCallbackPtr m_InfinityCallback = nullptr; + unsigned long m_BuildNumber = 0; + void* m_SystemCallTable = nullptr; + bool m_DetectThreadStatus = true; + void* m_EtwpDebuggerData = nullptr; + void* m_CkclWmiLoggerContext = nullptr; + void** m_EtwpDebuggerDataSilo = nullptr; + void** m_GetCpuClock = nullptr; + PETHREAD m_DetectThreadObject = NULL; + PLONGLONG m_QpcPointer = NULL; + PMDL m_QpcMdl = NULL; + unsigned long long m_OriginalGetCpuClock = 0; + unsigned long long m_HvlpReferenceTscPage = 0; + unsigned long long m_HvlGetQpcBias = 0; + unsigned long long m_HvlpGetReferenceTimeUsingTscPage = 0; + unsigned long long m_HalpPerformanceCounter = 0; + unsigned long long m_HalpOriginalPerformanceCounter = 0; + unsigned long long m_HalpOriginalPerformanceCounterCopy = 0; + unsigned long* m_HalpPerformanceCounterType = 0; + unsigned char m_VmHalpPerformanceCounterType = 0; + unsigned long m_OriginalHalpPerformanceCounterType = 0; + unsigned long long m_OriginalHvlpGetReferenceTimeUsingTscPage = 0; + typedef __int64 (*FHvlGetQpcBias)(); + FHvlGetQpcBias m_OriginalHvlGetQpcBias = nullptr; + CLIENT_ID m_ClientId = { 0 }; + + // 淇敼璺熻釜璁剧疆 + NTSTATUS EventTraceControl(ETWP_TRACE_TYPE nType) + { + const unsigned long nTag = 'VMON'; + + // 鐢宠缁撴瀯浣撶┖闂 + CKCL_TRACE_PROPERTIES* pProperty = (CKCL_TRACE_PROPERTIES*)ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, nTag); + if (!pProperty) { - const unsigned long nTag = 'VMON'; - - // 鐢宠缁撴瀯浣撶┖闂 - CKCL_TRACE_PROPERTIES* pProperty = (CKCL_TRACE_PROPERTIES*)ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, nTag); - if (!pProperty) - { - DbgPrintEx(0, 0, "[%s] allocate ckcl trace propertice struct fail \n", __FUNCTION__); - return STATUS_MEMORY_NOT_ALLOCATED; - } - - // 鐢宠淇濆瓨鍚嶇О鐨勭┖闂 - wchar_t* szProviderName = (wchar_t*)ExAllocatePoolWithTag(NonPagedPool, 256 * sizeof(wchar_t), nTag); - if (!szProviderName) - { - DbgPrintEx(0, 0, "[%s] allocate provider name fail \n", __FUNCTION__); - ExFreePoolWithTag(pProperty, nTag); - return STATUS_MEMORY_NOT_ALLOCATED; - } - - // 娓呯┖鍐呭瓨 - RtlZeroMemory(pProperty, PAGE_SIZE); - RtlZeroMemory(szProviderName, 256 * sizeof(wchar_t)); - - // 鍚嶇О璧嬪 - RtlCopyMemory(szProviderName, L"Circular Kernel Context Logger", sizeof(L"Circular Kernel Context Logger")); - RtlInitUnicodeString(&pProperty->ProviderName, (const wchar_t*)szProviderName); - - // 鍞竴鏍囪瘑绗 - GUID guidCkclSession = { 0x54dea73a, 0xed1f, 0x42a4, { 0xaf, 0x71, 0x3e, 0x63, 0xd0, 0x56, 0xf1, 0x74 } }; - - // 缁撴瀯浣撳~鍏 - pProperty->Wnode.BufferSize = PAGE_SIZE; - pProperty->Wnode.Flags = WNODE_FLAG_TRACED_GUID; - pProperty->Wnode.Guid = guidCkclSession; - pProperty->Wnode.ClientContext = 3; - pProperty->BufferSize = sizeof(unsigned long); - pProperty->MinimumBuffers = 2; - pProperty->MaximumBuffers = 2; - pProperty->LogFileMode = EVENT_TRACE_BUFFERING_MODE; - - // 鎵ц鎿嶄綔 - unsigned long nLength = 0; - if (nType == ETWP_TRACE_TYPE::EtwpUpdateTrace) pProperty->EnableFlags = EVENT_TRACE_FLAG_SYSTEMCALL; - NTSTATUS ntStatus = NtTraceControl(nType, pProperty, PAGE_SIZE, pProperty, PAGE_SIZE, &nLength); - - // 閲婃斁鍐呭瓨绌洪棿 - ExFreePoolWithTag(szProviderName, nTag); - ExFreePoolWithTag(pProperty, nTag); - - return ntStatus; + DbgPrintEx(0, 0, "[%s] allocate ckcl trace propertice struct fail \n", __FUNCTION__); + return STATUS_MEMORY_NOT_ALLOCATED; } - // 鎴戜滑鐨勬浛鎹㈠嚱鏁,閽堝鐨勬槸浠嶹in7鍒癢in10 1909鐨勭郴缁 - unsigned long long SelfGetCpuClock() + // 鐢宠淇濆瓨鍚嶇О鐨勭┖闂 + wchar_t* szProviderName = (wchar_t*)ExAllocatePoolWithTag(NonPagedPool, 256 * sizeof(wchar_t), nTag); + if (!szProviderName) { - // 鏀捐繃鍐呮牳妯″紡鐨勮皟鐢 - if (ExGetPreviousMode() == KernelMode) return __rdtsc(); - - // 鎷垮埌褰撳墠绾跨▼ - PKTHREAD pCurrentThread = (PKTHREAD)__readgsqword(0x188); - - // 涓嶅悓鐗堟湰涓嶅悓鍋忕Щ - unsigned int nCallIndex = 0; - if (m_BuildNumber <= 7601) nCallIndex = *(unsigned int*)((unsigned long long)pCurrentThread + 0x1f8); - else nCallIndex = *(unsigned int*)((unsigned long long)pCurrentThread + 0x80); - - // 鎷垮埌褰撳墠鏍堝簳鍜屾爤椤 - void** pStackMax = (void**)__readgsqword(0x1a8); - void** pStackFrame = (void**)_AddressOfReturnAddress(); + DbgPrintEx(0, 0, "[%s] allocate provider name fail \n", __FUNCTION__); + ExFreePoolWithTag(pProperty, nTag); + return STATUS_MEMORY_NOT_ALLOCATED; + } - // 寮濮嬫煡鎵惧綋鍓嶆爤涓殑ssdt璋冪敤 - for (void** pStackCurrent = pStackMax; pStackCurrent > pStackFrame; --pStackCurrent) - { - /* 鍑芥暟 PerfInfoLogSysCallEntry閫嗗悜 - Win11 23606 浠ュ墠 鏍堜腑ssdt璋冪敤鐗瑰緛, 鍒嗗埆鏄 - mov r9d, 0F33h - mov [rsp+48h+var_20], 501802h - Win11 23606 鍙婁互鍚 鏍堜腑ssdt璋冪敤鐗瑰緛, 鍒嗗埆鏄 - mov r9d, 0F33h - mov[rsp + 58h + var_30], 601802h - */ + // 娓呯┖鍐呭瓨 + RtlZeroMemory(pProperty, PAGE_SIZE); + RtlZeroMemory(szProviderName, 256 * sizeof(wchar_t)); + + // 鍚嶇О璧嬪 + RtlCopyMemory(szProviderName, L"Circular Kernel Context Logger", sizeof(L"Circular Kernel Context Logger")); + RtlInitUnicodeString(&pProperty->ProviderName, (const wchar_t*)szProviderName); + + // 鍞竴鏍囪瘑绗 + GUID guidCkclSession = { 0x54dea73a, 0xed1f, 0x42a4, { 0xaf, 0x71, 0x3e, 0x63, 0xd0, 0x56, 0xf1, 0x74 } }; + + // 缁撴瀯浣撳~鍏 + pProperty->Wnode.BufferSize = PAGE_SIZE; + pProperty->Wnode.Flags = WNODE_FLAG_TRACED_GUID; + pProperty->Wnode.Guid = guidCkclSession; + pProperty->Wnode.ClientContext = 3; + pProperty->BufferSize = sizeof(unsigned long); + pProperty->MinimumBuffers = 2; + pProperty->MaximumBuffers = 2; + pProperty->LogFileMode = EVENT_TRACE_BUFFERING_MODE; + + // 鎵ц鎿嶄綔 + unsigned long nLength = 0; + if (nType == ETWP_TRACE_TYPE::EtwpUpdateTrace) pProperty->EnableFlags = EVENT_TRACE_FLAG_SYSTEMCALL; + NTSTATUS ntStatus = NtTraceControl(nType, pProperty, PAGE_SIZE, pProperty, PAGE_SIZE, &nLength); + + // 閲婃斁鍐呭瓨绌洪棿 + ExFreePoolWithTag(szProviderName, nTag); + ExFreePoolWithTag(pProperty, nTag); + + return ntStatus; + } + + // 鎴戜滑鐨勬浛鎹㈠嚱鏁,閽堝鐨勬槸浠嶹in7鍒癢in10 1909鐨勭郴缁 + unsigned long long SelfGetCpuClock() + { + // 鏀捐繃鍐呮牳妯″紡鐨勮皟鐢 + if (ExGetPreviousMode() == KernelMode) return __rdtsc(); + + // 鎷垮埌褰撳墠绾跨▼ + PKTHREAD pCurrentThread = (PKTHREAD)__readgsqword(0x188); + + // 涓嶅悓鐗堟湰涓嶅悓鍋忕Щ + unsigned int nCallIndex = 0; + if (m_BuildNumber <= 7601) nCallIndex = *(unsigned int*)((unsigned long long)pCurrentThread + 0x1f8); + else nCallIndex = *(unsigned int*)((unsigned long long)pCurrentThread + 0x80); + + // 鎷垮埌褰撳墠鏍堝簳鍜屾爤椤 + void** pStackMax = (void**)__readgsqword(0x1a8); + void** pStackFrame = (void**)_AddressOfReturnAddress(); + + // 寮濮嬫煡鎵惧綋鍓嶆爤涓殑ssdt璋冪敤 + for (void** pStackCurrent = pStackMax; pStackCurrent > pStackFrame; --pStackCurrent) + { + /* 鍑芥暟 PerfInfoLogSysCallEntry閫嗗悜 + Win11 23606 浠ュ墠 鏍堜腑ssdt璋冪敤鐗瑰緛, 鍒嗗埆鏄 + mov r9d, 0F33h + mov [rsp+48h+var_20], 501802h + Win11 23606 鍙婁互鍚 鏍堜腑ssdt璋冪敤鐗瑰緛, 鍒嗗埆鏄 + mov r9d, 0F33h + mov[rsp + 58h + var_30], 601802h + */ #define INFINITYHOOK_MAGIC_501802 ((unsigned long)0x501802) //Win11 23606 浠ュ墠绯荤粺鐗瑰緛鐮 #define INFINITYHOOK_MAGIC_601802 ((unsigned long)0x601802) //Win11 23606 鍙婁互鍚庣郴缁熺殑鐗瑰緛鐮 #define INFINITYHOOK_MAGIC_F33 ((unsigned short)0xF33) - // 绗竴涓壒寰佸兼鏌 - unsigned long* pValue1 = (unsigned long*)pStackCurrent; - if ((*pValue1 != INFINITYHOOK_MAGIC_501802) && - (*pValue1 != INFINITYHOOK_MAGIC_601802)) - { - continue; - } - - // 杩欓噷涓轰粈涔堝噺?閰嶅悎瀵绘壘绗簩涓壒寰佸煎晩 - --pStackCurrent; - - // 绗簩涓壒寰佸兼鏌 - unsigned short* pValue2 = (unsigned short*)pStackCurrent; - if (*pValue2 != INFINITYHOOK_MAGIC_F33) - { - continue; - } - - // 鐗瑰緛鍊煎尮閰嶆垚鍔,鍐嶅掕繃鏉ユ煡鎵 - for (; pStackCurrent < pStackMax; ++pStackCurrent) - { - // 妫鏌ユ槸鍚﹀湪ssdt琛ㄥ唴 - unsigned long long* pllValue = (unsigned long long*)pStackCurrent; - if (!(PAGE_ALIGN(*pllValue) >= m_SystemCallTable && - PAGE_ALIGN(*pllValue) < (void*)((unsigned long long)m_SystemCallTable + (PAGE_SIZE * 2)))) - continue; - - // 鐜板湪宸茬粡纭畾鏄痵sdt鍑芥暟璋冪敤浜 - // 杩欓噷鏄壘鍒癒iSystemServiceExit - void** pSystemCallFunction = &pStackCurrent[9]; - - // 璋冪敤鍥炶皟鍑芥暟 - if (m_InfinityCallback) m_InfinityCallback(nCallIndex, pSystemCallFunction); - - // 璺冲嚭寰幆 - break; - } + // 绗竴涓壒寰佸兼鏌 + unsigned long* pValue1 = (unsigned long*)pStackCurrent; + if ((*pValue1 != INFINITYHOOK_MAGIC_501802) && + (*pValue1 != INFINITYHOOK_MAGIC_601802)) + { + continue; + } + + // 杩欓噷涓轰粈涔堝噺?閰嶅悎瀵绘壘绗簩涓壒寰佸煎晩 + --pStackCurrent; + + // 绗簩涓壒寰佸兼鏌 + unsigned short* pValue2 = (unsigned short*)pStackCurrent; + if (*pValue2 != INFINITYHOOK_MAGIC_F33) + { + continue; + } + + // 鐗瑰緛鍊煎尮閰嶆垚鍔,鍐嶅掕繃鏉ユ煡鎵 + for (; pStackCurrent < pStackMax; ++pStackCurrent) + { + // 妫鏌ユ槸鍚﹀湪ssdt琛ㄥ唴 + unsigned long long* pllValue = (unsigned long long*)pStackCurrent; + if (!(PAGE_ALIGN(*pllValue) >= m_SystemCallTable && + PAGE_ALIGN(*pllValue) < (void*)((unsigned long long)m_SystemCallTable + (PAGE_SIZE * 2)))) + continue; + + // 鐜板湪宸茬粡纭畾鏄痵sdt鍑芥暟璋冪敤浜 + // 杩欓噷鏄壘鍒癒iSystemServiceExit + void** pSystemCallFunction = &pStackCurrent[9]; + + // 璋冪敤鍥炶皟鍑芥暟 + if (m_InfinityCallback) m_InfinityCallback(nCallIndex, pSystemCallFunction); + + // 璺冲嚭寰幆 + break; + } + + // 璺冲嚭寰幆 + break; + } - // 璺冲嚭寰幆 - break; - } + // 璋冪敤鍘熷嚱鏁 + return __rdtsc(); + } - // 璋冪敤鍘熷嚱鏁 - return __rdtsc(); - } + // 鎴戜滑鐨勬浛鎹㈠嚱鏁,閽堝鐨勬槸Win 1919寰涓婄殑绯荤粺 + EXTERN_C __int64 FakeHvlGetQpcBias() + { + // 鎴戜滑鐨勮繃婊ゅ嚱鏁 + SelfGetCpuClock(); - // 鎴戜滑鐨勬浛鎹㈠嚱鏁,閽堝鐨勬槸Win 1919寰涓婄殑绯荤粺 - EXTERN_C __int64 FakeHvlGetQpcBias() + // 杩欓噷鏄湡姝vlGetQpcBias鍋氱殑浜嬫儏 + //鐗╃悊鏈轰笂 HvlpReferenceTscPage鎸囬拡鍊间负绌 + if (*((unsigned long long*)m_HvlpReferenceTscPage) != 0) { - // 鎴戜滑鐨勮繃婊ゅ嚱鏁 - SelfGetCpuClock(); - - // 杩欓噷鏄湡姝vlGetQpcBias鍋氱殑浜嬫儏 - //鐗╃悊鏈轰笂 HvlpReferenceTscPage鎸囬拡鍊间负绌 - if (*((unsigned long long*)m_HvlpReferenceTscPage) != 0) - { - return *((unsigned long long*)(*((unsigned long long*)m_HvlpReferenceTscPage)) + 3); - } - return 0; + return *((unsigned long long*)(*((unsigned long long*)m_HvlpReferenceTscPage)) + 3); } + return 0; + } - // 妫娴嬩緥绋 - void DetectThreadRoutine(void*) + // 妫娴嬩緥绋 + void DetectThreadRoutine(void*) + { + while (m_DetectThreadStatus) { - while (m_DetectThreadStatus) - { - // 绾跨▼甯哥敤浼戠湢 - KUtils::Sleep(1000); - // GetCpuClock杩樻槸涓涓嚱鏁版寚閽 - if (m_BuildNumber <= 18363) - { + // 绾跨▼甯哥敤浼戠湢 + KUtils::Sleep(1000); + // GetCpuClock杩樻槸涓涓嚱鏁版寚閽 + if (m_BuildNumber <= 18363) + { - if (MmIsAddressValid(m_GetCpuClock) && MmIsAddressValid(*m_GetCpuClock)) - { - // 鍊间笉涓鏍,蹇呴』閲嶆柊鎸傞挬 - if (SelfGetCpuClock != *m_GetCpuClock) - { - DbgPrintEx(0, 0, "[%s] fix 0x%p 0x%p \n", __FUNCTION__, m_GetCpuClock, MmIsAddressValid(m_GetCpuClock) ? *m_GetCpuClock : 0); - if (Initialize(m_InfinityCallback)) Start(); - } - } - else Initialize(m_InfinityCallback); // GetCpuClock鏃犳晥鍚庤閲嶆柊鑾峰彇 - } - LARGE_INTEGER li = KeQueryPerformanceCounter(NULL); - //DbgPrintEx(0, 0, "[%s] Tick Count %lld \n", __FUNCTION__, li.QuadPart); + if (MmIsAddressValid(m_GetCpuClock) && MmIsAddressValid(*m_GetCpuClock)) + { + // 鍊间笉涓鏍,蹇呴』閲嶆柊鎸傞挬 + if (SelfGetCpuClock != *m_GetCpuClock) + { + DbgPrintEx(0, 0, "[%s] fix 0x%p 0x%p \n", __FUNCTION__, m_GetCpuClock, MmIsAddressValid(m_GetCpuClock) ? *m_GetCpuClock : 0); + if (Initialize(m_InfinityCallback)) Start(); + } } - PsTerminateSystemThread(STATUS_SUCCESS); + else Initialize(m_InfinityCallback); // GetCpuClock鏃犳晥鍚庤閲嶆柊鑾峰彇 + } + LARGE_INTEGER li = KeQueryPerformanceCounter(NULL); + //DbgPrintEx(0, 0, "[%s] Tick Count %lld \n", __FUNCTION__, li.QuadPart); } + PsTerminateSystemThread(STATUS_SUCCESS); + } #define HALP_PERFORMANCE_COUNTER_TYPE_OFFSET (0xE4) //HalpPerformanceCounter绫诲瀷鍊煎亸绉伙紝璇ュ煎湪鐗╃悊鏈哄櫒涓负5锛岃櫄鎷熸満涓 Win11 22621 浠ヤ笂涓7, 浠ヤ笅涓 8 #define HALP_PERFORMANCE_COUNTER_BASE_RATE_OFFSET (0xC0) //HalpPerformanceCounter鍩烘湰閫熷害鍊嶇巼鍦板潃 铏氭嫙鏈轰腑涓哄间负 0x989680=10000000锛 鐗╃悊鏈轰腑涓虹害2000000000 #define HALP_PERFORMANCE_COUNTER_TYPE_PHYSICAL_MACHINE (0x5) //鐗╃悊鏈轰腑HalpPerformanceCounter鐨勭被鍨 #define HALP_PERFORMANCE_COUNTER_BASE_RATE (10000000i64) //鍩烘湰閫熷害 - bool Initialize(InfinityCallbackPtr pCallback) - { - if (!m_DetectThreadStatus) return false; + bool Initialize(InfinityCallbackPtr pCallback) + { + if (!m_DetectThreadStatus) return false; - // 鍥炶皟鍑芥暟鎸囬拡妫鏌 - DbgPrintEx(0, 0, "[%s] ssdt call back ptr is 0x%p \n", __FUNCTION__, pCallback); - if (!MmIsAddressValid(pCallback)) return false; - else m_InfinityCallback = pCallback; + // 鍥炶皟鍑芥暟鎸囬拡妫鏌 + DbgPrintEx(0, 0, "[%s] ssdt call back ptr is 0x%p \n", __FUNCTION__, pCallback); + if (!MmIsAddressValid(pCallback)) return false; + else m_InfinityCallback = pCallback; - // 鍏堝皾璇曟寕閽 - if (!NT_SUCCESS(EventTraceControl(EtwpUpdateTrace))) - { - // 鏃犳硶寮鍚疌KCL - if (!NT_SUCCESS(EventTraceControl(EtwpStartTrace))) - { - DbgPrintEx(0, 0, "[%s] start ckcl fail \n", __FUNCTION__); - return false; - } + // 鍏堝皾璇曟寕閽 + if (!NT_SUCCESS(EventTraceControl(EtwpUpdateTrace))) + { + // 鏃犳硶寮鍚疌KCL + if (!NT_SUCCESS(EventTraceControl(EtwpStartTrace))) + { + DbgPrintEx(0, 0, "[%s] start ckcl fail \n", __FUNCTION__); + return false; + } + + // 鍐嶆灏濊瘯鎸傞挬 + if (!NT_SUCCESS(EventTraceControl(EtwpUpdateTrace))) + { + DbgPrintEx(0, 0, "[%s] syscall ckcl fail \n", __FUNCTION__); + return false; + } + } - // 鍐嶆灏濊瘯鎸傞挬 - if (!NT_SUCCESS(EventTraceControl(EtwpUpdateTrace))) + // 鑾峰彇绯荤粺鐗堟湰鍙 + m_BuildNumber = KUtils::GetSystemBuildNumber(); + DbgPrintEx(0, 0, "[%s] build number is %ld \n", __FUNCTION__, m_BuildNumber); + if (!m_BuildNumber) return false; + + // 鑾峰彇绯荤粺鍩哄潃 + unsigned long long ntoskrnl = KUtils::GetModuleAddress("ntoskrnl.exe", nullptr); + DbgPrintEx(0, 0, "[%s] ntoskrnl address is 0x%llX \n", __FUNCTION__, ntoskrnl); + if (!ntoskrnl) return false; + + // 杩欓噷涓嶅悓绯荤粺涓嶅悓浣嶇疆 + // https://github.com/FiYHer/InfinityHookPro/issues/17 win10 21h2.2130 瀹夎 KB5018410 琛ヤ竵鍚庨渶瑕佷娇鐢ㄦ柊鐨勭壒寰佺爜 + unsigned long long EtwpDebuggerData = KUtils::FindPatternImage(ntoskrnl, "\x00\x00\x2c\x08\x04\x38\x0c", "??xxxxx", ".text"); + if (!EtwpDebuggerData) EtwpDebuggerData = KUtils::FindPatternImage(ntoskrnl, "\x00\x00\x2c\x08\x04\x38\x0c", "??xxxxx", ".data"); + if (!EtwpDebuggerData) EtwpDebuggerData = KUtils::FindPatternImage(ntoskrnl, "\x00\x00\x2c\x08\x04\x38\x0c", "??xxxxx", ".rdata"); + DbgPrintEx(0, 0, "[%s] etwp debugger data is 0x%llX \n", __FUNCTION__, EtwpDebuggerData); + if (!EtwpDebuggerData) return false; + m_EtwpDebuggerData = (void*)EtwpDebuggerData; + + // 杩欓噷鏆傛椂涓嶇煡閬撴庝箞瀹氫綅,鍋忕Щ0x10鍦ㄥ叏閮ㄧ郴缁熼兘涓鏍 + m_EtwpDebuggerDataSilo = *(void***)((unsigned long long)m_EtwpDebuggerData + 0x10); + DbgPrintEx(0, 0, "[%s] etwp debugger data silo is 0x%p \n", __FUNCTION__, m_EtwpDebuggerDataSilo); + if (!m_EtwpDebuggerDataSilo) return false; + + // 杩欓噷涔熶笉鐭ラ亾鎬庝箞瀹氫綅,鍋忕Щ0x2鍦ㄥ叏閮ㄧ郴缁熼兘鍝︿竴鏍 + m_CkclWmiLoggerContext = m_EtwpDebuggerDataSilo[0x2]; + DbgPrintEx(0, 0, "[%s] ckcl wmi logger context is 0x%p \n", __FUNCTION__, m_CkclWmiLoggerContext); + if (!m_CkclWmiLoggerContext) return false; + + /* Win7绯荤粺娴嬭瘯,m_GetCpuClock璇ュ间細鏀瑰彉鍑犳,鍏堥樁娈典娇鐢ㄧ嚎绋嬫娴嬪悗淇 + * 闈,Win11鐨勫亸绉诲彉鎴愪簡0x18,鐪嬫紡鐨勫鎴戣皟璇曡繖涔堜箙 -_- + * 杩欓噷鎬荤粨涓涓,Win7鍜學in11閮芥槸鍋忕Щ0x18,鍏跺畠鐨勬槸0x28 + */ + if (m_BuildNumber <= 7601 || m_BuildNumber >= 22000) m_GetCpuClock = (void**)((unsigned long long)m_CkclWmiLoggerContext + 0x18); // Win7鐗堟湰浠ュ強鏇存棫, Win11涔熸槸 + else m_GetCpuClock = (void**)((unsigned long long)m_CkclWmiLoggerContext + 0x28); // Win8 -> Win10鍏ㄧ郴缁 + if (!MmIsAddressValid(m_GetCpuClock)) return false; + DbgPrintEx(0, 0, "[%s] get cpu clock is 0x%p \n", __FUNCTION__, *m_GetCpuClock); + + // 鎷垮埌ssdt鎸囬拡 + m_SystemCallTable = PAGE_ALIGN(KUtils::GetSyscallEntry(ntoskrnl)); + DbgPrintEx(0, 0, "[%s] syscall table is 0x%p \n", __FUNCTION__, m_SystemCallTable); + if (!m_SystemCallTable) return false; + + if (m_BuildNumber > 18363) // 鍗崇増鏈1909 + { + /* HvlGetQpcBias鍑芥暟鍐呴儴闇瑕佺敤鍒拌繖涓粨鏋 + * 鎵浠ユ垜浠墜鍔ㄥ畾浣嶈繖涓粨鏋 + */ + // 鐗瑰緛鐮佷负 Win10 18363 鑷 Win11 22631鍏ㄥ钩鍙伴氱敤 + unsigned long long addressHvlpReferenceTscPage = KUtils::FindPatternImage(ntoskrnl, + "\x48\x8b\x05\x00\x00\x00\x00\x48\x8b\x40\x00\x48\x8b\x0d\x00\x00\x00\x00\x48\xf7\xe2", + "xxx????xxx?xxx????xxx"); + if (!addressHvlpReferenceTscPage) + { + DbgPrintEx(0, 0, "[%s] Find HvlpReferenceTscPage Failed! \n", __FUNCTION__); + return false; + } + m_HvlpReferenceTscPage = reinterpret_cast(reinterpret_cast(addressHvlpReferenceTscPage) + 7 + *reinterpret_cast(reinterpret_cast(addressHvlpReferenceTscPage) + 3)); + DbgPrintEx(0, 0, "[%s] HvlpReferenceTscPage is 0x%llX \n", __FUNCTION__, m_HvlpReferenceTscPage); + if (!m_HvlpReferenceTscPage) return false; + //-----------------------------------HvlpReferenceTscPage鐨勫師濮嬪---------------------------- + //-----------------------------铏氭嫙鏈------------------鐗╃悊鏈----------------------- + //Win10 20H2 鏈 绌 + //Win10 21H1 鏈 绌 + //Win10 21H2 鏈 绌 + //Win10 22H2 鏈 绌 + //Win11 22000 鏈 绌 + //Win11 22621 鏈 绌 + //Win11 22631 鏈 绌 + DbgPrintEx(0, 0, "[%s] HvlpReferenceTscPage Value Is 0x%llX \n", __FUNCTION__, *reinterpret_cast(m_HvlpReferenceTscPage)); + //if (*reinterpret_cast(m_HvlpReferenceTscPage) == 0) return false; + + /* 杩欓噷鎴戜滑鏌ユ壘鍒癏vlGetQpcBias鐨勬寚閽 + * 璇︾粏浠嬬粛鍙互鐪媓ttps://www.freebuf.com/articles/system/278857.html + */ + //鍦ㄥ嚱鏁 HalpTimerQueryHostPerformanceCounter 涓 + //__int64 __fastcall HalpTimerQueryHostPerformanceCounter(_QWORD * a1) + //{ + // __int64 v2; // rbx + + // if (!HalpPerformanceCounter + // || *(_DWORD*)(HalpPerformanceCounter + 0xE4) != 7 + // || !HvlGetQpcBiasPtr + // || !HvlGetReferenceTimeUsingTscPagePtr) + // { + // return 0xC00000BB; + // } + // v2 = HvlGetReferenceTimeUsingTscPagePtr(0i64); + // *a1 = HvlGetQpcBiasPtr() + v2; + // return 0i64; + //} + unsigned long long addressHvlGetQpcBias = 0; + //HalpTimerQueryHostPerformanceCounter涓煡鎵 HvlGetQpcBias 鐗╃悊鏈 铏氭嫙鏈 HvlGetQpcBias 鍊奸兘涓0 + addressHvlGetQpcBias = KUtils::FindPatternImage(ntoskrnl, + "\x48\x8b\x05\x00\x00\x00\x00\x48\x85\xc0\x74\x00\x48\x83\x3d\x00\x00\x00\x00\x00\x74", // Win10 22H2浠ュ墠 浠ュ強 Win11 22621浠ュ墠 + "xxx????xxxx?xxx?????x"); + if (!addressHvlGetQpcBias) + { + //璇ョ壒寰佺爜鍏ㄩ兘鏈夛紝浣嗕笂涓壒寰佺爜鍦╓in10 22H2 浠ュ強 Win11 22621浠ヤ笂娌℃湁锛屽啀鎼滅储杩欎釜鏃跺氨宸茬粡鏄 Win10 22H2 浠ュ強 Win11 22621浠ヤ笂鐗堟湰 + addressHvlGetQpcBias = KUtils::FindPatternImage(ntoskrnl, + "\x48\x8b\x05\x00\x00\x00\x00\xe8\x00\x00\x00\x00\x48\x03\xd8\x48\x89\x1f", + "xxx????x????xxxxxx"); + } + if (!addressHvlGetQpcBias) + { + DbgPrintEx(0, 0, "[%s] Find HvlGetQpcBias Failed! \n", __FUNCTION__); + return false; + } + m_HvlGetQpcBias = reinterpret_cast(reinterpret_cast(addressHvlGetQpcBias) + 7 + *reinterpret_cast(reinterpret_cast(addressHvlGetQpcBias) + 3)); + DbgPrintEx(0, 0, "[%s] HvlGetQpcBias Is 0x%llX \n", __FUNCTION__, m_HvlGetQpcBias); + if (!m_HvlGetQpcBias) return false; + //-----------------------------------HvlGetQpcBias鐨勫師濮嬪---------------------------- + //-----------------------------铏氭嫙鏈------------------鐗╃悊鏈----------------------- + //Win10 20H2 绌 绌 + //Win10 21H1 绌 绌 + //Win10 21H2 绌 绌 + //Win10 22H2 绌 绌 + //Win11 22000 绌 绌 + //Win11 22621 绌 绌 + //Win11 22631 绌 绌 + DbgPrintEx(0, 0, "[%s] HvlGetQpcBias Value Is 0x%llX \n", __FUNCTION__, *(unsigned long long*)m_HvlGetQpcBias); + + + + //HalpTimerQueryHostPerformanceCounter涓煡鎵 HvlGetReferenceTimeUsingTscPagePtr + //鐗╃悊鏈 HvlGetReferenceTimeUsingTscPagePtr 鍊间负0 + unsigned long long addressHvlpGetReferenceTimeUsingTscPage = KUtils::FindPatternImage(ntoskrnl, + "\x48\x8b\x05\x00\x00\x00\x00\x48\x85\xc0\x74\x00\x33\xc9\xe8\x00\x00\x00\x00\x48\x8b\xd8", //Win10 22H2 鍜 Win11 22621鍙婁互涓 + "xxx????xxxx?xxx????xxx"); + if (!addressHvlpGetReferenceTimeUsingTscPage) + { + //璇ョ壒寰佺爜鍏ㄥ钩鍙伴兘鏈夛紝浣嗕笂涓壒寰佺爜鍦 Win10 22H2浠ュ墠锛 浠ュ強 Win11 22621 浠ュ墠娌℃湁锛屽啀鎼滅储杩欎釜鏃跺氨宸茬粡鏄 Win10 21H1銆21H2銆 浠ュ強 Win11 22000鐗堟湰浜 + addressHvlpGetReferenceTimeUsingTscPage = KUtils::FindPatternImage(ntoskrnl, + "\x48\x8b\x05\x00\x00\x00\x00\xE8\x00\x00\x00\x00\x48\x03\xd8", + "xxx????x????xxx"); + } + if (!addressHvlpGetReferenceTimeUsingTscPage) + { + DbgPrintEx(0, 0, "[%s] Find HvlpGetReferenceTimeUsingTscPage Failed! \n", __FUNCTION__); + return false; + } + m_HvlpGetReferenceTimeUsingTscPage = (unsigned long long) + ((char*)(addressHvlpGetReferenceTimeUsingTscPage)+7 + + *(int*)((char*)(addressHvlpGetReferenceTimeUsingTscPage)+3)); + DbgPrintEx(0, 0, "[%s] HvlGetReferenceTimeUsingTscPage Is 0x%llX \n", __FUNCTION__, m_HvlpGetReferenceTimeUsingTscPage); + if (!m_HvlpGetReferenceTimeUsingTscPage) return false; + //-----------------------HvlpGetReferenceTimeUsingTscPage鐨勫師濮嬪---------------- + //--------------------------------------铏氭嫙鏈---------------------------------------------------鐗╃悊鏈----------------------- + //Win10 20H2 nt!HvlGetReferenceTimeUsingTscPage 绌 + //Win10 21H1 nt!HvlGetReferenceTimeUsingTscPage 绌 + //Win10 21H2 nt!HvlGetReferenceTimeUsingTscPage 绌 + //Win10 22H2 nt!HvlGetReferenceTimeUsingTscPage 绌 + //Win11 22000 nt!HvlGetReferenceTimeUsingTscPage 绌 + //Win11 22621 nt!HvlGetReferenceTimeUsingTscPage 绌 + //Win11 22631 nt!HvlGetReferenceTimeUsingTscPage 绌 + DbgPrintEx(0, 0, "[%s] HvlGetReferenceTimeUsingTscPage Value Is 0x%llX \n", __FUNCTION__, *reinterpret_cast(m_HvlpGetReferenceTimeUsingTscPage)); + + + //HalpTimerQueryHostPerformanceCounter涓悳绱alpPerformanceCounter + unsigned long long addressHalpPerformanceCounter = KUtils::FindPatternImage(ntoskrnl, + "\x48\x8b\x05\x00\x00\x00\x00\x48\x8b\xf9\x48\x85\xc0\x74\x00\x83\xb8", //鐗瑰緛鐮佸叏骞冲彴涓鏍 + "xxx????xxxxxxx?xx"); + if (!addressHalpPerformanceCounter) + { + DbgPrintEx(0, 0, "[%s] Find HalpPerformanceCounter Failed! \n", __FUNCTION__); + return false; + } + m_HalpPerformanceCounter = reinterpret_cast + (reinterpret_cast(addressHalpPerformanceCounter) + 7 + *reinterpret_cast(reinterpret_cast(addressHalpPerformanceCounter) + 3)); + DbgPrintEx(0, 0, "[%s] HalpPerformanceCounter Is 0x%llX \n", __FUNCTION__, m_HalpPerformanceCounter); + if (!m_HalpPerformanceCounter) return false; + DbgPrintEx(0, 0, "[%s] HalpPerformanceCounter Value is 0x%llX \n", __FUNCTION__, *reinterpret_cast(m_HalpPerformanceCounter)); + + + //鍦 KiUpdateTime涓悳绱alpOriginalPerformanceCounter锛學in10 21H1 鑷 Win11 22631 閫氱敤 + unsigned long long addressHalpOriginalPerformanceCounter = KUtils::FindPatternImage(ntoskrnl, + "\x48\x8b\x05\x00\x00\x00\x00\x48\x3b\x00\x0f\x85\x00\x00\x00\x00\xA0", + "xxx????xx?xx????x"); + if (!addressHalpOriginalPerformanceCounter) + { + //Win11 23606 涔嬪悗,鍦 KeQueryPerformanceCounter 涓悳绱alpOriginalPerformanceCounter + addressHalpOriginalPerformanceCounter = KUtils::FindPatternImage(ntoskrnl, + "\x48\x8b\x0d\x00\x00\x00\x00\x4c\x00\x00\x00\x00\x48\x3b\xf1", + "xxx????x????xxx"); + } + if (!addressHalpOriginalPerformanceCounter) + { + //鍦╓in11 29648 鍙嶆眹缂栧緱鍒扮殑鐗瑰緛鐮 + addressHalpOriginalPerformanceCounter = KUtils::FindPatternImage(ntoskrnl, + "\x48\xF7\xE2\x4C\x03\xDA\x48\x8B\x05\x00\x00\x00\x00\x48\x3B\xF0", + "xxxxxxxxx????xxx"); + if (addressHalpOriginalPerformanceCounter) { - DbgPrintEx(0, 0, "[%s] syscall ckcl fail \n", __FUNCTION__); - return false; + addressHalpOriginalPerformanceCounter += 6; } + if (!addressHalpOriginalPerformanceCounter) + { + DbgPrintEx(0, 0, "[%s] Find HalpOriginalPerformanceCounter Failed! \n", __FUNCTION__); + return false; } - - // 鑾峰彇绯荤粺鐗堟湰鍙 - m_BuildNumber = KUtils::GetSystemBuildNumber(); - DbgPrintEx(0, 0, "[%s] build number is %ld \n", __FUNCTION__, m_BuildNumber); - if (!m_BuildNumber) return false; - - // 鑾峰彇绯荤粺鍩哄潃 - unsigned long long ntoskrnl = KUtils::GetModuleAddress("ntoskrnl.exe", nullptr); - DbgPrintEx(0, 0, "[%s] ntoskrnl address is 0x%llX \n", __FUNCTION__, ntoskrnl); - if (!ntoskrnl) return false; - - // 杩欓噷涓嶅悓绯荤粺涓嶅悓浣嶇疆 - // https://github.com/FiYHer/InfinityHookPro/issues/17 win10 21h2.2130 瀹夎 KB5018410 琛ヤ竵鍚庨渶瑕佷娇鐢ㄦ柊鐨勭壒寰佺爜 - unsigned long long EtwpDebuggerData = KUtils::FindPatternImage(ntoskrnl, "\x00\x00\x2c\x08\x04\x38\x0c", "??xxxxx", ".text"); - if (!EtwpDebuggerData) EtwpDebuggerData = KUtils::FindPatternImage(ntoskrnl, "\x00\x00\x2c\x08\x04\x38\x0c", "??xxxxx", ".data"); - if (!EtwpDebuggerData) EtwpDebuggerData = KUtils::FindPatternImage(ntoskrnl, "\x00\x00\x2c\x08\x04\x38\x0c", "??xxxxx", ".rdata"); - DbgPrintEx(0, 0, "[%s] etwp debugger data is 0x%llX \n", __FUNCTION__, EtwpDebuggerData); - if (!EtwpDebuggerData) return false; - m_EtwpDebuggerData = (void*)EtwpDebuggerData; - - // 杩欓噷鏆傛椂涓嶇煡閬撴庝箞瀹氫綅,鍋忕Щ0x10鍦ㄥ叏閮ㄧ郴缁熼兘涓鏍 - m_EtwpDebuggerDataSilo = *(void***)((unsigned long long)m_EtwpDebuggerData + 0x10); - DbgPrintEx(0, 0, "[%s] etwp debugger data silo is 0x%p \n", __FUNCTION__, m_EtwpDebuggerDataSilo); - if (!m_EtwpDebuggerDataSilo) return false; - - // 杩欓噷涔熶笉鐭ラ亾鎬庝箞瀹氫綅,鍋忕Щ0x2鍦ㄥ叏閮ㄧ郴缁熼兘鍝︿竴鏍 - m_CkclWmiLoggerContext = m_EtwpDebuggerDataSilo[0x2]; - DbgPrintEx(0, 0, "[%s] ckcl wmi logger context is 0x%p \n", __FUNCTION__, m_CkclWmiLoggerContext); - if (!m_CkclWmiLoggerContext) return false; - - /* Win7绯荤粺娴嬭瘯,m_GetCpuClock璇ュ间細鏀瑰彉鍑犳,鍏堥樁娈典娇鐢ㄧ嚎绋嬫娴嬪悗淇 - * 闈,Win11鐨勫亸绉诲彉鎴愪簡0x18,鐪嬫紡鐨勫鎴戣皟璇曡繖涔堜箙 -_- - * 杩欓噷鎬荤粨涓涓,Win7鍜學in11閮芥槸鍋忕Щ0x18,鍏跺畠鐨勬槸0x28 - */ - if (m_BuildNumber <= 7601 || m_BuildNumber >= 22000) m_GetCpuClock = (void**)((unsigned long long)m_CkclWmiLoggerContext + 0x18); // Win7鐗堟湰浠ュ強鏇存棫, Win11涔熸槸 - else m_GetCpuClock = (void**)((unsigned long long)m_CkclWmiLoggerContext + 0x28); // Win8 -> Win10鍏ㄧ郴缁 - if (!MmIsAddressValid(m_GetCpuClock)) return false; - DbgPrintEx(0, 0, "[%s] get cpu clock is 0x%p \n", __FUNCTION__, *m_GetCpuClock); - - // 鎷垮埌ssdt鎸囬拡 - m_SystemCallTable = PAGE_ALIGN(KUtils::GetSyscallEntry(ntoskrnl)); - DbgPrintEx(0, 0, "[%s] syscall table is 0x%p \n", __FUNCTION__, m_SystemCallTable); - if (!m_SystemCallTable) return false; - - if (m_BuildNumber > 18363) // 鍗崇増鏈1909 + } + + m_HalpOriginalPerformanceCounter = reinterpret_cast + (reinterpret_cast(addressHalpOriginalPerformanceCounter) + 7 + *reinterpret_cast(reinterpret_cast(addressHalpOriginalPerformanceCounter) + 3)); + DbgPrintEx(0, 0, "[%s] HalpOriginalPerformanceCounter Is 0x%llX \n", __FUNCTION__, m_HalpOriginalPerformanceCounter); + if (!m_HalpOriginalPerformanceCounter) return false; + DbgPrintEx(0, 0, "[%s] HalpOriginalPerformanceCounter Value Is 0x%llX \n", __FUNCTION__, *reinterpret_cast(m_HalpOriginalPerformanceCounter)); + + //HalpPerformanceCounter涓被鍨嬬殑鎸囬拡锛屽悗闈㈣繘琛屼慨鏀规椂浣跨敤 + m_HalpPerformanceCounterType = (ULONG*)((ULONG_PTR)(*(PVOID*)m_HalpPerformanceCounter) + HALP_PERFORMANCE_COUNTER_TYPE_OFFSET); + if (!m_HalpPerformanceCounterType) + { + DbgPrintEx(0, 0, "[%s] m_HalpPerformanceCounterType Is Null! \n", __FUNCTION__); + return false; + } + //鍒ゆ柇鍦ㄧ墿鐞嗘満涓婃椂鎵嶈繘琛屽悗杈圭殑鎿嶄綔 + if (*m_HalpPerformanceCounterType == HALP_PERFORMANCE_COUNTER_TYPE_PHYSICAL_MACHINE) + { + //鎼滅储HalpTimerQueryHostPerformanceCounter涓垽鏂殑Type鍊硷紝鍏跺疄涔熷彲浠ョ洿鎺ュ垽鏂郴缁熺増鏈 + //鍙傝僅alpTimerQueryHostPerformanceCounter涓 *(_DWORD *)(HalpPerformanceCounter + 0xE4) != 7 , + //Win11 22000 鍙婁互涓嬪间负8 22621 浠ヤ笂涓7 + //鍒╃敤鍓嶈竟鎼滅储鐨 addressHalpPerformanceCounter,浠ヤ笅娉ㄩ噴涓篧in11 22621 HalpTimerQueryHostPerformanceCounter 鐨 IDA閫嗗悜浠g爜 + //.text : 0000000140520A1A 48 8B 05 8F 36 74 00 mov rax, cs : HalpPerformanceCounter + //.text : 0000000140520A21 48 8B F9 mov rdi, rcx + //.text : 0000000140520A24 48 85 C0 test rax, rax + //.text : 0000000140520A27 74 3F jz short loc_140520A68 + //.text : 0000000140520A29 83 B8 E4 00 00 00 07 cmp dword ptr[rax + 0E4h], 7 + m_VmHalpPerformanceCounterType = *(reinterpret_cast(addressHalpPerformanceCounter) + 21); + DbgPrintEx(0, 0, "[%s] HalpPerformanceCounterType In Virtual Machine Value is 0x%x \n", __FUNCTION__, m_VmHalpPerformanceCounterType); + + //鍒嗛厤涓涓悓HalpPerformanceCounter涓鏍风殑绌洪棿锛岀敤鏉ユ浛鎹alpOriginalPerformanceCounter锛 + //鏇挎崲鐨勬暟鎹腑Type涓 5, 鍊嶆暟涓哄熀鍑嗙殑 10000000, + //ntoskrnl涓殑鍘熼昏緫涓 HalpOriginalPerformanceCounter = HalpPerformanceCounter + m_HalpOriginalPerformanceCounterCopy = (ULONGLONG)ExAllocatePoolWithTag(NonPagedPool, 0xFF, 'freP'); + if (!m_HalpOriginalPerformanceCounterCopy) { - /* HvlGetQpcBias鍑芥暟鍐呴儴闇瑕佺敤鍒拌繖涓粨鏋 - * 鎵浠ユ垜浠墜鍔ㄥ畾浣嶈繖涓粨鏋 - */ - // 鐗瑰緛鐮佷负 Win10 18363 鑷 Win11 22631鍏ㄥ钩鍙伴氱敤 - unsigned long long addressHvlpReferenceTscPage = KUtils::FindPatternImage(ntoskrnl, - "\x48\x8b\x05\x00\x00\x00\x00\x48\x8b\x40\x00\x48\x8b\x0d\x00\x00\x00\x00\x48\xf7\xe2", - "xxx????xxx?xxx????xxx"); - if (!addressHvlpReferenceTscPage) - { - DbgPrintEx(0, 0, "[%s] Find HvlpReferenceTscPage Failed! \n", __FUNCTION__); - return false; - } - m_HvlpReferenceTscPage = reinterpret_cast(reinterpret_cast(addressHvlpReferenceTscPage) + 7 + *reinterpret_cast(reinterpret_cast(addressHvlpReferenceTscPage) + 3)); - DbgPrintEx(0, 0, "[%s] HvlpReferenceTscPage is 0x%llX \n", __FUNCTION__, m_HvlpReferenceTscPage); - if (!m_HvlpReferenceTscPage) return false; - //-----------------------------------HvlpReferenceTscPage鐨勫師濮嬪---------------------------- - //-----------------------------铏氭嫙鏈------------------鐗╃悊鏈----------------------- - //Win10 20H2 鏈 绌 - //Win10 21H1 鏈 绌 - //Win10 21H2 鏈 绌 - //Win10 22H2 鏈 绌 - //Win11 22000 鏈 绌 - //Win11 22621 鏈 绌 - //Win11 22631 鏈 绌 - DbgPrintEx(0, 0, "[%s] HvlpReferenceTscPage Value Is 0x%llX \n", __FUNCTION__, *reinterpret_cast(m_HvlpReferenceTscPage)); - //if (*reinterpret_cast(m_HvlpReferenceTscPage) == 0) return false; - - /* 杩欓噷鎴戜滑鏌ユ壘鍒癏vlGetQpcBias鐨勬寚閽 - * 璇︾粏浠嬬粛鍙互鐪媓ttps://www.freebuf.com/articles/system/278857.html - */ - //鍦ㄥ嚱鏁 HalpTimerQueryHostPerformanceCounter 涓 - //__int64 __fastcall HalpTimerQueryHostPerformanceCounter(_QWORD * a1) - //{ - // __int64 v2; // rbx - - // if (!HalpPerformanceCounter - // || *(_DWORD*)(HalpPerformanceCounter + 0xE4) != 7 - // || !HvlGetQpcBiasPtr - // || !HvlGetReferenceTimeUsingTscPagePtr) - // { - // return 0xC00000BB; - // } - // v2 = HvlGetReferenceTimeUsingTscPagePtr(0i64); - // *a1 = HvlGetQpcBiasPtr() + v2; - // return 0i64; - //} - unsigned long long addressHvlGetQpcBias = 0; - //HalpTimerQueryHostPerformanceCounter涓煡鎵 HvlGetQpcBias 鐗╃悊鏈 铏氭嫙鏈 HvlGetQpcBias 鍊奸兘涓0 - addressHvlGetQpcBias = KUtils::FindPatternImage(ntoskrnl, - "\x48\x8b\x05\x00\x00\x00\x00\x48\x85\xc0\x74\x00\x48\x83\x3d\x00\x00\x00\x00\x00\x74", // Win10 22H2浠ュ墠 浠ュ強 Win11 22621浠ュ墠 - "xxx????xxxx?xxx?????x"); - if (!addressHvlGetQpcBias) - { - //璇ョ壒寰佺爜鍏ㄩ兘鏈夛紝浣嗕笂涓壒寰佺爜鍦╓in10 22H2 浠ュ強 Win11 22621浠ヤ笂娌℃湁锛屽啀鎼滅储杩欎釜鏃跺氨宸茬粡鏄 Win10 22H2 浠ュ強 Win11 22621浠ヤ笂鐗堟湰 - addressHvlGetQpcBias = KUtils::FindPatternImage(ntoskrnl, - "\x48\x8b\x05\x00\x00\x00\x00\xe8\x00\x00\x00\x00\x48\x03\xd8\x48\x89\x1f", - "xxx????x????xxxxxx"); - } - if (!addressHvlGetQpcBias) - { - DbgPrintEx(0, 0, "[%s] Find HvlGetQpcBias Failed! \n", __FUNCTION__); - return false; - } - m_HvlGetQpcBias = reinterpret_cast(reinterpret_cast(addressHvlGetQpcBias) + 7 + *reinterpret_cast(reinterpret_cast(addressHvlGetQpcBias) + 3)); - DbgPrintEx(0, 0, "[%s] HvlGetQpcBias Is 0x%llX \n", __FUNCTION__, m_HvlGetQpcBias); - if (!m_HvlGetQpcBias) return false; - //-----------------------------------HvlGetQpcBias鐨勫師濮嬪---------------------------- - //-----------------------------铏氭嫙鏈------------------鐗╃悊鏈----------------------- - //Win10 20H2 绌 绌 - //Win10 21H1 绌 绌 - //Win10 21H2 绌 绌 - //Win10 22H2 绌 绌 - //Win11 22000 绌 绌 - //Win11 22621 绌 绌 - //Win11 22631 绌 绌 - DbgPrintEx(0, 0, "[%s] HvlGetQpcBias Value Is 0x%llX \n", __FUNCTION__, *(unsigned long long*)m_HvlGetQpcBias); - - - - //HalpTimerQueryHostPerformanceCounter涓煡鎵 HvlGetReferenceTimeUsingTscPagePtr - //鐗╃悊鏈 HvlGetReferenceTimeUsingTscPagePtr 鍊间负0 - unsigned long long addressHvlpGetReferenceTimeUsingTscPage = KUtils::FindPatternImage(ntoskrnl, - "\x48\x8b\x05\x00\x00\x00\x00\x48\x85\xc0\x74\x00\x33\xc9\xe8\x00\x00\x00\x00\x48\x8b\xd8", //Win10 22H2 鍜 Win11 22621鍙婁互涓 - "xxx????xxxx?xxx????xxx"); - if (!addressHvlpGetReferenceTimeUsingTscPage) - { - //璇ョ壒寰佺爜鍏ㄥ钩鍙伴兘鏈夛紝浣嗕笂涓壒寰佺爜鍦 Win10 22H2浠ュ墠锛 浠ュ強 Win11 22621 浠ュ墠娌℃湁锛屽啀鎼滅储杩欎釜鏃跺氨宸茬粡鏄 Win10 21H1銆21H2銆 浠ュ強 Win11 22000鐗堟湰浜 - addressHvlpGetReferenceTimeUsingTscPage = KUtils::FindPatternImage(ntoskrnl, - "\x48\x8b\x05\x00\x00\x00\x00\xE8\x00\x00\x00\x00\x48\x03\xd8", - "xxx????x????xxx"); - } - if (!addressHvlpGetReferenceTimeUsingTscPage) - { - DbgPrintEx(0, 0, "[%s] Find HvlpGetReferenceTimeUsingTscPage Failed! \n", __FUNCTION__); - return false; - } - m_HvlpGetReferenceTimeUsingTscPage = (unsigned long long) - ((char*)(addressHvlpGetReferenceTimeUsingTscPage)+7 + - *(int*)((char*)(addressHvlpGetReferenceTimeUsingTscPage)+3)); - DbgPrintEx(0, 0, "[%s] HvlGetReferenceTimeUsingTscPage Is 0x%llX \n", __FUNCTION__, m_HvlpGetReferenceTimeUsingTscPage); - if (!m_HvlpGetReferenceTimeUsingTscPage) return false; - //-----------------------HvlpGetReferenceTimeUsingTscPage鐨勫師濮嬪---------------- - //--------------------------------------铏氭嫙鏈---------------------------------------------------鐗╃悊鏈----------------------- - //Win10 20H2 nt!HvlGetReferenceTimeUsingTscPage 绌 - //Win10 21H1 nt!HvlGetReferenceTimeUsingTscPage 绌 - //Win10 21H2 nt!HvlGetReferenceTimeUsingTscPage 绌 - //Win10 22H2 nt!HvlGetReferenceTimeUsingTscPage 绌 - //Win11 22000 nt!HvlGetReferenceTimeUsingTscPage 绌 - //Win11 22621 nt!HvlGetReferenceTimeUsingTscPage 绌 - //Win11 22631 nt!HvlGetReferenceTimeUsingTscPage 绌 - DbgPrintEx(0, 0, "[%s] HvlGetReferenceTimeUsingTscPage Value Is 0x%llX \n", __FUNCTION__, *reinterpret_cast(m_HvlpGetReferenceTimeUsingTscPage)); - - - //HalpTimerQueryHostPerformanceCounter涓悳绱alpPerformanceCounter - unsigned long long addressHalpPerformanceCounter = KUtils::FindPatternImage(ntoskrnl, - "\x48\x8b\x05\x00\x00\x00\x00\x48\x8b\xf9\x48\x85\xc0\x74\x00\x83\xb8", //鐗瑰緛鐮佸叏骞冲彴涓鏍 - "xxx????xxxxxxx?xx"); - if (!addressHalpPerformanceCounter) - { - DbgPrintEx(0, 0, "[%s] Find HalpPerformanceCounter Failed! \n", __FUNCTION__); - return false; - } - m_HalpPerformanceCounter = reinterpret_cast - (reinterpret_cast(addressHalpPerformanceCounter) + 7 + *reinterpret_cast(reinterpret_cast(addressHalpPerformanceCounter) + 3)); - DbgPrintEx(0, 0, "[%s] HalpPerformanceCounter Is 0x%llX \n", __FUNCTION__, m_HalpPerformanceCounter); - if (!m_HalpPerformanceCounter) return false; - DbgPrintEx(0, 0, "[%s] HalpPerformanceCounter Value is 0x%llX \n", __FUNCTION__, *reinterpret_cast(m_HalpPerformanceCounter)); - - - //鍦 KiUpdateTime涓悳绱alpOriginalPerformanceCounter锛學in10 21H1 鑷 Win11 22631 閫氱敤 - unsigned long long addressHalpOriginalPerformanceCounter = KUtils::FindPatternImage(ntoskrnl, - "\x48\x8b\x05\x00\x00\x00\x00\x48\x3b\x00\x0f\x85\x00\x00\x00\x00\xA0", - "xxx????xx?xx????x"); - if (!addressHalpOriginalPerformanceCounter) - { - //Win11 23606 涔嬪悗,鍦 KeQueryPerformanceCounter 涓悳绱alpOriginalPerformanceCounter - addressHalpOriginalPerformanceCounter = KUtils::FindPatternImage(ntoskrnl, - "\x48\x8b\x0d\x00\x00\x00\x00\x4c\x00\x00\x00\x00\x48\x3b\xf1", - "xxx????x????xxx"); - - } - if (!addressHalpOriginalPerformanceCounter) - { - //鍦╓in11 29648 鍙嶆眹缂栧緱鍒扮殑鐗瑰緛鐮 - addressHalpOriginalPerformanceCounter = KUtils::FindPatternImage(ntoskrnl, - "\x48\xF7\xE2\x4C\x03\xDA\x48\x8B\x05\x00\x00\x00\x00\x48\x3B\xF0", - "xxxxxxxxx????xxx"); - if (addressHalpOriginalPerformanceCounter) - { - addressHalpOriginalPerformanceCounter += 6; - } - if (!addressHalpOriginalPerformanceCounter) - { - DbgPrintEx(0, 0, "[%s] Find HalpOriginalPerformanceCounter Failed! \n", __FUNCTION__); - return false; - } - } - m_HalpOriginalPerformanceCounter = reinterpret_cast - (reinterpret_cast(addressHalpOriginalPerformanceCounter) + 7 + *reinterpret_cast(reinterpret_cast(addressHalpOriginalPerformanceCounter) + 3)); - DbgPrintEx(0, 0, "[%s] HalpOriginalPerformanceCounter Is 0x%llX \n", __FUNCTION__, m_HalpOriginalPerformanceCounter); - if (!m_HalpOriginalPerformanceCounter) return false; - DbgPrintEx(0, 0, "[%s] HalpOriginalPerformanceCounter Value Is 0x%llX \n", __FUNCTION__, *reinterpret_cast(m_HalpOriginalPerformanceCounter)); - - //HalpPerformanceCounter涓被鍨嬬殑鎸囬拡锛屽悗闈㈣繘琛屼慨鏀规椂浣跨敤 - m_HalpPerformanceCounterType = (ULONG*)((ULONG_PTR)(*(PVOID*)m_HalpPerformanceCounter) + HALP_PERFORMANCE_COUNTER_TYPE_OFFSET); - if (!m_HalpPerformanceCounterType) - { - DbgPrintEx(0, 0, "[%s] m_HalpPerformanceCounterType Is Null! \n", __FUNCTION__); - return false; - } - //鍒ゆ柇鍦ㄧ墿鐞嗘満涓婃椂鎵嶈繘琛屽悗杈圭殑鎿嶄綔 - if (*m_HalpPerformanceCounterType == HALP_PERFORMANCE_COUNTER_TYPE_PHYSICAL_MACHINE) - { - //鎼滅储HalpTimerQueryHostPerformanceCounter涓垽鏂殑Type鍊硷紝鍏跺疄涔熷彲浠ョ洿鎺ュ垽鏂郴缁熺増鏈 - //鍙傝僅alpTimerQueryHostPerformanceCounter涓 *(_DWORD *)(HalpPerformanceCounter + 0xE4) != 7 , - //Win11 22000 鍙婁互涓嬪间负8 22621 浠ヤ笂涓7 - //鍒╃敤鍓嶈竟鎼滅储鐨 addressHalpPerformanceCounter,浠ヤ笅娉ㄩ噴涓篧in11 22621 HalpTimerQueryHostPerformanceCounter 鐨 IDA閫嗗悜浠g爜 - //.text : 0000000140520A1A 48 8B 05 8F 36 74 00 mov rax, cs : HalpPerformanceCounter - //.text : 0000000140520A21 48 8B F9 mov rdi, rcx - //.text : 0000000140520A24 48 85 C0 test rax, rax - //.text : 0000000140520A27 74 3F jz short loc_140520A68 - //.text : 0000000140520A29 83 B8 E4 00 00 00 07 cmp dword ptr[rax + 0E4h], 7 - m_VmHalpPerformanceCounterType = *(reinterpret_cast(addressHalpPerformanceCounter) + 21); - DbgPrintEx(0, 0, "[%s] HalpPerformanceCounterType In Virtual Machine Value is 0x%x \n", __FUNCTION__, m_VmHalpPerformanceCounterType); - - //鍒嗛厤涓涓悓HalpPerformanceCounter涓鏍风殑绌洪棿锛岀敤鏉ユ浛鎹alpOriginalPerformanceCounter锛 - //鏇挎崲鐨勬暟鎹腑Type涓 5, 鍊嶆暟涓哄熀鍑嗙殑 10000000, - //ntoskrnl涓殑鍘熼昏緫涓 HalpOriginalPerformanceCounter = HalpPerformanceCounter - m_HalpOriginalPerformanceCounterCopy = (ULONGLONG)ExAllocatePoolWithTag(NonPagedPool, 0xFF, 'freP'); - if (!m_HalpOriginalPerformanceCounterCopy) - { - DbgPrintEx(0, 0, "[%s] Allocate m_HalpOriginalPerformanceCounterReplace Failed!\n", __FUNCTION__); - return false; - } - RtlZeroMemory((PVOID)m_HalpOriginalPerformanceCounterCopy, 0xFF); - //璁剧疆鍩烘湰閫熷害锛 - *(PULONGLONG)(m_HalpOriginalPerformanceCounterCopy + HALP_PERFORMANCE_COUNTER_BASE_RATE_OFFSET) = HALP_PERFORMANCE_COUNTER_BASE_RATE; - *(PULONG)(m_HalpOriginalPerformanceCounterCopy + HALP_PERFORMANCE_COUNTER_TYPE_OFFSET) = HALP_PERFORMANCE_COUNTER_TYPE_PHYSICAL_MACHINE; - DbgPrintEx(0, 0, "[%s] m_HalpOriginalPerformanceCounterCopy锛0x%llX \n", __FUNCTION__, m_HalpOriginalPerformanceCounterCopy); - - // KUSER_SHARED_DATA鐨凲pcBias瀛楁锛屽湪浠庣郴缁熶粠鐫$湢鐘舵佹仮澶嶆甯哥姸鎬佸悗鍋滄鏃讹紝绯荤粺鏃堕棿淇鏃朵娇鐢 - PLONGLONG pQpcPointer = (PLONGLONG)0xFFFFF780000003B8; - m_QpcMdl = IoAllocateMdl(pQpcPointer, 8, false, false, NULL); - if (!m_QpcMdl) - { - DbgPrintEx(0, 0, "[%s] m_QpcMdl IoAllocateMdl Failed!\n", __FUNCTION__); - return false; - } - MmBuildMdlForNonPagedPool(m_QpcMdl); - m_QpcPointer = (PLONGLONG)MmMapLockedPagesSpecifyCache(m_QpcMdl, KernelMode, MmWriteCombined, NULL, false, NormalPagePriority); - if (!m_QpcPointer) - { - DbgPrintEx(0, 0, "[%s] m_QpcPointer MmMapLockedPagesSpecifyCache Failed!\n", __FUNCTION__); - return false; - } - } - + DbgPrintEx(0, 0, "[%s] Allocate m_HalpOriginalPerformanceCounterReplace Failed!\n", __FUNCTION__); + return false; + } + RtlZeroMemory((PVOID)m_HalpOriginalPerformanceCounterCopy, 0xFF); + //璁剧疆鍩烘湰閫熷害锛 + *(PULONGLONG)(m_HalpOriginalPerformanceCounterCopy + HALP_PERFORMANCE_COUNTER_BASE_RATE_OFFSET) = HALP_PERFORMANCE_COUNTER_BASE_RATE; + *(PULONG)(m_HalpOriginalPerformanceCounterCopy + HALP_PERFORMANCE_COUNTER_TYPE_OFFSET) = HALP_PERFORMANCE_COUNTER_TYPE_PHYSICAL_MACHINE; + DbgPrintEx(0, 0, "[%s] m_HalpOriginalPerformanceCounterCopy锛0x%llX \n", __FUNCTION__, m_HalpOriginalPerformanceCounterCopy); + + // KUSER_SHARED_DATA鐨凲pcBias瀛楁锛屽湪浠庣郴缁熶粠鐫$湢鐘舵佹仮澶嶆甯哥姸鎬佸悗鍋滄鏃讹紝绯荤粺鏃堕棿淇鏃朵娇鐢 + PLONGLONG pQpcPointer = (PLONGLONG)0xFFFFF780000003B8; + m_QpcMdl = IoAllocateMdl(pQpcPointer, 8, false, false, NULL); + if (!m_QpcMdl) + { + DbgPrintEx(0, 0, "[%s] m_QpcMdl IoAllocateMdl Failed!\n", __FUNCTION__); + return false; } + MmBuildMdlForNonPagedPool(m_QpcMdl); + m_QpcPointer = (PLONGLONG)MmMapLockedPagesSpecifyCache(m_QpcMdl, KernelMode, MmWriteCombined, NULL, false, NormalPagePriority); + if (!m_QpcPointer) + { + DbgPrintEx(0, 0, "[%s] m_QpcPointer MmMapLockedPagesSpecifyCache Failed!\n", __FUNCTION__); + return false; + } + } - return true; } - ULONG64 FakeGetReferenceTimeUsingTscPage() + return true; + } + + ULONG64 FakeGetReferenceTimeUsingTscPage() + { + return __rdtsc(); + } + + bool Start() + { + if (!m_InfinityCallback) return false; + + // 鏃犳晥鎸囬拡 + if (!MmIsAddressValid(m_GetCpuClock)) { - return __rdtsc(); + DbgPrintEx(0, 0, "[%s] get cpu clock vaild \n", __FUNCTION__); + return false; } - bool Start() + /* 杩欓噷鎴戜滑鍖哄垎涓涓嬬郴缁熺増鏈 + * 浠嶹in7鍒癢in10 1909,m_GetCpuClock鏄竴涓嚱鏁,寰鍚庣殑鐗堟湰鏄竴涓暟鍊间簡 + * 澶т簬3鎶涘紓甯 + * 绛変簬3鐢╮dtsc + * 绛変簬2鐢╫ff_140C00A30 + * 绛変簬1鐢↘eQueryPerformanceCounter + * 绛変簬0鐢≧tlGetSystemTimePrecise + * 鎴戜滑鐨勫仛娉曞弬鑰冪綉鍧https://www.freebuf.com/articles/system/278857.html + * 鎴戜滑杩欓噷鍦2韬笂鍋氭枃绔 + */ + // 淇濆瓨GetCpuClock鍘熷鍊,閫鍑烘椂濂芥仮澶 + m_OriginalGetCpuClock = (unsigned long long)(*m_GetCpuClock); + if (m_BuildNumber <= 18363) + { + // 鐩存帴淇敼鍑芥暟鎸囬拡 + DbgPrintEx(0, 0, "[%s] GetCpuClock Is 0x%p\n", __FUNCTION__, *m_GetCpuClock); + *m_GetCpuClock = SelfGetCpuClock; + DbgPrintEx(0, 0, "[%s] Update GetCpuClock Is 0x%p\n", __FUNCTION__, *m_GetCpuClock); + } + else { - if (!m_InfinityCallback) return false; - // 鏃犳晥鎸囬拡 - if (!MmIsAddressValid(m_GetCpuClock)) + /* 杩欓噷鎴戜滑璁剧疆涓2, 杩欐牱瀛愭墠鑳借皟鐢╫ff_140C00A30鍑芥暟 + * 鍏跺疄璇ユ寚閽堝氨鏄疕alpTimerQueryHostPerformanceCounter鍑芥暟 + * 璇ュ嚱鏁伴噷闈㈠張鏈変袱涓嚱鏁版寚閽,绗竴涓氨鏄疕vlGetQpcBias,灏辨槸鎴戜滑鐨勭洰鏍 + */ + *m_GetCpuClock = (void*)2; + DbgPrintEx(0, 0, "[%s] Update GetCpuClock Is %p \n", __FUNCTION__, *m_GetCpuClock); + + // 淇濆瓨鏃vlGetQpcBias鍦板潃,鏂逛究鍚庨潰娓呯悊鐨勬椂鍊欏鍘熺幆澧 + m_OriginalHvlGetQpcBias = (HvlGetQpcBiasPtr)(*((unsigned long long*)m_HvlGetQpcBias)); + + //鐗╃悊鏈篐vlpGetReferenceTimeUsingTscPage涓虹┖锛屽湪铏氭嫙鏈轰笂鎸囧悜HvlGetReferenceTimeUsingTscPage鍑芥暟锛 + //鏁呭湪鍊间负绌烘椂杩涜淇敼锛屼絾鏀逛负HvlGetReferenceTimeUsingTscPage鍚庤摑灞忥紝灏濊瘯鏀逛负NtYieldExecution浣嗘湭瀵煎嚭锛屾敼ZwYieldExecution鍚庡鑷撮噸鍏ラ敊璇紝 + //缁忓疄楠屾敼涓轰竴涓病鏈夊弬鏁扮殑鍑芥暟,鍑芥暟杩斿洖 __rdtsc + if (m_HvlpGetReferenceTimeUsingTscPage) + { + //涓嶈兘浣跨敤鍘熸潵鐨凥vlGetReferenceTimeUsingTscPage锛屽湪 HvlpGetReferenceTimeUsingTscPage 鍊间负绌烘椂锛屽嚱鏁伴噷鐨勬湁鏁版嵁缁撴瀯鏈垵濮嬪寲 + m_OriginalHvlpGetReferenceTimeUsingTscPage = *((unsigned long long*)m_HvlpGetReferenceTimeUsingTscPage); + if (m_OriginalHvlpGetReferenceTimeUsingTscPage == 0) //鍙湪HvlpGetReferenceTimeUsingTscPage鍊间负绌烘椂鎵嶈缃紝鍏跺畠淇濇寔鍘熷涓嶅彉 { - DbgPrintEx(0, 0, "[%s] get cpu clock vaild \n", __FUNCTION__); - return false; + *((unsigned long long*)m_HvlpGetReferenceTimeUsingTscPage) = (ULONGLONG)FakeGetReferenceTimeUsingTscPage; + DbgPrintEx(0, 0, "[%s] Update HvlpGetReferenceTimeUsingTscPage Value : %p \n", __FUNCTION__, (PVOID)FakeGetReferenceTimeUsingTscPage); } - /* 杩欓噷鎴戜滑鍖哄垎涓涓嬬郴缁熺増鏈 - * 浠嶹in7鍒癢in10 1909,m_GetCpuClock鏄竴涓嚱鏁,寰鍚庣殑鐗堟湰鏄竴涓暟鍊间簡 - * 澶т簬3鎶涘紓甯 - * 绛変簬3鐢╮dtsc - * 绛変簬2鐢╫ff_140C00A30 - * 绛変簬1鐢↘eQueryPerformanceCounter - * 绛変簬0鐢≧tlGetSystemTimePrecise - * 鎴戜滑鐨勫仛娉曞弬鑰冪綉鍧https://www.freebuf.com/articles/system/278857.html - * 鎴戜滑杩欓噷鍦2韬笂鍋氭枃绔 - */ - // 淇濆瓨GetCpuClock鍘熷鍊,閫鍑烘椂濂芥仮澶 - m_OriginalGetCpuClock = (unsigned long long)(*m_GetCpuClock); - if (m_BuildNumber <= 18363) - { - // 鐩存帴淇敼鍑芥暟鎸囬拡 - DbgPrintEx(0, 0, "[%s] GetCpuClock Is 0x%p\n", __FUNCTION__, *m_GetCpuClock); - *m_GetCpuClock = SelfGetCpuClock; - DbgPrintEx(0, 0, "[%s] Update GetCpuClock Is 0x%p\n", __FUNCTION__, *m_GetCpuClock); - } - else - { + } - /* 杩欓噷鎴戜滑璁剧疆涓2, 杩欐牱瀛愭墠鑳借皟鐢╫ff_140C00A30鍑芥暟 - * 鍏跺疄璇ユ寚閽堝氨鏄疕alpTimerQueryHostPerformanceCounter鍑芥暟 - * 璇ュ嚱鏁伴噷闈㈠張鏈変袱涓嚱鏁版寚閽,绗竴涓氨鏄疕vlGetQpcBias,灏辨槸鎴戜滑鐨勭洰鏍 - */ - *m_GetCpuClock = (void*)2; - DbgPrintEx(0, 0, "[%s] Update GetCpuClock Is %p \n", __FUNCTION__, *m_GetCpuClock); - // 淇濆瓨鏃vlGetQpcBias鍦板潃,鏂逛究鍚庨潰娓呯悊鐨勬椂鍊欏鍘熺幆澧 - m_OriginalHvlGetQpcBias = (HvlGetQpcBiasPtr)(*((unsigned long long*)m_HvlGetQpcBias)); + //杩欎釜鏄ц兘璁℃暟鍣ㄧ殑绫诲瀷 鍦ㄨ櫄鎷熸満涓婁负 7鎴栬8 鐗╃悊鏈轰笂涓 5 鍙傝 HalpTimerSelectRoles 涓殑 HalpTimerFindIdealPerformanceCounterSource + m_OriginalHalpPerformanceCounterType = *m_HalpPerformanceCounterType; + DbgPrintEx(0, 0, "[%s] Original HalpPerformanceCounterType Value : %d\n", __FUNCTION__, m_OriginalHalpPerformanceCounterType); + if (*m_HalpPerformanceCounterType == HALP_PERFORMANCE_COUNTER_TYPE_PHYSICAL_MACHINE) //鍙湪鐗╃悊鏈虹殑鎯呭喌涓嬭繘琛屼慨鏀 + { + //鏇存敼 HalpOriginalPerformanceCounter锛屽師鍊间负 m_HalpPerformanceCounter鐨勫 + *(unsigned long long*)m_HalpOriginalPerformanceCounter = m_HalpOriginalPerformanceCounterCopy; + DbgPrintEx(0, 0, "[%s] Update HalpOriginalPerformanceCounter Value: %llX\n", __FUNCTION__, m_HalpOriginalPerformanceCounterCopy); + LARGE_INTEGER li = KeQueryPerformanceCounter(NULL); + DbgPrintEx(0, 0, "[%s] Tick Count %lld \n", __FUNCTION__, li.QuadPart); + //闇瑕佹妸鎬ц兘璁℃暟鍣ㄧ被鍨嬫敼涓鸿櫄鎷熸満鐜涓嬬殑鍒ゆ柇鍊硷紝璋冩暣閫昏緫 鍙傝 HalpTimerSelectRoles 涓殑 HalpTimerFindIdealPerformanceCounterSource + *m_HalpPerformanceCounterType = m_VmHalpPerformanceCounterType; //鏀逛负铏氭嫙鏈虹幆澧冧腑鐨勭被鍨嬶紝7鎴栬8 + DbgPrintEx(0, 0, "[%s] Update HalpPerformanceCounterType Value : %d\n", __FUNCTION__, m_VmHalpPerformanceCounterType); + li = KeQueryPerformanceCounter(NULL); + DbgPrintEx(0, 0, "[%s] Tick Count %lld \n", __FUNCTION__, li.QuadPart); + } - //鐗╃悊鏈篐vlpGetReferenceTimeUsingTscPage涓虹┖锛屽湪铏氭嫙鏈轰笂鎸囧悜HvlGetReferenceTimeUsingTscPage鍑芥暟锛 - //鏁呭湪鍊间负绌烘椂杩涜淇敼锛屼絾鏀逛负HvlGetReferenceTimeUsingTscPage鍚庤摑灞忥紝灏濊瘯鏀逛负NtYieldExecution浣嗘湭瀵煎嚭锛屾敼ZwYieldExecution鍚庡鑷撮噸鍏ラ敊璇紝 - //缁忓疄楠屾敼涓轰竴涓病鏈夊弬鏁扮殑鍑芥暟,鍑芥暟杩斿洖 __rdtsc - if (m_HvlpGetReferenceTimeUsingTscPage) - { - //涓嶈兘浣跨敤鍘熸潵鐨凥vlGetReferenceTimeUsingTscPage锛屽湪 HvlpGetReferenceTimeUsingTscPage 鍊间负绌烘椂锛屽嚱鏁伴噷鐨勬湁鏁版嵁缁撴瀯鏈垵濮嬪寲 - m_OriginalHvlpGetReferenceTimeUsingTscPage = *((unsigned long long*)m_HvlpGetReferenceTimeUsingTscPage); - if (m_OriginalHvlpGetReferenceTimeUsingTscPage == 0) //鍙湪HvlpGetReferenceTimeUsingTscPage鍊间负绌烘椂鎵嶈缃紝鍏跺畠淇濇寔鍘熷涓嶅彉 - { - *((unsigned long long*)m_HvlpGetReferenceTimeUsingTscPage) = (ULONGLONG)FakeGetReferenceTimeUsingTscPage; - DbgPrintEx(0, 0, "[%s] Update HvlpGetReferenceTimeUsingTscPage Value : %p \n", __FUNCTION__, (PVOID)FakeGetReferenceTimeUsingTscPage); - } - } + // 璁剧疆閽╁瓙 + *((unsigned long long*)m_HvlGetQpcBias) = (unsigned long long)FakeHvlGetQpcBias; + DbgPrintEx(0, 0, "[%s] Update HvlGetQpcBias Value is %p \n", __FUNCTION__, FakeHvlGetQpcBias); + } - //杩欎釜鏄ц兘璁℃暟鍣ㄧ殑绫诲瀷 鍦ㄨ櫄鎷熸満涓婁负 7鎴栬8 鐗╃悊鏈轰笂涓 5 鍙傝 HalpTimerSelectRoles 涓殑 HalpTimerFindIdealPerformanceCounterSource - m_OriginalHalpPerformanceCounterType = *m_HalpPerformanceCounterType; - DbgPrintEx(0, 0, "[%s] Original HalpPerformanceCounterType Value : %d\n", __FUNCTION__, m_OriginalHalpPerformanceCounterType); - if (*m_HalpPerformanceCounterType == HALP_PERFORMANCE_COUNTER_TYPE_PHYSICAL_MACHINE) //鍙湪鐗╃悊鏈虹殑鎯呭喌涓嬭繘琛屼慨鏀 - { - //鏇存敼 HalpOriginalPerformanceCounter锛屽師鍊间负 m_HalpPerformanceCounter鐨勫 - *(unsigned long long*)m_HalpOriginalPerformanceCounter = m_HalpOriginalPerformanceCounterCopy; - DbgPrintEx(0, 0, "[%s] Update HalpOriginalPerformanceCounter Value: %llX\n", __FUNCTION__, m_HalpOriginalPerformanceCounterCopy); - LARGE_INTEGER li = KeQueryPerformanceCounter(NULL); - DbgPrintEx(0, 0, "[%s] Tick Count %lld \n", __FUNCTION__, li.QuadPart); - //闇瑕佹妸鎬ц兘璁℃暟鍣ㄧ被鍨嬫敼涓鸿櫄鎷熸満鐜涓嬬殑鍒ゆ柇鍊硷紝璋冩暣閫昏緫 鍙傝 HalpTimerSelectRoles 涓殑 HalpTimerFindIdealPerformanceCounterSource - *m_HalpPerformanceCounterType = m_VmHalpPerformanceCounterType; //鏀逛负铏氭嫙鏈虹幆澧冧腑鐨勭被鍨嬶紝7鎴栬8 - DbgPrintEx(0, 0, "[%s] Update HalpPerformanceCounterType Value : %d\n", __FUNCTION__, m_VmHalpPerformanceCounterType); - li = KeQueryPerformanceCounter(NULL); - DbgPrintEx(0, 0, "[%s] Tick Count %lld \n", __FUNCTION__, li.QuadPart); - } + static bool s_IsThreadCreated = false; + if (!s_IsThreadCreated) + { + s_IsThreadCreated = true; + OBJECT_ATTRIBUTES att{ 0 }; + HANDLE hThread = NULL; + InitializeObjectAttributes(&att, 0, OBJ_KERNEL_HANDLE, 0, 0); + NTSTATUS ntStatus = PsCreateSystemThread(&hThread, THREAD_ALL_ACCESS, &att, 0, &m_ClientId, DetectThreadRoutine, 0); + if (!NT_SUCCESS(ntStatus)) + { + DbgPrintEx(0, 0, "[%s] Create Detect Thread Failed! \n", __FUNCTION__); + } + else + { + ObReferenceObjectByHandle(hThread, THREAD_ALL_ACCESS, NULL, KernelMode, (PVOID*)&m_DetectThreadObject, NULL); + DbgPrintEx(0, 0, "[%s] Detect Routine Thread ID Is %d \n", __FUNCTION__, (int)m_ClientId.UniqueThread); + DbgPrintEx(0, 0, "[%s] Detect Routine Thread Object Is %p \n", __FUNCTION__, m_DetectThreadObject); + } + } - // 璁剧疆閽╁瓙 - *((unsigned long long*)m_HvlGetQpcBias) = (unsigned long long)FakeHvlGetQpcBias; - DbgPrintEx(0, 0, "[%s] Update HvlGetQpcBias Value is %p \n", __FUNCTION__, FakeHvlGetQpcBias); + return true; + } - } + bool Stop() + { + // 鍋滄妫娴嬬嚎绋 + m_DetectThreadStatus = false; - static bool s_IsThreadCreated = false; - if (!s_IsThreadCreated) - { - s_IsThreadCreated = true; - OBJECT_ATTRIBUTES att{ 0 }; - HANDLE hThread = NULL; - InitializeObjectAttributes(&att, 0, OBJ_KERNEL_HANDLE, 0, 0); - NTSTATUS ntStatus = PsCreateSystemThread(&hThread, THREAD_ALL_ACCESS, &att, 0, &m_ClientId, DetectThreadRoutine, 0); - if (!NT_SUCCESS(ntStatus)) - { - DbgPrintEx(0, 0, "[%s] Create Detect Thread Failed! \n", __FUNCTION__); - } - else - { - ObReferenceObjectByHandle(hThread, THREAD_ALL_ACCESS, NULL, KernelMode, (PVOID*)&m_DetectThreadObject, NULL); - DbgPrintEx(0, 0, "[%s] Detect Routine Thread ID Is %d \n", __FUNCTION__, (int)m_ClientId.UniqueThread); - DbgPrintEx(0, 0, "[%s] Detect Routine Thread Object Is %p \n", __FUNCTION__, m_DetectThreadObject); - } + bool bResult = NT_SUCCESS(EventTraceControl(EtwpStopTrace)) && NT_SUCCESS(EventTraceControl(EtwpStartTrace)); + DbgPrintEx(0, 0, "[%s] Enter... \n", __FUNCTION__); + if (m_DetectThreadObject) + { + DbgPrintEx(0, 0, "[%s] Wait For Detect Thread Termination \n", __FUNCTION__); + KeWaitForSingleObject(m_DetectThreadObject, Executive, KernelMode, false, NULL); + //Win7 7600 绯荤粺涓 ObDereferenceObject, Win7 7601鍙婁互涓婁负ObfDereferenceObject + //閲囩敤MmGetSystemRoutineAddress鍔ㄦ佽幏鍙栫浉搴旂殑鍑芥暟鍦板潃锛岃В鍐冲湪Win7 7600涓婁笉鑳藉姞杞介┍鍔ㄩ棶棰 + UNICODE_STRING usObfDereferenceObject = RTL_CONSTANT_STRING(L"ObfDereferenceObject"); + ObfDereferenceObjectPtr fnObfDereferenceObject = (ObfDereferenceObjectPtr)MmGetSystemRoutineAddress(&usObfDereferenceObject); + if (fnObfDereferenceObject) + { + fnObfDereferenceObject(m_DetectThreadObject); + } + else + { + + UNICODE_STRING usObDereferenceObject = RTL_CONSTANT_STRING(L"ObDereferenceObject"); + ObDereferenceObjectPtr fnObDereferenceObject = (ObDereferenceObjectPtr)MmGetSystemRoutineAddress(&usObDereferenceObject); + if (fnObDereferenceObject) + { + fnObDereferenceObject(m_DetectThreadObject); } - - return true; + else + { + DbgPrintEx(0, 0, "[%s] Can't Find ObDereferenceObject or ObfDereferenceObject \n", __FUNCTION__); + } + } + /*ObDereferenceObject(m_DetectThreadObject);*/ + DbgPrintEx(0, 0, "[%s] Detect Thread Terminated \n", __FUNCTION__); } - - bool Stop() + //m_GetCpuClock鍊艰繕鍘熻鍦ㄧ嚎绋嬪仠姝箣鍚庯紝鍚﹀垯鍙兘杩樺師鍚庡張琚嚎绋嬮噷鐨勯昏緫鏀逛负鎴戜滑鐨勫嚱鏁颁簡 + *m_GetCpuClock = (void*)m_OriginalGetCpuClock; + DbgPrintEx(0, 0, "[%s] Restore GetCpuClock is %p \n", __FUNCTION__, *m_GetCpuClock); + // Win10 1909浠ヤ笂绯荤粺闇瑕佹仮澶嶇幆澧 + if (m_BuildNumber > 18363) { - // 鍋滄妫娴嬬嚎绋 - m_DetectThreadStatus = false; - bool bResult = NT_SUCCESS(EventTraceControl(EtwpStopTrace)) && NT_SUCCESS(EventTraceControl(EtwpStartTrace)); - DbgPrintEx(0, 0, "[%s] Enter... \n", __FUNCTION__); - - if (m_DetectThreadObject) + if (m_HvlpGetReferenceTimeUsingTscPage) + { + //杩樺師 HvlpGetReferenceTimeUsingTscPage鐨勫间负m_OriginalHvlpGetReferenceTimeUsingTscPage锛屼篃鍗 0 + if (m_OriginalHvlpGetReferenceTimeUsingTscPage == 0) { - DbgPrintEx(0, 0, "[%s] Wait For Detect Thread Termination \n", __FUNCTION__); - KeWaitForSingleObject(m_DetectThreadObject, Executive, KernelMode, false, NULL); - //Win7 7600 绯荤粺涓 ObDereferenceObject, Win7 7601鍙婁互涓婁负ObfDereferenceObject - //閲囩敤MmGetSystemRoutineAddress鍔ㄦ佽幏鍙栫浉搴旂殑鍑芥暟鍦板潃锛岃В鍐冲湪Win7 7600涓婁笉鑳藉姞杞介┍鍔ㄩ棶棰 - UNICODE_STRING usObfDereferenceObject = RTL_CONSTANT_STRING(L"ObfDereferenceObject"); - ObfDereferenceObjectPtr fnObfDereferenceObject = (ObfDereferenceObjectPtr)MmGetSystemRoutineAddress(&usObfDereferenceObject); - if (fnObfDereferenceObject) - { - fnObfDereferenceObject(m_DetectThreadObject); - } - else - { - - UNICODE_STRING usObDereferenceObject = RTL_CONSTANT_STRING(L"ObDereferenceObject"); - ObDereferenceObjectPtr fnObDereferenceObject = (ObDereferenceObjectPtr)MmGetSystemRoutineAddress(&usObDereferenceObject); - if (fnObDereferenceObject) - { - fnObDereferenceObject(m_DetectThreadObject); - } - else - { - DbgPrintEx(0, 0, "[%s] Can't Find ObDereferenceObject or ObfDereferenceObject \n", __FUNCTION__); - } - } - /*ObDereferenceObject(m_DetectThreadObject);*/ - DbgPrintEx(0, 0, "[%s] Detect Thread Terminated \n", __FUNCTION__); + *((unsigned long long*)m_HvlpGetReferenceTimeUsingTscPage) = m_OriginalHvlpGetReferenceTimeUsingTscPage; + DbgPrintEx(0, 0, "[%s] Restore HvlpGetReferenceTimeUsingTscPage Value is 0x%llX \n", __FUNCTION__, m_OriginalHvlpGetReferenceTimeUsingTscPage); } - //m_GetCpuClock鍊艰繕鍘熻鍦ㄧ嚎绋嬪仠姝箣鍚庯紝鍚﹀垯鍙兘杩樺師鍚庡張琚嚎绋嬮噷鐨勯昏緫鏀逛负鎴戜滑鐨勫嚱鏁颁簡 - *m_GetCpuClock = (void*)m_OriginalGetCpuClock; - DbgPrintEx(0, 0, "[%s] Restore GetCpuClock is %p \n", __FUNCTION__, *m_GetCpuClock); - // Win10 1909浠ヤ笂绯荤粺闇瑕佹仮澶嶇幆澧 - if (m_BuildNumber > 18363) + } + + //鍙湪鐗╃悊鏈轰笂杩涜浠ヤ笅杩樺師 + if (m_OriginalHalpPerformanceCounterType == HALP_PERFORMANCE_COUNTER_TYPE_PHYSICAL_MACHINE) + { + LARGE_INTEGER liBegin = KeQueryPerformanceCounter(NULL); + DbgPrintEx(0, 0, "[%s] Tick Count Before Restore %lld \n", __FUNCTION__, liBegin.QuadPart); + //杩樺師 椤哄簭淇濇寔涓嬮潰鐨勯『搴 + *m_HalpPerformanceCounterType = m_OriginalHalpPerformanceCounterType; + //涓嶈兘杩樺師m_HalpOriginalPerformanceCounter涓哄師濮嬬殑鍊 m_HalpPerformanceCounter, + //鑰岄渶瑕佷繚鐣檓_HalpOriginalPerformanceCounter涓簃_HalpOriginalPerformanceCounterCopy鐨勫 + //鍚﹀垯杩樺師鍚庤鏁板櫒鏃堕棿杩斿洖浼氭瘮涔嬪墠灏忓緢澶氬鑷存閿 + //*(unsigned long long*)m_HalpOriginalPerformanceCounter = m_HalpPerformanceCounter; + + LARGE_INTEGER liEndFix = KeQueryPerformanceCounter(NULL); + //淇鐫$湢涔嬪悗鎭㈠姝e父鍋滄鏃舵椂闂撮敊璇鑷寸郴缁熷亣姝婚棶棰 + if (liEndFix.QuadPart - liBegin.QuadPart > HALP_PERFORMANCE_COUNTER_BASE_RATE) { - - if (m_HvlpGetReferenceTimeUsingTscPage) - { - //杩樺師 HvlpGetReferenceTimeUsingTscPage鐨勫间负m_OriginalHvlpGetReferenceTimeUsingTscPage锛屼篃鍗 0 - if (m_OriginalHvlpGetReferenceTimeUsingTscPage == 0) - { - *((unsigned long long*)m_HvlpGetReferenceTimeUsingTscPage) = m_OriginalHvlpGetReferenceTimeUsingTscPage; - DbgPrintEx(0, 0, "[%s] Restore HvlpGetReferenceTimeUsingTscPage Value is 0x%llX \n", __FUNCTION__, m_OriginalHvlpGetReferenceTimeUsingTscPage); - } - } - - //鍙湪鐗╃悊鏈轰笂杩涜浠ヤ笅杩樺師 - if (m_OriginalHalpPerformanceCounterType == HALP_PERFORMANCE_COUNTER_TYPE_PHYSICAL_MACHINE) - { - LARGE_INTEGER liBegin = KeQueryPerformanceCounter(NULL); - DbgPrintEx(0, 0, "[%s] Tick Count Before Restore %lld \n", __FUNCTION__, liBegin.QuadPart); - //杩樺師 椤哄簭淇濇寔涓嬮潰鐨勯『搴 - *m_HalpPerformanceCounterType = m_OriginalHalpPerformanceCounterType; - //涓嶈兘杩樺師m_HalpOriginalPerformanceCounter涓哄師濮嬬殑鍊 m_HalpPerformanceCounter, - //鑰岄渶瑕佷繚鐣檓_HalpOriginalPerformanceCounter涓簃_HalpOriginalPerformanceCounterCopy鐨勫 - //鍚﹀垯杩樺師鍚庤鏁板櫒鏃堕棿杩斿洖浼氭瘮涔嬪墠灏忓緢澶氬鑷存閿 - //*(unsigned long long*)m_HalpOriginalPerformanceCounter = m_HalpPerformanceCounter; - - LARGE_INTEGER liEndFix = KeQueryPerformanceCounter(NULL); - //淇鐫$湢涔嬪悗鎭㈠姝e父鍋滄鏃舵椂闂撮敊璇鑷寸郴缁熷亣姝婚棶棰 - if (liEndFix.QuadPart - liBegin.QuadPart > HALP_PERFORMANCE_COUNTER_BASE_RATE) - { - LONGLONG llQpcValue = *m_QpcPointer; - llQpcValue -= liEndFix.QuadPart - liBegin.QuadPart; - *m_QpcPointer = llQpcValue; - DbgPrintEx(0, 0, "[%s] Fix Qpc Value :%llX\n", __FUNCTION__, llQpcValue); - } - - LARGE_INTEGER liEnd = KeQueryPerformanceCounter(NULL); - DbgPrintEx(0, 0, "[%s] Restore HalpPerformanceCounterType Value is %ld \n", __FUNCTION__, m_OriginalHalpPerformanceCounterType); - DbgPrintEx(0, 0, "[%s] Tick Count After Restore %lld \n", __FUNCTION__, liEnd.QuadPart); - if (m_QpcMdl) - { - DbgPrintEx(0, 0, "[%s] Free Qpc Mdl\n", __FUNCTION__); - IoFreeMdl(m_QpcMdl); - m_QpcMdl = NULL; - } - } - *((unsigned long long*)m_HvlGetQpcBias) = (unsigned long long)m_OriginalHvlGetQpcBias; - DbgPrintEx(0, 0, "[%s] Restore HvlGetQpcBias is %p \n", __FUNCTION__, m_OriginalHvlGetQpcBias); - + LONGLONG llQpcValue = *m_QpcPointer; + llQpcValue -= liEndFix.QuadPart - liBegin.QuadPart; + *m_QpcPointer = llQpcValue; + DbgPrintEx(0, 0, "[%s] Fix Qpc Value :%llX\n", __FUNCTION__, llQpcValue); } - if (bResult) + LARGE_INTEGER liEnd = KeQueryPerformanceCounter(NULL); + DbgPrintEx(0, 0, "[%s] Restore HalpPerformanceCounterType Value is %ld \n", __FUNCTION__, m_OriginalHalpPerformanceCounterType); + DbgPrintEx(0, 0, "[%s] Tick Count After Restore %lld \n", __FUNCTION__, liEnd.QuadPart); + if (m_QpcMdl) { - DbgPrintEx(0, 0, "[%s] Stop Finished! \n", __FUNCTION__); + DbgPrintEx(0, 0, "[%s] Free Qpc Mdl\n", __FUNCTION__); + IoFreeMdl(m_QpcMdl); + m_QpcMdl = NULL; } - else - { - DbgPrintEx(0, 0, "[%s] Stop Failed! \n", __FUNCTION__); - } - return bResult; + } + *((unsigned long long*)m_HvlGetQpcBias) = (unsigned long long)m_OriginalHvlGetQpcBias; + DbgPrintEx(0, 0, "[%s] Restore HvlGetQpcBias is %p \n", __FUNCTION__, m_OriginalHvlGetQpcBias); + + } + + if (bResult) + { + DbgPrintEx(0, 0, "[%s] Stop Finished! \n", __FUNCTION__); + } + else + { + DbgPrintEx(0, 0, "[%s] Stop Failed! \n", __FUNCTION__); } + return bResult; + } }