eStrace - 使用eBPF追踪系统调用

2023-06-14
#ebpf #android

Android逆向时经常需要通过hook系统调用观察程序的行为,但使用seccomp很容易被目标程序检测。而eBPF是内核层面hook,用户态程序不可能能感知到,用于逆向时行为分析再合适不过了。在此之前也已经有教程教如何使用eBPF hook所有系统调用:60秒学会用eBPF-BCC hook系统调用 ( 2 ) hook安卓所有syscall。但是读下来发现,需要配置bcc环境、编写python代码,十分麻烦(我不相信真的60秒能学会)。

而我使用rust的aya框架,可以直接编译成一个单独的可执行程序,直接运行就可以hook所有系统调用了。同时借鉴了strace以及lurk等项目,将syscall执行以行日志形式输出,便于分析。

项目地址ri-char/eStrace

如何使用

Release中下载对应平台的二进制,直接运行即可。真的仅需60秒!

效果图:

原理

在eBPF中,使用TracePoint,分别挂载了两个函数在raw_syscalls/sys_enterraw_syscalls/sys_exit上,可以获取所有系统调用的事件。然后需要一张表来记录每一个系统调用有几个参数,每个参数的类型和名称,如果参数是指针的话,还需要记录指针指向结构体的大小,解引用的时机(有些指针作为系统调用的返回值)。详见:/ri-char/eStrace/cli/src/syscall_info/mod.rs

syscall!(read, fd = INT, buf = output_struct_ref(2), count = INT; ["DESC"]);
syscall!(write, fd = INT, buf = input_struct_ref(6), count = INT; ["DESC"]);
syscall!(open, filename = STR, flags = INT, flags = INT; ["DESC", "FILE"]);
syscall!(close, fd = INT; ["DESC"]);
syscall!(stat, filename=STR, statbuf = output_struct(sizeof!(stat)); ["FILE", "STAT", "STAT_LIKE"]);
syscall!(fstat, fd = INT, statbuf = output_struct(sizeof!(stat)); ["DESC", "FSTAT", "STAT_LIKE"]);
...

有了这样一张表,每个系统调用就去查表,将数据通过PerfEventArray传回用户态程序。用户态程序解析并将日志输出。

ToDo

  1. 上面这张系统调用的信息表可能存在错误
  2. 更加完整的过滤机制
  3. 参数结构体解析