抓包分析YY音频
YY的音频数据传输是P2P协议,音频的编码为AAC,下面抓去的音频编码的信息和频谱信息。
音频编码为AAC,采样为44K,码率24kb/s。音频编码在24kb/s码率能达到15K的音质。值得大家学习啊。
1.准备工具
procexp.exe 分析YY的进程信息
Procmon.exe 分析YY的网络数据包
wireshark.exe 分析网络包的内容
2.分析YY的进程信息
使用procexp分析YY的大致信息,比如进程号,网络连接等
3.分析YY的网络传输信息
使用procmon分析YY的网络数据,根据上面的得到的进程ID设置过滤,只接受YY的UDP数据包
过滤后得到数据包如下:
从上面的数据可以看到端口为8456的UDP接受数据最多,可以看出这个端口接受的就是P2P音频数据。
4.使用wireshark抓取P2P音频数据包
设置wireshark的过滤器,只抓去端口为8456的UDP数据包
抓去的数据如下:
查看UDP数据流,这里面存的就是YY的音频数据。从下面的数据看不出来具体的音频编码。
不急,我们多看几个数据包就会发现,他们都有固定的数据头,紧接着都刚好是0xff|0xf1(这个刚好是aac ADTS的同步头)。所以我们可以按照这个思路分析下去。
5. 使用代码分析pcap抓去的数据包
详细分析参考代码:
- #include <stdio.h>
- #include <stdlib.h>
- #include <WinSock2.h>
- #include <assert.h>
- ///
- typedef unsigned int bpf_u_int32;
- typedef unsigned char u_char;
- typedef unsigned short u_short;
- typedef unsigned int u_int;
- typedef int bpf_int32;
- /*
- Pcap文件分析如下:
- +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
- |Pcap Header |Packet Header |Packet Body |Packet Header |Packet Body |
- +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
- */
- /*
- Pcap文件头
- +-------+-------+-------+-------+
- | Magic 4B |
- +-------+-------+-------+-------+
- | Major 2B | Minor 2B |
- +-------+-------+-------+-------+
- | ThisZone 4B |
- +-------+-------+-------+-------+
- | SigFigs 4B |
- +-------+-------+-------+-------+
- | SnapLen 4B |
- +-------+-------+-------+-------+
- | LinkType 4B |
- +-------+-------+-------+-------+
- Pcap文件头24B各字段说明:
- Magic:4B:0x1A 2B 3C 4D:用来标示文件的开始
- Major:2B,0x02 00:当前文件主要的版本号
- Minor:2B,0x04 00当前文件次要的版本号
- ThisZone:4B当地的标准时间;全零
- SigFigs:4B时间戳的精度;全零
- SnapLen:4B最大的存储长度
- LinkType:4B链路类型
- 常用类型:
- 0 BSD loopback devices, except for later OpenBSD
- 1 Ethernet, and Linux loopback devices
- 6 802.5 Token Ring
- 7 ARCnet
- 8 SLIP
- 9 PPP
- */
- typedef struct pcap_file_header {
- bpf_u_int32 magic;
- u_short version_major;
- u_short version_minor;
- bpf_int32 thiszone;
- bpf_u_int32 sigfigs;
- bpf_u_int32 snaplen;
- bpf_u_int32 linktype;
- }pcap_file_header;
- /*
- Packet 包头和Packet数据组成
- +-------+-------+
- |Packet Header |
- +-------+-------+
- |Packet Body |
- +-------+-------+
- Paket 包头
- +-------+-------+-------+-------+
- | Timestamp 4B |
- +-------+-------+-------+-------+
- | Timestamp 4B |
- +-------+-------+-------+-------+
- | Caplen 4B |
- +-------+-------+-------+-------+
- | Len 4B |
- +-------+-------+-------+-------+
- 字段说明:
- Timestamp:时间戳高位,精确到seconds
- Timestamp:时间戳低位,精确到microseconds
- Caplen:当前数据区的长度,即抓取到的数据帧长度,由此可以得到下一个数据帧的位置。
- Len:离线数据长度:网络中实际数据帧的长度,一般不大于caplen,多数情况下和Caplen数值相等。
- Packet 数据:即 Packet(通常就是链路层的数据帧)具体内容,长度就是Caplen,这个长度的后面,就是当前PCAP文件中存放的下一个Packet数据包,也就 是说:PCAP文件里面并没有规定捕获的Packet数据包之间有什么间隔字符串,下一组数据在文件中的起始位置。我们需要靠第一个Packet包确定。
- */
- typedef struct timestamp{
- bpf_u_int32 timestamp_s;
- bpf_u_int32 timestamp_ms;
- }timestamp;
- typedef struct pcap_header{
- timestamp ts;
- bpf_u_int32 capture_len;
- bpf_u_int32 len;
- }pcap_header;
- //help funtion
- void printPcapHeader(pcap_file_header * ph)
- {
- printf("=====================\n"
- "magic:0x%0x\n"
- "version_major:%u\n"
- "version_minor:%u\n"
- "thiszone:%d\n"
- "sigfigs:%u\n"
- "snaplen:%u\n"
- "linktype:%u\n"
- "=====================\n",
- ph->magic,
- ph->version_major,
- ph->version_minor,
- ph->thiszone,
- ph->sigfigs,
- ph->snaplen,
- ph->linktype);
- }
- void printPacketHeader(pcap_header * ph)
- {
- printf("=====================\n"
- "ts.timestamp_s:%u\n"
- "ts.timestamp_ms:%u\n"
- "capture_len:%u\n"
- "len:%d\n"
- "=====================\n",
- ph->ts.timestamp_s,
- ph->ts.timestamp_ms,
- ph->capture_len,
- ph->len);
- }
- //////////////////////////////////////////////////////////////////////////
- /*
- UDP包分析
- */
- /* 4字节的IP地址 */
- typedef struct ip_address{
- u_char byte1;
- u_char byte2;
- u_char byte3;
- u_char byte4;
- }ip_address;
- /* IPv4头 */
- typedef struct ip_header{
- u_char ver_ihl; // 版本 (4 bits) + 首部长度 (4 bits) /// 首部长度
- u_char tos; // 服务类型(Type of service)
- u_short tlen; // 总长(Total length)
- u_short identification; // 标识(Identification)
- u_short flags_fo; // 标志位(Flags) (3 bits) + 段偏移量(Fragment offset) (13 bits)
- u_char ttl; // 存活时间(Time to live)
- u_char proto; // 协议(Protocol)
- u_short crc; // 首部校验和(Header checksum)
- ip_address saddr; // 源地址(Source address)
- ip_address daddr; // 目的地址(Destination address)
- u_int op_pad; // 选项与填充(Option + Padding)
- }ip_header;
- /* UDP头 */
- typedef struct udp_header{
- u_short sport; // 源端口(Source port)
- u_short dport; // 目的端口(Destination port)
- u_short len; // UDP数据包长度(Datagram length) /// UDP总长度
- u_short crc; // 校验和(Checksum)
- }udp_header;
- u_char pkt_data[65536];
- int main()
- {
- FILE * fp = fopen("yy.p2p.packet_long.pcap", "rb");
- if (!fp)
- {
- fprintf(stderr, "open file error\n");
- return -1;
- }
- FILE * aacfp = fopen("yy.p2p.packet_long.pcap.aac", "wb");
- if (!fp)
- {
- fprintf(stderr, "open file error\n");
- return -1;
- }
- //1. Read pcap file header
- pcap_file_header pfh;
- fread(&pfh, 1, sizeof(pfh), fp);
- printPcapHeader(&pfh);
- //2. Read pcap packet
- while (!feof(fp))
- {
- pcap_header ph;
- if (fread(&ph, 1, sizeof(ph), fp) != sizeof(ph))
- break;
- printPacketHeader(&ph);
- if (fread(pkt_data, 1, ph.capture_len, fp) != ph.capture_len)
- break;
- //3. 分析消息包内容
- //fseek(fp, ph.capture_len, 1);
- // 获取IP数据包头的位置
- ip_header *ih = (ip_header *)(pkt_data + 14); // 14以太网头部长度
- // 只处理UDP包
- if (ih->proto != 0x11)
- continue;
- // 获取UDP首部的位置
- u_int ip_len = (ih->ver_ihl & 0x0f) * 4;
- udp_header * uh = (udp_header *)((u_char *)ih + ip_len);
- //
- u_short sport = ntohs(uh->sport);
- u_short dport = ntohs(uh->dport);
- u_short udplen = ntohs(uh->len);
- if(sport != 8455) // yy源端口为8455
- continue;
- /* 打印IP地址和UDP端口 */
- printf("%d.%d.%d.%d.%d -> %d.%d.%d.%d.%d\n",
- ih->saddr.byte1,
- ih->saddr.byte2,
- ih->saddr.byte3,
- ih->saddr.byte4,
- sport,
- ih->daddr.byte1,
- ih->daddr.byte2,
- ih->daddr.byte3,
- ih->daddr.byte4,
- dport);
- //
- u_char * udp_data = (u_char *)uh + 8;
- //u_char * aac_data = udp_data + 34;
- //u_short aac_len = udplen - 8 - 34;
- u_char * aac_data = pkt_data + 14 + ip_len + 8 + 34;
- int aac_len = ph.capture_len - (14 + ip_len + 8 + 34);
- //assert(aac_len > 0);
- if (aac_len <= 0) continue; /// 只有 yy头,没有aac数据
- assert(aac_len < ph.capture_len);
- printf("aac len = %d pkt_len = %d\n", aac_len, ph.capture_len);
- assert(aac_data[0] == 0xff && aac_data[1] == 0xf1);
- fwrite(aac_data, 1, aac_len, aacfp);
- }
- fclose(fp);
- fclose(aacfp);
- return 0;
- }
抓包分析YY音频的更多相关文章
- Wireshark抓包分析/TCP/Http/Https及代理IP的识别
前言 坦白讲,没想好怎样的开头.辗转三年过去了.一切已经变化了许多,一切似乎从没有改变. 前段时间调研了一次代理相关的知识,简单整理一下分享之.如有错误,欢迎指正. 涉及 Proxy IP应用 原理/ ...
- HTTP2特性预览和抓包分析
背景 近年来,http网络请求量日益添加,以下是httparchive统计,从2012-11-01到2016-09-01的请求数量和传输大小的趋势图: 当前大部份客户端&服务端架构的应用程序, ...
- 抓包分析SSL/TLS连接建立过程【总结】
1.前言 最近在倒腾SSL方面的项目,之前只是虽然对SSL了解过,但是不够深入,正好有机会,认真学习一下.开始了解SSL的是从https开始的,自从百度支持https以后,如今全站https的趋势越来 ...
- 实战录 | 基于openflow协议的抓包分析
<实战录>导语 云端卫士<实战录>栏目定期会向粉丝朋友们分享一些在开发运维中的经验和技巧,希望对于关注我们的朋友有所裨益.本期分享人为云端卫士安全SDN工程师宋飞虎,将带来基于 ...
- 在Hdsi2.0 SQL的注入部分抓包分析语句
在Hdsi2.0 SQL的注入部分抓包分析语句 恢复cmd ;insert tb1 exec master..xp_cmdshell''net user ''-- ;exec master.dbo.s ...
- [转] Android实时抓包分析 : 善用adb调试桥
Android实时抓包分析 : 善用adb调试桥 谈到android网络抓包,很多人都能想到牛逼轰轰的神器tcpdump.方法就是在android机器上面安装tcpdump,然后通过-w参数把抓包 ...
- 云计算之路-阿里云上:Wireshark抓包分析一个耗时20秒的请求
这篇博文分享的是我们针对一个耗时20秒的请求,用Wireshark进行抓包分析的过程. 请求的流程是这样的:客户端浏览器 -> SLB(负载均衡) -> ECS(云服务器) -> S ...
- 用Wireshark抓包分析超过70秒的请求
超过70秒的请求是通过分析IIS日志发现的: 10.159.63.104是SLB的内网IP. 通过Wireshark抓包分析请求是9:22:21收到的(tcp.stream eq 23080): 09 ...
- Wireshark抓包分析HTTPS与HTTP报文的差异
一.什么是HTTPS: HTTPS(Secure Hypertext Transfer Protocol)安全超文本传输协议 它是一个安全通信通道,它基于HTTP开发,用于在客户计算机和服务器之间交换 ...
随机推荐
- Android5.1图库Gallery2代码分析数据加载流程
图片数据加载流程. Gallery---->GalleryActivity------>AlbumSetPage------->AlbumPage--------->Photo ...
- Java基础知识(一) 自增、自减运算符
.d1 { border-style: none } .d2 { border-style: solid } .d3 { border-style: dotted } .d4 { border-sty ...
- dedecms如何修改共0页/0条记录为英文版?
近日,在测试一个网站功能的时候,发现在搜索结果的下面为中文的“共0页/0条记录”,但客户的网站为英文版,所以我们需要将搜索的结果信息也要显示为英文,好了,我们开始动手修改dedecms的文件,以达到我 ...
- bi api 软件
https://www.interactivebrokers.com.hk/cn/index.php?f=5234&ns=T
- 更改CI框架默认访问路径及去掉index.php
下面是去掉index.php的操作 PHP CodeIgniter(CI)去掉 index.php - Langjun - 博客园 设置访问的默认路径是在
- Cocos2dx 学习笔记整理----开发环境搭建
最近在学习cocos2dx,预备将学习过程整理成笔记. 需要的工具和环境整理一下: 使用的版本 cocos2dx目前已经出到了v3.1.1,学习和项目的话还是用2.2.3为宜,毕竟不大想做小白鼠,并且 ...
- (简单) POJ 3264 Balanced Lineup,RMQ。
Description For the daily milking, Farmer John's N cows (1 ≤ N ≤ 50,000) always line up in the same ...
- ZOJ 3927 Programming Ability Test
水题,判断一下加起来是否大于等于80 #include<cstdio> #include<cstring> #include<cmath> #include< ...
- jQuery.extend({...})分析
作者:zccst 看一下是如何写的 jQuery.extend({ prop:"" method:function(){} }); 可以看出,这些方法是jQuery的静态属性和方法 ...
- JRPC 轻量级RPC框架
JRPC是一个轻量级的java RPC框架.它支持服务注册和发现. 目前它开源了,地址为:https://github.com/dinstone/jrpc. Quick Start step 1: g ...