D399 - The payloads were never handed what they read, and the instrument could not see it
measured - 2026-08-30
0x2001 had been recorded as a constant
elfldr and pldmgr die on, invariant to every
handoff variation tried. It is a module handle, and the
reason it looked like a constant is that nothing here had ever reached
the code that uses it.
What the hardware run said first
sceKernelLoadStartModule on a target console returned
0x15 and 0x14 for application modules and
0x2001 for a system one (D398). That is a
numbering scheme, not an error.
What the payload's own instructions said second
The entry function reads its first argument as a pointer to a table of function pointers and calls through field zero straight away:
4a76: mov %rdi,%rbx ; the argument, kept
4a8c: mov $0x1,%edi ; a module handle
4a91: call *(%rbx) ; resolve a name, through field zero
...
4aa2: mov $0x2001,%edi ; and if that failed, the system one
4aa7: call *(%rbx)
So 0x2001 is the second handle it
tries, in a fallback path. It was never a value this project produced;
it is a value the payload carries, and it agrees exactly with what
hardware returns for a system module. Two independent sources, one
number.
Why it never got there
The guest was entered with the argument count and vector a title
expects, so rdi was argc, which is 1.
call *(%rbx) then reads address 1. That is the whole of the
wall three sessions arrived at from different directions: not a handoff
field with a wrong value, but the handoff never being handed over.
Entered with the resolver table instead, the same payload resolves
sceKernelDlsym and getpid through it and makes
three calls where it previously made none.
The instrument was reporting on a structure the guest never received
orbistoun-cli handoff poisons one field and asks whether
the guest used it. It set the poison and nothing else -
so every run it made was under whatever entry argument the configuration
named, and for a bare payload that is not the handoff. It poisoned
fields of a block nobody was given and concluded no field was
reached.
That is the third principle's failure one level up: a report saying more than its measurement supports, and it is the eighth instrument in this project caught doing it. The pattern is identical every time - the tool varies one input and assumes the rest of the world is the shape it has in mind.
ORBISTOUN_ENTRY_ARGUMENT now exists so the instrument
can select what it is asking about, and it is registered with
Experiments in the same change - an unregistered setting is
one a run can be under while reporting itself ordinary, which is how an
honest status slot got written by a propped run once already. An
unrecognised value says so rather than silently meaning the default,
because a misspelled setting that behaves exactly like no setting is
what let the handoff instrument stay wrong for as long as it did.
Adding a setting touches three lists, not two
The registry, the DECLARED mirror beside its test, and
Experiments. This change remembered the third - the one
that was forgotten last time and let a propped run write an honest
record - and missed the second, which the env crate's own guard caught
immediately.
Worth writing down rather than filing as carelessness: the count is three, the failure mode of each is different, and knowing that the last time this went wrong it was a different one of the three is exactly the information a person adding the next setting does not have.
What it measured once it could
For elfldr: field 0 is called, fields 1 and 2 are read,
field 5 is written. That is structure knowledge taken
from the guest rather than guessed, and it is the first of it.
And what fields one and two are
Reading the sites the instrument named, both are pointers to a pair of 32-bit integers, and the payload rejects the lot if either is negative:
682b: mov 0x10(%rdi),%rcx ; field two, as a pointer
682f: mov (%rcx),%edx ; an int
683e: js 7469 ; negative, and the whole call returns -9
6844: mov 0x4(%rcx),%ecx ; a second int beside it
6855: mov 0x8(%rdi),%rcx ; field one, the same shape again
Two non-negative integers, in pairs, checked before anything else runs: that is the shape of descriptors, and a loader daemon wanting two pairs of them is unremarkable. It is not called proven here - the shape is measured, the meaning is inferred from it - but it is specific enough to act on, and the next run says whether it was right. Markers will not do: a marker is a large address whose low half reads as a negative int, which is the one value this code refuses.
What is deliberately not changed
The default entry argument stays as it is. Which one a guest wants is a fact about the guest - payloads want the resolver table, titles want the argument vector - and six real titles are measured against the current default. Choosing per guest is the right shape and it needs its own change, with those six re-measured under it.