aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NorthstarDLL/exploitfixes.cpp59
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))
{