zoukankan      html  css  js  c++  java
  • 【旧文章搬运】CsrssWalker学习笔记

    原文发表于百度空间及看雪论坛,2009-05-13

    看雪论坛地址:https://bbs.pediy.com/thread-89708.htm
    ==========================================================================

    最近很忙,也很懒,发点以前写的东西吧~
    学习了一下古老的CsrssWalker,写点笔记~~
    在Csrss.exe中,保存着所有Win32子系统进程的进程信息,这些信息以链表的形式保存。
    正常情况下,每一个新创建的进程都会通知Csrss.exe,Csrss.exe接收这些信息然后保存起来,所以遍历这个链表就可以得到所有Win32子系统进程的信息。首先就是找链表头了,链表头为CsrssRootProcess,在CSRSRV.DLL导出的函数中有对CsrssRootProcess的操作,因此可以通过CSRSRV.DLL的导出函数找到CsrssRootProcess。
    比较方便一点的,是从CsrLockProcessByClientId中找到CsrssRootProcess.

    mov      edx, [ebp+arg_4]
    and      dword ptr [edx], 0
    mov      esi, dword_75AA891C ; Base=75AA0000
    add      esi, 8
    mov      [ebp+arg_4], 0C0000001h

    75AA891C处就是CsrssRootProcess的指针了,这个指针的值可以通过特征匹配找到,具体请参考代码。读取其内容,得到CsrssRootProcess=0x001629C0(这个只是我的系统上的)

    从这里读就可以得到CsrssRootProcess的内容了,然后遍历Link即可
    涉及以的一些数据结构在CsrssStruct.h中。
    进程信息的结构如下:

    typedef struct _CSR_PROCESS
    {
         CLIENT_ID ClientId; //这里可以得到进程PID和主线程TID
         LIST_ENTRY ListLink; //就是这个链表
          LIST_ENTRY ThreadList;
         struct _CSR_PROCESS *Parent;
         PCSR_NT_SESSION NtSession;
        ULONG ExpectedVersion;
        HANDLE ClientPort;
        ULONG_PTR ClientViewBase;
        ULONG_PTR ClientViewBounds;
        HANDLE ProcessHandle;
        ULONG SequenceNumber;
        ULONG Flags;
        ULONG DebugFlags;
         CLIENT_ID DebugCid;
        ULONG ReferenceCount;
        ULONG ProcessGroupId;
        ULONG ProcessGroupSequence;
        ULONG fVDM;
        ULONG ThreadCount;
        ULONG PriorityClass;
        ULONG Reserved;
        ULONG ShutdownLevel;
        ULONG ShutdownFlags;
        PVOID ServerData[];
    } CSR_PROCESS, *PCSR_PROCESS;

    但是因为这不是在当前进程中,所以每次都要先读取出来,遍历时与普通的遍历双链表操作稍有差别,但是也很容易实现。

    具体的步骤为:
    1.找到Csrss.exe进程(这个很简单,Vista要注意有不止一个Csrss进程)
    2.遍历Csrss.exe中的模块列表,找到CSRSRV.DLL的基址。
    3.在CSRSRV.DLL中根据导出函数CsrLockProcessByClientId找CsrssRootProcess指针
    4.构建当前进程名称列表,为输出作准备
    5.根据CsrssRootProcess指针的地址,从Csrss.exe进程中读取和遍历每个进程的信息并输出

    在Csrss.exe中同样还保存着所有Win32线程的信息,由于线程数目较多,Csrss中采用Hash表的形式来保存线程信息。同样从CSRSRV.DLL的导出函数CsrLockThreadByClientId可以得到CsrThreadHashTable的地址,这是一个Hash表,定义为:

    LIST_ENTRY CsrThreadHashTable[256];

    Hash算法为:

    #define CsrHashThread(t) 
        (HandleToUlong(t)&(256 - 1))

        

    很简单的算法,查找CsrThreadHashTable的方法及遍历方法与前面遍历CsrssRootProcessLink基本相同,不多说。这部分我并未在代码中实现,有兴趣的自己写一写吧,很简单。
    对于Vista等较新的系统,由于Session隔离,系统中会有不止一个Csrss进程,这样就需要对这几个Csrss进程都进行处理。就说这么多了,具体地看代码~~
    代码下载地址:

    看雪:https://bbs.pediy.com/thread-89708.htm

  • 相关阅读:
    Maven 环境的配置
    zTree的简单例子
    plsql免安装客户端的配置
    HDU 1232 畅通工程
    HDU 5698 瞬间移动
    Codeforces 1015E1 Stars Drawing (Easy Edition)
    Codeforces 784B Santa Claus and Keyboard Check
    Codeforces 500C New Year Book Reading
    NSarray 赋值 拷贝 等问题记录
    UINavigationController 操作记录
  • 原文地址:https://www.cnblogs.com/achillis/p/10181640.html
Copyright © 2011-2022 走看看