使用gdb在指定的可执行文件之外单步执行汇编代码会导致错误“找不到当前函数的范围”

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

额外细节:

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

我想另外一个select是产生一个假的内核模块或debugging信息文件给gdb,使它相信这个区域在程序代码中。 gdb在内核可执行文件本身上工作正常。

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

(我可以在我的程序集里面的每条指令上设置一个断点,这样做可能会花费一些时间,因为x86汇编指令的大小会有所不同,并且每次重启时程序集的位置都会改变。

Solutions Collecting From Web of "使用gdb在指定的可执行文件之外单步执行汇编代码会导致错误“找不到当前函数的范围”"

您可以使用stepinexti (可缩写为sini )来遍历机器码。

运行gdbtui代替gdb 。 或者用-tui开关运行gdb 。 或者进入gdb后按Cx Ca。 现在你处于GDB的TUI模式。

输入layout asm使上层窗口显示程序集 – 这将自动遵循您的指令指针,但您也可以在调试时更改帧或滚动。 按Cx s进入单键模式,其中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),%r​​di |
    | 0x40268a <main + 26> movq $ 0x402a10,0x400(%rsp)|
    | 0x402696 <main + 38> movq $ 0x0,0x408(%rsp)|
    | 0x4026a2 <main + 50> movq $ 0x402510,0x410(%rsp)|
    + ------------------------------------------------- -------------------------- +
 子进程21518在:主线:??  PC:0x402670
 (gdb)文件/ opt / j64-602 / bin / jconsole
从/opt/j64-602/bin/jconsole.done中读取符号。
 (没有找到调试符号)...完成。
 (gdb)布局asm
 (gdb)启动
 (GDB)

你可以在这里做的最有用的事情是在使用stepi之前display/i $pc ,正如R Samuel Klatchko的回答中已经提到的那样。 这告诉gdb在每次打印提示之前都要拆开当前的指令; 那么你可以继续按Enter来重复stepi命令。

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