Thema: Delphi Mutex Hooken

Einzelnen Beitrag anzeigen

API

Registriert seit: 18. Apr 2004
637 Beiträge
 
#1

Mutex Hooken

  Alt 17. Feb 2008, 08:00
Guten Morgen

Ich probiere gerade die CreateMutex API zu hooken doch leider wird meine Ersatz Funktion nicht aufgerufen. Bei anderen APIs hingegen funktioniert es.
Habe ich vielleicht etwas bersehen?

Hier mal die eigentliche HookUnit. Den Rest des Codes ist in der Anlage zu finden.


Delphi-Quellcode:
unit HookUnit;

interface

uses
  Windows, PEStuff, Classes;

type
  TCreateMutex = function(lpMutexAttributes: PSecurityAttributes; bInitialOwner: BOOL; lpName: PChar): THandle; stdcall;
  TCreateMutexA = function(lpMutexAttributes: PSecurityAttributes; bInitialOwner: BOOL; lpName: PAnsiChar): THandle; stdcall;
  //Todo: TCreateMutexW ...

  PPointer = ^Pointer;

  TImportCode = packed record
    JumpInstruction: word; // should be $25FF
    AddressOfPointerToFunction: PPointer;
  end;
  PImportCode = ^TImportCode;

procedure HookFunctions;
procedure UnHookFunctions;

implementation

var
  OldCreateMutex: TCreateMutex = nil;
  OldCreateMutexA: TCreateMutexA = nil;


function NewCreateMutex(lpMutexAttributes: PSecurityAttributes; bInitialOwner: BOOL; lpName: PChar): THandle; stdcall;
begin
  Result := 0;
  if Windows.MessageBox(0, lpName, '[CreateMutex Hooked]', MB_OKCANCEL) = IDOK then
    Result := OldCreateMutex(lpMutexAttributes, bInitialOwner, lpName);
end;

function NewCreateMutexA(lpMutexAttributes: PSecurityAttributes; bInitialOwner: BOOL; lpName: PAnsiChar): THandle; stdcall;
begin
  Result := 0;
  if Windows.MessageBox(0, lpName, '[CreateMutexA Hooked]', MB_OKCANCEL) = IDOK then
    Result := OldCreateMutexA(lpMutexAttributes, bInitialOwner, lpName);
end;

function PointerToFunctionAddress(Code: Pointer): PPointer;
var
  func: PImportCode;
begin
  Result := nil;
  if Code = nil then Exit;
  try
    func := code;
    if (func.JumpInstruction = $25FF) then
    begin
      Result := func.AddressOfPointerToFunction;
    end;
  except
    Result := nil;
  end;
end;

function FinalFunctionAddress(Code: Pointer): Pointer;
var
  func: PImportCode;
begin
  Result := Code;
  if Code = nil then Exit;
  try
    func := code;
    if (func.JumpInstruction = $25FF) then
    begin
      Result := func.AddressOfPointerToFunction^;
    end;
  except
    Result := nil;
  end;
end;


function PatchAddress(OldFunc, NewFunc: Pointer): integer;
var
  BeenDone: TList;

  function PatchAddressInModule(hModule: THandle; OldFunc, NewFunc: Pointer): integer;
  var
    Dos: PImageDosHeader;
    NT: PImageNTHeaders;
    ImportDesc: PImage_Import_Entry;
    rva: DWORD;
    Func: PPointer;
    DLL: string;
    f: Pointer;
    written: DWORD;
  begin
    Result := 0;
    Dos := Pointer(hModule);
    if BeenDone.IndexOf(Dos) >= 0 then Exit;
    BeenDone.Add(Dos);
    OldFunc := FinalFunctionAddress(OldFunc);
    if IsBadReadPtr(Dos, SizeOf(TImageDosHeader)) then Exit;
    if Dos.e_magic <> IMAGE_DOS_SIGNATURE then Exit;
    NT := Pointer(integer(Dos) + dos._lfanew);
    // if IsBadReadPtr(NT,SizeOf(TImageNtHeaders)) then exit;

    RVA := NT^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;

    if RVA = 0 then Exit;
    ImportDesc := Pointer(integer(Dos) + RVA);
    while (ImportDesc^.Name <> 0) do
    begin
      DLL := PChar(integer(Dos) + ImportDesc^.Name);
      PatchAddressInModule(GetModuleHandle(PChar(DLL)), OldFunc, NewFunc);
      Func := Pointer(integer(DOS) + ImportDesc.LookupTable);
      while Func^ <> nil do
      begin
        f := FinalFunctionAddress(Func^);
        if f = OldFunc then
        begin
          WriteProcessMemory(GetCurrentProcess, Func, @NewFunc, 4, written);
          if Written > 0 then Inc(Result);
        end;
        Inc(Func);
      end;
      Inc(ImportDesc);
    end;
  end;
begin
  BeenDone := TList.Create;
  try
    Result := PatchAddressInModule(GetModuleHandle(nil), OldFunc, NewFunc);
  finally
    BeenDone.Free;
  end;
end;

procedure HookFunctions;
begin
  if @OldCreateMutex = nil then
    @OldCreateMutex := FinalFunctionAddress(@CreateMutex);

  if @OldCreateMutexA = nil then
    @OldCreateMutexA := FinalFunctionAddress(@CreateMutexA);

  PatchAddress(@OldCreateMutex, @NewCreateMutex);
  PatchAddress(@OldCreateMutexA, @NewCreateMutexA);
end;

procedure UnhookFunctions;
begin
  if @OldCreateMutex <> nil then
    PatchAddress(@NewCreateMutex, @OldCreateMutex);
  if @OldCreateMutexA <> nil then
    PatchAddress(@NewCreateMutexA, @OldCreateMutexA);
end;

initialization

finalization
  UnhookFunctions;
end.
Angehängte Dateien
Dateityp: zip mutexhook_110.zip (224,4 KB, 17x aufgerufen)
  Mit Zitat antworten Zitat