初试反调试

理论知识不是很多,很多操作,记录一下,样本是AliCrackme_2.apk

反调试中有一个方法是循环检查进程的status字段,如果进程被ptrace后,其TracerPid为ptrace进程的pid

1
2
3
4
5
6
7
8
9
10
11
root@hammerhead:/ # cat /proc/7063/status
Name: llux.smalilearn
State: t (tracing stop)
Tgid: 7063
Pid: 7063
PPid: 757
TracerPid: 7099
......

root@hammerhead:/ # ps |grep 7099
root 7099 7094 16964 11840 ffffffff b6efe854 S ./android_server

1、添加android:debuggable = “true”

修改AndroidManifest.xml在manifest标签下加上android:debuggable = "true",否则在用jdb附加进程时会报错,附加不上进程。

重新打包:

1
java -jar signapk.jar testkey.x509.pem testkey.pk8 AliCrackme_2.apk AliCrackme_2.sig.apk

2、使用am命令以debug方式启动程序,此时程序处于等待被附加状态

1
adb shell am start -D -n com.yaotong.crackme/.MainActivity

3、在安卓端启动android_server,程序在安装目录的dbgsrv文件夹下

4、为IDA设置端口转发

1
adb forward tcp:23946 tcp:23946

5、IDA附加进程,并设置加载库的断点

image-20191202160324614

6、打开ddms,使用jdb附加进程

8700是ddms开启的端口转发

1
jdb -attach 127.0.0.1:8700

返回IDA,运行程序,程序就会断在linker.so中,linker是用于加载so文件的模块
image-20191202161144065

双开IDA,计算JNI_Onload函数的地址,到该处下断,单步到BLX R7时退出JNI_Onload函数

image-20191202161354035

R7的值为pthread_create,回看so的伪代码,可以猜测程序开启新线程去循环查询TracerPid的值是否为0,定位到BLX R7的偏移为1C58,选中该行指令,CTRL+ALT+K将其patch为空指令

image-20191202163955073

ARM指令集中的NOP(0xe1a00000)是一条伪指令,编译系统用一条MOV r0, r0, lsl #0(0xe1a00000)指令替代其执行,设为ANDEQ r0,r0,r0,即可生成空指令

保存后,重新打包签名,IDA可以正常调试了