首页
社区
课程
招聘
[求助]通过EPROCESS枚举进程
发表于: 2009-2-22 16:54 5591

[求助]通过EPROCESS枚举进程

2009-2-22 16:54
5591
网上的一段代码 通过内存搜索EPROCESS来枚举进程
在我的xp sp2系统上测试 只能枚举出三个进程 这是为什么?

关键代码如下:

VOID searchprocess(void)
{
    ULONG    i;
    ULONG    result;
    
    for (i = 0x80000000 ;i<0x90000000;i+=4){
        result = validpage(i);
        if (result == VALID){
            if (*(PULONG)i == 0x7ffdf000){
                if(IsARealProcess(i)){
                    DbgPrint("EPROCESS: 0x%x  ",i-PEB_OFFSET);
                    getname(i);
                }
            }
        }
        else if(result == PTE_INVALID){
            i -=4;
            i += 0x1000;//4k
        }
        else{
            i-=4;
            i+= 0x400000;//4mb
        }
        
    }

    for (i = 0xf0000000 ;i<0xffbe0000;i+=4){
        result = validpage(i);
        if (result == VALID){
            if (*(PULONG)i == 0x7ffdf000){
                if(IsARealProcess(i)){
                    DbgPrint("EPROCESS: 0x%x  ",i-PEB_OFFSET);
                    getname(i);
                }
            }
        }
        else if(result == PTE_INVALID){
            i -=4;
            i += 0x1000;//4k
        }
        else{
            i-=4;
            i+= 0x400000;//4mb
        }        
    }

    DbgPrint("searching finish \n");
}
//--------------------------------------------------------------------
VOID getname(ULONG Addr)
{
    DbgPrint("process name: %s\n",(PCHAR)(Addr-PEB_OFFSET+EPROCESS_NAME_OFFSET));
}
//--------------------------------------------------------------------
ULONG validpage(ULONG Addr)
{
    ULONG    pte;
    ULONG    pde;
    
    pde = 0xc0300000 + (Addr>>22)*4;
    if((*(PULONG)pde & 0x1) != 0){
        //lArge pAge
        if((*(PULONG)pde & 0x80) != 0){
            return VALID;
        }
        pte = 0xc0000000 + (Addr>>12)*4;
        if((*(PULONG)pte & 0x1) != 0){
            return VALID;
        }
        else{
            return PTE_INVALID;
        }
    }
    return PDE_INVALID;
}
//--------------------------------------------------------------------
BOOLEAN IsARealProcess(ULONG i)
{
    NTSTATUS            status;
    PUNICODE_STRING        pUnicode;
    UNICODE_STRING        Process;
    ULONG                pObjectType;
    ULONG                pObjectTypeProcess;
    
    
    pObjectTypeProcess = *(PULONG)((ULONG)PsGetCurrentProcess() -OBJECT_HEADER_SIZE +OBJECT_TYPE_OFFSET);
    if (validpage(i-PEB_OFFSET) != VALID){
        return FALSE;
    }
    
    if (validpage(i-PEB_OFFSET - OBJECT_HEADER_SIZE + OBJECT_TYPE_OFFSET) == VALID){
        pObjectType = *(PULONG)(i-PEB_OFFSET - OBJECT_HEADER_SIZE + OBJECT_TYPE_OFFSET);
    }
    else{
        return FALSE;
    }
    
    if(pObjectTypeProcess == pObjectType){        
        return TRUE;
    }
    return FALSE;
    
}


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (7)
雪    币: 722
活跃值: (123)
能力值: ( LV12,RANK:300 )
在线值:
发帖
回帖
粉丝
2
*(PULONG)i == 0x7ffdf000
以上代码判断一个进程的关键是在这里,即只有当进程的PEB结构指针是0x7ffdf000你才能找到它。

但是在XP SP2系统下,进程PEB结构位置是不定的,并不固定为0x7ffdf000。

你可以自己在windbg里试一试看看系统当前所有进程的PEB就会发现这个问题了。
如在我的XP SP3下,我刚刚试了一下:

lkd> !process 0 0
**** NT ACTIVE PROCESS DUMP ****
PROCESS 855b6830  SessionId: none  Cid: 0004    Peb: 00000000  ParentCid: 0000
    DirBase: 05990020  ObjectTable: e1003df8  HandleCount: 437.
    Image: System

PROCESS 84c4d020  SessionId: none  Cid: 046c    Peb: 7ffde000  ParentCid: 0004
    DirBase: 05990040  ObjectTable: e100dc10  HandleCount:  19.
    Image: smss.exe

PROCESS 84bfb020  SessionId: 0  Cid: 04b0    Peb: 7ffd8000  ParentCid: 046c
    DirBase: 05990060  ObjectTable: e188da08  HandleCount: 702.
    Image: csrss.exe

PROCESS 84bf2a90  SessionId: 0  Cid: 04cc    Peb: 7ffde000  ParentCid: 046c
    DirBase: 05990080  ObjectTable: e188f170  HandleCount: 526.
    Image: winlogon.exe

PROCESS 84b2bc10  SessionId: 0  Cid: 04f8    Peb: 7ffd4000  ParentCid: 04cc
    DirBase: 059900a0  ObjectTable: e1d60518  HandleCount: 310.
    Image: SERVICES.EXE

PROCESS 84b363c0  SessionId: 0  Cid: 0504    Peb: 7ffdd000  ParentCid: 04cc
    DirBase: 059900c0  ObjectTable: e223c248  HandleCount: 477.
    Image: LSASS.EXE

PROCESS 84b5eda0  SessionId: 0  Cid: 05c0    Peb: 7ffda000  ParentCid: 04f8
    DirBase: 059900e0  ObjectTable: e236af00  HandleCount:  99.
    Image: Ati2evxx.exe

PROCESS 84b59b28  SessionId: 0  Cid: 05e0    Peb: 7ffd7000  ParentCid: 04f8
    DirBase: 05990100  ObjectTable: e23686c8  HandleCount: 196.
    Image: SVCHOST.EXE

PROCESS 846313b0  SessionId: 0  Cid: 063c    Peb: 7ffd5000  ParentCid: 04f8
    DirBase: 05990140  ObjectTable: e19a3c08  HandleCount: 317.
    Image: SVCHOST.EXE
(以下省略类似的条目)

你可以看到它们的PEB并不都是0x7ffdf000,这也就解释了你只能搜到一部分进程结构。

好像哪本书上说的XP SP2开始PEB结构位置才是不定的,在此之前好像就是固定为0x7ffdf000的,不知道我有没有记错。
2009-2-22 17:30
0
雪    币: 722
活跃值: (123)
能力值: ( LV12,RANK:300 )
在线值:
发帖
回帖
粉丝
3
2009-2-22 17:41
0
雪    币: 222
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
非常感谢
2009-2-22 18:19
0
雪    币: 222
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
这里还有一个问题
我把程序修改了一下 如下
VOID searchprocess(void)
{
    ULONG    i;
    ULONG    res;
    
    for (i = 0x80000000; i < 0x90000000; i += 4)
	{
        res = validpage(i);
        if (res == VALID)
		{
			DbgPrint("%x : %x\n", i, *(PULONG)i);
            //if (*(PULONG)i == 0x7ffdf000)
			if (*(PUCHAR)(i+0) == 0x00 &&
				*(PUCHAR)(i+2) == 0xfd &&
				*(PUCHAR)(i+3) == 0x7f &&
				(*(PUCHAR)(i+1) & 0x0f) == 0)
			{
                if(IsARealProcess(i))
				{
                    DbgPrint("EPROCESS: 0x%x  ",i-PEB_OFFSET);
                    getname(i);
                }
            }
        }
        else if(res == PTE_INVALID)
		{
			DbgPrint("%x  pte_invalid.\n", i);
            i -= 4;
            i += 0x1000;//4k
        }
        else
		{
			DbgPrint("%x pde_invalid.\n", i);
            i -= 4;
            i += 0x400000;//4mb
        }
        
    }

    for (i = 0xf0000000; i < 0xffbe0000; i += 4)
	{
        res = validpage(i);
        if (res == VALID)
		{
            //if (*(PULONG)i == 0x7ffdf000)
			if (*(PUCHAR)(i+0) == 0x00 &&
				*(PUCHAR)(i+2) == 0xfd &&
				*(PUCHAR)(i+3) == 0x7f &&
				(*(PUCHAR)(i+1) & 0x0f) == 0)
			{
                if(IsARealProcess(i))
				{
                    DbgPrint("EPROCESS: 0x%x  ",i-PEB_OFFSET);
                    getname(i);
                }
            }
        }
        else if(res == PTE_INVALID)
		{
            i -= 4;
            i += 0x1000;//4k
        }
        else
		{
            i -= 4;
            i += 0x400000;//4mb
        }        
    }

    DbgPrint("searching finish \n");
}


在xp sp2的虚拟机中成功的搜索出系统里的进程
可是在我的主机上却没有成功
从80000000到90000000全部显示pde_invalid
这是怎么回事?
2009-2-23 18:51
0
雪    币: 222
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
顶起 ~ 期待解答
2009-2-24 11:05
0
雪    币: 222
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
调了很久 从80000000到90000000还是都显示pde_invalid 为什么呢?
2009-2-24 13:24
0
雪    币: 2
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
windows xp sp2   的页目录是0xc0600000   而且是PAE(物理地址扩展)模式  计算方法有些不同的  2000的     具体请反汇编xp sp2 的涵数MmIsAddressValid()  就比较清楚
2009-2-24 15:55
0
游客
登录 | 注册 方可回帖
返回