百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分析 > 正文

iMonitorSDK 序列教程一 · 基础教程

liebian365 2024-10-20 10:00 25 浏览 0 评论

iMonitorSDK (https://imonitorsdk.com/) 一款为终端、主机提供系统行为监控的开发套件。旨在帮助终端安全、管控、审计、零信任、主机安全等行业应用可以快速实现必要功能,而不用关心底层驱动的开发、维护和兼容性问题,让其可以专注于业务开发。适用于下列场景:零信任、终端管控、行为审计、主机安全、主动防御(HIPS)、终端检测与响应(EDR)、数据防泄密(DLP)、上网行为管理。


本篇教程主要介绍iMonitorSDK基础概念和接入过程。

SDK目录说明

  • bin SDK二进制
  • inc SDK头文件
  • sample SDK示例代码
  • build.bat SDK示例代码编译脚本

SDK头文件说明

  • iMonitor.h 内核头文件,包括所有的监控消息、内核通讯协议、其他声明等。
  • iMonitorSDK.h 应用层SDK声明头文件,包括接口、接口的封装。
  • iMonitorSDKExtension.h 应用层扩展能力声明头文件,包括代理引擎、规则引擎等。
  • iMonitorProtocol.h 监控消息协议封装,把原始的消息封装成更加容易使用的结构体。

使用的时候,只需要包含iMonitorSDK.h、iMonitorProtocol.h就好了。

#include <iMonitorSDK.h>
#include <iMonitorProtocol.h>

SDK接入过程

继承IMonitorCallback,实现相应的函数,核心是OnCallback函数

所有监控到的消息,都会通过OnCallback通知过来,具体消息的类型、字段可以参考IMonitorMessasge接口

class MonitorCallback : public IMonitorCallback
{
public:
    void OnCallback(IMonitorMessage* Message) override
    {
    }
};

使用MonitorManager对象来启动并注册接口

    MonitorManager manager;
    MonitorCallback callback;

    HRESULT hr = manager.Start(&callback);

如果返回成功,初始化就完成了。

接下来根据实际需要,可以通过cxMSGUserSetMSGConfig设置不同的消息监控,比如要监控进程启动,可以设置下面的参数:

    cxMSGUserSetMSGConfig config;
    config.Config[emMSGProcessCreate] = emMSGConfigSend;
    manager.InControl(config);

cxMSGUserSetMSGConfig的使用说明

所有的监控都通过cxMSGUserSetMSGConfig来设置。

struct cxUserMSGConfig
{
    ULONG        Config[emMSGMax];
    ULONG        Fields[emMSGMax];
}

typedef cxMSGUser<emUserSetMSGConfig, cxUserMSGConfig> cxMSGUserSetMSGConfig;

Config说明

字段

说明

emMSGConfigPost

表示监控是异步消息,不会阻塞操作(也就无法拦截阻断)

emMSGConfigSend

表示监控是同步等待,会阻塞操作者,可以在回调里面通过SetBlock拦截操作的发生

emMSGConfigIncludeKernelEvent

表示监控是否要支持内核(System进程)触发的消息,默认不监控

注意:如果设置了emMSGConfigSend,最好不要开启调试,不然容易导致系统卡死。(因为同步等待会阻塞其他进程的操作,需要监控程序返回后才能继续执行,而调试器会挂起监控程序,导致没法处理监控消息而卡死系统)

Fields说明

Fields字段表示监控需要哪些字段,各个类型支持的字段可以参考 iMonitorProtocol.h

按需设置不同的字段,某些不需要的字段不设置,这样可以优化一些性能。

全部消息类型

进程相关消息

消息类型

说明

emMSGProcessCreate

进程创建事件,返回拦截可以阻止进程的创建

emMSGProcessExit

进程退出事件

emMSGProcessOpen

打开进程事件,可以拦截打开用于保护进程

emMSGThreadCreate

线程创建事件

emMSGThreadExit

线程退出事件

emMSGThreadOpen

打开线程事件

emMSGImageLoad

加载模块事件,返回拦截可以阻止某个模块、某个驱动的加载

emMSGProcessStart

(模拟事件)进程启动事件

emMSGThreadStart

(模拟事件)线程启动事件

文件相关消息(带Post的表示动作已经完成)

消息类型

说明

emMSGFileCreate

打开、创建文件事件,返回拦截可以阻止文件的打开、创建

emMSGFilePostCreate


emMSGFileQueryOpen

打开文件事件

emMSGFilePostQueryOpen


emMSGFileCleanup


emMSGFileCreateSection

映射文件事件

emMSGFilePostCreateSection


emMSGFileRead

读取文件事件

emMSGFilePostRead


emMSGFileWrite

写文件事件

emMSGFilePostWrite


emMSGFileCreateHardLink

创建文件硬链接事件

emMSGFilePostCreateHardLink


emMSGFileRename

文件重命名事件

emMSGFilePostRename


emMSGFileDelete

删除文件事件

emMSGFilePostDelete


emMSGFileSetSize

设置文件大小事件

emMSGFilePostSetSize


emMSGFileSetBasicInfo

设置文件基本信息事件

emMSGFilePostSetBasicInfo


emMSGFileFindFile

查找文件、遍历文件事件

emMSGFilePostFindFile


注册表相关消息(带Post的表示动作已经完成)

消息类型

说明

emMSGRegCreateKey

打开、创建注册表键

emMSGRegPostCreateKey


emMSGRegOpenKey

打开注册表键

emMSGRegPostOpenKey


emMSGRegDeleteKey

删除注册表键

emMSGRegPostDeleteKey


emMSGRegRenameKey

重命名注册表键

emMSGRegPostRenameKey


emMSGRegEnumKey

查找遍历注册表键

emMSGRegPostEnumKey


emMSGRegLoadKey

加载文件映射成注册表键

emMSGRegPostLoadKey


emMSGRegReplaceKey

加载文件替换注册表键

emMSGRegPostReplaceKey


emMSGRegDeleteValue

删除注册表值

emMSGRegPostDeleteValue


emMSGRegSetValue

设置注册表值

emMSGRegPostSetValue


emMSGRegQueryValue

查询注册表值内容

emMSGRegPostQueryValue


网络相关消息

基于AFD过滤驱动方式实现,所有操作同socket操作,可以获取套接字的调用回调

消息类型

说明

emMSGSocketCreate


emMSGSocketControl


emMSGSocketPostControl


emMSGSocketConnect


emMSGSocketPostConnect


emMSGSocketSend


emMSGSocketRecv


emMSGSocketPostRecv


emMSGSocketSendTo


emMSGSocketPostSendTo


emMSGSocketRecvFrom


emMSGSocketPostRecvFrom


emMSGSocketListen


emMSGSocketPostListen


emMSGSocketAccept


emMSGSocketPostAccept


基于WFP过滤驱动实现

消息类型

说明

emMSGWFPTcpConnect


emMSGWFPUdpConnect


emMSGWFPTcpAccept


emMSGWFPUdpAccept


emMSGWFPICMPConnect


emMSGWFPICMPAccept


emMSGWFPSend


emMSGWFPRecv


emMSGWFPSendTo


emMSGWFPRecvFrom


emMSGWFPICMPSendTo


emMSGWFPICMPRecvFrom


IMonitorCallback 接口说明

interface IMonitorCallback
{
    //
    //  DisableXxxMonitor: (在驱动启动前设置生效) 表示是否关闭Xxx的监控,如果只需要部分能力,建议关闭其他不需要的监控。一般用于优化性能,解决冲突。
    //  InternalCallback: 内部使用,接管原始的消息
    //  ExtensionFieldTable: 消息扩展字段
    //
    struct GlobalConfig {
            bool            DisableFileMonitor  = false;
            bool            DisableRegMonitor   = false;
            bool            DisableSocketMonitor= false;
            bool            DisableWFPMonitor   = false;
            bool            DisableNPMSMonitor  = false;

            bool            InternalCallback    = false;

            MonitorExtensionFieldTable ExtensionFieldTable;
    };

    virtual void            OnConfig            (GlobalConfig& Config) {}
    virtual void            OnCustomEvent       (ULONG Type, PVOID Context) {}
    virtual bool            OnInternalCallback  (cxMSGHeader* Header, HANDLE FilterHandle, ULONGLONG MessageId) { return false; }
    virtual void            OnCallback          (IMonitorMessage* Message) = 0;
};

函数

说明

OnCallback

【核心】监控消息回调函数,所有的消息都会通过这个回调触发

OnInternalCallback

内部接口,可以获取原始驱动通讯的协议

OnCustomEvent

自定义事件:消息回调都在同一个线程,有时候为了避免多线程,可以通过SendCustomEvent发送事件到消息回调的线程执行

OnConfig

全局配置,可以用于关闭某些监控开关,或者设置字段扩展

IMonitorMessage 接口说明

interface IMonitorMessage
{
    struct Binary {
        PVOID Data;
        ULONG Length;
    };

    //
    // 基础字段
    //

    virtual cxMSGHeader*    GetHeader           (void) = 0;
    inline ULONG            GetType             (void) { return GetHeader()->Type; }
    inline ULONG            GetStatus           (void) { return GetHeader()->Status; }
    inline ULONG            GetCurrentProcessId (void) { return GetHeader()->CurrentProcessId; }
    inline ULONG            GetCurrentThreadId  (void) { return GetHeader()->CurrentThreadId; }

    virtual IMonitorMessageProcess* GetProcess  (void) = 0;

    virtual LPCWSTR         GetTypeName         (void) = 0;
    virtual ULONG           GetFieldCount       (void) = 0;
    virtual emMSGDataType   GetFieldType        (ULONG Index) = 0;
    virtual LPCWSTR         GetFieldName        (ULONG Index) = 0;
    virtual ULONG           GetFieldIndex       (LPCWSTR Name) = 0;

    virtual ULONG           GetULONG            (ULONG Index) = 0;
    virtual ULONGLONG       GetULONGLONG        (ULONG Index) = 0;
    virtual cxMSGDataIPRef  GetIP               (ULONG Index) = 0;
    virtual Binary          GetBinary           (ULONG Index) = 0;
    virtual LPCWSTR         GetString           (ULONG Index) = 0;
    virtual LPCWSTR         GetFormatedString   (ULONG Index) = 0;

    virtual bool            IsMatch             (ULONG Index, LPCWSTR Pattern, bool IgnoreCase = true) = 0;

    //
    // 扩展字段,由开发者自行定义的字段,这些字段可以用于规则引擎,详细参考MonitorExtensionFieldTable
    //  HasValue: 表示是否有值,如果没有字段则返回默认值并且HasValue = false
    //

    virtual ULONGLONG       GetNumber           (LPCWSTR Name, bool* HasValue = nullptr) = 0;
    virtual LPCWSTR         GetString           (LPCWSTR Name, bool* HasValue = nullptr) = 0;

    //
    // Action 相关操作,用于返回消息结果给驱动:需要Waiting状态才能设置返回结果
    //

    virtual bool            IsWaiting           (void) = 0;
    virtual bool            SetAction           (const cxMSGAction& Action) = 0;
    virtual bool            SetBlock            (void) = 0;
    virtual bool            SetGrantedAccess    (ULONG Access) = 0;
    virtual bool            SetIPRedirect       (ULONG IP, USHORT Port, ULONG ProcessId = ::GetCurrentProcessId()) = 0;
    virtual bool            SetTerminateProcess (void) = 0;
    virtual bool            SetTerminateThread  (void) = 0;
    virtual bool            SetInjectDll        (LPCWSTR Path) = 0;
    virtual bool            SetFileRedirect     (LPCWSTR Path) = 0;

    //
    //  异步处理:
    //      设置Pending成功后,可以拥有IMonitorMessage的生命周期,允许在回调返回后继续使用。
    //      使用完毕,一定需要使用CompletePending来恢复状态,不然内核等待事件需要超时才能返回。
    //
    //  使用场景:需要弹框交互确认、或者是多线程处理的场景。
    //

    virtual bool            Pending             (void) = 0;
    virtual void            CompletePending     (void) = 0;

    virtual void            SetCustomContext    (PVOID Context) = 0;
    virtual PVOID           GetCustomContext    (void) = 0;
};

核心函数说明

函数

说明

GetType

返回消息类型

GetULONG、GetULONGLONG、GetString

获取消息字段

IsWaiting

判断是否同步消息

SetAction

设置消息响应动作,具体参考cxMSGAction

SetBlock

设置拦截,阻止事件发生

SetIPRedirect

设置网络重定向

SetTerminateProcess

结束当前操作进程

SetInjectDll

注入动态库

Pending

设置延迟处理,Pending成功后可以抛到其他线程处理消息,比如异步弹框

消息协议

为了更加方便获取消息的各个字段,SDK对所有的消息都进行了封装。

比如emMSGProcessCreate对应的协议封装是cxMSGProcessCreate,转换成协议封装后就可以更加方便获取字段。

    void OnCallback(IMonitorMessage* Message) override
    {
        if (Message->GetType() == emMSGProcessCreate) {
                cxMSGProcessCreate* msg = (cxMSGProcessCreate*)Message;
        }
    }
class cxMSGProcessCreate : public MonitorMessage
{
public:
	enum {
		emMSGFieldCallstack,
		emMSGFieldCurrentProcessCreateTime,
		emMSGFieldCurrentProcessName,
		emMSGFieldCurrentProcessPath,
		emMSGFieldCurrentProcessCommandline,
		emMSGFieldPath,
		emMSGFieldProcessId,
		emMSGFieldCommandline,
		emMSGFieldCreateTime,
		emMSGFieldParentPath,
		emMSGFieldParentProcessId,
		emMSGFieldParentCommandline,
		emMSGFieldParentCreateTime,
	};

public:
	auto Path() { return GetPath(emMSGFieldPath); }
	auto ProcessId() { return GetULONG(emMSGFieldProcessId); }
	auto Commandline() { return GetString(emMSGFieldCommandline); }
	auto CreateTime() { return GetTime(emMSGFieldCreateTime); }
	auto ParentPath() { return GetPath(emMSGFieldParentPath); }
	auto ParentProcessId() { return GetULONG(emMSGFieldParentProcessId); }
	auto ParentCommandline() { return GetString(emMSGFieldParentCommandline); }
	auto ParentCreateTime() { return GetTime(emMSGFieldParentCreateTime); }

	bool IsMatchPath(LPCWSTR Pattern, bool IgnoreCase = true) { return IsMatch(emMSGFieldPath, Pattern, IgnoreCase); }
	bool IsMatchCommandline(LPCWSTR Pattern, bool IgnoreCase = true) { return IsMatch(emMSGFieldCommandline, Pattern, IgnoreCase); }
	bool IsMatchParentPath(LPCWSTR Pattern, bool IgnoreCase = true) { return IsMatch(emMSGFieldParentPath, Pattern, IgnoreCase); }
	bool IsMatchParentCommandline(LPCWSTR Pattern, bool IgnoreCase = true) { return IsMatch(emMSGFieldParentCommandline, Pattern, IgnoreCase); }
};

如果想定制自己的封装,可以通过IDL + 模板的方式自动生成。

相关推荐

C++零基础入门学习指南(中篇)

目标:像拼装乐高一样理解程序模块,掌握内存管理核心技能...

“5 分钟 CMake 使用指南,解决我的 C++ 打包问题!”

...

Linux下跨语言调用C++实践

不同的开发语言适合不同的领域,例如Python适合做数据分析,C++适合做系统的底层开发,假如它们需要用到相同功能的基础组件,组件使用多种语言分别开发的话,不仅增加了开发和维护成本,而且不能确保多种语...

输入格式控制:C++程序中的数据接收与处理技巧

在C++编程中,输入输出是非常基本且重要的操作。尤其是输入部分,程序员通常需要从用户那里获取数据,并根据不同的输入格式进行处理。然而,用户的输入往往是多样化的,如何有效地控制输入格式,确保程序正确接收...

常见读写excel文件的库/类

在C++语言中读写EXCEL表格,有这几种方法:COM方式、ODBC方式、OLE方式、纯底层格式分析方式。Basicexcel使用方法:https://www.cnblogs.com/paullam/...

C++文档识别接口如何实现 高效办公

  数字化信息爆炸时代,办公效率的提升成为企业和个人的迫切需求。人工智能技术的飞速发展,为我们带来了前所未有的便利,翔云文档识别接口便是其中之一。  与传统的人工手动录入相比,文档识别接口优势显著。人...

C++如何生成Microsoft Word文档

...

超实用C++学习指南:语法要点、经典书籍、实战案例全汇总!

以下是为您整理的C++学习指南,综合了语法要点、资源推荐及实战方向,结合搜索结果和经典知识体系,帮助您系统学习:一、C++基础语法学习指南1.核心概念oC++是静态类型、编译式语言,支持面向对象和...

掌握C++文件读写,让代码更灵动!

文章改写指令通常涉及对原有文本进行调整、重组或重新表达,以保持或增强信息的准确性和可读性,同时可能改变风格、语气或目标受众。以下是一些具体的文章改写指令示例:·2.简化语言:→指令:将文章中的复杂词汇...

闲置宽带能换钱?P2P CDN、无线宝、赚钱宝到底靠不靠谱

无线宝类产品其实由来已久,无线宝类产品即与支付宝、余额宝、余利宝等货币基金毫无干系,与区块链“挖币”更存在本质的不同,而是一种利用家庭中的闲置宽带,通过流量来换取佣金的产品。无线宝类产品其实在过去几年...

攻略什么?闲置宽带还可以赚钱?

现在很多朋友在使用10Mbps、50Mbps甚至100Mbps的高速宽带,不过普通用户并不是长时间都需要这么高速的宽带。比如对于100Mbps的宽带用户,在日常浏览网页时,基本上2Mbps左右的带宽即...

明日学业水平考试开始报名 详细步骤都在这里

点击上面蓝字关注我们哦~日前,山东省教育考试院发布了《山东省2019年夏季学业水平考试报名考生操作说明》(点击文末阅读原文查看),明天就到了报名的时候了,详细的报名步骤、网上缴费流程、追加报考科目等...

瞄准用户上传带宽:HiWiFi 极路由 联合 迅雷 推出 “极赚钱”套餐

上次总理谈到宽带降价问题时,很多网友除了吐槽网速慢费用贵,还反映宽带网络的上下行速度不对等。比如说以前ADSL2M的宽带只有512Kbps的上行速度,现在升级到光纤网络之后,按理说技术上实现上下行...

揭秘P2P平台刷数据:交易额从100万到1200万

(作者:峰岭、刘珺、周娜)从默默无闻到万众瞩目,从“零数据”到“大数据”,从小众投资到大众理财,从个人借贷到企业借款,从个人信用到车、房、资产抵押……近两年来P2P行业以迅雷之速快速爆发,P2P平台也...

运营商让我签这个宽带违规使用告知函,我懵逼了

特么的是爱奇艺迅雷自己上传的p2p数据,btpt也会上传,直播也会上传,监控也会,传文件也会,到底他么的运营商你要干个啥啊,我不仅没捞着一分好处,夹在中间两头受气!真特么晦气这特么是谁弄的函?完全没搞...

取消回复欢迎 发表评论: