网络安全 频道

检测隐藏进程

函数的其余部分对我们来说没什么用,现在我们来看看PsLookupProcessByProcessId:

Code:

PAGE:0049D725 public PsLookupProcessByProcessId
PAGE:0049D725 PsLookupProcessByProcessId proc near
PAGE:0049D725
PAGE:0049D725
PAGE:0049D725 ProcessId = dword ptr 8
PAGE:0049D725 Process = dword ptr 0Ch
PAGE:0049D725
PAGE:0049D725 mov edi, edi
PAGE:0049D727 push ebp
PAGE:0049D728 mov ebp, esp
PAGE:0049D72A push ebx
PAGE:0049D72B push esi
PAGE:0049D72C mov eax, large fs:124h
PAGE:0049D732 push [ebp+ProcessId]
PAGE:0049D735 mov esi, eax
PAGE:0049D737 dec dword ptr [esi+0D4h]
PAGE:0049D73D push PspCidTable
PAGE:0049D743 call ExMapHandleToPointer
PAGE:0049D748 mov ebx, eax
PAGE:0049D74A test ebx, ebx
PAGE:0049D74C mov [ebp+ProcessId], STATUS_INVALID_PARAMETER
PAGE:0049D753 jz short loc_49D787
PAGE:0049D755 push edi
PAGE:0049D756 mov edi, [ebx]
PAGE:0049D758 cmp byte ptr [edi], 3
PAGE:0049D75B jnz short loc_49D77A
PAGE:0049D75D cmp dword ptr [edi+1A4h], 0
PAGE:0049D764 jz short loc_49D77A
PAGE:0049D766 mov ecx, edi
PAGE:0049D768 call sub_4134A9
PAGE:0049D76D test al, al
PAGE:0049D76F jz short loc_49D77A
PAGE:0049D771 mov eax, [ebp+Process]
PAGE:0049D774 and [ebp+ProcessId], 0
PAGE:0049D778 mov [eax], edi
PAGE:0049D77A loc_49D77A:
PAGE:0049D77A push ebx
PAGE:0049D77B push PspCidTable
PAGE:0049D781 call ExUnlockHandleTableEntry
PAGE:0049D786 pop edi
PAGE:0049D787 loc_49D787:
PAGE:0049D787 inc dword ptr [esi+0D4h]
PAGE:0049D78D jnz short loc_49D79A
PAGE:0049D78F lea eax, [esi+34h]
PAGE:0049D792 cmp [eax], eax
PAGE:0049D794 jnz loc_52388A
PAGE:0049D79A loc_49D79A:
PAGE:0049D79A mov eax, [ebp+ProcessId]
PAGE:0049D79D pop esi
PAGE:0049D79E pop ebx
PAGE:0049D79F pop ebp
PAGE:0049D7A0 retn 8

以上我们所看到的,证实了存在像HANDLE_TABLE一样组织结构的第2个进程列表。这个表叫做PspCidTable,它包括进程和线程的列表,

PsLookupProcessThreadByCid函数和PsLookupThreadByThreadId函数都用到了这个表。我们看到,句柄和句柄表的指针被传递给了

ExMapHandleToPointer函数,该函数(在句柄有效的情况下)返回一个指向描述给定句柄的表的一个元素 - HANDLE_TABLE_ENTRY。当我们用

PDBdump分析完ntoskrnl.pdb并且得到分析日志后,会得到如下结果:

Code:

struct _HANDLE_TABLE_ENTRY {
// static data ------------------------------------
// non-static data --------------------------------
/*<thisrel this+0x0>*/ /*|0x4|*/ void* Object;
/*<thisrel this+0x0>*/ /*|0x4|*/ unsigned long ObAttributes;
/*<thisrel this+0x0>*/ /*|0x4|*/ struct _HANDLE_TABLE_ENTRY_INFO* InfoTable;
/*<thisrel this+0x0>*/ /*|0x4|*/ unsigned long Value;
/*<thisrel this+0x4>*/ /*|0x4|*/ unsigned long GrantedAccess;
/*<thisrel this+0x4>*/ /*|0x2|*/ unsigned short GrantedAccessIndex;
/*<thisrel this+0x6>*/ /*|0x2|*/ unsigned short CreatorBackTraceIndex;
/*<thisrel this+0x4>*/ /*|0x4|*/ long NextFreeTableEntry;
};// <size 0x8>

We can recover HANDLE_TABLE_ENTRY structure from this:
我们还原一下HANDLE_TABLE_ENTRY结构的C代码:

Code:

typedef struct _HANDLE_TABLE_ENTRY
{
union
{
PVOID Object;
ULONG ObAttributes;
PHANDLE_TABLE_ENTRY_INFO InfoTable;
ULONG Value;
};

union
{
union
{
ACCESS_MASK GrantedAccess;
struct
{
USHORT GrantedAccessIndex;
USHORT CreatorBackTraceIndex;
};
};

LONG NextFreeTableEntry;
};
} HANDLE_TABLE_ENTRY, *PHANDLE_TABLE_ENTRY;

怎么使用它呢?首先,我们比较感兴趣的是Object域的内容,它是被句柄描述的目标指针和这个表的给定元素的用法标志(我将稍后解释这句

话)。GrantedAccess域指定了通过这个句柄对目标的访问权限许可,这个很有趣。比如,以只读方式打开一个文件,修改这个域之后就可以写

这个文件了。这个方法可以用在对一些正在被读/写的文件的访问上(比如,正在被其他进程锁定的文件)。应该回到我们的问题上来了 - 通

过对PspCidTable的分析得到进程句柄列表。

要分析它我们得了解句柄表的格式,这样才能遍历这个列表。在这个地方
Windows 2000和Windows XP有着巨大的不同。由于句柄表格式不尽相

同,所以我们应该把操作系统分类进行分析。

因为
Windows 2000的句柄表相对简单一些,所以我们先分析它。先来看看ExMapHandleToPointer函数:

Code:

PAGE:00493285 ExMapHandleToPointer proc near
PAGE:00493285
PAGE:00493285
PAGE:00493285 HandleTable = dword ptr 8
PAGE:00493285 Handle = dword ptr 0Ch
PAGE:00493285
PAGE:00493285 push esi
PAGE:00493286 push [esp+Handle]
PAGE:0049328A push [esp+4+HandleTable]
PAGE:0049328E call ExpLookupHandleTableEntry
PAGE:00493293 mov esi, eax
PAGE:00493295 test esi, esi
PAGE:00493297 jz short loc_4932A9
PAGE:00493299 push esi
PAGE:0049329A push [esp+4+HandleTable]
PAGE:0049329E call ExLockHandleTableEntry
PAGE:004932A3 neg al
PAGE:004932A5 sbb eax, eax
PAGE:004932A7 and eax, esi
PAGE:004932A9 loc_4932A9:
PAGE:004932A9 pop esi
PAGE:004932AA retn 8
PAGE:004932AA ExMapHandleToPointer endp

这里我们调用搜索HANDLE_TABLE的函数ExMapHandleToPointer以及设置Lock Bit的ExLockHandleTableEntry函数。要了解句柄表的内部结构我

们必须反汇编这些函数。先从ExpLookupHandleTableEntry函数开始:

Code:

PAGE:00493545 ExpLookupHandleTableEntry proc near
PAGE:00493545
PAGE:00493545
PAGE:00493545 HandleTable = dword ptr 0Ch
PAGE:00493545 Handle = dword ptr 10h
PAGE:00493545
PAGE:00493545 push esi
PAGE:00493546 push edi
PAGE:00493547 mov edi, [esp+Handle]
PAGE:0049354B mov eax, 0FFh
PAGE:00493550 mov ecx, edi
PAGE:00493552 mov edx, edi
PAGE:00493554 mov esi, edi
PAGE:00493556 shr ecx, 12h
PAGE:00493559 shr edx, 0Ah
PAGE:0049355C shr esi, 2
PAGE:0049355F and ecx, eax
PAGE:00493561 and edx, eax
PAGE:00493563 and esi, eax
PAGE:00493565 test edi, 0FC000000h
PAGE:0049356B jnz short loc_49358A
PAGE:0049356D mov eax, [esp+HandleTable]
PAGE:00493571 mov eax, [eax+8]
PAGE:00493574 mov ecx, [eax+ecx*4]
PAGE:00493577 test ecx, ecx
PAGE:00493579 jz short loc_49358A
PAGE:0049357B mov ecx, [ecx+edx*4]
PAGE:0049357E test ecx, ecx
PAGE:00493580 jz short loc_49358A
PAGE:00493582 lea eax, [ecx+esi*8]
PAGE:00493585 loc_493585:
PAGE:00493585 pop edi
PAGE:00493586 pop esi
PAGE:00493587 retn 8
PAGE:0049358A loc_49358A:
PAGE:0049358A xor eax, eax
PAGE:0049358C jmp short loc_493585
PAGE:0049358C ExpLookupHandleTableEntry endp

0
相关文章