地址空间布局随机化(ASLR)是否会对动态链接库(DLL)注入中的地址造成干扰?

3
我正在阅读有关DLL注入技术的文章,并且我有一个问题。
假设我们想要将DLL注入到Windows 7中启用了kernel32.dll ASLR的目标进程中。
因此,注入代码的任何部分都不能使用任何winapi或任何系统调用,因为注入器代码中的loadLibrary函数的地址与目标进程中的loadLibrary地址不同,是吗?
因此,对于CreateRemoteThread的这样的调用将无法正常工作:
CreateRemoteThread(hProcess,
                   NULL,
                   0,
                   (LPTHREAD_START_ROUTINE) ::GetProcAddress(hKernel32,
                                                             "LoadLibraryA" ),
                   pLibRemote,
                   0,
                   NULL );

::WaitForSingleObject( hThread, INFINITE );

如果我推理有误,请纠正我。

2个回答

8
没有,我认为那是错误的。像kernel32.dll这样的模块地址在机器启动时会随机化,但对于所有进程来说都是相同的。

这是否意味着像kernel32.dll这样的模块只会被加载一次?当可执行文件被加载并且在其导入表中有它时,它只是获取指向已加载的dll的指针?那么你能否解释一下这个链接中的“ASLR和LoadLibrary”部分http://www.insecure.in/papers/vista_dll_injection.pdf,为什么GetModuleHandle位于相同地址而LoadLibraryA不是? - CnativeFreak
我们使用 GetModuleHandle 函数来检索 LoadLibraryA 函数的地址,该地址在远程线程的地址空间中与之前相同。为什么 GetModuleHandle 函数在远程线程的地址空间中保持相同而 LoadLibraryA 函数不同呢? - CnativeFreak
@CnativeFreak,它们是一样的。它只是说明了这是如何完成的,并且 kernel32.dll 导出的任何函数的地址都不能被硬编码。 - hmjd
GetModuleHandle也被从kernel32导出,为什么它可以硬编码而LoadLibraryA不能呢?我不明白为什么他可以直接使用GetModuleHandle,却不能直接使用LoadLibraryA。 - CnativeFreak
1
模块的地址可能不会改变,但这并不意味着 OP 所做的是安全的!考虑一下你的应用程序在启用 shims 的情况下运行(这是你无法控制的事情!)或者甚至其他一些软件也在你的进程中执行 EAT 钩子(同样,这也是你无法控制的)。在这种情况下,GetProcAddress 可能会返回一个指向另一个模块中的函数的指针,而不是你期望/请求的函数,包括一个未加载到你要调用 CreateRemoteThread 的进程中的函数,在这种情况下,目标将崩溃。 - RaptorFactor
显示剩余2条评论

-3

他可以直接从注入器的导入表中使用GetModuleHandle(和GetProcAddress),它将重定向到对KERNEL32上的GetModuleHandle的调用,以获取KERNEL32上LoadLibraryA的地址,该地址可在任何进程中使用

如果他直接传递硬编码的LoadLibraryA地址,则会传递注入器导入表上LoadLibraryA的地址,而该地址与目标进程上的不同

有人可能会问:“为什么不翻译导入表,而是调用GetModuleHandle和GetProcAddress?”导入表只是一个指针表,由可执行文件加载程序使用相同的GetModuleHandle和GetProcAddress(实际上不同,但类似)获得


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接