Merge branch 'master' into web-add-releases-workflow

This commit is contained in:
Fariss
2024-10-14 12:51:25 +02:00
committed by GitHub
9 changed files with 45 additions and 12 deletions

View File

@@ -13,11 +13,14 @@
### Bug Fixes ### Bug Fixes
- extractor: fix exception when PE extractor encounters unknown architecture #2440 @Tamir-K - extractor: fix exception when PE extractor encounters unknown architecture #2440 @Tamir-K
- IDA Pro: rename ida to idapro module for plugin and idalib in IDA 9.0 #2453 @mr-tz
### capa Explorer Web ### capa Explorer Web
### capa Explorer IDA Pro plugin ### capa Explorer IDA Pro plugin
- fix bug preventing saving of capa results via Save button @mr-tz
### Development ### Development
### Raw diffs ### Raw diffs

View File

@@ -41,7 +41,7 @@ if hasattr(ida_bytes, "parse_binpat_str"):
return return
while True: while True:
ea, _ = ida_bytes.bin_search3(start, end, patterns, ida_bytes.BIN_SEARCH_FORWARD) ea, _ = ida_bytes.bin_search(start, end, patterns, ida_bytes.BIN_SEARCH_FORWARD)
if ea == idaapi.BADADDR: if ea == idaapi.BADADDR:
break break
start = ea + 1 start = ea + 1

View File

@@ -18,7 +18,7 @@ logger = logging.getLogger(__name__)
def is_idalib_installed() -> bool: def is_idalib_installed() -> bool:
try: try:
return importlib.util.find_spec("ida") is not None return importlib.util.find_spec("idapro") is not None
except ModuleNotFoundError: except ModuleNotFoundError:
return False return False
@@ -44,6 +44,7 @@ def get_idalib_user_config_path() -> Optional[Path]:
def find_idalib() -> Optional[Path]: def find_idalib() -> Optional[Path]:
config_path = get_idalib_user_config_path() config_path = get_idalib_user_config_path()
if not config_path: if not config_path:
logger.error("IDA Pro user configuration does not exist, please make sure you've installed idalib properly.")
return None return None
config = json.loads(config_path.read_text(encoding="utf-8")) config = json.loads(config_path.read_text(encoding="utf-8"))
@@ -51,6 +52,9 @@ def find_idalib() -> Optional[Path]:
try: try:
ida_install_dir = Path(config["Paths"]["ida-install-dir"]) ida_install_dir = Path(config["Paths"]["ida-install-dir"])
except KeyError: except KeyError:
logger.error(
"IDA Pro user configuration does not contain location of IDA Pro installation, please make sure you've installed idalib properly."
)
return None return None
if not ida_install_dir.exists(): if not ida_install_dir.exists():
@@ -73,7 +77,7 @@ def find_idalib() -> Optional[Path]:
if not idalib_path.exists(): if not idalib_path.exists():
return None return None
if not (idalib_path / "ida" / "__init__.py").is_file(): if not (idalib_path / "idapro" / "__init__.py").is_file():
return None return None
return idalib_path return idalib_path
@@ -96,7 +100,7 @@ def has_idalib() -> bool:
def load_idalib() -> bool: def load_idalib() -> bool:
try: try:
import ida import idapro
return True return True
except ImportError: except ImportError:
@@ -106,7 +110,7 @@ def load_idalib() -> bool:
sys.path.append(idalib_path.absolute().as_posix()) sys.path.append(idalib_path.absolute().as_posix())
try: try:
import ida # noqa: F401 unused import import idapro # noqa: F401 unused import
return True return True
except ImportError: except ImportError:

View File

@@ -1309,10 +1309,17 @@ class CapaExplorerForm(idaapi.PluginForm):
s = self.resdoc_cache.model_dump_json().encode("utf-8") s = self.resdoc_cache.model_dump_json().encode("utf-8")
path = Path(self.ask_user_capa_json_file()) path = self.ask_user_capa_json_file()
if not path.exists(): if not path:
# dialog canceled
return return
path = Path(path)
if not path.parent.exists():
logger.warning("Failed to save file: parent directory '%s' does not exist.", path.parent)
return
logger.info("Saving capa results to %s.", path)
write_file(path, s) write_file(path, s)
def save_function_analysis(self): def save_function_analysis(self):

View File

@@ -323,7 +323,7 @@ def get_extractor(
if not idalib.load_idalib(): if not idalib.load_idalib():
raise RuntimeError("failed to load IDA idalib module.") raise RuntimeError("failed to load IDA idalib module.")
import ida import idapro
import ida_auto import ida_auto
import capa.features.extractors.ida.extractor import capa.features.extractors.ida.extractor
@@ -333,7 +333,7 @@ def get_extractor(
# so as not to screw up structured output. # so as not to screw up structured output.
with capa.helpers.stdout_redirector(io.BytesIO()): with capa.helpers.stdout_redirector(io.BytesIO()):
with console.status("analyzing program...", spinner="dots"): with console.status("analyzing program...", spinner="dots"):
if ida.open_database(str(input_path), run_auto_analysis=True): if idapro.open_database(str(input_path), run_auto_analysis=True):
raise RuntimeError("failed to analyze input file") raise RuntimeError("failed to analyze input file")
logger.debug("idalib: waiting for analysis...") logger.debug("idalib: waiting for analysis...")

View File

@@ -177,7 +177,7 @@ known_first_party = [
"binaryninja", "binaryninja",
"flirt", "flirt",
"ghidra", "ghidra",
"ida", "idapro",
"ida_ida", "ida_ida",
"ida_auto", "ida_auto",
"ida_bytes", "ida_bytes",

View File

@@ -160,7 +160,7 @@
<!-- Source code dialog --> <!-- Source code dialog -->
<Dialog v-model:visible="sourceDialogVisible" style="width: 50vw"> <Dialog v-model:visible="sourceDialogVisible" style="width: 50vw">
<highlightjs autodetect :code="currentSource" /> <highlightjs :autodetect="false" language="yaml" :code="currentSource" />
</Dialog> </Dialog>
</template> </template>

View File

@@ -55,7 +55,12 @@
<!-- example node: "exit(0) -> 0" (if the node type is call-info, we highlight node.data.name.callInfo) --> <!-- example node: "exit(0) -> 0" (if the node type is call-info, we highlight node.data.name.callInfo) -->
<template v-else-if="node.data.type === 'call-info'"> <template v-else-if="node.data.type === 'call-info'">
<highlightjs lang="c" :code="node.data.name.callInfo" class="text-xs" /> <highlightjs
:autodetect="false"
language="c"
:code="node.data.name.callInfo"
class="text-xs highlightjs-wrapper"
/>
</template> </template>
<!-- example node: " = IMAGE_NT_SIGNATURE (PE)" --> <!-- example node: " = IMAGE_NT_SIGNATURE (PE)" -->
@@ -83,3 +88,11 @@ const getTooltipContent = (data) => {
return null; return null;
}; };
</script> </script>
<style scoped>
.highlightjs-wrapper {
width: 120ch;
word-wrap: break-word;
white-space: normal;
}
</style>

View File

@@ -215,6 +215,12 @@
<h2 class="mt-3">Tool Updates</h2> <h2 class="mt-3">Tool Updates</h2>
<h3 class="mt-2">v7.4.0 (<em>2024-10-04</em>)</h3>
<p class="mt-0">
The <a href="https://github.com/mandiant/capa/releases/tag/v7.4.0">v7.4.0</a> capa release fixes a bug when processing VMRay analysis archives and enhances API extraction for all dynamic backends. For better terminal rendering capa now solely relies on the rich library.<br />
The standalone capa executable can now automatically detect installations of relevant third party applications and use their backends (notably, idalib and Binary Ninja). For the extra standalone Linux build we've upgraded from Python 3.11 to 3.12.
</p>
<h3 class="mt-2">v7.3.0 (<em>2024-09-20</em>)</h3> <h3 class="mt-2">v7.3.0 (<em>2024-09-20</em>)</h3>
<div class="mt-0"> <div class="mt-0">
The <a href="https://github.com/mandiant/capa/releases/tag/v7.3.0">capa v7.3.0</a> release comes with the following three major enhancements: The <a href="https://github.com/mandiant/capa/releases/tag/v7.3.0">capa v7.3.0</a> release comes with the following three major enhancements: