侦测隐藏进程的强文[下]

利用以上信息还原该结构:

Code:

typedef struct _XP_HANDLE_TABLE
{
ULONG TableCode;
PEPROCESS QuotaProcess;
PVOID UniqueProcessId;
EX_PUSH_LOCK HandleTableLock[4];
LIST_ENTRY HandleTableList;
EX_PUSH_LOCK HandleContentionEvent;
PHANDLE_TRACE_DEBUG_INFO DebugInfo;
LONG ExtraInfoPages;
ULONG FirstFree;
ULONG LastFree;
ULONG NextHandleNeedingPool;
LONG HandleCount;
LONG Flags;
UCHAR StrictFIFO;
} XP_HANDLE_TABLE, *PXP_HANDLE_TABLE;

从上面的表中可以很明显看出ExpLookupHandleTableEntry函数从HANDLE_TABLE结构中得到TableCode的值,并基于其低2位的内容计算出表的层

次数。其余的位指向第1层表。因此Windows XP下的HANDLE_TABLE可以拥有1到3个层次,每一个层次的表的大小为1FFh。当表中记录的数量增加

时,系统会自动增加层数。很明显,当表中记录的数量超过0x200的时候表就会拥有两层,当大于0x40000时增加到第3层。不知道当销毁对象时

系统会不会减少表的层数,我没有注意到这件事。

Windows XP下没有ExLockHandleTableEntry函数,因此表中相应的模块被定位在ExMapHandleToPointer函数中。反汇编这个函数看看它做了什

么?

Code:

PAGE:0048F61E ExMapHandleToPointer proc near
PAGE:0048F61E
PAGE:0048F61E
PAGE:0048F61E var_8 = dword ptr -8
PAGE:0048F61E var_4 = dword ptr -4
PAGE:0048F61E HandleTable = dword ptr 8
PAGE:0048F61E Handle = dword ptr 0Ch
PAGE:0048F61E
PAGE:0048F61E mov edi, edi
PAGE:0048F620 push ebp
PAGE:0048F621 mov ebp, esp
PAGE:0048F623 push ecx
PAGE:0048F624 push ecx
PAGE:0048F625 push edi
PAGE:0048F626 mov edi, [ebp+Handle]
PAGE:0048F629 test di, 7FCh
PAGE:0048F62E jz loc_4A2A36
PAGE:0048F634 push ebx
PAGE:0048F635 push esi
PAGE:0048F636 push edi
PAGE:0048F637 push [ebp+HandleTable]
PAGE:0048F63A call ExpLookupHandleTableEntry
PAGE:0048F63F mov esi, eax
PAGE:0048F641 test esi, esi
PAGE:0048F643 jz loc_4A2711
PAGE:0048F649 mov [ebp+var_4], esi
PAGE:0048F64C loc_48F64C:
PAGE:0048F64C mov ebx, [esi]
PAGE:0048F64E test bl, 1
PAGE:0048F651 mov [ebp+var_8], ebx
PAGE:0048F654 jz loc_508844
PAGE:0048F65A lea eax, [ebx-1]
PAGE:0048F65D mov [ebp+Handle], eax
PAGE:0048F660 mov eax, [ebp+var_8]
PAGE:0048F663 mov ecx, [ebp+var_4]
PAGE:0048F666 mov edx, [ebp+Handle]
PAGE:0048F669 cmpxchg [ecx], edx
PAGE:0048F66C cmp eax, ebx
PAGE:0048F66E jnz loc_50884C
PAGE:0048F674 mov eax, esi
PAGE:0048F676 loc_48F676:
PAGE:0048F676 pop esi
PAGE:0048F677 pop ebx
PAGE:0048F678 loc_48F678:
PAGE:0048F678 pop edi
PAGE:0048F679 leave
PAGE:0048F67A retn 8
PAGE:0048F67A ExMapHandleToPointer endp

ExpLookuphandleTableEntry函数返回指向HANDLE_TABLE_ENTRY的指针后,我们要检查Object域的低字节,如果是被设置了的,说明是被清除了

的(俄文翻译者kao注:希望我翻译的对...),如果该位没有被设置,我们要等到它被设置了为止。因此当得到对象地址的时候我们不应该设

置高位(Windows 2000平台),而是要清除低位。综上所述,扫描表的代码如下:

Code:

void ScanXpHandleTable(PXP_HANDLE_TABLE HandleTable)
{
int i, j, k;
PHANDLE_TABLE_ENTRY Entry;
ULONG TableCode = HandleTable->TableCode & ~TABLE_LEVEL_MASK;

switch (HandleTable->TableCode & TABLE_LEVEL_MASK)
{
case 0 :
for (i = 0; i < 0x200; i++)
{
Entry = &((PHANDLE_TABLE_ENTRY)TableCode);

if (Entry->Object) ProcessObject((PVOID)((ULONG)Entry->Object & ~XP_TABLE_ENTRY_LOCK_BIT));
}
break;

case 1 :
for (i = 0; i < 0x200; i++)
{
if (((PVOID *)TableCode))
{
for (j = 0; j < 0x200; j++)
{
Entry = &((PHANDLE_TABLE_ENTRY *)TableCode)[j];

if (Entry->Object) ProcessObject((PVOID)((ULONG)Entry->Object & ~XP_TABLE_ENTRY_LOCK_BIT));
}
}
}
break;

case 2 :
for (i = 0; i < 0x200; i++)
{
if (((PVOID *)TableCode))
{
for (j = 0; j < 0x200; j++)
{
if (((PVOID **)TableCode)[j])
{
for (k = 0; k < 0x200; k++)
{
Entry = &((PHANDLE_TABLE_ENTRY **)TableCode)[j][k];

if (Entry->Object)
ProcessObject((PVOID)((ULONG)Entry->Object & ~XP_TABLE_ENTRY_LOCK_BIT));
}
}
}
}
}
break;
}
}

我们已经明白对象表格式了。现在想要枚举进程我们还需要得到PspCidTable的地址。也许你已经猜到了,我们要在

PsLookupProcessByProcessId函数中搜索,这个函数中的第1个函数调用包含着PspCidTable的地址。代码如下:

Code:

void GetPspCidTable()
{
PUCHAR cPtr, pOpcode;
ULONG Length;

for (cPtr = (PUCHAR)PsLookupProcessByProcessId;
cPtr < (PUCHAR)PsLookupProcessByProcessId + PAGE_SIZE;
cPtr += Length)
{
Length = SizeOfCode(cPtr, &pOpcode);

if (!Length) break;

if (*(PUSHORT)cPtr == 0x35FF && *(pOpcode + 6) == 0xE8)
{
PspCidTable = **(PVOID **)(pOpcode + 2);
break;
}
}
}

现在我们知道怎样处理PspCidTable了,可以非常容易地查看到所有进程的表中的所有元素,分析那些属于隐藏进程的对象,就像我们在用户态

做的一样,如果你已经理解了前面所讲的东西,你一定可以做得到。

中文参考:《JIURL玩玩Win2k进程线程篇 HANDLE_TABLE》(http://jiurl.nease.net/document/JiurlPlayWin2k/PsHandleTable.htm)

感谢:firstrose, JIURL, linhanshi.

 

 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值