PIE + ASLR 地址映射
(gdb) break *0x7a6e3b1 Breakpoint 1 at 0x7a6e3b1 (gdb) info break Num Type Disp Enb Address What 1 breakpoint keep y 0x0000000007a6e3b1 <<F as axum::handler::Handler<(M,T1,T2,T3),S>>::call::{{closure}}+4577> (gdb) run Starting program: /prog Warning: Cannot insert breakpoint 1. Cannot access memory at address 0x7a6e3b1

这个报错其实正好暴露了一个关键点:你现在用的地址是「文件里的虚拟地址」,但程序跑起来以后,它被重新映射了(PIE + ASLR),所以 0x7a6e3b1 这个位置在运行时根本没有内存映射,gdb 自然插不进去断点。

解决方案:https://github.com/hugsy/gef

GEF 是个 gdb 插件,专门帮你解决 PIE 这类事,它自带 pie breakpoint 命令,可以直接用你在 IDA 里看到的 offset 下断点,运行时自动换算真正地址。


# 用 “原地址” 下 PIE 断点 (gdb) pie breakpoint 0x7a6e3b1 # 简写是 pie b 0x7a6e3b1 # 看一下 GEF 记录的“虚拟断点”: (gdb) pie info VNum Num Addr 1 N/A 0x00000000007a6e3b1 # 用 pie run 启动程序 (gdb) pie run # 这时 GEF 会在程序真正加载后,自动算出实际基址,并把虚拟断点转换成真实断点 # 再重新看一下 GEF 记录的“虚拟断点” (gdb) pie info VNum Num Addr 1 1 0x00000000007a6e3b1 # Num 赋值,意味着已经映射到了 gdb 的真正断点 # 查看 gdb 断点 - 在真实地址处已经加上了断点 (gdb) info breakpoint Num Type Disp Enb Address What 1 breakpoint keep y 0x000055555cfc236b <<F as axum::handler::Handler<(M,T1,T2,T3),S>>::call::{{closure}}+4507>


相关命令:

  • pie b 0x123 设置断点

  • pie info 查看所有断点

  • pie delete 1 删除某个断点

  • 查看当前地址 p/x $pc - $_base()