Open
Description
Game can crash when clicking on player icon in Replay Mode. It is not 100%, but happens very regularly.
Here is a Replay for Zero Hour 1.04 where crash is reproducible:
GenTool fixes this crash as following:
Inject naked function call at address 0x5FC8F5
taking 6 bytes to call naked function.
// CPU Disasm (Zero Hour 1.04)
// Address Hex dump Command Comments
// 005FC8F0 |. A1 A4A2A200 MOV EAX,DWORD PTR DS:[0A2A2A4]
// 005FC8F5 |. E8 B6B7A00F MOV CL,BYTE PTR DS:[EAX+86C] ; inject here
// 005FC8FB |. 84C9 TEST CL,CL
// 005FC8FD |. 74 72 JE SHORT 005FC971
// 005FC8FF |. 8B0D E0B6A200 MOV ECX,DWORD PTR DS:[0A2B6E0]
// 005FC905 |. 8B5424 28 MOV EDX,DWORD PTR SS:[LOCAL.70]
// 005FC909 |. 3991 B8020000 CMP DWORD PTR DS:[ECX+2B8],EDX
// 005FC90F |. 75 60 JNE SHORT 005FC971
// 005FC911 |. 8BCD MOV ECX,EBP
// 005FC913 |. E8 A831F5FF CALL 0054FAC0 ; [game.0054FAC0
// 005FC918 |. 8B0D 88C0A200 MOV ECX,DWORD PTR DS:[0A2C088]
// The game crashes in function 0x54FAC0 -> called by multiple functions
// If you mess with 0x54FAC0, you can cause mismatches!
// It seems the object pointed to by EBP is missing data in a certain frames
// and the function wants to read data from it
// this will cause crashes as the memory is not valid
// To fix this, I figured that at EBP+C the value is always 0 when it crashes
// and greater one if not crashing
// So just skip the routine by moving 0 into CL and the work is done
//////////////////////////////////////////////////////////////////////////////////////
DWORD ccFixUnitSelectCrashRet;
__declspec(naked) void CC_FixUnitSelectCrash_ZH()
{
__asm
{
pop [ccFixUnitSelectCrashRet]
cmp dword ptr [ebp+0xC], 0
je Fix
mov cl, 1
jmp End
Fix:
mov cl, 0
End:
push [ccFixUnitSelectCrashRet]
ret
}
}