Skip to content

Incorrect Behaviour: Arm64 CopyLdrLiteral for non-SIMD inlines Pointer Read #305

Open

Description

@Sewer56

Describe the bug

In the following detours code,

Detours/src/disasm.cpp

Lines 4241 to 4251 in 4b8c659

else if (decoded.s.FpNeon == 0)
{
UINT64 value = 0;
switch (decoded.s.Size)
{
case 0: value = *(ULONG*)pTarget; break;
case 1: value = *(UINT64*)pTarget; break;
case 2: value = *(LONG*)pTarget; break;
}
EmitMovImmediate(pDstInst, decoded.s.Rt, value);
}

which rewrites LDR Literal, the value of a PC relative address is directly inlined into the register.

i.e. Detours transforms it into a sequence of MOVZ + MOVK.

This is problematic if the value behind the PC relative address changes. For example, if the relative address points into the .data segment in order to read/write a global variable; and the value of the variable changes, Detours' rewritten code will no longer insert the correct value into the register as it has inlined the old value.

Expected behavior

A read of PC relative address should not be inlined, as the value behind this offset is not guaranteed to be constant.

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions