PsSetCreateProcessNotifyRoutineEx 創建回調函數


轉載自http://blog.csdn.net/yushiqiang1688/article/details/5209597

 

最近要做一個進程監控的程序,功能很簡單,就是創建和退出進程的時候,能觸發我們的事件。

首先的第一想法,是Hook ZwCreateProcess,結果調試的時候發現,很多創建進程的動作,並沒有通過這個API執行,所以自然就是沒辦法監控進程的創建,於是回到本質,從創建進程的動作過程來分析,創建新的進程,其大致要經歷以下步驟:

(1)打開可執行文件,以FILE_EXECUTE權限打開;

(2)將可執行文件加載到內存空間;

(3)進程的活動結構將被創建,如(EPROCESS,KPROCESS和PEB結構);

(4)為新創建的進程分配地址空間;

(5)為進程的主線程創建線程活動結構,如(ETHREAD,KTHREAD和TEB結構);

(6)主線程的棧將會被分配;

(7)進程的主線程的上下文將被創建;

(8)通知windows子系統;

以上總結下來,無非有下面幾種辦法獲取進程創建的消息:

(1)HOOK ZeCreateSection,創建虛擬內存塊的時候,根據傳入的文件句柄,獲取句柄對應的文件名是否為exe可執行文件;

(2)Hook NtReadVirtualMemory,為新創建的進程分配地址空間等操作時,需要讀取進程空間,這樣捕獲,就能夠獲取進程的創建動作;

(3)通過windows提供的回調函數,注冊回調事件;

方法對比:

(1)該方法能夠准確的獲取進程創建的操作,但是由於此時進程並沒有創建完畢,一些進程的基本結構還沒有創建,所以進程ID等信息無法獲取;

(2)該方法能夠獲取進程的創建操作,但不准確。因為除了進程的創建會調用此操作外,人為的一些操作,例如某外部應用程序想讀取另一個進程的內存空間,也會調用這個函數,這時候也會有事件響應,因此結果不准確;

(3)第三種方法更直觀和簡單。因為采用的回調事件,並不直接HOOK API,因此更穩定。

重點分析第三種回調方法。

注冊回調事件,是通過PsSetCreateProcessNotifyRoutine來實現的,其函數原型如下:

NTSTATUS PsSetCreateProcessNotifyRoutine( 
IN PCREATE_PROCESS_NOTIFY_ROUTINE NotifyRoutine, 
IN BOOLEAN Remove 
);

NotifyRoutine就是注冊的回調函數,當有進程創建的時候,就會調用這個NotifyRoutine對應的函數,其函數定義原型如下:

VOID (*PCREATE_PROCESS_NOTIFY_ROUTINE) ( 
IN HANDLE ParentId, 
IN HANDLE ProcessId, 
IN BOOLEAN Create 
); 
其中,ParentId是父進程ID,ProcessId為子進程ID,而Create表示是創建進程還是結束進程,其中True表示創建進程,False表示結束進程。

通過這個函數,我們就能夠完成進程創建和退出的監控,首先調用PsSetCreateProcessNotifyRoutine注冊進程監控回調函數,然后在回調函數里面,判斷Create參數,分別處理進程創建和退出操作。

 

其它類似的函數還有PsSetLoadImageNotifyRoutine,PsSetCreateThreadNotifyRoutine等。

    


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM