예제 #1
0
파일: sem.py 프로젝트: wl496928838/miasm
def sdiv(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 = ExprId(ir.loc_db.add_location(), ir.IRDst.size)
    loc_next = ExprLoc(ir.get_next_loc_key(instr), ir.IRDst.size)

    e.append(ExprAff(ir.IRDst, ExprCond(c, loc_div, loc_except)))

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

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

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

    return e, [blk_div, blk_except]
예제 #2
0
파일: ira.py 프로젝트: shuixi2013/miasm
    def post_add_bloc(self, block, ir_blocks):
        IntermediateRepresentation.post_add_bloc(self, block, ir_blocks)
        for irb in ir_blocks:
            pc_val = None
            lr_val = None
            for assignblk in irb.irs:
                pc_val = assignblk.get(self.arch.regs.PC, pc_val)
                lr_val = assignblk.get(self.arch.regs.RA, lr_val)

            if pc_val is None or lr_val is None:
                continue
            if not expr_is_int_or_label(lr_val):
                continue
            if expr_is_label(lr_val):
                lr_val = ExprInt32(lr_val.name.offset)

            line = block.lines[-2]
            if lr_val.arg != line.offset + 8:
                raise ValueError("Wrong arg")

            # CALL
            lbl = block.get_next()
            new_lbl = self.gen_label()
            irs = self.call_effects(pc_val, line)
            irs.append(AssignBlock([ExprAff(self.IRDst,
                                            ExprId(lbl, size=self.pc.size))]))
            nblock = IRBlock(new_lbl, irs)
            nblock.lines = [line] * len(irs)
            self.blocks[new_lbl] = nblock
            irb.dst = ExprId(new_lbl, size=self.pc.size)
예제 #3
0
파일: sem.py 프로젝트: litestar/miasm
def udiv(ir, instr, a, b, c=None):
    e = []
    if c is None:
        b, c = a, b

    lbl_div = ExprId(ir.gen_label(), ir.IRDst.size)
    lbl_except = ExprId(ir.gen_label(), ir.IRDst.size)
    lbl_next = ExprId(ir.get_next_label(instr), ir.IRDst.size)

    e.append(ExprAff(ir.IRDst, ExprCond(c, lbl_div, lbl_except)))

    do_except = []
    do_except.append(
        ExprAff(exception_flags,
                ExprInt(EXCEPT_DIV_BY_ZERO, exception_flags.size)))
    do_except.append(ExprAff(ir.IRDst, lbl_next))
    blk_except = IRBlock(lbl_except.name, [AssignBlock(do_except, instr)])

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

    do_div.append(ExprAff(ir.IRDst, lbl_next))
    blk_div = IRBlock(lbl_div.name, [AssignBlock(do_div, instr)])

    return e, [blk_div, blk_except]
예제 #4
0
    def do_it_block(self, label, index, block, assignments, gen_pc_updt):
        instr = block.lines[index]
        it_hints, it_cond = self.parse_itt(instr)
        cond_num = cond_dct_inv[it_cond.name]
        cond_eq = tab_cond[cond_num]

        # if not index + len(it_hints) <= len(block.lines):
        #     raise NotImplementedError("Splitted IT block non supported yet")

        ir_blocks_all = []

        # Gen dummy irblock for IT instr
        label_next = self.get_next_label(instr)
        dst = ExprAff(self.IRDst, ExprId(label_next, 32))
        dst_blk = AssignBlock([dst], instr)
        assignments.append(dst_blk)
        irblock = IRBlock(label, assignments)
        ir_blocks_all.append([irblock])

        label = label_next
        assignments = []
        if isinstance(it_hints, Iterable):
            for hint in it_hints:
                irblocks = []
                index += 1
                instr = block.lines[index]

                # Add conditionnal jump to current irblock
                label_do = self.symbol_pool.gen_label()
                label_next = self.get_next_label(instr)

                if hint:
                    local_cond = ~cond_eq
                else:
                    local_cond = cond_eq
                dst = ExprAff(self.IRDst, ExprCond(local_cond, ExprId(label_do, 32), ExprId(label_next, 32)))
                dst_blk = AssignBlock([dst], instr)
                assignments.append(dst_blk)
                irblock = IRBlock(label, assignments)

                irblocks.append(irblock)

                assignments = []
                label = label_do
                split = self.add_instr_to_irblock(block, instr, assignments,
                                                  irblocks, gen_pc_updt)

                # if split:
                #     raise NotImplementedError("Unsupported instr in IT block (%s)" % instr)


                dst = ExprAff(self.IRDst, ExprId(label_next, 32))
                dst_blk = AssignBlock([dst], instr)
                assignments.append(dst_blk)
                irblock = IRBlock(label, assignments)
                irblocks.append(irblock)
                label = label_next
                assignments = []
                ir_blocks_all.append(irblocks)
        return index, ir_blocks_all
예제 #5
0
파일: sem.py 프로젝트: lallouslab/miasm
    def do_it_block(self, loc, index, block, assignments, gen_pc_updt):
        instr = block.lines[index]
        it_hints, it_cond = self.parse_itt(instr)
        cond_num = cond_dct_inv[it_cond.name]
        cond_eq = tab_cond[cond_num]

        if not index + len(it_hints) <= len(block.lines):
            raise NotImplementedError("Splitted IT block non supported yet")

        ir_blocks_all = []

        # Gen dummy irblock for IT instr
        loc_next = self.get_next_loc_key(instr)
        dst = ExprAff(self.IRDst, ExprId(loc_next, 32))
        dst_blk = AssignBlock([dst], instr)
        assignments.append(dst_blk)
        irblock = IRBlock(loc, assignments)
        ir_blocks_all.append([irblock])

        loc = loc_next
        assignments = []
        for hint in it_hints:
            irblocks = []
            index += 1
            instr = block.lines[index]

            # Add conditionnal jump to current irblock
            loc_do = self.loc_db.add_location()
            loc_next = self.get_next_loc_key(instr)

            if hint:
                local_cond = ~cond_eq
            else:
                local_cond = cond_eq
            dst = ExprAff(self.IRDst, ExprCond(local_cond, ExprLoc(loc_do, 32), ExprLoc(loc_next, 32)))
            dst_blk = AssignBlock([dst], instr)
            assignments.append(dst_blk)
            irblock = IRBlock(loc, assignments)

            irblocks.append(irblock)

            assignments = []
            loc = loc_do
            split = self.add_instr_to_current_state(
                instr, block, assignments,
                irblocks, gen_pc_updt
            )
            if split:
                raise NotImplementedError("Unsupported instr in IT block (%s)" % instr)

            dst = ExprAff(self.IRDst, ExprId(loc_next, 32))
            dst_blk = AssignBlock([dst], instr)
            assignments.append(dst_blk)
            irblock = IRBlock(loc, assignments)
            irblocks.append(irblock)
            loc = loc_next
            assignments = []
            ir_blocks_all.append(irblocks)
        return index, ir_blocks_all
예제 #6
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
                    assignments[self.ir_arch.IRDst] = m2_expr.ExprId(
                        self.ir_arch.get_next_instr(assignblock.instr), 32)
                    irs.append(AssignBlock(assignments, assignblock.instr))
                irblocks[blk_idx] = IRBlock(irblock.label, irs)

        return irblocks_list
예제 #7
0
파일: ira.py 프로젝트: wl496928838/miasm
    def post_add_asmblock_to_ircfg(self, block, ircfg, ir_blocks):
        IntermediateRepresentation.post_add_asmblock_to_ircfg(self, block, ircfg, ir_blocks)
        new_irblocks = []
        for irb in ir_blocks:
            pc_val = None
            lr_val = None
            for assignblk in irb:
                pc_val = assignblk.get(self.arch.regs.PC, pc_val)
                lr_val = assignblk.get(self.arch.regs.RA, lr_val)

            if pc_val is None or lr_val is None:
                new_irblocks.append(irb)
                continue
            if lr_val.is_loc():
                offset = self.loc_db.get_location_offset(lr_val.loc_key)
                if offset is not None:
                    lr_val = ExprInt(offset, 32)
            if not lr_val.is_int():
                continue

            instr = block.lines[-2]
            if int(lr_val) != instr.offset + 8:
                raise ValueError("Wrong arg")

            # CALL
            lbl = block.get_next()
            new_lbl = self.gen_label()
            call_assignblks, extra_irblocks = self.call_effects(pc_val, instr)
            ir_blocks += extra_irblocks
            irs.append(AssignBlock([ExprAff(self.IRDst,
                                            ExprId(lbl, size=self.pc.size))],
                                   instr))
            new_irblocks.append(IRBlock(new_lbl, call_assignblks))
            new_irblocks.append(irb.set_dst(ExprId(new_lbl, size=self.pc.size)))
        return new_irblocks
예제 #8
0
파일: depgraph.py 프로젝트: trietptm/miasm
    def emul(self, ir_arch, ctx=None, step=False):
        """Symbolic execution of relevant nodes according to the history
        Return the values of inputs nodes' elements
        @ir_arch: IntermediateRepresentation instance
        @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 = {}
        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._ircfg.blocks[loc_key],
                                             line_nb).assignblks

        # Eval the block
        loc_db = LocationDB()
        temp_loc = loc_db.get_or_create_name_location("Temp")
        symb_exec = SymbolicExecutionEngine(ir_arch, 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}
예제 #9
0
    def post_add_block(self, block, ir_blocks):
        IntermediateRepresentation.post_add_block(self, block, ir_blocks)
        new_irblocks = []
        for irb in ir_blocks:
            pc_val = None
            lr_val = None
            for assignblk in irb.irs:
                pc_val = assignblk.get(self.arch.regs.PC, pc_val)
                lr_val = assignblk.get(self.arch.regs.RA, lr_val)

            if pc_val is None or lr_val is None:
                new_irblocks.append(irb)
                continue
            if not expr_is_int_or_label(lr_val):
                new_irblocks.append(irb)
                continue
            if expr_is_label(lr_val):
                lr_val = ExprInt(lr_val.name.offset, 32)

            instr = block.lines[-2]
            if lr_val.arg != instr.offset + 8:
                raise ValueError("Wrong arg")

            # CALL
            lbl = block.get_next()
            new_lbl = self.gen_label()
            irs = self.call_effects(pc_val, instr)
            irs.append(
                AssignBlock(
                    [ExprAff(self.IRDst, ExprId(lbl, size=self.pc.size))],
                    instr))
            new_irblocks.append(IRBlock(new_lbl, irs))
            new_irblocks.append(irb.set_dst(ExprId(new_lbl,
                                                   size=self.pc.size)))
        return new_irblocks
예제 #10
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_labels)
        for index, label in enumerate(reversed(self.relevant_labels), 1):
            if index == last_index and label == self.initial_state.label:
                line_nb = self.initial_state.line_nb
            else:
                line_nb = None
            assignblks += self.irblock_slice(self._ira.blocks[label],
                                             line_nb).assignblks

        # Eval the block
        temp_label = AsmLabel("Temp")
        symb_exec = SymbolicExecutionEngine(self._ira, ctx_init)
        symb_exec.eval_updt_irblock(IRBlock(temp_label, assignblks), step=step)

        # Return only inputs values (others could be wrongs)
        return {element: symb_exec.symbols[element] for element in self.inputs}
예제 #11
0
    def emulbloc(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.irs):
            new_assignblk = {}
            links = {}
            for dst, src in assignblk.iteritems():
                src = self.propag_expr_cst(src)
                if dst.is_mem():
                    ptr = dst.arg
                    ptr = self.propag_expr_cst(ptr)
                    dst = ExprMem(ptr, dst.size)
                new_assignblk[dst] = src

            for arg in assignblk.instr.args:
                new_arg = self.propag_expr_cst(arg)
                links[new_arg] = arg
            self.cst_propag_link[(irb.label, index)] = links

            self.eval_ir(assignblk)
            assignblks.append(AssignBlock(new_assignblk, assignblk.instr))
        self.ir_arch.blocks[irb.label] = IRBlock(irb.label, assignblks)
예제 #12
0
def replace_stack_vars(ir_arch_a, ssa):
    """
    Try to replace stack based memory accesses by variables.
    WARNING: may fail

    @ir_arch_a: ira instance
    @ssa: SSADiGraph instance
    """

    base_to_info = retrieve_stack_accesses(ir_arch_a, ssa)
    modified = False
    for block in ssa.graph.blocks.itervalues():
        assignblks = []
        for assignblk in block:
            out = {}
            for dst, src in assignblk.iteritems():
                new_dst = dst.visit(lambda expr:replace_mem_stack_vars(expr, base_to_info))
                new_src = src.visit(lambda expr:replace_mem_stack_vars(expr, base_to_info))
                if new_dst != dst or new_src != src:
                    modified |= True

                out[new_dst] = new_src

            out = AssignBlock(out, assignblk.instr)
            assignblks.append(out)
        new_block = IRBlock(block.loc_key, assignblks)
        ssa.graph.blocks[block.loc_key] = new_block
    return modified
예제 #13
0
def _do_merge_blocks(ircfg, loc_key, son_loc_key):
    """
    Merge two irblocks at @loc_key and @son_loc_key

    @ircfg: DiGrpahIR
    @loc_key: LocKey instance of the parent IRBlock
    @loc_key: LocKey instance of the son IRBlock
    """

    assignblks = []
    for assignblk in ircfg.blocks[loc_key]:
        if ircfg.IRDst not in assignblk:
            assignblks.append(assignblk)
            continue
        affs = {}
        for dst, src in assignblk.iteritems():
            if dst != ircfg.IRDst:
                affs[dst] = src
        if affs:
            assignblks.append(AssignBlock(affs, assignblk.instr))

    assignblks += ircfg.blocks[son_loc_key].assignblks
    new_block = IRBlock(loc_key, assignblks)

    ircfg.discard_edge(loc_key, son_loc_key)

    for son_successor in ircfg.successors(son_loc_key):
        ircfg.add_uniq_edge(loc_key, son_successor)
        ircfg.discard_edge(son_loc_key, son_successor)
    del ircfg.blocks[son_loc_key]
    ircfg.del_node(son_loc_key)
    ircfg.blocks[loc_key] = new_block
예제 #14
0
def dead_simp(irarch, ircfg):
    """
    Remove useless affectations.

    This function is used to analyse relation of a * complete function *
    This means the blocks under study represent a solid full function graph.

    Source : Kennedy, K. (1979). A survey of data flow analysis techniques.
    IBM Thomas J. Watson Research Division, page 43

    @ircfg: IntermediateRepresentation instance
    """

    modified = False
    reaching_defs = ReachingDefinitions(ircfg)
    defuse = DiGraphDefUse(reaching_defs, deref_mem=True)
    useful = set(dead_simp_useful_assignblks(irarch, defuse, reaching_defs))
    for block in ircfg.blocks.itervalues():
        irs = []
        for idx, assignblk in enumerate(block):
            new_assignblk = dict(assignblk)
            for lval in assignblk:
                if AssignblkNode(block.loc_key, idx, lval) not in useful:
                    del new_assignblk[lval]
                    modified = True
            irs.append(AssignBlock(new_assignblk, assignblk.instr))
        ircfg.blocks[block.loc_key] = IRBlock(block.loc_key, irs)
    return modified
예제 #15
0
파일: sem.py 프로젝트: wl496928838/miasm
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(ExprAff(ir.IRDst, loc_next_expr))
    e_do = IRBlock(loc_do, [AssignBlock(instr_ir, instr)])
    e = [ExprAff(ir.IRDst, dst_cond)]
    return e, [e_do] + extra_ir
예제 #16
0
def discard_phi_sources(ircfg, deleted_vars):
    """
    Remove phi sources in @ircfg belonging to @deleted_vars set
    @ircfg: IRCFG instance in ssa form
    @deleted_vars: unused phi sources
    """
    for block in ircfg.blocks.values():
        if not block.assignblks:
            continue
        assignblk = block[0]
        todo = {}
        modified = False
        for dst, src in assignblk.iteritems():
            if not src.is_op('Phi'):
                todo[dst] = src
                continue
            srcs = set(expr for expr in src.args if expr not in deleted_vars)
            assert (srcs)
            if len(srcs) > 1:
                todo[dst] = srcs
                continue
            todo[dst] = srcs.pop()
            modified = True
        if not modified:
            continue
        assignblks = list(block)
        assignblk = dict(assignblk)
        assignblk.update(todo)
        assignblk = AssignBlock(assignblk, assignblks[0].instr)
        assignblks[0] = assignblk
        new_irblock = IRBlock(block.loc_key, assignblks)
        ircfg.blocks[block.loc_key] = new_irblock
    return True
예제 #17
0
파일: ira.py 프로젝트: xxtxiaofeng/miasm
    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
예제 #18
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)
         assignblk = AssignBlock(self._phinodes[loc_key])
         # insert at the beginning
         new_irs = IRBlock(loc_key, [assignblk] + list(irblock.assignblks))
         self.ircfg.blocks[loc_key] = new_irs
예제 #19
0
파일: unssa.py 프로젝트: hax0kartik/miasm
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(label, irs)
    return irbl
예제 #20
0
    def assignblk_to_irbloc(self, instr, assignblk):
        """
        Ensure IRDst is always set in the head @assignblk of the @instr
        @assignblk: Assignblk instance
        @instr: an instruction instance
        """
        if self.ir_arch.IRDst not in assignblk:
            assignblk[self.ir_arch.IRDst] = m2_expr.ExprInt(
                instr.offset + instr.l, self.ir_arch.IRDst.size)

        return IRBlock(self.ir_arch.get_instr_label(instr), [assignblk])
예제 #21
0
def gen_irblock(label, exprs_list):
    lines = [None for _ in xrange(len(exprs_list))]
    irs = []
    for exprs in exprs_list:
        if isinstance(exprs, AssignBlock):
            irs.append(exprs)
        else:
            irs.append(AssignBlock(exprs))

    irbl = IRBlock(label, irs, lines)
    return irbl
예제 #22
0
파일: sem.py 프로젝트: wl496928838/miasm
    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
예제 #23
0
    def add_block(self, block, 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 = None
        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_instr_label(instr)
            if instr.name.startswith("IT"):
                index, irblocks_it = self.do_it_block(label, index, block, assignments, gen_pc_updt)
                if isinstance(irblocks_it, Iterable):
                    for irblocks in irblocks_it:
                        ir_blocks_all += irblocks
                label = None
                continue

            split = self.add_instr_to_irblock(block, instr, 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_block(block, ir_blocks_all)
        if isinstance(new_ir_blocks_all, Iterable):
            for irblock in new_ir_blocks_all:
                self.blocks[irblock.label] = irblock
        return new_ir_blocks_all
예제 #24
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 ircfg.blocks.values():
            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_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 parent_to_parallel_copies.iteritems(
            ):
                parent = ircfg.blocks[parent]
                assignblks = list(parent)
                assignblks.append(
                    AssignBlock(parallel_copies, parent[-1].instr))
                new_irblock = IRBlock(parent.loc_key, assignblks)
                ircfg.blocks[parent.loc_key] = new_irblock
예제 #25
0
파일: sem.py 프로젝트: manwefm/miasm
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]
예제 #26
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
         dst = m2_expr.ExprInt(offset, self.ir_arch.IRDst.size)
         new_assignblk[self.ir_arch.IRDst] = dst
     irs = [AssignBlock(new_assignblk, instr)]
     return IRBlock(self.ir_arch.get_instr_label(instr), irs)
예제 #27
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(label, irs)
    return irbl
예제 #28
0
파일: codegen.py 프로젝트: sploving/miasm
 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)
예제 #29
0
파일: unssa.py 프로젝트: hax0kartik/miasm
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(irblock.loc_key, assignblks)
        ircfg_a.blocks[loc] = new_irblock
예제 #30
0
파일: ssa.py 프로젝트: hax0kartik/miasm
 def remove_assign_eq(self):
     """
     Remove trivial expressions (a=a) in the current graph
     """
     for irblock in self.ssa.graph.blocks.values():
         assignblks = list(irblock)
         for i, assignblk in enumerate(assignblks):
             out = {}
             for dst, src in assignblk.iteritems():
                 if dst == src:
                     continue
                 out[dst] = src
             assignblks[i] = AssignBlock(out, assignblk.instr)
         self.ssa.graph.blocks[irblock.loc_key] = IRBlock(irblock.loc_key, assignblks)