День добрый! Целевой процесс и dll произвольные, я пробовал для explorer.exe и correct.dll Библиотеку пытаюсь выгрузить путем создания удаленного потока, в который передаю адрес FreeLibrary и хэндл дллки в качестве параметра. При работе программы ошибок не возникает, но dll из процесса не выгружется... Не понимаю, что не так. Пробовал для других dll, результат тот же. Код (Text): format PE GUI 4.0 include 'win32a.inc' MAX_PATH equ 260 MAX_MODULE_NAME32 equ 256 TH32CS_SNAPMODULE equ 8 struct TProcessEntry32 dwSize dd 0 cntUsage dd 0 th32ProcessID dd 0 th32DefaultHeapID dd 0 th32ModuleID dd 0 cntThreads dd 0 th32ParentProcessID dd 0 pcPriClassBase dd 0 dwFlags dd 0 szExeFile TCHAR MAX_PATH dup (0) ends struct TModuleEntry32 dwSize dd ? th32ModuleID dd ? th32ProcessID dd ? GlblcntUsage dd ? ProccntUsage dd ? modBaseAddr dd ? modBaseSize dd ? hModule dd ? szModule TCHAR MAX_MODULE_NAME32 dup (0) szExePath TCHAR MAX_PATH dup (0) ends entry start start: ; получаем хэндл kernel32.dll invoke GetModuleHandle, libName test eax, eax jz go_out mov [hLibKernel32], eax ; получаю адрес FreeLibrary invoke GetProcAddress, [hLibKernel32], procName test eax, eax jz go_out mov [procAddr], eax ;================== Ищем процесс ======================== invoke CreateToolhelp32Snapshot, 2, 0 mov [fSnapshotHandle], eax mov [fProcessEntry32.dwSize], sizeof.TProcessEntry32 invoke Process32First, [fSnapshotHandle],fProcessEntry32 test eax, eax jz go_out searching: invoke lstrcmpi, ProcessName, fProcessEntry32.szExeFile test eax, eax jz pid_found invoke Process32Next,[fSnapshotHandle], fProcessEntry32 test eax, eax jz go_out jmp searching ; если нашли pid_found: push [fProcessEntry32.th32ProcessID] pop [PID] invoke CloseHandle, [fSnapshotHandle] test eax, eax jz go_out ;===================== Ищем dll ======================== invoke CreateToolhelp32Snapshot, TH32CS_SNAPMODULE, [PID] mov [fSnapshotHandle], eax mov [fModuleEntry32.dwSize], sizeof.TModuleEntry32 invoke Module32First, [fSnapshotHandle],fModuleEntry32 test eax, eax jz go_out searching_dll: invoke lstrcmpi, ModuleName, fModuleEntry32.szModule test eax, eax jz dll_found invoke Module32Next,[fSnapshotHandle], fModuleEntry32 test eax, eax jz go_out jmp searching_dll ; если нашли dll_found: ; сохраняем хэндл push [fModuleEntry32.hModule] pop [hModule] invoke CloseHandle, [fSnapshotHandle] test eax, eax jz go_out ;===== Выгружаем dll из целевого процесса ===== invoke OpenProcess, PROCESS_ALL_ACCESS, 0, [PID] test eax, eax jz go_out mov [hProcess], eax invoke CreateRemoteThread, [hProcess] ,\ NULL ,\ NULL ,\ [procAddr] ,\ hModule ,\ NULL ,\ lpThreadId test eax, eax jz go_out _ok: invoke MessageBox, NULL,lpTextOk, lpCaption, MB_OK jmp exit_ go_out: invoke MessageBox, NULL,lpTextNo, lpCaption, MB_OK exit_: invoke ExitProcess, eax section '.data' data readable writeable hLibKernel32 dd ? procAddr dd ? procName db 'FreeLibrary',0 libName db 'kernel32.dll',0 PID dd ? ProcessName db 'explorer.exe',0 fSnapshotHandle dd ? fProcessEntry32 TProcessEntry32 fModuleEntry32 TModuleEntry32 lpThreadId dd ? lpTextOk db 'OK!!!',0 lpTextNo db 'Не получилось чё-то...',0 lpCaption db 'Результат', 0 hProcess dd ? ModuleName db 'correct.dll',0 hModule dd ? section '.idata' import data readable library kernel32, 'kernel32.dll',\ user32, 'USER32.DLL' import kernel32, GetModuleHandle, 'GetModuleHandleA' ,\ GetProcAddress, 'GetProcAddress' ,\ OpenProcess, 'OpenProcess' ,\ CreateRemoteThread, 'CreateRemoteThread' ,\ ExitProcess, 'ExitProcess' ,\ CreateToolhelp32Snapshot, 'CreateToolhelp32Snapshot' ,\ Process32First, 'Process32First' ,\ Process32Next, 'Process32Next' ,\ lstrcmpi, 'lstrcmpiA' ,\ CloseHandle, 'CloseHandle' ,\ Module32First, 'Module32First' ,\ Module32Next, 'Module32Next' import user32, MessageBox, 'MessageBoxA'
не...вроде не то делал и по другому, запоминал ProccntUsage и вызывал CreateRemoteThread в цикле n-е кол-во раз. Всё равно не пашет. Код (Text): .... ; если нашли dll_found: ... push [fModuleEntry32.ProccntUsage] pop [cnt] ... ;===== Выгружаем dll из целевого процесса ===== ... cycle: invoke CreateRemoteThread, [hProcess] ,\ NULL ,\ NULL ,\ [procAddr] ,\ hModule ,\ NULL ,\ lpThreadId test eax, eax jz go_out dec [cnt] jnz cycle ...
Хорошо бы знать, что возвращает freelibrary. А код вроде правильный. Попробуй не на explorere, а на другой проге какой-нибудь.
если это статическая длл то она врядли будет выгружена, а DllMain вернет тебе Ок. Если тебе нада всё таки убрать эту длл из процесса, то вызови один раз DllMain, после почитсти референс в Peb и после сделай вызов NtUnmapViewOfSection с базой длл в параметре. Длл будет выгружена, независимо от того хочет она этого или нет.
deLight Если длл ни кто юзать не собираеться, то ни каких )), ну вообще конечно не стоит забывать что это не совсем документированный способ и все такое.
maverick Ты получаешь HANDLE в программе и передаешь его в удаленный поток? Тогда понятно почему не работает. Хэндлы объектов ядра специфичны для каждого процесса в отдельности - в другом процессе твой хэндл будет "пустой". Поэтому открой DLL в самом удаленном потоке и используй полученный HANDLE.
База загрузки DLL тоже специфична для процесса. Поэтому узнавать ее надо именно из самого процесса, в к-м создаем удаленный поток, а не в том процессе, который этот удаленный поток создает.
AndreyMust19 а что нам мешает узнать базу нужной длл из другого процесса? внимательнее первый пост смотрите. з.ы. попробуй приатачиться к эксплореру OllyDbg и поставить бряк допустим на FreeLibrary
AndreyMust19 А удалённые потоки зачем ? Наверно что лдр прочитать в текущем процессе, как это делает RtlQueryProcessDebugInformation(), ну или ваши апи работы со слепками. Это излишне, более того это палево - создание удалённого потока. Например psapi просто читают память чужого процесса. В общем это кривые способы, нужно перечислять все блоки памяти и получать имя файла, которому проекция относится.