使用gdb在指定的可执行文件外部执行单步汇编代码会导致错误"无法找到当前函数的边界"

Pau*_*aul 80 linux x86 assembly gdb linux-kernel

我在gdb的目标可执行文件之外,我甚至没有与该目标对应的堆栈.无论如何我想单步执行,以便我可以验证汇编代码中发生了什么,因为我不是x86汇编的专家.不幸的是,gdb拒绝进行这种简单的汇编级调试.它允许我在适当的断点上设置和停止,但是一旦我尝试单步执行,gdb就会报告错误"找不到当前函数的边界"并且EIP不会改变.

额外细节:

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

我想另一个替代方法是生成一个伪内核模块或调试信息文件给gdb,使它相信这个区域在程序代码中.gdb在内核可执行文件本身上运行良好.

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

(我可以在我的程序集中的每个指令上设置一个断点.这可以工作,但一段时间后会变得非常费力,因为x86汇编指令的大小会有所不同,每次重新启动时程序集的位置都会改变.)

eph*_*ent 145

而不是gdb,运行gdbtui.或者gdb使用-tui开关运行.或C-x C-a进入后按gdb.现在你处于GDB的TUI模式.

输入layout asm以生成上部窗口显示组件 - 这将自动跟随您的指令指针,但您也可以在调试时更改框架或滚动.按C-x s进入SingleKey模式,其中run continue up down finish等等缩写为单个键,允许您快速浏览程序.

   +---------------------------------------------------------------------------+
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)


R S*_*hko 106

您可以使用stepinexti(可以缩写为sini)来逐步执行您的机器代码.


Mat*_*ery 23

你可以在这里做的最有用的事情是display/i $pc,在使用之前stepi已经在Samuel Klatchko的回答中提到过.这告诉gdb每次打印提示之前都要反汇编当前指令; 然后你可以继续按Enter键重复stepi命令.

(有关更多详细信息,请参阅我对另一个问题的回答 - 该问题的背景不同,但原理是相同的.)