Beispiel #1
0
def sanitize_graph_head(ircfg, head):
    """
    In multiple algorithm, the @head of the ircfg may not have predecessors.
    The function transform the @ircfg in order to ensure this property
    @ircfg: IRCFG instance
    @head: the location of the graph's head
    """

    if not ircfg.predecessors(head):
        return
    original_edges = ircfg.predecessors(head)
    sub_head = ircfg.loc_db.add_location()

    # Duplicate graph, replacing references to head by sub_head
    replaced_expr = {
        ExprLoc(head, ircfg.IRDst.size): ExprLoc(sub_head, ircfg.IRDst.size)
    }
    ircfg.simplify(lambda expr: expr.replace_expr(replaced_expr))
    # Duplicate head block
    ircfg.add_irblock(IRBlock(ircfg.loc_db, sub_head,
                              list(ircfg.blocks[head])))

    # Remove original head block
    ircfg.del_node(head)

    for src in original_edges:
        ircfg.add_edge(src, sub_head)

    # Create new head, jumping to sub_head
    assignblk = AssignBlock({ircfg.IRDst: ExprLoc(sub_head, ircfg.IRDst.size)})
    new_irblock = IRBlock(ircfg.loc_db, head, [assignblk])
    ircfg.add_irblock(new_irblock)
Beispiel #2
0
 def recoverAlgorithm(self):
     if self.normalIRCFG is None:
         self.getNormalIRCFG()
     newLocDB = LocationDB()
     size = BinaryAnalysis.disasmEngine.attrib
     newIRA = BinaryAnalysis.iraType(newLocDB)
     newIRCFG = newIRA.new_ircfg()
     numLockey = 0
     head = LocKey(numLockey)
     todo = [(self.address, head, {}, None)]
     numLockey += 1
     while todo:
         nextTarget, lockey, state, preBlock = todo.pop()
         nextTarget, state = self.symbolicExecution(self.normalIRA,
                                                    self.normalIRCFG,
                                                    nextTarget, state)
         if isinstance(nextTarget, ExprCond):
             newLockey1 = LocKey(numLockey)
             newLockey2 = LocKey(numLockey + 1)
             ir_dst = state[newIRCFG.IRDst]
             new_cond = ExprCond(ir_dst.cond, ExprLoc(newLockey1, size),
                                 ExprLoc(newLockey2, size))
             state[newIRCFG.IRDst] = new_cond
             numLockey += 2
             newIRBlock = self.addIRBlock(newIRCFG, state, lockey)
             state[newIRCFG.IRDst] = ir_dst
             todo.append((nextTarget.src1, newLockey1, state, newIRBlock))
             todo.append((nextTarget.src2, newLockey2, state, newIRBlock))
         else:
             self.addIRBlock(newIRCFG, state, lockey)
     return newLocDB, newIRCFG
Beispiel #3
0
    def asm_ast_to_expr(self, arg, loc_db):
        """Convert AST to expressions
        Note: - code inspired by miasm/arch/mips32/arch.py"""

        if isinstance(arg, AstId):
            if isinstance(arg.name, ExprId):
                return arg.name
            if isinstance(arg.name, str) and arg.name in gpr_names:
                return None  # GV: why?
            loc_key = loc_db.get_or_create_name_location(arg.name.encode())
            return ExprLoc(loc_key, 32)

        elif isinstance(arg, AstMem):
            addr = self.asm_ast_to_expr(arg.ptr, loc_db)
            if addr is None:
                return None
            return ExprMem(addr, 32)

        elif isinstance(arg, AstInt):
            return ExprInt(arg.value, 32)

        elif 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)

        # Raise an exception if the argument was not processed
        message = "mep_arg.asm_ast_to_expr(): don't know what \
                to do with a '%s' instance." % type(arg)
        raise Exception(message)
Beispiel #4
0
    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)
Beispiel #5
0
  def dstflow2label(self, loc_db):
    """Set the label for the current destination.
        Note: it is used at disassembly"""

    loc_arg = self.get_dst_num()
    expr = self.args[loc_arg]
    if not expr.is_int():
      return
    addr = ((int(expr)*4)+self.offset + 8) & 0xffffffff
    loc_key = loc_db.get_or_create_offset_location(addr)
    self.args[0] = ExprLoc(loc_key, expr.size)
Beispiel #6
0
 def dstflow2label(self, loc_db):
     """Set the label for the current destination.
     Note: it is used at disassembly"""
     loc_arg = self.get_dst_num()
     expr = self.args[loc_arg]
     if not expr.is_int():
         return
     # mega hack we add 2 because imm16 is 2 bytes
     addr = (int(expr) + self.offset + 2) & int(expr.mask)
     loc_key = loc_db.get_or_create_offset_location(addr)
     self.args[loc_arg] = ExprLoc(loc_key, expr.size)
Beispiel #7
0
    def canonize_to_exprloc(self, expr):
        """
        If expr is ExprInt, return ExprLoc with corresponding loc_key
        Else, return expr

        @expr: Expr instance
        """
        if expr.is_int():
            loc_key = self.get_or_create_offset_location(int(expr))
            ret = ExprLoc(loc_key, expr.size)
            return ret
        return expr
Beispiel #8
0
def detect_func_name(cur_bloc, loc_db, *args, **kwargs):
    for line in cur_bloc.lines:
        for i in range(len(line.args)):
            arg = line.args[i]
            if isinstance(arg, ExprMem):
                ptr = arg.ptr
                if isinstance(ptr, ExprOp):
                    if isinstance(ptr.args[0], ExprId) and ('IP' in str(
                            ptr.args[0])) and isinstance(ptr.args[1], ExprInt):
                        ip = line.offset + line.l
                        offset = ptr.args[1].arg
                        loc_key = loc_db.get_offset_location(ip + offset)
                        if loc_key is not None:
                            line.args[i] = ExprLoc(loc_key, arg.size)
                            names = loc_db.get_location_names(cur_bloc.loc_key)
                            if len(names) == 0:
                                new_name = list(
                                    loc_db.get_location_names(loc_key))
                                if len(new_name) != 0:
                                    new_name = '_' + new_name[0].decode()
                                    try:
                                        loc_db.add_location_name(
                                            cur_bloc.loc_key, new_name)
                                    except:
                                        pass
                elif isinstance(ptr, ExprInt) and line.name == 'JMP':
                    offset = ptr.arg
                    loc_key = loc_db.get_offset_location(offset)
                    if loc_key is not None:
                        line.args[i] = ExprLoc(loc_key, arg.size)
                        names = loc_db.get_location_names(cur_bloc.loc_key)
                        if len(names) == 0:
                            new_name = list(loc_db.get_location_names(loc_key))
                            if len(new_name) != 0:
                                new_name = '_' + new_name[0].decode()
                                try:
                                    loc_db.add_location_name(
                                        cur_bloc.loc_key, new_name)
                                except:
                                    pass
Beispiel #9
0
def casp(ir, instr, arg1, arg2, arg3):
    # XXX TODO: memory barrier
    e = []
    if arg1.size == 32:
        regs = gpregs32_expr
    else:
        regs = gpregs64_expr
    index1 = regs.index(arg1)
    index2 = regs.index(arg2)

    # TODO endianness
    comp_value = ExprCompose(regs[index1], regs[index1 + 1])
    new_value = ExprCompose(regs[index2], regs[index2 + 1])
    assert arg3.is_op('preinc')
    ptr = arg3.args[0]
    data = ExprMem(ptr, comp_value.size)

    loc_store = ExprLoc(ir.loc_db.add_location(), ir.IRDst.size)
    loc_do = ExprLoc(ir.loc_db.add_location(), ir.IRDst.size)
    loc_next = ExprLoc(ir.get_next_loc_key(instr), ir.IRDst.size)

    e.append(
        ExprAssign(
            ir.IRDst,
            ExprCond(ExprOp("FLAG_EQ_CMP", data, comp_value), loc_do,
                     loc_store)))

    e_store = []
    e_store.append(ExprAssign(data, new_value))
    e_store.append(ExprAssign(ir.IRDst, loc_do))
    blk_store = IRBlock(loc_store.loc_key, [AssignBlock(e_store, instr)])

    e_do = []
    e_do.append(ExprAssign(regs[index1], data[:data.size // 2]))
    e_do.append(ExprAssign(regs[index1 + 1], data[data.size // 2:]))
    e_do.append(ExprAssign(ir.IRDst, loc_next))
    blk_do = IRBlock(loc_do.loc_key, [AssignBlock(e_do, instr)])

    return e, [blk_store, blk_do]
Beispiel #10
0
 def assignblk_to_irbloc(self, instr, assignblk):
     """
     Ensure IRDst is always set in the head @assignblk of the @instr
     @instr: an instruction instance
     @assignblk: Assignblk instance
     """
     new_assignblk = dict(assignblk)
     if self.ir_arch.IRDst not in assignblk:
         offset = instr.offset + instr.l
         loc_key = self.ir_arch.loc_db.get_or_create_offset_location(offset)
         dst = ExprLoc(loc_key, self.ir_arch.IRDst.size)
         new_assignblk[self.ir_arch.IRDst] = dst
     irs = [AssignBlock(new_assignblk, instr)]
     return IRBlock(self.ir_arch.get_loc_key_for_instr(instr), irs)
Beispiel #11
0
    def call_effects(self, ad, instr):
        call_assignblk = AssignBlock([
            ExprAssign(
                self.ret_reg,
                ExprOp(
                    'call_func_ret',
                    ad,
                    self.arch.regs.R0,
                    self.arch.regs.R1,
                    self.arch.regs.R2,
                    self.arch.regs.R3,
                )),
            ExprAssign(self.sp, ExprOp('call_func_stack', ad, self.sp)),
        ], instr)

        cond = instr.additional_info.cond
        if cond == 14:  # COND_ALWAYS:
            return [call_assignblk], []

        # Call is a conditional instruction
        cond = tab_cond[cond]

        loc_next = self.get_next_loc_key(instr)
        loc_next_expr = ExprLoc(loc_next, 32)
        loc_do = self.loc_db.add_location()
        loc_do_expr = ExprLoc(loc_do, 32)
        dst_cond = ExprCond(cond, loc_do_expr, loc_next_expr)

        call_assignblks = [
            call_assignblk,
            AssignBlock([ExprAssign(self.IRDst, loc_next_expr)], instr),
        ]
        e_do = IRBlock(loc_do, call_assignblks)
        assignblks_out = [
            AssignBlock([ExprAssign(self.IRDst, dst_cond)], instr)
        ]
        return assignblks_out, [e_do]
Beispiel #12
0
    def dstflow2label(self, loc_db):
        """Set the label for the current destination.
        Note: it is used at disassembly"""
        if self.name == 'JMP':
            loc_arg = 0
        elif self.name in ["JE", "JNE", "JGE", "JL"]:
            loc_arg = 2
        else:
            return
        expr = self.args[loc_arg]
        if not expr.is_int():
            return
        addr = int(expr) & int(expr.mask)

        loc_key = loc_db.get_or_create_offset_location(addr)
        self.args[loc_arg] = ExprLoc(loc_key, expr.size)
Beispiel #13
0
def stop_exec(jitter):
    global max_scount
    success_loc = ExprLoc(dse.loc_db.get_offset_location(success_ptr), 64)
    for path, model in dse.new_solutions.items():
        scount = path.count(success_loc)
        if scount > max_scount:
            candidate = bytearray(0x20)
            for i in range(0x20):
                bb = model.eval(
                    dse.z3_trans.from_expr(dse.memory_to_expr(flag_ptr + i)))
                candidate[i] = bb.as_long() if type(
                    bb) == z3.z3.BitVecNumRef else current[i]
            ustr = candidate.decode('UTF-16')
            print(f'\tHit success bbl {scount} times with: "{ustr[:scount]}"')
            todo.append(bytes(candidate))  # Put it back in the todo list
            max_scount = scount
    return False  # This ends execution
Beispiel #14
0
 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.encode())
         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
Beispiel #15
0
    def emul(self, lifter, ctx=None, step=False):
        # Init
        ctx_init = {}
        if ctx is not None:
            ctx_init.update(ctx)
        solver = z3.Solver()
        symb_exec = SymbolicExecutionEngine(lifter, ctx_init)
        history = self.history[::-1]
        history_size = len(history)
        translator = Translator.to_language("z3")
        size = self._ircfg.IRDst.size

        for hist_nb, loc_key in enumerate(history, 1):
            if hist_nb == history_size and loc_key == self.initial_state.loc_key:
                line_nb = self.initial_state.line_nb
            else:
                line_nb = None
            irb = self.irblock_slice(self._ircfg.blocks[loc_key], line_nb)

            # Emul the block and get back destination
            dst = symb_exec.eval_updt_irblock(irb, step=step)

            # Add constraint
            if hist_nb < history_size:
                next_loc_key = history[hist_nb]
                expected = symb_exec.eval_expr(ExprLoc(next_loc_key, size))
                solver.add(
                    self._gen_path_constraints(translator, dst, expected))
        # Save the solver
        self._solver = solver

        # Return only inputs values (others could be wrongs)
        return {
            element: symb_exec.eval_expr(element)
            for element in self.inputs
        }
Beispiel #16
0
def analyse_function():
    # Get settings
    settings = TypePropagationForm()
    ret = settings.Execute()
    if not ret:
        return

    end = None
    if settings.cScope.value == 0:
        addr = settings.functionAddr.value
    else:
        addr = settings.startAddr.value
        if settings.cScope.value == 2:
            end = settings.endAddr

    # Init
    machine = guess_machine(addr=addr)
    mn, dis_engine, lifter_model_call = machine.mn, machine.dis_engine, machine.lifter_model_call

    bs = bin_stream_ida()
    loc_db = LocationDB()

    mdis = dis_engine(bs, loc_db=loc_db, dont_dis_nulstart_bloc=True)
    if end is not None:
        mdis.dont_dis = [end]

    lifter_model_callCallStackFixer = get_lifter_model_call_call_fixer(
        lifter_model_call)
    lifter = lifter_model_callCallStackFixer(loc_db)

    asmcfg = mdis.dis_multiblock(addr)
    # Generate IR
    ircfg = lifter.new_ircfg_from_asmcfg(asmcfg)

    cst_propag_link = {}
    if settings.cUnalias.value:
        init_infos = {lifter.sp: lifter.arch.regs.regs_init[lifter.sp]}
        cst_propag_link = propagate_cst_expr(lifter, ircfg, addr, init_infos)

    types_mngr = get_types_mngr(settings.headerFile.value, settings.arch.value)
    mychandler = MyCHandler(types_mngr, {})
    infos_types = {}
    infos_types_raw = []

    if settings.cTypeFile.value:
        infos_types_raw = open(settings.typeFile.value).read().split('\n')
    else:
        infos_types_raw = settings.strTypesInfo.value.split('\n')

    for line in infos_types_raw:
        if not line:
            continue
        expr_str, ctype_str = line.split(':')
        expr_str, ctype_str = expr_str.strip(), ctype_str.strip()
        expr = str_to_expr(expr_str)
        ast = mychandler.types_mngr.types_ast.parse_c_type(ctype_str)
        ctype = mychandler.types_mngr.types_ast.ast_parse_declaration(
            ast.ext[0])
        objc = types_mngr.get_objc(ctype)
        print('=' * 20)
        print(expr, objc)
        infos_types[expr] = set([objc])

    # Add fake head
    lbl_real_start = loc_db.get_offset_location(addr)
    lbl_head = loc_db.get_or_create_name_location("start")

    first_block = asmcfg.loc_key_to_block(lbl_real_start)

    assignblk_head = AssignBlock([
        ExprAssign(lifter.IRDst, ExprLoc(lbl_real_start, lifter.IRDst.size)),
        ExprAssign(lifter.sp, lifter.arch.regs.regs_init[lifter.sp])
    ], first_block.lines[0])
    irb_head = IRBlock(loc_db, lbl_head, [assignblk_head])
    ircfg.blocks[lbl_head] = irb_head
    ircfg.add_uniq_edge(lbl_head, lbl_real_start)

    state = TypePropagationEngine.StateEngine(infos_types)
    states = {lbl_head: state}
    todo = set([lbl_head])
    done = set()

    while todo:
        lbl = todo.pop()
        state = states[lbl]
        if (lbl, state) in done:
            continue
        done.add((lbl, state))
        if lbl not in ircfg.blocks:
            continue
        symbexec_engine = TypePropagationEngine(lifter, types_mngr, state)
        symbexec_engine.run_block_at(ircfg, lbl)
        symbexec_engine.del_mem_above_stack(lifter.sp)

        sons = ircfg.successors(lbl)
        for son in sons:
            add_state(ircfg, todo, states, son, symbexec_engine.get_state())

    for lbl, state in viewitems(states):
        if lbl not in ircfg.blocks:
            continue
        symbexec_engine = CTypeEngineFixer(lifter, types_mngr, state,
                                           cst_propag_link)
        symbexec_engine.run_block_at(ircfg, lbl)
        symbexec_engine.del_mem_above_stack(lifter.sp)
Beispiel #17
0
        def myfunc(cpu):
            """Execute the function according to cpu and vmmngr states
            @cpu: JitCpu instance
            """
            # Get virtual memory handler
            vmmngr = cpu.vmmngr

            # Get execution engine (EmulatedSymbExec instance)
            exec_engine = self.symbexec

            # Refresh CPU values according to @cpu instance
            exec_engine.update_engine_from_cpu()

            # Get initial loc_key
            cur_loc_key = asmblock.loc_key

            # Update PC helper
            update_pc = lambda value: setattr(cpu, self.ir_arch.pc.name, value)

            while True:
                # Retrieve the expected irblock
                for instr, irblocks in zip(asmblock.lines, irblocks_list):
                    for index, irblock in enumerate(irblocks):
                        if irblock.loc_key == cur_loc_key:
                            break
                    else:
                        continue
                    break
                else:
                    raise RuntimeError("Unable to find the block for %r" % cur_loc_key)

                instr_attrib, irblocks_attributes = codegen.get_attributes(
                    instr, irblocks, self.log_mn, self.log_regs
                )
                irblock_attributes = irblocks_attributes[index]

                # Do IRBlock
                new_irblock = self.ir_arch.irbloc_fix_regs_for_mode(
                    irblock, self.ir_arch.attrib
                )
                if index == 0:
                    # Pre code
                    if instr_attrib.log_mn:
                        print("%.8X %s" % (
                            instr_attrib.instr.offset,
                            instr_attrib.instr.to_string(loc_db)
                        ))

                # Exec IRBlock
                instr = instr_attrib.instr

                for index, assignblk in enumerate(irblock):
                    attributes = irblock_attributes[index]

                    # Eval current instruction (in IR)
                    exec_engine.eval_updt_assignblk(assignblk)

                    # Check memory access / write exception
                    # TODO: insert a check between memory reads and writes
                    if attributes.mem_read or attributes.mem_write:
                        # Restricted exception
                        flag = ~csts.EXCEPT_CODE_AUTOMOD & csts.EXCEPT_DO_NOT_UPDATE_PC
                        if (vmmngr.get_exception() & flag != 0):
                            # Do not update registers
                            update_pc(instr.offset)
                            return instr.offset

                    # Update registers values
                    exec_engine.update_cpu_from_engine()

                    # Check post assignblk exception flags
                    if attributes.set_exception:
                        # Restricted exception
                        if cpu.get_exception() > csts.EXCEPT_NUM_UPDT_EIP:
                            # Update PC
                            update_pc(instr.offset)
                            return instr.offset

                dst = exec_engine.eval_expr(self.ir_arch.IRDst)
                if dst.is_int():
                    loc_key = loc_db.get_or_create_offset_location(int(dst))
                    dst = ExprLoc(loc_key, dst.size)

                assert dst.is_loc()
                loc_key = dst.loc_key
                offset = loc_db.get_location_offset(loc_key)
                if offset is None:
                    # Avoid checks on generated label
                    cur_loc_key = loc_key
                    continue

                if instr_attrib.log_regs:
                    update_pc(offset)
                    cpu.dump_gpregs_with_attrib(self.ir_arch.attrib)

                # Post-instr checks
                if instr_attrib.mem_read | instr_attrib.mem_write:
                    vmmngr.check_memory_breakpoint()
                    vmmngr.check_invalid_code_blocs()
                    if vmmngr.get_exception():
                        update_pc(offset)
                        return offset

                if instr_attrib.set_exception:
                    if cpu.get_exception():
                        update_pc(offset)
                        return offset

                if instr_attrib.mem_read | instr_attrib.mem_write:
                    vmmngr.reset_memory_access()

                # Manage resulting address
                if (loc_key in local_loc_keys and
                    offset > instr.offset):
                    # Forward local jump
                    # Note: a backward local jump has to be promoted to extern,
                    # for max_exec_per_call support
                    cur_loc_key = loc_key
                    continue

                # Delay slot
                if has_delayslot:
                    delay_slot_set = exec_engine.eval_expr(codegen.delay_slot_set)
                    if delay_slot_set.is_int() and int(delay_slot_set) != 0:
                        return int(exec_engine.eval_expr(codegen.delay_slot_dst))

                # Extern of asmblock, must have an offset
                assert offset is not None
                return offset
Beispiel #18
0
from __future__ import print_function
from miasm.expression.parser import str_to_expr
from miasm.expression.expression import ExprInt, ExprId, ExprSlice, ExprMem, \
    ExprCond, ExprCompose, ExprOp, ExprAssign, ExprLoc, LocKey

for expr_test in [ExprInt(0x12, 32),
                  ExprId('test', 32),
                  ExprLoc(LocKey(12), 32),
                  ExprSlice(ExprInt(0x10, 32), 0, 8),
                  ExprMem(ExprInt(0x10, 32), 32),
                  ExprCond(ExprInt(0x10, 32), ExprInt(0x11, 32), ExprInt(0x12, 32)),
                  ExprCompose(ExprInt(0x10, 16), ExprInt(0x11, 8), ExprInt(0x12, 8)),
                  ExprInt(0x11, 8) + ExprInt(0x12, 8),
                  ExprAssign(ExprId('EAX', 32),  ExprInt(0x12, 32)),
                  ]:

    print('Test: %s' % expr_test)
    assert str_to_expr(repr(expr_test)) == expr_test
Beispiel #19
0
def blr(arg1):
    PC = arg1
    ir.IRDst = arg1
    LR = ExprLoc(ir.get_next_loc_key(instr), 64)
Beispiel #20
0
def b_lt(arg1):
    cond = cond2expr['LT']
    dst = arg1 if cond else ExprLoc(ir.get_next_loc_key(instr), 64)
    PC = dst
    ir.IRDst = dst
Beispiel #21
0
def tbnz(arg1, arg2, arg3):
    bitmask = ExprInt(1, arg1.size) << arg2
    dst = arg3 if arg1 & bitmask else ExprLoc(ir.get_next_loc_key(instr), 64)
    PC = dst
    ir.IRDst = dst
Beispiel #22
0
def cbnz(arg1, arg2):
    dst = arg2 if arg1 else ExprLoc(ir.get_next_loc_key(instr), 64)
    PC = dst
    ir.IRDst = dst
Beispiel #23
0
def cbz(arg1, arg2):
    dst = ExprLoc(ir.get_next_loc_key(instr), 64) if arg1 else arg2
    PC = dst
    ir.IRDst = dst
        "test_s64_greater",
        "test_s64_greater_or_equal",
        "test_s64_lesser",
        "test_s64_lesser_or_equal",
        "test_u64_greater",
        "test_u64_greater_or_equal",
        "test_u64_lesser",
        "test_u64_lesser_or_equal",
    ]:
        head = mdis.loc_db.get_name_location(func_name)
        addr = mdis.loc_db.get_location_offset(head)
        asmcfg = mdis.dis_multiblock(addr)

        ircfg = lifter.new_ircfg_from_asmcfg(asmcfg)
        # Add fake head
        dct = {lifter.IRDst: ExprLoc(head, lifter.IRDst.size)}
        dct.update(args_x86_32)
        dct.update(args_x86_64)
        dct.update(args_arm)
        dct.update(args_aarch64)
        dct.update(args_mips32)

        assignblk = AssignBlock(dct, None)
        irblock = IRBlock(loc_db, fake_head, [assignblk])
        # print(irblock)
        ircfg.add_irblock(irblock)

        open("ircfg_%s.dot" % func_name, "w").write(ircfg.dot())

        simplifier = IRCFGSimplifierSSA(lifter)
Beispiel #25
0
def parse_loc_key(t):
    assert len(t) == 2
    loc_key, size = LocKey(t[0]), t[1]
    return ExprLoc(loc_key, size)
Beispiel #26
0
            irs.append(AssignBlock(exprs))

    irbl = IRBlock(loc_db, label, irs)
    return irbl


############# Tests #############
IRA = IRATest(loc_db)

########## G1 ##########
# Input
G1 = IRA.new_ircfg()

G1_IRB0 = gen_irblock(LBL0, [[
    ExprAssign(B, C),
    ExprAssign(IRDst, ExprLoc(LBL1, 32)),
]])

G1_IRB1 = gen_irblock(LBL1, [[
    ExprAssign(IRDst, ExprLoc(LBL2, 32)),
]])

G1_IRB2 = gen_irblock(LBL2, [[
    ExprAssign(A, B),
    ExprAssign(IRDst, C),
]])

for irb in [G1_IRB0, G1_IRB1, G1_IRB2]:
    G1.add_irblock(irb)

# Result
Beispiel #27
0
        for assignblk in xx:
            for dst in assignblk:
                if str(dst).startswith("r"):
                    out.add(dst)
        """
        out.add(r)
        return out


IRA = IRATest(loc_db)
END = ExprId("END", IRDst.size)

G0_IRA = IRA.new_ircfg()

G0_IRB0 = gen_irblock(
    LBL0, [[ExprAssign(a, CST1)], [ExprAssign(IRDst, ExprLoc(LBL1, 32))]])
G0_IRB1 = gen_irblock(
    LBL1,
    [[ExprAssign(a, a + CST1)],
     [ExprAssign(IRDst, ExprCond(x, ExprLoc(LBL1, 32), ExprLoc(LBL2, 32)))]])
G0_IRB2 = gen_irblock(LBL2, [[ExprAssign(r, a)], [ExprAssign(IRDst, END)]])

for irb in [G0_IRB0, G0_IRB1, G0_IRB2]:
    G0_IRA.add_irblock(irb)

G1_IRA = IRA.new_ircfg()

G1_IRB0 = gen_irblock(
    LBL0,
    [[ExprAssign(a, CST1)],
     [ExprAssign(IRDst, ExprCond(x, ExprLoc(LBL1, 32), ExprLoc(LBL2, 32)))]])
Beispiel #28
0
        machine.mn, 32, '''
    init:
    PUSH argv
    PUSH argc
    PUSH ret_addr
    ''',
        loc_db
    )


    argc_lbl = loc_db.get_name_location('argc')
    argv_lbl = loc_db.get_name_location('argv')
    ret_addr_lbl = loc_db.get_name_location('ret_addr')
    init_lbl = loc_db.get_name_location('init')

    argc_loc = ExprLoc(argc_lbl, 32)
    argv_loc = ExprLoc(argv_lbl, 32)
    ret_addr_loc = ExprLoc(ret_addr_lbl, 32)


    ret_addr = ExprId("ret_addr", ret_addr_loc.size)

    fix_args = {
        argc_loc: ExprId("argc", argc_loc.size),
        argv_loc: ExprId("argv", argv_loc.size),
        ret_addr_loc: ret_addr,
    }



    block = asmcfg.loc_key_to_block(init_lbl)
Beispiel #29
0
        for assignblk in xx:
            for dst in assignblk:
                if str(dst).startswith("r"):
                    out.add(dst)
        """
        out.add(r)
        return out

IRA = IRATest(loc_db)
END = ExprId("END", IRDst.size)

G0_IRA = IRA.new_ircfg()

G0_IRB0 = gen_irblock(LBL0, [
    [ExprAssign(a, CST1)],
    [ExprAssign(IRDst, ExprLoc(LBL1, 32))]
])
G0_IRB1 = gen_irblock(LBL1, [
    [ExprAssign(a, a+CST1)],
    [ExprAssign(IRDst, ExprCond(x,
                                ExprLoc(LBL1, 32),
                                ExprLoc(LBL2, 32)
                                )
    )]
])
G0_IRB2 = gen_irblock(LBL2, [
    [ExprAssign(r, a)],
    [ExprAssign(IRDst, END)]
])

for irb in [G0_IRB0, G0_IRB1, G0_IRB2]:
Beispiel #30
0
DNA = DependencyNode(LBL2, A, 0)
DNB = DependencyNode(LBL1, B, 1)
DNC = DependencyNode(LBL1, C, 0)
DNB2 = DependencyNode(LBL1, B, 1)
DNC2 = DependencyNode(LBL1, C, 0)
DNB3 = DependencyNode(LBL1, B, 1)
DNC3 = DependencyNode(LBL1, C, 0)

IRA = IRATest(loc_db)
IRDst = IRA.IRDst
END = ExprId("END", IRDst.size)
# graph 1

G1_IRA = IRA.new_ircfg()

G1_IRB0 = gen_irblock(LBL0, [[ExprAssign(C, CST1), ExprAssign(IRDst, ExprLoc(LBL1, 32))]])
G1_IRB1 = gen_irblock(LBL1, [[ExprAssign(B, C), ExprAssign(IRDst, ExprLoc(LBL2, 32))]])
G1_IRB2 = gen_irblock(LBL2, [[ExprAssign(A, B), ExprAssign(IRDst, END)]])

for irb in [G1_IRB0, G1_IRB1, G1_IRB2]:
    G1_IRA.add_irblock(irb)

# graph 2

G2_IRA = IRA.new_ircfg()

G2_IRB0 = gen_irblock(LBL0, [[ExprAssign(C, CST1), ExprAssign(IRDst, ExprLoc(LBL1, 32))]])
G2_IRB1 = gen_irblock(LBL1, [[ExprAssign(B, CST2), ExprAssign(IRDst, ExprLoc(LBL2, 32))]])
G2_IRB2 = gen_irblock(LBL2, [[ExprAssign(A, B + C), ExprAssign(IRDst, END)]])

for irb in [G2_IRB0, G2_IRB1, G2_IRB2]: