Windows进程中的句柄表首先一个进程的句柄表是在内核空间中的用户态下进行调试是无法获取进程的句柄表的。句柄Windows 使用句柄handle来管理进程中的对象引用。当一个进程利用名称来创建或打开一个对象时将获得一个句柄该句柄指向所创建或打开的对象。以后该进程无须使用名称来引用该对象使用此句柄即可访问。这样做可以显著地提高引用对象的效率。因此句柄只是一个对象引用同一个对象在不同的环境下可能有不同的引用句柄值。在 Windows 中句柄是进程范围内的对象引用换句话说句柄仅在一个进程范围内才有效。一个进程中的句柄传递给另一个进程后句柄值将不再有效。实际上Windows支持的句柄是一个索引指向该句柄所在进程的句柄表handle table中的一个表项。EPROCESS 数据结构的 ObjectTable 域指向进程的句柄表。句柄表的第一个索引为 4第二个为 8依此类推。句柄表是一个多层结构。ObjectTable 的类型为HANDLE_TABLE每个句柄项的结构为HANDLE_TABLE_ENTRY。ObjectTable在执行体进程结构体EPROCESS中偏移0x300处有一个名为ObjectTable的成员它的类型是_HANDLE_TABLE它指向了一个进程的句柄表。_HANDLE_TABLE类型TableCode该字段包含了两个信息句柄表最高层表项页面当前句柄表层级最低两位Windows中一页的大小为4KBWindows分配句柄表时按页来申请内存而一个句柄表项_HANDLE_TABLE_ENTRY结构体大小64位系统中为所以每申请一个页面进程中的句柄表的容量增加256。64 位系统指针大小为 8 字节句柄表项通常为 16 字节。此时第一层页面可容纳的指针数 4096 ÷ 8 512个。每个底层页面可容纳的句柄表项数 4096 ÷ 16 256个。两层结构的总容量 512 × 256 131,072个句柄。HandleTableListHandleTableList是 _HANDLE_TABLE结构中的一个 _LIST_ENTRY类型的成员它的作用是将当前进程的句柄表链接到系统全局的句柄表双向链表中。Windows 内核通过这个链表将系统中所有进程的句柄表_HANDLE_TABLE串联起来形成一个双向链表。这类似于 _EPROCESS中的 ActiveProcessLinks链表用于链接所有活动进程。内核或安全软件可以通过遍历这个链表快速获取系统中所有进程的句柄表信息用于资源统计、安全检测或调试。正因为这个链表暴露了所有进程的句柄表一些 rootkit 或进程隐藏技术会尝试修改或卸载链表中的对应节点即“摘链”以逃避检测。因此安全工具也会通过检查此链表的完整性来发现隐藏进程。_HANDLE_TABLE_ENTRY结构体这是句柄表项的类型句柄作为索引访问该类型的数组得到句柄表项进一步解析得到对象。解析句柄到对象这里说的内核句柄表是一个全局的句柄表在WRK中即变量ObpKernelHandleTable也是System进程的句柄表。ObpKernelHandleTable 中的句柄只有在内核模式下才可以被引用但可以位于任何一个进程环境中。所以这些句柄实际上是跨进程环境的。除了手动解析还可以使用一些执行体函数参考wrk或《Windows内核原理与实现》。
Windows进程中的句柄表
Windows进程中的句柄表首先一个进程的句柄表是在内核空间中的用户态下进行调试是无法获取进程的句柄表的。句柄Windows 使用句柄handle来管理进程中的对象引用。当一个进程利用名称来创建或打开一个对象时将获得一个句柄该句柄指向所创建或打开的对象。以后该进程无须使用名称来引用该对象使用此句柄即可访问。这样做可以显著地提高引用对象的效率。因此句柄只是一个对象引用同一个对象在不同的环境下可能有不同的引用句柄值。在 Windows 中句柄是进程范围内的对象引用换句话说句柄仅在一个进程范围内才有效。一个进程中的句柄传递给另一个进程后句柄值将不再有效。实际上Windows支持的句柄是一个索引指向该句柄所在进程的句柄表handle table中的一个表项。EPROCESS 数据结构的 ObjectTable 域指向进程的句柄表。句柄表的第一个索引为 4第二个为 8依此类推。句柄表是一个多层结构。ObjectTable 的类型为HANDLE_TABLE每个句柄项的结构为HANDLE_TABLE_ENTRY。ObjectTable在执行体进程结构体EPROCESS中偏移0x300处有一个名为ObjectTable的成员它的类型是_HANDLE_TABLE它指向了一个进程的句柄表。_HANDLE_TABLE类型TableCode该字段包含了两个信息句柄表最高层表项页面当前句柄表层级最低两位Windows中一页的大小为4KBWindows分配句柄表时按页来申请内存而一个句柄表项_HANDLE_TABLE_ENTRY结构体大小64位系统中为所以每申请一个页面进程中的句柄表的容量增加256。64 位系统指针大小为 8 字节句柄表项通常为 16 字节。此时第一层页面可容纳的指针数 4096 ÷ 8 512个。每个底层页面可容纳的句柄表项数 4096 ÷ 16 256个。两层结构的总容量 512 × 256 131,072个句柄。HandleTableListHandleTableList是 _HANDLE_TABLE结构中的一个 _LIST_ENTRY类型的成员它的作用是将当前进程的句柄表链接到系统全局的句柄表双向链表中。Windows 内核通过这个链表将系统中所有进程的句柄表_HANDLE_TABLE串联起来形成一个双向链表。这类似于 _EPROCESS中的 ActiveProcessLinks链表用于链接所有活动进程。内核或安全软件可以通过遍历这个链表快速获取系统中所有进程的句柄表信息用于资源统计、安全检测或调试。正因为这个链表暴露了所有进程的句柄表一些 rootkit 或进程隐藏技术会尝试修改或卸载链表中的对应节点即“摘链”以逃避检测。因此安全工具也会通过检查此链表的完整性来发现隐藏进程。_HANDLE_TABLE_ENTRY结构体这是句柄表项的类型句柄作为索引访问该类型的数组得到句柄表项进一步解析得到对象。解析句柄到对象这里说的内核句柄表是一个全局的句柄表在WRK中即变量ObpKernelHandleTable也是System进程的句柄表。ObpKernelHandleTable 中的句柄只有在内核模式下才可以被引用但可以位于任何一个进程环境中。所以这些句柄实际上是跨进程环境的。除了手动解析还可以使用一些执行体函数参考wrk或《Windows内核原理与实现》。