对进程句柄表的认识

17人阅读 评论(0) 收藏 举报

首先是句柄表结构,在_EPROCESS结构的的Object_Table域(一个指向_HANDLE_TABLE结构的指针),

lkd> DT _HANDLE_TABLE
nt!_HANDLE_TABLE
   +0x000 TableCode        : Uint4B                                //指向句柄表存储结构
   +0x004 QuotaProcess     : Ptr32 _EPROCESS
   +0x008 UniqueProcessId  : Ptr32 Void                            //PID
   +0x00c HandleLock       : _EX_PUSH_LOCK
   +0x010 HandleTableList  : _LIST_ENTRY                           //所有的句柄表形成的一个链表,链表头为全局HandleTableListHead
   +0x018 HandleContentionEvent : _EX_PUSH_LOCK
   +0x01c DebugInfo        : Ptr32 _HANDLE_TRACE_DEBUG_INFO
   +0x020 ExtraInfoPages   : Int4B
   +0x024 Flags            : Uint4B
   +0x024 StrictFIFO       : Pos 0, 1 Bit
   +0x028 FirstFreeHandle  : Uint4B                                 //空闲链表的表头句柄索引
   +0x02c LastFreeHandleEntry : Ptr32 _HANDLE_TABLE_ENTRY
   +0x030 HandleCount      : Uint4B        
   +0x034 NextHandleNeedingPool : Uint4B                            //下一个空闲链表的表头空闲索引
   +0x038 HandleCountHighWatermark : Uint4B
_HANDLE_TABLE的第一个成员TableCode,它是指向句柄表的储存结构


一,查看只有单层句柄表的程序

这里通过自己写的一个Test程序显示CreateFile来打开的句柄值。

通过Windbg查看这个_EPROCESS结构:

lkd> !PROCESS 6B0 0
Searching for Process with Cid == 6b0
Cid handle table at 97801000 with 600 entries in use

PROCESS 86d18030  SessionId: 1  Cid: 06b0    Peb: 7ffdc000  ParentCid: 07c4
    DirBase: be8335a0  ObjectTable: a88abbb8  HandleCount:  37.
    Image: test.exe

可以看到ObjectTable地址为a88abbb8,指向一个_HANDLE_TABLE的结构,再通过windbg查看这个地址的_HANDLE_TABLE

lkd> dt _handle_table a88abbb8
nt!_HANDLE_TABLE
   +0x000 TableCode        : 0xada1c000
   +0x004 QuotaProcess     : 0x86d18030 _EPROCESS
   +0x008 UniqueProcessId  : 0x000006b0 Void
   +0x00c HandleLock       : _EX_PUSH_LOCK
   +0x010 HandleTableList  : _LIST_ENTRY [ 0xada0e180 - 0xa6be53a8 ]
   +0x018 HandleContentionEvent : _EX_PUSH_LOCK
   +0x01c DebugInfo        : (null) 
   +0x020 ExtraInfoPages   : 0n0
   +0x024 Flags            : 0
   +0x024 StrictFIFO       : 0y0
   +0x028 FirstFreeHandle  : 0x64
   +0x02c LastFreeHandleEntry : 0xada1cff8 _HANDLE_TABLE_ENTRY
   +0x030 HandleCount      : 0x25
   +0x034 NextHandleNeedingPool : 0x800
   +0x038 HandleCountHighWatermark : 0x29

可以看到TbaleCode最低两位为0,说明为单层句柄表,那么windbg打印这个0xada1c000地址的值看看

lkd> dd 0xada1c000
ada1c000  00000000 fffffffe 8d4dc029 00000003
ada1c010  86bb7771 00100020 86d86ac9 001f0003
ada1c020  a88b9419 00020019 86cd6a61 001f0001
ada1c030  86da57d1 001f0001 86e03579 001f0001
ada1c040  ada18cc9 000f003f 86dd82e9 001f0003
ada1c050  aa9e0571 00000001 86dc26d9 00000804
ada1c060  86d4e109 021f0003 8847e571 000f037f
ada1c070  884baf61 000f01ff 8847e571 000f037f

TableCode每项8个字节,都是一个_HANDLE_TABLE_ENTRY结构,第一句柄表项表示该页面的审计掩码,从第二项开始就是有效的句柄项了。这里我这个Test程序打开的文件的句柄为0x48,也就是TbaleCode + 0x48 / 4 * 8偏移处(因为句柄表第一项索引为4,第二项为8。。。以此类推,而每一项又是8个字节的_HANDLE_TABLE_ENTRY结构),那么用windbg查看这个句柄表项:

lkd> dt _HANDLE_TABLE_ENTRY ada1c000+0x48/4*8
nt!_HANDLE_TABLE_ENTRY
   +0x000 Object           : 0x86cbcef9 Void
   +0x000 ObAttributes     : 0x86cbcef9
   +0x000 InfoTable        : 0x86cbcef9 _HANDLE_TABLE_ENTRY_INFO
   +0x000 Value            : 0x86cbcef9
   +0x004 GrantedAccess    : 0x120089
   +0x004 GrantedAccessIndex : 0x89
   +0x006 CreatorBackTraceIndex : 0x12
   +0x004 NextFreeTableEntry : 0x120089

这里_HANDLE_TABLE_ENTRY也就是两个union组成,Object指针指向句柄所代表的内核对象,它的最低三位又特殊含义:

第0位OBJ_PROTECT_CLOSE表示调用者能否关闭这个句柄,第一位OBJ_INHERIT表示进程的子进程能否继承这个句柄,就是能否拷贝到子进程的句柄表中,第二位OBJ_AUDIT_OBJECT_CLOSE,指示关闭这个对象是否会产生一个审计对象。这里的Object为 86cbcef9 ,它只有最低位是1,所以要查看这个句柄所指向的对象的话就要将第三位变为0才能表示指向的一个对象,这里就改成 86CBCEF8 ,这个地址就是一个对象地址,用windbg查看

lkd> dt _object_header 86CBCEF8 
nt!_OBJECT_HEADER
   +0x000 PointerCount     : 0n1
   +0x004 HandleCount      : 0n1
   +0x004 NextToFree       : 0x00000001 Void
   +0x008 Lock             : _EX_PUSH_LOCK
   +0x00c TypeIndex        : 0x1c ''
   +0x00d TraceFlags       : 0 ''
   +0x00e InfoMask         : 0xc ''
   +0x00f Flags            : 0x40 '@'
   +0x010 ObjectCreateInfo : 0x887c7640 _OBJECT_CREATE_INFORMATION
   +0x010 QuotaBlockCharged : 0x887c7640 Void
   +0x014 SecurityDescriptor : (null) 
   +0x018 Body             : _QUAD

看到TypeIndex为0x1c,对应着看下在ObTypeIndexTable这个全局对象类型表中的0x1c项,

lkd> dt _object_type poi(ObTypeIndexTable+0x1C*4)  
nt!_OBJECT_TYPE
   +0x000 TypeList         : _LIST_ENTRY [ 0x86813c58 - 0x86813c58 ]
   +0x008 Name             : _UNICODE_STRING "File"
   +0x010 DefaultObject    : 0x0000005c Void
   +0x014 Index            : 0x1c ''
   +0x018 TotalNumberOfObjects : 0x1773
   +0x01c TotalNumberOfHandles : 0x3e1
   +0x020 HighWaterNumberOfObjects : 0x1ee6
   +0x024 HighWaterNumberOfHandles : 0x4f1
   +0x028 TypeInfo         : _OBJECT_TYPE_INITIALIZER
   +0x078 TypeLock         : _EX_PUSH_LOCK
   +0x07c Key              : 0x656c6946
   +0x080 CallbackList     : _LIST_ENTRY [ 0x86813cd8 - 0x86813cd8 ]

可以看到正是对应着File对象,我们再看下打开的对象路径名等信息。

lkd> !object 86CBCEF8+0x18
Object: 86cbcf10  Type: (86813c58) File
    ObjectHeader: 86cbcef8 (new version)
    HandleCount: 1  PointerCount: 1
    Directory Object: 00000000  Name: \Users\Administrator\Desktop\TestHook.vmp.exe {HarddiskVolume1}

OK,Right!

二,查看查有高层句柄表的程序

这里就查看system(PID = 4)进程,

lkd> !process 4 0
Searching for Process with Cid == 4
Cid handle table at 97801000 with 639 entries in use

PROCESS 867d48a8  SessionId: none  Cid: 0004    Peb: 00000000  ParentCid: 0000
    DirBase: 00185000  ObjectTable: 8d401b28  HandleCount: 502.
    Image: System
lkd> dt _handle_table 8d401b28  
ntdll!_HANDLE_TABLE
   +0x000 TableCode        : 0xa5f0b001
   +0x004 QuotaProcess     : (null) 
   +0x008 UniqueProcessId  : 0x00000004 Void
   +0x00c HandleLock       : _EX_PUSH_LOCK
   +0x010 HandleTableList  : _LIST_ENTRY [ 0x8fa40418 - 0x8413f768 ]
   +0x018 HandleContentionEvent : _EX_PUSH_LOCK
   +0x01c DebugInfo        : (null) 
   +0x020 ExtraInfoPages   : 0n0
   +0x024 Flags            : 0
   +0x024 StrictFIFO       : 0y0
   +0x028 FirstFreeHandle  : 0x9a4
   +0x02c LastFreeHandleEntry : 0xa5f08ff8 _HANDLE_TABLE_ENTRY
   +0x030 HandleCount      : 0x1f5
   +0x034 NextHandleNeedingPool : 0x1000
   +0x038 HandleCountHighWatermark : 0x282

这里TableCode是0xa5f0b001,低两位为1,说明有两层,我们查看TableCode时候就应该查看0xa5f0b000

lkd> dd a5f0b000
a5f0b000  8d403000 a5f08000 00000000 00000000
a5f0b010  00000000 00000000 00000000 00000000
a5f0b020  00000000 00000000 00000000 00000000
a5f0b030  00000000 00000000 00000000 00000000
a5f0b040  00000000 00000000 00000000 00000000
a5f0b050  00000000 00000000 00000000 00000000
a5f0b060  00000000 00000000 00000000 00000000
a5f0b070  00000000 00000000 00000000 00000000

开头的两个即是两个低层句柄表的地址,这就和之前查看的方法一样了。每一个低层句柄表项是512个,除去第一个还有511个

我们这里查看一个0x68索引的句柄。

lkd> dt _handle_table_entry 8d403000 + 0x68/4*8
ntdll!_HANDLE_TABLE_ENTRY
   +0x000 Object           : 0x867f6ea1 Void
   +0x000 ObAttributes     : 0x867f6ea1
   +0x000 InfoTable        : 0x867f6ea1 _HANDLE_TABLE_ENTRY_INFO
   +0x000 Value            : 0x867f6ea1
   +0x004 GrantedAccess    : 0x2020003
   +0x004 GrantedAccessIndex : 3
   +0x006 CreatorBackTraceIndex : 0x202
   +0x004 NextFreeTableEntry : 0x2020003
这里Object为867F6EA1,让第三位为0,则为867F6EA0,查看一下信息
lkd> dt _object_header 867F6EA0
nt!_OBJECT_HEADER
   +0x000 PointerCount     : 0n1
   +0x004 HandleCount      : 0n1
   +0x004 NextToFree       : 0x00000001 Void
   +0x008 Lock             : _EX_PUSH_LOCK
   +0x00c TypeIndex        : 0x1c ''
   +0x00d TraceFlags       : 0 ''
   +0x00e InfoMask         : 0xc ''
   +0x00f Flags            : 0x42 'B'
   +0x010 ObjectCreateInfo : 0x00000001 _OBJECT_CREATE_INFORMATION
   +0x010 QuotaBlockCharged : 0x00000001 Void
   +0x014 SecurityDescriptor : (null) 
   +0x018 Body             : _QUAD

同样也是0x1c,也就是File类型对象,再看看其他信息是否一样。

lkd> !object 867F6EA0+0x18
Object: 867f6eb8  Type: (86813c58) File
    ObjectHeader: 867f6ea0 (new version)
    HandleCount: 1  PointerCount: 1
    Directory Object: 00000000  Name: \Boot\BCD {HarddiskVolume1}
OK Right!





查看评论

Win8下枚举任意进程的句柄表。。。(VB6 Code)

添加一个Command1、一个List1,代码: Private Type PROCESS_HANDLE_TABLE_ENTRY_INFO HandleValue As Long HandleCou...
  • a1875566250
  • a1875566250
  • 2012-12-26 12:26:52
  • 2084

Windows 进程的句柄表

本文源自《Windows内核原理与实现》第3章Windows 进程和线程 3.4.1 Windows 进程的句柄表(1) 上一章介绍了Windows 内核中的对象管理器,Win...
  • qiaoli278141408
  • qiaoli278141408
  • 2015-03-12 14:49:32
  • 1000

内核PspCidTable句柄表遍历获取隐藏进程

先从WinDBG中来看下PspCidTable. lkd> dd pspcidtable 84196eb4 8ae011c8 00000000 80000018 00000101 84196ec4...
  • hacklaolang
  • hacklaolang
  • 2013-09-23 14:27:38
  • 1293

sql-b表数据插入或更新到a表

yTest01:id,name,grade,age yTest02:id,name,grade,age   insert时: INSERT INTO yTest01 (id, NAME, gr...
  • rommel2171226
  • rommel2171226
  • 2014-03-31 16:59:08
  • 463

不完全遍历Csrss进程中的句柄表

使用ExEnumHandleTable函数来遍历的时候.我在WINDBG观察打印出的句柄. 我发现一个很郁闷的问题.遍历只到19XX的句柄.0x800后的第二.第三张句柄表似乎没有遍历出来. 而我...
  • u012187684
  • u012187684
  • 2014-01-11 20:22:06
  • 721

驱动遍历句柄表

 驱动遍历句柄表附加第二个方法的反汇编代码 其中还有对其拦截的方式的一些需要HOOK处比如伪造句柄表 因为大量使用硬编码所以此份代码通用性不强一切均在虚拟机XP3下操作 #include "...
  • qq_18942885
  • qq_18942885
  • 2015-04-27 15:46:31
  • 1004

枚举进程句柄

目前正在做的项目进行性能测试,被通知进程句柄数已经
  • xbgprogrammer
  • xbgprogrammer
  • 2014-05-20 18:05:56
  • 2533

windows进程句柄表

一.介绍 1.什么是句柄 句柄windows应用程序用来表示资源的一个符号,几乎所有的资源对于应用程序来说都表示为一个句柄。比如文件,用CreateFile打开一个文件,成功则会得到一...
  • rongwenbin
  • rongwenbin
  • 2014-02-24 15:46:13
  • 734

对新课改及其实施的认识

 对新课改及其实施的认识        1、新课程最核心的理念    新课程最核心的理念就是以学生为本。或可诠释为:一切为了学生、为了一切学生、为了学生的一切(包括现在和将来)。在新课改中,什么是正确...
  • cbxjxxx
  • cbxjxxx
  • 2007-06-02 12:08:00
  • 897

初步认识linux与入门

习惯了使用windows以后接触另外一个操作系统似乎不太习惯,考虑到linux众多优越性,首先就说说为什么学习linux。在接触linux之前先来说说我对linux的理解。1. linux完全开源,免...
  • cai2016
  • cai2016
  • 2016-07-10 18:27:47
  • 1019
    个人资料
    持之以恒
    等级:
    访问量: 3584
    积分: 260
    排名: 32万+
    文章分类