Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   uallCollection bringt Zielprozess mit WriteLn zum absturz... (https://www.delphipraxis.net/172279-uallcollection-bringt-zielprozess-mit-writeln-zum-absturz.html)

InfixIterator 22. Dez 2012 00:52

uallCollection bringt Zielprozess mit WriteLn zum absturz...
 
Hallo,
ich spiele etwas mit der uallCollection von brechi rum und bin sehr begeistert,
jedoch bin ich auf zwei Fragen gestoßen, bei denen ich absolut nicht mehr weiter komme...

Aber hier erstmal die Zwei Programm die ich verwende, als erstes der Zielprozess und danach das
Programm mit dem ich injiziere:
Die zwei Fragen stehen dann darunter.

Hier die Project1.exe:
Delphi-Quellcode:
program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils; //für FloatToStr, sleep

  var i:Integer;

function Funktion1 (arg:double):double; //stdcall;
begin
 WriteLn('Function: Much easier to find me this way! '+ FloatToStr(arg));
 result := arg;
end;

procedure Funktion2 (); //stdcall;
begin
 WriteLn('Function2: This is function2.');
end;

begin
  { TODO -oUser -cConsole Main : Hier Code einfügen }

WriteLn('starting...');
   
  while (true) do
  begin
   sleep(2500);
   Funktion1(3.14);
   sleep(2500);
   Funktion2();
  end;


end.

Hier die InjectMe.exe (ist etwas abgeändert von dem Example "Simple Wallhack with SelfInjection"):
Delphi-Quellcode:
program InjectMe;

{$APPTYPE CONSOLE}

uses
  uallDisasm in 'uallCollection\uallDisasm.pas',
  uallDisasmEx in 'uallCollection\uallDisasmEx.pas',
  uallHook in 'uallCollection\uallHook.pas',
  uallKernel in 'uallCollection\uallKernel.pas',
  uallProcess in 'uallCollection\uallProcess.pas',
  uallUtil in 'uallCollection\uallUtil.pas' , //;
  SysUtils,  //benötigt für FloatToStr
  Dialogs; //für showmessage


var
  OriginalFunction: function (a:Double): Double; stdcall;

function callbackUmleitung(a:Double): Double; stdcall;
begin
  //Writeln('original function: argument = '+FloatToStr(a) );  //bringt Project1.exe zum absturz...
  a:=50.1337;
  Result := OriginalFunction(a);   //Wert wurde erfolgreich geändert und die Ursprüngliche Funktion wird aufgerufen (mit dem neuen Wert)
end;

function DllMain(p: pointer): integer; stdcall;
var  Address : DWORD;
begin
  Address := $00408198;  //ist: function Funktion1 (arg:double):double; //stdcall;

  // showmessage('bla');              //bringt Project1.exe zum absturz...
  // Writeln('DllMain started');      //bringt Project1.exe zum absturz...

  //hook installieren:
  uallHook.HookCode(Pointer(Address),@callbackUmleitung,@OriginalFunction); //funktioniert!
end;

procedure Main;
var dwPID: DWord;
begin
  Writeln('press END-key to stop monitoring!');
  Writeln('searching for the exe...');
  repeat
     dwPID := uallProcess.FindProcess('Project1.exe');
    Sleep(100);
  until (dwPID <> 0) or (GetAsyncKeyState(VK_END) < 0);

  if (dwPID <> 0) then
  begin
    Writeln('exe found...');
    uallHook.InjectMe(dwPID,@DllMain);
    Writeln('...injected...');
  end else
  begin
    Writeln('Aborted by user. Press RETURN to close.');
  end;
  ReadLn;
end;


begin
  Main;
end.

Funktioniert soweit auch ganz ok, ABER wenn ich in der Funktion callbackUmleitung ein Writeln mache:
Writeln('original function: argument = '+FloatToStr(a) );
Stürzt die Zielanwendung (also Project1.exe) ab... Weiß jemand wieso das so ist? Und kann man das trotzdem irgendwie ausführen lassen? Denn wenn ich in C++ mit MS detour die gleiche Funktion detoure, kann ich dort auch in der Fremden Konsole etwas ausgeben (also dort geht folgendes) :
std::cout << "original function: argument = "<< a << std::endl;
und zwar ohne den Zielprozess zum absturz zu bringen...


Ich habe noch eine zweite Frage: Geht das alles nicht auch einfacher mit: uallHook.HookCode?
Also kann man nicht auch in uallHook.HookCode irgendwie den Prozess mit Pointer übergeben?
Sonst habe ich sowas nur bei DLL's gesehen, also ala
@origMessageBoxA := GetProcAddress(LoadLibrary('user32.dll'),'MessageB oxA');
uallHook.HookCode(@origMessageBoxA,@callbackMessag eBoxA,@newMessageBoxA);

Nun Frag ich mich, kann man sowas nicht auch mit *.exe-Dateien machen? Quasi sowas wie:
Code:
  Address := $00408198;
  dwPID := uallProcess.FindProcess('Project1.exe');
  @PointerToFunction := GetProcAddress(dwPID,Address); //klar, dass das so nicht wirklich geht, aber gibt es hier etwas äquivalentes?
  uallHook.HookCode(@PointerToFunction,@callbackUmleitung,@OriginalFunction);
Über google hab ich leider nichts gefunden, bin darum über jede Hilfe sehr Dankbar!
LG

Zacherl 22. Dez 2012 02:35

AW: uallCollection bringt Zielprozess mit WriteLn zum absturz...
 
Generell ist bei Injections oft das Problem, dass man APIs aufruft, welche im Zielprozess nicht importiert wurden. Selbst wenn die entsprechenden Libs geladen sind kann man nicht einfach Delphi Code injizieren, der API Aufrufe enthält. Delphi verwendet spezielle eigene Import Tables. Deshalb laufen die Calls im Fremdprozess ins Leere.

brechi 6. Jan 2013 20:35

AW: uallCollection bringt Zielprozess mit WriteLn zum absturz...
 
Hi,
die InjectMe Funktion habe ich nur eingebaut, damit man nicht immer noch eine Dll schreiben muss. Da die Exe als Dll in den Zielprozess geladen wird, kannst du Handles (z.B. die Console) die du im Main deiner Exe geladen hast nicht weiterverwenden. Also auch wenn du z.B. im Hauptprogramm einen Stream oeffnest, kannst du diesen in deiner Hook-Funktion nicht weiterverwenden.
Du solltest aber eine zweite Console im Zielprozess oeffnen koennen (AllocConsole). Hooken ueber Prozessgrenzen ist nicht moeglich (nur mit viel Aufwand ueber IPC, siehe Virtueller Adressraum).

vill hillft dir sowas:
Delphi-Quellcode:

function callbackUmleitung(a:Double): Double; stdcall;
begin
  if FirstCall then begin
    FirstCall := false;
    AllocConsole;
  end;
  Writeln('original function: argument = '+FloatToStr(a) ); //bringt Project1.exe zum absturz...
  a:=50.1337;
  Result := OriginalFunction(a); //Wert wurde erfolgreich geändert und die Ursprüngliche Funktion wird aufgerufen (mit dem neuen Wert)
end;
Ansonsten muesse es auch eine Moeglichkeit geben, im Zielprozess auf Exe-Main zu reagieren, muesse ich aber selbst erstmal nachschauen...

InfixIterator 21. Jan 2013 18:21

AW: uallCollection bringt Zielprozess mit WriteLn zum absturz...
 
Vielen Dank erstmal für die Antworten!!!
(Und auch Entschuldigung für die sehr späte Antwort von mir)

Ich habe nochmal etwas herum probiert:
Also wenn ich das gleiche in Grün nur als DLL Datei mache und dann injecte,
dann funktioniert das mit dem WriteLn perfekt (genauso wie ich es mit der C++ Detour Funktion von Microsoft vorher schon getestet hatte).
Aber alles in der exe und dann mit InjectMe, klappt immer noch nicht und bringt die Zielanwendung zum Absturz. Das Beispiel von Dir brechi, klappt leider nicht. Ich habe etwas herum probiert und gemerkt, dass man offensichtlich schon Zugriff auf die Konsole hat, unabhängig davon, ob man AllocConsole macht, oder nicht. Zum Beispiel kann man die Konsolenausgaben-Farbe problemlos verändern. Mit:
Delphi-Quellcode:
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),
                         FOREGROUND_INTENSITY OR FOREGROUND_GREEN //grün
                                          or BACKGROUND_RED );    //mit rotem Hintergrund
Gibt es eigentlich weitere Möglichkeiten aus einer exe heraus einen Zielprozess zu hooken?
(Außer die injectMe funktion und auch ohne eine dll zu injezieren?)
Ich dachte an sowas wie HookCode nur in der exe ausgeführt und nicht in der injezierten dll.
Ansonsten ist das injezieren einer dll ja auch kein Problem und sehr mächtig. Und mit der injectMe
Funktion kann man ja auch quasi alles (bis auf die Konsolenausgabe) machen.
Bin halt nur neugierig welche Möglichkeiten es so gibt :)

Vielen Dank nochmal für die Antworten!


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:44 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz