C++实现ETW进行进程变动监控详解

 更新时间:2022年07月12日 16:03:25   作者:Icys  
ETW提供了一种对用户层应用程序和内核层驱动创建的事件对象的跟踪记录机制。为开发者提供了一套快速、可靠、通用的一系列事件跟踪特性。本文将利用ETW进行进程变动监控,需要的可以参考一下

何为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不会自己关

以上就是C++实现ETW进行进程变动监控详解的详细内容,更多关于C++进程监控的资料请关注脚本之家其它相关文章!

相关文章

  • C语言各种变量的初始化方式

    C语言各种变量的初始化方式

    这篇文章主要介绍了C语言各种变量的初始化方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-04-04
  • C++实现LeetCode(41.首个缺失的正数)

    C++实现LeetCode(41.首个缺失的正数)

    这篇文章主要介绍了C++实现LeetCode(41.首个缺失的正数),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • C语言解3元1次方程组 用初中学的最基本的联合消元法

    C语言解3元1次方程组 用初中学的最基本的联合消元法

    最近就想自己能不能先写个算线性方程组的程序呢?后来就想了这么个方法,暂时只能算3元的,任意元的接下来继续想。有太多硬编码,希望有兴趣的读者可以给点修改建议
    2013-11-11
  • C++从零配置ffmpeg的详细过程

    C++从零配置ffmpeg的详细过程

    本博文源于笔者正在做的任务,将视频mp4每帧转换成jpg格式,前提是需要配置ffmpeg,因此本文从0下载教读者如何配置ffmpeg,文中通过图文结合的方式给大家介绍得非常详细,需要的朋友可以参考下
    2024-03-03
  • C++ WideCharToMultiByte()函数案例详解

    C++ WideCharToMultiByte()函数案例详解

    这篇文章主要介绍了C++ WideCharToMultiByte()函数案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • C++详细讲解模拟实现位图和布隆过滤器的方法

    C++详细讲解模拟实现位图和布隆过滤器的方法

    位图(bitset)是一种常用的数据结构,常用在给一个很大范围的数,判断其中的一个数是不是在其中。在索引、数据压缩方面有很大的应用。布隆过滤器是由布隆提出的,它实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中
    2022-06-06
  • 从C语言过渡到C++之基本变化

    从C语言过渡到C++之基本变化

    在之前的C++代码训练营系列中,我试图用完成具体项目的方式给大家介绍C++,但后来大家反馈说这样从C过渡到C++有点跟不上。于是我又专门设计了这个《从C到C++》的过渡专题,我准备通过10篇文章介绍一下C++和C的重要区别。
    2017-07-07
  • C语言圣诞树的实现示例

    C语言圣诞树的实现示例

    本篇主要介绍了C语言圣诞树的实现示例,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-12-12
  • C语言运用函数指针数组实现计算器功能

    C语言运用函数指针数组实现计算器功能

    这篇文章主要为大家详细介绍了C语言运用函数指针数组实现计算器功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-10-10
  • static关键字的作用详解

    static关键字的作用详解

    在C语言中,static的字面意思很容易把我们导入歧途,其实它的作用有三条。
    2013-04-04

最新评论