summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorQuentin LADEVIE <qladevie@wanadev.fr>2025-06-02 09:41:10 +0200
committerQuentin LADEVIE <qladevie@wanadev.fr>2025-06-02 09:41:10 +0200
commitab46e6bb57132bb84e05ad682a028a9cf1f60d40 (patch)
treef515faec1d53ec14d14f6bc9e02c00e23cefdff8 /src
parentdf9dfbdc46a5f60811efea05a86c3518e97527fc (diff)
Enable so system providers
Diffstat (limited to 'src')
-rw-r--r--src/main.c282
1 files changed, 222 insertions, 60 deletions
diff --git a/src/main.c b/src/main.c
index 1e8a507..350fbea 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,39 +1,61 @@
#include <stdint.h>
-#include <stddef.h>
#include <string.h>
#include <stdio.h>
+#include <math.h>
#include <Windows.h>
#include <evntrace.h>
#include <evntprov.h>
-#include <TraceLoggingProvider.h>
-
-#include <strsafe.h>
// #define REAL_TIME_MODE
struct EventTracePropertyData {
- EVENT_TRACE_PROPERTIES props;
+ EVENT_TRACE_PROPERTIES_V2 props;
#if !defined(REAL_TIME_MODE)
char log_file_name[128];
#endif
char logger_name[1024];
char buffer[64 * 1024U];
+} data = {
+ .props = {
+ .Wnode = {
+ .BufferSize = offsetof(struct EventTracePropertyData, buffer),
+ .Flags = WNODE_FLAG_TRACED_GUID | WNODE_FLAG_VERSIONED_PROPERTIES,
+ .Guid = { 0x9E814AAD, 0x3204, 0x11D2, 0x9A, 0x82, 0x00, 0x60, 0x08, 0xA8, 0x69, 0x39 },
+ },
+ .BufferSize = sizeof(data.buffer),
+ .MinimumBuffers = 4U,
+ .MaximumBuffers = 4U,
+ .EnableFlags = // EVENT_TRACE_FLAG_PROFILE |
+ EVENT_TRACE_FLAG_INTERRUPT |
+ EVENT_TRACE_FLAG_SYSTEMCALL |
+ EVENT_TRACE_FLAG_DPC |
+ EVENT_TRACE_FLAG_THREAD |
+ EVENT_TRACE_FLAG_CSWITCH |
+ EVENT_TRACE_FLAG_DISPATCHER |
+ EVENT_TRACE_FLAG_PROCESS |
+ EVENT_TRACE_FLAG_PROCESS_COUNTERS,
+ .LogFileMode = EVENT_TRACE_SYSTEM_LOGGER_MODE,
+#if defined(REAL_TIME_MODE)
+ .LogFileMode = EVENT_TRACE_REAL_TIME_MODE,
+#else
+ .LogFileNameOffset = offsetof(struct EventTracePropertyData, log_file_name),
+#endif
+ .LoggerNameOffset = offsetof(struct EventTracePropertyData, logger_name),
+ },
+ .log_file_name = "test_etw_log.etl",
+ .logger_name = KERNEL_LOGGER_NAMEA,
};
-// TRACELOGGING_DEFINE_PROVIDER(
-// provider_handle,
-// "test_etw_provider",
-// ( 0x9c898339, 0x0c32, 0x5d5d, 0xa6, 0x87, 0x43, 0x19, 0x59, 0xce, 0xf0, 0x8d )
-// );
+GUID system_profile_provider_guid = { 0xbfeb0324, 0x1cee, 0x496f, 0xa4, 0x09, 0x2a, 0xc2, 0xb4, 0x8a, 0x63, 0x22 };
+GUID thread_provider_guid = { 0x3d6fa8d1, 0xfe05, 0x11d0, 0x9d, 0xda, 0x00, 0xc0, 0x4f, 0xd7, 0xba, 0x7c };
+GUID process_provider_guid = { 0x3d6fa8d0, 0xfe05, 0x11d0, 0x9d, 0xda, 0x00, 0xc0, 0x4f, 0xd7, 0xba, 0x7c };
+GUID perf_info_provider_guid = { 0xce1dbfb4, 0x137e, 0x4da6, 0x87, 0xb0, 0x3f, 0x59, 0xaa, 0x10, 0x2c, 0xbc };
-void ErrorExit()
+void LogError(DWORD dw)
{
// Retrieve the system error message for the last-error code
-
LPVOID lpMsgBuf;
- LPVOID lpDisplayBuf;
- DWORD dw = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
@@ -46,59 +68,185 @@ void ErrorExit()
0, NULL );
// Display the error message and exit the process
- printf("%s\n", (char*)lpMsgBuf);
-
- lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
- (lstrlen((LPCTSTR)lpMsgBuf) + 40) * sizeof(TCHAR));
- StringCchPrintf((LPTSTR)lpDisplayBuf,
- LocalSize(lpDisplayBuf) / sizeof(TCHAR),
- TEXT("failed with error %d: %s"),
- dw, lpMsgBuf);
- MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);
+ printf("error %lu: %s\n", dw, (char*)lpMsgBuf);
LocalFree(lpMsgBuf);
- LocalFree(lpDisplayBuf);
- ExitProcess(dw);
}
int main() {
- // TraceLoggingRegister(provider_handle);
-
LPSTR log_file_name = "test_etw_log.etl";
- LPSTR logger_name = "test_etw_logger";
- LPCSTR trace_name = "test_trace";
- struct EventTracePropertyData data = { 0U };
- // data.props.Wnode.BufferSize = sizeof(data);
- data.props.Wnode.BufferSize = offsetof(struct EventTracePropertyData, buffer);
- data.props.Wnode.Flags = WNODE_FLAG_TRACED_GUID;
- data.props.BufferSize = sizeof(data.buffer);
- data.props.MinimumBuffers = 4U;
- data.props.MaximumBuffers = 4U;
- data.props.EnableFlags = EVENT_TRACE_FLAG_PROFILE;
-#if defined(REAL_TIME_MODE)
- data.props.LogFileMode = EVENT_TRACE_REAL_TIME_MODE;
-#else
- data.props.LogFileNameOffset = offsetof(struct EventTracePropertyData, log_file_name);
-#endif
- data.props.LoggerNameOffset = offsetof(struct EventTracePropertyData, logger_name);
-
- strncpy(data.log_file_name, log_file_name, strlen(log_file_name));
- // strncpy(data.logger_name, logger_name, strlen(logger_name));
-
TRACEHANDLE trace_handle = 0U;
- // EVENT_TRACE_PROPERTIES trace_props = { 0U };
- if (StartTrace(&trace_handle, trace_name, &data.props) != ERROR_SUCCESS) {
- ErrorExit();
- return 1;
+ ULONG res = 0U;
+ if ((res = StartTraceA(&trace_handle, KERNEL_LOGGER_NAMEA, (EVENT_TRACE_PROPERTIES*)&data.props)) != ERROR_SUCCESS) {
+ LogError(res);
+ goto close_trace;
}
- HRESULT hr = 0;
char* profile_source_infos[sizeof(PROFILE_SOURCE_INFO) * 256U];
ULONG bwrite = 0U;
- hr = TraceQueryInformation(0U, TraceProfileSourceListInfo, (void*)profile_source_infos, sizeof(profile_source_infos), &bwrite);
+ if ((res = TraceQueryInformation(0U, TraceProfileSourceListInfo, (void*)profile_source_infos, sizeof(profile_source_infos), &bwrite)) != ERROR_SUCCESS) {
+ LogError(res);
+ goto close_trace;
+ }
- // TraceSetInformation(trace_handle, TracePmcCounterListInfo, ) // PMCs to collect
- // TraceSetInformation(trace_handle, TracePmcEventListInfo) // Events on which we collect PMCs
+ ULONG masks[8U] = {
+ // EVENT_TRACE_FLAG_PROFILE |
+ EVENT_TRACE_FLAG_INTERRUPT |
+ EVENT_TRACE_FLAG_SYSTEMCALL |
+ EVENT_TRACE_FLAG_DPC |
+ EVENT_TRACE_FLAG_THREAD |
+ EVENT_TRACE_FLAG_CSWITCH |
+ EVENT_TRACE_FLAG_DISPATCHER |
+ EVENT_TRACE_FLAG_PROCESS |
+ EVENT_TRACE_FLAG_PROCESS_COUNTERS,
+ 0x20000400, // PERF_PERF_PMC
+ 0U,
+ 0U,
+ 0U,
+ 0U,
+ 0U,
+ 0U,
+ };
+ if ((res = TraceSetInformation(trace_handle, TraceSystemTraceEnableFlagsInfo, &masks, sizeof(masks))) != ERROR_SUCCESS) {
+ LogError(res);
+ goto close_trace;
+ }
+
+ uint32_t pmc_sources[] = { 6U, 19U, }; // instructions count, branch count
+ if ((res = TraceSetInformation(trace_handle, TracePmcCounterListInfo, pmc_sources, sizeof(pmc_sources))) != ERROR_SUCCESS) { // PMCs to collect
+ LogError(res);
+ goto close_trace;
+ }
+
+ CLASSIC_EVENT_ID events[] = {
+ {
+ .EventGuid = perf_info_provider_guid,
+ .Type = 46U,
+ .Reserved = { 0U },
+ },
+ {
+ .EventGuid = perf_info_provider_guid,
+ .Type = 51U,
+ .Reserved = { 0U },
+ },
+ {
+ .EventGuid = perf_info_provider_guid,
+ .Type = 52U,
+ .Reserved = { 0U },
+ },
+ {
+ .EventGuid = perf_info_provider_guid,
+ .Type = 66U,
+ .Reserved = { 0U },
+ },
+ {
+ .EventGuid = perf_info_provider_guid,
+ .Type = 67U,
+ .Reserved = { 0U },
+ },
+ {
+ .EventGuid = perf_info_provider_guid,
+ .Type = 68U,
+ .Reserved = { 0U },
+ },
+ {
+ .EventGuid = perf_info_provider_guid,
+ .Type = 69U,
+ .Reserved = { 0U },
+ },
+ {
+ .EventGuid = thread_provider_guid,
+ .Type = 1U,
+ .Reserved = { 0U },
+ },
+ {
+ .EventGuid = thread_provider_guid,
+ .Type = 2U,
+ .Reserved = { 0U },
+ },
+ {
+ .EventGuid = thread_provider_guid,
+ .Type = 3U,
+ .Reserved = { 0U },
+ },
+ {
+ .EventGuid = thread_provider_guid,
+ .Type = 4U,
+ .Reserved = { 0U },
+ },
+ {
+ .EventGuid = thread_provider_guid,
+ .Type = 36U,
+ .Reserved = { 0U },
+ },
+ {
+ .EventGuid = thread_provider_guid,
+ .Type = 50U,
+ .Reserved = { 0U },
+ },
+ {
+ .EventGuid = process_provider_guid,
+ .Type = 1U,
+ .Reserved = { 0U },
+ },
+ {
+ .EventGuid = process_provider_guid,
+ .Type = 2U,
+ .Reserved = { 0U },
+ },
+ {
+ .EventGuid = process_provider_guid,
+ .Type = 3U,
+ .Reserved = { 0U },
+ },
+ {
+ .EventGuid = process_provider_guid,
+ .Type = 4U,
+ .Reserved = { 0U },
+ },
+ {
+ .EventGuid = process_provider_guid,
+ .Type = 32U,
+ .Reserved = { 0U },
+ },
+ {
+ .EventGuid = process_provider_guid,
+ .Type = 33U,
+ .Reserved = { 0U },
+ },
+ {
+ .EventGuid = process_provider_guid,
+ .Type = 39U,
+ .Reserved = { 0U },
+ },
+ };
+ uint32_t index = 0U;
+ if ((res = TraceSetInformation(trace_handle, TracePmcEventListInfo, &events[index], sizeof(events))) != ERROR_SUCCESS) { // Events on which we collect PMCs
+ LogError(res);
+ goto close_trace;
+ }
+ // Looks like we aren't allowed to use system providers without some special previlegies, to be investigated
+ // EnableTraceEx2(trace_handle, &system_profile_provider_guid, EVENT_CONTROL_CODE_ENABLE_PROVIDER, TRACE_LEVEL_VERBOSE, ~0U, 0U, 0U, NULL);
+ if ((res = EnableTraceEx2(trace_handle, &perf_info_provider_guid, EVENT_CONTROL_CODE_ENABLE_PROVIDER, TRACE_LEVEL_VERBOSE, ~0U, 0U, 0U, NULL)) != ERROR_SUCCESS) {
+ LogError(res);
+ goto close_trace;
+ }
+ if ((res = EnableTraceEx2(trace_handle, &process_provider_guid, EVENT_CONTROL_CODE_ENABLE_PROVIDER, TRACE_LEVEL_VERBOSE, ~0U, 0U, 0U, NULL)) != ERROR_SUCCESS) {
+ LogError(res);
+ goto close_trace;
+ }
+ if ((res = EnableTraceEx2(trace_handle, &thread_provider_guid, EVENT_CONTROL_CODE_ENABLE_PROVIDER, TRACE_LEVEL_VERBOSE, ~0U, 0U, 0U, NULL)) != ERROR_SUCCESS) {
+ LogError(res);
+ goto close_trace;
+ }
+
+ int i = 0;
+ float f = 0.5f;
+ while (i < 4) {
+ Sleep(1000U);
+ f = sinf(f);
+ i++;
+ }
// EVENT_TRACE_LOGFILEA log = { 0U };
@@ -109,8 +257,6 @@ int main() {
// ErrorExit();
// return 1;
// }
-
- // EnableTraceEx2(trace_handle, provider)
// uint32_t counter = 0U;
// while (counter < ~0U) {
@@ -118,8 +264,20 @@ int main() {
// }
- ControlTrace(trace_handle, trace_name, &data.props, EVENT_TRACE_CONTROL_STOP);
- // StopTrace(trace_handle, "TestInstance", &trace_props);
+ if ((res = EnableTraceEx2(trace_handle, &thread_provider_guid, EVENT_CONTROL_CODE_DISABLE_PROVIDER, TRACE_LEVEL_VERBOSE, ~0U, 0U, 0U, NULL)) != ERROR_SUCCESS) {
+ LogError(res);
+ goto close_trace;
+ }
+ if ((res = EnableTraceEx2(trace_handle, &process_provider_guid, EVENT_CONTROL_CODE_DISABLE_PROVIDER, TRACE_LEVEL_VERBOSE, ~0U, 0U, 0U, NULL)) != ERROR_SUCCESS) {
+ LogError(res);
+ goto close_trace;
+ }
+ if ((res = EnableTraceEx2(trace_handle, &perf_info_provider_guid, EVENT_CONTROL_CODE_DISABLE_PROVIDER, TRACE_LEVEL_VERBOSE, ~0U, 0U, 0U, NULL)) != ERROR_SUCCESS) {
+ LogError(res);
+ goto close_trace;
+ goto close_trace;
+ }
+
PROFILE_SOURCE_INFO* cur_profile_source_info = (PROFILE_SOURCE_INFO*)&profile_source_infos[0U];
while (1) {
@@ -132,7 +290,11 @@ int main() {
cur_profile_source_info = (PROFILE_SOURCE_INFO*)((char*)cur_profile_source_info + cur_profile_source_info->NextEntryOffset);
}
- // TraceLoggingUnregister(provider_handle);
+close_trace:
+ if ((res = ControlTraceA(trace_handle, KERNEL_LOGGER_NAMEA, (EVENT_TRACE_PROPERTIES*)&data.props, EVENT_TRACE_CONTROL_STOP)) != ERROR_SUCCESS) {
+ LogError(res);
+ return 1;
+ }
return 0;
}