eBPF Talk: freplace on x86【汇编慎入】
文章目录
本系列是 x86 架构平台上 trampoline 的实现,从原理和实现上进行了详细的介绍。
- eBPF Talk: poke on x86【汇编慎入】
- eBPF Talk: perilogue on x86【汇编慎入】
- eBPF Talk: freplace on x86【汇编慎入】
- eBPF Talk: trampoline on x86【汇编慎入】
- eBPF Talk: trampoline on x86【续】【汇编慎入】
- eBPF Talk: trampoline stack on x86【汇编慎入】
freplace 技术便是对 prologue 进行 poke 的简单应用。
TL;DR 究竟有多简单呢?就是将 prologue 里的第一条 nop 指令替换成 jmp 指令;jmp 后不再回来继续执行原来的函数,是谓 freplace。

freplace 例子
demo 先行。源代码链接:ebpf-freplace。
|
|
没有进行 freplace 时:
|
|
|
|
进行 freplace 后:
|
|

freplace 实现原理
先看看 Go 代码是怎么调用 bpf() 系统调用的。
|
|
由上面的代码片段可知,调用的是 bpf() 系统调用中的 BPF_LINK_CREATE 命令。
|
|
看到 bpf_arch_text_poke() 函数时,便可知道上面代码片段的主要处理逻辑:
- 查询目标 bpf prog 的信息,特别是 bpf prog 的入口地址。
- 生成一个
trampoline对象。 - 调用
bpf_arch_text_poke()将目标 bpf prog 的prologue的第一条nop指令 live patch 成jmp指令,jmp到当前的freplacebpf prog 的入口地址。
复习一下 eBPF Talk: perilogue on x86【汇编慎入】 中的
prologue of bpf2bpf。

bpf2bpf 函数的第一条指令是 5 个字节大小的 nop 指令。
复习一下 eBPF Talk: poke on x86【汇编慎入】 中的
JIT on x86。
|
|
每个 bpf prog 的 prologue 都包含有 5 个字节大小的 nop 指令。据观察,每个可 trace 的内核函数的第一条指令也是如此。
总结
freplace 技术便是对 prologue 进行 poke 的简单应用,将 prologue 里的第一条 nop 指令替换成 jmp 指令。
不过,想要真正掌握 freplace,需要理解一些前置知识:
文章作者 Leon Hwang
上次更新 2023-05-23