Kernel Detective 的众多功能之一是可以检索在驱动程序 win32k.sys 中实现的本机 apis 函数的原始地址并检查它们是否被挂钩。实现相同目标的可能方法是什么?
Kernel Detective 如何检查 API 函数是否被挂钩?
对于传统的内联钩子(只是替换函数的前几个字节),您可以简单地读取每个函数的前几个字节来检查它是否被钩子。更深的内联钩子将难以检测。
除了内联钩子,有人还可以钩住 SSDT。SSDT 是一个位于 WINAPI 的系统调用和实现它们的内核模式函数之间的表。SSDT 由系统调用 ID 索引,并将每个 ID 映射到内核模式函数的地址。对于 Windows 操作系统的任何给定服务包,此映射保持静态。所以很容易搞清楚每个系统调用ID对应的函数是什么,从而SSDT中的每个条目应该对应哪个函数。
要检测 SSDT 挂钩并恢复原始地址,您可以尝试以下任一方法:
您可以在 SSDT 被挂钩之前加载您的程序/驱动程序一次,并获取原始地址。只要在挂钩就位之前加载驱动程序,这将是相当可靠的。
或者,您可以从 Microsoft 的符号存储下载 .pdb 文件,并使用 DIA SDK 或 DbgHelp API 从中获取原始地址。只要存在连接并且没有任何干扰,这是非常可靠的。但是,对于与 ntoskrnl 或 win32k 一样大的 .pdb,这将非常慢。
实际上有两个 SSDT,一个普通 SSDT 和一个影子 SSDT。如果只连接了第一个 SSDT,则可以使用 Shadow SSDT 中的值检查这些值。或相反亦然。
您可以检查 SSDT 中是否有任何条目指向内核/win32k 之外的地址。这是一种非常可靠的检测钩子的方法,但它不会轻易让您获得原始地址。
扫描字节签名是一种可以定位原始地址的可靠且隐蔽的方式。
还有一个类似的问题在这里
我认为您应该从导出的API函数的原始文件(exe,dll)中读取并与加载内存中的数据进行比较。为了避免读取 API 函数也被挂钩的假结果,您应该使用一些技巧从内存中获取原始读取 API 函数。
希望这有帮助!