From 77de7be3cedb6576e3c2390c06552e38d78ebdbb Mon Sep 17 00:00:00 2001 From: Zach Riggle Date: Sun, 17 May 2015 06:56:44 -0700 Subject: [PATCH] Add stepover, small fixes for ARM --- pwndbg/commands/next.py | 13 +++++++++++++ pwndbg/disasm/__init__.py | 4 ++++ pwndbg/disasm/arch.py | 2 +- pwndbg/disasm/arm.py | 19 ++++++++++--------- pwndbg/next.py | 10 +++++++++- 5 files changed, 37 insertions(+), 11 deletions(-) diff --git a/pwndbg/commands/next.py b/pwndbg/commands/next.py index 32f8a93c..f3d73d88 100644 --- a/pwndbg/commands/next.py +++ b/pwndbg/commands/next.py @@ -39,3 +39,16 @@ def nextc(*args): """Breaks at the next call instruction""" nextcall(*args) + +@pwndbg.commands.Command +@pwndbg.commands.OnlyWhenRunning +def stepover(*args): + """Sets a breakpoint on the instruction after this one""" + pwndbg.next.break_on_next(*args) + + +@pwndbg.commands.Command +@pwndbg.commands.OnlyWhenRunning +def so(*args): + stepover(*args) + diff --git a/pwndbg/disasm/__init__.py b/pwndbg/disasm/__init__.py index 4f57a7a2..ae22bf3e 100644 --- a/pwndbg/disasm/__init__.py +++ b/pwndbg/disasm/__init__.py @@ -118,6 +118,10 @@ def near(address, instructions=1): # Now find all of the instructions moving forward. insn = current while insn and len(insns) < 1+(2*instructions): + # In order to avoid annoying cycles where the current instruction + # is a branch, which evaluates to true, and jumps back a short + # number of instructions. + insn = one(insn.next) if insn: insns.append(insn) diff --git a/pwndbg/disasm/arch.py b/pwndbg/disasm/arch.py index cd2afd40..43065ef7 100644 --- a/pwndbg/disasm/arch.py +++ b/pwndbg/disasm/arch.py @@ -94,7 +94,7 @@ class DisassemblyAssistant(object): if next_addr is None: next_addr = instruction.address + instruction.size - instruction.next = next_addr + instruction.next = next_addr & pwndbg.arch.ptrmask def next(self, instruction): """ diff --git a/pwndbg/disasm/arm.py b/pwndbg/disasm/arm.py index edd29a78..d8423d41 100644 --- a/pwndbg/disasm/arm.py +++ b/pwndbg/disasm/arm.py @@ -14,7 +14,7 @@ import pwndbg.disasm.arch class DisassemblyAssistant(pwndbg.disasm.arch.DisassemblyAssistant): - def memory_sz(self, instruction, operand): + def memory_sz(self, instruction, op): segment = '' parts = [] @@ -29,18 +29,20 @@ class DisassemblyAssistant(pwndbg.disasm.arch.DisassemblyAssistant): scale = op.mem.scale parts.append("%s*%#x" % (index, scale)) - return "[%s]" % (segment, ', '.join(parts)) + return "[%s]" % (', '.join(parts)) def immediate_sz(self, instruction, operand): - imm = self.immediate(instruction, operand) - imm = self.arch.signed(imm) + return '#' + super(DisassemblyAssistant, self).immediate_sz(instruction, operand) - if abs(imm) < 0x10: - return '#%i' % imm + def condition(self, instruction): - return '#%#x' % imm + # We can't reason about anything except the current instruction + if instruction.cc == ARM_CC_AL: + return None + + if instruction.address != pwndbg.regs.pc: + return False - def taken(self, instruction): cpsr = pwndbg.regs.cpsr N = cpsr & (1<<31) @@ -63,7 +65,6 @@ class DisassemblyAssistant(pwndbg.disasm.arch.DisassemblyAssistant): ARM_CC_LT: N != V, ARM_CC_GT: not Z and (N==V), ARM_CC_LE: Z or (N != V), - # ARM_CC_AL: 1, }.get(instruction.id, None) assistant = DisassemblyAssistant('arm') diff --git a/pwndbg/next.py b/pwndbg/next.py index 97271eb7..0df98b7e 100644 --- a/pwndbg/next.py +++ b/pwndbg/next.py @@ -37,7 +37,7 @@ def break_next_branch(address=None): if ins: gdb.Breakpoint("*%#x" % ins.address, internal=True, temporary=True) - gdb.execute('continue') + gdb.execute('continue', from_tty=False, to_string=True) return ins def break_next_call(address=None): @@ -50,3 +50,11 @@ def break_next_call(address=None): if capstone.CS_GRP_CALL in ins.groups: return ins +def break_on_next(address=None): + address = address or pwndbg.regs.pc + ins = pwndbg.disasm.one(address) + + gdb.Breakpoint("*%#x" % (ins.address + ins.size), temporary=True) + gdb.execute('continue', from_tty=False, to_string=True) + +