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

📄 pr.c

📁 端口扫描工具(速度其快)源代码
💻 C
字号:

////////////////////////////////////////////////////////////////////////////////////////////////////
//工程 :PR
//版本 :1.6
//编译 :LCC-Win32 3.3
//版权 :源代码公开,不保留版权
//作者 :点普工作室(Yonsm)
//主页 :http://dotpot.533.net
//邮箱 :dotpot@163.net
//日期 :2002年1月
//说明 :这是PortReady的控制台版本,用LCC-Win32编译,大小为8KB。
//    此版本也可以在Visual C++ 6.0下编译,大小为36K。
//    LCC-Win32及其汉化补丁可在点普工作室主页上下载。
////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////
//LCC-Win32编译时请添加下列文件到工程中(可使用相对目路径):
//    WSOCK32.lib
//    PortReady.c
//    Resource.rc
////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <winsock.h>
#pragma comment(lib,"wsock32.lib")
////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////
typedef	struct tagThread
{
	DWORD			dwAddr;
	WORD			wPort;
}THREADINFO;
////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////
int					nTimeOut;
int					nThreadNum;
BOOL				isEnglish;
BOOL				isVerbose;
BOOL				isGetBanner;
FILE				*fpFile;
THREADINFO			thdINFO[300];
////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////
void WINAPI	ScanThread(int nCurTread)
{
	int					nThread = nCurTread;
	FD_SET				mask;
	u_long				value;
	SOCKET				sockfd;
	TIMEVAL				timeout;
	SOCKADDR_IN			addr;
	IN_ADDR				iaCurServer;
	int					i;
	char				*p;
	char				*pTemp;
	char				strTemp[256];
	char				strAddr[22];

	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if(sockfd==INVALID_SOCKET)
		printf("Socket %s!\n",isEnglish?"error":"错误");
	else
	{
		value=1;
		ioctlsocket(sockfd,FIONBIO,&value);
		addr.sin_family	= AF_INET;
		addr.sin_port =	htons(thdINFO[nThread].wPort);
		addr.sin_addr.s_addr = ntohl(thdINFO[nThread].dwAddr);
		connect(sockfd,(struct sockaddr	*) &addr, sizeof(addr));

		timeout.tv_sec=nTimeOut;
		timeout.tv_usec=0;
		FD_ZERO(&mask);
		FD_SET(sockfd,&mask);
		value=select(sockfd+1,NULL,&mask,NULL,&timeout);

		iaCurServer.s_addr=htonl(thdINFO[nThread].dwAddr);
		wsprintf(strAddr,"%s:%d",inet_ntoa(iaCurServer),thdINFO[nThread].wPort);
		if(value &&	value!=SOCKET_ERROR)
		{
			p=NULL;
			if(isGetBanner && ((thdINFO[nThread].wPort==21) || (thdINFO[nThread].wPort==23) || (thdINFO[nThread].wPort==25) ||	(thdINFO[nThread].wPort==79)	|| (thdINFO[nThread].wPort==80) || (thdINFO[nThread].wPort==110) ))
			{
				if(thdINFO[nThread].wPort==80)
					send(sockfd,"GET HEAD HTTP/1.1\n\n",20,0);
				ZeroMemory(strTemp,sizeof(strTemp));
				for(i=0;i<nTimeOut*20;i++)
				{
					Sleep(100);
					if(recv(sockfd,strTemp,sizeof(strTemp),0)>0)
						break;
				}
				if((thdINFO[nThread].wPort==80) && (p=strstr(strTemp,"Server:")))
				{
					p+=8;
					if(	(pTemp=strchr(p,'\r')) || (pTemp=strchr(p,'\n')) )
						*pTemp='\0';
				}
				else
					p=strTemp;
				for(pTemp=p;*pTemp;pTemp++)
				{
					if(*pTemp=='\n'||*pTemp=='\r')
						*pTemp=' ';
				}
			}
			printf("%s\t%s \t-> %s\n",isEnglish?"Scan":"扫描",strAddr,isEnglish?"Found !!!":"开放!!!!");
			if(p)
			{
				printf("\t%s\n",p);
				fprintf(fpFile,"%s\t%s\n",strAddr,p);
			}
			else
				fprintf(fpFile,"%s\n",strAddr);
			fflush(fpFile);
		}
		else if(isVerbose)
			printf("%s\t%s \t-> %s\n",isEnglish?"Scan":"扫描",strAddr,isEnglish?"No response":"没有反应");
	}
	thdINFO[nThread].wPort=0;
	nThreadNum--;
	closesocket(sockfd);
}
////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////
int main(int argc, char *argv[])
{
	char			*p;
	int				i;
	int				j;
	int				k;
	int				nMAXThread;
	int				nStartPort;
	int				nEndPort;
	int				nPort[100];
	int				nPortCount;
	DWORD			dwCurIP;
	DWORD			dwStartIP;
	DWORD			dwEndIP;
	DWORD			dwThreadID;
	WSADATA			wsaData;
	IN_ADDR			iaServer;

	isVerbose=1;
	nPortCount=-1;
	for(i=1;i<argc;i++)				//参数分析
	{
		if((argv[i][0]=='-') || (argv[i][0]=='/'))
		{
			p=&argv[i][3];
			switch(argv[i][1])
			{
				case 'b':
				case 'B':
					isGetBanner=1;
					break;
				case 'd':
				case 'D':
					nTimeOut=atoi(p);
					break;
				case 'e':
				case 'E':
					isEnglish=1;
					break;
				case 't':
				case 'T':
					nMAXThread=atoi(p);
					break;
				case 'o':
				case 'O':
					isVerbose=0;
			}
		}
	}

	printf("Dotpot PortReady Ver1.6\nCopyLeft(L) %s\n\n",isEnglish?"Dotpot Studio 2001-2002. No rights reserved\nFor more information,please visite http://dotpot.533.net":
		"点普工作室,2001-2002。不保留任何权利\n要获取更多信息,请访问 http://dotpot.533.net ");

	if(argc==1 || argc==2 || (argc==3 && isEnglish) || argc>8)//显示帮助信息
	{
		printf("%s\n\tPR.EXE <%s>[-%s] <%s1-%s2|%s1,%s2,...> [%s]\n",
			isEnglish?"Usage: ":"用法:",
			isEnglish?"StartIP":"起始地址",isEnglish?"EndIP":"停止地址",
			isEnglish?"Port":"端口",isEnglish?"Port":"端口",
			isEnglish?"Port":"端口",isEnglish?"Port":"端口",
			isEnglish?"Options":"选项");
		printf("\n%s\n",
			isEnglish?"Options:\n\t-b\t\tGet port banner\n\t-o\t\tOnly show open ports\n\t-e\t\tShow English message\n\t-d:delay\tScan delay,default is 2s\n\t-t:thread       Number of thread,default is 100":
			"选项:\n\t-b\t\t获取端口标识\n\t-e\t\t显示英文信息\n\t-o\t\t只显示开放端口\n\t-d:delay\t扫描延时,默认2秒\n\t-t:thread       线程数目,默认100个线程");
		printf("\n%s\n\tPR.EXE 192.168.0.1 1-65535 -d:1 -e\n\tPR.EXE 192.168.0.1 1-2000 -t:200 -v -b\n\tPR.EXE 192.168.0.1-192.168.9.255 21,3389 -t:200\n",
			isEnglish?"Example:":"例如:");
		return 1;
	}

	if(strchr(argv[1],'-'))//开始提取IP地址参数
	{
		for(p=argv[1];p;p++)
			if(*p=='-')
			{
				*p++='\0';
				dwEndIP=ntohl(inet_addr(p));
				break;
			}
	}
	else
		dwEndIP=ntohl(inet_addr(argv[1]));

	dwStartIP=ntohl(inet_addr(argv[1]));
	if((dwStartIP==INADDR_NONE)&&(dwEndIP==INADDR_NONE))
	{
		printf("%s\n",isEnglish?"IP address Error":"IP地址错误");
		return 2;
	}
	if(dwStartIP>dwEndIP)
	{
		dwCurIP=dwStartIP;
		dwStartIP=dwEndIP;
		dwEndIP=dwCurIP;
	}

	p=argv[2];//开始提取端口参数
	if(strstr(argv[2],"-"))//使用端口范围
	{
		nStartPort=atoi(argv[2]);
		for(;*p;)
			if(*(p++)=='-')
				break;
		nEndPort=atoi(p);
		if(nStartPort>nEndPort)
		{
			j=nStartPort;
			nStartPort=nEndPort;
			nEndPort=nStartPort;
		}
		if(nStartPort<1 || nEndPort>65535)
		{
			printf("%s!\n",isEnglish?"Port Error":"端口错误");
			return 3;
		}
	}
	else//使用端口列表
	{
		nPort[0]=atoi(p);
		if(nPort[0]<1 || nPort[0]>65535)
		{
			printf("%s!\n",isEnglish?"Port Error":"端口错误");
			return 3;
		}
		nPortCount++;
		for(i=0;*p && (i<100);)
		{
			if(*(p++)==',')
			{
				if(nPort[i]<1 || nPort[i]>65535)
				{
					printf("%s!\n",isEnglish?"Port Error":"端口错误");
					return 3;
				}
				i++;
				nPort[i]=atoi(p);
				nPortCount++;
			}
		}
	}

	if(nTimeOut<1 || nTimeOut>60)
		nTimeOut=2;
	if(nMAXThread<1 || nMAXThread>300)
		nMAXThread=100;//校验线程数目和延时时间

	if(!(fpFile=fopen("PortList.txt","a")))//打开结果文件
	{
		printf("%s:PortList.txt\n",isEnglish?"Could not create result file":"无法创建结果文件");
		return 5;
	}

	if(WSAStartup(MAKEWORD(1, 1), &wsaData))//初始化Winsock DLL
	{
		printf("%sWinsock DLL\n",isEnglish?"Could not initiate ":"无法初始化");
		return 6;
	}

	iaServer.s_addr=htonl(dwStartIP);//显示扫描范围和扫描端口
	printf("%s: %s-",isEnglish?"Scan range":"扫描范围",inet_ntoa(iaServer));
	iaServer.s_addr=htonl(dwEndIP);
	printf("%s\n%s: ",inet_ntoa(iaServer),isEnglish?"Scan ports":"扫描端口");

	if(nPortCount!=-1)
	{
		for(i=0;i<=nPortCount;i++)
			printf("%d ",nPort[i]);
		j=nPort[0];
	}
	else
	{
		j=nStartPort;
		printf("%d-%d",nStartPort,nEndPort);
	}
	printf("\n-----------------------------------------------------------------\n");

	k=0;
	dwCurIP=dwStartIP;
	while(dwCurIP<=dwEndIP)		//循环创建子线程
	{
		if(((dwCurIP % 256)==0)||((dwCurIP % 256)==255))		//忽略x.x.x.0和x.x.x.255
		{
			dwCurIP++;
			continue;
		}

		if(nThreadNum<nMAXThread)		//如果未达到最大线程数
		{
			for(i=0;i<300;i++)		//获取未使用的thdINFO
				if(thdINFO[i].wPort==0)
					break;

			thdINFO[i].wPort = j;
			thdINFO[i].dwAddr = dwCurIP;
			CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ScanThread,(LPVOID)i,0,&dwThreadID);	//创建子线程
			//ScanThread(i);	//由于LCC-Win32不支持多线程调试,为调试方便,可打开这一句并注释掉上一句
			nThreadNum++;

			if(nPortCount!=-1)	//更改端口
			{
				if(j==nPort[nPortCount])
				{
					j=nPort[0];
					dwCurIP++;
					k=0;
				}
				else
					j=nPort[++k];
			}
			else
			{
				if(j==nEndPort)
				{
					j=nStartPort;
					dwCurIP++;
				}
				else
					j++;
			}
		}
	}

	for(i=0;i<600;i++)		//等待线程退出,如果等了60秒仍未退出,可能出现了线程阻塞,强行退出
	{
		if(!nThreadNum)
			break;			//正常退出
		Sleep(100);
	}

	printf("-----------------------------------------------------------------\n%s.\t%s\n",
		isEnglish?"Scan complete":"扫描结束",
		isEnglish?"All available results appended to PortList.txt":"扫描结果保存在PortList.txt文件里");
	fclose(fpFile);
	WSACleanup();
	return 0;
}
////////////////////////////////////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

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