滴水逆向联盟

标题: 一个值得学习的 扫描器c++源码 [打印本页]

作者: dishui001    时间: 2014-5-14 19:50
标题: 一个值得学习的 扫描器c++源码
//首先 引入需要用到的库文件
#include <stdio.h>// 标准输入输出流
#include <winsock2.h>//socket套接字  网络发包性质的 网络通讯
#include <time.h>//时间的头文件
#pragma comment(lib,"ws2_32.lib")//编译链接用的库文件
//只有包含了这些头文件 才能引用里面的 函数方法


char *host;//定义字符型 变量  指针  保存主机IP
int threadnum,maxthread,totalport;//定义线程 端口
long nowport ;//当前端口
TIMEVAL timeout; //定义一个时间结构体的对象
FD_SET    mask;
void display(void)
{
    static int play=0;
    char *plays[12]=
    {
             " | ",
            " / ",
            " - ",
            " \\ ",
            " | ",
            " / ",
            " - ",
            " // ",
            " | ",
            " / ",
            " - ",
            " // ",
    };
printf("=%s=\t%d 线程 %d %s 完成...\r",plays[play],threadnum,nowport*100/(totalport+1),"%");
play=(play==11)?0:play+1;
Sleep(1);

}

void WaitThreadEnd(void)
{
    Sleep(1000);
    printf("\n 线程结束中.....\n");
    while (threadnum>0)
    {
        Sleep(1);
        printf("=|=\t%d 线程数 \r",threadnum);
    }
}
//最终的回调函数 线程
DWORD WINAPI ThreadFunc(LPVOID lp)
{
   int port=*(DWORD*)lp;//得到端口
   SOCKET sockfd;
   struct sockaddr_in addr;// 套接字 地址的一个 结构体的 对象
   u_long value;//定义一个 无符号的long;
   addr.sin_family=AF_INET;
   addr.sin_addr.s_addr=inet_addr(host);
   value=1;//非阻塞模式的参数
   sockfd=socket(AF_INET,SOCK_STREAM,0);//初始化 流模式TCP
   if (sockfd==INVALID_SOCKET)
   {
       printf("套接字错误\n");
       InterlockedExchangeAdd((long*)&threadnum,-1);
       //意思就是 互斥  在线程中  确保数据被一个线程修改。。
       return 0;
   }
   ioctlsocket(sockfd,FIONBIO,&value);
   //套接字的一个 非阻塞模式
   addr.sin_port=htons(port); //转换端口
   connect(sockfd,(struct sockaddr *)&addr,sizeof(addr));
   FD_ZERO(&mask);
   FD_SET(sockfd,&mask);
   value=select(0,NULL,&mask,NULL,&timeout);
   if (value==0||value==-1)
   {
       closesocket(sockfd);//超时了 关闭
       Sleep(50);
       InterlockedExchangeAdd((long *)&threadnum,-1);
       return 0;
   }
   else
   {
       shutdown(sockfd,0);
       printf("\t\t 发现 %d 打开\r\n",port);
       closesocket(sockfd);
       Sleep(50);
       InterlockedExchangeAdd((long *)&threadnum,-1);
   }
   return 0;


}




void usage(char *name)//传递一个参数进来 char类型
{
printf("\t========================猫猫专用扫描器=============================\n");
printf("\t========================QQ 图上有 2012.6.2========================\n\n");
printf("用法: 程序名 ip 开始端口-结束端口 线程\n\n",name);
printf("\t 程序名:  您的程序名%s\n",name);
printf("\t IP:      你想要扫描的IP地址\n");
printf("\t 端口:    (1-65535之间的数)\n");
printf("\t 线程:    最大开到1000\n\n");
printf("使用例子: %s 192.168.1.1 1-65535 500 \n",name);
}

//定义main 主入口函数
void main(int argc,char **argv)
{
//初始化套接字
    WSADATA ws;//初始化WSADATA
    char *p;//一个指向端口的指针 就是我们传递的端口
    int startport,endport;//定义两个整形变量 来保存开始 结束端口
    clock_t start,end; // 检测程序扫描用了多少时间
    float costtime;//花费的时间 float类型 浮点
    if (argc!=4)//如果参数不等于4个
    {
        usage(argv[0]);//调用该函数 。。usage 传递 argv[0]
        //第一个参数 默认指向的 是程序的名字
        return;
    }
    long lresult; //定义长整型的变量
    lresult=WSAStartup(MAKEWORD(2,2),&ws);// 进行开始wsadata
    p=argv[2];//指针指向第三个参数 端口 第一个是程序名 第二个 IP 第三个才是端口
    if (strstr(argv[2],"-"))  //查找这个- 线 查找到之后 进入if体
    {
       startport=atoi(argv[2]);//比如: 222-333
       for (;*p;)if(*(p++)=='-')break;

           //得到的是p的值  其实就是无限循环 *p取出指针对应的值
       endport=atoi(p);
       if (startport<1 || endport>65535)
       {
           printf("端口你写错了吧 1-65535 之间的一个数\n");
           return;
       }
    }
    host=argv[1];//保存主机IP
    maxthread=(atoi(argv[3]-1)>999)?999:atoi(argv[3])-1;
    //三目运算 如果大于1000那么 等于999 否则 等于用户输入的
    usage(argv[0]);//又输出了一次菜单

    timeout.tv_usec=0;//初始化时间0
    if (maxthread>500)timeout.tv_sec=2;
    //线程大 那么时间 给的多点
    else timeout.tv_sec=1;
    start=clock();
    totalport=endport-startport;
    //一共多少个端口
    for (int port=startport;port<endport;port++,nowport++,threadnum++)
    {
        display();
        while (threadnum>maxthread)
        {
            Sleep(10);
        }
        CreateThread(NULL,0,ThreadFunc,&port,0,NULL);//创建线程
    }
    end=clock();
    costtime=(float)(end-start)/CLOCKS_PER_SEC;//换算成时间格式
    printf("消耗时间: %f 秒",costtime);
    printf("\n\n");
    WaitThreadEnd();//等待线程结束
    WSACleanup();//关闭套接字
    return ;//返回







欢迎光临 滴水逆向联盟 (http://www.dtdebug.com/) Powered by Discuz! X3.2