diff --git a/AMBuildScript b/AMBuildScript index f9cfd01..3323d9a 100644 --- a/AMBuildScript +++ b/AMBuildScript @@ -353,7 +353,7 @@ class MMSConfig(object): 'BINARY_NAME="{0}"'.format(binary.outputFile), 'RC_COMPILE' ] - elif builder.target.platform == 'mac': + elif builder.target.platform == 'mac' and binary.type == 'library': binary.compiler.postlink += [ '-compatibility_version', '1.0.0', '-current_version', self.productVersion diff --git a/core/sourcehook/sh_memory.h b/core/sourcehook/sh_memory.h index 4ee1a63..7a163d0 100644 --- a/core/sourcehook/sh_memory.h +++ b/core/sourcehook/sh_memory.h @@ -340,7 +340,7 @@ namespace SourceHook return false; #elif SH_SYS == SH_SYS_APPLE - struct sigaction sa, osa; + struct sigaction sa, osa, osa2; sa.sa_sigaction = BadReadHandler; sa.sa_flags = SA_SIGINFO | SA_RESTART; @@ -351,6 +351,8 @@ namespace SourceHook if (sigaction(SIGBUS, &sa, &osa) == -1) return false; + if (sigaction(SIGSEGV, &sa, &osa) == -1) + return false; volatile const char *p = reinterpret_cast(addr); char dummy; @@ -361,6 +363,7 @@ namespace SourceHook g_BadReadCalled = false; sigaction(SIGBUS, &osa, NULL); + sigaction(SIGSEGV, &osa2, NULL); return true; #elif SH_XP == SH_XP_WINAPI diff --git a/core/sourcehook/sourcehook_impl_cvfnptr.cpp b/core/sourcehook/sourcehook_impl_cvfnptr.cpp index 65ea49a..83ff882 100644 --- a/core/sourcehook/sourcehook_impl_cvfnptr.cpp +++ b/core/sourcehook/sourcehook_impl_cvfnptr.cpp @@ -48,25 +48,35 @@ namespace SourceHook #if SH_COMP==SH_COMP_GCC if ((((ptrdiff_t)m_OrigEntry) & 1) != 0) { - // Odd orig entry. - if (SH_PTRSIZE != 4) - { - // We only have code for IA32 atm! - return false; - } - // Generate a new thunk - m_OrigCallThunk = ms_AlignedPageAllocator.Alloc(5); + m_OrigCallThunk = ms_AlignedPageAllocator.Alloc(12); ms_AlignedPageAllocator.SetRW(m_OrigCallThunk); unsigned char* thunkBase = reinterpret_cast(m_OrigCallThunk); - *(thunkBase + 0) = 0xE9; // offset jump, immediate operand - ptrdiff_t *offsetAddr = reinterpret_cast(thunkBase + 1); + ptrdiff_t offset = reinterpret_cast(m_OrigEntry) - thunkBase - 5; + + if (offset >= INT_MIN && offset <= INT_MAX) + { + *(thunkBase + 0) = 0xE9; // offset jump, immediate operand + ptrdiff_t *offsetAddr = reinterpret_cast(thunkBase + 1); - // destination = src + offset + 5 - // <=> offset = destination - src - 5 - *offsetAddr = - (reinterpret_cast(m_OrigEntry) - thunkBase) - 5; + // destination = src + offset + 5 + // <=> offset = destination - src - 5 + *offsetAddr = offset; + } + else + { + // mov rax, m_origEntry + *(thunkBase + 0) = 0x48; + *(thunkBase + 1) = 0xB8; + void **offsetAddr = reinterpret_cast(thunkBase + 2); + + *offsetAddr = m_OrigEntry; + + // jmp rax + *(thunkBase + 10) = 0xFF; + *(thunkBase + 11) = 0xE0; + } ms_AlignedPageAllocator.SetRE(m_OrigCallThunk); } diff --git a/core/sourcehook/test/AMBuilder b/core/sourcehook/test/AMBuilder index 493dfee..ce2f00f 100644 --- a/core/sourcehook/test/AMBuilder +++ b/core/sourcehook/test/AMBuilder @@ -1,35 +1,42 @@ # vim: set sts=2 ts=8 sw=2 tw=99 et ft=python: import os -binary = MMS.Program(builder, "test_sourcehook") -binary.compiler.cxxincludes += [ - os.path.join(builder.sourcePath, 'core', 'sourcehook'), -] +for arch in MMS.archs: + name = 'test_sourcehook' + binary = MMS.Program(builder, name, arch) + binary.compiler.cxxincludes += [ + os.path.join(builder.sourcePath, 'core', 'sourcehook'), + ] + if binary.compiler.version >= 'clang-2.9' or binary.compiler.version >= 'apple-clang-3.0': + binary.compiler.cxxflags += ['-Wno-null-dereference'] + if arch == 'x86_64': + binary.localFolder = name + ".x64" -binary.sources += [ - 'main.cpp', - '../sourcehook.cpp', - '../sourcehook_hookmangen.cpp', - '../sourcehook_impl_chookmaninfo.cpp', - '../sourcehook_impl_chookidman.cpp', - '../sourcehook_impl_cproto.cpp', - '../sourcehook_impl_cvfnptr.cpp', - 'test1.cpp', - 'test2.cpp', - 'test3.cpp', - 'test4.cpp', - 'testbail.cpp', - 'testbail2.cpp', - 'testhookmangen.cpp', - 'testlist.cpp', - 'testmanual.cpp', - 'testmulti.cpp', - 'testoddthunks.cpp', - 'testrecall.cpp', - 'testreentr.cpp', - 'testref.cpp', - 'testrefret.cpp', - 'testvphooks.cpp', -] + binary.sources += [ + 'main.cpp', + '../sourcehook.cpp', + '../sourcehook_impl_chookmaninfo.cpp', + '../sourcehook_impl_chookidman.cpp', + '../sourcehook_impl_cproto.cpp', + '../sourcehook_impl_cvfnptr.cpp', + 'test1.cpp', + 'test2.cpp', + 'test3.cpp', + 'test4.cpp', + 'testbail.cpp', + 'testbail2.cpp', + 'testhookmangen.cpp', + 'testlist.cpp', + 'testmanual.cpp', + 'testmulti.cpp', + 'testoddthunks.cpp', + 'testrecall.cpp', + 'testreentr.cpp', + 'testref.cpp', + 'testrefret.cpp', + 'testvphooks.cpp', + ] + if arch == 'x86': + binary.sources += ['../sourcehook_hookmangen.cpp'] -builder.Add(binary) + builder.Add(binary) diff --git a/core/sourcehook/test/main.cpp b/core/sourcehook/test/main.cpp index 2db137c..a04f39c 100644 --- a/core/sourcehook/test/main.cpp +++ b/core/sourcehook/test/main.cpp @@ -78,7 +78,7 @@ 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 +#if !defined( _M_AMD64 ) && !defined( __amd64__ ) && !defined(__x86_64__) // TODO: Fix for 64-bit DO_TEST(HookManGen); #endif DO_TEST(OddThunks); @@ -128,6 +128,7 @@ void Test_UnpausePlugin(SourceHook::ISourceHook *shptr, SourceHook::Plugin plug) static_cast(shptr)->UnpausePlugin(plug); } +#if !defined( _M_AMD64 ) && !defined( __amd64__ ) && !defined(__x86_64__) SourceHook::IHookManagerAutoGen *Test_HMAG_Factory(SourceHook::ISourceHook *shptr) { return new SourceHook::Impl::CHookManagerAutoGen(shptr); @@ -137,4 +138,5 @@ void Test_HMAG_Delete(SourceHook::IHookManagerAutoGen *ptr) { delete static_cast(ptr); } +#endif diff --git a/core/sourcehook/test/testhookmangen.cpp b/core/sourcehook/test/testhookmangen.cpp index bab1859..02715d3 100644 --- a/core/sourcehook/test/testhookmangen.cpp +++ b/core/sourcehook/test/testhookmangen.cpp @@ -1093,7 +1093,7 @@ namespace } } - +#if !defined( _M_AMD64 ) && !defined( __amd64__ ) && !defined(__x86_64__) bool TestHookManGen(std::string &error) { GET_SHPTR(g_SHPtr); @@ -1133,6 +1133,7 @@ bool TestHookManGen(std::string &error) return true; } +#endif bool TestCPageAlloc(std::string &error) {