Move all loadlibrary and freelibrary checks to ntdll hooks

This commit is contained in:
cdozdil
2025-09-12 17:57:42 +03:00
parent a11589048c
commit 5249f8a534
21 changed files with 1110 additions and 1850 deletions
+1
View File
@@ -347,6 +347,7 @@ copy NUL "$(SolutionDir)x64\Release\a\!! EXTRACT ALL FILES TO GAME FOLDER !!" /Y
<ClInclude Include="proxies\KernelBase_Proxy.h" />
<ClInclude Include="proxies\XeFG_Proxy.h" />
<ClInclude Include="proxies\XeLL_Proxy.h" />
<ClInclude Include="proxies\Ntdll_Proxy.h" />
<ClInclude Include="resource_tracking\ResTrack_dx12.h" />
<ClInclude Include="shaders\hudless_compare\HC_Common.h" />
<ClInclude Include="shaders\hudless_compare\HC_Dx12.h" />
+6
View File
@@ -563,6 +563,12 @@
<ClInclude Include="include\spdlog_sink\debug_sink.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="hooks\Ntdll_Hooks.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="proxies\Ntdll_Proxy.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Config.cpp">
+1 -1
View File
@@ -9,7 +9,7 @@ class OwnedMutex
{
private:
std::shared_mutex mtx;
std::atomic<uint32_t> owner {}; // don't use 0
std::atomic<uint32_t> owner = 0; // don't use 0
public:
void lock(uint32_t _owner)
+2
View File
@@ -6,6 +6,7 @@
#include <inputs/FG/Streamline_Inputs_Dx12.h>
#include "misc/Quirks.h"
#include <set>
#include <deque>
#include <vulkan/vulkan.h>
#include <ankerl/unordered_dense.h>
@@ -194,6 +195,7 @@ class State
std::string currentInputApiName;
bool isShuttingDown = false;
std::set<PVOID> modulesToFree;
// menu warnings
bool fgSettingsChanged = false;
+54 -45
View File
@@ -17,6 +17,7 @@
#include <hooks/Streamline_Hooks.h>
#include "proxies/Kernel32_Proxy.h"
#include "proxies/KernelBase_Proxy.h"
#include "proxies/Ntdll_Proxy.h"
#include <proxies/IGDExt_Proxy.h>
#include "inputs/FSR2_Dx12.h"
@@ -32,7 +33,6 @@
#include <hooks/HooksVk.h>
#include <hooks/Ntdll_Hooks.h>
#include <hooks/Kernel_Hooks.h>
#include <nvapi/NvApiHooks.h>
#include <cwctype>
@@ -190,7 +190,7 @@ void LoadAsiPlugins()
if (ext == L".asi")
{
HMODULE hMod = KernelBaseProxy::LoadLibraryW_()(entry.path().c_str());
HMODULE hMod = NtdllProxy::LoadLibraryExW_Ldr(entry.path().c_str(), NULL, 0);
if (hMod != nullptr)
{
@@ -237,14 +237,6 @@ static void CheckWorkingMode()
{
LOG_FUNC();
if (Config::Instance()->EarlyHooking.value_or_default())
{
NtdllHooks::Hook();
KernelHooks::Hook();
KernelHooks::HookBase();
}
bool modeFound = false;
std::string filename = Util::DllPath().filename().string();
std::string lCaseFilename(filename);
@@ -272,13 +264,20 @@ static void CheckWorkingMode()
break;
}
if (Config::Instance()->EarlyHooking.value_or_default())
{
NtdllHooks::Hook();
KernelHooks::Hook();
KernelHooks::HookBase();
}
// version.dll
if (lCaseFilename == "version.dll")
{
do
{
auto pluginFilePath = pluginPath / L"version.dll";
originalModule = KernelBaseProxy::LoadLibraryExW_()(pluginFilePath.wstring().c_str(), NULL, 0);
originalModule = NtdllProxy::LoadLibraryExW_Ldr(pluginFilePath.wstring().c_str(), NULL, 0);
if (originalModule != nullptr)
{
@@ -286,7 +285,7 @@ static void CheckWorkingMode()
break;
}
originalModule = KernelBaseProxy::LoadLibraryExW_()(L"version-original.dll", NULL, 0);
originalModule = NtdllProxy::LoadLibraryExW_Ldr(L"version-original.dll", NULL, 0);
if (originalModule != nullptr)
{
@@ -295,7 +294,7 @@ static void CheckWorkingMode()
}
auto sysFilePath = sysPath / L"version.dll";
originalModule = KernelBaseProxy::LoadLibraryExW_()(sysFilePath.wstring().c_str(), NULL, 0);
originalModule = NtdllProxy::LoadLibraryExW_Ldr(sysFilePath.wstring().c_str(), NULL, 0);
if (originalModule != nullptr)
LOG_INFO("OptiScaler working as version.dll, system dll loaded");
@@ -328,7 +327,7 @@ static void CheckWorkingMode()
do
{
auto pluginFilePath = pluginPath / L"winmm.dll";
originalModule = KernelBaseProxy::LoadLibraryExW_()(pluginFilePath.wstring().c_str(), NULL, 0);
originalModule = NtdllProxy::LoadLibraryExW_Ldr(pluginFilePath.wstring().c_str(), NULL, 0);
if (originalModule != nullptr)
{
@@ -336,7 +335,7 @@ static void CheckWorkingMode()
break;
}
originalModule = KernelBaseProxy::LoadLibraryExW_()(L"winmm-original.dll", NULL, 0);
originalModule = NtdllProxy::LoadLibraryExW_Ldr(L"winmm-original.dll", NULL, 0);
if (originalModule != nullptr)
{
@@ -345,7 +344,7 @@ static void CheckWorkingMode()
}
auto sysFilePath = sysPath / L"winmm.dll";
originalModule = KernelBaseProxy::LoadLibraryExW_()(sysFilePath.wstring().c_str(), NULL, 0);
originalModule = NtdllProxy::LoadLibraryExW_Ldr(sysFilePath.wstring().c_str(), NULL, 0);
if (originalModule != nullptr)
LOG_INFO("OptiScaler working as winmm.dll, system dll loaded");
@@ -377,7 +376,7 @@ static void CheckWorkingMode()
do
{
auto pluginFilePath = pluginPath / L"wininet.dll";
originalModule = KernelBaseProxy::LoadLibraryExW_()(pluginFilePath.wstring().c_str(), NULL, 0);
originalModule = NtdllProxy::LoadLibraryExW_Ldr(pluginFilePath.wstring().c_str(), NULL, 0);
if (originalModule != nullptr)
{
@@ -385,7 +384,7 @@ static void CheckWorkingMode()
break;
}
originalModule = KernelBaseProxy::LoadLibraryExW_()(L"wininet-original.dll", NULL, 0);
originalModule = NtdllProxy::LoadLibraryExW_Ldr(L"wininet-original.dll", NULL, 0);
if (originalModule != nullptr)
{
@@ -394,7 +393,7 @@ static void CheckWorkingMode()
}
auto sysFilePath = sysPath / L"wininet.dll";
originalModule = KernelBaseProxy::LoadLibraryExW_()(sysFilePath.wstring().c_str(), NULL, 0);
originalModule = NtdllProxy::LoadLibraryExW_Ldr(sysFilePath.wstring().c_str(), NULL, 0);
if (originalModule != nullptr)
LOG_INFO("OptiScaler working as wininet.dll, system dll loaded");
@@ -426,7 +425,7 @@ static void CheckWorkingMode()
do
{
auto pluginFilePath = pluginPath / L"dbghelp.dll";
originalModule = KernelBaseProxy::LoadLibraryExW_()(pluginFilePath.wstring().c_str(), NULL, 0);
originalModule = NtdllProxy::LoadLibraryExW_Ldr(pluginFilePath.wstring().c_str(), NULL, 0);
if (originalModule != nullptr)
{
@@ -434,7 +433,7 @@ static void CheckWorkingMode()
break;
}
originalModule = KernelBaseProxy::LoadLibraryExW_()(L"dbghelp-original.dll", NULL, 0);
originalModule = NtdllProxy::LoadLibraryExW_Ldr(L"dbghelp-original.dll", NULL, 0);
if (originalModule != nullptr)
{
@@ -443,7 +442,7 @@ static void CheckWorkingMode()
}
auto sysFilePath = sysPath / L"dbghelp.dll";
originalModule = KernelBaseProxy::LoadLibraryExW_()(sysFilePath.wstring().c_str(), NULL, 0);
originalModule = NtdllProxy::LoadLibraryExW_Ldr(sysFilePath.wstring().c_str(), NULL, 0);
if (originalModule != nullptr)
LOG_INFO("OptiScaler working as dbghelp.dll, system dll loaded");
@@ -509,7 +508,7 @@ static void CheckWorkingMode()
do
{
auto pluginFilePath = pluginPath / L"winhttp.dll";
originalModule = KernelBaseProxy::LoadLibraryExW_()(pluginFilePath.wstring().c_str(), NULL, 0);
originalModule = NtdllProxy::LoadLibraryExW_Ldr(pluginFilePath.wstring().c_str(), NULL, 0);
if (originalModule != nullptr)
{
@@ -517,7 +516,7 @@ static void CheckWorkingMode()
break;
}
originalModule = KernelBaseProxy::LoadLibraryExW_()(L"winhttp-original.dll", NULL, 0);
originalModule = NtdllProxy::LoadLibraryExW_Ldr(L"winhttp-original.dll", NULL, 0);
if (originalModule != nullptr)
{
@@ -526,7 +525,7 @@ static void CheckWorkingMode()
}
auto sysFilePath = sysPath / L"winhttp.dll";
originalModule = KernelBaseProxy::LoadLibraryExW_()(sysFilePath.wstring().c_str(), NULL, 0);
originalModule = NtdllProxy::LoadLibraryExW_Ldr(sysFilePath.wstring().c_str(), NULL, 0);
if (originalModule != nullptr)
LOG_INFO("OptiScaler working as winhttp.dll, system dll loaded");
@@ -558,7 +557,7 @@ static void CheckWorkingMode()
do
{
auto pluginFilePath = pluginPath / L"dxgi.dll";
originalModule = KernelBaseProxy::LoadLibraryExW_()(pluginFilePath.wstring().c_str(), NULL, 0);
originalModule = NtdllProxy::LoadLibraryExW_Ldr(pluginFilePath.wstring().c_str(), NULL, 0);
if (originalModule != nullptr)
{
@@ -566,7 +565,7 @@ static void CheckWorkingMode()
break;
}
originalModule = KernelBaseProxy::LoadLibraryExW_()(L"dxgi-original.dll", NULL, 0);
originalModule = NtdllProxy::LoadLibraryExW_Ldr(L"dxgi-original.dll", NULL, 0);
if (originalModule != nullptr)
{
@@ -575,7 +574,7 @@ static void CheckWorkingMode()
}
auto sysFilePath = sysPath / L"dxgi.dll";
originalModule = KernelBaseProxy::LoadLibraryExW_()(sysFilePath.wstring().c_str(), NULL, 0);
originalModule = NtdllProxy::LoadLibraryExW_Ldr(sysFilePath.wstring().c_str(), NULL, 0);
if (originalModule != nullptr)
LOG_INFO("OptiScaler working as dxgi.dll, system dll loaded");
@@ -609,17 +608,18 @@ static void CheckWorkingMode()
do
{
// Moved here to cover agility sdk
NtdllHooks::Hook();
KernelHooks::HookBase();
auto pluginFilePath = pluginPath / L"d3d12.dll";
originalModule = KernelBaseProxy::LoadLibraryExW_()(pluginFilePath.wstring().c_str(), NULL, 0);
originalModule = NtdllProxy::LoadLibraryExW_Ldr(pluginFilePath.wstring().c_str(), NULL, 0);
if (originalModule != nullptr)
{
LOG_INFO("OptiScaler working as d3d12.dll, original dll loaded from plugin folder");
break;
}
originalModule = KernelBaseProxy::LoadLibraryExW_()(L"d3d12-original.dll", NULL, 0);
originalModule = NtdllProxy::LoadLibraryExW_Ldr(L"d3d12-original.dll", NULL, 0);
if (originalModule != nullptr)
{
LOG_INFO("OptiScaler working as d3d12.dll, d3d12-original.dll loaded");
@@ -627,7 +627,7 @@ static void CheckWorkingMode()
}
auto sysFilePath = sysPath / L"d3d12.dll";
originalModule = KernelBaseProxy::LoadLibraryExW_()(sysFilePath.wstring().c_str(), NULL, 0);
originalModule = NtdllProxy::LoadLibraryExW_Ldr(sysFilePath.wstring().c_str(), NULL, 0);
if (originalModule != nullptr)
LOG_INFO("OptiScaler working as d3d12.dll, system dll loaded");
@@ -706,6 +706,7 @@ static void CheckWorkingMode()
{
// Moved here to cover agility sdk
KernelHooks::HookBase();
NtdllHooks::Hook();
LOG_DEBUG("Check for d3d12");
HMODULE d3d12Module = nullptr;
@@ -740,7 +741,7 @@ static void CheckWorkingMode()
// Vulkan
vulkanModule = GetDllNameWModule(&vkNamesW);
if ((State::Instance().isRunningOnDXVK || State::Instance().isRunningOnLinux) && vulkanModule == nullptr)
vulkanModule = KernelBaseProxy::LoadLibraryExW_()(vkNamesW[0].c_str(), NULL, 0);
vulkanModule = NtdllProxy::LoadLibraryExW_Ldr(vkNamesW[0].c_str(), NULL, 0);
if (vulkanModule != nullptr)
{
@@ -879,7 +880,7 @@ static void CheckWorkingMode()
SetEnvironmentVariableW(L"RESHADE_DISABLE_GRAPHICS_HOOK", L"1");
State::EnableServeOriginal(200);
skModule = LoadLibraryW(skFile.c_str());
skModule = NtdllProxy::LoadLibraryExW_Ldr(skFile.c_str(), NULL, 0);
State::DisableServeOriginal(200);
LOG_INFO("Loading SpecialK64.dll, result: {0:X}", (UINT64) skModule);
@@ -895,7 +896,7 @@ static void CheckWorkingMode()
SetEnvironmentVariableW(L"RESHADE_DISABLE_GRAPHICS_HOOK", L"1");
State::EnableServeOriginal(201);
reshadeModule = LoadLibraryW(rsFile.c_str());
reshadeModule = NtdllProxy::LoadLibraryExW_Ldr(rsFile.c_str(), NULL, 0);
State::DisableServeOriginal(201);
LOG_INFO("Loading ReShade64.dll, result: {0:X}", (size_t) reshadeModule);
@@ -917,7 +918,7 @@ static void CheckWorkingMode()
// Intel Extension Framework
if (Config::Instance()->UESpoofIntelAtomics64.value_or_default())
{
HMODULE igdext = KernelBaseProxy::LoadLibraryW_()(L"igdext64.dll");
HMODULE igdext = NtdllProxy::LoadLibraryExW_Ldr(L"igdext64.dll", NULL, 0);
if (igdext == nullptr)
{
@@ -927,7 +928,7 @@ static void CheckWorkingMode()
{
auto dllPath = paths[i] / L"igdext64.dll";
LOG_DEBUG("Trying to load: {}", wstring_to_string(dllPath.c_str()));
igdext = KernelBaseProxy::LoadLibraryExW_()(dllPath.c_str(), NULL, 0);
igdext = NtdllProxy::LoadLibraryExW_Ldr(dllPath.c_str(), NULL, 0);
if (igdext != nullptr)
{
@@ -1048,7 +1049,7 @@ bool isNvidia()
if (!nvapiModule)
{
nvapiModule = KernelBaseProxy::LoadLibraryExW_()(L"nvapi64.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
nvapiModule = NtdllProxy::LoadLibraryExW_Ldr(L"nvapi64.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
loadedHere = true;
}
@@ -1105,7 +1106,7 @@ bool isNvidia()
}
if (loadedHere)
KernelBaseProxy::FreeLibrary_()(nvapiModule);
NtdllProxy::FreeLibrary_Ldr(nvapiModule);
LOG_DEBUG("Detected: {}", nvidiaDetected);
@@ -1157,9 +1158,14 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv
spdlog::info("");
// Init Kernel proxies
NtdllProxy::Init();
KernelBaseProxy::Init();
Kernel32Proxy::Init();
// Check for working mode and attach hooks
spdlog::info("");
CheckWorkingMode();
// Check if real DLSS available
if (Config::Instance()->DLSSEnabled.value_or_default())
{
@@ -1222,10 +1228,6 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv
Config::Instance()->NvapiDllPath.set_volatile_value(L"fakenvapi.dll");
}
// Check for working mode and attach hooks
spdlog::info("");
CheckWorkingMode();
// Asi plugins
if (!State::Instance().isWorkingAsNvngx && Config::Instance()->LoadAsiPlugins.value_or_default())
{
@@ -1291,6 +1293,8 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv
break;
case DLL_PROCESS_DETACH:
State::Instance().isShuttingDown = true;
// Unhooking and cleaning stuff causing issues during shutdown.
// Disabled for now to check if it cause any issues
// UnhookApis();
@@ -1302,15 +1306,20 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv
// DetachHooks();
if (skModule != nullptr)
KernelBaseProxy::FreeLibrary_()(skModule);
NtdllProxy::FreeLibrary_Ldr(skModule);
if (reshadeModule != nullptr)
KernelBaseProxy::FreeLibrary_()(reshadeModule);
NtdllProxy::FreeLibrary_Ldr(reshadeModule);
if (_asiHandles.size() > 0)
{
for (size_t i = 0; i < _asiHandles.size(); i++)
KernelBaseProxy::FreeLibrary_()(_asiHandles[i]);
NtdllProxy::FreeLibrary_Ldr(_asiHandles[i]);
}
for (const PVOID& v : State::Instance().modulesToFree)
{
NtdllProxy::FreeLibrary_Ldr(v);
}
spdlog::info("");
+6 -6
View File
@@ -3,7 +3,7 @@
#include <pch.h>
#include <proxies/Dxgi_Proxy.h>
#include <proxies/KernelBase_Proxy.h>
#include <proxies/Ntdll_Proxy.h>
#include <detours/detours.h>
@@ -68,7 +68,7 @@ inline static std::vector<std::filesystem::path> GetDriverStore()
if (hGdi32 == nullptr)
{
hGdi32 = KernelBaseProxy::LoadLibraryExW_()(L"Gdi32.dll", NULL, 0);
hGdi32 = NtdllProxy::LoadLibraryExW_Ldr(L"Gdi32.dll", NULL, 0);
libraryLoaded = hGdi32 != nullptr;
}
@@ -140,7 +140,7 @@ inline static std::vector<std::filesystem::path> GetDriverStore()
} while (false);
if (libraryLoaded)
KernelBaseProxy::FreeLibrary_()(hGdi32);
NtdllProxy::FreeLibrary_Ldr(hGdi32);
return result;
}
@@ -315,7 +315,7 @@ struct AmdExtFfxApi : public IAmdExtFfxApi
if (o_UpdateFfxApiProvider == nullptr)
{
fsr4Module = KernelBaseProxy::LoadLibraryExW_()(L"amdxcffx64.dll", NULL, 0);
fsr4Module = NtdllProxy::LoadLibraryExW_Ldr(L"amdxcffx64.dll", NULL, 0);
if (fsr4Module == nullptr)
{
@@ -327,7 +327,7 @@ struct AmdExtFfxApi : public IAmdExtFfxApi
{
auto dllPath = storePath[i] / L"amdxcffx64.dll";
LOG_DEBUG("Trying to load: {}", wstring_to_string(dllPath.c_str()));
fsr4Module = KernelBaseProxy::LoadLibraryExW_()(dllPath.c_str(), NULL, 0);
fsr4Module = NtdllProxy::LoadLibraryExW_Ldr(dllPath.c_str(), NULL, 0);
if (fsr4Module != nullptr)
{
@@ -507,7 +507,7 @@ inline void InitFSR4Update()
// For FSR4 Upgrade
moduleAmdxc64 = KernelBaseProxy::GetModuleHandleW_()(L"amdxc64.dll");
if (moduleAmdxc64 == nullptr)
moduleAmdxc64 = KernelBaseProxy::LoadLibraryExW_()(L"amdxc64.dll", NULL, 0);
moduleAmdxc64 = NtdllProxy::LoadLibraryExW_Ldr(L"amdxc64.dll", NULL, 0);
if (moduleAmdxc64 != nullptr)
{
+1 -1
View File
@@ -5,7 +5,7 @@
#include <menu/menu_overlay_vk.h>
#include <proxies/Kernel32_Proxy.h>
#include <proxies/KernelBase_Proxy.h>
#include <detours/detours.h>
#include <misc/FrameLimit.h>
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -3,7 +3,7 @@
#include <NVNGX_Parameter.h>
#include "proxies/NVNGX_Proxy.h"
#include "proxies/KernelBase_Proxy.h"
#include "proxies/Ntdll_Proxy.h"
#define DLSSG_MOD_ID_OFFSET 2000000
@@ -69,7 +69,7 @@ class DLSSGMod
if (_dll == nullptr)
{
auto dllPath = Util::DllPath().parent_path() / "dlssg_to_fsr3_amd_is_better.dll";
_dll = KernelBaseProxy::LoadLibraryExW_()(dllPath.c_str(), NULL, 0);
_dll = NtdllProxy::LoadLibraryExW_Ldr(dllPath.c_str(), NULL, 0);
}
if (_dll != nullptr)
@@ -113,7 +113,7 @@ class DLSSGMod
if (_dll == nullptr)
{
auto dllPath = Util::DllPath().parent_path() / "dlssg_to_fsr3_amd_is_better.dll";
_dll = KernelBaseProxy::LoadLibraryExW_()(dllPath.c_str(), NULL, 0);
_dll = NtdllProxy::LoadLibraryExW_Ldr(dllPath.c_str(), NULL, 0);
}
if (_dll != nullptr)
+1 -1
View File
@@ -144,7 +144,7 @@ bool fakenvapi::loadForNvidia()
if (_dllForNvidia != nullptr)
return true;
_dllForNvidia = KernelBaseProxy::LoadLibraryExW_()(L"fakenvapi.dll", NULL, 0);
_dllForNvidia = NtdllProxy::LoadLibraryExW_Ldr(L"fakenvapi.dll", NULL, 0);
if (!_dllForNvidia)
return false;
+2 -1
View File
@@ -4,6 +4,7 @@
#include <State.h>
#include <proxies/Ntdll_Proxy.h>
#include <proxies/KernelBase_Proxy.h>
#include <detours/detours.h>
@@ -69,7 +70,7 @@ class D3d12Proxy
_dll = KernelBaseProxy::GetModuleHandleW_()(L"d3d12.dll");
if (_dll == nullptr)
_dll = KernelBaseProxy::LoadLibraryExW_()(L"d3d12.dll", NULL, 0);
_dll = NtdllProxy::LoadLibraryExW_Ldr(L"d3d12.dll", NULL, 0);
}
else
{
+2 -2
View File
@@ -4,7 +4,7 @@
#include <State.h>
#include <proxies/KernelBase_Proxy.h>
#include <proxies/Ntdll_Proxy.h>
#include <detours/detours.h>
@@ -29,7 +29,7 @@ class DxgiProxy
_dll = GetModuleHandle(L"dxgi.dll");
if (_dll == nullptr)
_dll = KernelBaseProxy::LoadLibraryExW_()(L"dxgi.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
_dll = NtdllProxy::LoadLibraryExW_Ldr(L"dxgi.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
}
else
{
+7 -6
View File
@@ -5,6 +5,7 @@
#include "Config.h"
#include "Logger.h"
#include <proxies/Ntdll_Proxy.h>
#include <proxies/KernelBase_Proxy.h>
#include <inputs/FfxApi_Dx12.h>
@@ -77,9 +78,9 @@ class FfxApiProxy
std::filesystem::path libPath(Config::Instance()->FfxDx12Path.value().c_str());
if (libPath.has_filename())
_dllDx12 = KernelBaseProxy::LoadLibraryExW_()(libPath.c_str(), NULL, 0);
_dllDx12 = NtdllProxy::LoadLibraryExW_Ldr(libPath.c_str(), NULL, 0);
else
_dllDx12 = KernelBaseProxy::LoadLibraryExW_()((libPath / dllNames[i]).c_str(), NULL, 0);
_dllDx12 = NtdllProxy::LoadLibraryExW_Ldr((libPath / dllNames[i]).c_str(), NULL, 0);
if (_dllDx12 != nullptr)
{
@@ -91,7 +92,7 @@ class FfxApiProxy
if (_dllDx12 == nullptr)
{
_dllDx12 = KernelBaseProxy::LoadLibraryExW_()(dllNames[i].c_str(), NULL, 0);
_dllDx12 = NtdllProxy::LoadLibraryExW_Ldr(dllNames[i].c_str(), NULL, 0);
if (_dllDx12 != nullptr)
{
@@ -222,9 +223,9 @@ class FfxApiProxy
std::filesystem::path libPath(Config::Instance()->FfxVkPath.value().c_str());
if (libPath.has_filename())
_dllVk = KernelBaseProxy::LoadLibraryExW_()(libPath.c_str(), NULL, 0);
_dllVk = NtdllProxy::LoadLibraryExW_Ldr(libPath.c_str(), NULL, 0);
else
_dllVk = KernelBaseProxy::LoadLibraryExW_()((libPath / L"amd_fidelityfx_vk.dll").c_str(), NULL, 0);
_dllVk = NtdllProxy::LoadLibraryExW_Ldr((libPath / L"amd_fidelityfx_vk.dll").c_str(), NULL, 0);
if (_dllVk != nullptr)
{
@@ -235,7 +236,7 @@ class FfxApiProxy
if (_dllVk == nullptr)
{
_dllVk = KernelBaseProxy::LoadLibraryExW_()(L"amd_fidelityfx_vk.dll", NULL, 0);
_dllVk = NtdllProxy::LoadLibraryExW_Ldr(L"amd_fidelityfx_vk.dll", NULL, 0);
if (_dllVk != nullptr)
LOG_INFO("amd_fidelityfx_vk.dll loaded from exe folder");
+16 -15
View File
@@ -5,6 +5,7 @@
#include <Util.h>
#include <Config.h>
#include "Ntdll_Proxy.h"
#include "KernelBase_Proxy.h"
#include <detours/detours.h>
@@ -12,20 +13,20 @@
class Kernel32Proxy
{
public:
typedef BOOL (*PFN_FreeLibrary)(HMODULE lpLibrary);
typedef HMODULE (*PFN_LoadLibraryA)(LPCSTR lpLibFileName);
typedef HMODULE (*PFN_LoadLibraryW)(LPCWSTR lpLibFileName);
typedef HMODULE (*PFN_LoadLibraryExA)(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags);
typedef HMODULE (*PFN_LoadLibraryExW)(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags);
typedef FARPROC (*PFN_GetProcAddress)(HMODULE hModule, LPCSTR lpProcName);
typedef HMODULE (*PFN_GetModuleHandleA)(LPCSTR lpModuleName);
typedef HMODULE (*PFN_GetModuleHandleW)(LPCWSTR lpModuleName);
typedef BOOL (*PFN_GetModuleHandleExA)(DWORD dwFlags, LPCSTR lpModuleName, HMODULE* phModule);
typedef BOOL (*PFN_GetModuleHandleExW)(DWORD dwFlags, LPCWSTR lpModuleName, HMODULE* phModule);
typedef DWORD (*PFN_GetFileAttributesW)(LPCWSTR lpFileName);
typedef HANDLE (*PFN_CreateFileW)(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition,
DWORD dwFlagsAndAttributes, HANDLE hTemplateFile);
typedef BOOL(WINAPI* PFN_FreeLibrary)(HMODULE lpLibrary);
typedef HMODULE(WINAPI* PFN_LoadLibraryA)(LPCSTR lpLibFileName);
typedef HMODULE(WINAPI* PFN_LoadLibraryW)(LPCWSTR lpLibFileName);
typedef HMODULE(WINAPI* PFN_LoadLibraryExA)(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags);
typedef HMODULE(WINAPI* PFN_LoadLibraryExW)(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags);
typedef FARPROC(WINAPI* PFN_GetProcAddress)(HMODULE hModule, LPCSTR lpProcName);
typedef HMODULE(WINAPI* PFN_GetModuleHandleA)(LPCSTR lpModuleName);
typedef HMODULE(WINAPI* PFN_GetModuleHandleW)(LPCWSTR lpModuleName);
typedef BOOL(WINAPI* PFN_GetModuleHandleExA)(DWORD dwFlags, LPCSTR lpModuleName, HMODULE* phModule);
typedef BOOL(WINAPI* PFN_GetModuleHandleExW)(DWORD dwFlags, LPCWSTR lpModuleName, HMODULE* phModule);
typedef DWORD(WINAPI* PFN_GetFileAttributesW)(LPCWSTR lpFileName);
typedef HANDLE(WINAPI* PFN_CreateFileW)(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition,
DWORD dwFlagsAndAttributes, HANDLE hTemplateFile);
static void Init()
{
@@ -35,7 +36,7 @@ class Kernel32Proxy
_dll = KernelBaseProxy::GetModuleHandleW_()(L"kernel32.dll");
if (_dll == nullptr)
_dll = KernelBaseProxy::LoadLibraryExW_()(L"kernel32.dll", NULL, 0);
_dll = NtdllProxy::LoadLibraryExW_Ldr(L"kernel32.dll", NULL, 0);
if (_dll == nullptr)
return;
+10 -10
View File
@@ -7,16 +7,16 @@
class KernelBaseProxy
{
public:
typedef BOOL (*PFN_FreeLibrary)(HMODULE lpLibrary);
typedef HMODULE (*PFN_LoadLibraryA)(LPCSTR lpLibFileName);
typedef HMODULE (*PFN_LoadLibraryW)(LPCWSTR lpLibFileName);
typedef HMODULE (*PFN_LoadLibraryExA)(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags);
typedef HMODULE (*PFN_LoadLibraryExW)(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags);
typedef FARPROC (*PFN_GetProcAddress)(HMODULE hModule, LPCSTR lpProcName);
typedef HMODULE (*PFN_GetModuleHandleA)(LPCSTR lpModuleName);
typedef HMODULE (*PFN_GetModuleHandleW)(LPCWSTR lpModuleName);
typedef BOOL (*PFN_GetModuleHandleExA)(DWORD dwFlags, LPCSTR lpModuleName, HMODULE* phModule);
typedef BOOL (*PFN_GetModuleHandleExW)(DWORD dwFlags, LPCWSTR lpModuleName, HMODULE* phModule);
typedef BOOL(WINAPI* PFN_FreeLibrary)(HMODULE lpLibrary);
typedef HMODULE(WINAPI* PFN_LoadLibraryA)(LPCSTR lpLibFileName);
typedef HMODULE(WINAPI* PFN_LoadLibraryW)(LPCWSTR lpLibFileName);
typedef HMODULE(WINAPI* PFN_LoadLibraryExA)(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags);
typedef HMODULE(WINAPI* PFN_LoadLibraryExW)(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags);
typedef FARPROC(WINAPI* PFN_GetProcAddress)(HMODULE hModule, LPCSTR lpProcName);
typedef HMODULE(WINAPI* PFN_GetModuleHandleA)(LPCSTR lpModuleName);
typedef HMODULE(WINAPI* PFN_GetModuleHandleW)(LPCWSTR lpModuleName);
typedef BOOL(WINAPI* PFN_GetModuleHandleExA)(DWORD dwFlags, LPCSTR lpModuleName, HMODULE* phModule);
typedef BOOL(WINAPI* PFN_GetModuleHandleExW)(DWORD dwFlags, LPCWSTR lpModuleName, HMODULE* phModule);
static void Init()
{
+8 -11
View File
@@ -5,6 +5,7 @@
#include "Config.h"
#include "Logger.h"
#include <proxies/Ntdll_Proxy.h>
#include <proxies/KernelBase_Proxy.h>
#include "nvapi/NvApiHooks.h"
@@ -427,8 +428,6 @@ class NVNGXProxy
if (_dll == nullptr)
{
State::DisableChecks(333);
do
{
std::wstring libraryName;
@@ -454,7 +453,7 @@ class NVNGXProxy
if (cfgPath.has_filename())
{
_dll = KernelBaseProxy::LoadLibraryExW_()(cfgPath.c_str(), NULL, 0);
_dll = NtdllProxy::LoadLibraryExW_Ldr(cfgPath.c_str(), NULL, 0);
if (_dll)
{
@@ -468,7 +467,7 @@ class NVNGXProxy
auto path = cfgPath / libraryNameUS;
LOG_INFO("trying to load _nvngx.dll path: {0}", wstring_to_string(cfgPath.wstring()));
_dll = KernelBaseProxy::LoadLibraryExW_()(path.c_str(), NULL, 0);
_dll = NtdllProxy::LoadLibraryExW_Ldr(path.c_str(), NULL, 0);
if (_dll)
{
@@ -479,7 +478,7 @@ class NVNGXProxy
path = cfgPath / libraryName;
LOG_INFO("trying to load nvngx.dll path: {0}", wstring_to_string(cfgPath.wstring()));
_dll = KernelBaseProxy::LoadLibraryExW_()(path.c_str(), NULL, 0);
_dll = NtdllProxy::LoadLibraryExW_Ldr(path.c_str(), NULL, 0);
if (_dll)
{
@@ -497,7 +496,7 @@ class NVNGXProxy
auto nvngxPath = regNGXCorePath.value() / libraryNameUS;
LOG_INFO("trying to load _nvngx.dll path: {0}", wstring_to_string(nvngxPath.wstring()));
_dll = KernelBaseProxy::LoadLibraryExW_()(nvngxPath.wstring().c_str(), NULL, 0);
_dll = NtdllProxy::LoadLibraryExW_Ldr(nvngxPath.wstring().c_str(), NULL, 0);
if (_dll)
{
LOG_INFO("_nvngx.dll loaded from {0}, ptr: {1:X}", wstring_to_string(nvngxPath.wstring()),
@@ -508,7 +507,7 @@ class NVNGXProxy
nvngxPath = regNGXCorePath.value() / libraryName;
LOG_INFO("trying to load nvngx.dll path: {0}", wstring_to_string(nvngxPath.wstring()));
_dll = KernelBaseProxy::LoadLibraryExW_()(nvngxPath.wstring().c_str(), NULL, 0);
_dll = NtdllProxy::LoadLibraryExW_Ldr(nvngxPath.wstring().c_str(), NULL, 0);
if (_dll)
{
LOG_INFO("nvngx.dll loaded from {0}, ptr: {1:X}", wstring_to_string(nvngxPath.wstring()),
@@ -525,7 +524,7 @@ class NVNGXProxy
auto nvngxPath = sysPath / libraryNameUS;
LOG_INFO("trying to load _nvngx.dll path: {0}", wstring_to_string(nvngxPath.wstring()));
_dll = KernelBaseProxy::LoadLibraryExW_()(nvngxPath.wstring().c_str(), NULL, 0);
_dll = NtdllProxy::LoadLibraryExW_Ldr(nvngxPath.wstring().c_str(), NULL, 0);
if (_dll)
{
LOG_INFO("_nvngx.dll loaded from {0}, ptr: {1:X}", wstring_to_string(nvngxPath.wstring()),
@@ -536,14 +535,12 @@ class NVNGXProxy
nvngxPath = sysPath / libraryName;
LOG_INFO("trying to load nvngx.dll path: {0}", wstring_to_string(nvngxPath.wstring()));
_dll = KernelBaseProxy::LoadLibraryExW_()(nvngxPath.wstring().c_str(), NULL, 0);
_dll = NtdllProxy::LoadLibraryExW_Ldr(nvngxPath.wstring().c_str(), NULL, 0);
if (_dll)
LOG_INFO("nvngx.dll loaded from {0}, ptr: {1:X}", wstring_to_string(nvngxPath.wstring()),
(ULONG64) _dll);
} while (false);
State::EnableChecks(333);
}
if (_dll != nullptr)
+120
View File
@@ -0,0 +1,120 @@
#pragma once
#include <pch.h>
#include <detours/detours.h>
#include <winternl.h>
class NtdllProxy
{
public:
typedef NTSTATUS(NTAPI* PFN_LdrLoadDll)(PWSTR PathToFile OPTIONAL, PULONG Flags OPTIONAL,
PUNICODE_STRING ModuleFileName, PHANDLE ModuleHandle);
typedef NTSTATUS(NTAPI* PFN_NtLoadDll)(PUNICODE_STRING PathToFile OPTIONAL, PULONG Flags OPTIONAL,
PUNICODE_STRING ModuleFileName, PHANDLE ModuleHandle);
typedef NTSTATUS(NTAPI* PFN_LdrUnloadDll)(PVOID ModuleHandle);
static HMODULE LoadLibraryExW_Ldr(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
{
UNICODE_STRING uName;
o_RtlInitUnicodeString(&uName, lpLibFileName);
// LdrLoadDll wants a ULONG*, so stash flags here:
ULONG flags = dwFlags;
// This will receive the module handle:
HANDLE hModule = nullptr;
NTSTATUS status = o_LdrLoadDll(nullptr, // PathToFile we rely on the default search order
&flags, // optional flags
&uName, // the name of the DLL
&hModule // out: module handle
);
if (NT_SUCCESS(status))
{
return static_cast<HMODULE>(hModule);
}
else
{
// translate NTSTATUS to a Win32 error code:
SetLastError(o_RtlNtStatusToDosError(status));
return nullptr;
}
}
static NTSTATUS FreeLibrary_Ldr(PVOID handle) { return o_LdrUnloadDll(handle); }
static void Init()
{
if (o_RtlInitUnicodeString != nullptr)
return;
_dll = GetModuleHandleW(L"ntdll.dll");
if (_dll == nullptr)
return;
o_RtlInitUnicodeString = (PFN_RtlInitUnicodeString) GetProcAddress(_dll, "RtlInitUnicodeString");
o_RtlNtStatusToDosError = (PFN_RtlNtStatusToDosError) GetProcAddress(_dll, "RtlNtStatusToDosError");
o_LdrLoadDll = (PFN_LdrLoadDll) GetProcAddress(_dll, "LdrLoadDll");
o_LdrUnloadDll = (PFN_LdrUnloadDll) GetProcAddress(_dll, "LdrUnloadDll");
o_NtLoadDll = (PFN_NtLoadDll) GetProcAddress(_dll, "NtLoadDll");
}
static HMODULE Module() { return _dll; }
static PFN_LdrLoadDll Hook_LdrLoadDll(PVOID method)
{
auto addr = o_LdrLoadDll;
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&) addr, method);
DetourTransactionCommit();
o_LdrLoadDll = addr;
return addr;
}
static PFN_LdrUnloadDll Hook_LdrUnloadDll(PVOID method)
{
auto addr = o_LdrUnloadDll;
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&) addr, method);
DetourTransactionCommit();
o_LdrUnloadDll = addr;
return addr;
}
static PFN_NtLoadDll Hook_NtLoadDll(PVOID method)
{
auto addr = o_NtLoadDll;
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&) addr, method);
DetourTransactionCommit();
o_NtLoadDll = addr;
return addr;
}
private:
typedef VOID(NTAPI* PFN_RtlInitUnicodeString)(PUNICODE_STRING DestinationString, PCWSTR SourceString);
typedef ULONG(NTAPI* PFN_RtlNtStatusToDosError)(NTSTATUS Status);
inline static HMODULE _dll = nullptr;
inline static PFN_LdrLoadDll o_LdrLoadDll = nullptr;
inline static PFN_LdrUnloadDll o_LdrUnloadDll = nullptr;
inline static PFN_NtLoadDll o_NtLoadDll = nullptr;
inline static PFN_RtlInitUnicodeString o_RtlInitUnicodeString = nullptr;
inline static PFN_RtlNtStatusToDosError o_RtlNtStatusToDosError = nullptr;
};
+2 -1
View File
@@ -5,6 +5,7 @@
#include "Config.h"
#include "Logger.h"
#include <proxies/Ntdll_Proxy.h>
#include <proxies/KernelBase_Proxy.h>
#include <xefg_swapchain.h>
@@ -192,7 +193,7 @@ class XeFGProxy
{
std::filesystem::path libXeFGPath = dllPath.parent_path() / libraryName;
LOG_INFO("Trying to load libxess_fg.dll from dll path: {}", libXeFGPath.string());
mainModule = KernelBaseProxy::LoadLibraryExW_()(libXeFGPath.c_str(), NULL, 0);
mainModule = NtdllProxy::LoadLibraryExW_Ldr(libXeFGPath.c_str(), NULL, 0);
}
if (mainModule != nullptr)
+2 -1
View File
@@ -5,6 +5,7 @@
#include "Config.h"
#include "Logger.h"
#include <proxies/Ntdll_Proxy.h>
#include <proxies/KernelBase_Proxy.h>
#include <xell.h>
@@ -170,7 +171,7 @@ class XeLLProxy
{
std::filesystem::path libXeLLPath = dllPath.parent_path() / libraryName;
LOG_INFO("Trying to load libxell.dll from dll path: {}", libXeLLPath.string());
mainModule = KernelBaseProxy::LoadLibraryExW_()(libXeLLPath.c_str(), NULL, 0);
mainModule = NtdllProxy::LoadLibraryExW_Ldr(libXeLLPath.c_str(), NULL, 0);
}
} while (false);
+12 -11
View File
@@ -5,6 +5,7 @@
#include "Config.h"
#include "Logger.h"
#include <proxies/Ntdll_Proxy.h>
#include <proxies/KernelBase_Proxy.h>
#include <inputs/XeSS_Common.h>
@@ -255,14 +256,14 @@ class XeSSProxy
LOG_INFO("Trying to load libxess.dll from ini path: {}", cfgPath.string());
cfgPath = cfgPath / libraryName;
mainModule = KernelBaseProxy::LoadLibraryExW_()(cfgPath.c_str(), NULL, 0);
mainModule = NtdllProxy::LoadLibraryExW_Ldr(cfgPath.c_str(), NULL, 0);
}
if (mainModule == nullptr)
{
std::filesystem::path libXessPath = dllPath.parent_path() / libraryName;
LOG_INFO("Trying to load libxess.dll from dll path: {}", libXessPath.string());
mainModule = KernelBaseProxy::LoadLibraryExW_()(libXessPath.c_str(), NULL, 0);
mainModule = NtdllProxy::LoadLibraryExW_Ldr(libXessPath.c_str(), NULL, 0);
}
if (mainModule != nullptr)
@@ -298,14 +299,14 @@ class XeSSProxy
LOG_INFO("Trying to load libxess.dll from ini path: {}", cfgPath.string());
auto dx11Path = cfgPath.parent_path() / libraryName;
dx11Module = KernelBaseProxy::LoadLibraryExW_()(dx11Path.c_str(), NULL, 0);
dx11Module = NtdllProxy::LoadLibraryExW_Ldr(dx11Path.c_str(), NULL, 0);
}
if (dx11Module == nullptr)
{
std::filesystem::path libXessDx11Path = dllPath.parent_path() / libraryName;
LOG_INFO("Trying to load libxess.dll from dll path: {}", libXessDx11Path.string());
dx11Module = KernelBaseProxy::LoadLibraryExW_()(libXessDx11Path.c_str(), NULL, 0);
dx11Module = NtdllProxy::LoadLibraryExW_Ldr(libXessDx11Path.c_str(), NULL, 0);
}
} while (false);
@@ -324,7 +325,7 @@ class XeSSProxy
if (_dll != nullptr && _xessD3D12CreateContext != nullptr)
return true;
spdlog::info("");
LOG_DEBUG("Loading XeSS methods from: {:X}", (size_t) libxessModule);
if (libxessModule != nullptr)
_dll = libxessModule;
@@ -334,9 +335,9 @@ class XeSSProxy
std::filesystem::path libPath(Config::Instance()->XeSSLibrary.value().c_str());
if (libPath.has_filename())
_dll = KernelBaseProxy::LoadLibraryExW_()(libPath.c_str(), NULL, 0);
_dll = NtdllProxy::LoadLibraryExW_Ldr(libPath.c_str(), NULL, 0);
else
_dll = KernelBaseProxy::LoadLibraryExW_()((libPath / L"libxess.dll").c_str(), NULL, 0);
_dll = NtdllProxy::LoadLibraryExW_Ldr((libPath / L"libxess.dll").c_str(), NULL, 0);
if (_dll != nullptr)
{
@@ -346,7 +347,7 @@ class XeSSProxy
if (_dll == nullptr)
{
_dll = KernelBaseProxy::LoadLibraryExW_()(L"libxess.dll", NULL, 0);
_dll = NtdllProxy::LoadLibraryExW_Ldr(L"libxess.dll", NULL, 0);
if (_dll != nullptr)
LOG_INFO("libxess.dll loaded from exe folder");
@@ -622,9 +623,9 @@ class XeSSProxy
std::filesystem::path libPath(Config::Instance()->XeSSDx11Library.value().c_str());
if (libPath.has_filename())
_dlldx11 = KernelBaseProxy::LoadLibraryExW_()(libPath.c_str(), NULL, 0);
_dlldx11 = NtdllProxy::LoadLibraryExW_Ldr(libPath.c_str(), NULL, 0);
else
_dlldx11 = KernelBaseProxy::LoadLibraryExW_()((libPath / L"libxess_dx11.dll").c_str(), NULL, 0);
_dlldx11 = NtdllProxy::LoadLibraryExW_Ldr((libPath / L"libxess_dx11.dll").c_str(), NULL, 0);
if (_dlldx11 != nullptr)
{
@@ -635,7 +636,7 @@ class XeSSProxy
if (_dlldx11 == nullptr)
{
_dlldx11 = KernelBaseProxy::LoadLibraryExW_()(L"libxess_dx11.dll", NULL, 0);
_dlldx11 = NtdllProxy::LoadLibraryExW_Ldr(L"libxess_dx11.dll", NULL, 0);
if (_dlldx11 != nullptr)
LOG_INFO("libxess_dx11.dll loaded from exe folder");