在GDB(实模式,连接到QEMU)中,在特定条件下的特定点,stepo和nexti似乎打破了断点机制

问题描述 投票:2回答:1

最小工作示例来源:

use16
org 0x7c00

jmp 0x0000:@start


@start:
    cli
        mov ax,cs
        mov ds,ax
        mov es,ax
        mov ss,ax
        mov sp,0x7c00
    sti

    mov bp,sp

    call @fails

jmp @start

@fails:
    nop
retn

times 510-($-$$) db 0
dw 0xAA55

以上内容通过FASM或NASM组装成二进制文件,并写入VHD(x.vhd)的MBR。 QEMU在启用调试支持的情况下启动:qemu-system-i386.exe -m 512 -boot c -net nic -net user -hda x.vhd -no-acpi -s -S -cpu 486

Cygwin中,使用GDB 9.1-1,然后发出以下命令来运行GDB并将其附加到QEMU,确定体系结构,跳过BIOS代码并在开始时设置断点MBR,加载到0x7c00,然后继续:

gdb
target remote localhost:1234
set architecture i8086
stepi 11
break *0x7c00
continue
nexti 10

此时,$ ip在nop行。

@fails:
    nop  ;  <---
retn

这里是遇到问题的地方。使用stepi,在retn行上放置一个临时断点,继续通过nop执行并在应有的位置中断。 但是使用steponexti,执行的确没有问题,但没有断点]。 GDB进入了无尽的等待。如果在nop之后手动插入断点(例如,在retnjmp @start上,调用返回的指令以retn插入),则GDB会在该处中断而不会出现问题。列出此时所有的断点不会产生新的断点,因此nexti似乎没有在任何地方放置临时断点(或未列出临时断点?)。

[经过大量调查,这是该问题的奇怪“解决方案],让nexti自动跳过nop并按原样在此处中断:((1) [C0 ],然后单击set $ebp = 0x7bfa(2)注释掉nexti行。

问题是:

  1. 为什么mov bp,sp似乎在特定位置打破了断点机制?也许在指令之间放置一个断点?还是nexti以某种方式出现16位代码问题?
  2. 为什么上面概述的奇怪的“修复”起作用?如果$ ebp在初始化后的任何时候都没有使用,怎么可能与任何东西相关? GDB是否在内部使用它?
assembly gdb breakpoints qemu real-mode
1个回答
0
投票

以下gdb命令启用远程协议调试,并显示gdb和QEMU gdbserver之间的交换显示:nexti。QEMU在交换中回复看起来很合理,但是gdb最终在地址0x5ea7c17处设置了断点,这是错误的。似乎它将set debug remote 1的4个字节解释为返回地址,而不是仅2。0x7c17是实际的返回地址,0xea和0x5是引导扇区代码的前两个字节。

© www.soinside.com 2019 - 2024. All rights reserved.