From 6649ae734d4da3add427b3c278b3d12d4be64666 Mon Sep 17 00:00:00 2001 From: qtkite Date: Sat, 26 Jun 2021 18:14:52 +1000 Subject: [PATCH] com class --- .gitignore | 700 ++--- LICENSE | 42 +- README.md | 802 +++--- logs.MD | 1046 +++---- src/defender-control.sln | 82 +- src/defender-control/dcontrol.cpp | 572 ++-- src/defender-control/dcontrol.h | 38 +- src/defender-control/defender-control.vcxproj | 304 +-- .../defender-control.vcxproj.filters | 64 +- src/defender-control/main.cpp | 46 +- src/detour/64/include/detours.h | 2418 ++++++++--------- src/detour/64/include/detver.h | 54 +- src/detour/64/include/syelog.h | 178 +- src/detour/86/include/detours.h | 2418 ++++++++--------- src/detour/86/include/detver.h | 54 +- src/detour/86/include/syelog.h | 178 +- src/detour/README.md | 6 +- src/dumper/dumper.cpp | 1152 ++++---- src/dumper/dumper.vcxproj | 346 +-- src/dumper/dumper.vcxproj.filters | 64 +- src/dumper/framework.h | 10 +- src/dumper/pch.cpp | 10 +- src/dumper/pch.h | 36 +- 23 files changed, 5325 insertions(+), 5295 deletions(-) diff --git a/.gitignore b/.gitignore index dfcfd56..cb43218 100644 --- a/.gitignore +++ b/.gitignore @@ -1,350 +1,350 @@ -## Ignore Visual Studio temporary files, build results, and -## files generated by popular Visual Studio add-ons. -## -## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore - -# User-specific files -*.rsuser -*.suo -*.user -*.userosscache -*.sln.docstates - -# User-specific files (MonoDevelop/Xamarin Studio) -*.userprefs - -# Mono auto generated files -mono_crash.* - -# Build results -[Dd]ebug/ -[Dd]ebugPublic/ -[Rr]elease/ -[Rr]eleases/ -x64/ -x86/ -[Aa][Rr][Mm]/ -[Aa][Rr][Mm]64/ -bld/ -[Bb]in/ -[Oo]bj/ -[Ll]og/ -[Ll]ogs/ - -# Visual Studio 2015/2017 cache/options directory -.vs/ -# Uncomment if you have tasks that create the project's static files in wwwroot -#wwwroot/ - -# Visual Studio 2017 auto generated files -Generated\ Files/ - -# MSTest test Results -[Tt]est[Rr]esult*/ -[Bb]uild[Ll]og.* - -# NUnit -*.VisualState.xml -TestResult.xml -nunit-*.xml - -# Build Results of an ATL Project -[Dd]ebugPS/ -[Rr]eleasePS/ -dlldata.c - -# Benchmark Results -BenchmarkDotNet.Artifacts/ - -# .NET Core -project.lock.json -project.fragment.lock.json -artifacts/ - -# StyleCop -StyleCopReport.xml - -# Files built by Visual Studio -*_i.c -*_p.c -*_h.h -*.ilk -*.meta -*.obj -*.iobj -*.pch -*.pdb -*.ipdb -*.pgc -*.pgd -*.rsp -*.sbr -*.tlb -*.tli -*.tlh -*.tmp -*.tmp_proj -*_wpftmp.csproj -*.log -*.vspscc -*.vssscc -.builds -*.pidb -*.svclog -*.scc - -# Chutzpah Test files -_Chutzpah* - -# Visual C++ cache files -ipch/ -*.aps -*.ncb -*.opendb -*.opensdf -*.sdf -*.cachefile -*.VC.db -*.VC.VC.opendb - -# Visual Studio profiler -*.psess -*.vsp -*.vspx -*.sap - -# Visual Studio Trace Files -*.e2e - -# TFS 2012 Local Workspace -$tf/ - -# Guidance Automation Toolkit -*.gpState - -# ReSharper is a .NET coding add-in -_ReSharper*/ -*.[Rr]e[Ss]harper -*.DotSettings.user - -# TeamCity is a build add-in -_TeamCity* - -# DotCover is a Code Coverage Tool -*.dotCover - -# AxoCover is a Code Coverage Tool -.axoCover/* -!.axoCover/settings.json - -# Visual Studio code coverage results -*.coverage -*.coveragexml - -# NCrunch -_NCrunch_* -.*crunch*.local.xml -nCrunchTemp_* - -# MightyMoose -*.mm.* -AutoTest.Net/ - -# Web workbench (sass) -.sass-cache/ - -# Installshield output folder -[Ee]xpress/ - -# DocProject is a documentation generator add-in -DocProject/buildhelp/ -DocProject/Help/*.HxT -DocProject/Help/*.HxC -DocProject/Help/*.hhc -DocProject/Help/*.hhk -DocProject/Help/*.hhp -DocProject/Help/Html2 -DocProject/Help/html - -# Click-Once directory -publish/ - -# Publish Web Output -*.[Pp]ublish.xml -*.azurePubxml -# Note: Comment the next line if you want to checkin your web deploy settings, -# but database connection strings (with potential passwords) will be unencrypted -*.pubxml -*.publishproj - -# Microsoft Azure Web App publish settings. Comment the next line if you want to -# checkin your Azure Web App publish settings, but sensitive information contained -# in these scripts will be unencrypted -PublishScripts/ - -# NuGet Packages -*.nupkg -# NuGet Symbol Packages -*.snupkg -# The packages folder can be ignored because of Package Restore -**/[Pp]ackages/* -# except build/, which is used as an MSBuild target. -!**/[Pp]ackages/build/ -# Uncomment if necessary however generally it will be regenerated when needed -#!**/[Pp]ackages/repositories.config -# NuGet v3's project.json files produces more ignorable files -*.nuget.props -*.nuget.targets - -# Microsoft Azure Build Output -csx/ -*.build.csdef - -# Microsoft Azure Emulator -ecf/ -rcf/ - -# Windows Store app package directories and files -AppPackages/ -BundleArtifacts/ -Package.StoreAssociation.xml -_pkginfo.txt -*.appx -*.appxbundle -*.appxupload - -# Visual Studio cache files -# files ending in .cache can be ignored -*.[Cc]ache -# but keep track of directories ending in .cache -!?*.[Cc]ache/ - -# Others -ClientBin/ -~$* -*~ -*.dbmdl -*.dbproj.schemaview -*.jfm -*.pfx -*.publishsettings -orleans.codegen.cs - -# Including strong name files can present a security risk -# (https://github.com/github/gitignore/pull/2483#issue-259490424) -#*.snk - -# Since there are multiple workflows, uncomment next line to ignore bower_components -# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) -#bower_components/ - -# RIA/Silverlight projects -Generated_Code/ - -# Backup & report files from converting an old project file -# to a newer Visual Studio version. Backup files are not needed, -# because we have git ;-) -_UpgradeReport_Files/ -Backup*/ -UpgradeLog*.XML -UpgradeLog*.htm -ServiceFabricBackup/ -*.rptproj.bak - -# SQL Server files -*.mdf -*.ldf -*.ndf - -# Business Intelligence projects -*.rdl.data -*.bim.layout -*.bim_*.settings -*.rptproj.rsuser -*- [Bb]ackup.rdl -*- [Bb]ackup ([0-9]).rdl -*- [Bb]ackup ([0-9][0-9]).rdl - -# Microsoft Fakes -FakesAssemblies/ - -# GhostDoc plugin setting file -*.GhostDoc.xml - -# Node.js Tools for Visual Studio -.ntvs_analysis.dat -node_modules/ - -# Visual Studio 6 build log -*.plg - -# Visual Studio 6 workspace options file -*.opt - -# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) -*.vbw - -# Visual Studio LightSwitch build output -**/*.HTMLClient/GeneratedArtifacts -**/*.DesktopClient/GeneratedArtifacts -**/*.DesktopClient/ModelManifest.xml -**/*.Server/GeneratedArtifacts -**/*.Server/ModelManifest.xml -_Pvt_Extensions - -# Paket dependency manager -.paket/paket.exe -paket-files/ - -# FAKE - F# Make -.fake/ - -# CodeRush personal settings -.cr/personal - -# Python Tools for Visual Studio (PTVS) -__pycache__/ -*.pyc - -# Cake - Uncomment if you are using it -# tools/** -# !tools/packages.config - -# Tabs Studio -*.tss - -# Telerik's JustMock configuration file -*.jmconfig - -# BizTalk build output -*.btp.cs -*.btm.cs -*.odx.cs -*.xsd.cs - -# OpenCover UI analysis results -OpenCover/ - -# Azure Stream Analytics local run output -ASALocalRun/ - -# MSBuild Binary and Structured Log -*.binlog - -# NVidia Nsight GPU debugger configuration file -*.nvuser - -# MFractors (Xamarin productivity tool) working folder -.mfractor/ - -# Local History for Visual Studio -.localhistory/ - -# BeatPulse healthcheck temp database -healthchecksdb - -# Backup folder for Package Reference Convert tool in Visual Studio 2017 -MigrationBackup/ - -# Ionide (cross platform F# VS Code tools) working folder -.ionide/ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ diff --git a/LICENSE b/LICENSE index c145ba9..7be0290 100644 --- a/LICENSE +++ b/LICENSE @@ -1,21 +1,21 @@ -MIT License - -Copyright (c) 2021 qtKite - -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: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -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. +MIT License + +Copyright (c) 2021 qtKite + +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: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +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. diff --git a/README.md b/README.md index 148e3cb..7ceeda8 100644 --- a/README.md +++ b/README.md @@ -1,386 +1,416 @@ -# defender-control -currently a work in progress - feel free to come back to check on any updates - -## what is this project? -We all know that disabling windefender is a pain going through countless registries. -The next easiest solution is to use freeware and currently the most popular one is by sordum. (i won't link here - you can find it on the first google result) -however, i was first wary of this program and the virus total detections; althought they are claimed to be false positive. -but i know that this program has worked well for me and friends in the past. - -but for those who like open source, i took apart this program and did the research to disable windows defender in an easy open source manner without having to worry about running malware. - -## reversal -Our tool of choice will be IDA & x64 debugger for this task -firstly we are going to inspect the strings and look for anything interesting. -Strings seems to be hidden in this one, so I will do 2 different PoC of attack. -The first one, is to hook the registry functions and output their arguments. Since I know -for a fact after looking at the imports - this program works by writing into relevant registries. - -The second method is to breakpoint each function with x64 debugger and take a look at the strings on runtime. - -I did eventually come up with a third method, and it was to let procmon do its thing while you debug the program - but ill leave that as an exercise for another day. - -## x64 Debug - -### disabling defender - -If we breakpoint onto RegSetKeyValue it writes into "DisableAntiSpyware" which we can research on the internet -There is a lot of occurance with the following registry directory: "Software\\Policies\\Microsoft\\Windows Defender" -It is found under the parent directory of HKLM64. - -```asm -008CE9E8 043DCA88 L"HKLM64" -... -008CEA08 043DCBC0 L"SOFTWARE\\Policies\\Microsoft\\Windows Defender" -``` - -The second breakpoint leads us here: - -```asm -008CE8F0 043DCFE8 L"HKLM64" -... -008CE910 043DD120 L"SYSTEM\\CurrentControlSet\\Services\\WinDefend" -``` - -So taking a look into the registry: SYSTEM\\CurrentControlSet\\Services\\WinDefend -and cross referencing back to x64 dbg: we notice this: - -`76122F7F | 397D 0C | cmp dword ptr ss:[ebp+C],edi | [ebp+C]:L"Start"` - -It appears that 0x03 disables windefender, while 0x02 means to enable. -A quick google search brings us here: https://answers.microsoft.com/en-us/protect/forum/protect_defender-protect_start-windows_10/how-to-disable-windows-defender-in-windows-10/b834d36e-6da8-42a8-85f6-da9a520f05f2 - -The next one is also in HKLM: - -```asm -76122FF0 | 8945 CC | mov dword ptr ss:[ebp-34],eax | [ebp-34]:L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StartupApproved\\Run" -76122FF3 | 66:8B01 | mov ax,word ptr ds:[ecx] | ecx:&L"SecurityHealth" -``` - -Seems to be set to 3 or off - -Now we will look at RegCreateKey -There seems to be a regisatry opened at - -```asm -EDX : 043DCD78 L"SOFTWARE\\Microsoft\\Windows Defender\\Real-Time Protection" -EIP : 7591E420 -``` - -However, there doesnt seem to be anymore functions breakpointed. So lets inspect the directory - -We have 2 flags set: -DisableRealtimeMonitoring as a REG_DWORD set to 0x01 -DpaDisabled as REG_DWORD set to 0x0 - -Another one opened here: - -```asm -008CEFF8 043EB4C8 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StartupApproved\\Run" -``` - -### enabling defender - -there seems to be a reference with "Policy Manager" using RegEnumKeyExW - -It seems to call RegDeleteValueW on security health (see above) - - -## reversing w hooks -We are going to write a simple dll to inject into defender control to dump out the parameters of the functions we are interested in. - -Here are the logs: -``` -obtained RegDeleteKeyW from 75A60000 -obtained RegDeleteValueW from 75A60000 -obtained RegEnumValueW from 75A60000 -obtained RegSetValueExW from 75A60000 -obtained RegCreateKeyExW from 75A60000 -obtained RegConnectRegistryW from 75A60000 -obtained RegEnumKeyExW from 75A60000 -obtained RegQueryValueExW from 75A60000 -obtained RegOpenKeyExW from 75A60000 -imports resolved -preparing to hook - -Registry Routine to check if defender activated: - -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows Defender\Real-Time Protection -[RegQueryValueExW] -lpValueName: DisableRealtimeMonitoring -[RegQueryValueExW] -lpValueName: DisableRealtimeMonitoring -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows Defender\Exclusions\Paths -[RegQueryValueExW] -lpValueName: C:\Program Files (x86)\DefenderControl\dControl.exe - -Routine to disable defender - -[RegCreateKeyExW] -lpSubKey: SOFTWARE\Policies\Microsoft\Windows Defender -[RegSetValueExW] -lpValueName: DisableAntiSpyware -[RegCreateKeyExW] -lpSubKey: SOFTWARE\Microsoft\Windows Defender -[RegCreateKeyExW] -lpSubKey: SOFTWARE\Microsoft\Windows Defender\Real-Time Protection -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows Defender -[RegQueryValueExW] -lpValueName: DisableAntiSpyware -[RegQueryValueExW] -lpValueName: DisableAntiSpyware -[RegCreateKeyExW] -lpSubKey: SYSTEM\CurrentControlSet\Services\WinDefend -[RegSetValueExW] -lpValueName: Start -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows\CurrentVersion\Run -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows\CurrentVersion\Run -[RegQueryValueExW] -lpValueName: SecurityHealth -[RegQueryValueExW] -lpValueName: SecurityHealth -[RegCreateKeyExW] -lpSubKey: SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\StartupApproved\Run -[RegSetValueExW] -lpValueName: SecurityHealth -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows\CurrentVersion\Run -[RegEnumValueW] -lpValueName: SecurityHealth -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows Defender\Real-Time Protection -[RegQueryValueExW] -lpValueName: DisableRealtimeMonitoring -[RegQueryValueExW] -lpValueName: DisableRealtimeMonitoring -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows Defender\Exclusions\Paths -[RegQueryValueExW] -lpValueName: C:\Program Files (x86)\DefenderControl\dControl.exe - -Routine to enable defender - -[RegOpenKeyExW] -lpValueName: SOFTWARE\Policies\Microsoft\Windows Defender -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegOpenKeyExW] -lpValueName: SOFTWARE\Policies\Microsoft\Windows Defender -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows Defender -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows Defender\Real-Time Protection -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows Defender\Real-Time Protection -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows Defender -[RegQueryValueExW] -lpValueName: DisableAntiSpyware -[RegQueryValueExW] -lpValueName: DisableAntiSpyware -[RegOpenKeyExW] -lpValueName: SOFTWARE\Policies\Microsoft\Windows Defender -[RegOpenKeyExW] -lpValueName: SOFTWARE\Policies\Microsoft\Windows Defender -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows Defender -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows Defender\Real-Time Protection -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows Defender\Real-Time Protection -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows Defender -[RegQueryValueExW] -lpValueName: DisableAntiSpyware -[RegQueryValueExW] -lpValueName: DisableAntiSpyware -[RegOpenKeyExW] -lpValueName: SYSTEM\CurrentControlSet\Services\SecLogon -[RegQueryValueExW] -lpValueName: Start -[RegQueryValueExW] -lpValueName: Start -[RegOpenKeyExW] -lpValueName: SOFTWARE\Policies\Microsoft\Windows Defender -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegOpenKeyExW] -lpValueName: SOFTWARE\Policies\Microsoft\Windows Defender -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows Defender -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows Defender\Real-Time Protection -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows Defender\Real-Time Protection -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows Defender -[RegQueryValueExW] -lpValueName: DisableAntiSpyware -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows Defender\Real-Time Protection -[RegQueryValueExW] -lpValueName: DisableRealtimeMonitoring -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows\CurrentVersion\Run -[RegEnumValueW] -lpValueName: SecurityHealth -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows\CurrentVersion\Run -[RegQueryValueExW] -lpValueName: SecurityHealth -[RegQueryValueExW] -lpValueName: SecurityHealth -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\StartupApproved\Run -[RegDeleteValueW] -lpValueNameSecurityHealth -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows\CurrentVersion\Run -[RegEnumValueW] -lpValueName: SecurityHealth -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows\CurrentVersion\Run -[RegQueryValueExW] -lpValueName: WindowsDefender -[RegQueryValueExW] -lpValueName: WindowsDefender -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows\CurrentVersion\Run -[RegEnumValueW] -lpValueName: WindowsDefender -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows Defender\Real-Time Protection -[RegQueryValueExW] -lpValueName: DisableRealtimeMonitoring -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows Defender\Exclusions\Paths -[RegQueryValueExW] -lpValueName: C:\Program Files (x86)\DefenderControl\dControl.exe - -``` - -So by analyzing these logs, it seems that we check if defender is enabled by reading these two registries: -``` -SOFTWARE\Microsoft\Windows Defender\Real-Time Protection -DisableRealtimeMonitoring -``` - -When it disables the AV it modifies these registries: -``` -[RegCreateKeyExW] -lpSubKey: SOFTWARE\Policies\Microsoft\Windows Defender -[RegSetValueExW] -lpValueName: DisableAntiSpyware -[RegCreateKeyExW] -lpSubKey: SOFTWARE\Microsoft\Windows Defender -[RegCreateKeyExW] -lpSubKey: SOFTWARE\Microsoft\Windows Defender\Real-Time Protection -[RegCreateKeyExW] -lpSubKey: SYSTEM\CurrentControlSet\Services\WinDefend -[RegSetValueExW] -lpValueName: Start -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows\CurrentVersion\Run -[RegQueryValueExW] -lpValueName: SecurityHealth -[RegCreateKeyExW] -lpSubKey: SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\StartupApproved\Run -[RegSetValueExW] -lpValueName: SecurityHealth -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows\CurrentVersion\Run -[RegEnumValueW] -lpValueName: SecurityHealth -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows Defender\Real-Time Protection -[RegQueryValueExW] -lpValueName: DisableRealtimeMonitoring -``` - -### Dumping VTable Calls -``` -[Control Table] 0x495b78 -[Control Table] 0x493658 -[Control Table] 0x4932f8 -[Control Table] 0x494e1c -[Control Table] 0x4949e4 -[Control Table] 0x4965e0 -[Control Table] 0x496088 -[Control Table] 0x4951c4 -[Control Table] 0x4960d0 -[Control Table] 0x49463c -[Control Table] 0x493808 -[Control Table] 0x493850 -[Control Table] 0x494ed0 -[Control Table] 0x49382c -[Control Table] 0x49532c -[Control Table] 0x493874 -[Control Table] 0x493898 -[Control Table] 0x4931fc -[Control Table] 0x4931b4 -[Control Table] 0x495500 -[Control Table] 0x495cbc -[Control Table] 0x495ce0 -[Control Table] 0x4958cc -[Control Table] 0x494a74 -[Control Table] 0x495c08 -[Control Table] 0x494cfc -[Control Table] 0x493c40 -[Control Table] 0x493e5c -[Control Table] 0x493ea4 -[Control Table] 0x493b8c -[Control Table] 0x495b0c -[Control Table] 0x495c2c -[Control Table] 0x493f7c -[Control Table] 0x4930dc -[Control Table] 0x493fe8 -[Control Table] 0x494c00 -[Control Table] 0x495644 -[Control Table] 0x495428 -[Control Table] 0x496430 -[Control Table] 0x4963e8 -[Control Table] 0x4954b8 -[Control Table] 0x4945d0 -[Control Table] 0x496040 -[Control Table] 0x4960ac -[Control Table] 0x494a50 -[Control Table] 0x495be4 -``` - -To enable the AV, we just do the opposite of what we needed to disable the AV. - -Upon starting the AV, the program calls CreateProcessW on C:\Windows\System32\SecurityHealthSystray.exe - -## Windows Tamper Protection - -But theres, a catch. In a newer recent windows update - you can no longer disable the defender via registries. Well, our program runs completely in usermode, so there must be another way its making these registry changes - most likely through the powershell command Set-MpPreference if we do some research into changing the registry. So we will need to take a peek into the wmic api it accesses. -Luckily for us, all this stuff is documented. Check out these two links: -- https://docs.microsoft.com/en-us/powershell/module/defender/set-mppreference?view=windowsserver2019-ps -- https://docs.microsoft.com/en-us/windows/win32/wmisdk/wmi-c---application-examples - -So, since its kind of difficult to debug the values DefenderControl accesses and this stuff is pretty well documented - we are going to base our work off research. - -I first wanted to see how powershell called the command, so i looked through the powershell github since its open sourced and found that the command was in a cmdlet that was not documented in the repository. So after reading up on some powershell commands I dumped the powershell informating using this: - -``` -Get-Command Set-MpPreference | fl -``` - -If we wanted to read the MSFT_MpPreference class, it is documented here: -https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/dn455323(v=vs.85)#requirements -We can access via powershell like so: -``` -Get-WmiObject -ClassName MSFT_MpPreference -Namespace root/microsoft/windows/defender -``` -If we look further we can write to this using the WMI as i suspected, it is documented here: -https://docs.microsoft.com/en-us/previous-versions/windows/desktop/defender/windows-defender-wmiv2-apis-portal - - - +# defender-control +currently a work in progress - feel free to come back to check on any updates + +## what is this project? +We all know that disabling windefender is a pain going through countless registries. +The next easiest solution is to use freeware and currently the most popular one is by sordum. (i won't link here - you can find it on the first google result) +however, i was first wary of this program and the virus total detections; althought they are claimed to be false positive. +but i know that this program has worked well for me and friends in the past. + +but for those who like open source, i took apart this program and did the research to disable windows defender in an easy open source manner without having to worry about running malware. + +## reversal +Our tool of choice will be IDA & x64 debugger for this task +firstly we are going to inspect the strings and look for anything interesting. +Strings seems to be hidden in this one, so I will do 2 different PoC of attack. +The first one, is to hook the registry functions and output their arguments. Since I know +for a fact after looking at the imports - this program works by writing into relevant registries. + +The second method is to breakpoint each function with x64 debugger and take a look at the strings on runtime. + +I did eventually come up with a third method, and it was to let procmon do its thing while you debug the program - but ill leave that as an exercise for another day. + +## x64 Debug + +### disabling defender + +If we breakpoint onto RegSetKeyValue it writes into "DisableAntiSpyware" which we can research on the internet +There is a lot of occurance with the following registry directory: "Software\\Policies\\Microsoft\\Windows Defender" +It is found under the parent directory of HKLM64. + +```asm +008CE9E8 043DCA88 L"HKLM64" +... +008CEA08 043DCBC0 L"SOFTWARE\\Policies\\Microsoft\\Windows Defender" +``` + +The second breakpoint leads us here: + +```asm +008CE8F0 043DCFE8 L"HKLM64" +... +008CE910 043DD120 L"SYSTEM\\CurrentControlSet\\Services\\WinDefend" +``` + +So taking a look into the registry: SYSTEM\\CurrentControlSet\\Services\\WinDefend +and cross referencing back to x64 dbg: we notice this: + +`76122F7F | 397D 0C | cmp dword ptr ss:[ebp+C],edi | [ebp+C]:L"Start"` + +It appears that 0x03 disables windefender, while 0x02 means to enable. +A quick google search brings us here: https://answers.microsoft.com/en-us/protect/forum/protect_defender-protect_start-windows_10/how-to-disable-windows-defender-in-windows-10/b834d36e-6da8-42a8-85f6-da9a520f05f2 + +The next one is also in HKLM: + +```asm +76122FF0 | 8945 CC | mov dword ptr ss:[ebp-34],eax | [ebp-34]:L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StartupApproved\\Run" +76122FF3 | 66:8B01 | mov ax,word ptr ds:[ecx] | ecx:&L"SecurityHealth" +``` + +Seems to be set to 3 or off + +Now we will look at RegCreateKey +There seems to be a regisatry opened at + +```asm +EDX : 043DCD78 L"SOFTWARE\\Microsoft\\Windows Defender\\Real-Time Protection" +EIP : 7591E420 +``` + +However, there doesnt seem to be anymore functions breakpointed. So lets inspect the directory + +We have 2 flags set: +DisableRealtimeMonitoring as a REG_DWORD set to 0x01 +DpaDisabled as REG_DWORD set to 0x0 + +Another one opened here: + +```asm +008CEFF8 043EB4C8 L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StartupApproved\\Run" +``` + +### enabling defender + +there seems to be a reference with "Policy Manager" using RegEnumKeyExW + +It seems to call RegDeleteValueW on security health (see above) + + +## reversing w hooks +We are going to write a simple dll to inject into defender control to dump out the parameters of the functions we are interested in. + +Here are the logs: +``` +obtained RegDeleteKeyW from 75A60000 +obtained RegDeleteValueW from 75A60000 +obtained RegEnumValueW from 75A60000 +obtained RegSetValueExW from 75A60000 +obtained RegCreateKeyExW from 75A60000 +obtained RegConnectRegistryW from 75A60000 +obtained RegEnumKeyExW from 75A60000 +obtained RegQueryValueExW from 75A60000 +obtained RegOpenKeyExW from 75A60000 +imports resolved +preparing to hook + +Registry Routine to check if defender activated: + +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows Defender\Real-Time Protection +[RegQueryValueExW] +lpValueName: DisableRealtimeMonitoring +[RegQueryValueExW] +lpValueName: DisableRealtimeMonitoring +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows Defender\Exclusions\Paths +[RegQueryValueExW] +lpValueName: C:\Program Files (x86)\DefenderControl\dControl.exe + +Routine to disable defender + +[RegCreateKeyExW] +lpSubKey: SOFTWARE\Policies\Microsoft\Windows Defender +[RegSetValueExW] +lpValueName: DisableAntiSpyware +[RegCreateKeyExW] +lpSubKey: SOFTWARE\Microsoft\Windows Defender +[RegCreateKeyExW] +lpSubKey: SOFTWARE\Microsoft\Windows Defender\Real-Time Protection +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows Defender +[RegQueryValueExW] +lpValueName: DisableAntiSpyware +[RegQueryValueExW] +lpValueName: DisableAntiSpyware +[RegCreateKeyExW] +lpSubKey: SYSTEM\CurrentControlSet\Services\WinDefend +[RegSetValueExW] +lpValueName: Start +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows\CurrentVersion\Run +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows\CurrentVersion\Run +[RegQueryValueExW] +lpValueName: SecurityHealth +[RegQueryValueExW] +lpValueName: SecurityHealth +[RegCreateKeyExW] +lpSubKey: SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\StartupApproved\Run +[RegSetValueExW] +lpValueName: SecurityHealth +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows\CurrentVersion\Run +[RegEnumValueW] +lpValueName: SecurityHealth +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows Defender\Real-Time Protection +[RegQueryValueExW] +lpValueName: DisableRealtimeMonitoring +[RegQueryValueExW] +lpValueName: DisableRealtimeMonitoring +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows Defender\Exclusions\Paths +[RegQueryValueExW] +lpValueName: C:\Program Files (x86)\DefenderControl\dControl.exe + +Routine to enable defender + +[RegOpenKeyExW] +lpValueName: SOFTWARE\Policies\Microsoft\Windows Defender +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegOpenKeyExW] +lpValueName: SOFTWARE\Policies\Microsoft\Windows Defender +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows Defender +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows Defender\Real-Time Protection +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows Defender\Real-Time Protection +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows Defender +[RegQueryValueExW] +lpValueName: DisableAntiSpyware +[RegQueryValueExW] +lpValueName: DisableAntiSpyware +[RegOpenKeyExW] +lpValueName: SOFTWARE\Policies\Microsoft\Windows Defender +[RegOpenKeyExW] +lpValueName: SOFTWARE\Policies\Microsoft\Windows Defender +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows Defender +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows Defender\Real-Time Protection +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows Defender\Real-Time Protection +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows Defender +[RegQueryValueExW] +lpValueName: DisableAntiSpyware +[RegQueryValueExW] +lpValueName: DisableAntiSpyware +[RegOpenKeyExW] +lpValueName: SYSTEM\CurrentControlSet\Services\SecLogon +[RegQueryValueExW] +lpValueName: Start +[RegQueryValueExW] +lpValueName: Start +[RegOpenKeyExW] +lpValueName: SOFTWARE\Policies\Microsoft\Windows Defender +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegOpenKeyExW] +lpValueName: SOFTWARE\Policies\Microsoft\Windows Defender +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows Defender +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows Defender\Real-Time Protection +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows Defender\Real-Time Protection +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows Defender +[RegQueryValueExW] +lpValueName: DisableAntiSpyware +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows Defender\Real-Time Protection +[RegQueryValueExW] +lpValueName: DisableRealtimeMonitoring +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows\CurrentVersion\Run +[RegEnumValueW] +lpValueName: SecurityHealth +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows\CurrentVersion\Run +[RegQueryValueExW] +lpValueName: SecurityHealth +[RegQueryValueExW] +lpValueName: SecurityHealth +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\StartupApproved\Run +[RegDeleteValueW] +lpValueNameSecurityHealth +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows\CurrentVersion\Run +[RegEnumValueW] +lpValueName: SecurityHealth +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows\CurrentVersion\Run +[RegQueryValueExW] +lpValueName: WindowsDefender +[RegQueryValueExW] +lpValueName: WindowsDefender +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows\CurrentVersion\Run +[RegEnumValueW] +lpValueName: WindowsDefender +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows Defender\Real-Time Protection +[RegQueryValueExW] +lpValueName: DisableRealtimeMonitoring +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows Defender\Exclusions\Paths +[RegQueryValueExW] +lpValueName: C:\Program Files (x86)\DefenderControl\dControl.exe + +``` + +So by analyzing these logs, it seems that we check if defender is enabled by reading these two registries: +``` +SOFTWARE\Microsoft\Windows Defender\Real-Time Protection +DisableRealtimeMonitoring +``` + +When it disables the AV it modifies these registries: +``` +[RegCreateKeyExW] +lpSubKey: SOFTWARE\Policies\Microsoft\Windows Defender +[RegSetValueExW] +lpValueName: DisableAntiSpyware +[RegCreateKeyExW] +lpSubKey: SOFTWARE\Microsoft\Windows Defender +[RegCreateKeyExW] +lpSubKey: SOFTWARE\Microsoft\Windows Defender\Real-Time Protection +[RegCreateKeyExW] +lpSubKey: SYSTEM\CurrentControlSet\Services\WinDefend +[RegSetValueExW] +lpValueName: Start +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows\CurrentVersion\Run +[RegQueryValueExW] +lpValueName: SecurityHealth +[RegCreateKeyExW] +lpSubKey: SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\StartupApproved\Run +[RegSetValueExW] +lpValueName: SecurityHealth +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows\CurrentVersion\Run +[RegEnumValueW] +lpValueName: SecurityHealth +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows Defender\Real-Time Protection +[RegQueryValueExW] +lpValueName: DisableRealtimeMonitoring +``` + +### Dumping VTable Calls +``` +[Control Table] 0x495b78 +[Control Table] 0x493658 +[Control Table] 0x4932f8 +[Control Table] 0x494e1c +[Control Table] 0x4949e4 +[Control Table] 0x4965e0 +[Control Table] 0x496088 +[Control Table] 0x4951c4 +[Control Table] 0x4960d0 +[Control Table] 0x49463c +[Control Table] 0x493808 +[Control Table] 0x493850 +[Control Table] 0x494ed0 +[Control Table] 0x49382c +[Control Table] 0x49532c +[Control Table] 0x493874 +[Control Table] 0x493898 +[Control Table] 0x4931fc +[Control Table] 0x4931b4 +[Control Table] 0x495500 +[Control Table] 0x495cbc +[Control Table] 0x495ce0 +[Control Table] 0x4958cc +[Control Table] 0x494a74 +[Control Table] 0x495c08 +[Control Table] 0x494cfc +[Control Table] 0x493c40 +[Control Table] 0x493e5c +[Control Table] 0x493ea4 +[Control Table] 0x493b8c +[Control Table] 0x495b0c +[Control Table] 0x495c2c +[Control Table] 0x493f7c +[Control Table] 0x4930dc +[Control Table] 0x493fe8 +[Control Table] 0x494c00 +[Control Table] 0x495644 +[Control Table] 0x495428 +[Control Table] 0x496430 +[Control Table] 0x4963e8 +[Control Table] 0x4954b8 +[Control Table] 0x4945d0 +[Control Table] 0x496040 +[Control Table] 0x4960ac +[Control Table] 0x494a50 +[Control Table] 0x495be4 +``` + +To enable the AV, we just do the opposite of what we needed to disable the AV. + +Upon starting the AV, the program calls CreateProcessW on C:\Windows\System32\SecurityHealthSystray.exe + +## Windows Tamper Protection + +But theres, a catch. In a newer recent windows update - you can no longer disable the defender via registries. Well, our program runs completely in usermode, so there must be another way its making these registry changes - most likely through the powershell command Set-MpPreference if we do some research into changing the registry. So we will need to take a peek into the wmic api it accesses. +Luckily for us, all this stuff is documented. Check out these two links: +- https://docs.microsoft.com/en-us/powershell/module/defender/set-mppreference?view=windowsserver2019-ps +- https://docs.microsoft.com/en-us/windows/win32/wmisdk/wmi-c---application-examples + +So, since its kind of difficult to debug the values DefenderControl accesses and this stuff is pretty well documented - we are going to base our work off research. + +I first wanted to see how powershell called the command, so i looked through the powershell github since its open sourced and found that the command was in a cmdlet that was not documented in the repository. So after reading up on some powershell commands I dumped the powershell informating using this: + +``` +Get-Command Set-MpPreference | fl +e`` + +If we wanted to read the MSFT_MpPreference class, it is documented here: +https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/dn455323(v=vs.85)#requirements +We can access via powershell like so: +``` +Get-WmiObject -ClassName MSFT_MpPreference -Namespace root/microsoft/windows/defender +``` +If we look further we can write to this using the WMI as i suspected, it is documented here: +https://docs.microsoft.com/en-us/previous-versions/windows/desktop/defender/windows-defender-wmiv2-apis-portal + +We can find the specific wmi com classes if we do the following command: + +``` +MpPreference |fl * +``` + +We get an output and we are intrested in this: +``` +CimClass : root/Microsoft/Windows/Defender:MSFT_MpPreference +CimInstanceProperties : {AllowDatagramProcessingOnWinServer, AllowNetworkProtectionDownLevel, + AllowNetworkProtectionOnWinServer, + AttackSurfaceReductionOnlyExclusions...} +CimSystemProperties : Microsoft.Management.Infrastructure.CimSystemProperties +``` + +We can find the class here: https://docs.microsoft.com/en-us/dotnet/api/microsoft.management.infrastructure.cimsystemproperties?view=powershellsdk-7.0.0 + +It is also located in windows binaries in the following path: C:\Program Files (x86)\Reference Assemblies\Microsoft\WMI\v1.0 + + + + + + + + + + + + + + diff --git a/logs.MD b/logs.MD index 99d7758..357be39 100644 --- a/logs.MD +++ b/logs.MD @@ -1,524 +1,524 @@ -Here is the complete log dump cleaned: -``` -obtained RegDeleteKeyW from 75A60000 -obtained RegDeleteValueW from 75A60000 -obtained RegEnumValueW from 75A60000 -obtained RegSetValueExW from 75A60000 -obtained RegCreateKeyExW from 75A60000 -obtained RegConnectRegistryW from 75A60000 -obtained RegEnumKeyExW from 75A60000 -obtained RegQueryValueExW from 75A60000 -obtained RegOpenKeyExW from 75A60000 -imports resolved -preparing to hook - -Check for AV: - -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows Defender\Real-Time Protection -[RegQueryValueExW] -lpValueName: DisableRealtimeMonitoring -[RegQueryValueExW] -lpValueName: DisableRealtimeMonitoring -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows Defender\Exclusions\Paths -[RegQueryValueExW] -lpValueName: C:\Program Files (x86)\DefenderControl\dControl.exe - -Disable AV: - -[RegCreateKeyExW] -lpSubKey: SOFTWARE\Policies\Microsoft\Windows Defender -[RegSetValueExW] -lpValueName: DisableAntiSpyware -[RegCreateKeyExW] -lpSubKey: SOFTWARE\Microsoft\Windows Defender -[RegCreateKeyExW] -lpSubKey: SOFTWARE\Microsoft\Windows Defender\Real-Time Protection -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows Defender -[RegQueryValueExW] -lpValueName: DisableAntiSpyware -[RegQueryValueExW] -lpValueName: DisableAntiSpyware -[RegCreateKeyExW] -lpSubKey: SYSTEM\CurrentControlSet\Services\WinDefend -[RegSetValueExW] -lpValueName: Start -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows\CurrentVersion\Run -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows\CurrentVersion\Run -[RegQueryValueExW] -lpValueName: SecurityHealth -[RegQueryValueExW] -lpValueName: SecurityHealth -[RegCreateKeyExW] -lpSubKey: SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\StartupApproved\Run -[RegSetValueExW] -lpValueName: SecurityHealth -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows\CurrentVersion\Run -[RegEnumValueW] -lpValueName: SecurityHealth -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows Defender\Real-Time Protection -[RegQueryValueExW] -lpValueName: DisableRealtimeMonitoring -[RegQueryValueExW] -lpValueName: DisableRealtimeMonitoring -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows Defender\Exclusions\Paths -[RegQueryValueExW] -lpValueName: C:\Program Files (x86)\DefenderControl\dControl.exe - -Enable AV: - -[RegOpenKeyExW] -lpValueName: SOFTWARE\Policies\Microsoft\Windows Defender -[RegEnumKeyExW] -lpName: ☺ -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: SOFTWARE\Policies\Microsoft\Windows Defender -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows Defender -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows Defender\Real-Time Protection -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows Defender\Real-Time Protection -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows Defender -[RegQueryValueExW] -lpValueName: DisableAntiSpyware -[RegQueryValueExW] -lpValueName: DisableAntiSpyware -[RegOpenKeyExW] -lpValueName: SOFTWARE\Policies\Microsoft\Windows Defender -[RegOpenKeyExW] -lpValueName: SOFTWARE\Policies\Microsoft\Windows Defender -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows Defender -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows Defender\Real-Time Protection -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows Defender\Real-Time Protection -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows Defender -[RegQueryValueExW] -lpValueName: DisableAntiSpyware -[RegQueryValueExW] -lpValueName: DisableAntiSpyware -[RegOpenKeyExW] -lpValueName: SYSTEM\CurrentControlSet\Services\SecLogon -[RegQueryValueExW] -lpValueName: Start -[RegQueryValueExW] -lpValueName: Start -[RegOpenKeyExW] -lpValueName: SOFTWARE\Policies\Microsoft\Windows Defender -[RegEnumKeyExW] -lpName: ☺ -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: SOFTWARE\Policies\Microsoft\Windows Defender -[RegEnumKeyExW] -lpName: ☺ -[RegOpenKeyExW] -lpValueName: Policy Manager -[RegEnumKeyExW] -lpName: ☺ -[RegEnumKeyExW] -lpName: Policy Manager -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows Defender -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows Defender\Real-Time Protection -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows Defender\Real-Time Protection -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows Defender -[RegQueryValueExW] -lpValueName: DisableAntiSpyware -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows Defender\Real-Time Protection -[RegQueryValueExW] -lpValueName: DisableRealtimeMonitoring -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows\CurrentVersion\Run -[RegEnumValueW] -lpValueName: SecurityHealth -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows\CurrentVersion\Run -[RegQueryValueExW] -lpValueName: SecurityHealth -[RegQueryValueExW] -lpValueName: SecurityHealth -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\StartupApproved\Run -[RegDeleteValueW] -lpValueNameSecurityHealth -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows\CurrentVersion\Run -[RegEnumValueW] -lpValueName: SecurityHealth -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows\CurrentVersion\Run -[RegQueryValueExW] -lpValueName: WindowsDefender -[RegQueryValueExW] -lpValueName: WindowsDefender -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows\CurrentVersion\Run -[RegEnumValueW] -lpValueName: WindowsDefender -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows Defender\Real-Time Protection -[RegQueryValueExW] -lpValueName: DisableRealtimeMonitoring -[RegOpenKeyExW] -lpValueName: SOFTWARE\Microsoft\Windows Defender\Exclusions\Paths -[RegQueryValueExW] -lpValueName: C:\Program Files (x86)\DefenderControl\dControl.exe -[RegOpenKeyExW] +Here is the complete log dump cleaned: +``` +obtained RegDeleteKeyW from 75A60000 +obtained RegDeleteValueW from 75A60000 +obtained RegEnumValueW from 75A60000 +obtained RegSetValueExW from 75A60000 +obtained RegCreateKeyExW from 75A60000 +obtained RegConnectRegistryW from 75A60000 +obtained RegEnumKeyExW from 75A60000 +obtained RegQueryValueExW from 75A60000 +obtained RegOpenKeyExW from 75A60000 +imports resolved +preparing to hook + +Check for AV: + +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows Defender\Real-Time Protection +[RegQueryValueExW] +lpValueName: DisableRealtimeMonitoring +[RegQueryValueExW] +lpValueName: DisableRealtimeMonitoring +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows Defender\Exclusions\Paths +[RegQueryValueExW] +lpValueName: C:\Program Files (x86)\DefenderControl\dControl.exe + +Disable AV: + +[RegCreateKeyExW] +lpSubKey: SOFTWARE\Policies\Microsoft\Windows Defender +[RegSetValueExW] +lpValueName: DisableAntiSpyware +[RegCreateKeyExW] +lpSubKey: SOFTWARE\Microsoft\Windows Defender +[RegCreateKeyExW] +lpSubKey: SOFTWARE\Microsoft\Windows Defender\Real-Time Protection +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows Defender +[RegQueryValueExW] +lpValueName: DisableAntiSpyware +[RegQueryValueExW] +lpValueName: DisableAntiSpyware +[RegCreateKeyExW] +lpSubKey: SYSTEM\CurrentControlSet\Services\WinDefend +[RegSetValueExW] +lpValueName: Start +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows\CurrentVersion\Run +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows\CurrentVersion\Run +[RegQueryValueExW] +lpValueName: SecurityHealth +[RegQueryValueExW] +lpValueName: SecurityHealth +[RegCreateKeyExW] +lpSubKey: SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\StartupApproved\Run +[RegSetValueExW] +lpValueName: SecurityHealth +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows\CurrentVersion\Run +[RegEnumValueW] +lpValueName: SecurityHealth +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows Defender\Real-Time Protection +[RegQueryValueExW] +lpValueName: DisableRealtimeMonitoring +[RegQueryValueExW] +lpValueName: DisableRealtimeMonitoring +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows Defender\Exclusions\Paths +[RegQueryValueExW] +lpValueName: C:\Program Files (x86)\DefenderControl\dControl.exe + +Enable AV: + +[RegOpenKeyExW] +lpValueName: SOFTWARE\Policies\Microsoft\Windows Defender +[RegEnumKeyExW] +lpName: ☺ +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: SOFTWARE\Policies\Microsoft\Windows Defender +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows Defender +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows Defender\Real-Time Protection +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows Defender\Real-Time Protection +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows Defender +[RegQueryValueExW] +lpValueName: DisableAntiSpyware +[RegQueryValueExW] +lpValueName: DisableAntiSpyware +[RegOpenKeyExW] +lpValueName: SOFTWARE\Policies\Microsoft\Windows Defender +[RegOpenKeyExW] +lpValueName: SOFTWARE\Policies\Microsoft\Windows Defender +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows Defender +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows Defender\Real-Time Protection +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows Defender\Real-Time Protection +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows Defender +[RegQueryValueExW] +lpValueName: DisableAntiSpyware +[RegQueryValueExW] +lpValueName: DisableAntiSpyware +[RegOpenKeyExW] +lpValueName: SYSTEM\CurrentControlSet\Services\SecLogon +[RegQueryValueExW] +lpValueName: Start +[RegQueryValueExW] +lpValueName: Start +[RegOpenKeyExW] +lpValueName: SOFTWARE\Policies\Microsoft\Windows Defender +[RegEnumKeyExW] +lpName: ☺ +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: SOFTWARE\Policies\Microsoft\Windows Defender +[RegEnumKeyExW] +lpName: ☺ +[RegOpenKeyExW] +lpValueName: Policy Manager +[RegEnumKeyExW] +lpName: ☺ +[RegEnumKeyExW] +lpName: Policy Manager +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows Defender +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows Defender\Real-Time Protection +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows Defender\Real-Time Protection +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows Defender +[RegQueryValueExW] +lpValueName: DisableAntiSpyware +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows Defender\Real-Time Protection +[RegQueryValueExW] +lpValueName: DisableRealtimeMonitoring +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows\CurrentVersion\Run +[RegEnumValueW] +lpValueName: SecurityHealth +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows\CurrentVersion\Run +[RegQueryValueExW] +lpValueName: SecurityHealth +[RegQueryValueExW] +lpValueName: SecurityHealth +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\StartupApproved\Run +[RegDeleteValueW] +lpValueNameSecurityHealth +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows\CurrentVersion\Run +[RegEnumValueW] +lpValueName: SecurityHealth +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows\CurrentVersion\Run +[RegQueryValueExW] +lpValueName: WindowsDefender +[RegQueryValueExW] +lpValueName: WindowsDefender +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows\CurrentVersion\Run +[RegEnumValueW] +lpValueName: WindowsDefender +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows Defender\Real-Time Protection +[RegQueryValueExW] +lpValueName: DisableRealtimeMonitoring +[RegOpenKeyExW] +lpValueName: SOFTWARE\Microsoft\Windows Defender\Exclusions\Paths +[RegQueryValueExW] +lpValueName: C:\Program Files (x86)\DefenderControl\dControl.exe +[RegOpenKeyExW] ``` \ No newline at end of file diff --git a/src/defender-control.sln b/src/defender-control.sln index ec52df4..e4106c7 100644 --- a/src/defender-control.sln +++ b/src/defender-control.sln @@ -1,41 +1,41 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.31229.75 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "defender-control", "defender-control\defender-control.vcxproj", "{7C2C0AEC-7B9D-4104-99FA-1844D609452C}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dumper", "dumper\dumper.vcxproj", "{089CA7D6-3277-4998-86AF-F6413290A442}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {7C2C0AEC-7B9D-4104-99FA-1844D609452C}.Debug|x64.ActiveCfg = Debug|x64 - {7C2C0AEC-7B9D-4104-99FA-1844D609452C}.Debug|x64.Build.0 = Debug|x64 - {7C2C0AEC-7B9D-4104-99FA-1844D609452C}.Debug|x86.ActiveCfg = Debug|Win32 - {7C2C0AEC-7B9D-4104-99FA-1844D609452C}.Debug|x86.Build.0 = Debug|Win32 - {7C2C0AEC-7B9D-4104-99FA-1844D609452C}.Release|x64.ActiveCfg = Release|x64 - {7C2C0AEC-7B9D-4104-99FA-1844D609452C}.Release|x64.Build.0 = Release|x64 - {7C2C0AEC-7B9D-4104-99FA-1844D609452C}.Release|x86.ActiveCfg = Release|Win32 - {7C2C0AEC-7B9D-4104-99FA-1844D609452C}.Release|x86.Build.0 = Release|Win32 - {089CA7D6-3277-4998-86AF-F6413290A442}.Debug|x64.ActiveCfg = Debug|x64 - {089CA7D6-3277-4998-86AF-F6413290A442}.Debug|x64.Build.0 = Debug|x64 - {089CA7D6-3277-4998-86AF-F6413290A442}.Debug|x86.ActiveCfg = Debug|Win32 - {089CA7D6-3277-4998-86AF-F6413290A442}.Debug|x86.Build.0 = Debug|Win32 - {089CA7D6-3277-4998-86AF-F6413290A442}.Release|x64.ActiveCfg = Release|x64 - {089CA7D6-3277-4998-86AF-F6413290A442}.Release|x64.Build.0 = Release|x64 - {089CA7D6-3277-4998-86AF-F6413290A442}.Release|x86.ActiveCfg = Release|Win32 - {089CA7D6-3277-4998-86AF-F6413290A442}.Release|x86.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {708A26F9-CBFF-49C9-8F9D-1C62AF49488E} - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31229.75 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "defender-control", "defender-control\defender-control.vcxproj", "{7C2C0AEC-7B9D-4104-99FA-1844D609452C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dumper", "dumper\dumper.vcxproj", "{089CA7D6-3277-4998-86AF-F6413290A442}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {7C2C0AEC-7B9D-4104-99FA-1844D609452C}.Debug|x64.ActiveCfg = Debug|x64 + {7C2C0AEC-7B9D-4104-99FA-1844D609452C}.Debug|x64.Build.0 = Debug|x64 + {7C2C0AEC-7B9D-4104-99FA-1844D609452C}.Debug|x86.ActiveCfg = Debug|Win32 + {7C2C0AEC-7B9D-4104-99FA-1844D609452C}.Debug|x86.Build.0 = Debug|Win32 + {7C2C0AEC-7B9D-4104-99FA-1844D609452C}.Release|x64.ActiveCfg = Release|x64 + {7C2C0AEC-7B9D-4104-99FA-1844D609452C}.Release|x64.Build.0 = Release|x64 + {7C2C0AEC-7B9D-4104-99FA-1844D609452C}.Release|x86.ActiveCfg = Release|Win32 + {7C2C0AEC-7B9D-4104-99FA-1844D609452C}.Release|x86.Build.0 = Release|Win32 + {089CA7D6-3277-4998-86AF-F6413290A442}.Debug|x64.ActiveCfg = Debug|x64 + {089CA7D6-3277-4998-86AF-F6413290A442}.Debug|x64.Build.0 = Debug|x64 + {089CA7D6-3277-4998-86AF-F6413290A442}.Debug|x86.ActiveCfg = Debug|Win32 + {089CA7D6-3277-4998-86AF-F6413290A442}.Debug|x86.Build.0 = Debug|Win32 + {089CA7D6-3277-4998-86AF-F6413290A442}.Release|x64.ActiveCfg = Release|x64 + {089CA7D6-3277-4998-86AF-F6413290A442}.Release|x64.Build.0 = Release|x64 + {089CA7D6-3277-4998-86AF-F6413290A442}.Release|x86.ActiveCfg = Release|Win32 + {089CA7D6-3277-4998-86AF-F6413290A442}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {708A26F9-CBFF-49C9-8F9D-1C62AF49488E} + EndGlobalSection +EndGlobal diff --git a/src/defender-control/dcontrol.cpp b/src/defender-control/dcontrol.cpp index 24790da..373e7ef 100644 --- a/src/defender-control/dcontrol.cpp +++ b/src/defender-control/dcontrol.cpp @@ -1,287 +1,287 @@ -#include "dcontrol.h" - -namespace REG -{ - // reads a key from HKEY_LOCAL_MACHINE - // - DWORD read_key(const wchar_t* root_name, const wchar_t* value_name, uint32_t flags) - { - LSTATUS status; - HKEY hkey; - DWORD result{}; - DWORD buff_sz = sizeof(DWORD); - - // https://docs.microsoft.com/en-us/windows/win32/winprog64/accessing-an-alternate-registry-view - - status = RegOpenKeyExW( - HKEY_LOCAL_MACHINE, - root_name, - 0, - KEY_READ | KEY_WOW64_64KEY, - &hkey - ); - - if (status) - { - if (flags & DBG_MSG) - std::cout << "Error opening " << root_name << " key" << std::endl; - - return -1; - } - - status = RegQueryValueExW( - hkey, - value_name, - 0, NULL, - reinterpret_cast(&result), - &buff_sz - ); - - if (status) - { - if (flags & DBG_MSG) - std::cout << "Failed to read " << result << std::endl; - - return -1; - } - - RegCloseKey(hkey); - - return result; - } - - // creates a registry in HKEY_LOCAL_MACHINE with KEY_ALL_ACCESS permissions - // - bool create_registry(const wchar_t* root_name, HKEY& hkey) - { - LSTATUS status; - - DWORD dwDisposition; - - status = RegCreateKeyExW( - HKEY_LOCAL_MACHINE, - root_name, - 0, - 0, - 0, - 131334, - 0, - &hkey, - &dwDisposition - ); - - if (status) - { - std::wcout << "could not find or create " << root_name << " error: " << status << std::endl; - return false; - } - - return true; - } - - bool set_keyval(HKEY& hkey, const wchar_t* value_name, DWORD value) - { - auto ret = RegSetValueExW(hkey, value_name, 0, REG_DWORD, - reinterpret_cast(&value), 4); - - if (ret) - { - std::cout << "Set error: " << ret << std::endl; - return false; - } - - return true; - } - - bool set_keyval_bin(HKEY& hkey, const wchar_t* value_name, DWORD value) - { - auto ret = RegSetValueExW(hkey, value_name, 0, REG_BINARY, - reinterpret_cast(&value), 12); - - if (ret) - { - std::cout << "Set error: " << ret << std::endl; - return false; - } - return true; - } -} - -namespace WMIC -{ -} - -namespace DCONTROL -{ - // Sets the programs debug priviliges - bool set_privilege(LPCSTR privilege, BOOL enable) - { - TOKEN_PRIVILEGES priv = { 0,0,0,0 }; - HANDLE token = nullptr; - LUID luid = { 0,0 }; - - if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token)) - { - if (token) - CloseHandle(token); - - return false; - } - - if (!LookupPrivilegeValueA(nullptr, SE_DEBUG_NAME, &luid)) - { - if (token) - CloseHandle(token); - - return false; - } - priv.PrivilegeCount = 1; - priv.Privileges[0].Luid = luid; - priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; - - if (!AdjustTokenPrivileges(token, false, &priv, 0, nullptr, nullptr)) - { - if (token) - CloseHandle(token); - - return false; - } - if (token) - CloseHandle(token); - - return true; - } - - char sub_43604B() - { - char v0; // bl - SC_HANDLE v1; // eax - SC_HANDLE v2; // esi - void* v3; // eax - - v0 = 0; - v1 = OpenSCManagerW(0, 0, 8u); - v2 = v1; - if (v1) - { - v3 = LockServiceDatabase(v1); - if (v3) - { - UnlockServiceDatabase(v3); - CloseServiceHandle(v2); - return 1; - } - if (GetLastError() == 1055) - v0 = 1; - CloseServiceHandle(v2); - } - return v0; - } - - // disables window defender - // - bool disable_defender() - { - if (!sub_43604B()) - { - std::cout << "permission error" << std::endl; - return false; - } - - set_privilege(SE_DEBUG_NAME, TRUE); - - HKEY hkey; - - // DisableAntiSpyware - { - if (!REG::create_registry(L"SOFTWARE\\Policies\\Microsoft\\Windows Defender", hkey)) - { - std::cout << "failed to access Policies" << std::endl; - return false; - } - - if (!REG::set_keyval(hkey, L"DisableAntiSpyware", 1)) - { - std::cout << "failed to write to DisableAntiSpyware" << std::endl; - return false; - } - -#if 0 - if (!REG::create_registry(L"SOFTWARE\\Microsoft\\Windows Defender", hkey)) - { - std::cout << "failed to access Windows Defender" << std::endl; - return false; - } - - if (!REG::set_keyval(hkey, L"DisableAntiSpyware", 1)) - { - std::cout << "failed to write to DisableAntiSpyware" << std::endl; - return false; - } -#endif - } - - // Start (3 off) (2 on) - { - if (!REG::create_registry(L"SYSTEM\\CurrentControlSet\\Services\\WinDefend", hkey)) - { - std::cout << "failed to access CurrentControlSet" << std::endl; - return false; - } - - if (!REG::set_keyval(hkey, L"Start", 3)) - { - std::cout << "failed to write to Start" << std::endl; - return false; - } - } - - std::cout << "Wrote to Start" << std::endl; - - - // SecurityHealth - { - if (!REG::create_registry(L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StartupApproved\\Run", hkey)) - { - std::cout << "failed to access CurrentVersion" << std::endl; - return false; - } - - if (!REG::set_keyval_bin(hkey, L"SecurityHealth", 3)) - { - std::cout << "failed to write to SecurityHealth" << std::endl; - return false; - } - } - - std::cout << "Wrote to SecurityHealth" << std::endl; - - -#if 0 - // DisableRealtimeMonitoring - { - if (!REG::create_registry(L"SOFTWARE\\Microsoft\\Windows Defender\\Real-Time Protection", hkey)) - { - std::cout << "failed to access registry" << std::endl; - return false; - } - if (!REG::set_keyval(hkey, L"DisableRealtimeMonitoring", 1)) - { - std::cout << "failed to disable DisableRealtimeMonitoring" << std::endl; - return false; - } -} -#endif - - return true; - } - - // Checks whether Real-Time Protection is activated on windows - // - bool check_defender(uint32_t flags) - { - return REG::read_key( - L"SOFTWARE\\Microsoft\\Windows Defender\\Real-Time Protection", - L"DisableRealtimeMonitoring") == 0; - } +#include "dcontrol.h" + +namespace REG +{ + // reads a key from HKEY_LOCAL_MACHINE + // + DWORD read_key(const wchar_t* root_name, const wchar_t* value_name, uint32_t flags) + { + LSTATUS status; + HKEY hkey; + DWORD result{}; + DWORD buff_sz = sizeof(DWORD); + + // https://docs.microsoft.com/en-us/windows/win32/winprog64/accessing-an-alternate-registry-view + + status = RegOpenKeyExW( + HKEY_LOCAL_MACHINE, + root_name, + 0, + KEY_READ | KEY_WOW64_64KEY, + &hkey + ); + + if (status) + { + if (flags & DBG_MSG) + std::cout << "Error opening " << root_name << " key" << std::endl; + + return -1; + } + + status = RegQueryValueExW( + hkey, + value_name, + 0, NULL, + reinterpret_cast(&result), + &buff_sz + ); + + if (status) + { + if (flags & DBG_MSG) + std::cout << "Failed to read " << result << std::endl; + + return -1; + } + + RegCloseKey(hkey); + + return result; + } + + // creates a registry in HKEY_LOCAL_MACHINE with KEY_ALL_ACCESS permissions + // + bool create_registry(const wchar_t* root_name, HKEY& hkey) + { + LSTATUS status; + + DWORD dwDisposition; + + status = RegCreateKeyExW( + HKEY_LOCAL_MACHINE, + root_name, + 0, + 0, + 0, + 131334, + 0, + &hkey, + &dwDisposition + ); + + if (status) + { + std::wcout << "could not find or create " << root_name << " error: " << status << std::endl; + return false; + } + + return true; + } + + bool set_keyval(HKEY& hkey, const wchar_t* value_name, DWORD value) + { + auto ret = RegSetValueExW(hkey, value_name, 0, REG_DWORD, + reinterpret_cast(&value), 4); + + if (ret) + { + std::cout << "Set error: " << ret << std::endl; + return false; + } + + return true; + } + + bool set_keyval_bin(HKEY& hkey, const wchar_t* value_name, DWORD value) + { + auto ret = RegSetValueExW(hkey, value_name, 0, REG_BINARY, + reinterpret_cast(&value), 12); + + if (ret) + { + std::cout << "Set error: " << ret << std::endl; + return false; + } + return true; + } +} + +namespace WMIC +{ +} + +namespace DCONTROL +{ + // Sets the programs debug priviliges + bool set_privilege(LPCSTR privilege, BOOL enable) + { + TOKEN_PRIVILEGES priv = { 0,0,0,0 }; + HANDLE token = nullptr; + LUID luid = { 0,0 }; + + if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token)) + { + if (token) + CloseHandle(token); + + return false; + } + + if (!LookupPrivilegeValueA(nullptr, SE_DEBUG_NAME, &luid)) + { + if (token) + CloseHandle(token); + + return false; + } + priv.PrivilegeCount = 1; + priv.Privileges[0].Luid = luid; + priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + + if (!AdjustTokenPrivileges(token, false, &priv, 0, nullptr, nullptr)) + { + if (token) + CloseHandle(token); + + return false; + } + if (token) + CloseHandle(token); + + return true; + } + + char sub_43604B() + { + char v0; // bl + SC_HANDLE v1; // eax + SC_HANDLE v2; // esi + void* v3; // eax + + v0 = 0; + v1 = OpenSCManagerW(0, 0, 8u); + v2 = v1; + if (v1) + { + v3 = LockServiceDatabase(v1); + if (v3) + { + UnlockServiceDatabase(v3); + CloseServiceHandle(v2); + return 1; + } + if (GetLastError() == 1055) + v0 = 1; + CloseServiceHandle(v2); + } + return v0; + } + + // disables window defender + // + bool disable_defender() + { + if (!sub_43604B()) + { + std::cout << "permission error" << std::endl; + return false; + } + + set_privilege(SE_DEBUG_NAME, TRUE); + + HKEY hkey; + + // DisableAntiSpyware + { + if (!REG::create_registry(L"SOFTWARE\\Policies\\Microsoft\\Windows Defender", hkey)) + { + std::cout << "failed to access Policies" << std::endl; + return false; + } + + if (!REG::set_keyval(hkey, L"DisableAntiSpyware", 1)) + { + std::cout << "failed to write to DisableAntiSpyware" << std::endl; + return false; + } + +#if 0 + if (!REG::create_registry(L"SOFTWARE\\Microsoft\\Windows Defender", hkey)) + { + std::cout << "failed to access Windows Defender" << std::endl; + return false; + } + + if (!REG::set_keyval(hkey, L"DisableAntiSpyware", 1)) + { + std::cout << "failed to write to DisableAntiSpyware" << std::endl; + return false; + } +#endif + } + + // Start (3 off) (2 on) + { + if (!REG::create_registry(L"SYSTEM\\CurrentControlSet\\Services\\WinDefend", hkey)) + { + std::cout << "failed to access CurrentControlSet" << std::endl; + return false; + } + + if (!REG::set_keyval(hkey, L"Start", 3)) + { + std::cout << "failed to write to Start" << std::endl; + return false; + } + } + + std::cout << "Wrote to Start" << std::endl; + + + // SecurityHealth + { + if (!REG::create_registry(L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StartupApproved\\Run", hkey)) + { + std::cout << "failed to access CurrentVersion" << std::endl; + return false; + } + + if (!REG::set_keyval_bin(hkey, L"SecurityHealth", 3)) + { + std::cout << "failed to write to SecurityHealth" << std::endl; + return false; + } + } + + std::cout << "Wrote to SecurityHealth" << std::endl; + + +#if 0 + // DisableRealtimeMonitoring + { + if (!REG::create_registry(L"SOFTWARE\\Microsoft\\Windows Defender\\Real-Time Protection", hkey)) + { + std::cout << "failed to access registry" << std::endl; + return false; + } + if (!REG::set_keyval(hkey, L"DisableRealtimeMonitoring", 1)) + { + std::cout << "failed to disable DisableRealtimeMonitoring" << std::endl; + return false; + } +} +#endif + + return true; + } + + // Checks whether Real-Time Protection is activated on windows + // + bool check_defender(uint32_t flags) + { + return REG::read_key( + L"SOFTWARE\\Microsoft\\Windows Defender\\Real-Time Protection", + L"DisableRealtimeMonitoring") == 0; + } } \ No newline at end of file diff --git a/src/defender-control/dcontrol.h b/src/defender-control/dcontrol.h index 14af5f1..1c6f7b1 100644 --- a/src/defender-control/dcontrol.h +++ b/src/defender-control/dcontrol.h @@ -1,20 +1,20 @@ -#pragma once - -#include -#include - -#define DBG_MSG (1 << 0) - -namespace REG -{ - DWORD read_key(const wchar_t* root_name, const wchar_t* value_name, uint32_t flags = 0); - bool create_registry(const wchar_t* root_name, HKEY& hkey); - bool set_keyval(HKEY& hkey, const wchar_t* value_name, DWORD value); - bool set_keyval_bin(HKEY& hkey, const wchar_t* value_name, DWORD value); -} - -namespace DCONTROL -{ - bool disable_defender(); - bool check_defender(uint32_t flags = 0); +#pragma once + +#include +#include + +#define DBG_MSG (1 << 0) + +namespace REG +{ + DWORD read_key(const wchar_t* root_name, const wchar_t* value_name, uint32_t flags = 0); + bool create_registry(const wchar_t* root_name, HKEY& hkey); + bool set_keyval(HKEY& hkey, const wchar_t* value_name, DWORD value); + bool set_keyval_bin(HKEY& hkey, const wchar_t* value_name, DWORD value); +} + +namespace DCONTROL +{ + bool disable_defender(); + bool check_defender(uint32_t flags = 0); } \ No newline at end of file diff --git a/src/defender-control/defender-control.vcxproj b/src/defender-control/defender-control.vcxproj index 9ebc782..796e510 100644 --- a/src/defender-control/defender-control.vcxproj +++ b/src/defender-control/defender-control.vcxproj @@ -1,153 +1,153 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 16.0 - Win32Proj - {7c2c0aec-7b9d-4104-99fa-1844d609452c} - defendercontrol - 10.0 - - - - Application - true - v142 - Unicode - - - Application - false - v142 - true - MultiByte - - - Application - true - v142 - Unicode - - - Application - false - v142 - true - Unicode - - - - - - - - - - - - - - - - - - - - - true - - - false - - - true - - - false - $(Platform)\$(Configuration) - - - - Level3 - true - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Console - true - - - - - Level3 - true - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Console - true - true - true - RequireAdministrator - - - - - Level3 - true - _DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Console - true - - - - - Level3 - true - true - true - NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Console - true - true - true - - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {7c2c0aec-7b9d-4104-99fa-1844d609452c} + defendercontrol + 10.0 + + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + MultiByte + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + + + false + $(Platform)\$(Configuration) + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + RequireAdministrator + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + + + + \ No newline at end of file diff --git a/src/defender-control/defender-control.vcxproj.filters b/src/defender-control/defender-control.vcxproj.filters index cdb1f07..6d614a9 100644 --- a/src/defender-control/defender-control.vcxproj.filters +++ b/src/defender-control/defender-control.vcxproj.filters @@ -1,33 +1,33 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - {8a88e18b-d3f3-447e-a3b0-9867c153c3c1} - - - - - Source Files - - - Source Files\defender-control - - - - - Source Files\defender-control - - + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {8a88e18b-d3f3-447e-a3b0-9867c153c3c1} + + + + + Source Files + + + Source Files\defender-control + + + + + Source Files\defender-control + + \ No newline at end of file diff --git a/src/defender-control/main.cpp b/src/defender-control/main.cpp index 53c897a..81c27b7 100644 --- a/src/defender-control/main.cpp +++ b/src/defender-control/main.cpp @@ -1,23 +1,23 @@ -#include "dcontrol.h" - -// to-do: -// write argument parser -// create cli program -// maybe make a ui for this - -// entrypoint -// -int main() -{ - printf(DCONTROL::check_defender() ? - "Windows defender is ACTIVE\n" : - "Windows defender is OFF\n"); - - printf(DCONTROL::disable_defender() ? - "Defender disabled\n" : - "Failed to disable\n"); - - system("pause"); - - return 0; -} +#include "dcontrol.h" + +// to-do: +// write argument parser +// create cli program +// maybe make a ui for this + +// entrypoint +// +int main() +{ + printf(DCONTROL::check_defender() ? + "Windows defender is ACTIVE\n" : + "Windows defender is OFF\n"); + + printf(DCONTROL::disable_defender() ? + "Defender disabled\n" : + "Failed to disable\n"); + + system("pause"); + + return 0; +} diff --git a/src/detour/64/include/detours.h b/src/detour/64/include/detours.h index 47dd3ea..b02165b 100644 --- a/src/detour/64/include/detours.h +++ b/src/detour/64/include/detours.h @@ -1,1209 +1,1209 @@ -///////////////////////////////////////////////////////////////////////////// -// -// Core Detours Functionality (detours.h of detours.lib) -// -// Microsoft Research Detours Package, Version 4.0.1 -// -// Copyright (c) Microsoft Corporation. All rights reserved. -// - -#pragma once -#ifndef _DETOURS_H_ -#define _DETOURS_H_ - -#define DETOURS_VERSION 0x4c0c1 // 0xMAJORcMINORcPATCH - -////////////////////////////////////////////////////////////////////////////// -// - -#ifdef DETOURS_INTERNAL - -#define _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS 1 -#define _ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE 1 - -#pragma warning(disable:4068) // unknown pragma (suppress) - -#if _MSC_VER >= 1900 -#pragma warning(push) -#pragma warning(disable:4091) // empty typedef -#endif - -// Suppress declspec(dllimport) for the sake of Detours -// users that provide kernel32 functionality themselves. -// This is ok in the mainstream case, it will just cost -// an extra instruction calling some functions, which -// LTCG optimizes away. -// -#define _KERNEL32_ 1 -#define _USER32_ 1 - -#include -#if (_MSC_VER < 1310) -#else -#pragma warning(push) -#if _MSC_VER > 1400 -#pragma warning(disable:6102 6103) // /analyze warnings -#endif -#include -#include -#pragma warning(pop) -#endif - -// Allow Detours to cleanly compile with the MingW toolchain. -// -#ifdef __GNUC__ -#define __try -#define __except(x) if (0) -#include -#endif - -// From winerror.h, as this error isn't found in some SDKs: -// -// MessageId: ERROR_DYNAMIC_CODE_BLOCKED -// -// MessageText: -// -// The operation was blocked as the process prohibits dynamic code generation. -// -#define ERROR_DYNAMIC_CODE_BLOCKED 1655L - -#endif // DETOURS_INTERNAL - -////////////////////////////////////////////////////////////////////////////// -// - -#undef DETOURS_X64 -#undef DETOURS_X86 -#undef DETOURS_IA64 -#undef DETOURS_ARM -#undef DETOURS_ARM64 -#undef DETOURS_BITS -#undef DETOURS_32BIT -#undef DETOURS_64BIT - -#if defined(_X86_) -#define DETOURS_X86 -#define DETOURS_OPTION_BITS 64 - -#elif defined(_AMD64_) -#define DETOURS_X64 -#define DETOURS_OPTION_BITS 32 - -#elif defined(_IA64_) -#define DETOURS_IA64 -#define DETOURS_OPTION_BITS 32 - -#elif defined(_ARM_) -#define DETOURS_ARM - -#elif defined(_ARM64_) -#define DETOURS_ARM64 - -#else -#error Unknown architecture (x86, amd64, ia64, arm, arm64) -#endif - -#ifdef _WIN64 -#undef DETOURS_32BIT -#define DETOURS_64BIT 1 -#define DETOURS_BITS 64 -// If all 64bit kernels can run one and only one 32bit architecture. -//#define DETOURS_OPTION_BITS 32 -#else -#define DETOURS_32BIT 1 -#undef DETOURS_64BIT -#define DETOURS_BITS 32 -// If all 64bit kernels can run one and only one 32bit architecture. -//#define DETOURS_OPTION_BITS 32 -#endif - -/////////////////////////////////////////////////////////////// Helper Macros. -// -#define DETOURS_STRINGIFY_(x) #x -#define DETOURS_STRINGIFY(x) DETOURS_STRINGIFY_(x) - -#define VER_DETOURS_BITS DETOURS_STRINGIFY(DETOURS_BITS) - -////////////////////////////////////////////////////////////////////////////// -// - -#if (_MSC_VER < 1299) && !defined(__MINGW32__) -typedef LONG LONG_PTR; -typedef ULONG ULONG_PTR; -#endif - -///////////////////////////////////////////////// SAL 2.0 Annotations w/o SAL. -// -// These definitions are include so that Detours will build even if the -// compiler doesn't have full SAL 2.0 support. -// -#ifndef DETOURS_DONT_REMOVE_SAL_20 - -#ifdef DETOURS_TEST_REMOVE_SAL_20 -#undef _Analysis_assume_ -#undef _Benign_race_begin_ -#undef _Benign_race_end_ -#undef _Field_range_ -#undef _Field_size_ -#undef _In_ -#undef _In_bytecount_ -#undef _In_count_ -#undef __in_ecount -#undef _In_opt_ -#undef _In_opt_bytecount_ -#undef _In_opt_count_ -#undef _In_opt_z_ -#undef _In_range_ -#undef _In_reads_ -#undef _In_reads_bytes_ -#undef _In_reads_opt_ -#undef _In_reads_opt_bytes_ -#undef _In_reads_or_z_ -#undef _In_z_ -#undef _Inout_ -#undef _Inout_opt_ -#undef _Inout_z_count_ -#undef _Out_ -#undef _Out_opt_ -#undef _Out_writes_ -#undef _Outptr_result_maybenull_ -#undef _Readable_bytes_ -#undef _Success_ -#undef _Writable_bytes_ -#undef _Pre_notnull_ -#endif - -#if defined(_Deref_out_opt_z_) && !defined(_Outptr_result_maybenull_) -#define _Outptr_result_maybenull_ _Deref_out_opt_z_ -#endif - -#if defined(_In_count_) && !defined(_In_reads_) -#define _In_reads_(x) _In_count_(x) -#endif - -#if defined(_In_opt_count_) && !defined(_In_reads_opt_) -#define _In_reads_opt_(x) _In_opt_count_(x) -#endif - -#if defined(_In_opt_bytecount_) && !defined(_In_reads_opt_bytes_) -#define _In_reads_opt_bytes_(x) _In_opt_bytecount_(x) -#endif - -#if defined(_In_bytecount_) && !defined(_In_reads_bytes_) -#define _In_reads_bytes_(x) _In_bytecount_(x) -#endif - -#ifndef _In_ -#define _In_ -#endif - -#ifndef _In_bytecount_ -#define _In_bytecount_(x) -#endif - -#ifndef _In_count_ -#define _In_count_(x) -#endif - -#ifndef __in_ecount -#define __in_ecount(x) -#endif - -#ifndef _In_opt_ -#define _In_opt_ -#endif - -#ifndef _In_opt_bytecount_ -#define _In_opt_bytecount_(x) -#endif - -#ifndef _In_opt_count_ -#define _In_opt_count_(x) -#endif - -#ifndef _In_opt_z_ -#define _In_opt_z_ -#endif - -#ifndef _In_range_ -#define _In_range_(x,y) -#endif - -#ifndef _In_reads_ -#define _In_reads_(x) -#endif - -#ifndef _In_reads_bytes_ -#define _In_reads_bytes_(x) -#endif - -#ifndef _In_reads_opt_ -#define _In_reads_opt_(x) -#endif - -#ifndef _In_reads_opt_bytes_ -#define _In_reads_opt_bytes_(x) -#endif - -#ifndef _In_reads_or_z_ -#define _In_reads_or_z_ -#endif - -#ifndef _In_z_ -#define _In_z_ -#endif - -#ifndef _Inout_ -#define _Inout_ -#endif - -#ifndef _Inout_opt_ -#define _Inout_opt_ -#endif - -#ifndef _Inout_z_count_ -#define _Inout_z_count_(x) -#endif - -#ifndef _Out_ -#define _Out_ -#endif - -#ifndef _Out_opt_ -#define _Out_opt_ -#endif - -#ifndef _Out_writes_ -#define _Out_writes_(x) -#endif - -#ifndef _Outptr_result_maybenull_ -#define _Outptr_result_maybenull_ -#endif - -#ifndef _Writable_bytes_ -#define _Writable_bytes_(x) -#endif - -#ifndef _Readable_bytes_ -#define _Readable_bytes_(x) -#endif - -#ifndef _Success_ -#define _Success_(x) -#endif - -#ifndef _Pre_notnull_ -#define _Pre_notnull_ -#endif - -#ifdef DETOURS_INTERNAL - -#pragma warning(disable:4615) // unknown warning type (suppress with older compilers) - -#ifndef _Benign_race_begin_ -#define _Benign_race_begin_ -#endif - -#ifndef _Benign_race_end_ -#define _Benign_race_end_ -#endif - -#ifndef _Field_size_ -#define _Field_size_(x) -#endif - -#ifndef _Field_range_ -#define _Field_range_(x,y) -#endif - -#ifndef _Analysis_assume_ -#define _Analysis_assume_(x) -#endif - -#endif // DETOURS_INTERNAL -#endif // DETOURS_DONT_REMOVE_SAL_20 - -////////////////////////////////////////////////////////////////////////////// -// -#ifndef GUID_DEFINED -#define GUID_DEFINED -typedef struct _GUID -{ - DWORD Data1; - WORD Data2; - WORD Data3; - BYTE Data4[ 8 ]; -} GUID; - -#ifdef INITGUID -#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ - const GUID name \ - = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } -#else -#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ - const GUID name -#endif // INITGUID -#endif // !GUID_DEFINED - -#if defined(__cplusplus) -#ifndef _REFGUID_DEFINED -#define _REFGUID_DEFINED -#define REFGUID const GUID & -#endif // !_REFGUID_DEFINED -#else // !__cplusplus -#ifndef _REFGUID_DEFINED -#define _REFGUID_DEFINED -#define REFGUID const GUID * const -#endif // !_REFGUID_DEFINED -#endif // !__cplusplus - -#ifndef ARRAYSIZE -#define ARRAYSIZE(x) (sizeof(x)/sizeof(x[0])) -#endif - -// -////////////////////////////////////////////////////////////////////////////// - -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus - -/////////////////////////////////////////////////// Instruction Target Macros. -// -#define DETOUR_INSTRUCTION_TARGET_NONE ((PVOID)0) -#define DETOUR_INSTRUCTION_TARGET_DYNAMIC ((PVOID)(LONG_PTR)-1) -#define DETOUR_SECTION_HEADER_SIGNATURE 0x00727444 // "Dtr\0" - -extern const GUID DETOUR_EXE_RESTORE_GUID; -extern const GUID DETOUR_EXE_HELPER_GUID; - -#define DETOUR_TRAMPOLINE_SIGNATURE 0x21727444 // Dtr! -typedef struct _DETOUR_TRAMPOLINE DETOUR_TRAMPOLINE, *PDETOUR_TRAMPOLINE; - -/////////////////////////////////////////////////////////// Binary Structures. -// -#pragma pack(push, 8) -typedef struct _DETOUR_SECTION_HEADER -{ - DWORD cbHeaderSize; - DWORD nSignature; - DWORD nDataOffset; - DWORD cbDataSize; - - DWORD nOriginalImportVirtualAddress; - DWORD nOriginalImportSize; - DWORD nOriginalBoundImportVirtualAddress; - DWORD nOriginalBoundImportSize; - - DWORD nOriginalIatVirtualAddress; - DWORD nOriginalIatSize; - DWORD nOriginalSizeOfImage; - DWORD cbPrePE; - - DWORD nOriginalClrFlags; - DWORD reserved1; - DWORD reserved2; - DWORD reserved3; - - // Followed by cbPrePE bytes of data. -} DETOUR_SECTION_HEADER, *PDETOUR_SECTION_HEADER; - -typedef struct _DETOUR_SECTION_RECORD -{ - DWORD cbBytes; - DWORD nReserved; - GUID guid; -} DETOUR_SECTION_RECORD, *PDETOUR_SECTION_RECORD; - -typedef struct _DETOUR_CLR_HEADER -{ - // Header versioning - ULONG cb; - USHORT MajorRuntimeVersion; - USHORT MinorRuntimeVersion; - - // Symbol table and startup information - IMAGE_DATA_DIRECTORY MetaData; - ULONG Flags; - - // Followed by the rest of the IMAGE_COR20_HEADER -} DETOUR_CLR_HEADER, *PDETOUR_CLR_HEADER; - -typedef struct _DETOUR_EXE_RESTORE -{ - DWORD cb; - DWORD cbidh; - DWORD cbinh; - DWORD cbclr; - - PBYTE pidh; - PBYTE pinh; - PBYTE pclr; - - IMAGE_DOS_HEADER idh; - union { - IMAGE_NT_HEADERS inh; // all environments have this -#ifdef IMAGE_NT_OPTIONAL_HDR32_MAGIC // some environments do not have this - IMAGE_NT_HEADERS32 inh32; -#endif -#ifdef IMAGE_NT_OPTIONAL_HDR64_MAGIC // some environments do not have this - IMAGE_NT_HEADERS64 inh64; -#endif -#ifdef IMAGE_NT_OPTIONAL_HDR64_MAGIC // some environments do not have this - BYTE raw[sizeof(IMAGE_NT_HEADERS64) + - sizeof(IMAGE_SECTION_HEADER) * 32]; -#else - BYTE raw[0x108 + sizeof(IMAGE_SECTION_HEADER) * 32]; -#endif - }; - DETOUR_CLR_HEADER clr; - -} DETOUR_EXE_RESTORE, *PDETOUR_EXE_RESTORE; - -#ifdef IMAGE_NT_OPTIONAL_HDR64_MAGIC -C_ASSERT(sizeof(IMAGE_NT_HEADERS64) == 0x108); -#endif - -// The size can change, but assert for clarity due to the muddying #ifdefs. -#ifdef _WIN64 -C_ASSERT(sizeof(DETOUR_EXE_RESTORE) == 0x688); -#else -C_ASSERT(sizeof(DETOUR_EXE_RESTORE) == 0x678); -#endif - -typedef struct _DETOUR_EXE_HELPER -{ - DWORD cb; - DWORD pid; - DWORD nDlls; - CHAR rDlls[4]; -} DETOUR_EXE_HELPER, *PDETOUR_EXE_HELPER; - -#pragma pack(pop) - -#define DETOUR_SECTION_HEADER_DECLARE(cbSectionSize) \ -{ \ - sizeof(DETOUR_SECTION_HEADER),\ - DETOUR_SECTION_HEADER_SIGNATURE,\ - sizeof(DETOUR_SECTION_HEADER),\ - (cbSectionSize),\ - \ - 0,\ - 0,\ - 0,\ - 0,\ - \ - 0,\ - 0,\ - 0,\ - 0,\ -} - -///////////////////////////////////////////////////////////// Binary Typedefs. -// -typedef BOOL (CALLBACK *PF_DETOUR_BINARY_BYWAY_CALLBACK)( - _In_opt_ PVOID pContext, - _In_opt_ LPCSTR pszFile, - _Outptr_result_maybenull_ LPCSTR *ppszOutFile); - -typedef BOOL (CALLBACK *PF_DETOUR_BINARY_FILE_CALLBACK)( - _In_opt_ PVOID pContext, - _In_ LPCSTR pszOrigFile, - _In_ LPCSTR pszFile, - _Outptr_result_maybenull_ LPCSTR *ppszOutFile); - -typedef BOOL (CALLBACK *PF_DETOUR_BINARY_SYMBOL_CALLBACK)( - _In_opt_ PVOID pContext, - _In_ ULONG nOrigOrdinal, - _In_ ULONG nOrdinal, - _Out_ ULONG *pnOutOrdinal, - _In_opt_ LPCSTR pszOrigSymbol, - _In_opt_ LPCSTR pszSymbol, - _Outptr_result_maybenull_ LPCSTR *ppszOutSymbol); - -typedef BOOL (CALLBACK *PF_DETOUR_BINARY_COMMIT_CALLBACK)( - _In_opt_ PVOID pContext); - -typedef BOOL (CALLBACK *PF_DETOUR_ENUMERATE_EXPORT_CALLBACK)(_In_opt_ PVOID pContext, - _In_ ULONG nOrdinal, - _In_opt_ LPCSTR pszName, - _In_opt_ PVOID pCode); - -typedef BOOL (CALLBACK *PF_DETOUR_IMPORT_FILE_CALLBACK)(_In_opt_ PVOID pContext, - _In_opt_ HMODULE hModule, - _In_opt_ LPCSTR pszFile); - -typedef BOOL (CALLBACK *PF_DETOUR_IMPORT_FUNC_CALLBACK)(_In_opt_ PVOID pContext, - _In_ DWORD nOrdinal, - _In_opt_ LPCSTR pszFunc, - _In_opt_ PVOID pvFunc); - -// Same as PF_DETOUR_IMPORT_FUNC_CALLBACK but extra indirection on last parameter. -typedef BOOL (CALLBACK *PF_DETOUR_IMPORT_FUNC_CALLBACK_EX)(_In_opt_ PVOID pContext, - _In_ DWORD nOrdinal, - _In_opt_ LPCSTR pszFunc, - _In_opt_ PVOID* ppvFunc); - -typedef VOID * PDETOUR_BINARY; -typedef VOID * PDETOUR_LOADED_BINARY; - -//////////////////////////////////////////////////////////// Transaction APIs. -// -LONG WINAPI DetourTransactionBegin(VOID); -LONG WINAPI DetourTransactionAbort(VOID); -LONG WINAPI DetourTransactionCommit(VOID); -LONG WINAPI DetourTransactionCommitEx(_Out_opt_ PVOID **pppFailedPointer); - -LONG WINAPI DetourUpdateThread(_In_ HANDLE hThread); - -LONG WINAPI DetourAttach(_Inout_ PVOID *ppPointer, - _In_ PVOID pDetour); - -LONG WINAPI DetourAttachEx(_Inout_ PVOID *ppPointer, - _In_ PVOID pDetour, - _Out_opt_ PDETOUR_TRAMPOLINE *ppRealTrampoline, - _Out_opt_ PVOID *ppRealTarget, - _Out_opt_ PVOID *ppRealDetour); - -LONG WINAPI DetourDetach(_Inout_ PVOID *ppPointer, - _In_ PVOID pDetour); - -BOOL WINAPI DetourSetIgnoreTooSmall(_In_ BOOL fIgnore); -BOOL WINAPI DetourSetRetainRegions(_In_ BOOL fRetain); -PVOID WINAPI DetourSetSystemRegionLowerBound(_In_ PVOID pSystemRegionLowerBound); -PVOID WINAPI DetourSetSystemRegionUpperBound(_In_ PVOID pSystemRegionUpperBound); - -////////////////////////////////////////////////////////////// Code Functions. -// -PVOID WINAPI DetourFindFunction(_In_ LPCSTR pszModule, - _In_ LPCSTR pszFunction); -PVOID WINAPI DetourCodeFromPointer(_In_ PVOID pPointer, - _Out_opt_ PVOID *ppGlobals); -PVOID WINAPI DetourCopyInstruction(_In_opt_ PVOID pDst, - _Inout_opt_ PVOID *ppDstPool, - _In_ PVOID pSrc, - _Out_opt_ PVOID *ppTarget, - _Out_opt_ LONG *plExtra); -BOOL WINAPI DetourSetCodeModule(_In_ HMODULE hModule, - _In_ BOOL fLimitReferencesToModule); -PVOID WINAPI DetourAllocateRegionWithinJumpBounds(_In_ LPCVOID pbTarget, - _Out_ PDWORD pcbAllocatedSize); - -///////////////////////////////////////////////////// Loaded Binary Functions. -// -HMODULE WINAPI DetourGetContainingModule(_In_ PVOID pvAddr); -HMODULE WINAPI DetourEnumerateModules(_In_opt_ HMODULE hModuleLast); -PVOID WINAPI DetourGetEntryPoint(_In_opt_ HMODULE hModule); -ULONG WINAPI DetourGetModuleSize(_In_opt_ HMODULE hModule); -BOOL WINAPI DetourEnumerateExports(_In_ HMODULE hModule, - _In_opt_ PVOID pContext, - _In_ PF_DETOUR_ENUMERATE_EXPORT_CALLBACK pfExport); -BOOL WINAPI DetourEnumerateImports(_In_opt_ HMODULE hModule, - _In_opt_ PVOID pContext, - _In_opt_ PF_DETOUR_IMPORT_FILE_CALLBACK pfImportFile, - _In_opt_ PF_DETOUR_IMPORT_FUNC_CALLBACK pfImportFunc); - -BOOL WINAPI DetourEnumerateImportsEx(_In_opt_ HMODULE hModule, - _In_opt_ PVOID pContext, - _In_opt_ PF_DETOUR_IMPORT_FILE_CALLBACK pfImportFile, - _In_opt_ PF_DETOUR_IMPORT_FUNC_CALLBACK_EX pfImportFuncEx); - -_Writable_bytes_(*pcbData) -_Readable_bytes_(*pcbData) -_Success_(return != NULL) -PVOID WINAPI DetourFindPayload(_In_opt_ HMODULE hModule, - _In_ REFGUID rguid, - _Out_opt_ DWORD *pcbData); - -_Writable_bytes_(*pcbData) -_Readable_bytes_(*pcbData) -_Success_(return != NULL) -PVOID WINAPI DetourFindPayloadEx(_In_ REFGUID rguid, - _Out_opt_ DWORD *pcbData); - -DWORD WINAPI DetourGetSizeOfPayloads(_In_opt_ HMODULE hModule); - -///////////////////////////////////////////////// Persistent Binary Functions. -// - -PDETOUR_BINARY WINAPI DetourBinaryOpen(_In_ HANDLE hFile); - -_Writable_bytes_(*pcbData) -_Readable_bytes_(*pcbData) -_Success_(return != NULL) -PVOID WINAPI DetourBinaryEnumeratePayloads(_In_ PDETOUR_BINARY pBinary, - _Out_opt_ GUID *pGuid, - _Out_ DWORD *pcbData, - _Inout_ DWORD *pnIterator); - -_Writable_bytes_(*pcbData) -_Readable_bytes_(*pcbData) -_Success_(return != NULL) -PVOID WINAPI DetourBinaryFindPayload(_In_ PDETOUR_BINARY pBinary, - _In_ REFGUID rguid, - _Out_ DWORD *pcbData); - -PVOID WINAPI DetourBinarySetPayload(_In_ PDETOUR_BINARY pBinary, - _In_ REFGUID rguid, - _In_reads_opt_(cbData) PVOID pData, - _In_ DWORD cbData); -BOOL WINAPI DetourBinaryDeletePayload(_In_ PDETOUR_BINARY pBinary, _In_ REFGUID rguid); -BOOL WINAPI DetourBinaryPurgePayloads(_In_ PDETOUR_BINARY pBinary); -BOOL WINAPI DetourBinaryResetImports(_In_ PDETOUR_BINARY pBinary); -BOOL WINAPI DetourBinaryEditImports(_In_ PDETOUR_BINARY pBinary, - _In_opt_ PVOID pContext, - _In_opt_ PF_DETOUR_BINARY_BYWAY_CALLBACK pfByway, - _In_opt_ PF_DETOUR_BINARY_FILE_CALLBACK pfFile, - _In_opt_ PF_DETOUR_BINARY_SYMBOL_CALLBACK pfSymbol, - _In_opt_ PF_DETOUR_BINARY_COMMIT_CALLBACK pfCommit); -BOOL WINAPI DetourBinaryWrite(_In_ PDETOUR_BINARY pBinary, _In_ HANDLE hFile); -BOOL WINAPI DetourBinaryClose(_In_ PDETOUR_BINARY pBinary); - -/////////////////////////////////////////////////// Create Process & Load Dll. -// -_Success_(return != NULL) -PVOID WINAPI DetourFindRemotePayload(_In_ HANDLE hProcess, - _In_ REFGUID rguid, - _Out_opt_ DWORD *pcbData); - -typedef BOOL (WINAPI *PDETOUR_CREATE_PROCESS_ROUTINEA)( - _In_opt_ LPCSTR lpApplicationName, - _Inout_opt_ LPSTR lpCommandLine, - _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, - _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, - _In_ BOOL bInheritHandles, - _In_ DWORD dwCreationFlags, - _In_opt_ LPVOID lpEnvironment, - _In_opt_ LPCSTR lpCurrentDirectory, - _In_ LPSTARTUPINFOA lpStartupInfo, - _Out_ LPPROCESS_INFORMATION lpProcessInformation); - -typedef BOOL (WINAPI *PDETOUR_CREATE_PROCESS_ROUTINEW)( - _In_opt_ LPCWSTR lpApplicationName, - _Inout_opt_ LPWSTR lpCommandLine, - _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, - _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, - _In_ BOOL bInheritHandles, - _In_ DWORD dwCreationFlags, - _In_opt_ LPVOID lpEnvironment, - _In_opt_ LPCWSTR lpCurrentDirectory, - _In_ LPSTARTUPINFOW lpStartupInfo, - _Out_ LPPROCESS_INFORMATION lpProcessInformation); - -BOOL WINAPI DetourCreateProcessWithDllA(_In_opt_ LPCSTR lpApplicationName, - _Inout_opt_ LPSTR lpCommandLine, - _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, - _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, - _In_ BOOL bInheritHandles, - _In_ DWORD dwCreationFlags, - _In_opt_ LPVOID lpEnvironment, - _In_opt_ LPCSTR lpCurrentDirectory, - _In_ LPSTARTUPINFOA lpStartupInfo, - _Out_ LPPROCESS_INFORMATION lpProcessInformation, - _In_ LPCSTR lpDllName, - _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); - -BOOL WINAPI DetourCreateProcessWithDllW(_In_opt_ LPCWSTR lpApplicationName, - _Inout_opt_ LPWSTR lpCommandLine, - _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, - _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, - _In_ BOOL bInheritHandles, - _In_ DWORD dwCreationFlags, - _In_opt_ LPVOID lpEnvironment, - _In_opt_ LPCWSTR lpCurrentDirectory, - _In_ LPSTARTUPINFOW lpStartupInfo, - _Out_ LPPROCESS_INFORMATION lpProcessInformation, - _In_ LPCSTR lpDllName, - _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); - -#ifdef UNICODE -#define DetourCreateProcessWithDll DetourCreateProcessWithDllW -#define PDETOUR_CREATE_PROCESS_ROUTINE PDETOUR_CREATE_PROCESS_ROUTINEW -#else -#define DetourCreateProcessWithDll DetourCreateProcessWithDllA -#define PDETOUR_CREATE_PROCESS_ROUTINE PDETOUR_CREATE_PROCESS_ROUTINEA -#endif // !UNICODE - -BOOL WINAPI DetourCreateProcessWithDllExA(_In_opt_ LPCSTR lpApplicationName, - _Inout_opt_ LPSTR lpCommandLine, - _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, - _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, - _In_ BOOL bInheritHandles, - _In_ DWORD dwCreationFlags, - _In_opt_ LPVOID lpEnvironment, - _In_opt_ LPCSTR lpCurrentDirectory, - _In_ LPSTARTUPINFOA lpStartupInfo, - _Out_ LPPROCESS_INFORMATION lpProcessInformation, - _In_ LPCSTR lpDllName, - _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); - -BOOL WINAPI DetourCreateProcessWithDllExW(_In_opt_ LPCWSTR lpApplicationName, - _Inout_opt_ LPWSTR lpCommandLine, - _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, - _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, - _In_ BOOL bInheritHandles, - _In_ DWORD dwCreationFlags, - _In_opt_ LPVOID lpEnvironment, - _In_opt_ LPCWSTR lpCurrentDirectory, - _In_ LPSTARTUPINFOW lpStartupInfo, - _Out_ LPPROCESS_INFORMATION lpProcessInformation, - _In_ LPCSTR lpDllName, - _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); - -#ifdef UNICODE -#define DetourCreateProcessWithDllEx DetourCreateProcessWithDllExW -#else -#define DetourCreateProcessWithDllEx DetourCreateProcessWithDllExA -#endif // !UNICODE - -BOOL WINAPI DetourCreateProcessWithDllsA(_In_opt_ LPCSTR lpApplicationName, - _Inout_opt_ LPSTR lpCommandLine, - _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, - _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, - _In_ BOOL bInheritHandles, - _In_ DWORD dwCreationFlags, - _In_opt_ LPVOID lpEnvironment, - _In_opt_ LPCSTR lpCurrentDirectory, - _In_ LPSTARTUPINFOA lpStartupInfo, - _Out_ LPPROCESS_INFORMATION lpProcessInformation, - _In_ DWORD nDlls, - _In_reads_(nDlls) LPCSTR *rlpDlls, - _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); - -BOOL WINAPI DetourCreateProcessWithDllsW(_In_opt_ LPCWSTR lpApplicationName, - _Inout_opt_ LPWSTR lpCommandLine, - _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, - _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, - _In_ BOOL bInheritHandles, - _In_ DWORD dwCreationFlags, - _In_opt_ LPVOID lpEnvironment, - _In_opt_ LPCWSTR lpCurrentDirectory, - _In_ LPSTARTUPINFOW lpStartupInfo, - _Out_ LPPROCESS_INFORMATION lpProcessInformation, - _In_ DWORD nDlls, - _In_reads_(nDlls) LPCSTR *rlpDlls, - _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); - -#ifdef UNICODE -#define DetourCreateProcessWithDlls DetourCreateProcessWithDllsW -#else -#define DetourCreateProcessWithDlls DetourCreateProcessWithDllsA -#endif // !UNICODE - -BOOL WINAPI DetourProcessViaHelperA(_In_ DWORD dwTargetPid, - _In_ LPCSTR lpDllName, - _In_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); - -BOOL WINAPI DetourProcessViaHelperW(_In_ DWORD dwTargetPid, - _In_ LPCSTR lpDllName, - _In_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); - -#ifdef UNICODE -#define DetourProcessViaHelper DetourProcessViaHelperW -#else -#define DetourProcessViaHelper DetourProcessViaHelperA -#endif // !UNICODE - -BOOL WINAPI DetourProcessViaHelperDllsA(_In_ DWORD dwTargetPid, - _In_ DWORD nDlls, - _In_reads_(nDlls) LPCSTR *rlpDlls, - _In_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); - -BOOL WINAPI DetourProcessViaHelperDllsW(_In_ DWORD dwTargetPid, - _In_ DWORD nDlls, - _In_reads_(nDlls) LPCSTR *rlpDlls, - _In_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); - -#ifdef UNICODE -#define DetourProcessViaHelperDlls DetourProcessViaHelperDllsW -#else -#define DetourProcessViaHelperDlls DetourProcessViaHelperDllsA -#endif // !UNICODE - -BOOL WINAPI DetourUpdateProcessWithDll(_In_ HANDLE hProcess, - _In_reads_(nDlls) LPCSTR *rlpDlls, - _In_ DWORD nDlls); - -BOOL WINAPI DetourUpdateProcessWithDllEx(_In_ HANDLE hProcess, - _In_ HMODULE hImage, - _In_ BOOL bIs32Bit, - _In_reads_(nDlls) LPCSTR *rlpDlls, - _In_ DWORD nDlls); - -BOOL WINAPI DetourCopyPayloadToProcess(_In_ HANDLE hProcess, - _In_ REFGUID rguid, - _In_reads_bytes_(cbData) LPCVOID pvData, - _In_ DWORD cbData); -_Success_(return != NULL) -PVOID WINAPI DetourCopyPayloadToProcessEx(_In_ HANDLE hProcess, - _In_ REFGUID rguid, - _In_reads_bytes_(cbData) LPCVOID pvData, - _In_ DWORD cbData); - -BOOL WINAPI DetourRestoreAfterWith(VOID); -BOOL WINAPI DetourRestoreAfterWithEx(_In_reads_bytes_(cbData) PVOID pvData, - _In_ DWORD cbData); -BOOL WINAPI DetourIsHelperProcess(VOID); -VOID CALLBACK DetourFinishHelperProcess(_In_ HWND, - _In_ HINSTANCE, - _In_ LPSTR, - _In_ INT); - -// -////////////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -} -#endif // __cplusplus - -/////////////////////////////////////////////////// Type-safe overloads for C++ -// -#if __cplusplus >= 201103L || _MSVC_LANG >= 201103L -#include - -template -struct DetoursIsFunctionPointer : std::false_type {}; - -template -struct DetoursIsFunctionPointer : std::is_function::type> {}; - -template< - typename T, - typename std::enable_if::value, int>::type = 0> -LONG DetourAttach(_Inout_ T *ppPointer, - _In_ T pDetour) noexcept -{ - return DetourAttach( - reinterpret_cast(ppPointer), - reinterpret_cast(pDetour)); -} - -template< - typename T, - typename std::enable_if::value, int>::type = 0> -LONG DetourAttachEx(_Inout_ T *ppPointer, - _In_ T pDetour, - _Out_opt_ PDETOUR_TRAMPOLINE *ppRealTrampoline, - _Out_opt_ T *ppRealTarget, - _Out_opt_ T *ppRealDetour) noexcept -{ - return DetourAttachEx( - reinterpret_cast(ppPointer), - reinterpret_cast(pDetour), - ppRealTrampoline, - reinterpret_cast(ppRealTarget), - reinterpret_cast(ppRealDetour)); -} - -template< - typename T, - typename std::enable_if::value, int>::type = 0> -LONG DetourDetach(_Inout_ T *ppPointer, - _In_ T pDetour) noexcept -{ - return DetourDetach( - reinterpret_cast(ppPointer), - reinterpret_cast(pDetour)); -} - -#endif // __cplusplus >= 201103L || _MSVC_LANG >= 201103L -// -////////////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////// Detours Internal Definitions. -// -#ifdef __cplusplus -#ifdef DETOURS_INTERNAL - -#define NOTHROW -// #define NOTHROW (nothrow) - -////////////////////////////////////////////////////////////////////////////// -// -#if (_MSC_VER < 1299) && !defined(__GNUC__) -#include -typedef IMAGEHLP_MODULE IMAGEHLP_MODULE64; -typedef PIMAGEHLP_MODULE PIMAGEHLP_MODULE64; -typedef IMAGEHLP_SYMBOL SYMBOL_INFO; -typedef PIMAGEHLP_SYMBOL PSYMBOL_INFO; - -static inline -LONG InterlockedCompareExchange(_Inout_ LONG *ptr, _In_ LONG nval, _In_ LONG oval) -{ - return (LONG)::InterlockedCompareExchange((PVOID*)ptr, (PVOID)nval, (PVOID)oval); -} -#else -#pragma warning(push) -#pragma warning(disable:4091) // empty typedef -#include -#pragma warning(pop) -#endif - -#ifdef IMAGEAPI // defined by DBGHELP.H -typedef LPAPI_VERSION (NTAPI *PF_ImagehlpApiVersionEx)(_In_ LPAPI_VERSION AppVersion); - -typedef BOOL (NTAPI *PF_SymInitialize)(_In_ HANDLE hProcess, - _In_opt_ LPCSTR UserSearchPath, - _In_ BOOL fInvadeProcess); -typedef DWORD (NTAPI *PF_SymSetOptions)(_In_ DWORD SymOptions); -typedef DWORD (NTAPI *PF_SymGetOptions)(VOID); -typedef DWORD64 (NTAPI *PF_SymLoadModule64)(_In_ HANDLE hProcess, - _In_opt_ HANDLE hFile, - _In_ LPSTR ImageName, - _In_opt_ LPSTR ModuleName, - _In_ DWORD64 BaseOfDll, - _In_opt_ DWORD SizeOfDll); -typedef BOOL (NTAPI *PF_SymGetModuleInfo64)(_In_ HANDLE hProcess, - _In_ DWORD64 qwAddr, - _Out_ PIMAGEHLP_MODULE64 ModuleInfo); -typedef BOOL (NTAPI *PF_SymFromName)(_In_ HANDLE hProcess, - _In_ LPSTR Name, - _Out_ PSYMBOL_INFO Symbol); - -typedef struct _DETOUR_SYM_INFO -{ - HANDLE hProcess; - HMODULE hDbgHelp; - PF_ImagehlpApiVersionEx pfImagehlpApiVersionEx; - PF_SymInitialize pfSymInitialize; - PF_SymSetOptions pfSymSetOptions; - PF_SymGetOptions pfSymGetOptions; - PF_SymLoadModule64 pfSymLoadModule64; - PF_SymGetModuleInfo64 pfSymGetModuleInfo64; - PF_SymFromName pfSymFromName; -} DETOUR_SYM_INFO, *PDETOUR_SYM_INFO; - -PDETOUR_SYM_INFO DetourLoadImageHlp(VOID); - -#endif // IMAGEAPI - -#if defined(_INC_STDIO) && !defined(_CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS) -#error detours.h must be included before stdio.h (or at least define _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS earlier) -#endif -#define _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS 1 - -#ifndef DETOUR_TRACE -#if DETOUR_DEBUG -#define DETOUR_TRACE(x) printf x -#define DETOUR_BREAK() __debugbreak() -#include -#include -#else -#define DETOUR_TRACE(x) -#define DETOUR_BREAK() -#endif -#endif - -#if 1 || defined(DETOURS_IA64) - -// -// IA64 instructions are 41 bits, 3 per bundle, plus 5 bit bundle template => 128 bits per bundle. -// - -#define DETOUR_IA64_INSTRUCTIONS_PER_BUNDLE (3) - -#define DETOUR_IA64_TEMPLATE_OFFSET (0) -#define DETOUR_IA64_TEMPLATE_SIZE (5) - -#define DETOUR_IA64_INSTRUCTION_SIZE (41) -#define DETOUR_IA64_INSTRUCTION0_OFFSET (DETOUR_IA64_TEMPLATE_SIZE) -#define DETOUR_IA64_INSTRUCTION1_OFFSET (DETOUR_IA64_TEMPLATE_SIZE + DETOUR_IA64_INSTRUCTION_SIZE) -#define DETOUR_IA64_INSTRUCTION2_OFFSET (DETOUR_IA64_TEMPLATE_SIZE + DETOUR_IA64_INSTRUCTION_SIZE + DETOUR_IA64_INSTRUCTION_SIZE) - -C_ASSERT(DETOUR_IA64_TEMPLATE_SIZE + DETOUR_IA64_INSTRUCTIONS_PER_BUNDLE * DETOUR_IA64_INSTRUCTION_SIZE == 128); - -__declspec(align(16)) struct DETOUR_IA64_BUNDLE -{ - public: - union - { - BYTE data[16]; - UINT64 wide[2]; - }; - - enum { - A_UNIT = 1u, - I_UNIT = 2u, - M_UNIT = 3u, - B_UNIT = 4u, - F_UNIT = 5u, - L_UNIT = 6u, - X_UNIT = 7u, - }; - struct DETOUR_IA64_METADATA - { - ULONG nTemplate : 8; // Instruction template. - ULONG nUnit0 : 4; // Unit for slot 0 - ULONG nUnit1 : 4; // Unit for slot 1 - ULONG nUnit2 : 4; // Unit for slot 2 - }; - - protected: - static const DETOUR_IA64_METADATA s_rceCopyTable[33]; - - UINT RelocateBundle(_Inout_ DETOUR_IA64_BUNDLE* pDst, _Inout_opt_ DETOUR_IA64_BUNDLE* pBundleExtra) const; - - bool RelocateInstruction(_Inout_ DETOUR_IA64_BUNDLE* pDst, - _In_ BYTE slot, - _Inout_opt_ DETOUR_IA64_BUNDLE* pBundleExtra) const; - - // 120 112 104 96 88 80 72 64 56 48 40 32 24 16 8 0 - // f. e. d. c. b. a. 9. 8. 7. 6. 5. 4. 3. 2. 1. 0. - - // 00 - // f.e. d.c. b.a. 9.8. 7.6. 5.4. 3.2. 1.0. - // 0000 0000 0000 0000 0000 0000 0000 001f : Template [4..0] - // 0000 0000 0000 0000 0000 03ff ffff ffe0 : Zero [ 41.. 5] - // 0000 0000 0000 0000 0000 3c00 0000 0000 : Zero [ 45.. 42] - // 0000 0000 0007 ffff ffff c000 0000 0000 : One [ 82.. 46] - // 0000 0000 0078 0000 0000 0000 0000 0000 : One [ 86.. 83] - // 0fff ffff ff80 0000 0000 0000 0000 0000 : Two [123.. 87] - // f000 0000 0000 0000 0000 0000 0000 0000 : Two [127..124] - BYTE GetTemplate() const; - // Get 4 bit opcodes. - BYTE GetInst0() const; - BYTE GetInst1() const; - BYTE GetInst2() const; - BYTE GetUnit(BYTE slot) const; - BYTE GetUnit0() const; - BYTE GetUnit1() const; - BYTE GetUnit2() const; - // Get 37 bit data. - UINT64 GetData0() const; - UINT64 GetData1() const; - UINT64 GetData2() const; - - // Get/set the full 41 bit instructions. - UINT64 GetInstruction(BYTE slot) const; - UINT64 GetInstruction0() const; - UINT64 GetInstruction1() const; - UINT64 GetInstruction2() const; - void SetInstruction(BYTE slot, UINT64 instruction); - void SetInstruction0(UINT64 instruction); - void SetInstruction1(UINT64 instruction); - void SetInstruction2(UINT64 instruction); - - // Get/set bitfields. - static UINT64 GetBits(UINT64 Value, UINT64 Offset, UINT64 Count); - static UINT64 SetBits(UINT64 Value, UINT64 Offset, UINT64 Count, UINT64 Field); - - // Get specific read-only fields. - static UINT64 GetOpcode(UINT64 instruction); // 4bit opcode - static UINT64 GetX(UINT64 instruction); // 1bit opcode extension - static UINT64 GetX3(UINT64 instruction); // 3bit opcode extension - static UINT64 GetX6(UINT64 instruction); // 6bit opcode extension - - // Get/set specific fields. - static UINT64 GetImm7a(UINT64 instruction); - static UINT64 SetImm7a(UINT64 instruction, UINT64 imm7a); - static UINT64 GetImm13c(UINT64 instruction); - static UINT64 SetImm13c(UINT64 instruction, UINT64 imm13c); - static UINT64 GetSignBit(UINT64 instruction); - static UINT64 SetSignBit(UINT64 instruction, UINT64 signBit); - static UINT64 GetImm20a(UINT64 instruction); - static UINT64 SetImm20a(UINT64 instruction, UINT64 imm20a); - static UINT64 GetImm20b(UINT64 instruction); - static UINT64 SetImm20b(UINT64 instruction, UINT64 imm20b); - - static UINT64 SignExtend(UINT64 Value, UINT64 Offset); - - BOOL IsMovlGp() const; - - VOID SetInst(BYTE Slot, BYTE nInst); - VOID SetInst0(BYTE nInst); - VOID SetInst1(BYTE nInst); - VOID SetInst2(BYTE nInst); - VOID SetData(BYTE Slot, UINT64 nData); - VOID SetData0(UINT64 nData); - VOID SetData1(UINT64 nData); - VOID SetData2(UINT64 nData); - BOOL SetNop(BYTE Slot); - BOOL SetNop0(); - BOOL SetNop1(); - BOOL SetNop2(); - - public: - BOOL IsBrl() const; - VOID SetBrl(); - VOID SetBrl(UINT64 target); - UINT64 GetBrlTarget() const; - VOID SetBrlTarget(UINT64 target); - VOID SetBrlImm(UINT64 imm); - UINT64 GetBrlImm() const; - - UINT64 GetMovlGp() const; - VOID SetMovlGp(UINT64 gp); - - VOID SetStop(); - - UINT Copy(_Out_ DETOUR_IA64_BUNDLE *pDst, _Inout_opt_ DETOUR_IA64_BUNDLE* pBundleExtra = NULL) const; -}; -#endif // DETOURS_IA64 - -#ifdef DETOURS_ARM - -#define DETOURS_PFUNC_TO_PBYTE(p) ((PBYTE)(((ULONG_PTR)(p)) & ~(ULONG_PTR)1)) -#define DETOURS_PBYTE_TO_PFUNC(p) ((PBYTE)(((ULONG_PTR)(p)) | (ULONG_PTR)1)) - -#endif // DETOURS_ARM - -////////////////////////////////////////////////////////////////////////////// - -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus - -#define DETOUR_OFFLINE_LIBRARY(x) \ -PVOID WINAPI DetourCopyInstruction##x(_In_opt_ PVOID pDst, \ - _Inout_opt_ PVOID *ppDstPool, \ - _In_ PVOID pSrc, \ - _Out_opt_ PVOID *ppTarget, \ - _Out_opt_ LONG *plExtra); \ - \ -BOOL WINAPI DetourSetCodeModule##x(_In_ HMODULE hModule, \ - _In_ BOOL fLimitReferencesToModule); \ - -DETOUR_OFFLINE_LIBRARY(X86) -DETOUR_OFFLINE_LIBRARY(X64) -DETOUR_OFFLINE_LIBRARY(ARM) -DETOUR_OFFLINE_LIBRARY(ARM64) -DETOUR_OFFLINE_LIBRARY(IA64) - -#undef DETOUR_OFFLINE_LIBRARY - -////////////////////////////////////////////////////////////////////////////// -// -// Helpers for manipulating page protection. -// - -_Success_(return != FALSE) -BOOL WINAPI DetourVirtualProtectSameExecuteEx(_In_ HANDLE hProcess, - _In_ PVOID pAddress, - _In_ SIZE_T nSize, - _In_ DWORD dwNewProtect, - _Out_ PDWORD pdwOldProtect); - -_Success_(return != FALSE) -BOOL WINAPI DetourVirtualProtectSameExecute(_In_ PVOID pAddress, - _In_ SIZE_T nSize, - _In_ DWORD dwNewProtect, - _Out_ PDWORD pdwOldProtect); - -// Detours must depend only on kernel32.lib, so we cannot use IsEqualGUID -BOOL WINAPI DetourAreSameGuid(_In_ REFGUID left, _In_ REFGUID right); -#ifdef __cplusplus -} -#endif // __cplusplus - -////////////////////////////////////////////////////////////////////////////// - -#define MM_ALLOCATION_GRANULARITY 0x10000 - -////////////////////////////////////////////////////////////////////////////// - -#endif // DETOURS_INTERNAL -#endif // __cplusplus - -#endif // _DETOURS_H_ -// -//////////////////////////////////////////////////////////////// End of File. +///////////////////////////////////////////////////////////////////////////// +// +// Core Detours Functionality (detours.h of detours.lib) +// +// Microsoft Research Detours Package, Version 4.0.1 +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// + +#pragma once +#ifndef _DETOURS_H_ +#define _DETOURS_H_ + +#define DETOURS_VERSION 0x4c0c1 // 0xMAJORcMINORcPATCH + +////////////////////////////////////////////////////////////////////////////// +// + +#ifdef DETOURS_INTERNAL + +#define _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS 1 +#define _ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE 1 + +#pragma warning(disable:4068) // unknown pragma (suppress) + +#if _MSC_VER >= 1900 +#pragma warning(push) +#pragma warning(disable:4091) // empty typedef +#endif + +// Suppress declspec(dllimport) for the sake of Detours +// users that provide kernel32 functionality themselves. +// This is ok in the mainstream case, it will just cost +// an extra instruction calling some functions, which +// LTCG optimizes away. +// +#define _KERNEL32_ 1 +#define _USER32_ 1 + +#include +#if (_MSC_VER < 1310) +#else +#pragma warning(push) +#if _MSC_VER > 1400 +#pragma warning(disable:6102 6103) // /analyze warnings +#endif +#include +#include +#pragma warning(pop) +#endif + +// Allow Detours to cleanly compile with the MingW toolchain. +// +#ifdef __GNUC__ +#define __try +#define __except(x) if (0) +#include +#endif + +// From winerror.h, as this error isn't found in some SDKs: +// +// MessageId: ERROR_DYNAMIC_CODE_BLOCKED +// +// MessageText: +// +// The operation was blocked as the process prohibits dynamic code generation. +// +#define ERROR_DYNAMIC_CODE_BLOCKED 1655L + +#endif // DETOURS_INTERNAL + +////////////////////////////////////////////////////////////////////////////// +// + +#undef DETOURS_X64 +#undef DETOURS_X86 +#undef DETOURS_IA64 +#undef DETOURS_ARM +#undef DETOURS_ARM64 +#undef DETOURS_BITS +#undef DETOURS_32BIT +#undef DETOURS_64BIT + +#if defined(_X86_) +#define DETOURS_X86 +#define DETOURS_OPTION_BITS 64 + +#elif defined(_AMD64_) +#define DETOURS_X64 +#define DETOURS_OPTION_BITS 32 + +#elif defined(_IA64_) +#define DETOURS_IA64 +#define DETOURS_OPTION_BITS 32 + +#elif defined(_ARM_) +#define DETOURS_ARM + +#elif defined(_ARM64_) +#define DETOURS_ARM64 + +#else +#error Unknown architecture (x86, amd64, ia64, arm, arm64) +#endif + +#ifdef _WIN64 +#undef DETOURS_32BIT +#define DETOURS_64BIT 1 +#define DETOURS_BITS 64 +// If all 64bit kernels can run one and only one 32bit architecture. +//#define DETOURS_OPTION_BITS 32 +#else +#define DETOURS_32BIT 1 +#undef DETOURS_64BIT +#define DETOURS_BITS 32 +// If all 64bit kernels can run one and only one 32bit architecture. +//#define DETOURS_OPTION_BITS 32 +#endif + +/////////////////////////////////////////////////////////////// Helper Macros. +// +#define DETOURS_STRINGIFY_(x) #x +#define DETOURS_STRINGIFY(x) DETOURS_STRINGIFY_(x) + +#define VER_DETOURS_BITS DETOURS_STRINGIFY(DETOURS_BITS) + +////////////////////////////////////////////////////////////////////////////// +// + +#if (_MSC_VER < 1299) && !defined(__MINGW32__) +typedef LONG LONG_PTR; +typedef ULONG ULONG_PTR; +#endif + +///////////////////////////////////////////////// SAL 2.0 Annotations w/o SAL. +// +// These definitions are include so that Detours will build even if the +// compiler doesn't have full SAL 2.0 support. +// +#ifndef DETOURS_DONT_REMOVE_SAL_20 + +#ifdef DETOURS_TEST_REMOVE_SAL_20 +#undef _Analysis_assume_ +#undef _Benign_race_begin_ +#undef _Benign_race_end_ +#undef _Field_range_ +#undef _Field_size_ +#undef _In_ +#undef _In_bytecount_ +#undef _In_count_ +#undef __in_ecount +#undef _In_opt_ +#undef _In_opt_bytecount_ +#undef _In_opt_count_ +#undef _In_opt_z_ +#undef _In_range_ +#undef _In_reads_ +#undef _In_reads_bytes_ +#undef _In_reads_opt_ +#undef _In_reads_opt_bytes_ +#undef _In_reads_or_z_ +#undef _In_z_ +#undef _Inout_ +#undef _Inout_opt_ +#undef _Inout_z_count_ +#undef _Out_ +#undef _Out_opt_ +#undef _Out_writes_ +#undef _Outptr_result_maybenull_ +#undef _Readable_bytes_ +#undef _Success_ +#undef _Writable_bytes_ +#undef _Pre_notnull_ +#endif + +#if defined(_Deref_out_opt_z_) && !defined(_Outptr_result_maybenull_) +#define _Outptr_result_maybenull_ _Deref_out_opt_z_ +#endif + +#if defined(_In_count_) && !defined(_In_reads_) +#define _In_reads_(x) _In_count_(x) +#endif + +#if defined(_In_opt_count_) && !defined(_In_reads_opt_) +#define _In_reads_opt_(x) _In_opt_count_(x) +#endif + +#if defined(_In_opt_bytecount_) && !defined(_In_reads_opt_bytes_) +#define _In_reads_opt_bytes_(x) _In_opt_bytecount_(x) +#endif + +#if defined(_In_bytecount_) && !defined(_In_reads_bytes_) +#define _In_reads_bytes_(x) _In_bytecount_(x) +#endif + +#ifndef _In_ +#define _In_ +#endif + +#ifndef _In_bytecount_ +#define _In_bytecount_(x) +#endif + +#ifndef _In_count_ +#define _In_count_(x) +#endif + +#ifndef __in_ecount +#define __in_ecount(x) +#endif + +#ifndef _In_opt_ +#define _In_opt_ +#endif + +#ifndef _In_opt_bytecount_ +#define _In_opt_bytecount_(x) +#endif + +#ifndef _In_opt_count_ +#define _In_opt_count_(x) +#endif + +#ifndef _In_opt_z_ +#define _In_opt_z_ +#endif + +#ifndef _In_range_ +#define _In_range_(x,y) +#endif + +#ifndef _In_reads_ +#define _In_reads_(x) +#endif + +#ifndef _In_reads_bytes_ +#define _In_reads_bytes_(x) +#endif + +#ifndef _In_reads_opt_ +#define _In_reads_opt_(x) +#endif + +#ifndef _In_reads_opt_bytes_ +#define _In_reads_opt_bytes_(x) +#endif + +#ifndef _In_reads_or_z_ +#define _In_reads_or_z_ +#endif + +#ifndef _In_z_ +#define _In_z_ +#endif + +#ifndef _Inout_ +#define _Inout_ +#endif + +#ifndef _Inout_opt_ +#define _Inout_opt_ +#endif + +#ifndef _Inout_z_count_ +#define _Inout_z_count_(x) +#endif + +#ifndef _Out_ +#define _Out_ +#endif + +#ifndef _Out_opt_ +#define _Out_opt_ +#endif + +#ifndef _Out_writes_ +#define _Out_writes_(x) +#endif + +#ifndef _Outptr_result_maybenull_ +#define _Outptr_result_maybenull_ +#endif + +#ifndef _Writable_bytes_ +#define _Writable_bytes_(x) +#endif + +#ifndef _Readable_bytes_ +#define _Readable_bytes_(x) +#endif + +#ifndef _Success_ +#define _Success_(x) +#endif + +#ifndef _Pre_notnull_ +#define _Pre_notnull_ +#endif + +#ifdef DETOURS_INTERNAL + +#pragma warning(disable:4615) // unknown warning type (suppress with older compilers) + +#ifndef _Benign_race_begin_ +#define _Benign_race_begin_ +#endif + +#ifndef _Benign_race_end_ +#define _Benign_race_end_ +#endif + +#ifndef _Field_size_ +#define _Field_size_(x) +#endif + +#ifndef _Field_range_ +#define _Field_range_(x,y) +#endif + +#ifndef _Analysis_assume_ +#define _Analysis_assume_(x) +#endif + +#endif // DETOURS_INTERNAL +#endif // DETOURS_DONT_REMOVE_SAL_20 + +////////////////////////////////////////////////////////////////////////////// +// +#ifndef GUID_DEFINED +#define GUID_DEFINED +typedef struct _GUID +{ + DWORD Data1; + WORD Data2; + WORD Data3; + BYTE Data4[ 8 ]; +} GUID; + +#ifdef INITGUID +#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + const GUID name \ + = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } +#else +#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + const GUID name +#endif // INITGUID +#endif // !GUID_DEFINED + +#if defined(__cplusplus) +#ifndef _REFGUID_DEFINED +#define _REFGUID_DEFINED +#define REFGUID const GUID & +#endif // !_REFGUID_DEFINED +#else // !__cplusplus +#ifndef _REFGUID_DEFINED +#define _REFGUID_DEFINED +#define REFGUID const GUID * const +#endif // !_REFGUID_DEFINED +#endif // !__cplusplus + +#ifndef ARRAYSIZE +#define ARRAYSIZE(x) (sizeof(x)/sizeof(x[0])) +#endif + +// +////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +/////////////////////////////////////////////////// Instruction Target Macros. +// +#define DETOUR_INSTRUCTION_TARGET_NONE ((PVOID)0) +#define DETOUR_INSTRUCTION_TARGET_DYNAMIC ((PVOID)(LONG_PTR)-1) +#define DETOUR_SECTION_HEADER_SIGNATURE 0x00727444 // "Dtr\0" + +extern const GUID DETOUR_EXE_RESTORE_GUID; +extern const GUID DETOUR_EXE_HELPER_GUID; + +#define DETOUR_TRAMPOLINE_SIGNATURE 0x21727444 // Dtr! +typedef struct _DETOUR_TRAMPOLINE DETOUR_TRAMPOLINE, *PDETOUR_TRAMPOLINE; + +/////////////////////////////////////////////////////////// Binary Structures. +// +#pragma pack(push, 8) +typedef struct _DETOUR_SECTION_HEADER +{ + DWORD cbHeaderSize; + DWORD nSignature; + DWORD nDataOffset; + DWORD cbDataSize; + + DWORD nOriginalImportVirtualAddress; + DWORD nOriginalImportSize; + DWORD nOriginalBoundImportVirtualAddress; + DWORD nOriginalBoundImportSize; + + DWORD nOriginalIatVirtualAddress; + DWORD nOriginalIatSize; + DWORD nOriginalSizeOfImage; + DWORD cbPrePE; + + DWORD nOriginalClrFlags; + DWORD reserved1; + DWORD reserved2; + DWORD reserved3; + + // Followed by cbPrePE bytes of data. +} DETOUR_SECTION_HEADER, *PDETOUR_SECTION_HEADER; + +typedef struct _DETOUR_SECTION_RECORD +{ + DWORD cbBytes; + DWORD nReserved; + GUID guid; +} DETOUR_SECTION_RECORD, *PDETOUR_SECTION_RECORD; + +typedef struct _DETOUR_CLR_HEADER +{ + // Header versioning + ULONG cb; + USHORT MajorRuntimeVersion; + USHORT MinorRuntimeVersion; + + // Symbol table and startup information + IMAGE_DATA_DIRECTORY MetaData; + ULONG Flags; + + // Followed by the rest of the IMAGE_COR20_HEADER +} DETOUR_CLR_HEADER, *PDETOUR_CLR_HEADER; + +typedef struct _DETOUR_EXE_RESTORE +{ + DWORD cb; + DWORD cbidh; + DWORD cbinh; + DWORD cbclr; + + PBYTE pidh; + PBYTE pinh; + PBYTE pclr; + + IMAGE_DOS_HEADER idh; + union { + IMAGE_NT_HEADERS inh; // all environments have this +#ifdef IMAGE_NT_OPTIONAL_HDR32_MAGIC // some environments do not have this + IMAGE_NT_HEADERS32 inh32; +#endif +#ifdef IMAGE_NT_OPTIONAL_HDR64_MAGIC // some environments do not have this + IMAGE_NT_HEADERS64 inh64; +#endif +#ifdef IMAGE_NT_OPTIONAL_HDR64_MAGIC // some environments do not have this + BYTE raw[sizeof(IMAGE_NT_HEADERS64) + + sizeof(IMAGE_SECTION_HEADER) * 32]; +#else + BYTE raw[0x108 + sizeof(IMAGE_SECTION_HEADER) * 32]; +#endif + }; + DETOUR_CLR_HEADER clr; + +} DETOUR_EXE_RESTORE, *PDETOUR_EXE_RESTORE; + +#ifdef IMAGE_NT_OPTIONAL_HDR64_MAGIC +C_ASSERT(sizeof(IMAGE_NT_HEADERS64) == 0x108); +#endif + +// The size can change, but assert for clarity due to the muddying #ifdefs. +#ifdef _WIN64 +C_ASSERT(sizeof(DETOUR_EXE_RESTORE) == 0x688); +#else +C_ASSERT(sizeof(DETOUR_EXE_RESTORE) == 0x678); +#endif + +typedef struct _DETOUR_EXE_HELPER +{ + DWORD cb; + DWORD pid; + DWORD nDlls; + CHAR rDlls[4]; +} DETOUR_EXE_HELPER, *PDETOUR_EXE_HELPER; + +#pragma pack(pop) + +#define DETOUR_SECTION_HEADER_DECLARE(cbSectionSize) \ +{ \ + sizeof(DETOUR_SECTION_HEADER),\ + DETOUR_SECTION_HEADER_SIGNATURE,\ + sizeof(DETOUR_SECTION_HEADER),\ + (cbSectionSize),\ + \ + 0,\ + 0,\ + 0,\ + 0,\ + \ + 0,\ + 0,\ + 0,\ + 0,\ +} + +///////////////////////////////////////////////////////////// Binary Typedefs. +// +typedef BOOL (CALLBACK *PF_DETOUR_BINARY_BYWAY_CALLBACK)( + _In_opt_ PVOID pContext, + _In_opt_ LPCSTR pszFile, + _Outptr_result_maybenull_ LPCSTR *ppszOutFile); + +typedef BOOL (CALLBACK *PF_DETOUR_BINARY_FILE_CALLBACK)( + _In_opt_ PVOID pContext, + _In_ LPCSTR pszOrigFile, + _In_ LPCSTR pszFile, + _Outptr_result_maybenull_ LPCSTR *ppszOutFile); + +typedef BOOL (CALLBACK *PF_DETOUR_BINARY_SYMBOL_CALLBACK)( + _In_opt_ PVOID pContext, + _In_ ULONG nOrigOrdinal, + _In_ ULONG nOrdinal, + _Out_ ULONG *pnOutOrdinal, + _In_opt_ LPCSTR pszOrigSymbol, + _In_opt_ LPCSTR pszSymbol, + _Outptr_result_maybenull_ LPCSTR *ppszOutSymbol); + +typedef BOOL (CALLBACK *PF_DETOUR_BINARY_COMMIT_CALLBACK)( + _In_opt_ PVOID pContext); + +typedef BOOL (CALLBACK *PF_DETOUR_ENUMERATE_EXPORT_CALLBACK)(_In_opt_ PVOID pContext, + _In_ ULONG nOrdinal, + _In_opt_ LPCSTR pszName, + _In_opt_ PVOID pCode); + +typedef BOOL (CALLBACK *PF_DETOUR_IMPORT_FILE_CALLBACK)(_In_opt_ PVOID pContext, + _In_opt_ HMODULE hModule, + _In_opt_ LPCSTR pszFile); + +typedef BOOL (CALLBACK *PF_DETOUR_IMPORT_FUNC_CALLBACK)(_In_opt_ PVOID pContext, + _In_ DWORD nOrdinal, + _In_opt_ LPCSTR pszFunc, + _In_opt_ PVOID pvFunc); + +// Same as PF_DETOUR_IMPORT_FUNC_CALLBACK but extra indirection on last parameter. +typedef BOOL (CALLBACK *PF_DETOUR_IMPORT_FUNC_CALLBACK_EX)(_In_opt_ PVOID pContext, + _In_ DWORD nOrdinal, + _In_opt_ LPCSTR pszFunc, + _In_opt_ PVOID* ppvFunc); + +typedef VOID * PDETOUR_BINARY; +typedef VOID * PDETOUR_LOADED_BINARY; + +//////////////////////////////////////////////////////////// Transaction APIs. +// +LONG WINAPI DetourTransactionBegin(VOID); +LONG WINAPI DetourTransactionAbort(VOID); +LONG WINAPI DetourTransactionCommit(VOID); +LONG WINAPI DetourTransactionCommitEx(_Out_opt_ PVOID **pppFailedPointer); + +LONG WINAPI DetourUpdateThread(_In_ HANDLE hThread); + +LONG WINAPI DetourAttach(_Inout_ PVOID *ppPointer, + _In_ PVOID pDetour); + +LONG WINAPI DetourAttachEx(_Inout_ PVOID *ppPointer, + _In_ PVOID pDetour, + _Out_opt_ PDETOUR_TRAMPOLINE *ppRealTrampoline, + _Out_opt_ PVOID *ppRealTarget, + _Out_opt_ PVOID *ppRealDetour); + +LONG WINAPI DetourDetach(_Inout_ PVOID *ppPointer, + _In_ PVOID pDetour); + +BOOL WINAPI DetourSetIgnoreTooSmall(_In_ BOOL fIgnore); +BOOL WINAPI DetourSetRetainRegions(_In_ BOOL fRetain); +PVOID WINAPI DetourSetSystemRegionLowerBound(_In_ PVOID pSystemRegionLowerBound); +PVOID WINAPI DetourSetSystemRegionUpperBound(_In_ PVOID pSystemRegionUpperBound); + +////////////////////////////////////////////////////////////// Code Functions. +// +PVOID WINAPI DetourFindFunction(_In_ LPCSTR pszModule, + _In_ LPCSTR pszFunction); +PVOID WINAPI DetourCodeFromPointer(_In_ PVOID pPointer, + _Out_opt_ PVOID *ppGlobals); +PVOID WINAPI DetourCopyInstruction(_In_opt_ PVOID pDst, + _Inout_opt_ PVOID *ppDstPool, + _In_ PVOID pSrc, + _Out_opt_ PVOID *ppTarget, + _Out_opt_ LONG *plExtra); +BOOL WINAPI DetourSetCodeModule(_In_ HMODULE hModule, + _In_ BOOL fLimitReferencesToModule); +PVOID WINAPI DetourAllocateRegionWithinJumpBounds(_In_ LPCVOID pbTarget, + _Out_ PDWORD pcbAllocatedSize); + +///////////////////////////////////////////////////// Loaded Binary Functions. +// +HMODULE WINAPI DetourGetContainingModule(_In_ PVOID pvAddr); +HMODULE WINAPI DetourEnumerateModules(_In_opt_ HMODULE hModuleLast); +PVOID WINAPI DetourGetEntryPoint(_In_opt_ HMODULE hModule); +ULONG WINAPI DetourGetModuleSize(_In_opt_ HMODULE hModule); +BOOL WINAPI DetourEnumerateExports(_In_ HMODULE hModule, + _In_opt_ PVOID pContext, + _In_ PF_DETOUR_ENUMERATE_EXPORT_CALLBACK pfExport); +BOOL WINAPI DetourEnumerateImports(_In_opt_ HMODULE hModule, + _In_opt_ PVOID pContext, + _In_opt_ PF_DETOUR_IMPORT_FILE_CALLBACK pfImportFile, + _In_opt_ PF_DETOUR_IMPORT_FUNC_CALLBACK pfImportFunc); + +BOOL WINAPI DetourEnumerateImportsEx(_In_opt_ HMODULE hModule, + _In_opt_ PVOID pContext, + _In_opt_ PF_DETOUR_IMPORT_FILE_CALLBACK pfImportFile, + _In_opt_ PF_DETOUR_IMPORT_FUNC_CALLBACK_EX pfImportFuncEx); + +_Writable_bytes_(*pcbData) +_Readable_bytes_(*pcbData) +_Success_(return != NULL) +PVOID WINAPI DetourFindPayload(_In_opt_ HMODULE hModule, + _In_ REFGUID rguid, + _Out_opt_ DWORD *pcbData); + +_Writable_bytes_(*pcbData) +_Readable_bytes_(*pcbData) +_Success_(return != NULL) +PVOID WINAPI DetourFindPayloadEx(_In_ REFGUID rguid, + _Out_opt_ DWORD *pcbData); + +DWORD WINAPI DetourGetSizeOfPayloads(_In_opt_ HMODULE hModule); + +///////////////////////////////////////////////// Persistent Binary Functions. +// + +PDETOUR_BINARY WINAPI DetourBinaryOpen(_In_ HANDLE hFile); + +_Writable_bytes_(*pcbData) +_Readable_bytes_(*pcbData) +_Success_(return != NULL) +PVOID WINAPI DetourBinaryEnumeratePayloads(_In_ PDETOUR_BINARY pBinary, + _Out_opt_ GUID *pGuid, + _Out_ DWORD *pcbData, + _Inout_ DWORD *pnIterator); + +_Writable_bytes_(*pcbData) +_Readable_bytes_(*pcbData) +_Success_(return != NULL) +PVOID WINAPI DetourBinaryFindPayload(_In_ PDETOUR_BINARY pBinary, + _In_ REFGUID rguid, + _Out_ DWORD *pcbData); + +PVOID WINAPI DetourBinarySetPayload(_In_ PDETOUR_BINARY pBinary, + _In_ REFGUID rguid, + _In_reads_opt_(cbData) PVOID pData, + _In_ DWORD cbData); +BOOL WINAPI DetourBinaryDeletePayload(_In_ PDETOUR_BINARY pBinary, _In_ REFGUID rguid); +BOOL WINAPI DetourBinaryPurgePayloads(_In_ PDETOUR_BINARY pBinary); +BOOL WINAPI DetourBinaryResetImports(_In_ PDETOUR_BINARY pBinary); +BOOL WINAPI DetourBinaryEditImports(_In_ PDETOUR_BINARY pBinary, + _In_opt_ PVOID pContext, + _In_opt_ PF_DETOUR_BINARY_BYWAY_CALLBACK pfByway, + _In_opt_ PF_DETOUR_BINARY_FILE_CALLBACK pfFile, + _In_opt_ PF_DETOUR_BINARY_SYMBOL_CALLBACK pfSymbol, + _In_opt_ PF_DETOUR_BINARY_COMMIT_CALLBACK pfCommit); +BOOL WINAPI DetourBinaryWrite(_In_ PDETOUR_BINARY pBinary, _In_ HANDLE hFile); +BOOL WINAPI DetourBinaryClose(_In_ PDETOUR_BINARY pBinary); + +/////////////////////////////////////////////////// Create Process & Load Dll. +// +_Success_(return != NULL) +PVOID WINAPI DetourFindRemotePayload(_In_ HANDLE hProcess, + _In_ REFGUID rguid, + _Out_opt_ DWORD *pcbData); + +typedef BOOL (WINAPI *PDETOUR_CREATE_PROCESS_ROUTINEA)( + _In_opt_ LPCSTR lpApplicationName, + _Inout_opt_ LPSTR lpCommandLine, + _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, + _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, + _In_ BOOL bInheritHandles, + _In_ DWORD dwCreationFlags, + _In_opt_ LPVOID lpEnvironment, + _In_opt_ LPCSTR lpCurrentDirectory, + _In_ LPSTARTUPINFOA lpStartupInfo, + _Out_ LPPROCESS_INFORMATION lpProcessInformation); + +typedef BOOL (WINAPI *PDETOUR_CREATE_PROCESS_ROUTINEW)( + _In_opt_ LPCWSTR lpApplicationName, + _Inout_opt_ LPWSTR lpCommandLine, + _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, + _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, + _In_ BOOL bInheritHandles, + _In_ DWORD dwCreationFlags, + _In_opt_ LPVOID lpEnvironment, + _In_opt_ LPCWSTR lpCurrentDirectory, + _In_ LPSTARTUPINFOW lpStartupInfo, + _Out_ LPPROCESS_INFORMATION lpProcessInformation); + +BOOL WINAPI DetourCreateProcessWithDllA(_In_opt_ LPCSTR lpApplicationName, + _Inout_opt_ LPSTR lpCommandLine, + _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, + _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, + _In_ BOOL bInheritHandles, + _In_ DWORD dwCreationFlags, + _In_opt_ LPVOID lpEnvironment, + _In_opt_ LPCSTR lpCurrentDirectory, + _In_ LPSTARTUPINFOA lpStartupInfo, + _Out_ LPPROCESS_INFORMATION lpProcessInformation, + _In_ LPCSTR lpDllName, + _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); + +BOOL WINAPI DetourCreateProcessWithDllW(_In_opt_ LPCWSTR lpApplicationName, + _Inout_opt_ LPWSTR lpCommandLine, + _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, + _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, + _In_ BOOL bInheritHandles, + _In_ DWORD dwCreationFlags, + _In_opt_ LPVOID lpEnvironment, + _In_opt_ LPCWSTR lpCurrentDirectory, + _In_ LPSTARTUPINFOW lpStartupInfo, + _Out_ LPPROCESS_INFORMATION lpProcessInformation, + _In_ LPCSTR lpDllName, + _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); + +#ifdef UNICODE +#define DetourCreateProcessWithDll DetourCreateProcessWithDllW +#define PDETOUR_CREATE_PROCESS_ROUTINE PDETOUR_CREATE_PROCESS_ROUTINEW +#else +#define DetourCreateProcessWithDll DetourCreateProcessWithDllA +#define PDETOUR_CREATE_PROCESS_ROUTINE PDETOUR_CREATE_PROCESS_ROUTINEA +#endif // !UNICODE + +BOOL WINAPI DetourCreateProcessWithDllExA(_In_opt_ LPCSTR lpApplicationName, + _Inout_opt_ LPSTR lpCommandLine, + _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, + _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, + _In_ BOOL bInheritHandles, + _In_ DWORD dwCreationFlags, + _In_opt_ LPVOID lpEnvironment, + _In_opt_ LPCSTR lpCurrentDirectory, + _In_ LPSTARTUPINFOA lpStartupInfo, + _Out_ LPPROCESS_INFORMATION lpProcessInformation, + _In_ LPCSTR lpDllName, + _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); + +BOOL WINAPI DetourCreateProcessWithDllExW(_In_opt_ LPCWSTR lpApplicationName, + _Inout_opt_ LPWSTR lpCommandLine, + _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, + _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, + _In_ BOOL bInheritHandles, + _In_ DWORD dwCreationFlags, + _In_opt_ LPVOID lpEnvironment, + _In_opt_ LPCWSTR lpCurrentDirectory, + _In_ LPSTARTUPINFOW lpStartupInfo, + _Out_ LPPROCESS_INFORMATION lpProcessInformation, + _In_ LPCSTR lpDllName, + _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); + +#ifdef UNICODE +#define DetourCreateProcessWithDllEx DetourCreateProcessWithDllExW +#else +#define DetourCreateProcessWithDllEx DetourCreateProcessWithDllExA +#endif // !UNICODE + +BOOL WINAPI DetourCreateProcessWithDllsA(_In_opt_ LPCSTR lpApplicationName, + _Inout_opt_ LPSTR lpCommandLine, + _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, + _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, + _In_ BOOL bInheritHandles, + _In_ DWORD dwCreationFlags, + _In_opt_ LPVOID lpEnvironment, + _In_opt_ LPCSTR lpCurrentDirectory, + _In_ LPSTARTUPINFOA lpStartupInfo, + _Out_ LPPROCESS_INFORMATION lpProcessInformation, + _In_ DWORD nDlls, + _In_reads_(nDlls) LPCSTR *rlpDlls, + _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); + +BOOL WINAPI DetourCreateProcessWithDllsW(_In_opt_ LPCWSTR lpApplicationName, + _Inout_opt_ LPWSTR lpCommandLine, + _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, + _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, + _In_ BOOL bInheritHandles, + _In_ DWORD dwCreationFlags, + _In_opt_ LPVOID lpEnvironment, + _In_opt_ LPCWSTR lpCurrentDirectory, + _In_ LPSTARTUPINFOW lpStartupInfo, + _Out_ LPPROCESS_INFORMATION lpProcessInformation, + _In_ DWORD nDlls, + _In_reads_(nDlls) LPCSTR *rlpDlls, + _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); + +#ifdef UNICODE +#define DetourCreateProcessWithDlls DetourCreateProcessWithDllsW +#else +#define DetourCreateProcessWithDlls DetourCreateProcessWithDllsA +#endif // !UNICODE + +BOOL WINAPI DetourProcessViaHelperA(_In_ DWORD dwTargetPid, + _In_ LPCSTR lpDllName, + _In_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); + +BOOL WINAPI DetourProcessViaHelperW(_In_ DWORD dwTargetPid, + _In_ LPCSTR lpDllName, + _In_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); + +#ifdef UNICODE +#define DetourProcessViaHelper DetourProcessViaHelperW +#else +#define DetourProcessViaHelper DetourProcessViaHelperA +#endif // !UNICODE + +BOOL WINAPI DetourProcessViaHelperDllsA(_In_ DWORD dwTargetPid, + _In_ DWORD nDlls, + _In_reads_(nDlls) LPCSTR *rlpDlls, + _In_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); + +BOOL WINAPI DetourProcessViaHelperDllsW(_In_ DWORD dwTargetPid, + _In_ DWORD nDlls, + _In_reads_(nDlls) LPCSTR *rlpDlls, + _In_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); + +#ifdef UNICODE +#define DetourProcessViaHelperDlls DetourProcessViaHelperDllsW +#else +#define DetourProcessViaHelperDlls DetourProcessViaHelperDllsA +#endif // !UNICODE + +BOOL WINAPI DetourUpdateProcessWithDll(_In_ HANDLE hProcess, + _In_reads_(nDlls) LPCSTR *rlpDlls, + _In_ DWORD nDlls); + +BOOL WINAPI DetourUpdateProcessWithDllEx(_In_ HANDLE hProcess, + _In_ HMODULE hImage, + _In_ BOOL bIs32Bit, + _In_reads_(nDlls) LPCSTR *rlpDlls, + _In_ DWORD nDlls); + +BOOL WINAPI DetourCopyPayloadToProcess(_In_ HANDLE hProcess, + _In_ REFGUID rguid, + _In_reads_bytes_(cbData) LPCVOID pvData, + _In_ DWORD cbData); +_Success_(return != NULL) +PVOID WINAPI DetourCopyPayloadToProcessEx(_In_ HANDLE hProcess, + _In_ REFGUID rguid, + _In_reads_bytes_(cbData) LPCVOID pvData, + _In_ DWORD cbData); + +BOOL WINAPI DetourRestoreAfterWith(VOID); +BOOL WINAPI DetourRestoreAfterWithEx(_In_reads_bytes_(cbData) PVOID pvData, + _In_ DWORD cbData); +BOOL WINAPI DetourIsHelperProcess(VOID); +VOID CALLBACK DetourFinishHelperProcess(_In_ HWND, + _In_ HINSTANCE, + _In_ LPSTR, + _In_ INT); + +// +////////////////////////////////////////////////////////////////////////////// +#ifdef __cplusplus +} +#endif // __cplusplus + +/////////////////////////////////////////////////// Type-safe overloads for C++ +// +#if __cplusplus >= 201103L || _MSVC_LANG >= 201103L +#include + +template +struct DetoursIsFunctionPointer : std::false_type {}; + +template +struct DetoursIsFunctionPointer : std::is_function::type> {}; + +template< + typename T, + typename std::enable_if::value, int>::type = 0> +LONG DetourAttach(_Inout_ T *ppPointer, + _In_ T pDetour) noexcept +{ + return DetourAttach( + reinterpret_cast(ppPointer), + reinterpret_cast(pDetour)); +} + +template< + typename T, + typename std::enable_if::value, int>::type = 0> +LONG DetourAttachEx(_Inout_ T *ppPointer, + _In_ T pDetour, + _Out_opt_ PDETOUR_TRAMPOLINE *ppRealTrampoline, + _Out_opt_ T *ppRealTarget, + _Out_opt_ T *ppRealDetour) noexcept +{ + return DetourAttachEx( + reinterpret_cast(ppPointer), + reinterpret_cast(pDetour), + ppRealTrampoline, + reinterpret_cast(ppRealTarget), + reinterpret_cast(ppRealDetour)); +} + +template< + typename T, + typename std::enable_if::value, int>::type = 0> +LONG DetourDetach(_Inout_ T *ppPointer, + _In_ T pDetour) noexcept +{ + return DetourDetach( + reinterpret_cast(ppPointer), + reinterpret_cast(pDetour)); +} + +#endif // __cplusplus >= 201103L || _MSVC_LANG >= 201103L +// +////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////// Detours Internal Definitions. +// +#ifdef __cplusplus +#ifdef DETOURS_INTERNAL + +#define NOTHROW +// #define NOTHROW (nothrow) + +////////////////////////////////////////////////////////////////////////////// +// +#if (_MSC_VER < 1299) && !defined(__GNUC__) +#include +typedef IMAGEHLP_MODULE IMAGEHLP_MODULE64; +typedef PIMAGEHLP_MODULE PIMAGEHLP_MODULE64; +typedef IMAGEHLP_SYMBOL SYMBOL_INFO; +typedef PIMAGEHLP_SYMBOL PSYMBOL_INFO; + +static inline +LONG InterlockedCompareExchange(_Inout_ LONG *ptr, _In_ LONG nval, _In_ LONG oval) +{ + return (LONG)::InterlockedCompareExchange((PVOID*)ptr, (PVOID)nval, (PVOID)oval); +} +#else +#pragma warning(push) +#pragma warning(disable:4091) // empty typedef +#include +#pragma warning(pop) +#endif + +#ifdef IMAGEAPI // defined by DBGHELP.H +typedef LPAPI_VERSION (NTAPI *PF_ImagehlpApiVersionEx)(_In_ LPAPI_VERSION AppVersion); + +typedef BOOL (NTAPI *PF_SymInitialize)(_In_ HANDLE hProcess, + _In_opt_ LPCSTR UserSearchPath, + _In_ BOOL fInvadeProcess); +typedef DWORD (NTAPI *PF_SymSetOptions)(_In_ DWORD SymOptions); +typedef DWORD (NTAPI *PF_SymGetOptions)(VOID); +typedef DWORD64 (NTAPI *PF_SymLoadModule64)(_In_ HANDLE hProcess, + _In_opt_ HANDLE hFile, + _In_ LPSTR ImageName, + _In_opt_ LPSTR ModuleName, + _In_ DWORD64 BaseOfDll, + _In_opt_ DWORD SizeOfDll); +typedef BOOL (NTAPI *PF_SymGetModuleInfo64)(_In_ HANDLE hProcess, + _In_ DWORD64 qwAddr, + _Out_ PIMAGEHLP_MODULE64 ModuleInfo); +typedef BOOL (NTAPI *PF_SymFromName)(_In_ HANDLE hProcess, + _In_ LPSTR Name, + _Out_ PSYMBOL_INFO Symbol); + +typedef struct _DETOUR_SYM_INFO +{ + HANDLE hProcess; + HMODULE hDbgHelp; + PF_ImagehlpApiVersionEx pfImagehlpApiVersionEx; + PF_SymInitialize pfSymInitialize; + PF_SymSetOptions pfSymSetOptions; + PF_SymGetOptions pfSymGetOptions; + PF_SymLoadModule64 pfSymLoadModule64; + PF_SymGetModuleInfo64 pfSymGetModuleInfo64; + PF_SymFromName pfSymFromName; +} DETOUR_SYM_INFO, *PDETOUR_SYM_INFO; + +PDETOUR_SYM_INFO DetourLoadImageHlp(VOID); + +#endif // IMAGEAPI + +#if defined(_INC_STDIO) && !defined(_CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS) +#error detours.h must be included before stdio.h (or at least define _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS earlier) +#endif +#define _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS 1 + +#ifndef DETOUR_TRACE +#if DETOUR_DEBUG +#define DETOUR_TRACE(x) printf x +#define DETOUR_BREAK() __debugbreak() +#include +#include +#else +#define DETOUR_TRACE(x) +#define DETOUR_BREAK() +#endif +#endif + +#if 1 || defined(DETOURS_IA64) + +// +// IA64 instructions are 41 bits, 3 per bundle, plus 5 bit bundle template => 128 bits per bundle. +// + +#define DETOUR_IA64_INSTRUCTIONS_PER_BUNDLE (3) + +#define DETOUR_IA64_TEMPLATE_OFFSET (0) +#define DETOUR_IA64_TEMPLATE_SIZE (5) + +#define DETOUR_IA64_INSTRUCTION_SIZE (41) +#define DETOUR_IA64_INSTRUCTION0_OFFSET (DETOUR_IA64_TEMPLATE_SIZE) +#define DETOUR_IA64_INSTRUCTION1_OFFSET (DETOUR_IA64_TEMPLATE_SIZE + DETOUR_IA64_INSTRUCTION_SIZE) +#define DETOUR_IA64_INSTRUCTION2_OFFSET (DETOUR_IA64_TEMPLATE_SIZE + DETOUR_IA64_INSTRUCTION_SIZE + DETOUR_IA64_INSTRUCTION_SIZE) + +C_ASSERT(DETOUR_IA64_TEMPLATE_SIZE + DETOUR_IA64_INSTRUCTIONS_PER_BUNDLE * DETOUR_IA64_INSTRUCTION_SIZE == 128); + +__declspec(align(16)) struct DETOUR_IA64_BUNDLE +{ + public: + union + { + BYTE data[16]; + UINT64 wide[2]; + }; + + enum { + A_UNIT = 1u, + I_UNIT = 2u, + M_UNIT = 3u, + B_UNIT = 4u, + F_UNIT = 5u, + L_UNIT = 6u, + X_UNIT = 7u, + }; + struct DETOUR_IA64_METADATA + { + ULONG nTemplate : 8; // Instruction template. + ULONG nUnit0 : 4; // Unit for slot 0 + ULONG nUnit1 : 4; // Unit for slot 1 + ULONG nUnit2 : 4; // Unit for slot 2 + }; + + protected: + static const DETOUR_IA64_METADATA s_rceCopyTable[33]; + + UINT RelocateBundle(_Inout_ DETOUR_IA64_BUNDLE* pDst, _Inout_opt_ DETOUR_IA64_BUNDLE* pBundleExtra) const; + + bool RelocateInstruction(_Inout_ DETOUR_IA64_BUNDLE* pDst, + _In_ BYTE slot, + _Inout_opt_ DETOUR_IA64_BUNDLE* pBundleExtra) const; + + // 120 112 104 96 88 80 72 64 56 48 40 32 24 16 8 0 + // f. e. d. c. b. a. 9. 8. 7. 6. 5. 4. 3. 2. 1. 0. + + // 00 + // f.e. d.c. b.a. 9.8. 7.6. 5.4. 3.2. 1.0. + // 0000 0000 0000 0000 0000 0000 0000 001f : Template [4..0] + // 0000 0000 0000 0000 0000 03ff ffff ffe0 : Zero [ 41.. 5] + // 0000 0000 0000 0000 0000 3c00 0000 0000 : Zero [ 45.. 42] + // 0000 0000 0007 ffff ffff c000 0000 0000 : One [ 82.. 46] + // 0000 0000 0078 0000 0000 0000 0000 0000 : One [ 86.. 83] + // 0fff ffff ff80 0000 0000 0000 0000 0000 : Two [123.. 87] + // f000 0000 0000 0000 0000 0000 0000 0000 : Two [127..124] + BYTE GetTemplate() const; + // Get 4 bit opcodes. + BYTE GetInst0() const; + BYTE GetInst1() const; + BYTE GetInst2() const; + BYTE GetUnit(BYTE slot) const; + BYTE GetUnit0() const; + BYTE GetUnit1() const; + BYTE GetUnit2() const; + // Get 37 bit data. + UINT64 GetData0() const; + UINT64 GetData1() const; + UINT64 GetData2() const; + + // Get/set the full 41 bit instructions. + UINT64 GetInstruction(BYTE slot) const; + UINT64 GetInstruction0() const; + UINT64 GetInstruction1() const; + UINT64 GetInstruction2() const; + void SetInstruction(BYTE slot, UINT64 instruction); + void SetInstruction0(UINT64 instruction); + void SetInstruction1(UINT64 instruction); + void SetInstruction2(UINT64 instruction); + + // Get/set bitfields. + static UINT64 GetBits(UINT64 Value, UINT64 Offset, UINT64 Count); + static UINT64 SetBits(UINT64 Value, UINT64 Offset, UINT64 Count, UINT64 Field); + + // Get specific read-only fields. + static UINT64 GetOpcode(UINT64 instruction); // 4bit opcode + static UINT64 GetX(UINT64 instruction); // 1bit opcode extension + static UINT64 GetX3(UINT64 instruction); // 3bit opcode extension + static UINT64 GetX6(UINT64 instruction); // 6bit opcode extension + + // Get/set specific fields. + static UINT64 GetImm7a(UINT64 instruction); + static UINT64 SetImm7a(UINT64 instruction, UINT64 imm7a); + static UINT64 GetImm13c(UINT64 instruction); + static UINT64 SetImm13c(UINT64 instruction, UINT64 imm13c); + static UINT64 GetSignBit(UINT64 instruction); + static UINT64 SetSignBit(UINT64 instruction, UINT64 signBit); + static UINT64 GetImm20a(UINT64 instruction); + static UINT64 SetImm20a(UINT64 instruction, UINT64 imm20a); + static UINT64 GetImm20b(UINT64 instruction); + static UINT64 SetImm20b(UINT64 instruction, UINT64 imm20b); + + static UINT64 SignExtend(UINT64 Value, UINT64 Offset); + + BOOL IsMovlGp() const; + + VOID SetInst(BYTE Slot, BYTE nInst); + VOID SetInst0(BYTE nInst); + VOID SetInst1(BYTE nInst); + VOID SetInst2(BYTE nInst); + VOID SetData(BYTE Slot, UINT64 nData); + VOID SetData0(UINT64 nData); + VOID SetData1(UINT64 nData); + VOID SetData2(UINT64 nData); + BOOL SetNop(BYTE Slot); + BOOL SetNop0(); + BOOL SetNop1(); + BOOL SetNop2(); + + public: + BOOL IsBrl() const; + VOID SetBrl(); + VOID SetBrl(UINT64 target); + UINT64 GetBrlTarget() const; + VOID SetBrlTarget(UINT64 target); + VOID SetBrlImm(UINT64 imm); + UINT64 GetBrlImm() const; + + UINT64 GetMovlGp() const; + VOID SetMovlGp(UINT64 gp); + + VOID SetStop(); + + UINT Copy(_Out_ DETOUR_IA64_BUNDLE *pDst, _Inout_opt_ DETOUR_IA64_BUNDLE* pBundleExtra = NULL) const; +}; +#endif // DETOURS_IA64 + +#ifdef DETOURS_ARM + +#define DETOURS_PFUNC_TO_PBYTE(p) ((PBYTE)(((ULONG_PTR)(p)) & ~(ULONG_PTR)1)) +#define DETOURS_PBYTE_TO_PFUNC(p) ((PBYTE)(((ULONG_PTR)(p)) | (ULONG_PTR)1)) + +#endif // DETOURS_ARM + +////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +#define DETOUR_OFFLINE_LIBRARY(x) \ +PVOID WINAPI DetourCopyInstruction##x(_In_opt_ PVOID pDst, \ + _Inout_opt_ PVOID *ppDstPool, \ + _In_ PVOID pSrc, \ + _Out_opt_ PVOID *ppTarget, \ + _Out_opt_ LONG *plExtra); \ + \ +BOOL WINAPI DetourSetCodeModule##x(_In_ HMODULE hModule, \ + _In_ BOOL fLimitReferencesToModule); \ + +DETOUR_OFFLINE_LIBRARY(X86) +DETOUR_OFFLINE_LIBRARY(X64) +DETOUR_OFFLINE_LIBRARY(ARM) +DETOUR_OFFLINE_LIBRARY(ARM64) +DETOUR_OFFLINE_LIBRARY(IA64) + +#undef DETOUR_OFFLINE_LIBRARY + +////////////////////////////////////////////////////////////////////////////// +// +// Helpers for manipulating page protection. +// + +_Success_(return != FALSE) +BOOL WINAPI DetourVirtualProtectSameExecuteEx(_In_ HANDLE hProcess, + _In_ PVOID pAddress, + _In_ SIZE_T nSize, + _In_ DWORD dwNewProtect, + _Out_ PDWORD pdwOldProtect); + +_Success_(return != FALSE) +BOOL WINAPI DetourVirtualProtectSameExecute(_In_ PVOID pAddress, + _In_ SIZE_T nSize, + _In_ DWORD dwNewProtect, + _Out_ PDWORD pdwOldProtect); + +// Detours must depend only on kernel32.lib, so we cannot use IsEqualGUID +BOOL WINAPI DetourAreSameGuid(_In_ REFGUID left, _In_ REFGUID right); +#ifdef __cplusplus +} +#endif // __cplusplus + +////////////////////////////////////////////////////////////////////////////// + +#define MM_ALLOCATION_GRANULARITY 0x10000 + +////////////////////////////////////////////////////////////////////////////// + +#endif // DETOURS_INTERNAL +#endif // __cplusplus + +#endif // _DETOURS_H_ +// +//////////////////////////////////////////////////////////////// End of File. diff --git a/src/detour/64/include/detver.h b/src/detour/64/include/detver.h index 3d4f544..7fb4eac 100644 --- a/src/detour/64/include/detver.h +++ b/src/detour/64/include/detver.h @@ -1,27 +1,27 @@ -////////////////////////////////////////////////////////////////////////////// -// -// Common version parameters. -// -// Microsoft Research Detours Package, Version 4.0.1 -// -// Copyright (c) Microsoft Corporation. All rights reserved. -// - -#define _USING_V110_SDK71_ 1 -#include "winver.h" -#if 0 -#include -#include -#else -#ifndef DETOURS_STRINGIFY -#define DETOURS_STRINGIFY_(x) #x -#define DETOURS_STRINGIFY(x) DETOURS_STRINGIFY_(x) -#endif - -#define VER_FILEFLAGSMASK 0x3fL -#define VER_FILEFLAGS 0x0L -#define VER_FILEOS 0x00040004L -#define VER_FILETYPE 0x00000002L -#define VER_FILESUBTYPE 0x00000000L -#endif -#define VER_DETOURS_BITS DETOURS_STRINGIFY(DETOURS_BITS) +////////////////////////////////////////////////////////////////////////////// +// +// Common version parameters. +// +// Microsoft Research Detours Package, Version 4.0.1 +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// + +#define _USING_V110_SDK71_ 1 +#include "winver.h" +#if 0 +#include +#include +#else +#ifndef DETOURS_STRINGIFY +#define DETOURS_STRINGIFY_(x) #x +#define DETOURS_STRINGIFY(x) DETOURS_STRINGIFY_(x) +#endif + +#define VER_FILEFLAGSMASK 0x3fL +#define VER_FILEFLAGS 0x0L +#define VER_FILEOS 0x00040004L +#define VER_FILETYPE 0x00000002L +#define VER_FILESUBTYPE 0x00000000L +#endif +#define VER_DETOURS_BITS DETOURS_STRINGIFY(DETOURS_BITS) diff --git a/src/detour/64/include/syelog.h b/src/detour/64/include/syelog.h index 7cfa9f3..e34e494 100644 --- a/src/detour/64/include/syelog.h +++ b/src/detour/64/include/syelog.h @@ -1,89 +1,89 @@ -////////////////////////////////////////////////////////////////////////////// -// -// Detours Test Program (syelog.h of syelog.lib) -// -// Microsoft Research Detours Package -// -// Copyright (c) Microsoft Corporation. All rights reserved. -// -#pragma once -#ifndef _SYELOGD_H_ -#define _SYELOGD_H_ -#include - -#pragma pack(push, 1) -#pragma warning(push) -#pragma warning(disable: 4200) - -////////////////////////////////////////////////////////////////////////////// -// -// -#define SYELOG_PIPE_NAMEA "\\\\.\\pipe\\syelog" -#define SYELOG_PIPE_NAMEW L"\\\\.\\pipe\\syelog" -#ifdef UNICODE -#define SYELOG_PIPE_NAME SYELOG_PIPE_NAMEW -#else -#define SYELOG_PIPE_NAME SYELOG_PIPE_NAMEA -#endif - -////////////////////////////////////////////////////////////////////////////// -// -#define SYELOG_MAXIMUM_MESSAGE 4086 // 4096 - sizeof(header stuff) - -typedef struct _SYELOG_MESSAGE -{ - USHORT nBytes; - BYTE nFacility; - BYTE nSeverity; - DWORD nProcessId; - FILETIME ftOccurance; - BOOL fTerminate; - CHAR szMessage[SYELOG_MAXIMUM_MESSAGE]; -} SYELOG_MESSAGE, *PSYELOG_MESSAGE; - - -// Facility Codes. -// -#define SYELOG_FACILITY_KERNEL 0x10 // OS Kernel -#define SYELOG_FACILITY_SECURITY 0x20 // OS Security -#define SYELOG_FACILITY_LOGGING 0x30 // OS Logging-internal -#define SYELOG_FACILITY_SERVICE 0x40 // User-mode system daemon -#define SYELOG_FACILITY_APPLICATION 0x50 // User-mode application -#define SYELOG_FACILITY_USER 0x60 // User self-generated. -#define SYELOG_FACILITY_LOCAL0 0x70 // Locally defined. -#define SYELOG_FACILITY_LOCAL1 0x71 // Locally defined. -#define SYELOG_FACILITY_LOCAL2 0x72 // Locally defined. -#define SYELOG_FACILITY_LOCAL3 0x73 // Locally defined. -#define SYELOG_FACILITY_LOCAL4 0x74 // Locally defined. -#define SYELOG_FACILITY_LOCAL5 0x75 // Locally defined. -#define SYELOG_FACILITY_LOCAL6 0x76 // Locally defined. -#define SYELOG_FACILITY_LOCAL7 0x77 // Locally defined. -#define SYELOG_FACILITY_LOCAL8 0x78 // Locally defined. -#define SYELOG_FACILITY_LOCAL9 0x79 // Locally defined. - -// Severity Codes. -// -#define SYELOG_SEVERITY_FATAL 0x00 // System is dead. -#define SYELOG_SEVERITY_ALERT 0x10 // Take action immediately. -#define SYELOG_SEVERITY_CRITICAL 0x20 // Critical condition. -#define SYELOG_SEVERITY_ERROR 0x30 // Error -#define SYELOG_SEVERITY_WARNING 0x40 // Warning -#define SYELOG_SEVERITY_NOTICE 0x50 // Significant condition. -#define SYELOG_SEVERITY_INFORMATION 0x60 // Informational -#define SYELOG_SEVERITY_AUDIT_FAIL 0x66 // Audit Failed -#define SYELOG_SEVERITY_AUDIT_PASS 0x67 // Audit Succeeeded -#define SYELOG_SEVERITY_DEBUG 0x70 // Debugging - -// Logging Functions. -// -VOID SyelogOpen(PCSTR pszIdentifier, BYTE nFacility); -VOID Syelog(BYTE nSeverity, PCSTR pszMsgf, ...); -VOID SyelogV(BYTE nSeverity, PCSTR pszMsgf, va_list args); -VOID SyelogClose(BOOL fTerminate); - -#pragma warning(pop) -#pragma pack(pop) - -#endif // _SYELOGD_H_ -// -///////////////////////////////////////////////////////////////// End of File. +////////////////////////////////////////////////////////////////////////////// +// +// Detours Test Program (syelog.h of syelog.lib) +// +// Microsoft Research Detours Package +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +#pragma once +#ifndef _SYELOGD_H_ +#define _SYELOGD_H_ +#include + +#pragma pack(push, 1) +#pragma warning(push) +#pragma warning(disable: 4200) + +////////////////////////////////////////////////////////////////////////////// +// +// +#define SYELOG_PIPE_NAMEA "\\\\.\\pipe\\syelog" +#define SYELOG_PIPE_NAMEW L"\\\\.\\pipe\\syelog" +#ifdef UNICODE +#define SYELOG_PIPE_NAME SYELOG_PIPE_NAMEW +#else +#define SYELOG_PIPE_NAME SYELOG_PIPE_NAMEA +#endif + +////////////////////////////////////////////////////////////////////////////// +// +#define SYELOG_MAXIMUM_MESSAGE 4086 // 4096 - sizeof(header stuff) + +typedef struct _SYELOG_MESSAGE +{ + USHORT nBytes; + BYTE nFacility; + BYTE nSeverity; + DWORD nProcessId; + FILETIME ftOccurance; + BOOL fTerminate; + CHAR szMessage[SYELOG_MAXIMUM_MESSAGE]; +} SYELOG_MESSAGE, *PSYELOG_MESSAGE; + + +// Facility Codes. +// +#define SYELOG_FACILITY_KERNEL 0x10 // OS Kernel +#define SYELOG_FACILITY_SECURITY 0x20 // OS Security +#define SYELOG_FACILITY_LOGGING 0x30 // OS Logging-internal +#define SYELOG_FACILITY_SERVICE 0x40 // User-mode system daemon +#define SYELOG_FACILITY_APPLICATION 0x50 // User-mode application +#define SYELOG_FACILITY_USER 0x60 // User self-generated. +#define SYELOG_FACILITY_LOCAL0 0x70 // Locally defined. +#define SYELOG_FACILITY_LOCAL1 0x71 // Locally defined. +#define SYELOG_FACILITY_LOCAL2 0x72 // Locally defined. +#define SYELOG_FACILITY_LOCAL3 0x73 // Locally defined. +#define SYELOG_FACILITY_LOCAL4 0x74 // Locally defined. +#define SYELOG_FACILITY_LOCAL5 0x75 // Locally defined. +#define SYELOG_FACILITY_LOCAL6 0x76 // Locally defined. +#define SYELOG_FACILITY_LOCAL7 0x77 // Locally defined. +#define SYELOG_FACILITY_LOCAL8 0x78 // Locally defined. +#define SYELOG_FACILITY_LOCAL9 0x79 // Locally defined. + +// Severity Codes. +// +#define SYELOG_SEVERITY_FATAL 0x00 // System is dead. +#define SYELOG_SEVERITY_ALERT 0x10 // Take action immediately. +#define SYELOG_SEVERITY_CRITICAL 0x20 // Critical condition. +#define SYELOG_SEVERITY_ERROR 0x30 // Error +#define SYELOG_SEVERITY_WARNING 0x40 // Warning +#define SYELOG_SEVERITY_NOTICE 0x50 // Significant condition. +#define SYELOG_SEVERITY_INFORMATION 0x60 // Informational +#define SYELOG_SEVERITY_AUDIT_FAIL 0x66 // Audit Failed +#define SYELOG_SEVERITY_AUDIT_PASS 0x67 // Audit Succeeeded +#define SYELOG_SEVERITY_DEBUG 0x70 // Debugging + +// Logging Functions. +// +VOID SyelogOpen(PCSTR pszIdentifier, BYTE nFacility); +VOID Syelog(BYTE nSeverity, PCSTR pszMsgf, ...); +VOID SyelogV(BYTE nSeverity, PCSTR pszMsgf, va_list args); +VOID SyelogClose(BOOL fTerminate); + +#pragma warning(pop) +#pragma pack(pop) + +#endif // _SYELOGD_H_ +// +///////////////////////////////////////////////////////////////// End of File. diff --git a/src/detour/86/include/detours.h b/src/detour/86/include/detours.h index 47dd3ea..b02165b 100644 --- a/src/detour/86/include/detours.h +++ b/src/detour/86/include/detours.h @@ -1,1209 +1,1209 @@ -///////////////////////////////////////////////////////////////////////////// -// -// Core Detours Functionality (detours.h of detours.lib) -// -// Microsoft Research Detours Package, Version 4.0.1 -// -// Copyright (c) Microsoft Corporation. All rights reserved. -// - -#pragma once -#ifndef _DETOURS_H_ -#define _DETOURS_H_ - -#define DETOURS_VERSION 0x4c0c1 // 0xMAJORcMINORcPATCH - -////////////////////////////////////////////////////////////////////////////// -// - -#ifdef DETOURS_INTERNAL - -#define _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS 1 -#define _ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE 1 - -#pragma warning(disable:4068) // unknown pragma (suppress) - -#if _MSC_VER >= 1900 -#pragma warning(push) -#pragma warning(disable:4091) // empty typedef -#endif - -// Suppress declspec(dllimport) for the sake of Detours -// users that provide kernel32 functionality themselves. -// This is ok in the mainstream case, it will just cost -// an extra instruction calling some functions, which -// LTCG optimizes away. -// -#define _KERNEL32_ 1 -#define _USER32_ 1 - -#include -#if (_MSC_VER < 1310) -#else -#pragma warning(push) -#if _MSC_VER > 1400 -#pragma warning(disable:6102 6103) // /analyze warnings -#endif -#include -#include -#pragma warning(pop) -#endif - -// Allow Detours to cleanly compile with the MingW toolchain. -// -#ifdef __GNUC__ -#define __try -#define __except(x) if (0) -#include -#endif - -// From winerror.h, as this error isn't found in some SDKs: -// -// MessageId: ERROR_DYNAMIC_CODE_BLOCKED -// -// MessageText: -// -// The operation was blocked as the process prohibits dynamic code generation. -// -#define ERROR_DYNAMIC_CODE_BLOCKED 1655L - -#endif // DETOURS_INTERNAL - -////////////////////////////////////////////////////////////////////////////// -// - -#undef DETOURS_X64 -#undef DETOURS_X86 -#undef DETOURS_IA64 -#undef DETOURS_ARM -#undef DETOURS_ARM64 -#undef DETOURS_BITS -#undef DETOURS_32BIT -#undef DETOURS_64BIT - -#if defined(_X86_) -#define DETOURS_X86 -#define DETOURS_OPTION_BITS 64 - -#elif defined(_AMD64_) -#define DETOURS_X64 -#define DETOURS_OPTION_BITS 32 - -#elif defined(_IA64_) -#define DETOURS_IA64 -#define DETOURS_OPTION_BITS 32 - -#elif defined(_ARM_) -#define DETOURS_ARM - -#elif defined(_ARM64_) -#define DETOURS_ARM64 - -#else -#error Unknown architecture (x86, amd64, ia64, arm, arm64) -#endif - -#ifdef _WIN64 -#undef DETOURS_32BIT -#define DETOURS_64BIT 1 -#define DETOURS_BITS 64 -// If all 64bit kernels can run one and only one 32bit architecture. -//#define DETOURS_OPTION_BITS 32 -#else -#define DETOURS_32BIT 1 -#undef DETOURS_64BIT -#define DETOURS_BITS 32 -// If all 64bit kernels can run one and only one 32bit architecture. -//#define DETOURS_OPTION_BITS 32 -#endif - -/////////////////////////////////////////////////////////////// Helper Macros. -// -#define DETOURS_STRINGIFY_(x) #x -#define DETOURS_STRINGIFY(x) DETOURS_STRINGIFY_(x) - -#define VER_DETOURS_BITS DETOURS_STRINGIFY(DETOURS_BITS) - -////////////////////////////////////////////////////////////////////////////// -// - -#if (_MSC_VER < 1299) && !defined(__MINGW32__) -typedef LONG LONG_PTR; -typedef ULONG ULONG_PTR; -#endif - -///////////////////////////////////////////////// SAL 2.0 Annotations w/o SAL. -// -// These definitions are include so that Detours will build even if the -// compiler doesn't have full SAL 2.0 support. -// -#ifndef DETOURS_DONT_REMOVE_SAL_20 - -#ifdef DETOURS_TEST_REMOVE_SAL_20 -#undef _Analysis_assume_ -#undef _Benign_race_begin_ -#undef _Benign_race_end_ -#undef _Field_range_ -#undef _Field_size_ -#undef _In_ -#undef _In_bytecount_ -#undef _In_count_ -#undef __in_ecount -#undef _In_opt_ -#undef _In_opt_bytecount_ -#undef _In_opt_count_ -#undef _In_opt_z_ -#undef _In_range_ -#undef _In_reads_ -#undef _In_reads_bytes_ -#undef _In_reads_opt_ -#undef _In_reads_opt_bytes_ -#undef _In_reads_or_z_ -#undef _In_z_ -#undef _Inout_ -#undef _Inout_opt_ -#undef _Inout_z_count_ -#undef _Out_ -#undef _Out_opt_ -#undef _Out_writes_ -#undef _Outptr_result_maybenull_ -#undef _Readable_bytes_ -#undef _Success_ -#undef _Writable_bytes_ -#undef _Pre_notnull_ -#endif - -#if defined(_Deref_out_opt_z_) && !defined(_Outptr_result_maybenull_) -#define _Outptr_result_maybenull_ _Deref_out_opt_z_ -#endif - -#if defined(_In_count_) && !defined(_In_reads_) -#define _In_reads_(x) _In_count_(x) -#endif - -#if defined(_In_opt_count_) && !defined(_In_reads_opt_) -#define _In_reads_opt_(x) _In_opt_count_(x) -#endif - -#if defined(_In_opt_bytecount_) && !defined(_In_reads_opt_bytes_) -#define _In_reads_opt_bytes_(x) _In_opt_bytecount_(x) -#endif - -#if defined(_In_bytecount_) && !defined(_In_reads_bytes_) -#define _In_reads_bytes_(x) _In_bytecount_(x) -#endif - -#ifndef _In_ -#define _In_ -#endif - -#ifndef _In_bytecount_ -#define _In_bytecount_(x) -#endif - -#ifndef _In_count_ -#define _In_count_(x) -#endif - -#ifndef __in_ecount -#define __in_ecount(x) -#endif - -#ifndef _In_opt_ -#define _In_opt_ -#endif - -#ifndef _In_opt_bytecount_ -#define _In_opt_bytecount_(x) -#endif - -#ifndef _In_opt_count_ -#define _In_opt_count_(x) -#endif - -#ifndef _In_opt_z_ -#define _In_opt_z_ -#endif - -#ifndef _In_range_ -#define _In_range_(x,y) -#endif - -#ifndef _In_reads_ -#define _In_reads_(x) -#endif - -#ifndef _In_reads_bytes_ -#define _In_reads_bytes_(x) -#endif - -#ifndef _In_reads_opt_ -#define _In_reads_opt_(x) -#endif - -#ifndef _In_reads_opt_bytes_ -#define _In_reads_opt_bytes_(x) -#endif - -#ifndef _In_reads_or_z_ -#define _In_reads_or_z_ -#endif - -#ifndef _In_z_ -#define _In_z_ -#endif - -#ifndef _Inout_ -#define _Inout_ -#endif - -#ifndef _Inout_opt_ -#define _Inout_opt_ -#endif - -#ifndef _Inout_z_count_ -#define _Inout_z_count_(x) -#endif - -#ifndef _Out_ -#define _Out_ -#endif - -#ifndef _Out_opt_ -#define _Out_opt_ -#endif - -#ifndef _Out_writes_ -#define _Out_writes_(x) -#endif - -#ifndef _Outptr_result_maybenull_ -#define _Outptr_result_maybenull_ -#endif - -#ifndef _Writable_bytes_ -#define _Writable_bytes_(x) -#endif - -#ifndef _Readable_bytes_ -#define _Readable_bytes_(x) -#endif - -#ifndef _Success_ -#define _Success_(x) -#endif - -#ifndef _Pre_notnull_ -#define _Pre_notnull_ -#endif - -#ifdef DETOURS_INTERNAL - -#pragma warning(disable:4615) // unknown warning type (suppress with older compilers) - -#ifndef _Benign_race_begin_ -#define _Benign_race_begin_ -#endif - -#ifndef _Benign_race_end_ -#define _Benign_race_end_ -#endif - -#ifndef _Field_size_ -#define _Field_size_(x) -#endif - -#ifndef _Field_range_ -#define _Field_range_(x,y) -#endif - -#ifndef _Analysis_assume_ -#define _Analysis_assume_(x) -#endif - -#endif // DETOURS_INTERNAL -#endif // DETOURS_DONT_REMOVE_SAL_20 - -////////////////////////////////////////////////////////////////////////////// -// -#ifndef GUID_DEFINED -#define GUID_DEFINED -typedef struct _GUID -{ - DWORD Data1; - WORD Data2; - WORD Data3; - BYTE Data4[ 8 ]; -} GUID; - -#ifdef INITGUID -#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ - const GUID name \ - = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } -#else -#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ - const GUID name -#endif // INITGUID -#endif // !GUID_DEFINED - -#if defined(__cplusplus) -#ifndef _REFGUID_DEFINED -#define _REFGUID_DEFINED -#define REFGUID const GUID & -#endif // !_REFGUID_DEFINED -#else // !__cplusplus -#ifndef _REFGUID_DEFINED -#define _REFGUID_DEFINED -#define REFGUID const GUID * const -#endif // !_REFGUID_DEFINED -#endif // !__cplusplus - -#ifndef ARRAYSIZE -#define ARRAYSIZE(x) (sizeof(x)/sizeof(x[0])) -#endif - -// -////////////////////////////////////////////////////////////////////////////// - -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus - -/////////////////////////////////////////////////// Instruction Target Macros. -// -#define DETOUR_INSTRUCTION_TARGET_NONE ((PVOID)0) -#define DETOUR_INSTRUCTION_TARGET_DYNAMIC ((PVOID)(LONG_PTR)-1) -#define DETOUR_SECTION_HEADER_SIGNATURE 0x00727444 // "Dtr\0" - -extern const GUID DETOUR_EXE_RESTORE_GUID; -extern const GUID DETOUR_EXE_HELPER_GUID; - -#define DETOUR_TRAMPOLINE_SIGNATURE 0x21727444 // Dtr! -typedef struct _DETOUR_TRAMPOLINE DETOUR_TRAMPOLINE, *PDETOUR_TRAMPOLINE; - -/////////////////////////////////////////////////////////// Binary Structures. -// -#pragma pack(push, 8) -typedef struct _DETOUR_SECTION_HEADER -{ - DWORD cbHeaderSize; - DWORD nSignature; - DWORD nDataOffset; - DWORD cbDataSize; - - DWORD nOriginalImportVirtualAddress; - DWORD nOriginalImportSize; - DWORD nOriginalBoundImportVirtualAddress; - DWORD nOriginalBoundImportSize; - - DWORD nOriginalIatVirtualAddress; - DWORD nOriginalIatSize; - DWORD nOriginalSizeOfImage; - DWORD cbPrePE; - - DWORD nOriginalClrFlags; - DWORD reserved1; - DWORD reserved2; - DWORD reserved3; - - // Followed by cbPrePE bytes of data. -} DETOUR_SECTION_HEADER, *PDETOUR_SECTION_HEADER; - -typedef struct _DETOUR_SECTION_RECORD -{ - DWORD cbBytes; - DWORD nReserved; - GUID guid; -} DETOUR_SECTION_RECORD, *PDETOUR_SECTION_RECORD; - -typedef struct _DETOUR_CLR_HEADER -{ - // Header versioning - ULONG cb; - USHORT MajorRuntimeVersion; - USHORT MinorRuntimeVersion; - - // Symbol table and startup information - IMAGE_DATA_DIRECTORY MetaData; - ULONG Flags; - - // Followed by the rest of the IMAGE_COR20_HEADER -} DETOUR_CLR_HEADER, *PDETOUR_CLR_HEADER; - -typedef struct _DETOUR_EXE_RESTORE -{ - DWORD cb; - DWORD cbidh; - DWORD cbinh; - DWORD cbclr; - - PBYTE pidh; - PBYTE pinh; - PBYTE pclr; - - IMAGE_DOS_HEADER idh; - union { - IMAGE_NT_HEADERS inh; // all environments have this -#ifdef IMAGE_NT_OPTIONAL_HDR32_MAGIC // some environments do not have this - IMAGE_NT_HEADERS32 inh32; -#endif -#ifdef IMAGE_NT_OPTIONAL_HDR64_MAGIC // some environments do not have this - IMAGE_NT_HEADERS64 inh64; -#endif -#ifdef IMAGE_NT_OPTIONAL_HDR64_MAGIC // some environments do not have this - BYTE raw[sizeof(IMAGE_NT_HEADERS64) + - sizeof(IMAGE_SECTION_HEADER) * 32]; -#else - BYTE raw[0x108 + sizeof(IMAGE_SECTION_HEADER) * 32]; -#endif - }; - DETOUR_CLR_HEADER clr; - -} DETOUR_EXE_RESTORE, *PDETOUR_EXE_RESTORE; - -#ifdef IMAGE_NT_OPTIONAL_HDR64_MAGIC -C_ASSERT(sizeof(IMAGE_NT_HEADERS64) == 0x108); -#endif - -// The size can change, but assert for clarity due to the muddying #ifdefs. -#ifdef _WIN64 -C_ASSERT(sizeof(DETOUR_EXE_RESTORE) == 0x688); -#else -C_ASSERT(sizeof(DETOUR_EXE_RESTORE) == 0x678); -#endif - -typedef struct _DETOUR_EXE_HELPER -{ - DWORD cb; - DWORD pid; - DWORD nDlls; - CHAR rDlls[4]; -} DETOUR_EXE_HELPER, *PDETOUR_EXE_HELPER; - -#pragma pack(pop) - -#define DETOUR_SECTION_HEADER_DECLARE(cbSectionSize) \ -{ \ - sizeof(DETOUR_SECTION_HEADER),\ - DETOUR_SECTION_HEADER_SIGNATURE,\ - sizeof(DETOUR_SECTION_HEADER),\ - (cbSectionSize),\ - \ - 0,\ - 0,\ - 0,\ - 0,\ - \ - 0,\ - 0,\ - 0,\ - 0,\ -} - -///////////////////////////////////////////////////////////// Binary Typedefs. -// -typedef BOOL (CALLBACK *PF_DETOUR_BINARY_BYWAY_CALLBACK)( - _In_opt_ PVOID pContext, - _In_opt_ LPCSTR pszFile, - _Outptr_result_maybenull_ LPCSTR *ppszOutFile); - -typedef BOOL (CALLBACK *PF_DETOUR_BINARY_FILE_CALLBACK)( - _In_opt_ PVOID pContext, - _In_ LPCSTR pszOrigFile, - _In_ LPCSTR pszFile, - _Outptr_result_maybenull_ LPCSTR *ppszOutFile); - -typedef BOOL (CALLBACK *PF_DETOUR_BINARY_SYMBOL_CALLBACK)( - _In_opt_ PVOID pContext, - _In_ ULONG nOrigOrdinal, - _In_ ULONG nOrdinal, - _Out_ ULONG *pnOutOrdinal, - _In_opt_ LPCSTR pszOrigSymbol, - _In_opt_ LPCSTR pszSymbol, - _Outptr_result_maybenull_ LPCSTR *ppszOutSymbol); - -typedef BOOL (CALLBACK *PF_DETOUR_BINARY_COMMIT_CALLBACK)( - _In_opt_ PVOID pContext); - -typedef BOOL (CALLBACK *PF_DETOUR_ENUMERATE_EXPORT_CALLBACK)(_In_opt_ PVOID pContext, - _In_ ULONG nOrdinal, - _In_opt_ LPCSTR pszName, - _In_opt_ PVOID pCode); - -typedef BOOL (CALLBACK *PF_DETOUR_IMPORT_FILE_CALLBACK)(_In_opt_ PVOID pContext, - _In_opt_ HMODULE hModule, - _In_opt_ LPCSTR pszFile); - -typedef BOOL (CALLBACK *PF_DETOUR_IMPORT_FUNC_CALLBACK)(_In_opt_ PVOID pContext, - _In_ DWORD nOrdinal, - _In_opt_ LPCSTR pszFunc, - _In_opt_ PVOID pvFunc); - -// Same as PF_DETOUR_IMPORT_FUNC_CALLBACK but extra indirection on last parameter. -typedef BOOL (CALLBACK *PF_DETOUR_IMPORT_FUNC_CALLBACK_EX)(_In_opt_ PVOID pContext, - _In_ DWORD nOrdinal, - _In_opt_ LPCSTR pszFunc, - _In_opt_ PVOID* ppvFunc); - -typedef VOID * PDETOUR_BINARY; -typedef VOID * PDETOUR_LOADED_BINARY; - -//////////////////////////////////////////////////////////// Transaction APIs. -// -LONG WINAPI DetourTransactionBegin(VOID); -LONG WINAPI DetourTransactionAbort(VOID); -LONG WINAPI DetourTransactionCommit(VOID); -LONG WINAPI DetourTransactionCommitEx(_Out_opt_ PVOID **pppFailedPointer); - -LONG WINAPI DetourUpdateThread(_In_ HANDLE hThread); - -LONG WINAPI DetourAttach(_Inout_ PVOID *ppPointer, - _In_ PVOID pDetour); - -LONG WINAPI DetourAttachEx(_Inout_ PVOID *ppPointer, - _In_ PVOID pDetour, - _Out_opt_ PDETOUR_TRAMPOLINE *ppRealTrampoline, - _Out_opt_ PVOID *ppRealTarget, - _Out_opt_ PVOID *ppRealDetour); - -LONG WINAPI DetourDetach(_Inout_ PVOID *ppPointer, - _In_ PVOID pDetour); - -BOOL WINAPI DetourSetIgnoreTooSmall(_In_ BOOL fIgnore); -BOOL WINAPI DetourSetRetainRegions(_In_ BOOL fRetain); -PVOID WINAPI DetourSetSystemRegionLowerBound(_In_ PVOID pSystemRegionLowerBound); -PVOID WINAPI DetourSetSystemRegionUpperBound(_In_ PVOID pSystemRegionUpperBound); - -////////////////////////////////////////////////////////////// Code Functions. -// -PVOID WINAPI DetourFindFunction(_In_ LPCSTR pszModule, - _In_ LPCSTR pszFunction); -PVOID WINAPI DetourCodeFromPointer(_In_ PVOID pPointer, - _Out_opt_ PVOID *ppGlobals); -PVOID WINAPI DetourCopyInstruction(_In_opt_ PVOID pDst, - _Inout_opt_ PVOID *ppDstPool, - _In_ PVOID pSrc, - _Out_opt_ PVOID *ppTarget, - _Out_opt_ LONG *plExtra); -BOOL WINAPI DetourSetCodeModule(_In_ HMODULE hModule, - _In_ BOOL fLimitReferencesToModule); -PVOID WINAPI DetourAllocateRegionWithinJumpBounds(_In_ LPCVOID pbTarget, - _Out_ PDWORD pcbAllocatedSize); - -///////////////////////////////////////////////////// Loaded Binary Functions. -// -HMODULE WINAPI DetourGetContainingModule(_In_ PVOID pvAddr); -HMODULE WINAPI DetourEnumerateModules(_In_opt_ HMODULE hModuleLast); -PVOID WINAPI DetourGetEntryPoint(_In_opt_ HMODULE hModule); -ULONG WINAPI DetourGetModuleSize(_In_opt_ HMODULE hModule); -BOOL WINAPI DetourEnumerateExports(_In_ HMODULE hModule, - _In_opt_ PVOID pContext, - _In_ PF_DETOUR_ENUMERATE_EXPORT_CALLBACK pfExport); -BOOL WINAPI DetourEnumerateImports(_In_opt_ HMODULE hModule, - _In_opt_ PVOID pContext, - _In_opt_ PF_DETOUR_IMPORT_FILE_CALLBACK pfImportFile, - _In_opt_ PF_DETOUR_IMPORT_FUNC_CALLBACK pfImportFunc); - -BOOL WINAPI DetourEnumerateImportsEx(_In_opt_ HMODULE hModule, - _In_opt_ PVOID pContext, - _In_opt_ PF_DETOUR_IMPORT_FILE_CALLBACK pfImportFile, - _In_opt_ PF_DETOUR_IMPORT_FUNC_CALLBACK_EX pfImportFuncEx); - -_Writable_bytes_(*pcbData) -_Readable_bytes_(*pcbData) -_Success_(return != NULL) -PVOID WINAPI DetourFindPayload(_In_opt_ HMODULE hModule, - _In_ REFGUID rguid, - _Out_opt_ DWORD *pcbData); - -_Writable_bytes_(*pcbData) -_Readable_bytes_(*pcbData) -_Success_(return != NULL) -PVOID WINAPI DetourFindPayloadEx(_In_ REFGUID rguid, - _Out_opt_ DWORD *pcbData); - -DWORD WINAPI DetourGetSizeOfPayloads(_In_opt_ HMODULE hModule); - -///////////////////////////////////////////////// Persistent Binary Functions. -// - -PDETOUR_BINARY WINAPI DetourBinaryOpen(_In_ HANDLE hFile); - -_Writable_bytes_(*pcbData) -_Readable_bytes_(*pcbData) -_Success_(return != NULL) -PVOID WINAPI DetourBinaryEnumeratePayloads(_In_ PDETOUR_BINARY pBinary, - _Out_opt_ GUID *pGuid, - _Out_ DWORD *pcbData, - _Inout_ DWORD *pnIterator); - -_Writable_bytes_(*pcbData) -_Readable_bytes_(*pcbData) -_Success_(return != NULL) -PVOID WINAPI DetourBinaryFindPayload(_In_ PDETOUR_BINARY pBinary, - _In_ REFGUID rguid, - _Out_ DWORD *pcbData); - -PVOID WINAPI DetourBinarySetPayload(_In_ PDETOUR_BINARY pBinary, - _In_ REFGUID rguid, - _In_reads_opt_(cbData) PVOID pData, - _In_ DWORD cbData); -BOOL WINAPI DetourBinaryDeletePayload(_In_ PDETOUR_BINARY pBinary, _In_ REFGUID rguid); -BOOL WINAPI DetourBinaryPurgePayloads(_In_ PDETOUR_BINARY pBinary); -BOOL WINAPI DetourBinaryResetImports(_In_ PDETOUR_BINARY pBinary); -BOOL WINAPI DetourBinaryEditImports(_In_ PDETOUR_BINARY pBinary, - _In_opt_ PVOID pContext, - _In_opt_ PF_DETOUR_BINARY_BYWAY_CALLBACK pfByway, - _In_opt_ PF_DETOUR_BINARY_FILE_CALLBACK pfFile, - _In_opt_ PF_DETOUR_BINARY_SYMBOL_CALLBACK pfSymbol, - _In_opt_ PF_DETOUR_BINARY_COMMIT_CALLBACK pfCommit); -BOOL WINAPI DetourBinaryWrite(_In_ PDETOUR_BINARY pBinary, _In_ HANDLE hFile); -BOOL WINAPI DetourBinaryClose(_In_ PDETOUR_BINARY pBinary); - -/////////////////////////////////////////////////// Create Process & Load Dll. -// -_Success_(return != NULL) -PVOID WINAPI DetourFindRemotePayload(_In_ HANDLE hProcess, - _In_ REFGUID rguid, - _Out_opt_ DWORD *pcbData); - -typedef BOOL (WINAPI *PDETOUR_CREATE_PROCESS_ROUTINEA)( - _In_opt_ LPCSTR lpApplicationName, - _Inout_opt_ LPSTR lpCommandLine, - _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, - _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, - _In_ BOOL bInheritHandles, - _In_ DWORD dwCreationFlags, - _In_opt_ LPVOID lpEnvironment, - _In_opt_ LPCSTR lpCurrentDirectory, - _In_ LPSTARTUPINFOA lpStartupInfo, - _Out_ LPPROCESS_INFORMATION lpProcessInformation); - -typedef BOOL (WINAPI *PDETOUR_CREATE_PROCESS_ROUTINEW)( - _In_opt_ LPCWSTR lpApplicationName, - _Inout_opt_ LPWSTR lpCommandLine, - _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, - _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, - _In_ BOOL bInheritHandles, - _In_ DWORD dwCreationFlags, - _In_opt_ LPVOID lpEnvironment, - _In_opt_ LPCWSTR lpCurrentDirectory, - _In_ LPSTARTUPINFOW lpStartupInfo, - _Out_ LPPROCESS_INFORMATION lpProcessInformation); - -BOOL WINAPI DetourCreateProcessWithDllA(_In_opt_ LPCSTR lpApplicationName, - _Inout_opt_ LPSTR lpCommandLine, - _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, - _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, - _In_ BOOL bInheritHandles, - _In_ DWORD dwCreationFlags, - _In_opt_ LPVOID lpEnvironment, - _In_opt_ LPCSTR lpCurrentDirectory, - _In_ LPSTARTUPINFOA lpStartupInfo, - _Out_ LPPROCESS_INFORMATION lpProcessInformation, - _In_ LPCSTR lpDllName, - _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); - -BOOL WINAPI DetourCreateProcessWithDllW(_In_opt_ LPCWSTR lpApplicationName, - _Inout_opt_ LPWSTR lpCommandLine, - _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, - _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, - _In_ BOOL bInheritHandles, - _In_ DWORD dwCreationFlags, - _In_opt_ LPVOID lpEnvironment, - _In_opt_ LPCWSTR lpCurrentDirectory, - _In_ LPSTARTUPINFOW lpStartupInfo, - _Out_ LPPROCESS_INFORMATION lpProcessInformation, - _In_ LPCSTR lpDllName, - _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); - -#ifdef UNICODE -#define DetourCreateProcessWithDll DetourCreateProcessWithDllW -#define PDETOUR_CREATE_PROCESS_ROUTINE PDETOUR_CREATE_PROCESS_ROUTINEW -#else -#define DetourCreateProcessWithDll DetourCreateProcessWithDllA -#define PDETOUR_CREATE_PROCESS_ROUTINE PDETOUR_CREATE_PROCESS_ROUTINEA -#endif // !UNICODE - -BOOL WINAPI DetourCreateProcessWithDllExA(_In_opt_ LPCSTR lpApplicationName, - _Inout_opt_ LPSTR lpCommandLine, - _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, - _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, - _In_ BOOL bInheritHandles, - _In_ DWORD dwCreationFlags, - _In_opt_ LPVOID lpEnvironment, - _In_opt_ LPCSTR lpCurrentDirectory, - _In_ LPSTARTUPINFOA lpStartupInfo, - _Out_ LPPROCESS_INFORMATION lpProcessInformation, - _In_ LPCSTR lpDllName, - _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); - -BOOL WINAPI DetourCreateProcessWithDllExW(_In_opt_ LPCWSTR lpApplicationName, - _Inout_opt_ LPWSTR lpCommandLine, - _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, - _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, - _In_ BOOL bInheritHandles, - _In_ DWORD dwCreationFlags, - _In_opt_ LPVOID lpEnvironment, - _In_opt_ LPCWSTR lpCurrentDirectory, - _In_ LPSTARTUPINFOW lpStartupInfo, - _Out_ LPPROCESS_INFORMATION lpProcessInformation, - _In_ LPCSTR lpDllName, - _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); - -#ifdef UNICODE -#define DetourCreateProcessWithDllEx DetourCreateProcessWithDllExW -#else -#define DetourCreateProcessWithDllEx DetourCreateProcessWithDllExA -#endif // !UNICODE - -BOOL WINAPI DetourCreateProcessWithDllsA(_In_opt_ LPCSTR lpApplicationName, - _Inout_opt_ LPSTR lpCommandLine, - _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, - _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, - _In_ BOOL bInheritHandles, - _In_ DWORD dwCreationFlags, - _In_opt_ LPVOID lpEnvironment, - _In_opt_ LPCSTR lpCurrentDirectory, - _In_ LPSTARTUPINFOA lpStartupInfo, - _Out_ LPPROCESS_INFORMATION lpProcessInformation, - _In_ DWORD nDlls, - _In_reads_(nDlls) LPCSTR *rlpDlls, - _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); - -BOOL WINAPI DetourCreateProcessWithDllsW(_In_opt_ LPCWSTR lpApplicationName, - _Inout_opt_ LPWSTR lpCommandLine, - _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, - _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, - _In_ BOOL bInheritHandles, - _In_ DWORD dwCreationFlags, - _In_opt_ LPVOID lpEnvironment, - _In_opt_ LPCWSTR lpCurrentDirectory, - _In_ LPSTARTUPINFOW lpStartupInfo, - _Out_ LPPROCESS_INFORMATION lpProcessInformation, - _In_ DWORD nDlls, - _In_reads_(nDlls) LPCSTR *rlpDlls, - _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); - -#ifdef UNICODE -#define DetourCreateProcessWithDlls DetourCreateProcessWithDllsW -#else -#define DetourCreateProcessWithDlls DetourCreateProcessWithDllsA -#endif // !UNICODE - -BOOL WINAPI DetourProcessViaHelperA(_In_ DWORD dwTargetPid, - _In_ LPCSTR lpDllName, - _In_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); - -BOOL WINAPI DetourProcessViaHelperW(_In_ DWORD dwTargetPid, - _In_ LPCSTR lpDllName, - _In_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); - -#ifdef UNICODE -#define DetourProcessViaHelper DetourProcessViaHelperW -#else -#define DetourProcessViaHelper DetourProcessViaHelperA -#endif // !UNICODE - -BOOL WINAPI DetourProcessViaHelperDllsA(_In_ DWORD dwTargetPid, - _In_ DWORD nDlls, - _In_reads_(nDlls) LPCSTR *rlpDlls, - _In_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); - -BOOL WINAPI DetourProcessViaHelperDllsW(_In_ DWORD dwTargetPid, - _In_ DWORD nDlls, - _In_reads_(nDlls) LPCSTR *rlpDlls, - _In_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); - -#ifdef UNICODE -#define DetourProcessViaHelperDlls DetourProcessViaHelperDllsW -#else -#define DetourProcessViaHelperDlls DetourProcessViaHelperDllsA -#endif // !UNICODE - -BOOL WINAPI DetourUpdateProcessWithDll(_In_ HANDLE hProcess, - _In_reads_(nDlls) LPCSTR *rlpDlls, - _In_ DWORD nDlls); - -BOOL WINAPI DetourUpdateProcessWithDllEx(_In_ HANDLE hProcess, - _In_ HMODULE hImage, - _In_ BOOL bIs32Bit, - _In_reads_(nDlls) LPCSTR *rlpDlls, - _In_ DWORD nDlls); - -BOOL WINAPI DetourCopyPayloadToProcess(_In_ HANDLE hProcess, - _In_ REFGUID rguid, - _In_reads_bytes_(cbData) LPCVOID pvData, - _In_ DWORD cbData); -_Success_(return != NULL) -PVOID WINAPI DetourCopyPayloadToProcessEx(_In_ HANDLE hProcess, - _In_ REFGUID rguid, - _In_reads_bytes_(cbData) LPCVOID pvData, - _In_ DWORD cbData); - -BOOL WINAPI DetourRestoreAfterWith(VOID); -BOOL WINAPI DetourRestoreAfterWithEx(_In_reads_bytes_(cbData) PVOID pvData, - _In_ DWORD cbData); -BOOL WINAPI DetourIsHelperProcess(VOID); -VOID CALLBACK DetourFinishHelperProcess(_In_ HWND, - _In_ HINSTANCE, - _In_ LPSTR, - _In_ INT); - -// -////////////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -} -#endif // __cplusplus - -/////////////////////////////////////////////////// Type-safe overloads for C++ -// -#if __cplusplus >= 201103L || _MSVC_LANG >= 201103L -#include - -template -struct DetoursIsFunctionPointer : std::false_type {}; - -template -struct DetoursIsFunctionPointer : std::is_function::type> {}; - -template< - typename T, - typename std::enable_if::value, int>::type = 0> -LONG DetourAttach(_Inout_ T *ppPointer, - _In_ T pDetour) noexcept -{ - return DetourAttach( - reinterpret_cast(ppPointer), - reinterpret_cast(pDetour)); -} - -template< - typename T, - typename std::enable_if::value, int>::type = 0> -LONG DetourAttachEx(_Inout_ T *ppPointer, - _In_ T pDetour, - _Out_opt_ PDETOUR_TRAMPOLINE *ppRealTrampoline, - _Out_opt_ T *ppRealTarget, - _Out_opt_ T *ppRealDetour) noexcept -{ - return DetourAttachEx( - reinterpret_cast(ppPointer), - reinterpret_cast(pDetour), - ppRealTrampoline, - reinterpret_cast(ppRealTarget), - reinterpret_cast(ppRealDetour)); -} - -template< - typename T, - typename std::enable_if::value, int>::type = 0> -LONG DetourDetach(_Inout_ T *ppPointer, - _In_ T pDetour) noexcept -{ - return DetourDetach( - reinterpret_cast(ppPointer), - reinterpret_cast(pDetour)); -} - -#endif // __cplusplus >= 201103L || _MSVC_LANG >= 201103L -// -////////////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////// Detours Internal Definitions. -// -#ifdef __cplusplus -#ifdef DETOURS_INTERNAL - -#define NOTHROW -// #define NOTHROW (nothrow) - -////////////////////////////////////////////////////////////////////////////// -// -#if (_MSC_VER < 1299) && !defined(__GNUC__) -#include -typedef IMAGEHLP_MODULE IMAGEHLP_MODULE64; -typedef PIMAGEHLP_MODULE PIMAGEHLP_MODULE64; -typedef IMAGEHLP_SYMBOL SYMBOL_INFO; -typedef PIMAGEHLP_SYMBOL PSYMBOL_INFO; - -static inline -LONG InterlockedCompareExchange(_Inout_ LONG *ptr, _In_ LONG nval, _In_ LONG oval) -{ - return (LONG)::InterlockedCompareExchange((PVOID*)ptr, (PVOID)nval, (PVOID)oval); -} -#else -#pragma warning(push) -#pragma warning(disable:4091) // empty typedef -#include -#pragma warning(pop) -#endif - -#ifdef IMAGEAPI // defined by DBGHELP.H -typedef LPAPI_VERSION (NTAPI *PF_ImagehlpApiVersionEx)(_In_ LPAPI_VERSION AppVersion); - -typedef BOOL (NTAPI *PF_SymInitialize)(_In_ HANDLE hProcess, - _In_opt_ LPCSTR UserSearchPath, - _In_ BOOL fInvadeProcess); -typedef DWORD (NTAPI *PF_SymSetOptions)(_In_ DWORD SymOptions); -typedef DWORD (NTAPI *PF_SymGetOptions)(VOID); -typedef DWORD64 (NTAPI *PF_SymLoadModule64)(_In_ HANDLE hProcess, - _In_opt_ HANDLE hFile, - _In_ LPSTR ImageName, - _In_opt_ LPSTR ModuleName, - _In_ DWORD64 BaseOfDll, - _In_opt_ DWORD SizeOfDll); -typedef BOOL (NTAPI *PF_SymGetModuleInfo64)(_In_ HANDLE hProcess, - _In_ DWORD64 qwAddr, - _Out_ PIMAGEHLP_MODULE64 ModuleInfo); -typedef BOOL (NTAPI *PF_SymFromName)(_In_ HANDLE hProcess, - _In_ LPSTR Name, - _Out_ PSYMBOL_INFO Symbol); - -typedef struct _DETOUR_SYM_INFO -{ - HANDLE hProcess; - HMODULE hDbgHelp; - PF_ImagehlpApiVersionEx pfImagehlpApiVersionEx; - PF_SymInitialize pfSymInitialize; - PF_SymSetOptions pfSymSetOptions; - PF_SymGetOptions pfSymGetOptions; - PF_SymLoadModule64 pfSymLoadModule64; - PF_SymGetModuleInfo64 pfSymGetModuleInfo64; - PF_SymFromName pfSymFromName; -} DETOUR_SYM_INFO, *PDETOUR_SYM_INFO; - -PDETOUR_SYM_INFO DetourLoadImageHlp(VOID); - -#endif // IMAGEAPI - -#if defined(_INC_STDIO) && !defined(_CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS) -#error detours.h must be included before stdio.h (or at least define _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS earlier) -#endif -#define _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS 1 - -#ifndef DETOUR_TRACE -#if DETOUR_DEBUG -#define DETOUR_TRACE(x) printf x -#define DETOUR_BREAK() __debugbreak() -#include -#include -#else -#define DETOUR_TRACE(x) -#define DETOUR_BREAK() -#endif -#endif - -#if 1 || defined(DETOURS_IA64) - -// -// IA64 instructions are 41 bits, 3 per bundle, plus 5 bit bundle template => 128 bits per bundle. -// - -#define DETOUR_IA64_INSTRUCTIONS_PER_BUNDLE (3) - -#define DETOUR_IA64_TEMPLATE_OFFSET (0) -#define DETOUR_IA64_TEMPLATE_SIZE (5) - -#define DETOUR_IA64_INSTRUCTION_SIZE (41) -#define DETOUR_IA64_INSTRUCTION0_OFFSET (DETOUR_IA64_TEMPLATE_SIZE) -#define DETOUR_IA64_INSTRUCTION1_OFFSET (DETOUR_IA64_TEMPLATE_SIZE + DETOUR_IA64_INSTRUCTION_SIZE) -#define DETOUR_IA64_INSTRUCTION2_OFFSET (DETOUR_IA64_TEMPLATE_SIZE + DETOUR_IA64_INSTRUCTION_SIZE + DETOUR_IA64_INSTRUCTION_SIZE) - -C_ASSERT(DETOUR_IA64_TEMPLATE_SIZE + DETOUR_IA64_INSTRUCTIONS_PER_BUNDLE * DETOUR_IA64_INSTRUCTION_SIZE == 128); - -__declspec(align(16)) struct DETOUR_IA64_BUNDLE -{ - public: - union - { - BYTE data[16]; - UINT64 wide[2]; - }; - - enum { - A_UNIT = 1u, - I_UNIT = 2u, - M_UNIT = 3u, - B_UNIT = 4u, - F_UNIT = 5u, - L_UNIT = 6u, - X_UNIT = 7u, - }; - struct DETOUR_IA64_METADATA - { - ULONG nTemplate : 8; // Instruction template. - ULONG nUnit0 : 4; // Unit for slot 0 - ULONG nUnit1 : 4; // Unit for slot 1 - ULONG nUnit2 : 4; // Unit for slot 2 - }; - - protected: - static const DETOUR_IA64_METADATA s_rceCopyTable[33]; - - UINT RelocateBundle(_Inout_ DETOUR_IA64_BUNDLE* pDst, _Inout_opt_ DETOUR_IA64_BUNDLE* pBundleExtra) const; - - bool RelocateInstruction(_Inout_ DETOUR_IA64_BUNDLE* pDst, - _In_ BYTE slot, - _Inout_opt_ DETOUR_IA64_BUNDLE* pBundleExtra) const; - - // 120 112 104 96 88 80 72 64 56 48 40 32 24 16 8 0 - // f. e. d. c. b. a. 9. 8. 7. 6. 5. 4. 3. 2. 1. 0. - - // 00 - // f.e. d.c. b.a. 9.8. 7.6. 5.4. 3.2. 1.0. - // 0000 0000 0000 0000 0000 0000 0000 001f : Template [4..0] - // 0000 0000 0000 0000 0000 03ff ffff ffe0 : Zero [ 41.. 5] - // 0000 0000 0000 0000 0000 3c00 0000 0000 : Zero [ 45.. 42] - // 0000 0000 0007 ffff ffff c000 0000 0000 : One [ 82.. 46] - // 0000 0000 0078 0000 0000 0000 0000 0000 : One [ 86.. 83] - // 0fff ffff ff80 0000 0000 0000 0000 0000 : Two [123.. 87] - // f000 0000 0000 0000 0000 0000 0000 0000 : Two [127..124] - BYTE GetTemplate() const; - // Get 4 bit opcodes. - BYTE GetInst0() const; - BYTE GetInst1() const; - BYTE GetInst2() const; - BYTE GetUnit(BYTE slot) const; - BYTE GetUnit0() const; - BYTE GetUnit1() const; - BYTE GetUnit2() const; - // Get 37 bit data. - UINT64 GetData0() const; - UINT64 GetData1() const; - UINT64 GetData2() const; - - // Get/set the full 41 bit instructions. - UINT64 GetInstruction(BYTE slot) const; - UINT64 GetInstruction0() const; - UINT64 GetInstruction1() const; - UINT64 GetInstruction2() const; - void SetInstruction(BYTE slot, UINT64 instruction); - void SetInstruction0(UINT64 instruction); - void SetInstruction1(UINT64 instruction); - void SetInstruction2(UINT64 instruction); - - // Get/set bitfields. - static UINT64 GetBits(UINT64 Value, UINT64 Offset, UINT64 Count); - static UINT64 SetBits(UINT64 Value, UINT64 Offset, UINT64 Count, UINT64 Field); - - // Get specific read-only fields. - static UINT64 GetOpcode(UINT64 instruction); // 4bit opcode - static UINT64 GetX(UINT64 instruction); // 1bit opcode extension - static UINT64 GetX3(UINT64 instruction); // 3bit opcode extension - static UINT64 GetX6(UINT64 instruction); // 6bit opcode extension - - // Get/set specific fields. - static UINT64 GetImm7a(UINT64 instruction); - static UINT64 SetImm7a(UINT64 instruction, UINT64 imm7a); - static UINT64 GetImm13c(UINT64 instruction); - static UINT64 SetImm13c(UINT64 instruction, UINT64 imm13c); - static UINT64 GetSignBit(UINT64 instruction); - static UINT64 SetSignBit(UINT64 instruction, UINT64 signBit); - static UINT64 GetImm20a(UINT64 instruction); - static UINT64 SetImm20a(UINT64 instruction, UINT64 imm20a); - static UINT64 GetImm20b(UINT64 instruction); - static UINT64 SetImm20b(UINT64 instruction, UINT64 imm20b); - - static UINT64 SignExtend(UINT64 Value, UINT64 Offset); - - BOOL IsMovlGp() const; - - VOID SetInst(BYTE Slot, BYTE nInst); - VOID SetInst0(BYTE nInst); - VOID SetInst1(BYTE nInst); - VOID SetInst2(BYTE nInst); - VOID SetData(BYTE Slot, UINT64 nData); - VOID SetData0(UINT64 nData); - VOID SetData1(UINT64 nData); - VOID SetData2(UINT64 nData); - BOOL SetNop(BYTE Slot); - BOOL SetNop0(); - BOOL SetNop1(); - BOOL SetNop2(); - - public: - BOOL IsBrl() const; - VOID SetBrl(); - VOID SetBrl(UINT64 target); - UINT64 GetBrlTarget() const; - VOID SetBrlTarget(UINT64 target); - VOID SetBrlImm(UINT64 imm); - UINT64 GetBrlImm() const; - - UINT64 GetMovlGp() const; - VOID SetMovlGp(UINT64 gp); - - VOID SetStop(); - - UINT Copy(_Out_ DETOUR_IA64_BUNDLE *pDst, _Inout_opt_ DETOUR_IA64_BUNDLE* pBundleExtra = NULL) const; -}; -#endif // DETOURS_IA64 - -#ifdef DETOURS_ARM - -#define DETOURS_PFUNC_TO_PBYTE(p) ((PBYTE)(((ULONG_PTR)(p)) & ~(ULONG_PTR)1)) -#define DETOURS_PBYTE_TO_PFUNC(p) ((PBYTE)(((ULONG_PTR)(p)) | (ULONG_PTR)1)) - -#endif // DETOURS_ARM - -////////////////////////////////////////////////////////////////////////////// - -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus - -#define DETOUR_OFFLINE_LIBRARY(x) \ -PVOID WINAPI DetourCopyInstruction##x(_In_opt_ PVOID pDst, \ - _Inout_opt_ PVOID *ppDstPool, \ - _In_ PVOID pSrc, \ - _Out_opt_ PVOID *ppTarget, \ - _Out_opt_ LONG *plExtra); \ - \ -BOOL WINAPI DetourSetCodeModule##x(_In_ HMODULE hModule, \ - _In_ BOOL fLimitReferencesToModule); \ - -DETOUR_OFFLINE_LIBRARY(X86) -DETOUR_OFFLINE_LIBRARY(X64) -DETOUR_OFFLINE_LIBRARY(ARM) -DETOUR_OFFLINE_LIBRARY(ARM64) -DETOUR_OFFLINE_LIBRARY(IA64) - -#undef DETOUR_OFFLINE_LIBRARY - -////////////////////////////////////////////////////////////////////////////// -// -// Helpers for manipulating page protection. -// - -_Success_(return != FALSE) -BOOL WINAPI DetourVirtualProtectSameExecuteEx(_In_ HANDLE hProcess, - _In_ PVOID pAddress, - _In_ SIZE_T nSize, - _In_ DWORD dwNewProtect, - _Out_ PDWORD pdwOldProtect); - -_Success_(return != FALSE) -BOOL WINAPI DetourVirtualProtectSameExecute(_In_ PVOID pAddress, - _In_ SIZE_T nSize, - _In_ DWORD dwNewProtect, - _Out_ PDWORD pdwOldProtect); - -// Detours must depend only on kernel32.lib, so we cannot use IsEqualGUID -BOOL WINAPI DetourAreSameGuid(_In_ REFGUID left, _In_ REFGUID right); -#ifdef __cplusplus -} -#endif // __cplusplus - -////////////////////////////////////////////////////////////////////////////// - -#define MM_ALLOCATION_GRANULARITY 0x10000 - -////////////////////////////////////////////////////////////////////////////// - -#endif // DETOURS_INTERNAL -#endif // __cplusplus - -#endif // _DETOURS_H_ -// -//////////////////////////////////////////////////////////////// End of File. +///////////////////////////////////////////////////////////////////////////// +// +// Core Detours Functionality (detours.h of detours.lib) +// +// Microsoft Research Detours Package, Version 4.0.1 +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// + +#pragma once +#ifndef _DETOURS_H_ +#define _DETOURS_H_ + +#define DETOURS_VERSION 0x4c0c1 // 0xMAJORcMINORcPATCH + +////////////////////////////////////////////////////////////////////////////// +// + +#ifdef DETOURS_INTERNAL + +#define _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS 1 +#define _ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE 1 + +#pragma warning(disable:4068) // unknown pragma (suppress) + +#if _MSC_VER >= 1900 +#pragma warning(push) +#pragma warning(disable:4091) // empty typedef +#endif + +// Suppress declspec(dllimport) for the sake of Detours +// users that provide kernel32 functionality themselves. +// This is ok in the mainstream case, it will just cost +// an extra instruction calling some functions, which +// LTCG optimizes away. +// +#define _KERNEL32_ 1 +#define _USER32_ 1 + +#include +#if (_MSC_VER < 1310) +#else +#pragma warning(push) +#if _MSC_VER > 1400 +#pragma warning(disable:6102 6103) // /analyze warnings +#endif +#include +#include +#pragma warning(pop) +#endif + +// Allow Detours to cleanly compile with the MingW toolchain. +// +#ifdef __GNUC__ +#define __try +#define __except(x) if (0) +#include +#endif + +// From winerror.h, as this error isn't found in some SDKs: +// +// MessageId: ERROR_DYNAMIC_CODE_BLOCKED +// +// MessageText: +// +// The operation was blocked as the process prohibits dynamic code generation. +// +#define ERROR_DYNAMIC_CODE_BLOCKED 1655L + +#endif // DETOURS_INTERNAL + +////////////////////////////////////////////////////////////////////////////// +// + +#undef DETOURS_X64 +#undef DETOURS_X86 +#undef DETOURS_IA64 +#undef DETOURS_ARM +#undef DETOURS_ARM64 +#undef DETOURS_BITS +#undef DETOURS_32BIT +#undef DETOURS_64BIT + +#if defined(_X86_) +#define DETOURS_X86 +#define DETOURS_OPTION_BITS 64 + +#elif defined(_AMD64_) +#define DETOURS_X64 +#define DETOURS_OPTION_BITS 32 + +#elif defined(_IA64_) +#define DETOURS_IA64 +#define DETOURS_OPTION_BITS 32 + +#elif defined(_ARM_) +#define DETOURS_ARM + +#elif defined(_ARM64_) +#define DETOURS_ARM64 + +#else +#error Unknown architecture (x86, amd64, ia64, arm, arm64) +#endif + +#ifdef _WIN64 +#undef DETOURS_32BIT +#define DETOURS_64BIT 1 +#define DETOURS_BITS 64 +// If all 64bit kernels can run one and only one 32bit architecture. +//#define DETOURS_OPTION_BITS 32 +#else +#define DETOURS_32BIT 1 +#undef DETOURS_64BIT +#define DETOURS_BITS 32 +// If all 64bit kernels can run one and only one 32bit architecture. +//#define DETOURS_OPTION_BITS 32 +#endif + +/////////////////////////////////////////////////////////////// Helper Macros. +// +#define DETOURS_STRINGIFY_(x) #x +#define DETOURS_STRINGIFY(x) DETOURS_STRINGIFY_(x) + +#define VER_DETOURS_BITS DETOURS_STRINGIFY(DETOURS_BITS) + +////////////////////////////////////////////////////////////////////////////// +// + +#if (_MSC_VER < 1299) && !defined(__MINGW32__) +typedef LONG LONG_PTR; +typedef ULONG ULONG_PTR; +#endif + +///////////////////////////////////////////////// SAL 2.0 Annotations w/o SAL. +// +// These definitions are include so that Detours will build even if the +// compiler doesn't have full SAL 2.0 support. +// +#ifndef DETOURS_DONT_REMOVE_SAL_20 + +#ifdef DETOURS_TEST_REMOVE_SAL_20 +#undef _Analysis_assume_ +#undef _Benign_race_begin_ +#undef _Benign_race_end_ +#undef _Field_range_ +#undef _Field_size_ +#undef _In_ +#undef _In_bytecount_ +#undef _In_count_ +#undef __in_ecount +#undef _In_opt_ +#undef _In_opt_bytecount_ +#undef _In_opt_count_ +#undef _In_opt_z_ +#undef _In_range_ +#undef _In_reads_ +#undef _In_reads_bytes_ +#undef _In_reads_opt_ +#undef _In_reads_opt_bytes_ +#undef _In_reads_or_z_ +#undef _In_z_ +#undef _Inout_ +#undef _Inout_opt_ +#undef _Inout_z_count_ +#undef _Out_ +#undef _Out_opt_ +#undef _Out_writes_ +#undef _Outptr_result_maybenull_ +#undef _Readable_bytes_ +#undef _Success_ +#undef _Writable_bytes_ +#undef _Pre_notnull_ +#endif + +#if defined(_Deref_out_opt_z_) && !defined(_Outptr_result_maybenull_) +#define _Outptr_result_maybenull_ _Deref_out_opt_z_ +#endif + +#if defined(_In_count_) && !defined(_In_reads_) +#define _In_reads_(x) _In_count_(x) +#endif + +#if defined(_In_opt_count_) && !defined(_In_reads_opt_) +#define _In_reads_opt_(x) _In_opt_count_(x) +#endif + +#if defined(_In_opt_bytecount_) && !defined(_In_reads_opt_bytes_) +#define _In_reads_opt_bytes_(x) _In_opt_bytecount_(x) +#endif + +#if defined(_In_bytecount_) && !defined(_In_reads_bytes_) +#define _In_reads_bytes_(x) _In_bytecount_(x) +#endif + +#ifndef _In_ +#define _In_ +#endif + +#ifndef _In_bytecount_ +#define _In_bytecount_(x) +#endif + +#ifndef _In_count_ +#define _In_count_(x) +#endif + +#ifndef __in_ecount +#define __in_ecount(x) +#endif + +#ifndef _In_opt_ +#define _In_opt_ +#endif + +#ifndef _In_opt_bytecount_ +#define _In_opt_bytecount_(x) +#endif + +#ifndef _In_opt_count_ +#define _In_opt_count_(x) +#endif + +#ifndef _In_opt_z_ +#define _In_opt_z_ +#endif + +#ifndef _In_range_ +#define _In_range_(x,y) +#endif + +#ifndef _In_reads_ +#define _In_reads_(x) +#endif + +#ifndef _In_reads_bytes_ +#define _In_reads_bytes_(x) +#endif + +#ifndef _In_reads_opt_ +#define _In_reads_opt_(x) +#endif + +#ifndef _In_reads_opt_bytes_ +#define _In_reads_opt_bytes_(x) +#endif + +#ifndef _In_reads_or_z_ +#define _In_reads_or_z_ +#endif + +#ifndef _In_z_ +#define _In_z_ +#endif + +#ifndef _Inout_ +#define _Inout_ +#endif + +#ifndef _Inout_opt_ +#define _Inout_opt_ +#endif + +#ifndef _Inout_z_count_ +#define _Inout_z_count_(x) +#endif + +#ifndef _Out_ +#define _Out_ +#endif + +#ifndef _Out_opt_ +#define _Out_opt_ +#endif + +#ifndef _Out_writes_ +#define _Out_writes_(x) +#endif + +#ifndef _Outptr_result_maybenull_ +#define _Outptr_result_maybenull_ +#endif + +#ifndef _Writable_bytes_ +#define _Writable_bytes_(x) +#endif + +#ifndef _Readable_bytes_ +#define _Readable_bytes_(x) +#endif + +#ifndef _Success_ +#define _Success_(x) +#endif + +#ifndef _Pre_notnull_ +#define _Pre_notnull_ +#endif + +#ifdef DETOURS_INTERNAL + +#pragma warning(disable:4615) // unknown warning type (suppress with older compilers) + +#ifndef _Benign_race_begin_ +#define _Benign_race_begin_ +#endif + +#ifndef _Benign_race_end_ +#define _Benign_race_end_ +#endif + +#ifndef _Field_size_ +#define _Field_size_(x) +#endif + +#ifndef _Field_range_ +#define _Field_range_(x,y) +#endif + +#ifndef _Analysis_assume_ +#define _Analysis_assume_(x) +#endif + +#endif // DETOURS_INTERNAL +#endif // DETOURS_DONT_REMOVE_SAL_20 + +////////////////////////////////////////////////////////////////////////////// +// +#ifndef GUID_DEFINED +#define GUID_DEFINED +typedef struct _GUID +{ + DWORD Data1; + WORD Data2; + WORD Data3; + BYTE Data4[ 8 ]; +} GUID; + +#ifdef INITGUID +#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + const GUID name \ + = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } +#else +#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + const GUID name +#endif // INITGUID +#endif // !GUID_DEFINED + +#if defined(__cplusplus) +#ifndef _REFGUID_DEFINED +#define _REFGUID_DEFINED +#define REFGUID const GUID & +#endif // !_REFGUID_DEFINED +#else // !__cplusplus +#ifndef _REFGUID_DEFINED +#define _REFGUID_DEFINED +#define REFGUID const GUID * const +#endif // !_REFGUID_DEFINED +#endif // !__cplusplus + +#ifndef ARRAYSIZE +#define ARRAYSIZE(x) (sizeof(x)/sizeof(x[0])) +#endif + +// +////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +/////////////////////////////////////////////////// Instruction Target Macros. +// +#define DETOUR_INSTRUCTION_TARGET_NONE ((PVOID)0) +#define DETOUR_INSTRUCTION_TARGET_DYNAMIC ((PVOID)(LONG_PTR)-1) +#define DETOUR_SECTION_HEADER_SIGNATURE 0x00727444 // "Dtr\0" + +extern const GUID DETOUR_EXE_RESTORE_GUID; +extern const GUID DETOUR_EXE_HELPER_GUID; + +#define DETOUR_TRAMPOLINE_SIGNATURE 0x21727444 // Dtr! +typedef struct _DETOUR_TRAMPOLINE DETOUR_TRAMPOLINE, *PDETOUR_TRAMPOLINE; + +/////////////////////////////////////////////////////////// Binary Structures. +// +#pragma pack(push, 8) +typedef struct _DETOUR_SECTION_HEADER +{ + DWORD cbHeaderSize; + DWORD nSignature; + DWORD nDataOffset; + DWORD cbDataSize; + + DWORD nOriginalImportVirtualAddress; + DWORD nOriginalImportSize; + DWORD nOriginalBoundImportVirtualAddress; + DWORD nOriginalBoundImportSize; + + DWORD nOriginalIatVirtualAddress; + DWORD nOriginalIatSize; + DWORD nOriginalSizeOfImage; + DWORD cbPrePE; + + DWORD nOriginalClrFlags; + DWORD reserved1; + DWORD reserved2; + DWORD reserved3; + + // Followed by cbPrePE bytes of data. +} DETOUR_SECTION_HEADER, *PDETOUR_SECTION_HEADER; + +typedef struct _DETOUR_SECTION_RECORD +{ + DWORD cbBytes; + DWORD nReserved; + GUID guid; +} DETOUR_SECTION_RECORD, *PDETOUR_SECTION_RECORD; + +typedef struct _DETOUR_CLR_HEADER +{ + // Header versioning + ULONG cb; + USHORT MajorRuntimeVersion; + USHORT MinorRuntimeVersion; + + // Symbol table and startup information + IMAGE_DATA_DIRECTORY MetaData; + ULONG Flags; + + // Followed by the rest of the IMAGE_COR20_HEADER +} DETOUR_CLR_HEADER, *PDETOUR_CLR_HEADER; + +typedef struct _DETOUR_EXE_RESTORE +{ + DWORD cb; + DWORD cbidh; + DWORD cbinh; + DWORD cbclr; + + PBYTE pidh; + PBYTE pinh; + PBYTE pclr; + + IMAGE_DOS_HEADER idh; + union { + IMAGE_NT_HEADERS inh; // all environments have this +#ifdef IMAGE_NT_OPTIONAL_HDR32_MAGIC // some environments do not have this + IMAGE_NT_HEADERS32 inh32; +#endif +#ifdef IMAGE_NT_OPTIONAL_HDR64_MAGIC // some environments do not have this + IMAGE_NT_HEADERS64 inh64; +#endif +#ifdef IMAGE_NT_OPTIONAL_HDR64_MAGIC // some environments do not have this + BYTE raw[sizeof(IMAGE_NT_HEADERS64) + + sizeof(IMAGE_SECTION_HEADER) * 32]; +#else + BYTE raw[0x108 + sizeof(IMAGE_SECTION_HEADER) * 32]; +#endif + }; + DETOUR_CLR_HEADER clr; + +} DETOUR_EXE_RESTORE, *PDETOUR_EXE_RESTORE; + +#ifdef IMAGE_NT_OPTIONAL_HDR64_MAGIC +C_ASSERT(sizeof(IMAGE_NT_HEADERS64) == 0x108); +#endif + +// The size can change, but assert for clarity due to the muddying #ifdefs. +#ifdef _WIN64 +C_ASSERT(sizeof(DETOUR_EXE_RESTORE) == 0x688); +#else +C_ASSERT(sizeof(DETOUR_EXE_RESTORE) == 0x678); +#endif + +typedef struct _DETOUR_EXE_HELPER +{ + DWORD cb; + DWORD pid; + DWORD nDlls; + CHAR rDlls[4]; +} DETOUR_EXE_HELPER, *PDETOUR_EXE_HELPER; + +#pragma pack(pop) + +#define DETOUR_SECTION_HEADER_DECLARE(cbSectionSize) \ +{ \ + sizeof(DETOUR_SECTION_HEADER),\ + DETOUR_SECTION_HEADER_SIGNATURE,\ + sizeof(DETOUR_SECTION_HEADER),\ + (cbSectionSize),\ + \ + 0,\ + 0,\ + 0,\ + 0,\ + \ + 0,\ + 0,\ + 0,\ + 0,\ +} + +///////////////////////////////////////////////////////////// Binary Typedefs. +// +typedef BOOL (CALLBACK *PF_DETOUR_BINARY_BYWAY_CALLBACK)( + _In_opt_ PVOID pContext, + _In_opt_ LPCSTR pszFile, + _Outptr_result_maybenull_ LPCSTR *ppszOutFile); + +typedef BOOL (CALLBACK *PF_DETOUR_BINARY_FILE_CALLBACK)( + _In_opt_ PVOID pContext, + _In_ LPCSTR pszOrigFile, + _In_ LPCSTR pszFile, + _Outptr_result_maybenull_ LPCSTR *ppszOutFile); + +typedef BOOL (CALLBACK *PF_DETOUR_BINARY_SYMBOL_CALLBACK)( + _In_opt_ PVOID pContext, + _In_ ULONG nOrigOrdinal, + _In_ ULONG nOrdinal, + _Out_ ULONG *pnOutOrdinal, + _In_opt_ LPCSTR pszOrigSymbol, + _In_opt_ LPCSTR pszSymbol, + _Outptr_result_maybenull_ LPCSTR *ppszOutSymbol); + +typedef BOOL (CALLBACK *PF_DETOUR_BINARY_COMMIT_CALLBACK)( + _In_opt_ PVOID pContext); + +typedef BOOL (CALLBACK *PF_DETOUR_ENUMERATE_EXPORT_CALLBACK)(_In_opt_ PVOID pContext, + _In_ ULONG nOrdinal, + _In_opt_ LPCSTR pszName, + _In_opt_ PVOID pCode); + +typedef BOOL (CALLBACK *PF_DETOUR_IMPORT_FILE_CALLBACK)(_In_opt_ PVOID pContext, + _In_opt_ HMODULE hModule, + _In_opt_ LPCSTR pszFile); + +typedef BOOL (CALLBACK *PF_DETOUR_IMPORT_FUNC_CALLBACK)(_In_opt_ PVOID pContext, + _In_ DWORD nOrdinal, + _In_opt_ LPCSTR pszFunc, + _In_opt_ PVOID pvFunc); + +// Same as PF_DETOUR_IMPORT_FUNC_CALLBACK but extra indirection on last parameter. +typedef BOOL (CALLBACK *PF_DETOUR_IMPORT_FUNC_CALLBACK_EX)(_In_opt_ PVOID pContext, + _In_ DWORD nOrdinal, + _In_opt_ LPCSTR pszFunc, + _In_opt_ PVOID* ppvFunc); + +typedef VOID * PDETOUR_BINARY; +typedef VOID * PDETOUR_LOADED_BINARY; + +//////////////////////////////////////////////////////////// Transaction APIs. +// +LONG WINAPI DetourTransactionBegin(VOID); +LONG WINAPI DetourTransactionAbort(VOID); +LONG WINAPI DetourTransactionCommit(VOID); +LONG WINAPI DetourTransactionCommitEx(_Out_opt_ PVOID **pppFailedPointer); + +LONG WINAPI DetourUpdateThread(_In_ HANDLE hThread); + +LONG WINAPI DetourAttach(_Inout_ PVOID *ppPointer, + _In_ PVOID pDetour); + +LONG WINAPI DetourAttachEx(_Inout_ PVOID *ppPointer, + _In_ PVOID pDetour, + _Out_opt_ PDETOUR_TRAMPOLINE *ppRealTrampoline, + _Out_opt_ PVOID *ppRealTarget, + _Out_opt_ PVOID *ppRealDetour); + +LONG WINAPI DetourDetach(_Inout_ PVOID *ppPointer, + _In_ PVOID pDetour); + +BOOL WINAPI DetourSetIgnoreTooSmall(_In_ BOOL fIgnore); +BOOL WINAPI DetourSetRetainRegions(_In_ BOOL fRetain); +PVOID WINAPI DetourSetSystemRegionLowerBound(_In_ PVOID pSystemRegionLowerBound); +PVOID WINAPI DetourSetSystemRegionUpperBound(_In_ PVOID pSystemRegionUpperBound); + +////////////////////////////////////////////////////////////// Code Functions. +// +PVOID WINAPI DetourFindFunction(_In_ LPCSTR pszModule, + _In_ LPCSTR pszFunction); +PVOID WINAPI DetourCodeFromPointer(_In_ PVOID pPointer, + _Out_opt_ PVOID *ppGlobals); +PVOID WINAPI DetourCopyInstruction(_In_opt_ PVOID pDst, + _Inout_opt_ PVOID *ppDstPool, + _In_ PVOID pSrc, + _Out_opt_ PVOID *ppTarget, + _Out_opt_ LONG *plExtra); +BOOL WINAPI DetourSetCodeModule(_In_ HMODULE hModule, + _In_ BOOL fLimitReferencesToModule); +PVOID WINAPI DetourAllocateRegionWithinJumpBounds(_In_ LPCVOID pbTarget, + _Out_ PDWORD pcbAllocatedSize); + +///////////////////////////////////////////////////// Loaded Binary Functions. +// +HMODULE WINAPI DetourGetContainingModule(_In_ PVOID pvAddr); +HMODULE WINAPI DetourEnumerateModules(_In_opt_ HMODULE hModuleLast); +PVOID WINAPI DetourGetEntryPoint(_In_opt_ HMODULE hModule); +ULONG WINAPI DetourGetModuleSize(_In_opt_ HMODULE hModule); +BOOL WINAPI DetourEnumerateExports(_In_ HMODULE hModule, + _In_opt_ PVOID pContext, + _In_ PF_DETOUR_ENUMERATE_EXPORT_CALLBACK pfExport); +BOOL WINAPI DetourEnumerateImports(_In_opt_ HMODULE hModule, + _In_opt_ PVOID pContext, + _In_opt_ PF_DETOUR_IMPORT_FILE_CALLBACK pfImportFile, + _In_opt_ PF_DETOUR_IMPORT_FUNC_CALLBACK pfImportFunc); + +BOOL WINAPI DetourEnumerateImportsEx(_In_opt_ HMODULE hModule, + _In_opt_ PVOID pContext, + _In_opt_ PF_DETOUR_IMPORT_FILE_CALLBACK pfImportFile, + _In_opt_ PF_DETOUR_IMPORT_FUNC_CALLBACK_EX pfImportFuncEx); + +_Writable_bytes_(*pcbData) +_Readable_bytes_(*pcbData) +_Success_(return != NULL) +PVOID WINAPI DetourFindPayload(_In_opt_ HMODULE hModule, + _In_ REFGUID rguid, + _Out_opt_ DWORD *pcbData); + +_Writable_bytes_(*pcbData) +_Readable_bytes_(*pcbData) +_Success_(return != NULL) +PVOID WINAPI DetourFindPayloadEx(_In_ REFGUID rguid, + _Out_opt_ DWORD *pcbData); + +DWORD WINAPI DetourGetSizeOfPayloads(_In_opt_ HMODULE hModule); + +///////////////////////////////////////////////// Persistent Binary Functions. +// + +PDETOUR_BINARY WINAPI DetourBinaryOpen(_In_ HANDLE hFile); + +_Writable_bytes_(*pcbData) +_Readable_bytes_(*pcbData) +_Success_(return != NULL) +PVOID WINAPI DetourBinaryEnumeratePayloads(_In_ PDETOUR_BINARY pBinary, + _Out_opt_ GUID *pGuid, + _Out_ DWORD *pcbData, + _Inout_ DWORD *pnIterator); + +_Writable_bytes_(*pcbData) +_Readable_bytes_(*pcbData) +_Success_(return != NULL) +PVOID WINAPI DetourBinaryFindPayload(_In_ PDETOUR_BINARY pBinary, + _In_ REFGUID rguid, + _Out_ DWORD *pcbData); + +PVOID WINAPI DetourBinarySetPayload(_In_ PDETOUR_BINARY pBinary, + _In_ REFGUID rguid, + _In_reads_opt_(cbData) PVOID pData, + _In_ DWORD cbData); +BOOL WINAPI DetourBinaryDeletePayload(_In_ PDETOUR_BINARY pBinary, _In_ REFGUID rguid); +BOOL WINAPI DetourBinaryPurgePayloads(_In_ PDETOUR_BINARY pBinary); +BOOL WINAPI DetourBinaryResetImports(_In_ PDETOUR_BINARY pBinary); +BOOL WINAPI DetourBinaryEditImports(_In_ PDETOUR_BINARY pBinary, + _In_opt_ PVOID pContext, + _In_opt_ PF_DETOUR_BINARY_BYWAY_CALLBACK pfByway, + _In_opt_ PF_DETOUR_BINARY_FILE_CALLBACK pfFile, + _In_opt_ PF_DETOUR_BINARY_SYMBOL_CALLBACK pfSymbol, + _In_opt_ PF_DETOUR_BINARY_COMMIT_CALLBACK pfCommit); +BOOL WINAPI DetourBinaryWrite(_In_ PDETOUR_BINARY pBinary, _In_ HANDLE hFile); +BOOL WINAPI DetourBinaryClose(_In_ PDETOUR_BINARY pBinary); + +/////////////////////////////////////////////////// Create Process & Load Dll. +// +_Success_(return != NULL) +PVOID WINAPI DetourFindRemotePayload(_In_ HANDLE hProcess, + _In_ REFGUID rguid, + _Out_opt_ DWORD *pcbData); + +typedef BOOL (WINAPI *PDETOUR_CREATE_PROCESS_ROUTINEA)( + _In_opt_ LPCSTR lpApplicationName, + _Inout_opt_ LPSTR lpCommandLine, + _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, + _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, + _In_ BOOL bInheritHandles, + _In_ DWORD dwCreationFlags, + _In_opt_ LPVOID lpEnvironment, + _In_opt_ LPCSTR lpCurrentDirectory, + _In_ LPSTARTUPINFOA lpStartupInfo, + _Out_ LPPROCESS_INFORMATION lpProcessInformation); + +typedef BOOL (WINAPI *PDETOUR_CREATE_PROCESS_ROUTINEW)( + _In_opt_ LPCWSTR lpApplicationName, + _Inout_opt_ LPWSTR lpCommandLine, + _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, + _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, + _In_ BOOL bInheritHandles, + _In_ DWORD dwCreationFlags, + _In_opt_ LPVOID lpEnvironment, + _In_opt_ LPCWSTR lpCurrentDirectory, + _In_ LPSTARTUPINFOW lpStartupInfo, + _Out_ LPPROCESS_INFORMATION lpProcessInformation); + +BOOL WINAPI DetourCreateProcessWithDllA(_In_opt_ LPCSTR lpApplicationName, + _Inout_opt_ LPSTR lpCommandLine, + _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, + _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, + _In_ BOOL bInheritHandles, + _In_ DWORD dwCreationFlags, + _In_opt_ LPVOID lpEnvironment, + _In_opt_ LPCSTR lpCurrentDirectory, + _In_ LPSTARTUPINFOA lpStartupInfo, + _Out_ LPPROCESS_INFORMATION lpProcessInformation, + _In_ LPCSTR lpDllName, + _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); + +BOOL WINAPI DetourCreateProcessWithDllW(_In_opt_ LPCWSTR lpApplicationName, + _Inout_opt_ LPWSTR lpCommandLine, + _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, + _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, + _In_ BOOL bInheritHandles, + _In_ DWORD dwCreationFlags, + _In_opt_ LPVOID lpEnvironment, + _In_opt_ LPCWSTR lpCurrentDirectory, + _In_ LPSTARTUPINFOW lpStartupInfo, + _Out_ LPPROCESS_INFORMATION lpProcessInformation, + _In_ LPCSTR lpDllName, + _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); + +#ifdef UNICODE +#define DetourCreateProcessWithDll DetourCreateProcessWithDllW +#define PDETOUR_CREATE_PROCESS_ROUTINE PDETOUR_CREATE_PROCESS_ROUTINEW +#else +#define DetourCreateProcessWithDll DetourCreateProcessWithDllA +#define PDETOUR_CREATE_PROCESS_ROUTINE PDETOUR_CREATE_PROCESS_ROUTINEA +#endif // !UNICODE + +BOOL WINAPI DetourCreateProcessWithDllExA(_In_opt_ LPCSTR lpApplicationName, + _Inout_opt_ LPSTR lpCommandLine, + _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, + _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, + _In_ BOOL bInheritHandles, + _In_ DWORD dwCreationFlags, + _In_opt_ LPVOID lpEnvironment, + _In_opt_ LPCSTR lpCurrentDirectory, + _In_ LPSTARTUPINFOA lpStartupInfo, + _Out_ LPPROCESS_INFORMATION lpProcessInformation, + _In_ LPCSTR lpDllName, + _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); + +BOOL WINAPI DetourCreateProcessWithDllExW(_In_opt_ LPCWSTR lpApplicationName, + _Inout_opt_ LPWSTR lpCommandLine, + _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, + _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, + _In_ BOOL bInheritHandles, + _In_ DWORD dwCreationFlags, + _In_opt_ LPVOID lpEnvironment, + _In_opt_ LPCWSTR lpCurrentDirectory, + _In_ LPSTARTUPINFOW lpStartupInfo, + _Out_ LPPROCESS_INFORMATION lpProcessInformation, + _In_ LPCSTR lpDllName, + _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); + +#ifdef UNICODE +#define DetourCreateProcessWithDllEx DetourCreateProcessWithDllExW +#else +#define DetourCreateProcessWithDllEx DetourCreateProcessWithDllExA +#endif // !UNICODE + +BOOL WINAPI DetourCreateProcessWithDllsA(_In_opt_ LPCSTR lpApplicationName, + _Inout_opt_ LPSTR lpCommandLine, + _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, + _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, + _In_ BOOL bInheritHandles, + _In_ DWORD dwCreationFlags, + _In_opt_ LPVOID lpEnvironment, + _In_opt_ LPCSTR lpCurrentDirectory, + _In_ LPSTARTUPINFOA lpStartupInfo, + _Out_ LPPROCESS_INFORMATION lpProcessInformation, + _In_ DWORD nDlls, + _In_reads_(nDlls) LPCSTR *rlpDlls, + _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); + +BOOL WINAPI DetourCreateProcessWithDllsW(_In_opt_ LPCWSTR lpApplicationName, + _Inout_opt_ LPWSTR lpCommandLine, + _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, + _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, + _In_ BOOL bInheritHandles, + _In_ DWORD dwCreationFlags, + _In_opt_ LPVOID lpEnvironment, + _In_opt_ LPCWSTR lpCurrentDirectory, + _In_ LPSTARTUPINFOW lpStartupInfo, + _Out_ LPPROCESS_INFORMATION lpProcessInformation, + _In_ DWORD nDlls, + _In_reads_(nDlls) LPCSTR *rlpDlls, + _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); + +#ifdef UNICODE +#define DetourCreateProcessWithDlls DetourCreateProcessWithDllsW +#else +#define DetourCreateProcessWithDlls DetourCreateProcessWithDllsA +#endif // !UNICODE + +BOOL WINAPI DetourProcessViaHelperA(_In_ DWORD dwTargetPid, + _In_ LPCSTR lpDllName, + _In_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); + +BOOL WINAPI DetourProcessViaHelperW(_In_ DWORD dwTargetPid, + _In_ LPCSTR lpDllName, + _In_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); + +#ifdef UNICODE +#define DetourProcessViaHelper DetourProcessViaHelperW +#else +#define DetourProcessViaHelper DetourProcessViaHelperA +#endif // !UNICODE + +BOOL WINAPI DetourProcessViaHelperDllsA(_In_ DWORD dwTargetPid, + _In_ DWORD nDlls, + _In_reads_(nDlls) LPCSTR *rlpDlls, + _In_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); + +BOOL WINAPI DetourProcessViaHelperDllsW(_In_ DWORD dwTargetPid, + _In_ DWORD nDlls, + _In_reads_(nDlls) LPCSTR *rlpDlls, + _In_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); + +#ifdef UNICODE +#define DetourProcessViaHelperDlls DetourProcessViaHelperDllsW +#else +#define DetourProcessViaHelperDlls DetourProcessViaHelperDllsA +#endif // !UNICODE + +BOOL WINAPI DetourUpdateProcessWithDll(_In_ HANDLE hProcess, + _In_reads_(nDlls) LPCSTR *rlpDlls, + _In_ DWORD nDlls); + +BOOL WINAPI DetourUpdateProcessWithDllEx(_In_ HANDLE hProcess, + _In_ HMODULE hImage, + _In_ BOOL bIs32Bit, + _In_reads_(nDlls) LPCSTR *rlpDlls, + _In_ DWORD nDlls); + +BOOL WINAPI DetourCopyPayloadToProcess(_In_ HANDLE hProcess, + _In_ REFGUID rguid, + _In_reads_bytes_(cbData) LPCVOID pvData, + _In_ DWORD cbData); +_Success_(return != NULL) +PVOID WINAPI DetourCopyPayloadToProcessEx(_In_ HANDLE hProcess, + _In_ REFGUID rguid, + _In_reads_bytes_(cbData) LPCVOID pvData, + _In_ DWORD cbData); + +BOOL WINAPI DetourRestoreAfterWith(VOID); +BOOL WINAPI DetourRestoreAfterWithEx(_In_reads_bytes_(cbData) PVOID pvData, + _In_ DWORD cbData); +BOOL WINAPI DetourIsHelperProcess(VOID); +VOID CALLBACK DetourFinishHelperProcess(_In_ HWND, + _In_ HINSTANCE, + _In_ LPSTR, + _In_ INT); + +// +////////////////////////////////////////////////////////////////////////////// +#ifdef __cplusplus +} +#endif // __cplusplus + +/////////////////////////////////////////////////// Type-safe overloads for C++ +// +#if __cplusplus >= 201103L || _MSVC_LANG >= 201103L +#include + +template +struct DetoursIsFunctionPointer : std::false_type {}; + +template +struct DetoursIsFunctionPointer : std::is_function::type> {}; + +template< + typename T, + typename std::enable_if::value, int>::type = 0> +LONG DetourAttach(_Inout_ T *ppPointer, + _In_ T pDetour) noexcept +{ + return DetourAttach( + reinterpret_cast(ppPointer), + reinterpret_cast(pDetour)); +} + +template< + typename T, + typename std::enable_if::value, int>::type = 0> +LONG DetourAttachEx(_Inout_ T *ppPointer, + _In_ T pDetour, + _Out_opt_ PDETOUR_TRAMPOLINE *ppRealTrampoline, + _Out_opt_ T *ppRealTarget, + _Out_opt_ T *ppRealDetour) noexcept +{ + return DetourAttachEx( + reinterpret_cast(ppPointer), + reinterpret_cast(pDetour), + ppRealTrampoline, + reinterpret_cast(ppRealTarget), + reinterpret_cast(ppRealDetour)); +} + +template< + typename T, + typename std::enable_if::value, int>::type = 0> +LONG DetourDetach(_Inout_ T *ppPointer, + _In_ T pDetour) noexcept +{ + return DetourDetach( + reinterpret_cast(ppPointer), + reinterpret_cast(pDetour)); +} + +#endif // __cplusplus >= 201103L || _MSVC_LANG >= 201103L +// +////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////// Detours Internal Definitions. +// +#ifdef __cplusplus +#ifdef DETOURS_INTERNAL + +#define NOTHROW +// #define NOTHROW (nothrow) + +////////////////////////////////////////////////////////////////////////////// +// +#if (_MSC_VER < 1299) && !defined(__GNUC__) +#include +typedef IMAGEHLP_MODULE IMAGEHLP_MODULE64; +typedef PIMAGEHLP_MODULE PIMAGEHLP_MODULE64; +typedef IMAGEHLP_SYMBOL SYMBOL_INFO; +typedef PIMAGEHLP_SYMBOL PSYMBOL_INFO; + +static inline +LONG InterlockedCompareExchange(_Inout_ LONG *ptr, _In_ LONG nval, _In_ LONG oval) +{ + return (LONG)::InterlockedCompareExchange((PVOID*)ptr, (PVOID)nval, (PVOID)oval); +} +#else +#pragma warning(push) +#pragma warning(disable:4091) // empty typedef +#include +#pragma warning(pop) +#endif + +#ifdef IMAGEAPI // defined by DBGHELP.H +typedef LPAPI_VERSION (NTAPI *PF_ImagehlpApiVersionEx)(_In_ LPAPI_VERSION AppVersion); + +typedef BOOL (NTAPI *PF_SymInitialize)(_In_ HANDLE hProcess, + _In_opt_ LPCSTR UserSearchPath, + _In_ BOOL fInvadeProcess); +typedef DWORD (NTAPI *PF_SymSetOptions)(_In_ DWORD SymOptions); +typedef DWORD (NTAPI *PF_SymGetOptions)(VOID); +typedef DWORD64 (NTAPI *PF_SymLoadModule64)(_In_ HANDLE hProcess, + _In_opt_ HANDLE hFile, + _In_ LPSTR ImageName, + _In_opt_ LPSTR ModuleName, + _In_ DWORD64 BaseOfDll, + _In_opt_ DWORD SizeOfDll); +typedef BOOL (NTAPI *PF_SymGetModuleInfo64)(_In_ HANDLE hProcess, + _In_ DWORD64 qwAddr, + _Out_ PIMAGEHLP_MODULE64 ModuleInfo); +typedef BOOL (NTAPI *PF_SymFromName)(_In_ HANDLE hProcess, + _In_ LPSTR Name, + _Out_ PSYMBOL_INFO Symbol); + +typedef struct _DETOUR_SYM_INFO +{ + HANDLE hProcess; + HMODULE hDbgHelp; + PF_ImagehlpApiVersionEx pfImagehlpApiVersionEx; + PF_SymInitialize pfSymInitialize; + PF_SymSetOptions pfSymSetOptions; + PF_SymGetOptions pfSymGetOptions; + PF_SymLoadModule64 pfSymLoadModule64; + PF_SymGetModuleInfo64 pfSymGetModuleInfo64; + PF_SymFromName pfSymFromName; +} DETOUR_SYM_INFO, *PDETOUR_SYM_INFO; + +PDETOUR_SYM_INFO DetourLoadImageHlp(VOID); + +#endif // IMAGEAPI + +#if defined(_INC_STDIO) && !defined(_CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS) +#error detours.h must be included before stdio.h (or at least define _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS earlier) +#endif +#define _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS 1 + +#ifndef DETOUR_TRACE +#if DETOUR_DEBUG +#define DETOUR_TRACE(x) printf x +#define DETOUR_BREAK() __debugbreak() +#include +#include +#else +#define DETOUR_TRACE(x) +#define DETOUR_BREAK() +#endif +#endif + +#if 1 || defined(DETOURS_IA64) + +// +// IA64 instructions are 41 bits, 3 per bundle, plus 5 bit bundle template => 128 bits per bundle. +// + +#define DETOUR_IA64_INSTRUCTIONS_PER_BUNDLE (3) + +#define DETOUR_IA64_TEMPLATE_OFFSET (0) +#define DETOUR_IA64_TEMPLATE_SIZE (5) + +#define DETOUR_IA64_INSTRUCTION_SIZE (41) +#define DETOUR_IA64_INSTRUCTION0_OFFSET (DETOUR_IA64_TEMPLATE_SIZE) +#define DETOUR_IA64_INSTRUCTION1_OFFSET (DETOUR_IA64_TEMPLATE_SIZE + DETOUR_IA64_INSTRUCTION_SIZE) +#define DETOUR_IA64_INSTRUCTION2_OFFSET (DETOUR_IA64_TEMPLATE_SIZE + DETOUR_IA64_INSTRUCTION_SIZE + DETOUR_IA64_INSTRUCTION_SIZE) + +C_ASSERT(DETOUR_IA64_TEMPLATE_SIZE + DETOUR_IA64_INSTRUCTIONS_PER_BUNDLE * DETOUR_IA64_INSTRUCTION_SIZE == 128); + +__declspec(align(16)) struct DETOUR_IA64_BUNDLE +{ + public: + union + { + BYTE data[16]; + UINT64 wide[2]; + }; + + enum { + A_UNIT = 1u, + I_UNIT = 2u, + M_UNIT = 3u, + B_UNIT = 4u, + F_UNIT = 5u, + L_UNIT = 6u, + X_UNIT = 7u, + }; + struct DETOUR_IA64_METADATA + { + ULONG nTemplate : 8; // Instruction template. + ULONG nUnit0 : 4; // Unit for slot 0 + ULONG nUnit1 : 4; // Unit for slot 1 + ULONG nUnit2 : 4; // Unit for slot 2 + }; + + protected: + static const DETOUR_IA64_METADATA s_rceCopyTable[33]; + + UINT RelocateBundle(_Inout_ DETOUR_IA64_BUNDLE* pDst, _Inout_opt_ DETOUR_IA64_BUNDLE* pBundleExtra) const; + + bool RelocateInstruction(_Inout_ DETOUR_IA64_BUNDLE* pDst, + _In_ BYTE slot, + _Inout_opt_ DETOUR_IA64_BUNDLE* pBundleExtra) const; + + // 120 112 104 96 88 80 72 64 56 48 40 32 24 16 8 0 + // f. e. d. c. b. a. 9. 8. 7. 6. 5. 4. 3. 2. 1. 0. + + // 00 + // f.e. d.c. b.a. 9.8. 7.6. 5.4. 3.2. 1.0. + // 0000 0000 0000 0000 0000 0000 0000 001f : Template [4..0] + // 0000 0000 0000 0000 0000 03ff ffff ffe0 : Zero [ 41.. 5] + // 0000 0000 0000 0000 0000 3c00 0000 0000 : Zero [ 45.. 42] + // 0000 0000 0007 ffff ffff c000 0000 0000 : One [ 82.. 46] + // 0000 0000 0078 0000 0000 0000 0000 0000 : One [ 86.. 83] + // 0fff ffff ff80 0000 0000 0000 0000 0000 : Two [123.. 87] + // f000 0000 0000 0000 0000 0000 0000 0000 : Two [127..124] + BYTE GetTemplate() const; + // Get 4 bit opcodes. + BYTE GetInst0() const; + BYTE GetInst1() const; + BYTE GetInst2() const; + BYTE GetUnit(BYTE slot) const; + BYTE GetUnit0() const; + BYTE GetUnit1() const; + BYTE GetUnit2() const; + // Get 37 bit data. + UINT64 GetData0() const; + UINT64 GetData1() const; + UINT64 GetData2() const; + + // Get/set the full 41 bit instructions. + UINT64 GetInstruction(BYTE slot) const; + UINT64 GetInstruction0() const; + UINT64 GetInstruction1() const; + UINT64 GetInstruction2() const; + void SetInstruction(BYTE slot, UINT64 instruction); + void SetInstruction0(UINT64 instruction); + void SetInstruction1(UINT64 instruction); + void SetInstruction2(UINT64 instruction); + + // Get/set bitfields. + static UINT64 GetBits(UINT64 Value, UINT64 Offset, UINT64 Count); + static UINT64 SetBits(UINT64 Value, UINT64 Offset, UINT64 Count, UINT64 Field); + + // Get specific read-only fields. + static UINT64 GetOpcode(UINT64 instruction); // 4bit opcode + static UINT64 GetX(UINT64 instruction); // 1bit opcode extension + static UINT64 GetX3(UINT64 instruction); // 3bit opcode extension + static UINT64 GetX6(UINT64 instruction); // 6bit opcode extension + + // Get/set specific fields. + static UINT64 GetImm7a(UINT64 instruction); + static UINT64 SetImm7a(UINT64 instruction, UINT64 imm7a); + static UINT64 GetImm13c(UINT64 instruction); + static UINT64 SetImm13c(UINT64 instruction, UINT64 imm13c); + static UINT64 GetSignBit(UINT64 instruction); + static UINT64 SetSignBit(UINT64 instruction, UINT64 signBit); + static UINT64 GetImm20a(UINT64 instruction); + static UINT64 SetImm20a(UINT64 instruction, UINT64 imm20a); + static UINT64 GetImm20b(UINT64 instruction); + static UINT64 SetImm20b(UINT64 instruction, UINT64 imm20b); + + static UINT64 SignExtend(UINT64 Value, UINT64 Offset); + + BOOL IsMovlGp() const; + + VOID SetInst(BYTE Slot, BYTE nInst); + VOID SetInst0(BYTE nInst); + VOID SetInst1(BYTE nInst); + VOID SetInst2(BYTE nInst); + VOID SetData(BYTE Slot, UINT64 nData); + VOID SetData0(UINT64 nData); + VOID SetData1(UINT64 nData); + VOID SetData2(UINT64 nData); + BOOL SetNop(BYTE Slot); + BOOL SetNop0(); + BOOL SetNop1(); + BOOL SetNop2(); + + public: + BOOL IsBrl() const; + VOID SetBrl(); + VOID SetBrl(UINT64 target); + UINT64 GetBrlTarget() const; + VOID SetBrlTarget(UINT64 target); + VOID SetBrlImm(UINT64 imm); + UINT64 GetBrlImm() const; + + UINT64 GetMovlGp() const; + VOID SetMovlGp(UINT64 gp); + + VOID SetStop(); + + UINT Copy(_Out_ DETOUR_IA64_BUNDLE *pDst, _Inout_opt_ DETOUR_IA64_BUNDLE* pBundleExtra = NULL) const; +}; +#endif // DETOURS_IA64 + +#ifdef DETOURS_ARM + +#define DETOURS_PFUNC_TO_PBYTE(p) ((PBYTE)(((ULONG_PTR)(p)) & ~(ULONG_PTR)1)) +#define DETOURS_PBYTE_TO_PFUNC(p) ((PBYTE)(((ULONG_PTR)(p)) | (ULONG_PTR)1)) + +#endif // DETOURS_ARM + +////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +#define DETOUR_OFFLINE_LIBRARY(x) \ +PVOID WINAPI DetourCopyInstruction##x(_In_opt_ PVOID pDst, \ + _Inout_opt_ PVOID *ppDstPool, \ + _In_ PVOID pSrc, \ + _Out_opt_ PVOID *ppTarget, \ + _Out_opt_ LONG *plExtra); \ + \ +BOOL WINAPI DetourSetCodeModule##x(_In_ HMODULE hModule, \ + _In_ BOOL fLimitReferencesToModule); \ + +DETOUR_OFFLINE_LIBRARY(X86) +DETOUR_OFFLINE_LIBRARY(X64) +DETOUR_OFFLINE_LIBRARY(ARM) +DETOUR_OFFLINE_LIBRARY(ARM64) +DETOUR_OFFLINE_LIBRARY(IA64) + +#undef DETOUR_OFFLINE_LIBRARY + +////////////////////////////////////////////////////////////////////////////// +// +// Helpers for manipulating page protection. +// + +_Success_(return != FALSE) +BOOL WINAPI DetourVirtualProtectSameExecuteEx(_In_ HANDLE hProcess, + _In_ PVOID pAddress, + _In_ SIZE_T nSize, + _In_ DWORD dwNewProtect, + _Out_ PDWORD pdwOldProtect); + +_Success_(return != FALSE) +BOOL WINAPI DetourVirtualProtectSameExecute(_In_ PVOID pAddress, + _In_ SIZE_T nSize, + _In_ DWORD dwNewProtect, + _Out_ PDWORD pdwOldProtect); + +// Detours must depend only on kernel32.lib, so we cannot use IsEqualGUID +BOOL WINAPI DetourAreSameGuid(_In_ REFGUID left, _In_ REFGUID right); +#ifdef __cplusplus +} +#endif // __cplusplus + +////////////////////////////////////////////////////////////////////////////// + +#define MM_ALLOCATION_GRANULARITY 0x10000 + +////////////////////////////////////////////////////////////////////////////// + +#endif // DETOURS_INTERNAL +#endif // __cplusplus + +#endif // _DETOURS_H_ +// +//////////////////////////////////////////////////////////////// End of File. diff --git a/src/detour/86/include/detver.h b/src/detour/86/include/detver.h index 3d4f544..7fb4eac 100644 --- a/src/detour/86/include/detver.h +++ b/src/detour/86/include/detver.h @@ -1,27 +1,27 @@ -////////////////////////////////////////////////////////////////////////////// -// -// Common version parameters. -// -// Microsoft Research Detours Package, Version 4.0.1 -// -// Copyright (c) Microsoft Corporation. All rights reserved. -// - -#define _USING_V110_SDK71_ 1 -#include "winver.h" -#if 0 -#include -#include -#else -#ifndef DETOURS_STRINGIFY -#define DETOURS_STRINGIFY_(x) #x -#define DETOURS_STRINGIFY(x) DETOURS_STRINGIFY_(x) -#endif - -#define VER_FILEFLAGSMASK 0x3fL -#define VER_FILEFLAGS 0x0L -#define VER_FILEOS 0x00040004L -#define VER_FILETYPE 0x00000002L -#define VER_FILESUBTYPE 0x00000000L -#endif -#define VER_DETOURS_BITS DETOURS_STRINGIFY(DETOURS_BITS) +////////////////////////////////////////////////////////////////////////////// +// +// Common version parameters. +// +// Microsoft Research Detours Package, Version 4.0.1 +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// + +#define _USING_V110_SDK71_ 1 +#include "winver.h" +#if 0 +#include +#include +#else +#ifndef DETOURS_STRINGIFY +#define DETOURS_STRINGIFY_(x) #x +#define DETOURS_STRINGIFY(x) DETOURS_STRINGIFY_(x) +#endif + +#define VER_FILEFLAGSMASK 0x3fL +#define VER_FILEFLAGS 0x0L +#define VER_FILEOS 0x00040004L +#define VER_FILETYPE 0x00000002L +#define VER_FILESUBTYPE 0x00000000L +#endif +#define VER_DETOURS_BITS DETOURS_STRINGIFY(DETOURS_BITS) diff --git a/src/detour/86/include/syelog.h b/src/detour/86/include/syelog.h index 7cfa9f3..e34e494 100644 --- a/src/detour/86/include/syelog.h +++ b/src/detour/86/include/syelog.h @@ -1,89 +1,89 @@ -////////////////////////////////////////////////////////////////////////////// -// -// Detours Test Program (syelog.h of syelog.lib) -// -// Microsoft Research Detours Package -// -// Copyright (c) Microsoft Corporation. All rights reserved. -// -#pragma once -#ifndef _SYELOGD_H_ -#define _SYELOGD_H_ -#include - -#pragma pack(push, 1) -#pragma warning(push) -#pragma warning(disable: 4200) - -////////////////////////////////////////////////////////////////////////////// -// -// -#define SYELOG_PIPE_NAMEA "\\\\.\\pipe\\syelog" -#define SYELOG_PIPE_NAMEW L"\\\\.\\pipe\\syelog" -#ifdef UNICODE -#define SYELOG_PIPE_NAME SYELOG_PIPE_NAMEW -#else -#define SYELOG_PIPE_NAME SYELOG_PIPE_NAMEA -#endif - -////////////////////////////////////////////////////////////////////////////// -// -#define SYELOG_MAXIMUM_MESSAGE 4086 // 4096 - sizeof(header stuff) - -typedef struct _SYELOG_MESSAGE -{ - USHORT nBytes; - BYTE nFacility; - BYTE nSeverity; - DWORD nProcessId; - FILETIME ftOccurance; - BOOL fTerminate; - CHAR szMessage[SYELOG_MAXIMUM_MESSAGE]; -} SYELOG_MESSAGE, *PSYELOG_MESSAGE; - - -// Facility Codes. -// -#define SYELOG_FACILITY_KERNEL 0x10 // OS Kernel -#define SYELOG_FACILITY_SECURITY 0x20 // OS Security -#define SYELOG_FACILITY_LOGGING 0x30 // OS Logging-internal -#define SYELOG_FACILITY_SERVICE 0x40 // User-mode system daemon -#define SYELOG_FACILITY_APPLICATION 0x50 // User-mode application -#define SYELOG_FACILITY_USER 0x60 // User self-generated. -#define SYELOG_FACILITY_LOCAL0 0x70 // Locally defined. -#define SYELOG_FACILITY_LOCAL1 0x71 // Locally defined. -#define SYELOG_FACILITY_LOCAL2 0x72 // Locally defined. -#define SYELOG_FACILITY_LOCAL3 0x73 // Locally defined. -#define SYELOG_FACILITY_LOCAL4 0x74 // Locally defined. -#define SYELOG_FACILITY_LOCAL5 0x75 // Locally defined. -#define SYELOG_FACILITY_LOCAL6 0x76 // Locally defined. -#define SYELOG_FACILITY_LOCAL7 0x77 // Locally defined. -#define SYELOG_FACILITY_LOCAL8 0x78 // Locally defined. -#define SYELOG_FACILITY_LOCAL9 0x79 // Locally defined. - -// Severity Codes. -// -#define SYELOG_SEVERITY_FATAL 0x00 // System is dead. -#define SYELOG_SEVERITY_ALERT 0x10 // Take action immediately. -#define SYELOG_SEVERITY_CRITICAL 0x20 // Critical condition. -#define SYELOG_SEVERITY_ERROR 0x30 // Error -#define SYELOG_SEVERITY_WARNING 0x40 // Warning -#define SYELOG_SEVERITY_NOTICE 0x50 // Significant condition. -#define SYELOG_SEVERITY_INFORMATION 0x60 // Informational -#define SYELOG_SEVERITY_AUDIT_FAIL 0x66 // Audit Failed -#define SYELOG_SEVERITY_AUDIT_PASS 0x67 // Audit Succeeeded -#define SYELOG_SEVERITY_DEBUG 0x70 // Debugging - -// Logging Functions. -// -VOID SyelogOpen(PCSTR pszIdentifier, BYTE nFacility); -VOID Syelog(BYTE nSeverity, PCSTR pszMsgf, ...); -VOID SyelogV(BYTE nSeverity, PCSTR pszMsgf, va_list args); -VOID SyelogClose(BOOL fTerminate); - -#pragma warning(pop) -#pragma pack(pop) - -#endif // _SYELOGD_H_ -// -///////////////////////////////////////////////////////////////// End of File. +////////////////////////////////////////////////////////////////////////////// +// +// Detours Test Program (syelog.h of syelog.lib) +// +// Microsoft Research Detours Package +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +#pragma once +#ifndef _SYELOGD_H_ +#define _SYELOGD_H_ +#include + +#pragma pack(push, 1) +#pragma warning(push) +#pragma warning(disable: 4200) + +////////////////////////////////////////////////////////////////////////////// +// +// +#define SYELOG_PIPE_NAMEA "\\\\.\\pipe\\syelog" +#define SYELOG_PIPE_NAMEW L"\\\\.\\pipe\\syelog" +#ifdef UNICODE +#define SYELOG_PIPE_NAME SYELOG_PIPE_NAMEW +#else +#define SYELOG_PIPE_NAME SYELOG_PIPE_NAMEA +#endif + +////////////////////////////////////////////////////////////////////////////// +// +#define SYELOG_MAXIMUM_MESSAGE 4086 // 4096 - sizeof(header stuff) + +typedef struct _SYELOG_MESSAGE +{ + USHORT nBytes; + BYTE nFacility; + BYTE nSeverity; + DWORD nProcessId; + FILETIME ftOccurance; + BOOL fTerminate; + CHAR szMessage[SYELOG_MAXIMUM_MESSAGE]; +} SYELOG_MESSAGE, *PSYELOG_MESSAGE; + + +// Facility Codes. +// +#define SYELOG_FACILITY_KERNEL 0x10 // OS Kernel +#define SYELOG_FACILITY_SECURITY 0x20 // OS Security +#define SYELOG_FACILITY_LOGGING 0x30 // OS Logging-internal +#define SYELOG_FACILITY_SERVICE 0x40 // User-mode system daemon +#define SYELOG_FACILITY_APPLICATION 0x50 // User-mode application +#define SYELOG_FACILITY_USER 0x60 // User self-generated. +#define SYELOG_FACILITY_LOCAL0 0x70 // Locally defined. +#define SYELOG_FACILITY_LOCAL1 0x71 // Locally defined. +#define SYELOG_FACILITY_LOCAL2 0x72 // Locally defined. +#define SYELOG_FACILITY_LOCAL3 0x73 // Locally defined. +#define SYELOG_FACILITY_LOCAL4 0x74 // Locally defined. +#define SYELOG_FACILITY_LOCAL5 0x75 // Locally defined. +#define SYELOG_FACILITY_LOCAL6 0x76 // Locally defined. +#define SYELOG_FACILITY_LOCAL7 0x77 // Locally defined. +#define SYELOG_FACILITY_LOCAL8 0x78 // Locally defined. +#define SYELOG_FACILITY_LOCAL9 0x79 // Locally defined. + +// Severity Codes. +// +#define SYELOG_SEVERITY_FATAL 0x00 // System is dead. +#define SYELOG_SEVERITY_ALERT 0x10 // Take action immediately. +#define SYELOG_SEVERITY_CRITICAL 0x20 // Critical condition. +#define SYELOG_SEVERITY_ERROR 0x30 // Error +#define SYELOG_SEVERITY_WARNING 0x40 // Warning +#define SYELOG_SEVERITY_NOTICE 0x50 // Significant condition. +#define SYELOG_SEVERITY_INFORMATION 0x60 // Informational +#define SYELOG_SEVERITY_AUDIT_FAIL 0x66 // Audit Failed +#define SYELOG_SEVERITY_AUDIT_PASS 0x67 // Audit Succeeeded +#define SYELOG_SEVERITY_DEBUG 0x70 // Debugging + +// Logging Functions. +// +VOID SyelogOpen(PCSTR pszIdentifier, BYTE nFacility); +VOID Syelog(BYTE nSeverity, PCSTR pszMsgf, ...); +VOID SyelogV(BYTE nSeverity, PCSTR pszMsgf, va_list args); +VOID SyelogClose(BOOL fTerminate); + +#pragma warning(pop) +#pragma pack(pop) + +#endif // _SYELOGD_H_ +// +///////////////////////////////////////////////////////////////// End of File. diff --git a/src/detour/README.md b/src/detour/README.md index 00e44c9..a1d3d57 100644 --- a/src/detour/README.md +++ b/src/detour/README.md @@ -1,3 +1,3 @@ -Please include microsoft detour binaries here. - -https://github.com/Microsoft/Detours/blob/master/samples/README.TXT +Please include microsoft detour binaries here. + +https://github.com/Microsoft/Detours/blob/master/samples/README.TXT diff --git a/src/dumper/dumper.cpp b/src/dumper/dumper.cpp index e005cf6..cea0d5c 100644 --- a/src/dumper/dumper.cpp +++ b/src/dumper/dumper.cpp @@ -1,576 +1,576 @@ -// this is to poc for dumping out registry files -// - -#include "pch.h" - -std::wstring string_to_wide(const std::string& s) -{ - std::wstring temp(s.length(), L' '); - std::copy(s.begin(), s.end(), temp.begin()); - return temp; -} - -std::string wide_to_string(const std::wstring& s) { - std::string temp(s.length(), ' '); - std::copy(s.begin(), s.end(), temp.begin()); - return temp; -} - -namespace RegHooks -{ - // 0x33FA4 - // - using StartProcWrapper_t = BOOL(__stdcall*)(LPWSTR); - uintptr_t StartProcWrapper_addr; - - BOOL __stdcall hk_StartProcWrapper(LPWSTR lpCommandLine) - { - std::cout << "[Start Proc Wrapper]" << std::endl; - return (reinterpret_cast(StartProcWrapper_addr))(lpCommandLine); - } - - // cmdlinestuff, 10/10 naming im tired - // 0x63F19 - // - using cmdlinestuff_t = int(__stdcall*)(DWORD*, char, char, int, int); - uintptr_t cmdlinestuff_addr; - - int __stdcall hk_cmdlinestuff(DWORD* a1, char a2, char a3, int a4, int a5) - { - std::cout << "[cmd stuff]" << std::endl; - - return (reinterpret_cast(cmdlinestuff_addr)) - (a1, a2, a3, a4, a5); - } - - - // 0x57C08 - // - using execute_shell_stuff_t = int(__stdcall*)(DWORD*, char, int, unsigned int, DWORD*); - uintptr_t execute_shell_stuff_addr; - - int __stdcall hk_execute_shell_stuff(DWORD* a1, char a2, int a3, unsigned int a4, DWORD* a5) - { - std::cout << "[shell execute stuff]" << std::endl; - - return (reinterpret_cast(execute_shell_stuff_addr)) - (a1, a2, a3, a4, a5); - } - - // 0x464DC - // - using alt_start_proc_t = char(__stdcall*)(LPCWSTR, LPCWSTR, LPCWSTR, LPVOID, LPWSTR, - HANDLE, LPCWSTR, LPSTARTUPINFOW, LPPROCESS_INFORMATION); - uintptr_t alt_start_proc_addr; - - char __stdcall hk_alt_start_proc(LPCWSTR lpUsername, LPCWSTR lpDomain, - LPCWSTR lpPassword, LPVOID Environment, LPWSTR lpCommandLine, - HANDLE TokenHandle, LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, - LPPROCESS_INFORMATION lpProcessInformation) - { - std::cout << "[Alt Start Proc]" << std::endl; - - return (reinterpret_cast(alt_start_proc_addr))(lpUsername, lpDomain, - lpPassword, Environment, lpCommandLine, - TokenHandle, lpCurrentDirectory, lpStartupInfo, - lpProcessInformation); - } - - // 0x45E0 - // - using control_table_t = int(__stdcall*)(DWORD*, int); - uintptr_t ControlTable_addr; - - std::vector cache = - { - 0x493730, 0x49451c, 0x4950c8, 0x4956f8, - 0x494db0, 0x495620, 0x493b20, 0x4954dc, - 0x4947a4, 0x495b30, 0x494d44 - }; - - int __stdcall hk_ControlTable(DWORD* a1, int a2) - { - auto ret = (reinterpret_cast(ControlTable_addr))(a1, a2); - - bool found = false; - - for (auto i : cache) - { - if (i == ret) - found = true; - } - - if (!found) - { - std::cout << "[Control Table] 0x" << std::hex << ret << std::endl; - cache.push_back(ret); - } - - return ret; - } - - // int __stdcall wmic_1(int a1, _DWORD *a2) - // 0x6CDA0 - // - using wmic_1_t = int(__stdcall*)(int, DWORD*); - uintptr_t wmic_1_addr; - - int __stdcall hk_wmic_1(int a1, DWORD* a2) - { - std::cout << "[wmic_1]" << std::endl; - return (reinterpret_cast(wmic_1_addr))(a1, a2); - } - - // int __thiscall hk_wmic_2(void* this, int a2, int a3) - // address: 0x75ACA - // - using hk_wmic_2_t = int(__thiscall*)(void*, int, int); - uintptr_t wmic_2_addr; - - int __fastcall hk_wmic_2(void* pthis, void* edx, int a2, int a3) - { - std::cout << "[wmic_2]" << std::endl; - return (reinterpret_cast(wmic_2_addr))(pthis, a2, a3); - } - - // wmic helper for setup - // address: 0x7A999 - // - using wmic_helper_t = int(__stdcall*)(int, int, wchar_t*, void*, wchar_t*, void*); - uintptr_t wmic_helper_addr; - - int __stdcall hk_wmic_helper(int a1, int a2, wchar_t* a3, void* Src, wchar_t* String, void* a6) - { - std::cout << "[wmic helper]" << std::endl; - return (reinterpret_cast(wmic_helper_addr))(a1, a2, a3, Src, String, a6); - } - - // helper to check when we enable defender - // address: 6AB70 - // calling convention: https://www.unknowncheats.me/forum/849605-post6.html - // pattern: 55 8B EC 83 E4 F8 83 EC 64 53 56 8B 75 08 8B 46 08 8B D9 57 8D 4C 24 50 89 44 24 20 C7 44 24 - // - using enable_def_helper_t = int(__thiscall*)(void*, int, DWORD*); - uintptr_t enable_def_help_addr; - - int __fastcall hk_enable_def(void* pThis, void* edx, int a2, DWORD* a3) - { - std::cout << "enabling defender" << std::endl; - return (reinterpret_cast(enable_def_help_addr))(pThis, a2, a3); - } - - // Disable defender handler - using disable_def_t = int(__thiscall*)(void*, int, DWORD*); - uintptr_t disable_def_addr; - - // disable defender routine: - // 0x6AEAF - // int __thiscall DisableDefender(void *this, int a1, _DWORD *a2) - - int __fastcall hk_disable_def(void* pThis, void* edx, int a1, DWORD* a2) - { - std::cout << "disabling defender" << std::endl; - return (reinterpret_cast(disable_def_addr))(pThis, a1, a2); - } - - // hook for RegEnumValueW - // ms docs: https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regenumvaluew - // - using regenumvaluew_t = LSTATUS(__stdcall*)(HKEY, DWORD, LPWSTR, LPDWORD, LPDWORD, LPDWORD, LPBYTE, LPDWORD); - uintptr_t regenumvaluew_addr; - - LSTATUS __stdcall hk_RegEnumValueW( - HKEY hKey, - DWORD dwIndex, - LPWSTR lpValueName, - LPDWORD lpcchValueName, - LPDWORD lpReserved, - LPDWORD lpType, - LPBYTE lpData, - LPDWORD lpcbData - ) - { - // there is a bug with a ridiculously large string we want to skip if we see it - // - auto converted = wide_to_string(lpValueName); - - if (converted.size() < MAX_PATH) - { - std::cout << "[RegEnumValueW]" << std::endl; - std::cout << "lpValueName: " << converted.c_str() << std::endl; - } - - return (reinterpret_cast(regenumvaluew_addr)) - (hKey, dwIndex, lpValueName, lpcchValueName, lpReserved, lpType, lpData, lpcbData); - } - - // hook for RegDeleteValueW - // ms docs: https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regdeletevaluew - // - using regdeletevaluew_t = LSTATUS(__stdcall*)(HKEY, LPCWSTR); - uintptr_t regdeletevaluew_addr; - - LSTATUS __stdcall hk_RegDeleteValueW( - HKEY hKey, - LPCWSTR lpValueName - ) - { - std::cout << "[RegDeleteValueW]" << std::endl; - std::cout << "lpValueName" << wide_to_string(lpValueName).c_str() << std::endl; - - return (reinterpret_cast(regdeletevaluew_addr))(hKey, lpValueName);; - } - - // hook for RegDeleteKeyW - // https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regdeletekeyw - // - using regdeletekeyw_t = LSTATUS(__stdcall*)(HKEY, LPCWSTR); - uintptr_t regdeletekeyw_addr; - - LSTATUS __stdcall hk_RegDeleteKeyW( - HKEY hKey, - LPCWSTR lpSubKey - ) - { - std::cout << "[RegDeleteValueW]" << std::endl; - std::cout << "lpSubkey" << wide_to_string(lpSubKey).c_str() << std::endl; - - return (reinterpret_cast(regdeletekeyw_addr))(hKey, lpSubKey); - } - - // RegSetValueExW - // ms docs: https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regsetvalueexw - // - using regsetkeyvalueexw_t = LSTATUS(__stdcall*)(HKEY, LPCWSTR, DWORD, DWORD, const BYTE*, DWORD); - uintptr_t regsetvalue_addr; - - LSTATUS __stdcall hk_RegSetValueExW( - HKEY hKey, - LPCWSTR lpValueName, - DWORD Reserved, - DWORD dwType, - const BYTE* lpData, - DWORD cbData - ) - { - std::cout << "[RegSetValueExW]" << std::endl; - std::cout << "lpValueName: " << wide_to_string(lpValueName).c_str() << std::endl; - std::cout << "Reserved: " << Reserved << std::endl; - std::cout << "dwType: " << dwType << std::endl; - std::cout << "cbData: " << cbData << std::endl; - - auto ret = (reinterpret_cast(regsetvalue_addr))(hKey, lpValueName, Reserved, dwType, lpData, cbData); - - std::cout << "Ret: " << ret << std::endl; - - return ret; - } - - // RegCreateKeyExW - // ms docs: https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regcreatekeyexw - // - using RegCreateKeyExW_t = LSTATUS(__stdcall*)(HKEY, LPCWSTR, DWORD, LPWSTR, DWORD, REGSAM, const LPSECURITY_ATTRIBUTES, - PHKEY, LPDWORD); - uintptr_t RegCreateKeyExW_addr; - - LSTATUS __stdcall hk_RegCreateKeyExW( - HKEY hKey, - LPCWSTR lpSubKey, - DWORD Reserved, - LPWSTR lpClass, - DWORD dwOptions, - REGSAM samDesired, - const LPSECURITY_ATTRIBUTES lpSecurityAttributes, - PHKEY phkResult, - LPDWORD lpdwDisposition - ) - { - - std::cout << "[RegCreateKeyExW]" << std::endl; - std::cout << "hKey: " << hKey << std::endl; - std::cout << "lpSubKey: " << wide_to_string(lpSubKey).c_str() << std::endl; - std::cout << "lpClass: " << wide_to_string(lpClass).c_str() << std::endl; - std::cout << "samDesired: " << samDesired << std::endl; - std::cout << "Reserved: " << Reserved << std::endl; - std::cout << "lpSecurityAttributes: " << lpSecurityAttributes << std::endl; - std::cout << "dwOptions: " << dwOptions << std::endl; - std::cout << "lpdwDisposition: " << lpdwDisposition << std::endl; - - auto ret = (reinterpret_cast(RegCreateKeyExW_addr)) - (hKey, lpSubKey, Reserved, lpClass, dwOptions, samDesired, lpSecurityAttributes, phkResult, lpdwDisposition); - - std::cout << "Ret: " << ret << std::endl; - - return ret; - } - - // RegConnectRegistryW - // ms docs: https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regconnectregistryw - // - using RegConnectRegistryW_t = LSTATUS(__stdcall*)(LPCWSTR, HKEY, PHKEY); - uintptr_t RegConnectRegistryW_addr; - - LSTATUS __stdcall hk_RegConnectRegistryW( - LPCWSTR lpMachineName, - HKEY hKey, - PHKEY phkResult - ) - { - std::cout << "[RegConnectRegistryW]" << std::endl; - std::cout << "MachineName: " << wide_to_string(lpMachineName).c_str() << std::endl; - return (reinterpret_cast(RegConnectRegistryW_addr))(lpMachineName, hKey, phkResult); - } - - // RegEnumKeyExW - // ms docs: https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regenumkeyexw - // - using RegEnumKeyExW_t = LSTATUS(__stdcall*)(HKEY, DWORD, LPWSTR, LPDWORD, LPDWORD, LPWSTR, LPDWORD, PFILETIME); - uintptr_t RegEnumKeyExW_addr; - - LSTATUS __stdcall hk_RegEnumKeyExW( - HKEY hKey, - DWORD dwIndex, - LPWSTR lpName, - LPDWORD lpcchName, - LPDWORD lpReserved, - LPWSTR lpClass, - LPDWORD lpcchClass, - PFILETIME lpftLastWriteTime - ) - { - std::cout << "[RegEnumKeyExW]" << std::endl; - std::cout << "lpName: " << wide_to_string(lpName).c_str() << std::endl; - - return (reinterpret_cast(RegEnumKeyExW_addr)) - (hKey, dwIndex, lpName, lpcchName, lpReserved, lpClass, lpcchClass, lpftLastWriteTime); - } - - // RegCloseKey - // ms docs: https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regclosekey - // seems redundant to hook - // - LSTATUS __stdcall hk_RegCloseKey( - HKEY hKey - ) - { - return EXIT_SUCCESS; - } - - // RegQueryValueExW - // ms docs: https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regqueryvalueexw - // - using RegQueryValueExW_t = LSTATUS(__stdcall*)(HKEY, LPCWSTR, LPDWORD, LPDWORD, LPBYTE, LPDWORD); - uintptr_t RegQueryValueExW_addr; - - LSTATUS __stdcall hk_RegQueryValueExW( - HKEY hKey, - LPCWSTR lpValueName, - LPDWORD lpReserved, - LPDWORD lpType, - LPBYTE lpData, - LPDWORD lpcbData - ) - { - std::cout << "[RegQueryValueExW]" << std::endl; - std::cout << "lpValueName: " << wide_to_string(lpValueName).c_str() << std::endl; - - return (reinterpret_cast(RegQueryValueExW_addr)) - (hKey, lpValueName, lpReserved, lpType, lpData, lpcbData); - } - - // RegOpenKeyExW - // ms docs: https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regopenkeyexw - // - using RegOpenKeyExW_t = LSTATUS(__stdcall*)(HKEY, LPCWSTR, DWORD, REGSAM, PHKEY); - uintptr_t RegOpenKeyExW_addr; - - LSTATUS __stdcall hk_RegOpenKeyExW( - HKEY hKey, - LPCWSTR lpSubKey, - DWORD ulOptions, - REGSAM samDesired, - PHKEY phkResult - ) - { - std::cout << "[RegOpenKeyExW]" << std::endl; - std::cout << "lpValueName: " << wide_to_string(lpSubKey).c_str() << std::endl; - std::cout << "ulOptions: " << ulOptions << std::endl; - std::cout << "samDesired: " << samDesired << std::endl; - - return (reinterpret_cast(RegOpenKeyExW_addr)) - (hKey, lpSubKey, ulOptions, samDesired, phkResult); - } - - // CreateProcessW - // ms docs: https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessw - // - using CreateProcessW_t = BOOL(__stdcall*)(LPCWSTR, LPWSTR, LPSECURITY_ATTRIBUTES, - LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, LPCWSTR, LPSTARTUPINFOW, LPPROCESS_INFORMATION); - uintptr_t CreateProcessW_addr; - - BOOL __stdcall hk_CreateProcessW( - LPCWSTR lpApplicationName, - LPWSTR lpCommandLine, - LPSECURITY_ATTRIBUTES lpProcessAttributes, - LPSECURITY_ATTRIBUTES lpThreadAttributes, - BOOL bInheritHandles, - DWORD dwCreationFlags, - LPVOID lpEnvironment, - LPCWSTR lpCurrentDirectory, - LPSTARTUPINFOW lpStartupInfo, - LPPROCESS_INFORMATION lpProcessInformation - ) - { - std::cout << "[CreateProcessW]" << std::endl; - std::cout << "lpCommandLine: " << wide_to_string(lpCommandLine).c_str() << std::endl; - - return (reinterpret_cast(CreateProcessW_addr))( - lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, - bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, - lpStartupInfo, lpProcessInformation); - } - -} - -namespace DetourHelper -{ - // places a hook - // - void perf_hook(PVOID* oFunction, PVOID pDetour) { - DetourTransactionBegin(); - DetourUpdateThread(GetCurrentThread()); - DetourAttach(oFunction, pDetour); - DetourTransactionCommit(); - } - - // removes a hook - // - void undo_hook(PVOID* oFunction, PVOID pDetour) { - DetourTransactionBegin(); - DetourUpdateThread(GetCurrentThread()); - DetourDetach(oFunction, pDetour); - DetourTransactionCommit(); - } -} - -uintptr_t get_func_addr(HMODULE mod, const char* name) -{ - auto ret = reinterpret_cast(GetProcAddress(mod, name)); - if (!ret) - std::cout << "failed to get " << name << std::endl; - std::cout << "obtained " << name << " from " << mod << std::endl; - return ret; -} - -void thread_main() -{ - // setup console - // - AllocConsole(); - UNREFERENCED_PARAMETER(freopen("CONIN$", "r", stdin)); - UNREFERENCED_PARAMETER(freopen("CONOUT$", "w", stdout)); - UNREFERENCED_PARAMETER(freopen("CONOUT$", "w", stderr)); - SetConsoleTitleA("Log"); - - // setup hooks - // - auto advapi32 = GetModuleHandleA("Advapi32.dll"); - auto kernel32 = GetModuleHandleA("Kernel32.dll"); - - if (!advapi32) - { - std::cout << "advapi32.dll not found" << std::endl; - return; - } - - if (!kernel32) - { - std::cout << "kernel32.dll not found" << std::endl; - return; - } - - RegHooks::regdeletekeyw_addr = get_func_addr(advapi32, "RegDeleteKeyW"); - RegHooks::regdeletevaluew_addr = get_func_addr(advapi32, "RegDeleteValueW"); - RegHooks::regenumvaluew_addr = get_func_addr(advapi32, "RegEnumValueW"); - RegHooks::regsetvalue_addr = get_func_addr(advapi32, "RegSetValueExW"); - RegHooks::RegCreateKeyExW_addr = get_func_addr(advapi32, "RegCreateKeyExW"); - RegHooks::RegConnectRegistryW_addr = get_func_addr(advapi32, "RegConnectRegistryW"); - RegHooks::RegEnumKeyExW_addr = get_func_addr(advapi32, "RegEnumKeyExW"); - RegHooks::RegQueryValueExW_addr = get_func_addr(advapi32, "RegQueryValueExW"); - RegHooks::RegOpenKeyExW_addr = get_func_addr(advapi32, "RegOpenKeyExW"); - RegHooks::CreateProcessW_addr = get_func_addr(kernel32, "CreateProcessW"); - - - std::cout << "imports resolved\npreparing to hook" << std::endl; - - // reg hooks - // -#if 0 - DetourHelper::perf_hook((PVOID*)&RegHooks::regdeletekeyw_addr, RegHooks::hk_RegDeleteKeyW); - DetourHelper::perf_hook((PVOID*)&RegHooks::regdeletevaluew_addr, RegHooks::hk_RegDeleteValueW); - DetourHelper::perf_hook((PVOID*)&RegHooks::regenumvaluew_addr, RegHooks::hk_RegEnumValueW); - DetourHelper::perf_hook((PVOID*)&RegHooks::regsetvalue_addr, RegHooks::hk_RegSetValueExW); - DetourHelper::perf_hook((PVOID*)&RegHooks::RegCreateKeyExW_addr, RegHooks::hk_RegCreateKeyExW); - DetourHelper::perf_hook((PVOID*)&RegHooks::RegConnectRegistryW_addr, RegHooks::hk_RegConnectRegistryW); - DetourHelper::perf_hook((PVOID*)&RegHooks::RegEnumKeyExW_addr, RegHooks::hk_RegEnumKeyExW); - DetourHelper::perf_hook((PVOID*)&RegHooks::RegQueryValueExW_addr, RegHooks::hk_RegQueryValueExW); - DetourHelper::perf_hook((PVOID*)&RegHooks::RegOpenKeyExW_addr, RegHooks::hk_RegOpenKeyExW); -#endif - - DetourHelper::perf_hook((PVOID*)&RegHooks::CreateProcessW_addr, RegHooks::hk_CreateProcessW); - - - // native hooks - // -#if 0 - RegHooks::enable_def_help_addr = (uintptr_t)GetModuleHandleA(0) + 0x6AB70; - DetourHelper::perf_hook((PVOID*)&RegHooks::enable_def_help_addr, RegHooks::hk_enable_def); - - RegHooks::disable_def_addr = (uintptr_t)GetModuleHandleA(0) + 0x6AEAF; - DetourHelper::perf_hook((PVOID*)&RegHooks::disable_def_addr, RegHooks::hk_disable_def); - - RegHooks::wmic_helper_addr = (uintptr_t)GetModuleHandleA(0) + 0x7A999; - DetourHelper::perf_hook((PVOID*)&RegHooks::wmic_helper_addr, RegHooks::hk_wmic_helper); - - RegHooks::wmic_1_addr = (uintptr_t)GetModuleHandleA(0) + 0x6CDA0; - DetourHelper::perf_hook((PVOID*)&RegHooks::wmic_1_addr, RegHooks::hk_wmic_1); - - RegHooks::wmic_2_addr = (uintptr_t)GetModuleHandleA(0) + 0x75ACA; - DetourHelper::perf_hook((PVOID*)&RegHooks::wmic_2_addr, RegHooks::hk_wmic_2); - - RegHooks::ControlTable_addr = (uintptr_t)GetModuleHandleA(0) + 0x45E0; - DetourHelper::perf_hook((PVOID*)&RegHooks::ControlTable_addr, RegHooks::hk_ControlTable); -#endif - - RegHooks::alt_start_proc_addr = (uintptr_t)GetModuleHandleA(0) + 0x464DC; - DetourHelper::perf_hook((PVOID*)&RegHooks::alt_start_proc_addr, RegHooks::hk_alt_start_proc); - - RegHooks::cmdlinestuff_addr = (uintptr_t)GetModuleHandleA(0) + 0x63F19; - DetourHelper::perf_hook((PVOID*)&RegHooks::cmdlinestuff_addr, RegHooks::hk_cmdlinestuff); - - RegHooks::StartProcWrapper_addr = (uintptr_t)GetModuleHandleA(0) + 0x33FA4; - DetourHelper::perf_hook((PVOID*)&RegHooks::StartProcWrapper_addr, RegHooks::hk_StartProcWrapper); - - - RegHooks::execute_shell_stuff_addr = (uintptr_t)GetModuleHandleA(0) + 0x33FA4; - DetourHelper::perf_hook((PVOID*)&RegHooks::execute_shell_stuff_addr, RegHooks::hk_execute_shell_stuff); - -} - -BOOL APIENTRY DllMain(HMODULE hModule, - DWORD ul_reason_for_call, - LPVOID lpReserved -) -{ - switch (ul_reason_for_call) - { - case DLL_PROCESS_ATTACH: - CreateThread(0, 0, reinterpret_cast(thread_main), 0, 0, 0); - case DLL_THREAD_ATTACH: - case DLL_THREAD_DETACH: - case DLL_PROCESS_DETACH: - break; - } - return TRUE; -} - +// this is to poc for dumping out registry files +// + +#include "pch.h" + +std::wstring string_to_wide(const std::string& s) +{ + std::wstring temp(s.length(), L' '); + std::copy(s.begin(), s.end(), temp.begin()); + return temp; +} + +std::string wide_to_string(const std::wstring& s) { + std::string temp(s.length(), ' '); + std::copy(s.begin(), s.end(), temp.begin()); + return temp; +} + +namespace RegHooks +{ + // 0x33FA4 + // + using StartProcWrapper_t = BOOL(__stdcall*)(LPWSTR); + uintptr_t StartProcWrapper_addr; + + BOOL __stdcall hk_StartProcWrapper(LPWSTR lpCommandLine) + { + std::cout << "[Start Proc Wrapper]" << std::endl; + return (reinterpret_cast(StartProcWrapper_addr))(lpCommandLine); + } + + // cmdlinestuff, 10/10 naming im tired + // 0x63F19 + // + using cmdlinestuff_t = int(__stdcall*)(DWORD*, char, char, int, int); + uintptr_t cmdlinestuff_addr; + + int __stdcall hk_cmdlinestuff(DWORD* a1, char a2, char a3, int a4, int a5) + { + std::cout << "[cmd stuff]" << std::endl; + + return (reinterpret_cast(cmdlinestuff_addr)) + (a1, a2, a3, a4, a5); + } + + + // 0x57C08 + // + using execute_shell_stuff_t = int(__stdcall*)(DWORD*, char, int, unsigned int, DWORD*); + uintptr_t execute_shell_stuff_addr; + + int __stdcall hk_execute_shell_stuff(DWORD* a1, char a2, int a3, unsigned int a4, DWORD* a5) + { + std::cout << "[shell execute stuff]" << std::endl; + + return (reinterpret_cast(execute_shell_stuff_addr)) + (a1, a2, a3, a4, a5); + } + + // 0x464DC + // + using alt_start_proc_t = char(__stdcall*)(LPCWSTR, LPCWSTR, LPCWSTR, LPVOID, LPWSTR, + HANDLE, LPCWSTR, LPSTARTUPINFOW, LPPROCESS_INFORMATION); + uintptr_t alt_start_proc_addr; + + char __stdcall hk_alt_start_proc(LPCWSTR lpUsername, LPCWSTR lpDomain, + LPCWSTR lpPassword, LPVOID Environment, LPWSTR lpCommandLine, + HANDLE TokenHandle, LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, + LPPROCESS_INFORMATION lpProcessInformation) + { + std::cout << "[Alt Start Proc]" << std::endl; + + return (reinterpret_cast(alt_start_proc_addr))(lpUsername, lpDomain, + lpPassword, Environment, lpCommandLine, + TokenHandle, lpCurrentDirectory, lpStartupInfo, + lpProcessInformation); + } + + // 0x45E0 + // + using control_table_t = int(__stdcall*)(DWORD*, int); + uintptr_t ControlTable_addr; + + std::vector cache = + { + 0x493730, 0x49451c, 0x4950c8, 0x4956f8, + 0x494db0, 0x495620, 0x493b20, 0x4954dc, + 0x4947a4, 0x495b30, 0x494d44 + }; + + int __stdcall hk_ControlTable(DWORD* a1, int a2) + { + auto ret = (reinterpret_cast(ControlTable_addr))(a1, a2); + + bool found = false; + + for (auto i : cache) + { + if (i == ret) + found = true; + } + + if (!found) + { + std::cout << "[Control Table] 0x" << std::hex << ret << std::endl; + cache.push_back(ret); + } + + return ret; + } + + // int __stdcall wmic_1(int a1, _DWORD *a2) + // 0x6CDA0 + // + using wmic_1_t = int(__stdcall*)(int, DWORD*); + uintptr_t wmic_1_addr; + + int __stdcall hk_wmic_1(int a1, DWORD* a2) + { + std::cout << "[wmic_1]" << std::endl; + return (reinterpret_cast(wmic_1_addr))(a1, a2); + } + + // int __thiscall hk_wmic_2(void* this, int a2, int a3) + // address: 0x75ACA + // + using hk_wmic_2_t = int(__thiscall*)(void*, int, int); + uintptr_t wmic_2_addr; + + int __fastcall hk_wmic_2(void* pthis, void* edx, int a2, int a3) + { + std::cout << "[wmic_2]" << std::endl; + return (reinterpret_cast(wmic_2_addr))(pthis, a2, a3); + } + + // wmic helper for setup + // address: 0x7A999 + // + using wmic_helper_t = int(__stdcall*)(int, int, wchar_t*, void*, wchar_t*, void*); + uintptr_t wmic_helper_addr; + + int __stdcall hk_wmic_helper(int a1, int a2, wchar_t* a3, void* Src, wchar_t* String, void* a6) + { + std::cout << "[wmic helper]" << std::endl; + return (reinterpret_cast(wmic_helper_addr))(a1, a2, a3, Src, String, a6); + } + + // helper to check when we enable defender + // address: 6AB70 + // calling convention: https://www.unknowncheats.me/forum/849605-post6.html + // pattern: 55 8B EC 83 E4 F8 83 EC 64 53 56 8B 75 08 8B 46 08 8B D9 57 8D 4C 24 50 89 44 24 20 C7 44 24 + // + using enable_def_helper_t = int(__thiscall*)(void*, int, DWORD*); + uintptr_t enable_def_help_addr; + + int __fastcall hk_enable_def(void* pThis, void* edx, int a2, DWORD* a3) + { + std::cout << "enabling defender" << std::endl; + return (reinterpret_cast(enable_def_help_addr))(pThis, a2, a3); + } + + // Disable defender handler + using disable_def_t = int(__thiscall*)(void*, int, DWORD*); + uintptr_t disable_def_addr; + + // disable defender routine: + // 0x6AEAF + // int __thiscall DisableDefender(void *this, int a1, _DWORD *a2) + + int __fastcall hk_disable_def(void* pThis, void* edx, int a1, DWORD* a2) + { + std::cout << "disabling defender" << std::endl; + return (reinterpret_cast(disable_def_addr))(pThis, a1, a2); + } + + // hook for RegEnumValueW + // ms docs: https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regenumvaluew + // + using regenumvaluew_t = LSTATUS(__stdcall*)(HKEY, DWORD, LPWSTR, LPDWORD, LPDWORD, LPDWORD, LPBYTE, LPDWORD); + uintptr_t regenumvaluew_addr; + + LSTATUS __stdcall hk_RegEnumValueW( + HKEY hKey, + DWORD dwIndex, + LPWSTR lpValueName, + LPDWORD lpcchValueName, + LPDWORD lpReserved, + LPDWORD lpType, + LPBYTE lpData, + LPDWORD lpcbData + ) + { + // there is a bug with a ridiculously large string we want to skip if we see it + // + auto converted = wide_to_string(lpValueName); + + if (converted.size() < MAX_PATH) + { + std::cout << "[RegEnumValueW]" << std::endl; + std::cout << "lpValueName: " << converted.c_str() << std::endl; + } + + return (reinterpret_cast(regenumvaluew_addr)) + (hKey, dwIndex, lpValueName, lpcchValueName, lpReserved, lpType, lpData, lpcbData); + } + + // hook for RegDeleteValueW + // ms docs: https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regdeletevaluew + // + using regdeletevaluew_t = LSTATUS(__stdcall*)(HKEY, LPCWSTR); + uintptr_t regdeletevaluew_addr; + + LSTATUS __stdcall hk_RegDeleteValueW( + HKEY hKey, + LPCWSTR lpValueName + ) + { + std::cout << "[RegDeleteValueW]" << std::endl; + std::cout << "lpValueName" << wide_to_string(lpValueName).c_str() << std::endl; + + return (reinterpret_cast(regdeletevaluew_addr))(hKey, lpValueName);; + } + + // hook for RegDeleteKeyW + // https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regdeletekeyw + // + using regdeletekeyw_t = LSTATUS(__stdcall*)(HKEY, LPCWSTR); + uintptr_t regdeletekeyw_addr; + + LSTATUS __stdcall hk_RegDeleteKeyW( + HKEY hKey, + LPCWSTR lpSubKey + ) + { + std::cout << "[RegDeleteValueW]" << std::endl; + std::cout << "lpSubkey" << wide_to_string(lpSubKey).c_str() << std::endl; + + return (reinterpret_cast(regdeletekeyw_addr))(hKey, lpSubKey); + } + + // RegSetValueExW + // ms docs: https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regsetvalueexw + // + using regsetkeyvalueexw_t = LSTATUS(__stdcall*)(HKEY, LPCWSTR, DWORD, DWORD, const BYTE*, DWORD); + uintptr_t regsetvalue_addr; + + LSTATUS __stdcall hk_RegSetValueExW( + HKEY hKey, + LPCWSTR lpValueName, + DWORD Reserved, + DWORD dwType, + const BYTE* lpData, + DWORD cbData + ) + { + std::cout << "[RegSetValueExW]" << std::endl; + std::cout << "lpValueName: " << wide_to_string(lpValueName).c_str() << std::endl; + std::cout << "Reserved: " << Reserved << std::endl; + std::cout << "dwType: " << dwType << std::endl; + std::cout << "cbData: " << cbData << std::endl; + + auto ret = (reinterpret_cast(regsetvalue_addr))(hKey, lpValueName, Reserved, dwType, lpData, cbData); + + std::cout << "Ret: " << ret << std::endl; + + return ret; + } + + // RegCreateKeyExW + // ms docs: https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regcreatekeyexw + // + using RegCreateKeyExW_t = LSTATUS(__stdcall*)(HKEY, LPCWSTR, DWORD, LPWSTR, DWORD, REGSAM, const LPSECURITY_ATTRIBUTES, + PHKEY, LPDWORD); + uintptr_t RegCreateKeyExW_addr; + + LSTATUS __stdcall hk_RegCreateKeyExW( + HKEY hKey, + LPCWSTR lpSubKey, + DWORD Reserved, + LPWSTR lpClass, + DWORD dwOptions, + REGSAM samDesired, + const LPSECURITY_ATTRIBUTES lpSecurityAttributes, + PHKEY phkResult, + LPDWORD lpdwDisposition + ) + { + + std::cout << "[RegCreateKeyExW]" << std::endl; + std::cout << "hKey: " << hKey << std::endl; + std::cout << "lpSubKey: " << wide_to_string(lpSubKey).c_str() << std::endl; + std::cout << "lpClass: " << wide_to_string(lpClass).c_str() << std::endl; + std::cout << "samDesired: " << samDesired << std::endl; + std::cout << "Reserved: " << Reserved << std::endl; + std::cout << "lpSecurityAttributes: " << lpSecurityAttributes << std::endl; + std::cout << "dwOptions: " << dwOptions << std::endl; + std::cout << "lpdwDisposition: " << lpdwDisposition << std::endl; + + auto ret = (reinterpret_cast(RegCreateKeyExW_addr)) + (hKey, lpSubKey, Reserved, lpClass, dwOptions, samDesired, lpSecurityAttributes, phkResult, lpdwDisposition); + + std::cout << "Ret: " << ret << std::endl; + + return ret; + } + + // RegConnectRegistryW + // ms docs: https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regconnectregistryw + // + using RegConnectRegistryW_t = LSTATUS(__stdcall*)(LPCWSTR, HKEY, PHKEY); + uintptr_t RegConnectRegistryW_addr; + + LSTATUS __stdcall hk_RegConnectRegistryW( + LPCWSTR lpMachineName, + HKEY hKey, + PHKEY phkResult + ) + { + std::cout << "[RegConnectRegistryW]" << std::endl; + std::cout << "MachineName: " << wide_to_string(lpMachineName).c_str() << std::endl; + return (reinterpret_cast(RegConnectRegistryW_addr))(lpMachineName, hKey, phkResult); + } + + // RegEnumKeyExW + // ms docs: https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regenumkeyexw + // + using RegEnumKeyExW_t = LSTATUS(__stdcall*)(HKEY, DWORD, LPWSTR, LPDWORD, LPDWORD, LPWSTR, LPDWORD, PFILETIME); + uintptr_t RegEnumKeyExW_addr; + + LSTATUS __stdcall hk_RegEnumKeyExW( + HKEY hKey, + DWORD dwIndex, + LPWSTR lpName, + LPDWORD lpcchName, + LPDWORD lpReserved, + LPWSTR lpClass, + LPDWORD lpcchClass, + PFILETIME lpftLastWriteTime + ) + { + std::cout << "[RegEnumKeyExW]" << std::endl; + std::cout << "lpName: " << wide_to_string(lpName).c_str() << std::endl; + + return (reinterpret_cast(RegEnumKeyExW_addr)) + (hKey, dwIndex, lpName, lpcchName, lpReserved, lpClass, lpcchClass, lpftLastWriteTime); + } + + // RegCloseKey + // ms docs: https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regclosekey + // seems redundant to hook + // + LSTATUS __stdcall hk_RegCloseKey( + HKEY hKey + ) + { + return EXIT_SUCCESS; + } + + // RegQueryValueExW + // ms docs: https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regqueryvalueexw + // + using RegQueryValueExW_t = LSTATUS(__stdcall*)(HKEY, LPCWSTR, LPDWORD, LPDWORD, LPBYTE, LPDWORD); + uintptr_t RegQueryValueExW_addr; + + LSTATUS __stdcall hk_RegQueryValueExW( + HKEY hKey, + LPCWSTR lpValueName, + LPDWORD lpReserved, + LPDWORD lpType, + LPBYTE lpData, + LPDWORD lpcbData + ) + { + std::cout << "[RegQueryValueExW]" << std::endl; + std::cout << "lpValueName: " << wide_to_string(lpValueName).c_str() << std::endl; + + return (reinterpret_cast(RegQueryValueExW_addr)) + (hKey, lpValueName, lpReserved, lpType, lpData, lpcbData); + } + + // RegOpenKeyExW + // ms docs: https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regopenkeyexw + // + using RegOpenKeyExW_t = LSTATUS(__stdcall*)(HKEY, LPCWSTR, DWORD, REGSAM, PHKEY); + uintptr_t RegOpenKeyExW_addr; + + LSTATUS __stdcall hk_RegOpenKeyExW( + HKEY hKey, + LPCWSTR lpSubKey, + DWORD ulOptions, + REGSAM samDesired, + PHKEY phkResult + ) + { + std::cout << "[RegOpenKeyExW]" << std::endl; + std::cout << "lpValueName: " << wide_to_string(lpSubKey).c_str() << std::endl; + std::cout << "ulOptions: " << ulOptions << std::endl; + std::cout << "samDesired: " << samDesired << std::endl; + + return (reinterpret_cast(RegOpenKeyExW_addr)) + (hKey, lpSubKey, ulOptions, samDesired, phkResult); + } + + // CreateProcessW + // ms docs: https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessw + // + using CreateProcessW_t = BOOL(__stdcall*)(LPCWSTR, LPWSTR, LPSECURITY_ATTRIBUTES, + LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, LPCWSTR, LPSTARTUPINFOW, LPPROCESS_INFORMATION); + uintptr_t CreateProcessW_addr; + + BOOL __stdcall hk_CreateProcessW( + LPCWSTR lpApplicationName, + LPWSTR lpCommandLine, + LPSECURITY_ATTRIBUTES lpProcessAttributes, + LPSECURITY_ATTRIBUTES lpThreadAttributes, + BOOL bInheritHandles, + DWORD dwCreationFlags, + LPVOID lpEnvironment, + LPCWSTR lpCurrentDirectory, + LPSTARTUPINFOW lpStartupInfo, + LPPROCESS_INFORMATION lpProcessInformation + ) + { + std::cout << "[CreateProcessW]" << std::endl; + std::cout << "lpCommandLine: " << wide_to_string(lpCommandLine).c_str() << std::endl; + + return (reinterpret_cast(CreateProcessW_addr))( + lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, + bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, + lpStartupInfo, lpProcessInformation); + } + +} + +namespace DetourHelper +{ + // places a hook + // + void perf_hook(PVOID* oFunction, PVOID pDetour) { + DetourTransactionBegin(); + DetourUpdateThread(GetCurrentThread()); + DetourAttach(oFunction, pDetour); + DetourTransactionCommit(); + } + + // removes a hook + // + void undo_hook(PVOID* oFunction, PVOID pDetour) { + DetourTransactionBegin(); + DetourUpdateThread(GetCurrentThread()); + DetourDetach(oFunction, pDetour); + DetourTransactionCommit(); + } +} + +uintptr_t get_func_addr(HMODULE mod, const char* name) +{ + auto ret = reinterpret_cast(GetProcAddress(mod, name)); + if (!ret) + std::cout << "failed to get " << name << std::endl; + std::cout << "obtained " << name << " from " << mod << std::endl; + return ret; +} + +void thread_main() +{ + // setup console + // + AllocConsole(); + UNREFERENCED_PARAMETER(freopen("CONIN$", "r", stdin)); + UNREFERENCED_PARAMETER(freopen("CONOUT$", "w", stdout)); + UNREFERENCED_PARAMETER(freopen("CONOUT$", "w", stderr)); + SetConsoleTitleA("Log"); + + // setup hooks + // + auto advapi32 = GetModuleHandleA("Advapi32.dll"); + auto kernel32 = GetModuleHandleA("Kernel32.dll"); + + if (!advapi32) + { + std::cout << "advapi32.dll not found" << std::endl; + return; + } + + if (!kernel32) + { + std::cout << "kernel32.dll not found" << std::endl; + return; + } + + RegHooks::regdeletekeyw_addr = get_func_addr(advapi32, "RegDeleteKeyW"); + RegHooks::regdeletevaluew_addr = get_func_addr(advapi32, "RegDeleteValueW"); + RegHooks::regenumvaluew_addr = get_func_addr(advapi32, "RegEnumValueW"); + RegHooks::regsetvalue_addr = get_func_addr(advapi32, "RegSetValueExW"); + RegHooks::RegCreateKeyExW_addr = get_func_addr(advapi32, "RegCreateKeyExW"); + RegHooks::RegConnectRegistryW_addr = get_func_addr(advapi32, "RegConnectRegistryW"); + RegHooks::RegEnumKeyExW_addr = get_func_addr(advapi32, "RegEnumKeyExW"); + RegHooks::RegQueryValueExW_addr = get_func_addr(advapi32, "RegQueryValueExW"); + RegHooks::RegOpenKeyExW_addr = get_func_addr(advapi32, "RegOpenKeyExW"); + RegHooks::CreateProcessW_addr = get_func_addr(kernel32, "CreateProcessW"); + + + std::cout << "imports resolved\npreparing to hook" << std::endl; + + // reg hooks + // +#if 0 + DetourHelper::perf_hook((PVOID*)&RegHooks::regdeletekeyw_addr, RegHooks::hk_RegDeleteKeyW); + DetourHelper::perf_hook((PVOID*)&RegHooks::regdeletevaluew_addr, RegHooks::hk_RegDeleteValueW); + DetourHelper::perf_hook((PVOID*)&RegHooks::regenumvaluew_addr, RegHooks::hk_RegEnumValueW); + DetourHelper::perf_hook((PVOID*)&RegHooks::regsetvalue_addr, RegHooks::hk_RegSetValueExW); + DetourHelper::perf_hook((PVOID*)&RegHooks::RegCreateKeyExW_addr, RegHooks::hk_RegCreateKeyExW); + DetourHelper::perf_hook((PVOID*)&RegHooks::RegConnectRegistryW_addr, RegHooks::hk_RegConnectRegistryW); + DetourHelper::perf_hook((PVOID*)&RegHooks::RegEnumKeyExW_addr, RegHooks::hk_RegEnumKeyExW); + DetourHelper::perf_hook((PVOID*)&RegHooks::RegQueryValueExW_addr, RegHooks::hk_RegQueryValueExW); + DetourHelper::perf_hook((PVOID*)&RegHooks::RegOpenKeyExW_addr, RegHooks::hk_RegOpenKeyExW); +#endif + + DetourHelper::perf_hook((PVOID*)&RegHooks::CreateProcessW_addr, RegHooks::hk_CreateProcessW); + + + // native hooks + // +#if 0 + RegHooks::enable_def_help_addr = (uintptr_t)GetModuleHandleA(0) + 0x6AB70; + DetourHelper::perf_hook((PVOID*)&RegHooks::enable_def_help_addr, RegHooks::hk_enable_def); + + RegHooks::disable_def_addr = (uintptr_t)GetModuleHandleA(0) + 0x6AEAF; + DetourHelper::perf_hook((PVOID*)&RegHooks::disable_def_addr, RegHooks::hk_disable_def); + + RegHooks::wmic_helper_addr = (uintptr_t)GetModuleHandleA(0) + 0x7A999; + DetourHelper::perf_hook((PVOID*)&RegHooks::wmic_helper_addr, RegHooks::hk_wmic_helper); + + RegHooks::wmic_1_addr = (uintptr_t)GetModuleHandleA(0) + 0x6CDA0; + DetourHelper::perf_hook((PVOID*)&RegHooks::wmic_1_addr, RegHooks::hk_wmic_1); + + RegHooks::wmic_2_addr = (uintptr_t)GetModuleHandleA(0) + 0x75ACA; + DetourHelper::perf_hook((PVOID*)&RegHooks::wmic_2_addr, RegHooks::hk_wmic_2); + + RegHooks::ControlTable_addr = (uintptr_t)GetModuleHandleA(0) + 0x45E0; + DetourHelper::perf_hook((PVOID*)&RegHooks::ControlTable_addr, RegHooks::hk_ControlTable); +#endif + + RegHooks::alt_start_proc_addr = (uintptr_t)GetModuleHandleA(0) + 0x464DC; + DetourHelper::perf_hook((PVOID*)&RegHooks::alt_start_proc_addr, RegHooks::hk_alt_start_proc); + + RegHooks::cmdlinestuff_addr = (uintptr_t)GetModuleHandleA(0) + 0x63F19; + DetourHelper::perf_hook((PVOID*)&RegHooks::cmdlinestuff_addr, RegHooks::hk_cmdlinestuff); + + RegHooks::StartProcWrapper_addr = (uintptr_t)GetModuleHandleA(0) + 0x33FA4; + DetourHelper::perf_hook((PVOID*)&RegHooks::StartProcWrapper_addr, RegHooks::hk_StartProcWrapper); + + + RegHooks::execute_shell_stuff_addr = (uintptr_t)GetModuleHandleA(0) + 0x33FA4; + DetourHelper::perf_hook((PVOID*)&RegHooks::execute_shell_stuff_addr, RegHooks::hk_execute_shell_stuff); + +} + +BOOL APIENTRY DllMain(HMODULE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved +) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + CreateThread(0, 0, reinterpret_cast(thread_main), 0, 0, 0); + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} + diff --git a/src/dumper/dumper.vcxproj b/src/dumper/dumper.vcxproj index 559943c..82b99ab 100644 --- a/src/dumper/dumper.vcxproj +++ b/src/dumper/dumper.vcxproj @@ -1,174 +1,174 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 16.0 - {089CA7D6-3277-4998-86AF-F6413290A442} - Win32Proj - dumper - 10.0 - - - - DynamicLibrary - true - v142 - Unicode - - - DynamicLibrary - false - v142 - true - Unicode - - - DynamicLibrary - true - v142 - Unicode - - - DynamicLibrary - false - v142 - true - Unicode - - - - - - - - - - - - - - - - - - - - - true - - - true - - - false - $(SolutionDir)\detour\86\include;$(IncludePath) - $(SolutionDir)\detour\86\lib;$(LibraryPath) - - - false - $(Platform)\$(Configuration) - $(SolutionDir)\detour\64\include;$(IncludePath) - $(SolutionDir)\detour\64\lib;$(LibraryPath) - - - - Use - Level3 - true - _DEBUG;DUMPER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - true - pch.h - - - Windows - true - false - - - - - Use - Level3 - true - WIN32;_DEBUG;DUMPER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - true - pch.h - - - Windows - true - false - - - - - Use - Level3 - true - true - true - WIN32;NDEBUG;DUMPER_EXPORTS;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - pch.h - - - Windows - true - true - true - false - - - - - Use - Level3 - true - true - true - NDEBUG;DUMPER_EXPORTS;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - pch.h - - - Windows - true - true - true - false - - - - - - - - - - Create - Create - Create - Create - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + {089CA7D6-3277-4998-86AF-F6413290A442} + Win32Proj + dumper + 10.0 + + + + DynamicLibrary + true + v142 + Unicode + + + DynamicLibrary + false + v142 + true + Unicode + + + DynamicLibrary + true + v142 + Unicode + + + DynamicLibrary + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + $(SolutionDir)\detour\86\include;$(IncludePath) + $(SolutionDir)\detour\86\lib;$(LibraryPath) + + + false + $(Platform)\$(Configuration) + $(SolutionDir)\detour\64\include;$(IncludePath) + $(SolutionDir)\detour\64\lib;$(LibraryPath) + + + + Use + Level3 + true + _DEBUG;DUMPER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + pch.h + + + Windows + true + false + + + + + Use + Level3 + true + WIN32;_DEBUG;DUMPER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + pch.h + + + Windows + true + false + + + + + Use + Level3 + true + true + true + WIN32;NDEBUG;DUMPER_EXPORTS;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + pch.h + + + Windows + true + true + true + false + + + + + Use + Level3 + true + true + true + NDEBUG;DUMPER_EXPORTS;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + pch.h + + + Windows + true + true + true + false + + + + + + + + + + Create + Create + Create + Create + + + + + \ No newline at end of file diff --git a/src/dumper/dumper.vcxproj.filters b/src/dumper/dumper.vcxproj.filters index ebc8560..780a6ea 100644 --- a/src/dumper/dumper.vcxproj.filters +++ b/src/dumper/dumper.vcxproj.filters @@ -1,33 +1,33 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;c++;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + \ No newline at end of file diff --git a/src/dumper/framework.h b/src/dumper/framework.h index 54b83e9..a9744f8 100644 --- a/src/dumper/framework.h +++ b/src/dumper/framework.h @@ -1,5 +1,5 @@ -#pragma once - -#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers -// Windows Header Files -#include +#pragma once + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +// Windows Header Files +#include diff --git a/src/dumper/pch.cpp b/src/dumper/pch.cpp index 64b7eef..91c22df 100644 --- a/src/dumper/pch.cpp +++ b/src/dumper/pch.cpp @@ -1,5 +1,5 @@ -// pch.cpp: source file corresponding to the pre-compiled header - -#include "pch.h" - -// When you are using pre-compiled headers, this source file is necessary for compilation to succeed. +// pch.cpp: source file corresponding to the pre-compiled header + +#include "pch.h" + +// When you are using pre-compiled headers, this source file is necessary for compilation to succeed. diff --git a/src/dumper/pch.h b/src/dumper/pch.h index b46f527..078d852 100644 --- a/src/dumper/pch.h +++ b/src/dumper/pch.h @@ -1,18 +1,18 @@ -// pch.h: This is a precompiled header file. -// Files listed below are compiled only once, improving build performance for future builds. -// This also affects IntelliSense performance, including code completion and many code browsing features. -// However, files listed here are ALL re-compiled if any one of them is updated between builds. -// Do not add files here that you will be updating frequently as this negates the performance advantage. - -#ifndef PCH_H -#define PCH_H - -#include -#include -#include -#include -#include -#include -#pragma comment(lib, "detours.lib") - -#endif //PCH_H +// pch.h: This is a precompiled header file. +// Files listed below are compiled only once, improving build performance for future builds. +// This also affects IntelliSense performance, including code completion and many code browsing features. +// However, files listed here are ALL re-compiled if any one of them is updated between builds. +// Do not add files here that you will be updating frequently as this negates the performance advantage. + +#ifndef PCH_H +#define PCH_H + +#include +#include +#include +#include +#include +#include +#pragma comment(lib, "detours.lib") + +#endif //PCH_H