Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Pointer auf Klassenfunktion erhalten
Flamefire - Do 26.08.10 15:49
Titel: Pointer auf Klassenfunktion erhalten
Ich will einen Pointer auf eine Klassen-Methode erhalten um DirectX-Funktionen zu hooken.
Bei directX kriege ich ja beim init nur ein Interface mit MethodenZeigern gefüllt. Darum das ganze dynamisch.
Mein Ansatz:
Delphi-Quelltext
1:
| HookCode(@(Keyboard.FDeviceObj.GetDeviceState),@HookedGDS,@realGDS); |
Mit: Keyboard.FDeviceObj:IDirectInputDevice8;
Der Meckert mir aber über "Nicht genügend wirkliche Parameter", als wollte er die Funktion ausführen.
Wie schaffe ich das, zum Laufen zu bringen?
Teekeks - Do 26.08.10 16:10
Hallo!
Versuche es mal so:
Delphi-Quelltext
1:
| HookCode(@Keyboard.FDeviceObj.GetDeviceState,@HookedGDS,@realGDS); |
delfiphan - Do 26.08.10 16:16
Also ein "Methodenpointer" gibt's so eigentlich nicht. Ein Methodenaufruf benötigt zwei Pointers (siehe TMethod), der Pointer auf den Code und der Pointer auf die Daten (d.h. auf Self).
Mit einem kleinen Trick kannst du jedoch einen "Methodenpointer" erhalten, wenn du nämlich ein Interface hast. Die Methodentabelle von Interfaces beinhalten nämlich nur Funktionspointer. Dort drin wird dann das Self noch dazugerechnet und dann die Methode aufgerufen. Blöderweise musst du aber das Interface selbst als Parameter übergeben, was ActiveX wohl kaum machen wird.
Weitere Möglichkeit ist, wenn du sowas wie MakeObjectInstance machst. Der generiert aus einer Methode einen Pointer (die Methode hat aber nicht die Signatur, die du benötigst).
Ansonsten globale Funktion, die die Methode aufruft.
Flamefire - Do 26.08.10 17:09
nja sagen wir so: in assembler sieht das ganze so aus:
Quelltext
1: 2: 3:
| push eax //parameter self mov eax,[eax] //laden der methodenpointertabelle call [eax+1C] //aufruf der methode |
Was meinst du mit der Signatur?
Die Variante von Teekeks hatte ich ja, aber ging nicht.
Meine Frage ist jetzt: Wie kriege ich den Pointer aus der Tabelle von dem Interface?
delfiphan - Do 26.08.10 17:19
Das Problem ist, dass dir DirectX den Interface-Pointer (<>Self!) nicht als Parameter mitgibt (Methodensignatur = Methodendeklaration; d.h. die Tatsache, dass du den Interface-Pointer übergeben musst).
Also entweder machst du eine globale Prozedur, die deine Methode aufruft oder du machst sowas wie MakeObjectInstance.
Also mit sowas wie hier kannst du ein
procedure of object in ein
procedure umwandeln. In dem Code unten ist die Variable
Code auf dem Stack. Das müsste man ändern, sodass man zuerst Speicher mittels
VirtualAlloc mit dem Flag
PAGE_EXECUTE_READWRITE holt und damit arbeitet.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39:
| type TObjProc = procedure of object; TProc = procedure;
type TCode = packed record MovEAX: Byte; Data: Pointer; MovEBX: Byte; Code: Pointer; CallEbx: Word; Ret: byte; end;
procedure TForm1.Button1Click(Sender: TObject); var ObjProc: TObjProc; Proc: TProc;
Code: TCode; begin ObjProc := Test; Code.MovEAX := $B8; Code.MovEBX := $BB; Code.CallEbx := $D3FF; Code.Ret := $C3; Code.Data := TMethod(ObjProc).Data; Code.Code := TMethod(ObjProc).Code;
@Proc := @Code;
Proc; end;
procedure TForm1.Test; begin ShowMessage('Success!'); end; |
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!