在Android中捕获网络数据包?

我正在开发一个项目,我需要捕获传入/传出的数据包并将它们存储在pcap文件中。

Android为此目的提供了VpnService ,这是在API级别14中添加的。尽管在SO上似乎有很多关于此的问题,但令人惊讶的是它的工作示例非常少。 我尝试使用添加在样本中的ToyVpn,但我无法使其工作。 然后我发现了这个例子。

VpnService示例

该示例总结了以下步骤中的捕获。

  1. 创建一个TUN界面(我仍然不确定TUN是什么,但在互联网上冲浪说它是在设备上模拟网络层)。
  2. 通过TUN获取传入数据包和传出数据包的文件描述符。
  3. 将这些数据包转发到实际的服务器。 (不确定这是什么服务器?每个传出的数据包都有一个requestUrl ,所以服务器在这里意味着将请求委托给requestUrl服务器 。或者服务器意味着在AWS上的某个地方创建自己的服务器并重定向那里的所有流量,反过来将流量重定向到实际目的地)。
  4. 从服务器获取响应。
  5. 在TUN的帮助下,再次将此响应传递给应用程序的预期组件。

我使用下面的代码创建了一个TUN。 我给出了上面提到的教程中给出的地址。 不确定,是否有正确的值。 以及如何确定这个地址。

  Builder builder = new Builder(); ParcelFileDescriptor mInterface = builder.setSession("MyVPNService") .addAddress("192.168.0.1", 24) .addDnsServer("8.8.8.8") .addRoute("0.0.0.0", 0).establish(); 

接下来,我获得了文件描述符,并打开了隧道。

  FileInputStream in = new FileInputStream( mInterface.getFileDescriptor()); DatagramChannel tunnel = DatagramChannel.open(); // I have created a EC2 instance on AWS, and gave the ip Address and port of that server. Not sure if this is the correct method. tunnel.connect(new InetSocketAddress("54.254.187.207", 5000)); //d. Protect this socket, so package send by it will not be feedback to the vpn service. protect(tunnel.socket()); 

然后应用while循环读取数据包。

  while (true) { BufferedReader reader = new BufferedReader(new InputStreamReader(in)); while(true){ String line = reader.readLine(); if(line ==null){ break; }else{ System.out.println("line is "+line); } // I am guessing that here after reading the packets, I need to forward them to the actual server. }} 

这给了我以下输出

 02-21 19:12:26.074 16435-16778/awesomedroidapps.com.debugger I/System.out: line is E    @ '@  @       Wz  y A x [     02-21 18:43:53.648 16435-16639/awesomedroidapps.com.debugger I/System.out: line is   T@  02-21 18:43:53.648 16435-16639/awesomedroidapps.com.debugger I/System.out: line is y 1 y 7E    A @  @        5  -  -                 decidemixpanelcom      E      ;@  @ F   d6    > Wz y A x       02-21 18:43:53.648 16435-16639/awesomedroidapps.com.debugger I/System.out: line is   ]@   F    BA  +  q ϔ   Jb2_' D y ̯  [: 1)   PΠ ѡ   h71 L 3 =~      (                 S ~'U      9d_   " I E    @0@  @  02-21 18:43:53.648 16435-16639/awesomedroidapps.com.debugger I/System.out: line is    d : N    P V x %0/ W       02-21 18:43:53.648 16435-16639/awesomedroidapps.com.debugger I/System.out: line is   ^P    02-21 18:43:53.648 16435-16639/awesomedroidapps.com.debugger I/System.out: line is  %0. %0/E    = @  @         5  )l                t appsflyercom      E    = @  @      6  5  ) .                t appsflyercom      E    @0@  @    d : N    P V x %0/ W       02-21 18:43:53.648 16435-16639/awesomedroidapps.com.debugger I/System.out: line is    P     02-21 19:12:26.074 16435-16778/awesomedroidapps.com.debugger I/System.out: line is E    @ '@  @       Wz  y A x [     02-21 18:43:53.648 16435-16639/awesomedroidapps.com.debugger I/System.out: line is   T@  02-21 18:43:53.648 16435-16639/awesomedroidapps.com.debugger I/System.out: line is y 1 y 7E    A @  @        5  -  -                 decidemixpanelcom      E      ;@  @ F   d6    > Wz y A x       02-21 18:43:53.648 16435-16639/awesomedroidapps.com.debugger I/System.out: line is   ]@   F    BA  +  q ϔ   Jb2_' D y ̯  [: 1)   PΠ ѡ   h71 L 3 =~      (                 S ~'U      9d_   " I E    @0@  @  02-21 18:43:53.648 16435-16639/awesomedroidapps.com.debugger I/System.out: line is    d : N    P V x %0/ W       02-21 18:43:53.648 16435-16639/awesomedroidapps.com.debugger I/System.out: line is   ^P    02-21 18:43:53.648 16435-16639/awesomedroidapps.com.debugger I/System.out: line is  %0. %0/E    = @  @         5  )l                t appsflyercom      E    = @  @      6  5  ) .                t appsflyercom      E    @0@  @    d : N    P V x %0/ W       02-21 18:43:53.648 16435-16639/awesomedroidapps.com.debugger I/System.out: line is    P    

从日志中可以清楚地看到我能够在TUN中捕获传出的数据包。 以上日志记录了像facebook.com这样的打印主机,这让我相信我在正确的轨道上。

但是在此之后我该怎么做呢? 如何将数据转发到服务器? 我相信工作的例子较少。 但有人可以给我一步一步的程序来实现这个目标吗?

更新 :进一步挖掘后,我开始知道我需要创建一个服务器并将截获的数据包转发到服务器。 我在我的计算机上创建了一个服务器,并能够成功地将截获的数据包转发到我的服务器。 但我不知道如何从收到的数据包中获取实际的目标IP和端口,以便我可以将它们发送到预定目的地。

PS :我也经历了JnetPcap库,但似乎要捕获实时数据包,手机需要植根,这不是我的应用程序的要求。

非常确定您最好的选择是设置代理服务器,然后使用wireshark之​​类的东西来监控往返的流量。 我不是这方面的专家,但在过去交换路由器之前这么便宜,它很容易,因为所有数据包都被广播到同一子网上的所有计算机。 也许如果您可以使用能够禁用切换的集线器/路由器,您可以使用此方法而不是代理。

这些天大多数通信是使用http完成的,因为你拥有像Charles(mac)和Fiddler(windows)这样的优秀工具,除了http之外,它们完全符合你的要求。 他们至少可以为您提供有关如何使用Wireshark执行相同操作的想法