Esempio n. 1
0
def symbolic_exec():
    from miasm2.ir.symbexec import SymbolicExecutionEngine
    from miasm2.core.bin_stream_ida import bin_stream_ida

    from utils import guess_machine

    bs = bin_stream_ida()
    machine = guess_machine()

    mdis = machine.dis_engine(bs)
    start, end = idc.SelStart(), idc.SelEnd()

    mdis.dont_dis = [end]
    asmcfg = mdis.dis_multiblock(start)
    ira = machine.ira(symbol_pool=mdis.symbol_pool)
    for block in asmcfg.blocks:
        ira.add_block(block)

    print "Run symbolic execution..."
    sb = SymbolicExecutionEngine(ira, machine.mn.regs.regs_init)
    sb.run_at(start)
    modified = {}

    for dst, src in sb.modified(init_state=machine.mn.regs.regs_init):
        modified[dst] = src

    view = symbolicexec_t()
    all_views.append(view)
    if not view.Create(modified, machine, mdis.symbol_pool,
                       "Symbolic Execution - 0x%x to 0x%x" % (start, end)):
        return

    view.Show()
Esempio n. 2
0
def symbolic_exec():
    from miasm2.ir.symbexec import SymbolicExecutionEngine
    from miasm2.core.bin_stream_ida import bin_stream_ida

    from utils import guess_machine

    bs = bin_stream_ida()
    machine = guess_machine()

    mdis = machine.dis_engine(bs)
    start, end = idc.SelStart(), idc.SelEnd()

    mdis.dont_dis = [end]
    asmcfg = mdis.dis_multiblock(start)
    ira = machine.ira(symbol_pool=mdis.symbol_pool)
    for block in asmcfg.blocks:
        ira.add_block(block)

    print "Run symbolic execution..."
    sb = SymbolicExecutionEngine(ira, machine.mn.regs.regs_init)
    sb.run_at(start)
    modified = {}

    for dst, src in sb.modified(init_state=machine.mn.regs.regs_init):
        modified[dst] = src

    view = symbolicexec_t()
    all_views.append(view)
    if not view.Create(modified, machine, mdis.symbol_pool,
                       "Symbolic Execution - 0x%x to 0x%x" % (start, end)):
        return

    view.Show()
Esempio n. 3
0
def symbolic_exec():
    from miasm2.ir.symbexec import SymbolicExecutionEngine
    from miasm2.core.bin_stream_ida import bin_stream_ida

    from utils import guess_machine

    bs = bin_stream_ida()
    machine = guess_machine()

    mdis = machine.dis_engine(bs)
    start, end = idc.SelStart(), idc.SelEnd()

    mdis.dont_dis = [end]
    blocks = mdis.dis_multiblock(start)
    ira = machine.ira()
    for block in blocks:
        ira.add_block(block)

    print "Run symbolic execution..."
    sb = SymbolicExecutionEngine(ira, machine.mn.regs.regs_init)
    sb.emul_ir_blocks(start)

    modified = {}
    for ident in sb.symbols.symbols_id:
        if ident in sb.ir_arch.arch.regs.regs_init and \
                ident in sb.symbols.symbols_id and \
                sb.symbols.symbols_id[ident] == sb.ir_arch.arch.regs.regs_init[ident]:
            continue
        modified[ident] = sb.symbols.symbols_id[ident]

    for ident in sb.symbols.symbols_mem:
        modified[sb.symbols.symbols_mem[ident][0]] = sb.symbols.symbols_mem[ident][1]


    view = symbolicexec_t()
    all_views.append(view)
    if not view.Create(modified, machine,
                       "Symbolic Execution - 0x%x to 0x%x" % (start, end)):
        return

    view.Show()
Esempio n. 4
0
def symbolic_exec():
    from miasm2.ir.symbexec import symbexec
    from miasm2.core.bin_stream_ida import bin_stream_ida

    from utils import guess_machine

    bs = bin_stream_ida()
    machine = guess_machine()

    mdis = machine.dis_engine(bs)
    start, end = SelStart(), SelEnd()

    mdis.dont_dis = [end]
    blocs = mdis.dis_multibloc(start)
    ira = machine.ira()
    for bloc in blocs:
        ira.add_bloc(bloc)

    print "Run symbolic execution..."
    sb = symbexec(ira, machine.mn.regs.regs_init)
    sb.emul_ir_blocks(start)

    modified = {}
    for ident in sb.symbols.symbols_id:
        if ident in sb.ir_arch.arch.regs.regs_init and \
                ident in sb.symbols.symbols_id and \
                sb.symbols.symbols_id[ident] == sb.ir_arch.arch.regs.regs_init[ident]:
            continue
        modified[ident] = sb.symbols.symbols_id[ident]

    for ident in sb.symbols.symbols_mem:
        modified[sb.symbols.symbols_mem[ident][0]] = sb.symbols.symbols_mem[ident][1]


    view = symbolicexec_t()
    if not view.Create(modified, machine,
                       "Symbolic Execution - 0x%x to 0x%x" % (start, end)):
        return

    view.Show()
Esempio n. 5
0
def symbolic_exec():
    from miasm2.ir.symbexec import SymbolicExecutionEngine
    from miasm2.core.bin_stream_ida import bin_stream_ida

    from utils import guess_machine

    start, end = idc.SelStart(), idc.SelEnd()

    bs = bin_stream_ida()
    machine = guess_machine(addr=start)

    mdis = machine.dis_engine(bs)

    if start == idc.BADADDR and end == idc.BADADDR:
        start = idc.ScreenEA()
        end = idc.next_head(start)  # Get next instruction address

    mdis.dont_dis = [end]
    asmcfg = mdis.dis_multiblock(start)
    ira = machine.ira(loc_db=mdis.loc_db)
    for block in asmcfg.blocks:
        ira.add_block(block)

    print "Run symbolic execution..."
    sb = SymbolicExecutionEngine(ira, machine.mn.regs.regs_init)
    sb.run_at(start)
    modified = {}

    for dst, src in sb.modified(init_state=machine.mn.regs.regs_init):
        modified[dst] = src

    view = symbolicexec_t()
    all_views.append(view)
    if not view.Create(
            modified, machine, mdis.loc_db,
            "Symbolic Execution - 0x%x to 0x%x" % (start, idc.prev_head(end))):
        return

    view.Show()
Esempio n. 6
0
def symbolic_exec():
    from miasm.ir.symbexec import SymbolicExecutionEngine
    from miasm.core.bin_stream_ida import bin_stream_ida

    from utils import guess_machine

    start, end = idc.read_selection_start(), idc.read_selection_end()
    loc_db = LocationDB()

    bs = bin_stream_ida()
    machine = guess_machine(addr=start)

    mdis = machine.dis_engine(bs, loc_db=loc_db)

    if start == idc.BADADDR and end == idc.BADADDR:
        start = idc.get_screen_ea()
        end = idc.next_head(start)  # Get next instruction address

    mdis.dont_dis = [end]
    asmcfg = mdis.dis_multiblock(start)
    ira = machine.ira(loc_db=loc_db)
    ircfg = ira.new_ircfg_from_asmcfg(asmcfg)

    print("Run symbolic execution...")
    sb = SymbolicExecutionEngine(ira, machine.mn.regs.regs_init)
    sb.run_at(ircfg, start)
    modified = {}

    for dst, src in sb.modified(init_state=machine.mn.regs.regs_init):
        modified[dst] = src

    view = symbolicexec_t()
    all_views.append(view)
    if not view.Create(
            modified, machine, loc_db, "Symbolic Execution - 0x%x to 0x%x" %
        (start, idc.prev_head(end))):
        return

    view.Show()
Esempio n. 7
0
def symbolic_exec():
    from miasm2.ir.symbexec import SymbolicExecutionEngine
    from miasm2.core.bin_stream_ida import bin_stream_ida

    from utils import guess_machine

    start, end = idc.SelStart(), idc.SelEnd()

    bs = bin_stream_ida()
    machine = guess_machine(addr=start)

    mdis = machine.dis_engine(bs)

    if start == idc.BADADDR and end == idc.BADADDR:
        start = idc.ScreenEA()
        end = idc.next_head(start) # Get next instruction address

    mdis.dont_dis = [end]
    asmcfg = mdis.dis_multiblock(start)
    ira = machine.ira(loc_db=mdis.loc_db)
    ircfg = ira.new_ircfg_from_asmcfg(asmcfg)

    print "Run symbolic execution..."
    sb = SymbolicExecutionEngine(ira, machine.mn.regs.regs_init)
    sb.run_at(ircfg, start)
    modified = {}

    for dst, src in sb.modified(init_state=machine.mn.regs.regs_init):
        modified[dst] = src

    view = symbolicexec_t()
    all_views.append(view)
    if not view.Create(modified, machine, mdis.loc_db,
                       "Symbolic Execution - 0x%x to 0x%x"
                       % (start, idc.prev_head(end))):
        return

    view.Show()
Esempio n. 8
0
def launch_depgraph():
    global graphs, comments, sol_nb, settings, addr, ir_arch
    # Init
    machine = guess_machine()
    mn, dis_engine, ira = machine.mn, machine.dis_engine, machine.ira

    bs = bin_stream_ida()
    mdis = dis_engine(bs, dont_dis_nulstart_bloc=True)
    ir_arch = ira(mdis.symbol_pool)

    # Populate symbols with ida names
    for ad, name in idautils.Names():
        if name is None:
            continue
        mdis.symbol_pool.add_label(name, ad)

    # Get the current function
    addr = idc.ScreenEA()
    func = ida_funcs.get_func(addr)
    blocks = mdis.dis_multiblock(func.startEA)

    # Generate IR
    for block in blocks:
        ir_arch.add_block(block)

    # Get settings
    settings = depGraphSettingsForm(ir_arch)
    settings.Execute()

    label, elements, line_nb = settings.label, settings.elements, settings.line_nb
    # Simplify affectations
    for irb in ir_arch.blocks.values():
        irs = []
        fix_stack = irb.label.offset is not None and settings.unalias_stack
        for assignblk in irb.irs:
            if fix_stack:
                stk_high = m2_expr.ExprInt(idc.GetSpd(assignblk.instr.offset), ir_arch.sp.size)
                fix_dct = {ir_arch.sp: mn.regs.regs_init[ir_arch.sp] + stk_high}

            new_assignblk = {}
            for dst, src in assignblk.iteritems():
                if fix_stack:
                    src = src.replace_expr(fix_dct)
                    if dst != ir_arch.sp:
                        dst = dst.replace_expr(fix_dct)
                dst, src = expr_simp(dst), expr_simp(src)
                new_assignblk[dst] = src
            irs.append(AssignBlock(new_assignblk, instr=assignblk.instr))
        ir_arch.blocks[irb.label] = IRBlock(irb.label, irs)

    # Get dependency graphs
    dg = settings.depgraph
    graphs = dg.get(label, elements, line_nb,
                    set([ir_arch.symbol_pool.getby_offset(func.startEA)]))

    # Display the result
    comments = {}
    sol_nb = 0

    # Register and launch
    ida_kernwin.add_hotkey("Shift-N", next_element)
    treat_element()
Esempio n. 9
0
def launch_depgraph():
    global graphs, comments, sol_nb, settings, addr, ir_arch, ircfg
    # Get the current function
    addr = idc.ScreenEA()
    func = ida_funcs.get_func(addr)

    # Init
    machine = guess_machine(addr=func.startEA)
    mn, dis_engine, ira = machine.mn, machine.dis_engine, machine.ira

    bs = bin_stream_ida()
    mdis = dis_engine(bs, dont_dis_nulstart_bloc=True)
    ir_arch = ira(mdis.loc_db)

    # Populate symbols with ida names
    for ad, name in idautils.Names():
        if name is None:
            continue
        mdis.loc_db.add_location(name, ad)

    asmcfg = mdis.dis_multiblock(func.startEA)

    # Generate IR
    ircfg = ir_arch.new_ircfg_from_asmcfg(asmcfg)

    # Get settings
    settings = depGraphSettingsForm(ir_arch, ircfg)
    settings.Execute()

    loc_key, elements, line_nb = settings.loc_key, settings.elements, settings.line_nb
    # Simplify affectations
    for irb in ircfg.blocks.values():
        irs = []
        offset = ir_arch.loc_db.get_location_offset(irb.loc_key)
        fix_stack = offset is not None and settings.unalias_stack
        for assignblk in irb:
            if fix_stack:
                stk_high = m2_expr.ExprInt(idc.GetSpd(assignblk.instr.offset), ir_arch.sp.size)
                fix_dct = {ir_arch.sp: mn.regs.regs_init[ir_arch.sp] + stk_high}

            new_assignblk = {}
            for dst, src in assignblk.iteritems():
                if fix_stack:
                    src = src.replace_expr(fix_dct)
                    if dst != ir_arch.sp:
                        dst = dst.replace_expr(fix_dct)
                dst, src = expr_simp(dst), expr_simp(src)
                new_assignblk[dst] = src
            irs.append(AssignBlock(new_assignblk, instr=assignblk.instr))
        ircfg.blocks[irb.loc_key] = IRBlock(irb.loc_key, irs)

    # Get dependency graphs
    dg = settings.depgraph
    graphs = dg.get(loc_key, elements, line_nb,
                    set([ir_arch.loc_db.get_offset_location(func.startEA)]))

    # Display the result
    comments = {}
    sol_nb = 0

    # Register and launch
    ida_kernwin.add_hotkey("Shift-N", next_element)
    treat_element()
Esempio n. 10
0
def build_graph(verbose=False, simplify=False):
    machine = guess_machine()
    mn, dis_engine, ira = machine.mn, machine.dis_engine, machine.ira

    if verbose:
        print "Arch", dis_engine

    fname = idc.GetInputFile()
    if verbose:
        print fname

    bs = bin_stream_ida()
    mdis = dis_engine(bs)
    ir_arch = ira(mdis.symbol_pool)

    # populate symbols with ida names
    for addr, name in idautils.Names():
        # print hex(ad), repr(name)
        if name is None:
            continue
        if (mdis.symbol_pool.getby_offset(addr)
                or mdis.symbol_pool.getby_name(name)):
            # Symbol alias
            continue
        mdis.symbol_pool.add_location(name, addr)

    if verbose:
        print "start disasm"
    addr = idc.ScreenEA()
    if verbose:
        print hex(addr)

    asmcfg = mdis.dis_multiblock(addr)

    if verbose:
        print "generating graph"
        open('asm_flow.dot', 'w').write(asmcfg.dot())

        print "generating IR... %x" % addr

    for block in asmcfg.blocks:
        if verbose:
            print 'ADD'
            print block
        ir_arch.add_block(block)

    if verbose:
        print "IR ok... %x" % addr

    for irb in ir_arch.blocks.itervalues():
        irs = []
        for assignblk in irb:
            new_assignblk = {
                expr_simp(dst): expr_simp(src)
                for dst, src in assignblk.iteritems()
            }
            irs.append(AssignBlock(new_assignblk, instr=assignblk.instr))
        ir_arch.blocks[irb.loc_key] = IRBlock(irb.loc_key, irs)

    if verbose:
        out = ir_arch.graph.dot()
        open(os.path.join(tempfile.gettempdir(), 'graph.dot'), 'wb').write(out)
    title = "Miasm IR graph"

    if simplify:
        dead_simp(ir_arch)

        ir_arch.simplify(expr_simp)
        modified = True
        while modified:
            modified = False
            modified |= dead_simp(ir_arch)
            modified |= ir_arch.remove_empty_assignblks()
            modified |= ir_arch.remove_jmp_blocks()
            modified |= ir_arch.merge_blocks()
        title += " (simplified)"

    g = GraphMiasmIR(ir_arch, title, None)

    g.Show()
Esempio n. 11
0
def build_graph(start_addr, type_graph, simplify=False, dontmodstack=True, loadint=False, verbose=False):
    machine = guess_machine(addr=start_addr)
    dis_engine, ira = machine.dis_engine, machine.ira

    class IRADelModCallStack(ira):
        def call_effects(self, addr, instr):
            assignblks, extra = super(IRADelModCallStack, self).call_effects(addr, instr)
            if not dontmodstack:
                return assignblks, extra
            out = []
            for assignblk in assignblks:
                dct = dict(assignblk)
                dct = {
                    dst:src for (dst, src) in viewitems(dct) if dst != self.sp
                }
                out.append(AssignBlock(dct, assignblk.instr))
            return out, extra


    if verbose:
        print("Arch", dis_engine)

    fname = idc.get_root_filename()
    if verbose:
        print(fname)

    bs = bin_stream_ida()
    mdis = dis_engine(bs)
    ir_arch = IRADelModCallStack(mdis.loc_db)


    # populate symbols with ida names
    for addr, name in idautils.Names():
        if name is None:
            continue
        if (mdis.loc_db.get_offset_location(addr) or
            mdis.loc_db.get_name_location(name)):
            # Symbol alias
            continue
        mdis.loc_db.add_location(name, addr)

    if verbose:
        print("start disasm")
    if verbose:
        print(hex(start_addr))

    asmcfg = mdis.dis_multiblock(start_addr)
    entry_points = set([mdis.loc_db.get_offset_location(start_addr)])
    if verbose:
        print("generating graph")
        open('asm_flow.dot', 'w').write(asmcfg.dot())
        print("generating IR... %x" % start_addr)

    ircfg = ir_arch.new_ircfg_from_asmcfg(asmcfg)

    if verbose:
        print("IR ok... %x" % start_addr)

    for irb in list(viewvalues(ircfg.blocks)):
        irs = []
        for assignblk in irb:
            new_assignblk = {
                expr_simp(dst): expr_simp(src)
                for dst, src in viewitems(assignblk)
            }
            irs.append(AssignBlock(new_assignblk, instr=assignblk.instr))
        ircfg.blocks[irb.loc_key] = IRBlock(irb.loc_key, irs)

    if verbose:
        out = ircfg.dot()
        open(os.path.join(tempfile.gettempdir(), 'graph.dot'), 'wb').write(out)
    title = "Miasm IR graph"


    head = list(entry_points)[0]

    if simplify:
        ircfg_simplifier = IRCFGSimplifierCommon(ir_arch)
        ircfg_simplifier.simplify(ircfg, head)
        title += " (simplified)"

    if type_graph == TYPE_GRAPH_IR:
        graph = GraphMiasmIR(ircfg, title, None)
        graph.Show()
        return


    class IRAOutRegs(ira):
        def get_out_regs(self, block):
            regs_todo = super(IRAOutRegs, self).get_out_regs(block)
            out = {}
            for assignblk in block:
                for dst in assignblk:
                    reg = self.ssa_var.get(dst, None)
                    if reg is None:
                        continue
                    if reg in regs_todo:
                        out[reg] = dst
            return set(viewvalues(out))



    # Add dummy dependency to uncover out regs affectation
    for loc in ircfg.leaves():
        irblock = ircfg.blocks.get(loc)
        if irblock is None:
            continue
        regs = {}
        for reg in ir_arch.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.blocks[loc] = new_irblock


    class CustomIRCFGSimplifierSSA(IRCFGSimplifierSSA):
        def do_simplify(self, ssa, head):
            modified = super(CustomIRCFGSimplifierSSA, self).do_simplify(ssa, head)
            if loadint:
                modified |= load_from_int(ssa.graph, bs, is_addr_ro_variable)
            return modified

        def simplify(self, ircfg, head):
            ssa = self.ircfg_to_ssa(ircfg, head)
            ssa = self.do_simplify_loop(ssa, head)

            if type_graph == TYPE_GRAPH_IRSSA:
                ret = ssa.graph
            elif type_graph == TYPE_GRAPH_IRSSAUNSSA:
                ircfg = self.ssa_to_unssa(ssa, head)
                ircfg_simplifier = IRCFGSimplifierCommon(self.ir_arch)
                ircfg_simplifier.simplify(ircfg, head)
                ret = ircfg
            else:
                raise ValueError("Unknown option")
            return ret


    head = list(entry_points)[0]
    simplifier = CustomIRCFGSimplifierSSA(ir_arch)
    ircfg = simplifier.simplify(ircfg, head)
    open('final.dot', 'w').write(ircfg.dot())


    graph = GraphMiasmIR(ircfg, title, None)
    graph.Show()
Esempio n. 12
0
def launch_depgraph():
    global graphs, comments, sol_nb, settings, addr, ir_arch, ircfg
    # Get the current function
    addr = idc.get_screen_ea()
    func = ida_funcs.get_func(addr)

    # Init
    machine = guess_machine(addr=func.start_ea)
    mn, dis_engine, ira = machine.mn, machine.dis_engine, machine.ira

    bs = bin_stream_ida()
    mdis = dis_engine(bs, dont_dis_nulstart_bloc=True)
    ir_arch = ira(mdis.loc_db)

    # Populate symbols with ida names
    for ad, name in idautils.Names():
        if name is None:
            continue
        mdis.loc_db.add_location(name, ad)

    asmcfg = mdis.dis_multiblock(func.start_ea)

    # Generate IR
    ircfg = ir_arch.new_ircfg_from_asmcfg(asmcfg)

    # Get settings
    settings = depGraphSettingsForm(ir_arch, ircfg, mn)
    settings.Execute()

    loc_key, elements, line_nb = settings.loc_key, settings.elements, settings.line_nb
    # Simplify assignments
    for irb in list(viewvalues(ircfg.blocks)):
        irs = []
        offset = ir_arch.loc_db.get_location_offset(irb.loc_key)
        fix_stack = offset is not None and settings.unalias_stack
        for assignblk in irb:
            if fix_stack:
                stk_high = m2_expr.ExprInt(idc.get_spd(assignblk.instr.offset), ir_arch.sp.size)
                fix_dct = {ir_arch.sp: mn.regs.regs_init[ir_arch.sp] + stk_high}

            new_assignblk = {}
            for dst, src in viewitems(assignblk):
                if fix_stack:
                    src = src.replace_expr(fix_dct)
                    if dst != ir_arch.sp:
                        dst = dst.replace_expr(fix_dct)
                dst, src = expr_simp(dst), expr_simp(src)
                new_assignblk[dst] = src
            irs.append(AssignBlock(new_assignblk, instr=assignblk.instr))
        ircfg.blocks[irb.loc_key] = IRBlock(irb.loc_key, irs)

    # Get dependency graphs
    dg = settings.depgraph
    graphs = dg.get(loc_key, elements, line_nb,
                    set([ir_arch.loc_db.get_offset_location(func.start_ea)]))

    # Display the result
    comments = {}
    sol_nb = 0

    # Register and launch
    ida_kernwin.add_hotkey("Shift-N", next_element)
    treat_element()
Esempio n. 13
0
def build_graph(start_addr, type_graph, simplify=False, dontmodstack=True, loadint=False, verbose=False):
    machine = guess_machine(addr=start_addr)
    dis_engine, ira = machine.dis_engine, machine.ira

    class IRADelModCallStack(ira):
        def call_effects(self, addr, instr):
            assignblks, extra = super(IRADelModCallStack, self).call_effects(addr, instr)
            if not dontmodstack:
                return assignblks, extra
            out = []
            for assignblk in assignblks:
                dct = dict(assignblk)
                dct = {
                    dst:src for (dst, src) in viewitems(dct) if dst != self.sp
                }
                out.append(AssignBlock(dct, assignblk.instr))
            return out, extra


    if verbose:
        print("Arch", dis_engine)

    fname = idc.GetInputFile()
    if verbose:
        print(fname)

    bs = bin_stream_ida()
    mdis = dis_engine(bs)
    ir_arch = IRADelModCallStack(mdis.loc_db)


    # populate symbols with ida names
    for addr, name in idautils.Names():
        if name is None:
            continue
        if (mdis.loc_db.get_offset_location(addr) or
            mdis.loc_db.get_name_location(name)):
            # Symbol alias
            continue
        mdis.loc_db.add_location(name, addr)

    if verbose:
        print("start disasm")
    if verbose:
        print(hex(start_addr))

    asmcfg = mdis.dis_multiblock(start_addr)
    entry_points = set([mdis.loc_db.get_offset_location(start_addr)])
    if verbose:
        print("generating graph")
        open('asm_flow.dot', 'w').write(asmcfg.dot())
        print("generating IR... %x" % start_addr)

    ircfg = ir_arch.new_ircfg_from_asmcfg(asmcfg)

    if verbose:
        print("IR ok... %x" % start_addr)

    for irb in list(viewvalues(ircfg.blocks)):
        irs = []
        for assignblk in irb:
            new_assignblk = {
                expr_simp(dst): expr_simp(src)
                for dst, src in viewitems(assignblk)
            }
            irs.append(AssignBlock(new_assignblk, instr=assignblk.instr))
        ircfg.blocks[irb.loc_key] = IRBlock(irb.loc_key, irs)

    if verbose:
        out = ircfg.dot()
        open(os.path.join(tempfile.gettempdir(), 'graph.dot'), 'wb').write(out)
    title = "Miasm IR graph"


    head = list(entry_points)[0]

    if simplify:
        ircfg_simplifier = IRCFGSimplifierCommon(ir_arch)
        ircfg_simplifier.simplify(ircfg, head)
        title += " (simplified)"

    if type_graph == TYPE_GRAPH_IR:
        graph = GraphMiasmIR(ircfg, title, None)
        graph.Show()
        return


    class IRAOutRegs(ira):
        def get_out_regs(self, block):
            regs_todo = super(IRAOutRegs, self).get_out_regs(block)
            out = {}
            for assignblk in block:
                for dst in assignblk:
                    reg = self.ssa_var.get(dst, None)
                    if reg is None:
                        continue
                    if reg in regs_todo:
                        out[reg] = dst
            return set(viewvalues(out))



    # Add dummy dependency to uncover out regs affectation
    for loc in ircfg.leaves():
        irblock = ircfg.blocks.get(loc)
        if irblock is None:
            continue
        regs = {}
        for reg in ir_arch.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.blocks[loc] = new_irblock


    class CustomIRCFGSimplifierSSA(IRCFGSimplifierSSA):
        def do_simplify(self, ssa, head):
            modified = super(CustomIRCFGSimplifierSSA, self).do_simplify(ssa, head)
            if loadint:
                modified |= load_from_int(ssa.graph, bs, is_addr_ro_variable)
            return modified

        def simplify(self, ircfg, head):
            ssa = self.ircfg_to_ssa(ircfg, head)
            ssa = self.do_simplify_loop(ssa, head)

            if type_graph == TYPE_GRAPH_IRSSA:
                ret = ssa.graph
            elif type_graph == TYPE_GRAPH_IRSSAUNSSA:
                ircfg = self.ssa_to_unssa(ssa, head)
                ircfg_simplifier = IRCFGSimplifierCommon(self.ir_arch)
                ircfg_simplifier.simplify(ircfg, head)
                ret = ircfg
            else:
                raise ValueError("Unknown option")
            return ret


    head = list(entry_points)[0]
    simplifier = CustomIRCFGSimplifierSSA(ir_arch)
    ircfg = simplifier.simplify(ircfg, head)
    open('final.dot', 'w').write(ircfg.dot())


    graph = GraphMiasmIR(ircfg, title, None)
    graph.Show()
Esempio n. 14
0
    def OnCommand(self, cmd_id):
        if self.cmd_test == cmd_id:
            print 'TEST!'
            return
        print "command:", cmd_id

    def Show(self):
        if not GraphViewer.Show(self):
            return False
        self.cmd_test = self.AddCommand("Test", "F2")
        if self.cmd_test == 0:
            print "Failed to add popup menu item!"
        return True


machine = guess_machine()
mn, dis_engine, ira = machine.mn, machine.dis_engine, machine.ira

print "Arch", dis_engine

fname = GetInputFile()
print fname

bs = bin_stream_ida()
mdis = dis_engine(bs)
ir_arch = ira(mdis.symbol_pool)

# populate symbols with ida names
for ad, name in Names():
    # print hex(ad), repr(name)
    if name is None:
Esempio n. 15
0
def analyse_function():

    # Init
    machine = guess_machine()
    mn, dis_engine, ira = machine.mn, machine.dis_engine, machine.ira

    bs = bin_stream_ida()
    mdis = dis_engine(bs, dont_dis_nulstart_bloc=True)


    iraCallStackFixer = get_ira_call_fixer(ira)
    ir_arch = iraCallStackFixer(mdis.symbol_pool)


    # Get settings
    settings = TypePropagationForm(ir_arch)
    ret = settings.Execute()
    if not ret:
        return

    if settings.cScope.value == 0:
        addr = settings.functionAddr.value
    else:
        addr = settings.startAddr.value
        if settings.cScope.value == 2:
            end = settings.endAddr
            mdis.dont_dis = [end]

    blocks = mdis.dis_multiblock(addr)
    # Generate IR
    for block in blocks:
        ir_arch.add_block(block)

    cst_propag_link = {}
    if settings.cUnalias.value:
        init_infos = {ir_arch.sp: ir_arch.arch.regs.regs_init[ir_arch.sp] }
        cst_propag_link = propagate_cst_expr(ir_arch, 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 = ir_arch.symbol_pool.getby_offset(addr)
    lbl_head = ir_arch.symbol_pool.getby_name_create("start")

    first_block = blocks.label2block(lbl_real_start)

    assignblk_head = AssignBlock([ExprAff(ir_arch.IRDst, ExprId(lbl_real_start, ir_arch.IRDst.size)),
                                  ExprAff(
                                      ir_arch.sp, ir_arch.arch.regs.regs_init[ir_arch.sp])
                                  ], first_block.lines[0])
    irb_head = IRBlock(lbl_head, [assignblk_head])
    ir_arch.blocks[lbl_head] = irb_head
    ir_arch.graph.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 ir_arch.blocks:
            continue

        symbexec_engine = TypePropagationEngine(ir_arch, types_mngr, state)
        addr = symbexec_engine.run_block_at(lbl)
        symbexec_engine.del_mem_above_stack(ir_arch.sp)

        ir_arch._graph = None
        sons = ir_arch.graph.successors(lbl)
        for son in sons:
            add_state(ir_arch, todo, states, son,
                      symbexec_engine.get_state())

    for lbl, state in states.iteritems():
        if lbl not in ir_arch.blocks:
            continue
        symbexec_engine = CTypeEngineFixer(ir_arch, types_mngr, state, cst_propag_link)
        addr = symbexec_engine.run_block_at(lbl)
        symbexec_engine.del_mem_above_stack(ir_arch.sp)
Esempio n. 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)
Esempio n. 17
0
    def OnCommand(self, cmd_id):
        if self.cmd_test == cmd_id:
            print 'TEST!'
            return
        print "command:", cmd_id

    def Show(self):
        if not GraphViewer.Show(self):
            return False
        self.cmd_test = self.AddCommand("Test", "F2")
        if self.cmd_test == 0:
            print "Failed to add popup menu item!"
        return True


machine = guess_machine()
mn, dis_engine, ira = machine.mn, machine.dis_engine, machine.ira

print "Arch", dis_engine

fname = GetInputFile()
print fname

bs = bin_stream_ida()
mdis = dis_engine(bs)
ir_arch = ira(mdis.symbol_pool)

# populate symbols with ida names
for ad, name in Names():
    # print hex(ad), repr(name)
    if name is None:
Esempio n. 18
0
def build_graph(verbose=False, simplify=False, ssa=False, ssa_simplify=False):
    start_addr = idc.ScreenEA()

    machine = guess_machine(addr=start_addr)
    dis_engine, ira = machine.dis_engine, machine.ira

    if verbose:
        print "Arch", dis_engine

    fname = idc.GetInputFile()
    if verbose:
        print fname

    bs = bin_stream_ida()
    mdis = dis_engine(bs)
    ir_arch = ira(mdis.loc_db)

    # populate symbols with ida names
    for addr, name in idautils.Names():
        if name is None:
            continue
        if (mdis.loc_db.get_offset_location(addr)
                or mdis.loc_db.get_name_location(name)):
            # Symbol alias
            continue
        mdis.loc_db.add_location(name, addr)

    if verbose:
        print "start disasm"
    if verbose:
        print hex(addr)

    asmcfg = mdis.dis_multiblock(start_addr)

    entry_points = set([mdis.loc_db.get_offset_location(start_addr)])
    if verbose:
        print "generating graph"
        open('asm_flow.dot', 'w').write(asmcfg.dot())

        print "generating IR... %x" % start_addr

    ircfg = ir_arch.new_ircfg_from_asmcfg(asmcfg)

    if verbose:
        print "IR ok... %x" % start_addr

    for irb in ircfg.blocks.itervalues():
        irs = []
        for assignblk in irb:
            new_assignblk = {
                expr_simp(dst): expr_simp(src)
                for dst, src in assignblk.iteritems()
            }
            irs.append(AssignBlock(new_assignblk, instr=assignblk.instr))
        ircfg.blocks[irb.loc_key] = IRBlock(irb.loc_key, irs)

    if verbose:
        out = ircfg.dot()
        open(os.path.join(tempfile.gettempdir(), 'graph.dot'), 'wb').write(out)
    title = "Miasm IR graph"

    if simplify:
        dead_simp(ir_arch, ircfg)

        ircfg.simplify(expr_simp)
        modified = True
        while modified:
            modified = False
            modified |= dead_simp(ir_arch, ircfg)
            modified |= remove_empty_assignblks(ircfg)
            modified |= merge_blocks(ircfg, entry_points)
        title += " (simplified)"

    graph = GraphMiasmIR(ircfg, title, None)

    if ssa:
        if len(entry_points) != 1:
            raise RuntimeError("Your graph should have only one head")
        head = list(entry_points)[0]
        ssa = SSADiGraph(ircfg)
        ssa.transform(head)
        title += " (SSA)"
        graph = GraphMiasmIR(ssa.graph, title, None)

    if ssa_simplify:

        class IRAOutRegs(ira):
            def get_out_regs(self, block):
                regs_todo = super(self.__class__, self).get_out_regs(block)
                out = {}
                for assignblk in block:
                    for dst in assignblk:
                        reg = self.ssa_var.get(dst, None)
                        if reg is None:
                            continue
                        if reg in regs_todo:
                            out[reg] = dst
                return set(out.values())

        # Add dummy dependency to uncover out regs affectation
        for loc in ircfg.leaves():
            irblock = ircfg.blocks.get(loc)
            if irblock is None:
                continue
            regs = {}
            for reg in ir_arch.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.blocks[loc] = new_irblock

        ir_arch = IRAOutRegs(mdis.loc_db)

        def is_addr_ro_variable(bs, addr, size):
            """
            Return True if address at @addr is a read-only variable.
            WARNING: Quick & Dirty

            @addr: integer representing the address of the variable
            @size: size in bits

            """
            try:
                _ = bs.getbytes(addr, size / 8)
            except IOError:
                return False
            return True

        ir_arch.ssa_var = {}
        index = 0
        modified = True
        ssa_forbidden_regs = set(
            [ir_arch.pc, ir_arch.IRDst, ir_arch.arch.regs.exception_flags])

        head = list(entry_points)[0]
        heads = set([head])
        all_ssa_vars = set()

        propagate_expr = PropagateExpr()

        while modified:
            ssa = SSADiGraph(ircfg)
            ssa.immutable_ids.update(ssa_forbidden_regs)

            ssa.transform(head)

            all_ssa_vars.update(ssa._ssa_variable_to_expr)

            ssa_regs = [reg for reg in ssa.expressions if reg.is_id()]
            ssa_forbidden_regs.update(ssa_regs)

            ir_arch.ssa_var.update(ssa._ssa_variable_to_expr)

            while modified:
                index += 1
                modified = False
                modified |= propagate_expr.propagate(ssa, head)
                modified |= ircfg.simplify(expr_simp)
                simp_modified = True
                while simp_modified:
                    index += 1
                    simp_modified = False
                    simp_modified |= dead_simp(ir_arch, ircfg)
                    index += 1
                    simp_modified |= remove_empty_assignblks(ircfg)
                    simp_modified |= merge_blocks(ircfg, heads)
                    simp_modified |= load_from_int(ircfg, bs,
                                                   is_addr_ro_variable)
                    modified |= simp_modified
                    index += 1

        merge_blocks(ircfg, heads)
        ssa = SSADiGraph(ircfg)
        ssa.immutable_ids.update(ssa_forbidden_regs)
        ssa.transform(head)
        all_ssa_vars.update(ssa._ssa_variable_to_expr)
        ssa._ssa_variable_to_expr = all_ssa_vars
        dead_simp(ir_arch, ssa.graph)

        title += " (SSA Simplified)"
        graph = GraphMiasmIR(ssa.graph, title, None)

    graph.Show()
Esempio n. 19
0
def build_graph(verbose=False, simplify=False):
    start_addr = idc.ScreenEA()

    machine = guess_machine(addr=start_addr)
    dis_engine, ira = machine.dis_engine, machine.ira

    if verbose:
        print "Arch", dis_engine

    fname = idc.GetInputFile()
    if verbose:
        print fname

    bs = bin_stream_ida()
    mdis = dis_engine(bs)
    ir_arch = ira(mdis.loc_db)

    # populate symbols with ida names
    for addr, name in idautils.Names():
        if name is None:
            continue
        if (mdis.loc_db.get_offset_location(addr)
                or mdis.loc_db.get_name_location(name)):
            # Symbol alias
            continue
        mdis.loc_db.add_location(name, addr)

    if verbose:
        print "start disasm"
    if verbose:
        print hex(addr)

    asmcfg = mdis.dis_multiblock(start_addr)

    entry_points = set([start_addr])

    if verbose:
        print "generating graph"
        open('asm_flow.dot', 'w').write(asmcfg.dot())

        print "generating IR... %x" % start_addr

    ircfg = ir_arch.new_ircfg_from_asmcfg(asmcfg)

    if verbose:
        print "IR ok... %x" % start_addr

    for irb in ircfg.blocks.itervalues():
        irs = []
        for assignblk in irb:
            new_assignblk = {
                expr_simp(dst): expr_simp(src)
                for dst, src in assignblk.iteritems()
            }
            irs.append(AssignBlock(new_assignblk, instr=assignblk.instr))
        ircfg.blocks[irb.loc_key] = IRBlock(irb.loc_key, irs)

    if verbose:
        out = ircfg.dot()
        open(os.path.join(tempfile.gettempdir(), 'graph.dot'), 'wb').write(out)
    title = "Miasm IR graph"

    if simplify:
        dead_simp(ir_arch, ircfg)

        ircfg.simplify(expr_simp)
        modified = True
        while modified:
            modified = False
            modified |= dead_simp(ir_arch, ircfg)
            modified |= remove_empty_assignblks(ircfg)
            modified |= merge_blocks(ircfg, entry_points)
        title += " (simplified)"

    graph = GraphMiasmIR(ircfg, title, None)

    graph.Show()
Esempio n. 20
0
def analyse_function():

    # Init
    machine = guess_machine()
    mn, dis_engine, ira = machine.mn, machine.dis_engine, machine.ira

    bs = bin_stream_ida()
    mdis = dis_engine(bs, dont_dis_nulstart_bloc=True)

    iraCallStackFixer = get_ira_call_fixer(ira)
    ir_arch = iraCallStackFixer(mdis.symbol_pool)

    # Get the current function
    func = ida_funcs.get_func(idc.ScreenEA())
    addr = func.startEA
    blocks = mdis.dis_multiblock(addr)
    # Generate IR
    for block in blocks:
        ir_arch.add_block(block)

    # Get settings
    settings = TypePropagationForm(ir_arch)
    ret = settings.Execute()
    if not ret:
        return

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

    types_mngr = get_types_mngr(settings.headerFile.value, settings.arch.value)
    mychandler = MyCHandler(types_mngr, {})
    infos_types = {}
    for line in settings.strTypesInfo.value.split('\n'):
        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 = ir_arch.symbol_pool.getby_offset(addr)
    lbl_head = ir_arch.symbol_pool.getby_name_create("start")

    first_block = blocks.label2block(lbl_real_start)

    assignblk_head = AssignBlock([
        ExprAff(ir_arch.IRDst, ExprId(lbl_real_start, ir_arch.IRDst.size)),
        ExprAff(ir_arch.sp, ir_arch.arch.regs.regs_init[ir_arch.sp])
    ], first_block.lines[0])
    irb_head = IRBlock(lbl_head, [assignblk_head])
    ir_arch.blocks[lbl_head] = irb_head
    ir_arch.graph.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 ir_arch.blocks:
            continue

        symbexec_engine = TypePropagationEngine(ir_arch, types_mngr, state)
        addr = symbexec_engine.emul_ir_block(lbl)
        symbexec_engine.del_mem_above_stack(ir_arch.sp)

        ir_arch._graph = None
        sons = ir_arch.graph.successors(lbl)
        for son in sons:
            add_state(ir_arch, todo, states, son, symbexec_engine.get_state())

    for lbl, state in states.iteritems():
        if lbl not in ir_arch.blocks:
            continue
        symbexec_engine = CTypeEngineFixer(ir_arch, types_mngr, state,
                                           cst_propag_link)
        addr = symbexec_engine.emul_ir_block(lbl)
        symbexec_engine.del_mem_above_stack(ir_arch.sp)
Esempio n. 21
0
def build_graph(start_addr,
                type_graph,
                simplify=False,
                dontmodstack=True,
                loadint=False,
                verbose=False):
    machine = guess_machine(addr=start_addr)
    dis_engine, ira = machine.dis_engine, machine.ira

    class IRADelModCallStack(ira):
        def call_effects(self, addr, instr):
            assignblks, extra = super(IRADelModCallStack,
                                      self).call_effects(addr, instr)
            if not dontmodstack:
                return assignblks, extra
            out = []
            for assignblk in assignblks:
                dct = dict(assignblk)
                dct = {
                    dst: src
                    for (dst, src) in dct.iteritems() if dst != self.sp
                }
                out.append(AssignBlock(dct, assignblk.instr))
            return out, extra

    if verbose:
        print "Arch", dis_engine

    fname = idc.GetInputFile()
    if verbose:
        print fname

    bs = bin_stream_ida()
    mdis = dis_engine(bs)
    ir_arch = IRADelModCallStack(mdis.loc_db)

    # populate symbols with ida names
    for addr, name in idautils.Names():
        if name is None:
            continue
        if (mdis.loc_db.get_offset_location(addr)
                or mdis.loc_db.get_name_location(name)):
            # Symbol alias
            continue
        mdis.loc_db.add_location(name, addr)

    if verbose:
        print "start disasm"
    if verbose:
        print hex(start_addr)

    asmcfg = mdis.dis_multiblock(start_addr)
    entry_points = set([mdis.loc_db.get_offset_location(start_addr)])
    if verbose:
        print "generating graph"
        open('asm_flow.dot', 'w').write(asmcfg.dot())
        print "generating IR... %x" % start_addr

    ircfg = ir_arch.new_ircfg_from_asmcfg(asmcfg)

    if verbose:
        print "IR ok... %x" % start_addr

    for irb in ircfg.blocks.itervalues():
        irs = []
        for assignblk in irb:
            new_assignblk = {
                expr_simp(dst): expr_simp(src)
                for dst, src in assignblk.iteritems()
            }
            irs.append(AssignBlock(new_assignblk, instr=assignblk.instr))
        ircfg.blocks[irb.loc_key] = IRBlock(irb.loc_key, irs)

    if verbose:
        out = ircfg.dot()
        open(os.path.join(tempfile.gettempdir(), 'graph.dot'), 'wb').write(out)
    title = "Miasm IR graph"

    if simplify:
        dead_simp(ir_arch, ircfg)
        ircfg.simplify(expr_simp)
        modified = True
        while modified:
            modified = False
            modified |= dead_simp(ir_arch, ircfg)
            modified |= remove_empty_assignblks(ircfg)
            modified |= merge_blocks(ircfg, entry_points)
        title += " (simplified)"

    if type_graph == TYPE_GRAPH_IR:
        graph = GraphMiasmIR(ircfg, title, None)
        graph.Show()
        return

    head = list(entry_points)[0]

    class IRAOutRegs(ira):
        def get_out_regs(self, block):
            regs_todo = super(IRAOutRegs, self).get_out_regs(block)
            out = {}
            for assignblk in block:
                for dst in assignblk:
                    reg = self.ssa_var.get(dst, None)
                    if reg is None:
                        continue
                    if reg in regs_todo:
                        out[reg] = dst
            return set(out.values())

    # Add dummy dependency to uncover out regs affectation
    for loc in ircfg.leaves():
        irblock = ircfg.blocks.get(loc)
        if irblock is None:
            continue
        regs = {}
        for reg in ir_arch.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.blocks[loc] = new_irblock

    ir_arch = IRAOutRegs(mdis.loc_db)
    ir_arch.ssa_var = {}
    modified = True
    ssa_forbidden_regs = set(
        [ir_arch.pc, ir_arch.IRDst, ir_arch.arch.regs.exception_flags])

    head = list(entry_points)[0]
    heads = set([head])
    all_ssa_vars = {}

    propagate_expr = PropagateExpr()

    ssa = SSADiGraph(ircfg)
    ssa.immutable_ids.update(ssa_forbidden_regs)
    ssa.ssa_variable_to_expr.update(all_ssa_vars)
    ssa.transform(head)
    all_ssa_vars.update(ssa.ssa_variable_to_expr)

    ir_arch.ssa_var.update(ssa.ssa_variable_to_expr)

    if simplify:

        while modified:
            ssa = SSADiGraph(ircfg)
            ssa.immutable_ids.update(ssa_forbidden_regs)
            ssa.ssa_variable_to_expr.update(all_ssa_vars)
            ssa.transform(head)
            all_ssa_vars.update(ssa.ssa_variable_to_expr)

            ir_arch.ssa_var.update(ssa.ssa_variable_to_expr)

            while modified:
                modified = False
                modified |= propagate_expr.propagate(ssa, head)
                modified |= ircfg.simplify(expr_simp)
                simp_modified = True
                while simp_modified:
                    simp_modified = False
                    simp_modified |= dead_simp(ir_arch, ircfg)
                    simp_modified |= remove_empty_assignblks(ircfg)
                    simp_modified |= load_from_int(ircfg, bs,
                                                   is_addr_ro_variable)
                    modified |= simp_modified

    ssa = SSADiGraph(ircfg)
    ssa.immutable_ids.update(ssa_forbidden_regs)
    ssa.ssa_variable_to_expr.update(all_ssa_vars)
    ssa.transform(head)
    all_ssa_vars.update(ssa.ssa_variable_to_expr)

    if type_graph == TYPE_GRAPH_IRSSA:
        graph = GraphMiasmIR(ssa.graph, title, None)
        graph.Show()
        return

    if type_graph == TYPE_GRAPH_IRSSAUNSSA:

        cfg_liveness = DiGraphLivenessSSA(ssa.graph)
        cfg_liveness.init_var_info(ir_arch)
        cfg_liveness.compute_liveness()

        UnSSADiGraph(ssa, head, cfg_liveness)
        if simplify:
            modified = True
            while modified:
                modified = False
                modified |= ssa.graph.simplify(expr_simp)
                simp_modified = True
                while simp_modified:
                    simp_modified = False
                    simp_modified |= dead_simp(ir_arch, ssa.graph)
                    simp_modified |= remove_empty_assignblks(ssa.graph)
                    simp_modified |= merge_blocks(ssa.graph, heads)
                    modified |= simp_modified
        graph = GraphMiasmIR(ssa.graph, title, None)
        graph.Show()
Esempio n. 22
0
def dataflow_analysis(addr, block_items, DG):
    machine = guess_machine()
    mn, dis_engine, ira = machine.mn, machine.dis_engine, machine.ira
    #
    # print "Arch", dis_engine
    #
    # fname = idc.GetInputFile()
    # print "file name : ",fname
    # print "machine",machine

    bs = bin_stream_ida()
    mdis = dis_engine(bs)
    mdis.dont_dis_retcall_funcs = []
    mdis.dont_dis = []
    ir_arch = ira(mdis.symbol_pool)
    blocks = mdis.dis_multiblock(addr)
    for block in blocks:
        ir_arch.add_block(block)
    # print ">>asm block",block

    IRs = {}
    for lbl, irblock in ir_arch.blocks.items():
        insr = []
        for assignblk in irblock:
            for dst, src in assignblk.iteritems():
                insr.append(str(dst) + "=" + str(src))
        # print ">>ir",(str(lbl)+"L"),insr
        IRs[str(lbl).split(' ')[0] + "L"] = insr
    # print	 "IRs.keys()",IRs.keys()

    IR_blocks = {}
    no_ir = {}
    # print "block_items",block_items
    for block in blocks:
        # print "block.label",block.label
        isFind = False
        item = str(block.label).split(' ')[0] + "L"
        # item = "0x"+(str(block.label).split(' ')[0].split(':')[1][2:]).lstrip('0') + "L"
        # print "block line number",item
        for block_item in block_items:
            # print block_item
            if item.endswith(block_item):
                isFind = True

        # for irlabel in IRs.keys():
        #	  print irlabel,item
        #	  if irlabel.endswith(item):
        #		  itrm = irlabel
        # print item,IRs[str(block.label) + "L"]
        if IRs.has_key(item):
            if isFind:
                IR_blocks[item] = IRs[item]
            else:
                IR_blocks[item] = IRs[item]
                no_ir[item] = IRs[item]
    # print "yes_ir : ",list(IR_blocks.keys())
    no_keys = list(no_ir.keys())
    # print "no_ir : ",no_keys
    for cur_label in no_keys:
        cur_block = None
        # print ""
        # print ""
        # print "find no_ir	 label is : ",cur_label
        for block in blocks:
            # 去除loc_0000000000413D4C:0x00413d4cL callXXX的情况
            temp_index = str(block.label).split(' ')[0] + "L"
            # print block.label,temp_index
            if temp_index.endswith(cur_label):
                cur_block = block
        if not cur_block is None:
            # print "find no_ir ",cur_block
            IR_blocks, no_ir = rebuild_graph(cur_block, blocks, IR_blocks,
                                             no_ir)
    # print len(no_ir)
    #
    # save_file = "C:/AppData/Setup/IDA_Pro_v6.8/" + idc.GetFunctionName(addr) + ".txt"
    # fp = open(save_file, 'w')
    # print "**********result*************"
    #
    # fp.write( str(DG.edges())	 + "\n")
    # for in_label, in_value in IR_blocks.items():
    #	  fp.write(in_label+"\n")
    #	  for i in in_value:
    #		  fp.write("\t\t"+i+"\n")
    IR_blocks_toDFG = {}
    for key, value in IR_blocks.items():
        if len(key.split(':')) > 1:
            key = key.split(':')[0] + ":0x" + key.split(
                ':')[1].strip()[2:].lstrip('0')
        # print "dg to dfg : ",key
        IR_blocks_toDFG[key] = value
    # print "IR_blocks_toDFG",IR_blocks_toDFG
    # print "CFG edges <<",DG.number_of_edges(),">> :",DG.edges()
    dfg = build_dfg(DG, IR_blocks_toDFG)
    dfg.add_nodes_from(DG.nodes())
    print "CFG edges <<", DG.number_of_edges(), ">> :", DG.edges()
    print "DFG edges <<", dfg.number_of_edges(), ">> :", dfg.edges()
    print "DFG nodes : ", dfg.number_of_nodes()
    return dfg
Esempio n. 23
0
def build_graph(verbose=False, simplify=False, ssa=False, ssa_simplify=False):
    start_addr = idc.ScreenEA()

    machine = guess_machine(addr=start_addr)
    dis_engine, ira = machine.dis_engine, machine.ira


    if verbose:
        print "Arch", dis_engine

    fname = idc.GetInputFile()
    if verbose:
        print fname

    bs = bin_stream_ida()
    mdis = dis_engine(bs)
    ir_arch = ira(mdis.loc_db)

    # populate symbols with ida names
    for addr, name in idautils.Names():
        if name is None:
            continue
        if (mdis.loc_db.get_offset_location(addr) or
            mdis.loc_db.get_name_location(name)):
            # Symbol alias
            continue
        mdis.loc_db.add_location(name, addr)

    if verbose:
        print "start disasm"
    if verbose:
        print hex(addr)

    asmcfg = mdis.dis_multiblock(start_addr)

    entry_points = set([mdis.loc_db.get_offset_location(start_addr)])
    if verbose:
        print "generating graph"
        open('asm_flow.dot', 'w').write(asmcfg.dot())

        print "generating IR... %x" % start_addr

    ircfg = ir_arch.new_ircfg_from_asmcfg(asmcfg)

    if verbose:
        print "IR ok... %x" % start_addr

    for irb in ircfg.blocks.itervalues():
        irs = []
        for assignblk in irb:
            new_assignblk = {
                expr_simp(dst): expr_simp(src)
                for dst, src in assignblk.iteritems()
            }
            irs.append(AssignBlock(new_assignblk, instr=assignblk.instr))
        ircfg.blocks[irb.loc_key] = IRBlock(irb.loc_key, irs)

    if verbose:
        out = ircfg.dot()
        open(os.path.join(tempfile.gettempdir(), 'graph.dot'), 'wb').write(out)
    title = "Miasm IR graph"

    if simplify:
        dead_simp(ir_arch, ircfg)

        ircfg.simplify(expr_simp)
        modified = True
        while modified:
            modified = False
            modified |= dead_simp(ir_arch, ircfg)
            modified |= remove_empty_assignblks(ircfg)
            modified |= merge_blocks(ircfg, entry_points)
        title += " (simplified)"

    graph = GraphMiasmIR(ircfg, title, None)

    if ssa:
        if len(entry_points) != 1:
            raise RuntimeError("Your graph should have only one head")
        head = list(entry_points)[0]
        ssa = SSADiGraph(ircfg)
        ssa.transform(head)
        title += " (SSA)"
        graph = GraphMiasmIR(ssa.graph, title, None)

    if ssa_simplify:
        class IRAOutRegs(ira):
            def get_out_regs(self, block):
                regs_todo = super(self.__class__, self).get_out_regs(block)
                out = {}
                for assignblk in block:
                    for dst in assignblk:
                        reg = self.ssa_var.get(dst, None)
                        if reg is None:
                            continue
                        if reg in regs_todo:
                            out[reg] = dst
                return set(out.values())

        # Add dummy dependecy to uncover out regs affectation
        for loc in ircfg.leaves():
            irblock = ircfg.blocks.get(loc)
            if irblock is None:
                continue
            regs = {}
            for reg in ir_arch.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.blocks[loc] = new_irblock



        ir_arch = IRAOutRegs(mdis.loc_db)

        def is_addr_ro_variable(bs, addr, size):
            """
            Return True if address at @addr is a read-only variable.
            WARNING: Quick & Dirty

            @addr: integer representing the address of the variable
            @size: size in bits

            """
            try:
                _ = bs.getbytes(addr, size/8)
            except IOError:
                return False
            return True


        ir_arch.ssa_var = {}
        index = 0
        modified = True
        ssa_forbidden_regs = set([
            ir_arch.pc,
            ir_arch.IRDst,
            ir_arch.arch.regs.exception_flags
        ])

        head = list(entry_points)[0]
        heads = set([head])
        all_ssa_vars = set()

        propagate_expr = PropagateExpr()


        while modified:
            ssa = SSADiGraph(ircfg)
            ssa.immutable_ids.update(ssa_forbidden_regs)

            ssa.transform(head)

            all_ssa_vars.update(ssa._ssa_variable_to_expr)

            ssa_regs = [reg for reg in ssa.expressions if reg.is_id()]
            ssa_forbidden_regs.update(ssa_regs)


            ir_arch.ssa_var.update(ssa._ssa_variable_to_expr)

            while modified:
                index += 1
                modified = False
                modified |= propagate_expr.propagate(ssa, head)
                modified |= ircfg.simplify(expr_simp)
                simp_modified = True
                while simp_modified:
                    index += 1
                    simp_modified = False
                    simp_modified |= dead_simp(ir_arch, ircfg)
                    index += 1
                    simp_modified |= remove_empty_assignblks(ircfg)
                    simp_modified |= merge_blocks(ircfg, heads)
                    simp_modified |= load_from_int(ircfg, bs, is_addr_ro_variable)
                    modified |= simp_modified
                    index += 1


        merge_blocks(ircfg, heads)
        ssa = SSADiGraph(ircfg)
        ssa.immutable_ids.update(ssa_forbidden_regs)
        ssa.transform(head)
        all_ssa_vars.update(ssa._ssa_variable_to_expr)
        ssa._ssa_variable_to_expr = all_ssa_vars
        dead_simp(ir_arch, ssa.graph)

        title += " (SSA Simplified)"
        graph = GraphMiasmIR(ssa.graph, title, None)


    graph.Show()