(self, formatting=None, show_edges: bool = True, show_addresses: bool = True,
               show_bytes: bool = False, ascii_only: Optional[bool] = None)
return '\n'.join(buf)
Render the disassembly to a string, with optional edges and addresses.

        Color will be added by default, if enabled. To disable color pass an empty formatting dict.
Render the disassembly to a string, with optional edges and addresses.
Render the disassembly to a string with optional edges and addresses .
def render(self, formatting=None, show_edges: bool = True, show_addresses: bool = True,
               show_bytes: bool = False, ascii_only: Optional[bool] = None) -> str:
        """
        Render the disassembly to a string, with optional edges and addresses.

        Color will be added by default, if enabled. To disable color pass an empty formatting dict.
        """
        max_bytes_per_line = 5
        bytes_width = max_bytes_per_line*3+1
        a2ln = defaultdict(list)
        buf = []

        if formatting is None:
            formatting = {
                'colors': {
                    'address':       'gray',
                    'bytes':         'cyan',
                    'edge':          'yellow',
                    Label:           'bright_yellow',
                    ConstantOperand: 'cyan',
                    MemoryOperand:   'yellow',
                    Comment:         'gray',
                    Hook:            'green',
                } if ansi_color_enabled else {},
                'format_callback': lambda item, s: ansi_color(s, formatting['colors'].get(type(item), None))
            }

        def col(item: Any) -> Optional[str]:
            try:
                return formatting['colors'][item]
            except KeyError:
                return None

        def format_address(addr: int, color: bool = True) -> str:
            if not show_addresses:
                return ''
            a, pad = f'{addr:x}', '  '
            return (ansi_color(a, col('address')) if color else a) + pad

        def format_bytes(data: bytes, color: bool = True) -> str:
            s = ' '.join(f'{x:02x}' for x in data).ljust(bytes_width)
            return ansi_color(s, col('bytes')) if color else s

        def format_comment(text: str, color: bool = True) -> str:
            s = ' ; ' + text
            return ansi_color(s, col(Comment)) if color else s

        comment = None

        for item in self.raw_result:
            if isinstance(item, BlockStart):
                if len(buf) > 0:
                    buf.append('')
            elif isinstance(item, Label):
                pad = len(format_address(item.addr, False)) * ' '
                if show_bytes:
                    pad += bytes_width * ' '
                buf.append(pad + item.render(formatting)[0])
            elif isinstance(item, Comment):
                comment = item
            elif isinstance(item, Hook):
                a2ln[item.addr].append(len(buf))
                buf.append(format_address(item.addr) + item.render(formatting)[0])
            elif isinstance(item, Instruction):
                a2ln[item.addr].append(len(buf))
                lines = []

                # Chop instruction bytes into line segments
                p, insn_bytes = 0, []
                while show_bytes and p < len(item.insn.bytes):
                    s = item.insn.bytes[p:p+min(len(item.insn.bytes)-p, max_bytes_per_line)]
                    p += len(s)
                    insn_bytes.append(s)

                # Format the instruction's address, bytes, disassembly, and comment
                s_plain = format_address(item.addr, False)
                s = format_address(item.addr)
                if show_bytes:
                    bytes_column = len(s_plain)
                    s_plain += format_bytes(insn_bytes[0], False)
                    s += format_bytes(insn_bytes[0])
                s_plain += item.render()[0]
                s += item.render(formatting)[0]
                if comment is not None:
                    comment_column = len(s_plain)
                    s += format_comment(comment.text[0])
                lines.append(s)

                # Add additional lines of instruction bytes
                for i in range(1, len(insn_bytes)):
                    lines.append(' ' * bytes_column + format_bytes(insn_bytes[i]))

                # Add additional lines of comments
                if comment is not None:
                    for i in range(1, len(comment.text)):
                        if len(lines) <= i:
                            lines.append(' ' * comment_column)
                        lines[i] += format_comment(comment.text[i])
                    comment = None

                buf.extend(lines)
            else:
                buf.append(''.join(item.render(formatting)))

        if self._graph is not None and show_edges and buf:
            edges_by_line = set()
            for edge in self._graph.edges.items():
                from_block, to_block = edge[0]
                if from_block.size is None:
                    continue
                if to_block.addr != from_block.addr + from_block.size:
                    from_addr = edge[1]['ins_addr']
                    to_addr = to_block.addr
                    if not (from_addr in a2ln and to_addr in a2ln):
                        continue
                    for f in a2ln[from_addr]:
                        for t in a2ln[to_addr]:
                            edges_by_line.add((f, t))

            # Render block edges, to a reference buffer for tracking and output buffer for display
            edge_buf = ['' for _ in buf]
            ref_buf = ['' for _ in buf]
            edge_col = col('edge')
            for f, t in sorted(edges_by_line, key=lambda e: abs(e[0]-e[1])):
                add_edge_to_buffer(edge_buf, ref_buf, f, t, lambda s: ansi_color(s, edge_col), ascii_only=ascii_only)
                add_edge_to_buffer(ref_buf, ref_buf, f, t, ascii_only=ascii_only)
            max_edge_depth = max(map(len, ref_buf))

            # Justify edge and combine with disassembly
            for i, line in enumerate(buf):
                buf[i] = ' ' * (max_edge_depth - len(ref_buf[i])) + edge_buf[i] + line

        return '\n'.join(buf)
def render ( self , formatting = None , show_edges : bool = True , show_addresses : bool = True , show_bytes : bool = False , ascii_only : Optional [ bool ] = None ) -> str : max_bytes_per_line = 5 bytes_width = max_bytes_per_line * 3 + 1 a2ln = defaultdict ( list ) buf = [ ] if formatting is None : formatting = { 'colors' : { 'address' : 'gray' , 'bytes' : 'cyan' , 'edge' : 'yellow' , Label : 'bright_yellow' , ConstantOperand : 'cyan' , MemoryOperand : 'yellow' , Comment : 'gray' , Hook : 'green' , } if ansi_color_enabled else { } , 'format_callback' : lambda item , s : ansi_color ( s , formatting [ 'colors' ] . get ( type ( item ) , None ) ) } def col ( item : Any ) -> Optional [ str ] : try : return formatting [ 'colors' ] [ item ] except KeyError : return None def format_address ( addr : int , color : bool = True ) -> str : if not show_addresses : return '' a , pad = f'{addr:x}' , '  ' return ( ansi_color ( a , col ( 'address' ) ) if color else a ) + pad def format_bytes ( data : bytes , color : bool = True ) -> str : s = ' ' . join ( f'{x:02x}' for x in data ) . ljust ( bytes_width ) return ansi_color ( s , col ( 'bytes' ) ) if color else s def format_comment ( text : str , color : bool = True ) -> str : s = ' ; ' + text return ansi_color ( s , col ( Comment ) ) if color else s comment = None for item in self . raw_result : if isinstance ( item , BlockStart ) : if len ( buf ) > 0 : buf . append ( '' ) elif isinstance ( item , Label ) : pad = len ( format_address ( item . addr , False ) ) * ' ' if show_bytes : pad += bytes_width * ' ' buf . append ( pad + item . render ( formatting ) [ 0 ] ) elif isinstance ( item , Comment ) : comment = item elif isinstance ( item , Hook ) : a2ln [ item . addr ] . append ( len ( buf ) ) buf . append ( format_address ( item . addr ) + item . render ( formatting ) [ 0 ] ) elif isinstance ( item , Instruction ) : a2ln [ item . addr ] . append ( len ( buf ) ) lines = [ ] # Chop instruction bytes into line segments p , insn_bytes = 0 , [ ] while show_bytes and p < len ( item . insn . bytes ) : s = item . insn . bytes [ p : p + min ( len ( item . insn . bytes ) - p , max_bytes_per_line ) ] p += len ( s ) insn_bytes . append ( s ) # Format the instruction's address, bytes, disassembly, and comment s_plain = format_address ( item . addr , False ) s = format_address ( item . addr ) if show_bytes : bytes_column = len ( s_plain ) s_plain += format_bytes ( insn_bytes [ 0 ] , False ) s += format_bytes ( insn_bytes [ 0 ] ) s_plain += item . render ( ) [ 0 ] s += item . render ( formatting ) [ 0 ] if comment is not None : comment_column = len ( s_plain ) s += format_comment ( comment . text [ 0 ] ) lines . append ( s ) # Add additional lines of instruction bytes for i in range ( 1 , len ( insn_bytes ) ) : lines . append ( ' ' * bytes_column + format_bytes ( insn_bytes [ i ] ) ) # Add additional lines of comments if comment is not None : for i in range ( 1 , len ( comment . text ) ) : if len ( lines ) <= i : lines . append ( ' ' * comment_column ) lines [ i ] += format_comment ( comment . text [ i ] ) comment = None buf . extend ( lines ) else : buf . append ( '' . join ( item . render ( formatting ) ) ) if self . _graph is not None and show_edges and buf : edges_by_line = set ( ) for edge in self . _graph . edges . items ( ) : from_block , to_block = edge [ 0 ] if from_block . size is None : continue if to_block . addr != from_block . addr + from_block . size : from_addr = edge [ 1 ] [ 'ins_addr' ] to_addr = to_block . addr if not ( from_addr in a2ln and to_addr in a2ln ) : continue for f in a2ln [ from_addr ] : for t in a2ln [ to_addr ] : edges_by_line . add ( ( f , t ) ) # Render block edges, to a reference buffer for tracking and output buffer for display edge_buf = [ '' for _ in buf ] ref_buf = [ '' for _ in buf ] edge_col = col ( 'edge' ) for f , t in sorted ( edges_by_line , key = lambda e : abs ( e [ 0 ] - e [ 1 ] ) ) : add_edge_to_buffer ( edge_buf , ref_buf , f , t , lambda s : ansi_color ( s , edge_col ) , ascii_only = ascii_only ) add_edge_to_buffer ( ref_buf , ref_buf , f , t , ascii_only = ascii_only ) max_edge_depth = max ( map ( len , ref_buf ) ) # Justify edge and combine with disassembly for i , line in enumerate ( buf ) : buf [ i ] = ' ' * ( max_edge_depth - len ( ref_buf [ i ] ) ) + edge_buf [ i ] + line return '\n' . join ( buf )