Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Помогите с кодом


Автор: Delphist 20.4.2004, 10:17
Я специально создал новую тему опять же про "Внедрением Dll и перехват Api функций",но несколько
иного характера.Поговорим про статью "Перехват API-функций в Windows NT/2000/XP"
(Кто бы мог перевести все исходники этой статьи"Перехват API-функций в Windows NT/2000/XP"
(если надо скинуть обращайтесь на Delphi71@yandex.ru)
на Delphi. И привести примеры на Delphi(с хорошими комментариями)по внедрению Dll в чужие процесы
всеми с пособами (через Хуки записью короткого участка машинного кода в память процесса))
Я перевел исходник на Delphi из пункта:"Перехват API непосредственной записью в код системной
функции" вот результат: MyDll.dll
Код
library WinApi_Hook;
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls,ShellApi;
{$R *.res}
Type
jmp_far = record
    instr_push:BYTE; //здесь будет код инструкции push
    arg:Dword;       //аргумент push
    instr_ret:BYTE;  //здесь будет код инструкции ret
    end;
Var
  old:Array[1..6]of BYTE; //область для хранения 6-ти затираемых байт начала функции
  adr_MessageBoxA:LongInt;  //будущий адрес оригинальной функции
  written:Dword;          //вспомогательная переменная
  jump:jmp_far;           //здесь будет машинный код инструкции перехода
  hModule:THANDLE;
  lpReserved:Pointer;
  S:PChar;
Function Intercept_MessageBoxA(hWnd: HWND; lpText, lpCaption: PChar; uType: UINT): Integer; stdcall;
//Var S:PAnsiChar;
Begin
{Сначала восстанавливаем 6 первых байт функции. Это не обязательное
действие, просто мы решили подшутить над пользователем, и все
сообщения функции MessageBoxA переделать на свои, поэтому нам придется
вызвать оригинальную функцию, а для этого следует восстановить ее адрес:}
WriteProcessMemory(GetCurrentProcess(), @adr_MessageBoxA,@old, 6,
written);
S := 'Перехват удался!!!';
//Вызываем оригинальную функцию через указатель
MessageBox(0,S,'MessageBox',MB_OK);
  //Снова заменяем  6 байт функции на команду перехода на нашу функцию
WriteProcessMemory(GetCurrentProcess(), @adr_MessageBoxA,
                     @jump, 6,written);
end;
Procedure InterceptFunctions;
Begin
  //сначала получим абсолютный адрес функции для перехвата
  adr_MessageBoxA := Dword(GetProcAddress(GetModuleHandle('user32.dll'),
                    'MessageBoxA'));
  if adr_MessageBoxA = 0 then
  begin
     MessageBox(0, 'Can`t get adr_MessageBoxA', 'Error!', 0);
     exit;
  end;
  // Зададим машинный код инструкции перехода, который затем впишем
  // в начало полученного адреса:
  jump.instr_push:= $68;
  jump.arg:= Dword(@Intercept_MessageBoxA);
  jump.instr_ret:=$C3 ;

//Прочитаем и сохраним первые оригинальные 6 байт стандартной API функции
ReadProcessMemory(GetCurrentProcess(), @adr_MessageBoxA,
                    @old, 6, written);
//Запишем команду перехода на нашу функцию поверх этих 6-ти байт
  WriteProcessMemory(GetCurrentProcess(), @adr_MessageBoxA,
     @jump, 6, written);
end;
Function DllMain(hModule:THANDLE;ul_reason_for_call:LongInt;Var
                       lpReserved:Pointer):BOOL;
{ Если система подключает DLL к какому-либо процессу,
 она сначала вызовет главную функцию DLL с параметром
 DLL_PROCESS_ATTACH, на что мы сразу вызовем нашу функцию
 InterceptFunctions, которая произведет подмену стандартной API функции
 MessageBoxA нашей функцией Intercept_MessageBoxA (см. ниже)}
begin
  if ul_reason_for_call = DLL_PROCESS_ATTACH
  then begin
        InterceptFunctions;
        Result:=TRUE
        end
  else begin ShowMessage('WinApi_Hook - не удалось загрузить');
       Result:=False;end;
end;
exports InterceptFunctions;
begin
DLLProc:= @DllMain;
DllMain(hModule,DLL_PROCESS_ATTACH,lpReserved)
end.

Подключаю я эту (MyDll.dll) к своей проге в которой по нажатию выдается сообщение
MessageBox(0,'HelloWorld','Information',0), и оно не перехватывается.
--------
С чего начал тем и закончу:
Вообщем кто бы мог перевести все исходники этой статьи"Перехват API-функций в Windows NT/2000/XP"
(если надо скинуть обращайтесь на Delphi71@yandex.ru)
на Delphi. И привести примеры на Delphi(с хорошими комментариями)по внедрению Dll в чужие процесы
всеми с пособами (через hook'и записью короткого участка машинного кода в память процесса)

Автор: Pathfider 3.1.2005, 22:38
Погляди в Арсенале пост RAdmin'а - ApiHook(архив). Именно то, чо ты ищешь, правда я и сам в нем разобраться не могу smile

Автор: dm9 4.1.2005, 01:24
smile
Delphist, постарайся пользоваться тэгами [ code ], если не сложно. Для этого надо нажать кнопку "Код" smile  

Вот так лучше же...

Код
library WinApi_Hook;
uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
 StdCtrls,ShellApi;
{$R *.res}
Type
jmp_far = record
   instr_push:BYTE; //здесь будет код инструкции push
   arg:Dword;       //аргумент push
   instr_ret:BYTE;  //здесь будет код инструкции ret
   end;
Var
 old:Array[1..6]of BYTE; //область для хранения 6-ти затираемых байт начала функции
 adr_MessageBoxA:LongInt;  //будущий адрес оригинальной функции
 written:Dword;          //вспомогательная переменная
 jump:jmp_far;           //здесь будет машинный код инструкции перехода
 hModule:THANDLE;
 lpReserved:Pointer;
 S:PChar;
Function Intercept_MessageBoxA(hWnd: HWND; lpText, lpCaption: PChar; uType: UINT): Integer; stdcall;
//Var S:PAnsiChar;
Begin
{Сначала восстанавливаем 6 первых байт функции. Это не обязательное
действие, просто мы решили подшутить над пользователем, и все
сообщения функции MessageBoxA переделать на свои, поэтому нам придется
вызвать оригинальную функцию, а для этого следует восстановить ее адрес:}
WriteProcessMemory(GetCurrentProcess(), @adr_MessageBoxA,@old, 6,
written);
S := 'Перехват удался!!!';
//Вызываем оригинальную функцию через указатель
MessageBox(0,S,'MessageBox',MB_OK);
 //Снова заменяем  6 байт функции на команду перехода на нашу функцию
WriteProcessMemory(GetCurrentProcess(), @adr_MessageBoxA,
                    @jump, 6,written);
end;
Procedure InterceptFunctions;
Begin
 //сначала получим абсолютный адрес функции для перехвата
 adr_MessageBoxA := Dword(GetProcAddress(GetModuleHandle('user32.dll'),
                   'MessageBoxA'));
 if adr_MessageBoxA = 0 then
 begin
    MessageBox(0, 'Can`t get adr_MessageBoxA', 'Error!', 0);
    exit;
 end;
 // Зададим машинный код инструкции перехода, который затем впишем
 // в начало полученного адреса:
 jump.instr_push:= $68;
 jump.arg:= Dword(@Intercept_MessageBoxA);
 jump.instr_ret:=$C3;

//Прочитаем и сохраним первые оригинальные 6 байт стандартной API функции
ReadProcessMemory(GetCurrentProcess(), @adr_MessageBoxA,
                   @old, 6, written);
//Запишем команду перехода на нашу функцию поверх этих 6-ти байт
 WriteProcessMemory(GetCurrentProcess(), @adr_MessageBoxA,
    @jump, 6, written);
end;
Function DllMain(hModule:THANDLE;ul_reason_for_call:LongInt;Var
                      lpReserved:Pointer):BOOL;
{ Если система подключает DLL к какому-либо процессу,
она сначала вызовет главную функцию DLL с параметром
DLL_PROCESS_ATTACH, на что мы сразу вызовем нашу функцию
InterceptFunctions, которая произведет подмену стандартной API функции
MessageBoxA нашей функцией Intercept_MessageBoxA (см. ниже)}
begin
 if ul_reason_for_call = DLL_PROCESS_ATTACH
 then begin
       InterceptFunctions;
       Result:=TRUE
       end
 else begin ShowMessage('WinApi_Hook - не удалось загрузить');
      Result:=False;end;
end;
exports InterceptFunctions;
begin
DLLProc:= @DllMain;
DllMain(hModule,DLL_PROCESS_ATTACH,lpReserved)
end.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)