Ejemplo n.º 1
0
def render_flowgraphs(view):
    global _graphs
    for function in view.functions:
        g = function.create_graph()
        g.layout_and_wait()

        f = FlowGraph()
        _graphs.append(f)
        f.function = function
        f_bbs = {}

        for node in g.nodes:
            n = FlowGraphNode(f)

            for line in node.lines:
                if line.tokens[
                        0].type == InstructionTextTokenType.AnnotationToken:
                    n.lines += [DisassemblyTextLine(line.tokens, line.address)]
                else:
                    n.lines += [
                        DisassemblyTextLine(
                            line.tokens[:next((i
                                               for i in range(len(line.tokens))
                                               if line.tokens[i].type ==
                                               InstructionTextTokenType.
                                               AnnotationToken), None)],
                            line.address)
                    ]

                f_bbs[line.address] = n

            f.append(n)

        for i in range(len(f.nodes)):
            is_jumpi = 'JUMPI' in str(f.nodes[i].lines[-1])

            for edge in g.nodes[i].outgoing_edges:
                if edge.type == BranchType.IndirectBranch and is_jumpi:
                    f.nodes[i].add_outgoing_edge(
                        BranchType.TrueBranch,
                        f_bbs[edge.target.basic_block.start])
                else:
                    f.nodes[i].add_outgoing_edge(
                        edge.type, f_bbs[edge.target.basic_block.start])

        f.show(function.name)
Ejemplo n.º 2
0
 def _build_function_text(self, function):
     res = \
      DisassemblyTextLine ([
        InstructionTextToken(
         InstructionTextTokenType.AddressDisplayToken,
         "{:#x}".format(function.start),
         value=function.start,
        ),
        InstructionTextToken(
         InstructionTextTokenType.OperandSeparatorToken,
         " @ "
        ),
        InstructionTextToken(
         InstructionTextTokenType.CodeSymbolToken,
         demangle_name(self.bv, function.name),
         function.start
        )
       ])
     return res
def generate_graphs(view: BinaryView):
    for func in view.functions:
        bbs = {}
        g = FlowGraph()
        g.function = func
        n = FlowGraphNode(g)
        for bb in func.basic_blocks:
            if bb.start not in bbs:
                print(f"bbs[{bb.start:x}] = n")
                bbs[bb.start] = n
            else:
                print("g.append(n)")
                g.append(n)
                print(f"n = bbs[{bb.start:x}]")
                n = bbs[bb.start]
            current_addr = bb.start
            for instr in bb:
                if instr[0][0].text not in ("nop", "jmp") or (
                        instr[0][0].text == "jmp" and not bb.outgoing_edges):
                    print(instr[0])
                    n.lines += [
                        DisassemblyTextLine(instr[0], address=current_addr)
                    ]

                current_addr += instr[1]
                if (instr[0][0].text == "jmp" and bb.outgoing_edges
                        and bb.outgoing_edges[0].target.start in bbs
                        and bb.outgoing_edges[0].target in bb.dominators):
                    n.add_outgoing_edge(
                        BranchType.UnconditionalBranch,
                        bbs[bb.outgoing_edges[0].target.start],
                    )
                else:
                    # Keep using the same FlowGraphNode
                    pass
        g.append(n)
        g.layout_and_wait()
        g.show(func.name)
Ejemplo n.º 4
0
	def load_raw_disassembly(self, start_ip):
		# Read a few instructions from rip and disassemble them
		inst_count = 50

		arch_dis = self.debug_state.remote_arch
		rip = self.debug_state.ip

		# Assume the worst, just in case
		read_length = arch_dis.max_instr_length * inst_count
		data = self.debug_state.memory_view.read(start_ip, read_length)

		lines = []

		# Append header line
		tokens = [InstructionTextToken(InstructionTextTokenType.TextToken, "(Code not backed by loaded file, showing only raw disassembly)")]
		contents = DisassemblyTextLine(tokens, start_ip)
		if (major == 2):
			line = LinearDisassemblyLine(LinearDisassemblyLineType.BasicLineType, None, None, contents)
		else:
			line = LinearDisassemblyLine(LinearDisassemblyLineType.BasicLineType, None, None, 0, contents)
		lines.append(line)

		total_read = 0
		for i in range(inst_count):
			line_addr = start_ip + total_read
			(insn_tokens, length) = arch_dis.get_instruction_text(data[total_read:], line_addr)

			if insn_tokens is None:
				insn_tokens = [InstructionTextToken(InstructionTextTokenType.TextToken, "??")]
				length = arch_dis.instr_alignment
				if length == 0:
					length = 1

			tokens = []
			color = HighlightStandardColor.NoHighlightColor
			if line_addr == rip:
				if self.debug_state.breakpoints.contains_absolute(start_ip + total_read):
					# Breakpoint & pc
					tokens.append(InstructionTextToken(InstructionTextTokenType.TagToken, self.debug_state.ui.get_breakpoint_tag_type().icon + ">", width=5))
					color = HighlightStandardColor.RedHighlightColor
				else:
					# PC
					tokens.append(InstructionTextToken(InstructionTextTokenType.TextToken, " ==> "))
					color = HighlightStandardColor.BlueHighlightColor
			else:
				if self.debug_state.breakpoints.contains_absolute(start_ip + total_read):
					# Breakpoint
					tokens.append(InstructionTextToken(InstructionTextTokenType.TagToken, self.debug_state.ui.get_breakpoint_tag_type().icon, width=5))
					color = HighlightStandardColor.RedHighlightColor
				else:
					# Regular line
					tokens.append(InstructionTextToken(InstructionTextTokenType.TextToken, "     "))
			# Address
			tokens.append(InstructionTextToken(InstructionTextTokenType.AddressDisplayToken, hex(line_addr)[2:], line_addr))
			tokens.append(InstructionTextToken(InstructionTextTokenType.TextToken, "  "))
			tokens.extend(insn_tokens)

			# Convert to linear disassembly line
			contents = DisassemblyTextLine(tokens, line_addr, color=color)
			if (major == 2):
				line = LinearDisassemblyLine(LinearDisassemblyLineType.CodeDisassemblyLineType, None, None, contents)
			else:
				line = LinearDisassemblyLine(LinearDisassemblyLineType.CodeDisassemblyLineType, None, None, 0, contents)
			lines.append(line)

			total_read += length

		# terrible workaround for libshiboken conversion issue
		for line in lines:
			# line is LinearDisassemblyLine
			last_tok = line.contents.tokens[-1]
			#if last_tok.type != InstructionTextTokenType.PossibleAddressToken: continue
			#if last_tok.width != 18: continue # strlen("0xFFFFFFFFFFFFFFF0")
			if last_tok.size != 8: continue
			#print('fixing: %s' % line)
			last_tok.value &= 0x7FFFFFFFFFFFFFFF

		self.binary_text.setLines(lines)
Ejemplo n.º 5
0
    def update_raw_disassembly(self):
        if self.debug_view is None:
            return

        # Read a few instructions from rip and disassemble them
        inst_count = 50

        rip = self.state.ip
        arch_dis = self.state.bv.arch
        if arch_dis.name == 'armv7':
            if self.state.adapter.reg_read('cpsr') & 0x20:
                arch_dis = binaryninja.Architecture['thumb2']

        # Assume the worst, just in case
        read_length = arch_dis.max_instr_length * inst_count
        data = self.state.memory_view.read(rip, read_length)

        lines = []

        # Append header line
        tokens = [
            InstructionTextToken(
                InstructionTextTokenType.TextToken,
                "(Code not backed by loaded file, showing only raw disassembly)"
            )
        ]
        contents = DisassemblyTextLine(tokens, rip)
        line = LinearDisassemblyLine(LinearDisassemblyLineType.BasicLineType,
                                     None, None, 0, contents)
        lines.append(line)

        total_read = 0
        for i in range(inst_count):
            line_addr = rip + total_read
            (insn_tokens,
             length) = arch_dis.get_instruction_text(data[total_read:],
                                                     line_addr)

            if insn_tokens is None:
                insn_tokens = [
                    InstructionTextToken(InstructionTextTokenType.TextToken,
                                         "??")
                ]
                length = arch_dis.instr_alignment
                if length == 0:
                    length = 1

            tokens = []
            color = HighlightStandardColor.NoHighlightColor
            if i == 0:
                if self.state.breakpoints.contains_absolute(rip + total_read):
                    # Breakpoint & pc
                    tokens.append(
                        InstructionTextToken(
                            InstructionTextTokenType.TagToken,
                            self.state.bv.tag_types["Crashes"].icon + ">",
                            width=5))
                    color = HighlightStandardColor.RedHighlightColor
                else:
                    # PC
                    tokens.append(
                        InstructionTextToken(
                            InstructionTextTokenType.TextToken, " ==> "))
                    color = HighlightStandardColor.BlueHighlightColor
            else:
                if self.state.breakpoints.contains_absolute(rip + total_read):
                    # Breakpoint
                    tokens.append(
                        InstructionTextToken(
                            InstructionTextTokenType.TagToken,
                            self.state.bv.tag_types["Crashes"].icon,
                            width=5))
                    color = HighlightStandardColor.RedHighlightColor
                else:
                    # Regular line
                    tokens.append(
                        InstructionTextToken(
                            InstructionTextTokenType.TextToken, "     "))
            # Address
            tokens.append(
                InstructionTextToken(
                    InstructionTextTokenType.AddressDisplayToken,
                    hex(line_addr)[2:], line_addr))
            tokens.append(
                InstructionTextToken(InstructionTextTokenType.TextToken, "  "))
            tokens.extend(insn_tokens)

            # Convert to linear disassembly line
            contents = DisassemblyTextLine(tokens, line_addr, color=color)
            line = LinearDisassemblyLine(
                LinearDisassemblyLineType.CodeDisassemblyLineType, None, None,
                0, contents)
            lines.append(line)

            total_read += length

        self.debug_view.setRawDisassembly(True, lines)
Ejemplo n.º 6
0
    def perform_get_lines_for_data(self, ctxt, view: BinaryView, addr: int,
                                   type_: Type, prefix: list, width: int,
                                   context):
        from_bytes = _get_from_bytes(view)

        symbol: Symbol = view.get_symbol_at(addr)

        cfstring = view.types.get('CFString')

        if cfstring is None:
            log_debug('CFString is not defined; how did we even get here?')
            return [DisassemblyTextLine(prefix, addr)]

        cfstring = cfstring.structure

        buffer = from_bytes(
            view.read(addr + cfstring['buffer'].offset, view.address_size))

        info = from_bytes(
            view.read(addr + cfstring['info'].offset,
                      cfstring['info'].type.width))

        length = from_bytes(
            view.read(addr + cfstring['length'].offset,
                      cfstring['length'].type.width))

        if info & 0xff == 0xc8:
            info_string = 'noinline,default,nofree,NI'
        elif info & 0xff == 0xd0:
            info_string = 'noinline,default,nofree,EUI'
        else:
            info_string = (
                f'{_cfstring_allocator_properties[(info >> 5) & 0x3]},'
                f'{"U" if info & 16 else ""}'
                f'{"N" if info & 8 else ""}'
                f'{"L" if info & 4 else ""}'
                f'{"I" if info & 1 else ""}')

        if 'U' not in info_string:
            string = view.get_ascii_string_at(buffer, 0)

            if string is None:
                log_debug('string returned None; how did we even get here?')
                return [DisassemblyTextLine(prefix, addr)]

            string = string.value
        else:
            string = view.read(buffer, length * 2)

        if symbol is None:
            name = f'data_{addr:x}'
        else:
            name = symbol.short_name

        prefix = [
            InstructionTextToken(InstructionTextTokenType.TypeNameToken,
                                 'CFString'),
            InstructionTextToken(InstructionTextTokenType.TextToken, ' '),
            InstructionTextToken(InstructionTextTokenType.AnnotationToken,
                                 f'{{{info_string}}}'),
            InstructionTextToken(InstructionTextTokenType.TextToken, ' '),
            InstructionTextToken(InstructionTextTokenType.DataSymbolToken,
                                 name, addr),
            InstructionTextToken(InstructionTextTokenType.TextToken, ' = '),
            InstructionTextToken(InstructionTextTokenType.StringToken,
                                 f'{string!r}', buffer),
            InstructionTextToken(InstructionTextTokenType.TextToken, ' ')
        ]
        return [DisassemblyTextLine(prefix, addr)]
Ejemplo n.º 7
0
	def load_raw_disassembly(self, start_ip):
		# Read a few instructions from rip and disassemble them
		inst_count = 50

		arch_dis = self.debug_state.remote_arch
		rip = self.debug_state.ip

		# Assume the worst, just in case
		read_length = arch_dis.max_instr_length * inst_count
		data = self.debug_state.memory_view.read(start_ip, read_length)

		lines = []

		# Append header line
		tokens = [InstructionTextToken(InstructionTextTokenType.TextToken, "(Code not backed by loaded file, showing only raw disassembly)")]
		contents = DisassemblyTextLine(tokens, start_ip)
		line = LinearDisassemblyLine(LinearDisassemblyLineType.BasicLineType, None, None, contents)
		lines.append(line)

		total_read = 0
		for i in range(inst_count):
			line_addr = start_ip + total_read
			(insn_tokens, length) = arch_dis.get_instruction_text(data[total_read:], line_addr)

			if insn_tokens is None:
				insn_tokens = [InstructionTextToken(InstructionTextTokenType.TextToken, "??")]
				length = arch_dis.instr_alignment
				if length == 0:
					length = 1

			# terrible libshiboken workaround, see #101
			for tok in insn_tokens:
				if tok.value.bit_length() == 64:
					tok.value ^= 0x8000000000000000

			tokens = []
			color = HighlightStandardColor.NoHighlightColor
			if line_addr == rip:
				if self.debug_state.breakpoints.contains_absolute(start_ip + total_read):
					# Breakpoint & pc
					tokens.append(InstructionTextToken(InstructionTextTokenType.TagToken, self.debug_state.ui.get_breakpoint_tag_type().icon + ">", width=5))
					color = HighlightStandardColor.RedHighlightColor
				else:
					# PC
					tokens.append(InstructionTextToken(InstructionTextTokenType.TextToken, " ==> "))
					color = HighlightStandardColor.BlueHighlightColor
			else:
				if self.debug_state.breakpoints.contains_absolute(start_ip + total_read):
					# Breakpoint
					tokens.append(InstructionTextToken(InstructionTextTokenType.TagToken, self.debug_state.ui.get_breakpoint_tag_type().icon, width=5))
					color = HighlightStandardColor.RedHighlightColor
				else:
					# Regular line
					tokens.append(InstructionTextToken(InstructionTextTokenType.TextToken, "     "))
			# Address
			tokens.append(InstructionTextToken(InstructionTextTokenType.AddressDisplayToken, hex(line_addr)[2:], line_addr))
			tokens.append(InstructionTextToken(InstructionTextTokenType.TextToken, "  "))
			tokens.extend(insn_tokens)

			# Convert to linear disassembly line
			contents = DisassemblyTextLine(tokens, line_addr, color=color)
			line = LinearDisassemblyLine(LinearDisassemblyLineType.CodeDisassemblyLineType, None, None, contents)
			lines.append(line)

			total_read += length

		self.binary_text.setLines(lines)
Ejemplo n.º 8
0
    def populate_nodes(self):
        func = self.function
        mlil = self.mlil

        method_t = self.view.types['method_t']

        settings = DisassemblySettings()
        settings.set_option('ShowVariableTypesWhenAssigned')
        renderer = DisassemblyTextRenderer(mlil, settings)

        nodes = {}
        for block in mlil:
            node = FlowGraphNode(self)
            node.basic_block = block
            nodes[block.start] = node
            self.append(node)

        # Construct graph
        for block in mlil:
            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 = mlil[block.start].address

            # Iterate through instructions in this block and add disassembly lines
            lines = []

            if mlil.basic_blocks.index(block) == 0:
                lines.append(
                    DisassemblyTextLine([
                        InstructionTextToken(
                            InstructionTextTokenType.CodeSymbolToken,
                            func.name, func.start),
                        InstructionTextToken(
                            InstructionTextTokenType.TextToken, ':')
                    ], func.start))

            for i in block:
                # Display IL instruction
                il_lines, length = renderer.get_disassembly_text(i.instr_index)
                if (i.operation
                        in (MediumLevelILOperation.MLIL_CALL,
                            MediumLevelILOperation.MLIL_TAILCALL,
                            MediumLevelILOperation.MLIL_TAILCALL_UNTYPED)
                        and i.dest.operation
                        in (MediumLevelILOperation.MLIL_CONST,
                            MediumLevelILOperation.MLIL_CONST_PTR,
                            MediumLevelILOperation.MLIL_IMPORT)):
                    if self._objc_retain and i.dest.constant == self._objc_retain.address:
                        self.render_retain(i, il_lines)

                    elif self._objc_release and i.dest.constant == self._objc_release.address:
                        self.render_release(i, il_lines)

                    elif self._objc_msgSend and i.dest.constant == self._objc_msgSend.address:
                        self.render_msgSend(i, il_lines, renderer)

                    elif self._objc_msgSend_stret and i.dest.constant == self._objc_msgSend_stret.address:
                        self.render_msgSend(i, il_lines, renderer, stret=True)

                    elif self._objc_msgSendSuper and i.dest.constant == self._objc_msgSendSuper.address:
                        self.render_msgSend(i, il_lines, renderer, super_=True)

                    elif (self._objc_msgSendSuper_stret and i.dest.constant
                          == self._objc_msgSendSuper_stret.address):
                        self.render_msgSend(i,
                                            il_lines,
                                            renderer,
                                            stret=True,
                                            super_=True)

                lines += il_lines

            nodes[block.start].lines = lines
Ejemplo n.º 9
0
    def update_raw_disassembly(self):
        # Read a few instructions from rip and disassemble them
        inst_count = 50
        if self.state.bv.arch.name == 'x86_64':
            rip = self.state.adapter.reg_read('rip')
            # Assume the worst, just in case
            read_length = self.state.bv.arch.max_instr_length * inst_count
            data = self.state.memory_view.read(rip, read_length)

            lines = []

            # Append header line
            tokens = [
                InstructionTextToken(
                    InstructionTextTokenType.TextToken,
                    "(Code not backed by loaded file, showing only raw disassembly)"
                )
            ]
            contents = DisassemblyTextLine(tokens, rip)
            line = LinearDisassemblyLine(
                LinearDisassemblyLineType.BasicLineType, None, None, 0,
                contents)
            lines.append(line)

            total_read = 0
            for i in range(inst_count):
                line_addr = rip + total_read
                (insn_tokens,
                 length) = self.state.bv.arch.get_instruction_text(
                     data[total_read:], line_addr)

                tokens = []
                color = HighlightStandardColor.NoHighlightColor
                if i == 0:
                    if (rip + total_read) in self.state.breakpoints:
                        # Breakpoint & pc
                        tokens.append(
                            InstructionTextToken(
                                InstructionTextTokenType.TagToken,
                                self.state.bv.tag_types["Crashes"].icon + ">",
                                width=5))
                        color = HighlightStandardColor.RedHighlightColor
                    else:
                        # PC
                        tokens.append(
                            InstructionTextToken(
                                InstructionTextTokenType.TextToken, " ==> "))
                        color = HighlightStandardColor.BlueHighlightColor
                else:
                    if (rip + total_read) in self.state.breakpoints:
                        # Breakpoint
                        tokens.append(
                            InstructionTextToken(
                                InstructionTextTokenType.TagToken,
                                self.state.bv.tag_types["Crashes"].icon,
                                width=5))
                        color = HighlightStandardColor.RedHighlightColor
                    else:
                        # Regular line
                        tokens.append(
                            InstructionTextToken(
                                InstructionTextTokenType.TextToken, "     "))
                # Address
                tokens.append(
                    InstructionTextToken(
                        InstructionTextTokenType.AddressDisplayToken,
                        hex(line_addr)[2:], line_addr))
                tokens.append(
                    InstructionTextToken(InstructionTextTokenType.TextToken,
                                         "  "))
                tokens.extend(insn_tokens)

                # Convert to linear disassembly line
                contents = DisassemblyTextLine(tokens, line_addr, color=color)
                line = LinearDisassemblyLine(
                    LinearDisassemblyLineType.CodeDisassemblyLineType, None,
                    None, 0, contents)
                lines.append(line)

                total_read += length

            self.debug_view.setRawDisassembly(True, lines)

        else:
            raise NotImplementedError('only x86_64 so far')