HidHide: Refactor unpatching Valve hooks

pull/175/head
Peter Repukat 2 years ago
parent 8a40649d0f
commit b522117169

@ -20,7 +20,6 @@ limitations under the License.
#include "HidHide.h"
#include <iostream>
#include <numeric>
#include <spdlog/spdlog.h>
#include <vector>
@ -147,112 +146,38 @@ void HidHide::UnPatchValveHooks()
{
spdlog::debug("Unpatching Valve HID hooks...");
// need to load addresses that way.. Otherwise we land before some jumps...
auto setupapidll = GetModuleHandle(L"setupapi.dll");
if (setupapidll) {
BYTE* addr = reinterpret_cast<BYTE*>(GetProcAddress(setupapidll, "SetupDiEnumDeviceInfo"));
if (addr) {
UnPatchHook(addr, SETUP_DI_ENUM_DEV_INFO_ORIG_BYTES);
spdlog::trace("Unpatched SetupDiEnumDeviceInfo");
}
else {
spdlog::error("failed to unpatch SetupDiEnumDeviceInfo");
}
//addr = reinterpret_cast<BYTE*>(GetProcAddress(setupapidll, "SetupDiGetClassDevsW"));
//if (addr) {
// UnPatchHook(addr, SETUP_DI_GETCLASSDEVSW_ORIG_BYTES);
// spdlog::trace("Unpatched SetupDiGetClassDevsW");
//}
//else {
// spdlog::error("failed to unpatch SetupDiGetClassDevsW");
//}
}
auto hiddll = GetModuleHandle(L"hid.dll");
if (hiddll) {
BYTE* addr = reinterpret_cast<BYTE*>(GetProcAddress(hiddll, "HidD_GetPreparsedData"));
if (addr) {
UnPatchHook(addr, HID_GETPREPARSED_ORIG_BYTES);
spdlog::trace("Unpatched HidD_GetPreparsedData");
}
else {
spdlog::error("failed to unpatch HidD_GetPreparsedData");
}
addr = reinterpret_cast<BYTE*>(GetProcAddress(hiddll, "HidP_GetCaps"));
if (addr) {
UnPatchHook(addr, HID_GETCAPS_ORIG_BYTES);
spdlog::trace("Unpatched HidP_GetCaps");
}
else {
spdlog::error("failed to unpatch HidP_GetCaps");
}
addr = reinterpret_cast<BYTE*>(GetProcAddress(hiddll, "HidD_GetAttributes"));
if (addr) {
UnPatchHook(addr, HID_GETATTRS_ORIG_BYTES);
spdlog::trace("Unpatched HidD_GetAttributes");
}
else {
spdlog::error("failed to unpatch HidD_GetAttributes");
}
addr = reinterpret_cast<BYTE*>(GetProcAddress(hiddll, "HidD_GetProductString"));
if (addr) {
UnPatchHook(addr, HID_GETPRODSTR_ORIG_BYTES);
spdlog::trace("Unpatched HidD_GetProductString");
}
else {
spdlog::error("failed to unpatch HidD_GetProductString");
}
addr = reinterpret_cast<BYTE*>(GetProcAddress(hiddll, "HidP_GetUsages"));
if (addr) {
UnPatchHook(addr, HID_GETUSAGE_ORIG_BYTES);
spdlog::trace("Unpatched HidP_GetUsages");
}
else {
spdlog::error("failed to unpatch HidP_GetUsages");
}
addr = reinterpret_cast<BYTE*>(GetProcAddress(hiddll, "HidP_GetData"));
if (addr) {
UnPatchHook(addr, HID_GETDATA_ORIG_BYTES);
spdlog::trace("Unpatched HidP_GetData");
}
else {
spdlog::error("failed to unpatch HidP_GetData");
}
addr = reinterpret_cast<BYTE*>(GetProcAddress(hiddll, "HidP_GetValueCaps"));
if (addr) {
UnPatchHook(addr, HID_GETVALUECAPS_ORIG_BYTES);
spdlog::trace("Unpatched HidP_GetValueCaps");
}
else {
spdlog::error("failed to unpatch HidP_GetValueCaps");
}
addr = reinterpret_cast<BYTE*>(GetProcAddress(hiddll, "HidP_GetUsageValue"));
if (addr) {
UnPatchHook(addr, HID_GETUSAGE_VAL_ORIG_BYTES);
spdlog::trace("Unpatched HidP_GetUsageValue");
}
else {
spdlog::error("failed to unpatch HidP_GetUsageValue");
}
addr = reinterpret_cast<BYTE*>(GetProcAddress(hiddll, "HidP_GetButtonCaps"));
if (addr) {
UnPatchHook(addr, HID_GETBTNCAPS_VAL_ORIG_BYTES);
spdlog::trace("Unpatched HidP_GetButtonCaps");
}
else {
spdlog::error("failed to unpatch HidP_GetButtonCaps");
if (const auto setupapidll = GetModuleHandle(L"setupapi.dll")) {
UnPatchHook("SetupDiEnumDeviceInfo", setupapidll);
//UnPatchHook("SetupDiGetClassDevsW", setupapidll);
}
if (const auto hiddll = GetModuleHandle(L"hid.dll")) {
for (const auto& name : ORIGINAL_BYTES | std::views::keys) {
if (name.starts_with("Hid")) {
UnPatchHook(name, hiddll);
}
}
}
}
void HidHide::UnPatchHook(BYTE* address, const std::string& bytes)
void HidHide::UnPatchHook(const std::string& name, HMODULE module)
{
spdlog::trace("Patching \"{}\"...", name);
BYTE* address = reinterpret_cast<BYTE*>(GetProcAddress(module, name.c_str()));
if (!address) {
spdlog::error("failed to unpatch \"{}\"", name);
}
auto 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..
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) = bytes[i];
}
VirtualProtect(address, len, dw_old_protect, &dw_bkup); //Revert permission change...
VirtualProtect(address, len, dw_old_protect, &dw_bkup); // Revert permission change...
spdlog::trace("Unpatched \"{}\"", name);
}
void HidHide::enableOverlayElement()

@ -22,6 +22,7 @@ limitations under the License.
#include <SetupAPI.h>
#include <array>
#include <filesystem>
#include <map>
#include <string>
#include <vector>
#include <SFML/System/Clock.hpp>
@ -68,32 +69,24 @@ class HidHide {
private:
HANDLE hidhide_handle = nullptr;
// Valve Hooks `SetupDiEnumDeviceInfo` and hides Gaming devices like this.
// Valve Hooks various functions and hides Gaming devices like this.
// To be able to query them, unpatch the hook with the original bytes...
static inline const std::string SETUP_DI_ENUM_DEV_INFO_ORIG_BYTES = "\x48\x89\x5C\x24\x08";
// Valve also Hooks `SetupDiGetClassDevsW` ..unhook that as well...
static inline const std::string SETUP_DI_GETCLASSDEVSW_ORIG_BYTES = "\x48\x89\x5C\x24\x08";
// Valve also Hooks `HidD_GetPreparsedData` ..unhook that as well...
static inline const std::string HID_GETPREPARSED_ORIG_BYTES = "\x48\x89\x5C\x24\x18";
// ..aand `HidP_GetCaps`
static inline const std::string HID_GETCAPS_ORIG_BYTES = "\x4C\x8B\xD1\x48\x85\xC9";
// ...aaand `HidD_GetAttributes`
static inline const std::string HID_GETATTRS_ORIG_BYTES = "\x40\x53\x48\x83\xEC";
// ...aaaaand `HidD_GetProductString`
static inline const std::string HID_GETPRODSTR_ORIG_BYTES = "\x48\x83\xEC\x48\x48";
// ...aaaaand `HidP_GetUsages`
static inline const std::string HID_GETUSAGE_ORIG_BYTES = "\x4C\x89\x4C\x24\x20";
// ...aaaaand `HidP_GetData`
static inline const std::string HID_GETDATA_ORIG_BYTES = "\x4C\x89\x44\x24\x18";
// ...aaaaand `HidP_GetValueCaps`
static inline const std::string HID_GETVALUECAPS_ORIG_BYTES = "\x48\x83\xEC\x48\x49";
// ...aaaaand `HidP_GetUsageValue`
static inline const std::string HID_GETUSAGE_VAL_ORIG_BYTES = "\x40\x53\x55\x56\x48";
// ...aaaaand `HidP_GetButtonCaps`
static inline const std::string HID_GETBTNCAPS_VAL_ORIG_BYTES = "\x48\x83\xEC\x48\x49";
static inline const std::map<std::string, std::string> ORIGINAL_BYTES = {
{"SetupDiEnumDeviceInfo", "\x48\x89\x5C\x24\x08"},
{"SetupDiGetClassDevsW", "\x48\x89\x5C\x24\x08"},
{"HidD_GetPreparsedData", "\x48\x89\x5C\x24\x18"},
{"HidP_GetCaps", "\x4C\x8B\xD1\x48\x85\xC9"},
{"HidD_GetAttributes", "\x40\x53\x48\x83\xEC"},
{"HidD_GetProductString", "\x48\x83\xEC\x48\x48"},
{"HidP_GetUsages", "\x4C\x89\x4C\x24\x20"},
{"HidP_GetData", "\x4C\x89\x44\x24\x18"},
{"HidP_GetValueCaps", "\x48\x83\xEC\x48\x49"},
{"HidP_GetUsageValue", "\x40\x53\x55\x56\x48"},
{"HidP_GetButtonCaps", "\x48\x83\xEC\x48\x49"},
};
static void UnPatchValveHooks();
static void UnPatchHook(BYTE* address, const std::string& bytes);
static void UnPatchHook(const std::string& name, HMODULE module);
void enableOverlayElement();
sf::Clock overlay_elem_clock_;

Loading…
Cancel
Save