Repository navigation
fix(patternfinder): don't follow a JMP thunk out of the game module - #17
Merged
TrackAndTruckDevs merged 1 commit intoOct 5, 2026
Conversation
Owner
|
merging :) |
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.
Summary
Fixes
FileSystemDataFinderfailing withPatternFinder: Find(block): memory access exception (code 0xC0000005)for users who run a third-party tool that inline-hooks a game function.Root cause
PatternFinder::Find(block)starts its scan at a function address. If the first byte is0xE9(aJMP rel32), it assumes a compiler thunk and follows the jump before scanning.A third-party inline hook (MinHook, as used by TruckersMP and others) overwrites a function's entry with exactly such a
JMP, pointing into its own trampoline allocation.Find(block)followed it and scanned 512 bytes of that foreign allocation instead of the game function. The trampoline sits near the end of a small committed page, so the scan read past the page boundary and raised0xC0000005.The SEH guard catches the exception, so it is logged rather than crashing, but every dependent step is lost:
Fix
Only follow the
JMPthunk when its target stays inside the main module. A real thunk resolves within the.exe; a third-party hook jumps out to its own allocation. When the target is outside the module, scan the original function instead. The signatures sit past the few bytes the hook overwrites at the entry, so they still resolve.Changes in
src/Utils/PatternFinder.cpp:IsAddressInMainModule(), which tests an address against the main module's mapped section range (cached).Find(block)follows the thunk only when the target is in-module; otherwise it scans the original bytes.Testing
Reproduced the exact failure in-game by simulating an inline hook on
UFS_RegisterMount(aJMPinto a trampoline at the end of a single committed page), without TruckersMP. Verified both before and after the fix on an MSVC build (before: exception caught and logged, as users see it).With the fix, the same simulated hook no longer traps SPF:
No memory access exception, and
FileSystemDataFinderresolves fully.