aios_collector/binder_probe.rs
1//! Binder eBPF 探针 — 跨进程通信监控
2//!
3//! "how" — 如何通过 eBPF tracepoint 监控 Android Binder 事务。
4//!
5//! Binder 是 Android 的核心 IPC 机制。所有系统服务调用
6//! (通知、Activity 启动、窗口管理) 都是 Binder 事务。
7//!
8//! eBPF tracepoint: `tracepoint/binder/binder_transaction`
9//! 提供: source_pid, target_pid, target_node (服务名), 事务类型。
10//!
11//! ## 实现状态
12//!
13//! 本模块提供完整的接口定义和 Linux 端实现 stubs。
14//! Android 真机部署需要:
15//! 1. 自编译内核 (CONFIG_BPF_SYSCALL=y, CONFIG_DEBUG_INFO_BTF=y)
16//! 2. 或 root 权限 (加载预编译的 BPF 程序)
17//! 3. Daemon 以 system 身份运行 (SELinux 允许 bpf)
18
19use aios_spec::BinderTxEvent;
20
21/// Binder 探针 — 订阅 Binder 事务事件
22pub struct BinderProbe {
23 /// 是否已初始化 eBPF 程序
24 initialized: bool,
25}
26
27/// 从 eBPF tracepoint 解析出的 Binder 事务
28#[derive(Debug, Clone)]
29pub struct BinderTransaction {
30 pub timestamp_ms: i64,
31 pub source_pid: u32,
32 pub source_uid: u32,
33 /// 目标服务名 (从 Binder node 名称解析)
34 /// 例如: "notification", "activity", "package"
35 pub target_service: String,
36 /// 目标方法 (从 Binder 事务 code 推断)
37 /// 例如: "enqueueNotificationWithTag" (code 5 in INotificationManager)
38 pub target_method: String,
39 /// 事务是否为 oneway (不需要返回值)
40 pub is_oneway: bool,
41 /// Parcel 数据大小 (bytes)
42 pub payload_size: u32,
43}
44
45impl BinderProbe {
46 /// 创建新的 Binder 探针
47 ///
48 /// 在 Linux 上: 返回一个标记为未初始化的实例。
49 /// 在 Android (root/system daemon) 上: 加载 BPF 程序并 attach 到 tracepoint。
50 pub fn new() -> Self {
51 // Linux 上 eBPF 需要特定内核版本和权限
52 // 我们返回一个未初始化的探针, 调用 poll() 时返回空
53 Self { initialized: false }
54 }
55
56 /// 尝试初始化 eBPF 程序
57 ///
58 /// 返回 Ok(true) 表示 BPF 程序已加载并 attach。
59 /// 返回 Ok(false) 表示当前平台不支持 (Linux 桌面 / 无权限)。
60 pub fn try_init(&mut self) -> Result<bool, ProbeError> {
61 // 检查是否有 /sys/kernel/debug/tracing/events/binder/ 目录
62 // 这是 Binder tracepoint 存在的标志
63 let binder_trace = std::path::Path::new(
64 "/sys/kernel/debug/tracing/events/binder/binder_transaction/enable",
65 );
66
67 if binder_trace.exists() {
68 // Android (有 Binder tracepoint) — 可以加载 eBPF
69 // 实际实现需要:
70 // 1. 编译 BPF 程序到 ELF (使用 aya 或 libbpf-rs)
71 // 2. 加载 BPF 程序 (调用 bpf() syscall)
72 // 3. Attach 到 tracepoint/binder/binder_transaction
73 // 4. 通过 perf buffer 或 ring buffer 读取事件
74 self.initialized = true;
75 tracing::info!("Binder tracepoint detected, probe initialized");
76 Ok(true)
77 } else {
78 // Linux 桌面 / 不支持的环境
79 tracing::warn!("Binder tracepoint not available — probe will return no events");
80 Ok(false)
81 }
82 }
83
84 /// 轮询 Binder 事件
85 ///
86 /// 返回自上次 poll 以来的所有新事务。
87 /// 在 Linux 桌面环境下始终返回空。
88 pub fn poll(&self) -> Vec<BinderTransaction> {
89 if !self.initialized {
90 return Vec::new();
91 }
92
93 // 从 eBPF perf buffer 读取事件
94 // 使用 aya::maps::perf::PerfBuffer 或 libbpf-rs::RingBuffer
95 //
96 // 伪代码:
97 // let events = self.bpf_map.read_events();
98 // events.into_iter().map(parse_binder_event).collect()
99
100 Vec::new()
101 }
102}
103
104impl Default for BinderProbe {
105 fn default() -> Self {
106 Self::new()
107 }
108}
109
110impl BinderTransaction {
111 /// 转换为 aios-spec 的 BinderTxEvent
112 pub fn to_event(&self) -> BinderTxEvent {
113 BinderTxEvent {
114 timestamp_ms: self.timestamp_ms,
115 source_pid: self.source_pid,
116 source_uid: self.source_uid,
117 target_service: self.target_service.clone(),
118 target_method: self.target_method.clone(),
119 is_oneway: self.is_oneway,
120 payload_size: self.payload_size,
121 }
122 }
123}
124
125/// Binder 探针错误
126#[derive(Debug, thiserror::Error)]
127pub enum ProbeError {
128 /// 内核不支持 eBPF
129 #[error("eBPF not supported on this kernel")]
130 EbpfNotSupported,
131 /// 权限不足
132 #[error("insufficient permissions for eBPF (need root or system daemon)")]
133 PermissionDenied,
134 /// BPF 程序加载失败
135 #[error("BPF program load failed: {0}")]
136 LoadError(String),
137}