Repository navigation
Fix ARM PLD/PLI handling - #393
Open
Yonatan Ziv (yonatan007ziv) wants to merge 2 commits into
Open
Yonatan Ziv (yonatan007ziv) wants to merge 2 commits into
Yonatan Ziv (yonatan007ziv) wants to merge 2 commits into
Conversation
The mask 0xFE70F000 clears bits 19:16, but the comparand 0xF81FF000 keeps 0xF there, so the test can never hold and the PLD/PLI block is dead code. Zero the Rn nibble to match the mask.
PLD/PLI (literal) are encoded as PC-relative loads, so the literal load check matches them first and CopyLiteralLoad32 reads their 0b1111 hint field as Rt == PC, emitting "ldr pc, [pc, #imm]". The preload hint becomes a branch to arbitrary data. Move the hint check above it so those instructions reach the noop conversion.
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
CDetourDis::CopyLoadAndStoreSinglemishandles Thumb-2 memory hints. Twodefects compound: the hint check can never fire, and once repaired it is still
shadowed by the PC-relative literal-load check above it. The result is that a
PLD/PLI (literal)in a hooked function's prologue is copied into thetrampoline as a branch.
1. The hint check is unsatisfiable (#94)
The mask clears bits 19:16, but the comparand keeps
0xFthere, so thecondition never holds and the entire
PLD/PLIblock - including the noopconversion inside it - is dead code. This is the bug reported in #94; the
0xF810F000value is the one Frerich Raabe (@frerich) derived there.2. Correcting the constant is not sufficient
PLD/PLI (literal)are encoded as PC-relative loads:The only thing marking the hint is
Rt == 0b1111, and the preceding check doesnot examine bits 15:12:
so it matches all four literal hint encodings first and returns.
CopyLiteralLoad32then reads bits 15:12 as the destination register:load.Registeris0b1111==c_PC, so the trampoline receivesldr pc, [pc, #imm]- an unconditional branch to whatever word happens to lieat the preload address.
Testing hints before the literal load resolves this. Affected encodings:
0xF81FFxxx,0xF89FFxxx,0xF91FFxxx,0xF99FFxxx.Scope
ARM32 only; the change lies entirely within
#ifdef DETOURS_ARM. Real literalloads (
LDR/LDRB/LDRSB/LDRH (literal)) are unaffected - they carryRt != 0b1111and still reachCopyLiteralLoad32.PLD/PLIwithRn != PCstill blit unchanged.
Fixes #94.