使用gdb在指定的可执行文件之外单步执行汇编代码会导致错误“找不到当前函数的范围”
我在gdb的目标可执行文件之外,我甚至没有对应于该目标的堆栈。 无论如何,我想要单步执行,这样我就可以validation我的汇编代码中发生了什么,因为我不是x86汇编的专家。 不幸的是,gdb拒绝做这个简单的汇编级debugging。 它允许我在适当的断点处设置和停止,但是一旦我尝试单步启动,gdb会报告错误“无法find当前函数的边界”,EIP不会改变。
额外细节:
机器代码是由gcc asm语句生成的,我将它从objdump -d的输出复制到执行的内核内存位置。 我不介意使用加载器将对象代码加载到重定位地址的简单方法,但请记住加载必须在内核模块中完成。
我想另外一个select是产生一个假的内核模块或debugging信息文件给gdb,使它相信这个区域在程序代码中。 gdb在内核可执行文件本身上工作正常。
(对于那些真正想知道的人,我在运行时将代码插入到VMware VM内的Linux内核数据空间中,并通过gdb从gdb远程debugging内核,通过VMware Workstation的内置gdb存根对其进行debugging。注意我没有编写内核利用;我是一个安全研究生写一个原型。)
(我可以在我的程序集里面的每条指令上设置一个断点,这样做可能会花费一些时间,因为x86汇编指令的大小会有所不同,并且每次重启时程序集的位置都会改变。
您可以使用stepi
或nexti
(可缩写为si
或ni
)来逐步执行机器代码。
运行gdbtui
代替gdb
。 或者用-tui
开关运行gdb
。 或者进入gdb
后按Cx Ca。 现在你处于GDB的TUI模式。
inputlayout asm
使上层窗口显示程序集 – 这将自动遵循您的指令指针,但您也可以在debugging时更改帧或滚动。 按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),%rdi | | 0x40268a <main + 26> movq $ 0x402a10,0x400(%rsp)| | 0x402696 <main + 38> movq $ 0x0,0x408(%rsp)| | 0x4026a2 <main + 50> movq $ 0x402510,0x410(%rsp)| + ------------------------------------------------- -------------------------- + subprocess21518在:主线:?? PC:0x402670 (gdb)文件/ opt / j64-602 / bin / jconsole 从/opt/j64-602/bin/jconsole.done中读取符号。 (没有finddebugging符号)...完成。 (gdb)布局asm (gdb)启动 (GDB)
你可以在这里做的最有用的事情是在使用stepi
之前display/i $pc
,正如R Samuel Klatchko的回答中已经提到的那样。 这告诉gdb在每次打印提示之前都要反汇编当前的指令; 那么你可以继续按Enter来重复stepi
命令。
(有关更详细的信息,请参阅我对另一个问题的回答 – 该问题的背景是不同的,但原理是相同的。)