|
0x0 前言
看本文之前发起先看一下《剖析InfinityHook原理 掀起一场更激烈的攻与防恶战》这篇文章。
相识一下InfinityHook的根本原理。
0xI InfinityHook探求指针方式解析
我们先来看看原作者是如何探求的,在源码的IfhpInternalGetCpuClock函数内
PVOID* StackMax = (PVOID*)__readgsqword(OFFSET_KPCR_RSP_BASE); PVOID* StackFrame = (PVOID*)_AddressOfReturnAddress();StackFrame为栈顶,StackMax为栈底,
获取两个值是为了确定范围,要在这两个值范围之间探求在堆栈中那个要替换的指针。
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; }将StackMax栈底给StackCurrent再给AsUlong,用AsUlong地点里的值与INFINITYHOOK_MAGIC_1相比较,
不相等就回到for循环减一,相等就减1继续与INFINITYHOOK_MAGIC_2比较,不相等就回到for减一循环,
直到找到两个值,也就是说,从栈底往上一个个的比对值是否为INFINITYHOOK_MAGIC,直到找到两个值才继续。这两个值分别为 0x501802 和0xF33,这里记下两个值背面有提及。
for (;StackCurrent < StackMax;++StackCurrent) { PULONGLONG AsUlonglong = (PULONGLONG)StackCurrent; if (!(PAGE_ALIGN(*AsUlonglong) >= SystemCallEntryPage && PAGE_ALIGN(*AsUlonglong) < (PVOID)((uintptr_t)SystemCallEntryPage + (PAGE_SIZE * 2)))) { continue; } void** SystemCallFunction = &StackCurrent[9]; if (IfhpCallback) { IfhpCallback(SystemCallIndex, SystemCallFunction); } break; }找到两个值的位置后,再从这个位置向下,探求系统调用,找到后,以这个系统调用的位置为基准,
以后找9个,每个8字节,也就是偏移72的位置的值,如许这个函数指针就找到了。
0x2逆向HOOK系统调用变乱
是不是看的一脸懵逼,没错我也是,为什么是那两个特定值,那两个值是怎么来的。
那篇文章没写 ,源码的注释也没说,那换个其他变乱这个探求方式还能用吗?
不能,我试过了。
这里就要理一理思路了,这两个值既然在堆栈中,那么不是当前函数搞进去的,就是前一个函数,
或者前前的函数.........., 那么这个函数就应该在调用栈上,那我们就下个断点,在windbg中看一下调用栈。 |
|