2025-09-28 00:37:03 +02:00
|
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
|
|
// Copyright (c) Lysann Tranvouez. All rights reserved.
|
|
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
#ifndef MACH_DETOURS_ARM64_H
|
|
|
|
|
#define MACH_DETOURS_ARM64_H
|
|
|
|
|
|
2025-09-28 00:42:23 +02:00
|
|
|
#include <stdint.h>
|
|
|
|
|
|
2025-09-28 00:37:03 +02:00
|
|
|
typedef struct detour_align
|
|
|
|
|
{
|
|
|
|
|
uint8_t obTarget;
|
|
|
|
|
uint8_t obTrampoline;
|
|
|
|
|
} detour_align;
|
|
|
|
|
|
|
|
|
|
typedef struct detour_trampoline
|
|
|
|
|
{
|
|
|
|
|
// An ARM64 instruction is 4 bytes long.
|
|
|
|
|
//
|
|
|
|
|
// The overwrite is always composed of 3 instructions (12 bytes) which perform an indirect jump
|
|
|
|
|
// using _DETOUR_TRAMPOLINE::pbDetour as the address holding the target location.
|
|
|
|
|
//
|
|
|
|
|
// Copied instructions can expand.
|
|
|
|
|
//
|
|
|
|
|
// The scheme using MovImmediate can cause an instruction
|
|
|
|
|
// to grow as much as 6 times.
|
|
|
|
|
// That would be Bcc or Tbz with a large address space:
|
|
|
|
|
// 4 instructions to form immediate
|
|
|
|
|
// inverted tbz/bcc
|
|
|
|
|
// br
|
|
|
|
|
//
|
|
|
|
|
// An expansion of 4 is not uncommon -- bl/blr and small address space:
|
|
|
|
|
// 3 instructions to form immediate
|
|
|
|
|
// br or brl
|
|
|
|
|
//
|
|
|
|
|
// A theoretical maximum for rbCode is thefore 4*4*6 + 16 = 112 (another 16 for jmp to pbRemain).
|
|
|
|
|
//
|
|
|
|
|
// With literals, the maximum expansion is 5, including the literals: 4*4*5 + 16 = 96.
|
|
|
|
|
//
|
|
|
|
|
// The number is rounded up to 128. m_rbScratchDst should match this.
|
|
|
|
|
//
|
|
|
|
|
uint8_t rbCode[128]; // target code + jmp to pbRemain
|
|
|
|
|
uint8_t cbCode; // size of moved target code.
|
|
|
|
|
uint8_t cbCodeBreak[3]; // padding to make debugging easier.
|
|
|
|
|
uint8_t rbRestore[24]; // original target code.
|
|
|
|
|
uint8_t cbRestore; // size of original target code.
|
|
|
|
|
uint8_t cbRestoreBreak[3]; // padding to make debugging easier.
|
|
|
|
|
detour_align rAlign[8]; // instruction alignment array.
|
|
|
|
|
uint8_t* pbRemain; // first instruction after moved code. [free list]
|
|
|
|
|
uint8_t* pbDetour; // first instruction of detour function.
|
|
|
|
|
} detour_trampoline;
|
|
|
|
|
|
|
|
|
|
static_assert(sizeof(detour_trampoline) == 192);
|
|
|
|
|
|
|
|
|
|
#endif //MACH_DETOURS_ARM64_H
|