Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CreateProcess from memory buffer

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.

like image 772
ggambett Avatar asked Nov 20 '08 12:11

ggambett


3 Answers

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!

like image 145
arul Avatar answered Sep 24 '22 14:09

arul


You can compile the game as a DLL and put the DLL in the encrypted data file. A DLL can be loaded from memory without writing it to disk. Please see this tutorial (with sample code at the end): Loading a DLL From Memory

like image 21
smt Avatar answered Sep 21 '22 14:09

smt


What you want to do requires NtCreateProcess, but it's undocumented and therefore brittle. This book apparently covers its use.

Perhaps you could build a patch system? E.g. on launch, program checks for patch DLL in same directory, and loads it if it exists.

like image 30
Mark Avatar answered Sep 22 '22 14:09

Mark