diff options
author | geni <me@geni.site> | 2021-12-31 14:44:15 +0200 |
---|---|---|
committer | geni <me@geni.site> | 2021-12-31 14:44:15 +0200 |
commit | 32b1257cd62ee6ec7f1087355a2d9e181429d165 (patch) | |
tree | 74041a1d0f8f1a32863a9f4bdab7444183e00bd7 | |
parent | 24e6b264919b9125a4f78991dc0f42fc7797cbf2 (diff) | |
download | NorthstarLauncher-32b1257cd62ee6ec7f1087355a2d9e181429d165.tar.gz NorthstarLauncher-32b1257cd62ee6ec7f1087355a2d9e181429d165.zip |
Remove linear allocator
-rw-r--r-- | LauncherInjector/main.cpp | 22 | ||||
-rw-r--r-- | NorthstarDedicatedTest/dllmain.cpp | 6 | ||||
-rw-r--r-- | NorthstarDedicatedTest/gameutils.cpp | 2 | ||||
-rw-r--r-- | NorthstarDedicatedTest/memalloc.cpp | 75 | ||||
-rw-r--r-- | NorthstarDedicatedTest/memalloc.h | 12 |
5 files changed, 35 insertions, 82 deletions
diff --git a/LauncherInjector/main.cpp b/LauncherInjector/main.cpp index f35a3015..761f443e 100644 --- a/LauncherInjector/main.cpp +++ b/LauncherInjector/main.cpp @@ -192,6 +192,15 @@ int main(int argc, char* argv[]) { PrependPath(); + printf("[*] Loading tier0.dll\n"); + swprintf_s(buffer, L"%s\\bin\\x64_retail\\tier0.dll", exePath); + hTier0Module = LoadLibraryExW(buffer, 0, LOAD_WITH_ALTERED_SEARCH_PATH); + if (!hTier0Module) + { + LibraryLoadError(GetLastError(), L"tier0.dll", buffer); + return 1; + } + bool loadNorthstar = ShouldLoadNorthstar(argc, argv); if (loadNorthstar) { @@ -204,23 +213,12 @@ int main(int argc, char* argv[]) { printf("[*] Loading launcher.dll\n"); swprintf_s(buffer, L"%s\\bin\\x64_retail\\launcher.dll", exePath); - hLauncherModule = LoadLibraryExW(buffer, 0i64, 8u); + hLauncherModule = LoadLibraryExW(buffer, 0, LOAD_WITH_ALTERED_SEARCH_PATH); if (!hLauncherModule) { LibraryLoadError(GetLastError(), L"launcher.dll", buffer); return 1; } - - printf("[*] Loading tier0.dll\n"); - // this makes zero sense given tier0.dll is already loaded via imports on launcher.dll, but we do it for full consistency with original launcher exe - // and to also let load callbacks in Northstar work for tier0.dll - swprintf_s(buffer, L"%s\\bin\\x64_retail\\tier0.dll", exePath); - hTier0Module = LoadLibraryW(buffer); - if (!hTier0Module) - { - LibraryLoadError(GetLastError(), L"tier0.dll", buffer); - return 1; - } } printf("[*] Launching the game...\n"); diff --git a/NorthstarDedicatedTest/dllmain.cpp b/NorthstarDedicatedTest/dllmain.cpp index 4f8a445c..07741801 100644 --- a/NorthstarDedicatedTest/dllmain.cpp +++ b/NorthstarDedicatedTest/dllmain.cpp @@ -58,7 +58,6 @@ void WaitForDebugger(HMODULE baseAddress) if (strstr(GetCommandLineA(), "-waitfordebugger")) { spdlog::info("waiting for debugger..."); - spdlog::info("{} bytes have been statically allocated", g_iStaticAllocated); while (!IsDebuggerPresent()) Sleep(100); @@ -71,7 +70,7 @@ bool InitialiseNorthstar() { if (initialised) { - fprintf(stderr, "[info] Called InitialiseNorthstar more than once!\n"); + spdlog::warn("Called InitialiseNorthstar more than once!"); return false; } initialised = true; @@ -85,7 +84,6 @@ bool InitialiseNorthstar() g_SourceAllocator = new SourceAllocator; curl_global_init(CURL_GLOBAL_DEFAULT); - AddDllLoadCallback("tier0.dll", InitialiseTier0GameUtilFunctions); AddDllLoadCallback("engine.dll", WaitForDebugger); AddDllLoadCallback("engine.dll", InitialiseEngineGameUtilFunctions); AddDllLoadCallback("server.dll", InitialiseServerGameUtilFunctions); @@ -93,8 +91,8 @@ bool InitialiseNorthstar() // dedi patches { + AddDllLoadCallback("launcher.dll", InitialiseDedicatedOrigin); AddDllLoadCallback("engine.dll", InitialiseDedicated); - AddDllLoadCallback("tier0.dll", InitialiseDedicatedOrigin); AddDllLoadCallback("server.dll", InitialiseDedicatedServerGameDLL); AddDllLoadCallback("materialsystem_dx11.dll", InitialiseDedicatedMaterialSystem); // this fucking sucks, but seemingly we somehow load after rtech_game???? unsure how, but because of this we have to apply patches here, not on rtech_game load diff --git a/NorthstarDedicatedTest/gameutils.cpp b/NorthstarDedicatedTest/gameutils.cpp index 3e62037c..b2c88e49 100644 --- a/NorthstarDedicatedTest/gameutils.cpp +++ b/NorthstarDedicatedTest/gameutils.cpp @@ -94,8 +94,6 @@ void InitialiseTier0GameUtilFunctions(HMODULE baseAddress) else { g_pMemAllocSingleton = *ppMemAllocSingleton; - extern size_t g_iStaticAllocated; - spdlog::info("Using existing g_pMemAllocSingleton for memory allocations, preallocated {} bytes beforehand", g_iStaticAllocated); } Error = reinterpret_cast<ErrorType>(GetProcAddress(baseAddress, "Error")); diff --git a/NorthstarDedicatedTest/memalloc.cpp b/NorthstarDedicatedTest/memalloc.cpp index c1fb70e7..c9cf4d60 100644 --- a/NorthstarDedicatedTest/memalloc.cpp +++ b/NorthstarDedicatedTest/memalloc.cpp @@ -2,43 +2,16 @@ #include "memalloc.h" #include "gameutils.h" -// so for anyone reading this code, you may be curious why the fuck i'm overriding new to alloc into a static 100k buffer -// pretty much, the issue here is that we need to use the game's memory allocator (g_pMemAllocSingleton) or risk heap corruptions, but this allocator is defined in tier0 -// as such, it doesn't exist when we inject -// initially i wanted to just call malloc and free until g_pMemAllocSingleton was initialised, but the issue then becomes that we might try to -// call g_pMemAllocSingleton->Free on memory that was allocated with malloc, which will cause game to crash -// so, the best idea i had for this was to just alloc 100k of memory, have all pre-tier0 allocations use that -// (from what i can tell we hit about 12k before tier0 is loaded atm in debug builds, so it's more than enough) -// then just use the game's allocator after that -// yes, this means we leak 100k of memory, idk how else to do this without breaking stuff - -const int STATIC_ALLOC_SIZE = 100000; // alot more than we need, could reduce to 50k or even 25k later potentially - -size_t g_iStaticAllocated = 0; -void* g_pLastAllocated = nullptr; -char pStaticAllocBuf[STATIC_ALLOC_SIZE]; - // TODO: rename to malloc and free after removing statically compiled .libs extern "C" void* _malloc_base(size_t n) { // allocate into static buffer if g_pMemAllocSingleton isn't initialised - if (g_pMemAllocSingleton) - { - //printf("Northstar malloc (g_pMemAllocSingleton): %llu\n", n); - return g_pMemAllocSingleton->m_vtable->Alloc(g_pMemAllocSingleton, n); - } - else + if (!g_pMemAllocSingleton) { - if (g_iStaticAllocated + n > STATIC_ALLOC_SIZE) - { - throw "Ran out of prealloc space"; // we could log, but spdlog probably does use allocations as well... - } - //printf("Northstar malloc (prealloc): %llu\n", n); - void* ret = pStaticAllocBuf + g_iStaticAllocated; - g_iStaticAllocated += n; - return ret; + InitialiseTier0GameUtilFunctions(GetModuleHandleA("tier0.dll")); } + return g_pMemAllocSingleton->m_vtable->Alloc(g_pMemAllocSingleton, n); } /*extern "C" void* malloc(size_t n) @@ -48,44 +21,30 @@ extern "C" void* _malloc_base(size_t n) extern "C" void _free_base(void* p) { - // if it was allocated into the static buffer, just do nothing, safest way to deal with it - if (p >= pStaticAllocBuf && p <= pStaticAllocBuf + STATIC_ALLOC_SIZE) + if (!g_pMemAllocSingleton) { - //printf("Northstar free (prealloc): %p\n", p); - return; + InitialiseTier0GameUtilFunctions(GetModuleHandleA("tier0.dll")); } - - //printf("Northstar free (g_pMemAllocSingleton): %p\n", p); g_pMemAllocSingleton->m_vtable->Free(g_pMemAllocSingleton, p); } -extern "C" void* _realloc_base(void* old_ptr, size_t size) { - // it was allocated into the static buffer - if (old_ptr >= pStaticAllocBuf && old_ptr <= pStaticAllocBuf + STATIC_ALLOC_SIZE) + +extern "C" void* _realloc_base(void* oldPtr, size_t size) { + if (!g_pMemAllocSingleton) { - if (g_pLastAllocated == old_ptr) - { - // nothing was allocated after this - size_t old_size = g_iStaticAllocated - ((size_t)g_pLastAllocated - (size_t)pStaticAllocBuf); - size_t diff = size - old_size; - if (diff > 0) - g_iStaticAllocated += diff; - return old_ptr; - } - else - { - return _malloc_base(size); - } + InitialiseTier0GameUtilFunctions(GetModuleHandleA("tier0.dll")); } - - if (g_pMemAllocSingleton) - return g_pMemAllocSingleton->m_vtable->Realloc(g_pMemAllocSingleton, old_ptr, size); - return nullptr; + return g_pMemAllocSingleton->m_vtable->Realloc(g_pMemAllocSingleton, oldPtr, size); } extern "C" void* _calloc_base(size_t n, size_t size) { - return _malloc_base(n * size); + size_t bytes = n * size; + void* memory = _malloc_base(bytes); + if (memory) { + memset(memory, 0, bytes); + } + return memory; } extern "C" char* _strdup_base(const char* src) @@ -96,7 +55,7 @@ extern "C" char* _strdup_base(const char* src) while (src[len]) len++; - str = reinterpret_cast<char*>(_malloc_base(len + 1)); + str = (char*)(_malloc_base(len + 1)); p = str; while (*src) *p++ = *src++; diff --git a/NorthstarDedicatedTest/memalloc.h b/NorthstarDedicatedTest/memalloc.h index d9277694..86d2ff58 100644 --- a/NorthstarDedicatedTest/memalloc.h +++ b/NorthstarDedicatedTest/memalloc.h @@ -3,16 +3,16 @@ #include "include/rapidjson/document.h" //#include "include/rapidjson/allocators.h" -extern size_t g_iStaticAllocated; - -extern "C" { - char* _strdup_base(const char* src); -} +extern "C" void* _malloc_base(size_t size); +extern "C" void* _calloc_base(size_t const count, size_t const size); +extern "C" void* _realloc_base(void* block, size_t size); +extern "C" void* _recalloc_base(void* const block, size_t const count, size_t const size); +extern "C" void _free_base(void* const block); +extern "C" char* _strdup_base(const char* src); void* operator new(size_t n); void operator delete(void* p); -void* _malloc_base(size_t n); //void* malloc(size_t n); class SourceAllocator { |