Goddamnit Valve!

pull/130/head
Peter Repukat 3 years ago
parent bc585e0232
commit 7ed33cc21b

@ -43,7 +43,7 @@ DEFINE_GUID(GUID_DEVINTERFACE_XUSB, 0xEC87F1E3, 0xC13B, 0x4100, 0xB5, 0xF7, 0x8B
// {00000000-0000-0000-FFFF-FFFFFFFFFFFF} the system container id
DEFINE_GUID(GUID_CONTAINER_ID_SYSTEM, 0x00000000, 0x0000, 0x0000, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF);
HidHide::HidHide() = default;
HidHide::HidHide(){};
void HidHide::openCtrlDevice()
{
@ -68,6 +68,8 @@ void HidHide::closeCtrlDevice()
void HidHide::hideDevices(const std::filesystem::path& steam_path)
{
UnPatchValveHooks();
openCtrlDevice();
auto active = getActive();
if (active) {
@ -109,14 +111,18 @@ void HidHide::hideDevices(const std::filesystem::path& steam_path)
if (std::ranges::none_of(blacklisted_devices_, [&dev](const auto& blackdev) {
return blackdev == dev.device_instance_path || blackdev == dev.base_container_device_instance_path;
})) {
if (!dev.device_instance_path.empty()) {
blacklisted_devices_.push_back(dev.device_instance_path);
}
if (!dev.device_instance_path.empty()) {
blacklisted_devices_.push_back(dev.base_container_device_instance_path);
// Valve emulated gamepad PID/VID; mirrord by ViGEm
if (!(dev.vendor_id == 0x28de && dev.product_id == 0x11FF)) {
if (!dev.device_instance_path.empty()) {
blacklisted_devices_.push_back(dev.device_instance_path);
}
if (!dev.device_instance_path.empty()) {
blacklisted_devices_.push_back(dev.base_container_device_instance_path);
}
}
}
}
// TODO: remove all vigem controllers added by GlosSI
setBlacklistDevices(blacklisted_devices_);
setActive(true);
closeCtrlDevice();
@ -132,6 +138,110 @@ void HidHide::disableHidHide()
spdlog::info("Un-hid Gaming Devices");
}
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");
}
}
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");
}
}
}
void HidHide::UnPatchHook(BYTE* address, const std::string& bytes)
{
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
{
*(address + i) = bytes[i];
}
VirtualProtect(address, len, dw_old_protect, &dw_bkup); //Revert permission change...
}
void HidHide::enableOverlayElement()
{
Overlay::AddOverlayElem([this]() {
@ -329,6 +439,7 @@ std::vector<HidHide::SmallHidInfo> HidHide::GetHidDeviceList()
}
auto device_instance_paths = BufferToStringVec(buffer);
device_instance_paths.erase(
std::ranges::remove_if(
device_instance_paths,
@ -419,6 +530,8 @@ HidHide::SmallHidInfo HidHide::GetDeviceInfo(const DeviceInstancePath& instance_
}
res.base_container_device_instance_path = BaseContainerDeviceInstancePath(instance_path);
res.gaming_device = IsGamingDevice(attributes, capabilities);
res.vendor_id = attributes.VendorID;
res.product_id = attributes.ProductID;
return res;
}

@ -50,6 +50,8 @@ class HidHide {
DeviceInstancePath device_instance_path;
DeviceInstancePath base_container_device_instance_path;
std::filesystem::path symlink;
USHORT vendor_id;
USHORT product_id;
bool gaming_device = false;
};
@ -66,6 +68,31 @@ class HidHide {
private:
HANDLE hidhide_handle = nullptr;
// Valve Hooks `SetupDiEnumDeviceInfo` 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 `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 void UnPatchValveHooks();
static void UnPatchHook(BYTE* address, const std::string& bytes);
void enableOverlayElement();
sf::Clock overlay_elem_clock_;

Loading…
Cancel
Save