delphimonkeypatching

Patch routine call in delphi


I want to patch a routine call to be able to handle it myself with some modifications. I am writing a resource loader. I want to patch the Delphi's LoadResourceModule and InitInheritedComponent routines with that of mine. I have checked PatchAPI call in MadExcept.pas unit, but couldn't figure it out if i can use that for my project.

I want something like

my exe at runtime calls -> LoadResourceModule -> jump to -> MyCustomResourceModule...

Any pointers on this would be very helpful.


Solution

  • I use the following code:

    procedure PatchCode(Address: Pointer; const NewCode; Size: Integer);
    var
      OldProtect: DWORD;
    begin
      if VirtualProtect(Address, Size, PAGE_EXECUTE_READWRITE, OldProtect) then 
      begin
        Move(NewCode, Address^, Size);
        FlushInstructionCache(GetCurrentProcess, Address, Size);
        VirtualProtect(Address, Size, OldProtect, @OldProtect);
      end;
    end;
    
    type
      PInstruction = ^TInstruction;
      TInstruction = packed record
        Opcode: Byte;
        Offset: Integer;
      end;
    
    procedure RedirectProcedure(OldAddress, NewAddress: Pointer);
    var
      NewCode: TInstruction;
    begin
      NewCode.Opcode := $E9;//jump relative
      NewCode.Offset := NativeInt(NewAddress)-NativeInt(OldAddress)-SizeOf(NewCode);
      PatchCode(OldAddress, NewCode, SizeOf(NewCode));
    end;
    

    You would implement your hook/patch/detour by calling RedirectProcedure:

    RedirectProcedure(@LoadResourceModule, @MyLoadResourceModule);
    

    This will work for 32 bit code. It will also work for 64 bit code provided that both the old and new functions reside in the same executable module. Otherwise the jump distance may exceed the range of a 32 bit integer.

    I'd be very interested if somebody could provide an alternative that worked for 64 bit address space irrespective of how far apart the two addresses were.