在SnipeSword.sys中有一个用于枚举系统进程的代码,比较强悍,看看代码就知道了.呵....
.text:00010E84 ; int __stdcall SS_AtachProcAndGetInfo(PVOID ppi)
.text:00010E84 SS_AtachProcAndGetInfo proc near
.text:00010E84
.text:00010E84 varPi = dword ptr -21Ch
.text:00010E84 ustrLength = dword ptr -218h
.text:00010E84 var_ppi = dword ptr -214h
.text:00010E84 var_210 = dword ptr -210h
.text:00010E84 pEprocess = dword ptr -4
.text:00010E84 ppi = dword ptr 8
.text:00010E84
.text:00010E84 000 55 push ebp
.text:00010E85 004 8B EC mov ebp, esp
.text:00010E87 004 81 C4 E4 FD FF FF add esp, 0FFFFFDE4h
.text:00010E8D 220 56 push esi
.text:00010E8E 224 57 push edi
.text:00010E8F 228 53 push ebx
.text:00010E90 22C 8B 7D 08 mov edi, [ebp+ppi]
.text:00010E93 22C 89 BD EC FD FF FF mov [ebp+var_ppi], edi
.text:00010E99 22C 33 DB xor ebx, ebx
.text:00010E9B 22C E9 F9 01 00 00 jmp loc_11099 ; 跳去判断EBX的值,小于4E1Ch则继续
.text:00010E9B ; 只是EBX已经清空,所以必然会小于4E1Ch
.text:00010EA0 ; ---------------------------------------------------------------------------
.text:00010EA0
.text:00010EA0 loc_10EA0:
.text:00010EA0 22C 8D 45 FC lea eax, [ebp+pEprocess]
.text:00010EA3 22C 50 push eax
.text:00010EA4 230 53 push ebx ; 进程ID
.text:00010EA5 234 E8 AE 64 00 00 call PsLookupProcessByProcessId
.text:00010EAA 234 0B C0 or eax, eax
.text:00010EAC 234 0F 85 E6 01 00 00 jnz lbl_AddEBX ; 如果得不到EPROCESS则继续增加EBX 并试图再次得到EPROCESS
.text:00010EB2 234 FF 75 FC push [ebp+pEprocess] ; VirtualAddress
.text:00010EB5 238 E8 D4 64 00 00 call MmIsAddressValid
.text:00010EBA 234 0B C0 or eax, eax
.text:00010EBC 234 0F 84 CE 01 00 00 jz lbl_DrefObj ; EPROCESS地址不正确,则减少引用后继续
.text:00010EC2 234 FF 75 FC push [ebp+pEprocess] ; 到此的话,EPROCESS就是正确的了
.text:00010EC5 238 E8 F4 64 00 00 call KeAttachProcess ; 切换地址空间
.text:00010ECA 238 8B 75 FC mov esi, [ebp+pEprocess]
.text:00010ECD 238 03 35 88 7C 01 00 add esi, g_ProcIdOffset
.text:00010ED3 238 8B 06 mov eax, [esi] ; EAX = 进程ID
.text:00010ED5 238 3B 85 F0 FD FF FF cmp eax, [ebp+var_210] ; var_210 并没有被初使化
.text:00010EDB 238 0F 84 AA 01 00 00 jz lbl_Detach ; 相等则换回地址空间
.text:00010EE1 238 89 85 F0 FD FF FF mov [ebp+var_210], eax ; 保存进程ID
.text:00010EE7 238 89 07 mov [edi], eax ; 保存到结构体中相应的域
.text:00010EE9 238 83 C7 04 add edi, 4 ; 下一个
.text:00010EEC 238 8B 75 FC mov esi, [ebp+pEprocess]
.text:00010EEF 238 03 35 8C 7C 01 00 add esi, g_InheritedFromUniqueProcId
.text:00010EF5 238 56 push esi ; VirtualAddress
.text:00010EF6 23C E8 93 64 00 00 call MmIsAddressValid
.text:00010EFB 238 8B 06 mov eax, [esi]
.text:00010EFD 238 89 07 mov [edi], eax ; 保存
.text:00010EFF 238 83 C7 04 add edi, 4 ; 下一个
.text:00010F02 238 8B 75 FC mov esi, [ebp+pEprocess]
.text:00010F05 238 03 35 90 7C 01 00 add esi, g_CreateTime
.text:00010F0B 238 8B 06 mov eax, [esi]
.text:00010F0D 238 89 07 mov [edi], eax ; 保存
.text:00010F0F 238 83 C7 04 add edi, 4 ; 下一个
.text:00010F12 238 83 C6 04 add esi, 4 ; 保存高4字节 LARGE_INTEGER型
.text:00010F15 238 8B 06 mov eax, [esi]
.text:00010F17 238 89 07 mov [edi], eax
.text:00010F19 238 83 C7 04 add edi, 4 ; 下一个域
.text:00010F1C 238 8B 75 FC mov esi, [ebp+pEprocess]
.text:00010F1F 238 03 35 94 7C 01 00 add esi, g_ExitTime
.text:00010F25 238 8B 06 mov eax, [esi]
.text:00010F27 238 89 07 mov [edi], eax ; 保存
.text:00010F29 238 83 C7 04 add edi, 4 ; 下一个
.text:00010F2C 238 83 C6 04 add esi, 4 ; 同上
.text:00010F2F 238 8B 06 mov eax, [esi]
.text:00010F31 238 89 07 mov [edi], eax
.text:00010F33 238 83 C7 04 add edi, 4 ; 下一个
.text:00010F36 238 83 FB 0A cmp ebx, 0Ah
.text:00010F39 238 0F 86 13 01 00 00 jbe lbl_GetName ; 跳去获得进程名称
.text:00010F3F 238 89 BD E4 FD FF FF mov [ebp+varPi], edi
.text:00010F45 238 8B 75 FC mov esi, [ebp+pEprocess]
.text:00010F48 238 03 35 98 7C 01 00 add esi, g_Peb
.text:00010F4E 238 56 push esi ; VirtualAddress
.text:00010F4F 23C E8 3A 64 00 00 call MmIsAddressValid
.text:00010F54 238 0B C0 or eax, eax
.text:00010F56 238 0F 84 D1 00 00 00 jz lbl_GetName2
.text:00010F5C 238 8B 36 mov esi, [esi] ; ESI指向PEB
.text:00010F5E 238 03 35 9C 7C 01 00 add esi, g_ProcessParameters
.text:00010F64 238 56 push esi ; VirtualAddress
.text:00010F65 23C E8 24 64 00 00 call MmIsAddressValid
.text:00010F6A 238 0B C0 or eax, eax
.text:00010F6C 238 0F 84 96 00 00 00 jz lbl_GetName3
.text:00010F72 238 8B 36 mov esi, [esi]
.text:00010F74 238 83 C6 40 add esi, 40h ; CommandLine
.text:00010F77 238 66 8B 06 mov ax, [esi] ; UNICODE_STRING.Length
.text:00010F7A 238 33 C9 xor ecx, ecx
.text:00010F7C 238 0F B7 C8 movzx ecx, ax ; 命令行参数的长度
.text:00010F7F 238 89 0F mov [edi], ecx ; 保存
.text:00010F81 238 83 C7 04 add edi, 4 ; 下一个
.text:00010F84 238 89 8D E8 FD FF FF mov [ebp+ustrLength], ecx
.text:00010F8A 238 83 C6 04 add esi, 4 ; UNICODE_STRING.PBuffer
.text:00010F8D 238 56 push esi ; VirtualAddress
.text:00010F8E 23C E8 FB 63 00 00 call MmIsAddressValid
.text:00010F93 238 0B C0 or eax, eax
.text:00010F95 238 74 4C jz short lbl_GetName4
.text:00010F97 238 8B 36 mov esi, [esi] ; PBuffer的内容
.text:00010F99 238 56 push esi ; VirtualAddress
.text:00010F9A 23C E8 EF 63 00 00 call MmIsAddressValid
.text:00010F9F 238 0B C0 or eax, eax
.text:00010FA1 238 74 18 jz short lbl_GetName5
.text:00010FA3 238 FF B5 E8 FD FF FF push [ebp+ustrLength]
.text:00010FA9 23C 56 push esi ; Buffer
.text:00010FAA 240 57 push edi ; ProcInfo.Buffer
.text:00010FAB 244 E8 6C 63 00 00 call RtlMoveMemory ; 将命令行参数考贝到结构体中
.text:00010FB0 244 03 BD E8 FD FF FF add edi, [ebp+ustrLength] ; 下一个域
.text:00010FB6 244 E9 B4 00 00 00 jmp loc_1106F
.text:00010FBB ; ---------------------------------------------------------------------------
.text:00010FBB
.text:00010FBB lbl_GetName5:
.text:00010FBB 238 8B BD E4 FD FF FF mov edi, [ebp+varPi] ; 居然将一个功能完全相同的函数写了六次,强!!
.text:00010FC1 238 33 C0 xor eax, eax
.text:00010FC3 238 89 07 mov [edi], eax
.text:00010FC5 238 83 C7 04 add edi, 4
.text:00010FC8 238 8B 75 FC mov esi, [ebp+pEprocess]
.text:00010FCB 238 03 35 84 7C 01 00 add esi, g_NameOffset
.text:00010FD1 238 56 push esi ; char *
.text:00010FD2 23C 57 push edi ; char *
.text:00010FD3 240 E8 46 64 00 00 call strcpy
.text:00010FD8 240 83 C4 08 add esp, 8
.text:00010FDB 238 83 C7 10 add edi, 10h
.text:00010FDE 238 E9 8C 00 00 00 jmp loc_1106F
.text:00010FE3 ; ---------------------------------------------------------------------------
.text:00010FE3
.text:00010FE3 lbl_GetName4:
.text:00010FE3 238 8B BD E4 FD FF FF mov edi, [ebp+varPi]
.text:00010FE9 238 33 C0 xor eax, eax
.text:00010FEB 238 89 07 mov [edi], eax
.text:00010FED 238 83 C7 04 add edi, 4
.text:00010FF0 238 8B 75 FC mov esi, [ebp+pEprocess]
.text:00010FF3 238 03 35 84 7C 01 00 add esi, g_NameOffset
.text:00010FF9 238 56 push esi ; char *
.text:00010FFA 23C 57 push edi ; char *
.text:00010FFB 240 E8 1E 64 00 00 call strcpy
.text:00011000 240 83 C4 08 add esp, 8
.text:00011003 238 83 C7 10 add edi, 10h
.text:00011006 238 EB 67 jmp short loc_1106F
.text:00011008 ; ---------------------------------------------------------------------------
.text:00011008
.text:00011008 lbl_GetName3:
.text:00011008 238 8B BD E4 FD FF FF mov edi, [ebp+varPi]
.text:0001100E 238 33 C0 xor eax, eax
.text:00011010 238 89 07 mov [edi], eax
.text:00011012 238 83 C7 04 add edi, 4
.text:00011015 238 8B 75 FC mov esi, [ebp+pEprocess]
.text:00011018 238 03 35 84 7C 01 00 add esi, g_NameOffset
.text:0001101E 238 56 push esi ; char *
.text:0001101F 23C 57 push edi ; char *
.text:00011020 240 E8 F9 63 00 00 call strcpy
.text:00011025 240 83 C4 08 add esp, 8
.text:00011028 238 83 C7 10 add edi, 10h
.text:0001102B 238 EB 42 jmp short loc_1106F
.text:0001102D ; ---------------------------------------------------------------------------
.text:0001102D
.text:0001102D lbl_GetName2:
.text:0001102D 238 8B BD E4 FD FF FF mov edi, [ebp+varPi]
.text:00011033 238 33 C0 xor eax, eax
.text:00011035 238 89 07 mov [edi], eax
.text:00011037 238 83 C7 04 add edi, 4
.text:0001103A 238 8B 75 FC mov esi, [ebp+pEprocess]
.text:0001103D 238 03 35 84 7C 01 00 add esi, g_NameOffset
.text:00011043 238 56 push esi ; char *
.text:00011044 23C 57 push edi ; char *
.text:00011045 240 E8 D4 63 00 00 call strcpy
.text:0001104A 240 83 C4 08 add esp, 8
.text:0001104D 238 83 C7 10 add edi, 10h
.text:00011050 238 EB 1D jmp short loc_1106F
.text:00011052 ; ---------------------------------------------------------------------------
.text:00011052
.text:00011052 lbl_GetName:
.text:00011052 238 33 C0 xor eax, eax
.text:00011054 238 89 07 mov [edi], eax
.text:00011056 238 83 C7 04 add edi, 4
.text:00011059 238 8B 75 FC mov esi, [ebp+pEprocess]
.text:0001105C 238 03 35 84 7C 01 00 add esi, g_NameOffset
.text:00011062 238 56 push esi ; char *
.text:00011063 23C 57 push edi ; char *
.text:00011064 240 E8 B5 63 00 00 call strcpy
.text:00011069 240 83 C4 08 add esp, 8
.text:0001106C 238 83 C7 10 add edi, 10h ; 跳过进程名的长度,来到了下一个域
.text:0001106F
.text:0001106F loc_1106F:
.text:0001106F 238 8B C7 mov eax, edi
.text:00011071 238 2B 85 EC FD FF FF sub eax, [ebp+var_ppi] ; 结构体大小??
.text:00011077 238 83 C0 29 add eax, 29h
.text:0001107A 238 3D 00 20 03 00 cmp eax, 32000h ; 范围
.text:0001107F 238 72 0A jb short lbl_Detach ; 在范围内则继续,否则返回
.text:00011081 238 FF 75 FC push [ebp+pEprocess]
.text:00011084 23C E8 F3 62 00 00 call ObDereferenceObject
.text:00011089 23C EB 1A jmp short lbl_ret
.text:0001108B ; ---------------------------------------------------------------------------
.text:0001108B
.text:0001108B lbl_Detach:
.text:0001108B 238 E8 22 63 00 00 call KeDetachProcess
.text:00011090
.text:00011090 lbl_DrefObj:
.text:00011090 238 FF 75 FC push [ebp+pEprocess]
.text:00011093 23C E8 E4 62 00 00 call ObDereferenceObject
.text:00011098
.text:00011098 lbl_AddEBX:
.text:00011098 23C 43 inc ebx
.text:00011099
.text:00011099 loc_11099:
.text:00011099 23C 81 FB 1C 4E 00 00 cmp ebx, 4E1Ch
.text:0001109F 23C 0F 82 FB FD FF FF jb loc_10EA0
.text:000110A5
.text:000110A5 lbl_ret:
.text:000110A5 23C 33 C0 xor eax, eax
.text:000110A7 23C 5B pop ebx
.text:000110A8 238 5F pop edi
.text:000110A9 234 5E pop esi
.text:000110AA 230 C9 leave
.text:000110AB 000 C2 04 00 retn 4
.text:000110AB SS_AtachProcAndGetInfo endp
它假定从0 到4E1Ch范围内的任何数值都可能为进程ID,并试图去获取进程的EPROCESS如失败则跳过以继续
只是不知会不会还有漏网之鱼呢 :)