Steuern von Threads und Prozessen
Eine Übersicht über Threads und Prozesse in der Debugger-Engine finden Sie unter Threads und Prozesse.
Wenn ein Ereignis auftritt, werden der Ereignisthread und der Ereignisprozess auf den Thread und den Prozess (Betriebssystem oder virtuell) festgelegt, in dem das Ereignis aufgetreten ist. Sie können mit GetEventThread bzw . GetEventProcess gefunden werden.
Implizite Threads und Prozesse
Beim Debuggen im Kernelmodus verwendet die Debugger-Engine den impliziten Prozess , um zu bestimmen, welcher virtuelle Adressraum bei der Übersetzung virtueller zu physischer Adressen verwendet werden soll, z. B. in den Methoden VirtualToPhysical und ReadVirtual. Wenn ein Ereignis auftritt, wird der implizite Prozess auf den aktuellen Prozess festgelegt.
Der implizite Prozess kann mithilfe von SetImplicitProcessDataOffset geändert werden. Verwenden Sie GetImplicitProcessDataOffset, um den impliziten Prozess zu bestimmen.
Hinweis Beim Festlegen von Haltepunkten während einer Live-Kerneldebugsitzung übergibt das Debuggermodul die virtuelle Adresse des Haltepunkts an das Ziel, und das Ziel legt den Haltepunkt fest. In diesem Fall wird bei der Behandlung des Haltepunkts nur der Prozesskontext des Ziels verwendet. der Wert des impliziten Prozesses ist irrelevant.
Beim Debuggen im Kernelmodus verwendet die Debugger-Engine den impliziten Thread , um einige Der Register des Ziels zu bestimmen. Dies umfasst den Prozessorstapel (siehe GetStackOffset), den Frameoffset (siehe GetFrameOffset) und den Anweisungsoffset (siehe GetInstructionOffset). Wenn ein Ereignis auftritt, wird der implizite Thread auf den aktuellen Thread festgelegt.
Der implizite Thread kann mithilfe von SetImplicitThreadDataOffset geändert werden. Verwenden Sie GetImplicitThreadDataOffset, um den impliziten Thread zu bestimmen.
Nicht alle Register werden vom impliziten Thread bestimmt. Einige Register bleiben gleich, wenn der implizite Thread geändert wird.
Warnung Der implizite Prozess und der implizite Thread sind unabhängig. Wenn der implizite Thread nicht zum impliziten Prozess gehört, befinden sich der Benutzer- und Sitzungsstatus für den impliziten Thread im falschen virtuellen Adressraum, und Versuche, auf diese Informationen zuzugreifen, führen zu Fehlern oder liefern falsche Ergebnisse. Dieses Problem tritt beim Zugriff auf den Kernelspeicher nicht auf, da Kernelspeicheradressen über alle virtuellen Adressräume hinweg konstant sind. Daher kann unabhängig vom impliziten Prozess auf Informationen für den impliziten Thread im Kernelspeicher zugegriffen werden.
Threads
Die Enginethread-ID wird von der Debugger-Engine verwendet, um jeden Betriebssystemthread und jeden virtuellen Thread für ein Ziel zu identifizieren.
Während ein Ziel beendet wird, verfügt jeder Thread auch über einen Index relativ zum Prozess, zu dem er gehört. Für jeden Prozess ist der Index des ersten Threads im Prozess 0, und der Index des letzten Threads ist die Anzahl der Threads im Prozess minus 1. Die Anzahl der Threads im aktuellen Prozess kann mithilfe von GetNumberThreads ermittelt werden. Die Gesamtanzahl von Threads in allen Prozessen im aktuellen Ziel kann mithilfe von GetTotalNumberThreads ermittelt werden.
Die Enginethread-ID und die Systemthread-ID für einen oder mehrere Threads im aktuellen Prozess können mithilfe von GetThreadIdsByIndex aus ihrem Index ermittelt werden.
Die Engine verwaltet mehrere Informationen zu jedem Thread. Diese Informationen werden möglicherweise für den aktuellen Thread abgefragt und können verwendet werden, um die Enginethread-ID für einen Thread zu finden.
Systemthread-ID (nur Debuggen im Benutzermodus)
Die Systemthread-ID des aktuellen Threads kann mithilfe von GetCurrentThreadSystemId ermittelt werden. Für eine bestimmte Systemthread-ID kann die entsprechende Enginethread-ID mithilfe von GetThreadIdBySystemId gefunden werden.
Threadumgebungsblock (TEB)
Die Adresse des TEB für den aktuellen Thread kann mithilfe von GetCurrentThreadTeb ermittelt werden. Für eine bestimmte TEB-Adresse kann die entsprechende Enginethread-ID mithilfe von GetThreadIdByTeb gefunden werden. Beim Debuggen im Kernelmodus ist der TEB eines (virtuellen) Threads der TEB des Systemthreads, der auf dem entsprechenden Prozessor ausgeführt wurde, als das letzte Ereignis aufgetreten ist.
Datenoffset
Beim Debuggen im Benutzermodus ist der Datenoffset eines (System-)Threads der Speicherort des TEB für diesen Thread. Beim Debuggen im Kernelmodus ist der Datenoffset eines (virtuellen) Threads die KTHREAD-Struktur für den Systemthread, der auf dem entsprechenden Prozessor ausgeführt wurde, als das letzte Ereignis aufgetreten ist. Der Datenoffset des aktuellen Threads kann mithilfe von GetCurrentThreadDataOffset gefunden werden. Für einen bestimmten Datenoffset kann die entsprechende Enginethread-THREAD-ID mithilfe von GetThreadIdByDataOffset gefunden werden.
Systemhandle
Das Systemhandle des aktuellen Threads kann mithilfe von GetCurrentThreadHandle gefunden werden. Für ein bestimmtes Systemhandle kann die entsprechende Enginethread-ID mithilfe von GetThreadIdByHandle gefunden werden. Beim Debuggen im Kernelmodus wird für jeden (virtuellen) Prozess ein künstlicher Handle erstellt. Dieses Handle kann nur mit API-Abfragen der Debugger-Engine verwendet werden.
Prozesse
Die Engine-Prozess-ID wird von der Debugger-Engine verwendet, um jeden Betriebssystemprozess und jeden virtuellen Prozess für ein Ziel zu identifizieren.
Während ein Ziel beendet wird, verfügt jeder Prozess relativ zum Ziel über einen Index. Der Index des ersten Prozesses im Ziel ist 0, und der Index des letzten Prozesses ist die Anzahl der Prozesse im Ziel minus 1. Die Anzahl der Prozesse im aktuellen Ziel kann mithilfe von GetNumberProcesses ermittelt werden.
Die Engineprozess-ID und die Systemprozess-ID für einen oder mehrere Threads im aktuellen Ziel können mithilfe von GetProcessIdsByIndex aus ihrem Index ermittelt werden.
Die Engine verwaltet mehrere Informationen zu jedem Prozess. Diese Informationen können für den aktuellen Prozess abgefragt und verwendet werden, um die Engine-Prozess-ID für einen Prozess zu ermitteln.
Systemprozess-ID (nur Debuggen im Benutzermodus)
Die Systemprozess-ID des aktuellen Prozesses kann mithilfe von GetCurrentProcessSystemId ermittelt werden. Für eine bestimmte Systemprozess-ID kann die entsprechende Engine-Prozess-ID mithilfe von GetProcessIdBySystemId gefunden werden.
Prozessumgebungsblock (PEB)
Die Adresse des PEB für den aktuellen Prozess kann mithilfe von GetCurrentProcessPeb ermittelt werden. Für eine bestimmte PEB-Adresse kann die entsprechende Engine-Prozess-ID mithilfe von GetProcessIdByPeb gefunden werden. Beim Debuggen im Kernelmodus ist die PEB des (virtuellen) Prozesses die PEB des Systemprozesses, der ausgeführt wurde, als das letzte Ereignis aufgetreten ist.
Datenoffset
Beim Debuggen im Benutzermodus ist der Datenoffset eines (System-)Prozesses der Speicherort des PEB dieses Prozesses. Beim Debuggen im Kernelmodus ist der Datenoffset des (virtuellen) Prozesses die KPROCESS-Struktur für den Systemprozess, der ausgeführt wurde, als das letzte Ereignis aufgetreten ist. Der Datenoffset des aktuellen Prozesses kann mithilfe von GetCurrentProcessDataOffset ermittelt werden. Für einen bestimmten Datenoffset kann die entsprechende Engine-Prozess-ID mithilfe von GetProcessIdByDataOffset gefunden werden.
Systemhandle
Das Systemhandle des aktuellen Prozesses finden Sie mithilfe von GetCurrentProcessHandle. Für ein bestimmtes Systemhandle kann die entsprechende Engine-Prozess-ID mithilfe von GetProcessIdByHandle gefunden werden. Beim Debuggen im Kernelmodus wird ein künstlicher Handle für den (virtuellen) Prozess erstellt. Dieses Handle kann nur mit Debuggermodulabfragen verwendet werden.
Events
Beim Debuggen im Livebenutzermodus werden die Debugereignisse create-thread und exit-thread generiert, wenn ein Thread in einem Ziel erstellt oder beendet wird. Diese Ereignisse führen zu Aufrufen der Rückrufmethoden IDebugEventCallbacks::CreateThread und IDebugEventCallbacks::ExitThread .
Beim Debuggen im Livebenutzermodus werden immer dann, wenn ein Prozess in einem Ziel erstellt oder beendet wird, die Debugereignisse create-process und exit-process generiert. Diese Ereignisse führen zu Aufrufen der Rückrufmethoden IDebugEventCallbacks::CreateProcess und IDebugEventCallbacks::ExitProcess .
Weitere Informationen zu Ereignissen finden Sie unter Überwachen von Ereignissen.
Weitere Informationen
Weitere Informationen zu Threads und Prozessen, einschließlich der TEB-, KTHREAD-, PEB- und KPROCESS-Strukturen, finden Sie unter Microsoft Windows Internals von David Solomon und Mark Russinovich.