Eclipse动态调试指南
本文对Eclipse进行动态调试做一个全面的讲解(动态调试还可以采用Android studio、netbeans等工具,请参见Android studio动态调试指南),旨在为广大只有apk而没有源代码的程序猿提供排查bug的另辟蹊径。
操作步骤
1.反编译
对目标apk使用apktool反编译出可调试的smali代码到out文件夹,目前apktool最新的版本是2.0.1。
e.g. java -jar apktool_2.0.1.jar d -d target.apk -o out
注意:-d参数是必须的,因为这样反编译出来的代码后缀均是java,因为只有java文件才能被eclipse/netbeans识别调试。
2.设置调试标记
在输出的out文件夹中,用文本编辑工具打开AndroidManifest.xml,在application节点中设置属性android:debuggable=”true”。
e.g. <application android:debuggable="true" android:icon="@drawable/icon" android:label="@string/app_name" android:name="com.boyaa.godsdk.core.MutiUnipayApplication">
3.在主Activity的onCreate事件中添加调试等待(可选)
注意:如果不需要在程序的开头调试的话,建议忽略这一步。
用文本编辑工具打开主类文件,找到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
e.g. java -jar apktool_2.0.1.jar b -d out -o debug.apk
5.对debug.apk签名(建议采用安卓逆向助手),生成debug_sign.apk
当然也可以直接采用JDK里面的签名工具通过命令行手动进行签名:
e.g. “jarsigner” -keystore “C:\Users\CoulsonChen\Desktop\kop.keystore” -storepass “kop1122334” -keypass “kop1122334” “D:\t\125.apk” “kop” -sigalg SHA1withRSA -digestalg SHA1
6.上传debug_sign.apk至手机或模拟器,然后安装并运行。
如果启用第3步,这时你会看到程序运行后停留在白屏界面,这时不要动设备和退出程序,因为程序现在是运行到刚才添加的waitForDebugger代码这里,这行代码的意思是一直挂起中,等待调试器。
如果未启用第3步,则apk正常运行(与普通安装apk无异)。
7.启动eclipse,构建java项目
- File -> New -> Project -> Java Project -> Next
- Project Name随便起,Use default location选项去掉,Location选择第1步指定的out文件夹,然后Next
- 把smali文件夹设为Source Folder,然后Finish
8.在eclipse中,在需要关注的地方添加断点
设置断点示例:
打开DDMS(路径在%android-sdks%\tools\ddms.bat),如果在第6步中运行了修改后的程序,在DDMS的设备列表中会显示可以调试的程序。
从上图可以看到,调试的端口为8608
9.现在要做的就是把代码与调试程序关联即可
回到eclipse,配置远程调试
- 菜单Run -> Debug -> Debug Configurations
- 双击Remote Java Application,Host处默认localhost就行,Port填第9步得到的8608,然后Apply -> Debug。
示意图:
10.切换至debug视图
看到程序已经运行并中断在下一行可执行的代码了,相关的变量可以直接查看了。示意图: