我可以使用CreateProcess来启动EXE。我希望在内存缓冲区中包含EXE的内容,并在其上执行CreateProcess(或等效),而不必将其写入文件。有没有办法做到这一点?
背景故事:我们制作游戏。我们向经销商发送一个简单的EXE,然后使用他们喜欢的DRM将其包装并出售给他们的用户。曾经有过用户发现崩溃的情况。大多数崩溃需要5分钟才能解决,但补丁必须经过分销商,可能需要几天甚至几周。我不能将修补后的EXE发送给玩家,因为它没有经销商的DRM。我正在考虑在加密的数据文件中分发真实的游戏EXE,以便包装(外部EXE)只是解密并启动真正的EXE。通过这种方式,我可以在不禁用DRM的情况下安全地分发修复程序。
答案 0 :(得分:42)
实际上很容易。我在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函数来执行它!
答案 1 :(得分:11)
您可以将游戏编译为DLL并将DLL放入加密数据文件中。可以从内存加载DLL而无需将其写入磁盘。请参阅本教程(最后的示例代码):Loading a DLL From Memory
答案 2 :(得分:3)
你想要做什么需要NtCreateProcess,但它没有文档,因此很脆弱。 This book显然涵盖了它的使用。
也许你可以建立一个补丁系统?例如。在启动时,程序检查同一目录中的补丁DLL,如果存在,则加载它。
答案 3 :(得分:2)
为什么需要创建新流程?我本以为你可以在进行解包/解密的过程中运行。
答案 4 :(得分:1)
你想要的东西可以通过一种叫做“包装工”的东西来实现。实际上从内存中启动exe可能是可能的,但它比打包器要难得多;)
最知名的包装商之一是UPX(google it)。有解密它的工具,但至少应该给你一个工作起点的起点。我也很确定UPX是开源的。
答案 5 :(得分:0)
它支持从内存缓冲区启动exe。
希望它有所帮助。