驱动开发:内核监控FileObject文件回调

本篇文章与上一篇文章《驱动开发:内核注册并监控对象回调》所使用的方式是一样的都是使用ObRegisterCallbacks注册回调事件,只不过上一篇博文中LyShark将回调结构体OB_OPERATION_REGISTRATION中的ObjectType填充为了PsProcessTypePsThreadType格式从而实现监控进程与线程,本章我们需要将该结构填充为IoFileObjectType以此来实现对文件的监控,文件过滤驱动不仅仅可以用来监控文件的打开,还可以用它实现对文件的保护,一旦驱动加载则文件是不可被删除和改动的 。
与进程线程回调有少许的不同,文件回调需要开启驱动的TypeInfo.SupportsObjectCallbacks开关,并定义一些微软结构,如下是我们所需要的公开结构体,可在微软官方或WinDBG中获取到最新的,将其保存为lyshark.h方便后期引用 。
// 署名权// right to sign one's name on a piece of work// PowerBy: LyShark// Email: me@lyshark.com#include <ntddk.h>#include <ntstrsafe.h>typedef struct _CALLBACK_ENTRY{ LIST_ENTRY CallbackList; OB_OPERATIONOperations; ULONG Active; PVOID Handle; POBJECT_TYPE ObjectType; POB_PRE_OPERATION_CALLBACKPreOperation; POB_POST_OPERATION_CALLBACK PostOperation; ULONG unknown;} CALLBACK_ENTRY, *PCALLBACK_ENTRY;typedef struct _LDR_DATA// 24 elements, 0xE0 bytes (sizeof){ /*0x000*/struct _LIST_ENTRY InLoadOrderLinks;// 2 elements, 0x10 bytes (sizeof) /*0x010*/struct _LIST_ENTRY InMemoryOrderLinks;// 2 elements, 0x10 bytes (sizeof) /*0x020*/struct _LIST_ENTRY InInitializationOrderLinks;// 2 elements, 0x10 bytes (sizeof) /*0x030*/VOID*DllBase; /*0x038*/VOID*EntryPoint; /*0x040*/ULONG32SizeOfImage; /*0x044*/UINT8_PADDING0_[0x4]; /*0x048*/struct _UNICODE_STRING FullDllName;// 3 elements, 0x10 bytes (sizeof) /*0x058*/struct _UNICODE_STRING BaseDllName;// 3 elements, 0x10 bytes (sizeof) /*0x068*/ULONG32Flags; /*0x06C*/UINT16LoadCount; /*0x06E*/UINT16TlsIndex; union// 2 elements, 0x10 bytes (sizeof) {/*0x070*/struct _LIST_ENTRY HashLinks;// 2 elements, 0x10 bytes (sizeof)struct// 2 elements, 0x10 bytes (sizeof){/*0x070*/VOID*SectionPointer;/*0x078*/ULONG32CheckSum;/*0x07C*/UINT8_PADDING1_[0x4];}; }; union// 2 elements, 0x8 bytes (sizeof) {/*0x080*/ULONG32TimeDateStamp;/*0x080*/VOID*LoadedImports; }; /*0x088*/struct _ACTIVATION_CONTEXT* EntryPointActivationContext; /*0x090*/VOID*PatchInformation; /*0x098*/struct _LIST_ENTRY ForwarderLinks;// 2 elements, 0x10 bytes (sizeof) /*0x0A8*/struct _LIST_ENTRY ServiceTagLinks;// 2 elements, 0x10 bytes (sizeof) /*0x0B8*/struct _LIST_ENTRY StaticLinks;// 2 elements, 0x10 bytes (sizeof) /*0x0C8*/VOID*ContextInformation; /*0x0D0*/UINT64OriginalBase; /*0x0D8*/union _LARGE_INTEGER LoadTime;// 4 elements, 0x8 bytes (sizeof)}LDR_DATA, *PLDR_DATA;typedef struct _OBJECT_TYPE_INITIALIZER// 25 elements, 0x70 bytes (sizeof){ /*0x000*/UINT16Length; union// 2 elements, 0x1 bytes (sizeof) {/*0x002*/UINT8ObjectTypeFlags;struct// 7 elements, 0x1 bytes (sizeof){/*0x002*/UINT8CaseInsensitive : 1;// 0 BitPosition/*0x002*/UINT8UnnamedObjectsOnly : 1;// 1 BitPosition/*0x002*/UINT8UseDefaultObject : 1;// 2 BitPosition/*0x002*/UINT8SecurityRequired : 1;// 3 BitPosition/*0x002*/UINT8MaintainHandleCount : 1;// 4 BitPosition/*0x002*/UINT8MaintainTypeList : 1;// 5 BitPosition/*0x002*/UINT8SupportsObjectCallbacks : 1;// 6 BitPosition}; }; /*0x004*/ULONG32ObjectTypeCode; /*0x008*/ULONG32InvalidAttributes; /*0x00C*/struct _GENERIC_MAPPING GenericMapping;// 4 elements, 0x10 bytes (sizeof) /*0x01C*/ULONG32ValidAccessMask; /*0x020*/ULONG32RetainAccess; /*0x024*/enum _POOL_TYPE PoolType; /*0x028*/ULONG32DefaultPagedPoolCharge; /*0x02C*/ULONG32DefaultNonPagedPoolCharge; /*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*/UINT64Locked : 1;// 0 BitPosition/*0x000*/UINT64Waiting : 1;// 1 BitPosition/*0x000*/UINT64Waking : 1;// 2 BitPosition/*0x000*/UINT64MultipleShared : 1; // 3 BitPosition/*0x000*/UINT64Shared : 60;// 4 BitPosition};/*0x000*/UINT64Value;/*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*/UINT8Index; /*0x029*/UINT8_PADDING0_[0x3]; /*0x02C*/ULONG32TotalNumberOfObjects; /*0x030*/ULONG32TotalNumberOfHandles; /*0x034*/ULONG32HighWaterNumberOfObjects; /*0x038*/ULONG32HighWaterNumberOfHandles; /*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*/ULONG32Key; /*0x0BC*/UINT8_PADDING2_[0x4]; /*0x0C0*/struct _LIST_ENTRY CallbackList;// 2 elements, 0x10 bytes (sizeof)}MY_OBJECT_TYPE, *PMY_OBJECT_TYPE;

经验总结扩展阅读