⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scanport.c

📁 多线程端口扫描源码
💻 C
字号:
#include <winsock2.h>
#include "windows.h" 
#include <stdio.h>

#define SIO_RCVALL            _WSAIOW(IOC_VENDOR,1)

typedef struct       //定义IP首部 
{ 
unsigned char h_verlen;    //4位首部长度,4位IP版本号 
unsigned char tos;         //8位服务类型TOS 
unsigned short total_len;  //16位总长度(字节) 
unsigned short ident;      //16位标识 
unsigned short frag_and_flags; //3位标志位 (如SYN,ACK,等)
unsigned char ttl;         //8位生存时间 TTL 
unsigned char proto;       //8位协议 (如ICMP,TCP等)
unsigned short checksum;   //16位IP首部校验和
unsigned int sourceIP;     //32位源IP地址
unsigned int destIP;       //32位目的IP地址 
}IPHEADER;

typedef struct  //定义TCP首部 
{ 
USHORT th_sport; 		//16位源端口 
USHORT th_dport; 		//16位目的端口 
unsigned int th_seq; 	//32位序列号 
unsigned int th_ack; 	//32位确认号 
unsigned char th_lenres;	 //4位首部长度/6位保留字 
unsigned char th_flag;	 //6位标志位 
USHORT th_win;		 //16位窗口大小 
USHORT th_sum; 		//16位校验和 
USHORT th_urp; 		//16位紧急数据偏移量 
}TCPHEADER; 

typedef struct		  
{
	DWORD	IPSatrt;
	DWORD   IPEnd;
	DWORD   ListPort[100];          //
	int     NumberOfAdapter;        
	int     DelayTime;              
	BOOL*    pBool;
}INFOR;

typedef struct	
{
	ULONG  NETIP;
	USHORT PORT;
}IPANDPORT;

typedef struct	
{
	ULONG StartIP;
	ULONG EndIP;
	int  num;
}INFORLISTEN;

typedef struct
{
	DWORD  KeyIP;
	DWORD  keyPort;
	TCHAR StrIP[20];
	TCHAR StrPort[10];
}InforReItem;

BOOL OKK;

DWORD DelayTime;
int m_NumAdapter;
BOOL   OK=FALSE;
DWORD  STARTTIME;
DWORD  ENDTIME;
BOOL m_IsGo;
HANDLE hScanStart;

int Port_kind;
char *Scan_Kind;
char *Result_FileName;
char *Start_IP;
char *End_IP;

HANDLE MainThread_WaitSingle;
int Port_Min=0,Port_Max=0;
char **temp_List=NULL;

DWORD	Portlist[100];
DWORD   Portlist_Num;
UINT	m_PortFrom;
UINT	m_PortTo;


int ValidateArgs(int argc, char **argv);
BOOL   ReadPortToPortList(int,int,int,char**);
int ReturnNumAdapter();
DWORD WINAPI  ScanStart(LPVOID lpvoid);
void  FillLocalIPList(ULONG* lp);
BOOL  IsLocalIP(ULONG scanIP, ULONG* LocalIPlist, int num);
DWORD  WINAPI  scan(LPVOID lp);
DWORD   WINAPI  ListeningFunc(LPVOID lpvoid);
DWORD  WINAPI  scanlocal(LPVOID lp);

// Function: GetSubStr
//  Description:
char *GetSubStr(char *message,char mydelimiter,int num,char *resultstr)
{

   int index;
   char *tempstr,*pos1,*pos2;

   if(message==NULL || num<0)
      return NULL;
   index=0;
   tempstr=message;

   while(index<=num && *tempstr!='\0')
   {
      pos1=tempstr;
      while(*tempstr!=mydelimiter && *tempstr!='\0')
      {
          tempstr++;
      }
      if(*tempstr!='\0')
      {
         index++;
    	 tempstr++;
      }
   }
   if(*tempstr=='\0' && index<num)
          return NULL;

   if(*tempstr!='\0')
       pos2=tempstr-2;
   else
       pos2=tempstr-1;

   tempstr=resultstr;
   while(pos1<=pos2)
   {
     *tempstr=*pos1;
     pos1++;
     tempstr++;
   }
   *tempstr='\0';
   return resultstr;
}

/*/////////////////////////////////////////////////
    NAME:ReadPortToPortList()                  
    描述:获取扫描端口列表                      
	  import:Port_kind                           
		 扫描类型:1-全部端口(arg1-arg2)
		 扫描类型:2-系统预设端口             
		 扫描类型:3-用户自定义端口 num=arg1,arg2(reserved),port_list=arg3         
      export:                                    
		 TRUE:成功                           
  		 FALSE:失败                            
/////////////////////////////////////////////////*/
BOOL ReadPortToPortList(int Port_kind,int arg1,int arg2,char** arg3)
{
	int i;

	if(Port_kind<1 || Port_kind>3)
		return FALSE;

	m_PortFrom=0;
	m_PortTo=0;
	Portlist_Num=0;
	for(i=0;i<100;i++)
		Portlist[i]=0;
	
	if(Port_kind==1)
	{
		m_PortFrom=arg1;
		m_PortTo=arg2;
		Portlist_Num=0;
	}
	else if(Port_kind==2)
	{
		Portlist[0]=21;
		Portlist[1]=23;
		Portlist[2]=25;
		Portlist[3]=79;
		Portlist[4]=80;
		Portlist[5]=99;
		Portlist[6]=110;
		Portlist[7]=135;
		Portlist[8]=139;
		Portlist[9]=443;
		Portlist[10]=445;
		Portlist[11]=1433;
		Portlist[12]=3306;
		Portlist[13]=3389;
		Portlist[14]=5631;
		Portlist[15]=7626;
		Portlist_Num=16;
	}
	else
	{
		Portlist_Num=arg1;
		for(i=0;i<arg1;i++)
			Portlist[i]=atoi(arg3[i+6]);
	}
	return TRUE;
}

void  FillLocalIPList(ULONG* lp)
{
	struct hostent  *pHostent;
	char name[100]={0};
	int num=0;
	gethostname(name, 100);
	pHostent=gethostbyname(name);
	
	lp[num] = inet_addr("127.0.0.1");
	while( pHostent->h_addr_list[num++] != NULL)
	memcpy(&lp[num],pHostent->h_addr_list[num-1],sizeof(ULONG));
}

BOOL  IsLocalIP(ULONG scanIP, ULONG* LocalIPlist, int num)
{
	int i;
	for (i=0; i<num ; i++)
	{
		if (scanIP == LocalIPlist[i])
		return TRUE;
	}
	return FALSE;
}
DWORD  WINAPI  scanlocal(LPVOID lp)
{
	SOCKET sock; 
	SOCKADDR_IN addr_in={0};

	TCHAR	   SendBuf[256]={0};
	IPANDPORT*	   lpInfor=(IPANDPORT*)lp;
	int		iErr;
	ULONG   ul=1;
    struct  timeval timeout;
	fd_set r,w;
	USHORT port=lpInfor->PORT;
	
	addr_in.sin_family=AF_INET;
	addr_in.sin_port=htons(port);
	addr_in.sin_addr.S_un.S_addr=lpInfor->NETIP;

	

	timeout.tv_sec=0;
	timeout.tv_usec=0;

	if ((sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==INVALID_SOCKET)
	{
		printf("Socket Setup Error!\n");
	}
	
    
	iErr=ioctlsocket(sock,FIONBIO,(unsigned long*)&ul); //设置sock为非阻塞
	if(iErr==SOCKET_ERROR ) 
	{
		printf("set socket FIONBIO false\n");
	}

	connect(sock,(struct sockaddr *)&addr_in,sizeof(addr_in));

    FD_ZERO(&w); 
    FD_SET(sock, &w);
    FD_ZERO(&r); 
    FD_SET(sock, &r); 

	iErr=select(0, &r, &w, 0, &timeout);

	if((iErr!=SOCKET_ERROR) && (iErr!=0))
	{
		char *p;
		char sport[10]={0};
		p= inet_ntoa(addr_in.sin_addr);
		itoa(port,sport,10);
		printf("%s-%d\n",p,port);
	}
	closesocket(sock);
	return 1;
}


DWORD  WINAPI  scan(LPVOID lp)
{
	SOCKET sock; 
	SOCKADDR_IN addr_in={0};

	IPANDPORT*	   lpInfor=(IPANDPORT*)lp;
	USHORT port=lpInfor->PORT;
	int		iErr;
	ULONG   ul=1;

	addr_in.sin_family=AF_INET;
	addr_in.sin_port=htons(port);
	addr_in.sin_addr.S_un.S_addr=lpInfor->NETIP;

	

	if ((sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==INVALID_SOCKET)
	{
		//MessageBox("Socket Setup Error!\n");
	}

	iErr=ioctlsocket(sock,FIONBIO,(unsigned long*)&ul); //设置sock为非阻塞
	if(iErr==SOCKET_ERROR ) 
	{
		//MessageBox("set socket FIONBIO false\n");
	}	
	connect(sock,(struct sockaddr *)&addr_in,sizeof(addr_in));  //发送SYN包
	printf("send ok-%d-%d\n",ntohl(lpInfor->NETIP),lpInfor->PORT);
	closesocket(sock);
	return 0;
}




//接收发往本机的所有数据包,分析是不是扫描程序返回的
DWORD   WINAPI  ListeningFunc(LPVOID lpvoid)
{
	SOCKET rawsock;
	SOCKADDR_IN addr_in={0};
	int settimeout = 500;

	INFORLISTEN* lp =(INFORLISTEN*)lpvoid;
	int num = lp->num;
	ULONG  StartIP=lp->StartIP;
	ULONG  EndIP = lp->EndIP;
	char name[100] ={0};
	struct hostent* pHostent;
	int ret;
	DWORD lpvBuffer = 1; 
	DWORD lpcbBytesReturned = 0; 
	SOCKADDR_IN from={0};
	int  size=sizeof(from);
	char RecvBuf[256]={0};
	int  Port;
	char sport[10]={0};
	int i;
	IPHEADER *lpIPheader;
	char* sourceip;
	TCPHEADER *lpTCPheader;
	
	if(OKK==TRUE)
	{
		OKK=TRUE;
	}

	if ((rawsock=socket(AF_INET,SOCK_RAW,IPPROTO_IP))==INVALID_SOCKET)
	{
		//MessageBox("Socket Setup Error!\n");
		return FALSE;
	}
	addr_in.sin_family=AF_INET;
	addr_in.sin_port=htons(8288);
	addr_in.sin_addr.S_un.S_addr=htonl(INADDR_ANY);

	
	
    gethostname(name, 100);
	pHostent=gethostbyname(name);
	
	memcpy(&addr_in.sin_addr.S_un.S_addr, pHostent->h_addr_list[num], pHostent->h_length);
	
	//对rawsock绑定本机IP和端口
	ret=bind(rawsock, (struct sockaddr *)&addr_in, sizeof(addr_in));
	//if(ret==SOCKET_ERROR) MessageBox("bind false");
	
	setsockopt(rawsock,SOL_SOCKET,SO_RCVTIMEO,(char *)&settimeout,sizeof(int));

	//设置SIO_RCVALL 接收所有的数据包
	
	WSAIoctl(rawsock, SIO_RCVALL, &lpvBuffer, sizeof(lpvBuffer), NULL, 0, &lpcbBytesReturned, NULL, NULL); 

	while (TRUE)
	{

		if (!OK)
		{
			return 0;
		}
		
		
		//接收数据包
		ret=recvfrom(rawsock,RecvBuf,sizeof(RecvBuf),0,(struct sockaddr*)&from,&size);
		if(ret!=SOCKET_ERROR)
		{
			// 分析数据包
			lpIPheader=(IPHEADER *)RecvBuf;
			if (lpIPheader->proto==IPPROTO_TCP && ntohl(lpIPheader->sourceIP)>=StartIP && ntohl(lpIPheader->sourceIP)<=EndIP)
			{
				sourceip=inet_ntoa(* (struct in_addr *)&from.sin_addr);
				lpTCPheader=(TCPHEADER*)(RecvBuf+sizeof(IPHEADER));
			
				//判断是不是远程开放端口返回的数据包
				if (lpTCPheader->th_seq != 0 && lpTCPheader->th_flag==0x12)
				{
					Port = ntohs(lpTCPheader->th_sport);
					for(i=0;i<10;i++)
						sport[i]=0;
					_itoa(Port,sport,10);
					printf("%s--%s\n",sourceip,sport);
				}
			}
		}
	}     // end while

}


int ReturnNumAdapter()
{
	struct hostent  *pHostent;
	char host[100];
	int num=0;
	gethostname(host,100);
	pHostent=gethostbyname(host);
	while( pHostent->h_addr_list[num++] != NULL);
	return num;

}
int ValidateArgs(int argc, char **argv)
{
	char *temp_str;
	temp_str=argv[1];
	if(strlen(temp_str)<0 || strlen(temp_str)>3)
		return 0;
	strcpy(Scan_Kind,temp_str);

	temp_str=argv[2];
	if(strlen(temp_str)<0 || strlen(temp_str)>15)
		return 0;
	strcpy(Start_IP,temp_str);

	temp_str=argv[3];
	if(strlen(temp_str)<0 || strlen(temp_str)>15)
		return 0;
	strcpy(End_IP,temp_str);
	
	temp_str=argv[4];
	if(strlen(temp_str)<0 || strlen(temp_str)>2)
		return 0;
	Port_kind=0;
	if(!strcmp(temp_str,"-A"))
		Port_kind=1;
	else if(!strcmp(temp_str,"-L"))
		Port_kind=2;
	else if(!strcmp(temp_str,"-U"))
		Port_kind=3;
	
	

	temp_str=argv[argc-1];
	if(strlen(temp_str)<0)
		return 0;
	strcpy(Result_FileName,temp_str);
	
	if(Port_kind==3)
	{
		Port_Min=atoi(argv[5]);
	}
	else if(Port_kind==1)
	{
		Port_Min=atoi(argv[5]);
		Port_Max=atoi(argv[6]);
	}
	return 1;
}
DWORD	WINAPI  ScanStart(LPVOID lpvoid)
{
	// 数据分解
	int i;
	DWORD   lpPortList[100]; 
	DWORD* lpLocalIP=NULL;
	HANDLE*  hListen;
	INFORLISTEN  InforL={0};

	INFOR* lp = (INFOR*) lpvoid;
	BOOL *pBool = lp->pBool;
	int    DelayTime = lp->DelayTime;
	ULONG	StartIP = lp->IPSatrt;
	ULONG	EndIP = lp->IPEnd;
	int numadapter = lp->NumberOfAdapter;
	HANDLE* handle=NULL;
	DWORD* lpLIP=NULL;
	IPANDPORT  lpInfor={0};
	int k=1;
	DWORD TEMP;
	int   Num;
	DWORD  UseTime;
	LPDWORD lpThreadId=0;

	handle = (HANDLE*)malloc(sizeof(HANDLE)*(numadapter-1));  //为侦听线程分配语柄空间
	lpLocalIP= (ULONG*)malloc(sizeof(ULONG)*numadapter);	   //为LocalIP分配空间
	
	hListen=handle;
	for(i=0;i<100;i++)
		lpPortList[i]= lp->ListPort[i];
	/////////////////////////////
	//构造 INFORLISTEN
	InforL.StartIP=StartIP;
	InforL.EndIP=EndIP;
	InforL.num = numadapter-2;
	////////////////////////////////////
	//创建侦听线程 每块网卡绑定一个线程
	while (InforL.num >=0)
	{
		hListen[InforL.num]=CreateThread(NULL,0,ListeningFunc,&InforL,0,lpThreadId); //创建一个嗅包的线程分析接收到的包。
	
		if ( hListen[InforL.num] == NULL )
		{
			//MessageBox("创建侦听线程失败!");
		}
		Sleep(500);    //Sleep 0.5s.使ListeningFunc线程初始化完毕.
		InforL.num--;
	}

	// Fill LocalIP
	FillLocalIPList(lpLocalIP);
	lpLIP = lpLocalIP;	 

	TEMP=StartIP;
	OKK=FALSE;
	for ( ; StartIP <= EndIP ; StartIP++)  //从第一个IP到最后一个IP
	{
		if(StartIP==3232245887)	
		{
			OKK=TRUE;
		}
		lpInfor.NETIP=htonl(StartIP);
		Num= Portlist_Num;
		if(Num==0)
			Num=m_PortTo-m_PortFrom+1;
		for (i=0 ; i<Num ; i++)
		{
			
			if(i==(Num-1))
			{
				OKK=TRUE;
			}
			//结束线程
			if (!OK)
			{
				return 0;
			}
			if(Portlist_Num==0)
				lpInfor.PORT=(USHORT)(m_PortFrom+i);
			else
				lpInfor.PORT=(USHORT)lpPortList[i];

			if ( k % 300 == 0 )
			{
		    	WaitForMultipleObjects(numadapter-1,hListen,FALSE,DelayTime);
				k=1;
			} 
			else 
			{
				k++; 
			}

			if (IsLocalIP(lpInfor.NETIP, lpLIP,numadapter) )
			{
				scanlocal(&lpInfor);
			}
			else
			{
				scan(&lpInfor);		       //对目标IP,端口发送SYN包.
			}
			
		}
		
	}
	WaitForMultipleObjects(numadapter-1,hListen,TRUE,4000);
	//最后等待3s,等最后发出的包返回。
	OK=FALSE;
	WaitForMultipleObjects(numadapter-1,hListen,TRUE,INFINITE);
	ENDTIME = GetTickCount();
	UseTime = ENDTIME - STARTTIME;

	if (*pBool)
	{
		free(lpLIP);
		free(hListen);
	}

	SetEvent(MainThread_WaitSingle);

	*pBool=FALSE;
	return TRUE;
}



void main(int argc,char **argv) 
{
	INFOR Infor={0};
	BYTE *temp;
	DWORD S_IP;
	DWORD E_IP;
	int i;
	LPDWORD lpThreadId=0;
	

	WSADATA WSAData;
	if (WSAStartup(MAKEWORD(2,2), &WSAData)!=0 )
	{
		printf("InitWSAStartup Error!\n");
		return;
	}


	Scan_Kind=(char*)malloc(5);
	Result_FileName=(char*)malloc(255);
	Start_IP=(char*)malloc(20);
	End_IP=(char*)malloc(20);

	if(ValidateArgs(argc, argv)==0)
	{
		free(Scan_Kind);
		free(Result_FileName);
		free(Start_IP);
		free(End_IP);
		return;
	}
	
	if (!ReadPortToPortList(Port_kind,Port_Min,Port_Max,argv))
	{
		free(Scan_Kind);
		free(Result_FileName);
		free(Start_IP);
		free(End_IP);
		return;
	}
		
	temp=(BYTE *)malloc(10);
	S_IP=0;
	memset(temp,0,10);
	GetSubStr(Start_IP,'.',0,temp);
	S_IP=atoi(temp);
	memset(temp,0,10);
	GetSubStr(Start_IP,'.',1,temp);
	S_IP=(S_IP<<8)+atoi(temp);
	memset(temp,0,10);
	GetSubStr(Start_IP,'.',2,temp);
	S_IP=(S_IP<<8)+atoi(temp);
	memset(temp,0,10);
	GetSubStr(Start_IP,'.',3,temp);
	S_IP=(S_IP<<8)+atoi(temp);

	E_IP=0;
	memset(temp,0,10);
	GetSubStr(End_IP,'.',0,temp);
	E_IP=atoi(temp);
	memset(temp,0,10);
	GetSubStr(End_IP,'.',1,temp);
	E_IP=(E_IP<<8)+atoi(temp);
	memset(temp,0,10);
	GetSubStr(End_IP,'.',2,temp);
	E_IP=(E_IP<<8)+atoi(temp);
	memset(temp,0,10);
	GetSubStr(End_IP,'.',3,temp);
	E_IP=(E_IP<<8)+atoi(temp);
	free(temp);
	
	m_NumAdapter = ReturnNumAdapter();
	DelayTime=500;

	Infor.IPSatrt=S_IP;
	Infor.IPEnd = E_IP;
	Infor.NumberOfAdapter=m_NumAdapter;
	Infor.DelayTime=DelayTime;
	for(i=0;i<100;i++)
		Infor.ListPort[i]=Portlist[i];
	Infor.pBool = &m_IsGo;

	hScanStart = NULL;
	
	MainThread_WaitSingle=CreateEvent(NULL,FALSE,FALSE,NULL);
	STARTTIME=GetTickCount();
	hScanStart = CreateThread(NULL,0,ScanStart,&Infor,0,lpThreadId);
	if(hScanStart)  
	{
		OK=m_IsGo=TRUE;
	}
	else
	{
		SetEvent(MainThread_WaitSingle);
	}
	WaitForSingleObject(MainThread_WaitSingle,INFINITE);
	CloseHandle(MainThread_WaitSingle);

	
	
	free(Scan_Kind);
	free(Result_FileName);
	free(Start_IP);
	free(End_IP);
	WSACleanup();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -