FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

binder-trace/kernel at master · CKAndroidProject/binder-trace · GitHub

Latest commit

 

History

History
 
 

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 

README.md

binder-trace 内核模块

这个目录存放 binder-trace 的 Android out-of-tree 内核模块后端。

当前 hook

模块加载时会通过 kallsyms_lookup_name 解析 Binder 相关符号,然后安装 ARM64 inline hook:

  • binder_ioctl:必需 hook,用来拿到 filp、cmd、arg。
  • binder_alloc_copy_user_to_buffer:必需 hook,用来拿到 Binder 写入用户态缓冲区前的入口参数。
  • binder_transaction:可选 hook。这个函数是 static,部分内核不会出现在 kallsyms 里,解析失败时模块会跳过它。

跨版本策略:hook 层默认只读取函数入口参数。为了把 reply 关联到对应 send,binder_transaction hook 额外 best-effort 读取 Android common 5.10-6.12/mainline 中相对稳定的最小私有字段:binder_thread.transaction_stack 和 binder_transaction.debug_id。这些字段不是 UAPI;读取不到或布局不匹配时事件中的 debug id 为 0,用户态应降级为 unmatched。

控制面 IPC

当前控制面采用自定义 socket 协议族,不创建 /dev 节点。模块加载时从 AF_DECnet 开始动态寻找空闲协议族并注册,只允许 root 且具备 CAP_SYS_ADMIN 的进程创建 SOCK_RAW 控制 socket。

连接流程:

  1. 用户态从 AF_DECnet 开始扫描协议族。
  2. 先用 SOCK_STREAM 探测;如果内核返回 ENOKEY,说明该 family 像 binder-trace 控制协议族。
  3. 再用同一个 family 创建 SOCK_RAW。
  4. 通过 BT_IOC_GET_FEATURE 获取驱动特征,只有 magic == BTRACE01 才认为这是 binder-trace。
  5. 特征匹配后再检查 ABI 版本并发送控制命令。

支持的控制命令定义在 src/ipc/bt_ipc_uapi.h:

  • BT_IOC_GET_ABI_VERSION
  • BT_IOC_SET_CONFIG
  • BT_IOC_GET_CONFIG
  • BT_IOC_GET_STATS
  • BT_IOC_CLEAR_STATS
  • BT_IOC_GET_FEATURE

自定义协议族同时承载低频控制面和当前阶段的事件流:ioctl 负责开启/关闭捕获、基础过滤和统计读取,recvmsg/poll/epoll 负责读取内核推送的固定布局 Binder 事件。事件结构当前为 ABI v3,包含当前任务身份、binder_transaction() 入口指针、transaction code、data/offsets 大小、目标 handle、发送方 pid/euid、reply 关联 debug id,以及发送方用户态 Parcel 的前 256 字节。

版本来源

已经对照过的 Android common 源码:

binder_alloc_copy_user_to_buffer 位于对应分支的 drivers/android/binder_alloc.c。5.10/5.15 内部使用 kmap(),6.1/6.6/6.12 内部使用 kmap_local_page(),但函数签名保持一致。

Android common 当前没有标准 android*-5.19* ACK/GKI 分支;如果后续遇到厂商 5.19 内核,需要拿厂商源码里的 drivers/android/binder.c 和 drivers/android/binder_alloc.c 单独对照。

构建

kernel/scripts/build-ddk.sh build android14-6.1

在 DDK devcontainer 里可以直接使用内核源码环境:

source kernel/envsetup.sh
make -C kernel

部署

kernel/scripts/insmod_ko.sh

默认 inline hook 的 backup trampoline 使用 BR X17 跳回原函数,并临时清理 相关 hooked text 页的 PTE_GP,避免 BTI 拒绝跳入函数内部地址。需要保留 BTI guarded 页属性时,可以加载模块时设置 preserve_bti=1;此时回跳改用 RET X17 保守策略。

kernel/scripts/insmod_ko.sh preserve_bti=1

支持使用 rmmod bt_kmod 卸载。卸载时模块会先设置 draining 标记,停止新 采集,恢复 Binder hook 入口,然后阻塞等待已经进入 hook 的调用退出,最后 释放 trampoline 和控制面资源。因为模块会 hook binder_ioctl(),而 binder_ioctl() 可能在 Binder read/looper 路径里长时间阻塞,所以 rmmod 可能等待较久;这是为了避免卸载后返回到已经释放的模块代码。


Back | FazBrowse Home | New Git URL