安卓|使用ptrace绕过ptrace反调试(二) – 作者:jerrybird

项目地址: https://github.com/chroblert/JC-AntiPtrace

环境:kali2020,ndkr17c,arm64,pixel2,android8.1

一、适用场景

1607928713_5fd70b899022e5c217081.png!small?1607928713467

描述:

  1. zygote通过fork()系统调用,fork出一个app
  2. app内通过ptrace(PTRACE_TRACEME,0,0,0);将父进程zygote做为自己的tracer
  3. 这样其他进程就无法ptrace()到app进程了

二、创建反调试app Demo

  1. demo版app放在GitHub中,app-debug.apk
  2. app运行后查看/proc/<pid>/status中的TracerPid
    • 1607928723_5fd70b93b3c004edc8575.png!small?1607928724194
  3. 使用frida进行调试,可以看到显示报错如下:
    • 1607928730_5fd70b9a4b23cf712ab1a.png!small?1607928730087

注:对于这种很简单的反调试,frida可以用-f进行绕过

1607928745_5fd70ba927570b7772082.png!small?1607928745266

三、绕过ptrace反调试

(一)、思路

  1. (这里主要来自看雪论坛https://bbs.pediy.com/thread-260731.htm)
    • 使用ptrace附加zygote进程
    • 拦截zygote的fork调用,在fork子进程时候获取当前进程名称,判断是不是我们想要的那个应用,若是则保存子进程pid
    • 获取到子进程pid后,再拦截子进程的系统调用,判断此系统调用是不是ptrace,并且参数是PTRACE_TRACEME
    • 拦截到指定系统调用后,修改调用参数,让ptrace(PTRACE_TRACEME);执行失败

(二)、差异:

由于ptrace对底层架构的依赖很高,同一份代码不适用于所有架构的手机,因而原作者给出的代码不适用于我的需求,我这里的是android 8.1,pixel2,arm64

  1. 有些代码需要做一些变换,如下:

ARM32 (AARCH32)

ARM64 (AARCH64)

PTRACE_GETREGS

PTRACE_GETREGSET

pid

pid

NULL

NT_PRSTATUS

struct pt_regs *

{ struct user_pt_regs *ubf, size_t len }

GETREGS

NT_PRSTATUS

PTRACE_SETREGS

PTRACE_SETREGSET

  1. 有些结构体在arm64中的头文件中的声明不一样,也需要重新define,如下:   
#define pt_regs user_pt_regs
#define uregs regs
#define ARM_r0 regs[0]
#define ARM_r7 regs[7]
#define ARM_1r regs[30]
#define ARM_sp sp
#define ARM_pc pc
#define ARM_cpsr pstate
#define NT_PRSTATUS 1
#define NT_foo 1
  1. 关于传参和返回值用的寄存器也有些差异,如下:

arch

syscall NR

return

arg0

arg1

arg2

arg3

arg4

arg5

arm

r7

r0

r0

r1

r2

r3

r4

r5

arm64

x8

x0

x0

x1

x2

x3

x4

x5

x86

eax

eax

ebx

ecx

edx

esi

edi

ebp

x86_64

rax

rax

rdi

rsi

rdx

r10

r8

r9

(三)、实现

代码在GitHub仓库中:[https://github.com/chroblert/JC-AntiPtrace](https://github.com/chroblert/JC-AntiPtrace)

(四)、使用

  1. 查看zygote64的pid
    • 1607928782_5fd70bceae7b0b1376903.png!small?1607928782465
    • 我这里的手机是arm64的,所有用zygote64的pid4979
  2. 执行编译后的JC-AntiPtrace-v1-arm64-1214.o程序
    • ./JC-AntiPtrace-v1-arm64-1214.o -p 4979 -t com.zer0ne_sec.ptrace.jnitest -n 117 -r1 -e
  3. 执行frida附加
  4. 效果如下:
    • 1607928803_5fd70be3c0e12a503d273.png!small?1607928803834
    • 成功拦截并修改ptrace()系统调用的结果,frida成功hook

(五)、使用说明

JC-AntiPtrace-v1-arm64.o [-v] -p <zygote_pid> -t <appname> [-n <syscallNo>] [-r<returnValue> [-e]]
options:
-v : verbose
-p <zygote_pid> : pid of zygote or zygote64
-t <appname> : application name of to hook
-n <syscallno> : syscalll number to hook(十进制)
117:ptrace
220:clone
260:wait
-r<returnValue> : update return value of the syscallno
-h : show helper
-e : detach when updated return value

(1)、用于监控系统调用

JC-AntiPtrace-v1-arm64.o [-v] -p <zygote_pid> -t <appname> [-n <syscallNo>]
-v: 表示显示详细输出,包含有每个系统调用的参数值与返回值
-p: 表示zygote进程的pid
-t: 要监控的app的名称
-n:表示监控某一个特定的系统调用

(2)、用于绕过ptrace反调试

JC-AntiPtrace-v1-arm64.o [-v] -p <zygote_pid> -t <appname> [-n 117] [-r0 [-e]]
-v: 表示显示详细输出,包含有每个系统调用的参数值与返回值
-p: 表示zygote进程的pid
-t: 要监控的app的名称
-n:表示监控某一个特定的系统调用
-r: 表示要修改返回值为某个值。-r后面紧跟数值
-e: 表示修改返回值后就detach

四、总结

本篇文章及代码只是对简单ptrace反调试的一种绕过,仅供研究。之后会继续研究其他ptrace反调试的场景,欢迎关注https://github.com/chroblert/JC-AntiPtrace该项目。

参考资料:[使用ptrace过ptrace反调试](https://bbs.pediy.com/thread-260731.htm)

参考资料:[一种绕过ptrace反调试的方法](https://www.cnblogs.com/gm-201705/p/9864051.html)

参考资料:[ptrace.h](https://sites.uclouvain.be/SystInfo/usr/include/sys/ptrace.h.html)

参考资料:[在Android操作系统中设置永久环境变量](https://blog.csdn.net/Ls4034/article/details/77774330)

参考资料:[Shared Library Injection on Android 8.0](https://fadeevab.com/shared-library-injection-on-android-8/)

参考资料:[NT_PRSTATUS](https://www.man7.org/linux/man-pages/man2/ptrace.2.html)

参考资料:[arm64 vs arm32](https://undo.io/resources/arm64-vs-arm32-whats-different-linux-programmers/)

参考资料:[linux沙箱之ptrace](https://blog.betamao.me/2019/02/02/Linux%E6%B2%99%E7%AE%B1%E4%B9%8Bptrace/)

参考资料:[arm64: ptrace: reload a syscall number after ptrace operations](https://patchwork.kernel.org/project/linux-arm-kernel/patch/[email protected]/)

参考资料:[ptrace change syscall number arm64](https://stackoverflow.com/questions/63620203/ptrace-change-syscall-number-arm64)

参考资料:[linux system call table](https://chromium.googlesource.com/chromiumos/docs/+/master/constants/syscalls.md)

来源:freebuf.com 2020-12-14 15:03:46 by: jerrybird

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论