1. 程式人生 > >【舊文章搬運】CsrssWalker學習筆記

【舊文章搬運】CsrssWalker學習筆記

RoCE 需要 ren 接收 構建 ted struct expected com

原文發表於百度空間及看雪論壇,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

【舊文章搬運】CsrssWalker學習筆記