CreateProcess从内存缓冲区 [英] CreateProcess from memory buffer

查看:260
本文介绍了CreateProcess从内存缓冲区的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以使用CreateProcess启动EXE。我想有一个EXE的内容在内存缓冲区,并做CreateProcess(或等效的),而不必将它写入一个文件。有什么办法吗?



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

解决方案

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



Windows允许你调用 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的BaseAddress修补到挂起进程的PEB-> ImageBaseAddress。



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

Voila!我们已准备好调用 ResumeThread 函数暂停进程执行它!


I can use CreateProcess to launch an EXE. I want to have the contents of an EXE in a memory buffer and do CreateProcess (or an equivalent) on it without having to write it to a file. Is there any way to do that?

The backstory : we make games. We send a plain EXE to our distributors, which then wrap it using their favorite DRM and sell it to their users. There have been instances where users find crashes. Most of the crashes take 5 minutes to fix, but the patch must go through the distributor and it may take several days, even weeks. I can't just send the patched EXE to the players because it wouldn't have the distributor's DRM. I'm thinking of distributing the real game EXE inside an encrypted datafile so what gets wrapped (the external EXE) just decrypts and launches the real EXE. This way I could safely distribute a fix without disabling the DRM.

解决方案

It's actually quite easy. Similar technique has been described in a paper I read like 3 years ago.

Windows allow you to call the CreateProcess function with CREATE_SUSPENDED flag, that tells the API to keep the process suspended until the ResumeThread function is called.

This gives us time to grab the suspended thread's context using GetThreadContext function, then the EBX register will hold a pointer to the PBE(Process Enviroment Block) structure, which we need to determine the base address.

From the layout of the PBE structure we can see that the ImageBaseAddress is stored at the 8th byte, therefore [EBX+8] will give us actual base address of the process being suspended.

Now we need the in-memory EXE and do appropiate alignment if the alignment of memory and in-memory EXE differs.

If the base address of suspended process and in-memory exe matches, plus if the imageSize of the in-memory exe is lesser or equal to the suspended process' we can simply use WriteProcessMemory to write in-memory exe into the memory space of the suspended process.

But if the aforementioned conditions weren't met, we need a little more magic. First, we need to unmap the original image using ZwUnmapViewOfSection, and then allocate enough memory using VirtualAllocEx within the memory space of the suspended process. Now we need to write the in-memory exe into the memory space of the suspended process using the WriteProcessMemory function.

Next, patch the BaseAddress of the in-memory exe into the PEB->ImageBaseAddress of the suspended process.

EAX register of the thread context holds EntryPoint address, which we need to rewrite with the EntryPoint address of the in-memory exe. Now we need to save the altered thread context using the SetThreadContext function.

Voila! We're ready to call the ResumeThread function on the suspended process to execute it!

这篇关于CreateProcess从内存缓冲区的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆