Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to break on instruction with a specific opcode in GDB?

I have the assembly code of some code that will be executed at a point in the program. I don't know the address of the code in memory.

Is it possible to make gdb break when the current instruction matches with an inputted instruction?

For example I want gdb to break whenever gdb reaches this instruction:

leaq        0x000008eb(%rip),%rax
like image 467
Tyilo Avatar asked Dec 25 '12 15:12

Tyilo


People also ask

How do I set a break in GDB?

You can also set breakpoints on function names. To do this, just type "break [functionname]". gdb will stop your program just before that function is called. Breakpoints stay set when your program ends, so you do not have to reset them unless you quit gdb and restart it.

How do you break a loop in GDB?

Like you can cancel a program on the command line, GDB lets you use ctrl-c to stop a program wherever it currently is. Hit ctrl-c now to break the infinite loop.

How do I list breakpoints in GDB?

You can see these breakpoints with the GDB maintenance command `maint info breakpoints' . Using the same format as `info breakpoints' , display both the breakpoints you've set explicitly, and those GDB is using for internal purposes. Internal breakpoints are shown with negative breakpoint numbers.

What does jump do in GDB?

Description. This command jumps the program counter to the specified location. The debugger resumes program execution at that point unless it encounters a breakpoint there.


1 Answers

As others said, it is likely impossible to do it efficiently because there is no hardware support.

But if you really want to do it, this Python command can serve as a starting point. The program single steps until a function with given opcode is given. Since execution returns to python for every instruction, this will be unusably slow slow if the target instruction is too many instructions away. But for a more or less nearby call, it should work fine.

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()

Just source it with:

source gdb.py

and use the command as:

ci mov
ci callq

and you will be left on the fist instruction executed with a given opcode.

TODO: this will ignore your other breakpoints.

For the particular common case of syscall, you can use catch syscall: https://reverseengineering.stackexchange.com/questions/6835/setting-a-breakpoint-at-system-call