You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
pwndbg/gef/regs.py

160 lines
5.0 KiB
Python

import gdb
import sys
from types import ModuleType
import gef.memoize
import gef.arch
class RegisterSet(object):
def __init__(self, pc, stack, frame, retaddr, flags, gpr, misc):
self.pc = pc
self.stack = stack
self.frame = frame
self.retaddr = retaddr
self.flags = flags
self.gpr = gpr
self.misc = misc
arm = RegisterSet('pc',
'sp',
None,
('lr',),
('cpsr',),
('r0','r1','r2','r3','r4','r5','r6','r7','r8','r9','r10','r11','r12'),
None)
amd64 = RegisterSet('rip',
'rsp',
'rbp',
None,
('eflags',),
('rax','rbx','rcx','rdx','rdi','rsi',
'r8', 'r9', 'r10','r11','r12',
'r13','r14','r15'),
('cs','ss','ds','es','fs','gs'))
i386 = RegisterSet('eip',
'esp',
'ebp',
None,
('eflags',),
('eax','ebx','ecx','edx','edi','esi'),
('cs','ss','ds','es','fs','gs'))
# http://math-atlas.sourceforge.net/devel/assembly/elfspec_ppc.pdf
# r0 Volatile register which may be modified during function linkage
# r1 Stack frame pointer, always valid
# r2 System-reserved register (points at GOT)
# r3-r4 Volatile registers used for parameter passing and return values
# r5-r10 Volatile registers used for parameter passing
# r11-r12 Volatile registers which may be modified during function linkage
# 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',
'r1',
('lr','r0'),
('msr','xer'),
tuple('r%i' % i for i in range(3,32)),
('cr','lr','trap','r2'))
# http://people.cs.clemson.edu/~mark/sparc/sparc_arch_desc.txt
# http://people.cs.clemson.edu/~mark/subroutines/sparc.html
# https://www.utdallas.edu/~edsha/security/sparcoverflow.htm
#
# http://people.cs.clemson.edu/~mark/sparc/assembly.txt
# ____________________________________
# %g0 == %r0 (always zero) \
# %g1 == %r1 | g stands for global
# ... |
# %g7 == %r7 |
# ____________________________________/
# %o0 == %r8 \
# ... | o stands for output (note: not 0)
# %o6 == %r14 == %sp (stack ptr) |
# %o7 == %r15 == for return address |
# ____________________________________/
# %l0 == %r16 \
# ... | l stands for local (note: not 1)
# %l7 == %r23 |
# ____________________________________/
# %i0 == %r24 \
# ... | i stands for input
# %i6 == %r30 == %fp (frame ptr) |
# %i7 == %r31 == for return address |
# ____________________________________/
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,
None)
# http://logos.cs.uic.edu/366/notes/mips%20quick%20tutorial.htm
# r0 => zero
# r1 => temporary
# r2-r3 => values
# r4-r7 => arguments
# r8-r15 => temporary
# r16-r23 => saved values
# r24-r25 => temporary
# r26-r27 => interrupt/trap handler
# r28 => global pointer
# r29 => stack pointer
# r30 => frame pointer
# r31 => return address
mips = RegisterSet('pc',
'r29',
'r30',
('r31',),
None,
('r%i' for i in range(1,26)),
None)
arch_to_regs = {
'i386': i386,
'i386:x86-64': amd64,
'mips': mips,
'sparc': sparc,
'arm': arm,
'aarch64': arm,
'powerpc:403': powerpc,
'powerpc:common64': powerpc,
}
class module(ModuleType):
def __getattr__(self, attr):
try:
value = int(gdb.parse_and_eval('$' + attr.lstrip('$')))
return value & gef.arch.ptrmask
except gdb.error:
return 0
def __getitem__(self, item):
return getattr(self, item)
@property
def gpr(self):
return arch_to_regs[gef.arch.current].gpr
@property
def frame(self):
return arch_to_regs[gef.arch.current].frame
@property
def retaddr(self):
return arch_to_regs[gef.arch.current].retaddr
# To prevent garbage collection
tether = sys.modules[__name__]
sys.modules[__name__] = module(__name__, '')