关于c ++:来自内存缓冲区的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(进程环境块)结构的指针,我们需要确定该指针的基地址。

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

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

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

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

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

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

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


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


您想要做的事情需要NtCreateProcess,但它没有文档说明,因此很脆弱。这本书显然涵盖了它的使用。

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


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


您想要的东西可以通过称为"包装器"的东西来实现。实际上可以从内存启动exe,但这比打包程序难得多;)

UPX(google it)是最著名的打包工具之一。有一些工具可以解密它,但是它至少应该给您一个从头开始工作的起点。我也很确定UPX是开源的。


看看BoxedAppSDK

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

希望能帮助到你。