Skip to content

P0: Comment CRUD for the decompiler CLI + IDA comment enumeration#205

Merged
mahaloz merged 1 commit into
feat/cli-persistencefrom
feat/cli-comments
Jul 17, 2026
Merged

P0: Comment CRUD for the decompiler CLI + IDA comment enumeration#205
mahaloz merged 1 commit into
feat/cli-persistencefrom
feat/cli-comments

Conversation

@mahaloz

@mahaloz mahaloz commented Jul 17, 2026

Copy link
Copy Markdown
Member

What & why

DecLib models Comment, but the CLI exposed nothing, and IDA's comment enumeration (_comments) was an unimplemented stub returning {}. This adds a complete annotation workflow — the primary way an agent leaves durable notes for later.

New capabilities

  • decompiler comment set|append|get|delete|list (nested subcommands). --decompiled targets the pseudocode view; addresses accept lifted or absolute form (a shared normalizer maps absolute→lifted).
  • IDA comment enumeration implemented (compat.comments()): walks disassembly comments (regular + repeatable via idautils.Heads), function header/range comments, and persisted Hexrays user comments — the last read straight from the netnode via restore_user_cmts, so no per-function re-decompilation. Also adds del_ida_comment and a richer get_ida_comment (disasm + decompiler comments, not just function headers).
  • Ghidra: _del_comment clears every comment slot.
  • Binary Ninja: fixed _comments (returned raw strings, now Comment objects), fixed _set_comment return value, added _del_comment.
  • Base: public get_comment/delete_comment (direct reads bypassing the light-artifact cache, so a just-set comment is visible) + client proxies.

Example

$ decompiler comment set 0x71d "parses argv, calls authenticate"
addr: 1821
decompiled: False
comment: parses argv, calls authenticate
success: True
$ decompiler comment append 0x71d "SOSNEAKY is the backdoor"
$ decompiler comment get 0x71d
parses argv, calls authenticate
SOSNEAKY is the backdoor
$ decompiler comment list --filter backdoor --json
[{"addr": 1821, "decompiled": false, "comment": "parses argv, calls authenticate\nSOSNEAKY is the backdoor", "addr_hex": "0x71d"}]
$ decompiler comment delete 0x71d
addr: 1821
deleted: True

Tests

Backend-parametrized: test_comment_set_get, test_comment_append, test_comment_list_and_delete, test_comment_get_missing_exits_nonzero.

  • IDA: 4/4 pass (exercises the new enumeration + delete).
  • Ghidra: 4/4 pass.
  • angr: writes succeed; reads/enumeration are a known gap (_reads_comments = False), so read assertions skip there.

Backend support matrix

Backend set get append delete list
IDA ✅ (in-function) ✅ (new)
Ghidra ✅ (new)
Binary Ninja ✅ (fixed) ✅ (new) ✅ (fixed)
angr

Second PR in the IDALib-parity series. Based on feat/cli-persistence (#204) — review/merge that first.

🤖 Generated with Claude Code

https://claude.ai/code/session_01HfZHdprXg38re1XyKxzGg5

…ation

Comments are modeled by DecLib but the CLI exposed nothing, and IDA's
comment enumeration (`_comments`) was an unimplemented stub. This adds a
full annotation workflow.

- New `decompiler comment set|append|get|delete|list` (nested subcommands).
  Addresses accept lifted or absolute form; a shared normalizer maps
  absolute -> lifted so pasted addresses land correctly.
- IDA: real `comments()` enumeration (disassembly regular/repeatable
  comments via idautils.Heads, function header/range comments, and
  persisted Hexrays user comments read from the netnode without
  re-decompiling), plus `del_ida_comment` and a richer `get_ida_comment`
  that also returns disassembly + decompiler comments.
- Ghidra: `_del_comment` clearing every comment slot.
- Binary Ninja: fixed `_comments` to return Comment objects (was raw
  strings), fixed `_set_comment` to return True, added `_del_comment`.
- Base DecompilerInterface gains public get_comment/delete_comment (direct
  reads, bypassing the light-artifact cache) with client proxies.
- Backend-parametrized tests: set/get, append, list+delete, get-missing.
  IDA + Ghidra full pass; angr writes only (reads are a known gap).
- SKILL.md / docs / CLI docstring updated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HfZHdprXg38re1XyKxzGg5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant