安卓逆向之反调试技术

1,220 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。


截屏2021-10-13 上午11.33.06.png 只有知道了反调试是怎么实现的才能更好的过反调试,调试在代码保护中扮演着很重要的角色,虽然不能完全阻止攻击者,但是还是能加大攻击者的时间成本,一般与加壳结合使用,核心还是加壳部分。

反调试可以分为两类:一类是检测,另一类是攻击,前者是去想各种办法去检测程序是否在被调试,如果正在被调试的话做出一些“反”的举措,比如退出等等,这种一般最为常见,其越过方法就是,找到代码检测的位置,通过frida进行hook,修改其返回值即可,这里先介绍下,常见的反调试技术。

三种反调试技术:Self-Debugging 反调试、轮训检测反调试和Java层反调试

Self-Debugging 反调试

Self-Debugging 是指父进程创建一个子进程,并用子进程调试父进程的技术。

通过ptrace函数实现,一个进程被调试时,只有两个状态:运行和暂停。

暂停状态又分为以下几种:

1.signal-delivery-stop状态

当一个进程收到除SIGKILL外的信号时,内核将选择进程内的任意一个线程处理这个信号,

如果被选择的线程正在被调试,则这个线程进入了此状态(线程进入暂停状态,调试器使用Waitpid函数等待这个事件,并取得这个信号)。此时,进程并没有真的收到这个信号,而且这个信号可以被调试器丢弃,导致进程永远无法收到这个信号。

2.group-stop状态

3.syscal-stop和ptrace-event-stop状态

轮询检测反调试

实现原理

读取进程的/proc/{pid}/status文件,通过该文件得到调试当前进程的调试器。

status文件的字段信息解释如下:

Name:进程名

State:表示进程的状态

Tgid:线程组ID,一般指进程名

Pid:线程ID,他的值和gettid函数的返回值相等

PPid:父进程的进程id

TracerPid:实现调试功能的进程ID,值为0表示当前进程未被检测。

方案实现

通过检测status文件内的Tracerpid字段的值判断当前进程或线程是否正在被调试。

java层反调试

在androidManifest.xml文件的Application标签中设置android:debuggable的属性为false即可。