Skip to content

fix: accept hexadecimal values for Disassemble x86 address arguments - #2721

Open
arjun2075 wants to merge 1 commit into
gchq:masterfrom
arjun2075:fix/2720-disassemble-x86-hex-code-segment
Open

fix: accept hexadecimal values for Disassemble x86 address arguments#2721
arjun2075 wants to merge 1 commit into
gchq:masterfrom
arjun2075:fix/2720-disassemble-x86-hex-code-segment

Conversation

@arjun2075

@arjun2075 arjun2075 commented Aug 10, 2026

Copy link
Copy Markdown

Description

The Code Segment (CS) and Offset (IP) arguments of the Disassemble x86 operation were declared as number ingredients. Ingredient.prepare parses those with parseFloat, so any hexadecimal input was rejected before reaching the operation:

Invalid ingredient value. Not a number: NaN

The underlying cause runs deeper than the reported symptom. SetBasePosition already parses both values with parseInt(x, 16), and GetPosition renders them back out with toString(16) — these fields have always been hexadecimal. The hex-parse on input and hex-format on output cancel each other visually, which is why the mismatch went unnoticed for so long.

It is observable, though. A code segment entered as 24 becomes 36 decimal internally, which crosses the documented "CS >= 36 switches 32-bit output to SEG:OFFSET" threshold, while 35 becomes 53.

Changes:

  • Both arguments are now string ingredients, parsed by a small parseHexAddress helper that accepts the three common ways of writing a hex literal — bare (ABC), prefixed (0xABC) and suffixed (ABCh) — and rejects anything else with a named error instead of a NaN message.
  • The code segment is left-padded to four digits, because SetBasePosition reads it via slice(length - 4) and silently truncated shorter values (ABC was read as C, i.e. 12). Without this, the exact input from the issue would still have produced a wrong result.
  • Offset (IP) is fixed alongside CS, as it is hex-parsed by the same function and had the identical latent bug.

Existing recipes are unaffected: the default value is unchanged, and numeric argument values from previously saved recipes are still handled (verified explicitly).

Existing Issue

Fixes #2720

Screenshots

N/A — no layout or styling changes. The Code Segment (CS) and Offset (IP) arguments change from number inputs to text inputs with a hex format hint, which follows directly from the ingredient type change in the diff.

AI disclosure

This change was written with AI assistance using Claude (Claude Code, model Opus 5). The root cause analysis, the hex/decimal mismatch, the slice(length - 4) truncation and the test cases were all verified by executing the code rather than by inspection alone. I have reviewed the change and understand it.

Test Coverage

Added tests/operations/tests/DisassembleX86.mjs — the operation previously had no test coverage (only Disassemble ARM did). Seven tests cover:

  • the default code segment (regression guard against a behaviour change)
  • the three hex notations from the issue: 0xABC, ABCh, ABC
  • a hex offset (0x1000)
  • invalid code segment and invalid offset, both rejected with a clear message

Full suite results locally:

  • tests/operations — 2287/2287 passing
  • tests/node — 272/272 passing
  • npx grunt lint — clean

The 'Code Segment (CS)' and 'Offset (IP)' arguments were declared as
'number' ingredients, so they were parsed with parseFloat and rejected
hexadecimal input such as '0xABC' with:

    Invalid ingredient value. Not a number: NaN

However, SetBasePosition already parses both values with parseInt(x, 16)
and GetPosition renders them back out with toString(16), so these fields
have always been hexadecimal. The two conversions cancel out visually,
which is why the mismatch went unnoticed. It is observable though: a code
segment entered as '24' becomes 36 decimal internally, which crosses the
documented 'CS >= 36 switches 32-bit output to SEG:OFFSET' threshold.

Both arguments are now 'string' ingredients parsed by a dedicated helper
that accepts bare ('ABC'), prefixed ('0xABC') and suffixed ('ABCh') hex,
and rejects anything else with a named error instead of a NaN message.

The code segment is left-padded to four digits because SetBasePosition
reads it via slice(length - 4), which silently truncated shorter values
('ABC' was read as 'C').

Existing recipes are unaffected: the default is unchanged and numeric
argument values from saved recipes are still handled.

Fixes gchq#2720
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.

Bug report: Disassemble x86: Unable to specify hexadecimal values for code segment

1 participant