2010-08-04 2 views
2

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

ответ

2

Я не думаю, что это сработает. Вызов FreeLibrary с дескриптором извне (LoadLibrary вызывается из области вне DLL), поскольку код работает в ячейке памяти, которая больше не будет действительна.

Даже если это возможно, он пахнет плохим дизайном. Возможно, вы хотите сделать какой-то обновитель или похожий. Объясните немного больше, каков результат, которого вы ожидаете. Выгрузка DLL изнутри сама по себе не путь.

+1

См. Мой ответ о функции FreeLibraryAndExitThread. –

+0

Вызов FreeLibrary - не лучший вариант, если у вас есть фоновый поток в вашей DLL. Лучше использовать [FreeLibraryAndExitThread] (https://msdn.microsoft.com/en-us/library/windows/desktop/ms683153 (v = vs.85) .aspx). Эта функция - скала, которая может убить 2 птиц. –

0

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

Подумайте об этом так: разгрузка DLL выполняется путем уменьшения его количества ссылок, используя FreeLibrary(). Проблема, конечно, в том, что после того, как счетчик ссылок DLL достигнет нуля, модуль не будет отображен. Это означает, что код в DLL, который вызвал FreeLibrary(), исчез.

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

4

Используйте этот режим, если длл сделал это задание:

CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)FreeLibrary, &__ImageBase, 0, NULL); 
    // terminate if dll run in a separate thread ExitThread(0); 
    // or just return out the dll 

И __ImageBase является структура заголовка PE вашей библиотеки DLL:

EXTERN_C IMAGE_DOS_HEADER __ImageBase; 
+0

Этот трюк может помочь, но теоретически это все равно может привести к состоянию гонки, если поток вызова CreateThread задержится слишком долго после вызова CreateThread. См. Мой ответ о функции FreeLibraryAndExitThread. –

11

Как я понимаю, это может быть сделано и (например, в случае инъекции dll с помощью CreateRemoteThread и других методов). Таким образом,

FreeLibraryAndExitThread(hModule, 0) 

будет делать именно это.

С другой стороны, называя

FreeLibrary(hModule) 

не будет делать здесь - из MSDN:. «Если бы они были назвать FreeLibrary и ExitThread отдельно, состояние гонки будет существовать библиотека может быть выгружен до того ExitThread называется." Как замечание, ExitThread делает некоторую бухгалтерскую отчетность, а не только возвращает функцию потока.

Все это предполагает, что Ваш Dll получил сам HMODULE по телефону LoadLibrary внутри загруженного Dll, или, вернее, путем вызова внутри загруженной Dll следующую функцию:

GetModuleHandleEx 
(
    GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, 
    (LPCTSTR)DllMain, 
    &hModule 
) 

Это увеличивает значение ссылки так что вы знаете, что, если вы освободите библиотеку позже, используя этот дескриптор, и если библиотека действительно выгружена, то вы получили последнюю ссылку на нее.
Если вы вместо того, чтобы пропустить приращение счетчика ссылок DLL и получить HMODULE только от аргумента DllMain во DLL_PROCESS_ATTACH тогда Вы не должны вызывать FreeLibraryAndExitThread, так как код, который зарядил Dll все еще использует его, и этот модуль ручка действительно не ваша.

Смежные вопросы