diff options
-rw-r--r-- | NorthstarDLL/exploitfixes.cpp | 59 |
1 files changed, 34 insertions, 25 deletions
diff --git a/NorthstarDLL/exploitfixes.cpp b/NorthstarDLL/exploitfixes.cpp index de60a854..2a5f02f3 100644 --- a/NorthstarDLL/exploitfixes.cpp +++ b/NorthstarDLL/exploitfixes.cpp @@ -114,36 +114,19 @@ bool, __fastcall, (void* pMsg)) // 48 8B D1 48 8B 49 18 48 8B 01 48 FF 60 10 if (!nameValid || !valValid) return BLOCKED_INFO("Missing null terminators"); - auto realVar = R2::g_pCVar->FindVar(entry->name); + ConVar* pVar = R2::g_pCVar->FindVar(entry->name); - if (realVar) + if (pVar) + { memcpy( entry->name, - realVar->m_ConCommandBase.m_pszName, - strlen(realVar->m_ConCommandBase.m_pszName) + 1); // Force name to match case + pVar->m_ConCommandBase.m_pszName, + strlen(pVar->m_ConCommandBase.m_pszName) + 1); // Force name to match case - bool isValidFlags = true; - if (bIsServerFrame) - { - if (realVar) - isValidFlags = realVar->IsFlagSet(FCVAR_USERINFO); // ConVar MUST be userinfo var - } - else - { - // TODO: Should probably have some sanity checks, but can't find any that are consistent - } - - if (!isValidFlags) - { - if (!realVar) - { - return BLOCKED_INFO("Invalid flags on nonexistant cvar (how tho???)"); - } - else - { + int iFlags = bIsServerFrame ? FCVAR_USERINFO : FCVAR_REPLICATED; + if (!pVar->IsFlagSet(iFlags)) return BLOCKED_INFO( - "Invalid flags (" << std::hex << "0x" << realVar->m_ConCommandBase.m_nFlags << "), var is " << entry->name); - } + "Invalid flags (" << std::hex << "0x" << pVar->m_ConCommandBase.m_nFlags << "), var is " << entry->name); } } else @@ -388,6 +371,32 @@ void*, __fastcall, (int i)) return GetEntByIndex(i); } +// clang-format off +AUTOHOOK(CL_CopyExistingEntity, engine.dll + 0x6F940, +bool, __fastcall, (void* a1)) +// clang-format on +{ + struct CEntityReadInfo + { + BYTE gap[40]; + int nNewEntity; + }; + + CEntityReadInfo* pReadInfo = (CEntityReadInfo*)a1; + if (pReadInfo->nNewEntity >= 0x1000 || pReadInfo->nNewEntity < 0) + { + // Value isn't sanitized in release builds for + // every game powered by the Source Engine 1 + // causing read/write outside of array bounds. + // This defect has let to the achievement of a + // full-chain RCE exploit. We hook and perform + // sanity checks for the value of m_nNewEntity + // here to prevent this behavior from happening. + return false; + } + + return CL_CopyExistingEntity(a1); +} ON_DLL_LOAD("engine.dll", EngineExploitFixes, (CModule module)) { |