miasm2.arch.msp430.arch module
#-*- coding:utf-8 -*- import logging from pyparsing import * from miasm2.expression.expression import * from miasm2.core.cpu import * from collections import defaultdict from miasm2.core.bin_stream import bin_stream import miasm2.arch.msp430.regs as regs_module from miasm2.arch.msp430.regs import * from miasm2.core.asm_ast import AstInt, AstId, AstMem, AstOp log = logging.getLogger("msp430dis") console_handler = logging.StreamHandler() console_handler.setFormatter(logging.Formatter("%(levelname)-5s: %(message)s")) log.addHandler(console_handler) log.setLevel(logging.DEBUG) conditional_branch = ['jnz', 'jz', 'jnc', 'jc', 'jn', 'jge', 'jl'] unconditional_branch = ['jmp'] def cb_deref_nooff(tokens): assert len(tokens) == 1 result = AstMem(tokens[0], 16) return result def cb_deref_pinc(tokens): assert len(tokens) == 1 result = AstOp('autoinc', *tokens) return result def cb_deref_off(tokens): assert len(tokens) == 2 result = AstMem(tokens[1] + tokens[0], 16) return result def cb_expr(tokens): assert(len(tokens) == 1) result = tokens[0] return result ARO = Suppress("@") LPARENT = Suppress("(") RPARENT = Suppress(")") PINC = Suppress("+") deref_nooff = (ARO + base_expr).setParseAction(cb_deref_nooff) deref_pinc = (ARO + base_expr + PINC).setParseAction(cb_deref_pinc) deref_off = (base_expr + LPARENT + gpregs.parser + RPARENT).setParseAction(cb_deref_off) sreg_p = (deref_pinc | deref_nooff | deref_off | base_expr).setParseAction(cb_expr) class msp430_arg(m_arg): def asm_ast_to_expr(self, value, loc_db): if isinstance(value, AstId): name = value.name if isinstance(name, Expr): return name assert isinstance(name, str) if name in gpregs.str: index = gpregs.str.index(name) reg = gpregs.expr[index] return reg loc_key = loc_db.get_or_create_name_location(value.name) return ExprLoc(loc_key, 16) if isinstance(value, AstOp): args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in value.args] if None in args: return None return ExprOp(value.op, *args) if isinstance(value, AstInt): return ExprInt(value.value, 16) if isinstance(value, AstMem): ptr = self.asm_ast_to_expr(value.ptr, loc_db) if ptr is None: return None return ExprMem(ptr, value.size) return None class additional_info: def __init__(self): self.except_on_instr = False class instruction_msp430(instruction): __slots__ = [] delayslot = 0 def dstflow(self): if self.name.startswith('j'): return True return self.name in ['call'] @staticmethod def arg2str(expr, index=None, loc_db=None): if isinstance(expr, ExprId): o = str(expr) elif isinstance(expr, ExprInt): o = str(expr) elif expr.is_loc(): if loc_db is not None: return loc_db.pretty_str(expr.loc_key) else: return str(expr) elif isinstance(expr, ExprOp) and expr.op == "autoinc": o = "@%s+" % str(expr.args[0]) elif isinstance(expr, ExprMem): if isinstance(expr.arg, ExprId): if index == 0: o = "@%s" % expr.arg else: o = "0x0(%s)" % expr.arg elif isinstance(expr.arg, ExprInt): o = "@%s" % expr.arg elif isinstance(expr.arg, ExprOp): o = "%s(%s)" % (expr.arg.args[1], expr.arg.args[0]) else: raise NotImplementedError('unknown instance expr = %s' % type(expr)) return o def dstflow2label(self, loc_db): expr = self.args[0] if not isinstance(expr, ExprInt): return if self.name == "call": addr = expr.arg else: addr = expr.arg + int(self.offset) loc_key = loc_db.get_or_create_offset_location(addr) self.args[0] = ExprLoc(loc_key, expr.size) def breakflow(self): if self.name in conditional_branch + unconditional_branch: return True if self.name.startswith('ret'): return True if self.name.startswith('int'): return True if self.name.startswith('mov') and self.args[1] == PC: return True return self.name in ['call'] def splitflow(self): if self.name in conditional_branch: return True if self.name in unconditional_branch: return False return self.name in ['call'] def setdstflow(self, a): return def is_subcall(self): return self.name in ['call'] def getdstflow(self, loc_db): return [self.args[0]] def get_symbol_size(self, symbol, loc_db): return 16 def fixDstOffset(self): e = self.args[0] if self.offset is None: raise ValueError('symbol not resolved %s' % l) if not isinstance(e, ExprInt): # raise ValueError('dst must be int or label') log.warning('dynamic dst %r', e) return # Call argument is an absolute offset # Other offsets are relative to instruction offset if self.name != "call": self.args[0] = ExprInt(int(e) - self.offset, 16) def get_info(self, c): pass def __str__(self): o = super(instruction_msp430, self).__str__() return o def get_args_expr(self): args = [] for a in self.args: args.append(a) return args mode_msp430 = None class mn_msp430(cls_mn): name = "msp430" regs = regs_module all_mn = [] bintree = {} num = 0 delayslot = 0 pc = {None: PC} sp = {None: SP} all_mn_mode = defaultdict(list) all_mn_name = defaultdict(list) all_mn_inst = defaultdict(list) instruction = instruction_msp430 max_instruction_len = 8 @classmethod def getpc(cls, attrib): return PC @classmethod def getsp(cls, attrib): return SP @classmethod def check_mnemo(cls, fields): l = sum([x.l for x in fields]) assert l % 16 == 00, "len %r" % l @classmethod def getbits(cls, bs, attrib, start, n): if not n: return 0 o = 0 if n > bs.getlen() * 8: raise ValueError('not enought bits %r %r' % (n, len(bs.bin) * 8)) while n: i = start / 8 c = cls.getbytes(bs, i) if not c: raise IOError c = ord(c) r = 8 - start % 8 c &= (1 << r) - 1 l = min(r, n) c >>= (r - l) o <<= l o |= c n -= l start += l return o @classmethod def getbytes(cls, bs, offset, l=1): out = "" for _ in xrange(l): n_offset = (offset & ~1) + 1 - offset % 2 out += bs.getbytes(n_offset, 1) offset += 1 return out def decoded2bytes(self, result): tmp = super(mn_msp430, self).decoded2bytes(result) out = [] for x in tmp: o = "" while x: o += x[:2][::-1] x = x[2:] out.append(o) return out @classmethod def gen_modes(cls, subcls, name, bases, dct, fields): dct['mode'] = None return [(subcls, name, bases, dct, fields)] def additional_info(self): info = additional_info() return info @classmethod def getmn(cls, name): return name.upper() def reset_class(self): super(mn_msp430, self).reset_class() def getnextflow(self, loc_db): raise NotImplementedError('not fully functional') def addop(name, fields, args=None, alias=False): dct = {"fields": fields} dct["alias"] = alias if args is not None: dct['args'] = args type(name, (mn_msp430,), dct) class bw_mn(bs_mod_name): prio = 5 mn_mod = ['.w', '.b'] class msp430_sreg_arg(reg_noarg, msp430_arg): prio = default_prio + 1 reg_info = gpregs parser = sreg_p def decode(self, v): size = 16 if hasattr(self.parent, 'size'): size = [16, 8][self.parent.size.value] v = v & self.lmask e = self.reg_info.expr[v] if self.parent.a_s.value == 0b00: if e == R3: self.expr = ExprInt(0, size) else: self.expr = e elif self.parent.a_s.value == 0b01: if e == SR: self.expr = ExprMem(ExprInt(self.parent.off_s.value, 16), size) elif e == R3: self.expr = ExprInt(1, size) else: self.expr = ExprMem( e + ExprInt(self.parent.off_s.value, 16), size) elif self.parent.a_s.value == 0b10: if e == SR: self.expr = ExprInt(4, size) elif e == R3: self.expr = ExprInt(2, size) else: self.expr = ExprMem(e, size) elif self.parent.a_s.value == 0b11: if e == SR: self.expr = ExprInt(8, size) elif e == R3: if self.parent.size.value == 0: self.expr = ExprInt(0xffff, size) else: self.expr = ExprInt(0xff, size) elif e == PC: self.expr = ExprInt(self.parent.off_s.value, size) else: self.expr = ExprOp('autoinc', e) else: raise NotImplementedError( "unknown value self.parent.a_s.value = " + "%d" % self.parent.a_s.value) return True def encode(self): e = self.expr if e in self.reg_info.expr: self.parent.a_s.value = 0 self.value = self.reg_info.expr.index(e) elif isinstance(e, ExprInt): v = int(e) if v == 0xffff and self.parent.size.value == 0: self.parent.a_s.value = 0b11 self.value = 3 elif v == 0xff and self.parent.size.value == 1: self.parent.a_s.value = 0b11 self.value = 3 elif v == 2: self.parent.a_s.value = 0b10 self.value = 3 elif v == 1: self.parent.a_s.value = 0b01 self.value = 3 elif v == 8: self.parent.a_s.value = 0b11 self.value = 2 elif v == 4: self.parent.a_s.value = 0b10 self.value = 2 elif v == 0: self.parent.a_s.value = 0b00 self.value = 3 else: self.parent.a_s.value = 0b11 self.value = 0 self.parent.off_s.value = v elif isinstance(e, ExprMem): if isinstance(e.arg, ExprId): self.parent.a_s.value = 0b10 self.value = self.reg_info.expr.index(e.arg) elif isinstance(e.arg, ExprInt): self.parent.a_s.value = 0b01 self.value = self.reg_info.expr.index(SR) self.parent.off_s.value = int(e.arg) elif isinstance(e.arg, ExprOp): self.parent.a_s.value = 0b01 self.value = self.reg_info.expr.index(e.arg.args[0]) self.parent.off_s.value = int(e.arg.args[1]) else: raise NotImplementedError( 'unknown instance e.arg = %s' % type(e.arg)) elif isinstance(e, ExprOp) and e.op == "autoinc": self.parent.a_s.value = 0b11 self.value = self.reg_info.expr.index(e.args[0]) else: raise NotImplementedError('unknown instance e = %s' % type(e)) return True class msp430_dreg_arg(msp430_sreg_arg): prio = default_prio + 1 reg_info = gpregs parser = sreg_p def decode(self, v): if hasattr(self.parent, 'size'): size = [16, 8][self.parent.size.value] else: size = 16 v = v & self.lmask e = self.reg_info.expr[v] if self.parent.a_d.value == 0: self.expr = e elif self.parent.a_d.value == 1: if e == SR: x = ExprInt(self.parent.off_d.value, 16) else: x = e + ExprInt(self.parent.off_d.value, 16) self.expr = ExprMem(x, size) else: raise NotImplementedError( "unknown value self.parent.a_d.value = " + "%d" % self.parent.a_d.value) return True def encode(self): e = self.expr if e in self.reg_info.expr: self.parent.a_d.value = 0 self.value = self.reg_info.expr.index(e) elif isinstance(e, ExprMem): if isinstance(e.arg, ExprId): r, i = e.arg, ExprInt(0, 16) elif isinstance(e.arg, ExprOp): r, i = e.arg.args[0], e.arg.args[1] elif isinstance(e.arg, ExprInt): r, i = SR, e.arg else: raise NotImplementedError( 'unknown instance e.arg = %s' % type(e.arg)) self.parent.a_d.value = 1 self.value = self.reg_info.expr.index(r) self.parent.off_d.value = int(i) else: raise NotImplementedError('unknown instance e = %s' % type(e)) return True class bs_cond_off_s(bs_cond): @classmethod def flen(cls, mode, v): if v['a_s'] == 0b00: return None elif v['a_s'] == 0b01: if v['sreg'] in [3]: return None else: return 16 elif v['a_s'] == 0b10: return None elif v['a_s'] == 0b11: """ if v['sreg'] in [2, 3]: return None else: return 16 """ if v['sreg'] in [0]: return 16 else: return None else: raise NotImplementedError("unknown value v[a_s] = %d" % v['a_s']) def encode(self): return super(bs_cond_off_s, self).encode() def decode(self, v): if self.l == 0: self.value = None self.value = v return True class bs_cond_off_d(bs_cond_off_s): @classmethod def flen(cls, mode, v): if v['a_d'] == 0: return None elif v['a_d'] == 1: return 16 else: raise NotImplementedError("unknown value v[a_d] = %d" % v['a_d']) class msp430_offs(imm_noarg, msp430_arg): parser = base_expr def int2expr(self, v): if v & ~self.intmask != 0: return None return ExprInt(v, 16) def decodeval(self, v): v <<= 1 v += self.parent.l return v def encodeval(self, v): plen = self.parent.l + self.l assert(plen % 8 == 0) v -= plen / 8 if v % 2 != 0: return False return v >> 1 def decode(self, v): v = v & self.lmask if (1 << (self.l - 1)) & v: v |= ~0 ^ self.lmask v = self.decodeval(v) self.expr = ExprInt(v, 16) return True def encode(self): if not isinstance(self.expr, ExprInt): return False v = int(self.expr) if (1 << (self.l - 1)) & v: v = -((0xffff ^ v) + 1) v = self.encodeval(v) self.value = (v & 0xffff) & self.lmask return True off_s = bs(l=16, order=-10, cls=(bs_cond_off_s,), fname = "off_s") off_d = bs(l=16, order=-10, cls=(bs_cond_off_d,), fname = "off_d") a_s = bs(l=2, order=-4, fname='a_s') a_d = bs(l=1, order=-6, fname='a_d') a_d2 = bs(l=2, order=-2, fname='a_d') sreg = bs(l=4, order=-3, cls=(msp430_sreg_arg,), fname='sreg') dreg = bs(l=4, order=-5, cls=(msp430_dreg_arg,), fname='dreg') bw = bw_mn(l=1, order=-10, mn_mod=['.w', '.b'], fname='size') bs_f1 = bs_name( l=4, name={ 'mov': 4, 'add': 5, 'addc': 6, 'subc': 7, 'sub': 8, 'cmp': 9, 'dadd': 10, 'bit': 11, 'bic': 12, 'bis': 13, 'xor': 14, 'and': 15}) addop("f1", [bs_f1, sreg, a_d, bw, a_s, dreg, off_s, off_d]) bs_f2 = bs_name(l=3, name={'rrc': 0, 'rra': 2, 'push': 4}) addop("f2_1", [bs('000100'), bs_f2, bw, a_s, sreg, off_s]) bs_f2_nobw = bs_name(l=3, name={'swpb': 1, 'sxt': 3, 'call': 5}) addop("f2_2", [bs('000100'), bs_f2_nobw, bs('0'), a_s, sreg, off_s]) # Offset must be decoded in last position to have final instruction len offimm = bs(l=10, cls=(msp430_offs,), fname="offs", order=-1) bs_f2_jcc = bs_name(l=3, name={'jnz': 0, 'jz': 1, 'jnc': 2, 'jc': 3, 'jn': 4, 'jge': 5, 'jl': 6, 'jmp': 7}) addop("f2_3", [bs('001'), bs_f2_jcc, offimm])
Module variables
var ARO
var EXPRAFF
var EXPRCOMPOSE
var EXPRCOND
var EXPRID
var EXPRINT
var EXPRLOC
var EXPRMEM
var EXPROP
var EXPRSLICE
var EXPR_ORDER_DICT
var LPARENT
var PINC
var PRIORITY_MAX
var RPARENT
var TOK_EQUAL
var TOK_INF
var TOK_INF_EQUAL
var TOK_INF_EQUAL_SIGNED
var TOK_INF_EQUAL_UNSIGNED
var TOK_INF_SIGNED
var TOK_INF_UNSIGNED
var TOK_POS
var TOK_POS_STRICT
var a_d
var a_d2
var a_s
var all_regs_ids
var all_regs_ids_byname
var all_regs_ids_init
var all_regs_ids_no_alias
var alphanums
var alphas
var alphas8bit
var attrib_to_regs
var bs_f1
var bs_f2
var bs_f2_jcc
var bs_f2_nobw
var bw
var conditional_branch
var console_handler
var default_prio
var deref_nooff
var deref_off
var deref_pinc
var dreg
var hexnums
var i
var log
var mod_size2uint
var mode_msp430
var nums
var off_d
var off_s
var offimm
var printables
var priorities
var priorities_list
var punc8bit
var reg_cf
var reg_cpuoff
var reg_gie
var reg_nf
var reg_of
var reg_osc
var reg_res
var reg_scg0
var reg_scg1
var reg_zf
var regs16_expr
var regs16_str
var regs_flt_expr
var regs_init
var size_to_IEEE754_info
var sreg
var sreg_p
var total_scans
var unconditional_branch
Functions
def addop(
name, fields, args=None, alias=False)
def addop(name, fields, args=None, alias=False): dct = {"fields": fields} dct["alias"] = alias if args is not None: dct['args'] = args type(name, (mn_msp430,), dct)
def cb_deref_nooff(
tokens)
def cb_deref_nooff(tokens): assert len(tokens) == 1 result = AstMem(tokens[0], 16) return result
def cb_deref_off(
tokens)
def cb_deref_off(tokens): assert len(tokens) == 2 result = AstMem(tokens[1] + tokens[0], 16) return result
def cb_deref_pinc(
tokens)
def cb_deref_pinc(tokens): assert len(tokens) == 1 result = AstOp('autoinc', *tokens) return result
def cb_expr(
tokens)
def cb_expr(tokens): assert(len(tokens) == 1) result = tokens[0] return result
Classes
class additional_info
class additional_info: def __init__(self): self.except_on_instr = False
Ancestors (in MRO)
Instance variables
var except_on_instr
Methods
def __init__(
self)
def __init__(self): self.except_on_instr = False
class bs_cond_off_d
class bs_cond_off_d(bs_cond_off_s): @classmethod def flen(cls, mode, v): if v['a_d'] == 0: return None elif v['a_d'] == 1: return 16 else: raise NotImplementedError("unknown value v[a_d] = %d" % v['a_d'])
Ancestors (in MRO)
- bs_cond_off_d
- bs_cond_off_s
- miasm2.core.cpu.bs_cond
- miasm2.core.cpu.bsi
- __builtin__.object
Instance variables
Methods
def __init__(
self, parent, strbits, l, cls, fname, order, lmask, fbits, fmask, value, flen, **kargs)
Inheritance:
bs_cond_off_s
.__init__
def __init__(self, parent, strbits, l, cls, fname, order, lmask, fbits, fmask, value, flen, **kargs): self.parent = parent self.strbits = strbits self.l = l self.cls = cls self.fname = fname self.order = order self.fbits = fbits self.fmask = fmask self.flen = flen self.value = value self.kargs = kargs self.__dict__.update(self.kargs)
def clone(
self)
Inheritance:
bs_cond_off_s
.clone
def clone(self): s = self.__class__(self.parent, self.strbits, self.l, self.cls, self.fname, self.order, self.lmask, self.fbits, self.fmask, self.value, self.flen, **self.kargs) s.__dict__.update(self.kargs) if hasattr(self, 'expr'): s.expr = self.expr return s
def decode(
self, v)
Inheritance:
bs_cond_off_s
.decode
def decode(self, v): if self.l == 0: self.value = None self.value = v return True
def encode(
self)
Inheritance:
bs_cond_off_s
.encode
def encode(self): return super(bs_cond_off_s, self).encode()
def flen(
cls, mode, v)
Inheritance:
bs_cond_off_s
.flen
@classmethod def flen(cls, mode, v): if v['a_d'] == 0: return None elif v['a_d'] == 1: return 16 else: raise NotImplementedError("unknown value v[a_d] = %d" % v['a_d'])
class bs_cond_off_s
class bs_cond_off_s(bs_cond): @classmethod def flen(cls, mode, v): if v['a_s'] == 0b00: return None elif v['a_s'] == 0b01: if v['sreg'] in [3]: return None else: return 16 elif v['a_s'] == 0b10: return None elif v['a_s'] == 0b11: """ if v['sreg'] in [2, 3]: return None else: return 16 """ if v['sreg'] in [0]: return 16 else: return None else: raise NotImplementedError("unknown value v[a_s] = %d" % v['a_s']) def encode(self): return super(bs_cond_off_s, self).encode() def decode(self, v): if self.l == 0: self.value = None self.value = v return True
Ancestors (in MRO)
- bs_cond_off_s
- miasm2.core.cpu.bs_cond
- miasm2.core.cpu.bsi
- __builtin__.object
Instance variables
var lmask
Methods
def __init__(
self, parent, strbits, l, cls, fname, order, lmask, fbits, fmask, value, flen, **kargs)
def __init__(self, parent, strbits, l, cls, fname, order, lmask, fbits, fmask, value, flen, **kargs): self.parent = parent self.strbits = strbits self.l = l self.cls = cls self.fname = fname self.order = order self.fbits = fbits self.fmask = fmask self.flen = flen self.value = value self.kargs = kargs self.__dict__.update(self.kargs)
def clone(
self)
def clone(self): s = self.__class__(self.parent, self.strbits, self.l, self.cls, self.fname, self.order, self.lmask, self.fbits, self.fmask, self.value, self.flen, **self.kargs) s.__dict__.update(self.kargs) if hasattr(self, 'expr'): s.expr = self.expr return s
def decode(
self, v)
def decode(self, v): if self.l == 0: self.value = None self.value = v return True
def encode(
self)
def encode(self): return super(bs_cond_off_s, self).encode()
def flen(
cls, mode, v)
@classmethod def flen(cls, mode, v): if v['a_s'] == 0b00: return None elif v['a_s'] == 0b01: if v['sreg'] in [3]: return None else: return 16 elif v['a_s'] == 0b10: return None elif v['a_s'] == 0b11: """ if v['sreg'] in [2, 3]: return None else: return 16 """ if v['sreg'] in [0]: return 16 else: return None else: raise NotImplementedError("unknown value v[a_s] = %d" % v['a_s'])
class bw_mn
class bw_mn(bs_mod_name): prio = 5 mn_mod = ['.w', '.b']
Ancestors (in MRO)
- bw_mn
- miasm2.core.cpu.bs_mod_name
- miasm2.core.cpu.bs_divert
- __builtin__.object
Class variables
var mn_mod
var prio
Methods
def __init__(
self, **kargs)
def __init__(self, **kargs): self.args = kargs
def divert(
self, i, candidates)
def divert(self, i, candidates): out = [] for cls, _, bases, dct, fields in candidates: tab = self.args['mn_mod'] if isinstance(tab, list): tmp = {} for j, v in enumerate(tab): tmp[j] = v tab = tmp for value, new_name in tab.iteritems(): nfields = fields[:] s = int2bin(value, self.args['l']) args = dict(self.args) args.update({'strbits': s}) f = bs(**args) nfields[i] = f ndct = dict(dct) ndct['name'] = self.modname(ndct['name'], value) out.append((cls, new_name, bases, ndct, nfields)) return out
def modname(
self, name, i)
def modname(self, name, i): return name + self.args['mn_mod'][i]
class instruction_msp430
class instruction_msp430(instruction): __slots__ = [] delayslot = 0 def dstflow(self): if self.name.startswith('j'): return True return self.name in ['call'] @staticmethod def arg2str(expr, index=None, loc_db=None): if isinstance(expr, ExprId): o = str(expr) elif isinstance(expr, ExprInt): o = str(expr) elif expr.is_loc(): if loc_db is not None: return loc_db.pretty_str(expr.loc_key) else: return str(expr) elif isinstance(expr, ExprOp) and expr.op == "autoinc": o = "@%s+" % str(expr.args[0]) elif isinstance(expr, ExprMem): if isinstance(expr.arg, ExprId): if index == 0: o = "@%s" % expr.arg else: o = "0x0(%s)" % expr.arg elif isinstance(expr.arg, ExprInt): o = "@%s" % expr.arg elif isinstance(expr.arg, ExprOp): o = "%s(%s)" % (expr.arg.args[1], expr.arg.args[0]) else: raise NotImplementedError('unknown instance expr = %s' % type(expr)) return o def dstflow2label(self, loc_db): expr = self.args[0] if not isinstance(expr, ExprInt): return if self.name == "call": addr = expr.arg else: addr = expr.arg + int(self.offset) loc_key = loc_db.get_or_create_offset_location(addr) self.args[0] = ExprLoc(loc_key, expr.size) def breakflow(self): if self.name in conditional_branch + unconditional_branch: return True if self.name.startswith('ret'): return True if self.name.startswith('int'): return True if self.name.startswith('mov') and self.args[1] == PC: return True return self.name in ['call'] def splitflow(self): if self.name in conditional_branch: return True if self.name in unconditional_branch: return False return self.name in ['call'] def setdstflow(self, a): return def is_subcall(self): return self.name in ['call'] def getdstflow(self, loc_db): return [self.args[0]] def get_symbol_size(self, symbol, loc_db): return 16 def fixDstOffset(self): e = self.args[0] if self.offset is None: raise ValueError('symbol not resolved %s' % l) if not isinstance(e, ExprInt): # raise ValueError('dst must be int or label') log.warning('dynamic dst %r', e) return # Call argument is an absolute offset # Other offsets are relative to instruction offset if self.name != "call": self.args[0] = ExprInt(int(e) - self.offset, 16) def get_info(self, c): pass def __str__(self): o = super(instruction_msp430, self).__str__() return o def get_args_expr(self): args = [] for a in self.args: args.append(a) return args
Ancestors (in MRO)
- instruction_msp430
- miasm2.core.cpu.instruction
- __builtin__.object
Class variables
var additional_info
var args
var b
var data
var delayslot
var l
var mode
var name
var offset
Static methods
def arg2str(
expr, index=None, loc_db=None)
@staticmethod def arg2str(expr, index=None, loc_db=None): if isinstance(expr, ExprId): o = str(expr) elif isinstance(expr, ExprInt): o = str(expr) elif expr.is_loc(): if loc_db is not None: return loc_db.pretty_str(expr.loc_key) else: return str(expr) elif isinstance(expr, ExprOp) and expr.op == "autoinc": o = "@%s+" % str(expr.args[0]) elif isinstance(expr, ExprMem): if isinstance(expr.arg, ExprId): if index == 0: o = "@%s" % expr.arg else: o = "0x0(%s)" % expr.arg elif isinstance(expr.arg, ExprInt): o = "@%s" % expr.arg elif isinstance(expr.arg, ExprOp): o = "%s(%s)" % (expr.arg.args[1], expr.arg.args[0]) else: raise NotImplementedError('unknown instance expr = %s' % type(expr)) return o
Methods
def __init__(
self, name, mode, args, additional_info=None)
def __init__(self, name, mode, args, additional_info=None): self.name = name self.mode = mode self.args = args self.additional_info = additional_info self.offset = None self.l = None self.b = None
def breakflow(
self)
def breakflow(self): if self.name in conditional_branch + unconditional_branch: return True if self.name.startswith('ret'): return True if self.name.startswith('int'): return True if self.name.startswith('mov') and self.args[1] == PC: return True return self.name in ['call']
def dstflow(
self)
def dstflow(self): if self.name.startswith('j'): return True return self.name in ['call']
def dstflow2label(
self, loc_db)
def dstflow2label(self, loc_db): expr = self.args[0] if not isinstance(expr, ExprInt): return if self.name == "call": addr = expr.arg else: addr = expr.arg + int(self.offset) loc_key = loc_db.get_or_create_offset_location(addr) self.args[0] = ExprLoc(loc_key, expr.size)
def fixDstOffset(
self)
def fixDstOffset(self): e = self.args[0] if self.offset is None: raise ValueError('symbol not resolved %s' % l) if not isinstance(e, ExprInt): # raise ValueError('dst must be int or label') log.warning('dynamic dst %r', e) return # Call argument is an absolute offset # Other offsets are relative to instruction offset if self.name != "call": self.args[0] = ExprInt(int(e) - self.offset, 16)
def gen_args(
self, args)
def gen_args(self, args): out = ', '.join([str(x) for x in args]) return out
def get_args_expr(
self)
def get_args_expr(self): args = [] for a in self.args: args.append(a) return args
def get_asm_next_offset(
self, expr)
def get_asm_next_offset(self, expr): return m2_expr.ExprInt(self.offset+self.l, expr.size)
def get_asm_offset(
self, expr)
def get_asm_offset(self, expr): return m2_expr.ExprInt(self.offset, expr.size)
def get_info(
self, c)
def get_info(self, c): pass
def get_symbol_size(
self, symbol, loc_db)
def get_symbol_size(self, symbol, loc_db): return 16
def getdstflow(
self, loc_db)
def getdstflow(self, loc_db): return [self.args[0]]
def is_subcall(
self)
def is_subcall(self): return self.name in ['call']
def resolve_args_with_symbols(
self, symbols=None)
def resolve_args_with_symbols(self, symbols=None): if symbols is None: symbols = {} args_out = [] for expr in self.args: # try to resolve symbols using symbols (0 for default value) loc_keys = m2_expr.get_expr_locs(expr) fixed_expr = {} for exprloc in loc_keys: loc_key = exprloc.loc_key names = symbols.get_location_names(loc_key) # special symbols if '$' in names: fixed_expr[exprloc] = self.get_asm_offset(exprloc) continue if '_' in names: fixed_expr[exprloc] = self.get_asm_next_offset(exprloc) continue if not names: raise ValueError('Unresolved symbol: %r' % exprloc) offset = symbols.get_location_offset(loc_key) if offset is None: raise ValueError( 'The offset of loc_key "%s" cannot be determined' % names ) else: # Fix symbol with its offset size = exprloc.size if size is None: default_size = self.get_symbol_size(exprloc, symbols) size = default_size value = m2_expr.ExprInt(offset, size) fixed_expr[exprloc] = value expr = expr.replace_expr(fixed_expr) expr = expr_simp(expr) args_out.append(expr) return args_out
def setdstflow(
self, a)
def setdstflow(self, a): return
def splitflow(
self)
def splitflow(self): if self.name in conditional_branch: return True if self.name in unconditional_branch: return False return self.name in ['call']
def to_string(
self, loc_db=None)
def to_string(self, loc_db=None): o = "%-10s " % self.name args = [] for i, arg in enumerate(self.args): if not isinstance(arg, m2_expr.Expr): raise ValueError('zarb arg type') x = self.arg2str(arg, i, loc_db) args.append(x) o += self.gen_args(args) return o
class mn_msp430
class mn_msp430(cls_mn): name = "msp430" regs = regs_module all_mn = [] bintree = {} num = 0 delayslot = 0 pc = {None: PC} sp = {None: SP} all_mn_mode = defaultdict(list) all_mn_name = defaultdict(list) all_mn_inst = defaultdict(list) instruction = instruction_msp430 max_instruction_len = 8 @classmethod def getpc(cls, attrib): return PC @classmethod def getsp(cls, attrib): return SP @classmethod def check_mnemo(cls, fields): l = sum([x.l for x in fields]) assert l % 16 == 00, "len %r" % l @classmethod def getbits(cls, bs, attrib, start, n): if not n: return 0 o = 0 if n > bs.getlen() * 8: raise ValueError('not enought bits %r %r' % (n, len(bs.bin) * 8)) while n: i = start / 8 c = cls.getbytes(bs, i) if not c: raise IOError c = ord(c) r = 8 - start % 8 c &= (1 << r) - 1 l = min(r, n) c >>= (r - l) o <<= l o |= c n -= l start += l return o @classmethod def getbytes(cls, bs, offset, l=1): out = "" for _ in xrange(l): n_offset = (offset & ~1) + 1 - offset % 2 out += bs.getbytes(n_offset, 1) offset += 1 return out def decoded2bytes(self, result): tmp = super(mn_msp430, self).decoded2bytes(result) out = [] for x in tmp: o = "" while x: o += x[:2][::-1] x = x[2:] out.append(o) return out @classmethod def gen_modes(cls, subcls, name, bases, dct, fields): dct['mode'] = None return [(subcls, name, bases, dct, fields)] def additional_info(self): info = additional_info() return info @classmethod def getmn(cls, name): return name.upper() def reset_class(self): super(mn_msp430, self).reset_class() def getnextflow(self, loc_db): raise NotImplementedError('not fully functional')
Ancestors (in MRO)
- mn_msp430
- miasm2.core.cpu.cls_mn
- __builtin__.object
Class variables
var alignment
var all_mn
var all_mn_inst
var all_mn_mode
var all_mn_name
var args_symb
var bintree
var delayslot
var instruction
var max_instruction_len
var name
var num
var pc
var regs
var sp
Methods
def add_pre_dis_info(
self, prefix=None)
def add_pre_dis_info(self, prefix=None): return True
def additional_info(
self)
def additional_info(self): info = additional_info() return info
def args2str(
self)
def args2str(self): args = [] for arg in self.args: # XXX todo test if not (isinstance(arg, m2_expr.Expr) or isinstance(arg.expr, m2_expr.Expr)): raise ValueError('zarb arg type') x = str(arg) args.append(x) return args
def asm(
cls, instr, symbols=None)
Re asm instruction by searching mnemo using name and args. We then can modify args and get the hex of a modified instruction
@classmethod def asm(cls, instr, symbols=None): """ Re asm instruction by searching mnemo using name and args. We then can modify args and get the hex of a modified instruction """ clist = cls.all_mn_name[instr.name] clist = [x for x in clist] vals = [] candidates = [] args = instr.resolve_args_with_symbols(symbols) for cc in clist: for c in cls.get_cls_instance( cc, instr.mode, instr.additional_info): cannot_parse = False if len(c.args) != len(instr.args): continue # only fix args expr for i in xrange(len(c.args)): c.args[i].expr = args[i] v = c.value(instr.mode) if not v: log.debug("cannot encode %r", c) cannot_parse = True if cannot_parse: continue vals += v candidates.append((c, v)) if len(vals) == 0: raise ValueError('cannot asm %r %r' % (instr.name, [str(x) for x in instr.args])) if len(vals) != 1: log.debug('asm multiple args ret default') vals = cls.filter_asm_candidates(instr, candidates) return vals
def check_mnemo(
cls, fields)
@classmethod def check_mnemo(cls, fields): l = sum([x.l for x in fields]) assert l % 16 == 00, "len %r" % l
def decoded2bytes(
self, result)
def decoded2bytes(self, result): tmp = super(mn_msp430, self).decoded2bytes(result) out = [] for x in tmp: o = "" while x: o += x[:2][::-1] x = x[2:] out.append(o) return out
def dis(
cls, bs_o, mode_o=None, offset=0)
@classmethod def dis(cls, bs_o, mode_o = None, offset=0): if not isinstance(bs_o, bin_stream): bs_o = bin_stream_str(bs_o) bs_o.enter_atomic_mode() offset_o = offset try: pre_dis_info, bs, mode, offset, prefix_len = cls.pre_dis( bs_o, mode_o, offset) except: bs_o.leave_atomic_mode() raise candidates = cls.guess_mnemo(bs, mode, pre_dis_info, offset) if not candidates: bs_o.leave_atomic_mode() raise Disasm_Exception('cannot disasm (guess) at %X' % offset) out = [] out_c = [] if hasattr(bs, 'getlen'): bs_l = bs.getlen() else: bs_l = len(bs) alias = False for c in candidates: log.debug("*" * 40, mode, c.mode) log.debug(c.fields) c = cls.all_mn_inst[c][0] c.reset_class() c.mode = mode if not c.add_pre_dis_info(pre_dis_info): continue todo = {} getok = True fname_values = dict(pre_dis_info) offset_b = offset * 8 total_l = 0 for i, f in enumerate(c.fields_order): if f.flen is not None: l = f.flen(mode, fname_values) else: l = f.l if l is not None: total_l += l f.l = l f.is_present = True log.debug("FIELD %s %s %s %s", f.__class__, f.fname, offset_b, l) if bs_l * 8 - offset_b < l: getok = False break try: bv = cls.getbits(bs, mode, offset_b, l) except: bs_o.leave_atomic_mode() raise offset_b += l if not f.fname in fname_values: fname_values[f.fname] = bv todo[i] = bv else: f.is_present = False todo[i] = None if not getok: continue c.l = prefix_len + total_l / 8 for i in c.to_decode: f = c.fields_order[i] if f.is_present: ret = f.decode(todo[i]) if not ret: log.debug("cannot decode %r", f) break if not ret: continue for a in c.args: a.expr = expr_simp(a.expr) c.b = cls.getbytes(bs, offset_o, c.l) c.offset = offset_o c = c.post_dis() if c is None: continue c_args = [a.expr for a in c.args] instr = cls.instruction(c.name, mode, c_args, additional_info=c.additional_info()) instr.l = prefix_len + total_l / 8 instr.b = cls.getbytes(bs, offset_o, instr.l) instr.offset = offset_o instr.get_info(c) if c.alias: alias = True out.append(instr) out_c.append(c) bs_o.leave_atomic_mode() if not out: raise Disasm_Exception('cannot disasm at %X' % offset_o) if len(out) != 1: if not alias: log.warning('dis multiple args ret default') for i, o in enumerate(out_c): if o.alias: return out[i] raise NotImplementedError('Multiple disas: \n' + "\n".join([str(x) for x in out])) return out[0]
def dup_info(
self, infos)
def dup_info(self, infos): return
def encodefields(
self, decoded)
def encodefields(self, decoded): bits = bitobj() for _, f in decoded: setattr(self, f.fname, f) if f.value is None: continue bits.putbits(f.value, f.l) return bits.tostring()
def filter_asm_candidates(
cls, instr, candidates)
@classmethod def filter_asm_candidates(cls, instr, candidates): o = [] for _, v in candidates: o += v o.sort(key=len) return o
def fromstring(
cls, text, loc_db, mode=None)
@classmethod def fromstring(cls, text, loc_db, mode = None): global total_scans name = re.search('(\S+)', text).groups() if not name: raise ValueError('cannot find name', text) name = name[0] if not name in cls.all_mn_name: raise ValueError('unknown name', name) clist = [x for x in cls.all_mn_name[name]] out = [] out_args = [] parsers = defaultdict(dict) for cc in clist: for c in cls.get_cls_instance(cc, mode): args_expr = [] args_str = text[len(name):].strip(' ') start = 0 cannot_parse = False len_o = len(args_str) for i, f in enumerate(c.args): start_i = len_o - len(args_str) if type(f.parser) == tuple: parser = f.parser else: parser = (f.parser,) for p in parser: if p in parsers[(i, start_i)]: continue try: total_scans += 1 v, start, stop = p.scanString(args_str).next() except StopIteration: v, start, stop = [None], None, None if start != 0: v, start, stop = [None], None, None if v != [None]: v = f.asm_ast_to_expr(v[0], loc_db) if v is None: v, start, stop = [None], None, None parsers[(i, start_i)][p] = v, start, stop start, stop = f.fromstring(args_str, loc_db, parsers[(i, start_i)]) if start != 0: log.debug("cannot fromstring %r", args_str) cannot_parse = True break if f.expr is None: raise NotImplementedError('not fully functional') f.expr = expr_simp(f.expr) args_expr.append(f.expr) args_str = args_str[stop:].strip(' ') if args_str.startswith(','): args_str = args_str[1:] args_str = args_str.strip(' ') if args_str: cannot_parse = True if cannot_parse: continue out.append(c) out_args.append(args_expr) break if len(out) == 0: raise ValueError('cannot fromstring %r' % text) if len(out) != 1: log.debug('fromstring multiple args ret default') c = out[0] c_args = out_args[0] instr = cls.instruction(c.name, mode, c_args, additional_info=c.additional_info()) return instr
def gen_args(
self, args)
def gen_args(self, args): out = ', '.join([str(x) for x in args]) return out
def gen_modes(
cls, subcls, name, bases, dct, fields)
@classmethod def gen_modes(cls, subcls, name, bases, dct, fields): dct['mode'] = None return [(subcls, name, bases, dct, fields)]
def get_cls_instance(
cls, cc, mode, infos=None)
@classmethod def get_cls_instance(cls, cc, mode, infos=None): c = cls.all_mn_inst[cc][0] c.reset_class() c.add_pre_dis_info() c.dup_info(infos) c.mode = mode yield c
def getbits(
cls, bs, attrib, start, n)
@classmethod def getbits(cls, bs, attrib, start, n): if not n: return 0 o = 0 if n > bs.getlen() * 8: raise ValueError('not enought bits %r %r' % (n, len(bs.bin) * 8)) while n: i = start / 8 c = cls.getbytes(bs, i) if not c: raise IOError c = ord(c) r = 8 - start % 8 c &= (1 << r) - 1 l = min(r, n) c >>= (r - l) o <<= l o |= c n -= l start += l return o
def getbytes(
cls, bs, offset, l=1)
@classmethod def getbytes(cls, bs, offset, l=1): out = "" for _ in xrange(l): n_offset = (offset & ~1) + 1 - offset % 2 out += bs.getbytes(n_offset, 1) offset += 1 return out
def getdstflow(
self, loc_db)
def getdstflow(self, loc_db): return [self.args[0].expr]
def getmn(
cls, name)
@classmethod def getmn(cls, name): return name.upper()
def getnextflow(
self, loc_db)
def getnextflow(self, loc_db): raise NotImplementedError('not fully functional')
def getpc(
cls, attrib)
@classmethod def getpc(cls, attrib): return PC
def getsp(
cls, attrib)
@classmethod def getsp(cls, attrib): return SP
def guess_mnemo(
cls, bs, attrib, pre_dis_info, offset)
@classmethod def guess_mnemo(cls, bs, attrib, pre_dis_info, offset): candidates = [] candidates = set() fname_values = pre_dis_info todo = [(dict(fname_values), branch, offset * 8) for branch in cls.bintree.items()] for fname_values, branch, offset_b in todo: (l, fmask, fbits, fname, flen), vals = branch if flen is not None: l = flen(attrib, fname_values) if l is not None: try: v = cls.getbits(bs, attrib, offset_b, l) except IOError: # Raised if offset is out of bound continue offset_b += l if v & fmask != fbits: continue if fname is not None and not fname in fname_values: fname_values[fname] = v for nb, v in vals.items(): if 'mn' in nb: candidates.update(v) else: todo.append((dict(fname_values), (nb, v), offset_b)) return [c for c in candidates]
def init_class(
self)
def init_class(self): args = [] fields_order = [] to_decode = [] off = 0 for i, fc in enumerate(self.fields): f = fc.gen(self) f.offset = off off += f.l fields_order.append(f) to_decode.append((i, f)) if isinstance(f, m_arg): args.append(f) if f.fname: setattr(self, f.fname, f) if hasattr(self, 'args_permut'): args = [args[self.args_permut[i]] for i in xrange(len(self.args_permut))] to_decode.sort(key=lambda x: (x[1].order, x[0])) to_decode = [fields_order.index(f[1]) for f in to_decode] self.args = args self.fields_order = fields_order self.to_decode = to_decode
def mod_fields(
cls, fields)
@classmethod def mod_fields(cls, fields): return fields
def parse_prefix(
self, v)
def parse_prefix(self, v): return 0
def post_dis(
self)
def post_dis(self): return self
def pre_dis(
cls, v_o, attrib, offset)
@classmethod def pre_dis(cls, v_o, attrib, offset): return {}, v_o, attrib, offset, 0
def reset_class(
self)
def reset_class(self): super(mn_msp430, self).reset_class()
def set_dst_symbol(
self, loc_db)
def set_dst_symbol(self, loc_db): dst = self.getdstflow(loc_db) args = [] for d in dst: if isinstance(d, m2_expr.ExprInt): l = loc_db.get_or_create_offset_location(int(d)) a = m2_expr.ExprId(l.name, d.size) else: a = d args.append(a) self.args_symb = args
def value(
self, mode)
def value(self, mode): todo = [(0, 0, [(x, self.fields_order[x]) for x in self.to_decode[::-1]])] result = [] done = [] while todo: index, cur_len, to_decode = todo.pop() # TEST XXX for _, f in to_decode: setattr(self, f.fname, f) if (index, [x[1].value for x in to_decode]) in done: continue done.append((index, [x[1].value for x in to_decode])) can_encode = True for i, f in to_decode[index:]: f.parent.l = cur_len ret = f.encode() if not ret: log.debug('cannot encode %r', f) can_encode = False break if f.value is not None and f.l: assert f.value <= f.lmask cur_len += f.l index += 1 if ret is True: continue for _ in ret: o = [] if ((index, cur_len, [xx[1].value for xx in to_decode]) in todo or (index, cur_len, [xx[1].value for xx in to_decode]) in done): raise NotImplementedError('not fully functional') for p, f in to_decode: fnew = f.clone() o.append((p, fnew)) todo.append((index, cur_len, o)) can_encode = False break if not can_encode: continue result.append(to_decode) return self.decoded2bytes(result)
class msp430_arg
class msp430_arg(m_arg): def asm_ast_to_expr(self, value, loc_db): if isinstance(value, AstId): name = value.name if isinstance(name, Expr): return name assert isinstance(name, str) if name in gpregs.str: index = gpregs.str.index(name) reg = gpregs.expr[index] return reg loc_key = loc_db.get_or_create_name_location(value.name) return ExprLoc(loc_key, 16) if isinstance(value, AstOp): args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in value.args] if None in args: return None return ExprOp(value.op, *args) if isinstance(value, AstInt): return ExprInt(value.value, 16) if isinstance(value, AstMem): ptr = self.asm_ast_to_expr(value.ptr, loc_db) if ptr is None: return None return ExprMem(ptr, value.size) return None
Ancestors (in MRO)
- msp430_arg
- miasm2.core.cpu.m_arg
- __builtin__.object
Methods
def asm_ast_to_expr(
self, value, loc_db)
def asm_ast_to_expr(self, value, loc_db): if isinstance(value, AstId): name = value.name if isinstance(name, Expr): return name assert isinstance(name, str) if name in gpregs.str: index = gpregs.str.index(name) reg = gpregs.expr[index] return reg loc_key = loc_db.get_or_create_name_location(value.name) return ExprLoc(loc_key, 16) if isinstance(value, AstOp): args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in value.args] if None in args: return None return ExprOp(value.op, *args) if isinstance(value, AstInt): return ExprInt(value.value, 16) if isinstance(value, AstMem): ptr = self.asm_ast_to_expr(value.ptr, loc_db) if ptr is None: return None return ExprMem(ptr, value.size) return None
def fromstring(
self, text, loc_db, parser_result=None)
def fromstring(self, text, loc_db, parser_result=None): if parser_result: e, start, stop = parser_result[self.parser] self.expr = e return start, stop try: v, start, stop = self.parser.scanString(text).next() except StopIteration: return None, None arg = v[0] expr = self.asm_ast_to_expr(arg, loc_db) self.expr = expr return start, stop
class msp430_dreg_arg
class msp430_dreg_arg(msp430_sreg_arg): prio = default_prio + 1 reg_info = gpregs parser = sreg_p def decode(self, v): if hasattr(self.parent, 'size'): size = [16, 8][self.parent.size.value] else: size = 16 v = v & self.lmask e = self.reg_info.expr[v] if self.parent.a_d.value == 0: self.expr = e elif self.parent.a_d.value == 1: if e == SR: x = ExprInt(self.parent.off_d.value, 16) else: x = e + ExprInt(self.parent.off_d.value, 16) self.expr = ExprMem(x, size) else: raise NotImplementedError( "unknown value self.parent.a_d.value = " + "%d" % self.parent.a_d.value) return True def encode(self): e = self.expr if e in self.reg_info.expr: self.parent.a_d.value = 0 self.value = self.reg_info.expr.index(e) elif isinstance(e, ExprMem): if isinstance(e.arg, ExprId): r, i = e.arg, ExprInt(0, 16) elif isinstance(e.arg, ExprOp): r, i = e.arg.args[0], e.arg.args[1] elif isinstance(e.arg, ExprInt): r, i = SR, e.arg else: raise NotImplementedError( 'unknown instance e.arg = %s' % type(e.arg)) self.parent.a_d.value = 1 self.value = self.reg_info.expr.index(r) self.parent.off_d.value = int(i) else: raise NotImplementedError('unknown instance e = %s' % type(e)) return True
Ancestors (in MRO)
- msp430_dreg_arg
- msp430_sreg_arg
- miasm2.core.cpu.reg_noarg
- msp430_arg
- miasm2.core.cpu.m_arg
- __builtin__.object
Class variables
Methods
def asm_ast_to_expr(
self, value, loc_db)
Inheritance:
msp430_sreg_arg
.asm_ast_to_expr
def asm_ast_to_expr(self, value, loc_db): if isinstance(value, AstId): name = value.name if isinstance(name, Expr): return name assert isinstance(name, str) if name in gpregs.str: index = gpregs.str.index(name) reg = gpregs.expr[index] return reg loc_key = loc_db.get_or_create_name_location(value.name) return ExprLoc(loc_key, 16) if isinstance(value, AstOp): args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in value.args] if None in args: return None return ExprOp(value.op, *args) if isinstance(value, AstInt): return ExprInt(value.value, 16) if isinstance(value, AstMem): ptr = self.asm_ast_to_expr(value.ptr, loc_db) if ptr is None: return None return ExprMem(ptr, value.size) return None
def check_fbits(
self, v)
Inheritance:
msp430_sreg_arg
.check_fbits
def check_fbits(self, v): return v & self.fmask == self.fbits
def decode(
self, v)
Inheritance:
msp430_sreg_arg
.decode
def decode(self, v): if hasattr(self.parent, 'size'): size = [16, 8][self.parent.size.value] else: size = 16 v = v & self.lmask e = self.reg_info.expr[v] if self.parent.a_d.value == 0: self.expr = e elif self.parent.a_d.value == 1: if e == SR: x = ExprInt(self.parent.off_d.value, 16) else: x = e + ExprInt(self.parent.off_d.value, 16) self.expr = ExprMem(x, size) else: raise NotImplementedError( "unknown value self.parent.a_d.value = " + "%d" % self.parent.a_d.value) return True
def encode(
self)
Inheritance:
msp430_sreg_arg
.encode
def encode(self): e = self.expr if e in self.reg_info.expr: self.parent.a_d.value = 0 self.value = self.reg_info.expr.index(e) elif isinstance(e, ExprMem): if isinstance(e.arg, ExprId): r, i = e.arg, ExprInt(0, 16) elif isinstance(e.arg, ExprOp): r, i = e.arg.args[0], e.arg.args[1] elif isinstance(e.arg, ExprInt): r, i = SR, e.arg else: raise NotImplementedError( 'unknown instance e.arg = %s' % type(e.arg)) self.parent.a_d.value = 1 self.value = self.reg_info.expr.index(r) self.parent.off_d.value = int(i) else: raise NotImplementedError('unknown instance e = %s' % type(e)) return True
def fromstring(
self, text, loc_db, parser_result=None)
Inheritance:
msp430_sreg_arg
.fromstring
def fromstring(self, text, loc_db, parser_result=None): if parser_result: e, start, stop = parser_result[self.parser] self.expr = e return start, stop try: v, start, stop = self.parser.scanString(text).next() except StopIteration: return None, None arg = v[0] expr = self.parses_to_expr(arg, loc_db) self.expr = expr return start, stop
class msp430_offs
class msp430_offs(imm_noarg, msp430_arg): parser = base_expr def int2expr(self, v): if v & ~self.intmask != 0: return None return ExprInt(v, 16) def decodeval(self, v): v <<= 1 v += self.parent.l return v def encodeval(self, v): plen = self.parent.l + self.l assert(plen % 8 == 0) v -= plen / 8 if v % 2 != 0: return False return v >> 1 def decode(self, v): v = v & self.lmask if (1 << (self.l - 1)) & v: v |= ~0 ^ self.lmask v = self.decodeval(v) self.expr = ExprInt(v, 16) return True def encode(self): if not isinstance(self.expr, ExprInt): return False v = int(self.expr) if (1 << (self.l - 1)) & v: v = -((0xffff ^ v) + 1) v = self.encodeval(v) self.value = (v & 0xffff) & self.lmask return True
Ancestors (in MRO)
- msp430_offs
- miasm2.core.cpu.imm_noarg
- msp430_arg
- miasm2.core.cpu.m_arg
- __builtin__.object
Class variables
var intmask
var intsize
var parser
Methods
def asm_ast_to_expr(
self, value, loc_db)
Inheritance:
msp430_arg
.asm_ast_to_expr
def asm_ast_to_expr(self, value, loc_db): if isinstance(value, AstId): name = value.name if isinstance(name, Expr): return name assert isinstance(name, str) if name in gpregs.str: index = gpregs.str.index(name) reg = gpregs.expr[index] return reg loc_key = loc_db.get_or_create_name_location(value.name) return ExprLoc(loc_key, 16) if isinstance(value, AstOp): args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in value.args] if None in args: return None return ExprOp(value.op, *args) if isinstance(value, AstInt): return ExprInt(value.value, 16) if isinstance(value, AstMem): ptr = self.asm_ast_to_expr(value.ptr, loc_db) if ptr is None: return None return ExprMem(ptr, value.size) return None
def decode(
self, v)
def decode(self, v): v = v & self.lmask if (1 << (self.l - 1)) & v: v |= ~0 ^ self.lmask v = self.decodeval(v) self.expr = ExprInt(v, 16) return True
def decodeval(
self, v)
def decodeval(self, v): v <<= 1 v += self.parent.l return v
def encode(
self)
def encode(self): if not isinstance(self.expr, ExprInt): return False v = int(self.expr) if (1 << (self.l - 1)) & v: v = -((0xffff ^ v) + 1) v = self.encodeval(v) self.value = (v & 0xffff) & self.lmask return True
def encodeval(
self, v)
def encodeval(self, v): plen = self.parent.l + self.l assert(plen % 8 == 0) v -= plen / 8 if v % 2 != 0: return False return v >> 1
def expr2int(
self, e)
def expr2int(self, e): if not isinstance(e, m2_expr.ExprInt): return None v = int(e) if v & ~self.intmask != 0: return None return v
def fromstring(
self, text, loc_db, parser_result=None)
Inheritance:
msp430_arg
.fromstring
def fromstring(self, text, loc_db, parser_result=None): if parser_result: e, start, stop = parser_result[self.parser] else: try: e, start, stop = self.parser.scanString(text).next() except StopIteration: return None, None if e == [None]: return None, None assert(isinstance(e, m2_expr.Expr)) if isinstance(e, tuple): self.expr = self.int2expr(e[1]) elif isinstance(e, m2_expr.Expr): self.expr = e else: raise TypeError('zarb expr') if self.expr is None: log.debug('cannot fromstring int %r', text) return None, None return start, stop
def int2expr(
self, v)
def int2expr(self, v): if v & ~self.intmask != 0: return None return ExprInt(v, 16)
class msp430_sreg_arg
class msp430_sreg_arg(reg_noarg, msp430_arg): prio = default_prio + 1 reg_info = gpregs parser = sreg_p def decode(self, v): size = 16 if hasattr(self.parent, 'size'): size = [16, 8][self.parent.size.value] v = v & self.lmask e = self.reg_info.expr[v] if self.parent.a_s.value == 0b00: if e == R3: self.expr = ExprInt(0, size) else: self.expr = e elif self.parent.a_s.value == 0b01: if e == SR: self.expr = ExprMem(ExprInt(self.parent.off_s.value, 16), size) elif e == R3: self.expr = ExprInt(1, size) else: self.expr = ExprMem( e + ExprInt(self.parent.off_s.value, 16), size) elif self.parent.a_s.value == 0b10: if e == SR: self.expr = ExprInt(4, size) elif e == R3: self.expr = ExprInt(2, size) else: self.expr = ExprMem(e, size) elif self.parent.a_s.value == 0b11: if e == SR: self.expr = ExprInt(8, size) elif e == R3: if self.parent.size.value == 0: self.expr = ExprInt(0xffff, size) else: self.expr = ExprInt(0xff, size) elif e == PC: self.expr = ExprInt(self.parent.off_s.value, size) else: self.expr = ExprOp('autoinc', e) else: raise NotImplementedError( "unknown value self.parent.a_s.value = " + "%d" % self.parent.a_s.value) return True def encode(self): e = self.expr if e in self.reg_info.expr: self.parent.a_s.value = 0 self.value = self.reg_info.expr.index(e) elif isinstance(e, ExprInt): v = int(e) if v == 0xffff and self.parent.size.value == 0: self.parent.a_s.value = 0b11 self.value = 3 elif v == 0xff and self.parent.size.value == 1: self.parent.a_s.value = 0b11 self.value = 3 elif v == 2: self.parent.a_s.value = 0b10 self.value = 3 elif v == 1: self.parent.a_s.value = 0b01 self.value = 3 elif v == 8: self.parent.a_s.value = 0b11 self.value = 2 elif v == 4: self.parent.a_s.value = 0b10 self.value = 2 elif v == 0: self.parent.a_s.value = 0b00 self.value = 3 else: self.parent.a_s.value = 0b11 self.value = 0 self.parent.off_s.value = v elif isinstance(e, ExprMem): if isinstance(e.arg, ExprId): self.parent.a_s.value = 0b10 self.value = self.reg_info.expr.index(e.arg) elif isinstance(e.arg, ExprInt): self.parent.a_s.value = 0b01 self.value = self.reg_info.expr.index(SR) self.parent.off_s.value = int(e.arg) elif isinstance(e.arg, ExprOp): self.parent.a_s.value = 0b01 self.value = self.reg_info.expr.index(e.arg.args[0]) self.parent.off_s.value = int(e.arg.args[1]) else: raise NotImplementedError( 'unknown instance e.arg = %s' % type(e.arg)) elif isinstance(e, ExprOp) and e.op == "autoinc": self.parent.a_s.value = 0b11 self.value = self.reg_info.expr.index(e.args[0]) else: raise NotImplementedError('unknown instance e = %s' % type(e)) return True
Ancestors (in MRO)
- msp430_sreg_arg
- miasm2.core.cpu.reg_noarg
- msp430_arg
- miasm2.core.cpu.m_arg
- __builtin__.object
Class variables
var parser
var prio
var reg_info
Methods
def asm_ast_to_expr(
self, value, loc_db)
Inheritance:
msp430_arg
.asm_ast_to_expr
def asm_ast_to_expr(self, value, loc_db): if isinstance(value, AstId): name = value.name if isinstance(name, Expr): return name assert isinstance(name, str) if name in gpregs.str: index = gpregs.str.index(name) reg = gpregs.expr[index] return reg loc_key = loc_db.get_or_create_name_location(value.name) return ExprLoc(loc_key, 16) if isinstance(value, AstOp): args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in value.args] if None in args: return None return ExprOp(value.op, *args) if isinstance(value, AstInt): return ExprInt(value.value, 16) if isinstance(value, AstMem): ptr = self.asm_ast_to_expr(value.ptr, loc_db) if ptr is None: return None return ExprMem(ptr, value.size) return None
def check_fbits(
self, v)
def check_fbits(self, v): return v & self.fmask == self.fbits
def decode(
self, v)
def decode(self, v): size = 16 if hasattr(self.parent, 'size'): size = [16, 8][self.parent.size.value] v = v & self.lmask e = self.reg_info.expr[v] if self.parent.a_s.value == 0b00: if e == R3: self.expr = ExprInt(0, size) else: self.expr = e elif self.parent.a_s.value == 0b01: if e == SR: self.expr = ExprMem(ExprInt(self.parent.off_s.value, 16), size) elif e == R3: self.expr = ExprInt(1, size) else: self.expr = ExprMem( e + ExprInt(self.parent.off_s.value, 16), size) elif self.parent.a_s.value == 0b10: if e == SR: self.expr = ExprInt(4, size) elif e == R3: self.expr = ExprInt(2, size) else: self.expr = ExprMem(e, size) elif self.parent.a_s.value == 0b11: if e == SR: self.expr = ExprInt(8, size) elif e == R3: if self.parent.size.value == 0: self.expr = ExprInt(0xffff, size) else: self.expr = ExprInt(0xff, size) elif e == PC: self.expr = ExprInt(self.parent.off_s.value, size) else: self.expr = ExprOp('autoinc', e) else: raise NotImplementedError( "unknown value self.parent.a_s.value = " + "%d" % self.parent.a_s.value) return True
def encode(
self)
def encode(self): e = self.expr if e in self.reg_info.expr: self.parent.a_s.value = 0 self.value = self.reg_info.expr.index(e) elif isinstance(e, ExprInt): v = int(e) if v == 0xffff and self.parent.size.value == 0: self.parent.a_s.value = 0b11 self.value = 3 elif v == 0xff and self.parent.size.value == 1: self.parent.a_s.value = 0b11 self.value = 3 elif v == 2: self.parent.a_s.value = 0b10 self.value = 3 elif v == 1: self.parent.a_s.value = 0b01 self.value = 3 elif v == 8: self.parent.a_s.value = 0b11 self.value = 2 elif v == 4: self.parent.a_s.value = 0b10 self.value = 2 elif v == 0: self.parent.a_s.value = 0b00 self.value = 3 else: self.parent.a_s.value = 0b11 self.value = 0 self.parent.off_s.value = v elif isinstance(e, ExprMem): if isinstance(e.arg, ExprId): self.parent.a_s.value = 0b10 self.value = self.reg_info.expr.index(e.arg) elif isinstance(e.arg, ExprInt): self.parent.a_s.value = 0b01 self.value = self.reg_info.expr.index(SR) self.parent.off_s.value = int(e.arg) elif isinstance(e.arg, ExprOp): self.parent.a_s.value = 0b01 self.value = self.reg_info.expr.index(e.arg.args[0]) self.parent.off_s.value = int(e.arg.args[1]) else: raise NotImplementedError( 'unknown instance e.arg = %s' % type(e.arg)) elif isinstance(e, ExprOp) and e.op == "autoinc": self.parent.a_s.value = 0b11 self.value = self.reg_info.expr.index(e.args[0]) else: raise NotImplementedError('unknown instance e = %s' % type(e)) return True
def fromstring(
self, text, loc_db, parser_result=None)
Inheritance:
msp430_arg
.fromstring
def fromstring(self, text, loc_db, parser_result=None): if parser_result: e, start, stop = parser_result[self.parser] self.expr = e return start, stop try: v, start, stop = self.parser.scanString(text).next() except StopIteration: return None, None arg = v[0] expr = self.parses_to_expr(arg, loc_db) self.expr = expr return start, stop