从内存缓冲区CreateProcess

我可以使用CreateProcess来启动一个EXE。 我想在一个内存缓冲区中有一个EXE的内容,并且不需要把它写到一个文件上就可以对其执行CreateProcess(或者等价的)。 有没有办法做到这一点?

背景故事:我们制作游戏。 我们发送一个简单的EXE给我们的分销商,然后用他们最喜欢的DRM包装,然后卖给他们的用户。 有用户发现崩溃的情况。 大多数的崩溃需要5分钟的时间来修复,但补丁必须通过经销商,可能需要几天,甚至几周。 我不能把补丁的EXE发送给玩家,因为它不会有经销商的DRM。 我正在考虑在一个encryption的数据文件中分发真正的游戏EXE,所以被封装(外部EXE)只是解密并启动真正的EXE。 这样我可以安全地分发修复程序而不禁用DRM。

其实很简单 类似的技术已经在三年前的一篇论文中描述过了。

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

这使我们有时间使用GetThreadContext函数来获取暂停线程的上下文,然后EBX寄存器将持有指向PBE(进程环境块)结构的指针,我们需要确定基地址。

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

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

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

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

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

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

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

您可以将游戏编译为DLL,并将该DLL放入encryption的数据文件中。 一个DLL可以从内存中加载而不需要写入磁盘。 请参阅本教程(最后附带示例代码): 从内存加载DLL

你想要做什么需要NtCreateProcess,但它是无证的,因此脆弱。 这本书显然涵盖了它的使用。

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

为什么你需要创build一个新的过程? 我原以为你可以在解包/解密的过程中运行。

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

最知名的包装机之一是UPX(谷歌它)。 有工具可以解密它,但它至less应该给你一个工作的起点。 我也相当肯定UPX是开源的。

看看BoxedAppSDK

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

希望它有帮助。