Инжект

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

  1. slavanap

    slavanap Вячеслав

    Публикаций:
    0
    Регистрация:
    10 сен 2008
    Сообщения:
    300
    Адрес:
    Смоленск, Россия
    Необходимо у конкретной exe'шки каждый раз при её запуске перехватывать пару функций и вместо них выполнять свой код.

    Подскажите, пожалуйста, как это реализовать?
     
  2. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    заменить а exe-шке код этих функций на свой или на вызов своего из динамически подгружаемой dll
    примерно так
    Код (Text):
    1. push '.dll'
    2. push 'name'
    3. push esp
    4. call [LoadLibraryA]
    5. add esp, 8
    6. test eax, eax
    7. jz exit
    8. push 'Name'
    9. push 'Func'
    10. push esp
    11. push eax
    12. call [GetProcAddress]
    13. add esp, 8
    14. test eax, eax
    15. jz exit
    16. jmp eax
    17. exit:
    18. ret XXX//XXX количество байт параметров
     
  3. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    примерно. забыл еще про 0 в конце имени dll-ки и функции и про сохранить/восстановить ecx, edx, eax
     
  4. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    ну так и быть напишу еще один пост. вот так. примерно. зависит от задачи
    Код (Text):
    1. push eax
    2. push ecx
    3. push edx
    4. push 0
    5. push '.dll'
    6. push 'name'
    7. push esp
    8. call [LoadLibraryA]
    9. add esp, 8
    10. test eax, eax
    11. jz exit
    12. push 'Name'
    13. push 'Func'
    14. push esp
    15. push eax
    16. call [GetProcAddress]
    17. add esp, 8
    18. test eax, eax
    19. jz exit
    20. pop edx
    21. pop edx
    22. pop ecx
    23. xchg [esp], eax
    24. ret
    25. exit:
    26. pop eax
    27. pop edx
    28. pop ecx
    29. pop eax
    30. ret 0xNNNN
    по сути это не поменяет ни одного регистра со входа на выходе при ошибке или вызове твоей dll. А функции вообще в данном случае лучше по ординалу экспортировать
    Код (Text):
    1. push 1
    2. push eax
    3. call [GetProcAddress]
    и LoadLibrary с GetProcAddress можно заменить не очень большим числом команд, но это ты уж сам. (писать влом)
     
  5. slavanap

    slavanap Вячеслав

    Публикаций:
    0
    Регистрация:
    10 сен 2008
    Сообщения:
    300
    Адрес:
    Смоленск, Россия
    max7C4,
    Изменять саму ехе-шку не вижу смысла, т.к. производитель наровит выпустить новую версию, а мне надо всего пара функций (CreateFile, WriteFile, ReadFile, CloseHandle).

    Думаю написать отдельный exe-файл, который будет сам запускать приложение-жертву и будет хукать некоторые функции в нем.
    Вот только на что заменить код функций в другом процессе через WriteProcessMemory, чтобы этот код вызывал событие/передавал данные в другой процесс, я ума не приложу...
     
  6. slavanap

    slavanap Вячеслав

    Публикаций:
    0
    Регистрация:
    10 сен 2008
    Сообщения:
    300
    Адрес:
    Смоленск, Россия
    *передавал данные в мой процесс, я ума не приложу...
     
  7. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    думаю
    таже отговорка. производитель выпустит новую и свою exe придется переписывать т.к. функции сдвинуться и/или изменятся.
     
  8. bendme

    bendme New Member

    Публикаций:
    0
    Регистрация:
    10 мар 2009
    Сообщения:
    179
    А чего сложного то? Заменяешь функцию на свою, она у тебя будет делать то, чего тебе надо (например, сохранять входящие переменные в логфайл какой-нибудь, затем вызывать оригинальную функцию, вообщем чего угодно)

    Передавать данные в другой процесс можно кучей способов, например через memory mapped файлы.

    Поповоду перехвата API функций куча статей есть, в том числе на этом сайте.
     
  9. slavanap

    slavanap Вячеслав

    Публикаций:
    0
    Регистрация:
    10 сен 2008
    Сообщения:
    300
    Адрес:
    Смоленск, Россия
    стало понятней. спасибо.
    меняю вопрос: как из одного процесса заставить подгрузиться специальную dll-шку в другой процесс, handle которого известен.
     
  10. bendme

    bendme New Member

    Публикаций:
    0
    Регистрация:
    10 мар 2009
    Сообщения:
    179
    внедрять длл можно несколькоми способами, читай Рихтера 22 главу, там всё описано.
     
  11. bendme

    bendme New Member

    Публикаций:
    0
    Регистрация:
    10 мар 2009
    Сообщения:
    179
    ниче не надо будет менять
     
  12. slavanap

    slavanap Вячеслав

    Публикаций:
    0
    Регистрация:
    10 сен 2008
    Сообщения:
    300
    Адрес:
    Смоленск, Россия
  13. slavanap

    slavanap Вячеслав

    Публикаций:
    0
    Регистрация:
    10 сен 2008
    Сообщения:
    300
    Адрес:
    Смоленск, Россия
    Пробую делать так, как написано в 22ой главе. Внедрение DLL и перехват API-вызовов Джеффри Рихтера "Windows для профессионалов"
    DLL уже загружается в чужой процесс. Единственное, не могу разобраться с "Перехватом API-вызовов с использованием раздела импорта".

    В Си я не специалист, только мельком его знаю. Для меня проще паскаль или асм.
    Переделал этот код в Паскал'евский.
    Код (Text):
    1. void ReplaceIATEntryInOneMod(PCSTR pszCalleeModName, PROC pfnCurrent, PROC pfnNew, HMODULE hmodCaller)
    2. {
    3.  
    4. ULONG ulSize;
    5.  
    6. PIMAGE_IMPORT_DESCRIPTOR pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR) ImageDirectoryEntryToData(hmodCallor, TRUE,IMAGE_DIRECTORY_ENTRY_IMPORT, &ulSize);
    7.  
    8. if (pImportDesc == NULL)
    9.  
    10. return,; // в этом модуле нет раздела импорта
    11.  
    12. // находим дескриптор раздела импорм со ссылками
    13. // на функции DLL (вызываемого модуля)
    14. for (; pImportDesc->Name; pImportDesc++)
    15. {
    16.  
    17. PSTR pszModName = (PSiR) ((PBYFE) hmodCaller + pImportDcsc->Name);
    18.  
    19. if (lstrcmpiA(pszModName, pszCalleeModName) == 0)
    20.  
    21. break;
    22.  
    23. }
    24.  
    25. if (pImportDesc->Name == 0)
    26.  
    27. // этот модуль не импортирует никаких функций из данной DLL return;
    28.  
    29. // получаем таблицу адресов импорта (IAT) для функций DLL PIMAGE_THUNK_DATA pThunk = (PIMAGE_THUNK_DATA) ((PBYTE} hirodCaller + pImportDesc->FirstThunk);
    30.  
    31. // заменяем адреса исходных функций адресами своих функций
    32. for (; pThunk->u1.Function; pThunk++)
    33. {
    34.  
    35. // получаем адрес адреса функции
    36. PROC* ppfn = (PROC*) &pThunk->u1.Function;
    37.  
    38. // та ли это функция, которая нас итересует?
    39. BOOL fFound = (*ppfn == pfnCurrent);
    40.  
    41. // см. текст программы-примера, в котором
    42. // содержится трюковый код для Windows 98
    43.  
    44. if (fFound)
    45. {
    46.  
    47. // адреса сходятся, изменяем адрес в разделе импорта
    48. WriteProcessMemory(GetCurrentProcess(), ppfn, &pfnNew, sizeof(pfnNew), NULL );
    49.  
    50. return; // получилось, выходим
    51.  
    52. }
    53.  
    54. }
    55.  
    56. // если мы попали сюда, значит, в разделе импорта
    57. // нет ссылки на нужную функцию
    58.  
    59. }
    Код (Text):
    1. Const
    2.   IMAGE_DIRECTORY_ENTRY_EXPORT       = 0;
    3.   IMAGE_DIRECTORY_ENTRY_IMPORT       = 1;
    4.   IMAGE_DIRECTORY_ENTRY_RESOURCE     = 2;
    5.   IMAGE_DIRECTORY_ENTRY_EXCEPTION    = 3;
    6.   IMAGE_DIRECTORY_ENTRY_SECURITY     = 4;
    7.   IMAGE_DIRECTORY_ENTRY_BASERELOC    = 5;
    8.   IMAGE_DIRECTORY_ENTRY_DEBUG        = 6;
    9.   IMAGE_DIRECTORY_ENTRY_COPYRIGHT    = 7;
    10.   IMAGE_DIRECTORY_ENTRY_GLOBALPTR    = 8;
    11.   IMAGE_DIRECTORY_ENTRY_TLS          = 9;
    12.   IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG  = 10;
    13.   IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT = 11;
    14.   IMAGE_DIRECTORY_ENTRY_IAT          = 12;
    15.   IMAGE_NUMBEROF_DIRECTORY_ENTRIES   = 16;
    16.  
    17.  
    18. Type
    19.   PIMAGE_IMPORT_DESCRIPTOR = ^IMAGE_IMPORT_DESCRIPTOR;
    20.   IMAGE_IMPORT_DESCRIPTOR = record
    21.     Characteristics: DWORD;
    22.     TimeDateStamp: DWORD;
    23.     ForwarderChain: DWORD;
    24.     Name1: DWORD;
    25.     FirstThunk: DWORD;
    26.   End;
    27.  
    28.   PIMAGE_IMPORT_BY_NAME = ^IMAGE_IMPORT_BY_NAME;
    29.   IMAGE_IMPORT_BY_NAME = record
    30.     Hint: WORD;
    31.     Name1: DWORD;
    32.   End;
    33.  
    34. Function ReplaceIATEntryInOneMod(pszCallModName: PChar; pfnCurrent, pfnNew: pointer;
    35.   hmodCaller: THandle): boolean;
    36. Var
    37.   ulSize: cardinal;
    38.   pImportDesc: PIMAGE_IMPORT_DESCRIPTOR;
    39.   pszModName: PChar;
    40.   pThunk: PIMAGE_IMPORT_BY_NAME;
    41.   ppfn: pointer;
    42.   bFound: boolean;
    43.   Temp: cardinal;
    44. Begin
    45.   Result := false;
    46.  
    47.   pImportDesc := ImageDirectoryEntryToData(hmodCaller, true,
    48.     IMAGE_DIRECTORY_ENTRY_IMPORT, ulSize);
    49.   IF pImportDesc = nil then
    50.     Exit;
    51.   While pImportDesc.Name1 <> 0 do
    52.   Begin
    53.     pszModName := pointer(hmodCaller + pImportDesc.Name1);
    54.     IF (lstrcmpiA(pszModName, pszCallModName) = 0) then
    55.       break;
    56.     Inc(pImportDesc, sizeof(pImportDesc));
    57.   End;
    58.   IF (pImportDesc.Name1 = 0) then
    59.     Exit;
    60.  
    61.   pThunk := pointer(hmodCaller + pImportDesc.FirstThunk);
    62.   While pThunk.Name1 <> 0 do
    63.   Begin
    64.     ppfn := pointer(pThunk^.Name1);
    65.     bFound := ppfn = pfnCurrent;
    66.     IF bFound then
    67.     Begin
    68.       WriteProcessMemory(GetCurrentProcess, ppfn, @pfnNew, sizeof(pfnNew), Temp);
    69.       Result := true;
    70.       break;
    71.     End;
    72.     Inc(pThunk, 4);
    73.   End;
    74. End;
    Пожалуйста, помогите найти ошибку. Вместо имеющихся 78 функций, импортируемых модулем из kernel32, код перебирает только 12. проверял.
     
  14. slavanap

    slavanap Вячеслав

    Публикаций:
    0
    Регистрация:
    10 сен 2008
    Сообщения:
    300
    Адрес:
    Смоленск, Россия
    весь импорт модуля, у которого планируется хукать функции:
     
  15. slavanap

    slavanap Вячеслав

    Публикаций:
    0
    Регистрация:
    10 сен 2008
    Сообщения:
    300
    Адрес:
    Смоленск, Россия
    странно, почему у меня одного файлы не прикрепляются?

    http://rghost.ru/267749
     
  16. Clerk

    Clerk Забанен

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

    bendme New Member

    Публикаций:
    0
    Регистрация:
    10 мар 2009
    Сообщения:
    179
    А с какими параметрами вызываешь свою функцию?
     
  18. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Clerk
    - я пони
    - обоснуйте
    (Ц) баш
     
  19. slavanap

    slavanap Вячеслав

    Публикаций:
    0
    Регистрация:
    10 сен 2008
    Сообщения:
    300
    Адрес:
    Смоленск, Россия
    bendme,
    Код (Text):
    1. Var
    2.   hMainModule: THandle;
    3.  
    4. Procedure Replace(module, func: string; pNew: pointer);
    5. Var
    6.   pOrig: pointer;
    7. Begin
    8.   pOrig := GetProcAddress(GetModuleHandle(PChar(module)), PChar(func));
    9.   ReplaceIATEntryInOneMod(PChar(module), pOrig, pNew, hMainModule);
    10. End;
    11.  
    12. Procedure Init;
    13. Begin
    14.   hMainModule := GetModuleHandle('EXE.EXE');
    15.   Replace('Kernel32.dll', 'CreateFileA', @New_CreateFileA);
    16.   Replace('Kernel32.dll', 'ReadFile', @New_ReadFile);
    17.   Replace('Kernel32.dll', 'WriteFile', @New_WriteFile);
    18.   Replace('Kernel32.dll', 'CloseHandle', @New_CloseHandle);
    19. End;
     
  20. slavanap

    slavanap Вячеслав

    Публикаций:
    0
    Регистрация:
    10 сен 2008
    Сообщения:
    300
    Адрес:
    Смоленск, Россия
    p.s. этот код в dll-шке, которая уже загружена в адресное пространство процесса-жертвы.