From 1ce7a7d3862bed06e27ffbafb92dac6a26bfba7b Mon Sep 17 00:00:00 2001 From: salmonik Date: Tue, 3 Nov 2026 22:33:56 +0100 Subject: Fix startup crash: use ClientCmd for fullbright; sanitize owner netvars - Poking VEngineCvar004/ConVar vtables directly crashed before the main menu (ConVar uses a secondary IConVar vtable). Use the stable IVEngineClient ClientCmd slot 7 for mat_fullbright instead. - Reject out-of-range m_hOwnerEntity/m_hOwner offsets: the resolver found a bogus negative owner offset (-136296061), which could make item-ESP weapon ownership read wild memory. --- src/hl2h.cpp | 34 +++++++++------------------------- src/netvars.cpp | 8 ++++++-- 2 files changed, 15 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/hl2h.cpp b/src/hl2h.cpp index ebb9b14..375cd5a 100644 --- a/src/hl2h.cpp +++ b/src/hl2h.cpp @@ -131,32 +131,16 @@ static int g_modified_logged = 0; // GetName, GetHelpText, IsRegistered, GetDLLIdentifier; ConVar then adds // SetValue(const char*), SetValue(float), SetValue(int) -> slot 11. bool cvar_set_int(const char *name, int value) { - if (!name) + if (!name || !g_iface.engine) return false; - if (g_iface.cvar) { - using FindVarFn = void *(*)(void *, const char *); - void *var = vfunc(g_iface.cvar, 12)(g_iface.cvar, name); - if (var) { - using GetNameFn = const char *(*)(void *); - const char *got = vfunc(var, 5)(var); - if (got && strcmp(got, name) == 0) { - using SetIntFn = void (*)(void *, int); - vfunc(var, 11)(var, value); - return true; - } - } - } - // Fallback for an engine that does not expose VEngineCvar004: ClientCmd - // slot 7. Cheat-protected cvars may still be rejected. - if (g_iface.engine) { - char cmd[96]; - snprintf(cmd, sizeof(cmd), "%s %d", name, value); - using CmdFn = void (*)(void *, const char *); - vfunc(g_iface.engine, 7)(g_iface.engine, cmd); - logd("cvar: fallback command '%s'", cmd); - return true; - } - return false; + // Use the stable IVEngineClient ClientCmd slot rather than poking ConVar's + // vtable; the installed VEngineCvar004 layout differs enough to crash. + char cmd[96]; + snprintf(cmd, sizeof(cmd), "%s %d", name, value); + using CmdFn = void (*)(void *, const char *); + vfunc(g_iface.engine, 7)(g_iface.engine, cmd); + logd("cvar: command '%s'", cmd); + return true; } void note_modified(const CUserCmd *cmd, int flags, const float *vel) { diff --git a/src/netvars.cpp b/src/netvars.cpp index adb5a6a..834aa2f 100644 --- a/src/netvars.cpp +++ b/src/netvars.cpp @@ -93,9 +93,13 @@ static void collect_netvars(uintptr_t table, uintptr_t base_off, int depth) { g_net.activeweapon < 0) { g_net.activeweapon = (int)(base_off + (uint32_t)poff); } else if (strcmp(pname2, "m_hOwnerEntity") == 0 && g_net.owner < 0) { - g_net.owner = (int)(base_off + (uint32_t)poff); + int off = (int)(base_off + (uint32_t)poff); + if (off > 0 && off < 0x2000) + g_net.owner = off; } else if (strcmp(pname2, "m_hOwner") == 0 && g_net.weapon_owner < 0) { - g_net.weapon_owner = (int)(base_off + (uint32_t)poff); + int off = (int)(base_off + (uint32_t)poff); + if (off > 0 && off < 0x2000) + g_net.weapon_owner = off; } else if (strcmp(pname2, "m_iTeamNum") == 0 && g_net.teamnum < 0) { g_net.teamnum = (int)(base_off + (uint32_t)poff); } else if (strcmp(pname2, "m_vecOrigin") == 0 && g_net.origin < 0) { -- cgit v1.2.3