remove unused state from CDetourDis

This commit is contained in:
Lysann Tranvouez 2025-10-01 00:21:04 +02:00
parent 4c22783a54
commit 21c874186d
4 changed files with 54 additions and 91 deletions

View file

@ -36,19 +36,8 @@
// TBZ z0110110 bbbbbiii iiiiiiii iiittttt & 0x7f000000 == 0x36000000 (z = size, b = bitnum, i = SignExtend(imm14:00, 64), t = Rt)
//
class CDetourDis
namespace detour_arm64_disasm
{
public:
explicit CDetourDis() = default;
uint8_t* CopyInstruction(uint8_t* pDst,
uint8_t* pSrc,
uint8_t* *ppTarget,
int32_t *plExtra);
public:
typedef uint8_t (CDetourDis::* COPYFUNC)(uint8_t* pbDst, uint8_t* pbSrc);
union AddImm12
{
uint32_t Assembled;
@ -310,37 +299,30 @@ class CDetourDis
}
};
static uint8_t PureCopy32(uint8_t* pSource, uint8_t* pDest);
static uint8_t EmitMovImmediate(uint32_t*& pDstInst, uint8_t rd, uint64_t immediate);
static uint8_t CopyAdr(uint8_t* pSource, uint8_t* pDest, uint32_t instruction) ;
static uint8_t CopyBcc(uint8_t* pSource, uint8_t* pDest, uint32_t instruction);
static uint8_t CopyB(uint8_t* pSource, uint8_t* pDest, uint32_t instruction);
static uint8_t CopyBl(uint8_t* pSource, uint8_t* pDest, uint32_t instruction);
static uint8_t CopyB_or_Bl(uint8_t* pSource, uint8_t* pDest, uint32_t instruction, bool link);
static uint8_t CopyCbz(uint8_t* pSource, uint8_t* pDest, uint32_t instruction);
static uint8_t CopyTbz(uint8_t* pSource, uint8_t* pDest, uint32_t instruction);
static uint8_t CopyLdrLiteral(uint8_t* pSource, uint8_t* pDest, uint32_t instruction);
protected:
uint8_t PureCopy32(uint8_t* pSource, uint8_t* pDest);
uint8_t EmitMovImmediate(uint32_t*& pDstInst, uint8_t rd, uint64_t immediate);
uint8_t CopyAdr(uint8_t* pSource, uint8_t* pDest, uint32_t instruction);
uint8_t CopyBcc(uint8_t* pSource, uint8_t* pDest, uint32_t instruction);
uint8_t CopyB(uint8_t* pSource, uint8_t* pDest, uint32_t instruction);
uint8_t CopyBl(uint8_t* pSource, uint8_t* pDest, uint32_t instruction);
uint8_t CopyB_or_Bl(uint8_t* pSource, uint8_t* pDest, uint32_t instruction, bool link);
uint8_t CopyCbz(uint8_t* pSource, uint8_t* pDest, uint32_t instruction);
uint8_t CopyTbz(uint8_t* pSource, uint8_t* pDest, uint32_t instruction);
uint8_t CopyLdrLiteral(uint8_t* pSource, uint8_t* pDest, uint32_t instruction);
protected:
uint32_t GetInstruction(uint8_t* pSource)
static uint32_t GetInstruction(uint8_t* pSource)
{
return ((uint32_t*)pSource)[0];
}
uint8_t EmitInstruction(uint32_t*& pDstInst, uint32_t instruction)
static uint8_t EmitInstruction(uint32_t*& pDstInst, uint32_t instruction)
{
*pDstInst++ = instruction;
return sizeof(uint32_t);
}
protected:
uint8_t* m_pbTarget = nullptr;
uint8_t m_rbScratchDst[128] {}; // matches or exceeds rbCode
};
uint8_t CDetourDis::PureCopy32(uint8_t* pSource, uint8_t* pDest)
uint8_t detour_arm64_disasm::PureCopy32(uint8_t* pSource, uint8_t* pDest)
{
*(uint32_t *)pDest = *(uint32_t*)pSource;
return sizeof(uint32_t);
@ -349,46 +331,7 @@ uint8_t CDetourDis::PureCopy32(uint8_t* pSource, uint8_t* pDest)
/////////////////////////////////////////////////////////// Disassembler Code.
//
uint8_t* CDetourDis::CopyInstruction(uint8_t* pDst,
uint8_t* pSrc,
uint8_t* *ppTarget,
int32_t *plExtra)
{
if (pDst == nullptr) {
pDst = m_rbScratchDst;
}
uint32_t Instruction = GetInstruction(pSrc);
uint32_t CopiedSize;
if ((Instruction & 0x1f000000) == 0x10000000) {
CopiedSize = CopyAdr(pSrc, pDst, Instruction);
} else if ((Instruction & 0xff000010) == 0x54000000) {
CopiedSize = CopyBcc(pSrc, pDst, Instruction);
} else if ((Instruction & 0x7c000000) == 0x14000000) {
CopiedSize = CopyB_or_Bl(pSrc, pDst, Instruction, (Instruction & 0x80000000) != 0);
} else if ((Instruction & 0x7e000000) == 0x34000000) {
CopiedSize = CopyCbz(pSrc, pDst, Instruction);
} else if ((Instruction & 0x7e000000) == 0x36000000) {
CopiedSize = CopyTbz(pSrc, pDst, Instruction);
} else if ((Instruction & 0x3b000000) == 0x18000000) {
CopiedSize = CopyLdrLiteral(pSrc, pDst, Instruction);
} else {
CopiedSize = PureCopy32(pSrc, pDst);
}
// If the target is needed, store our target
if (ppTarget) {
*ppTarget = m_pbTarget;
}
if (plExtra) {
*plExtra = CopiedSize - sizeof(uint32_t);
}
return pSrc + 4;
}
uint8_t CDetourDis::EmitMovImmediate(uint32_t*& pDstInst, uint8_t rd, uint64_t immediate)
uint8_t detour_arm64_disasm::EmitMovImmediate(uint32_t*& pDstInst, uint8_t rd, uint64_t immediate)
{
uint32_t piece[4];
piece[3] = (uint32_t)((immediate >> 48) & 0xffff);
@ -439,7 +382,7 @@ uint8_t CDetourDis::EmitMovImmediate(uint32_t*& pDstInst, uint8_t rd, uint64_t i
return (uint8_t)(count * sizeof(uint32_t));
}
uint8_t CDetourDis::CopyAdr(uint8_t* pSource, uint8_t* pDest, uint32_t instruction)
uint8_t detour_arm64_disasm::CopyAdr(uint8_t* pSource, uint8_t* pDest, uint32_t instruction)
{
Adr19& decoded = (Adr19&)(instruction);
uint32_t* pDstInst = (uint32_t*)(pDest);
@ -493,13 +436,12 @@ uint8_t CDetourDis::CopyAdr(uint8_t* pSource, uint8_t* pDest, uint32_t instructi
return (uint8_t)((uint8_t*)pDstInst - pDest);
}
uint8_t CDetourDis::CopyBcc(uint8_t* pSource, uint8_t* pDest, uint32_t instruction)
uint8_t detour_arm64_disasm::CopyBcc(uint8_t* pSource, uint8_t* pDest, uint32_t instruction)
{
Bcc19& decoded = (Bcc19&)(instruction);
uint32_t* pDstInst = (uint32_t*)(pDest);
uint8_t* pTarget = pSource + decoded.Imm();
m_pbTarget = pTarget;
int64_t delta = pTarget - pDest;
int64_t delta4 = pTarget - (pDest + 4);
@ -527,13 +469,12 @@ uint8_t CDetourDis::CopyBcc(uint8_t* pSource, uint8_t* pDest, uint32_t instructi
return (uint8_t)((uint8_t*)pDstInst - pDest);
}
uint8_t CDetourDis::CopyB_or_Bl(uint8_t* pSource, uint8_t* pDest, uint32_t instruction, bool link)
uint8_t detour_arm64_disasm::CopyB_or_Bl(uint8_t* pSource, uint8_t* pDest, uint32_t instruction, bool link)
{
Branch26& decoded = (Branch26&)(instruction);
uint32_t* pDstInst = (uint32_t*)(pDest);
uint8_t* pTarget = pSource + decoded.Imm();
m_pbTarget = pTarget;
int64_t delta = pTarget - pDest;
// output as B or BRL
@ -552,23 +493,22 @@ uint8_t CDetourDis::CopyB_or_Bl(uint8_t* pSource, uint8_t* pDest, uint32_t instr
return (uint8_t)((uint8_t*)pDstInst - pDest);
}
uint8_t CDetourDis::CopyB(uint8_t* pSource, uint8_t* pDest, uint32_t instruction)
uint8_t detour_arm64_disasm::CopyB(uint8_t* pSource, uint8_t* pDest, uint32_t instruction)
{
return CopyB_or_Bl(pSource, pDest, instruction, false);
}
uint8_t CDetourDis::CopyBl(uint8_t* pSource, uint8_t* pDest, uint32_t instruction)
uint8_t detour_arm64_disasm::CopyBl(uint8_t* pSource, uint8_t* pDest, uint32_t instruction)
{
return CopyB_or_Bl(pSource, pDest, instruction, true);
}
uint8_t CDetourDis::CopyCbz(uint8_t* pSource, uint8_t* pDest, uint32_t instruction)
uint8_t detour_arm64_disasm::CopyCbz(uint8_t* pSource, uint8_t* pDest, uint32_t instruction)
{
Cbz19& decoded = (Cbz19&)(instruction);
uint32_t* pDstInst = (uint32_t*)(pDest);
uint8_t* pTarget = pSource + decoded.Imm();
m_pbTarget = pTarget;
int64_t delta = pTarget - pDest;
int64_t delta4 = pTarget - (pDest + 4);
@ -596,13 +536,12 @@ uint8_t CDetourDis::CopyCbz(uint8_t* pSource, uint8_t* pDest, uint32_t instructi
return (uint8_t)((uint8_t*)pDstInst - pDest);
}
uint8_t CDetourDis::CopyTbz(uint8_t* pSource, uint8_t* pDest, uint32_t instruction)
uint8_t detour_arm64_disasm::CopyTbz(uint8_t* pSource, uint8_t* pDest, uint32_t instruction)
{
Tbz14& decoded = (Tbz14&)(instruction);
uint32_t* pDstInst = (uint32_t*)(pDest);
uint8_t* pTarget = pSource + decoded.Imm();
m_pbTarget = pTarget;
int64_t delta = pTarget - pDest;
int64_t delta4 = pTarget - (pDest + 4);
@ -630,7 +569,7 @@ uint8_t CDetourDis::CopyTbz(uint8_t* pSource, uint8_t* pDest, uint32_t instructi
return (uint8_t)((uint8_t*)pDstInst - pDest);
}
uint8_t CDetourDis::CopyLdrLiteral(uint8_t* pSource, uint8_t* pDest, uint32_t instruction)
uint8_t detour_arm64_disasm::CopyLdrLiteral(uint8_t* pSource, uint8_t* pDest, uint32_t instruction)
{
LdrLit19& decoded = (LdrLit19&)(instruction);
uint32_t* pDstInst = (uint32_t*)(pDest);
@ -667,8 +606,32 @@ uint8_t CDetourDis::CopyLdrLiteral(uint8_t* pSource, uint8_t* pDest, uint32_t in
return (uint8_t)((uint8_t*)pDstInst - pDest);
}
void* internal_detour_copy_instruction(void* dst, void* src, void** out_target, int32_t* out_extra_len)
uint8_t* internal_detour_copy_instruction(uint8_t* dst, uint8_t* src, uint32_t* out_extra_len)
{
CDetourDis state;
return (void*)state.CopyInstruction((uint8_t*)dst, (uint8_t*)src, (uint8_t**)out_target, out_extra_len);
using namespace detour_arm64_disasm;
const uint32_t Instruction = GetInstruction(src);
uint32_t CopiedSize;
if ((Instruction & 0x1f000000) == 0x10000000) {
CopiedSize = CopyAdr(src, dst, Instruction);
} else if ((Instruction & 0xff000010) == 0x54000000) {
CopiedSize = CopyBcc(src, dst, Instruction);
} else if ((Instruction & 0x7c000000) == 0x14000000) {
CopiedSize = CopyB_or_Bl(src, dst, Instruction, (Instruction & 0x80000000) != 0);
} else if ((Instruction & 0x7e000000) == 0x34000000) {
CopiedSize = CopyCbz(src, dst, Instruction);
} else if ((Instruction & 0x7e000000) == 0x36000000) {
CopiedSize = CopyTbz(src, dst, Instruction);
} else if ((Instruction & 0x3b000000) == 0x18000000) {
CopiedSize = CopyLdrLiteral(src, dst, Instruction);
} else {
CopiedSize = PureCopy32(src, dst);
}
if (out_extra_len) {
*out_extra_len = CopiedSize - sizeof(uint32_t);
}
return src + 4;
}

View file

@ -11,7 +11,7 @@ extern "C" {
#include <stdint.h>
void* internal_detour_copy_instruction(void* dst, void* src, void** out_target, int32_t* out_extra_len);
uint8_t* internal_detour_copy_instruction(uint8_t* dst, uint8_t* src, uint32_t* out_extra_len);
#ifdef __cplusplus
}

View file

@ -766,10 +766,10 @@ mach_error_t detour_attach_ex(detour_func_t* inout_pointer, detour_func_t detour
while (offset_target < DETOUR_SIZE_OF_JMP) {
const uint8_t* curr_op = src;
int32_t extra_len = 0;
uint32_t extra_len = 0;
DETOUR_TRACE((" copy instruction src=%p, dest=%p\n", src, trampoline_code));
src = (uint8_t*)internal_detour_copy_instruction(trampoline_code, src, nullptr, &extra_len);
src = internal_detour_copy_instruction(trampoline_code, src, &extra_len);
DETOUR_TRACE((" after: src=%p (copied %d bytes)\n", src, (int)(src - curr_op)));
trampoline_code += (src - curr_op) + extra_len;
offset_target = (int32_t)(src - target);