Hooking 是一种技术,它允许用户重定向程序的执行流。大多数时候我们使用函数 hooking。我们要么替换要么将函数重定向到我们自己的函数,这非常有用并且有多种用例。有多种 hooking 方式,这里我们关注的是 IAT Hooking,它代表导入地址表(Import Address Table)。它包括在一个运行时填充的大表中,将函数的地址替换为我们自己的地址。正如我在另一个仓库中所述,我建议你阅读更多关于 PE 格式 的内容,以理解这段代码中 IAT 解析部分。以下是 IAT Hooking 工作原理的基本示意图。在这个例子中,恶意代码执行后会调用原始函数。在这个例子中,我们将简单地调用另一个函数而不是原始函数。这种技术的优势在于它不需要像常规的 detours .text 补丁 hook 那样修改函数体,后者必须更改函数开头的指令以放置一个 jmp 例如。
实际上它比听起来要简单得多,我们将在内部进行以使事情更容易,这意味着这个仓库将编译成一个 DLL,可以使用我的 LoadLibraryA 或 Manual Mapping 注入器注入到目标进程中。
首先我们解析目标进程的 PE Headers 以定位 Import Descriptor,如下所示:
process_base + nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
然后我们可以遍历每个导入的模块,遍历该模块中的每个函数(这就是嵌套循环的原因),并找到运行时填充的该函数的地址。在这个例子中,我们将 hook TranslateMessage,它被 Windows 用于处理 GUI 上的事件。所以一旦我们找到了该函数的地址,我们就将其替换为我们之前定义的、存在于远程进程上下文中的我们自己的函数的地址,因为我们是内部注入。不要忘记使用 VirtualProtect 来确保你有权限写入该位置。
VirtualProtect(&firstThunk->u1.Function, sizeof(uint64_t), PAGE_READWRITE, &old_protection);
firstThunk->u1.Function = (uint64_t)hookfunction;
如你所见,当 notepad 调用 TranslateMessage(几乎一直如此)时,它将运行我们的 hook 函数,最终显示一个消息框!
image