delphi - 如何使FastCodePatch在Delphi XE2 Win64平台上工作?

标签 delphi 64-bit delphi-xe2

Unit FastCodePatch.pas 适用于 Win32 平台。 Delphi XE2支持Win64平台,请问如何让FastCodePatch在Win64平台上工作?

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.

Ville Krumlinde 提供的解决方案不适用于 64 位软件包。它仅适用于独立的 .exe 应用程序。

最佳答案

对于 FastcodeAddressPatch 函数,当我尝试时,该版本可以在 32 位和 64 位下运行。关键是将“指针”更改为“整数”,因为 Intel 相对跳转指令 ($E9) 在 64 位模式下仍然使用 32 位偏移量。

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;

我不确定其他函数的作用,但我猜它应该是这样的:

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;

关于delphi - 如何使FastCodePatch在Delphi XE2 Win64平台上工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7581321/

相关文章:

引擎盖下的 perl 64 位整数

delphi - 如何在XE2中获取TExcelWorksheet(64位版本)?

delphi - 如何枚举对象中的所有属性并获取它们的值?

delphi - 我如何将 WNDPROC 转换为 TWndMethod

delphi - 如何在delphi中找到两个开始和结束字符串之间的字符串?

delphi - 如何通过名称杀死进程?

windows - 将 x32 lib 与 x64 进程集成的最佳方法是什么(无需将 lib 转换为 x64)?

delphi - 在delphi : interrupt encoding process中使用ffmpeg

x86 - 一个操作系统上有两个 Java 运行时环境,但具有不同的架构?

delphi - 功能 'rich' 为何是 FireMonkey 框架