1. 为什么要学会动态调试Smali代码?
为了减轻我们逆向分析的负担!
Smali文件中代码量是十分庞大的,而且Smali语法也并不是那么容易就会明白,逆向分析APK,试图找到它的漏洞,面对大篇幅的Smali文件代码,还有现如今基本上每一款商业级的App为了安全都会采用混淆和加壳策略,就算使用ApkTool等工具将APK反编译成Smali文件,生成的Smali代码还是一堆诸如:a,b,c,d.....等无用的类、函数、变量。可能完全找不到实现程序功能的“真正”代码!因此采用动态调试的方法,以打断点的方式来逐步调试Smali代码是势在必行的一个技能。动态调试也是逆向的基本技能!
2. 动态调试Smali代码总结
参考链接(建议查看此教程,自己搭建环境进行Smali代码的动态调试)
(1) 知识点儿
- 远程调试的前题是:确认调试APK的AndroidManifest.xml文件中,<application>标签的android:debuggable属性为true。
- DDMS
Dalvik Debug Monitor Serivce,Dalvik调试监控服务,为Android SDK提供的一款拥有监控Dalvik虚拟机的调试软件,启动:打开Andorid SDK选择Tools>Android>Android Device Monitor。 - adb forward命令
用于创建一个端口映射,将本地端口(本地PC端口),映射到远程端口(测试软件使用的手机)
例如这里用到的:adb forward tcp:8700 jdwp:5657 - JDWP
Java Debug Wire Protocol,Java调试线程协议,定义了调试器(debugger)和被调试的 Java 虚拟机(target vm)之间的通信协议。
为什么使用JDWP协议?
Dalvik虚拟机会启动一个JDWP线程,用于远程调试。远程调试器可以通过JDWP端口号,调试指定进程。每个可调试的进程的PID就是其JDWP的端口号。可以使用adb jdwp命令查看所有可以调试的进程PID(需要使用ctrl + c退出)。
- 在.method字段,使用"Find Usage"功能,可以定位该方法的所有调用者。
- 在方法类型上,使用"Declaration",可以定位方法的定义处。
(2) 动态调试基本流程
a. 首先使用ApkTool工具反编译APK文件,得到Smali文件。
b. 然后使用AS打开反编译APK生成的文件夹。并将Smali文件,设置成Source Root 文件。
c. 然后创建远程调试(调试的本地端口一般为8700)
d. 然后启动应用:
adb shell am start -D -n 主活动路径/主活动,在Android Device Monitor查看端口号和程序的PID。
e. 然后绑定端口:adb forward tcp:8700 jdwp:5657
f. 如果调试过程中,修改了代码。需要使用apktool重新打包,重新安装。之后重复6步骤,开始调试。
g. 调试结束后,建议使用adb forward --remove-all命令,清理端口绑定。
(3) 注意
-
如果先查打开DDMS查看端口,再去设置进程debug,进程的pid会变,此时会出现错误提示:
报错1 -
如果未开启端口转发,则会出现如下错误:
报错2