Загрузка exe из exe - PullRequest
       21

Загрузка exe из exe

3 голосов
/ 12 января 2010

Я экспортирую функцию [используя _declspec (dllexport)] из C ++ exe. Функция работает нормально, когда вызывается самой исполняемой программой. Я загружаю этот exe (давайте назовем этот exe1) из другого exe [exe тестового проекта - я назову этот exe2], используя статическое связывание, т.е. я использую файл exe1 .lib при компиляции exe2, а exe2 загружает его в память при запуске так же, как любая длл. Это приводит к сбою функции при выполнении.

Точная проблема обнаружена в разборке для оператора case переключения в функции.

Код сборки, когда exe1 вызывает функцию

   switch (dwType)
0040FF84  mov         eax,dword ptr [dwType] 
0040FF87  mov         dword ptr [ebp-4],eax 
0040FF8A  cmp         dword ptr [ebp-4],0Bh 
0040FF8E  ja          $LN2+7 (40FFD2h) 
0040FF90  mov         ecx,dword ptr [ebp-4] 
0040FF93  jmp         dword ptr  (40FFE0h)[ecx*4] 

Рассмотрим последние две инструкции. Mov перемещает переданный аргумент в ecx. В 40EFF0h у нас есть адреса к различным инструкциям для соответствующих заявлений случая. Таким образом, jmp приведет нас к соответствующим инструкциям кейса

Код сборки, когда exe2 вызывает функцию

   switch (dwType)
0037FF84  mov         eax,dword ptr [dwType] 
0037FF87  mov         dword ptr [ebp-4],eax 
0037FF8A  cmp         dword ptr [ebp-4],0Bh 
0037FF8E  ja          $LN2+7 (37FFD2h) 
0037FF90  mov         ecx,dword ptr [ebp-4] 
0037FF93  jmp         dword ptr [ecx*4+40FFE0h]

Найди что происходит не так? Адреса инструкции . Код был загружен в другое место в памяти. Когда exe1 был скомпилирован, компилятор предположил, что мы всегда будем запускать его, и, следовательно, он всегда будет загружаться в 0x0040000 [как в случае всех окон exes]. Поэтому он жестко запрограммировал в инструкции несколько значений, таких как 40FFE0h. Только во втором случае 40FFE0 столь же хорош, как и нежелательная память, поскольку искомая таблица адресов команд там не находится.

Как я могу решить эту проблему без преобразования exe1 в dll?

Ответы [ 2 ]

1 голос
/ 12 января 2010

Рассматривали ли вы другой способ сделать это? Например, сделать 2-й .exe-файл в .dll и вызвать его с помощью rundll32, когда вы хотите использовать его в качестве исполняемого файла?

В противном случае: Сгенерированная сборка в порядке. Проблема заключается в том, что переносимые исполняемые файлы Win32 имеют базовый адрес (в данном случае 0x0040000) и раздел, содержащий подробные положения адресов, чтобы их можно было перебазировать при необходимости.

Так происходит одна на две вещи: - Либо компилятор не включает записи IMAGE_BASE_RELOCATION при сборке .exe. - Или среда выполнения не выполняет базовые перемещения, когда динамически загружает .exe - (возможно оба)

Если .exe-файл содержит записи о перемещении, вы можете прочитать их и выполнить базовое перемещение самостоятельно. Вам придется перепрыгивать через обручи, например, убедиться, что у вас есть доступ для записи в память (VirtualAlloc и т. Д.), Но это концептуально довольно просто.

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

Редактировать: Как указывает шош, вы можете столкнуться с другими проблемами, как только исправите это.

1 голос
/ 12 января 2010

просто не делай этого. Это не стоит беспокоиться.

Я пытался делать то, что вы пытаетесь некоторое время назад. Возможно, вы можете решить проблему не перемещаемого exe-файла, изменив параметр в окне свойств в «Linker-> Advenced-> Fixed base address», но тогда у вас будут другие проблемы. То, что, наконец, заставило меня осознать, что это пустая трата времени, это понимание того, что в EXE нет функции DllMain(). Это означает, что библиотека CRT не инициализируется и что всякие вещи работают не так, как вы ожидаете.

Вот вопрос, который я написал об этом некоторое время назад

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...