当我输入:
gdb mybinary
mybinary是一个PIE可执行的(位置独立代码)。
我收到了gdb提示。二进制文件未完全加载到内存中。我为什么这么说?这是因为我们在这一步不知道主入口点的地址是什么。
有时可以键入disassemble main,但在我的情况下,二进制文件不包含调试信息。
如果类型为“run”,则加载程序将程序加载到内存中并运行程序。
我该怎么做才能强制gdb运行加载器并中断main中的第一条指令。有可能吗?
由于
答案 0 :(得分:1)
是否可能
不确定。这是一种方法:
$ echo "int main() { return 0; }" | gcc -xc -
$ gdb -q ./a.out
Reading symbols from ./a.out...(no debugging symbols found)...done.
(gdb) x/i &main
0x5fa <main>: push %rbp
请注意,这是一个PIE二进制文件,它尚未重新定位(Linux系统上的地址0x5fa
上不会执行任何代码)。
(gdb) set stop-on-solib-events 1
(gdb) run
Starting program: /tmp/a.out
Stopped due to shared library event (no libraries added or removed)
(gdb) x/i &main
0x5555555545fa <main>: push %rbp
您现在可以看到二进制文件已经重新定位,并且可以在main
上设置断点。
(gdb) b main
Breakpoint 1 at 0x5555555545fe
(gdb) c
Continuing.
Stopped due to shared library event:
Inferior loaded /lib/x86_64-linux-gnu/libc.so.6
(gdb) c
Continuing.
Breakpoint 1, 0x00005555555545fe in main ()
瞧。
答案 1 :(得分:0)
在现代 GDB 中,start
在 main 和 run 中设置了一个临时断点。该命令是在过去几年中添加的,可能是因为 PIE 可执行文件变得普遍。
start
确实适用于 PIE 可执行文件,避免了 main
的真实地址直到 run
之后才知道的问题,只要 main
在它们的符号中表,以便 GDB 可以通过名称找到它。
如果没有,您只能在运行任何用户空间指令之前使用 starti
停止,就像您的问题标题所示。 (或许@Employed Russian 对 set stop-on-solib-events 1
的建议可以帮助您在一些有趣的地方停下来,即使是在剥离的二进制文件中也是如此。)