CreateProcess из буфера памяти

Я могу использовать CreateProcess для запуска EXE. Я хочу иметь содержимое EXE в буфере памяти и делать CreateProcess (или эквивалент) на нем, не записывая его в файл. Есть ли способ сделать это?

Предыстория: мы делаем игры. Мы отправляем простой EXE нашим дистрибьюторам, которые затем переносят их с помощью своего любимого DRM и продают его своим пользователям. Были случаи, когда пользователи находят сбои. Большинство аварий приходится на 5 минут, но исправление должно пройти через дистрибьютора, и это может занять несколько дней, даже недель. Я не могу просто отправить исправленный EXE игрокам, потому что у него не было бы DRM дистрибьютора. Я думаю о распространении реальной игры EXE в зашифрованном файле данных, так что то, что обернуто (внешний EXE), просто расшифровывает и запускает реальный EXE. Таким образом, я мог бы безопасно распространять исправление без отключения DRM.

Ответ 1

На самом деле это довольно просто. Подобная техника была описана в документе, который я читал, как 3 года назад.

Windows позволяет вам вызвать функцию CreateProcess с флагом CREATE_SUSPENDED, который сообщает API о приостановлении процесса пока не вызывается функция ResumeThread.

Это дает нам время, чтобы захватить приостановленный контекст потока, используя функцию GetThreadContext, тогда регистр EBX будет содержать указатель на структура PBE (Process Enviroment Block), которую мы должны определить для базового адреса.

Из компоновки структуры PBE видно, что ImageBaseAddress сохраняется на 8-м байте, поэтому [EBX + 8] предоставит нам фактический базовый адрес приостановленного процесса.

Теперь нам нужен EXE в памяти и выполнить выравнивание, если выравнивание памяти и EXE в памяти отличается.

Если базовый адрес приостановленного процесса и exe-памяти в памяти совпадает, плюс, если imageSize для exe файла в памяти меньше или равно приостановленному процессу, мы можем просто использовать WriteProcessMemory для записи in-memory exe в пространство памяти приостановленного процесса.

Но если вышеупомянутые условия не были выполнены, нам нужно немного больше магии. Во-первых, нам нужно отформатировать исходное изображение с помощью ZwUnmapViewOfSection, а затем выделить достаточное количество памяти, используя VirtualAllocEx в пространстве памяти приостановленного процесса. Теперь нам нужно записать exe in-memory в пространство памяти приостановленного процесса, используя функцию ResumeThread в приостановленном процессе для ее выполнения!

Ответ 2

Вы можете скомпилировать игру как DLL и поместить DLL в зашифрованный файл данных. DLL может быть загружена из памяти, не записывая ее на диск. См. Этот учебник (с примерным кодом в конце): Загрузка DLL из памяти

Ответ 3

То, что вы хотите сделать, требует NtCreateProcess, но оно недокументировано и, следовательно, хрупкое. Эта книга, по-видимому, охватывает ее использование.

Возможно, вы могли бы создать систему патчей? Например. при запуске программа проверяет DLL файл патча в том же каталоге и загружает его, если он существует.

Ответ 4

Зачем вам нужен новый процесс? Я бы подумал, что вы можете работать в контексте процесса, который выполняет распаковку/дешифрование.

Ответ 5

То, что вы хотите, может быть достигнуто с помощью так называемого "упаковщика". Фактически запуск exe из памяти может быть возможен, но это намного сложнее, чем пакер;)

Один из самых известных упаковщиков - UPX (google it). Есть инструменты для его расшифровки, но это должно по крайней мере дать вам отправную точку для работы. Я также довольно уверен, что UPX является открытым исходным кодом.

Ответ 6

Посмотрите BoxedAppSDK

Он поддерживает запуск exe из буфера памяти.

надеюсь, что это поможет.