【问题标题】:How to detect API Hook?如何检测 API Hook?
【发布时间】:2017-02-09 02:49:21
【问题描述】:

我一直在尝试检测 API Hook、inline 和 EAT hook。

目前我没有找到任何关于如何检测 EAT 钩子的信息。

对于 Inline Ring 3 挂钩,我目前所拥有的:

FARPROC Address = GetProcAddress(GetModuleHandle("kernel32.dll"),"ExitProcess");
if (*(BYTE*)Address == 0xE9 || *(BYTE*)Address == 0x90 || *(BYTE*)Address == 0xC3)
{
 printf("Api hooked\n");
}

问题是有几个操作码可用于挂钩/更改函数的序言,检查 JMP / NOP / RET 是微不足道的,我见过很多 HOOK 类型,如 PUSH RET、MOV、RETN 等...

我想知道是否有人知道如何检测 API 中的这些钩子(弯路)或修改。 还有一些检测 EAT 钩子的方法。

谢谢。

【问题讨论】:

  • 如果有人挂钩了您的程序,那么他们可以挂钩您的挂钩检测器。
  • 嗯,检查导出地址表是否已被挂钩的明显方法是查看表中的任何地址是否指向 EAT 所属的 DLL 之外的某个位置。虽然,我相信一些标准 DLL 通过 EAT 将一些函数转发给其他 DLL,所以你必须处理这种情况。

标签: c++ api assembly hook detection


【解决方案1】:

GetProcAddress 也可以被钩住。此外,由于您无法知道要修补的确切 API,因此您必须检查所有导入的函数,这非常乏味。由于入侵者有足够的权限注入您的进程地址空间和挂钩 API 方法,老实说,几乎没有办法阻止他完全修补任何保护机制。通常现代软件保护系统包括内核模式驱动程序,它扫描程序内存并防止 dll 注入和远程内存修改。此外,使用代码加密/混淆系统(例如 Themida),甚至是具有完全外来处理器指令集的内部虚拟执行机也很常见,这使得动态修补代码非常困难。

【讨论】:

  • 你是对的,当然,但我已经看到了一些非常有效的对策——从磁盘手动加载 Kernel32.dll,确保文件已签名,以及比较指令前奏等, GetProcAddress 等关键函数。如果 GPA 被挂钩,他们必须在比较数据之前动态取消挂钩以避免检测。之后,您可以比较磁盘与内存中的函数指令校验和......等等。但是,是的,这是一场猫捉老鼠的游戏,没有万无一失的方法。
【解决方案2】:

我认为您应该将磁盘中的 kernel32.dll 与内存中的当前 dll 进行比较,并且您应该忽略 IAT 并修复重定位,否则您会得到不同的哈希值。

如果您想要一个更简单的解决方案,只需重命名 kernel32.dll 并从重命名的 DLL 进行 API 调用。

【讨论】:

    【解决方案3】:

    您需要为当前进程挂钩 IAT 地址,然后立即保存字节。

    在这之后你有原始字节,所以你可以稍后尝试再次复制它们并使用 memcmp() 将旧(原始)字节与新字节进行比较,如果它们不同,那么您的 IAT 地址已被另一个进程挂钩。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-03
      • 1970-01-01
      • 1970-01-01
      • 2020-02-14
      • 1970-01-01
      • 2021-06-03
      • 2021-04-05
      • 2019-04-16
      相关资源
      最近更新 更多