object hook实现禁止创建文件
object hook实现禁止创建文件
原理不说了,大伙都懂得..
1. 怎么在windbg中看到_OBJECT_TYPE和_OBJECT_TYPE_INITIALIZER结构的内容。
2. 怎样得到pOldParseProcedure的地址
3. 怎样改写((POBJECT_TYPE)*IoDeviceObjectType)->TypeInfo.ParseProcedure=pNewProcedure
对于第一个问题:
nt!_OBJECT_HEADER
+0x000 PointerCount : Int4B
+0x004 HandleCount : Int4B
+0x004 NextToFree : Ptr32 Void
+0x008 Type : Ptr32 _OBJECT_TYPE
+0x00c NameInfoOffset : UChar
+0x00d HandleInfoOffset : UChar
+0x00e QuotaInfoOffset : UChar
+0x00f Flags : UChar
+0x010 ObjectCreateInfo : Ptr32 _OBJECT_CREATE_INFORMATION
+0x010 QuotaBlockCharged : Ptr32 Void
+0x014 SecurityDescriptor : Ptr32 Void
+0x018 Body : _QUAD
lkd> dt _OBJECT_TYPE
nt!_OBJECT_TYPE
+0x000 Mutex : _ERESOURCE
+0x038 TypeList : _LIST_ENTRY
+0x040 Name : _UNICODE_STRING
+0x048 DefaultObject : Ptr32 Void
+0x04c Index : Uint4B
+0x050 TotalNumberOfObjects : Uint4B
+0x054 TotalNumberOfHandles : Uint4B
+0x058 HighWaterNumberOfObjects : Uint4B
+0x05c HighWaterNumberOfHandles : Uint4B
+0x060 TypeInfo : _OBJECT_TYPE_INITIALIZER
+0x0ac Key : Uint4B
+0x0b0 ObjectLocks : [4] _ERESOURCE
lkd> dt _OBJECT_TYPE_INITIALIZER
nt!_OBJECT_TYPE_INITIALIZER
+0x000 Length : Uint2B
+0x002 UseDefaultObject : UChar
+0x003 CaseInsensitive : UChar
+0x004 InvalidAttributes : Uint4B
+0x008 GenericMapping : _GENERIC_MAPPING
+0x018 ValidAccessMask : Uint4B
+0x01c SecurityRequired : UChar
+0x01d MaintainHandleCount : UChar
+0x01e MaintainTypeList : UChar
+0x020 PoolType : _POOL_TYPE
+0x024 DefaultPagedPoolCharge : Uint4B
+0x028 DefaultNonPagedPoolCharge : Uint4B
+0x02c DumpProcedure : Ptr32 void
+0x030 OpenProcedure : Ptr32 long
+0x034 CloseProcedure : Ptr32 void
+0x038 DeleteProcedure : Ptr32 void
+0x03c ParseProcedure : Ptr32 long
+0x040 SecurityProcedure : Ptr32 long
+0x044 QueryNameProcedure : Ptr32 long
+0x048 OkayToCloseProcedure : Ptr32 unsigned char
对于第二个问题:
2. 怎样得到pOldParseProcedure的地址
1. 打开一个文件得到文件句柄 ZwOpenFile
2. 依据文件句柄得到文件 ObReferenceObjectByHandle得到pObject
3. pObject是_OBJECT_HEADER 结构中Body的数值,如今要得到_OBJECT_HEADER 的地址,用宏CONTAINING_RECORD((o),OBJECT_HEADER,Body)
4. POBJECT_HEADER结构的Type指向了一个OBJECT_TYPE( pType)
4. OldParseProcedure = pType->TypeInfo.ParseProcedure就是要的结果
整理一下结构间的关系:
- #define OBJECT_TO_OBJECT_HEADER(o) CONTAINING_RECORD((o),OBJECT_HEADER,Body)
- POBJECT_HEADER addrs=NULL;
- POBJECT_TYPE pType= NULL;
- addrs=OBJECT_TO_OBJECT_HEADER(pObject);//获取对象头
- pType=addrs->Type;//获取对象类型结构 object-10h
- OldParseProcedure = pType->TypeInfo.ParseProcedure;//获取服务函数原始地址OBJECT_TYPE+9C位置为打开
typedef struct _OBJECT_HEADER {
LONG PointerCount;
union {
LONG HandleCount;
PSINGLE_LIST_ENTRY SEntry;
};
POBJECT_TYPE Type;
UCHAR NameInfoOffset;
UCHAR HandleInfoOffset;
UCHAR QuotaInfoOffset;
UCHAR Flags;
union
{
POBJECT_CREATE_INFORMATION ObjectCreateInfo;
PVOID QuotaBlockCharged;
};
PSECURITY_DESCRIPTOR SecurityDescriptor;
QUAD Body;
} OBJECT_HEADER, *POBJECT_HEADER;
pType的值为0x821ebe70
lkd> dt _object_type 0x821ebe70
nt!_OBJECT_TYPE
+0x000 Mutex : _ERESOURCE
+0x038 TypeList : _LIST_ENTRY [ 0x821ebea8 - 0x821ebea8 ]
+0x040 Name : _UNICODE_STRING "File"
+0x048 DefaultObject : 0x0000005c
+0x04c Index : 0x1c
+0x050 TotalNumberOfObjects : 0xcd6
+0x054 TotalNumberOfHandles : 0x316
+0x058 HighWaterNumberOfObjects : 0xd6e
+0x05c HighWaterNumberOfHandles : 0x3ad
+0x060 TypeInfo : _OBJECT_TYPE_INITIALIZER
+0x0ac Key : 0x656c6946
+0x0b0 ObjectLocks : [4] _ERESOURCE
3. 怎样改写((POBJECT_TYPE)*IoDeviceObjectType)->TypeInfo.ParseProcedure=pNewProcedure
关闭写保护
HOOK
打开写保护
函数定义方法:
NTSTATUS (*oldParseProcedure)(IN PVOID ParseObject,
IN PVOID ObjectType,
IN OUT PACCESS_STATE AccessState,
IN KPROCESSOR_MODE AccessMode,
IN ULONG Attributes,
IN OUT PUNICODE_STRING CompleteName,
IN OUT PUNICODE_STRING RemainingName,
IN OUT PVOID Context OPTIONAL,
IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
OUT PVOID *Object);
此时,就已经HOOK成功了
解决完上面的困难,真正的代码来了
.c
//PVOID oldParseProcedure;//typedef int (*FP_CALC)(int, int);NTSTATUS (*oldParseProcedure)(IN PVOID ParseObject,IN PVOID ObjectType,IN OUT PACCESS_STATE AccessState,IN KPROCESSOR_MODE AccessMode,IN ULONG Attributes,IN OUT PUNICODE_STRING CompleteName,IN OUT PUNICODE_STRING RemainingName,IN OUT PVOID Context OPTIONAL,IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,OUT PVOID *Object);VOID MyObjectHook(){UNICODE_STRING uFileName;OBJECT_ATTRIBUTES ob;NTSTATUS status;HANDLE hFile;IO_STATUS_BLOCK ioStaBlock;PVOID pObject;POBJECT_HEADER addr;POBJECT_TYPE pType;OBJECT_TYPE_INITIALIZER obTypeInit;KIRQL irql;dprintf("enter myObjectHook...\n");DbgBreakPoint();RtlInitUnicodeString(&uFileName,L"\\Device\\HarddiskVolume1\\123.txt");//这个文件必需存在InitializeObjectAttributes(&ob,&uFileName,OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE ,NULL, NULL);status = ZwOpenFile(&hFile,GENERIC_ALL,&ob,&ioStaBlock,0,FILE_NON_DIRECTORY_FILE);if (!NT_SUCCESS(status)){dprintf("ZwOpenFile error..\n");return ;}status = ObReferenceObjectByHandle(hFile,GENERIC_ALL,NULL,KernelMode,&pObject,NULL);if (!NT_SUCCESS(status)){dprintf("ObReferenceObjectByHandle:Object is Null\n");return ;}dprintf("pObject is 0x%08X\n",pObject);addr = OBJECT_TO_OBJECT_HEADER(pObject);dprintf("addr is 0x%08X\n",addr); //这里是pObject-0x18的位置pType = addr->Type;dprintf("pType is 0x%08X\n",pType);//oldParseProcedure = (PVOID)(pType->TypeInfo.ParseProcedure);oldParseProcedure = pType->TypeInfo.ParseProcedure;dprintf("OldParseProcedure addrs is %08X\n",oldParseProcedure);//HOOK 一下下irql = WPOFF();pType->TypeInfo.ParseProcedure = NewParseProcedure;//hookWPON(irql);//关闭句柄ZwClose(hFile);}//OBJECT HOOK 函数NTSTATUS NewParseProcedure(IN PVOID ParseObject,IN PVOID ObjectType,IN OUT PACCESS_STATE AccessState,IN KPROCESSOR_MODE AccessMode,IN ULONG Attributes,IN OUT PUNICODE_STRING CompleteName,IN OUT PUNICODE_STRING RemainingName,IN OUT PVOID Context OPTIONAL,IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,OUT PVOID *Object){NTSTATUS status = STATUS_UNSUCCESSFUL;PVOID namePool;if (RemainingName->Buffer){namePool = ExAllocatePool(NonPagedPool, RemainingName->Buffer+2);RtlZeroMemory(namePool, RemainingName->Buffer+2);if (namePool){RtlCopyMemory(namePool, RemainingName->Buffer,RemainingName->Length);_wcsupr((wchar_t*)namePool);if (wcsstr(namePool, L"TEST.TXT")){ExFreePool(namePool);return STATUS_ACCESS_DENIED;}}}return oldParseProcedure(ParseObject,ObjectType,AccessState,AccessMode,Attributes,CompleteName,RemainingName,Context,SecurityQos,*Object);}
.h
//object hookVOID MyObjectHook();#define OBJECT_TO_OBJECT_HEADER(o)\CONTAINING_RECORD((o),OBJECT_HEADER,Body)typedef struct _OBJECT_HEADER {LONG PointerCount;union {LONG HandleCount;PSINGLE_LIST_ENTRY SEntry;};POBJECT_TYPE Type;UCHAR NameInfoOffset;UCHAR HandleInfoOffset;UCHAR QuotaInfoOffset;UCHAR Flags;union{PVOID ObjectCreateInfo;PVOID QuotaBlockCharged;};PSECURITY_DESCRIPTOR SecurityDescriptor;QUAD Body;} OBJECT_HEADER, *POBJECT_HEADER;NTSTATUS NewParseProcedure(IN PVOID ParseObject,IN PVOID ObjectType,IN OUT PACCESS_STATE AccessState,IN KPROCESSOR_MODE AccessMode,IN ULONG Attributes,IN OUT PUNICODE_STRING CompleteName,IN OUT PUNICODE_STRING RemainingName,IN OUT PVOID Context OPTIONAL,IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,OUT PVOID *Object);

浙公网安备 33010602011771号