Per-agent x64dbg session through debugger()/debugger_tools()

Harbor starts the x64dbg-automate MCP server (stdio) on first use and keeps
it for the life of the agent's Harbor process; the debuggee is terminated
when that process exits. Configured by debugger_command/_path/_temp in
[reverse].
This commit is contained in:
KeelrLeek committed 2026-10-05 12:44:25 -05:00
1 parent 7ed914ebdb
commit 584fabeb74
5 files changed
+175 -4

No files matched your search

+8 -3
View File
@@ -255,7 +255,7 @@ def build_parser():
p = sub.add_parser("who", help="who has worked on a scope (notes, reviews, claims, messages)")
p.add_argument("scope")
p = sub.add_parser("re", help="reverse-engineering lookups from the project's image and annotations")
p.add_argument("action", choices=["disasm", "xrefs", "bytes", "lookup", "ghidra", "ghidra-tools"])
p.add_argument("action", choices=["disasm", "xrefs", "bytes", "lookup", "ghidra", "ghidra-tools", "debugger-tools"])
p.add_argument("target", nargs="?", default="", help="an address (0x4AD850) or a name; for ghidra, the tool")
p.add_argument("arguments", nargs="?", default="{}", help="ghidra: the tool's arguments as JSON")
p.add_argument("--max-bytes", type=int, dest="max_bytes")
@@ -675,8 +675,13 @@ def main(argv=None):
out(r, f"summary #{r['id']} pinned to {r['thread']}")
elif cmd == "re":
from .reverse import Ghidra, Reverse
r = None if args.action.startswith("ghidra") else Reverse(harbor.project.reverse)
if args.action == "ghidra-tools":
r = None if args.action.startswith(("ghidra", "debugger")) else Reverse(harbor.project.reverse)
if args.action == "debugger-tools":
from .reverse import Debugger
res = Debugger(harbor.project.reverse).tools()
out(res, "\n".join(f"{t['name']:<22} {(t['description'] or '').splitlines()[0][:90] if t['description'] else ''}"
for t in res))
elif args.action == "ghidra-tools":
res = Ghidra(harbor.project.reverse).tools()
out(res, "\n".join(f"{t['name']:<26} {t['description'].splitlines()[0][:90]}" for t in res))
elif args.action == "ghidra":