探测句柄表结构一
每个进程都存在一个句柄表,是很重要的数据结构,系统分配资源创建内核对象,之后生成一个整数返还给用户,而自己管理对象的生命周期学习句柄表结构最直接的方式无非是通过句柄表操作的api了,下面的句柄表操作函数和相关数据结构已经经过精简,可以说明句柄表的用法:
typedef struct _HANDLE_TABLE //每个进程都存在一个句柄表,所有句柄表都链接到一个全局链表中
{
ULONG_PTR TableCode;//指向句柄表上层树节点
struct _EPROCESS *QuotaProcess;
HANDLE UniqueProcessId;
#define HANDLE_TABLE_LOCKS 4
EX_PUSH_LOCK HandleTableLock;
LIST_ENTRY HandleTableList;//全局句柄表链表
EX_PUSH_LOCK HandleContentionEvent;
PHANDLE_TRACE_DEBUG_INFO DebugInfo;
LONG ExtraInfoPages;
ULONG FirstFree;
ULONG LastFree;
ULONG NextHandleNeedingPool;
LONG HandleCount;
union {
ULONG Flags;
BOOLEAN StrictFIFO : 1;
};
} HANDLE_TABLE, *PHANDLE_TABLE;
NTSTATUS ObReferenceObjectByHandle (HANDLE Handle,ACCESS_MASK DesiredAccess,POBJECT_TYPE ObjectType,KPROCESSOR_MODE AccessMode,
PVOID *Object,POBJECT_HANDLE_INFORMATION HandleInformation)
{
ACCESS_MASK GrantedAccess;
PHANDLE_TABLE HandleTable;
POBJECT_HEADER ObjectHeader;
PHANDLE_TABLE_ENTRY ObjectTableEntry;
PEPROCESS Process;
NTSTATUS Status;
PETHREAD Thread;
*Object = NULL;
if ((LONG)(ULONG_PTR) Handle < 0) // <0的情况可能是:内核句柄,-1,-2
{
if (Handle == NtCurrentProcess()) //NtCurrentProcess=-1
{//如果是当前进程
if ((ObjectType == PsProcessType) || (ObjectType == NULL))
{
Process = PsGetCurrentProcessByThread(Thread);
ObjectHeader = OBJECT_TO_OBJECT_HEADER(Process);
ObpIncrPointerCount(ObjectHeader);
*Object = Process;
return;
}
else if (Handle == NtCurrentThread()) //NtCurrentThread=-2
{
if ((ObjectType == PsThreadType) || (ObjectType == NULL))
{//如果是当前线程
ObjectHeader = OBJECT_TO_OBJECT_HEADER(Thread);
ObpIncrPointerCount(ObjectHeader);
*Object = Thread;
return;
}
else if (AccessMode == KernelMode)
{
Handle = DecodeKernelHandle( Handle );//去除最高位
HandleTable = ObpKernelHandleTable;
}
}
else
{
HandleTable = PsGetCurrentProcessByThread(Thread)->ObjectTable;
}
KeEnterCriticalRegionThread(&Thread->Tcb);//加锁
ObjectTableEntry = ExMapHandleToPointerEx ( HandleTable, Handle, AccessMode );//将句柄表句柄转换成句柄表入口
if (ObjectTableEntry != NULL)
{
ObjectHeader = (POBJECT_HEADER)(((ULONG_PTR)(ObjectTableEntry->Object)) & ~OBJ_HANDLE_ATTRIBUTES);
ReadForWriteAccess(ObjectHeader);
if ((ObjectHeader->Type == ObjectType) || (ObjectType == NULL))
{
ObpIncrPointerCount(ObjectHeader);
ExUnlockHandleTableEntry( HandleTable, ObjectTableEntry );
KeLeaveCriticalRegionThread(&Thread->Tcb);
*Object = &ObjectHeader->Body;
}
}
KeLeaveCriticalRegionThread(&Thread->Tcb);
return Status;
}
NTKERNELAPI PHANDLE_TABLE_ENTRY ExMapHandleToPointerEx ( PHANDLE_TABLE HandleTable, HANDLE Handle, KPROCESSOR_MODE PreviousMode)
{
EXHANDLE LocalHandle;
PHANDLE_TABLE_ENTRY HandleTableEntry = NULL;
PETHREAD CurrentThread;
LocalHandle.GenericHandleOverlay = Handle;
if (((LocalHandle.Index & (LOWLEVEL_COUNT - 1)) == 0) || ((HandleTableEntry = ExpLookupHandleTableEntry(HandleTable, LocalHandle)) == NULL) ||
!ExpLockHandleTableEntry( HandleTable, HandleTableEntry))
{
return NULL;
}
return HandleTableEntry;
}
typedef struct _EXHANDLE {
union {
struct {
ULONG TagBits : 2;
ULONG Index : 30;//句柄表入口索引
};
HANDLE GenericHandleOverlay;
#define HANDLE_VALUE_INC 4 // Amount to increment the Value to get to the next handle
ULONG_PTR Value;
};
} EXHANDLE, *PEXHANDLE;
PHANDLE_TABLE_ENTRY ExpLookupHandleTableEntry (PHANDLE_TABLE HandleTable,EXHANDLE tHandle)
{
ULONG_PTR i,j,k;
ULONG_PTR CapturedTable;
ULONG TableLevel;
PHANDLE_TABLE_ENTRY Entry = NULL;
EXHANDLE Handle;
PUCHAR TableLevel1;
PUCHAR TableLevel2;
PUCHAR TableLevel3;
ULONG_PTR MaxHandle;
Handle = tHandle;
Handle.TagBits = 0;
MaxHandle = *(volatile ULONG *) &HandleTable->NextHandleNeedingPool;
if (Handle.Value >= MaxHandle) {
return NULL;
}
CapturedTable = *(volatile ULONG_PTR *) &HandleTable->TableCode;
TableLevel = (ULONG)(CapturedTable & LEVEL_CODE_MASK);
CapturedTable = CapturedTable - TableLevel;
switch (TableLevel)
{
case 0://简单索引表,索引已经乘4
TableLevel1 = (PUCHAR) CapturedTable;
Entry = (PHANDLE_TABLE_ENTRY) &TableLevel1;
break;
case 1://2级索引表
TableLevel2 = (PUCHAR) CapturedTable;
i = Handle.Value % (LOWLEVEL_COUNT * HANDLE_VALUE_INC);
Handle.Value -= i;
j = Handle.Value / ((LOWLEVEL_COUNT * HANDLE_VALUE_INC) / sizeof (PHANDLE_TABLE_ENTRY));
TableLevel1 =(PUCHAR) *(PHANDLE_TABLE_ENTRY *) &TableLevel2;
Entry = (PHANDLE_TABLE_ENTRY) &TableLevel1;
break;
case 2://3级索引表
TableLevel3 = (PUCHAR) CapturedTable;
i = Handle.Value% (LOWLEVEL_COUNT * HANDLE_VALUE_INC);
Handle.Value -= i;
k = Handle.Value / ((LOWLEVEL_COUNT * HANDLE_VALUE_INC) / sizeof (PHANDLE_TABLE_ENTRY));
j = k % (MIDLEVEL_COUNT * sizeof (PHANDLE_TABLE_ENTRY));
k -= j;
k /= MIDLEVEL_COUNT;
TableLevel2 = (PUCHAR) *(PHANDLE_TABLE_ENTRY *) &TableLevel3;
TableLevel1 = (PUCHAR) *(PHANDLE_TABLE_ENTRY *) &TableLevel2;
Entry = (PHANDLE_TABLE_ENTRY) &TableLevel1;
break;
}
return Entry;
}
页:
[1]