mirror of
https://github.com/mandiant/capa.git
synced 2025-12-15 09:00:45 -08:00
flake8 checks resolved
This commit is contained in:
@@ -71,10 +71,9 @@ AnalyzeOptionsText = {
|
||||
}
|
||||
|
||||
|
||||
def write_file(path, data):
|
||||
def write_file(path: Path, data):
|
||||
""" """
|
||||
with open(path, "wb") as save_file:
|
||||
save_file.write(data)
|
||||
path.write_bytes(data)
|
||||
|
||||
|
||||
def trim_function_name(f, max_length=25):
|
||||
@@ -600,7 +599,7 @@ class CapaExplorerForm(idaapi.PluginForm):
|
||||
raise UserCancelledError()
|
||||
|
||||
if not path.exists():
|
||||
logger.error("rule path %s does not exist or cannot be accessed" % path)
|
||||
logger.error("rule path %s does not exist or cannot be accessed", path)
|
||||
return False
|
||||
|
||||
settings.user[CAPA_SETTINGS_RULE_PATH] = str(path)
|
||||
@@ -1307,8 +1306,8 @@ class CapaExplorerForm(idaapi.PluginForm):
|
||||
|
||||
s = self.resdoc_cache.json().encode("utf-8")
|
||||
|
||||
path = self.ask_user_capa_json_file()
|
||||
if not path:
|
||||
path = Path(self.ask_user_capa_json_file())
|
||||
if not path.exists():
|
||||
return
|
||||
|
||||
write_file(path, s)
|
||||
@@ -1320,8 +1319,8 @@ class CapaExplorerForm(idaapi.PluginForm):
|
||||
idaapi.info("No rule to save.")
|
||||
return
|
||||
|
||||
path = self.ask_user_capa_rule_file()
|
||||
if not path:
|
||||
path = Path(self.ask_user_capa_rule_file())
|
||||
if not path.exists():
|
||||
return
|
||||
|
||||
write_file(path, s)
|
||||
|
||||
@@ -434,7 +434,7 @@ def get_default_root() -> Path:
|
||||
# its injected by pyinstaller.
|
||||
# so we'll fetch this attribute dynamically.
|
||||
assert hasattr(sys, "_MEIPASS")
|
||||
return Path(getattr(sys, "_MEIPASS"))
|
||||
return Path(sys._MEIPASS)
|
||||
else:
|
||||
return Path(__file__).resolve().parent.parent
|
||||
|
||||
@@ -577,7 +577,7 @@ def get_extractor(
|
||||
|
||||
|
||||
def get_file_extractors(sample: Path, format_: str) -> List[FeatureExtractor]:
|
||||
file_extractors: List[FeatureExtractor] = list()
|
||||
file_extractors: List[FeatureExtractor] = []
|
||||
|
||||
if format_ == FORMAT_PE:
|
||||
file_extractors.append(capa.features.extractors.pefile.PefileFeatureExtractor(sample))
|
||||
|
||||
@@ -14,6 +14,7 @@ import logging
|
||||
import binascii
|
||||
import collections
|
||||
from enum import Enum
|
||||
from pathlib import Path
|
||||
|
||||
from capa.helpers import assert_never
|
||||
|
||||
@@ -825,7 +826,7 @@ class Rule:
|
||||
|
||||
@classmethod
|
||||
def from_yaml_file(cls, path, use_ruamel=False) -> "Rule":
|
||||
with open(path, "rb") as f:
|
||||
with Path(path).open("rb") as f:
|
||||
try:
|
||||
rule = cls.from_yaml(f.read().decode("utf-8"), use_ruamel=use_ruamel)
|
||||
# import here to avoid circular dependency
|
||||
|
||||
@@ -72,8 +72,8 @@ default_tags = "CAPA "
|
||||
# minimum number of rounds to do be able to convert rules which depend on referenced rules in several levels of depth
|
||||
min_rounds = 5
|
||||
|
||||
unsupported_capa_rules = open("unsupported_capa_rules.yml", "wb")
|
||||
unsupported_capa_rules_names = open("unsupported_capa_rules.txt", "wb")
|
||||
unsupported_capa_rules = Path("unsupported_capa_rules.yml").open("wb")
|
||||
unsupported_capa_rules_names = Path("unsupported_capa_rules.txt").open("wb")
|
||||
unsupported_capa_rules_list = []
|
||||
|
||||
condition_header = """
|
||||
|
||||
@@ -17,6 +17,7 @@ See the License for the specific language governing permissions and limitations
|
||||
import sys
|
||||
import logging
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
|
||||
import capa.rules
|
||||
|
||||
@@ -70,8 +71,7 @@ def main(argv=None):
|
||||
return 1
|
||||
|
||||
if args.in_place:
|
||||
with open(args.path, "wb") as f:
|
||||
f.write(reformatted_rule.encode("utf-8"))
|
||||
Path(args.path).write_bytes(reformatted_rule.encode("utf-8"))
|
||||
else:
|
||||
print(reformatted_rule)
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ import logging
|
||||
import argparse
|
||||
import contextlib
|
||||
from typing import BinaryIO
|
||||
from pathlib import Path
|
||||
|
||||
import capa.helpers
|
||||
import capa.features.extractors.elf
|
||||
@@ -56,7 +57,7 @@ def main(argv=None):
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logging.getLogger().setLevel(logging.INFO)
|
||||
|
||||
f = open(args.sample, "rb")
|
||||
f = Path(args.sample).open("rb")
|
||||
|
||||
with contextlib.closing(f):
|
||||
try:
|
||||
|
||||
@@ -43,7 +43,7 @@ def get_features(rule_path: str) -> list:
|
||||
list: A list of all feature statements contained within the rule file.
|
||||
"""
|
||||
feature_list = []
|
||||
with open(rule_path, "r", encoding="utf-8") as f:
|
||||
with Path(rule_path).open("r", encoding="utf-8") as f:
|
||||
try:
|
||||
new_rule = capa.rules.Rule.from_yaml(f.read())
|
||||
feature_list = get_child_features(new_rule.statement)
|
||||
|
||||
@@ -355,7 +355,7 @@ class DoesntMatchExample(Lint):
|
||||
try:
|
||||
capabilities = get_sample_capabilities(ctx, path)
|
||||
except Exception as e:
|
||||
logger.error("failed to extract capabilities: %s %s %s", rule.name, path, e, exc_info=True)
|
||||
logger.exception("failed to extract capabilities: %s %s %s", rule.name, path, e)
|
||||
return True
|
||||
|
||||
if rule.name not in capabilities:
|
||||
@@ -883,12 +883,12 @@ def lint(ctx: Context):
|
||||
return ret
|
||||
|
||||
|
||||
def collect_samples(path: Path) -> Dict[str, Path]:
|
||||
def collect_samples(samples_path: Path) -> Dict[str, Path]:
|
||||
"""
|
||||
recurse through the given path, collecting all file paths, indexed by their content sha256, md5, and filename.
|
||||
"""
|
||||
samples = {}
|
||||
for path in path.rglob("*"):
|
||||
for path in samples_path.rglob("*"):
|
||||
if path.suffix in [".viv", ".idb", ".i64", ".frz", ".fnames"]:
|
||||
continue
|
||||
|
||||
|
||||
@@ -103,8 +103,7 @@ def main(argv=None):
|
||||
if (args.format == "freeze") or (
|
||||
args.format == capa.features.common.FORMAT_AUTO and capa.features.freeze.is_freeze(taste)
|
||||
):
|
||||
with open(args.sample, "rb") as f:
|
||||
extractor = capa.features.freeze.load(f.read())
|
||||
extractor = capa.features.freeze.load(Path(args.sample).read_bytes())
|
||||
else:
|
||||
extractor = capa.main.get_extractor(
|
||||
args.sample, args.format, args.os, capa.main.BACKEND_VIV, sig_paths, should_save_workspace=False
|
||||
|
||||
@@ -34,6 +34,7 @@ Example:
|
||||
import sys
|
||||
import logging
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
|
||||
import capa.render.json
|
||||
import capa.render.proto
|
||||
@@ -71,8 +72,7 @@ def main(argv=None):
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logging.getLogger().setLevel(logging.INFO)
|
||||
|
||||
with open(args.pb, "rb") as f:
|
||||
pb = f.read()
|
||||
pb = Path(args.pb).read_bytes()
|
||||
|
||||
rdpb = capa.render.proto.capa_pb2.ResultDocument()
|
||||
rdpb.ParseFromString(pb)
|
||||
|
||||
@@ -172,7 +172,7 @@ def main(args: argparse.Namespace) -> None:
|
||||
|
||||
logging.info("Writing results to %s", args.output)
|
||||
try:
|
||||
with open(args.output, "w", encoding="utf-8") as jf:
|
||||
with Path(args.output).open("w", encoding="utf-8") as jf:
|
||||
json.dump(data, jf, indent=2)
|
||||
except BaseException as e:
|
||||
logging.error("Exception encountered when writing results: %s", e)
|
||||
|
||||
@@ -160,8 +160,7 @@ def main(argv=None):
|
||||
|
||||
if (args.format == "freeze") or (args.format == FORMAT_AUTO and capa.features.freeze.is_freeze(taste)):
|
||||
format_ = "freeze"
|
||||
with open(args.sample, "rb") as f:
|
||||
extractor = capa.features.freeze.load(f.read())
|
||||
extractor = capa.features.freeze.load(Path(args.sample).read_bytes())
|
||||
else:
|
||||
format_ = args.format
|
||||
should_save_workspace = os.environ.get("CAPA_SAVE_WORKSPACE") not in ("0", "no", "NO", "n", None)
|
||||
|
||||
@@ -116,8 +116,7 @@ def main(argv=None):
|
||||
if (args.format == "freeze") or (
|
||||
args.format == capa.features.common.FORMAT_AUTO and capa.features.freeze.is_freeze(taste)
|
||||
):
|
||||
with open(args.sample, "rb") as f:
|
||||
extractor = capa.features.freeze.load(f.read())
|
||||
extractor = capa.features.freeze.load(Path(args.sample).read_bytes())
|
||||
else:
|
||||
should_save_workspace = os.environ.get("CAPA_SAVE_WORKSPACE") not in ("0", "no", "NO", "n", None)
|
||||
try:
|
||||
|
||||
109
setup.py
109
setup.py
@@ -1,109 +0,0 @@
|
||||
# Copyright (C) 2020 Mandiant, Inc. All Rights Reserved.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at: [package root]/LICENSE.txt
|
||||
# Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
# is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and limitations under the License.
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
import setuptools
|
||||
|
||||
requirements = [
|
||||
"tqdm==4.65.0",
|
||||
"pyyaml==6.0",
|
||||
"tabulate==0.9.0",
|
||||
"colorama==0.4.6",
|
||||
"termcolor==2.3.0",
|
||||
"wcwidth==0.2.6",
|
||||
"ida-settings==2.1.0",
|
||||
"viv-utils[flirt]==0.7.9",
|
||||
"halo==0.0.31",
|
||||
"networkx==3.1",
|
||||
"ruamel.yaml==0.17.32",
|
||||
"vivisect==1.1.1",
|
||||
"pefile==2023.2.7",
|
||||
"pyelftools==0.29",
|
||||
"dnfile==0.13.0",
|
||||
"dncil==1.0.2",
|
||||
"pydantic==1.10.9",
|
||||
"protobuf==4.23.2",
|
||||
]
|
||||
|
||||
# this sets __version__
|
||||
# via: http://stackoverflow.com/a/7071358/87207
|
||||
# and: http://stackoverflow.com/a/2073599/87207
|
||||
exec((Path("capa") / "version.py").read_text())
|
||||
|
||||
|
||||
# via: https://packaging.python.org/guides/making-a-pypi-friendly-readme/
|
||||
long_description = (Path(__file__).resolve().parent / "README.md").read_text()
|
||||
|
||||
|
||||
setuptools.setup(
|
||||
name="flare-capa",
|
||||
version=__version__,
|
||||
description="The FLARE team's open-source tool to identify capabilities in executable files.",
|
||||
long_description=long_description,
|
||||
long_description_content_type="text/markdown",
|
||||
author="Willi Ballenthin, Moritz Raabe",
|
||||
author_email="william.ballenthin@mandiant.com, moritz.raabe@mandiant.com",
|
||||
url="https://www.github.com/mandiant/capa",
|
||||
project_urls={
|
||||
"Documentation": "https://github.com/mandiant/capa/tree/master/doc",
|
||||
"Rules": "https://github.com/mandiant/capa-rules",
|
||||
"Rules Documentation": "https://github.com/mandiant/capa-rules/tree/master/doc",
|
||||
},
|
||||
packages=setuptools.find_packages(exclude=["tests"]),
|
||||
package_dir={"capa": "capa"},
|
||||
entry_points={
|
||||
"console_scripts": [
|
||||
"capa=capa.main:main",
|
||||
]
|
||||
},
|
||||
include_package_data=True,
|
||||
install_requires=requirements,
|
||||
extras_require={
|
||||
"dev": [
|
||||
"pytest==7.4.0",
|
||||
"pytest-sugar==0.9.4",
|
||||
"pytest-instafail==0.5.0",
|
||||
"pytest-cov==4.1.0",
|
||||
"pycodestyle==2.10.0",
|
||||
"ruff==0.0.275",
|
||||
"black==23.3.0",
|
||||
"isort==5.11.4",
|
||||
"mypy==1.4.1",
|
||||
"psutil==5.9.2",
|
||||
"stix2==3.0.1",
|
||||
"requests==2.31.0",
|
||||
"mypy-protobuf==3.4.0",
|
||||
# type stubs for mypy
|
||||
"types-backports==0.1.3",
|
||||
"types-colorama==0.4.15.11",
|
||||
"types-PyYAML==6.0.8",
|
||||
"types-tabulate==0.9.0.1",
|
||||
"types-termcolor==1.1.4",
|
||||
"types-psutil==5.8.23",
|
||||
"types_requests==2.31.0.1",
|
||||
"types-protobuf==4.23.0.1",
|
||||
],
|
||||
"build": [
|
||||
"pyinstaller==5.10.1",
|
||||
],
|
||||
},
|
||||
zip_safe=False,
|
||||
keywords="capa malware analysis capability detection FLARE",
|
||||
classifiers=[
|
||||
"Development Status :: 5 - Production/Stable",
|
||||
"Intended Audience :: Developers",
|
||||
"Intended Audience :: Information Technology",
|
||||
"License :: OSI Approved :: Apache Software License",
|
||||
"Natural Language :: English",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Topic :: Security",
|
||||
],
|
||||
python_requires=">=3.8",
|
||||
)
|
||||
@@ -7,6 +7,7 @@
|
||||
# See the License for the specific language governing permissions and limitations under the License.
|
||||
import textwrap
|
||||
from typing import List
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
from fixtures import z9324d_extractor
|
||||
@@ -173,10 +174,8 @@ def test_freeze_load_sample(tmpdir, request, extractor):
|
||||
|
||||
extractor = request.getfixturevalue(extractor)
|
||||
|
||||
with open(o.strpath, "wb") as f:
|
||||
f.write(capa.features.freeze.dump(extractor))
|
||||
Path(o.strpath).write_bytes(capa.features.freeze.dump(extractor))
|
||||
|
||||
with open(o.strpath, "rb") as f:
|
||||
null_extractor = capa.features.freeze.load(f.read())
|
||||
null_extractor = capa.features.freeze.load(Path(o.strpath).read_bytes())
|
||||
|
||||
compare_extractors(extractor, null_extractor)
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
# See the License for the specific language governing permissions and limitations under the License.
|
||||
import io
|
||||
import zlib
|
||||
from pathlib import Path
|
||||
|
||||
from fixtures import get_data_path_by_name
|
||||
|
||||
@@ -23,7 +24,7 @@ def test_elf_sh_notes():
|
||||
# guess: symtab: None
|
||||
# guess: needed dependencies: None
|
||||
path = get_data_path_by_name("2f7f5f")
|
||||
with open(path, "rb") as f:
|
||||
with Path(path).open("rb") as f:
|
||||
assert capa.features.extractors.elf.detect_elf_os(f) == "linux"
|
||||
|
||||
|
||||
@@ -36,7 +37,7 @@ def test_elf_pt_notes():
|
||||
# guess: symtab: None
|
||||
# guess: needed dependencies: None
|
||||
path = get_data_path_by_name("7351f.elf")
|
||||
with open(path, "rb") as f:
|
||||
with Path(path).open("rb") as f:
|
||||
assert capa.features.extractors.elf.detect_elf_os(f) == "linux"
|
||||
|
||||
|
||||
@@ -49,7 +50,7 @@ def test_elf_so_needed():
|
||||
# guess: symtab: None
|
||||
# guess: needed dependencies: OS.HURD
|
||||
path = get_data_path_by_name("b5f052")
|
||||
with open(path, "rb") as f:
|
||||
with Path(path).open("rb") as f:
|
||||
assert capa.features.extractors.elf.detect_elf_os(f) == "hurd"
|
||||
|
||||
|
||||
@@ -62,7 +63,7 @@ def test_elf_abi_version_hurd():
|
||||
# guess: symtab: None
|
||||
# guess: needed dependencies: None
|
||||
path = get_data_path_by_name("bf7a9c")
|
||||
with open(path, "rb") as f:
|
||||
with Path(path).open("rb") as f:
|
||||
assert capa.features.extractors.elf.detect_elf_os(f) == "hurd"
|
||||
|
||||
|
||||
@@ -75,7 +76,7 @@ def test_elf_symbol_table():
|
||||
# guess: symtab: OS.LINUX
|
||||
# guess: needed dependencies: None
|
||||
path = get_data_path_by_name("2bf18d")
|
||||
with open(path, "rb") as f:
|
||||
with Path(path).open("rb") as f:
|
||||
assert capa.features.extractors.elf.detect_elf_os(f) == "linux"
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user