[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

相关文章
相关标签/搜索