object hook

object是什么东西?光从名字上面不难看出,对象。这篇是关于内核对象的hook,为什么要hook他呢,额,这个嘛。因人而异。

看雪上面有很详细的说明,本菜鸟算是抄袭过来而已。版权归看雪所有。

objectHook简单介绍


windbg截图为XP SP3系统。


_OBJECT_HEADER结构:


typedef struct _OBJECT_HEADER {
    LONG_PTR PointerCount;
    union {
        LONG_PTR HandleCount;
        PVOID NextToFree;
    };
    POBJECT_TYPE Type; //hook就靠它了。(对象类型结构,也是一个对象,他是系统第一个创建出来的对象类型!)
    UCHAR NameInfoOffset;//OBJECT_HEADER_NAME_INFO 的偏移
    UCHAR HandleInfoOffset;//OBJECT_HEADER_HANDLE_INFO 的偏移
    UCHAR QuotaInfoOffset;
    UCHAR Flags;

    union {
        POBJECT_CREATE_INFORMATION ObjectCreateInfo;
        PVOID QuotaBlockCharged;
    };
    PSECURITY_DESCRIPTOR SecurityDescriptor;
    QUAD Body; //对象他本身
} OBJECT_HEADER, *POBJECT_HEADER;



_OBJECT_TYPE对象类型)结构:


typedef struct _OBJECT_TYPE {
    ERESOURCE Mutex;
    LIST_ENTRY TypeList;
    UNICODE_STRING Name;            // Copy from object header for convenience
    PVOID DefaultObject;
    ULONG Index;
    ULONG TotalNumberOfObjects;
    ULONG TotalNumberOfHandles;
    ULONG HighWaterNumberOfObjects;
    ULONG HighWaterNumberOfHandles;
    OBJECT_TYPE_INITIALIZERTypeInfo;
#ifdef POOL_TAGGING
    ULONG Key;
#endif //POOL_TAGGING
    ERESOURCE ObjectLocks[ OBJECT_LOCK_COUNT ];
} OBJECT_TYPE, *POBJECT_TYPE;


对象类型结构主要是创建对象类型,比如*IoFileObjectType, *PsProcessType, *PsThreadType 这些。

系统初始化的时候第一个创建的对象类型结构就是TYPE结构,生成对象目录\ObjectTypes 其后面的对象类型直接挂在这个目录上

比如对象类型 \ObjectTypes\File 或者设备类型 \ObjectTypes\Device



最重要的一个结构 OBJECT_TYPE_INITIALIZER


typedef struct _OBJECT_TYPE_INITIALIZER {
    USHORT Length;
    BOOLEAN UseDefaultObject;
    BOOLEAN CaseInsensitive;
    ULONG InvalidAttributes;
    GENERIC_MAPPING GenericMapping;
    ULONG ValidAccessMask;
    BOOLEAN SecurityRequired;
    BOOLEAN MaintainHandleCount;
    BOOLEAN MaintainTypeList;
    POOL_TYPE PoolType;
    ULONG DefaultPagedPoolCharge;
    ULONG DefaultNonPagedPoolCharge;
    PVOID DumpProcedure;这几个函数决定对象的一些操作
    PVOID OpenProcedure; 例如 打开 创建 删除 
    PVOID CloseProcedure; 不同对象类型(OBJECT_TYPE)的操作也不同
    PVOID DeleteProcedure; 所以要清楚知道对象是什么类型
    PVOID ParseProcedure; 如果没有匹配系统调用的对象类型,都是NtOpenFile
    PVOID SecurityProcedure;
    OB_QUERYNAME_METHOD QueryNameProcedure;
    OB_OKAYTOCLOSE_METHOD OkayToCloseProcedure;

} OBJECT_TYPE_INITIALIZER, *POBJECT_TYPE_INITIALIZER;


这些方法何时被调用呢,我举个例子
当你调用NtCreateFile->IoCreateFile->ObOpenObjectByName->ObpLookupObjectName->IopParseFile->IopParseDevice
IopParseFile最终也会调用IopParseDevice
ObjectHook其实就是比如你要HOOK 创建打开  就是 OBJECT_TYPE_INITIALIZER->ParseProcedure


看具体代码:

POBJECT_TYPE   pType = NULL;
POBJECT_HEADER addrs =NULL;
PVOID          OldParseProcedure = NULL;

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;
     KdPrint(("object is hook\n"));
 
  __asm
  {
      push eax
      push Object
      push SecurityQos
      push Context
      push RemainingName
      push CompleteName
      push Attributes
      movzx eax, AccessMode
      push eax
      push AccessState
      push ObjectType
      push ParseObject
      call OldParseProcedure
      mov Status, eax
      pop eax
  } 
  return Status;

}
NTSTATUS Hook()
{
  NTSTATUS  Status;
  HANDLE hFile;
  UNICODE_STRING Name;
  OBJECT_ATTRIBUTES Attr;
  IO_STATUS_BLOCK ioStaBlock;
  PVOID pObject = NULL;
  
  
  RtlInitUnicodeString(&Name,L"\\Device\\HarddiskVolume1\\1.txt");
  InitializeObjectAttributes(&Attr,&Name,OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE ,\
    0,NULL);
  Status = ZwOpenFile(&hFile,GENERIC_ALL,&Attr,&ioStaBlock,\
    0,FILE_NON_DIRECTORY_FILE);
  if (!NT_SUCCESS(Status))
  {
    KdPrint(("File is Null\n"));
    return Status;
  }
 
  Status = ObReferenceObjectByHandle(hFile,GENERIC_ALL,NULL,KernelMode,&pObject,NULL);
  if (!NT_SUCCESS(Status))
  {
    KdPrint(("Object is Null\n"));
    return Status;
  }
 
 KdPrint(("pobject is %08X\n",pObject));

 addrs=OBJECT_TO_OBJECT_HEADER(pObject);//获取对象头


pType=addrs->Type;//获取对象类型结构 object-10h

KdPrint(("pType is %08X\n",pType));
OldParseProcedure = pType->TypeInfo.ParseProcedure;//获取服务函数原始地址OBJECT_TYPE+9C位置为打开
KdPrint(("OldParseProcedure addrs is %08X\n",OldParseProcedure));
KdPrint(("addrs is %08X\n",addrs));
//这里最好检查一下OldParseProcedure ,我真的是太懒了。

pType->TypeInfo.ParseProcedure = NewParseProcedure;//hook 因为object原本就是是可写的,所以不用特意去除内存保护
 Status = ZwClose(hFile);
  return Status;
}

NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath)
{
  NTSTATUS Status = STATUS_SUCCESS;
  Status=Hook();
  return Status;
}


你可能感兴趣的:(windows内核)