How to make FastCodePatch work in Delphi XE2 Win64 platform?

匿名 (未验证) 提交于 2019-12-03 02:48:02

问题:

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

unit FastcodePatch;  interface  function FastcodeGetAddress(AStub: Pointer): Pointer; procedure FastcodeAddressPatch(const ASource, ADestination: Pointer);  implementation  uses   Windows;  type   PJump = ^TJump;   TJump = packed record     OpCode: Byte;     Distance: Pointer;   end;  function FastcodeGetAddress(AStub: Pointer): Pointer; begin   if PBYTE(AStub)^ = $E8 then   begin     Inc(Integer(AStub));     Result := Pointer(Integer(AStub) + SizeOf(Pointer) + PInteger(AStub)^);   end   else     Result := nil; end;  procedure FastcodeAddressPatch(const ASource, ADestination: Pointer); const   Size = SizeOf(TJump); var   NewJump: PJump;   OldProtect: Cardinal; begin   if VirtualProtect(ASource, Size, PAGE_EXECUTE_READWRITE, OldProtect) then   begin     NewJump := PJump(ASource);     NewJump.OpCode := $E9;     NewJump.Distance := Pointer(Integer(ADestination) - Integer(ASource) - 5);      FlushInstructionCache(GetCurrentProcess, ASource, SizeOf(TJump));     VirtualProtect(ASource, Size, OldProtect, @OldProtect);   end; end;  end.

The solution provided by Ville Krumlinde doesn't work on 64 bits package. It works on Standalone .exe application only.

回答1:

For the FastcodeAddressPatch-function, this version works both in 32-bit and 64-bit when I try. The key is changing "pointer" to "integer" because the Intel relative jump-instruction ($E9) still use an 32-bit offset in 64-bit mode.

type   PJump = ^TJump;   TJump = packed record     OpCode: Byte;     Distance: integer;   end;  procedure FastcodeAddressPatch(const ASource, ADestination: Pointer); const   Size = SizeOf(TJump); var   NewJump: PJump;   OldProtect: Cardinal; begin   if VirtualProtect(ASource, Size, PAGE_EXECUTE_READWRITE, OldProtect) then   begin     NewJump := PJump(ASource);     NewJump.OpCode := $E9;     NewJump.Distance := NativeInt(ADestination) - NativeInt(ASource) - Size;      FlushInstructionCache(GetCurrentProcess, ASource, SizeOf(TJump));     VirtualProtect(ASource, Size, OldProtect, @OldProtect);   end; end;  procedure Test; begin   MessageBox(0,'Original','',0); end;  procedure NewTest; begin   MessageBox(0,'Patched','',0); end;  procedure TForm5.FormCreate(Sender: TObject); begin   FastcodeAddressPatch(@Test,@NewTest);   Test; end;

I'm not sure what the other function does but I'm guessing it should be like this:

function FastcodeGetAddress(AStub: Pointer): Pointer; begin   if PBYTE(AStub)^ = $E8 then   begin     Inc(NativeInt(AStub));     Result := Pointer(NativeInt(AStub) + SizeOf(integer) + PInteger(AStub)^);   end   else     Result := nil; end;


回答2:

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;


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!