首页
社区
课程
招聘
[原创] 端口扫描器分析
发表于: 2012-1-22 20:30 6520

[原创] 端口扫描器分析

2012-1-22 20:30
6520
[原创] 端口扫描器分析
端口扫描器分析
玉面飞龙     BY: http://hi.baidu.com/alalmn
QQ 群30096995
TIME:2012-1-22
最近看很多朋友在写类似的东西自己也有点想玩玩,找些代码看看到底是怎么回事。
先看段代码
UINT _stdcall        ScanThread2()    //线程运行
{

        CString show;
        CSMQDlg*   dlg_r1=(CSMQDlg*)AfxGetMainWnd();;
// CListCtrl*   IDC_SHOWPORT=(CListCtrl*)   dlg_r1-> GetDlgItem(IDC_SHOWPORT);
        show += "显示结果...\r\n";
                dlg_r1->SetDlgItemText(IDC_EDIT2,show);

        CSMQDlg*   dlg_r2=(CSMQDlg*)AfxGetMainWnd();;
    // CEdit*   AEdit=(CEdit*)   dlg_r2-> GetDlgItem(IDC_EDIT2);
        for(;;){
        if (nPort<65535)
{
        dlg_r1->SetDlgItemInt(IDC_SHOWPORT,nPort,TRUE);  // 设置值
        FD_SET                                mask;
        u_long                                value;
        SOCKET                                sockfd;
        TIMEVAL                                timeout;   //定时微妙
        SOCKADDR_IN                        addr;  //TCP  数据结构
        dlg_r1->SetDlgItemInt(IDC_SHOWPORT,nPort,TRUE); // 设置值        
        sockfd = socket(AF_INET, SOCK_STREAM, 0);  //AF_INET地址族    SOCK_STREAM(TCP)使用的协议  0特定的家族协议相关的协议
        value=1;

ioctlsocket(sockfd,FIONBIO,&value); //控制套接口   //标识套接口   确定套接口s自动读入的数据量    指向cmd命令所带参数的指针
        addr.sin_family        = AF_INET;  //指代协议族,在socket编程中只能是AF_INET
        addr.sin_port =        htons(nPort);//端口号
        addr.sin_addr.s_addr = inet_addr(ip);//存储IP地址
        connect(sockfd,(struct sockaddr        *) &addr, sizeof(addr));  //建立socket连线

        timeout.tv_sec=2;  //定时2微秒
        timeout.tv_usec=0;
        FD_ZERO(&mask);  //初始化套接字
        FD_SET(sockfd,&mask); //设置stdout
        value=select(sockfd+1,NULL,&mask,NULL,&timeout);  //确定一个或多个套接口的状态
                  //忽略参数   等待可读的套接字接口    等待可写的套接字接口   等待错误检查的套接口   最多等待时间
        if(value &&        value!=SOCKET_ERROR)  //SOCKET_ERROR  连接失败
        {  //连接成功
                char result[50];
                //wsprintf(result,"[Found] %-14s-> %-5d\r\n",ip,nPort);   //[Found] 192.168.1.104 -> 445  
                wsprintf(result,"[建立连接] %s-> %d\r\n",ip,nPort);
                show += result;
                dlg_r1->SetDlgItemText(IDC_EDIT2,show);
        }
        closesocket(sockfd);  //关闭一个套接口
        nPort++;
        //CString   str;   
    //  str.Format("%d",nPort);
//        MessageBox(NULL,str, "Greetings", MB_OKCANCEL);
}
else
{
        dlg_r1->m_show +="\r\n扫描结束";
                dlg_r1->SetDlgItemText(IDC_EDIT2,dlg->m_show);
        return 0;
}  }
}

其实很简单就是
socket指点一个IP 在设置端口连接
看socket的返回值 是否连接成功连接成功说明这个IP的指定端口是开放的

        addr.sin_port =        htons(nPort);//端口号
        addr.sin_addr.s_addr = inet_addr(ip);//存储IP地址
指定IP 和端口号

        if(value &&        value!=SOCKET_ERROR)  //SOCKET_ERROR  连接失败
        看这个是否连接成功
连接上了  说明这个端口是开放的

写歌死循环在在里面判断
        if (nPort<65535)
从0开始到65535 端口
在nPort++;    也就是端口号+1
这样就完成了  一个简单的端口扫描

但是在写的过程中发现我写的单线程扫描速度非常慢  1秒也才扫描2个端口号   
我参考的是   特南克斯的

扫描速度
特南克斯使用了TIME 时钟来创建线程  

        if (m_speed == 20) //速度
        {
                nSpeed = 100;
                SetTimer(0,nSpeed,NULL);
        }
        if (m_speed == 40) //速度
        {
                nSpeed = 50;
                SetTimer(0,nSpeed,NULL);
        }
        if (m_speed == 60) //速度
        {
                nSpeed = 20;
                SetTimer(0,nSpeed,NULL);
        }

这样的话   等于 100毫秒或者50毫秒就要创建一个线程
1个线程扫描完一个端口后推出当前的线程  TIME 创建新的时钟会补上

这样的话我的单线程速度肯定是慢的了


使用多线程扫描(多线程1)
使用2个线程模仿的类似特南克斯使用的TIME  事件类似

使用多线程扫描(多线程2)
完全使用多线程操作

不说了  过年了  代码自己看吧

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 0
支持
分享
最新回复 (2)
雪    币: 768
活跃值: (530)
能力值: ( LV13,RANK:460 )
在线值:
发帖
回帖
粉丝
2
楼主勤奋:)过年了,借地拜年:)看雪兄弟过年好!
2012-1-22 20:35
0
雪    币: 54
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
借来收藏下 等我研究时候就有教材了 谢谢楼主
2012-1-23 00:02
0
游客
登录 | 注册 方可回帖
返回
//