예제 #1
0
    def emul(self, ctx=None, step=False):
        """Symbolic execution of relevant nodes according to the history
        Return the values of inputs nodes' elements
        @ctx: (optional) Initial context as dictionnary
        @step: (optional) Verbose execution
        Warning: The emulation is not sound if the inputs nodes depend on loop
        variant.
        """
        # Init
        ctx_init = self._ira.arch.regs.regs_init
        if ctx is not None:
            ctx_init.update(ctx)
        assignblks = []

        # Build a single affectation block according to history
        last_index = len(self.relevant_loc_keys)
        for index, loc_key in enumerate(reversed(self.relevant_loc_keys), 1):
            if index == last_index and loc_key == self.initial_state.loc_key:
                line_nb = self.initial_state.line_nb
            else:
                line_nb = None
            assignblks += self.irblock_slice(self._ira.blocks[loc_key],
                                             line_nb).assignblks

        # Eval the block
        symbol_pool = AsmSymbolPool()
        temp_loc = symbol_pool.getby_name_create("Temp")
        symb_exec = SymbolicExecutionEngine(self._ira, ctx_init)
        symb_exec.eval_updt_irblock(IRBlock(temp_loc, assignblks), step=step)

        # Return only inputs values (others could be wrongs)
        return {element: symb_exec.symbols[element]
                for element in self.inputs}
예제 #2
0
def arm_guess_jump_table(
    mnemo, attrib, pool_bin, cur_bloc, offsets_to_dis, symbol_pool):
    ira = get_ira(mnemo, attrib)

    jra = ExprId('jra')
    jrb = ExprId('jrb')

    sp = AsmSymbolPool()
    ir_arch = ira(sp)
    ir_arch.add_block(cur_bloc)

    ir_blocks = ir_arch.blocks.values()
    for irblock in ir_blocks:
        # print 'X'*40
        # print irblock
        pc_val = None
        # lr_val = None
        for exprs in irblock.irs:
            for e in exprs:
                if e.dst == ir_arch.pc:
                    pc_val = e.src
                # if e.dst == mnemo.regs.LR:
                #    lr_val = e.src
        if pc_val is None:
            continue
        if not isinstance(pc_val, ExprMem):
            continue
        assert(pc_val.size == 32)
        print pc_val
        ad = pc_val.arg
        ad = expr_simp(ad)
        print ad
        res = match_expr(ad, jra + jrb, set([jra, jrb]))
        if res is False:
            raise NotImplementedError('not fully functional')
        print res
        if not isinstance(res[jrb], ExprInt):
            raise NotImplementedError('not fully functional')
        base_ad = int(res[jrb])
        print base_ad
        addrs = set()
        i = -1
        max_table_entry = 10000
        max_diff_addr = 0x100000  # heuristic
        while i < max_table_entry:
            i += 1
            try:
                ad = upck32(pool_bin.getbytes(base_ad + 4 * i, 4))
            except:
                break
            if abs(ad - base_ad) > max_diff_addr:
                break
            addrs.add(ad)
        print [hex(x) for x in addrs]

        for ad in addrs:
            offsets_to_dis.add(ad)
            l = symbol_pool.getby_offset_create(ad)
            c = AsmConstraintTo(l)
            cur_bloc.addto(c)
예제 #3
0
파일: ir.py 프로젝트: zhencang/miasm
 def __init__(self, arch, attrib, symbol_pool=None):
     if symbol_pool is None:
         symbol_pool = AsmSymbolPool()
     self.symbol_pool = symbol_pool
     self.blocks = {}
     self.pc = arch.getpc(attrib)
     self.sp = arch.getsp(attrib)
     self.arch = arch
     self.attrib = attrib
     # Lazy structure
     self._graph = None
예제 #4
0
def arm_guess_subcall(
    mnemo, attrib, pool_bin, cur_bloc, offsets_to_dis, symbol_pool):
    ira = get_ira(mnemo, attrib)

    sp = AsmSymbolPool()
    ir_arch = ira(sp)
    print '###'
    print cur_bloc
    ir_arch.add_block(cur_bloc)

    ir_blocks = ir_arch.blocks.values()
    # flow_graph = DiGraph()
    to_add = set()
    for irblock in ir_blocks:
        # print 'X'*40
        # print irblock
        pc_val = None
        lr_val = None
        for exprs in irblock.irs:
            for e in exprs:
                if e.dst == ir_arch.pc:
                    pc_val = e.src
                if e.dst == mnemo.regs.LR:
                    lr_val = e.src
        if pc_val is None or lr_val is None:
            continue
        if not isinstance(lr_val, ExprInt):
            continue

        l = cur_bloc.lines[-1]
        if lr_val.arg != l.offset + l.l:
            continue
        # print 'IS CALL!'
        l = symbol_pool.getby_offset_create(int(lr_val))
        c = AsmConstraintNext(l)

        to_add.add(c)
        offsets_to_dis.add(int(lr_val))

    # if to_add:
    #    print 'R'*70
    for c in to_add:
        # print c
        cur_bloc.addto(c)
예제 #5
0
def miasm_anal(r2_op, r2_address, r2_buffer, r2_length):
    """Define an instruction behavior using miasm."""

    # Cast radare2 variables
    opcode = ffi.cast("char*", r2_buffer)


    # Prepare the opcode
    opcode = ffi.unpack(opcode, r2_length)


    # Disassemble the opcode
    try:
        machine = miasm_machine()
        mode = machine.dis_engine().attrib
        instr = machine.mn().dis(opcode, mode)
        instr.offset = r2_address
        if instr.dstflow():
            # Adjust arguments values using the instruction offset
            instr.dstflow2label(AsmSymbolPool())
        dis_len = instr.l
    except:
        # Can't do anything with an invalid instruction
        return


    # Cast the RAnalOp structure and fill some fields
    r2_analop = ffi.cast("RAnalOp_r2m2*", r2_op)
    r2_analop.mnemonic = alloc_string(instr.name)
    r2_analop.size = dis_len
    r2_analop.type = R_ANAL_OP_TYPE_UNK
    r2_analop.eob = 0   # End Of Block

    # Convert miasm expressions to ESIL
    get_esil(r2_analop, instr)


    ### Architecture agnostic analysis

    # Instructions that *DO NOT* stop a basic bloc
    if instr.breakflow() is False:
        return
    else:
        r2_analop.eob = 1  # End Of Block


    # Assume that an instruction starting with 'RET' is a return
    # Note: add it to miasm2 as getpc() ?
    if instr.name[:3].upper().startswith("RET"):
        r2_analop.type = R_ANAL_OP_TYPE_RET

    # Instructions that explicitly provide the destination
    if instr and instr.dstflow():
        expr = instr.getdstflow(None)[0]

        if instr.is_subcall():
            r2_anal_subcall(r2_analop, expr)
            return

        if r2_analop.type == R_ANAL_OP_TYPE_UNK and instr.splitflow():
            r2_anal_splitflow(r2_analop, r2_address, instr, expr)
            return

        if isinstance(expr, ExprInt):
            r2_analop.type = R_ANAL_OP_TYPE_JMP
            r2_analop.jump = int(expr.arg) & 0xFFFFFFFFFFFFFFFF

        elif isinstance(expr, ExprId):
            if isinstance(expr.name, AsmLabel):
                # Get the miasm2 AsmLabel address
                r2_analop.type = R_ANAL_OP_TYPE_JMP
                r2_analop.jump = label2address(expr) & 0xFFFFFFFFFFFFFFFF
            else:
                r2_analop.type = R_ANAL_OP_TYPE_UJMP

        elif isinstance(expr, ExprMem):
            r2_analop.type = R_ANAL_OP_TYPE_MJMP

        else:
            print >> sys.stderr, "miasm_anal(): don't know what to do with: %s" % instr
예제 #6
0
""" Test cases for dead code elimination"""
from miasm2.expression.expression import ExprId, ExprInt, ExprAff, ExprMem
from miasm2.core.asmblock import AsmSymbolPool
from miasm2.analysis.data_flow import *
from miasm2.ir.analysis import ira
from miasm2.ir.ir import IRBlock, AssignBlock

symbol_pool = AsmSymbolPool()

a = ExprId("a", 32)
b = ExprId("b", 32)
c = ExprId("c", 32)
d = ExprId("d", 32)
r = ExprId("r", 32)

a_init = ExprId("a_init", 32)
b_init = ExprId("b_init", 32)
c_init = ExprId("c_init", 32)
d_init = ExprId("d_init", 32)
r_init = ExprId("r_init", 32) # Return register

pc = ExprId("pc", 32)
sp = ExprId("sp", 32)

CST1 = ExprInt(0x11, 32)
CST2 = ExprInt(0x12, 32)
CST3 = ExprInt(0x13, 32)

LBL0 = symbol_pool.add_location("lbl0", 0)
LBL1 = symbol_pool.add_location("lbl1", 1)
LBL2 = symbol_pool.add_location("lbl2", 2)
예제 #7
0
def miasm_dis(r2_op, r2_address, r2_buffer, r2_length):
    """Disassemble an instruction using miasm."""

    # Cast radare2 variables
    rasmop = ffi.cast("RAsmOp_r2m2*", r2_op)
    opcode = ffi.cast("char*", r2_buffer)

    # Prepare the opcode
    opcode = ffi.unpack(opcode, r2_length)

    # Get the miasm2 machine
    machine = miasm_machine()
    if machine is None:
        return

    # Disassemble the opcode
    try:
        mode = machine.dis_engine().attrib
        instr = machine.mn().dis(opcode, mode)
        instr.offset = r2_address
        if instr.dstflow():

            # Remember ExprInt arguments sizes
            args_size = list()
            for i in range(len(instr.args)):
                if isinstance(instr.args[i], ExprInt):
                    args_size.append(instr.args[i].size)
                else:
                    args_size.append(None)

            # Adjust arguments values using the instruction offset
            instr.dstflow2label(AsmSymbolPool())

            # Convert label back to ExprInt
            for i in range(len(instr.args)):
                if args_size[i] is None:
                    continue
                if isinstance(instr.args[i], ExprId) and \
                   isinstance(instr.args[i].name, AsmLabel):
                    addr = str(instr.args[i].name)
                    addr = int(addr.split(":")[1], 16)
                    instr.args[i] = ExprInt(addr, args_size[i])


        dis_str = str(instr)
        dis_len = instr.l
    except:
        dis_str = "/!\ Can't disassemble using miasm /!\\"
        dis_len = 2  # GV: seems fischy !

    # Remaining bytes
    buf_hex = opcode[0:dis_len].encode("hex")

    # Check buffer sizes
    if len(dis_str)-1 > 256:
        dis_str = "/!\ Disassembled instruction is too long /!\\"
    if len(buf_hex)-1 > 256:
        buf_hex = buf_hex[:255]

    # Fill the RAsmOp structure
    rasmop.size = dis_len
    rasmop.buf_asm = dis_str
    rasmop.buf_hex = buf_hex
예제 #8
0
파일: arch.py 프로젝트: damnya/miasm
import time
from pdb import pm
from miasm2.arch.msp430.arch import *
from miasm2.core.asmblock import AsmSymbolPool

symbol_pool = AsmSymbolPool()


def h2i(s):
    return s.replace(' ', '').decode('hex')


def u16swap(i):
    return struct.unpack('<H', struct.pack('>H', i))[0]


reg_tests_msp = [
    ("4456    mov.w      SP, R4", "0441"),
    ("4d4f    mov.b      R13, R15", "4f4d"),
    ("49fe    mov.w      @R13, R9", "294d"),
    ("4982    mov.w      0x10(R14), R13", "1d4e1000"),
    ("4972    mov.w      R14, 0x0(SP)", "814e0000"),
    ("46de    mov.w      0x2(R14), 0x2(R13)", "9d4e02000200"),
    ("469e    mov.w      @0x2400, R11", "1b420024"),
    ("4c14    mov.w      0x4A96, R15", "3f40964a"),
    ("47c0    mov.w      0x1, R8", "1843"),
    ("48fc    mov.w      0x2, R10", "2a43"),
    ("44fe    mov.w      0x4, R7", "2742"),
    ("4a28    mov.w      0xFFFF, R15", "3f43"),
    ("4416    mov.w      R5, @0x15C", "82455c01"),
    ("4a22    add.w      R11, R15", "0f5b"),
예제 #9
0
파일: z3_ir.py 프로젝트: etsangsplk/miasm
import z3

from miasm2.core.asmblock import AsmSymbolPool
from miasm2.expression.expression import *
from miasm2.ir.translators.z3_ir import Z3Mem, TranslatorZ3

# Some examples of use/unit tests.

symbol_pool = AsmSymbolPool()
translator1 = TranslatorZ3(endianness="<", symbol_pool=symbol_pool)
translator2 = TranslatorZ3(endianness=">", symbol_pool=symbol_pool)


def equiv(z3_expr1, z3_expr2):
    s = z3.Solver()
    s.add(z3.Not(z3_expr1 == z3_expr2))
    return s.check() == z3.unsat

def check_interp(interp, constraints, bits=32, valbits=8):
    """Checks that a list of @constraints (addr, value) (as python ints)
    match a z3 FuncInterp (@interp).
    """
    constraints = dict((addr,
                        z3.BitVecVal(val, valbits))
                       for addr, val in constraints)
    l = interp.as_list()
    for entry in l:
        if not isinstance(entry, list) or len(entry) < 2:
            continue
        addr, value = entry[0], entry[1]
        if addr.as_long() in constraints: