Esempio n. 1
0
 def simplify(self, ircfg, head):
     ssa = self.ircfg_to_ssa(ircfg, head)
     ssa = self.do_simplify_loop(ssa, head)
     ircfg = self.ssa_to_unssa(ssa, head)
     ircfg_simplifier = IRCFGSimplifierCommon(self.ir_arch)
     ircfg_simplifier.simplify(ircfg, head)
     return ircfg
Esempio n. 2
0
        def simplify(self, ircfg, head):
            ssa = self.ircfg_to_ssa(ircfg, head)
            ssa = self.do_simplify_loop(ssa, head)
            ircfg = self.ssa_to_unssa(ssa, head)

            ircfg_simplifier = IRCFGSimplifierCommon(self.ir_arch)
            ircfg_simplifier.deadremoval.add_expr_to_original_expr(ssa.ssa_variable_to_expr)
            ircfg_simplifier.simplify(ircfg, head)
            return ircfg
Esempio n. 3
0
 def getNormalIRCFG(self):
     if self.normalIRCFG is not None:
         return self.normalIRCFG
     else:
         self.normalIRCFG = self.normalIRA.new_ircfg_from_asmcfg(self.cfg)
         simplifier = IRCFGSimplifierCommon(self.normalIRA)
         simplifier.simplify(self.normalIRCFG, self.head)
         self.normalDefUse = DiGraphDefUse(
             ReachingDefinitions(self.normalIRCFG))
         return self.normalIRCFG
Esempio n. 4
0
        def simplify(self, ircfg, head):
            ssa = self.ircfg_to_ssa(ircfg, head)
            ssa = self.do_simplify_loop(ssa, head)
            ircfg = self.ssa_to_unssa(ssa, head)

            if args.stack2var:
                replace_stack_vars(self.ir_arch, ircfg)

            ircfg_simplifier = IRCFGSimplifierCommon(self.ir_arch)
            ircfg_simplifier.simplify(ircfg, head)
            return ircfg
Esempio n. 5
0
File: full.py Progetto: yarhrn/miasm
        def simplify(self, ircfg, head):
            ssa = self.ircfg_to_ssa(ircfg, head)
            ssa = self.do_simplify_loop(ssa, head)
            ircfg = self.ssa_to_unssa(ssa, head)

            if args.stack2var:
                replace_stack_vars(self.ir_arch, ircfg)

            ircfg_simplifier = IRCFGSimplifierCommon(self.ir_arch)
            ircfg_simplifier.simplify(ircfg, head)
            return ircfg
Esempio n. 6
0
 def getSSAIRCFG(self):
     if self.ssaIRCFG is not None:
         return self.ssaIRCFG
     else:
         self.ssaIRCFG = self.ssaIRA.new_ircfg_from_asmcfg(self.cfg)
         simplifier = IRCFGSimplifierCommon(self.ssaIRA)
         simplifier.simplify(self.ssaIRCFG, self.head)
         ssa = SSADiGraph(self.ssaIRCFG)
         ssa.transform(self.head)
         self.ssaDefUse = DiGraphDefUse(ReachingDefinitions(self.ssaIRCFG))
         return self.ssaIRCFG
Esempio n. 7
0
        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
Esempio n. 8
0
        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
Esempio n. 9
0
 def __init__(self, raw, address):
     self.cont = Container.fallback_container(raw + b'\xC3',
                                              vm=None,
                                              addr=address)
     self.address = address
     self.machine = Machine('x86_64')
     self.mdis = self.machine.dis_engine(self.cont.bin_stream,
                                         loc_db=self.cont.loc_db)
     self.asmcfg = self.mdis.dis_multiblock(self.address)
     self.head = self.asmcfg.getby_offset(self.address).loc_key
     self.orignal_ira = self.machine.ira(self.mdis.loc_db)
     self.orginal_ircfg = self.orignal_ira.new_ircfg_from_asmcfg(
         self.asmcfg)
     self.common_simplifier = IRCFGSimplifierCommon(self.orignal_ira)
     self.common_simplifier.simplify(self.orginal_ircfg, self.head)
     self.custom_ira1 = IRADelModCallStack(self.mdis.loc_db)
     self.custom_ira2 = IRAOutRegs(self.mdis.loc_db)
     self.ircfg = self.custom_ira1.new_ircfg_from_asmcfg(self.asmcfg)
     self.simplify()
Esempio n. 10
0
class Block:
    def __init__(self, raw, address):
        self.cont = Container.fallback_container(raw + b'\xC3',
                                                 vm=None,
                                                 addr=address)
        self.address = address
        self.machine = Machine('x86_64')
        self.mdis = self.machine.dis_engine(self.cont.bin_stream,
                                            loc_db=self.cont.loc_db)
        self.asmcfg = self.mdis.dis_multiblock(self.address)
        self.head = self.asmcfg.getby_offset(self.address).loc_key
        self.orignal_ira = self.machine.ira(self.mdis.loc_db)
        self.orginal_ircfg = self.orignal_ira.new_ircfg_from_asmcfg(
            self.asmcfg)
        self.common_simplifier = IRCFGSimplifierCommon(self.orignal_ira)
        self.common_simplifier.simplify(self.orginal_ircfg, self.head)
        self.custom_ira1 = IRADelModCallStack(self.mdis.loc_db)
        self.custom_ira2 = IRAOutRegs(self.mdis.loc_db)
        self.ircfg = self.custom_ira1.new_ircfg_from_asmcfg(self.asmcfg)
        self.simplify()

    def simplify(self):
        simplifier = IRCFGSimplifierCommon(self.custom_ira1)
        simplifier.simplify(self.ircfg, self.head)
        for loc in self.ircfg.leaves():
            irblock = self.ircfg.blocks.get(loc)
            if irblock is None:
                continue
            regs = {}
            for reg in self.custom_ira1.get_out_regs(irblock):
                regs[reg] = reg
            assignblks = list(irblock)
            newAssignBlk = AssignBlock(regs, assignblks[-1].instr)
            assignblks.append(newAssignBlk)
            newIrBlock = IRBlock(irblock.loc_key, assignblks)
            self.ircfg.blocks[loc] = newIrBlock
        simplifier = CustomIRCFGSimplifierSSA(self.custom_ira2)
        simplifier.simplify(self.ircfg, self.head)
Esempio n. 11
0
 def simplify(self):
     simplifier = IRCFGSimplifierCommon(self.custom_ira1)
     simplifier.simplify(self.ircfg, self.head)
     for loc in self.ircfg.leaves():
         irblock = self.ircfg.blocks.get(loc)
         if irblock is None:
             continue
         regs = {}
         for reg in self.custom_ira1.get_out_regs(irblock):
             regs[reg] = reg
         assignblks = list(irblock)
         newAssignBlk = AssignBlock(regs, assignblks[-1].instr)
         assignblks.append(newAssignBlk)
         newIrBlock = IRBlock(irblock.loc_key, assignblks)
         self.ircfg.blocks[loc] = newIrBlock
     simplifier = CustomIRCFGSimplifierSSA(self.custom_ira2)
     simplifier.simplify(self.ircfg, self.head)
Esempio n. 12
0
 def getMaxIRCFG(self):
     if self.maxIRCFG is not None:
         return self.maxIRCFG
     else:
         self.maxIRCFG = self.maxIRA1.new_ircfg_from_asmcfg(self.cfg)
         simplifier = IRCFGSimplifierCommon(self.maxIRA1)
         simplifier.simplify(self.maxIRCFG, self.head)
         for loc in self.maxIRCFG.leaves():
             irblock = self.maxIRCFG.blocks.get(loc)
             if irblock is None:
                 continue
             regs = {}
             for reg in self.maxIRA1.get_out_regs(irblock):
                 regs[reg] = reg
             assignblks = list(irblock)
             newAssignBlk = AssignBlock(regs, assignblks[-1].instr)
             assignblks.append(newAssignBlk)
             newIrBlock = IRBlock(irblock.loc_key, assignblks)
             self.maxIRCFG.blocks[loc] = newIrBlock
         simplifier = CustomIRCFGSimplifierSSA(self.maxIRA2)
         simplifier.simplify(self.maxIRCFG, self.head)
         self.maxDefUse = DiGraphDefUse(ReachingDefinitions(self.maxIRCFG))
         return self.maxIRCFG
Esempio n. 13
0
            ir_arch.add_asmblock_to_ircfg(block, ircfg)
            ir_arch_a.add_asmblock_to_ircfg(block, ircfg_a)

    log.info("Print blocks (without analyse)")
    for label, block in viewitems(ir_arch.blocks):
        print(block)

    log.info("Gen Graph... %x" % ad)

    log.info("Print blocks (with analyse)")
    for label, block in viewitems(ir_arch_a.blocks):
        print(block)

    if args.simplify > 0:
        log.info("Simplify...")
        ircfg_simplifier = IRCFGSimplifierCommon(ir_arch_a)
        ircfg_simplifier.simplify(ircfg_a, head)
        log.info("ok...")

    if args.defuse:
        reachings = ReachingDefinitions(ircfg_a)
        open('graph_defuse.dot', 'w').write(DiGraphDefUse(reachings).dot())

    out = ircfg.dot()
    open('graph_irflow_raw.dot', 'w').write(out)
    out = ircfg_a.dot()
    open('graph_irflow.dot', 'w').write(out)

    if args.ssa and not args.propagexpr:
        if len(entry_points) != 1:
            raise RuntimeError("Your graph should have only one head")
Esempio n. 14
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. 15
0
            lifter.add_asmblock_to_ircfg(block, ircfg)
            lifter_model_call.add_asmblock_to_ircfg(block, ircfg_a)

    log.info("Print blocks (without analyse)")
    for label, block in viewitems(ircfg.blocks):
        print(block)

    log.info("Gen Graph... %x" % ad)

    log.info("Print blocks (with analyse)")
    for label, block in viewitems(ircfg_a.blocks):
        print(block)

    if args.simplify > 0:
        log.info("Simplify...")
        ircfg_simplifier = IRCFGSimplifierCommon(lifter_model_call)
        ircfg_simplifier.simplify(ircfg_a, head)
        log.info("ok...")

    if args.defuse:
        reachings = ReachingDefinitions(ircfg_a)
        open('graph_defuse.dot', 'w').write(DiGraphDefUse(reachings).dot())

    out = ircfg.dot()
    open('graph_irflow_raw.dot', 'w').write(out)
    out = ircfg_a.dot()
    open('graph_irflow.dot', 'w').write(out)

    if args.ssa and not args.propagexpr:
        if len(entry_points) != 1:
            raise RuntimeError("Your graph should have only one head")
Esempio n. 16
0
            ir_arch.add_asmblock_to_ircfg(block, ircfg)
            ir_arch_a.add_asmblock_to_ircfg(block, ircfg_a)

    log.info("Print blocks (without analyse)")
    for label, block in viewitems(ir_arch.blocks):
        print(block)

    log.info("Gen Graph... %x" % ad)

    log.info("Print blocks (with analyse)")
    for label, block in viewitems(ir_arch_a.blocks):
        print(block)

    if args.simplify > 0:
        log.info("Simplify...")
        ircfg_simplifier = IRCFGSimplifierCommon(ir_arch_a)
        ircfg_simplifier.simplify(ircfg_a, head)
        log.info("ok...")

    if args.defuse:
        reachings = ReachingDefinitions(ircfg_a)
        open('graph_defuse.dot', 'w').write(DiGraphDefUse(reachings).dot())

    out = ircfg.dot()
    open('graph_irflow_raw.dot', 'w').write(out)
    out = ircfg_a.dot()
    open('graph_irflow.dot', 'w').write(out)

    if args.ssa and not args.propagexpr:
        if len(entry_points) != 1:
            raise RuntimeError("Your graph should have only one head")
Esempio n. 17
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. 18
0
    def get_graph(self):
        simplify = self.simplify
        dontmodstack = self.dontmodstack
        loadmemint = self.loadmemint
        type_graph = self.type_graph

        bin_str = ""
        for s in self.data.segments:
            bin_str += self.data.read(s.start, len(s))
            # add padding between each segment
            if s.end != self.data.end:
                bin_str += '\x00' * (((s.end | 0xfff) + 1) - s.end)

        bs = bin_stream_str(input_str=bin_str, base_address=self.data.start)
        machine = Machine(archs[self.data.arch.name])
        mdis = machine.dis_engine(bs)

        asmcfg = mdis.dis_multiblock(self.function.start)
        entry_points = set(
            [mdis.loc_db.get_offset_location(self.function.start)])

        class IRADelModCallStack(machine.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

        ir_arch = IRADelModCallStack(mdis.loc_db)
        ircfg = ir_arch.new_ircfg_from_asmcfg(asmcfg)

        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)

        head = list(entry_points)[0]

        if simplify:
            ircfg_simplifier = IRCFGSimplifierCommon(ir_arch)
            ircfg_simplifier.simplify(ircfg, head)

        if type_graph == TYPE_GRAPH_IR:
            return MiasmIRGraph(self.add_names(ircfg))

        class IRAOutRegs(machine.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 loadmemint:
                    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

        # dirty patch to synchronize nodes and blocks lists in ircfg
        nodes_to_del = [
            node for node in ircfg.nodes() if not node in ircfg.blocks
        ]
        for node in nodes_to_del:
            ircfg.del_node(node)

        head = list(entry_points)[0]
        simplifier = CustomIRCFGSimplifierSSA(ir_arch)
        ircfg = simplifier.simplify(ircfg, head)

        return MiasmIRGraph(self.add_names(ircfg))