内核-句柄表

本文探讨了Windows程序中的句柄表概念,它如何保护内核对象安全,以及如何通过句柄定位和操作内核资源。作者详细讲解了句柄的作用、创建和打开的区别,展示了如何遍历进程句柄表并解析内核对象信息。此外,还涉及到了全局句柄表和不同级别的句柄结构。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

私有句柄表

属于一个程序独有的 每个程序都有属于自己程序的句柄表 里面存储了所有本程序打开的内核对象

内核对象

进程创建 或打开内核对象的时候 将获得句柄,通过句柄访问内核对象

 

为什么需要句柄???

句柄存在的目的是为了避免在应用层直接修改内核对象 应用层要是可以修改 如果修改成无效的地址在传送到0环 操作系统就会崩溃 所以操作系统并没有像用户层公开这个结构体 而是创建了一个句柄表

每个进程都有自己的这样的私有的表 这个表存储在0环 而你的进程里创建几个句柄 表中就用几项 而句柄则是内核句柄表的索引

 

创建和打开是两种概念

创建:windos会为刚创建的内核对象在0环分配一个结构体

打开:返回之前创建的结构体的地址

句柄表在哪???

 句柄表的地址

 打开100次内核对象 并不是打开一次给你创建一个结构体 一个内核对象只有一个结构体 打开一次只会增加计数器

 

 

 

拷贝到虚拟机 找到当前进程的句柄表

使用!process 0 0指令 遍历进程 找到我们的进程

 找到进程结构体

 找到成员

第一个成员 指向一张表 tablecode的低两位 有特殊含义 最后解释

 

 Dd到这个地址

 随便拿一个下标 找到真正句柄值的计算方法168 / 4 = 5a

因为句柄表一个成员是8字节

 

这就是0x168所对应的句柄的值 我们观察下 看这块内存值都是一样的因为他们都是同一个内核对象

这0x0000003a 87bf168b八个字节具体含义是什么哪

 

 代码更改  在看下有什么变化 SetHandleInformation修改的肯定是最后一个句柄因为循环出来最后打开的那个句柄

再次运行 找到最后一个句柄 解析这个句柄

 

1c4  / 4 = 71 句柄表里面的最后一项

 

为了和之前的句柄对比 现指令更改成如下 可以看到和之前的句柄值都不同

 后四字节........~97bf168b 最后三位 b 1 0 1 1  第二位表示当前的句柄可不可以被继承 像我们当前的句柄是可以被继承的所以是1

而这个句柄值真正指向内核对象的地址是97bf1688 最后三位清0

真正的内核对象的开头都是_OBJECT_HEADER这个结构体

这个句柄表里面值指向的其实是这个完整的结构 我们打开的是进程 地址+18才是EPROCESS  0X16C 就是当前的镜像名称

 

验证

 

 作用:在反调试的时候 遍历别人的句柄表 看别人的句柄表里有没有我们的句柄 有的话就说明这个程序打开了我

 

TableCode

低2位为0 一个页4kb 一个成员8字节 最多512个

低2位为1 表示你当前的句柄表结构为2级的 前1级为地址 一个成员4字节 一共1024个成员  而每个成员所指向的才是句柄的信息

 

 低2位为2 就是3级 前两级是地址 第三级才是内核对象信息

全局句柄表

 

 这三个函数在遍历的时候 遍历的其实就是这个表

 

实验

根据pid的值 在PspCidTable中找到内核对象

 

  首地址 也是HANDLE_TABLE结构的

此时的tablecode的值最后两位为1 说明是两级的 第一级的每个成员为4个字节

 

PID为十进制的转为16进制就是E88

 

tablecode低两位为1  E88/4 = 3A2  

因为一个表成员个数为512(0x200)  

(3A2 / 200)可以判断在哪个表中 在第二个表中

(3A2 % 200)可以判断在第二个表中的下标1a2

1A2就是第二个表的偏移

通过_HANDLE_TABLE_ENTRY结构查看.

 

 也可以使用DQ查看

因为是全局句柄表和私有的句柄表有差异 所以地址直接指向了_EPROCESS

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值