Einzelnen Beitrag anzeigen

Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#43

Re: Subclassing einer fremden Application, warum funzt das n

  Alt 11. Nov 2003, 10:04
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
  Mit Zitat antworten Zitat