add FORMAT_RESULT

This commit is contained in:
Pratham Chauhan
2023-03-23 18:07:03 +05:30
parent 03996f2b82
commit 0358b46fcd
3 changed files with 21 additions and 8 deletions

View File

@@ -448,6 +448,7 @@ FORMAT_AUTO = "auto"
FORMAT_SC32 = "sc32"
FORMAT_SC64 = "sc64"
FORMAT_FREEZE = "freeze"
FORMAT_RESULT = "result"
FORMAT_UNKNOWN = "unknown"

View File

@@ -10,7 +10,7 @@ import capa.features
import capa.features.extractors.elf
import capa.features.extractors.pefile
import capa.features.extractors.strings
from capa.features.common import OS, FORMAT_PE, FORMAT_ELF, OS_WINDOWS, FORMAT_FREEZE, Arch, Format, String, Feature
from capa.features.common import OS, FORMAT_PE, FORMAT_ELF, OS_ANY, OS_WINDOWS, FORMAT_FREEZE, FORMAT_RESULT, ARCH_ANY, Arch, Format, String, Feature
from capa.features.freeze import is_freeze
from capa.features.address import NO_ADDRESS, Address, FileOffsetAddress
@@ -35,6 +35,8 @@ def extract_format(buf) -> Iterator[Tuple[Feature, Address]]:
yield Format(FORMAT_ELF), NO_ADDRESS
elif is_freeze(buf):
yield Format(FORMAT_FREEZE), NO_ADDRESS
elif buf.startswith(b"{\"meta\":"):
yield Format(FORMAT_RESULT), NO_ADDRESS
else:
# we likely end up here:
# 1. handling a file format (e.g. macho)
@@ -51,6 +53,9 @@ def extract_arch(buf) -> Iterator[Tuple[Feature, Address]]:
elif buf.startswith(b"\x7fELF"):
with contextlib.closing(io.BytesIO(buf)) as f:
arch = capa.features.extractors.elf.detect_elf_arch(f)
elif buf.startswith(b"{\"meta\":"):
arch = ARCH_ANY
if arch not in capa.features.common.VALID_ARCH:
logger.debug("unsupported arch: %s", arch)
@@ -79,6 +84,8 @@ def extract_os(buf) -> Iterator[Tuple[Feature, Address]]:
elif buf.startswith(b"\x7fELF"):
with contextlib.closing(io.BytesIO(buf)) as f:
os = capa.features.extractors.elf.detect_elf_os(f)
elif buf.startswith(b"{\"meta\":"):
os = OS_ANY
if os not in capa.features.common.VALID_OS:
logger.debug("unsupported os: %s", os)

View File

@@ -65,6 +65,7 @@ from capa.features.common import (
FORMAT_SC64,
FORMAT_DOTNET,
FORMAT_FREEZE,
FORMAT_RESULT
)
from capa.features.address import NO_ADDRESS, Address
from capa.features.extractors.base_extractor import BBHandle, InsnHandle, FunctionHandle, FeatureExtractor
@@ -1123,8 +1124,11 @@ def main(argv=None):
if not (args.verbose or args.vverbose or args.json):
logger.debug("file limitation short circuit, won't analyze fully.")
return E_FILE_LIMITATION
if format_ == FORMAT_FREEZE:
if format_ == FORMAT_RESULT:
with open(args.sample, "rb") as f:
buf = f.read()
print(buf)
elif format_ == FORMAT_FREEZE:
with open(args.sample, "rb") as f:
extractor = capa.features.freeze.load(f.read())
else:
@@ -1153,12 +1157,13 @@ def main(argv=None):
except UnsupportedOSError:
log_unsupported_os_error()
return E_INVALID_FILE_OS
if not FORMAT_RESULT:
meta = collect_metadata(argv, args.sample, args.rules, extractor)
meta = collect_metadata(argv, args.sample, args.rules, extractor)
capabilities, counts = find_capabilities(rules, extractor, disable_progress=args.quiet)
meta["analysis"].update(counts)
meta["analysis"]["layout"] = compute_layout(rules, extractor, capabilities)
capabilities, counts = find_capabilities(rules, extractor, disable_progress=args.quiet)
meta["analysis"].update(counts)
meta["analysis"]["layout"] = compute_layout(rules, extractor, capabilities)
if has_file_limitation(rules, capabilities):
# bail if capa encountered file limitation e.g. a packed binary