Перехват API функций, на примере MessageBoxA

Материал из DRKB

Перехват API функций, на примере MessageBoxA[править | править код]

DLL[править | править код]

library Mouse_mes;

uses
  sysutils,
  windows,
  messages;

type
  TImageImportDescriptor = packed record
    OriginalFirstThunk    : DWORD;
    TimeDateStamp         : DWORD;
    ForwarderChain        : DWORD;
    Name                  : DWORD;
    FirstThunk            : DWORD;
  end;
  PImageImportDescriptor = ^TImageImportDescriptor;

var
  filename: array[0..max_path-1] of Char;
  hook: HHook = 0;
  PEHeader: PImageNtHeaders;
  ImageBase: Cardinal;

function MyHookProcedure(hWnd: HWND; lpText, lpCaption: PWideChar; uType: UINT): Integer; stdcall;
begin
  Result := MessageBoxA(0, 'Notepad', 'my hook', 0);
  // Но уже через нашу табл. импорта
end;

procedure ProcessImports(PImports:PImageImportDescriptor);
var
  PImport: PImageImportDescriptor;
  PRVA_Import: LPDWORD;
  ProcAddress: Pointer;
  Temp_Cardinal: Cardinal;
begin
  ProcAddress := GetProcAddress(GetModuleHandle('USER32.DLL'), 'MessageBoxA');
  PImport := PImports;
  while PImport.Name <> 0 do
  begin
    PRVA_Import := LPDWORD(pImport.FirstThunk + ImageBase);
    while PRVA_Import^ <> 0 do
    begin
      if PPointer(PRVA_Import)^ = ProcAddress then
      begin
        VirtualProtect(PPointer(PRVA_Import), 4, PAGE_READWRITE, Temp_Cardinal);
        PPointer(PRVA_Import)^ := @MyHookProcedure; // пишем свою...
        VirtualProtect(PPointer(PRVA_Import), 4, Temp_Cardinal, Temp_Cardinal);
      end;
      Inc(PRVA_Import);
    end;
    Inc(PImport);
  end;
end;

procedure DllEntryPoint(reson: LongInt); stdcall;
begin
  case reson of
    DLL_PROCESS_ATTACH:
    begin
      DisableThreadLibraryCalls(hInstance);
      ZeroMemory(@FileName, SizeOf(FileName));
      GetModuleFileName(GetModuleHandle(nil), @FileName, SizeOf(FileName));
      // сейчас я хочу попробовать все это дело над нотепадом
      if Pos('NOTEPAD.EXE', AnsiUpper(@FileName)) <> 0 then
      begin
        ImageBase := GetModuleHandle(nil);
        PEHeader := Pointer(Int64(ImageBase) + PImageDosHeader(ImageBase)._lfanew); // pe header
        ProcessImports(Pointer(PEHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress + ImageBase));
      end;
    end;
  end;
end;

function NextHook(code: Integer; wParam, lParam: LongInt): LongInt; stdcall;
begin
  Result := CallNextHookEx(hook, code, wParam, lParam);
end;

procedure SetHook(flag: Bool); export; stdcall;
begin
  if flag then
    hook := SetWindowsHookEx(wh_getmessage, @NextHook, hInstance, 0)
  else
  begin
    UnhookWindowsHookEx(hook);
    hook := 0;
  end;
end;

exports SetHook;

begin
  DLLProc := @DllEntryPoint;
  DllEntryPoint(DLL_PROCESS_ATTACH);
end.


EXE[править | править код]

program Project2;

uses windows;

var
  SetHook: procedure(flag: Bool) stdcall;
  hDll: hModule;

begin
  hDll := LoadLibrary('Mouse_mes.dll');
  @SetHook := GetProcAddress(hDll, 'SetHook');
  SetHook(True);
  MessageBox(0, 'Не закрывай, пока идет работа', '', 0);
  SetHook(False);
  FreeLibrary(hDll);
end.



Author: Song
Source: Взято из http://forum.sources.ru
ID: 02219