Выгрузка всех DLL.

Тема в разделе "WASM.WIN32", создана пользователем sysexit, 8 ноя 2010.

  1. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    sysexit
    Загрузчик блокирует статически прилинкованные модуля, загружая в счётчик загрузок модуля маркер, проверяя который лодер блокирует попытки выгрузки. Легальный способ обойти это - поиск описателя(LdrFindEntryForAddress() etc.) и правка счётчика загрузок.
     
  2. sysexit

    sysexit New Member

    Публикаций:
    0
    Регистрация:
    27 авг 2010
    Сообщения:
    176
    Тут еще нашел некоторую информацию (http://wasm.ru/forum/viewtopic.php?id=32253), user32.dll она же динамическая библиотека... Как тогда понять какая динамическая а какая нет?
     
  3. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    sysexit
    Модуля подгружаемые автоматически системным загрузчиком на основе импорта модуля это статическая линковка. Остальные способы загрузки это динамическая линковка.
     
  4. sysexit

    sysexit New Member

    Публикаций:
    0
    Регистрация:
    27 авг 2010
    Сообщения:
    176
    Если в импорте exe есть user32.dll статическая линковка -- dll не выгрузится. Если его там нету, и в самой программе сделать так:

    invoke LoadLibraryA, "user32.dll"
    invoke FreeLibrary,EAX

    То Dll опять же не выгрузится, или это тоже статическая линковка?
     
  5. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    sysexit
    Выгрузится, почему же нет. Просто некоторые модуля могут увеличивать счётчик загрузок, изза чего одного вызова FreeLibrary() будет не достаточно.
     
  6. sysexit

    sysexit New Member

    Публикаций:
    0
    Регистрация:
    27 авг 2010
    Сообщения:
    176
    http://www.sendspace.com/file/gg2q7k

    Вот тут динамически загружается user32.dll и в цикле крутится FreeLibrary() в связке с GetModuleHanldeA().

    Сколько нужно итераций что бы выгрузилась данамически подгруженая dll, 1000? Миллион?
     
  7. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
  8. sysexit

    sysexit New Member

    Публикаций:
    0
    Регистрация:
    27 авг 2010
    Сообщения:
    176
    Я неудачник выходит, у меня на WinXP SP3 Rus, процесс user32.exe висит и нагружает процессор.
     
  9. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    sysexit
    Ну на чистой оси не виснет. Мало ли какой гуан у вас установлен. В конце концов отладчик откройте и посмотрите.
     
  10. sysexit

    sysexit New Member

    Публикаций:
    0
    Регистрация:
    27 авг 2010
    Сообщения:
    176
    Я уже смотрел в отладчике. Виснет означает что user32.dll не выгружается, и поле после 11 итераций обнуления становится 0xFFFF. На другом компьютере тоже самое.

    А ось у меня грязная только на user32.dll а когда с comctl32.dll работаю, она чистая, раз все выгружается?
     
  11. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    sysexit
    У меня XPSP3(nt 5.1.2600.5512) и всё выгружается на второй итерации. С user32 обычно куча модулей загружается, из них могут быть сторонние, которые запретят выгрузку или даже вобще нотификацию модулей загрузчиком. Вы не должны выгружать то, что явно не загрузили, а только уменьшить счётчик загрузок.
     
  12. _Lamer

    _Lamer Petr

    Публикаций:
    0
    Регистрация:
    19 ноя 2010
    Сообщения:
    9
    Адрес:
    Vitebsk
    Сказано верно, но еще продолжу:
    Если написать
    Код (Text):
    1. int Main (....){
    2. MessageBox(....);
    3. return 0;
    4. }
    то линкер ругнется на MessageBox, исправить код, значит добавить
    Код (Text):
    1. #include "Windows.h"
    - теперь запустишь и все заработает, НО уже есть статическая линковка
    Альтернатива - не писать #include "Windows.h", а ипользовать след код
    Код (Text):
    1. #define UNICODE
    2. typedef int (MessageBoxProc)(HWND, LPCTSTR, LPCTSTR, UINT);
    3.  
    4. int Main (....){
    5. // подгрузим DLL (явная динамическая загрузка)
    6. hDll = ::LoadLibrary(_T("User32")); // для MessageBox
    7. MessageBoxProc* MessageBox;
    8. if (hDll)
    9.    MessageBox = (MessageBoxProc*)GetProcAddress(hDll, "MessageBoxW"); // UNICODE определен.
    10. else
    11.    return false;
    12. // Вызовем MessageBox
    13. int nRes = (*MessageBox)(NULL, _T("Текст сообщения"), _T("Заголовок"), 0);
    14. // а теперь выгрузим User32.dll
    15. FreeLibrary(hDll);
    16. }
    Но есть одно НО, таким способом нужно запускать все функции из User32.dll которые ты используешь в своей проге И ТОЛЬКО ТОГДА у тебя будет ТОЛЬКО ДИНАМИЧЕСКАЯ ЗАГРУЗКА DLL и вызвав FreeLibrary ты уменьшишь счетчик и "выбросишь" DLL из адресного пространства тек процесса
     
  13. sn0w

    sn0w Active Member

    Публикаций:
    0
    Регистрация:
    27 фев 2010
    Сообщения:
    958
    интересно, а если VirtualFree пройтись по региону с инкрементом PAGE_SIZE?
     
  14. _Lamer

    _Lamer Petr

    Публикаций:
    0
    Регистрация:
    19 ноя 2010
    Сообщения:
    9
    Адрес:
    Vitebsk
    ну во первыз речь идет о выгрузке DLL а не освобождении памяти
    из MSDN {
    VirtualFree Function
    Releases, decommits, or releases and decommits a region of pages within the virtual address space of the calling process.
    To free memory allocated in another process by the VirtualAllocEx function, use the VirtualFreeEx function.
    }

    Во вторых а стараюсь писать по принципу:
    не я выделял память и не мне освобождать (за исключением того если докуменнтировано требование освободить)
    не я загружал и не мне выгружать.

    в третьих я ПРЕДЛОЖИЛ вариант использования динамической загрузки, в результате которой корректно выгружается DLL без "последствий" для процесса.