Обработка события при выгрузке DLL (DLL_PROCESS_DETACH)

Тема в разделе "WASM.ASSEMBLER", создана пользователем miae, 14 фев 2009.

  1. miae

    miae Member

    Публикаций:
    0
    Регистрация:
    22 дек 2007
    Сообщения:
    44
    Приветствую.

    Есть либа (liba.dll) почему не отрабатывает сообщение при выгрузке DLL ...

    liba.dll
    Код (Text):
    1. format PE GUI 4.0 DLL
    2. entry DllEntryPoint
    3.  
    4. include 'win32a.inc'
    5.  
    6. section '.data' data readable writeable
    7.         Message01 db   'DLL_PROCESS_ATTACH', 0
    8.         Message02 db   'DLL_PROCESS_DETACH', 0
    9.         ThreadID  dd ?
    10.  
    11. section '.code' code readable executable
    12.  
    13. proc DllEntryPoint hinstDLL,fdwReason,lpvReserved
    14.         cmp     [fdwReason],DLL_PROCESS_ATTACH
    15.         jne     .unload
    16.         invoke  CreateThread, 0, 0, SomeProc01, 0, 0, ThreadID
    17.         jmp     .finish
    18. .unload:
    19.         cmp     [fdwReason],DLL_PROCESS_DETACH
    20.         jne     .finish
    21.         invoke  CreateThread, 0, 0, SomeProc01, 0, 0, ThreadID
    22. .finish:
    23.         xor     eax, eax
    24.         inc     eax
    25.         ret
    26. endp
    27.  
    28. proc SomeProc01
    29.         invoke  MessageBox, 0, Message01, 0, 0
    30.         ret
    31. endp
    32.  
    33. proc SomeProc02
    34.         invoke  MessageBox, 0, Message02, 0, 0
    35.         ret
    36. endp
    37.  
    38. section '.idata' import data readable writeable
    39.         library kernel32,'KERNEL32.DLL',\
    40.                 user32,'USER32.DLL'
    41.  
    42. include 'api\kernel32.inc'
    43. include 'api\user32.inc'
    44.  
    45. section '.reloc' fixups data discardable
     
  2. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Перед вызовом InitRoutine модуля выполняется захват потоком критической секции загрузчика(LdrpLoaderLock). Новый поток начинается с LdrInitializeThunk и самое первое что он исполнит(в LdrpInitialize) - выполнит захват тойже критической секции и поток будет ждать её освобождения, а оно произойдёт по освобождению первым потоком критической секции, когда нотификация всех модулей будет исполнена.
    В таком случае как вариант - перехват APC-диспетчера, либо создавать суспенденным и устанавливать в EFlags.TF, что приведёт к переходу на диспетчер исключений(к примеру на VEH).
     
  3. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Возможный вариант:
    > RtlAddVectoredExceptionHandler(ExceptionHandler)
    > RtlCreateUserThread() или CreateThread(), CREATE_SUSPENDED.
    > NtGetContextThread
    > CONTEXT.EFlags.TF -> 1.
    > NtSetContextThread
    > NtResumeThread

    ExceptionHandler:
    > Выполняем необходимые действия.
    > CONTEXT.EFlags.TF -> 0.
    > LdrInitializeThink()/NtContinue, как будет вызвана, если загрузчик залочен, то будет ждать.
    > Либо возврат на прерванный диспетчер исключений(это удобнее).
     
  4. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    ИМХО, создавать поток при выгрузке dll просто глупо, т.к. он в любом случае запускается не сразу (а уж из DllMain подавно) и на момент его запуска код dll, включая функцию потока, уже м.б. выгружен из памяти
     
  5. Clerk

    Clerk Забанен

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