выгрузка dll из чужого процесса

Тема в разделе "WASM.BEGINNERS", создана пользователем SiruS, 26 сен 2008.

  1. SiruS

    SiruS Алекс

    Публикаций:
    0
    Регистрация:
    19 фев 2005
    Сообщения:
    145
    Адрес:
    Львов
    я так понял ты относительно своей процедуры выгрузки длл из памяти? это я уже научился делать правда несколько иным способом )))))
    сейчас надо снять установленные хуки, чтобы небыло бсодов при выгрузке этой дллки из винлогона...

    з.ы. токо сча заметил твой пост относительно FreeLibraryAndExitThread. прийду домой - попробую. спасибо!!!
     
  2. Magnum

    Magnum New Member

    Публикаций:
    0
    Регистрация:
    29 дек 2007
    Сообщения:
    925
    SiruS
    Как-то ты очень интересно выгружаешь длл-ки.
    Если длл-ка посторонняя - удаленный поток - еще более менее приемлимое решение.
    Но для своей дллки - это глупость.

    Используй средства межпроцессной синхронизации.
    В самом простом случае достаточно события (Event-а)
    Отдельным потоком мониторишь в дллке эвент. И в случае если кто-то выполнил SetEvent() - тотально выгружаешься.

    В более сложном: эвент + разделяемая память (куда можно передавать имя процесса или ПИД, из которого нужно выгрузиться)

    О приемах межпроцессной синхронизации читай статьи на васме
     
  3. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    писал для себя побыстрому, поэтому имя Dll и PId процесса подставляется до компиляции, можно было сделать GUI

    Код (Text):
    1. format PE GUI 4.0
    2. entry start
    3.  
    4. include '%fasminc%\win32a.inc'
    5.  
    6. PID        =    0000009A8h
    7. DLLNAME   equ   'uxtheme.dll'
    8.  
    9. INFINITE   =    0FFFFFFFFh  ; Infinite timeout
    10.  
    11. section '.code' code readable executable
    12.  
    13. align 4
    14. start:
    15.     mov eax, [FreeLibrary]
    16.     mov [ddFreeLibrary], eax
    17.     mov eax, [GetModuleHandle]
    18.     mov [ddGetModuleHandle], eax
    19.     invoke OpenProcess, PROCESS_CREATE_THREAD or PROCESS_VM_OPERATION or PROCESS_VM_WRITE or SYNCHRONIZE, FALSE, PID
    20.     test eax, eax
    21.     jz @exit
    22.     mov [hProcess], eax
    23.     invoke VirtualAllocEx, eax, NULL, inject_code_size, MEM_COMMIT, PAGE_EXECUTE_READWRITE
    24.     test eax, eax
    25.     jz @close
    26.     mov [DllNameAddress], eax
    27.     invoke WriteProcessMemory, [hProcess], eax, inject_code_start, inject_code_size, NULL
    28.     test eax, eax
    29.     jz @free
    30.     mov eax, [DllNameAddress]
    31.     add eax, sizeofDllName
    32.     invoke CreateRemoteThread, [hProcess], NULL, 0, eax, 0, 0, NULL
    33.     test eax, eax
    34.     jz @free
    35.     push eax
    36.     invoke WaitForSingleObject, eax, INFINITE
    37.     call [CloseHandle]
    38.     invoke VirtualFreeEx, [hProcess], [DllNameAddress], 0, MEM_RELEASE
    39.     invoke CloseHandle, [hProcess]
    40.     invoke MessageBox, NULL, szDone, NULL, MB_OK or MB_ICONINFORMATION
    41.     jmp @exit
    42. @free:
    43.     invoke VirtualFreeEx, [hProcess], [DllNameAddress], 0, MEM_RELEASE
    44. @close:
    45.     invoke CloseHandle, [hProcess]
    46. @exit:
    47.     invoke ExitProcess, 0
    48.  
    49.  
    50. section '.data' data readable writeable
    51.  
    52. inject_code_start = $
    53. DllName   db  DLLNAME,0
    54. sizeofDllName = $ - DllName
    55.   db 68h ; push
    56. DllNameAddress dd 0
    57.   db 0B8h ; mov eax,
    58. ddGetModuleHandle dd 0
    59.   call eax
    60.   push eax
    61.   db 0B8h ; mov eax,
    62. ddFreeLibrary dd 0
    63.   call eax
    64.   retn 4
    65. inject_code_size = $ - inject_code_start
    66.  
    67. szDone  db  'Done!',0
    68.  
    69. hProcess  dd  ?
    70.  
    71.  
    72. section '.idata' import data readable
    73.  
    74. library kernel32,'KERNEL32.DLL',\
    75.         user32,'USER32.DLL'
    76.  
    77.  
    78. include '%fasminc%\APIA\KERNEL32.INC'
    79. include '%fasminc%\APIA\USER32.INC'
     
  4. Flasher

    Flasher Member

    Публикаций:
    0
    Регистрация:
    31 янв 2004
    Сообщения:
    640
    А Если попробовать вот так:

    1) получить TEB процесса, перебрать все LDR модули, и найти нужный
    2) суспендить либо полностью процесс, либо все потоки
    3) открыть процесс, и вызвать invoke ZwUnmapViewOfSection,ProcessHendl,LDR_DATA_TABLE_ENTRY.DllBase
    4) ресуспенд

    Должно сработать.., и некакие записы в процесс и удаленные потоки не понадобятся..
     
  5. SiruS

    SiruS Алекс

    Публикаций:
    0
    Регистрация:
    19 фев 2005
    Сообщения:
    145
    Адрес:
    Львов
    Magnum
    говорю же, эт не моя дллка. была бы моя - было бы проще )))

    Asterix
    делаю так же как и ты, ток без VirtualAllocEx и WriteProcessMemory

    Flasher
    спасибо, мне пока и создание удаленного потока подходит )

    slow
    по прежнему неудаеться снять хуки. поиск по форуму на предмет "снятие хуков" ничего не дал (
     
  6. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    SiruS
    "Хуки" - это на самом деле скорее всего сплайсинг. Вам нужно искать в отладчике, где dll ставит свои перехваты и просто заменить подменённые инструкции оригинальными.
     
  7. asmfan

    asmfan New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2006
    Сообщения:
    1.004
    Адрес:
    Abaddon
    Добавить к коду Asterix цикл - это при возможном ref count не 1.
    + хорошо бы сделать поиск апишек (в случае ASLR).
     
  8. SiruS

    SiruS Алекс

    Публикаций:
    0
    Регистрация:
    19 фев 2005
    Сообщения:
    145
    Адрес:
    Львов
    спасибо за совет - попробую так.
     
  9. SiruS

    SiruS Алекс

    Публикаций:
    0
    Регистрация:
    19 фев 2005
    Сообщения:
    145
    Адрес:
    Львов
    нашел вот такой код:
    Код (Text):
    1. VOID UnhookMod( LPSTR lpModName ) {
    2.     HANDLE  hFile, hMapping;
    3.     HMODULE hMod;
    4.     LPVOID  hMap;
    5.     CHAR    lpSystemDir[MAX_PATH*2];
    6.     ULONG   b;
    7.  
    8.     GetSystemDirectory( lpSystemDir, MAX_PATH-1 );
    9.     lstrcat( lpSystemDir, "\\" );
    10.     lstrcat( lpSystemDir, lpModName );
    11.     hFile = CreateFile( lpSystemDir, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0 );
    12.  
    13.     if (hFile != INVALID_HANDLE_VALUE) {
    14.  
    15.         hMapping = CreateFileMapping( hFile, 0, PAGE_READONLY|SEC_IMAGE, 0, 0, 0 );
    16.         if (hMapping != INVALID_HANDLE_VALUE) {
    17.  
    18.             hMap = MapViewOfFile( hMapping, FILE_MAP_READ, 0, 0, 0 );
    19.             if (hMap) {
    20.  
    21.                 IMAGE_DOS_HEADER *dh = (IMAGE_DOS_HEADER*)hMap;
    22.                 IMAGE_NT_HEADERS *nh = (IMAGE_NT_HEADERS*)((ULONG)hMap+dh->e_lfanew);
    23.                 IMAGE_FILE_HEADER *fh = (IMAGE_FILE_HEADER*)&nh->FileHeader;
    24.                 IMAGE_OPTIONAL_HEADER *oh = (IMAGE_OPTIONAL_HEADER*)&nh->OptionalHeader;
    25.                 IMAGE_EXPORT_DIRECTORY *ed = (IMAGE_EXPORT_DIRECTORY*)((ULONG)hMap+oh->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
    26.                 ULONG *functionEntryPoints = (ULONG*)((ULONG)hMap+ed->AddressOfFunctions);
    27.  
    28.                 BYTE entryPointBytes[10], originalBytes[10];
    29.  
    30.                 for (int i = 0; i < ed->NumberOfFunctions; i++) {
    31.  
    32.                     ULONG entryVA = oh->ImageBase+functionEntryPoints[i],
    33.                           entryMA = ((ULONG)hMap+functionEntryPoints[i]);
    34.  
    35.                     memcpy( originalBytes, (PVOID)entryMA, 10 );
    36.                     ReadProcessMemory( (HANDLE)-1, (LPVOID)entryVA, (LPVOID)entryPointBytes, 10, &b );
    37.  
    38.                     if (memcmp( entryPointBytes, originalBytes, 10 ))
    39.                         WriteProcessMemory( (HANDLE)-1, (LPVOID)entryVA, (LPVOID)originalBytes, 10, &b );
    40.                 }
    41.             }
    42.         }
    43.     }
    44.  
    45.     UnmapViewOfFile( hMap );
    46.     CloseHandle( hMapping );
    47.     CloseHandle( hFile );
    48. }
    49.  
    50. VOID UnloadWLHook( VOID ) {
    51.     MODULEENTRY32 me;
    52.     HANDLE hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, GetCurrentProcessId() );
    53.  
    54.     if (hSnapshot != INVALID_HANDLE_VALUE && Module32First( hSnapshot, &me )) {
    55.         do {
    56.             if (lstrcmp( me.szModule, "wl_hook.dll" )) UnhookMod( me.szModule );
    57.         } while (Module32Next( hSnapshot, &me ));
    58.     }
    59.  
    60.     CloseHandle( hSnapshot );
    61.     FreeLibrary( GetModuleHandle( "wl_hook.dll" ) );
    62. }
    помогите перевести вот этот кусок:
    Код (Text):
    1. IMAGE_DOS_HEADER *dh = (IMAGE_DOS_HEADER*)hMap;
    2.                 IMAGE_NT_HEADERS *nh = (IMAGE_NT_HEADERS*)((ULONG)hMap+dh->e_lfanew);
    3.                 IMAGE_FILE_HEADER *fh = (IMAGE_FILE_HEADER*)&nh->FileHeader;
    4.                 IMAGE_OPTIONAL_HEADER *oh = (IMAGE_OPTIONAL_HEADER*)&nh->OptionalHeader;
    5.                 IMAGE_EXPORT_DIRECTORY *ed = (IMAGE_EXPORT_DIRECTORY*)((ULONG)hMap+oh->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
    6.                 ULONG *functionEntryPoints = (ULONG*)((ULONG)hMap+ed->AddressOfFunctions);
    7.  
    8.                 BYTE entryPointBytes[10], originalBytes[10];
    9.  
    10.                 for (int i = 0; i < ed->NumberOfFunctions; i++) {
    11.  
    12.                     ULONG entryVA = oh->ImageBase+functionEntryPoints[i],
    13.                           entryMA = ((ULONG)hMap+functionEntryPoints[i]);
    заранее спасибо!
     
  10. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    SiruS
    //обычное переприсвоение dh = hMap
    IMAGE_DOS_HEADER *dh = (IMAGE_DOS_HEADER*)hMap;
    //по смещению e_lfanew (поле структуры IMAGE_DOS_HEADER) относительно адреса структуры dh берём двойное слово, которое является смещением NT-заголовка, прибавляем к нему базу (hMap) и запоминаем в nh
    IMAGE_NT_HEADERS *nh = (IMAGE_NT_HEADERS*)((ULONG)hMap+dh->e_lfanew);
    //адрес смещения FileHeader (поле структуры IMAGE_NT_HEADERS) относительно адреса nh запоминаем в fh
    IMAGE_FILE_HEADER *fh = (IMAGE_FILE_HEADER*)&nh->FileHeader;
    //адрес смещения OptionalHeader (поле структуры IMAGE_NT_HEADERS) относительно nh запоминаем в oh
    IMAGE_OPTIONAL_HEADER *oh = (IMAGE_OPTIONAL_HEADER*)&nh->OptionalHeader;
    //по смещению DataDirectory (поле структуры IMAGE_OPTIONAL_HEADER, а так же массив структур IMAGE_DATA_DIRECTORY) относительно oh находим поле VirtualAddress нулевой структуры (т.к. IMAGE_DIRECTORY_ENTRY_EXPORT = 0), которое содержит смещение таблицы экспорта, прибавляем к нему базу (hMap) и запоминаем в ed.
    IMAGE_EXPORT_DIRECTORY *ed = (IMAGE_EXPORT_DIRECTORY*)((ULONG)hMap+oh->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
    //по смещению AddressOfFunctions относительно ed (начало таблицы экспорта) берём двойное слово, которое является смещением массива смещений экспортируемых функций, прибавляем к нему базу и запоминаем в functionEntryPoints
    ULONG *functionEntryPoints = (ULONG*)((ULONG)hMap+ed->AddressOfFunctions);
    BYTE entryPointBytes[10], originalBytes[10];
    //Этим циклом проходимся по массиву смещений экспортируемых функций и копируем оригинальные байты из библиотеки, загруженной по адресу hMap в библиотеку, загруженную по адресу ImageBase. И это, кстати, грубая ошибка, т.к. библиотека во многих случаях не будет загружена по адресу ImageBase. Поэтому вместо значения oh->ImageBase нужно подставлять значение GetModuleHandle(lpModName).
    for (int i = 0; i < ed->NumberOfFunctions; i++) {
    ULONG entryVA = oh->ImageBase+functionEntryPoints,
    entryMA = ((ULONG)hMap+functionEntryPoints);

    Везде, где упоминается слово "смещение", его можно заменить на слово "RVA".
    Подробнее читайте этот цикл. А ещё подробнее эту статью.
     
  11. SiruS

    SiruS Алекс

    Публикаций:
    0
    Регистрация:
    19 фев 2005
    Сообщения:
    145
    Адрес:
    Львов
    l_inc, пасибо, это многое что прояснило, вот токо я по прежнему немогу перевести этот кусок кода (
     
  12. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    SiruS
    Так я ж перевёл... на русский. Если нужно на ассемблер, показывайте, что получается, и задавайте конкретные вопросы по тому, что не получается.