diff --git a/pwndbg/__init__.py b/pwndbg/__init__.py index dd3109c2d..89c915117 100644 --- a/pwndbg/__init__.py +++ b/pwndbg/__init__.py @@ -39,6 +39,7 @@ import pwndbg.commands.rop import pwndbg.commands.shell import pwndbg.commands.aslr import pwndbg.commands.misc +import pwndbg.commands.next __all__ = [ 'arch', diff --git a/pwndbg/commands/next.py b/pwndbg/commands/next.py index b857b656d..abc6e353c 100644 --- a/pwndbg/commands/next.py +++ b/pwndbg/commands/next.py @@ -3,7 +3,32 @@ """ Stepping until an event occurs """ +import gdb +import pwndbg.commands +import pwndbg.next + +@pwndbg.commands.Command +@pwndbg.commands.OnlyWhenRunning +def nextjmp(*args): + pwndbg.next.break_next_branch() + +@pwndbg.commands.Command +@pwndbg.commands.OnlyWhenRunning +def nextj(*args): + nextjmp(*args) + +@pwndbg.commands.Command +@pwndbg.commands.OnlyWhenRunning +def nextjump(*args): + nextjmp(*args) @pwndbg.commands.Command @pwndbg.commands.OnlyWhenRunning def nextcall(*args): + pwndbg.next.break_next_call() + +@pwndbg.commands.Command +@pwndbg.commands.OnlyWhenRunning +def nextc(*args): + nextcall(*args) + diff --git a/pwndbg/next.py b/pwndbg/next.py index 773b704f3..390d1a241 100644 --- a/pwndbg/next.py +++ b/pwndbg/next.py @@ -8,11 +8,45 @@ import gdb import pwndbg.disasm import pwndbg.regs +import capstone -def next_branch(callback, address=None): +jumps = set(( + capstone.CS_GRP_CALL, + capstone.CS_GRP_JUMP, + capstone.CS_GRP_RET, + capstone.CS_GRP_IRET +)) + +def next_branch(address=None): if address is None: - address = pwndbg.regs.pc + ins = pwndbg.disasm.one(pwndbg.regs.pc) + if not ins: + return None + address = ins.next + + ins = pwndbg.disasm.one(address) + while ins: + if set(ins.groups) & jumps: + return ins + ins = pwndbg.disasm.one(ins.next) + + return None + +def break_next_branch(address=None): + ins = next_branch(address) + + if ins: + gdb.Breakpoint("*%#x" % ins.address, temporary=True) + gdb.execute('continue') + return ins + +def break_next_call(address=None): + while True: + ins = break_next_branch(address) + + if not ins: + break + + if capstone.CS_GRP_CALL in ins.groups: + return ins - # Disassemble forward until we find *any* branch instruction - # Set a temporary, internal breakpoint on it so the user is - # not bothered.