Android VpnService数据包嗅探

时间:2016-03-11 20:33:48

标签: java android network-programming packets

我在一个学校项目上工作并遇到障碍,想看看是否有人可以帮我指出正确的方向。我们正在尝试从Android手机中捕获数据包,而无需根植手机。我发现的唯一选择是使用Android的VPNService将其用作捕获数据包的中间人。 我的想法是在onclick事件上创建一个捕获数据包的按钮。

package cybutech.com.datacapture;

import android.app.ActionBar;
import android.content.Intent;
import android.graphics.Color;
import android.net.VpnService;
import android.preference.PreferenceFragment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    private int capture = 1;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar myToolbar = (Toolbar) findViewById(R.id.my_toolbar);
        setSupportActionBar(myToolbar);

        final Button captureData = (Button)findViewById(R.id.capture);
        captureData.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                if (capture == 1) {
                    captureData.setBackgroundColor(Color.RED);
                    captureData.setText("Stop Capture!");
                    Intent intent = VpnService.prepare(getApplicationContext());
                    if (intent != null) {
                        startActivityForResult(intent, 0);
                    } else {
                        onActivityResult(0, RESULT_OK, null);
                    }
                    capture *= -1;
                } else {
                    captureData.setBackgroundColor(Color.GREEN);
                    captureData.setText("Start!");
                    capture *= -1;
                }

            }
        });
    }

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == RESULT_OK) {
            Intent intent = new Intent(this, MyVpnService.class);
            startService(intent);
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.action, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.action_settings:
                startActivity(new Intent(this, Settings.class));

                break;
            default:
                break;
        }

        return true;
    }

}


    package cybutech.com.datacapture;

    import android.content.Intent;
    import android.net.VpnService;
    import android.os.ParcelFileDescriptor;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;

    import java.io.BufferedReader;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.InputStreamReader;
    import java.net.InetSocketAddress;
    import java.nio.channels.DatagramChannel;

    public class MyVpnService extends VpnService {

        private Thread mThread;
        private ParcelFileDescriptor mInterface;
        //a. Configure a builder for the interface.
        Builder builder = new Builder();

        // Services interface
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            // Start a new session by creating a new thread.
            mThread = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        //a. Configure the TUN and get the interface.
                        mInterface = builder.setSession("MyVPNService")
                                .addAddress("192.168.0.1", 24)
                                .addDnsServer("8.8.8.8")
                                .addRoute("0.0.0.0", 0).establish();
                        //b. Packets to be sent are queued in this input stream.
                        FileInputStream in = new FileInputStream(
                                mInterface.getFileDescriptor());
                        //b. Packets received need to be written to this output stream.
                        FileOutputStream out = new FileOutputStream(
                                mInterface.getFileDescriptor());
                        //c. The UDP channel can be used to pass/get ip package to/from server
                        DatagramChannel tunnel = DatagramChannel.open();
                        // Connect to the server, localhost is used for demonstration only.
                        tunnel.connect(new InetSocketAddress("127.0.0.1", 8087));
                        //d. Protect this socket, so package send by it will not be feedback to the vpn service.
                        protect(tunnel.socket());
                        //e. Use a loop to pass packets.
                        while (true) {
                            BufferedReader reader  = new BufferedReader(new InputStreamReader(in));
                            while(true) {
                                String line = reader.readLine();
                                if (line == null) {
                                    System.out.print("NULLLLLLL");
                                    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.

                                Thread.sleep(100);
                            }
                        }

                    } catch (Exception e) {
                        // Catch any exception
                        e.printStackTrace();
                    } finally {
                        try {
                            if (mInterface != null) {
                                mInterface.close();
                                mInterface = null;
                            }
                        } catch (Exception e) {

                        }
                    }
                }

            }, "MyVpnRunnable");

            //start the service
            mThread.start();
            return START_STICKY;
        }

        @Override
        public void onDestroy() {
            // TODO Auto-generated method stub
            if (mThread != null) {
                mThread.interrupt();
            }
            super.onDestroy();
        }
    }

0 个答案:

没有答案