예제 #1
0
 def add_node(self, func):
     func_node = FlowGraphNode(self)
     line = DisassemblyTextLine([])
     line.tokens.append(
         InstructionTextToken(InstructionTextTokenType.CodeSymbolToken,
                              func.name,
                              value=func.start,
                              address=func.start))
     func_node.lines = [line]
     self.append(func_node)
예제 #2
0
    def add_func_node(self, func):
        if func in self.func_nodes:
            print(f"{func} already in, returning existing...")
            return self.func_nodes[func]

        func_node = FlowGraphNode(self)
        line = DisassemblyTextLine([])
        line.tokens.append(
            InstructionTextToken(InstructionTextTokenType.CodeSymbolToken,
                                 func.name,
                                 value=func.start,
                                 address=func.start))
        func_node.lines = [line]
        self.append(func_node)
        self.func_nodes[func] = func_node
        return func_node
    def populate_nodes(self):
        func = self.function
        view = self.view

        nodes = {f: FlowGraphNode(self) for f in view.functions}

        for function, node in nodes.items():
            if function.symbol.type == SymbolType.ImportedFunctionSymbol:
                token_type = InstructionTextTokenType.ImportToken
            else:
                token_type = InstructionTextTokenType.CodeSymbolToken

            node.lines = [
                DisassemblyTextLine(
                    [
                        InstructionTextToken(token_type, function.name,
                                             function.start)
                    ],
                    function.start,
                )
            ]

            self.append(node)

        for function in view.functions:
            node = nodes[function]
            for callee in set(function.callees):
                callee_node = nodes[callee]
                node.add_outgoing_edge(BranchType.IndirectBranch, callee_node)
예제 #4
0
    def populate_nodes(self):
        nodes = {}
        # create nodes for every block in the function
        for irb in viewvalues(self.ircfg.blocks):
            node = FlowGraphNode(self)
            nodes[irb.loc_key] = node
            self.append(node)

        for irb in viewvalues(self.ircfg.blocks):
            if not irb:
                continue

            # add edges for each block
            if irb.dst.is_cond():
                if irb.dst.src1.is_loc() and irb.dst.src1.loc_key in nodes:
                    nodes[irb.loc_key].add_outgoing_edge(
                        BranchType.TrueBranch, nodes[irb.dst.src1.loc_key])
                if irb.dst.src2.is_loc() and irb.dst.src2.loc_key in nodes:
                    nodes[irb.loc_key].add_outgoing_edge(
                        BranchType.FalseBranch, nodes[irb.dst.src2.loc_key])
            elif irb.dst.is_loc() and irb.dst.loc_key in nodes:
                nodes[irb.loc_key].add_outgoing_edge(
                    BranchType.UnconditionalBranch, nodes[irb.dst.loc_key])

            lines = []
            irb_token = self.expr_to_token(ExprLoc(irb.loc_key, irb.dst.size))
            irb_token += [
                InstructionTextToken(InstructionTextTokenType.TextToken, ":")
            ]
            lines.append(irb_token)
            for assignblk in irb:
                for dst, src in sorted(viewitems(assignblk)):
                    tokens = []
                    tokens.append(
                        InstructionTextToken(
                            InstructionTextTokenType.TextToken, "   "))
                    tokens += self.expr_to_token(dst)
                    tokens.append(
                        InstructionTextToken(
                            InstructionTextTokenType.TextToken, " = "))
                    tokens += self.expr_to_token(src)
                    lines.append(tokens)
                lines.append("")
            lines.pop()  # remove last empty line
            nodes[irb.loc_key].lines = lines
예제 #5
0
    def populate_nodes(self):
        # Create disassembly text renderers for assembly and IL
        func = self.function
        il = self.il_function
        asm_renderer = DisassemblyTextRenderer(func)
        il_renderer = DisassemblyTextRenderer(il)

        # First create nodes for every block in the function
        nodes = {}
        for block in il:
            node = FlowGraphNode(self)
            node.basic_block = block
            nodes[block.start] = node
            self.append(node)

        # Construct graph
        for block in il:
            il_renderer.basic_block = block

            # Add outgoing edges for the node
            for edge in block.outgoing_edges:
                nodes[block.start].add_outgoing_edge(edge.type,
                                                     nodes[edge.target.start])

            # Get instruction starts for assembly instructions in the block
            start_addr = il[block.start].address
            asm_block = func.get_basic_block_at(start_addr)
            if asm_block is None:
                # If first IL instruction was removed in IL translation, the previous call will fail. Find
                # the block that contains the instruction
                for i in func.basic_blocks:
                    if start_addr >= i.start and start_addr < i.end:
                        asm_block = i
                        break
            asm_instrs = []
            if asm_block is not None:
                asm_renderer.basic_block = asm_block
                start = asm_block.start
                end = asm_block.end
                addr = start
                while addr < end:
                    asm_instrs.append(addr)
                    data = func.view.read(
                        addr, min(asm_block.arch.max_instr_length, end - addr))
                    info = asm_block.arch.get_instruction_info(data, addr)
                    addr += info.length
                    if info.length == 0:
                        break

            # Iterate through instructions in this block and add disassembly lines
            lines = []
            for i in block:
                # Display assembly instructions at or before the current IL instruction
                while len(asm_instrs) > 0 and i.address >= asm_instrs[0]:
                    asm_lines, length = asm_renderer.get_disassembly_text(
                        asm_instrs[0])
                    lines += asm_lines
                    asm_instrs = asm_instrs[1:]

                # Display IL instruction
                il_lines, length = il_renderer.get_disassembly_text(
                    i.instr_index)
                lines += il_lines

            # Go through lines and add addresses to them
            for line in lines:
                if line.il_instruction is None:
                    # For assembly lines, show address
                    line.tokens.insert(
                        0,
                        InstructionTextToken(
                            InstructionTextTokenType.AddressDisplayToken,
                            "%.8x" % line.address, line.address))
                    line.tokens.insert(
                        1,
                        InstructionTextToken(
                            InstructionTextTokenType.TextToken, "  "))
                else:
                    # For IL lines, show IL instruction index
                    line.tokens.insert(
                        0,
                        InstructionTextToken(
                            InstructionTextTokenType.AnnotationToken, "%8s" %
                            ("[%d]" % line.il_instruction.instr_index)))
                    line.tokens.insert(
                        1,
                        InstructionTextToken(
                            InstructionTextTokenType.AnnotationToken,
                            "   => "))

            nodes[block.start].lines = lines