How to make FastCodePatch work in Delphi XE2 Win64 platform?

前端 未结 2 2014
星月不相逢
星月不相逢 2021-02-08 05:10

Unit FastCodePatch.pas works in Win32 platform. Delphi XE2 supports Win64 platform, any ideas how to make FastCodePatch works in Win64 platform?

unit FastcodePa         


        
2条回答
  •  南笙
    南笙 (楼主)
    2021-02-08 05:33

    The following code works for both Win32 - Standalone and Package, Win64 - Standalone and Package:

    type
      TNativeUInt = {$if CompilerVersion < 23}Cardinal{$else}NativeUInt{$ifend};
    
      PJump = ^TJump;
      TJump = packed record
        OpCode: Byte;
        Distance: integer;
      end;
    
    function GetActualAddr(Proc: Pointer): Pointer;
    type
      PAbsoluteIndirectJmp = ^TAbsoluteIndirectJmp;
      TAbsoluteIndirectJmp = packed record
        OpCode: Word;   //$FF25(Jmp, FF /4)
        Addr: Cardinal;
      end;
    var J: PAbsoluteIndirectJmp;
    begin
      J := PAbsoluteIndirectJmp(Proc);
      if (J.OpCode = $25FF) then
        {$ifdef Win32}Result := PPointer(J.Addr)^{$endif}
        {$ifdef Win64}Result := PPointer(TNativeUInt(Proc) + J.Addr + 6{Instruction Size})^{$endif}
      else
        Result := Proc;
    end;
    
    procedure FastcodeAddressPatch(const ASource, ADestination: Pointer);
    const
      Size = SizeOf(TJump);
    var
      NewJump: PJump;
      OldProtect: Cardinal;
      P: Pointer;
    begin
      P := GetActualAddr(ASource);
      if VirtualProtect(P, Size, PAGE_EXECUTE_READWRITE, OldProtect) then
      begin
        NewJump := PJump(P);
        NewJump.OpCode := $E9;
        NewJump.Distance := TNativeUInt(ADestination) - TNativeUInt(P) - Size;
    
        FlushInstructionCache(GetCurrentProcess, P, SizeOf(TJump));
        VirtualProtect(P, Size, OldProtect, @OldProtect);
      end;
    end;
    

提交回复
热议问题