关于一款开源远程控制软件(gh0st)的源码分析(一)

2020注定是不平凡的一年,前有冠状病毒的肆虐,全国上下都笼罩在一种紧张而又不安的氛围下;因为疫情的严重性,使我被迫享受了学生时代的超长假期。闲来无事,就分析了一下那些静静地躺在我磁盘里的开源软件源码。
gh0st这款软件,主要用途是用于远程操作另一台计算机(包括远程文件的拷贝、远程视频连接等),功能有点类似于QQ中的远程桌面。该软件由两个工程文件组成,分别为gh0st_Client和gh0st_Server,如图1所示:

关于一款开源远程控制软件(gh0st)的源码分析(一)
gh0st_server代表该软件的服务端,服务端启动时开启了10个线程(这和本地处理器个数有关),其中一个为主线程(MainThread),负责注册窗口、创建窗口、初始化线程池与内存池资源及IOCP(完成端口模型);主线程完成资源的初始化,便创建工作线程(ListenThreadProc)并监听客户端的连接请求。

因为此时客户端并没有发起连接远程主机的请求,所以主线程创建完工作线程——ListenThreadProc,ListenThreadProc便一直处于while(1)循环中,反复判断m_hkillEvent事件是否有信号(主线程和工作线程之间通过Event事件实现同步)、是否有IO事件的产生。

当gh0st_server发出关闭窗口的命令(也即主线程发起退出线程的请求),m_hkillEvent将被设置成受信状态。

当工作线程执行到如下代码处:

等待100毫秒,工作线程退出while循环,如此设计的好处在于:主线程退出,工作线程(子线程)能够及时地进行资源的回收,从而增强了程序的健壮性。
再回头看gh0st_server中IOCPServer这个类,该类是gh0st_server的核心,网络事件的检测、IO请求、网络数据的收发都依赖该类来实现,该类的成员变量和成员方法声明如下:

#define	NC_CLIENT_CONNECT		0x0001#define	NC_CLIENT_DISCONNECT	0x0002#define	NC_TRANSMIT				0x0003#define	NC_RECEIVE				0x0004#define NC_RECEIVE_COMPLETE		0x0005 // 完整接收class CLock{public:	CLock(CRITICAL_SECTION& cs, const CString& strFunc)	{		m_strFunc = strFunc;		m_pcs = &cs;		Lock();	}	~CLock()	{		Unlock();	}	void Unlock()	{		LeaveCriticalSection(m_pcs);		TRACE(_T("LC %d %sn") , GetCurrentThreadId() , m_strFunc);	}	void Lock()	{		TRACE(_T("EC %d %sn") , GetCurrentThreadId(), m_strFunc);		EnterCriticalSection(m_pcs);	}protected:	CRITICAL_SECTION*	m_pcs;	CString				m_strFunc;};//声明IO事件enum IOType {	IOInitialize,	IORead,	IOWrite,	IOIdle};class OVERLAPPEDPLUS {public:	OVERLAPPED			m_ol;	IOType				m_ioType;	OVERLAPPEDPLUS(IOType ioType) {		ZeroMemory(this, sizeof(OVERLAPPEDPLUS));		m_ioType = ioType;	}};//客户端context类,包括客户端socket、收发缓冲区struct ClientContext{    SOCKET				m_Socket;	// Store buffers	CBuffer				m_WriteBuffer;	//自定义的内存池类CBuffer	CBuffer				m_CompressionBuffer;	// 接收到的压缩的数据	CBuffer				m_DeCompressionBuffer;	// 解压后的数据	CBuffer				m_ResendWriteBuffer;	// 上次发送的数据包,接收失败时重发时用	int					m_Dialog[2]; // 放对话框列表用,第一个int是类型,第二个是CDialog的地址	int					m_nTransferProgress;	// Input Elements for Winsock	WSABUF				m_wsaInBuffer;	BYTE				m_byInBuffer[8192];	//

来源:梦溪笔谈之C++

声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2020年1月3日
下一篇 2020年1月3日

相关推荐