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-09); 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-09)"
|
|
},
|
|
{
|
|
"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-09)"
|
|
},
|
|
{
|
|
"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-09)"
|
|
},
|
|
{
|
|
"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 g_SpeciesDefTable via SpeciesDef_Get",
|
|
"status": "verified",
|
|
"source": "findings/control-flow/raid-target-pick-verdict.md (lane AR 2026-09-09)"
|
|
}
|
|
]
|
|
}
|