大多數APP都對API接口進行了加密,防止第三方隨意調用接口绩聘,常用的方法是,設置一個key凿菩,在調用接口來發(fā)送請求時,組合各個參數和key按照一定的規(guī)則(排序帜讲,MD5等等)生成一個用于驗證的token參數,服務端接收到請求后似将,按照相同的規(guī)則組合參數和key去生成token,和收到的token去對比在验,判斷請求是否是第三方偽造發(fā)送的肢执。
但是通過抓包和反編譯APP,是可以得到key和生成token的規(guī)則兴溜,來將自己偽裝成官方的APP侦厚,調用API接口
下面的文章拙徽,主要是總結我自己反編譯魅族天氣的APP來獲取API的過程。
工具
- 魅族天氣
- dex2jar
- jd-gui
- Android Studio(內置adb膘怕,apktool)
- ideasmali(Android Studio插件)
反編譯class.dex獲取java代碼
原理:打包生成apk時,java源代碼先被編譯成.class文件岛心,然后Android SDK自帶的dx工具將這些.class文件轉換成classes.dex来破,所以可以反編譯classes.dex來得到java源代碼
步驟
- 下載dex2jar.zip和jd-gui徘禁,并解壓
- 將com.meizu.flyme.weather-2.2.1-2002001.apk重命名為com.meizu.flyme.weather-2.2.1-2002001.zip
- 解壓com.meizu.flyme.weather-2.2.1-2002001.zip,在解壓得到的目錄里找到classes.dex
- 使用dex2jar將classes.dex反編譯得到classes-dex2jar.jar
- 使用jd-gui查看classes-dex2jar.jar
操作截圖(Mac)
![image](http://ww1.sinaimg.cn/large/006Jp30hgy1fhv1ita681j31cs12wwm1.jpg)
![image](http://ww1.sinaimg.cn/large/006Jp30hgy1fhv1ithka8j31ni12agv9.jpg)
注意:執(zhí)行反編譯指令時送朱,可能會提示d2j_invoke.sh: Permission denied娘荡,輸入sudo chmod +x d2j_invoke.sh來解決
閱讀java代碼
這一步要耐心驶沼,因為代碼一般經過來混淆,生成很難看懂的代碼回怜,來到達保護代碼的目的
通過抓包大年,獲得了天氣信息的請求
![image](http://ww1.sinaimg.cn/large/006Jp30hgy1fhv2d1y6lfj325c1b6guo.jpg)
然后我觀察到sign參數鹉戚,在每次請求時都會發(fā)生變化,它應該就是那個用于驗證的參數抹凳。
在一堆經過混淆的代碼中,會需要比較多的時間赢底,查找到生成驗證參數sign的相關代碼,這需要耐心幸冻。但利用搜索粹庞,可以加快查找的速度洽损。
在jd-gui里,F(xiàn)ile->Save All Sources碑定,將反編譯的java文件保存到source文件夾,我們利用請求的url去搜索(代碼里的常量字符串一般不會被混淆延刘,利用字符串去搜索漫试,一般都會找到有用的信息碘赖,來進一步查找
)
![image](http://ww1.sinaimg.cn/large/006Jp30hgy1fhv35ik5orj31cs0tgai0.jpg)
可以看到在source/com/meizu/flyme/weather/common/ad.java有拼接url的代碼,這很有可能是我們需要的代碼片段
在jd-gui里普泡,打開ad.java
![image](http://ww1.sinaimg.cn/large/006Jp30hgy1fhv3bpu7uuj325c1bcwtf.jpg)
paramAnonymousVarArgs = "cityId=" + paramString + "&bizId=" + "aider_app" + "×tamp=" + l + "&sign=" + ad.a(paramAnonymousVarArgs);
這應該就是我們需要的代碼,可以點擊ad.a撼班,跳轉到函數內部,里面的代碼并不復雜权烧。通過閱讀代碼眯亦,可以很容易地得到生成sign的規(guī)則(MD5(城市id+"aider_app"+時間戳+"29cc0378-3802-4470-a1e2-07ce9f34b208"))。
反編譯APP獲取smali代碼
Android系統(tǒng)有自己的虛擬機Dalvik,代碼編譯最終不是采用的java的class妻率,而是使用的smali。我們反編譯得到的代碼宫静,jar的話可能很多地方無法正確的解釋出來走净,如果我們反編譯的是smali則可以正確的理解程序的意思孤里。
在抓取短時預報的請求,就出現(xiàn)了無法解釋的情況
![image](http://ww1.sinaimg.cn/large/006Jp30hgy1fhv70c6jlzj325c1b6k2k.jpg)
通過搜索捌袜,最后跳轉到下圖的方法
![image](http://ww1.sinaimg.cn/large/006Jp30hgy1fhv719wgklj325c1bawxt.jpg)
這些看起來像偽代碼。虏等。弄唧。
我們可以利用apktool來反編譯App候引,獲取最終的smali代碼,解決無法解釋的問題
mv com.meizu.flyme.weather-2.2.1-2002001.zip com.meizu.flyme.weather-2.2.1-2002001.apk
apktool -o weather_apktool d com.meizu.flyme.weather-2.2.1-2002001.apk
![image](http://ww1.sinaimg.cn/large/006Jp30hgy1fhv7hjx701j31cs0y648y.jpg)
切換到weather_apktool目錄敦跌,smali文件夾里就是反編譯得到的smali代碼,我們找到剛才解釋錯誤的文件
vim weather_apktool/smali/com/moji/mjweather/request/MJWeatherSDK.smali
![image](http://ww1.sinaimg.cn/large/006Jp30hgy1fhv7maqmurj31ce18kwn8.jpg)
上圖就是代碼對應的smali代碼柠傍,語法有點像匯編,這里有一篇教程(android反編譯-smali語法)携兵,可以先閱讀一遍教程,再去閱讀smali代碼
利用apktool反編譯apk來二次打包
看著smali代碼徐紧,還是有點懵逼...有沒有方法像debug一樣,可以隨時查看變量的值炭懊,一行一行地運行程序呢?
還真有N旮埂!父阻!我們可以用Android Studio來動態(tài)調試smali代碼S!履婉!
我們先用usb連接手機,開啟手機的開發(fā)者模式毁腿,然后打開Android Studio的Android Device Monitor辑奈,可以看到我們的手機已經連接上電腦了
![image](http://ww1.sinaimg.cn/large/006Jp30hgy1fhv8dppmimj325c1b6n87.jpg)
但是我們沒有看到程序對應的進程已烤。。胯究。
經過google,原來真機上唐片,只有AndroidManifest.xml里設置有android:debuggable="true"時丙猬,ADM才會出現(xiàn)對應的進程费韭。那我們要如何添加android:debuggable="true"呢?這就涉及到了apk的二次打包星持。
我們可以修改程序的smali代碼,修改app的行為(例如去掉廣告督暂,或者游戲里面增加金幣)揪垄,然后重新打包成apk文件逻翁,安裝到我們的手機上“嘶兀看到這里,你當然會想缠诅,這樣我們不就可以隨意修改app了嗎溶浴?當然不可能這么簡單管引,一般大公司的app都會加入各種機制,來防止用戶修改app的行為褥伴,二次打包漾狼,難以重新打包成功或者運行程序時馬上崩潰。這就涉及到了如何防反編譯的話題了戏自。
我們拿之前的魅族天氣來嘗試進行二次打包,這種小的擅笔,不涉及到金錢的程序志衣,防反編譯的處理都比較弱
我們在之前apktool反編譯smali的weather_apktool里猛们,找到AndroidManifest.xml,加入
<application ....
android:debuggable="true">...</application>
![image](http://ww1.sinaimg.cn/large/006Jp30hgy1fhv91b056cj31ce18ktf5.jpg)
重新打包成apk后弯淘,還需要加上數字簽名,才能安裝到手機上庐橙,Android系統(tǒng)要求每一個Android應用程序必須要經過數字簽名才能夠安裝到系統(tǒng)中,也就是說如果一個Android應用程序沒有經過數字簽名态鳖,是沒有辦法安裝到系統(tǒng)中的转培!
我們使用keytool(Java數據證書的管理工具)
來生成數字簽名
keytool -genkey -keystore cmd.keystore -keyalg RSA -validity 10000 -alias cmd.keystore
![image](http://ww1.sinaimg.cn/large/006Jp30hgy1fhv955e2gpj31ce18kwor.jpg)
給二次打包的apk加上數字簽名
jarsigner -verbose -keystore cmd.keystore -signedjar weather.apk weather.apk cmd.keystore
安裝app
adb devices
adb -s 手機編碼 install weather.apk
安裝過程中浆竭,可能會出現(xiàn)Failure [INSTALL_FAILED_UPDATE_INCOMPATIBLE]的錯誤,這一般是卸載得不干凈的原因邦泄,可以執(zhí)行
adb shell pm list packages # 列出手機安裝的所有app包名
adb uninstall 包名
然后重新安裝,安裝成功后顺囊,執(zhí)行
adb shell am start -D -n 包名/MainActivity #(包名和MainActivity可以在AndroidManifest.xml找到)
在debug模式下啟動App肌索,成功了L靥肌!测萎!
天氣的自動定位問題
原因:重新打包后亡电,APK簽名文件的sha1與高德地圖的key對應的sha1不符合
http://lbs.amap.com/faq/top/hot-questions/249
Android Studio動態(tài)調試smali代碼
好硅瞧,我們開始動態(tài)調試smali代碼,先下載ideasmali腕唧,打開Android Studio或辖,安裝好ideasmali插件枣接,選擇Import project(Eclipse ADT, Gradle, etc.), 選擇weather_apktool文件夾,然后一路next
![image](http://ww1.sinaimg.cn/large/006Jp30hgy1fhva6kaw8tj31de0vsgr9.jpg)
選著smali文件夾但惶,右鍵Mark Directory As -> Sources Root
![image](http://ww1.sinaimg.cn/large/006Jp30hgy1fhvw9fon28j31tq17mwox.jpg)
配置遠程調試的選項耳鸯,選擇Run-->Edit Configurations:增加一個Remote調試的調試選項膀曾,端口選擇:8700
![image](http://ww1.sinaimg.cn/large/006Jp30hgy1fhvalrvc1sj31tq17mwox.jpg)
之后選擇File-->Project Structure 配置JDK
![image](http://ww1.sinaimg.cn/large/006Jp30hgy1fhvanvncp9j31r41b813s.jpg)
查看Android Device Monitor,查看進程的端口
![image](http://ww1.sinaimg.cn/large/006Jp30hgy1fhvatcjt1bj325c1b67fl.jpg)
以調試狀態(tài)啟動app添谊,并轉發(fā)端口
![image](http://ww1.sinaimg.cn/large/006Jp30hgy1fhvb6wq5zvj31d619iwky.jpg)
記得關閉Android Device Monitor
下好斷點之后Run-->Debug 'remote'
![image](http://ww1.sinaimg.cn/large/006Jp30hgy1fhvarrej42j325c1b6qmz.jpg)
運行起來之后就可以單步執(zhí)行,查看寄存器的值斩狱,慢慢調試了
![image](http://ww1.sinaimg.cn/large/006Jp30hgy1fhvb8pg5coj325c1b6x0h.jpg)
總結
Android的反編譯很有很多內容沒有深入了解過,為了能更好地反編譯出代碼所踊,深入了解Android系統(tǒng)是必要的泌枪,推薦一本書污筷,Android軟件安全與逆向分析,可以更加系統(tǒng)和深入的學習Android軟件的反編譯