将 gdb 用于指定可执行文件之外的单步汇编代码会导致错误“无法找到当前函数的边界”

我在 gdb 的目标可执行文件之外,甚至没有与该目标对应的堆栈。无论如何,我想单步执行,这样我就可以验证汇编代码中发生了什么,因为我不是 x86汇编的专家。不幸的是,gdb 拒绝执行这个简单的程序集级调试。它允许我在适当的断点上设置和停止,但只要我尝试单步执行,gdb 就会报告错误“无法找到当前函数的界限”,EIP 也不会改变。

其他详情:

机器代码是由 gcc asm 语句生成的,我把它复制到了它正在执行的内核内存位置,从 objecdump-d 的输出。我不介意用一种简单的方法来使用加载程序将我的目标代码加载到一个重新定位的地址,但是请记住,加载必须在内核模块中完成。

我认为另一种方法是生成一个假的内核模块或调试信息文件给 gdb,使其相信这个区域在程序代码中。Gdb 在内核可执行文件本身上工作得很好。

(对于那些真正想知道的人,我在运行时将代码插入到一个 VMware VM 中的 Linux 内核数据空间中,并通过 VMware Workstation 内置的 gdb 存根从 gdb 远程调试内核。注意,我不是在编写内核开发; 我是一名正在编写原型的安全研究生。)

(我可以在程序集中的每条指令上设置断点。这种方法可以工作,但是在一段时间之后会变得相当费力,因为 x86汇编指令的大小会发生变化,而且每次重新启动时汇编的位置都会发生变化。)

122278 次浏览

You can use stepi or nexti (which can be abbreviated to si or ni) to step through your machine code.

The most useful thing you can do here is display/i $pc, before using stepi as already suggested in R Samuel Klatchko's answer. This tells gdb to disassemble the current instruction just before printing the prompt each time; then you can just keep hitting Enter to repeat the stepi command.

(See my answer to another question for more detail - the context of that question was different, but the principle is the same.)

Instead of gdb, run gdbtui. Or run gdb with the -tui switch. Or press C-x C-a after entering gdb. Now you're in GDB's TUI mode.

Enter layout asm to make the upper window display assembly -- this will automatically follow your instruction pointer, although you can also change frames or scroll around while debugging. Press C-x s to enter SingleKey mode, where run continue up down finish etc. are abbreviated to a single key, allowing you to walk through your program very quickly.

+---------------------------------------------------------------------------+
B+>|0x402670 <main>         push   %r15                                        |
|0x402672 <main+2>       mov    %edi,%r15d                                  |
|0x402675 <main+5>       push   %r14                                        |
|0x402677 <main+7>       push   %r13                                        |
|0x402679 <main+9>       mov    %rsi,%r13                                   |
|0x40267c <main+12>      push   %r12                                        |
|0x40267e <main+14>      push   %rbp                                        |
|0x40267f <main+15>      push   %rbx                                        |
|0x402680 <main+16>      sub    $0x438,%rsp                                 |
|0x402687 <main+23>      mov    (%rsi),%rdi                                 |
|0x40268a <main+26>      movq   $0x402a10,0x400(%rsp)                       |
|0x402696 <main+38>      movq   $0x0,0x408(%rsp)                            |
|0x4026a2 <main+50>      movq   $0x402510,0x410(%rsp)                       |
+---------------------------------------------------------------------------+
child process 21518 In: main                            Line: ??   PC: 0x402670
(gdb) file /opt/j64-602/bin/jconsole
Reading symbols from /opt/j64-602/bin/jconsole...done.
(no debugging symbols found)...done.
(gdb) layout asm
(gdb) start
(gdb)