detour_transaction_commit

This commit is contained in:
Lysann Tranvouez 2025-09-29 01:07:56 +02:00
parent b1eb0ad995
commit d8d3d85444
5 changed files with 351 additions and 8 deletions

View file

@ -9,8 +9,8 @@
typedef struct detour_align
{
uint8_t obTarget;
uint8_t obTrampoline;
uint8_t offset_target;
uint8_t offset_trampoline;
} detour_align;
typedef struct detour_trampoline
@ -54,4 +54,93 @@ typedef struct detour_trampoline
static_assert(sizeof(detour_trampoline) == 192);
typedef uint32_t detours_arm64_opcode_t;
static inline detours_arm64_opcode_t fetch_opcode(uint8_t* code)
{
return *(detours_arm64_opcode_t*)code;
}
static inline void write_opcode(uint8_t** int_out_code, detours_arm64_opcode_t opcode)
{
uint8_t* code = *int_out_code;
*(detours_arm64_opcode_t*)code = opcode;
*int_out_code += sizeof(detours_arm64_opcode_t);
}
struct detours_arm64_indirect_jmp {
struct {
uint32_t Rd : 5;
uint32_t immhi : 19;
uint32_t iop : 5;
uint32_t immlo : 2;
uint32_t op : 1;
} ardp;
struct {
uint32_t Rt : 5;
uint32_t Rn : 5;
uint32_t imm : 12;
uint32_t opc : 2;
uint32_t iop1 : 2;
uint32_t V : 1;
uint32_t iop2 : 3;
uint32_t size : 2;
} ldr;
uint32_t br;
};
union detours_arm64_indirect_imm {
struct {
uint64_t pad : 12;
uint64_t adrp_immlo : 2;
uint64_t adrp_immhi : 19;
};
int64_t value;
};
static inline uint8_t* internal_detour_gen_jmp_indirect(uint8_t* code, uint64_t* jump_val)
{
// adrp x17, [jmpval]
// ldr x17, [x17, jmpval]
// br x17
union detours_arm64_indirect_imm jmp_ind_addr;
jmp_ind_addr.value = (((uint64_t)jump_val) & 0xFFFFFFFFFFFFF000) -
(((uint64_t)code) & 0xFFFFFFFFFFFFF000);
struct detours_arm64_indirect_jmp* ind_jmp = (struct detours_arm64_indirect_jmp*)code;
code = (uint8_t*)(ind_jmp + 1);
ind_jmp->ardp.Rd = 17;
ind_jmp->ardp.immhi = jmp_ind_addr.adrp_immhi;
ind_jmp->ardp.iop = 0x10;
ind_jmp->ardp.immlo = jmp_ind_addr.adrp_immlo;
ind_jmp->ardp.op = 1;
ind_jmp->ldr.Rt = 17;
ind_jmp->ldr.Rn = 17;
ind_jmp->ldr.imm = (((uint64_t)jump_val) & 0xFFF) / 8;
ind_jmp->ldr.opc = 1;
ind_jmp->ldr.iop1 = 1;
ind_jmp->ldr.V = 0;
ind_jmp->ldr.iop2 = 7;
ind_jmp->ldr.size = 3;
ind_jmp->br = 0xD61F0220;
return code;
}
static inline uint8_t* internal_detour_gen_brk(uint8_t* code, uint8_t* limit)
{
while (code < limit) {
write_opcode(&code, 0xd4100000 | (0xf000 << 5));
}
return code;
}
#endif //MACH_DETOURS_ARM64_H