在Android中捕获网络数据包?

the*_*ger 16 sockets vpn networking 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();
Run Code Online (Sandbox Code Playgroud)

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

     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());
Run Code Online (Sandbox Code Playgroud)

然后应用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. 

        }}
Run Code Online (Sandbox Code Playgroud)

这给了我以下输出

02-21 19:12:26.074 16435-16778/awesomedroidapps.com.debugger I/System.out: line is E????@?'@??@??????<??5??,????????????????????graphfacebookcom??????E????@?(@??
    02-21 18:43:53.648 16435-16639/awesomedroidapps.com.debugger I/System.out: line is 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 ??EP???
    02-21 18:43:53.648 16435-16639/awesomedroidapps.com.debugger I/System.out: line is ?%0.?%0/E????L?@??@????????5??8?[?????????????????apploadingestcrittercismcom??????E????@?:@??@?????d6?? ?>?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???
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

shr*_*der 1

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

如今,大多数通信都是使用 http 完成的,因此您可以使用Charles (mac)Fiddler (windows)等出色的工具,它们可以完全满足您除了 http 之外的要求。他们至少可以为您提供有关如何使用Wireshark做同样事情的想法