首页
社区
课程
招聘
[原创]OBJECT_METHOD初窥
发表于: 2013-8-1 02:08 16775

[原创]OBJECT_METHOD初窥

2013-8-1 02:08
16775

写在开头:
前些日子突然对Object Hook的兴趣大增,同时发现坛子里分析内核对象机制的文章非常少,这里就当抛砖引玉吧。期待能系统分析Windows 内核的对象机制的文章

一、        背景:Windows NT 的对象机制

Windows NT系统将各种资源以对象的方式进行组织和管理。虽然Windows NT内核使用C语言和汇编语言编写的,本身并未使用到C++中的面向对象机制。但依然通过抽象化的对象概念来对各类资源进行管理。

        对象分为对象头和对象体两部分,对象头又分为标准的对象头和可选头部,后者这里不介绍。标准头部的定义如下:

typedef struct _OBJECT_HEADER {
    LONG_PTR PointerCount;
    union {
        LONG_PTR HandleCount;
        PVOID NextToFree;
    };
    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_HEADE
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_INITIALIZER TypeInfo;
#ifdef POOL_TAGGING
    ULONG Key;
#endif //POOL_TAGGING
    ERESOURCE ObjectLocks[ OBJECT_LOCK_COUNT ];
} OBJECT_TYPE, *POBJECT_TYPE;
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;
    OB_DUMP_METHOD DumpProcedure;
    OB_OPEN_METHOD OpenProcedure;
    OB_CLOSE_METHOD CloseProcedure;
    OB_DELETE_METHOD DeleteProcedure;
    OB_PARSE_METHOD ParseProcedure;
    OB_SECURITY_METHOD SecurityProcedure;
    OB_QUERYNAME_METHOD QueryNameProcedure;
    OB_OKAYTOCLOSE_METHOD OkayToCloseProcedure;
} OBJECT_TYPE_INITIALIZER, *POBJECT_TYPE_INITIALIZER;
0: kd> dt_OBJECT_HEADER 0x8ad84708
nt!_OBJECT_HEADER
   +0x000 PointerCount     : 0n108
   +0x004 HandleCount      : 0n4
   +0x004 NextToFree       : 0x00000004 Void
   +0x008 Type             : 0x8af7cca0 _OBJECT_TYPE
   +0x00c NameInfoOffset   : 0 ''
   +0x00d HandleInfoOffset : 0 ''
   +0x00e QuotaInfoOffset  : 0 ''
   +0x00f Flags            : 0x20 ' '
   +0x010 ObjectCreateInfo : 0x8a5a7008 _OBJECT_CREATE_INFORMATION
   +0x010 QuotaBlockCharged : 0x8a5a7008 Void
   +0x014 SecurityDescriptor : 0xe16cd8c5 Void
   +0x018 Body             : _QUAD
0: kd> dt_OBJECT_TYPE 0x8af7cca0
nt!_OBJECT_TYPE
   +0x000 Mutex            : _ERESOURCE
   +0x038 TypeList         : _LIST_ENTRY [ 0x8af7ccd8 - 0x8af7ccd8 ]
   +0x040 Name             : _UNICODE_STRING "Process"
   +0x048 DefaultObject    : (null) 
   +0x04c Index            : 5
   +0x050 TotalNumberOfObjects : 0x1c
   +0x054 TotalNumberOfHandles : 0x7d
   +0x058 HighWaterNumberOfObjects : 0x20
   +0x05c HighWaterNumberOfHandles : 0x82
   +0x060 TypeInfo         : _OBJECT_TYPE_INITIALIZER
   +0x0ac Key              : 0x636f7250
   +0x0b0 ObjectLocks      : [4] _ERESOURCE
0: kd> dt _OBJECT_TYPE_INITIALIZER 0x8af7cd00
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 : 0x2a8
   +0x02c DumpProcedure    : (null) 
   +0x030 OpenProcedure    : (null) 
   +0x034 CloseProcedure   : (null) 
   +0x038 DeleteProcedure  : 0x80932460     void  nt!PspProcessDelete+0
   +0x03c ParseProcedure   : (null) 
   +0x040 SecurityProcedure : 0x8091ce64     long  nt!SeDefaultObjectMethod+0
   +0x044 QueryNameProcedure : (null) 
   +0x048 OkayToCloseProcedure : (null)
0: kd> ba r4 0x8af7cd30
0: kd> ba r4 0x8af7cd40

3: kd> bl
 0 e 8af7cd30 r 4 0001 (0001) 
 1 e 8af7cd40 r 4 0001 (0001)

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 5
支持
分享
最新回复 (16)
雪    币: 110
活跃值: (34)
能力值: (RANK:50 )
在线值:
发帖
回帖
粉丝
2
补充:所有代码来自WRK1.2
环境:Windows Server 2003 (Windows NT 5.2.3800WRK)32bit
2013-8-1 02:09
0
雪    币: 219
活跃值: (773)
能力值: (RANK:290 )
在线值:
发帖
回帖
粉丝
3
~~~~~~~~~~~~~~顶~~~~~~~~~~~~~~~~~~
2013-8-1 02:21
0
雪    币: 167
活跃值: (190)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
4
目前我也只能参照现有的源码 HOOK下解析过程例程  
至于自己造OBJETPYE替换怎么弄不清楚   
造会造了  index也多出来了  删也能删了
就是一替换就蓝。。。
没办法我用最2的办法
初始化全部copy原来的,造个objecttype
我靠 不蓝了
卡死了 我艹
2013-8-1 04:03
0
雪    币: 257
活跃值: (67)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
5
LZ讲解得很详细...
不过某些程序的行为已经留下了一丝蛛丝马迹
这些行为证明了要HOOK OBJECT,可以完全不用改任何OBJECT_METHOD...
甚至隐藏得相当深,而且完全无kernel patch...
2013-8-1 04:06
0
雪    币: 371
活跃值: (72)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
6
必须支持~~~~~~
论坛object文章讲得详细的比较少.......
2013-8-1 08:29
0
雪    币: 1140
活跃值: (3166)
能力值: ( LV12,RANK:385 )
在线值:
发帖
回帖
粉丝
7
学习了。
讲的不错。
2013-8-1 09:11
0
雪    币: 110
活跃值: (34)
能力值: (RANK:50 )
在线值:
发帖
回帖
粉丝
8
搞清楚原理后自己写比参照别人的好使
2013-8-1 10:28
0
雪    币: 167
活跃值: (190)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
9
我只想知道为什么不能直接替换结构  替换里面的几个函数怎么pass保护
2013-8-1 11:30
0
雪    币: 41
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
  看不懂
2013-8-1 13:55
0
雪    币: 110
活跃值: (34)
能力值: (RANK:50 )
在线值:
发帖
回帖
粉丝
11
替换POBJECT_TYPE Type,然后检查一下编译时生成的asm文件看看结构对不对
2013-8-1 18:22
0
雪    币: 46
活跃值: (14)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
技术这东西 蒙在鼓里的时候 怎么也穿不破那张皮
有人给你一下捅破 你也很轻松了
2013-8-4 15:44
0
雪    币: 10
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
很基礎的Windows核心知識,不過總結下的有點突兀,
一般軟體開發工程也是不建議從這裡去找solution,
但用來了解整個object與object method是個不錯的開始
2013-8-5 22:09
0
雪    币: 110
活跃值: (34)
能力值: (RANK:50 )
在线值:
发帖
回帖
粉丝
14
看这位一定是大神了,那么请明示solution的"典型"方法

至于这个结论就当抛砖引玉了,期待更多例子和关于实用性和稳定性的分析
2013-8-6 00:06
0
雪    币: 680
活跃值: (68)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
15
学习之,没太看懂
2013-8-6 11:46
0
雪    币: 10
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
(非官方回答)
幾年前還在做內核的時候有機會去MS總部找工程師聊天,
問到類似檢查object method的有效性問題,
他原本盯著螢幕,突然轉過來瞪大眼睛看著我,
"你覺得那樣系統不會受影響嗎?"
"會變慢?"
"你感覺的到的那種"
"那安全性?"
"it's all about trade-off"

我在想當時的電腦的確是不快,他們真的很計較那多出來的幾行指令

要做solution在object method當然是可以,
但是相容性跟穩定性就要靠qa/tester努力點,
好幾年沒寫內核的程式了,當時如果要加東西在object method上,
就得傷腦筋race condition的問題,有些object在創建的時候還拿不到一些資料,
最後只能說做產品的話,還是走MS建議的方法會少走些冤枉路,
譬如說object filtering,雖然爛但至少很多地方不用RD自己摸,
如果是寫rootkit就衝吧,反正沒什麼損失

至於結論有些突兀指的是看得正入戲就進結論了,本來以為還有下文 :)
帶了快十次的Windows Internals,幾乎大部份人都在object跟object method上傷腦筋,
這篇是蠻值得推薦的
2013-8-8 03:39
0
雪    币: 110
活跃值: (34)
能力值: (RANK:50 )
在线值:
发帖
回帖
粉丝
17
这个,俺的表述水平确实不高哈
2013-8-11 17:55
0
游客
登录 | 注册 方可回帖
返回
//