在另一个进程地址空间,调用dll中的函数,如何
好的,我将一个 dll 注入到目标进程地址空间中。如何返回目标进程正在使用的 dll 提供的函数列表,例如 user32.dll;然后假设 user32.dll 包含一个名为 (int test1(str 1, str 2)) 的函数(我知道它没有),并且我想调用该函数,我该怎么做?
谢谢。
Ok, so I have a dll injected into a target process address space. How do I return a list of the functions provided by a dll that the target process is using, lets say user32.dll; then lets say that user32.dll contains a function called (int test1(str 1, str 2)) (I know it doesn't) and I want to call that function, how would I do it?
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
你真的需要做你写的所有事情吗?通过 dll 获取导出函数的列表并不简单,在获取内存中的模块地址之后,您必须遍历 PE 格式的几个数据结构,这并不容易手动完成(尽管 DbgHelp 函数 自动化大多数操作的过程)。
另一方面,如果您只想检查 dll 是否已加载并调用其函数之一,那么工作就会变得很容易。
如果您不关心是否必须加载 dll,只需调用
LoadLibrary
并获取模块句柄;否则,请先调用GetModuleHandle
,如果已加载,它将为您提供模块的句柄;如果未加载,则为NULL
;如果您想继续,则在之后调用LoadLibrary
(LoadLibrary
会增加 dll 的引用计数,因此您可以确定 dll 不会同时被卸载)。然后,要检查您需要的过程是否存在并获取其地址,请使用
GetProcAddress
;请注意,通常 C 函数(如 Windows dll 导出的函数)仅通过其名称导出,而不是通过其签名(在 C 中不存在重载);如果要调用使用修饰名称导出的 C++ 过程,则必须指定修饰名称。GetProcAddress
将返回一个指针,您必须将其转换为具有正确函数签名的函数指针;现在你已经完成了,只需使用它来调用函数,不要忘记调用FreeLibrary
减少 dll 的引用计数器。请注意,所有这些事情都不能从注入函数的 DllMain 内部安全地完成;请参阅此处。
Do you really need to do all the stuff you wrote? Getting the list of exported functions by a dll is not trivial, after getting the module address in memory you have to walk several data structures of the PE format, which is not so easy to do manually (although the DbgHelp functions automate most of the process).
On the other hand, if you just want to check if a dll is loaded and call one of its function the work gets easy.
If you don't care if the dll has to be loaded, just call
LoadLibrary
and get the module handle; otherwise, call firstGetModuleHandle
, which will provide you a handle to the module if is loaded,NULL
if it's not, and, if you want to continue, after that callLoadLibrary
(LoadLibrary
increments the reference count of the dll, so you're sure the dll won't get unloaded in the meantime).Then, to check if the procedure you need is present and get its address, use
GetProcAddress
; notice that usually C functions like the ones exported by Windows dlls are exported just by their name, not by their signature (in C overloading doesn't exist); if you want to call C++ procedures exported with decorated names you have to specify the mangled name.GetProcAddress
will return you a pointer, that you'll have to cast to a function pointer with the correct signature of your function; now you're done, just use it to call the function and don't forget to callFreeLibrary
to decrement the reference counter to the dll.Notice that all this stuff cannot be done safely from the inside of the
DllMain
of your injected function; see here.第一种方法是使用 DependencyWalker。您将获得该进程中每个 dll 的所有导入。
当然,这种方法不会覆盖使用 LoadLibrary / GetProcAddress 的动态调用,但要覆盖它,您需要挂钩 LdrLoadDll / GetProcAddress 以获取附加的进程/dll 正在使用的确切函数。
这不是什么大问题,但需要一些时间。
The first approach is to use DependencyWalker. You will get all imports of each dll in the process.
Of course, this approach wouldn't cover dynamic calls with LoadLibrary / GetProcAddress but to cover it you'll need to hook LdrLoadDll / GetProcAddress to get the exact functions that the process / dlls attached are using.
It's not a big deal but it takes some time.