需求
先前有些手機(jī)應(yīng)用,想獲取接口自動(dòng)化拿些數(shù)據(jù),比如說音樂文件自動(dòng)下載之類的,或者手機(jī)網(wǎng)絡(luò)游戲上自動(dòng)化戰(zhàn)斗什么的,
有些ID或者會(huì)話ID時(shí)常變動(dòng),老是在連電腦用ADB來抓包太麻煩,就想著做個(gè)簡單的抓包應(yīng)用,至于抓到包后如何分析那就是根據(jù)不同
應(yīng)用有不同操作了,這個(gè)本文就不提了。
實(shí)現(xiàn)
本文題目也提到了,是基于tcpdump來實(shí)現(xiàn),(不基于它還真不知道怎么做了,網(wǎng)絡(luò)小白一個(gè))
但是目前很多手機(jī)本身是沒提供這個(gè)可執(zhí)行文件,這是一個(gè)問題;
還有就是這個(gè)命令需要在root下執(zhí)行,這是另外一個(gè)問題。
解決這兩個(gè)問題之后,基本就沒什么難度了。
首先要說下用adb的方式抓包,如果已了解的可跳過,這個(gè)相對(duì)來說權(quán)限更大,可能寫的應(yīng)用抓不到數(shù)據(jù)時(shí)有個(gè)對(duì)比會(huì)比較清楚發(fā)生了什么。
即使在adb下也是需要把tcpdump拷到手機(jī)一個(gè)可執(zhí)行分區(qū)下的,比如MIUI中的/data/local下可讀寫可執(zhí)行。
有些地方看見是remount /system也可以,具體可以自己進(jìn)到shell中mount看下有哪些可讀寫分區(qū)吧。
拷到對(duì)應(yīng)位置后,手機(jī)插上USB,打開調(diào)試,進(jìn)入命令行,執(zhí)行/data/local/tcpdump -p -vv -s 0 -w /sdcard/capture.pcap
類似命令,具體參數(shù)根據(jù)具體情況調(diào)整即可,(中間是v v啊 不是w,顯示更詳細(xì)信息的,后面?zhèn)€才是w指定存儲(chǔ)文件的)
進(jìn)入這種狀態(tài)即開始抓包了,su之后記得手機(jī)端要求給予權(quán)限的。抓包結(jié)果存儲(chǔ)在/sdcard/capture.pcap下
可以adb pull出來查看。
好了,adb下如果成功了,接下來就利用這個(gè)東西來開發(fā)自己的應(yīng)用了。
最底層如何實(shí)現(xiàn)主要考慮上面提到的兩個(gè)問題,那么從第一個(gè)問題開始說。
如果你的手機(jī)還沒有tcpdump功能,那么需要查看下你手機(jī)哪個(gè)分區(qū)可讀寫
我這里直接選擇/data來使用。
由于Android應(yīng)用沒權(quán)限直接對(duì)該分區(qū)讀寫的,SDCARD又沒執(zhí)行權(quán)限,那么這里考慮使用應(yīng)用下載文件到sdcard之后
使用root命令 cat /sdcard/xxx > /data/local/xxx 拷貝過去,之后刪除sdcard文件即可。還需要注意的是拷貝完了要修改文件
權(quán)限,一般增加個(gè)rx讀取執(zhí)行權(quán)限即可。
這個(gè)地方也涉及到使用root來執(zhí)行,這里我只嘗試成功過一種方案,不知道正常的android應(yīng)用需要root執(zhí)行的時(shí)候是不是這種方式,
- Process process = Runtime.getRuntime().exec("su");
- //這個(gè)地方要稍微等待會(huì),系統(tǒng)會(huì)提示給予root權(quán)限,要等待權(quán)限給完,再輸出下一步
- Thread.sleep(1000);
- //按照正常命令行終端執(zhí)行su之后會(huì)進(jìn)入一個(gè)帶#開始的終端
- //這里再嘗試用runtime.exec行不通的感覺,也沒嘗試成功
- //之后就試著獲取process的輸出流輸出命令,記得帶上換行符\n
- process.getOutputStream().write(command.getBytes());
- //先別急著關(guān)閉輸出流,等你不需要用su了再關(guān)閉流吧
- //到這里等待會(huì)應(yīng)該會(huì)有反應(yīng)的,可以嘗試獲取process的錯(cuò)誤流或者輸入流讀取
- //但是這個(gè)地方很煩人的是,如果沒有輸入就被卡住了。。。所以起個(gè)線程讀吧,或者沒必要就不讀取了
- process.getErrorStream()
- process.getInputStream()
root執(zhí)行命令也解決了,剩下的就是來執(zhí)行tcpdump命令了,參數(shù)注意下就行
比如將輸出結(jié)果保存到文件時(shí),tcpdump有一個(gè)緩存區(qū)的,大小默認(rèn)是35567吧,如果沒讀取到就結(jié)束了,整個(gè)信息就都沒有了
android的tcpdump貌似沒有-B參數(shù)指定緩存大小,不過可以用-U來指定每一個(gè)package讀完就寫文件
- String TCPDUMP_COMMAND = String.format(
- "%1$s -p -vv -U -s 0 -w %2$s\n", tcpdumpFilePath, captureFilePath);
好了,整個(gè)應(yīng)用比較簡單,抓包結(jié)果輸出到文件后,解析這個(gè)文件即可。
然后如果有朋友在bluestacks做測(cè)試的話會(huì)發(fā)現(xiàn)有自帶的tcpdump工具,
- // bluestacks自帶tcpdump,用下面的即可
- // static String tcpdumpFilePath = "/system/xbin/tcpdump";
介紹得比較零散,有興趣的直接下代碼看哈~
寫了個(gè)簡單的android應(yīng)用demo丟到google code上了,
svn地址https://my-test-google-svn.googlecode.com/svn/branches/tcpdump
中間有很多參數(shù)都沒做null判斷之類的,按鈕點(diǎn)擊順序就是先點(diǎn)root獲取root權(quán)限后,點(diǎn)開啟,就會(huì)看有沒tcpdump文件
沒有的話會(huì)下載一個(gè)丟到/data/local/下,然后開始執(zhí)行,刷下網(wǎng)頁,弄點(diǎn)流量什么的,之后點(diǎn)停止,關(guān)閉抓包即可,文件保存到
/sdcard/capture.pcap了,之后分析就不要點(diǎn)了,個(gè)人針對(duì)特殊應(yīng)用寫的個(gè)分析。
個(gè)人android應(yīng)用開發(fā)較少,純粹好玩,不恰當(dāng)?shù)牡胤秸?qǐng)留言指點(diǎn)下,thx!
當(dāng)然這個(gè)應(yīng)用寫個(gè)shell腳本之類的可能會(huì)更簡單點(diǎn),主要看個(gè)人需求吧。