首页 > 代码库 > Android tcpdump抓包应用实现

Android tcpdump抓包应用实现

 

Android tcpdump抓包应用实现

 

Android应用很多时候都会涉及到网络,在请求网络出错时,我们可以通过抓包来分析网络请求,返回的数据等,通常我们是用tcpdump这个工具来抓包,再通过wireshark工具来分析生成的文件,关于tcpdump的使,可以从网上查一下,有很多介绍,比如:http://www.cnblogs.com/likwo/archive/2012/09/06/2673944.html。关于如何用wireshark来分析文件,本文不作介绍。

使用adb的命令来操作,还是比较麻烦,所以我写了一个应用,把这些命令封装了起来。实现的最根本的原理是通过Runtime.exec来执行linux命令。

运行截图

实现代码

CommandsHelper.java
/** *  * @author lihong06 * @since 2014-3-3 */public class CommandsHelper {    private static final String NAME = "tcpdump";    private static final String TAG = "CommandsHelper";    public static final String DEST_FILE = Environment.getExternalStorageDirectory() + "/capture.pcap";        public static boolean startCapture(Context context) {        InputStream is = null;        OutputStream os = null;        boolean retVal = false;        try {            AssetManager am = context.getAssets();            is = am.open(NAME);            File sdcardFile = Environment.getExternalStorageDirectory();            File dstFile = new File(sdcardFile, NAME);            os = new FileOutputStream(dstFile);                        copyStream(is, os);                        String[] commands = new String[7];            commands[0] = "adb shell";            commands[1] = "su";            commands[2] = "cp -rf " + dstFile.toString() + " /data/local/tcpdump";            commands[3] = "rm -r " + dstFile.toString();            commands[4] = "chmod 777 /data/local/tcpdump";            commands[5] = "cd /data/local";            commands[6] = "tcpdump -p -vv -s 0 -w " + DEST_FILE;                        execCmd(commands);        } catch (IOException e) {            e.printStackTrace();            Log.i(TAG, "    error: " + e.getMessage());        } finally {            closeSafely(is);            closeSafely(os);        }                return retVal;    }        public static void stopCapture(Context context) {        // 找出所有的带有tcpdump的进程        String[] commands = new String[2];        commands[0] = "adb shell";        commands[1] = "ps|grep tcpdump|grep root|awk ‘{print $2}‘";        Process process = execCmd(commands);        String result = parseInputStream(process.getInputStream());        if (!TextUtils.isEmpty(result)) {            String[] pids = result.split("\n");            if (null != pids) {                String[] killCmds = new String[pids.length];                for (int i = 0; i < pids.length; ++i) {                    killCmds[i] = "kill -9 " + pids[i];                }                execCmd(killCmds);            }        }    }        public static Process execCmd(String command) {        return execCmd(new String[] { command }, true);    }        public static Process execCmd(String[] commands) {        return execCmd(commands, true);    }        public static Process execCmd(String[] commands, boolean waitFor) {        Process suProcess = null;        try {            suProcess = Runtime.getRuntime().exec("su");            DataOutputStream os = new DataOutputStream(suProcess.getOutputStream());            for (String cmd : commands) {                if (!TextUtils.isEmpty(cmd)) {                    os.writeBytes(cmd + "\n");                }            }            os.flush();            os.writeBytes("exit\n");            os.flush();        } catch (IOException e) {            e.printStackTrace();        }        if (waitFor) {            boolean retval = false;            try {                int suProcessRetval = suProcess.waitFor();                if (255 != suProcessRetval) {                    retval = true;                } else {                    retval = false;                }            } catch (Exception ex) {                Log.w("Error ejecutando el comando Root", ex);            }        }                return suProcess;    }        private static void copyStream(InputStream is, OutputStream os) {        final int BUFFER_SIZE = 1024;        try {            byte[] bytes = new byte[BUFFER_SIZE];            for (;;) {                int count = is.read(bytes, 0, BUFFER_SIZE);                if (count == -1) {                    break;                }                os.write(bytes, 0, count);            }        } catch (IOException e) {            e.printStackTrace();        }    }        private static void closeSafely(Closeable is) {        try {            if (null != is) {                is.close();            }        } catch (IOException e) {            e.printStackTrace();        }    }        private static String parseInputStream(InputStream is) {        InputStreamReader isr = new InputStreamReader(is);        BufferedReader br = new BufferedReader(isr);        String line = null;        StringBuilder sb = new StringBuilder();        try {            while ( (line = br.readLine()) != null) {                sb.append(line).append("\n");            }        } catch (IOException e) {            e.printStackTrace();        }                return sb.toString();    }}

MainActivity.java
public class MainActivity extends Activity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);                final TextView textView = (TextView) findViewById(R.id.textView1);        String oldText = textView.getText().toString();        textView.setText(oldText + "\n\n" + "目标文件: " + CommandsHelper.DEST_FILE);                findViewById(R.id.start_capture).setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                v.setEnabled(false);                new Thread(new Runnable() {                    @Override                    public void run() {                        final boolean retVal = CommandsHelper.startCapture(MainActivity.this);                        runOnUiThread(new Runnable() {                            @Override                            public void run() {                                Toast.makeText(MainActivity.this, "startCapture result = " + retVal, Toast.LENGTH_SHORT).show();                            }                        });                    }                }).start();            }        });                findViewById(R.id.stop_capture).setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                CommandsHelper.stopCapture(MainActivity.this);                findViewById(R.id.start_capture).setEnabled(true);            }        });    }    @Override    public boolean onCreateOptionsMenu(Menu menu) {        // Inflate the menu; this adds items to the action bar if it is present.        getMenuInflater().inflate(R.menu.main, menu);        return true;    }}

说明

1、手机必须要Root,没有root的我没有测试过,另外,我也只测试了我一台手机,没有覆盖到所有的手机。
2、大家如果发现问题,请告知于我,谢谢。

Android tcpdump抓包应用实现