microsoft / microsoft/Detours

Incorrect Behaviour: Arm64 CopyLdrLiteral rewrites Prefetch as Memory Read, which can Trash a Potentially Used Register

Open
#306 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
C++
Stars
6.4k
Forks
1.2k
PR merge metrics
No merged PRs in 30d

Description

Describe the bug

This is a sister bug to:

  • #305

In the following detours code

https://github.com/microsoft/Detours/blob/4b8c659f549b0ab21cf649377c7a84eb708f5e68/src/disasm.cpp#L4226-L4261

which rewrites LDR Literal, the PRFM (Prefetch) instruction is rewritten as a load.

This happens because LDR literal and PRFM use the same opcode, and thus the LDR code path would be used for PRFM

https://github.com/microsoft/Detours/blob/4b8c659f549b0ab21cf649377c7a84eb708f5e68/src/disasm.cpp#L3967-L3969

e.g. PRFM PLIL1KEEP, #0 is 0xD8000008. (0xD8000008 & 0x3b000000) == 0x18000000 is true, thus the LDR code path is executed for PRFM.

Expected behavior

Prefetch operation should not be rewritten as a load, as this will trash the existing value in the register, which may still be used by the function.

Additional context

I'm building a cross platform, multi architecture hooking library [big WIP]; and I found detours' source to be pretty invaluable as a reference for code rewriting.

This is just a small thing I noticed while working on code rewriting on my end while referencing detours.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in src/disasm.cpp at the LDR literal handling around lines 4226-4261 and the opcode check around lines 3967-3969. Compare the referenced ARM documentation and the PRFM PLIL1KEEP, #0 encoding; done means a prefetch is not rewritten as a load or used to overwrite the existing register value.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
reverse-engineering
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.