Как выполнить исполняемый файл, встроенный как ресурс

Действительно ли возможно выполнить EXE-файл, который включен в проект как ресурс? Я могу выбрать файл как массив байтов и выполнить его в памяти?

Я не хочу писать файл во временное местоположение и выполнять его там. Я ищу решение, где я могу выполнить его в памяти. (Это не блок.NET.)

12
задан dtb 1 February 2010 в 11:06
поделиться

3 ответа

Это вполне возможно - я сделал это сам - но это неудобно, и тем более из управляемого кода. Для него нет ни .NET API, ни собственного API, который можно было бы использовать с помощью PInvoke. Так что вам придется загружать вручную, что потребует некоторых знаний о формате файла PE (Portable Executable), который используется для таких модулей, как библиотеки DLL и EXE - http://msdn.microsoft.com/en- us / magazine / cc301805.aspx . Будет много манипуляций с указателями (требующих использования небезопасных блоков {}) и PInvoke.

Сначала загрузите PE-файл в память (или используйте MapViewOfFile). PE-файл внутри состоит из различных разделов, содержащих код, данные или ресурсы. Смещения каждого раздела в файле не всегда соответствуют предполагаемым смещениям в памяти, поэтому требуются некоторые незначительные корректировки.

Каждый PE-файл предполагает, что он будет загружен по определенному базовому адресу в виртуальной памяти. Если вы не можете гарантировать это, вам нужно будет пройтись по таблице перемещения PE-файла, чтобы соответствующим образом настроить указатели.

Каждый PE-файл также имеет таблицу импорта, в которой перечислены функции других DLL, которые он хочет вызвать. Вам нужно будет пройтись по этой таблице и вызвать LoadLibrary () / GetProcAddress (), чтобы заполнить каждый импорт.

Затем необходимо правильно настроить защиту памяти для каждого раздела. В заголовке каждого раздела указывается, какая защита ему нужна, поэтому достаточно вызвать VirtualProtect () для каждого раздела с правильными флагами. Как минимум, вам потребуется VirtualProtect для загруженного модуля с помощью PAGE_EXECUTE_READWRITE, иначе вы вряд ли сможете выполнить какой-либо код.

Наконец, для DLL вам нужно вызвать ее точку входа, адрес которой можно найти в заголовке PE; затем вы можете свободно вызывать экспортированные функции.

Поскольку вы хотите запустить EXE, у вас возникнут дополнительные проблемы. Вы можете просто запустить новый поток и вызвать из него точку входа EXE, но многие EXE могут расстроиться, поскольку процесс настроен для вас, а не EXE. Это также может убить ваш процесс, когда он попытается выйти. Поэтому вы можете захотеть создать новый процесс - возможно, еще одну копию вашего основного EXE со специальными аргументами, чтобы сообщить ему, что он будет запускать какой-то другой код - и в этом случае вам придется поместить EXE в его пространство памяти. Вы, вероятно, захотите проделать большую часть вышеуказанной работы в новом процессе, а не в старом. Вы можете либо создать именованный канал и отправлять данные из одного EXE в другой, либо выделить именованную общую область памяти с помощью MapViewOfFile. Конечно, EXE все еще может расстроиться, поскольку процесс, в котором он запущен, все еще не является его собственным.

В общем, намного проще просто записать во временный файл, а затем использовать Process.Start ().

Если вы все еще хотите сделать это трудным путем, взгляните на этот пример в неуправляемом коде: http://www.joachim-bauch.de/tutorials/loading-a-dll-from-memory / . Это не касается исполняемых файлов, только DLL, но если код в нем вас не пугает, вы можете расширить процесс, чтобы охватить исполняемые файлы.

7
ответ дан 2 December 2019 в 22:51
поделиться

Это не очень легко создать новый процесс из изображения памяти, все функции ядра предназначены для загрузки изображения с диска. См. Раздел «Секция процесса» Windows Windows NT / 2000 Нативную ссылку API для получения дополнительной информации - Page 161 имеет пример вручную раздум к процессу.

Если для запуска кода входит в свой собственный процесс, вы можете создать небольшую DLL, которая примет указатель на исполняемые данные и запустить его.

0
ответ дан 2 December 2019 в 22:51
поделиться

Попробуйте следующее:

setBackgroundColor(0xFF5DB9FB);
-121--335738-

Необходимо добавить предложение OUTPUT для запуска совместимости Linq с SQL.

Например:

INSERT MyTable (ParentEntityID, Number)
OUTPUT inserted.* 
SELECT
  i.ParentEntityID,
  ROW_NUMBER() OVER
  (
   PARTITION BY i.ParentEntityID
   ORDER BY (SELECT 1)
  ) + ISNULL(m.Number, 0) AS Number
FROM inserted i
LEFT JOIN MaxNumbers_CTE m
ON m.ParentEntityID = i.ParentEntityID
-121--2722712-

Гораздо лучший способ - создать временный файл DLL с FILE_FLAG_DELETE_ON_CLOSE атрибутом. Таким образом, файл будет автоматически удален, когда он больше не будет использоваться.

Я не думаю, что есть способ загрузить DLL из памяти (а не файла).

1
ответ дан 2 December 2019 в 22:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: