diff --git a/wumsloader/src/entry.cpp b/wumsloader/src/entry.cpp index 33f6e37..5a6e18e 100644 --- a/wumsloader/src/entry.cpp +++ b/wumsloader/src/entry.cpp @@ -11,6 +11,7 @@ #include "utils/utils.h" #include "version.h" #include +#include #include #include #include @@ -23,6 +24,25 @@ void CallInitHooksForModule(const std::shared_ptr &curModule); bool CheckModulesByDependencies(const std::vector> &loadedModules); std::vector> OrderModulesByDependencies(const std::vector> &loadedModules); +void wipeStack(void *stackEnd) { + volatile char current_stack_marker = 0; + volatile char *wipePtr = static_cast(stackEnd) + 16; + const char *safeLimit = reinterpret_cast(reinterpret_cast(¤t_stack_marker) - 256); + + if (wipePtr >= safeLimit) { + return; + } + + const auto state = OSDisableInterrupts(); + while (const_cast(wipePtr) < safeLimit) { + *wipePtr = 0; + wipePtr++; + } + + OSRestoreInterrupts(state); +} + + // We need to wrap it to make sure the main function is called AFTER our code. // The compiler tries to optimize this otherwise and calling the main function earlier extern "C" int _start(int argc, char **argv) { @@ -44,6 +64,11 @@ extern "C" int _start(int argc, char **argv) { doStart(argc, argv); } + // Some games like TNT Racers (00050000-10142800) have parts of the games state on the stack with uninitialized fields. + // Usually the stack is completely empty when booting into a game, but our modules/plugins run on the same thread, leaving "garbage"" on the (unused) stack. + // To make sure the stack is as clean as possible, we want to clear it + wipeStack(OSGetCurrentThread()->stackEnd); + KernelInfo0 kernelInfo0; __KernelGetInfo0(&kernelInfo0, 0); asm( diff --git a/wumsloader/src/utils/imports.h b/wumsloader/src/utils/imports.h index 375996b..4f36a1b 100644 --- a/wumsloader/src/utils/imports.h +++ b/wumsloader/src/utils/imports.h @@ -56,6 +56,8 @@ IMPORT(OSFastCond_Signal); IMPORT(OSFastMutex_Unlock); IMPORT(OSInitSpinLock); IMPORT(OSGetAlarmUserData); +IMPORT(OSRestoreInterrupts); +IMPORT(OSDisableInterrupts); IMPORT(FSTimeToCalendarTime); IMPORT(FSInit);