Parsi Coders
IAT Hooking Example - نسخه قابل چاپ

+- Parsi Coders (http://parsicoders.com)
+-- انجمن: Software Development Programming (http://parsicoders.com/forumdisplay.php?fid=37)
+--- انجمن: Pascal/Delphi (http://parsicoders.com/forumdisplay.php?fid=45)
+---- انجمن: Delphi (http://parsicoders.com/forumdisplay.php?fid=69)
+---- موضوع: IAT Hooking Example (/showthread.php?tid=1104)



IAT Hooking Example - Amin_Mansouri - 10-17-2011

کد:
{*******************************************************}
{                                                       }
{  EvilSoftIATHook.pas                                  }
{  www.EvilSoft.de                                      }
{                                                       }
{*******************************************************}

unit EvilSoftIATHook;

interface

uses
  Windows;

function IATHook(DLL, FuncName: PAnsiChar; CallbackFunction: Pointer):Pointer;
function IATUnHook(CallbackFunction, OldFunction: Pointer):Boolean;

implementation

type

IMAGE_IMPORT_DESCRIPTOR = record
  OriginalFirstThunk: DWORD;
  TimeDateStamp: DWORD;
  ForwarderChain: DWORD;
  Name: DWORD;
  FirstThunk: DWORD;
end;
PIMAGE_IMPORT_DESCRIPTOR = ^IMAGE_IMPORT_DESCRIPTOR;


function ChangePointers(pFrom,pTo:Pointer):Boolean;
var
  pImportDir: PIMAGE_IMPORT_DESCRIPTOR;
  Base,Size,OldProtect,Process,Module: DWORD;

  pThunk: PDWORD;

  ImageDirectoryEntryToData : function(Base: Pointer; MappedAsImage: ByteBool;
    DirectoryEntry: Word; var Size: ULONG): PIMAGE_IMPORT_DESCRIPTOR; stdcall;
begin
  Result := False;

  Module := LoadLibrary('IMAGEHLP.DLL');
  @ImageDirectoryEntryToData := GetProcAddress(Module,
    'ImageDirectoryEntryToData');
  if not Assigned(ImageDirectoryEntryToData) then
    Exit;
  Process := GetCurrentProcess;
  if Process = 0 then
    Exit;
  {$WARNINGS OFF}
  Base := GetModuleHandle(0);
  {$WARNINGS ON}
  if Base = 0 then
    Exit;
  pImportDir := ImageDirectoryEntryToData(Pointer(Base),True,
    IMAGE_DIRECTORY_ENTRY_IMPORT,Size);
  FreeLibrary(Module);
  while pImportDir^.Name <> 0 do
  begin
    pThunk := Pointer(Base + pImportDir^.FirstThunk);
    while pThunk^ <> 0 do
    begin
      if pthunk^ = DWORD(pFrom)  then
      begin
        if VirtualProtectEx(Process,pThunk,SizeOf(Pointer),
          PAGE_EXECUTE_READWRITE,@OldProtect) then
        begin
          try
            pThunk^ := DWORD(pTo);
            Result := True;
          finally
            VirtualProtectEx(Process, pThunk, SizeOf(Pointer), OldProtect,
              @OldProtect);
          end;
        end;
      end;
      inc(pThunk);
    end;
    inc(PImportDir);
  end;
end;

function IATHook(DLL, FuncName: PAnsiChar; CallbackFunction: Pointer):Pointer;
var
  OriginalFunction: Pointer;
begin
  Result := nil;
  OriginalFunction := GetProcAddress(GetModuleHandle(@String(DLL)[1]), FuncName);
  if not Assigned(OriginalFunction) then
    Exit;
  if not Assigned(CallbackFunction) then
    Exit;
  if ChangePointers(OriginalFunction, CallbackFunction) then
    Result := OriginalFunction;
end;

function IATUnHook(CallbackFunction, OldFunction: Pointer):Boolean;
begin
  Result := ChangePointers(CallbackFunction, OldFunction);
end;


end.

کد:
library Hook;

uses
  Windows,
  EvilSoftIATHook;

var
  Old_MessageBoxA : function(hWnd: Cardinal; lpText, lpCaption: PAnsiChar;
    uType: UINT): Integer; stdcall = nil;

function Callback_MessageBoxA(hWnd: Cardinal; lpText, lpCaption: PAnsiChar;
  uType: UINT): Integer; stdcall;
begin
  lpCaption := @AnsiString('[Hooked]'+lpCaption+'[/Hooked]')[1];
  lpText    := @AnsiString('[Hooked]'+lpText+'[/Hooked]')[1];
  Result := Old_MessageBoxA(hWnd, lpText, lpCaption, uType);
end;

procedure inject;
begin
  @Old_MessageBoxA := IATHook('User32.dll', 'MessageBoxA', @Callback_MessageBoxA);
end;

procedure uninject;
begin
  if Assigned(Old_MessageBoxA) then
    IATUnHook(@Callback_MessageBoxA, @Old_MessageBoxA);
end;

procedure dllmain(dwReason: integer);
begin
  case dwreason of
    DLL_PROCESS_ATTACH:
      inject;
    DLL_PROCESS_DETACH:
      uninject;
  end;
end;

begin
  DLLProc := @DLLMain;
  DLLMain(1);
end.