由於工作原因,大家都可能需要反編譯一些apk去學習別人優秀的界面設計或者代碼實現,那么網上的關於androd APK反編譯的貼已經很多了,大家肯定都非常清楚,有些貼子還非常貼心的給出了反編譯工具的下載鏈接,非常溫馨,對於像我這樣下載的反編譯工具有時找不見,然后又去翻帖子,可以很快的獲得整套工具實現反編譯,非常感謝他們!!
同時在看帖子的同時發現有個小小的問題,就是這些帖子給出的托管在服務器上鏈接下載地址,有時帖子寫的比較早,下載的反編譯工具版本低,就無法反編譯使用新版本的aapt編譯出來的apk,同時許多人下載以后並沒有看看官網,這工具來源和版本,了解更多一些東西,當然這只是針對於android開發職業的要求,俗話說蛋好吃,無須知道是那只雞下的蛋,但是如果你是專業下蛋的,那還是得了解下好哇。
背景交代完畢,下面給介紹一下反編譯APK流程,同時附上最新的反編譯工具下載地址以及谷歌官網下載鏈接地址,做專業下蛋。
工具列表:
jd-gui,用來查看反編譯源碼的代碼工具,版本比較穩定,一般來說不需要更新
官網地址為http://java.decompiler.free.fr/?q=jdgui,
下載地址為:http://jd.benow.ca/jd-gui/downloads/jd-gui-0.3.5.windows.zip
apktools, 用來反編譯源代碼和圖片、XML配置、語言資源等文件 ,反編譯出來的源代碼都是一些無法看的文件,這個工具主要用來反編譯界面上配置,或者是用來漢化軟件。
官網地址:http://code.google.com/p/android-apktool/
托管地址 :https://code.google.com/p/android-apktool/downloads/list
注意最新的版本為1.5.2,2013.2.2更新的,低於這個版本需要更新。
1.5.2 下載鏈接: https://android-apktool.googlecode.com/files/apktool1.5.2.tar.bz2
dex2jar ,用來反編譯源碼的工具,由谷歌提供,版本在不斷更新,反編譯版本比編譯版本低,就會發生無法反編譯成功的意外。
這個工具理解上就是講dex文件反編譯成jar包,而jar我們可以通過jd_gui來查看源碼,當然,這里反編譯的代碼是經過谷歌官方的混淆的。
官網地址: http://code.google.com/p/dex2jar/
托管地址: http://code.google.com/p/dex2jar/downloads/list
注意最新版本為 dex2jar-0.0.9.11 , 2012.10.25更新的,低於這個版本需要更新。
0.0.9.11 下載地址:http://dex2jar.googlecode.com/files/dex2jar-0.0.9.13.zip
注意:經過一段時間版本可能會更新,如果大家按照正常的方式提示編譯不成功的話,大家則去到官網查看最新版本,是否需要升級 。
以下部分為新手反編譯准備,也歡迎大家指正錯誤,謝謝。
下面是反編譯百度地圖的步驟:
1.工具准備 ---百度地圖 apk+dex2jar+apktools+jd-jui
2.反編譯代碼
首先將apk文件后綴改為zip並解壓,得到其中的classes.dex,它就是java文件編譯再通過dx工具打包而成的,將classes.dex復制到dex2jar.bat所在目錄dex2jar-0.0.9.13文件夾。
在命令行下定位到dex2jar.bat所在目錄,運行
1 D:\360Downloads\Apk\dex2jar-0.0.9.13>dex2jar.bat classes.dex 2 this cmd is deprecated, use the d2j-dex2jar if possible 3 dex2jar version: translator-0.0.9.13 4 dex2jar classes.dex -> classes_dex2jar.jar 5 Done.
使用jd-gui打開,如圖:
3. 使用apktools,反編譯如下:
C:\Users\Administrator>d: D:\360Downloads\Apk\apktool1.5.2>apktool.bat d -f baidumap.apk baidu Input file (baidumap.apk) was not found or was not readable. D:\360Downloads\Apk\apktool1.5.2>apktool.bat d -f D:\360Downloads\Apk\baidumap.a pk D:\360Downloads\Apk\baidumap I: Baksmaling... I: Loading resource table... I: Loaded. I: Decoding AndroidManifest.xml with resources... I: Loading resource table from file: C:\Users\Administrator\apktool\framework\1. apk I: Loaded. I: Regular manifest package... I: Decoding file-resources... I: Decoding values */* XMLs... I: Done. I: Copying assets and libs... D:\360Downloads\Apk\apktool1.5.2>
接下來看下反編譯出來的東西
代碼都是smali,所以你是很難看懂的啦。
通過看assert里面文件夾,其實發現百度地圖加載頁面其實本地已經有了,服務器傳輸一些數據過來顯示即可,這好像很多程序都是這樣做的,
但是注意了,百度的是放在assert里面不是res中,為什么呢?大家想想。
我這次主要就是想看看manifest文件,
我現在關注manifest中,啟動百度地圖的方式和原理是神馬,大家請看下面:
百度manifest文件: 谷歌manifest文件:
百度intent-filter全部如下:

1 <intent-filter> 2 <action android:name="android.intent.action.VIEW" /> 3 <category android:name="android.intent.category.DEFAULT" /> 4 <data android:mimeType="vnd.android.cursor.item/postal-address_v2" /> 5 </intent-filter> 6 <intent-filter> 7 <action android:name="android.intent.action.CREATE_SHORTCUT" /> 8 </intent-filter> 9 <intent-filter> 10 <action android:name="android.intent.action.VIEW" /> 11 <category android:name="android.intent.category.DEFAULT" /> 12 <data android:mimeType="vnd.android.cursor.item/postal-address" /> 13 </intent-filter> 14 <intent-filter> 15 <action android:name="android.intent.action.VIEW" /> 16 <category android:name="android.intent.category.DEFAULT" /> 17 <data android:scheme="geo" /> 18 </intent-filter> 19 <intent-filter> 20 <action android:name="android.intent.action.VIEW" /> 21 <category android:name="android.intent.category.DEFAULT" /> 22 <data android:scheme="http" android:host="j.map.baidu.com" /> 23 </intent-filter> 24 <intent-filter> 25 <action android:name="android.intent.action.VIEW" /> 26 <category android:name="android.intent.category.DEFAULT" /> 27 <category android:name="android.intent.category.BROWSABLE" /> 28 <data android:scheme="bdapp" android:host="map" /> 29 </intent-filter> 30 <intent-filter> 31 <action android:name="android.intent.action.VIEW" /> 32 <category android:name="android.intent.category.DEFAULT" /> 33 <data android:scheme="http" android:host="api.map.baidu.com" /> 34 </intent-filter>
接下來分析一下intent-filter,
1.通過 發送聯系人地址 啟動百度地圖 APP
在這個intent-filter中,開始的兩行說 當你想查看 聯系人地址 時,使用地圖直接幫你定位到地圖中,非常人性化吧,
但是為什么這里給了兩個intent-filter呢? postal-address_v2 以及 postal-address,你懂的,android版本差異咯。
對比谷歌的查看聯系人地址信息intent-filter
1 <intent-filter android:label="@string/MAPS_APP_NAME"> 2 <action android:name="android.intent.action.VIEW" /> 3 <category android:name="android.intent.category.DEFAULT" /> 4 <data android:mimeType="vnd.android.cursor.item/postal-address" /> 5 </intent-filter> 6 <intent-filter android:label="@string/MAPS_APP_NAME"> 7 <action android:name="android.intent.action.VIEW" /> 8 <category android:name="android.intent.category.DEFAULT" /> 9 <data android:mimeType="vnd.android.cursor.item/postal-address_v2" /> 10 </intent-filter>
2.通過 geo,啟動百度地圖APP
intent發送geo方式,
百度的
1 <intent-filter> 2 <action android:name="android.intent.action.VIEW" /> 3 <category android:name="android.intent.category.DEFAULT" /> 4 <data android:scheme="geo" /> 5 </intent-filter>
這個意思就是視同intent.action.view,方式來查看某個地址,而且很巧的是這個地址的開頭是geo,那么就通過百度地圖APP來打開
谷歌的
1 <intent-filter android:label="@string/MAPS_APP_NAME"> 2 <action android:name="android.intent.action.VIEW" /> 3 <category android:name="android.intent.category.DEFAULT" /> 4 <category android:name="android.intent.category.BROWSABLE" /> 5 <data android:scheme="geo" /> 6 </intent-filter>
這個意思就是說通過瀏覽器打開一個地址,而且很巧的是這個地址的開頭是geo,那么就通過百度地圖APP來打開
3.http打開百度地圖
百度

1 <intent-filter> 2 <action android:name="android.intent.action.VIEW" /> 3 <category android:name="android.intent.category.DEFAULT" /> 4 <data android:scheme="http" android:host="j.map.baidu.com" /> 5 </intent-filter> 6 <intent-filter> 7 <action android:name="android.intent.action.VIEW" /> 8 <category android:name="android.intent.category.DEFAULT" /> 9 <categoryandroid:name="android.intent.category.BROWSABLE" /> 10 <data android:scheme="bdapp" android:host="map" /> 11 </intent-filter> 12 <intent-filter> 13 <action android:name="android.intent.action.VIEW" /> 14 <category android:name="android.intent.category.DEFAULT" /> 15 <dataandroid:scheme="http"android:host="api.map.baidu.com" /> 16 </intent-filter>
這個意思是說,使用intent-filter-view,啟動一個activity,intent中帶的數據sceme = http 或者bdapp,且 host= j.baidu.com或者是api.map.baidu.com 的時候,那么就啟動百度地圖APP
谷歌的

1 <intent-filter> 2 <action android:name="android.intent.action.VIEW" /> 3 <category android:name="android.intent.category.DEFAULT" /> 4 <category android:name="android.intent.category.BROWSABLE" /> 5 <data android:scheme="http" /> 6 <data android:scheme="https" /> 7 <data android:host="maps.google.com.br" android:path="/" /> 8 </intent-filter> 9 <intent-filter> 10 <action android:name="android.intent.action.VIEW" /> 11 <category android:name="android.intent.category.DEFAULT" /> 12 <category android:name="android.intent.category.BROWSABLE" /> 13 <data android:scheme="http" /> 14 <data android:scheme="https" /> 15 <data android:host="maps.google.com.br" android:pathPrefix="/maps" /> 16 </intent-filter>
意思是使用intent-filter-view,啟動一個activity,intent中帶的數據sceme = http,且 host= j.baidu.com 的時候,那么就啟動谷歌地圖APP,
那么這里有個地方 host,谷歌給很多國家都對應一個host 比如英國:maps.google.com.br 法國:maps.google.fr 等等。
4.谷歌地圖有的但是百度地圖沒有的啟動方式
a) 通過nfc近場通訊
谷歌的:
1 <intent-filter> 2 <action android:name="android.nfc.action.NDEF_DISCOVERED" /> 3 <category android:name="android.intent.category.DEFAULT" /> 4 <data android:scheme="http" /> 5 <data android:scheme="https" /> 6 <data android:host="maps.google.com.br" android:path="/" /> 7 </intent-filter> 8 <intent-filter> 9 <action android:name="android.nfc.action.NDEF_DISCOVERED" /> 10 <category android:name="android.intent.category.DEFAULT" /> 11 <data android:scheme="http" /> 12 <data android:scheme="https" /> 13 <data android:host="maps.google.com.br" android:pathPrefix="/maps" /> 14 </intent-filter>
b)通過search來 啟動
1 <intent-filter> 2 <action android:name="android.intent.action.SEARCH" /> 3 <category android:name="android.intent.category.DEFAULT" /> 4 </intent-filter>
c) 通過設置 網絡來啟動
1 <intent-filter android:label="@string/MAPS_APP_NAME"> 2 <action android:name="android.intent.action.MANAGE_NETWORK_USAGE" /> 3 <category android:name="android.intent.category.DEFAULT" /> 4 </intent-filter> 5 <intent-filter android:label="@string/MAPS_APP_NAME"> 6 <action android:name="com.google.android.apps.maps.LOCATION_SETTINGS" /> 7 <category android:name="android.intent.category.DEFAULT" /> 8 </intent-filter>
d)通過 全景圖 來啟動
1 <intent-filter android:label="@string/MAPS_APP_NAME"> 2 <action android:name="android.intent.action.SEND" /> 3 <category android:name="android.intent.category.DEFAULT" /> 4 <data android:mimeType="application/vnd.google.panorama360+jpg" /> 5 </intent-filter>
這里大家可能不清楚 application/vnd.google.panorama360+jpg 這是個什么玩意,其實這個是谷歌應用市場上的一個付費app。具體大家可以看到
https://play.google.com/store/apps/details?id=com.occipital.panorama
e) 這個我也不知道是用來干嘛的 lol 。。。。
1 <intent-filter android:label="@string/MAPS_APP_NAME"> 2 <action android:name="android.intent.action.VIEW" /> 3 <category android:name="android.intent.category.DEFAULT" /> 4 <data android:scheme="google.layeritemdetails" /> 5 </intent-filter>
有什么不對,請大家指正。謝謝