以ä¸ã®ã¹ãããã§é²ãã
- uprobeã®æ¦è¦ã使ç¨æ³
- eBPFããã°ã©ã ã®ä½æ
- ã¦ã¼ã¶ç©ºéããã°ã©ã ã®ä½æ
- ã³ã³ãã¤ã«ãåä½ç¢ºèª
1. uprobeã®æ¦è¦ã使ç¨æ³
eBPFã«ã¯ã·ã¹ãã ã³ã¼ã«ãé¢æ°ã«ããã¯ããæ©è½ãããããç¨éã«ãã£ã¦å¤§ãã2ã¤ã«åãããã
- kprobeï¼ã«ã¼ãã«ç©ºéã®é¢æ°ï¼ä¸»ã«ã·ã¹ãã ã³ã¼ã«ï¼ã«ã¢ã¿ãããããã®
- uprobeï¼ã¦ã¼ã¶ç©ºéã®é¢æ°ï¼ä¸»ã«ã·ã¹ãã ã³ã¼ã«ä»¥å¤ã
printf
ãã¦ã¼ã¶å®ç¾©é¢æ°ï¼ã«ã¢ã¿ãããããã®
ä»åã¯printf
ã«ã¢ã¿ãããããã®ã§uprobeã使ããã¨ã«ãªãã
ãã¦ãeBPFã§é¢æ°ãããã¯ããã«ã¯2ã¤ã®ããã°ã©ã ãå¿ è¦ã¨ãªãï¼ããã¯kprobe/uprobeå ±éï¼ãããã§ã¯ä¾¿å®ä¸ãeBPFããã°ã©ã ãã¨ãã¦ã¼ã¶ç©ºéããã°ã©ã ãã¨å¼ã¶ãã¨ã«ããã
- eBPFããã°ã©ã ï¼ããã¯ããéã®å¦çãè¨è¿°ããããã°ã©ã
- ã¦ã¼ã¶ç©ºéããã°ã©ã ï¼eBPFããã°ã©ã ãã«ã¼ãã«ã«ãã¼ãããé¢æ°ã«ã¢ã¿ããããããã°ã©ã
ããã2ã¤ã®ããã°ã©ã ãæã£ã¦åãã¦ããã¯ãå¯è½ã¨ãªããã¨ã«æ³¨æã
2. eBPFããã°ã©ã ã®ä½æ
ãã¡ã¤ã«åã¯hook.bpf.c
#include "vmlinux.h" #include <bpf/bpf_helpers.h> #include <bpf/bpf_tracing.h> #include <bpf/bpf_core_read.h> SEC("uprobe//lib/x86_64-linux-gnu/libc.so.6:printf") int BPF_KPROBE(printf_hook, const char *str) { bpf_printk("hello, printf!: %s\n", str); return 0; } char LICENSE[] SEC("license") = "Dual BSD/GPL";
3. ã¦ã¼ã¶ç©ºéããã°ã©ã ã®ä½æ
ãã¡ã¤ã«åã¯hook.c
#include <stdio.h> #include <unistd.h> #include <bpf/libbpf.h> #include <bpf/bpf.h> #include "hook.skel.h" int main() { int err = 0; struct hook_bpf *skel = hook_bpf__open_and_load(); if (!skel) { printf("error: failed to open BPF object\n"); return 1; } LIBBPF_OPTS(bpf_uprobe_opts, uprobe_opts, .func_name = "printf", .retprobe = false); skel->links.printf_hook = bpf_program__attach_uprobe_opts( skel->progs.printf_hook, -1, "/lib/x86_64-linux-gnu/libc.so.6", 0, &uprobe_opts); for (;;) { sleep(1); } hook_bpf__destroy(skel); return 0; }
4. ã³ã³ãã¤ã«ãåä½ç¢ºèª
Makefile
TARGET = hook ARCH = $(shell uname -m | sed 's/x86_64/x86/' | sed 's/aarch64/arm64/') BPF_OBJ = ${TARGET:=.bpf.o} USER_C = ${TARGET:=.c} USER_SKEL = ${TARGET:=.skel.h} all: $(TARGET) $(BPF_OBJ) .PHONY: all $(TARGET): $(USER_C) $(USER_SKEL) - rm -f $(TARGET).bpf-*.o.tmp - rm -f $(TARGET).bpf.o.temp-stream* gcc -Wall -o $(TARGET) $(USER_C) -Lãããã«libbpfã®ãã¹ãå ¥ãã(ä¾ï¼-L/home/user/libbpf/src)ã -l:libbpf.a -lelf -lz %.bpf.o: %.bpf.c vmlinux.h clang \ -target bpf \ -D __TARGET_ARCH_$(ARCH) \ -I/usr/include/$(shell uname -m)-linux-gnu \ -Wall \ -O2 -g -o $@ -c $< llvm-strip -g $@ $(USER_SKEL): $(BPF_OBJ) bpftool gen skeleton $< > $@ vmlinux.h: bpftool btf dump file /sys/kernel/btf/vmlinux format c > vmlinux.h clean: - rm $(BPF_OBJ) - rm $(TARGET) - rm -f $(TARGET).bpf-*.o.tmp - rm -f $(TARGET).bpf.o.temp-stream*
ãã¹ãç¨ã®ãã¡ã¤ã«ï¼hello.c
ï¼
#include <stdio.h> int main() { int tmp = 1; printf("hello! %d\n", tmp); printf("hello! %d\n", tmp); return 0; }
tmux
ãªã©ã§3ç»é¢éãã以ä¸ãé ã«è¡ãã
- 1ç»é¢ç®ã¯
sudo make
ãã¦ããsudo ./hook
- 2ç»é¢ç®ã¯
sudo cat /sys/kernel/tracing/trace_pipe
- 3ç»é¢ç®ã¯
gcc -Wall hello.c
ãã¦ãã./a.out
a.out
ãå®è¡ãã¦ã2ç»é¢ç®ã«hello, printf!: hello! %d
ã¨åºããOKï¼