当前位置: 首页 > backend >正文

获取发起DNS请求的真实进程及请求域名,不是取服务进程svchost.exe,做网络过滤或网络加速用得上。

做网络过滤或者加速类项目时,有时候要取发起dns的真实进程。但是windows的dns都是通过dnscache服务进程,也就是svchost.exe发出的,所以普通方法取到的进程都是svchost.exe。其实还有很多方法,如修改服务状态,hook dns查询api,拦截rpc请求,修改句柄及nsp等。不过这个最简单稳定。

const wchar_t* sessionName = L"MyDNSSession1";
static const GUID DNSClientProviderGuid = { 0x1C95126E, 0x7EEA, 0x49A9, { 0xA3, 0xFE, 0xA3, 0x78, 0xB0, 0x3D, 0xDB, 0x4D } };  // DNS Client Provider GUIDstd::string GetProcessName(DWORD ProcessId)
{std::string ProcessName;HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);if (hProcessSnap != INVALID_HANDLE_VALUE){PROCESSENTRY32 pe32 = { sizeof(pe32) };BOOL bFind = Process32First(hProcessSnap, &pe32);while (bFind){if (pe32.th32ProcessID == ProcessId){ProcessName = pe32.szExeFile;break;}bFind = Process32Next(hProcessSnap, &pe32);}}::CloseHandle(hProcessSnap);return ProcessName;
}void EnableDNSClientProvider(TRACEHANDLE sessionHandle) {ULONG enableStatus = EnableTraceEx(&DNSClientProviderGuid,nullptr,sessionHandle,EVENT_CONTROL_CODE_ENABLE_PROVIDER,TRACE_LEVEL_INFORMATION,0, 0, 0, nullptr);if (enableStatus != ERROR_SUCCESS) {std::cerr << "Failed to enable DNS client provider. Error: " << enableStatus << std::endl;}
}bool GetPropertyValue(PEVENT_RECORD evt, LPCWSTR propName, std::unique_ptr<BYTE[]>& data) {PROPERTY_DATA_DESCRIPTOR dataDesc = {};dataDesc.PropertyName = reinterpret_cast<ULONGLONG>(propName);dataDesc.ArrayIndex = 0;ULONG propertySize = 0;ULONG status = TdhGetPropertySize(evt, 0, nullptr, 1, &dataDesc, &propertySize);if (status != ERROR_SUCCESS) return false;data = std::make_unique<BYTE[]>(propertySize);status = TdhGetProperty(evt, 0, nullptr, 1, &dataDesc, propertySize, data.get());return status == ERROR_SUCCESS;
}void WINAPI ProcessEvent(PEVENT_RECORD pEvent) {if (pEvent->EventHeader.ProviderId == DNSClientProviderGuid) {std::wstring domain;std::unique_ptr<BYTE[]> value;if (GetPropertyValue(pEvent, L"QueryName", value)) {domain.assign(reinterpret_cast<wchar_t*>(value.get()));}DWORD processId = pEvent->EventHeader.ProcessId;std::wcout << L"DNS Query Event: ProcessName: " << GetProcessName(processId).c_str() << " ProcessId: " << processId << L"  Domain: " << domain << std::endl;}
}void StopExistingSession(const wchar_t* sessionName) {EVENT_TRACE_PROPERTIES traceProps = {};traceProps.Wnode.BufferSize = sizeof(EVENT_TRACE_PROPERTIES) + sizeof(WCHAR) * 100;traceProps.LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);ULONG status = ControlTraceW(0, sessionName, &traceProps, EVENT_TRACE_CONTROL_STOP);if (status != ERROR_SUCCESS && status != ERROR_WMI_INSTANCE_NOT_FOUND) {std::cerr << "Failed to stop existing ETW session. Error: " << status << std::endl;}
}void StartETWSession(LPCWSTR sessionName) {StopExistingSession(sessionName);auto traceProps = std::make_unique<BYTE[]>(sizeof(EVENT_TRACE_PROPERTIES) + sizeof(WCHAR) * 100);auto traceProperties = reinterpret_cast<EVENT_TRACE_PROPERTIES*>(traceProps.get());ZeroMemory(traceProperties, sizeof(EVENT_TRACE_PROPERTIES) + sizeof(WCHAR) * 100);traceProperties->Wnode.BufferSize = sizeof(EVENT_TRACE_PROPERTIES) + sizeof(WCHAR) * 100;traceProperties->Wnode.Flags = WNODE_FLAG_TRACED_GUID;traceProperties->Wnode.ClientContext = 1; // QPC clock resolutiontraceProperties->Wnode.Guid = DNSClientProviderGuid;traceProperties->LogFileMode = EVENT_TRACE_REAL_TIME_MODE;traceProperties->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);wcscpy_s(reinterpret_cast<LPWSTR>(traceProps.get() + traceProperties->LoggerNameOffset), 100, sessionName);TRACEHANDLE sessionHandle = 0;ULONG status = StartTraceW(&sessionHandle, sessionName, traceProperties);if (status != ERROR_SUCCESS) {std::cerr << "Failed to start ETW session. Error: " << status << std::endl;return;}EnableDNSClientProvider(sessionHandle);EVENT_TRACE_LOGFILEW logFile = {};logFile.LoggerName = const_cast<LPWSTR>(sessionName);logFile.ProcessTraceMode = PROCESS_TRACE_MODE_REAL_TIME | PROCESS_TRACE_MODE_EVENT_RECORD;logFile.EventRecordCallback = ProcessEvent;TRACEHANDLE traceHandle = OpenTraceW(&logFile);if (traceHandle == INVALID_PROCESSTRACE_HANDLE) {std::cerr << "Failed to open trace. Error: " << GetLastError() << std::endl;ControlTraceW(sessionHandle, nullptr, traceProperties, EVENT_TRACE_CONTROL_STOP);return;}ProcessTrace(&traceHandle, 1, nullptr, nullptr);ControlTraceW(sessionHandle, nullptr, traceProperties, EVENT_TRACE_CONTROL_STOP);
}

在这里插入图片描述

http://www.xdnf.cn/news/1437.html

相关文章:

  • Android 回显
  • 实验二 多线程编程实验
  • 云原生--CNCF-2-五层生态结构(成熟度3层分类,云原生生态5层结构)
  • 前端加密介绍与实战
  • 3dmax模型怎么导入酷家乐插件,材质贴图在,可优化不卡,可批量处理,无需打开一个个max,可批量转FBX/GLB/GLTF/OBJ/SU
  • Git简介与入门
  • 使用分布式ID作为MybatisID生成器
  • 【NVIDIA】Isaac Sim 4.5.0 Franka 机械臂参数解析
  • QT软件安装(12)
  • Sentinel源码—9.限流算法的实现对比一
  • 黑马点评redis改 part 5
  • 面向 C# 初学者的完整教程
  • 千问2.5-VL-7B的推理、微调、部署_笔记2
  • MyBatis中的@Param注解-如何传入多个不同类型的参数
  • .NET 6 + Dapper + User-Defined Table Type
  • 缓存与数据库一致性方案
  • 数据分析:用Excel做周报
  • Android开发常用外部组件及使用指南(上)
  • maple实现移位算法
  • 智驭未来:NVIDIA自动驾驶安全白皮书与实验室创新实践深度解析
  • Dart Flutter数据类型详解 int double String bool list Map
  • 亚远景-基于ASPICE标准的汽车软件过程优化路径
  • 电路中的DGND、GROUND、GROUND_REF的区别,VREF、VCC、VDD、VEE和VSS的区别?
  • Django 实现电影推荐系统:从搭建到功能完善(附源码)
  • AutoGPT超详细教程
  • SQL 时间转换的CONVERT()函数应用说明
  • Sentinel源码—9.限流算法的实现对比二
  • HSTL详解
  • 容器化-Docker-进阶
  • 高光谱相机在工业检测中的应用:LED屏检、PCB板缺陷检测