“ mov%eax,%db0”的分段错误

时间:2018-10-24 11:55:00

标签: c assembly gdb

我正在尝试动态创建硬件观察点,为此,我正在程序中设置调试寄存器。我仅使用dr0,并且选择的长度为3(对齐的4个字节),类型为1(写时中断)。我的cpu是Intel x86_it。但是,在每次运行中,每当我尝试写入db0 / dr0时,我都会看到segfault。令人讨厌的功能及其从gdb的汇编如下所示。

int watchpoint(void* addr)
{
    unsigned long value = (unsigned long) addr;
    asm("mov %0, %%dr0"     ::"r" (0));
    asm("mov %0, %%dr7"     ::"r" (0));
    asm("mov %0, %%dr0"     ::"r" (value));
    asm("mov %0, %%dr7"     ::"r" (851969));
    return 0;
}



   0x0832aa38 <+0>:     push   %ebp
   0x0832aa39 <+1>:     mov    %esp,%ebp
   0x0832aa3b <+3>:     sub    $0x10,%esp
   0x0832aa3e <+6>:     mov    0x8(%ebp),%eax
   0x0832aa41 <+9>:     mov    %eax,-0x4(%ebp)
   0x0832aa44 <+12>:    mov    $0x0,%eax
=> 0x0832aa49 <+17>:    mov    %eax,%db0  >>>>> Crashes here.
   0x0832aa4c <+20>:    mov    $0x0,%eax
   0x0832aa51 <+25>:    mov    %eax,%db7
   0x0832aa54 <+28>:    mov    -0x4(%ebp),%eax
   0x0832aa57 <+31>:    mov    %eax,%db0
   0x0832aa5a <+34>:    mov    $0xd0001,%eax
   0x0832aa5f <+39>:    mov    %eax,%db7
   0x0832aa62 <+42>:    mov    $0x0,%eax
   0x0832aa67 <+47>:    leave
   0x0832aa68 <+48>:    ret

我写错了寄存器吗?有人可以帮忙吗?

谢谢。

1 个答案:

答案 0 :(得分:2)

http://felixcloutier.com/x86/MOV-2.htmlmov用于调试寄存器)说:

  

#GP(0)如果当前特权级别不为0。

用户空间代码在环3(特权级别3)中运行。 root特权只是软件而已;它仍然是纯响3。

Linux iopl系统调用可以提高x86硬件I / O特权级别,但这只会影响诸如in / outcli / { {1}}。调试寄存器的MOV并不是其中之一。


在Linux下,您可以编写自己的内核模块,也可以使用sti系统调用来设置断点。

在其他操作系统下,您会找到调试器可以使用的其他API。