打造一款属于自己的黑客远控软件(一)
自己以便工作上便于管理手上很多的电脑始终在找寻这款适合的远程控制软件。由于网站下載的远程控制软件大部分都被不一样水平地嵌入后门,因此萌发了自身塑造这款远控的念头,恰好趁着这一机遇再次捡起即将被遗弃了的C++,也介词将源码与斯柯达网民共享。选用旺盛期的MFC架构工艺来构建远控服务端和服务器端,保持了进程管理、文件管理、服务培训、无线SHELL和显示屏监控作用,层次结构清楚,为今后手机app板本的多目标优化留有了拓展空間。
程序编写坏境
Visual Studio 2010
联接
选用反跳型联接,被控端积极联接操纵端进而可以更好透过大部分防火墙。
工作内容
工作内容.jpg
基础传送构造
1、被控端汇报基础计算机信息构造
被控端联接操纵端,并将计算机信息汇报操纵端显视。
typedef struct tagSytemInit
{ char computer[32]; //计算机名 char user[32]; //登录名 char os[72]; //服务器系统 char processor[16]; //Cpu消息 char mem[16]; //运存消息 char version[16]; //手机app板本 char HDSerial[32]; //硬盘序列号 }SYSTEMINIT,*LPSYSTEMINIT;
2、暂时连接结构
该构造用于储存联接到操纵端上的socket消息及其相对的硬盘序列号。在后边的应用上将此构造储存到vector中用以监管被控端。
typedef struct tagTmpSocket
{
SOCKET ClientSocket; char HDSerial[64];
}TMPSOCKET,*LPTMPSOCKET;
3、程序通讯构造
操纵端操纵被控端,保持程序中间的通讯。
typedef struct tagLinkInfo
{
SOCKET s; string strBindIp; //被控端IP u_short BindPort; //监视网关 }LINKINFO,*LPLINKINFO;
基础通讯类
CTcpTran是全部远控的基本通讯类,用以保持socket网络通信的复位,封裝相对的API函数。应用类来封裝Socket API能够防止编码的反复,有利于调节。
CTcpTran类中的4个基础友元函数给出:
SOCKET InitSocket(int SocketType, string strBindIp,u_short BindPort,int opt); //复位socket,挑选联接种类 SOCKET myaccept(SOCKET s,struct sockaddr* addr,int* addrlen); //当地监视处理函数 int mysend(SOCKET sock, const char *buf, int len, int flag,int overtime); //传送数据 int myrecv(SOCKET sock, char *buf, int len, int flag , int overtime,char*EndMark,BOOL soonflag=FALSE); //接收数据
InitSocket涵数
InitSocket叁数表述给出,SocketType为联接种类,当值为 SOCKET_BIND时表达关联当地网关,虚拟主机监视网关等候服务端来联接,当值为SOCKET_NOBIND时表达不关联,服务器端积极联接服务端。strBindIp为要关联的IP地址,”"(空)为当地随意地点,那样做的目地是当虚拟主机有几块网口时,无论哪家网段上的客户程序都能与虚拟主机通讯。uBindPort为要关联的网关。
SOCKETCTcpTran::InitSocket( int SocketType, string strBindIp,u_short BindPort,int opt)
{
SOCKET socketid = INVALID_SOCKET;
socketid = socket(PF_INET,SOCK_STREAM,0); //创建1个流式套接字句柄
SOCKADDR_IN sockStruct; //复位1个地点构造
sockStruct.sin_family = AF_INET; //应用TCP/IP协议 if( strBindIp.empty() )
{
sockStruct.sin_addr.S_un.S_addr = INADDR_ANY; //假如strBindIp为空,则为当地随意地点
}else {
sockStruct.sin_addr.S_un.S_addr = inet_addr(strBindIp.c_str());
}
sockStruct.sin_port = htons(BindPort); //变换为互联网字节 if( SocketType == SOCKETNOBIND )
{ if(connect(socketid,(LPSOCKADDR)&sockStruct,sizeof(sockStruct)) == SOCKET_ERROR) //不关联,立即联接,被控端挑选非关联方法联接
{ // AfxMessageBox("InitSocket 不正确");
closesocket(socketid); shutdown(socketid,2);
socketid = INVALID_SOCKET;
}
m_Socket = socketid;
}else if( SocketType == SOCKETBIND ) //操纵端挑选关联当地网关
{ if(bind(socketid,(sockaddr*)&sockStruct,sizeof(sockaddr_in)) == SOCKET_ERROR) //关联地点构造
{
closesocket(socketid);
socketid = INVALID_SOCKET;
}else { if( listen(socketid,SOMAXCONN) == SOCKET_ERROR ) //进到监视
{
closesocket(socketid);
socketid = INVALID_SOCKET;
}
}
m_Socket = socketid;
} return socketid; //回到创建的socket }
myaccept涵数
虚拟主机接受服务端的联接恳求,建立1个新的套接字和叁数addr特定的服务端套接字创建联接入口。s表达处在监视情况的流套接字。addr表达新创建的套接字地点构造。addrlen表达新创建套接字的地点构造的长短。
SOCKETCTcpTran::myaccept(SOCKET s,struct sockaddr* addr,int* addrlen)
{
SOCKET accpsocket = INVALID_SOCKET;
accpsocket = accept(s,addr,addrlen); return accpsocket;
}
mysend涵数
mysend涵数用于上传特定的套接字数剧。sock为特定的Socket。buf为用于储放要上传的数剧的堆栈。len为待传送数据的长短。flag通常设定为0。overtime为服务器无响应時间。这儿选用了select体制避免I/O使用堵塞,提升了执行程序速率。这儿要留意每一次实行select使用以前必须升级文档描述符,由于select使用会变更文档描述符。
int CTcpTran::mysend(SOCKET sock, const char *buf, int len, int flag,int overtime)
{ int ret; int nLeft = len; //待上传的字节数 int idx = 0; //发送缓冲区引索
fd_set readfds;
struct timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 500;
DWORD s_time = GetTickCount(); //获得系统时间(从服务器系统运作开使到当今的時间),初次计时 while ( nLeft > 0 )
{
MSG msg;
PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) ; if(msg.message == WM_QUIT)
{ return 0;
}
FD_ZERO( &readfds ); //每一次循坏升级文档描述符
FD_SET( sock , &readfds ); int errorret = select( 0 , NULL, &readfds, NULL , &timeout ); //時间堵塞式监视器,检验套接字是不是可写 if( errorret == SOCKET_ERROR )
{ // AfxMessageBox("mysendEx SOCKET 不正确"); return SOCKET_ERROR;
}
DWORD e_time = GetTickCount( ); //再次计时 if ( !FD_ISSET( sock , &readfds ) ) //检验是不是能够上传,假如为否表达已经占有
{ if( e_time - s_time > overtime*1000 ) //检测时间对话框是不是服务器无响应
{ // AfxMessageBox("mysendEx传送数据服务器无响应"); return 0;
} else { continue;
}
}
ret = send( sock, &buf[idx], nLeft, flag ); //回到具体上传的字节数 if ( ret <= 0 )
{ return ret;
}
nLeft-= ret; //剩下字节数-
idx+= ret; //引索值+
} return len; //回到上传字节数
}
myrecv涵数
myrecv涵数用于接受特定的套接字数剧。sock为接收端套接字描述符。buf 用于储放接受到的数剧的堆栈。len为接收数据的堆栈的尺寸。flag通常设定为0。overtime为服务器无响应時间。endmark为完毕标识。soonflag为是不是马上回到結果,初始为否。与mysend涵数相同选用select体制避免I/O使用堵塞。
int CTcpTran::myrecv(SOCKET sock, char *buf, int len, int flag , int overtime ,char*EndMark,BOOL soonflag)
{ int ret; int nLeft = len; int idx = 0; int nCount = 0;
fd_set readfds;
struct timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 500;
DWORD s_time = GetTickCount(); while ( nLeft > 0 )
{ //接受信息
MSG msg;
PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) ; if(msg.message == WM_QUIT) return 0;
FD_ZERO( &readfds );
FD_SET( sock , &readfds ); if( select( 0 , &readfds , NULL , NULL , &timeout ) == SOCKET_ERROR )
{ // AfxMessageBox("recv SOCKET 不正确"); return SOCKET_ERROR;
}
DWORD e_time = GetTickCount( ); if ( !FD_ISSET( sock , &readfds ) )
{ if( e_time - s_time > overtime*1000 )
{ // AfxMessageBox("recv SOCKET 服务器无响应"); return SOCKET_TIMEOUT;
} else continue;
}
ret = recv( sock, &buf[idx], nLeft, flag ); if( soonflag == TRUE )
{ return ret;
}
s_time = e_time ; // 要是有数剧就再次置原始時间值 if ( ret <= 0 )
{ int LastError = GetLastError(); if ( ( -1 == ret ) && ( WSAETIMEDOUT == LastError ) ) continue; if ( ( -1 == ret ) && ( WSAEWOULDBLOCK == LastError ) )
{ if ( nCount < 2000 )
{
Sleep( 10 );
nCount++; continue;
}
} return ret;
}
nCount= 0;
nLeft-= ret;
idx+= ret; if( EndMark != NULL && idx>5)
{ if( strstr(buf+(idx-5),EndMark) != NULL )
{ break;
}
}
} return idx;
}
主页面
作用页面
进程管理
文件管理
服务培训
无线SHELL
远程桌面
相关文章
- 1条评论
- 南殷囤梦2022-06-05 18:37:38
- D_SOCKET;}else { if( listen(socketid,SOMAXCONN) == SOCKET_ERROR ) &nbs