开篇
之前工作内容不涉及安卓调试,所以对安卓的测试并不了解。但是最近工作关于安卓的调试越来越多,需要用到动态调试技术,刚好这里就整理下最近所了解到关于安卓动态调试的测试方法。
动态调试的主要的几种方式
1.Android Studio对smali代码进行动态调试,AS工具动态调试smail代码需要安装smalidea工具。
2.Eclipse对java代码进行动态调试,Eclipse不能识别smali代码,所以需要将smali代码转换成java代码进行调试,之前学习说Eclipse不太方便,但是现在在做的项目会方便很多,看来世间无觉得。
3.IDA pro对dex,so的动态调试,dex是可以通过静态附加来进行动态调试的,但是IDA pro对变量类型支持不太友好,所以能用idea还是idea吧,IDA pro主要用于so调试,脱壳,dump数据等
4.JEB动态调试,自从JEB2.2开始已经支持动态调试,并且是无缝调试,可以从java层跟踪到native层,并可以正常返回到java层,非常强大,最新版本同时支持了amd64调试,只是买不起。
5.GDB动态调试,本人暂时对这个没啥研究,略过。
本篇主要记录前面3种动态调试方法,记录方式流程,方便自己查阅
Smalidea+AndroidStudio动态调试安卓APP
既然我们要用AndroidStudio动态调试smali代码,第一步就是将apk反编译成smali文件然后到入AndroidStudio中。将apk反编译成smali文件 我这里使用的Android crack tool,也可以使用其他反编译工具。
直接将apk文件拖入工具中,点击反编译apk,然后点击执行,查看当前目录下就得到了smali文件夹
接着就可以将反编译出来文文件导入AndroidStudio中,
File---New--Import Project.
然后将smali文件夹设置成Sources Root
之前说AndroidStudio不支持直接调试smali代码,所有还需要安装ideasmali插件。可以百度搜索下载,这里需要将插件导入到AS中。这里选择从硬盘中安装插件,然后重启AS,环境安装就基本完成了。
开始调试
打开AndroidMainfest.xml首先将android:debugganble的值修改为true,不然的话没法进行调试,现在调试的这个例子中默认是有这句代码的,有的apk中没有这句代码要自行添加上。然后需要记住包名和入口的Activity名。图中都已经圈起来了。
用数据线连接手机,并将要调试的apk安装到手机上,手机需要开启USB调试模式。
安装apk 可以使用命令
adb install xxx.apk
安装完成后,可以使用命令行
adb shell am start -D -n packagename/android:name
[am命令参考](https://blog.csdn.net/xiezechang/article/details/8528446)对apk进行动态调试,这条命令运行后屏幕将会进入到调试模式(如果手机没有进入到调试模式的话可能是手机USB没有连接上,活着USB调试模式没有打开,或者是其他原因)
等待调试,然后在AndroidStudio中添加配置。
run-edit-configurations中添加配置 点击+选择remote填写name选择本地端口
然后通过adb shell 查看运行的程序在哪个端口,然后进行端口转发
adb forword tcp:8700 jdwp:4597
配置好JDK,在Project Structure选择合适版本的jdk
在smali代码中下好断点,就能在程序运行到这个地方的时候断下来
这里设置的断点在输入用户名和密码的位置,当程序运行到输入用户名密码时,点击登陆城西会自动停在这一步
可以看到watches中的寄存器的值,可以点击修改参数,点击下一步既可以进行尝试,可以尝试在更多的地方下断点,用以分析程序的逻辑。
使用eclipse进行动态调试
背景介绍
整个项目的需求是这样的,项目对整个APP都进行了数据包加密,直接抓包只能看见加密后的报文,而我们的工作就是对这个APP进行渗透测试,所以想法就是我们需要将断点下在加密函数之前,这样就可以看到没加密的报文,然后对报文数据进行修改测试。
加密后的数据包如图:
调试前准备
和上面调试方法一样application标签中需要含有android:debuggable="true"这句代码,没有这句代码是不鞥调试apk的。现在调试的这个例子默认是有这句代码的,有的apk中没有这句代码要自行添加上,还有在入口点的类的onCreate中添加如下代码等待调试如waitForDebuggable()函数这些操作,是做任何调试都需要的。
我们都知道Eclipse调试的是java代码,但是apktool反编译出来的代码是smali代码,而不是java代码,那我们如何才能得到java代码呢?apktool的d操作有哥-d参数,是debug,也就是说反编译出来的代码是做调试用的,加上-d参数后反编译出来的代码就能被eclipse识别,具体的命令
java -jar apktool.jar d -d xxx.apk
(这里生成一个文件)
正常反编译出来的文件
加-d后的反编译过程
加-d后反编译出来的文件
这里虽然变成了java文件,但是内容还是和smali文件一样的
改完重新打包也要加-d参数
java -jar apktool.jar b -d /apk;
(这里会重新生成一个apk文件),在签名后才能正常安装。
开始调试
1.导入工程
2.下断点
假设我们事先知道加密函数的位置,断点下在加密函数之前
3.连接手机
把需要调试的apk安装到测试手机中,并用数据线连接手机,打开USB调试模式。
4.启动应用
这里可以看到应用有个红色的小虫子的标志,这里带包此应用可以被调试;
因为在入口处设置了waitForDebuggable()函数,所以在启动的时候会进入调试模式。
调试应用
回到eclipse,找到小虫子的图标,进入Debug Configuration。
双击进入Remote Java Application Project记得要设置成当前应调试的项目
其中connect有两种连接方式一种是Listner,另外一种是Attach方式,这里简单介绍下这两种连接方式
Listner方式:是调试客户端启动就准备好一个端口,当调试服务端准备好了就直接连接这个端口进行调试
Attach方式:是调试服务端启动就准备好一个端口,当调试客户端来连接这个端口。
我们在该配置中选择Attach。然后我们设置Host和port Host因为是本地调试,所以我们设置成localhost,port的话要看
这里还有JDWP县城,可以看到上图的8631的这个数字,当前应用使用的就是这个端口,点一下就可以看到8631/8700,所以也可以设置8700为调试端口。如果系统同时存在两个或者两个以上的调试程序的话,设置8700就不知道调试哪个端口了。设置完成后,就可以开始调试应用了
结语
针对加密的情况因为断点下在了加密函数运行之前,所以我们能在拦截的参数中看到没有加密的参数,eclipse中支持参数修改,这是我们修改参数,运行。查看返回的数据包是同样的,在返回的数据包,也即是return中下断点,就能看到从服务端反回来的没有加密的数据。这次的调试是在已知加密点的情况下进行。