作为开发者,我们都很清楚,我们开发的跟网络相关的程序,一般都会通过使用HTTP协议,发出相关的请求信息。当在应用运行之初时,这些网络上的信息的传递是十分畅顺的,我们获得的信息都是我们期望所获得的。

然而,开发者会发现经常都不会出现上面说的情况,尤其是在应用连接在网络中的时候,特别是当高并发流量时,如果出现了数据的丢失或错误,没人准确知道当前已发送和接受的数据是什么,这样对我们的程序调试是很不利的。这就要求我们必须能够抓取网络中的相关包数据,对数据进行解包分析验证。

前言

对网络中的数据包进行抓取为稍后的分析是很有用的,但如果我们在抓取数据包的同时就能够开展这种分析那将获得更好的效果。这样做的话,开发者能很清晰了解到对每一个测试用例中的请求和应答的数据是哪些。在本文中,将展示如何实时地抓取Android应用联网程序中的数据包,并且将使用著名的网络数据分析利器Wireshark进行分析。

教程详情

  • 技术:Android+Wireshark

  • 难度:中等

  • 完成时间:30-45分钟

步骤1安装tcpdump软件

首先必须在设备上安装tcpdump软件。Tcpdump是一款命令行下的网络数据抓包工具,并能将抓取的数据存放到文件系统中,可以在这个地址下载:http://www.tcpdump.org/

当下载完tcpdump文件后,我们需要做的只需要使用adb命令去将其放到设备中去。首先当然要将手机连接到电脑上,使用的命令如下:

adbdevices

这样就会列出当前已连接到电脑上的设备。再用如下命令将tcpdump文件push到设备中去,如下命令:

adb push /home/tcpdump   /data/local

在接下来的几个步骤中,必须要使用root的权限进行操作,并且要使的tcpdump为可执行属性,如下:

adb shell

cd data/local

su

chmod 777 tcpdump

步骤2保存抓包数据到文件

我们可以在adbshell中启动tcpdmup,命令如下:

/tcpdump-s0-v-wout.pcap

完整的tcpdump的命令参数请参考这个地址:http://www.tcpdump.org/tcpdump_man.html

运行后如下图所示:

可以看到,tcpdump会监控当前网卡的数据包情况,当用户想停止监控时,只需要CTRL+C即可停止监控了,并使用pull将其保存到文件系统中去,以方便使用Wireshark去进行分析,命令如下:

adb pull/data/local/out.pcap/home/out.pcap


保存在本地文件系统中的数据将稍后使用Wireshark进行分析。

步骤3捕捉指定端口的数据

接下来,我们更改下tcpdump的输出格式,将其输出不输出到文件,而输出到指定的输出端口中,以方便使用netcat这个工具去过滤数据,这个工具等下会讲解到。命令如下:

adb shell "./data/local/tcpdump -n -s 0 -w - | nc -l -p 12345"

这样的话,所有的网络流量数据包将会经过12345端口。

步骤4安装netcat

首先在http://www.securityfocus.com/tools/139这个地址下载windows版本的netcat进行安装,这个工具的原理是:,从网络的一端读入数据,然后输出到网络的另一端,它可以使用tcp和udp协议.

步骤5使用Wireshark分析网络数据包

下面我们开始使用Wireshark分析网络数据包。首先使用adb的forward指令,将数据包从手机设备的12345端口重定向到PC电脑的54321端口,然后再通过netstat工具捕获进入54321端口的数据,最后再通过管道操作交给wireshark进行分析,命令如下:

 adb forward tcp:12345 tcp:54321 && nc 127.0.0.1 54321 | wireshark -k -S -i -

要注意的是,例子中端口的选择是随机的。之所以选择不同的端口,其原因为了展示不同的命令之间的相互调用,相同的命令可以调用同一个端口,只要这些端口是未被占用的即可。

运行后入下图所示,可以看到wireshark的运行情况:

综合的操作

现在,在不同的工具搭建完毕后,我们可以通过在两个不同的终端,分别使用两条不同的命令,来完成从捕捉数据包到整个数据包分析的过程,命令如下:

adb shell "./data/local/tcpdump -n -s 0 -w - | nc -l -p 12345"
adb forward tcp:12345 tcp:54321 && nc 127.0.0.1 54321 | wireshark -k -S -i -

但这个操作有点麻烦,要打开两个终端进行操作,因此在windows下,可以用本文的附件中的如下脚本,实现一条语句运行:

start adb shell "./data/local/tcpdump -n -s 0 -w - | nc -l -p 12345"
adb forward tcp:12345 tcp:54321 && nc 127.0.0.1 54321 | wireshark -k -S -i -

如下图,可以看到只打开了一个终端窗口。

Mac用户请注意

如果你是MAC机用户,则请需要注意如下几点:

使用完整的路径调用,比如“/Applications/Wireshark.app/Contents/Resources/bin/wireshark”去调用

2)此外,在命令行下调用时,要按入下格式调用:

 adb forward tcp:12345 tcp:54321 && nc 127.0.0.1 54321 | sudo wireshark -k -S -i 2

其中,要使用sudo授予wireshark管理员权限,并且注意最后的参数为2,最后给出一段perl的script,在本文附件中可以下载,用来完成整个在MAC机器上捕获数据包并交给wireshark分析的过程:

 
  
  1. #!/usr/bin/perl

  2. # Perform adb command on shell

  3. # to check if the device is attached

  4. $netstat = `adb shell 'netstat' 2>&1`;

  5. if($netstat =~ m/error: device not found/)

  6. {

  7. die("Plug in your phone!\n");

  8. }

  9. # Gain root priviledges

  10. open(SUDO, "|sudo echo ''");

  11. close(SUDO);

  12. # Redirect STDERR output to STDOUT

  13. open STDERR, '>&STDOUT';

  14. # Perform tcpdump and nc in background

  15. open(COMMAND1, "(adb shell \"data/local/tcpdump -n -s 0 -w - | nc -l -p 12345\") |");

  16. # Perform piping to wireshark

  17. open(COMMAND2, "((adb forward tcp:12345 tcp:54321 && nc 127.0.0.1 54321 | sudo wireshark -k -S -i 2) &) 2>&1 > /dev/null |");

  18. # Make sure the exit message appears after wireshark has been launched (hacky)

  19. sleep(5);

  20. print("Press ctrl-c to exit...");

  21. <STDIN>;



不知道为什么,最后一直没有测试成功,虽然tcpdump完全可以使用,生成的pcap也能够让wireshark正确解析,但是之间使用nc产生的动态桥梁却一直没有打通,用nc的时候发现wireshark

获取不了数据,这个事情让我感觉很郁闷,等有时间换个思路再看看...