单元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;