Einzelnen Beitrag anzeigen

Benutzerbild von negaH
negaH

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

Re: Subclassing einer fremden Application, warum funzt das n

  Alt 10. Nov 2003, 23:56
Es ist eigentlich egal ob man MMF's nimmt oder nicht. Man könnte auch VirtualAllocEx() benutzten um einen Speicherbereich innerhalb eines anderen Processes zu injezieren. Man sollte nun zwei unterschiedliche Vorgehensweisen betrachten, abhängig ob Win9x oder Win2x.

Generell sähe es so aus:
1.) erzeuge einen Speicherbereich im Zielprozess
2.) initialisiere in diesem Speicher den Code + Datenstrukturen. In diesem Speicher liegt eine Threadfunktion und die WindowProc
3.) erzeuge einen Remote Thread, also einen Thread der im Zielprozess läuft. Unter Win2x gibts dafür CreateRemoteThread() unter Win9x kann man diese Funktion nachbauen.
4.) die Threadfunktion zeigt in unserem Speicherbereich

Nun ist es wichtig was die Threadfunktion überhaupt macht. Sie subclasses das betroffene Fensterhandle und setzt deren Fensterfunktion auf die Fensterfunktion in unserem Speicherbereich. Danach Terminiert sie den Thread.

Als Pseudocode sähe das so aus:

Delphi-Quellcode:
type
  PHookData = ^THookData;
  THookData = packed record
    SaveWindowProc: Pointer;
    hWnd: HWnd;
    GetWindowLong: function(hWnd, Index): Pointer: stdcall;
    SetWindowLong: function(hWnd, Index, Pointer): Bool; stdcall;
    ExitThread: procedure(Return); stdcall;
    CallWndProc: function(Proc, hWnd, wParam, lParam): lResult; stdcall;
    VirtualFree: fucntion(Pointer): Integer; stdcall;
    WindowProc: array[0..0] of Byte; // hier wird MyWndProc rein kopiert
    ThreadCode: array[0..0] of Byte; // hier wird ThreadProc hineinkopiert
  end;

function MyWndProc(...): Integer; stdcall;
var
  Memory: PHookData;
begin
  asm
     CALL @@1
@@1: POP EAX
     AND EAX,$FFFFF000 // align
     MOV Memory,EAX
  end;
  if Msg = wm_Destroy then
  begin
    Memory.CallWndProc(Memory.SaveWindowProc, hWnd, Msg, wParam, lParam);

 // hier Memory freigeben, wichtig dabei das der aktuelle Code ja in diesem Memory^ liegt
 // wir müssen also die Reücksrungadresse aus dem Stack holen. Dann Memory auf den Stack pushen
 // danach Rücksrungadresse pushen und einem Jump nach VirtualFree() durchführen.
 // Somit kehrt VirtualFree NICHT in unseren nun freigegebene Memory zurück, sondern zum
 // Aufrufer von MyWndProc().
    asm
      POP EDX
      MOV EAX,Memory
      PUSH EAX
      PUSH EDX
      JMP [EAX].VirtualFree
    end;
  end else
    if Msg = wm_Close then
    begin
    end else
      Result := Memory.CallWndProc(Memory.SaveWindowProc, Wnd, Msg, wParam, lParam);
end;

function ThreadProc(Memory: PHookData): Dword; stdcall;
// wichtig !! keine Aufrufe von Funktionen und Daten die nicht Importe/Inhalte in Memory sind !!
begin
  Memory.SaveWindowProc := Memory.GetWindowLong(Memory.hWnd, gwl_WndProc);
  Memory.SetWindowLong(Memory.hWnd, gwl_WindowProc, @Memory.WindowProc);
  Memory.ExitThread(0);
end;
 
procedure Subclass(hWnd);
var
  Memory: PHookData;
  ProcSize: Integer;
  ThreadFunc: Pointer;
begin
  ProcSize := PChar(@Subclass) - PChar(@MyWndProc);

  Memory := VirtualAllocEx(..., SizeOf(THookData) + ProcSize); // align on Pageboundary needed !!
  Move(@MyWndProc, @Memory.WindowProc, ProcSize);
  Memory.hWnd := hWnd;
  Memory.GetWindowLong := GetProcAddress();
  Memory.SetWindowLong := GetProcAddress();
  Memory.ExitThread := GetProcAddress();
  Memory.CallWndProc := GetProcAddress();
  Memory.VirtualFree := GetProcAddress();
  
  ThreadFunc := PChar(Memory) + SizeOf(THookData) + PChar(@ThreadProc) - PChar(@MyWndProc);
  
  CreateRemoteThread(..., ThreadFunc, Memory, ...);
end;
WICHTIG ! dies niemals mit dem integrierten Debugger testen, da BorDbk Importe im Prozess wie GetProcAddress() selber umbiegt. Somit kann zB. GetProcAddress(, 'GetWindowLong') eine Adresse zurückgeben die in den BorDbk zeigt statt in's Kernel/GDI. Am besten eine eigene GetProcAddress() Funktion benutzen die ohne API auskommt !.

Jetzt mus man nur noch zum hWnd das Process Handle und Process ID rausbekommen.

Gruß Hagen

PS: Den Feinschliff müsst ihr selber rausfinden, da dieses Posting so ziemlich der direkte Weg ist für schlaue Jungs.
  Mit Zitat antworten Zitat