Lernereignisverfolgung für Windows: Theorie und Praxis

Guten Tag. Vor kurzem musste ich mich mit dem Windows-Ablaufverfolgungsdienst befassen. Dieser Dienst wurde in Windows 2000 veröffentlicht. Es gab jedoch nur sehr wenige Artikel zu diesem Dienst im Internet. Daher kam die Idee, diesen Artikel zu schreiben. Also fangen wir an!

Heute werde ich versuchen zu sprechen über:

  1. Theorie des Windows-Ablaufverfolgungsdienstes
  2. Erstellen Ihrer ETW-Sitzung
  3. Verwenden der Ereignisverfolgungs-API für die Arbeit mit ETW
  4. Verwenden von Tracerpt und Xperf für die Arbeit mit ETW

Theorie des Windows-Ablaufverfolgungsdienstes


Event Tracing für Windows (ETW) ist ein Dienst, mit dem Sie Ereignisse von einem oder mehreren Ereignisanbietern in Echtzeit oder aus einer * .etl-Datei für einen bestimmten Zeitraum empfangen können. Unverständlich? Jetzt lass es uns herausfinden!

Um zu verstehen, wie ETW funktioniert, müssen Sie die Struktur dieses Dienstes verstehen. Die

Bild

ETW-Architektur enthält 4 Elemente

  1. Eventanbieter
  2. Event-Konsumenten
  3. ETW-Controller
  4. ETW-Sitzungen (Event-Tracing-Sitzungen)

Das Funktionsprinzip ist wie folgt.

Eine Anzahl von Ereignisanbietern ist im System registriert, d.h. Anwendungen, die ihre Erfahrungen mit ETW-Sitzungen teilen können. Auch in diesem System gibt es eine bestimmte Anzahl aktiver ETW-Sitzungen, die Ereignisse von einem oder mehreren Anbietern verarbeiten und dem Benutzer entweder in Echtzeit zur Verfügung stellen oder alle Ereignisse von Lieferanten in eine Protokolldatei (* .etl) schreiben können. Und Controller steuern diese ganze Bewegung.

Und jetzt werden wir jedes Element der oben betrachteten Architektur genauer betrachten, um endlich das Prinzip der Arbeit zu verstehen!

Eventanbieter


Ereignisanbieter sind Anwendungen, die Ereignisverfolgungstools enthalten. Nachdem sich der Anbieter registriert hat, kann der Controller die Ereignisverfolgung im Anbieter aktivieren oder deaktivieren. Der Anbieter bestimmt seine Interpretation von Ein oder Aus. In der Regel generiert ein aktivierter Anbieter Ereignisse, ein deaktivierter Anbieter jedoch nicht. Auf diese Weise können Sie unserer Anwendung Ereignisverfolgung hinzufügen, ohne dass ständig Ereignisse generiert werden müssen.

Ein Anbieter kann seine Ereignisse für mehrere ETW-Sitzungen gleichzeitig freigeben.

Jedes Ereignis besteht aus zwei Elementen: einem Header und Daten! Der Ereigniskopf enthält Informationen zum Ereignis: Anbieterkennung, Ereigniskennung, Zeitstempel usw. Der Rest der Daten wird von einem bestimmten Anbieter festgelegt: ETW empfängt alle Daten und schreibt sie in den Puffer, und ihre Interpretation wird den Verbrauchern von Informationen zugewiesen.
Es gibt vier Haupttypen von Anbietern:

MOF-Anbieter (klassische)
Anbieter WPP-
Anbieter basierend auf den Manifest-
Anbietern TraceLogging.

Ereignisanbieter unterscheiden sich in den Feldtypen, die sie in Ereignisnutzdaten speichern.

Eventanbieter scheinen aussortiert zu sein. Mach weiter!

Controller


Ein Controller ist eine Anwendung, die für den Betrieb einer oder mehrerer ETW-Sitzungen verantwortlich ist. Es ist der Controller, der die Größe und den Speicherort der Protokolldatei bestimmt, Ereignisverfolgungssitzungen (ETW-Sitzungen) startet und stoppt und es Anbietern ermöglicht, Ereignisse in der Sitzung aufzuzeichnen. Wie bereits erwähnt, ist es der Controller, der es dem Anbieter ermöglicht, seine Ereignisse zu teilen!

Verbraucher


Verbraucher sind Anwendungen, die Ereignisse von einer oder mehreren Ablaufverfolgungssitzungen gleichzeitig empfangen und verarbeiten. Verbraucher können Ereignisse empfangen, die in Protokolldateien oder aus Sitzungen gespeichert sind, die Ereignisse in Echtzeit liefern. Wie wir bereits wissen, kann eine ETW-Sitzung mehrere Lieferanten haben. Es stellt sich die Frage: Wird es Verwirrung geben? In welcher Beziehung stehen die Ereignisse der verschiedenen ETW-Sitzungen zueinander? Ereignisse werden nach dem Zeitpunkt ihres Auftretens sortiert, d. H. Das System liefert Ereignisse in chronologischer Reihenfolge!

ETW-Sitzungen


Ereignisverfolgungssitzungen (ETW-Sitzungen) zeichnen Ereignisse von einem oder mehreren Anbietern auf, die der Controller zulässt. Die Sitzung ist auch für die Verwaltung und das Löschen von Puffern verantwortlich.

Die Ereignisverfolgung unterstützt bis zu 64 Ereignisverfolgungssitzungen, die gleichzeitig ausgeführt werden. Von diesen Sitzungen gibt es zwei spezielle Sitzungen. Die verbleibenden Sitzungen stehen für den allgemeinen Gebrauch zur Verfügung. Zwei spezielle Sitzungen:

  • Globale Loggersitzung
  • NT Kernel Logger Session

Eine Global Logger-Ereignisablaufverfolgungssitzung zeichnet Ereignisse auf, die zu Beginn des Startvorgangs des Betriebssystems auftreten, z. B. solche, die von Gerätetreibern generiert werden.
Der Kernel Logger für NT-Ereignisverfolgungssitzungen zeichnet vordefinierte Systemereignisse auf, die vom Betriebssystem generiert wurden, z. B. Festplatten-E / A-Ereignisse oder Seitenfehler.

Also, jetzt lass uns üben !!!

Erstellen Ihrer ETW-Sitzung


Bevor wir mit der Arbeit beginnen, benötigen wir Kenntnisse über verschiedene Dienstprogramme, nämlich: eine

Liste der Anbieter, die auf einem bestimmten Betriebssystem verfügbar sind

logman query providers

Erhalten Sie vollständige Informationen über den Anbieter

wevtutil gp < > /ge /gm

Liste aller aktiven ETW-Sitzungen

xperf -loggers

Zum Anzeigen von Dateien ist außerdem Notepad ++ ratsam.

Nachdem wir uns die Liste der Anbieter auf Ihrem Computer angesehen haben (und es gibt mehr als 1000 unter Windows 10), wählen wir einen für unsere Sitzung aus:

Bild

Ich habe Microsoft-Windows-WinINet ausgewählt (dieser Dienst zeichnet alle unsere Aktionen auf, wenn Sie im Microsoft Edge-Browser arbeiten).

1. Win + R -> compmgmt.msc
2. "Leistung"
3. " Datenkollektorsätze "
4. "Ereignisablaufverfolgungssitzungen"
5. "Neu"
6. "Datenkollektorsatz"
7. Geben Sie den Namen des Datenkollektors an.
8. "Manuell erstellen (Erweitert)" (Manuell hinzufügen (für erfahrene) ")

Bild
9. Interessant hinzufügen uns Anbieter pro Sitzung
10. Geben Sie die für uns interessanten Schlüsselwörter in das Feld „Schlüsselwörter (beliebig)“ ein - 0xFFFFFFFFFFFFFFFFFFFF
11. Geben Sie die Protokollierungsstufe 0xFF
= Bild

12 an. Wählen Sie den Pfad aus, in dem die Sitzungsprotokolldatei gespeichert werden soll
. Starten Sie diesen Datenkollektorsatz jetzt. “(„ Führen Sie jetzt die Gruppe der Datenkollektoren aus “)

Nun funktioniert die von uns erstellte Sitzung. Microsoft Edge benötigt einige Arbeit, damit die Sitzung Informationen über uns sammelt!

Nach einiger Zeit gehen wir zu dem Ort, an dem wir die Protokolldatei gespeichert haben. Wir führen dort den folgenden Befehl aus.

tracerpt "   .etl" -o -report -summary -lr

Nach Ausführung dieses Befehls werden 4 Dateien generiert.

Bild

Wir sind derzeit an dumpfile.xml interessiert. Sie können diese Datei entweder über Notepad ++ öffnen, dies können Sie auch in Excel tun.

Nachdem Sie diese Datei sorgfältig studiert haben, können Sie sehen, dass diese Sitzung fast alle Informationen über unsere Bewegung im Internet gesammelt hat !!! Hier können Sie mehr darüber lesen. Wir studieren ETW und extrahieren Gewinne .

Nun, und wir gehen weiter. Wir haben gerade eine Sitzung mit einem einzelnen Ereignisanbieter erstellt. Empfangene Sitzungsdaten aus der Protokolldatei. Es ist Zeit zu codieren!

Verwenden der Ereignisverfolgungs-API für die Arbeit mit ETW


Auf habr gibt es einen interessanten Artikel, die schlechteste API, die jemals erstellt wurde .

In diesem Artikel finden Sie Antworten auf viele Fragen, die Sie höchstwahrscheinlich beim Schreiben von Bewerbungen haben werden!

Wir werden in C ++ codieren.

Beginnen wir mit dem einfachsten.

Konfigurieren und starten Sie eine Ereignisverfolgungssitzung


Betrachten Sie zunächst die allgemeine Idee.

So starten Sie eine Ablaufverfolgungssitzung:

1) Legen Sie die Struktur EVENT_TRACE_PROPERTIES fest.

2) Starten Sie die Sitzung mit StartTrace
. Aktivieren Sie anschließend die Ereignisanbieter.

3) Aktivieren Sie die Anbieter mit EnableTrace | EnableTraceEx | EnableTraceEx2
Um die Ablaufverfolgungssitzung zu stoppen, müssen Sie:

4) Bevor Sie die Ablaufverfolgungssitzung beenden, müssen Sie die Anbieter mit EnableTrace | deaktivieren EnableTraceEx | EnableTraceEx2, EVENT_CONTROL_CODE_DISABLE_PROVIDER übergeben

5) Rufen Sie die ControlTrace-Funktion auf und übergeben Sie sie EVENT_TRACE_CONTROL_STOP

Im folgenden Beispiel erstelle ich eine Sitzung mit dem Namen MyEventTraceSession. Die Protokolldatei im aktuellen Verzeichnis heißt WriteThePuth.etl.

Der Ereignisanbieter ist Microsoft-Windows-Kernel-Process. Sie können seine GUID mit herausfinden

wevtutil gp Microsoft-Windows-Kernel-Process /ge /gm

Code direkt:

#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <strsafe.h>
#include <wmistr.h>
#include <evntrace.h>
#include <iostream>
#define LOGFILE_PATH L"WriteThePuth.etl"
#define LOGSESSION_NAME L"MyEventTraceSession"


// GUID,     .
//      GUID .

// {AE44CB98-BD11-4069-8093-770EC9258A12}
static const GUID SessionGuid =
{ 0xae44cb98, 0xbd11, 0x4069, { 0x80, 0x93, 0x77, 0xe, 0xc9, 0x25, 0x8a, 0x12 } };


// GUID,   ,   
//    .

//{22FB2CD6-0E7B-422B-A0C7-2FAD1FD0E716} Microsoft-Windows-Kernel-Process
static const GUID ProviderGuid =
{ 0xd22FB2CD6, 0x0E7B, 0x422B, {0xA0, 0xC7, 0x2F, 0xAD, 0x1F, 0xD0, 0xE7, 0x16 } };

void wmain(void)
{
    setlocale(LC_ALL, "ru");
    ULONG status = ERROR_SUCCESS;
    TRACEHANDLE SessionHandle = 0;
    EVENT_TRACE_PROPERTIES* pSessionProperties = NULL;
    ULONG BufferSize = 0;
    BOOL TraceOn = TRUE;

    
    BufferSize = sizeof(EVENT_TRACE_PROPERTIES) + sizeof(LOGFILE_PATH) + sizeof(LOGSESSION_NAME);
    pSessionProperties = (EVENT_TRACE_PROPERTIES*)malloc(BufferSize);
    if (NULL == pSessionProperties)
    {
        wprintf(L"Unable to allocate %d bytes for properties structure.\n", BufferSize);
        goto cleanup;
    }

    ZeroMemory(pSessionProperties, BufferSize);
    pSessionProperties->Wnode.BufferSize = BufferSize;
    pSessionProperties->Wnode.Flags = WNODE_FLAG_TRACED_GUID;
    pSessionProperties->Wnode.ClientContext = 1; //QPC clock resolution
    pSessionProperties->Wnode.Guid = SessionGuid;
    pSessionProperties->LogFileMode = EVENT_TRACE_FILE_MODE_SEQUENTIAL;
    pSessionProperties->MaximumFileSize = 1024;  // 1024 MB
    pSessionProperties->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
    pSessionProperties->LogFileNameOffset = sizeof(EVENT_TRACE_PROPERTIES) + sizeof(LOGSESSION_NAME);
    StringCbCopy((LPWSTR)((char*)pSessionProperties + pSessionProperties->LogFileNameOffset), sizeof(LOGFILE_PATH), LOGFILE_PATH);
    

    status = StartTrace((PTRACEHANDLE)&SessionHandle, LOGSESSION_NAME, pSessionProperties);
    if (ERROR_SUCCESS != status)
    {
        wprintf(L"StartTrace() failed with %lu\n", status);
        goto cleanup;
    }

    //  ,   ,      .

    status = EnableTraceEx2(
        SessionHandle,
        (LPCGUID)&ProviderGuid,
        EVENT_CONTROL_CODE_ENABLE_PROVIDER,
        TRACE_LEVEL_INFORMATION,
        0,
        0,
        0,
        NULL
        );

    if (ERROR_SUCCESS != status)
    {
        wprintf(L"EnableTrace() failed with %lu\n", status);
        TraceOn = FALSE;
        goto cleanup;
    }

    //   .    ,   
    wprintf(L"Run the provider application. Then hit any key to stop the session.\n");
    _getch();
   

cleanup:
    if (SessionHandle)
    {
        if (TraceOn)
        {
            status = EnableTraceEx2(
                SessionHandle,
                (LPCGUID)&ProviderGuid,
                EVENT_CONTROL_CODE_DISABLE_PROVIDER,
                TRACE_LEVEL_INFORMATION,
                0,
                0,
                0,
                NULL
                );
        }

        status = ControlTrace(SessionHandle, LOGSESSION_NAME, pSessionProperties, EVENT_TRACE_CONTROL_STOP);

        if (ERROR_SUCCESS != status)
        {
            wprintf(L"ControlTrace(stop) failed with %lu\n", status);
        }
    }

    if (pSessionProperties)
    {
        free(pSessionProperties);
        pSessionProperties = NULL;
    }
}

Wir werden das obige Programm genauer analysieren.

1) Festlegen der Struktur EVENT_TRACE_PROPERTIES

Um eine Ereignisablaufverfolgungssitzung zu konfigurieren, müssen Sie die Struktur EVENT_TRACE_PROPERTIES verwenden, um Sitzungseigenschaften anzugeben. Der Speicher, den Sie für die Struktur EVENT_TRACE_PROPERTIES zuweisen, muss groß genug sein, um auch die Namen der Sitzungs- und Protokolldateien zu enthalten, die der Struktur im Speicher folgen.

2) Starten Sie die Sitzung mit StartTrace.

Nachdem Sie die Eigenschaften der Sitzung angegeben haben, rufen Sie die StartTrace-Funktion auf, um die Sitzung zu starten. Wenn die Funktion erfolgreich ist, enthält der Parameter SessionHandle den Sitzungsdeskriptor und die Eigenschaft LoggerNameOffset den Offset des Sitzungsnamens.

3) Schalten Sie Anbieter mit EnableTrace | ein EnableTraceEx | EnableTraceEx2

Um die Anbieter zu aktivieren, denen das Aufzeichnen von Ereignissen in Ihrer Sitzung gestattet werden soll, rufen Sie die EnableTrace-Funktion auf, um klassische Anbieter zu aktivieren, und die EnableTraceEx-Funktion, um manifestbasierte Anbieter zu aktivieren. In anderen Fällen - EnableTraceEx2.

4) Bevor Sie die Ablaufverfolgungssitzung beenden, müssen Sie Anbieter mit EnableTrace | deaktivieren EnableTraceEx | Aktivieren SieTraceEx2, indem Sie EVENT_CONTROL_CODE_DISABLE_PROVIDER übergeben

Um die Ablaufverfolgungssitzung nach dem Sammeln von Ereignissen zu stoppen, rufen Sie die ControlTrace-Funktion auf und übergeben Sie EVENT_TRACE_CONTROL_STOP als Steuercode. Um eine zu stoppende Sitzung anzugeben, können Sie den Sitzungsdeskriptor der Ereignisablaufverfolgung, der aus einem früheren Aufruf erhalten wurde, an die StartTrace-Funktion oder den Namen einer zuvor gestarteten Sitzung übergeben. Stellen Sie sicher, dass Sie alle Anbieter trennen, bevor Sie die Sitzung beenden. Wenn Sie die Sitzung beenden, bevor Sie den Provider zum ersten Mal ausschalten, trennt ETW den Provider und versucht, die Provider-Rückrufsteuerungsfunktion aufzurufen. Wenn die Anwendung, die die Sitzung gestartet hat, beendet wird, ohne den Anbieter zu trennen oder die ControlTrace-Funktion aufzurufen, bleibt der Anbieter aktiviert.

5) Um die Ablaufverfolgungssitzung zu stoppen, rufen Sie die ControlTrace-Funktion auf und übergeben Sie sie EVENT_TRACE_CONTROL_STOP

Wie wir im obigen Beispiel gesehen haben, ist die Verwendung der Ereignisverfolgungs-API nicht die einfachste. Je nachdem, was Sie tun, können Sie weiterhin Ereignisanbieter oder Ereigniskonsumenten schreiben. Beide Aufgaben sind jedoch recht umfangreich und werden in diesem Artikel nicht berücksichtigt! Zusätzliche Komplexität wird durch 4 Arten von Ereignisanbietern und dementsprechend 4 Optionen zum Schreiben von Ereignissen und 4 Optionen für deren Konsum erzeugt. Die Arbeit mit der Event-Tracing-API wird auf der offiziellen Microsoft-Website mit Event-Tracing ausführlich und ausführlich beschrieben.

Nachdem ich einige Zeit mit der Event-Tracing-API gearbeitet hatte, hatte ich die Frage: Gibt es Dienstprogramme, die mein Leben vereinfachen?

Verwenden von Tracerpt und Xperf für die Arbeit mit ETW


In diesem Kapitel werde ich diese Dienstprogramme aus theoretischer Sicht nicht betrachten.

Mit dem Befehl Tracerpt können Sie Ereignisablaufverfolgungsprotokolle, vom Leistungsmonitor generierte Protokolldateien und Echtzeit-Ereignisablaufverfolgungsanbieter analysieren. Es werden Speicherauszugsdateien, Berichtsdateien und Berichtsschemata erstellt. Dieses Dienstprogramm verfügt über eine große Anzahl von Parametern, aber das folgende "Minimum" eignet sich zum Starten der Arbeit

tracerpt " 1- .etl" ... " n- .etl" -o <   > -report <    > -summary<    > 

Das Dienstprogramm xperf.exe ist ein vollwertiger Controller. Es unterstützt Befehlszeilenargumente zum Verwalten von ETW-Anbietern und -Sitzungen. Controller können den Status aktuell aktiver Sitzungen anfordern und Listen aller im System registrierten Anbieter empfangen. Verwenden Sie beispielsweise den folgenden Befehl, um alle aktiven Sitzungen abzurufen:

C:\>xperf -loggers

Verwenden Sie den folgenden Befehl, um eine Liste aller im System registrierten Anbieter zu erhalten:

C:\>xperf -providers

Controller verfügen über einige weitere wichtige Funktionen. Sie können Sitzungen aktualisieren und Puffer auf die Festplatte leeren.

Das ist alles für jetzt!

Leider habe ich in diesem Artikel einige interessante Themen nicht angesprochen (z. B. den Verbrauch von Ereignissen in Echtzeit oder die Arbeit mit speziellen Sitzungen).

Sie können darüber auf den folgenden Websites lesen:

Ereignisverfolgung - offizielle Microsoft-Dokumentation.
Wir untersuchen ETW und extrahieren die Vorteile der
Ereignisverfolgung für Windows auf der bösen Seite. Dies ist jedoch nicht gerade die
schlechteste API, die jemals erstellt wurde

All Articles