(cmsg, function_manager=None, project=None, all_func_addrs=None)
return obj
:param cmsg: The data to instanciate the <Function> from.

        :return Function:
:param cmsg: The data to instanciate the <Function> from.
: param cmsg : The data to instanciate the <Function > from .
def parse_from_cmsg(cmsg, function_manager=None, project=None, all_func_addrs=None):
        """
        :param cmsg: The data to instanciate the <Function> from.

        :return Function:
        """
        # delayed import
        from .function import Function  # pylint:disable=import-outside-toplevel

        obj = Function(
            function_manager,
            cmsg.ea,
            name=cmsg.name,
            is_plt=cmsg.is_plt,
            syscall=cmsg.is_syscall,
            is_simprocedure=cmsg.is_simprocedure,
            returning=cmsg.returning,
            alignment=cmsg.alignment,
            binary_name=cmsg.binary_name,
        )
        obj._project = project
        obj.normalized = cmsg.normalized

        # signature matched?
        if cmsg.matched_from == function_pb2.Function.UNMATCHED:
            obj.from_signature = None
        elif cmsg.matched_from == function_pb2.Function.FLIRT:
            obj.from_signature = "flirt"
        else:
            raise ValueError(f"Cannot convert SignatureSource enum {cmsg.matched_from} to Function.from_signature.")

        # blocks
        blocks = {}
        for b in cmsg.blocks:
            if project is not None and project.is_hooked(b.ea):
                # create a HookNode
                block = HookNode(b.ea, 0, project.hooked_by(b.ea))
            else:
                block = BlockNode(b.ea, b.size, bytestr=b.bytes)
            blocks[block.addr] = block
        external_addrs = set(cmsg.external_functions)  # addresses of referenced blocks or nodes that are not inside
                                                       # the current function

        # edges
        edges = {}
        fake_return_edges = defaultdict(list)
        for edge_cmsg in cmsg.graph.edges:
            try:
                src = FunctionParser._get_block_or_func(
                    edge_cmsg.src_ea,
                    blocks,
                    external_addrs,
                    function_manager,
                    project,
                    all_func_addrs=all_func_addrs,
                )
            except KeyError:
                raise KeyError("Address of the edge source %#x is not found." % edge_cmsg.src_ea)

            edge_type = func_edge_type_from_pb(edge_cmsg.jumpkind)
            assert edge_type is not None

            dst = None
            dst_addr = edge_cmsg.dst_ea
            if dst_addr not in blocks:
                if (edge_type == 'call' # call has to go to either a HookNode or a function
                    or (all_func_addrs is not None and dst_addr in all_func_addrs)  # jumps to another function
                ):
                    if function_manager is not None:
                        # get a function
                        dst = FunctionParser._get_func(dst_addr, function_manager)
                    else:
                        l.warning("About to get or create a function at %#x, but function_manager is not provided. "
                                  "Will create a block instead.", dst_addr)

            if dst is None:
                # create a block instead
                try:
                    dst = FunctionParser._get_block_or_func(
                        dst_addr,
                        blocks,
                        external_addrs,
                        function_manager,
                        project,
                        all_func_addrs=all_func_addrs,
                    )
                except KeyError:
                    raise KeyError("Address of the edge destination %#x is not found." % edge_cmsg.dst_ea)

            data = dict((k, pickle.loads(v)) for k, v in edge_cmsg.data.items())
            data['outside'] = edge_cmsg.is_outside
            data['ins_addr'] = edge_cmsg.ins_addr
            data['stmt_idx'] = edge_cmsg.stmt_idx
            if edge_type == 'fake_return':
                fake_return_edges[edge_cmsg.src_ea].append((src, dst, data))
            else:
                edges[(edge_cmsg.src_ea, dst_addr, edge_type)] = (src, dst, data)

        added_nodes = set()
        for k, v in edges.items():
            src_addr, dst_addr, edge_type = k
            src, dst, data = v

            outside = data.get('outside', False)
            ins_addr = data.get('ins_addr', None)
            stmt_idx = data.get('stmt_idx', None)
            added_nodes.add(src)
            added_nodes.add(dst)
            if edge_type in ('transition', 'exception'):
                obj._transit_to(src, dst, outside=outside, ins_addr=ins_addr, stmt_idx=stmt_idx,
                                is_exception=edge_type == 'exception')
            elif edge_type == 'call':
                # find the corresponding fake_ret edge
                fake_ret_edge = next(iter(edge_ for edge_ in fake_return_edges[src_addr]
                                          if edge_[1].addr == src.addr + src.size), None)
                if dst is None:
                    l.warning("The destination function %#x does not exist, and it cannot be created since function "
                              "manager is not provided. Please consider passing in a function manager to rebuild this "
                              "graph.", dst_addr)
                else:
                    if isinstance(dst, Function):
                        obj._call_to(src, dst, None if fake_ret_edge is None else fake_ret_edge[1],
                                     stmt_idx=stmt_idx,
                                     ins_addr=ins_addr,
                                     return_to_outside=fake_ret_edge is None,
                                     )
                    if fake_ret_edge is not None:
                        fakeret_src, fakeret_dst, fakeret_data = fake_ret_edge
                        added_nodes.add(fakeret_dst)
                        obj._fakeret_to(fakeret_src, fakeret_dst,
                                        confirmed=fakeret_data.get('confirmed'),
                                        to_outside=fakeret_data.get('outside', None))
            elif edge_type == 'fake_return':
                pass

        # add leftover blocks
        for block in blocks.values():
            if block not in added_nodes:
                obj._register_nodes(True, block)

        return obj
def parse_from_cmsg ( cmsg , function_manager = None , project = None , all_func_addrs = None ) : # delayed import from . function import Function # pylint:disable=import-outside-toplevel obj = Function ( function_manager , cmsg . ea , name = cmsg . name , is_plt = cmsg . is_plt , syscall = cmsg . is_syscall , is_simprocedure = cmsg . is_simprocedure , returning = cmsg . returning , alignment = cmsg . alignment , binary_name = cmsg . binary_name , ) obj . _project = project obj . normalized = cmsg . normalized # signature matched? if cmsg . matched_from == function_pb2 . Function . UNMATCHED : obj . from_signature = None elif cmsg . matched_from == function_pb2 . Function . FLIRT : obj . from_signature = "flirt" else : raise ValueError ( f"Cannot convert SignatureSource enum {cmsg.matched_from} to Function.from_signature." ) # blocks blocks = { } for b in cmsg . blocks : if project is not None and project . is_hooked ( b . ea ) : # create a HookNode block = HookNode ( b . ea , 0 , project . hooked_by ( b . ea ) ) else : block = BlockNode ( b . ea , b . size , bytestr = b . bytes ) blocks [ block . addr ] = block external_addrs = set ( cmsg . external_functions ) # addresses of referenced blocks or nodes that are not inside # the current function # edges edges = { } fake_return_edges = defaultdict ( list ) for edge_cmsg in cmsg . graph . edges : try : src = FunctionParser . _get_block_or_func ( edge_cmsg . src_ea , blocks , external_addrs , function_manager , project , all_func_addrs = all_func_addrs , ) except KeyError : raise KeyError ( "Address of the edge source %#x is not found." % edge_cmsg . src_ea ) edge_type = func_edge_type_from_pb ( edge_cmsg . jumpkind ) assert edge_type is not None dst = None dst_addr = edge_cmsg . dst_ea if dst_addr not in blocks : if ( edge_type == 'call' # call has to go to either a HookNode or a function or ( all_func_addrs is not None and dst_addr in all_func_addrs ) # jumps to another function ) : if function_manager is not None : # get a function dst = FunctionParser . _get_func ( dst_addr , function_manager ) else : l . warning ( "About to get or create a function at %#x, but function_manager is not provided. " "Will create a block instead." , dst_addr ) if dst is None : # create a block instead try : dst = FunctionParser . _get_block_or_func ( dst_addr , blocks , external_addrs , function_manager , project , all_func_addrs = all_func_addrs , ) except KeyError : raise KeyError ( "Address of the edge destination %#x is not found." % edge_cmsg . dst_ea ) data = dict ( ( k , pickle . loads ( v ) ) for k , v in edge_cmsg . data . items ( ) ) data [ 'outside' ] = edge_cmsg . is_outside data [ 'ins_addr' ] = edge_cmsg . ins_addr data [ 'stmt_idx' ] = edge_cmsg . stmt_idx if edge_type == 'fake_return' : fake_return_edges [ edge_cmsg . src_ea ] . append ( ( src , dst , data ) ) else : edges [ ( edge_cmsg . src_ea , dst_addr , edge_type ) ] = ( src , dst , data ) added_nodes = set ( ) for k , v in edges . items ( ) : src_addr , dst_addr , edge_type = k src , dst , data = v outside = data . get ( 'outside' , False ) ins_addr = data . get ( 'ins_addr' , None ) stmt_idx = data . get ( 'stmt_idx' , None ) added_nodes . add ( src ) added_nodes . add ( dst ) if edge_type in ( 'transition' , 'exception' ) : obj . _transit_to ( src , dst , outside = outside , ins_addr = ins_addr , stmt_idx = stmt_idx , is_exception = edge_type == 'exception' ) elif edge_type == 'call' : # find the corresponding fake_ret edge fake_ret_edge = next ( iter ( edge_ for edge_ in fake_return_edges [ src_addr ] if edge_ [ 1 ] . addr == src . addr + src . size ) , None ) if dst is None : l . warning ( "The destination function %#x does not exist, and it cannot be created since function " "manager is not provided. Please consider passing in a function manager to rebuild this " "graph." , dst_addr ) else : if isinstance ( dst , Function ) : obj . _call_to ( src , dst , None if fake_ret_edge is None else fake_ret_edge [ 1 ] , stmt_idx = stmt_idx , ins_addr = ins_addr , return_to_outside = fake_ret_edge is None , ) if fake_ret_edge is not None : fakeret_src , fakeret_dst , fakeret_data = fake_ret_edge added_nodes . add ( fakeret_dst ) obj . _fakeret_to ( fakeret_src , fakeret_dst , confirmed = fakeret_data . get ( 'confirmed' ) , to_outside = fakeret_data . get ( 'outside' , None ) ) elif edge_type == 'fake_return' : pass # add leftover blocks for block in blocks . values ( ) : if block not in added_nodes : obj . _register_nodes ( True , block ) return obj