├── HidHide ├── Version.rc ├── HidHideMSIb.bmp ├── HidHideMSId.bmp ├── src │ ├── Device.h │ ├── Driver.h │ ├── ControlDevice.h │ ├── Device.c │ ├── Driver.c │ ├── Logging.h │ ├── ControlDevice.c │ ├── Config.h │ └── Logging.c ├── resource.h ├── HidHide.wprp ├── stdafx.h ├── HidHide.vcxproj.filters ├── ReinstallDriver.cmd ├── HidHide.inf └── HidHide.man ├── Watchdog ├── AppIcon.rc ├── favicon.ico ├── Main.cpp ├── Directory.Build.props ├── .editorconfig ├── vcpkg.json ├── Directory.Build.targets ├── ETWUtil.h ├── vcpkg-configuration.json ├── resource.h ├── resource1.h ├── README.md ├── App.hpp ├── Watchdog.vcxproj.filters ├── Watchdog.rc └── ETWUtil.cpp ├── HidHideCLI ├── Version.rc ├── src │ ├── Application.ico │ ├── Commands.h │ ├── Volume.h │ ├── HID.h │ ├── HidHideCLI.cpp │ ├── Utils.h │ ├── FilterDriverProxy.h │ ├── CommandInterpreter.h │ ├── CommandInterpreter.cpp │ ├── Volume.cpp │ └── Logging.h ├── stdafx.cpp ├── targetver.h ├── HidHideCLI.wprp ├── HidHideCLI.vcxproj.filters ├── stdafx.h ├── resource.h └── HidHideCLI.man ├── README ├── DlgDevices.jpg └── DlgApplications.jpg ├── HidHideClient ├── Version.rc ├── src │ ├── LockOn.ico │ ├── LockOff.ico │ ├── Application.ico │ ├── LockBlank.ico │ ├── HidHideClient.h │ ├── IDropTarget.h │ ├── WhitelistDlg.h │ ├── BlacklistDlg.h │ ├── HidHideClientDlg.h │ ├── HidHideClientDlg.cpp │ └── HidHideClient.cpp ├── stdafx.cpp ├── targetver.h ├── HidHideClient.wprp ├── stdafx.h ├── HidHideClient.vcxproj.filters ├── resource.h └── HidHideClient.man ├── assets ├── hidhide-128x128.png ├── hidhide-logo-dark.png ├── hidhide-logo-light.svg └── hidhide-logo-dark.svg ├── drivers ├── x64 │ ├── HidHide │ │ ├── hidhide.cat │ │ ├── HidHide.sys │ │ ├── LICENSE.rtf │ │ └── HidHide.inf │ └── HidHide.pdb └── HidHide_ARM64.zip ├── .gitmodules ├── .github ├── dependabot.yml └── workflows │ ├── winget.yml │ └── support.yml ├── Setup ├── nefconw.exe ├── nefarius_HidHide_Updater.exe ├── install.cmd └── uninstall.cmd ├── .gitattributes ├── HidHide_x64.ddf ├── HidHide_ARM64.ddf ├── appveyor.yml ├── LICENSE ├── HidHide.sln.DotSettings ├── LICENSE.rtf ├── stage0.ps1 └── .gitignore /HidHide/Version.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nefarius/HidHide/HEAD/HidHide/Version.rc -------------------------------------------------------------------------------- /Watchdog/AppIcon.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nefarius/HidHide/HEAD/Watchdog/AppIcon.rc -------------------------------------------------------------------------------- /Watchdog/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nefarius/HidHide/HEAD/Watchdog/favicon.ico -------------------------------------------------------------------------------- /HidHide/HidHideMSIb.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nefarius/HidHide/HEAD/HidHide/HidHideMSIb.bmp -------------------------------------------------------------------------------- /HidHide/HidHideMSId.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nefarius/HidHide/HEAD/HidHide/HidHideMSId.bmp -------------------------------------------------------------------------------- /HidHideCLI/Version.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nefarius/HidHide/HEAD/HidHideCLI/Version.rc -------------------------------------------------------------------------------- /README/DlgDevices.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nefarius/HidHide/HEAD/README/DlgDevices.jpg -------------------------------------------------------------------------------- /Watchdog/Main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "App.hpp" 3 | 4 | POCO_SERVER_MAIN(App) 5 | -------------------------------------------------------------------------------- /HidHideClient/Version.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nefarius/HidHide/HEAD/HidHideClient/Version.rc -------------------------------------------------------------------------------- /HidHideClient/src/LockOn.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nefarius/HidHide/HEAD/HidHideClient/src/LockOn.ico -------------------------------------------------------------------------------- /README/DlgApplications.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nefarius/HidHide/HEAD/README/DlgApplications.jpg -------------------------------------------------------------------------------- /assets/hidhide-128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nefarius/HidHide/HEAD/assets/hidhide-128x128.png -------------------------------------------------------------------------------- /assets/hidhide-logo-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nefarius/HidHide/HEAD/assets/hidhide-logo-dark.png -------------------------------------------------------------------------------- /HidHideCLI/src/Application.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nefarius/HidHide/HEAD/HidHideCLI/src/Application.ico -------------------------------------------------------------------------------- /HidHideClient/src/LockOff.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nefarius/HidHide/HEAD/HidHideClient/src/LockOff.ico -------------------------------------------------------------------------------- /HidHideClient/src/Application.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nefarius/HidHide/HEAD/HidHideClient/src/Application.ico -------------------------------------------------------------------------------- /HidHideClient/src/LockBlank.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nefarius/HidHide/HEAD/HidHideClient/src/LockBlank.ico -------------------------------------------------------------------------------- /drivers/x64/HidHide/hidhide.cat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nefarius/HidHide/HEAD/drivers/x64/HidHide/hidhide.cat -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "Watchdog/vcpkg"] 2 | path = Watchdog/vcpkg 3 | url = https://github.com/microsoft/vcpkg.git 4 | -------------------------------------------------------------------------------- /HidHideCLI/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // (c) Eric Korff de Gidts 2 | // SPDX-License-Identifier: MIT 3 | // stdafx.cpp 4 | #include "stdafx.h" 5 | -------------------------------------------------------------------------------- /HidHideClient/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // (c) Eric Korff de Gidts 2 | // SPDX-License-Identifier: MIT 3 | // stdafx.cpp 4 | #include "stdafx.h" 5 | -------------------------------------------------------------------------------- /HidHideCLI/targetver.h: -------------------------------------------------------------------------------- 1 | // (c) Eric Korff de Gidts 2 | // SPDX-License-Identifier: MIT 3 | // targetver.h 4 | #pragma once 5 | 6 | #include 7 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "github-actions" 4 | directory: "/" 5 | schedule: 6 | interval: "daily" 7 | -------------------------------------------------------------------------------- /HidHideClient/targetver.h: -------------------------------------------------------------------------------- 1 | // (c) Eric Korff de Gidts 2 | // SPDX-License-Identifier: MIT 3 | // targetver.h 4 | #pragma once 5 | 6 | #include 7 | -------------------------------------------------------------------------------- /Setup/nefconw.exe: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:1482fa240cad984e02206427f1eb211e62c9a44b058484fc3e83ccb5b1a1fbca 3 | size 556968 4 | -------------------------------------------------------------------------------- /Watchdog/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /drivers/HidHide_ARM64.zip: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:6cb54a891918737075c091484d928919d9b9ee99a9e6cd72e9965d1d8be9cab0 3 | size 44754 4 | -------------------------------------------------------------------------------- /drivers/x64/HidHide.pdb: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:456760f76b3c5b0ec71007b33529f77e0251fae03a87335359dac61b1f99688d 3 | size 839680 4 | -------------------------------------------------------------------------------- /drivers/x64/HidHide/HidHide.sys: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:cc53c64e309008b2096f61a789b3f07b2252e9a4d486428452306687db843746 3 | size 69776 4 | -------------------------------------------------------------------------------- /Setup/nefarius_HidHide_Updater.exe: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:e4123488e49fc8fcf74f6036180733bcbeb28ad08e3f0ae401b286aea4cdce18 3 | size 2367400 4 | -------------------------------------------------------------------------------- /HidHideCLI/src/Commands.h: -------------------------------------------------------------------------------- 1 | // (c) Eric Korff de Gidts 2 | // SPDX-License-Identifier: MIT 3 | // Commands.h 4 | #pragma once 5 | 6 | // Extends 7 | #include "CommandInterpreter.h" 8 | -------------------------------------------------------------------------------- /HidHide/src/Device.h: -------------------------------------------------------------------------------- 1 | // (c) Eric Korff de Gidts 2 | // SPDX-License-Identifier: MIT 3 | // Device.h 4 | #pragma once 5 | #include "Logic.h" 6 | 7 | EXTERN_C_START 8 | 9 | _IRQL_requires_same_ 10 | _IRQL_requires_max_(PASSIVE_LEVEL) 11 | NTSTATUS HidHideCreateDevice(_Inout_ PWDFDEVICE_INIT DeviceInit); 12 | 13 | EXTERN_C_END 14 | -------------------------------------------------------------------------------- /.github/workflows/winget.yml: -------------------------------------------------------------------------------- 1 | name: Publish to Winget 2 | on: 3 | release: 4 | types: [released] 5 | 6 | jobs: 7 | publish: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: vedantmgoyal2009/winget-releaser@v2 11 | with: 12 | identifier: Nefarius.HidHide 13 | installers-regex: '\.exe$' 14 | token: ${{ secrets.WINGET_TOKEN }} 15 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | *.cab filter=lfs diff=lfs merge=lfs -text 4 | *.msi filter=lfs diff=lfs merge=lfs -text 5 | *.dll filter=lfs diff=lfs merge=lfs -text 6 | *.exe filter=lfs diff=lfs merge=lfs -text 7 | *.sys filter=lfs diff=lfs merge=lfs -text 8 | *.zip filter=lfs diff=lfs merge=lfs -text 9 | *.pdb filter=lfs diff=lfs merge=lfs -text 10 | -------------------------------------------------------------------------------- /Watchdog/.editorconfig: -------------------------------------------------------------------------------- 1 | # top-most EditorConfig file 2 | root = true 3 | 4 | # Unix-style newlines with a newline ending every file 5 | [*] 6 | charset = utf-8 7 | trim_trailing_whitespace = true 8 | end_of_line = crlf 9 | insert_final_newline = true 10 | 11 | # Tab indentation (no size specified) 12 | [Makefile] 13 | indent_style = tab 14 | 15 | [*.{c,h,cpp,hpp}] 16 | indent_style = space 17 | indent_size = 4 18 | -------------------------------------------------------------------------------- /Watchdog/vcpkg.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hidhide-watchdog", 3 | "version": "1.0.0", 4 | "description": "hidhide-watchdog", 5 | "license": "MIT", 6 | "supports": "!(arm | uwp)", 7 | "dependencies": [ 8 | { 9 | "name": "poco", 10 | "features": [ 11 | "util", 12 | "net", 13 | "json" 14 | ] 15 | }, 16 | "spdlog", 17 | "winreg", 18 | "neflib", 19 | "scope-guard" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /Watchdog/Directory.Build.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | $(MSBuildThisFileDirectory)vcpkg\bootstrap-vcpkg.bat 6 | Bootstrap vcpkg 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Watchdog/ETWUtil.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define WIN32_LEAN_AND_MEAN 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | namespace etw::utils 13 | { 14 | std::expected SetLogEnabled(LPCWSTR channel, bool enabled); 15 | 16 | std::expected StartSession(); 17 | } 18 | -------------------------------------------------------------------------------- /Watchdog/vcpkg-configuration.json: -------------------------------------------------------------------------------- 1 | { 2 | "registries": [ 3 | { 4 | "kind": "git", 5 | "repository": "https://github.com/nefarius/nefarius-vcpkg-registry.git", 6 | "baseline": "a49373c595ad9a64f9b7c935066c1cd59ee960b1", 7 | "packages": [ 8 | "neflib" 9 | ] 10 | } 11 | ], 12 | "default-registry": { 13 | "kind": "builtin", 14 | "baseline": "ef7dbf94b9198bc58f45951adcf1f041fcbc5ea0" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /HidHide/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by Version.rc 4 | 5 | // Next default values for new objects 6 | // 7 | #ifdef APSTUDIO_INVOKED 8 | #ifndef APSTUDIO_READONLY_SYMBOLS 9 | #define _APS_NEXT_RESOURCE_VALUE 101 10 | #define _APS_NEXT_COMMAND_VALUE 40001 11 | #define _APS_NEXT_CONTROL_VALUE 1001 12 | #define _APS_NEXT_SYMED_VALUE 101 13 | #endif 14 | #endif 15 | -------------------------------------------------------------------------------- /Watchdog/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by Watchdog.rc 4 | 5 | // Next default values for new objects 6 | // 7 | #ifdef APSTUDIO_INVOKED 8 | #ifndef APSTUDIO_READONLY_SYMBOLS 9 | #define _APS_NEXT_RESOURCE_VALUE 101 10 | #define _APS_NEXT_COMMAND_VALUE 40001 11 | #define _APS_NEXT_CONTROL_VALUE 1001 12 | #define _APS_NEXT_SYMED_VALUE 101 13 | #endif 14 | #endif 15 | -------------------------------------------------------------------------------- /Watchdog/resource1.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by AppIcon.rc 4 | // 5 | #define IDI_ICON1 101 6 | 7 | // Next default values for new objects 8 | // 9 | #ifdef APSTUDIO_INVOKED 10 | #ifndef APSTUDIO_READONLY_SYMBOLS 11 | #define _APS_NEXT_RESOURCE_VALUE 102 12 | #define _APS_NEXT_COMMAND_VALUE 40001 13 | #define _APS_NEXT_CONTROL_VALUE 1001 14 | #define _APS_NEXT_SYMED_VALUE 101 15 | #endif 16 | #endif 17 | -------------------------------------------------------------------------------- /HidHide_x64.ddf: -------------------------------------------------------------------------------- 1 | ; HidHide cab file for attestation submission 2 | .OPTION EXPLICIT 3 | .Set CabinetFileCountThreshold=0 4 | .Set FolderFileCountThreshold=0 5 | .Set FolderSizeThreshold=0 6 | .Set MaxCabinetSize=0 7 | .Set MaxDiskFileCount=0 8 | .Set MaxDiskSize=0 9 | .Set CompressionType=MSZIP 10 | .Set Cabinet=on 11 | .Set Compress=on 12 | ; x64 13 | .Set CabinetNameTemplate=HidHide_x64.cab 14 | .Set DestinationDir=HidHide_x64 15 | LICENSE.rtf 16 | bin\Release\x64\HidHide.pdb 17 | bin\Release\x64\HidHide\HidHide.inf 18 | bin\Release\x64\HidHide\HidHide.sys -------------------------------------------------------------------------------- /Watchdog/README.md: -------------------------------------------------------------------------------- 1 | # HidHide Watchdog 2 | 3 | Small Windows service checking and rectifying missing device class filter entries. 4 | 5 | ## How to install 6 | 7 | Elevated terminal: 8 | 9 | ```PowerShell 10 | .\HidHideWatchdog.exe /registerService /displayName "HidHide Watchdog" 11 | ``` 12 | 13 | ## 3rd party credits 14 | 15 | - [Fast C++ logging library](https://github.com/gabime/spdlog) 16 | - [POCO C++ Libraries](https://pocoproject.org/) 17 | - [WinReg](https://github.com/GiovanniDicanio/WinReg) 18 | - [nefcon](https://github.com/nefarius/nefcon) 19 | -------------------------------------------------------------------------------- /HidHide_ARM64.ddf: -------------------------------------------------------------------------------- 1 | ; HidHide cab file for attestation submission 2 | .OPTION EXPLICIT 3 | .Set CabinetFileCountThreshold=0 4 | .Set FolderFileCountThreshold=0 5 | .Set FolderSizeThreshold=0 6 | .Set MaxCabinetSize=0 7 | .Set MaxDiskFileCount=0 8 | .Set MaxDiskSize=0 9 | .Set CompressionType=MSZIP 10 | .Set Cabinet=on 11 | .Set Compress=on 12 | ; ARM64 13 | .Set CabinetNameTemplate=HidHide_ARM64.cab 14 | .Set DestinationDir=HidHide_ARM64 15 | LICENSE.rtf 16 | bin\Release\ARM64\HidHide.pdb 17 | bin\Release\ARM64\HidHide\HidHide.inf 18 | bin\Release\ARM64\HidHide\HidHide.sys -------------------------------------------------------------------------------- /Setup/install.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | @setlocal 3 | 4 | set MYDIR=%~dp0 5 | pushd "%MYDIR%" 6 | 7 | RUNDLL32.EXE SETUPAPI.DLL,InstallHinfSection DefaultInstall 128 "%MYDIR%HidHide\HidHide_HID.inf" 8 | RUNDLL32.EXE SETUPAPI.DLL,InstallHinfSection DefaultInstall 128 "%MYDIR%HidHide\HidHide_XNA.inf" 9 | RUNDLL32.EXE SETUPAPI.DLL,InstallHinfSection DefaultInstall 128 "%MYDIR%HidHide\HidHide_XBOX.inf" 10 | 11 | .\devcon.exe classfilter HIDClass upper -HidHide 12 | .\devcon.exe classfilter XnaComposite upper -HidHide 13 | .\devcon.exe classfilter XboxComposite upper -HidHide 14 | 15 | popd 16 | endlocal 17 | -------------------------------------------------------------------------------- /Watchdog/App.hpp: -------------------------------------------------------------------------------- 1 | #ifndef POCO_WINDOWS_SERVICE_APP_H 2 | #define POCO_WINDOWS_SERVICE_APP_H 3 | 4 | #define _SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING 5 | 6 | #include 7 | 8 | class App : public Poco::Util::ServerApplication 9 | { 10 | public: 11 | App() = default; 12 | 13 | ~App() override = default; 14 | 15 | protected: 16 | void initialize(Application& self) override; 17 | 18 | void uninitialize() override; 19 | 20 | int main(const std::vector& args) override; 21 | }; 22 | 23 | 24 | #endif //POCO_WINDOWS_SERVICE_APP_H 25 | -------------------------------------------------------------------------------- /Setup/uninstall.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | @setlocal 3 | 4 | set MYDIR=%~dp0 5 | pushd "%MYDIR%" 6 | 7 | .\devcon.exe classfilter HIDClass upper !HidHide 8 | .\devcon.exe classfilter XnaComposite upper !HidHide 9 | .\devcon.exe classfilter XboxComposite upper !HidHide 10 | 11 | RUNDLL32.EXE SETUPAPI.DLL,InstallHinfSection DefaultUninstall 128 "%MYDIR%HidHide\HidHide_HID.inf" 12 | RUNDLL32.EXE SETUPAPI.DLL,InstallHinfSection DefaultUninstall 128 "%MYDIR%HidHide\HidHide_XNA.inf" 13 | RUNDLL32.EXE SETUPAPI.DLL,InstallHinfSection DefaultUninstall 128 "%MYDIR%HidHide\HidHide_XBOX.inf" 14 | 15 | popd 16 | endlocal 17 | -------------------------------------------------------------------------------- /HidHideClient/src/HidHideClient.h: -------------------------------------------------------------------------------- 1 | // (c) Eric Korff de Gidts 2 | // SPDX-License-Identifier: MIT 3 | // HidHideClient.h 4 | #pragma once 5 | 6 | class CHidHideClientApp : public CWinApp 7 | { 8 | public: 9 | 10 | CHidHideClientApp() noexcept; 11 | CHidHideClientApp(_In_ CHidHideClientApp const& rhs) = delete; 12 | CHidHideClientApp(_In_ CHidHideClientApp&& rhs) noexcept = delete; 13 | CHidHideClientApp& operator=(_In_ CHidHideClientApp const& rhs) = delete; 14 | CHidHideClientApp& operator=(_In_ CHidHideClientApp&& rhs) = delete; 15 | virtual ~CHidHideClientApp(); 16 | 17 | private: 18 | 19 | BOOL InitInstance() override; 20 | 21 | DECLARE_MESSAGE_MAP() 22 | }; 23 | -------------------------------------------------------------------------------- /HidHide/src/Driver.h: -------------------------------------------------------------------------------- 1 | // (c) Eric Korff de Gidts 2 | // SPDX-License-Identifier: MIT 3 | // Driver.h 4 | #pragma once 5 | 6 | EXTERN_C_START 7 | 8 | // Main entry point of device driver called after a driver is loaded and responsible for initializing the driver 9 | DRIVER_INITIALIZE DriverEntry; 10 | 11 | // Notification handler called when the driver has no more device objects after it handles an IRP_MN_REMOVE_DEVICE request 12 | EVT_WDF_DRIVER_UNLOAD HidHideDriverEvtUnload; 13 | 14 | // Notification handler called after a bus driver detects a device that has a hardware identifier (ID) matching a hardware ID this driver supports 15 | EVT_WDF_DRIVER_DEVICE_ADD HidHideDriverEvtDeviceAdd; 16 | 17 | EXTERN_C_END 18 | -------------------------------------------------------------------------------- /HidHide/src/ControlDevice.h: -------------------------------------------------------------------------------- 1 | // (c) Eric Korff de Gidts 2 | // SPDX-License-Identifier: MIT 3 | // ControlDevice.h 4 | #pragma once 5 | 6 | EXTERN_C_START 7 | 8 | // Create the control device and returns 9 | _Must_inspect_result_ 10 | _IRQL_requires_same_ 11 | _IRQL_requires_max_(PASSIVE_LEVEL) 12 | NTSTATUS HidHideControlDeviceCreate( 13 | _In_ WDFDRIVER wdfDriver, 14 | _Out_ WDFDEVICE* wdfControlDevice); 15 | 16 | // Notification handler called when a user-mode application calls DeviceIoControl or when another driver creates a request by calling either WdfIoTargetSendIoctlSynchronously or WdfIoTargetFormatRequestForIoctl 17 | EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL HidHideControlDeviceEvtIoDeviceControl; 18 | 19 | EXTERN_C_END 20 | -------------------------------------------------------------------------------- /HidHideCLI/src/Volume.h: -------------------------------------------------------------------------------- 1 | // (c) Eric Korff de Gidts 2 | // SPDX-License-Identifier: MIT 3 | // Volume.h 4 | #pragma once 5 | 6 | namespace HidHide 7 | { 8 | typedef std::filesystem::path FullImageName; 9 | typedef std::set FullImageNames; 10 | 11 | // Determine the full image name for storage of the file specified while considering mounted folder structures 12 | // Return an empty path when the specified file name can't be stored on any of the volumes present 13 | FullImageName FileNameToFullImageName(_In_ std::filesystem::path const& fullyQualifiedFileName); 14 | 15 | // Determine the file name associated with a full image name 16 | // Return an empty path when the logical file name couldn't be located on any of the volumes present 17 | std::filesystem::path FullImageNameToFileName(_In_ FullImageName const& fullImageName); 18 | } 19 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | version: 1.6.{build}.0 2 | build_cloud: WIN-LKR467JS4GL 3 | image: Windows 4 | configuration: Release 5 | branches: 6 | only: 7 | - master 8 | - /v\d+\.\d+\.\d+/ 9 | skip_commits: 10 | files: 11 | - '**/*.md' 12 | test: off 13 | platform: 14 | - x64 # ARM64 is built in the same job 15 | install: 16 | - cmd: git submodule update --init --recursive 17 | - ps: Setup-VS2022 18 | build: 19 | parallel: true 20 | verbosity: minimal 21 | build_script: 22 | - cmd: msbuild /p:Configuration="Release" /p:Platform="x64" "%APPVEYOR_BUILD_FOLDER%\%APPVEYOR_PROJECT_NAME%.sln" 23 | - cmd: msbuild /p:Configuration="Release" /p:Platform="ARM64" "%APPVEYOR_BUILD_FOLDER%\%APPVEYOR_PROJECT_NAME%.sln" 24 | after_build: 25 | - cmd: makecab.exe /f HidHide_x64.ddf 26 | - cmd: makecab.exe /f HidHide_ARM64.ddf 27 | artifacts: 28 | - path: 'bin**\$(APPVEYOR_PROJECT_NAME)\*.inf' 29 | - path: 'bin**\$(APPVEYOR_PROJECT_NAME)\*.sys' 30 | - path: 'bin**\*.pdb' 31 | - path: 'bin**\*.exe' 32 | - path: 'disk1\*.cab' 33 | deploy: 34 | - provider: Environment 35 | name: BUILDBOT 36 | on: 37 | appveyor_repo_tag: true -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Eric Korff de Gidts 4 | Copyright (c) 2021-2024 Benjamin Höglinger-Stelzer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 7 | 8 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 9 | 10 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 11 | -------------------------------------------------------------------------------- /HidHide/HidHide.wprp: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /HidHideCLI/HidHideCLI.wprp: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /.github/workflows/support.yml: -------------------------------------------------------------------------------- 1 | name: 'Support Requests' 2 | 3 | on: 4 | workflow_run: 5 | workflows: ["*"] 6 | issues: 7 | types: [labeled, unlabeled, reopened] 8 | 9 | permissions: 10 | issues: write 11 | 12 | jobs: 13 | action: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: dessant/support-requests@v4 17 | with: 18 | github-token: ${{ github.token }} 19 | support-label: 'support' 20 | issue-comment: > 21 | :wave: @{issue-author}, we use the issue tracker exclusively 22 | for bug reports and feature requests. However, this issue appears 23 | to be a support request, of low quality or a topic covered in the 24 | documentation. Please consult the documentation first and if that 25 | didn't help use our support channels to get help with your particular 26 | case. In the future kindly read the instructions in the issue template 27 | instead of ignoring it. Failing to do so might result in your account 28 | getting blocked for spam. Your compliance is appreciated. 29 | close-issue: true 30 | lock-issue: true 31 | issue-lock-reason: 'off-topic' 32 | -------------------------------------------------------------------------------- /HidHideCLI/src/HID.h: -------------------------------------------------------------------------------- 1 | // (c) Eric Korff de Gidts 2 | // SPDX-License-Identifier: MIT 3 | // HID.h 4 | #pragma once 5 | 6 | namespace HidHide 7 | { 8 | typedef std::wstring DeviceInstancePath; 9 | 10 | struct HidDeviceInformation 11 | { 12 | bool present; 13 | bool gamingDevice; 14 | std::filesystem::path symbolicLink; 15 | std::wstring vendor; 16 | std::wstring product; 17 | std::wstring serialNumber; 18 | std::wstring usage; 19 | std::wstring description; 20 | DeviceInstancePath deviceInstancePath; 21 | DeviceInstancePath baseContainerDeviceInstancePath; 22 | GUID baseContainerClassGuid; 23 | size_t baseContainerDeviceCount; 24 | }; 25 | 26 | typedef std::multimap> FriendlyNamesAndHidDeviceInformation; 27 | 28 | // Get the device instance paths of the HID devices (present or not) and associated device information and cluster/group them on their device friendly names 29 | FriendlyNamesAndHidDeviceInformation HidDevices(_In_ bool gamingDevicesOnly); 30 | } 31 | -------------------------------------------------------------------------------- /HidHideClient/HidHideClient.wprp: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /HidHide/stdafx.h: -------------------------------------------------------------------------------- 1 | // (c) Eric Korff de Gidts 2 | // SPDX-License-Identifier: MIT 3 | // stdafx.h 4 | #pragma once 5 | #include 6 | #include 7 | #define NTSTRSAFE_NO_CB_FUNCTIONS 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | // Define _countof 14 | #define _countof(array) (sizeof(array) / sizeof(array[0])) 15 | 16 | // Define standard text conversions 17 | #define __L(s) L#s 18 | #define _L(s) __L(s) 19 | 20 | // The typical process PID for system 21 | #define SYSTEM_PID 4 22 | 23 | // API call-back prototype missing so define it here 24 | typedef 25 | _Function_class_(CREATE_PROCESS_NOTIFY_ROUTINE) 26 | _IRQL_requires_same_ 27 | _IRQL_requires_max_(PASSIVE_LEVEL) 28 | VOID 29 | CREATE_PROCESS_NOTIFY_ROUTINE( 30 | _In_ HANDLE ParentId, 31 | _In_ HANDLE ProcessId, 32 | _In_ BOOLEAN Create 33 | ); 34 | 35 | // API call-back prototype missing so define it here 36 | typedef 37 | _Function_class_(LOAD_IMAGE_NOTIFY_ROUTINE) 38 | _IRQL_requires_same_ 39 | _IRQL_requires_max_(DISPATCH_LEVEL) 40 | VOID 41 | LOAD_IMAGE_NOTIFY_ROUTINE( 42 | _In_opt_ PUNICODE_STRING FullImageName, 43 | _In_ HANDLE ProcessId, 44 | _In_ PIMAGE_INFO ImageInfo 45 | ); 46 | 47 | // Include the message file generated by the message compiler from the ETW manifest 48 | #pragma warning(push) 49 | #pragma warning(disable: 26451) // Warning(s) in code generated by the message compiler 50 | #include "HidHideETW.h" 51 | #pragma warning(pop) 52 | -------------------------------------------------------------------------------- /HidHide.sln.DotSettings: -------------------------------------------------------------------------------- 1 | 2 | True 3 | True 4 | True 5 | True 6 | True 7 | True 8 | True 9 | True 10 | True 11 | True 12 | True 13 | True 14 | True -------------------------------------------------------------------------------- /HidHideClient/src/IDropTarget.h: -------------------------------------------------------------------------------- 1 | // (c) Eric Korff de Gidts 2 | // SPDX-License-Identifier: MIT 3 | // IDropTarget.h 4 | #pragma once 5 | 6 | namespace HidHide 7 | { 8 | // Interface for forwarding drop target events 9 | class IDropTarget 10 | { 11 | public: 12 | 13 | // Called when the cursor first enters the window 14 | virtual DROPEFFECT OnDragEnter(_In_ CWnd* pWnd, _In_ COleDataObject* pDataObject, _In_ DWORD dwKeyState, _In_ CPoint point) 15 | { 16 | UNREFERENCED_PARAMETER(pWnd); 17 | UNREFERENCED_PARAMETER(pDataObject); 18 | UNREFERENCED_PARAMETER(dwKeyState); 19 | UNREFERENCED_PARAMETER(point); 20 | return (DROPEFFECT_NONE); 21 | } 22 | 23 | // Called repeatedly when the cursor is dragged over the window 24 | virtual DROPEFFECT OnDragOver(_In_ CWnd* pWnd, _In_ COleDataObject* pDataObject, _In_ DWORD dwKeyState, _In_ CPoint point) 25 | { 26 | UNREFERENCED_PARAMETER(pWnd); 27 | UNREFERENCED_PARAMETER(pDataObject); 28 | UNREFERENCED_PARAMETER(dwKeyState); 29 | UNREFERENCED_PARAMETER(point); 30 | return (DROPEFFECT_NONE); 31 | } 32 | 33 | // Called when data is dropped into the window, initial handler 34 | virtual DROPEFFECT OnDropEx(_In_ CWnd* pWnd, _In_ COleDataObject* pDataObject, _In_ DROPEFFECT dropDefault, _In_ DROPEFFECT dropList, _In_ CPoint point) 35 | { 36 | UNREFERENCED_PARAMETER(pWnd); 37 | UNREFERENCED_PARAMETER(pDataObject); 38 | UNREFERENCED_PARAMETER(dropDefault); 39 | UNREFERENCED_PARAMETER(dropList); 40 | UNREFERENCED_PARAMETER(point); 41 | return (DROPEFFECT_NONE); 42 | } 43 | }; 44 | } 45 | -------------------------------------------------------------------------------- /HidHide/src/Device.c: -------------------------------------------------------------------------------- 1 | // (c) Eric Korff de Gidts 2 | // SPDX-License-Identifier: MIT 3 | // Device.c 4 | #include "stdafx.h" 5 | #include "Device.h" 6 | #include "ControlDevice.h" 7 | #include "Driver.h" 8 | #include "Logging.h" 9 | #include "Logic.h" 10 | 11 | _Use_decl_annotations_ 12 | NTSTATUS HidHideCreateDevice(PWDFDEVICE_INIT wdfDeviceInit) 13 | { 14 | TRACE_ALWAYS(L""); 15 | 16 | WDF_OBJECT_ATTRIBUTES wdfObjectAttributes; 17 | WDF_FILEOBJECT_CONFIG wdfFileObjectConfig; 18 | WDFDEVICE wdfDevice; 19 | NTSTATUS ntstatus; 20 | 21 | // This is a filter 22 | WdfFdoInitSetFilter(wdfDeviceInit); // PASSIVE_LEVEL 23 | 24 | WDF_OBJECT_ATTRIBUTES_INIT(&wdfObjectAttributes); 25 | wdfObjectAttributes.SynchronizationScope = WdfSynchronizationScopeNone; 26 | WDF_FILEOBJECT_CONFIG_INIT(&wdfFileObjectConfig, OnDeviceFileCreate, WDF_NO_EVENT_CALLBACK, OnDeviceFileCleanup); 27 | WdfDeviceInitSetFileObjectConfig(wdfDeviceInit, &wdfFileObjectConfig, &wdfObjectAttributes); 28 | 29 | // Create the device 30 | WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&wdfObjectAttributes, DEVICE_CONTEXT); 31 | wdfObjectAttributes.EvtCleanupCallback = OnDeviceContextCleanup; 32 | ntstatus = WdfDeviceCreate(&wdfDeviceInit, &wdfObjectAttributes, &wdfDevice); 33 | if (!NT_SUCCESS(ntstatus)) LOG_AND_RETURN_NTSTATUS(L"WdfDeviceCreate", ntstatus); 34 | 35 | // Register the device interface 36 | ntstatus = WdfDeviceCreateDeviceInterface(wdfDevice, &HidHideInterfaceGuid, NULL); 37 | if (!NT_SUCCESS(ntstatus)) LOG_AND_RETURN_NTSTATUS(L"WdfDeviceCreateDeviceInterface", ntstatus); 38 | 39 | // Initilize the device context for future usage 40 | ntstatus = OnDeviceCreate(wdfDevice); 41 | if (!NT_SUCCESS(ntstatus)) return (ntstatus); 42 | 43 | return (STATUS_SUCCESS); 44 | } 45 | -------------------------------------------------------------------------------- /HidHide/src/Driver.c: -------------------------------------------------------------------------------- 1 | // (c) Eric Korff de Gidts 2 | // SPDX-License-Identifier: MIT 3 | // Driver.c 4 | #include "stdafx.h" 5 | #include "Driver.h" 6 | #include "Device.h" 7 | #include "Logging.h" 8 | #include "Logic.h" 9 | 10 | _Use_decl_annotations_ 11 | NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath) 12 | { 13 | WDF_DRIVER_CONFIG wdfDriverConfig; 14 | WDFDRIVER wdfDriver; 15 | NTSTATUS ntstatus; 16 | 17 | // Note use DBG_AND_RETURN_NTSTATUS for now till the ETW provides are registered 18 | // Note that INFO_LEVEL and TRACE_LEVEL are suppressed per default; only ERROR_LEVEL is immediately forwarded 19 | 20 | ExInitializeDriverRuntime(DrvRtPoolNxOptIn); 21 | 22 | WDF_DRIVER_CONFIG_INIT(&wdfDriverConfig, NULL); 23 | wdfDriverConfig.EvtDriverDeviceAdd = HidHideDriverEvtDeviceAdd; 24 | wdfDriverConfig.EvtDriverUnload = HidHideDriverEvtUnload; 25 | ntstatus = WdfDriverCreate(pDriverObject, pRegistryPath, WDF_NO_OBJECT_ATTRIBUTES, &wdfDriverConfig, &wdfDriver); 26 | if (!NT_SUCCESS(ntstatus)) DBG_AND_RETURN_NTSTATUS("WdfDriverCreate", ntstatus); 27 | 28 | // Bail out when the environment is tampered with 29 | ntstatus = LogRegisterProviders(); 30 | if (!NT_SUCCESS(ntstatus)) return (ntstatus); 31 | 32 | // Allow logic to act 33 | ntstatus = OnDriverCreate(wdfDriver); 34 | if (!NT_SUCCESS(ntstatus)) return (ntstatus); 35 | 36 | return (ntstatus); 37 | } 38 | 39 | _Use_decl_annotations_ 40 | VOID HidHideDriverEvtUnload(WDFDRIVER wdfDriver) 41 | { 42 | TRACE_ALWAYS(L""); 43 | UNREFERENCED_PARAMETER(wdfDriver); 44 | 45 | LogUnregisterProviders(); 46 | } 47 | 48 | _Use_decl_annotations_ 49 | NTSTATUS 50 | HidHideDriverEvtDeviceAdd(WDFDRIVER wdfDriver, PWDFDEVICE_INIT wdfDeviceInit) 51 | { 52 | TRACE_ALWAYS(L""); 53 | UNREFERENCED_PARAMETER(wdfDriver); 54 | 55 | NTSTATUS ntstatus; 56 | 57 | ntstatus = HidHideCreateDevice(wdfDeviceInit); 58 | return (ntstatus); 59 | } 60 | -------------------------------------------------------------------------------- /Watchdog/Watchdog.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | 29 | 30 | Header Files 31 | 32 | 33 | Header Files 34 | 35 | 36 | Header Files 37 | 38 | 39 | Header Files 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | Resource Files 51 | 52 | 53 | Resource Files 54 | 55 | 56 | 57 | 58 | Resource Files 59 | 60 | 61 | -------------------------------------------------------------------------------- /HidHideCLI/src/HidHideCLI.cpp: -------------------------------------------------------------------------------- 1 | // (c) Eric Korff de Gidts 2 | // SPDX-License-Identifier: MIT 3 | // HidHideCLI.cpp 4 | #include "stdafx.h" 5 | #include "CommandInterpreter.h" 6 | #include "Utils.h" 7 | #include "Logging.h" 8 | 9 | namespace 10 | { 11 | // Main application handling exceptions 12 | _Success_(return == ERROR_SUCCESS) 13 | DWORD MainApplication() noexcept 14 | { 15 | try 16 | { 17 | TRACE_ALWAYS(L""); 18 | HidHide::CommandInterpreter(false).Start(HidHide::CommandLineArguments()); 19 | return (ERROR_SUCCESS); 20 | } 21 | catch (std::exception const& exc) 22 | { 23 | std::wcerr << exc.what() << std::endl; 24 | LOGEXC_AND_RETURN_WIN32; 25 | } 26 | catch (...) 27 | { 28 | std::wcerr << L"Unhandled exception" << std::endl; 29 | LOGEXC_AND_RETURN_WIN32; 30 | } 31 | } 32 | } 33 | 34 | // Register the ETW logging and tracing providers 35 | NTSTATUS WINAPI LogRegisterProviders() noexcept 36 | { 37 | try 38 | { 39 | EventRegisterNefarius_HidHide_CLI(); 40 | EventRegisterNefarius_Drivers_HidHideCLI(); 41 | 42 | // The define for BldProductVersion is passed from the project file to the source code via a define 43 | ::LogEvent(ETW(Started), L"%s", _L(BldProductVersion)); 44 | return (STATUS_SUCCESS); 45 | } 46 | catch (...) 47 | { 48 | DBG_AND_RETURN_NTSTATUS("LogRegisterProviders", STATUS_UNHANDLED_EXCEPTION); 49 | } 50 | } 51 | 52 | // Unregister the ETW logging and tracing providers 53 | NTSTATUS WINAPI LogUnregisterProviders() noexcept 54 | { 55 | try 56 | { 57 | ::LogEvent(ETW(Stopped), L""); 58 | EventUnregisterNefarius_Drivers_HidHideCLI(); 59 | EventUnregisterNefarius_HidHide_CLI(); 60 | return (STATUS_SUCCESS); 61 | } 62 | catch (...) 63 | { 64 | DBG_AND_RETURN_NTSTATUS("LogUnregisterProviders", STATUS_UNHANDLED_EXCEPTION); 65 | } 66 | } 67 | 68 | _Success_(return == ERROR_SUCCESS) 69 | int wmain(int argc, wchar_t* argv[], wchar_t* envp[]) 70 | { 71 | UNREFERENCED_PARAMETER(argc); 72 | UNREFERENCED_PARAMETER(argv); 73 | UNREFERENCED_PARAMETER(envp); 74 | 75 | ::LogRegisterProviders(); 76 | auto const result{ MainApplication() }; 77 | ::LogUnregisterProviders(); 78 | return (static_cast(result)); 79 | } 80 | -------------------------------------------------------------------------------- /HidHideClient/src/WhitelistDlg.h: -------------------------------------------------------------------------------- 1 | // (c) Eric Korff de Gidts 2 | // SPDX-License-Identifier: MIT 3 | // WhitelistDlg.h 4 | #pragma once 5 | #include "IDropTarget.h" 6 | #include "FilterDriverProxy.h" 7 | 8 | class CHidHideClientDlg; 9 | 10 | class CWhitelistDlg : public CDialogEx, public HidHide::IDropTarget 11 | { 12 | DECLARE_DYNAMIC(CWhitelistDlg) 13 | 14 | public: 15 | 16 | CWhitelistDlg(_In_ CHidHideClientDlg& hidHideClientDlg, _In_opt_ CWnd* pParent); 17 | virtual ~CWhitelistDlg(); 18 | 19 | // Called when the cursor first enters the window 20 | DROPEFFECT OnDragEnter(_In_ CWnd* pWnd, _In_ COleDataObject* pDataObject, _In_ DWORD dwKeyState, _In_ CPoint point) override; 21 | 22 | // Called repeatedly when the cursor is dragged over the window 23 | DROPEFFECT OnDragOver(_In_ CWnd* pWnd, _In_ COleDataObject* pDataObject, _In_ DWORD dwKeyState, _In_ CPoint point) override; 24 | 25 | // Called when data is dropped into the window, initial handler 26 | DROPEFFECT OnDropEx(_In_ CWnd* pWnd, _In_ COleDataObject* pDataObject, _In_ DROPEFFECT dropDefault, _In_ DROPEFFECT dropList, _In_ CPoint point) override; 27 | 28 | private: 29 | 30 | // Dialog Data 31 | #ifdef AFX_DESIGN_TIME 32 | enum { IDD = IDD_DIALOG_WHITELIST }; 33 | #endif 34 | 35 | void DoDataExchange(_In_ CDataExchange* pDX) override; 36 | BOOL OnInitDialog() override; 37 | 38 | // Post a request to refresh the list 39 | void Refresh(); 40 | 41 | // Is the mouse pointer in the whitelist control ? 42 | bool MousePointerAtWhitelist(_In_ CPoint point); 43 | 44 | // User Message on CM Notification Callbacks 45 | LRESULT OnUserMessageRefresh(_In_ WPARAM wParam, _In_ LPARAM lParam); 46 | 47 | // The shared filter driver proxy 48 | HidHide::FilterDriverProxy& FilterDriverProxy() noexcept; 49 | 50 | DECLARE_MESSAGE_MAP() 51 | 52 | // The parent 53 | CHidHideClientDlg& m_HidHideClientDlg; 54 | 55 | // Attributes 56 | HidHide::FullImageNames m_DropTargetFullImageNames; 57 | 58 | // Controls 59 | CListBox m_Whitelist; 60 | CStatic m_Guidance; 61 | CButton m_Insert; 62 | CButton m_Delete; 63 | CButton m_Inverse; 64 | 65 | // Events 66 | afx_msg void OnBnClickedButtonWhitelistInsert(); 67 | afx_msg void OnBnClickedButtonWhitelistDelete(); 68 | afx_msg void OnBnClickedCheckInverse(); 69 | afx_msg void OnShowWindow(_In_ BOOL bShow, _In_ UINT nStatus); 70 | }; 71 | -------------------------------------------------------------------------------- /assets/hidhide-logo-light.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /assets/hidhide-logo-dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /HidHideClient/src/BlacklistDlg.h: -------------------------------------------------------------------------------- 1 | // (c) Eric Korff de Gidts 2 | // SPDX-License-Identifier: MIT 3 | // BlacklistDlg.h 4 | #pragma once 5 | #include "IDropTarget.h" 6 | #include "FilterDriverProxy.h" 7 | #include "HID.h" 8 | 9 | class CHidHideClientDlg; 10 | 11 | class CBlacklistDlg : public CDialogEx, public HidHide::IDropTarget 12 | { 13 | DECLARE_DYNAMIC(CBlacklistDlg) 14 | 15 | public: 16 | 17 | CBlacklistDlg() noexcept = delete; 18 | CBlacklistDlg(_In_ CBlacklistDlg const& rhs) = delete; 19 | CBlacklistDlg(_In_ CBlacklistDlg && rhs) noexcept = delete; 20 | CBlacklistDlg& operator=(_In_ CBlacklistDlg const& rhs) = delete; 21 | CBlacklistDlg& operator=(_In_ CBlacklistDlg && rhs) = delete; 22 | 23 | CBlacklistDlg(_In_ CHidHideClientDlg& hidHideClientDlg, _In_opt_ CWnd* pParent); 24 | virtual ~CBlacklistDlg(); 25 | 26 | // Notification handler called when a PnP event of the specified type occurs 27 | // Be sure to handle Plug and Play device events as quickly as possible 28 | DWORD OnCmNotificationCallback(_In_ HCMNOTIFICATION cmNotification, _In_ CM_NOTIFY_ACTION cmNotifyAction, _In_reads_bytes_(cmNotifyEventDataSize) PCM_NOTIFY_EVENT_DATA cmNotifyEventData, _In_ DWORD cmNotifyEventDataSize); 29 | 30 | private: 31 | 32 | // Dialog Data 33 | #ifdef AFX_DESIGN_TIME 34 | enum { IDD = IDD_DIALOG_BLACKLIST }; 35 | #endif 36 | 37 | void DoDataExchange(_In_ CDataExchange* pDX) override; 38 | BOOL OnInitDialog() override; 39 | 40 | // Post a request to refresh the list 41 | void Refresh(); 42 | 43 | // User Message on CM Notification Callbacks 44 | LRESULT OnUserMessageRefresh(_In_ WPARAM wParam, _In_ LPARAM lParam); 45 | 46 | // The shared filter driver proxy 47 | HidHide::FilterDriverProxy& FilterDriverProxy() noexcept; 48 | 49 | DECLARE_MESSAGE_MAP() 50 | 51 | // The parent 52 | CHidHideClientDlg& m_HidHideClientDlg; 53 | 54 | // The item data for the black-list 55 | HidHide::FriendlyNamesAndHidDeviceInformation m_BlacklistItemData; 56 | 57 | // Controls 58 | CTreeCtrl m_Blacklist; 59 | HCMNOTIFICATION m_CmNotificationHandle; 60 | HICON m_LockOn; 61 | HICON m_LockOff; 62 | HICON m_LockBlank; 63 | CImageList m_ImageList; 64 | CButton m_Filter; 65 | CButton m_Gaming; 66 | CButton m_Enable; 67 | CStatic m_Guidance; 68 | 69 | // Events 70 | afx_msg void OnTvnItemChangedTreeBlacklist(_In_ NMHDR* pNMHDR, _Out_ LRESULT* pResult); 71 | afx_msg void OnBnClickedCheckFilter(); 72 | afx_msg void OnBnClickedCheckGaming(); 73 | afx_msg void OnBnClickedCheckEnable(); 74 | afx_msg void OnShowWindow(_In_ BOOL bShow, _In_ UINT nStatus); 75 | }; 76 | -------------------------------------------------------------------------------- /HidHideCLI/src/Utils.h: -------------------------------------------------------------------------------- 1 | // (c) Eric Korff de Gidts 2 | // SPDX-License-Identifier: MIT 3 | // Utils.h 4 | #pragma once 5 | 6 | namespace HidHide 7 | { 8 | // Get the module file name 9 | std::filesystem::path ModuleFileName(); 10 | 11 | // Get the command line arguments while excluding the module file name 12 | std::wstring CommandLineArguments(); 13 | 14 | // Convert the error code into an error text 15 | std::wstring ErrorMessage(_In_ DWORD errorCode); 16 | 17 | // Lookup a value from the string table resource based on the resource id provided 18 | std::wstring StringTable(_In_ UINT stringTableResourceId); 19 | 20 | // Is the standard input based on console input or not (e.g. redirected from a file and/or pipe) 21 | bool StandardInputRedirected(); 22 | 23 | // Convert a guid into a string 24 | std::wstring GuidToString(_In_ GUID const& guid); 25 | 26 | // Determine if the file is an application (.exe, .com, or .bin) 27 | bool FileIsAnApplication(_In_ std::filesystem::path const& fullyQualifiedFileName); 28 | 29 | // Split the string at the white-spaces 30 | std::vector SplitStringAtWhitespaces(_In_ std::wstring const& value); 31 | 32 | // Trim whitespaces at left and right 33 | std::wstring& Trim(_Inout_ std::wstring& value); 34 | 35 | // Convert a string list into a string set 36 | std::set StringListToStringSet(_In_ std::vector const& strings); 37 | 38 | // Convert a string list into a path set 39 | std::set StringListToPathSet(_In_ std::vector const& paths); 40 | 41 | // Convert a string set into a string list 42 | std::vector StringSetToStringList(_In_ std::set const& strings); 43 | 44 | // Convert a path set into a string list 45 | std::vector PathSetToStringList(_In_ std::set const& paths); 46 | 47 | // Convert a multi-string into a list of strings 48 | std::vector MultiStringToStringList(_In_ std::vector const& multiString); 49 | 50 | // Convert a set of strings into a multi-string 51 | std::vector StringListToMultiString(_In_ std::vector const& strings); 52 | 53 | // Get the logical file name that is being dragged 54 | // Returns an empty set when the data dragged isn't a list of files 55 | std::set DragTargetFileNames(_In_ COleDataObject* pDataObject); 56 | 57 | // Determine if the key state matches that of a copy operation (left mouse button + with or without control) 58 | constexpr bool DragTargetCopyOperation(_In_ DWORD keyState) noexcept 59 | { 60 | return ((0 != (MK_LBUTTON & keyState)) && (0 == (MK_MBUTTON & keyState)) && (0 == (MK_RBUTTON & keyState)) && (0 == (MK_SHIFT & keyState)) && (0 == (MK_ALT & keyState))); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Watchdog/Watchdog.rc: -------------------------------------------------------------------------------- 1 | // Microsoft Visual C++ generated resource script. 2 | // 3 | #include "resource.h" 4 | 5 | #define APSTUDIO_READONLY_SYMBOLS 6 | ///////////////////////////////////////////////////////////////////////////// 7 | // 8 | // Generated from the TEXTINCLUDE 2 resource. 9 | // 10 | #include "winres.h" 11 | 12 | ///////////////////////////////////////////////////////////////////////////// 13 | #undef APSTUDIO_READONLY_SYMBOLS 14 | 15 | ///////////////////////////////////////////////////////////////////////////// 16 | // English (United States) resources 17 | 18 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) 19 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 20 | 21 | #ifdef APSTUDIO_INVOKED 22 | ///////////////////////////////////////////////////////////////////////////// 23 | // 24 | // TEXTINCLUDE 25 | // 26 | 27 | 1 TEXTINCLUDE 28 | BEGIN 29 | "resource.h\0" 30 | END 31 | 32 | 2 TEXTINCLUDE 33 | BEGIN 34 | "#include ""winres.h""\r\n" 35 | "\0" 36 | END 37 | 38 | 3 TEXTINCLUDE 39 | BEGIN 40 | "\r\n" 41 | "\0" 42 | END 43 | 44 | #endif // APSTUDIO_INVOKED 45 | 46 | 47 | ///////////////////////////////////////////////////////////////////////////// 48 | // 49 | // Version 50 | // 51 | 52 | #define __T(s) #s 53 | #define _T(s) __T(s) 54 | 55 | VS_VERSION_INFO VERSIONINFO 56 | FILEVERSION BldProductVersionMajor, BldProductVersionMinor, BldProductVersionRevision, BldProductVersionBuild 57 | PRODUCTVERSION BldProductVersionMajor, BldProductVersionMinor, BldProductVersionRevision, BldProductVersionBuild 58 | FILEFLAGSMASK 0x3fL 59 | #ifdef _DEBUG 60 | FILEFLAGS 0x1L 61 | #else 62 | FILEFLAGS 0x0L 63 | #endif 64 | FILEOS 0x40004L 65 | FILETYPE 0x1L 66 | FILESUBTYPE 0x0L 67 | BEGIN 68 | BLOCK "StringFileInfo" 69 | BEGIN 70 | BLOCK "080904b0" 71 | BEGIN 72 | VALUE "CompanyName", _T(BldCompanyName) 73 | VALUE "FileDescription", "HidHide Watchdog service for configuration integrity" 74 | VALUE "FileVersion", _T(BldProductVersion) 75 | VALUE "InternalName", "HidHideWatchdog.exe" 76 | VALUE "LegalCopyright", "Copyright (C) 2023-2024 Nefarius Software Solutions e.U." 77 | VALUE "OriginalFilename", "HidHideWatchdog.exe" 78 | VALUE "ProductName", "HidHide Watchdog service for configuration integrity" 79 | VALUE "ProductVersion", _T(BldProductVersion) 80 | END 81 | END 82 | BLOCK "VarFileInfo" 83 | BEGIN 84 | VALUE "Translation", 0x809, 1200 85 | END 86 | END 87 | 88 | #endif // English (United States) resources 89 | ///////////////////////////////////////////////////////////////////////////// 90 | 91 | 92 | 93 | #ifndef APSTUDIO_INVOKED 94 | ///////////////////////////////////////////////////////////////////////////// 95 | // 96 | // Generated from the TEXTINCLUDE 3 resource. 97 | // 98 | 99 | 100 | ///////////////////////////////////////////////////////////////////////////// 101 | #endif // not APSTUDIO_INVOKED 102 | 103 | -------------------------------------------------------------------------------- /HidHide/HidHide.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {63b290c8-2e6f-487a-815e-7820ed9e2a12} 18 | 19 | 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | Source Files 35 | 36 | 37 | Source Files 38 | 39 | 40 | 41 | 42 | Header Files 43 | 44 | 45 | Header Files 46 | 47 | 48 | Header Files 49 | 50 | 51 | Header Files 52 | 53 | 54 | Header Files 55 | 56 | 57 | Header Files 58 | 59 | 60 | Header Files 61 | 62 | 63 | Header Files 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | Content Files 73 | 74 | 75 | 76 | 77 | Resource Files 78 | 79 | 80 | Resource Files 81 | 82 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /HidHide/ReinstallDriver.cmd: -------------------------------------------------------------------------------- 1 | rem DEPRECATED 2 | @echo off 3 | rem (c) Eric Korff de Gidts 4 | rem SPDX-License-Identifier: MIT 5 | rem ReinstallDriver.cmd 6 | rem 7 | rem Command script requiring administrator rights used for testing purposes at target environment 8 | rem Mount the Visual Studio build output directory as network share and execute this script on the target environment 9 | rem In order to install and/or update the Nefarius HidHide filter device driver 10 | rem 11 | 12 | rem we have to options and per default for the jenkens test job we will deploy the test environment using the installer 13 | if "_%1" == "_" goto :L1 14 | 15 | rem 16 | rem This is the first installation option where we utilize the installer 17 | rem It is typically used for deploying the package in a test environment during production builds 18 | rem 19 | echo Deploy installer 20 | hidhide.exe /install /quiet /log ReinstallDriver.log INSTALLLEVEL=2 21 | goto :L2 22 | 23 | rem 24 | rem This is the second installation option where we bypass the installer 25 | rem It is typically used during development on the PC of the developer 26 | rem 27 | :L1 28 | echo Close eventvwr 29 | pause 30 | 31 | echo Uninstalling the old driver 32 | ".\devcon.exe" classfilter HIDClass upper !HidHide 33 | ".\devcon.exe" classfilter XnaComposite upper !HidHide 34 | ".\devcon.exe" classfilter XboxComposite upper !HidHide 35 | ".\devcon.exe" /r remove "root\HidHide" 36 | del "%windir%\INF\SetupApi.dev.log" > NUL 37 | 38 | echo Updating Nefarius HidHide filter device driver 39 | if not exist "C:\Program Files\Nefarius" mkdir "C:\Program Files\Nefarius" 40 | if not exist "C:\Program Files\Nefarius\HidHide" mkdir "C:\Program Files\Nefarius\HidHide" 41 | copy "HidHide\HidHide.cat" "C:\Program Files\Nefarius\HidHide" /Y > NUL 42 | copy "HidHide\HidHide.sys" "C:\Program Files\Nefarius\HidHide" /Y > NUL 43 | copy "HidHide\HidHide.inf" "C:\Program Files\Nefarius\HidHide" /Y > NUL 44 | copy "HidHide.man" "C:\Program Files\Nefarius\HidHide" /Y > NUL 45 | copy "HidHide.wprp" "C:\Program Files\Nefarius\HidHide" /Y > NUL 46 | 47 | echo Updating Nefarius HidHide client 48 | if not exist "C:\Program Files\Nefarius\HidHideClient" mkdir "C:\Program Files\Nefarius\HidHideClient" 49 | copy "HidHideClient.exe" "C:\Program Files\Nefarius\HidHideClient" /Y > NUL 50 | 51 | echo Updating Symbols 52 | if not exist "C:\Program Files\Nefarius\Symbols" mkdir "C:\Program Files\Nefarius\Symbols" 53 | copy "HidHide.pdb" "C:\Program Files\Nefarius\Symbols" /Y > NUL 54 | copy "HidHideClient.pdb" "C:\Program Files\Nefarius\Symbols" /Y > NUL 55 | 56 | echo Clear logging 57 | wevtutil.exe cl Application 58 | wevtutil.exe cl Security 59 | wevtutil.exe cl Setup 60 | wevtutil.exe cl System 61 | 62 | echo Restart tracing 63 | wevtutil.exe um "C:\Program Files\Nefarius\HidHide\HidHide.man" > NUL 64 | wevtutil.exe im "C:\Program Files\Nefarius\HidHide\HidHide.man" > NUL 65 | wevtutil.exe sl "Nefarius-Drivers-HidHide/Diagnostic" /e:false /q:true > NUL 66 | wevtutil.exe sl "Nefarius-Drivers-HidHide/Diagnostic" /e:true /q:true > NUL 67 | 68 | echo Install device 69 | ".\devcon.exe" /r install "C:\Program Files\Nefarius\HidHide\HidHide.inf" "root\HidHide" 70 | ".\devcon.exe" classfilter HIDClass upper -HidHide 71 | ".\devcon.exe" classfilter XnaComposite upper -HidHide 72 | ".\devcon.exe" classfilter XboxComposite upper -HidHide 73 | 74 | echo Done (inspect %windir%\INF\SetupApi.dev.log when needed) 75 | rem goto :L1 76 | :L2 77 | -------------------------------------------------------------------------------- /Watchdog/ETWUtil.cpp: -------------------------------------------------------------------------------- 1 | #include "ETWUtil.h" 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | using namespace nefarius::utilities; 11 | 12 | 13 | std::expected etw::utils::SetLogEnabled(LPCWSTR channel, bool enabled) 14 | { 15 | EVT_HANDLE config = EvtOpenChannelConfig(NULL, channel, 0); 16 | if (!config) 17 | { 18 | return std::unexpected(Win32Error("EvtOpenChannelConfig")); 19 | } 20 | 21 | auto guard = sg::make_scope_guard( 22 | [ config ]() noexcept 23 | { 24 | if (config) 25 | EvtClose(config); 26 | }); 27 | 28 | EVT_VARIANT logEnabled = {}; 29 | logEnabled.Type = EvtVarTypeBoolean; 30 | logEnabled.BooleanVal = enabled; 31 | 32 | if (!EvtSetChannelConfigProperty(config, EvtChannelConfigEnabled, 0, &logEnabled)) 33 | { 34 | return std::unexpected(Win32Error("EvtSetChannelConfigProperty")); 35 | } 36 | 37 | if (!EvtSaveChannelConfig(config, 0)) 38 | { 39 | return std::unexpected(Win32Error("EvtSaveChannelConfig")); 40 | } 41 | 42 | return {}; 43 | } 44 | 45 | std::expected etw::utils::StartSession() 46 | { 47 | // TODO: example code, finish and test! 48 | 49 | TRACEHANDLE sessionHandle = 0; 50 | EVENT_TRACE_PROPERTIES* sessionProperties = NULL; 51 | DWORD bufferSize = sizeof(EVENT_TRACE_PROPERTIES) + sizeof(TCHAR) * (MAX_PATH + 1); 52 | sessionProperties = (EVENT_TRACE_PROPERTIES*)malloc(bufferSize); 53 | ZeroMemory(sessionProperties, bufferSize); 54 | 55 | // Set the properties for the session 56 | sessionProperties->Wnode.BufferSize = bufferSize; 57 | sessionProperties->Wnode.Flags = WNODE_FLAG_TRACED_GUID; 58 | sessionProperties->Wnode.ClientContext = 1; // QPC clock resolution 59 | sessionProperties->Wnode.Guid = SystemTraceControlGuid; // GUID for kernel tracing 60 | sessionProperties->LogFileMode = EVENT_TRACE_FILE_MODE_SEQUENTIAL; // Use file for output 61 | sessionProperties->MaximumFileSize = 10; // Maximum size of log file in MB 62 | sessionProperties->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES); 63 | sessionProperties->LogFileNameOffset = sizeof(EVENT_TRACE_PROPERTIES) + sizeof(TCHAR) * (MAX_PATH + 1); 64 | 65 | 66 | TCHAR logFileName[MAX_PATH] = TEXT("C:\\ETWLog.etl"); 67 | StringCchCopy((TCHAR*)(((char*)sessionProperties) + sessionProperties->LogFileNameOffset), MAX_PATH, logFileName); 68 | 69 | TCHAR sessionName[MAX_PATH] = TEXT("MyETWSession"); 70 | ULONG status = StartTrace(&sessionHandle, sessionName, sessionProperties); 71 | 72 | if (status != ERROR_SUCCESS) 73 | { 74 | printf("Error starting trace session: %lu\n", status); 75 | //return 1; 76 | } 77 | 78 | printf("ETW session started successfully!\n"); 79 | 80 | status = EnableTraceEx2( 81 | sessionHandle, 82 | &SystemTraceControlGuid, 83 | EVENT_CONTROL_CODE_ENABLE_PROVIDER, 84 | TRACE_LEVEL_VERBOSE, 85 | 0, 86 | 0, 87 | 0, 88 | NULL 89 | ); 90 | 91 | if (status != ERROR_SUCCESS) 92 | { 93 | printf("Error enabling provider: %lu\n", status); 94 | //return 1; 95 | } 96 | 97 | printf("Provider enabled successfully!\n"); 98 | 99 | return {}; 100 | } 101 | -------------------------------------------------------------------------------- /HidHideCLI/HidHideCLI.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | Source Files 35 | 36 | 37 | Source Files 38 | 39 | 40 | Source Files 41 | 42 | 43 | Source Files 44 | 45 | 46 | 47 | 48 | Header Files 49 | 50 | 51 | Header Files 52 | 53 | 54 | Header Files 55 | 56 | 57 | Header Files 58 | 59 | 60 | Header Files 61 | 62 | 63 | Header Files 64 | 65 | 66 | Header Files 67 | 68 | 69 | Header Files 70 | 71 | 72 | Header Files 73 | 74 | 75 | Resource Files 76 | 77 | 78 | 79 | 80 | Resource Files 81 | 82 | 83 | Resource Files 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | Resource Files 95 | 96 | 97 | -------------------------------------------------------------------------------- /HidHideCLI/stdafx.h: -------------------------------------------------------------------------------- 1 | // (c) Eric Korff de Gidts 2 | // SPDX-License-Identifier: MIT 3 | // stdafx.h 4 | #pragma once 5 | 6 | #define VC_EXTRALEAN 7 | #include "targetver.h" 8 | 9 | // COM/MFC related 10 | #define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS 11 | #define _AFX_ALL_WARNINGS 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #ifdef _UNICODE 21 | #if defined _M_IX86 22 | #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"") 23 | #elif defined _M_X64 24 | #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"") 25 | #else 26 | #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") 27 | #endif 28 | #endif 29 | 30 | // Define standard text conversions 31 | #define __L(s) L#s 32 | #define _L(s) __L(s) 33 | 34 | // Resources related 35 | #include "resource.h" 36 | 37 | // Device setup related 38 | #include 39 | #pragma comment(lib, "SetupAPI.lib") 40 | 41 | // Device configuration related 42 | #include 43 | #pragma comment(lib, "Cfgmgr32.lib") 44 | 45 | // Device properties related 46 | #include 47 | #include 48 | #include 49 | #include 50 | 51 | // ETW related 52 | #pragma warning(push) 53 | #pragma warning(disable: 4005) // Duplicate definitions 54 | #include 55 | #pragma warning(pop) 56 | #include 57 | #include 58 | 59 | // As defined in ntdef.h 60 | #define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) 61 | 62 | // HID releated 63 | #include 64 | #include 65 | #pragma comment(lib, "Hid.lib") 66 | 67 | // USB related 68 | #include 69 | 70 | // {D61CA365-5AF4-4486-998B-9DB4734C6CA3}add the XUSB class GUID as it is missing in the public interfaces 71 | DEFINE_GUID(GUID_DEVCLASS_XUSBCLASS, 0xD61CA365, 0x5AF4, 0x4486, 0x99, 0x8B, 0x9D, 0xB4, 0x73, 0x4C, 0x6C, 0xA3); 72 | 73 | // {EC87F1E3-C13B-4100-B5F7-8B84D54260CB} add the XUSB interface class GUID as it is missing in the public interfaces 74 | DEFINE_GUID(GUID_DEVINTERFACE_XUSB, 0xEC87F1E3, 0xC13B, 0x4100, 0xB5, 0xF7, 0x8B, 0x84, 0xD5, 0x42, 0x60, 0xCB); 75 | 76 | // {00000000-0000-0000-FFFF-FFFFFFFFFFFF} the system container id 77 | DEFINE_GUID(GUID_CONTAINER_ID_SYSTEM, 0x00000000, 0x0000, 0x0000, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF); 78 | 79 | // Extend guiddef.h with an operator that enables a GUID to be used in container classes 80 | __inline bool operator<(REFGUID lhs, REFGUID rhs) noexcept 81 | { 82 | return (::memcmp(&lhs, &rhs, sizeof(GUID)) < 0); 83 | } 84 | 85 | // Standard library related 86 | #include 87 | #include 88 | #include 89 | #include 90 | #include 91 | #include 92 | #include 93 | #include 94 | #include 95 | #include 96 | #include 97 | #include 98 | #include 99 | #include 100 | 101 | // Include the message file generated by the message compiler from the ETW manifest 102 | #pragma warning(push) 103 | #pragma warning(disable: 26451) // Warning(s) in code generated by the message compiler 104 | #include "HidHideCLIETW.h" 105 | #pragma warning(pop) 106 | -------------------------------------------------------------------------------- /HidHideClient/stdafx.h: -------------------------------------------------------------------------------- 1 | // (c) Eric Korff de Gidts 2 | // SPDX-License-Identifier: MIT 3 | // stdafx.h 4 | #pragma once 5 | 6 | #define VC_EXTRALEAN 7 | #include "targetver.h" 8 | 9 | // COM/MFC related 10 | #define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS 11 | #define _AFX_ALL_WARNINGS 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #ifdef _UNICODE 21 | #if defined _M_IX86 22 | #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"") 23 | #elif defined _M_X64 24 | #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"") 25 | #else 26 | #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") 27 | #endif 28 | #endif 29 | 30 | // Define standard text conversions 31 | #define __L(s) L#s 32 | #define _L(s) __L(s) 33 | 34 | // Resources related 35 | #include "resource.h" 36 | 37 | // Device setup related 38 | #include 39 | #pragma comment(lib, "SetupAPI.lib") 40 | 41 | // Device configuration related 42 | #include 43 | #pragma comment(lib, "Cfgmgr32.lib") 44 | 45 | // Device properties related 46 | #include 47 | #include 48 | #include 49 | #include 50 | 51 | // ETW related 52 | #pragma warning(push) 53 | #pragma warning(disable: 4005) // Duplicate definitions 54 | #include 55 | #pragma warning(pop) 56 | #include 57 | #include 58 | 59 | // As defined in ntdef.h 60 | #define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) 61 | 62 | // HID releated 63 | #include 64 | #include 65 | #pragma comment(lib, "Hid.lib") 66 | 67 | // USB related 68 | #include 69 | 70 | // {D61CA365-5AF4-4486-998B-9DB4734C6CA3}add the XUSB class GUID as it is missing in the public interfaces 71 | DEFINE_GUID(GUID_DEVCLASS_XUSBCLASS, 0xD61CA365, 0x5AF4, 0x4486, 0x99, 0x8B, 0x9D, 0xB4, 0x73, 0x4C, 0x6C, 0xA3); 72 | 73 | // {EC87F1E3-C13B-4100-B5F7-8B84D54260CB} add the XUSB interface class GUID as it is missing in the public interfaces 74 | DEFINE_GUID(GUID_DEVINTERFACE_XUSB, 0xEC87F1E3, 0xC13B, 0x4100, 0xB5, 0xF7, 0x8B, 0x84, 0xD5, 0x42, 0x60, 0xCB); 75 | 76 | // {00000000-0000-0000-FFFF-FFFFFFFFFFFF} the system container id 77 | DEFINE_GUID(GUID_CONTAINER_ID_SYSTEM, 0x00000000, 0x0000, 0x0000, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF); 78 | 79 | // Extend guiddef.h with an operator that enables a GUID to be used in container classes 80 | __inline bool operator<(REFGUID lhs, REFGUID rhs) noexcept 81 | { 82 | return (::memcmp(&lhs, &rhs, sizeof(GUID)) < 0); 83 | } 84 | 85 | // Standard library related 86 | #include 87 | #include 88 | #include 89 | #include 90 | #include 91 | #include 92 | #include 93 | #include 94 | #include 95 | #include 96 | #include 97 | #include 98 | #include 99 | #include 100 | 101 | // Include the message file generated by the message compiler from the ETW manifest 102 | #pragma warning(push) 103 | #pragma warning(disable: 26451) // Warning(s) in code generated by the message compiler 104 | #include "HidHideClientETW.h" 105 | #pragma warning(pop) 106 | -------------------------------------------------------------------------------- /HidHideClient/src/HidHideClientDlg.h: -------------------------------------------------------------------------------- 1 | // (c) Eric Korff de Gidts 2 | // SPDX-License-Identifier: MIT 3 | // HidHideClientDlg.h 4 | #pragma once 5 | #include "IDropTarget.h" 6 | #include "BlacklistDlg.h" 7 | #include "WhitelistDlg.h" 8 | 9 | class CHidHideClientDlg : public CDialogEx, public HidHide::IDropTarget 10 | { 11 | public: 12 | 13 | CHidHideClientDlg() noexcept = delete; 14 | CHidHideClientDlg(_In_ CHidHideClientDlg const& rhs) = delete; 15 | CHidHideClientDlg(_In_ CHidHideClientDlg&& rhs) noexcept = delete; 16 | CHidHideClientDlg& operator=(_In_ CHidHideClientDlg const& rhs) = delete; 17 | CHidHideClientDlg& operator=(_In_ CHidHideClientDlg&& rhs) = delete; 18 | 19 | explicit CHidHideClientDlg(_In_opt_ CWnd* pParent); 20 | virtual ~CHidHideClientDlg() = default; 21 | 22 | // Allow child dialogs access to the shared filter driver proxy 23 | HidHide::FilterDriverProxy& FilterDriverProxy() noexcept; 24 | 25 | private: 26 | 27 | // Handler for drop target events 28 | class CDropTarget : public COleDropTarget 29 | { 30 | public: 31 | 32 | CDropTarget(_In_ CDropTarget const& rhs) = delete; 33 | CDropTarget(_In_ CDropTarget&& rhs) noexcept = delete; 34 | CDropTarget& operator=(_In_ CDropTarget const& rhs) = delete; 35 | CDropTarget& operator=(_In_ CDropTarget&& rhs) = delete; 36 | 37 | CDropTarget() noexcept : m_IDropTarget{} {}; 38 | virtual ~CDropTarget() {}; 39 | 40 | // Called when the cursor first enters the window 41 | DROPEFFECT OnDragEnter(_In_ CWnd* pWnd, _In_ COleDataObject* pDataObject, _In_ DWORD dwKeyState, _In_ CPoint point) override 42 | { 43 | return ((nullptr == m_IDropTarget) ? DROPEFFECT_NONE : m_IDropTarget->OnDragEnter(pWnd, pDataObject, dwKeyState, point)); 44 | } 45 | 46 | // Called repeatedly when the cursor is dragged over the window 47 | DROPEFFECT OnDragOver(_In_ CWnd* pWnd, _In_ COleDataObject* pDataObject, _In_ DWORD dwKeyState, _In_ CPoint point) override 48 | { 49 | return ((nullptr == m_IDropTarget) ? DROPEFFECT_NONE : m_IDropTarget->OnDragOver(pWnd, pDataObject, dwKeyState, point)); 50 | } 51 | 52 | // Called when data is dropped into the window, initial handler 53 | DROPEFFECT OnDropEx(_In_ CWnd* pWnd, _In_ COleDataObject* pDataObject, _In_ DROPEFFECT dropDefault, _In_ DROPEFFECT dropList, _In_ CPoint point) override 54 | { 55 | return ((nullptr == m_IDropTarget) ? DROPEFFECT_NONE : m_IDropTarget->OnDropEx(pWnd, pDataObject, dropDefault, dropList, point)); 56 | } 57 | 58 | // Define redirection 59 | void SetRedirectionTarget(IDropTarget& iDropTarget) 60 | { 61 | m_IDropTarget = &iDropTarget; 62 | } 63 | 64 | private: 65 | IDropTarget* m_IDropTarget; 66 | }; 67 | 68 | // Dialog Data 69 | #ifdef AFX_DESIGN_TIME 70 | enum { IDD = IDD_DIALOG_APPLICATION }; 71 | #endif 72 | 73 | // Update visibility of tab dialogs based on the currently selected tab 74 | void ResyncTabDialogVisibilityState(); 75 | 76 | void DoDataExchange(_In_ CDataExchange* pDX) override; 77 | BOOL OnInitDialog() override; 78 | 79 | DECLARE_MESSAGE_MAP() 80 | 81 | // Acquire exclusive access to the filter driver 82 | std::unique_ptr m_FilterDriverProxy; 83 | 84 | // Drop file support 85 | CDropTarget m_DropTarget; 86 | 87 | // Controls 88 | HICON m_hIcon; 89 | CTabCtrl m_TabApplication; 90 | CBlacklistDlg m_BlacklistDlg; 91 | CWhitelistDlg m_WhitelistDlg; 92 | 93 | // Events 94 | afx_msg void OnPaint(); 95 | afx_msg HCURSOR OnQueryDragIcon(); 96 | afx_msg void OnTcnSelchangeTabApplication(_In_ NMHDR* pNMHDR, _Out_ LRESULT* pResult); 97 | afx_msg void OnShowWindow(_In_ BOOL bShow, _In_ UINT nStatus); 98 | }; 99 | -------------------------------------------------------------------------------- /HidHide/src/Logging.h: -------------------------------------------------------------------------------- 1 | // (c) Eric Korff de Gidts 2 | // SPDX-License-Identifier: MIT 3 | // Logging.h 4 | #pragma once 5 | 6 | // Macros for tracing 7 | // The define for ProjectDirLength is passed from the project file to the source code via a define 8 | #define TRACE_DETAILED(message) { TraceEvent(&__FILE__[ProjectDirLength], __LINE__, __FUNCTION__, &EtwEventTraceDetailed, message, ""); if (MCGEN_EVENT_ENABLED(EtwEventTraceDetailed) && MCGEN_EVENT_ENABLED(EtwEventTraceDebugging)) DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "%s(%d) %s\n", &__FILE__[ProjectDirLength], __LINE__, __FUNCTION__); } 9 | #define TRACE_PERFORMANCE(message) { TraceEvent(&__FILE__[ProjectDirLength], __LINE__, __FUNCTION__, &EtwEventTracePerformance, message, ""); if (MCGEN_EVENT_ENABLED(EtwEventTracePerformance) && MCGEN_EVENT_ENABLED(EtwEventTraceDebugging)) DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "%s(%d) %s\n", &__FILE__[ProjectDirLength], __LINE__, __FUNCTION__); } 10 | #define TRACE_ALWAYS(message) { TraceEvent(&__FILE__[ProjectDirLength], __LINE__, __FUNCTION__, &EtwEventTraceAlways, message, ""); if (MCGEN_EVENT_ENABLED(EtwEventTraceAlways) && MCGEN_EVENT_ENABLED(EtwEventTraceDebugging)) DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "%s(%d) %s\n", &__FILE__[ProjectDirLength], __LINE__, __FUNCTION__); } 11 | 12 | // Macro for a shorter notation on the LogEvent parameter list 13 | #define ETW(eventDescriptor) &__FILE__[ProjectDirLength], __LINE__, __FUNCTION__, &EtwEventLog##eventDescriptor 14 | 15 | // Macros for logging 16 | #define LOG_AND_RETURN_NTSTATUS(message, result) { LogEvent(ETW(Exception), L"%s reports NT status 0x%08X", message, result); return (result); } 17 | 18 | // Macros for debugging messages (for logging internally or when logging isn't yet available) 19 | #define DBG_AND_RETURN_NTSTATUS(message, result) { DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "%s reports NT status 0x%08X\n", message, result); return (result); } // DIRQL 20 | 21 | // The maximum logging message length supported (as TRACE_MESSAGE_MAXIMUM_SIZE is too large) 22 | #define LOGGING_MESSAGE_MAXIMUM_SIZE 200 23 | 24 | #if MCGEN_USE_KERNEL_MODE_APIS 25 | EXTERN_C_START 26 | 27 | // Register the ETW logging and tracing providers 28 | _IRQL_requires_same_ 29 | _IRQL_requires_max_(PASSIVE_LEVEL) 30 | NTSTATUS LogRegisterProviders(); 31 | 32 | // Unregister the ETW logging and tracing providers 33 | _IRQL_requires_same_ 34 | _IRQL_requires_max_(PASSIVE_LEVEL) 35 | NTSTATUS LogUnregisterProviders(); 36 | 37 | // Trace a message 38 | _IRQL_requires_same_ 39 | _IRQL_requires_max_(HIGH_LEVEL) 40 | NTSTATUS TraceEvent(_In_ NTSTRSAFE_PCSTR fileName, _In_ UINT32 lineNumber, _In_ NTSTRSAFE_PCSTR functionName, _In_ PCEVENT_DESCRIPTOR event, _In_ NTSTRSAFE_PCWSTR messageW, _In_ NTSTRSAFE_PCSTR messageA); 41 | 42 | // Log an entry and trace a message 43 | _IRQL_requires_same_ 44 | _IRQL_requires_max_(HIGH_LEVEL) 45 | NTSTATUS LogEvent(_In_ NTSTRSAFE_PCSTR fileName, _In_ UINT32 lineNumber, _In_ NTSTRSAFE_PCSTR functionName, _In_ PCEVENT_DESCRIPTOR event, _In_z_ _Printf_format_string_ NTSTRSAFE_PCWSTR format, ...); 46 | 47 | EXTERN_C_END 48 | #else 49 | 50 | // DbgPrintEx equavalent for user mode applications 51 | NTSTATUS DbgPrintEx(_In_ ULONG componentId, _In_ ULONG level, _In_z_ _Printf_format_string_ LPCSTR format, ...) noexcept; 52 | 53 | // Register the ETW logging and tracing providers 54 | NTSTATUS LogRegisterProviders() noexcept; 55 | 56 | // Unregister the ETW logging and tracing providers 57 | NTSTATUS LogUnregisterProviders() noexcept; 58 | 59 | // Trace a message 60 | NTSTATUS TraceEvent(_In_ LPCSTR fileName, _In_ UINT32 lineNumber, _In_ LPCSTR functionName, _In_ PCEVENT_DESCRIPTOR event, _In_ LPCWSTR messageW, _In_ LPCSTR messageA) noexcept; 61 | 62 | // Format a message and add it to the event log and trace file 63 | NTSTATUS LogEvent(_In_ LPCSTR fileName, _In_ UINT32 lineNumber, _In_ LPCSTR functionName, _In_ PCEVENT_DESCRIPTOR event, _In_z_ _Printf_format_string_ LPCWSTR format, ...) noexcept; 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /HidHide/src/ControlDevice.c: -------------------------------------------------------------------------------- 1 | // (c) Eric Korff de Gidts 2 | // SPDX-License-Identifier: MIT 3 | // ControlDevice.c 4 | #include "stdafx.h" 5 | #include "ControlDevice.h" 6 | #include "Logging.h" 7 | #include "Logic.h" 8 | 9 | _Use_decl_annotations_ 10 | NTSTATUS HidHideControlDeviceCreate(WDFDRIVER wdfDriver, WDFDEVICE* wdfControlDevice) 11 | { 12 | TRACE_ALWAYS(L""); 13 | 14 | PWDFDEVICE_INIT wdfDeviceInit; 15 | WDF_FILEOBJECT_CONFIG wdfFileObjectConfig; 16 | WDF_OBJECT_ATTRIBUTES wdfObjectAttributes; 17 | WDF_IO_QUEUE_CONFIG wdfIoQueueConfig; 18 | WDFQUEUE wdfQueue; 19 | NTSTATUS ntstatus; 20 | 21 | DECLARE_CONST_UNICODE_STRING(controlDeviceNtDeviceName, CONTROL_DEVICE_NT_DEVICE_NAME); 22 | DECLARE_CONST_UNICODE_STRING(controlDeviceDosDeviceName, CONTROL_DEVICE_DOS_DEVICE_NAME); 23 | 24 | // Initialize the device init structure 25 | wdfDeviceInit = WdfControlDeviceInitAllocate(wdfDriver, &SDDL_DEVOBJ_SYS_ALL_ADM_RWX_WORLD_RWX_RES_RWX); // PASSIVE_LEVEL 26 | if (NULL == wdfDeviceInit) LOG_AND_RETURN_NTSTATUS(L"WdfControlDeviceInitAllocate", STATUS_INSUFFICIENT_RESOURCES); 27 | 28 | // Register the device name 29 | ntstatus = WdfDeviceInitAssignName(wdfDeviceInit, &controlDeviceNtDeviceName); 30 | if (!NT_SUCCESS(ntstatus)) 31 | { 32 | WdfDeviceInitFree(wdfDeviceInit); 33 | LOG_AND_RETURN_NTSTATUS(L"WdfDeviceInitAssignName", ntstatus); 34 | } 35 | 36 | // Register to shutdown notifications so we know when to destroy the control device enabling the driver to unload in turn 37 | WdfControlDeviceInitSetShutdownNotification(wdfDeviceInit, OnSystemShutdown, WdfDeviceShutdown); 38 | 39 | // Lock-out multiple clients interacting with this control device at the same time 40 | WdfDeviceInitSetExclusive(wdfDeviceInit, TRUE); 41 | 42 | // Create the device 43 | WDF_FILEOBJECT_CONFIG_INIT(&wdfFileObjectConfig, OnControlDeviceFileCreate, NULL, OnControlDeviceFileCleanup); 44 | WdfDeviceInitSetFileObjectConfig(wdfDeviceInit, &wdfFileObjectConfig, WDF_NO_OBJECT_ATTRIBUTES); 45 | WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&wdfObjectAttributes, CONTROL_DEVICE_CONTEXT); 46 | wdfObjectAttributes.EvtCleanupCallback = OnControlDeviceContextCleanup; 47 | ntstatus = WdfDeviceCreate(&wdfDeviceInit, &wdfObjectAttributes, wdfControlDevice); 48 | if (!NT_SUCCESS(ntstatus)) 49 | { 50 | WdfDeviceInitFree(wdfDeviceInit); 51 | LOG_AND_RETURN_NTSTATUS(L"WdfDeviceCreate", ntstatus); 52 | } 53 | 54 | // Register the DOS device name 55 | ntstatus = WdfDeviceCreateSymbolicLink(*wdfControlDevice, &controlDeviceDosDeviceName); 56 | if (!NT_SUCCESS(ntstatus)) LOG_AND_RETURN_NTSTATUS(L"WdfDeviceCreateSymbolicLink", ntstatus); 57 | 58 | // Create the I/O requests queue 59 | WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&wdfIoQueueConfig, WdfIoQueueDispatchParallel); 60 | wdfIoQueueConfig.EvtIoDeviceControl = HidHideControlDeviceEvtIoDeviceControl; 61 | ntstatus = WdfIoQueueCreate(*wdfControlDevice, &wdfIoQueueConfig, WDF_NO_OBJECT_ATTRIBUTES, &wdfQueue); 62 | if (!NT_SUCCESS(ntstatus)) LOG_AND_RETURN_NTSTATUS(L"WdfIoQueueCreate", ntstatus); 63 | 64 | // Custom logic hook 65 | ntstatus = OnControlDeviceCreate(*wdfControlDevice); 66 | if (!NT_SUCCESS(ntstatus)) return (ntstatus); 67 | 68 | // Enable I/O control requests 69 | WdfControlFinishInitializing(*wdfControlDevice); 70 | 71 | return (STATUS_SUCCESS); 72 | } 73 | 74 | _Use_decl_annotations_ 75 | VOID HidHideControlDeviceEvtIoDeviceControl(WDFQUEUE wdfQueue, WDFREQUEST wdfRequest, size_t outputBufferLength, size_t inputBufferLength, ULONG ioControlCode) 76 | { 77 | TRACE_ALWAYS(L""); 78 | 79 | NTSTATUS ntstatus; 80 | 81 | ntstatus = OnControlDeviceIoDeviceControl(WdfIoQueueGetDevice(wdfQueue), wdfQueue, wdfRequest, outputBufferLength, inputBufferLength, ioControlCode); 82 | if (!NT_SUCCESS(ntstatus)) 83 | { 84 | WdfRequestComplete(wdfRequest, ntstatus); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /HidHideCLI/src/FilterDriverProxy.h: -------------------------------------------------------------------------------- 1 | // (c) Eric Korff de Gidts 2 | // SPDX-License-Identifier: MIT 3 | // FilterDriverProxy.h 4 | #pragma once 5 | 6 | namespace HidHide 7 | { 8 | typedef std::wstring DeviceInstancePath; 9 | typedef std::set DeviceInstancePaths; 10 | typedef std::filesystem::path FullImageName; 11 | typedef std::set FullImageNames; 12 | 13 | class FilterDriverProxy 14 | { 15 | public: 16 | 17 | FilterDriverProxy() noexcept = delete; 18 | FilterDriverProxy(_In_ FilterDriverProxy const& rhs) = delete; 19 | FilterDriverProxy(_In_ FilterDriverProxy&& rhs) noexcept = delete; 20 | FilterDriverProxy& operator=(_In_ FilterDriverProxy const& rhs) = delete; 21 | FilterDriverProxy& operator=(_In_ FilterDriverProxy&& rhs) = delete; 22 | 23 | // Exclusively lock the device driver, fill the cache layer, and ensure the module file name is always on the whitelist 24 | explicit FilterDriverProxy(_In_ bool writeThrough); 25 | ~FilterDriverProxy() = default; 26 | 27 | // Get the control device state 28 | // Returns ERROR_SUCCESS when available for use 29 | // Returns FILE_NOT_FOUND when the device is disabled (assuming it is installed) 30 | // Returns ACCESS_DENIED when in use (assuming it is not an ACL issue) 31 | static DWORD DeviceStatus(); 32 | 33 | // Apply the configuration changes (if any) 34 | // Throws when the class is using write-through 35 | void ApplyConfigurationChanges(); 36 | 37 | // Get the device Instance Paths of the Human Interface Devices that are on the black-list (may reference not present devices) 38 | DeviceInstancePaths GetBlacklist() const; 39 | 40 | // Set the device Instance Paths of the Human Interface Devices that are on the black-list 41 | void SetBlacklist(_In_ DeviceInstancePaths const& deviceInstancePaths); 42 | 43 | // Add a device to the black-list 44 | void BlacklistAddEntry(_In_ DeviceInstancePath const& deviceInstancePath); 45 | 46 | // Delete a device from the white-list 47 | void BlacklistDelEntry(_In_ DeviceInstancePath const& deviceInstancePath); 48 | 49 | // Get the applications on the white-list 50 | FullImageNames GetWhitelist() const; 51 | 52 | // Set the applications on the white-list 53 | void SetWhitelist(_In_ FullImageNames const& fullImageNames); 54 | 55 | // Add an application to the white-list 56 | void WhitelistAddEntry(_In_ FullImageName const& fullImageName); 57 | 58 | // Delete an application from the white-list 59 | void WhitelistDelEntry(_In_ FullImageName const& fullImageName); 60 | 61 | // Get the current enabled state; returns true when the device is active in hiding devices on the black-list 62 | bool GetActive() const; 63 | 64 | // Set the current enabled state 65 | void SetActive(_In_ bool active); 66 | 67 | // Get the current whitelist inverse state; returns true when the whitelist logic is the inverse (effectively an application backlist) 68 | bool GetInverse() const; 69 | 70 | // Set the current whitelist inverse state 71 | void SetInverse(_In_ bool inverse); 72 | 73 | private: 74 | 75 | typedef std::unique_ptr::type, decltype(&::CloseHandle)> CloseHandlePtr; 76 | 77 | bool const m_WriteThrough; // Flag indicating that changes should be applied instantly 78 | CloseHandlePtr const m_Device; // The handle to the filter driver 79 | bool m_Active; // Indicates if the filter driver is hiding devices or not 80 | DeviceInstancePaths m_Blacklist; // The device instance paths of the blacklisted HID devices 81 | FullImageNames m_Whitelist; // The full image names of the whitelisted applications 82 | bool m_Inverse; // Indicates if the inverse whitelist is enabled 83 | }; 84 | } 85 | -------------------------------------------------------------------------------- /HidHideClient/HidHideClient.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Header Files 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | Header Files 29 | 30 | 31 | Header Files 32 | 33 | 34 | Header Files 35 | 36 | 37 | Resource Files 38 | 39 | 40 | Header Files 41 | 42 | 43 | Header Files 44 | 45 | 46 | Header Files 47 | 48 | 49 | Header Files 50 | 51 | 52 | Header Files 53 | 54 | 55 | Header Files 56 | 57 | 58 | 59 | 60 | Resource Files 61 | 62 | 63 | Resource Files 64 | 65 | 66 | 67 | 68 | Source Files 69 | 70 | 71 | Source Files 72 | 73 | 74 | Source Files 75 | 76 | 77 | Source Files 78 | 79 | 80 | Source Files 81 | 82 | 83 | Source Files 84 | 85 | 86 | Source Files 87 | 88 | 89 | Source Files 90 | 91 | 92 | Source Files 93 | 94 | 95 | Source Files 96 | 97 | 98 | 99 | 100 | Resource Files 101 | 102 | 103 | Resource Files 104 | 105 | 106 | Resource Files 107 | 108 | 109 | Resource Files 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | -------------------------------------------------------------------------------- /HidHide/src/Config.h: -------------------------------------------------------------------------------- 1 | // (c) Eric Korff de Gidts 2 | // SPDX-License-Identifier: MIT 3 | // Config.h 4 | #pragma once 5 | 6 | // Conversion from HANDLE to PID 7 | #define PROCESS_HANDLE_TO_PROCESS_ID(handle) (ULONG)((ULONG_PTR)handle & 0xFFFFFFFF) 8 | 9 | EXTERN_C_START 10 | 11 | // Register a PID and its load image 12 | // Returns STATUS_PROCESS_IN_JOB (success) when the process id is already registered 13 | // Returns STATUS_SUCCESS when the process id is registered, and the root of the tree may have changed 14 | _IRQL_requires_same_ 15 | _IRQL_requires_max_(DISPATCH_LEVEL) 16 | NTSTATUS HidHideProcessIdRegister(_In_ WDFWAITLOCK wdfWaitLock, _In_ HANDLE processId, _In_ PUNICODE_STRING fullImageName); 17 | 18 | // Unregister a PID 19 | // When the PID isn't registered, the operation is ignored silently (STATUS_SUCCESS) 20 | // When the PID is unregistered, the root of the tree may have changed 21 | _IRQL_requires_same_ 22 | _IRQL_requires_max_(DISPATCH_LEVEL) 23 | NTSTATUS HidHideProcessIdUnregister(_In_ WDFWAITLOCK wdfWaitLock, _In_ HANDLE processId); 24 | 25 | // Lookup the full image name associated with a registered process id and check it against the list of white-listed full image names provided 26 | // cache-hit is TRUE when the result could be taken from the evaluation cache, or FALSE when the result had to be evaluated 27 | // Returns STATUS_PROCESS_IN_JOB (Success) when the process id is known and the full image name is found in the string list provided 28 | // Returns STATUS_PROCESS_NOT_IN_JOB (Success) when the process id is known and the full image name is not found in the string list provided 29 | // Returns STATUS_SUCCESS when the process id isn't known 30 | _IRQL_requires_same_ 31 | _IRQL_requires_max_(PASSIVE_LEVEL) 32 | NTSTATUS HidHideProcessIdCheckFullImageNameAgainstWhitelist(_In_ WDFWAITLOCK wdfWaitLock, _In_ HANDLE processId, _In_ WDFCOLLECTION wdfCollection, _Out_ BOOLEAN* cacheHit); 33 | 34 | // Unregister all PIDs and return the new root (NULL) 35 | _IRQL_requires_same_ 36 | _IRQL_requires_max_(DISPATCH_LEVEL) 37 | VOID HidHideProcessIdsCleanup(_In_ WDFWAITLOCK wdfWaitLock); 38 | 39 | // Flush the currently cached evaluation results 40 | _IRQL_requires_same_ 41 | _IRQL_requires_max_(DISPATCH_LEVEL) 42 | VOID HidHideProcessIdsFlushWhitelistEvaluationCache(_In_ WDFWAITLOCK wdfWaitLock); 43 | 44 | // Run-time check on the btree algorithm 45 | // Returns STATUS_SUCCESS when the algorithm passes the tests 46 | _IRQL_requires_same_ 47 | _IRQL_requires_max_(DISPATCH_LEVEL) 48 | NTSTATUS HidHideVerifyInternalConsistency(); 49 | 50 | // Get a boolean driver property (DWORD) 51 | // Returns STATUS_OBJECT_NAME_NOT_FOUND (Error) when the parameter is isn't found 52 | _IRQL_requires_same_ 53 | _IRQL_requires_max_(PASSIVE_LEVEL) 54 | NTSTATUS HidHideDriverGetBooleanProperty(_In_ PCUNICODE_STRING valueName, _Out_ BOOLEAN* value); 55 | 56 | // Set a boolean driver property (REG_DWORD) 57 | _IRQL_requires_same_ 58 | _IRQL_requires_max_(PASSIVE_LEVEL) 59 | NTSTATUS HidHideDriverSetBooleanProperty(_In_ PCUNICODE_STRING valueName, _In_ BOOLEAN value); 60 | 61 | // Set a multi-string driver property (REG_MULTI_SZ) 62 | _IRQL_requires_same_ 63 | _IRQL_requires_max_(PASSIVE_LEVEL) 64 | NTSTATUS HidHideDriverSetMultiStringProperty(_In_ PCUNICODE_STRING valueName, _In_reads_(valueInCharacters) LPWSTR value, _In_ size_t valueInCharacters); 65 | 66 | // Get a multi-string driver property and convert the string list into a string collection 67 | // Returns STATUS_PROCESS_IN_JOB (Success) when the parameter is available and converted into a collection 68 | // Returns STATUS_PROCESS_NOT_IN_JOB (Success) when the parameter isn't available (the collection returned is empty) 69 | // On success the caller becomes responsible for calling WdfObjectDelete on the collection when the result is no longer needed 70 | _IRQL_requires_same_ 71 | _IRQL_requires_max_(PASSIVE_LEVEL) 72 | NTSTATUS HidHideDriverCreateCollectionForMultiStringProperty(_In_ PCUNICODE_STRING valueName, _Out_ WDFCOLLECTION* value); 73 | 74 | // Get a device instance path of a given device 75 | // On success the caller becomes responsible for calling WdfObjectDelete on the object returned when it is no longer needed 76 | _IRQL_requires_same_ 77 | _IRQL_requires_max_(PASSIVE_LEVEL) 78 | NTSTATUS HidHideDeviceInstancePath(_In_ WDFDEVICE wdfDevice, _Out_ WDFSTRING* deviceInstancePath); 79 | 80 | // Get the multi-string from a string collection 81 | // When the supplied buffer is NULL, the method returns STATUS_SUCCESS and indicates the buffer size needed for the multi-string (incl. terminator) 82 | // When the supplied buffer isn't NULL, the whitelist will be copied into the buffer, providing the buffer is large enough for holding the result 83 | _IRQL_requires_same_ 84 | _IRQL_requires_max_(PASSIVE_LEVEL) 85 | NTSTATUS HidHideCollectionToMultiString(_In_ WDFCOLLECTION wdfCollection, _Out_writes_to_opt_(bufferSizeInCharacters, *neededSizeInCharacters) LPWSTR buffer, _In_ size_t bufferSizeInCharacters, _Out_ size_t* neededSizeInCharacters); 86 | 87 | EXTERN_C_END 88 | -------------------------------------------------------------------------------- /HidHide/src/Logging.c: -------------------------------------------------------------------------------- 1 | // (c) Eric Korff de Gidts 2 | // SPDX-License-Identifier: MIT 3 | // Logging.c 4 | #include "stdafx.h" 5 | #include "Logging.h" 6 | 7 | // Write to log/trace file 8 | _IRQL_requires_same_ 9 | _IRQL_requires_max_(PASSIVE_LEVEL) 10 | NTSTATUS LogWriteTransfer(_In_ PMCGEN_TRACE_CONTEXT context, _In_ PCEVENT_DESCRIPTOR eventDescriptor, _In_ PCSTR fileName, _In_ UINT32 lineNumber, _In_ PCSTR functionName, _In_ PCWSTR messageW, _In_ PCSTR messageA) 11 | { 12 | EVENT_DATA_DESCRIPTOR eventDataDescriptor[6]; 13 | USHORT UNALIGNED const* traits; 14 | 15 | EventDataDescCreate(&eventDataDescriptor[1], fileName, (ULONG)(strlen(fileName) + 1)); 16 | EventDataDescCreate(&eventDataDescriptor[2], &lineNumber, (ULONG)(sizeof(unsigned int))); 17 | EventDataDescCreate(&eventDataDescriptor[3], functionName, (ULONG)(strlen(functionName) + 1)); 18 | EventDataDescCreate(&eventDataDescriptor[4], messageW, (ULONG)(wcslen(messageW) + 1) * sizeof(WCHAR)); 19 | EventDataDescCreate(&eventDataDescriptor[5], messageA, (ULONG)(strlen(messageA) + 1)); 20 | 21 | // The part below is taken from the generated message compiler code (McGenEventWrite) 22 | traits = (USHORT UNALIGNED*)(UINT_PTR)EtwProviderTracing_Context.Logger; 23 | if (NULL == traits) 24 | { 25 | eventDataDescriptor[0].Ptr = 0; 26 | eventDataDescriptor[0].Size = 0; 27 | eventDataDescriptor[0].Reserved = 0; 28 | } 29 | else 30 | { 31 | eventDataDescriptor[0].Ptr = (ULONG_PTR)traits; 32 | eventDataDescriptor[0].Size = *traits; 33 | eventDataDescriptor[0].Reserved = 2; // EVENT_DATA_DESCRIPTOR_TYPE_PROVIDER_METADATA 34 | } 35 | 36 | return (MCGEN_EVENTWRITETRANSFER(context->RegistrationHandle, eventDescriptor, NULL, NULL, _countof(eventDataDescriptor), &eventDataDescriptor[0])); 37 | } 38 | 39 | _Use_decl_annotations_ 40 | NTSTATUS LogRegisterProviders() 41 | { 42 | NTSTATUS ntstatus; 43 | 44 | ntstatus = EventRegisterNefarius_HidHide(); // PASSIVE_LEVEL 45 | if (!NT_SUCCESS(ntstatus)) DBG_AND_RETURN_NTSTATUS("EventRegister logging", ntstatus); 46 | ntstatus = EventRegisterNefarius_Drivers_HidHide(); 47 | if (!NT_SUCCESS(ntstatus)) DBG_AND_RETURN_NTSTATUS("EventRegister tracing", ntstatus); 48 | 49 | // The define for BldProductVersion is passed from the project file to the source code via a define 50 | LogEvent(ETW(Started), L"%s", _L(BldProductVersion)); 51 | 52 | return (ntstatus); 53 | } 54 | 55 | _Use_decl_annotations_ 56 | NTSTATUS LogUnregisterProviders() 57 | { 58 | NTSTATUS ntstatus; 59 | 60 | LogEvent(ETW(Stopped), L""); 61 | 62 | ntstatus = EventUnregisterNefarius_Drivers_HidHide(); // PASSIVE_LEVEL 63 | if (!NT_SUCCESS(ntstatus)) DBG_AND_RETURN_NTSTATUS("EventRegister tracing", ntstatus); 64 | ntstatus = EventUnregisterNefarius_HidHide(); 65 | if (!NT_SUCCESS(ntstatus)) DBG_AND_RETURN_NTSTATUS("EventRegister logging", ntstatus); 66 | 67 | return (ntstatus); 68 | } 69 | 70 | _Use_decl_annotations_ 71 | NTSTATUS TraceEvent(NTSTRSAFE_PCSTR fileName, UINT32 lineNumber, NTSTRSAFE_PCSTR functionName, PCEVENT_DESCRIPTOR event, NTSTRSAFE_PCWSTR messageW, NTSTRSAFE_PCSTR messageA) 72 | { 73 | return (LogWriteTransfer(&EtwProviderTracing_Context, event, fileName, lineNumber, functionName, messageW, messageA)); 74 | } 75 | 76 | _Use_decl_annotations_ 77 | NTSTATUS LogEvent(NTSTRSAFE_PCSTR fileName, const UINT32 lineNumber, NTSTRSAFE_PCSTR functionName, PCEVENT_DESCRIPTOR event, NTSTRSAFE_PCWSTR format, ...) 78 | { 79 | EVENT_DESCRIPTOR eventDescriptor; 80 | WCHAR buffer[LOGGING_MESSAGE_MAXIMUM_SIZE]; 81 | va_list args; 82 | NTSTATUS ntstatus; 83 | 84 | // Create message 85 | va_start(args, format); 86 | ntstatus = RtlStringCchVPrintfW(&buffer[0], _countof(buffer), format, args); 87 | if (!NT_SUCCESS(ntstatus)) DBG_AND_RETURN_NTSTATUS("RtlStringCchVPrintfW", ntstatus); 88 | 89 | // Log the entry 90 | ntstatus = LogWriteTransfer(&EtwProviderLogging_Context, event, fileName, lineNumber, functionName, &buffer[0], ""); // HIGH_LEVEL 91 | if (!NT_SUCCESS(ntstatus)) DBG_AND_RETURN_NTSTATUS("LogWriteTransfer logging", ntstatus); 92 | 93 | // Trace the entry after having copied the relevant information from the log entry 94 | eventDescriptor.Id = event->Id; 95 | eventDescriptor.Version = EtwEventTraceAlways.Version; 96 | eventDescriptor.Channel = EtwEventTraceAlways.Channel; 97 | eventDescriptor.Opcode = EtwEventTraceAlways.Opcode; 98 | eventDescriptor.Level = event->Level; 99 | eventDescriptor.Opcode = EtwEventTraceAlways.Opcode; 100 | eventDescriptor.Task = EtwTaskLog; 101 | eventDescriptor.Keyword = EtwEventTraceAlways.Keyword; 102 | 103 | // Trace the entry 104 | ntstatus = LogWriteTransfer(&EtwProviderTracing_Context, &eventDescriptor, fileName, lineNumber, functionName, &buffer[0], ""); 105 | if (!NT_SUCCESS(ntstatus)) DBG_AND_RETURN_NTSTATUS("LogWriteTransfer tracing", ntstatus); 106 | 107 | return (ntstatus); 108 | } 109 | -------------------------------------------------------------------------------- /LICENSE.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\ansi\deff0\adeflang1025 2 | {\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\froman\fprq0\fcharset128 Times New Roman;}{\f4\fswiss\fprq2\fcharset128 Tahoma;}{\f5\fswiss\fprq1\fcharset0 Consolas;}{\f6\froman\fprq0\fcharset128 ;}{\f7\fnil\fprq2\fcharset0 Microsoft YaHei;}{\f8\fmodern\fprq1\fcharset0 NSimSun;}{\f9\fswiss\fprq0\fcharset128 Arial;}{\f10\fmodern\fprq1\fcharset0 Courier New;}} 3 | {\colortbl;\red0\green0\blue0;\red0\green128\blue0;\red128\green128\blue128;} 4 | {\stylesheet{\s0\snext0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\hich\af6\langfe2052\dbch\af2\afs24\lang1081\loch\f0\fs24\lang1043 Default;} 5 | {\s15\sbasedon0\snext16{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb240\sa120\keepn\cf0\hich\af7\langfe2052\dbch\af2\loch\f2\fs28\lang1043 Heading;} 6 | {\s16\sbasedon0\snext16{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb0\sa120\cf0\hich\af0\langfe2052\dbch\af0\loch\f0\fs24\lang1043 Text body;} 7 | {\s17\sbasedon16\snext17{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb0\sa120\cf0\hich\af0\langfe2052\dbch\af9\loch\f0\fs24\lang1043 List;} 8 | {\s18\sbasedon0\snext18{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb120\sa120\cf0\i\hich\af0\langfe2052\dbch\af9\ai\loch\f0\fs24\lang1043 Caption;} 9 | {\s19\sbasedon0\snext19{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\hich\af0\langfe2052\dbch\af9\loch\f0\fs24\lang1043 Index;} 10 | {\s20\sbasedon0\snext20{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb0\sa0\cf0\hich\af8\langfe2052\dbch\af10\loch\f3\fs20\lang1043 Preformatted Text;} 11 | }{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}{\comment OpenOffice}{\vern4180}}\deftab709\deftab709\deftab709\deftab709\deftab709\deftab709\deftab709\deftab709\deftab709\deftab709\deftab709\deftab709\deftab709\deftab709\deftab709\deftab709\deftab709\deftab709\deftab709\deftab709 12 | 13 | {\*\pgdsctbl 14 | {\pgdsc0\pgdscuse195\pgwsxn11906\pghsxn16838\marglsxn1134\margrsxn1134\margtsxn1134\margbsxn1134\pgdscnxt0 Default;}} 15 | \formshade\paperh16838\paperw11906\margl1134\margr1134\margt1134\margb1134\sectd\sbknone\sectunlocked1\pgndec\pgwsxn11906\pghsxn16838\marglsxn1134\margrsxn1134\margtsxn1134\margbsxn1134\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc 16 | \pgndec\pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\hich\af6\langfe2052\dbch\af2\afs24\lang1081\loch\f0\fs24\lang1043{\afs16\rtlch \ltrch\loch\fs16\loch\f4 17 | SPDX-License-Identifier: MIT License} 18 | \par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\hich\af6\langfe2052\dbch\af2\afs24\lang1081\loch\f0\fs24\lang1043{\rtlch \ltrch\loch 19 | } 20 | \par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\hich\af6\langfe2052\dbch\af2\afs24\lang1081\loch\f0\fs24\lang1043{\afs16\rtlch \ltrch\loch\fs16\loch\f4 21 | Copyright (c) 2020 Eric Korff de Gidts} 22 | \par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\hich\af6\langfe2052\dbch\af2\afs24\lang1081\loch\f0\fs24\lang1043{\rtlch \ltrch\loch 23 | } 24 | \par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\hich\af6\langfe2052\dbch\af2\afs24\lang1081\loch\f0\fs24\lang1043{\afs16\rtlch \ltrch\loch\fs16\loch\f4 25 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:} 26 | \par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\hich\af6\langfe2052\dbch\af2\afs24\lang1081\loch\f0\fs24\lang1043{\rtlch \ltrch\loch 27 | } 28 | \par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\hich\af6\langfe2052\dbch\af2\afs24\lang1081\loch\f0\fs24\lang1043{\afs16\rtlch \ltrch\loch\fs16\loch\f4 29 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.} 30 | \par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\hich\af6\langfe2052\dbch\af2\afs24\lang1081\loch\f0\fs24\lang1043{\rtlch \ltrch\loch 31 | } 32 | \par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\hich\af6\langfe2052\dbch\af2\afs24\lang1081\loch\f0\fs24\lang1043{\afs16\rtlch \ltrch\loch\fs16\loch\f4 33 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.} 34 | \par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\hich\af6\langfe2052\dbch\af2\afs24\lang1081\loch\f0\fs24\lang1043{\rtlch \ltrch\loch 35 | } 36 | \par } -------------------------------------------------------------------------------- /drivers/x64/HidHide/LICENSE.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\ansi\deff0\adeflang1025 2 | {\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\froman\fprq2\fcharset2 Symbol;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\froman\fprq0\fcharset128 Times New Roman;}{\f4\fswiss\fprq2\fcharset128 Tahoma;}{\f5\fswiss\fprq1\fcharset0 Consolas;}{\f6\froman\fprq0\fcharset128 ;}{\f7\fnil\fprq2\fcharset0 Microsoft YaHei;}{\f8\fmodern\fprq1\fcharset0 NSimSun;}{\f9\fswiss\fprq0\fcharset128 Arial;}{\f10\fmodern\fprq1\fcharset0 Courier New;}} 3 | {\colortbl;\red0\green0\blue0;\red0\green128\blue0;\red128\green128\blue128;} 4 | {\stylesheet{\s0\snext0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\hich\af6\langfe2052\dbch\af2\afs24\lang1081\loch\f0\fs24\lang1043 Default;} 5 | {\s15\sbasedon0\snext16{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb240\sa120\keepn\cf0\hich\af7\langfe2052\dbch\af2\loch\f2\fs28\lang1043 Heading;} 6 | {\s16\sbasedon0\snext16{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb0\sa120\cf0\hich\af0\langfe2052\dbch\af0\loch\f0\fs24\lang1043 Text body;} 7 | {\s17\sbasedon16\snext17{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb0\sa120\cf0\hich\af0\langfe2052\dbch\af9\loch\f0\fs24\lang1043 List;} 8 | {\s18\sbasedon0\snext18{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb120\sa120\cf0\i\hich\af0\langfe2052\dbch\af9\ai\loch\f0\fs24\lang1043 Caption;} 9 | {\s19\sbasedon0\snext19{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\cf0\hich\af0\langfe2052\dbch\af9\loch\f0\fs24\lang1043 Index;} 10 | {\s20\sbasedon0\snext20{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\sb0\sa0\cf0\hich\af8\langfe2052\dbch\af10\loch\f3\fs20\lang1043 Preformatted Text;} 11 | }{\info{\creatim\yr0\mo0\dy0\hr0\min0}{\revtim\yr0\mo0\dy0\hr0\min0}{\printim\yr0\mo0\dy0\hr0\min0}{\comment OpenOffice}{\vern4180}}\deftab709\deftab709\deftab709\deftab709\deftab709\deftab709\deftab709\deftab709\deftab709\deftab709\deftab709\deftab709\deftab709\deftab709\deftab709\deftab709\deftab709\deftab709\deftab709\deftab709 12 | 13 | {\*\pgdsctbl 14 | {\pgdsc0\pgdscuse195\pgwsxn11906\pghsxn16838\marglsxn1134\margrsxn1134\margtsxn1134\margbsxn1134\pgdscnxt0 Default;}} 15 | \formshade\paperh16838\paperw11906\margl1134\margr1134\margt1134\margb1134\sectd\sbknone\sectunlocked1\pgndec\pgwsxn11906\pghsxn16838\marglsxn1134\margrsxn1134\margtsxn1134\margbsxn1134\ftnbj\ftnstart1\ftnrstcont\ftnnar\aenddoc\aftnrstcont\aftnstart1\aftnnrlc 16 | \pgndec\pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\hich\af6\langfe2052\dbch\af2\afs24\lang1081\loch\f0\fs24\lang1043{\afs16\rtlch \ltrch\loch\fs16\loch\f4 17 | SPDX-License-Identifier: MIT License} 18 | \par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\hich\af6\langfe2052\dbch\af2\afs24\lang1081\loch\f0\fs24\lang1043{\rtlch \ltrch\loch 19 | } 20 | \par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\hich\af6\langfe2052\dbch\af2\afs24\lang1081\loch\f0\fs24\lang1043{\afs16\rtlch \ltrch\loch\fs16\loch\f4 21 | Copyright (c) 2020 Eric Korff de Gidts} 22 | \par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\hich\af6\langfe2052\dbch\af2\afs24\lang1081\loch\f0\fs24\lang1043{\rtlch \ltrch\loch 23 | } 24 | \par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\hich\af6\langfe2052\dbch\af2\afs24\lang1081\loch\f0\fs24\lang1043{\afs16\rtlch \ltrch\loch\fs16\loch\f4 25 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:} 26 | \par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\hich\af6\langfe2052\dbch\af2\afs24\lang1081\loch\f0\fs24\lang1043{\rtlch \ltrch\loch 27 | } 28 | \par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\hich\af6\langfe2052\dbch\af2\afs24\lang1081\loch\f0\fs24\lang1043{\afs16\rtlch \ltrch\loch\fs16\loch\f4 29 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.} 30 | \par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\hich\af6\langfe2052\dbch\af2\afs24\lang1081\loch\f0\fs24\lang1043{\rtlch \ltrch\loch 31 | } 32 | \par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\hich\af6\langfe2052\dbch\af2\afs24\lang1081\loch\f0\fs24\lang1043{\afs16\rtlch \ltrch\loch\fs16\loch\f4 33 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.} 34 | \par \pard\plain \s0{\*\hyphen2\hyphlead2\hyphtrail2\hyphmax0}\nowidctlpar\cf0\hich\af6\langfe2052\dbch\af2\afs24\lang1081\loch\f0\fs24\lang1043{\rtlch \ltrch\loch 35 | } 36 | \par } -------------------------------------------------------------------------------- /stage0.ps1: -------------------------------------------------------------------------------- 1 | Param( 2 | [Parameter(Mandatory=$true)] 3 | [string]$BuildVersion, 4 | [Parameter(Mandatory=$true)] 5 | [string]$Token, 6 | [Parameter(Mandatory=$false)] 7 | [string]$Path = "./artifacts", 8 | [Parameter(Mandatory=$false)] 9 | [Switch]$NoSigning 10 | ) #end param 11 | 12 | $signTool = "$(wdkwhere)\signtool.exe" 13 | $timestampUrl = "http://timestamp.digicert.com" 14 | $certName = "Nefarius Software Solutions e.U." 15 | 16 | function Get-AppVeyorArtifacts 17 | { 18 | [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Low')] 19 | param( 20 | #The name of the account you wish to download artifacts from 21 | [parameter(Mandatory = $true)] 22 | [string]$Account, 23 | #The name of the project you wish to download artifacts from 24 | [parameter(Mandatory = $true)] 25 | [string]$Project, 26 | #Where to save the downloaded artifacts. Defaults to current directory. 27 | [alias("DownloadDirectory")][string]$Path = '.', 28 | [string]$Token, 29 | #Filter to a specific branch or project directory. You can specify Branch as either branch name ("master") or build version ("0.1.29") 30 | [string]$Branch, 31 | #If you have multiple build jobs, specify which job you wish to retrieve the artifacts from 32 | [string]$JobName, 33 | #Download all files into a single directory, do not preserve any hierarchy that might exist in the artifacts 34 | [switch]$Flat, 35 | [string]$Proxy, 36 | [switch]$ProxyUseDefaultCredentials, 37 | #URL of Appveyor API. You normally shouldn't need to change this. 38 | $apiUrl = 'https://ci.appveyor.com/api' 39 | ) 40 | 41 | $headers = @{ 42 | 'Content-type' = 'application/json' 43 | } 44 | 45 | if ($Token) {$headers.'Authorization' = "Bearer $token"} 46 | 47 | # Prepare proxy args to splat to Invoke-RestMethod 48 | $proxyArgs = @{} 49 | if (-not [string]::IsNullOrEmpty($proxy)) { 50 | $proxyArgs.Add('Proxy', $proxy) 51 | } 52 | if ($proxyUseDefaultCredentials.IsPresent) { 53 | $proxyArgs.Add('ProxyUseDefaultCredentials', $proxyUseDefaultCredentials) 54 | } 55 | 56 | $errorActionPreference = 'Stop' 57 | $projectURI = "$apiUrl/projects/$account/$project" 58 | if ($Branch) {$projectURI = $projectURI + "/build/$Branch"} 59 | 60 | $projectObject = Invoke-RestMethod -Method Get -Uri $projectURI ` 61 | -Headers $headers @proxyArgs 62 | 63 | if (-not $projectObject.build.jobs) {throw "No jobs found for this project or the project and/or account name was incorrectly specified"} 64 | 65 | if (($projectObject.build.jobs.count -gt 1) -and -not $jobName) { 66 | throw "Multiple Jobs found for the latest build. Please specify the -JobName paramter to select which job you want the artifacts for" 67 | } 68 | 69 | if ($JobName) { 70 | $jobid = ($projectObject.build.jobs | Where-Object name -eq "$JobName" | Select-Object -first 1).jobid 71 | if (-not $jobId) {throw "Unable to find a job named $JobName within the latest specified build. Did you spell it correctly?"} 72 | } else { 73 | $jobid = $projectObject.build.jobs[0].jobid 74 | } 75 | 76 | $artifacts = Invoke-RestMethod -Method Get -Uri "$apiUrl/buildjobs/$jobId/artifacts" ` 77 | -Headers $headers @proxyArgs 78 | $artifacts ` 79 | | ? { $psCmdlet.ShouldProcess($_.fileName) } ` 80 | | % { 81 | 82 | $type = $_.type 83 | 84 | $localArtifactPath = $_.fileName -split '/' | % { [Uri]::UnescapeDataString($_) } 85 | if ($flat.IsPresent) { 86 | $localArtifactPath = ($localArtifactPath | select -Last 1) 87 | } else { 88 | $localArtifactPath = $localArtifactPath -join [IO.Path]::DirectorySeparatorChar 89 | } 90 | $localArtifactPath = Join-Path $path $localArtifactPath 91 | 92 | $artifactUrl = "$apiUrl/buildjobs/$jobId/artifacts/$($_.fileName)" 93 | Write-Verbose "Downloading $artifactUrl to $localArtifactPath" 94 | 95 | New-Item -ItemType Directory -Force -Path (Split-Path -Path $localArtifactPath) | Out-Null 96 | 97 | Invoke-RestMethod -Method Get -Uri $artifactUrl -OutFile $localArtifactPath -Headers $headers @proxyArgs 98 | 99 | New-Object PSObject -Property @{ 100 | 'Source' = $artifactUrl 101 | 'Type' = $type 102 | 'Target' = $localArtifactPath 103 | } 104 | } 105 | } 106 | 107 | Remove-Item -Recurse -Force ".\artifacts\bin" 108 | 109 | # Download x64 binaries 110 | Get-AppVeyorArtifacts -Account "nefarius" -Project "HidHide" -Path $Path -Token $Token -Branch $BuildVersion 111 | 112 | # List of files to sign 113 | $files = "`".\artifacts\bin\Release\x64\*.exe`" " + 114 | "`".\artifacts\bin\Release\ARM64\*.exe`" " + 115 | "`".\artifacts\disk1\*.cab`" " 116 | 117 | if ($NoSigning -eq $false) { 118 | # sign with only one certificate 119 | Invoke-Expression "& `"$signTool`" sign /v /as /n `"$certName`" /tr $timestampUrl /fd sha256 /td sha256 $files" 120 | } 121 | 122 | # Print helper job names for sign portal 123 | "HidHide x64 v$BuildVersion $(Get-Date -Format "dd.MM.yyyy")" 124 | "HidHide ARM64 v$BuildVersion $(Get-Date -Format "dd.MM.yyyy")" 125 | -------------------------------------------------------------------------------- /HidHideClient/src/HidHideClientDlg.cpp: -------------------------------------------------------------------------------- 1 | // (c) Eric Korff de Gidts 2 | // SPDX-License-Identifier: MIT 3 | // HidHideClientDlg.cpp 4 | #include "stdafx.h" 5 | #include "HidHideClient.h" 6 | #include "HidHideClientDlg.h" 7 | #include "FilterDriverProxy.h" 8 | #include "Utils.h" 9 | #include "Logging.h" 10 | 11 | #pragma warning(push) 12 | #pragma warning(disable: 26454 28213) // Warnings caused by Microsoft MFC macros 13 | BEGIN_MESSAGE_MAP(CHidHideClientDlg, CDialogEx) 14 | ON_WM_PAINT() 15 | ON_WM_QUERYDRAGICON() 16 | ON_NOTIFY(TCN_SELCHANGE, IDC_TAB_APPLICATION, &CHidHideClientDlg::OnTcnSelchangeTabApplication) 17 | ON_WM_SHOWWINDOW() 18 | END_MESSAGE_MAP() 19 | #pragma warning(pop) 20 | 21 | _Use_decl_annotations_ 22 | CHidHideClientDlg::CHidHideClientDlg(CWnd* pParent) 23 | : CDialogEx(IDD_DIALOG_APPLICATION, pParent) 24 | , m_FilterDriverProxy{} 25 | , m_DropTarget{} 26 | , m_hIcon{} 27 | , m_TabApplication{} 28 | , m_BlacklistDlg(*this, nullptr) 29 | , m_WhitelistDlg(*this, nullptr) 30 | { 31 | TRACE_ALWAYS(L""); 32 | m_hIcon = ::AfxGetApp()->LoadIcon(IDR_DIALOG_APPLICATION); 33 | } 34 | 35 | HidHide::FilterDriverProxy& CHidHideClientDlg::FilterDriverProxy() noexcept 36 | { 37 | return (*m_FilterDriverProxy.get()); 38 | } 39 | 40 | _Use_decl_annotations_ 41 | void CHidHideClientDlg::DoDataExchange(CDataExchange* pDX) 42 | { 43 | TRACE_ALWAYS(L""); 44 | CDialogEx::DoDataExchange(pDX); 45 | DDX_Control(pDX, IDC_TAB_APPLICATION, m_TabApplication); 46 | } 47 | 48 | BOOL CHidHideClientDlg::OnInitDialog() 49 | { 50 | TRACE_ALWAYS(L""); 51 | CDialogEx::OnInitDialog(); 52 | 53 | // Acquire exclusive access to the filter driver 54 | m_FilterDriverProxy = std::make_unique(true); 55 | 56 | // Register this window as a drop target 57 | m_DropTarget.Register(this); 58 | 59 | // Set the dialog title and include the version number, as defined via a define from the build environment 60 | std::wostringstream title; 61 | title << HidHide::StringTable(IDS_DIALOG_APPLICATION) << L" v" << _L(BldProductVersion); 62 | SetWindowTextW(title.str().c_str()); 63 | 64 | // Add tabs to tab-control so the height of the client rectangle is defined 65 | TCITEM tcItem; 66 | tcItem.mask = TCIF_TEXT; 67 | auto tabApplicationHeader0{ HidHide::StringTable(IDS_TAB_APPLICATION_HEADER_0) }; 68 | tcItem.pszText = tabApplicationHeader0.data(); 69 | m_TabApplication.InsertItem(0, &tcItem); 70 | auto tabApplicationHeader1{ HidHide::StringTable(IDS_TAB_APPLICATION_HEADER_1) }; 71 | tcItem.pszText = tabApplicationHeader1.data(); 72 | m_TabApplication.InsertItem(1, &tcItem); 73 | 74 | // Determine the proper offset for the tab dialogs 75 | CRect clientRect; 76 | CRect windowRect; 77 | m_TabApplication.GetClientRect(&clientRect); 78 | m_TabApplication.AdjustRect(FALSE, &clientRect); 79 | m_TabApplication.GetWindowRect(&windowRect); 80 | ScreenToClient(windowRect); 81 | clientRect.OffsetRect(windowRect.left, windowRect.top); 82 | 83 | // Create the dialogs (invisible per default) 84 | m_BlacklistDlg.Create(IDD_DIALOG_BLACKLIST, m_TabApplication.GetWindow(IDD_DIALOG_BLACKLIST)); 85 | m_BlacklistDlg.MoveWindow(clientRect); 86 | m_WhitelistDlg.Create(IDD_DIALOG_WHITELIST, m_TabApplication.GetWindow(IDD_DIALOG_WHITELIST)); 87 | m_WhitelistDlg.MoveWindow(clientRect); 88 | 89 | return (TRUE); 90 | } 91 | 92 | void CHidHideClientDlg::OnPaint() 93 | { 94 | TRACE_ALWAYS(L""); 95 | if (IsIconic()) 96 | { 97 | CPaintDC dc(this); // device context for painting 98 | 99 | SendMessage(WM_ICONERASEBKGND, reinterpret_cast(dc.GetSafeHdc()), 0); 100 | 101 | // Center icon in client rectangle 102 | int cxIcon = GetSystemMetrics(SM_CXICON); 103 | int cyIcon = GetSystemMetrics(SM_CYICON); 104 | CRect rect; 105 | GetClientRect(&rect); 106 | int x = (rect.Width() - cxIcon + 1) / 2; 107 | int y = (rect.Height() - cyIcon + 1) / 2; 108 | 109 | // Draw the icon 110 | dc.DrawIcon(x, y, m_hIcon); 111 | } 112 | else 113 | { 114 | CDialogEx::OnPaint(); 115 | } 116 | } 117 | 118 | HCURSOR CHidHideClientDlg::OnQueryDragIcon() 119 | { 120 | TRACE_ALWAYS(L""); 121 | return static_cast(m_hIcon); 122 | } 123 | 124 | void CHidHideClientDlg::ResyncTabDialogVisibilityState() 125 | { 126 | TRACE_ALWAYS(L""); 127 | switch (m_TabApplication.GetCurSel()) 128 | { 129 | case 0: // Applications 130 | m_BlacklistDlg.ShowWindow(SW_HIDE); 131 | m_WhitelistDlg.ShowWindow(SW_SHOW); 132 | m_DropTarget.SetRedirectionTarget(m_WhitelistDlg); 133 | break; 134 | case 1: // Devices 135 | m_BlacklistDlg.ShowWindow(SW_SHOW); 136 | m_WhitelistDlg.ShowWindow(SW_HIDE); 137 | m_DropTarget.SetRedirectionTarget(m_BlacklistDlg); 138 | break; 139 | } 140 | } 141 | 142 | _Use_decl_annotations_ 143 | void CHidHideClientDlg::OnTcnSelchangeTabApplication(NMHDR* pNMHDR, LRESULT* pResult) 144 | { 145 | TRACE_ALWAYS(L""); 146 | UNREFERENCED_PARAMETER(pNMHDR); 147 | ResyncTabDialogVisibilityState(); 148 | *pResult = 0; 149 | } 150 | 151 | _Use_decl_annotations_ 152 | void CHidHideClientDlg::OnShowWindow(BOOL bShow, UINT nStatus) 153 | { 154 | TRACE_ALWAYS(L""); 155 | CDialogEx::OnShowWindow(bShow, nStatus); 156 | m_TabApplication.SetCurSel(0); 157 | ResyncTabDialogVisibilityState(); 158 | } 159 | -------------------------------------------------------------------------------- /HidHideCLI/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by HidHideCLI.rc 4 | // 5 | #define IDD_DIALOG_APPLICATION 101 6 | #define IDR_DIALOG_APPLICATION 128 7 | #define IDS_DIALOG_APPLICATION 129 8 | #define IDS_CONTROL_DEVICE_NAME 130 9 | #define IDS_HELP_GUIDANCE 131 10 | #define IDS_CONSOLE_GUIDANCE 132 11 | #define IDS_SYNTAX_ERROR 133 12 | #define IDS_COMMAND_NOT_RECOGNIZED 134 13 | #define IDS_WRONG_NUMBER_OF_ARGUMENTS 135 14 | #define IDS_NOT_A_FULLY_QUALIFIED_PATH 136 15 | #define IDS_NOT_AN_EXECUTABLE 137 16 | #define IDS_NOT_ON_A_VOLUME 138 17 | #define IDS_DEV_INST_PATH_TOO_LONG 139 18 | #define IDS_CLI_SYNTAX_APP_PATH 140 19 | #define IDS_CLI_SYNTAX_DEV_INST_PATH 141 20 | #define IDS_CLI_SYNTAX_NO_ARGUMENTS 142 21 | #define IDS_CLI_APP_CLEAN 143 22 | #define IDS_CLI_APP_LIST 144 23 | #define IDS_CLI_APP_REG 145 24 | #define IDS_CLI_APP_UNREG 146 25 | #define IDS_CLI_CANCEL 147 26 | #define IDS_CLI_CLOAK_OFF 148 27 | #define IDS_CLI_CLOAK_ON 149 28 | #define IDS_CLI_CLOAK_STATE 150 29 | #define IDS_CLI_CLOAK_TOGGLE 151 30 | #define IDS_CLI_DEV_ALL 152 31 | #define IDS_CLI_DEV_GAMING 153 32 | #define IDS_CLI_DEV_HIDE 154 33 | #define IDS_CLI_DEV_LIST 155 34 | #define IDS_CLI_DEV_UNHIDE 156 35 | #define IDS_CLI_HELP 157 36 | #define IDS_CLI_VERSION 158 37 | #define IDS_HID_ATTRIBUTE_DENIED 159 38 | #define IDS_HID_ATTRIBUTE_ABSENT 160 39 | #define IDS_CLI_INV_ON 161 40 | #define IDS_CLI_INFO_OFF 162 41 | #define IDS_CLI_INV_OFF 162 42 | #define IDS_CLI_INV_STATE 163 43 | #define IDS_PAGE_01 0x1001 44 | #define IDS_PAGE_02 0x1002 45 | #define IDS_PAGE_03 0x1003 46 | #define IDS_PAGE_04 0x1004 47 | #define IDS_PAGE_05 0x1005 48 | #define IDS_PAGE_06 0x1006 49 | #define IDS_PAGE_07 0x1007 50 | #define IDS_PAGE_08 0x1008 51 | #define IDS_PAGE_09 0x1009 52 | #define IDS_PAGE_0A 0x100A 53 | #define IDS_PAGE_0B 0x100B 54 | #define IDS_PAGE_0C 0x100C 55 | #define IDS_PAGE_0D 0x100D 56 | #define IDS_PABE_0E 0x100E 57 | #define IDS_PAGE_0F 0x100F 58 | #define IDS_PAGE_10 0x1010 59 | #define IDS_PAGE_12 0x1012 60 | #define IDS_PAGE_14 0x1014 61 | #define IDS_PAGE_20 0x1020 62 | #define IDS_PAGE_40 0x1040 63 | #define IDS_PAGE_41 0x1041 64 | #define IDS_PAGE_59 0x1059 65 | #define IDS_PAGE_8C 0x108C 66 | #define IDS_PAGE_8D 0x108D 67 | #define IDS_PAGE_8E 0x108E 68 | #define IDS_PAGE_90 0x1090 69 | #define IDS_PAGE_91 0x1091 70 | #define IDS_PAGE_01_USAGE_01 0x1101 71 | #define IDS_PAGE_01_USAGE_02 0x1102 72 | #define IDS_PAGE_01_USAGE_04 0x1104 73 | #define IDS_PAGE_01_USAGE_05 0x1105 74 | #define IDS_PAGE_01_USAGE_06 0x1106 75 | #define IDS_PAGE_01_USAGE_07 0x1107 76 | #define IDS_PAGE_01_USAGE_08 0x1108 77 | #define IDS_PAGE_01_USAGE_09 0x1109 78 | #define IDS_PAGE_01_USAGE_0D 0x110D 79 | #define IDS_PAGE_01_USAGE_0E 0x110E 80 | #define IDS_PAGE_01_USAGE_0F 0x110F 81 | #define IDS_PAGE_01_USAGE_10 0x1110 82 | #define IDS_PAGE_01_USAGE_11 0x1111 83 | #define IDS_PAGE_01_USAGE_12 0x1112 84 | #define IDS_PAGE_01_USAGE_30 0x1130 85 | #define IDS_PAGE_01_USAGE_31 0x1131 86 | #define IDS_PAGE_01_USAGE_32 0x1132 87 | #define IDS_PAGE_01_USAGE_33 0x1133 88 | #define IDS_PAGE_01_USAGE_34 0x1134 89 | #define IDS_PAGE_01_USAGE_35 0x1135 90 | #define IDS_PAGE_01_USAGE_36 0x1136 91 | #define IDS_PAGE_01_USAGE_37 0x1137 92 | #define IDS_PAGE_01_USAGE_38 0x1138 93 | #define IDS_PAGE_01_USAGE_39 0x1139 94 | #define IDS_PAGE_01_USAGE_3A 0x113A 95 | #define IDS_PAGE_01_USAGE_3B 0x113B 96 | #define IDS_PAGE_01_USAGE_3C 0x113C 97 | #define IDS_PAGE_01_USAGE_3D 0x113D 98 | #define IDS_PAGE_01_USAGE_3E 0x113E 99 | #define IDS_PAGE_01_USAGE_80 0x1180 100 | #define IDS_PAGE_01_USAGE_96 0x1196 101 | #define IDS_PAGE_01_USAGE_C0 0x11C0 102 | #define IDS_PAGE_01_USAGE_C5 0x11C5 103 | #define IDS_PAGE_0C_USAGE_01 0x1201 104 | #define IDS_PAGE_0C_USAGE_02 0x1202 105 | #define IDS_PAGE_0C_USAGE_03 0x1203 106 | #define IDS_PAGE_0C_USAGE_04 0x1204 107 | #define IDS_PAGE_0C_USAGE_05 0x1205 108 | #define IDS_PAGE_0C_USAGE_06 0x1206 109 | #define IDS_PAGE_0C_USAGE_36 0x1236 110 | #define IDS_PAGE_0C_USAGE_80 0x1280 111 | #define IDS_PAGE_0C_USAGE_87 0x1287 112 | #define IDS_PAGE_0C_USAGE_BA 0x12BA 113 | #define IDS_PAGE_0C_USAGE_F1 0x12F1 114 | 115 | // Next default values for new objects 116 | // 117 | #ifdef APSTUDIO_INVOKED 118 | #ifndef APSTUDIO_READONLY_SYMBOLS 119 | #define _APS_NEXT_RESOURCE_VALUE 161 120 | #define _APS_NEXT_COMMAND_VALUE 32771 121 | #define _APS_NEXT_CONTROL_VALUE 1010 122 | #define _APS_NEXT_SYMED_VALUE 102 123 | #endif 124 | #endif 125 | -------------------------------------------------------------------------------- /HidHideClient/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by HidHideClient.rc 4 | // 5 | #define IDD_DIALOG_APPLICATION 101 6 | #define IDD_DIALOG_WHITELIST 102 7 | #define IDD_DIALOG_BLACKLIST 103 8 | #define IDR_DIALOG_APPLICATION 128 9 | #define IDI_ICON_BLACKLIST_LOCK_BLANK 129 10 | #define IDI_ICON_BLACKLIST_LOCK_OFF 130 11 | #define IDI_ICON_BLACKLIST_LOCK_ON 131 12 | #define IDS_STATIC_MESSAGEBOX_OK 132 13 | #define IDS_STATIC_MESSAGEBOX_CANCEL 133 14 | #define IDS_STATIC_MESSAGEBOX_RETRY 134 15 | #define IDS_STATIC_MESSAGEBOX_IGNORE 135 16 | #define IDS_STATIC_MESSAGEBOX_ABORT 136 17 | #define IDS_STATIC_MESSAGEBOX_YES 137 18 | #define IDS_STATIC_MESSAGEBOX_NO 138 19 | #define IDS_DIALOG_APPLICATION 139 20 | #define IDS_DIALOG_FILE_OPEN 140 21 | #define IDS_STATIC_FILE_OPEN_FILTER 141 22 | #define IDS_TAB_APPLICATION_HEADER_0 142 23 | #define IDS_TAB_APPLICATION_HEADER_1 143 24 | #define IDS_STATIC_WHITELIST_GUIDANCE 144 25 | #define IDS_BUTTON_WHITELIST_INSERT 145 26 | #define IDS_BUTTON_WHITELIST_DELETE 146 27 | #define IDS_CHECK_BLACKLIST_FILTER 147 28 | #define IDS_CHECK_BLACKLIST_GAMING 148 29 | #define IDS_CHECK_BLACKLIST_ENABLE 149 30 | #define IDS_STATIC_BLACKLIST_GUIDANCE 150 31 | #define IDS_CONTROL_DEVICE_NAME 151 32 | #define IDS_HID_ATTRIBUTE_DENIED 152 33 | #define IDS_HID_ATTRIBUTE_ABSENT 153 34 | #define IDS_STATIC_MESSAGEBOX_PRESENT 154 35 | #define IDS_STATIC_MESSAGEBOX_IN_USE 155 36 | #define IDS_STATIC_MESSAGEBOX_EXCEPTION 156 37 | #define IDS_CHECK_WHITELIST_INVERSE 157 38 | #define IDC_TAB_APPLICATION 1000 39 | #define IDC_LIST_WHITELIST 1001 40 | #define IDC_STATIC_WHITELIST_GUIDANCE 1002 41 | #define IDC_BUTTON_WHITELIST_INSERT 1003 42 | #define IDC_BUTTON_WHITELIST_DELETE 1004 43 | #define IDC_TREE_BLACKLIST 1005 44 | #define IDC_CHECK_BLACKLIST_FILTER 1006 45 | #define IDC_CHECK_BLACKLIST_GAMING 1007 46 | #define IDC_CHECK_BLACKLIST_ENABLE 1008 47 | #define IDC_STATIC_BLACKLIST_GUIDANCE 1009 48 | #define IDC_CHECK_WHITELIST_INVERSE 1010 49 | #define IDS_PAGE_01 0x1001 50 | #define IDS_PAGE_02 0x1002 51 | #define IDS_PAGE_03 0x1003 52 | #define IDS_PAGE_04 0x1004 53 | #define IDS_PAGE_05 0x1005 54 | #define IDS_PAGE_06 0x1006 55 | #define IDS_PAGE_07 0x1007 56 | #define IDS_PAGE_08 0x1008 57 | #define IDS_PAGE_09 0x1009 58 | #define IDS_PAGE_0A 0x100A 59 | #define IDS_PAGE_0B 0x100B 60 | #define IDS_PAGE_0C 0x100C 61 | #define IDS_PAGE_0D 0x100D 62 | #define IDS_PABE_0E 0x100E 63 | #define IDS_PAGE_0F 0x100F 64 | #define IDS_PAGE_10 0x1010 65 | #define IDS_PAGE_12 0x1012 66 | #define IDS_PAGE_14 0x1014 67 | #define IDS_PAGE_20 0x1020 68 | #define IDS_PAGE_40 0x1040 69 | #define IDS_PAGE_41 0x1041 70 | #define IDS_PAGE_59 0x1059 71 | #define IDS_PAGE_8C 0x108C 72 | #define IDS_PAGE_8D 0x108D 73 | #define IDS_PAGE_8E 0x108E 74 | #define IDS_PAGE_90 0x1090 75 | #define IDS_PAGE_91 0x1091 76 | #define IDS_PAGE_01_USAGE_01 0x1101 77 | #define IDS_PAGE_01_USAGE_02 0x1102 78 | #define IDS_PAGE_01_USAGE_04 0x1104 79 | #define IDS_PAGE_01_USAGE_05 0x1105 80 | #define IDS_PAGE_01_USAGE_06 0x1106 81 | #define IDS_PAGE_01_USAGE_07 0x1107 82 | #define IDS_PAGE_01_USAGE_08 0x1108 83 | #define IDS_PAGE_01_USAGE_09 0x1109 84 | #define IDS_PAGE_01_USAGE_0D 0x110D 85 | #define IDS_PAGE_01_USAGE_0E 0x110E 86 | #define IDS_PAGE_01_USAGE_0F 0x110F 87 | #define IDS_PAGE_01_USAGE_10 0x1110 88 | #define IDS_PAGE_01_USAGE_11 0x1111 89 | #define IDS_PAGE_01_USAGE_12 0x1112 90 | #define IDS_PAGE_01_USAGE_30 0x1130 91 | #define IDS_PAGE_01_USAGE_31 0x1131 92 | #define IDS_PAGE_01_USAGE_32 0x1132 93 | #define IDS_PAGE_01_USAGE_33 0x1133 94 | #define IDS_PAGE_01_USAGE_34 0x1134 95 | #define IDS_PAGE_01_USAGE_35 0x1135 96 | #define IDS_PAGE_01_USAGE_36 0x1136 97 | #define IDS_PAGE_01_USAGE_37 0x1137 98 | #define IDS_PAGE_01_USAGE_38 0x1138 99 | #define IDS_PAGE_01_USAGE_39 0x1139 100 | #define IDS_PAGE_01_USAGE_3A 0x113A 101 | #define IDS_PAGE_01_USAGE_3B 0x113B 102 | #define IDS_PAGE_01_USAGE_3C 0x113C 103 | #define IDS_PAGE_01_USAGE_3D 0x113D 104 | #define IDS_PAGE_01_USAGE_3E 0x113E 105 | #define IDS_PAGE_01_USAGE_80 0x1180 106 | #define IDS_PAGE_01_USAGE_96 0x1196 107 | #define IDS_PAGE_01_USAGE_C0 0x11C0 108 | #define IDS_PAGE_01_USAGE_C5 0x11C5 109 | #define IDS_PAGE_0C_USAGE_01 0x1201 110 | #define IDS_PAGE_0C_USAGE_02 0x1202 111 | #define IDS_PAGE_0C_USAGE_03 0x1203 112 | #define IDS_PAGE_0C_USAGE_04 0x1204 113 | #define IDS_PAGE_0C_USAGE_05 0x1205 114 | #define IDS_PAGE_0C_USAGE_06 0x1206 115 | #define IDS_PAGE_0C_USAGE_36 0x1236 116 | #define IDS_PAGE_0C_USAGE_80 0x1280 117 | #define IDS_PAGE_0C_USAGE_87 0x1287 118 | #define IDS_PAGE_0C_USAGE_BA 0x12BA 119 | #define IDS_PAGE_0C_USAGE_F1 0x12F1 120 | 121 | // Next default values for new objects 122 | // 123 | #ifdef APSTUDIO_INVOKED 124 | #ifndef APSTUDIO_READONLY_SYMBOLS 125 | #define _APS_NEXT_RESOURCE_VALUE 157 126 | #define _APS_NEXT_COMMAND_VALUE 32771 127 | #define _APS_NEXT_CONTROL_VALUE 1011 128 | #define _APS_NEXT_SYMED_VALUE 104 129 | #endif 130 | #endif 131 | -------------------------------------------------------------------------------- /HidHideClient/src/HidHideClient.cpp: -------------------------------------------------------------------------------- 1 | // (c) Eric Korff de Gidts 2 | // SPDX-License-Identifier: MIT 3 | // HidHideClient.cpp 4 | #include "stdafx.h" 5 | #include "HidHideClient.h" 6 | #include "HidHideClientDlg.h" 7 | #include "FilterDriverProxy.h" 8 | #include "Utils.h" 9 | #include "Logging.h" 10 | 11 | CHidHideClientApp theApp; 12 | 13 | BEGIN_MESSAGE_MAP(CHidHideClientApp, CWinApp) 14 | ON_COMMAND(ID_HELP, &CWinApp::OnHelp) 15 | END_MESSAGE_MAP() 16 | 17 | namespace 18 | { 19 | HHOOK s_hHook; 20 | 21 | // Alter message box labels and detach from the window activiation notification 22 | LRESULT CALLBACK LocalizedMessageBoxCBTProc(_In_ INT code, _In_ WPARAM wParam, _In_ LPARAM lParam) 23 | { 24 | // Act during window activitation 25 | if (HCBT_ACTIVATE == code) 26 | { 27 | TRACE_ALWAYS(L""); 28 | auto dlg{ reinterpret_cast(wParam) }; 29 | 30 | // Alter labels 31 | if (nullptr != ::GetDlgItem(dlg, IDOK)) ::SetDlgItemTextW(dlg, IDOK, HidHide::StringTable(IDS_STATIC_MESSAGEBOX_OK).c_str()); 32 | if (nullptr != ::GetDlgItem(dlg, IDCANCEL)) ::SetDlgItemTextW(dlg, IDCANCEL, HidHide::StringTable(IDS_STATIC_MESSAGEBOX_CANCEL).c_str()); 33 | if (nullptr != ::GetDlgItem(dlg, IDRETRY)) ::SetDlgItemTextW(dlg, IDRETRY, HidHide::StringTable(IDS_STATIC_MESSAGEBOX_RETRY).c_str()); 34 | if (nullptr != ::GetDlgItem(dlg, IDIGNORE)) ::SetDlgItemTextW(dlg, IDIGNORE, HidHide::StringTable(IDS_STATIC_MESSAGEBOX_IGNORE).c_str()); 35 | if (nullptr != ::GetDlgItem(dlg, IDABORT)) ::SetDlgItemTextW(dlg, IDABORT, HidHide::StringTable(IDS_STATIC_MESSAGEBOX_ABORT).c_str()); 36 | if (nullptr != ::GetDlgItem(dlg, IDYES)) ::SetDlgItemTextW(dlg, IDYES, HidHide::StringTable(IDS_STATIC_MESSAGEBOX_YES).c_str()); 37 | if (nullptr != ::GetDlgItem(dlg, IDNO)) ::SetDlgItemTextW(dlg, IDNO, HidHide::StringTable(IDS_STATIC_MESSAGEBOX_NO).c_str()); 38 | 39 | // Fire-once so detach again 40 | ::UnhookWindowsHookEx(s_hHook); 41 | } 42 | 43 | // Allow other hooks to act too 44 | ::CallNextHookEx(s_hHook, code, wParam, lParam); 45 | return (0); 46 | } 47 | 48 | // Show message box with localized buttons 49 | INT WINAPI LocalizedMessageBox(_In_ UINT resourceId, _In_ UINT type) 50 | { 51 | TRACE_ALWAYS(L""); 52 | 53 | // Attach hook (fire-once) 54 | s_hHook = ::SetWindowsHookExW(WH_CBT, &LocalizedMessageBoxCBTProc, 0, ::GetCurrentThreadId()); 55 | return (::MessageBoxExW(::AfxGetApp()->GetMainWnd()->m_hWnd, HidHide::StringTable(resourceId).c_str(), HidHide::StringTable(IDS_DIALOG_APPLICATION).c_str(), type, LANG_USER_DEFAULT)); 56 | } 57 | } 58 | 59 | // Register the ETW logging and tracing providers 60 | NTSTATUS WINAPI LogRegisterProviders() noexcept 61 | { 62 | try 63 | { 64 | EventRegisterNefarius_HidHide_Client(); 65 | EventRegisterNefarius_Drivers_HidHideClient(); 66 | 67 | // The define for BldProductVersion is passed from the project file to the source code via a define 68 | ::LogEvent(ETW(Started), L"%s", _L(BldProductVersion)); 69 | return (STATUS_SUCCESS); 70 | } 71 | catch (...) 72 | { 73 | DBG_AND_RETURN_NTSTATUS("LogRegisterProviders", STATUS_UNHANDLED_EXCEPTION); 74 | } 75 | } 76 | 77 | // Unregister the ETW logging and tracing providers 78 | NTSTATUS WINAPI LogUnregisterProviders() noexcept 79 | { 80 | try 81 | { 82 | ::LogEvent(ETW(Stopped), L""); 83 | EventUnregisterNefarius_Drivers_HidHideClient(); 84 | EventUnregisterNefarius_HidHide_Client(); 85 | return (STATUS_SUCCESS); 86 | } 87 | catch (...) 88 | { 89 | DBG_AND_RETURN_NTSTATUS("LogUnregisterProviders", STATUS_UNHANDLED_EXCEPTION); 90 | } 91 | } 92 | 93 | CHidHideClientApp::CHidHideClientApp() noexcept 94 | { 95 | ::LogRegisterProviders(); 96 | } 97 | 98 | CHidHideClientApp::~CHidHideClientApp() 99 | { 100 | ::LogUnregisterProviders(); 101 | } 102 | 103 | BOOL CHidHideClientApp::InitInstance() 104 | { 105 | TRACE_ALWAYS(L""); 106 | 107 | // Initialize OLE library 108 | AfxOleInit(); 109 | 110 | // Initialize the common controls .dll first 111 | INITCOMMONCONTROLSEX initCommonControlsEx; 112 | initCommonControlsEx.dwSize = sizeof(initCommonControlsEx); 113 | initCommonControlsEx.dwICC = ICC_WIN95_CLASSES; 114 | InitCommonControlsEx(&initCommonControlsEx); 115 | 116 | // Initialize the application instance 117 | CWinApp::InitInstance(); 118 | 119 | // Initialize COM services 120 | AfxEnableControlContainer(); 121 | 122 | // Create the shell manager, in case the dialog contains any shell tree view or shell list view controls 123 | std::unique_ptr const shellManager{ std::make_unique() }; 124 | 125 | // Activate "Windows Native" visual manager for enabling themes in MFC controls 126 | CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows)); 127 | 128 | // We can't do anything when the control device isn't present so allow for a retry on failure 129 | CHidHideClientDlg dlg(nullptr); 130 | m_pMainWnd = &dlg; 131 | 132 | // We use exception handling so catch it at top-level and bail out 133 | try 134 | { 135 | // Keep retrying when the device is unavailable 136 | while (true) 137 | { 138 | if (auto const deviceStatus{ HidHide::FilterDriverProxy::DeviceStatus() }; (ERROR_SUCCESS == deviceStatus)) 139 | { 140 | if (-1 == dlg.DoModal()) THROW_WIN32_LAST_ERROR; 141 | break; 142 | } 143 | else 144 | { 145 | TRACE_ALWAYS(L""); 146 | if (IDRETRY != LocalizedMessageBox(((ERROR_ACCESS_DENIED == deviceStatus) ? IDS_STATIC_MESSAGEBOX_IN_USE : IDS_STATIC_MESSAGEBOX_PRESENT), (MB_RETRYCANCEL | MB_ICONEXCLAMATION))) 147 | { 148 | break; 149 | } 150 | } 151 | } 152 | } 153 | catch (...) 154 | { 155 | LOGEXC_AND_CONTINUE; 156 | LocalizedMessageBox(IDS_STATIC_MESSAGEBOX_EXCEPTION, (MB_OK | MB_ICONERROR)); 157 | } 158 | 159 | // Don't start the application's message pump as we are done already 160 | return (FALSE); 161 | } 162 | -------------------------------------------------------------------------------- /HidHideCLI/src/CommandInterpreter.h: -------------------------------------------------------------------------------- 1 | // (c) Eric Korff de Gidts 2 | // SPDX-License-Identifier: MIT 3 | // CommandInterpreter.h 4 | #pragma once 5 | #include "FilterDriverProxy.h" 6 | 7 | namespace HidHide 8 | { 9 | class CommandInterpreter 10 | { 11 | public: 12 | 13 | CommandInterpreter() noexcept = delete; 14 | CommandInterpreter(_In_ CommandInterpreter const& rhs) = delete; 15 | CommandInterpreter(_In_ CommandInterpreter&& rhs) noexcept = delete; 16 | CommandInterpreter& operator=(_In_ CommandInterpreter const& rhs) = delete; 17 | CommandInterpreter& operator=(_In_ CommandInterpreter&& rhs) = delete; 18 | 19 | // Exclusively lock the device driver and ensure the module file name is on the whitelist 20 | explicit CommandInterpreter(_In_ bool writeThrough); 21 | ~CommandInterpreter(); 22 | 23 | // Start the command interpreter using stdin, stdout, and stderr 24 | // - Script mode (standard input redirected and/or command line not empty) 25 | // - Interactive mode (standard input not redirected + empty command line) 26 | void Start(_In_ std::wstring const& commandLine); 27 | 28 | private: 29 | 30 | typedef std::vector Args; 31 | typedef std::function ExecuteFunction; 32 | typedef std::function ValidateFunction; 33 | 34 | struct RegisteredCommandInfo 35 | { 36 | std::wstring syntax; // Help text explaining the command syntax 37 | std::wstring description; // Help text describing what the command does 38 | ExecuteFunction execute; // Command handler 39 | ValidateFunction validate; // Argument validation prior to execution 40 | }; 41 | 42 | typedef std::map RegisteredCommands; 43 | 44 | // Execute a sequence of commands 45 | std::wstring ExecuteCommands(_In_ std::vector const& commands) const; 46 | 47 | // Extract a keyword (no double-quote allowed) 48 | // Returns empty an on empty string 49 | static std::wstring ExtractKeyword(_Inout_ std::wstring& value); 50 | 51 | // Extract a string (double-quotes allowed) 52 | // Returns empty on syntax error 53 | static std::wstring ExtractString(_Inout_ std::wstring& value); 54 | 55 | // Extract the next command and its arguments 56 | // Returns empty on syntax error 57 | static Args ExtractCommand(_Inout_ std::wstring& value); 58 | 59 | // Extract all commands from a command line 60 | // Returns empty on syntax error 61 | static std::vector ExtractCommands(_Inout_ std::wstring& value); 62 | 63 | // Get the size of the command 64 | static size_t CommandSize(_In_ RegisteredCommands::value_type const& registeredCommand) noexcept; 65 | 66 | // Get the size of the syntax 67 | static size_t SyntaxSize(_In_ RegisteredCommands::value_type const& registeredCommand) noexcept; 68 | 69 | // Get the size of the largest command 70 | size_t MaxCommandSize() const; 71 | 72 | // Get the size of the largest syntax 73 | size_t MaxSyntaxSize() const; 74 | 75 | // Validate that there are no additional arguments; returns the parsing error message 76 | std::wstring ValNoArguments(_In_ Args const& args) const; 77 | 78 | // Validate that there is exactly one argument pointing to a valid device instance path; returns the parsing error message 79 | std::wstring ValOneDeviceInstancePath(_In_ Args const& args) const; 80 | 81 | // Validate that there is exactly one argument pointing to an executable file on a storage volume; returns the parsing error message 82 | // Note that this doesn't imply that the file actually exists; application registration may go in advance of its actual installation 83 | std::wstring ValOneFullyQualifiedExecutablePath(_In_ Args const& args) const; 84 | 85 | // Summarizes the commands supported 86 | void Help(_In_ Args const& args) const; 87 | 88 | // Displays the current version label 89 | void Version(_In_ Args const& args) const; 90 | 91 | // Exit without saving configuration changes 92 | void Cancel(_In_ Args const& args); 93 | 94 | // Grants ability to see hidden devices 95 | void AppReg(_In_ Args const& args); 96 | 97 | // Revokes ability to see hidden devices 98 | void AppUnreg(_In_ Args const& args); 99 | 100 | // Remove absent registered applications 101 | void AppClean(Args const&); 102 | 103 | // Lists the registered applications 104 | void AppList(_In_ Args const& args) const; 105 | 106 | // Hide the device specified 107 | void DevHide(_In_ Args const& args); 108 | 109 | // Unhide the device specified 110 | void DevUnhinde(_In_ Args const& args); 111 | 112 | // Lists the hidden devices 113 | void DevList(_In_ Args const& args) const; 114 | 115 | // Lists all HID devices used for gaming 116 | void DevGaming(_In_ Args const& args) const; 117 | 118 | // Lists all HID devices 119 | void DevAll(_In_ Args const& args) const; 120 | 121 | // Turns device hiding on 122 | void CloakOn(_In_ Args const& args); 123 | 124 | // Turns device hiding off 125 | void CloakOff(_In_ Args const& args); 126 | 127 | // Toggles current device hiding state 128 | void CloakToggle(_In_ Args const& args); 129 | 130 | // Reports the current cloaking state 131 | void CloakState(_In_ Args const& args) const; 132 | 133 | // Turns whitelist inverse on 134 | void InvOn(_In_ Args const& args); 135 | 136 | // Turns whitelist inverse off 137 | void InvOff(_In_ Args const& args); 138 | 139 | // Reports the current whitelist inverse 140 | void InvState(_In_ Args const& args) const; 141 | 142 | bool const m_ScriptMode; // Active when standard input is redirected 143 | bool const m_InteractiveMode; // Active without command line arguments or input redirection 144 | RegisteredCommands const m_RegisteredCommands; // Self reflection on all commands supported 145 | FilterDriverProxy m_FilterDriverProxy; // Filter driver access and cache layer 146 | bool m_Cancel; // Flag set when the configuration changes shouldn't be applied 147 | }; 148 | } 149 | -------------------------------------------------------------------------------- /HidHideCLI/HidHideCLI.man: -------------------------------------------------------------------------------- 1 | 2 | 7 | 11 | 12 | 13 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 38 | 39 | 40 | 46 | 47 | 48 | 49 | true 50 | 51 | 52 | 0x000000000001 53 | 16 54 | 0 55 | QPC 56 | None 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /HidHideClient/HidHideClient.man: -------------------------------------------------------------------------------- 1 | 2 | 7 | 11 | 12 | 13 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 38 | 39 | 40 | 46 | 47 | 48 | 49 | true 50 | 51 | 52 | 0x000000000001 53 | 16 54 | 0 55 | QPC 56 | None 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /HidHideCLI/src/CommandInterpreter.cpp: -------------------------------------------------------------------------------- 1 | // (c) Eric Korff de Gidts 2 | // SPDX-License-Identifier: MIT 3 | // CommandInterpreter.cpp 4 | #include "stdafx.h" 5 | #include "CommandInterpreter.h" 6 | #include "Utils.h" 7 | #include "Logging.h" 8 | 9 | namespace HidHide 10 | { 11 | CommandInterpreter::~CommandInterpreter() 12 | { 13 | TRACE_ALWAYS(L""); 14 | } 15 | 16 | _Use_decl_annotations_ 17 | void CommandInterpreter::Start(std::wstring const& commandLine) 18 | { 19 | TRACE_ALWAYS(L""); 20 | 21 | // Display the console welcome 22 | if (m_InteractiveMode) std::wcout << std::endl << HidHide::StringTable(IDS_DIALOG_APPLICATION) << std::endl << HidHide::StringTable(IDS_CONSOLE_GUIDANCE) << std::endl << std::endl; 23 | 24 | // Keep processing commands till ctrl-z is entered 25 | auto line{ commandLine }; 26 | do 27 | { 28 | auto const commands{ ExtractCommands(line) }; 29 | auto const errorMessage{ line.empty() ? ExecuteCommands(commands) : HidHide::StringTable(IDS_SYNTAX_ERROR) }; 30 | if (!errorMessage.empty()) 31 | { 32 | std::wcerr << errorMessage << std::endl; 33 | if (!m_InteractiveMode) return; 34 | } 35 | 36 | // Bail out on cancellation 37 | if (m_Cancel) return; 38 | 39 | // Display the command prompt 40 | if (m_InteractiveMode) std::wcout << L"$ "; 41 | 42 | } while ((m_InteractiveMode || m_ScriptMode) && (std::getline(std::wcin, line))); 43 | 44 | // Apply configuration changes 45 | m_FilterDriverProxy.ApplyConfigurationChanges(); 46 | } 47 | 48 | _Use_decl_annotations_ 49 | std::wstring CommandInterpreter::ExecuteCommands(std::vector const& commands) const 50 | { 51 | TRACE_ALWAYS(L""); 52 | 53 | for (auto const& command : commands) 54 | { 55 | auto const commandInfo{ m_RegisteredCommands.find(command.at(0)) }; 56 | if (std::end(m_RegisteredCommands) == commandInfo) return (HidHide::StringTable(IDS_COMMAND_NOT_RECOGNIZED)); 57 | if (auto const result{ commandInfo->second.validate(command) }; !result.empty()) return (result); 58 | commandInfo->second.execute(command); 59 | } 60 | 61 | return (std::wstring{}); 62 | } 63 | 64 | _Use_decl_annotations_ 65 | std::wstring CommandInterpreter::ExtractKeyword(std::wstring& value) 66 | { 67 | TRACE_ALWAYS(L""); 68 | 69 | // Find the next white space 70 | if (auto const it{ std::find_if(std::begin(value), std::end(value), [](wchar_t character) { return (std::isspace(character)); }) }; (std::end(value) != it)) 71 | { 72 | auto const result{ std::wstring(std::begin(value), it) }; 73 | value.erase(std::begin(value), it + 1); 74 | return (result); 75 | } 76 | 77 | // When no white spaces are found then the whole value is the file name 78 | auto const result{ value }; 79 | value.clear(); 80 | return (result); 81 | } 82 | 83 | _Use_decl_annotations_ 84 | std::wstring CommandInterpreter::ExtractString(std::wstring& value) 85 | { 86 | TRACE_ALWAYS(L""); 87 | 88 | // When the string is starting with a double-quote then look for the next double-quote 89 | // There has to be a double-quote followed by either a whitespace or an end-of-line or we have a syntax error 90 | if (value.empty()) return (std::wstring{}); 91 | if (L'"' == value.at(0)) 92 | { 93 | auto const index{ value.find(L'"', 1) }; 94 | auto const indexAtEnd{ index == (value.size() - 1) }; 95 | if (!((std::wstring::npos != index) && (indexAtEnd || std::isspace(value.at(index + 1))))) return (std::wstring{}); 96 | auto const result{ std::wstring(std::begin(value) + 1, std::begin(value) + index) }; 97 | value.erase(std::begin(value), std::begin(value) + index + (indexAtEnd ? 1 : 2)); 98 | return (result); 99 | } 100 | 101 | // When the string isn't starting with a double-quote then the file name delimiter is a whitespace 102 | return (ExtractKeyword(value)); 103 | } 104 | 105 | _Use_decl_annotations_ 106 | CommandInterpreter::Args CommandInterpreter::ExtractCommand(std::wstring& value) 107 | { 108 | TRACE_ALWAYS(L""); 109 | Args result{}; 110 | 111 | // Remove leading indicator (if any) 112 | if (L"--" == value.substr(0, 2)) value.erase(std::begin(value), std::begin(value) + 2); 113 | 114 | // Any command starts with a keyword 115 | auto const keyword{ ExtractKeyword(value) }; 116 | result.emplace_back(keyword); 117 | 118 | // Read all arguments till the start of new command or the string end but bail out on a syntax error 119 | while ((!Trim(value).empty()) && (L"--" != value.substr(0, 2))) 120 | { 121 | auto const arg{ ExtractString(value) }; 122 | if ((arg.empty()) && (!value.empty())) return (Args{}); 123 | result.emplace_back(arg); 124 | } 125 | 126 | return (result); 127 | } 128 | 129 | _Use_decl_annotations_ 130 | std::vector CommandInterpreter::ExtractCommands(std::wstring& value) 131 | { 132 | TRACE_ALWAYS(L""); 133 | std::vector result{}; 134 | 135 | // Process the whole command line but bail out on a syntax error 136 | while (!Trim(value).empty()) 137 | { 138 | auto const command{ ExtractCommand(value) }; 139 | if (command.empty() && (!value.empty())) return (std::vector()); 140 | result.emplace_back(command); 141 | } 142 | 143 | return (result); 144 | } 145 | 146 | _Use_decl_annotations_ 147 | size_t CommandInterpreter::CommandSize(RegisteredCommands::value_type const& registeredCommand) noexcept 148 | { 149 | TRACE_ALWAYS(L""); 150 | return (registeredCommand.first.size()); 151 | } 152 | 153 | _Use_decl_annotations_ 154 | size_t CommandInterpreter::SyntaxSize(RegisteredCommands::value_type const& registeredCommand) noexcept 155 | { 156 | TRACE_ALWAYS(L""); 157 | return (registeredCommand.second.syntax.size()); 158 | } 159 | 160 | size_t CommandInterpreter::MaxCommandSize() const 161 | { 162 | TRACE_ALWAYS(L""); 163 | return (std::max_element(std::begin(m_RegisteredCommands), std::end(m_RegisteredCommands), [](RegisteredCommands::value_type const& lhs, RegisteredCommands::value_type const& rhs) { return (lhs.first.size() < rhs.first.size()); })->first.size()); 164 | } 165 | 166 | size_t CommandInterpreter::MaxSyntaxSize() const 167 | { 168 | TRACE_ALWAYS(L""); 169 | return (std::max_element(std::begin(m_RegisteredCommands), std::end(m_RegisteredCommands), [](RegisteredCommands::value_type const& lhs, RegisteredCommands::value_type const& rhs) { return (lhs.second.syntax.size() < rhs.second.syntax.size()); })->second.syntax.size()); 170 | } 171 | } 172 | -------------------------------------------------------------------------------- /drivers/x64/HidHide/HidHide.inf: -------------------------------------------------------------------------------- 1 | ; (c) Eric Korff de Gidts 2 | ; SPDX-License-Identifier: MIT 3 | ; HidHide.inf 4 | 5 | ; ==== Version Section ==== 6 | 7 | [Version] 8 | Signature = "$Windows NT$" 9 | Class = System 10 | ClassGUID = {4D36E97D-E325-11CE-BFC1-08002BE10318} 11 | Provider = %ManufacturerName% 12 | CatalogFile = HidHide.cat 13 | PnpLockdown = 1 14 | DriverVer = 10/31/2023,1.4.181.0 15 | 16 | ; ==== SourceDisksNames Section ==== 17 | 18 | [SourceDisksNames] 19 | 1 = %DiskName%,,,"" 20 | 21 | ; ==== SourceDisksFiles Section ==== 22 | 23 | [SourceDisksFiles] 24 | HidHide.sys = 1,, 25 | 26 | ; ==== DestinationDirs Section ==== 27 | 28 | [DestinationDirs] 29 | HidHide_Device_CopyFiles = 12 ; %windir%\System32\DRIVERS\ 30 | 31 | ; ==== Manufacturer Section ==== 32 | 33 | [Manufacturer] 34 | %ManufacturerName% = Standard,NTamd64 35 | 36 | ; ==== Models Section ==== 37 | 38 | [Standard.NTamd64] 39 | %HidHideDeviceName% = HidHide_Device,root\HidHide 40 | 41 | ; ==== DDInstall Section ==== 42 | 43 | [HidHide_Device] 44 | CopyFiles = HidHide_Device_CopyFiles 45 | 46 | [HidHide_Device_CopyFiles] 47 | HidHide.sys,,,0x00004000 ; COPYFLG_IN_USE_RENAME 48 | 49 | ; ==== DDInstall.Services Section ==== 50 | 51 | [HidHide_Device.Services] 52 | AddService = HidHide,%AddServiceFlags%,HidHide_Device_Service_AddService 53 | 54 | [HidHide_Device_Service_AddService] 55 | DisplayName = %HidHideServiceDisplayName% 56 | ServiceType = %SERVICE_KERNEL_DRIVER% 57 | StartType = %SERVICE_DEMAND_START% 58 | ErrorControl = %SERVICE_ERROR_NORMAL% 59 | ServiceBinary = %12%\HidHide.sys 60 | AddReg = HidHide_Device_Service_AddReg 61 | 62 | [HidHide_Device_Service_AddReg] 63 | HKR,"Parameters","WhitelistedFullImageNames",%AddRegMultiSzInitialOnly%,"" ; HKLM\SYSTEM\ControlSet001\Services\HidHide\Parameters\WhitelistedFullImageNames (set initially-only as we may want to preserve earlier user selections) 64 | HKR,"Parameters","BlacklistedDeviceInstancePaths",%AddRegMultiSzInitialOnly%,"" ; HKLM\SYSTEM\ControlSet001\Services\HidHide\Parameters\BlacklistedDeviceInstancePaths (set initially-only as we may want to preserve earlier user selections) 65 | HKR,"Parameters","Active",%FLG_ADDREG_TYPE_DWORD%,0 ; HKLM\SYSTEM\ControlSet001\Services\HidHide\Parameters\Active (disable service after each install as we require the user to run the configuration utility first) 66 | 67 | [HidHide_Device_Service_AddReg.Security] 68 | "D:P(OD;CI;KA;;;BA)(OD;CI;KA;;;BU)" ; HKLM\SYSTEM\ControlSet001\Services\HidHide\Parameters\ (prohibit build in adminstrators, and build in users of doing anything with the keys) 69 | 70 | ; ==== DDInstall.Wdf Section ==== 71 | 72 | [HidHide_Device.Wdf] 73 | KmdfService = HidHide,HidHide_Device_Wdf_KmdfService 74 | 75 | [HidHide_Device_Wdf_KmdfService] 76 | KmdfLibraryVersion = 1.15 77 | 78 | ; ==== Strings Section ==== 79 | 80 | [Strings] 81 | ManufacturerName = "Nefarius Software Solutions e.U." 82 | DiskName = "Nefarius HidHide Installation Disk" 83 | HidHideDeviceName = "Nefarius HidHide Device" 84 | HidHideServiceDisplayName = "Nefarius HidHide Service" 85 | AddServiceFlags = 0x000013FE ; SPSVCINST_NOCLOBBER_REQUIREDPRIVILEGES 86 | ; SPSVCINST_STOPSERVICE 87 | ; SPSVCINST_NOCLOBBER_DESCRIPTION 88 | ; SPSVCINST_NOCLOBBER_DEPENDENCIES 89 | ; SPSVCINST_NOCLOBBER_LOADORDERGROUP 90 | ; SPSVCINST_NOCLOBBER_ERRORCONTROL 91 | ; SPSVCINST_NOCLOBBER_STARTTYPE 92 | ; SPSVCINST_NOCLOBBER_DISPLAYNAME 93 | ; SPSVCINST_DELETEEVENTLOGENTRY 94 | ; SPSVCINST_ASSOCSERVICE 95 | AddRegMultiSzInitialOnly = 0x00010002 ; FLG_ADDREG_TYPE_MULTI_SZ 96 | ; FLG_ADDREG_NOCLOBBER 97 | 98 | SPSVCINST_TAGTOFRONT = 0x00000001 99 | SPSVCINST_ASSOCSERVICE = 0x00000002 100 | SPSVCINST_DELETEEVENTLOGENTRY = 0x00000004 101 | SPSVCINST_NOCLOBBER_DISPLAYNAME = 0x00000008 102 | SPSVCINST_NOCLOBBER_STARTTYPE = 0x00000010 103 | SPSVCINST_NOCLOBBER_ERRORCONTROL = 0x00000020 104 | SPSVCINST_NOCLOBBER_LOADORDERGROUP = 0x00000040 105 | SPSVCINST_NOCLOBBER_DEPENDENCIES = 0x00000080 106 | SPSVCINST_NOCLOBBER_DESCRIPTION = 0x00000100 107 | SPSVCINST_STOPSERVICE = 0x00000200 108 | SPSVCINST_CLOBBER_SECURITY = 0x00000400 109 | SPSVCINST_STARTSERVICE = 0x00000800 110 | SPSVCINST_NOCLOBBER_REQUIREDPRIVILEGES = 0x00001000 111 | 112 | SERVICE_KERNEL_DRIVER = 0x00000001 113 | SERVICE_FILE_SYSTEM_DRIVER = 0x00000002 114 | SERVICE_WIN32_OWN_PROCESS = 0x00000010 115 | SERVICE_WIN32_SHARE_PROCESS = 0x00000020 116 | SERVICE_INTERACTIVE_PROCESS = 0x00000100 117 | 118 | SERVICE_BOOT_START = 0x0 119 | SERVICE_SYSTEM_START = 0x1 120 | SERVICE_AUTO_START = 0x2 121 | SERVICE_DEMAND_START = 0x3 122 | SERVICE_DISABLED = 0x4 123 | 124 | SERVICE_ERROR_IGNORE = 0x0 125 | SERVICE_ERROR_NORMAL = 0x1 126 | SERVICE_ERROR_SEVERE = 0x2 127 | SERVICE_ERROR_CRITICAL = 0x3 128 | 129 | DEVPROP_TYPE_STRING = 0x00000012 130 | DEVPROP_TYPE_STRING_LIST = 0x00002012 131 | DEVPROP_TYPE_BINARY = 0x00001003 132 | DEVPROP_TYPE_BOOLEAN = 0x00000011 133 | DEVPROP_TYPE_UINT32 = 0x00000007 134 | 135 | FLG_ADDREG_BINVALUETYPE = 0x00000001 136 | FLG_ADDREG_NOCLOBBER = 0x00000002 137 | FLG_ADDREG_DELVAL = 0x00000004 138 | FLG_ADDREG_APPEND = 0x00000008 139 | FLG_ADDREG_KEYONLY = 0x00000010 140 | FLG_ADDREG_OVERWRITEONLY = 0x00000020 141 | FLG_ADDREG_64BITKEY = 0x00001000 142 | FLG_ADDREG_KEYONLY_COMMON = 0x00002000 143 | FLG_ADDREG_32BITKEY = 0x00004000 144 | FLG_ADDREG_TYPE_SZ = 0x00000000 145 | FLG_ADDREG_TYPE_MULTI_SZ = 0x00010000 146 | FLG_ADDREG_TYPE_EXPAND_SZ = 0x00020000 147 | FLG_ADDREG_TYPE_DWORD = 0x00010001 148 | FLG_ADDREG_TYPE_NONE = 0x00020001 149 | -------------------------------------------------------------------------------- /HidHide/HidHide.inf: -------------------------------------------------------------------------------- 1 | ; (c) Eric Korff de Gidts, Benjamin Hoeglinger-Stelzer 2 | ; Creator: Eric Korff de Gidts 3 | ; Maintainer: Benjamin Hoeglinger-Stelzer 4 | ; Signer: Nefarius Software Solutions e.U. 5 | ; SPDX-License-Identifier: MIT 6 | ; HidHide.inf 7 | 8 | ; ==== Version Section ==== 9 | 10 | [Version] 11 | Signature = "$Windows NT$" 12 | Class = System 13 | ClassGUID = {4D36E97D-E325-11CE-BFC1-08002BE10318} 14 | Provider = %ManufacturerName% 15 | CatalogFile = HidHide.cat 16 | PnpLockdown = 1 17 | DriverVer = 18 | 19 | ; ==== SourceDisksNames Section ==== 20 | 21 | [SourceDisksNames] 22 | 1 = %DiskName%,,,"" 23 | 24 | ; ==== SourceDisksFiles Section ==== 25 | 26 | [SourceDisksFiles] 27 | HidHide.sys = 1,, 28 | 29 | ; ==== DestinationDirs Section ==== 30 | 31 | [DestinationDirs] 32 | HidHide_Device_CopyFiles = 12 ; %windir%\System32\DRIVERS\ 33 | 34 | ; ==== Manufacturer Section ==== 35 | 36 | [Manufacturer] 37 | %ManufacturerName% = Standard,NT$ARCH$ 38 | 39 | ; ==== Models Section ==== 40 | 41 | [Standard.NT$ARCH$] 42 | %HidHideDeviceName% = HidHide_Device,root\HidHide 43 | 44 | ; ==== DDInstall Section ==== 45 | 46 | [HidHide_Device] 47 | CopyFiles = HidHide_Device_CopyFiles 48 | 49 | [HidHide_Device_CopyFiles] 50 | HidHide.sys,,,0x00004000 ; COPYFLG_IN_USE_RENAME 51 | 52 | ; ==== DDInstall.Services Section ==== 53 | 54 | [HidHide_Device.Services] 55 | AddService = HidHide,%AddServiceFlags%,HidHide_Device_Service_AddService 56 | 57 | [HidHide_Device_Service_AddService] 58 | DisplayName = %HidHideServiceDisplayName% 59 | ServiceType = %SERVICE_KERNEL_DRIVER% 60 | StartType = %SERVICE_DEMAND_START% 61 | ErrorControl = %SERVICE_ERROR_NORMAL% 62 | ServiceBinary = %12%\HidHide.sys 63 | AddReg = HidHide_Device_Service_AddReg 64 | 65 | [HidHide_Device_Service_AddReg] 66 | HKR,"Parameters","WhitelistedFullImageNames",%AddRegMultiSzInitialOnly%,"" ; HKLM\SYSTEM\ControlSet001\Services\HidHide\Parameters\WhitelistedFullImageNames (set initially-only as we may want to preserve earlier user selections) 67 | HKR,"Parameters","BlacklistedDeviceInstancePaths",%AddRegMultiSzInitialOnly%,"" ; HKLM\SYSTEM\ControlSet001\Services\HidHide\Parameters\BlacklistedDeviceInstancePaths (set initially-only as we may want to preserve earlier user selections) 68 | HKR,"Parameters","Active",%FLG_ADDREG_TYPE_DWORD%,0 ; HKLM\SYSTEM\ControlSet001\Services\HidHide\Parameters\Active (disable service after each install as we require the user to run the configuration utility first) 69 | 70 | [HidHide_Device_Service_AddReg.Security] 71 | "D:P(OD;CI;KA;;;BA)(OD;CI;KA;;;BU)" ; HKLM\SYSTEM\ControlSet001\Services\HidHide\Parameters\ (prohibit build in adminstrators, and build in users of doing anything with the keys) 72 | 73 | ; ==== DDInstall.Wdf Section ==== 74 | 75 | [HidHide_Device.Wdf] 76 | KmdfService = HidHide,HidHide_Device_Wdf_KmdfService 77 | 78 | [HidHide_Device_Wdf_KmdfService] 79 | KmdfLibraryVersion = $KMDFVERSION$ 80 | 81 | ; ==== Strings Section ==== 82 | 83 | [Strings] 84 | ManufacturerName = "Nefarius Software Solutions e.U." 85 | DiskName = "Nefarius HidHide Installation Disk" 86 | HidHideDeviceName = "Nefarius HidHide Device" 87 | HidHideServiceDisplayName = "Nefarius HidHide Service" 88 | AddServiceFlags = 0x000013FE ; SPSVCINST_NOCLOBBER_REQUIREDPRIVILEGES 89 | ; SPSVCINST_STOPSERVICE 90 | ; SPSVCINST_NOCLOBBER_DESCRIPTION 91 | ; SPSVCINST_NOCLOBBER_DEPENDENCIES 92 | ; SPSVCINST_NOCLOBBER_LOADORDERGROUP 93 | ; SPSVCINST_NOCLOBBER_ERRORCONTROL 94 | ; SPSVCINST_NOCLOBBER_STARTTYPE 95 | ; SPSVCINST_NOCLOBBER_DISPLAYNAME 96 | ; SPSVCINST_DELETEEVENTLOGENTRY 97 | ; SPSVCINST_ASSOCSERVICE 98 | AddRegMultiSzInitialOnly = 0x00010002 ; FLG_ADDREG_TYPE_MULTI_SZ 99 | ; FLG_ADDREG_NOCLOBBER 100 | 101 | SPSVCINST_TAGTOFRONT = 0x00000001 102 | SPSVCINST_ASSOCSERVICE = 0x00000002 103 | SPSVCINST_DELETEEVENTLOGENTRY = 0x00000004 104 | SPSVCINST_NOCLOBBER_DISPLAYNAME = 0x00000008 105 | SPSVCINST_NOCLOBBER_STARTTYPE = 0x00000010 106 | SPSVCINST_NOCLOBBER_ERRORCONTROL = 0x00000020 107 | SPSVCINST_NOCLOBBER_LOADORDERGROUP = 0x00000040 108 | SPSVCINST_NOCLOBBER_DEPENDENCIES = 0x00000080 109 | SPSVCINST_NOCLOBBER_DESCRIPTION = 0x00000100 110 | SPSVCINST_STOPSERVICE = 0x00000200 111 | SPSVCINST_CLOBBER_SECURITY = 0x00000400 112 | SPSVCINST_STARTSERVICE = 0x00000800 113 | SPSVCINST_NOCLOBBER_REQUIREDPRIVILEGES = 0x00001000 114 | 115 | SERVICE_KERNEL_DRIVER = 0x00000001 116 | SERVICE_FILE_SYSTEM_DRIVER = 0x00000002 117 | SERVICE_WIN32_OWN_PROCESS = 0x00000010 118 | SERVICE_WIN32_SHARE_PROCESS = 0x00000020 119 | SERVICE_INTERACTIVE_PROCESS = 0x00000100 120 | 121 | SERVICE_BOOT_START = 0x0 122 | SERVICE_SYSTEM_START = 0x1 123 | SERVICE_AUTO_START = 0x2 124 | SERVICE_DEMAND_START = 0x3 125 | SERVICE_DISABLED = 0x4 126 | 127 | SERVICE_ERROR_IGNORE = 0x0 128 | SERVICE_ERROR_NORMAL = 0x1 129 | SERVICE_ERROR_SEVERE = 0x2 130 | SERVICE_ERROR_CRITICAL = 0x3 131 | 132 | DEVPROP_TYPE_STRING = 0x00000012 133 | DEVPROP_TYPE_STRING_LIST = 0x00002012 134 | DEVPROP_TYPE_BINARY = 0x00001003 135 | DEVPROP_TYPE_BOOLEAN = 0x00000011 136 | DEVPROP_TYPE_UINT32 = 0x00000007 137 | 138 | FLG_ADDREG_BINVALUETYPE = 0x00000001 139 | FLG_ADDREG_NOCLOBBER = 0x00000002 140 | FLG_ADDREG_DELVAL = 0x00000004 141 | FLG_ADDREG_APPEND = 0x00000008 142 | FLG_ADDREG_KEYONLY = 0x00000010 143 | FLG_ADDREG_OVERWRITEONLY = 0x00000020 144 | FLG_ADDREG_64BITKEY = 0x00001000 145 | FLG_ADDREG_KEYONLY_COMMON = 0x00002000 146 | FLG_ADDREG_32BITKEY = 0x00004000 147 | FLG_ADDREG_TYPE_SZ = 0x00000000 148 | FLG_ADDREG_TYPE_MULTI_SZ = 0x00010000 149 | FLG_ADDREG_TYPE_EXPAND_SZ = 0x00020000 150 | FLG_ADDREG_TYPE_DWORD = 0x00010001 151 | FLG_ADDREG_TYPE_NONE = 0x00020001 152 | -------------------------------------------------------------------------------- /HidHide/HidHide.man: -------------------------------------------------------------------------------- 1 | 2 | 7 | 11 | 12 | 13 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 0x000000000001 53 | 16 54 | 0 55 | QPC 56 | None 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Ww][Ii][Nn]32/ 27 | [Aa][Rr][Mm]/ 28 | [Aa][Rr][Mm]64/ 29 | bld/ 30 | [Bb]in/ 31 | [Oo]bj/ 32 | [Ll]og/ 33 | [Ll]ogs/ 34 | 35 | # Visual Studio 2015/2017 cache/options directory 36 | .vs/ 37 | # Uncomment if you have tasks that create the project's static files in wwwroot 38 | #wwwroot/ 39 | 40 | # Visual Studio 2017 auto generated files 41 | Generated\ Files/ 42 | 43 | # MSTest test Results 44 | [Tt]est[Rr]esult*/ 45 | [Bb]uild[Ll]og.* 46 | 47 | # NUnit 48 | *.VisualState.xml 49 | TestResult.xml 50 | nunit-*.xml 51 | 52 | # Build Results of an ATL Project 53 | [Dd]ebugPS/ 54 | [Rr]eleasePS/ 55 | dlldata.c 56 | 57 | # Benchmark Results 58 | BenchmarkDotNet.Artifacts/ 59 | 60 | # .NET Core 61 | project.lock.json 62 | project.fragment.lock.json 63 | artifacts/ 64 | 65 | # ASP.NET Scaffolding 66 | ScaffoldingReadMe.txt 67 | 68 | # StyleCop 69 | StyleCopReport.xml 70 | 71 | # Files built by Visual Studio 72 | *_i.c 73 | *_p.c 74 | *_h.h 75 | *.ilk 76 | *.meta 77 | *.obj 78 | *.iobj 79 | *.pch 80 | *.pdb 81 | *.ipdb 82 | *.pgc 83 | *.pgd 84 | *.rsp 85 | *.sbr 86 | *.tlb 87 | *.tli 88 | *.tlh 89 | *.tmp 90 | *.tmp_proj 91 | *_wpftmp.csproj 92 | *.log 93 | *.vspscc 94 | *.vssscc 95 | .builds 96 | *.pidb 97 | *.svclog 98 | *.scc 99 | 100 | # Chutzpah Test files 101 | _Chutzpah* 102 | 103 | # Visual C++ cache files 104 | ipch/ 105 | *.aps 106 | *.ncb 107 | *.opendb 108 | *.opensdf 109 | *.sdf 110 | *.cachefile 111 | *.VC.db 112 | *.VC.VC.opendb 113 | 114 | # Visual Studio profiler 115 | *.psess 116 | *.vsp 117 | *.vspx 118 | *.sap 119 | 120 | # Visual Studio Trace Files 121 | *.e2e 122 | 123 | # TFS 2012 Local Workspace 124 | $tf/ 125 | 126 | # Guidance Automation Toolkit 127 | *.gpState 128 | 129 | # ReSharper is a .NET coding add-in 130 | _ReSharper*/ 131 | *.[Rr]e[Ss]harper 132 | *.DotSettings.user 133 | 134 | # TeamCity is a build add-in 135 | _TeamCity* 136 | 137 | # DotCover is a Code Coverage Tool 138 | *.dotCover 139 | 140 | # AxoCover is a Code Coverage Tool 141 | .axoCover/* 142 | !.axoCover/settings.json 143 | 144 | # Coverlet is a free, cross platform Code Coverage Tool 145 | coverage*.json 146 | coverage*.xml 147 | coverage*.info 148 | 149 | # Visual Studio code coverage results 150 | *.coverage 151 | *.coveragexml 152 | 153 | # NCrunch 154 | _NCrunch_* 155 | .*crunch*.local.xml 156 | nCrunchTemp_* 157 | 158 | # MightyMoose 159 | *.mm.* 160 | AutoTest.Net/ 161 | 162 | # Web workbench (sass) 163 | .sass-cache/ 164 | 165 | # Installshield output folder 166 | [Ee]xpress/ 167 | 168 | # DocProject is a documentation generator add-in 169 | DocProject/buildhelp/ 170 | DocProject/Help/*.HxT 171 | DocProject/Help/*.HxC 172 | DocProject/Help/*.hhc 173 | DocProject/Help/*.hhk 174 | DocProject/Help/*.hhp 175 | DocProject/Help/Html2 176 | DocProject/Help/html 177 | 178 | # Click-Once directory 179 | publish/ 180 | 181 | # Publish Web Output 182 | *.[Pp]ublish.xml 183 | *.azurePubxml 184 | # Note: Comment the next line if you want to checkin your web deploy settings, 185 | # but database connection strings (with potential passwords) will be unencrypted 186 | *.pubxml 187 | *.publishproj 188 | 189 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 190 | # checkin your Azure Web App publish settings, but sensitive information contained 191 | # in these scripts will be unencrypted 192 | PublishScripts/ 193 | 194 | # NuGet Packages 195 | *.nupkg 196 | # NuGet Symbol Packages 197 | *.snupkg 198 | # The packages folder can be ignored because of Package Restore 199 | **/[Pp]ackages/* 200 | # except build/, which is used as an MSBuild target. 201 | !**/[Pp]ackages/build/ 202 | # Uncomment if necessary however generally it will be regenerated when needed 203 | #!**/[Pp]ackages/repositories.config 204 | # NuGet v3's project.json files produces more ignorable files 205 | *.nuget.props 206 | *.nuget.targets 207 | 208 | # Microsoft Azure Build Output 209 | csx/ 210 | *.build.csdef 211 | 212 | # Microsoft Azure Emulator 213 | ecf/ 214 | rcf/ 215 | 216 | # Windows Store app package directories and files 217 | AppPackages/ 218 | BundleArtifacts/ 219 | Package.StoreAssociation.xml 220 | _pkginfo.txt 221 | *.appx 222 | *.appxbundle 223 | *.appxupload 224 | 225 | # Visual Studio cache files 226 | # files ending in .cache can be ignored 227 | *.[Cc]ache 228 | # but keep track of directories ending in .cache 229 | !?*.[Cc]ache/ 230 | 231 | # Others 232 | ClientBin/ 233 | ~$* 234 | *~ 235 | *.dbmdl 236 | *.dbproj.schemaview 237 | *.jfm 238 | *.pfx 239 | *.publishsettings 240 | orleans.codegen.cs 241 | 242 | # Including strong name files can present a security risk 243 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 244 | #*.snk 245 | 246 | # Since there are multiple workflows, uncomment next line to ignore bower_components 247 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 248 | #bower_components/ 249 | 250 | # RIA/Silverlight projects 251 | Generated_Code/ 252 | 253 | # Backup & report files from converting an old project file 254 | # to a newer Visual Studio version. Backup files are not needed, 255 | # because we have git ;-) 256 | _UpgradeReport_Files/ 257 | Backup*/ 258 | UpgradeLog*.XML 259 | UpgradeLog*.htm 260 | ServiceFabricBackup/ 261 | *.rptproj.bak 262 | 263 | # SQL Server files 264 | *.mdf 265 | *.ldf 266 | *.ndf 267 | 268 | # Business Intelligence projects 269 | *.rdl.data 270 | *.bim.layout 271 | *.bim_*.settings 272 | *.rptproj.rsuser 273 | *- [Bb]ackup.rdl 274 | *- [Bb]ackup ([0-9]).rdl 275 | *- [Bb]ackup ([0-9][0-9]).rdl 276 | 277 | # Microsoft Fakes 278 | FakesAssemblies/ 279 | 280 | # GhostDoc plugin setting file 281 | *.GhostDoc.xml 282 | 283 | # Node.js Tools for Visual Studio 284 | .ntvs_analysis.dat 285 | node_modules/ 286 | 287 | # Visual Studio 6 build log 288 | *.plg 289 | 290 | # Visual Studio 6 workspace options file 291 | *.opt 292 | 293 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 294 | *.vbw 295 | 296 | # Visual Studio LightSwitch build output 297 | **/*.HTMLClient/GeneratedArtifacts 298 | **/*.DesktopClient/GeneratedArtifacts 299 | **/*.DesktopClient/ModelManifest.xml 300 | **/*.Server/GeneratedArtifacts 301 | **/*.Server/ModelManifest.xml 302 | _Pvt_Extensions 303 | 304 | # Paket dependency manager 305 | .paket/paket.exe 306 | paket-files/ 307 | 308 | # FAKE - F# Make 309 | .fake/ 310 | 311 | # CodeRush personal settings 312 | .cr/personal 313 | 314 | # Python Tools for Visual Studio (PTVS) 315 | __pycache__/ 316 | *.pyc 317 | 318 | # Cake - Uncomment if you are using it 319 | # tools/** 320 | # !tools/packages.config 321 | 322 | # Tabs Studio 323 | *.tss 324 | 325 | # Telerik's JustMock configuration file 326 | *.jmconfig 327 | 328 | # BizTalk build output 329 | *.btp.cs 330 | *.btm.cs 331 | *.odx.cs 332 | *.xsd.cs 333 | 334 | # OpenCover UI analysis results 335 | OpenCover/ 336 | 337 | # Azure Stream Analytics local run output 338 | ASALocalRun/ 339 | 340 | # MSBuild Binary and Structured Log 341 | *.binlog 342 | 343 | # NVidia Nsight GPU debugger configuration file 344 | *.nvuser 345 | 346 | # MFractors (Xamarin productivity tool) working folder 347 | .mfractor/ 348 | 349 | # Local History for Visual Studio 350 | .localhistory/ 351 | 352 | # BeatPulse healthcheck temp database 353 | healthchecksdb 354 | 355 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 356 | MigrationBackup/ 357 | 358 | # Ionide (cross platform F# VS Code tools) working folder 359 | .ionide/ 360 | 361 | # Fody - auto-generated XML schema 362 | FodyWeavers.xsd 363 | 364 | HidHide/RC* 365 | HidHideClient/RC* 366 | *.opendb 367 | *.aps 368 | /Setup 369 | vcpkg_installed 370 | -------------------------------------------------------------------------------- /HidHideCLI/src/Volume.cpp: -------------------------------------------------------------------------------- 1 | // (c) Eric Korff de Gidts 2 | // SPDX-License-Identifier: MIT 3 | // Volume.cpp 4 | #pragma once 5 | #include "stdafx.h" 6 | #include "Volume.h" 7 | #include "Utils.h" 8 | #include "Logging.h" 9 | 10 | namespace HidHide 11 | { 12 | typedef std::unique_ptr::type, decltype(&::FindVolumeClose)> FindVolumeClosePtr; 13 | typedef std::function<__declspec(noreturn) bool(_In_ std::wstring const& volumeName, _In_ std::filesystem::path const& volumeMountPoint)> IterateAllVolumeMountPointsForFileStorageCallback; 14 | typedef std::pair VolumeMountPointAndDosDeviceName; 15 | 16 | // Get the DosDeviceName associated with a volume name 17 | std::filesystem::path DosDeviceNameForVolumeName(_In_ std::wstring const& volumeName) 18 | { 19 | TRACE_ALWAYS(L""); 20 | std::vector buffer(UNICODE_STRING_MAX_CHARS); 21 | // Strip the leading '\\?\' and trailing '\' and isolate the Volume{} part in the volume name 22 | if (0 == ::QueryDosDeviceW(volumeName.substr(4, volumeName.size() - 5).c_str(), buffer.data(), static_cast(buffer.size()))) THROW_WIN32_LAST_ERROR; 23 | return (buffer.data()); 24 | } 25 | 26 | // Get the mount points associated with a volume 27 | std::set VolumeMountPoints(_In_ std::wstring const& volumeName) 28 | { 29 | TRACE_ALWAYS(L""); 30 | std::set result; 31 | 32 | std::vector buffer(UNICODE_STRING_MAX_CHARS); 33 | DWORD needed{}; 34 | if (FALSE == ::GetVolumePathNamesForVolumeNameW(volumeName.data(), buffer.data(), static_cast(buffer.size()), &needed)) 35 | { 36 | if (ERROR_MORE_DATA != ::GetLastError()) THROW_WIN32_LAST_ERROR; 37 | } 38 | else 39 | { 40 | // Iterate all logical disks associated with this volume 41 | auto const list{ MultiStringToStringList(buffer) }; 42 | for (auto it{ std::begin(list) }; (std::end(list) != it); it++) result.emplace(*it); 43 | } 44 | 45 | return (result); 46 | } 47 | 48 | // Iterates all volume mount points and calls the callback method for each entry found 49 | void IterateAllVolumeMountPointsForFileStorage(_In_ IterateAllVolumeMountPointsForFileStorageCallback iterateAllVolumeMountPointsForFileStorageCallback) 50 | { 51 | TRACE_ALWAYS(L""); 52 | 53 | // Prepare the volume iterator 54 | std::vector volumeName(UNICODE_STRING_MAX_CHARS); 55 | auto const findVolumeClosePtr{ FindVolumeClosePtr(::FindFirstVolumeW(volumeName.data(), static_cast(volumeName.size())), &::FindVolumeClose) }; 56 | if (INVALID_HANDLE_VALUE == findVolumeClosePtr.get()) THROW_WIN32_LAST_ERROR; 57 | 58 | // Iterate all volume names with syntax '\\?\Volume{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}' 59 | while (true) 60 | { 61 | // Iterate all mount points for this volume 62 | for (auto const& volumeMountPoint : VolumeMountPoints(volumeName.data())) 63 | { 64 | // Bail out when the callback signals no more processing is needed (not continue) 65 | if (!iterateAllVolumeMountPointsForFileStorageCallback(volumeName.data(), volumeMountPoint)) return; 66 | } 67 | 68 | // Move to the next volume 69 | if (FALSE == ::FindNextVolumeW(findVolumeClosePtr.get(), volumeName.data(), static_cast(volumeName.size()))) 70 | { 71 | if (ERROR_NO_MORE_FILES != ::GetLastError()) THROW_WIN32_LAST_ERROR; 72 | 73 | // No more volumes to iterate 74 | break; 75 | } 76 | } 77 | } 78 | 79 | // Find the volume mount point that could store the file specified 80 | // Returns an empty path when no suitable volume was found 81 | std::filesystem::path FindVolumeMountPointForFullyQualifiedFileName(_In_ std::filesystem::path const& fullyQualifiedFileName) 82 | { 83 | TRACE_ALWAYS(L""); 84 | 85 | auto const fullyQualifiedFileNameNative{ fullyQualifiedFileName.native() }; 86 | std::wstring result; 87 | IterateAllVolumeMountPointsForFileStorage([&fullyQualifiedFileNameNative, &result](_In_ std::wstring const& volumeName, _In_ std::filesystem::path const& volumeMountPoint) 88 | { 89 | UNREFERENCED_PARAMETER(volumeName); 90 | auto const volumeMountPointNative{ volumeMountPoint.native() }; 91 | if (0 == volumeMountPointNative.compare(0, std::wstring::npos, fullyQualifiedFileNameNative, 0, volumeMountPointNative.size())) 92 | { 93 | // Keep track of the best, most specialized (hence longest) path while iterating 94 | if (volumeMountPointNative.size() > result.size()) result = volumeMountPoint; 95 | } 96 | 97 | // Continue iterating 98 | return (true); 99 | }); 100 | 101 | return (result); 102 | } 103 | 104 | // Find the mount point and dos device name where the full image name can be stored 105 | // Returns an empty mount point when no suitable storage location was found 106 | VolumeMountPointAndDosDeviceName FindVolumeMountPointAndDosDeviceNameForFullImageName(_In_ HidHide::FullImageName const& fullImageName) 107 | { 108 | TRACE_ALWAYS(L""); 109 | 110 | auto const fullImageNameNative{ fullImageName.native() }; 111 | VolumeMountPointAndDosDeviceName result; 112 | IterateAllVolumeMountPointsForFileStorage([&fullImageNameNative, &result](_In_ std::wstring const& volumeName, _In_ std::filesystem::path const& volumeMountPoint) 113 | { 114 | auto const dosDeviceName{ DosDeviceNameForVolumeName(volumeName) }; 115 | auto const dosDeviceNameNative{ dosDeviceName.native() }; 116 | if (0 == dosDeviceNameNative.compare(0, std::wstring::npos, fullImageNameNative, 0, dosDeviceNameNative.size())) 117 | { 118 | result = std::make_pair(volumeMountPoint, dosDeviceName); 119 | return (false); 120 | } 121 | 122 | // Continue iterating 123 | return (true); 124 | }); 125 | 126 | return (result); 127 | } 128 | 129 | // Get the volume name associated with a volume mount point 130 | std::wstring VolumeNameForVolumeMountPoint(_In_ std::filesystem::path const& volumeMountPoint) 131 | { 132 | TRACE_ALWAYS(L""); 133 | std::vector buffer(UNICODE_STRING_MAX_CHARS); 134 | if (FALSE == ::GetVolumeNameForVolumeMountPointW(volumeMountPoint.native().c_str(), buffer.data(), static_cast(buffer.size()))) THROW_WIN32_LAST_ERROR; 135 | return (buffer.data()); 136 | } 137 | } 138 | 139 | namespace HidHide 140 | { 141 | _Use_decl_annotations_ 142 | FullImageName FileNameToFullImageName(std::filesystem::path const& fullyQualifiedFileName) 143 | { 144 | TRACE_ALWAYS(L""); 145 | auto const volumeMountPoint{ FindVolumeMountPointForFullyQualifiedFileName(fullyQualifiedFileName) }; 146 | if (volumeMountPoint.empty()) return (FullImageName{}); 147 | auto const dosDeviceName{ DosDeviceNameForVolumeName(VolumeNameForVolumeMountPoint(volumeMountPoint)) }; 148 | auto const fileNameWithoutMountPoint{ std::filesystem::path(fullyQualifiedFileName.native().substr(volumeMountPoint.native().size())) }; 149 | return (dosDeviceName / fileNameWithoutMountPoint); 150 | } 151 | 152 | _Use_decl_annotations_ 153 | std::filesystem::path FullImageNameToFileName(_In_ FullImageName const& fullImageName) 154 | { 155 | TRACE_ALWAYS(L""); 156 | auto const volumeMountPointAndDosDeviceName{ FindVolumeMountPointAndDosDeviceNameForFullImageName(fullImageName) }; 157 | auto const& [volumeMountPoint, dosDeviceName] { volumeMountPointAndDosDeviceName }; 158 | if (volumeMountPoint.empty()) return (FullImageName{}); 159 | auto const fullImageNameWithoutDosDeviceName{ std::filesystem::path(fullImageName.native().substr(dosDeviceName.native().size() + 1)) }; 160 | return (volumeMountPoint / fullImageNameWithoutDosDeviceName); 161 | } 162 | } 163 | -------------------------------------------------------------------------------- /HidHideCLI/src/Logging.h: -------------------------------------------------------------------------------- 1 | // (c) Eric Korff de Gidts 2 | // SPDX-License-Identifier: MIT 3 | // Logging.h 4 | #pragma once 5 | 6 | // The define for ProjectDirLength is passed from the project file to the source code via a define 7 | static_assert((sizeof(__FILE__) > ProjectDirLength), "Ensure any source code is located in a subdirectory of the project"); 8 | 9 | // Macros for tracing 10 | #define TRACE_DETAILED(message) { TraceEvent(&__FILE__[ProjectDirLength], __LINE__, __FUNCTION__, &EtwEventTraceDetailed, message, ""); if (MCGEN_EVENT_ENABLED(EtwEventTraceDetailed) && MCGEN_EVENT_ENABLED(EtwEventTraceDebugging)) DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "%s(%d) %s\n", &__FILE__[ProjectDirLength], __LINE__, __FUNCTION__); } 11 | #define TRACE_PERFORMANCE(message) { TraceEvent(&__FILE__[ProjectDirLength], __LINE__, __FUNCTION__, &EtwEventTracePerformance, message, ""); if (MCGEN_EVENT_ENABLED(EtwEventTracePerformance) && MCGEN_EVENT_ENABLED(EtwEventTraceDebugging)) DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "%s(%d) %s\n", &__FILE__[ProjectDirLength], __LINE__, __FUNCTION__); } 12 | #define TRACE_ALWAYS(message) { TraceEvent(&__FILE__[ProjectDirLength], __LINE__, __FUNCTION__, &EtwEventTraceAlways, message, ""); if (MCGEN_EVENT_ENABLED(EtwEventTraceAlways) && MCGEN_EVENT_ENABLED(EtwEventTraceDebugging)) DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "%s(%d) %s\n", &__FILE__[ProjectDirLength], __LINE__, __FUNCTION__); } 13 | 14 | // Macro for a shorter notation on the LogEvent parameter list 15 | #define ETW(eventDescriptor) &__FILE__[ProjectDirLength], __LINE__, __FUNCTION__, &EtwEventLog##eventDescriptor 16 | 17 | // Macros for logging 18 | #define LOG_AND_RETURN_NTSTATUS(message, result) { LogEvent(ETW(Exception), L"%s reports NT status 0x%08X", message, result); return (result); } 19 | 20 | // Macros for debugging messages (for logging internally or when logging isn't yet available) 21 | #define DBG_AND_RETURN_NTSTATUS(message, result) { DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "%s reports NT status 0x%08X\n", message, result); return (result); } // DIRQL 22 | 23 | // The maximum logging message length supported (as TRACE_MESSAGE_MAXIMUM_SIZE is too large) 24 | #define LOGGING_MESSAGE_MAXIMUM_SIZE 200 25 | 26 | #if MCGEN_USE_KERNEL_MODE_APIS 27 | EXTERN_C_START 28 | 29 | // Register the ETW logging and tracing providers 30 | _IRQL_requires_same_ 31 | _IRQL_requires_max_(PASSIVE_LEVEL) 32 | NTSTATUS LogRegisterProviders(); 33 | 34 | // Unregister the ETW logging and tracing providers 35 | _IRQL_requires_same_ 36 | _IRQL_requires_max_(PASSIVE_LEVEL) 37 | NTSTATUS LogUnregisterProviders(); 38 | 39 | // Trace a message 40 | _IRQL_requires_same_ 41 | _IRQL_requires_max_(HIGH_LEVEL) 42 | NTSTATUS TraceEvent(_In_ NTSTRSAFE_PCSTR fileName, _In_ UINT32 lineNumber, _In_ NTSTRSAFE_PCSTR functionName, _In_ PCEVENT_DESCRIPTOR event, _In_ NTSTRSAFE_PCWSTR messageW, _In_ NTSTRSAFE_PCSTR messageA); 43 | 44 | // Log and trace a message 45 | _IRQL_requires_same_ 46 | _IRQL_requires_max_(HIGH_LEVEL) 47 | NTSTATUS LogEvent(_In_ NTSTRSAFE_PCSTR fileName, _In_ UINT32 lineNumber, _In_ NTSTRSAFE_PCSTR functionName, _In_ PCEVENT_DESCRIPTOR event, _In_z_ _Printf_format_string_ NTSTRSAFE_PCWSTR format, ...); 48 | 49 | EXTERN_C_END 50 | #else 51 | 52 | // Class converting error codes into text and pin-pointing the location where an exception is thrown 53 | class LogException 54 | { 55 | public: 56 | 57 | LogException() noexcept = delete; 58 | ~LogException() = default; 59 | LogException(_In_ LogException const& rhs) = delete; 60 | LogException(_In_ LogException && rhs) noexcept = delete; 61 | LogException& operator=(_In_ LogException const& rhs) = delete; 62 | LogException& operator=(_In_ LogException && rhs) = delete; 63 | 64 | // Maintain formatted string containing exception location, result type, and result 65 | inline explicit LogException(_In_ std::string&& encodedExceptionData) noexcept { std::swap(m_EncodedExceptionData, encodedExceptionData); } 66 | 67 | // Log the location from where the exception is being reported together with the exception text 68 | LogException const& Log(_In_ LPCSTR fileName, _In_ UINT32 lineNumber, _In_opt_ LPCSTR functionName, _In_ PCEVENT_DESCRIPTOR event) noexcept; 69 | 70 | // Convert the error code where needed and get the result in the specified type 71 | CONFIGRET ToCONFIGRET() const noexcept; 72 | HRESULT ToHRESULT() const noexcept; 73 | NTSTATUS ToNTSTATUS() const noexcept; 74 | DWORD ToWIN32() const noexcept; 75 | 76 | // Pin point the source code location where the exception is thrown together with the exception text 77 | static std::string EncodeCONFIGRET(_In_ LPCSTR fileName, _In_ UINT32 lineNumber, _In_opt_ LPCSTR functionName, _In_ PCEVENT_DESCRIPTOR event, _In_ CONFIGRET result) noexcept; 78 | static std::string EncodeHRESULT (_In_ LPCSTR fileName, _In_ UINT32 lineNumber, _In_opt_ LPCSTR functionName, _In_ PCEVENT_DESCRIPTOR event, _In_ HRESULT result) noexcept; 79 | static std::string EncodeNTSTATUS (_In_ LPCSTR fileName, _In_ UINT32 lineNumber, _In_opt_ LPCSTR functionName, _In_ PCEVENT_DESCRIPTOR event, _In_ NTSTATUS result) noexcept; 80 | static std::string EncodeWIN32 (_In_ LPCSTR fileName, _In_ UINT32 lineNumber, _In_opt_ LPCSTR functionName, _In_ PCEVENT_DESCRIPTOR event, _In_ DWORD result) noexcept; 81 | 82 | // Re-throw an exception and copy its message 83 | static std::string ExceptionMessage() noexcept; 84 | 85 | private: 86 | 87 | std::string m_EncodedExceptionData; 88 | }; 89 | 90 | // Macros for throwing exceptions 91 | #define THROW_CONFIGRET(result) { throw std::runtime_error(LogException::EncodeCONFIGRET(ETW(Exception), result)); } 92 | #define THROW_HRESULT(result) { throw std::runtime_error(LogException::EncodeHRESULT (ETW(Exception), result)); } 93 | #define THROW_NTSTATUS(result) { throw std::runtime_error(LogException::EncodeNTSTATUS (ETW(Exception), result)); } 94 | #define THROW_WIN32(result) { throw std::runtime_error(LogException::EncodeWIN32 (ETW(Exception), result)); } 95 | #define THROW_WIN32_LAST_ERROR { throw std::runtime_error(LogException::EncodeWIN32 (ETW(Exception), ::GetLastError())); } 96 | 97 | // Macros for logging from within an exception handler 98 | #define LOGEXC_AND_CONTINUE { LogException(LogException::ExceptionMessage()).Log(ETW(Exception)); } 99 | #define LOGEXC_AND_RETURN { LogException(LogException::ExceptionMessage()).Log(ETW(Exception)); return; } 100 | #define LOGEXC_AND_RETURN_RESULT(result) { LogException(LogException::ExceptionMessage()).Log(ETW(Exception)); return (result); } 101 | #define LOGEXC_AND_RETURN_CONFIGRET { return (LogException(LogException::ExceptionMessage()).Log(ETW(Exception)).ToCONFIGRET()); } 102 | #define LOGEXC_AND_RETURN_HRESULT { return (LogException(LogException::ExceptionMessage()).Log(ETW(Exception)).ToHRESULT()); } 103 | #define LOGEXC_AND_RETURN_NTSTATUS { return (LogException(LogException::ExceptionMessage()).Log(ETW(Exception)).ToNTSTATUS()); } 104 | #define LOGEXC_AND_RETURN_WIN32 { return (LogException(LogException::ExceptionMessage()).Log(ETW(Exception)).ToWIN32()); } 105 | 106 | // Convert an NTSTATUS into a WIN32 error code 107 | DWORD WIN32_FROM_NTSTATUS(_In_ NTSTATUS result) noexcept; 108 | 109 | // Convert an NTSTATUS into a WIN32 error code 110 | DWORD WIN32_FROM_CONFIGRET(_In_ CONFIGRET result) noexcept; 111 | 112 | // DbgPrintEx equavalent for user mode applications 113 | NTSTATUS DbgPrintEx(_In_ ULONG componentId, _In_ ULONG level, _In_z_ _Printf_format_string_ LPCSTR format, ...) noexcept; 114 | 115 | // Register the ETW logging and tracing providers 116 | EXTERN_C NTSTATUS LogRegisterProviders() noexcept; 117 | 118 | // Unregister the ETW logging and tracing providers 119 | EXTERN_C NTSTATUS LogUnregisterProviders() noexcept; 120 | 121 | // Trace a message 122 | NTSTATUS TraceEvent(_In_ LPCSTR fileName, _In_ UINT32 lineNumber, _In_opt_ LPCSTR functionName, _In_ PCEVENT_DESCRIPTOR event, _In_opt_ LPCWSTR messageW, _In_opt_ LPCSTR messageA) noexcept; 123 | 124 | // Log and trace a message 125 | NTSTATUS LogEvent(_In_ LPCSTR fileName, _In_ UINT32 lineNumber, _In_opt_ LPCSTR functionName, _In_ PCEVENT_DESCRIPTOR event, _In_z_ _Printf_format_string_ LPCWSTR format, ...) noexcept; 126 | 127 | #endif 128 | --------------------------------------------------------------------------------