Skip to content

Game crashes when exiting Replay Mode while player places beacon #76

Description

@xezon

Game crashes when exiting Replay Mode while player places beacon. Maybe also happens in regular match. However, this crash is easy to reproduce in Replay Mode when using Frame Step functionality from GenTool to reach specific frame in Replay.

GenTool fixes this crash by injecting naked function at address 0x4544C1 taking 6 bytes.

//////////////////////////////////////////////////////////////////////////////////////

// CPU Disasm (Zero Hour 1.04)
// Address   Hex dump          Command                                  Comments
// 004544C0  /$  51            PUSH ECX                                 ; game.004544C0(guessed Arg1)
// 004544C1  |.  8B81 DC000000 MOV EAX,DWORD PTR DS:[ECX+0DC]
// 004544C7  |.  85C0          TEST EAX,EAX
// 004544C9  |.  56            PUSH ESI
// 004544CA  |.  8B7424 0C     MOV ESI,DWORD PTR SS:[ARG.1]
// 004544CE  |.  C74424 04 000 MOV DWORD PTR SS:[LOCAL.0],0
// 004544D6  |.  8906          MOV DWORD PTR DS:[ESI],EAX
// 004544D8  |.  74 07         JZ SHORT 004544E1
// 004544DA  |.  50            PUSH EAX                                 ; /pTarget => [ARG.ECX+0DC]
// 004544DB  |.  FF15 2C929300 CALL DWORD PTR DS:[<&KERNEL32.Interlocke ; \KERNEL32.InterlockedIncrement
// 004544E1  |>  8BC6          MOV EAX,ESI
// 004544E3  |.  5E            POP ESI
// 004544E4  |.  59            POP ECX
// 004544E5  \.  C2 0400       RETN 4

//////////////////////////////////////////////////////////////////////////////////////

DWORD ccFixBeaconCrashRet;
__declspec(naked) void CC_FixBeaconCrash_ZH()
{
	__asm
	{
		pop [ccFixBeaconCrashRet]
		test ecx, ecx
		je Fix
		MOV EAX, DWORD PTR DS:[ECX+0xDC]
		jmp End
	Fix:
		mov eax, 0
	End:
		push [ccFixBeaconCrashRet]
		ret
	}
}

Activity

  1. added
    BugSomething is not working right, typically is user facing
    GenToolRelates to GenTool
    CriticalSeverity: Minor < Major < Critical < Blocker
    ExecutableIs game code related
    on Oct 5, 2021
  2. reopened this on Dec 21, 2021
  3. added theissue type on Mar 4, 2025
  4. added
    ZHRelates to Zero Hour
    and removed
    ExecutableIs game code related
    on Mar 4, 2025
  5. added this to the Stability fixes milestone on Apr 28, 2025
  6. xezon commented on Jun 1, 2025

    @xezon
    Author

    Attached replay that crashes when exiting the Replay playback at logic frame 115.

    beacon_crash_frame_115.zip

    Callstack

    >	generalszh.exe!AsciiString::AsciiString(const AsciiString & stringSrc) Line 87	C++
     	[Inline Frame] generalszh.exe!PlayerTemplate::getBeaconTemplate() Line 109	C++
     	generalszh.exe!GameLogic::logicMessageDispatcher(GameMessage * msg, void * userData) Line 1614	C++
     	generalszh.exe!GameLogic::processCommandList(CommandList * list) Line 2565	C++
     	generalszh.exe!GameLogic::update() Line 3735	C++
     	generalszh.exe!Win32GameEngine::update() Line 93	C++
     	generalszh.exe!GameEngine::execute() Line 823	C++
     	generalszh.exe!GameMain(int argc, char * * argv) Line 47	C++
     	generalszh.exe!WinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, char * lpCmdLine, int nCmdShow) Line 1038	C++
     	[Inline Frame] generalszh.exe!invoke_main() Line 102	C++
     	generalszh.exe!__scrt_common_main_seh() Line 288	C++
     	kernel32.dll!75abfcc9()	Unknown
     	[Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]	
     	ntdll.dll!772682ae()	Unknown
     	ntdll.dll!7726827e()	Unknown
    Exception thrown at 0x00672BBA in generalszh.exe: 0xC0000005: Access violation reading location 0x000000D0.
    

    Crashing code

    void GameLogic::logicMessageDispatcher( GameMessage *msg, void *userData )
    {
    ...
      case GameMessage::MSG_PLACE_BEACON:
      {
        // how many does this player have active?
        Coord3D pos = msg->getArgument( 0 )->location;
        Region3D r;
        TheTerrainLogic->getExtent(&r);
        if (!r.isInRegionNoZ(&pos))
          pos = TheTerrainLogic->findClosestEdgePoint(&pos);
        const ThingTemplate *thing = TheThingFactory->findTemplate( thisPlayer->getPlayerTemplate()->getBeaconTemplate() ); // <--- xezon: crashes here when getPlayerTemplate() returns NULL
        if (thing && !TheVictoryConditions->hasSinglePlayerBeenDefeated(thisPlayer))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugSomething is not working right, typically is user facingCriticalSeverity: Minor < Major < Critical < BlockerGenToolRelates to GenToolZHRelates to Zero Hour

    Type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions