diff --git a/core-legacy/sourcehook/sh_list.h b/core-legacy/sourcehook/sh_list.h index b672361..700a7a6 100644 --- a/core-legacy/sourcehook/sh_list.h +++ b/core-legacy/sourcehook/sh_list.h @@ -12,7 +12,7 @@ #define _INCLUDE_SMM_LIST_H #include -#include +#include namespace SourceHook { diff --git a/core-legacy/sourcehook/sh_memory.h b/core-legacy/sourcehook/sh_memory.h index d2d3531..0e185e8 100644 --- a/core-legacy/sourcehook/sh_memory.h +++ b/core-legacy/sourcehook/sh_memory.h @@ -16,12 +16,12 @@ // Unprotect now sets to readwrite // The vtable doesn't need to be executable anyway -# if /********/ defined _WIN32 +# if SH_XP == SH_XP_WINAPI # include # define SH_MEM_READ 1 # define SH_MEM_WRITE 2 # define SH_MEM_EXEC 4 -# elif /******/ defined __linux__ +# elif SH_XP == SH_XP_POSIX # include # include # include @@ -48,7 +48,7 @@ namespace SourceHook { inline bool SetMemAccess(void *addr, size_t len, int access) { -# ifdef __linux__ +# if SH_XP == SH_XP_POSIX return mprotect(SH_LALIGN(addr), len + SH_LALDIF(addr), access)==0 ? true : false; # else DWORD tmp; @@ -69,17 +69,25 @@ namespace SourceHook # endif } -#ifdef __linux__ +#if SH_XP == SH_XP_POSIX namespace { bool g_BadReadCalled; jmp_buf g_BadReadJmpBuf; +# if SH_SYS == SH_SYS_LINUX static void BadReadHandler(int sig) { if (g_BadReadCalled) longjmp(g_BadReadJmpBuf, 1); } +# elif SH_SYS == SH_SYS_APPLE + static void BadReadHandler(int signal, siginfo_t* my_siginfo, void* my_context) + { + if (g_BadReadCalled) + longjmp(g_BadReadJmpBuf, 1); + } +# endif } #endif @@ -93,7 +101,7 @@ namespace SourceHook { bool ModuleInMemory(char *addr, size_t len) { -#ifdef __linux__ +#if SH_SYS == SH_SYS_LINUX // On linux, first check /proc/self/maps long lower = reinterpret_cast(addr); long upper = lower + len; @@ -175,7 +183,29 @@ namespace SourceHook signal(SIGSEGV, prevHandler); return false; -#else +#elif SH_SYS == SH_SYS_APPLE + struct sigaction sa, osa; + sa.sa_sigaction = BadReadHandler; + sa.sa_flags = SA_SIGINFO | SA_RESTART; + + g_BadReadCalled = true; + + if (setjmp(g_BadReadJmpBuf)) + return false; + + if (sigaction(SIGBUS, &sa, &osa) == -1) + return false; + + volatile const char *p = reinterpret_cast(addr); + char dummy; + + for (size_t i = 0; i < len; i++) + dummy = p[i]; + + g_BadReadCalled = false; + + return true; +#elif SH_SYS == SH_SYS_WINAPI // On Win32, simply use IsBadReadPtr return !IsBadReadPtr(addr, len); #endif diff --git a/core-legacy/sourcehook/sourcehook.h b/core-legacy/sourcehook/sourcehook.h index 92ff0c0..1958bd8 100644 --- a/core-legacy/sourcehook/sourcehook.h +++ b/core-legacy/sourcehook/sourcehook.h @@ -61,11 +61,21 @@ // System #define SH_SYS_WIN32 1 #define SH_SYS_LINUX 2 +#define SH_SYS_APPLE 3 + +// OS +#define SH_XP_POSIX 10 +#define SH_XP_WINAPI 20 #ifdef _WIN32 # define SH_SYS SH_SYS_WIN32 +# define SH_XP SH_XP_WINAPI #elif defined __linux__ # define SH_SYS SH_SYS_LINUX +# define SH_XP SH_XP_POSIX +#elif defined __APPLE__ +# define SH_SYS SH_SYS_APPLE +# define SH_XP SH_XP_POSIX #else # error Unsupported system #endif