修改Android内核输出syscall某些调用日志
想要使用Seccomp
来查看某个apk的syscall日志, 发现apk本身有反Seccomp
机制, 设置PR_SET_NO_NEW_PRIVS
就闪退了.后续更无法使用 prctl PR_SET_SECCOMP, SECCOMP_MODE_FILTER
只好从内核层直接输入日志.
烧录内核的步骤主要参考:
https://blog.lleavesg.top/article/pixel5-kernel-build
https://github.com/zhanghecn/luckzh_android_flash_notes/blob/main/doc/note3-kernel/index.md
可以成功烧录内核. 主要的注意点就是: 解压原始boot.img的得到的boot.img-ramdisk.cpio.lz4 并将其放入android-kernel目录中. 再打包重新烧录 boot.img 和vendor_boot.img两个分区即可.
1.取消PR_SET_NO_NEW_PRIVS
设置后status状态值
这个修改比较简单,把文件fs/proc/array.c 里设置NoNewPrivs写死0即可.
1 | static inline void task_seccomp(struct seq_file *m, struct task_struct *p) |
编译烧录之后,开启PR_SET_NO_NEW_PRIVS
,apk就检测不到状态了. 但是设置了PR_SET_SECCOMP
仍然闪退. 因此需要在kernel里分析是调用了哪些syscall之后退出,就可以反推出检测逻辑.
2.增加syscall日志
kernel的syscall调用非常频繁,如果不过滤直接开printk, 日志就太多了. 因此只能过滤一下我们关心的.
安卓为每个apk分配了一个user,按照userid来过滤是个很好的方案. 查询到apk的userid之后,设置过滤如下即可只过滤当前apk的日志.
比如openat时加入日志:
1 | long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode) |
其他的系统调用可以按照类似修改.
3.增加userid可修改.
apk不卸载重装,userid是不会变的, 但是写死userid到代码里总不是一个好的方案. 因此需要userid能在应用层指定.
因此GPT给出的方案是使用debugfs来增加一个文件, 使用adb 可以写入这个userid值, kenrel检测到修改后更新这个userid.
基本代码如下:
1 | int DEBUG_USER_APP_USERID =0; |
为了简单,没必要单独写驱动, 可以放到kernel/configs.c 文件里,本身这个模块功能简单,不到一百行代码.
修改监控userid的方法也简单了.
1 | redfin:/sys/kernel/debug/my_debug # echo 10144 > debug_user_app_userid |