make InfinityHook great again
前言
在我折腾InfinityHook的时候我发现2004下系统没啥作用,原因是在2004系统上 WMI_LOGGER_CONTEXT->GetCpuClock已经不是rdtsc()函数了而是一个叫做 EtwpGetLoggerTimeStamp的函数
EtwpGetLoggerTimeStamp函数按照WMI_LOGGER_CONTEXT->GetCpuClock的值有如下操作:
大于3抛异常
等于3用rdtsc
等于2用off_140C00A30
等于1用KeQueryPerformanceCounter
等于0用RtlGetSystemTimePrecise
3,1,0都好说,但是这个2的off_140C00A30是什么鬼?
查看引用:
他是一个在data上,指向HalpTimerQueryHostPerformanceCounter的指针
(我虽然不知道他有什么作用,但是我非常震撼,因为他的引用就那几个…为什么还要用指针)
当在内核遇到不是那么热度高的指针的时候,我们可以搭档尝试一下hook,因为内核里面这些指针太多,pg是管不来的.所以我尝试改一下InfinityHook,让他能在2004上支持:
干活
1.获取指针地址
// off_140C009E0 pattern
UCHAR pattern[] = "x48xccxccxccxccxccxccxE8xccxccxccxccx83xccxccx75xccx38xccxccxccxccxccx75xccx48xccxccxccxccxccxccx83xB8xccxccxccxccxccx0Fxccxccxccxccxcc";
NTSTATUS status = UtilScanSection(".text", (PCUCHAR)pattern, 0xCC, sizeof(pattern) - 1, (PVOID*)&PtrOff140C009E0);
if (!NT_SUCCESS(status))
{
kprintf("[DebugMessAge] off_140C009E0 not found! :( n");
return false;
}
PtrOff140C009E0 = PtrOff140C009E0 + *(ULONG*)(PtrOff140C009E0 + 3) + 7;
2.修改这个指针
拥有指针后,记得将WMI_LOGGER_CONTEXT->GetCpuClock设置为2:
*reinterpret_cast<uintptr_t*>((uintptr_t)CkclWmiLoggerContext + OFFSET_WMI_LOGGER_CONTEXT_CPU_CYCLE_CLOCK) = 2;
然后就是修改为自己的地址:
*((ULONG64*)PtrOff140C009E0) = (ULONG64)HookHalpTimerQueryHostPerformanceCounter;
hook函数:
extern "C" __int64 __fastcall HookHalpTimerQueryHostPerformanceCounter(ULONG64 * pTime)
{
if (ExGetPreviousMode() != KernelMode)
{
//__debugbreak();
IfhpInternalGetCpuClock();
}
return OldPtrOff140C009E0(pTime);
}
IfhpInternalGetCpuClock里面,就是从stack上得到syscall地址,如果是自己的就改为原来的.
ps: 第一次知道kthread里面还有syscallnum这个字段….
static ULONG64 IfhpInternalGetCpuClock()
{
//
// Extract the system call index (if you so desire).
//
PKTHREAD CurrentThread = (PKTHREAD)__readgsqword(OFFSET_KPCR_CURRENT_THREAD);
unsigned int SystemCallIndex = *(unsigned int*)((uintptr_t)CurrentThread + OFFSET_KTHREAD_SYSTEM_CALL_NUMBER);
PVOID* StackMax = (PVOID*)__readgsqword(OFFSET_KPCR_RSP_BASE);
PVOID* StackFrame = (PVOID*)_AddressOfReturnAddress();
//
// First walk backwards on the stack to find the 2 magic values.
//
for (PVOID* StackCurrent = StackMax;
StackCurrent > StackFrame;
--StackCurrent)
{
//
// This is intentionally being read as 4-byte magic on an 8
// byte aligned boundary.
//
PULONG AsUlong = (PULONG)StackCurrent;
if (*AsUlong != INFINITYHOOK_MAGIC_1)
{
continue;
}
//
// If the first magic is set, check for the second magic.
//
--StackCurrent;
PUSHORT AsShort = (PUSHORT)StackCurrent;
if (*AsShort != INFINITYHOOK_MAGIC_2)
{
continue;
}
//
// Now we reverse the direction of the stack walk.
//
for (;
StackCurrent < StackMax;
++StackCurrent)
{
PULONGLONG AsUlonglong = (PULONGLONG)StackCurrent;
if (!(PAGE_ALIGN(*AsUlonglong) >= SystemCallEntryPage &&
PAGE_ALIGN(*AsUlonglong) < (PVOID)((uintptr_t)SystemCallEntryPage + (PAGE_SIZE * 2))))
{
continue;
}
//
// If you want to "hook" this function, replace this stack memory
// with a pointer to your own function.
//
void** SystemCallFunction = &StackCurrent[9];
if (IfhpCallback)
{
IfhpCallback(SystemCallIndex, SystemCallFunction);
}
break;
}
break;
}
return __rdtsc();
}
至此魔改完毕,关闭调试器打签名上虚拟机看看会不会被pg:
2004上至少两个小时内没有PG,但是测试了经过5个小时后,他蓝屏了
难道真的我们没办法让他great again了?
再次伟大!
在HalpTimerQueryHostPerformanceCounter中,往下看:
这两个指针其实就是得到系统时间..而且是唯一在HalpTimerQueryHostPerformanceCounter用到的指针…
如果之前的off_140C00A30是被PG监控的,这两个指针会不会被监控呢?能不能利用呢?
此外不仅这个off_140C00A30函数,还有几个在ETW上必call的函数指针,这些指针有没有被监控呢?
让我们跟踪这个HalpTimerQueryHostPerformanceCounter上的两个函数:
微软在栈上初始化了一个数组,然后依次给这个数组赋值,根据赋值的信息,我们可以逆向推导出函数名字:

从而得知如下信息:
就从这个HvlGetQpcBias下手:
他会查询一个HvlpReferenceTscPage表,我们手动定位:
status = UtilScanSection(".text", (PCUCHAR)pattern_HvlpReferenceTscPage, 0xCC, sizeof(pattern_HvlpReferenceTscPage) - 1, (PVOID*)&HvlpReferenceTscPage);
if (!NT_SUCCESS(status))
{
kprintf("[DebugMessAge] HvlGetQpcBias not found! :( n");
return false;
}
HvlpReferenceTscPage = HvlpReferenceTscPage + *(ULONG*)(HvlpReferenceTscPage + 3) + 7;
之后还是老套路,但是请记住修改我们的函数:
extern "C" __int64 HookHvlGetQpcBias()
{
//__debugbreak();
if (ExGetPreviousMode() != KernelMode)
{
IfhpInternalGetCpuClock();
}
return *((ULONG64*)(*((ULONG64*)HvlpReferenceTscPage)) + 3);
}
测试:
working,看看多久会蓝屏
暂时21: 00-0: 00没有蓝屏
21:00 – 第二天10:19
继续测试满24小时看看
扩展
再除此之外,不仅仅syscall,还有一些其他的异常信息、内存分配、文件创建等都会调用存在这些指针函数的函数,能不能做一些内核异常hook?
halv这部分的函数指针在kebugcheck2中也有而且也被调用了,是不是可以从蓝屏中恢复系统?
等你来回答了,因为我时间不多
github:
https://github.com/huoji120/MakeInfinityHookGreatAgain
修正,也有人做了差不多的,不过他是HalpPerformanceCounter:
https://www.anquanke.com/post/id/206288
这洞留不久,估计再过几天就完全完蛋蛋了
来源:freebuf.com 2021-06-28 18:19:11 by: huoji120
相关推荐: pikachu靶场-XSS跨站脚本-xss之js输出 – 作者:知非知非知非
出题人真是皮的很!!!!http://localhost/pikachu/assets/images/nbaplayer/tmac.jpeg查看前台源代码!!!URL地址为:http://localhost/pikachu/vul/xss/xss_04.php…













