在Android中捕获网络数据包?

时间:2016-02-21 13:39:45

标签: android sockets networking vpn

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

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

VpnService Example

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

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

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

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

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

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

1 个答案:

答案 0 :(得分:1)

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

现在大多数通信都是使用http完成的,因此您拥有像Charles (mac)Fiddler (windows)这样的优秀工具,除了http之外,它们可以完全按照您的要求进行操作。他们至少可以通过Wireshark

为您提供有关如何做同样事情的想法