#winapi #c -cli #exe #loadlibrary
#winapi #c -cli #exe #loadlibrary
Вопрос:
До сих пор у меня был какой-то механизм плагинов, в котором я загружал библиотеки dll, используя LoadLibrary и GetProcAddress, чтобы создать конкретный объект и вернуть общий интерфейс. Это работало нормально, пока я не решил, что одна из библиотек dll должна быть exe.
В документации LoadLibrary говорится, что его можно использовать и для exe-файлов, поэтому я попробовал. Исполняемый файл загружается без ошибок, как GetProcAddress. Но когда я пытаюсь вызвать конструктор моего конкретного объекта, я получаю нарушение доступа.
Я думал, что это произойдет, потому что загрузка exe-файла не загружает все используемые им библиотеки DLL. Итак, я попытался загрузить их с помощью LoadLibrary, но я получил ту же ошибку. Есть какие-нибудь советы по этому поводу?
Вот мой код (смешанный C / CLI):
Interface* MCFactory::LoadInstanceFromAssembly( String ^ concreteAssemblyName, String ^ param ){
string fullPathToAssembly = "";
fullPathToAssembly = FileSystem::GetPathToProgramDirectory();
fullPathToAssembly = "\" marshal_as<string>(concreteAssemblyName);
MODULE hDLL = AssemblyLoader::GetInstance().LoadAssembly( fullPathToAssembly );
Interface* pObject = NULL;
if (hDLL != NULL){
t_pCreateInstanceFunction pCreateInstanceFunction =
(t_pCreateInstanceFunction) ::GetProcAddress (hDLL, CREATE_INSTANCE_FUNCTION_NAME.c_str());
if ( pCreateInstanceFunction != NULL ){
//Yes, this assembly exposes the function we need
//Invoke the function to create the object
pObject = (*pCreateInstanceFunction)( marshal_as<string>(param) );
}
}
return pObject;
}
(AssemblyLoader::getInstance().LoadAssembly — это просто оболочка для ::LoadLibrary)
Ответ №1:
Вы можете использовать LoadLibrary
и GetProcAddress
для основного исполняемого файла вашего процесса, это позволяет выполнять динамический экспорт в обратном направлении (.exe в .dll).
Вы не можете загрузить второй файл .exe в пространство памяти вашего процесса, за исключением доступа к ресурсам / данным, потому что .exe-код нельзя переместить. (Чистые MSIL .exe-файлы являются исключением, потому что в файле нет кода, все это генерируется JIT.)
В принципе, LoadLibrary
в .exe полезно только тогда, когда
-
.exe является основным исполняемым файлом процесса, и в этом случае вы также можете использовать
GetModuleHandle
или
-
Используется
LOAD_LIBRARY_AS_DATAFILE
флаг
Комментарии:
1. Позволяет ли включение ASLR загружать несколько .exes в один процесс?
2. @ildjarn: Вы имеете в виду параметр компилятора, совместимого с ASLR, а не настройку операционной системы? Я так не думаю.
3. Да, это то, что я имел в виду. Просто любопытно.
4.@ildjarn: Возможно, это имеет отношение к делу:
/FIXED
/DYNAMICBASE
5. @ildjarn: И этот поток , похоже, указывает на то, что исполняемый файл, даже с поддержкой ASLR, не может быть загружен как код.
Ответ №2:
Это возможно.
http://www.codeproject.com/Articles/1045674/Load-EXE-as-DLL-Mission-Possible
Идея состоит в том, чтобы исправить IAT, а затем вызвать CRT. Конечно, EXE-файл должен быть перемещаемым, и по умолчанию (ASLR) это так.
Комментарии:
1. Конечно, этот метод требует некоторых очень агрессивных изменений в EXE. Это может сработать в определенных сценариях, но не для общего случая.
2. Все, что я говорю в этой статье, не является недокументированным. Поэтому он будет работать до тех пор, пока условия остаются неизменными (т. Е. Существующие местоположения, вызываемый CRT, исправленный IAT).
3. Да? Каждый трюк, который вы используете, заключается в создании недокументированных предположений. Покажите мне один официальный документ Microsoft, в котором говорится, что можно вызывать
WinMainCRTStartup
во втором модуле (Важное замечание: при каждомWinMainCRTStartup
вызовеGetModuleHandle(0)
он получает дескриптор не инициализируемого модуля, а основного модуля процесса. Все виды ресурсов не будут найдены правильно, включая манифесты.) И это только начало.4. В этом есть смысл, но вызывать CRT необязательно. Это предназначено только для инициализации глобальных переменных — если они вам нужны.
Ответ №3:
Хотя ответ Бена охватывает большинство случаев в этой статье http://sandsprite.com/CodeStuff/Using_an_exe_as_a_dll.html может быть полезно в некоторых обстоятельствах