#pragma comment(lib,"ws2_32.lib")
#pragma warning (disable:4786)
#include <iostream>
#include <strstream>
#include <winsock2.h>
#include <windows.h>
#include <string>
#include <vector>
#include <map>
#include <fstream>
#include <time.h>
//#include "IpScan.h"
using namespace std;
//全局变量:
//待扫描的端口
short g_portsTOscan[]= {20,21,22,23,25,42,43,47,53,63,67,68,79,80,95,106,107,109,110,113,135,137,138,139,143,
144,161,162,443,445,1024,1080,1433,1434,1755,3306,4000,5010,5190,5631,5632,8000,8080 };
const short PORTSNUM = sizeof(g_portsTOscan) / sizeof(short);//端口个数
//等扫描的IP
vector<unsigned long> g_vec_IpToScan;
string g_startIp;
string g_endIp;
//开启的线程数,目前为1个IP1个线程
long g_runThreadNum;
//socket相关
TIMEVAL g_timeout; //阻塞等待时间
//FD_SET g_mask; //socket模式设置,储存socket信息
const short TIMEOUT = 1; //阻塞等待时间
WSADATA g_wsadata; //socket版本信息
//线程中的互斥体
HANDLE g_PortMutex;
HANDLE g_ThreadNumMutex;
HANDLE g_ResultMutex; //输入结果的互斥量
//保存IP扫描的结果
multimap<unsigned long, string> g_map_ScanResult;
//-------------------------------------------------------------------------------------------------------------------
//线程函数,扫描每一个IP
DWORD WINAPI ThreadFunc(LPVOID th_para)
{
//获取需要扫描的IP
//char *pStrIp = (char*)th_para;
unsigned long ulScanIp = *(unsigned long*)th_para;
int index = 0; //端口索引
SOCKET link_sock; //SOCKET
FD_SET set_flag; //SOCKET描述
short select_ret; //select异步返回值
short port; //正在扫描的端口
while (index < PORTSNUM)
{
port = g_portsTOscan[index];
//创建数据流套接字
link_sock = socket(AF_INET, SOCK_STREAM, 0);
if (link_sock == INVALID_SOCKET)
{
//cout << "创建link_sock socket失败:错误号为: " << GetLastError() << endl;
WaitForSingleObject(g_ThreadNumMutex,INFINITE);
g_runThreadNum--;
ReleaseMutex(g_ThreadNumMutex);
//cout << "***还有_"<< g_runThreadNum << "_个扫描线程进行中**"<< endl;
return -1;
}
FD_ZERO(&set_flag); //将指定文件描述符清空
FD_SET(link_sock,&set_flag); //用于在文件描述符集合中增加一个新的文件描述符
//设置连接地址
SOCKADDR_IN scan_addr;
scan_addr.sin_family = AF_INET;
scan_addr.sin_addr.s_addr = ulScanIp;
scan_addr.sin_port = htons(port);
unsigned long sock_set = 1;
ioctlsocket(link_sock,FIONBIO,&sock_set); //设置套接字为非阻塞模式,第3个参数非0为非阻塞
connect(link_sock,(struct sockaddr *) &scan_addr, sizeof(scan_addr));//连接指定IP端口
select_ret = select(0,NULL,&set_flag,NULL,&g_timeout);//异步返回值
if (select_ret == 0 || select_ret == -1)
{
++index;
continue;
}
else
{
strstream stream_result;
struct in_addr ipaddr;
ipaddr.s_addr = ulScanIp;
char *pStrIp = inet_ntoa(ipaddr);
stream_result << "\t 主机地址为:" << pStrIp << "\t找到开放的端口: " << port <<'\0';
string str_result(stream_result.str());
//将扫描结果储存到输出变量中去
WaitForSingleObject(g_ResultMutex,INFINITE);
g_map_ScanResult.insert(make_pair(ulScanIp,str_result));
ReleaseMutex(g_ResultMutex);
}
++index;
}
//扫描完一个线程
shutdown(link_sock, 0);
closesocket(link_sock);
WaitForSingleObject(g_ThreadNumMutex,INFINITE);
g_runThreadNum--;
ReleaseMutex(g_ThreadNumMutex);
//cout << "****还有_"<< g_runThreadNum << "_个扫描线程进行中****"<< endl;
return 0;
}
//----------------------------------------------------------------------------------------------------------
//将IP转化成能直接递增和递减的地址
unsigned long InvertIp(unsigned long srcIp)
{
unsigned char first;
unsigned char second;
unsigned char third;
unsigned char fourth;
first = srcIp & 0x00FF;
second = (srcIp >> 8) & 0x00FF;
third = (srcIp >> 16) & 0x00FF;
fourth = (srcIp >> 24) & 0x00FF;
return (first << 24) | (second << 16) | (third << 8) | fourth;
}
//------------------------------------------------------------------------------------------------
//将IP内的IP转化成一个一个unsigned long 类型存在数组中
int GetIpToScan(const string &StartIp, const string &EndIp, vector<unsigned long> &vec_ip)
{
//判断输入的IP是否合法
unsigned long ulStartIp = inet_addr(StartIp.c_str());
unsigned long ulEndIp = inet_addr(EndIp.c_str());
if(
INADDR_NONE == ulStartIp
||
INADDR_NONE == ulEndIp
)
{
cout << " 请输入合法的IP" << endl;
return -1;
}
//////////////判断查询的是一个IP还是IP段/////////////////////////////////////
if (ulStartIp == ulEndIp && ulStartIp !=0)
{
vec_ip.push_back(ulStartIp);
return 0;
}
if (ulStartIp == 0 && ulEndIp == 0)
{
return 0;
}
if (ulStartIp == 0)
{
vec_ip.push_back(ulEndIp);
return 0;
}
if (ulEndIp == 0)
{
vec_ip.push_back(ulStartIp);
return 0;
}
////////////////////////////////////////////////////////////////////////////
//将IP转换成可以递增比较的类型
ulStartIp = InvertIp(ulStartIp);
ulEndIp = InvertIp(ulEndIp);
//指定前后顺序,ulEndIp较大
unsigned long max_ip;
if (ulStartIp > ulEndIp)
{
max_ip = ulStartIp;
ulStartIp = ulEndIp;
ulEndIp = max_ip;
}
int ipnums = ulEndIp - ulStartIp;
for(int i = 0;i <= ipnums;++i)
{
//将每个IP的unsigned long型存到数组中供扫描
vec_ip.push_back(InvertIp(ulStartIp++));
}
return 0;
}
//-----------------------------------------------------------------------------------------------------------------
//功能: 输入一个IP段,输出该IP段内的端口开放情况信息
int ScanIp(const string &start_Ip, const string &endIp, multimap<unsigned long, string> &ouputMap)
{
//分解IP段内的IP到全局数组中去
GetIpToScan(start_Ip,endIp,g_vec_IpToScan);
int scanNum = g_vec_IpToScan.size();
//线程总数
g_runThreadNum = scanNum;
cout<<endl;
cout<<endl;
cout<<"********************************************************************************";
cout << " 共有 " << scanNum <<" 个IP要扫描 " << endl;
//对每个IP开一个线程
for (int i = 0; i < scanNum; ++i)
{
CreateThread(NULL,0,ThreadFunc,&g_vec_IpToScan[i],0,NULL);
//要是不间隔时间的话,同时创建socket会出现10093错误
Sleep(50);
}
return 0;
}
//-------------------------------------------------------------------------------------------------------
//输出扫描结果
int OutPutScanInfo()
{
cout <<" 扫描到 " << g_map_ScanResult.size() << " 条记录 " << endl;
multimap<unsigned long, string>::iterator iter = g_map_ScanResult.begin();
ofstream out("out.txt");
cout <<" 显示总 " << g_map_ScanResult.size() << " 条记录: " << endl;
cout<<endl;
for (; iter!=g_map_ScanResult.end(); ++iter)
{
out << iter->second << endl;
cout << iter->second << endl;
}
return 0;
}
//-----------------------------------------------------------

海棠花开555
- 粉丝: 33
最新资源
- ### 2025即时零售全时段消费场景新趋势报告:全时段消费生态的深度解析与未来展望
- python入门教程学习.md
- 基于文心大模型开发的 AI 机器人绘画插件
- ### 【玩具市场分析】2025解压玩具品类洞察报告:市场规模、消费者洞察与品牌案例分析
- python入门教程学习.md
- sysbench安装包
- ### 文章总结:2025金融大模型应用与智能体建设案例集述 本文档
- 通过VS实现TXT文件的读取
- python入门教程学习.md
- ### 2025年618大促消费数据洞察:电商行业全域概览与重点赛道复盘
- python入门教程学习.md
- 大模型基础前端CSS flex重点
- chromedriver-win32-141.0.7370.0(Canary).zip
- chromedriver-mac-x64-141.0.7370.0(Canary).zip
- chromedriver-win64-141.0.7370.0(Canary).zip
- chromedriver-mac-arm64-141.0.7370.0(Canary).zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈


