From a946e4018df787aba9df23e36449969834dbf060 Mon Sep 17 00:00:00 2001 From: Ren Date: Wed, 24 Jul 2024 18:31:18 +0300 Subject: [PATCH] Add files via upload --- Detours.cpp | 375 +++++++++++++++++++++++++++------------------------- main.cpp | 33 ++++- 2 files changed, 226 insertions(+), 182 deletions(-) diff --git a/Detours.cpp b/Detours.cpp index da535af..fbe626f 100644 --- a/Detours.cpp +++ b/Detours.cpp @@ -7513,250 +7513,271 @@ namespace Detours { } static void FixMemoryHookAddress(const PCONTEXT pCTX, const void* pExceptionAddress, MEMORY_HOOK_OPERATION unOperation, const void* pAddress, void* pNewAddress) { - if (!pCTX || !pExceptionAddress || !pAddress) { + if (!pCTX || !pAddress || !pNewAddress) { return; } - INSTRUCTION ins; + if (pExceptionAddress) { + INSTRUCTION ins; #ifdef _M_X64 - if (!RD_SUCCESS(RdDecode(&ins, reinterpret_cast(const_cast(pExceptionAddress)), RD_CODE_64, RD_DATA_64))) { + if (!RD_SUCCESS(RdDecode(&ins, reinterpret_cast(const_cast(pExceptionAddress)), RD_CODE_64, RD_DATA_64))) { #elif _M_IX86 - if (!RD_SUCCESS(RdDecode(&ins, reinterpret_cast(const_cast(pExceptionAddress)), RD_CODE_32, RD_DATA_32))) { + if (!RD_SUCCESS(RdDecode(&ins, reinterpret_cast(const_cast(pExceptionAddress)), RD_CODE_32, RD_DATA_32))) { #endif - return; - } - - switch (unOperation) { - case MEMORY_HOOK_OPERATION::MEMORY_READ: { - if (ins.OperandsCount) { - auto& ReadOperand = ins.Operands[ins.OperandsCount - 1]; - if (!ReadOperand.Access.Read) { - return; - } + return; + } - if (ReadOperand.Type == RD_OP_NOT_PRESENT) { - return; - } else if (ReadOperand.Type == RD_OP_REG) { - ULONG_PTR unValue = GetRegisterValue(pCTX, ReadOperand.Info.Register.Reg, ReadOperand.Info.Register.Size); - if (reinterpret_cast(pAddress) == unValue) { - SetRegisterValue(pCTX, ReadOperand.Info.Register.Reg, ReadOperand.Info.Register.Size, unValue); + switch (unOperation) { + case MEMORY_HOOK_OPERATION::MEMORY_READ: { + if (ins.OperandsCount) { + auto& ReadOperand = ins.Operands[ins.OperandsCount - 1]; + if (!ReadOperand.Access.Read) { + return; } - } else if (ReadOperand.Type == RD_OP_MEM) { + + if (ReadOperand.Type == RD_OP_NOT_PRESENT) { + return; + } else if (ReadOperand.Type == RD_OP_REG) { + ULONG_PTR unValue = GetRegisterValue(pCTX, ReadOperand.Info.Register.Reg, ReadOperand.Info.Register.Size); + if (reinterpret_cast(pAddress) == unValue) { + SetRegisterValue(pCTX, ReadOperand.Info.Register.Reg, ReadOperand.Info.Register.Size, unValue); + } + } else if (ReadOperand.Type == RD_OP_MEM) { #ifdef _M_X64 - unsigned long long unBase = 0; - unsigned long long unIndex = 0; + unsigned long long unBase = 0; + unsigned long long unIndex = 0; #elif _M_IX86 - unsigned int unBase = 0; - unsigned int unIndex = 0; + unsigned int unBase = 0; + unsigned int unIndex = 0; #endif - unsigned long long unDisp = 0; + unsigned long long unDisp = 0; - if (ReadOperand.Info.Memory.HasBase) { - unBase = GetRegisterValue(pCTX, ReadOperand.Info.Memory.Base, ReadOperand.Info.Memory.BaseSize); - } + if (ReadOperand.Info.Memory.HasBase) { + unBase = GetRegisterValue(pCTX, ReadOperand.Info.Memory.Base, ReadOperand.Info.Memory.BaseSize); + } - if (ReadOperand.Info.Memory.HasIndex) { - unIndex = GetRegisterValue(pCTX, ReadOperand.Info.Memory.Index, ReadOperand.Info.Memory.IndexSize) * ReadOperand.Info.Memory.Scale; - } + if (ReadOperand.Info.Memory.HasIndex) { + unIndex = GetRegisterValue(pCTX, ReadOperand.Info.Memory.Index, ReadOperand.Info.Memory.IndexSize) * ReadOperand.Info.Memory.Scale; + } - if (ReadOperand.Info.Memory.HasDisp) { - unDisp = ReadOperand.Info.Memory.Disp; - } + if (ReadOperand.Info.Memory.HasDisp) { + unDisp = ReadOperand.Info.Memory.Disp; + } + + if (reinterpret_cast(pAddress) == unBase + unIndex + unDisp) { + if (unBase) { + const size_t unOffset = reinterpret_cast(pAddress) - unBase; + SetRegisterValue(pCTX, ReadOperand.Info.Memory.Base, ReadOperand.Info.Memory.BaseSize, reinterpret_cast(pNewAddress) - unOffset); + return; + } + + if (unIndex) { + const size_t unOffset = reinterpret_cast(pAddress) - unIndex; + SetRegisterValue(pCTX, ReadOperand.Info.Memory.Index, ReadOperand.Info.Memory.IndexSize, reinterpret_cast(pNewAddress) - unOffset); + return; + } - if (reinterpret_cast(pAddress) == unBase + unIndex + unDisp) { - if (unBase) { - const size_t unOffset = reinterpret_cast(pAddress) - unBase; - SetRegisterValue(pCTX, ReadOperand.Info.Memory.Base, ReadOperand.Info.Memory.BaseSize, reinterpret_cast(pNewAddress) - unOffset); return; } - - return; + } else if (ReadOperand.Type == RD_OP_IMM) { + __debugbreak(); // TODO: Implement. + } else if (ReadOperand.Type == RD_OP_OFFS) { + __debugbreak(); // TODO: Implement. + } else if (ReadOperand.Type == RD_OP_ADDR) { + __debugbreak(); // TODO: Implement. + } else if (ReadOperand.Type == RD_OP_CONST) { + __debugbreak(); // TODO: Implement. } - } else if (ReadOperand.Type == RD_OP_IMM) { - __debugbreak(); // TODO: Implement. - } else if (ReadOperand.Type == RD_OP_OFFS) { - __debugbreak(); // TODO: Implement. - } else if (ReadOperand.Type == RD_OP_ADDR) { - __debugbreak(); // TODO: Implement. - } else if (ReadOperand.Type == RD_OP_CONST) { - __debugbreak(); // TODO: Implement. } + + return; } - return; - } + case MEMORY_HOOK_OPERATION::MEMORY_WRITE: { + if (ins.OperandsCount) { + auto& WriteOperand = ins.Operands[ins.OperandsCount - 1]; + if (!WriteOperand.Access.Write) { + if (ins.OperandsCount > 1) { + WriteOperand = ins.Operands[ins.OperandsCount - 2]; + } - case MEMORY_HOOK_OPERATION::MEMORY_WRITE: { - if (ins.OperandsCount) { - auto& WriteOperand = ins.Operands[ins.OperandsCount - 1]; - if (!WriteOperand.Access.Write) { - if (ins.OperandsCount > 1) { - WriteOperand = ins.Operands[ins.OperandsCount - 2]; + if (!WriteOperand.Access.Write) { + return; + } } - if (!WriteOperand.Access.Write) { + if (WriteOperand.Type == RD_OP_NOT_PRESENT) { return; - } - } - - if (WriteOperand.Type == RD_OP_NOT_PRESENT) { - return; - } else if (WriteOperand.Type == RD_OP_REG) { - ULONG_PTR unValue = GetRegisterValue(pCTX, WriteOperand.Info.Register.Reg, WriteOperand.Info.Register.Size); - if (reinterpret_cast(pAddress) == unValue) { - SetRegisterValue(pCTX, WriteOperand.Info.Register.Reg, WriteOperand.Info.Register.Size, unValue); - } - } else if (WriteOperand.Type == RD_OP_MEM) { + } else if (WriteOperand.Type == RD_OP_REG) { + ULONG_PTR unValue = GetRegisterValue(pCTX, WriteOperand.Info.Register.Reg, WriteOperand.Info.Register.Size); + if (reinterpret_cast(pAddress) == unValue) { + SetRegisterValue(pCTX, WriteOperand.Info.Register.Reg, WriteOperand.Info.Register.Size, unValue); + } + } else if (WriteOperand.Type == RD_OP_MEM) { #ifdef _M_X64 - unsigned long long unBase = 0; - unsigned long long unIndex = 0; + unsigned long long unBase = 0; + unsigned long long unIndex = 0; #elif _M_IX86 - unsigned int unBase = 0; - unsigned int unIndex = 0; + unsigned int unBase = 0; + unsigned int unIndex = 0; #endif - unsigned long long unDisp = 0; + unsigned long long unDisp = 0; - if (WriteOperand.Info.Memory.HasBase) { - unBase = GetRegisterValue(pCTX, WriteOperand.Info.Memory.Base, WriteOperand.Info.Memory.BaseSize); - } + if (WriteOperand.Info.Memory.HasBase) { + unBase = GetRegisterValue(pCTX, WriteOperand.Info.Memory.Base, WriteOperand.Info.Memory.BaseSize); + } - if (WriteOperand.Info.Memory.HasIndex) { - unIndex = GetRegisterValue(pCTX, WriteOperand.Info.Memory.Index, WriteOperand.Info.Memory.IndexSize) * WriteOperand.Info.Memory.Scale; - } + if (WriteOperand.Info.Memory.HasIndex) { + unIndex = GetRegisterValue(pCTX, WriteOperand.Info.Memory.Index, WriteOperand.Info.Memory.IndexSize) * WriteOperand.Info.Memory.Scale; + } - if (WriteOperand.Info.Memory.HasDisp) { - unDisp = WriteOperand.Info.Memory.Disp; - } + if (WriteOperand.Info.Memory.HasDisp) { + unDisp = WriteOperand.Info.Memory.Disp; + } + + if (reinterpret_cast(pAddress) == unBase + unIndex + unDisp) { + if (unBase) { + const size_t unOffset = reinterpret_cast(pAddress) - unBase; + SetRegisterValue(pCTX, WriteOperand.Info.Memory.Base, WriteOperand.Info.Memory.BaseSize, reinterpret_cast(pNewAddress) - unOffset); + return; + } + + if (unIndex) { + const size_t unOffset = reinterpret_cast(pAddress) - unIndex; + SetRegisterValue(pCTX, WriteOperand.Info.Memory.Index, WriteOperand.Info.Memory.IndexSize, reinterpret_cast(pNewAddress) - unOffset); + return; + } - if (reinterpret_cast(pAddress) == unBase + unIndex + unDisp) { - if (unBase) { - const size_t unOffset = reinterpret_cast(pAddress) - unBase; - SetRegisterValue(pCTX, WriteOperand.Info.Memory.Base, WriteOperand.Info.Memory.BaseSize, reinterpret_cast(pNewAddress) - unOffset); return; } - - return; + } else if (WriteOperand.Type == RD_OP_IMM) { + __debugbreak(); // TODO: Implement. + } else if (WriteOperand.Type == RD_OP_OFFS) { + __debugbreak(); // TODO: Implement. + } else if (WriteOperand.Type == RD_OP_ADDR) { + __debugbreak(); // TODO: Implement. + } else if (WriteOperand.Type == RD_OP_CONST) { + __debugbreak(); // TODO: Implement. } - } else if (WriteOperand.Type == RD_OP_IMM) { - __debugbreak(); // TODO: Implement. - } else if (WriteOperand.Type == RD_OP_OFFS) { - __debugbreak(); // TODO: Implement. - } else if (WriteOperand.Type == RD_OP_ADDR) { - __debugbreak(); // TODO: Implement. - } else if (WriteOperand.Type == RD_OP_CONST) { - __debugbreak(); // TODO: Implement. } - } - return; - } + return; + } - case MEMORY_HOOK_OPERATION::MEMORY_EXECUTE: { - break; + default: + break; } - - default: - break; } + if (unOperation == MEMORY_HOOK_OPERATION::MEMORY_EXECUTE) { #ifdef _M_X64 - if (pCTX->Rax == reinterpret_cast(pAddress)) { - pCTX->Rax = reinterpret_cast(pNewAddress); - } + if (pCTX->Rip == reinterpret_cast(pAddress)) { + pCTX->Rip = reinterpret_cast(pNewAddress); + } #elif _M_IX86 - if (pCTX->Eax == reinterpret_cast(pAddress)) { - pCTX->Eax = reinterpret_cast(pNewAddress); - } + if (pCTX->Eip == reinterpret_cast(pAddress)) { + pCTX->Eip = reinterpret_cast(pNewAddress); + } #endif #ifdef _M_X64 - if (pCTX->Rcx == reinterpret_cast(pAddress)) { - pCTX->Rcx = reinterpret_cast(pNewAddress); - } + if (pCTX->Rax == reinterpret_cast(pAddress)) { + pCTX->Rax = reinterpret_cast(pNewAddress); + } #elif _M_IX86 - if (pCTX->Ecx == reinterpret_cast(pAddress)) { - pCTX->Ecx = reinterpret_cast(pNewAddress); - } + if (pCTX->Eax == reinterpret_cast(pAddress)) { + pCTX->Eax = reinterpret_cast(pNewAddress); + } #endif #ifdef _M_X64 - if (pCTX->Rdx == reinterpret_cast(pAddress)) { - pCTX->Rdx = reinterpret_cast(pNewAddress); - } + if (pCTX->Rcx == reinterpret_cast(pAddress)) { + pCTX->Rcx = reinterpret_cast(pNewAddress); + } #elif _M_IX86 - if (pCTX->Edx == reinterpret_cast(pAddress)) { - pCTX->Edx = reinterpret_cast(pNewAddress); - } + if (pCTX->Ecx == reinterpret_cast(pAddress)) { + pCTX->Ecx = reinterpret_cast(pNewAddress); + } #endif #ifdef _M_X64 - if (pCTX->Rbx == reinterpret_cast(pAddress)) { - pCTX->Rbx = reinterpret_cast(pNewAddress); - } + if (pCTX->Rdx == reinterpret_cast(pAddress)) { + pCTX->Rdx = reinterpret_cast(pNewAddress); + } #elif _M_IX86 - if (pCTX->Ebx == reinterpret_cast(pAddress)) { - pCTX->Ebx = reinterpret_cast(pNewAddress); - } + if (pCTX->Edx == reinterpret_cast(pAddress)) { + pCTX->Edx = reinterpret_cast(pNewAddress); + } #endif #ifdef _M_X64 - if (pCTX->Rsp == reinterpret_cast(pAddress)) { - pCTX->Rsp = reinterpret_cast(pNewAddress); - } + if (pCTX->Rbx == reinterpret_cast(pAddress)) { + pCTX->Rbx = reinterpret_cast(pNewAddress); + } #elif _M_IX86 - if (pCTX->Esp == reinterpret_cast(pAddress)) { - pCTX->Esp = reinterpret_cast(pNewAddress); - } + if (pCTX->Ebx == reinterpret_cast(pAddress)) { + pCTX->Ebx = reinterpret_cast(pNewAddress); + } #endif #ifdef _M_X64 - if (pCTX->Rbp == reinterpret_cast(pAddress)) { - pCTX->Rbp = reinterpret_cast(pNewAddress); - } + if (pCTX->Rsp == reinterpret_cast(pAddress)) { + pCTX->Rsp = reinterpret_cast(pNewAddress); + } #elif _M_IX86 - if (pCTX->Ebp == reinterpret_cast(pAddress)) { - pCTX->Ebp = reinterpret_cast(pNewAddress); - } + if (pCTX->Esp == reinterpret_cast(pAddress)) { + pCTX->Esp = reinterpret_cast(pNewAddress); + } #endif #ifdef _M_X64 - if (pCTX->Rsi == reinterpret_cast(pAddress)) { - pCTX->Rsi = reinterpret_cast(pNewAddress); - } + if (pCTX->Rbp == reinterpret_cast(pAddress)) { + pCTX->Rbp = reinterpret_cast(pNewAddress); + } #elif _M_IX86 - if (pCTX->Esi == reinterpret_cast(pAddress)) { - pCTX->Esi = reinterpret_cast(pNewAddress); - } + if (pCTX->Ebp == reinterpret_cast(pAddress)) { + pCTX->Ebp = reinterpret_cast(pNewAddress); + } #endif #ifdef _M_X64 - if (pCTX->Rdi == reinterpret_cast(pAddress)) { - pCTX->Rdi = reinterpret_cast(pNewAddress); - } + if (pCTX->Rsi == reinterpret_cast(pAddress)) { + pCTX->Rsi = reinterpret_cast(pNewAddress); + } #elif _M_IX86 - if (pCTX->Edi == reinterpret_cast(pAddress)) { - pCTX->Edi = reinterpret_cast(pNewAddress); - } + if (pCTX->Esi == reinterpret_cast(pAddress)) { + pCTX->Esi = reinterpret_cast(pNewAddress); + } #endif #ifdef _M_X64 - if (pCTX->R8 == reinterpret_cast(pAddress)) { - pCTX->R8 = reinterpret_cast(pNewAddress); - } - if (pCTX->R9 == reinterpret_cast(pAddress)) { - pCTX->R9 = reinterpret_cast(pNewAddress); - } - if (pCTX->R10 == reinterpret_cast(pAddress)) { - pCTX->R10 = reinterpret_cast(pNewAddress); - } - if (pCTX->R11 == reinterpret_cast(pAddress)) { - pCTX->R11 = reinterpret_cast(pNewAddress); - } - if (pCTX->R12 == reinterpret_cast(pAddress)) { - pCTX->R12 = reinterpret_cast(pNewAddress); - } - if (pCTX->R13 == reinterpret_cast(pAddress)) { - pCTX->R13 = reinterpret_cast(pNewAddress); - } - if (pCTX->R14 == reinterpret_cast(pAddress)) { - pCTX->R14 = reinterpret_cast(pNewAddress); - } - if (pCTX->R15 == reinterpret_cast(pAddress)) { - pCTX->R15 = reinterpret_cast(pNewAddress); - } + if (pCTX->Rdi == reinterpret_cast(pAddress)) { + pCTX->Rdi = reinterpret_cast(pNewAddress); + } +#elif _M_IX86 + if (pCTX->Edi == reinterpret_cast(pAddress)) { + pCTX->Edi = reinterpret_cast(pNewAddress); + } #endif +#ifdef _M_X64 + if (pCTX->R8 == reinterpret_cast(pAddress)) { + pCTX->R8 = reinterpret_cast(pNewAddress); + } + if (pCTX->R9 == reinterpret_cast(pAddress)) { + pCTX->R9 = reinterpret_cast(pNewAddress); + } + if (pCTX->R10 == reinterpret_cast(pAddress)) { + pCTX->R10 = reinterpret_cast(pNewAddress); + } + if (pCTX->R11 == reinterpret_cast(pAddress)) { + pCTX->R11 = reinterpret_cast(pNewAddress); + } + if (pCTX->R12 == reinterpret_cast(pAddress)) { + pCTX->R12 = reinterpret_cast(pNewAddress); + } + if (pCTX->R13 == reinterpret_cast(pAddress)) { + pCTX->R13 = reinterpret_cast(pNewAddress); + } + if (pCTX->R14 == reinterpret_cast(pAddress)) { + pCTX->R14 = reinterpret_cast(pNewAddress); + } + if (pCTX->R15 == reinterpret_cast(pAddress)) { + pCTX->R15 = reinterpret_cast(pNewAddress); + } +#endif + } } static bool MemoryHookCallBack(const EXCEPTION_RECORD& Exception, const PCONTEXT pCTX) { diff --git a/main.cpp b/main.cpp index 9440de4..e79510d 100644 --- a/main.cpp +++ b/main.cpp @@ -1728,27 +1728,50 @@ TEST_SUITE("Detours::Hook") { CHECK(Region.GetRegionAddress() != nullptr); void* pAddress = Region.Alloc(1); CHECK(pAddress != nullptr); - *reinterpret_cast(pAddress) = 0; + reinterpret_cast(pAddress)[0] = 0; + reinterpret_cast(pAddress)[1] = 0; + reinterpret_cast(pAddress)[2] = 0; + + + Detours::Memory::Protection RegionProtection(pAddress, 3, false); + CHECK(RegionProtection.Change(PAGE_READWRITE) == true); + reinterpret_cast(pAddress)[0] = 0xB0; + reinterpret_cast(pAddress)[1] = 0x01; + reinterpret_cast(pAddress)[2] = 0xC3; + CHECK(RegionProtection.Change(PAGE_EXECUTE_READWRITE) == true); + + using fnType = bool(__cdecl*)(); + CHECK(reinterpret_cast(pAddress)() == true); + CHECK(Detours::Hook::HookMemory(MemoryHook, Region.GetRegionAddress(), Region.GetRegionCapacity()) == true); - *reinterpret_cast(pAddress) = 1; + reinterpret_cast(pAddress)[0] = 0xB0; + reinterpret_cast(pAddress)[1] = 0x01; + reinterpret_cast(pAddress)[2] = 0xC3; + CHECK(reinterpret_cast(pAddress)() == true); + CHECK(reinterpret_cast(pAddress)[0] == 0xB0); + CHECK(reinterpret_cast(pAddress)[1] == 0x01); + CHECK(reinterpret_cast(pAddress)[2] == 0xC3); CHECK(Detours::Hook::UnHookMemory(MemoryHook) == true); + CHECK(reinterpret_cast(pAddress)[0] == 0xB0); + CHECK(reinterpret_cast(pAddress)[1] == 0x01); + CHECK(reinterpret_cast(pAddress)[2] == 0xC3); } TEST_CASE("MemoryHook [benchmark]" * doctest::skip(false)) { - Detours::Memory::Region Region(nullptr, static_cast(0x1000)); + Detours::Memory::Region Region(nullptr, static_cast(0x4000000)); CHECK(Region.GetRegionAddress() != nullptr); void* pAddress = Region.Alloc(1); CHECK(pAddress != nullptr); srand(time(nullptr) & 0xffffffff); ULONG unBegin = Detours::KUserSharedData.SystemTime.LowPart; for (size_t i = 0; i < 1'000'000; ++i) { - reinterpret_cast(pAddress)[rand() % 0x1000] = 1; + reinterpret_cast(pAddress)[rand() % (0x4000000 - 1)] = 1; } MESSAGE("Benckmark with 1 000 000 iterations (without hook): ", (Detours::KUserSharedData.SystemTime.LowPart - unBegin) / 10000, " ms"); CHECK(Detours::Hook::HookMemory(MemoryHook, Region.GetRegionAddress(), Region.GetRegionCapacity()) == true); unBegin = Detours::KUserSharedData.SystemTime.LowPart; for (size_t i = 0; i < 1'000'000; ++i) { - reinterpret_cast(pAddress)[rand() % 0x1000] = 2; + reinterpret_cast(pAddress)[rand() % (0x4000000 - 1)] = 2; } MESSAGE("Benckmark with 1 000 000 iterations (with hook): ", (Detours::KUserSharedData.SystemTime.LowPart - unBegin) / 10000, " ms"); CHECK(Detours::Hook::UnHookMemory(MemoryHook) == true);