我最近写了一个内核驱动程序,它做了很多事情,但我想为某个驱动程序添加一个 IAT 钩子。
如果有意义的话,我想从我的驱动程序中挂钩另一个驱动程序的 IAT。
所以我了解您的典型 IAT 挂钩是通过 DLL 注入完成的,因此您与所述模块位于相同的地址空间内。
我遇到的主要问题是有人可以举一个 IAT 通过内核驱动程序挂接内核驱动程序的例子吗?我想不通。
我一直在使用多个通过 dll 注入进行常规 IAT 挂钩的示例,但将其应用于内核驱动程序。
预期结果: Driver1.sys(执行IAT 挂钩)解析Driver2.sys 的导入表,并用位于Driver1.sys 中的函数(即完成IAT 挂钩)替换函数“DbgPrintEx”导入。
这是我写/引用的内容:
NTSTATUS _HOOKS_::HookFn(PVOID ModuleBase, const char* FunctionName, uintptr_t HookFunc, uintptr_t* OrigFunc) {
IMAGE_DOS_HEADER DosHeader{ 0 };
memcpy(&DosHeader, ModuleBase, sizeof(IMAGE_DOS_HEADER));
IMAGE_NT_HEADERS NtHeaders{ 0 };
memcpy(&NtHeaders, (PVOID)((uintptr_t)ModuleBase + DosHeader.e_lfanew), sizeof(IMAGE_NT_HEADERS));
IMAGE_IMPORT_DESCRIPTOR ImportDescriptor{ 0 };
IMAGE_DATA_DIRECTORY ImportsDirectory = NtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
memcpy(&ImportDescriptor, (PVOID)((uintptr_t)ModuleBase + ImportsDirectory.VirtualAddress), sizeof(ImportDescriptor));
LPCSTR LibraryName = NULL;
PVOID Library = NULL;
IMAGE_IMPORT_BY_NAME FunctionNamee{ 0 };
while (ImportDescriptor.Name != NULL) {
memcpy(&LibraryName, &ImportDescriptor.Name + (uintptr_t)ModuleBase, sizeof(LibraryName));
IMAGE_THUNK_DATA OriginalFirstThunk{ 0 }, firstThunk{ 0 };
memcpy(&OriginalFirstThunk, (PVOID)(ImportDescriptor.OriginalFirstThunk + (uintptr_t)ModuleBase), sizeof(IMAGE_THUNK_DATA));
memcpy(&firstThunk, (PVOID)(ImportDescriptor.FirstThunk + (uintptr_t)ModuleBase), sizeof(IMAGE_THUNK_DATA));
while (OriginalFirstThunk.u1.AddressOfData != NULL) {
memcpy(&FunctionNamee, (PVOID)(OriginalFirstThunk.u1.AddressOfData + (uintptr_t)ModuleBase), sizeof(IMAGE_IMPORT_BY_NAME));
Log::Debug("First function name -> %s\n", FunctionNamee);
if (!strcmp(FunctionNamee.Name, FunctionName)) {
Log::Debug("FOUND FUNCTION!!! Address -> %p\n", firstThunk.u1.Function);
}
}
}
return STATUS_SUCCESS;
此代码 BSOD 位于: memcpy(&ImportDescriptor, (PVOID)((uintptr_t)ModuleBase + ImportsDirectory.VirtualAddress), sizeof(ImportDescriptor));
如果我错了,请纠正我,但由于内核驱动程序共享相同的地址空间,我可以简单地使用 memcpy 或 RtlCopyMemory 来获取此挂钩所需的结构,是否有人有任何参考资料或某种我可以阅读的文档?
提前感谢大家!
额外信息:
- 视窗 10
- 使用 VMWare 进行测试
- 我正在我自己的驱动程序上测试钩子
编辑:发布了导致蓝屏死机的错误源代码行。
通过 WinDbg(x64) 进行调试时,驱动程序会正确地将所有地址与内存视图进行比较。除了ImportDescriptor
获得 0x6000 的 RVA,在检查ModuleBase + 0x6000
RVA 时它显示该内存区域无效,所以我认为 0x6000 RVA 不正确,我不知道为什么
错误检查代码:
- 蓝屏错误代码:PAGE_FAULT_IN_NONPAGED_AREA
- BUG校验码:50