eXeLab
eXeL@B ВИДЕОКУРС !

ВИДЕОКУРС ВЗЛОМ
выпущен 12 ноября!


УЗНАТЬ БОЛЬШЕ >>
Домой | Статьи | RAR-cтатьи | FAQ | Форум | Скачать | Видеокурс
Новичку | Ссылки | Программирование | Интервью | Архив | Связь

Русский / Russian English / Английский

Сейчас на форуме: (+2 невидимых)
 · Начало · Статистика · Регистрация · Поиск · ПРАВИЛА ФОРУМА · Язык · RSS · SVN ·

 eXeL@B —› Вопросы новичков —› Про перехват API функции
Посл.ответ Сообщение

Ранг: 0.4 (гость)
Статус: Участник

Создано: 2 марта 2018 17:07 New!
Цитата · Личное сообщение · #1

Перехватываю функцию так
Code:
  1. function ReplaceIATEntry(const OldProc, NewProc: FARPROC): Boolean;
  2. var
  3.   ImportEntry: PImageImportDescriptor;
  4.   Thunk: PImageThunkData;
  5.   Protect: DWORD;
  6.   ImageBase: Cardinal;
  7.   DOSHeader: PImageDosHeader;
  8.   NTHeader: PImageNtHeaders;
  9. begin
  10.   Result := False;
  11.   if OldProc = nil then Exit;
  12.   if NewProc = nil then Exit;
  13.   ImageBase := GetModuleHandle(nil);
  14.  
  15.   // Получаем адрес таблицы импорта
  16.   DOSHeader := PImageDosHeader(ImageBase);
  17.   NTHeader := PImageNtHeaders(DWORD(DOSHeader) + DWORD(DOSHeader^._lfanew));
  18.   ImportEntry := PImageImportDescriptor(DWORD(ImageBase) +
  19.       DWORD(NTHeader^.OptionalHeader.DataDirectory[
  20.       IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress));
  21.  
  22.   // Бежим по записям таблицы ...
  23.   while ImportEntry^.Name <> 0 do
  24.   begin
  25.     Thunk := PImageThunkData(DWORD(ImageBase) +
  26.       DWORD(ImportEntry^.FirstThunk));
  27.     // ... пока таблица не кончится ...
  28.     while Pointer(Thunk^._function) <> nil do
  29.     begin
  30.       // ... или не найдем нужную нам запись.
  31.       if Pointer(Thunk^._function) = OldProc then
  32.       begin
  33.         // Производим подмену
  34.         if VirtualProtect(@Thunk^._function, SizeOf(DWORD),
  35.           PAGE_EXECUTE_READWRITE, Protect) then
  36.         try
  37.           // Можно вот так...
  38.           //Thunk^._function := DWORD(NewProc);
  39.           // ... но лучше атомарно.
  40.           InterlockedExchange(Integer(Thunk^._function), Integer(NewProc));
  41.           Result := True;
  42.         finally
  43.           VirtualProtect(@Thunk^._function, SizeOf(DWORD), Protect, Protect);
  44.           FlushInstructionCache(GetCurrentProcess, @Thunk^._function, SizeOf(DWORD));
  45.         end;
  46.       end
  47.       else
  48.         Inc(PAnsiChar(Thunk), SizeOf(TImageThunkData32));
  49.     end;
  50.     ImportEntry := Pointer(Integer(ImportEntry) + SizeOf(TImageImportDescriptor));
  51.   end;
  52. end;
  53.  
  54. var
  55.   OrigAddr: Pointer = nil;
  56.  
  57. function InterceptedHttpSendRequestW(hRequest: HINTERNET; lpszHeaders: PWideChar;
  58.                                   dwHeadersLength: DWORD; lpOptional: Pointer;
  59.                                   dwOptionalLength: DWORD): BOOL; stdcall;
  60. type
  61.   TOrigHttpSendRequestW = function(hRequest: HINTERNET; lpszHeaders: PWideChar;
  62.                                   dwHeadersLength: DWORD; lpOptional: Pointer;
  63.                                   dwOptionalLength: DWORD): BOOL; stdcall;
  64. var
  65.   S: AnsiString;
  66.   NewHeaders:PWideChar;
  67. begin
  68.  NewHeaders:= lpszHeaders;
  69.  Result := TOrigHttpSendRequestW(OrigAddr)(hRequest, NewHeaders, length(NewHeaders), lpOptional, dwOptionalLength);
  70. end;
  71.  
  72. procedure TForm1.Button2Click(Sender: TObject);
  73. begin
  74. HttpSendRequest(0,'',0,0,0);
  75. end;
  76.  
  77. procedure TForm1.FormCreate(Sender: TObject);
  78. begin
  79.   OrigAddr := GetProcAddress(GetModuleHandle('wininet.dll'), 'HttpSendRequestW');
  80.   ReplaceIATEntry(OrigAddr, @InterceptedHttpSendRequestW);
  81. end;

При нажатии на кнопку - перехват работает норм. Но когда функция выполняется через TShockwaveFlash (там находится flash видеоплеер), функция не перехватывается. Как можно отловить эту функцию, которую вызывает плеер?

Ранг: 97.8 (постоянный)
Статус: Участник

Создано: 2 марта 2018 18:02 New!
Цитата · Личное сообщение · #2

А, декомпилятор delphi вам не подходит?

Ранг: 0.4 (гость)
Статус: Участник

Создано: 2 марта 2018 18:10 New!
Цитата · Личное сообщение · #3

Скажите пжлста... Как декомпилятор delphi может помочь?

Ранг: 271.6 (наставник)
Статус: Модератор
CrackLab

Создано: 2 марта 2018 18:33 New!
Цитата · Личное сообщение · #4

TelFon а ты уверен что эта апи должна дергаться через таблицу импорта?

Ранг: 0.4 (гость)
Статус: Участник

Создано: 2 марта 2018 18:53 New!
Цитата · Личное сообщение · #5

Есть такие подозрения. Если я убираю HttpSendRequest(0,'',0,0,0);, то функция HttpSendRequestW будет отсутствовать в импортах, а запрос все равно проходит. Прога загружает Flash32_25_0_0_171.ocx. Но там отсутствует эта функция. Я начинаю подозревать что его вызывает библиотека, или эта же .ocx. Помогите разобраться.

Ранг: 271.6 (наставник)
Статус: Модератор
CrackLab

Создано: 2 марта 2018 19:24 New!
Цитата · Личное сообщение · #6

не нужно тебе патчить иат, возьми апи монитор для начала, узнай какие апи тебе надо хукнуть.
а потом написать нормальный код, чтоб кровь с глаз не шла и он работал, либо взять готовый двиг для перехвата коих полно


Ранг: 512.2 (!)
Статус: Участник
оптимист

Создано: 3 марта 2018 02:51 · Поправил: ClockMan New!
Цитата · Личное сообщение · #7

Code:
  1. // Производим подмену
  2.         if VirtualProtect(@Thunk^._function, SizeOf(DWORD),

еслиб так просто всё было
сделай обычный jmp в айпишке, или через железку сделай

Ранг: 32.2 (посетитель)
Статус: Участник

Создано: 3 марта 2018 09:20 New!
Цитата · Личное сообщение · #8

ClockMan пишет:
сделай обычный jmp в айпишке

Или лучше прыжок через стек
Code:
  1. push address
  2. ret

Так высчитывать jmp не надо

Ранг: 0.4 (гость)
Статус: Участник

Создано: 3 марта 2018 11:52 New!
Цитата · Личное сообщение · #9

ClockMan пишет:
сделай обычный jmp в айпишке, или через железку сделай

BlackCode пишет:
Или лучше прыжок через стек


Можно по подробнее. Может наглядный пример есть?

Ранг: 32.2 (посетитель)
Статус: Участник

Создано: 3 марта 2018 12:27 New!
Цитата · Личное сообщение · #10

TelFon пишет:
Можно по подробнее. Может наглядный пример есть?


Code:
  1. SetApiFixedHookGlobal proto :dword,:dword,:dword
  2.  
  3. .code
  4.  
  5. SetApiFixedHookGlobal proc uses ebx ecx edx esi edi lpszModuleName,lpszApiName,lpNewProc
  6.  
  7.     local OldProtect:dword
  8.     local hModule:dword
  9.     
  10.     mov hModule,FUNC(GetModuleHandle,lpszModuleName)
  11.     .if hModule == 0
  12.         mov hModule,FUNC(LoadLibrary,lpszModuleName)
  13.         .if hModule == 0
  14.             ret
  15.         .endif
  16.     .endif
  17.     mov ebx,FUNC(GetProcAddress,hModule,lpszApiName)
  18.     .if ebx == 0
  19.         ret
  20.     .endif
  21.     invoke VirtualProtect,ebx,6,PAGE_READWRITE,addr OldProtect
  22.     mov byte ptr[ebx],68h
  23.     mov eax,lpNewProc
  24.     mov dword ptr[ebx+1],eax
  25.     mov byte ptr[ebx+1+4],0C3h
  26.     invoke VirtualProtect,ebx,6,OldProtect,addr OldProtect
  27.     ret
  28.  
  29. SetApiFixedHookGlobal endp


Ранг: 281.5 (наставник)
Статус: Участник

Создано: 4 марта 2018 00:47 New!
Цитата · Личное сообщение · #11

BlackCode
А исходные 6 байт перехватываемой функи кто восстанавливать будет?
не всегда там
mov edi, edi
push ebp
mob ebp, esp

И вместо 6 байт, 5 вполне хватило бы - jmp lpNewProc - (FUNC(GetProcAddress,hModule,lpszApiName) + 5)

Ранг: 32.2 (посетитель)
Статус: Участник

Создано: 4 марта 2018 07:10 New!
Цитата · Личное сообщение · #12

DenCoder пишет:
А исходные 6 байт перехватываемой функи кто восстанавливать будет?

Волшебное слово "Fixed" в названии функции "SetApiFixedHookGlobal" говорит о фиксированном хуке, который ставится один раз и присутствует постоянно, до завершения процесса.
DenCoder пишет:
И вместо 6 байт, 5 вполне хватило бы - jmp lpNewProc - (FUNC(GetProcAddress,hModule,lpszApiName) + 5)

Это моя реализация и я так захотел.


Ранг: 264.9 (наставник)
Статус: Участник

Создано: 8 марта 2018 13:20 · Поправил: difexacaw New!
Цитата · Личное сообщение · #13

TelFon

Вы долго будите разбираться в этом, тема заезжена до дыр". Для корректного изменения кода вам нужен будет морфер(конструктор). Который пересобирает код в буфер, а сама модификация кода должна происходить атомарно(cmpxchg). Никаким иным образом данная задача не решается, увы. Тем более на 64, где релатив адресация.)

ps: дельфи не лучший яп, он считается унылым говном и не просто так.
 eXeL@B —› Вопросы новичков —› Про перехват API функции

Оригинальный DVD-ROM: eXeL@B DVD !

Вы находитесь на форуме сайта EXELAB.RU
Проект ReactOS