Можно ли узнать значение счетчика загрузок DLL? Ситуация такая: ДЛЛ должна выгрузить сама себя. Но в общем случае неизвестно сколько раз была вызвана для нее LoadLibrary. FreeLibraryAndExitThread уменьшает счетчик загрузок и завершает поток. А поскольку счетчик загрузок не обнулился, ДЛЛ остается загруженной. Необходимо предварительно сделать FreeLibrary, столько раз, сколько значение счетчика загрузок - 1, и потом уже FreeLibraryAndExitThread. Проблема в том, где взять это значение...
K10 Вот сделол кодес: Код (Text): UnloadAndExitDll proc uses ebx Status:NTSTATUS Local Entry:PLDR_DATA_TABLE_ENTRY Call @f @@: pop edx invoke LdrFindEntryForAddress, edx, addr Entry test eax,eax mov edx,Entry jnz exit_ mov eax,dword ptr [RtlExitUserThread + 2] assume edx:PLDR_DATA_TABLE_ENTRY push Status push offset exit_ push [edx].DllBase push dword ptr [eax] ;RtlExitUserThread mov [edx].LoadCount,0ffffh jmp LdrUnloadDll exit_: ret UnloadAndExitDll endp Работает ))
Тока вот не выгружаетсо почемуто непонятно.. [Выгружаетсо если счётчик в 1 поставить, но не основной модуль. Основной не выгружает, хз смотри в сурцах что к чему.]
Clerk Спасибо, конечно, но мне там надо было еще самоудалять эту DLL, поэтому я сделал шеллкодес... Код (Text): DeleteSelf PROC LOCAL pFreeLibrary, pDeleteFileA, pExitThread: DWORD PUSHAD invoke GetModuleHandle, zStr("kernel32.dll") MOV EBX, EAX invoke GetProcAddress, EBX, zStr("FreeLibrary") TEST EAX, EAX JZ ds_exit MOV pFreeLibrary, EAX invoke GetProcAddress, EBX, zStr("ExitThread") TEST EAX, EAX JZ ds_exit MOV pExitThread, EAX invoke GetProcAddress, EBX, zStr("DeleteFileA") TEST EAX, EAX JZ ds_exit MOV pDeleteFileA, EAX invoke VirtualAlloc, NULL, 4096, MEM_COMMIT OR MEM_RESERVE , PAGE_EXECUTE_READWRITE TEST EAX, EAX JZ ds_exit MOV EDI, EAX invoke GetModuleFileName, ModuleInstance, EDI, MAX_PATH TEST EAX, EAX JZ ds_exit MOV EBX, EDI ADD EDI, MAX_PATH + 100 _STOSB(068h) ; PUSH _STOSD(ModuleInstance) ; hModule _STOSB(0B8h) ; MOV EAX, _STOSD(pFreeLibrary) ; OFFSET kernel32:FreeLibrary _STOSW(0D0FFh) ; CALL EAX _STOSW(0C085h) ; TEST EAX, EAX _STOSW(0F075h) ; JNZ -10 _STOSB(068h) ; PUSH _STOSD(EBX) ; lpFileName _STOSB(0B8h) ; MOV EAX, _STOSD(pDeleteFileA) ; OFFSET kernel32:DeleteFileA _STOSW(0D0FFh) ; CALL EAX _STOSW(006Ah) ; PUSH 0 _STOSB(0B8h) ; MOV EAX, _STOSD(pExitThread) ; OFFSET kernel32.ExitThread _STOSW(0D0FFh) ; CALL EAX _STOSB(0C3h) ; RET ADD EBX, MAX_PATH + 100 ;INT 3 invoke CreateThread, NULL, 0, EBX, NULL, NULL, NULL ds_exit: POPAD RET DeleteSelf endp Работает