2008-11-20 115 views
33

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

背景故事:我们制作游戏。我们向我们的经销商发送简单的EXE,然后使用他们最喜爱的DRM将其包装出售给用户。有用户发现崩溃的情况。大部分崩溃需要5分钟才能修复,但修补程序必须通过经销商,可能需要几天甚至几周。我不能只将修补程序EXE发送给玩家,因为它不会有分发者的DRM。我正在考虑将真实的游戏EXE分发到加密的数据文件中,这样封装的东西(外部EXE)就解密并启动真正的EXE。通过这种方式,我可以安全地分发修复程序而不禁用DRM。

回答

2

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

+0

我绝对可以做到这一点。我提到了CreateProcess,因为这是我最好的选择,但是你说什么都可以。 – ggambett 2008-11-20 13:21:27

1

你想要的东西可以通过称为“Packer”的东西来实现。实际上从内存中启动一个EXE可能是可能的,但它比一个打包机要困难得多;)

其中一个最着名的包装是UPX(谷歌它)。有工具可以解密它,但它至少应该给你一个工作的起点。我也很确定UPX是开源的。

+0

我之前使用过UPX,但这次我没有想到它。可能值得探索。谢谢! – ggambett 2008-11-20 13:22:39

+0

这是一个非常古老的线程;但只是为了确切,虽然UPX确实是开源的,但它的许可明确禁止将其用于加密/混淆目的。 – Ale 2014-03-25 12:29:46

3

你想要做什么需要NtCreateProcess,但它没有记录,因此很脆弱。 This book显然涵盖了它的使用。

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

11

您可以将游戏编译为DLL并将该DLL放入加密的数据文件中。 DLL可以从内存中加载而不需要写入磁盘。请参阅本教程(示例代码结尾处):Loading a DLL From Memory

+0

也http://stackoverflow.com/questions/638277/loading-dll-from-a-location-in-memory – Suma 2010-08-19 11:58:38

40

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

窗口允许您致电CreateProcess功能与CREATE_SUSPENDED标志,告诉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到挂起的进程的PEB-> ImageBaseAddress的BaseAddress。线程上下文的

EAX寄存器存放入口点的地址,这是我们需要在内存中的exe文件的入口点地址重写。现在我们需要使用SetThreadContext函数来保存修改的线程上下文。

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

+0

查看是否EXE有明显这是行不通的。哦,它装载正确,但不好的事情可能发生。 – Joshua 2011-12-13 21:58:57

0

BoxedAppSDK

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

希望它帮助。