📄 scanport.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 + -