我编写了一个简单的程序来附加到execve系统调用,但是我无法看到相关的输出。
这里是我的第一个c (BPF程序):
#include <errno.h>
#include <bpf/bpf.h>
#include <stdio.h>
#include <string.h>
#include "bpf_load.h"
#include "bpf_util.h"
#include "libbpf.h"
#define SEC(NAME) __attribute__((section(NAME), used))
SEC("kprobe/execve")
int bpf_prog1(struct pt_regs *ctx)
{
char m[]="hello world";
bpf_trace_printk(m,sizeof(m));
return 0;
}
char _license[] SEC("license") = "GPL";bpf_load.c (用户空间加载器):
#include "bpf_load.h"
#include <stdio.h>
#include <linux/bpf.h>
#include <sys/resource.h>
int main(int argc, char **argv) {
if (load_bpf_file("one.o")) {
printf("%s", bpf_log_buf);
return 1;
}
return 0;
}以及Makefile:
CLANG = clang
EXECABLE = monitor-exec
BPFCODE = one
BPFTOOLS = /kernel-src/samples/bpf
BPFLOADER = $(BPFTOOLS)/bpf_load.c
INCLUDE += -I/kernel-src/samples/bpf
INCLUDE += -I/kernel-src/tools/lib
CCINCLUDE += -I/kernel-src/tools/testing/selftests/bpf
CCINCLUDE += -I/kernel-src/tools/lib/bpf
CCINCLUDE += ${INCLUDE}
LOADINCLUDE += -I/kernel-src/tools/include
LOADINCLUDE += -I/kernel-src/tools/perf
LOADINCLUDE += ${INCLUDE}
LIBRARY_PATH = -L/usr/local/lib64
BPFSO = -lbpf
.PHONY: clean bpfload build
clean:
rm -f *.o *.so $(EXECABLE)
build: ${BPFCODE.c} ${BPFLOADER}
$(CLANG) -O2 -DHAVE_ATTR_TEST=0 -target bpf -c $(BPFCODE:=.c) $(CCINCLUDE) -o ${BPFCODE:=.o}
bpfload: build
clang -o $(EXECABLE) -DHAVE_ATTR_TEST=0 -lelf $(LOADINCLUDE) $(LIBRARY_PATH) $(BPFSO) \
$(BPFLOADER) loader.c
$(EXECABLE): bpfload
.DEFAULT_GOAL := $(EXECABLE)到目前为止,我还没有从Makefile中得到任何错误。
在执行./monitor-exec时,我将得到以下输出
invalid relo for insn[6].code 0x85
bpf_load_program() err=22
last insn is not an exit or jmp
processed 0 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0
last insn is not an exit or jmp
processed 0 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0我无法理解我做错了什么。我只是附加一个k探头,当系统调用发生时,应该打印hello world。
发布于 2020-07-16 13:39:45
在您的eBPF程序中:
#include <errno.h>
#include <bpf/bpf.h>
#include <stdio.h>
#include <string.h>
#include "bpf_load.h"
#include "bpf_util.h"
#include "libbpf.h"
#define SEC(NAME) __attribute__((section(NAME), used))
SEC("kprobe/execve")
int bpf_prog1(struct pt_regs *ctx)
{
char m[]="hello world";
bpf_trace_printk(m,sizeof(m));
return 0;
}您正确地使用了bpf_trace_printk() (虽然您可能希望在消息的末尾添加一个\n,或者您的输出会很混乱),但是您所包含的文件中没有一个包含此助手的定义。
bpf_trace_printk()是作为内核的一部分编译的,永远不会编译到您的BPF对象文件中。当尝试加载程序时,函数load_bpf_file()执行重定位步骤,它将与bpf_trace_printk()关联的数字(在用户API中)放置在eBPF字节码的相关指令中。
但它需要在某个地方找到这个号码。它在头linux/bpf.h (从多个包含中提取)中定义为FN(trace_printk) (正在进行的一些宏魔术),结果实际上是一个#define BPF_FUNC_trace_prink 6。但是,您需要告诉加载函数它对应于您正在调用的bpf_trace_prink()!
有两种解决办法:
https://stackoverflow.com/questions/62936008
复制相似问题