首页
社区
课程
招聘
[讨论]关于System Idle Process 的一点问题
发表于: 2008-1-23 23:15 8168

[讨论]关于System Idle Process 的一点问题

2008-1-23 23:15
8168
今天在读书的时候<<ROOTKITS Windows内核的安全防护>>时候看到了关于进程隐藏的
一些内容,感觉跟不错,就用他的思想和提供的部分代码代码,综合了综合试验一下,不过我不是做进程的隐藏只是用他的思路和实例代码来实现了一个“枚举系统的所以进程”的功能,可是在枚举完成的时候发现了一个小问题,
出现了一个这样的信息:
第 34 个进程 ImageName   =    , PID   =   0x80882080

正常的信息因该是:
第 0 个进程 ImageName   =   smss.exe , PID   =   0x270
第 1 个进程 ImageName   =   csrss.exe , PID   =   0x2a8
...

第 32 个进程 ImageName   =   hh.exe , PID   =   0xe78
第 33 个进程 ImageName   =   dexplore.exe , PID   =   0xcd4

我感觉这个奇怪的信息应该是:Idle Process 这个虚拟进程,用windbg看了一下,的却是。
lkd> !process 0x80882080
PROCESS 80882080  SessionId: none  Cid: 0000    Peb: 00000000  ParentCid: 0000
    DirBase: 00039000  ObjectTable: e1001c28  HandleCount: 932.
    Image: Idle
    VadRoot 00000000 Vads 0 Clone 0 Private 0. Modified 0. Locked 0.
    DeviceMap 00000000
    Token                             e1000790
    ElapsedTime                       00:00:00.000
    UserTime                          00:00:00.000
    KernelTime                        00:21:18.593
    QuotaPoolUsage[PagedPool]         0
    QuotaPoolUsage[NonPagedPool]      0
    Working Set Sizes (now,min,max)  (4, 50, 450) (16KB, 200KB, 1800KB)
    PeakWorkingSetSize                0
    VirtualSize                       0 Mb
    PeakVirtualSize                   0 Mb
    PageFaultCount                    0
    MemoryPriority                    BACKGROUND
    BasePriority                      0
    CommitCharge                      0

虽然是一个虚拟的进程,我为什么得不到他的名字呢??
现在的是我想在我的程序里面能判断出来是这个进程的话显示的时候做一下处理:
pList_active_proc=(LIST_ENTRY*)(eproc+FLINKOFFSET);
                        eproc=(DWORD)pList_active_proc->Flink;
                        eproc-=FLINKOFFSET;                       
                        CurrentPID=*((int*)(eproc+PIDOFFSET));
                        if(!(CurrentPID & 0xf0000000))
                        {
        DbgPrint("第 %d 个进程 ImageName   =   %s , PID   =   0x%x\n",nCount,(char*)(eproc+ImageOffset),CurrentPID);
      }
      else
      {
        DbgPrint("第 %d 个进程 ImageName   =   %S , PID   =   0x%x\n",nCount,L"[System Idle Process]",0);
      }

上面是我自己写的,很牵强 感觉不好,不知大家有没有好的办法。
/***************************************************************/
一下为我的测试程序代码
/***************************************************************/
#ifdef __cplusplus
extern "C"
{
#endif
#include "ntddk.h"
typedef unsigned long       DWORD;

VOID
xxDriverUnload(IN PDRIVER_OBJECT DriverObject);

VOID
EnumPID();

DWORD
GetImageOffset(DWORD PID);

#ifdef __cplusplus
}
extern "C"
#endif

NTSTATUS
DriverEntry(IN PDRIVER_OBJECT DriverObject,
                        IN PUNICODE_STRING RegistryPath)
{
        NTSTATUS ntStatus=STATUS_SUCCESS;
        ULONG i=0;

        DbgPrint(__TIME__ __FILE__"  >>> DriverEntry function...\n");

        DriverObject->DriverUnload=xxDriverUnload;
        EnumPID();
        return ntStatus;
}

VOID
xxDriverUnload(IN PDRIVER_OBJECT DriverObject)
{
        DbgPrint(__TIME__ __FILE__"  >>> xxDriverUnload function...\n");
                return;

}

VOID
EnumPID()
{
        DWORD eproc=0x00000000;
        int CurrentPID;
        int StartPID;
        int nCount=0;
        PLIST_ENTRY pList_active_proc;
        DWORD PIDOFFSET=0x84;
        DWORD FLINKOFFSET=0x88;
        DWORD ImageOffset=0x0000;
        DWORD oldeproc=0x00000000;

        eproc=(DWORD)PsGetCurrentProcess();
        StartPID=*((int*)(eproc+PIDOFFSET));
        CurrentPID=StartPID;
       
        DbgPrint(__TIME__"  >> CurrentPID=0x%x\n",CurrentPID);
  ImageOffset=GetImageOffset(eproc);
        while(1)
        {
                if((nCount>=1) && (StartPID == CurrentPID))
                {
                        return;
                }
                else
                {
               
                        pList_active_proc=(LIST_ENTRY*)(eproc+FLINKOFFSET);
                        eproc=(DWORD)pList_active_proc->Flink;
                        eproc-=FLINKOFFSET;                       
                        CurrentPID=*((int*)(eproc+PIDOFFSET));
                        if(!(CurrentPID & 0xf0000000))
                        {
        DbgPrint("第 %d 个进程 ImageName   =   %s , PID   =   0x%x\n",nCount,(char*)(eproc+ImageOffset),CurrentPID);
      }
      else
      {
        DbgPrint("第 %d 个进程 ImageName   =   %S , PID   =   0x%x\n",nCount,L"[System Idle Process]",0);
      }

                        nCount++;
                }
        }

}

DWORD
GetImageOffset(DWORD PID)
{
  DWORD offset=0x0000;
  ULONG i=0;
  for(i=0;i<PAGE_SIZE;i++)
  {
    if(!strncmp("System",(PCHAR)(PID+i),strlen("System")))
    {
      return i;
    }
  }
  return offset;
}

/************************************************/
sources文件内容
/************************************************/
TARGETNAME=GetPID
TARGETPATH=obj
TARGETTYPE=DRIVER

SOURCES                =        GetPID.cpp

/************************************************/
makefile文件内容
/************************************************/
#
# DO NOT EDIT THIS FILE!!!  Edit .\sources. if you want to add a new source
# file to this component.  This file merely indirects to the real make file
# that is shared by all the driver components of the Windows NT DDK
#

!INCLUDE $(NTMAKEENV)\makefile.def

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

收藏
免费 0
支持
分享
最新回复 (18)
雪    币: 709
活跃值: (2420)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
2
PspInitPhase0中,创建系统进程时,顺便为IDLE Process赋值了

strcpy((char *) &PsIdleProcess->ImageFileName[0], "Idle");

应该能枚举出来的呀~
2008-1-24 03:22
0
雪    币: 66
活跃值: (16)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
3
if(!(CurrentPID & 0xf0000000))

idle的peprocess中pid=0才对。

PID   =   0x80882080本身就没有参考价值
2008-1-24 04:43
0
雪    币: 223
活跃值: (10)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
4
在我的系统上我用windbg,显示idle的ERPOCESS的内容,
lkd> dt _eprocess 0x80889650
.....
+0x084 UniqueProcessId  : 0x80882080
+0x088 ActiveProcessLinks : _LIST_ENTRY [ 0x82fbb678 - 0x827406a8 ]
.....
+0x174 ImageFileName    : [16]  "???"
......

可见0x80882080 这个数值并非没有意义,至于他为什么会使这样的一个数字,估计是不是和他自身有关(因为他不是系统真正的进程是OS虚拟出来的为了和一般的进程区分,我是瞎猜的)

相同的方法我在显示不同的进程的EPROCESS的时候得到的内容就会是我们想要的。

lkd> dt _eprocess 0x82baf998
....
+0x084 UniqueProcessId  : 0x0000029c
+0x088 ActiveProcessLinks : _LIST_ENTRY [ 0x829d5e28 - 0x82b630b8 ]
....
+0x174 ImageFileName    : [16]  "360tray.exe"
....

所以我估计不是程序的问题,是进程自身的特点的问题。

大家有什么看法欢迎交流!!!
2008-1-24 10:41
0
雪    币: 66
活跃值: (16)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
5
你输入dd PsIdleProcess L 1然后把得到的数值跟0x80889650比较,如果相等就真的有意思了
2008-1-24 14:45
0
雪    币: 223
活跃值: (10)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
6
谢谢大家的参与。
我看了一篇文章(http://www.5iaspx.com/vcnet/JIURL-WanWan-Win2k-JinChengXianChengPian-EPROCESS-oymh02454_2.html)不知道他说的是不是符合WINXP。
假如说的是队的,哪我在枚举进程的时候出来的那个家伙是什么东西?
为什么我在windbg中的操作会处来这样的结果:
lkd> !process 0x80882080
PROCESS 80882080  SessionId: none  Cid: 0000    Peb: 00000000  ParentCid: 0000
    DirBase: 00039000  ObjectTable: e1001c28  HandleCount: 448.
    Image: Idle
还请大家指点。。。
2008-1-24 22:28
0
雪    币: 375
活跃值: (12)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
7
你应该这样:

KPCR= 0xFFDFF000;
dprintf("KPCR : 0x%X",KPCR);
KPRCB = *((ULONG *)(KPCR + 0x020));
dprintf("KPRCB : 0x%X",KPRCB);
kIdleThread = *((ULONG *)(KPRCB + 0x00c));
dprintf("kIdleThread : 0x%X",kIdleThread);
KAPC = *((ULONG *)(kIdleThread + 0x034));
dprintf("KAPC : 0x%X",KAPC);
Idle = *((ULONG *)(KAPC + 0x010));
dprintf("Idle : 0x%X",Idle);
2008-1-25 21:39
0
雪    币: 66
活跃值: (16)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
8
小伟你怎么能这样  - -! 全用偏移量
2008-1-25 21:41
0
雪    币: 709
活跃值: (2420)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
9
[QUOTE=xPLK;410532]

KPRCB = *((ULONG *)(KPCR + 0x020));
[QUOTE]

哈哈,硬编码还写错了.是 0x120
2008-1-25 21:48
0
雪    币: 375
活跃值: (12)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
10
没错吧~
如果错我当初就蓝了

自己你KD一下。
2008-1-26 14:40
0
雪    币: 709
活跃值: (2420)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
11
汗,原来2个都可以的.

static inline PKPRCB KeGetCurrentPrcb(VOID)
{
  ULONG value;

#if defined(__GNUC__)
  __asm__ __volatile__ ("movl %%fs:0x20, %0\n\t"
   : "=r" (value)
    : /* no inputs */
    );
#elif defined(_MSC_VER)
  . . . . . .
#endif
  return((PKPRCB)value);
}

fs:0x20就是KPCR数据结构中的指针Prcb,指向相应的KPRCB数据结构

而KPCR的0x120处也是指向prcb结构的
2008-1-26 14:48
0
雪    币: 709
活跃值: (2420)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
12
typedef struct _KPCR {
  KPCR_TIB  Tib;            /* 00 */
  struct _KPCR  *Self;          /* 1C */
  struct _KPRCB  *Prcb;       /* 20 */
  KIRQL  Irql;                 /* 24 */
  ULONG  IRR;               /* 28 */
  ULONG  IrrActive;           /* 2C */
  ULONG  IDR;               /* 30 */
  PVOID  KdVersionBlock;        /* 34 */
  PUSHORT  IDT;              /* 38 */
  PUSHORT  GDT;             /* 3C */
  struct _KTSS  *TSS;           /* 40 */
  USHORT  MajorVersion;        /* 44 */
  USHORT  MinorVersion;        /* 46 */
  KAFFINITY  SetMember;       /* 48 */
  ULONG  StallScaleFactor;       /* 4C */
  UCHAR  DebugActive;         /* 50 */
  UCHAR  ProcessorNumber;     /* 51 */
  UCHAR  Reserved;            /* 52 */
  UCHAR  L2CacheAssociativity;  /* 53 */
  ULONG  VdmAlert;           /* 54 */
  ULONG  KernelReserved[14];   /* 58 */
  ULONG  L2CacheSize;        /* 90 */
  ULONG  HalReserved[16];     /* 94 */
  ULONG  InterruptMode;       /* D4 */
  UCHAR  KernelReserved2[0x48]; /* D8 */
  KPRCB  PrcbData;           /* 120 */
} KPCR, *PKPCR;

讨论中学习,收获很大呀
2008-1-26 14:54
0
雪    币: 375
活跃值: (12)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
13
!-.-
放驱动吧~
反正我没蓝就对了。
2008-1-26 15:17
0
雪    币: 66
活跃值: (16)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
14
[QUOTE=sudami;410542][QUOTE=xPLK;410532]

KPRCB = *((ULONG *)(KPCR + 0x020));



哈哈,硬编码还写错了.是 0x120...


还是有区别的

如果用0x120  应该是KPRCB = &KPCR+0x120
2008-1-26 18:46
0
雪    币: 709
活跃值: (2420)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
15
嗯, 一个是指针,一个是实体,
2008-1-26 19:41
0
雪    币: 375
活跃值: (12)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
16
反正弄出Idle的Eprocess就可以了。。。
苏大米是牛人。。。
2008-1-26 21:32
0
雪    币: 66
活跃值: (16)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
17
嘿。。  苏大米这外号开始 in use了  哈哈哈哈哈!
2008-1-26 21:37
0
雪    币: 709
活跃值: (2420)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
18
2位牛就不要再寒碜小弟了.

想大牛门看齐,努力学习
2008-1-26 21:45
0
雪    币: 223
活跃值: (10)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
19
谢谢,各位。
小弟学习了。
2008-1-26 21:50
0
游客
登录 | 注册 方可回帖
返回
//