Delphi-Quellcode:
asm
JMP [EAX].THookData.VirtualFree
end;
Wie gesagt, der Code lässt sich nicht so ohne weiteres direkt in Delphi umsetzen. Es gibt also noch ein paar Details zu beachten. Z.b. sind die Function Deklarationen der Windows
API Funktionen nicht korrekt, sondern nur angedeutet.
Wichtig ist das VirtualAllocEx() einen an einer Speichergrenze von $1000 ausgerichteten Speicherbereich alloziert. Dies hat mehrere Gründe, der wichtigste ist aber wie im Assemblerpart von MyWndproc() am Anfang diese Speicheradresse ermittelt wird. Da alles dynamisch ist, auch für die Programmierung im Source, gibt es keine direkte und einfache Möglichkeit die korrekte Speicheradresse von Memory direkt der MyWndProc() zu übergeben. Diese Funktion muß also eine "Brute Force" Methode benutzen. Sie geht davon aus das Memory = $XXXXX000 ist.
Man könnte aber einen Dispatcher für MyWndProc() schreiben, d.h. eine kleine Assembler procedure vor MyWndProc() die einen zusätzlichen Parameter "Memory" in MyWndProc() einführt.
Delphi-Quellcode:
type
PHookData = ^THookData;
THookData =
packed record
... bla bla
case Integer
of
0: (WindowProc:
array[0..0]
of Byte);
1: (WindowProc_POP_EDX: Byte;
WindowProc_PUSH_CONST: Byte;
WindowProc_Memory: Pointer);
end;
function MyWndProc(): lResult;
stdcall;
forward;
procedure MyWndProcDispatch;
asm
POP EDX
PUSH $12345678
PUSH EDX
JMP MyWndProc
end;
function MyWndProc(Wnd: hWnd,....,lParam: LParam; Memory: PHookData): lResult;
stdcall
begin
end;
procedure SubClassWnd();
begin
... blabla
Move(@MyWndProcDispatch, Memory^, CodeSize);
Memory.WindowProc_Memory := Memory;
... blabla
Memory...... := ......
end;
Nun muß man bei VirtualAllocEx() nicht mehr auf die Ausrichtung des Speicherbereiches achten, da gezielt ein neuer Parameter in MyWndProc() eingeführt wird der die Adresse von Memory enthält.
Obige Vorgehensweise ist notwendig da der Delphi Linker alle Prozeduren auf 4 Bytes Grenzen ausrichtet, also optimiert. Es können also zwischen den Proceduren MyWndProcDispatch() und MyWndProc() und ThreadFunc() und SubClassWnd() Bytes im Code stehen, die nur Fillerbytes sind.
Da MyWndProc() aber von dir beliebig erweitert werden kann und auch soll, können wir nicht direkt den Code vom MyWndproc() in Memory patchen. Denn je nach dem was für lokale Variablen du benutzt ändert sich auch der Code den der Compiler als Stackframe automatisch ohne deinen Einfluß ändert.
gruß Hagen