0x00 本文参考
本文主要是参考Anti-Debugging Skills In APK ,请读者先阅读此文,本文只是对其中的难点进行讲解和说明。
0x01 ida调试so原理
要理解反调试原理,首先要理解调试原理。有关如何使用ida调试so,请参考ida动态调试so,在init_array和JNI_ONLOAD处下断点。
几个关键的步骤,说明下原理:
1.1 在手机端运行android_server
启动server在手机端监听23946端口。
1.2 端口转发,adb forward tcp:23946 tcp:23946
使电脑端可以通过端口23946和手机端通信。
1.3 以debug模式启动被调试进程
adb shell am start -D -n com.example.ndkreverse/.MainActivity
1.4 ida列出所有进程
之所以可以列举出所有进程,是因为电脑端请求android_server返回的所有进程名。
1.5 ida attach 被调试的进程
电脑端于手机端android_server通信,使android_server ptrace到目标进程,我们可以查看目标进程的TracePid,就是android_server的进程号。
1.6 使debug模式的应用程序继续运行
jdb -connect com.sun.jdi.SocketAttach:port=8700,hostname=localhost
1.7 ida 设置断点
ida通知手机端,首先保存原汇编代码,之后替换为breakpoint命令,当程序执行到此时,产生SIGTRAP信号,SIGTRAP信号被android_server捕获,首先用刚保存的原汇编代码替换breakpoint指令,好让程序继续执行,然后把现在的寄存器状态通过端口转发,传递给ida。
0x02 理解Anti-Debugging Skills In APK 第四点用Signal来反调试
刚刚在ida调试so原理时,1.7中已经说了ida设置断点的原理。
如果我们在代码中主动加入breakpoint指令,执行到这行汇编代码时,会产生SIGTRAP信号,在非调试的状态下,我们定义了SIGTRAP信号处理函数,在信号处理函数中,我们把breakpoint指令替换为正确的指令,然程序正常运行。
如果处于调试状态,我们自定义的信号处理函数捕获不到SIGTRAP,因为android_server会捕获SIGTRAP信号。会将刚保存的原汇编代码替换为breakpoint指令,而原来的指令就是breakpoint指令,这样继续运行还是breakpoint指令,出现死循环。达到反调试的目的。