Пример #1
0
def match_functions(bv, flirt_path, action, keep_manually_renamed, prefix):
    callback = partial(analysis_callback,
                       bv,
                       action=action,
                       keep_manually_renamed=keep_manually_renamed,
                       prefix=prefix)
    ilog('opening "{}"'.format(flirt_path))
    with open(flirt_path, 'rb') as f:
        flirt = nampa.parse_flirt_file(f)
        ilog('signature name: "{}"'.format(flirt.header.library_name))

        ilog('processing...')
        for funk in bv.functions:
            f_start = funk.start
            f_end = get_function_end(funk)
            buff = bytes(
                bv.read(f_start, f_end - f_start + FUNCTION_TAIL_LENGTH))
            nampa.match_function(flirt, buff, f_start, callback)

        # ff = [f.start for f in bv.functions] + [bv.end]
        # for f_start, f_end in zip(ff[:-1], ff[1:]):
        #     buff = bytes(bv.read(f_start, f_end - f_start))
        #     nampa.match_function(flirt, buff, f_start, callback)

    ilog('done :B')
Пример #2
0
    def _match_all_against_one_signature(self, sig: FlirtSignature):
        # match each function
        self._suggestions = {}
        with open(sig.sig_path, "rb") as sigfile:
            flirt = nampa.parse_flirt_file(sigfile)
            for func in self.project.kb.functions.values():
                func: 'Function'
                if func.is_simprocedure or func.is_plt:
                    continue
                if not func.is_default_name:
                    # it already has a name. skip
                    continue

                start = func.addr
                if self._is_arm:
                    start = start & 0xffff_fffe

                max_block_addr = max(func.block_addrs_set)
                end_block = func.get_block(max_block_addr)
                end = max_block_addr + end_block.size

                if self._is_arm:
                    end = end & 0xffff_fffe

                # load all bytes
                func_bytes = self.project.loader.memory.load(
                    start, end - start + 0x100)
                _callback = partial(self._on_func_matched, func)
                nampa.match_function(flirt, func_bytes, start, _callback)
Пример #3
0
def load_signatures(path: str) -> None:
    """
    Recursively load all FLIRT signatures under a specific path.

    :param path:    Location of FLIRT signatures.
    """

    FLIRT_SIGNATURES_BY_ARCH.clear()
    LIBRARY_TO_SIGNATURES.clear()
    STRING_TO_LIBRARIES.clear()

    for root, _, filenames in os.walk(path):
        for filename in filenames:
            if filename.endswith(".sig"):
                # parse it
                sig_path = os.path.join(root, filename)
                with open(sig_path, "rb") as f:
                    flirt = nampa.parse_flirt_file(f)

                # is there a meta data file?
                meta_path = os.path.join(root, filename[:-4] + ".meta")
                if os.path.isfile(meta_path):
                    # yes!
                    with open(meta_path, "r") as f:
                        meta = json.load(f)

                    arch = meta.get("arch", None)
                    platform = meta.get("platform", None)
                    os_name = meta.get("os", None)
                    os_version = meta.get("os_version", None)
                    compiler = meta.get("compiler", None)
                    compiler_version = meta.get("compiler_version", None)
                    unique_strings = meta.get("unique_strings", None)

                else:
                    # nope... we need to extract information from the signature file
                    # TODO: Convert them to angr-specific strings
                    arch = flirt.header.arch
                    platform = flirt.header.os_types
                    os_name = None
                    os_version = None
                    unique_strings = None
                    compiler = None
                    compiler_version = None

                signature = FlirtSignature(
                    arch,
                    platform,
                    flirt.header.library_name.decode("utf-8"),
                    sig_path,
                    unique_strings=unique_strings,
                    compiler=compiler,
                    compiler_version=compiler_version,
                    os_name=os_name,
                    os_version=os_version,
                )

                FLIRT_SIGNATURES_BY_ARCH[arch].append(signature)

    # fill in LIBRARY_TO_SIGNATURES and STRING_TO_LIBRARIES
    for sigs in FLIRT_SIGNATURES_BY_ARCH.values():
        for sig in sigs:
            LIBRARY_TO_SIGNATURES[sig.sig_name].append(sig)
            if sig.unique_strings:
                for us in sig.unique_strings:
                    STRING_TO_LIBRARIES[us].add(sig.sig_name)
Пример #4
0
def main(fpath):
    sig = nampa.parse_flirt_file(open(fpath, 'rb'))
    for child in sig.root.children:
        recurse(child, level=0)