PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : GetThreadContext - Read 'Kernel Context'



DerAssembler
30.08.2010, 10:54
Hey Leute, mich plagt seit einiger Zeit schon ein kleines Problem.
Und zwar:

Starte ich einen Prozess im DEBUG_PROCESS Modus und setze/schreibe einen Breakpoint (0xCC) auf eine Kernel32 API-Funktion. Soweit läuft dann auch alles gut, dann beim Debug-Event möchte ich den derzeitigen Context via GetThreadContext auslesen, doch blöderweiße liefert diese Funktion komplett falsche Werte zurück. Zum Beispiel statt ESP: 1298FF eben 1235AB.
Wenn ich die Funktion im "normalem" Code-Bereich aufrufe stimmen die ganzen Werte.

Nun wäre ich euch sehr verbunden, wenn jemand die Ursache und eine Lösung dafür wüsste. Vielen Dank. :)

p.s. vielen Dank nochmal an DizzY_D, der mir da schon sehr sehr viel geholfen hat. ;)

EBFE
30.08.2010, 11:01
Bist du sicher, dass nicht mehrere Threads laufen (vor allem bei NET&Co, aber auch bei "komplexeren" Programmen, die mittels RAD-Tools (Delphi/Borland IDEs)) öfters der Fall. Prüfbar z.B mit ProzessExplorer.
Wie liest du die Werte ein, um zu prüfen, ob GetThreadContext richtig ausgeführt wurde? :)

Edit/PS: um sicherzustellen: verstehe ich den Satz "Breakpoint (0xCC) auf eine Kernel32 API-Funktion" richtig, dass du damit einen BP in der Kernel32.DLL setzt (und nicht etwa bei einem Call dieser Funktion in der Exe)?

blackberry
30.08.2010, 11:02
You cannot get a valid context for a running thread. Use the SuspendThread (http://msdn.microsoft.com/en-us/library/ms686345%28v=VS.85%29.aspx) function to suspend the thread before calling GetThreadContext.
(Quelle: GetThreadContext Function (Windows) (http://msdn.microsoft.com/en-us/library/ms679362%28VS.85%29.aspx))

Vielleicht hilft's ja.

DerAssembler
30.08.2010, 11:10
Bist du sicher, dass nicht mehrere Threads laufen (vor allem bei NET&Co, aber auch bei "komplexeren" Programmen, die mittels RAD-Tools (Delphi/Borland IDEs)) öfters der Fall. Prüfbar z.B mit ProzessExplorer.
Wie liest du die Werte ein, um zu prüfen, ob GetThreadContext richtig ausgeführt wurde? :)

Edit/PS: um sicherzustellen: verstehe ich den Satz "Breakpoint (0xCC) auf eine Kernel32 API-Funktion" richtig, dass du damit einen BP in der Kernel32.DLL setzt (und nicht etwa bei einem Call dieser Funktion in der Exe)?

Soweit ich es beurteilen kann läuft nur 1 Thread im Debuggee. Die Anwendung (also das Debuggee) ist in C++ geschrieben. Nunja wenn ich den "Debugger" debugge bekomm ich keinen Error (auch nicht GetLastError). Und die Werte überprüfe ich wenn ich das Debuggee manuell in Olly debugge.

Ja du verstehst den Satz richtig. Der BP befindet sich in der Kernel32.dll.

@BlackBerry: Danke ich werds mal versuchen.

EBFE
30.08.2010, 12:20
Abgesehen von BlackBerrys Hinweis:
wohin zeigt eigentlich der ESP? (also der Wert an 0x1298FF) lies den mal aus und vergleiche mit dem Wert, den dir Olly anzeigt :) <-- ist nämlich die Rücksprungsadresse. Damit lässt sich leicht herausfinden, wer der Caller ist. Und du kannst prüfen, ob du in Olly die gleiche "Situation" betrachtest, wie in deinem Programm.

Auch wenn die Exe die API nicht nativ aufruft, sondern gewrapt (z.B über RuntimeDLL) - sowas lässt sich relativ leicht herausfinden, in dem man einmal in Olly den Stack durchgeht und die Rücksprungadresse in den Exe-Mem-Bereich sucht. Der Abstand zwischen ESP Wert am BP-Event und der Stackadresse, die den Rücksprung in die Exe beinhaltet, ändert sich nicht. D.h wenn API-BP-Event auftritt, Thread einfrieren, ESP auslesen, Abstand dazuaddieren und schauen, ob der Wert an dieser Adresse gleich Exe-Bereich ist. Dient quasi der Identifikation, um zwischen internen Calls und dem gewünschten unterscheiden zu können.

Zum Olly:
Alt+O für Optionen ->Events -> Make first pause at -> System BP
nun restarten und den BP machen.
Damit kannst du halt prüfen, ob die API nicht intern, vor dem eigentlichen Exestart, aufgerufen wird ;) .

alternativ platzierst du in deine Programm noch einen BP am EntryPoint, liest zusätzlich EIP aus und merkst dir irgendwo, ob BP am EntryPoint aufgerufen wurde. Damit kannst du (in deinem Programm) auch prüfen, ob die API noch vor dem EP aufgerufen wird. Eine Art "identifikation" mittels Parameterprüfung oder Rücksprungadresse (wie oben beschrieben) sollte man aber trotzdem einbauen.

DerAssembler
30.08.2010, 15:40
Danke EBFE, ich werde jetzt mal BlackBerrys Ratschlag versuchen und anschließend mal prüfen ob die API schon vorher aufgerufen wird. Eben ist es mein Ziel die Rücksprungaddresse auszulesen um den Caller zufinden um dann mit meiner Analyse fortzusetzen. ;)

Vielen dank ihr beiden, ich werd dann Feedback geben obs geklappt hat.

Feedback:

EBFE du bist der Beste! ;) Es war genau so wie du vermutet hast. Die API wurde schon vorher einmal intern aufgerufen! Und dort stimmen die ganzen Werte/Register.

Vielen dank nochmal EBFE! :cool: