ebpf在安卓中的使用
前置条件
-
电脑端:
Linux环境(Ubuntu),安装了adb,git,debootstrap,qemu-user-static。 -
手机端:已
Root,开启USB调试,内核版本≥ 4.14(推荐Android 10+)。
构建 Debian 镜像
-
获取源代码
git clone https://github.com/joelagnel/adeb.git cd adeb-
坑点 \(1\):国外源无法下载
现象:运行构建脚本时,卡在下载阶段,或者报
Failed getting release file。原因:默认的
ftp.us.debian.org在国内无法访问。解决:修改
buildstrap文件,将源替换为清华源。 -
坑点 \(2\) :
Debian 10 (Buster)版本过旧现象:即使换了源,下载依然报错,或者找不到
Release文件。原因:
Debian 10已停止常规支持,源的路径结构发生了变化。解决:升级到
Debian 11 (Bullseye)。
修改androdeb文件(注意不是buildstrap,这是参数传递的源头):
找到DISTRO=buster改为DISTRO=bullseye。 -
坑点 \(3\) :软件包名不兼容
现象:报错
Couldn't find these debs: llvm-7-dev, python...。原因:
Debian 11淘汰了旧版包名(如clang-7, python),必须用新名(clang, python3)。解决:编辑
packages/bcc文件。
清空内容,填入适配Debian 11的新列表(包含llvm-dev, python3, clang等)。 -
坑点 \(4\) :备份文件导致冲突
现象:修改了
packages/bcc后依然报错,提示新旧包名混杂。原因:
ADEB脚本会读取packages/目录下所有文件。你备份的bcc.bak和默认自带的compilers等文件里依然包含旧包名,被脚本误读了。解决:只保留
packages/bcc这一个文件。删除或移走所有其他文件(bcc.bak, compilers, editors等)。 -
坑点 \(5\):幽灵挂载
现象:构建失败后,无法删除
/data/androdeb,提示Read-only file system。原因:上次失败的构建残留了
/proc,/sys的挂载,导致无法直接删除文件夹。解决:重启手机(最稳妥),然后
adb shell rm -rf /data/androdeb。
-
-
解决坑点
-
步骤\(1\) : 把默认的
Debian 10 (Buster)升级为Debian 11 (Bullseye)。把
adeb文件中DISTRO=buster改为DISTRO=bullseye。 -
步骤\(2\) : 修改下载源
把
buildstrap文件中http://ftp.us.debian.org/debian/或http://mirrors.aliyun.com/debian/替换成http://mirrors.tuna.tsinghua.edu.cn/debian/。 -
步骤\(3\) : 把旧的
clang-7, python替换为Debian 11支持的新包名。把
packages/bcc中的内容全部删除,复制下述内容。PACKAGES+=" llvm-dev libclang-dev libelf-dev libfl-dev libunwind-dev libdw-dev git gcc libtool autoconf make cmake iperf arping ethtool flex bison python3 clang python3-netaddr python3-pyroute2 python3-distutils " INSTALL_BCC=1 -
步骤 \(4\) : 移除
packages/目录下所有可能包含旧配置的文件,只留我们改好的bcc。# 先创建一个临时文件夹存放旧文件 mkdir -p ~/adeb_old_packages # 把除了 bcc 以外的所有文件都移走(包括 compilers, editors 以及你可能备份的 bcc.bak) mv packages/compilers packages/editors packages/others packages/scheduler packages/tracers ~/adeb_old_packages/ # 如果你有备份文件,也删掉或移走 rm -f packages/*.bak packages/*~ -
步骤 \(5\) : 清除之前的“幽灵挂载”,开始正式下载和推送。
-
重启手机
adb reboot # 等待手机开机并连接 adb wait-for-device -
删除手机的旧目录
adb shell rm -rf /data/androdeb -
执行最终构建命令 (前两步的执行都建立到
3.的执行失败)sudo ./adeb prepare --build --arch arm64 --full
-
-
打通网络与权限 (ADEB 内部操作)
-
进入环境
./adeb shell
-
坑点 \(6\) :
DNS解析失败现象:
ping mirrors.tuna.tsinghua.edu.cn提示Temporary failure in name resolution。原因:
/etc/resolv.conf丢失或为空。解决:手动写入
DNS。echo "nameserver 223.5.5.5" > /etc/resolv.conf -
坑点 \(7\):无网络权限
现象:
ping 223.5.5.5报错Network is unreachable。原因:安卓内核限制只有特定
GID (Group ID)的用户才能联网。Debian的root用户默认不在安卓的“上网组”里。解决:添加安卓用户组。
groupadd -g 3003 aid_inet groupadd -g 3004 aid_net_raw usermod -a -G aid_inet,aid_net_raw root关键动作:执行完必须 exit 退出并重新进入 ADEB,权限才生效。
-
坑点 \(8\):
SELinux拦截现象:即使用了正确的
GID,依然Ping不通。原因:安卓的防火墙 (
SELinux) 处于Enforcing模式,拦截了陌生环境的请求。解决:在电脑端执行
adb shell su -c setenforce 0。 -
坑点 \(9\):
DNS依然不稳定现象:
IP能通,但域名解析时好时坏。解决:绕过
DNS,直接改Hosts。echo "101.6.15.130 mirrors.tuna.tsinghua.edu.cn" >> /etc/hosts
-
软件最终安装成功
apt update apt install bpftrace bpfcc-tools linux-perf xz-utils
挂载内核接口(eBPF 运行环境)
软件装好了,但 bpftrace 报错。
-
坑点 \(10\) :
Debugfs未挂载现象:运行
bpftrace报No such file或open(/sys/kernel/debug/...): failed。原因:手机内核默认没挂载调试文件系统,
eBPF没法通过文件系统和内核对话。解决:手动挂载。
mount -t debugfs debugfs /sys/kernel/debug -
坑点 \(11\):
Tracepoint找不到 (通讯录丢失)现象:能运行
interval(打点),但tracepoint:syscalls:...报错not found,且列表为空。原因:新版安卓内核把
tracing独立为tracefs,需要单独挂载,且需要手动创建挂载点。解决:
mkdir -p /sys/kernel/debug/tracing mount -t tracefs nodev /sys/kernel/debug/tracing -
坑点 \(12\):内核阉割了 \(Syscalls\) 分类
现象:挂载都对了,但
tracepoint:syscalls:sys_enter_openat还是报错。原因:安卓生产版内核为了精简,移除了标准的
syscalls分类。解决:使用
raw_syscalls(原始入口)或kprobe(动态探针)。# 成功方案 bpftrace -e 'tracepoint:raw_syscalls:sys_enter { ... }'
最终成果
为了防止重启手机后还要把上面那些挂载命令重敲一遍,我们在adeb主文件夹下保存了 run.sh。
#!/bin/bash
echo "[+] 正在获取 Root 权限..."
adb root
adb wait-for-device
echo "[+] 正在关闭防火墙 (SELinux)..."
adb shell setenforce 0
echo "[+] 正在挂载内核调试系统..."
adb shell mount -t debugfs debugfs /sys/kernel/debug
adb shell mkdir -p /sys/kernel/debug/tracing
adb shell mount -t tracefs nodev /sys/kernel/debug/tracing
echo "[+] 准备完毕,正在进入 ADEB..."
./adeb shell
只需要运行 ./run.sh,进去直接运行。
测试查看
-
bpftrace -e 'kprobe:vfs_read { @[comm] = count(); }'玩法:运行后,操作手机打开几个
APP,等待5秒,按Ctrl+C结束。看点:它会打印一个排行榜,告诉你刚才谁读文件次数最多(通常
logd或system_server会排前面)。

浙公网安备 33010602011771号