逆向分析中常用的分析方法有:静态分析、动态调试、HOOK等。动态调试的好处是:1)可以在调试的过程中知道参数或者局部变量的值以及变化过程,2)可以快速履清代码运行的先后顺序,验证自己的想法是否正确。安卓中需要调试的代码有dex中代码和so中代码,对于dex层java代码调试,本人常用的是dex Java代码用JEB调试和IDEA + Smalidea调试,so层代码是用IDA附加调试。下面就这三种方法进行一一介绍。
命令:adb jdwp 用于查看Android手机中可调式的进程。
先安装好JEB,并配置好Java环境。JEB调试并不需要事先将apk转换成smali代码,只需要打开和安装到安卓手机上对应的apk文件即可。不过前提是让想要调试的apk支持被调试,这一点对后面的两种调试方法也是要符合才行。至于怎么支持调试?1)apk的Manifest.xml文件的Application的属性中包含android:debuggable=“true” ;2)或者第一条不满足时,安卓手机的default.prop文件中ro.debuggable=1时也行,mprop工具可用于修改该属性值。用JEB调试时,得把Eclipse和Android Studio关掉,不然会占用adb端口。 做好前期准备后,下面正式进入调试环节: (1)打开JEB,并打开一个apk文件,安卓手机打开相应的应用,并且连接好电脑: 调试时,需要在smali界面才能单步(可以发现在Java代码界面单步是无效的),但是在调试过程中可以随时切换看源码,单步时切回去即可,调试快捷键直接点击debugger查看,不同版本会有些不同。 (2)开始附加调试 点击Debugger——start,然后弹出选择附加进程界面,如下图: (3)查看变量的值 调试时,变量的值都是地址,即使是String类型也是,所以需要将类型转成String,选中类型,然后Ctrl + 输入String,不过很不稳定,很多时候都不成功,查找变量的值在用smalidea + idea调试时很容易观察。
idea直接到官网下载一个社区版(不收费版,够我们调试用了)安装,然后下载smalidea插件(github地址:https://github.com/JesusFreke/smali/wiki/smalidea 下载地址:https://bitbucket.org/JesusFreke/smali/downloads),在IDEA界面中选择:File——Setting——Plugin——Install plugin fromdisk…,选择下载好的smalidea插件,安装即可。 环境配好了,接下来介绍调试的步骤: (1)找到要调试的应用的相应的apk文件,可以是从手机里面导出来,高版本的系统导出来的apk可能是包含odex文件的,或者是vdex文件的,所以遇到时,得需要将这些文件转成包含dex的apk文件。 (2)通过apktool工具将apk反编译成smali文件,然后用IDEA打开smali文件所在的总目录。 (3)初次调试时,需要配置:Run——Edit Configurations,点击左上角+,然后选择remote,然后打开DDMS(ddms工具在安装好Android的Eclipse中会自带,也可网上下载),查看需要调试的包名对应的端口,替换掉8700,保存后,Run——debug unnamed,即能实现调试。 (4)查看变量的值 smali+Idea调试时,查看变量很稳定,如下:
IDA调试so时,可以在打开相应的so文件下调试,也可以在不带so文件的情况下调试,二者都需要附加,常用的是后者,现在直接说明后者的步骤。 (1)启动IDA的调试服务 根据getprop ro.product.cpu.abi,查看CPU型号,我的是armeabi-v7a,所以选择android_server。
adb push android_server /data/local/tmp adb shell chmod 777 /data/local/tmp/android_server adb shell su #:/data/local/tmp/android_server -p3000 之后另一cmd窗口中映射指定的端口: adb forward tcp:3000 tcp:3000上面最后一行中,5566是给服务指定的端口,默认是23946,也可以改成其它的。必须是root权限下执行这个命令,不然调试进程只会显示两个,不是所有的包名对应的进程。 (2) 打开IDA开始附加 IDA一般会有32位和64位,在经验中,64位IDA调试32位的so会出问题,32位的IDA调试64位的so目前没怎么试过,但最好是位数对应好,然后启动相应位数的IDA调试服务。 选择Debugger——Attach——Remote ARMLinux/Android Debugger; 到这里就可以下断点调试了,如下图,一般会把要调试的so用另一个IDA打开,找到代码偏移,然后加上此时调试时模块的首地址就是我们想调试的地址,下断点,然后F9便可。 下断点地址:B3D30000 + 7B04 = B3D37B04 有的时候会调试Jni_Onload这个函数,但是这个函数很早就调用了,用上面的步骤是没法调试到这个函数的,这是可以尝试先用JADB调试启动apk,然后用IDA附加,最后用JADB接管调试。操作步骤如下: (1)在cmd窗口中用:adb shell am start -D -n 包名/Activity名 命令调试启动应用; (2)启动IDA的服务,映射端口; (3)IDA附加进程; (4)jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8700 port可以换成ddsm中查看到的相应报名的端口; (5)之后在IDA中调试同上面非启动调试一样操作了。
(1)JEB和smalidea+IDEA用于安卓Java层调试,二者的各自优点主要如下: 1)JEB调试时方便随时看JAVA代码,不过单步时还得跳回smali代码界面; 2)smalidea+IDEA调试时相对较稳定,并且查看变量比较方便。 (2)IDA主要用于调试安卓的so文件,当然IDA也可用于调试Linux中so和Mac中so,功能是飞航的强大。