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
到当前的freplace
bpf 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