通过读取KiWaitInListHead列出隐藏的进程

转载 2006年06月13日 15:50:00

通过读取KiWaitInListHead列出隐藏的进程
/*
有些ROOTKIT通过更改PsActiveProcess链表或相关Native API来隐藏进程.下面这个程序通过直接读取
KiWaitInListHead和KiWaitOutListHead(windows的dispatcher所使用的内核链表),来列出隐藏的进程.
技术细节请参照Jan K. Rutkowski的原文
http://www.blackhat.com/presentations/bh-usa-03/bh-us-03-rutkowski/rutkowski-antirootkit.zip.
原文的示范代码使用驱动来实现,这里使用了/Device/PhysicalMemory.代码很乱,勉强可以工作.这里感谢pjf的代码.
如果有错误的地方请斧正,如果你有更好的idea,与我分享?谢谢!
*/

 

/* code token from Jan K. Rutkowski(jkrutkowski<a>elka.pw.edu.pl) */
/* and pjf (jfpan20000@sina.com)s article */
/* compile under cygwin> gcc -o kps kps.c -I/usr/include/w32api/ddk -lntdll -lntoskrnl */
/* see Jan K. Rutkowskis article for more info. */

/* This tool will list all the procs include those hiden by some rootkit. 2003/10, fantas1a*/

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <ntddk.h>

typedef struct _KLISTER_PROCINFO {
int pid;
char name [18];
} KLISTER_PROCINFO, *PKLISTER_PROCINFO;

PLIST_ENTRY pKiWaitInListHead ;
PLIST_ENTRY pKiWaitOutListHead ;
PLIST_ENTRY pKiDispatcherReadyListHead ;
#define WAITLIST_OFFSET 0x5c // in _KTHREAD

PVOID g_pMapPhysicalMemory = NULL;
HANDLE g_hMPM = NULL;

#define MAX_PROCS 1000
KLISTER_PROCINFO procs[MAX_PROCS];
int nprocs = 0;

PVOID LinearToPhys(PULONG BaseAddress,PVOID addr)
{
ULONG VAddr=(ULONG)addr,PGDE,PTE,PAddr;
PGDE=BaseAddress[VAddr>>22];
if ((PGDE&1)!=0)
{
ULONG tmp=PGDE&0x00000080;
if (tmp!=0)
{
PAddr=(PGDE&0xFFC00000)+(VAddr&0x003FFFFF);
}
else
{
PGDE=(ULONG)MapViewOfFile(g_hMPM, 4, 0, PGDE & 0xfffff000, 0x1000);
PTE=((PULONG)PGDE)[(VAddr&0x003FF000)>>12];
if ((PTE&1)!=0)
{
PAddr=(PTE&0xFFFFF000)+(VAddr&0x00000FFF);
UnmapViewOfFile((PVOID)PGDE);
}
else {
//fprintf(stderr, "LinearToPhys return 0, page not in/r/n");
return 0;
}
}
} else {
//fprintf(stderr, "LinearToPhys return 0, page table not in/r/n");
return 0;
}
//fprintf(stderr, "LinearToPhys return %08x/r/n", PAddr);
return (PVOID)PAddr;
}

ULONG GetData(PVOID addr)
{
ULONG phys=(ULONG)LinearToPhys((PULONG)g_pMapPhysicalMemory,(PVOID)addr);
if(phys==0) return 0;
PULONG tmp=(PULONG)MapViewOfFile(g_hMPM, 4, 0, phys & 0xfffff000, 0x1000);
if (tmp==0) {
exit(-1);
}
ULONG ret=tmp[(phys & 0xFFF)>>2];
UnmapViewOfFile(tmp);
return ret;
}

HANDLE OpenPhysicalMemory()
{
NTSTATUS status;
UNICODE_STRING physmemString;
OBJECT_ATTRIBUTES attributes;

RtlInitUnicodeString( &physmemString, L"//Device//PhysicalMemory" );

attributes.Length = sizeof(OBJECT_ATTRIBUTES);
attributes.RootDirectory = NULL;
attributes.ObjectName = &physmemString;
attributes.Attributes = 0;
attributes.SecurityDescriptor = NULL;
attributes.SecurityQualityOfService = NULL;

status = ZwOpenSection(&g_hMPM,SECTION_MAP_READ,&attributes);


if( !NT_SUCCESS( status ))
{
return NULL;
}

g_pMapPhysicalMemory = MapViewOfFile(
g_hMPM,
4,
0,
0x30000,
0x1000);
if( g_pMapPhysicalMemory == NULL )
{
return NULL;
}

return g_hMPM;
}

void insertProc (int pid, char* name) {
int i;

for (i = 0; i < nprocs; i++)
if (procs.pid == pid) return;

procs [nprocs].pid = pid;
strncpy (procs [nprocs].name, name, 16);
//fprintf(stderr, "%d %s/r/n", pid, name);
nprocs++;

}

PEPROCESS processObject (PETHREAD ethread) {
ULONG p;
p = (ULONG) ethread;
//(PEPROCESS)(ethread->Tcb.ApcState.Process);
p = GetData((PVOID)(p+0x0+0x34+0x10));
return (PEPROCESS)(p);
}

char* processName (PEPROCESS eprocess, char *buf) {
//&eprocess->ImageFileName[0]
ULONG phys=(ULONG)LinearToPhys((PULONG)g_pMapPhysicalMemory,(PVOID)((ULONG)eprocess+0x01fc));
if(phys==0) return 0;
PUCHAR tmp=(PUCHAR)MapViewOfFile(g_hMPM, 4, 0, phys & 0xfffff000, 0x1000);
if (tmp==0) {
return 0;
}
strncpy(buf, &tmp[(phys & 0xFFF)], 16);
UnmapViewOfFile(tmp);

return buf;
}

void listProc()
{
int i;
printf("---- %d process ----/r/n", nprocs);
for(i=0; i<nprocs; i++) {
printf("[+]% 4d %s/r/n", procs.pid, procs.name);
}
}void createProcList () {
int i, j;
char buf1[18];
PVOID obj, p, q, tmp;
PETHREAD pethread=NULL;
ULONG pid;
char *pn;
//fprintf(stderr, "pKiWaitInListHead/r/n");
for (obj = (PVOID)GetData(pKiWaitInListHead);
obj && (obj != pKiWaitInListHead); obj = (PVOID)GetData(obj)) {
pethread = (PETHREAD) (GetData((PVOID)obj) - WAITLIST_OFFSET);
p = processObject(pethread);
pid = GetData((PVOID)((ULONG)pethread + 0x01e0)); //pethread->Cid.UniqueProcess
if(pid==0) {
//fprintf(stderr, "pid is 0/r/n");
break;
}
pn = processName(p, buf1);
if(pn==0) break;
insertProc( pid, pn );
}
//fprintf(stderr, "pKiWaitOutListHead/r/n");
for (obj = (PVOID)GetData(pKiWaitOutListHead);
obj && (obj != pKiWaitOutListHead); obj = (PVOID)GetData(obj)) {
pethread = (PETHREAD) (GetData((PVOID)obj) - WAITLIST_OFFSET);
p = processObject(pethread);
pid = GetData((PVOID)((ULONG)pethread + 0x01e0));
if(pid==0) {
//fprintf(stderr, "pid is 0/r/n");
break;
}
pn = processName(p, buf1);
if(pn==0) break;
insertProc( pid, pn );
}
/*
fprintf(stderr, "pKiDispatcherReadyListHead/r/n");
for (i = 0; i < 32; i++)
for (obj = (PVOID)GetData((PVOID)(&pKiDispatcherReadyListHead));
obj && (obj != &pKiDispatcherReadyListHead);
obj = (PVOID)GetData(obj)) {
pethread = (PETHREAD) (GetData((PVOID)obj) - WAITLIST_OFFSET);
p = processObject(pethread);
pid = GetData((PVOID)((ULONG)pethread + 0x01e0));
if(pid==0) {
fprintf(stderr, "pid is 0/r/n");
break;
}
pn = processName(p, buf1);
if(pn==0) break;
insertProc( pid, pn );

}
*/
}

int main(int argc, char **argv) {

if (OpenPhysicalMemory()==0)
{
printf("OpenPhysicalMemory failed/r/n");
return -1;
}
pKiWaitInListHead = (PLIST_ENTRY) 0x80482258; //under win2k + sp4en
pKiWaitOutListHead = (PLIST_ENTRY) 0x80482808;
pKiDispatcherReadyListHead = (PLIST_ENTRY) 0x804822e0;
//fprintf(stderr, "0x%08x, 0x%08x/r/n", (ULONG)pKiWaitInListHead, (ULONG)pKiWaitOutListHead);

createProcList();
listProc();
UnmapViewOfFile(g_pMapPhysicalMemory);
CloseHandle(g_hMPM);

return(0);
}

from: http://th3ee.blogchina.com/271213.html 

相关文章推荐

WRK列出进程和线程的详情

typedef struct _MyThread{ int sid; char*name; int cidp[100][100]; int cidt[100][100]; int pid[1...

WinCE下的系统进程列出程序

  • 2004年06月28日 00:00
  • 17KB
  • 下载

使用CreateToolHelp32Snapshot函数列出所有进程

列出所有进程,需要调用CreateToolHelp32Snapshot函数先得到系统进程快照的句柄,函数包含在头中。函数的具体格式如下: HANDLE_WINAPI CreateToolHelp32...

隐藏进程小工具

  • 2014年10月03日 12:23
  • 25KB
  • 下载

专用隐藏进程工具

  • 2013年12月22日 17:31
  • 216KB
  • 下载

linux命令 ps 列出进程

Linux中的ps命令是Process Status的缩写。ps命令用来列出系统中当前运行的那些进程。 如果想对进程时间监控,应该用 top 工具。 kill 命令用于杀死进程。 ps工...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:通过读取KiWaitInListHead列出隐藏的进程
举报原因:
原因补充:

(最多只允许输入30个字)