mirror of
https://github.com/mandiant/capa.git
synced 2025-12-15 09:00:45 -08:00
lint: get backend from format (#1964)
* get backend from format * add lint.py script test * create FakeArgs object * adjust EOL handling in lints --------- Co-authored-by: Willi Ballenthin <wballenthin@google.com>
This commit is contained in:
@@ -356,19 +356,17 @@ def get_sample_capabilities(ctx: Context, path: Path) -> Set[str]:
|
|||||||
logger.debug("found cached results: %s: %d capabilities", nice_path, len(ctx.capabilities_by_sample[path]))
|
logger.debug("found cached results: %s: %d capabilities", nice_path, len(ctx.capabilities_by_sample[path]))
|
||||||
return ctx.capabilities_by_sample[path]
|
return ctx.capabilities_by_sample[path]
|
||||||
|
|
||||||
if nice_path.name.endswith(capa.helpers.EXTENSIONS_SHELLCODE_32):
|
|
||||||
format_ = "sc32"
|
|
||||||
elif nice_path.name.endswith(capa.helpers.EXTENSIONS_SHELLCODE_64):
|
|
||||||
format_ = "sc64"
|
|
||||||
else:
|
|
||||||
format_ = capa.helpers.get_auto_format(nice_path)
|
|
||||||
|
|
||||||
logger.debug("analyzing sample: %s", nice_path)
|
logger.debug("analyzing sample: %s", nice_path)
|
||||||
|
|
||||||
|
args = argparse.Namespace(input_file=nice_path, format=capa.main.FORMAT_AUTO, backend=capa.main.BACKEND_AUTO)
|
||||||
|
format_ = capa.main.get_input_format_from_cli(args)
|
||||||
|
backend = capa.main.get_backend_from_cli(args, format_)
|
||||||
|
|
||||||
extractor = capa.loader.get_extractor(
|
extractor = capa.loader.get_extractor(
|
||||||
nice_path,
|
nice_path,
|
||||||
format_,
|
format_,
|
||||||
OS_AUTO,
|
OS_AUTO,
|
||||||
capa.main.BACKEND_VIV,
|
backend,
|
||||||
DEFAULT_SIGNATURES,
|
DEFAULT_SIGNATURES,
|
||||||
should_save_workspace=False,
|
should_save_workspace=False,
|
||||||
disable_progress=True,
|
disable_progress=True,
|
||||||
@@ -656,16 +654,6 @@ class FeatureNtdllNtoskrnlApi(Lint):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
class FormatLineFeedEOL(Lint):
|
|
||||||
name = "line(s) end with CRLF (\\r\\n)"
|
|
||||||
recommendation = "convert line endings to LF (\\n) for example using dos2unix"
|
|
||||||
|
|
||||||
def check_rule(self, ctx: Context, rule: Rule):
|
|
||||||
if len(rule.definition.split("\r\n")) > 0:
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
class FormatSingleEmptyLineEOF(Lint):
|
class FormatSingleEmptyLineEOF(Lint):
|
||||||
name = "EOF format"
|
name = "EOF format"
|
||||||
recommendation = "end file with a single empty line"
|
recommendation = "end file with a single empty line"
|
||||||
@@ -681,16 +669,14 @@ class FormatIncorrect(Lint):
|
|||||||
recommendation_template = "use scripts/capafmt.py or adjust as follows\n{:s}"
|
recommendation_template = "use scripts/capafmt.py or adjust as follows\n{:s}"
|
||||||
|
|
||||||
def check_rule(self, ctx: Context, rule: Rule):
|
def check_rule(self, ctx: Context, rule: Rule):
|
||||||
actual = rule.definition
|
# EOL depends on Git and our .gitattributes defines text=auto (Git handles files it thinks is best)
|
||||||
|
# we prefer LF only, but enforcing across OSs seems tedious and unnecessary
|
||||||
|
actual = rule.definition.replace("\r\n", "\n")
|
||||||
expected = capa.rules.Rule.from_yaml(rule.definition, use_ruamel=True).to_yaml()
|
expected = capa.rules.Rule.from_yaml(rule.definition, use_ruamel=True).to_yaml()
|
||||||
|
|
||||||
if actual != expected:
|
if actual != expected:
|
||||||
diff = difflib.ndiff(actual.splitlines(1), expected.splitlines(True))
|
diff = difflib.ndiff(actual.splitlines(1), expected.splitlines(True))
|
||||||
recommendation_template = self.recommendation_template
|
recommendation_template = self.recommendation_template
|
||||||
if "\r\n" in actual:
|
|
||||||
recommendation_template = (
|
|
||||||
self.recommendation_template + "\nplease make sure that the file uses LF (\\n) line endings only"
|
|
||||||
)
|
|
||||||
self.recommendation = recommendation_template.format("".join(diff))
|
self.recommendation = recommendation_template.format("".join(diff))
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@@ -804,7 +790,6 @@ def lint_features(ctx: Context, rule: Rule):
|
|||||||
|
|
||||||
|
|
||||||
FORMAT_LINTS = (
|
FORMAT_LINTS = (
|
||||||
FormatLineFeedEOL(),
|
|
||||||
FormatSingleEmptyLineEOF(),
|
FormatSingleEmptyLineEOF(),
|
||||||
FormatStringQuotesIncorrect(),
|
FormatStringQuotesIncorrect(),
|
||||||
FormatIncorrect(),
|
FormatIncorrect(),
|
||||||
|
|||||||
@@ -40,7 +40,10 @@ def get_rule_path():
|
|||||||
[
|
[
|
||||||
pytest.param("capa2yara.py", [get_rules_path()]),
|
pytest.param("capa2yara.py", [get_rules_path()]),
|
||||||
pytest.param("capafmt.py", [get_rule_path()]),
|
pytest.param("capafmt.py", [get_rule_path()]),
|
||||||
# not testing lint.py as it runs regularly anyway
|
# testing some variations of linter script
|
||||||
|
pytest.param("lint.py", ["-t", "create directory", get_rules_path()]),
|
||||||
|
# `create directory` rule has native and .NET example PEs
|
||||||
|
pytest.param("lint.py", ["--thorough", "-t", "create directory", get_rules_path()]),
|
||||||
pytest.param("match-function-id.py", [get_file_path()]),
|
pytest.param("match-function-id.py", [get_file_path()]),
|
||||||
pytest.param("show-capabilities-by-function.py", [get_file_path()]),
|
pytest.param("show-capabilities-by-function.py", [get_file_path()]),
|
||||||
pytest.param("show-features.py", [get_file_path()]),
|
pytest.param("show-features.py", [get_file_path()]),
|
||||||
|
|||||||
Reference in New Issue
Block a user