eBPF Talk: trampoline 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【汇编慎入】
书接上回,使用 fexit
的时候,为什么在 ret
前增加 add $0x8,%rsp
指令就能跳过执行原来的函数?
call
学习一下几条常用指令:
call %N
: 相当于push %eip
+mov %N, %eip
。leave
: 相当于mov %ebp, %esp
+pop %ebp
。ret
: 相当于pop %eip
。
push
and pop
看下执行内核 inet_csk_complete_hashdance()
函数、和 attach 到上面的 fexit
trampoline
时,寄存器和栈的变化。
0,因为 call
inet_csk_complete_hashdance()
,所以栈上存有一个旧的 %eip
值。
call %0xffffffff9eda55a0
相当于push %eip
+mov %0xffffffff9eda55a0, %eip
。
1,call %0xffffffffc0431000
。
call %0xffffffffc0431000
相当于push %eip
+mov %0xffffffffc0431000, %eip
。
此时,栈上保存了两个连续的 %eip
值。
2,执行完 fexit
trampoline
的 prologue
后。
push %rbp
mov %rsp, %rbp
sub $0x40, %rsp
3,执行 epilogue
里的 leave
后。
leave
相当于mov %ebp, %esp
+pop %ebp
。
4,执行 epilogue
里的 add $0x8, %rbp
后。
add $0x8, %rbp
丢弃栈上保存的 %eip
值 0xffffffff9eda55a5
,就不会继续执行原来的函数。
5,执行 epilogue
里的 ret
后。
ret
相当于pop %eip
。
总结
经过几张寄存器与栈状态变化的图片,便可知道在 leave
和 ret
之间增加 add $0x8,%rsp
指令就能跳过执行原来的函数。
学习汇编、机器指令时,画图分析寄存器和栈的变化,或者通过可视化工具将寄存器和栈的变化呈现出来,才是正确的学习方法。
文章作者 Leon Hwang
上次更新 2023-05-23