(转) Csrss进程剖析
http://bbs.pediy.com/showthread.php?t=150284
這幾天想了解下神秘的進(jìn)程csrss,在學(xué)習(xí)和了解的過程中就寫下了自己對csrss進(jìn)程的理解。
Csrss(客戶端/服務(wù)器運(yùn)行時子系統(tǒng))是?Win32?子系統(tǒng)的用戶模式部分,在桌面管理、終端登錄、控制臺管理、錯誤報告報告和DOS?虛擬機(jī)等方面起著重要作用,另外還監(jiān)控著系統(tǒng)內(nèi)所有Win32?子系統(tǒng)進(jìn)程和線程的運(yùn)行,進(jìn)程的創(chuàng)建與退出,都需要通知Csrss。
圖1是用內(nèi)核工具xuetr觀察Csrss進(jìn)程加載的模塊。(以下的分析環(huán)境為xp?sp2?32位)
???????????????????????????????圖1
??
由圖1中我們可以知道Csrss進(jìn)程除了加載諸如Kernel32,ntdll等基礎(chǔ)模塊之外,basesrv.dll,csrsrv.dll?,winsrv.dll就是Csrss進(jìn)程的核心模塊,因此我們重點(diǎn)研究這幾個模塊,當(dāng)然研究這幾個模塊就要那個這幾個模塊的pdb文件,我們利用windbg提供的工具SymChk?下載這幾個模塊的pdb文件,首先在cmd命令行中進(jìn)入windbg目錄,然后用如下命令:
Symchk?/r??c:\windows\system32?/s?SRV*c:\mysymbols\*http://msdl.microsoft.com/download/symbols
如圖2.? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
????????????????????????????????????????????圖2
??
這樣我們就有了csrss進(jìn)程核心模塊的pdb文件,為下面我們用IDA分析這些模塊提供了方便。
??
csrsrv.dll?里面有一個未導(dǎo)出符號叫做?CsrRootProcess,?對?csrss?起著重要的作用。CsrRootProcess?指向一個?CSR_PROCESS?結(jié)構(gòu)。
??
CSR_PROCESS?結(jié)構(gòu)?(Vista/2008,?對于?XP/2003?同樣適用)?如下:
每一個進(jìn)程都對應(yīng)著一個?CSR_PROCESS?結(jié)構(gòu)體,所有進(jìn)程的CSR_PROCESS?結(jié)構(gòu)體
通過成員struct?_LIST_ENTRY?ListLink?構(gòu)成了一個鏈表,通過CsrRootProcess?可以遍歷這個鏈表。當(dāng)一個進(jìn)程創(chuàng)建時,Csrss.exe?會新建一個CSR_PROCESS?結(jié)構(gòu)體,加入到這個鏈表
中(從Csrss.dll中我們可以看到插入鏈表是通過未導(dǎo)出函數(shù)CsrInsertProcess實(shí)現(xiàn)的);當(dāng)一個進(jìn)程退出時,Csrss.exe?會將該進(jìn)程對應(yīng)的CSR_PROCESS?結(jié)構(gòu)體從鏈表中刪除(從Csrss.dll中我們可以看到插入鏈表是通過未導(dǎo)出函數(shù)CsrRemoveProcess實(shí)現(xiàn)的)。
下面我們可以簡單看下這連個函數(shù)的實(shí)現(xiàn):
Csrss?里面還存在著一個?關(guān)于線程的未導(dǎo)出符號叫做?CsrThreadHashTable。它是一個有?256?個元素的數(shù)組,?每一個元素都指向一個?CSR_THREAD?結(jié)構(gòu),?而?CSR_THREAD?結(jié)構(gòu)同樣包含一個?LIST_ENTRY。
typedef struct _CSR_THREAD { // <size 0x38> union _LARGE_INTEGER CreateTime; struct _LIST_ENTRY Link; struct _LIST_ENTRY HashLinks; struct _CLIENT_ID ClientId; struct _CSR_PROCESS* Process; struct _CSR_WAIT_BLOCK* WaitBlock; void* ThreadHandle; unsigned long Flags; unsigned long ReferenceCount; unsigned long ImpersonateCount; } CSR_THREAD, *PCSR_THREAD;相關(guān)操作函數(shù)CsrInsertThread,CsrRemoveThread。
Win32?子系統(tǒng)進(jìn)程與CSRSS?的通信
我們首先從csrss是怎么啟動的作為入口點(diǎn),用進(jìn)程查看工具procexp.exe查看相關(guān)信息。
如下圖3? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
??????????????????????????????圖3
從圖3中我們可以知道csrss進(jìn)程的父進(jìn)程是smss,我們同樣利用procexp.exe工具查看csrss的啟動參數(shù)是什么,如圖4:
?????????????????????????????
??????????????????????????????圖4
從圖4中我們首先能猜想到的就是ServerDll=winsrv:UserServerDllInitialization,3?的意思是winsev.dll這個核心服務(wù)dll里面存在導(dǎo)出函數(shù)UserServerDllInitialization。那么我們就先從這個函數(shù)里面找找看有什么有用的線索沒。
從UserServerDllInitialization代碼片段中我們發(fā)現(xiàn)了兩張表,如圖5
????????????????????????????????????????????
我們在IDA中看看這兩張表(UserServerApiDispatchTable?圖6):
?????????????????????????????
???????????????????????????????????????????圖6
UserServerApiDispatchTable?這張表保存了很多函數(shù)。而UserServerApiServerValidTable這張表保存的是UserServerApiDispatchTable?表里面相對應(yīng)函數(shù)是否有效的標(biāo)志。
同樣的道理我們看看ConServerDllInitialization這個函數(shù),我們也發(fā)現(xiàn)了類似的表。
如下圖7:
?????
????????????????????
所以winsrv.dll里面有兩個重要的保存函數(shù)的表:ConsoleServerApiDispatchTable(控制臺管理),UserServerApiDispatchTable(終端登錄之類)。
??
??
最后我們發(fā)現(xiàn)basesrv.DLL也存在一張保存函數(shù)的表:BaseServerApiDispatchTable,
如下圖8???
?????????????????????????????????????
???????????????????????????????????????????????圖8
??
Csrsrv.dll存在CsrServerApiDispatchTable這張表。(圖9)
?????????????????????????????
????????????????????????????????圖9
??
??四個分發(fā)表序號如下:
??CsrServerApiDispatchTable:0
??BaseServerApiDispatchTable:1
??ConsoleServerApiDispatchTable:2
??UserServerApiDispatchTable:3
??
因此我們可以知道csrss.exe啟動時候參數(shù)winsrv:UserServerDllInitialization,3?的意思了。
Win32?子系統(tǒng)進(jìn)程與CSRSS?的通信是通過lpc?port,在圖3中我們可以看到個名為\Windows\ApiPort?的LPC?端口與名為\Windows\sbApiPort的LPC端口。那么在?Csrss?中,對ApiPort?端口所接收到的LPC?消息的處理,主要是由csrsrv.dll?中的
CsrApiRequestThread?函數(shù)完成。CsrApiRequestThread?函數(shù)調(diào)用NtReplyWaitReceivePort?接收
消息,根據(jù)消息的類型執(zhí)行特定的操作。
CsrApiRequestThread函數(shù)里面有一while循環(huán)處理各種請求,ReceiveMsg參數(shù)的ReceiveMsg.h.u2.s2.Type字段保存了消息的類型,當(dāng)請求為LPC_REQUEST:
??LPC參數(shù)中某一字段:高16?位指定是哪個分發(fā)表,低16?位為分發(fā)表中函數(shù)的索引值
,定義如下:
#define?CSR_APINUMBER_TO_SERVERDLLINDEX(?ApiNumber?)?\
????((ULONG)((ULONG)(ApiNumber)?>>?16))????//高16?位指定是哪個分發(fā)表
#define?CSR_APINUMBER_TO_APITABLEINDEX(?ApiNumber?)?\
??((ULONG)((USHORT)(ApiNumber)))??//低16?位為分發(fā)表中函數(shù)的索引值
???這樣就可以通過分發(fā)表調(diào)用函數(shù)。
??
??ApiNumber?=?ReceiveMsg.ApiNumber;ServerDllIndex?=?CSR_APINUMBER_TO_SERVERDLLINDEX(?ApiNumber?);LoadedServerDll?=?CsrLoadedServerDll[?ServerDllIndex?](*(LoadedServerDll->ApiDispatchTable[?ApiTableIndex?]))(?????????????????????????????????????&ReceiveMsg,?????????????????????????????????????&ReplyStatus?????????????????????????????????????);
轉(zhuǎn)載于:https://www.cnblogs.com/himessage/archive/2012/12/27/2835286.html
總結(jié)
以上是生活随笔為你收集整理的(转) Csrss进程剖析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 字库芯片GT20L16S1Y 读取字体数
- 下一篇: java导出excel问题记录