From 77e74a5eeba43a5b5fa38c842fdeac7ade114740 Mon Sep 17 00:00:00 2001 From: Scott Ehlert Date: Thu, 9 Jul 2015 15:12:16 -0500 Subject: [PATCH] Partial 64-bit support for SourceHook on Windows --- core/sourcehook/sh_memfuncinfo.h | 9 +- core/sourcehook/test/main.cpp | 2 + core/sourcehook/test/msvc12/test.sln | 12 ++ core/sourcehook/test/msvc12/test.vcxproj | 189 +++++++++++++++++++++++ core/sourcehook/test/testoddthunks.cpp | 27 +++- 5 files changed, 232 insertions(+), 7 deletions(-) diff --git a/core/sourcehook/sh_memfuncinfo.h b/core/sourcehook/sh_memfuncinfo.h index 883e044..ceaa16e 100644 --- a/core/sourcehook/sh_memfuncinfo.h +++ b/core/sourcehook/sh_memfuncinfo.h @@ -125,6 +125,11 @@ namespace SourceHook addr += 2; ok = true; } + else if (addr[0] == 0x48 && addr[1] == 0x8B && addr[2] == 0x01) + { + addr += 3; + ok = true; + } if (!ok) return -1; @@ -132,11 +137,11 @@ namespace SourceHook { if (*addr == 0x60) { - return *++addr / 4; + return *++addr / SH_PTRSIZE; } else if (*addr == 0xA0) { - return *((unsigned int*)++addr) / 4; + return *((unsigned int*)++addr) / SH_PTRSIZE; } else if (*addr == 0x20) return 0; diff --git a/core/sourcehook/test/main.cpp b/core/sourcehook/test/main.cpp index 77a32f2..a4a297a 100644 --- a/core/sourcehook/test/main.cpp +++ b/core/sourcehook/test/main.cpp @@ -78,7 +78,9 @@ int main(int argc, char *argv[]) DO_TEST(RefRet); DO_TEST(VPHooks); DO_TEST(CPageAlloc); +#if !defined( _M_AMD64 ) && !defined( __amd64__ ) // TODO: Fix for 64-bit DO_TEST(HookManGen); +#endif DO_TEST(OddThunks); cout << endl << "----" << endl << "Passed: " << passed << endl << "Failed: " << failed << endl; diff --git a/core/sourcehook/test/msvc12/test.sln b/core/sourcehook/test/msvc12/test.sln index e69e650..8c9edab 100644 --- a/core/sourcehook/test/msvc12/test.sln +++ b/core/sourcehook/test/msvc12/test.sln @@ -8,19 +8,31 @@ EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug_NoDebugRuntimeLib|Win32 = Debug_NoDebugRuntimeLib|Win32 + Debug_NoDebugRuntimeLib|x64 = Debug_NoDebugRuntimeLib|x64 Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 DebugOpt|Win32 = DebugOpt|Win32 + DebugOpt|x64 = DebugOpt|x64 Release|Win32 = Release|Win32 + Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {456BBA64-FF14-4292-8443-3BA79E4D84CC}.Debug_NoDebugRuntimeLib|Win32.ActiveCfg = Debug_NoDebugRuntimeLib|Win32 {456BBA64-FF14-4292-8443-3BA79E4D84CC}.Debug_NoDebugRuntimeLib|Win32.Build.0 = Debug_NoDebugRuntimeLib|Win32 + {456BBA64-FF14-4292-8443-3BA79E4D84CC}.Debug_NoDebugRuntimeLib|x64.ActiveCfg = Debug_NoDebugRuntimeLib|x64 + {456BBA64-FF14-4292-8443-3BA79E4D84CC}.Debug_NoDebugRuntimeLib|x64.Build.0 = Debug_NoDebugRuntimeLib|x64 {456BBA64-FF14-4292-8443-3BA79E4D84CC}.Debug|Win32.ActiveCfg = Debug|Win32 {456BBA64-FF14-4292-8443-3BA79E4D84CC}.Debug|Win32.Build.0 = Debug|Win32 + {456BBA64-FF14-4292-8443-3BA79E4D84CC}.Debug|x64.ActiveCfg = Debug|x64 + {456BBA64-FF14-4292-8443-3BA79E4D84CC}.Debug|x64.Build.0 = Debug|x64 {456BBA64-FF14-4292-8443-3BA79E4D84CC}.DebugOpt|Win32.ActiveCfg = DebugOpt|Win32 {456BBA64-FF14-4292-8443-3BA79E4D84CC}.DebugOpt|Win32.Build.0 = DebugOpt|Win32 + {456BBA64-FF14-4292-8443-3BA79E4D84CC}.DebugOpt|x64.ActiveCfg = DebugOpt|x64 + {456BBA64-FF14-4292-8443-3BA79E4D84CC}.DebugOpt|x64.Build.0 = DebugOpt|x64 {456BBA64-FF14-4292-8443-3BA79E4D84CC}.Release|Win32.ActiveCfg = Release|Win32 {456BBA64-FF14-4292-8443-3BA79E4D84CC}.Release|Win32.Build.0 = Release|Win32 + {456BBA64-FF14-4292-8443-3BA79E4D84CC}.Release|x64.ActiveCfg = Release|x64 + {456BBA64-FF14-4292-8443-3BA79E4D84CC}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/core/sourcehook/test/msvc12/test.vcxproj b/core/sourcehook/test/msvc12/test.vcxproj index cb22fcd..f86fa5c 100644 --- a/core/sourcehook/test/msvc12/test.vcxproj +++ b/core/sourcehook/test/msvc12/test.vcxproj @@ -5,18 +5,34 @@ DebugOpt Win32 + + DebugOpt + x64 + Debug_NoDebugRuntimeLib Win32 + + Debug_NoDebugRuntimeLib + x64 + Debug Win32 + + Debug + x64 + Release Win32 + + Release + x64 + {456BBA64-FF14-4292-8443-3BA79E4D84CC} @@ -29,21 +45,41 @@ v120 MultiByte + + Application + v120 + MultiByte + Application v120 MultiByte + + Application + v120 + MultiByte + Application v120 MultiByte + + Application + v120 + MultiByte + Application v120 MultiByte + + Application + v120 + MultiByte + @@ -51,18 +87,34 @@ + + + + + + + + + + + + + + + + <_ProjectFileVersion>12.0.30501.0 @@ -72,21 +124,33 @@ Debug\ true + + true + Release\ Release\ false + + false + DebugOpt\ DebugOpt\ true + + true + Debug_NoDebugRuntimeLib\ Debug_NoDebugRuntimeLib\ true + + true + Disabled @@ -113,6 +177,32 @@ MachineX86 + + + Disabled + Neither + ../..;..;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;SH_DEBUG;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + true + true + + + Level3 + ProgramDatabase + + + $(OutDir)test.exe + true + $(OutDir)test.pdb + Console + false + + + + Full @@ -144,6 +234,39 @@ MachineX86 + + + Full + OnlyExplicitInline + Size + true + ../..;..;%(AdditionalIncludeDirectories) + NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + true + MultiThreaded + true + true + + + + + Level3 + true + ProgramDatabase + + + $(OutDir)test.exe + true + true + true + Console + true + true + false + + + + Full @@ -173,6 +296,36 @@ MachineX86 + + + Full + OnlyExplicitInline + false + Size + true + ..;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + true + false + Default + MultiThreaded + true + true + + + Level3 + ProgramDatabase + + + $(OutDir)test.exe + true + $(OutDir)test.pdb + Console + false + + + + Disabled @@ -200,6 +353,33 @@ MachineX86 + + + Disabled + Neither + ../..;..;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + true + Sync + EnableFastChecks + MultiThreaded + true + true + + + Level3 + ProgramDatabase + + + $(OutDir)test.exe + true + $(OutDir)test.pdb + Console + false + + + + @@ -218,7 +398,9 @@ false + false false + false @@ -237,8 +419,15 @@ pushd ..\..\generate shworker.exe iter sourcehook.hxx sourcehook.h 16 copy sourcehook.h ..\sourcehook.h popd + + echo on +pushd ..\..\generate +shworker.exe iter sourcehook.hxx sourcehook.h 16 +copy sourcehook.h ..\sourcehook.h +popd ..\..\sourcehook.h;%(Outputs) + ..\..\sourcehook.h;%(Outputs) diff --git a/core/sourcehook/test/testoddthunks.cpp b/core/sourcehook/test/testoddthunks.cpp index c0e3917..03980e5 100644 --- a/core/sourcehook/test/testoddthunks.cpp +++ b/core/sourcehook/test/testoddthunks.cpp @@ -96,13 +96,30 @@ namespace // Now generate the jump code g_ThunkAllocator.SetRW(g_OddThunkMemory); - *(base + 0) = 0xE9; // offset jump, immediate operand - ptrdiff_t *offsetAddr = reinterpret_cast(base + 1); - // destination = src + offset + 5 // <=> offset = destination - src - 5 - *offsetAddr = - (reinterpret_cast(origEntry) - base) - 5; + ptrdiff_t offset = reinterpret_cast(origEntry) - base - 5; + + if (offset >= INT_MIN && offset <= INT_MAX) + { + *(base + 0) = 0xE9; // offset jump, immediate operand + ptrdiff_t *offsetAddr = reinterpret_cast(base + 1); + + *offsetAddr = offset; + } + else + { + // mov rax, origEntry + *(base + 0) = 0x48; + *(base + 1) = 0xB8; + void **offsetAddr = reinterpret_cast(reinterpret_cast(base) + 2); + + *offsetAddr = origEntry; + + // jmp rax + *(base + 10) = 0xFF; + *(base + 11) = 0xE0; + } g_ThunkAllocator.SetRE(g_OddThunkMemory);