繁体   English   中英

来自内存缓冲区的 CreateProcess

[英]CreateProcess from memory buffer

我可以使用 CreateProcess 来启动一个 EXE。 我想在内存缓冲区中拥有 EXE 的内容并对其执行 CreateProcess(或等效项),而不必将其写入文件。 有没有办法做到这一点?

背景故事:我们制作游戏。 我们将一个普通的 EXE 发送给我们的分销商,然后他们使用他们最喜欢的 DRM 对其进行包装并将其出售给他们的用户。 曾有用户发现崩溃的情况。 大多数崩溃需要 5 分钟才能修复,但补丁必须通过分销商,并且可能需要几天甚至几周的时间。 我不能只将修补的 EXE 发送给播放器,因为它没有发行商的 DRM。 我正在考虑将真正的游戏 EXE 分发到加密的数据文件中,这样被包装的(外部 EXE)只是解密并启动真正的 EXE。 这样我就可以在不禁用 DRM 的情况下安全地分发修复程序。

这实际上很容易。 我在 3 年前读过的一篇论文中描述了类似的技术。

Windows 允许您使用CREATE_SUSPENDED标志调用CreateProcess函数,该标志告诉 API 在调用 ResumeThread函数之前保持进程挂起。

这让我们有时间使用GetThreadContext函数来获取挂起线程的上下文,然后 EBX 寄存器将保存指向PBE(Process Enviroment Block)结构的指针,我们需要确定基地址。

从 PBE 结构的布局中我们可以看到 ImageBaseAddress 存储在第 8 个字节,因此 [EBX+8] 将为我们提供被挂起进程的实际基地址。

现在我们需要内存中的 EXE,如果内存和内存中的 EXE 的对齐方式不同,请进行适当的对齐。

如果挂起的进程和内存中的exe的基地址匹配,加上如果内存中的exe的imageSize小于或等于挂起的进程'我们可以简单地使用WriteProcessMemory将内存中的exe写入内存空间暂停的过程。

但如果不满足上述条件,我们需要更多的魔法。 首先,我们需要使用ZwUnmapViewOfSection取消映射原始图像,然后在挂起进程的内存空间内使用VirtualAllocEx分配足够的内存。 现在我们需要使用WriteProcessMemory函数将内存中的 exe 写入挂起进程的内存空间。

接下来,将内存中 exe 的 BaseAddress 修补到挂起进程的 PEB->ImageBaseAddress 中。

线程上下文的EAX寄存器保存EntryPoint地址,我们需要用内存中exe的EntryPoint地址重写。 现在我们需要使用SetThreadContext函数保存更改后的线程上下文。

瞧! 我们准备在挂起的进程上调用ResumeThread函数来执行它!

您可以将游戏编译为 DLL,并将 DLL 放入加密的数据文件中。 可以从内存中加载 DLL 而无需将其写入磁盘。 请参阅本教程(最后附有示例代码): Loading a DLL From Memory

你想做的事情需要 NtCreateProcess,但它没有记录,因此很脆弱。 这本书显然涵盖了它的使用。

也许你可以建立一个补丁系统? 例如,在启动时,程序会检查同一目录中的补丁 DLL,如果存在则加载它。

为什么需要创建新流程? 我原以为您可以在进行解包/解密的进程的上下文中运行。

你想要的东西可以用一个叫做“Packer”的东西来实现。 实际上从内存中启动 exe 可能是可能的,但它比打包程序要困难得多;)

最著名的打包程序之一是 UPX(google it)。 有一些工具可以解密它,但它至少应该给你一个开始工作的起点。 我也相当肯定 UPX 是开源的。

看看BoxedAppSDK

它支持从内存缓冲区启动 exe。

希望能帮助到你。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM