📄 tcpconnectscan.cpp
字号:
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#pragma comment (lib, "ws2_32.lib")
// 端口结构,包括开始端口和结束端口
typedef struct _PortList
{
unsigned int start_port;
unsigned int end_port;
unsigned short thread_id;
}PortList;
#define MAX_THREAD 60 // 定义最大线程数
char TargetIP[20]; // 目标机IP地址
unsigned int ThreadNum; // 扫描线程数
unsigned int StartPort;
unsigned int EndPort;
// 解析命令函数
void ParseCmd(int argc, char **argv)
{
char *pdest;
int result;
int ch = '-'; // 分隔符
char startport[8];
char endport[8];
ZeroMemory(startport,8);
ZeroMemory(endport,8);
if(argc < 3 || argc >4)
{
printf("usage : %s [TargetIP] [StartPort-EndPort] [ThreadNum]\n");
}
else// 参数为3个时,默认线程数为1
{
strcpy(TargetIP,argv[1]); // 获取目标机IP
pdest = strchr( argv[2], ch );
result = pdest - argv[2] + 1; // 寻找‘-’的位置
strncpy(startport,argv[2],result-1); // 提取开始端口
strncpy(endport,argv[2]+result,strlen(argv[2])-result); // 提取结束端口
StartPort = atoi(startport);
EndPort = atoi(endport);
}
if(argc == 3)
{
ThreadNum = 1;
}
else
{
ThreadNum = atoi(argv[3]); // 提取线程数
if(ThreadNum>MAX_THREAD)
{
printf("超出最大线程数范围(1-60)!\n");
exit(0);
}
}
}
// 端口扫描线程
DWORD WINAPI ScanHost(LPVOID lpParam)
{
WSADATA wsd;
// 初始化Winsock库
if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
{
printf("加载Winsock失败!\n");
return 0;
}
unsigned int startport; // 每个线程的开始端口
unsigned int endport; // 每个线程的结束端口
unsigned short threadid; // 进程标志位
PortList *pl;
pl = (PortList *)malloc(sizeof(PortList));
if(pl == NULL)
{
printf(" 不能分配足够的内存!\n");
exit(0);
}
pl = (PortList *)lpParam;
startport = pl->start_port;
endport = pl->end_port;
threadid = pl->thread_id;
SOCKET client_sock;
struct sockaddr_in server;
// 创建连接端口的套接字
client_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (client_sock == INVALID_SOCKET)
{
printf("创建socket失败: %d\n", WSAGetLastError());
return 0;
}
// 设置目标机相关参数
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr(TargetIP);
// 开始探测端口
for( unsigned int i=startport; i<=endport; i++)
{
// 设置目标机端口
server.sin_port = htons(i);
if (connect(client_sock, (struct sockaddr *)&server,
sizeof(server)) == SOCKET_ERROR)
{ // 连接不成功,端口未开放
// printf("端口 %5d 未开放 ---Thread %d\n", i, threadid);
}
else
{ // 连接成功,端口开放
printf("端口 %5d 开放!! ---Thread %d\n",i ,threadid);
}
Sleep(1);
}
closesocket(client_sock);
return NULL;
}
int main(int argc, char **argv)
{
ParseCmd(argc,argv);
unsigned int portnum = EndPort-StartPort+1; // 总共的端口数目
if(portnum<ThreadNum)
{
printf("请确保总端口数目大于线程数!\n");
exit(0);
}
PortList *pl;
pl = (PortList *)malloc(sizeof(PortList));
if(pl == NULL)
{
printf(" 不能分配足够的内存!\n");
exit(0);
}
printf("\n开始扫描目标主机 %s 端口范围 %d-%d 线程数 %d\n\n",TargetIP,StartPort,EndPort,ThreadNum);
int aver = portnum/ThreadNum; // 每个线程的端口数目
DWORD dwStart = GetTickCount(); // 计时开始
HANDLE h[MAX_THREAD]; // 线程句柄
for(unsigned int i=0; i<ThreadNum; i++)
{
// 设置每个线程开始端口
pl->start_port = StartPort + i*aver;
pl->thread_id = i+1; // 线程ID
// 设置每个线程结束端口
if(i!=ThreadNum-1)
{
pl->end_port = StartPort + (i+1)*aver -1;
}
else
{
pl->end_port = EndPort;
}
// 创建扫描线程
h[i] = CreateThread(NULL, 0, ScanHost, pl, 0, 0);
Sleep(100);
}
// 等待线程全部结束
WaitForMultipleObjects(ThreadNum,h,TRUE,INFINITE);
printf("\n 端口扫描消耗时间 : %d ms \n",GetTickCount()-dwStart);
free(pl);
return 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -