Running eBPF on Android: A Practical Guide

Quick Reference:
# Check Android kernel eBPF support
adb shell cat /proc/config.gz | gunzip | grep BPF
# Check kernel version (needs 4.9+)
adb shell uname -r
# Push and run bpftrace (if available)
adb push bpftrace /data/local/tmp/
adb shell /data/local/tmp/bpftrace -e 'tracepoint:syscalls:sys_enter_open { printf("%s\n", comm); }'
eBPF has revolutionized Linux observability and security. But what about the billions of Android devices running Linux kernels? Can you run eBPF on your phone for security research, app analysis, or performance debugging?
The short answer: yes, but with significant caveats. This guide covers what works, what doesn't, and how to get eBPF running on Android.
Android's eBPF Support
Android has included eBPF support since Android 9 (Pie), but primarily for internal use:
| Android Version | Kernel | eBPF Support |
|---|---|---|
| Android 9 (Pie) | 4.9+ | Basic, internal only |
| Android 10 | 4.14+ | Traffic monitoring |
| Android 11 | 4.19+ | Extended, still limited |
| Android 12+ | 5.4+ | Better support, BTF possible |
| Android 14+ | 5.15+ | Improved CO-RE support |
Google uses eBPF internally for:
- Network traffic accounting
- CPU frequency tracking
- Memory statistics
- Battery usage attribution
But running your own eBPF programs requires root access and some effort.
Requirements
To run custom eBPF on Android, you need:
- Root access (Magisk, KernelSU, or unlocked bootloader)
- Kernel with eBPF enabled (check CONFIG_BPF=y)
- Appropriate kernel version (4.9 minimum, 5.x preferred)
- Cross-compiled eBPF tools
Check Kernel eBPF Config
# Pull and check kernel config
adb shell cat /proc/config.gz | gunzip | grep -E "CONFIG_BPF|CONFIG_HAVE_EBPF"
# Essential configs
CONFIG_BPF=y
CONFIG_BPF_SYSCALL=y
CONFIG_BPF_JIT=y
CONFIG_HAVE_EBPF_JIT=y
# For tracing
CONFIG_BPF_EVENTS=y
CONFIG_KPROBE_EVENTS=y
CONFIG_UPROBE_EVENTS=y
# For BTF/CO-RE (newer kernels)
CONFIG_DEBUG_INFO_BTF=y
Most stock Android kernels have basic BPF enabled but lack advanced features like BTF.
Method 1: Using Android's Built-in eBPF
Android includes /sys/fs/bpf/ for its internal programs:
adb shell ls /sys/fs/bpf/
# map_netd_app_uid_stats_map
# map_netd_configuration_map
# prog_netd_cgroupskb_egress_stats
# ...
These are loaded by system services and not directly usable for custom purposes, but you can inspect them:
# Dump map contents (needs root)
adb shell cat /sys/fs/bpf/map_netd_app_uid_stats_map
Method 2: Cross-Compile bpftool
Build bpftool for Android:
# Clone Android NDK
export NDK=/path/to/android-ndk
# Clone bpftool source
git clone https://github.com/libbpf/bpftool.git
cd bpftool/src
# Cross-compile for ARM64
make CC=$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android30-clang \
EXTRA_CFLAGS="--sysroot=$NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot"
Push and run:
adb push bpftool /data/local/tmp/
adb shell chmod +x /data/local/tmp/bpftool
adb shell /data/local/tmp/bpftool prog list
Method 3: Use adeb (Android Debian)
adeb provides a Debian chroot on Android with pre-built tracing tools:
# Install adeb
git clone https://github.com/joelagnel/adeb.git
cd adeb
# Prepare device (needs root)
./adeb prepare
# Enter chroot
./adeb shell
# Inside chroot, tools like trace-cmd may be available
trace-cmd record -e sched
Method 4: Build Custom eBPF Programs
For custom eBPF programs, cross-compile with the Android NDK:
Simple eBPF Program
// trace_open.bpf.c
#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>
SEC("tracepoint/syscalls/sys_enter_openat")
int trace_openat(void *ctx) {
char comm[16];
bpf_get_current_comm(&comm, sizeof(comm));
bpf_printk("openat called by: %s", comm);
return 0;
}
char LICENSE[] SEC("license") = "GPL";
Compile for Android
# Use clang to compile BPF bytecode
clang -target bpf -O2 -g -c trace_open.bpf.c -o trace_open.bpf.o
# Push to device
adb push trace_open.bpf.o /data/local/tmp/
# Load with bpftool (needs root)
adb shell /data/local/tmp/bpftool prog load /data/local/tmp/trace_open.bpf.o /sys/fs/bpf/trace_open
# Attach to tracepoint
adb shell /data/local/tmp/bpftool prog attach pinned /sys/fs/bpf/trace_open tracepoint syscalls sys_enter_openat
Read Output
# BPF trace output goes to trace_pipe
adb shell cat /sys/kernel/debug/tracing/trace_pipe
Method 5: Simpleperf with eBPF
Android's simpleperf can use eBPF for some operations:
# Record with eBPF-backed features (if supported)
adb shell simpleperf record -a --duration 10
# Pull and analyze
adb pull /data/local/tmp/perf.data
simpleperf report -i perf.data
Challenges on Android
No BTF on Most Devices
Stock Android kernels rarely include BTF:
adb shell ls /sys/kernel/btf/vmlinux
# ls: /sys/kernel/btf/vmlinux: No such file or directory
Without BTF, CO-RE doesn't work. You must compile eBPF programs for your specific kernel version.
SELinux Restrictions
Even with root, SELinux may block eBPF operations:
# Check SELinux status
adb shell getenforce
# Enforcing
# Temporarily set permissive (needs root)
adb shell setenforce 0
For persistent access, you need SELinux policy modifications.
Limited Kernel Features
Many tracing features require kernel config options that stock kernels lack:
# Often missing on stock kernels
CONFIG_FTRACE=y
CONFIG_FUNCTION_TRACER=y
CONFIG_KPROBE_EVENTS=y
CONFIG_UPROBE_EVENTS=y
CONFIG_BPF_KPROBE_OVERRIDE=y
Architecture Differences
Most Android devices are ARM64, requiring cross-compilation:
# Check architecture
adb shell uname -m
# aarch64
Ensure your eBPF programs target the correct architecture.
Custom Kernel for Full eBPF
For serious eBPF work on Android, build a custom kernel:
Enable eBPF Features
# Essential
CONFIG_BPF=y
CONFIG_BPF_SYSCALL=y
CONFIG_BPF_JIT=y
# Tracing
CONFIG_FTRACE=y
CONFIG_KPROBES=y
CONFIG_KPROBE_EVENTS=y
CONFIG_UPROBE_EVENTS=y
CONFIG_BPF_EVENTS=y
# BTF for CO-RE
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_INFO_BTF=y
CONFIG_DEBUG_INFO_BTF_MODULES=y
# Network
CONFIG_CGROUP_BPF=y
CONFIG_NETFILTER_XT_MATCH_BPF=y
Build and Flash
# Clone kernel source for your device
git clone https://android.googlesource.com/kernel/common
cd common
git checkout android-5.15
# Configure
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- defconfig
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- menuconfig
# Enable eBPF options
# Build
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc)
# Flash (device-specific)
fastboot flash boot boot.img
Practical Use Cases
App Syscall Tracing
Monitor which syscalls an app makes:
SEC("tracepoint/raw_syscalls/sys_enter")
int trace_syscall(struct trace_event_raw_sys_enter *ctx) {
u32 pid = bpf_get_current_pid_tgid() >> 32;
if (pid == TARGET_PID) {
bpf_printk("syscall: %d", ctx->id);
}
return 0;
}
Network Monitoring
Track network connections per app:
SEC("cgroup_skb/egress")
int track_egress(struct __sk_buff *skb) {
u32 uid = bpf_get_socket_uid(skb);
// Count bytes per UID
return 1;
}
Security Research
Detect suspicious behavior:
SEC("kprobe/__arm64_sys_ptrace")
int detect_ptrace(struct pt_regs *ctx) {
char comm[16];
bpf_get_current_comm(&comm, sizeof(comm));
bpf_printk("ptrace from: %s", comm);
return 0;
}
Tools Summary
| Tool | Purpose | Root Required |
|---|---|---|
| bpftool | Load/manage BPF programs | Yes |
| adeb | Debian chroot with tools | Yes |
| simpleperf | Performance analysis | No (limited) / Yes (full) |
| trace-cmd | Ftrace frontend | Yes |
| perfetto | System tracing | No (limited) / Yes (full) |
Alternatives Without Root
If you can't root the device:
- Perfetto: Android's official tracing system (limited but powerful)
- Simpleperf: CPU profiling without root
- Android Studio Profiler: App-level profiling
- Frida: Dynamic instrumentation (different approach)
Conclusion
Running eBPF on Android is possible but requires effort. Stock devices with root access can run basic eBPF programs, but advanced features like CO-RE need custom kernels with BTF enabled.
For security research and deep system analysis, the investment in a proper eBPF-enabled Android setup pays off. You get the same powerful observability that's transforming Linux server monitoring, right on mobile devices.
Building mobile security tools? Akmatori AI agents can help automate security analysis, monitor app behavior, and detect anomalies across your mobile fleet.
