diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ce50fcc..3566bb00 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ It includes many new rules, including all new techniques introduced in MITRE ATT - main: auto detect shellcode based on file extension #516 @mr-tz - main: use FLIRT signatures to identify and ignore library code #446 @williballenthin - explorer: IDA 7.6 support #497 @williballenthin +- scripts: capa2yara.py convert capa rules to YARA rules #561 @ruppde ### New Rules (69) @@ -95,13 +96,14 @@ It includes many new rules, including all new techniques introduced in MITRE ATT - explorer: document IDA 7.6sp1 as alternative to the patch #536 @Ana06 - rules: update ATT&CK and MBC mappings https://github.com/fireeye/capa-rules/pull/317 @williballenthin - tests: update test cases and caching #545 @mr-tz -- linter: summarize results at the end #571 @williballenthin +- show-features: don't show features from library functions #569 @williballenthin ### Development - ci: add capa release link to capa-rules tag #517 @Ana06 - ci, changelog: update `New Rules` section in CHANGELOG automatically https://github.com/fireeye/capa-rules/pull/374 #549 @Ana06 - ci, changelog: support multiple author in sync GH https://github.com/fireeye/capa-rules/pull/378 @Ana06 +- ci, lint: check statements for single child statements #563 @mr-tz ### Raw diffs diff --git a/rules b/rules index b06c2a31..021b7efd 160000 --- a/rules +++ b/rules @@ -1 +1 @@ -Subproject commit b06c2a316a55fe27b7dec26d0e78059e4c0a1b66 +Subproject commit 021b7efdf4fcf21dba96a0d4af0e3b6491bc7d13 diff --git a/scripts/lint.py b/scripts/lint.py index cf025c39..0d757429 100644 --- a/scripts/lint.py +++ b/scripts/lint.py @@ -218,6 +218,29 @@ class DoesntMatchExample(Lint): return True +class StatementWithSingleChildStatement(Lint): + name = "rule contains one or more statements with a single child statement" + recommendation = "remove the superfluous parent statement" + recommendation_template = "remove the superfluous parent statement: {:s}" + violation = False + + def check_rule(self, ctx, rule): + self.violation = False + + def rec(statement, is_root=False): + if isinstance(statement, (capa.engine.And, capa.engine.Or)): + children = list(statement.get_children()) + if not is_root and len(children) == 1 and isinstance(children[0], capa.engine.Statement): + self.recommendation = self.recommendation_template.format(str(statement)) + self.violation = True + for child in children: + rec(child) + + rec(rule.statement, is_root=True) + + return self.violation + + class UnusualMetaField(Lint): name = "unusual meta field" recommendation = "Remove the meta field" @@ -472,7 +495,10 @@ def get_rule_features(rule): return features -LOGIC_LINTS = (DoesntMatchExample(),) +LOGIC_LINTS = ( + DoesntMatchExample(), + StatementWithSingleChildStatement(), +) def lint_logic(ctx, rule): diff --git a/scripts/show-features.py b/scripts/show-features.py index 8960deca..5f0e5df7 100644 --- a/scripts/show-features.py +++ b/scripts/show-features.py @@ -182,6 +182,13 @@ def ida_main(): def print_features(functions, extractor): for f in functions: + function_address = int(f) + + if extractor.is_library_function(function_address): + function_name = extractor.get_function_name(function_address) + logger.debug("skipping library function 0x%x (%s)", function_address, function_name) + continue + for feature, va in extractor.extract_function_features(f): print("func: 0x%08x: %s" % (va, feature)) diff --git a/tests/data b/tests/data index b5ee7ac7..dbcc4ca5 160000 --- a/tests/data +++ b/tests/data @@ -1 +1 @@ -Subproject commit b5ee7ac7b9ff806cefe8d07abed9d4a7a18cafa7 +Subproject commit dbcc4ca51f87733990526f566c99f1d36216161a