let's continue to dissect ETW (part 1& 2). This time consider how tracing is implemented in the kernel itself. I made PoC to find all tracing handles in arm64 kernel and now give short explanation of what each of them is used for
So knowing offsets of ETW_REG_ENTRY.GuidEntry and ETW_GUID_ENTRY.ProviderEnableInfo fields you can dynamically disable kernel ETW tracing. Very ironic that you can find this offsets with disassembling exported function EtwEventEnabled:
But perhaps there is even more interesting thing - in theory you can just replace ETW_REG_ENTRY.GuidEntry to your own ETW_GUID_ENTRY and so hijaq kernel tracing to your own (and even usermode) logger!
EtwpEventTracingProvRegHandle
GUID B675EC37-BDB6-4648-BC92-F3FDC74D3CA2 (EventTracingProvGuid). Used in lots of internal etw related functions like EtwpTraceStackWalk, EtwpWriteUserEvent, EtwpFailLogging, NtTraceEvent, WmiTraceMessage, EtwWriteEx, EtwWrite etcEtwKernelProvRegHandle
GUID A68CA8B7-004F-D7B6-A698-07E2DE0F1F5D (KernelProvGuid). Used for kernel tracing in functions like SeLogAccessFailure, CmpReorganizeHive, SepSetTokenUserAndGroups, EtwTraceSystemTimeChange, EtwTraceTimeZoneInformationRefresh etcEtwpPsProvRegHandle
GUID 22FB2CD6-0E7B-422B-A0C7-2FAD1FD0E716 (PsProvGuid). Used for tracing processes subsystem activity in functions like PsImpersonateContainerOfThread, PspRevertContainerImpersonation, PspSetJobIoRateControl, PspSetJobIoAttribution, EtwTraceFreezeThawProcess etc
EtwpNetProvRegHandle
GUID 7DD42A49-5329-4832-8DFD-43D979153A88 (NetProvGuid). Used only in function EtwpTraceNetwork which assigning as callback in WmiSetNetworkNotify
EtwpDiskProvRegHandle
GUID C7BDE69A-E1E0-4177-B6EF-283AD1525271 (DiskProvGuid). Used in function EtwpTraceIo which assigning as callback in EtwpDiskIoNotifyRoutinesEtwpFileProvRegHandle
GUID EDD08927-9CC4-4E65-B970-C2560FB5C289 (FileProvGuid). Used in function EtwpTraceFileName which assigning as callback in array EtwpTraceFileName
EtwpRegTraceHandle
GUID 70EB4F03-C1DE-4F73-A051-33D13D5413BD (RegistryProvGuid). Seems that this handle was introduced in build 20170. Used in lots of registry related functions like CmpTraceHiveMountStop, CmpTraceHiveLoadStart, CmpTraceHiveMountBaseFileMounted etc
EtwpMemoryProvRegHandle
GUID D1D93EF7-E1F2-4F45-9943-03D245FE6C00 (MemoryProvGuid). Used in memory related functions like MiAllocatePagesForMdl, MiAllocateContiguousMemory etc
EtwAppCompatProvRegHandle
GUID 16A1ADC1-9B7F-4CD9-94B3-D8296AB1B130 (MS_Windows_Kernel_AppCompat_Provider). Used only in function CmpPublishEventForPcaResolver and perhaps related with AppCompat
EtwApiCallsProvRegHandle
GUID E02A841C-75A3-4FA7-AFC8-AE09CF9B7F23 (KernelAuditApiCallsGuid). Used in some API functions like PsOpenProcess, PsOpenThread, NtCreateSymbolicLinkObject etc. Very interesting trace results
EtwCVEAuditProvRegHandle
GUID 85A62A0D-7E17-485F-9D4F-749A287193A6 (CVEAuditProviderGuid). Used in exported function SeEtwWriteKMCveEvent and perhaps intended for 3rd party drivers. For now imported only by win32kfull.sys
EtwThreatIntProvRegHandle & EtwSecurityMitigationsRegHandle
See detailed description in my post
EtwLpacProvRegHandle
GUID 45EEC9E5-4A1B-5446-7AD8-A4AB1313C437 (MS_Windows_Security_LPAC_Provider). Used in function EtwTraceLpacAccessFailure -> SepLogLpacAccessFailure -> SeAccessCheckWithHintWithAdminlessChecks
EtwAdminlessProvRegHandle
GUID EA216962-877B-5B73-F7C5-8AEF5375959E (MS_Windows_Security_Adminless_Provider). Used in function EtwTraceAdminlessAccessFailure ->NtQueryInformationToken
What are all this handles?
They are just pointers to ETW_REG_ENTRY. In turn, this structure has a pointer to ETW_GUID_ENTRY and here the story becomes much more interesting. ETW_GUID_ENTRY has field TRACE_ENABLE_INFO:
struct _TRACE_ENABLE_INFO {
// static data ------------------------------------
// non-static data --------------------------------
/**/ /*|0x4|*/ unsigned long IsEnabled;
/**/ /*|0x1|*/ unsigned char Level;
/**/ /*|0x1|*/ unsigned char Reserved1;
/**/ /*|0x2|*/ unsigned short LoggerId;
/**/ /*|0x4|*/ unsigned long EnableProperty;
/**/ /*|0x4|*/ unsigned long Reserved2;
/**/ /*|0x8|*/ unsigned __int64 MatchAnyKeyword;
/**/ /*|0x8|*/ unsigned __int64 MatchAllKeyword;
So knowing offsets of ETW_REG_ENTRY.GuidEntry and ETW_GUID_ENTRY.ProviderEnableInfo fields you can dynamically disable kernel ETW tracing. Very ironic that you can find this offsets with disassembling exported function EtwEventEnabled:
EtwEventEnabled proc near
sub rsp, 28h
mov r8, rcx
test rcx, rcx
jz short loc_140076F70
mov rax, [rcx+20h] ; ETW_REG_ENTRY.GuidEntry
mov r9, [rdx+8]
add rax, 50h ; ETW_GUID_ENTRY.ProviderEnableInfo
cmp dword ptr [rax], 0
But perhaps there is even more interesting thing - in theory you can just replace ETW_REG_ENTRY.GuidEntry to your own ETW_GUID_ENTRY and so hijaq kernel tracing to your own (and even usermode) logger!