├── .gitattributes ├── .gitignore ├── HookCoreAppWinUI.sln ├── HookCoreAppWinUI ├── HookCoreAppWinUI.vcxproj ├── HookCoreAppWinUI.vcxproj.filters └── dllmain.cpp ├── LICENSE.txt ├── README.md └── detours ├── README.md ├── include ├── detours.h └── detver.h ├── lib.ARM64 ├── detours.lib └── detours.pdb ├── lib.X64 ├── detours.lib └── detours.pdb └── lib.X86 ├── detours.lib └── detours.pdb /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.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 | [Oo]ut/ 33 | [Ll]og/ 34 | [Ll]ogs/ 35 | 36 | # Visual Studio 2015/2017 cache/options directory 37 | .vs/ 38 | # Uncomment if you have tasks that create the project's static files in wwwroot 39 | #wwwroot/ 40 | 41 | # Visual Studio 2017 auto generated files 42 | Generated\ Files/ 43 | 44 | # MSTest test Results 45 | [Tt]est[Rr]esult*/ 46 | [Bb]uild[Ll]og.* 47 | 48 | # NUnit 49 | *.VisualState.xml 50 | TestResult.xml 51 | nunit-*.xml 52 | 53 | # Build Results of an ATL Project 54 | [Dd]ebugPS/ 55 | [Rr]eleasePS/ 56 | dlldata.c 57 | 58 | # Benchmark Results 59 | BenchmarkDotNet.Artifacts/ 60 | 61 | # .NET Core 62 | project.lock.json 63 | project.fragment.lock.json 64 | artifacts/ 65 | 66 | # ASP.NET Scaffolding 67 | ScaffoldingReadMe.txt 68 | 69 | # StyleCop 70 | StyleCopReport.xml 71 | 72 | # Files built by Visual Studio 73 | *_i.c 74 | *_p.c 75 | *_h.h 76 | *.ilk 77 | *.meta 78 | *.obj 79 | *.iobj 80 | *.pch 81 | *.pdb 82 | *.ipdb 83 | *.pgc 84 | *.pgd 85 | *.rsp 86 | *.sbr 87 | *.tlb 88 | *.tli 89 | *.tlh 90 | *.tmp 91 | *.tmp_proj 92 | *_wpftmp.csproj 93 | *.log 94 | *.vspscc 95 | *.vssscc 96 | .builds 97 | *.pidb 98 | *.svclog 99 | *.scc 100 | 101 | # Chutzpah Test files 102 | _Chutzpah* 103 | 104 | # Visual C++ cache files 105 | ipch/ 106 | *.aps 107 | *.ncb 108 | *.opendb 109 | *.opensdf 110 | *.sdf 111 | *.cachefile 112 | *.VC.db 113 | *.VC.VC.opendb 114 | 115 | # Visual Studio profiler 116 | *.psess 117 | *.vsp 118 | *.vspx 119 | *.sap 120 | 121 | # Visual Studio Trace Files 122 | *.e2e 123 | 124 | # TFS 2012 Local Workspace 125 | $tf/ 126 | 127 | # Guidance Automation Toolkit 128 | *.gpState 129 | 130 | # ReSharper is a .NET coding add-in 131 | _ReSharper*/ 132 | *.[Rr]e[Ss]harper 133 | *.DotSettings.user 134 | 135 | # TeamCity is a build add-in 136 | _TeamCity* 137 | 138 | # DotCover is a Code Coverage Tool 139 | *.dotCover 140 | 141 | # AxoCover is a Code Coverage Tool 142 | .axoCover/* 143 | !.axoCover/settings.json 144 | 145 | # Coverlet is a free, cross platform Code Coverage Tool 146 | coverage*.json 147 | coverage*.xml 148 | coverage*.info 149 | 150 | # Visual Studio code coverage results 151 | *.coverage 152 | *.coveragexml 153 | 154 | # NCrunch 155 | _NCrunch_* 156 | .*crunch*.local.xml 157 | nCrunchTemp_* 158 | 159 | # MightyMoose 160 | *.mm.* 161 | AutoTest.Net/ 162 | 163 | # Web workbench (sass) 164 | .sass-cache/ 165 | 166 | # Installshield output folder 167 | [Ee]xpress/ 168 | 169 | # DocProject is a documentation generator add-in 170 | DocProject/buildhelp/ 171 | DocProject/Help/*.HxT 172 | DocProject/Help/*.HxC 173 | DocProject/Help/*.hhc 174 | DocProject/Help/*.hhk 175 | DocProject/Help/*.hhp 176 | DocProject/Help/Html2 177 | DocProject/Help/html 178 | 179 | # Click-Once directory 180 | publish/ 181 | 182 | # Publish Web Output 183 | *.[Pp]ublish.xml 184 | *.azurePubxml 185 | # Note: Comment the next line if you want to checkin your web deploy settings, 186 | # but database connection strings (with potential passwords) will be unencrypted 187 | *.pubxml 188 | *.publishproj 189 | 190 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 191 | # checkin your Azure Web App publish settings, but sensitive information contained 192 | # in these scripts will be unencrypted 193 | PublishScripts/ 194 | 195 | # NuGet Packages 196 | *.nupkg 197 | # NuGet Symbol Packages 198 | *.snupkg 199 | # The packages folder can be ignored because of Package Restore 200 | **/[Pp]ackages/* 201 | # except build/, which is used as an MSBuild target. 202 | !**/[Pp]ackages/build/ 203 | # Uncomment if necessary however generally it will be regenerated when needed 204 | #!**/[Pp]ackages/repositories.config 205 | # NuGet v3's project.json files produces more ignorable files 206 | *.nuget.props 207 | *.nuget.targets 208 | 209 | # Microsoft Azure Build Output 210 | csx/ 211 | *.build.csdef 212 | 213 | # Microsoft Azure Emulator 214 | ecf/ 215 | rcf/ 216 | 217 | # Windows Store app package directories and files 218 | AppPackages/ 219 | BundleArtifacts/ 220 | Package.StoreAssociation.xml 221 | _pkginfo.txt 222 | *.appx 223 | *.appxbundle 224 | *.appxupload 225 | 226 | # Visual Studio cache files 227 | # files ending in .cache can be ignored 228 | *.[Cc]ache 229 | # but keep track of directories ending in .cache 230 | !?*.[Cc]ache/ 231 | 232 | # Others 233 | ClientBin/ 234 | ~$* 235 | *~ 236 | *.dbmdl 237 | *.dbproj.schemaview 238 | *.jfm 239 | *.pfx 240 | *.publishsettings 241 | orleans.codegen.cs 242 | 243 | # Including strong name files can present a security risk 244 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 245 | #*.snk 246 | 247 | # Since there are multiple workflows, uncomment next line to ignore bower_components 248 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 249 | #bower_components/ 250 | 251 | # RIA/Silverlight projects 252 | Generated_Code/ 253 | 254 | # Backup & report files from converting an old project file 255 | # to a newer Visual Studio version. Backup files are not needed, 256 | # because we have git ;-) 257 | _UpgradeReport_Files/ 258 | Backup*/ 259 | UpgradeLog*.XML 260 | UpgradeLog*.htm 261 | ServiceFabricBackup/ 262 | *.rptproj.bak 263 | 264 | # SQL Server files 265 | *.mdf 266 | *.ldf 267 | *.ndf 268 | 269 | # Business Intelligence projects 270 | *.rdl.data 271 | *.bim.layout 272 | *.bim_*.settings 273 | *.rptproj.rsuser 274 | *- [Bb]ackup.rdl 275 | *- [Bb]ackup ([0-9]).rdl 276 | *- [Bb]ackup ([0-9][0-9]).rdl 277 | 278 | # Microsoft Fakes 279 | FakesAssemblies/ 280 | 281 | # GhostDoc plugin setting file 282 | *.GhostDoc.xml 283 | 284 | # Node.js Tools for Visual Studio 285 | .ntvs_analysis.dat 286 | node_modules/ 287 | 288 | # Visual Studio 6 build log 289 | *.plg 290 | 291 | # Visual Studio 6 workspace options file 292 | *.opt 293 | 294 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 295 | *.vbw 296 | 297 | # Visual Studio LightSwitch build output 298 | **/*.HTMLClient/GeneratedArtifacts 299 | **/*.DesktopClient/GeneratedArtifacts 300 | **/*.DesktopClient/ModelManifest.xml 301 | **/*.Server/GeneratedArtifacts 302 | **/*.Server/ModelManifest.xml 303 | _Pvt_Extensions 304 | 305 | # Paket dependency manager 306 | .paket/paket.exe 307 | paket-files/ 308 | 309 | # FAKE - F# Make 310 | .fake/ 311 | 312 | # CodeRush personal settings 313 | .cr/personal 314 | 315 | # Python Tools for Visual Studio (PTVS) 316 | __pycache__/ 317 | *.pyc 318 | 319 | # Cake - Uncomment if you are using it 320 | # tools/** 321 | # !tools/packages.config 322 | 323 | # Tabs Studio 324 | *.tss 325 | 326 | # Telerik's JustMock configuration file 327 | *.jmconfig 328 | 329 | # BizTalk build output 330 | *.btp.cs 331 | *.btm.cs 332 | *.odx.cs 333 | *.xsd.cs 334 | 335 | # OpenCover UI analysis results 336 | OpenCover/ 337 | 338 | # Azure Stream Analytics local run output 339 | ASALocalRun/ 340 | 341 | # MSBuild Binary and Structured Log 342 | *.binlog 343 | 344 | # NVidia Nsight GPU debugger configuration file 345 | *.nvuser 346 | 347 | # MFractors (Xamarin productivity tool) working folder 348 | .mfractor/ 349 | 350 | # Local History for Visual Studio 351 | .localhistory/ 352 | 353 | # BeatPulse healthcheck temp database 354 | healthchecksdb 355 | 356 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 357 | MigrationBackup/ 358 | 359 | # Ionide (cross platform F# VS Code tools) working folder 360 | .ionide/ 361 | 362 | # Fody - auto-generated XML schema 363 | FodyWeavers.xsd -------------------------------------------------------------------------------- /HookCoreAppWinUI.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.7.34202.233 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HookCoreAppWinUI", "HookCoreAppWinUI\HookCoreAppWinUI.vcxproj", "{33078F30-7E07-4C0B-8C0C-94001F0B4A2B}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|ARM64 = Debug|ARM64 11 | Debug|x64 = Debug|x64 12 | Debug|x86 = Debug|x86 13 | Release|ARM64 = Release|ARM64 14 | Release|x64 = Release|x64 15 | Release|x86 = Release|x86 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {33078F30-7E07-4C0B-8C0C-94001F0B4A2B}.Debug|ARM64.ActiveCfg = Debug|ARM64 19 | {33078F30-7E07-4C0B-8C0C-94001F0B4A2B}.Debug|ARM64.Build.0 = Debug|ARM64 20 | {33078F30-7E07-4C0B-8C0C-94001F0B4A2B}.Debug|x64.ActiveCfg = Debug|x64 21 | {33078F30-7E07-4C0B-8C0C-94001F0B4A2B}.Debug|x64.Build.0 = Debug|x64 22 | {33078F30-7E07-4C0B-8C0C-94001F0B4A2B}.Debug|x86.ActiveCfg = Debug|Win32 23 | {33078F30-7E07-4C0B-8C0C-94001F0B4A2B}.Debug|x86.Build.0 = Debug|Win32 24 | {33078F30-7E07-4C0B-8C0C-94001F0B4A2B}.Release|ARM64.ActiveCfg = Release|ARM64 25 | {33078F30-7E07-4C0B-8C0C-94001F0B4A2B}.Release|ARM64.Build.0 = Release|ARM64 26 | {33078F30-7E07-4C0B-8C0C-94001F0B4A2B}.Release|x64.ActiveCfg = Release|x64 27 | {33078F30-7E07-4C0B-8C0C-94001F0B4A2B}.Release|x64.Build.0 = Release|x64 28 | {33078F30-7E07-4C0B-8C0C-94001F0B4A2B}.Release|x86.ActiveCfg = Release|Win32 29 | {33078F30-7E07-4C0B-8C0C-94001F0B4A2B}.Release|x86.Build.0 = Release|Win32 30 | EndGlobalSection 31 | GlobalSection(SolutionProperties) = preSolution 32 | HideSolutionNode = FALSE 33 | EndGlobalSection 34 | GlobalSection(ExtensibilityGlobals) = postSolution 35 | SolutionGuid = {722C0B3F-B528-4E2F-BC4C-FC4AE9F15848} 36 | EndGlobalSection 37 | EndGlobal 38 | -------------------------------------------------------------------------------- /HookCoreAppWinUI/HookCoreAppWinUI.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | ARM64 7 | 8 | 9 | Debug 10 | Win32 11 | 12 | 13 | Release 14 | ARM64 15 | 16 | 17 | Release 18 | Win32 19 | 20 | 21 | Debug 22 | x64 23 | 24 | 25 | Release 26 | x64 27 | 28 | 29 | 30 | 17.0 31 | Win32Proj 32 | {33078f30-7e07-4c0b-8c0c-94001f0b4a2b} 33 | HookCoreAppWinUI 34 | 10.0 35 | 36 | 37 | 38 | DynamicLibrary 39 | true 40 | v143 41 | Unicode 42 | 43 | 44 | DynamicLibrary 45 | false 46 | v143 47 | true 48 | Unicode 49 | 50 | 51 | DynamicLibrary 52 | true 53 | v143 54 | Unicode 55 | 56 | 57 | DynamicLibrary 58 | true 59 | v143 60 | Unicode 61 | 62 | 63 | DynamicLibrary 64 | false 65 | v143 66 | true 67 | Unicode 68 | 69 | 70 | DynamicLibrary 71 | false 72 | v143 73 | true 74 | Unicode 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | Level3 103 | true 104 | WIN32;_DEBUG;HOOKCOREAPPWINUI_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 105 | true 106 | NotUsing 107 | pch.h 108 | 109 | 110 | Windows 111 | true 112 | false 113 | 114 | 115 | 116 | 117 | Level3 118 | true 119 | true 120 | true 121 | WIN32;NDEBUG;HOOKCOREAPPWINUI_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 122 | true 123 | NotUsing 124 | pch.h 125 | 126 | 127 | Windows 128 | true 129 | true 130 | true 131 | false 132 | 133 | 134 | 135 | 136 | Level3 137 | true 138 | _DEBUG;HOOKCOREAPPWINUI_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 139 | true 140 | NotUsing 141 | pch.h 142 | 143 | 144 | Windows 145 | true 146 | false 147 | 148 | 149 | 150 | 151 | Level3 152 | true 153 | _DEBUG;HOOKCOREAPPWINUI_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 154 | true 155 | NotUsing 156 | pch.h 157 | 158 | 159 | Windows 160 | true 161 | false 162 | 163 | 164 | 165 | 166 | Level3 167 | true 168 | true 169 | true 170 | NDEBUG;HOOKCOREAPPWINUI_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 171 | true 172 | NotUsing 173 | pch.h 174 | 175 | 176 | Windows 177 | true 178 | true 179 | true 180 | false 181 | 182 | 183 | 184 | 185 | Level3 186 | true 187 | true 188 | true 189 | NDEBUG;HOOKCOREAPPWINUI_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 190 | true 191 | NotUsing 192 | pch.h 193 | 194 | 195 | Windows 196 | true 197 | true 198 | true 199 | false 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | -------------------------------------------------------------------------------- /HookCoreAppWinUI/HookCoreAppWinUI.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 | 源文件 20 | 21 | 22 | -------------------------------------------------------------------------------- /HookCoreAppWinUI/dllmain.cpp: -------------------------------------------------------------------------------- 1 | #define WIN32_LEAN_AND_MEAN 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "../detours/include/detours.h" 8 | 9 | #if defined(_M_AMD64) 10 | #pragma comment(lib, "../detours/lib.X64/detours.lib") 11 | #elif defined(_M_ARM64) 12 | #pragma comment(lib, "../detours/lib.ARM64/detours.lib") 13 | #elif defined(_M_IX86) 14 | #pragma comment(lib, "../detours/lib.X86/detours.lib") 15 | #endif 16 | 17 | std::mutex xamlKeyMtx; 18 | std::map xamlKeyMap; 19 | 20 | LSTATUS(APIENTRY* oldRegOpenKeyExW)(HKEY, LPCWSTR, DWORD, REGSAM, PHKEY) = RegOpenKeyExW; 21 | LSTATUS APIENTRY NewRegOpenKeyExW(HKEY hkey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult) 22 | { 23 | LSTATUS result = oldRegOpenKeyExW(hkey, lpSubKey, ulOptions, samDesired, phkResult); 24 | 25 | if (hkey == HKEY_LOCAL_MACHINE && !_wcsicmp(lpSubKey, L"Software\\Microsoft\\WinUI\\XAML")) 26 | { 27 | std::lock_guard lock(xamlKeyMtx); 28 | if (result == ERROR_FILE_NOT_FOUND) 29 | { 30 | xamlKeyMap.emplace((HKEY)INVALID_HANDLE_VALUE, false); 31 | *phkResult = (HKEY)INVALID_HANDLE_VALUE; 32 | result = ERROR_SUCCESS; 33 | } 34 | else if (result == ERROR_SUCCESS) 35 | { 36 | xamlKeyMap.emplace(*phkResult, true); 37 | } 38 | } 39 | return result; 40 | } 41 | 42 | LSTATUS(APIENTRY* oldRegCloseKey)(HKEY hKey) = RegCloseKey; 43 | LSTATUS APIENTRY NewRegCloseKey(HKEY hKey) 44 | { 45 | bool isXamlKey; 46 | bool isRealKey = false; 47 | { 48 | std::lock_guard lock(xamlKeyMtx); 49 | auto pos = xamlKeyMap.find(hKey); 50 | isXamlKey = pos != xamlKeyMap.end(); 51 | if (isXamlKey) 52 | { 53 | isRealKey = pos->second; 54 | xamlKeyMap.erase(pos); 55 | } 56 | } 57 | 58 | LSTATUS result; 59 | if (isXamlKey) 60 | { 61 | if (isRealKey) 62 | { 63 | // real key 64 | result = oldRegCloseKey(hKey); 65 | } 66 | else 67 | { 68 | // simulated key 69 | result = ERROR_SUCCESS; 70 | } 71 | } 72 | else 73 | { 74 | if (hKey == INVALID_HANDLE_VALUE) 75 | { 76 | result = ERROR_INVALID_HANDLE; 77 | } 78 | else 79 | { 80 | result = oldRegCloseKey(hKey); 81 | } 82 | 83 | } 84 | return result; 85 | } 86 | 87 | LSTATUS(APIENTRY* oldRegQueryValueExW)(HKEY hKey, LPCWSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData) = RegQueryValueExW; 88 | LSTATUS APIENTRY NewRegQueryValueExW(HKEY hKey, LPCWSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData) 89 | { 90 | LSTATUS result; 91 | if (lpValueName != NULL && !_wcsicmp(lpValueName, L"EnableUWPWindow")) 92 | { 93 | bool isXamlKey; 94 | bool isRealKey = false; 95 | { 96 | std::lock_guard lock(xamlKeyMtx); 97 | auto pos = xamlKeyMap.find(hKey); 98 | isXamlKey = pos != xamlKeyMap.end(); 99 | if (isXamlKey) 100 | { 101 | isRealKey = pos->second; 102 | } 103 | } 104 | 105 | if (isXamlKey) 106 | { 107 | if (isRealKey) 108 | { 109 | // real key 110 | result = oldRegQueryValueExW(hKey, lpValueName, lpReserved, lpType, lpData, lpcbData); 111 | if (result == ERROR_SUCCESS && lpData != NULL) 112 | { 113 | *lpData = 1; 114 | } 115 | else if (result == ERROR_FILE_NOT_FOUND) 116 | { 117 | if (lpData == NULL && lpcbData != NULL) 118 | { 119 | *lpcbData = sizeof(DWORD); 120 | result = ERROR_SUCCESS; 121 | } 122 | else if (lpData != NULL && lpcbData != NULL) 123 | { 124 | if (*lpcbData >= sizeof(DWORD)) 125 | { 126 | *lpData = 1; 127 | result = ERROR_SUCCESS; 128 | } 129 | else 130 | { 131 | result = ERROR_MORE_DATA; 132 | } 133 | } 134 | } 135 | } 136 | else 137 | { 138 | // simulated key 139 | result = ERROR_FILE_NOT_FOUND; 140 | if (lpData == NULL && lpcbData != NULL) 141 | { 142 | *lpcbData = sizeof(DWORD); 143 | result = ERROR_SUCCESS; 144 | } 145 | else if (lpData != NULL && lpcbData != NULL) 146 | { 147 | if (*lpcbData >= sizeof(DWORD)) 148 | { 149 | *lpData = 1; 150 | result = ERROR_SUCCESS; 151 | } 152 | else 153 | { 154 | result = ERROR_MORE_DATA; 155 | } 156 | } 157 | } 158 | } 159 | else 160 | { 161 | result = oldRegQueryValueExW(hKey, lpValueName, lpReserved, lpType, lpData, lpcbData); 162 | } 163 | } 164 | else 165 | { 166 | result = oldRegQueryValueExW(hKey, lpValueName, lpReserved, lpType, lpData, lpcbData); 167 | } 168 | return result; 169 | } 170 | 171 | void StartHook() 172 | { 173 | OutputDebugStringW(L"StartHook\n"); 174 | DetourTransactionBegin(); 175 | DetourUpdateThread(GetCurrentThread()); 176 | DetourAttach((PVOID*)&oldRegOpenKeyExW, NewRegOpenKeyExW); 177 | DetourAttach((PVOID*)&oldRegCloseKey, NewRegCloseKey); 178 | DetourAttach((PVOID*)&oldRegQueryValueExW, NewRegQueryValueExW); 179 | DetourTransactionCommit(); 180 | } 181 | 182 | void EndHook() 183 | { 184 | OutputDebugStringW(L"EndHook\n"); 185 | DetourTransactionBegin(); 186 | DetourUpdateThread(GetCurrentThread()); 187 | DetourDetach((PVOID*)&oldRegOpenKeyExW, NewRegOpenKeyExW); 188 | DetourDetach((PVOID*)&oldRegCloseKey, NewRegCloseKey); 189 | DetourDetach((PVOID*)&oldRegQueryValueExW, NewRegQueryValueExW); 190 | DetourTransactionCommit(); 191 | } 192 | 193 | 194 | BOOL APIENTRY DllMain(HMODULE hModule, 195 | DWORD ul_reason_for_call, 196 | LPVOID lpReserved 197 | ) 198 | { 199 | switch (ul_reason_for_call) 200 | { 201 | case DLL_PROCESS_ATTACH: 202 | break; 203 | case DLL_THREAD_ATTACH: 204 | StartHook(); 205 | break; 206 | case DLL_THREAD_DETACH: 207 | EndHook(); 208 | break; 209 | case DLL_PROCESS_DETACH: 210 | break; 211 | } 212 | return TRUE; 213 | } 214 | 215 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 driver1998 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # HookCoreAppWinUI 2 | 3 | This is a hacky hook to allow WinUI 3 to run in UWP environment. 4 | 5 | ## Disclaimer 6 | 7 | Windows App SDK and WinUI 3 are **NOT SUPPORTED** in UWP, this is just a fun science project expoliting an old workaround method, you should **NEVER EVER USE IT IN PRODUCTION ENVIRONMENT**. 8 | 9 | Also this is my first ever API hook, it might contain some bone-headed mistakes, **USE IT AT YOUR OWN RISK**. While you are at it, review the code, it isn't long ;-). 10 | 11 | ## How to use 12 | 13 | Windows App SDK version 1.4.2 is tested. 14 | 15 | You'll need to write your own entrypoint (`main` method). As the auto-generated one will not work in UWP. Namely, you'll need to use `MTAThread` instead of `STAThread`. 16 | 17 | Then, just load this dll before `Microsoft.UI.Xaml.Application.Start`, like this: 18 | 19 | ```csharp 20 | public static class Program 21 | { 22 | [DllImport("Microsoft.ui.xaml.dll")] 23 | private static extern void XamlCheckProcessRequirements(); 24 | 25 | [DllImport("api-ms-win-core-libraryloader-l2-1-0.dll", SetLastError = true)] 26 | private static extern IntPtr LoadPackagedLibrary([MarshalAs(UnmanagedType.LPWStr)] string libraryName, int reserved = 0); 27 | 28 | [global::System.MTAThread] 29 | static void Main(string[] args) 30 | { 31 | // Enable the hook here 32 | LoadPackagedLibrary("HookCoreAppWinUI.dll"); 33 | 34 | XamlCheckProcessRequirements(); 35 | 36 | // Do your normal WinUI 3 initialization 37 | WinRT.ComWrappersSupport.InitializeComWrappers(); 38 | Microsoft.UI.Xaml.Application.Start( 39 | // ... 40 | ); 41 | } 42 | } 43 | ``` 44 | 45 | While we are at it, define `DISABLE_XAML_GENERATED_MAIN` in the project file so it won't generate its own `main`: 46 | ```xml 47 | 48 | 49 | 50 | $(SamplesTargetFrameworkMoniker) 51 | 10.0.17763.0 52 | WinExe 53 | true 54 | 55 | DISABLE_XAML_GENERATED_MAIN 56 | 57 | 58 | ``` 59 | 60 | Lastly, update `Package.appxmanifest` and use a fixed entrypoint (if you keep it as is it will be `Windows.FullTrustApplication` which means an full-trust Win32 app). 61 | 62 | It should be your `App` class. 63 | 64 | ```xml 65 | 66 | 67 | 68 | 69 | ``` 70 | 71 | Also remove the `runFullTrust` capability, and add whatever you need. 72 | 73 | Now you should be able to build, deploy and run your WinUI 3 UWP app. -------------------------------------------------------------------------------- /detours/README.md: -------------------------------------------------------------------------------- 1 | # Detours binaries 2 | 3 | Built from https://github.com/microsoft/Detours/commit/4b8c659f549b0ab21cf649377c7a84eb708f5e68. -------------------------------------------------------------------------------- /detours/include/detours.h: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Core Detours Functionality (detours.h of detours.lib) 4 | // 5 | // Microsoft Research Detours Package, Version 4.0.1 6 | // 7 | // Copyright (c) Microsoft Corporation. All rights reserved. 8 | // 9 | 10 | #pragma once 11 | #ifndef _DETOURS_H_ 12 | #define _DETOURS_H_ 13 | 14 | #define DETOURS_VERSION 0x4c0c1 // 0xMAJORcMINORcPATCH 15 | 16 | ////////////////////////////////////////////////////////////////////////////// 17 | // 18 | 19 | #ifdef DETOURS_INTERNAL 20 | 21 | #define _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS 1 22 | #define _ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE 1 23 | 24 | #pragma warning(disable:4068) // unknown pragma (suppress) 25 | 26 | #if _MSC_VER >= 1900 27 | #pragma warning(push) 28 | #pragma warning(disable:4091) // empty typedef 29 | #endif 30 | 31 | // Suppress declspec(dllimport) for the sake of Detours 32 | // users that provide kernel32 functionality themselves. 33 | // This is ok in the mainstream case, it will just cost 34 | // an extra instruction calling some functions, which 35 | // LTCG optimizes away. 36 | // 37 | #define _KERNEL32_ 1 38 | #define _USER32_ 1 39 | 40 | #include 41 | #if (_MSC_VER < 1310) 42 | #else 43 | #pragma warning(push) 44 | #if _MSC_VER > 1400 45 | #pragma warning(disable:6102 6103) // /analyze warnings 46 | #endif 47 | #include 48 | #include 49 | #pragma warning(pop) 50 | #endif 51 | #include 52 | 53 | // Allow Detours to cleanly compile with the MingW toolchain. 54 | // 55 | #ifdef __GNUC__ 56 | #define __try 57 | #define __except(x) if (0) 58 | #include 59 | #include 60 | #endif 61 | 62 | // From winerror.h, as this error isn't found in some SDKs: 63 | // 64 | // MessageId: ERROR_DYNAMIC_CODE_BLOCKED 65 | // 66 | // MessageText: 67 | // 68 | // The operation was blocked as the process prohibits dynamic code generation. 69 | // 70 | #define ERROR_DYNAMIC_CODE_BLOCKED 1655L 71 | 72 | #endif // DETOURS_INTERNAL 73 | 74 | ////////////////////////////////////////////////////////////////////////////// 75 | // 76 | 77 | #undef DETOURS_X64 78 | #undef DETOURS_X86 79 | #undef DETOURS_IA64 80 | #undef DETOURS_ARM 81 | #undef DETOURS_ARM64 82 | #undef DETOURS_BITS 83 | #undef DETOURS_32BIT 84 | #undef DETOURS_64BIT 85 | 86 | #if defined(_X86_) 87 | #define DETOURS_X86 88 | #define DETOURS_OPTION_BITS 64 89 | 90 | #elif defined(_AMD64_) 91 | #define DETOURS_X64 92 | #define DETOURS_OPTION_BITS 32 93 | 94 | #elif defined(_IA64_) 95 | #define DETOURS_IA64 96 | #define DETOURS_OPTION_BITS 32 97 | 98 | #elif defined(_ARM_) 99 | #define DETOURS_ARM 100 | 101 | #elif defined(_ARM64_) 102 | #define DETOURS_ARM64 103 | 104 | #else 105 | #error Unknown architecture (x86, amd64, ia64, arm, arm64) 106 | #endif 107 | 108 | #ifdef _WIN64 109 | #undef DETOURS_32BIT 110 | #define DETOURS_64BIT 1 111 | #define DETOURS_BITS 64 112 | // If all 64bit kernels can run one and only one 32bit architecture. 113 | //#define DETOURS_OPTION_BITS 32 114 | #else 115 | #define DETOURS_32BIT 1 116 | #undef DETOURS_64BIT 117 | #define DETOURS_BITS 32 118 | // If all 64bit kernels can run one and only one 32bit architecture. 119 | //#define DETOURS_OPTION_BITS 32 120 | #endif 121 | 122 | /////////////////////////////////////////////////////////////// Helper Macros. 123 | // 124 | #define DETOURS_STRINGIFY_(x) #x 125 | #define DETOURS_STRINGIFY(x) DETOURS_STRINGIFY_(x) 126 | 127 | #define VER_DETOURS_BITS DETOURS_STRINGIFY(DETOURS_BITS) 128 | 129 | ////////////////////////////////////////////////////////////////////////////// 130 | // 131 | 132 | #if (_MSC_VER < 1299) && !defined(__MINGW32__) 133 | typedef LONG LONG_PTR; 134 | typedef ULONG ULONG_PTR; 135 | #endif 136 | 137 | ///////////////////////////////////////////////// SAL 2.0 Annotations w/o SAL. 138 | // 139 | // These definitions are include so that Detours will build even if the 140 | // compiler doesn't have full SAL 2.0 support. 141 | // 142 | #ifndef DETOURS_DONT_REMOVE_SAL_20 143 | 144 | #ifdef DETOURS_TEST_REMOVE_SAL_20 145 | #undef _Analysis_assume_ 146 | #undef _Benign_race_begin_ 147 | #undef _Benign_race_end_ 148 | #undef _Field_range_ 149 | #undef _Field_size_ 150 | #undef _In_ 151 | #undef _In_bytecount_ 152 | #undef _In_count_ 153 | #undef __in_ecount 154 | #undef _In_opt_ 155 | #undef _In_opt_bytecount_ 156 | #undef _In_opt_count_ 157 | #undef _In_opt_z_ 158 | #undef _In_range_ 159 | #undef _In_reads_ 160 | #undef _In_reads_bytes_ 161 | #undef _In_reads_opt_ 162 | #undef _In_reads_opt_bytes_ 163 | #undef _In_reads_or_z_ 164 | #undef _In_z_ 165 | #undef _Inout_ 166 | #undef _Inout_opt_ 167 | #undef _Inout_z_count_ 168 | #undef _Out_ 169 | #undef _Out_opt_ 170 | #undef _Out_writes_ 171 | #undef _Outptr_result_maybenull_ 172 | #undef _Readable_bytes_ 173 | #undef _Success_ 174 | #undef _Writable_bytes_ 175 | #undef _Pre_notnull_ 176 | #endif 177 | 178 | #if defined(_Deref_out_opt_z_) && !defined(_Outptr_result_maybenull_) 179 | #define _Outptr_result_maybenull_ _Deref_out_opt_z_ 180 | #endif 181 | 182 | #if defined(_In_count_) && !defined(_In_reads_) 183 | #define _In_reads_(x) _In_count_(x) 184 | #endif 185 | 186 | #if defined(_In_opt_count_) && !defined(_In_reads_opt_) 187 | #define _In_reads_opt_(x) _In_opt_count_(x) 188 | #endif 189 | 190 | #if defined(_In_opt_bytecount_) && !defined(_In_reads_opt_bytes_) 191 | #define _In_reads_opt_bytes_(x) _In_opt_bytecount_(x) 192 | #endif 193 | 194 | #if defined(_In_bytecount_) && !defined(_In_reads_bytes_) 195 | #define _In_reads_bytes_(x) _In_bytecount_(x) 196 | #endif 197 | 198 | #ifndef _In_ 199 | #define _In_ 200 | #endif 201 | 202 | #ifndef _In_bytecount_ 203 | #define _In_bytecount_(x) 204 | #endif 205 | 206 | #ifndef _In_count_ 207 | #define _In_count_(x) 208 | #endif 209 | 210 | #ifndef __in_ecount 211 | #define __in_ecount(x) 212 | #endif 213 | 214 | #ifndef _In_opt_ 215 | #define _In_opt_ 216 | #endif 217 | 218 | #ifndef _In_opt_bytecount_ 219 | #define _In_opt_bytecount_(x) 220 | #endif 221 | 222 | #ifndef _In_opt_count_ 223 | #define _In_opt_count_(x) 224 | #endif 225 | 226 | #ifndef _In_opt_z_ 227 | #define _In_opt_z_ 228 | #endif 229 | 230 | #ifndef _In_range_ 231 | #define _In_range_(x,y) 232 | #endif 233 | 234 | #ifndef _In_reads_ 235 | #define _In_reads_(x) 236 | #endif 237 | 238 | #ifndef _In_reads_bytes_ 239 | #define _In_reads_bytes_(x) 240 | #endif 241 | 242 | #ifndef _In_reads_opt_ 243 | #define _In_reads_opt_(x) 244 | #endif 245 | 246 | #ifndef _In_reads_opt_bytes_ 247 | #define _In_reads_opt_bytes_(x) 248 | #endif 249 | 250 | #ifndef _In_reads_or_z_ 251 | #define _In_reads_or_z_ 252 | #endif 253 | 254 | #ifndef _In_z_ 255 | #define _In_z_ 256 | #endif 257 | 258 | #ifndef _Inout_ 259 | #define _Inout_ 260 | #endif 261 | 262 | #ifndef _Inout_opt_ 263 | #define _Inout_opt_ 264 | #endif 265 | 266 | #ifndef _Inout_z_count_ 267 | #define _Inout_z_count_(x) 268 | #endif 269 | 270 | #ifndef _Out_ 271 | #define _Out_ 272 | #endif 273 | 274 | #ifndef _Out_opt_ 275 | #define _Out_opt_ 276 | #endif 277 | 278 | #ifndef _Out_writes_ 279 | #define _Out_writes_(x) 280 | #endif 281 | 282 | #ifndef _Outptr_result_maybenull_ 283 | #define _Outptr_result_maybenull_ 284 | #endif 285 | 286 | #ifndef _Writable_bytes_ 287 | #define _Writable_bytes_(x) 288 | #endif 289 | 290 | #ifndef _Readable_bytes_ 291 | #define _Readable_bytes_(x) 292 | #endif 293 | 294 | #ifndef _Success_ 295 | #define _Success_(x) 296 | #endif 297 | 298 | #ifndef _Pre_notnull_ 299 | #define _Pre_notnull_ 300 | #endif 301 | 302 | #ifdef DETOURS_INTERNAL 303 | 304 | #pragma warning(disable:4615) // unknown warning type (suppress with older compilers) 305 | 306 | #ifndef _Benign_race_begin_ 307 | #define _Benign_race_begin_ 308 | #endif 309 | 310 | #ifndef _Benign_race_end_ 311 | #define _Benign_race_end_ 312 | #endif 313 | 314 | #ifndef _Field_size_ 315 | #define _Field_size_(x) 316 | #endif 317 | 318 | #ifndef _Field_range_ 319 | #define _Field_range_(x,y) 320 | #endif 321 | 322 | #ifndef _Analysis_assume_ 323 | #define _Analysis_assume_(x) 324 | #endif 325 | 326 | #endif // DETOURS_INTERNAL 327 | #endif // DETOURS_DONT_REMOVE_SAL_20 328 | 329 | ////////////////////////////////////////////////////////////////////////////// 330 | // 331 | #ifndef GUID_DEFINED 332 | #define GUID_DEFINED 333 | typedef struct _GUID 334 | { 335 | DWORD Data1; 336 | WORD Data2; 337 | WORD Data3; 338 | BYTE Data4[ 8 ]; 339 | } GUID; 340 | 341 | #ifdef INITGUID 342 | #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ 343 | const GUID name \ 344 | = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } 345 | #else 346 | #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ 347 | const GUID name 348 | #endif // INITGUID 349 | #endif // !GUID_DEFINED 350 | 351 | #if defined(__cplusplus) 352 | #ifndef _REFGUID_DEFINED 353 | #define _REFGUID_DEFINED 354 | #define REFGUID const GUID & 355 | #endif // !_REFGUID_DEFINED 356 | #else // !__cplusplus 357 | #ifndef _REFGUID_DEFINED 358 | #define _REFGUID_DEFINED 359 | #define REFGUID const GUID * const 360 | #endif // !_REFGUID_DEFINED 361 | #endif // !__cplusplus 362 | 363 | #ifndef ARRAYSIZE 364 | #define ARRAYSIZE(x) (sizeof(x)/sizeof(x[0])) 365 | #endif 366 | 367 | // 368 | ////////////////////////////////////////////////////////////////////////////// 369 | 370 | #ifdef __cplusplus 371 | extern "C" { 372 | #endif // __cplusplus 373 | 374 | /////////////////////////////////////////////////// Instruction Target Macros. 375 | // 376 | #define DETOUR_INSTRUCTION_TARGET_NONE ((PVOID)0) 377 | #define DETOUR_INSTRUCTION_TARGET_DYNAMIC ((PVOID)(LONG_PTR)-1) 378 | #define DETOUR_SECTION_HEADER_SIGNATURE 0x00727444 // "Dtr\0" 379 | 380 | extern const GUID DETOUR_EXE_RESTORE_GUID; 381 | extern const GUID DETOUR_EXE_HELPER_GUID; 382 | 383 | #define DETOUR_TRAMPOLINE_SIGNATURE 0x21727444 // Dtr! 384 | typedef struct _DETOUR_TRAMPOLINE DETOUR_TRAMPOLINE, *PDETOUR_TRAMPOLINE; 385 | 386 | #ifndef DETOUR_MAX_SUPPORTED_IMAGE_SECTION_HEADERS 387 | #define DETOUR_MAX_SUPPORTED_IMAGE_SECTION_HEADERS 32 388 | #endif // !DETOUR_MAX_SUPPORTED_IMAGE_SECTION_HEADERS 389 | 390 | /////////////////////////////////////////////////////////// Binary Structures. 391 | // 392 | #pragma pack(push, 8) 393 | typedef struct _DETOUR_SECTION_HEADER 394 | { 395 | DWORD cbHeaderSize; 396 | DWORD nSignature; 397 | DWORD nDataOffset; 398 | DWORD cbDataSize; 399 | 400 | DWORD nOriginalImportVirtualAddress; 401 | DWORD nOriginalImportSize; 402 | DWORD nOriginalBoundImportVirtualAddress; 403 | DWORD nOriginalBoundImportSize; 404 | 405 | DWORD nOriginalIatVirtualAddress; 406 | DWORD nOriginalIatSize; 407 | DWORD nOriginalSizeOfImage; 408 | DWORD cbPrePE; 409 | 410 | DWORD nOriginalClrFlags; 411 | DWORD reserved1; 412 | DWORD reserved2; 413 | DWORD reserved3; 414 | 415 | // Followed by cbPrePE bytes of data. 416 | } DETOUR_SECTION_HEADER, *PDETOUR_SECTION_HEADER; 417 | 418 | typedef struct _DETOUR_SECTION_RECORD 419 | { 420 | DWORD cbBytes; 421 | DWORD nReserved; 422 | GUID guid; 423 | } DETOUR_SECTION_RECORD, *PDETOUR_SECTION_RECORD; 424 | 425 | typedef struct _DETOUR_CLR_HEADER 426 | { 427 | // Header versioning 428 | ULONG cb; 429 | USHORT MajorRuntimeVersion; 430 | USHORT MinorRuntimeVersion; 431 | 432 | // Symbol table and startup information 433 | IMAGE_DATA_DIRECTORY MetaData; 434 | ULONG Flags; 435 | 436 | // Followed by the rest of the IMAGE_COR20_HEADER 437 | } DETOUR_CLR_HEADER, *PDETOUR_CLR_HEADER; 438 | 439 | typedef struct _DETOUR_EXE_RESTORE 440 | { 441 | DWORD cb; 442 | DWORD cbidh; 443 | DWORD cbinh; 444 | DWORD cbclr; 445 | 446 | PBYTE pidh; 447 | PBYTE pinh; 448 | PBYTE pclr; 449 | 450 | IMAGE_DOS_HEADER idh; 451 | union { 452 | IMAGE_NT_HEADERS inh; // all environments have this 453 | #ifdef IMAGE_NT_OPTIONAL_HDR32_MAGIC // some environments do not have this 454 | IMAGE_NT_HEADERS32 inh32; 455 | #endif 456 | #ifdef IMAGE_NT_OPTIONAL_HDR64_MAGIC // some environments do not have this 457 | IMAGE_NT_HEADERS64 inh64; 458 | #endif 459 | #ifdef IMAGE_NT_OPTIONAL_HDR64_MAGIC // some environments do not have this 460 | BYTE raw[sizeof(IMAGE_NT_HEADERS64) + 461 | sizeof(IMAGE_SECTION_HEADER) * DETOUR_MAX_SUPPORTED_IMAGE_SECTION_HEADERS]; 462 | #else 463 | BYTE raw[0x108 + sizeof(IMAGE_SECTION_HEADER) * DETOUR_MAX_SUPPORTED_IMAGE_SECTION_HEADERS]; 464 | #endif 465 | }; 466 | DETOUR_CLR_HEADER clr; 467 | 468 | } DETOUR_EXE_RESTORE, *PDETOUR_EXE_RESTORE; 469 | 470 | #ifdef IMAGE_NT_OPTIONAL_HDR64_MAGIC 471 | C_ASSERT(sizeof(IMAGE_NT_HEADERS64) == 0x108); 472 | #endif 473 | 474 | // The size can change, but assert for clarity due to the muddying #ifdefs. 475 | #ifdef _WIN64 476 | C_ASSERT(sizeof(DETOUR_EXE_RESTORE) == 0x688); 477 | #else 478 | C_ASSERT(sizeof(DETOUR_EXE_RESTORE) == 0x678); 479 | #endif 480 | 481 | typedef struct _DETOUR_EXE_HELPER 482 | { 483 | DWORD cb; 484 | DWORD pid; 485 | DWORD nDlls; 486 | CHAR rDlls[4]; 487 | } DETOUR_EXE_HELPER, *PDETOUR_EXE_HELPER; 488 | 489 | #pragma pack(pop) 490 | 491 | #define DETOUR_SECTION_HEADER_DECLARE(cbSectionSize) \ 492 | { \ 493 | sizeof(DETOUR_SECTION_HEADER),\ 494 | DETOUR_SECTION_HEADER_SIGNATURE,\ 495 | sizeof(DETOUR_SECTION_HEADER),\ 496 | (cbSectionSize),\ 497 | \ 498 | 0,\ 499 | 0,\ 500 | 0,\ 501 | 0,\ 502 | \ 503 | 0,\ 504 | 0,\ 505 | 0,\ 506 | 0,\ 507 | } 508 | 509 | ///////////////////////////////////////////////////////////// Binary Typedefs. 510 | // 511 | typedef BOOL (CALLBACK *PF_DETOUR_BINARY_BYWAY_CALLBACK)( 512 | _In_opt_ PVOID pContext, 513 | _In_opt_ LPCSTR pszFile, 514 | _Outptr_result_maybenull_ LPCSTR *ppszOutFile); 515 | 516 | typedef BOOL (CALLBACK *PF_DETOUR_BINARY_FILE_CALLBACK)( 517 | _In_opt_ PVOID pContext, 518 | _In_ LPCSTR pszOrigFile, 519 | _In_ LPCSTR pszFile, 520 | _Outptr_result_maybenull_ LPCSTR *ppszOutFile); 521 | 522 | typedef BOOL (CALLBACK *PF_DETOUR_BINARY_SYMBOL_CALLBACK)( 523 | _In_opt_ PVOID pContext, 524 | _In_ ULONG nOrigOrdinal, 525 | _In_ ULONG nOrdinal, 526 | _Out_ ULONG *pnOutOrdinal, 527 | _In_opt_ LPCSTR pszOrigSymbol, 528 | _In_opt_ LPCSTR pszSymbol, 529 | _Outptr_result_maybenull_ LPCSTR *ppszOutSymbol); 530 | 531 | typedef BOOL (CALLBACK *PF_DETOUR_BINARY_COMMIT_CALLBACK)( 532 | _In_opt_ PVOID pContext); 533 | 534 | typedef BOOL (CALLBACK *PF_DETOUR_ENUMERATE_EXPORT_CALLBACK)(_In_opt_ PVOID pContext, 535 | _In_ ULONG nOrdinal, 536 | _In_opt_ LPCSTR pszName, 537 | _In_opt_ PVOID pCode); 538 | 539 | typedef BOOL (CALLBACK *PF_DETOUR_IMPORT_FILE_CALLBACK)(_In_opt_ PVOID pContext, 540 | _In_opt_ HMODULE hModule, 541 | _In_opt_ LPCSTR pszFile); 542 | 543 | typedef BOOL (CALLBACK *PF_DETOUR_IMPORT_FUNC_CALLBACK)(_In_opt_ PVOID pContext, 544 | _In_ DWORD nOrdinal, 545 | _In_opt_ LPCSTR pszFunc, 546 | _In_opt_ PVOID pvFunc); 547 | 548 | // Same as PF_DETOUR_IMPORT_FUNC_CALLBACK but extra indirection on last parameter. 549 | typedef BOOL (CALLBACK *PF_DETOUR_IMPORT_FUNC_CALLBACK_EX)(_In_opt_ PVOID pContext, 550 | _In_ DWORD nOrdinal, 551 | _In_opt_ LPCSTR pszFunc, 552 | _In_opt_ PVOID* ppvFunc); 553 | 554 | typedef VOID * PDETOUR_BINARY; 555 | typedef VOID * PDETOUR_LOADED_BINARY; 556 | 557 | //////////////////////////////////////////////////////////// Transaction APIs. 558 | // 559 | LONG WINAPI DetourTransactionBegin(VOID); 560 | LONG WINAPI DetourTransactionAbort(VOID); 561 | LONG WINAPI DetourTransactionCommit(VOID); 562 | LONG WINAPI DetourTransactionCommitEx(_Out_opt_ PVOID **pppFailedPointer); 563 | 564 | LONG WINAPI DetourUpdateThread(_In_ HANDLE hThread); 565 | 566 | LONG WINAPI DetourAttach(_Inout_ PVOID *ppPointer, 567 | _In_ PVOID pDetour); 568 | 569 | LONG WINAPI DetourAttachEx(_Inout_ PVOID *ppPointer, 570 | _In_ PVOID pDetour, 571 | _Out_opt_ PDETOUR_TRAMPOLINE *ppRealTrampoline, 572 | _Out_opt_ PVOID *ppRealTarget, 573 | _Out_opt_ PVOID *ppRealDetour); 574 | 575 | LONG WINAPI DetourDetach(_Inout_ PVOID *ppPointer, 576 | _In_ PVOID pDetour); 577 | 578 | BOOL WINAPI DetourSetIgnoreTooSmall(_In_ BOOL fIgnore); 579 | BOOL WINAPI DetourSetRetainRegions(_In_ BOOL fRetain); 580 | PVOID WINAPI DetourSetSystemRegionLowerBound(_In_ PVOID pSystemRegionLowerBound); 581 | PVOID WINAPI DetourSetSystemRegionUpperBound(_In_ PVOID pSystemRegionUpperBound); 582 | 583 | ////////////////////////////////////////////////////////////// Code Functions. 584 | // 585 | PVOID WINAPI DetourFindFunction(_In_ LPCSTR pszModule, 586 | _In_ LPCSTR pszFunction); 587 | PVOID WINAPI DetourCodeFromPointer(_In_ PVOID pPointer, 588 | _Out_opt_ PVOID *ppGlobals); 589 | PVOID WINAPI DetourCopyInstruction(_In_opt_ PVOID pDst, 590 | _Inout_opt_ PVOID *ppDstPool, 591 | _In_ PVOID pSrc, 592 | _Out_opt_ PVOID *ppTarget, 593 | _Out_opt_ LONG *plExtra); 594 | BOOL WINAPI DetourSetCodeModule(_In_ HMODULE hModule, 595 | _In_ BOOL fLimitReferencesToModule); 596 | PVOID WINAPI DetourAllocateRegionWithinJumpBounds(_In_ LPCVOID pbTarget, 597 | _Out_ PDWORD pcbAllocatedSize); 598 | BOOL WINAPI DetourIsFunctionImported(_In_ PBYTE pbCode, 599 | _In_ PBYTE pbAddress); 600 | 601 | ///////////////////////////////////////////////////// Loaded Binary Functions. 602 | // 603 | HMODULE WINAPI DetourGetContainingModule(_In_ PVOID pvAddr); 604 | HMODULE WINAPI DetourEnumerateModules(_In_opt_ HMODULE hModuleLast); 605 | PVOID WINAPI DetourGetEntryPoint(_In_opt_ HMODULE hModule); 606 | ULONG WINAPI DetourGetModuleSize(_In_opt_ HMODULE hModule); 607 | BOOL WINAPI DetourEnumerateExports(_In_ HMODULE hModule, 608 | _In_opt_ PVOID pContext, 609 | _In_ PF_DETOUR_ENUMERATE_EXPORT_CALLBACK pfExport); 610 | BOOL WINAPI DetourEnumerateImports(_In_opt_ HMODULE hModule, 611 | _In_opt_ PVOID pContext, 612 | _In_opt_ PF_DETOUR_IMPORT_FILE_CALLBACK pfImportFile, 613 | _In_opt_ PF_DETOUR_IMPORT_FUNC_CALLBACK pfImportFunc); 614 | 615 | BOOL WINAPI DetourEnumerateImportsEx(_In_opt_ HMODULE hModule, 616 | _In_opt_ PVOID pContext, 617 | _In_opt_ PF_DETOUR_IMPORT_FILE_CALLBACK pfImportFile, 618 | _In_opt_ PF_DETOUR_IMPORT_FUNC_CALLBACK_EX pfImportFuncEx); 619 | 620 | _Writable_bytes_(*pcbData) 621 | _Readable_bytes_(*pcbData) 622 | _Success_(return != NULL) 623 | PVOID WINAPI DetourFindPayload(_In_opt_ HMODULE hModule, 624 | _In_ REFGUID rguid, 625 | _Out_opt_ DWORD *pcbData); 626 | 627 | _Writable_bytes_(*pcbData) 628 | _Readable_bytes_(*pcbData) 629 | _Success_(return != NULL) 630 | PVOID WINAPI DetourFindPayloadEx(_In_ REFGUID rguid, 631 | _Out_opt_ DWORD *pcbData); 632 | 633 | DWORD WINAPI DetourGetSizeOfPayloads(_In_opt_ HMODULE hModule); 634 | 635 | BOOL WINAPI DetourFreePayload(_In_ PVOID pvData); 636 | ///////////////////////////////////////////////// Persistent Binary Functions. 637 | // 638 | 639 | PDETOUR_BINARY WINAPI DetourBinaryOpen(_In_ HANDLE hFile); 640 | 641 | _Writable_bytes_(*pcbData) 642 | _Readable_bytes_(*pcbData) 643 | _Success_(return != NULL) 644 | PVOID WINAPI DetourBinaryEnumeratePayloads(_In_ PDETOUR_BINARY pBinary, 645 | _Out_opt_ GUID *pGuid, 646 | _Out_ DWORD *pcbData, 647 | _Inout_ DWORD *pnIterator); 648 | 649 | _Writable_bytes_(*pcbData) 650 | _Readable_bytes_(*pcbData) 651 | _Success_(return != NULL) 652 | PVOID WINAPI DetourBinaryFindPayload(_In_ PDETOUR_BINARY pBinary, 653 | _In_ REFGUID rguid, 654 | _Out_ DWORD *pcbData); 655 | 656 | PVOID WINAPI DetourBinarySetPayload(_In_ PDETOUR_BINARY pBinary, 657 | _In_ REFGUID rguid, 658 | _In_reads_opt_(cbData) PVOID pData, 659 | _In_ DWORD cbData); 660 | BOOL WINAPI DetourBinaryDeletePayload(_In_ PDETOUR_BINARY pBinary, _In_ REFGUID rguid); 661 | BOOL WINAPI DetourBinaryPurgePayloads(_In_ PDETOUR_BINARY pBinary); 662 | BOOL WINAPI DetourBinaryResetImports(_In_ PDETOUR_BINARY pBinary); 663 | BOOL WINAPI DetourBinaryEditImports(_In_ PDETOUR_BINARY pBinary, 664 | _In_opt_ PVOID pContext, 665 | _In_opt_ PF_DETOUR_BINARY_BYWAY_CALLBACK pfByway, 666 | _In_opt_ PF_DETOUR_BINARY_FILE_CALLBACK pfFile, 667 | _In_opt_ PF_DETOUR_BINARY_SYMBOL_CALLBACK pfSymbol, 668 | _In_opt_ PF_DETOUR_BINARY_COMMIT_CALLBACK pfCommit); 669 | BOOL WINAPI DetourBinaryWrite(_In_ PDETOUR_BINARY pBinary, _In_ HANDLE hFile); 670 | BOOL WINAPI DetourBinaryClose(_In_ PDETOUR_BINARY pBinary); 671 | 672 | /////////////////////////////////////////////////// Create Process & Load Dll. 673 | // 674 | _Success_(return != NULL) 675 | PVOID WINAPI DetourFindRemotePayload(_In_ HANDLE hProcess, 676 | _In_ REFGUID rguid, 677 | _Out_opt_ DWORD *pcbData); 678 | 679 | typedef BOOL (WINAPI *PDETOUR_CREATE_PROCESS_ROUTINEA)( 680 | _In_opt_ LPCSTR lpApplicationName, 681 | _Inout_opt_ LPSTR lpCommandLine, 682 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 683 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 684 | _In_ BOOL bInheritHandles, 685 | _In_ DWORD dwCreationFlags, 686 | _In_opt_ LPVOID lpEnvironment, 687 | _In_opt_ LPCSTR lpCurrentDirectory, 688 | _In_ LPSTARTUPINFOA lpStartupInfo, 689 | _Out_ LPPROCESS_INFORMATION lpProcessInformation); 690 | 691 | typedef BOOL (WINAPI *PDETOUR_CREATE_PROCESS_ROUTINEW)( 692 | _In_opt_ LPCWSTR lpApplicationName, 693 | _Inout_opt_ LPWSTR lpCommandLine, 694 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 695 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 696 | _In_ BOOL bInheritHandles, 697 | _In_ DWORD dwCreationFlags, 698 | _In_opt_ LPVOID lpEnvironment, 699 | _In_opt_ LPCWSTR lpCurrentDirectory, 700 | _In_ LPSTARTUPINFOW lpStartupInfo, 701 | _Out_ LPPROCESS_INFORMATION lpProcessInformation); 702 | 703 | BOOL WINAPI DetourCreateProcessWithDllA(_In_opt_ LPCSTR lpApplicationName, 704 | _Inout_opt_ LPSTR lpCommandLine, 705 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 706 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 707 | _In_ BOOL bInheritHandles, 708 | _In_ DWORD dwCreationFlags, 709 | _In_opt_ LPVOID lpEnvironment, 710 | _In_opt_ LPCSTR lpCurrentDirectory, 711 | _In_ LPSTARTUPINFOA lpStartupInfo, 712 | _Out_ LPPROCESS_INFORMATION lpProcessInformation, 713 | _In_ LPCSTR lpDllName, 714 | _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); 715 | 716 | BOOL WINAPI DetourCreateProcessWithDllW(_In_opt_ LPCWSTR lpApplicationName, 717 | _Inout_opt_ LPWSTR lpCommandLine, 718 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 719 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 720 | _In_ BOOL bInheritHandles, 721 | _In_ DWORD dwCreationFlags, 722 | _In_opt_ LPVOID lpEnvironment, 723 | _In_opt_ LPCWSTR lpCurrentDirectory, 724 | _In_ LPSTARTUPINFOW lpStartupInfo, 725 | _Out_ LPPROCESS_INFORMATION lpProcessInformation, 726 | _In_ LPCSTR lpDllName, 727 | _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); 728 | 729 | #ifdef UNICODE 730 | #define DetourCreateProcessWithDll DetourCreateProcessWithDllW 731 | #define PDETOUR_CREATE_PROCESS_ROUTINE PDETOUR_CREATE_PROCESS_ROUTINEW 732 | #else 733 | #define DetourCreateProcessWithDll DetourCreateProcessWithDllA 734 | #define PDETOUR_CREATE_PROCESS_ROUTINE PDETOUR_CREATE_PROCESS_ROUTINEA 735 | #endif // !UNICODE 736 | 737 | BOOL WINAPI DetourCreateProcessWithDllExA(_In_opt_ LPCSTR lpApplicationName, 738 | _Inout_opt_ LPSTR lpCommandLine, 739 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 740 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 741 | _In_ BOOL bInheritHandles, 742 | _In_ DWORD dwCreationFlags, 743 | _In_opt_ LPVOID lpEnvironment, 744 | _In_opt_ LPCSTR lpCurrentDirectory, 745 | _In_ LPSTARTUPINFOA lpStartupInfo, 746 | _Out_ LPPROCESS_INFORMATION lpProcessInformation, 747 | _In_ LPCSTR lpDllName, 748 | _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); 749 | 750 | BOOL WINAPI DetourCreateProcessWithDllExW(_In_opt_ LPCWSTR lpApplicationName, 751 | _Inout_opt_ LPWSTR lpCommandLine, 752 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 753 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 754 | _In_ BOOL bInheritHandles, 755 | _In_ DWORD dwCreationFlags, 756 | _In_opt_ LPVOID lpEnvironment, 757 | _In_opt_ LPCWSTR lpCurrentDirectory, 758 | _In_ LPSTARTUPINFOW lpStartupInfo, 759 | _Out_ LPPROCESS_INFORMATION lpProcessInformation, 760 | _In_ LPCSTR lpDllName, 761 | _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); 762 | 763 | #ifdef UNICODE 764 | #define DetourCreateProcessWithDllEx DetourCreateProcessWithDllExW 765 | #else 766 | #define DetourCreateProcessWithDllEx DetourCreateProcessWithDllExA 767 | #endif // !UNICODE 768 | 769 | BOOL WINAPI DetourCreateProcessWithDllsA(_In_opt_ LPCSTR lpApplicationName, 770 | _Inout_opt_ LPSTR lpCommandLine, 771 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 772 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 773 | _In_ BOOL bInheritHandles, 774 | _In_ DWORD dwCreationFlags, 775 | _In_opt_ LPVOID lpEnvironment, 776 | _In_opt_ LPCSTR lpCurrentDirectory, 777 | _In_ LPSTARTUPINFOA lpStartupInfo, 778 | _Out_ LPPROCESS_INFORMATION lpProcessInformation, 779 | _In_ DWORD nDlls, 780 | _In_reads_(nDlls) LPCSTR *rlpDlls, 781 | _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); 782 | 783 | BOOL WINAPI DetourCreateProcessWithDllsW(_In_opt_ LPCWSTR lpApplicationName, 784 | _Inout_opt_ LPWSTR lpCommandLine, 785 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 786 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 787 | _In_ BOOL bInheritHandles, 788 | _In_ DWORD dwCreationFlags, 789 | _In_opt_ LPVOID lpEnvironment, 790 | _In_opt_ LPCWSTR lpCurrentDirectory, 791 | _In_ LPSTARTUPINFOW lpStartupInfo, 792 | _Out_ LPPROCESS_INFORMATION lpProcessInformation, 793 | _In_ DWORD nDlls, 794 | _In_reads_(nDlls) LPCSTR *rlpDlls, 795 | _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); 796 | 797 | #ifdef UNICODE 798 | #define DetourCreateProcessWithDlls DetourCreateProcessWithDllsW 799 | #else 800 | #define DetourCreateProcessWithDlls DetourCreateProcessWithDllsA 801 | #endif // !UNICODE 802 | 803 | BOOL WINAPI DetourProcessViaHelperA(_In_ DWORD dwTargetPid, 804 | _In_ LPCSTR lpDllName, 805 | _In_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); 806 | 807 | BOOL WINAPI DetourProcessViaHelperW(_In_ DWORD dwTargetPid, 808 | _In_ LPCSTR lpDllName, 809 | _In_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); 810 | 811 | #ifdef UNICODE 812 | #define DetourProcessViaHelper DetourProcessViaHelperW 813 | #else 814 | #define DetourProcessViaHelper DetourProcessViaHelperA 815 | #endif // !UNICODE 816 | 817 | BOOL WINAPI DetourProcessViaHelperDllsA(_In_ DWORD dwTargetPid, 818 | _In_ DWORD nDlls, 819 | _In_reads_(nDlls) LPCSTR *rlpDlls, 820 | _In_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); 821 | 822 | BOOL WINAPI DetourProcessViaHelperDllsW(_In_ DWORD dwTargetPid, 823 | _In_ DWORD nDlls, 824 | _In_reads_(nDlls) LPCSTR *rlpDlls, 825 | _In_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); 826 | 827 | #ifdef UNICODE 828 | #define DetourProcessViaHelperDlls DetourProcessViaHelperDllsW 829 | #else 830 | #define DetourProcessViaHelperDlls DetourProcessViaHelperDllsA 831 | #endif // !UNICODE 832 | 833 | BOOL WINAPI DetourUpdateProcessWithDll(_In_ HANDLE hProcess, 834 | _In_reads_(nDlls) LPCSTR *rlpDlls, 835 | _In_ DWORD nDlls); 836 | 837 | BOOL WINAPI DetourUpdateProcessWithDllEx(_In_ HANDLE hProcess, 838 | _In_ HMODULE hImage, 839 | _In_ BOOL bIs32Bit, 840 | _In_reads_(nDlls) LPCSTR *rlpDlls, 841 | _In_ DWORD nDlls); 842 | 843 | BOOL WINAPI DetourCopyPayloadToProcess(_In_ HANDLE hProcess, 844 | _In_ REFGUID rguid, 845 | _In_reads_bytes_(cbData) LPCVOID pvData, 846 | _In_ DWORD cbData); 847 | _Success_(return != NULL) 848 | PVOID WINAPI DetourCopyPayloadToProcessEx(_In_ HANDLE hProcess, 849 | _In_ REFGUID rguid, 850 | _In_reads_bytes_(cbData) LPCVOID pvData, 851 | _In_ DWORD cbData); 852 | 853 | BOOL WINAPI DetourRestoreAfterWith(VOID); 854 | BOOL WINAPI DetourRestoreAfterWithEx(_In_reads_bytes_(cbData) PVOID pvData, 855 | _In_ DWORD cbData); 856 | BOOL WINAPI DetourIsHelperProcess(VOID); 857 | VOID CALLBACK DetourFinishHelperProcess(_In_ HWND, 858 | _In_ HINSTANCE, 859 | _In_ LPSTR, 860 | _In_ INT); 861 | 862 | // 863 | ////////////////////////////////////////////////////////////////////////////// 864 | #ifdef __cplusplus 865 | } 866 | #endif // __cplusplus 867 | 868 | /////////////////////////////////////////////////// Type-safe overloads for C++ 869 | // 870 | #if __cplusplus >= 201103L || _MSVC_LANG >= 201103L 871 | #include 872 | 873 | template 874 | struct DetoursIsFunctionPointer : std::false_type {}; 875 | 876 | template 877 | struct DetoursIsFunctionPointer : std::is_function::type> {}; 878 | 879 | template< 880 | typename T, 881 | typename std::enable_if::value, int>::type = 0> 882 | LONG DetourAttach(_Inout_ T *ppPointer, 883 | _In_ T pDetour) noexcept 884 | { 885 | return DetourAttach( 886 | reinterpret_cast(ppPointer), 887 | reinterpret_cast(pDetour)); 888 | } 889 | 890 | template< 891 | typename T, 892 | typename std::enable_if::value, int>::type = 0> 893 | LONG DetourAttachEx(_Inout_ T *ppPointer, 894 | _In_ T pDetour, 895 | _Out_opt_ PDETOUR_TRAMPOLINE *ppRealTrampoline, 896 | _Out_opt_ T *ppRealTarget, 897 | _Out_opt_ T *ppRealDetour) noexcept 898 | { 899 | return DetourAttachEx( 900 | reinterpret_cast(ppPointer), 901 | reinterpret_cast(pDetour), 902 | ppRealTrampoline, 903 | reinterpret_cast(ppRealTarget), 904 | reinterpret_cast(ppRealDetour)); 905 | } 906 | 907 | template< 908 | typename T, 909 | typename std::enable_if::value, int>::type = 0> 910 | LONG DetourDetach(_Inout_ T *ppPointer, 911 | _In_ T pDetour) noexcept 912 | { 913 | return DetourDetach( 914 | reinterpret_cast(ppPointer), 915 | reinterpret_cast(pDetour)); 916 | } 917 | 918 | #endif // __cplusplus >= 201103L || _MSVC_LANG >= 201103L 919 | // 920 | ////////////////////////////////////////////////////////////////////////////// 921 | 922 | //////////////////////////////////////////////// Detours Internal Definitions. 923 | // 924 | #ifdef __cplusplus 925 | #ifdef DETOURS_INTERNAL 926 | 927 | #define NOTHROW 928 | // #define NOTHROW (nothrow) 929 | 930 | ////////////////////////////////////////////////////////////////////////////// 931 | // 932 | #if (_MSC_VER < 1299) && !defined(__GNUC__) 933 | #include 934 | typedef IMAGEHLP_MODULE IMAGEHLP_MODULE64; 935 | typedef PIMAGEHLP_MODULE PIMAGEHLP_MODULE64; 936 | typedef IMAGEHLP_SYMBOL SYMBOL_INFO; 937 | typedef PIMAGEHLP_SYMBOL PSYMBOL_INFO; 938 | 939 | static inline 940 | LONG InterlockedCompareExchange(_Inout_ LONG *ptr, _In_ LONG nval, _In_ LONG oval) 941 | { 942 | return (LONG)::InterlockedCompareExchange((PVOID*)ptr, (PVOID)nval, (PVOID)oval); 943 | } 944 | #else 945 | #pragma warning(push) 946 | #pragma warning(disable:4091) // empty typedef 947 | #include 948 | #pragma warning(pop) 949 | #endif 950 | 951 | #ifdef IMAGEAPI // defined by DBGHELP.H 952 | typedef LPAPI_VERSION (NTAPI *PF_ImagehlpApiVersionEx)(_In_ LPAPI_VERSION AppVersion); 953 | 954 | typedef BOOL (NTAPI *PF_SymInitialize)(_In_ HANDLE hProcess, 955 | _In_opt_ LPCSTR UserSearchPath, 956 | _In_ BOOL fInvadeProcess); 957 | typedef DWORD (NTAPI *PF_SymSetOptions)(_In_ DWORD SymOptions); 958 | typedef DWORD (NTAPI *PF_SymGetOptions)(VOID); 959 | typedef DWORD64 (NTAPI *PF_SymLoadModule64)(_In_ HANDLE hProcess, 960 | _In_opt_ HANDLE hFile, 961 | _In_opt_ LPSTR ImageName, 962 | _In_opt_ LPSTR ModuleName, 963 | _In_ DWORD64 BaseOfDll, 964 | _In_ DWORD SizeOfDll); 965 | typedef BOOL (NTAPI *PF_SymGetModuleInfo64)(_In_ HANDLE hProcess, 966 | _In_ DWORD64 qwAddr, 967 | _Out_ PIMAGEHLP_MODULE64 ModuleInfo); 968 | typedef BOOL (NTAPI *PF_SymFromName)(_In_ HANDLE hProcess, 969 | _In_ LPSTR Name, 970 | _Out_ PSYMBOL_INFO Symbol); 971 | 972 | typedef struct _DETOUR_SYM_INFO 973 | { 974 | HANDLE hProcess; 975 | HMODULE hDbgHelp; 976 | PF_ImagehlpApiVersionEx pfImagehlpApiVersionEx; 977 | PF_SymInitialize pfSymInitialize; 978 | PF_SymSetOptions pfSymSetOptions; 979 | PF_SymGetOptions pfSymGetOptions; 980 | PF_SymLoadModule64 pfSymLoadModule64; 981 | PF_SymGetModuleInfo64 pfSymGetModuleInfo64; 982 | PF_SymFromName pfSymFromName; 983 | } DETOUR_SYM_INFO, *PDETOUR_SYM_INFO; 984 | 985 | PDETOUR_SYM_INFO DetourLoadImageHlp(VOID); 986 | 987 | #endif // IMAGEAPI 988 | 989 | #if defined(_INC_STDIO) && !defined(_CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS) 990 | #error detours.h must be included before stdio.h (or at least define _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS earlier) 991 | #endif 992 | #define _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS 1 993 | 994 | #ifdef _DEBUG 995 | 996 | int Detour_AssertExprWithFunctionName(int reportType, const char* filename, int linenumber, const char* FunctionName, const char* msg); 997 | 998 | #define DETOUR_ASSERT_EXPR_WITH_FUNCTION(expr, msg) \ 999 | (void) ((expr) || \ 1000 | (1 != Detour_AssertExprWithFunctionName(_CRT_ASSERT, __FILE__, __LINE__,__FUNCTION__, msg)) || \ 1001 | (_CrtDbgBreak(), 0)) 1002 | 1003 | #define DETOUR_ASSERT(expr) DETOUR_ASSERT_EXPR_WITH_FUNCTION((expr), #expr) 1004 | 1005 | #else// _DEBUG 1006 | #define DETOUR_ASSERT(expr) 1007 | #endif// _DEBUG 1008 | 1009 | #ifndef DETOUR_TRACE 1010 | #if DETOUR_DEBUG 1011 | #define DETOUR_TRACE(x) printf x 1012 | #define DETOUR_BREAK() __debugbreak() 1013 | #include 1014 | #include 1015 | #else 1016 | #define DETOUR_TRACE(x) 1017 | #define DETOUR_BREAK() 1018 | #endif 1019 | #endif 1020 | 1021 | #if 1 || defined(DETOURS_IA64) 1022 | 1023 | // 1024 | // IA64 instructions are 41 bits, 3 per bundle, plus 5 bit bundle template => 128 bits per bundle. 1025 | // 1026 | 1027 | #define DETOUR_IA64_INSTRUCTIONS_PER_BUNDLE (3) 1028 | 1029 | #define DETOUR_IA64_TEMPLATE_OFFSET (0) 1030 | #define DETOUR_IA64_TEMPLATE_SIZE (5) 1031 | 1032 | #define DETOUR_IA64_INSTRUCTION_SIZE (41) 1033 | #define DETOUR_IA64_INSTRUCTION0_OFFSET (DETOUR_IA64_TEMPLATE_SIZE) 1034 | #define DETOUR_IA64_INSTRUCTION1_OFFSET (DETOUR_IA64_TEMPLATE_SIZE + DETOUR_IA64_INSTRUCTION_SIZE) 1035 | #define DETOUR_IA64_INSTRUCTION2_OFFSET (DETOUR_IA64_TEMPLATE_SIZE + DETOUR_IA64_INSTRUCTION_SIZE + DETOUR_IA64_INSTRUCTION_SIZE) 1036 | 1037 | C_ASSERT(DETOUR_IA64_TEMPLATE_SIZE + DETOUR_IA64_INSTRUCTIONS_PER_BUNDLE * DETOUR_IA64_INSTRUCTION_SIZE == 128); 1038 | 1039 | __declspec(align(16)) struct DETOUR_IA64_BUNDLE 1040 | { 1041 | public: 1042 | union 1043 | { 1044 | BYTE data[16]; 1045 | UINT64 wide[2]; 1046 | }; 1047 | 1048 | enum { 1049 | A_UNIT = 1u, 1050 | I_UNIT = 2u, 1051 | M_UNIT = 3u, 1052 | B_UNIT = 4u, 1053 | F_UNIT = 5u, 1054 | L_UNIT = 6u, 1055 | X_UNIT = 7u, 1056 | }; 1057 | struct DETOUR_IA64_METADATA 1058 | { 1059 | ULONG nTemplate : 8; // Instruction template. 1060 | ULONG nUnit0 : 4; // Unit for slot 0 1061 | ULONG nUnit1 : 4; // Unit for slot 1 1062 | ULONG nUnit2 : 4; // Unit for slot 2 1063 | }; 1064 | 1065 | protected: 1066 | static const DETOUR_IA64_METADATA s_rceCopyTable[33]; 1067 | 1068 | UINT RelocateBundle(_Inout_ DETOUR_IA64_BUNDLE* pDst, _Inout_opt_ DETOUR_IA64_BUNDLE* pBundleExtra) const; 1069 | 1070 | bool RelocateInstruction(_Inout_ DETOUR_IA64_BUNDLE* pDst, 1071 | _In_ BYTE slot, 1072 | _Inout_opt_ DETOUR_IA64_BUNDLE* pBundleExtra) const; 1073 | 1074 | // 120 112 104 96 88 80 72 64 56 48 40 32 24 16 8 0 1075 | // f. e. d. c. b. a. 9. 8. 7. 6. 5. 4. 3. 2. 1. 0. 1076 | 1077 | // 00 1078 | // f.e. d.c. b.a. 9.8. 7.6. 5.4. 3.2. 1.0. 1079 | // 0000 0000 0000 0000 0000 0000 0000 001f : Template [4..0] 1080 | // 0000 0000 0000 0000 0000 03ff ffff ffe0 : Zero [ 41.. 5] 1081 | // 0000 0000 0000 0000 0000 3c00 0000 0000 : Zero [ 45.. 42] 1082 | // 0000 0000 0007 ffff ffff c000 0000 0000 : One [ 82.. 46] 1083 | // 0000 0000 0078 0000 0000 0000 0000 0000 : One [ 86.. 83] 1084 | // 0fff ffff ff80 0000 0000 0000 0000 0000 : Two [123.. 87] 1085 | // f000 0000 0000 0000 0000 0000 0000 0000 : Two [127..124] 1086 | BYTE GetTemplate() const; 1087 | // Get 4 bit opcodes. 1088 | BYTE GetInst0() const; 1089 | BYTE GetInst1() const; 1090 | BYTE GetInst2() const; 1091 | BYTE GetUnit(BYTE slot) const; 1092 | BYTE GetUnit0() const; 1093 | BYTE GetUnit1() const; 1094 | BYTE GetUnit2() const; 1095 | // Get 37 bit data. 1096 | UINT64 GetData0() const; 1097 | UINT64 GetData1() const; 1098 | UINT64 GetData2() const; 1099 | 1100 | // Get/set the full 41 bit instructions. 1101 | UINT64 GetInstruction(BYTE slot) const; 1102 | UINT64 GetInstruction0() const; 1103 | UINT64 GetInstruction1() const; 1104 | UINT64 GetInstruction2() const; 1105 | void SetInstruction(BYTE slot, UINT64 instruction); 1106 | void SetInstruction0(UINT64 instruction); 1107 | void SetInstruction1(UINT64 instruction); 1108 | void SetInstruction2(UINT64 instruction); 1109 | 1110 | // Get/set bitfields. 1111 | static UINT64 GetBits(UINT64 Value, UINT64 Offset, UINT64 Count); 1112 | static UINT64 SetBits(UINT64 Value, UINT64 Offset, UINT64 Count, UINT64 Field); 1113 | 1114 | // Get specific read-only fields. 1115 | static UINT64 GetOpcode(UINT64 instruction); // 4bit opcode 1116 | static UINT64 GetX(UINT64 instruction); // 1bit opcode extension 1117 | static UINT64 GetX3(UINT64 instruction); // 3bit opcode extension 1118 | static UINT64 GetX6(UINT64 instruction); // 6bit opcode extension 1119 | 1120 | // Get/set specific fields. 1121 | static UINT64 GetImm7a(UINT64 instruction); 1122 | static UINT64 SetImm7a(UINT64 instruction, UINT64 imm7a); 1123 | static UINT64 GetImm13c(UINT64 instruction); 1124 | static UINT64 SetImm13c(UINT64 instruction, UINT64 imm13c); 1125 | static UINT64 GetSignBit(UINT64 instruction); 1126 | static UINT64 SetSignBit(UINT64 instruction, UINT64 signBit); 1127 | static UINT64 GetImm20a(UINT64 instruction); 1128 | static UINT64 SetImm20a(UINT64 instruction, UINT64 imm20a); 1129 | static UINT64 GetImm20b(UINT64 instruction); 1130 | static UINT64 SetImm20b(UINT64 instruction, UINT64 imm20b); 1131 | 1132 | static UINT64 SignExtend(UINT64 Value, UINT64 Offset); 1133 | 1134 | BOOL IsMovlGp() const; 1135 | 1136 | VOID SetInst(BYTE Slot, BYTE nInst); 1137 | VOID SetInst0(BYTE nInst); 1138 | VOID SetInst1(BYTE nInst); 1139 | VOID SetInst2(BYTE nInst); 1140 | VOID SetData(BYTE Slot, UINT64 nData); 1141 | VOID SetData0(UINT64 nData); 1142 | VOID SetData1(UINT64 nData); 1143 | VOID SetData2(UINT64 nData); 1144 | BOOL SetNop(BYTE Slot); 1145 | BOOL SetNop0(); 1146 | BOOL SetNop1(); 1147 | BOOL SetNop2(); 1148 | 1149 | public: 1150 | BOOL IsBrl() const; 1151 | VOID SetBrl(); 1152 | VOID SetBrl(UINT64 target); 1153 | UINT64 GetBrlTarget() const; 1154 | VOID SetBrlTarget(UINT64 target); 1155 | VOID SetBrlImm(UINT64 imm); 1156 | UINT64 GetBrlImm() const; 1157 | 1158 | UINT64 GetMovlGp() const; 1159 | VOID SetMovlGp(UINT64 gp); 1160 | 1161 | VOID SetStop(); 1162 | 1163 | UINT Copy(_Out_ DETOUR_IA64_BUNDLE *pDst, _Inout_opt_ DETOUR_IA64_BUNDLE* pBundleExtra = NULL) const; 1164 | }; 1165 | #endif // DETOURS_IA64 1166 | 1167 | #ifdef DETOURS_ARM 1168 | 1169 | #define DETOURS_PFUNC_TO_PBYTE(p) ((PBYTE)(((ULONG_PTR)(p)) & ~(ULONG_PTR)1)) 1170 | #define DETOURS_PBYTE_TO_PFUNC(p) ((PBYTE)(((ULONG_PTR)(p)) | (ULONG_PTR)1)) 1171 | 1172 | #endif // DETOURS_ARM 1173 | 1174 | ////////////////////////////////////////////////////////////////////////////// 1175 | 1176 | #ifdef __cplusplus 1177 | extern "C" { 1178 | #endif // __cplusplus 1179 | 1180 | #define DETOUR_OFFLINE_LIBRARY(x) \ 1181 | PVOID WINAPI DetourCopyInstruction##x(_In_opt_ PVOID pDst, \ 1182 | _Inout_opt_ PVOID *ppDstPool, \ 1183 | _In_ PVOID pSrc, \ 1184 | _Out_opt_ PVOID *ppTarget, \ 1185 | _Out_opt_ LONG *plExtra); \ 1186 | \ 1187 | BOOL WINAPI DetourSetCodeModule##x(_In_ HMODULE hModule, \ 1188 | _In_ BOOL fLimitReferencesToModule); \ 1189 | 1190 | DETOUR_OFFLINE_LIBRARY(X86) 1191 | DETOUR_OFFLINE_LIBRARY(X64) 1192 | DETOUR_OFFLINE_LIBRARY(ARM) 1193 | DETOUR_OFFLINE_LIBRARY(ARM64) 1194 | DETOUR_OFFLINE_LIBRARY(IA64) 1195 | 1196 | #undef DETOUR_OFFLINE_LIBRARY 1197 | 1198 | ////////////////////////////////////////////////////////////////////////////// 1199 | // 1200 | // Helpers for manipulating page protection. 1201 | // 1202 | 1203 | _Success_(return != FALSE) 1204 | BOOL WINAPI DetourVirtualProtectSameExecuteEx(_In_ HANDLE hProcess, 1205 | _In_ PVOID pAddress, 1206 | _In_ SIZE_T nSize, 1207 | _In_ DWORD dwNewProtect, 1208 | _Out_ PDWORD pdwOldProtect); 1209 | 1210 | _Success_(return != FALSE) 1211 | BOOL WINAPI DetourVirtualProtectSameExecute(_In_ PVOID pAddress, 1212 | _In_ SIZE_T nSize, 1213 | _In_ DWORD dwNewProtect, 1214 | _Out_ PDWORD pdwOldProtect); 1215 | 1216 | // Detours must depend only on kernel32.lib, so we cannot use IsEqualGUID 1217 | BOOL WINAPI DetourAreSameGuid(_In_ REFGUID left, _In_ REFGUID right); 1218 | #ifdef __cplusplus 1219 | } 1220 | #endif // __cplusplus 1221 | 1222 | ////////////////////////////////////////////////////////////////////////////// 1223 | 1224 | #define MM_ALLOCATION_GRANULARITY 0x10000 1225 | 1226 | ////////////////////////////////////////////////////////////////////////////// 1227 | 1228 | #endif // DETOURS_INTERNAL 1229 | #endif // __cplusplus 1230 | 1231 | #endif // _DETOURS_H_ 1232 | // 1233 | //////////////////////////////////////////////////////////////// End of File. 1234 | -------------------------------------------------------------------------------- /detours/include/detver.h: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Common version parameters. 4 | // 5 | // Microsoft Research Detours Package, Version 4.0.1 6 | // 7 | // Copyright (c) Microsoft Corporation. All rights reserved. 8 | // 9 | 10 | #define _USING_V110_SDK71_ 1 11 | #include "winver.h" 12 | #if 0 13 | #include 14 | #include 15 | #else 16 | #ifndef DETOURS_STRINGIFY 17 | #define DETOURS_STRINGIFY_(x) #x 18 | #define DETOURS_STRINGIFY(x) DETOURS_STRINGIFY_(x) 19 | #endif 20 | 21 | #define VER_FILEFLAGSMASK 0x3fL 22 | #define VER_FILEFLAGS 0x0L 23 | #define VER_FILEOS 0x00040004L 24 | #define VER_FILETYPE 0x00000002L 25 | #define VER_FILESUBTYPE 0x00000000L 26 | #endif 27 | #define VER_DETOURS_BITS DETOURS_STRINGIFY(DETOURS_BITS) 28 | -------------------------------------------------------------------------------- /detours/lib.ARM64/detours.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/driver1998/HookCoreAppWinUI/9b407de2f4921c7a04fa697702cbdb9248f3d63e/detours/lib.ARM64/detours.lib -------------------------------------------------------------------------------- /detours/lib.ARM64/detours.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/driver1998/HookCoreAppWinUI/9b407de2f4921c7a04fa697702cbdb9248f3d63e/detours/lib.ARM64/detours.pdb -------------------------------------------------------------------------------- /detours/lib.X64/detours.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/driver1998/HookCoreAppWinUI/9b407de2f4921c7a04fa697702cbdb9248f3d63e/detours/lib.X64/detours.lib -------------------------------------------------------------------------------- /detours/lib.X64/detours.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/driver1998/HookCoreAppWinUI/9b407de2f4921c7a04fa697702cbdb9248f3d63e/detours/lib.X64/detours.pdb -------------------------------------------------------------------------------- /detours/lib.X86/detours.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/driver1998/HookCoreAppWinUI/9b407de2f4921c7a04fa697702cbdb9248f3d63e/detours/lib.X86/detours.lib -------------------------------------------------------------------------------- /detours/lib.X86/detours.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/driver1998/HookCoreAppWinUI/9b407de2f4921c7a04fa697702cbdb9248f3d63e/detours/lib.X86/detours.pdb --------------------------------------------------------------------------------