C++实现ETW进行进程变动监控
C++实现ETW进行进程变动监控
文章地址:https://www.cnblogs.com/Icys/p/EtwProcess.html
何为Etw
ETW(Event Tracing for Windows)提供了一种对用户层应用程序和内核层驱动创建的事件对象的跟踪记录机制。为开发者提供了一套快速、可靠、通用的一系列事件跟踪特性。
前言
一直想研究一种监控进程的方法,但\(wmi/枚举进程\)的方法,要么反应太慢,要么占用高。最近看到有人用\(易语言\)完成了Etw对进程变动监控的实现。
但是一直没看到\(C++\)的实现,于是决定将\(易语言\)翻译为\(C++\)。
代码
直接上翻译的代码
#include <iostream>
#include <string>
#include <cstring>
#include <windows.h>
#include <evntrace.h>
#include <psapi.h>
#include <direct.h>
#include <evntcons.h>
using namespace std;
char SESSION_NAME_FILE[] = "Sample_Process";
const UCHAR _Flag[] = { 173, 74, 129, 158, 4, 50, 210, 17, 154, 130, 0, 96, 8, 168, 105, 57 };
EVENT_TRACE_PROPERTIES m_TraceConfig;
UCHAR m_pTraceConfig[2048];
char m_File[256];
BOOL m_DoWhile;
TRACEHANDLE m_hTraceHandle;
ULONG64 m_hTraceHandle_econt[1];
TRACEHANDLE m_hSessionHandle;
string Unicode_To_Ansi(wstring strValue)
{
static CHAR sBuff[1024] = { 0 };
int iRet = WideCharToMultiByte(CP_ACP, 0, strValue.c_str(), -1, sBuff, sizeof(sBuff), NULL, NULL);
if (iRet > 0) {
return string(sBuff);
}
return "";
}
VOID WINAPI MyProcessRecordEvents(PEVENT_RECORD EventRecord)
{
switch (EventRecord->EventHeader.EventDescriptor.Id)
{
case 1://创建进程
cout << "创建进程!进行创建进行的进程ID:" <<
EventRecord->EventHeader.ProcessId <<
",线程ID:" <<
EventRecord->EventHeader.ThreadId <<
",进程SessionID:" <<
*(ULONG*)(((PUCHAR)EventRecord->UserData)+32)<<
",创建的进程ID:"<<
*(ULONG*)(((PUCHAR)EventRecord->UserData) + 0) <<
",创建的进程路径:"<<
Unicode_To_Ansi( wstring((wchar_t*)(((PUCHAR)EventRecord->UserData) + 60)))
<<endl;
break;
case 2://进程退出
cout << "进程退出!进程ID:" <<
EventRecord->EventHeader.ProcessId <<
",线程ID:" <<
EventRecord->EventHeader.ThreadId <<
", 进程名:"<<
((LPSTR)EventRecord->UserData) + 84
<<endl;
break;
cout << "进程ID:" << EventRecord->EventHeader.ProcessId << ",未知的行为:0x"<<hex<<EventRecord->EventHeader.EventDescriptor.Id << endl;
default:
break;
}
}
void CloseEtw()
{
ULONG l_result = StopTraceA(m_hSessionHandle, SESSION_NAME_FILE, (PEVENT_TRACE_PROPERTIES)(m_pTraceConfig + 8));
if (m_hTraceHandle != NULL)
{
CloseTrace(m_hTraceHandle);
}
}
DWORD WINAPI OpenEtw(LPVOID lpThreadParameter)
{
m_DoWhile = TRUE;
_getcwd(m_File, sizeof(m_File));
strcat(m_File, "\\MyFile.etl");
m_TraceConfig.Wnode.BufferSize = 1024;
m_TraceConfig.Wnode.Flags = WNODE_FLAG_TRACED_GUID;
m_TraceConfig.Wnode.ClientContext = 3;
m_TraceConfig.BufferSize = 1;
m_TraceConfig.MinimumBuffers = 16;
m_TraceConfig.LogFileMode = EVENT_TRACE_REAL_TIME_MODE;
m_TraceConfig.LoggerNameOffset = 120;
m_TraceConfig.FlushTimer = 1;
RtlMoveMemory(m_pTraceConfig + 8, &m_TraceConfig, 120);
RtlCopyMemory(m_pTraceConfig + 128, SESSION_NAME_FILE, sizeof(SESSION_NAME_FILE));
RtlCopyMemory(m_pTraceConfig + 128 + sizeof(SESSION_NAME_FILE), m_File, strlen(m_File));
RtlCopyMemory(m_pTraceConfig + 28, _Flag, sizeof(_Flag));
ULONG l_result = StartTraceA(&m_hSessionHandle, SESSION_NAME_FILE, (PEVENT_TRACE_PROPERTIES)(m_pTraceConfig + 8));
if (m_hSessionHandle == NULL && l_result == ERROR_ACCESS_DENIED)
{
cout << "StartTraceA失败!原因:无管理员权限!" << endl;
return 0;
}
else if (m_hSessionHandle == NULL && l_result == ERROR_ALREADY_EXISTS)
{
m_hSessionHandle = 44;//输入上一次终止时候的句柄
CloseEtw();
cout << "StartTraceA失败!原因:已经有Etw事件进行数据跟踪!请使用上方屏蔽代码关闭事件或者使用 计算机管理 停用事件:Sample_Process" << endl;
ControlTraceA(m_hSessionHandle, SESSION_NAME_FILE, (PEVENT_TRACE_PROPERTIES)(m_pTraceConfig + 8), 1);
return 0;
}
cout << "hSessionHandle: " << m_hSessionHandle << endl;
const UCHAR m_ProcessGUID[] = { 214, 44, 251, 34, 123, 14, 43, 66, 160, 199, 47, 173, 31, 208, 231, 22 }; // PsProvGuid
l_result = EnableTraceEx((LPCGUID)(m_ProcessGUID), 0, m_hSessionHandle, 1, 0, 16, 0, 0, 0); //这里MatchAnyKeyword的64其实是0x40,表示 #KERNEL_KEYWORDS_IMAGE
EVENT_TRACE_LOGFILEA m_Logfile;
ZeroMemory(&m_Logfile, sizeof(m_Logfile));
m_Logfile.LoggerName = SESSION_NAME_FILE;
*((ULONG*)((PUCHAR)&m_Logfile + 20)) = 268439808;
m_Logfile.EventRecordCallback = MyProcessRecordEvents;
m_Logfile.Context = (PVOID)0x114514;//随便输入一个数就好了
SetLastError(0);
m_hTraceHandle = OpenTraceA(&m_Logfile);
cout << "开始监视!" << endl;
m_hTraceHandle_econt[0] = m_hTraceHandle;
ULONG rc = ProcessTrace(m_hTraceHandle_econt, 1, 0, 0);
return 0;
}
int main()
{
CreateThread(NULL, NULL, OpenEtw, NULL, NULL, NULL);
//Sleep(10000);
system("pause");
CloseEtw();
return 0;
}
注意事项
必须给管理员权限
请正常退出(按任意键),否则Trace不会自己关
其他
作者(本人)水平有限,部分翻译可能有误,代码有问题可以直接回复我。
以后有时间可能会考虑翻译一下这个作者其他的关于Etw的例子,毕竟Etw实现的这些功能都很有意思,并且都比较高级。
C++实现ETW进行进程变动监控的更多相关文章
- zabbix3.0.4添加对指定进程的监控
zabbix3.0.4添加对进程的监控: 主要思路: 通过 ps -ef|grep sdk-push-1.0.0.jar |grep -v grep|wc -l 这个命令来判断进程sdk-push是否 ...
- C#进程创建监控
关于c#进程创建监控的文章大多都是“遍历一次进程用if去判断存在或否”这样的方法,我觉得体验不是很好.这几天写的一个软件正好需要实时监控进程创建的模块,在网上找到了很不错的方法,整理一下分享出来给大家 ...
- .NET Core项目部署到Linux(Centos7)(八)为.NET Core项目创建Supervisor进程守护监控
目录 1.前言 2.环境和软件的准备 3.创建.NET Core API项目 4.VMware Workstation虚拟机及Centos 7安装 5.Centos 7安装.NET Core环境 6. ...
- 如何灵活运用Linux 进程资源监控和进程限制
导读 每个 Linux 系统管理员都应该知道如何验证硬件.资源和主要进程的完整性和可用性.另外,基于每个用户设置资源限制也是其中一项必备技能. 在这篇文章中,我们会介绍一些能够确保系统硬件和软件正常工 ...
- Ubuntu 14.10 下运行进程实时监控pidstat命令详解
简介 pidstat主要用于监控全部或指定进程占用系统资源的情况,如CPU,内存.设备IO.任务切换.线程等.pidstat首次运行时显示自系统启动开始的各项统计信息,之后运行pidstat将显示自上 ...
- linux服务器内存、根目录使用率、某进程的监控告警脚本
脚本内容如下 #!/bin/bash #磁盘超过百分之80发送邮件告警 DISK_USED=`df -T |sed -n "2p" |awk '{print ($4/$3)*100 ...
- Linux 运行进程实时监控pidstat命令详解
简介 pidstat主要用于监控全部或指定进程占用系统资源的情况,如CPU,内存.设备IO.任务切换.线程等.pidstat首次运行时显示自系统启动开始的各项统计信息,之后运行pidstat将显示自上 ...
- python 守护进程,监控进程
守护进程代码: import time, os import subprocess def run(): while True: taskList = os.popen('tasklist').rea ...
- 进程实时监控pidstat命令详解
pidstat主要用于监控全部或指定进程占用系统资源的情况,如CPU,内存.设备IO.任务切换.线程等.pidstat首次运行时显示自系统启动开始的各项统计信息,之后运行pidstat将显示自上次运行 ...
随机推荐
- Python 工匠:使用数字与字符串的技巧
序言 这是 "Python 工匠"系列的第 3 篇文章. 数字是几乎所有编程语言里最基本的数据类型,它是我们通过代码连接现实世界的基础.在 Python 里有三种数值类型:整型(i ...
- 聊聊 node 如何优雅地获取 mac 系统版本
背景 今天突然碰到了一个兼容性需求,需要根据不同 macOS 版本,进行不同的兼容性处理. 没想到看似简单的需求,中间也经历了一番波折,好在最后解决了问题. 在此记录一下解决问题的过程,也方便其他有类 ...
- SDDC的Windows初体验-QT篇
前言 如果熟悉爱智和看过我之前文章的朋友见到这篇文章一定会有很大疑问,SDDC 作为智能设备发现控制协议,怎么会用在 windows 上? 这一切还是源自于我巨大的脑洞,因为这段在搞 Windows ...
- Blazor和Vue对比学习(基础1.3):属性和父子传值
组件除了要解决视图层展示.视图层与逻辑层的数据绑定,还需要解决一个重大问题,就是在组件树中实现数据传递,包括了父到子.子到父.祖到孙,以及任意组织之间.而我们上一章讲到的实现双向绑定的两个指令,Vue ...
- Nginx中FastCGI参数的优化配置实例
在配置完成Nginx+FastCGI之后,为了保证Nginx下PHP环境的高速稳定运行,需要添加一些FastCGI优化指令.下面给出一个优化实例,将下面代码添加到Nginx主配置文件中的HTTP层级. ...
- opencv学习之边缘检测
边缘检测 是图像处理 过程中经常会涉及到的一个环节.而在计算机视觉 和 机器学习领域,边缘检测 用于 特征提取 和 特征检测 效果也是特别明显.而 openCV 中进行边缘检测的 算法 真是五花八门, ...
- [java并发编程]基于信号量semaphore实现限流器
目录 一.什么是信号量 二.信号量类Semaphore 三.实现限流器 欢迎关注我的博客,更多精品知识合集 一.什么是信号量 "信号量"在编程术语中使用单词semaphore,那什 ...
- 实践torch.fx第一篇——基于Pytorch的模型优化量化神器
第一篇--什么是torch.fx 今天聊一下比较重要的torch.fx,也趁着这次机会把之前的torch.fx笔记整理下,笔记大概拆成三份,分别对应三篇: 什么是torch.fx 基于torch.fx ...
- git 无法拉取最新代码
删除本地文件后,想从远程仓库中重新新Pull最新代码,但是执行了git pull origin develop 命令后始终无法拉取下来 提示 Already up-to-date. 原因:当前本地库处 ...
- 省HVV初体验(edu)
浙江省HVV初体验 此次参加的HVV是edu分会场,总的来说是对HVV有了一个初步的认识,了解实战和靶场练习之间存在的巨大鸿沟. 经历了这次HVV,对于渗透测试有了更深一步的理解.渗透测试的本质就是信 ...