单元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,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,OldProtect) then
- begin
- NewJump := PJump(ASource);
- NewJump.OpCode := $E9;
- NewJump.Distance := NativeInt(ADestination) - NativeInt(ASource) - Size;
- FlushInstructionCache(GetCurrentProcess,@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;