上一次调试各种手抖F9跳过了许多关键内容,这次继续。
case31分支
case31分支中每一次设置的LR寄存器地址都不一样,反调试验证等手段大都在这里进行跳转。
1:
验证加载的so文件是不是libjiaguXXX.so
单步跟,一直到case32中进入函数sub_75CEA9FC里发现处理结果的分支:
R4跳转为raise函数,向进程自己发送SIGKILL(9)信号来终止进程。但是我们这里加载的是正确的so文件,tst指令结果为0,跳过了这里。
2:
获取时间戳,猜测是获取执行时间差来判断是不是被调试了,那就让time()返回0就好了
3:重调用外围函数_Z10__arm_a_21v
4、5:memcpy
6:解密字符串
sub_75CEBF2C,说明前面从so文件某处拷贝加密的字符串,在这里解密。
解密函数在后面还有多次用到:
BYTE * sub_75CEBF2C(BYTE *result, int a2)
{
int v2; // r2
if ( a2 )
{
v2 = (int)&result[a2];
do
{
*result = ~(*result ^ 0x5A);
++result;
}
while ( result != (BYTE *)v2 );
}
return result;
}
/system/bin/linker里有什么东西呢- -,在模块里找到了它
上次没搞懂,这次找到了这个rtld_db_dlactivity
rtld_db_dlactivity函数默认情况下为空函数,当有调试器时将被改为断点指令。Android反调试对抗中,SIGTRAP信号反调试可通过判断该函数的数值来判断是否处于被调试状态等,所以必要时需要将该函数对应的寄存器的值修改为0。
7:
解密字符串rtld_db_dlactivity
8:遍历符号表获取rtld_db_dlactivity地址
打开maps文件寻找/system/bin/linker模块,找到rtld_db_dlactivity。
把DE 10修改为nop指令 C0 46或者00 00(0xDE10为thumb breakpoint)
9:读取rtld_db_dlactivity
sub_75CE73E4函数读取文件内容
此时该地址在上一步已经被手动修改为00
单步跟踪,到case32 - sub_75CEA9FC,又是熟悉的分支,此时R4为__stack_chk_fail,不过我们验证通过了。
10、11: _Z10__arm_a_20v函数TracerPid反调试
上一篇中有提到过,这里手动修改TracerPid为0
12:getpid,后续操作没有跟出来。。
在这里判断,R1&0x40000000!=0,会跳转到R4,修改为0
case40,Debugger: thread 406 has exited (code 0)!
重开这次不修改上一步中的R1,r4为:
随后再次进入case31:sub_75CEDCE4。
跳过了退出,再次进入case31,sub_75CEDD20:解密了一些函数名字符串
跟了不知道多少次BLX LR跳转到了这里sub_75CE7C84:
通过uncompress函数解压libz.so文件并解密找到对应的JNI_Onload函数,主要作用就是动态注册那些被native的函数。
至此全部反调试都应该没了,一直下断点跟踪调试。
…
在内存中找到最新的区段,dump出来。