Skip to main content

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}