Skip to content

Commit 5b7fe14

Browse files
committed
Fix crash and reworked find_memloc
1 parent 1be6696 commit 5b7fe14

5 files changed

Lines changed: 40 additions & 11 deletions

File tree

metamod/src/mlist.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,9 @@ MPlugin* MPluginList::find(const char* findpath)
8686
// Find a plugin that uses the given memory location.
8787
MPlugin* MPluginList::find_memloc(void* memptr)
8888
{
89-
for (auto p : m_plugins) {
90-
if (p->m_sys_module.load(memptr))
91-
return p;
89+
module_handle_t ptr = CSysModule::find(memptr);
90+
if (ptr != CSysModule::INVALID_HANDLE) {
91+
return find(ptr);
9292
}
9393

9494
return nullptr;

metamod/src/mreg.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#include "precompiled.h"
22

3-
MRegCmd::MRegCmd(const char* cmd_name, REG_CMD_FN cmd_handler, MPlugin* cmd_plugin) : m_pfunction(cmd_handler), m_plugid(cmd_plugin->index()), m_status(RG_VALID)
3+
MRegCmd::MRegCmd(const char* cmd_name, REG_CMD_FN cmd_handler, MPlugin* cmd_plugin) : m_pfunction(cmd_handler), m_plugid(cmd_plugin ? cmd_plugin->index() : 0), m_status(RG_VALID)
44
{
55
m_name = Q_strdup(cmd_name);
66
}

metamod/src/reg_support.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,7 @@ void EXT_FUNC meta_AddServerCommand(const char* cmd_name, void (*function)())
3131
META_DEBUG(4, "called: meta_AddServerCommand; cmd_name=%s, function=%d, plugin=%s", cmd_name, function, plug ? plug->file() : "unknown");
3232

3333
if (!plug) {
34-
META_ERROR("Failed to find memloc for regcmd '%s'", cmd_name);
35-
return;
34+
META_WARNING("Failed to find memloc for regcmd '%s'", cmd_name);
3635
}
3736

3837
// See if this command was previously registered, ie a "reloaded" plugin.
@@ -64,13 +63,11 @@ void EXT_FUNC meta_CVarRegister(cvar_t* pCvar)
6463

6564
// try to find which plugin is registering this cvar
6665
if (!plug) {
67-
META_ERROR("Failed to find memloc for regcvar '%s'", pCvar->name);
68-
return;
66+
META_WARNING("Failed to find memloc for regcvar '%s'", pCvar->name);
6967
}
7068

7169
// See if this cvar was previously registered, ie a "reloaded" plugin.
7270
auto reg = g_regCvars->find(pCvar->name);
73-
7471
if (!reg) {
7572
reg = g_regCvars->add(pCvar, plug);
7673
CVAR_REGISTER(reg->getcvar());
@@ -89,7 +86,6 @@ void EXT_FUNC meta_CVarRegister(cvar_t* pCvar)
8986
// commands) nor any useful actions to perform upon plugin unload (like the
9087
// commands and cvars). This merely provides differently located storage
9188
// for the string.
92-
9389
int EXT_FUNC meta_RegUserMsg(const char* pszName, int iSize)
9490
{
9591
char* cp = Q_strdup(pszName);

metamod/src/sys_module.cpp

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,14 @@ char *CSysModule::find_pattern(char *pos, int range, const char *pattern, size_t
3131
module_handle_t CSysModule::load(void *addr)
3232
{
3333
MEMORY_BASIC_INFORMATION mem;
34-
VirtualQuery(addr, &mem, sizeof(mem));
34+
if (!VirtualQuery(addr, &mem, sizeof(mem)))
35+
return INVALID_HANDLE;
36+
37+
if (mem.State != MEM_COMMIT)
38+
return INVALID_HANDLE;
39+
40+
if (!mem.AllocationBase)
41+
return INVALID_HANDLE;
3542

3643
IMAGE_DOS_HEADER *dos = (IMAGE_DOS_HEADER *)mem.AllocationBase;
3744
IMAGE_NT_HEADERS *pe = (IMAGE_NT_HEADERS *)((uintptr_t)dos + (uintptr_t)dos->e_lfanew);
@@ -47,6 +54,16 @@ module_handle_t CSysModule::load(void *addr)
4754
return m_handle;
4855
}
4956

57+
module_handle_t CSysModule::find(void *addr)
58+
{
59+
module_handle_t hHandle = INVALID_HANDLE;
60+
if (!GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT | GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, reinterpret_cast<LPCTSTR>(addr), &hHandle)) {
61+
return INVALID_HANDLE;
62+
}
63+
64+
return hHandle;
65+
}
66+
5067
module_handle_t CSysModule::load(const char *filepath)
5168
{
5269
if (!m_handle) {
@@ -121,6 +138,21 @@ module_handle_t CSysModule::load(void *addr)
121138
return m_handle;
122139
}
123140

141+
module_handle_t CSysModule::find(void *addr)
142+
{
143+
Dl_info dlinfo;
144+
if ((!dladdr(addr, &dlinfo) && !dlinfo.dli_fbase) || !dlinfo.dli_fname) {
145+
return false;
146+
}
147+
148+
module_handle_t hHandle = INVALID_HANDLE;
149+
if (!(hHandle = dlopen(dlinfo.dli_fname, RTLD_NOW | RTLD_NOLOAD))) {
150+
return INVALID_HANDLE;
151+
}
152+
153+
return hHandle;
154+
}
155+
124156
module_handle_t CSysModule::load(const char *filepath)
125157
{
126158
if (!m_handle) {

metamod/src/sys_module.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class CSysModule
2424
char *find_string_push(const char *string);
2525
char *find_pattern(char *pos, int range, const char *pattern, size_t len);
2626

27+
static module_handle_t find(void *addr);
2728
static const char *getloaderror();
2829
static const module_handle_t INVALID_HANDLE;
2930

0 commit comments

Comments
 (0)