예제 #1
0
bool GetEventData(EVENT_RECORD* pEventRecord, wchar_t const* name, T* out, bool bPrintOnError = true)
{
    PROPERTY_DATA_DESCRIPTOR descriptor;
    descriptor.PropertyName = (ULONGLONG) name;
    descriptor.ArrayIndex = ULONG_MAX;

    auto status = TdhGetProperty(pEventRecord, 0, nullptr, 1, &descriptor, sizeof(T), (BYTE*) out);
    if (status != ERROR_SUCCESS) {
        if (bPrintOnError) {
            fprintf(stderr, "error: could not get event %ls property (error=%lu).\n", name, status);
            PrintEventInformation(stderr, pEventRecord);
        }
        return false;
    }

    return true;
}
예제 #2
0
void CALLBACK EventRecordCallback(_In_ EVENT_RECORD* per)
{
	auto data = static_cast<EventTraceData*>(per->UserContext);

	static std::unordered_map<GUID, std::vector<BYTE>, GuidHash> fragment;
	if (false)
	{
		std::wostringstream s;
		WCHAR tmp[39];
		if (per->EventHeader.ProviderId == __uuidof(Microsoft_Windows_Networking_Correlation))
		{
			s << "C";
		}
		else if (per->EventHeader.ProviderId == __uuidof(Microsoft_Windows_NDIS_PacketCapture))
		{
			s << "P";
		}
		else
		{
			StringFromGUID2(per->EventHeader.ProviderId, tmp, ARRAYSIZE(tmp));
			s << tmp;
		}
		StringFromGUID2(per->EventHeader.ActivityId, tmp, ARRAYSIZE(tmp));
		s << ", Activity ID: " << tmp;
		for (int i = 0; i < per->ExtendedDataCount; ++i)
		{
			const auto& e = per->ExtendedData[i];
			if (e.ExtType == EVENT_HEADER_EXT_TYPE_RELATED_ACTIVITYID)
			{
				const auto& r = *(const EVENT_EXTENDED_ITEM_RELATED_ACTIVITYID*)(e.DataPtr);
				StringFromGUID2(r.RelatedActivityId, tmp, ARRAYSIZE(tmp));
				s << ", RelatedActivityId: " << tmp;
			}
			else
			{
				s << ", ExtType: " << e.ExtType;
			}
		}
		if (per->UserDataLength <= 26 || *((BYTE*)per->UserData + 24) != 0x08 || *((BYTE*)per->UserData + 25) != 0x00)
		{
			if (per->EventHeader.ProviderId == __uuidof(Microsoft_Windows_NDIS_PacketCapture))
			{
				s << " !";
			}
		}
		if (per->EventHeader.ProviderId != __uuidof(Microsoft_Windows_Networking_Correlation))
		{
			ULONG bufferSize = 0;
			auto statusSize = TdhGetEventInformation(per, 0, nullptr, nullptr, &bufferSize);
			if (statusSize != ERROR_INSUFFICIENT_BUFFER)
			{
				return;
			}

			auto buffer = std::make_unique<std::uint8_t[]>(bufferSize);
			auto info = reinterpret_cast<TRACE_EVENT_INFO*>(buffer.get());
			auto status = TdhGetEventInformation(per, 0, nullptr, info, &bufferSize);
			if (status != ERROR_SUCCESS)
			{
				return;
			}
			for (ULONG i = 0; i < info->TopLevelPropertyCount; i++)
			{
				const auto& propertyInfo = info->EventPropertyInfoArray[i];
				auto name = reinterpret_cast<PCWSTR>(buffer.get() + propertyInfo.NameOffset);
				if (std::wcscmp(name, L"FragmentSize") != 0)
				{
					continue;
				}
				PROPERTY_DATA_DESCRIPTOR desc{
					reinterpret_cast<uintptr_t>(name),
					ULONG_MAX,
				};
				ULONG propertyBufferSize;
				auto statusPropSize = TdhGetPropertySize(per, 0, nullptr, 1, &desc, &propertyBufferSize);
				if (statusPropSize != ERROR_SUCCESS)
				{
					continue;
				}
				auto propertyBuffer = std::make_unique<std::uint8_t[]>(propertyBufferSize);
				auto statusProp = TdhGetProperty(per, 0, nullptr, 1, &desc, propertyBufferSize, propertyBuffer.get());
				if (statusProp != ERROR_SUCCESS)
				{
					continue;
				}
				if ((propertyInfo.Flags & PropertyStruct) != 0)
				{
					continue;
				}
				if (propertyInfo.nonStructType.InType != TDH_INTYPE_UINT32)
				{
					continue;
				}
				s << L", Fragment size: " << *reinterpret_cast<UINT32*>(propertyBuffer.get());
			}

		}
		s << "\r\n";
		OutputDebugStringW(s.str().c_str());
	}

	if (per->EventHeader.ProviderId != __uuidof(Microsoft_Windows_NDIS_PacketCapture))
	{
		return;
	}

	ULONG bufferSize = 0;
	auto statusSize = TdhGetEventInformation(per, 0, nullptr, nullptr, &bufferSize);
	if (statusSize != ERROR_INSUFFICIENT_BUFFER)
	{
		return;
	}

	auto buffer = std::make_unique<std::uint8_t[]>(bufferSize);
	auto info = reinterpret_cast<TRACE_EVENT_INFO*>(buffer.get());
	auto status = TdhGetEventInformation(per, 0, nullptr, info, &bufferSize);
	if (status != ERROR_SUCCESS)
	{
		return;
	}
	for (ULONG i = 0; i < info->TopLevelPropertyCount; i++)
	{
		const auto& propertyInfo = info->EventPropertyInfoArray[i];
		auto name = reinterpret_cast<PCWSTR>(buffer.get() + propertyInfo.NameOffset);
		if (std::wcscmp(name, L"Fragment") != 0)
		{
			continue;
		}
		PROPERTY_DATA_DESCRIPTOR desc{
			reinterpret_cast<uintptr_t>(name),
			ULONG_MAX,
		};
		ULONG propertyBufferSize;
		auto statusPropSize = TdhGetPropertySize(per, 0, nullptr, 1, &desc, &propertyBufferSize);
		if (statusPropSize != ERROR_SUCCESS)
		{
			continue;
		}
		auto propertyBuffer = std::make_unique<std::uint8_t[]>(propertyBufferSize);
		auto statusProp = TdhGetProperty(per, 0, nullptr, 1, &desc, propertyBufferSize, propertyBuffer.get());
		if (statusProp != ERROR_SUCCESS)
		{
			continue;
		}
		if ((propertyInfo.Flags & PropertyStruct) != 0)
		{
			continue;
		}
		if (propertyInfo.nonStructType.InType != TDH_INTYPE_BINARY)
		{
			continue;
		}

		std::wostringstream s;
		WCHAR tmp[39];
		StringFromGUID2(per->EventHeader.ActivityId, tmp, ARRAYSIZE(tmp));
		s << tmp << ' ' << std::hex << per->EventHeader.Flags;

		auto it = fragment.find(per->EventHeader.ActivityId);
		if (it == fragment.end())
		{
			if ((per->EventHeader.EventDescriptor.Keyword & KeywordPacketEnd) != 0)
			{
				data->Packet.push(std::vector<std::uint8_t>(propertyBuffer.get(), propertyBuffer.get() + propertyBufferSize));
			}
			else
			{
				fragment.emplace(
					per->EventHeader.ActivityId,
					std::vector<std::uint8_t>(propertyBuffer.get(), propertyBuffer.get() + propertyBufferSize));
			}
		}
		else
		{
			it->second.insert(
				it->second.end(),
				propertyBuffer.get(),
				propertyBuffer.get() + propertyBufferSize);
			if ((per->EventHeader.EventDescriptor.Keyword & KeywordPacketEnd) != 0)
			{
				data->Packet.push(std::move(it->second));
				fragment.erase(it);
			}
		}
	}
}