''' Freeze capa features. Example usage: freeze_features.py freeze_features.py samples\benign ''' import os import sys import time import logging import argparse from scripts.testbed import FREEZE_EXTENSION from capa.features.freeze import main as freeze_features # only process files with these extensions TARGET_EXTENSIONS = [ '.mal_', '.exe_', '.dll_', '.sys_' ] logger = logging.getLogger('check_rule') def freeze(input_path, reprocess): if not os.path.exists(input_path): raise IOError('%s does not exist or cannot be accessed' % input_path) if os.path.isfile(input_path): outfile = '%s%s' % (input_path, FREEZE_EXTENSION) freeze_file(input_path, outfile, reprocess) elif os.path.isdir(input_path): logger.info('freezing features of %s files in %s', '|'.join(TARGET_EXTENSIONS), input_path) for root, dirs, files in os.walk(input_path): for file in files: if not os.path.splitext(file)[1] in TARGET_EXTENSIONS: logger.debug('skipping non-target file: %s', file) continue path = os.path.join(root, file) outfile = '%s%s' % (path, FREEZE_EXTENSION) freeze_file(path, outfile, reprocess) def freeze_file(path, output, reprocess=False): logger.info('freezing features of %s', path) if os.path.exists(output) and not reprocess: logger.info('%s already exists, provide -r argument to reprocess', output) return try: freeze_features([path, output]) # args: sample, output except Exception as e: logger.error('could not freeze features for %s: %s', path, str(e)) def main(argv=None): if argv is None: argv = sys.argv[1:] parser = argparse.ArgumentParser(description='Freeze capa features of a file or of files in a directory') parser.add_argument('file_path', type=str, help='Path to file or directory to analyze') parser.add_argument('-r', '--reprocess', action='store_true', default=False, help='Overwrite existing analysis') parser.add_argument('-v', '--verbose', action='store_true', help='Enable verbose output') 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.verbose: logging.basicConfig(level=logging.DEBUG) logging.getLogger().setLevel(logging.DEBUG) else: logging.basicConfig(level=logging.INFO) logging.getLogger().setLevel(logging.INFO) time0 = time.time() try: freeze(args.file_path, args.reprocess) except IOError as e: logger.error('%s', str(e)) return -1 logger.info('freezing features took %d seconds', time.time() - time0) return 0 if __name__ == '__main__': sys.exit(main())