最近大部分的人都阳了,但既然活着能坚持就还得卷......
ebpf底层原理是很简单的,但基于hook框架做了很多事情,一个是有自己的程序空间(小操作系统那种),二个是大部分地方都能插桩,三个是支持动态静态插桩,四个是r3环跟r0环都能做,也就说他把我们常用的一些东西全集成于一身,然后做了非常多的扩展。
ebpf简单说了下,但是他的文档对初学者不是那么的友好,比如你要用一个接口:
看他的指导:
初学者你会被他带偏的,cpp的教程给你python例子(python做了更多的封装),反正我至少看到好几个Issues,里面问cpp怎么写的,当然你喜欢研究的话这都小场面,有文档不错了,这篇文章把bcc的前面部分全写了一个案例。
* 1. kprobes案例
* 2. kretprobes案例
* 3. Tracepoints案例
* 4. uprobes与uretprobes
* 5. USDT probes
* 6. Raw Tracepoints
* 7. syscall追踪
* 8. kfuncs与kretfuncs
* 9. lsm probes
* 10. 数据获取相关api使用
* 11. 参数与返回值修改
* 12. 日志输出
kprobes案例
#include <unistd.h>
#include <fstream>
#include <iostream>
#include <string>
#include "bcc_version.h"
#include "BPF.h"
//detach_kprobe
const std::string BPF_PROGRAM = R"(
int my_tcp_send(struct pt_regs *ctx) {
bpf_trace_printk("my_tcp_send hook !\n");
return 0;
}
)";
int main() {
ebpf::BPF bpf;
auto init_res = bpf.init(BPF_PROGRAM);
if (!init_res.ok()) {
std::cerr << init_res.msg() << std::endl;
return 1;
}
std::ifstream pipe("/sys/kernel/debug/tracing/trace_pipe");
std::string line;
std::cout << "Starting HelloWorld with BCC " << LIBBCC_VERSION << std::endl;
auto attach_res = bpf.attach_kprobe("tcp_sendmsg", "my_tcp_send");
if (!attach_res.ok()) {
std::cerr << attach_res.msg() << std::endl;
return 1;
}
while (true) {
if (std::getline(pipe, line)) {
std::cout << line << std::endl;
// Detach the probe if we got at least one line.
// auto detach_res = bpf.detach_kprobe(clone_fnname);
// if (!detach_res.ok()) {
// std::cerr << detach_res.msg() << std::endl;
// return 1;
// }
// break;
} else {
std::cout << "Waiting for a sys_clone event" << std::endl;
sleep(1);
}
}
return 0;
}
kretprobes案例