mirror of
https://github.com/optiscaler/OptiScaler.git
synced 2026-08-25 07:36:45 +00:00
Added optional User32 EnumDisplayDevicesA & EnumDisplayDevicesW spoofing
This commit is contained in:
@@ -844,6 +844,9 @@ Registry=auto
|
||||
; string value - Default (auto) is 32.0.15.7302 (For Nvidia)
|
||||
RegistryDriver=auto
|
||||
|
||||
; Spoofs Vendor ID, Device ID at User32 level
|
||||
; true or false - Default (auto) is false
|
||||
User32=auto
|
||||
|
||||
|
||||
; -------------------------------------------------------
|
||||
|
||||
@@ -589,6 +589,7 @@ bool Config::Reload(std::filesystem::path iniPath)
|
||||
UESpoofIntelAtomics64.set_from_config(readBool("Spoofing", "UEIntelAtomics"));
|
||||
SpoofRegistry.set_from_config(readBool("Spoofing", "Registry"));
|
||||
SpoofedDriver.set_from_config(readWString("Spoofing", "RegistryDriver"));
|
||||
SpoofUser32.set_from_config(readBool("Spoofing", "User32"));
|
||||
}
|
||||
|
||||
// Inputs
|
||||
@@ -1248,6 +1249,7 @@ bool Config::SaveIni()
|
||||
ini.SetValue("Spoofing", "Registry", GetBoolValue(Instance()->SpoofRegistry.value_for_config()).c_str());
|
||||
ini.SetValue("Spoofing", "RegistryDriver",
|
||||
wstring_to_string(Instance()->SpoofedDriver.value_for_config_or(L"auto")).c_str());
|
||||
ini.SetValue("Spoofing", "User32", GetBoolValue(Instance()->SpoofUser32.value_for_config()).c_str());
|
||||
|
||||
// Enable HAGS when DLSS-G will be used
|
||||
if (!Instance()->SpoofHAGS.has_value())
|
||||
|
||||
@@ -406,6 +406,7 @@ class Config
|
||||
CustomOptional<std::wstring> SpoofedGPUName { L"NVIDIA GeForce RTX 4090" };
|
||||
CustomOptional<bool> UESpoofIntelAtomics64 { false };
|
||||
CustomOptional<bool> SpoofRegistry { false };
|
||||
CustomOptional<bool> SpoofUser32 { false };
|
||||
CustomOptional<std::wstring> SpoofedDriver { L"32.0.15.7302" };
|
||||
|
||||
// Plugins
|
||||
|
||||
@@ -318,6 +318,7 @@ copy NUL "$(SolutionDir)x64\Release\a\!! EXTRACT ALL FILES TO GAME FOLDER !!" /Y
|
||||
<ClInclude Include="hooks\FG_Hooks.h" />
|
||||
<ClInclude Include="hooks\LibraryLoad_Hooks.h" />
|
||||
<ClInclude Include="hooks\CommandBuffer_StateTracker.h" />
|
||||
<ClInclude Include="spoofing\User32_Spoofing.h" />
|
||||
<ClInclude Include="hooks\VulkanwDx12_Hooks.h" />
|
||||
<ClInclude Include="inputs\FSR2_Dx11.h" />
|
||||
<ClInclude Include="inputs\FSR2_Vk.h" />
|
||||
@@ -566,6 +567,7 @@ copy NUL "$(SolutionDir)x64\Release\a\!! EXTRACT ALL FILES TO GAME FOLDER !!" /Y
|
||||
<ClCompile Include="shaders\Shader_Dx12.cpp" />
|
||||
<ClCompile Include="shaders\Shader_Vk.cpp" />
|
||||
<ClCompile Include="spoofing\Dxgi_Spoofing.cpp" />
|
||||
<ClCompile Include="spoofing\User32_Spoofing.cpp" />
|
||||
<ClCompile Include="spoofing\Vulkan_Spoofing.cpp" />
|
||||
<ClCompile Include="upscalers\fsr2_212\FSR2Feature_VkOnDx12_212.cpp" />
|
||||
<ClCompile Include="upscalers\fsr31\FSR31Feature_VkOn12.cpp" />
|
||||
|
||||
@@ -764,6 +764,9 @@
|
||||
<ClInclude Include="shaders\output_scaling\precompile\bcds_lanczos3_Shader_Vk.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="spoofing\User32_Spoofing.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Config.cpp">
|
||||
@@ -1169,6 +1172,9 @@
|
||||
<ClCompile Include="shaders\render_ui\RUI_Dx12.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="spoofing\User32_Spoofing.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="OptiScaler.rc" />
|
||||
|
||||
+16
-5
@@ -10,11 +10,6 @@
|
||||
#include "proxies/Dxgi_Proxy.h"
|
||||
#include <proxies/XeSS_Proxy.h>
|
||||
#include <proxies/NVNGX_Proxy.h>
|
||||
#include <hooks/Gdi32_Hooks.h>
|
||||
#include <hooks/Wintrust_Hooks.h>
|
||||
#include <hooks/Crypt32_Hooks.h>
|
||||
#include <hooks/Advapi32_Hooks.h>
|
||||
#include <hooks/Streamline_Hooks.h>
|
||||
#include "proxies/Kernel32_Proxy.h"
|
||||
#include "proxies/KernelBase_Proxy.h"
|
||||
#include "proxies/Ntdll_Proxy.h"
|
||||
@@ -36,8 +31,16 @@
|
||||
#include <hooks/Vulkan_Hooks.h>
|
||||
#include <hooks/Ntdll_Hooks.h>
|
||||
#include <hooks/Kernel_Hooks.h>
|
||||
#include <hooks/Gdi32_Hooks.h>
|
||||
#include <hooks/Wintrust_Hooks.h>
|
||||
#include <hooks/Crypt32_Hooks.h>
|
||||
#include <hooks/Advapi32_Hooks.h>
|
||||
#include <hooks/Streamline_Hooks.h>
|
||||
|
||||
#include <nvapi/NvApiHooks.h>
|
||||
|
||||
#include "spoofing/User32_Spoofing.h"
|
||||
|
||||
#include <cwctype>
|
||||
#include <version_check.h>
|
||||
|
||||
@@ -878,7 +881,15 @@ static void CheckWorkingMode()
|
||||
// Advapi32
|
||||
if (Config::Instance()->DxgiSpoofing.value_or_default() ||
|
||||
Config::Instance()->StreamlineSpoofing.value_or_default())
|
||||
{
|
||||
hookAdvapi32();
|
||||
}
|
||||
|
||||
// User32
|
||||
if (Config::Instance()->SpoofUser32.value_or_default())
|
||||
{
|
||||
User32Spoofing::Hook();
|
||||
}
|
||||
|
||||
// hook streamline right away if it's already loaded
|
||||
HMODULE slModule = nullptr;
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
#include <pch.h>
|
||||
#include "User32_Spoofing.h"
|
||||
|
||||
#include <Config.h>
|
||||
|
||||
#include <detours/detours.h>
|
||||
|
||||
typedef BOOL(WINAPI* PFN_EnumDisplayDevicesA)(PSTR lpDevice, uint32_t iDevNum, DISPLAY_DEVICEA* lpDisplayDevice,
|
||||
uint32_t dwFlags);
|
||||
typedef BOOL(WINAPI* PFN_EnumDisplayDevicesW)(PWSTR lpDevice, uint32_t iDevNum, DISPLAY_DEVICEW* lpDisplayDevice,
|
||||
uint32_t dwFlags);
|
||||
|
||||
static PFN_EnumDisplayDevicesA o_EnumDisplayDevicesA = nullptr;
|
||||
static PFN_EnumDisplayDevicesW o_EnumDisplayDevicesW = nullptr;
|
||||
|
||||
inline static BOOL WINAPI hkEnumDisplayDevicesA(PSTR lpDevice, uint32_t iDevNum, DISPLAY_DEVICEA* lpDisplayDevice,
|
||||
uint32_t dwFlags)
|
||||
{
|
||||
auto result = o_EnumDisplayDevicesA(lpDevice, iDevNum, lpDisplayDevice, dwFlags);
|
||||
|
||||
if (!result || lpDisplayDevice == nullptr)
|
||||
return result;
|
||||
|
||||
static std::string vendorId = std::format("VEN_{:04X}", Config::Instance()->SpoofedVendorId.value_or_default());
|
||||
static std::string deviceId = std::format("DEV_{:04X}", Config::Instance()->SpoofedDeviceId.value_or_default());
|
||||
|
||||
// Spoof DeviceString (GPU name)
|
||||
auto gpuName = wstring_to_string(Config::Instance()->SpoofedGPUName.value_or_default());
|
||||
strncpy_s(lpDisplayDevice->DeviceString, gpuName.c_str(), sizeof(lpDisplayDevice->DeviceString) - 1);
|
||||
|
||||
// Spoof VEN_/DEV_ tokens in DeviceID (e.g. "PCI\VEN_1002&DEV_687F&...")
|
||||
std::string deviceIdStr(lpDisplayDevice->DeviceID);
|
||||
bool found = false;
|
||||
|
||||
static const char* srcVendors[] = { "VEN_1002", "VEN_8086" };
|
||||
for (auto srcVendor : srcVendors)
|
||||
{
|
||||
size_t pos = 0;
|
||||
while ((pos = deviceIdStr.find(srcVendor, pos)) != std::string::npos)
|
||||
{
|
||||
deviceIdStr.replace(pos, 8, vendorId);
|
||||
pos += vendorId.size();
|
||||
found = true;
|
||||
}
|
||||
if (found)
|
||||
break;
|
||||
}
|
||||
|
||||
if (found)
|
||||
{
|
||||
size_t pos = 0;
|
||||
while ((pos = deviceIdStr.find("DEV_", pos)) != std::string::npos)
|
||||
{
|
||||
deviceIdStr.replace(pos, 8, deviceId);
|
||||
pos += deviceId.size();
|
||||
}
|
||||
strncpy_s(lpDisplayDevice->DeviceID, deviceIdStr.c_str(), sizeof(lpDisplayDevice->DeviceID) - 1);
|
||||
LOG_INFO("Spoofed DeviceID: {}", deviceIdStr);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
inline static BOOL WINAPI hkEnumDisplayDevicesW(PWSTR lpDevice, uint32_t iDevNum, DISPLAY_DEVICEW* lpDisplayDevice,
|
||||
uint32_t dwFlags)
|
||||
{
|
||||
auto result = o_EnumDisplayDevicesW(lpDevice, iDevNum, lpDisplayDevice, dwFlags);
|
||||
|
||||
if (!result || lpDisplayDevice == nullptr)
|
||||
return result;
|
||||
|
||||
static std::wstring vendorId = std::format(L"VEN_{:04X}", Config::Instance()->SpoofedVendorId.value_or_default());
|
||||
static std::wstring deviceId = std::format(L"DEV_{:04X}", Config::Instance()->SpoofedDeviceId.value_or_default());
|
||||
|
||||
// Spoof DeviceString (GPU name)
|
||||
auto gpuName = Config::Instance()->SpoofedGPUName.value_or_default();
|
||||
wcsncpy_s(lpDisplayDevice->DeviceString, gpuName.c_str(),
|
||||
sizeof(lpDisplayDevice->DeviceString) / sizeof(wchar_t) - 1);
|
||||
|
||||
// Spoof VEN_/DEV_ tokens in DeviceID (e.g. L"PCI\VEN_1002&DEV_687F&...")
|
||||
std::wstring deviceIdStr(lpDisplayDevice->DeviceID);
|
||||
bool found = false;
|
||||
|
||||
static const wchar_t* srcVendors[] = { L"VEN_1002", L"VEN_8086" };
|
||||
for (auto srcVendor : srcVendors)
|
||||
{
|
||||
size_t pos = 0;
|
||||
while ((pos = deviceIdStr.find(srcVendor, pos)) != std::wstring::npos)
|
||||
{
|
||||
deviceIdStr.replace(pos, 8, vendorId);
|
||||
pos += vendorId.size();
|
||||
found = true;
|
||||
}
|
||||
if (found)
|
||||
break;
|
||||
}
|
||||
|
||||
if (found)
|
||||
{
|
||||
size_t pos = 0;
|
||||
while ((pos = deviceIdStr.find(L"DEV_", pos)) != std::wstring::npos)
|
||||
{
|
||||
deviceIdStr.replace(pos, 8, deviceId);
|
||||
pos += deviceId.size();
|
||||
}
|
||||
wcsncpy_s(lpDisplayDevice->DeviceID, deviceIdStr.c_str(),
|
||||
sizeof(lpDisplayDevice->DeviceID) / sizeof(wchar_t) - 1);
|
||||
LOG_INFO("Spoofed DeviceID: {}", wstring_to_string(deviceIdStr));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void User32Spoofing::Hook()
|
||||
{
|
||||
LOG_FUNC();
|
||||
|
||||
o_EnumDisplayDevicesA =
|
||||
reinterpret_cast<PFN_EnumDisplayDevicesA>(DetourFindFunction("User32.dll", "EnumDisplayDevicesA"));
|
||||
o_EnumDisplayDevicesW =
|
||||
reinterpret_cast<PFN_EnumDisplayDevicesW>(DetourFindFunction("User32.dll", "EnumDisplayDevicesW"));
|
||||
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
|
||||
if (o_EnumDisplayDevicesA)
|
||||
DetourAttach(&(PVOID&) o_EnumDisplayDevicesA, hkEnumDisplayDevicesA);
|
||||
|
||||
if (o_EnumDisplayDevicesW)
|
||||
DetourAttach(&(PVOID&) o_EnumDisplayDevicesW, hkEnumDisplayDevicesW);
|
||||
|
||||
DetourTransactionCommit();
|
||||
}
|
||||
|
||||
void User32Spoofing::Unhook()
|
||||
{
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
|
||||
if (o_EnumDisplayDevicesA)
|
||||
{
|
||||
DetourDetach(&(PVOID&) o_EnumDisplayDevicesA, hkEnumDisplayDevicesA);
|
||||
o_EnumDisplayDevicesA = nullptr;
|
||||
}
|
||||
|
||||
if (o_EnumDisplayDevicesW)
|
||||
{
|
||||
DetourDetach(&(PVOID&) o_EnumDisplayDevicesW, hkEnumDisplayDevicesW);
|
||||
o_EnumDisplayDevicesW = nullptr;
|
||||
}
|
||||
|
||||
DetourTransactionCommit();
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include "SysUtils.h"
|
||||
|
||||
|
||||
class User32Spoofing
|
||||
{
|
||||
public:
|
||||
static void Hook();
|
||||
static void Unhook();
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
Reference in New Issue
Block a user