回调监控文件

使用 ObRegisterCallbacks 实现保护进程,其实稍微 PATCH 下内核,这个函数还能实现文件操作监视。但可惜只能在 WIN7X64 上用。因为在 WIN7X64 上 PATCH 对象结构的成员(ObjectType->TypeInfo.SupportsObjectCallbacks)是合法的,在 WIN8X64 以及之后系统上会触发 PATCHGUARD。但是经过实际测试,我手里的Win7 64 是可以在不修改myobtype->TypeInfo.SupportsObjectCallbacks = 1;的前提下直接注册回调,但是win8 64不行,win8 64 修改了myobtype->TypeInfo.SupportsObjectCallbacks = 1;之后发现没有蓝屏并且目前可以成功进行回调处理(只测试了手里的一台win8 64)。文件回调容易出问题,频率非常高。使用的时候建议使用成熟的文件过滤框架。

使用的时候和进程线程的回调句柄处理一样,需要修改标记使得无签名可以正常注册回调,然后在修改文件的myobtype->TypeInfo.SupportsObjectCallbacks = 1;然后在进行回调注册就行了。

注册:
// init callbacks
OB_CALLBACK_REGISTRATION obReg;
OB_OPERATION_REGISTRATION opReg;
memset(&obReg, 0, sizeof(obReg));
obReg.Version = ObGetFilterVersion();
obReg.OperationRegistrationCount = 1;
obReg.RegistrationContext = NULL;
RtlInitUnicodeString(&obReg.Altitude, L"321000");
obReg.OperationRegistration = &opReg;
memset(&opReg, 0, sizeof(opReg));
opReg.ObjectType = IoFileObjectType;
opReg.Operations = OB_OPERATION_HANDLE_CREATE|OB_OPERATION_HANDLE_DUPLICATE;
opReg.PreOperation = (POB_PRE_OPERATION_CALLBACK)&preCall;
//opReg.PostOperation = (POB_POST_OPERATION_CALLBACK)&postCall;//不需要
// register callbacks
status = ObRegisterCallbacks(&obReg, &obHandle);
注销:
ObUnRegisterCallbacks(obHandle);回调函数:
PVOID obHandle;OB_PREOP_CALLBACK_STATUS preCall(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION OperationInformation)
{
UNICODE_STRING DosName;
PFILE_OBJECT fileo = OperationInformation->Object;
HANDLE CurrentProcessId = PsGetCurrentProcessId();
UNREFERENCED_PARAMETER(RegistrationContext);
if( OperationInformation->ObjectType!=*IoFileObjectType )
return OB_PREOP_SUCCESS;
//过滤无效指针
if( fileo->FileName.Buffer==NULL   ||
!MmIsAddressValid(fileo->FileName.Buffer)    ||
fileo->DeviceObject==NULL  ||
!MmIsAddressValid(fileo->DeviceObject)   )
return OB_PREOP_SUCCESS;
//过滤无效路径
if( !_wcsicmp(fileo->FileName.Buffer,L"\\Endpoint")    ||
!_wcsicmp(fileo->FileName.Buffer,L"?") ||
!_wcsicmp(fileo->FileName.Buffer,L"\\.\\.")    ||
!_wcsicmp(fileo->FileName.Buffer,L"\\"))
return OB_PREOP_SUCCESS;
//阻止访问readme.txt
if(wcsstr(_wcslwr(fileo->FileName.Buffer),L"xxxx.txt"))
{
if (OperationInformation->Operation == OB_OPERATION_HANDLE_CREATE)
{
OperationInformation->Parameters->CreateHandleInformation.DesiredAccess=0;
}
if(OperationInformation->Operation == OB_OPERATION_HANDLE_DUPLICATE)
{
OperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess=0;
}
}
RtlVolumeDeviceToDosName(fileo->DeviceObject, &DosName);
DbgPrint("[FILE_MONITOR_X64][PID]%ld [File]%wZ%wZ\n", (ULONG64)CurrentProcessId, &DosName, &fileo->FileName);
return OB_PREOP_SUCCESS;
}文件标记处理相关结构体:
typedef struct _OBJECT_TYPE_INITIALIZER                                                                                                                                         // 25 elements, 0x70 bytes (sizeof)
{
/*0x000*/     UINT16       Length;union                                                                                                                                                                       // 2 elements, 0x1 bytes (sizeof){
/*0x002*/         UINT8        ObjectTypeFlags;struct                                                                                                                                                                  // 7 elements, 0x1 bytes (sizeof){
/*0x002*/             UINT8        CaseInsensitive : 1;                                                                                                                                   // 0 BitPosition
/*0x002*/             UINT8        UnnamedObjectsOnly : 1;                                                                                                                                // 1 BitPosition
/*0x002*/             UINT8        UseDefaultObject : 1;                                                                                                                                  // 2 BitPosition
/*0x002*/             UINT8        SecurityRequired : 1;                                                                                                                                  // 3 BitPosition
/*0x002*/             UINT8        MaintainHandleCount : 1;                                                                                                                               // 4 BitPosition
/*0x002*/             UINT8        MaintainTypeList : 1;                                                                                                                                  // 5 BitPosition
/*0x002*/             UINT8        SupportsObjectCallbacks : 1;                                                                                                                           // 6 BitPosition};};
/*0x004*/     ULONG32      ObjectTypeCode;
/*0x008*/     ULONG32      InvalidAttributes;
/*0x00C*/     struct _GENERIC_MAPPING GenericMapping;                                                                                                                                     // 4 elements, 0x10 bytes (sizeof)
/*0x01C*/     ULONG32      ValidAccessMask;
/*0x020*/     ULONG32      RetainAccess;
/*0x024*/     enum _POOL_TYPE PoolType;
/*0x028*/     ULONG32      DefaultPagedPoolCharge;
/*0x02C*/     ULONG32      DefaultNonPagedPoolCharge;
/*0x030*/     PVOID DumpProcedure;
/*0x038*/     PVOID OpenProcedure;
/*0x040*/     PVOID CloseProcedure;
/*0x048*/     PVOID DeleteProcedure;
/*0x050*/     PVOID ParseProcedure;
/*0x058*/     PVOID SecurityProcedure;
/*0x060*/     PVOID QueryNameProcedure;
/*0x068*/     PVOID OkayToCloseProcedure;
}OBJECT_TYPE_INITIALIZER, *POBJECT_TYPE_INITIALIZER;typedef struct _EX_PUSH_LOCK                 // 7 elements, 0x8 bytes (sizeof)
{union                                    // 3 elements, 0x8 bytes (sizeof){struct                               // 5 elements, 0x8 bytes (sizeof){
/*0x000*/             UINT64       Locked : 1;         // 0 BitPosition
/*0x000*/             UINT64       Waiting : 1;        // 1 BitPosition
/*0x000*/             UINT64       Waking : 1;         // 2 BitPosition
/*0x000*/             UINT64       MultipleShared : 1; // 3 BitPosition
/*0x000*/             UINT64       Shared : 60;        // 4 BitPosition};
/*0x000*/         UINT64       Value;
/*0x000*/         VOID*        Ptr;};
}EX_PUSH_LOCK, *PEX_PUSH_LOCK;typedef struct _MY_OBJECT_TYPE                   // 12 elements, 0xD0 bytes (sizeof)
{
/*0x000*/     struct _LIST_ENTRY TypeList;              // 2 elements, 0x10 bytes (sizeof)
/*0x010*/     struct _UNICODE_STRING Name;              // 3 elements, 0x10 bytes (sizeof)
/*0x020*/     VOID*        DefaultObject;
/*0x028*/     UINT8        Index;
/*0x029*/     UINT8        _PADDING0_[0x3];
/*0x02C*/     ULONG32      TotalNumberOfObjects;
/*0x030*/     ULONG32      TotalNumberOfHandles;
/*0x034*/     ULONG32      HighWaterNumberOfObjects;
/*0x038*/     ULONG32      HighWaterNumberOfHandles;
/*0x03C*/     UINT8        _PADDING1_[0x4];
/*0x040*/     struct _OBJECT_TYPE_INITIALIZER TypeInfo; // 25 elements, 0x70 bytes (sizeof)
/*0x0B0*/     struct _EX_PUSH_LOCK TypeLock;            // 7 elements, 0x8 bytes (sizeof)
/*0x0B8*/     ULONG32      Key;
/*0x0BC*/     UINT8        _PADDING2_[0x4];
/*0x0C0*/     struct _LIST_ENTRY CallbackList;          // 2 elements, 0x10 bytes (sizeof)
}MY_OBJECT_TYPE, *PMY_OBJECT_TYPE;处理文件标记:
VOID EnableObType(POBJECT_TYPE ObjectType)
{
PMY_OBJECT_TYPE myobtype = (PMY_OBJECT_TYPE)ObjectType;
myobtype->TypeInfo.SupportsObjectCallbacks = 1;
}
EnableObType(*IoFileObjectType);

结果:

Win7 64

Win8 64

Win64 驱动内核编程-14.回调监控文件相关推荐

  1. Win64 驱动内核编程-12.回调监控进线程创建和退出

    回调监控进线程创建和退出 两个注册回调的函数:PsSetCreateProcessNotifyRoutine   进程回调PsSetCreateThreadNotifyRoutine    线程回调分 ...

  2. Win64 驱动内核编程-15.回调监控注册表

    回调监控注册表 在 WIN32 平台上,监控注册表的手段通常是 SSDT HOOK.不过用 SSDT HOOK 的方式监控注册表实在是太麻烦了,要 HOOK 一大堆函数,还要处理一些 NT6 系统有而 ...

  3. Win64 驱动内核编程-11.回调监控进线程句柄操作

    无HOOK监控进线程句柄操作 在 NT5 平台下,要监控进线程句柄的操作. 通常要挂钩三个API:NtOpenProcess.NtOpenThread.NtDuplicateObject.但是在 VI ...

  4. Win64 驱动内核编程-13.回调监控模块加载

    回调监控模块加载 模块加载包括用户层模块(.DLL)和内核模块(.SYS)的加载.传统方法要监控这两者加在必须 HOOK 好几个函数,比如 NtCreateSection 和 NtLoadDriver ...

  5. Win64 驱动内核编程-18.SSDT

    SSDT 学习资料:http://blog.csdn.net/zfdyq0/article/details/26515019 学习资料:WIN64内核编程基础 胡文亮 SSDT(系统服务描述表),刚开 ...

  6. Win64 驱动内核编程-17. MINIFILTER(文件保护)

     MINIFILTER(文件保护) 使用 HOOK 来监控文件操作的方法有很多,可以在 SSDT 上 HOOK 一堆和 FILE 有关的函数,也可以对 FSD 进行 IRP HOOK,不过这些方法既不 ...

  7. Win64 驱动内核编程-3.内核里使用内存

    内核里使用内存 内存使用,无非就是申请.复制.设置.释放.在 C 语言里,它们对应的函数是:malloc.memcpy.memset.free:在内核编程里,他们分别对应 ExAllocatePool ...

  8. Win64 驱动内核编程-2.基本框架(安装.通讯.HelloWorld)

    驱动安装,通讯,Hello World 开发驱动的简单流程是这样,开发驱动安装程序,开发驱动程序,然后安装程序(或者其他程序)通过通讯给驱动传命令,驱动接到之后进行解析并且执行,然后把执行结果返回. ...

  9. Win64 驱动内核编程-8.内核里的其他常用

    内核里的其他常用 1.遍历链表.内核里有很多数据结构,但它们并不是孤立的,内核使用双向链表把它们像糖 葫芦一样给串了起来.所以遍历双向链表能获得很多重要的内核数据.举个简单的例子,驱 动对象 Driv ...

最新文章

  1. 将特定像素点在图像上连接起来_(NeurIPS 2019) Gated CRF Loss-一种用于弱监督图像语义分割的新型损失函数...
  2. SQL2000 统计每周,每月,每季,每年的数据
  3. 高并发网络编程之epoll(个人遇到最好理解的一篇文章、易懂)
  4. python条件控制语句要注意什么_浅析Python 条件控制语句
  5. Oracle 20c 新特性:SQL 宏支持(SQL Macro)Scalar 和 Table 模式
  6. 【Cocos2D-X 】初窥门径(9)播放音乐/音效
  7. 敏捷开发用户故事系列之三:用户建模
  8. thinkpad 使用技巧
  9. 局网满猿关不住,一波码农出墙来。
  10. ElasticSearch 插件开发
  11. 实现加载页Loading Page 的几种方法
  12. 人力资源SaaS“一哥”,二十年艰难进化
  13. 基于Springboot+Vue+ElementUI物流配送管理系统
  14. 中科院计算所培训中心新一期javascript培训结束
  15. 大厂面试必问!疯狂Java讲义第五版pdf在线阅读
  16. Fedora core 5.0加载ntfs分区(yum方法)
  17. 六年如逆旅,我亦是行人
  18. 在VMWare虚拟机上安装Kali linux系统的完整过程(图文)
  19. java怎么创建jsp文件怎么打开_Eclipse中怎么创建jsp文件?
  20. 【随笔】在CSDN的第一年,你好,桐小白~ —— 在CSDN的一岁生日

热门文章

  1. 115天 起飞ing
  2. display vs visibility
  3. legend3---阿里云如何多个域名指向同一个网站
  4. flask 连接数据库
  5. jquery下拉分页
  6. 在线引入bootstrap包
  7. Win7命令终端基础配色指南
  8. iOS证书申请详细流程
  9. ConfigUtil读取配置文件
  10. 登陆sqlserver及修改端口号