Android 反編譯(一,apktool+smail2java)
一:解壓縮(擷取圖片等資源)
對於apk中豐富的資源,如果我們在練習的時候需要引用某些apk中的資源檔時,最簡單的辦法使用解壓縮工具對apk進行解壓縮,然後在相應的目錄下尋找需要的資源檔。
二:反編譯APK
我們可以通過解壓縮的方式去使用某些apk中res/drawable,res/raw,assets目錄下的相關多媒體資源和字型檔等,但是想要同時臨摹動畫、布局等xml資源卻無能為力,因為res/raw和assets檔案夾來存放不需要系統編譯成二進位的檔案,而其他檔案在打包的過程會編譯成二進位檔案。那麼此時我們該怎麼辦呢?
Google Code上為我們提供了對apk進行反編譯的工具包-apktool,當前最新的版本是2.0.0 RC4,2015-02-12由iBotPeaches上傳在https://bitbucket.org/iBotPeaches/apktool/downloads(由於google將要關閉google code服務,所有版本的apktool將會在Bitbucket上發布),當然我們也可以從Google Code中搜尋到該入口。
我們通過apktool對apk進行反編譯操作,從而得到apk應用中的原始碼和圖片、XML配置、語言資源等檔案。那麼如何使用apktool呢,下面我們簡單的介紹一下(這裡參考Google Code上提供的文檔,查看原文檔請移步https://code.google.com/p/android-apktool/wiki/ApktoolOptions):
1.apktool下載
通過上面的下載串連我們可以得到名為apktool_2.0.0rc4.jar的jar包,那麼我們該如何使用它呢?
1>重新命名
將apktool_2.0.0rc4.jar修改為apktool.jar;
2>適配不同的作業系統
windows下
將下面指令碼內容儲存在apktool.bat檔案中
@echo offset PATH=%CD%;%PATH%;java -jar -Duser.language=en %~dp0apktool.jar %1 %2 %3 %4 %5 %6 %7 %8 %9
linux下:
將下面指令碼內容儲存為apktool檔案
#!/bin/bash## Copyright (C) 2007 The Android Open Source Project## Licensed under the Apache License, Version 2.0 (the License);# you may not use this file except in compliance with the License.# You may obtain a copy of the License at## http://www.apache.org/licenses/LICENSE-2.0## Unless required by applicable law or agreed to in writing, software# distributed under the License is distributed on an AS IS BASIS,# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# See the License for the specific language governing permissions and# limitations under the License.# This script is a wrapper for smali.jar, so you can simply call smali,# instead of java -jar smali.jar. It is heavily based on the dx script# from the Android SDK# Set up prog to be the path of this script, including following symlinks,# and set up progdir to be the fully-qualified pathname of its directory.prog=$0while [ -h ${prog} ]; do newProg=`/bin/ls -ld ${prog}` echo ${newProg} newProg=`expr ${newProg} : .* -> (.*)$` if expr x${newProg} : 'x/' >/dev/null; then prog=${newProg} else progdir=`dirname ${prog}` prog=${progdir}/${newProg} fidoneoldwd=`pwd`progdir=`dirname ${prog}`cd ${progdir}progdir=`pwd`prog=${progdir}/`basename ${prog}`cd ${oldwd}jarfile=apktool.jarlibdir=$progdirif [ ! -r $libdir/$jarfile ]then echo `basename $prog`: can't find $jarfile exit 1fijavaOpts=# If you want DX to have more memory when executing, uncomment the following# line and adjust the value accordingly. Use java -X for a list of options# you can pass here.# javaOpts=-Xmx512M# Alternatively, this will extract any parameter -Jxxx from the command line# and pass them to Java (instead of to dx). This makes it possible for you to# add a command-line parameter such as -JXmx256M in your ant scripts, for# example.while expr x$1 : 'x-J' >/dev/null; do opt=`expr $1 : '-J(.*)'` javaOpts=${javaOpts} -${opt} shiftdoneif [ $OSTYPE = cygwin ] ; thenjarpath=`cygpath -w $libdir/$jarfile`elsejarpath=$libdir/$jarfilefi# add current location to path for aaptPATH=$PATH:`pwd`;export PATH;exec java $javaOpts -jar $jarpath $@
3>設定環境變數
將apktool.jar和apktoo.bat所在的檔案夾添加到系統內容變數中或者拷貝到系統檔案夾中C://Windows,Linux下拷貝到/usr/local/bin (root needed)中,並且要記得修改檔案許可權(chmod +x)
實用選項
-version, --version
輸出目前的版本。
-v, --verbose
詳細輸出,該命令在所有其他命令之前。
-q, --quiet
靜態輸出. 該命令在所有其他命令之前。
-advance, --advanced
列印進階選項。
反編譯選項
--api
產生smali檔案的api版本。(eg 14 for ICS).
-b, --no-debug-info
不列印log資訊.
-d, --debug
啟動debug模式
--debug-line-prefix
Smali line prefix when decoding in debug mode. Default a=0;//
-f, --force
如果反編譯後產生的檔案目錄已經存在,則強制覆蓋。
--keep-broken-res
如果反編譯過程正發生錯誤,需手動修複。
-m, --match-original
最大可能保持檔案接近原始檔案,防止重建,通常用於分析。
-o, --output
指定輸出路徑.
-p, --frame-path
指定framework路徑.
-r, --no-res
防止重新編譯資源檔。
-s, --no src
防止重新編譯源檔案.
-t, --frame-tag
使用framework檔案標記.
如何反編譯?
反編譯之前, 必須保證frameworks已經安裝。有關Frameworks可以訪問https://code.google.com/p/android-apktool/wiki/FrameworkFiles。如果已安裝了frameworks,可以運行如下命令進行反編譯:
apktool d name_of_apk.apk
重建選項
-a, --aapt
從指定的路徑總載入aapt,如果找不到相關目錄則會執行復原操作.
-c, --copy-original
拷貝 AndroidManifest.xml 和 META-INF 檔案夾到重建的apk中.
-d, --debug
啟動debug模式。
-f, --force-all
重建過程中覆蓋已存在的檔案.
-o, --output
指定輸出路徑.
-p, --frame-path
指定framework files的路徑.
如何重建一個項目?
apktool b folder_of_decoded_apk
那麼通過apktool d xx.apk,我們將apk檔案反編譯之後我們就可以使用編輯工具查看一些xml設定檔了,但是源檔案對於我們來說還是未解之謎。因為apktool將Android位元組碼檔案轉換為smali檔案。
smali是將Android位元組碼用可閱讀的字串形式表現出來的一種語言,可以稱之為Android位元組碼的反組譯碼語言。使用baksmali或apktool可以將Android應用程式套件組合(apk或jar)反編譯為smali代碼。
那麼我們接下來要做的就是把smali檔案反編譯為java檔案。
三:反編譯smali
smali2java是一個將smali代碼反編譯成java代碼的工具,是基於apktool v1.5.0(baksmali v1.3.4)產生的smali檔案,依賴於smali檔案中的程式碼數(.line關鍵字)和變數別名(.local關鍵字)等資訊,可以最大程度還原原始的java代碼。還原出的java代碼將具有原始的變數命名,代碼的順序也與原始的java代碼保持一致。