diff --git a/CHANGELOG.md b/CHANGELOG.md index b7d8cbfd56..820744584d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Change Log ## master (unreleased) +- main: add initial elf files support ### New Features diff --git a/capa/features/extractors/viv/file.py b/capa/features/extractors/viv/file.py index 55171ff2b7..00eb57edae 100644 --- a/capa/features/extractors/viv/file.py +++ b/capa/features/extractors/viv/file.py @@ -41,7 +41,7 @@ def extract_file_import_names(vw, file_path): """ for va, _, _, tinfo in vw.getImports(): # vivisect source: tinfo = "%s.%s" % (libname, impname) - modname, impname = tinfo.split(".") + modname, impname = tinfo.split(".", 1) if is_viv_ord_impname(impname): # replace ord prefix with # impname = "#%s" % impname[len("ord") :] diff --git a/capa/features/extractors/viv/insn.py b/capa/features/extractors/viv/insn.py index 88515fb646..ffe9e3c966 100644 --- a/capa/features/extractors/viv/insn.py +++ b/capa/features/extractors/viv/insn.py @@ -127,6 +127,10 @@ def extract_insn_api_features(f, bb, insn): for name in capa.features.extractors.helpers.generate_symbols(dll, symbol): yield API(name), insn.va + # if jump leads to an ENDBRANCH instruction, skip it + if f.vw.getByteDef(target)[1].startswith(b"\xf3\x0f\x1e"): + target += 4 + target = capa.features.extractors.viv.helpers.get_coderef_from(f.vw, target) if not target: return diff --git a/capa/main.py b/capa/main.py index 09c0119fc3..7aea943d07 100644 --- a/capa/main.py +++ b/capa/main.py @@ -45,7 +45,7 @@ RULES_PATH_DEFAULT_STRING = "(embedded rules)" SIGNATURES_PATH_DEFAULT_STRING = "(embedded signatures)" -SUPPORTED_FILE_MAGIC = set([b"MZ"]) +SUPPORTED_FILE_MAGIC = (b"MZ", b"\x7fELF") BACKEND_VIV = "vivisect" BACKEND_SMDA = "smda" EXTENSIONS_SHELLCODE_32 = ("sc32", "raw32") @@ -240,8 +240,8 @@ def is_supported_file_type(sample: str) -> bool: Return if this is a supported file based on magic header values """ with open(sample, "rb") as f: - magic = f.read(2) - if magic in SUPPORTED_FILE_MAGIC: + magic = f.read(4) + if magic.startswith(SUPPORTED_FILE_MAGIC): return True else: return False @@ -414,7 +414,7 @@ def get_workspace(path, format, sigpaths): # don't analyze, so that we can add our Flirt function analyzer first. vw = viv_utils.getWorkspace(path, analyze=False, should_save=False) - elif format == "pe": + elif format in {"pe", "elf"}: vw = viv_utils.getWorkspace(path, analyze=False, should_save=False) elif format == "sc32": # these are not analyzed nor saved. @@ -668,6 +668,7 @@ def install_common_args(parser, wanted=None): formats = [ ("auto", "(default) detect file type automatically"), ("pe", "Windows PE file"), + ("elf", "Executable and Linkable Format"), ("sc32", "32-bit shellcode"), ("sc64", "64-bit shellcode"), ("freeze", "features previously frozen by capa"),