From b84cd76f671e44a686df6f2b36be6642b0bd24a5 Mon Sep 17 00:00:00 2001 From: Tom Barham Date: Wed, 15 Jun 2022 06:07:04 +1000 Subject: Guard against GetEntByIndex read out of bounds (#191) * Guard against GetEntByIndex read out of bounds * Move to ExploitFixes.cpp * format * Log out of bounds access --- NorthstarDedicatedTest/ExploitFixes.cpp | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'NorthstarDedicatedTest/ExploitFixes.cpp') diff --git a/NorthstarDedicatedTest/ExploitFixes.cpp b/NorthstarDedicatedTest/ExploitFixes.cpp index db754ad5..277475f6 100644 --- a/NorthstarDedicatedTest/ExploitFixes.cpp +++ b/NorthstarDedicatedTest/ExploitFixes.cpp @@ -347,6 +347,21 @@ KHOOK( return oCrashFunc_ParseUTF8(a1, a2, strData); } +// GetEntByIndex (called by ScriptGetEntByIndex) doesn't check for the index being out of bounds when it's +// above the max entity count. This allows it to be used to crash servers. +typedef void*(__fastcall* GetEntByIndexType)(int idx); +GetEntByIndexType GetEntByIndex; + +static void* GetEntByIndexHook(int idx) +{ + if (idx >= 0x4000) + { + spdlog::info("GetEntByIndex {} is out of bounds", idx); + return nullptr; + } + return GetEntByIndex(idx); +} + ////////////////////////////////////////////////// void DoBytePatches() @@ -394,7 +409,7 @@ void DoBytePatches() } } -void ExploitFixes::LoadCallback(HMODULE unused) +void ExploitFixes::LoadCallback(HMODULE baseAddress) { spdlog::info("ExploitFixes::LoadCallback ..."); @@ -416,4 +431,7 @@ void ExploitFixes::LoadCallback(HMODULE unused) ns_exploitfixes_log = new ConVar("ns_exploitfixes_log", "1", FCVAR_GAMEDLL, "Whether to log whenever ExploitFixes.cpp blocks/corrects something"); -} \ No newline at end of file + + HookEnabler hook; + ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x2a8a50, &GetEntByIndexHook, reinterpret_cast(&GetEntByIndex)); +} -- cgit v1.2.3 From d9f39f14fa0b0e8d025a8deef1d0c85da89c31f6 Mon Sep 17 00:00:00 2001 From: Emma Miler <27428383+emma-miler@users.noreply.github.com> Date: Wed, 15 Jun 2022 01:10:39 +0200 Subject: Fix bug where emit wouldn't be blocked if uppercase (#192) * Fix bug where emit wouldnt be blocked if uppercase * Moved emit blocker to ExploitFixes.cpp * Format change * Use `strnicmp` instead of a custom functions * Resolve merge conflicts * Format changes --- NorthstarDedicatedTest/ExploitFixes.cpp | 19 ++++++++++++++++ .../NorthstarDedicatedTest.vcxproj | 1 - .../NorthstarDedicatedTest.vcxproj.filters | 3 --- NorthstarDedicatedTest/dllmain.cpp | 1 - NorthstarDedicatedTest/emit_blocker.cpp | 26 ---------------------- 5 files changed, 19 insertions(+), 31 deletions(-) delete mode 100644 NorthstarDedicatedTest/emit_blocker.cpp (limited to 'NorthstarDedicatedTest/ExploitFixes.cpp') diff --git a/NorthstarDedicatedTest/ExploitFixes.cpp b/NorthstarDedicatedTest/ExploitFixes.cpp index 277475f6..af7d48ac 100644 --- a/NorthstarDedicatedTest/ExploitFixes.cpp +++ b/NorthstarDedicatedTest/ExploitFixes.cpp @@ -5,6 +5,9 @@ #include "NSMem.h" #include "cvar.h" +typedef char(__fastcall* function_containing_emit_t)(uint64_t a1, uint64_t a2); +function_containing_emit_t function_containing_emit; +ConVar* sv_cheats; ConVar* ns_exploitfixes_log; #define SHOULD_LOG (ns_exploitfixes_log->m_Value.m_nValue > 0) #define BLOCKED_INFO(s) \ @@ -409,6 +412,18 @@ void DoBytePatches() } } +char function_containing_emit_hook(uint64_t unknown_value, uint64_t command_ptr) +{ + char* command_string = *(char**)(command_ptr + 1040); // From decompile + + if (!sv_cheats->m_Value.m_nValue && !_strnicmp(command_string, "emit", 5)) + { + spdlog::info("Blocking command \"emit\" because sv_cheats was 0"); + return 1; + } + return function_containing_emit(unknown_value, command_ptr); +} + void ExploitFixes::LoadCallback(HMODULE baseAddress) { spdlog::info("ExploitFixes::LoadCallback ..."); @@ -433,5 +448,9 @@ void ExploitFixes::LoadCallback(HMODULE baseAddress) new ConVar("ns_exploitfixes_log", "1", FCVAR_GAMEDLL, "Whether to log whenever ExploitFixes.cpp blocks/corrects something"); HookEnabler hook; + + sv_cheats = g_pCVar->FindVar("sv_cheats"); + ENABLER_CREATEHOOK( + hook, (char*)baseAddress + 0x5889A0, &function_containing_emit_hook, reinterpret_cast(&function_containing_emit)); ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x2a8a50, &GetEntByIndexHook, reinterpret_cast(&GetEntByIndex)); } diff --git a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj b/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj index cddbd3a7..5a7c9529 100644 --- a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj +++ b/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj @@ -587,7 +587,6 @@ - diff --git a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters b/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters index 8e429c9f..81dc3817 100644 --- a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters +++ b/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters @@ -1685,9 +1685,6 @@ Source Files\Client - - Source Files\Shared\Exploit Fixes - diff --git a/NorthstarDedicatedTest/dllmain.cpp b/NorthstarDedicatedTest/dllmain.cpp index 98ac97bd..5e747ec5 100644 --- a/NorthstarDedicatedTest/dllmain.cpp +++ b/NorthstarDedicatedTest/dllmain.cpp @@ -289,7 +289,6 @@ bool InitialiseNorthstar() // activate exploit fixes AddDllLoadCallback("server.dll", ExploitFixes::LoadCallback); - AddDllLoadCallback("server.dll", InitialiseServerEmit_Blocker); // run callbacks for any libraries that are already loaded by now CallAllPendingDLLLoadCallbacks(); diff --git a/NorthstarDedicatedTest/emit_blocker.cpp b/NorthstarDedicatedTest/emit_blocker.cpp deleted file mode 100644 index 3f996c69..00000000 --- a/NorthstarDedicatedTest/emit_blocker.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "pch.h" -#include "cvar.h" - -ConVar* sv_cheats; - -typedef char(__fastcall* function_containing_emit_t)(uint64_t a1, uint64_t a2); -function_containing_emit_t function_containing_emit; - -char function_containing_emit_hook(uint64_t unknown_value, uint64_t command_ptr) -{ - char* command_string = *(char**)(command_ptr + 1040); // From decompile - if (!sv_cheats->m_Value.m_nValue && !strncmp(command_string, "emit", 5)) - { - spdlog::info("Blocking command \"emit\" because sv_cheats was 0"); - return 1; - } - return function_containing_emit(unknown_value, command_ptr); -} - -void InitialiseServerEmit_Blocker(HMODULE baseAddress) -{ - HookEnabler hook; - sv_cheats = g_pCVar->FindVar("sv_cheats"); - ENABLER_CREATEHOOK( - hook, (char*)baseAddress + 0x5889A0, &function_containing_emit_hook, reinterpret_cast(&function_containing_emit)); -} \ No newline at end of file -- cgit v1.2.3