From a63de06aa91b96254b96512e388abceef54aff1a Mon Sep 17 00:00:00 2001 From: Lysann Tranvouez Date: Wed, 1 Oct 2025 21:19:29 +0200 Subject: [PATCH] remove namespace --- src/arm64/detours_arm64_disasm.cpp | 622 ++++++++++++++--------------- 1 file changed, 304 insertions(+), 318 deletions(-) diff --git a/src/arm64/detours_arm64_disasm.cpp b/src/arm64/detours_arm64_disasm.cpp index 4ce1c5b..e14d83e 100644 --- a/src/arm64/detours_arm64_disasm.cpp +++ b/src/arm64/detours_arm64_disasm.cpp @@ -36,291 +36,279 @@ // TBZ z0110110 bbbbbiii iiiiiiii iiittttt & 0x7f000000 == 0x36000000 (z = size, b = bitnum, i = SignExtend(imm14:00, 64), t = Rt) // -namespace detour_arm64_disasm +union detour_arm64_disasm_add_imm12 { - union add_imm12 + uint32_t assembled; + struct { - uint32_t assembled; - struct - { - uint32_t rd : 5; // Destination register - uint32_t rn : 5; // Source register - uint32_t imm12 : 12; // 12-bit immediate - uint32_t shift : 2; // shift (must be 0 or 1) - uint32_t opcode1 : 7; // Must be 0010001 == 0x11 - uint32_t size : 1; // 0 = 32-bit, 1 = 64-bit - } s; - static uint32_t assemble(uint32_t size, uint32_t rd, uint32_t rn, uint32_t imm, uint32_t shift) - { - add_imm12 temp; - temp.s.rd = rd; - temp.s.rn = rn; - temp.s.imm12 = imm & 0xfff; - temp.s.shift = shift; - temp.s.opcode1 = 0x11; - temp.s.size = size; - return temp.assembled; - } - static uint32_t assemble_add_32(const uint32_t rd, const uint32_t rn, const uint32_t imm, const uint32_t shift) { return assemble(0, rd, rn, imm, shift); } - static uint32_t assemble_add_64(const uint32_t rd, const uint32_t rn, const uint32_t imm, const uint32_t shift) { return assemble(1, rd, rn, imm, shift); } - }; - - union adr19 + uint32_t rd : 5; // Destination register + uint32_t rn : 5; // Source register + uint32_t imm12 : 12; // 12-bit immediate + uint32_t shift : 2; // shift (must be 0 or 1) + uint32_t opcode1 : 7; // Must be 0010001 == 0x11 + uint32_t size : 1; // 0 = 32-bit, 1 = 64-bit + } s; + static uint32_t assemble(uint32_t size, uint32_t rd, uint32_t rn, uint32_t imm, uint32_t shift) { - uint32_t assembled; - struct - { - uint32_t rd : 5; // Destination register - uint32_t imm19 : 19; // 19-bit upper immediate - uint32_t opcode1 : 5; // Must be 10000 == 0x10 - uint32_t imm2 : 2; // 2-bit lower immediate - uint32_t type : 1; // 0 = ADR, 1 = ADRP - } s; - inline int32_t imm() const { uint32_t Imm = (s.imm19 << 2) | s.imm2; return (int32_t)(Imm << 11) >> 11; } - static uint32_t assemble(uint32_t type, uint32_t rd, int32_t delta) - { - adr19 temp; - temp.s.rd = rd; - temp.s.imm19 = (delta >> 2) & 0x7ffff; - temp.s.opcode1 = 0x10; - temp.s.imm2 = delta & 3; - temp.s.type = type; - return temp.assembled; - } - static uint32_t assemble_adr(uint32_t rd, int32_t delta) { return assemble(0, rd, delta); } - static uint32_t assemble_adrp(uint32_t rd, int32_t delta) { return assemble(1, rd, delta); } - }; - - union bcc19 - { - uint32_t assembled; - struct - { - uint32_t condition : 4; // Condition - uint32_t opcode1 : 1; // Must be 0 - uint32_t imm19 : 19; // 19-bit immediate - uint32_t opcode2 : 8; // Must be 01010100 == 0x54 - } s; - inline int32_t imm() const { return (int32_t)(s.imm19 << 13) >> 11; } - static uint32_t assemble_bcc(uint32_t condition, int32_t delta) - { - bcc19 temp; - temp.s.condition = condition; - temp.s.opcode1 = 0; - temp.s.imm19 = delta >> 2; - temp.s.opcode2 = 0x54; - return temp.assembled; - } - }; - - union branch26 - { - uint32_t assembled; - struct - { - uint32_t imm26 : 26; // 26-bit immediate - uint32_t opcode1 : 5; // Must be 00101 == 0x5 - uint32_t link : 1; // 0 = B, 1 = BL - } s; - inline int32_t imm() const { return (int32_t)(s.imm26 << 6) >> 4; } - static uint32_t assemble(uint32_t link, int32_t delta) - { - branch26 temp; - temp.s.imm26 = delta >> 2; - temp.s.opcode1 = 0x5; - temp.s.link = link; - return temp.assembled; - } - static uint32_t assemble_b(int32_t delta) { return assemble(0, delta); } - static uint32_t assemble_bl(int32_t delta) { return assemble(1, delta); } - }; - - union br - { - uint32_t assembled; - struct - { - uint32_t opcode1 : 5; // Must be 00000 == 0 - uint32_t rn : 5; // Register number - uint32_t opcode2 : 22; // Must be 1101011000011111000000 == 0x3587c0 for Br - // 0x358fc0 for Brl - } s; - static uint32_t assemble(uint32_t rn, bool link) - { - br temp; - temp.s.opcode1 = 0; - temp.s.rn = rn; - temp.s.opcode2 = 0x3587c0; - if (link) - temp.assembled |= 0x00200000; - return temp.assembled; - } - static uint32_t assemble_br(uint32_t rn) - { - return assemble(rn, false); - } - static uint32_t assemble_brl(uint32_t rn) - { - return assemble(rn, true); - } - }; - - union cbz19 - { - uint32_t assembled; - struct - { - uint32_t rt : 5; // Register to test - uint32_t imm19 : 19; // 19-bit immediate - uint32_t nz : 1; // 0 = CBZ, 1 = CBNZ - uint32_t opcode1 : 6; // Must be 011010 == 0x1a - uint32_t size : 1; // 0 = 32-bit, 1 = 64-bit - } s; - inline int32_t imm() const { return (int32_t)(s.imm19 << 13) >> 11; } - static uint32_t assemble(uint32_t size, uint32_t nz, uint32_t rt, int32_t delta) - { - cbz19 temp; - temp.s.rt = rt; - temp.s.imm19 = delta >> 2; - temp.s.nz = nz; - temp.s.opcode1 = 0x1a; - temp.s.size = size; - return temp.assembled; - } - }; - - union ldr_lit19 - { - uint32_t assembled; - struct - { - uint32_t rt : 5; // Destination register - uint32_t imm19 : 19; // 19-bit immediate - uint32_t opcode1 : 2; // Must be 0 - uint32_t fp_neon : 1; // 0 = LDR Wt/LDR Xt/LDRSW/PRFM, 1 = LDR St/LDR Dt/LDR Qt - uint32_t opcode2 : 3; // Must be 011 = 3 - uint32_t size : 2; // 00 = LDR Wt/LDR St, 01 = LDR Xt/LDR Dt, 10 = LDRSW/LDR Qt, 11 = PRFM/invalid - } s; - inline int32_t imm() const { return (int32_t)(s.imm19 << 13) >> 11; } - static uint32_t assemble(uint32_t size, uint32_t fpneon, uint32_t rt, int32_t delta) - { - ldr_lit19 temp; - temp.s.rt = rt; - temp.s.imm19 = delta >> 2; - temp.s.opcode1 = 0; - temp.s.fp_neon = fpneon; - temp.s.opcode2 = 3; - temp.s.size = size; - return temp.assembled; - } - }; - - union ldr_fp_neon_imm9 - { - uint32_t assembled; - struct - { - uint32_t rt : 5; // Destination register - uint32_t rn : 5; // Base register - uint32_t imm12 : 12; // 12-bit immediate - uint32_t opcode1 : 1; // Must be 1 == 1 - uint32_t opc : 1; // Part of size - uint32_t opcode2 : 6; // Must be 111101 == 0x3d - uint32_t size : 2; // Size (0=8-bit, 1=16-bit, 2=32-bit, 3=64-bit, 4=128-bit) - } s; - static uint32_t assemble(uint32_t size, uint32_t rt, uint32_t rn, uint32_t imm) - { - ldr_fp_neon_imm9 temp; - temp.s.rt = rt; - temp.s.rn = rn; - temp.s.imm12 = imm; - temp.s.opcode1 = 1; - temp.s.opc = size >> 2; - temp.s.opcode2 = 0x3d; - temp.s.size = size & 3; - return temp.assembled; - } - }; - - union mov16 - { - uint32_t assembled; - struct - { - uint32_t rd : 5; // Destination register - uint32_t imm16 : 16; // Immediate - uint32_t shift : 2; // Shift amount (0=0, 1=16, 2=32, 3=48) - uint32_t opcode : 6; // Must be 100101 == 0x25 - uint32_t type : 2; // 0 = MOVN, 1 = reserved, 2 = MOVZ, 3 = MOVK - uint32_t size : 1; // 0 = 32-bit, 1 = 64-bit - } s; - static uint32_t assemble(uint32_t size, uint32_t type, uint32_t rd, uint32_t imm, uint32_t shift) - { - mov16 temp; - temp.s.rd = rd; - temp.s.imm16 = imm; - temp.s.shift = shift; - temp.s.opcode = 0x25; - temp.s.type = type; - temp.s.size = size; - return temp.assembled; - } - static uint32_t assemble_movn32(uint32_t rd, uint32_t imm, uint32_t shift) { return assemble(0, 0, rd, imm, shift); } - static uint32_t assemble_movn64(uint32_t rd, uint32_t imm, uint32_t shift) { return assemble(1, 0, rd, imm, shift); } - static uint32_t assemble_movz32(uint32_t rd, uint32_t imm, uint32_t shift) { return assemble(0, 2, rd, imm, shift); } - static uint32_t assemble_movz64(uint32_t rd, uint32_t imm, uint32_t shift) { return assemble(1, 2, rd, imm, shift); } - static uint32_t assemble_movk32(uint32_t rd, uint32_t imm, uint32_t shift) { return assemble(0, 3, rd, imm, shift); } - static uint32_t assemble_movk64(uint32_t rd, uint32_t imm, uint32_t shift) { return assemble(1, 3, rd, imm, shift); } - }; - - union tbz14 - { - uint32_t assembled; - struct - { - uint32_t rt : 5; // Register to test - uint32_t imm14 : 14; // 14-bit immediate - uint32_t bit : 5; // 5-bit index - uint32_t nz : 1; // 0 = TBZ, 1 = TBNZ - uint32_t opcode1 : 6; // Must be 011011 == 0x1b - uint32_t size : 1; // 0 = 32-bit, 1 = 64-bit - } s; - inline int32_t imm() const { return (int32_t)(s.imm14 << 18) >> 16; } - static uint32_t assemble(uint32_t size, uint32_t nz, uint32_t rt, uint32_t bit, int32_t delta) - { - tbz14 temp; - temp.s.rt = rt; - temp.s.imm14 = delta >> 2; - temp.s.bit = bit; - temp.s.nz = nz; - temp.s.opcode1 = 0x1b; - temp.s.size = size; - return temp.assembled; - } - }; - - static uint8_t pure_copy32(uint8_t* source, uint8_t* dest); - static uint8_t emit_mov_immediate(uint32_t*& dst_inst, uint8_t rd, uint64_t immediate); - static uint8_t copy_adr(uint8_t* source, uint8_t* dest, uint32_t instruction) ; - static uint8_t copy_bcc(uint8_t* source, uint8_t* dest, uint32_t instruction); - static uint8_t copy_b_or_bl(uint8_t* source, uint8_t* dest, uint32_t instruction, bool link); - static uint8_t copy_cbz(uint8_t* source, uint8_t* dest, uint32_t instruction); - static uint8_t copy_tbz(uint8_t* source, uint8_t* dest, uint32_t instruction); - static uint8_t copy_ldr_literal(uint8_t* source, uint8_t* dest, uint32_t instruction); - - static uint32_t get_instruction(uint8_t* source) - { - return ((uint32_t*)source)[0]; + detour_arm64_disasm_add_imm12 temp; + temp.s.rd = rd; + temp.s.rn = rn; + temp.s.imm12 = imm & 0xfff; + temp.s.shift = shift; + temp.s.opcode1 = 0x11; + temp.s.size = size; + return temp.assembled; } + static uint32_t assemble_add_32(const uint32_t rd, const uint32_t rn, const uint32_t imm, const uint32_t shift) { return assemble(0, rd, rn, imm, shift); } + static uint32_t assemble_add_64(const uint32_t rd, const uint32_t rn, const uint32_t imm, const uint32_t shift) { return assemble(1, rd, rn, imm, shift); } +}; - static uint8_t emit_instruction(uint32_t*& dst_inst, uint32_t instruction) +union detour_arm64_disasm_adr19 +{ + uint32_t assembled; + struct { - *dst_inst++ = instruction; - return sizeof(uint32_t); + uint32_t rd : 5; // Destination register + uint32_t imm19 : 19; // 19-bit upper immediate + uint32_t opcode1 : 5; // Must be 10000 == 0x10 + uint32_t imm2 : 2; // 2-bit lower immediate + uint32_t type : 1; // 0 = ADR, 1 = ADRP + } s; + inline int32_t imm() const { uint32_t Imm = (s.imm19 << 2) | s.imm2; return (int32_t)(Imm << 11) >> 11; } + static uint32_t assemble(uint32_t type, uint32_t rd, int32_t delta) + { + detour_arm64_disasm_adr19 temp; + temp.s.rd = rd; + temp.s.imm19 = (delta >> 2) & 0x7ffff; + temp.s.opcode1 = 0x10; + temp.s.imm2 = delta & 3; + temp.s.type = type; + return temp.assembled; + } + static uint32_t assemble_adr(uint32_t rd, int32_t delta) { return assemble(0, rd, delta); } + static uint32_t assemble_adrp(uint32_t rd, int32_t delta) { return assemble(1, rd, delta); } +}; + +union detour_arm64_disasm_bcc19 +{ + uint32_t assembled; + struct + { + uint32_t condition : 4; // Condition + uint32_t opcode1 : 1; // Must be 0 + uint32_t imm19 : 19; // 19-bit immediate + uint32_t opcode2 : 8; // Must be 01010100 == 0x54 + } s; + inline int32_t imm() const { return (int32_t)(s.imm19 << 13) >> 11; } + static uint32_t assemble_bcc(uint32_t condition, int32_t delta) + { + detour_arm64_disasm_bcc19 temp; + temp.s.condition = condition; + temp.s.opcode1 = 0; + temp.s.imm19 = delta >> 2; + temp.s.opcode2 = 0x54; + return temp.assembled; } }; -uint8_t detour_arm64_disasm::pure_copy32(uint8_t* source, uint8_t* dest) +union detour_arm64_disasm_branch26 +{ + uint32_t assembled; + struct + { + uint32_t imm26 : 26; // 26-bit immediate + uint32_t opcode1 : 5; // Must be 00101 == 0x5 + uint32_t link : 1; // 0 = B, 1 = BL + } s; + inline int32_t imm() const { return (int32_t)(s.imm26 << 6) >> 4; } + static uint32_t assemble(uint32_t link, int32_t delta) + { + detour_arm64_disasm_branch26 temp; + temp.s.imm26 = delta >> 2; + temp.s.opcode1 = 0x5; + temp.s.link = link; + return temp.assembled; + } + static uint32_t assemble_b(int32_t delta) { return assemble(0, delta); } + static uint32_t assemble_bl(int32_t delta) { return assemble(1, delta); } +}; + +union detour_arm64_disasm_br +{ + uint32_t assembled; + struct + { + uint32_t opcode1 : 5; // Must be 00000 == 0 + uint32_t rn : 5; // Register number + uint32_t opcode2 : 22; // Must be 1101011000011111000000 == 0x3587c0 for Br + // 0x358fc0 for Brl + } s; + static uint32_t assemble(uint32_t rn, bool link) + { + detour_arm64_disasm_br temp; + temp.s.opcode1 = 0; + temp.s.rn = rn; + temp.s.opcode2 = 0x3587c0; + if (link) + temp.assembled |= 0x00200000; + return temp.assembled; + } + static uint32_t assemble_br(uint32_t rn) + { + return assemble(rn, false); + } + static uint32_t assemble_brl(uint32_t rn) + { + return assemble(rn, true); + } +}; + +union detour_arm64_disasm_cbz19 +{ + uint32_t assembled; + struct + { + uint32_t rt : 5; // Register to test + uint32_t imm19 : 19; // 19-bit immediate + uint32_t nz : 1; // 0 = CBZ, 1 = CBNZ + uint32_t opcode1 : 6; // Must be 011010 == 0x1a + uint32_t size : 1; // 0 = 32-bit, 1 = 64-bit + } s; + inline int32_t imm() const { return (int32_t)(s.imm19 << 13) >> 11; } + static uint32_t assemble(uint32_t size, uint32_t nz, uint32_t rt, int32_t delta) + { + detour_arm64_disasm_cbz19 temp; + temp.s.rt = rt; + temp.s.imm19 = delta >> 2; + temp.s.nz = nz; + temp.s.opcode1 = 0x1a; + temp.s.size = size; + return temp.assembled; + } +}; + +union detour_arm64_disasm_ldr_lit19 +{ + uint32_t assembled; + struct + { + uint32_t rt : 5; // Destination register + uint32_t imm19 : 19; // 19-bit immediate + uint32_t opcode1 : 2; // Must be 0 + uint32_t fp_neon : 1; // 0 = LDR Wt/LDR Xt/LDRSW/PRFM, 1 = LDR St/LDR Dt/LDR Qt + uint32_t opcode2 : 3; // Must be 011 = 3 + uint32_t size : 2; // 00 = LDR Wt/LDR St, 01 = LDR Xt/LDR Dt, 10 = LDRSW/LDR Qt, 11 = PRFM/invalid + } s; + inline int32_t imm() const { return (int32_t)(s.imm19 << 13) >> 11; } + static uint32_t assemble(uint32_t size, uint32_t fpneon, uint32_t rt, int32_t delta) + { + detour_arm64_disasm_ldr_lit19 temp; + temp.s.rt = rt; + temp.s.imm19 = delta >> 2; + temp.s.opcode1 = 0; + temp.s.fp_neon = fpneon; + temp.s.opcode2 = 3; + temp.s.size = size; + return temp.assembled; + } +}; + +union detour_arm64_disasm_ldr_fp_neon_imm9 +{ + uint32_t assembled; + struct + { + uint32_t rt : 5; // Destination register + uint32_t rn : 5; // Base register + uint32_t imm12 : 12; // 12-bit immediate + uint32_t opcode1 : 1; // Must be 1 == 1 + uint32_t opc : 1; // Part of size + uint32_t opcode2 : 6; // Must be 111101 == 0x3d + uint32_t size : 2; // Size (0=8-bit, 1=16-bit, 2=32-bit, 3=64-bit, 4=128-bit) + } s; + static uint32_t assemble(uint32_t size, uint32_t rt, uint32_t rn, uint32_t imm) + { + detour_arm64_disasm_ldr_fp_neon_imm9 temp; + temp.s.rt = rt; + temp.s.rn = rn; + temp.s.imm12 = imm; + temp.s.opcode1 = 1; + temp.s.opc = size >> 2; + temp.s.opcode2 = 0x3d; + temp.s.size = size & 3; + return temp.assembled; + } +}; + +union detour_arm64_disasm_mov16 +{ + uint32_t assembled; + struct + { + uint32_t rd : 5; // Destination register + uint32_t imm16 : 16; // Immediate + uint32_t shift : 2; // Shift amount (0=0, 1=16, 2=32, 3=48) + uint32_t opcode : 6; // Must be 100101 == 0x25 + uint32_t type : 2; // 0 = MOVN, 1 = reserved, 2 = MOVZ, 3 = MOVK + uint32_t size : 1; // 0 = 32-bit, 1 = 64-bit + } s; + static uint32_t assemble(uint32_t size, uint32_t type, uint32_t rd, uint32_t imm, uint32_t shift) + { + detour_arm64_disasm_mov16 temp; + temp.s.rd = rd; + temp.s.imm16 = imm; + temp.s.shift = shift; + temp.s.opcode = 0x25; + temp.s.type = type; + temp.s.size = size; + return temp.assembled; + } + static uint32_t assemble_movn32(uint32_t rd, uint32_t imm, uint32_t shift) { return assemble(0, 0, rd, imm, shift); } + static uint32_t assemble_movn64(uint32_t rd, uint32_t imm, uint32_t shift) { return assemble(1, 0, rd, imm, shift); } + static uint32_t assemble_movz32(uint32_t rd, uint32_t imm, uint32_t shift) { return assemble(0, 2, rd, imm, shift); } + static uint32_t assemble_movz64(uint32_t rd, uint32_t imm, uint32_t shift) { return assemble(1, 2, rd, imm, shift); } + static uint32_t assemble_movk32(uint32_t rd, uint32_t imm, uint32_t shift) { return assemble(0, 3, rd, imm, shift); } + static uint32_t assemble_movk64(uint32_t rd, uint32_t imm, uint32_t shift) { return assemble(1, 3, rd, imm, shift); } +}; + +union detour_arm64_disasm_tbz14 +{ + uint32_t assembled; + struct + { + uint32_t rt : 5; // Register to test + uint32_t imm14 : 14; // 14-bit immediate + uint32_t bit : 5; // 5-bit index + uint32_t nz : 1; // 0 = TBZ, 1 = TBNZ + uint32_t opcode1 : 6; // Must be 011011 == 0x1b + uint32_t size : 1; // 0 = 32-bit, 1 = 64-bit + } s; + inline int32_t imm() const { return (int32_t)(s.imm14 << 18) >> 16; } + static uint32_t assemble(uint32_t size, uint32_t nz, uint32_t rt, uint32_t bit, int32_t delta) + { + detour_arm64_disasm_tbz14 temp; + temp.s.rt = rt; + temp.s.imm14 = delta >> 2; + temp.s.bit = bit; + temp.s.nz = nz; + temp.s.opcode1 = 0x1b; + temp.s.size = size; + return temp.assembled; + } +}; + +static uint32_t get_instruction(uint8_t* source) +{ + return ((uint32_t*)source)[0]; +} + +static uint8_t emit_instruction(uint32_t*& dst_inst, uint32_t instruction) +{ + *dst_inst++ = instruction; + return sizeof(uint32_t); +}; + +uint8_t pure_copy32(uint8_t* source, uint8_t* dest) { *(uint32_t *)dest = *(uint32_t*)source; return sizeof(uint32_t); @@ -329,7 +317,7 @@ uint8_t detour_arm64_disasm::pure_copy32(uint8_t* source, uint8_t* dest) /////////////////////////////////////////////////////////// Disassembler Code. // -uint8_t detour_arm64_disasm::emit_mov_immediate(uint32_t*& dst_inst, uint8_t rd, uint64_t immediate) +uint8_t emit_mov_immediate(uint32_t*& dst_inst, uint8_t rd, uint64_t immediate) { uint32_t piece[4]; piece[3] = (uint32_t)((immediate >> 48) & 0xffff); @@ -341,7 +329,7 @@ uint8_t detour_arm64_disasm::emit_mov_immediate(uint32_t*& dst_inst, uint8_t rd, // special case: MOVN with 32-bit dest if (piece[3] == 0 && piece[2] == 0 && piece[1] == 0xffff) { - emit_instruction(dst_inst, mov16::assemble_movn32(rd, piece[0] ^ 0xffff, 0)); + emit_instruction(dst_inst, detour_arm64_disasm_mov16::assemble_movn32(rd, piece[0] ^ 0xffff, 0)); count++; } @@ -362,17 +350,17 @@ uint8_t detour_arm64_disasm::emit_mov_immediate(uint32_t*& dst_inst, uint8_t rd, { if (default_piece == 0xffff) { - emit_instruction(dst_inst, mov16::assemble_movn64(rd, cur_piece ^ 0xffff, piece_num)); + emit_instruction(dst_inst, detour_arm64_disasm_mov16::assemble_movn64(rd, cur_piece ^ 0xffff, piece_num)); } else { - emit_instruction(dst_inst, mov16::assemble_movz64(rd, cur_piece, piece_num)); + emit_instruction(dst_inst, detour_arm64_disasm_mov16::assemble_movz64(rd, cur_piece, piece_num)); } first = false; } else { - emit_instruction(dst_inst, mov16::assemble_movk64(rd, cur_piece, piece_num)); + emit_instruction(dst_inst, detour_arm64_disasm_mov16::assemble_movk64(rd, cur_piece, piece_num)); } } } @@ -380,9 +368,9 @@ uint8_t detour_arm64_disasm::emit_mov_immediate(uint32_t*& dst_inst, uint8_t rd, return (uint8_t)(count * sizeof(uint32_t)); } -uint8_t detour_arm64_disasm::copy_adr(uint8_t* source, uint8_t* dest, uint32_t instruction) +uint8_t copy_adr(uint8_t* source, uint8_t* dest, uint32_t instruction) { - adr19& decoded = (adr19&)(instruction); + detour_arm64_disasm_adr19& decoded = (detour_arm64_disasm_adr19&)(instruction); uint32_t* dst_inst = (uint32_t*)(dest); // ADR case @@ -395,14 +383,14 @@ uint8_t detour_arm64_disasm::copy_adr(uint8_t* source, uint8_t* dest, uint32_t i // output as ADR if (delta >= -(1 << 20) && delta < (1 << 20)) { - emit_instruction(dst_inst, adr19::assemble_adr(decoded.s.rd, (int32_t)delta)); + emit_instruction(dst_inst, detour_arm64_disasm_adr19::assemble_adr(decoded.s.rd, (int32_t)delta)); } // output as ADRP; ADD else if (delta_page >= -(1 << 20) && (delta_page < (1 << 20))) { - emit_instruction(dst_inst, adr19::assemble_adrp(decoded.s.rd, (int32_t)delta_page)); - emit_instruction(dst_inst, add_imm12::assemble_add_32(decoded.s.rd, decoded.s.rd, ((std::ptrdiff_t)target) & 0xfff, 0)); + emit_instruction(dst_inst, detour_arm64_disasm_adr19::assemble_adrp(decoded.s.rd, (int32_t)delta_page)); + emit_instruction(dst_inst, detour_arm64_disasm_add_imm12::assemble_add_32(decoded.s.rd, decoded.s.rd, ((std::ptrdiff_t)target) & 0xfff, 0)); } // output as immediate move @@ -421,7 +409,7 @@ uint8_t detour_arm64_disasm::copy_adr(uint8_t* source, uint8_t* dest, uint32_t i // output as ADRP if (delta_page >= -(1 << 20) && (delta_page < (1 << 20))) { - emit_instruction(dst_inst, adr19::assemble_adrp(decoded.s.rd, (int32_t)delta_page)); + emit_instruction(dst_inst, detour_arm64_disasm_adr19::assemble_adrp(decoded.s.rd, (int32_t)delta_page)); } // output as immediate move @@ -434,9 +422,9 @@ uint8_t detour_arm64_disasm::copy_adr(uint8_t* source, uint8_t* dest, uint32_t i return (uint8_t)((uint8_t*)dst_inst - dest); } -uint8_t detour_arm64_disasm::copy_bcc(uint8_t* source, uint8_t* dest, uint32_t instruction) +uint8_t copy_bcc(uint8_t* source, uint8_t* dest, uint32_t instruction) { - bcc19& decoded = (bcc19&)(instruction); + detour_arm64_disasm_bcc19& decoded = (detour_arm64_disasm_bcc19&)(instruction); uint32_t* dst_inst = (uint32_t*)(dest); uint8_t* target = source + decoded.imm(); @@ -446,30 +434,30 @@ uint8_t detour_arm64_disasm::copy_bcc(uint8_t* source, uint8_t* dest, uint32_t i // output as BCC if (delta >= -(1 << 20) && delta < (1 << 20)) { - emit_instruction(dst_inst, bcc19::assemble_bcc(decoded.s.condition, (int32_t)delta)); + emit_instruction(dst_inst, detour_arm64_disasm_bcc19::assemble_bcc(decoded.s.condition, (int32_t)delta)); } // output as BCC ; B else if (delta4 >= -(1 << 27) && (delta4 < (1 << 27))) { - emit_instruction(dst_inst, bcc19::assemble_bcc(decoded.s.condition ^ 1, 8)); - emit_instruction(dst_inst, branch26::assemble_b((int32_t)delta4)); + emit_instruction(dst_inst, detour_arm64_disasm_bcc19::assemble_bcc(decoded.s.condition ^ 1, 8)); + emit_instruction(dst_inst, detour_arm64_disasm_branch26::assemble_b((int32_t)delta4)); } // output as MOV x17, Target; BCC ; BR x17 (BIG assumption that x17 isn't being used for anything!!) else { emit_mov_immediate(dst_inst, 17, (std::ptrdiff_t)target); - emit_instruction(dst_inst, bcc19::assemble_bcc(decoded.s.condition ^ 1, 8)); - emit_instruction(dst_inst, br::assemble_br(17)); + emit_instruction(dst_inst, detour_arm64_disasm_bcc19::assemble_bcc(decoded.s.condition ^ 1, 8)); + emit_instruction(dst_inst, detour_arm64_disasm_br::assemble_br(17)); } return (uint8_t)((uint8_t*)dst_inst - dest); } -uint8_t detour_arm64_disasm::copy_b_or_bl(uint8_t* source, uint8_t* dest, uint32_t instruction, bool link) +uint8_t copy_b_or_bl(uint8_t* source, uint8_t* dest, uint32_t instruction, bool link) { - branch26& decoded = (branch26&)(instruction); + detour_arm64_disasm_branch26& decoded = (detour_arm64_disasm_branch26&)(instruction); uint32_t* dst_inst = (uint32_t*)(dest); uint8_t* target = source + decoded.imm(); @@ -478,22 +466,22 @@ uint8_t detour_arm64_disasm::copy_b_or_bl(uint8_t* source, uint8_t* dest, uint32 // output as B or BRL if (delta >= -(1 << 27) && (delta < (1 << 27))) { - emit_instruction(dst_inst, branch26::assemble(link, (int32_t)delta)); + emit_instruction(dst_inst, detour_arm64_disasm_branch26::assemble(link, (int32_t)delta)); } // output as MOV x17, Target; BR or BRL x17 (BIG assumption that x17 isn't being used for anything!!) else { emit_mov_immediate(dst_inst, 17, (std::ptrdiff_t)target); - emit_instruction(dst_inst, br::assemble(17, link)); + emit_instruction(dst_inst, detour_arm64_disasm_br::assemble(17, link)); } return (uint8_t)((uint8_t*)dst_inst - dest); } -uint8_t detour_arm64_disasm::copy_cbz(uint8_t* source, uint8_t* dest, uint32_t instruction) +uint8_t copy_cbz(uint8_t* source, uint8_t* dest, uint32_t instruction) { - cbz19& decoded = (cbz19&)(instruction); + detour_arm64_disasm_cbz19& decoded = (detour_arm64_disasm_cbz19&)(instruction); uint32_t* dst_inst = (uint32_t*)(dest); uint8_t* target = source + decoded.imm(); @@ -503,30 +491,30 @@ uint8_t detour_arm64_disasm::copy_cbz(uint8_t* source, uint8_t* dest, uint32_t i // output as CBZ/NZ if (delta >= -(1 << 20) && delta < (1 << 20)) { - emit_instruction(dst_inst, cbz19::assemble(decoded.s.size, decoded.s.nz, decoded.s.rt, (int32_t)delta)); + emit_instruction(dst_inst, detour_arm64_disasm_cbz19::assemble(decoded.s.size, decoded.s.nz, decoded.s.rt, (int32_t)delta)); } // output as CBNZ/Z ; B else if (delta4 >= -(1 << 27) && (delta4 < (1 << 27))) { - emit_instruction(dst_inst, cbz19::assemble(decoded.s.size, decoded.s.nz ^ 1, decoded.s.rt, 8)); - emit_instruction(dst_inst, branch26::assemble_b((int32_t)delta4)); + emit_instruction(dst_inst, detour_arm64_disasm_cbz19::assemble(decoded.s.size, decoded.s.nz ^ 1, decoded.s.rt, 8)); + emit_instruction(dst_inst, detour_arm64_disasm_branch26::assemble_b((int32_t)delta4)); } // output as MOV x17, Target; CBNZ/Z ; BR x17 (BIG assumption that x17 isn't being used for anything!!) else { emit_mov_immediate(dst_inst, 17, (std::ptrdiff_t)target); - emit_instruction(dst_inst, cbz19::assemble(decoded.s.size, decoded.s.nz ^ 1, decoded.s.rt, 8)); - emit_instruction(dst_inst, br::assemble_br(17)); + emit_instruction(dst_inst, detour_arm64_disasm_cbz19::assemble(decoded.s.size, decoded.s.nz ^ 1, decoded.s.rt, 8)); + emit_instruction(dst_inst, detour_arm64_disasm_br::assemble_br(17)); } return (uint8_t)((uint8_t*)dst_inst - dest); } -uint8_t detour_arm64_disasm::copy_tbz(uint8_t* source, uint8_t* dest, uint32_t instruction) +uint8_t copy_tbz(uint8_t* source, uint8_t* dest, uint32_t instruction) { - tbz14& decoded = (tbz14&)(instruction); + detour_arm64_disasm_tbz14& decoded = (detour_arm64_disasm_tbz14&)(instruction); uint32_t* dst_inst = (uint32_t*)(dest); uint8_t* target = source + decoded.imm(); @@ -536,30 +524,30 @@ uint8_t detour_arm64_disasm::copy_tbz(uint8_t* source, uint8_t* dest, uint32_t i // output as TBZ/NZ if (delta >= -(1 << 13) && delta < (1 << 13)) { - emit_instruction(dst_inst, tbz14::assemble(decoded.s.size, decoded.s.nz, decoded.s.rt, decoded.s.bit, (int32_t)delta)); + emit_instruction(dst_inst, detour_arm64_disasm_tbz14::assemble(decoded.s.size, decoded.s.nz, decoded.s.rt, decoded.s.bit, (int32_t)delta)); } // output as TBNZ/Z ; B else if (delta4 >= -(1 << 27) && (delta4 < (1 << 27))) { - emit_instruction(dst_inst, tbz14::assemble(decoded.s.size, decoded.s.nz ^ 1, decoded.s.rt, decoded.s.bit, 8)); - emit_instruction(dst_inst, branch26::assemble_b((int32_t)delta4)); + emit_instruction(dst_inst, detour_arm64_disasm_tbz14::assemble(decoded.s.size, decoded.s.nz ^ 1, decoded.s.rt, decoded.s.bit, 8)); + emit_instruction(dst_inst, detour_arm64_disasm_branch26::assemble_b((int32_t)delta4)); } // output as MOV x17, Target; TBNZ/Z ; BR x17 (BIG assumption that x17 isn't being used for anything!!) else { emit_mov_immediate(dst_inst, 17, (std::ptrdiff_t)target); - emit_instruction(dst_inst, tbz14::assemble(decoded.s.size, decoded.s.nz ^ 1, decoded.s.rt, decoded.s.bit, 8)); - emit_instruction(dst_inst, br::assemble_br(17)); + emit_instruction(dst_inst, detour_arm64_disasm_tbz14::assemble(decoded.s.size, decoded.s.nz ^ 1, decoded.s.rt, decoded.s.bit, 8)); + emit_instruction(dst_inst, detour_arm64_disasm_br::assemble_br(17)); } return (uint8_t)((uint8_t*)dst_inst - dest); } -uint8_t detour_arm64_disasm::copy_ldr_literal(uint8_t* source, uint8_t* dest, uint32_t instruction) +uint8_t copy_ldr_literal(uint8_t* source, uint8_t* dest, uint32_t instruction) { - ldr_lit19& decoded = (ldr_lit19&)(instruction); + detour_arm64_disasm_ldr_lit19& decoded = (detour_arm64_disasm_ldr_lit19&)(instruction); uint32_t* dst_inst = (uint32_t*)(dest); uint8_t* target = source + decoded.imm(); @@ -568,7 +556,7 @@ uint8_t detour_arm64_disasm::copy_ldr_literal(uint8_t* source, uint8_t* dest, ui // output as LDR if (delta >= -(1 << 21) && delta < (1 << 21)) { - emit_instruction(dst_inst, ldr_lit19::assemble(decoded.s.size, decoded.s.fp_neon, decoded.s.rt, (int32_t)delta)); + emit_instruction(dst_inst, detour_arm64_disasm_ldr_lit19::assemble(decoded.s.size, decoded.s.fp_neon, decoded.s.rt, (int32_t)delta)); } // output as move immediate @@ -588,7 +576,7 @@ uint8_t detour_arm64_disasm::copy_ldr_literal(uint8_t* source, uint8_t* dest, ui else { emit_mov_immediate(dst_inst, 17, (std::ptrdiff_t)target); - emit_instruction(dst_inst, ldr_fp_neon_imm9::assemble(2 + decoded.s.size, decoded.s.rt, 17, 0)); + emit_instruction(dst_inst, detour_arm64_disasm_ldr_fp_neon_imm9::assemble(2 + decoded.s.size, decoded.s.rt, 17, 0)); } return (uint8_t)((uint8_t*)dst_inst - dest); @@ -596,8 +584,6 @@ uint8_t detour_arm64_disasm::copy_ldr_literal(uint8_t* source, uint8_t* dest, ui uint8_t* internal_detour_copy_instruction(uint8_t* dst, uint8_t* src, uint32_t* out_extra_len) { - using namespace detour_arm64_disasm; - const uint32_t instruction = get_instruction(src); uint32_t copied_size;