0x00 前言
动态调试是比静态分析更为高效地一种破解手段。因此在破解安卓应用之前,一般会先对应用进行动态调试,了解应用大致运行流程和各个类之间的逻辑关系。
反动态调试可以从以下两个个方向着手:
1.运行环境检测:检测应用的运行环境是否安全,是否可能存在被调试的风险
2.动态调试指令检测:检测应用的运行过程中是否受到动态调试指令的控制
本文完全参考自网友 爱吃菠菜 的反调试总结,由于我的资料是pdf文档,已经找不到出处,在此对网友 爱吃菠菜 说一声抱歉。
0x01 运行环境检测
1.调试端口检测
不同调试器默认使用不同的调试端口,且这些端口默认值往往不被修改。
2.调试器进程检测
不同调试器会在系统中创建不同进程对应用进行劫持以达到动态调试目的。
3.父进程名检测
针对so文件,破解者可以自己编写一个APK对so库进行调试。
4.自身进程名检测
原理同上条。正常的APK进程名一般为入口类的目录。形如:com.xxx.xxx.xxxx.xxxMainActivity。在开发时,该值是已知的,因此可对该值进行检测。
5.apk线程检测
正常APK运行时一般会有多个线程在运行,可以在开发阶段分析自己的源码,正常运行时至少会有多少线程同时运行。针对如果破解者仍是自己编写APK调用so库调试分析的情况,此时的APK中一般只有一条线程。
6.apk进程fd文件检测
分析系统中/ proc/pid/fd路径下的文件差异进行判断。
1)APK本身启动的进程和非APK启动的进程,fd数量不一样
7.安卓系统自带的动态调试检测函数
8.tracepid
/proc/pid/status文件中有一个tracepid字段,若进程被调试,则tracepid值不为0,否则为0。可以对该值进行检测以判断该进程是否被调试。
可以将statue字段写为t,停止调试
10.stat
如果是被调试状态,则
/proc/pid/stat
/proc/pid/task/pid/stat
第二个字段是t(T)
11.wchan
/proc/pid/wchan
/proc/pid/task/pid/wchan
ptrace_stop
12.ptrace
每个进程同一时刻只能被一个进程ptrace。
可以主动ptrace自己,让别的进程无法对自己ptrace;也可以写多个进程,让其互相之间ptrace以免被调试器ptrace
13.代码执行时间间隔检测
在两段不同代码处插入时间函数,获取当前时间。对两个时间差进行检测,如果差值过大,则说明两段代码运行时间间隔过长,可能是被单步调试。
14.mem、pagemap监测
0x02 动态调试中检测
1.断点指令检测
2.函数hash值检测
so文件中函数的指令是固定,但是如果被下了软件断点,指令就会发生改变(断点地址被改写为bkpt断点指令),可以计算内存中一段指令的hash值进行校验,检测函数是否被修改或被下断点。
3.单步调试陷阱
4.利用IDA先截获信号的特性进行检测
5.利用IDA解析缺陷攻击IDA调试器
IDA调试器原理:IDA采用递归下降算法来反汇编指令,而该算法最大的缺点在于它无法处理间接代码路径,无法识别动态算出来的跳转。而arm架构下由于存在arm和thumb指令集,就涉及到指令集切换,IDA在某些情况下无法智能识别arm和thumb指令,进一步导致无法进行伪代码还原。