2011-09-28 9 views
11

यूनिट FastCodePatch.pas Win32 प्लेटफार्म में काम करता है। डेल्फी एक्सई 2 Win64 प्लेटफ़ॉर्म का समर्थन करता है, किसी भी विचार को Win64 प्लेटफॉर्म में FastCodePatch कैसे काम करता है?डेल्फी XE2 Win64 मंच में FastCodePatch कैसे काम करें?

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. 

विल Krumlinde द्वारा प्रदान समाधान 64 बिट्स पैकेज पर काम नहीं करता। यह केवल स्टैंडअलोन .exe एप्लिकेशन पर काम करता है।

उत्तर

4

निम्न कोड के लिए दोनों Win32 काम करता है - स्टैंडअलोन और पैकेज, Win64 - स्टैंडअलोन और पैकेज:

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; 
+0

यह वास्तव में है एक अलग प्रश्न का उत्तर। विले ने आपके मूल प्रश्न का उत्तर दिया। पैकेज में पैचिंग फ़ंक्शंस एक अलग गेम है। आपके द्वारा प्रस्तुत कोड 32 बिट लक्ष्यों पर भी आवश्यक है। –

+0

ग्रेट कोड ! मैं पुष्टि करता हूं कि यह 'डेल्फी 10.1' (बर्लिन) के साथ 32/64-बिट' विंडोज 7' के तहत पूरी तरह से काम करता है, यहां तक ​​कि 'डीईपी' सक्षम भी है। –

12

FastcodeAddressPatch-function के लिए, यह संस्करण 32-बिट और 64-बिट दोनों में काम करता है जब मैं कोशिश करता हूं। कुंजी "सूचक" को "पूर्णांक" में बदल रही है क्योंकि इंटेल रिश्तेदार कूद-निर्देश ($ 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; 
+0

+1 अंतर स्पष्ट करने के लिए यह है कि प्रश्न में संस्करण TJump रिकॉर्ड में 8 बाइट पॉइंटर का उपयोग करता है जो गलत है। –

+0

आह, अब मैं अपना अपवॉट हटाना चाहता हूं। 'पूर्णांक (प्रमाणीकरण) - Win64 पर पूर्णांक (ASource)' सही नहीं हो सकता है। आपको 'मूल INT' का उपयोग करने की आवश्यकता है। –

+0

@ डेविड: अभिव्यक्ति में मूल INT में बदल गया। अभिव्यक्ति का गंतव्य दूरी-क्षेत्र केवल 32-बिट होना चाहिए जैसा कि आप कहते हैं। –

संबंधित मुद्दे