Top

miasm2.arch.msp430.sem module

#-*- coding:utf-8 -*-

from miasm2.expression.expression import *
from miasm2.arch.msp430.regs import *
from miasm2.arch.msp430.arch import mn_msp430
from miasm2.ir.ir import IntermediateRepresentation


# Utils
def hex2bcd(val):
    "Return val as BCD"
    try:
        return int("%x" % val, 10)
    except ValueError:
        raise NotImplementedError("Not defined behaviour")


def bcd2hex(val):
    "Return the hex value of a BCD"
    try:
        return int("0x%d" % val, 16)
    except ValueError:
        raise NotImplementedError("Not defined behaviour")


def reset_sr_res():
    return [ExprAff(res, ExprInt(0, 7))]


def update_flag_zf(a):
    return [ExprAff(zf, ExprCond(a, ExprInt(0, zf.size), ExprInt(1, zf.size)))]


def update_flag_nf(a):
    return [ExprAff(nf, a.msb())]


def update_flag_pf(a):
    return [ExprAff(pf, ExprOp('parity', a & ExprInt(0xFF, a.size)))]


def update_flag_cf_inv_zf(a):
    return [ExprAff(cf, ExprCond(a, ExprInt(1, cf.size), ExprInt(0, cf.size)))]


def update_flag_zn_r(a):
    e = []
    e += update_flag_zf(a)
    e += update_flag_nf(a)
    e += reset_sr_res()
    return e


def update_flag_sub_cf(a, b, c):
    return [ExprAff(cf,
        ((((a ^ b) ^ c) ^ ((a ^ c) & (a ^ b))).msb()) ^ ExprInt(1, 1))]


def update_flag_add_cf(a, b, c):
    return [ExprAff(cf, (((a ^ b) ^ c) ^ ((a ^ c) & (~(a ^ b)))).msb())]


def update_flag_add_of(a, b, c):
    return [ExprAff(of, (((a ^ c) & (~(a ^ b)))).msb())]


def update_flag_sub_of(a, b, c):
    return [ExprAff(of, (((a ^ c) & (a ^ b))).msb())]


def mng_autoinc(a, b, size):
    e = []
    if not (isinstance(a, ExprOp) and a.op == "autoinc"):
        return e, a, b

    a_r = a.args[0]
    e.append(ExprAff(a_r, a_r + ExprInt(size / 8, a_r.size)))
    a = ExprMem(a_r, size)
    if isinstance(b, ExprMem) and a_r in b.arg:
        b = ExprMem(b.arg + ExprInt(size / 8, 16), b.size)
    return e, a, b

# Mnemonics


def mov_b(ir, instr, a, b):
    e, a, b = mng_autoinc(a, b, 8)
    if isinstance(b, ExprMem):
        b = ExprMem(b.arg, 8)
        a = a[:8]
    else:
        a = a[:8].zeroExtend(16)
    e.append(ExprAff(b, a))
    return e, []


def mov_w(ir, instr, a, b):
    e, a, b = mng_autoinc(a, b, 16)
    e.append(ExprAff(b, a))
    if b == ir.pc:
        e.append(ExprAff(ir.IRDst, a))
    return e, []


def and_b(ir, instr, a, b):
    e, a, b = mng_autoinc(a, b, 8)
    c = a[:8] & b[:8]
    e.append(ExprAff(b, c.zeroExtend(16)))
    e += update_flag_zn_r(c)
    e += update_flag_cf_inv_zf(c)
    e += [ExprAff(of, ExprInt(0, 1))]
    return e, []


def and_w(ir, instr, a, b):
    e, a, b = mng_autoinc(a, b, 16)
    c = a & b
    e.append(ExprAff(b, c))
    e += update_flag_zn_r(c)
    e += update_flag_cf_inv_zf(c)
    e += [ExprAff(of, ExprInt(0, 1))]
    return e, []


def bic_b(ir, instr, a, b):
    e, a, b = mng_autoinc(a, b, 8)
    c = (a[:8] ^ ExprInt(0xff, 8)) & b[:8]
    c = c.zeroExtend(b.size)
    e.append(ExprAff(b, c))
    return e, []


def bic_w(ir, instr, a, b):
    e, a, b = mng_autoinc(a, b, 16)
    c = (a ^ ExprInt(0xffff, 16)) & b
    e.append(ExprAff(b, c))
    return e, []


def bis_w(ir, instr, a, b):
    e, a, b = mng_autoinc(a, b, 16)
    c = a | b
    e.append(ExprAff(b, c))
    return e, []


def bit_w(ir, instr, a, b):
    e, a, b = mng_autoinc(a, b, 16)
    c = a & b
    e += update_flag_zn_r(c)
    e += update_flag_cf_inv_zf(c)
    e.append(ExprAff(of, ExprInt(0, 1)))
    return e, []

"""
def sub_b(ir, instr, a, b):
    e, a, b = mng_autoinc(a, b, 8)
    c = b - a
    e.append(ExprAff(b, c))
    e += update_flag_zn_r(c)
    e += update_flag_sub_cf(b, a, c)
    return None, e, []
"""


def sub_w(ir, instr, a, b):
    e, a, b = mng_autoinc(a, b, 16)
    c = b - a
    e.append(ExprAff(b, c))
    e += update_flag_zn_r(c)
    e += update_flag_sub_cf(b, a, c)
    # micrcorruption
    # e += update_flag_sub_of(a, b, c)
    # e += update_flag_sub_of(b, a, c)
    return e, []


def add_b(ir, instr, a, b):
    e, a, b = mng_autoinc(a, b, 8)
    if isinstance(b, ExprMem):
        b = ExprMem(b.arg, 8)
    else:
        b = b[:8]
    a = a[:8]
    c = b + a
    e.append(ExprAff(b, c))
    e += update_flag_zn_r(c)
    e += update_flag_add_cf(a, b, c)
    e += update_flag_add_of(a, b, c)
    return e, []


def add_w(ir, instr, a, b):
    e, a, b = mng_autoinc(a, b, 16)
    c = b + a
    e.append(ExprAff(b, c))
    e += update_flag_zn_r(c)
    e += update_flag_add_cf(a, b, c)
    e += update_flag_add_of(a, b, c)
    return e, []


def dadd_w(ir, instr, a, b):
    e, a, b = mng_autoinc(a, b, 16)
    # TODO: microcorruption no carryflag
    c = ExprOp("bcdadd", b, a)  # +zeroExtend(cf, 16))

    e.append(ExprAff(b, c))
    # e += update_flag_zn_r(c)

    # micrcorruption
    e += update_flag_zf(a)
    # e += update_flag_nf(a)
    e += reset_sr_res()

    e.append(ExprAff(cf, ExprOp("bcdadd_cf", b, a)))  # +zeroExtend(cf, 16))))

    # of : undefined
    return e, []


def xor_w(ir, instr, a, b):
    e, a, b = mng_autoinc(a, b, 16)
    c = b ^ a
    e.append(ExprAff(b, c))
    e += update_flag_zn_r(c)
    e += update_flag_cf_inv_zf(c)
    e.append(ExprAff(of, b.msb() & a.msb()))
    return e, []


def push_w(ir, instr, a):
    e = []
    e.append(ExprAff(ExprMem(SP - ExprInt(2, 16), 16), a))
    e.append(ExprAff(SP, SP - ExprInt(2, 16)))
    return e, []


def call(ir, instr, a):
    e, a, dummy = mng_autoinc(a, None, 16)

    loc_next = ir.get_next_loc_key(instr)
    loc_next_expr = ExprLoc(loc_next, 16)

    e.append(ExprAff(ExprMem(SP - ExprInt(2, 16), 16), loc_next_expr))
    e.append(ExprAff(SP, SP - ExprInt(2, 16)))
    e.append(ExprAff(PC, a))
    e.append(ExprAff(ir.IRDst, a))
    return e, []


def swpb(ir, instr, a):
    e = []
    x, y = a[:8], a[8:16]
    e.append(ExprAff(a, ExprCompose(y, x)))
    return e, []


def cmp_w(ir, instr, a, b):
    e, a, b = mng_autoinc(a, b, 16)
    c = b - a
    e += update_flag_zn_r(c)
    e += update_flag_sub_cf(b, a, c)
    e += update_flag_sub_of(b, a, c)
    return e, []


def cmp_b(ir, instr, a, b):
    e, a, b = mng_autoinc(a, b, 8)
    c = b[:8] - a[:8]
    e += update_flag_zn_r(c)
    e += update_flag_sub_cf(b[:8], a[:8], c)
    e += update_flag_sub_of(b[:8], a[:8], c)
    return e, []


def jz(ir, instr, a):
    loc_next = ir.get_next_loc_key(instr)
    loc_next_expr = ExprLoc(loc_next, 16)
    e = []
    e.append(ExprAff(PC, ExprCond(zf, a, loc_next_expr)))
    e.append(ExprAff(ir.IRDst, ExprCond(zf, a, loc_next_expr)))
    return e, []


def jnz(ir, instr, a):
    loc_next = ir.get_next_loc_key(instr)
    loc_next_expr = ExprLoc(loc_next, 16)
    e = []
    e.append(ExprAff(PC, ExprCond(zf, loc_next_expr, a)))
    e.append(ExprAff(ir.IRDst, ExprCond(zf, loc_next_expr, a)))
    return e, []


def jl(ir, instr, a):
    loc_next = ir.get_next_loc_key(instr)
    loc_next_expr = ExprLoc(loc_next, 16)
    e = []
    e.append(ExprAff(PC, ExprCond(nf ^ of, a, loc_next_expr)))
    e.append(ExprAff(ir.IRDst, ExprCond(nf ^ of, a, loc_next_expr)))
    return e, []


def jc(ir, instr, a):
    loc_next = ir.get_next_loc_key(instr)
    loc_next_expr = ExprLoc(loc_next, 16)
    e = []
    e.append(ExprAff(PC, ExprCond(cf, a, loc_next_expr)))
    e.append(ExprAff(ir.IRDst, ExprCond(cf, a, loc_next_expr)))
    return e, []


def jnc(ir, instr, a):
    loc_next = ir.get_next_loc_key(instr)
    loc_next_expr = ExprLoc(loc_next, 16)
    e = []
    e.append(ExprAff(PC, ExprCond(cf, loc_next_expr, a)))
    e.append(ExprAff(ir.IRDst, ExprCond(cf, loc_next_expr, a)))
    return e, []


def jge(ir, instr, a):
    loc_next = ir.get_next_loc_key(instr)
    loc_next_expr = ExprLoc(loc_next, 16)
    e = []
    e.append(ExprAff(PC, ExprCond(nf ^ of, loc_next_expr, a)))
    e.append(ExprAff(ir.IRDst, ExprCond(nf ^ of, loc_next_expr, a)))
    return e, []


def jmp(ir, instr, a):
    e = []
    e.append(ExprAff(PC, a))
    e.append(ExprAff(ir.IRDst, a))
    return e, []


def rrc_w(ir, instr, a):
    e = []
    c = ExprCompose(a[1:16], cf)
    e.append(ExprAff(a, c))
    e.append(ExprAff(cf, a[:1]))
    # e += update_flag_zn_r(c)

    # micrcorruption
    e += update_flag_zf(a)
    # e += update_flag_nf(a)
    e += reset_sr_res()

    e.append(ExprAff(of, ExprInt(0, 1)))
    return e, []


def rra_w(ir, instr, a):
    e = []
    c = ExprCompose(a[1:16], a[15:16])
    e.append(ExprAff(a, c))
    # TODO: error in disasm microcorruption?
    # e.append(ExprAff(cf, a[:1]))
    # e += update_flag_zn_r(c)

    # micrcorruption
    e += update_flag_zf(a)
    # e += update_flag_nf(a)
    e += reset_sr_res()

    e.append(ExprAff(of, ExprInt(0, 1)))
    return e, []


def sxt(ir, instr, a):
    e = []
    c = a[:8].signExtend(16)
    e.append(ExprAff(a, c))

    e += update_flag_zn_r(c)
    e += update_flag_cf_inv_zf(c)
    e.append(ExprAff(of, ExprInt(0, 1)))

    return e, []

mnemo_func = {
    "mov.b": mov_b,
    "mov.w": mov_w,
    "and.b": and_b,
    "and.w": and_w,
    "bic.b": bic_b,
    "bic.w": bic_w,
    "bis.w": bis_w,
    "bit.w": bit_w,
    "sub.w": sub_w,
    "add.b": add_b,
    "add.w": add_w,
    "push.w": push_w,
    "dadd.w": dadd_w,
    "xor.w": xor_w,
    "call": call,
    "swpb": swpb,
    "cmp.w": cmp_w,
    "cmp.b": cmp_b,
    "jz": jz,
    "jnz": jnz,
    "jl": jl,
    "jc": jc,
    "jnc": jnc,
    "jmp": jmp,
    "jge": jge,
    "rrc.w": rrc_w,
    "rra.w": rra_w,
    "sxt": sxt,
}


composed_sr = ExprCompose(cf, zf, nf, gie, cpuoff, osc, scg0, scg1, of, res)


def ComposeExprAff(dst, src):
    e = []
    for start, arg in dst.iter_args():
        e.append(ExprAff(arg, src[start:start+arg.size]))
    return e


class ir_msp430(IntermediateRepresentation):

    def __init__(self, loc_db=None):
        IntermediateRepresentation.__init__(self, mn_msp430, None, loc_db)
        self.pc = PC
        self.sp = SP
        self.IRDst = ExprId('IRDst', 16)
        self.addrsize = 16

    def mod_pc(self, instr, instr_ir, extra_ir):
        pass

    def get_ir(self, instr):
        args = instr.args
        instr_ir, extra_ir = mnemo_func[instr.name](self, instr, *args)
        self.mod_sr(instr, instr_ir, extra_ir)

        return instr_ir, extra_ir

    def mod_sr(self, instr, instr_ir, extra_ir):
        for i, x in enumerate(instr_ir):
            x = ExprAff(x.dst, x.src.replace_expr({SR: composed_sr}))
            instr_ir[i] = x
            if x.dst != SR:
                continue
            xx = ComposeExprAff(composed_sr, x.src)
            instr_ir[i:i+1] = xx
        for i, x in enumerate(instr_ir):
            x = ExprAff(x.dst, x.src.replace_expr(
                {self.pc: ExprInt(instr.offset + instr.l, 16)}))
            instr_ir[i] = x

        if extra_ir:
            raise NotImplementedError('not fully functional')

Module variables

var EXPRAFF

var EXPRCOMPOSE

var EXPRCOND

var EXPRID

var EXPRINT

var EXPRLOC

var EXPRMEM

var EXPROP

var EXPRSLICE

var EXPR_ORDER_DICT

var PRIORITY_MAX

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 all_regs_ids

var all_regs_ids_byname

var all_regs_ids_init

var all_regs_ids_no_alias

var attrib_to_regs

var composed_sr

var i

var mnemo_func

var mod_size2uint

var priorities

var priorities_list

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

Functions

def ComposeExprAff(

dst, src)

def ComposeExprAff(dst, src):
    e = []
    for start, arg in dst.iter_args():
        e.append(ExprAff(arg, src[start:start+arg.size]))
    return e

def add_b(

ir, instr, a, b)

def add_b(ir, instr, a, b):
    e, a, b = mng_autoinc(a, b, 8)
    if isinstance(b, ExprMem):
        b = ExprMem(b.arg, 8)
    else:
        b = b[:8]
    a = a[:8]
    c = b + a
    e.append(ExprAff(b, c))
    e += update_flag_zn_r(c)
    e += update_flag_add_cf(a, b, c)
    e += update_flag_add_of(a, b, c)
    return e, []

def add_w(

ir, instr, a, b)

def add_w(ir, instr, a, b):
    e, a, b = mng_autoinc(a, b, 16)
    c = b + a
    e.append(ExprAff(b, c))
    e += update_flag_zn_r(c)
    e += update_flag_add_cf(a, b, c)
    e += update_flag_add_of(a, b, c)
    return e, []

def and_b(

ir, instr, a, b)

def and_b(ir, instr, a, b):
    e, a, b = mng_autoinc(a, b, 8)
    c = a[:8] & b[:8]
    e.append(ExprAff(b, c.zeroExtend(16)))
    e += update_flag_zn_r(c)
    e += update_flag_cf_inv_zf(c)
    e += [ExprAff(of, ExprInt(0, 1))]
    return e, []

def and_w(

ir, instr, a, b)

def and_w(ir, instr, a, b):
    e, a, b = mng_autoinc(a, b, 16)
    c = a & b
    e.append(ExprAff(b, c))
    e += update_flag_zn_r(c)
    e += update_flag_cf_inv_zf(c)
    e += [ExprAff(of, ExprInt(0, 1))]
    return e, []

def bcd2hex(

val)

Return the hex value of a BCD

def bcd2hex(val):
    "Return the hex value of a BCD"
    try:
        return int("0x%d" % val, 16)
    except ValueError:
        raise NotImplementedError("Not defined behaviour")

def bic_b(

ir, instr, a, b)

def bic_b(ir, instr, a, b):
    e, a, b = mng_autoinc(a, b, 8)
    c = (a[:8] ^ ExprInt(0xff, 8)) & b[:8]
    c = c.zeroExtend(b.size)
    e.append(ExprAff(b, c))
    return e, []

def bic_w(

ir, instr, a, b)

def bic_w(ir, instr, a, b):
    e, a, b = mng_autoinc(a, b, 16)
    c = (a ^ ExprInt(0xffff, 16)) & b
    e.append(ExprAff(b, c))
    return e, []

def bis_w(

ir, instr, a, b)

def bis_w(ir, instr, a, b):
    e, a, b = mng_autoinc(a, b, 16)
    c = a | b
    e.append(ExprAff(b, c))
    return e, []

def bit_w(

ir, instr, a, b)

def bit_w(ir, instr, a, b):
    e, a, b = mng_autoinc(a, b, 16)
    c = a & b
    e += update_flag_zn_r(c)
    e += update_flag_cf_inv_zf(c)
    e.append(ExprAff(of, ExprInt(0, 1)))
    return e, []

def call(

ir, instr, a)

def call(ir, instr, a):
    e, a, dummy = mng_autoinc(a, None, 16)

    loc_next = ir.get_next_loc_key(instr)
    loc_next_expr = ExprLoc(loc_next, 16)

    e.append(ExprAff(ExprMem(SP - ExprInt(2, 16), 16), loc_next_expr))
    e.append(ExprAff(SP, SP - ExprInt(2, 16)))
    e.append(ExprAff(PC, a))
    e.append(ExprAff(ir.IRDst, a))
    return e, []

def cmp_b(

ir, instr, a, b)

def cmp_b(ir, instr, a, b):
    e, a, b = mng_autoinc(a, b, 8)
    c = b[:8] - a[:8]
    e += update_flag_zn_r(c)
    e += update_flag_sub_cf(b[:8], a[:8], c)
    e += update_flag_sub_of(b[:8], a[:8], c)
    return e, []

def cmp_w(

ir, instr, a, b)

def cmp_w(ir, instr, a, b):
    e, a, b = mng_autoinc(a, b, 16)
    c = b - a
    e += update_flag_zn_r(c)
    e += update_flag_sub_cf(b, a, c)
    e += update_flag_sub_of(b, a, c)
    return e, []

def dadd_w(

ir, instr, a, b)

def dadd_w(ir, instr, a, b):
    e, a, b = mng_autoinc(a, b, 16)
    # TODO: microcorruption no carryflag
    c = ExprOp("bcdadd", b, a)  # +zeroExtend(cf, 16))

    e.append(ExprAff(b, c))
    # e += update_flag_zn_r(c)

    # micrcorruption
    e += update_flag_zf(a)
    # e += update_flag_nf(a)
    e += reset_sr_res()

    e.append(ExprAff(cf, ExprOp("bcdadd_cf", b, a)))  # +zeroExtend(cf, 16))))

    # of : undefined
    return e, []

def hex2bcd(

val)

Return val as BCD

def hex2bcd(val):
    "Return val as BCD"
    try:
        return int("%x" % val, 10)
    except ValueError:
        raise NotImplementedError("Not defined behaviour")

def jc(

ir, instr, a)

def jc(ir, instr, a):
    loc_next = ir.get_next_loc_key(instr)
    loc_next_expr = ExprLoc(loc_next, 16)
    e = []
    e.append(ExprAff(PC, ExprCond(cf, a, loc_next_expr)))
    e.append(ExprAff(ir.IRDst, ExprCond(cf, a, loc_next_expr)))
    return e, []

def jge(

ir, instr, a)

def jge(ir, instr, a):
    loc_next = ir.get_next_loc_key(instr)
    loc_next_expr = ExprLoc(loc_next, 16)
    e = []
    e.append(ExprAff(PC, ExprCond(nf ^ of, loc_next_expr, a)))
    e.append(ExprAff(ir.IRDst, ExprCond(nf ^ of, loc_next_expr, a)))
    return e, []

def jl(

ir, instr, a)

def jl(ir, instr, a):
    loc_next = ir.get_next_loc_key(instr)
    loc_next_expr = ExprLoc(loc_next, 16)
    e = []
    e.append(ExprAff(PC, ExprCond(nf ^ of, a, loc_next_expr)))
    e.append(ExprAff(ir.IRDst, ExprCond(nf ^ of, a, loc_next_expr)))
    return e, []

def jmp(

ir, instr, a)

def jmp(ir, instr, a):
    e = []
    e.append(ExprAff(PC, a))
    e.append(ExprAff(ir.IRDst, a))
    return e, []

def jnc(

ir, instr, a)

def jnc(ir, instr, a):
    loc_next = ir.get_next_loc_key(instr)
    loc_next_expr = ExprLoc(loc_next, 16)
    e = []
    e.append(ExprAff(PC, ExprCond(cf, loc_next_expr, a)))
    e.append(ExprAff(ir.IRDst, ExprCond(cf, loc_next_expr, a)))
    return e, []

def jnz(

ir, instr, a)

def jnz(ir, instr, a):
    loc_next = ir.get_next_loc_key(instr)
    loc_next_expr = ExprLoc(loc_next, 16)
    e = []
    e.append(ExprAff(PC, ExprCond(zf, loc_next_expr, a)))
    e.append(ExprAff(ir.IRDst, ExprCond(zf, loc_next_expr, a)))
    return e, []

def jz(

ir, instr, a)

def jz(ir, instr, a):
    loc_next = ir.get_next_loc_key(instr)
    loc_next_expr = ExprLoc(loc_next, 16)
    e = []
    e.append(ExprAff(PC, ExprCond(zf, a, loc_next_expr)))
    e.append(ExprAff(ir.IRDst, ExprCond(zf, a, loc_next_expr)))
    return e, []

def mng_autoinc(

a, b, size)

def mng_autoinc(a, b, size):
    e = []
    if not (isinstance(a, ExprOp) and a.op == "autoinc"):
        return e, a, b

    a_r = a.args[0]
    e.append(ExprAff(a_r, a_r + ExprInt(size / 8, a_r.size)))
    a = ExprMem(a_r, size)
    if isinstance(b, ExprMem) and a_r in b.arg:
        b = ExprMem(b.arg + ExprInt(size / 8, 16), b.size)
    return e, a, b

def mov_b(

ir, instr, a, b)

def mov_b(ir, instr, a, b):
    e, a, b = mng_autoinc(a, b, 8)
    if isinstance(b, ExprMem):
        b = ExprMem(b.arg, 8)
        a = a[:8]
    else:
        a = a[:8].zeroExtend(16)
    e.append(ExprAff(b, a))
    return e, []

def mov_w(

ir, instr, a, b)

def mov_w(ir, instr, a, b):
    e, a, b = mng_autoinc(a, b, 16)
    e.append(ExprAff(b, a))
    if b == ir.pc:
        e.append(ExprAff(ir.IRDst, a))
    return e, []

def push_w(

ir, instr, a)

def push_w(ir, instr, a):
    e = []
    e.append(ExprAff(ExprMem(SP - ExprInt(2, 16), 16), a))
    e.append(ExprAff(SP, SP - ExprInt(2, 16)))
    return e, []

def reset_sr_res(

)

def reset_sr_res():
    return [ExprAff(res, ExprInt(0, 7))]

def rra_w(

ir, instr, a)

def rra_w(ir, instr, a):
    e = []
    c = ExprCompose(a[1:16], a[15:16])
    e.append(ExprAff(a, c))
    # TODO: error in disasm microcorruption?
    # e.append(ExprAff(cf, a[:1]))
    # e += update_flag_zn_r(c)

    # micrcorruption
    e += update_flag_zf(a)
    # e += update_flag_nf(a)
    e += reset_sr_res()

    e.append(ExprAff(of, ExprInt(0, 1)))
    return e, []

def rrc_w(

ir, instr, a)

def rrc_w(ir, instr, a):
    e = []
    c = ExprCompose(a[1:16], cf)
    e.append(ExprAff(a, c))
    e.append(ExprAff(cf, a[:1]))
    # e += update_flag_zn_r(c)

    # micrcorruption
    e += update_flag_zf(a)
    # e += update_flag_nf(a)
    e += reset_sr_res()

    e.append(ExprAff(of, ExprInt(0, 1)))
    return e, []

def sub_w(

ir, instr, a, b)

def sub_w(ir, instr, a, b):
    e, a, b = mng_autoinc(a, b, 16)
    c = b - a
    e.append(ExprAff(b, c))
    e += update_flag_zn_r(c)
    e += update_flag_sub_cf(b, a, c)
    # micrcorruption
    # e += update_flag_sub_of(a, b, c)
    # e += update_flag_sub_of(b, a, c)
    return e, []

def swpb(

ir, instr, a)

def swpb(ir, instr, a):
    e = []
    x, y = a[:8], a[8:16]
    e.append(ExprAff(a, ExprCompose(y, x)))
    return e, []

def sxt(

ir, instr, a)

def sxt(ir, instr, a):
    e = []
    c = a[:8].signExtend(16)
    e.append(ExprAff(a, c))

    e += update_flag_zn_r(c)
    e += update_flag_cf_inv_zf(c)
    e.append(ExprAff(of, ExprInt(0, 1)))

    return e, []

def update_flag_add_cf(

a, b, c)

def update_flag_add_cf(a, b, c):
    return [ExprAff(cf, (((a ^ b) ^ c) ^ ((a ^ c) & (~(a ^ b)))).msb())]

def update_flag_add_of(

a, b, c)

def update_flag_add_of(a, b, c):
    return [ExprAff(of, (((a ^ c) & (~(a ^ b)))).msb())]

def update_flag_cf_inv_zf(

a)

def update_flag_cf_inv_zf(a):
    return [ExprAff(cf, ExprCond(a, ExprInt(1, cf.size), ExprInt(0, cf.size)))]

def update_flag_nf(

a)

def update_flag_nf(a):
    return [ExprAff(nf, a.msb())]

def update_flag_pf(

a)

def update_flag_pf(a):
    return [ExprAff(pf, ExprOp('parity', a & ExprInt(0xFF, a.size)))]

def update_flag_sub_cf(

a, b, c)

def update_flag_sub_cf(a, b, c):
    return [ExprAff(cf,
        ((((a ^ b) ^ c) ^ ((a ^ c) & (a ^ b))).msb()) ^ ExprInt(1, 1))]

def update_flag_sub_of(

a, b, c)

def update_flag_sub_of(a, b, c):
    return [ExprAff(of, (((a ^ c) & (a ^ b))).msb())]

def update_flag_zf(

a)

def update_flag_zf(a):
    return [ExprAff(zf, ExprCond(a, ExprInt(0, zf.size), ExprInt(1, zf.size)))]

def update_flag_zn_r(

a)

def update_flag_zn_r(a):
    e = []
    e += update_flag_zf(a)
    e += update_flag_nf(a)
    e += reset_sr_res()
    return e

def xor_w(

ir, instr, a, b)

def xor_w(ir, instr, a, b):
    e, a, b = mng_autoinc(a, b, 16)
    c = b ^ a
    e.append(ExprAff(b, c))
    e += update_flag_zn_r(c)
    e += update_flag_cf_inv_zf(c)
    e.append(ExprAff(of, b.msb() & a.msb()))
    return e, []

Classes

class ir_msp430

class ir_msp430(IntermediateRepresentation):

    def __init__(self, loc_db=None):
        IntermediateRepresentation.__init__(self, mn_msp430, None, loc_db)
        self.pc = PC
        self.sp = SP
        self.IRDst = ExprId('IRDst', 16)
        self.addrsize = 16

    def mod_pc(self, instr, instr_ir, extra_ir):
        pass

    def get_ir(self, instr):
        args = instr.args
        instr_ir, extra_ir = mnemo_func[instr.name](self, instr, *args)
        self.mod_sr(instr, instr_ir, extra_ir)

        return instr_ir, extra_ir

    def mod_sr(self, instr, instr_ir, extra_ir):
        for i, x in enumerate(instr_ir):
            x = ExprAff(x.dst, x.src.replace_expr({SR: composed_sr}))
            instr_ir[i] = x
            if x.dst != SR:
                continue
            xx = ComposeExprAff(composed_sr, x.src)
            instr_ir[i:i+1] = xx
        for i, x in enumerate(instr_ir):
            x = ExprAff(x.dst, x.src.replace_expr(
                {self.pc: ExprInt(instr.offset + instr.l, 16)}))
            instr_ir[i] = x

        if extra_ir:
            raise NotImplementedError('not fully functional')

Ancestors (in MRO)

  • ir_msp430
  • miasm2.ir.ir.IntermediateRepresentation
  • __builtin__.object

Instance variables

var IRDst

var addrsize

var pc

var sp

Methods

def __init__(

self, loc_db=None)

def __init__(self, loc_db=None):
    IntermediateRepresentation.__init__(self, mn_msp430, None, loc_db)
    self.pc = PC
    self.sp = SP
    self.IRDst = ExprId('IRDst', 16)
    self.addrsize = 16

def add_asmblock_to_ircfg(

self, block, ircfg, gen_pc_updt=False)

Add a native block to the current IR @block: native assembly block @ircfg: IRCFG instance @gen_pc_updt: insert PC update effects between instructions

def add_asmblock_to_ircfg(self, block, ircfg, gen_pc_updt=False):
    """
    Add a native block to the current IR
    @block: native assembly block
    @ircfg: IRCFG instance
    @gen_pc_updt: insert PC update effects between instructions
    """
    loc_key = block.loc_key
    ir_blocks_all = []
    assignments = []
    for instr in block.lines:
        if loc_key is None:
            assignments = []
            loc_key = self.get_loc_key_for_instr(instr)
        split = self.add_instr_to_current_state(
            instr, block, assignments,
            ir_blocks_all, gen_pc_updt
        )
        if split:
            ir_blocks_all.append(IRBlock(loc_key, assignments))
            loc_key = None
            assignments = []
    if loc_key is not None:
        ir_blocks_all.append(IRBlock(loc_key, assignments))
    new_ir_blocks_all = self.post_add_asmblock_to_ircfg(block, ircfg, ir_blocks_all)
    for irblock in new_ir_blocks_all:
        ircfg.add_irblock(irblock)
    return new_ir_blocks_all

def add_bloc(

self, block, gen_pc_updt=False)

DEPRECATED function Use add_block instead of add_block

def add_bloc(self, block, gen_pc_updt=False):
    """
    DEPRECATED function
    Use add_block instead of add_block
    """
    self.add_block(block, gen_pc_updt)

def add_block(

self, block, gen_pc_updt=False)

DEPRECATED function Use add_block instead of add_block

def add_block(self, block, gen_pc_updt=False):
    """
    DEPRECATED function
    Use add_block instead of add_block
    """
    warnings.warn("""DEPRECATION WARNING
    ircfg is now out of IntermediateRepresentation
    Use:
    ircfg = ir_arch.new_ircfg()
    ir_arch.add_asmblock_to_ircfg(block, ircfg)
    """)
    raise RuntimeError("API Deprecated")

def add_instr_to_current_state(

self, instr, block, assignments, ir_blocks_all, gen_pc_updt)

Add the IR effects of an instruction to the current state.

Returns a bool: True if the current assignments list must be split False in other cases.

@instr: native instruction @block: native block source @assignments: list of current AssignBlocks @ir_blocks_all: list of additional effects @gen_pc_updt: insert PC update effects between instructions

def add_instr_to_current_state(self, instr, block, assignments, ir_blocks_all, gen_pc_updt):
    """
    Add the IR effects of an instruction to the current state.
    Returns a bool:
    * True if the current assignments list must be split
    * False in other cases.
    @instr: native instruction
    @block: native block source
    @assignments: list of current AssignBlocks
    @ir_blocks_all: list of additional effects
    @gen_pc_updt: insert PC update effects between instructions
    """
    if gen_pc_updt is not False:
        self.gen_pc_update(assignments, instr)
    assignblk, ir_blocks_extra = self.instr2ir(instr)
    assignments.append(assignblk)
    ir_blocks_all += ir_blocks_extra
    if ir_blocks_extra:
        return True
    return False

def add_instr_to_ircfg(

self, instr, ircfg, loc_key=None, gen_pc_updt=False)

Add the native instruction @instr to the @ircfg @instr: instruction instance @ircfg: IRCFG instance @loc_key: loc_key instance of the instruction destination @gen_pc_updt: insert PC update effects between instructions

def add_instr_to_ircfg(self, instr, ircfg, loc_key=None, gen_pc_updt=False):
    """
    Add the native instruction @instr to the @ircfg
    @instr: instruction instance
    @ircfg: IRCFG instance
    @loc_key: loc_key instance of the instruction destination
    @gen_pc_updt: insert PC update effects between instructions
    """
    if loc_key is None:
        offset = getattr(instr, "offset", None)
        loc_key = self.loc_db.add_location(offset=offset)
    block = AsmBlock(loc_key)
    block.lines = [instr]
    self.add_asmblock_to_ircfg(block, ircfg, gen_pc_updt)
    return loc_key

def expr_fix_regs_for_mode(

self, expr, *args, **kwargs)

def expr_fix_regs_for_mode(self, expr, *args, **kwargs):
    return expr

def expraff_fix_regs_for_mode(

self, expr, *args, **kwargs)

def expraff_fix_regs_for_mode(self, expr, *args, **kwargs):
    return expr

def gen_loc_key_and_expr(

self, size)

Return a loc_key and it's corresponding ExprLoc @size: size of expression

def gen_loc_key_and_expr(self, size):
    """
    Return a loc_key and it's corresponding ExprLoc
    @size: size of expression
    """
    loc_key = self.loc_db.add_location()
    return loc_key, m2_expr.ExprLoc(loc_key, size)

def gen_pc_update(

self, assignments, instr)

def gen_pc_update(self, assignments, instr):
    offset = m2_expr.ExprInt(instr.offset, self.pc.size)
    assignments.append(AssignBlock({self.pc:offset}, instr))

def get_ir(

self, instr)

def get_ir(self, instr):
    args = instr.args
    instr_ir, extra_ir = mnemo_func[instr.name](self, instr, *args)
    self.mod_sr(instr, instr_ir, extra_ir)
    return instr_ir, extra_ir

def get_loc_key_for_instr(

self, instr)

Returns the loc_key associated to an instruction @instr: current instruction

def get_loc_key_for_instr(self, instr):
    """Returns the loc_key associated to an instruction
    @instr: current instruction"""
    return self.loc_db.get_or_create_offset_location(instr.offset)

def get_next_loc_key(

self, instr)

def get_next_loc_key(self, instr):
    loc_key = self.loc_db.get_or_create_offset_location(instr.offset + instr.l)
    return loc_key

def instr2ir(

self, instr)

def instr2ir(self, instr):
    ir_bloc_cur, extra_irblocks = self.get_ir(instr)
    for index, irb in enumerate(extra_irblocks):
        irs = []
        for assignblk in irb:
            irs.append(AssignBlock(assignblk, instr))
        extra_irblocks[index] = IRBlock(irb.loc_key, irs)
    assignblk = AssignBlock(ir_bloc_cur, instr)
    return assignblk, extra_irblocks

def irbloc_fix_regs_for_mode(

self, irblock, *args, **kwargs)

def irbloc_fix_regs_for_mode(self, irblock, *args, **kwargs):
    return irblock

def is_pc_written(

self, block)

Return the first Assignblk of the @blockin which PC is written @block: IRBlock instance

def is_pc_written(self, block):
    """Return the first Assignblk of the @blockin which PC is written
    @block: IRBlock instance"""
    all_pc = self.arch.pc.values()
    for assignblk in block:
        if assignblk.dst in all_pc:
            return assignblk
    return None

def mod_pc(

self, instr, instr_ir, extra_ir)

def mod_pc(self, instr, instr_ir, extra_ir):
    pass

def mod_sr(

self, instr, instr_ir, extra_ir)

def mod_sr(self, instr, instr_ir, extra_ir):
    for i, x in enumerate(instr_ir):
        x = ExprAff(x.dst, x.src.replace_expr({SR: composed_sr}))
        instr_ir[i] = x
        if x.dst != SR:
            continue
        xx = ComposeExprAff(composed_sr, x.src)
        instr_ir[i:i+1] = xx
    for i, x in enumerate(instr_ir):
        x = ExprAff(x.dst, x.src.replace_expr(
            {self.pc: ExprInt(instr.offset + instr.l, 16)}))
        instr_ir[i] = x
    if extra_ir:
        raise NotImplementedError('not fully functional')

def new_ircfg(

self, *args, **kwargs)

Return a new instance of IRCFG

def new_ircfg(self, *args, **kwargs):
    """
    Return a new instance of IRCFG
    """
    return IRCFG(self.IRDst, self.loc_db, *args, **kwargs)

def new_ircfg_from_asmcfg(

self, asmcfg, *args, **kwargs)

Return a new instance of IRCFG from an @asmcfg @asmcfg: AsmCFG instance

def new_ircfg_from_asmcfg(self, asmcfg, *args, **kwargs):
    """
    Return a new instance of IRCFG from an @asmcfg
    @asmcfg: AsmCFG instance
    """
    ircfg = IRCFG(self.IRDst, self.loc_db, *args, **kwargs)
    for block in asmcfg.blocks:
        self.add_asmblock_to_ircfg(block, ircfg)
    return ircfg

def post_add_asmblock_to_ircfg(

self, block, ircfg, ir_blocks)

def post_add_asmblock_to_ircfg(self, block, ircfg, ir_blocks):
    self.set_empty_dst_to_next(block, ir_blocks)
    new_irblocks = []
    for irblock in ir_blocks:
        new_irblock = self.irbloc_fix_regs_for_mode(irblock, self.attrib)
        ircfg.add_irblock(new_irblock)
        new_irblocks.append(new_irblock)
    return new_irblocks

def set_empty_dst_to_next(

self, block, ir_blocks)

def set_empty_dst_to_next(self, block, ir_blocks):
    for index, irblock in enumerate(ir_blocks):
        if irblock.dst is not None:
            continue
        next_loc_key = block.get_next()
        if next_loc_key is None:
            loc_key = None
            if block.lines:
                line = block.lines[-1]
                if line.offset is not None:
                    loc_key = self.loc_db.get_or_create_offset_location(line.offset + line.l)
            if loc_key is None:
                loc_key = self.loc_db.add_location()
            block.add_cst(loc_key, AsmConstraint.c_next)
        else:
            loc_key = next_loc_key
        dst = m2_expr.ExprLoc(loc_key, self.pc.size)
        if irblock.assignblks:
            instr = irblock.assignblks[-1].instr
        else:
            instr = None
        assignblk = AssignBlock({self.IRDst: dst}, instr)
        ir_blocks[index] = IRBlock(irblock.loc_key, list(irblock.assignblks) + [assignblk])