DLL выгружается сама - PullRequest
       5

DLL выгружается сама

3 голосов
/ 05 августа 2010

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

Ответы [ 4 ]

13 голосов
/ 29 ноября 2013

Насколько я понимаю, это МОЖЕТ быть сделано и ОБЯЗАНО иногда выполняться (например, в случае внедрения 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, так что вы знаете, что если вы позже освободите библиотеку, используя этот дескриптор, и если библиотека действительно выгружена, то у вас будет последняя ссылка на нее.
Если вместо этого вы пропустили увеличение счетчика ссылок Dll и получили hModule только из аргумента DllMain во время DLL_PROCESS_ATTACH , то вам не следует вызывать FreeLibraryAndExitThread , так как загруженный код Dll все еще использует его, и этот дескриптор модуля действительно не Ваш, чтобы управлять им.

5 голосов
/ 22 марта 2013

Используйте это, когда DLL сделал это работу:

    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;
2 голосов
/ 05 августа 2010

Не думаю, что это сработает.Вызов FreeLibrary с дескриптором извне (LoadLibrary был бы вызван из области за пределами DLL), поскольку код выполняется в области памяти, которая больше не будет действительной.как плохой дизайн.Может быть, вы хотите сделать некоторые обновления или тому подобное.Объясните немного больше, какой результат вы ожидаете.Выгрузка DLL изнутри сама по себе - это не тот путь.

0 голосов
/ 05 августа 2010

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

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

...