自己定义Object Type对抗Object Hook

莫灰灰版主说“Object hook 自己定义Process Type和Thread Type才是王道。 ”
今天咱就来这个。
Windows系统的各种资源以对象(Object)的形式来组织,例如File Object, Driver Object,Device Object等等,但实际上这些所谓的“对象”在系统的对象管理器(Object Manager)看来只是完整对象的一个部分——对象实体(Object Body)。各种Object的共有的信息(例如,对象类型、对象的引用计数、句柄数等信息)保存在OBJECT_HEADER与其他的几个结构中。换而言之,在对象管理器内部,不同类型的对象具有相同的Object Header,但Object Body部分却是不同的。

  一个对象由三部分组成,在Object Header之前是一段变长的区域,由四个独立的结构体组成:
代码:
typedef struct _OBJECT_HEADER_QUOTA_INFO {
  ULONG PagedPoolCharge;
  ULONG NonPagedPoolCharge;
  ULONG SecurityDescriptorCharge;
  PEPROCESS ExclusiveProcess;
  #ifdef _WIN64
  ULONG64 Reserved; // Win64 requires these structures to be 16 byte aligned.
  #endif
  } OBJECT_HEADER_QUOTA_INFO, *POBJECT_HEADER_QUOTA_INFO;
  typedef struct _OBJECT_HEADER_HANDLE_INFO {
  union {
  POBJECT_HANDLE_COUNT_DATABASE HandleCountDataBase;
  OBJECT_HANDLE_COUNT_ENTRY SingleEntry;
  };
  } OBJECT_HEADER_HANDLE_INFO, *POBJECT_HEADER_HANDLE_INFO;
  // begin_ntosp
  typedef struct _OBJECT_HEADER_NAME_INFO {
  POBJECT_DIRECTORY Directory;
  UNICODE_STRING Name;
  ULONG QueryReferences;
  #if DBG
  ULONG Reserved2;
  LONG DbgDereferenceCount;
  #ifdef _WIN64
  ULONG64 Reserved3; // Win64 requires these structures to be 16 byte aligned.
  #endif
  #endif
  } OBJECT_HEADER_NAME_INFO, *POBJECT_HEADER_NAME_INFO;
  // end_ntosp
  typedef struct _OBJECT_HEADER_CREATOR_INFO {
  LIST_ENTRY TypeList;
  HANDLE CreatorUniqueProcess;
  USHORT CreatorBackTraceIndex;
  USHORT Reserved;
  } OBJECT_HEADER_CREATOR_INFO, *POBJECT_HEADER_CREATOR_INFO;

一个对象可以包含全部四个结构,也可能只包含其中的某个,因此这段区域是变长的。之后是OBJECT_HEADER结构,NameInfoOffset、HandleInfoOffset、QuotaInfoOffset分别为OBJECT_HEADER到OBJECT_HEADER_NAME_INFO、OBJECT_HEADER_HANDLE_INFO、OBJECT_HEADER_QUOTA_INFO这三个结构的偏移。
看一下OBJECT_HEADER结构的信息:
代码:
kd> dt nt!_object_header 8985d9f0
  nt!_OBJECT_HEADER
  +0x000 PointerCount : 6
  +0x004 HandleCount : 0
  +0x004 NextToFree : (null)
  +0x008 Type : 0x898df3b0 _OBJECT_TYPE
  +0x00c NameInfoOffset : 0x10 ''
  +0x00d HandleInfoOffset : 0 ''
  +0x00e QuotaInfoOffset : 0 ''
  +0x00f Flags : 0x32 '2'
  +0x010 ObjectCreateInfo : 0x00000001 _OBJECT_CREATE_INFORMATION
  +0x010 QuotaBlockCharged : 0x00000001
  +0x014 SecurityDescriptor : 0xe100c843
  +0x018 Body : _QUAD

OBJECT_HEADER的大小为0×18字节,因此Object Body = OBJECT_HEADER + 0×18,但是0×18是个硬编码值,如果OBJECT_HEADER在以后的系统中发生了变化,显然用这个0×18是不可靠的。利用OBJECT_TO_OBJECT_HEADER()传递一个Object Body的地址给它,就可以得到这个对象的OBJECT_HEADER结构。
下面看看_OBJECT_TYPE结构。
代码:
lkd> dt 0x8a5f8e70 _OBJECT_TYPE
nt!_OBJECT_TYPE
   +0x000 Mutex            : _ERESOURCE
   +0x038 TypeList         : _LIST_ENTRY [ 0x8a5f8ea8 - 0x8a5f8ea8 ]
   +0x040 Name             : _UNICODE_STRING "Process"
   +0x048 DefaultObject    : (null)
   +0x04c Index            : 5
   +0x050 TotalNumberOfObjects : 0x4b
   +0x054 TotalNumberOfHandles : 0xca
   +0x058 HighWaterNumberOfObjects : 0x51
   +0x05c HighWaterNumberOfHandles : 0xd3
   +0x060 TypeInfo         : _OBJECT_TYPE_INITIALIZER
   +0x0ac Key              : 0x636f7250
   +0x0b0 ObjectLocks      : [4] _ERESOURCE

继续看一下_OBJECT_TYPE_INITIALIZER结构。
代码:
lkd> dt _OBJECT_TYPE_INITIALIZER 0x8a5f8e70 +60
nt!_OBJECT_TYPE_INITIALIZER
   +0x000 Length           : 0x4c
   +0x002 UseDefaultObject : 0 ''
   +0x003 CaseInsensitive  : 0 ''
   +0x004 InvalidAttributes : 0xb0
   +0x008 GenericMapping   : _GENERIC_MAPPING
   +0x018 ValidAccessMask  : 0x1f0fff
   +0x01c SecurityRequired : 0x1 ''
   +0x01d MaintainHandleCount : 0 ''
   +0x01e MaintainTypeList : 0 ''
   +0x020 PoolType         : 0 ( NonPagedPool )
   +0x024 DefaultPagedPoolCharge : 0x1000
   +0x028 DefaultNonPagedPoolCharge : 0x290
   +0x02c DumpProcedure    : (null)
   +0x030 OpenProcedure    : (null)
   +0x034 CloseProcedure   : (null)
   +0x038 DeleteProcedure  : 0x805d2cdc     void  nt!PspProcessDelete+0
   +0x03c ParseProcedure   : (null)
   +0x040 SecurityProcedure : 0x805f9150     long  nt!SeDefaultObjectMethod+0
   +0x044 QueryNameProcedure : (null)
   +0x048 OkayToCloseProcedure : (null) 

看到OpenProcedure了吧。所以在被hook之前要保存_OBJECT_TYPE结构。
然后替换_OBJECT_TYPE。
留下的就是写代码实现了,请自己动手。除非你不会申请内存,不会拷贝,。。。。。。。
要锻炼动手能力,有问题大家交流。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值