首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C++:从64位进程注入32位目标

C++:从64位进程注入32位目标
EN

Stack Overflow用户
提问于 2012-01-08 09:03:04
回答 3查看 8.5K关注 0票数 6

我最近用C++编写了一个DLL-注入器,其要求如下

  • 注入过程(我们称之为‘注入器’)以及要注入的DLL (注入)都存在于64位和32位变体中。根据目标,将尝试注入匹配版本的注入。
  • 必须能够注入32位(WOW64)的目标进程,即使注入器在64位中运行

我很快注意到,Injector中的GetProcAddress("LoadLibraryA")调用返回一个“不可用”句柄,因为32位目标有另一个内核32.dll加载,并且函数的地址不同,因此注入失败(不能使用返回的地址/句柄启动远程线程)。此外,32位进程将内核32.dll加载到不同的基址,这使得创建远程线程变得更加不可能。

为了明确我的意思,会发生以下情况:

  • 注入器有64位版本的kernel32.dll加载在0x12340000
  • 从这个内核检索LoadLibraryA 0x00005678的注射器句柄
  • 在0xABCD 0000加载了32位版本的kernel32.dll
  • 这个内核的LoadLibrary的句柄为0x0000EFAB。
  • 注入器尝试使用函数0x12345678在目标中启动远程线程,但希望使用0xABCDEFAB。

当从64位进程注入64位进程,从32位注入32位进程时,通常没有问题,因为内核32.dll(很可能)加载在相同的基址上,并且可以使用相同的函数地址--到目前为止,这就是我的错误所在。然而,在这种情况下,情况不同。

为了克服这个问题,我执行了以下步骤:

  • 64位注入器使用EnumProcessModulesEx()检索32位目标加载的内核32.dll的地址(应该是0xABCD 000)
  • 获取该kernel32.dll,的文件名,解析PE头并获取LoadLibraryA的RVA (应该是0x000EFAB)
  • 此时,我们知道在32位目标中加载kernel32.dll的位置以及该DLL函数的地址。
  • 64位注入器使用ImageBase +函数RVA在32位目标中启动远程线程,在本例中是神奇的0xABCDEFAB

这种方法实际上运行得很好,但我无法摆脱这样的想法:这是总开销,必须有一个更简单的解决方案,从64位注入器中注入32位目标。

我有两个问题,如果能在这里得到答复,我将非常感激:

  1. 有更简单的方法来实现这种注射吗?
  2. 我一直在考虑的方法是否可能有问题?

任何答案都是非常感谢的,谢谢!

编辑:哦,天哪.我刚刚意识到,我在最初的帖子中描述了错误的情况。注入器是64位,目标是32位(最初是相反的,但我已经更正了)。Ben在下面的评论是完全正确的,对EnumProcessModulesEx的调用将失败。一个大的,大的,抱歉的,对这种混乱:

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-01-08 15:24:23

我认为您可以使用调试符号API来保存自己,解析PE头和导出表。这个路由应该为32位注入器提供所需的信息;64位目标情况也是如此,尽管我仍然不知道您将如何将64位地址传递给CreateRemoteThread

  • EnumerateLoadedModules64
  • SymFromName
  • ImageRvaToVa

通常,这些调试符号函数需要一个.pdb或.sym文件来操作,但是我确信它们也会从DLL导出表中获得信息(只是从调试器对没有符号的文件显示的经验来看)。

票数 0
EN

Stack Overflow用户

发布于 2012-10-30 04:12:28

我无意中发现了这条线索,正在寻找解决同样问题的方法。

到目前为止,我倾向于使用另一个更简单的解决方案。要获得32位内核proc地址,64位进程只需执行一个32位程序,该程序将为我们查找proc地址:

代码语言:javascript
运行
复制
#include <Windows.h>

int main(int argc, const char**)
{
    if(argc > 1)
        return (int) LoadLibraryA;
    else
        return (int) GetProcAddress;
}
票数 6
EN

Stack Overflow用户

发布于 2012-01-08 09:39:20

这个答案解决了这个问题的早期版本,它基本上与64位注入器的情况无关。

你是说这种方法有效吗?因为根据文献资料,您无法从WOW64获得有关64位进程的信息:

如果在WOW64下运行的32位应用程序调用该函数,则忽略dwFilterFlag选项,该函数提供与EnumProcessModules函数相同的结果。

(EnumProcessModules进一步解释了这一限制)

如果该函数是从运行在WOW64上的32位应用程序调用的,它只能枚举32位进程的模块。如果进程是64位进程,则此函数将失败,最后一个错误代码是ERROR_PARTIAL_COPY (299)。

但是,由于kernel32.dll的存在,您确实需要找到加载ASLR的基地址。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8776437

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档