句柄表及全局句柄表
句柄表结构
1.这一块共计两个字节,低字节保留为0,高位字节是给SetHandleInformation这个函数用的,比如写成SetHandleInformation(Handle,HANDLE_FLAG_PROTECT_FROM_CLOSE,HANDLE_FLAG_PROTECT_FROM_CLOSE),那么这个位置将被写入0x02;
HANDLE_FLAG_PROTECT_FROM_CLOSE 宏的值为0x00000002,取最低字节,最终1这块是0x0200,
2.这块是访问掩码,是给OpenProcess 这个函数用的OpenProcess(dwDesiredAcess,bInheritHandle,dwProcessId);具体的存的就是这个函数的第一个参数的值
3和4这两块共四个字节,其中bit0-bit2 存的是这个句柄的属性,其中bit2 bit0默认为0,1;bit1 表示的函数是该句柄是否可继承;OpenProcess的第二个参数与bit1有关;
bit31-bit3则是存放的该内核对象在内核中的具体的地址
实例:
1.编码获得当前的句柄
2.获得handle_table结构
windbg中!process 0 0 获得当前进程的RVA
PROCESS 8617f020 SessionId: 0 Cid: 04d0 Peb: 7ffd8000 ParentCid: 04f0
DirBase: 1b2ca000 ObjectTable: e25a9358 HandleCount: 77.
Image: HandleText.exe
3.获得句柄表的地址
4.通过索引查看句柄表中句柄的实际地址 7cc/4 = 1fc 因为句柄表是8字节进行排列的 所以需要乘以8
获得OpenProcess打开的进程的句柄
5.验证这个地址 因为后3位是标志位 所以需要清零 得到的地址就是86076008 这个地址实际指向的是OBJECT_HEANDER结构 0x18的位置才是eprocess的地址
6.获得这个地址的名称等相关信息 因为是打开的计数器 所以这里验证最后确实是计算器这个地址
1、全局句柄表
1) 所有的进程和线程无论无论是否打开,都在这个表中。
2) 每个进程和线程都有一个唯一的编号:PID和CID 这两个值其实就是全局句柄表中的索引。
进程和线程的查询,主要是以下三个函数,按照给定的PID或CID从PspCidTable从查找相应的进线程对象:
PsLookupProcessThreadByCid()
PsLookupProcessByProcessId()
PsLookupThreadByThreadId()
2、全局句柄表结构
实例:
1.获得全局句柄表地址
2.通过PID获得起在全局句柄表中的地址值 计算器PID=1440 1440/4=0x168
3.通过第一个地址获得指定地址的名称及其相信信息