[Android]反編譯apk + eclipse中調試smali

    歷來沒有想過反編譯apk是來的如此方便,而且還能夠修改後從新編譯運行,這比在win下修改pe容易多了,感謝apktool和smali工具的做者提供這麼好的工具。html

 

    跟蹤apk通常的作法是在反編譯的smali代碼中插入log輸出,而後從新編譯運行看輸出日誌,這種方法費時費力,若是可以實時調試是最好的了。搜了一下,目前比較好的方法是使用NetBeans+DDMS。我嘗試過能夠調試,但不大認識NetBeans的操做,eclipse估計不少人都會吧,其實設置跟NetBeans大同小異。java

    調試步驟:android

    1.對apk使用apktool反編譯出可調試的smali代碼到out文件夾,目前apktool最新的版本是2.0.0b7。app

java -jar apktool_2.0.0b7.jar d -d test.apk -o out

    這裏必須使用-d參數,這樣反編譯出來的代碼後綴均是java,由於只有java文件才能被eclipse/netbeans識別調試。eclipse

    2.設置調試標記和尋找主類工具

    在輸出的out文件夾中,用文本編輯工具打開AndroidManifest.xml,在application節點中設置屬性android:debuggable="true"。ui

    繼續在AndroidManifest.xml中,搜索如下關鍵字google

<intent-filter>
    <action android:name="android.intent.action.MAIN"/>
    <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>

    找到含有以上信息的activity節點,記錄其android:name屬性的值,該值則爲其應用的主類。以下面的例子,主類爲com.acids.helloworld.MainActivity。spa

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.acids.helloworld">
    <application android:debuggable="true" android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme">
        <activity android:label="@string/app_name" android:name="com.acids.helloworld.MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>
</manifest>

    3.在主類的onCreate事件中添加調試等待。debug

    用文本編輯工具打開主類文件,找到onCreate方法,在第一句前插入invoke-static {}, Landroid/os/Debug;->waitForDebugger()V,記得添加a=0;//的前綴保持上下一致,結果以下:

a=0;// # virtual methods
a=0;// .method protected onCreate(Landroid/os/Bundle;)V
a=0;//     invoke-static {}, Landroid/os/Debug;->waitForDebugger()V
a=0;// 
a=0;//     .locals 1
a=0;//     .param p1, "savedInstanceState"    # Landroid/os/Bundle;
a=0;// 
a=0;//     .prologue
a=0;//     .line 11
a=0;//     invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V

    4.保存文件,用apktool從新編譯打包爲debug.apk

java -jar apktool_2.0.0b7.jar b -d out -o debug.apk

    5.對debug.apk簽名(須要下載簽名工具),我把簽名工具放在了signapk文件夾下,生成debug.sign.apk

java -jar .\signapk\signapk.jar .\signapk\testkey.x509.pem .\signapk\testkey.pk8 .\debug.apk .\debug.sign.apk

    6.上傳debug.sign.apk至手機或模擬器,而後安裝並運行。這時你會看到程序運行後停留在白屏界面,這時不要動設備和退出程序,由於程序如今是運行到剛纔添加的waitForDebugger代碼這裏,這行代碼的意思是一直掛起中,等待調試器。

 

    下面開始設置實時調試的環境。

    7.啓動eclipse,構建java項目

    1) File -> New -> Project -> Java Project -> Next

    2) Project Name隨便起,Use default location選項去掉,Location選擇out文件夾,而後Next

    3) 把smali文件夾設爲Source Folder,而後Finish

    8.在eclipse中,打開第2步找到的主類,並找到onCreate方法,在waitForDebugger後面的第一個方法開始添加斷點。以下圖

    9.打開DDMS(路徑在%android-sdks%\tools\ddms.bat),若是在第6步中運行了修改後的程序,在DDMS的設備列表中會顯示能夠調試的程序。

    對應程序最後一欄爲8600/8700,其中8600即爲調試該程序的端口。

    10.如今要作的就是把代碼與調試程序關聯便可。 回到eclipse,配置遠程調試

    1) 菜單Run -> Debug -> Debug Configurations

    2) 雙擊Remote Java Application,Host處默認localhost就行,Port填第10步獲得的8600,而後Apply -> Debug。

    11.這時eclipse自動切換至debug視圖,並看到程序已經運行並中斷在下一行可執行的代碼了,相關的變量能夠直接查看了。

 

 

    總結

    已經能夠用eclipse調試smali了,上面的例子是從程序開頭的地方開始調試,但要調試到本身所關心地方的代碼處確實麻煩。建議先用jd-gui等軟件直接查看反編譯的java代碼,肯定要調試的位置後,再進入smali定位斷點並實時調試,就能夠事半功倍。若是不須要在程序的開頭調試的話,建議把第三部的代碼註釋掉。

 

    相關工具能夠在這裏下載

    apktool: https://code.google.com/p/android-apktool/

    dex2jar: https://code.google.com/p/dex2jar/

    jd-gui: http://jd.benow.ca/

 

    轉載請註明原文地址:http://www.cnblogs.com/litou/p/3539281.html

相關文章
相關標籤/搜索