一. 内核对象
1. 进程对象(EPROCESS)
较简单的方法是判断EPROCESS中的ExitTime是否为0,如果是0则说明该进程正在运行。但是由于该值不会对进程的运行产生任何影响,如果rootkit会在此处填值,使判断失效。
根据《Windows 核心编程 第五版》 P231中的叙述,Windows中的进程内核对象中存在一个布尔变量,标示进程是否终止,使得WaitForSingleObject能够等待进程结束的时间通知。
[Windows XP sp2]
kd> dt -b _eprocess 820c8d50
nt!_EPROCESS
+0x000 Pcb : _KPROCESS
+0x000 Header : _DISPATCHER_HEADER
+0x000 Type : 0x3 ''
+0x001 Absolute : 0 ''
+0x002 Size : 0x1b ''
+0x003 Inserted : 0 ''
+0x004 SignalState : 1
+0x008 WaitListHead : _LIST_ENTRY [ 0x820c8d58 - 0x820c8d58 ]
+0x000 Flink : 0x820c8d58
+0x004 Blink : 0x820c8d58
nt!_EPROCESS
+0x000 Pcb : _KPROCESS
+0x000 Header : _DISPATCHER_HEADER
+0x000 Type : 0x3 ''
+0x001 Absolute : 0 ''
+0x002 Size : 0x1b ''
+0x003 Inserted : 0 ''
+0x004 SignalState : 1
+0x008 WaitListHead : _LIST_ENTRY [ 0x820c8d58 - 0x820c8d58 ]
+0x000 Flink : 0x820c8d58
+0x004 Blink : 0x820c8d58
可以看到SignalState正是上面说的布尔值。SignalState为TRUE表示此时该进程已被结束。
试验后发现,在windbg中手动修改SignalState为1后,用WaitForSingleObject等待进程结束的调用立即返回成功(WAIT_OBJECT_0),但该进程并未受影响。
试验后发现,在windbg中手动修改SignalState为1后,用WaitForSingleObject等待进程结束的调用立即返回成功(WAIT_OBJECT_0),但该进程并未受影响。
通过记录进程结束前和进程结束后的EPROCESS结构,试图发现对无效进程内核对象的判别有用的结构成员。
使用UE附带的比较工具比较后,可能有用的成员如下
[Windows XP sp2]
结束前 结束后
+0x004 SignalState : 0 +0x004 SignalState : 1 // 修改为1后,只影响WaitForSingalObject等API。
+0x060 StackCount : 1 +0x060 StackCount : 0
+0x0a8 CommitCharge : 0x1fa +0x0a8 CommitCharge : 0
+0x060 StackCount : 1 +0x060 StackCount : 0
+0x0a8 CommitCharge : 0x1fa +0x0a8 CommitCharge : 0