Decides lane AG's section 3.3 final paragraph, which lane AD correctly reported it could not separate on sector 832. STATIC: FUN_00841700 is the writer AG's section 7 lists as not found. It resizes the +0x0c vector to the length of the systems vector -- the container trfr indexes -- and fills it with containingSector[system.Idx] = sector. It runs from the deserialiser, so a loaded save has it populated. G_B1a cannot reject a valid trfr. LIVE: four raiders parked (2 CR on sector 832, 2 DE on sector 816), probes=8. Slot13RngCalleeA entered 4x/turn at 4 words every turn; on turn 42 the pick fired at 0x0088b613, calls=1 words=1, and the tail cost 5 words against 4 elsewhere. The same run carries its own control: B entered on 832 twice at 0 words. B costs ONE word, not two: FUN_00820af0's third short-circuit is a flag word InitTable sets only for Human and Zuul, so AG's committed 3-words-on-success is 2. Two hooks=off processes gave byte-identical autosaves, and so did a probes=8 process -- an oracle pair and a whole-save byte-neutrality proof for the instrument, both firsts on this lineage. Also first firings of 0x008939ee (rule 20's case study) and 0x00820c1b.
52 lines
5.2 KiB
JSON
52 lines
5.2 KiB
JSON
{
|
|
"entries": [
|
|
{
|
|
"name": "TradeManager_RebuildSystemToSectorTable",
|
|
"addr": "0x00841700",
|
|
"convention": "thiscall",
|
|
"prototype": "void __thiscall (TradeManager* this) // 214 B, 0x00841700-0x008417d5, decoded to the next function start. THE WRITER OF TradeManager+0x0c that lane AG's gate-indexed audit section 7 lists as NOT FOUND, and it settles AG section 3.3: (1) `lea ecx,[this+0x0c]; push 0; call 0x00459f70` clears the vector; (2) resizes it to `count(([this+4])+0x40 .. +0x44)` -- the SYSTEMS vector, the very container FUN_00841cd0 indexes with rt->trfr at 0x00841d36 -- growing with vector::_Insert_n 0x0050e6a0 (fill value NULL) or shrinking with erase 0x004ddfc0; (3) walks this->+0x1c (the SECTOR vector) x sector->+0x78 (that sector's MEMBER SYSTEM vector) and executes `mov [this->+0x0c + m->+0x5c * 4], sector` at 0x008417a8. ServerSystem+0x5c is the serialised `Idx` field (objects/layouts.md, grade verified), so this is literally `containingSector[system.Idx] = sector`. CONSEQUENCE: TradeManager+0x0c is a PER-SYSTEM table whose length is BY CONSTRUCTION the length of the container trfr indexes, so Slot13RngCalleeB's bounds check G_B1a can never reject a valid trfr and 0x0088b613 is reachable. Five callers; FUN_00858a10 is the DESERIALISER (ReadInt/ReadFloat throughout, calls this at 0x00858f07), so the table is rebuilt on load",
|
|
"status": "verified",
|
|
"source": "findings/control-flow/raid-target-pick-verdict.md (lane AR 2026-09-08); disassembled from dumps/sots.exe to the next function start"
|
|
},
|
|
{
|
|
"name": "TradeManager_GetSectorForSystem",
|
|
"addr": "0x00841c70",
|
|
"convention": "thiscall",
|
|
"prototype": "void __thiscall (TradeManager* this, ServerSystem* sys) // 83 B, RET 4. Reads TradeManager+0x0c back the same way the writer fills it: bounds-checks `sys->+0x5c` (= the `Idx` tag) against `(this->+0x10 - this->+0x0c)/4` and indexes `((TradeSector**)this->+0x0c)[sys->Idx]`, then passes `sector + 0x78` -- the sector's MEMBER SYSTEM vector, the same vector the writer iterates -- to FUN_0059ec00 with the system. Independent confirmation that +0x5c on the indexing object and +0x78 on the table element are the two halves of one relation. Tail-calls TradeManager_RebuildSystemToSectorTable 0x00841700",
|
|
"status": "verified",
|
|
"source": "findings/control-flow/raid-target-pick-verdict.md (lane AR 2026-09-08)"
|
|
},
|
|
{
|
|
"name": "Vector_ResizePtr",
|
|
"addr": "0x00459f70",
|
|
"convention": "thiscall",
|
|
"prototype": "void __thiscall (std::vector<void*>* this, size_t n) // RET 4. resize(n): when size > n it moves _Mylast down to _Myfirst + n (the shrink arm the trade manager uses with n = 0, i.e. clear); when size < n it calls 0x00538180 to grow",
|
|
"status": "verified",
|
|
"source": "findings/control-flow/raid-target-pick-verdict.md (lane AR 2026-09-08)"
|
|
},
|
|
{
|
|
"name": "SpeciesDef_InterceptFlagWord",
|
|
"addr": "0x00b10b44",
|
|
"convention": "data",
|
|
"prototype": "int, at g_SpeciesDefTable + 0*0x184 + 0x144 -- i.e. the +0x144 slot of SpeciesDef[0]. The SAME slot in every element is written ONLY by SpeciesDef_InitTable 0x005453a0 at 0x0054562f (`or [ebx+0x144],2` when the element's species index is 5) and 0x00545638 (`or [ebx+0x144],1` when it is 0). So the word is 1 for HUMAN, 2 for ZUUL and 0 for the other five species, and SpeciesDef_HasInterceptFlag 0x0053baf0 tests it. This is the value that decides whether TradeManager's raid interception draws a NextFloat at 0x00820c1b; the table base g_SpeciesDefTable 0x00b10a00 and accessor SpeciesDef_Get 0x00545cc0 were already named in addresses.json and this lane's independent derivation reproduced both",
|
|
"status": "verified",
|
|
"source": "findings/control-flow/raid-target-pick-verdict.md (lane AR 2026-09-09)"
|
|
},
|
|
{
|
|
"name": "SpeciesDef_HasInterceptFlag",
|
|
"addr": "0x0053baf0",
|
|
"convention": "thiscall",
|
|
"prototype": "bool __thiscall (SpeciesDef* this) // 12 B: `xor eax,eax; cmp [ecx+0x144],eax; setne al; ret`. TRUE for HUMAN (species 0) and ZUUL (species 5) only. This is the third disjunct of FUN_00820af0's short-circuit, so a HUMAN raider intercepts at frac = 1.0 and the NextFloat at 0x00820c1b IS NOT DRAWN -- correcting lane AG section 3.3's committed `3 words on a success` and section 5.2's `B costs 2 on a success`, both of which hold only for a raider whose species does not set this flag",
|
|
"status": "verified",
|
|
"source": "findings/control-flow/raid-target-pick-verdict.md (lane AR 2026-09-08)"
|
|
},
|
|
{
|
|
"name": "StarFleet_GetCrewSpeciesForIntercept",
|
|
"addr": "0x0081a2d0",
|
|
"convention": "cdecl",
|
|
"prototype": "int __cdecl (StarFleet* fleet) // returns the fleet owner's species (FUN_0071e280(fleet)->+0x5c) on the default path; only when that species is 4 does it scan the fleet's ship vector (+0xa4..+0xa8) for a ship whose design->+0x14->+0xac..+0xb4 slot is non-null and return THAT record's +0x4 instead. Called TWICE from FUN_00820af0 (0x00820bcf, 0x00820bdd) -- once compared against 1, once used as the index into SpeciesDef_Table",
|
|
"status": "verified",
|
|
"source": "findings/control-flow/raid-target-pick-verdict.md (lane AR 2026-09-08)"
|
|
}
|
|
]
|
|
}
|