Skip to content

Commit 65f5afc

Browse files
committed
Fix SA crash at 0x00897C28 (dump name wrongly identifies it as 0x003F0090), likely 'caused' by VS2026 but a latent stack offsets bug since its introduction (736660b).
Theory: VS2026 changed changed how inline assembly works. Probably something with different stack alignment, optimization choices, register allocation, calling convention optimizations, or code generation. (This can all be relevant to spot similar bugs manifesting now across hooks). The broken, now patched, assembly code was reading stack values from wrong offsets, and while the old compiler's code generation might have accidentally put "harmless" values at those wrong locations, the new compiler's different stack layout or register usage puts critical values (like 0xC97C28 - the address of _RwD3DDevice) at those locations. Affected only users with "optimus-alt-startup" setting enabled
1 parent ce75b6e commit 65f5afc

File tree

1 file changed

+15
-11
lines changed

1 file changed

+15
-11
lines changed

Client/multiplayer_sa/CMultiplayerSA_Direct3D.cpp

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -90,19 +90,23 @@ void _declspec(naked) HOOK_PreCreateDevice()
9090
push ecx // pDirect3D
9191

9292
// Now we have 7 parameters on stack (28 bytes)
93-
// Stack layout: [pDirect3D][Adapter][DeviceType][hFocusWindow][BehaviorFlags][pPresentationParameters][ppReturnedDeviceInterface]
93+
// Stack layout at ESP: [pDirect3D][Adapter][DeviceType][hFocusWindow][BehaviorFlags][pPresentationParameters][ppReturnedDeviceInterface]
9494

95-
pushad // Save all registers (32 bytes)
95+
pushad // Save all registers (32 bytes), ESP now at ESP-32
9696

97-
// Pass parameters to OnPreCreateDevice - stack offset is now 32 (pushad) + 28 (pushes) = 60
98-
push [esp+60+24] // ppReturnedDeviceInterface
99-
push [esp+60+20] // pPresentationParameters
100-
lea eax,[esp+60+16] // BehaviorFlags as pointer
101-
push eax
102-
push [esp+60+12] // hFocusWindow
103-
push [esp+60+8] // DeviceType
104-
push [esp+60+4] // Adapter
105-
push [esp+60+0] // pDirect3D
97+
// Pass parameters to OnPreCreateDevice
98+
// After pushad, params start at ESP+32. Each push decreases ESP by 4,
99+
// so [esp+32+4*6] effectively walks backward through the params:
100+
// 1st access: ESP+56 = ppReturnedDeviceInterface, then ESP -= 4
101+
// 2nd access: ESP+56 = pPresentationParameters (was at ESP+52), etc.
102+
push [esp+32+4*6] // ppReturnedDeviceInterface
103+
push [esp+32+4*6] // pPresentationParameters
104+
lea eax,[esp+32+4*6] // BehaviorFlags as pointer
105+
push eax
106+
push [esp+32+4*6] // hFocusWindow
107+
push [esp+32+4*6] // DeviceType
108+
push [esp+32+4*6] // Adapter
109+
push [esp+32+4*6] // pDirect3D
106110
call OnPreCreateDevice
107111
add esp, 4*7
108112
popad

0 commit comments

Comments
 (0)