@@ -7540,7 +7540,42 @@ namespace Detours {
7540
7540
} CACHED_OPERATION, *PCACHED_OPERATION;
7541
7541
7542
7542
static std::deque<CACHED_OPERATION> g_CachedOperations;
7543
- static std::unordered_map<const void*, std::unique_ptr<INSTRUCTION>> g_CachedInstructions;
7543
+
7544
+ PRD_OPERAND GetReadOperand(PRD_OPERAND pOperands, unsigned char unCount) {
7545
+ if (!pOperands || !unCount) {
7546
+ return nullptr;
7547
+ }
7548
+
7549
+ for (unsigned char i = 0; i < unCount; ++i) {
7550
+ if (pOperands[i].Access.Read) {
7551
+ if ((pOperands[i].Type == RD_OP_IMM) && !pOperands[i].Info.Immediate.Imm) {
7552
+ continue;
7553
+ }
7554
+
7555
+ return &pOperands[i];
7556
+ }
7557
+ }
7558
+
7559
+ return nullptr;
7560
+ }
7561
+
7562
+ PRD_OPERAND GetWriteOperand(PRD_OPERAND pOperands, unsigned char unCount) {
7563
+ if (!pOperands || !unCount) {
7564
+ return nullptr;
7565
+ }
7566
+
7567
+ for (unsigned char i = 0; i < unCount; ++i) {
7568
+ if (pOperands[i].Access.Write) {
7569
+ if ((pOperands[i].Type == RD_OP_IMM) && !pOperands[i].Info.Immediate.Imm) {
7570
+ continue;
7571
+ }
7572
+
7573
+ return &pOperands[i];
7574
+ }
7575
+ }
7576
+
7577
+ return nullptr;
7578
+ }
7544
7579
7545
7580
static void FixMemoryHookAddress(const PCONTEXT pCTX, const void* pExceptionAddress, MEMORY_HOOK_OPERATION unOperation, const void* pAddress, void* pNewAddress) {
7546
7581
if (!pCTX || !pAddress || !pNewAddress) {
@@ -7571,58 +7606,33 @@ namespace Detours {
7571
7606
}
7572
7607
}
7573
7608
7574
- PINSTRUCTION pInsn = nullptr;
7575
-
7576
- {
7577
- bool bIsCachedInstruction = false;
7578
-
7579
- auto it = g_CachedInstructions.find(pExceptionAddress);
7580
- if (it != g_CachedInstructions.end()) {
7581
- pInsn = it->second.get();
7582
- bIsCachedInstruction = true;
7583
- }
7584
-
7585
- if (!bIsCachedInstruction) {
7586
- auto pInstruction = std::make_unique<INSTRUCTION>();
7587
- if (!pInstruction) {
7588
- return;
7589
- }
7590
-
7609
+ INSTRUCTION insn;
7591
7610
#ifdef _M_X64
7592
- if (!RD_SUCCESS(RdDecode(pInstruction.get() , reinterpret_cast<unsigned char*>(const_cast<void*>(pExceptionAddress)), RD_CODE_64, RD_DATA_64))) {
7611
+ if (!RD_SUCCESS(RdDecode(&insn , reinterpret_cast<unsigned char*>(const_cast<void*>(pExceptionAddress)), RD_CODE_64, RD_DATA_64))) {
7593
7612
#elif _M_IX86
7594
- if (!RD_SUCCESS(RdDecode(pInstruction.get() , reinterpret_cast<unsigned char*>(const_cast<void*>(pExceptionAddress)), RD_CODE_32, RD_DATA_32))) {
7613
+ if (!RD_SUCCESS(RdDecode(&insn , reinterpret_cast<unsigned char*>(const_cast<void*>(pExceptionAddress)), RD_CODE_32, RD_DATA_32))) {
7595
7614
#endif
7596
- return;
7597
- }
7598
-
7599
- pInsn = pInstruction.get();
7600
- g_CachedInstructions.emplace_hint(it, std::make_pair(pExceptionAddress, std::move(pInstruction)));
7601
- }
7602
- }
7603
-
7604
- if (!pInsn) {
7605
7615
return;
7606
7616
}
7607
7617
7608
7618
switch (unOperation) {
7609
7619
case MEMORY_HOOK_OPERATION::MEMORY_READ: {
7610
- if (pInsn-> OperandsCount) {
7611
- auto ReadOperand = pInsn-> Operands[pInsn->OperandsCount - 1] ;
7612
- if (!ReadOperand.Access.Read ) {
7620
+ if (insn. OperandsCount) {
7621
+ auto pReadOperand = GetReadOperand(insn. Operands, insn.OperandsCount) ;
7622
+ if (!pReadOperand ) {
7613
7623
return;
7614
7624
}
7615
7625
7616
- if (ReadOperand. Type == RD_OP_NOT_PRESENT) {
7626
+ if (pReadOperand-> Type == RD_OP_NOT_PRESENT) {
7617
7627
return;
7618
- } else if (ReadOperand. Type == RD_OP_REG) {
7619
- ULONG_PTR unValue = GetRegisterValue(pCTX, ReadOperand. Info.Register.Reg, ReadOperand. Info.Register.Size);
7628
+ } else if (pReadOperand-> Type == RD_OP_REG) {
7629
+ ULONG_PTR unValue = GetRegisterValue(pCTX, pReadOperand-> Info.Register.Reg, pReadOperand-> Info.Register.Size);
7620
7630
if (reinterpret_cast<ULONG_PTR>(pAddress) == unValue) {
7621
- SetRegisterValue(pCTX, ReadOperand. Info.Register.Reg, ReadOperand. Info.Register.Size, reinterpret_cast<size_t>(pNewAddress));
7622
- g_CachedOperations.emplace_back(const_cast<void*>(pExceptionAddress), unOperation, const_cast<void*>(pAddress), ReadOperand , pNewAddress);
7631
+ SetRegisterValue(pCTX, pReadOperand-> Info.Register.Reg, pReadOperand-> Info.Register.Size, reinterpret_cast<size_t>(pNewAddress));
7632
+ g_CachedOperations.emplace_back(const_cast<void*>(pExceptionAddress), unOperation, const_cast<void*>(pAddress), *pReadOperand , pNewAddress);
7623
7633
return;
7624
7634
}
7625
- } else if (ReadOperand. Type == RD_OP_MEM) {
7635
+ } else if (pReadOperand-> Type == RD_OP_MEM) {
7626
7636
#ifdef _M_X64
7627
7637
unsigned long long unBase = 0;
7628
7638
unsigned long long unIndex = 0;
@@ -7632,42 +7642,42 @@ namespace Detours {
7632
7642
#endif
7633
7643
unsigned long long unDisp = 0;
7634
7644
7635
- if (ReadOperand. Info.Memory.HasBase) {
7636
- unBase = GetRegisterValue(pCTX, ReadOperand. Info.Memory.Base, ReadOperand. Info.Memory.BaseSize);
7645
+ if (pReadOperand-> Info.Memory.HasBase) {
7646
+ unBase = GetRegisterValue(pCTX, pReadOperand-> Info.Memory.Base, pReadOperand-> Info.Memory.BaseSize);
7637
7647
}
7638
7648
7639
- if (ReadOperand. Info.Memory.HasIndex) {
7640
- unIndex = GetRegisterValue(pCTX, ReadOperand. Info.Memory.Index, ReadOperand. Info.Memory.IndexSize) * ReadOperand. Info.Memory.Scale;
7649
+ if (pReadOperand-> Info.Memory.HasIndex) {
7650
+ unIndex = GetRegisterValue(pCTX, pReadOperand-> Info.Memory.Index, pReadOperand-> Info.Memory.IndexSize) * pReadOperand-> Info.Memory.Scale;
7641
7651
}
7642
7652
7643
- if (ReadOperand. Info.Memory.HasDisp) {
7644
- unDisp = ReadOperand. Info.Memory.Disp;
7653
+ if (pReadOperand-> Info.Memory.HasDisp) {
7654
+ unDisp = pReadOperand-> Info.Memory.Disp;
7645
7655
}
7646
7656
7647
7657
if (reinterpret_cast<ULONG_PTR>(pAddress) == unBase + unIndex + unDisp) {
7648
7658
if (unBase) {
7649
7659
const size_t unOffset = reinterpret_cast<size_t>(pAddress) - unBase;
7650
- SetRegisterValue(pCTX, ReadOperand. Info.Memory.Base, ReadOperand. Info.Memory.BaseSize, reinterpret_cast<size_t>(pNewAddress) - unOffset);
7651
- ReadOperand. Info.Memory.HasIndex = false;
7652
- g_CachedOperations.emplace_back(const_cast<void*>(pExceptionAddress), unOperation, const_cast<void*>(pAddress), ReadOperand , static_cast<char*>(pNewAddress) - unOffset);
7660
+ SetRegisterValue(pCTX, pReadOperand-> Info.Memory.Base, pReadOperand-> Info.Memory.BaseSize, reinterpret_cast<size_t>(pNewAddress) - unOffset);
7661
+ pReadOperand-> Info.Memory.HasIndex = false;
7662
+ g_CachedOperations.emplace_back(const_cast<void*>(pExceptionAddress), unOperation, const_cast<void*>(pAddress), *pReadOperand , static_cast<char*>(pNewAddress) - unOffset);
7653
7663
return;
7654
7664
}
7655
7665
7656
7666
if (unIndex) {
7657
7667
const size_t unOffset = reinterpret_cast<size_t>(pAddress) - unIndex;
7658
- SetRegisterValue(pCTX, ReadOperand. Info.Memory.Index, ReadOperand. Info.Memory.IndexSize, reinterpret_cast<size_t>(pNewAddress) - unOffset);
7659
- ReadOperand. Info.Memory.HasBase = false;
7660
- g_CachedOperations.emplace_back(const_cast<void*>(pExceptionAddress), unOperation, const_cast<void*>(pAddress), ReadOperand , static_cast<char*>(pNewAddress) - unOffset);
7668
+ SetRegisterValue(pCTX, pReadOperand-> Info.Memory.Index, pReadOperand-> Info.Memory.IndexSize, reinterpret_cast<size_t>(pNewAddress) - unOffset);
7669
+ pReadOperand-> Info.Memory.HasBase = false;
7670
+ g_CachedOperations.emplace_back(const_cast<void*>(pExceptionAddress), unOperation, const_cast<void*>(pAddress), *pReadOperand , static_cast<char*>(pNewAddress) - unOffset);
7661
7671
return;
7662
7672
}
7663
7673
}
7664
- } else if (ReadOperand. Type == RD_OP_IMM) {
7674
+ } else if (pReadOperand-> Type == RD_OP_IMM) {
7665
7675
__debugbreak(); // TODO: Implement.
7666
- } else if (ReadOperand. Type == RD_OP_OFFS) {
7676
+ } else if (pReadOperand-> Type == RD_OP_OFFS) {
7667
7677
__debugbreak(); // TODO: Implement.
7668
- } else if (ReadOperand. Type == RD_OP_ADDR) {
7678
+ } else if (pReadOperand-> Type == RD_OP_ADDR) {
7669
7679
__debugbreak(); // TODO: Implement.
7670
- } else if (ReadOperand. Type == RD_OP_CONST) {
7680
+ } else if (pReadOperand-> Type == RD_OP_CONST) {
7671
7681
__debugbreak(); // TODO: Implement.
7672
7682
}
7673
7683
}
@@ -7676,28 +7686,22 @@ namespace Detours {
7676
7686
}
7677
7687
7678
7688
case MEMORY_HOOK_OPERATION::MEMORY_WRITE: {
7679
- if (pInsn->OperandsCount) {
7680
- auto WriteOperand = pInsn->Operands[pInsn->OperandsCount - 1];
7681
- if (!WriteOperand.Access.Write) {
7682
- if (pInsn->OperandsCount > 1) {
7683
- WriteOperand = pInsn->Operands[pInsn->OperandsCount - 2];
7684
- }
7685
-
7686
- if (!WriteOperand.Access.Write) {
7687
- return;
7688
- }
7689
+ if (insn.OperandsCount) {
7690
+ auto pWriteOperand = GetWriteOperand(insn.Operands, insn.OperandsCount);
7691
+ if (!pWriteOperand) {
7692
+ return;
7689
7693
}
7690
7694
7691
- if (WriteOperand. Type == RD_OP_NOT_PRESENT) {
7695
+ if (pWriteOperand-> Type == RD_OP_NOT_PRESENT) {
7692
7696
return;
7693
- } else if (WriteOperand. Type == RD_OP_REG) {
7694
- ULONG_PTR unValue = GetRegisterValue(pCTX, WriteOperand. Info.Register.Reg, WriteOperand. Info.Register.Size);
7697
+ } else if (pWriteOperand-> Type == RD_OP_REG) {
7698
+ ULONG_PTR unValue = GetRegisterValue(pCTX, pWriteOperand-> Info.Register.Reg, pWriteOperand-> Info.Register.Size);
7695
7699
if (reinterpret_cast<ULONG_PTR>(pAddress) == unValue) {
7696
- SetRegisterValue(pCTX, WriteOperand. Info.Register.Reg, WriteOperand. Info.Register.Size, reinterpret_cast<size_t>(pNewAddress));
7697
- g_CachedOperations.emplace_back(const_cast<void*>(pExceptionAddress), unOperation, const_cast<void*>(pAddress), WriteOperand , pNewAddress);
7700
+ SetRegisterValue(pCTX, pWriteOperand-> Info.Register.Reg, pWriteOperand-> Info.Register.Size, reinterpret_cast<size_t>(pNewAddress));
7701
+ g_CachedOperations.emplace_back(const_cast<void*>(pExceptionAddress), unOperation, const_cast<void*>(pAddress), *pWriteOperand , pNewAddress);
7698
7702
return;
7699
7703
}
7700
- } else if (WriteOperand. Type == RD_OP_MEM) {
7704
+ } else if (pWriteOperand-> Type == RD_OP_MEM) {
7701
7705
#ifdef _M_X64
7702
7706
unsigned long long unBase = 0;
7703
7707
unsigned long long unIndex = 0;
@@ -7707,42 +7711,42 @@ namespace Detours {
7707
7711
#endif
7708
7712
unsigned long long unDisp = 0;
7709
7713
7710
- if (WriteOperand. Info.Memory.HasBase) {
7711
- unBase = GetRegisterValue(pCTX, WriteOperand. Info.Memory.Base, WriteOperand. Info.Memory.BaseSize);
7714
+ if (pWriteOperand-> Info.Memory.HasBase) {
7715
+ unBase = GetRegisterValue(pCTX, pWriteOperand-> Info.Memory.Base, pWriteOperand-> Info.Memory.BaseSize);
7712
7716
}
7713
7717
7714
- if (WriteOperand. Info.Memory.HasIndex) {
7715
- unIndex = GetRegisterValue(pCTX, WriteOperand. Info.Memory.Index, WriteOperand. Info.Memory.IndexSize) * WriteOperand. Info.Memory.Scale;
7718
+ if (pWriteOperand-> Info.Memory.HasIndex) {
7719
+ unIndex = GetRegisterValue(pCTX, pWriteOperand-> Info.Memory.Index, pWriteOperand-> Info.Memory.IndexSize) * pWriteOperand-> Info.Memory.Scale;
7716
7720
}
7717
7721
7718
- if (WriteOperand. Info.Memory.HasDisp) {
7719
- unDisp = WriteOperand. Info.Memory.Disp;
7722
+ if (pWriteOperand-> Info.Memory.HasDisp) {
7723
+ unDisp = pWriteOperand-> Info.Memory.Disp;
7720
7724
}
7721
7725
7722
7726
if (reinterpret_cast<ULONG_PTR>(pAddress) == unBase + unIndex + unDisp) {
7723
7727
if (unBase) {
7724
7728
const size_t unOffset = reinterpret_cast<size_t>(pAddress) - unBase;
7725
- SetRegisterValue(pCTX, WriteOperand. Info.Memory.Base, WriteOperand. Info.Memory.BaseSize, reinterpret_cast<size_t>(pNewAddress) - unOffset);
7726
- WriteOperand. Info.Memory.HasIndex = false;
7727
- g_CachedOperations.emplace_back(const_cast<void*>(pExceptionAddress), unOperation, const_cast<void*>(pAddress), WriteOperand , static_cast<char*>(pNewAddress) - unOffset);
7729
+ SetRegisterValue(pCTX, pWriteOperand-> Info.Memory.Base, pWriteOperand-> Info.Memory.BaseSize, reinterpret_cast<size_t>(pNewAddress) - unOffset);
7730
+ pWriteOperand-> Info.Memory.HasIndex = false;
7731
+ g_CachedOperations.emplace_back(const_cast<void*>(pExceptionAddress), unOperation, const_cast<void*>(pAddress), *pWriteOperand , static_cast<char*>(pNewAddress) - unOffset);
7728
7732
return;
7729
7733
}
7730
7734
7731
7735
if (unIndex) {
7732
7736
const size_t unOffset = reinterpret_cast<size_t>(pAddress) - unIndex;
7733
- SetRegisterValue(pCTX, WriteOperand. Info.Memory.Index, WriteOperand. Info.Memory.IndexSize, reinterpret_cast<size_t>(pNewAddress) - unOffset);
7734
- WriteOperand. Info.Memory.HasBase = false;
7735
- g_CachedOperations.emplace_back(const_cast<void*>(pExceptionAddress), unOperation, const_cast<void*>(pAddress), WriteOperand , static_cast<char*>(pNewAddress) - unOffset);
7737
+ SetRegisterValue(pCTX, pWriteOperand-> Info.Memory.Index, pWriteOperand-> Info.Memory.IndexSize, reinterpret_cast<size_t>(pNewAddress) - unOffset);
7738
+ pWriteOperand-> Info.Memory.HasBase = false;
7739
+ g_CachedOperations.emplace_back(const_cast<void*>(pExceptionAddress), unOperation, const_cast<void*>(pAddress), *pWriteOperand , static_cast<char*>(pNewAddress) - unOffset);
7736
7740
return;
7737
7741
}
7738
7742
}
7739
- } else if (WriteOperand. Type == RD_OP_IMM) {
7743
+ } else if (pWriteOperand-> Type == RD_OP_IMM) {
7740
7744
__debugbreak(); // TODO: Implement.
7741
- } else if (WriteOperand. Type == RD_OP_OFFS) {
7745
+ } else if (pWriteOperand-> Type == RD_OP_OFFS) {
7742
7746
__debugbreak(); // TODO: Implement.
7743
- } else if (WriteOperand. Type == RD_OP_ADDR) {
7747
+ } else if (pWriteOperand-> Type == RD_OP_ADDR) {
7744
7748
__debugbreak(); // TODO: Implement.
7745
- } else if (WriteOperand. Type == RD_OP_CONST) {
7749
+ } else if (pWriteOperand-> Type == RD_OP_CONST) {
7746
7750
__debugbreak(); // TODO: Implement.
7747
7751
}
7748
7752
}
@@ -7912,7 +7916,7 @@ namespace Detours {
7912
7916
}
7913
7917
}
7914
7918
7915
- const bool bResult = pRecord->m_pCallBack(pCTX, pExceptionAddress, unOperation, pAddress, &pNewAddress);
7919
+ const bool bResult = pRecord->m_pCallBack(pCTX, pExceptionAddress, unOperation, pRecord->m_pAddress, pAddress, &pNewAddress);
7916
7920
if (bResult) {
7917
7921
FixMemoryHookAddress(pCTX, pExceptionAddress, unOperation, pAddress, pNewAddress);
7918
7922
}
0 commit comments