From 5d9699efe3f0d329c429b7487a112a11c69375ad Mon Sep 17 00:00:00 2001 From: IcePixelx <41352111+PixieCore@users.noreply.github.com> Date: Fri, 6 Aug 2021 16:30:57 +0200 Subject: [PATCH] Added minhook compile project. --- apex.sln | 20 +- external/minhook/lib/libMinHook.x64.lib | Bin 423458 -> 0 bytes external/minhook/libMinHook.vcxproj | 173 ++++ external/minhook/libMinHook.vcxproj.filters | 57 ++ external/minhook/src/buffer.c | 312 +++++++ external/minhook/src/buffer.h | 42 + external/minhook/src/hde/hde32.c | 324 +++++++ external/minhook/src/hde/hde32.h | 105 +++ external/minhook/src/hde/hde64.c | 333 +++++++ external/minhook/src/hde/hde64.h | 112 +++ external/minhook/src/hde/pstdint.h | 39 + external/minhook/src/hde/table32.h | 73 ++ external/minhook/src/hde/table64.h | 74 ++ external/minhook/src/hook.c | 906 ++++++++++++++++++++ external/minhook/src/trampoline.c | 320 +++++++ external/minhook/src/trampoline.h | 105 +++ r5dedicated/r5dedicated.vcxproj | 24 +- r5dev/r5dev.def | 2 +- r5dev/r5dev.vcxproj | 30 +- r5launcher/r5launcher.vcxproj | 9 +- 20 files changed, 3033 insertions(+), 27 deletions(-) delete mode 100644 external/minhook/lib/libMinHook.x64.lib create mode 100644 external/minhook/libMinHook.vcxproj create mode 100644 external/minhook/libMinHook.vcxproj.filters create mode 100644 external/minhook/src/buffer.c create mode 100644 external/minhook/src/buffer.h create mode 100644 external/minhook/src/hde/hde32.c create mode 100644 external/minhook/src/hde/hde32.h create mode 100644 external/minhook/src/hde/hde64.c create mode 100644 external/minhook/src/hde/hde64.h create mode 100644 external/minhook/src/hde/pstdint.h create mode 100644 external/minhook/src/hde/table32.h create mode 100644 external/minhook/src/hde/table64.h create mode 100644 external/minhook/src/hook.c create mode 100644 external/minhook/src/trampoline.c create mode 100644 external/minhook/src/trampoline.h diff --git a/apex.sln b/apex.sln index ae23e289..d2240193 100644 --- a/apex.sln +++ b/apex.sln @@ -9,38 +9,30 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "r5dev", "r5dev\r5dev.vcxpro EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "r5dedicated", "r5dedicated\r5dedicated.vcxproj", "{71988D92-343C-49AB-B52B-0AE0E83B0401}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Minhook", "external\minhook\libMinHook.vcxproj", "{F142A341-5EE0-442D-A15F-98AE9B48DBAE}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 Release|x64 = Release|x64 - Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {18F8C75E-3844-4AA6-AB93-980A08253519}.Debug|x64.ActiveCfg = Debug|x64 {18F8C75E-3844-4AA6-AB93-980A08253519}.Debug|x64.Build.0 = Debug|x64 - {18F8C75E-3844-4AA6-AB93-980A08253519}.Debug|x86.ActiveCfg = Debug|Win32 - {18F8C75E-3844-4AA6-AB93-980A08253519}.Debug|x86.Build.0 = Debug|Win32 {18F8C75E-3844-4AA6-AB93-980A08253519}.Release|x64.ActiveCfg = Release|x64 {18F8C75E-3844-4AA6-AB93-980A08253519}.Release|x64.Build.0 = Release|x64 - {18F8C75E-3844-4AA6-AB93-980A08253519}.Release|x86.ActiveCfg = Release|Win32 - {18F8C75E-3844-4AA6-AB93-980A08253519}.Release|x86.Build.0 = Release|Win32 {28CC6B4F-7A95-4933-ADA9-65E38D48516D}.Debug|x64.ActiveCfg = Debug|x64 {28CC6B4F-7A95-4933-ADA9-65E38D48516D}.Debug|x64.Build.0 = Debug|x64 - {28CC6B4F-7A95-4933-ADA9-65E38D48516D}.Debug|x86.ActiveCfg = Debug|Win32 - {28CC6B4F-7A95-4933-ADA9-65E38D48516D}.Debug|x86.Build.0 = Debug|Win32 {28CC6B4F-7A95-4933-ADA9-65E38D48516D}.Release|x64.ActiveCfg = Release|x64 {28CC6B4F-7A95-4933-ADA9-65E38D48516D}.Release|x64.Build.0 = Release|x64 - {28CC6B4F-7A95-4933-ADA9-65E38D48516D}.Release|x86.ActiveCfg = Release|Win32 - {28CC6B4F-7A95-4933-ADA9-65E38D48516D}.Release|x86.Build.0 = Release|Win32 {71988D92-343C-49AB-B52B-0AE0E83B0401}.Debug|x64.ActiveCfg = Debug|x64 {71988D92-343C-49AB-B52B-0AE0E83B0401}.Debug|x64.Build.0 = Debug|x64 - {71988D92-343C-49AB-B52B-0AE0E83B0401}.Debug|x86.ActiveCfg = Debug|Win32 - {71988D92-343C-49AB-B52B-0AE0E83B0401}.Debug|x86.Build.0 = Debug|Win32 {71988D92-343C-49AB-B52B-0AE0E83B0401}.Release|x64.ActiveCfg = Release|x64 {71988D92-343C-49AB-B52B-0AE0E83B0401}.Release|x64.Build.0 = Release|x64 - {71988D92-343C-49AB-B52B-0AE0E83B0401}.Release|x86.ActiveCfg = Release|Win32 - {71988D92-343C-49AB-B52B-0AE0E83B0401}.Release|x86.Build.0 = Release|Win32 + {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Debug|x64.ActiveCfg = Debug|x64 + {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Debug|x64.Build.0 = Debug|x64 + {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Release|x64.ActiveCfg = Release|x64 + {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/external/minhook/lib/libMinHook.x64.lib b/external/minhook/lib/libMinHook.x64.lib deleted file mode 100644 index ab34a9ddc8f7151984a89609f66c40ba7b5ed22b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 423458 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�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 C(0h;o diff --git a/external/minhook/libMinHook.vcxproj b/external/minhook/libMinHook.vcxproj new file mode 100644 index 00000000..626f1374 --- /dev/null +++ b/external/minhook/libMinHook.vcxproj @@ -0,0 +1,173 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + + {F142A341-5EE0-442D-A15F-98AE9B48DBAE} + libMinHook + Win32Proj + 10.0 + Minhook + + + + StaticLibrary + Unicode + true + v142 + + + StaticLibrary + Unicode + v142 + + + StaticLibrary + Unicode + true + v142 + + + StaticLibrary + Unicode + v142 + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(SolutionDir)lib\$(Configuration)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + $(ProjectDir)lib\$(Configuration) + $(SolutionDir)build\$(ProjectName)\$(Configuration) + $(SolutionDir)lib\$(Configuration)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + $(ProjectDir)lib\$(Configuration) + $(SolutionDir)build\$(ProjectName)\$(Configuration) + $(ProjectName).x86 + $(ProjectName).x86 + $(ProjectName).x64 + $(ProjectName).x64 + + + + Disabled + %(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;STRICT;%(PreprocessorDefinitions) + false + EnableFastChecks + MultiThreadedDebug + Level3 + None + NoExtensions + + + + + + X64 + + + Disabled + %(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;STRICT;%(PreprocessorDefinitions) + false + EnableFastChecks + MultiThreadedDebugDLL + Level3 + None + NotSet + stdcpp17 + stdc17 + + + + + + MinSpace + true + %(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;STRICT;%(PreprocessorDefinitions) + false + MultiThreaded + true + Level3 + None + AnySuitable + true + NoExtensions + + + + + + X64 + + + MinSpace + true + %(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;STRICT;%(PreprocessorDefinitions) + false + MultiThreaded + true + Level3 + None + true + AnySuitable + stdcpp17 + stdc17 + + + + + + + \ No newline at end of file diff --git a/external/minhook/libMinHook.vcxproj.filters b/external/minhook/libMinHook.vcxproj.filters new file mode 100644 index 00000000..76694c63 --- /dev/null +++ b/external/minhook/libMinHook.vcxproj.filters @@ -0,0 +1,57 @@ + + + + + src + + + src + + + src + + + src\hde + + + src\hde + + + + + src + + + src + + + src\hde + + + src\hde + + + src\hde + + + src\hde + + + src\hde + + + include + + + + + {62eb648f-1c53-4909-8805-77a8cdc6f408} + + + {161a8d4e-b988-418b-a31e-d089ae0e9e22} + + + {dd59bf86-2fa2-4576-bb49-7b65617b67a5} + + + \ No newline at end of file diff --git a/external/minhook/src/buffer.c b/external/minhook/src/buffer.c new file mode 100644 index 00000000..55412b0f --- /dev/null +++ b/external/minhook/src/buffer.c @@ -0,0 +1,312 @@ +/* + * MinHook - The Minimalistic API Hooking Library for x64/x86 + * Copyright (C) 2009-2017 Tsuda Kageyu. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "buffer.h" + +// Size of each memory block. (= page size of VirtualAlloc) +#define MEMORY_BLOCK_SIZE 0x1000 + +// Max range for seeking a memory block. (= 1024MB) +#define MAX_MEMORY_RANGE 0x40000000 + +// Memory protection flags to check the executable address. +#define PAGE_EXECUTE_FLAGS \ + (PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY) + +// Memory slot. +typedef struct _MEMORY_SLOT +{ + union + { + struct _MEMORY_SLOT *pNext; + UINT8 buffer[MEMORY_SLOT_SIZE]; + }; +} MEMORY_SLOT, *PMEMORY_SLOT; + +// Memory block info. Placed at the head of each block. +typedef struct _MEMORY_BLOCK +{ + struct _MEMORY_BLOCK *pNext; + PMEMORY_SLOT pFree; // First element of the free slot list. + UINT usedCount; +} MEMORY_BLOCK, *PMEMORY_BLOCK; + +//------------------------------------------------------------------------- +// Global Variables: +//------------------------------------------------------------------------- + +// First element of the memory block list. +PMEMORY_BLOCK g_pMemoryBlocks; + +//------------------------------------------------------------------------- +VOID InitializeBuffer(VOID) +{ + // Nothing to do for now. +} + +//------------------------------------------------------------------------- +VOID UninitializeBuffer(VOID) +{ + PMEMORY_BLOCK pBlock = g_pMemoryBlocks; + g_pMemoryBlocks = NULL; + + while (pBlock) + { + PMEMORY_BLOCK pNext = pBlock->pNext; + VirtualFree(pBlock, 0, MEM_RELEASE); + pBlock = pNext; + } +} + +//------------------------------------------------------------------------- +#if defined(_M_X64) || defined(__x86_64__) +static LPVOID FindPrevFreeRegion(LPVOID pAddress, LPVOID pMinAddr, DWORD dwAllocationGranularity) +{ + ULONG_PTR tryAddr = (ULONG_PTR)pAddress; + + // Round down to the allocation granularity. + tryAddr -= tryAddr % dwAllocationGranularity; + + // Start from the previous allocation granularity multiply. + tryAddr -= dwAllocationGranularity; + + while (tryAddr >= (ULONG_PTR)pMinAddr) + { + MEMORY_BASIC_INFORMATION mbi; + if (VirtualQuery((LPVOID)tryAddr, &mbi, sizeof(mbi)) == 0) + break; + + if (mbi.State == MEM_FREE) + return (LPVOID)tryAddr; + + if ((ULONG_PTR)mbi.AllocationBase < dwAllocationGranularity) + break; + + tryAddr = (ULONG_PTR)mbi.AllocationBase - dwAllocationGranularity; + } + + return NULL; +} +#endif + +//------------------------------------------------------------------------- +#if defined(_M_X64) || defined(__x86_64__) +static LPVOID FindNextFreeRegion(LPVOID pAddress, LPVOID pMaxAddr, DWORD dwAllocationGranularity) +{ + ULONG_PTR tryAddr = (ULONG_PTR)pAddress; + + // Round down to the allocation granularity. + tryAddr -= tryAddr % dwAllocationGranularity; + + // Start from the next allocation granularity multiply. + tryAddr += dwAllocationGranularity; + + while (tryAddr <= (ULONG_PTR)pMaxAddr) + { + MEMORY_BASIC_INFORMATION mbi; + if (VirtualQuery((LPVOID)tryAddr, &mbi, sizeof(mbi)) == 0) + break; + + if (mbi.State == MEM_FREE) + return (LPVOID)tryAddr; + + tryAddr = (ULONG_PTR)mbi.BaseAddress + mbi.RegionSize; + + // Round up to the next allocation granularity. + tryAddr += dwAllocationGranularity - 1; + tryAddr -= tryAddr % dwAllocationGranularity; + } + + return NULL; +} +#endif + +//------------------------------------------------------------------------- +static PMEMORY_BLOCK GetMemoryBlock(LPVOID pOrigin) +{ + PMEMORY_BLOCK pBlock; +#if defined(_M_X64) || defined(__x86_64__) + ULONG_PTR minAddr; + ULONG_PTR maxAddr; + + SYSTEM_INFO si; + GetSystemInfo(&si); + minAddr = (ULONG_PTR)si.lpMinimumApplicationAddress; + maxAddr = (ULONG_PTR)si.lpMaximumApplicationAddress; + + // pOrigin ± 512MB + if ((ULONG_PTR)pOrigin > MAX_MEMORY_RANGE && minAddr < (ULONG_PTR)pOrigin - MAX_MEMORY_RANGE) + minAddr = (ULONG_PTR)pOrigin - MAX_MEMORY_RANGE; + + if (maxAddr > (ULONG_PTR)pOrigin + MAX_MEMORY_RANGE) + maxAddr = (ULONG_PTR)pOrigin + MAX_MEMORY_RANGE; + + // Make room for MEMORY_BLOCK_SIZE bytes. + maxAddr -= MEMORY_BLOCK_SIZE - 1; +#endif + + // Look the registered blocks for a reachable one. + for (pBlock = g_pMemoryBlocks; pBlock != NULL; pBlock = pBlock->pNext) + { +#if defined(_M_X64) || defined(__x86_64__) + // Ignore the blocks too far. + if ((ULONG_PTR)pBlock < minAddr || (ULONG_PTR)pBlock >= maxAddr) + continue; +#endif + // The block has at least one unused slot. + if (pBlock->pFree != NULL) + return pBlock; + } + +#if defined(_M_X64) || defined(__x86_64__) + // Alloc a new block above if not found. + { + LPVOID pAlloc = pOrigin; + while ((ULONG_PTR)pAlloc >= minAddr) + { + pAlloc = FindPrevFreeRegion(pAlloc, (LPVOID)minAddr, si.dwAllocationGranularity); + if (pAlloc == NULL) + break; + + pBlock = (PMEMORY_BLOCK)VirtualAlloc( + pAlloc, MEMORY_BLOCK_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); + if (pBlock != NULL) + break; + } + } + + // Alloc a new block below if not found. + if (pBlock == NULL) + { + LPVOID pAlloc = pOrigin; + while ((ULONG_PTR)pAlloc <= maxAddr) + { + pAlloc = FindNextFreeRegion(pAlloc, (LPVOID)maxAddr, si.dwAllocationGranularity); + if (pAlloc == NULL) + break; + + pBlock = (PMEMORY_BLOCK)VirtualAlloc( + pAlloc, MEMORY_BLOCK_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); + if (pBlock != NULL) + break; + } + } +#else + // In x86 mode, a memory block can be placed anywhere. + pBlock = (PMEMORY_BLOCK)VirtualAlloc( + NULL, MEMORY_BLOCK_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); +#endif + + if (pBlock != NULL) + { + // Build a linked list of all the slots. + PMEMORY_SLOT pSlot = (PMEMORY_SLOT)pBlock + 1; + pBlock->pFree = NULL; + pBlock->usedCount = 0; + do + { + pSlot->pNext = pBlock->pFree; + pBlock->pFree = pSlot; + pSlot++; + } while ((ULONG_PTR)pSlot - (ULONG_PTR)pBlock <= MEMORY_BLOCK_SIZE - MEMORY_SLOT_SIZE); + + pBlock->pNext = g_pMemoryBlocks; + g_pMemoryBlocks = pBlock; + } + + return pBlock; +} + +//------------------------------------------------------------------------- +LPVOID AllocateBuffer(LPVOID pOrigin) +{ + PMEMORY_SLOT pSlot; + PMEMORY_BLOCK pBlock = GetMemoryBlock(pOrigin); + if (pBlock == NULL) + return NULL; + + // Remove an unused slot from the list. + pSlot = pBlock->pFree; + pBlock->pFree = pSlot->pNext; + pBlock->usedCount++; +#ifdef _DEBUG + // Fill the slot with INT3 for debugging. + memset(pSlot, 0xCC, sizeof(MEMORY_SLOT)); +#endif + return pSlot; +} + +//------------------------------------------------------------------------- +VOID FreeBuffer(LPVOID pBuffer) +{ + PMEMORY_BLOCK pBlock = g_pMemoryBlocks; + PMEMORY_BLOCK pPrev = NULL; + ULONG_PTR pTargetBlock = ((ULONG_PTR)pBuffer / MEMORY_BLOCK_SIZE) * MEMORY_BLOCK_SIZE; + + while (pBlock != NULL) + { + if ((ULONG_PTR)pBlock == pTargetBlock) + { + PMEMORY_SLOT pSlot = (PMEMORY_SLOT)pBuffer; +#ifdef _DEBUG + // Clear the released slot for debugging. + memset(pSlot, 0x00, sizeof(MEMORY_SLOT)); +#endif + // Restore the released slot to the list. + pSlot->pNext = pBlock->pFree; + pBlock->pFree = pSlot; + pBlock->usedCount--; + + // Free if unused. + if (pBlock->usedCount == 0) + { + if (pPrev) + pPrev->pNext = pBlock->pNext; + else + g_pMemoryBlocks = pBlock->pNext; + + VirtualFree(pBlock, 0, MEM_RELEASE); + } + + break; + } + + pPrev = pBlock; + pBlock = pBlock->pNext; + } +} + +//------------------------------------------------------------------------- +BOOL IsExecutableAddress(LPVOID pAddress) +{ + MEMORY_BASIC_INFORMATION mi; + VirtualQuery(pAddress, &mi, sizeof(mi)); + + return (mi.State == MEM_COMMIT && (mi.Protect & PAGE_EXECUTE_FLAGS)); +} diff --git a/external/minhook/src/buffer.h b/external/minhook/src/buffer.h new file mode 100644 index 00000000..204d551b --- /dev/null +++ b/external/minhook/src/buffer.h @@ -0,0 +1,42 @@ +/* + * MinHook - The Minimalistic API Hooking Library for x64/x86 + * Copyright (C) 2009-2017 Tsuda Kageyu. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +// Size of each memory slot. +#if defined(_M_X64) || defined(__x86_64__) + #define MEMORY_SLOT_SIZE 64 +#else + #define MEMORY_SLOT_SIZE 32 +#endif + +VOID InitializeBuffer(VOID); +VOID UninitializeBuffer(VOID); +LPVOID AllocateBuffer(LPVOID pOrigin); +VOID FreeBuffer(LPVOID pBuffer); +BOOL IsExecutableAddress(LPVOID pAddress); diff --git a/external/minhook/src/hde/hde32.c b/external/minhook/src/hde/hde32.c new file mode 100644 index 00000000..eb6af9b8 --- /dev/null +++ b/external/minhook/src/hde/hde32.c @@ -0,0 +1,324 @@ +/* + * Hacker Disassembler Engine 32 C + * Copyright (c) 2008-2009, Vyacheslav Patkov. + * All rights reserved. + * + */ + +#if defined(_M_IX86) || defined(__i386__) + +#include +#include "hde32.h" +#include "table32.h" + +unsigned int hde32_disasm(const void *code, hde32s *hs) +{ + uint8_t x, c, *p = (uint8_t *)code, cflags, opcode, pref = 0; + uint8_t *ht = hde32_table, m_mod, m_reg, m_rm, disp_size = 0; + + memset(hs, 0, sizeof(hde32s)); + + for (x = 16; x; x--) + switch (c = *p++) { + case 0xf3: + hs->p_rep = c; + pref |= PRE_F3; + break; + case 0xf2: + hs->p_rep = c; + pref |= PRE_F2; + break; + case 0xf0: + hs->p_lock = c; + pref |= PRE_LOCK; + break; + case 0x26: case 0x2e: case 0x36: + case 0x3e: case 0x64: case 0x65: + hs->p_seg = c; + pref |= PRE_SEG; + break; + case 0x66: + hs->p_66 = c; + pref |= PRE_66; + break; + case 0x67: + hs->p_67 = c; + pref |= PRE_67; + break; + default: + goto pref_done; + } + pref_done: + + hs->flags = (uint32_t)pref << 23; + + if (!pref) + pref |= PRE_NONE; + + if ((hs->opcode = c) == 0x0f) { + hs->opcode2 = c = *p++; + ht += DELTA_OPCODES; + } else if (c >= 0xa0 && c <= 0xa3) { + if (pref & PRE_67) + pref |= PRE_66; + else + pref &= ~PRE_66; + } + + opcode = c; + cflags = ht[ht[opcode / 4] + (opcode % 4)]; + + if (cflags == C_ERROR) { + hs->flags |= F_ERROR | F_ERROR_OPCODE; + cflags = 0; + if ((opcode & -3) == 0x24) + cflags++; + } + + x = 0; + if (cflags & C_GROUP) { + uint16_t t; + t = *(uint16_t *)(ht + (cflags & 0x7f)); + cflags = (uint8_t)t; + x = (uint8_t)(t >> 8); + } + + if (hs->opcode2) { + ht = hde32_table + DELTA_PREFIXES; + if (ht[ht[opcode / 4] + (opcode % 4)] & pref) + hs->flags |= F_ERROR | F_ERROR_OPCODE; + } + + if (cflags & C_MODRM) { + hs->flags |= F_MODRM; + hs->modrm = c = *p++; + hs->modrm_mod = m_mod = c >> 6; + hs->modrm_rm = m_rm = c & 7; + hs->modrm_reg = m_reg = (c & 0x3f) >> 3; + + if (x && ((x << m_reg) & 0x80)) + hs->flags |= F_ERROR | F_ERROR_OPCODE; + + if (!hs->opcode2 && opcode >= 0xd9 && opcode <= 0xdf) { + uint8_t t = opcode - 0xd9; + if (m_mod == 3) { + ht = hde32_table + DELTA_FPU_MODRM + t*8; + t = ht[m_reg] << m_rm; + } else { + ht = hde32_table + DELTA_FPU_REG; + t = ht[t] << m_reg; + } + if (t & 0x80) + hs->flags |= F_ERROR | F_ERROR_OPCODE; + } + + if (pref & PRE_LOCK) { + if (m_mod == 3) { + hs->flags |= F_ERROR | F_ERROR_LOCK; + } else { + uint8_t *table_end, op = opcode; + if (hs->opcode2) { + ht = hde32_table + DELTA_OP2_LOCK_OK; + table_end = ht + DELTA_OP_ONLY_MEM - DELTA_OP2_LOCK_OK; + } else { + ht = hde32_table + DELTA_OP_LOCK_OK; + table_end = ht + DELTA_OP2_LOCK_OK - DELTA_OP_LOCK_OK; + op &= -2; + } + for (; ht != table_end; ht++) + if (*ht++ == op) { + if (!((*ht << m_reg) & 0x80)) + goto no_lock_error; + else + break; + } + hs->flags |= F_ERROR | F_ERROR_LOCK; + no_lock_error: + ; + } + } + + if (hs->opcode2) { + switch (opcode) { + case 0x20: case 0x22: + m_mod = 3; + if (m_reg > 4 || m_reg == 1) + goto error_operand; + else + goto no_error_operand; + case 0x21: case 0x23: + m_mod = 3; + if (m_reg == 4 || m_reg == 5) + goto error_operand; + else + goto no_error_operand; + } + } else { + switch (opcode) { + case 0x8c: + if (m_reg > 5) + goto error_operand; + else + goto no_error_operand; + case 0x8e: + if (m_reg == 1 || m_reg > 5) + goto error_operand; + else + goto no_error_operand; + } + } + + if (m_mod == 3) { + uint8_t *table_end; + if (hs->opcode2) { + ht = hde32_table + DELTA_OP2_ONLY_MEM; + table_end = ht + sizeof(hde32_table) - DELTA_OP2_ONLY_MEM; + } else { + ht = hde32_table + DELTA_OP_ONLY_MEM; + table_end = ht + DELTA_OP2_ONLY_MEM - DELTA_OP_ONLY_MEM; + } + for (; ht != table_end; ht += 2) + if (*ht++ == opcode) { + if ((*ht++ & pref) && !((*ht << m_reg) & 0x80)) + goto error_operand; + else + break; + } + goto no_error_operand; + } else if (hs->opcode2) { + switch (opcode) { + case 0x50: case 0xd7: case 0xf7: + if (pref & (PRE_NONE | PRE_66)) + goto error_operand; + break; + case 0xd6: + if (pref & (PRE_F2 | PRE_F3)) + goto error_operand; + break; + case 0xc5: + goto error_operand; + } + goto no_error_operand; + } else + goto no_error_operand; + + error_operand: + hs->flags |= F_ERROR | F_ERROR_OPERAND; + no_error_operand: + + c = *p++; + if (m_reg <= 1) { + if (opcode == 0xf6) + cflags |= C_IMM8; + else if (opcode == 0xf7) + cflags |= C_IMM_P66; + } + + switch (m_mod) { + case 0: + if (pref & PRE_67) { + if (m_rm == 6) + disp_size = 2; + } else + if (m_rm == 5) + disp_size = 4; + break; + case 1: + disp_size = 1; + break; + case 2: + disp_size = 2; + if (!(pref & PRE_67)) + disp_size <<= 1; + break; + } + + if (m_mod != 3 && m_rm == 4 && !(pref & PRE_67)) { + hs->flags |= F_SIB; + p++; + hs->sib = c; + hs->sib_scale = c >> 6; + hs->sib_index = (c & 0x3f) >> 3; + if ((hs->sib_base = c & 7) == 5 && !(m_mod & 1)) + disp_size = 4; + } + + p--; + switch (disp_size) { + case 1: + hs->flags |= F_DISP8; + hs->disp.disp8 = *p; + break; + case 2: + hs->flags |= F_DISP16; + hs->disp.disp16 = *(uint16_t *)p; + break; + case 4: + hs->flags |= F_DISP32; + hs->disp.disp32 = *(uint32_t *)p; + break; + } + p += disp_size; + } else if (pref & PRE_LOCK) + hs->flags |= F_ERROR | F_ERROR_LOCK; + + if (cflags & C_IMM_P66) { + if (cflags & C_REL32) { + if (pref & PRE_66) { + hs->flags |= F_IMM16 | F_RELATIVE; + hs->imm.imm16 = *(uint16_t *)p; + p += 2; + goto disasm_done; + } + goto rel32_ok; + } + if (pref & PRE_66) { + hs->flags |= F_IMM16; + hs->imm.imm16 = *(uint16_t *)p; + p += 2; + } else { + hs->flags |= F_IMM32; + hs->imm.imm32 = *(uint32_t *)p; + p += 4; + } + } + + if (cflags & C_IMM16) { + if (hs->flags & F_IMM32) { + hs->flags |= F_IMM16; + hs->disp.disp16 = *(uint16_t *)p; + } else if (hs->flags & F_IMM16) { + hs->flags |= F_2IMM16; + hs->disp.disp16 = *(uint16_t *)p; + } else { + hs->flags |= F_IMM16; + hs->imm.imm16 = *(uint16_t *)p; + } + p += 2; + } + if (cflags & C_IMM8) { + hs->flags |= F_IMM8; + hs->imm.imm8 = *p++; + } + + if (cflags & C_REL32) { + rel32_ok: + hs->flags |= F_IMM32 | F_RELATIVE; + hs->imm.imm32 = *(uint32_t *)p; + p += 4; + } else if (cflags & C_REL8) { + hs->flags |= F_IMM8 | F_RELATIVE; + hs->imm.imm8 = *p++; + } + + disasm_done: + + if ((hs->len = (uint8_t)(p-(uint8_t *)code)) > 15) { + hs->flags |= F_ERROR | F_ERROR_LENGTH; + hs->len = 15; + } + + return (unsigned int)hs->len; +} + +#endif // defined(_M_IX86) || defined(__i386__) diff --git a/external/minhook/src/hde/hde32.h b/external/minhook/src/hde/hde32.h new file mode 100644 index 00000000..1112450d --- /dev/null +++ b/external/minhook/src/hde/hde32.h @@ -0,0 +1,105 @@ +/* + * Hacker Disassembler Engine 32 + * Copyright (c) 2006-2009, Vyacheslav Patkov. + * All rights reserved. + * + * hde32.h: C/C++ header file + * + */ + +#ifndef _HDE32_H_ +#define _HDE32_H_ + +/* stdint.h - C99 standard header + * http://en.wikipedia.org/wiki/stdint.h + * + * if your compiler doesn't contain "stdint.h" header (for + * example, Microsoft Visual C++), you can download file: + * http://www.azillionmonkeys.com/qed/pstdint.h + * and change next line to: + * #include "pstdint.h" + */ +#include "pstdint.h" + +#define F_MODRM 0x00000001 +#define F_SIB 0x00000002 +#define F_IMM8 0x00000004 +#define F_IMM16 0x00000008 +#define F_IMM32 0x00000010 +#define F_DISP8 0x00000020 +#define F_DISP16 0x00000040 +#define F_DISP32 0x00000080 +#define F_RELATIVE 0x00000100 +#define F_2IMM16 0x00000800 +#define F_ERROR 0x00001000 +#define F_ERROR_OPCODE 0x00002000 +#define F_ERROR_LENGTH 0x00004000 +#define F_ERROR_LOCK 0x00008000 +#define F_ERROR_OPERAND 0x00010000 +#define F_PREFIX_REPNZ 0x01000000 +#define F_PREFIX_REPX 0x02000000 +#define F_PREFIX_REP 0x03000000 +#define F_PREFIX_66 0x04000000 +#define F_PREFIX_67 0x08000000 +#define F_PREFIX_LOCK 0x10000000 +#define F_PREFIX_SEG 0x20000000 +#define F_PREFIX_ANY 0x3f000000 + +#define PREFIX_SEGMENT_CS 0x2e +#define PREFIX_SEGMENT_SS 0x36 +#define PREFIX_SEGMENT_DS 0x3e +#define PREFIX_SEGMENT_ES 0x26 +#define PREFIX_SEGMENT_FS 0x64 +#define PREFIX_SEGMENT_GS 0x65 +#define PREFIX_LOCK 0xf0 +#define PREFIX_REPNZ 0xf2 +#define PREFIX_REPX 0xf3 +#define PREFIX_OPERAND_SIZE 0x66 +#define PREFIX_ADDRESS_SIZE 0x67 + +#pragma pack(push,1) + +typedef struct { + uint8_t len; + uint8_t p_rep; + uint8_t p_lock; + uint8_t p_seg; + uint8_t p_66; + uint8_t p_67; + uint8_t opcode; + uint8_t opcode2; + uint8_t modrm; + uint8_t modrm_mod; + uint8_t modrm_reg; + uint8_t modrm_rm; + uint8_t sib; + uint8_t sib_scale; + uint8_t sib_index; + uint8_t sib_base; + union { + uint8_t imm8; + uint16_t imm16; + uint32_t imm32; + } imm; + union { + uint8_t disp8; + uint16_t disp16; + uint32_t disp32; + } disp; + uint32_t flags; +} hde32s; + +#pragma pack(pop) + +#ifdef __cplusplus +extern "C" { +#endif + +/* __cdecl */ +unsigned int hde32_disasm(const void *code, hde32s *hs); + +#ifdef __cplusplus +} +#endif + +#endif /* _HDE32_H_ */ diff --git a/external/minhook/src/hde/hde64.c b/external/minhook/src/hde/hde64.c new file mode 100644 index 00000000..55a702e7 --- /dev/null +++ b/external/minhook/src/hde/hde64.c @@ -0,0 +1,333 @@ +/* + * Hacker Disassembler Engine 64 C + * Copyright (c) 2008-2009, Vyacheslav Patkov. + * All rights reserved. + * + */ + +#if defined(_M_X64) || defined(__x86_64__) + +#include +#include "hde64.h" +#include "table64.h" + +unsigned int hde64_disasm(const void *code, hde64s *hs) +{ + uint8_t x, c, *p = (uint8_t *)code, cflags, opcode, pref = 0; + uint8_t *ht = hde64_table, m_mod, m_reg, m_rm, disp_size = 0; + uint8_t op64 = 0; + + memset(hs, 0, sizeof(hde64s)); + + for (x = 16; x; x--) + switch (c = *p++) { + case 0xf3: + hs->p_rep = c; + pref |= PRE_F3; + break; + case 0xf2: + hs->p_rep = c; + pref |= PRE_F2; + break; + case 0xf0: + hs->p_lock = c; + pref |= PRE_LOCK; + break; + case 0x26: case 0x2e: case 0x36: + case 0x3e: case 0x64: case 0x65: + hs->p_seg = c; + pref |= PRE_SEG; + break; + case 0x66: + hs->p_66 = c; + pref |= PRE_66; + break; + case 0x67: + hs->p_67 = c; + pref |= PRE_67; + break; + default: + goto pref_done; + } + pref_done: + + hs->flags = (uint32_t)pref << 23; + + if (!pref) + pref |= PRE_NONE; + + if ((c & 0xf0) == 0x40) { + hs->flags |= F_PREFIX_REX; + if ((hs->rex_w = (c & 0xf) >> 3) && (*p & 0xf8) == 0xb8) + op64++; + hs->rex_r = (c & 7) >> 2; + hs->rex_x = (c & 3) >> 1; + hs->rex_b = c & 1; + if (((c = *p++) & 0xf0) == 0x40) { + opcode = c; + goto error_opcode; + } + } + + if ((hs->opcode = c) == 0x0f) { + hs->opcode2 = c = *p++; + ht += DELTA_OPCODES; + } else if (c >= 0xa0 && c <= 0xa3) { + op64++; + if (pref & PRE_67) + pref |= PRE_66; + else + pref &= ~PRE_66; + } + + opcode = c; + cflags = ht[ht[opcode / 4] + (opcode % 4)]; + + if (cflags == C_ERROR) { + error_opcode: + hs->flags |= F_ERROR | F_ERROR_OPCODE; + cflags = 0; + if ((opcode & -3) == 0x24) + cflags++; + } + + x = 0; + if (cflags & C_GROUP) { + uint16_t t; + t = *(uint16_t *)(ht + (cflags & 0x7f)); + cflags = (uint8_t)t; + x = (uint8_t)(t >> 8); + } + + if (hs->opcode2) { + ht = hde64_table + DELTA_PREFIXES; + if (ht[ht[opcode / 4] + (opcode % 4)] & pref) + hs->flags |= F_ERROR | F_ERROR_OPCODE; + } + + if (cflags & C_MODRM) { + hs->flags |= F_MODRM; + hs->modrm = c = *p++; + hs->modrm_mod = m_mod = c >> 6; + hs->modrm_rm = m_rm = c & 7; + hs->modrm_reg = m_reg = (c & 0x3f) >> 3; + + if (x && ((x << m_reg) & 0x80)) + hs->flags |= F_ERROR | F_ERROR_OPCODE; + + if (!hs->opcode2 && opcode >= 0xd9 && opcode <= 0xdf) { + uint8_t t = opcode - 0xd9; + if (m_mod == 3) { + ht = hde64_table + DELTA_FPU_MODRM + t*8; + t = ht[m_reg] << m_rm; + } else { + ht = hde64_table + DELTA_FPU_REG; + t = ht[t] << m_reg; + } + if (t & 0x80) + hs->flags |= F_ERROR | F_ERROR_OPCODE; + } + + if (pref & PRE_LOCK) { + if (m_mod == 3) { + hs->flags |= F_ERROR | F_ERROR_LOCK; + } else { + uint8_t *table_end, op = opcode; + if (hs->opcode2) { + ht = hde64_table + DELTA_OP2_LOCK_OK; + table_end = ht + DELTA_OP_ONLY_MEM - DELTA_OP2_LOCK_OK; + } else { + ht = hde64_table + DELTA_OP_LOCK_OK; + table_end = ht + DELTA_OP2_LOCK_OK - DELTA_OP_LOCK_OK; + op &= -2; + } + for (; ht != table_end; ht++) + if (*ht++ == op) { + if (!((*ht << m_reg) & 0x80)) + goto no_lock_error; + else + break; + } + hs->flags |= F_ERROR | F_ERROR_LOCK; + no_lock_error: + ; + } + } + + if (hs->opcode2) { + switch (opcode) { + case 0x20: case 0x22: + m_mod = 3; + if (m_reg > 4 || m_reg == 1) + goto error_operand; + else + goto no_error_operand; + case 0x21: case 0x23: + m_mod = 3; + if (m_reg == 4 || m_reg == 5) + goto error_operand; + else + goto no_error_operand; + } + } else { + switch (opcode) { + case 0x8c: + if (m_reg > 5) + goto error_operand; + else + goto no_error_operand; + case 0x8e: + if (m_reg == 1 || m_reg > 5) + goto error_operand; + else + goto no_error_operand; + } + } + + if (m_mod == 3) { + uint8_t *table_end; + if (hs->opcode2) { + ht = hde64_table + DELTA_OP2_ONLY_MEM; + table_end = ht + sizeof(hde64_table) - DELTA_OP2_ONLY_MEM; + } else { + ht = hde64_table + DELTA_OP_ONLY_MEM; + table_end = ht + DELTA_OP2_ONLY_MEM - DELTA_OP_ONLY_MEM; + } + for (; ht != table_end; ht += 2) + if (*ht++ == opcode) { + if (*ht++ & pref && !((*ht << m_reg) & 0x80)) + goto error_operand; + else + break; + } + goto no_error_operand; + } else if (hs->opcode2) { + switch (opcode) { + case 0x50: case 0xd7: case 0xf7: + if (pref & (PRE_NONE | PRE_66)) + goto error_operand; + break; + case 0xd6: + if (pref & (PRE_F2 | PRE_F3)) + goto error_operand; + break; + case 0xc5: + goto error_operand; + } + goto no_error_operand; + } else + goto no_error_operand; + + error_operand: + hs->flags |= F_ERROR | F_ERROR_OPERAND; + no_error_operand: + + c = *p++; + if (m_reg <= 1) { + if (opcode == 0xf6) + cflags |= C_IMM8; + else if (opcode == 0xf7) + cflags |= C_IMM_P66; + } + + switch (m_mod) { + case 0: + if (pref & PRE_67) { + if (m_rm == 6) + disp_size = 2; + } else + if (m_rm == 5) + disp_size = 4; + break; + case 1: + disp_size = 1; + break; + case 2: + disp_size = 2; + if (!(pref & PRE_67)) + disp_size <<= 1; + } + + if (m_mod != 3 && m_rm == 4) { + hs->flags |= F_SIB; + p++; + hs->sib = c; + hs->sib_scale = c >> 6; + hs->sib_index = (c & 0x3f) >> 3; + if ((hs->sib_base = c & 7) == 5 && !(m_mod & 1)) + disp_size = 4; + } + + p--; + switch (disp_size) { + case 1: + hs->flags |= F_DISP8; + hs->disp.disp8 = *p; + break; + case 2: + hs->flags |= F_DISP16; + hs->disp.disp16 = *(uint16_t *)p; + break; + case 4: + hs->flags |= F_DISP32; + hs->disp.disp32 = *(uint32_t *)p; + } + p += disp_size; + } else if (pref & PRE_LOCK) + hs->flags |= F_ERROR | F_ERROR_LOCK; + + if (cflags & C_IMM_P66) { + if (cflags & C_REL32) { + if (pref & PRE_66) { + hs->flags |= F_IMM16 | F_RELATIVE; + hs->imm.imm16 = *(uint16_t *)p; + p += 2; + goto disasm_done; + } + goto rel32_ok; + } + if (op64) { + hs->flags |= F_IMM64; + hs->imm.imm64 = *(uint64_t *)p; + p += 8; + } else if (!(pref & PRE_66)) { + hs->flags |= F_IMM32; + hs->imm.imm32 = *(uint32_t *)p; + p += 4; + } else + goto imm16_ok; + } + + + if (cflags & C_IMM16) { + imm16_ok: + hs->flags |= F_IMM16; + hs->imm.imm16 = *(uint16_t *)p; + p += 2; + } + if (cflags & C_IMM8) { + hs->flags |= F_IMM8; + hs->imm.imm8 = *p++; + } + + if (cflags & C_REL32) { + rel32_ok: + hs->flags |= F_IMM32 | F_RELATIVE; + hs->imm.imm32 = *(uint32_t *)p; + p += 4; + } else if (cflags & C_REL8) { + hs->flags |= F_IMM8 | F_RELATIVE; + hs->imm.imm8 = *p++; + } + + disasm_done: + + if ((hs->len = (uint8_t)(p-(uint8_t *)code)) > 15) { + hs->flags |= F_ERROR | F_ERROR_LENGTH; + hs->len = 15; + } + + return (unsigned int)hs->len; +} + +#endif // defined(_M_X64) || defined(__x86_64__) diff --git a/external/minhook/src/hde/hde64.h b/external/minhook/src/hde/hde64.h new file mode 100644 index 00000000..ecbf4df9 --- /dev/null +++ b/external/minhook/src/hde/hde64.h @@ -0,0 +1,112 @@ +/* + * Hacker Disassembler Engine 64 + * Copyright (c) 2008-2009, Vyacheslav Patkov. + * All rights reserved. + * + * hde64.h: C/C++ header file + * + */ + +#ifndef _HDE64_H_ +#define _HDE64_H_ + +/* stdint.h - C99 standard header + * http://en.wikipedia.org/wiki/stdint.h + * + * if your compiler doesn't contain "stdint.h" header (for + * example, Microsoft Visual C++), you can download file: + * http://www.azillionmonkeys.com/qed/pstdint.h + * and change next line to: + * #include "pstdint.h" + */ +#include "pstdint.h" + +#define F_MODRM 0x00000001 +#define F_SIB 0x00000002 +#define F_IMM8 0x00000004 +#define F_IMM16 0x00000008 +#define F_IMM32 0x00000010 +#define F_IMM64 0x00000020 +#define F_DISP8 0x00000040 +#define F_DISP16 0x00000080 +#define F_DISP32 0x00000100 +#define F_RELATIVE 0x00000200 +#define F_ERROR 0x00001000 +#define F_ERROR_OPCODE 0x00002000 +#define F_ERROR_LENGTH 0x00004000 +#define F_ERROR_LOCK 0x00008000 +#define F_ERROR_OPERAND 0x00010000 +#define F_PREFIX_REPNZ 0x01000000 +#define F_PREFIX_REPX 0x02000000 +#define F_PREFIX_REP 0x03000000 +#define F_PREFIX_66 0x04000000 +#define F_PREFIX_67 0x08000000 +#define F_PREFIX_LOCK 0x10000000 +#define F_PREFIX_SEG 0x20000000 +#define F_PREFIX_REX 0x40000000 +#define F_PREFIX_ANY 0x7f000000 + +#define PREFIX_SEGMENT_CS 0x2e +#define PREFIX_SEGMENT_SS 0x36 +#define PREFIX_SEGMENT_DS 0x3e +#define PREFIX_SEGMENT_ES 0x26 +#define PREFIX_SEGMENT_FS 0x64 +#define PREFIX_SEGMENT_GS 0x65 +#define PREFIX_LOCK 0xf0 +#define PREFIX_REPNZ 0xf2 +#define PREFIX_REPX 0xf3 +#define PREFIX_OPERAND_SIZE 0x66 +#define PREFIX_ADDRESS_SIZE 0x67 + +#pragma pack(push,1) + +typedef struct { + uint8_t len; + uint8_t p_rep; + uint8_t p_lock; + uint8_t p_seg; + uint8_t p_66; + uint8_t p_67; + uint8_t rex; + uint8_t rex_w; + uint8_t rex_r; + uint8_t rex_x; + uint8_t rex_b; + uint8_t opcode; + uint8_t opcode2; + uint8_t modrm; + uint8_t modrm_mod; + uint8_t modrm_reg; + uint8_t modrm_rm; + uint8_t sib; + uint8_t sib_scale; + uint8_t sib_index; + uint8_t sib_base; + union { + uint8_t imm8; + uint16_t imm16; + uint32_t imm32; + uint64_t imm64; + } imm; + union { + uint8_t disp8; + uint16_t disp16; + uint32_t disp32; + } disp; + uint32_t flags; +} hde64s; + +#pragma pack(pop) + +#ifdef __cplusplus +extern "C" { +#endif + +/* __cdecl */ +unsigned int hde64_disasm(const void *code, hde64s *hs); + +#ifdef __cplusplus +} +#endif + +#endif /* _HDE64_H_ */ diff --git a/external/minhook/src/hde/pstdint.h b/external/minhook/src/hde/pstdint.h new file mode 100644 index 00000000..84d82a01 --- /dev/null +++ b/external/minhook/src/hde/pstdint.h @@ -0,0 +1,39 @@ +/* + * MinHook - The Minimalistic API Hooking Library for x64/x86 + * Copyright (C) 2009-2017 Tsuda Kageyu. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include + +// Integer types for HDE. +typedef INT8 int8_t; +typedef INT16 int16_t; +typedef INT32 int32_t; +typedef INT64 int64_t; +typedef UINT8 uint8_t; +typedef UINT16 uint16_t; +typedef UINT32 uint32_t; +typedef UINT64 uint64_t; diff --git a/external/minhook/src/hde/table32.h b/external/minhook/src/hde/table32.h new file mode 100644 index 00000000..7b3e12e3 --- /dev/null +++ b/external/minhook/src/hde/table32.h @@ -0,0 +1,73 @@ +/* + * Hacker Disassembler Engine 32 C + * Copyright (c) 2008-2009, Vyacheslav Patkov. + * All rights reserved. + * + */ + +#define C_NONE 0x00 +#define C_MODRM 0x01 +#define C_IMM8 0x02 +#define C_IMM16 0x04 +#define C_IMM_P66 0x10 +#define C_REL8 0x20 +#define C_REL32 0x40 +#define C_GROUP 0x80 +#define C_ERROR 0xff + +#define PRE_ANY 0x00 +#define PRE_NONE 0x01 +#define PRE_F2 0x02 +#define PRE_F3 0x04 +#define PRE_66 0x08 +#define PRE_67 0x10 +#define PRE_LOCK 0x20 +#define PRE_SEG 0x40 +#define PRE_ALL 0xff + +#define DELTA_OPCODES 0x4a +#define DELTA_FPU_REG 0xf1 +#define DELTA_FPU_MODRM 0xf8 +#define DELTA_PREFIXES 0x130 +#define DELTA_OP_LOCK_OK 0x1a1 +#define DELTA_OP2_LOCK_OK 0x1b9 +#define DELTA_OP_ONLY_MEM 0x1cb +#define DELTA_OP2_ONLY_MEM 0x1da + +unsigned char hde32_table[] = { + 0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3, + 0xa8,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xac,0xaa,0xb2,0xaa,0x9f,0x9f, + 0x9f,0x9f,0xb5,0xa3,0xa3,0xa4,0xaa,0xaa,0xba,0xaa,0x96,0xaa,0xa8,0xaa,0xc3, + 0xc3,0x96,0x96,0xb7,0xae,0xd6,0xbd,0xa3,0xc5,0xa3,0xa3,0x9f,0xc3,0x9c,0xaa, + 0xaa,0xac,0xaa,0xbf,0x03,0x7f,0x11,0x7f,0x01,0x7f,0x01,0x3f,0x01,0x01,0x90, + 0x82,0x7d,0x97,0x59,0x59,0x59,0x59,0x59,0x7f,0x59,0x59,0x60,0x7d,0x7f,0x7f, + 0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x9a,0x88,0x7d, + 0x59,0x50,0x50,0x50,0x50,0x59,0x59,0x59,0x59,0x61,0x94,0x61,0x9e,0x59,0x59, + 0x85,0x59,0x92,0xa3,0x60,0x60,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59, + 0x59,0x59,0x9f,0x01,0x03,0x01,0x04,0x03,0xd5,0x03,0xcc,0x01,0xbc,0x03,0xf0, + 0x10,0x10,0x10,0x10,0x50,0x50,0x50,0x50,0x14,0x20,0x20,0x20,0x20,0x01,0x01, + 0x01,0x01,0xc4,0x02,0x10,0x00,0x00,0x00,0x00,0x01,0x01,0xc0,0xc2,0x10,0x11, + 0x02,0x03,0x11,0x03,0x03,0x04,0x00,0x00,0x14,0x00,0x02,0x00,0x00,0xc6,0xc8, + 0x02,0x02,0x02,0x02,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0xca, + 0x01,0x01,0x01,0x00,0x06,0x00,0x04,0x00,0xc0,0xc2,0x01,0x01,0x03,0x01,0xff, + 0xff,0x01,0x00,0x03,0xc4,0xc4,0xc6,0x03,0x01,0x01,0x01,0xff,0x03,0x03,0x03, + 0xc8,0x40,0x00,0x0a,0x00,0x04,0x00,0x00,0x00,0x00,0x7f,0x00,0x33,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0xff,0xbf,0xff,0xff,0x00,0x00,0x00,0x00,0x07,0x00, + 0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xff,0xff,0x00,0x00,0x00,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x7f,0x00,0x00,0xff,0x4a,0x4a,0x4a,0x4a,0x4b,0x52,0x4a,0x4a,0x4a,0x4a,0x4f, + 0x4c,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x55,0x45,0x40,0x4a,0x4a,0x4a, + 0x45,0x59,0x4d,0x46,0x4a,0x5d,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a, + 0x4a,0x4a,0x4a,0x4a,0x4a,0x61,0x63,0x67,0x4e,0x4a,0x4a,0x6b,0x6d,0x4a,0x4a, + 0x45,0x6d,0x4a,0x4a,0x44,0x45,0x4a,0x4a,0x00,0x00,0x00,0x02,0x0d,0x06,0x06, + 0x06,0x06,0x0e,0x00,0x00,0x00,0x00,0x06,0x06,0x06,0x00,0x06,0x06,0x02,0x06, + 0x00,0x0a,0x0a,0x07,0x07,0x06,0x02,0x05,0x05,0x02,0x02,0x00,0x00,0x04,0x04, + 0x04,0x04,0x00,0x00,0x00,0x0e,0x05,0x06,0x06,0x06,0x01,0x06,0x00,0x00,0x08, + 0x00,0x10,0x00,0x18,0x00,0x20,0x00,0x28,0x00,0x30,0x00,0x80,0x01,0x82,0x01, + 0x86,0x00,0xf6,0xcf,0xfe,0x3f,0xab,0x00,0xb0,0x00,0xb1,0x00,0xb3,0x00,0xba, + 0xf8,0xbb,0x00,0xc0,0x00,0xc1,0x00,0xc7,0xbf,0x62,0xff,0x00,0x8d,0xff,0x00, + 0xc4,0xff,0x00,0xc5,0xff,0x00,0xff,0xff,0xeb,0x01,0xff,0x0e,0x12,0x08,0x00, + 0x13,0x09,0x00,0x16,0x08,0x00,0x17,0x09,0x00,0x2b,0x09,0x00,0xae,0xff,0x07, + 0xb2,0xff,0x00,0xb4,0xff,0x00,0xb5,0xff,0x00,0xc3,0x01,0x00,0xc7,0xff,0xbf, + 0xe7,0x08,0x00,0xf0,0x02,0x00 +}; diff --git a/external/minhook/src/hde/table64.h b/external/minhook/src/hde/table64.h new file mode 100644 index 00000000..01d4541f --- /dev/null +++ b/external/minhook/src/hde/table64.h @@ -0,0 +1,74 @@ +/* + * Hacker Disassembler Engine 64 C + * Copyright (c) 2008-2009, Vyacheslav Patkov. + * All rights reserved. + * + */ + +#define C_NONE 0x00 +#define C_MODRM 0x01 +#define C_IMM8 0x02 +#define C_IMM16 0x04 +#define C_IMM_P66 0x10 +#define C_REL8 0x20 +#define C_REL32 0x40 +#define C_GROUP 0x80 +#define C_ERROR 0xff + +#define PRE_ANY 0x00 +#define PRE_NONE 0x01 +#define PRE_F2 0x02 +#define PRE_F3 0x04 +#define PRE_66 0x08 +#define PRE_67 0x10 +#define PRE_LOCK 0x20 +#define PRE_SEG 0x40 +#define PRE_ALL 0xff + +#define DELTA_OPCODES 0x4a +#define DELTA_FPU_REG 0xfd +#define DELTA_FPU_MODRM 0x104 +#define DELTA_PREFIXES 0x13c +#define DELTA_OP_LOCK_OK 0x1ae +#define DELTA_OP2_LOCK_OK 0x1c6 +#define DELTA_OP_ONLY_MEM 0x1d8 +#define DELTA_OP2_ONLY_MEM 0x1e7 + +unsigned char hde64_table[] = { + 0xa5,0xaa,0xa5,0xb8,0xa5,0xaa,0xa5,0xaa,0xa5,0xb8,0xa5,0xb8,0xa5,0xb8,0xa5, + 0xb8,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xac,0xc0,0xcc,0xc0,0xa1,0xa1, + 0xa1,0xa1,0xb1,0xa5,0xa5,0xa6,0xc0,0xc0,0xd7,0xda,0xe0,0xc0,0xe4,0xc0,0xea, + 0xea,0xe0,0xe0,0x98,0xc8,0xee,0xf1,0xa5,0xd3,0xa5,0xa5,0xa1,0xea,0x9e,0xc0, + 0xc0,0xc2,0xc0,0xe6,0x03,0x7f,0x11,0x7f,0x01,0x7f,0x01,0x3f,0x01,0x01,0xab, + 0x8b,0x90,0x64,0x5b,0x5b,0x5b,0x5b,0x5b,0x92,0x5b,0x5b,0x76,0x90,0x92,0x92, + 0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x6a,0x73,0x90, + 0x5b,0x52,0x52,0x52,0x52,0x5b,0x5b,0x5b,0x5b,0x77,0x7c,0x77,0x85,0x5b,0x5b, + 0x70,0x5b,0x7a,0xaf,0x76,0x76,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b, + 0x5b,0x5b,0x86,0x01,0x03,0x01,0x04,0x03,0xd5,0x03,0xd5,0x03,0xcc,0x01,0xbc, + 0x03,0xf0,0x03,0x03,0x04,0x00,0x50,0x50,0x50,0x50,0xff,0x20,0x20,0x20,0x20, + 0x01,0x01,0x01,0x01,0xc4,0x02,0x10,0xff,0xff,0xff,0x01,0x00,0x03,0x11,0xff, + 0x03,0xc4,0xc6,0xc8,0x02,0x10,0x00,0xff,0xcc,0x01,0x01,0x01,0x00,0x00,0x00, + 0x00,0x01,0x01,0x03,0x01,0xff,0xff,0xc0,0xc2,0x10,0x11,0x02,0x03,0x01,0x01, + 0x01,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0x10, + 0x10,0x10,0x10,0x02,0x10,0x00,0x00,0xc6,0xc8,0x02,0x02,0x02,0x02,0x06,0x00, + 0x04,0x00,0x02,0xff,0x00,0xc0,0xc2,0x01,0x01,0x03,0x03,0x03,0xca,0x40,0x00, + 0x0a,0x00,0x04,0x00,0x00,0x00,0x00,0x7f,0x00,0x33,0x01,0x00,0x00,0x00,0x00, + 0x00,0x00,0xff,0xbf,0xff,0xff,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff, + 0x00,0x00,0x00,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x00,0x00, + 0xff,0x40,0x40,0x40,0x40,0x41,0x49,0x40,0x40,0x40,0x40,0x4c,0x42,0x40,0x40, + 0x40,0x40,0x40,0x40,0x40,0x40,0x4f,0x44,0x53,0x40,0x40,0x40,0x44,0x57,0x43, + 0x5c,0x40,0x60,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, + 0x40,0x40,0x64,0x66,0x6e,0x6b,0x40,0x40,0x6a,0x46,0x40,0x40,0x44,0x46,0x40, + 0x40,0x5b,0x44,0x40,0x40,0x00,0x00,0x00,0x00,0x06,0x06,0x06,0x06,0x01,0x06, + 0x06,0x02,0x06,0x06,0x00,0x06,0x00,0x0a,0x0a,0x00,0x00,0x00,0x02,0x07,0x07, + 0x06,0x02,0x0d,0x06,0x06,0x06,0x0e,0x05,0x05,0x02,0x02,0x00,0x00,0x04,0x04, + 0x04,0x04,0x05,0x06,0x06,0x06,0x00,0x00,0x00,0x0e,0x00,0x00,0x08,0x00,0x10, + 0x00,0x18,0x00,0x20,0x00,0x28,0x00,0x30,0x00,0x80,0x01,0x82,0x01,0x86,0x00, + 0xf6,0xcf,0xfe,0x3f,0xab,0x00,0xb0,0x00,0xb1,0x00,0xb3,0x00,0xba,0xf8,0xbb, + 0x00,0xc0,0x00,0xc1,0x00,0xc7,0xbf,0x62,0xff,0x00,0x8d,0xff,0x00,0xc4,0xff, + 0x00,0xc5,0xff,0x00,0xff,0xff,0xeb,0x01,0xff,0x0e,0x12,0x08,0x00,0x13,0x09, + 0x00,0x16,0x08,0x00,0x17,0x09,0x00,0x2b,0x09,0x00,0xae,0xff,0x07,0xb2,0xff, + 0x00,0xb4,0xff,0x00,0xb5,0xff,0x00,0xc3,0x01,0x00,0xc7,0xff,0xbf,0xe7,0x08, + 0x00,0xf0,0x02,0x00 +}; diff --git a/external/minhook/src/hook.c b/external/minhook/src/hook.c new file mode 100644 index 00000000..a1975893 --- /dev/null +++ b/external/minhook/src/hook.c @@ -0,0 +1,906 @@ +/* + * MinHook - The Minimalistic API Hooking Library for x64/x86 + * Copyright (C) 2009-2017 Tsuda Kageyu. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +#include "../include/MinHook.h" +#include "buffer.h" +#include "trampoline.h" + +#ifndef ARRAYSIZE + #define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0])) +#endif + +// Initial capacity of the HOOK_ENTRY buffer. +#define INITIAL_HOOK_CAPACITY 32 + +// Initial capacity of the thread IDs buffer. +#define INITIAL_THREAD_CAPACITY 128 + +// Special hook position values. +#define INVALID_HOOK_POS UINT_MAX +#define ALL_HOOKS_POS UINT_MAX + +// Freeze() action argument defines. +#define ACTION_DISABLE 0 +#define ACTION_ENABLE 1 +#define ACTION_APPLY_QUEUED 2 + +// Thread access rights for suspending/resuming threads. +#define THREAD_ACCESS \ + (THREAD_SUSPEND_RESUME | THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION | THREAD_SET_CONTEXT) + +// Hook information. +typedef struct _HOOK_ENTRY +{ + LPVOID pTarget; // Address of the target function. + LPVOID pDetour; // Address of the detour or relay function. + LPVOID pTrampoline; // Address of the trampoline function. + UINT8 backup[8]; // Original prologue of the target function. + + UINT8 patchAbove : 1; // Uses the hot patch area. + UINT8 isEnabled : 1; // Enabled. + UINT8 queueEnable : 1; // Queued for enabling/disabling when != isEnabled. + + UINT nIP : 4; // Count of the instruction boundaries. + UINT8 oldIPs[8]; // Instruction boundaries of the target function. + UINT8 newIPs[8]; // Instruction boundaries of the trampoline function. +} HOOK_ENTRY, *PHOOK_ENTRY; + +// Suspended threads for Freeze()/Unfreeze(). +typedef struct _FROZEN_THREADS +{ + LPDWORD pItems; // Data heap + UINT capacity; // Size of allocated data heap, items + UINT size; // Actual number of data items +} FROZEN_THREADS, *PFROZEN_THREADS; + +//------------------------------------------------------------------------- +// Global Variables: +//------------------------------------------------------------------------- + +// Spin lock flag for EnterSpinLock()/LeaveSpinLock(). +volatile LONG g_isLocked = FALSE; + +// Private heap handle. If not NULL, this library is initialized. +HANDLE g_hHeap = NULL; + +// Hook entries. +struct +{ + PHOOK_ENTRY pItems; // Data heap + UINT capacity; // Size of allocated data heap, items + UINT size; // Actual number of data items +} g_hooks; + +//------------------------------------------------------------------------- +// Returns INVALID_HOOK_POS if not found. +static UINT FindHookEntry(LPVOID pTarget) +{ + UINT i; + for (i = 0; i < g_hooks.size; ++i) + { + if ((ULONG_PTR)pTarget == (ULONG_PTR)g_hooks.pItems[i].pTarget) + return i; + } + + return INVALID_HOOK_POS; +} + +//------------------------------------------------------------------------- +static PHOOK_ENTRY AddHookEntry() +{ + if (g_hooks.pItems == NULL) + { + g_hooks.capacity = INITIAL_HOOK_CAPACITY; + g_hooks.pItems = (PHOOK_ENTRY)HeapAlloc( + g_hHeap, 0, g_hooks.capacity * sizeof(HOOK_ENTRY)); + if (g_hooks.pItems == NULL) + return NULL; + } + else if (g_hooks.size >= g_hooks.capacity) + { + PHOOK_ENTRY p = (PHOOK_ENTRY)HeapReAlloc( + g_hHeap, 0, g_hooks.pItems, (g_hooks.capacity * 2) * sizeof(HOOK_ENTRY)); + if (p == NULL) + return NULL; + + g_hooks.capacity *= 2; + g_hooks.pItems = p; + } + + return &g_hooks.pItems[g_hooks.size++]; +} + +//------------------------------------------------------------------------- +static void DeleteHookEntry(UINT pos) +{ + if (pos < g_hooks.size - 1) + g_hooks.pItems[pos] = g_hooks.pItems[g_hooks.size - 1]; + + g_hooks.size--; + + if (g_hooks.capacity / 2 >= INITIAL_HOOK_CAPACITY && g_hooks.capacity / 2 >= g_hooks.size) + { + PHOOK_ENTRY p = (PHOOK_ENTRY)HeapReAlloc( + g_hHeap, 0, g_hooks.pItems, (g_hooks.capacity / 2) * sizeof(HOOK_ENTRY)); + if (p == NULL) + return; + + g_hooks.capacity /= 2; + g_hooks.pItems = p; + } +} + +//------------------------------------------------------------------------- +static DWORD_PTR FindOldIP(PHOOK_ENTRY pHook, DWORD_PTR ip) +{ + UINT i; + + if (pHook->patchAbove && ip == ((DWORD_PTR)pHook->pTarget - sizeof(JMP_REL))) + return (DWORD_PTR)pHook->pTarget; + + for (i = 0; i < pHook->nIP; ++i) + { + if (ip == ((DWORD_PTR)pHook->pTrampoline + pHook->newIPs[i])) + return (DWORD_PTR)pHook->pTarget + pHook->oldIPs[i]; + } + +#if defined(_M_X64) || defined(__x86_64__) + // Check relay function. + if (ip == (DWORD_PTR)pHook->pDetour) + return (DWORD_PTR)pHook->pTarget; +#endif + + return 0; +} + +//------------------------------------------------------------------------- +static DWORD_PTR FindNewIP(PHOOK_ENTRY pHook, DWORD_PTR ip) +{ + UINT i; + for (i = 0; i < pHook->nIP; ++i) + { + if (ip == ((DWORD_PTR)pHook->pTarget + pHook->oldIPs[i])) + return (DWORD_PTR)pHook->pTrampoline + pHook->newIPs[i]; + } + + return 0; +} + +//------------------------------------------------------------------------- +static void ProcessThreadIPs(HANDLE hThread, UINT pos, UINT action) +{ + // If the thread suspended in the overwritten area, + // move IP to the proper address. + + CONTEXT c; +#if defined(_M_X64) || defined(__x86_64__) + DWORD64 *pIP = &c.Rip; +#else + DWORD *pIP = &c.Eip; +#endif + UINT count; + + c.ContextFlags = CONTEXT_CONTROL; + if (!GetThreadContext(hThread, &c)) + return; + + if (pos == ALL_HOOKS_POS) + { + pos = 0; + count = g_hooks.size; + } + else + { + count = pos + 1; + } + + for (; pos < count; ++pos) + { + PHOOK_ENTRY pHook = &g_hooks.pItems[pos]; + BOOL enable; + DWORD_PTR ip; + + switch (action) + { + case ACTION_DISABLE: + enable = FALSE; + break; + + case ACTION_ENABLE: + enable = TRUE; + break; + + default: // ACTION_APPLY_QUEUED + enable = pHook->queueEnable; + break; + } + if (pHook->isEnabled == enable) + continue; + + if (enable) + ip = FindNewIP(pHook, *pIP); + else + ip = FindOldIP(pHook, *pIP); + + if (ip != 0) + { + *pIP = ip; + SetThreadContext(hThread, &c); + } + } +} + +//------------------------------------------------------------------------- +static VOID EnumerateThreads(PFROZEN_THREADS pThreads) +{ + HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); + if (hSnapshot != INVALID_HANDLE_VALUE) + { + THREADENTRY32 te; + te.dwSize = sizeof(THREADENTRY32); + if (Thread32First(hSnapshot, &te)) + { + do + { + if (te.dwSize >= (FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) + sizeof(DWORD)) + && te.th32OwnerProcessID == GetCurrentProcessId() + && te.th32ThreadID != GetCurrentThreadId()) + { + if (pThreads->pItems == NULL) + { + pThreads->capacity = INITIAL_THREAD_CAPACITY; + pThreads->pItems + = (LPDWORD)HeapAlloc(g_hHeap, 0, pThreads->capacity * sizeof(DWORD)); + if (pThreads->pItems == NULL) + break; + } + else if (pThreads->size >= pThreads->capacity) + { + LPDWORD p = (LPDWORD)HeapReAlloc( + g_hHeap, 0, pThreads->pItems, (pThreads->capacity * 2) * sizeof(DWORD)); + if (p == NULL) + { + HeapFree(g_hHeap, 0, pThreads->pItems); + pThreads->pItems = NULL; + break; + } + + pThreads->capacity *= 2; + pThreads->pItems = p; + } + pThreads->pItems[pThreads->size++] = te.th32ThreadID; + } + + te.dwSize = sizeof(THREADENTRY32); + } while (Thread32Next(hSnapshot, &te)); + } + CloseHandle(hSnapshot); + } +} + +//------------------------------------------------------------------------- +static MH_STATUS Freeze(PFROZEN_THREADS pThreads, UINT pos, UINT action) +{ + pThreads->pItems = NULL; + pThreads->capacity = 0; + pThreads->size = 0; + EnumerateThreads(pThreads); + + MH_STATUS status = MH_OK; + + if (pThreads->pItems != NULL) + { + UINT i; + for (i = 0; i < pThreads->size; ++i) + { + HANDLE hThread = OpenThread(THREAD_ACCESS, FALSE, pThreads->pItems[i]); + if (hThread != NULL) + { + SuspendThread(hThread); + ProcessThreadIPs(hThread, pos, action); + CloseHandle(hThread); + } + } + } + else + { + status = MH_ERROR_MEMORY_ALLOC; + } + + return status; +} + +//------------------------------------------------------------------------- +static VOID Unfreeze(PFROZEN_THREADS pThreads) +{ + UINT i; + for (i = 0; i < pThreads->size; ++i) + { + HANDLE hThread = OpenThread(THREAD_ACCESS, FALSE, pThreads->pItems[i]); + if (hThread != NULL) + { + ResumeThread(hThread); + CloseHandle(hThread); + } + } + + HeapFree(g_hHeap, 0, pThreads->pItems); +} + +//------------------------------------------------------------------------- +static MH_STATUS EnableHookLL(UINT pos, BOOL enable) +{ + PHOOK_ENTRY pHook = &g_hooks.pItems[pos]; + DWORD oldProtect; + SIZE_T patchSize = sizeof(JMP_REL); + LPBYTE pPatchTarget = (LPBYTE)pHook->pTarget; + + if (pHook->patchAbove) + { + pPatchTarget -= sizeof(JMP_REL); + patchSize += sizeof(JMP_REL_SHORT); + } + + if (!VirtualProtect(pPatchTarget, patchSize, PAGE_EXECUTE_READWRITE, &oldProtect)) + return MH_ERROR_MEMORY_PROTECT; + + if (enable) + { + PJMP_REL pJmp = (PJMP_REL)pPatchTarget; + pJmp->opcode = 0xE9; + pJmp->operand = (UINT32)((LPBYTE)pHook->pDetour - (pPatchTarget + sizeof(JMP_REL))); + + if (pHook->patchAbove) + { + PJMP_REL_SHORT pShortJmp = (PJMP_REL_SHORT)pHook->pTarget; + pShortJmp->opcode = 0xEB; + pShortJmp->operand = (UINT8)(0 - (sizeof(JMP_REL_SHORT) + sizeof(JMP_REL))); + } + } + else + { + if (pHook->patchAbove) + memcpy(pPatchTarget, pHook->backup, sizeof(JMP_REL) + sizeof(JMP_REL_SHORT)); + else + memcpy(pPatchTarget, pHook->backup, sizeof(JMP_REL)); + } + + VirtualProtect(pPatchTarget, patchSize, oldProtect, &oldProtect); + + // Just-in-case measure. + FlushInstructionCache(GetCurrentProcess(), pPatchTarget, patchSize); + + pHook->isEnabled = enable; + pHook->queueEnable = enable; + + return MH_OK; +} + +//------------------------------------------------------------------------- +static MH_STATUS EnableAllHooksLL(BOOL enable) +{ + MH_STATUS status = MH_OK; + UINT i, first = INVALID_HOOK_POS; + + for (i = 0; i < g_hooks.size; ++i) + { + if (g_hooks.pItems[i].isEnabled != enable) + { + first = i; + break; + } + } + + if (first != INVALID_HOOK_POS) + { + FROZEN_THREADS threads; + status = Freeze(&threads, ALL_HOOKS_POS, enable ? ACTION_ENABLE : ACTION_DISABLE); + if (status == MH_OK) + { + for (i = first; i < g_hooks.size; ++i) + { + if (g_hooks.pItems[i].isEnabled != enable) + { + status = EnableHookLL(i, enable); + if (status != MH_OK) + break; + } + } + + Unfreeze(&threads); + } + } + + return status; +} + +//------------------------------------------------------------------------- +static VOID EnterSpinLock(VOID) +{ + SIZE_T spinCount = 0; + + // Wait until the flag is FALSE. + while (InterlockedCompareExchange(&g_isLocked, TRUE, FALSE) != FALSE) + { + // No need to generate a memory barrier here, since InterlockedCompareExchange() + // generates a full memory barrier itself. + + // Prevent the loop from being too busy. + if (spinCount < 32) + Sleep(0); + else + Sleep(1); + + spinCount++; + } +} + +//------------------------------------------------------------------------- +static VOID LeaveSpinLock(VOID) +{ + // No need to generate a memory barrier here, since InterlockedExchange() + // generates a full memory barrier itself. + + InterlockedExchange(&g_isLocked, FALSE); +} + +//------------------------------------------------------------------------- +MH_STATUS WINAPI MH_Initialize(VOID) +{ + MH_STATUS status = MH_OK; + + EnterSpinLock(); + + if (g_hHeap == NULL) + { + g_hHeap = HeapCreate(0, 0, 0); + if (g_hHeap != NULL) + { + // Initialize the internal function buffer. + InitializeBuffer(); + } + else + { + status = MH_ERROR_MEMORY_ALLOC; + } + } + else + { + status = MH_ERROR_ALREADY_INITIALIZED; + } + + LeaveSpinLock(); + + return status; +} + +//------------------------------------------------------------------------- +MH_STATUS WINAPI MH_Uninitialize(VOID) +{ + MH_STATUS status = MH_OK; + + EnterSpinLock(); + + if (g_hHeap != NULL) + { + status = EnableAllHooksLL(FALSE); + if (status == MH_OK) + { + // Free the internal function buffer. + + // HeapFree is actually not required, but some tools detect a false + // memory leak without HeapFree. + + UninitializeBuffer(); + + HeapFree(g_hHeap, 0, g_hooks.pItems); + HeapDestroy(g_hHeap); + + g_hHeap = NULL; + + g_hooks.pItems = NULL; + g_hooks.capacity = 0; + g_hooks.size = 0; + } + } + else + { + status = MH_ERROR_NOT_INITIALIZED; + } + + LeaveSpinLock(); + + return status; +} + +//------------------------------------------------------------------------- +MH_STATUS WINAPI MH_CreateHook(LPVOID pTarget, LPVOID pDetour, LPVOID *ppOriginal) +{ + MH_STATUS status = MH_OK; + + EnterSpinLock(); + + if (g_hHeap != NULL) + { + if (IsExecutableAddress(pTarget) && IsExecutableAddress(pDetour)) + { + UINT pos = FindHookEntry(pTarget); + if (pos == INVALID_HOOK_POS) + { + LPVOID pBuffer = AllocateBuffer(pTarget); + if (pBuffer != NULL) + { + TRAMPOLINE ct; + + ct.pTarget = pTarget; + ct.pDetour = pDetour; + ct.pTrampoline = pBuffer; + if (CreateTrampolineFunction(&ct)) + { + PHOOK_ENTRY pHook = AddHookEntry(); + if (pHook != NULL) + { + pHook->pTarget = ct.pTarget; +#if defined(_M_X64) || defined(__x86_64__) + pHook->pDetour = ct.pRelay; +#else + pHook->pDetour = ct.pDetour; +#endif + pHook->pTrampoline = ct.pTrampoline; + pHook->patchAbove = ct.patchAbove; + pHook->isEnabled = FALSE; + pHook->queueEnable = FALSE; + pHook->nIP = ct.nIP; + memcpy(pHook->oldIPs, ct.oldIPs, ARRAYSIZE(ct.oldIPs)); + memcpy(pHook->newIPs, ct.newIPs, ARRAYSIZE(ct.newIPs)); + + // Back up the target function. + + if (ct.patchAbove) + { + memcpy( + pHook->backup, + (LPBYTE)pTarget - sizeof(JMP_REL), + sizeof(JMP_REL) + sizeof(JMP_REL_SHORT)); + } + else + { + memcpy(pHook->backup, pTarget, sizeof(JMP_REL)); + } + + if (ppOriginal != NULL) + *ppOriginal = pHook->pTrampoline; + } + else + { + status = MH_ERROR_MEMORY_ALLOC; + } + } + else + { + status = MH_ERROR_UNSUPPORTED_FUNCTION; + } + + if (status != MH_OK) + { + FreeBuffer(pBuffer); + } + } + else + { + status = MH_ERROR_MEMORY_ALLOC; + } + } + else + { + status = MH_ERROR_ALREADY_CREATED; + } + } + else + { + status = MH_ERROR_NOT_EXECUTABLE; + } + } + else + { + status = MH_ERROR_NOT_INITIALIZED; + } + + LeaveSpinLock(); + + return status; +} + +//------------------------------------------------------------------------- +MH_STATUS WINAPI MH_RemoveHook(LPVOID pTarget) +{ + MH_STATUS status = MH_OK; + + EnterSpinLock(); + + if (g_hHeap != NULL) + { + UINT pos = FindHookEntry(pTarget); + if (pos != INVALID_HOOK_POS) + { + if (g_hooks.pItems[pos].isEnabled) + { + FROZEN_THREADS threads; + status = Freeze(&threads, pos, ACTION_DISABLE); + if (status == MH_OK) + { + status = EnableHookLL(pos, FALSE); + + Unfreeze(&threads); + } + } + + if (status == MH_OK) + { + FreeBuffer(g_hooks.pItems[pos].pTrampoline); + DeleteHookEntry(pos); + } + } + else + { + status = MH_ERROR_NOT_CREATED; + } + } + else + { + status = MH_ERROR_NOT_INITIALIZED; + } + + LeaveSpinLock(); + + return status; +} + +//------------------------------------------------------------------------- +static MH_STATUS EnableHook(LPVOID pTarget, BOOL enable) +{ + MH_STATUS status = MH_OK; + + EnterSpinLock(); + + if (g_hHeap != NULL) + { + if (pTarget == MH_ALL_HOOKS) + { + status = EnableAllHooksLL(enable); + } + else + { + UINT pos = FindHookEntry(pTarget); + if (pos != INVALID_HOOK_POS) + { + if (g_hooks.pItems[pos].isEnabled != enable) + { + FROZEN_THREADS threads; + status = Freeze(&threads, pos, ACTION_ENABLE); + if (status == MH_OK) + { + status = EnableHookLL(pos, enable); + + Unfreeze(&threads); + } + } + else + { + status = enable ? MH_ERROR_ENABLED : MH_ERROR_DISABLED; + } + } + else + { + status = MH_ERROR_NOT_CREATED; + } + } + } + else + { + status = MH_ERROR_NOT_INITIALIZED; + } + + LeaveSpinLock(); + + return status; +} + +//------------------------------------------------------------------------- +MH_STATUS WINAPI MH_EnableHook(LPVOID pTarget) +{ + return EnableHook(pTarget, TRUE); +} + +//------------------------------------------------------------------------- +MH_STATUS WINAPI MH_DisableHook(LPVOID pTarget) +{ + return EnableHook(pTarget, FALSE); +} + +//------------------------------------------------------------------------- +static MH_STATUS QueueHook(LPVOID pTarget, BOOL queueEnable) +{ + MH_STATUS status = MH_OK; + + EnterSpinLock(); + + if (g_hHeap != NULL) + { + if (pTarget == MH_ALL_HOOKS) + { + UINT i; + for (i = 0; i < g_hooks.size; ++i) + g_hooks.pItems[i].queueEnable = queueEnable; + } + else + { + UINT pos = FindHookEntry(pTarget); + if (pos != INVALID_HOOK_POS) + { + g_hooks.pItems[pos].queueEnable = queueEnable; + } + else + { + status = MH_ERROR_NOT_CREATED; + } + } + } + else + { + status = MH_ERROR_NOT_INITIALIZED; + } + + LeaveSpinLock(); + + return status; +} + +//------------------------------------------------------------------------- +MH_STATUS WINAPI MH_QueueEnableHook(LPVOID pTarget) +{ + return QueueHook(pTarget, TRUE); +} + +//------------------------------------------------------------------------- +MH_STATUS WINAPI MH_QueueDisableHook(LPVOID pTarget) +{ + return QueueHook(pTarget, FALSE); +} + +//------------------------------------------------------------------------- +MH_STATUS WINAPI MH_ApplyQueued(VOID) +{ + MH_STATUS status = MH_OK; + UINT i, first = INVALID_HOOK_POS; + + EnterSpinLock(); + + if (g_hHeap != NULL) + { + for (i = 0; i < g_hooks.size; ++i) + { + if (g_hooks.pItems[i].isEnabled != g_hooks.pItems[i].queueEnable) + { + first = i; + break; + } + } + + if (first != INVALID_HOOK_POS) + { + FROZEN_THREADS threads; + status = Freeze(&threads, ALL_HOOKS_POS, ACTION_APPLY_QUEUED); + if (status == MH_OK) + { + for (i = first; i < g_hooks.size; ++i) + { + PHOOK_ENTRY pHook = &g_hooks.pItems[i]; + if (pHook->isEnabled != pHook->queueEnable) + { + status = EnableHookLL(i, pHook->queueEnable); + if (status != MH_OK) + break; + } + } + + Unfreeze(&threads); + } + } + } + else + { + status = MH_ERROR_NOT_INITIALIZED; + } + + LeaveSpinLock(); + + return status; +} + +//------------------------------------------------------------------------- +MH_STATUS WINAPI MH_CreateHookApiEx( + LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, + LPVOID *ppOriginal, LPVOID *ppTarget) +{ + HMODULE hModule; + LPVOID pTarget; + + hModule = GetModuleHandleW(pszModule); + if (hModule == NULL) + return MH_ERROR_MODULE_NOT_FOUND; + + pTarget = (LPVOID)GetProcAddress(hModule, pszProcName); + if (pTarget == NULL) + return MH_ERROR_FUNCTION_NOT_FOUND; + + if(ppTarget != NULL) + *ppTarget = pTarget; + + return MH_CreateHook(pTarget, pDetour, ppOriginal); +} + +//------------------------------------------------------------------------- +MH_STATUS WINAPI MH_CreateHookApi( + LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, LPVOID *ppOriginal) +{ + return MH_CreateHookApiEx(pszModule, pszProcName, pDetour, ppOriginal, NULL); +} + +//------------------------------------------------------------------------- +const char * WINAPI MH_StatusToString(MH_STATUS status) +{ +#define MH_ST2STR(x) \ + case x: \ + return #x; + + switch (status) { + MH_ST2STR(MH_UNKNOWN) + MH_ST2STR(MH_OK) + MH_ST2STR(MH_ERROR_ALREADY_INITIALIZED) + MH_ST2STR(MH_ERROR_NOT_INITIALIZED) + MH_ST2STR(MH_ERROR_ALREADY_CREATED) + MH_ST2STR(MH_ERROR_NOT_CREATED) + MH_ST2STR(MH_ERROR_ENABLED) + MH_ST2STR(MH_ERROR_DISABLED) + MH_ST2STR(MH_ERROR_NOT_EXECUTABLE) + MH_ST2STR(MH_ERROR_UNSUPPORTED_FUNCTION) + MH_ST2STR(MH_ERROR_MEMORY_ALLOC) + MH_ST2STR(MH_ERROR_MEMORY_PROTECT) + MH_ST2STR(MH_ERROR_MODULE_NOT_FOUND) + MH_ST2STR(MH_ERROR_FUNCTION_NOT_FOUND) + } + +#undef MH_ST2STR + + return "(unknown)"; +} diff --git a/external/minhook/src/trampoline.c b/external/minhook/src/trampoline.c new file mode 100644 index 00000000..617baf3f --- /dev/null +++ b/external/minhook/src/trampoline.c @@ -0,0 +1,320 @@ +/* + * MinHook - The Minimalistic API Hooking Library for x64/x86 + * Copyright (C) 2009-2017 Tsuda Kageyu. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +#ifdef _MSC_VER + #include +#endif + +#ifndef ARRAYSIZE + #define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0])) +#endif + +#if defined(_M_X64) || defined(__x86_64__) + #include "./hde/hde64.h" + typedef hde64s HDE; + #define HDE_DISASM(code, hs) hde64_disasm(code, hs) +#else + #include "./hde/hde32.h" + typedef hde32s HDE; + #define HDE_DISASM(code, hs) hde32_disasm(code, hs) +#endif + +#include "trampoline.h" +#include "buffer.h" + +// Maximum size of a trampoline function. +#if defined(_M_X64) || defined(__x86_64__) + #define TRAMPOLINE_MAX_SIZE (MEMORY_SLOT_SIZE - sizeof(JMP_ABS)) +#else + #define TRAMPOLINE_MAX_SIZE MEMORY_SLOT_SIZE +#endif + +//------------------------------------------------------------------------- +static BOOL IsCodePadding(LPBYTE pInst, UINT size) +{ + UINT i; + + if (pInst[0] != 0x00 && pInst[0] != 0x90 && pInst[0] != 0xCC) + return FALSE; + + for (i = 1; i < size; ++i) + { + if (pInst[i] != pInst[0]) + return FALSE; + } + return TRUE; +} + +//------------------------------------------------------------------------- +BOOL CreateTrampolineFunction(PTRAMPOLINE ct) +{ +#if defined(_M_X64) || defined(__x86_64__) + CALL_ABS call = { + 0xFF, 0x15, 0x00000002, // FF15 00000002: CALL [RIP+8] + 0xEB, 0x08, // EB 08: JMP +10 + 0x0000000000000000ULL // Absolute destination address + }; + JMP_ABS jmp = { + 0xFF, 0x25, 0x00000000, // FF25 00000000: JMP [RIP+6] + 0x0000000000000000ULL // Absolute destination address + }; + JCC_ABS jcc = { + 0x70, 0x0E, // 7* 0E: J** +16 + 0xFF, 0x25, 0x00000000, // FF25 00000000: JMP [RIP+6] + 0x0000000000000000ULL // Absolute destination address + }; +#else + CALL_REL call = { + 0xE8, // E8 xxxxxxxx: CALL +5+xxxxxxxx + 0x00000000 // Relative destination address + }; + JMP_REL jmp = { + 0xE9, // E9 xxxxxxxx: JMP +5+xxxxxxxx + 0x00000000 // Relative destination address + }; + JCC_REL jcc = { + 0x0F, 0x80, // 0F8* xxxxxxxx: J** +6+xxxxxxxx + 0x00000000 // Relative destination address + }; +#endif + + UINT8 oldPos = 0; + UINT8 newPos = 0; + ULONG_PTR jmpDest = 0; // Destination address of an internal jump. + BOOL finished = FALSE; // Is the function completed? +#if defined(_M_X64) || defined(__x86_64__) + UINT8 instBuf[16]; +#endif + + ct->patchAbove = FALSE; + ct->nIP = 0; + + do + { + HDE hs; + UINT copySize; + LPVOID pCopySrc; + ULONG_PTR pOldInst = (ULONG_PTR)ct->pTarget + oldPos; + ULONG_PTR pNewInst = (ULONG_PTR)ct->pTrampoline + newPos; + + copySize = HDE_DISASM((LPVOID)pOldInst, &hs); + if (hs.flags & F_ERROR) + return FALSE; + + pCopySrc = (LPVOID)pOldInst; + if (oldPos >= sizeof(JMP_REL)) + { + // The trampoline function is long enough. + // Complete the function with the jump to the target function. +#if defined(_M_X64) || defined(__x86_64__) + jmp.address = pOldInst; +#else + jmp.operand = (UINT32)(pOldInst - (pNewInst + sizeof(jmp))); +#endif + pCopySrc = &jmp; + copySize = sizeof(jmp); + + finished = TRUE; + } +#if defined(_M_X64) || defined(__x86_64__) + else if ((hs.modrm & 0xC7) == 0x05) + { + // Instructions using RIP relative addressing. (ModR/M = 00???101B) + + // Modify the RIP relative address. + PUINT32 pRelAddr; + + // Avoid using memcpy to reduce the footprint. +#ifndef _MSC_VER + memcpy(instBuf, (LPBYTE)pOldInst, copySize); +#else + __movsb(instBuf, (LPBYTE)pOldInst, copySize); +#endif + pCopySrc = instBuf; + + // Relative address is stored at (instruction length - immediate value length - 4). + pRelAddr = (PUINT32)(instBuf + hs.len - ((hs.flags & 0x3C) >> 2) - 4); + *pRelAddr + = (UINT32)((pOldInst + hs.len + (INT32)hs.disp.disp32) - (pNewInst + hs.len)); + + // Complete the function if JMP (FF /4). + if (hs.opcode == 0xFF && hs.modrm_reg == 4) + finished = TRUE; + } +#endif + else if (hs.opcode == 0xE8) + { + // Direct relative CALL + ULONG_PTR dest = pOldInst + hs.len + (INT32)hs.imm.imm32; +#if defined(_M_X64) || defined(__x86_64__) + call.address = dest; +#else + call.operand = (UINT32)(dest - (pNewInst + sizeof(call))); +#endif + pCopySrc = &call; + copySize = sizeof(call); + } + else if ((hs.opcode & 0xFD) == 0xE9) + { + // Direct relative JMP (EB or E9) + ULONG_PTR dest = pOldInst + hs.len; + + if (hs.opcode == 0xEB) // isShort jmp + dest += (INT8)hs.imm.imm8; + else + dest += (INT32)hs.imm.imm32; + + // Simply copy an internal jump. + if ((ULONG_PTR)ct->pTarget <= dest + && dest < ((ULONG_PTR)ct->pTarget + sizeof(JMP_REL))) + { + if (jmpDest < dest) + jmpDest = dest; + } + else + { +#if defined(_M_X64) || defined(__x86_64__) + jmp.address = dest; +#else + jmp.operand = (UINT32)(dest - (pNewInst + sizeof(jmp))); +#endif + pCopySrc = &jmp; + copySize = sizeof(jmp); + + // Exit the function if it is not in the branch. + finished = (pOldInst >= jmpDest); + } + } + else if ((hs.opcode & 0xF0) == 0x70 + || (hs.opcode & 0xFC) == 0xE0 + || (hs.opcode2 & 0xF0) == 0x80) + { + // Direct relative Jcc + ULONG_PTR dest = pOldInst + hs.len; + + if ((hs.opcode & 0xF0) == 0x70 // Jcc + || (hs.opcode & 0xFC) == 0xE0) // LOOPNZ/LOOPZ/LOOP/JECXZ + dest += (INT8)hs.imm.imm8; + else + dest += (INT32)hs.imm.imm32; + + // Simply copy an internal jump. + if ((ULONG_PTR)ct->pTarget <= dest + && dest < ((ULONG_PTR)ct->pTarget + sizeof(JMP_REL))) + { + if (jmpDest < dest) + jmpDest = dest; + } + else if ((hs.opcode & 0xFC) == 0xE0) + { + // LOOPNZ/LOOPZ/LOOP/JCXZ/JECXZ to the outside are not supported. + return FALSE; + } + else + { + UINT8 cond = ((hs.opcode != 0x0F ? hs.opcode : hs.opcode2) & 0x0F); +#if defined(_M_X64) || defined(__x86_64__) + // Invert the condition in x64 mode to simplify the conditional jump logic. + jcc.opcode = 0x71 ^ cond; + jcc.address = dest; +#else + jcc.opcode1 = 0x80 | cond; + jcc.operand = (UINT32)(dest - (pNewInst + sizeof(jcc))); +#endif + pCopySrc = &jcc; + copySize = sizeof(jcc); + } + } + else if ((hs.opcode & 0xFE) == 0xC2) + { + // RET (C2 or C3) + + // Complete the function if not in a branch. + finished = (pOldInst >= jmpDest); + } + + // Can't alter the instruction length in a branch. + if (pOldInst < jmpDest && copySize != hs.len) + return FALSE; + + // Trampoline function is too large. + if ((newPos + copySize) > TRAMPOLINE_MAX_SIZE) + return FALSE; + + // Trampoline function has too many instructions. + if (ct->nIP >= ARRAYSIZE(ct->oldIPs)) + return FALSE; + + ct->oldIPs[ct->nIP] = oldPos; + ct->newIPs[ct->nIP] = newPos; + ct->nIP++; + + // Avoid using memcpy to reduce the footprint. +#ifndef _MSC_VER + memcpy((LPBYTE)ct->pTrampoline + newPos, pCopySrc, copySize); +#else + __movsb((LPBYTE)ct->pTrampoline + newPos, (LPBYTE)pCopySrc, copySize); +#endif + newPos += copySize; + oldPos += hs.len; + } + while (!finished); + + // Is there enough place for a long jump? + if (oldPos < sizeof(JMP_REL) + && !IsCodePadding((LPBYTE)ct->pTarget + oldPos, sizeof(JMP_REL) - oldPos)) + { + // Is there enough place for a short jump? + if (oldPos < sizeof(JMP_REL_SHORT) + && !IsCodePadding((LPBYTE)ct->pTarget + oldPos, sizeof(JMP_REL_SHORT) - oldPos)) + { + return FALSE; + } + + // Can we place the long jump above the function? + if (!IsExecutableAddress((LPBYTE)ct->pTarget - sizeof(JMP_REL))) + return FALSE; + + if (!IsCodePadding((LPBYTE)ct->pTarget - sizeof(JMP_REL), sizeof(JMP_REL))) + return FALSE; + + ct->patchAbove = TRUE; + } + +#if defined(_M_X64) || defined(__x86_64__) + // Create a relay function. + jmp.address = (ULONG_PTR)ct->pDetour; + + ct->pRelay = (LPBYTE)ct->pTrampoline + newPos; + memcpy(ct->pRelay, &jmp, sizeof(jmp)); +#endif + + return TRUE; +} diff --git a/external/minhook/src/trampoline.h b/external/minhook/src/trampoline.h new file mode 100644 index 00000000..bdffdac0 --- /dev/null +++ b/external/minhook/src/trampoline.h @@ -0,0 +1,105 @@ +/* + * MinHook - The Minimalistic API Hooking Library for x64/x86 + * Copyright (C) 2009-2017 Tsuda Kageyu. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#pragma pack(push, 1) + +// Structs for writing x86/x64 instructions. + +// 8-bit relative jump. +typedef struct _JMP_REL_SHORT +{ + UINT8 opcode; // EB xx: JMP +2+xx + UINT8 operand; +} JMP_REL_SHORT, *PJMP_REL_SHORT; + +// 32-bit direct relative jump/call. +typedef struct _JMP_REL +{ + UINT8 opcode; // E9/E8 xxxxxxxx: JMP/CALL +5+xxxxxxxx + UINT32 operand; // Relative destination address +} JMP_REL, *PJMP_REL, CALL_REL; + +// 64-bit indirect absolute jump. +typedef struct _JMP_ABS +{ + UINT8 opcode0; // FF25 00000000: JMP [+6] + UINT8 opcode1; + UINT32 dummy; + UINT64 address; // Absolute destination address +} JMP_ABS, *PJMP_ABS; + +// 64-bit indirect absolute call. +typedef struct _CALL_ABS +{ + UINT8 opcode0; // FF15 00000002: CALL [+6] + UINT8 opcode1; + UINT32 dummy0; + UINT8 dummy1; // EB 08: JMP +10 + UINT8 dummy2; + UINT64 address; // Absolute destination address +} CALL_ABS; + +// 32-bit direct relative conditional jumps. +typedef struct _JCC_REL +{ + UINT8 opcode0; // 0F8* xxxxxxxx: J** +6+xxxxxxxx + UINT8 opcode1; + UINT32 operand; // Relative destination address +} JCC_REL; + +// 64bit indirect absolute conditional jumps that x64 lacks. +typedef struct _JCC_ABS +{ + UINT8 opcode; // 7* 0E: J** +16 + UINT8 dummy0; + UINT8 dummy1; // FF25 00000000: JMP [+6] + UINT8 dummy2; + UINT32 dummy3; + UINT64 address; // Absolute destination address +} JCC_ABS; + +#pragma pack(pop) + +typedef struct _TRAMPOLINE +{ + LPVOID pTarget; // [In] Address of the target function. + LPVOID pDetour; // [In] Address of the detour function. + LPVOID pTrampoline; // [In] Buffer address for the trampoline and relay function. + +#if defined(_M_X64) || defined(__x86_64__) + LPVOID pRelay; // [Out] Address of the relay function. +#endif + BOOL patchAbove; // [Out] Should use the hot patch area? + UINT nIP; // [Out] Number of the instruction boundaries. + UINT8 oldIPs[8]; // [Out] Instruction boundaries of the target function. + UINT8 newIPs[8]; // [Out] Instruction boundaries of the trampoline function. +} TRAMPOLINE, *PTRAMPOLINE; + +BOOL CreateTrampolineFunction(PTRAMPOLINE ct); diff --git a/r5dedicated/r5dedicated.vcxproj b/r5dedicated/r5dedicated.vcxproj index 055520ed..961013f0 100644 --- a/r5dedicated/r5dedicated.vcxproj +++ b/r5dedicated/r5dedicated.vcxproj @@ -81,14 +81,18 @@ true dedicated - $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)external\detours\include;$(SolutionDir)external\spdlog\include;$(SolutionDir)shared\include;$(SolutionDir)r5dedicated;$(IncludePath) - $(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(SolutionDir)external\detours\libs;$(LibraryPath) + $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)external\minhook\include;$(SolutionDir)external\spdlog\include;$(SolutionDir)shared\include;$(SolutionDir)r5dedicated;$(IncludePath) + $(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(SolutionDir)external\minhook\lib\$(Configuration);$(LibraryPath) + $(SolutionDir)bin\$(Configuration)\ + $(SolutionDir)build\$(ProjectName)\$(Configuration)\ false dedicated $(VC_IncludePath);$(WindowsSDK_IncludePath);$(SolutionDir)external\minhook\include;$(SolutionDir)external\spdlog\include;$(SolutionDir)shared\include;$(SolutionDir)r5dedicated;$(IncludePath) - $(SolutionDir)external\minhook\lib;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(LibraryPath) + $(SolutionDir)external\minhook\lib\$(Configuration);$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(LibraryPath) + $(SolutionDir)bin\$(Configuration)\ + $(SolutionDir)build\$(ProjectName)\$(Configuration)\ @@ -137,9 +141,14 @@ Console true - detours.lib;%(AdditionalDependencies) + Minhook.x64.lib r5dedicated.def + + if not EXIST $(SolutionDir)external\minhook\lib\$(Configuration)\Minhook.x64.lib ( +"$(DevEnvDir)devenv" "$(SolutionDir)apex.sln" /Rebuild $(Configuration) /project "$(SolutionDir)external\minhook\libMinHook.vcxproj" +) + @@ -164,9 +173,14 @@ true true true - libMinHook.x64.lib + Minhook.x64.lib r5dedicated.def + + if not EXIST $(SolutionDir)external\minhook\lib\$(Configuration)\Minhook.x64.lib ( +"$(DevEnvDir)devenv" "$(SolutionDir)apex.sln" /Rebuild $(Configuration) /project "$(SolutionDir)external\minhook\libMinHook.vcxproj" +) + diff --git a/r5dev/r5dev.def b/r5dev/r5dev.def index 0f3d28b4..fadeb105 100644 --- a/r5dev/r5dev.def +++ b/r5dev/r5dev.def @@ -1,4 +1,4 @@ -LIBRARY r5dev +LIBRARY r5detours EXPORTS DummyExport @1 \ No newline at end of file diff --git a/r5dev/r5dev.vcxproj b/r5dev/r5dev.vcxproj index 7bdf4dc2..01991df1 100644 --- a/r5dev/r5dev.vcxproj +++ b/r5dev/r5dev.vcxproj @@ -82,13 +82,19 @@ true - $(SolutionDir)external\detours\include;$(SolutionDir)external\imgui\include;$(SolutionDir)external\spdlog\include;$(SolutionDir)shared\include;$(SolutionDir)r5dev\include;$(IncludePath) - $(SolutionDir)external\detours\libs;$(LibraryPath) + $(SolutionDir)external\minhook\include;$(SolutionDir)external\imgui\include;$(SolutionDir)external\spdlog\include;$(SolutionDir)shared\include;$(SolutionDir)r5dev\include;$(IncludePath) + $(SolutionDir)external\minhook\lib\$(Configuration);$(LibraryPath) + $(SolutionDir)bin\$(Configuration)\ + r5detours + $(SolutionDir)build\$(ProjectName)\$(Configuration)\ false $(SolutionDir)external\minhook\include;$(SolutionDir)external\imgui\include;$(SolutionDir)external\spdlog\include;$(SolutionDir)shared\include;$(SolutionDir)r5dev\include;$(IncludePath) - $(SolutionDir)external\minhook\lib;$(LibraryPath) + $(SolutionDir)external\minhook\lib\$(Configuration);$(LibraryPath) + $(SolutionDir)bin\$(Configuration)\ + $(SolutionDir)build\$(ProjectName)\$(Configuration)\ + r5detours @@ -142,12 +148,17 @@ true false r5dev.def - detours.lib;%(AdditionalDependencies) + Minhook.x64.lib;%(AdditionalDependencies) + + if not EXIST $(SolutionDir)external\minhook\lib\$(Configuration)\Minhook.x64.lib ( +"$(DevEnvDir)devenv" "$(SolutionDir)apex.sln" /Rebuild $(Configuration) /project "$(SolutionDir)external\minhook\libMinHook.vcxproj" +) + @@ -174,11 +185,17 @@ true false r5dev.def - libMinHook.x64.lib;%(AdditionalDependencies) + Minhook.x64.lib;%(AdditionalDependencies) - del "$(TargetDir)\r5detours.dll" && rename "$(TargetPath)" "r5detours.dll" + + + + if not EXIST $(SolutionDir)external\minhook\lib\$(Configuration)\Minhook.x64.lib ( +"$(DevEnvDir)devenv" "$(SolutionDir)apex.sln" /Rebuild $(Configuration) /project "$(SolutionDir)external\minhook\libMinHook.vcxproj" +) + @@ -326,6 +343,7 @@ NotUsing + NotUsing NotUsing diff --git a/r5launcher/r5launcher.vcxproj b/r5launcher/r5launcher.vcxproj index 3535c03b..9e0a8685 100644 --- a/r5launcher/r5launcher.vcxproj +++ b/r5launcher/r5launcher.vcxproj @@ -83,11 +83,17 @@ true $(SolutionDir)external\detours\include;$(IncludePath) $(SolutionDir)external\detours\libs;$(LibraryPath) + $(SolutionDir)build\$(ProjectName)\$(Configuration)\ + $(SolutionDir)bin\$(Configuration)\ + launcher false $(SolutionDir)external\detours\include;$(IncludePath) $(SolutionDir)external\detours\libs;$(LibraryPath) + $(SolutionDir)bin\$(Configuration)\ + $(SolutionDir)build\$(ProjectName)\$(Configuration)\ + launcher @@ -159,7 +165,8 @@ detours.lib;%(AdditionalDependencies) - del "$(TargetDir)\launcher.exe" && rename "$(TargetPath)" "launcher.exe" + +