Skip to content

Commit afb2ae0

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 a5a118d commit afb2ae0

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
@@ -92,19 +92,23 @@ static void __declspec(naked) HOOK_PreCreateDevice()
9292
push ecx // pDirect3D
9393

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

97-
pushad // Save all registers (32 bytes)
97+
pushad // Save all registers (32 bytes), ESP now at ESP-32
9898

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

0 commit comments

Comments
 (0)