aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgeni <me@geni.site>2021-12-31 14:44:15 +0200
committergeni <me@geni.site>2021-12-31 14:44:15 +0200
commit32b1257cd62ee6ec7f1087355a2d9e181429d165 (patch)
tree74041a1d0f8f1a32863a9f4bdab7444183e00bd7
parent24e6b264919b9125a4f78991dc0f42fc7797cbf2 (diff)
downloadNorthstarLauncher-32b1257cd62ee6ec7f1087355a2d9e181429d165.tar.gz
NorthstarLauncher-32b1257cd62ee6ec7f1087355a2d9e181429d165.zip
Remove linear allocator
-rw-r--r--LauncherInjector/main.cpp22
-rw-r--r--NorthstarDedicatedTest/dllmain.cpp6
-rw-r--r--NorthstarDedicatedTest/gameutils.cpp2
-rw-r--r--NorthstarDedicatedTest/memalloc.cpp75
-rw-r--r--NorthstarDedicatedTest/memalloc.h12
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 {