43 PROVIDER_ENUMERATION_INFO* providerInfo =
nullptr;
44 std::optional<GUID>
result;
47 ULONG status = TdhEnumerateProviders(
nullptr, &
bufferSize);
48 if (status == ERROR_INSUFFICIENT_BUFFER) {
49 providerInfo = (PROVIDER_ENUMERATION_INFO*)malloc(
bufferSize);
50 if (providerInfo ==
nullptr) {
51 throw std::runtime_error(
"Failed to allocate memory");
55 status = TdhEnumerateProviders(providerInfo, &
bufferSize);
56 if (status == ERROR_SUCCESS) {
57 for (ULONG i = 0; i < providerInfo->NumberOfProviders; i++) {
58 TRACE_PROVIDER_INFO& provider = providerInfo->TraceProviderInfoArray[i];
59 wchar_t* providerName = (
wchar_t*)((
BYTE*)providerInfo + provider.ProviderNameOffset);
61 std::wstring wProviderName(providerName);
62 std::string providerNameStr(wProviderName.begin(), wProviderName.end());
64 if (providerNameStr == providerNameToFind) {
65 result = provider.ProviderGuid;
71 throw std::runtime_error(
"TdhEnumerateProviders failed with error: " + std::to_string(status));
77 throw std::runtime_error(
"TdhEnumerateProviders failed with error: " + std::to_string(status));
108 nlohmann::json jsonObject;
109 if (info->KeywordsNameOffset)
110 printf(
"Keywords: %ws ", (PCWSTR)((
BYTE*)info + info->KeywordsNameOffset));
111 if (info->OpcodeNameOffset)
112 printf(
"Opcode: %ws ", (PCWSTR)((
BYTE*)info + info->OpcodeNameOffset));
113 if (info->LevelNameOffset)
114 printf(
"Level: %ws ", (PCWSTR)((
BYTE*)info + info->LevelNameOffset));
115 if (info->TaskNameOffset) {
116 printf(
"Task: %ws ", (PCWSTR)((
BYTE*)info + info->TaskNameOffset));
117 std::wstring taskName = (PCWSTR)((
BYTE*)info + info->TaskNameOffset);
118 jsonObject[
"Event"] =
ToString(taskName);
120 if (info->EventMessageOffset)
121 printf(
"\nMessage: %ws", (PCWSTR)((
BYTE*)info + info->EventMessageOffset));
123 printf(
"\nProperties: %u\n", info->TopLevelPropertyCount);
126 auto userlen = rec->UserDataLength;
127 auto data = (PBYTE)rec->UserData;
129 auto pointerSize = (rec->EventHeader.Flags & EVENT_HEADER_FLAG_32_BIT_HEADER) ? 4 : 8;
133 for (
DWORD i = 0; i < info->TopLevelPropertyCount; i++) {
134 auto& pi = info->EventPropertyInfoArray[i];
135 auto propName = (PCWSTR)((
BYTE*)info + pi.NameOffset);
136 printf(
" Name: %ws ", propName);
137 std::string propNameStr =
ToString(propName);
140 if ((pi.Flags & (PropertyStruct | PropertyParamCount)) == 0) {
144 PEVENT_MAP_INFO mapInfo =
nullptr;
145 std::unique_ptr<BYTE[]> mapBuffer;
146 PWSTR mapName =
nullptr;
150 if (pi.nonStructType.MapNameOffset) {
152 mapName = (PWSTR)((
BYTE*)info + pi.nonStructType.MapNameOffset);
153 if (ERROR_INSUFFICIENT_BUFFER == ::TdhGetEventMapInformation(rec, mapName, mapInfo, &size)) {
154 mapBuffer = std::make_unique<BYTE[]>(size);
155 mapInfo =
reinterpret_cast<PEVENT_MAP_INFO
>(mapBuffer.get());
156 if (ERROR_SUCCESS != ::TdhGetEventMapInformation(rec, mapName, mapInfo, &size))
161 ULONG size =
sizeof(value);
164 if (pi.nonStructType.InType == TDH_INTYPE_BINARY && pi.nonStructType.OutType == TDH_OUTTYPE_IPV6)
165 len =
sizeof(IN6_ADDR);
167 auto error = ::TdhFormatProperty(info, mapInfo, pointerSize,
168 pi.nonStructType.InType, pi.nonStructType.OutType,
169 (USHORT)len, userlen, data, &size, value, &consumed);
170 if (ERROR_SUCCESS == error) {
171 printf(
"Value: %ws", value);
172 jsonObject[propNameStr] =
ToString(value);
175 printf(
" (%ws)", (PCWSTR)mapName);
179 error = ::TdhFormatProperty(info,
nullptr, pointerSize,
180 pi.nonStructType.InType, pi.nonStructType.OutType,
181 (USHORT)len, userlen, data, &size, value, &consumed);
182 if (ERROR_SUCCESS == error) {
183 printf(
"Value: %ws\n", value);
184 jsonObject[propNameStr] =
ToString(value);
187 if (ERROR_SUCCESS != error)
188 printf(
"(failed to get value)\n");
191 printf(
"(not a simple property)\n");
193 userlen -= (USHORT)len;
196 auto& header = rec->EventHeader;
197 jsonObject[
"TID"] = header.ThreadId;
198 jsonObject[
"PID"] = header.ProcessId;
199 if (header.ProcessId == GetCurrentProcessId()) {
203 jsonObject[
"Time"] = timeLog;
206 std::string eventName = jsonObject[
"Event"].get<std::string>();
207 if (!eventName.empty()) {
208 if (eventName ==
"FileCreated" || eventName ==
"FileModified") {
209 std::string fileName = jsonObject[
"FileName"].get<std::string>();
212 else if (eventName ==
"KERNEL_NETWORK_TASK_TCPIP" || eventName ==
"KERNEL_NETWORK_TASK_UDPIP"){
213 auto destAddr = jsonObject[
"daddr"].get<std::string>();
214 auto srcAddr = jsonObject[
"saddr"].get<std::string>();
215 if (srcAddr ==
"127.0.0.1" || destAddr ==
"127.0.0.1") {
218 if (srcAddr ==
"::1" || destAddr ==
"::1") {
247 auto status = ::TdhGetEventInformation(pEventRecord, 0,
nullptr,
nullptr, &size);
248 assert(status == ERROR_INSUFFICIENT_BUFFER);
250 auto buffer = std::make_unique<BYTE[]>(size);
252 printf(
"Out of memory!\n");
256 auto info =
reinterpret_cast<PTRACE_EVENT_INFO
>(buffer.get());
257 status = ::TdhGetEventInformation(pEventRecord, 0,
nullptr, info, &size);
258 if (status != ERROR_SUCCESS) {
259 printf(
"Error processing event!\n");
273 EVENT_TRACE_PROPERTIES* pProperties = NULL;
275 ULONG status = ERROR_SUCCESS;
278 bufferSize =
sizeof(EVENT_TRACE_PROPERTIES) + (wcslen(sessionName.c_str()) + 1) *
sizeof(WCHAR);
279 pProperties = (EVENT_TRACE_PROPERTIES*)malloc(
bufferSize);
280 if (pProperties == NULL)
282 return ERROR_OUTOFMEMORY;
287 pProperties->Wnode.Flags = WNODE_FLAG_TRACED_GUID;
288 pProperties->LoggerNameOffset =
sizeof(EVENT_TRACE_PROPERTIES);
291 status = ControlTraceW(NULL, sessionName.c_str(), pProperties, EVENT_TRACE_CONTROL_STOP);
312 EVENT_TRACE_PROPERTIES* pProperties = (EVENT_TRACE_PROPERTIES*)malloc(
bufferSize);
316 pProperties->Wnode.Flags = WNODE_FLAG_TRACED_GUID;
317 pProperties->Wnode.ClientContext = 1;
318 pProperties->LogFileMode = EVENT_TRACE_REAL_TIME_MODE;
319 pProperties->LoggerNameOffset =
sizeof(EVENT_TRACE_PROPERTIES);
320 pProperties->LogFileNameOffset = 0;
324 WCHAR sessionName[] = L
"Panoptes";
325 ULONG
result = StartTraceW(&
hTrace, sessionName, pProperties);
326 if (
result != ERROR_SUCCESS)
334 for (
const auto& provider : providers)
336 auto [provName, provMatchAny, provMatchAll] = provider;
339 if (provGUID == GUID{}) {
340 printf(
"[!] Could not retrieve GUID for %s\n", provName);
347 EVENT_CONTROL_CODE_ENABLE_PROVIDER,
348 TRACE_LEVEL_INFORMATION,
354 if (
result != ERROR_SUCCESS)
357 printf(
"[!] Could not enable trace for %s\n", provName);
363 EVENT_TRACE_LOGFILEW
trace;
364 ZeroMemory(&
trace,
sizeof(EVENT_TRACE_LOGFILE));
365 trace.LoggerName = (LPWSTR)sessionName;
366 trace.ProcessTraceMode = PROCESS_TRACE_MODE_REAL_TIME | PROCESS_TRACE_MODE_EVENT_RECORD;
370 TRACEHANDLE hProcessTrace = OpenTraceW(&
trace);
371 if (hProcessTrace == INVALID_PROCESSTRACE_HANDLE)
374 ControlTraceW(
hTrace, NULL, pProperties, EVENT_TRACE_CONTROL_STOP);
379 ProcessTrace(&hProcessTrace, 1, NULL, NULL);
382 CloseTrace(hProcessTrace);
383 ControlTraceW(
hTrace, NULL, pProperties, EVENT_TRACE_CONTROL_STOP);