Second decode error in the same investigation; stopping rather than trusting this decoder

Following e1482ab I disassembled the function supplying r2 and made two errors,
both mine. First I read the jal target as 0x2ee178 when it is 0x2ee138 --
0x0bb84e << 2 is 3,072,312. Second, at the correct address the bytes do not
decode: d8a10000 is opcode 0x36, which is not a valid MIPS major opcode for
user-space code. The coherent readings are that this is data, that the decomp's
extent is mis-bounded, or that the jal target is still wrong.

Stopping here deliberately. An un-masked branch target that reported a false
negative, and a transposed address that produced plausible-looking garbage, are
enough to make anything else from this decoder untrustworthy. The next step is not
another immediate scan or another hand-decoded disassembly -- it is
tools/overlay-anchors, which links capstone, verified against a known-good
function first.

The established chain, with nothing inferred beyond it:

    0x3a3d70  jal   0x2ee138     target decoded, callee unidentified
    0x3a3d84  jal   0x3a7c30     r2 = return value of the above
    0x3a7c30                     580 bytes, never writes r2
    0x3a7d88  jal   0x3a8060     passes r2 through
    0x3a8060  addiu r17, r18, 0xc0  with 0xd0 and 0xe0; 16-byte-stride walk

What 0x2ee138 returns is unknown, and it is the single remaining link between the
program and moby_classes.offset.

284 passing with the disc present, clippy clean.
This commit is contained in:
2026-10-14 05:56:00 +02:00
parent e1482abd75
commit d97e7df41f
+42
View File
@@ -2314,3 +2314,45 @@ worth nothing until the decoder is checked against a case where the answer is
already known. `jal 0x3a8060` decoded correctly under a different constant in the
same probe and I did not notice, because one probe reporting a plausible number is
as convincing as one reporting zero.
### Second decode error, and why the hand-rolled decoder is now untrusted
Following `e1482ab`, I disassembled the function that supplies `r2`. Two errors,
both mine:
**First: transposed digits.** I read the `jal` target as `0x2ee178`. It is
`0x2ee138` -- `0x0bb84e << 2` is 3,072,312. I disassembled the wrong address and
got obviously nonsensical output, which is the only reason it was caught.
**Second, and the one that matters: at the correct address the bytes do not
decode.**
0x2ee138 d8a10000 opcode 0x36
0x2ee13c d8c20000 opcode 0x36
0x2ee140 4bc2086c opcode 0x12 (COP2)
0x2ee144 00000000 nop
0x2ee148 03e00008 jr $ra
`0x36` is not a valid MIPS major opcode for user-space code. The only coherent
readings are that this is data rather than code, that the function extent from the
decomp is mis-bounded, or that the `jal` target is still wrong.
**I am stopping here rather than continuing.** Two decode bugs in the same
investigation -- an un-masked branch target that reported a false negative, and a
transposed hex address that produced plausible-looking garbage -- are enough to
make anything else produced by this same hand-rolled decoder untrustworthy. The
next step is not another immediate scan or another hand-decoded disassembly. It is
to use `tools/overlay-anchors`, which links capstone and has a proper MIPS
decoder, and to verify it against a known-correct function before trusting
anything it says.
The chain as far as it is established, with nothing inferred beyond it:
0x3a3d70 jal 0x2ee138 target decoded, callee not yet identified
0x3a3d84 jal 0x3a7c30 r2 = v0, the return value of the above
0x3a7c30 580 bytes, never writes r2
0x3a7d88 jal 0x3a8060 passes r2 through
0x3a8060 addiu r17, r18, 0xc0 with 0xd0 and 0xe0; 16-byte-stride walk
Everything above that is verified; what `0x2ee138` returns is **unknown**, and it
is the single remaining link between the program and `moby_classes.offset`.