首页
社区
课程
招聘
[解决]晕啊,pspCidTable中的Object[解决代码见四楼]
发表于: 2009-1-6 15:56 6011

[解决]晕啊,pspCidTable中的Object[解决代码见四楼]

2009-1-6 15:56
6011
搞了一个下午,单独打出一个进程的信息还是很容易的,但是如果是穷举,系统就崩溃了。我对ObReferenceXXX系列的函数不是很了解,麻烦大侠指点一下。

ULONG GetPspCidTable()
{

    ULONG pAddr;
    ULONG Len;
    PUCHAR opcode;
    ULONG ulFunc = (ULONG)PsLookupProcessByProcessId;

    __try
    {
       //
       //如果是调试模式,需要计算一下真实位置
       //用来校正jmp thunk
       //

       if(*(PUSHORT)PsLookupProcessByProcessId==0x25ff)
       {
           ulFunc = **(ULONG**)((ULONG)PsLookupProcessByProcessId+2);
       }

       //DbgPrint("[My1st] ulFunc: 0X&08X\n", ulFunc);
       for(pAddr=ulFunc;
           pAddr<ulFunc+0x60;
           pAddr+=Len)
       {
           Len = SizeOfCode((PUCHAR)pAddr, &opcode);
           if(!Len)
           {
              break;
           }

           if( *(PUSHORT)pAddr==0x35ff && *(PUCHAR)(pAddr+6)==0xe8 )
           {
               return **(ULONG**)(opcode+2);
           }
       }

       return 0;
    }

    __except(1)
    {
       return 0;
    }

}

/*++

通过进程的id,获取进程的EPROCESS结构

--*/

PEPROCESS GetProcessById(ULONG id)
{
    PHANDLE_TABLE pspCidTable;
    ULONG Eprocess;

     //
    //如果查找pspCidTable失败,直接返回NULL
    //

    pspCidTable = (PHANDLE_TABLE)GetPspCidTable();
    if(!pspCidTable)
    {
       return NULL;
    }

    //
    //越界检查
    //

    id &= 0xfffffffc; //忽略id的后两位
    if(id>=pspCidTable->NextHandleNeedingPool)
    {
       return NULL;
    }

    //
    //由于pspCidTable只是一个简单的0级表,所以检索很容易
    //

    Eprocess = *(ULONG*)(pspCidTable->TableCode + id*2) & 0xfffffffc;

    //
    //检查获取的对象是不是EPROCESS
    //

    if(*(UCHAR*)Eprocess==0x03
       && *(ULONG*)(Eprocess+0x1a4)!=0)
       //&& ObReferenceObjectSafe((PVOID)Eprocess))
        //应该就是这里的问题,在WRK中这个代码是有的,windbg反汇编也是有的,但是这个函数却是没有导出的!张皇失措了
    {
       return (PEPROCESS)Eprocess;
    }

    return NULL;
}

/*++
通过线程的id,获取进程的ETHREAD结构
--*/
PETHREAD GetThreadById(ULONG id)
{
    PHANDLE_TABLE pspCidTable;
    ULONG Ethread;

    //
    //如果查找pspCidTable失败,直接返回NULL
    //

    pspCidTable = (PHANDLE_TABLE)GetPspCidTable();
    if(!pspCidTable)
    {
       return NULL;
    }

    //
    //越界检查
    //

    id &= 0xfffffffc; //忽略id的后两位
    if(id>=pspCidTable->NextHandleNeedingPool)
    {
       return NULL;
    }

    //
    //由于pspCidTable只是一个简单的0级表,所以检索很容易
    //
    Ethread = *(ULONG*)(pspCidTable->TableCode + id*2) & 0xfffffffc;

    //
    //检查获取的对象是不是ETHREAD
    //

     if(*(UCHAR*)Ethread==0x06
       && *(ULONG*)(Ethread+0x244)!=0)
       //&& ObReferenceObjectSafe((PVOID)Ethread))
    {
       return (PETHREAD)Ethread;
    }

    return NULL;
}

/*++
通过id,获取对象的指针
--*/
ULONG GetObjectById(ULONG id)
{
    PHANDLE_TABLE pspCidTable;
    ULONG Eobject;

    //
    //如果查找pspCidTable失败,直接返回NULL
    //

    pspCidTable = (PHANDLE_TABLE)GetPspCidTable();
    if(!pspCidTable)
    {
       return 0;
    }

    //
    //越界检查
    //
    id &= 0xfffffffc; //忽略id的后两位
    if(id>=pspCidTable->NextHandleNeedingPool)
    {
       return 0;
    }

    //
    //由于pspCidTable只是一个简单的0级表,所以检索很容易
    //
    Eobject = *(ULONG*)(pspCidTable->TableCode + id*2) & 0xfffffffc;

    //if(ObReferenceObjectSafe((PVOID)Eobject))
    //{
    return Eobject;
    //}

    return 0;

}

void DisplayProcessNameById(ULONG id)//这个工作还算正常,不过我估计也不稳定
{
    ULONG ulProcessName;
    ULONG ulProcess;

    ulProcess = (ULONG)GetProcessById(id);
    if(!ulProcess)
    {
       return;
    }

    ulProcessName = ulProcess + 0x174; //Windows XP
    dprintf("[My1st] %s\n", (PUCHAR)ulProcessName);
}

void EnumerateProcesses()//这个工作异常
{
    ULONG ulIte;

    for(ulIte=1;ulIte<0x40;ulIte++)
    {
       DisplayProcessNameById(ulIte<<2);
    }
}

心寒到此,期待解决。

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

收藏
免费 0
支持
分享
最新回复 (5)
雪    币: 178
活跃值: (10)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
2
那个ksbinsword的不就是pspCidTable遍历进程的么,可以去看看
2009-1-6 16:26
0
雪    币: 247
活跃值: (10)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
3
靠,怎么忘记了这个,谢谢,好好看看~~~
2009-1-6 17:48
0
雪    币: 247
活跃值: (10)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
4
ULONG GetPspCidTable()
/*++
获取系统中未导出的pspCidTable
--*/
{
        ULONG pAddr;
        ULONG Len;
        PUCHAR opcode;
        ULONG ulFunc = (ULONG)PsLookupProcessByProcessId;
       
       
        __try
        {
                //
                //如果是调试模式,需要计算一下真实位置
                //用来校正jmp thunk
                //
               
                if(*(PUSHORT)PsLookupProcessByProcessId==0x25ff)
                {
                        ulFunc = **(ULONG**)((ULONG)PsLookupProcessByProcessId+2);
                }
               
                //DbgPrint("[My1st] ulFunc: 0X&08X\n", ulFunc);
                for(pAddr=ulFunc;
                pAddr<ulFunc+0x60;
                pAddr+=Len)
                {
                        Len = SizeOfCode((PUCHAR)pAddr, &opcode);
                       
                        if(!Len)
                        {
                                break;
                        }
                       
                        if( *(PUSHORT)pAddr==0x35ff && *(PUCHAR)(pAddr+6)==0xe8 )
                        {
                                return **(ULONG**)(opcode+2);
                        }
                }
               
                return 0;
        }
        __except(1)
        {
                return 0;
        }
}

/*++
通过进程的id,获取进程的EPROCESS结构
--*/
PEPROCESS GetProcessById(ULONG id)
{
        PHANDLE_TABLE pspCidTable;
        ULONG Eprocess;
        ULONG* pEprocess;

        //
        //如果查找pspCidTable失败,直接返回NULL
        //

        pspCidTable = (PHANDLE_TABLE)GetPspCidTable();
        if(!pspCidTable)
        {
                return NULL;
        }

        //
        //越界检查
        //

        id &= 0xfffffffc; //忽略id的后两位
        if(id>=pspCidTable->NextHandleNeedingPool)
        {
                return NULL;
        }

        //
        //由于pspCidTable只是一个简单的0级表,所以检索很容易
        //

        pEprocess = (ULONG*)(pspCidTable->TableCode + id*2);
        if(!MmIsAddressValid(pEprocess))   //检查一下地址的有效性,参考KsBinSword的源代码,原来在内核中检查地址的函数是这个
        {                                                                               //同时感谢2楼
                return NULL;
        }
        Eprocess = (*pEprocess) & 0xfffffffc;
        if(!MmIsAddressValid((PVOID)Eprocess))
        {
                return NULL;
        }

        //
        //检查获取的对象是不是EPROCESS
        //

        if(*(UCHAR*)Eprocess==0x03
                && *(ULONG*)(Eprocess+0x1a4)!=0)
                //&& ObReferenceObjectSafe((PVOID)Eprocess))
        {
                return (PEPROCESS)Eprocess;
        }

        return NULL;
}

/*++
通过线程的id,获取进程的ETHREAD结构
--*/
PETHREAD GetThreadById(ULONG id)
{
        PHANDLE_TABLE pspCidTable;
        ULONG Ethread;
        ULONG* pEthread;

        //
        //如果查找pspCidTable失败,直接返回NULL
        //

        pspCidTable = (PHANDLE_TABLE)GetPspCidTable();
        if(!pspCidTable)
        {
                return NULL;
        }

        //
        //越界检查
        //

        id &= 0xfffffffc; //忽略id的后两位
        if(id>=pspCidTable->NextHandleNeedingPool)
        {
                return NULL;
        }

        //
        //由于pspCidTable只是一个简单的0级表,所以检索很容易
        //

        pEthread = (ULONG*)((pspCidTable->TableCode + id*2) & 0xfffffffc);
        if(!MmIsAddressValid(pEthread))
        {
                return NULL;
        }
        Ethread = (*pEthread) & 0xfffffffc;
        if(!MmIsAddressValid((PVOID)Ethread))
        {
                return NULL;
        }

        //
        //检查获取的对象是不是ETHREAD
        //

        if(*(UCHAR*)Ethread==0x06
                && *(ULONG*)(Ethread+0x244)!=0)
                //&& ObReferenceObjectSafe((PVOID)Ethread))
        {
                return (PETHREAD)Ethread;
        }

        return NULL;
}

/*++
通过id,获取对象的指针
--*/
ULONG GetObjectById(ULONG id)
{
        PHANDLE_TABLE pspCidTable;
        ULONG Eobject;
        ULONG* pEobject;

        //
        //如果查找pspCidTable失败,直接返回NULL
        //

        pspCidTable = (PHANDLE_TABLE)GetPspCidTable();
        if(!pspCidTable)
        {
                return 0;
        }

        //
        //越界检查
        //

        id &= 0xfffffffc; //忽略id的后两位
        if(id>=pspCidTable->NextHandleNeedingPool)
        {
                return 0;
        }

        //
        //由于pspCidTable只是一个简单的0级表,所以检索很容易
        //

        pEobject = (ULONG*)((pspCidTable->TableCode + id*2) & 0xfffffffc);
        if(!MmIsAddressValid(pEobject))
        {
                return 0;
        }
        Eobject = (*pEobject) & 0xfffffffc;
        if(!MmIsAddressValid((PVOID)Eobject))
        {
                return 0;
        }

        //if(ObReferenceObjectSafe((PVOID)Eobject))
        //{
                return Eobject;
        //}

        return 0;
}

void DisplayProcessNameById(ULONG id)
{
        ULONG ulProcessName;
        ULONG ulProcess;

        ulProcess = (ULONG)GetProcessById(id);
        if(!ulProcess)
        {
                return;
        }

        ulProcessName = ulProcess + 0x174; //Windows XP
        dprintf("[My1st] %s\n", (PUCHAR)ulProcessName);
}

void EnumerateProcesses()
{
        ULONG ulIte;

        for(ulIte=1;ulIte<0x800;ulIte++)
        {
                DisplayProcessNameById(ulIte<<2);
        }
}

效果如下:
[My1st] DriverEntry
[My1st] System
[My1st] VMwareUser.exe
[My1st] ctfmon.exe
[My1st] wscntfy.exe
[My1st] smss.exe
[My1st] csrss.exe
[My1st] winlogon.exe
[My1st] services.exe
[My1st] lsass.exe
[My1st] svchost.exe
[My1st] svchost.exe
[My1st] svchost.exe
[My1st] svchost.exe
[My1st] svchost.exe
[My1st] cmd.exe
[My1st] conime.exe
[My1st] explorer.exe
[My1st] spoolsv.exe
[My1st] net.exe
[My1st] net1.exe
[My1st] VMwareService.e
[My1st] alg.exe
[My1st] VMwareTray.exe
2009-1-10 13:46
0
雪    币: 364
活跃值: (152)
能力值: ( LV12,RANK:450 )
在线值:
发帖
回帖
粉丝
5
呵呵,很高兴kbs的代码能对你有用~~  不用二楼的马甲算了。
2009-1-10 15:13
0
雪    币: 247
活跃值: (10)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
6
Orz, 呵呵,大侠还是真身的好啊~~~
2009-1-10 17:22
0
游客
登录 | 注册 方可回帖
返回
//