remove unused state from CDetourDis
This commit is contained in:
parent
4c22783a54
commit
21c874186d
4 changed files with 54 additions and 91 deletions
|
|
@ -1,4 +1,4 @@
|
||||||
cmake_minimum_required(VERSION 4.0)
|
cmake_minimum_required(VERSION 3.29)
|
||||||
project(mach_detours C CXX)
|
project(mach_detours C CXX)
|
||||||
|
|
||||||
set(CMAKE_C_STANDARD 23)
|
set(CMAKE_C_STANDARD 23)
|
||||||
|
|
|
||||||
|
|
@ -36,19 +36,8 @@
|
||||||
// TBZ z0110110 bbbbbiii iiiiiiii iiittttt & 0x7f000000 == 0x36000000 (z = size, b = bitnum, i = SignExtend(imm14:00, 64), t = Rt)
|
// 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
|
union AddImm12
|
||||||
{
|
{
|
||||||
uint32_t Assembled;
|
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:
|
static uint32_t GetInstruction(uint8_t* pSource)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
return ((uint32_t*)pSource)[0];
|
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;
|
*pDstInst++ = instruction;
|
||||||
return sizeof(uint32_t);
|
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;
|
*(uint32_t *)pDest = *(uint32_t*)pSource;
|
||||||
return sizeof(uint32_t);
|
return sizeof(uint32_t);
|
||||||
|
|
@ -349,46 +331,7 @@ uint8_t CDetourDis::PureCopy32(uint8_t* pSource, uint8_t* pDest)
|
||||||
/////////////////////////////////////////////////////////// Disassembler Code.
|
/////////////////////////////////////////////////////////// Disassembler Code.
|
||||||
//
|
//
|
||||||
|
|
||||||
uint8_t* CDetourDis::CopyInstruction(uint8_t* pDst,
|
uint8_t detour_arm64_disasm::EmitMovImmediate(uint32_t*& pDstInst, uint8_t rd, uint64_t immediate)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
uint32_t piece[4];
|
uint32_t piece[4];
|
||||||
piece[3] = (uint32_t)((immediate >> 48) & 0xffff);
|
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));
|
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);
|
Adr19& decoded = (Adr19&)(instruction);
|
||||||
uint32_t* pDstInst = (uint32_t*)(pDest);
|
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);
|
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);
|
Bcc19& decoded = (Bcc19&)(instruction);
|
||||||
uint32_t* pDstInst = (uint32_t*)(pDest);
|
uint32_t* pDstInst = (uint32_t*)(pDest);
|
||||||
|
|
||||||
uint8_t* pTarget = pSource + decoded.Imm();
|
uint8_t* pTarget = pSource + decoded.Imm();
|
||||||
m_pbTarget = pTarget;
|
|
||||||
int64_t delta = pTarget - pDest;
|
int64_t delta = pTarget - pDest;
|
||||||
int64_t delta4 = pTarget - (pDest + 4);
|
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);
|
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);
|
Branch26& decoded = (Branch26&)(instruction);
|
||||||
uint32_t* pDstInst = (uint32_t*)(pDest);
|
uint32_t* pDstInst = (uint32_t*)(pDest);
|
||||||
|
|
||||||
uint8_t* pTarget = pSource + decoded.Imm();
|
uint8_t* pTarget = pSource + decoded.Imm();
|
||||||
m_pbTarget = pTarget;
|
|
||||||
int64_t delta = pTarget - pDest;
|
int64_t delta = pTarget - pDest;
|
||||||
|
|
||||||
// output as B or BRL
|
// 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);
|
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);
|
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);
|
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);
|
Cbz19& decoded = (Cbz19&)(instruction);
|
||||||
uint32_t* pDstInst = (uint32_t*)(pDest);
|
uint32_t* pDstInst = (uint32_t*)(pDest);
|
||||||
|
|
||||||
uint8_t* pTarget = pSource + decoded.Imm();
|
uint8_t* pTarget = pSource + decoded.Imm();
|
||||||
m_pbTarget = pTarget;
|
|
||||||
int64_t delta = pTarget - pDest;
|
int64_t delta = pTarget - pDest;
|
||||||
int64_t delta4 = pTarget - (pDest + 4);
|
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);
|
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);
|
Tbz14& decoded = (Tbz14&)(instruction);
|
||||||
uint32_t* pDstInst = (uint32_t*)(pDest);
|
uint32_t* pDstInst = (uint32_t*)(pDest);
|
||||||
|
|
||||||
uint8_t* pTarget = pSource + decoded.Imm();
|
uint8_t* pTarget = pSource + decoded.Imm();
|
||||||
m_pbTarget = pTarget;
|
|
||||||
int64_t delta = pTarget - pDest;
|
int64_t delta = pTarget - pDest;
|
||||||
int64_t delta4 = pTarget - (pDest + 4);
|
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);
|
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);
|
LdrLit19& decoded = (LdrLit19&)(instruction);
|
||||||
uint32_t* pDstInst = (uint32_t*)(pDest);
|
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);
|
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;
|
using namespace detour_arm64_disasm;
|
||||||
return (void*)state.CopyInstruction((uint8_t*)dst, (uint8_t*)src, (uint8_t**)out_target, out_extra_len);
|
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ extern "C" {
|
||||||
|
|
||||||
#include <stdint.h>
|
#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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
while (offset_target < DETOUR_SIZE_OF_JMP) {
|
||||||
const uint8_t* curr_op = src;
|
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));
|
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)));
|
DETOUR_TRACE((" after: src=%p (copied %d bytes)\n", src, (int)(src - curr_op)));
|
||||||
trampoline_code += (src - curr_op) + extra_len;
|
trampoline_code += (src - curr_op) + extra_len;
|
||||||
offset_target = (int32_t)(src - target);
|
offset_target = (int32_t)(src - target);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue