PS:很老的东西,想看原理的话 ,我是看着两个明白原理的
1.基于pspCidTable的进程检测技术
2.pspcidtable完全解读
xp sp3 当pid到4088时开始填充空缺,尽量不开第三层表(2层表4096),但当我开了300多个进程以后,终于开了
kd> dd pspcidtable
805649c0 e1000c80 00000002 00000002 00000000
805649d0 00000000 00000000 00000000 00000000
805649e0 e16e4267 e153f737 00000000 00000000
805649f0 00000000 00000000 00000000 00000000
80564a00 00000000 00000000 00000000 00000000
80564a10 00000000 00000000 00000000 00000000
80564a20 00000000 00000000 00000000 00000000
80564a30 00000000 00000000 00000000 00000000
得到 handle table,TableCode 最后两位显示为用了二层表
kd> dd e1000c80
e1000c80 e1d54001 00000000 00000000 00000000
e1000c90 00000000 00000000 00000000 e1000c9c
e1000ca0 e1000c9c 00000000 00000000 00000000
e1000cb0 00001670 0000166c 00001800 0000039e
e1000cc0 00000001 00000000 0c0b040a 64546553
e1000cd0 00000101 05000000 00000012 00440002
e1000ce0 00000002 00140000 10000000 00000101
e1000cf0 05000000 00000012 00180000 a0020000
这里却有三个地址
kd> dd e1d54000
e1d54000 e1005000 e1d55000 e1d9e000 00000000
e1d54010 00000000 00000000 00000000 00000000
e1d54020 00000000 00000000 00000000 00000000
e1d54030 00000000 00000000 00000000 00000000
e1d54040 00000000 00000000 00000000 00000000
e1d54050 00000000 00000000 00000000 00000000
e1d54060 00000000 00000000 00000000 00000000
e1d54070 00000000 00000000 00000000 00000000
看了下第三个地址
kd> dd e1d9e000
e1d9e000 00000000 fffffffe 00000000 00000000
e1d9e010 00000000 00001004 00000000 00001008
e1d9e020 00000000 0000100c 8126c991 00000000
e1d9e030 8126c719 00000000 8126b931 00000000
e1d9e040 8126b6b9 00000000 8126a541 00000000
e1d9e050 8126a2c9 00000000 00000000 00001010
e1d9e060 00000000 0000102c 00000000 00001030
e1d9e070 00000000 00001034 81268021 00000000
随便取了一个数值
kd> dt _eprocess 8126c990
ntdll!_EPROCESS
+0x000 Pcb : _KPROCESS
+0x06c ProcessLock : _EX_PUSH_LOCK
+0x070 CreateTime : _LARGE_INTEGER 0x1ca653b`039a2530
+0x078 ExitTime : _LARGE_INTEGER 0x0
+0x080 RundownProtect : _EX_RUNDOWN_REF
+0x084 UniqueProcessId : 0x00001014
+0x088 ActiveProcessLinks : _LIST_ENTRY [ 0x8126b9b8 - 0x8126dde8 ]
+0x090 QuotaUsage : [3] 0x730
+0x09c QuotaPeak : [3] 0x838
。。。。。。。。。。。。。。。。。。。。
+0x168 Filler : 0
+0x170 Session : 0xf9ede000
+0x174 ImageFileName : [16] "INSTDRV (2).EXE"
没有问题,得到了大于pid 4096 的进程信息
1.基于pspCidTable的进程检测技术
2.pspcidtable完全解读
xp sp3 当pid到4088时开始填充空缺,尽量不开第三层表(2层表4096),但当我开了300多个进程以后,终于开了
kd> dd pspcidtable
805649c0 e1000c80 00000002 00000002 00000000
805649d0 00000000 00000000 00000000 00000000
805649e0 e16e4267 e153f737 00000000 00000000
805649f0 00000000 00000000 00000000 00000000
80564a00 00000000 00000000 00000000 00000000
80564a10 00000000 00000000 00000000 00000000
80564a20 00000000 00000000 00000000 00000000
80564a30 00000000 00000000 00000000 00000000
得到 handle table,TableCode 最后两位显示为用了二层表
kd> dd e1000c80
e1000c80 e1d54001 00000000 00000000 00000000
e1000c90 00000000 00000000 00000000 e1000c9c
e1000ca0 e1000c9c 00000000 00000000 00000000
e1000cb0 00001670 0000166c 00001800 0000039e
e1000cc0 00000001 00000000 0c0b040a 64546553
e1000cd0 00000101 05000000 00000012 00440002
e1000ce0 00000002 00140000 10000000 00000101
e1000cf0 05000000 00000012 00180000 a0020000
这里却有三个地址
kd> dd e1d54000
e1d54000 e1005000 e1d55000 e1d9e000 00000000
e1d54010 00000000 00000000 00000000 00000000
e1d54020 00000000 00000000 00000000 00000000
e1d54030 00000000 00000000 00000000 00000000
e1d54040 00000000 00000000 00000000 00000000
e1d54050 00000000 00000000 00000000 00000000
e1d54060 00000000 00000000 00000000 00000000
e1d54070 00000000 00000000 00000000 00000000
看了下第三个地址
kd> dd e1d9e000
e1d9e000 00000000 fffffffe 00000000 00000000
e1d9e010 00000000 00001004 00000000 00001008
e1d9e020 00000000 0000100c 8126c991 00000000
e1d9e030 8126c719 00000000 8126b931 00000000
e1d9e040 8126b6b9 00000000 8126a541 00000000
e1d9e050 8126a2c9 00000000 00000000 00001010
e1d9e060 00000000 0000102c 00000000 00001030
e1d9e070 00000000 00001034 81268021 00000000
随便取了一个数值
kd> dt _eprocess 8126c990
ntdll!_EPROCESS
+0x000 Pcb : _KPROCESS
+0x06c ProcessLock : _EX_PUSH_LOCK
+0x070 CreateTime : _LARGE_INTEGER 0x1ca653b`039a2530
+0x078 ExitTime : _LARGE_INTEGER 0x0
+0x080 RundownProtect : _EX_RUNDOWN_REF
+0x084 UniqueProcessId : 0x00001014
+0x088 ActiveProcessLinks : _LIST_ENTRY [ 0x8126b9b8 - 0x8126dde8 ]
+0x090 QuotaUsage : [3] 0x730
+0x09c QuotaPeak : [3] 0x838
。。。。。。。。。。。。。。。。。。。。
+0x168 Filler : 0
+0x170 Session : 0xf9ede000
+0x174 ImageFileName : [16] "INSTDRV (2).EXE"
没有问题,得到了大于pid 4096 的进程信息
于是我的代码写成了这样,很纠结
1 VOID EnumProcess()
2 {
3 //详见http://bbs.pediy.com/showthread.php?t=90449&highlight=pspcidtable
4 ULONG HandleTable = *(ULONG *)PspCidTable;
5 ULONG TableCode = *(ULONG *)HandleTable;
6 //取最后两位
7 ULONG flag = TableCode & 3;
8 //后两位清零
9 TableCode &= 0xfffffffc;
10 //_asm int 3
11 switch(flag)
12 {
13 case 0:
14 {
15 EnumProcessFromLevel0(TableCode);
16 break;
17 }
18 case 1:
19 {
20 for (int i = 0;*(ULONG *)(TableCode+i) != 0;i+=4)
21 {
22 EnumProcessFromLevel0(*(ULONG *)(TableCode+i));
23 }
24 break;
25 }
26 case 2:
27 {
28 // EnumProcessFromLevel0(*(ULONG *)TableCode);
29 // EnumProcessFromLevel0(*(ULONG *)(TableCode+4));
30 // EnumProcessFromLevel0(*(ULONG *)(TableCode+8));
31 //三层表的情况没有实现,因为很难用到,一直没在虚拟机中测试出这种情况
32 PsTerminateSystemThread(STATUS_SUCCESS);
33 break;
34 }
35 }
36
43 }
38 VOID EnumProcessFromLevel0(ULONG uBase)
39 {
40 ULONG pepro;
41
42 for (int i=0;i<0x800;i+=4)
43 {
44 if (*(ULONG *)uBase == 0)
45 {
46 uBase+=8;
47 continue;
48 }
49 //-1
50 pepro = (*(ULONG *)uBase) & 0xfffffff8;
51 if ((*PsProcessType) == *(POBJECT_TYPE *)(pepro-0x10))
52 {
53 DbgPrint("process: %s- PID:%d\n",(pepro+0x174),*(ULONG *)(pepro+0x84));
54 }
55
56 uBase+=8;
57 }
58 }
59