ULONG GetPspCidTable()
/*++
获取系统中未导出的pspCidTable
--*/
{
ULONG pAddr;
ULONG Len;
PUCHAR opcode;
ULONG ulFunc = (ULONG)PsLookupProcessByProcessId;
__try
{
//
//如果是调试模式,需要计算一下真实位置
//用来校正jmp thunk
//
if(*(PUSHORT)PsLookupProcessByProcessId==0x25ff)
{
ulFunc = **(ULONG**)((ULONG)PsLookupProcessByProcessId+2);
}
//DbgPrint("[My1st] ulFunc: 0X&08X\n", ulFunc);
for(pAddr=ulFunc;
pAddr<ulFunc+0x60;
pAddr+=Len)
{
Len = SizeOfCode((PUCHAR)pAddr, &opcode);
if(!Len)
{
break;
}
if( *(PUSHORT)pAddr==0x35ff && *(PUCHAR)(pAddr+6)==0xe8 )
{
return **(ULONG**)(opcode+2);
}
}
return 0;
}
__except(1)
{
return 0;
}
}
/*++
通过进程的id,获取进程的EPROCESS结构
--*/
PEPROCESS GetProcessById(ULONG id)
{
PHANDLE_TABLE pspCidTable;
ULONG Eprocess;
ULONG* pEprocess;
//
//如果查找pspCidTable失败,直接返回NULL
//
pspCidTable = (PHANDLE_TABLE)GetPspCidTable();
if(!pspCidTable)
{
return NULL;
}
//
//越界检查
//
id &= 0xfffffffc; //忽略id的后两位
if(id>=pspCidTable->NextHandleNeedingPool)
{
return NULL;
}
//
//由于pspCidTable只是一个简单的0级表,所以检索很容易
//
pEprocess = (ULONG*)(pspCidTable->TableCode + id*2);
if(!MmIsAddressValid(pEprocess)) //检查一下地址的有效性,参考KsBinSword的源代码,原来在内核中检查地址的函数是这个
{
//同时感谢2楼
return NULL;
}
Eprocess = (*pEprocess) & 0xfffffffc;
if(!MmIsAddressValid((PVOID)Eprocess))
{
return NULL;
}
//
//检查获取的对象是不是EPROCESS
//
if(*(UCHAR*)Eprocess==0x03
&& *(ULONG*)(Eprocess+0x1a4)!=0)
//&& ObReferenceObjectSafe((PVOID)Eprocess))
{
return (PEPROCESS)Eprocess;
}
return NULL;
}
/*++
通过线程的id,获取进程的ETHREAD结构
--*/
PETHREAD GetThreadById(ULONG id)
{
PHANDLE_TABLE pspCidTable;
ULONG Ethread;
ULONG* pEthread;
//
//如果查找pspCidTable失败,直接返回NULL
//
pspCidTable = (PHANDLE_TABLE)GetPspCidTable();
if(!pspCidTable)
{
return NULL;
}
//
//越界检查
//
id &= 0xfffffffc; //忽略id的后两位
if(id>=pspCidTable->NextHandleNeedingPool)
{
return NULL;
}
//
//由于pspCidTable只是一个简单的0级表,所以检索很容易
//
pEthread = (ULONG*)((pspCidTable->TableCode + id*2) & 0xfffffffc);
if(!MmIsAddressValid(pEthread))
{
return NULL;
}
Ethread = (*pEthread) & 0xfffffffc;
if(!MmIsAddressValid((PVOID)Ethread))
{
return NULL;
}
//
//检查获取的对象是不是ETHREAD
//
if(*(UCHAR*)Ethread==0x06
&& *(ULONG*)(Ethread+0x244)!=0)
//&& ObReferenceObjectSafe((PVOID)Ethread))
{
return (PETHREAD)Ethread;
}
return NULL;
}
/*++
通过id,获取对象的指针
--*/
ULONG GetObjectById(ULONG id)
{
PHANDLE_TABLE pspCidTable;
ULONG Eobject;
ULONG* pEobject;
//
//如果查找pspCidTable失败,直接返回NULL
//
pspCidTable = (PHANDLE_TABLE)GetPspCidTable();
if(!pspCidTable)
{
return 0;
}
//
//越界检查
//
id &= 0xfffffffc; //忽略id的后两位
if(id>=pspCidTable->NextHandleNeedingPool)
{
return 0;
}
//
//由于pspCidTable只是一个简单的0级表,所以检索很容易
//
pEobject = (ULONG*)((pspCidTable->TableCode + id*2) & 0xfffffffc);
if(!MmIsAddressValid(pEobject))
{
return 0;
}
Eobject = (*pEobject) & 0xfffffffc;
if(!MmIsAddressValid((PVOID)Eobject))
{
return 0;
}
//if(ObReferenceObjectSafe((PVOID)Eobject))
//{
return Eobject;
//}
return 0;
}
void DisplayProcessNameById(ULONG id)
{
ULONG ulProcessName;
ULONG ulProcess;
ulProcess = (ULONG)GetProcessById(id);
if(!ulProcess)
{
return;
}
ulProcessName = ulProcess + 0x174; //Windows XP
dprintf("[My1st] %s\n", (PUCHAR)ulProcessName);
}
void EnumerateProcesses()
{
ULONG ulIte;
for(ulIte=1;ulIte<0x800;ulIte++)
{
DisplayProcessNameById(ulIte<<2);
}
}
效果如下:
[My1st] DriverEntry
[My1st] System
[My1st] VMwareUser.exe
[My1st] ctfmon.exe
[My1st] wscntfy.exe
[My1st] smss.exe
[My1st] csrss.exe
[My1st] winlogon.exe
[My1st] services.exe
[My1st] lsass.exe
[My1st] svchost.exe
[My1st] svchost.exe
[My1st] svchost.exe
[My1st] svchost.exe
[My1st] svchost.exe
[My1st] cmd.exe
[My1st] conime.exe
[My1st] explorer.exe
[My1st] spoolsv.exe
[My1st] net.exe
[My1st] net1.exe
[My1st] VMwareService.e
[My1st] alg.exe
[My1st] VMwareTray.exe