Repository navigation
Conversation
…e it got (#779) On Windows on ARM (x64 emulation, Windows 11 26H1) the game code generator still stops with 0xC0000409 although it runs with Control Flow Guard off. Both generators reach unicorn's first jump table emulation within seconds; the sdk one just has no log line before it, so its log stays empty. unicorn leaves its generated code with VCRUNTIME140's longjmp from a setjmp that saved no frame. That longjmp fast-fails for it when CFG is on (#337), and when a shadow stack is present it always unwinds with RtlUnwindEx, which can't walk the generated code. So the generator is now also started with user-mode shadow stacks off (falling back to CFG off alone where Windows refuses that policy). gen.py now logs a first line with the CPU it runs on (emulated or not) and whether CFG and shadow stacks are on in its process, and a line before its first unicorn run, so a failure's last log line shows how far it got. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
For #779: on Windows on ARM (Snapdragon X2, Windows 11 26H1) the game code generator
lasgen.exe(x64, run under Prism) stops with 0xC0000409 even though it is started with Control Flow Guard off (#337).What we found
sdkandmaingenerators take the same path. Both get to unicorn's first jump table emulation (Module.jump_table→emu_start) within seconds.mainprints its game version line before that, butsdkprints nothing before it, sogen_sdk.logstays empty.mainwas most likely stopped by the runtime whensdkfailed (gamebuild.cstops the rest after a failure). So this is not something only the sdk path does.unicorn.dllis an MSVC build that importslongjmpand__intrinsic_setjmpfrom VCRUNTIME140. Disassembly of the VCRUNTIME140.dll in the windows-arm64 test build shows itslongjmp:__guard_check_icall_fptris not the no-op), it runsint 0x29(fast fail 13) if the jmp_buf frame is 0. That is Game files setup fails: "The game code didn't build, make sure there is 2GB free" #337.rdsspq: if a shadow stack is present it always goes throughRtlUnwindEx, even with frame 0. That unwinds through unicorn's generated code, which has no unwind data, and fails. With no shadow stack and frame 0, it just restores the registers.lasgen.exehas CFG off (pe_no_cfg.py) and is not CETCOMPAT.VCRUNTIME140*.dllare CFG and CETCOMPAT. unicorn, capstone and python312 are neither. Sope_no_cfg.pyneeds no change.Change
spawn_child(Windows) now starts the generator withPROCESS_CREATION_MITIGATION_POLICY2_CET_USER_SHADOW_STACKS_ALWAYS_OFFas well as CFG off. If Windows refuses the pair, it falls back to CFG off alone, then to a plain start.plat_spawn_no_cfgreports both results, and the log says which one applied.gen.pylogs a first line before any work, e.g.sdk: started (x64 on arm64 (emulated), Control Flow Guard off, shadow stacks off, strict shadow stacks off), and a line before its first unicorn run. A failure's last line, whichhelper_failedcopies intolasrecomp.log, then shows how far it got and which mitigations were really on.test_windows_processes.pyalso checks that the child has shadow stacks off. The test stubs follow the new signature.Caveat
This can't be tested here: we have no Windows on ARM machine. The shadow stack theory fits the longjmp code, but
lasgen.exeisn't CETCOMPAT, so on x64 Windows it only gets a shadow stack if one is forced system-wide. Whether 26H1's emulation enables one is unconfirmed. If this build still fails, the new first log line will say whether CFG or shadow stacks were on in the generator anyway (for example, a policy not applied under emulation). That points to the next fix: replacing unicorn'slongjmpimport.Tested:
test_gamebuild_resume.pyon macOS. The Windows build andtest_windows_processes.py(x64 and ARM64) run in CI.test_gamebuild_ios.pycan't run locally (no zig here).🤖 Generated with Claude Code