我最近在C ++中编写了一个DLL-Injector,其要求如下
我很快注意到,Injector中 GetProcAddress(“LoadLibraryA”)的调用返回一个“不可用”句柄,因为32位目标已加载另一个kernel32.dll并且地址函数有不同,因此注入失败(远程线程无法使用返回的地址/句柄启动)。此外,32位进程将kernel32.dll加载到不同的基址,这使得创建远程线程更加不可能。
为了说清楚我的意思,会发生以下情况:
当从64位进程注入64位进程,从32位注入32位时,通常没有问题,因为kernel32.dll(很可能)在相同的基址加载,并且相同的函数地址可以使用 - 这是我到目前为止的解释。在这种情况下,条件不同。
为了克服这个问题,我做了以下步骤:
这种方法实际上运行得很好,但我无法摆脱这是总开销的想法,并且必须有一个更简单的解决方案来从64位注入器注入32位目标。
我有两个问题,如果可以在这里回答,我将非常感激:
非常感谢任何答案,谢谢!
编辑:哦,我的天啊......我刚刚意识到,我在最初的帖子中描述了错误的情况。 INJECTOR是64位,TARGET是32位(最初是另一种方式,但我已经纠正了它)。 Ben Voigt在下面的评论完全正确,对EnumProcessModulesEx的调用将失败。这个混乱让人感到非常抱歉:(答案 0 :(得分:5)
我偶然发现这个线程正在寻找同样问题的解决方案。
到目前为止,我倾向于使用另一种更简单的解决方案。要获得32位内核proc地址,64位进程只需执行一个32位程序,它将为我们查找proc地址:
#include <Windows.h>
int main(int argc, const char**)
{
if(argc > 1)
return (int) LoadLibraryA;
else
return (int) GetProcAddress;
}
答案 1 :(得分:0)
这个答案解决了问题的早期版本,它与64位注入器的情况大多无关。
你是说这种方法有效吗?因为根据the documentation,您无法从WOW64获取有关64位进程的信息:
如果在WOW64下运行的32位应用程序调用该函数,则忽略dwFilterFlag选项,该函数提供与EnumProcessModules函数相同的结果。
(EnumProcessModules
进一步解释了限制)
如果从WOW64上运行的32位应用程序调用此函数,则它只能枚举32位进程的模块。如果进程是64位进程,则此函数失败,最后一个错误代码为ERROR_PARTIAL_COPY(299)。
但由于ASLR,您确实需要找到加载kernel32.dll
的基地址。
答案 2 :(得分:0)
我认为您可以使用调试符号API来保存自己解析PE头和导出表。该路由应该产生32位注入器所需的信息;虽然我仍然不知道如何将64位地址传递给CreateRemoteThread
,但64位目标情况也是如此。
通常这些调试符号函数需要一个.pdb或.sym文件才能运行,但是我很确定它们也从DLL导出表中获取信息(只是从调试器显示的文件中获取的信息) t有符号)。