这两天一直看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源码分析:屏幕监控相关推荐

  1. gh0st源码分析与远控的编写(三)

    好久不见.距离上次写gh0st来有好久了,一是期末考试,忙不开,二是后来电脑坏了,几天没能上网. 昨天总算是把电脑修好了,虽说没到一切重头开始的地步,但是也重装各种东西花了很久.闲下来的时间,我就来继 ...

  2. gh0st源码分析与远控的编写(二)

    上次说了那么多,基本上就是一个叫"大局观"的东西,只有脑子里有了一个软件的设计.运行思路,才能把一个一个类写出来,组合在一起. Gh0st的作者是一个对代码有很好掌控的人,他对代码 ...

  3. gh0st源码分析与远控的编写(一)

    再过几天期末考试了,还有好多要复习..蛋都快碎了.最近在看老狼的gh0st内核编程,想了很久要不要写文章,最后还是觉得很有必要,原因过一会讲. 先送上老狼的gh0st无加密(lxe格式)视频下载地址: ...

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

    真的很久很久了,距离上一次写gh0st的文章(http://www.leavesongs.com/C/gh0st_3.html),过去有大半年了.总算有一个时间,我放下手里所有的活,能够继续把这份努力 ...

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

    在 Spring Developer Tools 源码分析一中介绍了 devtools 提供的文件监控实现,在第二部分中,我们将会使用第一部分提供的目录监控功能,实现对开发环境中 classpath ...

  6. Kubernetes监控之Heapster源码分析

    源码版本 heapster version: release-1.2 简介 Heapster是Kubernetes下的一个监控项目,用于进行容器集群的监控和性能分析. 基本的功能及概念介绍可以回顾我之 ...

  7. Android屏幕刷新——源码分析

    Android屏幕刷新原理--源码分析 文章目录 Android屏幕刷新原理--源码分析 概述 VSync信号 三级缓冲 源码分析 消息队列的同步屏障 参考资料 概述 Android系统每16ms(一 ...

  8. 【SA8295P 源码分析】28 - QNX Ethernet MAC 驱动 之 emac_mdio_link_monitor_thrd() MDIO监控线程 源码分析

    [SA8295P 源码分析]28 - QNX Ethernet MAC 驱动 之 emac_mdio_link_monitor_thrd MDIO监控线程 源码分析 一.emac_mdio_link_ ...

  9. 【Android SDM660源码分析】- 02 - UEFI XBL QcomChargerApp充电流程代码分析

    [Android SDM660源码分析]- 02 - UEFI XBL QcomChargerApp充电流程代码分析 一.加载 UEFI 默认应用程序 1.1 LaunchDefaultBDSApps ...

最新文章

  1. python_day2基本数据类型
  2. python使用ssh 中文_Python3制作简易SSH登录工具
  3. 自定义session,cookie
  4. 4 基于优化的攻击——CW
  5. 400电话查询php,PHP 匹配电话,手机,400号码 函数 及正则。很管用。
  6. 省市县行政区划代码sql及源地址
  7. 《人类简史》笔记二——一场永远的革命
  8. html在电脑中怎么用,电脑的基本操作是什么?
  9. 什么是编程?该怎么学习编程?
  10. SQLite 使用问题记录(一)
  11. LPF与HPF是什么意思?
  12. 网络电视地址大全- -
  13. 借了十几万的 p2p 跑路了。。。
  14. 通达信有量化接口吗?
  15. 使用zsh和oh-my-zsh修改xshell中命令颜色
  16. Avaya交换机呼叫中心解决方案
  17. Docker 基本原理
  18. “黑洞效应”下的苏宁小Biu、小米,谁能站到制高点?
  19. C++就要这样学7--C++的数据类型2.1
  20. 爬虫大数据软件开发中程序员的伦理问题

热门文章

  1. SpringMVC的请求-文件上传-单文件上传的代码实现1
  2. 工厂模式解耦的升级版
  3. 文件操作-读取文件后文件指针会发生变化
  4. 尚硅谷-SpringBoot高级-检索-Elasticsearch快速入门
  5. java中的equals拿什么鞋的_Java中==和equals方法
  6. Spring ribbon
  7. Linux 下 GitLab 安装教程
  8. tomcat 访问去掉项目名 直接访问 localhsot
  9. asp.net identity的学习记录
  10. iOS一些推荐的学习路径发展