Mempelajari Pelacakan Peristiwa untuk Windows: Teori dan Praktik

Selamat sore. Baru-baru ini, saya perlu berurusan dengan layanan jejak Windows. Layanan ini muncul di Windows 2000, namun, ada sangat sedikit artikel tentang layanan ini di Internet, sehingga muncul ide untuk menulis artikel ini. Jadi, mari kita mulai!

Hari ini saya akan mencoba berbicara tentang:

  1. Teori Layanan Tracing Windows
  2. Membuat Sesi ETW Anda
  3. Menggunakan API penelusuran peristiwa untuk bekerja dengan ETW
  4. Menggunakan tracerpt dan xperf untuk bekerja dengan ETW

Teori Layanan Tracing Windows


Pelacakan Peristiwa untuk Windows (ETW) adalah layanan yang memungkinkan Anda untuk menerima acara dari satu atau lebih penyedia acara secara langsung atau dari file * .etl untuk periode waktu tertentu. Tidak jelas? Sekarang mari kita cari tahu!

Untuk memahami cara kerja ETW, Anda perlu memahami struktur layanan ini.

gambar

Arsitektur ETW mencakup 4 elemen

  1. penyedia acara
  2. konsumen acara
  3. Pengontrol ETW
  4. Sesi ETW (sesi pelacakan acara)

Prinsip operasi adalah sebagai berikut.

Sejumlah penyedia acara terdaftar dalam sistem, mis. aplikasi yang dapat berbagi pengalaman mereka dengan sesi ETW. Juga dalam sistem ini ada sejumlah sesi ETW aktif yang dapat mengkonsumsi acara dari satu atau lebih penyedia dan memberikannya kepada pengguna baik secara real time atau menulis semua peristiwa dari pemasok ke file log (* .etl). Dan pengendali mengendalikan seluruh gerakan ini.

Dan sekarang kita akan mempertimbangkan setiap elemen arsitektur yang dibahas di atas secara lebih rinci untuk akhirnya memahami prinsip kerja!

Penyedia Acara


Penyedia acara adalah aplikasi yang berisi alat pelacak peristiwa. Setelah penyedia terdaftar, pengontrol dapat mengaktifkan atau menonaktifkan pelacakan peristiwa di penyedia. Penyedia menentukan interpretasinya on atau off. Biasanya, penyedia yang diaktifkan menghasilkan peristiwa, tetapi penyedia yang dinonaktifkan tidak. Ini memungkinkan Anda untuk menambahkan pelacakan acara ke aplikasi kami tanpa harus membuat acara setiap saat.

Satu vendor dapat membagikan acara mereka dengan beberapa sesi ETW sekaligus.

Setiap acara terdiri dari dua elemen: header dan data! Header acara mencakup informasi tentang acara: pengidentifikasi penyedia, pengidentifikasi acara, stempel waktu, dll. Sisa data ditentukan oleh penyedia tertentu: ETW menerima data apa pun dan menulisnya ke buffer, dan interpretasinya diberikan kepada konsumen informasi.
Ada empat jenis utama penyedia: penyedia

MOF (klasik)
penyedia WPP
berdasarkan
TraceLogging penyedia nyata.

Penyedia acara berbeda dalam jenis bidang yang mereka simpan dalam muatan acara.

Penyedia acara tampaknya beres. Berpindah!

Pengontrol


Pengontrol adalah aplikasi yang bertanggung jawab untuk pengoperasian satu atau lebih sesi ETW. Ini adalah pengontrol yang menentukan ukuran dan lokasi file log, memulai dan menghentikan sesi pelacakan peristiwa (sesi ETW), dan memungkinkan penyedia untuk merekam acara dalam sesi. Seperti yang disebutkan sebelumnya, itu adalah pengontrol yang memungkinkan penyedia untuk berbagi acara mereka!

Konsumen


Konsumen adalah aplikasi yang menerima dan memproses acara dari satu sesi jejak atau lebih pada saat yang sama. Konsumen dapat menerima acara yang disimpan dalam file log atau dari sesi yang menyampaikan acara secara real time. Seperti yang sudah kita ketahui, satu sesi ETW dapat memiliki beberapa pemasok. Muncul pertanyaan: apakah akan ada kebingungan? Bagaimana acara dari berbagai sesi ETW saling berhubungan? Peristiwa diurutkan berdasarkan waktu terjadinya, yaitu sistem menghadirkan peristiwa dalam urutan kronologis!

Sesi ETW


Sesi pelacakan peristiwa (sesi ETW) merekam acara dari satu atau lebih penyedia yang diizinkan oleh pengontrol. Sesi ini juga bertanggung jawab untuk mengelola dan membersihkan buffer.

Pelacakan Peristiwa mendukung hingga 64 pelacakan sesi sesi berjalan secara bersamaan. Dari sesi-sesi ini, ada dua sesi dengan tujuan khusus. Sesi yang tersisa tersedia untuk penggunaan umum. Dua sesi tujuan khusus:

  • Sesi logger global
  • Sesi Logger Kernel NT

Sesi pelacakan peristiwa Global Logger mencatat peristiwa yang terjadi pada awal proses boot sistem operasi, seperti yang dihasilkan oleh driver perangkat.
Sesi Pelacakan Kejadian NT Sesi Kernel Logger mencatat peristiwa sistem yang telah ditetapkan yang dihasilkan oleh sistem operasi, seperti peristiwa I / O disk atau kegagalan halaman.

Jadi, sekarang mari kita berlatih !!!

Membuat Sesi ETW Anda


Sebelum mulai bekerja, kita perlu pengetahuan tentang beberapa utilitas, yaitu:

daftar penyedia yang tersedia pada OS tertentu

logman query providers

dapatkan informasi lengkap tentang penyedia

wevtutil gp < > /ge /gm

daftar semua sesi ETW aktif

xperf -loggers

Juga, untuk melihat file, disarankan untuk memiliki Notepad ++.

Setelah melihat daftar penyedia di komputer Anda (dan ada lebih dari 1000 di Windows 10), kami akan memilih salah satunya untuk sesi kami:

gambar

Saya memilih Microsoft-Windows-WinINet (layanan ini mencatat semua tindakan kami saat bekerja di browser Microsoft Edge).

1. Win + R -> compmgmt.msc
2. "Kinerja"
3. "Set Kolektor Data"
4. "Sesi Jejak Acara"
5. "Baru"
6. "Set Pengumpul Data"
7. Tetapkan nama pengumpul data
8. "Buat secara manual (Lanjutan)" ("Buat secara manual (untuk yang berpengalaman)")

gambar
9. Tambahkan yang menarik kami penyedia per sesi
10. Tentukan kata kunci yang menarik bagi kami di bidang β€œKata Kunci (Apa Saja)” - 0xFFFFFFFFFFFFFFFFFFFF
11. Tentukan tingkat pencatatan 0xFF
= gambar

12. Pilih jalur tempat file log sesi akan disimpan
13. Pilih " Mulai kumpulan pengumpul data ini sekarang ”(β€œ Jalankan grup pengumpul data sekarang ”)

Sekarang sesi yang kami buat berhasil. Microsoft Edge memerlukan beberapa pekerjaan untuk mendapatkan sesi untuk mengumpulkan informasi tentang kami!

Setelah beberapa waktu berlalu, kami pergi ke tempat kami menyimpan file log. Kami menjalankan perintah berikut di sana.

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

Setelah menjalankan perintah ini, 4 file akan dibuat.

gambar

Kami saat ini tertarik pada dumpfile.xml. Anda dapat membuka file ini melalui notepad ++, Anda juga dapat melakukannya di Excel.

Setelah mempelajari file ini dengan cermat, Anda dapat melihat bahwa sesi ini mengumpulkan hampir semua informasi tentang pergerakan kami di Internet !!! Anda dapat membaca lebih lanjut tentang ini di sini. Kami mempelajari ETW dan mendapatkan keuntungan .

Baiklah, dan kita melanjutkan. Kami baru saja membuat sesi dengan penyedia acara tunggal. Menerima data sesi dari file log. Sudah waktunya untuk kode!

Menggunakan API penelusuran peristiwa untuk bekerja dengan ETW


Di habr ada artikel yang menarik, API Terburuk yang pernah dibuat .

Dalam artikel ini Anda akan menemukan jawaban untuk banyak pertanyaan yang kemungkinan besar akan Anda miliki ketika menulis aplikasi!

Kami akan kode dalam C ++.

Mari kita mulai dengan yang paling sederhana.

Konfigurasikan dan mulai sesi pelacakan acara


Pertama, pertimbangkan gagasan umum.

Untuk memulai sesi penelusuran:

1) Tetapkan struktur EVENT_TRACE_PROPERTIES

2) Mulai sesi dengan menggunakan StartTrace
Selanjutnya, aktifkan penyedia acara

3) Nyalakan penyedia menggunakan EnableTrace | EnableTraceEx | EnableTraceEx2
Untuk menghentikan sesi pelacakan, Anda harus:

4) Sebelum menghentikan sesi pelacakan, Anda harus menonaktifkan penyedia menggunakan EnableTrace | EnableTraceEx | EnableTraceEx2, melewati EVENT_CONTROL_CODE_DISABLE_PROVIDER

5) Panggil fungsi ControlTrace dan berikan EVENT_TRACE_CONTROL_STOP

Dalam contoh di bawah ini, saya membuat sesi yang disebut MyEventTraceSession. File log dalam direktori saat ini disebut WriteThePuth.etl.

Penyedia acara adalah Microsoft-Windows-Kernel-Process. Anda dapat mengetahui GUID-nya menggunakan

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

Kode langsung:

#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;
    }
}

Kami akan menganalisis program di atas secara lebih rinci.

1) Setel struktur EVENT_TRACE_PROPERTIES

Untuk mengonfigurasi sesi penelusuran peristiwa, Anda harus menggunakan struktur EVENT_TRACE_PROPERTIES untuk menentukan properti sesi. Memori yang Anda alokasikan untuk struktur EVENT_TRACE_PROPERTIES harus cukup besar untuk juga memuat nama-nama sesi dan log file yang mengikuti struktur dalam memori.

2) Mulai sesi menggunakan StartTrace

Setelah Anda menentukan properti sesi, panggil fungsi StartTrace untuk memulai sesi. Jika fungsi berhasil, parameter SessionHandle akan berisi deskriptor sesi, dan properti LoggerNameOffset akan berisi offset nama sesi.

3) Nyalakan penyedia menggunakan EnableTrace | EnableTraceEx | EnableTraceEx2

Untuk mengaktifkan penyedia yang ingin Anda izinkan merekam peristiwa di sesi Anda, panggil fungsi EnableTrace untuk mengaktifkan penyedia klasik dan fungsi EnableTraceEx untuk mengaktifkan penyedia berbasis manifes. Dalam kasus lain - EnableTraceEx2.

4) Sebelum menghentikan sesi penelusuran, Anda harus menonaktifkan penyedia menggunakan EnableTrace | EnableTraceEx | AktifkanTraceEx2 dengan mengirimkan EVENT_CONTROL_CODE_DISABLE_PROVIDER

Untuk menghentikan sesi penelusuran setelah mengumpulkan acara, panggil fungsi ControlTrace dan berikan EVENT_TRACE_CONTROL_STOP sebagai kode kontrol. Untuk menentukan sesi yang akan dihentikan, Anda bisa meneruskan deskriptor sesi jejak acara yang diperoleh dari panggilan sebelumnya ke fungsi StartTrace, atau nama sesi yang dimulai sebelumnya. Pastikan untuk memutuskan koneksi semua penyedia sebelum menghentikan sesi. Jika Anda menghentikan sesi sebelum mematikan penyedia untuk pertama kalinya, ETW akan memutuskan sambungan penyedia dan mencoba memanggil fungsi kontrol panggilan balik penyedia. Jika aplikasi yang memulai sesi berakhir tanpa memutuskan penyedia atau memanggil fungsi ControlTrace, penyedia tetap dihidupkan.

5) Untuk menghentikan sesi penelusuran, panggil fungsi ControlTrace dan berikan EVENT_TRACE_CONTROL_STOP

Seperti yang kita lihat dalam contoh di atas, menggunakan API Pelacakan Peristiwa bukan yang termudah. Bergantung pada apa yang Anda lakukan, Anda dapat terus menulis penyedia acara atau menulis acara konsumen. Namun, kedua tugas ini cukup banyak dan tidak akan dipertimbangkan dalam artikel ini! Kompleksitas tambahan dibuat oleh 4 jenis penyedia acara, dan, karenanya, 4 opsi untuk menulis acara dan 4 opsi untuk konsumsi mereka. Bekerja dengan API Pelacakan Peristiwa dijelaskan dengan sangat rinci dan baik di Situs Web Microsoft resmi Menggunakan Pelacakan Peristiwa

Setelah bekerja selama beberapa waktu dengan API Pelacakan Peristiwa, saya punya pertanyaan: apakah ada utilitas yang akan menyederhanakan hidup saya?

Menggunakan tracerpt dan xperf untuk bekerja dengan ETW


Dalam bab ini, saya tidak akan mempertimbangkan utilitas ini dari sudut pandang teoritis.

Anda dapat menggunakan perintah Tracerpt untuk menganalisis log pelacakan peristiwa, file log yang dihasilkan oleh monitor kinerja, dan penyedia pelacakan peristiwa real-time. Ini membuat file dump, file laporan, dan skema laporan. Utilitas ini memiliki sejumlah besar parameter, tetapi "minimum" berikut ini cocok untuk memulai pekerjaan

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

Utilitas xperf.exe adalah pengontrol lengkap. Ini mendukung argumen baris perintah untuk mengelola penyedia dan sesi ETW. Pengontrol dapat meminta status sesi aktif saat ini dan menerima daftar semua penyedia yang terdaftar dalam sistem. Misalnya, untuk mendapatkan semua sesi aktif, gunakan perintah berikut:

C:\>xperf -loggers

dan untuk mendapatkan daftar semua penyedia yang terdaftar dalam sistem, gunakan perintah:

C:\>xperf -providers

Pengendali memiliki beberapa fitur utama. Mereka dapat memperbarui sesi dan menyiram buffer ke disk.

Itu saja untuk saat ini!

Sayangnya, dalam artikel ini saya tidak membahas sejumlah masalah menarik (misalnya, konsumsi acara secara real time atau bekerja dengan sesi tujuan khusus).

Anda dapat membacanya di situs berikut:

Pelacakan Peristiwa - dokumentasi Microsoft resmi.
Kami mempelajari ETW dan mengekstrak manfaat
Pelacakan Peristiwa untuk Windows di sisi jahat. Tapi ini bukan
API terburuk yang pernah dibuat

All Articles