AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

OutputDebugString überwachen

Ein Thema von Delphi Star · begonnen am 28. Mär 2005 · letzter Beitrag vom 29. Mär 2005
Antwort Antwort
Seite 2 von 2     12   
Dax
(Gast)

n/a Beiträge
 
#11

Re: OutputDebugString überwachen

  Alt 28. Mär 2005, 20:34
Zitat:
Ich habe mir soeben mal die Implementation von Windows 2000's kernel32!OutputDebugString() angeschaut.
Du hast die Windows-Sourcen?
  Mit Zitat antworten Zitat
Mephistopheles
(Gast)

n/a Beiträge
 
#12

Re: OutputDebugString überwachen

  Alt 28. Mär 2005, 20:35
Ich sehe gerade, daß du eine DEBUG_EVENT-Struktur übergeben mußt, deren Member dann von der Funktion scheinbar gefüllt werden. Danach vergleichst du dwDebugEventCode, dwProcessId und dwThreadId mit den von dir gewünschten Werten und bist fein raus. Ob das ohne eigentliches Debuggen funktioniert, kannst du ja selber testen.

Zitat von Dax:
Zitat:
Ich habe mir soeben mal die Implementation von Windows 2000's kernel32!OutputDebugString() angeschaut.
Du hast die Windows-Sourcen?
Ich zitier mich:
Zitat von Mephistopheles:
Das alles war ein sehr oberflächliches Anschauen des Codes. Könnte also Fehler in der Beschreibung enthalten.
... scheint also nicht so zu sein. Allerdings habe ich einen Disassembler (siehe Signatur), sowie einen feinen Debugger namens Bei Google suchenWinDbg.

Okay, ich gestehe "des Codes" ist zweideutig - mein Fehler. Beim Quelltext wäre aber sicherlich keine "peu-a-peu"-Beschreibung rauskommen. Aber wozu rechtfertige ich mich eigentlich dir gegenüber?!

Mit Worten läßt sich trefflich streiten,
Mit Worten ein System bereiten,
An Worte läßt sich trefflich glauben,
Von einem Wort läßt sich kein Iota rauben.
  Mit Zitat antworten Zitat
w3seek
(Gast)

n/a Beiträge
 
#13

Re: OutputDebugString überwachen

  Alt 28. Mär 2005, 23:21
Ich bin davon ausgegangen dass er nur die OutputDebugString ausgaben eines bestimmten prozesses moechte. Mir ist DebugView selbstverstaendlich bekannt und es setzt in der Tat einen Level tiefer an.

Um OutputDebugString zu verstehen, ist ein wenig SEH (Structured Exception Handling) notwendig. Zuerst sollte man wissen, dass sobald ein prozess debugged wird, jede Exception erst einmal an den debugger weitergeleitet wird der ueber die weitere Vorgehensweise entscheided (im prinzip wie jeder "normale" exception handler), dies funktioniert ueber die sog. debug ports.

OutputDebugString macht im prinzip nichts anderes, als dass es eine spezielle exception ausloest (DBG_PRINTEXCEPTION_C). Ist nun ein debugger praesent fuer diesen prozess, wird dieser aktiv (d.h. der debug port sendet eine nachricht an den debugger prozess der den Thread, der gerade in WaitForDebugEvent waert, aufwachen laesst und die exception informationen uebermittelt. Waehrend der debugger diese exception dann behandelt, ist der thread der sie ausgeloest hat, im Schlummerzustand so dass es dem Debugger ermoeglicht saemtliche zusaetzliche Informationen wie image dumps, register dumps, stack traces, ... auszulesen. Der Debugger kann dabei (wie jeder exception handler) auch die Ausfuehrung des threads uneingeschraenkt beeinflussen, beispielsweise die Register veraendern um Instruktionen zu ueberspringen oder den stack unwind (RtlUnwind) durchfuehren, oder die exception unbehandelt lassen so dass sich der thread spaeter selbst um die behandlung kuemmern muss. Schliesslich um die Ausfuehrung des Threads fortzusetzen, muss der debugger noch ContinueDebugEvent aufrufen, das den eingeschlaeferten Thread wieder aufwachen laesst.

Im Prinzip durchlaeuft jeder Debugger diese Schleife um breakpoints, debug ausgaben, ... zu behandeln.

DebugView ist aber in diesem Sinne kein richtiger debugger, d.h. er wird nicht automatisch aktiv sobald eine exception ausgeloest wird. Er macht sich dagegen einer anderen Eigenschaft (die weniger dokumentiert ist) zunutze die OutputDebugStringA hat. Wenn naemlich kein debugger aktiv ist, der diese spezielle exception behandelt, schreibt es diese informationen in eine named (DBWIN_BUFFER) section (aka Memory Mapped File, wie bereits angemerkt wurde). Named, deswegen, dass es im object namespace von jedem Prozess in der selben session (entsprechende Rechte vorausgesetzt) auffindbar ist. Diese section ist fuer alle Prozesse lesbar und schreibbar, weshalb man jeglichen zugriff darauf sichern sollte da die Informationen beim Lesen der Daten jederzeit veraendert oder corrupted werden koennen. Damit DebugView also nicht staendig von diesem puffer lesen (pollen) muss, um herauszufinden ob daten hineingeschrieben wurden, gibt es noch named events(DBWIN_BUFFER_READY und DBWIN_DATA_READY), die OutputDebugString ausloest. DBWIN_BUFFER_READY zeigt an, ob jemand gerade mit dieser section arbeitet und verhindert OutputDebugString Daten in der section zu veraendern. Sobald man also den string aus dem puffer gelesen hatte, sollte man diesen event wieder signalisieren so dass weitere OutputDebugString aufrufe erfolgen koennen. Dies deckt die Synchronisierung zum lesen/schreiben der Daten in diese section ab, um jetzt beispielsweise DebugView nicht staendig pollen lassen zu muessen, gibt es noch den DBWIN_DATA_READY event, welchen OutputDebugString signalisiert sobald es die nachricht in die section geschrieben hat.

Kurz gefasst sieht die Vorgehensweise zum globalen Auslesen der OutputDebugString messages so aus:
1. Die DBWIN_BUFFER section mappen
2. Handles zu den DBWIN_BUFFER_READY und DBWIN_DATA_READY events erstellen
3. Den DBWIN_BUFFER_READY event setzen so dass OutputDebugString wieder Zugriff auf den puffer hat
4. Auf den DBWIN_DATA_READY event warten welcher signalisiert, dass neue nachrichten vorhanden sind
5. Die geoeffneten Handles schliessen

Die Schritte 2-4 in einer Endlosschleife durchfuehren wenn man mehr als nur eine Nachricht abfangen moechte.

Zu bemerken ist, dass man damit nur jene Debug ausgaben abfangen kann, die von Prozessen gesendet werden, die nicht mit einem Debugger verbunden sind, da sonst diese spezielle exception an den Debugger uebermittelt wuerde.

Ich hoffe ich konnte das halbwegs erklaeren (sorry fuer die vielen Rechtschreib- und Grammatikfehler), so sollte das in der Realitaet funktionieren.

Einen Treiber braucht man jedenfalls fuer das Abfangen von OutputDebugString nicht, anders sieht es mit DbgPrint aus, denn dafuer gibt es eine kernel mode implementierung (ntoskrnl.exe) und eine user mode implementierung (ntdll) - welche letztendlich aber auf den gleichen port schreiben...
  Mit Zitat antworten Zitat
Mephistopheles
(Gast)

n/a Beiträge
 
#14

Re: OutputDebugString überwachen

  Alt 28. Mär 2005, 23:38
Ich habe absichtlich die Win32-Termini benutzt um niemanden zu verwirren. Nicht jeder hier ist mit K-Mode und/oder Native API vertraut, denke ich.
Die Frage haben wir also offenbar unterschiedlich aufgefaßt.

Ansonsten eine sehr gute Erklärung. Daß DebugView die Section ausliest, wußte ich garnicht - ich ging wegen des gleichen Schemas, welches sich durch viele der Sysinternals-Tools zieht, davon aus, daß einzig auf der tiefsten Ebene (eben K-Mode) gehookt wird. Wie gesagt, auch OutputDebugString() ruft ja schließlich DbgPrint() auf, welches in den K-Mode geroutet wird (s.o.). Genaueres muß man wohl oder übel in einem KD anschauen.

Da hat wohl einer in die Windows-Sourcen geguckt - oder war es vielleicht doch nur ROS, ein guter Disassembler und ein Debugger ? Gelle, w3seek? ... naja, Dax kennt eben noch nicht die besten und interessantesten OpenSource-Projekte, wie mir scheint.

@Thomas:

Hier eine Funktion, die in ROS 0.2.5 noch nicht deklariert war. Die wurde allerdings auch erst mit Windows XP eingeführt. Viel Spaß
Delphi-Quellcode:
// Resembles the RtlValidateUnicodeString() function available from Windows XP
// on exactly as it is on this OS version, except for the calling convention.
function RtlValidateUnicodeString(dwMustBeNull: DWORD; UnicodeString: PUNICODE_STRING): NTSTATUS;
begin
  result := STATUS_INVALID_PARAMETER;
  if(dwMustBeNull = 0) then
  begin
    result := STATUS_SUCCESS;
    if(Assigned(UnicodeString)) then
    begin
      result := STATUS_INVALID_PARAMETER;
      if((UnicodeString^.Length mod 2 = 0) and (UnicodeString^.MaximumLength mod 2 = 0) and (UnicodeString^.Length <= UnicodeString^.MaximumLength)) then
        if((UnicodeString^.Length > 0) and (UnicodeString^.MaximumLength > 0)) then
          if(Assigned(UnicodeString^.Buffer)) then
            result := STATUS_SUCCESS;
    end;
  end;
end;
  Mit Zitat antworten Zitat
w3seek
(Gast)

n/a Beiträge
 
#15

Re: OutputDebugString überwachen

  Alt 28. Mär 2005, 23:52
Zitat von Mephistopheles:
Wie gesagt, auch OutputDebugString() ruft ja schließlich DbgPrint() auf, welches in den K-Mode geroutet wird (s.o.).
Das habe ich zumindest nie gesagt und ist auch nicht richtig. OutputDebugString ruft DbgPrint niemals auf.

Zitat von Mephistopheles:
Da hat wohl einer in die Windows-Sourcen geguckt - oder war es vielleicht doch nur ROS, ein guter Disassembler und ein Debugger ? Gelle, w3seek? ... naja, Dax kennt eben noch nicht die besten und interessantesten OpenSource-Projekte, wie mir scheint.
Nope, ich habe niemals Einblick noch Zugriff darauf gehabt und mich interessiert es eigentlich auch nicht wirklich. Ueber dieses Thema duerfte genug Informationen im Netz zu finden sein (codeproject hat bestimmt was), ansonsten haben wir diese sachen zumindest zum Teil bereits implementiert. Ich hab mich mit diesem Thema vor langer Zeit bereits mal auseinander gesetzt.

Zitat von Mephistopheles:
Hier eine Funktion, die in ROS 0.2.5 noch nicht deklariert war
Danke, werde mich darum kuemmern
  Mit Zitat antworten Zitat
Mephistopheles
(Gast)

n/a Beiträge
 
#16

Re: OutputDebugString überwachen

  Alt 29. Mär 2005, 00:08
Zitat von w3seek:
Zitat von Mephistopheles:
Wie gesagt, auch OutputDebugString() ruft ja schließlich DbgPrint() auf, welches in den K-Mode geroutet wird (s.o.).
Das habe ich zumindest nie gesagt und ist auch nicht richtig. OutputDebugString ruft DbgPrint niemals auf.
Stimmt. Das habe ich gesagt - und es wird aufgerufen. Wenn du willst, kann ich dir die entsprechenden Stellen hier posten. Alternativ per PN.

Zitat von w3seek:
Nope, ich habe niemals Einblick noch Zugriff darauf gehabt und mich interessiert es eigentlich auch nicht wirklich.
Das ist aber unpraktisch, wenn du doch im ROS-Projekt mitmachst ... da muß man sich doch wenigstens ein wenig für die ROS-Sourcen interessieren

Der Kommentar war auch mehr auf Dax gemünzt, welcher offenbar meint, daß die mystischen Windows-Quelltexte, die ja wohl durch's Internet geistern, die einzige Möglichkeit zur Informationsbeschaffung sind.

Achso, die Implementation der Funktion sollte dem Orginal entsprechen, aber natürlich ist das Orginal als __stdcall deklariert - dies beweisen Aufrufe dieser Funktion von anderen Stellen der ntdll.dll!

Ach ja ... und unter C kannst du natürlich einfach mal "return" sagen. Unter Delphi ist das nicht so schön, weshalb ich geschachtelte IFs verwende.
  Mit Zitat antworten Zitat
w3seek
(Gast)

n/a Beiträge
 
#17

Re: OutputDebugString überwachen

  Alt 29. Mär 2005, 00:16
Zitat von Mephistopheles:
Stimmt. Das habe ich gesagt - und es wird aufgerufen.
Man sollte nicht so pessimistisch sein und davon ausgehen dass OutputDebugString auch noch fehlschlaegt Aber dann wird auch nicht der gewuenschte Text nach DbgPrint ausgegeben.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:38 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