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/