backend: trust the signature over a stale pinned RVA, and stop the guard log line claiming the shield is off - #51
Merged
adiazpar merged 2 commits intoJul 28, 2026
Conversation
ae_pick_engine_fn cross-checks each signature-resolved engine leaf against a hardcoded fallback RVA and, on a mismatch, REFUSED the signature and used the RVA instead. That is backwards on the only case it can actually fire in. A mismatch means the recorded RVA no longer describes the running build -- either DOOM was patched, or the value was wrong when it was written (the four addresses corrected in 8d50f80 were exactly that). In both cases the RVA points into arbitrary code while the signature is correct, so preferring the RVA guarantees the outcome the cross-check exists to prevent. The scan is not a loose match: sig_resolve_one enforces uniqueness across the whole executable range and reports AMBIGUOUS rather than guessing, so a lone hit is a strong result. The RVA still earns its place. It makes drift VISIBLE -- the log line names the leaf and now tells you to re-derive it -- and it is still used when the scan misses ENTIRELY, the one case where there is nothing better and the caller's own guards have to carry the risk. No behavior change on the pinned build: both leaves routed through this helper resolve to their recorded RVA, so the changed branch is never reached. The fix matters on a patched build, which is precisely where the old policy was harmful. Build clean; 16/16 native tests, sig_test 59/59 unique with 0 RVA-mismatches, hooktol_test 3/3 with 0 failures; gofmt/vet/go test clean. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… is off The render-node guard has been commented out since the 2026-07-05 shield-off diagnostic, and its log line still read: rendernode-guard: TEMP-DISABLED (shield-off diagnostic build) The fault shield was turned off alongside the guard for that diagnostic, was cleared by it, and was RE-ENABLED the same day -- see shield_install() at the end of bootstrap_thread. Only the guard stayed off. The wording was never updated, so every launch still reports a shield state that has not been true for weeks, and it reads as a serious regression to anyone scanning the log. Wording only. sh_palette_guard_install stays commented out exactly as it was, so guard behavior is unchanged. The surrounding comment now states plainly that the fault shield is ACTIVE and records why the guard stays off: the render-node root cause (a reclassed node-less timeline keeping the pasted command's stale render-node +0x70) was fixed at the source in ae_apply_one, which makes the guard a redundant mitigation rather than a load-bearing one. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
adiazpar
approved these changes
Jul 28, 2026
adiazpar
left a comment
Contributor
There was a problem hiding this comment.
Reviewed against the diff, not the description. Both changes verified: ae_pick_engine_fn now returns the signature on mismatch, and the dllmain change is comment/log wording only with sh_palette_guard_install still commented out. Validated against the real pinned DOOMx64vk image rather than CI alone (CI has no game image): sig_test 59/59 unique, 0 RVA-mismatches, hooktol_test 3/3, all 16 native suites green. The zero mismatches independently confirm the changed branch is unreachable on the pinned build, so the policy change is inert here and only takes effect on a patched build.
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.
What this changes
Two follow-ups to
8d50f80, both about the backend reporting build-pinned state honestly. One commit each.1.
ae_pick_engine_fnpreferred a stale RVA over a good signature hit.The helper cross-checks each signature-resolved engine leaf against a hardcoded fallback RVA, and on a
mismatch it REFUSED the signature and used the RVA. That is backwards on the only case it can fire in.
A mismatch means the recorded RVA no longer describes the running build -- either DOOM was patched, or
the value was wrong when written (the four addresses corrected in
8d50f80were exactly that). In bothcases the RVA points into arbitrary code while the signature is correct, so preferring it guarantees the
outcome the cross-check exists to prevent.
The scan is not a loose match:
sig_resolve_oneenforces uniqueness across the whole executable rangeand reports
AMBIGUOUSrather than guessing, so a lone hit is a strong result. The RVA still makes driftvisible (the log line names the leaf and now says to re-derive it) and is still used when the scan misses
entirely, the one case with nothing better.
No behavior change on the pinned build -- both leaves routed through this helper resolve to their
recorded RVA, so the changed branch is never reached. It matters on a patched build, which is where the
old policy was harmful.
2. The rendernode-guard log line claimed the fault shield was off.
Every launch printed
rendernode-guard: TEMP-DISABLED (shield-off diagnostic build). The shield wasturned off alongside the guard for the 2026-07-05 diagnostic, was cleared by it, and was re-enabled the
same day -- only the guard stayed off. The wording was never updated, so the log reported a shield state
that had not been true for weeks and reads as a serious regression to anyone scanning it.
Wording only:
sh_palette_guard_installstays commented out exactly as it was, so guard behavior isunchanged. The surrounding comment now states the shield is ACTIVE and records why the guard stays off
(the render-node root cause was fixed at the source in
ae_apply_one).Independent corroboration of
8d50f80Worth noting since it was found separately: the four addresses in
8d50f80were reproduced here from aSteamless-unpacked image of the pinned build, arriving at the same four values. Two additional details
that support the "two builds" framing in that commit:
DOOMx64vk.exeis SteamStub Variant 3.1 (x64) with an encrypted.text;searching the shipped file for any engine pattern returns 0 matches. SteamStub decrypts in place and
does not relocate -- shipped and unpacked section tables are identical apart from
.bind-- so theunpacked image's RVAs equal the running module's exactly.
0x7FF6E31B0000, the prefab ctor resolved at0x7FF6E36FD0A0(= RVA
0x54D0A0). The previously stored0x11AC8D0would require a base of0x7FF6E25507D0, whichis not 64 KB aligned and so is impossible for a loaded module.
Checklist
original-SnapHak content is pasted into the repo.
.dll/.exe/.obj/.pdb/.zip...) -- the source is the only deliverable..c/.h/.cpp/.ps1).build.ps1clean.tests\run-tests.ps1 -Doom <unpacked pinned image>: all 16 native tests pass,sig_test59/59 unique, 0 RVA-mismatches,
hooktol_test3/3 hook-tolerant, 0 failures.gofmt -lclean,go vet ./...clean,go test ./...ok.package.ps1->snapmap-plus install --local dist.8d50f80-- backend attached,59/59sigs resolved withrva-pinned 59, rva-shifted 0, bothC2 siglinesMATCH, and SWF textcopy/paste plus prefab stage-paste were exercised working. The branch build itself has not been run
in-game; note that change 1 is unreachable on the pinned build and change 2 is text-only.
build; both changes are explained in-place in the code comments they touch.