如何调试汇编?
How to debug assembly?
我有以下要调试的汇编文件test
,
我该怎么做?
请注意,我使用的是 x86-64 和 att 语法,而且我无权访问 C 代码。
我想在每一行之后停下来,并能够在 table 中看到寄存器(我记得有这样一个选项)。
我试过了:
gdb test
r
但我得到:
Starting program:
No executable file specified.
Use the "file" or "exec-file" command.
在 运行ning GDB 之后在可执行文件上1:
使用start
或starti
分别在main或_start和运行程序中设置断点。
或使用 b 12
自己设置断点以在源代码第 12 行设置断点(如果您构建时有足够的调试信息使其工作),或 b *0x00401007
在地址上设置断点你 copy/pasted 从 disas
输出。
layout asm
/ layout reg
将 GDB 置于 text-UI 模式,在终端中使用“windows”进行反汇编和注册。 (这可能有点不稳定,您有时需要 control-L 来重绘屏幕,有时当您的进程退出时 GDB 会崩溃,尽管我不确定这是否专门来自 TUI。)
否则没有 TUI 模式,info reg
和 disas
可能有用。
有关更多 asm 调试技巧,请参阅 https://whosebug.com/tags/x86/info 的底部。
特别是 strace ./test
对于查看程序进行的系统调用非常有用,解码为 C 风格。在您为自己的实验而玩的玩具程序中,这基本上可以作为检查错误 return 值的替代方法。
脚注 1:您没有正确执行该部分:
No executable file specified.
这意味着您 运行 gdb test
.
所在的目录中不存在名为 test
的文件
你必须 assemble + link test.S
到一个名为 test
的可执行文件中,然后你才能 运行 GDB 在该文件上。如果 ls -l test
显示它,那么 gdb test
可以调试它。 (而且 ./test
可以 运行 它。)
通常 gcc -no-pie foo.S
是使调试更容易的好选择:地址将固定在 link 时间,因此 objdump -drwC -Mintel test
输出将匹配您在 [=81= 看到的地址]-时间。地址在数字上会更小,因此更容易直观地发现代码(.text)地址与 .rodata(现代 ld
将其放在单独的页面中,因此可以避免 exec 权限)与 .data / .bss.
无论哪种方式,堆栈地址仍然很容易从代码中区分出来,0x555 ...或0x0000...XXXXXX
在可执行文件中,0x7fffff...
在堆栈中,mmap中的其他地址是运行驯化。 (但是 libc 也被映射到堆栈附近的高地址,有或没有 PIE。)
(或者如果你写的是 _start
而不是 main
,gcc -nostdlib -static foo.S
意味着 -no-pie
)
我有以下要调试的汇编文件test
,
我该怎么做?
请注意,我使用的是 x86-64 和 att 语法,而且我无权访问 C 代码。 我想在每一行之后停下来,并能够在 table 中看到寄存器(我记得有这样一个选项)。
我试过了:
gdb test
r
但我得到:
Starting program:
No executable file specified.
Use the "file" or "exec-file" command.
在 运行ning GDB 之后在可执行文件上1:
使用start
或starti
分别在main或_start和运行程序中设置断点。
或使用 b 12
自己设置断点以在源代码第 12 行设置断点(如果您构建时有足够的调试信息使其工作),或 b *0x00401007
在地址上设置断点你 copy/pasted 从 disas
输出。
layout asm
/ layout reg
将 GDB 置于 text-UI 模式,在终端中使用“windows”进行反汇编和注册。 (这可能有点不稳定,您有时需要 control-L 来重绘屏幕,有时当您的进程退出时 GDB 会崩溃,尽管我不确定这是否专门来自 TUI。)
否则没有 TUI 模式,info reg
和 disas
可能有用。
有关更多 asm 调试技巧,请参阅 https://whosebug.com/tags/x86/info 的底部。
特别是 strace ./test
对于查看程序进行的系统调用非常有用,解码为 C 风格。在您为自己的实验而玩的玩具程序中,这基本上可以作为检查错误 return 值的替代方法。
脚注 1:您没有正确执行该部分:
No executable file specified.
这意味着您 运行 gdb test
.
test
的文件
你必须 assemble + link test.S
到一个名为 test
的可执行文件中,然后你才能 运行 GDB 在该文件上。如果 ls -l test
显示它,那么 gdb test
可以调试它。 (而且 ./test
可以 运行 它。)
通常 gcc -no-pie foo.S
是使调试更容易的好选择:地址将固定在 link 时间,因此 objdump -drwC -Mintel test
输出将匹配您在 [=81= 看到的地址]-时间。地址在数字上会更小,因此更容易直观地发现代码(.text)地址与 .rodata(现代 ld
将其放在单独的页面中,因此可以避免 exec 权限)与 .data / .bss.
无论哪种方式,堆栈地址仍然很容易从代码中区分出来,0x555 ...或0x0000...XXXXXX
在可执行文件中,0x7fffff...
在堆栈中,mmap中的其他地址是运行驯化。 (但是 libc 也被映射到堆栈附近的高地址,有或没有 PIE。)
(或者如果你写的是 _start
而不是 main
,gcc -nostdlib -static foo.S
意味着 -no-pie
)