搜索了好久都没有找到关于Android中使用kprobe的例子,基本都是用tracepoint .于是自己摸索了下,记录下
首先是prog程序
#include <linux/bpf.h>
#include <stdbool.h>
#include <stdint.h>
#include <bpf_helpers.h>
#include <string.h>
struct switch_args {
unsigned long long ignore;
char prev_comm[16];
int prev_pid;
int prev_prio;
long long prev_state;
char next_comm[16];
int next_pid;
int next_prio;
};
struct data {
char str[16];
void *ptr;
};
DEFINE_BPF_MAP(do_faccessat_map, ARRAY, int, struct data, 1024);
DEFINE_BPF_PROG("kprobe/do_faccessat", AID_ROOT, AID_NET_ADMIN, kp_do_faccessat)
//(struct pt_regs *ctx, int dirfd, const char __user *pathname, int mode) {
//(void *ctx, int dirfd, const char __user *pathname, int mode) {
(struct switch_args *ctx) { //参数这里暂时还不知道怎么获取传递过去,因为中途忙其他的去了
int key = 100;
struct data data_t;
data_t.ptr = ctx;
memcpy(data_t.str, "hello world", 16);
bpf_do_faccessat_map_update_elem(&key, &data_t, BPF_ANY);
return 0;
}
LICENSE("Apache 2.0");
测试程序
// bpf_kprobe_test_cli.cpp
#include <android-base/macros.h>
#include <stdlib.h>
#include <unistd.h>
#include <iostream>
#include <bpf/BpfMap.h> // system/bpf/libbpf_android/include/bpf/BpfMap.h
#include <bpf/BpfUtils.h>
#include <libbpf_android.h>
struct data {
char str[16];
void *ptr;
};
int main() {
constexpr const char tp_prog_path[] = "/sys/fs/bpf/prog_bpf_kprobe_test_kprobe_do_faccessat";
constexpr const char tp_map_path[] = "/sys/fs/bpf/map_bpf_kprobe_test_do_faccessat_map";
// Attach tracepoint and wait for 4 seconds
int mProgFd = bpf_obj_get(tp_prog_path);
// int mMapFd = bpf_obj_get(tp_map_path);
/**
* int bpf_attach_kprobe(int progfd, enum bpf_probe_attach_type attach_type,
* const char *ev_name, const char *fn_name, uint64_t fn_offset)
* 打开 /sys/kernel/tracing/kprobe_events
* 写入对应事件 'echo 'p:kprobes/do_faccessat_bcc_pid_ do_faccessat'
* 参考: https://www.kernel.org/doc/html/latest/trace/kprobetrace.html
*/
int pfd = bpf_attach_kprobe(mProgFd, BPF_PROBE_ENTRY,
"myprobe"/*probe name*/, "do_faccessat" /*函数符号*/, 0);
if (pfd < 0) {
printf("bpf_attach_kprobe error!\n");
exit(0);
}
sleep(1);
// 高版本使用fd构造BpfMap
android::bpf::BpfMap<int, struct data> myMap(tp_map_path);
pid_t pid = getpid();
printf("pid: %d\n", pid);
while(1) {
usleep(40000);
// android::base::Result<Value> 类型
data data_t = myMap.readValue(100).value();
printf("kprobe do_faccessat %s map addr %p\n", data_t.str, data_t.ptr);
}
exit(0);
}
Android.bp
bpf {
name: "bpf_kprobe_test.o",
srcs: ["bpf_kprobe_test.c"],
cflags: [
"-Wall",
"-Werror",
],
}
cc_binary {
name: "bpf_kprobe_test_cli",
cflags: [
"-Wall",
"-Werror",
"-Wthread-safety",
],
clang: true,
shared_libs: [
"libcutils",
"libbpf_android",
"libbase",
"liblog",
"libnetdutils",
"libbpf",
],
srcs: [
"bpf_kprobe_test_cli.cpp",
],
}
运行效果