def register_flirt_signature_analyzers(vw, sigpaths): """ args: vw (vivisect.VivWorkspace): sigpaths (List[str]): file system paths of .sig/.pat files """ # lazy import enables us to only require flirt here and not in IDA, for example import flirt import viv_utils.flirt for sigpath in sigpaths: try: sigs = load_flirt_signature(sigpath) except ValueError as e: logger.warning("could not load %s: %s", sigpath, str(e)) continue logger.debug("flirt: sig count: %d", len(sigs)) with timing("flirt: compiling sigs"): matcher = flirt.compile(sigs) analyzer = viv_utils.flirt.FlirtFunctionAnalyzer(matcher, sigpath) logger.debug("registering viv function analyzer: %s", repr(analyzer)) viv_utils.flirt.addFlirtFunctionAnalyzer(vw, analyzer)
def test_parse_pat(__EH_prolog3_pat): sigs = flirt.parse_pat(__EH_prolog3_pat) matcher = flirt.compile(sigs) matches = matcher.match(__EH_prolog3_catch_align) assert len(matches) == 1 match = matches[0] assert match.names[0] == ("__EH_prolog3_catch_align", "public", 0) assert str(match) == 'FlirtSignature("__EH_prolog3_catch_align")'
def register_flirt_signature_analyzers(vw, sigpaths): """ args: vw (vivisect.VivWorkspace): sigpaths (List[str]): file system paths of .sig/.pat files """ import viv_utils.flirt for sigpath in sigpaths: sigs = load_flirt_signature(sigpath) logger.debug("flirt: sig count: %d", len(sigs)) with timing("flirt: compiling sigs"): matcher = flirt.compile(sigs) analyzer = viv_utils.flirt.FlirtFunctionAnalyzer(matcher, sigpath) logger.debug("registering viv function analyzer: %s", repr(analyzer)) viv_utils.flirt.addFlirtFunctionAnalyzer(vw, analyzer)
def main(argv=None): if argv is None: argv = sys.argv[1:] parser = argparse.ArgumentParser(description="FLIRT match each function") parser.add_argument("sample", type=str, help="Path to sample to analyze") parser.add_argument( "-F", "--function", type=lambda x: int(x, 0x10), help="match a specific function by VA, rather than add functions", ) parser.add_argument( "--signature", action="append", dest="signatures", type=str, default=[], help= "use the given signatures to identify library functions, file system paths to .sig/.pat files.", ) parser.add_argument("-d", "--debug", action="store_true", help="Enable debugging output on STDERR") parser.add_argument("-q", "--quiet", action="store_true", help="Disable all output but errors") args = parser.parse_args(args=argv) if args.quiet: logging.basicConfig(level=logging.ERROR) logging.getLogger().setLevel(logging.ERROR) elif args.debug: logging.basicConfig(level=logging.DEBUG) logging.getLogger().setLevel(logging.DEBUG) else: logging.basicConfig(level=logging.INFO) logging.getLogger().setLevel(logging.INFO) # disable vivisect-related logging, it's verbose and not relevant for capa users capa.main.set_vivisect_log_level(logging.CRITICAL) analyzers = [] for sigpath in args.signatures: sigs = capa.main.load_flirt_signature(sigpath) with capa.main.timing("flirt: compiling sigs"): matcher = flirt.compile(sigs) analyzer = viv_utils.flirt.FlirtFunctionAnalyzer(matcher, sigpath) logger.debug("registering viv function analyzer: %s", repr(analyzer)) analyzers.append(analyzer) vw = viv_utils.getWorkspace(args.sample, analyze=True, should_save=False) functions = vw.getFunctions() if args.function: functions = [args.function] for function in functions: logger.debug("matching function: 0x%04x", function) for analyzer in analyzers: name = viv_utils.flirt.match_function_flirt_signatures( analyzer.matcher, vw, function) if name: print("0x%04x: %s" % (function, name)) return 0