From 7f03db9fe44fd69e6660cf5fef5bf9e21dc46b98 Mon Sep 17 00:00:00 2001 From: William Ballenthin Date: Tue, 15 Jun 2021 12:24:01 -0600 Subject: [PATCH] main: dont save .viv by default, unless CAPA_SAVE_WORKSPACE set closes #507 --- capa/features/freeze.py | 2 +- capa/main.py | 20 +++++++++++++------- scripts/bulk-process.py | 3 ++- scripts/capa_as_library.py | 2 +- scripts/lint.py | 2 +- scripts/show-capabilities-by-function.py | 3 ++- 6 files changed, 20 insertions(+), 12 deletions(-) diff --git a/capa/features/freeze.py b/capa/features/freeze.py index c6d4d7f5..4fcf1f52 100644 --- a/capa/features/freeze.py +++ b/capa/features/freeze.py @@ -254,7 +254,7 @@ def main(argv=None): args = parser.parse_args(args=argv) capa.main.handle_common_args(args) - extractor = capa.main.get_extractor(args.sample, args.format, args.backend, sigpaths=args.signatures) + extractor = capa.main.get_extractor(args.sample, args.format, args.backend, args.signatures, False) with open(args.output, "wb") as f: f.write(dump(extractor)) diff --git a/capa/main.py b/capa/main.py index f12aeb29..1c42a50a 100644 --- a/capa/main.py +++ b/capa/main.py @@ -401,7 +401,7 @@ class UnsupportedRuntimeError(RuntimeError): pass -def get_extractor(path, format, backend, sigpaths, disable_progress=False): +def get_extractor(path, format, backend, sigpaths, should_save_workspace, disable_progress=False): """ raises: UnsupportedFormatError: @@ -430,11 +430,15 @@ def get_extractor(path, format, backend, sigpaths, disable_progress=False): format = "sc64" vw = get_workspace(path, format, sigpaths) - try: - vw.saveWorkspace() - except IOError: - # see #168 for discussion around how to handle non-writable directories - logger.info("source directory is not writable, won't save intermediate workspace") + if should_save_workspace: + logger.debug("saving workspace") + try: + vw.saveWorkspace() + except IOError: + # see #168 for discussion around how to handle non-writable directories + logger.info("source directory is not writable, won't save intermediate workspace") + else: + logger.debug("CAPA_SAVE_WORKSPACE unset, not saving workspace") return capa.features.extractors.viv.extractor.VivisectFeatureExtractor(vw, path) @@ -813,8 +817,10 @@ def main(argv=None): extractor = capa.features.freeze.load(f.read()) else: format = args.format + should_save_workspace = os.environ.get("CAPA_SAVE_WORKSPACE") not in ("0", "no", "NO", "n", None) + try: - extractor = get_extractor(args.sample, format, args.backend, args.signatures, disable_progress=args.quiet) + extractor = get_extractor(args.sample, format, args.backend, args.signatures, should_save_workspace, disable_progress=args.quiet) except UnsupportedFormatError: logger.error("-" * 80) logger.error(" Input file does not appear to be a PE file.") diff --git a/scripts/bulk-process.py b/scripts/bulk-process.py index 5939744f..864e8f05 100644 --- a/scripts/bulk-process.py +++ b/scripts/bulk-process.py @@ -95,9 +95,10 @@ def get_capa_results(args): capabilities (dict): the matched capabilities and their result objects """ rules, format, path = args + should_save_workspace = os.environ.get("CAPA_SAVE_WORKSPACE") not in ("0", "no", "NO", "n", None) logger.info("computing capa results for: %s", path) try: - extractor = capa.main.get_extractor(path, format, capa.main.BACKEND_VIV, args.signatures, disable_progress=True) + extractor = capa.main.get_extractor(path, format, capa.main.BACKEND_VIV, args.signatures, should_save_workspace, disable_progress=True) except capa.main.UnsupportedFormatError: # i'm 100% sure if multiprocessing will reliably raise exceptions across process boundaries. # so instead, return an object with explicit success/failure status. diff --git a/scripts/capa_as_library.py b/scripts/capa_as_library.py index 8cc4dee8..3a9eb295 100644 --- a/scripts/capa_as_library.py +++ b/scripts/capa_as_library.py @@ -193,7 +193,7 @@ def render_dictionary(doc): def capa_details(file_path, output_format="dictionary"): # extract features and find capabilities - extractor = capa.main.get_extractor(file_path, "auto", capa.main.BACKEND_VIV, sigpaths=[], disable_progress=True) + extractor = capa.main.get_extractor(file_path, "auto", capa.main.BACKEND_VIV, [], False, disable_progress=True) capabilities, counts = capa.main.find_capabilities(rules, extractor, disable_progress=True) # collect metadata (used only to make rendering more complete) diff --git a/scripts/lint.py b/scripts/lint.py index 19eb93eb..0d765849 100644 --- a/scripts/lint.py +++ b/scripts/lint.py @@ -220,7 +220,7 @@ class DoesntMatchExample(Lint): try: extractor = capa.main.get_extractor( - path, "auto", capa.main.BACKEND_VIV, sigpaths=DEFAULT_SIGNATURES, disable_progress=True + path, "auto", capa.main.BACKEND_VIV, DEFAULT_SIGNATURES, False, disable_progress=True ) capabilities, meta = capa.main.find_capabilities(ctx["rules"], extractor, disable_progress=True) except Exception as e: diff --git a/scripts/show-capabilities-by-function.py b/scripts/show-capabilities-by-function.py index ad0af057..153c567a 100644 --- a/scripts/show-capabilities-by-function.py +++ b/scripts/show-capabilities-by-function.py @@ -152,9 +152,10 @@ def main(argv=None): extractor = capa.features.freeze.load(f.read()) else: format = args.format + should_save_workspace = os.environ.get("CAPA_SAVE_WORKSPACE") not in ("0", "no", "NO", "n", None) try: - extractor = capa.main.get_extractor(args.sample, args.format, args.backend, args.signatures) + extractor = capa.main.get_extractor(args.sample, args.format, args.backend, args.signatures, should_save_workspace) except capa.main.UnsupportedFormatError: logger.error("-" * 80) logger.error(" Input file does not appear to be a PE file.")