1
0
mirror of https://github.com/alliedmodders/metamod-source.git synced 2025-02-21 14:54:14 +01:00

Fix detection of Blade Symphony on Windows x64 (#67)

* Fix detection of Blade Symphony on Windows x64

Port finding the module base address on x64 builds from SourceMod.
Fix a bunch of truncation warnings on x64 while at it too.

* Fix mm_TrimComments stripping last char before comment

```c
char test[] = "hi this is a a test!// comment";
mm_TrimComments(test);
puts(test); // prints "hi this is a test" without the !
```

* Fix unsigned comparison warnings

* Fix truncation warnings in SourceHook::String

* Fix unsigned comparison warnings

clang does have some nice analysis.
This commit is contained in:
peace-maker 2020-06-25 02:04:36 +02:00 committed by GitHub
parent a919db5694
commit b267567e50
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 104 additions and 80 deletions

View File

@ -206,7 +206,7 @@ namespace SourceMM
* @return The newly incremented iface version number. * @return The newly incremented iface version number.
* @deprecated Use InterfaceSearch() or VInterfaceMatch instead. * @deprecated Use InterfaceSearch() or VInterfaceMatch instead.
*/ */
virtual int FormatIface(char iface[], unsigned int maxlength) =0; virtual int FormatIface(char iface[], size_t maxlength) =0;
/** /**
* @brief Searches for an interface, eliminating the need to loop * @brief Searches for an interface, eliminating the need to loop

View File

@ -792,13 +792,13 @@ void MetamodSource::GetShVersions(int &shvers, int &shimpl)
shimpl = SH_IMPL_VERSION; shimpl = SH_IMPL_VERSION;
} }
int MetamodSource::FormatIface(char iface[], unsigned int maxlength) int MetamodSource::FormatIface(char iface[], size_t maxlength)
{ {
int length = (int)strlen(iface); size_t length = strlen(iface);
int i; size_t i;
int num = 0; int num = 0;
for (i = length - 1; i >= 0; i--) for (i = length - 1; i + 1 > 0; i--)
{ {
if (!isdigit(iface[i])) if (!isdigit(iface[i]))
{ {
@ -810,7 +810,7 @@ int MetamodSource::FormatIface(char iface[], unsigned int maxlength)
} }
} }
if ( (num && ((int)maxlength <= length)) || (!num && ((int)maxlength <= length + 3)) ) if ( (num && (maxlength <= length)) || (!num && (maxlength <= length + 3)) )
{ {
return -1; return -1;
} }

View File

@ -72,7 +72,7 @@ public:
void GetShVersions(int &shvers, int &shimpl); void GetShVersions(int &shvers, int &shimpl);
void AddListener(ISmmPlugin *plugin, IMetamodListener *pListener); void AddListener(ISmmPlugin *plugin, IMetamodListener *pListener);
void *MetaFactory(const char *iface, int *ret, PluginId *id); void *MetaFactory(const char *iface, int *ret, PluginId *id);
int FormatIface(char iface[], unsigned int maxlength); int FormatIface(char iface[], size_t maxlength);
void *InterfaceSearch(CreateInterfaceFn fn, const char *iface, int max, int *ret); void *InterfaceSearch(CreateInterfaceFn fn, const char *iface, int max, int *ret);
const char *GetBaseDir(); const char *GetBaseDir();
size_t PathFormat(char *buffer, size_t len, const char *fmt, ...); size_t PathFormat(char *buffer, size_t len, const char *fmt, ...);

View File

@ -184,7 +184,7 @@ bool Command_Meta(IMetamodSourceCommandInfo *info)
const char *plname; const char *plname;
PluginIter i; PluginIter i;
char buffer[256]; char buffer[256];
int len; size_t len;
int plnum = g_PluginMngr.GetPluginCount(); int plnum = g_PluginMngr.GetPluginCount();
if (!plnum) if (!plnum)
@ -688,7 +688,7 @@ bool Command_ClientMeta(edict_t *client, IMetamodSourceCommandInfo *info)
const char *plname; const char *plname;
PluginIter i; PluginIter i;
char buffer[256]; char buffer[256];
int len = 0; size_t len = 0;
int plnum = 0; int plnum = 0;
for (i = g_PluginMngr._begin(); i != g_PluginMngr._end(); i++, len=0) for (i = g_PluginMngr._begin(); i != g_PluginMngr._end(); i++, len=0)

View File

@ -81,7 +81,7 @@ bool GetFileOfAddress(void *pAddr, char *buffer, size_t maxlength)
if (mem.AllocationBase == NULL) if (mem.AllocationBase == NULL)
return false; return false;
HMODULE dll = (HMODULE)mem.AllocationBase; HMODULE dll = (HMODULE)mem.AllocationBase;
GetModuleFileName(dll, (LPTSTR)buffer, maxlength); GetModuleFileName(dll, (LPTSTR)buffer, static_cast<DWORD>(maxlength));
#elif defined __linux__ || defined __APPLE__ #elif defined __linux__ || defined __APPLE__
Dl_info info; Dl_info info;
if (!dladdr(pAddr, &info)) if (!dladdr(pAddr, &info))

View File

@ -38,10 +38,10 @@
const char *UTIL_GetExtension(const char *file) const char *UTIL_GetExtension(const char *file)
{ {
int len = strlen(file); size_t len = strlen(file);
int i = 0; size_t i = 0;
for (i = len - 1; i >= 0; i--) for (i = len - 1; i + 1 > 0; i--)
{ {
if (file[i] == '/' || file[i] == '\\') if (file[i] == '/' || file[i] == '\\')
{ {

View File

@ -134,14 +134,14 @@ public:
return 0; return 0;
} }
int find(const char c, int index = 0) const size_t find(const char c, size_t index = 0) const
{ {
int len = static_cast<int>(size()); size_t len = size();
if (len < 1) if (len < 1)
return npos; return npos;
if (index >= len || index < 0) if (index >= len)
return npos; return npos;
int i = 0; size_t i = 0;
for (i=index; i<len; i++) for (i=index; i<len; i++)
{ {
if (v[i] == c) if (v[i] == c)
@ -153,20 +153,20 @@ public:
return npos; return npos;
} }
int find_last_of(const char c, int index = npos) const size_t find_last_of(const char c, size_t index = npos) const
{ {
int len = static_cast<int>(size()); size_t len = size();
if (len < 1) if (len < 1)
return npos; return npos;
if (index >= len || index < npos) if (index >= len)
return npos; return npos;
int i; size_t i;
if (index == npos) if (index == npos)
i = len - 1; i = len - 1;
else else
i = index; i = index;
for (; i>=0; i--) for (; i+1>0; i--)
{ {
if (v[i] == c) if (v[i] == c)
{ {
@ -194,8 +194,8 @@ public:
if (!v) if (!v)
return; return;
unsigned int i = 0; size_t i = 0;
unsigned int j = 0; size_t j = 0;
size_t len = strlen(v); size_t len = strlen(v);
if (len == 1) if (len == 1)
@ -213,7 +213,7 @@ public:
{ {
for (i=0; i<len; i++) for (i=0; i<len; i++)
{ {
if (!is_space(v[i]) || (is_space(v[i]) && ((unsigned char)i==len-1))) if (!is_space(v[i]) || (is_space(v[i]) && (i==len-1)))
{ {
erase(0, i); erase(0, i);
break; break;
@ -252,11 +252,11 @@ public:
} }
} }
void erase(unsigned int start, int num = npos) void erase(size_t start, size_t num = npos)
{ {
if (!v) if (!v)
return; return;
unsigned int i = 0; size_t i = 0;
size_t len = size(); size_t len = size();
//check for bounds //check for bounds
if (num == npos || start+num > len-start) if (num == npos || start+num > len-start)
@ -287,7 +287,7 @@ public:
v[len] = 0; v[len] = 0;
} }
String substr(unsigned int index, int num = npos) const String substr(size_t index, size_t num = npos) const
{ {
if (!v) if (!v)
{ {
@ -309,8 +309,8 @@ public:
num = len - index; num = len - index;
} }
unsigned int i = 0; size_t i = 0;
unsigned int nslen = num + 2; size_t nslen = num + 2;
ns.Grow(nslen); ns.Grow(nslen);
@ -324,7 +324,7 @@ public:
{ {
if (!v) if (!v)
return; return;
unsigned int i = 0; size_t i = 0;
size_t len = strlen(v); size_t len = strlen(v);
for (i=0; i<len; i++) for (i=0; i<len; i++)
{ {
@ -346,9 +346,9 @@ public:
} }
char operator [] (unsigned int index) const char operator [] (size_t index) const
{ {
if (index > size() || !v) if (index >= size() || !v)
{ {
return -1; return -1;
} else { } else {
@ -356,17 +356,17 @@ public:
} }
} }
int at(int a) const int at(size_t a) const
{ {
if (a < 0 || a >= (int)size() || !v) if (a >= size() || !v)
return -1; return -1;
return v[a]; return v[a];
} }
bool at(int at, char c) bool at(size_t at, char c)
{ {
if (at < 0 || at >= (int)size() || !v) if (at >= size() || !v)
return false; return false;
v[at] = c; v[at] = c;
@ -375,7 +375,7 @@ public:
} }
private: private:
void Grow(unsigned int d, bool copy=true) void Grow(size_t d, bool copy=true)
{ {
if (d <= a_size) if (d <= a_size)
return; return;
@ -385,15 +385,15 @@ private:
if (v) if (v)
delete [] v; delete [] v;
else else
strcpy(n, ""); strcpy(n, "");
v = n; v = n;
a_size = d + 1; a_size = d + 1;
} }
char *v; char *v;
unsigned int a_size; size_t a_size;
public: public:
static const int npos = -1; static const size_t npos = static_cast<size_t>(-1);
}; };
}; //NAMESPACE }; //NAMESPACE

View File

@ -2,6 +2,7 @@
#include "sourcehook.h" #include "sourcehook.h"
#include "sourcehook_test.h" #include "sourcehook_test.h"
#include "testevents.h" #include "testevents.h"
#include <ctime>
// TEST VP HOOKS // TEST VP HOOKS
// Test vfnptr-wide hooks // Test vfnptr-wide hooks

View File

@ -54,7 +54,7 @@ mm_GetPlatformError(char *buffer, size_t maxlength)
dw, dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPSTR)buffer, (LPSTR)buffer,
maxlength, static_cast<DWORD>(maxlength),
NULL); NULL);
} }
#endif #endif
@ -148,33 +148,24 @@ mm_TrimRight(char *buffer)
void void
mm_TrimComments(char *buffer) mm_TrimComments(char *buffer)
{ {
int num_sc = 0;
size_t len = strlen(buffer);
if (buffer) if (buffer)
{ {
for (int i = len - 1; i >= 0; i--) int num_sc = 0;
size_t len = strlen(buffer);
for (size_t i = 0; i < len; i++)
{ {
if (buffer[i] == '/') if (buffer[i] == '/')
{ {
if (++num_sc >= 2 && i==0) if (++num_sc >= 2)
{ {
buffer[i] = '\0'; buffer[i-1] = '\0';
return; return;
} }
} }
else else
{ {
if (num_sc >= 2)
{
buffer[i] = '\0';
return;
}
num_sc = 0; num_sc = 0;
} }
/* size_t won't go below 0, manually break out */
if (i == 0)
break;
} }
} }
} }
@ -371,7 +362,7 @@ mm_GetFileOfAddress(void *pAddr, char *buffer, size_t maxlength)
if (mem.AllocationBase == NULL) if (mem.AllocationBase == NULL)
return false; return false;
HMODULE dll = (HMODULE)mem.AllocationBase; HMODULE dll = (HMODULE)mem.AllocationBase;
GetModuleFileName(dll, (LPTSTR)buffer, maxlength); GetModuleFileName(dll, (LPTSTR)buffer, static_cast<DWORD>(maxlength));
#elif defined __linux__ || defined __APPLE__ #elif defined __linux__ || defined __APPLE__
Dl_info info; Dl_info info;
if (!dladdr(pAddr, &info)) if (!dladdr(pAddr, &info))
@ -402,6 +393,14 @@ mm_GetLibraryInfo(const void *libPtr, DynLibInfo &lib)
#ifdef _WIN32 #ifdef _WIN32
#ifdef _M_X64
const WORD PE_FILE_MACHINE = IMAGE_FILE_MACHINE_AMD64;
const WORD PE_NT_OPTIONAL_HDR_MAGIC = IMAGE_NT_OPTIONAL_HDR64_MAGIC;
#else
const WORD PE_FILE_MACHINE = IMAGE_FILE_MACHINE_I386;
const WORD PE_NT_OPTIONAL_HDR_MAGIC = IMAGE_NT_OPTIONAL_HDR32_MAGIC;
#endif
MEMORY_BASIC_INFORMATION info; MEMORY_BASIC_INFORMATION info;
IMAGE_DOS_HEADER *dos; IMAGE_DOS_HEADER *dos;
IMAGE_NT_HEADERS *pe; IMAGE_NT_HEADERS *pe;
@ -422,15 +421,13 @@ mm_GetLibraryInfo(const void *libPtr, DynLibInfo &lib)
opt = &pe->OptionalHeader; opt = &pe->OptionalHeader;
/* Check PE magic and signature */ /* Check PE magic and signature */
if (dos->e_magic != IMAGE_DOS_SIGNATURE || pe->Signature != IMAGE_NT_SIGNATURE || opt->Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC) if (dos->e_magic != IMAGE_DOS_SIGNATURE || pe->Signature != IMAGE_NT_SIGNATURE || opt->Magic != PE_NT_OPTIONAL_HDR_MAGIC)
{ {
return false; return false;
} }
/* Check architecture, which is 32-bit/x86 right now /* Check architecture */
* Should change this for 64-bit if Valve gets their act together if (file->Machine != PE_FILE_MACHINE)
*/
if (file->Machine != IMAGE_FILE_MACHINE_I386)
{ {
return false; return false;
} }
@ -446,9 +443,21 @@ mm_GetLibraryInfo(const void *libPtr, DynLibInfo &lib)
#elif defined __linux__ #elif defined __linux__
#ifdef __x86_64__
typedef Elf64_Ehdr ElfHeader;
typedef Elf64_Phdr ElfPHeader;
const unsigned char ELF_CLASS = ELFCLASS64;
const uint16_t ELF_MACHINE = EM_X86_64;
#else
typedef Elf32_Ehdr ElfHeader;
typedef Elf32_Phdr ElfPHeader;
const unsigned char ELF_CLASS = ELFCLASS32;
const uint16_t ELF_MACHINE = EM_386;
#endif
Dl_info info; Dl_info info;
Elf32_Ehdr *file; ElfHeader *file;
Elf32_Phdr *phdr; ElfPHeader *phdr;
uint16_t phdrCount; uint16_t phdrCount;
if (!dladdr(libPtr, &info)) if (!dladdr(libPtr, &info))
@ -463,7 +472,7 @@ mm_GetLibraryInfo(const void *libPtr, DynLibInfo &lib)
/* This is for our insane sanity checks :o */ /* This is for our insane sanity checks :o */
baseAddr = reinterpret_cast<uintptr_t>(info.dli_fbase); baseAddr = reinterpret_cast<uintptr_t>(info.dli_fbase);
file = reinterpret_cast<Elf32_Ehdr *>(baseAddr); file = reinterpret_cast<ElfHeader *>(baseAddr);
/* Check ELF magic */ /* Check ELF magic */
if (memcmp(ELFMAG, file->e_ident, SELFMAG) != 0) if (memcmp(ELFMAG, file->e_ident, SELFMAG) != 0)
@ -477,10 +486,8 @@ mm_GetLibraryInfo(const void *libPtr, DynLibInfo &lib)
return false; return false;
} }
/* Check ELF architecture, which is 32-bit/x86 right now /* Check ELF architecture */
* Should change this for 64-bit if Valve gets their act together if (file->e_ident[EI_CLASS] != ELF_CLASS || file->e_machine != ELF_MACHINE || file->e_ident[EI_DATA] != ELFDATA2LSB)
*/
if (file->e_ident[EI_CLASS] != ELFCLASS32 || file->e_machine != EM_386 || file->e_ident[EI_DATA] != ELFDATA2LSB)
{ {
return false; return false;
} }
@ -492,11 +499,11 @@ mm_GetLibraryInfo(const void *libPtr, DynLibInfo &lib)
} }
phdrCount = file->e_phnum; phdrCount = file->e_phnum;
phdr = reinterpret_cast<Elf32_Phdr *>(baseAddr + file->e_phoff); phdr = reinterpret_cast<ElfPHeader *>(baseAddr + file->e_phoff);
for (uint16_t i = 0; i < phdrCount; i++) for (uint16_t i = 0; i < phdrCount; i++)
{ {
Elf32_Phdr &hdr = phdr[i]; ElfPHeader &hdr = phdr[i];
/* We only really care about the segment with executable code */ /* We only really care about the segment with executable code */
if (hdr.p_type == PT_LOAD && hdr.p_flags == (PF_X|PF_R)) if (hdr.p_type == PT_LOAD && hdr.p_flags == (PF_X|PF_R))
@ -515,9 +522,25 @@ mm_GetLibraryInfo(const void *libPtr, DynLibInfo &lib)
#elif defined __APPLE__ #elif defined __APPLE__
#ifdef __x86_64__
typedef struct mach_header_64 MachHeader;
typedef struct segment_command_64 MachSegment;
const uint32_t MACH_MAGIC = MH_MAGIC_64;
const uint32_t MACH_LOADCMD_SEGMENT = LC_SEGMENT_64;
const cpu_type_t MACH_CPU_TYPE = CPU_TYPE_X86_64;
const cpu_subtype_t MACH_CPU_SUBTYPE = CPU_SUBTYPE_X86_64_ALL;
#else
typedef struct mach_header MachHeader;
typedef struct segment_command MachSegment;
const uint32_t MACH_MAGIC = MH_MAGIC;
const uint32_t MACH_LOADCMD_SEGMENT = LC_SEGMENT;
const cpu_type_t MACH_CPU_TYPE = CPU_TYPE_I386;
const cpu_subtype_t MACH_CPU_SUBTYPE = CPU_SUBTYPE_I386_ALL;
#endif
Dl_info info; Dl_info info;
struct mach_header *file; MachHeader *file;
struct segment_command *seg; MachSegment *seg;
uint32_t cmd_count; uint32_t cmd_count;
if (!dladdr(libPtr, &info)) if (!dladdr(libPtr, &info))
@ -532,16 +555,16 @@ mm_GetLibraryInfo(const void *libPtr, DynLibInfo &lib)
/* This is for our insane sanity checks :o */ /* This is for our insane sanity checks :o */
baseAddr = (uintptr_t)info.dli_fbase; baseAddr = (uintptr_t)info.dli_fbase;
file = (struct mach_header *)baseAddr; file = (MachHeader *)baseAddr;
/* Check Mach-O magic */ /* Check Mach-O magic */
if (file->magic != MH_MAGIC) if (file->magic != MACH_MAGIC)
{ {
return false; return false;
} }
/* Check architecture (32-bit/x86) */ /* Check architecture */
if (file->cputype != CPU_TYPE_I386 || file->cpusubtype != CPU_SUBTYPE_I386_ALL) if (file->cputype != MACH_CPU_TYPE || file->cpusubtype != MACH_CPU_SUBTYPE)
{ {
return false; return false;
} }
@ -553,17 +576,17 @@ mm_GetLibraryInfo(const void *libPtr, DynLibInfo &lib)
} }
cmd_count = file->ncmds; cmd_count = file->ncmds;
seg = (struct segment_command *)(baseAddr + sizeof(struct mach_header)); seg = (MachSegment *)(baseAddr + sizeof(MachHeader));
/* Add up memory sizes of mapped segments */ /* Add up memory sizes of mapped segments */
for (uint32_t i = 0; i < cmd_count; i++) for (uint32_t i = 0; i < cmd_count; i++)
{ {
if (seg->cmd == LC_SEGMENT) if (seg->cmd == MACH_LOADCMD_SEGMENT)
{ {
lib.memorySize += seg->vmsize; lib.memorySize += seg->vmsize;
} }
seg = (struct segment_command *)((uintptr_t)seg + seg->cmdsize); seg = (MachSegment *)((uintptr_t)seg + seg->cmdsize);
} }
#endif #endif