Skip to content

P0: Global-variable CRUD + full function signatures for the decompiler CLI#206

Closed
mahaloz wants to merge 1 commit into
feat/cli-commentsfrom
feat/cli-globals-signatures
Closed

P0: Global-variable CRUD + full function signatures for the decompiler CLI#206
mahaloz wants to merge 1 commit into
feat/cli-commentsfrom
feat/cli-globals-signatures

Conversation

@mahaloz

@mahaloz mahaloz commented Jul 17, 2026

Copy link
Copy Markdown
Member

What & why

IDALib can list/read/rename/type globals and set complete function signatures; the DecLib CLI could do neither. This adds both.

Globals — decompiler global list|get|rename|retype

  • IDA enumeration broadened: was a hardcoded scan of .artifacts/.bss only; now uses idautils.Names(), so named data across .data/.bss/.rodata/.got all surface (function starts and code labels filtered out).
  • Ghidra retype implemented (DataUtilities.createData) — previously a # TODO: pass. Also filtered Ghidra's enumeration to memory-mapped symbols, so synthetic/EXTERNAL symbols (which lift to negative addresses and can't round-trip) no longer pollute global list.
  • Base get_global_var (direct read, no cache) + client proxy.
$ decompiler global list --filter 'key|flag'
ADDR         SIZE   TYPE                 NAME
0x4040       8      char *               g_key
$ decompiler global rename 0x4040 g_secret_key
$ decompiler global retype 0x4040 "char[32]"

Signatures — decompiler signature get|set

  • Shared declib/api/prototype.py parses/formats C prototypes (pointer returns/args, varargs, void).
  • IDA applies the whole prototype atomically via idc.SetType. This sidesteps a real bug in the existing set_function_header: when both return type and args change, the args pass rebuilds the prototype from a stale cfunc and clobbers the just-applied return type. SetType sets it in one shot (and can change the parameter count).
  • Ghidra/Binary Ninja use the generic parse → header-overwrite → set path (their setters apply return + arg types independently). angr sets arg names but not types.
$ decompiler signature get main
int main(int argc, char **argv)
$ decompiler signature set main "int main(int argc, char **argv, char **envp)"
$ decompiler signature get main
int main(int argc, char **argv, char **envp)

Tests

Backend-parametrized: test_global_list, test_global_rename, test_signature_get, test_signature_set, test_signature_get_missing_exits_nonzero, plus backend-free TestPrototypeParser.

  • IDA: full pass. Ghidra: full pass. angr: signature get/missing pass; globals + signature-type-set skip (unsupported, gated by capability flags).

Support matrix

IDA Ghidra Binary Ninja angr
global list/get/rename
global retype ✅ (new)
signature get
signature set (types) ✅ (atomic) names only

Third PR in the IDALib-parity series. Based on feat/cli-comments (#205).

🤖 Generated with Claude Code

https://claude.ai/code/session_01HfZHdprXg38re1XyKxzGg5

Closes the P0 gap for globals and complete function signatures.

Globals:
- New `decompiler global list|get|rename|retype`.
- IDA: broadened enumeration to idautils.Names() (all named data across
  .data/.bss/.rodata/.got), not just a hardcoded .artifacts/.bss pair.
- Ghidra: implemented global retype (DataUtilities.createData); filtered
  the enumeration to memory-mapped symbols so synthetic/EXTERNAL symbols
  (which lift to negative addresses and can't round-trip) no longer leak
  into `global list`.
- Base: public get_global_var (direct read) + client proxy.

Signatures:
- New `decompiler signature get|set`.
- Shared declib/api/prototype.py parses/formats C prototypes (pointers,
  varargs, void args).
- IDA applies the full prototype atomically via idc.SetType — this avoids
  the existing set_function_header bug where the args pass rebuilt the
  prototype from a stale cfunc and clobbered a just-set return type. Other
  backends use the generic parse -> header-overwrite -> set path.
- Base get/set_function_signature + client proxies.

Tests: backend-parametrized global list/rename and signature get/set/missing
(IDA + Ghidra full; angr skips unsupported bits), plus backend-free
prototype-parser unit tests. SKILL.md / docs updated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HfZHdprXg38re1XyKxzGg5
@mahaloz

mahaloz commented Jul 17, 2026

Copy link
Copy Markdown
Member Author

Integrated into main as commit 0ea35a5. The stack got tangled when the bottom PRs (#204/#205) were squash-merged (#205 landed on feat/cli-persistence instead of main), so I reconciled by cherry-picking the whole series onto main linearly. The exact reviewed content of this PR is on main — closing this stacked PR as its changes are shipped.

@mahaloz mahaloz closed this Jul 17, 2026
@mahaloz
mahaloz deleted the feat/cli-globals-signatures branch July 17, 2026 16:35
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