microsoft / krabsetw

KrabsETW provides a modern C++ wrapper and a .NET wrapper around the low-level ETW trace consumption functions.
Other
610 stars 149 forks source link

Use krabsetw to detect .Net memory loading #202

Open findream opened 2 years ago

findream commented 2 years ago

hello, I want to use ETW to detect .Net memory loading, I found the code online. You can see that this is using the ".Net Command Language Runtime" provider to filter out the AssemblyDCStart event. ID is 155. to detect .Net memory loading, but the event generation is not detected until the loader exits, so I decided to use krabsetw.

define AssemblyDCStart_V1 155

static GUID ClrRuntimeProviderGuid = {0xe13c0d23, 0xccbc, 0x4e12, {0x93, 0x1b, 0xd9, 0xcc, 0x2e, 0xee, 0x27, 0xe4}}; int main(void) { TRACEHANDLE hTrace = 0; ULONG result, bufferSize; EVENT_TRACE_LOGFILEA trace; EVENT_TRACE_PROPERTIES traceProp; printf("ETW .NET Trace example\n\n"); memset(&trace, 0, sizeof(EVENT_TRACE_LOGFILEA)); trace.ProcessTraceMode = PROCESS_TRACE_MODE_REAL_TIME | PROCESS_TRACE_MODE_EVENT_RECORD; trace.LoggerName = (LPSTR)name; trace.EventRecordCallback = (PEVENT_RECORD_CALLBACK)ProcessEvent; bufferSize = sizeof(EVENT_TRACE_PROPERTIES) + sizeof(name) + sizeof(WCHAR); traceProp = (EVENT_TRACE_PROPERTIES)LocalAlloc(LPTR, bufferSize); traceProp->Wnode.BufferSize = bufferSize; traceProp->Wnode.ClientContext = 2; traceProp->Wnode.Flags = WNODE_FLAG_TRACED_GUID; traceProp->LogFileMode = EVENT_TRACE_REAL_TIME_MODE | EVENT_TRACE_USE_PAGED_MEMORY; traceProp->LogFileNameOffset = 0; traceProp->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES); result = StartTraceA(&hTrace, (LPCSTR)name, traceProp) result = EnableTraceEx( &ClrRuntimeProviderGuid, NULL, hTrace, 1, TRACE_LEVEL_VERBOSE, 0x8, // LoaderKeyword 0, 0, NULL ) hTrace = OpenTrace(&trace); result = ProcessTrace(&hTrace, 1, NULL, NULL); return 0; }



Then I use krabsetw, the code is as follows, you can see that the ".NET Common Language Runtime" provider is used, and the AssemblyDCStart event is filtered. The Loader is run, but the AssemblyDCStart event is not detected.

void start_etw_trace()
{
    auto assembly_callback = [](const EVENT_RECORD& record, const krabs::trace_context& trace_context)
    {
        krabs::schema schema(record, trace_context.schema_locator);
        krabs::parser parser(schema);
        std::wcout << L" ProcessId=" << record.EventHeader.ProcessId;
        std::wcout << std::endl;
    };

    krabs::user_trace trace(L"user_trace_007");
    krabs::provider<> dotnet_rundown_provider(L".NET Common Language Runtime");

    dotnet_rundown_provider.any(LoaderKeyword);
    krabs::event_filter assembly_rundown_filter(krabs::predicates::id_is(AssemblyDCStart));  
    assembly_rundown_filter.add_on_event_callback(assembly_callback);
    dotnet_rundown_provider.add_filter(assembly_rundown_filter);
    //dotnet_rundown_provider.add_on_event_callback(assembly_callback);
    trace.enable(dotnet_rundown_provider);
    trace.start();
}
![image](https://user-images.githubusercontent.com/24735680/195992136-ed0bcc08-9629-4f43-a1e3-35109cfd66fb.png)

anybody can help?