Exemple #1
0
def udiv(ir, instr, a, b, c=None):
    e = []
    if c is None:
        b, c = a, b

    loc_div = ExprLoc(ir.loc_db.add_location(), ir.IRDst.size)
    loc_except = 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(c, loc_div, loc_except)))

    do_except = []
    do_except.append(
        ExprAssign(exception_flags,
                   ExprInt(EXCEPT_DIV_BY_ZERO, exception_flags.size)))
    do_except.append(ExprAssign(ir.IRDst, loc_next))
    blk_except = IRBlock(loc_except.loc_key, [AssignBlock(do_except, instr)])

    r = ExprOp("udiv", b, c)
    do_div = []
    do_div.append(ExprAssign(a, r))
    dst = get_dst(a)
    if dst is not None:
        do_div.append(ExprAssign(ir.IRDst, r))

    do_div.append(ExprAssign(ir.IRDst, loc_next))
    blk_div = IRBlock(loc_div.loc_key, [AssignBlock(do_div, instr)])

    return e, [blk_div, blk_except]
Exemple #2
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)
Exemple #3
0
    def eval_updt_irblock(self, irb, step=False):
        """
        Symbolic execution of the @irb on the current state
        @irb: IRBlock instance
        @step: display intermediate steps
        """
        assignblks = []
        for index, assignblk in enumerate(irb):
            new_assignblk = {}
            links = {}
            for dst, src in viewitems(assignblk):
                src = self.propag_expr_cst(src)
                if dst.is_mem():
                    ptr = dst.ptr
                    ptr = self.propag_expr_cst(ptr)
                    dst = ExprMem(ptr, dst.size)
                new_assignblk[dst] = src

            if assignblk.instr is not None:
                for arg in assignblk.instr.args:
                    new_arg = self.propag_expr_cst(arg)
                    links[new_arg] = arg
                self.cst_propag_link[(irb.loc_key, index)] = links

            self.eval_updt_assignblk(assignblk)
            assignblks.append(AssignBlock(new_assignblk, assignblk.instr))
        self.ircfg.blocks[irb.loc_key] = IRBlock(irb.loc_key, assignblks)
Exemple #4
0
def add_condition_expr(ir, instr, cond, instr_ir, extra_ir):
    if cond == COND_AL:
        return instr_ir, extra_ir
    if not cond in tab_cond:
        raise ValueError('unknown condition %r' % cond)
    cond = tab_cond[cond]

    loc_next = ir.get_next_loc_key(instr)
    loc_next_expr = ExprLoc(loc_next, 32)
    loc_do = ir.loc_db.add_location()
    loc_do_expr = ExprLoc(loc_do, 32)

    dst_cond = ExprCond(cond, loc_do_expr, loc_next_expr)
    assert (isinstance(instr_ir, list))

    has_irdst = False
    for e in instr_ir:
        if e.dst == ir.IRDst:
            has_irdst = True
            break
    if not has_irdst:
        instr_ir.append(ExprAssign(ir.IRDst, loc_next_expr))
    e_do = IRBlock(loc_do, [AssignBlock(instr_ir, instr)])
    e = [ExprAssign(ir.IRDst, dst_cond)]
    return e, [e_do] + extra_ir
Exemple #5
0
    def _recog_init(self, merging_var_candidates):
        # recognize cff loops and initiate deobfuscation
        self._merging_var_candidates = merging_var_candidates
        self.ircfg = self.ir_arch.new_ircfg_from_asmcfg(self.asmcfg)
        self.asmcfg.rebuild_edges()

        # TODO put constant propagation here when fixed in Miasm
        # simp = IRCFGSimplifierSSA(self.ir_arch)
        # from datetime import datetime
        # startTime = datetime.now()
        # ssa = simp.ircfg_to_ssa(self.ircfg, LocKey(0))
        # simp.do_propagate_expressions(ssa, LocKey(0))
        # self.ircfg = simp.ssa_to_unssa(ssa, LocKey(0))
        # print(datetime.now() - startTime)

        # init_infos = self.ir_arch.arch.regs.regs_init
        # cst_propag_link = cst_prop.propagate_cst_expr(self.ir_arch, self.ircfg, self.asmcfg.func_addr, init_infos)

        # raise Exception("test")

        self._normalize_ircfg(self.conn)
        irb_bak = None
        if merging_var_candidates:
            self.pad = True
            new_line = AssignBlock([ExprAssign(k, k) for k in merging_var_candidates])
            irb_bak = self.ircfg.blocks[LocKey(0)]
            new_irb = IRBlock(LocKey(0), tuple([new_line, *self.ircfg.blocks[LocKey(0)].assignblks]))
            self.ircfg.blocks[LocKey(0)] = new_irb

        self.analyses = Analyses(self.ircfg, self.asmcfg)
        return irb_bak
Exemple #6
0
    def emul(self, lifter, ctx=None, step=False):
        """Symbolic execution of relevant nodes according to the history
        Return the values of inputs nodes' elements
        @lifter: Lifter instance
        @ctx: (optional) Initial context as dictionary
        @step: (optional) Verbose execution
        Warning: The emulation is not sound if the inputs nodes depend on loop
        variant.
        """
        # Init
        ctx_init = {}
        if ctx is not None:
            ctx_init.update(ctx)
        assignblks = []

        # Build a single assignment 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._ircfg.blocks[loc_key],
                                             line_nb).assignblks

        # Eval the block
        loc_db = lifter.loc_db
        temp_loc = loc_db.get_or_create_name_location("Temp")
        symb_exec = SymbolicExecutionEngine(lifter, ctx_init)
        symb_exec.eval_updt_irblock(IRBlock(loc_db, temp_loc, assignblks),
                                    step=step)

        # Return only inputs values (others could be wrongs)
        return {element: symb_exec.symbols[element] for element in self.inputs}
Exemple #7
0
    def block2assignblks(self, block):
        irblocks_list = super(mipsCGen, self).block2assignblks(block)
        for irblocks in irblocks_list:
            for blk_idx, irblock in enumerate(irblocks):
                has_breakflow = any(assignblock.instr.breakflow()
                                    for assignblock in irblock)
                if not has_breakflow:
                    continue

                irs = []
                for assignblock in irblock:
                    if self.ir_arch.pc not in assignblock:
                        irs.append(AssignBlock(assignments, assignblock.instr))
                        continue
                    assignments = dict(assignblock)
                    # Add internal branch destination
                    assignments[self.delay_slot_dst] = assignblock[
                        self.ir_arch.pc]
                    assignments[self.delay_slot_set] = m2_expr.ExprInt(1, 32)
                    # Replace IRDst with next instruction
                    dst_loc_key = self.ir_arch.get_next_instr(
                        assignblock.instr)
                    assignments[self.ir_arch.IRDst] = m2_expr.ExprLoc(
                        dst_loc_key, 32)
                    irs.append(AssignBlock(assignments, assignblock.instr))
                irblocks[blk_idx] = IRBlock(irblock.loc_key, irs)

        return irblocks_list
Exemple #8
0
    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 index, instr in enumerate(block.lines):
            if loc_key is None:
                assignments = []
                loc_key = self.get_loc_key_for_instr(instr)
            if instr.is_subcall():
                assert index == len(block.lines) - 2

                # Add last instruction first (before call)
                split = self.add_instr_to_current_state(
                    block.lines[-1], block, assignments,
                    ir_blocks_all, gen_pc_updt
                )
                assert not split
                # Add call effects after the delay splot
                split = self.add_instr_to_current_state(
                    instr, block, assignments,
                    ir_blocks_all, gen_pc_updt
                )
                assert split
                break
            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
Exemple #9
0
def gen_irblock(label, exprs_list):
    irs = []
    for exprs in exprs_list:
        if isinstance(exprs, AssignBlock):
            irs.append(exprs)
        else:
            irs.append(AssignBlock(exprs))

    irbl = IRBlock(loc_db, label, irs)
    return irbl
Exemple #10
0
    def process(self, pending, merging_val, reached_funcs):
        if len(self.flat_loops) == 0:
            # add all reached functions
            for func_addr, possible_merge_vars, loc_key in self.possible_merge_funcs:
                reached_funcs.add(func_addr)
                for expr, val in possible_merge_vars:
                    pending.setdefault(func_addr,
                                       {}).setdefault(expr, set()).add(val)
            return None

        assert len(self.asmcfg.heads()) == 1

        # add merging var to the ircfg
        if self.pad:
            initial_block_bak = self.ircfg.blocks[LocKey(0)]
            if merging_val and self.merging_var:
                asgn_blk = AssignBlock(
                    [ExprAssign(self.merging_var, merging_val)])
            else:
                asgn_blk = AssignBlock()
            assignblks = tuple(
                [asgn_blk, *self.ircfg.blocks[LocKey(0)].assignblks])
            self.ircfg.blocks[LocKey(0)] = IRBlock(LocKey(0), assignblks)

        head = self.asmcfg.heads()[0]
        head_block = self.asmcfg.loc_key_to_block(head)
        new_head = self._deobfuscate_cff_loops(
            head_block, self.asmcfg.machine.mn.regs.regs_init)

        if self.pad:
            self.ircfg.blocks[LocKey(0)] = initial_block_bak
            if merging_val and self.merging_var:
                mode = self.asmcfg.mode
                fix_dct = {
                    self.asmcfg.machine.mn.regs.regs_init[self.ir_arch.sp]:
                    self.ir_arch.sp
                }
                mov = instruction_x86(
                    "MOV", mode,
                    [self.merging_var.replace_expr(fix_dct), merging_val])
                mov.additional_info = additional_info()
                mov.additional_info.g1.value = 0
                self.out_asmcfg.loc_key_to_block(LocKey(0)).lines.insert(
                    0, mov)

        loc_keys = self.relevant_nodes
        for func_addr, possible_merge_vars, loc_key in self.possible_merge_funcs:
            if loc_key in loc_keys:
                reached_funcs.add(func_addr)
                for expr, val in possible_merge_vars:
                    pending.setdefault(func_addr,
                                       {}).setdefault(expr, set()).add(val)

        return new_head
Exemple #11
0
    def insert_parallel_copy(self):
        """
        Naive Out-of-SSA from CSSA (without coalescing for now)
        - Replace Phi
        - Create room for parallel copies in Phi's parents
        """
        ircfg = self.ssa.graph

        for irblock in list(viewvalues(ircfg.blocks)):
            if not irblock_has_phi(irblock):
                continue

            # Replace Phi with Phi's dst = new_var
            parallel_copies = {}
            for dst in self.phi_destinations[irblock.loc_key]:
                new_var = self.phi_new_var[dst]
                parallel_copies[dst] = new_var

            assignblks = list(irblock)
            assignblks[0] = AssignBlock(parallel_copies, irblock[0].instr)
            new_irblock = IRBlock(irblock.loc_db, irblock.loc_key, assignblks)
            ircfg.blocks[irblock.loc_key] = new_irblock

            # Insert new_var = src in each Phi's parent, at the end of the block
            parent_to_parallel_copies = {}
            parallel_copies = {}
            for dst in irblock[0]:
                new_var = self.phi_new_var[dst]
                for parent, src in self.phi_parent_sources[dst]:
                    parent_to_parallel_copies.setdefault(parent,
                                                         {})[new_var] = src

            for parent, parallel_copies in viewitems(
                    parent_to_parallel_copies):
                parent = ircfg.blocks[parent]
                assignblks = list(parent)
                assignblks.append(
                    AssignBlock(parallel_copies, parent[-1].instr))
                new_irblock = IRBlock(parent.loc_db, parent.loc_key,
                                      assignblks)
                ircfg.blocks[parent.loc_key] = new_irblock
Exemple #12
0
    def add_asmblock_to_ircfg(self, block, ircfg, gen_pc_updt=False):
        """
        Add a native block to the current IR
        @block: native assembly block
        @gen_pc_updt: insert PC update effects between instructions
        """

        it_hints = None
        it_cond = None
        label = block.loc_key
        assignments = []
        ir_blocks_all = []
        index = -1
        while index + 1 < len(block.lines):
            index += 1
            instr = block.lines[index]
            if label is None:
                assignments = []
                label = self.get_loc_key_for_instr(instr)
            if instr.name.startswith("IT"):
                index, irblocks_it = self.do_it_block(label, index, block,
                                                      assignments, gen_pc_updt)
                for irblocks in irblocks_it:
                    ir_blocks_all += irblocks
                label = None
                continue

            split = self.add_instr_to_current_state(instr, block, assignments,
                                                    ir_blocks_all, gen_pc_updt)
            if split:
                ir_blocks_all.append(IRBlock(label, assignments))
                label = None
                assignments = []
        if label is not None:
            ir_blocks_all.append(IRBlock(label, 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
Exemple #13
0
 def _convert_phi(self):
     """Inserts corresponding phi functions inplace
     into IRBlock at the beginning"""
     for loc_key in self._phinodes:
         irblock = self.get_block(loc_key)
         if irblock is None:
             continue
         assignblk = AssignBlock(self._phinodes[loc_key])
         if irblock_has_phi(irblock):
             # If first block contains phi, we are updating an existing ssa form
             # so update phi
             assignblks = list(irblock.assignblks)
             out = dict(assignblks[0])
             out.update(dict(assignblk))
             assignblks[0] = AssignBlock(out, assignblk.instr)
             new_irblock = IRBlock(self.ircfg.loc_db, loc_key, assignblks)
         else:
             # insert at the beginning
             new_irblock = IRBlock(self.ircfg.loc_db, loc_key,
                                   [assignblk] + list(irblock.assignblks))
         self.ircfg.blocks[loc_key] = new_irblock
Exemple #14
0
def gen_irblock(label, exprs_list):
    """ Returns an IRBlock.
    Used only for tests purpose
    """
    irs = []
    for exprs in exprs_list:
        if isinstance(exprs, AssignBlock):
            irs.append(exprs)
        else:
            irs.append(AssignBlock(exprs))

    irbl = IRBlock(loc_db, label, irs)
    return irbl
Exemple #15
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]
Exemple #16
0
def custom_add_asmblock_to_ircfg(self,
                                 block,
                                 ircfg,
                                 gen_pc_updt=False,
                                 asmcfg=None):
    """
    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 = []
    self.asm_block = block
    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
            if len(assignments) != len(block.lines) and asmcfg:
                new_block = block.split(asmcfg.loc_db, self.split_offset)
                self.new_blocks.append(new_block)
                break
            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
Exemple #17
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)
Exemple #18
0
def add_out_reg_end(ir_arch_a, ircfg_a):
    # Add dummy dependency to uncover out regs affectation
    for loc in ircfg_a.leaves():
        irblock = ircfg_a.blocks.get(loc)
        if irblock is None:
            continue
        regs = {}
        for reg in ir_arch_a.get_out_regs(irblock):
            regs[reg] = reg
        assignblks = list(irblock)
        new_assiblk = AssignBlock(regs, assignblks[-1].instr)
        assignblks.append(new_assiblk)
        new_irblock = IRBlock(loc_db, irblock.loc_key, assignblks)
        ircfg_a.blocks[loc] = new_irblock
Exemple #19
0
 def remove_assign_eq(self):
     """
     Remove trivial expressions (a=a) in the current graph
     """
     for irblock in list(viewvalues(self.ssa.graph.blocks)):
         assignblks = list(irblock)
         for i, assignblk in enumerate(assignblks):
             out = {}
             for dst, src in viewitems(assignblk):
                 if dst == src:
                     continue
                 out[dst] = src
             assignblks[i] = AssignBlock(out, assignblk.instr)
         self.ssa.graph.blocks[irblock.loc_key] = IRBlock(
             irblock.loc_db, irblock.loc_key, assignblks)
Exemple #20
0
 def addIRBlock(self, newIRCFG, state, lockey):
     assignBlocks = []
     lastAssign = None
     lastIndex = None
     for dst, src in state.items():
         newAssign = AssignBlock({dst: src})
         if dst == newIRCFG._irdst:
             lastAssign = newAssign
             lastIndex = len(assignBlocks)
         assignBlocks.append(newAssign)
     tmp = assignBlocks[-1]
     assignBlocks[-1] = lastAssign
     assignBlocks[lastIndex] = tmp
     newIRBlock = IRBlock(lockey, assignBlocks)
     newIRCFG.add_irblock(newIRBlock)
     return newIRBlock
Exemple #21
0
 def simplify(self):
     simplifier = IRCFGSimplifierCommon(self.custom_ira1)
     simplifier.simplify(self.ircfg, self.head)
     for loc in self.ircfg.leaves():
         irblock = self.ircfg.blocks.get(loc)
         if irblock is None:
             continue
         regs = {}
         for reg in self.custom_ira1.get_out_regs(irblock):
             regs[reg] = reg
         assignblks = list(irblock)
         newAssignBlk = AssignBlock(regs, assignblks[-1].instr)
         assignblks.append(newAssignBlk)
         newIrBlock = IRBlock(irblock.loc_key, assignblks)
         self.ircfg.blocks[loc] = newIrBlock
     simplifier = CustomIRCFGSimplifierSSA(self.custom_ira2)
     simplifier.simplify(self.ircfg, self.head)
Exemple #22
0
    def remove_phi(self):
        """
        Remove phi operators in @ifcfg
        @ircfg: IRDiGraph instance
        """

        for irblock in list(viewvalues(self.ssa.graph.blocks)):
            assignblks = list(irblock)
            out = {}
            for dst, src in viewitems(assignblks[0]):
                if src.is_op('Phi'):
                    assert set([dst]) == set(src.args)
                    continue
                out[dst] = src
            assignblks[0] = AssignBlock(out, assignblks[0].instr)
            self.ssa.graph.blocks[irblock.loc_key] = IRBlock(
                irblock.loc_db, irblock.loc_key, assignblks)
Exemple #23
0
    def _fix_no_def_var(self, head):
        """
        Replace phi source variables which are not ssa vars by ssa vars.
        @head: loc_key of the graph head
        """
        var_to_insert = set()
        for loc_key in self._phinodes:
            for dst, sources in viewitems(self._phinodes[loc_key]):
                for src in sources.args:
                    if src in self.ssa_variable_to_expr:
                        continue
                    var_to_insert.add(src)
        var_to_newname = {}
        newname_to_var = {}
        for var in var_to_insert:
            new_var = self._transform_var_lhs(var)
            var_to_newname[var] = new_var
            newname_to_var[new_var] = var

        # Replace non modified node used in phi with new variable
        self.ircfg.simplify(lambda expr: expr.replace_expr(var_to_newname))

        if newname_to_var:
            irblock = self.ircfg.blocks[head]
            assignblks = list(irblock)
            assignblks[0:0] = [
                AssignBlock(newname_to_var, assignblks[0].instr)
            ]
            self.ircfg.blocks[head] = IRBlock(self.ircfg.loc_db, head,
                                              assignblks)

        # Updt structure
        for loc_key in self._phinodes:
            for dst, sources in viewitems(self._phinodes[loc_key]):
                self._phinodes[loc_key][dst] = sources.replace_expr(
                    var_to_newname)

        for var, (loc_key, index) in list(viewitems(self.ssa_to_location)):
            if loc_key == head:
                self.ssa_to_location[var] = loc_key, index + 1

        for newname, var in viewitems(newname_to_var):
            self.ssa_to_location[newname] = head, 0
            self.ssa_variable_to_expr[newname] = var
            self.expressions[newname] = var
Exemple #24
0
    def del_dst_zr(self, instr, instr_ir, extra_ir):
        "Writes to zero register are discarded"
        regs_to_fix = [WZR, XZR]
        instr_ir = [expr for expr in instr_ir if expr.dst not in regs_to_fix]

        new_irblocks = []
        for irblock in extra_ir:
            irs = []
            for assignblk in irblock:
                new_dsts = {
                    dst: src
                    for dst, src in viewitems(assignblk)
                    if dst not in regs_to_fix
                }
                irs.append(AssignBlock(new_dsts, assignblk.instr))
            new_irblocks.append(IRBlock(irblock.loc_key, irs))

        return instr_ir, new_irblocks
Exemple #25
0
    def irbloc_fix_regs_for_mode(self, irblock, mode=64):
        irs = []
        for assignblk in irblock:
            new_assignblk = dict(assignblk)
            for dst, src in viewitems(assignblk):
                del (new_assignblk[dst])
                # Special case for 64 bits:
                # If destination is a 32 bit reg, zero extend the 64 bit reg
                if (isinstance(dst, ExprId) and dst.size == 32
                        and dst in replace_regs):
                    src = src.zeroExtend(64)
                    dst = replace_regs[dst].arg

                dst = self.expr_fix_regs_for_mode(dst)
                src = self.expr_fix_regs_for_mode(src)
                new_assignblk[dst] = src
            irs.append(AssignBlock(new_assignblk, assignblk.instr))
        return IRBlock(irblock.loc_key, irs)
Exemple #26
0
 def _convert_block(irblock, ssa_list):
     """
     Transforms an IRBlock inplace into SSA
     :param irblock: IRBlock to be transformed
     :param ssa_list: list of SSA expressions
     """
     # iterator over SSA expressions
     ssa_iter = iter(ssa_list)
     new_irs = []
     # walk over IR blocks' assignblocks
     for assignblk in irblock.assignblks:
         # list of instructions
         instructions = []
         # insert SSA instructions
         for _ in assignblk:
             instructions.append(next(ssa_iter))
         # replace instructions of assignblock in IRBlock
         new_irs.append(AssignBlock(instructions, assignblk.instr))
     return IRBlock(irblock.loc_db, irblock.loc_key, new_irs)
Exemple #27
0
def tne(ir, instr, arg1, arg2):
    e = []

    loc_except, loc_except_expr = ir.gen_loc_key_and_expr(ir.IRDst.size)
    loc_next = ir.get_next_loc_key(instr)
    loc_next_expr = m2_expr.ExprLoc(loc_next, ir.IRDst.size)

    do_except = []
    do_except.append(m2_expr.ExprAssign(exception_flags, m2_expr.ExprInt(
        EXCEPT_DIV_BY_ZERO, exception_flags.size)))
    do_except.append(m2_expr.ExprAssign(ir.IRDst, loc_next_expr))
    blk_except = IRBlock(ir.loc_db, loc_except, [AssignBlock(do_except, instr)])

    cond = arg1 ^ arg2


    e = []
    e.append(m2_expr.ExprAssign(ir.IRDst,
                             m2_expr.ExprCond(cond, loc_next_expr, loc_except_expr)))

    return e, [blk_except]
Exemple #28
0
 def getMaxIRCFG(self):
     if self.maxIRCFG is not None:
         return self.maxIRCFG
     else:
         self.maxIRCFG = self.maxIRA1.new_ircfg_from_asmcfg(self.cfg)
         simplifier = IRCFGSimplifierCommon(self.maxIRA1)
         simplifier.simplify(self.maxIRCFG, self.head)
         for loc in self.maxIRCFG.leaves():
             irblock = self.maxIRCFG.blocks.get(loc)
             if irblock is None:
                 continue
             regs = {}
             for reg in self.maxIRA1.get_out_regs(irblock):
                 regs[reg] = reg
             assignblks = list(irblock)
             newAssignBlk = AssignBlock(regs, assignblks[-1].instr)
             assignblks.append(newAssignBlk)
             newIrBlock = IRBlock(irblock.loc_key, assignblks)
             self.maxIRCFG.blocks[loc] = newIrBlock
         simplifier = CustomIRCFGSimplifierSSA(self.maxIRA2)
         simplifier.simplify(self.maxIRCFG, self.head)
         self.maxDefUse = DiGraphDefUse(ReachingDefinitions(self.maxIRCFG))
         return self.maxIRCFG
Exemple #29
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]
Exemple #30
0
    def irblock_slice(self, irb, max_line=None):
        """Slice of the dependency nodes on the irblock @irb
        @irb: irbloc instance
        """

        assignblks = []
        line2elements = {}
        for depnode in self.relevant_nodes:
            if depnode.loc_key != irb.loc_key:
                continue
            line2elements.setdefault(depnode.line_nb,
                                     set()).add(depnode.element)

        for line_nb, elements in sorted(viewitems(line2elements)):
            if max_line is not None and line_nb >= max_line:
                break
            assignmnts = {}
            for element in elements:
                if element in irb[line_nb]:
                    # constants, loc_key, ... are not in destination
                    assignmnts[element] = irb[line_nb][element]
            assignblks.append(AssignBlock(assignmnts))

        return IRBlock(irb.loc_db, irb.loc_key, assignblks)