Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Code/immersive_launcher/Launcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ LaunchContext* GetLaunchContext()
return g_context;
}

bool LaunchContext::GetLoaded()
{
return isLoaded;
}

// Everything is nothing, life is worth living, just look to the stars
#define DIE_NOW(err) \
{ \
Expand Down Expand Up @@ -126,6 +131,7 @@ bool LoadProgram(LaunchContext& LC)
LC.Version = QueryFileVersion(LC.exePath.c_str());
if (LC.Version.empty())
DIE_NOW(L"Failed to query game version");
LC.SetLoaded();

ExeLoader loader(CurrentTarget.exeLoadSz);
if (!loader.Load(reinterpret_cast<uint8_t*>(content.data())))
Expand Down
4 changes: 4 additions & 0 deletions Code/immersive_launcher/Launcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@ struct LaunchContext
fs::path exePath;
fs::path gamePath;
TiltedPhoques::String Version;
bool isLoaded{false};
ExeLoader::TEntryPoint gameMain = nullptr;

void SetLoaded() { isLoaded = true; } // If loaded, need to spoof GetModuleFileName*(nullptr)
bool GetLoaded();
};

LaunchContext* GetLaunchContext();
Expand Down
55 changes: 5 additions & 50 deletions Code/immersive_launcher/stubs/FileMapping.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ inline bool IsUsingMO2()
return GetModuleHandleW(L"usvfs_x64.dll");
}

inline bool IsMyModule(HMODULE aHmod)
bool IsMyModule(HMODULE aHmod)
{
return aHmod == nullptr || aHmod == NtInternal::ThePeb()->pImageBase;
}
Expand Down Expand Up @@ -156,56 +156,19 @@ NTSTATUS WINAPI TP_LdrGetDllFullName(HMODULE Module, PUNICODE_STRING DllName)
return RealLdrGetDllFullName(Module, DllName);
}

bool NeedsToFool(void* pRbp, bool* wantsTruth = nullptr)
{
// game code/stub segment within this exe needs to be fooled
if (IsThisExeAddress(static_cast<uint8_t*>(pRbp)))
{
return IsGameMemoryAddress(static_cast<uint8_t*>(pRbp));
}

// this heuristic indicates hooked game code... that is still owned by us...
// not recognized immedeatly, but still looks like game code...
HMODULE hMod = HModFromAddress(pRbp);

// simple debug hook
#if 0
if (hMod == GetModuleHandleW(L"NvCameraAllowlisting64.dll"))
{
__debugbreak();
}
#endif

if (hMod == NtInternal::ThePeb()->pImageBase || hMod == nullptr /*This is a hook, virtual allocd, not owned by anybody, so we assign ownership to the ST directory*/)
{
if (wantsTruth)
*wantsTruth = true;
return false;
}

return !IsLocalModulePath(hMod);
}

DWORD WINAPI TP_GetModuleFileNameW(HMODULE aModule, LPWSTR alpFilename, DWORD aSize)
{
// trampoline space for USVFS
TP_EMPTY_HOOK_PLACEHOLDER;

void* rbp = _ReturnAddress();
// PrintOwnerNa me(rbp);

bool force = false;
if (IsMyModule(aModule) && NeedsToFool(rbp, &force) && launcher::GetLaunchContext())
if (IsMyModule(aModule) && launcher::GetLaunchContext() && launcher::GetLaunchContext()->GetLoaded())
{
auto& aExePath = launcher::GetLaunchContext()->exePath;
StringCchCopyW(alpFilename, aSize, aExePath.c_str());

return static_cast<DWORD>(std::wcslen(alpFilename));
}

if (force)
return MYGetModuleFileNameW(aModule, alpFilename, aSize);

return RealGetModuleFileNameW(aModule, alpFilename, aSize);
}

Expand All @@ -228,15 +191,6 @@ DWORD WINAPI TP_GetModuleFileNameA(HMODULE aModule, char* alpFileName, DWORD aBu
{
TP_EMPTY_HOOK_PLACEHOLDER;

void* rbp = _ReturnAddress();
if (IsMyModule(aModule) && NeedsToFool(rbp) && launcher::GetLaunchContext())
{
auto aExePath = launcher::GetLaunchContext()->exePath.string();
StringCchCopyA(alpFileName, aBufferSize, aExePath.c_str());

return static_cast<DWORD>(std::strlen(alpFileName));
}

ScopedOSHeapItem wideBuffer((aBufferSize * sizeof(wchar_t)) + 1);

wchar_t* pBuffer = static_cast<wchar_t*>(wideBuffer.m_pBlock);
Expand All @@ -246,8 +200,9 @@ DWORD WINAPI TP_GetModuleFileNameA(HMODULE aModule, char* alpFileName, DWORD aBu
// of quitting, so just avoid the bug.
// TODO: Further analysis of what is under MO2 USVFS and what is needed.
DWORD result = 0;
if (aModule != GetModuleHandleW(L"XAudio2_7.dll"))
result = RealGetModuleFileNameW(aModule, pBuffer, aBufferSize * sizeof(wchar_t));
HMODULE tMod = RealGetModuleHandleW(L"XAudio2_7.dll");
if (tMod == nullptr || aModule != tMod)
result = TP_GetModuleFileNameW(aModule, pBuffer, aBufferSize * sizeof(wchar_t)); // To make sure spoofing happens if needed

if (result == 0)
{
Expand Down
2 changes: 1 addition & 1 deletion xmake.lua
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ end
add_requires(
"entt v3.10.0",
"recastnavigation v1.6.0",
"tiltedcore v0.2.7",
"tiltedcore master",
"cryptopp 8.9.0",
"spdlog v1.13.0",
"cpp-httplib 0.14.0",
Expand Down
Loading