1. 程式人生 > >【舊文章搬運】遍歷EPROCESS中的ActiveProcessLinks列舉程序

【舊文章搬運】遍歷EPROCESS中的ActiveProcessLinks列舉程序

原文發表於百度空間,2008-7-25
==========================================================================

前面對PEB的相關結構和其中的重要成員進行了分析和學習,現在開始真正進入核心,學習核心中的一些結構.
這個EPROCESS結構在ntddk.h中有定義,但是並未給出具體的結構,因此要得到EPROCESS中一些重要的成員變數,只能通過偏移的方法,比如PID,ImageName等.這些偏移可以在Windbg中dt _EPROCESS得到,但是不公開感覺還是不爽,而且這東西在不同的系統版本中不一樣,如果要相容的話,就必須先判斷作業系統版本.
在此程式中用到的相關偏移如下(XP系統):

#define EPROCESS_ACTIVELIST_OFFSET 0x88  //活動程序鏈
#define EPROCESS_PID_OFFSET 0x84                     //PID了
#define EPROCESS_IMAGENAME_OFFSET 0x174    //映像名稱
#define EPROCESS_FLINK_OFFSET 0x88                //雙鏈表的前向指標
#define EPROCESS_BLINK_OFFSET 0x8C                //雙鏈表的後向指標

由於是第一次寫驅動,有些寫法還不太清楚,下面的程式碼參考了別人的一些.

VOID ShowEPROCESS(void)
{
DWORD EProcess,FirstEProcess;
LIST_ENTRY*     ActiveProcessLinks;
DWORD pid,dwCount=0;
PUCHAR pImage;
PPROCESS_INFO ProcessInfo={0};
EProcess=FirstEProcess=(DWORD)PsGetCurrentProcess();
//pid=*(DWORD*)((char*)EProcess+EPROCESS_PID_OFFSET);
__try {   
        while
( EProcess!= 0) { dwCount++; pid= *( (DWORD*)( EProcess + EPROCESS_PID_OFFSET ) ); pImage= (PUCHAR)( EProcess + EPROCESS_IMAGENAME_OFFSET ) ; DbgPrint ( "[Pid=%8d] EProcess=0x%08X %s\n", pid, EProcess, pImage) ; ActiveProcessLinks = (LIST_ENTRY*) ( EProcess + EPROCESS_FLINK_OFFSET ) ; EProcess = (DWORD)ActiveProcessLinks->Flink - EPROCESS_FLINK_OFFSET ; if ( EProcess == FirstEProcess ) break ; } DbgPrint ( "ProcessCount = %d\n", dwCount ) ; } __except ( 1 ) { DbgPrint ( "EnumProcessList exception !" ) ; } }

上面程式碼的實現思想很簡單,因為系統中所有程序的EPROCESS通過它的一個成員變ActiveProcessLinks這個雙向連結串列連線起來,遍歷連結串列的操作很簡單,每得到一個ActiveProcessLinks,取其地址,再減去它離EPROCESS結構入口處的偏移,就可以得到EPROCESS的地址了,然後就可以輕鬆得到想要的成員變數.

下面的結果圖:

結果比實際程序數要多,表明其中有一部分其實是殭屍程序,已經死掉卻還在程序鏈上掛著.
由此我感覺到,這個程序鏈並不是那麼嚴格,因此也就可以把正常程序從鏈上摘掉,這為下面的隱藏程序實現提供了基礎.
至於對抗這種檢測方法,很簡單,DKOM把想要隱藏的程序從活動程序鏈上摘掉即可.
實現原理如下圖:

圖中,著色部分即是LIST_ENTRY結構,綠色指標Flink指向前一個,黃色指標Blink指向後一個.
正常的連線情況如藍線所示,若要摘要某個結點,修改該結點前後兩個結點的指標即可,修改示意如紅線所示.同時,還要把被隱藏的程序的EPROCESS中的兩個指標都修改為NULL.
這樣,通過遍歷雙鏈表的方法就找不到這個程序了,這就是最簡單的DKOM法隱藏程序.