miasm2.arch.mips32.arch module
#-*- coding:utf-8 -*- import logging from collections import defaultdict from pyparsing import Literal, Group, Optional from miasm2.expression.expression import ExprMem, ExprInt, ExprId, ExprOp, ExprLoc from miasm2.core.bin_stream import bin_stream import miasm2.arch.mips32.regs as regs import miasm2.core.cpu as cpu from miasm2.core.asm_ast import AstInt, AstId, AstMem, AstOp log = logging.getLogger("mips32dis") console_handler = logging.StreamHandler() console_handler.setFormatter(logging.Formatter("%(levelname)-5s: %(message)s")) log.addHandler(console_handler) log.setLevel(logging.DEBUG) gpregs = cpu.reg_info(regs.regs32_str, regs.regs32_expr) LPARENTHESIS = Literal("(") RPARENTHESIS = Literal(")") def cb_deref(tokens): if len(tokens) != 4: raise NotImplementedError("TODO") return AstMem(tokens[2] + tokens[0], 32) def cb_deref_nooff(tokens): if len(tokens) != 3: raise NotImplementedError("TODO") return AstMem(tokens[1], 32) base_expr = cpu.base_expr deref_off = (Optional(base_expr) + LPARENTHESIS + gpregs.parser + RPARENTHESIS).setParseAction(cb_deref) deref_nooff = (LPARENTHESIS + gpregs.parser + RPARENTHESIS).setParseAction(cb_deref_nooff) deref = deref_off | deref_nooff class additional_info: def __init__(self): self.except_on_instr = False br_0 = ['B', 'J', 'JR', 'BAL', 'JAL', 'JALR'] br_1 = ['BGEZ', 'BLTZ', 'BGTZ', 'BLEZ', 'BC1T', 'BC1F'] br_2 = ['BEQ', 'BEQL', 'BNE'] class instruction_mips32(cpu.instruction): __slots__ = [] delayslot = 1 def __init__(self, *args, **kargs): super(instruction_mips32, self).__init__(*args, **kargs) @staticmethod def arg2str(expr, index=None, loc_db=None): if expr.is_id() or expr.is_int(): return str(expr) elif expr.is_loc(): if loc_db is not None: return loc_db.pretty_str(expr.loc_key) else: return str(expr) assert(isinstance(expr, ExprMem)) arg = expr.arg if isinstance(arg, ExprId): return "(%s)"%arg assert(len(arg.args) == 2 and arg.op == '+') return "%s(%s)"%(arg.args[1], arg.args[0]) def dstflow(self): if self.name == 'BREAK': return False if self.name in br_0 + br_1 + br_2: return True return False def get_dst_num(self): if self.name in br_0: i = 0 elif self.name in br_1: i = 1 elif self.name in br_2: i = 2 else: raise NotImplementedError("TODO %s"%self) return i def dstflow2label(self, loc_db): if self.name in ["J", 'JAL']: expr = self.args[0].arg addr = (self.offset & (0xFFFFFFFF ^ ((1<< 28)-1))) + expr loc_key = loc_db.get_or_create_offset_location(addr) self.args[0] = ExprLoc(loc_key, expr.size) return ndx = self.get_dst_num() expr = self.args[ndx] if not isinstance(expr, ExprInt): return addr = expr.arg + self.offset loc_key = loc_db.get_or_create_offset_location(addr) self.args[ndx] = ExprLoc(loc_key, expr.size) def breakflow(self): if self.name == 'BREAK': return False if self.name in br_0 + br_1 + br_2: return True return False def is_subcall(self): if self.name in ['JAL', 'JALR', 'BAL']: return True return False def getdstflow(self, loc_db): if self.name in br_0: return [self.args[0]] elif self.name in br_1: return [self.args[1]] elif self.name in br_2: return [self.args[2]] elif self.name in ['JAL', 'JALR', 'JR', 'J']: return [self.args[0]] else: raise NotImplementedError("fix mnemo %s"%self.name) def splitflow(self): if self.name in ["B", 'JR', 'J']: return False if self.name in br_0: return True if self.name in br_1: return True if self.name in br_2: return True if self.name in ['JAL', 'JALR']: return True return False def get_symbol_size(self, symbol, loc_db): return 32 def fixDstOffset(self): ndx = self.get_dst_num() e = self.args[ndx] if self.offset is None: raise ValueError('symbol not resolved %s' % self.l) if not isinstance(e, ExprInt): return off = e.arg - self.offset if int(off % 4): raise ValueError('strange offset! %r' % off) self.args[ndx] = ExprInt(off, 32) def get_args_expr(self): args = [a for a in self.args] return args class mn_mips32(cpu.cls_mn): delayslot = 1 name = "mips32" regs = regs bintree = {} num = 0 all_mn = [] all_mn_mode = defaultdict(list) all_mn_name = defaultdict(list) all_mn_inst = defaultdict(list) pc = {'l':regs.PC, 'b':regs.PC} sp = {'l':regs.SP, 'b':regs.SP} instruction = instruction_mips32 max_instruction_len = 4 @classmethod def getpc(cls, attrib = None): return regs.PC @classmethod def getsp(cls, attrib = None): return regs.SP def additional_info(self): info = additional_info() return info @classmethod def getbits(cls, bitstream, attrib, start, n): if not n: return 0 o = 0 while n: offset = start / 8 n_offset = cls.endian_offset(attrib, offset) c = cls.getbytes(bitstream, n_offset, 1) 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 endian_offset(cls, attrib, offset): if attrib == "l": return (offset & ~3) + 3 - offset % 4 elif attrib == "b": return offset else: raise NotImplementedError('bad attrib') @classmethod def check_mnemo(cls, fields): l = sum([x.l for x in fields]) assert l == 32, "len %r" % l @classmethod def getmn(cls, name): return name.upper() @classmethod def gen_modes(cls, subcls, name, bases, dct, fields): dct['mode'] = None return [(subcls, name, bases, dct, fields)] def value(self, mode): v = super(mn_mips32, self).value(mode) if mode == 'l': return [x[::-1] for x in v] elif mode == 'b': return [x for x in v] else: raise NotImplementedError('bad attrib') def mips32op(name, fields, args=None, alias=False): dct = {"fields": fields} dct["alias"] = alias if args is not None: dct['args'] = args type(name, (mn_mips32,), dct) #type(name, (mn_mips32b,), dct) class mips32_arg(cpu.m_arg): def asm_ast_to_expr(self, arg, loc_db): if isinstance(arg, AstId): if isinstance(arg.name, ExprId): return arg.name if arg.name in gpregs.str: return None loc_key = loc_db.get_or_create_name_location(arg.name) return ExprLoc(loc_key, 32) if isinstance(arg, AstOp): args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args] if None in args: return None return ExprOp(arg.op, *args) if isinstance(arg, AstInt): return ExprInt(arg.value, 32) if isinstance(arg, AstMem): ptr = self.asm_ast_to_expr(arg.ptr, loc_db) if ptr is None: return None return ExprMem(ptr, arg.size) return None class mips32_reg(cpu.reg_noarg, mips32_arg): pass class mips32_gpreg(mips32_reg): reg_info = gpregs parser = reg_info.parser class mips32_fltpreg(mips32_reg): reg_info = regs.fltregs parser = reg_info.parser class mips32_fccreg(mips32_reg): reg_info = regs.fccregs parser = reg_info.parser class mips32_imm(cpu.imm_noarg): parser = base_expr class mips32_s16imm_noarg(mips32_imm): def decode(self, v): v = v & self.lmask v = cpu.sign_ext(v, 16, 32) self.expr = ExprInt(v, 32) return True def encode(self): if not isinstance(self.expr, ExprInt): return False v = self.expr.arg.arg if v & 0x80000000: nv = v & ((1 << 16) - 1) assert( v == cpu.sign_ext(nv, 16, 32)) v = nv self.value = v return True class mips32_soff_noarg(mips32_imm): def decode(self, v): v = v & self.lmask v <<= 2 v = cpu.sign_ext(v, 16+2, 32) # Add pipeline offset self.expr = ExprInt(v + 4, 32) return True def encode(self): if not isinstance(self.expr, ExprInt): return False # Remove pipeline offset v = int(self.expr.arg - 4) if v & 0x80000000: nv = v & ((1 << 16+2) - 1) assert( v == cpu.sign_ext(nv, 16+2, 32)) v = nv self.value = v>>2 return True class mips32_s16imm(mips32_s16imm_noarg, mips32_arg): pass class mips32_soff(mips32_soff_noarg, mips32_arg): pass class mips32_instr_index(mips32_imm, mips32_arg): def decode(self, v): v = v & self.lmask self.expr = ExprInt(v<<2, 32) return True def encode(self): if not isinstance(self.expr, ExprInt): return False v = self.expr.arg.arg if v & 3: return False v>>=2 if v > (1<<self.l): return False self.value = v return True class mips32_u16imm(mips32_imm, mips32_arg): def decode(self, v): v = v & self.lmask self.expr = ExprInt(v, 32) return True def encode(self): if not isinstance(self.expr, ExprInt): return False v = self.expr.arg.arg assert(v < (1<<16)) self.value = v return True class mips32_dreg_imm(mips32_arg): parser = deref def decode(self, v): imm = self.parent.imm.expr r = gpregs.expr[v] self.expr = ExprMem(r+imm, 32) return True def encode(self): e = self.expr if not isinstance(e, ExprMem): return False arg = e.arg if isinstance(arg, ExprId): self.parent.imm.expr = ExprInt(0, 32) r = arg elif len(arg.args) == 2 and arg.op == "+": self.parent.imm.expr = arg.args[1] r = arg.args[0] else: return False self.value = gpregs.expr.index(r) return True @staticmethod def arg2str(expr, index=None): assert(isinstance(expr, ExprMem)) arg = expr.arg if isinstance(arg, ExprId): return "(%s)"%arg assert(len(arg.args) == 2 and arg.op == '+') return "%s(%s)"%(arg.args[1], arg.args[0]) class mips32_esize(mips32_imm, mips32_arg): def decode(self, v): v = v & self.lmask self.expr = ExprInt(v+1, 32) return True def encode(self): if not isinstance(self.expr, ExprInt): return False v = self.expr.arg.arg -1 assert(v < (1<<16)) self.value = v return True class mips32_eposh(mips32_imm, mips32_arg): def decode(self, v): self.expr = ExprInt(v-int(self.parent.epos.expr)+1, 32) return True def encode(self): if not isinstance(self.expr, ExprInt): return False v = int(self.expr.arg) + int(self.parent.epos.expr) -1 self.value = v return True class mips32_cpr(mips32_arg): parser = regs.regs_cpr0_info.parser def decode(self, v): index = int(self.parent.cpr0.expr) << 3 index += v self.expr = regs.regs_cpr0_expr[index] return True def encode(self): e = self.expr if not e in regs.regs_cpr0_expr: return False index = regs.regs_cpr0_expr.index(e) self.value = index & 7 index >>=2 self.parent.cpr0.value = index return True rs = cpu.bs(l=5, cls=(mips32_gpreg,)) rt = cpu.bs(l=5, cls=(mips32_gpreg,)) rd = cpu.bs(l=5, cls=(mips32_gpreg,)) ft = cpu.bs(l=5, cls=(mips32_fltpreg,)) fs = cpu.bs(l=5, cls=(mips32_fltpreg,)) fd = cpu.bs(l=5, cls=(mips32_fltpreg,)) s16imm = cpu.bs(l=16, cls=(mips32_s16imm,)) u16imm = cpu.bs(l=16, cls=(mips32_u16imm,)) sa = cpu.bs(l=5, cls=(mips32_u16imm,)) base = cpu.bs(l=5, cls=(mips32_dreg_imm,)) soff = cpu.bs(l=16, cls=(mips32_soff,)) cpr0 = cpu.bs(l=5, cls=(mips32_imm,), fname="cpr0") cpr = cpu.bs(l=3, cls=(mips32_cpr,)) s16imm_noarg = cpu.bs(l=16, cls=(mips32_s16imm_noarg,), fname="imm", order=-1) hint = cpu.bs(l=5, default_val="00000") fcc = cpu.bs(l=3, cls=(mips32_fccreg,)) sel = cpu.bs(l=3, cls=(mips32_u16imm,)) code = cpu.bs(l=20, cls=(mips32_u16imm,)) esize = cpu.bs(l=5, cls=(mips32_esize,)) epos = cpu.bs(l=5, cls=(mips32_u16imm,), fname="epos", order=-1) eposh = cpu.bs(l=5, cls=(mips32_eposh,)) instr_index = cpu.bs(l=26, cls=(mips32_instr_index,)) bs_fmt = cpu.bs_mod_name(l=5, fname='fmt', mn_mod={0x10: '.S', 0x11: '.D', 0x14: '.W', 0x15: '.L', 0x16: '.PS'}) class bs_cond(cpu.bs_mod_name): mn_mod = ['.F', '.UN', '.EQ', '.UEQ', '.OLT', '.ULT', '.OLE', '.ULE', '.SF', '.NGLE', '.SEQ', '.NGL', '.LT', '.NGE', '.LE', '.NGT' ] def modname(self, name, f_i): raise NotImplementedError("Not implemented") class bs_cond_name(cpu.bs_divert): prio = 2 mn_mod = [['.F', '.UN', '.EQ', '.UEQ', '.OLT', '.ULT', '.OLE', '.ULE'], ['.SF', '.NGLE', '.SEQ', '.NGL', '.LT', '.NGE', '.LE', '.NGT'] ] def divert(self, index, candidates): out = [] for candidate in candidates: cls, name, bases, dct, fields = candidate cond1 = [f for f in fields if f.fname == "cond1"] assert(len(cond1) == 1) cond1 = cond1.pop() mm = self.mn_mod[cond1.value] for value, new_name in enumerate(mm): nfields = fields[:] s = cpu.int2bin(value, self.args['l']) args = dict(self.args) args.update({'strbits': s}) f = cpu.bs(**args) nfields[index] = f ndct = dict(dct) ndct['name'] = name + new_name out.append((cls, new_name, bases, ndct, nfields)) return out class bs_cond_mod(cpu.bs_mod_name): prio = 1 bs_cond = bs_cond_mod(l=4, mn_mod = ['.F', '.UN', '.EQ', '.UEQ', '.OLT', '.ULT', '.OLE', '.ULE', '.SF', '.NGLE', '.SEQ', '.NGL', '.LT', '.NGE', '.LE', '.NGT']) bs_arith = cpu.bs_name(l=6, name={'ADDU':0b100001, 'SUBU':0b100011, 'OR':0b100101, 'AND':0b100100, 'SLTU':0b101011, 'XOR':0b100110, 'SLT':0b101010, 'SUBU':0b100011, 'NOR':0b100111, 'MOVN':0b001011, 'MOVZ':0b001010, }) bs_shift = cpu.bs_name(l=6, name={'SLL':0b000000, 'SRL':0b000010, 'SRA':0b000011, }) bs_shift1 = cpu.bs_name(l=6, name={'SLLV':0b000100, 'SRLV':0b000110, 'SRAV':0b000111, }) bs_arithfmt = cpu.bs_name(l=6, name={'ADD':0b000000, 'SUB':0b000001, 'MUL':0b000010, 'DIV':0b000011, }) bs_s_l = cpu.bs_name(l=6, name = {"SW": 0b101011, "SH": 0b101001, "SB": 0b101000, "LW": 0b100011, "LH": 0b100001, "LB": 0b100000, "LHU": 0b100101, "LBU": 0b100100, "LWL": 0b100010, "LWR": 0b100110, "SWL": 0b101010, "SWR": 0b101110, }) bs_oax = cpu.bs_name(l=6, name = {"ORI": 0b001101, "ANDI": 0b001100, "XORI": 0b001110, }) bs_bcc = cpu.bs_name(l=5, name = {"BGEZ": 0b00001, "BGEZL": 0b00011, "BGEZAL": 0b10001, "BGEZALL": 0b10011, "BLTZ": 0b00000, "BLTZL": 0b00010, "BLTZAL": 0b10000, "BLTZALL": 0b10010, }) bs_code = cpu.bs(l=10) mips32op("addi", [cpu.bs('001000'), rs, rt, s16imm], [rt, rs, s16imm]) mips32op("addiu", [cpu.bs('001001'), rs, rt, s16imm], [rt, rs, s16imm]) mips32op("nop", [cpu.bs('0'*32)], alias = True) mips32op("lui", [cpu.bs('001111'), cpu.bs('00000'), rt, u16imm]) mips32op("oax", [bs_oax, rs, rt, u16imm], [rt, rs, u16imm]) mips32op("arith", [cpu.bs('000000'), rs, rt, rd, cpu.bs('00000'), bs_arith], [rd, rs, rt]) mips32op("shift1", [cpu.bs('000000'), rs, rt, rd, cpu.bs('00000'), bs_shift1], [rd, rt, rs]) mips32op("shift", [cpu.bs('000000'), cpu.bs('00000'), rt, rd, sa, bs_shift], [rd, rt, sa]) mips32op("rotr", [cpu.bs('000000'), cpu.bs('00001'), rt, rd, sa, cpu.bs('000010')], [rd, rt, sa]) mips32op("mul", [cpu.bs('011100'), rs, rt, rd, cpu.bs('00000'), cpu.bs('000010')], [rd, rs, rt]) mips32op("div", [cpu.bs('000000'), rs, rt, cpu.bs('0000000000'), cpu.bs('011010')]) mips32op("s_l", [bs_s_l, base, rt, s16imm_noarg], [rt, base]) #mips32op("mfc0", [bs('010000'), bs('00000'), rt, rd, bs('00000000'), sel]) mips32op("mfc0", [cpu.bs('010000'), cpu.bs('00000'), rt, cpr0, cpu.bs('00000000'), cpr]) mips32op("mfc1", [cpu.bs('010001'), cpu.bs('00000'), rt, fs, cpu.bs('00000000000')]) mips32op("ldc1", [cpu.bs('110101'), base, ft, s16imm_noarg], [ft, base]) mips32op("mov", [cpu.bs('010001'), bs_fmt, cpu.bs('00000'), fs, fd, cpu.bs('000110')], [fd, fs]) mips32op("add", [cpu.bs('010001'), bs_fmt, ft, fs, fd, bs_arithfmt], [fd, fs, ft]) mips32op("divu", [cpu.bs('000000'), rs, rt, cpu.bs('0000000000'), cpu.bs('011011')]) mips32op("mult", [cpu.bs('000000'), rs, rt, cpu.bs('0000000000'), cpu.bs('011000')]) mips32op("multu", [cpu.bs('000000'), rs, rt, cpu.bs('0000000000'), cpu.bs('011001')]) mips32op("mflo", [cpu.bs('000000'), cpu.bs('0000000000'), rd, cpu.bs('00000'), cpu.bs('010010')]) mips32op("mfhi", [cpu.bs('000000'), cpu.bs('0000000000'), rd, cpu.bs('00000'), cpu.bs('010000')]) mips32op("b", [cpu.bs('000100'), cpu.bs('00000'), cpu.bs('00000'), soff], alias = True) mips32op("bne", [cpu.bs('000101'), rs, rt, soff]) mips32op("beq", [cpu.bs('000100'), rs, rt, soff]) mips32op("blez", [cpu.bs('000110'), rs, cpu.bs('00000'), soff]) mips32op("bcc", [cpu.bs('000001'), rs, bs_bcc, soff]) mips32op("bgtz", [cpu.bs('000111'), rs, cpu.bs('00000'), soff]) mips32op("bal", [cpu.bs('000001'), cpu.bs('00000'), cpu.bs('10001'), soff], alias = True) mips32op("slti", [cpu.bs('001010'), rs, rt, s16imm], [rt, rs, s16imm]) mips32op("sltiu", [cpu.bs('001011'), rs, rt, s16imm], [rt, rs, s16imm]) mips32op("j", [cpu.bs('000010'), instr_index]) mips32op("jal", [cpu.bs('000011'), instr_index]) mips32op("jalr", [cpu.bs('000000'), rs, cpu.bs('00000'), rd, hint, cpu.bs('001001')]) mips32op("jr", [cpu.bs('000000'), rs, cpu.bs('0000000000'), hint, cpu.bs('001000')]) mips32op("lwc1", [cpu.bs('110001'), base, ft, s16imm_noarg], [ft, base]) #mips32op("mtc0", [bs('010000'), bs('00100'), rt, rd, bs('00000000'), sel]) mips32op("mtc0", [cpu.bs('010000'), cpu.bs('00100'), rt, cpr0, cpu.bs('00000000'), cpr]) mips32op("mtc1", [cpu.bs('010001'), cpu.bs('00100'), rt, fs, cpu.bs('00000000000')]) # XXXX TODO CFC1 mips32op("cfc1", [cpu.bs('010001'), cpu.bs('00010'), rt, fs, cpu.bs('00000000000')]) # XXXX TODO CTC1 mips32op("ctc1", [cpu.bs('010001'), cpu.bs('00110'), rt, fs, cpu.bs('00000000000')]) mips32op("break", [cpu.bs('000000'), code, cpu.bs('001101')]) mips32op("syscall", [cpu.bs('000000'), code, cpu.bs('001100')]) mips32op("c", [cpu.bs('010001'), bs_fmt, ft, fs, fcc, cpu.bs('0'), cpu.bs('0'), cpu.bs('11'), bs_cond], [fcc, fs, ft]) mips32op("bc1t", [cpu.bs('010001'), cpu.bs('01000'), fcc, cpu.bs('0'), cpu.bs('1'), soff]) mips32op("bc1f", [cpu.bs('010001'), cpu.bs('01000'), fcc, cpu.bs('0'), cpu.bs('0'), soff]) mips32op("swc1", [cpu.bs('111001'), base, ft, s16imm_noarg], [ft, base]) mips32op("cvt.d", [cpu.bs('010001'), bs_fmt, cpu.bs('00000'), fs, fd, cpu.bs('100001')], [fd, fs]) mips32op("cvt.w", [cpu.bs('010001'), bs_fmt, cpu.bs('00000'), fs, fd, cpu.bs('100100')], [fd, fs]) mips32op("cvt.s", [cpu.bs('010001'), bs_fmt, cpu.bs('00000'), fs, fd, cpu.bs('100000')], [fd, fs]) mips32op("ext", [cpu.bs('011111'), rs, rt, esize, epos, cpu.bs('000000')], [rt, rs, epos, esize]) mips32op("ins", [cpu.bs('011111'), rs, rt, eposh, epos, cpu.bs('000100')], [rt, rs, epos, eposh]) mips32op("seb", [cpu.bs('011111'), cpu.bs('00000'), rt, rd, cpu.bs('10000'), cpu.bs('100000')], [rd, rt]) mips32op("seh", [cpu.bs('011111'), cpu.bs('00000'), rt, rd, cpu.bs('11000'), cpu.bs('100000')], [rd, rt]) mips32op("wsbh", [cpu.bs('011111'), cpu.bs('00000'), rt, rd, cpu.bs('00010'), cpu.bs('100000')], [rd, rt]) mips32op("di", [cpu.bs('010000'), cpu.bs('01011'), rt, cpu.bs('01100'), cpu.bs('00000'), cpu.bs('0'), cpu.bs('00'), cpu.bs('000')]) mips32op("ei", [cpu.bs('010000'), cpu.bs('01011'), rt, cpu.bs('01100'), cpu.bs('00000'), cpu.bs('1'), cpu.bs('00'), cpu.bs('000')]) mips32op("tlbp", [cpu.bs('010000'), cpu.bs('1'), cpu.bs('0'*19), cpu.bs('001000')]) mips32op("tlbwi", [cpu.bs('010000'), cpu.bs('1'), cpu.bs('0'*19), cpu.bs('000010')]) mips32op("teq", [cpu.bs('000000'), rs, rt, bs_code, cpu.bs('110100')], [rs, rt])
Module variables
var LPARENTHESIS
var RPARENTHESIS
var base
var base_expr
var br_0
var br_1
var br_2
var bs_arith
var bs_arithfmt
var bs_bcc
var bs_code
var bs_cond
var bs_fmt
var bs_oax
var bs_s_l
var bs_shift
var bs_shift1
var code
var console_handler
var cpr
var cpr0
var deref
var deref_nooff
var deref_off
var epos
var eposh
var esize
var fcc
var fd
var fs
var ft
var gpregs
var hint
var instr_index
var log
var rd
var rs
var rt
var s16imm
var s16imm_noarg
var sa
var sel
var soff
var u16imm
Functions
def cb_deref(
tokens)
def cb_deref(tokens): if len(tokens) != 4: raise NotImplementedError("TODO") return AstMem(tokens[2] + tokens[0], 32)
def cb_deref_nooff(
tokens)
def cb_deref_nooff(tokens): if len(tokens) != 3: raise NotImplementedError("TODO") return AstMem(tokens[1], 32)
def mips32op(
name, fields, args=None, alias=False)
def mips32op(name, fields, args=None, alias=False): dct = {"fields": fields} dct["alias"] = alias if args is not None: dct['args'] = args type(name, (mn_mips32,), dct)
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_mod
class bs_cond_mod(cpu.bs_mod_name): prio = 1
Ancestors (in MRO)
- bs_cond_mod
- miasm2.core.cpu.bs_mod_name
- miasm2.core.cpu.bs_divert
- __builtin__.object
Class variables
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 bs_cond_name
class bs_cond_name(cpu.bs_divert): prio = 2 mn_mod = [['.F', '.UN', '.EQ', '.UEQ', '.OLT', '.ULT', '.OLE', '.ULE'], ['.SF', '.NGLE', '.SEQ', '.NGL', '.LT', '.NGE', '.LE', '.NGT'] ] def divert(self, index, candidates): out = [] for candidate in candidates: cls, name, bases, dct, fields = candidate cond1 = [f for f in fields if f.fname == "cond1"] assert(len(cond1) == 1) cond1 = cond1.pop() mm = self.mn_mod[cond1.value] for value, new_name in enumerate(mm): nfields = fields[:] s = cpu.int2bin(value, self.args['l']) args = dict(self.args) args.update({'strbits': s}) f = cpu.bs(**args) nfields[index] = f ndct = dict(dct) ndct['name'] = name + new_name out.append((cls, new_name, bases, ndct, nfields)) return out
Ancestors (in MRO)
- bs_cond_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, index, candidates)
def divert(self, index, candidates): out = [] for candidate in candidates: cls, name, bases, dct, fields = candidate cond1 = [f for f in fields if f.fname == "cond1"] assert(len(cond1) == 1) cond1 = cond1.pop() mm = self.mn_mod[cond1.value] for value, new_name in enumerate(mm): nfields = fields[:] s = cpu.int2bin(value, self.args['l']) args = dict(self.args) args.update({'strbits': s}) f = cpu.bs(**args) nfields[index] = f ndct = dict(dct) ndct['name'] = name + new_name out.append((cls, new_name, bases, ndct, nfields)) return out
class instruction_mips32
class instruction_mips32(cpu.instruction): __slots__ = [] delayslot = 1 def __init__(self, *args, **kargs): super(instruction_mips32, self).__init__(*args, **kargs) @staticmethod def arg2str(expr, index=None, loc_db=None): if expr.is_id() or expr.is_int(): return str(expr) elif expr.is_loc(): if loc_db is not None: return loc_db.pretty_str(expr.loc_key) else: return str(expr) assert(isinstance(expr, ExprMem)) arg = expr.arg if isinstance(arg, ExprId): return "(%s)"%arg assert(len(arg.args) == 2 and arg.op == '+') return "%s(%s)"%(arg.args[1], arg.args[0]) def dstflow(self): if self.name == 'BREAK': return False if self.name in br_0 + br_1 + br_2: return True return False def get_dst_num(self): if self.name in br_0: i = 0 elif self.name in br_1: i = 1 elif self.name in br_2: i = 2 else: raise NotImplementedError("TODO %s"%self) return i def dstflow2label(self, loc_db): if self.name in ["J", 'JAL']: expr = self.args[0].arg addr = (self.offset & (0xFFFFFFFF ^ ((1<< 28)-1))) + expr loc_key = loc_db.get_or_create_offset_location(addr) self.args[0] = ExprLoc(loc_key, expr.size) return ndx = self.get_dst_num() expr = self.args[ndx] if not isinstance(expr, ExprInt): return addr = expr.arg + self.offset loc_key = loc_db.get_or_create_offset_location(addr) self.args[ndx] = ExprLoc(loc_key, expr.size) def breakflow(self): if self.name == 'BREAK': return False if self.name in br_0 + br_1 + br_2: return True return False def is_subcall(self): if self.name in ['JAL', 'JALR', 'BAL']: return True return False def getdstflow(self, loc_db): if self.name in br_0: return [self.args[0]] elif self.name in br_1: return [self.args[1]] elif self.name in br_2: return [self.args[2]] elif self.name in ['JAL', 'JALR', 'JR', 'J']: return [self.args[0]] else: raise NotImplementedError("fix mnemo %s"%self.name) def splitflow(self): if self.name in ["B", 'JR', 'J']: return False if self.name in br_0: return True if self.name in br_1: return True if self.name in br_2: return True if self.name in ['JAL', 'JALR']: return True return False def get_symbol_size(self, symbol, loc_db): return 32 def fixDstOffset(self): ndx = self.get_dst_num() e = self.args[ndx] if self.offset is None: raise ValueError('symbol not resolved %s' % self.l) if not isinstance(e, ExprInt): return off = e.arg - self.offset if int(off % 4): raise ValueError('strange offset! %r' % off) self.args[ndx] = ExprInt(off, 32) def get_args_expr(self): args = [a for a in self.args] return args
Ancestors (in MRO)
- instruction_mips32
- 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 expr.is_id() or expr.is_int(): return str(expr) elif expr.is_loc(): if loc_db is not None: return loc_db.pretty_str(expr.loc_key) else: return str(expr) assert(isinstance(expr, ExprMem)) arg = expr.arg if isinstance(arg, ExprId): return "(%s)"%arg assert(len(arg.args) == 2 and arg.op == '+') return "%s(%s)"%(arg.args[1], arg.args[0])
Methods
def __init__(
self, *args, **kargs)
def __init__(self, *args, **kargs): super(instruction_mips32, self).__init__(*args, **kargs)
def breakflow(
self)
def breakflow(self): if self.name == 'BREAK': return False if self.name in br_0 + br_1 + br_2: return True return False
def dstflow(
self)
def dstflow(self): if self.name == 'BREAK': return False if self.name in br_0 + br_1 + br_2: return True return False
def dstflow2label(
self, loc_db)
def dstflow2label(self, loc_db): if self.name in ["J", 'JAL']: expr = self.args[0].arg addr = (self.offset & (0xFFFFFFFF ^ ((1<< 28)-1))) + expr loc_key = loc_db.get_or_create_offset_location(addr) self.args[0] = ExprLoc(loc_key, expr.size) return ndx = self.get_dst_num() expr = self.args[ndx] if not isinstance(expr, ExprInt): return addr = expr.arg + self.offset loc_key = loc_db.get_or_create_offset_location(addr) self.args[ndx] = ExprLoc(loc_key, expr.size)
def fixDstOffset(
self)
def fixDstOffset(self): ndx = self.get_dst_num() e = self.args[ndx] if self.offset is None: raise ValueError('symbol not resolved %s' % self.l) if not isinstance(e, ExprInt): return off = e.arg - self.offset if int(off % 4): raise ValueError('strange offset! %r' % off) self.args[ndx] = ExprInt(off, 32)
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 = [a for a in self.args] 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_dst_num(
self)
def get_dst_num(self): if self.name in br_0: i = 0 elif self.name in br_1: i = 1 elif self.name in br_2: i = 2 else: raise NotImplementedError("TODO %s"%self) return i
def get_info(
self, c)
def get_info(self, c): return
def get_symbol_size(
self, symbol, loc_db)
def get_symbol_size(self, symbol, loc_db): return 32
def getdstflow(
self, loc_db)
def getdstflow(self, loc_db): if self.name in br_0: return [self.args[0]] elif self.name in br_1: return [self.args[1]] elif self.name in br_2: return [self.args[2]] elif self.name in ['JAL', 'JALR', 'JR', 'J']: return [self.args[0]] else: raise NotImplementedError("fix mnemo %s"%self.name)
def is_subcall(
self)
def is_subcall(self): if self.name in ['JAL', 'JALR', 'BAL']: return True return False
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 splitflow(
self)
def splitflow(self): if self.name in ["B", 'JR', 'J']: return False if self.name in br_0: return True if self.name in br_1: return True if self.name in br_2: return True if self.name in ['JAL', 'JALR']: return True return False
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 mips32_arg
class mips32_arg(cpu.m_arg): def asm_ast_to_expr(self, arg, loc_db): if isinstance(arg, AstId): if isinstance(arg.name, ExprId): return arg.name if arg.name in gpregs.str: return None loc_key = loc_db.get_or_create_name_location(arg.name) return ExprLoc(loc_key, 32) if isinstance(arg, AstOp): args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args] if None in args: return None return ExprOp(arg.op, *args) if isinstance(arg, AstInt): return ExprInt(arg.value, 32) if isinstance(arg, AstMem): ptr = self.asm_ast_to_expr(arg.ptr, loc_db) if ptr is None: return None return ExprMem(ptr, arg.size) return None
Ancestors (in MRO)
- mips32_arg
- miasm2.core.cpu.m_arg
- __builtin__.object
Methods
def asm_ast_to_expr(
self, arg, loc_db)
def asm_ast_to_expr(self, arg, loc_db): if isinstance(arg, AstId): if isinstance(arg.name, ExprId): return arg.name if arg.name in gpregs.str: return None loc_key = loc_db.get_or_create_name_location(arg.name) return ExprLoc(loc_key, 32) if isinstance(arg, AstOp): args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args] if None in args: return None return ExprOp(arg.op, *args) if isinstance(arg, AstInt): return ExprInt(arg.value, 32) if isinstance(arg, AstMem): ptr = self.asm_ast_to_expr(arg.ptr, loc_db) if ptr is None: return None return ExprMem(ptr, arg.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 mips32_cpr
class mips32_cpr(mips32_arg): parser = regs.regs_cpr0_info.parser def decode(self, v): index = int(self.parent.cpr0.expr) << 3 index += v self.expr = regs.regs_cpr0_expr[index] return True def encode(self): e = self.expr if not e in regs.regs_cpr0_expr: return False index = regs.regs_cpr0_expr.index(e) self.value = index & 7 index >>=2 self.parent.cpr0.value = index return True
Ancestors (in MRO)
- mips32_cpr
- mips32_arg
- miasm2.core.cpu.m_arg
- __builtin__.object
Class variables
var parser
Methods
def asm_ast_to_expr(
self, arg, loc_db)
Inheritance:
mips32_arg
.asm_ast_to_expr
def asm_ast_to_expr(self, arg, loc_db): if isinstance(arg, AstId): if isinstance(arg.name, ExprId): return arg.name if arg.name in gpregs.str: return None loc_key = loc_db.get_or_create_name_location(arg.name) return ExprLoc(loc_key, 32) if isinstance(arg, AstOp): args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args] if None in args: return None return ExprOp(arg.op, *args) if isinstance(arg, AstInt): return ExprInt(arg.value, 32) if isinstance(arg, AstMem): ptr = self.asm_ast_to_expr(arg.ptr, loc_db) if ptr is None: return None return ExprMem(ptr, arg.size) return None
def decode(
self, v)
def decode(self, v): index = int(self.parent.cpr0.expr) << 3 index += v self.expr = regs.regs_cpr0_expr[index] return True
def encode(
self)
def encode(self): e = self.expr if not e in regs.regs_cpr0_expr: return False index = regs.regs_cpr0_expr.index(e) self.value = index & 7 index >>=2 self.parent.cpr0.value = index return True
def fromstring(
self, text, loc_db, parser_result=None)
Inheritance:
mips32_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.asm_ast_to_expr(arg, loc_db) self.expr = expr return start, stop
class mips32_dreg_imm
class mips32_dreg_imm(mips32_arg): parser = deref def decode(self, v): imm = self.parent.imm.expr r = gpregs.expr[v] self.expr = ExprMem(r+imm, 32) return True def encode(self): e = self.expr if not isinstance(e, ExprMem): return False arg = e.arg if isinstance(arg, ExprId): self.parent.imm.expr = ExprInt(0, 32) r = arg elif len(arg.args) == 2 and arg.op == "+": self.parent.imm.expr = arg.args[1] r = arg.args[0] else: return False self.value = gpregs.expr.index(r) return True @staticmethod def arg2str(expr, index=None): assert(isinstance(expr, ExprMem)) arg = expr.arg if isinstance(arg, ExprId): return "(%s)"%arg assert(len(arg.args) == 2 and arg.op == '+') return "%s(%s)"%(arg.args[1], arg.args[0])
Ancestors (in MRO)
- mips32_dreg_imm
- mips32_arg
- miasm2.core.cpu.m_arg
- __builtin__.object
Class variables
var parser
Static methods
def arg2str(
expr, index=None)
@staticmethod def arg2str(expr, index=None): assert(isinstance(expr, ExprMem)) arg = expr.arg if isinstance(arg, ExprId): return "(%s)"%arg assert(len(arg.args) == 2 and arg.op == '+') return "%s(%s)"%(arg.args[1], arg.args[0])
Methods
def asm_ast_to_expr(
self, arg, loc_db)
Inheritance:
mips32_arg
.asm_ast_to_expr
def asm_ast_to_expr(self, arg, loc_db): if isinstance(arg, AstId): if isinstance(arg.name, ExprId): return arg.name if arg.name in gpregs.str: return None loc_key = loc_db.get_or_create_name_location(arg.name) return ExprLoc(loc_key, 32) if isinstance(arg, AstOp): args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args] if None in args: return None return ExprOp(arg.op, *args) if isinstance(arg, AstInt): return ExprInt(arg.value, 32) if isinstance(arg, AstMem): ptr = self.asm_ast_to_expr(arg.ptr, loc_db) if ptr is None: return None return ExprMem(ptr, arg.size) return None
def decode(
self, v)
def decode(self, v): imm = self.parent.imm.expr r = gpregs.expr[v] self.expr = ExprMem(r+imm, 32) return True
def encode(
self)
def encode(self): e = self.expr if not isinstance(e, ExprMem): return False arg = e.arg if isinstance(arg, ExprId): self.parent.imm.expr = ExprInt(0, 32) r = arg elif len(arg.args) == 2 and arg.op == "+": self.parent.imm.expr = arg.args[1] r = arg.args[0] else: return False self.value = gpregs.expr.index(r) return True
def fromstring(
self, text, loc_db, parser_result=None)
Inheritance:
mips32_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.asm_ast_to_expr(arg, loc_db) self.expr = expr return start, stop
class mips32_eposh
class mips32_eposh(mips32_imm, mips32_arg): def decode(self, v): self.expr = ExprInt(v-int(self.parent.epos.expr)+1, 32) return True def encode(self): if not isinstance(self.expr, ExprInt): return False v = int(self.expr.arg) + int(self.parent.epos.expr) -1 self.value = v return True
Ancestors (in MRO)
- mips32_eposh
- mips32_imm
- miasm2.core.cpu.imm_noarg
- mips32_arg
- miasm2.core.cpu.m_arg
- __builtin__.object
Class variables
Methods
def asm_ast_to_expr(
self, arg, loc_db)
Inheritance:
mips32_arg
.asm_ast_to_expr
def asm_ast_to_expr(self, arg, loc_db): if isinstance(arg, AstId): if isinstance(arg.name, ExprId): return arg.name if arg.name in gpregs.str: return None loc_key = loc_db.get_or_create_name_location(arg.name) return ExprLoc(loc_key, 32) if isinstance(arg, AstOp): args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args] if None in args: return None return ExprOp(arg.op, *args) if isinstance(arg, AstInt): return ExprInt(arg.value, 32) if isinstance(arg, AstMem): ptr = self.asm_ast_to_expr(arg.ptr, loc_db) if ptr is None: return None return ExprMem(ptr, arg.size) return None
def decode(
self, v)
Inheritance:
mips32_imm
.decode
def decode(self, v): self.expr = ExprInt(v-int(self.parent.epos.expr)+1, 32) return True
def encode(
self)
Inheritance:
mips32_imm
.encode
def encode(self): if not isinstance(self.expr, ExprInt): return False v = int(self.expr.arg) + int(self.parent.epos.expr) -1 self.value = v return True
def encodeval(
self, v)
Inheritance:
mips32_imm
.encodeval
def encodeval(self, v): if v > self.lmask: return False return v
def expr2int(
self, e)
Inheritance:
mips32_imm
.expr2int
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:
mips32_imm
.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)
Inheritance:
mips32_imm
.int2expr
def int2expr(self, v): if (v & ~self.intmask) != 0: return None return m2_expr.ExprInt(v, self.intsize)
class mips32_esize
class mips32_esize(mips32_imm, mips32_arg): def decode(self, v): v = v & self.lmask self.expr = ExprInt(v+1, 32) return True def encode(self): if not isinstance(self.expr, ExprInt): return False v = self.expr.arg.arg -1 assert(v < (1<<16)) self.value = v return True
Ancestors (in MRO)
- mips32_esize
- mips32_imm
- miasm2.core.cpu.imm_noarg
- mips32_arg
- miasm2.core.cpu.m_arg
- __builtin__.object
Class variables
Methods
def asm_ast_to_expr(
self, arg, loc_db)
Inheritance:
mips32_arg
.asm_ast_to_expr
def asm_ast_to_expr(self, arg, loc_db): if isinstance(arg, AstId): if isinstance(arg.name, ExprId): return arg.name if arg.name in gpregs.str: return None loc_key = loc_db.get_or_create_name_location(arg.name) return ExprLoc(loc_key, 32) if isinstance(arg, AstOp): args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args] if None in args: return None return ExprOp(arg.op, *args) if isinstance(arg, AstInt): return ExprInt(arg.value, 32) if isinstance(arg, AstMem): ptr = self.asm_ast_to_expr(arg.ptr, loc_db) if ptr is None: return None return ExprMem(ptr, arg.size) return None
def decode(
self, v)
Inheritance:
mips32_imm
.decode
def decode(self, v): v = v & self.lmask self.expr = ExprInt(v+1, 32) return True
def encode(
self)
Inheritance:
mips32_imm
.encode
def encode(self): if not isinstance(self.expr, ExprInt): return False v = self.expr.arg.arg -1 assert(v < (1<<16)) self.value = v return True
def encodeval(
self, v)
Inheritance:
mips32_imm
.encodeval
def encodeval(self, v): if v > self.lmask: return False return v
def expr2int(
self, e)
Inheritance:
mips32_imm
.expr2int
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:
mips32_imm
.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)
Inheritance:
mips32_imm
.int2expr
def int2expr(self, v): if (v & ~self.intmask) != 0: return None return m2_expr.ExprInt(v, self.intsize)
class mips32_fccreg
class mips32_fccreg(mips32_reg): reg_info = regs.fccregs parser = reg_info.parser
Ancestors (in MRO)
- mips32_fccreg
- mips32_reg
- miasm2.core.cpu.reg_noarg
- mips32_arg
- miasm2.core.cpu.m_arg
- __builtin__.object
Class variables
Methods
def asm_ast_to_expr(
self, arg, loc_db)
Inheritance:
mips32_reg
.asm_ast_to_expr
def asm_ast_to_expr(self, arg, loc_db): if isinstance(arg, AstId): if isinstance(arg.name, ExprId): return arg.name if arg.name in gpregs.str: return None loc_key = loc_db.get_or_create_name_location(arg.name) return ExprLoc(loc_key, 32) if isinstance(arg, AstOp): args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args] if None in args: return None return ExprOp(arg.op, *args) if isinstance(arg, AstInt): return ExprInt(arg.value, 32) if isinstance(arg, AstMem): ptr = self.asm_ast_to_expr(arg.ptr, loc_db) if ptr is None: return None return ExprMem(ptr, arg.size) return None
def check_fbits(
self, v)
Inheritance:
mips32_reg
.check_fbits
def check_fbits(self, v): return v & self.fmask == self.fbits
def decode(
self, v)
Inheritance:
mips32_reg
.decode
def decode(self, v): v = v & self.lmask if v >= len(self.reg_info.expr): return False self.expr = self.reg_info.expr[v] return True
def encode(
self)
Inheritance:
mips32_reg
.encode
def encode(self): if not self.expr in self.reg_info.expr: log.debug("cannot encode reg %r", self.expr) return False self.value = self.reg_info.expr.index(self.expr) if self.value > self.lmask: log.debug("cannot encode field value %x %x", self.value, self.lmask) return False return True
def fromstring(
self, text, loc_db, parser_result=None)
Inheritance:
mips32_reg
.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 mips32_fltpreg
class mips32_fltpreg(mips32_reg): reg_info = regs.fltregs parser = reg_info.parser
Ancestors (in MRO)
- mips32_fltpreg
- mips32_reg
- miasm2.core.cpu.reg_noarg
- mips32_arg
- miasm2.core.cpu.m_arg
- __builtin__.object
Class variables
Methods
def asm_ast_to_expr(
self, arg, loc_db)
Inheritance:
mips32_reg
.asm_ast_to_expr
def asm_ast_to_expr(self, arg, loc_db): if isinstance(arg, AstId): if isinstance(arg.name, ExprId): return arg.name if arg.name in gpregs.str: return None loc_key = loc_db.get_or_create_name_location(arg.name) return ExprLoc(loc_key, 32) if isinstance(arg, AstOp): args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args] if None in args: return None return ExprOp(arg.op, *args) if isinstance(arg, AstInt): return ExprInt(arg.value, 32) if isinstance(arg, AstMem): ptr = self.asm_ast_to_expr(arg.ptr, loc_db) if ptr is None: return None return ExprMem(ptr, arg.size) return None
def check_fbits(
self, v)
Inheritance:
mips32_reg
.check_fbits
def check_fbits(self, v): return v & self.fmask == self.fbits
def decode(
self, v)
Inheritance:
mips32_reg
.decode
def decode(self, v): v = v & self.lmask if v >= len(self.reg_info.expr): return False self.expr = self.reg_info.expr[v] return True
def encode(
self)
Inheritance:
mips32_reg
.encode
def encode(self): if not self.expr in self.reg_info.expr: log.debug("cannot encode reg %r", self.expr) return False self.value = self.reg_info.expr.index(self.expr) if self.value > self.lmask: log.debug("cannot encode field value %x %x", self.value, self.lmask) return False return True
def fromstring(
self, text, loc_db, parser_result=None)
Inheritance:
mips32_reg
.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 mips32_gpreg
class mips32_gpreg(mips32_reg): reg_info = gpregs parser = reg_info.parser
Ancestors (in MRO)
- mips32_gpreg
- mips32_reg
- miasm2.core.cpu.reg_noarg
- mips32_arg
- miasm2.core.cpu.m_arg
- __builtin__.object
Class variables
Methods
def asm_ast_to_expr(
self, arg, loc_db)
Inheritance:
mips32_reg
.asm_ast_to_expr
def asm_ast_to_expr(self, arg, loc_db): if isinstance(arg, AstId): if isinstance(arg.name, ExprId): return arg.name if arg.name in gpregs.str: return None loc_key = loc_db.get_or_create_name_location(arg.name) return ExprLoc(loc_key, 32) if isinstance(arg, AstOp): args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args] if None in args: return None return ExprOp(arg.op, *args) if isinstance(arg, AstInt): return ExprInt(arg.value, 32) if isinstance(arg, AstMem): ptr = self.asm_ast_to_expr(arg.ptr, loc_db) if ptr is None: return None return ExprMem(ptr, arg.size) return None
def check_fbits(
self, v)
Inheritance:
mips32_reg
.check_fbits
def check_fbits(self, v): return v & self.fmask == self.fbits
def decode(
self, v)
Inheritance:
mips32_reg
.decode
def decode(self, v): v = v & self.lmask if v >= len(self.reg_info.expr): return False self.expr = self.reg_info.expr[v] return True
def encode(
self)
Inheritance:
mips32_reg
.encode
def encode(self): if not self.expr in self.reg_info.expr: log.debug("cannot encode reg %r", self.expr) return False self.value = self.reg_info.expr.index(self.expr) if self.value > self.lmask: log.debug("cannot encode field value %x %x", self.value, self.lmask) return False return True
def fromstring(
self, text, loc_db, parser_result=None)
Inheritance:
mips32_reg
.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 mips32_imm
class mips32_imm(cpu.imm_noarg): parser = base_expr
Ancestors (in MRO)
- mips32_imm
- miasm2.core.cpu.imm_noarg
- __builtin__.object
Class variables
var intmask
var intsize
var parser
Methods
def decode(
self, v)
def decode(self, v): v = v & self.lmask v = self.decodeval(v) e = self.int2expr(v) if not e: return False self.expr = e return True
def decodeval(
self, v)
def decodeval(self, v): return v
def encode(
self)
def encode(self): v = self.expr2int(self.expr) if v is None: return False v = self.encodeval(v) if v is False: return False if v > self.lmask: return False self.value = v return True
def encodeval(
self, v)
def encodeval(self, v): if v > self.lmask: return False return v
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)
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 m2_expr.ExprInt(v, self.intsize)
class mips32_instr_index
class mips32_instr_index(mips32_imm, mips32_arg): def decode(self, v): v = v & self.lmask self.expr = ExprInt(v<<2, 32) return True def encode(self): if not isinstance(self.expr, ExprInt): return False v = self.expr.arg.arg if v & 3: return False v>>=2 if v > (1<<self.l): return False self.value = v return True
Ancestors (in MRO)
- mips32_instr_index
- mips32_imm
- miasm2.core.cpu.imm_noarg
- mips32_arg
- miasm2.core.cpu.m_arg
- __builtin__.object
Class variables
Methods
def asm_ast_to_expr(
self, arg, loc_db)
Inheritance:
mips32_arg
.asm_ast_to_expr
def asm_ast_to_expr(self, arg, loc_db): if isinstance(arg, AstId): if isinstance(arg.name, ExprId): return arg.name if arg.name in gpregs.str: return None loc_key = loc_db.get_or_create_name_location(arg.name) return ExprLoc(loc_key, 32) if isinstance(arg, AstOp): args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args] if None in args: return None return ExprOp(arg.op, *args) if isinstance(arg, AstInt): return ExprInt(arg.value, 32) if isinstance(arg, AstMem): ptr = self.asm_ast_to_expr(arg.ptr, loc_db) if ptr is None: return None return ExprMem(ptr, arg.size) return None
def decode(
self, v)
Inheritance:
mips32_imm
.decode
def decode(self, v): v = v & self.lmask self.expr = ExprInt(v<<2, 32) return True
def encode(
self)
Inheritance:
mips32_imm
.encode
def encode(self): if not isinstance(self.expr, ExprInt): return False v = self.expr.arg.arg if v & 3: return False v>>=2 if v > (1<<self.l): return False self.value = v return True
def encodeval(
self, v)
Inheritance:
mips32_imm
.encodeval
def encodeval(self, v): if v > self.lmask: return False return v
def expr2int(
self, e)
Inheritance:
mips32_imm
.expr2int
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:
mips32_imm
.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)
Inheritance:
mips32_imm
.int2expr
def int2expr(self, v): if (v & ~self.intmask) != 0: return None return m2_expr.ExprInt(v, self.intsize)
class mips32_reg
class mips32_reg(cpu.reg_noarg, mips32_arg): pass
Ancestors (in MRO)
- mips32_reg
- miasm2.core.cpu.reg_noarg
- mips32_arg
- miasm2.core.cpu.m_arg
- __builtin__.object
Class variables
var parser
var reg_info
Methods
def asm_ast_to_expr(
self, arg, loc_db)
Inheritance:
mips32_arg
.asm_ast_to_expr
def asm_ast_to_expr(self, arg, loc_db): if isinstance(arg, AstId): if isinstance(arg.name, ExprId): return arg.name if arg.name in gpregs.str: return None loc_key = loc_db.get_or_create_name_location(arg.name) return ExprLoc(loc_key, 32) if isinstance(arg, AstOp): args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args] if None in args: return None return ExprOp(arg.op, *args) if isinstance(arg, AstInt): return ExprInt(arg.value, 32) if isinstance(arg, AstMem): ptr = self.asm_ast_to_expr(arg.ptr, loc_db) if ptr is None: return None return ExprMem(ptr, arg.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): v = v & self.lmask if v >= len(self.reg_info.expr): return False self.expr = self.reg_info.expr[v] return True
def encode(
self)
def encode(self): if not self.expr in self.reg_info.expr: log.debug("cannot encode reg %r", self.expr) return False self.value = self.reg_info.expr.index(self.expr) if self.value > self.lmask: log.debug("cannot encode field value %x %x", self.value, self.lmask) return False return True
def fromstring(
self, text, loc_db, parser_result=None)
Inheritance:
mips32_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 mips32_s16imm
class mips32_s16imm(mips32_s16imm_noarg, mips32_arg): pass
Ancestors (in MRO)
- mips32_s16imm
- mips32_s16imm_noarg
- mips32_imm
- miasm2.core.cpu.imm_noarg
- mips32_arg
- miasm2.core.cpu.m_arg
- __builtin__.object
Class variables
Methods
def asm_ast_to_expr(
self, arg, loc_db)
Inheritance:
mips32_arg
.asm_ast_to_expr
def asm_ast_to_expr(self, arg, loc_db): if isinstance(arg, AstId): if isinstance(arg.name, ExprId): return arg.name if arg.name in gpregs.str: return None loc_key = loc_db.get_or_create_name_location(arg.name) return ExprLoc(loc_key, 32) if isinstance(arg, AstOp): args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args] if None in args: return None return ExprOp(arg.op, *args) if isinstance(arg, AstInt): return ExprInt(arg.value, 32) if isinstance(arg, AstMem): ptr = self.asm_ast_to_expr(arg.ptr, loc_db) if ptr is None: return None return ExprMem(ptr, arg.size) return None
def decode(
self, v)
Inheritance:
mips32_s16imm_noarg
.decode
def decode(self, v): v = v & self.lmask v = cpu.sign_ext(v, 16, 32) self.expr = ExprInt(v, 32) return True
def encode(
self)
Inheritance:
mips32_s16imm_noarg
.encode
def encode(self): if not isinstance(self.expr, ExprInt): return False v = self.expr.arg.arg if v & 0x80000000: nv = v & ((1 << 16) - 1) assert( v == cpu.sign_ext(nv, 16, 32)) v = nv self.value = v return True
def encodeval(
self, v)
Inheritance:
mips32_s16imm_noarg
.encodeval
def encodeval(self, v): if v > self.lmask: return False return v
def expr2int(
self, e)
Inheritance:
mips32_s16imm_noarg
.expr2int
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:
mips32_s16imm_noarg
.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)
Inheritance:
mips32_s16imm_noarg
.int2expr
def int2expr(self, v): if (v & ~self.intmask) != 0: return None return m2_expr.ExprInt(v, self.intsize)
class mips32_s16imm_noarg
class mips32_s16imm_noarg(mips32_imm): def decode(self, v): v = v & self.lmask v = cpu.sign_ext(v, 16, 32) self.expr = ExprInt(v, 32) return True def encode(self): if not isinstance(self.expr, ExprInt): return False v = self.expr.arg.arg if v & 0x80000000: nv = v & ((1 << 16) - 1) assert( v == cpu.sign_ext(nv, 16, 32)) v = nv self.value = v return True
Ancestors (in MRO)
- mips32_s16imm_noarg
- mips32_imm
- miasm2.core.cpu.imm_noarg
- __builtin__.object
Class variables
Methods
def decode(
self, v)
Inheritance:
mips32_imm
.decode
def decode(self, v): v = v & self.lmask v = cpu.sign_ext(v, 16, 32) self.expr = ExprInt(v, 32) return True
def encode(
self)
Inheritance:
mips32_imm
.encode
def encode(self): if not isinstance(self.expr, ExprInt): return False v = self.expr.arg.arg if v & 0x80000000: nv = v & ((1 << 16) - 1) assert( v == cpu.sign_ext(nv, 16, 32)) v = nv self.value = v return True
def encodeval(
self, v)
Inheritance:
mips32_imm
.encodeval
def encodeval(self, v): if v > self.lmask: return False return v
def expr2int(
self, e)
Inheritance:
mips32_imm
.expr2int
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:
mips32_imm
.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)
Inheritance:
mips32_imm
.int2expr
def int2expr(self, v): if (v & ~self.intmask) != 0: return None return m2_expr.ExprInt(v, self.intsize)
class mips32_soff
class mips32_soff(mips32_soff_noarg, mips32_arg): pass
Ancestors (in MRO)
- mips32_soff
- mips32_soff_noarg
- mips32_imm
- miasm2.core.cpu.imm_noarg
- mips32_arg
- miasm2.core.cpu.m_arg
- __builtin__.object
Class variables
Methods
def asm_ast_to_expr(
self, arg, loc_db)
Inheritance:
mips32_arg
.asm_ast_to_expr
def asm_ast_to_expr(self, arg, loc_db): if isinstance(arg, AstId): if isinstance(arg.name, ExprId): return arg.name if arg.name in gpregs.str: return None loc_key = loc_db.get_or_create_name_location(arg.name) return ExprLoc(loc_key, 32) if isinstance(arg, AstOp): args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args] if None in args: return None return ExprOp(arg.op, *args) if isinstance(arg, AstInt): return ExprInt(arg.value, 32) if isinstance(arg, AstMem): ptr = self.asm_ast_to_expr(arg.ptr, loc_db) if ptr is None: return None return ExprMem(ptr, arg.size) return None
def decode(
self, v)
Inheritance:
mips32_soff_noarg
.decode
def decode(self, v): v = v & self.lmask v <<= 2 v = cpu.sign_ext(v, 16+2, 32) # Add pipeline offset self.expr = ExprInt(v + 4, 32) return True
def encode(
self)
Inheritance:
mips32_soff_noarg
.encode
def encode(self): if not isinstance(self.expr, ExprInt): return False # Remove pipeline offset v = int(self.expr.arg - 4) if v & 0x80000000: nv = v & ((1 << 16+2) - 1) assert( v == cpu.sign_ext(nv, 16+2, 32)) v = nv self.value = v>>2 return True
def encodeval(
self, v)
Inheritance:
mips32_soff_noarg
.encodeval
def encodeval(self, v): if v > self.lmask: return False return v
def expr2int(
self, e)
Inheritance:
mips32_soff_noarg
.expr2int
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:
mips32_soff_noarg
.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)
Inheritance:
mips32_soff_noarg
.int2expr
def int2expr(self, v): if (v & ~self.intmask) != 0: return None return m2_expr.ExprInt(v, self.intsize)
class mips32_soff_noarg
class mips32_soff_noarg(mips32_imm): def decode(self, v): v = v & self.lmask v <<= 2 v = cpu.sign_ext(v, 16+2, 32) # Add pipeline offset self.expr = ExprInt(v + 4, 32) return True def encode(self): if not isinstance(self.expr, ExprInt): return False # Remove pipeline offset v = int(self.expr.arg - 4) if v & 0x80000000: nv = v & ((1 << 16+2) - 1) assert( v == cpu.sign_ext(nv, 16+2, 32)) v = nv self.value = v>>2 return True
Ancestors (in MRO)
- mips32_soff_noarg
- mips32_imm
- miasm2.core.cpu.imm_noarg
- __builtin__.object
Class variables
Methods
def decode(
self, v)
Inheritance:
mips32_imm
.decode
def decode(self, v): v = v & self.lmask v <<= 2 v = cpu.sign_ext(v, 16+2, 32) # Add pipeline offset self.expr = ExprInt(v + 4, 32) return True
def encode(
self)
Inheritance:
mips32_imm
.encode
def encode(self): if not isinstance(self.expr, ExprInt): return False # Remove pipeline offset v = int(self.expr.arg - 4) if v & 0x80000000: nv = v & ((1 << 16+2) - 1) assert( v == cpu.sign_ext(nv, 16+2, 32)) v = nv self.value = v>>2 return True
def encodeval(
self, v)
Inheritance:
mips32_imm
.encodeval
def encodeval(self, v): if v > self.lmask: return False return v
def expr2int(
self, e)
Inheritance:
mips32_imm
.expr2int
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:
mips32_imm
.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)
Inheritance:
mips32_imm
.int2expr
def int2expr(self, v): if (v & ~self.intmask) != 0: return None return m2_expr.ExprInt(v, self.intsize)
class mips32_u16imm
class mips32_u16imm(mips32_imm, mips32_arg): def decode(self, v): v = v & self.lmask self.expr = ExprInt(v, 32) return True def encode(self): if not isinstance(self.expr, ExprInt): return False v = self.expr.arg.arg assert(v < (1<<16)) self.value = v return True
Ancestors (in MRO)
- mips32_u16imm
- mips32_imm
- miasm2.core.cpu.imm_noarg
- mips32_arg
- miasm2.core.cpu.m_arg
- __builtin__.object
Class variables
Methods
def asm_ast_to_expr(
self, arg, loc_db)
Inheritance:
mips32_arg
.asm_ast_to_expr
def asm_ast_to_expr(self, arg, loc_db): if isinstance(arg, AstId): if isinstance(arg.name, ExprId): return arg.name if arg.name in gpregs.str: return None loc_key = loc_db.get_or_create_name_location(arg.name) return ExprLoc(loc_key, 32) if isinstance(arg, AstOp): args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args] if None in args: return None return ExprOp(arg.op, *args) if isinstance(arg, AstInt): return ExprInt(arg.value, 32) if isinstance(arg, AstMem): ptr = self.asm_ast_to_expr(arg.ptr, loc_db) if ptr is None: return None return ExprMem(ptr, arg.size) return None
def decode(
self, v)
Inheritance:
mips32_imm
.decode
def decode(self, v): v = v & self.lmask self.expr = ExprInt(v, 32) return True
def encode(
self)
Inheritance:
mips32_imm
.encode
def encode(self): if not isinstance(self.expr, ExprInt): return False v = self.expr.arg.arg assert(v < (1<<16)) self.value = v return True
def encodeval(
self, v)
Inheritance:
mips32_imm
.encodeval
def encodeval(self, v): if v > self.lmask: return False return v
def expr2int(
self, e)
Inheritance:
mips32_imm
.expr2int
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:
mips32_imm
.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)
Inheritance:
mips32_imm
.int2expr
def int2expr(self, v): if (v & ~self.intmask) != 0: return None return m2_expr.ExprInt(v, self.intsize)
class mn_mips32
class mn_mips32(cpu.cls_mn): delayslot = 1 name = "mips32" regs = regs bintree = {} num = 0 all_mn = [] all_mn_mode = defaultdict(list) all_mn_name = defaultdict(list) all_mn_inst = defaultdict(list) pc = {'l':regs.PC, 'b':regs.PC} sp = {'l':regs.SP, 'b':regs.SP} instruction = instruction_mips32 max_instruction_len = 4 @classmethod def getpc(cls, attrib = None): return regs.PC @classmethod def getsp(cls, attrib = None): return regs.SP def additional_info(self): info = additional_info() return info @classmethod def getbits(cls, bitstream, attrib, start, n): if not n: return 0 o = 0 while n: offset = start / 8 n_offset = cls.endian_offset(attrib, offset) c = cls.getbytes(bitstream, n_offset, 1) 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 endian_offset(cls, attrib, offset): if attrib == "l": return (offset & ~3) + 3 - offset % 4 elif attrib == "b": return offset else: raise NotImplementedError('bad attrib') @classmethod def check_mnemo(cls, fields): l = sum([x.l for x in fields]) assert l == 32, "len %r" % l @classmethod def getmn(cls, name): return name.upper() @classmethod def gen_modes(cls, subcls, name, bases, dct, fields): dct['mode'] = None return [(subcls, name, bases, dct, fields)] def value(self, mode): v = super(mn_mips32, self).value(mode) if mode == 'l': return [x[::-1] for x in v] elif mode == 'b': return [x for x in v] else: raise NotImplementedError('bad attrib')
Ancestors (in MRO)
- mn_mips32
- 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 == 32, "len %r" % l
def decoded2bytes(
self, result)
def decoded2bytes(self, result): if not result: return [] out = [] for decoded in result: decoded.sort() o = self.encodefields(decoded) if o is None: continue out.append(o) out = list(set(out)) 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 endian_offset(
cls, attrib, offset)
@classmethod def endian_offset(cls, attrib, offset): if attrib == "l": return (offset & ~3) + 3 - offset % 4 elif attrib == "b": return offset else: raise NotImplementedError('bad attrib')
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, bitstream, attrib, start, n)
@classmethod def getbits(cls, bitstream, attrib, start, n): if not n: return 0 o = 0 while n: offset = start / 8 n_offset = cls.endian_offset(attrib, offset) c = cls.getbytes(bitstream, n_offset, 1) 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)
@classmethod def getbytes(cls, bs, offset, l): return bs.getbytes(offset, l)
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 getpc(
cls, attrib=None)
@classmethod def getpc(cls, attrib = None): return regs.PC
def getsp(
cls, attrib=None)
@classmethod def getsp(cls, attrib = None): return regs.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): for f in self.fields_order: if f.strbits and isbin(f.strbits): f.value = int(f.strbits, 2) elif 'default_val' in f.kargs: f.value = int(f.kargs['default_val'], 2) else: f.value = None if f.fname: setattr(self, f.fname, f)
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): v = super(mn_mips32, self).value(mode) if mode == 'l': return [x[::-1] for x in v] elif mode == 'b': return [x for x in v] else: raise NotImplementedError('bad attrib')