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将显示自上次运行 ...
随机推荐
- 项目完成 - 基于Django3.x版本 - 开发部署小结
前言 最近因为政企部门的工作失误,导致我们的项目差点挂掉,客户意见很大,然后我们只能被动进入007加班状态,忙得嗷嗷叫,直到今天才勉强把项目改完交付,是时候写一个小结. 技术 因为前期需求不明确,数据 ...
- go学习第一课--语法基础
一.hello world 新建文件helloworld.go package main import "fmt" func main() { fmt.Println( ...
- 【FAQ】接入HMS Core地图服务过程中常见问题总结
HMS Core地图服务(Map Kit)给开发者提供一套地图开发调用的SDK,助力全球开发者实现个性化地图呈现与交互,方便轻松地在应用中集成地图相关的功能,全方位提升用户体验. 在日常工作中,我们会 ...
- create-react-app的TS支持以及css模块化
开始: 利用官方脚手架,搭建react工程.参考:https://react.docschina.org/docs/create-a-new-react-app.html. 过程: 1.暴露webpa ...
- Linux系统创建可执行文件软链接
技术背景 由于创建软链接这个事情,在算法开发的日常中使用到的并不是很多,因此本文也是做一个简单的回顾.这里我们使用的案例是通过TMalign这个蛋白质打分文件,在编译好可执行文件之后,可以使用建立软链 ...
- ELF文件结构
ELF文件结构 ELF文件的全称是Executable and Linkable Format,直译为"可执行可链接格式",包括目标文件(.o).可执行文件(可以直接运行).静态链 ...
- PHP反序列化链分析
前言 基本的魔术方法和反序列化漏洞原理这里就不展开了. 给出一些魔术方法的触发条件: __construct()当一个对象创建(new)时被调用,但在unserialize()时是不会自动调用的 __ ...
- Rainbond结合NeuVector实践容器安全管理
前言 Rainbond 是一个云原生应用管理平台,使用简单,不需要懂容器.Kubernetes和底层复杂技术,支持管理多个Kubernetes集群,和管理企业应用全生命周期.但是随着云原生时代的一点点 ...
- 什么叫做 SSO
什么叫做 SSO 本文写于 2020 年 12 月 8 日 SSO 的全称叫做 Single Sign On,意味「单点登录」. 何为单点登录?就是你希望自己的两个网站,可以做到:一个网站登录了,另一 ...
- 890. Find and Replace Pattern - LeetCode
Question 890. Find and Replace Pattern Solution 题目大意:从字符串数组中找到类型匹配的如xyy,xxx 思路: 举例:words = ["ab ...