通过ActiveProcessLinks遍历进程

进程的遍历有多种方法。在应用程序里可以使用CreateToolHelp32SnapShot函数先做个进程快照(snapshot),然后通过返回的数据进行遍历。在内核编程里可以通过内核数据结构来实现。
内核结构EPROCESS(执行体进程块 executive process)是一个不透明(opaque)的结构体,大概意思就是这个结构不对外公开,但是还是可以通过WinDbg获取它的各成员名和类型。在Win7 32上,eprocess结构体在偏移为0xb8处成员是ActiveProcessLinks,从字面意思就可以看出来是关于活动进程的链表。内核中常常使用循环双链表将相同类型的对象(object)串在一起,便于管理。在了解循环双链表之后就可以通过该链表来遍历进程。

lkd> dt nt!_list_entry
   +0x000 Flink            : Ptr32 _LIST_ENTRY 
   +0x004 Blink            : Ptr32 _LIST_ENTRY 
 list_entry使用时应注意,当该表项是头节点时,Flink指第一个,Blink指最后一个;当该表项是中间节点时,Flink指向下一个,Blink指向前一个。
lkd> dt nt!_eprocess
   +0x000 Pcb              : _KPROCESS
   +0x098 ProcessLock      : _EX_PUSH_LOCK
   +0x0a0 CreateTime       : _LARGE_INTEGER
   +0x0a8 ExitTime         : _LARGE_INTEGER
   +0x0b0 RundownProtect   : _EX_RUNDOWN_REF
   +0x0b4 UniqueProcessId  : Ptr32 Void
   +0x0b8 ActiveProcessLinks : _LIST_ENTRY  这个结构里保存了两个eprocess结构里,ActiveProcessLinks的地址,有张类似的图,可以对照看一看。 
   ....(后面还有一大块没copy_paste)  
   实现遍历的主要代码:  
    ULONG AddrOfTheCurrentProcess=0,AddrOfTheFirstProcess=0;
    AddrOfTheFirstProcess=AddrOfTheCurrentProcess=(ULONG)IoGetCurrentProcess();
    do
    {
        KdPrint(("ImageFileName:%s\n",(char *)(AddrOfTheCurrentProcess+0x16c)));//打印进程名
        AddrOfTheCurrentProcess=(ULONG)(*(ULONG *)(AddrOfTheCurrentProcess+0xb8)-0xb8);//得到下一个进程的地址
    }while(AddrOfTheCurrentProcess!=AddrOfTheFirstProcess);

IoGetCurrentProcess()返回一个类型为Eprocess的指针,该指针指向当前进程的eprocess结构,并用ULONG转换一下。eprocess结构的0x16c偏移出时ImageFileName,一个长度为16的字符串数组,用来存放进程名(如果名字过长怎么办呢?还没发现怎么办:))。接下来就是从当前进程的地址到下一个进程的地址转换操作:(ULONG )(AddrOfTheCurrentProcess+0xb8),得到下一个eprocess里ActiveProcessLinks地址,然后再减去该成员的偏移就是结构体的首地址。(ULONG )(AddrOfTheCurrentProcess+0xb8)看上去不对劲呀?怎么感觉前面的(ULONG )抵消呢?来看看,假如AddrOfTheCurrentProcess+0xb8=0x00400100,该地址,保存另一个对象的地址。先把它变成指针(实际上都是地址好吧!),(ULONG )就得到想要的地址。可能没讲那么明白,可以去编一编,看看对不对,加深理解。
关于遍历的结果,因为是在内核第一个列出的是System,最后一个打印的乱码。实际上在命令行下使用tasklist命令得到的结果第一个是System Idle Process,它好像没有名字(悲哀呀)。
list_entry的连接示例

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值