pep8: scripts

This commit is contained in:
William Ballenthin
2020-07-01 12:42:33 -06:00
parent d23ef48bb6
commit 23e70b4e85
3 changed files with 182 additions and 176 deletions

View File

@@ -1,11 +1,11 @@
''' """
Reformat the given capa rule into a consistent style. Reformat the given capa rule into a consistent style.
Use the -i flag to update the rule in-place. Use the -i flag to update the rule in-place.
Usage: Usage:
$ python capafmt.py -i foo.yml $ python capafmt.py -i foo.yml
''' """
import sys import sys
import logging import logging
@@ -14,22 +14,24 @@ import argparse
import capa.rules import capa.rules
logger = logging.getLogger('capafmt') logger = logging.getLogger("capafmt")
def main(argv=None): def main(argv=None):
if argv is None: if argv is None:
argv = sys.argv[1:] argv = sys.argv[1:]
parser = argparse.ArgumentParser(description='Capa rule formatter.') parser = argparse.ArgumentParser(description="Capa rule formatter.")
parser.add_argument('path', type=str, parser.add_argument("path", type=str, help="Path to rule to format")
help='Path to rule to format') parser.add_argument(
parser.add_argument('-i', '--in-place', action='store_true', dest='in_place', "-i",
help='Format the rule in place, otherwise, write formatted rule to STDOUT') "--in-place",
parser.add_argument('-v', '--verbose', action='store_true', action="store_true",
help='Enable debug logging') dest="in_place",
parser.add_argument('-q', '--quiet', action='store_true', help="Format the rule in place, otherwise, write formatted rule to STDOUT",
help='Disable all output but errors') )
parser.add_argument("-v", "--verbose", action="store_true", help="Enable debug logging")
parser.add_argument("-q", "--quiet", action="store_true", help="Disable all output but errors")
args = parser.parse_args(args=argv) args = parser.parse_args(args=argv)
if args.verbose: if args.verbose:
@@ -40,17 +42,17 @@ def main(argv=None):
level = logging.INFO level = logging.INFO
logging.basicConfig(level=level) logging.basicConfig(level=level)
logging.getLogger('capafmt').setLevel(level) logging.getLogger("capafmt").setLevel(level)
rule = capa.rules.Rule.from_yaml_file(args.path) rule = capa.rules.Rule.from_yaml_file(args.path)
if args.in_place: if args.in_place:
with open(args.path, 'wb') as f: with open(args.path, "wb") as f:
f.write(rule.to_yaml().encode('utf-8')) f.write(rule.to_yaml().encode("utf-8"))
else: else:
print(rule.to_yaml().rstrip("\n")) print(rule.to_yaml().rstrip("\n"))
return 0 return 0
if __name__ == '__main__': if __name__ == "__main__":
sys.exit(main()) sys.exit(main())

View File

@@ -1,10 +1,10 @@
''' """
Check the given capa rules for style issues. Check the given capa rules for style issues.
Usage: Usage:
$ python scripts/lint.py rules/ $ python scripts/lint.py rules/
''' """
import os import os
import os.path import os.path
import sys import sys
@@ -22,41 +22,40 @@ import capa.engine
import capa.features import capa.features
import capa.features.insn import capa.features.insn
logger = logging.getLogger('capa.lint') logger = logging.getLogger("capa.lint")
class Lint(object): class Lint(object):
name = 'lint' name = "lint"
recommendation = '' recommendation = ""
def check_rule(self, ctx, rule): def check_rule(self, ctx, rule):
return False return False
class NameCasing(Lint): class NameCasing(Lint):
name = 'rule name casing' name = "rule name casing"
recommendation = 'Rename rule using to start with lower case letters' recommendation = "Rename rule using to start with lower case letters"
def check_rule(self, ctx, rule): def check_rule(self, ctx, rule):
return (rule.name[0] in string.ascii_uppercase and return rule.name[0] in string.ascii_uppercase and rule.name[1] not in string.ascii_uppercase
rule.name[1] not in string.ascii_uppercase)
class FilenameDoesntMatchRuleName(Lint): class FilenameDoesntMatchRuleName(Lint):
name = 'filename doesn\'t match the rule name' name = "filename doesn't match the rule name"
recommendation = 'Rename rule file to match the rule name, expected: "{:s}", found: "{:s}"' recommendation = 'Rename rule file to match the rule name, expected: "{:s}", found: "{:s}"'
def check_rule(self, ctx, rule): def check_rule(self, ctx, rule):
expected = rule.name expected = rule.name
expected = expected.lower() expected = expected.lower()
expected = expected.replace(' ', '-') expected = expected.replace(" ", "-")
expected = expected.replace('(', '') expected = expected.replace("(", "")
expected = expected.replace(')', '') expected = expected.replace(")", "")
expected = expected.replace('+', '') expected = expected.replace("+", "")
expected = expected.replace('/', '') expected = expected.replace("/", "")
expected = expected + '.yml' expected = expected + ".yml"
found = os.path.basename(rule.meta['capa/path']) found = os.path.basename(rule.meta["capa/path"])
self.recommendation = self.recommendation.format(expected, found) self.recommendation = self.recommendation.format(expected, found)
@@ -64,95 +63,99 @@ class FilenameDoesntMatchRuleName(Lint):
class MissingNamespace(Lint): class MissingNamespace(Lint):
name = 'missing rule namespace' name = "missing rule namespace"
recommendation = 'Add meta.namespace so that the rule is emitted correctly' recommendation = "Add meta.namespace so that the rule is emitted correctly"
def check_rule(self, ctx, rule): def check_rule(self, ctx, rule):
return ('namespace' not in rule.meta and return (
not is_nursery_rule(rule) and "namespace" not in rule.meta
'maec/malware-category' not in rule.meta and and not is_nursery_rule(rule)
'lib' not in rule.meta) and "maec/malware-category" not in rule.meta
and "lib" not in rule.meta
)
class NamespaceDoesntMatchRulePath(Lint): class NamespaceDoesntMatchRulePath(Lint):
name = 'file path doesn\'t match rule namespace' name = "file path doesn't match rule namespace"
recommendation = 'Move rule to appropriate directory or update the namespace' recommendation = "Move rule to appropriate directory or update the namespace"
def check_rule(self, ctx, rule): def check_rule(self, ctx, rule):
# let the other lints catch namespace issues # let the other lints catch namespace issues
if 'namespace' not in rule.meta: if "namespace" not in rule.meta:
return False return False
if is_nursery_rule(rule): if is_nursery_rule(rule):
return False return False
if 'maec/malware-category' in rule.meta: if "maec/malware-category" in rule.meta:
return False return False
if 'lib' in rule.meta: if "lib" in rule.meta:
return False return False
return rule.meta['namespace'] not in posixpath.normpath(rule.meta['capa/path']) return rule.meta["namespace"] not in posixpath.normpath(rule.meta["capa/path"])
class MissingScope(Lint): class MissingScope(Lint):
name = 'missing scope' name = "missing scope"
recommendation = 'Add meta.scope so that the scope is explicit (defaults to `function`)' recommendation = "Add meta.scope so that the scope is explicit (defaults to `function`)"
def check_rule(self, ctx, rule): def check_rule(self, ctx, rule):
return 'scope' not in rule.meta return "scope" not in rule.meta
class InvalidScope(Lint): class InvalidScope(Lint):
name = 'invalid scope' name = "invalid scope"
recommendation = 'Use only file, function, or basic block rule scopes' recommendation = "Use only file, function, or basic block rule scopes"
def check_rule(self, ctx, rule): def check_rule(self, ctx, rule):
return rule.meta.get('scope') not in ('file', 'function', 'basic block') return rule.meta.get("scope") not in ("file", "function", "basic block")
class MissingAuthor(Lint): class MissingAuthor(Lint):
name = 'missing author' name = "missing author"
recommendation = 'Add meta.author so that users know who to contact with questions' recommendation = "Add meta.author so that users know who to contact with questions"
def check_rule(self, ctx, rule): def check_rule(self, ctx, rule):
return 'author' not in rule.meta return "author" not in rule.meta
class MissingExamples(Lint): class MissingExamples(Lint):
name = 'missing examples' name = "missing examples"
recommendation = 'Add meta.examples so that the rule can be tested and verified' recommendation = "Add meta.examples so that the rule can be tested and verified"
def check_rule(self, ctx, rule): def check_rule(self, ctx, rule):
return ('examples' not in rule.meta or return (
not isinstance(rule.meta['examples'], list) or "examples" not in rule.meta
len(rule.meta['examples']) == 0 or or not isinstance(rule.meta["examples"], list)
rule.meta['examples'] == [None]) or len(rule.meta["examples"]) == 0
or rule.meta["examples"] == [None]
)
class MissingExampleOffset(Lint): class MissingExampleOffset(Lint):
name = 'missing example offset' name = "missing example offset"
recommendation = 'Add offset of example function' recommendation = "Add offset of example function"
def check_rule(self, ctx, rule): def check_rule(self, ctx, rule):
if rule.meta.get('scope') in ('function', 'basic block'): if rule.meta.get("scope") in ("function", "basic block"):
for example in rule.meta.get('examples', []): for example in rule.meta.get("examples", []):
if example and ':' not in example: if example and ":" not in example:
logger.debug('example: %s', example) logger.debug("example: %s", example)
return True return True
class ExampleFileDNE(Lint): class ExampleFileDNE(Lint):
name = 'referenced example doesn\'t exist' name = "referenced example doesn't exist"
recommendation = 'Add the referenced example to samples directory ($capa-root/tests/data or supplied via --samples)' recommendation = "Add the referenced example to samples directory ($capa-root/tests/data or supplied via --samples)"
def check_rule(self, ctx, rule): def check_rule(self, ctx, rule):
if not rule.meta.get('examples'): if not rule.meta.get("examples"):
# let the MissingExamples lint catch this case, don't double report. # let the MissingExamples lint catch this case, don't double report.
return False return False
found = False found = False
for example in rule.meta.get('examples', []): for example in rule.meta.get("examples", []):
if example: if example:
example_id = example.partition(':')[0] example_id = example.partition(":")[0]
if example_id in ctx['samples']: if example_id in ctx["samples"]:
found = True found = True
break break
@@ -160,27 +163,27 @@ class ExampleFileDNE(Lint):
class DoesntMatchExample(Lint): class DoesntMatchExample(Lint):
name = 'doesn\'t match on referenced example' name = "doesn't match on referenced example"
recommendation = 'Fix the rule logic or provide a different example' recommendation = "Fix the rule logic or provide a different example"
def check_rule(self, ctx, rule): def check_rule(self, ctx, rule):
if not ctx['is_thorough']: if not ctx["is_thorough"]:
return False return False
for example in rule.meta.get('examples', []): for example in rule.meta.get("examples", []):
example_id = example.partition(':')[0] example_id = example.partition(":")[0]
try: try:
path = ctx['samples'][example_id] path = ctx["samples"][example_id]
except KeyError: except KeyError:
# lint ExampleFileDNE will catch this. # lint ExampleFileDNE will catch this.
# don't double report. # don't double report.
continue continue
try: try:
extractor = capa.main.get_extractor(path, 'auto') extractor = capa.main.get_extractor(path, "auto")
capabilities = capa.main.find_capabilities(ctx['rules'], extractor, disable_progress=True) capabilities = capa.main.find_capabilities(ctx["rules"], extractor, disable_progress=True)
except Exception as e: except Exception as e:
logger.error('failed to extract capabilities: %s %s %s', rule.name, path, e) logger.error("failed to extract capabilities: %s %s %s", rule.name, path, e)
return True return True
if rule.name not in capabilities: if rule.name not in capabilities:
@@ -188,7 +191,7 @@ class DoesntMatchExample(Lint):
class UnusualMetaField(Lint): class UnusualMetaField(Lint):
name = 'unusual meta field' name = "unusual meta field"
recommendation = 'Remove the meta field: "{:s}"' recommendation = 'Remove the meta field: "{:s}"'
def check_rule(self, ctx, rule): def check_rule(self, ctx, rule):
@@ -204,32 +207,32 @@ class UnusualMetaField(Lint):
class LibRuleNotInLibDirectory(Lint): class LibRuleNotInLibDirectory(Lint):
name = 'lib rule not found in lib directory' name = "lib rule not found in lib directory"
recommendation = 'Move the rule to the `lib` subdirectory of the rules path' recommendation = "Move the rule to the `lib` subdirectory of the rules path"
def check_rule(self, ctx, rule): def check_rule(self, ctx, rule):
if is_nursery_rule(rule): if is_nursery_rule(rule):
return False return False
if 'lib' not in rule.meta: if "lib" not in rule.meta:
return False return False
return '/lib/' not in posixpath.normpath(rule.meta['capa/path']) return "/lib/" not in posixpath.normpath(rule.meta["capa/path"])
class LibRuleHasNamespace(Lint): class LibRuleHasNamespace(Lint):
name = 'lib rule has a namespace' name = "lib rule has a namespace"
recommendation = 'Remove the namespace from the rule' recommendation = "Remove the namespace from the rule"
def check_rule(self, ctx, rule): def check_rule(self, ctx, rule):
if 'lib' not in rule.meta: if "lib" not in rule.meta:
return False return False
return 'namespace' in rule.meta return "namespace" in rule.meta
class FeatureStringTooShort(Lint): class FeatureStringTooShort(Lint):
name = 'feature string too short' name = "feature string too short"
recommendation = 'capa only extracts strings with length >= 4; will not match on "{:s}"' recommendation = 'capa only extracts strings with length >= 4; will not match on "{:s}"'
def check_features(self, ctx, features): def check_features(self, ctx, features):
@@ -242,9 +245,11 @@ class FeatureStringTooShort(Lint):
class FeatureNegativeNumberOrOffset(Lint): class FeatureNegativeNumberOrOffset(Lint):
name = 'feature value is negative' name = "feature value is negative"
recommendation = 'capa treats all numbers as unsigned values; you may specify the number\'s two\'s complement ' \ recommendation = (
'representation; will not match on "{:d}"' "capa treats all numbers as unsigned values; you may specify the number's two's complement "
'representation; will not match on "{:d}"'
)
def check_features(self, ctx, features): def check_features(self, ctx, features):
for feature in features: for feature in features:
@@ -318,7 +323,7 @@ def lint_features(ctx, rule):
def get_features(ctx, rule): def get_features(ctx, rule):
# get features from rule and all dependencies including subscopes and matched rules # get features from rule and all dependencies including subscopes and matched rules
features = [] features = []
deps = [ctx['rules'].rules[dep] for dep in rule.get_dependencies()] deps = [ctx["rules"].rules[dep] for dep in rule.get_dependencies()]
for r in [rule] + deps: for r in [rule] + deps:
features.extend(get_rule_features(r)) features.extend(get_rule_features(r))
return features return features
@@ -338,9 +343,7 @@ def get_rule_features(rule):
return features return features
LOGIC_LINTS = ( LOGIC_LINTS = (DoesntMatchExample(),)
DoesntMatchExample(),
)
def lint_logic(ctx, rule): def lint_logic(ctx, rule):
@@ -348,53 +351,58 @@ def lint_logic(ctx, rule):
def is_nursery_rule(rule): def is_nursery_rule(rule):
''' """
The nursery is a spot for rules that have not yet been fully polished. The nursery is a spot for rules that have not yet been fully polished.
For example, they may not have references to public example of a technique. For example, they may not have references to public example of a technique.
Yet, we still want to capture and report on their matches. Yet, we still want to capture and report on their matches.
''' """
return rule.meta.get('capa/nursery') return rule.meta.get("capa/nursery")
def lint_rule(ctx, rule): def lint_rule(ctx, rule):
logger.debug(rule.name) logger.debug(rule.name)
violations = list(itertools.chain( violations = list(
lint_name(ctx, rule), itertools.chain(
lint_scope(ctx, rule), lint_name(ctx, rule),
lint_meta(ctx, rule), lint_scope(ctx, rule),
lint_logic(ctx, rule), lint_meta(ctx, rule),
lint_features(ctx, rule), lint_logic(ctx, rule),
)) lint_features(ctx, rule),
)
)
if len(violations) > 0: if len(violations) > 0:
category = rule.meta.get('rule-category') category = rule.meta.get("rule-category")
print('') print("")
print('%s%s %s' % (' (nursery) ' if is_nursery_rule(rule) else '', print(
rule.name, "%s%s %s"
('(%s)' % category) if category else '')) % (" (nursery) " if is_nursery_rule(rule) else "", rule.name, ("(%s)" % category) if category else "",)
)
level = 'WARN' if is_nursery_rule(rule) else 'FAIL' level = "WARN" if is_nursery_rule(rule) else "FAIL"
for violation in violations: for violation in violations:
print('%s %s: %s: %s' % ( print(
' ' if is_nursery_rule(rule) else '', level, violation.name, violation.recommendation)) "%s %s: %s: %s"
% (" " if is_nursery_rule(rule) else "", level, violation.name, violation.recommendation,)
)
return len(violations) > 0 and not is_nursery_rule(rule) return len(violations) > 0 and not is_nursery_rule(rule)
def lint(ctx, rules): def lint(ctx, rules):
''' """
Args: Args:
samples (Dict[string, string]): map from sample id to path. samples (Dict[string, string]): map from sample id to path.
for each sample, record sample id of sha256, md5, and filename. for each sample, record sample id of sha256, md5, and filename.
see `collect_samples(path)`. see `collect_samples(path)`.
rules (List[Rule]): the rules to lint. rules (List[Rule]): the rules to lint.
''' """
did_suggest_fix = False did_suggest_fix = False
for rule in rules.rules.values(): for rule in rules.rules.values():
if rule.meta.get('capa/subscope-rule', False): if rule.meta.get("capa/subscope-rule", False):
continue continue
did_suggest_fix = lint_rule(ctx, rule) or did_suggest_fix did_suggest_fix = lint_rule(ctx, rule) or did_suggest_fix
@@ -403,27 +411,27 @@ def lint(ctx, rules):
def collect_samples(path): def collect_samples(path):
''' """
recurse through the given path, collecting all file paths, indexed by their content sha256, md5, and filename. recurse through the given path, collecting all file paths, indexed by their content sha256, md5, and filename.
''' """
samples = {} samples = {}
for root, dirs, files in os.walk(path): for root, dirs, files in os.walk(path):
for name in files: for name in files:
if name.endswith('.viv'): if name.endswith(".viv"):
continue continue
if name.endswith('.idb'): if name.endswith(".idb"):
continue continue
if name.endswith('.i64'): if name.endswith(".i64"):
continue continue
if name.endswith('.frz'): if name.endswith(".frz"):
continue continue
if name.endswith('.fnames'): if name.endswith(".fnames"):
continue continue
path = os.path.join(root, name) path = os.path.join(root, name)
try: try:
with open(path, 'rb') as f: with open(path, "rb") as f:
buf = f.read() buf = f.read()
except IOError: except IOError:
continue continue
@@ -447,19 +455,16 @@ def main(argv=None):
if argv is None: if argv is None:
argv = sys.argv[1:] argv = sys.argv[1:]
samples_path = os.path.join(os.path.dirname(__file__), '..', 'tests', 'data') samples_path = os.path.join(os.path.dirname(__file__), "..", "tests", "data")
parser = argparse.ArgumentParser(description='A program.') parser = argparse.ArgumentParser(description="A program.")
parser.add_argument('rules', type=str, parser.add_argument("rules", type=str, help="Path to rules")
help='Path to rules') parser.add_argument("--samples", type=str, default=samples_path, help="Path to samples")
parser.add_argument('--samples', type=str, default=samples_path, parser.add_argument(
help='Path to samples') "--thorough", action="store_true", help="Enable thorough linting - takes more time, but does a better job",
parser.add_argument('--thorough', action='store_true', )
help='Enable thorough linting - takes more time, but does a better job') parser.add_argument("-v", "--verbose", action="store_true", help="Enable debug logging")
parser.add_argument('-v', '--verbose', action='store_true', parser.add_argument("-q", "--quiet", action="store_true", help="Disable all output but errors")
help='Enable debug logging')
parser.add_argument('-q', '--quiet', action='store_true',
help='Disable all output but errors')
args = parser.parse_args(args=argv) args = parser.parse_args(args=argv)
if args.verbose: if args.verbose:
@@ -470,42 +475,42 @@ def main(argv=None):
level = logging.INFO level = logging.INFO
logging.basicConfig(level=level) logging.basicConfig(level=level)
logging.getLogger('capa.lint').setLevel(level) logging.getLogger("capa.lint").setLevel(level)
capa.main.set_vivisect_log_level(logging.CRITICAL) capa.main.set_vivisect_log_level(logging.CRITICAL)
logging.getLogger('capa').setLevel(logging.CRITICAL) logging.getLogger("capa").setLevel(logging.CRITICAL)
try: try:
rules = capa.main.get_rules(args.rules) rules = capa.main.get_rules(args.rules)
rules = capa.rules.RuleSet(rules) rules = capa.rules.RuleSet(rules)
logger.info('successfully loaded %s rules', len(rules)) logger.info("successfully loaded %s rules", len(rules))
except IOError as e: except IOError as e:
logger.error('%s', str(e)) logger.error("%s", str(e))
return -1 return -1
except capa.rules.InvalidRule as e: except capa.rules.InvalidRule as e:
logger.error('%s', str(e)) logger.error("%s", str(e))
return -1 return -1
logger.info('collecting potentially referenced samples') logger.info("collecting potentially referenced samples")
if not os.path.exists(args.samples): if not os.path.exists(args.samples):
logger.error('samples path %s does not exist', args.samples) logger.error("samples path %s does not exist", args.samples)
return -1 return -1
samples = collect_samples(args.samples) samples = collect_samples(args.samples)
ctx = { ctx = {
'samples': samples, "samples": samples,
'rules': rules, "rules": rules,
'is_thorough': args.thorough, "is_thorough": args.thorough,
} }
did_violate = lint(ctx, rules) did_violate = lint(ctx, rules)
if not did_violate: if not did_violate:
logger.info('no suggestions, nice!') logger.info("no suggestions, nice!")
return 0 return 0
else: else:
return 1 return 1
if __name__ == '__main__': if __name__ == "__main__":
sys.exit(main()) sys.exit(main())

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python2 #!/usr/bin/env python2
''' """
show the features extracted by capa. show the features extracted by capa.
''' """
import sys import sys
import logging import logging
@@ -20,28 +20,27 @@ def main(argv=None):
argv = sys.argv[1:] argv = sys.argv[1:]
formats = [ formats = [
('auto', '(default) detect file type automatically'), ("auto", "(default) detect file type automatically"),
('pe', 'Windows PE file'), ("pe", "Windows PE file"),
('sc32', '32-bit shellcode'), ("sc32", "32-bit shellcode"),
('sc64', '64-bit shellcode'), ("sc64", "64-bit shellcode"),
('freeze', 'features previously frozen by capa'), ("freeze", "features previously frozen by capa"),
] ]
format_help = ', '.join(['%s: %s' % (f[0], f[1]) for f in formats]) format_help = ", ".join(["%s: %s" % (f[0], f[1]) for f in formats])
parser = argparse.ArgumentParser(description='detect capabilities in programs.') parser = argparse.ArgumentParser(description="detect capabilities in programs.")
parser.add_argument('sample', type=str, parser.add_argument("sample", type=str, help="Path to sample to analyze")
help='Path to sample to analyze') parser.add_argument(
parser.add_argument('-f', '--format', choices=[f[0] for f in formats], default='auto', "-f", "--format", choices=[f[0] for f in formats], default="auto", help="Select sample format, %s" % format_help
help='Select sample format, %s' % format_help) )
parser.add_argument('-F', '--function', type=lambda x: int(x, 0), parser.add_argument("-F", "--function", type=lambda x: int(x, 0), help="Show features for specific function")
help='Show features for specific function')
args = parser.parse_args(args=argv) args = parser.parse_args(args=argv)
logging.basicConfig(level=logging.INFO) logging.basicConfig(level=logging.INFO)
logging.getLogger().setLevel(logging.INFO) logging.getLogger().setLevel(logging.INFO)
if args.format == 'freeze': if args.format == "freeze":
with open(args.sample, 'rb') as f: with open(args.sample, "rb") as f:
extractor = capa.features.freeze.load(f.read()) extractor = capa.features.freeze.load(f.read())
else: else:
vw = capa.main.get_workspace(args.sample, args.format) vw = capa.main.get_workspace(args.sample, args.format)
@@ -50,32 +49,32 @@ def main(argv=None):
if not args.function: if not args.function:
for feature, va in extractor.extract_file_features(): for feature, va in extractor.extract_file_features():
if va: if va:
print('file: 0x%08x: %s' % (va, feature)) print("file: 0x%08x: %s" % (va, feature))
else: else:
print('file: 0x00000000: %s' % (feature)) print("file: 0x00000000: %s" % (feature))
functions = extractor.get_functions() functions = extractor.get_functions()
if args.function: if args.function:
if args.format == 'freeze': if args.format == "freeze":
functions = filter(lambda f: f == args.function, functions) functions = filter(lambda f: f == args.function, functions)
else: else:
functions = filter(lambda f: f.va == args.function, functions) functions = filter(lambda f: f.va == args.function, functions)
for f in functions: for f in functions:
for feature, va in extractor.extract_function_features(f): for feature, va in extractor.extract_function_features(f):
print('func: 0x%08x: %s' % (va, feature)) print("func: 0x%08x: %s" % (va, feature))
for bb in extractor.get_basic_blocks(f): for bb in extractor.get_basic_blocks(f):
for feature, va in extractor.extract_basic_block_features(f, bb): for feature, va in extractor.extract_basic_block_features(f, bb):
print('bb : 0x%08x: %s' % (va, feature)) print("bb : 0x%08x: %s" % (va, feature))
for insn in extractor.get_instructions(f, bb): for insn in extractor.get_instructions(f, bb):
for feature, va in extractor.extract_insn_features(f, bb, insn): for feature, va in extractor.extract_insn_features(f, bb, insn):
print('insn: 0x%08x: %s' % (va, feature)) print("insn: 0x%08x: %s" % (va, feature))
return 0 return 0
if __name__ == '__main__': if __name__ == "__main__":
sys.exit(main()) sys.exit(main())