From c6347c6bd6a8da274036f94ab1e7b11874a0ddce Mon Sep 17 00:00:00 2001 From: Zach Riggle Date: Sat, 16 May 2015 03:01:10 -0400 Subject: [PATCH] WIPWIPWIP --- pwndbg/__init__.py | 1 + pwndbg/arch.py | 18 +++- pwndbg/commands/next.py | 9 ++ pwndbg/disasm/__init__.py | 24 ++++- pwndbg/disasm/arch.py | 89 +++++++++++++++++ pwndbg/disasm/arm.py | 73 ++++++++++++++ pwndbg/disasm/x86.py | 92 ++++++++++++++++-- pwndbg/disasm_powerpc.py | 100 ------------------- pwndbg/memoize.py | 11 +++ pwndbg/regs.py | 199 ++++++++++++++++++++++---------------- 10 files changed, 415 insertions(+), 201 deletions(-) create mode 100644 pwndbg/commands/next.py create mode 100644 pwndbg/disasm/arch.py delete mode 100644 pwndbg/disasm_powerpc.py diff --git a/pwndbg/__init__.py b/pwndbg/__init__.py index 0fdd26fc6..8cb237d55 100644 --- a/pwndbg/__init__.py +++ b/pwndbg/__init__.py @@ -1,6 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- import gdb +import pwndbg.disasm import pwndbg.arch import pwndbg.arguments import pwndbg.vmmap diff --git a/pwndbg/arch.py b/pwndbg/arch.py index eb0fcb88c..e446ed90a 100644 --- a/pwndbg/arch.py +++ b/pwndbg/arch.py @@ -1,17 +1,23 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +import collections import struct import sys import gdb import pwndbg.events import pwndbg.memoize +import pwndbg.memory +import pwndbg.regs import pwndbg.typeinfo +from capstone import * + current = 'i386' ptrmask = 0xfffffffff endian = 'little' ptrsize = pwndbg.typeinfo.ptrsize fmt = '=i' -disasm = lambda: None def fix_arch(arch): arches = ['x86-64', 'i386', 'mips', 'powerpc', 'sparc', 'arm', 'aarch64', arch] @@ -37,11 +43,15 @@ def update(): (8, 'big'): '>Q', }.get((m.ptrsize, m.endian)) - m.disasm = gdb.selected_frame().architecture().disassemble - - def pack(integer): return struct.pack(fmt, integer & ptrmask) def unpack(data): return struct.unpack(fmt, data)[0] + +def signed(integer): + return unpack(pack(integer), signed=True) + +def unsigned(integer): + return unpack(pack(integer)) + diff --git a/pwndbg/commands/next.py b/pwndbg/commands/next.py new file mode 100644 index 000000000..b857b656d --- /dev/null +++ b/pwndbg/commands/next.py @@ -0,0 +1,9 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +Stepping until an event occurs +""" + +@pwndbg.commands.Command +@pwndbg.commands.OnlyWhenRunning +def nextcall(*args): diff --git a/pwndbg/disasm/__init__.py b/pwndbg/disasm/__init__.py index 4889eb21a..656241527 100644 --- a/pwndbg/disasm/__init__.py +++ b/pwndbg/disasm/__init__.py @@ -8,12 +8,13 @@ import collections import gdb import pwndbg.arch -import pwndbg.disasm.mips +import pwndbg.disasm.arch import pwndbg.disasm.arm -import pwndbg.disasm.ppc -import pwndbg.disasm.x86 import pwndbg.disasm.jump +import pwndbg.disasm.mips +import pwndbg.disasm.ppc import pwndbg.disasm.sparc +import pwndbg.disasm.x86 import pwndbg.ida import pwndbg.memory import pwndbg.symbol @@ -55,6 +56,23 @@ VariableInstructionSizeMax = { backward_cache = {} +def get_assistant(): + return { + 'i386': pwndbg.disasm.x86.assistant, + 'x86-64': pwndbg.disasm.x86.assistant, + 'arm': pwndbg.disasm.arm.assistant + }.get(pwndbg.arch.current, lambda *a: None)(instruction) + +def get_operands(instruction): + """ + IFF instruction is the next instruction to be executed, + return an OrderedDict which maps the operand names to + their current values. + + Otherwise, returns an empty dict. + """ + if instruction.address != pwndbg.regs.pc: + return {} def get_target(instruction): """ diff --git a/pwndbg/disasm/arch.py b/pwndbg/disasm/arch.py new file mode 100644 index 000000000..0e453b450 --- /dev/null +++ b/pwndbg/disasm/arch.py @@ -0,0 +1,89 @@ + + +groups = {v:k for k,v in globals().items() if k.startswith('CS_GRP_')} +ops = {v:k for k,v in globals().items() if k.startswith('CS_OP_')} +access = {v:k for k,v in globals().items() if k.startswith('CS_AC_')} + +for value1, name1 in access.items(): + for value2, name2 in access.items(): + access.setdefault(value1 | value2, '%s | %s' % (name1, name2)) + +class DisassemblyAssistant(object): + def __init__(self): + self.op_handlers = { + CS_OP_IMM: self.immediate, + CS_OP_REG: self.register, + CS_OP_MEM: self.memory + } + + self.op_names = { + CS_OP_IMM: self.immediate_sz, + CS_OP_REG: self.register_sz, + CS_OP_MEM: self.memory_sz + } + + def operands(self, instruction): + current = (instruction.address == pwndbg.regs.pc) + + rv = collections.OrderedDict() + + for i, op in enumerate(instruction.operands): + T = op.type + + if not current or T not in op_handlers: + rv['op%i' % i] = None + continue + + result = self.op_handlers[T](instruction, op) + + if result is not None: + rv[self.op_names[T]] = result + + return rv + + def immediate(self, instruction, operand): + return operand.value.imm + + def immediate_sz(self, instruction, operand): + return "%#x" % self.immediate(instruction, operand) + + def register(self, instruction, operand): + # Don't care about registers which are only overwritten + if operand.access & CS_AC_READ == 0: + return None + + reg = operand.value.reg + name = instruction.reg_name(reg) + + return pwndbg.regsisters[name] + + def register_sz(self, instruction, operand): + reg = operand.value.reg + return instruction.reg_name(reg).lower() + + def memory(self, instruction, operand): + return None + + def memory_sz(self, instruction, operand): + raise NotImplementedError + + def dump(self, instruction): + ins = instruction + rv = [] + rv.append('%s %s' % (ins.mnemonic,ins.op_str)) + + for i, group in enumerate(ins.groups): + rv.append(' groups[%i] = %s' % (i, groups[group])) + + ops = self.operands(instruction) + + for i, ((name, value), op) in enumerate(zip(ops.items(), ins.operands)): + rv.append(' operands[%i] = %s' % (i, ops[op.type])) + rv.append(' access = %s' % (get_access(op.access))) + + if None not in (name, value): + rv.append(' %s = %#x' % (name, value)) + + return '\n'.join(rv) + +assistant = DisassemblyAssistant() \ No newline at end of file diff --git a/pwndbg/disasm/arm.py b/pwndbg/disasm/arm.py index e69de29bb..747e66286 100644 --- a/pwndbg/disasm/arm.py +++ b/pwndbg/disasm/arm.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +import collections + +import pwndbg.arch +import pwndbg.disasm.arch +import pwndbg.memory +import pwndbg.regs + +from capstone import * +from capstone.arm import * + +import pwndbg.disasm.arch + +import pdb +pdb.set_trace() + +class DisassemblyAssistant(pwndbg.disasm.arch.DisassemblyAssistant): + def memory_sz(self, instruction, operand): + segment = '' + parts = [] + + if op.mem.base != 0: + parts.append(instruction.reg_name(op.mem.base)) + + if op.mem.disp != 0: + parts.append("%#x" % op.value.mem.disp) + + if op.mem.index != 0: + index = pwndbg.regs[instruction.reg_name(op.mem.index)] + scale = op.mem.scale + parts.append("%s*%#x" % (index, scale)) + + return "[%s]" % (segment, ', '.join(parts)) + + def immediate_sz(self, instruction, operand): + imm = self.immediate(instruction, operand) + imm = self.arch.signed(imm) + + if abs(imm) < 0x10: + return '#%i' % imm + + return '#%#x' % imm + +assistant = DisassemblyAssistant() + +def is_jump_taken(instruction): + cpsr = pwndbg.regs.cpsr + + N = cpsr & (1<<31) + Z = cpsr & (1<<30) + C = cpsr & (1<<29) + V = cpsr & (1<<28) + + return { + ARM_CC_EQ: Z, + ARM_CC_NE: not Z, + ARM_CC_HS: C, + ARM_CC_LO: not C, + ARM_CC_MI: N, + ARM_CC_PL: not N, + ARM_CC_VS: V, + ARM_CC_VC: not V, + ARM_CC_HI: C and not Z, + ARM_CC_LS: Z or not C, + ARM_CC_GE: N == V, + 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) + +is_condition_true = is_jump_taken diff --git a/pwndbg/disasm/x86.py b/pwndbg/disasm/x86.py index 03df74941..e92d1fc06 100644 --- a/pwndbg/disasm/x86.py +++ b/pwndbg/disasm/x86.py @@ -1,5 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- +import collections + import pwndbg.arch import pwndbg.memory import pwndbg.regs @@ -12,6 +14,30 @@ ops = {v:k for k,v in globals().items() if k.startswith('X86_OP_')} regs = {v:k for k,v in globals().items() if k.startswith('X86_REG_')} access = {v:k for k,v in globals().items() if k.startswith('CS_AC_')} +class DisassemblyAssistant(pwndbg.disasm.arch.DisassemblyAssistant): + def memory_sz(self, instruction, operand): + segment = '' + parts = [] + + if op.mem.segment != 0: + segment = '%s:' % instructions.reg_name(op.mem.segment) + + + if op.mem.base != 0: + parts.append(instruction.reg_name(op.mem.base)) + + if op.mem.disp != 0: + parts.append("%#x" % op.value.mem.disp) + + if op.mem.index != 0: + index = pwndbg.regs[instruction.reg_name(op.mem.index)] + scale = op.mem.scale + parts.append("%s*%#x" % (index, scale)) + + return "%s[%s]" % (segment, ' + '.join(parts)) + +assistant = DisassemblyAssistant() + def is_memory_op(op): return op.type == X86_OP_MEM @@ -21,16 +47,16 @@ def get_access(ac): if ac & k: rv.append(v) return ' | '.join(rv) -def dump(instruction): - ins = instruction - rv = [] - rv.append('%s %s' % (ins.mnemonic,ins.op_str)) - for i, group in enumerate(ins.groups): - rv.append(' groups[%i] = %s' % (i, groups[group])) - for i, op in enumerate(ins.operands): - rv.append(' operands[%i] = %s' % (i, ops[op.type])) - rv.append(' access = %s' % (get_access(op.access))) - return '\n'.join(rv) + def dump(self, instruction): + ins = instruction + rv = [] + rv.append('%s %s' % (ins.mnemonic,ins.op_str)) + for i, group in enumerate(ins.groups): + rv.append(' groups[%i] = %s' % (i, groups[group])) + for i, op in enumerate(ins.operands): + rv.append(' operands[%i] = %s' % (i, ops[op.type])) + rv.append(' access = %s' % (get_access(op.access))) + return '\n'.join(rv) def resolve(instruction): ops = list(instruction.operands) @@ -61,6 +87,52 @@ def resolve(instruction): print("Weird number of operands!!!!!") print(dump(instruction)) +def register(i, op): + assert CS_OP_REG == op.type + regname = instruction.reg_name(op.value.reg) + return pwndbg.regs[regname] + +def immediate(i, op): + assert CS_OP_IMM == op.type + return op.value.imm + +def memory(): + current = (instruction.address == pwndbg.regs.pc) + + constant = bool(op.mem.base == 0 and op.mem.index == 0) + if not current and not constant: + return (None, False) + + if op.mem.segment != 0: + return (None, False) + + if op.mem.base != 0: + regname = instruction.reg_name(op.mem.base) + target += pwndbg.regs[regname] + + if op.mem.disp != 0: + target += op.value.mem.disp + + if op.mem.index != 0: + scale = op.mem.scale + index = pwndbg.regs[instruction.reg_name(op.mem.index)] + target += (scale * index) + + # for source operands, resolve + if op.access == CS_AC_READ: + try: + target = pwndbg.memory.u(target, op.size * 8) + except: + return (None, False) + + return (target, constant) + +resolvers = { + CS_OP_REG: register, + CS_OP_IMM: immediate, + CS_OP_MEM: memory +} + def get_operand_target(instruction, op): current = (instruction.address == pwndbg.regs.pc) diff --git a/pwndbg/disasm_powerpc.py b/pwndbg/disasm_powerpc.py deleted file mode 100644 index 0f986d07a..000000000 --- a/pwndbg/disasm_powerpc.py +++ /dev/null @@ -1,100 +0,0 @@ -# Table stolen from -# http://ps-2.kev009.com/wisclibrary/aix52/usr/share/man/info/en_US/a_doc_lib/aixassem/alangref/branch_mnem.htm -powerpc = """ - bc+ bc- bca+ bca- - bcctr+ bcctr- bcctrl+ bcctrl- - bcl+ bcl- bcla+ bcla- - bclr+ bclr- bclrl+ bclrl- - bdneq+ bdneq- bdnge+ bdnge- - bdngt+ bdngt- bdnle+ bdnle- - bdnlt+ bdnlt- bdnne+ bdnne- - bdnns+ bdnns- bdnso+ bdnso- - bdnz+ bdnz- bdnza+ bdnza- - bdnzf+ bdnzf- bdnzfa+ bdnzfa- - bdnzfl+ bdnzfl- bdnzfla+ bdnzfla- - bdnzflr+ bdnzflr- bdnzflrl+ bdnzflrl- - bdnzl+ bdnzl- bdnzla+ bdnzla- - bdnzlr+ bdnzlr- bdnzlrl+ bdnzlrl- - bdnzt+ bdnzt- bdnzta+ bdnzta- - bdnztl+ bdnztl- bdnztla+ bdnztla- - bdnztlr+ bdnztlr- bdnztlrl+ bdnztlrl- - bdz+ bdz- bdza+ bdza- - bdzeq+ bdzeq- bdzf+ bdzf- - bdzfa+ bdzfa- bdzfl+ bdzfl- - bdzfla+ bdzfla- bdzflr+ bdzflr- - bdzflrl+ bdzflrl- bdzge+ bdzge- - bdzgt+ bdzgt- bdzl+ bdzl- - bdzla+ bdzla- bdzle+ bdzle- - bdzlr+ bdzlr- bdzlrl+ bdzlrl- - bdzlt+ bdzlt- bdzne+ bdzne- - bdzns+ bdzns- bdzso+ bdzso- - bdzt+ bdzt- bdzta+ bdzta- - bdztl+ bdztl- bdztla+ bdztla- - bdztlr+ bdztlr- bdztlrl+ bdztlrl- - beq+ beq- beqa+ beqa- - beqctr+ beqctr- beqctrl+ beqctrl- - beql+ beql- beqla+ beqla- - beqlr+ beqlr- beqlrl+ beqlrl- - bf+ bf- bfa+ bfa- - bfctr+ bfctr- bfctrl+ bfctrl- - bfl+ bfl- bfla+ bfla- - bflr+ bflr- bflrl+ bflrl- - bge+ bge- bgea+ bgea- - bgectr+ bgectr- bgectrl+ bgectrl- - bgel+ bgel- bgela+ bgela- - bgelr+ bgelr- bgelrl+ bgelrl- - bgt+ bgt- bgta+ bgta- - bgtctr+ bgtctr- bgtctrl+ bgtctrl- - bgtl+ bgtl- bgtla+ bgtla- - bgtlr+ bgtlr- bgtlrl+ bgtlrl- - ble+ ble- blea+ blea- - blectr+ blectr- blectrl+ blectrl- - blel+ blel- blela+ blela- - blelr+ blelr- blelrl+ blelrl- - blt+ blt- blta+ blta- - bltctr+ bltctr- bltctrl+ bltctrl- - bltl+ bltl- bltla+ bltla- - bltlr+ bltlr- bltlrl+ bltlrl- - bne+ bne- bnea+ bnea- - bnectr+ bnectr- bnectrl+ bnectrl- - bnel+ bnel- bnela+ bnela- - bnelr+ bnelr- bnelrl+ bnelrl- - bng+ bng- bnga+ bnga- - bngctr+ bngctr- bngctrl+ bngctrl- - bngl+ bngl- bngla+ bngla- - bnglr+ bnglr- bnglrl+ bnglrl- - bnl+ bnl- bnla+ bnla- - bnlctr+ bnlctr- bnlctrl+ bnlctrl- - bnll+ bnll- bnlla+ bnlla- - bnllr+ bnllr- bnllrl+ bnllrl- - bns+ bns- bnsa+ bnsa- - bnsctr+ bnsctr- bnsctrl+ bnsctrl- - bnsl+ bnsl- bnsla+ bnsla- - bnslr+ bnslr- bnslrl+ bnslrl- - bnu+ bnu- bnua+ bnua- - bnuctr+ bnuctr- bnuctrl+ bnuctrl- - bnul+ bnul- bnula+ bnula- - bnulr+ bnulr- bnulrl+ bnulrl- - bnz+ bnz- bnza+ bnza- - bnzctr+ bnzctr- bnzctrl+ bnzctrl- - bnzl+ bnzl- bnzla+ bnzla- - bnzlr+ bnzlr- bnzlrl+ bnzlrl- - bso+ bso- bsoa+ bsoa- - bsoctr+ bsoctr- bsoctrl+ bsoctrl- - bsol+ bsol- bsola+ bsola- - bsolr+ bsolr- bsolrl+ bsolrl- - bt+ bt- bta+ bta- - btctr+ btctr- btctrl+ btctrl- - btl+ btl- btla+ btla- - btlr+ btlr- btlrl+ btlrl- - bun+ bun- buna+ buna- - bunctr+ bunctr- bunctrl+ bunctrl- - bunl+ bunl- bunla+ bunla- - bunlr+ bunlr- bunlrl+ bunlrl- - bz+ bz- bza+ bza- - bzctr+ bzctr- bzctrl+ bzctrl- - bzl+ bzl- bzla+ bzla- - bzlr+ bzlr- bzlrl+ bzlrl- -""".strip().split() - -branches = set(map(lambda x: x.rstrip('+-'), powerpc)) diff --git a/pwndbg/memoize.py b/pwndbg/memoize.py index 11ec0c249..a17f7b039 100644 --- a/pwndbg/memoize.py +++ b/pwndbg/memoize.py @@ -106,6 +106,17 @@ class reset_on_start(memoize): for obj in reset_on_start.caches: obj.clear() +class reset_on_cont(memoize): + caches = [] + kind = 'cont' + + @staticmethod + @pwndbg.events.cont + def __reset(): + for obj in reset_on_cont.caches: + obj.clear() + + class while_running(memoize): caches = [] kind = 'running' diff --git a/pwndbg/regs.py b/pwndbg/regs.py index d44d7cc38..1ae8cf8ab 100644 --- a/pwndbg/regs.py +++ b/pwndbg/regs.py @@ -16,19 +16,61 @@ import pwndbg.memoize class RegisterSet(object): - def __init__(self, pc, stack, frame, retaddr, flags, gpr, misc, args, retval): - self.pc = pc + #: Program counter register + pc = None + + #: Stack pointer register + stack = None + + #: Frame pointer register + frame = None + + #: Return address register + retaddr = None + + #: Flags register (eflags, cpsr) + flags = None + + #: List of native-size generalp-purpose registers + gpr = None + + #: List of miscellaneous, valid registers + misc = None + + #: Register-based arguments for most common ABI + regs = None + + #: Return value register + retval = None + + #: Common registers which should be displayed in the register context + common = None + + #: All valid registers + all = None + + def __init__(self, + pc='pc', + stack='sp', + frame=None, + retaddr=tuple(), + flags=tuple(), + gpr=tuple(), + misc=tuple(), + args=tuple(), + retval=None): + self.pc = pc self.stack = stack self.frame = frame self.retaddr = retaddr - self.flags = flags - self.gpr = gpr - self.misc = misc - self.args = args + self.flags = flags + self.gpr = gpr + self.misc = misc + self.args = args self.retval = retval self.common = set(i for i in gpr + (frame, stack, pc) if i) - self.all = set(i for i in misc or tuple()) | set(flags or tuple()) | self.common + self.all = set(i for i in misc) | set(flags) | self.common self.common -= {None} self.all -= {None} @@ -37,54 +79,50 @@ class RegisterSet(object): for r in self.all: yield r -arm = RegisterSet( 'pc', - 'sp', - None, - ('lr',), - ('cpsr',), - ('r0','r1','r2','r3','r4','r5','r6','r7','r8','r9','r10','r11','r12'), - tuple(), - ('r0','r1','r2','r3'), - 'r0') - -aarch64 = RegisterSet('pc', - 'sp', - None, - ('lr',), - ('cpsr',), - ('x0','x1','x2','x3','x4','x5','x6','x7','x8','x9','x10','x11','x12'), - tuple(), - ('x0','x1','x2','x3'), - 'x0') - - -amd64 = RegisterSet('rip', - 'rsp', - 'rbp', - tuple(), - ('eflags',), - ('rax','rbx','rcx','rdx','rdi','rsi', - 'r8', 'r9', 'r10','r11','r12', - 'r13','r14','r15'), - ('cs','ss','ds','es','fs','gs'), - ('rdi','rsi','rdx','rcx','r8','r9'), - 'rax') - -i386 = RegisterSet('eip', - 'esp', - 'ebp', - tuple(), - ('eflags',), - ('eax','ebx','ecx','edx','edi','esi'), - ('cs','ss','ds','es','fs','gs'), - ('*((void**)$sp+0)', - '*((void**)$sp+1)', - '*((void**)$sp+2)', - '*((void**)$sp+3)', - '*((void**)$sp+4)', - '*((void**)$sp+5)', - '*((void**)$sp+6)',), - 'eax') +arm = RegisterSet( retaddr = ('lr',), + flags = ('cpsr',), + gpr = tuple('r%i' % i for i in range(13)), + args = ('r0','r1','r2','r3'), + retval = 'r0') + +aarch64 = RegisterSet( retaddr = ('lr',), + flags = ('cpsr',), + gpr = tuple('x%i' % i for i in range(32)), + misc = tuple('w%i' % i for i in range(32)), + args = ('x0','x1','x2','x3'), + retval = 'x0') + + +amd64 = RegisterSet(pc = 'rip', + stack = 'rsp', + frame = 'rbp', + flags = ('eflags',), + gpr = ('rax','rbx','rcx','rdx','rdi','rsi', + 'r8', 'r9', 'r10','r11','r12', + 'r13','r14','r15'), + misc = ('cs','ss','ds','es','fs','gs', + 'ax','ah','al', + 'bx','bh','bl', + 'cx','ch','cl', + 'dx','dh','dl', + 'dil','sil','spl','bpl', + 'di','si','bp','sp','ip'), + args = ('rdi','rsi','rdx','rcx','r8','r9'), + retval = 'rax') + +i386 = RegisterSet( pc = 'eip', + stack = 'esp', + frame = 'ebp', + flags = ('eflags',), + gpr = ('eax','ebx','ecx','edx','edi','esi'), + misc = ('cs','ss','ds','es','fs','gs', + 'ax','ah','al', + 'bx','bh','bl', + 'cx','ch','cl', + 'dx','dh','dl', + 'dil','sil','spl','bpl', + 'di','si','bp','sp','ip'), + retval = 'eax') # http://math-atlas.sourceforge.net/devel/assembly/elfspec_ppc.pdf @@ -97,15 +135,12 @@ i386 = RegisterSet('eip', # r13 Small data area pointer register (points to TLS) # r14-r30 Registers used for local variables # r31 Used for local variables or "environment pointers" -powerpc = RegisterSet('pc', - 'sp', - None, - ('lr','r0'), - ('msr','xer'), - tuple('r%i' % i for i in range(3,32)), - ('cr','lr','r2'), - tuple(), - 'r3') +powerpc = RegisterSet( retaddr = ('lr','r0'), + flags = ('msr','xer'), + gpr = tuple('r%i' % i for i in range(3,32)), + misc = ('cr','lr','r2'), + args = tuple('r%i' for i in range(3,11)), + retval = 'r3') # http://people.cs.clemson.edu/~mark/sparc/sparc_arch_desc.txt # http://people.cs.clemson.edu/~mark/subroutines/sparc.html @@ -137,15 +172,13 @@ sparc_gp = tuple(['g%i' % i for i in range(1,8)] +['o%i' % i for i in range(0,6)] +['l%i' % i for i in range(0,8)] +['i%i' % i for i in range(0,6)]) -sparc = RegisterSet('pc', - 'o6', - 'i6', - ('o7',), - ('psr',), - sparc_gp, - tuple(), - ('i0','i1','i2','i3','i4','i5'), - 'o0') +sparc = RegisterSet(stack = 'o6', + frame = 'i6', + retaddr = ('o7',), + flags = ('psr',), + gpr = sparc_gp, + args = ('i0','i1','i2','i3','i4','i5'), + retval = 'o0') # http://logos.cs.uic.edu/366/notes/mips%20quick%20tutorial.htm @@ -161,17 +194,13 @@ sparc = RegisterSet('pc', # r29 => stack pointer # r30 => frame pointer # r31 => return address -mips = RegisterSet( 'pc', - 'sp', - 'fp', - ('ra',), - tuple(), - ('v0','v1','a0','a1','a2','a3') \ - + tuple('t%i' % i for i in range(10)) \ - + tuple('s%i' % i for i in range(9)), - tuple(), - ('a0','a1','a2','a3'), - 'v0') +mips = RegisterSet( frame = 'fp', + retaddr = ('ra',), + gpr = ('v0','v1','a0','a1','a2','a3') \ + + tuple('t%i' % i for i in range(10)) \ + + tuple('s%i' % i for i in range(9)), + args = ('a0','a1','a2','a3'), + retval = 'v0') arch_to_regs = { 'i386': i386, @@ -188,6 +217,7 @@ arch_to_regs = { class module(ModuleType): last = {} + @pwndbg.memoize.reset_on_stop def __getattr__(self, attr): try: value = gdb.parse_and_eval('$' + attr.lstrip('$')) @@ -201,6 +231,7 @@ class module(ModuleType): except gdb.error: return None + @pwndbg.memoize.reset_on_stop def __getitem__(self, item): if isinstance(item, int): return arch_to_regs[pwndbg.arch.current][item]