枚舉進程——暴力搜索內存(Ring0)


上面說過了隱藏進程,這篇博客我們就簡單描述一下暴力搜索進程。

 

一個進程要運行,必然會加載到內存中,斷鏈隱藏進程只是把EPROCESS從鏈表上摘除了,但它還是駐留在內存中的。這樣我們就有了找到它的方法。

在內核中,傳入進程ID,通過ZwOpenProcess得到句柄,再傳入句柄,通過ObReferenceObjectByHandle,可以獲得EPROCESS,既然獲得了EPROCESS,問題就迎刃而解了。

既可以選擇用加偏移的方法得到進程名,也可以用PsGetProcessFileName來獲取進程名。這樣就得到了進程的信息。

 

所以,我們從0枚舉到一個很大的數,比如100000(我們所見過的進程ID沒有大過100000的),作為進程ID,為了提高效率,可以只把4的倍數作為進程ID(進程ID都是4的倍數),在Ring3層通過OpenProcess打開,如果得到的句柄不為空,在將其ID傳入Ring0層,通過上面的方法,就可以搜索出內存中的所有進程。

 

下面是關鍵部分源碼:

  
BOOLEAN
GetProcessImageNameByProcessID(/*IN*/ULONG ulProcessID,/*OUT*/char* szProcessImageName,/*OUT*/ULONG* ulProcessNameLen)
{
    CLIENT_ID Cid;    
    HANDLE    hProcess;
    NTSTATUS  Status;
    OBJECT_ATTRIBUTES  oa;
    PEPROCESS  EProcess = NULL;
    


    Cid.UniqueProcess = (HANDLE)ulProcessID;
    Cid.UniqueThread = 0;
    
    InitializeObjectAttributes(&oa,0,0,0,0);

    Status = ZwOpenProcess(&hProcess,PROCESS_ALL_ACCESS,&oa,&Cid);   

    if (!NT_SUCCESS(Status))
    {
        return FALSE;
    }

    Status = ObReferenceObjectByHandle(hProcess,FILE_READ_DATA,0,
        KernelMode,&EProcess, 0);

    if (!NT_SUCCESS(Status))
    {

        ZwClose(hProcess);
        return FALSE;
    }


    ObDereferenceObject(EProcess);       //上面用過ObReferenceObjectByHandle,所以這里要解一次引用計數
    

    *ulProcessNameLen = strlen((const char*)PsGetProcessImageFileName(EProcess));

    memcpy(szProcessImageName,(const char*)PsGetProcessImageFileName(EProcess),*ulProcessNameLen);     
        DbgPrint("%s\r\n",szProcessImageName);

    ZwClose(hProcess);
}

 

 


免責聲明!

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



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