吾爱破解安卓逆向入门教程(八)--- App动态调试
本帖最后由 世事繁华皆成空 于 2016-6-21 11:35 编辑{:1_911:}快一年没更新教程了,期间实在是蛋疼,介于水平有限,也不知道能教什么,这次就讲讲App动态调试吧
0x0 什么是动态调试
我们常规的拿到一个App,往往是通过AndroidKiller ,Jeb ,Jadx来进行反编译后查看源代码,通过一定的特征追踪到程序关键处,对关键处进行分析或是爆破以达到破解,逆向的目的,
静态分析比较考验一个人的分析能力和代码阅读能力,很多新手可能看到smali代码或是java代码内心是拒绝的,因为不了解程序逻辑,不知道下一步会做些什么,那这时候就需要动态调试了,当然了,动静结合才是王道,此篇教程主要讲动态。
0x1 有哪些动态调试手段
1.Idea对smali代码进行动态调试,Eclipse不管是开发还是调试我都不推荐,实在是落后的很,Android Studio是基于Idea修改而来,所以调试方法一样,还有其他一些,我没用过就不提了,Idea需要安装调试插件SmaliIdea,可以在官网下载到最新版:https://bitbucket.org/JesusFreke/smali/downloads
2.IDA对dex、so动态调试,dex是可以通过静态附加进行来进行动态调试的,但IDA对变量类型支持不太友好,所以能用Idea还是用idea吧,IDA主要用于so调试,脱壳,dump数据等等。
3.JEB动态调试,自jeb2.2以上,已经支持动态调试,并且是无缝调试,可以从java层跟踪到native层,并可以正常返回到java层,非常强大,最新版同时支持了arm64调试,奈何买不起。
4.GDB动态调试,个人对GDB的使用仅限于附加,dump,而GDB的功能远不止于此,下断,跳转等等都能做,个人理解不深,就略过了
0x2 Idea调试smali
由于是入门教程,我就讲的详细点,打开Idiea,长这样
点击Configure中的pluign,之后如下图,找到smaliidea的压缩包文件进行安装
安装完成后需要重新启动程序,找个测试样本,反编译,安利一下自己做的反编译工具箱:http://www.52pojie.cn/thread-429318-1-1.html 。
新建工程,配置一下jdk环境
为了调试方便,请把反编译后的smali文件夹重命名为src,把将工程目录选择为反编译的工程目录
正常的情况应该如下图:
找到Manifest下的启动类,在该类入口出点击左侧栏可以直接下断
之后找到我们需要分析的地方进行下断,我随便找了一处,如下图
之后就需要以debug模式启动App了,通过ApkTool Box可以很轻松的生成
启动后需要打开ddms,或者通过adb shell ps查看进程号,方便起见直接ddms
点击Run ,点击debug,需要配置一下,如下
完成后就可以点击Debug来附加App了,成功后如下
我们直接Ctrl + R让程序恢复运行,程序断在了下一个断点处
比如这里我们需要获取Token值,我们F6单步,顺便说一下,这些调试都是可以把寄存器添加到watch窗口的,这样可以很清楚的看到寄存器的值
看到token值会保存在v2中,我们直接选中v2右键Add to Watches,单步。。。
此处由于是涉及到支付宝登录,出现一些问题,换个app重新来吧,之前步骤略过,这里用了飘云13期教程的例子,本章节也将围绕这个App讲了,
Watches已经显示我们输入的值
调试方法已经教给大家,剩下的就是逻辑分析了,大家自行尝试
0x3 IDA动态调试
IDA动态调试通常有两种,一种直接附加App,另一种是程序运行时,通过IDA将静态分析的文件附加到进程上,通常情况下如果需要刻意分析某个程序中特定so时,则使用第二种方法,脱壳分析时,一般使用第一种
adb forward tcp:23946 tcp:23946
adb shell su -c /data/local/tmp/Android_server
adb shell am start -D -n cn.wq.myandroidtoolspro/cn.wq.myandroidtoolspro.MainActivity
jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8700
adb forward tcp:8700 jdwp:PID
auto fp, dexAddress;
fp = fopen("D:\\classes.dex", "wb");
for ( dexAddress=0x5C9C7000; dexAddress < 0x5C9C7000+0x00566FDC; dexAddress++ )
fputc(Byte(dexAddress), fp);
动态调试通常会使用到这么多指令,转发23946端口,这是andrdoid_server的端口值,以root权限启动android_server监听23946端口,以调试模式启动需要调试的App,转发程序进程的端口到8700
1.直接附加App,这里以调试某壳为例,本章不讲脱壳,脱壳部分会略过,只是讲一个调试的形式
输入上面的指令后,点击Debugger的Attach to Progress就可以看到需要的调试的进程了,如果没有显示进程,请确认android_server文件是否已经被赋予执行权限,并且以root模式启动,jdb附加后就可以正常调试so了
对关键地方下断,就可以对此处寄存器值进行修改,达到反-反调试的目的,处理完这个就可以很轻松的拿到dex
2.静态分析so后附加进程,还是以飘云的例子,反汇编so后找到导出函数
这里因为没有发现java开头的函数,那就知道是动态注册,f5 JNI_Onload函数,发现很混乱,需要导入jni.h处理一下
在Structures标签处按下键盘下的insert按钮点击添加,添加jniEnv和javaVM两个指针,修改后的代码如下
具体操作可以看飘云的视频教程:http://www.52pojie.cn/thread-507566-1-1.html
知道so有反调试后,我们可以尝试静态附加,直接断在Jni_Onload处,下断
选择debugger调试器
成功附加后,选择第二关,即会加载so文件,点击same后来到JNI_Onload处
之间静态看代码时已经看到函数首选会ptrace进程,不去除的话我们将无法调试,直接NOP掉
工具可以在这个帖子中下载:http://www.52pojie.cn/thread-506728-1-1.html
F8运行到此处,直接在16进制窗口填充进去F2即可,
此时程序已经可以正常调试了,剩下的也交给大家自行尝试吧
PS:文章中有几张截图直接引用了视频教程中的过程,{:1_907:}本人在实验过程中遇到ida一些问题
总结:这次的教程主要也是讲个方法,具体的还是得大家自行实践,动态调试往往用于那些代码比较复杂,静态分析困难时会使用到,或者是dump一些重要数据,比如脱壳,dump游戏中的lua文件,等等
说说个人对于反调试的理解,目前主要用到的反调试手段有,检测模拟器,检测IsDebuggerConnected,检测android_server名称,检测android_server端口号,检测tracerpid,检测单步调试时间,子进程ptrace主进程,主进程fork子进程,hook fopen函数等等
除fork,hook fopen外,其余几种一般都可以在ida调试时手动去除,或者是通过写hook 插件去除,或者是直接修改系统源码来去除,:lol看大牛写的hook插件并不困难,可以过滤到大部分反调试,最后记得调试一定要用真机,调试一定要用真机,调试一定要用真机。
繁华大神又发作品了,跟进学习。 启动APP命令提示:
获取命令失败,请确认apk名称及路径不包含中文
这是什么情况? 我是沙发吗... 为什么你们这么熟练的抢沙发,支持繁华大 先评分,有空再学习 不知所云膜拜 想学习.但都没看懂 Hmily 发表于 2016-6-21 11:40
繁华大神又发作品了,跟进学习。
尼玛,入门教程 千年更新一回