Description
From Claude, take with grain of salt but whatever:
Subject: Antares + Phobos co-load — null deref in EBolt_DrawArcs crashes on every electric bolt
Environment
Syringe 0.7.2.0 (CnCNet branch), gamemd-spawn.exe, injection order Antares.dll, CnCNet-Spawner.dll, Phobos.dll, …. Antares reports "Yuri's Revenge 1.001 (modified). Applying Ares 3.0p1."
Symptom
C0000005 at 0x778F65CB (Phobos.dll base 0x778C0000, RVA 0x365CB = EBolt_DrawArcs), ECX = 0. Reproduced identically in three crash dumps over four days. Fires on the first electric bolt drawn — any Tesla Coil / Tesla Trooper / Tesla Tank shot.
Faulting code — Phobos EBolt_DrawArcs, hook site 0x004C20BC (11 bytes, replaces vanilla cmp [esp+0x28],8 / jge 0x4C2400):
Root cause
BoltTemp::ExtData has exactly one writer in Phobos .text: the hook at 0x004C1F33 (EBolt_Draw_Colors), which caches the lookup for the consumer at 0x004C20BC.
Antares hooks the same address 0x004C1F33 with its own EBolt_Draw_Colors (Ares-parity [Weapon] Bolt.Color1/2/3). That hook replaces the vanilla colour-init loop at 0x4C1F33–0x4C1F64 and therefore must return 0x4C1F66. Under Syringe, a non-zero return is a jump target and suppresses the remaining hooks at that address — so Phobos's EBolt_Draw_Colors never runs, and the global stays zero from BSS.
0x004C20BC is hooked by Phobos only. Antares has nothing there, so the consumer runs against the null producer.
Antares' colour hooks at 0x4C24BE/0x4C25CB/0x4C26CF return targets that jump past Phobos's 0x4C24C3/0x4C25D0/0x4C26D5, so those Phobos hooks are also inert — they'd have dereferenced the same null. EBolt_DrawArcs is the sole survivor of the shadowing, and the sole crash.
Evidence
Minidump ModuleList → EIP resolves into Phobos.dll; export table → EBolt_DrawArcs + 0x1B.
Live value read from the dump: BoltTemp::ExtData @ 0x779F4FA8 = 0x00000000. Symbol name from Phobos.pdb (S_GDATA32, .data-relative 0x1FA8).
.syhks00 diff across all loaded DLLs confirms 0x004C1F33 is the only contested site in the EBolt range, and that 0x004C20BC is uncontested.
Antares source src/Ext/WeaponType/Hooks.Bolt.cpp:31 confirms the unconditional return 0x4C1F66.
Assessment
Antares' behaviour at 0x4C1F33 is correct and its return value is forced by the instruction range it replaces. The fragility is on the Phobos side: one feature split across a producer hook and a consumer hook, with no guard if the producer is shadowed. Any framework legitimately claiming 0x4C1F33 turns 0x4C20BC into a null deref.
Suggested fix (Phobos)
Guard the consumer so a shadowed producer degrades to vanilla instead of crashing:
Same guard applies to EBolt_DrawFirst/Second/ThirdColor, which read the identical global and are currently only saved by Antares jumping over them.
Structurally: the producer/consumer pair is only safe if both sites are uncontested. Merging into a single hook, or reading the per-bolt BoltExt map directly at 0x4C20BC instead of via the cached global, removes the coupling — the map itself is populated correctly, since Phobos's EBolt_CTOR (0x4C1E42) and TechnoClass_FireEBolt_SetExtMap_AfterAres (0x6FD494) both run without interference.
Broader note
Antares and Phobos share 144 hook addresses. Most are CTOR/DTOR/SaveLoad_Prefix observers returning 0, which chain safely. The risk set is the feature hooks that return jump targets — worth an automated .syhks00 diff in CI flagging addresses hooked by both projects where either side returns non-zero.
Phobos Version
b48
Conditions to reproduce
Antares. I never had this with Ares.
https://drive.google.com/file/d/1Zzj79-sTxU2PcrTV5NQpBVkFYLF-GB4e/view?usp=sharing
syringe.log
except.txt
debug.log
INI code
Steps to reproduce
- AI builds SHK
- SHK attacks
- GG
...
Expected behaviour
bzzt bzzt
Actual behaviour
Fatal Error
Additional context
No response
Checklist
Description
From Claude, take with grain of salt but whatever:
Subject: Antares + Phobos co-load — null deref in EBolt_DrawArcs crashes on every electric bolt
Environment
Syringe 0.7.2.0 (CnCNet branch), gamemd-spawn.exe, injection order Antares.dll, CnCNet-Spawner.dll, Phobos.dll, …. Antares reports "Yuri's Revenge 1.001 (modified). Applying Ares 3.0p1."
Symptom
C0000005 at 0x778F65CB (Phobos.dll base 0x778C0000, RVA 0x365CB = EBolt_DrawArcs), ECX = 0. Reproduced identically in three crash dumps over four days. Fires on the first electric bolt drawn — any Tesla Coil / Tesla Trooper / Tesla Tank shot.
Faulting code — Phobos EBolt_DrawArcs, hook site 0x004C20BC (11 bytes, replaces vanilla cmp [esp+0x28],8 / jge 0x4C2400):
Root cause
BoltTemp::ExtData has exactly one writer in Phobos .text: the hook at 0x004C1F33 (EBolt_Draw_Colors), which caches the lookup for the consumer at 0x004C20BC.
Antares hooks the same address 0x004C1F33 with its own EBolt_Draw_Colors (Ares-parity [Weapon] Bolt.Color1/2/3). That hook replaces the vanilla colour-init loop at 0x4C1F33–0x4C1F64 and therefore must return 0x4C1F66. Under Syringe, a non-zero return is a jump target and suppresses the remaining hooks at that address — so Phobos's EBolt_Draw_Colors never runs, and the global stays zero from BSS.
0x004C20BC is hooked by Phobos only. Antares has nothing there, so the consumer runs against the null producer.
Antares' colour hooks at 0x4C24BE/0x4C25CB/0x4C26CF return targets that jump past Phobos's 0x4C24C3/0x4C25D0/0x4C26D5, so those Phobos hooks are also inert — they'd have dereferenced the same null. EBolt_DrawArcs is the sole survivor of the shadowing, and the sole crash.
Evidence
Minidump ModuleList → EIP resolves into Phobos.dll; export table → EBolt_DrawArcs + 0x1B.
Live value read from the dump: BoltTemp::ExtData @ 0x779F4FA8 = 0x00000000. Symbol name from Phobos.pdb (S_GDATA32, .data-relative 0x1FA8).
.syhks00 diff across all loaded DLLs confirms 0x004C1F33 is the only contested site in the EBolt range, and that 0x004C20BC is uncontested.
Antares source src/Ext/WeaponType/Hooks.Bolt.cpp:31 confirms the unconditional return 0x4C1F66.
Assessment
Antares' behaviour at 0x4C1F33 is correct and its return value is forced by the instruction range it replaces. The fragility is on the Phobos side: one feature split across a producer hook and a consumer hook, with no guard if the producer is shadowed. Any framework legitimately claiming 0x4C1F33 turns 0x4C20BC into a null deref.
Suggested fix (Phobos)
Guard the consumer so a shadowed producer degrades to vanilla instead of crashing:
Same guard applies to EBolt_DrawFirst/Second/ThirdColor, which read the identical global and are currently only saved by Antares jumping over them.
Structurally: the producer/consumer pair is only safe if both sites are uncontested. Merging into a single hook, or reading the per-bolt BoltExt map directly at 0x4C20BC instead of via the cached global, removes the coupling — the map itself is populated correctly, since Phobos's EBolt_CTOR (0x4C1E42) and TechnoClass_FireEBolt_SetExtMap_AfterAres (0x6FD494) both run without interference.
Broader note
Antares and Phobos share 144 hook addresses. Most are CTOR/DTOR/SaveLoad_Prefix observers returning 0, which chain safely. The risk set is the feature hooks that return jump targets — worth an automated .syhks00 diff in CI flagging addresses hooked by both projects where either side returns non-zero.
Phobos Version
b48
Conditions to reproduce
Antares. I never had this with Ares.
https://drive.google.com/file/d/1Zzj79-sTxU2PcrTV5NQpBVkFYLF-GB4e/view?usp=sharing
syringe.log
except.txt
debug.log
INI code
Steps to reproduce
...
Expected behaviour
bzzt bzzt
Actual behaviour
Fatal Error
Additional context
No response
Checklist