以某厨房为例.

反调试函数

(jiagu.so基址5287d000)

在library load/unload断下,在mmap函数尾部下断点,断下后f8执行几句,可找到libjiagu.so:528855E4 BL loc_5288308C,进入反调试.

往下执行的关键跳转有
libjiagu.so:528830D0 BLX LR ; debug079:5287C000
debug079:5287C014 BLX LR ; loc_5288042C
debug079:5287C038 BLX LR ; loc_52880614

5287C000是一个反调试模块的起始.

libjiagu.so:loc_5288042C函数作用是打开status文件获得TracerPid,此函数地址不变 其中的 libjiagu.so:52880528 BL open_0 是调用open打开/proc/self/status的.

loc_52880614是第二种反调试.


具体的反调试过程

解析status文件

找出 TracerPid

转换 TracerPid

比较 TracerPid

如果TracerPid不为0,kill!

解析/proc/net/tcp文件

在比较过tracerid后,接着又解析了tcp文件.

调用处

打开文件

解析

逐行比较是否含有00000000:5D8A,5d8a就是23946,android_server监听端口即为23946,0A状态表示监听.
这里r0会被赋为1,返回调用处时进程就会被kill.

如本机tcp文件中的内容为:

1
2
3
4
5
6
sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
0: 00000000:5D8A 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 42138 1 00000000 100 0 0 10 -1
1: 00000000:15B3 00000000:0000 0A 00000000:00000000 00:00000000 00000000 2000 0 20426 1 00000000 100 0 0 10 -1
2: 0100007F:91AF 0100007F:5D8A 01 00000000:00000000 00:00000000 00000000 2000 0 43283 1 00000000 21 4 2 10 -1
3: ED01A8C0:15B3 EE01A8C0:E1B6 01 00000018:00000000 01:00000018 00000000 2000 0 20427 2 00000000 24 4 28 8 6
4: 0100007F:5D8A 0100007F:91AF 01 00000000:00000000 02:00083C35 00000000 0 0 42634 2 00000000 22 4 3 10 -1

绕过反调试

关键断点是:libjiagu.so:loc_5288042C,返回之后就是cmp.
第二种反调试libjiagu.so:52880614在cmp下面(若有).

断下之后在lr对应的地址下断点,f9,将两个反调试函数下面的比较的r0值修改就可以了.


反调试的patch

但是不止一次反调试,每次的地址也不同,而且每个采用这种加固的app都要如此,这样也太不划算了吧.既然如此,为什么不patch一下呢?

libjiagu.so作如下修改即可去掉反调试:(返回值r0改为0,mov r0,#0)
文件偏移35EC处 -> 04 00 A0 E1改为00 00 A0 E3
文件偏移3720处 -> 01 00 A0 E3改为00 00 A0 E3


本文小白鼠: here

Reference

xxx加固 之 动态脱壳