Fixed line endings.

This commit is contained in:
Cody Brocious 2017-05-16 14:57:39 -06:00
parent bd045eeea7
commit 9591e6978e
8 changed files with 32915 additions and 32915 deletions

View file

@ -1,22 +1,22 @@
import struct
from glob import glob
mainaddr = raw_input('Enter main module address: ')
if mainaddr.startswith('0x'):
mainaddr = mainaddr[2:]
mainaddr = int(mainaddr, 16)
print 'Main at 0x%016x' % mainaddr
wkcaddr = raw_input('Enter wkc module address: ')
if wkcaddr.startswith('0x'):
wkcaddr = wkcaddr[2:]
wkcaddr = int(wkcaddr, 16)
print 'WKC at 0x%016x' % wkcaddr
with file('membundle.bin', 'wb') as fp:
files = glob('memdumps/*.bin')
fp.write(struct.pack('<IQQ', len(files), mainaddr, wkcaddr))
for fn in files:
addr = int(fn[11:].split(' ')[0], 16)
data = file(fn, 'rb').read()
fp.write(struct.pack('<QI', addr, len(data)))
fp.write(data)
import struct
from glob import glob
mainaddr = raw_input('Enter main module address: ')
if mainaddr.startswith('0x'):
mainaddr = mainaddr[2:]
mainaddr = int(mainaddr, 16)
print 'Main at 0x%016x' % mainaddr
wkcaddr = raw_input('Enter wkc module address: ')
if wkcaddr.startswith('0x'):
wkcaddr = wkcaddr[2:]
wkcaddr = int(wkcaddr, 16)
print 'WKC at 0x%016x' % wkcaddr
with file('membundle.bin', 'wb') as fp:
files = glob('memdumps/*.bin')
fp.write(struct.pack('<IQQ', len(files), mainaddr, wkcaddr))
for fn in files:
addr = int(fn[11:].split(' ')[0], 16)
data = file(fn, 'rb').read()
fp.write(struct.pack('<QI', addr, len(data)))
fp.write(data)

582
ceval.py
View file

@ -1,291 +1,291 @@
from pycparser.c_parser import CParser
from pycparser.c_ast import *
import struct
class AstTranslator(object):
def process(self, ast):
node = ast.__class__.__name__
if hasattr(self, node):
func = getattr(self, node)
fcode = func.im_func.func_code
argnames = fcode.co_varnames[1:fcode.co_argcount]
args = [getattr(ast, name) for name in argnames]
return func(*args)
else:
print 'Unhandled AST node:'
ast.show()
return '?unknown?'
def UnaryOp(self, op, expr):
opmap = {'*' : 'deref', '-' : 'neg', '!' : 'not', '~' : 'bnot'}
return opmap[op], self.process(expr)
def BinaryOp(self, op, left, right):
return op, self.process(left), self.process(right)
def Cast(self, to_type, expr):
return 'cast', self.process(to_type), self.process(expr)
def ID(self, name):
return 'register', name
def Typename(self, type):
return self.process(type)
def TypeDecl(self, type):
return self.process(type)
def IdentifierType(self, names):
return ' '.join(names)
def PtrDecl(self, type):
return 'ptr', self.process(type)
def ArrayRef(self, name, subscript):
return '[]', self.process(name), self.process(subscript)
def Constant(self, type, value):
if type == 'int':
if value.startswith('0x'):
return int(value[2:], 16)
elif value.startswith('0b'):
return int(value[2:], 2)
elif value.startswith('0'):
return int(value, 8)
else:
return int(value)
elif type == 'float':
return float(value)
else:
print 'Unknown constant type:', type, `value`
return '?unkconst?'
def Assignment(self, op, lvalue, rvalue):
lvalue = self.process(lvalue)
rvalue = self.process(rvalue)
if op != '=':
rvalue = op[0], lvalue, rvalue
return '=', lvalue, rvalue
dispatchers = {}
def ddp(name):
def sub(func):
dispatchers[name] = func
return func
if callable(name):
dispatchers[name.func_name] = name
return name
return sub
class Register(object):
def __init__(self, name):
self.name = name
def __repr__(self):
return self.name
class TypedValue(object):
def __init__(self, type, value):
self.type, self.value = type, value
while isinstance(self.value, TypedValue):
self.value = self.value.value
def __repr__(self):
return '%s:%r' % (self.type, self.value)
@property
def stride(self):
return int(self.type[1:].rstrip('*')) / 8
@property
def pointer(self):
return '*' in self.type
def bare(value):
if isinstance(value, TypedValue):
return value.value
else:
return value
def autotype(value):
if isinstance(value, TypedValue):
return value
elif isinstance(value, float):
return TypedValue('f64', value)
elif isinstance(value, str):
return value
else:
return TypedValue('i64', value)
class SexpRunner(object):
def __init__(self, ctu):
self.ctu = ctu
def run(self, sexp, rvalue=None):
if not isinstance(sexp, tuple):
return autotype(sexp)
if sexp[0] in dispatchers:
if rvalue is None:
return dispatchers[sexp[0]](self, *sexp[1:])
else:
return dispatchers[sexp[0]](self, *tuple(list(sexp[1:]) + [rvalue]))
else:
print 'Unhandled S-exp:', sexp
return None
@ddp('=')
def assign(self, left, right):
return self.run(left, self.run(right))
@ddp('[]')
def subscript(self, base, sub, ass=None):
base, sub = self.run(base), self.run(sub)
addr = bare(base) + bare(sub) * base.stride
return self.deref(TypedValue(base.type, addr), ass)
@ddp
def deref(self, ptr, ass=None):
ptr = self.run(ptr)
assert ptr.pointer
fmtmap = dict(u8='B', i8='b', u16='H', i16='h', u32='I', i32='i', u64='L', i64='l', f32='f', f64='d')
fmt = fmtmap[ptr.type.rstrip('*')]
size = struct.calcsize(fmt)
if ass is None:
data = self.ctu.readmem(bare(ptr), size)
return TypedValue(ptr.type[:-1], struct.unpack(fmt, data)[0])
else:
self.ctu.writemem(bare(ptr), struct.pack(fmt, bare(ass)))
@ddp
def register(self, name, ass=None):
name = name.upper()
if name == 'PC':
if ass is None:
return TypedValue('u64', self.ctu.pc)
else:
self.ctu.pc = bare(ass)
else:
typemap = dict(X='u64', W='u32', D='f64', Q='f128')
assert name[0] in 'XW' # XXX: Add float support
if ass is None:
type = typemap[name[0]]
value = self.ctu.reg(int(name[1:]))
if type == 'u32':
value &= 0xFFFFFFFF
return TypedValue(type, value)
else:
self.ctu.reg(int(name[1:]), bare(ass))
@ddp
def cast(self, type, value):
return TypedValue(self.run(type), self.run(value))
@ddp
def ptr(self, type):
return self.run(type) + '*'
@ddp('+')
def add(self, a, b):
a, b = self.run(a), self.run(b)
if b.pointer and not a.pointer:
a, b = b, a
if a.pointer and not b.pointer:
return TypedValue(a.type, bare(a) + bare(b) * a.stride)
return TypedValue(a.type, bare(a) + bare(b))
@ddp('-')
def sub(self, a, b):
a, b = self.run(a), self.run(b)
if b.pointer and not a.pointer:
return TypedValue(b.type, bare(a) * b.stride - bare(b))
elif a.pointer and not b.pointer:
return TypedValue(a.type, bare(a) - bare(b) * a.stride)
return TypedValue(a.type, bare(a) + bare(b))
@ddp('*')
def mul(self, a, b):
a, b = self.run(a), self.run(b)
return TypedValue(a.type, bare(a) * bare(b))
@ddp('/')
def div(self, a, b):
a, b = self.run(a), self.run(b)
return TypedValue(a.type, bare(a) / bare(b))
@ddp('==')
def eq(self, a, b):
a, b = self.run(a), self.run(b)
return TypedValue('i64', 1 if a.value == b.value else 0)
@ddp('!=')
def ne(self, a, b):
a, b = self.run(a), self.run(b)
return TypedValue('i64', 1 if a.value != b.value else 0)
@ddp('>')
def gt(self, a, b):
a, b = self.run(a), self.run(b)
return TypedValue('i64', 1 if a.value > b.value else 0)
@ddp('>=')
def ge(self, a, b):
a, b = self.run(a), self.run(b)
return TypedValue('i64', 1 if a.value >= b.value else 0)
@ddp('<')
def lt(self, a, b):
a, b = self.run(a), self.run(b)
return TypedValue('i64', 1 if a.value < b.value else 0)
@ddp('<=')
def le(self, a, b):
a, b = self.run(a), self.run(b)
return TypedValue('i64', 1 if a.value <= b.value else 0)
@ddp('&&')
def booland(self, a, b):
a, b = self.run(a), self.run(b)
return TypedValue('i64', 1 if bool(a.value) and bool(b.value) else 0)
@ddp('||')
def boolor(self, a, b):
a, b = self.run(a), self.run(b)
return TypedValue('i64', 1 if bool(a.value) or bool(b.value) else 0)
def compile(code):
parser = CParser()
stypes = 'u8 i8 u16 i16 u32 i32 u64 i64 f32 f64 f128'
code = 'void runner() { ' + code + ' ; }'
for type in stypes.split(' '):
code = 'typedef void %s; %s' % (type, code)
ast = parser.parse(code)
found = None
for _, child in ast.children():
if isinstance(child, FuncDef):
found = child
break
assert found is not None
assert len(found.body.children()) == 1
ast = found.body.children()[0][1]
sexp = AstTranslator().process(ast)
def run(ctu):
return bare(SexpRunner(ctu).run(sexp))
return run
def ceval(code, ctu):
return compile(code)(ctu)
from pycparser.c_parser import CParser
from pycparser.c_ast import *
import struct
class AstTranslator(object):
def process(self, ast):
node = ast.__class__.__name__
if hasattr(self, node):
func = getattr(self, node)
fcode = func.im_func.func_code
argnames = fcode.co_varnames[1:fcode.co_argcount]
args = [getattr(ast, name) for name in argnames]
return func(*args)
else:
print 'Unhandled AST node:'
ast.show()
return '?unknown?'
def UnaryOp(self, op, expr):
opmap = {'*' : 'deref', '-' : 'neg', '!' : 'not', '~' : 'bnot'}
return opmap[op], self.process(expr)
def BinaryOp(self, op, left, right):
return op, self.process(left), self.process(right)
def Cast(self, to_type, expr):
return 'cast', self.process(to_type), self.process(expr)
def ID(self, name):
return 'register', name
def Typename(self, type):
return self.process(type)
def TypeDecl(self, type):
return self.process(type)
def IdentifierType(self, names):
return ' '.join(names)
def PtrDecl(self, type):
return 'ptr', self.process(type)
def ArrayRef(self, name, subscript):
return '[]', self.process(name), self.process(subscript)
def Constant(self, type, value):
if type == 'int':
if value.startswith('0x'):
return int(value[2:], 16)
elif value.startswith('0b'):
return int(value[2:], 2)
elif value.startswith('0'):
return int(value, 8)
else:
return int(value)
elif type == 'float':
return float(value)
else:
print 'Unknown constant type:', type, `value`
return '?unkconst?'
def Assignment(self, op, lvalue, rvalue):
lvalue = self.process(lvalue)
rvalue = self.process(rvalue)
if op != '=':
rvalue = op[0], lvalue, rvalue
return '=', lvalue, rvalue
dispatchers = {}
def ddp(name):
def sub(func):
dispatchers[name] = func
return func
if callable(name):
dispatchers[name.func_name] = name
return name
return sub
class Register(object):
def __init__(self, name):
self.name = name
def __repr__(self):
return self.name
class TypedValue(object):
def __init__(self, type, value):
self.type, self.value = type, value
while isinstance(self.value, TypedValue):
self.value = self.value.value
def __repr__(self):
return '%s:%r' % (self.type, self.value)
@property
def stride(self):
return int(self.type[1:].rstrip('*')) / 8
@property
def pointer(self):
return '*' in self.type
def bare(value):
if isinstance(value, TypedValue):
return value.value
else:
return value
def autotype(value):
if isinstance(value, TypedValue):
return value
elif isinstance(value, float):
return TypedValue('f64', value)
elif isinstance(value, str):
return value
else:
return TypedValue('i64', value)
class SexpRunner(object):
def __init__(self, ctu):
self.ctu = ctu
def run(self, sexp, rvalue=None):
if not isinstance(sexp, tuple):
return autotype(sexp)
if sexp[0] in dispatchers:
if rvalue is None:
return dispatchers[sexp[0]](self, *sexp[1:])
else:
return dispatchers[sexp[0]](self, *tuple(list(sexp[1:]) + [rvalue]))
else:
print 'Unhandled S-exp:', sexp
return None
@ddp('=')
def assign(self, left, right):
return self.run(left, self.run(right))
@ddp('[]')
def subscript(self, base, sub, ass=None):
base, sub = self.run(base), self.run(sub)
addr = bare(base) + bare(sub) * base.stride
return self.deref(TypedValue(base.type, addr), ass)
@ddp
def deref(self, ptr, ass=None):
ptr = self.run(ptr)
assert ptr.pointer
fmtmap = dict(u8='B', i8='b', u16='H', i16='h', u32='I', i32='i', u64='L', i64='l', f32='f', f64='d')
fmt = fmtmap[ptr.type.rstrip('*')]
size = struct.calcsize(fmt)
if ass is None:
data = self.ctu.readmem(bare(ptr), size)
return TypedValue(ptr.type[:-1], struct.unpack(fmt, data)[0])
else:
self.ctu.writemem(bare(ptr), struct.pack(fmt, bare(ass)))
@ddp
def register(self, name, ass=None):
name = name.upper()
if name == 'PC':
if ass is None:
return TypedValue('u64', self.ctu.pc)
else:
self.ctu.pc = bare(ass)
else:
typemap = dict(X='u64', W='u32', D='f64', Q='f128')
assert name[0] in 'XW' # XXX: Add float support
if ass is None:
type = typemap[name[0]]
value = self.ctu.reg(int(name[1:]))
if type == 'u32':
value &= 0xFFFFFFFF
return TypedValue(type, value)
else:
self.ctu.reg(int(name[1:]), bare(ass))
@ddp
def cast(self, type, value):
return TypedValue(self.run(type), self.run(value))
@ddp
def ptr(self, type):
return self.run(type) + '*'
@ddp('+')
def add(self, a, b):
a, b = self.run(a), self.run(b)
if b.pointer and not a.pointer:
a, b = b, a
if a.pointer and not b.pointer:
return TypedValue(a.type, bare(a) + bare(b) * a.stride)
return TypedValue(a.type, bare(a) + bare(b))
@ddp('-')
def sub(self, a, b):
a, b = self.run(a), self.run(b)
if b.pointer and not a.pointer:
return TypedValue(b.type, bare(a) * b.stride - bare(b))
elif a.pointer and not b.pointer:
return TypedValue(a.type, bare(a) - bare(b) * a.stride)
return TypedValue(a.type, bare(a) + bare(b))
@ddp('*')
def mul(self, a, b):
a, b = self.run(a), self.run(b)
return TypedValue(a.type, bare(a) * bare(b))
@ddp('/')
def div(self, a, b):
a, b = self.run(a), self.run(b)
return TypedValue(a.type, bare(a) / bare(b))
@ddp('==')
def eq(self, a, b):
a, b = self.run(a), self.run(b)
return TypedValue('i64', 1 if a.value == b.value else 0)
@ddp('!=')
def ne(self, a, b):
a, b = self.run(a), self.run(b)
return TypedValue('i64', 1 if a.value != b.value else 0)
@ddp('>')
def gt(self, a, b):
a, b = self.run(a), self.run(b)
return TypedValue('i64', 1 if a.value > b.value else 0)
@ddp('>=')
def ge(self, a, b):
a, b = self.run(a), self.run(b)
return TypedValue('i64', 1 if a.value >= b.value else 0)
@ddp('<')
def lt(self, a, b):
a, b = self.run(a), self.run(b)
return TypedValue('i64', 1 if a.value < b.value else 0)
@ddp('<=')
def le(self, a, b):
a, b = self.run(a), self.run(b)
return TypedValue('i64', 1 if a.value <= b.value else 0)
@ddp('&&')
def booland(self, a, b):
a, b = self.run(a), self.run(b)
return TypedValue('i64', 1 if bool(a.value) and bool(b.value) else 0)
@ddp('||')
def boolor(self, a, b):
a, b = self.run(a), self.run(b)
return TypedValue('i64', 1 if bool(a.value) or bool(b.value) else 0)
def compile(code):
parser = CParser()
stypes = 'u8 i8 u16 i16 u32 i32 u64 i64 f32 f64 f128'
code = 'void runner() { ' + code + ' ; }'
for type in stypes.split(' '):
code = 'typedef void %s; %s' % (type, code)
ast = parser.parse(code)
found = None
for _, child in ast.children():
if isinstance(child, FuncDef):
found = child
break
assert found is not None
assert len(found.body.children()) == 1
ast = found.body.children()[0][1]
sexp = AstTranslator().process(ast)
def run(ctu):
return bare(SexpRunner(ctu).run(sexp))
return run
def ceval(code, ctu):
return compile(code)(ctu)

1234
ctu.py

File diff suppressed because it is too large Load diff

25002
main.map

File diff suppressed because it is too large Load diff

56
main.py
View file

@ -1,28 +1,28 @@
from ctu import *
from util import *
from ceval import ceval
@run
@debug
def main(ctu):
fPath = ctu.malloc(36)
ctu.writemem(fPath, 'blacklist:/blacklist.txt\0')
fOption = ctu.malloc(16)
ctu.writemem(fOption, 'rb\0')
print '%016x' % ctu.call(MainAddress(0x43ddb4), fPath, fOption)
#ctu.dumpmem(WKCAddress(0x887828), 0x1000)
#ctu.call(WKCAddress(0x397B3C))
"""sbuf = ctu.malloc(32)
ctu.writemem(sbuf + 4, struct.pack('<I', 0xAABCDDEF))
obuf = ctu.malloc(0x1000)
print 'obuf at %x' % obuf
ctu.call(MainAddress(0x397c68), sbuf, obuf, 0xDEADBEEF01234567, 0xCAFEBABE)"""
"""dname = ctu.malloc(64)
ctu.writemem(dname, '/dev/nvmap')
print '%016x' % ctu.call(MainAddress(0x1a49c4), dname)"""
#print '%016x' % ctu.call(MainAddress(0x1a4b10), 0xdeadbeef, 0xcafebabe, 0x0123456789, 0xf0e0d0c0)
#print '%016x' % ctu.call(MainAddress(0x1a4ae8), 0x6b0001)
from ctu import *
from util import *
from ceval import ceval
@run
@debug
def main(ctu):
fPath = ctu.malloc(36)
ctu.writemem(fPath, 'blacklist:/blacklist.txt\0')
fOption = ctu.malloc(16)
ctu.writemem(fOption, 'rb\0')
print '%016x' % ctu.call(MainAddress(0x43ddb4), fPath, fOption)
#ctu.dumpmem(WKCAddress(0x887828), 0x1000)
#ctu.call(WKCAddress(0x397B3C))
"""sbuf = ctu.malloc(32)
ctu.writemem(sbuf + 4, struct.pack('<I', 0xAABCDDEF))
obuf = ctu.malloc(0x1000)
print 'obuf at %x' % obuf
ctu.call(MainAddress(0x397c68), sbuf, obuf, 0xDEADBEEF01234567, 0xCAFEBABE)"""
"""dname = ctu.malloc(64)
ctu.writemem(dname, '/dev/nvmap')
print '%016x' % ctu.call(MainAddress(0x1a49c4), dname)"""
#print '%016x' % ctu.call(MainAddress(0x1a4b10), 0xdeadbeef, 0xcafebabe, 0x0123456789, 0xf0e0d0c0)
#print '%016x' % ctu.call(MainAddress(0x1a4ae8), 0x6b0001)

94
svc.py
View file

@ -1,47 +1,47 @@
from util import *
import struct
handlers = {}
def handler(num):
def sub(func):
handlers[num] = func
return func
return sub
class SvcHandler(object):
def __init__(self, ctu):
self.ctu = ctu
for i in xrange(0x60):
ctu.hookinsn(0xD4000001 | (i << 5), (lambda i: lambda _, __: self.svcDispatch(i))(i))
def svcDispatch(self, svc):
if svc in handlers:
print 'svc %x' % svc
handlers[svc](self)
return False
print 'Unhandled: SVC 0x%02x @ %s' % (svc, raw(self.ctu.pc))
self.ctu.debugbreak()
return False
def ipcDispatcher(self, handle, addr, size):
print 'IPC! Handle: %08x' % handle
self.ctu.dumpmem(addr, size)
@handler(0x1D)
def SignalEvent(self):
self.ctu.reg(0, 0)
@handler(0x21)
def SendSyncRequest(self):
return self.ipcDispatcher(self.ctu.reg(0), self.ctu.tlsbase, 0x100)
@handler(0x22)
def SendSyncRequestEx(self):
return self.ipcDispatcher(self.ctu.reg(2), self.ctu.reg(0), self.ctu.reg(1))
@handler(0x25)
def GetThreadId(self):
self.ctu.writemem(self.ctu.reg(0), struct.pack('<Q', 0xf00))
self.ctu.reg(0, 0)
from util import *
import struct
handlers = {}
def handler(num):
def sub(func):
handlers[num] = func
return func
return sub
class SvcHandler(object):
def __init__(self, ctu):
self.ctu = ctu
for i in xrange(0x60):
ctu.hookinsn(0xD4000001 | (i << 5), (lambda i: lambda _, __: self.svcDispatch(i))(i))
def svcDispatch(self, svc):
if svc in handlers:
print 'svc %x' % svc
handlers[svc](self)
return False
print 'Unhandled: SVC 0x%02x @ %s' % (svc, raw(self.ctu.pc))
self.ctu.debugbreak()
return False
def ipcDispatcher(self, handle, addr, size):
print 'IPC! Handle: %08x' % handle
self.ctu.dumpmem(addr, size)
@handler(0x1D)
def SignalEvent(self):
self.ctu.reg(0, 0)
@handler(0x21)
def SendSyncRequest(self):
return self.ipcDispatcher(self.ctu.reg(0), self.ctu.tlsbase, 0x100)
@handler(0x22)
def SendSyncRequestEx(self):
return self.ipcDispatcher(self.ctu.reg(2), self.ctu.reg(0), self.ctu.reg(1))
@handler(0x25)
def GetThreadId(self):
self.ctu.writemem(self.ctu.reg(0), struct.pack('<Q', 0xf00))
self.ctu.reg(0, 0)

218
util.py
View file

@ -1,109 +1,109 @@
import re
class Restart(Exception):
pass
class BadAddr(Exception):
pass
symbols = {}
invsyms = {}
def mapLoader(fn, acls, base):
cut = 'nullsub_', 'def_%s' % ('%x' % base)[:2]
with file(fn, 'r') as fp:
for line in fp:
if not line.startswith(' 00000001:'):
continue
addr = acls(int(line[10:26], 16) - base)
name = line[33:].strip().split('(', 1)[0]
if any(name.startswith(x) for x in cut):
continue
symbols[name] = addr
invsyms[addr] = name
class Address(object):
display_specialized = True
def __init__(self, addr, pad=False, raw=False):
self.addr = addr + (0 if raw else self.baseaddr)
self.pad = pad
def __hash__(self):
return self.addr.__hash__()
def __eq__(self, b):
b = raw(b)
return self.addr == b.addr
@property
def baseaddr(self):
return type(self).realbase
@property
def offset(self):
return self.addr - self.baseaddr
def to(self, cls):
if isinstance(self, cls):
return self
return cls(self.addr, pad=self.pad, raw=True)
@property
def symbol(self):
if self in invsyms:
return invsyms[self]
def __str__(self):
if not Address.display_specialized and not isinstance(self, RawAddress):
return self.to(RawAddress).__str__()
sym = self.symbol
if sym is None:
return self.mname % (('0x%016x' if self.pad else '0x%x') % self.offset)
else:
return self.mname % (('%s @ 0x%016x' if self.pad else '%s @ 0x%x') % (sym, self.offset))
def __add__(self, b):
return type(self)(self.addr + b, pad=self.pad, raw=True)
def specialize(self):
if not isinstance(self, RawAddress):
return self.to(RawAddress).specialize()
if WKCAddress.realbase <= self.addr < WKCAddress.realbase + WKCAddress.realsize:
return self.to(WKCAddress)
elif MainAddress.realbase <= self.addr < MainAddress.realbase + MainAddress.realbase:
return self.to(MainAddress)
return self
class RawAddress(Address):
mname = '%s'
realbase = 0
realsize = 1 << 64
class WKCAddress(Address):
mname = 'WKC(%s)'
# realbase/size assigned at runtime
class MainAddress(Address):
mname = 'Main(%s)'
# realbase/size assigned at runtime
def raw(addr, pad=False):
if isinstance(addr, str) or isinstance(addr, unicode):
if addr in symbols:
return symbols[addr]
else:
raise BadAddr()
elif isinstance(addr, Address):
return addr.to(RawAddress)
return RawAddress(addr, pad=pad).specialize()
def native(addr):
if isinstance(addr, Address):
return addr.addr
else:
return addr
def parseInt(addr, implicitHex=False):
if (implicitHex or addr.startswith('0x')) and re.match(r'^(0x)?[0-9a-fA-F]+$', addr):
return int(addr[2:] if addr.startswith('0x') else addr, 16)
elif re.match(r'^[0-9]+$', addr):
return int(addr)
else:
return None
import re
class Restart(Exception):
pass
class BadAddr(Exception):
pass
symbols = {}
invsyms = {}
def mapLoader(fn, acls, base):
cut = 'nullsub_', 'def_%s' % ('%x' % base)[:2]
with file(fn, 'r') as fp:
for line in fp:
if not line.startswith(' 00000001:'):
continue
addr = acls(int(line[10:26], 16) - base)
name = line[33:].strip().split('(', 1)[0]
if any(name.startswith(x) for x in cut):
continue
symbols[name] = addr
invsyms[addr] = name
class Address(object):
display_specialized = True
def __init__(self, addr, pad=False, raw=False):
self.addr = addr + (0 if raw else self.baseaddr)
self.pad = pad
def __hash__(self):
return self.addr.__hash__()
def __eq__(self, b):
b = raw(b)
return self.addr == b.addr
@property
def baseaddr(self):
return type(self).realbase
@property
def offset(self):
return self.addr - self.baseaddr
def to(self, cls):
if isinstance(self, cls):
return self
return cls(self.addr, pad=self.pad, raw=True)
@property
def symbol(self):
if self in invsyms:
return invsyms[self]
def __str__(self):
if not Address.display_specialized and not isinstance(self, RawAddress):
return self.to(RawAddress).__str__()
sym = self.symbol
if sym is None:
return self.mname % (('0x%016x' if self.pad else '0x%x') % self.offset)
else:
return self.mname % (('%s @ 0x%016x' if self.pad else '%s @ 0x%x') % (sym, self.offset))
def __add__(self, b):
return type(self)(self.addr + b, pad=self.pad, raw=True)
def specialize(self):
if not isinstance(self, RawAddress):
return self.to(RawAddress).specialize()
if WKCAddress.realbase <= self.addr < WKCAddress.realbase + WKCAddress.realsize:
return self.to(WKCAddress)
elif MainAddress.realbase <= self.addr < MainAddress.realbase + MainAddress.realbase:
return self.to(MainAddress)
return self
class RawAddress(Address):
mname = '%s'
realbase = 0
realsize = 1 << 64
class WKCAddress(Address):
mname = 'WKC(%s)'
# realbase/size assigned at runtime
class MainAddress(Address):
mname = 'Main(%s)'
# realbase/size assigned at runtime
def raw(addr, pad=False):
if isinstance(addr, str) or isinstance(addr, unicode):
if addr in symbols:
return symbols[addr]
else:
raise BadAddr()
elif isinstance(addr, Address):
return addr.to(RawAddress)
return RawAddress(addr, pad=pad).specialize()
def native(addr):
if isinstance(addr, Address):
return addr.addr
else:
return addr
def parseInt(addr, implicitHex=False):
if (implicitHex or addr.startswith('0x')) and re.match(r'^(0x)?[0-9a-fA-F]+$', addr):
return int(addr[2:] if addr.startswith('0x') else addr, 16)
elif re.match(r'^[0-9]+$', addr):
return int(addr)
else:
return None

File diff suppressed because it is too large Load diff