mirror of
https://github.com/reswitched/CageTheUnicorn.git
synced 2024-05-11 09:14:50 -04:00
Fixed line endings.
This commit is contained in:
parent
bd045eeea7
commit
9591e6978e
44
bundler.py
44
bundler.py
|
@ -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
582
ceval.py
|
@ -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)
|
||||
|
|
56
main.py
56
main.py
|
@ -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
94
svc.py
|
@ -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
218
util.py
|
@ -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
|
||||
|
|
38600
webkit_wkc.map
38600
webkit_wkc.map
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue