Merge branch 'develop'

pull/184/head 0.0.9.1
Peter Repukat 2 years ago
commit 711a0cd2ed

@ -752,7 +752,7 @@ Item {
}
}
Button {
text: qsTr("Done")
text: qsTr("Save")
highlighted: true
enabled: nameInput.acceptableInput
onClicked: function() {

@ -167,6 +167,7 @@ void AppLauncher::getProcessHwnds()
#ifdef _WIN32
void AppLauncher::UnPatchValveHooks()
{
// TODO: move and re-use reusable unhook util from HidHide.cpp
spdlog::debug("Unpatching Valve CreateProcess hook...");
// need to load addresses that way.. Otherwise we may land before some jumps...
auto kernel32dll = GetModuleHandle(L"kernel32.dll");
@ -176,12 +177,18 @@ void AppLauncher::UnPatchValveHooks()
DWORD dw_old_protect, dw_bkup;
const auto len = CREATE_PROC_ORIG_BYTES.size();
VirtualProtect(address, len, PAGE_EXECUTE_READWRITE, &dw_old_protect); //Change permissions of memory..
for (DWORD i = 0; i < len; i++) //unpatch Valve's hook
{
*(address + i) = CREATE_PROC_ORIG_BYTES[i];
const auto opcode = *(address);
if (opcode != 0xE9 && opcode != 0xE8 && opcode != 0xEB && opcode != 0xEA && opcode != 0xFF) {
spdlog::debug("\"CreateProcessW\" Doesn't appear to be hooked, skipping!");
VirtualProtect(address, len, dw_old_protect, &dw_bkup); // Revert permission change...
} else {
for (DWORD i = 0; i < len; i++) // unpatch Valve's hook
{
*(address + i) = CREATE_PROC_ORIG_BYTES[i];
}
VirtualProtect(address, len, dw_old_protect, &dw_bkup); // Revert permission change...
spdlog::trace("Unpatched CreateProcessW");
}
VirtualProtect(address, len, dw_old_protect, &dw_bkup); //Revert permission change...
spdlog::trace("Unpatched CreateProcessW");
}
else {
spdlog::error("failed to unpatch CreateProcessW");

@ -68,6 +68,10 @@ void HidHide::closeCtrlDevice()
void HidHide::hideDevices(const std::filesystem::path& steam_path)
{
if (!Settings::devices.hideDevices) {
spdlog::info("Hiding devices is disabled; Not un-patching valve hooks, not looking for HidHide");
return;
}
UnPatchValveHooks();
openCtrlDevice();
@ -169,7 +173,7 @@ void HidHide::UnPatchValveHooks()
for (const auto& name : ORIGINAL_BYTES | std::views::keys) {
if (name.starts_with("Hid")) {
UnPatchHook(name, hiddll);
}
}
}
}
}
@ -182,12 +186,22 @@ void HidHide::UnPatchHook(const std::string& name, HMODULE module)
if (!address) {
spdlog::error("failed to unpatch \"{}\"", name);
}
auto bytes = ORIGINAL_BYTES.at(name);
std::string bytes;
if (Settings::isWin10 && ORIGINAL_BYTES_WIN10.contains(name)) {
bytes = ORIGINAL_BYTES_WIN10.at(name);
} else {
bytes = ORIGINAL_BYTES.at(name);
}
DWORD dw_old_protect, dw_bkup;
const auto len = bytes.size();
VirtualProtect(address, len, PAGE_EXECUTE_READWRITE, &dw_old_protect); // Change permissions of memory..
for (DWORD i = 0; i < len; i++) //unpatch Valve's hook
const auto opcode = *(address);
if (!std::ranges::any_of(JUMP_INSTR_OPCODES, [&opcode](const auto& op) { return op == opcode; })) {
spdlog::debug("\"{}\" Doesn't appear to be hooked, skipping!", name);
VirtualProtect(address, len, dw_old_protect, &dw_bkup); // Revert permission change...
return;
}
for (DWORD i = 0; i < len; i++) // unpatch Valve's hook
{
*(address + i) = bytes[i];
}
@ -496,6 +510,12 @@ HidHide::SmallHidInfo HidHide::GetDeviceInfo(const DeviceInstancePath& instance_
res.name = (HidD_GetProductString(device_object.get(), buffer.data(), static_cast<ULONG>(sizeof(WCHAR) * buffer.size()))
? buffer
: L"");
for (size_t i = 0; i < res.name.size(); ++i) {
if (res.name[i] == L'\0') {
res.name.resize(i + 1);
break;
}
}
// Valve emulated gamepad PID/VID; mirrord by ViGEm
if (attributes.VendorID == 0x28de /* && attributes.ProductID == 0x11FF*/) {
res.name = std::wstring(L"ViGEm Emulated: ") + res.name;

@ -85,6 +85,19 @@ class HidHide {
{"HidP_GetButtonCaps", "\x48\x83\xEC\x48\x49"},
};
static inline const std::map<std::string, std::string> ORIGINAL_BYTES_WIN10 = {
{"SetupDiEnumDeviceInfo", "\x40\x53\x56\x57\x41\x54\x41\x55"},
{"SetupDiGetClassDevsW", "\x48\x8B\xC4\x48\x89\x58\x08"},
};
static inline const std::vector<uint8_t> JUMP_INSTR_OPCODES = {
0xE9,
0xE8,
0xEB,
0xEA,
0xFF
};
static void UnPatchValveHooks();
static void UnPatchHook(const std::string& name, HMODULE module);

@ -250,7 +250,7 @@ void Overlay::showLogs(ImGuiID dockspace_id)
return res;
});
}
if (logs.empty() || ( !enabled_ && !logs_contain_warn_or_worse && time_since_start_clock_.getElapsedTime().asSeconds() > HIDE_NORMAL_LOGS_AFTER_S))
if (logs.empty() || ( !enabled_ && !force_enable_ && !logs_contain_warn_or_worse && time_since_start_clock_.getElapsedTime().asSeconds() > HIDE_NORMAL_LOGS_AFTER_S))
return;
ImGui::SetNextWindowSizeConstraints({150, 150}, {1000, window_.getSize().y - 250.f});
if (!enabled_) {

@ -23,6 +23,12 @@ limitations under the License.
#include <locale>
#include <codecvt>
#ifdef WIN32
#define NOMINMAX
#include <Windows.h>
#endif
namespace Settings {
inline struct Launch {
@ -56,6 +62,7 @@ inline bool extendedLogging = false;
inline std::filesystem::path settings_path_ = "";
inline bool checkIsUwp(const std::wstring& launch_path)
{
if (launch_path.find(L"://") != std::wstring::npos) {
@ -68,6 +75,45 @@ inline bool checkIsUwp(const std::wstring& launch_path)
return false;
}
#ifdef WIN32
inline bool isWin10 = false;
typedef LONG NTSTATUS, *PNTSTATUS;
#define STATUS_SUCCESS (0x00000000)
typedef NTSTATUS(WINAPI* RtlGetVersionPtr)(PRTL_OSVERSIONINFOW);
inline RTL_OSVERSIONINFOW GetRealOSVersion()
{
HMODULE hMod = ::GetModuleHandleW(L"ntdll.dll");
if (hMod) {
RtlGetVersionPtr fxPtr = (RtlGetVersionPtr)::GetProcAddress(hMod, "RtlGetVersion");
if (fxPtr != nullptr) {
RTL_OSVERSIONINFOW rovi = {0};
rovi.dwOSVersionInfoSize = sizeof(rovi);
if (STATUS_SUCCESS == fxPtr(&rovi)) {
return rovi;
}
}
}
RTL_OSVERSIONINFOW rovi = {0};
return rovi;
}
inline void checkWinVer()
{
auto VN = GetRealOSVersion();
isWin10 = VN.dwBuildNumber < 22000;
if (isWin10) {
spdlog::info("Running on Windows 10");
} else {
spdlog::info("Running on Windows 11");
}
}
#endif
inline void Parse(std::wstring arg1)
{
if (!arg1.ends_with(L".json")) {
@ -156,8 +202,7 @@ inline void Parse(std::wstring arg1)
json_file.close();
// c++ is stupid...
spdlog::debug(L"Read config file \"{}\"; config: {}", path.wstring(), std::filesystem::path(json.dump()).wstring());
spdlog::debug("Read config file \"{}\"; config: {}", path.string(), json.dump());
if (launch.launch) {
launch.isUWP = checkIsUwp(launch.launchPath);

@ -158,6 +158,7 @@ int main(int argc, char* argv[])
argsv += i == 1 ? args[i] : std::wstring(L" ") + args[i];
}
Settings::Parse(argsv);
Settings::checkWinVer();
SteamTarget target;
#else // Code below is broken now due to parse requiring std::wstring instead of std:string. Sorry.
std::string argsv = "";

@ -55,6 +55,7 @@ There are two (known to me, at time of writing) ways to get a working overlay fo
#include <spdlog/spdlog.h>
#include <fstream>
#include <chrono>
enum ZBID
{
@ -89,6 +90,10 @@ std::atomic<bool> allow_exit = false;
std::atomic<ZBID> to_set_window_band = ZBID_SYSTEM_TOOLS;
std::chrono::time_point<std::chrono::system_clock> start_time;
static constexpr int hook_timeout_seconds_ = 60;
BOOL WINAPI SetGlosSIWindowBand(HWND hWnd, HWND hwndInsertAfter, DWORD dwBand)
{
subhook::ScopedHookRemove remove(&SetWindowBandHook);
@ -103,6 +108,13 @@ BOOL WINAPI SetGlosSIWindowBand(HWND hWnd, HWND hwndInsertAfter, DWORD dwBand)
auto success = SetWindowBand(glossi_hwnd, nullptr, to_set_window_band);
allow_exit = true;
spdlog::info("Set GlosSI Window Band to {}; success: {}", static_cast<int>(to_set_window_band), success);
} else if (allow_exit == false) {
const auto time = std::chrono::system_clock::now();
if (std::chrono::duration_cast<std::chrono::seconds>(time - start_time).count() > hook_timeout_seconds_)
{
spdlog::info("GlosSI Window not found after {} seconds, exiting", hook_timeout_seconds_);
allow_exit = true;
}
}
return SetWindowBand(hWnd, hwndInsertAfter, dwBand);
}
@ -208,6 +220,7 @@ BOOL APIENTRY DllMain( HMODULE hModule,
const auto hpath = LoadLibrary(L"user32.dll");
if (hpath)
{
start_time = std::chrono::system_clock::now();
spdlog::debug("Loaded user32.dll");
spdlog::debug("Installing SetWindowBand hook");
SetWindowBand = reinterpret_cast<fSetWindowBand>(GetProcAddress(hpath, "SetWindowBand"));

2
deps/ViGEmClient vendored

@ -1 +1 @@
Subproject commit c8c312ef33d6112dbb8b86d5cd80d25716d32ff1
Subproject commit 3bc2cee48ab0b10b5dd31323a621677175cfb00d

@ -1,3 +1,3 @@
Invoke-WebRequest -o ViGEmBusSetup_x64.exe https://github.com/ViGEm/ViGEmBus/releases/download/v1.18.367.0/ViGEmBus_1.18.367_x64_x86.exe
Invoke-WebRequest -o ViGEmBusSetup_x64.exe https://github.com/ViGEm/ViGEmBus/releases/download/v1.21.442.0/ViGEmBus_1.21.442_x64_x86_arm64.exe
Invoke-WebRequest -o HidHideSetup.exe https://github.com/ViGEm/HidHide/releases/download/v1.2.98.0/HidHide_1.2.98_x64.exe
Invoke-WebRequest -o vc_redist.x64.exe https://aka.ms/vs/16/release/vc_redist.x64.exe
Loading…
Cancel
Save