From d2e1a47192faf65fdd9228f3d7ed3ea495df4e3c Mon Sep 17 00:00:00 2001 From: Willi Ballenthin Date: Thu, 25 Jan 2024 16:26:31 +0100 Subject: [PATCH] more ELF OS detection techniques (#1947) * elf: os: deprioritize .ident strategy due to potential for FPs * elf: os: same as parent, fix .ident FP * elf: os: detect Android via clang compiler .ident note * elf: os: detect Android via dependency on liblog.so * changelog --- CHANGELOG.md | 1 + capa/features/extractors/elf.py | 13 +++++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 21e89ce94..3ae7d02a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -95,6 +95,7 @@ Also a big thanks to the other contributors: @aaronatp, @Aayush-Goel-04, @bkojus - binja: use `binaryninja.load` to open files @xusheng6 - binja: bump binja version to 3.5 #1789 @xusheng6 - elf: better detect ELF OS via GCC .ident directives #1928 @williballenthin +- elf: better detect ELF OS via Android dependencies #1947 @williballenthin - fix setuptools package discovery #1886 @gmacon @mr-tz ### capa explorer IDA Pro plugin diff --git a/capa/features/extractors/elf.py b/capa/features/extractors/elf.py index 74e91117a..b969463df 100644 --- a/capa/features/extractors/elf.py +++ b/capa/features/extractors/elf.py @@ -866,6 +866,8 @@ def guess_os_from_ident_directive(elf: ELF) -> Optional[OS]: return OS.LINUX elif "Red Hat" in comment: return OS.LINUX + elif "Android" in comment: + return OS.ANDROID return None @@ -921,6 +923,8 @@ def guess_os_from_needed_dependencies(elf: ELF) -> Optional[OS]: return OS.HURD if needed.startswith("libandroid.so"): return OS.ANDROID + if needed.startswith("liblog.so"): + return OS.ANDROID return None @@ -1023,10 +1027,6 @@ def detect_elf_os(f) -> str: if osabi_guess: ret = osabi_guess - elif ident_guess: - # we don't trust this too much due to non-cross-compilation assumptions - ret = ident_guess - elif ph_notes_guess: ret = ph_notes_guess @@ -1045,6 +1045,11 @@ def detect_elf_os(f) -> str: elif symtab_guess: ret = symtab_guess + elif ident_guess: + # at the bottom because we don't trust this too much + # due to potential for bugs with cross-compilation. + ret = ident_guess + return ret.value if ret is not None else "unknown"