Приветствую. Есть либа (liba.dll) почему не отрабатывает сообщение при выгрузке DLL ... liba.dll Код (Text): format PE GUI 4.0 DLL entry DllEntryPoint include 'win32a.inc' section '.data' data readable writeable Message01 db 'DLL_PROCESS_ATTACH', 0 Message02 db 'DLL_PROCESS_DETACH', 0 ThreadID dd ? section '.code' code readable executable proc DllEntryPoint hinstDLL,fdwReason,lpvReserved cmp [fdwReason],DLL_PROCESS_ATTACH jne .unload invoke CreateThread, 0, 0, SomeProc01, 0, 0, ThreadID jmp .finish .unload: cmp [fdwReason],DLL_PROCESS_DETACH jne .finish invoke CreateThread, 0, 0, SomeProc01, 0, 0, ThreadID .finish: xor eax, eax inc eax ret endp proc SomeProc01 invoke MessageBox, 0, Message01, 0, 0 ret endp proc SomeProc02 invoke MessageBox, 0, Message02, 0, 0 ret endp section '.idata' import data readable writeable library kernel32,'KERNEL32.DLL',\ user32,'USER32.DLL' include 'api\kernel32.inc' include 'api\user32.inc' section '.reloc' fixups data discardable
Перед вызовом InitRoutine модуля выполняется захват потоком критической секции загрузчика(LdrpLoaderLock). Новый поток начинается с LdrInitializeThunk и самое первое что он исполнит(в LdrpInitialize) - выполнит захват тойже критической секции и поток будет ждать её освобождения, а оно произойдёт по освобождению первым потоком критической секции, когда нотификация всех модулей будет исполнена. В таком случае как вариант - перехват APC-диспетчера, либо создавать суспенденным и устанавливать в EFlags.TF, что приведёт к переходу на диспетчер исключений(к примеру на VEH).
Возможный вариант: > RtlAddVectoredExceptionHandler(ExceptionHandler) > RtlCreateUserThread() или CreateThread(), CREATE_SUSPENDED. > NtGetContextThread > CONTEXT.EFlags.TF -> 1. > NtSetContextThread > NtResumeThread ExceptionHandler: > Выполняем необходимые действия. > CONTEXT.EFlags.TF -> 0. > LdrInitializeThink()/NtContinue, как будет вызвана, если загрузчик залочен, то будет ждать. > Либо возврат на прерванный диспетчер исключений(это удобнее).
ИМХО, создавать поток при выгрузке dll просто глупо, т.к. он в любом случае запускается не сразу (а уж из DllMain подавно) и на момент его запуска код dll, включая функцию потока, уже м.б. выгружен из памяти
leo При выгрузке обычно да, но малоли какие махинации выполняются.. Вот запустил из InitRoutine поток, тот который юзал её суспендится.