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 off
set 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=$0
while [ -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}
    fi
done
oldwd=`pwd`
progdir=`dirname ${prog}`
cd ${progdir}
progdir=`pwd`
prog=${progdir}/`basename ${prog}`
cd ${oldwd}


jarfile=apktool.jar
libdir=$progdir
if [ ! -r $libdir/$jarfile ]
then
    echo `basename $prog`: can't find $jarfile
    exit 1
fi

javaOpts=

# 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}
    shift
done

if [ $OSTYPE = cygwin ] ; then
	jarpath=`cygpath -w  $libdir/$jarfile`
else
	jarpath=$libdir/$jarfile
fi

# add current location to path for aapt
PATH=$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代碼保持一致。

 

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *