Skip to content

Accept integer addresses for address-style tool params (Fixes #9) - #10

Merged
duty1g merged 1 commit into
duty1g:mainfrom
wanderer741:fix/integer-address-params
Oct 12, 2026
Merged

duty1g merged 1 commit into
duty1g:mainfrom
wanderer741:fix/integer-address-params

Conversation

@wanderer741

Copy link
Copy Markdown
Contributor

As confirmed in #9, getParamStr → json.getStringField only matched the JSON .string variant, so an integer address/target silently fell back to the parameter default ("cip" in Disassemble/DisassembleFunction) or errored as "... is required" in the other address-taking tools — even though agents naturally pass numbers.

This implements the accept-both approach:

  • json.getAddrField(parsed, field, buf) — JSON strings ("0x...", symbols, expressions) pass through unchanged; JSON integers are formatted as 0x{X} into the caller's buffer; negative integers and non-integer/non-string values return null (unchanged behavior).
  • tools.getParamAddr(params, field, buf) — thin wrapper, used at all 25 address-style call sites (23 × address, 2 × target): Disassemble, DisassembleFunction, ReadMemory, SetBreakpoint, DeleteBreakpoint, WriteMemToAddress, CommentOrLabelAtAddress, Assemble, SetHardwareBreakpoint, SetMemoryBreakpoint, GetReferences, RunToAddress, SetConditionalBreakpoint, FollowPointer, DumpMemory, FreeMemory, Enable/Disable/Toggle/ResetHitCount, Set/DeleteBookmark, AnalyzeCode, SetBreakpointCommand, SetBreakpointFastResume.
  • Schemas for address-style params now declare ["string","integer"], so the machine-readable contract matches what the server accepts.
  • Disassemble.count clamp is now documented in its schema description as [1, 100].

Tests

zig build test (Zig 0.14.0, as pinned by CI) — new unit tests in json.zig: string passthrough, integer formatting (5368714928 → "0x1400016B0"), zero → "0x0", negative/float/bool/array/missing → null, undersized buffer → null.

zig build -Doptimize=ReleaseFast builds both the x32 and x64 plugins (end-to-end testing below was on x64).

End-to-end verification (live x64dbg, Windows)

Control = plugin built from unmodified v1.5 with the same toolchain; treatment = this branch. Same target, same flow (paused at the entry breakpoint, target = cip + 0x200):

Check v1.5 (control) this branch
Disassemble {"address": <int>} silently disassembled at CIP disassembles at the requested address; output byte-identical to the string form
ReadMemory {"address": <int>} Error: address is required. returns the same bytes as the string form
SetBreakpoint / DeleteBreakpoint {"target": <int>} Error: target is required. set / visible in ListBreakpoints / deleted
Disassemble {"address": "0x..."} works works (unchanged)
Disassemble {"count": 500} clamped to 100 clamped to 100 (unchanged)

Concrete: the control int-address call returned CIP 0x7FFA897FD78E instead of the requested 0x7FFA897FD98E; with this branch both int and string forms return the requested 0x7FF670B616B0.

Notes

  • Negative integers and other JSON types keep the previous behavior (null → tool default / "required" error) — unchanged.
  • Heads-up, unrelated to this change: current main fails to build with Zig 0.16.0 (24 errors from the Windows BOOL → os.windows.Bool(c_int) change and the ws2_32.SOCKET/WSADATA move); the CI-pinned 0.14.0 builds cleanly. Mentioning in case the README's "Zig 0.16-dev or later" build note needs a look.

Fixes #9

getParamStr -> getStringField only matched the JSON .string variant, so an integer address/target silently fell back to the parameter default ("cip" in Disassemble/DisassembleFunction) or errored as "required" in the other address-taking tools. Add getAddrField/getParamAddr: strings pass through unchanged, integers are formatted as "0x{X}" before expression resolution. Applied to all 25 address/target call sites (23 address, 2 target).

Tool schemas now declare address-style params as ["string","integer"], and the Disassemble count clamp is documented as [1, 100]. Unit tests cover string passthrough, integer formatting, zero, negative integers, floats, non-address types, missing fields, and small buffers.

Fixes duty1g#9
@duty1g

duty1g commented Oct 12, 2026

Copy link
Copy Markdown
Owner

Merged into main as v1.6. Clean work — thorough coverage across all 25 call sites, good tests, and the end-to-end verification was appreciated. Thanks!

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.

Disassemble silently falls back to CIP when address is a JSON number

2 participants