如何在GDB中使用特定操作码中断指令?

Tyi*_*ilo 7 debugging gdb breakpoints

我有一些代码的汇编代码,将在程序中的某个点执行.我不知道内存中代码的地址.

当前指令与输入指令匹配时,是否可以使gdb中断?

例如,每当gdb到达此指令时,我希望gdb中断:

leaq        0x000008eb(%rip),%rax
Run Code Online (Sandbox Code Playgroud)

Cir*_*四事件 7

正如其他人所说,由于没有硬件支持,很可能无法有效地完成它.

但是如果你真的想这样做,这个Python命令可以作为一个起点:

class ContinueI(gdb.Command):
    """
Continue until instruction with given opcode.

    ci OPCODE

Example:

    ci callq
    ci mov
"""
    def __init__(self):
        super().__init__(
            'ci',
            gdb.COMMAND_BREAKPOINTS,
            gdb.COMPLETE_NONE,
            False
        )
    def invoke(self, arg, from_tty):
        if arg == '':
            gdb.write('Argument missing.\n')
        else:
            thread = gdb.inferiors()[0].threads()[0]
            while thread.is_valid():
                gdb.execute('si', to_string=True)
                frame = gdb.selected_frame()
                arch = frame.architecture()
                pc = gdb.selected_frame().pc()
                instruction = arch.disassemble(pc)[0]['asm']
                if instruction.startswith(arg + ' '):
                    gdb.write(instruction + '\n')
                    break
ContinueI()
Run Code Online (Sandbox Code Playgroud)

只需用它来源:

source gdb.py
Run Code Online (Sandbox Code Playgroud)

并使用命令:

breaki mov
breaki callq
Run Code Online (Sandbox Code Playgroud)

并且您将被留在使用给定操作码执行的第一条指令上.

TODO:这会忽略你的其他断点.

对于特殊情况syscall,您可以使用catch syscall:https://reverseengineering.stackexchange.com/questions/6835/setting-a-breakpoint-at-system-call


Mar*_*lig 2

不,这是不可能的,而且实施起来效率也很低。

调试器通常支持两种断点:

  • 硬件断点:当某些事件发生时,例如内存中的某些位置发生更改,调试器会要求 CPU 引发特殊的异常中断。
  • 软件断点:调试器用特殊的“陷阱”指令( x86 架构上的int 3/ )替换断点地址处的操作码。0xcc

匹配当前指令的操作码要么需要 CPU 支持来插入硬件断点,要么调试器需要知道使用软件断点的地址。

理论上,调试器可以在整个内存中搜索指令的字节序列,但由于字节序列也可能出现在指令或数据的中间,因此可能会出现误报。

由于汇编指令是可变长度的,控制可以跳转到任何任意地址,或者代码可以修改自身,因此反汇编整个内存区域以查找某些特定指令也并非易事。

因此基本上,在任意汇编代码中可靠地查找指令的唯一方法是在指令级别上单步执行。这将是非常昂贵的,printf()如果您单步执行每条指令,即使是一个微不足道的库调用(例如在当今的硬件上也可能需要几分钟的时间)。