Microsoft MVP성태의 닷넷 이야기
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일

(시리즈 글이 11개 있습니다.)
.NET Framework: 475. ETW(Event Tracing for Windows)를 C#에서 사용하는 방법
; https://www.sysnet.pe.kr/2/0/1804

.NET Framework: 483. 코드로 살펴 보는 ETW의 활성화 시점
; https://www.sysnet.pe.kr/2/0/1815

.NET Framework: 915. ETW(Event Tracing for Windows)를 이용한 닷넷 프로그램의 내부 이벤트 활용
; https://www.sysnet.pe.kr/2/0/12244

.NET Framework: 923. C# - ETW(Event Tracing for Windows)를 이용한 Finalizer 실행 감시
; https://www.sysnet.pe.kr/2/0/12255

.NET Framework: 932. C# - ETW 관련 Win32 API 사용 예제 코드 (1)
; https://www.sysnet.pe.kr/2/0/12292

.NET Framework: 933. C# - ETW 관련 Win32 API 사용 예제 코드 (2) NT Kernel Logger
; https://www.sysnet.pe.kr/2/0/12296

.NET Framework: 934. C# - ETW 관련 Win32 API 사용 예제 코드 (3) ETW Consumer 구현
; https://www.sysnet.pe.kr/2/0/12299

.NET Framework: 935. C# - ETW 관련 Win32 API 사용 예제 코드 (4) CLR ETW Consumer
; https://www.sysnet.pe.kr/2/0/12300

.NET Framework: 936. C# - ETW 관련 Win32 API 사용 예제 코드 (5) - Private Logger
; https://www.sysnet.pe.kr/2/0/12302

개발 환경 구성: 504. ETW - 닷넷 프레임워크 기반의 응용 프로그램을 위한 명령행 도구 etrace 소개
; https://www.sysnet.pe.kr/2/0/12303

.NET Framework: 994. C# - (.NET Core 2.2부터 가능한) 프로세스 내부에서 CLR ETW 이벤트 수신
; https://www.sysnet.pe.kr/2/0/12474




C# - ETW 관련 Win32 API 사용 예제 코드 (2) NT Kernel Logger

지난 글에 이어,

C# - ETW 관련 Win32 API 사용 예제 코드 (1)
; https://www.sysnet.pe.kr/2/0/12292

이번에는 ETW Consumer를 Win32 API를 이용해 작성해 보겠습니다.




우선 세션을 먼저 생성해야 하는데 이를 위해 StartTrace API를 사용할 수 있습니다.

string sessionName = NativeMethods.KERNEL_LOGGER_NAME; // KERNEL_LOGGER_NAME == "NT Kernel Logger"

EventTraceProperties prop = new EventTraceProperties(true, sessionName, NativeMethods.SystemTraceControlGuid); // SystemTraceControlGuid == 9e814aad-3204-11d2-9a82-006008a86939

result = NativeMethods.StartTrace(out sessionHandle, sessionName, ref prop);

위의 코드는 (xperf -providers 출력 결과의) ETW Provider 중 "Windows Kernel Trace" (9e814aad-3204-11d2-9a82-006008a86939)를 사용하는 코드로 예를 든 것입니다. 주의할 것은, SystemTraceControlGuid의 경우 반드시 세션 이름을 "NT Kernel Logger"로 해야 한다는 건데, 이런 사실은 다음의 글을 통해 알게 되었습니다.

THE WORST API EVER MADE
; https://caseymuratori.com/blog_0025

Configuring and Starting the NT Kernel Logger Session
; https://learn.microsoft.com/en-us/windows/win32/etw/configuring-and-starting-the-nt-kernel-logger-session

(제목에서 볼 수 있는 것처럼, 저 개인적으로도 ETW 관련 API의 이름이나 사용법이 체계적이지 않음을 100% 공감합니다. ^^;)

저렇게 세션을 생성했으면, (이전에 StartTrace라는 이름의 API를 호출했음에도) "Trace"를 "시작"하기 위해 OpenTrace API를 호출해야 합니다.

EventTraceLogfile logFile = new EventTraceLogfile();
logFile.LoggerName = sessionName;
logFile.EventRecordCallback = EventRecordCallback;

logFile.ProcessTraceMode = NativeMethods.PROCESS_TRACE_MODE_EVENT_RECORD | NativeMethods.PROCESS_TRACE_MODE_REAL_TIME
    | NativeMethods.PROCESS_TRACE_MODE_RAW_TIMESTAMP;
traceHandle = NativeMethods.OpenTrace(ref logFile);

static private void EventRecordCallback([In] ref EventRecord eventRecord)
{
    Console.WriteLine(DateTime.Now + ": " + eventRecord.EventHeader.ProcessId);
}

위의 코드는 이벤트가 발생했을 시 콜백을 실행하라고 등록하는데 원한다면 파일로도 지정할 수 있습니다. 하지만, 이렇게 등록했다고 해서 trace로 인한 콜백이 호출되는 것은 아닙니다. 콜백이 호출되려면 이후 ProcessTrace API를 호출해야 하는데, 이 함수는 호출 스레드를 블록시키기 때문에 보통 새로운 스레드를 생성해 호출하는 식으로 구현합니다.

new Thread((ThreadStart)(
() =>
{
    ProcessTrace(traceHandle);
})).Start();

Console.WriteLine("Press ENTER key to exit...");
Console.ReadLine();

public static int ProcessTrace(ulong traceHandle)
{
    ulong[] handles = { traceHandle };
    int result = NativeMethods.ProcessTrace(handles, (uint)handles.Length, IntPtr.Zero, IntPtr.Zero);
    return result;
}

마지막으로, ProcessTrace의 blocking 상태를 해제하려면 CloseTrace를 호출하고,

NativeMethods.CloseTrace(traceHandle);

세션까지 완전히 종료하려면 ControlTrace 호출로 마무리를 합니다.

// https://www.sysnet.pe.kr/2/0/12292#control_trace
EtwInterop.CloseActiveSession(sessionName);




"Windows Kernel Trace"의 경우, 기본적인 사용법은 위와 같은 순서로 구현할 수 있지만 한 가지 설명해야 할 것이 더 있습니다. 이에 대해서는 EVENT_TRACE_PROPERTIES 구조체 문서를 확인해야 하는데,

EVENT_TRACE_PROPERTIES structure
; https://learn.microsoft.com/en-us/windows/win32/api/evntrace/ns-evntrace-event_trace_properties

위의 글에 보면, "system logger" 유형인 경우 "EnableFlags"에 설정할 수 있는 값들을 설명하고 있습니다.

//
// Enable flags for Kernel Events
//
#define EVENT_TRACE_FLAG_PROCESS            0x00000001  // process start & end
#define EVENT_TRACE_FLAG_THREAD             0x00000002  // thread start & end
#define EVENT_TRACE_FLAG_IMAGE_LOAD         0x00000004  // image load

#define EVENT_TRACE_FLAG_DISK_IO            0x00000100  // physical disk IO
#define EVENT_TRACE_FLAG_DISK_FILE_IO       0x00000200  // requires disk IO

#define EVENT_TRACE_FLAG_MEMORY_PAGE_FAULTS 0x00001000  // all page faults
#define EVENT_TRACE_FLAG_MEMORY_HARD_FAULTS 0x00002000  // hard faults only

#define EVENT_TRACE_FLAG_NETWORK_TCPIP      0x00010000  // tcpip send & receive

#define EVENT_TRACE_FLAG_REGISTRY           0x00020000  // registry calls
#define EVENT_TRACE_FLAG_DBGPRINT           0x00040000  // DbgPrint(ex) Calls

//
// Enable flags for Kernel Events on Vista and above
//
#define EVENT_TRACE_FLAG_PROCESS_COUNTERS   0x00000008  // process perf counters
#define EVENT_TRACE_FLAG_CSWITCH            0x00000010  // context switches
#define EVENT_TRACE_FLAG_DPC                0x00000020  // deferred procedure calls
#define EVENT_TRACE_FLAG_INTERRUPT          0x00000040  // interrupts
#define EVENT_TRACE_FLAG_SYSTEMCALL         0x00000080  // system calls

#define EVENT_TRACE_FLAG_DISK_IO_INIT       0x00000400  // physical disk IO initiation
#define EVENT_TRACE_FLAG_ALPC               0x00100000  // ALPC traces
#define EVENT_TRACE_FLAG_SPLIT_IO           0x00200000  // split io traces (VolumeManager)

#define EVENT_TRACE_FLAG_DRIVER             0x00800000  // driver delays
#define EVENT_TRACE_FLAG_PROFILE            0x01000000  // sample based profiling
#define EVENT_TRACE_FLAG_FILE_IO            0x02000000  // file IO
#define EVENT_TRACE_FLAG_FILE_IO_INIT       0x04000000  // file IO initiation

//
// Enable flags for Kernel Events on Win7 and above
//
#define EVENT_TRACE_FLAG_DISPATCHER         0x00000800  // scheduler (ReadyThread)
#define EVENT_TRACE_FLAG_VIRTUAL_ALLOC      0x00004000  // VM operations

//
// Enable flags for Kernel Events on Win8 and above
//
#define EVENT_TRACE_FLAG_VAMAP              0x00008000  // map/unmap (excluding images)
#define EVENT_TRACE_FLAG_NO_SYSCONFIG       0x10000000  // Do not do sys config rundown

//
// Enable flags for Kernel Events on Threshold and above
//
#define EVENT_TRACE_FLAG_JOB                0x00080000  // job start & end
#define EVENT_TRACE_FLAG_DEBUG_EVENTS       0x00400000  // debugger events (break/continue/...)

예를 들어, 이 중에서 EVENT_TRACE_FLAG_PROCESS 플래그는 프로세스의 생성/종료에 대한 이벤트를 받을 수 있게 합니다. 따라서, 다음과 같이 설정해 주면,

EventTraceProperties prop = new EventTraceProperties(true, sessionName, NativeMethods.SystemTraceControlGuid);
prop.SetFlags(NativeMethods.EVENT_TRACE_FLAG_PROCESS);

result = NativeMethods.StartTrace(out sessionHandle, sessionName, ref prop);

이후 (EXE) 프로세스 생성/종료마다 이벤트 콜백 함수가 실행됩니다.

(첨부 파일은 이 글의 예제 코드를 포함합니다.)




참고로 아래의 문서에도 나오지만,

Controlling Event Tracing Sessions
; https://learn.microsoft.com/en-us/windows/win32/etw/controlling-event-tracing-sessions

ETW 세션을 다루는 방식이 여러 가지이므로 자신이 사용하려는 Provider에 따라 저 문서를 보고 어느 유형에 속하는지 선택해 코딩을 해야 합니다.




이 글에서 EVENT_TRACE_FLAG_PROCESS를 설정한 "Windows Kernel Trace" 동작은 지난 글에서 설명한,

C# - 특정 EXE 프로세스를 종료시킨 EXE를 찾아내는 방법
; https://www.sysnet.pe.kr/2/0/11172

"Microsoft-Windows-Kernel-Audit-API-Calls" ETW provider를 통해서도 유사하게 구현할 수 있습니다. 이에 대해서는 다음번 글에서 살펴보겠습니다.




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]







[최초 등록일: ]
[최종 수정일: 6/28/2023]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 




... 91  92  93  94  95  96  97  98  99  100  [101]  102  103  104  105  ...
NoWriterDateCnt.TitleFile(s)
11407정성태12/18/201724187.NET Framework: 712. C# - SharpDX + DXGI를 이용한 윈도우 화면 캡처 소스 코드 + Direct2D 출력 + OpenCV [1]파일 다운로드1
11406정성태12/17/201746572.NET Framework: 711. C# - OpenCvSharp의 Mat 데이터 조작 방법 [5]파일 다운로드1
11405정성태12/17/201742544.NET Framework: 710. C# - OpenCvSharp을 이용한 Webcam 영상 처리 + Direct2D [1]파일 다운로드1
11404정성태12/16/201729866.NET Framework: 709. C# - OpenCvSharp을 이용한 동영상(avi, mp4, ...) 처리 + Direct2D [7]파일 다운로드1
11403정성태12/16/201732495.NET Framework: 708. C# - OpenCvSharp을 이용한 동영상(avi, mp4, ...) 처리 [3]파일 다운로드1
11402정성태12/15/201737161.NET Framework: 707. OpenCV 응용 프로그램을 C#으로 구현 - OpenCvSharp [2]파일 다운로드1
11401정성태12/15/201726105.NET Framework: 706. C# - SharpDX + DXGI를 이용한 윈도우 화면 캡처 소스 코드 + Direct2D 출력 [2]파일 다운로드1
11400정성태12/14/201728969.NET Framework: 705. C# - SharpDX + DXGI를 이용한 윈도우 화면 캡처 소스 코드 [9]파일 다운로드1
11399정성태12/13/201717558.NET Framework: 704. Win32 API의 UnionRect를 닷넷 BCL의 Rectangle.Union으로 바꿀 때 주의 사항
11398정성태12/13/201717763오류 유형: 442. ASP.NET Core Web Application (on .NET Framework) 프로젝트에서 외부 라이브러리 동적 로드 시 런타임 버전 문제파일 다운로드1
11397정성태12/12/201720341.NET Framework: 703. 양자 컴퓨팅을 위한 마이크로소프트의 Q# 언어
11396정성태12/8/201742700개발 환경 구성: 343. Visual Studio - 리눅스 용 프로젝트의 인텔리센스를 위한 헤더 파일 처리 방법 [3]
11395정성태12/8/201718581오류 유형: 441. 이벤트 로그 - Time Provider NtpClient: No valid response has been received from domain controller
11394정성태12/8/201718206개발 환경 구성: 342. 비주얼 스튜디오에서 실행하던 ASP.NET Core (.NET Framework) 응용 프로그램을 명령행에서 실행하는 방법
11393정성태12/7/201722750Windows: 145. 윈도우 10 빌드 17046부터 WSL에서 백그라운드 작업 지원 [5]
11392정성태12/7/201718030개발 환경 구성: 341. openSUSE에 닷넷 코어 설치
11391정성태12/7/201720878개발 환경 구성: 340. WSL을 이용해 윈도우 PC 1대에서 openSUSE 응용 프로그램을 Visual Studio로 개발하는 방법 [1]
11390정성태12/7/201729525개발 환경 구성: 339. WSL을 이용해 윈도우 PC 1대에서 Linux 응용 프로그램을 Visual Studio로 개발하는 방법 [6]
11389정성태12/7/201718191오류 유형: 440. .NET Core 오류 - 0x80131620 Unable to load DLL 'libuv'
11388정성태12/6/201721842개발 환경 구성: 338. WSL 또는 Ubuntu에 닷넷 코어 설치 [3]
11387정성태12/6/201722170오류 유형: 439. 이벤트 로그 - Data Sharing Service 서비스의 %%3239247874 오류 메시지
11386정성태12/5/201717726오류 유형: 438. Hyper-V - '...' failed to add device 'Virtual CD/DVD Disk'
11385정성태12/5/201730844VC++: 121. DXGI를 이용한 윈도우 화면 캡처 소스 코드(Visual C++) [16]파일 다운로드1
11384정성태12/5/201720143오류 유형: 437. Visual C++ - Cannot open include file: 'SDKDDKVer.h'
11383정성태12/4/201723252디버깅 기술: 110. 비동기 코드 실행 중 예외로 인한 ASP.NET 프로세스 비정상 종료 현상 [1]
11382정성태12/4/201721848오류 유형: 436. System.Data.SqlClient.SqlException (0x80131904): Connection Timeout Expired 예외 발생 시 "[Pre-Login] initialization=48; handshake=1944;" 값의 의미
... 91  92  93  94  95  96  97  98  99  100  [101]  102  103  104  105  ...