zoukankan      html  css  js  c++  java
  • windows抓包程序

    生成RAW Socket

    SOCKET s = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
    if(INVALID_SOCKET == s)
    {
    	printf("socket(AF_INET, SOCK_RAW, IPPROTO_IP) == INVALID_SOCKET, ErrorCode=%d", GetLastError());
    	return false;
    }

    RAW Socket接收到的数据包保留原始的IP包头。

    SOCK_RAW能操作底层传输,所以它们能用于造成安全威胁的恶意目的,故在Windows2000及以后操作系统中只有Administrator组成员可以创建RAW socket。

    RAW Socket发送和接收的所有包一概视为无连接的数据报。


    绑定本地地址

    sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr("192.168.4.111");
    addr.sin_port = htons(4445);
    
    if(SOCKET_ERROR == bind(s, (sockaddr*)&addr, sizeof(addr)))
    {
    	printf("bind == SOCKET_ERROR, ErrorCode=%d
    ", GetLastError());
    	return 0;
    }

    必须进行地址绑定否则设置SIO_RCVALL时出10022错误。

    socket绑定IP后将仅接收通过该网卡的IP数据包。它不会接收到流经其他网卡的IP数据包。

    有多个网卡,则需循环处理,一次绑定一个,不能使用htonl(INADDR_ANY),否则失败。


    设置SIO_RCVALL控制码

    RCVALL_VALUE emRcvallValue = RCVALL_IPLEVEL;
    DWORD dwBytesReturned = 0;
    if(SOCKET_ERROR == WSAIoctl(s, SIO_RCVALL, &emRcvallValue, sizeof(emRcvallValue), NULL, 0, &dwBytesReturned, NULL, NULL))
    {
    	printf("WSAIoctl == SOCKET_ERROR, ErrorCode=%d", GetLastError());
    	return 0;
    }
    SIO_RCVALL控制码将使一个socket能够接收经过该网卡的所有IP数据包。

    RCVALL_IPLEVEL为SIO_RCVALL控制码的选项值,类型为RCVALL_VALUE

    typedef enum {
        RCVALL_OFF             = 0,
        RCVALL_ON              = 1,
        RCVALL_SOCKETLEVELONLY = 2,
        RCVALL_IPLEVEL         = 3,
    } RCVALL_VALUE, *PRCVALL_VALUE;

    RCVALL_IPLEVEL在IP层抓包,不会设置网卡为杂乱模式避免了可能的错误,网卡仍旧仅接收发给自己的数据包或广播数据包。该选项仅影响IP层对数据包的处理过程。

    不允许先将该控制码作用于一个网卡而后作用于另一个网卡。在把该控制码用于其他网卡前必选先关闭现有socket的SIO_RCVALL控制码。(因电脑只有一个网卡故未得到验证)


    抓包

    char cBuffer[100*1024] = {0};
    int iLenRecv = recv(s, cBuffer, 100*1024, 0);
    if(SOCKET_ERROR == iLenRecv)
    {
    	printf("recv == SOCKET_ERROR, ErrorCode=%d", GetLastError());
    	return false;
    }
    if(0 == iLenRecv)
    {
    	printf("recv == SOCKET_ERROR, Connection Closed");
    	break;
    }
    
    cBuffer[iLenRecv] = '';

    妥善关闭

    /*关闭SIO_RCVALL*/
    emRcvallValue = RCVALL_OFF;
    if(SOCKET_ERROR == WSAIoctl(s, SIO_RCVALL, &emRcvallValue, sizeof(emRcvallValue), NULL, 0, &dwBytesReturned, NULL, NULL))
    {
    	printf("WSAIoctl == SOCKET_ERROR, ErrorCode=%d
    ", GetLastError());
    	return false;
    }
    
    /*关闭socket*/
    closesocket(s);


    完整代码

    /*生成RAW socket*/
    SOCKET s = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
    if(INVALID_SOCKET == s)
    {
    	WriteToLog("LogicModule::GetProcNetworkFlow: socket == INVALID_SOCKET, ErrorCode=%d", GetLastError());
    	return false;
    }
    
    /*初始化sockaddr*/
    sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr("192.168.4.111");
    addr.sin_port = htons(4444);
    
    /*绑定网卡地址*/
    if(SOCKET_ERROR == bind(s, (sockaddr*)&addr, sizeof(addr)))
    {
    	printf("bind == SOCKET_ERROR, ErrorCode=%d", GetLastError());
    	return false;
    }
    
    /*设置socket模式*/
    RCVALL_VALUE emRcvallValue = RCVALL_IPLEVEL;
    DWORD dwBytesReturned = 0;
    if(SOCKET_ERROR == WSAIoctl(s, SIO_RCVALL, &emRcvallValue, sizeof(emRcvallValue), NULL, 0, &dwBytesReturned, NULL, NULL))
    {
    	printf("WSAIoctl == SOCKET_ERROR, ErrorCode=%d", GetLastError());
    	return false;
    }
    
    /*抓包*/
    char cBuffer[100*1024] = {0};
    int iLenRecv = recv(s, cBuffer, 100*1024, 0);
    if(SOCKET_ERROR == iLenRecv)
    {
    	printf("recv == SOCKET_ERROR, ErrorCode=%d", GetLastError());
    	return false;
    }
    if(0 == iLenRecv)
    {
    	printf("recv == SOCKET_ERROR, Connection Closed");
    	break;
    }
    
    cBuffer[iLenRecv] = '';
    
    /*关闭SIO_RCVALL*/
    emRcvallValue = RCVALL_OFF;
    if(SOCKET_ERROR == WSAIoctl(s, SIO_RCVALL, &emRcvallValue, sizeof(emRcvallValue), NULL, 0, &dwBytesReturned, NULL, NULL))
    {
    	printf("WSAIoctl == SOCKET_ERROR, ErrorCode=%d
    ", GetLastError());
    	return false;
    }
    
    /*关闭socket*/
    closesocket(s);


  • 相关阅读:
    Air-WIFI使用方法
    libeasy代码学习:一次简单的TCP请求处理流程
    log_pipe日志收集分析系统介绍
    asp.net 项目在 IE 11 下出现 “__doPostBack”未定义 的解决办法
    用命令行实现“一键休眠”
    C#几个经常用到的字符串的截取
    MYSQL存储过程怎么写
    如何用myeclipse和eclipse搭建安卓开发环境
    C#随机生成不重复字符串
    Inno setup 简单打包教程
  • 原文地址:https://www.cnblogs.com/chaikefusibushiji/p/6775758.html
Copyright © 2011-2022 走看看