aboutsummaryrefslogtreecommitdiffstats
path: root/experiments/worker_smoke.py
blob: 9b55138a69afae084f1ac4443c2452fe2b600e56 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
"""Exercise the real domain.Program through an IDA Code Mode lease.

A matching registered GUI is reused; otherwise Code Mode starts a managed
idalib worker. Usage: ``uv run python experiments/worker_smoke.py FILE``.
"""
from __future__ import annotations

import os
import sys
import time

from idatui.codemode_client import CodeModeClient
from idatui.domain import Program


def main() -> int:
    target = os.path.abspath(sys.argv[1] if len(sys.argv) > 1 else "experiments/fibonacci.elf")
    print(f"attaching Code Mode to {target}…", flush=True)
    started = time.time()
    client = CodeModeClient(target)
    client.connect(progress=lambda message: print(f"  {message}", flush=True))
    print(
        f"  ready in {time.time() - started:.2f}s; backend={client.backend}; "
        f"session={client.resolve_db()}",
        flush=True,
    )
    program = Program(client)
    try:
        index = program.functions()
        index.load_all()
        print(f"functions() -> {len(index)}", flush=True)
        first = index.get(0)
        if first is None:
            print("VERDICT: FAIL — no functions", flush=True)
            return 1
        fn = program.function_of(first.addr)
        data = program.read_bytes(first.addr, 16)
        decompilation = program.decompile(first.addr)
        print(f"function_of() -> {fn}", flush=True)
        print(f"read_bytes() -> {data.hex()}", flush=True)
        print(
            f"decompile() -> failed={decompilation.failed}; "
            f"lines={len((decompilation.code or '').splitlines())}",
            flush=True,
        )
        print(f"file_regions() -> {len(program.file_regions())}", flush=True)
        ok = fn is not None and bool(data) and bool(program.file_regions())
        print(f"VERDICT: {'OK' if ok else 'FAIL'}", flush=True)
        return 0 if ok else 1
    finally:
        program.close()
        client.close()


if __name__ == "__main__":
    raise SystemExit(main())