-
-
[求助]在R0下抹CSRSS中的句柄的问题
-
发表于:
2009-9-6 15:02
10101
-
由于在R3duplicate出CSRSS中句柄并close的方法不可逆,会引发诸多问题,于是我想自己在R0下定位句柄信息,并保存相关的地址和数据,先抹掉,再系统需要该信息时通过前面保存的信息还原之
我的做法是先定位到CSRSS的EPROCESS结构,通过ObjectTable定位到TableCode,这个就是句柄表地址了,我用Windbg看了下,后3位为0,即该句柄表只有一层,但是问题是,通过遍历该句柄表,我发现里面的存放的对象没有PROCESS对象,我是通过对象头的Type == ProcessType来判断的,但是发现没有满足该条件的。。。。
请问我的这种思路有问题吗??
详细代码如下:
//该函数通过以当前进程作为例子来获取自身的对象类型的指针,类型也就是ProcessType
POBJECT_TYPE GetProcessType()
{
PEPROCESS Process = PsGetCurrentProcess();
POBJECT_HEADER ObjectHeader = (POBJECT_HEADER)((ULONG)Process - 0x18); //得到对象头指针
return ObjectHeader->Type;
}
PCSRSS_INFO HideProcessInCsrss(ULONG CsrssId, ULONG ProcessId) //在Csrss中抹掉该进程的信息,并返回该信息用于还原
{
PEPROCESS Csrss;
NTSTATUS ntStatus = PsLookupProcessByProcessId((HANDLE)CsrssId, &Csrss);
if(!NT_SUCCESS(ntStatus))
{
return NULL;
}
PHANDLE_TABLE ObjectTable = *(PHANDLE_TABLE*)((ULONG)Csrss + OFFSET_EPROCESS_OBJECTTABLE);
ULONG TableCode = ObjectTable->TableCode;
PHANDLE_TABLE_ENTRY Table_1,Table_2;
ULONG Object;
POBJECT_TYPE ProcessType;
POBJECT_HEADER ObjectHeader;
ProcessType = GetProcessType();
if((TableCode & 0x03) == 0x00)
{
Table_1 = (PHANDLE_TABLE_ENTRY)TableCode;
Table_2 = 0;
}
else if((TableCode & 0x03) == 0x01)
{
TableCode = TableCode & 0xfffffffc; //去除低2位掩码
Table_1 = *(PHANDLE_TABLE_ENTRY*)TableCode;
Table_2 = *(PHANDLE_TABLE_ENTRY*)(TableCode + 1); //1级表每8字节存放一个索引项,索引项为PHANDLE_TABLE_ENTRY(个人理解)
}
for (ULONG index = 0; index < 0x4e1c; index++)
{
if(index <= 0x800)
{
if(MmIsAddressValid((PHANDLE_TABLE_ENTRY)(Table_1 + index)))
{
Object = ((Table_1 + index)->Object) & 0xfffffff8; //去掉掩码(因为是以4字节作为内存对齐)
// if( (Table_1 + index)->NextFreeTableEntry == 0 )
{
//为0则为正常
ObjectHeader = (POBJECT_HEADER)(Object - 0x18); //Object相对于ObjectHeader偏移0x18
if(MmIsAddressValid((POBJECT_TYPE)&(ObjectHeader->Type)))
{
if(ObjectHeader->Type == ProcessType)
{
PEPROCESS Process = (PEPROCESS)Object;
if( (*(PULONG)((ULONG)Process + OFFSET_EPROCESS_FLAGS) & 0x0c) != 0x0c )
{
if(MmIsAddressValid((PEPROCESS)Process))
{
if( ((ULONG)Process + OFFSET_EPROCESS_UNIQUEPROCESSID) == ProcessId )
{
PCSRSS_INFO pCsrssInfo = (PCSRSS_INFO)ExAllocatePool(PagedPool, sizeof(CSRSS_INFO));
pCsrssInfo->Address = (PHANDLE_TABLE_ENTRY)(Table_1 + index);
RtlCopyMemory(&(pCsrssInfo->hte), pCsrssInfo->Address, sizeof(HANDLE_TABLE_ENTRY));
RtlZeroMemory(pCsrssInfo->Address, sizeof(HANDLE_TABLE_ENTRY));
return pCsrssInfo;
}
}
}
}
}
}
}
}
else
{
if(Table_2 != 0)
{
if(MmIsAddressValid((PHANDLE_TABLE_ENTRY)(Table_2 + index - 0x800)))
{
Object = ((Table_2 + index - 0x800)->Object) & 0xfffffff8; //去掉掩码(因为是以4字节作为内存对齐)
if( (Table_2 + index - 0x800)->NextFreeTableEntry == 0 )
{
//为0则为正常
ObjectHeader = (POBJECT_HEADER)(Object - 0x18); //Object相对于ObjectHeader偏移0x18
if(MmIsAddressValid((POBJECT_TYPE)&(ObjectHeader->Type)))
{
if(ObjectHeader->Type == ProcessType)
{
PEPROCESS Process = (PEPROCESS)Object;
if( (*(PULONG)((ULONG)Process + OFFSET_EPROCESS_FLAGS) & 0x0c) != 0x0c )
{
if(MmIsAddressValid((PEPROCESS)Process))
{
if( ((ULONG)Process + OFFSET_EPROCESS_UNIQUEPROCESSID) == ProcessId )
{
PCSRSS_INFO pCsrssInfo = (PCSRSS_INFO)ExAllocatePool(PagedPool, sizeof(CSRSS_INFO));
pCsrssInfo->Address = (PHANDLE_TABLE_ENTRY)(Table_2 + index - 0x800);
RtlCopyMemory(&(pCsrssInfo->hte), pCsrssInfo->Address, sizeof(HANDLE_TABLE_ENTRY));
RtlZeroMemory(pCsrssInfo->Address, sizeof(HANDLE_TABLE_ENTRY));
return pCsrssInfo;
}
}
}
}
}
}
}
}
}
}
return NULL;
}
代码写得很挫,如果不想看就麻烦看看我的思路,指点下我的思路是否有问题?谢谢各位了
[课程]Linux pwn 探索篇!