aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--idatui/codemode_client.py5
-rw-r--r--tests/test_codemode_client.py24
2 files changed, 27 insertions, 2 deletions
diff --git a/idatui/codemode_client.py b/idatui/codemode_client.py
index 77a0227..b43bfca 100644
--- a/idatui/codemode_client.py
+++ b/idatui/codemode_client.py
@@ -975,7 +975,10 @@ class CodeModeClient:
timeout=max(0.1, timeout),
output_database=self._output_database,
processor=self._processor,
- loading_address=self._loading_address,
+ # DatabaseHandle calls this image_base and wants the
+ # natural (16-byte aligned) address; it does the
+ # conversion to IDA's paragraph-based -b itself.
+ image_base=self._loading_address,
file_type=self._file_type,
new_database=self._new_database,
)
diff --git a/tests/test_codemode_client.py b/tests/test_codemode_client.py
index 0954918..2f70ba3 100644
--- a/tests/test_codemode_client.py
+++ b/tests/test_codemode_client.py
@@ -76,6 +76,21 @@ class FakeDatabaseHandle:
return FakeHandle(path)
+def _open_kwargs_are_real(sent: dict):
+ """(ok, detail) for the kwargs the adapter passes to DatabaseHandle.open.
+
+ Skips (passes) when ida_codemode is not installed, so the file stays pure.
+ """
+ try:
+ import inspect
+ from ida_codemode.client import DatabaseHandle as Real
+ except ImportError:
+ return True, "ida_codemode not installed - signature not checked"
+ accepted = set(inspect.signature(Real.open).parameters)
+ unknown = sorted(set(sent) - accepted)
+ return not unknown, f"open() rejects {unknown}"
+
+
def main() -> int:
proc, base, file_type = _parse_load_args("-parm:ARMv7-M -b800000 -TRaw")
check("legacy switches map to typed Code Mode options",
@@ -103,8 +118,15 @@ def main() -> int:
FakeDatabaseHandle.opened == path and handle is not None)
check("typed loader options cross the dependency boundary",
FakeDatabaseHandle.kwargs["processor"] == "arm:ARMv7-A"
- and FakeDatabaseHandle.kwargs["loading_address"] == 0x1000,
+ and FakeDatabaseHandle.kwargs["image_base"] == 0x1000,
FakeDatabaseHandle.kwargs)
+ # A fake that swallows **kwargs cannot catch a keyword the real
+ # library does not have -- which is exactly how this port shipped
+ # `loading_address` (the real name is `image_base`) and would have
+ # raised TypeError on the very first connect. Check the names we
+ # send against the real signature whenever it is importable.
+ check("every open() keyword exists in the real library",
+ *_open_kwargs_are_real(FakeDatabaseHandle.kwargs))
check("connect waits for Code Mode autoanalysis",
handle.waited == 42, getattr(handle, "waited", None))
check("progress distinguishes discovery and backend attachment",