Win32 API 挂钩/导入地址表

Win32 API hooking/Import address table

提问人:Pieter Jansen 提问时间:11/6/2023 最后编辑:Brian Tompsett - 汤莱恩Pieter Jansen 更新时间:11/6/2023 访问量:76

问:

任何人都可以阅读这篇文章并纠正我的错误/回答我的问题吗?这是我到目前为止的理解:

当可执行文件加载到内存中时,编译时已知的导入将加载到内存中。指向这些函数的指针存储在导入地址表中,当进程想要调用函数时,它必须从导入地址表中检索指针(我了解 IAT、INT、H/N 表等之间的关系)。

当函数在运行时加载并且动态链接器检索指针时;因此,例如,当进程调用 MessageBoxA 时,操作系统加载程序会在内存中加载 DLL Kernel32 并返回指向此特定函数的指针。到目前为止,这部分是正确的吗?LoadLibraryGetProcAddress()

  • 据我所知,操作系统根据定义加载的第一个库是 ntdll.dll,第二个是更抽象的包装器 Kernel32.dll。我想知道什么..当进程在运行时调用 MessageBoxA 或 CreateFileA 时,DLL 不需要加载到内存中吧?因为这些函数是已经加载的库的一部分,即 Kernel32。

  • 动态链接器是否将指向动态加载函数的指针存储在某种缓存中,或者..?据我所知,它没有更新导入地址表,那么当进程再次调用函数时会发生什么,是需要再次调用解析虚拟地址还是有更有效的方法?GetProcAddress

  • 当我想钩接动态加载的函数时,我是否需要在运行时钩接并使用跳转指令将返回指针更改为我的填充函数(并存储原始函数指针以调用原始函数/之后使用原始参数)。GetProcAddress

Windows WinAPI DLL

评论


答:

0赞 500 - Internal Server Error 11/6/2023 #1

当进程想要调用函数时,它必须从导入地址表中检索指针

检索听起来有点麻烦,但是的:对导入函数的调用被编译为对 IAT 的调用,其中有一个 JMP [地址] 指令,在加载库时,该指令会使用实际的函数地址进行修补。

当在运行时使用 LoadLibrary 和 GetProcAddress() 加载函数时,动态链接器将检索指针;因此,例如,当进程调用 MessageBoxA 时,操作系统加载程序会在内存中加载 DLL Kernel32 并返回指向此特定函数的指针。

LoadLibrary将 DLL 加载到内存中。 返回指向特定导出函数的指针。不是上面那样的存根,而是模块中实际函数的地址。GetProcAddress

当进程在运行时调用 MessageBoxA 或 CreateFileA 时,DLL 不需要加载到内存中吧?

MessageBoxA实际上驻留在 user32.dll 中,但对于 CreateFileA,您是正确的,kernel32.dll 已经加载。

动态链接器是否将指向动态加载函数的指针存储在某种缓存中,或者..?

加载的模块的地址记录在内核对象中。据我所知,单个函数的地址没有被缓存。

据我所知,它不会更新import addres表,那么当进程再次调用函数时会发生什么,是否需要再次调用GetProcAddress来解析虚拟地址,或者有没有更有效的方法?

通常,如果您需要多次使用变量,您会将返回的内容存储在变量中。GetProcAddress

当我想钩接动态加载的函数时,我是否需要在运行时钩接GetProcAddress,并使用跳转指令更改返回指针到我的钩子函数(并存储原始函数指针以调用原始函数/之后使用原始参数)。

是的,没错。

评论

0赞 Pieter Jansen 11/6/2023
非常感谢您的快速回复。关于我的最后一个问题(也许我对此选项和内联钩子有点混淆),因为在 x86 中,我们必须将前 n(通常为 5)个字节替换为相对 jmp 来调用自定义函数;但是这如何改变 GetProcAddress 调用的返回指针。
0赞 500 - Internal Server Error 11/6/2023
如果按照建议的方式修补模块的所有导出函数,则无需挂钩 .相反,如果所有函数都加载了 ,而不是通过导入表条目加载,则无需进行修补,而只需将自定义函数指针从钩子返回给调用方即可。这能回答你的担忧吗?GetProcAddressGetProcAddressGetProcAddress
0赞 Pieter Jansen 11/20/2023
先生,还有一个问题;虽然我想挂钩 Win32 API 调用,但我只想针对特定进程监视它们。因此,进程 x 例如称为 CreateFileA 和 CreateFileW(带有时间戳)。我是否仍需要注入自定义 DLL?我知道有像 API 监视器或进程黑客这样的工具可以做到这一点,但我想自己编写它。我可以使用 Detours 或 Easyhook,但我很好奇是否需要 DLL 注入。谢谢。
0赞 500 - Internal Server Error 11/21/2023
我不知道IAT挂钩(使用注入的dll)是否是唯一的方法,但这是一种方法 - 如果我需要它,我会这样做。
0赞 Pieter Jansen 11/21/2023
好的,谢谢你,我的最后一个问题,我保证:)我读了陈先生的一篇文章,内容是关于IAT几年来一直无法写入。您知道更多有关这方面的信息吗?我在网上看了很多,但没有人真正提到它,但最近的一些教程确实钩住了 IAT,这意味着它仍然是可能的。devblogs.microsoft.com/oldnewthing/20221006-07/?p=107257