安卓动态调试与反反调试
通过一道题目学习安卓的动态调试与反反调试。
- 2015阿里&看雪移动安全挑战赛-第二题 https://blog.csdn.net/scoronepion/article/details/51340137
- https://mp.weixin.qq.com/s/--EF_0X-FV9apmNPMWpCfg
工具:jadx、ida、雷电模拟器
启动雷电模拟器,安装程序。
adb install ./AliCrackme_2.apk
拿到AliCrackme_2.apk,首先jadx反编译一波,查看MainActivity类,程序在native方法securityCheck()进行验证。
找到加载的动态链接库,对应的文件即是libcrackme.so。
解压apk,把AliCrackme_2\lib\armeabi\libcrackme.so拖进ida,静态调试。
找到Java_com_yaotong_crackme_MainActivity_securityCheck,这个函数就是MainActivity类声明的native方法。
F5反编译,分析代码,关键部分如下:
对应的汇编代码:
作用:输入的字符串与off_B5F628Cb比较,相等则返回1。
查看off_B5F628Cb的值
flag到手?
验证失败,说明寄存器的值在程序运行时会发生动态改变。使用动态调试看看程序运行时发生了什么。
动态调试
安卓开启监听
首先查看手机的cpu架构
adb shell uname -a
到ida dbgsrv目录下把对应cpu架构的远程调试服务器上传到模拟器
adb push .\android_server64 /data/local/tmp/
给权限
adb shell
cd /data/local/tmp
chmod 777 *
启动远程调试,指定监听端口
.\android_server64 -p1314
手机没有联网,无法使用ip访问,将安卓本地端口映射到远程(windows本机)端口
开启另一个终端
adb forward tcp:1314 tcp:1314
在ida连接到远程调试服务器,apk运行时进行连接
attach到apk运行的进程
**这里有个小坑,受到SElinux的限制,只有root用户才能查看所有进程。所以远程调试服务器要以root身份执行,否则可供attach选择的进程只有寥寥几个,而且还不包括运行着的apk。
找到libcrackme.so,进入Java_com_yaotong_crackme_MainActivity_securityCheck函数入口,F2下断点
F9运行,程序奔溃。
大概是程序做了反调试保护。
反反调试
一般情况下反调试的机制
这是使用ida对程序进行动态调试时,程序进程的状态,可以看到TracePid为3537。
反调试保护时开启一个线程,检测TracePid是否为0,如果不为0,就认为程序处于调试状态,这个程序采取的处理措施是闪退!!
找出检测tracepid的线程并挂起,即可绕过反调试
找不到线程就需要阅读大量的代码了,看看大佬怎么做的(看不懂):https://bbs.kanxue.com/thread-258595.html
可以看到此时程序没有闪退,函数顺利执行。
如何跳到函数关键代码(静态调试与动态调试相结合)
如何跳到函数关键代码?即静态调试时进行比较的部分:
静态调试时,.so文件的基址地址是0x00000000,所以这里的地址不是程序运行时真正的内存地址。
使用动态调试.so文件的基址替换掉静态调试的基址,即可知道关键代码的真实地址0x0B5F12B0。
jump到0x0B5F12B0,得到寄存器在运行时的值。拿到flag。
总结
这道题的代码阅读量不大,主要用来学习动态调试和反反调试技术,也对native函数声明、动态注册、调用的过程更加清晰。人肉过反调试那篇文章以后得看(C水平不够)。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步