我做了一个简单的 SSDT Hooks 检测器,它遍历所有条目并检查内核模块之外是否有任何地址。如果是这样,我什至可以返回并使用syscall找出应该存在的功能。我想此时我也可以尝试解开钩子,但我还没有尝试过。
我ZwQuerySystemInformation用来获取模块列表,我总是假设第一个模块是内核。这种方法有多安全?内核模块有没有可能不是第一个?我可以按名称搜索,但它并不总是相同的,所以我试图避免这种情况;我可以让它搜索内核模块可能具有的名称之一。我还需要该列表以查看挂钩来自哪个模块。有没有办法可以在没有的情况下获取已加载模块的列表ZwQuerySystemInformation?如果它被钩住了,它可以对我隐藏信息。
关于内联钩子,现在我遍历内核模块的所有导出并检查每个函数的代码以查看它是否以相对跳转或推送偏移量和 ret 开头。我还应该检查跳转 / ret 的地址是在内核模块之外还是多余的?如果我不检查跳转地址,我会得到一个误报(我认为)KePollFreezeExecution在内核模块内跳转。unt!KePollFreezeExecution在 WinDbg 中给出以下输出
jmp nt!KeIpiGenericCall+0x132
int 3
看起来还可以。
我知道这并不完美(有人可以将钩子放在函数代码中的任何位置,或者可能在内核模块中找到一个地方放置他的函数等等),但我这样做只是为了了解所有这些作品。
另外,我知道在 x64 上这种方法实现起来不会那么简单,但目前我正在尝试 x86。
更多的是“我应该如何处理这个”问题而不是“我应该如何编码”。