C++开源项目研究——gh0st远控(一)

本文详细介绍了主控端如何监听端口并使用I/O多路复用技术处理连接请求,涉及回调函数、消息传递机制以及多线程在不同功能模块中的应用,如登录、打开对话框和远程控制等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上一节我们讲过肉机最关键的一步就是通过connect来连接指定的主控端

if (connect(m_Socket, (SOCKADDR *)&ClientAddr, sizeof(ClientAddr)) == SOCKET_ERROR)   
		return false;

其实在次之前应当是主控端先监听相应的端口,然后肉机再来连接这个端口的

在主控端的OnInitDialog当中调用:listenPort();    //开始监听端口

// 监听端口
void CPCRemoteDlg::listenPort()
{
	int	nPort = ((CPCRemoteApp*)AfxGetApp())->m_IniFile.GetInt("Settings", "ListenPort");         //读取ini文件中的监听端口
	int	nMaxConnection = ((CPCRemoteApp*)AfxGetApp())->m_IniFile.GetInt("Settings", "MaxConnection");   //读取最大连接数
	if (nPort == 0)
		nPort = 80;
	if (nMaxConnection == 0)
		nMaxConnection = 10000;
	Activate(nPort, nMaxConnection);             //开始监听
}

我们跟进Activate函数:

void CPCRemoteDlg::Activate(UINT nPort, UINT nMaxConnections)
{
	CString		str;

	if (m_iocpServer != NULL)
	{
		m_iocpServer->Shutdown();
		delete m_iocpServer;

	}
	m_iocpServer = new CIOCPServer;

	// 开启IPCP服务器 最大连接  端口     查看NotifyProc回调函数  函数定义
	if (m_iocpServer->Initialize(NotifyProc, NULL, 100000, nPort))
	{

		char hostname[256];
		gethostname(hostname, sizeof(hostname));
		HOSTENT* host = gethostbyname(hostname);
		if (host != NULL)
		{
			for (int i = 0; ; i++)
			{
				str += inet_ntoa(*(IN_ADDR*)host->h_addr_list[i]);
				if (host->h_addr_list[i] + host->h_length >= host->h_name)
					break;
				str += "/";
			}
		}

		str.Format("监听端口: %d成功", nPort);
		showMessage(true, str);
	}
	else
	{
		str.Format("监听端口: %d失败", nPort);
		showMessage(false, str);
	}
}

比较关键的就是m_iocpServer->Initialize(NotifyProc, NULL, 100000, nPort)

其中第一个参数NotifyProc是一个回调函数,原型为:

typedef void (CALLBACK* NOTIFYPROC)(LPVOID, ClientContext*, UINT nCode);

回调函数其实就是函数指针的一种特殊形式(二者是共性与个性,一般与个别的关系😋)

//函数指针
typedef void(_cdecl* TestRunT)(char* strHost, int nPort);

//回调函数
typedef void (CALLBACK* NOTIFYPROC)(LPVOID, ClientContext*, UINT nCode);

Initialize函数当中创建了ListenThreadProc线程用来处理端口的监听,至于怎么监听的细节就不再展开

//开启监听线程  跟进ListenThreadProc
	m_hThread =
			(HANDLE)_beginthreadex(NULL,				// Security
									 0,					// Stack size - use default
									 ListenThreadProc,  // Thread fn entry point
									 (void*) this,	    
									 0,					// Init flag
									 &dwThreadId);	// Thread address

我们来看一下几处回调函数调用的位置:

1)一处是在OnAccept处,表示有连接到来

m_pNotifyProc((LPVOID) m_pFrame, pContext, NC_CLIENT_CONNECT); 

2)另外比较关键的一处是在OnClientReading,对应完整接收:NC_RECEIVE_COMPLETE

if (nRet == Z_OK)   //如果完整接收
				{
					//写入数据
					pContext->m_DeCompressionBuffer.ClearBuffer();
					pContext->m_DeCompressionBuffer.Write(pDeCompressionData, destLen);
					 /
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值