проблема с релокацией(инжект в процесс)

Тема в разделе "WASM.BEGINNERS", создана пользователем ilja_, 27 май 2010.

  1. ilja_

    ilja_ New Member

    Публикаций:
    0
    Регистрация:
    27 май 2010
    Сообщения:
    33
    Всем привет.

    есть код:

    Код (Text):
    1. typedef struct
    2. {
    3.     WORD    Offset:12;
    4.     WORD    Type:4;
    5. } IMAGE_FIXUP_ENTRY, *PIMAGE_FIXUP_ENTRY;
    6.  
    7. void ProcessRelocs( PVOID Image, PVOID NewImageBase )
    8. {
    9.     PIMAGE_DOS_HEADER dHeader   = (PIMAGE_DOS_HEADER)Image;
    10.     PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)RVATOVA(Image, dHeader->e_lfanew);
    11.  
    12.     ULONG RelRVA   = ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
    13.     ULONG RelSize  = ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
    14.     ULONG Delta    = (ULONG)NewImageBase - ntHeaders->OptionalHeader.ImageBase;
    15.  
    16.     if ( RelRVA && RelSize && !(ntHeaders->FileHeader.Characteristics & IMAGE_FILE_RELOCS_STRIPPED) &&
    17.          RelRVA + RelSize <= ntHeaders->OptionalHeader.SizeOfImage )
    18.     {
    19.         PIMAGE_BASE_RELOCATION Reloc = (PIMAGE_BASE_RELOCATION)RVATOVA(Image, RelRVA);
    20.         BOOLEAN bFirstChunk = TRUE;
    21.  
    22.         while ( bFirstChunk || Reloc->VirtualAddress )
    23.         {
    24.             PIMAGE_FIXUP_ENTRY Fixup = (PIMAGE_FIXUP_ENTRY)((ULONG)Reloc + sizeof(IMAGE_BASE_RELOCATION));
    25.             ULONG r, dwPointerRva;
    26.  
    27.             bFirstChunk = FALSE;
    28.  
    29.             for ( r = 0; r < (Reloc->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) >> 1; r++ )
    30.             {
    31.                 if ( Fixup->Type == IMAGE_REL_BASED_HIGHLOW )
    32.                 {
    33.                     dwPointerRva = Reloc->VirtualAddress + Fixup->Offset;
    34.  
    35.                     if ( dwPointerRva > ntHeaders->OptionalHeader.SizeOfImage )
    36.                     {
    37.                         return;
    38.                     }
    39.  
    40.                     *(PULONG)((ULONG)dHeader + dwPointerRva) += Delta;
    41.                 }
    42.  
    43.                 Fixup++;
    44.             }
    45.  
    46.             Reloc = (PIMAGE_BASE_RELOCATION)((ULONG)Reloc + Reloc->SizeOfBlock);
    47.         }
    48.     }
    49. }
    50.  
    51.  
    52. DWORD InjectCode( HANDLE hProcess, LPTHREAD_START_ROUTINE lpStartProc )
    53. {
    54.     HMODULE hModule = (HMODULE)GetImageBase();
    55.  
    56.     PIMAGE_DOS_HEADER pDH = (PIMAGE_DOS_HEADER)hModule;
    57.     PIMAGE_NT_HEADERS pPE = (PIMAGE_NT_HEADERS) ((LPSTR)pDH + pDH->e_lfanew);
    58.  
    59.     DWORD dwSize = pPE->OptionalHeader.SizeOfImage;
    60.  
    61.     LPVOID lpNewAddr = MemAlloc( dwSize );
    62.  
    63.     if ( lpNewAddr == NULL )
    64.     {
    65.         return -1;
    66.     }
    67.  
    68.     m_memcpy( lpNewAddr, hModule, dwSize );
    69.  
    70.     LPVOID lpNewModule = NULL;
    71.  
    72.     DWORD dwAddr = -1;
    73.     HMODULE hNewModule = NULL;
    74.  
    75.     if ( (NTSTATUS)ZwAllocateVirtualMemory( hProcess, &lpNewModule, 0, &dwSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE ) == STATUS_SUCCESS )
    76.     {
    77.         hNewModule = (HMODULE)lpNewModule;     
    78.  
    79.         ProcessRelocs( lpNewAddr, hNewModule );
    80.  
    81.         dwNewBase = (DWORD)hNewModule;
    82.  
    83.         if ( (NTSTATUS)ZwWriteVirtualMemory( hProcess, hNewModule, lpNewAddr, dwSize, NULL ) == STATUS_SUCCESS )
    84.         {
    85.             dwAddr = (DWORD)lpStartProc - (DWORD)hModule + (DWORD)hNewModule;
    86.         }
    87.     }
    88.  
    89.     DWORD dwOldProtect = 0;
    90.     ZwProtectVirtualMemory( hProcess, hNewModule, &dwSize, PAGE_EXECUTE_READWRITE, &dwOldProtect );
    91.    
    92.     MemFree( lpNewAddr );
    93.    
    94.     return dwAddr;
    95. }
    Код ProcessRelocs был взят с wasm.ru, инжект работает нормально, но дело в том что после запаковки программы upx он работать перестает, причем upx я пакую с --strip-relocs=0, даже если ехе распаковать обратно, работоспособность так же теряется, если нужно могу выложить ехе, я так понимаю проблема именно в релоках, т.к. отладочный вывод работает нормально, не работает именно инжект или я криво обращаюсь с пакером? делаю так upx -9 --strip-relocs=0 inject.exe
     
  2. baldr

    baldr New Member

    Публикаций:
    0
    Регистрация:
    29 апр 2010
    Сообщения:
    327
    ilja_,

    Я не уверен в том, что UPX воссоздаёт в памяти таблицу перемещения. Точнее, я проверил 3.05w на jview.exe: не воссоздаёт. В заголовке в памяти таблица с единственным фиксом внутри распаковщика (секция UPX1), как и в упакованном файле на диске. Возможно, какой-нибудь упаковщик и воссоздаёт в памяти точный образ загруженного незапакованного файла, но UPX на него не похож.
     
  3. freyr

    freyr New Member

    Публикаций:
    0
    Регистрация:
    23 фев 2010
    Сообщения:
    95
    Посмотрите в отладчике, вроде нада еще импорт настроить для загрузчика UPX поэтому тупо инжектировать не прокатит, стаб UPX не находит API динамически.
     
  4. baldr

    baldr New Member

    Публикаций:
    0
    Регистрация:
    29 апр 2010
    Сообщения:
    327
    freyr,

    Сам UPX уже отработал, импорты в порядке (относительном: перемещение кода подразумевает коррекцию ссылок на элементы IAT). Проблема в том, что элемент каталога данных с индексом IMAGE_DIRECTORY_ENTRY_BASERELOC ссылается на таблицу перемещения UPXа (ту самую с одним фиксапом) вместо оригинальной таблицы исходного файла, вот алгоритм перемещения и не работает (точнее он корректирует уже ненужный dword внутри кода UPX).

    Можно, наверное, изгалиться и выполнить кусок кода UPXа, ответственный за применение запакованной родной таблицы исходного файла или реализовать его алгоритм вместо использованного. :derisive:
     
  5. freyr

    freyr New Member

    Публикаций:
    0
    Регистрация:
    23 фев 2010
    Сообщения:
    95
    а кто вам даст гарантию, что в процессе, в который выполняется инжект разные длл не загруженны по иным базовым адресам (ASLR/etc).
     
  6. baldr

    baldr New Member

    Публикаций:
    0
    Регистрация:
    29 апр 2010
    Сообщения:
    327
    Мне, собственно, гарантия ни к чему. Я пытаюсь подсказать тов. ilja_ в чём может быть проблема вышеприведённого кода, если (подчёркивание моё)

    В общем, надо ждать реакции автора темы.
     
  7. ilja_

    ilja_ New Member

    Публикаций:
    0
    Регистрация:
    27 май 2010
    Сообщения:
    33
    baldr, freyr
    спасибо за ответы, дело в том что импорт я не использую, т.е. восстанавливать его не нужно, апи получаю динамически.

    я тоже думаю что проблема именно в этом, но тут что то универсальное нужно, темболее что файл может быть запакован не только upx, а может вобще быть не запакован (:.
     
  8. freyr

    freyr New Member

    Публикаций:
    0
    Регистрация:
    23 фев 2010
    Сообщения:
    95
    универсальным решением будет базонезависимый код, либо еще вариант - носить за собой "секцию" fixup'ов, который упх и дургие пакеры не затронут, например в конце кода ее втулить и перед исполнением кода настраивать ее вручную.
     
  9. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    у меня работает, хотя я фиксапы самостоятельно не юзаю, это системный загрузчик делает(а зачем они, если уже в систему встороен функционал для релокации..).
     
  10. ilja_

    ilja_ New Member

    Публикаций:
    0
    Регистрация:
    27 май 2010
    Сообщения:
    33
    Clerk
    Если вам не сложно, вы не могли бы более подробно осветить ваш пост, так я мало чего понял из этого, если я делаю инжект, как тут учавствует системный загрузчик?
     
  11. Clerk

    Clerk Забанен

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