最近要做一個(gè)進(jìn)程監(jiān)控的程序,功能很簡(jiǎn)單,就是創(chuàng)建和退出進(jìn)程的時(shí)候,能觸發(fā)我們的事件。
首先的第一想法,是Hook ZwCreateProcess,結(jié)果調(diào)試的時(shí)候發(fā)現(xiàn),很多創(chuàng)建進(jìn)程的動(dòng)作,并沒(méi)有通過(guò)這個(gè)API執(zhí)行,所以自然就是沒(méi)辦法監(jiān)控進(jìn)程的創(chuàng)建,于是回到本質(zhì),從創(chuàng)建進(jìn)程的動(dòng)作過(guò)程來(lái)分析,創(chuàng)建新的進(jìn)程,其大致要經(jīng)歷以下步驟:
(1)打開可執(zhí)行文件,以FILE_EXECUTE權(quán)限打開;
(2)將可執(zhí)行文件加載到內(nèi)存空間;
(3)進(jìn)程的活動(dòng)結(jié)構(gòu)將被創(chuàng)建,如(EPROCESS,KPROCESS和PEB結(jié)構(gòu));
(4)為新創(chuàng)建的進(jìn)程分配地址空間;
(5)為進(jìn)程的主線程創(chuàng)建線程活動(dòng)結(jié)構(gòu),如(ETHREAD,KTHREAD和TEB結(jié)構(gòu));
(6)主線程的棧將會(huì)被分配;
(7)進(jìn)程的主線程的上下文將被創(chuàng)建;
(8)通知windows子系統(tǒng);
以上總結(jié)下來(lái),無(wú)非有下面幾種辦法獲取進(jìn)程創(chuàng)建的消息:
(1)HOOK ZeCreateSection,創(chuàng)建虛擬內(nèi)存塊的時(shí)候,根據(jù)傳入的文件句柄,獲取句柄對(duì)應(yīng)的文件名是否為exe可執(zhí)行文件;
(2)Hook NtReadVirtualMemory,為新創(chuàng)建的進(jìn)程分配地址空間等操作時(shí),需要讀取進(jìn)程空間,這樣捕獲,就能夠獲取進(jìn)程的創(chuàng)建動(dòng)作;
(3)通過(guò)windows提供的回調(diào)函數(shù),注冊(cè)回調(diào)事件;
方法對(duì)比:
(1)該方法能夠準(zhǔn)確的獲取進(jìn)程創(chuàng)建的操作,但是由于此時(shí)進(jìn)程并沒(méi)有創(chuàng)建完畢,一些進(jìn)程的基本結(jié)構(gòu)還沒(méi)有創(chuàng)建,所以進(jìn)程ID等信息無(wú)法獲??;
(2)該方法能夠獲取進(jìn)程的創(chuàng)建操作,但不準(zhǔn)確。因?yàn)槌诉M(jìn)程的創(chuàng)建會(huì)調(diào)用此操作外,人為的一些操作,例如某外部應(yīng)用程序想讀取另一個(gè)進(jìn)程的內(nèi)存空間,也會(huì)調(diào)用這個(gè)函數(shù),這時(shí)候也會(huì)有事件響應(yīng),因此結(jié)果不準(zhǔn)確;
(3)第三種方法更直觀和簡(jiǎn)單。因?yàn)椴捎玫幕卣{(diào)事件,并不直接HOOK API,因此更穩(wěn)定。
重點(diǎn)分析第三種回調(diào)方法。
注冊(cè)回調(diào)事件,是通過(guò)PsSetCreateProcessNotifyRoutine來(lái)實(shí)現(xiàn)的,其函數(shù)原型如下:
NTSTATUS PsSetCreateProcessNotifyRoutine(
IN PCREATE_PROCESS_NOTIFY_ROUTINE NotifyRoutine,
IN BOOLEAN Remove
);
NotifyRoutine就是注冊(cè)的回調(diào)函數(shù),當(dāng)有進(jìn)程創(chuàng)建的時(shí)候,就會(huì)調(diào)用這個(gè)NotifyRoutine對(duì)應(yīng)的函數(shù),其函數(shù)定義原型如下:
VOID (*PCREATE_PROCESS_NOTIFY_ROUTINE) (
IN HANDLE ParentId,
IN HANDLE ProcessId,
IN BOOLEAN Create
);
其中,ParentId是父進(jìn)程ID,ProcessId為子進(jìn)程ID,而Create表示是創(chuàng)建進(jìn)程還是結(jié)束進(jìn)程,其中True表示創(chuàng)建進(jìn)程,F(xiàn)alse表示結(jié)束進(jìn)程。
通過(guò)這個(gè)函數(shù),我們就能夠完成進(jìn)程創(chuàng)建和退出的監(jiān)控,首先調(diào)用PsSetCreateProcessNotifyRoutine注冊(cè)進(jìn)程監(jiān)控回調(diào)函數(shù),然后在回調(diào)函數(shù)里面,判斷Create參數(shù),分別處理進(jìn)程創(chuàng)建和退出操作。
其它類似的函數(shù)還有PsSetLoadImageNotifyRoutine,PsSetCreateThreadNotifyRoutine等函數(shù),通過(guò)函數(shù)名,能夠比較清晰的明白函數(shù)的意義,在此就不細(xì)講了。
本文來(lái)自CSDN博客,轉(zhuǎn)載請(qǐng)標(biāo)明出處:http://wwv.renren.com/xn.do?ss=10791&rt=1