diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..d23ba71 --- /dev/null +++ b/.clang-format @@ -0,0 +1,6 @@ +--- +BasedOnStyle: Microsoft +IncludeBlocks: Preserve +SortIncludes: Never + +... diff --git a/.gitignore b/.gitignore index 7a043ac..82b4247 100644 --- a/.gitignore +++ b/.gitignore @@ -1,61 +1,401 @@ -# Prerequisites -*.d +## 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/main/VisualStudio.gitignore -# Compiled Object files -*.slo -*.lo -*.o -*.obj +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates -# Precompiled Headers -*.gch -*.pch +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs -# Compiled Dynamic libraries -*.so -*.dylib -*.dll - -# Fortran module files -*.mod -*.smod - -# Compiled Static libraries -*.lai -*.la -*.a -*.lib - -# Executables -*.exe -*.out -*.app -*.sys -*.pdb -*.manifest -*.cache +# Mono auto generated files +mono_crash.* -#Ignore files build by Visual Studio -*.user -*.aps -*.pch -*.vspscc +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[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/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio *_i.c *_p.c -*.ncb -*.suo -*.bak -*.cache +*_h.h *.ilk -*.log -[Bb]in -[Dd]ebug*/ +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +# but not Directory.Build.rsp, as it configures directory-level build defaults +!Directory.Build.rsp *.sbr -obj/ -[Rr]elease*/ -_ReSharper*/ -*.db -*.db-shm -*.db-wal +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.tlog +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb *.opendb -*.ipch +*.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 + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# 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 6 auto-generated project file (contains which files were open etc.) +*.vbp + +# Visual Studio 6 workspace and project file (working project files containing files to include in project) +*.dsw +*.dsp + +# Visual Studio 6 technical files +*.ncb +*.aps + +# 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/ + +# Visual Studio History (VSHistory) files +.vshistory/ + +# 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/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd + +# VS Code files for those working on multiple tools +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +*.code-workspace + +# Local History for Visual Studio Code +.history/ + +# Windows Installer files from build outputs +*.cab +*.msi +*.msix +*.msm +*.msp + +# JetBrains Rider +*.sln.iml +/MasterHide/tmf diff --git a/.gitmodules b/.gitmodules index f0e9d6a..3b8f184 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "KasperskyHook"] path = KasperskyHook url = https://github.com/iPower/KasperskyHook/ +[submodule "MasterHide/thirdparty/phnt"] + path = MasterHide/thirdparty/phnt + url = https://github.com/winsiderss/phnt.git diff --git a/.vs/MasterHide/v17/DocumentLayout.backup.json b/.vs/MasterHide/v17/DocumentLayout.backup.json new file mode 100644 index 0000000..11cf487 --- /dev/null +++ b/.vs/MasterHide/v17/DocumentLayout.backup.json @@ -0,0 +1,537 @@ +{ + "Version": 1, + "WorkspaceRootPath": "A:\\work\\MasterHide\\", + "Documents": [ + { + "AbsoluteMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|A:\\work\\MasterHide\\MasterHide\\dyn.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|solutionrelative:MasterHide\\dyn.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|A:\\work\\MasterHide\\MasterHide\\dyn.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|solutionrelative:MasterHide\\dyn.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|A:\\work\\MasterHide\\MasterHide\\tools.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|solutionrelative:MasterHide\\tools.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|A:\\work\\MasterHide\\MasterHide\\includes.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|solutionrelative:MasterHide\\includes.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|A:\\work\\MasterHide\\MasterHide\\tools.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|solutionrelative:MasterHide\\tools.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|A:\\work\\MasterHide\\MasterHide\\drivermain.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|solutionrelative:MasterHide\\drivermain.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{018FEB18-6063-4D5F-AC3A-7CDFBD224016}|MasterHideLoader\\MasterHideLoader.vcxproj|A:\\work\\MasterHide\\MasterHideLoader\\loader.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{018FEB18-6063-4D5F-AC3A-7CDFBD224016}|MasterHideLoader\\MasterHideLoader.vcxproj|solutionrelative:MasterHideLoader\\loader.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{018FEB18-6063-4D5F-AC3A-7CDFBD224016}|MasterHideLoader\\MasterHideLoader.vcxproj|A:\\work\\MasterHide\\MasterHideLoader\\main.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{018FEB18-6063-4D5F-AC3A-7CDFBD224016}|MasterHideLoader\\MasterHideLoader.vcxproj|solutionrelative:MasterHideLoader\\main.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{018FEB18-6063-4D5F-AC3A-7CDFBD224016}|MasterHideLoader\\MasterHideLoader.vcxproj|A:\\work\\MasterHide\\MasterHideLoader\\service.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{018FEB18-6063-4D5F-AC3A-7CDFBD224016}|MasterHideLoader\\MasterHideLoader.vcxproj|solutionrelative:MasterHideLoader\\service.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{018FEB18-6063-4D5F-AC3A-7CDFBD224016}|MasterHideLoader\\MasterHideLoader.vcxproj|A:\\work\\MasterHide\\MasterHideLoader\\loader.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{018FEB18-6063-4D5F-AC3A-7CDFBD224016}|MasterHideLoader\\MasterHideLoader.vcxproj|solutionrelative:MasterHideLoader\\loader.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{018FEB18-6063-4D5F-AC3A-7CDFBD224016}|MasterHideLoader\\MasterHideLoader.vcxproj|A:\\work\\MasterHide\\MasterHideLoader\\includes.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{018FEB18-6063-4D5F-AC3A-7CDFBD224016}|MasterHideLoader\\MasterHideLoader.vcxproj|solutionrelative:MasterHideLoader\\includes.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{018FEB18-6063-4D5F-AC3A-7CDFBD224016}|MasterHideLoader\\MasterHideLoader.vcxproj|A:\\work\\MasterHide\\MasterHideLoader\\klhk.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{018FEB18-6063-4D5F-AC3A-7CDFBD224016}|MasterHideLoader\\MasterHideLoader.vcxproj|solutionrelative:MasterHideLoader\\klhk.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{018FEB18-6063-4D5F-AC3A-7CDFBD224016}|MasterHideLoader\\MasterHideLoader.vcxproj|A:\\work\\MasterHide\\MasterHideLoader\\klhk.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{018FEB18-6063-4D5F-AC3A-7CDFBD224016}|MasterHideLoader\\MasterHideLoader.vcxproj|solutionrelative:MasterHideLoader\\klhk.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{018FEB18-6063-4D5F-AC3A-7CDFBD224016}|MasterHideLoader\\MasterHideLoader.vcxproj|A:\\work\\MasterHide\\MasterHideLoader\\service.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{018FEB18-6063-4D5F-AC3A-7CDFBD224016}|MasterHideLoader\\MasterHideLoader.vcxproj|solutionrelative:MasterHideLoader\\service.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|A:\\work\\MasterHide\\MasterHide\\rules.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|solutionrelative:MasterHide\\rules.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|A:\\work\\MasterHide\\MasterHide\\rules.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|solutionrelative:MasterHide\\rules.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|A:\\work\\MasterHide\\MasterHide\\hooks.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|solutionrelative:MasterHide\\hooks.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|A:\\work\\MasterHide\\MasterHide\\hooks.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|solutionrelative:MasterHide\\hooks.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|A:\\work\\MasterHide\\MasterHide\\infinityhook.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|solutionrelative:MasterHide\\infinityhook.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|A:\\work\\MasterHide\\MasterHide\\wpp_trace.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|solutionrelative:MasterHide\\wpp_trace.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|A:\\work\\MasterHide\\MasterHide\\infinityhook.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|solutionrelative:MasterHide\\infinityhook.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|A:\\work\\MasterHide\\MasterHide\\syscalls.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|solutionrelative:MasterHide\\syscalls.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|A:\\work\\MasterHide\\MasterHide\\object.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|solutionrelative:MasterHide\\object.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|A:\\work\\MasterHide\\MasterHide\\fnv1a.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|solutionrelative:MasterHide\\fnv1a.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|A:\\work\\MasterHide\\MasterHide\\callbacks.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|solutionrelative:MasterHide\\callbacks.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|A:\\work\\MasterHide\\MasterHide\\syscalls.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|solutionrelative:MasterHide\\syscalls.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|A:\\work\\MasterHide\\MasterHide\\callbacks.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|solutionrelative:MasterHide\\callbacks.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|A:\\work\\MasterHide\\KasperskyHook\\KasperskyHookDrv\\pe.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|solutionrelative:KasperskyHook\\KasperskyHookDrv\\pe.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|A:\\work\\MasterHide\\KasperskyHook\\KasperskyHookDrv\\utils.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|solutionrelative:KasperskyHook\\KasperskyHookDrv\\utils.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|A:\\work\\MasterHide\\KasperskyHook\\KasperskyHookDrv\\utils.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|solutionrelative:KasperskyHook\\KasperskyHookDrv\\utils.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|A:\\work\\MasterHide\\KasperskyHook\\KasperskyHookDrv\\kaspersky.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|solutionrelative:KasperskyHook\\KasperskyHookDrv\\kaspersky.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|A:\\work\\MasterHide\\MasterHide\\thirdparty\\phnt\\ntwow64.h||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:MasterHide\\thirdparty\\phnt\\ntwow64.h||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + } + ], + "DocumentGroupContainers": [ + { + "Orientation": 0, + "VerticalTabListWidth": 256, + "DocumentGroups": [ + { + "DockedWidth": 200, + "SelectedChildIndex": 0, + "Children": [ + { + "$type": "Document", + "DocumentIndex": 0, + "Title": "dyn.cpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHide\\dyn.cpp", + "RelativeDocumentMoniker": "MasterHide\\dyn.cpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHide\\dyn.cpp", + "RelativeToolTip": "MasterHide\\dyn.cpp", + "ViewState": "AgIAAIsAAAAAAAAAAAAIwJkAAAAFAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|", + "WhenOpened": "2024-08-30T01:17:32.053Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 31, + "Title": "ntwow64.h", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHide\\thirdparty\\phnt\\ntwow64.h", + "RelativeDocumentMoniker": "MasterHide\\thirdparty\\phnt\\ntwow64.h", + "ToolTip": "A:\\work\\MasterHide\\MasterHide\\thirdparty\\phnt\\ntwow64.h", + "RelativeToolTip": "MasterHide\\thirdparty\\phnt\\ntwow64.h", + "ViewState": "AgIAAAAAAAAAAAAAAAAAABUAAAAyAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|", + "WhenOpened": "2024-09-09T19:12:37.182Z" + }, + { + "$type": "Bookmark", + "Name": "ST:0:0:{cce594b6-0c39-4442-ba28-10c64ac7e89f}" + }, + { + "$type": "Document", + "DocumentIndex": 3, + "Title": "includes.hpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHide\\includes.hpp", + "RelativeDocumentMoniker": "MasterHide\\includes.hpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHide\\includes.hpp", + "RelativeToolTip": "MasterHide\\includes.hpp", + "ViewState": "AgIAABgAAAAAAAAAAAAAACgAAAALAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|", + "WhenOpened": "2024-12-10T23:18:02.179Z" + }, + { + "$type": "Document", + "DocumentIndex": 2, + "Title": "tools.cpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHide\\tools.cpp", + "RelativeDocumentMoniker": "MasterHide\\tools.cpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHide\\tools.cpp", + "RelativeToolTip": "MasterHide\\tools.cpp", + "ViewState": "AgIAAGYCAAAAAAAAAAAIwG8CAAAQAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|", + "WhenOpened": "2024-12-10T23:15:23.498Z" + }, + { + "$type": "Document", + "DocumentIndex": 11, + "Title": "klhk.cpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHideLoader\\klhk.cpp", + "RelativeDocumentMoniker": "MasterHideLoader\\klhk.cpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHideLoader\\klhk.cpp", + "RelativeToolTip": "MasterHideLoader\\klhk.cpp", + "ViewState": "AgIAAAAAAAAAAAAAAAAAABUAAAA8AAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|", + "WhenOpened": "2024-12-10T23:10:19.035Z" + }, + { + "$type": "Document", + "DocumentIndex": 8, + "Title": "service.cpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHideLoader\\service.cpp", + "RelativeDocumentMoniker": "MasterHideLoader\\service.cpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHideLoader\\service.cpp", + "RelativeToolTip": "MasterHideLoader\\service.cpp", + "ViewState": "AgIAAAYAAAAAAAAAAAAIwA4AAAABAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|", + "WhenOpened": "2024-12-10T23:08:22.818Z" + }, + { + "$type": "Document", + "DocumentIndex": 10, + "Title": "includes.hpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHideLoader\\includes.hpp", + "RelativeDocumentMoniker": "MasterHideLoader\\includes.hpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHideLoader\\includes.hpp", + "RelativeToolTip": "MasterHideLoader\\includes.hpp", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAoAAAASAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|", + "WhenOpened": "2024-12-10T23:07:36.964Z" + }, + { + "$type": "Document", + "DocumentIndex": 9, + "Title": "loader.cpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHideLoader\\loader.cpp", + "RelativeDocumentMoniker": "MasterHideLoader\\loader.cpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHideLoader\\loader.cpp", + "RelativeToolTip": "MasterHideLoader\\loader.cpp", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAgAAAALAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|", + "WhenOpened": "2024-12-10T23:06:49.822Z" + }, + { + "$type": "Document", + "DocumentIndex": 5, + "Title": "drivermain.cpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHide\\drivermain.cpp", + "RelativeDocumentMoniker": "MasterHide\\drivermain.cpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHide\\drivermain.cpp", + "RelativeToolTip": "MasterHide\\drivermain.cpp", + "ViewState": "AgIAABMAAAAAAAAAAAAIwC8AAAAmAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|", + "WhenOpened": "2024-08-23T18:20:14.613Z" + }, + { + "$type": "Document", + "DocumentIndex": 7, + "Title": "main.cpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHideLoader\\main.cpp", + "RelativeDocumentMoniker": "MasterHideLoader\\main.cpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHideLoader\\main.cpp", + "RelativeToolTip": "MasterHideLoader\\main.cpp", + "ViewState": "AgIAAAAAAAAAAAAAAAAAABQAAAAWAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|", + "WhenOpened": "2024-08-23T02:42:22.298Z" + }, + { + "$type": "Document", + "DocumentIndex": 6, + "Title": "loader.hpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHideLoader\\loader.hpp", + "RelativeDocumentMoniker": "MasterHideLoader\\loader.hpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHideLoader\\loader.hpp", + "RelativeToolTip": "MasterHideLoader\\loader.hpp", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAYAAAAMAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|", + "WhenOpened": "2024-08-23T04:14:42.168Z" + }, + { + "$type": "Document", + "DocumentIndex": 4, + "Title": "tools.hpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHide\\tools.hpp", + "RelativeDocumentMoniker": "MasterHide\\tools.hpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHide\\tools.hpp", + "RelativeToolTip": "MasterHide\\tools.hpp", + "ViewState": "AgIAAFUAAAAAAAAAAAAIwHoAAAAQAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|", + "WhenOpened": "2024-12-06T18:47:30.067Z" + }, + { + "$type": "Document", + "DocumentIndex": 1, + "Title": "dyn.hpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHide\\dyn.hpp", + "RelativeDocumentMoniker": "MasterHide\\dyn.hpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHide\\dyn.hpp", + "RelativeToolTip": "MasterHide\\dyn.hpp", + "ViewState": "AgIAAB4AAAAAAAAAAAAnwDIAAABEAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|", + "WhenOpened": "2024-10-24T03:39:18.349Z" + }, + { + "$type": "Document", + "DocumentIndex": 12, + "Title": "klhk.hpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHideLoader\\klhk.hpp", + "RelativeDocumentMoniker": "MasterHideLoader\\klhk.hpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHideLoader\\klhk.hpp", + "RelativeToolTip": "MasterHideLoader\\klhk.hpp", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAcAAAAmAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|", + "WhenOpened": "2024-08-24T03:11:58.364Z" + }, + { + "$type": "Document", + "DocumentIndex": 13, + "Title": "service.hpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHideLoader\\service.hpp", + "RelativeDocumentMoniker": "MasterHideLoader\\service.hpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHideLoader\\service.hpp", + "RelativeToolTip": "MasterHideLoader\\service.hpp", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAgAAABDAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|", + "WhenOpened": "2024-12-10T23:07:11.26Z" + }, + { + "$type": "Document", + "DocumentIndex": 14, + "Title": "rules.cpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHide\\rules.cpp", + "RelativeDocumentMoniker": "MasterHide\\rules.cpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHide\\rules.cpp", + "RelativeToolTip": "MasterHide\\rules.cpp", + "ViewState": "AgIAAAYBAAAAAAAAAAAIwA0BAAA0AAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|", + "WhenOpened": "2024-09-10T02:49:17.205Z" + }, + { + "$type": "Document", + "DocumentIndex": 15, + "Title": "rules.hpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHide\\rules.hpp", + "RelativeDocumentMoniker": "MasterHide\\rules.hpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHide\\rules.hpp", + "RelativeToolTip": "MasterHide\\rules.hpp", + "ViewState": "AgIAAEwAAAAAAAAAAAAIwFcAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|", + "WhenOpened": "2024-12-10T17:39:31.406Z" + }, + { + "$type": "Document", + "DocumentIndex": 21, + "Title": "syscalls.hpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHide\\syscalls.hpp", + "RelativeDocumentMoniker": "MasterHide\\syscalls.hpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHide\\syscalls.hpp", + "RelativeToolTip": "MasterHide\\syscalls.hpp", + "ViewState": "AgIAAAAAAAAAAAAAAAAAABQAAAAYAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|", + "WhenOpened": "2024-10-29T18:44:25.323Z" + }, + { + "$type": "Document", + "DocumentIndex": 22, + "Title": "object.hpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHide\\object.hpp", + "RelativeDocumentMoniker": "MasterHide\\object.hpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHide\\object.hpp", + "RelativeToolTip": "MasterHide\\object.hpp", + "ViewState": "AgIAAAAAAAAAAAAAAAAAABwAAAApAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|", + "WhenOpened": "2024-09-16T06:55:07.795Z" + }, + { + "$type": "Document", + "DocumentIndex": 23, + "Title": "fnv1a.hpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHide\\fnv1a.hpp", + "RelativeDocumentMoniker": "MasterHide\\fnv1a.hpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHide\\fnv1a.hpp", + "RelativeToolTip": "MasterHide\\fnv1a.hpp", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|", + "WhenOpened": "2024-12-06T04:42:08.944Z" + }, + { + "$type": "Document", + "DocumentIndex": 20, + "Title": "infinityhook.hpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHide\\infinityhook.hpp", + "RelativeDocumentMoniker": "MasterHide\\infinityhook.hpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHide\\infinityhook.hpp", + "RelativeToolTip": "MasterHide\\infinityhook.hpp", + "ViewState": "AgIAAEEAAAAAAAAAAAAnwFYAAAAFAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|", + "WhenOpened": "2024-10-24T03:40:05.124Z" + }, + { + "$type": "Document", + "DocumentIndex": 19, + "Title": "wpp_trace.hpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHide\\wpp_trace.hpp", + "RelativeDocumentMoniker": "MasterHide\\wpp_trace.hpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHide\\wpp_trace.hpp", + "RelativeToolTip": "MasterHide\\wpp_trace.hpp", + "ViewState": "AgIAAAAAAAAAAAAAAAAAABIAAAB4AAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|", + "WhenOpened": "2024-08-29T20:21:21.03Z" + }, + { + "$type": "Document", + "DocumentIndex": 16, + "Title": "hooks.cpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHide\\hooks.cpp", + "RelativeDocumentMoniker": "MasterHide\\hooks.cpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHide\\hooks.cpp", + "RelativeToolTip": "MasterHide\\hooks.cpp", + "ViewState": "AgIAAMwCAAAAAAAAAAAIwN4CAAAsAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|", + "WhenOpened": "2024-08-30T01:16:53.254Z" + }, + { + "$type": "Document", + "DocumentIndex": 17, + "Title": "hooks.hpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHide\\hooks.hpp", + "RelativeDocumentMoniker": "MasterHide\\hooks.hpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHide\\hooks.hpp", + "RelativeToolTip": "MasterHide\\hooks.hpp", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|", + "WhenOpened": "2024-10-24T02:00:39.127Z" + }, + { + "$type": "Document", + "DocumentIndex": 18, + "Title": "infinityhook.cpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHide\\infinityhook.cpp", + "RelativeDocumentMoniker": "MasterHide\\infinityhook.cpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHide\\infinityhook.cpp", + "RelativeToolTip": "MasterHide\\infinityhook.cpp", + "ViewState": "AgIAAAAAAAAAAAAAAAAAACEBAAAVAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|", + "WhenOpened": "2024-10-24T03:41:45.461Z" + }, + { + "$type": "Document", + "DocumentIndex": 25, + "Title": "syscalls.cpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHide\\syscalls.cpp", + "RelativeDocumentMoniker": "MasterHide\\syscalls.cpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHide\\syscalls.cpp", + "RelativeToolTip": "MasterHide\\syscalls.cpp", + "ViewState": "AgIAABsAAAAAAAAAAAAIwCAAAAABAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|", + "WhenOpened": "2024-08-30T19:28:43.011Z" + }, + { + "$type": "Document", + "DocumentIndex": 24, + "Title": "callbacks.hpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHide\\callbacks.hpp", + "RelativeDocumentMoniker": "MasterHide\\callbacks.hpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHide\\callbacks.hpp", + "RelativeToolTip": "MasterHide\\callbacks.hpp", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAoAAAAPAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|", + "WhenOpened": "2024-09-02T17:13:19.356Z" + }, + { + "$type": "Document", + "DocumentIndex": 26, + "Title": "callbacks.cpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHide\\callbacks.cpp", + "RelativeDocumentMoniker": "MasterHide\\callbacks.cpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHide\\callbacks.cpp", + "RelativeToolTip": "MasterHide\\callbacks.cpp", + "ViewState": "AgIAAAIAAAAAAAAAAADgvxgAAAAtAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|", + "WhenOpened": "2024-09-02T17:13:40.189Z" + }, + { + "$type": "Document", + "DocumentIndex": 29, + "Title": "utils.cpp", + "DocumentMoniker": "A:\\work\\MasterHide\\KasperskyHook\\KasperskyHookDrv\\utils.cpp", + "RelativeDocumentMoniker": "KasperskyHook\\KasperskyHookDrv\\utils.cpp", + "ToolTip": "A:\\work\\MasterHide\\KasperskyHook\\KasperskyHookDrv\\utils.cpp", + "RelativeToolTip": "KasperskyHook\\KasperskyHookDrv\\utils.cpp", + "ViewState": "AgIAACgAAAAAAAAAAAAcwG4AAAAnAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|", + "WhenOpened": "2024-08-23T20:16:21.755Z" + }, + { + "$type": "Document", + "DocumentIndex": 28, + "Title": "utils.hpp", + "DocumentMoniker": "A:\\work\\MasterHide\\KasperskyHook\\KasperskyHookDrv\\utils.hpp", + "RelativeDocumentMoniker": "KasperskyHook\\KasperskyHookDrv\\utils.hpp", + "ToolTip": "A:\\work\\MasterHide\\KasperskyHook\\KasperskyHookDrv\\utils.hpp", + "RelativeToolTip": "KasperskyHook\\KasperskyHookDrv\\utils.hpp", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAgAAAAIAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|", + "WhenOpened": "2024-08-23T20:14:46.181Z" + }, + { + "$type": "Document", + "DocumentIndex": 30, + "Title": "kaspersky.hpp", + "DocumentMoniker": "A:\\work\\MasterHide\\KasperskyHook\\KasperskyHookDrv\\kaspersky.hpp", + "RelativeDocumentMoniker": "KasperskyHook\\KasperskyHookDrv\\kaspersky.hpp", + "ToolTip": "A:\\work\\MasterHide\\KasperskyHook\\KasperskyHookDrv\\kaspersky.hpp", + "RelativeToolTip": "KasperskyHook\\KasperskyHookDrv\\kaspersky.hpp", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|", + "WhenOpened": "2024-08-23T20:14:42.005Z" + }, + { + "$type": "Document", + "DocumentIndex": 27, + "Title": "pe.cpp", + "DocumentMoniker": "A:\\work\\MasterHide\\KasperskyHook\\KasperskyHookDrv\\pe.cpp", + "RelativeDocumentMoniker": "KasperskyHook\\KasperskyHookDrv\\pe.cpp", + "ToolTip": "A:\\work\\MasterHide\\KasperskyHook\\KasperskyHookDrv\\pe.cpp", + "RelativeToolTip": "KasperskyHook\\KasperskyHookDrv\\pe.cpp", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|", + "WhenOpened": "2024-08-23T20:17:12.605Z" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/.vs/MasterHide/v17/DocumentLayout.json b/.vs/MasterHide/v17/DocumentLayout.json new file mode 100644 index 0000000..11cf487 --- /dev/null +++ b/.vs/MasterHide/v17/DocumentLayout.json @@ -0,0 +1,537 @@ +{ + "Version": 1, + "WorkspaceRootPath": "A:\\work\\MasterHide\\", + "Documents": [ + { + "AbsoluteMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|A:\\work\\MasterHide\\MasterHide\\dyn.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|solutionrelative:MasterHide\\dyn.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|A:\\work\\MasterHide\\MasterHide\\dyn.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|solutionrelative:MasterHide\\dyn.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|A:\\work\\MasterHide\\MasterHide\\tools.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|solutionrelative:MasterHide\\tools.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|A:\\work\\MasterHide\\MasterHide\\includes.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|solutionrelative:MasterHide\\includes.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|A:\\work\\MasterHide\\MasterHide\\tools.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|solutionrelative:MasterHide\\tools.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|A:\\work\\MasterHide\\MasterHide\\drivermain.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|solutionrelative:MasterHide\\drivermain.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{018FEB18-6063-4D5F-AC3A-7CDFBD224016}|MasterHideLoader\\MasterHideLoader.vcxproj|A:\\work\\MasterHide\\MasterHideLoader\\loader.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{018FEB18-6063-4D5F-AC3A-7CDFBD224016}|MasterHideLoader\\MasterHideLoader.vcxproj|solutionrelative:MasterHideLoader\\loader.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{018FEB18-6063-4D5F-AC3A-7CDFBD224016}|MasterHideLoader\\MasterHideLoader.vcxproj|A:\\work\\MasterHide\\MasterHideLoader\\main.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{018FEB18-6063-4D5F-AC3A-7CDFBD224016}|MasterHideLoader\\MasterHideLoader.vcxproj|solutionrelative:MasterHideLoader\\main.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{018FEB18-6063-4D5F-AC3A-7CDFBD224016}|MasterHideLoader\\MasterHideLoader.vcxproj|A:\\work\\MasterHide\\MasterHideLoader\\service.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{018FEB18-6063-4D5F-AC3A-7CDFBD224016}|MasterHideLoader\\MasterHideLoader.vcxproj|solutionrelative:MasterHideLoader\\service.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{018FEB18-6063-4D5F-AC3A-7CDFBD224016}|MasterHideLoader\\MasterHideLoader.vcxproj|A:\\work\\MasterHide\\MasterHideLoader\\loader.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{018FEB18-6063-4D5F-AC3A-7CDFBD224016}|MasterHideLoader\\MasterHideLoader.vcxproj|solutionrelative:MasterHideLoader\\loader.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{018FEB18-6063-4D5F-AC3A-7CDFBD224016}|MasterHideLoader\\MasterHideLoader.vcxproj|A:\\work\\MasterHide\\MasterHideLoader\\includes.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{018FEB18-6063-4D5F-AC3A-7CDFBD224016}|MasterHideLoader\\MasterHideLoader.vcxproj|solutionrelative:MasterHideLoader\\includes.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{018FEB18-6063-4D5F-AC3A-7CDFBD224016}|MasterHideLoader\\MasterHideLoader.vcxproj|A:\\work\\MasterHide\\MasterHideLoader\\klhk.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{018FEB18-6063-4D5F-AC3A-7CDFBD224016}|MasterHideLoader\\MasterHideLoader.vcxproj|solutionrelative:MasterHideLoader\\klhk.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{018FEB18-6063-4D5F-AC3A-7CDFBD224016}|MasterHideLoader\\MasterHideLoader.vcxproj|A:\\work\\MasterHide\\MasterHideLoader\\klhk.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{018FEB18-6063-4D5F-AC3A-7CDFBD224016}|MasterHideLoader\\MasterHideLoader.vcxproj|solutionrelative:MasterHideLoader\\klhk.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{018FEB18-6063-4D5F-AC3A-7CDFBD224016}|MasterHideLoader\\MasterHideLoader.vcxproj|A:\\work\\MasterHide\\MasterHideLoader\\service.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{018FEB18-6063-4D5F-AC3A-7CDFBD224016}|MasterHideLoader\\MasterHideLoader.vcxproj|solutionrelative:MasterHideLoader\\service.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|A:\\work\\MasterHide\\MasterHide\\rules.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|solutionrelative:MasterHide\\rules.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|A:\\work\\MasterHide\\MasterHide\\rules.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|solutionrelative:MasterHide\\rules.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|A:\\work\\MasterHide\\MasterHide\\hooks.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|solutionrelative:MasterHide\\hooks.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|A:\\work\\MasterHide\\MasterHide\\hooks.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|solutionrelative:MasterHide\\hooks.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|A:\\work\\MasterHide\\MasterHide\\infinityhook.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|solutionrelative:MasterHide\\infinityhook.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|A:\\work\\MasterHide\\MasterHide\\wpp_trace.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|solutionrelative:MasterHide\\wpp_trace.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|A:\\work\\MasterHide\\MasterHide\\infinityhook.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|solutionrelative:MasterHide\\infinityhook.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|A:\\work\\MasterHide\\MasterHide\\syscalls.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|solutionrelative:MasterHide\\syscalls.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|A:\\work\\MasterHide\\MasterHide\\object.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|solutionrelative:MasterHide\\object.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|A:\\work\\MasterHide\\MasterHide\\fnv1a.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|solutionrelative:MasterHide\\fnv1a.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|A:\\work\\MasterHide\\MasterHide\\callbacks.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|solutionrelative:MasterHide\\callbacks.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|A:\\work\\MasterHide\\MasterHide\\syscalls.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|solutionrelative:MasterHide\\syscalls.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|A:\\work\\MasterHide\\MasterHide\\callbacks.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|solutionrelative:MasterHide\\callbacks.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|A:\\work\\MasterHide\\KasperskyHook\\KasperskyHookDrv\\pe.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|solutionrelative:KasperskyHook\\KasperskyHookDrv\\pe.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|A:\\work\\MasterHide\\KasperskyHook\\KasperskyHookDrv\\utils.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|solutionrelative:KasperskyHook\\KasperskyHookDrv\\utils.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|A:\\work\\MasterHide\\KasperskyHook\\KasperskyHookDrv\\utils.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|solutionrelative:KasperskyHook\\KasperskyHookDrv\\utils.cpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|A:\\work\\MasterHide\\KasperskyHook\\KasperskyHookDrv\\kaspersky.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{68D74A79-3DE6-463F-9F5A-03E719657B14}|MasterHide\\MasterHide.vcxproj|solutionrelative:KasperskyHook\\KasperskyHookDrv\\kaspersky.hpp||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + }, + { + "AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|A:\\work\\MasterHide\\MasterHide\\thirdparty\\phnt\\ntwow64.h||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}", + "RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:MasterHide\\thirdparty\\phnt\\ntwow64.h||{D0E1A5C6-B359-4E41-9B60-3365922C2A22}" + } + ], + "DocumentGroupContainers": [ + { + "Orientation": 0, + "VerticalTabListWidth": 256, + "DocumentGroups": [ + { + "DockedWidth": 200, + "SelectedChildIndex": 0, + "Children": [ + { + "$type": "Document", + "DocumentIndex": 0, + "Title": "dyn.cpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHide\\dyn.cpp", + "RelativeDocumentMoniker": "MasterHide\\dyn.cpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHide\\dyn.cpp", + "RelativeToolTip": "MasterHide\\dyn.cpp", + "ViewState": "AgIAAIsAAAAAAAAAAAAIwJkAAAAFAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|", + "WhenOpened": "2024-08-30T01:17:32.053Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 31, + "Title": "ntwow64.h", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHide\\thirdparty\\phnt\\ntwow64.h", + "RelativeDocumentMoniker": "MasterHide\\thirdparty\\phnt\\ntwow64.h", + "ToolTip": "A:\\work\\MasterHide\\MasterHide\\thirdparty\\phnt\\ntwow64.h", + "RelativeToolTip": "MasterHide\\thirdparty\\phnt\\ntwow64.h", + "ViewState": "AgIAAAAAAAAAAAAAAAAAABUAAAAyAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|", + "WhenOpened": "2024-09-09T19:12:37.182Z" + }, + { + "$type": "Bookmark", + "Name": "ST:0:0:{cce594b6-0c39-4442-ba28-10c64ac7e89f}" + }, + { + "$type": "Document", + "DocumentIndex": 3, + "Title": "includes.hpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHide\\includes.hpp", + "RelativeDocumentMoniker": "MasterHide\\includes.hpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHide\\includes.hpp", + "RelativeToolTip": "MasterHide\\includes.hpp", + "ViewState": "AgIAABgAAAAAAAAAAAAAACgAAAALAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|", + "WhenOpened": "2024-12-10T23:18:02.179Z" + }, + { + "$type": "Document", + "DocumentIndex": 2, + "Title": "tools.cpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHide\\tools.cpp", + "RelativeDocumentMoniker": "MasterHide\\tools.cpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHide\\tools.cpp", + "RelativeToolTip": "MasterHide\\tools.cpp", + "ViewState": "AgIAAGYCAAAAAAAAAAAIwG8CAAAQAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|", + "WhenOpened": "2024-12-10T23:15:23.498Z" + }, + { + "$type": "Document", + "DocumentIndex": 11, + "Title": "klhk.cpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHideLoader\\klhk.cpp", + "RelativeDocumentMoniker": "MasterHideLoader\\klhk.cpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHideLoader\\klhk.cpp", + "RelativeToolTip": "MasterHideLoader\\klhk.cpp", + "ViewState": "AgIAAAAAAAAAAAAAAAAAABUAAAA8AAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|", + "WhenOpened": "2024-12-10T23:10:19.035Z" + }, + { + "$type": "Document", + "DocumentIndex": 8, + "Title": "service.cpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHideLoader\\service.cpp", + "RelativeDocumentMoniker": "MasterHideLoader\\service.cpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHideLoader\\service.cpp", + "RelativeToolTip": "MasterHideLoader\\service.cpp", + "ViewState": "AgIAAAYAAAAAAAAAAAAIwA4AAAABAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|", + "WhenOpened": "2024-12-10T23:08:22.818Z" + }, + { + "$type": "Document", + "DocumentIndex": 10, + "Title": "includes.hpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHideLoader\\includes.hpp", + "RelativeDocumentMoniker": "MasterHideLoader\\includes.hpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHideLoader\\includes.hpp", + "RelativeToolTip": "MasterHideLoader\\includes.hpp", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAoAAAASAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|", + "WhenOpened": "2024-12-10T23:07:36.964Z" + }, + { + "$type": "Document", + "DocumentIndex": 9, + "Title": "loader.cpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHideLoader\\loader.cpp", + "RelativeDocumentMoniker": "MasterHideLoader\\loader.cpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHideLoader\\loader.cpp", + "RelativeToolTip": "MasterHideLoader\\loader.cpp", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAgAAAALAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|", + "WhenOpened": "2024-12-10T23:06:49.822Z" + }, + { + "$type": "Document", + "DocumentIndex": 5, + "Title": "drivermain.cpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHide\\drivermain.cpp", + "RelativeDocumentMoniker": "MasterHide\\drivermain.cpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHide\\drivermain.cpp", + "RelativeToolTip": "MasterHide\\drivermain.cpp", + "ViewState": "AgIAABMAAAAAAAAAAAAIwC8AAAAmAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|", + "WhenOpened": "2024-08-23T18:20:14.613Z" + }, + { + "$type": "Document", + "DocumentIndex": 7, + "Title": "main.cpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHideLoader\\main.cpp", + "RelativeDocumentMoniker": "MasterHideLoader\\main.cpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHideLoader\\main.cpp", + "RelativeToolTip": "MasterHideLoader\\main.cpp", + "ViewState": "AgIAAAAAAAAAAAAAAAAAABQAAAAWAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|", + "WhenOpened": "2024-08-23T02:42:22.298Z" + }, + { + "$type": "Document", + "DocumentIndex": 6, + "Title": "loader.hpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHideLoader\\loader.hpp", + "RelativeDocumentMoniker": "MasterHideLoader\\loader.hpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHideLoader\\loader.hpp", + "RelativeToolTip": "MasterHideLoader\\loader.hpp", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAYAAAAMAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|", + "WhenOpened": "2024-08-23T04:14:42.168Z" + }, + { + "$type": "Document", + "DocumentIndex": 4, + "Title": "tools.hpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHide\\tools.hpp", + "RelativeDocumentMoniker": "MasterHide\\tools.hpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHide\\tools.hpp", + "RelativeToolTip": "MasterHide\\tools.hpp", + "ViewState": "AgIAAFUAAAAAAAAAAAAIwHoAAAAQAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|", + "WhenOpened": "2024-12-06T18:47:30.067Z" + }, + { + "$type": "Document", + "DocumentIndex": 1, + "Title": "dyn.hpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHide\\dyn.hpp", + "RelativeDocumentMoniker": "MasterHide\\dyn.hpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHide\\dyn.hpp", + "RelativeToolTip": "MasterHide\\dyn.hpp", + "ViewState": "AgIAAB4AAAAAAAAAAAAnwDIAAABEAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|", + "WhenOpened": "2024-10-24T03:39:18.349Z" + }, + { + "$type": "Document", + "DocumentIndex": 12, + "Title": "klhk.hpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHideLoader\\klhk.hpp", + "RelativeDocumentMoniker": "MasterHideLoader\\klhk.hpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHideLoader\\klhk.hpp", + "RelativeToolTip": "MasterHideLoader\\klhk.hpp", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAcAAAAmAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|", + "WhenOpened": "2024-08-24T03:11:58.364Z" + }, + { + "$type": "Document", + "DocumentIndex": 13, + "Title": "service.hpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHideLoader\\service.hpp", + "RelativeDocumentMoniker": "MasterHideLoader\\service.hpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHideLoader\\service.hpp", + "RelativeToolTip": "MasterHideLoader\\service.hpp", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAgAAABDAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|", + "WhenOpened": "2024-12-10T23:07:11.26Z" + }, + { + "$type": "Document", + "DocumentIndex": 14, + "Title": "rules.cpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHide\\rules.cpp", + "RelativeDocumentMoniker": "MasterHide\\rules.cpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHide\\rules.cpp", + "RelativeToolTip": "MasterHide\\rules.cpp", + "ViewState": "AgIAAAYBAAAAAAAAAAAIwA0BAAA0AAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|", + "WhenOpened": "2024-09-10T02:49:17.205Z" + }, + { + "$type": "Document", + "DocumentIndex": 15, + "Title": "rules.hpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHide\\rules.hpp", + "RelativeDocumentMoniker": "MasterHide\\rules.hpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHide\\rules.hpp", + "RelativeToolTip": "MasterHide\\rules.hpp", + "ViewState": "AgIAAEwAAAAAAAAAAAAIwFcAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|", + "WhenOpened": "2024-12-10T17:39:31.406Z" + }, + { + "$type": "Document", + "DocumentIndex": 21, + "Title": "syscalls.hpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHide\\syscalls.hpp", + "RelativeDocumentMoniker": "MasterHide\\syscalls.hpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHide\\syscalls.hpp", + "RelativeToolTip": "MasterHide\\syscalls.hpp", + "ViewState": "AgIAAAAAAAAAAAAAAAAAABQAAAAYAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|", + "WhenOpened": "2024-10-29T18:44:25.323Z" + }, + { + "$type": "Document", + "DocumentIndex": 22, + "Title": "object.hpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHide\\object.hpp", + "RelativeDocumentMoniker": "MasterHide\\object.hpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHide\\object.hpp", + "RelativeToolTip": "MasterHide\\object.hpp", + "ViewState": "AgIAAAAAAAAAAAAAAAAAABwAAAApAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|", + "WhenOpened": "2024-09-16T06:55:07.795Z" + }, + { + "$type": "Document", + "DocumentIndex": 23, + "Title": "fnv1a.hpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHide\\fnv1a.hpp", + "RelativeDocumentMoniker": "MasterHide\\fnv1a.hpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHide\\fnv1a.hpp", + "RelativeToolTip": "MasterHide\\fnv1a.hpp", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|", + "WhenOpened": "2024-12-06T04:42:08.944Z" + }, + { + "$type": "Document", + "DocumentIndex": 20, + "Title": "infinityhook.hpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHide\\infinityhook.hpp", + "RelativeDocumentMoniker": "MasterHide\\infinityhook.hpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHide\\infinityhook.hpp", + "RelativeToolTip": "MasterHide\\infinityhook.hpp", + "ViewState": "AgIAAEEAAAAAAAAAAAAnwFYAAAAFAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|", + "WhenOpened": "2024-10-24T03:40:05.124Z" + }, + { + "$type": "Document", + "DocumentIndex": 19, + "Title": "wpp_trace.hpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHide\\wpp_trace.hpp", + "RelativeDocumentMoniker": "MasterHide\\wpp_trace.hpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHide\\wpp_trace.hpp", + "RelativeToolTip": "MasterHide\\wpp_trace.hpp", + "ViewState": "AgIAAAAAAAAAAAAAAAAAABIAAAB4AAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|", + "WhenOpened": "2024-08-29T20:21:21.03Z" + }, + { + "$type": "Document", + "DocumentIndex": 16, + "Title": "hooks.cpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHide\\hooks.cpp", + "RelativeDocumentMoniker": "MasterHide\\hooks.cpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHide\\hooks.cpp", + "RelativeToolTip": "MasterHide\\hooks.cpp", + "ViewState": "AgIAAMwCAAAAAAAAAAAIwN4CAAAsAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|", + "WhenOpened": "2024-08-30T01:16:53.254Z" + }, + { + "$type": "Document", + "DocumentIndex": 17, + "Title": "hooks.hpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHide\\hooks.hpp", + "RelativeDocumentMoniker": "MasterHide\\hooks.hpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHide\\hooks.hpp", + "RelativeToolTip": "MasterHide\\hooks.hpp", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|", + "WhenOpened": "2024-10-24T02:00:39.127Z" + }, + { + "$type": "Document", + "DocumentIndex": 18, + "Title": "infinityhook.cpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHide\\infinityhook.cpp", + "RelativeDocumentMoniker": "MasterHide\\infinityhook.cpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHide\\infinityhook.cpp", + "RelativeToolTip": "MasterHide\\infinityhook.cpp", + "ViewState": "AgIAAAAAAAAAAAAAAAAAACEBAAAVAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|", + "WhenOpened": "2024-10-24T03:41:45.461Z" + }, + { + "$type": "Document", + "DocumentIndex": 25, + "Title": "syscalls.cpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHide\\syscalls.cpp", + "RelativeDocumentMoniker": "MasterHide\\syscalls.cpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHide\\syscalls.cpp", + "RelativeToolTip": "MasterHide\\syscalls.cpp", + "ViewState": "AgIAABsAAAAAAAAAAAAIwCAAAAABAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|", + "WhenOpened": "2024-08-30T19:28:43.011Z" + }, + { + "$type": "Document", + "DocumentIndex": 24, + "Title": "callbacks.hpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHide\\callbacks.hpp", + "RelativeDocumentMoniker": "MasterHide\\callbacks.hpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHide\\callbacks.hpp", + "RelativeToolTip": "MasterHide\\callbacks.hpp", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAoAAAAPAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|", + "WhenOpened": "2024-09-02T17:13:19.356Z" + }, + { + "$type": "Document", + "DocumentIndex": 26, + "Title": "callbacks.cpp", + "DocumentMoniker": "A:\\work\\MasterHide\\MasterHide\\callbacks.cpp", + "RelativeDocumentMoniker": "MasterHide\\callbacks.cpp", + "ToolTip": "A:\\work\\MasterHide\\MasterHide\\callbacks.cpp", + "RelativeToolTip": "MasterHide\\callbacks.cpp", + "ViewState": "AgIAAAIAAAAAAAAAAADgvxgAAAAtAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|", + "WhenOpened": "2024-09-02T17:13:40.189Z" + }, + { + "$type": "Document", + "DocumentIndex": 29, + "Title": "utils.cpp", + "DocumentMoniker": "A:\\work\\MasterHide\\KasperskyHook\\KasperskyHookDrv\\utils.cpp", + "RelativeDocumentMoniker": "KasperskyHook\\KasperskyHookDrv\\utils.cpp", + "ToolTip": "A:\\work\\MasterHide\\KasperskyHook\\KasperskyHookDrv\\utils.cpp", + "RelativeToolTip": "KasperskyHook\\KasperskyHookDrv\\utils.cpp", + "ViewState": "AgIAACgAAAAAAAAAAAAcwG4AAAAnAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|", + "WhenOpened": "2024-08-23T20:16:21.755Z" + }, + { + "$type": "Document", + "DocumentIndex": 28, + "Title": "utils.hpp", + "DocumentMoniker": "A:\\work\\MasterHide\\KasperskyHook\\KasperskyHookDrv\\utils.hpp", + "RelativeDocumentMoniker": "KasperskyHook\\KasperskyHookDrv\\utils.hpp", + "ToolTip": "A:\\work\\MasterHide\\KasperskyHook\\KasperskyHookDrv\\utils.hpp", + "RelativeToolTip": "KasperskyHook\\KasperskyHookDrv\\utils.hpp", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAgAAAAIAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|", + "WhenOpened": "2024-08-23T20:14:46.181Z" + }, + { + "$type": "Document", + "DocumentIndex": 30, + "Title": "kaspersky.hpp", + "DocumentMoniker": "A:\\work\\MasterHide\\KasperskyHook\\KasperskyHookDrv\\kaspersky.hpp", + "RelativeDocumentMoniker": "KasperskyHook\\KasperskyHookDrv\\kaspersky.hpp", + "ToolTip": "A:\\work\\MasterHide\\KasperskyHook\\KasperskyHookDrv\\kaspersky.hpp", + "RelativeToolTip": "KasperskyHook\\KasperskyHookDrv\\kaspersky.hpp", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000680|", + "WhenOpened": "2024-08-23T20:14:42.005Z" + }, + { + "$type": "Document", + "DocumentIndex": 27, + "Title": "pe.cpp", + "DocumentMoniker": "A:\\work\\MasterHide\\KasperskyHook\\KasperskyHookDrv\\pe.cpp", + "RelativeDocumentMoniker": "KasperskyHook\\KasperskyHookDrv\\pe.cpp", + "ToolTip": "A:\\work\\MasterHide\\KasperskyHook\\KasperskyHookDrv\\pe.cpp", + "RelativeToolTip": "KasperskyHook\\KasperskyHookDrv\\pe.cpp", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000677|", + "WhenOpened": "2024-08-23T20:17:12.605Z" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/KasperskyHook b/KasperskyHook index 9c7d412..238c1b8 160000 --- a/KasperskyHook +++ b/KasperskyHook @@ -1 +1 @@ -Subproject commit 9c7d412ddf59f622b5a054a23aeffaaa0e77d3c3 +Subproject commit 238c1b8f376b91b63fbac260d7c6b5fefa76f375 diff --git a/MasterHide.sln b/MasterHide.sln index 0fe977e..e4b92fc 100644 --- a/MasterHide.sln +++ b/MasterHide.sln @@ -1,62 +1,76 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 -VisualStudioVersion = 16.0.30406.217 +VisualStudioVersion = 16.0.35425.106 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MasterHide", "MasterHide\MasterHide.vcxproj", "{68D74A79-3DE6-463F-9F5A-03E719657B14}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestHide", "TestHide\TestHide.vcxproj", "{F3EC3652-037E-45A3-9C0B-7703800D858B}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MasterHideCLI", "MasterHideCLI\MasterHideCLI.vcxproj", "{018FEB18-6063-4D5F-AC3A-7CDFBD224016}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KasperskyHookLoader", "KasperskyHook\KasperskyHookLoader\KasperskyHookLoader.vcxproj", "{AC843DC7-AE89-45D5-AD78-EDCB560ACCC3}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MasterHideGUI", "MasterHideGUI\MasterHideGUI.csproj", "{A467E282-D784-4C89-9394-818316B0661D}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|ARM = Debug|ARM - Debug|ARM64 = Debug|ARM64 + Debug|Any CPU = Debug|Any CPU + Debug|Win32 = Debug|Win32 Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 - Release|ARM = Release|ARM - Release|ARM64 = Release|ARM64 + Release|Any CPU = Release|Any CPU + Release|Win32 = Release|Win32 Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {68D74A79-3DE6-463F-9F5A-03E719657B14}.Debug|ARM.ActiveCfg = Debug|x64 - {68D74A79-3DE6-463F-9F5A-03E719657B14}.Debug|ARM64.ActiveCfg = Debug|x64 + {68D74A79-3DE6-463F-9F5A-03E719657B14}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {68D74A79-3DE6-463F-9F5A-03E719657B14}.Debug|Win32.ActiveCfg = Debug|Win32 + {68D74A79-3DE6-463F-9F5A-03E719657B14}.Debug|Win32.Build.0 = Debug|Win32 + {68D74A79-3DE6-463F-9F5A-03E719657B14}.Debug|Win32.Deploy.0 = Debug|Win32 {68D74A79-3DE6-463F-9F5A-03E719657B14}.Debug|x64.ActiveCfg = Debug|x64 {68D74A79-3DE6-463F-9F5A-03E719657B14}.Debug|x64.Build.0 = Debug|x64 {68D74A79-3DE6-463F-9F5A-03E719657B14}.Debug|x64.Deploy.0 = Debug|x64 - {68D74A79-3DE6-463F-9F5A-03E719657B14}.Debug|x86.ActiveCfg = Debug|x64 - {68D74A79-3DE6-463F-9F5A-03E719657B14}.Release|ARM.ActiveCfg = Release|x64 - {68D74A79-3DE6-463F-9F5A-03E719657B14}.Release|ARM64.ActiveCfg = Release|x64 + {68D74A79-3DE6-463F-9F5A-03E719657B14}.Debug|x86.ActiveCfg = Debug|Win32 + {68D74A79-3DE6-463F-9F5A-03E719657B14}.Debug|x86.Build.0 = Debug|Win32 + {68D74A79-3DE6-463F-9F5A-03E719657B14}.Debug|x86.Deploy.0 = Debug|Win32 + {68D74A79-3DE6-463F-9F5A-03E719657B14}.Release|Any CPU.ActiveCfg = Release|Win32 + {68D74A79-3DE6-463F-9F5A-03E719657B14}.Release|Win32.ActiveCfg = Release|Win32 + {68D74A79-3DE6-463F-9F5A-03E719657B14}.Release|Win32.Build.0 = Release|Win32 + {68D74A79-3DE6-463F-9F5A-03E719657B14}.Release|Win32.Deploy.0 = Release|Win32 {68D74A79-3DE6-463F-9F5A-03E719657B14}.Release|x64.ActiveCfg = Release|x64 {68D74A79-3DE6-463F-9F5A-03E719657B14}.Release|x64.Build.0 = Release|x64 {68D74A79-3DE6-463F-9F5A-03E719657B14}.Release|x64.Deploy.0 = Release|x64 - {68D74A79-3DE6-463F-9F5A-03E719657B14}.Release|x86.ActiveCfg = Release|x64 - {F3EC3652-037E-45A3-9C0B-7703800D858B}.Debug|ARM.ActiveCfg = Debug|Win32 - {F3EC3652-037E-45A3-9C0B-7703800D858B}.Debug|ARM64.ActiveCfg = Debug|Win32 - {F3EC3652-037E-45A3-9C0B-7703800D858B}.Debug|x64.ActiveCfg = Debug|x64 - {F3EC3652-037E-45A3-9C0B-7703800D858B}.Debug|x64.Build.0 = Debug|x64 - {F3EC3652-037E-45A3-9C0B-7703800D858B}.Debug|x86.ActiveCfg = Debug|Win32 - {F3EC3652-037E-45A3-9C0B-7703800D858B}.Debug|x86.Build.0 = Debug|Win32 - {F3EC3652-037E-45A3-9C0B-7703800D858B}.Release|ARM.ActiveCfg = Release|Win32 - {F3EC3652-037E-45A3-9C0B-7703800D858B}.Release|ARM64.ActiveCfg = Release|Win32 - {F3EC3652-037E-45A3-9C0B-7703800D858B}.Release|x64.ActiveCfg = Release|x64 - {F3EC3652-037E-45A3-9C0B-7703800D858B}.Release|x64.Build.0 = Release|x64 - {F3EC3652-037E-45A3-9C0B-7703800D858B}.Release|x86.ActiveCfg = Release|Win32 - {F3EC3652-037E-45A3-9C0B-7703800D858B}.Release|x86.Build.0 = Release|Win32 - {AC843DC7-AE89-45D5-AD78-EDCB560ACCC3}.Debug|ARM.ActiveCfg = Debug|Win32 - {AC843DC7-AE89-45D5-AD78-EDCB560ACCC3}.Debug|ARM64.ActiveCfg = Debug|Win32 - {AC843DC7-AE89-45D5-AD78-EDCB560ACCC3}.Debug|x64.ActiveCfg = Debug|x64 - {AC843DC7-AE89-45D5-AD78-EDCB560ACCC3}.Debug|x64.Build.0 = Debug|x64 - {AC843DC7-AE89-45D5-AD78-EDCB560ACCC3}.Debug|x86.ActiveCfg = Debug|Win32 - {AC843DC7-AE89-45D5-AD78-EDCB560ACCC3}.Debug|x86.Build.0 = Debug|Win32 - {AC843DC7-AE89-45D5-AD78-EDCB560ACCC3}.Release|ARM.ActiveCfg = Release|Win32 - {AC843DC7-AE89-45D5-AD78-EDCB560ACCC3}.Release|ARM64.ActiveCfg = Release|Win32 - {AC843DC7-AE89-45D5-AD78-EDCB560ACCC3}.Release|x64.ActiveCfg = Release|x64 - {AC843DC7-AE89-45D5-AD78-EDCB560ACCC3}.Release|x64.Build.0 = Release|x64 - {AC843DC7-AE89-45D5-AD78-EDCB560ACCC3}.Release|x86.ActiveCfg = Release|Win32 - {AC843DC7-AE89-45D5-AD78-EDCB560ACCC3}.Release|x86.Build.0 = Release|Win32 + {68D74A79-3DE6-463F-9F5A-03E719657B14}.Release|x86.ActiveCfg = Release|Win32 + {68D74A79-3DE6-463F-9F5A-03E719657B14}.Release|x86.Build.0 = Release|Win32 + {68D74A79-3DE6-463F-9F5A-03E719657B14}.Release|x86.Deploy.0 = Release|Win32 + {018FEB18-6063-4D5F-AC3A-7CDFBD224016}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {018FEB18-6063-4D5F-AC3A-7CDFBD224016}.Debug|Win32.ActiveCfg = Debug|Win32 + {018FEB18-6063-4D5F-AC3A-7CDFBD224016}.Debug|Win32.Build.0 = Debug|Win32 + {018FEB18-6063-4D5F-AC3A-7CDFBD224016}.Debug|x64.ActiveCfg = Debug|x64 + {018FEB18-6063-4D5F-AC3A-7CDFBD224016}.Debug|x64.Build.0 = Debug|x64 + {018FEB18-6063-4D5F-AC3A-7CDFBD224016}.Debug|x86.ActiveCfg = Debug|Win32 + {018FEB18-6063-4D5F-AC3A-7CDFBD224016}.Debug|x86.Build.0 = Debug|Win32 + {018FEB18-6063-4D5F-AC3A-7CDFBD224016}.Release|Any CPU.ActiveCfg = Release|Win32 + {018FEB18-6063-4D5F-AC3A-7CDFBD224016}.Release|Win32.ActiveCfg = Release|Win32 + {018FEB18-6063-4D5F-AC3A-7CDFBD224016}.Release|Win32.Build.0 = Release|Win32 + {018FEB18-6063-4D5F-AC3A-7CDFBD224016}.Release|x64.ActiveCfg = Release|x64 + {018FEB18-6063-4D5F-AC3A-7CDFBD224016}.Release|x64.Build.0 = Release|x64 + {018FEB18-6063-4D5F-AC3A-7CDFBD224016}.Release|x86.ActiveCfg = Release|Win32 + {018FEB18-6063-4D5F-AC3A-7CDFBD224016}.Release|x86.Build.0 = Release|Win32 + {A467E282-D784-4C89-9394-818316B0661D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A467E282-D784-4C89-9394-818316B0661D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A467E282-D784-4C89-9394-818316B0661D}.Debug|Win32.ActiveCfg = Debug|Any CPU + {A467E282-D784-4C89-9394-818316B0661D}.Debug|Win32.Build.0 = Debug|Any CPU + {A467E282-D784-4C89-9394-818316B0661D}.Debug|x64.ActiveCfg = Debug|Any CPU + {A467E282-D784-4C89-9394-818316B0661D}.Debug|x64.Build.0 = Debug|Any CPU + {A467E282-D784-4C89-9394-818316B0661D}.Debug|x86.ActiveCfg = Debug|Any CPU + {A467E282-D784-4C89-9394-818316B0661D}.Debug|x86.Build.0 = Debug|Any CPU + {A467E282-D784-4C89-9394-818316B0661D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A467E282-D784-4C89-9394-818316B0661D}.Release|Any CPU.Build.0 = Release|Any CPU + {A467E282-D784-4C89-9394-818316B0661D}.Release|Win32.ActiveCfg = Release|Any CPU + {A467E282-D784-4C89-9394-818316B0661D}.Release|Win32.Build.0 = Release|Any CPU + {A467E282-D784-4C89-9394-818316B0661D}.Release|x64.ActiveCfg = Release|Any CPU + {A467E282-D784-4C89-9394-818316B0661D}.Release|x64.Build.0 = Release|Any CPU + {A467E282-D784-4C89-9394-818316B0661D}.Release|x86.ActiveCfg = Release|Any CPU + {A467E282-D784-4C89-9394-818316B0661D}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/MasterHide/MasterHide.mof b/MasterHide/MasterHide.mof new file mode 100644 index 0000000..995d1ab --- /dev/null +++ b/MasterHide/MasterHide.mof @@ -0,0 +1,28 @@ +#pragma autorecover +#pragma classflags("forceupdate") +#pragma namespace("\\\\.\\root\\WMI") +// +// WPP Generated File +// PDB: A:\work\MasterHide\bin\Debug\MasterHide.pdb +// PDB: Last Updated :2024-12-26:18:17:16:454 (UTC) [tracepdb] +// + +//ModuleName = MasterHideMasterHideCtrlGUID (Init called in Function WPP_CONTROL_ANNOTATION) +[Dynamic, + Description("MasterHide_MasterHideCtrlGUID"), + guid("{EDC00A52-CBB9-490E-89A3-69E3FFF137BA}"), + locale("MS\\0x409")] +class MasterHideMasterHideCtrlGUID : EventTrace +{ + [Description ("Enable Flags") : amended, + ValueDescriptions{ + "GENERAL Flag"}, + DefineValues{ + "GENERAL"}, + Values{ + "GENERAL"}, + ValueMap{ + "0x00000001"}: amended + ] + uint32 Flags; +}; diff --git a/MasterHide/MasterHide.vcxproj b/MasterHide/MasterHide.vcxproj index 5df1e38..edd9221 100644 --- a/MasterHide/MasterHide.vcxproj +++ b/MasterHide/MasterHide.vcxproj @@ -1,10 +1,18 @@  + + Debug + Win32 + Debug x64 + + Release + Win32 + Release x64 @@ -18,16 +26,28 @@ Debug Win32 MasterHide - 10.0.18362.0 + MasterHide + 10.0.19041.0 + true + WindowsKernelModeDriver10.0 + Driver + WDM Windows7 + false + <_NT_TARGET_VERSION>0x0601 + 6.1.0 + + true WindowsKernelModeDriver10.0 Driver WDM - Desktop + Windows10 + false + <_NT_TARGET_VERSION>0x0A00 Windows7 @@ -35,8 +55,18 @@ WindowsKernelModeDriver10.0 Driver WDM - Desktop <_NT_TARGET_VERSION>0x0601 + false + 6.1.0 + + + Windows10 + false + WindowsKernelModeDriver10.0 + Driver + WDM + <_NT_TARGET_VERSION>0x0A00 + false @@ -49,17 +79,47 @@ DbgengKernelDebugger false + $(VC_IncludePath);$(KM_IncludePath);$(KIT_SHARED_IncludePath) + $(ExternalIncludePath) + ..\bin\$(Configuration)\ + intermediate\$(Platform)\$(ConfigurationName)\ + + + DbgengKernelDebugger + false + $(VC_IncludePath);$(KM_IncludePath);$(KIT_SHARED_IncludePath) + $(ExternalIncludePath) DbgengKernelDebugger false + $(VC_IncludePath);$(KM_IncludePath);$(KIT_SHARED_IncludePath) + $(ExternalIncludePath) + ..\bin\$(Configuration)\ + intermediate\$(Platform)\$(ConfigurationName)\ + + + DbgengKernelDebugger + false + $(VC_IncludePath);$(KM_IncludePath);$(KIT_SHARED_IncludePath) + $(ExternalIncludePath) $(DDK_LIB_PATH)\BufferOverflowK.lib;$(DDK_LIB_PATH)ntoskrnl.lib;$(DDK_LIB_PATH)hal.lib;$(DDK_LIB_PATH)wmilib.lib + true + /INTEGRITYCHECK %(AdditionalOptions) - ..\KasperskyHook\KasperskyHookDrv;%(AdditionalIncludeDirectories) + $(VC_IncludePath);$(KM_IncludePath);$(KIT_SHARED_IncludePath);$(ProjectDir)thirdparty\phnt;$(SolutionDir)KasperskyHook\KasperskyHookDrv;%(AdditionalIncludeDirectories) + PHNT_VERSION=PHNT_WIN11;PHNT_MODE=PHNT_KERNEL;TMH_FILE=%(FileName)%(Extension).tmh;_NO_CRT_STDIO_INLINE;__STDC_WANT_SECURE_LIB__=0;SCOPE_GUARD_NO_THROW_ACTION;%(PreprocessorDefinitions) + 4996;4201;%(DisableSpecificWarnings) + stdcpp20 + false + true + WppTracePrint(LEVEL,EVENT,MSG,...) + .c.cpp.h.hpp + .c.cpp.h.hpp false @@ -67,44 +127,151 @@ false + + sha256 + + + if not exist "$(ProjectDir)tmf" mkdir "$(ProjectDir)tmf" +"$(WDKBinRoot_x64)\tracepdb.exe" -f "$(TargetDir)$(AssemblyName).pdb" -p $(ProjectDir)tmf + + + + + $(DDK_LIB_PATH)\BufferOverflowK.lib;$(DDK_LIB_PATH)ntoskrnl.lib;$(DDK_LIB_PATH)hal.lib;$(DDK_LIB_PATH)wmilib.lib + false + + + $(VC_IncludePath);$(KM_IncludePath);$(KIT_SHARED_IncludePath);$(ProjectDir)thirdparty\phnt;$(SolutionDir)KasperskyHook\KasperskyHookDrv;%(AdditionalIncludeDirectories) + PHNT_VERSION=PHNT_WIN11;PHNT_MODE=PHNT_KERNEL;TMH_FILE=%(FileName)%(Extension).tmh;_NO_CRT_STDIO_INLINE;__STDC_WANT_SECURE_LIB__=0;SCOPE_GUARD_NO_THROW_ACTION;%(PreprocessorDefinitions) + 4996;4201;%(DisableSpecificWarnings) + stdcpp20 + false + true + WppTracePrint(LEVEL,EVENT,MSG,...) + .c.cpp.h.hpp + .c.cpp.h.hpp + + + false + false + false + + + + + sha256 + $(DDK_LIB_PATH)\BufferOverflowK.lib;$(DDK_LIB_PATH)ntoskrnl.lib;$(DDK_LIB_PATH)hal.lib;$(DDK_LIB_PATH)wmilib.lib + true + /INTEGRITYCHECK %(AdditionalOptions) - ..\KasperskyHook\KasperskyHookDrv;%(AdditionalIncludeDirectories) + $(VC_IncludePath);$(KM_IncludePath);$(KIT_SHARED_IncludePath);$(ProjectDir)thirdparty\phnt;$(SolutionDir)KasperskyHook\KasperskyHookDrv;%(AdditionalIncludeDirectories) + 4996;4201;%(DisableSpecificWarnings) + stdcpp20 + PHNT_VERSION=PHNT_WIN11;PHNT_MODE=PHNT_KERNEL;TMH_FILE=%(FileName)%(Extension).tmh;_NO_CRT_STDIO_INLINE;__STDC_WANT_SECURE_LIB__=0;SCOPE_GUARD_NO_THROW_ACTION;_WIN64;_AMD64_;AMD64;%(PreprocessorDefinitions) + false + true + WppTracePrint(LEVEL,EVENT,MSG,...) + .c.cpp.h.hpp + .c.cpp.h.hpp false + + sha256 + + + if not exist "$(ProjectDir)tmf" mkdir "$(ProjectDir)tmf" +"$(WDKBinRoot_x64)\tracepdb.exe" -f "$(TargetDir)$(AssemblyName).pdb" -p $(ProjectDir)tmf + + + + + $(DDK_LIB_PATH)\BufferOverflowK.lib;$(DDK_LIB_PATH)ntoskrnl.lib;$(DDK_LIB_PATH)hal.lib;$(DDK_LIB_PATH)wmilib.lib + false + + + $(VC_IncludePath);$(KM_IncludePath);$(KIT_SHARED_IncludePath);$(ProjectDir)thirdparty\phnt;$(SolutionDir)KasperskyHook\KasperskyHookDrv;%(AdditionalIncludeDirectories) + 4996;4201;%(DisableSpecificWarnings) + stdcpp20 + PHNT_VERSION=PHNT_WIN11;PHNT_MODE=PHNT_KERNEL;TMH_FILE=%(FileName)%(Extension).tmh;_NO_CRT_STDIO_INLINE;__STDC_WANT_SECURE_LIB__=0;SCOPE_GUARD_NO_THROW_ACTION;_WIN64;_AMD64_;AMD64;%(PreprocessorDefinitions) + false + true + WppTracePrint(LEVEL,EVENT,MSG,...) + .c.cpp.h.hpp + .c.cpp.h.hpp + + + false + + + sha256 + - + + true + true + true + true + + + true + true + true + true + - - - - + + + + + + + + + + + + true + true + true + true + + - - - - - - - + + + + + + + + + + + + + + + + diff --git a/MasterHide/MasterHide.vcxproj.filters b/MasterHide/MasterHide.vcxproj.filters index 588b752..4194378 100644 --- a/MasterHide/MasterHide.vcxproj.filters +++ b/MasterHide/MasterHide.vcxproj.filters @@ -17,72 +17,135 @@ {8E41214B-6785-4CFE-B992-037D68949A14} inf;inv;inx;mof;mc; - + {6c5d2264-5690-4b45-b290-99996ca571c5} + + {11a32ebc-6299-48de-ab64-db9b9aaca9d2} + + + {27574ec6-ab53-4c6f-a20b-9a5ebc0db643} + + + {7abbcebf-eca4-4bce-9d2d-73b68b3fd090} + - + Source Files Source Files - - Source Files - - - Source Files - - Header Files\Kaspersky + Header Files\KasperskyHook - Header Files\Kaspersky + Header Files\KasperskyHook - Header Files\Kaspersky + Header Files\KasperskyHook - Header Files\Kaspersky + Header Files\KasperskyHook - Header Files\Kaspersky + Header Files\KasperskyHook + + + Source Files + + + Header Files\KasperskyHook + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Header Files\infinityhook + + + Header Files\infinityhook\hde - + Source Files - + Header Files - + Header Files - + Header Files - + + Header Files\KasperskyHook + + + Header Files\KasperskyHook + + + Header Files\KasperskyHook + + Header Files - + + Header Files\KasperskyHook + + + Header Files\KasperskyHook + + Header Files - - Header Files\Kaspersky + + Header Files - - Header Files\Kaspersky + + Header Files - - Header Files\Kaspersky + + Header Files + + + Header Files - + Header Files - + Header Files + + Header Files\infinityhook + + + Header Files\infinityhook\hde + + + Header Files\infinityhook\hde + + + Header Files\infinityhook\hde + + + Header Files\shared + \ No newline at end of file diff --git a/MasterHide/callbacks.cpp b/MasterHide/callbacks.cpp new file mode 100644 index 0000000..c53ffd5 --- /dev/null +++ b/MasterHide/callbacks.cpp @@ -0,0 +1,99 @@ +#include "includes.hpp" + +namespace masterhide +{ +using namespace process; +using namespace rules; + +namespace callbacks +{ +VOID CreateProcessNotifyRoutineEx(_Inout_ PEPROCESS Process, _In_ HANDLE ProcessId, + _Inout_ PPS_CREATE_NOTIFY_INFO CreateInfo); + +inline bool g_initialized = false; + +NTSTATUS Initialize() +{ + PAGED_CODE(); + NT_ASSERT(!g_initialized); + + if (g_initialized) + { + return STATUS_ALREADY_INITIALIZED; + } + + const NTSTATUS status = PsSetCreateProcessNotifyRoutineEx(&CreateProcessNotifyRoutineEx, FALSE); + if (!NT_SUCCESS(status)) + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "PsSetCreateProcessNotifyRoutine returned %!STATUS!", status); + return STATUS_UNSUCCESSFUL; + } + + g_initialized = true; + + return STATUS_SUCCESS; +} + +void Deinitialize() +{ + PAGED_CODE(); + + if (!g_initialized) + { + return; + } + + PsSetCreateProcessNotifyRoutineEx(&CreateProcessNotifyRoutineEx, TRUE); + + g_initialized = false; + + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, "Successfully de-initialized callbacks interface!"); + return; +} + +VOID CreateProcessNotifyRoutineEx(_Inout_ PEPROCESS Process, _In_ HANDLE ProcessId, + _Inout_ PPS_CREATE_NOTIFY_INFO CreateInfo) +{ + if (CreateInfo) + { + if (!CreateInfo->ImageFileName) + { + return; + } + + PPROCESS_RULE_ENTRY processRuleEntry = GetProcessRuleEntry(CreateInfo->ImageFileName); + + // If there's a rule for the creating process + // + if (processRuleEntry) + { + // Proceed to create a process entry + // + const NTSTATUS status = AddProcessEntry(Process, processRuleEntry->PolicyFlags); + if (NT_SUCCESS(status)) + { + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, + "Successfully added process rule entry imageName:%wZ pid:%d policyFlags:%lld", + CreateInfo->ImageFileName, HandleToUlong(ProcessId), processRuleEntry->PolicyFlags); + } + else + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "Failed to add process entry %!STATUS!", status); + } + + object::DereferenceObject(processRuleEntry); + } + } + else + { + // Will remove if on list + // + if (NT_SUCCESS(RemoveProcessEntry(Process))) + { + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, "Removed process entry pid:%d", HandleToUlong(ProcessId)); + } + } +} + +} // namespace callbacks +} // namespace masterhide \ No newline at end of file diff --git a/MasterHide/callbacks.hpp b/MasterHide/callbacks.hpp new file mode 100644 index 0000000..df078a0 --- /dev/null +++ b/MasterHide/callbacks.hpp @@ -0,0 +1,21 @@ +#pragma once + +namespace masterhide +{ +namespace callbacks +{ +VOID CreateProcessNotifyRoutineEx(_Inout_ PEPROCESS Process, _In_ HANDLE ProcessId, + _Inout_ PPS_CREATE_NOTIFY_INFO CreateInfo); + +/// +/// Initialize callbacks. +/// +/// STATUS_SUCCESS on success, otherwise any NTSTATUS value +NTSTATUS Initialize(); + +/// +/// De-initialize callbacks. +/// +void Deinitialize(); +} // namespace callbacks +} // namespace masterhide \ No newline at end of file diff --git a/MasterHide/drivermain.cpp b/MasterHide/drivermain.cpp new file mode 100644 index 0000000..afa1500 --- /dev/null +++ b/MasterHide/drivermain.cpp @@ -0,0 +1,371 @@ +#include "includes.hpp" + +UNICODE_STRING g_deviceName = RTL_CONSTANT_STRING(L"\\Device\\" MASTERHIDE_GUID); +UNICODE_STRING g_symbolicLinkName = RTL_CONSTANT_STRING(L"\\DosDevices\\" MASTERHIDE_GUID); +PDEVICE_OBJECT g_deviceObject = nullptr; + +static void OnDriverUnload() +{ + // (1) De-initialize hooks + // + hooks::Deinitialize(); + + // (2) De-initialize tables and lists + // + syscalls::Deinitialize(); + callbacks::Deinitialize(); + process::rules::Deinitialize(); + process::Deinitialize(); + + // (3) Delete driver device + // + if (g_deviceObject) + { + IoDeleteDevice(g_deviceObject); + g_deviceObject = nullptr; + } + + IoDeleteSymbolicLink(&g_symbolicLinkName); + + WppTracePrint(TRACE_LEVEL_INFORMATION, GENERAL, "MasterHide successfully unloaded!"); +} + +void DriverUnload(PDRIVER_OBJECT driverObject) +{ + UNREFERENCED_PARAMETER(driverObject); + + WppTracePrint(TRACE_LEVEL_INFORMATION, GENERAL, "MasterHide is unloading"); + + OnDriverUnload(); + WPP_CLEANUP(driverObject); +} + +static NTSTATUS DispatchCreateClose(_In_ PDEVICE_OBJECT deviceObject, _Inout_ PIRP irp) +{ + UNREFERENCED_PARAMETER(deviceObject); + + irp->IoStatus.Status = STATUS_SUCCESS; + irp->IoStatus.Information = 0; + IoCompleteRequest(irp, IO_NO_INCREMENT); + return STATUS_SUCCESS; +} + +static NTSTATUS DispatchDeviceControl(_In_ PDEVICE_OBJECT deviceObject, _Inout_ PIRP irp) +{ + UNREFERENCED_PARAMETER(deviceObject); + + PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(irp); + const ULONG controlCode = irpStack->Parameters.DeviceIoControl.IoControlCode; + + NTSTATUS status = STATUS_SUCCESS; + + __try + { + switch (controlCode) + { + case IOCTL_MASTERHIDE_ADD_RULE: { + + auto processRule = static_cast(irp->AssociatedIrp.SystemBuffer); + + if (processRule->UseProcessId) + { + if (!NT_SUCCESS( + process::AddProcessEntry(UlongToHandle(processRule->ProcessId), processRule->PolicyFlags))) + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "Failed to add process entry"); + status = STATUS_UNSUCCESSFUL; + } + else + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "Successfully created rule for pid %u", + processRule->ProcessId); + } + } + else + { + if (!NT_SUCCESS( + process::rules::AddProcessRuleEntry(&processRule->ImageFileName, processRule->PolicyFlags))) + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "Failed to add process rule entry"); + status = STATUS_UNSUCCESSFUL; + } + else + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "Successfully created rule for image %wZ", + &processRule->ImageFileName); + } + } + + break; + } + case IOCTL_MASTERHIDE_UPDATE_RULE: { + + auto processRule = static_cast(irp->AssociatedIrp.SystemBuffer); + + if (processRule->UseProcessId) + { + if (!NT_SUCCESS( + process::UpdateProcessEntry(UlongToHandle(processRule->ProcessId), processRule->PolicyFlags))) + { + status = STATUS_UNSUCCESSFUL; + } + else + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "Successfully update rule for pid %u", + processRule->ProcessId); + } + } + else + { + if (!NT_SUCCESS( + process::rules::UpdateProcessRuleEntry(&processRule->ImageFileName, processRule->PolicyFlags))) + { + status = STATUS_UNSUCCESSFUL; + } + else + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "Successfully update rule for image %wZ", + &processRule->ImageFileName); + } + } + + break; + } + case IOCTL_MASTERHIDE_REMOVE_RULE: { + + auto processRule = static_cast(irp->AssociatedIrp.SystemBuffer); + + if (processRule->UseProcessId) + { + if (!NT_SUCCESS(process::RemoveProcessEntry(UlongToHandle(processRule->ProcessId)))) + { + status = STATUS_UNSUCCESSFUL; + } + else + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "Successfully removed rule for pid %u", + processRule->ProcessId); + } + } + else + { + if (!NT_SUCCESS(process::rules::RemoveProcessRuleEntry(&processRule->ImageFileName))) + { + status = STATUS_UNSUCCESSFUL; + } + else + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "Successfully removed rule for image %wZ", + &processRule->ImageFileName); + } + } + + break; + } + case IOCTL_MASTERHIDE_PROCESS_RESUME: { + + auto processId = static_cast(irp->AssociatedIrp.SystemBuffer); + + PEPROCESS process = nullptr; + if (NT_SUCCESS(PsLookupProcessByProcessId(UlongToHandle(*processId), &process))) + { + process::UpdateDelta(process); + + if (process::ResumeCounterForProcess(process) == FALSE) + { + status = STATUS_UNSUCCESSFUL; + } + + ObDereferenceObject(process); + } + else + { + status = STATUS_UNSUCCESSFUL; + } + break; + } + case IOCTL_MASTERHIDE_PROCESS_STOP: { + + auto processId = static_cast(irp->AssociatedIrp.SystemBuffer); + + PEPROCESS process = nullptr; + if (NT_SUCCESS(PsLookupProcessByProcessId(UlongToHandle(*processId), &process))) + { + process::GetBegin(process); + + if (process::StopCounterForProcess(process) == FALSE) + { + status = STATUS_UNSUCCESSFUL; + } + + ObDereferenceObject(process); + } + else + { + status = STATUS_UNSUCCESSFUL; + } + break; + } + default: + status = STATUS_INVALID_DEVICE_REQUEST; + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, "Unrecognized IOCTL request 0x%08X", status); + break; + } + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + status = GetExceptionCode(); + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "Exception in dispatch handler %!STATUS!", status); + } + + irp->IoStatus.Status = status; + irp->IoStatus.Information = 0; + IoCompleteRequest(irp, IO_NO_INCREMENT); + return status; +} + +static ULONG QueryHookType(_In_ PUNICODE_STRING registryPath) +{ + PAGED_CODE(); + NT_ASSERT(registryPath); + + ULONG hookType = HookTypeInfinityHook; + + NTSTATUS status; + + UNICODE_STRING registryPathParameters{}; + registryPathParameters.Length = 0; + registryPathParameters.MaximumLength = NTSTRSAFE_UNICODE_STRING_MAX_CCH; + registryPathParameters.Buffer = tools::AllocatePoolZero( + NonPagedPool, registryPathParameters.MaximumLength * sizeof(WCHAR), tags::TAG_STRING); + if (!registryPathParameters.Buffer) + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "Failed to allocate memory for registry path"); + return hookType; + } + + SCOPE_EXIT + { + RtlFreeUnicodeString(®istryPathParameters); + }; + + RtlCopyUnicodeString(®istryPathParameters, registryPath); + + status = RtlAppendUnicodeToString(®istryPathParameters, L"\\Parameters"); + if (!NT_SUCCESS(status)) + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "RtlAppendUnicodeToString returned %!STATUS!", status); + return hookType; + } + + RTL_QUERY_REGISTRY_TABLE query[2]{}; + query[0].Flags = RTL_QUERY_REGISTRY_DIRECT; + query[0].Name = (PWSTR)L"HookType"; + query[0].EntryContext = &hookType; + query[0].DefaultType = REG_DWORD; + query[0].DefaultData = &hookType; + query[0].DefaultLength = sizeof(ULONG); + + status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, registryPathParameters.Buffer, query, NULL, NULL); + if (!NT_SUCCESS(status)) + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "RtlQueryRegistryValues returned %!STATUS!", status); + } + + return hookType; +} + +extern "C" NTSTATUS NTAPI DriverEntry(_In_ PDRIVER_OBJECT driverObject, _In_ PUNICODE_STRING registryPath) +{ + NTSTATUS status = STATUS_UNSUCCESSFUL; + PEPROCESS winlogon = nullptr; + + WPP_INIT_TRACING(driverObject, registryPath); + WppTracePrint(TRACE_LEVEL_INFORMATION, GENERAL, "MasterHide driver is loading"); + + DBGPRINT("RegistryPath %wZ", registryPath); + + // (1) Setup driver object + // + status = IoCreateDevice(driverObject, 0, &g_deviceName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, + &g_deviceObject); + if (!NT_SUCCESS(status)) + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "IoCreateDevice returned %!STATUS!", status); + goto Exit; + } + + status = IoCreateSymbolicLink(&g_symbolicLinkName, &g_deviceName); + if (!NT_SUCCESS(status)) + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "IoCreateSymbolicLink returned %!STATUS!", status); + goto Exit; + } + + driverObject->MajorFunction[IRP_MJ_CREATE] = DispatchCreateClose; + driverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchCreateClose; + driverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchDeviceControl; + driverObject->DriverUnload = &DriverUnload; + driverObject->Flags |= DO_BUFFERED_IO; + + // Query the type of hook that should be used + // + MASTERHIDE_HOOK_TYPE = QueryHookType(registryPath); + + if (MASTERHIDE_HOOK_TYPE <= HookTypeInvalid || MASTERHIDE_HOOK_TYPE >= HookTypeMax) + { + MASTERHIDE_HOOK_TYPE = HookTypeInfinityHook; + + WppTracePrint(TRACE_LEVEL_INFORMATION, GENERAL, + "Hook type was not set or invalid, defaulting to infinityhook."); + } + + // (2) Attach to Win32K process memory space + // + winlogon = tools::GetProcessByName(L"winlogon.exe"); + if (!winlogon) + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "winlogon.exe not found!"); + goto Exit; + } + + KeAttachProcess(winlogon); + +#define INITIALIZE_INTERFACE(name) \ + status = name::Initialize(); \ + if (!NT_SUCCESS(status)) \ + { \ + DBGPRINT(#name " initialize returned 0x%08X", status); \ + goto Exit; \ + } + + // (3) Initialize all interfaces + // + INITIALIZE_INTERFACE(dyn); + INITIALIZE_INTERFACE(process); + INITIALIZE_INTERFACE(process::rules); + INITIALIZE_INTERFACE(callbacks); + INITIALIZE_INTERFACE(syscalls); + INITIALIZE_INTERFACE(hooks); + +#undef INITIALIZE_INTERFACE + + WppTracePrint(TRACE_LEVEL_INFORMATION, GENERAL, "MasterHide successfully loaded!"); + +Exit: + if (winlogon) + { + KeDetachProcess(); + ObDereferenceObject(winlogon); + } + + if (!NT_SUCCESS(status)) + { + OnDriverUnload(); + WPP_CLEANUP(driverObject); + + status = STATUS_FAILED_DRIVER_ENTRY; + } + + return status; +} \ No newline at end of file diff --git a/MasterHide/dyn.cpp b/MasterHide/dyn.cpp new file mode 100644 index 0000000..0ddcbf3 --- /dev/null +++ b/MasterHide/dyn.cpp @@ -0,0 +1,318 @@ +#include "includes.hpp" + +namespace masterhide +{ +namespace dyn +{ +DynamicContext_t DynCtx{}; + +static NTSTATUS GetOffsets() +{ + switch (KERNEL_BUILD_VERSION) + { + case WINDOWS_11_VERSION_21H2: + case WINDOWS_11_VERSION_22H2: + case WINDOWS_11_VERSION_23H2: + case WINDOWS_11_VERSION_24H2: { + DynCtx.Offsets.BypassProcessFreezeFlag = 0x74; + DynCtx.Offsets.ThreadHideFromDebuggerFlag = 0x560; + DynCtx.Offsets.ThreadBreakOnTerminationFlag = 0x560; + DynCtx.Offsets.PicoContext = 0x630; + DynCtx.Offsets.RestrictSetThreadContext = 0x460; + DynCtx.Offsets.SeAuditProcessCreationInfo = 0x5c0; + DynCtx.Offsets.SystemCallNumber = 0x80; + break; + } + case WINDOWS_10_VERSION_22H2: + case WINDOWS_10_VERSION_21H1: + case WINDOWS_10_VERSION_21H2: + case WINDOWS_10_VERSION_20H2: + case WINDOWS_10_VERSION_20H1: { + DynCtx.Offsets.BypassProcessFreezeFlag = 0x74; + DynCtx.Offsets.ThreadHideFromDebuggerFlag = 0x510; + DynCtx.Offsets.ThreadBreakOnTerminationFlag = 0x510; + DynCtx.Offsets.PicoContext = 0x5e0; + DynCtx.Offsets.RestrictSetThreadContext = 0x460; + DynCtx.Offsets.SeAuditProcessCreationInfo = 0x5c0; + DynCtx.Offsets.SystemCallNumber = 0x80; + break; + } + case WINDOWS_10_VERSION_19H2: + case WINDOWS_10_VERSION_19H1: { + DynCtx.Offsets.BypassProcessFreezeFlag = 0x74; + DynCtx.Offsets.ThreadHideFromDebuggerFlag = 0x6e0; + DynCtx.Offsets.ThreadBreakOnTerminationFlag = 0x6e0; + DynCtx.Offsets.PicoContext = 0x7a8; + DynCtx.Offsets.RestrictSetThreadContext = 0x308; + DynCtx.Offsets.SeAuditProcessCreationInfo = 0x468; + DynCtx.Offsets.SystemCallNumber = 0x80; + break; + } + case WINDOWS_10_VERSION_REDSTONE5: { + DynCtx.Offsets.BypassProcessFreezeFlag = 0; + DynCtx.Offsets.ThreadHideFromDebuggerFlag = 0x6d0; + DynCtx.Offsets.ThreadBreakOnTerminationFlag = 0x6d0; + DynCtx.Offsets.PicoContext = 0x798; + DynCtx.Offsets.RestrictSetThreadContext = 0x300; + DynCtx.Offsets.SeAuditProcessCreationInfo = 0x468; + DynCtx.Offsets.SystemCallNumber = 0x80; + break; + } + case WINDOWS_10_VERSION_REDSTONE4: { + DynCtx.Offsets.BypassProcessFreezeFlag = 0; + DynCtx.Offsets.ThreadHideFromDebuggerFlag = 0x6d0; + DynCtx.Offsets.ThreadBreakOnTerminationFlag = 0x6d0; + DynCtx.Offsets.PicoContext = 0x7a0; + DynCtx.Offsets.RestrictSetThreadContext = 0x300; + DynCtx.Offsets.SeAuditProcessCreationInfo = 0x468; + DynCtx.Offsets.SystemCallNumber = 0x80; + break; + } + case WINDOWS_10_VERSION_REDSTONE3: { + DynCtx.Offsets.BypassProcessFreezeFlag = 0; + DynCtx.Offsets.ThreadHideFromDebuggerFlag = 0x6d0; + DynCtx.Offsets.ThreadBreakOnTerminationFlag = 0x6d0; + DynCtx.Offsets.PicoContext = 0x7a0; + DynCtx.Offsets.RestrictSetThreadContext = 0x300; + DynCtx.Offsets.SeAuditProcessCreationInfo = 0x468; + DynCtx.Offsets.SystemCallNumber = 0x80; + break; + } + case WINDOWS_10_VERSION_REDSTONE2: { + DynCtx.Offsets.BypassProcessFreezeFlag = 0; + DynCtx.Offsets.ThreadHideFromDebuggerFlag = 0x6c8; + DynCtx.Offsets.ThreadBreakOnTerminationFlag = 0x6c8; + DynCtx.Offsets.PicoContext = 0x798; + DynCtx.Offsets.RestrictSetThreadContext = 0x810; + DynCtx.Offsets.SeAuditProcessCreationInfo = 0x468; + DynCtx.Offsets.SystemCallNumber = 0x80; + break; + } + case WINDOWS_10_VERSION_REDSTONE1: { + DynCtx.Offsets.BypassProcessFreezeFlag = 0; + DynCtx.Offsets.ThreadHideFromDebuggerFlag = 0x6c0; + DynCtx.Offsets.ThreadBreakOnTerminationFlag = 0x6c0; + DynCtx.Offsets.PicoContext = 0x790; + DynCtx.Offsets.RestrictSetThreadContext = 0; + DynCtx.Offsets.SeAuditProcessCreationInfo = 0x468; + DynCtx.Offsets.SystemCallNumber = 0x80; + break; + } + case WINDOWS_10_VERSION_THRESHOLD2: { + DynCtx.Offsets.BypassProcessFreezeFlag = 0; + DynCtx.Offsets.ThreadHideFromDebuggerFlag = 0x6bc; + DynCtx.Offsets.ThreadBreakOnTerminationFlag = 0x6bc; + DynCtx.Offsets.PicoContext = 0x788; + DynCtx.Offsets.RestrictSetThreadContext = 0; + DynCtx.Offsets.SeAuditProcessCreationInfo = 0x468; + DynCtx.Offsets.SystemCallNumber = 0x80; + break; + } + case WINDOWS_10_VERSION_THRESHOLD1: { + DynCtx.Offsets.BypassProcessFreezeFlag = 0; + DynCtx.Offsets.ThreadHideFromDebuggerFlag = 0x6bc; + DynCtx.Offsets.ThreadBreakOnTerminationFlag = 0x6bc; + DynCtx.Offsets.PicoContext = 0x788; + DynCtx.Offsets.RestrictSetThreadContext = 0; + DynCtx.Offsets.SeAuditProcessCreationInfo = 0x460; + DynCtx.Offsets.SystemCallNumber = 0x80; + break; + } + case WINDOWS_8_1: { + DynCtx.Offsets.BypassProcessFreezeFlag = 0; + DynCtx.Offsets.ThreadHideFromDebuggerFlag = 0x6b4; + DynCtx.Offsets.ThreadBreakOnTerminationFlag = 0x6b4; + DynCtx.Offsets.PicoContext = 0x770; + DynCtx.Offsets.RestrictSetThreadContext = 0; + DynCtx.Offsets.SeAuditProcessCreationInfo = 0x450; + DynCtx.Offsets.SystemCallNumber = 0x80; + break; + } + case WINDOWS_8: { + DynCtx.Offsets.BypassProcessFreezeFlag = 0; + DynCtx.Offsets.ThreadHideFromDebuggerFlag = 0x42c; + DynCtx.Offsets.ThreadBreakOnTerminationFlag = 0x42c; + DynCtx.Offsets.PicoContext = 0x770; + DynCtx.Offsets.RestrictSetThreadContext = 0; + DynCtx.Offsets.SeAuditProcessCreationInfo = 0x450; + DynCtx.Offsets.SystemCallNumber = 0x80; + break; + } + case WINDOWS_7_SP1: + case WINDOWS_7: { + DynCtx.Offsets.BypassProcessFreezeFlag = 0; + DynCtx.Offsets.ThreadHideFromDebuggerFlag = 0x448; + DynCtx.Offsets.ThreadBreakOnTerminationFlag = 0x448; + DynCtx.Offsets.PicoContext = 0; + DynCtx.Offsets.RestrictSetThreadContext = 0; + DynCtx.Offsets.SeAuditProcessCreationInfo = 0x390; + DynCtx.Offsets.SystemCallNumber = 0x1f8; + break; + } + default: { + return STATUS_NOT_SUPPORTED; + } + } + + return STATUS_SUCCESS; +} + +NTSTATUS Initialize() +{ + NT_ASSERT(!g_initialized); + + if (g_initialized) + { + return STATUS_ALREADY_INITIALIZED; + } + + RTL_OSVERSIONINFOW os{}; + os.dwOSVersionInfoSize = sizeof(os); + + NTSTATUS status = RtlGetVersion(&os); + if (!NT_SUCCESS(status)) + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "RtlGetVersion returned %!STATUS!", status); + + return status; + } + + PVOID ntoskrnlBase = nullptr; + ULONG ntoskrnlSize = 0; + + if (!tools::GetNtoskrnl(&ntoskrnlBase, &ntoskrnlSize)) + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "Failed to obtain ntoskrnl.exe information!"); + + return STATUS_NOT_SUPPORTED; + } + + KERNEL_BASE = ntoskrnlBase; + KERNEL_SIZE = ntoskrnlSize; + KERNEL_BUILD_MAJOR = os.dwMajorVersion; + KERNEL_BUILD_MINOR = os.dwMinorVersion; + KERNEL_BUILD_VERSION = os.dwBuildNumber; + + DBGPRINT("Windows major %d minor %d build %d", KERNEL_BUILD_MAJOR, KERNEL_BUILD_MINOR, KERNEL_BUILD_VERSION); + + if (KERNEL_BUILD_VERSION < WINDOWS_7_SP1 || KERNEL_BUILD_VERSION > WINDOWS_11_VERSION_24H2) + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "Unsupported windows version!"); + + return STATUS_NOT_SUPPORTED; + } + + if (MASTERHIDE_HOOK_TYPE == HookTypeInfinityHook) + { + if (KERNEL_BUILD_VERSION <= WINDOWS_7_SP1 || KERNEL_BUILD_VERSION >= WINDOWS_11_VERSION_21H2) + { + DynCtx.Offsets.GetCpuClock = 0x18; + } + else + { + DynCtx.Offsets.GetCpuClock = 0x28; + } + + PUCHAR EtwpDebuggerData = tools::FindPattern(KERNEL_BASE, ".rdata", "2C 08 04 38 0C"); + if (!EtwpDebuggerData) + { + EtwpDebuggerData = tools::FindPattern(KERNEL_BASE, ".data", "2C 08 04 38 0C"); + if (!EtwpDebuggerData) + { + EtwpDebuggerData = tools::FindPattern(KERNEL_BASE, ".text", "2C 08 04 38 0C"); + if (!EtwpDebuggerData) + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "EtwpDebuggerData not found!"); + return STATUS_PROCEDURE_NOT_FOUND; + } + } + } + + EtwpDebuggerData -= 2; + + if (!MmIsAddressValid(EtwpDebuggerData)) + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "Invalid EtwpDebuggerData at 0x%p", EtwpDebuggerData); + return STATUS_PROCEDURE_NOT_FOUND; + } + + DBGPRINT("EtwpDebuggerData = 0x%p", EtwpDebuggerData); + DynCtx.Kernel.EtwpDebuggerData = reinterpret_cast(EtwpDebuggerData); + + // Starting Win10 1909 a new method to achieve infinityhook is necessary + // + if (KERNEL_BUILD_VERSION > WINDOWS_10_VERSION_19H2) + { + const PUCHAR HvlpReferenceTscPage = + tools::FindPattern(KERNEL_BASE, ".text", "48 8B 05 ?? ?? ?? ?? 48 8B 40 08 48 8B 0D"); + if (!HvlpReferenceTscPage) + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "HvlpReferenceTscPage not found!"); + return STATUS_PROCEDURE_NOT_FOUND; + } + + DBGPRINT("HvlpReferenceTscPageRef = 0x%p", HvlpReferenceTscPage); + DynCtx.Kernel.HvlpReferenceTscPage = reinterpret_cast(HvlpReferenceTscPage); + + PUCHAR HvlGetQpcBias = tools::FindPattern( + KERNEL_BASE, ".text", "48 89 5C 24 08 57 48 83 EC 20 48 8B 05 ?? ?? ?? ?? 48 8B F9 48 85"); + if (!HvlGetQpcBias) + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "HvlGetQpcBias not found!"); + return STATUS_PROCEDURE_NOT_FOUND; + } + + HvlGetQpcBias += 0x22; + + DBGPRINT("HvlGetQpcBiasRef = 0x%p", HvlGetQpcBias); + DynCtx.Kernel.HvlGetQpcBias = reinterpret_cast(HvlGetQpcBias); + } + } + + if (KERNEL_BUILD_VERSION >= 14322 /*Win10 August 2016*/) + { + WppTracePrint(TRACE_LEVEL_INFORMATION, GENERAL, "Initializing debugger block to obtain PTE information"); + + auto InitializeDebuggerBlock = []() -> bool { + CONTEXT context = {0}; + context.ContextFlags = CONTEXT_FULL; + RtlCaptureContext(&context); + + auto dumpHeader = tools::AllocatePoolZero(NonPagedPool, DUMP_BLOCK_SIZE, tags::TAG_DEFAULT); + if (!dumpHeader) + { + return false; + } + + KeCapturePersistentThreadState(&context, NULL, 0, 0, 0, 0, 0, dumpHeader); + RtlCopyMemory(&DynCtx.Kernel.KdBlock, reinterpret_cast(dumpHeader) + KDDEBUGGER_DATA_OFFSET, + sizeof(DynCtx.Kernel.KdBlock)); + + ExFreePool(dumpHeader); + return true; + }; + + if (!InitializeDebuggerBlock()) + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "Failed to read debugger block!"); + + return STATUS_NOT_SUPPORTED; + } + + PteInitialize(DynCtx.Kernel.KdBlock.PteBase, *(PMMPFN *)DynCtx.Kernel.KdBlock.MmPfnDatabase); + } + + status = GetOffsets(); + if (!NT_SUCCESS(status)) + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "Failed to fill dynamic system offsets!"); + + return status; + } + + g_initialized = true; + + return STATUS_SUCCESS; +} +} // namespace dyn +} // namespace masterhide \ No newline at end of file diff --git a/MasterHide/dyn.hpp b/MasterHide/dyn.hpp new file mode 100644 index 0000000..61acd1b --- /dev/null +++ b/MasterHide/dyn.hpp @@ -0,0 +1,74 @@ +#pragma once + +#define DEFINE_DYN_CONTEXT_PROC(return_type, proc_name, var_type) \ + __forceinline return_type proc_name(var_type p) \ + { \ + return reinterpret_cast(PTR_OFFSET_ADD(p, Offsets.proc_name)); \ + } + +#define DEFINE_DYN_CONTEXT_PROC_PTR(return_type, proc_name, var_type) \ + __forceinline return_type proc_name(var_type p) \ + { \ + return *reinterpret_cast(PTR_OFFSET_ADD(p, Offsets.proc_name)); \ + } + +namespace masterhide +{ +namespace dyn +{ +#define KERNEL_BASE dyn::DynCtx.Kernel.Base +#define KERNEL_SIZE dyn::DynCtx.Kernel.Size +#define KERNEL_BUILD_VERSION dyn::DynCtx.Kernel.BuildVersion +#define KERNEL_BUILD_MAJOR dyn::DynCtx.Kernel.MajorVersion +#define KERNEL_BUILD_MINOR dyn::DynCtx.Kernel.MinorVersion +#define MASTERHIDE_HOOK_TYPE dyn::DynCtx.HookType + +// Structs +// +struct DynamicContext_t +{ + struct + { + PVOID Base; + ULONG Size; + ULONG MajorVersion; + ULONG MinorVersion; + ULONG BuildVersion; + KDDEBUGGER_DATA64 KdBlock; + ULONG_PTR EtwpDebuggerData; + ULONG_PTR HvlpReferenceTscPage; + ULONG_PTR HvlGetQpcBias; + + } Kernel; + + struct + { + ULONG GetCpuClock; // _WMI_LOGGER_CONTEXT->GetCpuClock + ULONG SeAuditProcessCreationInfo; // _EPROCESS->SeAuditProcessCreationInfo + ULONG BypassProcessFreezeFlag; // _KTHREAD->BypassProcessFreeze + ULONG ThreadHideFromDebuggerFlag; // _ETHREAD->ThreadHideFromDebugger + ULONG ThreadBreakOnTerminationFlag; // _ETHREAD->ThreadBreakOnTermination + ULONG PicoContext; // _ETHREAD->PicoContext + ULONG RestrictSetThreadContext; // _EPROCESS->RestrictSetThreadContext + ULONG SystemCallNumber; // _KTHREAD->SystemCallNumber + + } Offsets; + + int HookType; + + DEFINE_DYN_CONTEXT_PROC(PVOID *, GetCpuClock, ULONG_PTR) +}; + +extern DynamicContext_t DynCtx; + +// Globals +// +inline bool g_initialized = false; + +/// +/// Initialize dynamic context. +/// +/// STATUS_SUCCESS on success, otherwise any NTSTATUS value +NTSTATUS Initialize(); +} // namespace dyn +} // namespace masterhide \ No newline at end of file diff --git a/MasterHide/fnv1a.hpp b/MasterHide/fnv1a.hpp new file mode 100644 index 0000000..1c5713f --- /dev/null +++ b/MasterHide/fnv1a.hpp @@ -0,0 +1,35 @@ +#pragma once + +using FNV1A_t = ULONGLONG; + +namespace FNV1A +{ +constexpr FNV1A_t ullBasis = 0xCBF29CE484222325ULL; +constexpr FNV1A_t ullPrime = 0x100000001B3ULL; + +/// string for which you want to generate a hash +/// key of hash generation +/// FNV1A hash calculated at compile-time of given string +consteval FNV1A_t HashConst(const char *str, const FNV1A_t key = ullBasis) noexcept +{ + return (str[0] == '\0') ? key : HashConst(&str[1], (key ^ static_cast(str[0])) * ullPrime); +} + +/// string for which you want to generate a hash +/// key of hash generation +/// FNV1A hash calculated at run-time of given string +inline FNV1A_t Hash(const char *str, FNV1A_t key = ullBasis) noexcept +{ + const char *s; + + for (s = str; *s; ++s) + { + key ^= *s; + key *= ullPrime; + } + + return key; +} +} // namespace FNV1A + +#define FNV(s) FNV1A::HashConst(s) \ No newline at end of file diff --git a/MasterHide/globals.hpp b/MasterHide/globals.hpp deleted file mode 100644 index 55307d6..0000000 --- a/MasterHide/globals.hpp +++ /dev/null @@ -1,61 +0,0 @@ -#pragma once - -namespace masterhide -{ - namespace globals - { - // - // Custom MAC Address - // - static UCHAR szFakeMAC[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0x01, 0x2 }; - - // - // Custom HD Serial and Model - // - static char szFakeSerial[] = "XJEBA1973M2"; - - static char* szFakeModels[] = - { - "Samsung EVO 970", - //... - }; - - // - // Those drivers will not appear on drivers list - // - static char* szProtectedDrivers[] = - { - "dbk64", - "processhacker2", - //... - }; - - // - // Those processes will not appear on process list or via window methods - // - static wchar_t* wsProtectedProcesses[] = - { - L"cheatengine", - L"ProcessHacker" - //... - }; - - // - // Those processes will be monitored - // - static wchar_t* wsMonitoredProcesses[] = - { - L"Tibia", - //... - }; - - // - // Those processess will be blacklisted to query data on protect processes - // - static wchar_t* wsBlacklistedProcessess[] = - { - L"Tibia", - //... - }; - } -}; \ No newline at end of file diff --git a/MasterHide/hde/hde64.cpp b/MasterHide/hde/hde64.cpp new file mode 100644 index 0000000..d67083c --- /dev/null +++ b/MasterHide/hde/hde64.cpp @@ -0,0 +1,399 @@ +/* + * Hacker Disassembler Engine 64 C + * Copyright (c) 2008-2009, Vyacheslav Patkov. + * All rights reserved. + * + */ + +#include "..\includes.hpp" + +#if defined(_M_X64) || defined(__x86_64__) +#pragma warning(push, 0) +#pragma warning(disable : 4701 4706 26451) + +#include "hde64.h" +#include "table64.h" + +unsigned int hde64_disasm(const void *code, hde64s *hs) +{ + uint8_t x, c, *p = (uint8_t *)code, cflags, opcode, pref = 0; + uint8_t *ht = hde64_table, m_mod, m_reg, m_rm, disp_size = 0; + uint8_t op64 = 0; + + // Avoid using memset to reduce the footprint. + memset(hs, 0, sizeof(hde64s)); + + for (x = 16; x; x--) + switch (c = *p++) + { + case 0xf3: + hs->p_rep = c; + pref |= PRE_F3; + break; + case 0xf2: + hs->p_rep = c; + pref |= PRE_F2; + break; + case 0xf0: + hs->p_lock = c; + pref |= PRE_LOCK; + break; + case 0x26: + case 0x2e: + case 0x36: + case 0x3e: + case 0x64: + case 0x65: + hs->p_seg = c; + pref |= PRE_SEG; + break; + case 0x66: + hs->p_66 = c; + pref |= PRE_66; + break; + case 0x67: + hs->p_67 = c; + pref |= PRE_67; + break; + default: + goto pref_done; + } +pref_done: + + hs->flags = (uint32_t)pref << 23; + + if (!pref) + pref |= PRE_NONE; + + if ((c & 0xf0) == 0x40) + { + hs->flags |= F_PREFIX_REX; + if ((hs->rex_w = (c & 0xf) >> 3) && (*p & 0xf8) == 0xb8) + op64++; + hs->rex_r = (c & 7) >> 2; + hs->rex_x = (c & 3) >> 1; + hs->rex_b = c & 1; + if (((c = *p++) & 0xf0) == 0x40) + { + opcode = c; + goto error_opcode; + } + } + + if ((hs->opcode = c) == 0x0f) + { + hs->opcode2 = c = *p++; + ht += DELTA_OPCODES; + } + else if (c >= 0xa0 && c <= 0xa3) + { + op64++; + if (pref & PRE_67) + pref |= PRE_66; + else + pref &= ~PRE_66; + } + + opcode = c; + cflags = ht[ht[opcode / 4] + (opcode % 4)]; + + if (cflags == C_ERROR) + { + error_opcode: + hs->flags |= F_ERROR | F_ERROR_OPCODE; + cflags = 0; + if ((opcode & -3) == 0x24) + cflags++; + } + + x = 0; + if (cflags & C_GROUP) + { + uint16_t t; + t = *(uint16_t *)(ht + (cflags & 0x7f)); + cflags = (uint8_t)t; + x = (uint8_t)(t >> 8); + } + + if (hs->opcode2) + { + ht = hde64_table + DELTA_PREFIXES; + if (ht[ht[opcode / 4] + (opcode % 4)] & pref) + hs->flags |= F_ERROR | F_ERROR_OPCODE; + } + + if (cflags & C_MODRM) + { + hs->flags |= F_MODRM; + hs->modrm = c = *p++; + hs->modrm_mod = m_mod = c >> 6; + hs->modrm_rm = m_rm = c & 7; + hs->modrm_reg = m_reg = (c & 0x3f) >> 3; + + if (x && ((x << m_reg) & 0x80)) + hs->flags |= F_ERROR | F_ERROR_OPCODE; + + if (!hs->opcode2 && opcode >= 0xd9 && opcode <= 0xdf) + { + uint8_t t = opcode - 0xd9; + if (m_mod == 3) + { + ht = hde64_table + DELTA_FPU_MODRM + t * 8; + t = ht[m_reg] << m_rm; + } + else + { + ht = hde64_table + DELTA_FPU_REG; + t = ht[t] << m_reg; + } + if (t & 0x80) + hs->flags |= F_ERROR | F_ERROR_OPCODE; + } + + if (pref & PRE_LOCK) + { + if (m_mod == 3) + { + hs->flags |= F_ERROR | F_ERROR_LOCK; + } + else + { + uint8_t *table_end, op = opcode; + if (hs->opcode2) + { + ht = hde64_table + DELTA_OP2_LOCK_OK; + table_end = ht + DELTA_OP_ONLY_MEM - DELTA_OP2_LOCK_OK; + } + else + { + ht = hde64_table + DELTA_OP_LOCK_OK; + table_end = ht + DELTA_OP2_LOCK_OK - DELTA_OP_LOCK_OK; + op &= -2; + } + for (; ht != table_end; ht++) + if (*ht++ == op) + { + if (!((*ht << m_reg) & 0x80)) + goto no_lock_error; + else + break; + } + hs->flags |= F_ERROR | F_ERROR_LOCK; + no_lock_error:; + } + } + + if (hs->opcode2) + { + switch (opcode) + { + case 0x20: + case 0x22: + m_mod = 3; + if (m_reg > 4 || m_reg == 1) + goto error_operand; + else + goto no_error_operand; + case 0x21: + case 0x23: + m_mod = 3; + if (m_reg == 4 || m_reg == 5) + goto error_operand; + else + goto no_error_operand; + } + } + else + { + switch (opcode) + { + case 0x8c: + if (m_reg > 5) + goto error_operand; + else + goto no_error_operand; + case 0x8e: + if (m_reg == 1 || m_reg > 5) + goto error_operand; + else + goto no_error_operand; + } + } + + if (m_mod == 3) + { + uint8_t *table_end; + if (hs->opcode2) + { + ht = hde64_table + DELTA_OP2_ONLY_MEM; + table_end = ht + sizeof(hde64_table) - DELTA_OP2_ONLY_MEM; + } + else + { + ht = hde64_table + DELTA_OP_ONLY_MEM; + table_end = ht + DELTA_OP2_ONLY_MEM - DELTA_OP_ONLY_MEM; + } + for (; ht != table_end; ht += 2) + if (*ht++ == opcode) + { + if (*ht++ & pref && !((*ht << m_reg) & 0x80)) + goto error_operand; + else + break; + } + goto no_error_operand; + } + else if (hs->opcode2) + { + switch (opcode) + { + case 0x50: + case 0xd7: + case 0xf7: + if (pref & (PRE_NONE | PRE_66)) + goto error_operand; + break; + case 0xd6: + if (pref & (PRE_F2 | PRE_F3)) + goto error_operand; + break; + case 0xc5: + goto error_operand; + } + goto no_error_operand; + } + else + goto no_error_operand; + + error_operand: + hs->flags |= F_ERROR | F_ERROR_OPERAND; + no_error_operand: + + c = *p++; + if (m_reg <= 1) + { + if (opcode == 0xf6) + cflags |= C_IMM8; + else if (opcode == 0xf7) + cflags |= C_IMM_P66; + } + + switch (m_mod) + { + case 0: + if (pref & PRE_67) + { + if (m_rm == 6) + disp_size = 2; + } + else if (m_rm == 5) + disp_size = 4; + break; + case 1: + disp_size = 1; + break; + case 2: + disp_size = 2; + if (!(pref & PRE_67)) + disp_size <<= 1; + } + + if (m_mod != 3 && m_rm == 4) + { + hs->flags |= F_SIB; + p++; + hs->sib = c; + hs->sib_scale = c >> 6; + hs->sib_index = (c & 0x3f) >> 3; + if ((hs->sib_base = c & 7) == 5 && !(m_mod & 1)) + disp_size = 4; + } + + p--; + switch (disp_size) + { + case 1: + hs->flags |= F_DISP8; + hs->disp.disp8 = *p; + break; + case 2: + hs->flags |= F_DISP16; + hs->disp.disp16 = *(uint16_t *)p; + break; + case 4: + hs->flags |= F_DISP32; + hs->disp.disp32 = *(uint32_t *)p; + } + p += disp_size; + } + else if (pref & PRE_LOCK) + hs->flags |= F_ERROR | F_ERROR_LOCK; + + if (cflags & C_IMM_P66) + { + if (cflags & C_REL32) + { + if (pref & PRE_66) + { + hs->flags |= F_IMM16 | F_RELATIVE; + hs->imm.imm16 = *(uint16_t *)p; + p += 2; + goto disasm_done; + } + goto rel32_ok; + } + if (op64) + { + hs->flags |= F_IMM64; + hs->imm.imm64 = *(uint64_t *)p; + p += 8; + } + else if (!(pref & PRE_66)) + { + hs->flags |= F_IMM32; + hs->imm.imm32 = *(uint32_t *)p; + p += 4; + } + else + goto imm16_ok; + } + + if (cflags & C_IMM16) + { + imm16_ok: + hs->flags |= F_IMM16; + hs->imm.imm16 = *(uint16_t *)p; + p += 2; + } + if (cflags & C_IMM8) + { + hs->flags |= F_IMM8; + hs->imm.imm8 = *p++; + } + + if (cflags & C_REL32) + { + rel32_ok: + hs->flags |= F_IMM32 | F_RELATIVE; + hs->imm.imm32 = *(uint32_t *)p; + p += 4; + } + else if (cflags & C_REL8) + { + hs->flags |= F_IMM8 | F_RELATIVE; + hs->imm.imm8 = *p++; + } + +disasm_done: + + if ((hs->len = (uint8_t)(p - (uint8_t *)code)) > 15) + { + hs->flags |= F_ERROR | F_ERROR_LENGTH; + hs->len = 15; + } + + return (unsigned int)hs->len; +} + +#pragma warning(pop) +#endif // defined(_M_X64) || defined(__x86_64__) diff --git a/MasterHide/hde/hde64.h b/MasterHide/hde/hde64.h new file mode 100644 index 0000000..39f4345 --- /dev/null +++ b/MasterHide/hde/hde64.h @@ -0,0 +1,114 @@ +/* + * Hacker Disassembler Engine 64 + * Copyright (c) 2008-2009, Vyacheslav Patkov. + * All rights reserved. + * + * hde64.h: C/C++ header file + * + */ + +#ifndef _HDE64_H_ +#define _HDE64_H_ + +/* stdint.h - C99 standard header + * http://en.wikipedia.org/wiki/stdint.h + * + * if your compiler doesn't contain "stdint.h" header (for + * example, Microsoft Visual C++), you can download file: + * http://www.azillionmonkeys.com/qed/pstdint.h + * and change next line to: + * #include "pstdint.h" + */ +#include "pstdint.h" + +#define F_MODRM 0x00000001 +#define F_SIB 0x00000002 +#define F_IMM8 0x00000004 +#define F_IMM16 0x00000008 +#define F_IMM32 0x00000010 +#define F_IMM64 0x00000020 +#define F_DISP8 0x00000040 +#define F_DISP16 0x00000080 +#define F_DISP32 0x00000100 +#define F_RELATIVE 0x00000200 +#define F_ERROR 0x00001000 +#define F_ERROR_OPCODE 0x00002000 +#define F_ERROR_LENGTH 0x00004000 +#define F_ERROR_LOCK 0x00008000 +#define F_ERROR_OPERAND 0x00010000 +#define F_PREFIX_REPNZ 0x01000000 +#define F_PREFIX_REPX 0x02000000 +#define F_PREFIX_REP 0x03000000 +#define F_PREFIX_66 0x04000000 +#define F_PREFIX_67 0x08000000 +#define F_PREFIX_LOCK 0x10000000 +#define F_PREFIX_SEG 0x20000000 +#define F_PREFIX_REX 0x40000000 +#define F_PREFIX_ANY 0x7f000000 + +#define PREFIX_SEGMENT_CS 0x2e +#define PREFIX_SEGMENT_SS 0x36 +#define PREFIX_SEGMENT_DS 0x3e +#define PREFIX_SEGMENT_ES 0x26 +#define PREFIX_SEGMENT_FS 0x64 +#define PREFIX_SEGMENT_GS 0x65 +#define PREFIX_LOCK 0xf0 +#define PREFIX_REPNZ 0xf2 +#define PREFIX_REPX 0xf3 +#define PREFIX_OPERAND_SIZE 0x66 +#define PREFIX_ADDRESS_SIZE 0x67 + +#pragma pack(push, 1) + +typedef struct +{ + uint8_t len; + uint8_t p_rep; + uint8_t p_lock; + uint8_t p_seg; + uint8_t p_66; + uint8_t p_67; + uint8_t rex; + uint8_t rex_w; + uint8_t rex_r; + uint8_t rex_x; + uint8_t rex_b; + uint8_t opcode; + uint8_t opcode2; + uint8_t modrm; + uint8_t modrm_mod; + uint8_t modrm_reg; + uint8_t modrm_rm; + uint8_t sib; + uint8_t sib_scale; + uint8_t sib_index; + uint8_t sib_base; + union { + uint8_t imm8; + uint16_t imm16; + uint32_t imm32; + uint64_t imm64; + } imm; + union { + uint8_t disp8; + uint16_t disp16; + uint32_t disp32; + } disp; + uint32_t flags; +} hde64s; + +#pragma pack(pop) + +#ifdef __cplusplus +extern "C" +{ +#endif + + /* __cdecl */ + unsigned int hde64_disasm(const void *code, hde64s *hs); + +#ifdef __cplusplus +} +#endif + +#endif /* _HDE64_H_ */ diff --git a/MasterHide/hde/pstdint.h b/MasterHide/hde/pstdint.h new file mode 100644 index 0000000..365bea5 --- /dev/null +++ b/MasterHide/hde/pstdint.h @@ -0,0 +1,37 @@ +/* + * MinHook - The Minimalistic API Hooking Library for x64/x86 + * Copyright (C) 2009-2017 Tsuda Kageyu. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +// Integer types for HDE. +typedef INT8 int8_t; +typedef INT16 int16_t; +typedef INT32 int32_t; +typedef INT64 int64_t; +typedef UINT8 uint8_t; +typedef UINT16 uint16_t; +typedef UINT32 uint32_t; +typedef UINT64 uint64_t; diff --git a/MasterHide/hde/table64.h b/MasterHide/hde/table64.h new file mode 100644 index 0000000..04f016d --- /dev/null +++ b/MasterHide/hde/table64.h @@ -0,0 +1,65 @@ +/* + * Hacker Disassembler Engine 64 C + * Copyright (c) 2008-2009, Vyacheslav Patkov. + * All rights reserved. + * + */ + +#define C_NONE 0x00 +#define C_MODRM 0x01 +#define C_IMM8 0x02 +#define C_IMM16 0x04 +#define C_IMM_P66 0x10 +#define C_REL8 0x20 +#define C_REL32 0x40 +#define C_GROUP 0x80 +#define C_ERROR 0xff + +#define PRE_ANY 0x00 +#define PRE_NONE 0x01 +#define PRE_F2 0x02 +#define PRE_F3 0x04 +#define PRE_66 0x08 +#define PRE_67 0x10 +#define PRE_LOCK 0x20 +#define PRE_SEG 0x40 +#define PRE_ALL 0xff + +#define DELTA_OPCODES 0x4a +#define DELTA_FPU_REG 0xfd +#define DELTA_FPU_MODRM 0x104 +#define DELTA_PREFIXES 0x13c +#define DELTA_OP_LOCK_OK 0x1ae +#define DELTA_OP2_LOCK_OK 0x1c6 +#define DELTA_OP_ONLY_MEM 0x1d8 +#define DELTA_OP2_ONLY_MEM 0x1e7 + +unsigned char hde64_table[] = { + 0xa5, 0xaa, 0xa5, 0xb8, 0xa5, 0xaa, 0xa5, 0xaa, 0xa5, 0xb8, 0xa5, 0xb8, 0xa5, 0xb8, 0xa5, 0xb8, 0xc0, 0xc0, 0xc0, + 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xac, 0xc0, 0xcc, 0xc0, 0xa1, 0xa1, 0xa1, 0xa1, 0xb1, 0xa5, 0xa5, 0xa6, 0xc0, 0xc0, + 0xd7, 0xda, 0xe0, 0xc0, 0xe4, 0xc0, 0xea, 0xea, 0xe0, 0xe0, 0x98, 0xc8, 0xee, 0xf1, 0xa5, 0xd3, 0xa5, 0xa5, 0xa1, + 0xea, 0x9e, 0xc0, 0xc0, 0xc2, 0xc0, 0xe6, 0x03, 0x7f, 0x11, 0x7f, 0x01, 0x7f, 0x01, 0x3f, 0x01, 0x01, 0xab, 0x8b, + 0x90, 0x64, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x92, 0x5b, 0x5b, 0x76, 0x90, 0x92, 0x92, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, + 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x6a, 0x73, 0x90, 0x5b, 0x52, 0x52, 0x52, 0x52, 0x5b, 0x5b, 0x5b, 0x5b, + 0x77, 0x7c, 0x77, 0x85, 0x5b, 0x5b, 0x70, 0x5b, 0x7a, 0xaf, 0x76, 0x76, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, + 0x5b, 0x5b, 0x5b, 0x5b, 0x86, 0x01, 0x03, 0x01, 0x04, 0x03, 0xd5, 0x03, 0xd5, 0x03, 0xcc, 0x01, 0xbc, 0x03, 0xf0, + 0x03, 0x03, 0x04, 0x00, 0x50, 0x50, 0x50, 0x50, 0xff, 0x20, 0x20, 0x20, 0x20, 0x01, 0x01, 0x01, 0x01, 0xc4, 0x02, + 0x10, 0xff, 0xff, 0xff, 0x01, 0x00, 0x03, 0x11, 0xff, 0x03, 0xc4, 0xc6, 0xc8, 0x02, 0x10, 0x00, 0xff, 0xcc, 0x01, + 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x03, 0x01, 0xff, 0xff, 0xc0, 0xc2, 0x10, 0x11, 0x02, 0x03, 0x01, + 0x01, 0x01, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x10, 0x10, 0x10, 0x10, + 0x02, 0x10, 0x00, 0x00, 0xc6, 0xc8, 0x02, 0x02, 0x02, 0x02, 0x06, 0x00, 0x04, 0x00, 0x02, 0xff, 0x00, 0xc0, 0xc2, + 0x01, 0x01, 0x03, 0x03, 0x03, 0xca, 0x40, 0x00, 0x0a, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x33, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xbf, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xbf, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0xff, 0x40, 0x40, 0x40, 0x40, 0x41, 0x49, 0x40, + 0x40, 0x40, 0x40, 0x4c, 0x42, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x4f, 0x44, 0x53, 0x40, 0x40, 0x40, + 0x44, 0x57, 0x43, 0x5c, 0x40, 0x60, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x40, 0x64, 0x66, 0x6e, 0x6b, 0x40, 0x40, 0x6a, 0x46, 0x40, 0x40, 0x44, 0x46, 0x40, 0x40, 0x5b, 0x44, 0x40, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x01, 0x06, 0x06, 0x02, 0x06, 0x06, 0x00, 0x06, 0x00, 0x0a, 0x0a, + 0x00, 0x00, 0x00, 0x02, 0x07, 0x07, 0x06, 0x02, 0x0d, 0x06, 0x06, 0x06, 0x0e, 0x05, 0x05, 0x02, 0x02, 0x00, 0x00, + 0x04, 0x04, 0x04, 0x04, 0x05, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x08, 0x00, 0x10, 0x00, 0x18, + 0x00, 0x20, 0x00, 0x28, 0x00, 0x30, 0x00, 0x80, 0x01, 0x82, 0x01, 0x86, 0x00, 0xf6, 0xcf, 0xfe, 0x3f, 0xab, 0x00, + 0xb0, 0x00, 0xb1, 0x00, 0xb3, 0x00, 0xba, 0xf8, 0xbb, 0x00, 0xc0, 0x00, 0xc1, 0x00, 0xc7, 0xbf, 0x62, 0xff, 0x00, + 0x8d, 0xff, 0x00, 0xc4, 0xff, 0x00, 0xc5, 0xff, 0x00, 0xff, 0xff, 0xeb, 0x01, 0xff, 0x0e, 0x12, 0x08, 0x00, 0x13, + 0x09, 0x00, 0x16, 0x08, 0x00, 0x17, 0x09, 0x00, 0x2b, 0x09, 0x00, 0xae, 0xff, 0x07, 0xb2, 0xff, 0x00, 0xb4, 0xff, + 0x00, 0xb5, 0xff, 0x00, 0xc3, 0x01, 0x00, 0xc7, 0xff, 0xbf, 0xe7, 0x08, 0x00, 0xf0, 0x02, 0x00}; diff --git a/MasterHide/hooks.cpp b/MasterHide/hooks.cpp new file mode 100644 index 0000000..b84843c --- /dev/null +++ b/MasterHide/hooks.cpp @@ -0,0 +1,2997 @@ +#include "includes.hpp" + +namespace masterhide +{ +using namespace process; + +namespace hooks +{ +KMUTEX g_NtCloseMutex{}; +bool g_initialized = false; + +#define BACKUP_RETURNLENGTH() \ + ULONG TempReturnLength = 0; \ + if (ARGUMENT_PRESENT(ReturnLength)) \ + { \ + ProbeForWrite(ReturnLength, sizeof(ULONG), 1); \ + TempReturnLength = *ReturnLength; \ + } + +#define RESTORE_RETURNLENGTH() \ + if (ARGUMENT_PRESENT(ReturnLength)) \ + (*ReturnLength) = TempReturnLength + +HOOK_ENTRY g_HookList[] = { + // NT + // + { + "NtQuerySystemInformation", + FALSE, + &hkNtQuerySystemInformation, + }, + {"NtSetInformationThread", FALSE, &hkNtSetInformationThread}, + {"NtQueryInformationThread", FALSE, &hkNtQueryInformationThread}, + {"NtSetInformationProcess", FALSE, &hkNtSetInformationProcess}, + {"NtQueryInformationProcess", FALSE, &hkNtQueryInformationProcess}, + {"NtQueryObject", FALSE, &hkNtQueryObject}, + {"NtCreateThreadEx", FALSE, &hkNtCreateThreadEx}, + {"NtGetContextThread", FALSE, &hkNtGetContextThread}, + {"NtSetContextThread", FALSE, &hkNtSetContextThread}, + {"NtContinue", FALSE, &hkNtContinue}, + {"NtYieldExecution", FALSE, &hkNtYieldExecution}, + {"NtClose", FALSE, &hkNtClose}, + {"NtSystemDebugControl", FALSE, &hkNtSystemDebugControl}, + {"NtQuerySystemTime", FALSE, &hkNtQuerySystemTime}, + {"NtQueryPerformanceCounter", FALSE, &hkNtQueryPerformanceCounter}, + {"NtQueryInformationJobObject", FALSE, &hkNtQueryInformationJobObject}, + {"NtGetNextProcess", FALSE, &hkNtGetNextProcess}, + {"NtCreateUserProcess", FALSE, &hkNtCreateUserProcess}, + //{"NtCreateFile", FALSE, &hkNtCreateFile}, + // Win32K + // + {"NtUserWindowFromPoint", TRUE, &hkNtUserWindowFromPoint}, + {"NtUserQueryWindow", TRUE, &hkNtUserQueryWindow}, + {"NtUserFindWindowEx", TRUE, &hkNtUserFindWindowEx}, + {"NtUserBuildHwndList", TRUE, &hkNtUserBuildHwndList}, + {"NtUserGetForegroundWindow", TRUE, &hkNtUserGetForegroundWindow}, + {"NtUserGetThreadState", TRUE, nullptr}, +}; + +FORCEINLINE PHOOK_ENTRY FindHookEntry(_In_ FNV1A_t serviceNameHash) +{ + for (auto &entry : g_HookList) + { + if (serviceNameHash == FNV1A::Hash(entry.ServiceName)) + { + return &entry; + } + } + + NT_ASSERT(FALSE); + +#if !DBG + __fastfail(FAST_FAIL_INVALID_ARG); +#endif + + return nullptr; +} + +void __fastcall SsdtCallback(ULONG ServiceIndex, PVOID *ServiceAddress) +{ + for (HOOK_ENTRY &entry : g_HookList) + { + if (ServiceIndex == entry.ServiceIndex) + { + if (entry.OriginalFunc == nullptr) + { + entry.OriginalFunc = *ServiceAddress; + } + + if (entry.NewFunc) + { + *ServiceAddress = entry.NewFunc; + } + + return; + } + } +} + +[[nodiscard]] static NTSTATUS CreateHooks() +{ + PAGED_CODE(); + + for (HOOK_ENTRY &entry : g_HookList) + { + KeInitializeEvent(&entry.Event, NotificationEvent, TRUE); + entry.RefCount.SetEvent(&entry.Event); + + // Some actions has to be done based on Windows builds + // + USHORT serviceIndex = MAXUSHORT; + + if (KERNEL_BUILD_VERSION <= WINDOWS_7_SP1) + { + if (!strcmp(entry.ServiceName, "NtUserBuildHwndList")) + { + entry.NewFunc = &hkNtUserBuildHwndList_Win7; + } + } + else if (KERNEL_BUILD_VERSION >= WINDOWS_10_VERSION_20H1) + { + if (!strcmp(entry.ServiceName, "NtContinue")) + { + serviceIndex = syscalls::GetSyscallIndexByName("NtContinueEx"); + goto validateIndex; + } + } + + // NtQuerySystemTime is not exported by ntdll.dll so we have to obtain the index that way + // + if (!strcmp(entry.ServiceName, "NtQuerySystemTime")) + { + serviceIndex = syscalls::GetSyscallIndexByName("NtAccessCheckByTypeAndAuditAlarm"); + if (serviceIndex == MAXUSHORT) + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "Could not find index for service NtQuerySystemTime"); + return STATUS_PROCEDURE_NOT_FOUND; + } + serviceIndex += 1; + } + else + { + serviceIndex = syscalls::GetSyscallIndexByName(entry.ServiceName); + } + + validateIndex: + if (serviceIndex == MAXUSHORT) + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "Could not find index for service %s", entry.ServiceName); + return STATUS_PROCEDURE_NOT_FOUND; + } + + entry.ServiceIndex = serviceIndex; + + if (MASTERHIDE_HOOK_TYPE == HookTypeKasperskyHook) + { + if (entry.Win32k) + { + if (!kaspersky::hook_shadow_ssdt_routine(entry.ServiceIndex, entry.NewFunc, + reinterpret_cast(&entry.OriginalFunc))) + { + return STATUS_UNSUCCESSFUL; + } + } + else + { + if (!kaspersky::hook_ssdt_routine(entry.ServiceIndex, entry.NewFunc, + reinterpret_cast(&entry.OriginalFunc))) + { + return STATUS_UNSUCCESSFUL; + } + } + } + else if (MASTERHIDE_HOOK_TYPE == HookTypeInfinityHook) + { + // Nothing has to be done, relevant action is already done at SsdtCallback + } + + DBGPRINT("Created hook for service %s at index %u", entry.ServiceName, entry.ServiceIndex); + } + return STATUS_SUCCESS; +} + +static NTSTATUS UninstallHooks() +{ + PAGED_CODE(); + + if (MASTERHIDE_HOOK_TYPE == HookTypeInfinityHook) + { + DeinitializeInfinityHook(); + } + + for (HOOK_ENTRY &entry : g_HookList) + { + if (MASTERHIDE_HOOK_TYPE == HookTypeKasperskyHook) + { + if (entry.Win32k) + { + if (!kaspersky::unhook_shadow_ssdt_routine(entry.ServiceIndex, entry.OriginalFunc)) + { + return STATUS_UNSUCCESSFUL; + } + } + else + { + if (!kaspersky::unhook_ssdt_routine(entry.ServiceIndex, entry.OriginalFunc)) + { + return STATUS_UNSUCCESSFUL; + } + } + } + + DBGPRINT("Waiting for references in %s", entry.ServiceName); + + const NTSTATUS status = entry.RefCount.Wait(); + if (!NT_SUCCESS(status)) + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "Could not wait for hook %s reference count %!STATUS!", + entry.ServiceName, status); + return status; + } + + entry.OriginalFunc = nullptr; + } + + return STATUS_SUCCESS; +} + +NTSTATUS Initialize() +{ + PAGED_CODE(); + NT_ASSERT(!g_initialized); + + if (g_initialized) + { + return STATUS_ALREADY_INITIALIZED; + } + + NTSTATUS status = STATUS_SUCCESS; + + KeInitializeMutex(&g_NtCloseMutex, 0); + + if (MASTERHIDE_HOOK_TYPE == HookTypeKasperskyHook) + { + DBGPRINT("Using kaspersky hook."); + + if (!::utils::init()) + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "Failed to initialize utils!"); + return STATUS_UNSUCCESSFUL; + } + + if (!kaspersky::is_klhk_loaded() || !kaspersky::initialize()) + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "Failed to load kaspersky!"); + return STATUS_UNSUCCESSFUL; + } + + status = kaspersky::hvm_init(); + if (!NT_SUCCESS(status)) + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "hvm_init returned %!STATUS!", status); + return STATUS_UNSUCCESSFUL; + } + + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, "Kaspersky hypervisor is set up!"); + } + else if (MASTERHIDE_HOOK_TYPE == HookTypeInfinityHook) + { + status = InitializeInfinityHook(&SsdtCallback); + if (!NT_SUCCESS(status)) + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "InitializeInfinityHook returned %!STATUS!", status); + return STATUS_UNSUCCESSFUL; + } + } + + status = CreateHooks(); + if (!NT_SUCCESS(status)) + { + if (MASTERHIDE_HOOK_TYPE == HookTypeInfinityHook) + { + DeinitializeInfinityHook(); + } + + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "CreateHooks returned %!STATUS!", status); + return STATUS_UNSUCCESSFUL; + } + + g_initialized = true; + + return status; +} + +void Deinitialize() +{ + PAGED_CODE(); + + if (!g_initialized) + { + return; + } + + const NTSTATUS status = UninstallHooks(); + if (!NT_SUCCESS(status)) + { + WppTracePrint(TRACE_LEVEL_WARNING, GENERAL, + "UninstallHooks returned %!STATUS!, one of more hooks where not successfully unninstalled!", + status); + } + + g_initialized = false; + + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, "Successfully de-initialized hooks interface!"); + return; +} + +NTSTATUS NTAPI hkNtQuerySystemTime(PLARGE_INTEGER SystemTime) +{ + PAGED_CODE(); + + const PHOOK_ENTRY hookEntry = FindHookEntry(FNV("NtQuerySystemTime")); + const ScopedReferenceGuard lock(&hookEntry->RefCount); + + const KPROCESSOR_MODE previousMode = ExGetPreviousMode(); + if (previousMode == UserMode) + { + const HANDLE currentProcessId = PsGetCurrentProcessId(); + PPROCESS_ENTRY processEntry = GetProcessEntry(currentProcessId); + + SCOPE_EXIT + { + if (processEntry) + { + object::DereferenceObject(processEntry); + processEntry = nullptr; + } + }; + + // If (1) it's a ruled process and (2) current hook is meant to be intercepted + // + if (processEntry && BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagNtQuerySystemTime)) + { + NTSTATUS status = STATUS_SUCCESS; + bool handled = false; + + if (BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagHideFromDebugger)) + { + __try + { + ProbeForWrite(SystemTime, sizeof(ULONG64), 4); + + if (BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagHideKUserSharedData)) + { + SystemTime->QuadPart = *(ULONG64 *)&processEntry->Kusd.KuserSharedData->SystemTime; + } + else + { + if (processEntry->FakeSystemTime.QuadPart == NULL) + { + KeQuerySystemTime(&processEntry->FakeSystemTime); + } + + SystemTime->QuadPart = processEntry->FakeSystemTime.QuadPart; + processEntry->FakeSystemTime.QuadPart += 1; + } + + status = STATUS_SUCCESS; + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + status = GetExceptionCode(); + } + + handled = true; + } + + if (!handled) + { + status = reinterpret_cast(hookEntry->OriginalFunc)(SystemTime); + } + + if (BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagMonitored)) + { + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, "NtQuerySystemTime from pid %u returned %!STATUS!\n", + HandleToUlong(PsGetCurrentProcessId()), status); + } + + return status; + } + } + return reinterpret_cast(hookEntry->OriginalFunc)(SystemTime); +} + +NTSTATUS NTAPI hkNtQueryPerformanceCounter(PLARGE_INTEGER PerformanceCounter, PLARGE_INTEGER PerformanceFrequency) +{ + PAGED_CODE(); + + const PHOOK_ENTRY hookEntry = FindHookEntry(FNV("NtQueryPerformanceCounter")); + const ScopedReferenceGuard lock(&hookEntry->RefCount); + + const KPROCESSOR_MODE previousMode = ExGetPreviousMode(); + if (previousMode == UserMode) + { + const HANDLE currentProcessId = PsGetCurrentProcessId(); + PPROCESS_ENTRY processEntry = GetProcessEntry(currentProcessId); + + SCOPE_EXIT + { + if (processEntry) + { + object::DereferenceObject(processEntry); + processEntry = nullptr; + } + }; + + // If (1) it's a ruled process and (2) current hook is meant to be intercepted + // + if (processEntry && BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagNtQueryPerformanceCounter)) + { + NTSTATUS status = STATUS_SUCCESS; + bool handled = false; + + if (BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagHideFromDebugger)) + { + __try + { + ProbeForWrite(PerformanceCounter, sizeof(ULONG64), 4); + + if (PerformanceFrequency != NULL) + { + ProbeForWrite(PerformanceFrequency, sizeof(ULONG64), 4); + } + + if (BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagHideKUserSharedData)) + { + PerformanceCounter->QuadPart = processEntry->Kusd.KuserSharedData->BaselineSystemTimeQpc; + } + else + { + if (processEntry->FakePerformanceCounter.QuadPart == NULL) + { + processEntry->FakePerformanceCounter = KeQueryPerformanceCounter(NULL); + } + + PerformanceCounter->QuadPart = processEntry->FakePerformanceCounter.QuadPart; + processEntry->FakePerformanceCounter.QuadPart += 1; + } + + if (PerformanceFrequency != NULL) + { + PerformanceFrequency->QuadPart = KuserSharedData->QpcFrequency; + } + + status = STATUS_SUCCESS; + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + status = GetExceptionCode(); + } + + handled = true; + } + + if (!handled) + { + status = reinterpret_cast(hookEntry->OriginalFunc)( + PerformanceCounter, PerformanceFrequency); + } + + if (BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagMonitored)) + { + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, + "NtQueryPerformanceCounter from pid %u returned %!STATUS!\n", + HandleToUlong(PsGetCurrentProcessId()), status); + } + + return status; + } + } + return reinterpret_cast(hookEntry->OriginalFunc)(PerformanceCounter, + PerformanceFrequency); +} + +NTSTATUS NTAPI hkNtSystemDebugControl(SYSDBG_COMMAND Command, PVOID InputBuffer, ULONG InputBufferLength, + PVOID OutputBuffer, ULONG OutputBufferLength, PULONG ReturnLength) +{ + PAGED_CODE(); + + const PHOOK_ENTRY hookEntry = FindHookEntry(FNV("NtSystemDebugControl")); + const ScopedReferenceGuard lock(&hookEntry->RefCount); + + const KPROCESSOR_MODE previousMode = ExGetPreviousMode(); + if (previousMode == UserMode) + { + const HANDLE currentProcessId = PsGetCurrentProcessId(); + PPROCESS_ENTRY processEntry = GetProcessEntry(currentProcessId); + + SCOPE_EXIT + { + if (processEntry) + { + object::DereferenceObject(processEntry); + processEntry = nullptr; + } + }; + + // If (1) it's a ruled process and (2) current hook is meant to be intercepted + // + if (processEntry && BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagNtSystemDebugControl)) + { + NTSTATUS status = STATUS_SUCCESS; + bool handled = false; + + if (BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagHideFromDebugger)) + { + if (Command != SysDbgGetTriageDump && Command != SysDbgGetLiveKernelDump) + { + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, + "Spoofed NtSystemDebugControl(commad:%d) anti-debug query!", Command); + + status = STATUS_DEBUGGER_INACTIVE; + handled = true; + } + } + + if (!handled) + { + status = reinterpret_cast(hookEntry->OriginalFunc)( + Command, InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength, ReturnLength); + } + + if (BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagMonitored)) + { + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, + "NtSystemDebugControl from pid %u Command %u returned %!STATUS!\n", + HandleToUlong(PsGetCurrentProcessId()), Command, status); + } + + return status; + } + } + return reinterpret_cast(hookEntry->OriginalFunc)( + Command, InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength, ReturnLength); +} + +NTSTATUS NTAPI hkNtClose(HANDLE Handle) +{ + PAGED_CODE(); + + const PHOOK_ENTRY hookEntry = FindHookEntry(FNV("NtClose")); + const ScopedReferenceGuard lock(&hookEntry->RefCount); + + const KPROCESSOR_MODE previousMode = ExGetPreviousMode(); + if (previousMode == UserMode) + { + const HANDLE currentProcessId = PsGetCurrentProcessId(); + PPROCESS_ENTRY processEntry = GetProcessEntry(currentProcessId); + + SCOPE_EXIT + { + if (processEntry) + { + object::DereferenceObject(processEntry); + processEntry = nullptr; + } + }; + + // If (1) it's a ruled process and (2) current hook is meant to be intercepted + // + if (processEntry && BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagNtClose)) + { + NTSTATUS status = STATUS_SUCCESS; + bool handled = false; + + if (BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagHideFromDebugger)) + { + // If two or more threads were to simultaneously check and act on this information without + // synchronization, it might lead to inconsistent states where a handle that is meant to be + // protected gets closed, or an exception is raised improperly. + KeWaitForSingleObject(&g_NtCloseMutex, Executive, KernelMode, FALSE, nullptr); + + OBJECT_HANDLE_ATTRIBUTE_INFORMATION handleAttribInfo{}; + + status = + reinterpret_cast(FindHookEntry(FNV("NtQueryObject"))->OriginalFunc)( + Handle, static_cast(ObjectDataInformation), &handleAttribInfo, + sizeof(OBJECT_HANDLE_ATTRIBUTE_INFORMATION), nullptr); + + if (status == STATUS_INVALID_HANDLE) + { + KeReleaseMutex(&g_NtCloseMutex, FALSE); + + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, "Spoofed NtClose(Invalid Handle) anti-debug query!"); + + if (processEntry->Flags.ProcessHandleTracingEnabled) + { + return KeRaiseUserException(STATUS_INVALID_HANDLE); + } + + status = STATUS_INVALID_HANDLE; + handled = true; + } + + if (NT_SUCCESS(status)) + { + if (handleAttribInfo.ProtectFromClose == TRUE) + { + KeReleaseMutex(&g_NtCloseMutex, FALSE); + + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, + "Spoofed NtClose(ProtectFromClose) anti-debug query!"); + + if (processEntry->Flags.ProcessHandleTracingEnabled) + { + return KeRaiseUserException(STATUS_HANDLE_NOT_CLOSABLE); + } + + status = STATUS_HANDLE_NOT_CLOSABLE; + handled = true; + } + } + + KeReleaseMutex(&g_NtCloseMutex, FALSE); + } + + if (!handled) + { + status = reinterpret_cast(hookEntry->OriginalFunc)(Handle); + } + + if (BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagMonitored)) + { + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, "NtClose from pid %ureturned %!STATUS!\n", + HandleToUlong(PsGetCurrentProcessId()), status); + } + + return status; + } + } + return reinterpret_cast(hookEntry->OriginalFunc)(Handle); +} + +NTSTATUS NTAPI hkNtYieldExecution() +{ + PAGED_CODE(); + + const PHOOK_ENTRY hookEntry = FindHookEntry(FNV("NtYieldExecution")); + const ScopedReferenceGuard lock(&hookEntry->RefCount); + + const KPROCESSOR_MODE previousMode = ExGetPreviousMode(); + if (previousMode == UserMode) + { + const HANDLE currentProcessId = PsGetCurrentProcessId(); + PPROCESS_ENTRY processEntry = GetProcessEntry(currentProcessId); + + SCOPE_EXIT + { + if (processEntry) + { + object::DereferenceObject(processEntry); + processEntry = nullptr; + } + }; + + // If (1) it's a ruled process and (2) current hook is meant to be intercepted + // + if (processEntry && BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagNtYieldExecution)) + { + NTSTATUS status = STATUS_SUCCESS; + bool handled = false; + + if (BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagHideFromDebugger)) + { + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, "Spoofed NtYieldExecution anti-debug query!"); + + reinterpret_cast(hookEntry->OriginalFunc)(); + status = STATUS_SUCCESS; + handled = true; + } + + if (!handled) + { + status = reinterpret_cast(hookEntry->OriginalFunc)(); + } + + if (BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagMonitored)) + { + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, "NtYieldExecution from pid %ureturned %!STATUS!\n", + HandleToUlong(PsGetCurrentProcessId()), status); + } + } + } + return reinterpret_cast(hookEntry->OriginalFunc)(); +} + +NTSTATUS NTAPI hkNtContinue(PCONTEXT Context, ULONG64 TestAlert) +{ + PAGED_CODE(); + + const PHOOK_ENTRY hookEntry = FindHookEntry(FNV("NtContinue")); + const ScopedReferenceGuard lock(&hookEntry->RefCount); + + const KPROCESSOR_MODE previousMode = ExGetPreviousMode(); + if (previousMode == UserMode) + { + const HANDLE currentProcessId = PsGetCurrentProcessId(); + PPROCESS_ENTRY processEntry = GetProcessEntry(currentProcessId); + + SCOPE_EXIT + { + if (processEntry) + { + object::DereferenceObject(processEntry); + processEntry = nullptr; + } + }; + + // If (1) it's a ruled process and (2) current hook is meant to be intercepted + // + if (processEntry && BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagNtContinue)) + { + NTSTATUS status = STATUS_SUCCESS; + bool handled = false; + + if (BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagHideFromDebugger)) + { + __try + { + ProbeForRead(Context, sizeof(*Context), __alignof(_CONTEXT)); + + PTHREAD_ENTRY threadEntry = processEntry->AppendThreadList(PsGetCurrentThread()); + + if ((Context->Dr0 != __readdr(0) && Context->Dr1 != __readdr(1) && Context->Dr2 != __readdr(2) && + Context->Dr3 != __readdr(3) && Context->ContextFlags & 0x10 && threadEntry)) + { + RtlCopyMemory(&threadEntry->SavedDebugContext.Dr0, &Context->Dr0, sizeof(ULONG64) * 6); + RtlCopyMemory(&threadEntry->SavedDebugContext.DebugControl, &Context->DebugControl, + sizeof(ULONG64) * 5); + } + + Context->ContextFlags &= ~0x10; + + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, "Spoofed NtContinue anti-debug query!"); + + status = reinterpret_cast(hookEntry->OriginalFunc)(Context, TestAlert); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + status = GetExceptionCode(); + } + + handled = true; + } + + if (!handled) + { + status = reinterpret_cast(hookEntry->OriginalFunc)(Context, TestAlert); + } + + if (BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagMonitored)) + { + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, "NtContinue from pid %u returned %!STATUS!\n", + HandleToUlong(PsGetCurrentProcessId()), status); + } + + return status; + } + } + return reinterpret_cast(hookEntry->OriginalFunc)(Context, TestAlert); +} + +NTSTATUS NTAPI hkNtGetNextProcess(HANDLE ProcessHandle, ACCESS_MASK DesiredAccess, ULONG HandleAttributes, ULONG Flags, + PHANDLE NewProcessHandle) +{ + const PHOOK_ENTRY hookEntry = FindHookEntry(FNV("NtGetNextProcess")); + const ScopedReferenceGuard lock(&hookEntry->RefCount); + + NTSTATUS status = reinterpret_cast(hookEntry->OriginalFunc)( + ProcessHandle, DesiredAccess, HandleAttributes, Flags, NewProcessHandle); + + const KPROCESSOR_MODE previousMode = ExGetPreviousMode(); + if (previousMode == UserMode) + { + const HANDLE currentProcessId = PsGetCurrentProcessId(); + PPROCESS_ENTRY processEntry = GetProcessEntry(currentProcessId); + + SCOPE_EXIT + { + if (processEntry) + { + object::DereferenceObject(processEntry); + processEntry = nullptr; + } + }; + + // If (1) it's a ruled process and (2) current hook is meant to be intercepted + // + if (processEntry && BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagNtGetNextProcess)) + { + __try + { + // No probe is required in this context, we already check if function return successful status. + // + if (NT_SUCCESS(status) && BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagHideFromDebugger)) + { + PEPROCESS process = nullptr; + if (NT_SUCCESS(ObReferenceObjectByHandle(*NewProcessHandle, PROCESS_QUERY_LIMITED_INFORMATION, + *PsProcessType, previousMode, + reinterpret_cast(&process), nullptr))) + { + if (IsProtectedProcess(process)) + { + HANDLE oldHandleValue = *NewProcessHandle; + + status = reinterpret_cast(hookEntry->OriginalFunc)( + *NewProcessHandle, DesiredAccess, HandleAttributes, Flags, NewProcessHandle); + + ObCloseHandle(oldHandleValue, UserMode); + } + + ObDereferenceObject(process); + } + } + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + status = GetExceptionCode(); + } + + if (BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagMonitored)) + { + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, "NtGetNextProcess from pid %u returned %!STATUS!\n", + HandleToUlong(PsGetCurrentProcessId()), status); + } + } + } + return status; +} + +NTSTATUS NTAPI hkNtSetInformationThread(HANDLE ThreadHandle, THREADINFOCLASS ThreadInformationClass, + PVOID ThreadInformation, ULONG ThreadInformationLength) +{ + PAGED_CODE(); + + const PHOOK_ENTRY hookEntry = FindHookEntry(FNV("NtSetInformationThread")); + const ScopedReferenceGuard lock(&hookEntry->RefCount); + + const KPROCESSOR_MODE previousMode = ExGetPreviousMode(); + if (previousMode == UserMode) + { + const HANDLE currentProcessId = PsGetCurrentProcessId(); + PPROCESS_ENTRY processEntry = GetProcessEntry(currentProcessId); + + SCOPE_EXIT + { + if (processEntry) + { + object::DereferenceObject(processEntry); + processEntry = nullptr; + } + }; + + // If (1) it's a blacklisted process and (2) current hook is meant to be intercepted + // + if (processEntry && BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagNtSetInformationThread)) + { + NTSTATUS status = STATUS_SUCCESS; + bool handled = false; + + if (BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagHideFromDebugger) && + (ThreadInformationClass == ThreadHideFromDebugger || ThreadInformationClass == ThreadWow64Context || + ThreadInformationClass == ThreadBreakOnTermination)) + { + __try + { + if (ThreadInformationLength != 0) + { + ProbeForRead(ThreadInformation, ThreadInformationLength, TYPE_ALIGNMENT(ULONG)); + } + + PETHREAD thread = nullptr; + + if (ThreadHandle == ZwCurrentThread()) + { + thread = PsGetCurrentThread(); + } + else + { + status = ObReferenceObjectByHandle(ThreadHandle, THREAD_QUERY_INFORMATION, *PsThreadType, + previousMode, reinterpret_cast(&thread), nullptr); + if (!NT_SUCCESS(status)) + { + goto Exit; + } + + SCOPE_EXIT + { + ObDereferenceObject(thread); + }; + } + + PPROCESS_ENTRY threadProcessEntry = GetProcessEntry(PsGetThreadProcessId(thread)); + + SCOPE_EXIT + { + if (threadProcessEntry) + { + object::DereferenceObject(threadProcessEntry); + threadProcessEntry = nullptr; + } + }; + + if (threadProcessEntry && + BooleanFlagOn(threadProcessEntry->PolicyFlags, ProcessPolicyFlagNtSetInformationThread)) + { + if (BooleanFlagOn(threadProcessEntry->PolicyFlags, ProcessPolicyFlagHideFromDebugger)) + { + if (ThreadInformationClass == ThreadHideFromDebugger) + { + if (ThreadInformationLength != 0) + { + status = STATUS_INFO_LENGTH_MISMATCH; + goto Exit; + } + + PTHREAD_ENTRY threadEntry = threadProcessEntry->AppendThreadList(thread); + if (threadEntry) + { + threadEntry->Flags.IsThreadHidden = TRUE; + + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, + "Spoofed NtSetInformationThread(ThreadHideFromDebugger) tid:%d", + HandleToUlong(PsGetThreadId(threadEntry->Thread))); + } + + status = STATUS_SUCCESS; + handled = true; + } + else if (ThreadInformationClass == ThreadWow64Context) + { + if (ThreadInformationLength != sizeof(WOW64_CONTEXT)) + { + status = STATUS_INFO_LENGTH_MISMATCH; + goto Exit; + } + + PVOID WoW64Process = PsGetCurrentProcessWow64Process(); + if (!WoW64Process) + { + status = STATUS_INVALID_PARAMETER; + goto Exit; + } + + auto Wow64Context = static_cast(ThreadInformation); + ULONG OriginalFlags = Wow64Context->ContextFlags; + + Wow64Context->ContextFlags &= ~0x10; + + status = reinterpret_cast(hookEntry->OriginalFunc)( + ThreadHandle, ThreadInformationClass, ThreadInformation, ThreadInformationLength); + + if (OriginalFlags & 0x10) + { + Wow64Context->ContextFlags |= 0x10; + + PTHREAD_ENTRY threadEntry = threadProcessEntry->AppendThreadList(thread); + if (threadEntry) + { + RtlCopyMemory(&threadEntry->SavedWow64DebugContext, &Wow64Context->Dr0, + sizeof(ULONG) * 6); + + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, + "Spoofed NtSetInformationThread(ThreadWow64Context) tid:%d", + HandleToUlong(PsGetThreadId(threadEntry->Thread))); + } + } + + handled = true; + } + else if (ThreadInformationClass == ThreadBreakOnTermination) + { + if (ThreadInformationLength != sizeof(ULONG)) + { + status = STATUS_INFO_LENGTH_MISMATCH; + goto Exit; + } + + volatile ULONG Touch = *(ULONG *)ThreadInformation; + UNREFERENCED_PARAMETER(Touch); + + // Caller process needs debug privileges + // + if (!tools::HasDebugPrivilege()) + { + status = STATUS_PRIVILEGE_NOT_HELD; + goto Exit; + } + + PTHREAD_ENTRY threadEntry = threadProcessEntry->AppendThreadList(thread); + if (threadEntry) + { + threadEntry->Flags.BreakOnTermination = *(ULONG *)ThreadInformation ? TRUE : FALSE; + + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, + "Spoofed NtSetInformationThread(ThreadBreakOnTermination) tid:%d", + HandleToUlong(PsGetThreadId(threadEntry->Thread))); + } + + status = STATUS_SUCCESS; + handled = true; + } + } + } + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + status = GetExceptionCode(); + handled = true; + } + } + + if (!handled) + { + status = reinterpret_cast(hookEntry->OriginalFunc)( + ThreadHandle, ThreadInformationClass, ThreadInformation, ThreadInformationLength); + } + + Exit: + if (BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagMonitored)) + { + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, + "NtSetInformationThread from pid %u ThreadHandle = 0x%p ThreadInformationClass %d " + "returned %!STATUS!\n", + HandleToUlong(PsGetCurrentProcessId()), ThreadHandle, ThreadInformationClass, status); + } + return status; + } + } + return reinterpret_cast(hookEntry->OriginalFunc)( + ThreadHandle, ThreadInformationClass, ThreadInformation, ThreadInformationLength); +} + +NTSTATUS NTAPI hkNtQueryInformationThread(HANDLE ThreadHandle, THREADINFOCLASS ThreadInformationClass, + PVOID ThreadInformation, ULONG ThreadInformationLength, PULONG ReturnLength) +{ + PAGED_CODE(); + + const PHOOK_ENTRY hookEntry = FindHookEntry(FNV("NtQueryInformationThread")); + const ScopedReferenceGuard lock(&hookEntry->RefCount); + + const KPROCESSOR_MODE previousMode = ExGetPreviousMode(); + if (previousMode == UserMode) + { + const HANDLE currentProcessId = PsGetCurrentProcessId(); + PPROCESS_ENTRY processEntry = GetProcessEntry(currentProcessId); + + SCOPE_EXIT + { + if (processEntry) + { + object::DereferenceObject(processEntry); + processEntry = nullptr; + } + }; + + // If (1) it's a blacklisted process and (2) current hook is meant to be intercepted + // + if (processEntry && BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagNtQueryInformationThread)) + { + if (BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagHideFromDebugger) && ThreadInformation && + (ThreadInformationClass == ThreadHideFromDebugger || + ThreadInformationClass == ThreadBreakOnTermination || ThreadInformationClass == ThreadWow64Context)) + { + NTSTATUS status = STATUS_SUCCESS; + bool handled = false; + + __try + { + const ULONG alignment = ThreadInformationLength < 4 ? 1 : 4; + + if (ThreadInformationLength != 0) + { + ProbeForWrite(ThreadInformation, ThreadInformationLength, alignment); + } + + if (ARGUMENT_PRESENT(ReturnLength)) + { + ProbeForWrite(ReturnLength, sizeof(*ReturnLength), 1); + } + + PETHREAD thread = nullptr; + + if (ThreadHandle == ZwCurrentThread()) + { + thread = PsGetCurrentThread(); + } + else + { + status = ObReferenceObjectByHandle(ThreadHandle, THREAD_QUERY_INFORMATION, *PsThreadType, + previousMode, reinterpret_cast(&thread), nullptr); + if (!NT_SUCCESS(status)) + { + goto Exit; + } + + SCOPE_EXIT + { + ObDereferenceObject(thread); + }; + } + + PPROCESS_ENTRY threadProcessEntry = GetProcessEntry(PsGetThreadProcessId(thread)); + + SCOPE_EXIT + { + if (threadProcessEntry) + { + object::DereferenceObject(threadProcessEntry); + threadProcessEntry = nullptr; + } + }; + + // If (1) it's a blacklisted process and (2) current hook is meant to be intercepted + // + if (threadProcessEntry && + BooleanFlagOn(threadProcessEntry->PolicyFlags, ProcessPolicyFlagNtQueryInformationThread)) + { + if (BooleanFlagOn(threadProcessEntry->PolicyFlags, ProcessPolicyFlagHideFromDebugger)) + { + PTHREAD_ENTRY threadEntry = threadProcessEntry->AppendThreadList(thread); + if (threadEntry) + { + if (ThreadInformationClass == ThreadHideFromDebugger) + { + if (ThreadInformationLength != 1) + { + status = STATUS_INFO_LENGTH_MISMATCH; + goto Exit; + } + + *(BOOLEAN *)ThreadInformation = threadEntry->Flags.IsThreadHidden; + + if (ReturnLength != 0) + { + *ReturnLength = 1; + } + + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, + "Spoofed NtQueryInformationThread(ThreadHideFromDebugger) tid:%d", + HandleToUlong(PsGetThreadId(threadEntry->Thread))); + + status = STATUS_SUCCESS; + handled = true; + } + else if (ThreadInformationClass == ThreadBreakOnTermination) + { + if (ThreadInformationLength != 4) + { + status = STATUS_INFO_LENGTH_MISMATCH; + goto Exit; + } + + *(ULONG *)ThreadInformation = threadEntry->Flags.BreakOnTermination; + + if (ReturnLength != NULL) + { + *ReturnLength = 4; + } + + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, + "Spoofed NtQueryInformationThread(ThreadBreakOnTermination) tid:%d", + HandleToUlong(PsGetThreadId(threadEntry->Thread))); + + status = STATUS_SUCCESS; + handled = true; + } + else if (ThreadInformationClass == ThreadWow64Context) + { + if (ThreadInformationLength != sizeof(WOW64_CONTEXT)) + { + status = STATUS_INFO_LENGTH_MISMATCH; + goto Exit; + } + + PWOW64_CONTEXT Context = PWOW64_CONTEXT(ThreadInformation); + ULONG OriginalFlags = Context->ContextFlags; + + Context->ContextFlags &= ~0x10; + + status = reinterpret_cast( + hookEntry->OriginalFunc)(ThreadHandle, ThreadInformationClass, + ThreadInformation, ThreadInformationLength, + ReturnLength); + + if (NT_SUCCESS(status) && OriginalFlags & 0x10) + { + Context->ContextFlags |= 0x10; + + RtlCopyMemory(&Context->Dr0, &threadEntry->SavedWow64DebugContext, + sizeof(ULONG) * 6); + + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, + "Spoofed NtQueryInformationThread(ThreadWow64Context) tid:%d", + HandleToUlong(PsGetThreadId(threadEntry->Thread))); + } + + handled = true; + } + } + } + } + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + status = GetExceptionCode(); + handled = true; + } + + if (!handled) + { + status = reinterpret_cast(hookEntry->OriginalFunc)( + ThreadHandle, ThreadInformationClass, ThreadInformation, ThreadInformationLength, ReturnLength); + } + + Exit: + if (BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagMonitored)) + { + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, + "NtQueryInformationThread from pid %u ThreadHandle = 0x%p ThreadInformationClass %d " + "returned %!STATUS!\n", + HandleToUlong(PsGetCurrentProcessId()), ThreadHandle, ThreadInformationClass, status); + } + + return status; + } + } + } + return reinterpret_cast(hookEntry->OriginalFunc)( + ThreadHandle, ThreadInformationClass, ThreadInformation, ThreadInformationLength, ReturnLength); +} + +NTSTATUS NTAPI hkNtQueryInformationProcess(HANDLE ProcessHandle, PROCESSINFOCLASS ProcessInformationClass, + PVOID ProcessInformation, ULONG ProcessInformationLength, + PULONG ReturnLength) +{ + PAGED_CODE(); + + const PHOOK_ENTRY hookEntry = FindHookEntry(FNV("NtQueryInformationProcess")); + const ScopedReferenceGuard lock(&hookEntry->RefCount); + + const KPROCESSOR_MODE previousMode = ExGetPreviousMode(); + if (previousMode == UserMode) + { + const HANDLE currentProcessId = PsGetCurrentProcessId(); + PPROCESS_ENTRY processEntry = GetProcessEntry(currentProcessId); + + SCOPE_EXIT + { + if (processEntry) + { + object::DereferenceObject(processEntry); + processEntry = nullptr; + } + }; + + // (1) check if the process is blacklisted (2) check if hook is meant to be intercepted + // + if (processEntry && BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagNtQueryInformationProcess)) + { + if (BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagHideFromDebugger) && + (ProcessInformationClass == ProcessDebugObjectHandle || ProcessInformationClass == ProcessDebugPort || + ProcessInformationClass == ProcessDebugFlags || ProcessInformationClass == ProcessBreakOnTermination || + ProcessInformationClass == ProcessBasicInformation || ProcessInformationClass == ProcessIoCounters || + ProcessInformationClass == ProcessInstrumentationCallback || + ProcessInformationClass == ProcessHandleTracing)) + { + NTSTATUS status = STATUS_SUCCESS; + bool handled = false; + + __try + { + if (ProcessInformationLength != 0) + { + ProbeForWrite(ProcessInformation, ProcessInformationLength, 4); + } + + if (ReturnLength != 0) + { + ProbeForWrite(ReturnLength, sizeof(*ReturnLength), 1); + } + + PEPROCESS process = nullptr; + + if (ProcessHandle == ZwCurrentProcess()) + { + process = PsGetCurrentProcess(); + } + else + { + status = ObReferenceObjectByHandle(ProcessHandle, PROCESS_QUERY_INFORMATION, *PsProcessType, + previousMode, reinterpret_cast(&process), nullptr); + if (!NT_SUCCESS(status)) + { + goto Exit; + } + + SCOPE_EXIT + { + ObDereferenceObject(process); + }; + } + + PPROCESS_ENTRY threadProcessEntry = GetProcessEntry(PsGetProcessId(process)); + + SCOPE_EXIT + { + if (threadProcessEntry) + { + object::DereferenceObject(threadProcessEntry); + threadProcessEntry = nullptr; + } + }; + + if (threadProcessEntry && + BooleanFlagOn(threadProcessEntry->PolicyFlags, ProcessPolicyFlagNtQueryInformationProcess)) + { + if (BooleanFlagOn(threadProcessEntry->PolicyFlags, ProcessPolicyFlagHideFromDebugger)) + { + if (ProcessInformationClass == ProcessDebugObjectHandle) + { + *static_cast(ProcessInformation) = nullptr; + + if (ReturnLength != nullptr) + { + *ReturnLength = sizeof(HANDLE); + } + + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, + "Spoofed NtQueryInformationProcess(ProcessDebugObjectHandle) tid:%d", + HandleToUlong(threadProcessEntry->ProcessId)); + + status = STATUS_PORT_NOT_SET; + handled = true; + } + else if (ProcessInformationClass == ProcessInstrumentationCallback && + BooleanFlagOn(threadProcessEntry->PolicyFlags, + ProcessPolicyFlagBypassInstrumentationCallback)) + { + WppTracePrint( + TRACE_LEVEL_VERBOSE, GENERAL, + "Spoofed NtQueryInformationProcess(ProcessInstrumentationCallback) tid:%d", + HandleToUlong(threadProcessEntry->ProcessId)); + + status = STATUS_INVALID_INFO_CLASS; + handled = true; + } + else if (ProcessInformationClass == ProcessDebugPort) + { + BACKUP_RETURNLENGTH(); + + *(static_cast(ProcessInformation)) = nullptr; + + if (ReturnLength != nullptr) + { + *ReturnLength = sizeof(HANDLE); + } + + RESTORE_RETURNLENGTH(); + + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, + "Spoofed NtQueryInformationProcess(ProcessDebugPort) tid:%d", + HandleToUlong(threadProcessEntry->ProcessId)); + + status = STATUS_SUCCESS; + handled = true; + } + else if (ProcessInformationClass == ProcessDebugFlags) + { + BACKUP_RETURNLENGTH(); + + *((ULONG *)ProcessInformation) = + ((threadProcessEntry->Flags.ValueProcessDebugFlags & PROCESS_NO_DEBUG_INHERIT) != 0) + ? 0 + : PROCESS_DEBUG_INHERIT; + + if (ReturnLength != nullptr) + { + *ReturnLength = sizeof(ULONG); + } + + RESTORE_RETURNLENGTH(); + + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, + "Spoofed NtQueryInformationProcess(ProcessDebugFlags) tid:%d", + HandleToUlong(threadProcessEntry->ProcessId)); + + status = STATUS_SUCCESS; + handled = true; + } + else if (ProcessInformationClass == ProcessBreakOnTermination) + { + BACKUP_RETURNLENGTH(); + + *((ULONG *)ProcessInformation) = + threadProcessEntry->Flags.ValueProcessBreakOnTermination; + + RESTORE_RETURNLENGTH(); + + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, + "Spoofed NtQueryInformationProcess(ProcessBreakOnTermination) tid:%d", + HandleToUlong(threadProcessEntry->ProcessId)); + + status = STATUS_SUCCESS; + handled = true; + } + + status = reinterpret_cast(hookEntry->OriginalFunc)( + ProcessHandle, ProcessInformationClass, ProcessInformation, ProcessInformationLength, + ReturnLength); + + if (NT_SUCCESS(status)) + { + if (ProcessInformationClass == ProcessBasicInformation) // Fake parent + { + BACKUP_RETURNLENGTH(); + + PEPROCESS parentProcess = + tools::GetProcessByName(threadProcessEntry->FakeParentProcessName); + if (parentProcess) + { + (static_cast(ProcessInformation)) + ->InheritedFromUniqueProcessId = + HandleToUlong(PsGetProcessId(parentProcess)); + + ObDereferenceObject(parentProcess); + } + + RESTORE_RETURNLENGTH(); + + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, + "Spoofed NtQueryInformationProcess(ProcessBasicInformation) tid:%d", + HandleToUlong(threadProcessEntry->ProcessId)); + + status = STATUS_SUCCESS; + handled = true; + } + + else if (ProcessInformationClass == ProcessHandleTracing) + { + BACKUP_RETURNLENGTH(); + RESTORE_RETURNLENGTH(); // Trigger any possible exceptions caused by messing + // with the output buffer before changing the final + // return status + + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, + "Spoofed NtQueryInformationProcess(ProcessHandleTracing) tid:%d", + HandleToUlong(threadProcessEntry->ProcessId)); + + status = threadProcessEntry->Flags.ProcessHandleTracingEnabled + ? STATUS_SUCCESS + : STATUS_INVALID_PARAMETER; + handled = true; + } + else if (ProcessInformationClass == ProcessIoCounters) + { + BACKUP_RETURNLENGTH(); + + ((PIO_COUNTERS)ProcessInformation)->OtherOperationCount = 1; + + RESTORE_RETURNLENGTH(); + + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, + "Spoofed NtQueryInformationProcess(ProcessIoCounters) tid:%d", + HandleToUlong(threadProcessEntry->ProcessId)); + + status = STATUS_SUCCESS; + handled = true; + } + } + } + } + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + status = GetExceptionCode(); + handled = true; + } + + if (!handled) + { + status = reinterpret_cast(hookEntry->OriginalFunc)( + ProcessHandle, ProcessInformationClass, ProcessInformation, ProcessInformationLength, + ReturnLength); + } + + Exit: + if (BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagMonitored)) + { + WppTracePrint( + TRACE_LEVEL_VERBOSE, GENERAL, + "NtQueryInformationProcess from pid %u ProcessHandle = 0x%p ProcessInformationClass %d " + "returned %!STATUS!\n", + HandleToUlong(PsGetCurrentProcessId()), ProcessHandle, ProcessInformationClass, status); + } + + return status; + } + } + } + return reinterpret_cast(hookEntry->OriginalFunc)( + ProcessHandle, ProcessInformationClass, ProcessInformation, ProcessInformationLength, ReturnLength); +} + +NTSTATUS NTAPI hkNtSetInformationProcess(HANDLE ProcessHandle, PROCESSINFOCLASS ProcessInformationClass, + PVOID ProcessInformation, ULONG ProcessInformationLength) +{ + PAGED_CODE(); + + const PHOOK_ENTRY hookEntry = FindHookEntry(FNV("NtSetInformationProcess")); + const ScopedReferenceGuard lock(&hookEntry->RefCount); + + const KPROCESSOR_MODE previousMode = ExGetPreviousMode(); + if (previousMode == UserMode) + { + const HANDLE currentProcessId = PsGetCurrentProcessId(); + PPROCESS_ENTRY processEntry = GetProcessEntry(currentProcessId); + + SCOPE_EXIT + { + if (processEntry) + { + object::DereferenceObject(processEntry); + processEntry = nullptr; + } + }; + + // (1) check if the process is blacklisted (2) check if hook is meant to be intercepted + // + if (processEntry && BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagNtSetInformationProcess)) + { + if (BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagHideFromDebugger) && + (ProcessInformationClass == ProcessBreakOnTermination || ProcessInformationClass == ProcessDebugFlags || + ProcessInformationClass == ProcessInstrumentationCallback || + ProcessInformationClass == ProcessHandleTracing)) + { + NTSTATUS status = STATUS_SUCCESS; + bool handled = false; + + __try + { + if (ProcessInformationLength != 0) + { + ProbeForRead(ProcessInformation, ProcessInformationLength, 1); + } + + PEPROCESS process = nullptr; + + if (ProcessHandle == ZwCurrentProcess()) + { + process = PsGetCurrentProcess(); + } + else + { + status = ObReferenceObjectByHandle(ProcessHandle, PROCESS_QUERY_INFORMATION, *PsProcessType, + previousMode, reinterpret_cast(&process), nullptr); + if (!NT_SUCCESS(status)) + { + goto Exit; + } + + SCOPE_EXIT + { + ObDereferenceObject(process); + }; + } + + PPROCESS_ENTRY threadProcessEntry = GetProcessEntry(PsGetProcessId(process)); + + SCOPE_EXIT + { + if (threadProcessEntry) + { + object::DereferenceObject(threadProcessEntry); + threadProcessEntry = nullptr; + } + }; + + if (threadProcessEntry && + BooleanFlagOn(threadProcessEntry->PolicyFlags, ProcessPolicyFlagNtSetInformationProcess)) + { + if (ProcessInformationClass == ProcessBreakOnTermination) + { + if (ProcessInformationLength != sizeof(ULONG)) + { + status = STATUS_INFO_LENGTH_MISMATCH; + goto Exit; + } + + volatile ULONG Touch = *(ULONG *)ProcessInformation; + UNREFERENCED_PARAMETER(Touch); + + // A process must have debug privileges enabled to set the ProcessBreakOnTermination + // flag + if (!tools::HasDebugPrivilege()) + { + status = STATUS_PRIVILEGE_NOT_HELD; + goto Exit; + } + + threadProcessEntry->Flags.ValueProcessBreakOnTermination = *(ULONG *)ProcessInformation & 1; + + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, + "Spoofed NtSetInformationProcess(ProcessBreakOnTermination) tid:%d", + HandleToUlong(threadProcessEntry->ProcessId)); + + status = STATUS_SUCCESS; + handled = true; + } + else if (ProcessInformationClass == ProcessInstrumentationCallback && + BooleanFlagOn(threadProcessEntry->PolicyFlags, + ProcessPolicyFlagBypassInstrumentationCallback)) + { + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, + "Spoofed NtSetInformationProcess(ProcessInstrumentationCallback) tid:%d", + HandleToUlong(threadProcessEntry->ProcessId)); + + status = STATUS_SUCCESS; + handled = true; + } + else if (ProcessInformationClass == ProcessDebugFlags) + { + if (ProcessInformationLength != sizeof(ULONG)) + { + status = STATUS_INFO_LENGTH_MISMATCH; + goto Exit; + } + + ULONG Flags = *(ULONG *)ProcessInformation; + if ((Flags & ~PROCESS_DEBUG_INHERIT) != 0) + { + status = STATUS_INVALID_PARAMETER; + goto Exit; + } + + if ((Flags & PROCESS_DEBUG_INHERIT) != 0) + { + threadProcessEntry->Flags.ValueProcessDebugFlags = 0; + } + else + { + threadProcessEntry->Flags.ValueProcessDebugFlags = TRUE; + } + + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, + "Spoofed NtSetInformationProcess(ProcessDebugFlags) tid:%d", + HandleToUlong(threadProcessEntry->ProcessId)); + + status = STATUS_SUCCESS; + handled = true; + } + else if (ProcessInformationClass == ProcessHandleTracing) + { + const bool enable = ProcessInformationLength != 0; + if (enable) + { + if (ProcessInformationLength != sizeof(ULONG) && + ProcessInformationLength != (sizeof(ULONG64))) + { + status = STATUS_INFO_LENGTH_MISMATCH; + goto Exit; + } + + auto *phtEx = static_cast(ProcessInformation); + if (phtEx->Flags != 0) + { + status = STATUS_INVALID_PARAMETER; + goto Exit; + } + } + + processEntry->Flags.ProcessHandleTracingEnabled = enable; + + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, + "Spoofed NtSetInformationProcess(ProcessHandleTracing) tid:%d", + HandleToUlong(threadProcessEntry->ProcessId)); + + status = STATUS_SUCCESS; + handled = true; + } + } + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + status = GetExceptionCode(); + handled = true; + } + + Exit: + if (BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagMonitored)) + { + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, + "NtSetInformationProcess from pid %u ProcessHandle = 0x%p ProcessInformationClass %d " + "returned %!STATUS!\n", + HandleToUlong(PsGetCurrentProcessId()), ProcessHandle, ProcessInformationClass, + status); + } + + return status; + } + } + } + return reinterpret_cast(hookEntry->OriginalFunc)( + ProcessHandle, ProcessInformationClass, ProcessInformation, ProcessInformationLength); +} + +void FilterObject(_In_ POBJECT_TYPE_INFORMATION object) +{ + PAGED_CODE(); + NT_ASSERT(object); + + UNICODE_STRING debugObjectName = RTL_CONSTANT_STRING(L"DebugObject"); + if (RtlEqualUnicodeString(&debugObjectName, &object->TypeName, FALSE)) + { + // Subtract just one from both counts for our debugger, unless the query was a generic one for all object + // types + if (object->TotalNumberOfObjects > 1) + { + object->TotalNumberOfObjects = 1; + object->TotalNumberOfHandles = 1; + } + else + { + object->TotalNumberOfObjects = 0; + object->TotalNumberOfHandles = 0; + } + } +} + +void FilterObjects(_In_ POBJECT_ALL_INFORMATION objectAllInformation) +{ + PAGED_CODE(); + NT_ASSERT(objectAllInformation); + + POBJECT_TYPE_INFORMATION object = objectAllInformation->ObjectInformation; + + for (ULONG i = 0; i < objectAllInformation->NumberOfObjectsTypes; i++) + { + FilterObject(object); + + object = reinterpret_cast(reinterpret_cast(object + 1) + + ALIGN_UP(object->TypeName.MaximumLength, ULONG_PTR)); + } +} + +NTSTATUS NTAPI hkNtQueryObject(HANDLE Handle, OBJECT_INFORMATION_CLASS ObjectInformationClass, PVOID ObjectInformation, + ULONG ObjectInformationLength, PULONG ReturnLength) +{ + PAGED_CODE(); + + const PHOOK_ENTRY hookEntry = FindHookEntry(FNV("NtQueryObject")); + const ScopedReferenceGuard lock(&hookEntry->RefCount); + + NTSTATUS status = reinterpret_cast(hookEntry->OriginalFunc)( + Handle, ObjectInformationClass, ObjectInformation, ObjectInformationLength, ReturnLength); + + const KPROCESSOR_MODE previousMode = ExGetPreviousMode(); + if (previousMode == UserMode) + { + const HANDLE currentProcessId = PsGetCurrentProcessId(); + PPROCESS_ENTRY processEntry = GetProcessEntry(currentProcessId); + + SCOPE_EXIT + { + if (processEntry) + { + object::DereferenceObject(processEntry); + processEntry = nullptr; + } + }; + + // (1) check if the process is blacklisted (2) check if hook is meant to be intercepted + // + if (processEntry && BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagNtQueryObject)) + { + if (BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagHideFromDebugger)) + { + if (NT_SUCCESS(status) && ObjectInformation && + (ObjectInformationClass == ObjectTypesInformation || + ObjectInformationClass == ObjectTypeInformation)) + { + __try + { + ProbeForWrite(ObjectInformation, ObjectInformationLength, 1); + + if (ObjectInformationClass == ObjectTypesInformation) + { + BACKUP_RETURNLENGTH(); + + FilterObjects(static_cast(ObjectInformation)); + + RESTORE_RETURNLENGTH(); + + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, + "Spoofed NtQueryObject(ObjectTypesInformation) tid:%d", + HandleToUlong(processEntry->ProcessId)); + } + else if (ObjectInformationClass == ObjectTypeInformation) + { + BACKUP_RETURNLENGTH(); + + FilterObject(static_cast(ObjectInformation)); + + RESTORE_RETURNLENGTH(); + + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, + "Spoofed NtQueryObject(ObjectTypeInformation) tid:%d", + HandleToUlong(processEntry->ProcessId)); + } + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + status = GetExceptionCode(); + } + } + } + + if (BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagMonitored)) + { + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, + "NtQueryObject from pid %u Handle = 0x%p ObjectInformationClass %d " + "returned %!STATUS!\n", + HandleToUlong(PsGetCurrentProcessId()), Handle, ObjectInformationClass, status); + } + } + } + return status; +} + +NTSTATUS NTAPI hkNtCreateUserProcess(PHANDLE ProcessHandle, PHANDLE ThreadHandle, ACCESS_MASK ProcessDesiredAccess, + ACCESS_MASK ThreadDesiredAccess, POBJECT_ATTRIBUTES ProcessObjectAttributes, + POBJECT_ATTRIBUTES ThreadObjectAttributes, ULONG ProcessFlags, ULONG ThreadFlags, + PRTL_USER_PROCESS_PARAMETERS ProcessParameters, + PVOID CreateInfo, // PPS_CREATE_INFO + PVOID AttributeList // PPS_ATTRIBUTE_LIST +) +{ + const PHOOK_ENTRY hookEntry = FindHookEntry(FNV("NtCreateUserProcess")); + const ScopedReferenceGuard lock(&hookEntry->RefCount); + + NTSTATUS status = reinterpret_cast(hookEntry->OriginalFunc)( + ProcessHandle, ThreadHandle, ProcessDesiredAccess, ThreadDesiredAccess, ProcessObjectAttributes, + ThreadObjectAttributes, ProcessFlags, ThreadFlags, ProcessParameters, CreateInfo, AttributeList); + + const KPROCESSOR_MODE previousMode = ExGetPreviousMode(); + if (previousMode == UserMode) + { + const HANDLE currentProcessId = PsGetCurrentProcessId(); + PPROCESS_ENTRY processEntry = GetProcessEntry(currentProcessId); + + SCOPE_EXIT + { + if (processEntry) + { + object::DereferenceObject(processEntry); + processEntry = nullptr; + } + }; + + // (1) check if the process is blacklisted (2) check if hook is meant to be intercepted + // + if (processEntry && BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagNtCreateUserProcess)) + { + __try + { + if (NT_SUCCESS(status) && + BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagHideChildFromDebugger)) + { + PEPROCESS process = nullptr; + if (NT_SUCCESS(ObReferenceObjectByHandle(*ProcessHandle, PROCESS_QUERY_LIMITED_INFORMATION, + *PsProcessType, previousMode, + reinterpret_cast(&process), nullptr))) + { + const NTSTATUS status2 = AddProcessEntry(process, processEntry->PolicyFlags); + if (!NT_SUCCESS(status2)) + { + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, "Failed to add new process entry %!STATUS!\n", + status2); + } + + ObDereferenceObject(process); + } + } + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + status = GetExceptionCode(); + } + + if (BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagMonitored)) + { + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, + "NtCreateUserProcess from pid %u ProcessHandle = 0x%p ThreadHandle = 0x%p " + "ProcessDesiredAccess 0x%08X ThreadDesiredAccess 0x%08X " + "returned %!STATUS!\n", + HandleToUlong(PsGetCurrentProcessId()), ProcessHandle, ThreadHandle, ProcessDesiredAccess, + ThreadDesiredAccess, status); + } + } + } + return status; +} + +NTSTATUS NTAPI hkNtCreateThreadEx(PHANDLE ThreadHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, + HANDLE ProcessHandle, PVOID StartRoutine, PVOID Argument, ULONG CreateFlags, + SIZE_T ZeroBits, SIZE_T StackSize, SIZE_T MaximumStackSize, PVOID AttributeList) +{ + PAGED_CODE(); + + const PHOOK_ENTRY hookEntry = FindHookEntry(FNV("NtCreateThreadEx")); + const ScopedReferenceGuard lock(&hookEntry->RefCount); + + const KPROCESSOR_MODE previousMode = ExGetPreviousMode(); + if (previousMode == UserMode && (CreateFlags & THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER || + CreateFlags & THREAD_CREATE_FLAGS_BYPASS_PROCESS_FREEZE)) + { + const HANDLE currentProcessId = PsGetCurrentProcessId(); + PPROCESS_ENTRY processEntry = GetProcessEntry(currentProcessId); + + SCOPE_EXIT + { + if (processEntry) + { + object::DereferenceObject(processEntry); + processEntry = nullptr; + } + }; + + // (1) check if the process is blacklisted (2) check if hook is meant to be intercepted + // + if (processEntry && BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagNtCreateThreadEx)) + { + NTSTATUS status = STATUS_SUCCESS; + bool handled = false; + + if (BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagHideFromDebugger)) + { + const ULONG OriginalFlags = CreateFlags; + ULONG ClearFlags = OriginalFlags & ~(THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER); + + if (KERNEL_BUILD_VERSION >= WINDOWS_10_VERSION_19H1) + { + ClearFlags = OriginalFlags & + ~(THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER | THREAD_CREATE_FLAGS_BYPASS_PROCESS_FREEZE); + } + + status = reinterpret_cast(hookEntry->OriginalFunc)( + ThreadHandle, DesiredAccess, ObjectAttributes, ProcessHandle, StartRoutine, Argument, ClearFlags, + ZeroBits, StackSize, MaximumStackSize, AttributeList); + handled = true; + + if (NT_SUCCESS(status)) + { + PETHREAD thread = nullptr; + if (NT_SUCCESS(ObReferenceObjectByHandle(*ThreadHandle, THREAD_QUERY_INFORMATION, *PsThreadType, + previousMode, reinterpret_cast(&thread), NULL))) + { + SCOPE_EXIT + { + ObDereferenceObject(thread); + }; + + PEPROCESS process = nullptr; + + if (ProcessHandle == ZwCurrentProcess()) + { + process = PsGetCurrentProcess(); + } + else + { + if (!NT_SUCCESS(ObReferenceObjectByHandle(ProcessHandle, PROCESS_QUERY_INFORMATION, + *PsProcessType, previousMode, + reinterpret_cast(&process), NULL))) + { + goto Exit; + } + + SCOPE_EXIT + { + ObDereferenceObject(process); + }; + } + + PPROCESS_ENTRY threadProcessEntry = GetProcessEntry(process); + + SCOPE_EXIT + { + if (threadProcessEntry) + { + object::DereferenceObject(threadProcessEntry); + threadProcessEntry = nullptr; + } + }; + + // If (1) it's a blacklisted process and (2) current hook is meant to be intercepted + // + if (threadProcessEntry && + BooleanFlagOn(threadProcessEntry->PolicyFlags, ProcessPolicyFlagNtCreateThreadEx)) + { + if (BooleanFlagOn(threadProcessEntry->PolicyFlags, ProcessPolicyFlagHideFromDebugger)) + { + PTHREAD_ENTRY threadEntry = threadProcessEntry->AppendThreadList(thread); + if (threadEntry) + { + threadEntry->Flags.IsThreadHidden = + OriginalFlags & THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER; + + WppTracePrint( + TRACE_LEVEL_VERBOSE, GENERAL, + "NtCreateThreadEx hide thread %u from pid %u from debugger and freeze", + HandleToUlong(PsGetThreadId(thread)), + HandleToUlong(threadProcessEntry->ProcessId)); + } + } + } + } + } + } + + if (!handled) + { + status = reinterpret_cast(hookEntry->OriginalFunc)( + ThreadHandle, DesiredAccess, ObjectAttributes, ProcessHandle, StartRoutine, Argument, CreateFlags, + ZeroBits, StackSize, MaximumStackSize, AttributeList); + } + + Exit: + if (BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagMonitored)) + { + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, + "NtCreateThreadEx from pid %u ProcessHandle = 0x%p StartRoutine 0x%p Argument 0x%p " + "CreateFlags %d " + "returned %!STATUS!\n", + HandleToUlong(PsGetCurrentProcessId()), ProcessHandle, StartRoutine, Argument, + CreateFlags, status); + } + + return status; + } + } + return reinterpret_cast(hookEntry->OriginalFunc)( + ThreadHandle, DesiredAccess, ObjectAttributes, ProcessHandle, StartRoutine, Argument, CreateFlags, ZeroBits, + StackSize, MaximumStackSize, AttributeList); +} + +NTSTATUS NTAPI hkNtGetContextThread(HANDLE ThreadHandle, PCONTEXT ThreadContext) +{ + PAGED_CODE(); + + const PHOOK_ENTRY hookEntry = FindHookEntry(FNV("NtGetContextThread")); + const ScopedReferenceGuard lock(&hookEntry->RefCount); + + const KPROCESSOR_MODE previousMode = ExGetPreviousMode(); + if (previousMode == UserMode) + { + const HANDLE currentProcessId = PsGetCurrentProcessId(); + PPROCESS_ENTRY processEntry = GetProcessEntry(currentProcessId); + + SCOPE_EXIT + { + if (processEntry) + { + object::DereferenceObject(processEntry); + processEntry = nullptr; + } + }; + + // (1) check if the process is blacklisted (2) check if hook is meant to be intercepted + // + if (processEntry && BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagNtGetContextThread)) + { + NTSTATUS status = STATUS_SUCCESS; + bool handled = false; + + if (BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagHideFromDebugger)) + { + __try + { + ProbeForWrite(ThreadContext, sizeof(*ThreadContext), TYPE_ALIGNMENT(CONTEXT)); + + PETHREAD thread = nullptr; + + if (ThreadHandle == ZwCurrentThread()) + { + thread = PsGetCurrentThread(); + } + else + { + if (!NT_SUCCESS(ObReferenceObjectByHandle(ThreadHandle, THREAD_QUERY_INFORMATION, *PsThreadType, + previousMode, reinterpret_cast(&thread), + nullptr))) + { + goto Exit; + } + } + + PPROCESS_ENTRY threadProcessEntry = GetProcessEntry(PsGetThreadProcessId(thread)); + + SCOPE_EXIT + { + ObDereferenceObject(thread); + + if (threadProcessEntry) + { + object::DereferenceObject(threadProcessEntry); + threadProcessEntry = nullptr; + } + }; + + if (threadProcessEntry && + BooleanFlagOn(threadProcessEntry->PolicyFlags, ProcessPolicyFlagNtGetContextThread)) + { + if (BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagHideFromDebugger)) + { + ULONG OriginalFlags = ThreadContext->ContextFlags; + ThreadContext->ContextFlags &= ~0x10; + + status = reinterpret_cast(hookEntry->OriginalFunc)( + ThreadHandle, ThreadContext); + + if (OriginalFlags & 0x10) + { + ThreadContext->ContextFlags |= 0x10; + + PTHREAD_ENTRY threadEntry = threadProcessEntry->AppendThreadList(thread); + if (threadEntry) + { + RtlCopyMemory(&ThreadContext->Dr0, &threadEntry->SavedDebugContext.Dr0, + sizeof(ULONG64) * 6); + RtlCopyMemory(&ThreadContext->DebugControl, + &threadEntry->SavedDebugContext.DebugControl, sizeof(ULONG64) * 5); + + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, "Spoofed NtGetContextThread tid:%d", + HandleToUlong(PsGetThreadId(threadEntry->Thread))); + } + else + { + RtlSecureZeroMemory(&ThreadContext->Dr0, sizeof(ULONG64) * 6); + RtlSecureZeroMemory(&ThreadContext->DebugControl, sizeof(ULONG64) * 5); + } + } + + handled = true; + } + } + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + status = GetExceptionCode(); + handled = true; + } + } + + if (!handled) + { + status = reinterpret_cast(hookEntry->OriginalFunc)(ThreadHandle, + ThreadContext); + } + + Exit: + if (BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagMonitored)) + { + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, + "NtGetContextThread from pid %u ThreadHandle = 0x%p returned %!STATUS!\n", + HandleToUlong(PsGetCurrentProcessId()), ThreadHandle, status); + } + + return status; + } + } + return reinterpret_cast(hookEntry->OriginalFunc)(ThreadHandle, ThreadContext); +} + +NTSTATUS NTAPI hkNtSetContextThread(HANDLE ThreadHandle, PCONTEXT ThreadContext) +{ + PAGED_CODE(); + + const PHOOK_ENTRY hookEntry = FindHookEntry(FNV("NtSetContextThread")); + const ScopedReferenceGuard lock(&hookEntry->RefCount); + + const KPROCESSOR_MODE previousMode = ExGetPreviousMode(); + if (previousMode == UserMode) + { + const HANDLE currentProcessId = PsGetCurrentProcessId(); + PPROCESS_ENTRY processEntry = GetProcessEntry(currentProcessId); + + SCOPE_EXIT + { + if (processEntry) + { + object::DereferenceObject(processEntry); + processEntry = nullptr; + } + }; + + // (1) check if the process is blacklisted (2) check if hook is meant to be intercepted + // + if (processEntry && BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagNtSetContextThread)) + { + NTSTATUS status = STATUS_SUCCESS; + bool handled = false; + + if (BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagHideFromDebugger)) + { + __try + { + ProbeForWrite(ThreadContext, sizeof(*ThreadContext), TYPE_ALIGNMENT(CONTEXT)); + + PETHREAD thread = nullptr; + + if (ThreadHandle == ZwCurrentThread()) + { + thread = PsGetCurrentThread(); + } + else + { + if (!NT_SUCCESS(ObReferenceObjectByHandle(ThreadHandle, THREAD_QUERY_INFORMATION, *PsThreadType, + previousMode, reinterpret_cast(&thread), + nullptr))) + { + goto Exit; + } + } + + PPROCESS_ENTRY threadProcessEntry = GetProcessEntry(PsGetThreadProcessId(thread)); + + SCOPE_EXIT + { + ObDereferenceObject(thread); + + if (threadProcessEntry) + { + object::DereferenceObject(threadProcessEntry); + threadProcessEntry = nullptr; + } + }; + + if (threadProcessEntry && + BooleanFlagOn(threadProcessEntry->PolicyFlags, ProcessPolicyFlagNtSetContextThread)) + { + if (BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagHideFromDebugger)) + { + ULONG OriginalFlags = ThreadContext->ContextFlags; + ThreadContext->ContextFlags &= ~0x10; + + status = reinterpret_cast(hookEntry->OriginalFunc)( + ThreadHandle, ThreadContext); + + if (OriginalFlags & 0x10) + { + ThreadContext->ContextFlags |= 0x10; + + PTHREAD_ENTRY threadEntry = threadProcessEntry->AppendThreadList(thread); + if (threadEntry) + { + RtlCopyMemory(&threadEntry->SavedDebugContext.Dr0, &ThreadContext->Dr0, + sizeof(ULONG64) * 6); + RtlCopyMemory(&threadEntry->SavedDebugContext.DebugControl, + &ThreadContext->DebugControl, sizeof(ULONG64) * 5); + + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, "Spoofed NtSetContextThread tid:%d", + HandleToUlong(PsGetThreadId(threadEntry->Thread))); + } + } + + handled = true; + } + } + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + status = GetExceptionCode(); + handled = true; + } + } + + if (!handled) + { + status = reinterpret_cast(hookEntry->OriginalFunc)(ThreadHandle, + ThreadContext); + } + + Exit: + if (BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagMonitored)) + { + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, + "NtSetContextThread from pid %u ThreadHandle = 0x%p returned %!STATUS!\n", + HandleToUlong(PsGetCurrentProcessId()), ThreadHandle, status); + } + + return status; + } + } + return reinterpret_cast(hookEntry->OriginalFunc)(ThreadHandle, ThreadContext); +} + +void FilterJobProcessList(PJOBOBJECT_BASIC_PROCESS_ID_LIST JobInformation, PULONG pReturnLengthAdjust) +{ + *pReturnLengthAdjust = 0; + const ULONG TrueCount = JobInformation->NumberOfAssignedProcesses; + for (ULONG i = 0; i < TrueCount; ++i) + { + const auto processId = (HANDLE)JobInformation->ProcessIdList[i]; + if (process::IsProtectedProcess(processId)) + { + JobInformation->NumberOfAssignedProcesses--; + JobInformation->NumberOfProcessIdsInList--; + *pReturnLengthAdjust += sizeof(ULONG_PTR); + for (ULONG j = i; j < TrueCount - 1; ++j) + { + JobInformation->ProcessIdList[j] = JobInformation->ProcessIdList[j + 1]; + RtlZeroMemory(&JobInformation->ProcessIdList[j + 1], sizeof(JobInformation->ProcessIdList[j + 1])); + } + i--; + } + } +} + +NTSTATUS NTAPI hkNtQueryInformationJobObject(HANDLE JobHandle, JOBOBJECTINFOCLASS JobInformationClass, + PVOID JobInformation, ULONG JobInformationLength, PULONG ReturnLength) +{ + const PHOOK_ENTRY hookEntry = FindHookEntry(FNV("NtQueryInformationJobObject")); + const ScopedReferenceGuard lock(&hookEntry->RefCount); + + auto status = reinterpret_cast(hookEntry->OriginalFunc)( + JobHandle, JobInformationClass, JobInformation, JobInformationLength, ReturnLength); + + const KPROCESSOR_MODE previousMode = ExGetPreviousMode(); + if (previousMode == UserMode) + { + const HANDLE currentProcessId = PsGetCurrentProcessId(); + process::PPROCESS_ENTRY processEntry = GetProcessEntry(currentProcessId); + + SCOPE_EXIT + { + if (processEntry) + { + object::DereferenceObject(processEntry); + processEntry = nullptr; + } + }; + + // If (1) process has entry and (2) current hook is meant to be intercepted + // + if (processEntry && BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagNtQueryInformationJobObject)) + { + if (NT_SUCCESS(status) && BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagHideFromDebugger) && + JobInformationClass == JobObjectBasicProcessIdList) + { + BACKUP_RETURNLENGTH(); + ULONG ReturnLengthAdjust = 0; + + FilterJobProcessList(static_cast(JobInformation), + &ReturnLengthAdjust); + + if (ReturnLengthAdjust <= TempReturnLength) + { + TempReturnLength -= ReturnLengthAdjust; + } + + RESTORE_RETURNLENGTH(); + + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, + "Spoofed NtQueryInformationJobObject(JobObjectBasicProcessIdList) pid:%d", + HandleToUlong(processEntry->ProcessId)); + } + + if (BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagMonitored)) + { + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, + "NtQueryInformationJobObject from pid %u JobHandle = 0x%p JobInformationClass = %u " + "returned %!STATUS!\n", + HandleToUlong(PsGetCurrentProcessId()), JobHandle, JobInformationClass, status); + } + } + } + return status; +} + +void FilterHandleInfo(PSYSTEM_HANDLE_INFORMATION pHandleInfo, PULONG pReturnLengthAdjust) +{ + *pReturnLengthAdjust = 0; + const ULONG TrueCount = pHandleInfo->NumberOfHandles; + for (ULONG i = 0; i < TrueCount; ++i) + { + if (IsProtectedProcess((HANDLE)pHandleInfo->Handles[i].UniqueProcessId)) + { + pHandleInfo->NumberOfHandles--; + *pReturnLengthAdjust += sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO); + for (ULONG j = i; j < TrueCount - 1; ++j) + { + pHandleInfo->Handles[j] = pHandleInfo->Handles[j + 1]; + RtlZeroMemory(&pHandleInfo->Handles[j + 1], sizeof(pHandleInfo->Handles[j + 1])); + } + i--; + } + } +} + +void FilterHandleInfoEx(PSYSTEM_HANDLE_INFORMATION_EX pHandleInfoEx, PULONG pReturnLengthAdjust) +{ + *pReturnLengthAdjust = 0; + const ULONG TrueCount = (ULONG)pHandleInfoEx->NumberOfHandles; + for (ULONG i = 0; i < TrueCount; ++i) + { + if (IsProtectedProcess((HANDLE)pHandleInfoEx->Handles[i].UniqueProcessId)) + { + pHandleInfoEx->NumberOfHandles--; + *pReturnLengthAdjust += sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX); + for (ULONG j = i; j < TrueCount - 1; ++j) + { + pHandleInfoEx->Handles[j] = pHandleInfoEx->Handles[j + 1]; + RtlZeroMemory(&pHandleInfoEx->Handles[j + 1], sizeof(pHandleInfoEx->Handles[j + 1])); + } + i--; + } + } +} + +void FilterProcess(PSYSTEM_PROCESS_INFORMATION pInfo) +{ + PSYSTEM_PROCESS_INFORMATION pPrev = pInfo; + + while (TRUE) + { + if (IsProtectedProcess(pInfo->UniqueProcessId)) + { + if (pInfo->ImageName.Buffer) + { + RtlZeroMemory(pInfo->ImageName.Buffer, pInfo->ImageName.Length); + } + + if (pInfo->NextEntryOffset == 0) // last element + { + pPrev->NextEntryOffset = 0; + } + else + { + pPrev->NextEntryOffset += pInfo->NextEntryOffset; + } + } + else + { + pPrev = pInfo; + } + + if (pInfo->NextEntryOffset == 0) + { + break; + } + else + { + pInfo = (PSYSTEM_PROCESS_INFORMATION)((DWORD_PTR)pInfo + pInfo->NextEntryOffset); + } + } +} + +NTSTATUS NTAPI hkNtQuerySystemInformation(SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID SystemInformation, + ULONG SystemInformationLength, PULONG ReturnLength) +{ + PAGED_CODE(); + + const PHOOK_ENTRY hookEntry = FindHookEntry(FNV("NtQuerySystemInformation")); + const ScopedReferenceGuard lock(&hookEntry->RefCount); + + NTSTATUS status = reinterpret_cast(hookEntry->OriginalFunc)( + SystemInformationClass, SystemInformation, SystemInformationLength, ReturnLength); + + const KPROCESSOR_MODE previousMode = ExGetPreviousMode(); + if (previousMode == UserMode) + { + const HANDLE currentProcessId = PsGetCurrentProcessId(); + PPROCESS_ENTRY processEntry = GetProcessEntry(currentProcessId); + + SCOPE_EXIT + { + if (processEntry) + { + object::DereferenceObject(processEntry); + processEntry = nullptr; + } + }; + + // (1) check if the process is blacklisted (2) check if hook is meant to be intercepted + // + if (NT_SUCCESS(status) && + (processEntry && BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagNtQuerySystemInformation))) + { + if (BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagHideFromDebugger)) + { + __try + { + ProbeForWrite(SystemInformation, SystemInformationLength, 1); + + if (SystemInformationClass == SystemProcessInformation || + SystemInformationClass == SystemSessionProcessInformation || + SystemInformationClass == SystemExtendedProcessInformation) + { + BACKUP_RETURNLENGTH(); + + auto ProcessInfo = static_cast(SystemInformation); + if (SystemInformationClass == SystemSessionProcessInformation) + { + ProcessInfo = static_cast( + (static_cast(SystemInformation))->Buffer); + } + + FilterProcess(ProcessInfo); + + for (PSYSTEM_PROCESS_INFORMATION entry = ProcessInfo; entry->NextEntryOffset != NULL; + entry = reinterpret_cast(reinterpret_cast(entry) + + entry->NextEntryOffset)) + { + PPROCESS_ENTRY processEntry2 = GetProcessEntry(entry->UniqueProcessId); + + SCOPE_EXIT + { + if (processEntry2) + { + object::DereferenceObject(processEntry2); + processEntry2 = nullptr; + } + }; + + if (processEntry2 && + BooleanFlagOn(processEntry2->PolicyFlags, ProcessPolicyFlagNtQuerySystemInformation)) + { + if (BooleanFlagOn(processEntry2->PolicyFlags, ProcessPolicyFlagHideFromDebugger)) + { + PEPROCESS process = tools::GetProcessByName(processEntry2->FakeParentProcessName); + if (process) + { + entry->InheritedFromUniqueProcessId = PsGetProcessId(process); + ObDereferenceObject(process); + } + + entry->OtherOperationCount.QuadPart = 1; + + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, + "Spoofed NtQuerySystemInformation(ProcessInformation) pid:%d", + HandleToUlong(processEntry->ProcessId)); + } + } + } + + RESTORE_RETURNLENGTH(); + } + else if (SystemInformationClass == SystemHandleInformation) + { + BACKUP_RETURNLENGTH(); + ULONG ReturnLengthAdjust = 0; + + FilterHandleInfo(static_cast(SystemInformation), + &ReturnLengthAdjust); + + if (ReturnLengthAdjust <= TempReturnLength) + { + TempReturnLength -= ReturnLengthAdjust; + } + + RESTORE_RETURNLENGTH(); + + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, + "Spoofed NtQuerySystemInformation(SystemHandleInformation) pid:%d", + HandleToUlong(processEntry->ProcessId)); + } + else if (SystemInformationClass == SystemExtendedHandleInformation) + { + BACKUP_RETURNLENGTH(); + ULONG ReturnLengthAdjust = 0; + + FilterHandleInfoEx(static_cast(SystemInformation), + &ReturnLengthAdjust); + + if (ReturnLengthAdjust <= TempReturnLength) + { + TempReturnLength -= ReturnLengthAdjust; + } + + RESTORE_RETURNLENGTH(); + + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, + "Spoofed NtQuerySystemInformation(SystemExtendedHandleInformation) pid:%d", + HandleToUlong(processEntry->ProcessId)); + } + else if (SystemInformationClass == SystemCodeIntegrityInformation && + BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagHideSystemCodeIntegrity)) + { + BACKUP_RETURNLENGTH(); + + auto systemInformation = static_cast(SystemInformation); + + ULONG options = systemInformation->CodeIntegrityOptions; + + options &= ~CODEINTEGRITY_OPTION_DEBUGMODE_ENABLED; + options &= ~CODEINTEGRITY_OPTION_TESTSIGN; + options |= CODEINTEGRITY_OPTION_ENABLED; + + systemInformation->CodeIntegrityOptions = options; + + RESTORE_RETURNLENGTH(); + + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, + "Spoofed NtQuerySystemInformation(SystemCodeIntegrityInformation) pid:%d", + HandleToUlong(processEntry->ProcessId)); + } + else if (SystemInformationClass == SystemCodeIntegrityUnlockInformation && + BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagHideSystemCodeIntegrity)) + { + BACKUP_RETURNLENGTH(); + + // The size of the buffer for this class changed from 4 to 36, but the output should still + // be all zeroes + RtlSecureZeroMemory(SystemInformation, SystemInformationLength); + + RESTORE_RETURNLENGTH(); + + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, + "Spoofed NtQuerySystemInformation(SystemCodeIntegrityUnlockInformation) pid:%d", + HandleToUlong(processEntry->ProcessId)); + } + else if (SystemInformationClass == SystemKernelDebuggerInformation) + { + auto debuggerInfo = static_cast(SystemInformation); + + BACKUP_RETURNLENGTH(); + + debuggerInfo->KernelDebuggerEnabled = 0; + debuggerInfo->KernelDebuggerNotPresent = 1; + + RESTORE_RETURNLENGTH(); + + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, + "Spoofed NtQuerySystemInformation(SystemKernelDebuggerInformation) pid:%d", + HandleToUlong(processEntry->ProcessId)); + } + else if (SystemInformationClass == SystemKernelDebuggerInformationEx) + { + auto debuggerInfoEx = static_cast(SystemInformation); + + BACKUP_RETURNLENGTH(); + + debuggerInfoEx->DebuggerAllowed = FALSE; + debuggerInfoEx->DebuggerEnabled = FALSE; + debuggerInfoEx->DebuggerPresent = FALSE; + + RESTORE_RETURNLENGTH(); + + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, + "Spoofed NtQuerySystemInformation(SystemKernelDebuggerInformationEx) pid:%d", + HandleToUlong(processEntry->ProcessId)); + } + else if (SystemInformationClass == SystemKernelDebuggerFlags) + { + BACKUP_RETURNLENGTH(); + + *reinterpret_cast(SystemInformation) = 0; + + RESTORE_RETURNLENGTH(); + + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, + "Spoofed NtQuerySystemInformation(SystemKernelDebuggerFlags) pid:%d", + HandleToUlong(processEntry->ProcessId)); + } + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + status = GetExceptionCode(); + } + } + + if (BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagMonitored)) + { + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, + "NtQuerySystemInformation from pid %u SystemInformationClass = %u returned %!STATUS!\n", + HandleToUlong(PsGetCurrentProcessId()), SystemInformationClass, status); + } + } + } + return status; +} + +HWND NTAPI hkNtUserWindowFromPoint(LONG x, LONG y) +{ + PAGED_CODE(); + + const PHOOK_ENTRY hookEntry = FindHookEntry(FNV("NtUserWindowFromPoint")); + const ScopedReferenceGuard lock(&hookEntry->RefCount); + + const HWND resultHwnd = reinterpret_cast(hookEntry->OriginalFunc)(x, y); + + const KPROCESSOR_MODE previousMode = ExGetPreviousMode(); + if (previousMode == UserMode) + { + const HANDLE currentProcessId = PsGetCurrentProcessId(); + PPROCESS_ENTRY processEntry = GetProcessEntry(currentProcessId); + + SCOPE_EXIT + { + if (processEntry) + { + object::DereferenceObject(processEntry); + processEntry = nullptr; + } + }; + + // (1) check if the process is blacklisted (2) check if hook is meant to be intercepted + // + if (processEntry && BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagNtUserWindowFromPoint)) + { + if (BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagHideFromDebugger)) + { + const HANDLE processId = reinterpret_cast( + FindHookEntry(FNV("NtUserQueryWindow"))->OriginalFunc)(resultHwnd, WindowProcess); + if (IsProtectedProcess(processId)) + { + return reinterpret_cast( + FindHookEntry(FNV("NtUserGetThreadState"))->OriginalFunc)(THREADSTATE_ACTIVEWINDOW); + } + } + } + } + return resultHwnd; +} + +HANDLE NTAPI hkNtUserQueryWindow(HWND WindowHandle, WINDOWINFOCLASS WindowInfo) +{ + PAGED_CODE(); + + const PHOOK_ENTRY hookEntry = FindHookEntry(FNV("NtUserQueryWindow")); + const ScopedReferenceGuard lock(&hookEntry->RefCount); + + const KPROCESSOR_MODE previousMode = ExGetPreviousMode(); + if (previousMode == UserMode) + { + const HANDLE currentProcessId = PsGetCurrentProcessId(); + PPROCESS_ENTRY processEntry = GetProcessEntry(currentProcessId); + + SCOPE_EXIT + { + if (processEntry) + { + object::DereferenceObject(processEntry); + processEntry = nullptr; + } + }; + + // (1) check if the process is blacklisted (2) check if hook is meant to be intercepted + // + if (processEntry && BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagNtUserQueryWindow)) + { + if (BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagHideFromDebugger)) + { + // Spoof result if trying to query protected process + // + const HANDLE processId = reinterpret_cast(hookEntry->OriginalFunc)( + WindowHandle, WindowProcess); + if (IsProtectedProcess(processId)) + { + switch (WindowInfo) + { + case WindowProcess: + return PsGetCurrentProcessId(); + case WindowThread: + return PsGetCurrentThreadId(); + + default: + break; + } + } + } + } + } + return reinterpret_cast(hookEntry->OriginalFunc)(WindowHandle, WindowInfo); +} + +HWND NTAPI hkNtUserFindWindowEx(HWND hWndParent, HWND hWndChildAfter, PUNICODE_STRING lpszClass, + PUNICODE_STRING lpszWindow, DWORD dwType) +{ + PAGED_CODE(); + + const PHOOK_ENTRY hookEntry = FindHookEntry(FNV("NtUserFindWindowEx")); + const ScopedReferenceGuard lock(&hookEntry->RefCount); + + const HWND resultHwnd = reinterpret_cast(hookEntry->OriginalFunc)( + hWndParent, hWndChildAfter, lpszClass, lpszWindow, dwType); + + const KPROCESSOR_MODE previousMode = ExGetPreviousMode(); + if (previousMode == UserMode) + { + const HANDLE currentProcessId = PsGetCurrentProcessId(); + PPROCESS_ENTRY processEntry = GetProcessEntry(currentProcessId); + + SCOPE_EXIT + { + if (processEntry) + { + object::DereferenceObject(processEntry); + processEntry = nullptr; + } + }; + + // (1) check if the process is blacklisted (2) check if hook is meant to be intercepted + // + if (resultHwnd && + (processEntry && BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagNtUserFindWindowEx))) + { + if (BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagHideFromDebugger)) + { + // Spoof result if trying to query protected process + // + const HANDLE processId = reinterpret_cast( + FindHookEntry(FNV("NtUserQueryWindow"))->OriginalFunc)(resultHwnd, WindowProcess); + if (IsProtectedProcess(processId)) + { + return 0; + } + } + } + } + return resultHwnd; +} + +void FilterHwndList(HWND *phwndFirst, PULONG pcHwndNeeded) +{ + for (UINT i = 0; i < *pcHwndNeeded; i++) + { + // Spoof result if trying to query protected process + // + HANDLE processId = reinterpret_cast( + FindHookEntry(FNV("NtUserQueryWindow"))->OriginalFunc)(phwndFirst[i], WindowProcess); + + if (phwndFirst[i] != nullptr && IsProtectedProcess(processId)) + { + if (i == 0) + { + // Find the first HWND that belongs to a different process (i + 1, i + 2... may still be ours) + for (UINT j = i + 1; j < *pcHwndNeeded; j++) + { + processId = reinterpret_cast( + FindHookEntry(FNV("NtUserQueryWindow"))->OriginalFunc)(phwndFirst[j], WindowProcess); + + if (phwndFirst[j] != nullptr && !IsProtectedProcess(processId)) + { + phwndFirst[i] = phwndFirst[j]; + break; + } + } + } + else + { + phwndFirst[i] = phwndFirst[i - 1]; // just override with previous + } + } + } +} + +NTSTATUS NTAPI hkNtUserBuildHwndList_Win7(HDESK hdesk, HWND hwndNext, ULONG fEnumChildren, DWORD idThread, + UINT cHwndMax, HWND *phwndFirst, ULONG *pcHwndNeeded) +{ + PAGED_CODE(); + + const PHOOK_ENTRY hookEntry = FindHookEntry(FNV("NtUserBuildHwndList")); + const ScopedReferenceGuard lock(&hookEntry->RefCount); + + const NTSTATUS status = reinterpret_cast(hookEntry->OriginalFunc)( + hdesk, hwndNext, fEnumChildren, idThread, cHwndMax, phwndFirst, pcHwndNeeded); + + const KPROCESSOR_MODE previousMode = ExGetPreviousMode(); + if (previousMode == UserMode) + { + if (NT_SUCCESS(status) && phwndFirst && pcHwndNeeded) + { + const HANDLE currentProcessId = PsGetCurrentProcessId(); + PPROCESS_ENTRY processEntry = GetProcessEntry(currentProcessId); + + SCOPE_EXIT + { + if (processEntry) + { + object::DereferenceObject(processEntry); + processEntry = nullptr; + } + }; + + // (1) check if the process is blacklisted (2) check if hook is meant to be intercepted + // + if (processEntry && BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagNtUserBuildHwndList)) + { + if (BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagHideFromDebugger)) + { + FilterHwndList(phwndFirst, pcHwndNeeded); + } + } + } + } + return status; +} + +NTSTATUS NTAPI hkNtUserBuildHwndList(HDESK hDesktop, HWND hwndParent, BOOLEAN bChildren, BOOLEAN bUnknownFlag, + ULONG dwThreadId, ULONG lParam, HWND *pWnd, PULONG pBufSize) +{ + PAGED_CODE(); + + const PHOOK_ENTRY hookEntry = FindHookEntry(FNV("NtUserBuildHwndList")); + const ScopedReferenceGuard lock(&hookEntry->RefCount); + + const NTSTATUS status = reinterpret_cast(hookEntry->OriginalFunc)( + hDesktop, hwndParent, bChildren, bUnknownFlag, dwThreadId, lParam, pWnd, pBufSize); + + const KPROCESSOR_MODE previousMode = ExGetPreviousMode(); + if (previousMode == UserMode) + { + if (NT_SUCCESS(status) && pWnd && pBufSize) + { + const HANDLE currentProcessId = PsGetCurrentProcessId(); + PPROCESS_ENTRY processEntry = GetProcessEntry(currentProcessId); + + SCOPE_EXIT + { + if (processEntry) + { + object::DereferenceObject(processEntry); + processEntry = nullptr; + } + }; + + // (1) check if the process is blacklisted (2) check if hook is meant to be intercepted + // + if (processEntry && BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagNtUserBuildHwndList)) + { + if (BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagHideFromDebugger)) + { + FilterHwndList(pWnd, pBufSize); + } + } + } + } + return status; +} + +HWND NTAPI hkNtUserGetForegroundWindow(VOID) +{ + PAGED_CODE(); + + const PHOOK_ENTRY hookEntry = FindHookEntry(FNV("NtUserGetForegroundWindow")); + const ScopedReferenceGuard lock(&hookEntry->RefCount); + + const HWND resultHwnd = reinterpret_cast(hookEntry->OriginalFunc)(); + + const KPROCESSOR_MODE previousMode = ExGetPreviousMode(); + if (previousMode == UserMode) + { + const HANDLE currentProcessId = PsGetCurrentProcessId(); + PPROCESS_ENTRY processEntry = GetProcessEntry(currentProcessId); + + SCOPE_EXIT + { + if (processEntry) + { + object::DereferenceObject(processEntry); + processEntry = nullptr; + } + }; + + // (1) check if the process is blacklisted (2) check if hook is meant to be intercepted + // + if (processEntry && BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagNtUserGetForegroundWindow)) + { + if (BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagHideFromDebugger)) + { + // Spoof result if trying to query protected process + // + const HANDLE processId = reinterpret_cast( + FindHookEntry(FNV("NtUserQueryWindow"))->OriginalFunc)(resultHwnd, WindowProcess); + if (IsProtectedProcess(processId)) + { + return reinterpret_cast( + FindHookEntry(FNV("NtUserGetThreadState"))->OriginalFunc)(THREADSTATE_ACTIVEWINDOW); + } + } + } + } + return resultHwnd; +} +} // namespace hooks +} // namespace masterhide \ No newline at end of file diff --git a/MasterHide/hooks.hpp b/MasterHide/hooks.hpp new file mode 100644 index 0000000..94b366e --- /dev/null +++ b/MasterHide/hooks.hpp @@ -0,0 +1,110 @@ +#pragma once + +namespace masterhide +{ +namespace hooks +{ +/// +/// Initialize hooks. +/// +/// STATUS_SUCCESS on success, otherwise any NTSTATUS value +NTSTATUS Initialize(); + +/// +/// De-initialize hooks. +/// +void Deinitialize(); + +// SSDT hooks +// +NTSTATUS NTAPI hkNtQuerySystemInformation(SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID Buffer, ULONG Length, + PULONG ReturnLength); +NTSTATUS NTAPI hkNtSetInformationThread(HANDLE ThreadHandle, THREADINFOCLASS ThreadInformationClass, + PVOID ThreadInformation, ULONG ThreadInformationLength); +NTSTATUS NTAPI hkNtQueryInformationProcess(HANDLE ProcessHandle, PROCESSINFOCLASS ProcessInformationClass, + PVOID ProcessInformation, ULONG ProcessInformationLength, + PULONG ReturnLength); +NTSTATUS NTAPI hkNtSetInformationProcess(HANDLE ProcessHandle, PROCESSINFOCLASS ProcessInformationClass, + PVOID ProcessInformation, ULONG ProcessInformationLength); +NTSTATUS NTAPI hkNtQueryInformationThread(HANDLE ThreadHandle, THREADINFOCLASS ThreadInformationClass, + PVOID ThreadInformation, ULONG ThreadInformationLength, PULONG ReturnLength); +NTSTATUS NTAPI hkNtQueryObject(HANDLE Handle, OBJECT_INFORMATION_CLASS ObjectInformationClass, PVOID ObjectInformation, + ULONG ObjectInformationLength, PULONG ReturnLength); +NTSTATUS NTAPI hkNtCreateThreadEx(PHANDLE ThreadHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, + HANDLE ProcessHandle, PVOID StartRoutine, PVOID Argument, ULONG CreateFlags, + SIZE_T ZeroBits, SIZE_T StackSize, SIZE_T MaximumStackSize, PVOID AttributeList); +NTSTATUS NTAPI hkNtGetContextThread(HANDLE ThreadHandle, PCONTEXT ThreadContext); +NTSTATUS NTAPI hkNtSetContextThread(HANDLE ThreadHandle, PCONTEXT ThreadContext); +NTSTATUS NTAPI hkNtContinue(PCONTEXT Context, ULONG64 TestAlert); +NTSTATUS NTAPI hkNtYieldExecution(); +NTSTATUS NTAPI hkNtClose(HANDLE Handle); +NTSTATUS NTAPI hkNtSystemDebugControl(SYSDBG_COMMAND Command, PVOID InputBuffer, ULONG InputBufferLength, + PVOID OutputBuffer, ULONG OutputBufferLength, PULONG ReturnLength); +NTSTATUS NTAPI hkNtQuerySystemTime(PLARGE_INTEGER SystemTime); +NTSTATUS NTAPI hkNtQueryPerformanceCounter(PLARGE_INTEGER PerformanceCounter, PLARGE_INTEGER PerformanceFrequency); +NTSTATUS NTAPI hkNtQueryInformationJobObject(HANDLE JobHandle, JOBOBJECTINFOCLASS JobInformationClass, + PVOID JobInformation, ULONG JobInformationLength, PULONG ReturnLength); +NTSTATUS NTAPI hkNtGetNextProcess(HANDLE ProcessHandle, ACCESS_MASK DesiredAccess, ULONG HandleAttributes, ULONG Flags, + PHANDLE NewProcessHandle); +NTSTATUS NTAPI hkNtCreateUserProcess(PHANDLE ProcessHandle, PHANDLE ThreadHandle, ACCESS_MASK ProcessDesiredAccess, + ACCESS_MASK ThreadDesiredAccess, POBJECT_ATTRIBUTES ProcessObjectAttributes, + POBJECT_ATTRIBUTES ThreadObjectAttributes, ULONG ProcessFlags, ULONG ThreadFlags, + PRTL_USER_PROCESS_PARAMETERS ProcessParameters, + PVOID CreateInfo, // PPS_CREATE_INFO + PVOID AttributeList // PPS_ATTRIBUTE_LIST +); + +// Shadow SSDT hooks +// +HWND hkNtUserWindowFromPoint(LONG x, LONG y); +HANDLE hkNtUserQueryWindow(HWND WindowHandle, WINDOWINFOCLASS WindowInfo); +HWND NTAPI hkNtUserFindWindowEx(HWND hWndParent, HWND hWndChildAfter, PUNICODE_STRING lpszClass, + PUNICODE_STRING lpszWindow, DWORD dwType); +NTSTATUS NTAPI hkNtUserBuildHwndList_Win7(HDESK hdesk, HWND hwndNext, ULONG fEnumChildren, DWORD idThread, + UINT cHwndMax, HWND *phwndFirst, ULONG *pcHwndNeeded); +NTSTATUS NTAPI hkNtUserBuildHwndList(HDESK hDesktop, HWND hwndParent, BOOLEAN bChildren, BOOLEAN bUnknownFlag, + ULONG dwThreadId, ULONG lParam, HWND *pWnd, PULONG pBufSize); +HWND NTAPI hkNtUserGetForegroundWindow(VOID); +HWND NTAPI NtUserGetThreadState(ThreadStateRoutines Routine); + +typedef struct _HOOK_ENTRY +{ + KEVENT Event; + PVOID OriginalFunc; + PVOID NewFunc; + CHAR ServiceName[64]; + BOOLEAN Win32k; + ReferenceGuard RefCount; + USHORT ServiceIndex; + UCHAR OriginalBytes[12]; + + _HOOK_ENTRY() + { + RtlZeroMemory(this, sizeof(*this)); + } + + constexpr _HOOK_ENTRY(const char *serviceName, BOOLEAN win32k, PVOID newFunc) + : Event{}, OriginalFunc(nullptr), NewFunc(newFunc), Win32k(win32k), RefCount{}, ServiceIndex(MAXUSHORT), + OriginalBytes{} + { + size_t length = 0; + + while (serviceName[length] != '\0' && length < ARRAYSIZE(ServiceName) - 1) + { + ServiceName[length] = serviceName[length]; + ++length; + } + + ServiceName[length] = '\0'; + + for (size_t i = length + 1; i < sizeof(ServiceName); ++i) + { + ServiceName[i] = '\0'; + } + } + +} HOOK_ENTRY, *PHOOK_ENTRY; + +extern HOOK_ENTRY g_HookList[]; +} // namespace hooks +} // namespace masterhide \ No newline at end of file diff --git a/MasterHide/includes.hpp b/MasterHide/includes.hpp new file mode 100644 index 0000000..47436cc --- /dev/null +++ b/MasterHide/includes.hpp @@ -0,0 +1,57 @@ +#pragma once + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "thirdparty/scope_guard/include/scope_guard.hpp" + +#ifdef __cplusplus +extern "C" +{ +#endif +#include +#include +#include +#include "ntfill.hpp" +#ifdef __cplusplus +} +#endif + +#ifndef DBGPRINT +#if DBG +#define DBGPRINT(x, ...) DbgPrintEx(NULL, NULL, "[MasterHide] " x "\n", __VA_ARGS__); +#else +#define DBGPRINT(...) +#endif +#endif + +#include "kaspersky.hpp" +#include "infinityhook.hpp" + +#include "..\shared\shared.hpp" + +#include "fnv1a.hpp" +#include "wpp_trace.hpp" +#include "dyn.hpp" +#include "tools.hpp" +#include "callbacks.hpp" +#include "syscalls.hpp" +#include "utils.hpp" +#include "object.hpp" +#include "process.hpp" +#include "hooks.hpp" + +using namespace masterhide; \ No newline at end of file diff --git a/MasterHide/infinityhook.cpp b/MasterHide/infinityhook.cpp new file mode 100644 index 0000000..6ef6dfc --- /dev/null +++ b/MasterHide/infinityhook.cpp @@ -0,0 +1,461 @@ +#include "includes.hpp" + +NTSTATUS InitializeInfinityHook(_In_ SSDT_CALLBACK ssdtCallback) +{ + PAGED_CODE(); + NT_ASSERT(ssdtCallback); + + g_SsdtCallback = ssdtCallback; + + NTSTATUS status; + + ModifyTraceSettings(CKCL_TRACE_END); + + status = ModifyTraceSettings(CKCL_TRACE_SYSCALL); + if (!NT_SUCCESS(status)) + { + status = ModifyTraceSettings(CKCL_TRACE_START); + if (!NT_SUCCESS(status)) + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, + "ModifyTraceSettings(CKCL_TRACE_START) " + "failed %!STATUS!", + status); + + return status; + } + + status = ModifyTraceSettings(CKCL_TRACE_SYSCALL); + if (!NT_SUCCESS(status)) + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, + "ModifyTraceSettings(CKCL_TRACE_SYSCALL) " + "failed %!STATUS!", + status); + + return status; + } + } + + ULONG_PTR EtwpDebuggerData = dyn::DynCtx.Kernel.EtwpDebuggerData; + DBGPRINT("EtwpDebuggerData = 0x%p", (void *)EtwpDebuggerData); + + auto *EtwpDebuggerDataSilo = *reinterpret_cast(PTR_OFFSET_ADD(EtwpDebuggerData, 0x10)); + DBGPRINT("EtwpDebuggerDataSilo = 0x%p", EtwpDebuggerDataSilo); + + if (!MmIsAddressValid(EtwpDebuggerDataSilo)) + { + return STATUS_UNSUCCESSFUL; + } + + ULONG_PTR CkclWmiLoggerContext = EtwpDebuggerDataSilo[2]; + DBGPRINT("CkclWmiLoggerContext = 0x%p", (void *)CkclWmiLoggerContext); + + if (!CkclWmiLoggerContext) + { + return STATUS_UNSUCCESSFUL; + } + + g_GetCpuClock = dyn::DynCtx.GetCpuClock(CkclWmiLoggerContext); + DBGPRINT("g_GetCpuClock = 0x%p", g_GetCpuClock); + + if (!MmIsAddressValid(g_GetCpuClock)) + { + return STATUS_UNSUCCESSFUL; + } + + PVOID syscallEntry = GetSyscallEntry(); + DBGPRINT("syscallEntry = 0x%p", syscallEntry); + + if (!syscallEntry) + { + return STATUS_UNSUCCESSFUL; + } + + g_SyscallTableAddress = PAGE_ALIGN(syscallEntry); + DBGPRINT("g_SyscallTableAddress = 0x%p", g_SyscallTableAddress); + + if (!g_SyscallTableAddress) + { + return STATUS_UNSUCCESSFUL; + } + + return StartSyscallHook() ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL; +} + +void DeinitializeInfinityHook() +{ + if (g_WatchdogThreadHandle) + { + g_WatchdogSignal = TRUE; + + // Wait for thread to terminate + // + ZwWaitForSingleObject(g_WatchdogThreadHandle, FALSE, nullptr); + ZwClose(g_WatchdogThreadHandle); + g_WatchdogThreadHandle = nullptr; + } + + if (g_GetCpuClock) + { + InterlockedExchangePointer(g_GetCpuClock, g_GetCpuClockOriginal); + } + + if (g_HvlGetQpcBias) + { + InterlockedExchangePointer(g_HvlGetQpcBias, g_HvlGetQpcBiasOriginal); + } + + // Restart trace session to ensure cleanup + // + NTSTATUS Status = ModifyTraceSettings(CKCL_TRACE_END); + if (NT_SUCCESS(Status)) + { + ModifyTraceSettings(CKCL_TRACE_START); + } + + DBGPRINT("Deinitialized infinityhook"); +} + +VOID WatchdogThread(_In_ PVOID StartContext) +{ + UNREFERENCED_PARAMETER(StartContext); + + DBGPRINT("Created watchdog thread for infinityhook"); + + while (!g_WatchdogSignal) + { + // This will ensure infinityhook is still active all the time + // + if (dyn::DynCtx.Kernel.BuildVersion <= WINDOWS_10_VERSION_19H2) + { + if (g_GetCpuClock && MmIsAddressValid(g_GetCpuClock)) + { + // GetCpuClock is a pointer before build 2004 + // + PVOID oldValue = + InterlockedCompareExchangePointer(g_GetCpuClock, &SyscallHookHandler, g_GetCpuClockOriginal); + if (oldValue == g_GetCpuClockOriginal) + { + g_GetCpuClockOriginal = oldValue; + } + } + } + else + { + if (g_GetCpuClock && MmIsAddressValid(g_GetCpuClock)) + { + // GetCpuClock is a variable starting build 2004, by changing GetCpuClock to 2 we're telling to use + // HvlGetQpcBias internally + // + PVOID oldValue = InterlockedCompareExchangePointer(g_GetCpuClock, ULongToPtr(2), g_GetCpuClockOriginal); + if (oldValue == g_GetCpuClockOriginal) + { + g_GetCpuClockOriginal = oldValue; + } + } + + if (g_HvlGetQpcBias && MmIsAddressValid(g_HvlGetQpcBias)) + { + PVOID oldValue = + InterlockedCompareExchangePointer(g_HvlGetQpcBias, &hkHvlGetQpcBias, g_HvlGetQpcBiasOriginal); + if (oldValue == g_HvlGetQpcBiasOriginal) + { + g_HvlGetQpcBiasOriginal = oldValue; + } + } + } + + tools::DelayThread(512); + } + + DBGPRINT("Exiting watchdog thread for infinityhook"); + + PsTerminateSystemThread(STATUS_SUCCESS); +} + +BOOLEAN +StartSyscallHook(VOID) +{ + PAGED_CODE(); + + if (!g_GetCpuClock || !MmIsAddressValid(g_GetCpuClock)) + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "Invalid g_GetCpuClock!"); + return FALSE; + } + + if (dyn::DynCtx.Kernel.BuildVersion <= WINDOWS_10_VERSION_19H2) + { + g_GetCpuClockOriginal = InterlockedExchangePointer(g_GetCpuClock, &SyscallHookHandler); + + DBGPRINT("g_GetCpuClock = 0x%p", g_GetCpuClock); + DBGPRINT("g_GetCpuClockOriginal = 0x%p", g_GetCpuClockOriginal); + } + else + { + g_GetCpuClockOriginal = InterlockedExchangePointer(g_GetCpuClock, ULongToPtr(2)); + + DBGPRINT("g_GetCpuClock = 0x%p", g_GetCpuClock); + DBGPRINT("g_GetCpuClockOriginal = 0x%p", g_GetCpuClockOriginal); + + ULONG_PTR HvlpReferenceTscPage = dyn::DynCtx.Kernel.HvlpReferenceTscPage; + + g_HvlpReferenceTscPage = tools::RipToAbsolute(HvlpReferenceTscPage, 3, 7); + DBGPRINT("g_HvlpReferenceTscPage = 0x%p", g_HvlpReferenceTscPage); + + ULONG_PTR HvlGetQpcBias = dyn::DynCtx.Kernel.HvlGetQpcBias; + + g_HvlGetQpcBias = tools::RipToAbsolute(HvlGetQpcBias, 3, 7); + DBGPRINT("g_HvlGetQpcBias = 0x%p", g_HvlGetQpcBias); + + g_HvlGetQpcBiasOriginal = InterlockedExchangePointer(g_HvlGetQpcBias, &hkHvlGetQpcBias); + DBGPRINT("g_HvlGetQpcBiasOriginal = 0x%p", g_HvlGetQpcBiasOriginal); + } + + const NTSTATUS status = PsCreateSystemThread(&g_WatchdogThreadHandle, THREAD_ALL_ACCESS, nullptr, nullptr, nullptr, + &WatchdogThread, nullptr); + if (!NT_SUCCESS(status)) + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "PsCreateSystemThread returned %!STATUS!", status); + + DeinitializeInfinityHook(); + return FALSE; + } + + return TRUE; +} + +NTSTATUS +ModifyTraceSettings(_In_ const CKCL_TRACE_OPERATION &traceOperation) +{ + PAGED_CODE(); + + auto traceProperty = tools::AllocatePoolZero(NonPagedPool, PAGE_SIZE, tags::TAG_DEFAULT); + if (!traceProperty) + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, + "Could not allocate " + "memory for trace properties!"); + + return STATUS_INSUFFICIENT_RESOURCES; + } + + SCOPE_EXIT + { + ExFreePool(traceProperty); + }; + + auto providerName = tools::AllocatePoolZero(NonPagedPool, 0x1000, tags::TAG_STRING); + if (!providerName) + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, + "Could not allocate " + "memory for provider name!"); + + return STATUS_INSUFFICIENT_RESOURCES; + } + + SCOPE_EXIT + { + ExFreePool(providerName); + }; + + NTSTATUS status = RtlStringCchCopyW(providerName, 0x1000 / sizeof(wchar_t), L"Circular Kernel Context Logger"); + if (!providerName) + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "RtlStringCchCopyW failed %!STATUS!", status); + + return status; + } + + RtlInitUnicodeString(&traceProperty->ProviderName, providerName); + traceProperty->Wnode.BufferSize = PAGE_SIZE; + traceProperty->Wnode.Flags = WNODE_FLAG_TRACED_GUID; + traceProperty->Wnode.Guid = CkclSessionGuid; + traceProperty->Wnode.ClientContext = 1; + traceProperty->BufferSize = sizeof(ULONG); + traceProperty->MinimumBuffers = traceProperty->MaximumBuffers = 2; + traceProperty->LogFileMode = EVENT_TRACE_BUFFERING_MODE; + + status = STATUS_ACCESS_DENIED; + ULONG returnLength = 0UL; + + KPROCESSOR_MODE origMode = ExGetPreviousMode(); + if (origMode == UserMode) + { + tools::SetPreviousMode(KernelMode); + } + + switch (traceOperation) + { + case CKCL_TRACE_START: { + status = NtTraceControl(EtwpStartTrace, traceProperty, PAGE_SIZE, traceProperty, PAGE_SIZE, &returnLength); + break; + } + case CKCL_TRACE_END: { + status = NtTraceControl(EtwpStopTrace, traceProperty, PAGE_SIZE, traceProperty, PAGE_SIZE, &returnLength); + break; + } + case CKCL_TRACE_SYSCALL: { + traceProperty->EnableFlags = EVENT_TRACE_FLAG_SYSTEMCALL; + status = NtTraceControl(EtwpUpdateTrace, traceProperty, PAGE_SIZE, traceProperty, PAGE_SIZE, &returnLength); + break; + } + } + + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, "NtTraceControl returned %!STATUS! retLength: %u", status, + returnLength); + + tools::SetPreviousMode(origMode); + return status; +} + +PVOID GetSyscallEntry() +{ + PAGED_CODE(); + + PIMAGE_NT_HEADERS64 nth = RtlImageNtHeader(dyn::DynCtx.Kernel.Base); + if (!nth) + { + return nullptr; + } + + PVOID syscallEntry = reinterpret_cast(__readmsr(IA32_LSTAR_MSR)); + + // If KVASCODE section does not exists it probably means the system does not support it. + // + PIMAGE_SECTION_HEADER section = tools::GetModuleSection(nth, "KVASCODE"); + if (!section) + { + return syscallEntry; + } + + const PVOID sectionBase = reinterpret_cast(dyn::DynCtx.Kernel.Base) + section->VirtualAddress; + const ULONG sectionSize = section->Misc.VirtualSize; + + // Is the value within this KVA shadow region? If not, we're done. + // + if (!(syscallEntry >= sectionBase && syscallEntry < reinterpret_cast(sectionBase) + sectionSize)) + { + return syscallEntry; + } + + // This is KiSystemCall64Shadow. + // + hde64s hde{}; + int totalBytesRead = 0; + + for (PUCHAR KiSystemServiceUser = reinterpret_cast(syscallEntry); /* */; + KiSystemServiceUser, totalBytesRead += hde.len) + { + // Note: This jump should not be very far in theory so lets just try the next 512 bytes + // + if (totalBytesRead >= 512 || !hde64_disasm(KiSystemServiceUser, &hde)) + { + break; + } + + // Disassemble every instruction till the first near jmp (E9). + // + if (hde.opcode != 0xE9) + { + continue; + } + + // Ignore jmps within the KVA shadow region. + // + syscallEntry = KiSystemServiceUser + static_cast(hde.len) + static_cast(hde.imm.imm32); + if (syscallEntry >= sectionBase && syscallEntry < reinterpret_cast(sectionBase) + sectionSize) + { + continue; + } + + // Found KiSystemServiceUser. + // + return syscallEntry; + } + return nullptr; +} + +ULONG64 +SyscallHookHandler(VOID) +{ +#define INFINITYHOOK_MAGIC_1 ((ULONG)0x501802) +#define INFINITYHOOK_MAGIC_2 ((USHORT)0xF33) + + if (ExGetPreviousMode() == KernelMode) + { + return __rdtsc(); + } + + const auto currentThread = reinterpret_cast(KeGetCurrentThread()); + const auto systemCallIndex = *(ULONG *)(currentThread + dyn::DynCtx.Offsets.SystemCallNumber); + + const auto stackMax = __readgsqword(KPCR_RSP_BASE); + const PVOID *stackFrame = (PVOID *)_AddressOfReturnAddress(); + + UINT offset = 0; + + // First walk backwards on the stack to find the 2 magic values. + for (PVOID *stackCurrent = (PVOID *)stackMax; stackCurrent > stackFrame; --stackCurrent) + { + PULONG AsUlong = (PULONG)stackCurrent; + if (*AsUlong != INFINITYHOOK_MAGIC_1) + { + continue; + } + + // If the first magic is set, check for the second magic. + --stackCurrent; + + PUSHORT AsShort = (PUSHORT)stackCurrent; + if (*AsShort != INFINITYHOOK_MAGIC_2) + { + continue; + } + + // Now we reverse the direction of the stack walk. + for (; (ULONG_PTR)stackCurrent < stackMax; ++stackCurrent) + { + PULONGLONG AsUlonglong = (PULONGLONG)stackCurrent; + + if (!(PAGE_ALIGN(*AsUlonglong) >= g_SyscallTableAddress && + PAGE_ALIGN(*AsUlonglong) < (PVOID)((uintptr_t)g_SyscallTableAddress + (PAGE_SIZE * 2)))) + { + continue; + } + + offset = (UINT)((ULONG_PTR)stackCurrent - (ULONG_PTR)stackFrame); + break; + } + + break; + } + + if (offset) + { + PVOID *stackCurrent = (PVOID *)((ULONG_PTR)stackFrame + offset); + + if (*(ULONG_PTR *)stackCurrent >= (ULONG_PTR)g_SyscallTableAddress && + *(ULONG_PTR *)stackCurrent < ((ULONG_PTR)g_SyscallTableAddress + (PAGE_SIZE * 2))) + { + PVOID *systemCallFunction = &stackCurrent[9]; + + if (g_SsdtCallback) + { + g_SsdtCallback(systemCallIndex, systemCallFunction); + } + } + } + + return __rdtsc(); +} + +ULONG64 +hkHvlGetQpcBias(VOID) +{ + SyscallHookHandler(); + + return *((ULONG64 *)(*((ULONG64 *)g_HvlpReferenceTscPage)) + 3); +} \ No newline at end of file diff --git a/MasterHide/infinityhook.hpp b/MasterHide/infinityhook.hpp new file mode 100644 index 0000000..70a94d3 --- /dev/null +++ b/MasterHide/infinityhook.hpp @@ -0,0 +1,91 @@ +#pragma once + +#include +#include +#include "hde\hde64.h" + +#define IA32_LSTAR_MSR 0xC0000082 +#define KPCR_RSP_BASE 0x1A8 + +#define EtwpStartTrace 1 +#define EtwpStopTrace 2 +#define EtwpQueryTrace 3 +#define EtwpUpdateTrace 4 +#define EtwpFlushTrace 5 + +typedef struct _EVENT_TRACE_PROPERTIES +{ + WNODE_HEADER Wnode; + ULONG BufferSize; + ULONG MinimumBuffers; + ULONG MaximumBuffers; + ULONG MaximumFileSize; + ULONG LogFileMode; + ULONG FlushTimer; + ULONG EnableFlags; + union { + LONG AgeLimit; + LONG FlushThreshold; + } DUMMYUNIONNAME; + ULONG NumberOfBuffers; + ULONG FreeBuffers; + ULONG EventsLost; + ULONG BuffersWritten; + ULONG LogBuffersLost; + ULONG RealTimeBuffersLost; + HANDLE LoggerThreadId; + ULONG LogFileNameOffset; + ULONG LoggerNameOffset; + +} EVENT_TRACE_PROPERTIES, *PEVENT_TRACE_PROPERTIES; + +/* 54dea73a-ed1f-42a4-af713e63d056f174 */ +const GUID CkclSessionGuid = {0x54dea73a, 0xed1f, 0x42a4, {0xaf, 0x71, 0x3e, 0x63, 0xd0, 0x56, 0xf1, 0x74}}; + +enum CKCL_TRACE_OPERATION +{ + CKCL_TRACE_START, + CKCL_TRACE_SYSCALL, + CKCL_TRACE_END +}; + +typedef struct _CKCL_TRACE_PROPERIES : EVENT_TRACE_PROPERTIES +{ + ULONG64 Unknown[3]; + UNICODE_STRING ProviderName; + +} CKCL_TRACE_PROPERTIES, *PCKCL_TRACE_PROPERTIES; + +typedef VOID(__fastcall *SSDT_CALLBACK)(ULONG, PVOID *); + +inline HANDLE g_WatchdogThreadHandle = nullptr; +inline BOOLEAN g_WatchdogSignal = FALSE; + +inline SSDT_CALLBACK g_SsdtCallback = NULL; +inline PVOID g_SyscallTableAddress = nullptr; + +inline PVOID *g_GetCpuClock = nullptr; +inline PVOID *g_HvlpReferenceTscPage = nullptr; +inline PVOID *g_HvlGetQpcBias = nullptr; + +inline PVOID g_HvlGetQpcBiasOriginal = nullptr; +inline PVOID g_GetCpuClockOriginal = nullptr; + +PVOID GetSyscallEntry(); + +ULONG64 +hkHvlGetQpcBias(VOID); + +BOOLEAN +StartSyscallHook(VOID); + +ULONG64 +SyscallHookHandler(VOID); + +VOID WatchdogThread(_In_ PVOID StartContext); + +NTSTATUS +ModifyTraceSettings(_In_ const CKCL_TRACE_OPERATION &TraceOperation); + +NTSTATUS InitializeInfinityHook(_In_ SSDT_CALLBACK ssdtCallback); +void DeinitializeInfinityHook(); \ No newline at end of file diff --git a/MasterHide/main.cpp b/MasterHide/main.cpp deleted file mode 100644 index de7745e..0000000 --- a/MasterHide/main.cpp +++ /dev/null @@ -1,116 +0,0 @@ -#include "stdafx.h" - -void OnDriverUnload( PDRIVER_OBJECT pDriverObject ) -{ - UNREFERENCED_PARAMETER( pDriverObject ); - - ssdt::Destroy(); - sssdt::Destroy(); - - // - // Delay the execution for a second to make sure no thread is executing the hooked function - // - LARGE_INTEGER LargeInteger{ }; - LargeInteger.QuadPart = -11000000; - - KeDelayExecutionThread( KernelMode, FALSE, &LargeInteger ); - tools::UnloadImages(); - - DBGPRINT( "Driver unload routine triggered!\n" ); -} - -extern "C" NTSTATUS NTAPI DriverEntry( PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath ) -{ - UNREFERENCED_PARAMETER( pRegistryPath ); - - if ( !pDriverObject ) - { - DBGPRINT( "Err: No driver object!\n" ); - return STATUS_FAILED_DRIVER_ENTRY; - } - - RTL_OSVERSIONINFOW os{ }; - os.dwOSVersionInfoSize = sizeof( os ); - - if ( !NT_SUCCESS( RtlGetVersion( &os ) ) ) - { - DBGPRINT( "Err: RtlGetVersion failed!\n" ); - return STATUS_FAILED_DRIVER_ENTRY; - } - - pDriverObject->DriverUnload = &OnDriverUnload; - DBGPRINT( "Driver loaded!\n" ); - - // - // If the OS is either Windows 10, 8/8.1 those are the only supported OS - // - bool bIsWin7 = ( os.dwMajorVersion == 6 && os.dwMinorVersion == 1 ); - - if ( os.dwMajorVersion == 10 || ( bIsWin7 || ( os.dwMajorVersion == 6 && os.dwMinorVersion == 2 ) || ( os.dwMajorVersion == 6 && os.dwMinorVersion == 3 ) ) ) - { - // This special API only works in Win8+ and it basically allows you to set no executable flag in NonPagedPools - ExInitializeDriverRuntime( DrvRtPoolNxOptIn ); - - // - // Sycalls numbers are OS based, since user32.dll doesnt export them in early Windows versions ( Win7 for example ) we hardcode them and extract them on newer - // systems that export it ( Win8+ for example in win32u.dll ) - // - if ( !bIsWin7 ) - { - SYSCALL_NTUSERQUERYWND = tools::GetWin32Syscall( "NtUserQueryWindow" ); - SYSCALL_NTUSERFINDWNDEX = tools::GetWin32Syscall( "NtUserFindWindowEx" ); - SYSCALL_NTUSERWNDFROMPOINT = tools::GetWin32Syscall( "NtUserWindowFromPoint" ); - SYSCALL_NTUSERBUILDWNDLIST = tools::GetWin32Syscall( "NtUserBuildHwndList" ); - SYSCALL_NTGETFOREGROUNDWND = tools::GetWin32Syscall( "NtUserGetForegroundWindow" ); - - SYSCALL_NTOPENPROCESS = tools::GetNtSyscall( "NtOpenProcess" ); - SYSCALL_NTDEVICEIOCTRLFILE = tools::GetNtSyscall( "NtDeviceIoControlFile" ); - SYSCALL_NTQUERYSYSINFO = tools::GetNtSyscall( "NtQuerySystemInformation" ); - SYSCALL_NTALLOCVIRTUALMEM = tools::GetNtSyscall( "NtAllocateVirtualMemory" ); - SYSCALL_NTFREEVIRTUALMEM = tools::GetNtSyscall( "NtFreeVirtualMemory" ); - SYSCALL_NTWRITEVIRTUALMEM = tools::GetNtSyscall( "NtWriteVirtualMemory" ); - SYSCALL_NTLOADDRIVER = tools::GetNtSyscall( "NtLoadDriver" ); - } - -#ifndef USE_KASPERSKY - // - // (S)SSDT Hooks are only Win7 compatible ( hardcoded ) - // - DBGPRINT( "Not using Kaspersky to hook, Shadow SSDT is unstable!\n" ); -#else - DBGPRINT( "Using Kaspersky!\n" ); - - if ( !kaspersky::is_klhk_loaded() ) - { - tools::UnloadImages(); - DBGPRINT( "Kaspersky not loaded!\n" ); - return STATUS_UNSUCCESSFUL; - } - - if ( !kaspersky::initialize() ) - { - tools::UnloadImages(); - DBGPRINT( "Kaspersky init failed!\n" ); - return STATUS_UNSUCCESSFUL; - } - - DBGPRINT( "Using Kaspersky hypervisor!\n" ); - - if ( !kaspersky::hvm_init() ) - { - tools::UnloadImages(); - DBGPRINT( "Hypervisor not loaded!\n" ); - return STATUS_UNSUCCESSFUL; - } - - DBGPRINT( "Hypervisor loaded!\n" ); -#endif - ssdt::Init(); - sssdt::Init(); - } - else - // No support for other OS - return STATUS_NOT_SUPPORTED; - - return STATUS_SUCCESS; -} \ No newline at end of file diff --git a/MasterHide/mh_hooks.cpp b/MasterHide/mh_hooks.cpp deleted file mode 100644 index c1c72f3..0000000 --- a/MasterHide/mh_hooks.cpp +++ /dev/null @@ -1,832 +0,0 @@ -#include "stdafx.h" - -namespace masterhide -{ - namespace tools - { - bool IsProtectedProcess( HANDLE PID ) - { - UNICODE_STRING wsProcName{ }; - if ( !GetProcessName( PID, &wsProcName ) ) - return false; - - bool bResult = false; - if ( wsProcName.Buffer ) - { - for ( int i = 0; i < ARRAYSIZE( globals::wsProtectedProcesses ); ++i ) - { - if ( wcsstr( wsProcName.Buffer, globals::wsProtectedProcesses[ i ] ) ) - { - bResult = true; - break; - } - } - FreeUnicodeString( &wsProcName ); - } - return bResult; - } - - bool IsProtectedProcess( PWCH Buffer ) - { - if ( !Buffer ) - return false; - - for ( int i = 0; i < ARRAYSIZE( globals::wsProtectedProcesses ); ++i ) - { - if ( wcsstr( Buffer, globals::wsProtectedProcesses[ i ] ) ) - { - return true; - } - } - return false; - } - - bool IsProtectedProcessEx( PEPROCESS Process ) - { - UNICODE_STRING wsProcName{ }; - if ( !GetProcessNameByPEPROCESS( Process, &wsProcName ) ) - return false; - - bool bResult = false; - if ( wsProcName.Buffer ) - { - for ( int i = 0; i < ARRAYSIZE( globals::wsProtectedProcesses ); ++i ) - { - if ( wcsstr( wsProcName.Buffer, globals::wsProtectedProcesses[ i ] ) ) - { - bResult = true; - break; - } - } - FreeUnicodeString( &wsProcName ); - } - return bResult; - } - - bool IsMonitoredProcess( HANDLE PID ) - { - UNICODE_STRING wsProcName{ }; - if ( !GetProcessName( PID, &wsProcName ) ) - return false; - - bool bResult = false; - if ( wsProcName.Buffer ) - { - for ( int i = 0; i < ARRAYSIZE( globals::wsMonitoredProcesses ); ++i ) - { - if ( wcsstr( wsProcName.Buffer, globals::wsMonitoredProcesses[ i ] ) ) - { - bResult = true; - break; - } - } - FreeUnicodeString( &wsProcName ); - } - return bResult; - } - - bool IsMonitoredProcessEx( PEPROCESS Process ) - { - UNICODE_STRING wsProcName{ }; - if ( !GetProcessNameByPEPROCESS( Process, &wsProcName ) ) - return false; - - bool bResult = false; - if ( wsProcName.Buffer ) - { - for ( int i = 0; i < ARRAYSIZE( globals::wsMonitoredProcesses ); ++i ) - { - if ( wcsstr( wsProcName.Buffer, globals::wsMonitoredProcesses[ i ] ) ) - { - bResult = true; - break; - } - } - FreeUnicodeString( &wsProcName ); - } - return bResult; - } - - bool IsBlacklistedProcess( HANDLE PID ) - { - UNICODE_STRING wsProcName{ }; - if ( !GetProcessName( PID, &wsProcName ) ) - return false; - - bool bResult = false; - if ( wsProcName.Buffer ) - { - for ( int i = 0; i < ARRAYSIZE( globals::wsBlacklistedProcessess ); ++i ) - { - if ( wcsstr( wsProcName.Buffer, globals::wsBlacklistedProcessess[ i ] ) ) - { - bResult = true; - break; - } - } - FreeUnicodeString( &wsProcName ); - } - return bResult; - } - - bool IsBlacklistedProcessEx( PEPROCESS Process ) - { - UNICODE_STRING wsProcName{ }; - if ( !GetProcessNameByPEPROCESS( Process, &wsProcName ) ) - return false; - - bool bResult = false; - if ( wsProcName.Buffer ) - { - for ( int i = 0; i < ARRAYSIZE( globals::wsBlacklistedProcessess ); ++i ) - { - if ( wcsstr( wsProcName.Buffer, globals::wsBlacklistedProcessess[ i ] ) ) - { - bResult = true; - break; - } - } - FreeUnicodeString( &wsProcName ); - } - return bResult; - } - } -}; - -NtOpenProcess_ oNtOpenProcess = NULL; -NTSTATUS NTAPI hkNtOpenProcess( PHANDLE ProcessHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PCLIENT_ID ClientId ) -{ - const auto ret = oNtOpenProcess( ProcessHandle, DesiredAccess, ObjectAttributes, ClientId ); - if ( PsIsProtectedProcess( PsGetCurrentProcess() ) || PsIsSystemProcess( PsGetCurrentProcess() ) || tools::IsProtectedProcess( PsGetCurrentProcessId() ) ) - return ret; - - if ( NT_SUCCESS( ret ) ) - { - if ( tools::IsBlacklistedProcess( PsGetCurrentProcessId() ) ) - { - if ( tools::IsProtectedProcess( ClientId->UniqueProcess ) ) - { - DBGPRINT( "Denying access from PID %p to PID %p\n", PsGetCurrentProcessId(), ClientId->UniqueProcess ); - ZwClose( *ProcessHandle ); - *ProcessHandle = HANDLE( -1 ); - return STATUS_ACCESS_DENIED; - } - } - - if ( tools::IsMonitoredProcess( ClientId->UniqueProcess ) ) - { - UNICODE_STRING wsProcName{ }; - if ( tools::GetProcessName( ClientId->UniqueProcess, &wsProcName ) ) - { - if ( wsProcName.Buffer ) - { - auto ShortName = wcsrchr( wsProcName.Buffer, '\\' ); - DBGPRINT( "[ OP ] PID %p is opening a handle with access mask 0x%X to process %ws\n", PsGetCurrentProcessId(), DesiredAccess, ShortName ); - FreeUnicodeString( &wsProcName ); - } - } - } - } - return ret; -} - -NtWriteVirtualMemory_ oNtWriteVirtualMemory = NULL; -NTSTATUS NTAPI hkNtWriteVirtualMemory( HANDLE ProcessHandle, PVOID BaseAddress, PVOID Buffer, ULONG NumberOfBytesToWrite, PULONG NumberOfBytesWritten ) -{ - const auto res = oNtWriteVirtualMemory( ProcessHandle, BaseAddress, Buffer, NumberOfBytesToWrite, NumberOfBytesWritten ); - if ( PsIsProtectedProcess( PsGetCurrentProcess() ) || PsIsSystemProcess( PsGetCurrentProcess() ) || tools::IsProtectedProcess( PsGetCurrentProcessId() ) ) - return res; - - if ( NT_SUCCESS( res ) ) - { - // - // Get Name from handle - // - PEPROCESS Process = nullptr; - auto ret = ObReferenceObjectByHandle( ProcessHandle, 0, *PsProcessType, ExGetPreviousMode(), ( PVOID* )&Process, nullptr ); - if ( !NT_SUCCESS( ret ) ) - return res; - - if ( tools::IsMonitoredProcessEx( Process ) ) - { - UNICODE_STRING wsProcName{ }; - if ( tools::GetProcessName( PsGetCurrentProcessId(), &wsProcName ) ) - { - if ( wsProcName.Buffer ) - { - auto ShortName = wcsrchr( wsProcName.Buffer, '\\' ); - DBGPRINT( "[ WPM ] From: %p to %ws with BaseAddress 0x%p Buffer 0x%p Length %d\n", PsGetCurrentProcessId(), ShortName, BaseAddress, Buffer, NumberOfBytesToWrite ); - FreeUnicodeString( &wsProcName ); - } - } - } - - ObDereferenceObject( Process ); - } - return res; -} - -NtAllocateVirtualMemory_ oNtAllocateVirtualMemory = NULL; -NTSTATUS NTAPI hkNtAllocateVirtualMemory( HANDLE ProcessHandle, PVOID* BaseAddress, ULONG_PTR ZeroBits, PSIZE_T RegionSize, ULONG AllocationType, ULONG Protect ) -{ - const auto res = oNtAllocateVirtualMemory( ProcessHandle, BaseAddress, ZeroBits, RegionSize, AllocationType, Protect ); - if ( PsIsProtectedProcess( PsGetCurrentProcess() ) || PsIsSystemProcess( PsGetCurrentProcess() ) || tools::IsProtectedProcess( PsGetCurrentProcessId() ) ) - return res; - - if ( NT_SUCCESS( res ) && BaseAddress && RegionSize && *RegionSize >= 0x1000 ) - { - // - // Get Name from handle - // - PEPROCESS Process = nullptr; - auto ret = ObReferenceObjectByHandle( ProcessHandle, 0, *PsProcessType, ExGetPreviousMode(), ( PVOID* )&Process, nullptr ); - if ( !NT_SUCCESS( ret ) ) - return res; - - if ( tools::IsMonitoredProcessEx( Process ) ) - { - UNICODE_STRING wsProcName{ }; - if ( tools::GetProcessName( PsGetCurrentProcessId(), &wsProcName ) ) - { - if ( wsProcName.Buffer ) - { - auto ShortName = wcsrchr( wsProcName.Buffer, '\\' ); - DBGPRINT( "[ AVM ] From: %p to %ws with BaseAddress 0x%p Length 0x%llx Type 0x%X Protect 0x%X\n", PsGetCurrentProcessId(), ShortName, *BaseAddress, *RegionSize, AllocationType, Protect ); - FreeUnicodeString( &wsProcName ); - } - } - } - - ObDereferenceObject( Process ); - } - return res; -} - -NtFreeVirtualMemory_ oNtFreeVirtualMemory = NULL; -NTSTATUS NTAPI hkNtFreeVirtualMemory( HANDLE ProcessHandle, PVOID* BaseAddress, PSIZE_T RegionSize, ULONG FreeType ) -{ - const auto res = oNtFreeVirtualMemory( ProcessHandle, BaseAddress, RegionSize, FreeType ); - if ( PsIsProtectedProcess( PsGetCurrentProcess() ) || PsIsSystemProcess( PsGetCurrentProcess() ) || tools::IsProtectedProcess( PsGetCurrentProcessId() ) ) - return res; - - if ( NT_SUCCESS( res ) && BaseAddress && RegionSize && *RegionSize >= 0x1000 ) - { - // - // Get Name from handle - // - PEPROCESS Process = nullptr; - auto ret = ObReferenceObjectByHandle( ProcessHandle, 0, *PsProcessType, ExGetPreviousMode(), ( PVOID* )&Process, nullptr ); - if ( !NT_SUCCESS( ret ) ) - return res; - - if ( tools::IsMonitoredProcessEx( Process ) ) - { - UNICODE_STRING wsProcName{ }; - if ( tools::GetProcessName( PsGetCurrentProcessId(), &wsProcName ) ) - { - if ( wsProcName.Buffer ) - { - auto ShortName = wcsrchr( wsProcName.Buffer, '\\' ); - DBGPRINT( "[ FVM ] From: %p to %ws with BaseAddress 0x%p Length 0x%llx FreeType 0x%X\n", PsGetCurrentProcessId(), ShortName, *BaseAddress, *RegionSize, FreeType ); - tools::DumpMZ( PUCHAR( *BaseAddress ) ); - FreeUnicodeString( &wsProcName ); - } - } - } - - ObDereferenceObject( Process ); - } - return res; -} - -NtDeviceIoControlFile_ oNtDeviceIoControlFile = NULL; -NTSTATUS NTAPI hkNtDeviceIoControlFile( HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, ULONG IoControlCode, PVOID InputBuffer, ULONG InputBufferLength, PVOID OutputBuffer, ULONG OutputBufferLength ) -{ - const auto ret = oNtDeviceIoControlFile( FileHandle, Event, ApcRoutine, ApcContext, IoStatusBlock, IoControlCode, InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength ); - - // - // If the callee process is a protected process we ignore it - // - if ( !tools::IsBlacklistedProcess( PsGetCurrentProcessId() ) ) - return ret; - - if ( NT_SUCCESS( ret ) ) - { - const auto szNewModel = globals::szFakeModels[ 0 ]; - wchar_t wsProcess[ MAX_PATH ] = L"\\Unknown"; - - UNICODE_STRING wsProcName{ }; - if ( tools::GetProcessName( PsGetCurrentProcessId(), &wsProcName ) ) - { - if ( wsProcName.Buffer ) - { - wcscpy_s( wsProcess, wsProcName.Buffer ); - FreeUnicodeString( &wsProcName ); - } - } - - auto ShortName = wcsrchr( wsProcess, '\\' ); - - __try - { - // - // Hardware Spoofing - // - switch ( IoControlCode ) - { - - case IOCTL_STORAGE_QUERY_PROPERTY: - { - PSTORAGE_PROPERTY_QUERY Query = PSTORAGE_PROPERTY_QUERY( InputBuffer ); - if ( Query && Query->PropertyId == StorageDeviceProperty ) - { - if ( OutputBufferLength >= sizeof( STORAGE_DEVICE_DESCRIPTOR ) ) - { - PSTORAGE_DEVICE_DESCRIPTOR Desc = PSTORAGE_DEVICE_DESCRIPTOR( OutputBuffer ); - if ( Desc ) - { - if ( Desc->SerialNumberOffset ) - { - auto Serial = PCHAR( Desc ) + Desc->SerialNumberOffset; - DBGPRINT( "%ws Spoofing Serial ( 0x%X ) Old: %s New: %s\n", ShortName, IoControlCode, Serial, globals::szFakeSerial ); - memset( Serial, 0, strlen( Serial ) ); - strcpy( Serial, globals::szFakeSerial ); - } - - if ( Desc->ProductIdOffset ) - { - auto Model = PCHAR( Desc ) + Desc->ProductIdOffset; - DBGPRINT( "%ws Spoofing Model ( 0x%X ) Old: %s New: %s\n", ShortName, IoControlCode, Model, szNewModel ); - memset( Model, 0, strlen( Model ) ); - strcpy( Model, szNewModel ); - } - } - } - } - break; - } - - case IOCTL_ATA_PASS_THROUGH: - { - if ( OutputBufferLength >= sizeof( ATA_PASS_THROUGH_EX ) + sizeof( PIDENTIFY_DEVICE_DATA ) ) - { - PATA_PASS_THROUGH_EX Ata = PATA_PASS_THROUGH_EX( OutputBuffer ); - if ( Ata && Ata->DataBufferOffset ) - { - PIDENTIFY_DEVICE_DATA Identify = PIDENTIFY_DEVICE_DATA( PCHAR( OutputBuffer ) + Ata->DataBufferOffset ); - if ( Identify ) - { - auto Serial = PCHAR( Identify->SerialNumber ); - if ( strlen( Serial ) > 0 ) - { - tools::SwapEndianness( Serial, sizeof( Identify->SerialNumber ) ); - - DBGPRINT( "%ws Spoofing Serial ( 0x%X ) Old: %s New: %s\n", ShortName, IoControlCode, Serial, globals::szFakeSerial ); - memset( Serial, 0, strlen( Serial ) ); - strcpy( Serial, globals::szFakeSerial ); - - tools::SwapEndianness( Serial, sizeof( Identify->SerialNumber ) ); - } - - auto Model = PCHAR( Identify->ModelNumber ); - if ( strlen( Model ) > 0 ) - { - // Fix invalid characters. - Model[ sizeof( Identify->ModelNumber ) - 1 ] = 0; - Model[ sizeof( Identify->ModelNumber ) - 2 ] = 0; - - tools::SwapEndianness( Model, sizeof( Identify->ModelNumber ) - 2 ); - - DBGPRINT( "%ws Spoofing Model ( 0x%X ) Old: %s New: %s\n", ShortName, IoControlCode, Model, szNewModel ); - memset( Model, 0, strlen( Model ) ); - strcpy( Model, szNewModel ); - - tools::SwapEndianness( Model, sizeof( Identify->ModelNumber ) - 2 ); - } - } - } - } - break; - } - - case SMART_RCV_DRIVE_DATA: - { - if ( OutputBufferLength >= sizeof( SENDCMDOUTPARAMS ) ) - { - PSENDCMDOUTPARAMS Cmd = PSENDCMDOUTPARAMS( OutputBuffer ); - if ( Cmd ) - { - PIDSECTOR Sector = PIDSECTOR( Cmd->bBuffer ); - if ( Sector ) - { - auto Serial = PCHAR( Sector->sSerialNumber ); - if ( strlen( Serial ) > 0 ) - { - tools::SwapEndianness( Serial, sizeof( Sector->sSerialNumber ) ); - - DBGPRINT( "%ws Spoofing Serial ( 0x%X ) Old: %s New: %s\n", ShortName, IoControlCode, Serial, globals::szFakeSerial ); - memset( Serial, 0, strlen( Serial ) ); - strcpy( Serial, globals::szFakeSerial ); - - tools::SwapEndianness( Serial, sizeof( Sector->sSerialNumber ) ); - } - - auto Model = PCHAR( Sector->sModelNumber ); - if ( strlen( Model ) > 0 ) - { - // Fix invalid characters. - Model[ sizeof( Sector->sModelNumber ) - 1 ] = 0; - Model[ sizeof( Sector->sModelNumber ) - 2 ] = 0; - - tools::SwapEndianness( Model, sizeof( Sector->sModelNumber ) - 2 ); - - DBGPRINT( "%ws Spoofing Model ( 0x%X ) Old: %s New: %s\n", ShortName, IoControlCode, Model, szNewModel ); - memset( Model, 0, strlen( Model ) ); - strcpy( Model, szNewModel ); - - tools::SwapEndianness( Model, sizeof( Sector->sModelNumber ) - 2 ); - } - } - } - } - break; - } - - case IOCTL_DISK_GET_PARTITION_INFO_EX: - { - if ( OutputBufferLength >= sizeof( PARTITION_INFORMATION_EX ) ) - { - PPARTITION_INFORMATION_EX PartInfo = PPARTITION_INFORMATION_EX( OutputBuffer ); - if ( PartInfo && PartInfo->PartitionStyle == PARTITION_STYLE_GPT ) - { - DBGPRINT( "%ws Zero'ing partition GUID (EX)\n", ShortName ); - memset( &PartInfo->Gpt.PartitionId, 0, sizeof( GUID ) ); - } - } - break; - } - - case IOCTL_DISK_GET_DRIVE_LAYOUT_EX: - { - if ( OutputBufferLength >= sizeof( DRIVE_LAYOUT_INFORMATION_EX ) ) - { - PDRIVE_LAYOUT_INFORMATION_EX LayoutInfo = PDRIVE_LAYOUT_INFORMATION_EX( OutputBuffer ); - if ( LayoutInfo && LayoutInfo->PartitionStyle == PARTITION_STYLE_GPT ) - { - DBGPRINT( "%ws Zero'ing partition GUID\n", ShortName ); - memset( &LayoutInfo->Gpt.DiskId, 0, sizeof( GUID ) ); - } - } - break; - } - - case IOCTL_MOUNTMGR_QUERY_POINTS: - { - if ( OutputBufferLength >= sizeof( MOUNTMGR_MOUNT_POINTS ) ) - { - PMOUNTMGR_MOUNT_POINTS Points = PMOUNTMGR_MOUNT_POINTS( OutputBuffer ); - if ( Points ) - { - DBGPRINT( "%ws Spoofing mounted points\n", ShortName ); - for ( unsigned i = 0; i < Points->NumberOfMountPoints; ++i ) - { - auto Point = &Points->MountPoints[ i ]; - - if ( Point->UniqueIdOffset ) - Point->UniqueIdLength = 0; - - if ( Point->SymbolicLinkNameOffset ) - Point->SymbolicLinkNameLength = 0; - } - } - } - break; - } - - case IOCTL_MOUNTDEV_QUERY_UNIQUE_ID: - { - if ( OutputBufferLength >= sizeof( MOUNTDEV_UNIQUE_ID ) ) - { - PMOUNTDEV_UNIQUE_ID UniqueId = PMOUNTDEV_UNIQUE_ID( OutputBuffer ); - if ( UniqueId ) - { - DBGPRINT( "%ws Spoofing mounted unique id\n", ShortName ); - UniqueId->UniqueIdLength = 0; - } - } - break; - } - - case IOCTL_NDIS_QUERY_GLOBAL_STATS: - { - switch ( *( PDWORD )InputBuffer ) - { - case OID_802_3_PERMANENT_ADDRESS: - case OID_802_3_CURRENT_ADDRESS: - case OID_802_5_PERMANENT_ADDRESS: - case OID_802_5_CURRENT_ADDRESS: - DBGPRINT( "%ws Spoofing permanent MAC\n", ShortName ); - memcpy( OutputBuffer, globals::szFakeMAC, sizeof( globals::szFakeMAC ) ); - break; - } - } - - } - } - __except ( EXCEPTION_EXECUTE_HANDLER ) - { - - } - } - return ret; -} - -NtQuerySystemInformation_ oNtQuerySystemInformation = NULL; -NTSTATUS NTAPI hkNtQuerySystemInformation( SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID Buffer, ULONG Length, PULONG ReturnLength ) -{ - const auto ret = oNtQuerySystemInformation( SystemInformationClass, Buffer, Length, ReturnLength ); - - // - // If the callee process is a protected process we ignore it - // - if ( tools::IsProtectedProcess( PsGetCurrentProcessId() ) ) - return ret; - - if ( NT_SUCCESS( ret ) ) - { - // - // Hide from Driver list - // - if ( SystemInformationClass == SystemModuleInformation ) - { - const auto pModule = PRTL_PROCESS_MODULES( Buffer ); - const auto pEntry = &pModule->Modules[ 0 ]; - - for ( unsigned i = 0; i < pModule->NumberOfModules; ++i ) - { - if ( pEntry[ i ].ImageBase && pEntry[ i ].ImageSize && strlen( ( char* )pEntry[ i ].FullPathName ) > 2 ) - { - for ( int x = 0; x < ARRAYSIZE( globals::szProtectedDrivers ); ++x ) - { - if ( strstr( ( char* )pEntry[ i ].FullPathName, globals::szProtectedDrivers[ x ] ) ) - { - const auto next_entry = i + 1; - - if ( next_entry < pModule->NumberOfModules ) - memcpy( &pEntry[ i ], &pEntry[ next_entry ], sizeof( RTL_PROCESS_MODULE_INFORMATION ) ); - else - { - memset( &pEntry[ i ], 0, sizeof( RTL_PROCESS_MODULE_INFORMATION ) ); - pModule->NumberOfModules--; - } - } - } - } - } - } - // - // Hide from Process list - // - else if ( - SystemInformationClass == SystemProcessInformation || - SystemInformationClass == SystemSessionProcessInformation || - SystemInformationClass == SystemExtendedProcessInformation ) - { - PSYSTEM_PROCESS_INFO pCurr = NULL; - PSYSTEM_PROCESS_INFO pNext = PSYSTEM_PROCESS_INFO( Buffer ); - - while ( pNext->NextEntryOffset != 0 ) - { - pCurr = pNext; - pNext = ( PSYSTEM_PROCESS_INFO )( ( PUCHAR )pCurr + pCurr->NextEntryOffset ); - - // - // Erase our protected processes from the list - // - if ( pNext->ImageName.Buffer && tools::IsProtectedProcess( pNext->ImageName.Buffer ) ) - { - if ( pNext->NextEntryOffset == 0 ) - { - pCurr->NextEntryOffset = 0; - } - else - { - pCurr->NextEntryOffset += pNext->NextEntryOffset; - } - - pNext = pCurr; - } - } - } - // - // Hide from handle list - // - else if ( SystemInformationClass == SystemHandleInformation ) - { - if ( tools::IsBlacklistedProcess( PsGetCurrentProcessId() ) ) - { - const auto pHandle = PSYSTEM_HANDLE_INFORMATION( Buffer ); - const auto pEntry = &pHandle->Information[ 0 ]; - - for ( unsigned i = 0; i < pHandle->NumberOfHandles; ++i ) - { - if ( tools::IsProtectedProcess( ULongToHandle( pEntry[ i ].ProcessId ) ) ) - { - const auto next_entry = i + 1; - - if ( next_entry < pHandle->NumberOfHandles ) - memcpy( &pEntry[ i ], &pEntry[ next_entry ], sizeof( SYSTEM_HANDLE ) ); - else - { - memset( &pEntry[ i ], 0, sizeof( SYSTEM_HANDLE ) ); - pHandle->NumberOfHandles--; - } - } - } - } - } - else if ( SystemInformationClass == SystemExtendedHandleInformation ) - { - if ( tools::IsBlacklistedProcess( PsGetCurrentProcessId() ) ) - { - const auto pHandle = PSYSTEM_HANDLE_INFORMATION_EX( Buffer ); - const auto pEntry = &pHandle->Information[ 0 ]; - - for ( unsigned i = 0; i < pHandle->NumberOfHandles; ++i ) - { - if ( tools::IsProtectedProcess( ULongToHandle( pEntry[ i ].ProcessId ) ) ) - { - const auto next_entry = i + 1; - - if ( next_entry < pHandle->NumberOfHandles ) - memcpy( &pEntry[ i ], &pEntry[ next_entry ], sizeof( SYSTEM_HANDLE ) ); - else - { - memset( &pEntry[ i ], 0, sizeof( SYSTEM_HANDLE ) ); - pHandle->NumberOfHandles--; - } - } - } - } - } - // - // Spoof code integrity status - // - else if ( SystemInformationClass == SystemCodeIntegrityInformation ) - { - PSYSTEM_CODEINTEGRITY_INFORMATION Integrity = PSYSTEM_CODEINTEGRITY_INFORMATION( Buffer ); - - // Spoof test sign flag if present - if ( Integrity->CodeIntegrityOptions & CODEINTEGRITY_OPTION_TESTSIGN ) - Integrity->CodeIntegrityOptions &= ~CODEINTEGRITY_OPTION_TESTSIGN; - - // Set as always enabled. - Integrity->CodeIntegrityOptions |= CODEINTEGRITY_OPTION_ENABLED; - } - } - return ret; -} - -NtLoadDriver_ oNtLoadDriver = NULL; -NTSTATUS NTAPI hkNtLoadDriver( PUNICODE_STRING DriverServiceName ) -{ - NTSTATUS ret = STATUS_UNSUCCESSFUL; - bool bLoad = true; - - if ( DriverServiceName && DriverServiceName->Buffer ) - { - /* - - For example: - - if ( wcsstr( DriverServiceName->Buffer, L"BEDaisy.sys" ) ) - bLoad = false; - - Loading will be blocked. - */ - } - - if ( bLoad ) - { - ret = oNtLoadDriver( DriverServiceName ); - if ( NT_SUCCESS( ret ) ) - DBGPRINT( "Loading Driver: %ws\n", DriverServiceName->Buffer ); - } - return ret; -} - -NtUserWindowFromPoint_ oNtUserWindowFromPoint = NULL; -HWND NTAPI hkNtUserWindowFromPoint( LONG x, LONG y ) -{ - const auto res = oNtUserWindowFromPoint( x, y ); - - if ( PsIsProtectedProcess( PsGetCurrentProcess() ) || PsIsSystemProcess( PsGetCurrentProcess() ) ) - return res; - - if ( !tools::IsBlacklistedProcessEx( PsGetCurrentProcess() ) ) - return res; - - return 0; -} - -NtUserQueryWindow_ oNtUserQueryWindow = NULL; -HANDLE NTAPI hkNtUserQueryWindow( HWND WindowHandle, HANDLE TypeInformation ) -{ - const auto res = oNtUserQueryWindow( WindowHandle, TypeInformation ); - - if ( PsIsProtectedProcess( PsGetCurrentProcess() ) || PsIsSystemProcess( PsGetCurrentProcess() ) ) - return res; - - if ( !tools::IsBlacklistedProcessEx( PsGetCurrentProcess() ) ) - return res; - - auto PID = oNtUserQueryWindow( WindowHandle, 0 ); - if ( tools::IsProtectedProcess( PID ) ) - return 0; - - return res; -} - -NtUserFindWindowEx_ oNtUserFindWindowEx = NULL; -HWND NTAPI hkNtUserFindWindowEx( HWND hWndParent, HWND hWndChildAfter, PUNICODE_STRING lpszClass, PUNICODE_STRING lpszWindow, DWORD dwType ) -{ - const auto res = oNtUserFindWindowEx( hWndParent, hWndChildAfter, lpszClass, lpszWindow, dwType ); - - if ( PsIsProtectedProcess( PsGetCurrentProcess() ) || PsIsSystemProcess( PsGetCurrentProcess() ) ) - return res; - - if ( !tools::IsBlacklistedProcessEx( PsGetCurrentProcess() ) ) - return res; - - if ( res ) - { - auto PID = oNtUserQueryWindow( res, 0 ); - if ( tools::IsProtectedProcess( PID ) ) - { - return NULL; - } - } - return res; -} - -NtUserBuildHwndList_ oNtUserBuildHwndList = NULL; -NTSTATUS NTAPI hkNtUserBuildHwndList( HDESK hdesk, HWND hwndNext, ULONG fEnumChildren, DWORD idThread, UINT cHwndMax, HWND* phwndFirst, ULONG* pcHwndNeeded ) -{ - const auto res = oNtUserBuildHwndList( hdesk, hwndNext, fEnumChildren, idThread, cHwndMax, phwndFirst, pcHwndNeeded ); - - if ( PsIsProtectedProcess( PsGetCurrentProcess() ) || PsIsSystemProcess( PsGetCurrentProcess() ) ) - return res; - - if ( !tools::IsBlacklistedProcessEx( PsGetCurrentProcess() ) ) - return res; - - if ( fEnumChildren == 1 ) - { - auto PID = oNtUserQueryWindow( hwndNext, 0 ); - if ( tools::IsProtectedProcess( PID ) ) - return STATUS_UNSUCCESSFUL; - } - - if ( NT_SUCCESS( res ) ) - { - ULONG i = 0; - ULONG j; - - while ( i < *pcHwndNeeded ) - { - auto PID = oNtUserQueryWindow( phwndFirst[ i ], 0 ); - if ( tools::IsProtectedProcess( PID ) ) - { - for ( j = i; j < ( *pcHwndNeeded ) - 1; j++ ) - phwndFirst[ j ] = phwndFirst[ j + 1 ]; - phwndFirst[ *pcHwndNeeded - 1 ] = 0; - ( *pcHwndNeeded )--; - continue; - } - i++; - } - } - return res; -} - -NtUserGetForegroundWindow_ oNtUserGetForegroundWindow = NULL; -HWND LastForeWnd = HWND( -1 ); - -HWND NTAPI hkNtUserGetForegroundWindow( VOID ) -{ - const auto res = oNtUserGetForegroundWindow(); - - if ( PsIsProtectedProcess( PsGetCurrentProcess() ) || PsIsSystemProcess( PsGetCurrentProcess() ) ) - return res; - - if ( !tools::IsBlacklistedProcessEx( PsGetCurrentProcess() ) ) - return res; - - auto PID = oNtUserQueryWindow( res, 0 ); - if ( tools::IsProtectedProcess( PID ) ) - return LastForeWnd; - else - LastForeWnd = res; - - return res; -} \ No newline at end of file diff --git a/MasterHide/mh_hooks.h b/MasterHide/mh_hooks.h deleted file mode 100644 index 913cafe..0000000 --- a/MasterHide/mh_hooks.h +++ /dev/null @@ -1,103 +0,0 @@ -#pragma once - -//HARDCODED for Windows 7 x64 SP1 7601 - -// -// ntoskrnl.exe -// -static auto SYSCALL_NTUSERFINDWNDEX = 0x106e; -static auto SYSCALL_NTUSERWNDFROMPOINT = 0x1014; -static auto SYSCALL_NTUSERBUILDWNDLIST = 0x101c; -static auto SYSCALL_NTGETFOREGROUNDWND = 0x103c; -static auto SYSCALL_NTUSERQUERYWND = 0x1010; - -// -// win32k.sys -// -static auto SYSCALL_NTQUERYSYSINFO = 0x0033; -static auto SYSCALL_NTOPENPROCESS = 0x0023; -static auto SYSCALL_NTALLOCVIRTUALMEM = 0x0015; -static auto SYSCALL_NTWRITEVIRTUALMEM = 0x0037; -static auto SYSCALL_NTFREEVIRTUALMEM = 0x001b; -static auto SYSCALL_NTDEVICEIOCTRLFILE = 0x0004; -static auto SYSCALL_NTLOADDRIVER = 0x0004; - -namespace masterhide -{ - namespace tools - { - extern bool IsProtectedProcess( HANDLE PID ); - extern bool IsProtectedProcess( PWCH Buffer ); - extern bool IsProtectedProcessEx( PEPROCESS Process ); - extern bool IsMonitoredProcess( HANDLE PID ); - extern bool IsMonitoredProcessEx( PEPROCESS Process ); - extern bool IsBlacklistedProcess( HANDLE PID ); - extern bool IsBlacklistedProcessEx( PEPROCESS Process ); - } -}; - -// -// ntoskrnl.exe hooks -// -using NtQuerySystemInformation_ = NTSTATUS( NTAPI* )( SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG ); -extern NtQuerySystemInformation_ oNtQuerySystemInformation; - -NTSTATUS NTAPI hkNtQuerySystemInformation( SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID Buffer, ULONG Length, PULONG ReturnLength ); - -using NtOpenProcess_ = NTSTATUS( NTAPI* ) ( PHANDLE ProcessHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PCLIENT_ID ClientId ); -extern NtOpenProcess_ oNtOpenProcess; - -NTSTATUS NTAPI hkNtOpenProcess( PHANDLE ProcessHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PCLIENT_ID ClientId ); - -using NtAllocateVirtualMemory_ = NTSTATUS( NTAPI* )( HANDLE ProcessHandle, PVOID* BaseAddress, ULONG_PTR ZeroBits, PSIZE_T RegionSize, ULONG AllocationType, ULONG Protect ); -extern NtAllocateVirtualMemory_ oNtAllocateVirtualMemory; - -NTSTATUS NTAPI hkNtAllocateVirtualMemory( HANDLE ProcessHandle, PVOID* BaseAddress, ULONG_PTR ZeroBits, PSIZE_T RegionSize, ULONG AllocationType, ULONG Protect ); - -using NtFreeVirtualMemory_ = NTSTATUS( NTAPI* )( HANDLE ProcessHandle, PVOID* BaseAddress, PSIZE_T RegionSize, ULONG FreeType ); -extern NtFreeVirtualMemory_ oNtFreeVirtualMemory; - -NTSTATUS NTAPI hkNtFreeVirtualMemory( HANDLE ProcessHandle, PVOID* BaseAddress, PSIZE_T RegionSize, ULONG FreeType ); - -using NtWriteVirtualMemory_ = NTSTATUS( NTAPI* )( HANDLE ProcessHandle, PVOID BaseAddress, PVOID Buffer, ULONG NumberOfBytesToWrite, PULONG NumberOfBytesWritten ); -extern NtWriteVirtualMemory_ oNtWriteVirtualMemory; - -NTSTATUS NTAPI hkNtWriteVirtualMemory( HANDLE ProcessHandle, PVOID BaseAddress, PVOID Buffer, ULONG NumberOfBytesToWrite, PULONG NumberOfBytesWritten ); - -using NtDeviceIoControlFile_ = NTSTATUS( NTAPI* )( HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, ULONG IoControlCode, PVOID InputBuffer, ULONG InputBufferLength, PVOID OutputBuffer, ULONG OutputBufferLength ); -extern NtDeviceIoControlFile_ oNtDeviceIoControlFile; - -NTSTATUS NTAPI hkNtDeviceIoControlFile( HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, ULONG IoControlCode, PVOID InputBuffer, ULONG InputBufferLength, PVOID OutputBuffer, ULONG OutputBufferLength ); - -using NtLoadDriver_ = NTSTATUS( NTAPI* )( PUNICODE_STRING DriverServiceName ); -extern NtLoadDriver_ oNtLoadDriver; - -NTSTATUS NTAPI hkNtLoadDriver( PUNICODE_STRING DriverServiceName ); - -// -// win32k.sys hooks -// -using NtUserWindowFromPoint_ = HWND( NTAPI* )( LONG, LONG ); -extern NtUserWindowFromPoint_ oNtUserWindowFromPoint; - -HWND hkNtUserWindowFromPoint( LONG x, LONG y ); - -using NtUserQueryWindow_ = HANDLE( NTAPI* )( HWND, HANDLE ); -extern NtUserQueryWindow_ oNtUserQueryWindow; - -HANDLE hkNtUserQueryWindow( HWND WindowHandle, HANDLE TypeInformation ); - -using NtUserFindWindowEx_ = HWND( NTAPI* )( HWND, HWND, PUNICODE_STRING, PUNICODE_STRING, DWORD ); -extern NtUserFindWindowEx_ oNtUserFindWindowEx; - -HWND NTAPI hkNtUserFindWindowEx( HWND hWndParent, HWND hWndChildAfter, PUNICODE_STRING lpszClass, PUNICODE_STRING lpszWindow, DWORD dwType ); - -using NtUserBuildHwndList_ = NTSTATUS( NTAPI* )( HDESK hdesk, HWND hwndNext, ULONG fEnumChildren, DWORD idThread, UINT cHwndMax, HWND* phwndFirst, ULONG* pcHwndNeeded ); -extern NtUserBuildHwndList_ oNtUserBuildHwndList; - -NTSTATUS NTAPI hkNtUserBuildHwndList( HDESK hdesk, HWND hwndNext, ULONG fEnumChildren, DWORD idThread, UINT cHwndMax, HWND* phwndFirst, ULONG* pcHwndNeeded ); - -using NtUserGetForegroundWindow_ = HWND( NTAPI* )( VOID ); -extern NtUserGetForegroundWindow_ oNtUserGetForegroundWindow; - -HWND NTAPI hkNtUserGetForegroundWindow( VOID ); \ No newline at end of file diff --git a/MasterHide/ntfill.cpp b/MasterHide/ntfill.cpp new file mode 100644 index 0000000..4041d47 --- /dev/null +++ b/MasterHide/ntfill.cpp @@ -0,0 +1,11 @@ +#include "includes.hpp" + +PKUSER_SHARED_DATA KernelKuserSharedData = (PKUSER_SHARED_DATA)KUSER_SHARED_DATA_KERNELMODE; +const PKUSER_SHARED_DATA KuserSharedData = (PKUSER_SHARED_DATA)KUSER_SHARED_DATA_USERMODE; + +PMMPFN MmPfnDatabase = (PMMPFN)0xFFFFFA8000000000; +ULONG_PTR MmPteBase = 0xFFFFF68000000000U; +ULONG_PTR MmPdeBase = 0xFFFFF6FB40000000U; +ULONG_PTR MmPpeBase = 0xFFFFF6FB7DA00000U; +ULONG_PTR MmPxeBase = 0xFFFFF6FB7DBED000U; +ULONG_PTR MmPxeSelf = 0xFFFFF6FB7DBEDF68U; \ No newline at end of file diff --git a/MasterHide/ntfill.hpp b/MasterHide/ntfill.hpp new file mode 100644 index 0000000..3337bed --- /dev/null +++ b/MasterHide/ntfill.hpp @@ -0,0 +1,2271 @@ +#pragma once + +#define WINDOWS_7 7600 +#define WINDOWS_7_SP1 7601 +#define WINDOWS_8 9200 +#define WINDOWS_8_1 9600 +#define WINDOWS_10_VERSION_THRESHOLD1 10240 +#define WINDOWS_10_VERSION_THRESHOLD2 10586 +#define WINDOWS_10_VERSION_REDSTONE1 14393 +#define WINDOWS_10_VERSION_REDSTONE2 15063 +#define WINDOWS_10_VERSION_REDSTONE3 16299 +#define WINDOWS_10_VERSION_REDSTONE4 17134 +#define WINDOWS_10_VERSION_REDSTONE5 17763 +#define WINDOWS_10_VERSION_19H1 18362 +#define WINDOWS_10_VERSION_19H2 18363 +#define WINDOWS_10_VERSION_20H1 19041 +#define WINDOWS_10_VERSION_20H2 19042 +#define WINDOWS_10_VERSION_21H1 19043 +#define WINDOWS_10_VERSION_21H2 19044 +#define WINDOWS_10_VERSION_22H2 19045 +#define WINDOWS_11_VERSION_21H2 22000 +#define WINDOWS_11_VERSION_22H2 22621 +#define WINDOWS_11_VERSION_23H2 22631 +#define WINDOWS_11_VERSION_24H2 26100 + +#define PTR_OFFSET_ADD(p, o) ((ULONG_PTR)(p) + (ULONG_PTR)(o)) +#define PTR_OFFSET_SUB(p, o) ((ULONG_PTR)(p) - (ULONG_PTR)(o)) + +#ifndef ABSOLUTE +#define ABSOLUTE(wait) (wait) +#endif + +#ifndef RELATIVE +#define RELATIVE(wait) (-(wait)) +#endif + +#ifndef NANOSECONDS +#define NANOSECONDS(nanos) (((signed __int64)(nanos)) / 100L) +#endif + +#ifndef MICROSECONDS +#define MICROSECONDS(micros) (((signed __int64)(micros)) * NANOSECONDS(1000L)) +#endif + +#ifndef MILLISECONDS +#define MILLISECONDS(milli) (((signed __int64)(milli)) * MICROSECONDS(1000L)) +#endif + +#ifndef SECONDS +#define SECONDS(seconds) (((signed __int64)(seconds)) * MILLISECONDS(1000L)) +#endif + +#pragma warning(push) +#pragma warning(disable : 4201) + +#define THREAD_CREATE_FLAGS_BYPASS_PROCESS_FREEZE 0x40 +#define THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER 0x4 + +#define PROCESS_DEBUG_INHERIT 0x00000001 // default for a non-debugged process +#define PROCESS_NO_DEBUG_INHERIT 0x00000002 // default for a debugged process + +#define HEAP_SKIP_VALIDATION_CHECKS 0x10000000 +#define HEAP_VALIDATE_PARAMETERS_ENABLED 0x40000000 + +#define FLG_HEAP_ENABLE_TAIL_CHECK 0x10 +#define FLG_HEAP_ENABLE_FREE_CHECK 0x20 +#define FLG_HEAP_VALIDATE_PARAMETERS 0x40 +#define NT_GLOBAL_FLAG_DEBUGGED (FLG_HEAP_ENABLE_TAIL_CHECK | FLG_HEAP_ENABLE_FREE_CHECK | FLG_HEAP_VALIDATE_PARAMETERS) + +#define ObjectDataInformation 4 + +FORCEINLINE +SSIZE_T InterlockedIncrementSSizeT(_Inout_ _Interlocked_operand_ volatile SSIZE_T *Target) +{ + return (SSIZE_T)InterlockedIncrementSizeT((SIZE_T *)Target); +} + +FORCEINLINE +SSIZE_T InterlockedDecrementSSizeT(_Inout_ _Interlocked_operand_ volatile SSIZE_T *Target) +{ + return (SSIZE_T)InterlockedDecrementSizeT((SIZE_T *)Target); +} + +FORCEINLINE +SIZE_T InterlockedCompareExchangeSizeT(_Inout_ _Interlocked_operand_ volatile SIZE_T *Target, _In_ SIZE_T Value, + _In_ SIZE_T Expected) +{ + return (SIZE_T)InterlockedCompareExchangePointer((PVOID *)Target, (PVOID)Value, (PVOID)Expected); +} + +FORCEINLINE +SIZE_T InterlockedExchangeIfGreaterSizeT(_Inout_ _Interlocked_operand_ volatile SIZE_T *Target, _In_ SIZE_T Value) +{ + SIZE_T expected; + + for (;;) + { + expected = ReadSizeTAcquire(Target); + + if (Value <= expected) + { + break; + } + + if (InterlockedCompareExchangeSizeT(Target, Value, expected) == expected) + { + break; + } + } + + return expected; +} + +typedef enum _WINDOWINFOCLASS +{ + WindowProcess, + WindowThread, + WindowActiveWindow, + WindowFocusWindow, + WindowIsHung, + WindowClientBase, + WindowIsForegroundThread, +#ifdef FE_IME + WindowDefaultImeWindow, + WindowDefaultInputContext, +#endif +} WINDOWINFOCLASS; + +enum ThreadStateRoutines +{ + THREADSTATE_FOCUSWINDOW = 0, + THREADSTATE_ACTIVEWINDOW, + THREADSTATE_CAPTUREWINDOW, + THREADSTATE_DEFAULTIMEWINDOW, + THREADSTATE_DEFAULTINPUTCONTEXT, + THREADSTATE_GETINPUTSTATE, + THREADSTATE_GETCURSOR, + THREADSTATE_CHANGEBITS, + THREADSTATE_UPTIMELASTREAD, + THREADSTATE_GETMESSAGEEXTRAINFO, + THREADSTATE_INSENDMESSAGE, + THREADSTATE_GETMESSAGETIME, + THREADSTATE_FOREGROUNDTHREAD, + THREADSTATE_IMECOMPATFLAGS, + THREADSTATE_OLDKEYBOARDLAYOUT, + THREADSTATE_ISWINLOGON, + THREADSTATE_UNKNOWN_0x10, + THREADSTATE_CHECKCONIME, + THREADSTATE_GETTHREADINFO, +}; + +enum JOBOBJECTINFOCLASS +{ + JobObjectBasicAccountingInformation = 1, + JobObjectBasicLimitInformation = 2, + JobObjectBasicProcessIdList = 3, + JobObjectBasicUIRestrictions = 4, + JobObjectSecurityLimitInformation = 5, + JobObjectEndOfJobTimeInformation = 6, + JobObjectAssociateCompletionPortInformation = 7, + JobObjectBasicAndIoAccountingInformation = 8, + JobObjectExtendedLimitInformation = 9, + JobObjectJobSetInformation = 10, + JobObjectGroupInformation = 11, + JobObjectNotificationLimitInformation = 12, + JobObjectLimitViolationInformation = 13, + JobObjectGroupInformationEx = 14, + JobObjectCpuRateControlInformation = 15, + JobObjectCompletionFilter = 16, + JobObjectCompletionCounter = 17, + JobObjectFreezeInformation = 18, + JobObjectExtendedAccountingInformation = 19, + JobObjectWakeInformation = 20, + JobObjectBackgroundInformation = 21, + JobObjectSchedulingRankBiasInformation = 22, + JobObjectTimerVirtualizationInformation = 23, + JobObjectCycleTimeNotification = 24, + JobObjectClearEvent = 25, + JobObjectReserved1Information = 18, + JobObjectReserved2Information = 19, + JobObjectReserved3Information = 20, + JobObjectReserved4Information = 21, + JobObjectReserved5Information = 22, + JobObjectReserved6Information = 23, + JobObjectReserved7Information = 24, + JobObjectReserved8Information = 25, + MaxJobObjectInfoClass = 26 +}; + +typedef enum _SYSDBG_COMMAND +{ + SysDbgGetTriageDump = 29, + SysDbgGetLiveKernelDump = 37 // Windows 8.1+ +} SYSDBG_COMMAND, *PSYSDBG_COMMAND; + +typedef struct _SYSTEM_SERVICE_TABLE +{ + PVOID ServiceTableBase; + PVOID ServiceCounterTableBase; + ULONGLONG NumberOfServices; + PVOID ParamTableBase; +} SYSTEM_SERVICE_TABLE, *PSYSTEM_SERVICE_TABLE; + +typedef struct _OBJECT_ALL_INFORMATION +{ + ULONG NumberOfObjectsTypes; + OBJECT_TYPE_INFORMATION ObjectInformation[1]; +} OBJECT_ALL_INFORMATION, *POBJECT_ALL_INFORMATION; + +typedef union _WOW64_APC_CONTEXT { + struct + { + ULONG Apc32BitContext; + ULONG Apc32BitRoutine; + }; + + PVOID Apc64BitContext; + +} WOW64_APC_CONTEXT, *PWOW64_APC_CONTEXT; + +#define WOW64_SIZE_OF_80387_REGISTERS 80 +#define WOW64_MAXIMUM_SUPPORTED_EXTENSION 512 + +typedef struct _WOW64_FLOATING_SAVE_AREA +{ + ULONG ControlWord; + ULONG StatusWord; + ULONG TagWord; + ULONG ErrorOffset; + ULONG ErrorSelector; + ULONG DataOffset; + ULONG DataSelector; + UCHAR RegisterArea[WOW64_SIZE_OF_80387_REGISTERS]; + ULONG Cr0NpxState; +} WOW64_FLOATING_SAVE_AREA; + +#pragma pack(push, 4) + +typedef struct _WOW64_CONTEXT +{ + ULONG ContextFlags; + + ULONG Dr0; + ULONG Dr1; + ULONG Dr2; + ULONG Dr3; + ULONG Dr6; + ULONG Dr7; + + WOW64_FLOATING_SAVE_AREA FloatSave; + + ULONG SegGs; + ULONG SegFs; + ULONG SegEs; + ULONG SegDs; + + ULONG Edi; + ULONG Esi; + ULONG Ebx; + ULONG Edx; + ULONG Ecx; + ULONG Eax; + + ULONG Ebp; + ULONG Eip; + ULONG SegCs; + ULONG EFlags; + ULONG Esp; + ULONG SegSs; + + UCHAR ExtendedRegisters[WOW64_MAXIMUM_SUPPORTED_EXTENSION]; +} WOW64_CONTEXT, *PWOW64_CONTEXT; + +#pragma pack(pop) + +typedef struct _KLDR_DATA_TABLE_ENTRY +{ + LIST_ENTRY InLoadOrderLinks; + PVOID ExceptionTable; + ULONG ExceptionTableSize; + PVOID GpValue; + struct NON_PAGED_DEBUG_INFO *NonPagedDebugInfo; + PVOID DllBase; + PVOID EntryPoint; + ULONG SizeOfImage; + UNICODE_STRING FullDllName; + UNICODE_STRING BaseDllName; + ULONG Flags; + USHORT LoadCount; + union { + USHORT SignatureLevel : 4; + USHORT SignatureType : 3; + USHORT Frozen : 2; + USHORT HotPatch : 1; + USHORT Unused : 6; + USHORT EntireField; + } u1; + PVOID SectionPointer; + ULONG CheckSum; + ULONG CoverageSectionSize; + PVOID CoverageSection; + PVOID LoadedImports; + union { + PVOID Spare; + struct _KLDR_DATA_TABLE_ENTRY *NtDataTableEntry; // win11 + }; + ULONG SizeOfImageNotRounded; + ULONG TimeDateStamp; +} KLDR_DATA_TABLE_ENTRY, *PKLDR_DATA_TABLE_ENTRY; + +typedef struct _OBJECT_HANDLE_ATTRIBUTE_INFORMATION +{ + BOOLEAN Inherit; + BOOLEAN ProtectFromClose; +} OBJECT_HANDLE_ATTRIBUTE_INFORMATION, *POBJECT_HANDLE_ATTRIBUTE_INFORMATION; + +typedef struct _JOBOBJECT_BASIC_PROCESS_ID_LIST +{ + ULONG NumberOfAssignedProcesses; + ULONG NumberOfProcessIdsInList; + ULONG_PTR ProcessIdList[1]; +} JOBOBJECT_BASIC_PROCESS_ID_LIST, *PJOBOBJECT_BASIC_PROCESS_ID_LIST; + +typedef struct _PEB32 +{ + UCHAR InheritedAddressSpace; // 0x0 + UCHAR ReadImageFileExecOptions; // 0x1 + UCHAR BeingDebugged; // 0x2 + union { + UCHAR BitField; // 0x3 + struct + { + UCHAR ImageUsesLargePages : 1; // 0x3 + UCHAR IsProtectedProcess : 1; // 0x3 + UCHAR IsImageDynamicallyRelocated : 1; // 0x3 + UCHAR SkipPatchingUser32Forwarders : 1; // 0x3 + UCHAR IsPackagedProcess : 1; // 0x3 + UCHAR IsAppContainer : 1; // 0x3 + UCHAR IsProtectedProcessLight : 1; // 0x3 + UCHAR IsLongPathAwareProcess : 1; // 0x3 + }; + }; + ULONG Mutant; // 0x4 + ULONG ImageBaseAddress; // 0x8 + ULONG Ldr; // 0xc + ULONG ProcessParameters; // 0x10 + ULONG SubSystemData; // 0x14 + ULONG ProcessHeap; // 0x18 + ULONG FastPebLock; // 0x1c + ULONG AtlThunkSListPtr; // 0x20 + ULONG IFEOKey; // 0x24 + union { + ULONG CrossProcessFlags; // 0x28 + struct + { + ULONG ProcessInJob : 1; // 0x28 + ULONG ProcessInitializing : 1; // 0x28 + ULONG ProcessUsingVEH : 1; // 0x28 + ULONG ProcessUsingVCH : 1; // 0x28 + ULONG ProcessUsingFTH : 1; // 0x28 + ULONG ProcessPreviouslyThrottled : 1; // 0x28 + ULONG ProcessCurrentlyThrottled : 1; // 0x28 + ULONG ProcessImagesHotPatched : 1; // 0x28 + ULONG ReservedBits0 : 24; // 0x28 + }; + }; + union { + ULONG KernelCallbackTable; // 0x2c + ULONG UserSharedInfoPtr; // 0x2c + }; + ULONG SystemReserved; // 0x30 + ULONG AtlThunkSListPtr32; // 0x34 + ULONG ApiSetMap; // 0x38 + ULONG TlsExpansionCounter; // 0x3c + ULONG TlsBitmap; // 0x40 + ULONG TlsBitmapBits[2]; // 0x44 + ULONG ReadOnlySharedMemoryBase; // 0x4c + ULONG SharedData; // 0x50 + ULONG ReadOnlyStaticServerData; // 0x54 + ULONG AnsiCodePageData; // 0x58 + ULONG OemCodePageData; // 0x5c + ULONG UnicodeCaseTableData; // 0x60 + ULONG NumberOfProcessors; // 0x64 + ULONG NtGlobalFlag; // 0x68 + LARGE_INTEGER CriticalSectionTimeout; // 0x70 + ULONG HeapSegmentReserve; // 0x78 + ULONG HeapSegmentCommit; // 0x7c + ULONG HeapDeCommitTotalFreeThreshold; // 0x80 + ULONG HeapDeCommitFreeBlockThreshold; // 0x84 + ULONG NumberOfHeaps; // 0x88 + ULONG MaximumNumberOfHeaps; // 0x8c + ULONG ProcessHeaps; // 0x90 + ULONG GdiSharedHandleTable; // 0x94 + ULONG ProcessStarterHelper; // 0x98 + ULONG GdiDCAttributeList; // 0x9c + ULONG LoaderLock; // 0xa0 + ULONG OSMajorVersion; // 0xa4 + ULONG OSMinorVersion; // 0xa8 + USHORT OSBuildNumber; // 0xac + USHORT OSCSDVersion; // 0xae + ULONG OSPlatformId; // 0xb0 + ULONG ImageSubsystem; // 0xb4 + ULONG ImageSubsystemMajorVersion; // 0xb8 + ULONG ImageSubsystemMinorVersion; // 0xbc + ULONG ActiveProcessAffinityMask; // 0xc0 + ULONG GdiHandleBuffer[34]; // 0xc4 + ULONG PostProcessInitRoutine; // 0x14c + ULONG TlsExpansionBitmap; // 0x150 + ULONG TlsExpansionBitmapBits[32]; // 0x154 + ULONG SessionId; // 0x1d4 + ULARGE_INTEGER AppCompatFlags; // 0x1d8 + ULARGE_INTEGER AppCompatFlagsUser; // 0x1e0 + ULONG pShimData; // 0x1e8 + ULONG AppCompatInfo; // 0x1ec + STRING32 CSDVersion; // 0x1f0 + ULONG ActivationContextData; // 0x1f8 + ULONG ProcessAssemblyStorageMap; // 0x1fc + ULONG SystemDefaultActivationContextData; // 0x200 + ULONG SystemAssemblyStorageMap; // 0x204 + ULONG MinimumStackCommit; // 0x208 + ULONG SparePointers[4]; // 0x20c + ULONG SpareUlongs[5]; // 0x21c + ULONG WerRegistrationData; // 0x230 + ULONG WerShipAssertPtr; // 0x234 + ULONG pUnused; // 0x238 + ULONG pImageHeaderHash; // 0x23c + union { + ULONG TracingFlags; // 0x240 + struct + { + ULONG HeapTracingEnabled : 1; // 0x240 + ULONG CritSecTracingEnabled : 1; // 0x240 + ULONG LibLoaderTracingEnabled : 1; // 0x240 + ULONG SpareTracingBits : 29; // 0x240 + }; + }; + ULONGLONG CsrServerReadOnlySharedMemoryBase; // 0x248 + ULONG TppWorkerpListLock; // 0x250 + LIST_ENTRY32 TppWorkerpList; // 0x254 + ULONG WaitOnAddressHashTable[128]; // 0x25c + ULONG TelemetryCoverageHeader; // 0x45c + ULONG CloudFileFlags; // 0x460 + ULONG CloudFileDiagFlags; // 0x464 + CHAR PlaceholderCompatibilityMode; // 0x468 + CHAR PlaceholderCompatibilityModeReserved[7]; // 0x469 + ULONG LeapSecondData; // 0x470 + union { + ULONG LeapSecondFlags; // 0x474 + struct + { + ULONG SixtySecondEnabled : 1; // 0x474 + ULONG Reserved : 31; // 0x474 + }; + }; + ULONG NtGlobalFlag2; // 0x478 +} PEB32, *PPEB32; + +#pragma warning(pop) + +#define IDE_COMMAND_NOP 0x00 +#define IDE_COMMAND_DATA_SET_MANAGEMENT 0x06 +#define IDE_COMMAND_ATAPI_RESET 0x08 +#define IDE_COMMAND_READ 0x20 +#define IDE_COMMAND_READ_EXT 0x24 +#define IDE_COMMAND_READ_DMA_EXT 0x25 +#define IDE_COMMAND_READ_DMA_QUEUED_EXT 0x26 +#define IDE_COMMAND_READ_MULTIPLE_EXT 0x29 +#define IDE_COMMAND_READ_LOG_EXT 0x2f +#define IDE_COMMAND_WRITE 0x30 +#define IDE_COMMAND_WRITE_EXT 0x34 +#define IDE_COMMAND_WRITE_DMA_EXT 0x35 +#define IDE_COMMAND_WRITE_DMA_QUEUED_EXT 0x36 +#define IDE_COMMAND_WRITE_MULTIPLE_EXT 0x39 +#define IDE_COMMAND_WRITE_DMA_FUA_EXT 0x3D +#define IDE_COMMAND_WRITE_DMA_QUEUED_FUA_EXT 0x3E +#define IDE_COMMAND_WRITE_LOG_EXT 0x3f +#define IDE_COMMAND_VERIFY 0x40 +#define IDE_COMMAND_VERIFY_EXT 0x42 +#define IDE_COMMAND_WRITE_LOG_DMA_EXT 0x57 +#define IDE_COMMAND_TRUSTED_NON_DATA 0x5B +#define IDE_COMMAND_TRUSTED_RECEIVE 0x5C +#define IDE_COMMAND_TRUSTED_RECEIVE_DMA 0x5D +#define IDE_COMMAND_TRUSTED_SEND 0x5E +#define IDE_COMMAND_TRUSTED_SEND_DMA 0x5F +#define IDE_COMMAND_READ_FPDMA_QUEUED 0x60 // NCQ Read command +#define IDE_COMMAND_WRITE_FPDMA_QUEUED 0x61 // NCQ Write command +#define IDE_COMMAND_NCQ_NON_DATA 0x63 // NCQ Non-Data command +#define IDE_COMMAND_SEND_FPDMA_QUEUED 0x64 // NCQ Send command +#define IDE_COMMAND_RECEIVE_FPDMA_QUEUED 0x65 // NCQ Receive command +#define IDE_COMMAND_SET_DATE_AND_TIME 0x77 // optional 48bit command +#define IDE_COMMAND_EXECUTE_DEVICE_DIAGNOSTIC 0x90 +#define IDE_COMMAND_SET_DRIVE_PARAMETERS 0x91 +#define IDE_COMMAND_ATAPI_PACKET 0xA0 +#define IDE_COMMAND_ATAPI_IDENTIFY 0xA1 +#define IDE_COMMAND_SMART 0xB0 +#define IDE_COMMAND_READ_LOG_DMA_EXT 0xB1 +#define IDE_COMMAND_SANITIZE_DEVICE 0xB4 +#define IDE_COMMAND_READ_MULTIPLE 0xC4 +#define IDE_COMMAND_WRITE_MULTIPLE 0xC5 +#define IDE_COMMAND_SET_MULTIPLE 0xC6 +#define IDE_COMMAND_READ_DMA 0xC8 +#define IDE_COMMAND_WRITE_DMA 0xCA +#define IDE_COMMAND_WRITE_DMA_QUEUED 0xCC +#define IDE_COMMAND_WRITE_MULTIPLE_FUA_EXT 0xCE +#define IDE_COMMAND_GET_MEDIA_STATUS 0xDA +#define IDE_COMMAND_DOOR_LOCK 0xDE +#define IDE_COMMAND_DOOR_UNLOCK 0xDF +#define IDE_COMMAND_STANDBY_IMMEDIATE 0xE0 +#define IDE_COMMAND_IDLE_IMMEDIATE 0xE1 +#define IDE_COMMAND_CHECK_POWER 0xE5 +#define IDE_COMMAND_SLEEP 0xE6 +#define IDE_COMMAND_FLUSH_CACHE 0xE7 +#define IDE_COMMAND_FLUSH_CACHE_EXT 0xEA +#define IDE_COMMAND_IDENTIFY 0xEC +#define IDE_COMMAND_MEDIA_EJECT 0xED +#define IDE_COMMAND_SET_FEATURE 0xEF +#define IDE_COMMAND_SECURITY_SET_PASSWORD 0xF1 +#define IDE_COMMAND_SECURITY_UNLOCK 0xF2 +#define IDE_COMMAND_SECURITY_ERASE_PREPARE 0xF3 +#define IDE_COMMAND_SECURITY_ERASE_UNIT 0xF4 +#define IDE_COMMAND_SECURITY_FREEZE_LOCK 0xF5 +#define IDE_COMMAND_SECURITY_DISABLE_PASSWORD 0xF6 +#define IDE_COMMAND_NOT_VALID 0xFF + +#define IDE_STATUS_ERROR 0x01 +#define IDE_STATUS_INDEX 0x02 +#define IDE_STATUS_CORRECTED_ERROR 0x04 +#define IDE_STATUS_DRQ 0x08 +#define IDE_STATUS_DSC 0x10 +#define IDE_STATUS_DEVICE_FAULT 0x20 +#define IDE_STATUS_DRDY 0x40 +#define IDE_STATUS_IDLE 0x50 +#define IDE_STATUS_BUSY 0x80 + +typedef struct _IDSECTOR +{ + USHORT wGenConfig; + USHORT wNumCyls; + USHORT wReserved; + USHORT wNumHeads; + USHORT wBytesPerTrack; + USHORT wBytesPerSector; + USHORT wSectorsPerTrack; + USHORT wVendorUnique[3]; + CHAR sSerialNumber[20]; + USHORT wBufferType; + USHORT wBufferSize; + USHORT wECCSize; + CHAR sFirmwareRev[8]; + CHAR sModelNumber[40]; + USHORT wMoreVendorUnique; + USHORT wDoubleWordIO; + USHORT wCapabilities; + USHORT wReserved1; + USHORT wPIOTiming; + USHORT wDMATiming; + USHORT wBS; + USHORT wNumCurrentCyls; + USHORT wNumCurrentHeads; + USHORT wNumCurrentSectorsPerTrack; + ULONG ulCurrentSectorCapacity; + USHORT wMultSectorStuff; + ULONG ulTotalAddressableSectors; + USHORT wSingleWordDMA; + USHORT wMultiWordDMA; + UCHAR bReserved[128]; +} IDSECTOR, *PIDSECTOR; + +#pragma pack(push, 1) +typedef struct _IDENTIFY_DEVICE_DATA +{ + struct + { + USHORT Reserved1 : 1; + USHORT Retired3 : 1; + USHORT ResponseIncomplete : 1; + USHORT Retired2 : 3; + USHORT FixedDevice : 1; // obsolete + USHORT RemovableMedia : 1; // obsolete + USHORT Retired1 : 7; + USHORT DeviceType : 1; + } GeneralConfiguration; // word 0 + + USHORT NumCylinders; // word 1, obsolete + USHORT SpecificConfiguration; // word 2 + USHORT NumHeads; // word 3, obsolete + USHORT Retired1[2]; + USHORT NumSectorsPerTrack; // word 6, obsolete + USHORT VendorUnique1[3]; + UCHAR SerialNumber[20]; // word 10-19 + USHORT Retired2[2]; + USHORT Obsolete1; + UCHAR FirmwareRevision[8]; // word 23-26 + UCHAR ModelNumber[40]; // word 27-46 + UCHAR MaximumBlockTransfer; // word 47. 01h-10h = Maximum number of sectors that shall be transferred per interrupt + // on READ/WRITE MULTIPLE commands + UCHAR VendorUnique2; + + struct + { + USHORT FeatureSupported : 1; + USHORT Reserved : 15; + } TrustedComputing; // word 48 + + struct + { + UCHAR CurrentLongPhysicalSectorAlignment : 2; + UCHAR ReservedByte49 : 6; + + UCHAR DmaSupported : 1; + UCHAR LbaSupported : 1; // Shall be set to one to indicate that LBA is supported. + UCHAR IordyDisable : 1; + UCHAR IordySupported : 1; + UCHAR Reserved1 : 1; // Reserved for the IDENTIFY PACKET DEVICE command + UCHAR StandybyTimerSupport : 1; + UCHAR Reserved2 : 2; // Reserved for the IDENTIFY PACKET DEVICE command + + USHORT ReservedWord50; + } Capabilities; // word 49-50 + + USHORT ObsoleteWords51[2]; + + USHORT TranslationFieldsValid : 3; // word 53, bit 0 - Obsolete; bit 1 - words 70:64 valid; bit 2; word 88 valid + USHORT Reserved3 : 5; + USHORT FreeFallControlSensitivity : 8; + + USHORT NumberOfCurrentCylinders; // word 54, obsolete + USHORT NumberOfCurrentHeads; // word 55, obsolete + USHORT CurrentSectorsPerTrack; // word 56, obsolete + ULONG CurrentSectorCapacity; // word 57, word 58, obsolete + + UCHAR CurrentMultiSectorSetting; // word 59 + UCHAR MultiSectorSettingValid : 1; + UCHAR ReservedByte59 : 3; + UCHAR SanitizeFeatureSupported : 1; + UCHAR CryptoScrambleExtCommandSupported : 1; + UCHAR OverwriteExtCommandSupported : 1; + UCHAR BlockEraseExtCommandSupported : 1; + + ULONG UserAddressableSectors; // word 60-61, for 28-bit commands + + USHORT ObsoleteWord62; + + USHORT MultiWordDMASupport : 8; // word 63 + USHORT MultiWordDMAActive : 8; + + USHORT AdvancedPIOModes : 8; // word 64. bit 0:1 - PIO mode supported + USHORT ReservedByte64 : 8; + + USHORT MinimumMWXferCycleTime; // word 65 + USHORT RecommendedMWXferCycleTime; // word 66 + USHORT MinimumPIOCycleTime; // word 67 + USHORT MinimumPIOCycleTimeIORDY; // word 68 + + struct + { + USHORT Reserved : 2; + USHORT NonVolatileWriteCache : 1; // All write cache is non-volatile + USHORT ExtendedUserAddressableSectorsSupported : 1; + USHORT DeviceEncryptsAllUserData : 1; + USHORT ReadZeroAfterTrimSupported : 1; + USHORT Optional28BitCommandsSupported : 1; + USHORT IEEE1667 : 1; // Reserved for IEEE 1667 + USHORT DownloadMicrocodeDmaSupported : 1; + USHORT SetMaxSetPasswordUnlockDmaSupported : 1; + USHORT WriteBufferDmaSupported : 1; + USHORT ReadBufferDmaSupported : 1; + USHORT DeviceConfigIdentifySetDmaSupported : 1; // obsolete + USHORT LPSAERCSupported : 1; // Long Physical Sector Alignment Error Reporting Control is supported. + USHORT DeterministicReadAfterTrimSupported : 1; + USHORT CFastSpecSupported : 1; + } AdditionalSupported; // word 69 + + USHORT ReservedWords70[5]; // word 70 - reserved + // word 71:74 - Reserved for the IDENTIFY PACKET DEVICE command + + // Word 75 + USHORT QueueDepth : 5; // Maximum queue depth - 1 + USHORT ReservedWord75 : 11; + + struct + { + // Word 76 + USHORT Reserved0 : 1; // shall be set to 0 + USHORT SataGen1 : 1; // Supports SATA Gen1 Signaling Speed (1.5Gb/s) + USHORT SataGen2 : 1; // Supports SATA Gen2 Signaling Speed (3.0Gb/s) + USHORT SataGen3 : 1; // Supports SATA Gen3 Signaling Speed (6.0Gb/s) + + USHORT Reserved1 : 4; + + USHORT NCQ : 1; // Supports the NCQ feature set + USHORT HIPM : 1; // Supports HIPM + USHORT PhyEvents : 1; // Supports the SATA Phy Event Counters log + USHORT NcqUnload : 1; // Supports Unload while NCQ commands are outstanding + + USHORT NcqPriority : 1; // Supports NCQ priority information + USHORT HostAutoPS : 1; // Supports Host Automatic Partial to Slumber transitions + USHORT DeviceAutoPS : 1; // Supports Device Automatic Partial to Slumber transitions + USHORT ReadLogDMA : 1; // Supports READ LOG DMA EXT as equivalent to READ LOG EXT + + // Word 77 + USHORT Reserved2 : 1; // shall be set to 0 + USHORT CurrentSpeed : 3; // Coded value indicating current negotiated Serial ATA signal speed + + USHORT NcqStreaming : 1; // Supports NCQ Streaming + USHORT NcqQueueMgmt : 1; // Supports NCQ Queue Management Command + USHORT NcqReceiveSend : 1; // Supports RECEIVE FPDMA QUEUED and SEND FPDMA QUEUED commands + USHORT DEVSLPtoReducedPwrState : 1; + + USHORT Reserved3 : 8; + } SerialAtaCapabilities; + + // Word 78 + struct + { + USHORT Reserved0 : 1; // shall be set to 0 + USHORT NonZeroOffsets : 1; // Device supports non-zero buffer offsets in DMA Setup FIS + USHORT DmaSetupAutoActivate : 1; // Device supports DMA Setup auto-activation + USHORT DIPM : 1; // Device supports DIPM + + USHORT InOrderData : 1; // Device supports in-order data delivery + USHORT HardwareFeatureControl : 1; // Hardware Feature Control is supported + USHORT SoftwareSettingsPreservation : 1; // Device supports Software Settings Preservation + USHORT NCQAutosense : 1; // Supports NCQ Autosense + + USHORT DEVSLP : 1; // Device supports link power state - device sleep + USHORT HybridInformation : 1; // Device supports Hybrid Information Feature (If the device does not support NCQ + // (word 76 bit 8 is 0), then this bit shall be cleared to 0.) + + USHORT Reserved1 : 6; + } SerialAtaFeaturesSupported; + + // Word 79 + struct + { + USHORT Reserved0 : 1; // shall be set to 0 + USHORT NonZeroOffsets : 1; // Non-zero buffer offsets in DMA Setup FIS enabled + USHORT DmaSetupAutoActivate : 1; // DMA Setup auto-activation optimization enabled + USHORT DIPM : 1; // DIPM enabled + + USHORT InOrderData : 1; // In-order data delivery enabled + USHORT HardwareFeatureControl : 1; // Hardware Feature Control is enabled + USHORT SoftwareSettingsPreservation : 1; // Software Settings Preservation enabled + USHORT DeviceAutoPS : 1; // Device Automatic Partial to Slumber transitions enabled + + USHORT DEVSLP : 1; // link power state - device sleep is enabled + USHORT HybridInformation : 1; // Hybrid Information Feature is enabled + + USHORT Reserved1 : 6; + } SerialAtaFeaturesEnabled; + + USHORT MajorRevision; // word 80. bit 5 - supports ATA5; bit 6 - supports ATA6; bit 7 - supports ATA7; bit 8 - + // supports ATA8-ACS; bit 9 - supports ACS-2; + USHORT MinorRevision; // word 81. T13 minior version number + + struct + { + + // + // Word 82 + // + USHORT SmartCommands : 1; // The SMART feature set is supported + USHORT SecurityMode : 1; // The Security feature set is supported + USHORT RemovableMediaFeature : 1; // obsolete + USHORT PowerManagement : 1; // shall be set to 1 + USHORT Reserved1 : 1; // PACKET feature set, set to 0 indicates not supported for ATA devices (only support for + // ATAPI devices) + USHORT WriteCache : 1; // The volatile write cache is supported + USHORT LookAhead : 1; // Read look-ahead is supported + USHORT ReleaseInterrupt : 1; // obsolete + USHORT ServiceInterrupt : 1; // obsolete + USHORT DeviceReset : 1; // Shall be cleared to zero to indicate that the DEVICE RESET command is not supported + USHORT HostProtectedArea : 1; // obsolete + USHORT Obsolete1 : 1; + USHORT WriteBuffer : 1; // The WRITE BUFFER command is supported + USHORT ReadBuffer : 1; // The READ BUFFER command is supported + USHORT Nop : 1; // The NOP command is supported + USHORT Obsolete2 : 1; + + // + // Word 83 + // + USHORT DownloadMicrocode : 1; // The DOWNLOAD MICROCODE command is supported + USHORT DmaQueued : 1; // obsolete + USHORT Cfa : 1; // The CFA feature set is supported + USHORT AdvancedPm : 1; // The APM feature set is supported + USHORT Msn : 1; // obsolete + USHORT PowerUpInStandby : 1; // The PUIS feature set is supported + USHORT ManualPowerUp : 1; // SET FEATURES subcommand is required to spin-up after power-up + USHORT Reserved2 : 1; + USHORT SetMax : 1; // obsolete + USHORT Acoustics : 1; // obsolete + USHORT BigLba : 1; // The 48-bit Address feature set is supported + USHORT DeviceConfigOverlay : 1; // obsolete + USHORT FlushCache : 1; // Shall be set to one to indicate that the mandatory FLUSH CACHE command is supported + USHORT FlushCacheExt : 1; // The FLUSH CACHE EXT command is supported + USHORT WordValid83 : 2; // shall be 01b + + // + // Word 84 + // + USHORT SmartErrorLog : 1; // SMART error logging is supported + USHORT SmartSelfTest : 1; // The SMART self-test is supported + USHORT MediaSerialNumber : 1; // Media serial number is supported + USHORT MediaCardPassThrough : 1; // obsolete + USHORT StreamingFeature : 1; // The Streaming feature set is supported + USHORT GpLogging : 1; // The GPL feature set is supported + USHORT WriteFua : 1; // The WRITE DMA FUA EXT and WRITE MULTIPLE FUA EXT commands are supported + USHORT WriteQueuedFua : 1; // obsolete + USHORT WWN64Bit : 1; // The 64-bit World wide name is supported + USHORT URGReadStream : 1; // obsolete + USHORT URGWriteStream : 1; // obsolete + USHORT ReservedForTechReport : 2; + USHORT IdleWithUnloadFeature : 1; // The IDLE IMMEDIATE command with UNLOAD feature is supported + USHORT WordValid : 2; // shall be 01b + + } CommandSetSupport; + + struct + { + + // + // Word 85 + // + USHORT SmartCommands : 1; // The SMART feature set is enabled + USHORT SecurityMode : 1; // The Security feature set is enabled + USHORT RemovableMediaFeature : 1; // obsolete + USHORT PowerManagement : 1; // Shall be set to one to indicate that the mandatory Power Management feature set + // is supported + USHORT Reserved1 : 1; // Shall be cleared to zero to indicate that the PACKET feature set is not supported + USHORT WriteCache : 1; // The volatile write cache is enabled + USHORT LookAhead : 1; // Read look-ahead is enabled + USHORT ReleaseInterrupt : 1; // The release interrupt is enabled + USHORT ServiceInterrupt : 1; // The SERVICE interrupt is enabled + USHORT DeviceReset : 1; // Shall be cleared to zero to indicate that the DEVICE RESET command is not supported + USHORT HostProtectedArea : 1; // obsolete + USHORT Obsolete1 : 1; + USHORT WriteBuffer : 1; // The WRITE BUFFER command is supported + USHORT ReadBuffer : 1; // The READ BUFFER command is supported + USHORT Nop : 1; // The NOP command is supported + USHORT Obsolete2 : 1; + + // + // Word 86 + // + USHORT DownloadMicrocode : 1; // The DOWNLOAD MICROCODE command is supported + USHORT DmaQueued : 1; // obsolete + USHORT Cfa : 1; // The CFA feature set is supported + USHORT AdvancedPm : 1; // The APM feature set is enabled + USHORT Msn : 1; // obsolete + USHORT PowerUpInStandby : 1; // The PUIS feature set is enabled + USHORT ManualPowerUp : 1; // SET FEATURES subcommand is required to spin-up after power-up + USHORT Reserved2 : 1; + USHORT SetMax : 1; // obsolete + USHORT Acoustics : 1; // obsolete + USHORT BigLba : 1; // The 48-bit Address features set is supported + USHORT DeviceConfigOverlay : 1; // obsolete + USHORT FlushCache : 1; // FLUSH CACHE command supported + USHORT FlushCacheExt : 1; // FLUSH CACHE EXT command supported + USHORT Resrved3 : 1; + USHORT Words119_120Valid : 1; // Words 119..120 are valid + + // + // Word 87 + // + USHORT SmartErrorLog : 1; // SMART error logging is supported + USHORT SmartSelfTest : 1; // SMART self-test supported + USHORT MediaSerialNumber : 1; // Media serial number is valid + USHORT MediaCardPassThrough : 1; // obsolete + USHORT StreamingFeature : 1; // obsolete + USHORT GpLogging : 1; // The GPL feature set is supported + USHORT WriteFua : 1; // The WRITE DMA FUA EXT and WRITE MULTIPLE FUA EXT commands are supported + USHORT WriteQueuedFua : 1; // obsolete + USHORT WWN64Bit : 1; // The 64-bit World wide name is supported + USHORT URGReadStream : 1; // obsolete + USHORT URGWriteStream : 1; // obsolete + USHORT ReservedForTechReport : 2; + USHORT IdleWithUnloadFeature : 1; // The IDLE IMMEDIATE command with UNLOAD FEATURE is supported + USHORT Reserved4 : 2; // bit 14 shall be set to 1; bit 15 shall be cleared to 0 + + } CommandSetActive; + + USHORT UltraDMASupport : 8; // word 88. bit 0 - UDMA mode 0 is supported ... bit 6 - UDMA mode 6 and below are + // supported + USHORT UltraDMAActive : 8; // word 88. bit 8 - UDMA mode 0 is selected ... bit 14 - UDMA mode 6 is selected + + struct + { // word 89 + USHORT TimeRequired : 15; + USHORT ExtendedTimeReported : 1; + } NormalSecurityEraseUnit; + + struct + { // word 90 + USHORT TimeRequired : 15; + USHORT ExtendedTimeReported : 1; + } EnhancedSecurityEraseUnit; + + USHORT CurrentAPMLevel : 8; // word 91 + USHORT ReservedWord91 : 8; + + USHORT MasterPasswordID; // word 92. Master Password Identifier + + USHORT HardwareResetResult; // word 93 + + USHORT CurrentAcousticValue : 8; // word 94. obsolete + USHORT RecommendedAcousticValue : 8; + + USHORT StreamMinRequestSize; // word 95 + USHORT StreamingTransferTimeDMA; // word 96 + USHORT StreamingAccessLatencyDMAPIO; // word 97 + ULONG StreamingPerfGranularity; // word 98, 99 + + ULONG Max48BitLBA[2]; // word 100-103 + + USHORT StreamingTransferTime; // word 104. Streaming Transfer Time - PIO + + USHORT DsmCap; // word 105 + + struct + { + USHORT LogicalSectorsPerPhysicalSector : 4; // n power of 2: logical sectors per physical sector + USHORT Reserved0 : 8; + USHORT LogicalSectorLongerThan256Words : 1; + USHORT MultipleLogicalSectorsPerPhysicalSector : 1; + USHORT Reserved1 : 2; // bit 14 - shall be set to 1; bit 15 - shall be clear to 0 + } PhysicalLogicalSectorSize; // word 106 + + USHORT InterSeekDelay; // word 107. Inter-seek delay for ISO 7779 standard acoustic testing + USHORT WorldWideName[4]; // words 108-111 + USHORT ReservedForWorldWideName128[4]; // words 112-115 + USHORT ReservedForTlcTechnicalReport; // word 116 + USHORT WordsPerLogicalSector[2]; // words 117-118 Logical sector size (DWord) + + struct + { + USHORT ReservedForDrqTechnicalReport : 1; + USHORT WriteReadVerify : 1; // The Write-Read-Verify feature set is supported + USHORT WriteUncorrectableExt : 1; // The WRITE UNCORRECTABLE EXT command is supported + USHORT ReadWriteLogDmaExt : 1; // The READ LOG DMA EXT and WRITE LOG DMA EXT commands are supported + USHORT DownloadMicrocodeMode3 : 1; // Download Microcode mode 3 is supported + USHORT FreefallControl : 1; // The Free-fall Control feature set is supported + USHORT SenseDataReporting : 1; // Sense Data Reporting feature set is supported + USHORT ExtendedPowerConditions : 1; // Extended Power Conditions feature set is supported + USHORT Reserved0 : 6; + USHORT WordValid : 2; // shall be 01b + } CommandSetSupportExt; // word 119 + + struct + { + USHORT ReservedForDrqTechnicalReport : 1; + USHORT WriteReadVerify : 1; // The Write-Read-Verify feature set is enabled + USHORT WriteUncorrectableExt : 1; // The WRITE UNCORRECTABLE EXT command is supported + USHORT ReadWriteLogDmaExt : 1; // The READ LOG DMA EXT and WRITE LOG DMA EXT commands are supported + USHORT DownloadMicrocodeMode3 : 1; // Download Microcode mode 3 is supported + USHORT FreefallControl : 1; // The Free-fall Control feature set is enabled + USHORT SenseDataReporting : 1; // Sense Data Reporting feature set is enabled + USHORT ExtendedPowerConditions : 1; // Extended Power Conditions feature set is enabled + USHORT Reserved0 : 6; + USHORT Reserved1 : 2; // bit 14 - shall be set to 1; bit 15 - shall be clear to 0 + } CommandSetActiveExt; // word 120 + + USHORT ReservedForExpandedSupportandActive[6]; + + USHORT MsnSupport : 2; // word 127. obsolete + USHORT ReservedWord127 : 14; + + struct + { // word 128 + USHORT SecuritySupported : 1; + USHORT SecurityEnabled : 1; + USHORT SecurityLocked : 1; + USHORT SecurityFrozen : 1; + USHORT SecurityCountExpired : 1; + USHORT EnhancedSecurityEraseSupported : 1; + USHORT Reserved0 : 2; + USHORT SecurityLevel : 1; // Master Password Capability: 0 = High, 1 = Maximum + USHORT Reserved1 : 7; + } SecurityStatus; + + USHORT ReservedWord129[31]; // word 129...159. Vendor specific + + struct + { // word 160 + USHORT MaximumCurrentInMA : 12; + USHORT CfaPowerMode1Disabled : 1; + USHORT CfaPowerMode1Required : 1; + USHORT Reserved0 : 1; + USHORT Word160Supported : 1; + } CfaPowerMode1; + + USHORT ReservedForCfaWord161[7]; // Words 161-167 + + USHORT NominalFormFactor : 4; // Word 168 + USHORT ReservedWord168 : 12; + + struct + { // Word 169 + USHORT SupportsTrim : 1; + USHORT Reserved0 : 15; + } DataSetManagementFeature; + + USHORT AdditionalProductID[4]; // Words 170-173 + + USHORT ReservedForCfaWord174[2]; // Words 174-175 + + USHORT CurrentMediaSerialNumber[30]; // Words 176-205 + + struct + { // Word 206 + USHORT Supported : 1; // The SCT Command Transport is supported + USHORT Reserved0 : 1; // obsolete + USHORT WriteSameSuported : 1; // The SCT Write Same command is supported + USHORT ErrorRecoveryControlSupported : 1; // The SCT Error Recovery Control command is supported + USHORT FeatureControlSuported : 1; // The SCT Feature Control command is supported + USHORT DataTablesSuported : 1; // The SCT Data Tables command is supported + USHORT Reserved1 : 6; + USHORT VendorSpecific : 4; + } SCTCommandTransport; + + USHORT ReservedWord207[2]; // Words 207-208 + + struct + { // Word 209 + USHORT AlignmentOfLogicalWithinPhysical : 14; + USHORT Word209Supported : 1; // shall be set to 1 + USHORT Reserved0 : 1; // shall be cleared to 0 + } BlockAlignment; + + USHORT WriteReadVerifySectorCountMode3Only[2]; // Words 210-211 + USHORT WriteReadVerifySectorCountMode2Only[2]; // Words 212-213 + + struct + { + USHORT NVCachePowerModeEnabled : 1; + USHORT Reserved0 : 3; + USHORT NVCacheFeatureSetEnabled : 1; + USHORT Reserved1 : 3; + USHORT NVCachePowerModeVersion : 4; + USHORT NVCacheFeatureSetVersion : 4; + } NVCacheCapabilities; // Word 214. obsolete + USHORT NVCacheSizeLSW; // Word 215. obsolete + USHORT NVCacheSizeMSW; // Word 216. obsolete + + USHORT NominalMediaRotationRate; // Word 217; value 0001h means non-rotating media. + + USHORT ReservedWord218; // Word 218 + + struct + { + UCHAR NVCacheEstimatedTimeToSpinUpInSeconds; + UCHAR Reserved; + } NVCacheOptions; // Word 219. obsolete + + USHORT WriteReadVerifySectorCountMode : 8; // Word 220. Write-Read-Verify feature set current mode + USHORT ReservedWord220 : 8; + + USHORT ReservedWord221; // Word 221 + + struct + { // Word 222 Transport major version number + USHORT MajorVersion : 12; // 0000h or FFFFh = device does not report version + USHORT TransportType : 4; + } TransportMajorVersion; + + USHORT TransportMinorVersion; // Word 223 + + USHORT ReservedWord224[6]; // Word 224...229 + + ULONG ExtendedNumberOfUserAddressableSectors[2]; // Words 230...233 Extended Number of User Addressable Sectors + + USHORT MinBlocksPerDownloadMicrocodeMode03; // Word 234 Minimum number of 512-byte data blocks per Download + // Microcode mode 03h operation + USHORT MaxBlocksPerDownloadMicrocodeMode03; // Word 235 Maximum number of 512-byte data blocks per Download + // Microcode mode 03h operation + + USHORT ReservedWord236[19]; // Word 236...254 + + USHORT Signature : 8; // Word 255 + USHORT CheckSum : 8; + +} IDENTIFY_DEVICE_DATA, *PIDENTIFY_DEVICE_DATA; +#pragma pack(pop) + +typedef struct _HEAP_UNPACKED_ENTRY +{ + VOID *PreviousBlockPrivateData; // 0x0 + union { + struct + { + USHORT Size; // 0x8 + UCHAR Flags; // 0xa + UCHAR SmallTagIndex; // 0xb + } set1; + struct + { + ULONG SubSegmentCode; // 0x8 + USHORT PreviousSize; // 0xc + union { + UCHAR SegmentOffset; // 0xe + UCHAR LFHFlags; // 0xe + }; + UCHAR UnusedBytes; // 0xf + } set2; + ULONGLONG CompactHeader; // 0x8 + }; +} HEAP_UNPACKED_ENTRY, *PHEAP_UNPACKED_ENTRY; + +typedef struct _HEAP_EXTENDED_ENTRY +{ + VOID *Reserved; // 0x0 + union { + struct + { + USHORT FunctionIndex; // 0x8 + USHORT ContextValue; // 0xa + }; + ULONG InterceptorValue; // 0x8 + }; + USHORT UnusedBytesLength; // 0xc + UCHAR EntryOffset; // 0xe + UCHAR ExtendedBlockSignature; // 0xf +} HEAP_EXTENDED_ENTRY, *PHEAP_EXTENDED_ENTRY; + +typedef struct _HEAP_ENTRY +{ + union { + HEAP_UNPACKED_ENTRY UnpackedEntry; // 0x0 + struct + { + VOID *PreviousBlockPrivateData; // 0x0 + union { + struct + { + USHORT Size; // 0x8 + UCHAR Flags; // 0xa + UCHAR SmallTagIndex; // 0xb + }; + struct + { + ULONG SubSegmentCode; // 0x8 + USHORT PreviousSize; // 0xc + union { + UCHAR SegmentOffset; // 0xe + UCHAR LFHFlags; // 0xe + }; + UCHAR UnusedBytes; // 0xf + }; + ULONGLONG CompactHeader; // 0x8 + }; + }; + HEAP_EXTENDED_ENTRY ExtendedEntry; // 0x0 + struct + { + VOID *Reserved; // 0x0 + union { + struct + { + USHORT FunctionIndex; // 0x8 + USHORT ContextValue; // 0xa + }; + ULONG InterceptorValue; // 0x8 + }; + USHORT UnusedBytesLength; // 0xc + UCHAR EntryOffset; // 0xe + UCHAR ExtendedBlockSignature; // 0xf + }; + struct + { + VOID *ReservedForAlignment; // 0x0 + union { + struct + { + ULONG Code1; // 0x8 + union { + struct + { + USHORT Code2; // 0xc + UCHAR Code3; // 0xe + UCHAR Code4; // 0xf + }; + ULONG Code234; // 0xc + }; + }; + ULONGLONG AgregateCode; // 0x8 + }; + }; + }; +} HEAP_ENTRY, *PHEAP_ENTRY; + +typedef struct _HEAP_SEGMENT +{ + HEAP_ENTRY Entry; // 0x0 + ULONG SegmentSignature; // 0x10 + ULONG SegmentFlags; // 0x14 + LIST_ENTRY SegmentListEntry; // 0x18 + VOID *Heap; // 0x28 + VOID *BaseAddress; // 0x30 + ULONG NumberOfPages; // 0x38 + HEAP_ENTRY *FirstEntry; // 0x40 + HEAP_ENTRY *LastValidEntry; // 0x48 + ULONG NumberOfUnCommittedPages; // 0x50 + ULONG NumberOfUnCommittedRanges; // 0x54 + USHORT SegmentAllocatorBackTraceIndex; // 0x58 + USHORT Reserved; // 0x5a + LIST_ENTRY UCRSegmentList; // 0x60 +} HEAP_SEGMENT, *PHEAP_SEGMENT; + +typedef struct _HEAP_TAG_ENTRY +{ + ULONG Allocs; // 0x0 + ULONG Frees; // 0x4 + ULONGLONG Size; // 0x8 + USHORT TagIndex; // 0x10 + USHORT CreatorBackTraceIndex; // 0x12 + WCHAR TagName[24]; // 0x14 +} HEAP_TAG_ENTRY, *PHEAP_TAG_ENTRY; + +typedef struct _HEAP_PSEUDO_TAG_ENTRY +{ + ULONG Allocs; // 0x0 + ULONG Frees; // 0x4 + ULONGLONG Size; // 0x8 +} HEAP_PSEUDO_TAG_ENTRY, *PHEAP_PSEUDO_TAG_ENTRY; + +// typedef struct _HEAP_LOCK +//{ +// union +// { +// RTL_CRITICAL_SECTION CriticalSection; //0x0 +// ERESOURCE Resource; //0x0 +// } Lock; //0x0 +// }HEAP_LOCK, * PHEAP_LOCK; + +// typedef struct _RTL_HEAP_MEMORY_LIMIT_DATA +//{ +// ULONGLONG CommitLimitBytes; //0x0 +// ULONGLONG CommitLimitFailureCode; //0x8 +// ULONGLONG MaxAllocationSizeBytes; //0x10 +// ULONGLONG AllocationLimitFailureCode; //0x18 +// }RTL_HEAP_MEMORY_LIMIT_DATA, * PRTL_HEAP_MEMORY_LIMIT_DATA; + +typedef struct _HEAP_COUNTERS +{ + ULONGLONG TotalMemoryReserved; // 0x0 + ULONGLONG TotalMemoryCommitted; // 0x8 + ULONGLONG TotalMemoryLargeUCR; // 0x10 + ULONGLONG TotalSizeInVirtualBlocks; // 0x18 + ULONG TotalSegments; // 0x20 + ULONG TotalUCRs; // 0x24 + ULONG CommittOps; // 0x28 + ULONG DeCommitOps; // 0x2c + ULONG LockAcquires; // 0x30 + ULONG LockCollisions; // 0x34 + ULONG CommitRate; // 0x38 + ULONG DecommittRate; // 0x3c + ULONG CommitFailures; // 0x40 + ULONG InBlockCommitFailures; // 0x44 + ULONG PollIntervalCounter; // 0x48 + ULONG DecommitsSinceLastCheck; // 0x4c + ULONG HeapPollInterval; // 0x50 + ULONG AllocAndFreeOps; // 0x54 + ULONG AllocationIndicesActive; // 0x58 + ULONG InBlockDeccommits; // 0x5c + ULONGLONG InBlockDeccomitSize; // 0x60 + ULONGLONG HighWatermarkSize; // 0x68 + ULONGLONG LastPolledSize; // 0x70 +} HEAP_COUNTERS, *PHEAP_COUNTERS; + +typedef struct _HEAP_TUNING_PARAMETERS +{ + ULONG CommittThresholdShift; // 0x0 + ULONGLONG MaxPreCommittThreshold; // 0x8 +} HEAP_TUNING_PARAMETERS, *PHEAP_TUNING_PARAMETERS; + +typedef struct _HEAP +{ + union { + HEAP_SEGMENT Segment; // 0x0 + struct + { + HEAP_ENTRY Entry; // 0x0 + ULONG SegmentSignature; // 0x10 //0x8 + ULONG SegmentFlags; // 0x14 //0xC + LIST_ENTRY SegmentListEntry; // 0x18 //0x10 + VOID *Heap; // 0x28 //0x18 + VOID *BaseAddress; // 0x30 //0x1c + ULONG NumberOfPages; // 0x38 //0x20 + HEAP_ENTRY *FirstEntry; // 0x40 //0x24 + HEAP_ENTRY *LastValidEntry; // 0x48 //0x28 + ULONG NumberOfUnCommittedPages; // 0x50 //0x2c + ULONG NumberOfUnCommittedRanges; // 0x54 + USHORT SegmentAllocatorBackTraceIndex; // 0x58 + USHORT Reserved; // 0x5a + LIST_ENTRY UCRSegmentList; // 0x60 + }; + }; + ULONG Flags; // 0x70 + ULONG ForceFlags; // 0x74 + ULONG CompatibilityFlags; // 0x78 + ULONG EncodeFlagMask; // 0x7c + HEAP_ENTRY Encoding; // 0x80 + ULONG Interceptor; // 0x90 + ULONG VirtualMemoryThreshold; // 0x94 + ULONG Signature; // 0x98 + ULONGLONG SegmentReserve; // 0xa0 + ULONGLONG SegmentCommit; // 0xa8 + ULONGLONG DeCommitFreeBlockThreshold; // 0xb0 + ULONGLONG DeCommitTotalFreeThreshold; // 0xb8 + ULONGLONG TotalFreeSize; // 0xc0 + ULONGLONG MaximumAllocationSize; // 0xc8 + USHORT ProcessHeapsListIndex; // 0xd0 + USHORT HeaderValidateLength; // 0xd2 + VOID *HeaderValidateCopy; // 0xd8 + USHORT NextAvailableTagIndex; // 0xe0 + USHORT MaximumTagIndex; // 0xe2 + PHEAP_TAG_ENTRY TagEntries; // 0xe8 + LIST_ENTRY UCRList; // 0xf0 + ULONGLONG AlignRound; // 0x100 + ULONGLONG AlignMask; // 0x108 + LIST_ENTRY VirtualAllocdBlocks; // 0x110 + LIST_ENTRY SegmentList; // 0x120 + USHORT AllocatorBackTraceIndex; // 0x130 + ULONG NonDedicatedListLength; // 0x134 + VOID *BlocksIndex; // 0x138 + VOID *UCRIndex; // 0x140 + PHEAP_PSEUDO_TAG_ENTRY PseudoTagEntries; // 0x148 + LIST_ENTRY FreeLists; // 0x150 + PVOID LockVariable; // 0x160 + LONG (*CommitRoutine)(VOID *arg1, VOID **arg2, ULONGLONG *arg3); // 0x168 + RTL_RUN_ONCE StackTraceInitVar; // 0x170 + VOID *CommitLimitData; // 0x178 + VOID *FrontEndHeap; // 0x198 + USHORT FrontHeapLockCount; // 0x1a0 + UCHAR FrontEndHeapType; // 0x1a2 + UCHAR RequestedFrontEndHeapType; // 0x1a3 + WCHAR *FrontEndHeapUsageData; // 0x1a8 + USHORT FrontEndHeapMaximumIndex; // 0x1b0 + volatile UCHAR FrontEndHeapStatusBitmap[129]; // 0x1b2 + HEAP_COUNTERS Counters; // 0x238 + HEAP_TUNING_PARAMETERS TuningParameters; // 0x2b0 +} HEAP, *PHEAP; + +typedef struct _IMAGE_DOS_HEADER +{ // DOS .EXE header + USHORT e_magic; // Magic number + USHORT e_cblp; // Bytes on last page of file + USHORT e_cp; // Pages in file + USHORT e_crlc; // Relocations + USHORT e_cparhdr; // Size of header in paragraphs + USHORT e_minalloc; // Minimum extra paragraphs needed + USHORT e_maxalloc; // Maximum extra paragraphs needed + USHORT e_ss; // Initial (relative) SS value + USHORT e_sp; // Initial SP value + USHORT e_csum; // Checksum + USHORT e_ip; // Initial IP value + USHORT e_cs; // Initial (relative) CS value + USHORT e_lfarlc; // File address of relocation table + USHORT e_ovno; // Overlay number + USHORT e_res[4]; // Reserved words + USHORT e_oemid; // OEM identifier (for e_oeminfo) + USHORT e_oeminfo; // OEM information; e_oemid specific + USHORT e_res2[10]; // Reserved words + LONG e_lfanew; // File address of new exe header +} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER; + +typedef struct _IMAGE_FILE_HEADER +{ + USHORT Machine; + USHORT NumberOfSections; + ULONG TimeDateStamp; + ULONG PointerToSymbolTable; + ULONG NumberOfSymbols; + USHORT SizeOfOptionalHeader; + USHORT Characteristics; +} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; + +#define IMAGE_SIZEOF_FILE_HEADER 20 + +#define IMAGE_FILE_RELOCS_STRIPPED 0x0001 // Relocation info stripped from file. +#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 // File is executable (i.e. no unresolved external references). +#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 // Line nunbers stripped from file. +#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 // Local symbols stripped from file. +#define IMAGE_FILE_AGGRESIVE_WS_TRIM 0x0010 // Aggressively trim working set +#define IMAGE_FILE_LARGE_ADDRESS_AWARE 0x0020 // App can handle >2gb addresses +#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080 // Bytes of machine word are reversed. +#define IMAGE_FILE_32BIT_MACHINE 0x0100 // 32 bit word machine. +#define IMAGE_FILE_DEBUG_STRIPPED 0x0200 // Debugging info stripped from file in .DBG file +#define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP 0x0400 // If Image is on removable media, copy and run from the swap file. +#define IMAGE_FILE_NET_RUN_FROM_SWAP 0x0800 // If Image is on Net, copy and run from the swap file. +#define IMAGE_FILE_SYSTEM 0x1000 // System File. +#define IMAGE_FILE_DLL 0x2000 // File is a DLL. +#define IMAGE_FILE_UP_SYSTEM_ONLY 0x4000 // File should only be run on a UP machine +#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000 // Bytes of machine word are reversed. + +#define IMAGE_FILE_MACHINE_UNKNOWN 0 +#define IMAGE_FILE_MACHINE_TARGET_HOST \ + 0x0001 // Useful for indicating we want to interact with the host and not a WoW guest. +#define IMAGE_FILE_MACHINE_I386 0x014c // Intel 386. +#define IMAGE_FILE_MACHINE_R3000 0x0162 // MIPS little-endian, 0x160 big-endian +#define IMAGE_FILE_MACHINE_R4000 0x0166 // MIPS little-endian +#define IMAGE_FILE_MACHINE_R10000 0x0168 // MIPS little-endian +#define IMAGE_FILE_MACHINE_WCEMIPSV2 0x0169 // MIPS little-endian WCE v2 +#define IMAGE_FILE_MACHINE_ALPHA 0x0184 // Alpha_AXP +#define IMAGE_FILE_MACHINE_SH3 0x01a2 // SH3 little-endian +#define IMAGE_FILE_MACHINE_SH3DSP 0x01a3 +#define IMAGE_FILE_MACHINE_SH3E 0x01a4 // SH3E little-endian +#define IMAGE_FILE_MACHINE_SH4 0x01a6 // SH4 little-endian +#define IMAGE_FILE_MACHINE_SH5 0x01a8 // SH5 +#define IMAGE_FILE_MACHINE_ARM 0x01c0 // ARM Little-Endian +#define IMAGE_FILE_MACHINE_THUMB 0x01c2 // ARM Thumb/Thumb-2 Little-Endian +#define IMAGE_FILE_MACHINE_ARMNT 0x01c4 // ARM Thumb-2 Little-Endian +#define IMAGE_FILE_MACHINE_AM33 0x01d3 +#define IMAGE_FILE_MACHINE_POWERPC 0x01F0 // IBM PowerPC Little-Endian +#define IMAGE_FILE_MACHINE_POWERPCFP 0x01f1 +#define IMAGE_FILE_MACHINE_IA64 0x0200 // Intel 64 +#define IMAGE_FILE_MACHINE_MIPS16 0x0266 // MIPS +#define IMAGE_FILE_MACHINE_ALPHA64 0x0284 // ALPHA64 +#define IMAGE_FILE_MACHINE_MIPSFPU 0x0366 // MIPS +#define IMAGE_FILE_MACHINE_MIPSFPU16 0x0466 // MIPS +#define IMAGE_FILE_MACHINE_AXP64 IMAGE_FILE_MACHINE_ALPHA64 +#define IMAGE_FILE_MACHINE_TRICORE 0x0520 // Infineon +#define IMAGE_FILE_MACHINE_CEF 0x0CEF +#define IMAGE_FILE_MACHINE_EBC 0x0EBC // EFI Byte Code +#define IMAGE_FILE_MACHINE_AMD64 0x8664 // AMD64 (K8) +#define IMAGE_FILE_MACHINE_M32R 0x9041 // M32R little-endian +#define IMAGE_FILE_MACHINE_ARM64 0xAA64 // ARM64 Little-Endian +#define IMAGE_FILE_MACHINE_CEE 0xC0EE + +#define IMAGE_FILE_MACHINE_CHPE_X86 0x3A64 +#define IMAGE_FILE_MACHINE_ARM64EC 0xA641 +#define IMAGE_FILE_MACHINE_ARM64X 0xA64E + +typedef struct _IMAGE_DATA_DIRECTORY +{ + ULONG VirtualAddress; + ULONG Size; +} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY; + +#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 + +typedef struct _IMAGE_OPTIONAL_HEADER +{ + // + // Standard fields. + // + + USHORT Magic; + UCHAR MajorLinkerVersion; + UCHAR MinorLinkerVersion; + ULONG SizeOfCode; + ULONG SizeOfInitializedData; + ULONG SizeOfUninitializedData; + ULONG AddressOfEntryPoint; + ULONG BaseOfCode; + ULONG BaseOfData; + + // + // NT additional fields. + // + + ULONG ImageBase; + ULONG SectionAlignment; + ULONG FileAlignment; + USHORT MajorOperatingSystemVersion; + USHORT MinorOperatingSystemVersion; + USHORT MajorImageVersion; + USHORT MinorImageVersion; + USHORT MajorSubsystemVersion; + USHORT MinorSubsystemVersion; + ULONG Win32VersionValue; + ULONG SizeOfImage; + ULONG SizeOfHeaders; + ULONG CheckSum; + USHORT Subsystem; + USHORT DllCharacteristics; + ULONG SizeOfStackReserve; + ULONG SizeOfStackCommit; + ULONG SizeOfHeapReserve; + ULONG SizeOfHeapCommit; + ULONG LoaderFlags; + ULONG NumberOfRvaAndSizes; + IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; +} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32; + +typedef struct _IMAGE_OPTIONAL_HEADER64 +{ + USHORT Magic; + UCHAR MajorLinkerVersion; + UCHAR MinorLinkerVersion; + ULONG SizeOfCode; + ULONG SizeOfInitializedData; + ULONG SizeOfUninitializedData; + ULONG AddressOfEntryPoint; + ULONG BaseOfCode; + ULONGLONG ImageBase; + ULONG SectionAlignment; + ULONG FileAlignment; + USHORT MajorOperatingSystemVersion; + USHORT MinorOperatingSystemVersion; + USHORT MajorImageVersion; + USHORT MinorImageVersion; + USHORT MajorSubsystemVersion; + USHORT MinorSubsystemVersion; + ULONG Win32VersionValue; + ULONG SizeOfImage; + ULONG SizeOfHeaders; + ULONG CheckSum; + USHORT Subsystem; + USHORT DllCharacteristics; + ULONGLONG SizeOfStackReserve; + ULONGLONG SizeOfStackCommit; + ULONGLONG SizeOfHeapReserve; + ULONGLONG SizeOfHeapCommit; + ULONG LoaderFlags; + ULONG NumberOfRvaAndSizes; + IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; +} IMAGE_OPTIONAL_HEADER64, *PIMAGE_OPTIONAL_HEADER64; + +#define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b +#define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b +#define IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x107 + +#ifdef _WIN64 +typedef IMAGE_OPTIONAL_HEADER64 IMAGE_OPTIONAL_HEADER; +typedef PIMAGE_OPTIONAL_HEADER64 PIMAGE_OPTIONAL_HEADER; +#define IMAGE_NT_OPTIONAL_HDR_MAGIC IMAGE_NT_OPTIONAL_HDR64_MAGIC +#else +typedef IMAGE_OPTIONAL_HEADER32 IMAGE_OPTIONAL_HEADER; +typedef PIMAGE_OPTIONAL_HEADER32 PIMAGE_OPTIONAL_HEADER; +#define IMAGE_NT_OPTIONAL_HDR_MAGIC IMAGE_NT_OPTIONAL_HDR32_MAGIC +#endif + +typedef struct _IMAGE_NT_HEADERS64 +{ + ULONG Signature; + IMAGE_FILE_HEADER FileHeader; + IMAGE_OPTIONAL_HEADER64 OptionalHeader; +} IMAGE_NT_HEADERS64, *PIMAGE_NT_HEADERS64; + +typedef struct _IMAGE_NT_HEADERS +{ + ULONG Signature; + IMAGE_FILE_HEADER FileHeader; + IMAGE_OPTIONAL_HEADER32 OptionalHeader; +} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32; + +#ifdef _WIN64 +typedef IMAGE_NT_HEADERS64 IMAGE_NT_HEADERS; +typedef PIMAGE_NT_HEADERS64 PIMAGE_NT_HEADERS; +#else +typedef IMAGE_NT_HEADERS32 IMAGE_NT_HEADERS; +typedef PIMAGE_NT_HEADERS32 PIMAGE_NT_HEADERS; +#endif + +// IMAGE_FIRST_SECTION doesn't need 32/64 versions since the file header is the same either way. + +#define IMAGE_FIRST_SECTION(ntheader) \ + ((PIMAGE_SECTION_HEADER)((ULONG_PTR)(ntheader) + FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader) + \ + ((ntheader))->FileHeader.SizeOfOptionalHeader)) + +// +// Export Format +// + +typedef struct _IMAGE_EXPORT_DIRECTORY +{ + ULONG Characteristics; + ULONG TimeDateStamp; + USHORT MajorVersion; + USHORT MinorVersion; + ULONG Name; + ULONG Base; + ULONG NumberOfFunctions; + ULONG NumberOfNames; + ULONG AddressOfFunctions; + ULONG AddressOfNames; + ULONG AddressOfNameOrdinals; +} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY; + +// Subsystem Values + +#define IMAGE_SUBSYSTEM_UNKNOWN 0 // Unknown subsystem. +#define IMAGE_SUBSYSTEM_NATIVE 1 // Image doesn't require a subsystem. +#define IMAGE_SUBSYSTEM_WINDOWS_GUI 2 // Image runs in the Windows GUI subsystem. +#define IMAGE_SUBSYSTEM_WINDOWS_CUI 3 // Image runs in the Windows character subsystem. +// end_winnt +// reserved 4 // Old Windows CE subsystem. +// begin_winnt +#define IMAGE_SUBSYSTEM_OS2_CUI 5 // image runs in the OS/2 character subsystem. +#define IMAGE_SUBSYSTEM_POSIX_CUI 7 // image runs in the Posix character subsystem. +#define IMAGE_SUBSYSTEM_NATIVE_WINDOWS 8 // image is a native Win9x driver. +#define IMAGE_SUBSYSTEM_WINDOWS_CE_GUI 9 // Image runs in the Windows CE subsystem. +#define IMAGE_SUBSYSTEM_EFI_APPLICATION 10 // +#define IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11 // +#define IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 12 // +#define IMAGE_SUBSYSTEM_EFI_ROM 13 +#define IMAGE_SUBSYSTEM_XBOX 14 +#define IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION 16 +#define IMAGE_SUBSYSTEM_XBOX_CODE_CATALOG 17 + +// DllCharacteristics Entries + +// IMAGE_LIBRARY_PROCESS_INIT 0x0001 // Reserved. +// IMAGE_LIBRARY_PROCESS_TERM 0x0002 // Reserved. +// IMAGE_LIBRARY_THREAD_INIT 0x0004 // Reserved. +// IMAGE_LIBRARY_THREAD_TERM 0x0008 // Reserved. +#define IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA 0x0020 // Image can handle a high entropy 64-bit virtual address space. +#define IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE 0x0040 // DLL can move. +#define IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY 0x0080 // Code Integrity Image +#define IMAGE_DLLCHARACTERISTICS_NX_COMPAT 0x0100 // Image is NX compatible +#define IMAGE_DLLCHARACTERISTICS_NO_ISOLATION 0x0200 // Image understands isolation and doesn't want it +#define IMAGE_DLLCHARACTERISTICS_NO_SEH 0x0400 // Image does not use SEH. No SE handler may reside in this image +#define IMAGE_DLLCHARACTERISTICS_NO_BIND 0x0800 // Do not bind this image. +#define IMAGE_DLLCHARACTERISTICS_APPCONTAINER 0x1000 // Image should execute in an AppContainer +#define IMAGE_DLLCHARACTERISTICS_WDM_DRIVER 0x2000 // Driver uses WDM model +#define IMAGE_DLLCHARACTERISTICS_GUARD_CF 0x4000 // Image supports Control Flow Guard. +#define IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE 0x8000 + +// Note: The Borland linker sets IMAGE_LIBRARY_xxx flags in DllCharacteristics + +// LoaderFlags Values + +#define IMAGE_LOADER_FLAGS_COMPLUS 0x00000001 // COM+ image +#define IMAGE_LOADER_FLAGS_SYSTEM_GLOBAL 0x01000000 // Global subsections apply across TS sessions. + +// Directory Entries + +#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory +#define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // Import Directory +#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 // Resource Directory +#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 // Exception Directory +#define IMAGE_DIRECTORY_ENTRY_SECURITY 4 // Security Directory +#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 // Base Relocation Table +#define IMAGE_DIRECTORY_ENTRY_DEBUG 6 // Debug Directory +// IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 // (X86 usage) +#define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE 7 // Architecture Specific Data +#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 // RVA of GP +#define IMAGE_DIRECTORY_ENTRY_TLS 9 // TLS Directory +#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 // Load Configuration Directory +#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 // Bound Import Directory in headers +#define IMAGE_DIRECTORY_ENTRY_IAT 12 // Import Address Table +#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13 // Delay Load Import Descriptors +#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14 // COM Runtime descriptor + +#define IMAGE_SIZEOF_SHORT_NAME 8 + +typedef struct _IMAGE_SECTION_HEADER +{ + UCHAR Name[IMAGE_SIZEOF_SHORT_NAME]; + union { + ULONG PhysicalAddress; + ULONG VirtualSize; + } Misc; + ULONG VirtualAddress; + ULONG SizeOfRawData; + ULONG PointerToRawData; + ULONG PointerToRelocations; + ULONG PointerToLinenumbers; + USHORT NumberOfRelocations; + USHORT NumberOfLinenumbers; + ULONG Characteristics; +} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER; + +#define IMAGE_SIZEOF_SECTION_HEADER 40 + +#define IMAGE_DOS_SIGNATURE 0x5A4D // MZ +#define IMAGE_NT_SIGNATURE 0x00004550 // PE00 + +typedef struct _MMPFN +{ + union { + LIST_ENTRY ListEntry; // 0x0 + RTL_BALANCED_NODE TreeNode; // 0x0 + struct + { + union { + SINGLE_LIST_ENTRY NextSlistPfn; // 0x0 + VOID *Next; // 0x0 + ULONGLONG Flink : 36; // 0x0 + ULONGLONG NodeFlinkHigh : 28; // 0x0 + ULONGLONG Active; // 0x0 + } u1; // 0x0 + union { + ULONGLONG *PteAddress; // 0x8 + ULONGLONG PteLong; // 0x8 + }; + ULONGLONG OriginalPte; // 0x10 + }; + }; + ULONGLONG u2; // 0x18 + union { + struct + { + USHORT ReferenceCount; // 0x20 + UCHAR e1; // 0x22 + }; + struct + { + UCHAR e3; // 0x23 + struct + { + USHORT ReferenceCount; // 0x20 + } e2; // 0x20 + }; + struct + { + ULONG EntireField; // 0x20 + } e4; // 0x20 + } u3; // 0x20 + USHORT NodeBlinkLow; // 0x24 + UCHAR Unused : 4; // 0x26 + UCHAR Unused2 : 4; // 0x26 + union { + UCHAR ViewCount; // 0x27 + UCHAR NodeFlinkLow; // 0x27 + }; + union { + ULONGLONG PteFrame : 36; // 0x28 + ULONGLONG Channel : 2; // 0x28 + ULONGLONG Unused1 : 1; // 0x28 + ULONGLONG Unused2 : 1; // 0x28 + ULONGLONG Partition : 10; // 0x28 + ULONGLONG Spare : 2; // 0x28 + ULONGLONG FileOnly : 1; // 0x28 + ULONGLONG PfnExists : 1; // 0x28 + ULONGLONG PageIdentity : 3; // 0x28 + ULONGLONG PrototypePte : 1; // 0x28 + ULONGLONG PageColor : 6; // 0x28 + ULONGLONG EntireField; // 0x28 + } u4; // 0x28 + +} MMPFN, *PMMPFN; + +struct _MMPTE_HARDWARE +{ + ULONGLONG Valid : 1; // 0x0 + ULONGLONG Dirty1 : 1; // 0x0 + ULONGLONG Owner : 1; // 0x0 + ULONGLONG WriteThrough : 1; // 0x0 + ULONGLONG CacheDisable : 1; // 0x0 + ULONGLONG Accessed : 1; // 0x0 + ULONGLONG Dirty : 1; // 0x0 + ULONGLONG LargePage : 1; // 0x0 + ULONGLONG Global : 1; // 0x0 + ULONGLONG CopyOnWrite : 1; // 0x0 + ULONGLONG Unused : 1; // 0x0 + ULONGLONG Write : 1; // 0x0 + ULONGLONG PageFrameNumber : 40; // 0x0 + ULONGLONG ReservedForSoftware : 4; // 0x0 + ULONGLONG WsleAge : 4; // 0x0 + ULONGLONG WsleProtection : 3; // 0x0 + ULONGLONG NoExecute : 1; // 0x0 +}; + +typedef struct _MMPTE +{ + union { + ULONGLONG Long; // 0x0 + volatile ULONGLONG VolatileLong; // 0x0 + struct _MMPTE_HARDWARE Hard; // 0x0 + } u; + +} MMPTE, *PMMPTE; + +// +// This structure is used by the debugger for all targets +// It is the same size as DBGKD_DATA_HEADER on all systems +// +typedef struct _DBGKD_DEBUG_DATA_HEADER64 +{ + + // + // Link to other blocks + // + + LIST_ENTRY64 List; + + // + // This is a unique tag to identify the owner of the block. + // If your component only uses one pool tag, use it for this, too. + // + + ULONG OwnerTag; + + // + // This must be initialized to the size of the data block, + // including this structure. + // + + ULONG Size; + +} DBGKD_DEBUG_DATA_HEADER64, *PDBGKD_DEBUG_DATA_HEADER64; + +// +// This structure is the same size on all systems. The only field +// which must be translated by the debugger is Header.List. +// + +// +// DO NOT ADD OR REMOVE FIELDS FROM THE MIDDLE OF THIS STRUCTURE!!! +// +// If you remove a field, replace it with an "unused" placeholder. +// Do not reuse fields until there has been enough time for old debuggers +// and extensions to age out. +// +typedef struct _KDDEBUGGER_DATA64 +{ + + DBGKD_DEBUG_DATA_HEADER64 Header; + + // + // Base address of kernel image + // + + ULONG64 KernBase; + + // + // DbgBreakPointWithStatus is a function which takes an argument + // and hits a breakpoint. This field contains the address of the + // breakpoint instruction. When the debugger sees a breakpoint + // at this address, it may retrieve the argument from the first + // argument register, or on x86 the eax register. + // + + ULONG64 BreakpointWithStatus; // address of breakpoint + + // + // Address of the saved context record during a bugcheck + // + // N.B. This is an automatic in KeBugcheckEx's frame, and + // is only valid after a bugcheck. + // + + ULONG64 SavedContext; + + // + // help for walking stacks with user callbacks: + // + + // + // The address of the thread structure is provided in the + // WAIT_STATE_CHANGE packet. This is the offset from the base of + // the thread structure to the pointer to the kernel stack frame + // for the currently active usermode callback. + // + + USHORT ThCallbackStack; // offset in thread data + + // + // these values are offsets into that frame: + // + + USHORT NextCallback; // saved pointer to next callback frame + USHORT FramePointer; // saved frame pointer + + // + // pad to a quad boundary + // + USHORT PaeEnabled; + + // + // Address of the kernel callout routine. + // + + ULONG64 KiCallUserMode; // kernel routine + + // + // Address of the usermode entry point for callbacks. + // + + ULONG64 KeUserCallbackDispatcher; // address in ntdll + + // + // Addresses of various kernel data structures and lists + // that are of interest to the kernel debugger. + // + + ULONG64 PsLoadedModuleList; + ULONG64 PsActiveProcessHead; + ULONG64 PspCidTable; + + ULONG64 ExpSystemResourcesList; + ULONG64 ExpPagedPoolDescriptor; + ULONG64 ExpNumberOfPagedPools; + + ULONG64 KeTimeIncrement; + ULONG64 KeBugCheckCallbackListHead; + ULONG64 KiBugcheckData; + + ULONG64 IopErrorLogListHead; + + ULONG64 ObpRootDirectoryObject; + ULONG64 ObpTypeObjectType; + + ULONG64 MmSystemCacheStart; + ULONG64 MmSystemCacheEnd; + ULONG64 MmSystemCacheWs; + + ULONG64 MmPfnDatabase; + ULONG64 MmSystemPtesStart; + ULONG64 MmSystemPtesEnd; + ULONG64 MmSubsectionBase; + ULONG64 MmNumberOfPagingFiles; + + ULONG64 MmLowestPhysicalPage; + ULONG64 MmHighestPhysicalPage; + ULONG64 MmNumberOfPhysicalPages; + + ULONG64 MmMaximumNonPagedPoolInBytes; + ULONG64 MmNonPagedSystemStart; + ULONG64 MmNonPagedPoolStart; + ULONG64 MmNonPagedPoolEnd; + + ULONG64 MmPagedPoolStart; + ULONG64 MmPagedPoolEnd; + ULONG64 MmPagedPoolInformation; + ULONG64 MmPageSize; + + ULONG64 MmSizeOfPagedPoolInBytes; + + ULONG64 MmTotalCommitLimit; + ULONG64 MmTotalCommittedPages; + ULONG64 MmSharedCommit; + ULONG64 MmDriverCommit; + ULONG64 MmProcessCommit; + ULONG64 MmPagedPoolCommit; + ULONG64 MmExtendedCommit; + + ULONG64 MmZeroedPageListHead; + ULONG64 MmFreePageListHead; + ULONG64 MmStandbyPageListHead; + ULONG64 MmModifiedPageListHead; + ULONG64 MmModifiedNoWritePageListHead; + ULONG64 MmAvailablePages; + ULONG64 MmResidentAvailablePages; + + ULONG64 PoolTrackTable; + ULONG64 NonPagedPoolDescriptor; + + ULONG64 MmHighestUserAddress; + ULONG64 MmSystemRangeStart; + ULONG64 MmUserProbeAddress; + + ULONG64 KdPrintCircularBuffer; + ULONG64 KdPrintCircularBufferEnd; + ULONG64 KdPrintWritePointer; + ULONG64 KdPrintRolloverCount; + + ULONG64 MmLoadedUserImageList; + + // NT 5.1 Addition + + ULONG64 NtBuildLab; + ULONG64 KiNormalSystemCall; + + // NT 5.0 hotfix addition + + ULONG64 KiProcessorBlock; + ULONG64 MmUnloadedDrivers; + ULONG64 MmLastUnloadedDriver; + ULONG64 MmTriageActionTaken; + ULONG64 MmSpecialPoolTag; + ULONG64 KernelVerifier; + ULONG64 MmVerifierData; + ULONG64 MmAllocatedNonPagedPool; + ULONG64 MmPeakCommitment; + ULONG64 MmTotalCommitLimitMaximum; + ULONG64 CmNtCSDVersion; + + // NT 5.1 Addition + + ULONG64 MmPhysicalMemoryBlock; + ULONG64 MmSessionBase; + ULONG64 MmSessionSize; + ULONG64 MmSystemParentTablePage; + + // Server 2003 addition + + ULONG64 MmVirtualTranslationBase; + + USHORT OffsetKThreadNextProcessor; + USHORT OffsetKThreadTeb; + USHORT OffsetKThreadKernelStack; + USHORT OffsetKThreadInitialStack; + + USHORT OffsetKThreadApcProcess; + USHORT OffsetKThreadState; + USHORT OffsetKThreadBStore; + USHORT OffsetKThreadBStoreLimit; + + USHORT SizeEProcess; + USHORT OffsetEprocessPeb; + USHORT OffsetEprocessParentCID; + USHORT OffsetEprocessDirectoryTableBase; + + USHORT SizePrcb; + USHORT OffsetPrcbDpcRoutine; + USHORT OffsetPrcbCurrentThread; + USHORT OffsetPrcbMhz; + + USHORT OffsetPrcbCpuType; + USHORT OffsetPrcbVendorString; + USHORT OffsetPrcbProcStateContext; + USHORT OffsetPrcbNumber; + + USHORT SizeEThread; + + ULONG64 KdPrintCircularBufferPtr; + ULONG64 KdPrintBufferSize; + + ULONG64 KeLoaderBlock; + + USHORT SizePcr; + USHORT OffsetPcrSelfPcr; + USHORT OffsetPcrCurrentPrcb; + USHORT OffsetPcrContainedPrcb; + + USHORT OffsetPcrInitialBStore; + USHORT OffsetPcrBStoreLimit; + USHORT OffsetPcrInitialStack; + USHORT OffsetPcrStackLimit; + + USHORT OffsetPrcbPcrPage; + USHORT OffsetPrcbProcStateSpecialReg; + USHORT GdtR0Code; + USHORT GdtR0Data; + + USHORT GdtR0Pcr; + USHORT GdtR3Code; + USHORT GdtR3Data; + USHORT GdtR3Teb; + + USHORT GdtLdt; + USHORT GdtTss; + USHORT Gdt64R3CmCode; + USHORT Gdt64R3CmTeb; + + ULONG64 IopNumTriageDumpDataBlocks; + ULONG64 IopTriageDumpDataBlocks; + + // Longhorn addition + + ULONG64 VfCrashDataBlock; + ULONG64 MmBadPagesDetected; + ULONG64 MmZeroedPageSingleBitErrorsDetected; + + // Windows 7 addition + + ULONG64 EtwpDebuggerData; + USHORT OffsetPrcbContext; + + // Windows 8 addition + + USHORT OffsetPrcbMaxBreakpoints; + USHORT OffsetPrcbMaxWatchpoints; + + ULONG OffsetKThreadStackLimit; + ULONG OffsetKThreadStackBase; + ULONG OffsetKThreadQueueListEntry; + ULONG OffsetEThreadIrpList; + + USHORT OffsetPrcbIdleThread; + USHORT OffsetPrcbNormalDpcState; + USHORT OffsetPrcbDpcStack; + USHORT OffsetPrcbIsrStack; + + USHORT SizeKDPC_STACK_FRAME; + + // Windows 8.1 Addition + + USHORT OffsetKPriQueueThreadListHead; + USHORT OffsetKThreadWaitReason; + + // Windows 10 RS1 Addition + + USHORT Padding; + ULONG64 PteBase; + + // Windows 10 RS5 Addition + + ULONG64 RetpolineStubFunctionTable; + ULONG RetpolineStubFunctionTableSize; + ULONG RetpolineStubOffset; + ULONG RetpolineStubSize; + +} KDDEBUGGER_DATA64, *PKDDEBUGGER_DATA64; + +typedef struct _DUMP_HEADER +{ + ULONG Signature; + ULONG ValidDump; + ULONG MajorVersion; + ULONG MinorVersion; + ULONG_PTR DirectoryTableBase; + ULONG_PTR PfnDataBase; + PLIST_ENTRY PsLoadedModuleList; + PLIST_ENTRY PsActiveProcessHead; + ULONG MachineImageType; + ULONG NumberProcessors; + ULONG BugCheckCode; + ULONG_PTR BugCheckParameter1; + ULONG_PTR BugCheckParameter2; + ULONG_PTR BugCheckParameter3; + ULONG_PTR BugCheckParameter4; + CHAR VersionUser[32]; + struct _KDDEBUGGER_DATA64 *KdDebuggerDataBlock; + +} DUMP_HEADER, *PDUMP_HEADER; + +#ifndef _WIN64 +#define DUMP_BLOCK_SIZE 0x20000 +#else +#define DUMP_BLOCK_SIZE 0x40000 +#endif + +#ifndef _WIN64 +#define KDDEBUGGER_DATA_OFFSET 0x1068 +#else +#define KDDEBUGGER_DATA_OFFSET 0x2080 +#endif + +typedef struct _SERVICE_DESCRIPTOR +{ + PULONG ServiceTableBase; + PULONG ServiceCounterTableBase; + ULONG NumberOfService; + PVOID ParamTableBase; +} SERVICE_DESCRIPTOR, *PSERVICE_DESCRIPTOR; + +typedef struct _SERVICE_DESCRIPTOR_TABLE +{ + SERVICE_DESCRIPTOR NtosTable; + SERVICE_DESCRIPTOR Win32kTable; + +} SERVICE_DESCRIPTOR_TABLE, *PSERVICE_DESCRIPTOR_TABLE; + +__forceinline size_t KeFlushCurrentTbImmediately() +{ + size_t v0; // rcx + size_t result; // rax + + v0 = __readcr4(); + if ((v0 & 0x20080) != 0) + { + result = v0 ^ 0x80; + __writecr4(v0 ^ 0x80); + __writecr4(v0); + } + else + { + result = __readcr3(); + __writecr3(result); + } + return result; +} + +extern PMMPFN MmPfnDatabase; +extern ULONG_PTR MmPteBase; +extern ULONG_PTR MmPdeBase; +extern ULONG_PTR MmPpeBase; +extern ULONG_PTR MmPxeBase; +extern ULONG_PTR MmPxeSelf; + +__forceinline void PteInitialize(ULONG_PTR PteBase, PMMPFN PfnDatabase) +{ + MmPteBase = PteBase; + MmPdeBase = MmPteBase + (MmPteBase >> 9 & 0x7FFFFFFFFF); + MmPpeBase = MmPdeBase + (MmPdeBase >> 9 & 0x3FFFFFFF); + MmPxeBase = MmPpeBase + (MmPpeBase >> 9 & 0x1FFFFF); + MmPxeSelf = MmPxeBase + (MmPxeBase >> 9 & 0xFFF); + MmPfnDatabase = PfnDatabase; +} + +__forceinline PMMPTE MiGetPteAddress(IN PVOID VirtualAddress) +{ + return (PMMPTE)(MmPteBase + (((ULONG_PTR)VirtualAddress >> 9) & 0x7FFFFFFFF8)); +} + +__forceinline PMMPTE MiGetPdeAddress(IN PVOID VirtualAddress) +{ + return (PMMPTE)(MmPdeBase + (((ULONG_PTR)VirtualAddress >> 18) & 0x3FFFFFF8)); +} + +__forceinline PMMPTE MiGetPpeAddress(IN PVOID VirtualAddress) +{ + return (PMMPTE)(MmPpeBase + (((ULONG_PTR)VirtualAddress >> 27) & 0x1FFFF8)); +} + +__forceinline PMMPTE MiGetPxeAddress(IN PVOID VirtualAddress) +{ + return ((PMMPTE)MmPxeBase + (((ULONG_PTR)VirtualAddress >> 39) & 0x1FF)); +} + +__forceinline PVOID MiGetVirtualAddressMappedByPte(IN PMMPTE PteAddress) +{ + return ((PVOID)((((LONG_PTR)PteAddress - (LONG_PTR)MmPteBase) << 25) >> 16)); +} + +#define KUSER_SHARED_DATA_USERMODE 0x7FFE0000 +#define KUSER_SHARED_DATA_KERNELMODE 0xFFFFF78000000000 + +extern PKUSER_SHARED_DATA KernelKuserSharedData; +extern const PKUSER_SHARED_DATA KuserSharedData; + +EXTERN_C_START + +NTKERNELAPI PVOID NTAPI PsGetProcessWow64Process(IN PEPROCESS Process); + +NTKERNELAPI PVOID NTAPI PsGetCurrentProcessWow64Process(); + +NTKERNELAPI PPEB NTAPI PsGetProcessPeb(IN PEPROCESS Process); + +NTSYSAPI BOOLEAN NTAPI PsIsProcessBeingDebugged(PEPROCESS Process); + +NTSYSAPI PVOID RtlPcToFileHeader(_In_ PVOID PcValue, _Out_ PVOID *BaseOfImage); + +NTSYSAPI BOOLEAN NTAPI PsIsProtectedProcess(_In_ PEPROCESS Process); + +NTSYSAPI +BOOLEAN +NTAPI +PsIsSystemProcess(_In_ PEPROCESS Process); + +NTSYSAPI +PVOID NTAPI PsGetProcessSectionBaseAddress(__in PEPROCESS Process); + +NTSYSAPI NTSTATUS NTAPI ObReferenceObjectByName(__in PUNICODE_STRING ObjectName, __in ULONG Attributes, + __in_opt PACCESS_STATE AccessState, __in_opt ACCESS_MASK DesiredAccess, + __in POBJECT_TYPE ObjectType, __in KPROCESSOR_MODE AccessMode, + __inout_opt PVOID ParseContext, __out PVOID *Object); + +NTSYSAPI NTSTATUS NTAPI ZwQuerySystemInformation(_In_ SYSTEM_INFORMATION_CLASS SystemInformationClass, + _Inout_ PVOID SystemInformation, _In_ ULONG SystemInformationLength, + _Out_opt_ PULONG ReturnLength); + +NTSYSAPI NTSTATUS NTAPI ZwQueryInformationProcess(_In_ HANDLE ProcessHandle, + _In_ PROCESSINFOCLASS ProcessInformationClass, + _Out_ PVOID ProcessInformation, _In_ ULONG ProcessInformationLength, + _Out_opt_ PULONG ReturnLength); + +NTSYSAPI NTSTATUS NTAPI ZwSetInformationProcess(HANDLE ProcessHandle, PROCESSINFOCLASS ProcessInformationClass, + PVOID ProcessInformation, ULONG ProcessInformationLength); + +NTSYSAPI +PIMAGE_NT_HEADERS +NTAPI +RtlImageNtHeader(IN PVOID ModuleAddress); + +NTSYSAPI NTSTATUS NTAPI KeRaiseUserException(NTSTATUS Status); + +NTSYSAPI +ULONG +NTAPI +KeCapturePersistentThreadState(IN PCONTEXT Context, IN PKTHREAD Thread, IN ULONG BugCheckCode, + IN ULONG BugCheckParameter1, IN ULONG BugCheckParameter2, IN ULONG BugCheckParameter3, + IN ULONG BugCheckParameter4, OUT PVOID VirtualAddress); + +NTSYSCALLAPI +PVOID +NTAPI +RtlImageDirectoryEntryToData(PVOID BaseAddress, BOOLEAN MappedAsImage, USHORT Directory, PULONG Size); + +NTSYSCALLAPI +NTSTATUS +NTAPI +NtTraceControl(_In_ ULONG FunctionCode, _In_reads_bytes_opt_(InBufferLen) PVOID InBuffer, _In_ ULONG InBufferLen, + _Out_writes_bytes_opt_(OutBufferLen) PVOID OutBuffer, _In_ ULONG OutBufferLen, + _Out_ PULONG ReturnLength); + +EXTERN_C_END \ No newline at end of file diff --git a/MasterHide/object.cpp b/MasterHide/object.cpp new file mode 100644 index 0000000..e8eeeef --- /dev/null +++ b/MasterHide/object.cpp @@ -0,0 +1,111 @@ +#include "includes.hpp" + +namespace masterhide +{ +namespace object +{ +OBJECT_TYPE g_objectTypes[3]{}; +volatile LONG g_objectTypeCount = 0; + +void ObjectDelete(_In_ POBJECT_HEADER header) +{ + const POBJECT_TYPE type = &g_objectTypes[header->TypeIndex]; + + if (type->TypeInfo.Delete) + { + type->TypeInfo.Delete(ObjectHeaderToObject(header)); + } + + type->TypeInfo.Free(header); + + InterlockedDecrementSizeT(&type->TotalNumberOfObjects); +} + +void ReferenceObject(_In_ PVOID object) +{ + POBJECT_HEADER header = ObjectToObjectHeader(object); + + NT_VERIFY(InterlockedIncrementSSizeT(&header->PointerCount) > 0); +} + +void DereferenceObject(_In_ PVOID object) +{ + POBJECT_HEADER header = ObjectToObjectHeader(object); + + const SSIZE_T refCount = InterlockedDecrementSSizeT(&header->PointerCount); + if (refCount > 0) + { + return; + } + + NT_ASSERT(refCount == 0); + + ObjectDelete(header); +} + +void CreateObjectType(_In_ PCUNICODE_STRING typeName, _In_ POBJECT_TYPE_INFO typeInfo, + _Outptr_ POBJECT_TYPE *objectType) +{ + const LONG index = (InterlockedIncrement(&g_objectTypeCount) - 1); + + // + // We have failure free object type creation, to achieve this we have + // a pre-reserved sized array above. If this asserts the array wasn't + // expanded correctly to support a new type. + // + NT_ASSERT((index >= 0) && (index < ARRAYSIZE(g_objectTypes))); + NT_ASSERT(index < MAXUCHAR); + + POBJECT_TYPE type = &g_objectTypes[index]; + + type->Name.Buffer = typeName->Buffer; + type->Name.MaximumLength = typeName->MaximumLength; + type->Name.Length = typeName->Length; + + type->Index = (UCHAR)index; + type->TotalNumberOfObjects = 0; + type->HighWaterNumberOfObjects = 0; + + RtlCopyMemory(&type->TypeInfo, typeInfo, sizeof(*typeInfo)); + + *objectType = type; +} + +NTSTATUS CreateObject(_In_ POBJECT_TYPE objectType, _In_ ULONG objectBodySize, + _Outptr_result_nullonfailure_ PVOID *object, _In_opt_ PVOID parameter) +{ + NTSTATUS status; + + *object = nullptr; + + auto header = static_cast(objectType->TypeInfo.Allocate(AddObjectHeaderSize(objectBodySize))); + if (!header) + { + return STATUS_INSUFFICIENT_RESOURCES; + } + + header->PointerCount = 1; + header->TypeIndex = objectType->Index; + + PVOID obj = ObjectHeaderToObject(header); + + if (objectType->TypeInfo.Initialize) + { + status = objectType->TypeInfo.Initialize(obj, parameter); + if (!NT_SUCCESS(status)) + { + objectType->TypeInfo.Free(header); + return status; + } + } + + const SIZE_T total = InterlockedIncrementSizeT(&objectType->TotalNumberOfObjects); + + InterlockedExchangeIfGreaterSizeT(&objectType->HighWaterNumberOfObjects, total); + + *object = obj; + + return STATUS_SUCCESS; +} +} // namespace object +} // namespace masterhide \ No newline at end of file diff --git a/MasterHide/object.hpp b/MasterHide/object.hpp new file mode 100644 index 0000000..757cf26 --- /dev/null +++ b/MasterHide/object.hpp @@ -0,0 +1,55 @@ +#pragma once + +namespace masterhide +{ +namespace object +{ +using TYPE_ALLOCATE_PROCEDURE = PVOID (*)(_In_ SIZE_T); +using TYPE_INITIALIZE_PROCEDURE = NTSTATUS (*)(_Inout_ PVOID, _In_opt_ PVOID); +using TYPE_DELETE_PROCEDURE = void (*)(_Inout_ PVOID); +using TYPE_FREE_PROCEDURE = void (*)(_In_ PVOID); + +typedef struct _OBJECT_HEADER +{ + UCHAR TypeIndex; + volatile SSIZE_T PointerCount; + QUAD Body; + +} OBJECT_HEADER, *POBJECT_HEADER; + +C_ASSERT((FIELD_OFFSET(OBJECT_HEADER, Body) % MEMORY_ALLOCATION_ALIGNMENT) == 0); + +#define ObjectToObjectHeader(x) ((POBJECT_HEADER)CONTAINING_RECORD((PCHAR)x, OBJECT_HEADER, Body)) +#define ObjectHeaderToObject(x) ((PVOID) & ((POBJECT_HEADER)(x))->Body) +#define AddObjectHeaderSize(x) ((SIZE_T)(x) + FIELD_OFFSET(OBJECT_HEADER, Body)) + +typedef struct _OBJECT_TYPE_INFO +{ + TYPE_ALLOCATE_PROCEDURE Allocate; + TYPE_INITIALIZE_PROCEDURE Initialize; + TYPE_DELETE_PROCEDURE Delete; + TYPE_FREE_PROCEDURE Free; + +} OBJECT_TYPE_INFO, *POBJECT_TYPE_INFO; + +typedef struct _OBJECT_TYPE +{ + UNICODE_STRING Name; + UCHAR Index; + volatile SIZE_T TotalNumberOfObjects; + volatile SIZE_T HighWaterNumberOfObjects; + OBJECT_TYPE_INFO TypeInfo; + +} OBJECT_TYPE, *POBJECT_TYPE; + +void ObjectDelete(_In_ POBJECT_HEADER header); +void ReferenceObject(_In_ PVOID object); +void DereferenceObject(_In_ PVOID object); + +void CreateObjectType(_In_ PCUNICODE_STRING typeName, _In_ POBJECT_TYPE_INFO typeInfo, + _Outptr_ POBJECT_TYPE *objectType); + +[[nodiscard]] NTSTATUS CreateObject(_In_ POBJECT_TYPE objectType, _In_ ULONG objectBodySize, + _Outptr_result_nullonfailure_ PVOID *object, _In_opt_ PVOID parameter); +} // namespace object +} // namespace masterhide \ No newline at end of file diff --git a/MasterHide/process.cpp b/MasterHide/process.cpp new file mode 100644 index 0000000..7da9017 --- /dev/null +++ b/MasterHide/process.cpp @@ -0,0 +1,1530 @@ +#include "includes.hpp" + +#pragma once + +namespace masterhide +{ +namespace process +{ +DECLARE_GLOBAL_CONST_UNICODE_STRING(g_processEntryObjectName, L"ProcessEntryObject"); +object::POBJECT_TYPE g_objTypeProcessEntry = nullptr; +bool g_stopCounterThread = false; +HANDLE g_counterThreadHandle = nullptr; + +NTSTATUS Initialize() +{ + NT_ASSERT(!g_initialized); + + if (g_initialized) + { + return STATUS_ALREADY_INITIALIZED; + } + + InitializeListHead(&g_processListHead); + + NTSTATUS status = g_processResource.Initialize(); + if (!NT_SUCCESS(status)) + { + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, "Failed to initialize processes resource %!STATUS!", status); + return STATUS_UNSUCCESSFUL; + } + + g_initialized = true; + + status = PsCreateSystemThread(&g_counterThreadHandle, THREAD_ALL_ACCESS, nullptr, nullptr, nullptr, CounterUpdater, + nullptr); + if (!NT_SUCCESS(status)) + { + g_initialized = false; + g_processResource.Deinitialize(); + + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, "PsCreateSystemThread returned %!STATUS!", status); + + return status; + } + + // Create object + // + object::OBJECT_TYPE_INFO typeInfo{}; + typeInfo.Allocate = AllocateProcessEntry; + typeInfo.Initialize = NULL; + typeInfo.Delete = DeleteProcessEntry; + typeInfo.Free = FreeProcessEntry; + object::CreateObjectType(&g_processEntryObjectName, &typeInfo, &g_objTypeProcessEntry); + + return STATUS_SUCCESS; +} + +void Deinitialize() +{ + PAGED_CODE(); + + if (!g_initialized) + { + return; + } + + // Tell counter thread to stop. + // + g_stopCounterThread = true; + + ZwWaitForSingleObject(g_counterThreadHandle, FALSE, nullptr); + ZwClose(g_counterThreadHandle); + + // (1) Obtain lock and free all list objects recursively + // + if (g_processResource.LockExclusive()) + { + while (!IsListEmpty(&g_processListHead)) + { + PLIST_ENTRY listEntry = RemoveHeadList(&g_processListHead); + PPROCESS_ENTRY processEntry = CONTAINING_RECORD(listEntry, PROCESS_ENTRY, ListEntry); + + object::DereferenceObject(processEntry); + } + + g_processResource.Unlock(); + } + + // (2) De-initialize the resource + // + g_processResource.Deinitialize(); + + g_initialized = false; + + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, "Successfully de-initialized process interface!"); + return; +} + +/* + + Process entry object Allocate, Delete and Free. + +*/ +PVOID AllocateProcessEntry(_In_ SIZE_T size) +{ + PAGED_CODE(); + + return tools::AllocatePoolZero(NonPagedPool, size, tags::TAG_PROCESS_ENTRY); +} + +void FreeProcessEntry(_In_ PVOID object) +{ + PAGED_CODE(); + + ExFreePool(object); +} + +void DeleteProcessEntry(_In_ PVOID object) +{ + NT_ASSERT(object); + + PPROCESS_ENTRY processEntry = static_cast(object); + + // Delete thread objects + // + if (processEntry->ThreadsResource.LockExclusive()) + { + while (!IsListEmpty(&processEntry->Threads.ListEntry)) + { + PLIST_ENTRY listEntry = RemoveHeadList(&processEntry->Threads.ListEntry); + PTHREAD_ENTRY threadEntry = CONTAINING_RECORD(listEntry, THREAD_ENTRY, ListEntry); + + ObDereferenceObject(threadEntry->Thread); + ExFreePool(threadEntry); + } + + processEntry->ThreadsResource.Unlock(); + } + + processEntry->ThreadsResource.Deinitialize(); + + // Delete process objects + // + if (processEntry->Kusd.KuserSharedData != NULL) + { + process::UnHookKuserSharedData(processEntry); + } + + if (processEntry->ImageFileName.Buffer) + { + RtlFreeUnicodeString(&processEntry->ImageFileName); + } + + ObDereferenceObject(processEntry->Process); +} + +bool ClearHeapFlags(PEPROCESS process) +{ + PAGED_CODE(); + NT_ASSERT(process); + + PPEB Peb = (PPEB)PsGetProcessPeb(process); + PPEB32 Peb32 = (PPEB32)PsGetProcessWow64Process(process); + + KAPC_STATE apcState{}; + + // https://ctf-wiki.github.io/ctf-wiki/reverse/windows/anti-debug/heap-flags/ + // In all versions of Windows, the value of the Flags + // field is normally set to HEAP_GROWABLE(2), + // and the ForceFlags field is normally set to 0 + + // 32-bit process.Both of these default values depend on the[subsystem] of its host process + if (Peb32) + { + __try + { + KeStackAttachProcess(process, &apcState); + + for (size_t i = 0; i < Peb32->NumberOfHeaps; i++) + { + ULONG Heap = *(ULONG *)(Peb32->ProcessHeaps + 4 * i); + + // Heap Flags + *(ULONG *)(Heap + 0x40) &= ~(HEAP_TAIL_CHECKING_ENABLED | HEAP_FREE_CHECKING_ENABLED | + HEAP_SKIP_VALIDATION_CHECKS | HEAP_VALIDATE_PARAMETERS_ENABLED); + + // Heap Force Flags + *(ULONG *)(Heap + 0x44) &= + ~(HEAP_TAIL_CHECKING_ENABLED | HEAP_FREE_CHECKING_ENABLED | HEAP_VALIDATE_PARAMETERS_ENABLED); + } + } + __finally + { + KeUnstackDetachProcess(&apcState); + } + } + + if (Peb != NULL) + { + __try + { + KeStackAttachProcess(process, &apcState); + + for (size_t i = 0; i < Peb->NumberOfHeaps; i++) + { + PHEAP Heap = (PHEAP)Peb->ProcessHeaps[i]; + Heap->Flags &= ~(HEAP_TAIL_CHECKING_ENABLED | HEAP_FREE_CHECKING_ENABLED | HEAP_SKIP_VALIDATION_CHECKS | + HEAP_VALIDATE_PARAMETERS_ENABLED); + Heap->ForceFlags &= + ~(HEAP_TAIL_CHECKING_ENABLED | HEAP_FREE_CHECKING_ENABLED | HEAP_VALIDATE_PARAMETERS_ENABLED); + } + } + __finally + { + KeUnstackDetachProcess(&apcState); + } + } + else + { + return false; + } + return true; +} + +bool SetPebDeuggerFlag(PEPROCESS process, BOOLEAN value) +{ + PAGED_CODE(); + NT_ASSERT(process); + + PPEB Peb = PsGetProcessPeb(process); + PPEB32 Peb32 = (PPEB32)PsGetProcessWow64Process(process); + + KAPC_STATE apcState{}; + + if (Peb32) + { + __try + { + KeStackAttachProcess(process, &apcState); + Peb32->BeingDebugged = value; + Peb->BeingDebugged = value; + } + __finally + { + KeUnstackDetachProcess(&apcState); + } + } + else if (Peb) + { + __try + { + KeStackAttachProcess(process, &apcState); + Peb->BeingDebugged = value; + } + __finally + { + KeUnstackDetachProcess(&apcState); + } + } + else + { + return false; + } + return true; +} + +bool ClearPebNtGlobalFlag(PEPROCESS process) +{ + PAGED_CODE(); + NT_ASSERT(process); + + PPEB Peb = PsGetProcessPeb(process); + PPEB32 Peb32 = (PPEB32)PsGetProcessWow64Process(process); + + KAPC_STATE apcState{}; + + if (Peb32) + { + __try + { + KeStackAttachProcess(process, &apcState); + ClearFlag(Peb32->NtGlobalFlag, NT_GLOBAL_FLAG_DEBUGGED); + ClearFlag(Peb->NtGlobalFlag, NT_GLOBAL_FLAG_DEBUGGED); + } + __finally + { + KeUnstackDetachProcess(&apcState); + } + } + else if (Peb) + { + __try + { + KeStackAttachProcess(process, &apcState); + ClearFlag(Peb->NtGlobalFlag, NT_GLOBAL_FLAG_DEBUGGED); + } + __finally + { + KeUnstackDetachProcess(&apcState); + } + } + else + { + return false; + } + return true; +} + +bool ClearBypassProcessFreezeFlag(_In_ PPROCESS_ENTRY processEntry) +{ + PAGED_CODE(); + NT_ASSERT(processEntry); + + NTSTATUS status; + + if (KERNEL_BUILD_VERSION < WINDOWS_10_VERSION_19H1) + { + return true; + } + + PSYSTEM_PROCESS_INFORMATION processInfo = nullptr; + + status = tools::QuerySystemInformation(SystemProcessInformation, reinterpret_cast(&processInfo)); + if (!NT_SUCCESS(status)) + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "ZwQuerySystemInformation returned %!STATUS!", status); + return false; + } + + SCOPE_EXIT + { + ExFreePool(processInfo); + }; + + for (PSYSTEM_PROCESS_INFORMATION entry = processInfo; entry->NextEntryOffset != NULL; + entry = reinterpret_cast((PUCHAR)entry + entry->NextEntryOffset)) + { + if (processEntry->ProcessId == entry->UniqueProcessId) + { + for (ULONG i = 0ul; i < entry->NumberOfThreads; i++) + { + PETHREAD thread = nullptr; + if (NT_SUCCESS(PsLookupThreadByThreadId(entry->Threads[i].ClientId.UniqueThread, &thread))) + { + *(ULONG *)((ULONG64)thread + dyn::DynCtx.Offsets.BypassProcessFreezeFlag) &= ~(1 << 21); + + ObDereferenceObject(thread); + } + } + return true; + } + } + return false; +} + +bool ClearThreadHideFromDebuggerFlag(_In_ PPROCESS_ENTRY processEntry) +{ + PAGED_CODE(); + NT_ASSERT(processEntry); + + PSYSTEM_PROCESS_INFORMATION processInfo = nullptr; + + const NTSTATUS status = + tools::QuerySystemInformation(SystemProcessInformation, reinterpret_cast(&processInfo)); + if (!NT_SUCCESS(status)) + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "ZwQuerySystemInformation returned %!STATUS!", status); + return false; + } + + SCOPE_EXIT + { + ExFreePool(processInfo); + }; + + for (PSYSTEM_PROCESS_INFORMATION entry = processInfo; entry->NextEntryOffset != NULL; + entry = (PSYSTEM_PROCESS_INFORMATION)((PUCHAR)entry + entry->NextEntryOffset)) + { + if (processEntry->ProcessId == entry->UniqueProcessId) + { + for (ULONG i = 0ul; i < entry->NumberOfThreads; i++) + { + PETHREAD thread = nullptr; + if (NT_SUCCESS(PsLookupThreadByThreadId(entry->Threads[i].ClientId.UniqueThread, &thread))) + { + if (*(ULONG *)((ULONG64)thread + dyn::DynCtx.Offsets.ThreadHideFromDebuggerFlag) & 0x4) + { + PTHREAD_ENTRY threadEntry = processEntry->AppendThreadList(thread); + if (threadEntry) + { + threadEntry->Flags.IsThreadHidden = TRUE; + } + + *(ULONG *)((ULONG64)thread + dyn::DynCtx.Offsets.ThreadHideFromDebuggerFlag) &= ~0x4LU; + } + ObDereferenceObject(thread); + } + } + return true; + } + } + return false; +} + +bool ClearProcessBreakOnTerminationFlag(_In_ PPROCESS_ENTRY processEntry) +{ + PAGED_CODE(); + NT_ASSERT(processEntry); + + HANDLE processHandle = nullptr; + + if (NT_SUCCESS(ObOpenObjectByPointer(processEntry->Process, OBJ_KERNEL_HANDLE, NULL, NULL, *PsProcessType, + KernelMode, &processHandle))) + { + SCOPE_EXIT + { + ObCloseHandle(processHandle, KernelMode); + }; + + ULONG BreakOnTermination; + if (NT_SUCCESS(ZwQueryInformationProcess(processHandle, ProcessBreakOnTermination, &BreakOnTermination, + sizeof(ULONG), NULL))) + { + processEntry->Flags.ValueProcessBreakOnTermination = BreakOnTermination & 1; + BreakOnTermination = 0; + + if (NT_SUCCESS(ZwSetInformationProcess(processHandle, ProcessBreakOnTermination, &BreakOnTermination, + sizeof(ULONG)))) + { + return true; + } + } + } + return false; +} + +void SaveProcessDebugFlags(_In_ PPROCESS_ENTRY processEntry) +{ + PAGED_CODE(); + NT_ASSERT(processEntry); + + HANDLE processHandle = nullptr; + + if (NT_SUCCESS(ObOpenObjectByPointer(processEntry->Process, OBJ_KERNEL_HANDLE, NULL, NULL, *PsProcessType, + KernelMode, &processHandle))) + { + SCOPE_EXIT + { + ObCloseHandle(processHandle, KernelMode); + }; + + ULONG DebugFlags; + if (NT_SUCCESS(ZwQueryInformationProcess(processHandle, ProcessDebugFlags, &DebugFlags, sizeof(ULONG), NULL)) && + PsIsProcessBeingDebugged(processEntry->Process) == FALSE) + { + processEntry->Flags.ValueProcessDebugFlags = !DebugFlags; + } + } +} + +void SaveProcessHandleTracing(_In_ PPROCESS_ENTRY processEntry) +{ + PAGED_CODE(); + NT_ASSERT(processEntry); + + HANDLE processHandle = nullptr; + + if (NT_SUCCESS(ObOpenObjectByPointer(processEntry->Process, OBJ_KERNEL_HANDLE, NULL, NULL, *PsProcessType, + KernelMode, &processHandle))) + { + SCOPE_EXIT + { + ObCloseHandle(processHandle, KernelMode); + }; + + ULONG64 ProcessInformationBuffer[2] = {0}; + + NTSTATUS status = + ZwQueryInformationProcess(processHandle, ProcessHandleTracing, &ProcessInformationBuffer[0], 16, NULL); + if (status == STATUS_SUCCESS) + { + processEntry->Flags.ProcessHandleTracingEnabled = 1; + } + else if (status == STATUS_INVALID_PARAMETER) + { + processEntry->Flags.ProcessHandleTracingEnabled = 0; + } + } +} + +bool ClearThreadBreakOnTerminationFlags(_In_ PPROCESS_ENTRY processEntry) +{ + PAGED_CODE(); + NT_ASSERT(processEntry); + + NTSTATUS status; + PSYSTEM_PROCESS_INFORMATION processInfo = nullptr; + + status = tools::QuerySystemInformation(SystemProcessInformation, reinterpret_cast(&processInfo)); + if (!NT_SUCCESS(status)) + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "ZwQuerySystemInformation returned %!STATUS!", status); + return false; + } + + SCOPE_EXIT + { + ExFreePool(processInfo); + }; + + for (PSYSTEM_PROCESS_INFORMATION entry = processInfo; entry->NextEntryOffset != NULL; + entry = (PSYSTEM_PROCESS_INFORMATION)((PUCHAR)entry + entry->NextEntryOffset)) + { + if (processEntry->ProcessId == entry->UniqueProcessId) + { + for (size_t i = 0; i < entry->NumberOfThreads; i++) + { + PETHREAD thread; + if (NT_SUCCESS(PsLookupThreadByThreadId(entry->Threads[i].ClientId.UniqueThread, &thread))) + { + SCOPE_EXIT + { + ObDereferenceObject(thread); + }; + + if (*(ULONG *)((ULONG64)thread + dyn::DynCtx.Offsets.ThreadBreakOnTerminationFlag) & 0x20) + { + PTHREAD_ENTRY threadEntry = processEntry->AppendThreadList(thread); + if (threadEntry) + { + threadEntry->Flags.BreakOnTermination = TRUE; + *(ULONG *)((ULONG64)thread + dyn::DynCtx.Offsets.ThreadBreakOnTerminationFlag) &= ~0x20; + + return true; + } + } + } + } + } + } + return false; +} + +static ULONG_PTR IpiFlushTbCallback(_In_opt_ ULONG_PTR argument) +{ + UNREFERENCED_PARAMETER(argument); + KeFlushCurrentTbImmediately(); + return 0; +}; + +void HookKuserSharedData(_In_ PPROCESS_ENTRY processEntry) +{ + PAGED_CODE(); + NT_ASSERT(processEntry); + + PHYSICAL_ADDRESS highestAddr; + highestAddr.QuadPart = ~0ULL; + + PVOID NewKuserSharedData = MmAllocateContiguousMemory(sizeof(KUSER_SHARED_DATA), highestAddr); + if (!NewKuserSharedData) + { + return; + } + + ULONG64 PfnNewKuserSharedData = MmGetPhysicalAddress(NewKuserSharedData).QuadPart >> PAGE_SHIFT; + + KAPC_STATE apcState{}; + KeStackAttachProcess(processEntry->Process, &apcState); + { + PMMPFN FakeKUSDMmpfn = (PMMPFN)(MmPfnDatabase + PfnNewKuserSharedData); + FakeKUSDMmpfn->u4.EntireField |= 0x200000000000000; + + RtlCopyMemory(NewKuserSharedData, (PVOID)KUSER_SHARED_DATA_USERMODE, sizeof(KUSER_SHARED_DATA)); + + processEntry->Kusd.PteKuserSharedData = MiGetPteAddress((PVOID)KUSER_SHARED_DATA_USERMODE); + processEntry->Kusd.OriginalKuserSharedDataPfn = processEntry->Kusd.PteKuserSharedData->u.Hard.PageFrameNumber; + processEntry->Kusd.PteKuserSharedData->u.Hard.PageFrameNumber = PfnNewKuserSharedData; + processEntry->Kusd.KuserSharedData = (PKUSER_SHARED_DATA)NewKuserSharedData; + + // issue IPI to flush tb on all cores + // + KeIpiGenericCall(IpiFlushTbCallback, NULL); + KeInvalidateAllCaches(); + + KeUnstackDetachProcess(&apcState); + } +} + +void UnHookKuserSharedData(_In_ PPROCESS_ENTRY processEntry) +{ + PAGED_CODE(); + NT_ASSERT(processEntry); + + ClearFlag(processEntry->PolicyFlags, ProcessPolicyFlagHideKUserSharedData); + + KAPC_STATE apcState{}; + KeStackAttachProcess(processEntry->Process, &apcState); + { + PMMPFN FakeKUSDMmpfn = (PMMPFN)(MmPfnDatabase + processEntry->Kusd.PteKuserSharedData->u.Hard.PageFrameNumber); + FakeKUSDMmpfn->u4.EntireField &= ~0x200000000000000; + + MmFreeContiguousMemory(processEntry->Kusd.KuserSharedData); + + processEntry->Kusd.KuserSharedData = NULL; + processEntry->Kusd.PteKuserSharedData->u.Hard.PageFrameNumber = processEntry->Kusd.OriginalKuserSharedDataPfn; + + // issue IPI to flush tb on all cores + // + KeIpiGenericCall(IpiFlushTbCallback, NULL); + KeInvalidateAllCaches(); + + KeUnstackDetachProcess(&apcState); + } +} + +bool IsWhitelistedDriver(_In_ LPCSTR driverName) +{ + UNREFERENCED_PARAMETER(driverName); + // TODO: implement + return false; +} + +PPROCESS_ENTRY GetProcessEntry(_In_ HANDLE processId) +{ + PAGED_CODE(); + NT_ASSERT(g_initialized); + + PPROCESS_ENTRY resultProcessEntry = nullptr; + + if (g_processResource.LockShared()) + { + EnumProcessesUnsafe([&](PPROCESS_ENTRY processEntry) -> bool { + if (processEntry->ProcessId == processId) + { + object::ReferenceObject(processEntry); + resultProcessEntry = processEntry; + return true; + } + return false; + }); + + g_processResource.Unlock(); + } + + return resultProcessEntry; +} + +PPROCESS_ENTRY GetProcessEntry(_In_ PEPROCESS process) +{ + PAGED_CODE(); + NT_ASSERT(g_initialized); + NT_ASSERT(process); + + return GetProcessEntry(PsGetProcessId(process)); +} + +bool IsProtectedProcess(_In_ HANDLE processId) +{ + PAGED_CODE(); + NT_ASSERT(g_initialized); + + bool result = false; + + if (g_processResource.LockShared()) + { + result = EnumProcessesUnsafe([&](PPROCESS_ENTRY processEntry) -> bool { + return (processEntry->ProcessId == processId && + BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagProtected)); + }); + + g_processResource.Unlock(); + } + + return result; +} + +bool IsProtectedProcess(_In_ PEPROCESS process) +{ + PAGED_CODE(); + NT_ASSERT(g_initialized); + NT_ASSERT(process); + + return IsProtectedProcess(PsGetProcessId(process)); +} + +bool IsProtectedProcess(_In_ PUNICODE_STRING imageFileName) +{ + PAGED_CODE(); + NT_ASSERT(g_initialized); + NT_ASSERT(imageFileName); + + bool result = false; + + if (g_processResource.LockShared()) + { + result = EnumProcessesUnsafe([&](PPROCESS_ENTRY processEntry) -> bool { + return (!RtlCompareUnicodeString(&processEntry->ImageFileName, imageFileName, TRUE) && + BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagProtected)); + }); + + g_processResource.Unlock(); + } + + return result; +} + +bool IsMonitoredProcess(_In_ HANDLE processId) +{ + PAGED_CODE(); + NT_ASSERT(g_initialized); + + bool result = false; + + if (g_processResource.LockShared()) + { + result = EnumProcessesUnsafe([&](PPROCESS_ENTRY processEntry) -> bool { + return (processEntry->ProcessId == processId && + BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagMonitored)); + }); + + g_processResource.Unlock(); + } + + return result; +} + +bool IsMonitoredProcess(_In_ PEPROCESS process) +{ + PAGED_CODE(); + NT_ASSERT(g_initialized); + NT_ASSERT(process); + + return IsMonitoredProcess(PsGetProcessId(process)); +} + +bool IsHiddenFromDebugProcess(_In_ HANDLE processId) +{ + PAGED_CODE(); + NT_ASSERT(g_initialized); + + bool result = false; + + if (g_processResource.LockShared()) + { + result = EnumProcessesUnsafe([&](PPROCESS_ENTRY processEntry) -> bool { + return (processEntry->ProcessId == processId && + BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagHideFromDebugger)); + }); + + g_processResource.Unlock(); + } + + return result; +} + +bool IsHiddenFromDebugProcess(_In_ PEPROCESS process) +{ + PAGED_CODE(); + NT_ASSERT(g_initialized); + NT_ASSERT(process); + + return IsHiddenFromDebugProcess(PsGetProcessId(process)); +} + +void UpdateProcessEntryFlags(_In_ PPROCESS_ENTRY processEntry, _In_ ProcessPolicyFlag_t newFlags) +{ + PAGED_CODE(); + NT_ASSERT(processEntry); + + // Check if any flag was changed + // + if (BooleanFlagOn(newFlags, ProcessPolicyFlagHideKUserSharedData) && + !BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagHideKUserSharedData)) + { + process::HookKuserSharedData(processEntry); + } + else if (!BooleanFlagOn(newFlags, ProcessPolicyFlagHideKUserSharedData) && + BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagHideKUserSharedData)) + { + process::UnHookKuserSharedData(processEntry); + } + + if (BooleanFlagOn(newFlags, ProcessPolicyFlagClearThreadHideFromDebuggerFlag) && + processEntry->Flags.HideFromDebuggerFlagCleared == FALSE) + { + process::ClearThreadHideFromDebuggerFlag(processEntry); + processEntry->Flags.HideFromDebuggerFlagCleared = TRUE; + } + + if (BooleanFlagOn(newFlags, ProcessPolicyFlagClearBypassProcessFreeze) && + processEntry->Flags.BypassProcessFreezeFlagCleared == FALSE) + { + process::ClearBypassProcessFreezeFlag(processEntry); + processEntry->Flags.BypassProcessFreezeFlagCleared = TRUE; + } + + if (BooleanFlagOn(newFlags, ProcessPolicyFlagClearPebBeingDebugged) && + processEntry->Flags.PebBeingDebuggedCleared == FALSE) + { + process::SetPebDeuggerFlag(processEntry->Process, FALSE); + processEntry->Flags.PebBeingDebuggedCleared = TRUE; + } + + if (BooleanFlagOn(newFlags, ProcessPolicyFlagClearPebNtGlobalFlag) && + processEntry->Flags.PebNtGlobalFlagCleared == FALSE) + { + process::ClearPebNtGlobalFlag(processEntry->Process); + processEntry->Flags.PebNtGlobalFlagCleared = TRUE; + } + + if (BooleanFlagOn(newFlags, ProcessPolicyFlagClearHeapFlags) && processEntry->Flags.HeapFlagsCleared == FALSE) + { + process::ClearHeapFlags(processEntry->Process); + processEntry->Flags.HeapFlagsCleared = TRUE; + } + + if (BooleanFlagOn(newFlags, ProcessPolicyFlagClearKUserSharedData) && + processEntry->Flags.KUserSharedDataCleared == FALSE) + { + if (processEntry->Kusd.KuserSharedData != NULL) + { + processEntry->Kusd.KuserSharedData->KdDebuggerEnabled = 0; + processEntry->Flags.KUserSharedDataCleared = TRUE; + } + } + + if (BooleanFlagOn(newFlags, ProcessPolicyFlagClearProcessBreakOnTerminationFlag) && + processEntry->Flags.ProcessBreakOnTerminationCleared == FALSE) + { + process::ClearProcessBreakOnTerminationFlag(processEntry); + processEntry->Flags.ProcessBreakOnTerminationCleared = TRUE; + } + + if (BooleanFlagOn(newFlags, ProcessPolicyFlagClearThreadBreakOnTerminationFlag) && + processEntry->Flags.ThreadBreakOnTerminationCleared == FALSE) + { + process::ClearThreadBreakOnTerminationFlags(processEntry); + processEntry->Flags.ThreadBreakOnTerminationCleared = TRUE; + } + + if (BooleanFlagOn(newFlags, ProcessPolicyFlagSaveProcessDebugFlags) && + processEntry->Flags.ProcessDebugFlagsSaved == FALSE) + { + process::SaveProcessDebugFlags(processEntry); + processEntry->Flags.ProcessDebugFlagsSaved = TRUE; + } + + if (BooleanFlagOn(newFlags, ProcessPolicyFlagSaveProcessHandleTracing) && + processEntry->Flags.ProcessHandleTracingSaved == FALSE) + { + process::SaveProcessHandleTracing(processEntry); + processEntry->Flags.ProcessHandleTracingSaved = TRUE; + } + + // Finally set the policy flags + // + InterlockedExchange64(&processEntry->PolicyFlags, newFlags); +} + +NTSTATUS UpdateProcessEntry(_In_ HANDLE processId, _In_ ProcessPolicyFlag_t flags) +{ + PAGED_CODE(); + NT_ASSERT(g_initialized); + + PPROCESS_ENTRY processEntry = GetProcessEntry(processId); + if (!processEntry) + { + return STATUS_NOT_FOUND; + } + + SCOPE_EXIT + { + object::DereferenceObject(processEntry); + }; + + if (!g_processResource.LockExclusive()) + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "Failed to obtain process resource lock!"); + return STATUS_LOCK_NOT_GRANTED; + } + + SCOPE_EXIT + { + g_processResource.Unlock(); + }; + + UpdateProcessEntryFlags(processEntry, flags); + + return STATUS_SUCCESS; +} + +NTSTATUS UpdateProcessEntry(_In_ PEPROCESS process, _In_ ProcessPolicyFlag_t flags) +{ + PAGED_CODE(); + NT_ASSERT(g_initialized); + NT_ASSERT(process); + + return UpdateProcessEntry(PsGetProcessId(process), flags); +} + +NTSTATUS AddProcessEntry(_In_ PEPROCESS process, _In_ ProcessPolicyFlag_t flags) +{ + PAGED_CODE(); + NT_ASSERT(g_initialized); + NT_ASSERT(process); + + auto ExistsProcessEntry = [&]() -> bool { + return EnumProcessesUnsafe( + [&](PPROCESS_ENTRY processEntry) -> bool { return (processEntry->Process == process); }); + }; + + UNICODE_STRING imageFileName{}; + + // We have to obtain file name first because acquiring lock will disable kernel APCs + // + if (!tools::GetProcessFileName(process, &imageFileName)) + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "Failed to obtain pid:%d file name!", + HandleToUlong(PsGetProcessId(process))); + + return STATUS_UNSUCCESSFUL; + } + + if (!g_processResource.LockExclusive()) + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "Failed to obtain process resource lock!"); + return STATUS_LOCK_NOT_GRANTED; + } + + SCOPE_EXIT + { + g_processResource.Unlock(); + }; + + if (ExistsProcessEntry()) + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "Failed to add process entry, pid:%d already exists in list!", + HandleToUlong(PsGetProcessId(process))); + + return STATUS_ALREADY_REGISTERED; + } + + PPROCESS_ENTRY processEntry = nullptr; + + NTSTATUS status = object::CreateObject(g_objTypeProcessEntry, sizeof(PROCESS_ENTRY), + reinterpret_cast(&processEntry), nullptr); + if (!NT_SUCCESS(status)) + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "Failed to create process entry object %!STATUS!", status); + + return STATUS_UNSUCCESSFUL; + } + + status = processEntry->ThreadsResource.Initialize(); + if (!NT_SUCCESS(status)) + { + object::DereferenceObject(processEntry); + + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "Failed to initialize threads list resource!"); + + return STATUS_UNSUCCESSFUL; + } + + ObReferenceObject(process); + processEntry->Process = process; + processEntry->ProcessId = PsGetProcessId(process); + processEntry->ImageFileName = imageFileName; + RtlStringCchCopyW(processEntry->FakeParentProcessName, ARRAYSIZE(processEntry->FakeParentProcessName) - 1, + L"explorer.exe"); + + UpdateProcessEntryFlags(processEntry, flags); + + InitializeListHead(&processEntry->Threads.ListEntry); + InsertTailList(&g_processListHead, &processEntry->ListEntry); + + return STATUS_SUCCESS; +} + +NTSTATUS AddProcessEntry(_In_ HANDLE processId, _In_ ProcessPolicyFlag_t flags) +{ + PAGED_CODE(); + NT_ASSERT(g_initialized); + + PEPROCESS process = nullptr; + NTSTATUS status = PsLookupProcessByProcessId(processId, &process); + if (!NT_SUCCESS(status)) + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "PsLookupProcessByProcessId returned %!STATUS!", status); + + return status; + } + + SCOPE_EXIT + { + ObDereferenceObject(process); + }; + + return AddProcessEntry(process, flags); +} + +NTSTATUS RemoveProcessEntry(_In_ HANDLE processId) +{ + PAGED_CODE(); + NT_ASSERT(g_initialized); + + NTSTATUS status = STATUS_NOT_CAPABLE; + + if (g_processResource.LockExclusive()) + { + if (EnumProcessesUnsafe([&](PPROCESS_ENTRY processEntry) -> bool { + if (processEntry->ProcessId == processId) + { + if (processEntry->Kusd.KuserSharedData != NULL) + { + process::UnHookKuserSharedData(processEntry); + } + + RemoveEntryList(&processEntry->ListEntry); + object::DereferenceObject(processEntry); + + return true; + } + return false; + })) + { + status = STATUS_SUCCESS; + } + + g_processResource.Unlock(); + } + return status; +} + +NTSTATUS RemoveProcessEntry(_In_ PEPROCESS process) +{ + PAGED_CODE(); + NT_ASSERT(g_initialized); + NT_ASSERT(process); + + return RemoveProcessEntry(PsGetProcessId(process)); +} + +void CounterUpdater(PVOID Context) +{ + UNREFERENCED_PARAMETER(Context); + + LARGE_INTEGER timeToWait = {0}; + timeToWait.QuadPart = -10000LL; // relative 1ms + + DBGPRINT("Starting counter updater thread"); + + while (!g_stopCounterThread) + { + KeDelayExecutionThread(KernelMode, FALSE, &timeToWait); + + if (g_processResource.LockExclusive()) + { + EnumProcessesUnsafe([](_In_ PPROCESS_ENTRY processEntry) -> bool { + if (!processEntry->Flags.ProcessPaused && processEntry->Kusd.KuserSharedData && + BooleanFlagOn(processEntry->PolicyFlags, ProcessPolicyFlagHideKUserSharedData)) + { + *(ULONG64 *)&processEntry->Kusd.KuserSharedData->InterruptTime = + *(ULONG64 *)&KernelKuserSharedData->InterruptTime.LowPart - + processEntry->Kusd.DeltaInterruptTime; + processEntry->Kusd.KuserSharedData->InterruptTime.High2Time = + processEntry->Kusd.KuserSharedData->InterruptTime.High1Time; + + *(ULONG64 *)&processEntry->Kusd.KuserSharedData->SystemTime = + *(ULONG64 *)&KernelKuserSharedData->SystemTime.LowPart - processEntry->Kusd.DeltaSystemTime; + processEntry->Kusd.KuserSharedData->SystemTime.High2Time = + processEntry->Kusd.KuserSharedData->SystemTime.High1Time; + + processEntry->Kusd.KuserSharedData->LastSystemRITEventTickCount = + KernelKuserSharedData->LastSystemRITEventTickCount - + processEntry->Kusd.DeltaLastSystemRITEventTickCount; + + *(ULONG64 *)&processEntry->Kusd.KuserSharedData->TickCount = + *(ULONG64 *)&KernelKuserSharedData->TickCount.LowPart - processEntry->Kusd.DeltaTickCount; + processEntry->Kusd.KuserSharedData->TickCount.High2Time = + processEntry->Kusd.KuserSharedData->TickCount.High1Time; + + processEntry->Kusd.KuserSharedData->TimeUpdateLock = + KernelKuserSharedData->TimeUpdateLock - processEntry->Kusd.DeltaTimeUpdateLock; + + processEntry->Kusd.KuserSharedData->BaselineSystemTimeQpc = + KernelKuserSharedData->BaselineSystemTimeQpc - processEntry->Kusd.DeltaBaselineSystemQpc; + processEntry->Kusd.KuserSharedData->BaselineInterruptTimeQpc = + processEntry->Kusd.KuserSharedData->BaselineSystemTimeQpc; + } + + return false; + }); + g_processResource.Unlock(); + } + } + + DBGPRINT("Leaving counter updater thread"); + PsTerminateSystemThread(STATUS_SUCCESS); +} + +void GetBegin(_In_ PEPROCESS process) +{ + PAGED_CODE(); + NT_ASSERT(process); + + if (g_processResource.LockExclusive()) + { + EnumProcessesUnsafe([&](_In_ PPROCESS_ENTRY processEntry) -> bool { + if (processEntry->Process == process && processEntry->Kusd.BeginInterruptTime == NULL) + { + processEntry->Kusd.BeginInterruptTime = *(ULONG64 *)&KernelKuserSharedData->InterruptTime; + processEntry->Kusd.BeginSystemTime = *(ULONG64 *)&KernelKuserSharedData->SystemTime; + processEntry->Kusd.BeginLastSystemRITEventTickCount = + KernelKuserSharedData->LastSystemRITEventTickCount; + processEntry->Kusd.BeginTickCount = *(ULONG64 *)&KernelKuserSharedData->TickCount; + processEntry->Kusd.BeginTimeUpdateLock = KernelKuserSharedData->TimeUpdateLock; + processEntry->Kusd.BeginBaselineSystemQpc = KernelKuserSharedData->BaselineSystemTimeQpc; + } + + return false; + }); + + g_processResource.Unlock(); + } +} + +void UpdateDelta(_In_ PEPROCESS process) +{ + PAGED_CODE(); + NT_ASSERT(process); + + if (g_processResource.LockExclusive()) + { + EnumProcessesUnsafe([&](_In_ PPROCESS_ENTRY processEntry) -> bool { + if (processEntry->Process == process && processEntry->Kusd.BeginInterruptTime != NULL) + { + processEntry->Kusd.DeltaInterruptTime += + *(ULONG64 *)&KernelKuserSharedData->InterruptTime - processEntry->Kusd.BeginInterruptTime; + processEntry->Kusd.DeltaSystemTime += + *(ULONG64 *)&KernelKuserSharedData->SystemTime - processEntry->Kusd.BeginSystemTime; + processEntry->Kusd.DeltaLastSystemRITEventTickCount += + KernelKuserSharedData->LastSystemRITEventTickCount - + processEntry->Kusd.BeginLastSystemRITEventTickCount; + processEntry->Kusd.DeltaTickCount += + *(ULONG64 *)&KernelKuserSharedData->TickCount - processEntry->Kusd.BeginTickCount; + processEntry->Kusd.DeltaTimeUpdateLock += + KernelKuserSharedData->TimeUpdateLock - processEntry->Kusd.BeginTimeUpdateLock; + processEntry->Kusd.DeltaBaselineSystemQpc += + KernelKuserSharedData->BaselineSystemTimeQpc - processEntry->Kusd.BeginBaselineSystemQpc; + + RtlZeroMemory(&processEntry->Kusd.BeginInterruptTime, sizeof(ULONG64) * 5 + 4); + } + + return false; + }); + + g_processResource.Unlock(); + } +} + +NTSTATUS ModifyCounterForProcess(_In_ PEPROCESS process, _In_ BOOLEAN value) +{ + PAGED_CODE(); + NT_ASSERT(g_initialized); + NT_ASSERT(process); + + NTSTATUS status = STATUS_NOT_CAPABLE; + + if (g_processResource.LockExclusive()) + { + if (EnumProcessesUnsafe([&](_In_ PPROCESS_ENTRY processEntry) -> bool { + if (processEntry->Process == process) + { + processEntry->Flags.ProcessPaused = value; + return true; + } + return false; + })) + { + status = STATUS_SUCCESS; + } + g_processResource.Unlock(); + } + return status; +} + +BOOLEAN StopCounterForProcess(_In_ PEPROCESS process) +{ + PAGED_CODE(); + NT_ASSERT(g_initialized); + NT_ASSERT(process); + + BOOLEAN status = FALSE; + + if (g_processResource.LockExclusive()) + { + if (EnumProcessesUnsafe([&](_In_ PPROCESS_ENTRY processEntry) -> bool { + if (processEntry->Process == process) + { + status = (processEntry->Flags.ProcessPaused = TRUE); + return true; + } + return false; + })) + { + status = STATUS_SUCCESS; + } + g_processResource.Unlock(); + } + return status; +} + +BOOLEAN ResumeCounterForProcess(_In_ PEPROCESS process) +{ + PAGED_CODE(); + NT_ASSERT(g_initialized); + NT_ASSERT(process); + + BOOLEAN status = FALSE; + + if (g_processResource.LockExclusive()) + { + if (EnumProcessesUnsafe([&](_In_ PPROCESS_ENTRY processEntry) -> bool { + if (processEntry->Process == process) + { + status = (processEntry->Flags.ProcessPaused = FALSE); + return true; + } + return false; + })) + { + status = STATUS_SUCCESS; + } + g_processResource.Unlock(); + } + return status; +} + +PTHREAD_ENTRY PROCESS_ENTRY::AppendThreadList(_In_ PETHREAD thread) +{ + PAGED_CODE(); + NT_ASSERT(thread); + + if (ThreadsResource.LockExclusive()) + { + SCOPE_EXIT + { + ThreadsResource.Unlock(); + }; + + // First search thread in list + // + PLIST_ENTRY listEntry = Threads.ListEntry.Flink; + PTHREAD_ENTRY threadEntry = nullptr; + + while (listEntry != &Threads.ListEntry) + { + threadEntry = CONTAINING_RECORD(listEntry, THREAD_ENTRY, ListEntry); + listEntry = listEntry->Flink; + + if (threadEntry->Thread == thread) + { + return threadEntry; + } + } + + // If not found then proceed to insert to list + // + threadEntry = + tools::AllocatePoolZero(NonPagedPool, sizeof(THREAD_ENTRY), tags::TAG_THREAD_ENTRY); + if (!threadEntry) + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "Failed to allocate thread entry!"); + return nullptr; + } + + ObReferenceObject(thread); + threadEntry->Thread = thread; + InsertTailList(&Threads.ListEntry, &threadEntry->ListEntry); + + return threadEntry; + } + return nullptr; +} + +namespace rules +{ +DECLARE_GLOBAL_CONST_UNICODE_STRING(g_processRuleEntryObjectName, L"ProcessRuleEntryObject"); +object::POBJECT_TYPE g_objTypeProcessRuleEntry = nullptr; + +void FreeProcessRuleEntry(_In_ PVOID object); +PVOID AllocateProcessRuleEntry(_In_ SIZE_T size); +void DeleteProcessRuleEntry(_In_ PVOID object); + +NTSTATUS Initialize() +{ + NT_ASSERT(!g_initialized); + + if (g_initialized) + { + return STATUS_ALREADY_INITIALIZED; + } + + InitializeListHead(&g_processRuleListHead); + + NTSTATUS status = g_processRuleResource.Initialize(); + if (!NT_SUCCESS(status)) + { + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, "Failed to initialize processes rules resource %!STATUS!", status); + return STATUS_UNSUCCESSFUL; + } + + // Create object types + // + object::OBJECT_TYPE_INFO typeInfo{}; + typeInfo.Allocate = AllocateProcessRuleEntry; + typeInfo.Initialize = NULL; + typeInfo.Delete = DeleteProcessRuleEntry; + typeInfo.Free = FreeProcessRuleEntry; + object::CreateObjectType(&g_processRuleEntryObjectName, &typeInfo, &g_objTypeProcessRuleEntry); + + g_initialized = true; + + return STATUS_SUCCESS; +} + +void Deinitialize() +{ + PAGED_CODE(); + + if (!g_initialized) + { + return; + } + + // (1) Obtain lock and free all list objects recursively + // + if (g_processRuleResource.LockExclusive()) + { + while (!IsListEmpty(&g_processRuleListHead)) + { + PLIST_ENTRY listEntry = RemoveHeadList(&g_processRuleListHead); + PPROCESS_RULE_ENTRY processRuleEntry = CONTAINING_RECORD(listEntry, PROCESS_RULE_ENTRY, ListEntry); + + object::DereferenceObject(processRuleEntry); + } + + g_processRuleResource.Unlock(); + } + + // (2) De-initialize the resource + // + g_processRuleResource.Deinitialize(); + + g_initialized = false; + + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, "Successfully de-initialized process rules interface!"); + return; +} + +void FreeProcessRuleEntry(_In_ PVOID object) +{ + PAGED_CODE(); + + ExFreePool(object); +} + +PVOID AllocateProcessRuleEntry(_In_ SIZE_T size) +{ + PAGED_CODE(); + + return tools::AllocatePoolZero(NonPagedPool, size, tags::TAG_PROCESS_RULE_ENTRY); +} + +void DeleteProcessRuleEntry(_In_ PVOID object) +{ + NT_ASSERT(object); + + auto processRuleEntry = static_cast(object); + + if (processRuleEntry->ImageFileName.Buffer) + { + RtlFreeUnicodeString(&processRuleEntry->ImageFileName); + } +} + +NTSTATUS AddProcessRuleEntry(_In_ PUNICODE_STRING imageFileName, _In_ ProcessPolicyFlag_t flags) +{ + PAGED_CODE(); + NT_ASSERT(g_initialized); + NT_ASSERT(imageFileName); + + auto ExistsProcessRuleEntry = [&]() -> bool { + return EnumRuleProcessesUnsafe([&](PPROCESS_RULE_ENTRY processRuleEntry) -> bool { + return !RtlCompareUnicodeString(&processRuleEntry->ImageFileName, imageFileName, TRUE); + }); + }; + + if (!g_processRuleResource.LockExclusive()) + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "Failed to obtain process rule entry resource lock!"); + + return STATUS_LOCK_NOT_GRANTED; + } + + SCOPE_EXIT + { + g_processRuleResource.Unlock(); + }; + + if (ExistsProcessRuleEntry()) + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "image:%wZ already exists in process rule list!", imageFileName); + + return STATUS_ALREADY_REGISTERED; + } + + PPROCESS_RULE_ENTRY processRuleEntry = nullptr; + NTSTATUS status = object::CreateObject(g_objTypeProcessRuleEntry, sizeof(PROCESS_RULE_ENTRY), + reinterpret_cast(&processRuleEntry), nullptr); + if (!NT_SUCCESS(status)) + { + + return STATUS_UNSUCCESSFUL; + } + + processRuleEntry->PolicyFlags = flags; + processRuleEntry->ImageFileName.Length = 0; + processRuleEntry->ImageFileName.MaximumLength = NTSTRSAFE_UNICODE_STRING_MAX_CCH; + processRuleEntry->ImageFileName.Buffer = tools::AllocatePoolZero( + NonPagedPool, processRuleEntry->ImageFileName.MaximumLength * sizeof(WCHAR), tags::TAG_STRING); + if (!processRuleEntry->ImageFileName.Buffer) + { + object::DereferenceObject(processRuleEntry); + + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "Failed to allocate image file name!"); + + return STATUS_INSUFFICIENT_RESOURCES; + } + + RtlCopyUnicodeString(&processRuleEntry->ImageFileName, imageFileName); + InsertTailList(&g_processRuleListHead, &processRuleEntry->ListEntry); + + return STATUS_SUCCESS; +} + +PPROCESS_RULE_ENTRY GetProcessRuleEntry(_In_ PCUNICODE_STRING imageFileName) +{ + PAGED_CODE(); + NT_ASSERT(g_initialized); + NT_ASSERT(imageFileName); + + PPROCESS_RULE_ENTRY resultProcessRuleEntry = nullptr; + + if (g_processRuleResource.LockShared()) + { + EnumRuleProcessesUnsafe([&](_In_ PPROCESS_RULE_ENTRY processRuleEntry) -> bool { + if (!RtlCompareUnicodeString(&processRuleEntry->ImageFileName, imageFileName, TRUE)) + { + object::ReferenceObject(processRuleEntry); + resultProcessRuleEntry = processRuleEntry; + return true; + } + return false; + }); + + g_processRuleResource.Unlock(); + } + + return resultProcessRuleEntry; +} + +NTSTATUS UpdateProcessRuleEntry(_In_ PUNICODE_STRING imageFileName, _In_ ProcessPolicyFlag_t flags) +{ + PAGED_CODE(); + NT_ASSERT(g_initialized); + NT_ASSERT(imageFileName); + + NTSTATUS status = STATUS_NOT_CAPABLE; + + if (g_processRuleResource.LockExclusive()) + { + if (EnumRuleProcessesUnsafe([&](_In_ PPROCESS_RULE_ENTRY processRuleEntry) -> bool { + if (!RtlCompareUnicodeString(&processRuleEntry->ImageFileName, imageFileName, TRUE)) + { + processRuleEntry->PolicyFlags = flags; + return true; + } + return false; + })) + { + status = STATUS_SUCCESS; + } + + g_processRuleResource.Unlock(); + } + + return status; +} + +NTSTATUS RemoveProcessRuleEntry(_In_ PCUNICODE_STRING imageFileName) +{ + PAGED_CODE(); + NT_ASSERT(g_initialized); + NT_ASSERT(imageFileName); + + NTSTATUS status = STATUS_NOT_CAPABLE; + + if (g_processRuleResource.LockExclusive()) + { + if (EnumRuleProcessesUnsafe([&](_In_ PPROCESS_RULE_ENTRY processRuleEntry) -> bool { + if (!RtlCompareUnicodeString(&processRuleEntry->ImageFileName, imageFileName, TRUE)) + { + RemoveEntryList(&processRuleEntry->ListEntry); + return true; + } + return false; + })) + { + status = STATUS_SUCCESS; + } + + g_processRuleResource.Unlock(); + } + + return status; +} +} // namespace rules +} // namespace process +} // namespace masterhide \ No newline at end of file diff --git a/MasterHide/process.hpp b/MasterHide/process.hpp new file mode 100644 index 0000000..4133afd --- /dev/null +++ b/MasterHide/process.hpp @@ -0,0 +1,233 @@ +#pragma once + +namespace masterhide +{ +namespace process +{ +typedef struct _DEBUG_CONTEXT +{ + ULONG64 Dr0; + ULONG64 Dr1; + ULONG64 Dr2; + ULONG64 Dr3; + ULONG64 Dr6; + ULONG64 Dr7; + + ULONG64 DebugControl; + ULONG64 LastBranchFromRip; + ULONG64 LastBranchToRip; + ULONG64 LastExceptionFromRip; + ULONG64 LastExceptionToRip; + +} DEBUG_CONTEXT, *PDEBUG_CONTEXT; + +typedef struct _WOW64_DEBUG_CONTEXT +{ + ULONG Dr0; + ULONG Dr1; + ULONG Dr2; + ULONG Dr3; + ULONG Dr6; + ULONG Dr7; + +} WOW64_DEBUG_CONTEXT, *PWOW64_DEBUG_CONTEXT; + +typedef struct _KUSD +{ + PKUSER_SHARED_DATA KuserSharedData; + PMMPTE PteKuserSharedData; + ULONG OriginalKuserSharedDataPfn; + ULONG64 BeginInterruptTime; + ULONG64 BeginSystemTime; + ULONG BeginLastSystemRITEventTickCount; + ULONG64 BeginTickCount; + ULONG64 BeginTimeUpdateLock; + ULONG64 BeginBaselineSystemQpc; + ULONG64 DeltaInterruptTime; + ULONG64 DeltaSystemTime; + ULONG DeltaLastSystemRITEventTickCount; + ULONG64 DeltaTickCount; + ULONG64 DeltaTimeUpdateLock; + ULONG64 DeltaBaselineSystemQpc; + +} KUSD, *PKUSD; + +typedef struct _THREAD_ENTRY +{ + PETHREAD Thread; + WOW64_DEBUG_CONTEXT SavedWow64DebugContext; + DEBUG_CONTEXT SavedDebugContext; + union { + struct + { + BOOLEAN IsThreadHidden : 1; + BOOLEAN BreakOnTermination : 1; + } Flags; + LONG Long; + }; + LIST_ENTRY ListEntry; + +} THREAD_ENTRY, *PTHREAD_ENTRY; + +typedef struct _PROCESS_ENTRY +{ + PEPROCESS Process; + HANDLE ProcessId; + UNICODE_STRING ImageFileName; + ProcessPolicyFlag_t PolicyFlags; + WCHAR FakeParentProcessName[_MAX_FNAME]; + LARGE_INTEGER FakePerformanceCounter; + LARGE_INTEGER FakeSystemTime; + union { + struct + { + BOOLEAN ProcessPaused : 1; + BOOLEAN PebBeingDebuggedCleared : 1; + BOOLEAN HeapFlagsCleared : 1; + BOOLEAN PebNtGlobalFlagCleared : 1; + BOOLEAN KUserSharedDataCleared : 1; + BOOLEAN HideFromDebuggerFlagCleared : 1; + BOOLEAN BypassProcessFreezeFlagCleared : 1; + BOOLEAN ProcessHandleTracingEnabled : 1; + BOOLEAN ProcessBreakOnTerminationCleared : 1; + BOOLEAN ThreadBreakOnTerminationCleared : 1; + BOOLEAN ProcessDebugFlagsSaved : 1; + BOOLEAN ProcessHandleTracingSaved : 1; + BOOLEAN ValueProcessBreakOnTermination : 1; + BOOLEAN ValueProcessDebugFlags : 1; + } Flags; + LONG Long; + }; + KUSD Kusd; + THREAD_ENTRY Threads; + mutex::EResource ThreadsResource; + LIST_ENTRY ListEntry; + + [[nodiscard]] PTHREAD_ENTRY AppendThreadList(_In_ PETHREAD thread); + +} PROCESS_ENTRY, *PPROCESS_ENTRY; + +inline LIST_ENTRY g_processListHead{}; +inline mutex::EResource g_processResource{}; +inline bool g_initialized = false; + +NTSTATUS Initialize(); +void Deinitialize(); + +PVOID AllocateProcessEntry(_In_ SIZE_T size); +void FreeProcessEntry(_In_ PVOID object); +void DeleteProcessEntry(_In_ PVOID object); + +[[nodiscard]] NTSTATUS AddProcessEntry(_In_ PEPROCESS process, _In_ ProcessPolicyFlag_t flags); +[[nodiscard]] NTSTATUS AddProcessEntry(_In_ HANDLE processId, _In_ ProcessPolicyFlag_t flags); + +[[nodiscard]] PPROCESS_ENTRY GetProcessEntry(_In_ PEPROCESS process); +[[nodiscard]] PPROCESS_ENTRY GetProcessEntry(_In_ HANDLE processId); + +[[nodiscard]] NTSTATUS UpdateProcessEntry(_In_ PEPROCESS process, _In_ ProcessPolicyFlag_t flags); +[[nodiscard]] NTSTATUS UpdateProcessEntry(_In_ HANDLE processId, _In_ ProcessPolicyFlag_t flags); + +NTSTATUS RemoveProcessEntry(_In_ PEPROCESS process); +NTSTATUS RemoveProcessEntry(_In_ HANDLE processId); + +[[nodiscard]] bool IsProtectedProcess(_In_ HANDLE processId); +[[nodiscard]] bool IsProtectedProcess(_In_ PEPROCESS process); +[[nodiscard]] bool IsProtectedProcess(_In_ PUNICODE_STRING processFullPath); + +[[nodiscard]] bool IsMonitoredProcess(_In_ HANDLE processId); +[[nodiscard]] bool IsMonitoredProcess(_In_ PEPROCESS process); +[[nodiscard]] bool IsMonitoredProcess(_In_ PUNICODE_STRING processFullPath); + +[[nodiscard]] bool IsHiddenFromDebugProcess(_In_ HANDLE processId); +[[nodiscard]] bool IsHiddenFromDebugProcess(_In_ PEPROCESS process); +[[nodiscard]] bool IsHiddenFromDebugProcess(_In_ PUNICODE_STRING processFullPath); + +void GetBegin(_In_ PEPROCESS process); +void UpdateDelta(_In_ PEPROCESS process); +void CounterUpdater(PVOID Context); +BOOLEAN StopCounterForProcess(_In_ PEPROCESS process); +BOOLEAN ResumeCounterForProcess(_In_ PEPROCESS process); +NTSTATUS ModifyCounterForProcess(_In_ PEPROCESS process, _In_ BOOLEAN status); + +bool ClearHeapFlags(PEPROCESS process); +bool SetPebDeuggerFlag(PEPROCESS process, BOOLEAN value); +bool ClearPebNtGlobalFlag(PEPROCESS process); + +bool ClearBypassProcessFreezeFlag(_In_ PPROCESS_ENTRY processEntry); +bool ClearThreadHideFromDebuggerFlag(_In_ PPROCESS_ENTRY processEntry); +bool ClearProcessBreakOnTerminationFlag(_In_ PPROCESS_ENTRY processEntry); +void SaveProcessDebugFlags(_In_ PPROCESS_ENTRY processEntry); +void SaveProcessHandleTracing(_In_ PPROCESS_ENTRY processEntry); +bool ClearThreadBreakOnTerminationFlags(_In_ PPROCESS_ENTRY processEntry); + +void HookKuserSharedData(_In_ PPROCESS_ENTRY processEntry); +void UnHookKuserSharedData(PPROCESS_ENTRY processEntry); + +using ENUM_PROCESSES_CALLBACK = bool (*)(_In_ PPROCESS_ENTRY); + +template bool EnumProcessesUnsafe(Callback &&callback) +{ + NT_ASSERT(g_initialized); + + if (!IsListEmpty(&g_processListHead)) + { + for (PLIST_ENTRY listEntry = g_processListHead.Flink; listEntry != &g_processListHead; + listEntry = listEntry->Flink) + { + PPROCESS_ENTRY processEntry = CONTAINING_RECORD(listEntry, PROCESS_ENTRY, ListEntry); + if (callback(processEntry)) + { + return true; + } + } + } + return false; +} + +namespace rules +{ +typedef struct _PROCESS_RULE_ENTRY +{ + UNICODE_STRING ImageFileName; + ProcessPolicyFlag_t PolicyFlags; + LIST_ENTRY ListEntry; + +} PROCESS_RULE_ENTRY, *PPROCESS_RULE_ENTRY; + +inline LIST_ENTRY g_processRuleListHead{}; +inline mutex::EResource g_processRuleResource{}; +inline bool g_initialized = false; + +NTSTATUS Initialize(); +void Deinitialize(); + +using ENUM_RULE_PROCESSES_CALLBACK = bool (*)(_In_ PPROCESS_RULE_ENTRY); + +template bool EnumRuleProcessesUnsafe(Callback &&callback) +{ + NT_ASSERT(g_initialized); + + if (!IsListEmpty(&g_processRuleListHead)) + { + for (PLIST_ENTRY listEntry = g_processRuleListHead.Flink; listEntry != &g_processRuleListHead; + listEntry = listEntry->Flink) + { + PPROCESS_RULE_ENTRY processRuleEntry = CONTAINING_RECORD(listEntry, PROCESS_RULE_ENTRY, ListEntry); + if (callback(processRuleEntry)) + { + return true; + } + } + } + return false; +} + +[[nodiscard]] NTSTATUS AddProcessRuleEntry(_In_ PUNICODE_STRING imageFileName, _In_ ProcessPolicyFlag_t flags); + +[[nodiscard]] NTSTATUS UpdateProcessRuleEntry(_In_ PUNICODE_STRING imageFileName, _In_ ProcessPolicyFlag_t flags); +[[nodiscard]] PPROCESS_RULE_ENTRY GetProcessRuleEntry(_In_ PCUNICODE_STRING imageFileName); + +NTSTATUS RemoveProcessRuleEntry(_In_ PCUNICODE_STRING imageFileName); +} // namespace rules +} // namespace process +} // namespace masterhide \ No newline at end of file diff --git a/MasterHide/shadow_ssdt.cpp b/MasterHide/shadow_ssdt.cpp index 1bad560..7608f2f 100644 --- a/MasterHide/shadow_ssdt.cpp +++ b/MasterHide/shadow_ssdt.cpp @@ -1,402 +1,325 @@ -#include "stdafx.h" +#include "includes.hpp" PSYSTEM_SERVICE_TABLE g_KeServiceDescriptorTableShadow = NULL; -HANDLE hCsrssPID = HANDLE( -1 ); ULONGLONG GetKeServiceDescriptorTableShadow64() { - PUCHAR StartSearchAddress = ( PUCHAR )__readmsr( 0xC0000082 ); - PUCHAR EndSearchAddress = StartSearchAddress + 0x500; - PUCHAR i = NULL; - UCHAR b1 = 0, b2 = 0, b3 = 0; - ULONG templong = 0; - ULONGLONG addr = 0; - for ( i = StartSearchAddress; i < EndSearchAddress; i++ ) - { - if ( MmIsAddressValid( i ) && MmIsAddressValid( i + 1 ) && MmIsAddressValid( i + 2 ) ) - { - b1 = *i; - b2 = *( i + 1 ); - b3 = *( i + 2 ); - if ( b1 == 0x4c && b2 == 0x8d && b3 == 0x1d ) - { - memcpy( &templong, i + 3, 4 ); - addr = ( ULONGLONG )templong + ( ULONGLONG )i + 7; - return addr; - } - } - } - return 0; + PUCHAR StartSearchAddress = (PUCHAR)__readmsr(0xC0000082); + PUCHAR EndSearchAddress = StartSearchAddress + 0x500; + PUCHAR i = NULL; + UCHAR b1 = 0, b2 = 0, b3 = 0; + ULONG templong = 0; + ULONGLONG addr = 0; + for (i = StartSearchAddress; i < EndSearchAddress; i++) + { + if (MmIsAddressValid(i) && MmIsAddressValid(i + 1) && MmIsAddressValid(i + 2)) + { + b1 = *i; + b2 = *(i + 1); + b3 = *(i + 2); + if (b1 == 0x4c && b2 == 0x8d && b3 == 0x1d) + { + memcpy(&templong, i + 3, 4); + addr = (ULONGLONG)templong + (ULONGLONG)i + 7; + return addr; + } + } + } + return 0; } -ULONGLONG GetSSSDTFuncCurAddr64( ULONG64 Index ) +ULONGLONG GetSSSDTFuncCurAddr64(ULONG64 Index) { - ULONGLONG W32pServiceTable = 0, qwTemp = 0; - LONG dwTemp = 0; - W32pServiceTable = ( ULONGLONG )( g_KeServiceDescriptorTableShadow->ServiceTableBase ); - qwTemp = W32pServiceTable + 4 * ( Index - 0x1000 ); - dwTemp = *( PLONG )qwTemp; - dwTemp = dwTemp >> 4; - qwTemp = W32pServiceTable + ( LONG64 )dwTemp; - return qwTemp; + ULONGLONG W32pServiceTable = 0, qwTemp = 0; + LONG dwTemp = 0; + W32pServiceTable = (ULONGLONG)(g_KeServiceDescriptorTableShadow->ServiceTableBase); + qwTemp = W32pServiceTable + 4 * (Index - 0x1000); + dwTemp = *(PLONG)qwTemp; + dwTemp = dwTemp >> 4; + qwTemp = W32pServiceTable + (LONG64)dwTemp; + return qwTemp; } -bool HookSSSDT( PUCHAR pCode, ULONG ulCodeSize, PVOID pNewFunction, PVOID* pOldFunction, ULONG SyscallNum ) +bool HookSSSDT(PUCHAR pCode, ULONG ulCodeSize, PVOID pNewFunction, PVOID *pOldFunction, ULONG SyscallNum) { - if ( !pNewFunction || !pOldFunction || SyscallNum <= 0 ) - return false; - - ULONGLONG W32pServiceTable = 0, qwTemp = 0; - LONG dwTemp = 0; - KIRQL irql; - - // - // Log the Syscall number that we're hooking - // - DBGPRINT( "[ HookSSSDT ] Syscall: 0x%X\n", SyscallNum ); - - // - // Log the Original function address - // - *pOldFunction = PVOID( GetSSSDTFuncCurAddr64( SyscallNum ) ); - DBGPRINT( "[ HookSSSDT ] Original: 0x%p\n", *pOldFunction ); - - *( PULONG64 )( jmp_trampoline + 3 ) = ULONG64( pNewFunction ); - - // - // Find a suitable code cave inside the module .text section that we can use to trampoline to our hook - // - auto pCodeCave = utils::FindCodeCave( pCode, ulCodeSize, sizeof( jmp_trampoline ) ); - if ( !pCodeCave ) - { - DBGPRINT( "[ HookSSSDT ] Failed to find a suitable code cave.\n" ); - return false; - } - - DBGPRINT( "[ HookSSSDT ] Code Cave: 0x%p\n", pCodeCave ); - - // - // Change page protection - // - auto Mdl = IoAllocateMdl( pCodeCave, sizeof( jmp_trampoline ), 0, 0, NULL ); - if ( Mdl == NULL ) - { - DBGPRINT( "[ HookSSSDT ] IoAllocateMdl failed!\n" ); - return false; - } - - MmProbeAndLockPages( Mdl, KernelMode, IoWriteAccess ); - - auto Mapping = MmMapLockedPagesSpecifyCache( Mdl, KernelMode, MmCached, NULL, FALSE, NormalPagePriority ); - if ( Mapping == NULL ) - { - MmUnlockPages( Mdl ); - IoFreeMdl( Mdl ); - DBGPRINT( "[ HookSSSDT ] MmMapLockedPagesSpecifyCache failed!\n" ); - return false; - } - - // - // Modify SSSDT table - // - irql = utils::WPOFF(); - - RtlCopyMemory( Mapping, jmp_trampoline, sizeof( jmp_trampoline ) ); - - W32pServiceTable = ( ULONGLONG )( g_KeServiceDescriptorTableShadow->ServiceTableBase ); - qwTemp = W32pServiceTable + 4 * ( SyscallNum - 0x1000 ); - dwTemp = ( LONG )( ( ULONG64 )pCodeCave - W32pServiceTable ); - dwTemp = dwTemp << 4; - - *( PLONG )qwTemp = dwTemp; - - utils::WPON( irql ); - - // - // Restore protection - // - MmUnmapLockedPages( Mapping, Mdl ); - MmUnlockPages( Mdl ); - IoFreeMdl( Mdl ); - - return true; + if (!pNewFunction || !pOldFunction || SyscallNum <= 0) + return false; + + ULONGLONG W32pServiceTable = 0, qwTemp = 0; + LONG dwTemp = 0; + + // + // Log the Syscall number that we're hooking + // + DBGPRINT("[ HookSSSDT ] Syscall: 0x%X\n", SyscallNum); + + // + // Log the Original function address + // + *pOldFunction = PVOID(GetSSSDTFuncCurAddr64(SyscallNum)); + DBGPRINT("[ HookSSSDT ] Original: 0x%p\n", *pOldFunction); + + *(PULONG64)(jmp_trampoline + 3) = ULONG64(pNewFunction); + + // + // Find a suitable code cave inside the module .text section that we can use to trampoline to our hook + // + auto pCodeCave = tools::FindCodeCave(pCode, ulCodeSize, sizeof(jmp_trampoline)); + if (!pCodeCave) + { + DBGPRINT("[ HookSSSDT ] Failed to find a suitable code cave.\n"); + return false; + } + + DBGPRINT("[ HookSSSDT ] Code Cave: 0x%p\n", pCodeCave); + + // + // Change page protection + // + auto Mdl = IoAllocateMdl(pCodeCave, sizeof(jmp_trampoline), 0, 0, NULL); + if (Mdl == NULL) + { + DBGPRINT("[ HookSSSDT ] IoAllocateMdl failed!\n"); + return false; + } + + MmProbeAndLockPages(Mdl, KernelMode, IoWriteAccess); + + auto Mapping = MmMapLockedPagesSpecifyCache(Mdl, KernelMode, MmCached, NULL, FALSE, NormalPagePriority); + if (Mapping == NULL) + { + MmUnlockPages(Mdl); + IoFreeMdl(Mdl); + DBGPRINT("[ HookSSSDT ] MmMapLockedPagesSpecifyCache failed!\n"); + return false; + } + + // + // Modify SSSDT table + // + // irql = utils::WPOFF(); + + RtlCopyMemory(Mapping, jmp_trampoline, sizeof(jmp_trampoline)); + + W32pServiceTable = (ULONGLONG)(g_KeServiceDescriptorTableShadow->ServiceTableBase); + qwTemp = W32pServiceTable + 4 * (SyscallNum - 0x1000); + dwTemp = (LONG)((ULONG64)pCodeCave - W32pServiceTable); + dwTemp = dwTemp << 4; + + *(PLONG)qwTemp = dwTemp; + + // utils::WPON(irql); + + // + // Restore protection + // + MmUnmapLockedPages(Mapping, Mdl); + MmUnlockPages(Mdl); + IoFreeMdl(Mdl); + + return true; } -bool UnhookSSSDT( PVOID pFunction, ULONG SyscallNum ) +bool UnhookSSSDT(PVOID pFunction, ULONG SyscallNum) { - if ( !pFunction || SyscallNum <= 0 ) - return false; + if (!pFunction || SyscallNum <= 0) + return false; - ULONGLONG W32pServiceTable = 0, qwTemp = 0; - LONG dwTemp = 0; - KIRQL irql; + ULONGLONG W32pServiceTable = 0, qwTemp = 0; + LONG dwTemp = 0; - irql = utils::WPOFF(); + // irql = utils::WPOFF(); - W32pServiceTable = ( ULONGLONG )( g_KeServiceDescriptorTableShadow->ServiceTableBase ); - qwTemp = W32pServiceTable + 4 * ( SyscallNum - 0x1000 ); - dwTemp = ( LONG )( ( ULONG64 )pFunction - W32pServiceTable ); - dwTemp = dwTemp << 4; + W32pServiceTable = (ULONGLONG)(g_KeServiceDescriptorTableShadow->ServiceTableBase); + qwTemp = W32pServiceTable + 4 * (SyscallNum - 0x1000); + dwTemp = (LONG)((ULONG64)pFunction - W32pServiceTable); + dwTemp = dwTemp << 4; - *( PLONG )qwTemp = dwTemp; + *(PLONG)qwTemp = dwTemp; - utils::WPON( irql ); + // utils::WPON(irql); - return true; + return true; } -PSYSTEM_HANDLE_INFORMATION_EX GetSystemHandleInformation() -{ - PSYSTEM_HANDLE_INFORMATION_EX pSHInfo = NULL; - NTSTATUS Status = STATUS_NO_MEMORY; - ULONG SMInfoLen = 0x1000; - - do - { - pSHInfo = ( PSYSTEM_HANDLE_INFORMATION_EX )ExAllocatePoolWithTag( PagedPool, SMInfoLen, TAG ); - if ( !pSHInfo ) - break; - - Status = ZwQuerySystemInformation( SystemHandleInformation, pSHInfo, SMInfoLen, &SMInfoLen ); - if ( !NT_SUCCESS( Status ) ) - { - ExFreePoolWithTag( pSHInfo, TAG ); - pSHInfo = NULL; - } - } while ( Status == STATUS_INFO_LENGTH_MISMATCH ); - - return pSHInfo; -} - -HANDLE GetCsrssPid() -{ - HANDLE CsrId = ( HANDLE )0; - PSYSTEM_HANDLE_INFORMATION_EX pHandles = GetSystemHandleInformation(); - if ( pHandles ) - { - unsigned i; - for ( i = 0; i < pHandles->NumberOfHandles && !CsrId; i++ ) - { - OBJECT_ATTRIBUTES obj; CLIENT_ID cid; - HANDLE Process, hObject; - InitializeObjectAttributes( &obj, NULL, OBJ_KERNEL_HANDLE, NULL, NULL ); - cid.UniqueProcess = ( HANDLE )pHandles->Information[ i ].ProcessId; - cid.UniqueThread = 0; - - auto res = ZwOpenProcess( &Process, PROCESS_DUP_HANDLE, &obj, &cid ); - if ( NT_SUCCESS( res ) ) - { - res = ZwDuplicateObject( Process, ( PHANDLE )( pHandles->Information[ i ].Handle ), NtCurrentProcess(), &hObject, 0, FALSE, DUPLICATE_SAME_ACCESS ); - if ( NT_SUCCESS( res ) ) - { - UCHAR Buff[ 0x200 ]; - POBJECT_NAME_INFORMATION ObjName = ( POBJECT_NAME_INFORMATION )&Buff; - - res = ZwQueryObject( hObject, ObjectTypeInformation, ObjName, sizeof( Buff ), NULL ); - if ( NT_SUCCESS( res ) ) - { - if ( ObjName->Name.Buffer && ( !wcsncmp( L"Port", ObjName->Name.Buffer, 4 ) || !wcsncmp( L"ALPC Port", ObjName->Name.Buffer, 9 ) ) ) - { - res = ZwQueryObject( hObject, ( OBJECT_INFORMATION_CLASS )1, ObjName, sizeof( Buff ), NULL ); - if ( NT_SUCCESS( res ) ) - { - if ( ObjName->Name.Buffer && !wcsncmp( L"\\Windows\\ApiPort", ObjName->Name.Buffer, 20 ) ) - CsrId = ( HANDLE )pHandles->Information[ i ].ProcessId; - } - } - } - else - DBGPRINT( "[ GetCsr ] ZwQueryObject failed 0x%X\n", res ); - - ZwClose( hObject ); - } - else if ( res != STATUS_NOT_SUPPORTED ) - DBGPRINT( "[ GetCsr ] ZwDuplicateObject failed 0x%X\n", res ); - - ZwClose( Process ); - } - else - DBGPRINT( "[ GetCsr ] NtOpenProcess failed 0x%X\n", res ); - } - ExFreePoolWithTag( pHandles, TAG ); - } - return CsrId; -} - -void sssdt::Init() +bool sssdt::Init() { #ifndef USE_KASPERSKY - g_KeServiceDescriptorTableShadow = PSYSTEM_SERVICE_TABLE( GetKeServiceDescriptorTableShadow64() + sizeof( SYSTEM_SERVICE_TABLE ) ); - DBGPRINT( "KeServiceDescriptorTableShadow: 0x%p\n", g_KeServiceDescriptorTableShadow ); - - if ( !g_KeServiceDescriptorTableShadow ) - return; - - auto W32pServiceTable = PULONG( g_KeServiceDescriptorTableShadow->ServiceTableBase ); - DBGPRINT( "KeServiceDescriptorTableShadow->ServiceTableBase: 0x%p\n", W32pServiceTable ); - - if ( !W32pServiceTable ) - return; - - DBGPRINT( "KeServiceDescriptorTableShadow->NumberOfServices: %lld\n", g_KeServiceDescriptorTableShadow->NumberOfServices ); - - auto Csrss = GetCsrssPid(); - - PEPROCESS Process = nullptr; - auto res = PsLookupProcessByProcessId( Csrss, &Process ); - if ( !NT_SUCCESS( res ) ) - { - DBGPRINT( "[ ShadowSSDT ] PsLookupProcessByProcessId failed 0x%X\n", res ); - return; - } - - // - // Save csrss.exe PID for later - // - hCsrssPID = Csrss; - - KAPC_STATE apc{ }; - KeStackAttachProcess( Process, &apc ); - - auto win32k = ULONG64( tools::GetModuleBase( "\\SystemRoot\\System32\\win32k.sys" ) ); - DBGPRINT( "win32k: 0x%llx\n", win32k ); - if ( !win32k ) - return; - - ULONG ulCodeSize = 0; - auto pCode = PUCHAR( tools::GetImageTextSection( win32k, &ulCodeSize ) ); - if ( pCode ) - { - DBGPRINT( "win32k.sys .text section 0x%p\n", pCode ); - - if ( HookSSSDT( pCode, ulCodeSize, &hkNtUserQueryWindow, reinterpret_cast< PVOID* >( &oNtUserQueryWindow ), SYSCALL_NTUSERQUERYWND ) ) - { - DBGPRINT( "NtUserQueryWindow hooked successfully!\n" ); - } - else - DBGPRINT( "Failed to hook NtUserQueryWindow!\n" ); - - if ( HookSSSDT( pCode, ulCodeSize, &hkNtUserFindWindowEx, reinterpret_cast< PVOID* >( &oNtUserFindWindowEx ), SYSCALL_NTUSERFINDWNDEX ) ) - { - DBGPRINT( "NtUserFindWindowEx hooked successfully!\n" ); - } - else - DBGPRINT( "Failed to hook NtUserFindWindowEx!\n" ); - - if ( HookSSSDT( pCode, ulCodeSize, &hkNtUserWindowFromPoint, reinterpret_cast< PVOID* >( &oNtUserWindowFromPoint ), SYSCALL_NTUSERWNDFROMPOINT ) ) - { - DBGPRINT( "NtUserWindowFromPoint hooked successfully!\n" ); - } - else - DBGPRINT( "Failed to hook NtUserWindowFromPoint!\n" ); - - if ( HookSSSDT( pCode, ulCodeSize, &hkNtUserBuildHwndList, reinterpret_cast< PVOID* >( &oNtUserBuildHwndList ), SYSCALL_NTUSERBUILDWNDLIST ) ) - { - DBGPRINT( "NtUserBuildHwndList hooked successfully!\n" ); - } - else - DBGPRINT( "Failed to hook NtUserBuildHwndList!\n" ); - - if ( HookSSSDT( pCode, ulCodeSize, &hkNtUserGetForegroundWindow, reinterpret_cast< PVOID* >( &oNtUserGetForegroundWindow ), SYSCALL_NTGETFOREGROUNDWND ) ) - { - DBGPRINT( "NtUserGetForegroundWindow hooked successfully!\n" ); - } - else - DBGPRINT( "Failed to hook NtUserGetForegroundWindow!\n" ); - } - - KeUnstackDetachProcess( &apc ); - ObDereferenceObject( Process ); + g_KeServiceDescriptorTableShadow = + PSYSTEM_SERVICE_TABLE(GetKeServiceDescriptorTableShadow64() + sizeof(SYSTEM_SERVICE_TABLE)); + DBGPRINT("KeServiceDescriptorTableShadow: 0x%p\n", g_KeServiceDescriptorTableShadow); + + if (!g_KeServiceDescriptorTableShadow) + return; + + auto W32pServiceTable = PULONG(g_KeServiceDescriptorTableShadow->ServiceTableBase); + DBGPRINT("KeServiceDescriptorTableShadow->ServiceTableBase: 0x%p\n", W32pServiceTable); + + if (!W32pServiceTable) + return; + + DBGPRINT("KeServiceDescriptorTableShadow->NumberOfServices: %lld\n", + g_KeServiceDescriptorTableShadow->NumberOfServices); + + auto Csrss = GetCsrssPid(); + + PEPROCESS Process = nullptr; + auto res = PsLookupProcessByProcessId(Csrss, &Process); + if (!NT_SUCCESS(res)) + { + DBGPRINT("[ ShadowSSDT ] PsLookupProcessByProcessId failed 0x%X\n", res); + return; + } + + // + // Save csrss.exe PID for later + // + hCsrssPID = Csrss; + + KAPC_STATE apc{}; + KeStackAttachProcess(Process, &apc); + + auto win32k = ULONG64(tools::GetModuleBase("\\SystemRoot\\System32\\win32k.sys")); + DBGPRINT("win32k: 0x%llx\n", win32k); + if (!win32k) + return; + + ULONG ulCodeSize = 0; + auto pCode = PUCHAR(tools::GetImageTextSection(win32k, &ulCodeSize)); + if (pCode) + { + DBGPRINT("win32k.sys .text section 0x%p\n", pCode); + + if (HookSSSDT(pCode, ulCodeSize, &hkNtUserQueryWindow, reinterpret_cast(&oNtUserQueryWindow), + SYSCALL_NTUSERQUERYWND)) + { + DBGPRINT("NtUserQueryWindow hooked successfully!\n"); + } + else + DBGPRINT("Failed to hook NtUserQueryWindow!\n"); + + if (HookSSSDT(pCode, ulCodeSize, &hkNtUserFindWindowEx, reinterpret_cast(&oNtUserFindWindowEx), + SYSCALL_NTUSERFINDWNDEX)) + { + DBGPRINT("NtUserFindWindowEx hooked successfully!\n"); + } + else + DBGPRINT("Failed to hook NtUserFindWindowEx!\n"); + + if (HookSSSDT(pCode, ulCodeSize, &hkNtUserWindowFromPoint, reinterpret_cast(&oNtUserWindowFromPoint), + SYSCALL_NTUSERWNDFROMPOINT)) + { + DBGPRINT("NtUserWindowFromPoint hooked successfully!\n"); + } + else + DBGPRINT("Failed to hook NtUserWindowFromPoint!\n"); + + if (HookSSSDT(pCode, ulCodeSize, &hkNtUserBuildHwndList, reinterpret_cast(&oNtUserBuildHwndList), + SYSCALL_NTUSERBUILDWNDLIST)) + { + DBGPRINT("NtUserBuildHwndList hooked successfully!\n"); + } + else + DBGPRINT("Failed to hook NtUserBuildHwndList!\n"); + + if (HookSSSDT(pCode, ulCodeSize, &hkNtUserGetForegroundWindow, + reinterpret_cast(&oNtUserGetForegroundWindow), SYSCALL_NTGETFOREGROUNDWND)) + { + DBGPRINT("NtUserGetForegroundWindow hooked successfully!\n"); + } + else + DBGPRINT("Failed to hook NtUserGetForegroundWindow!\n"); + } + + KeUnstackDetachProcess(&apc); + ObDereferenceObject(Process); #else - - if ( kaspersky::hook_shadow_ssdt_routine( SYSCALL_NTUSERQUERYWND, hkNtUserQueryWindow, reinterpret_cast< PVOID* >( &oNtUserQueryWindow ) ) ) - { - DBGPRINT( "NtUserQueryWindow ( 0x%X ) hooked successfully!\n", SYSCALL_NTUSERQUERYWND ); - } - else - DBGPRINT( "Failed to hook NtUserQueryWindow!\n" ); - - if ( kaspersky::hook_shadow_ssdt_routine( SYSCALL_NTUSERFINDWNDEX, hkNtUserFindWindowEx, reinterpret_cast< PVOID* >( &oNtUserFindWindowEx ) ) ) - { - DBGPRINT( "NtUserFindWindowEx ( 0x%X ) hooked successfully!\n", SYSCALL_NTUSERFINDWNDEX ); - } - else - DBGPRINT( "Failed to hook NtUserFindWindowEx!\n" ); - - if ( kaspersky::hook_shadow_ssdt_routine( SYSCALL_NTUSERWNDFROMPOINT, hkNtUserWindowFromPoint, reinterpret_cast< PVOID* >( &oNtUserWindowFromPoint ) ) ) - { - DBGPRINT( "NtUserWindowFromPoint ( 0x%X ) hooked successfully!\n", SYSCALL_NTUSERWNDFROMPOINT ); - } - else - DBGPRINT( "Failed to hook NtUserWindowFromPoint!\n" ); - - if ( kaspersky::hook_shadow_ssdt_routine( SYSCALL_NTUSERBUILDWNDLIST, hkNtUserBuildHwndList, reinterpret_cast< PVOID* >( &oNtUserBuildHwndList ) ) ) - { - DBGPRINT( "NtUserBuildHwndList ( 0x%X ) hooked successfully!\n", SYSCALL_NTUSERBUILDWNDLIST ); - } - else - DBGPRINT( "Failed to hook NtUserBuildHwndList!\n" ); - - if ( kaspersky::hook_shadow_ssdt_routine( SYSCALL_NTGETFOREGROUNDWND, hkNtUserGetForegroundWindow, reinterpret_cast< PVOID* >( &oNtUserGetForegroundWindow ) ) ) - { - DBGPRINT( "NtUserGetForegroundWindow ( 0x%X ) hooked successfully!\n", SYSCALL_NTGETFOREGROUNDWND ); - } - else - DBGPRINT( "Failed to hook NtUserGetForegroundWindow!\n" ); +#define KASPERSKY_HOOK_ROUTINE(name) \ + if (!kaspersky::hook_shadow_ssdt_routine(syscalls::GetSyscallIndexByName(#name) + 0x1000, hooks::hk##name, \ + reinterpret_cast(&hooks::o##name))) \ + { \ + DBGPRINT("Failed to hook " #name); \ + return false; \ + } \ + else \ + { \ + DBGPRINT(#name " hooked successfully!"); \ + } + + hooks::NtUserGetThreadState = reinterpret_cast( + kaspersky::get_shadow_ssdt_routine(syscalls::GetSyscallIndexByName("NtUserGetThreadState") + 0x1000)); + + if (!hooks::NtUserGetThreadState) + { + DBGPRINT("NtUserGetThreadState not found!"); + return false; + } + + KASPERSKY_HOOK_ROUTINE(NtUserQueryWindow); + KASPERSKY_HOOK_ROUTINE(NtUserFindWindowEx); + KASPERSKY_HOOK_ROUTINE(NtUserWindowFromPoint); + KASPERSKY_HOOK_ROUTINE(NtUserBuildHwndList); + KASPERSKY_HOOK_ROUTINE(NtUserGetForegroundWindow); + + // NtUserGetThreadState + +#undef KASPERSKY_HOOK_ROUTINE #endif + return true; } void sssdt::Destroy() { #ifndef USE_KASPERSKY - if ( !g_KeServiceDescriptorTableShadow ) - return; + if (!g_KeServiceDescriptorTableShadow) + return; - PEPROCESS Process = nullptr; - auto res = PsLookupProcessByProcessId( hCsrssPID, &Process ); - if ( !NT_SUCCESS( res ) ) - { - DBGPRINT( "[ DestroyShadowSSDT ] PsLookupProcessByProcessId failed 0x%X\n", res ); - return; - } + PEPROCESS Process = nullptr; + auto res = PsLookupProcessByProcessId(hCsrssPID, &Process); + if (!NT_SUCCESS(res)) + { + DBGPRINT("[ DestroyShadowSSDT ] PsLookupProcessByProcessId failed 0x%X\n", res); + return; + } - KAPC_STATE apc{ }; - KeStackAttachProcess( Process, &apc ); + KAPC_STATE apc{}; + KeStackAttachProcess(Process, &apc); - if ( !UnhookSSSDT( oNtUserFindWindowEx, SYSCALL_NTUSERFINDWNDEX ) ) - DBGPRINT( "Failed to unhook NtUserFindWindowEx!\n" ); + if (!UnhookSSSDT(oNtUserFindWindowEx, SYSCALL_NTUSERFINDWNDEX)) + DBGPRINT("Failed to unhook NtUserFindWindowEx!\n"); - if ( !UnhookSSSDT( oNtUserWindowFromPoint, SYSCALL_NTUSERWNDFROMPOINT ) ) - DBGPRINT( "Failed to unhook NtUserWindowFromPoint!\n" ); + if (!UnhookSSSDT(oNtUserWindowFromPoint, SYSCALL_NTUSERWNDFROMPOINT)) + DBGPRINT("Failed to unhook NtUserWindowFromPoint!\n"); - if ( !UnhookSSSDT( oNtUserBuildHwndList, SYSCALL_NTUSERBUILDWNDLIST ) ) - DBGPRINT( "Failed to unhook NtUserBuildHwndList!\n" ); + if (!UnhookSSSDT(oNtUserBuildHwndList, SYSCALL_NTUSERBUILDWNDLIST)) + DBGPRINT("Failed to unhook NtUserBuildHwndList!\n"); - if ( !UnhookSSSDT( oNtUserGetForegroundWindow, SYSCALL_NTGETFOREGROUNDWND ) ) - DBGPRINT( "Failed to unhook NtUserGetForegroundWindow!\n" ); + if (!UnhookSSSDT(oNtUserGetForegroundWindow, SYSCALL_NTGETFOREGROUNDWND)) + DBGPRINT("Failed to unhook NtUserGetForegroundWindow!\n"); - if ( !UnhookSSSDT( oNtUserQueryWindow, SYSCALL_NTUSERQUERYWND ) ) - DBGPRINT( "Failed to unhook NtUserQueryWindow!\n" ); + if (!UnhookSSSDT(oNtUserQueryWindow, SYSCALL_NTUSERQUERYWND)) + DBGPRINT("Failed to unhook NtUserQueryWindow!\n"); - KeUnstackDetachProcess( &apc ); - ObDereferenceObject( Process ); + KeUnstackDetachProcess(&apc); + ObDereferenceObject(Process); #else - if ( !kaspersky::is_klhk_loaded() ) - return; - - if ( !kaspersky::unhook_shadow_ssdt_routine( SYSCALL_NTUSERBUILDWNDLIST, oNtUserBuildHwndList ) ) - DBGPRINT( "Failed to unhook NtUserBuildHwndList" ); - - if ( !kaspersky::unhook_shadow_ssdt_routine( SYSCALL_NTUSERWNDFROMPOINT, oNtUserWindowFromPoint ) ) - DBGPRINT( "Failed to unhook NtUserWindowFromPoint" ); - - if ( !kaspersky::unhook_shadow_ssdt_routine( SYSCALL_NTUSERFINDWNDEX, oNtUserFindWindowEx ) ) - DBGPRINT( "Failed to unhook NtUserFindWindowEx" ); - - if ( !kaspersky::unhook_shadow_ssdt_routine( SYSCALL_NTGETFOREGROUNDWND, oNtUserGetForegroundWindow ) ) - DBGPRINT( "Failed to unhook NtUserGetForegroundWindow" ); - - if ( !kaspersky::unhook_shadow_ssdt_routine( SYSCALL_NTUSERQUERYWND, oNtUserQueryWindow ) ) - DBGPRINT( "Failed to unhook NtUserQueryWindow" ); + if (!kaspersky::is_klhk_loaded()) + return; + +#define KASPERSKY_UNHOOK_ROUTINE(name) \ + if (!kaspersky::unhook_shadow_ssdt_routine(syscalls::GetSyscallIndexByName(#name) + 0x1000, hooks::o##name)) \ + { \ + DBGPRINT("Failed to unhook " #name); \ + } \ + else \ + { \ + DBGPRINT(#name " unhooked successfully!"); \ + } + + KASPERSKY_UNHOOK_ROUTINE(NtUserQueryWindow); + KASPERSKY_UNHOOK_ROUTINE(NtUserFindWindowEx); + KASPERSKY_UNHOOK_ROUTINE(NtUserWindowFromPoint); + KASPERSKY_UNHOOK_ROUTINE(NtUserBuildHwndList); + KASPERSKY_UNHOOK_ROUTINE(NtUserGetForegroundWindow); #endif } \ No newline at end of file diff --git a/MasterHide/shadow_ssdt.h b/MasterHide/shadow_ssdt.h deleted file mode 100644 index 5ee8161..0000000 --- a/MasterHide/shadow_ssdt.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -namespace masterhide -{ - namespace sssdt - { - extern void Init(); - extern void Destroy(); - } -}; diff --git a/MasterHide/shadow_ssdt.hpp b/MasterHide/shadow_ssdt.hpp new file mode 100644 index 0000000..7597e3b --- /dev/null +++ b/MasterHide/shadow_ssdt.hpp @@ -0,0 +1,10 @@ +#pragma once + +namespace masterhide +{ +namespace sssdt +{ +extern bool Init(); +extern void Destroy(); +} // namespace sssdt +}; // namespace masterhide diff --git a/MasterHide/ssdt.cpp b/MasterHide/ssdt.cpp index 7851c85..72f849a 100644 --- a/MasterHide/ssdt.cpp +++ b/MasterHide/ssdt.cpp @@ -1,306 +1,285 @@ -#include "stdafx.h" +#include "includes.hpp" PSYSTEM_SERVICE_TABLE g_KeServiceDescriptorTable = NULL; ULONGLONG GetKeServiceDescriptorTable64() { - PUCHAR pStartSearchAddress = ( PUCHAR )__readmsr( 0xC0000082 ); - PUCHAR pEndSearchAddress = ( PUCHAR )( ( ( ULONG_PTR )pStartSearchAddress + PAGE_SIZE ) & ( ~0x0FFF ) ); - PULONG pFindCodeAddress = NULL; - - while ( ++pStartSearchAddress < pEndSearchAddress ) - { - if ( ( *( PULONG )pStartSearchAddress & 0xFFFFFF00 ) == 0x83f70000 ) - { - pFindCodeAddress = ( PULONG )( pStartSearchAddress - 12 ); - return ( ULONG_PTR )pFindCodeAddress + ( ( ( *( PULONG )pFindCodeAddress ) >> 24 ) + 7 ) + ( ULONG_PTR )( ( ( *( PULONG )( pFindCodeAddress + 1 ) ) & 0x0FFFF ) << 8 ); - } - } - return 0; + PUCHAR pStartSearchAddress = (PUCHAR)__readmsr(0xC0000082); + PUCHAR pEndSearchAddress = (PUCHAR)(((ULONG_PTR)pStartSearchAddress + PAGE_SIZE) & (~0x0FFF)); + PULONG pFindCodeAddress = NULL; + + while (++pStartSearchAddress < pEndSearchAddress) + { + if ((*(PULONG)pStartSearchAddress & 0xFFFFFF00) == 0x83f70000) + { + pFindCodeAddress = (PULONG)(pStartSearchAddress - 12); + return (ULONG_PTR)pFindCodeAddress + (((*(PULONG)pFindCodeAddress) >> 24) + 7) + + (ULONG_PTR)(((*(PULONG)(pFindCodeAddress + 1)) & 0x0FFFF) << 8); + } + } + return 0; } -ULONGLONG GetSSDTFuncCurAddr64( ULONG id ) +ULONGLONG GetSSDTFuncCurAddr64(ULONG id) { - LONG dwtmp = 0; - PULONG ServiceTableBase = NULL; - ServiceTableBase = ( PULONG )g_KeServiceDescriptorTable->ServiceTableBase; - dwtmp = ServiceTableBase[ id ]; - dwtmp = dwtmp >> 4; - return ( LONGLONG )dwtmp + ( ULONGLONG )ServiceTableBase; + LONG dwtmp = 0; + PULONG ServiceTableBase = NULL; + ServiceTableBase = (PULONG)g_KeServiceDescriptorTable->ServiceTableBase; + dwtmp = ServiceTableBase[id]; + dwtmp = dwtmp >> 4; + return (LONGLONG)dwtmp + (ULONGLONG)ServiceTableBase; } -ULONG GetOffsetAddress( ULONGLONG FuncAddr ) +ULONG GetOffsetAddress(ULONGLONG FuncAddr) { - ULONG dwtmp = 0; - PULONG ServiceTableBase = NULL; - ServiceTableBase = ( PULONG )g_KeServiceDescriptorTable->ServiceTableBase; - dwtmp = ( ULONG )( FuncAddr - ( ULONGLONG )ServiceTableBase ); - dwtmp = dwtmp << 4; - return dwtmp; + ULONG dwtmp = 0; + PULONG ServiceTableBase = NULL; + ServiceTableBase = (PULONG)g_KeServiceDescriptorTable->ServiceTableBase; + dwtmp = (ULONG)(FuncAddr - (ULONGLONG)ServiceTableBase); + dwtmp = dwtmp << 4; + return dwtmp; } -bool HookSSDT( PUCHAR pCode, ULONG ulCodeSize, PVOID pNewFunction, PVOID* pOldFunction, ULONG SyscallNum ) +bool HookSSDT(PUCHAR pCode, ULONG ulCodeSize, PVOID pNewFunction, PVOID *pOldFunction, ULONG SyscallNum) { - if ( !pNewFunction || !pOldFunction || SyscallNum <= 0 ) - return false; - - // - // Log the Syscall number that we're hooking - // - DBGPRINT( "[ HookSSDT ] Syscall: 0x%X\n", SyscallNum ); - - // - // Log the Original function address - // - *pOldFunction = PVOID( GetSSDTFuncCurAddr64( SyscallNum ) ); - DBGPRINT( "[ HookSSDT ] Original: 0x%p\n", *pOldFunction ); - - *( PULONG64 )( jmp_trampoline + 3 ) = ULONG64( pNewFunction ); - - // - // Find a suitable code cave inside the module .text section that we can use to trampoline to our hook - // - auto pCodeCave = utils::FindCodeCave( pCode, ulCodeSize, sizeof( jmp_trampoline ) ); - if ( !pCodeCave ) - { - DBGPRINT( "[ HookSSDT ] Failed to find a suitable code cave.\n" ); - return false; - } - - DBGPRINT( "[ HookSSDT ] Code Cave: 0x%p\n", pCodeCave ); - - // - // Change page protection - // - auto Mdl = IoAllocateMdl( pCodeCave, sizeof( jmp_trampoline ), 0, 0, NULL ); - if ( Mdl == NULL ) - { - DBGPRINT( "[ HookSSDT ] IoAllocateMdl failed!\n" ); - return false; - } - - MmProbeAndLockPages( Mdl, KernelMode, IoWriteAccess ); - - auto Mapping = MmMapLockedPagesSpecifyCache( Mdl, KernelMode, MmCached, NULL, FALSE, NormalPagePriority ); - if ( Mapping == NULL ) - { - MmUnlockPages( Mdl ); - IoFreeMdl( Mdl ); - DBGPRINT( "[ HookSSDT ] MmMapLockedPagesSpecifyCache failed!\n" ); - return false; - } - - // - // Modify SSDT table - // - auto ServiceTableBase = ( PULONG )g_KeServiceDescriptorTable->ServiceTableBase; - - auto irql = utils::WPOFF(); - - RtlCopyMemory( Mapping, jmp_trampoline, sizeof( jmp_trampoline ) ); - - auto SsdtEntry = GetOffsetAddress( ULONG64( pCodeCave ) ); - SsdtEntry &= 0xFFFFFFF0; - SsdtEntry += ServiceTableBase[ SyscallNum ] & 0x0F; - ServiceTableBase[ SyscallNum ] = SsdtEntry; - - utils::WPON( irql ); - - // - // Restore protection - // - MmUnmapLockedPages( Mapping, Mdl ); - MmUnlockPages( Mdl ); - IoFreeMdl( Mdl ); - - return true; + if (!pNewFunction || !pOldFunction || SyscallNum <= 0) + return false; + + // + // Log the Syscall number that we're hooking + // + DBGPRINT("[ HookSSDT ] Syscall: 0x%X\n", SyscallNum); + + // + // Log the Original function address + // + *pOldFunction = PVOID(GetSSDTFuncCurAddr64(SyscallNum)); + DBGPRINT("[ HookSSDT ] Original: 0x%p\n", *pOldFunction); + + *(PULONG64)(jmp_trampoline + 3) = ULONG64(pNewFunction); + + // + // Find a suitable code cave inside the module .text section that we can use to trampoline to our hook + // + auto pCodeCave = tools::FindCodeCave(pCode, ulCodeSize, sizeof(jmp_trampoline)); + if (!pCodeCave) + { + DBGPRINT("[ HookSSDT ] Failed to find a suitable code cave.\n"); + return false; + } + + DBGPRINT("[ HookSSDT ] Code Cave: 0x%p\n", pCodeCave); + + // + // Change page protection + // + auto Mdl = IoAllocateMdl(pCodeCave, sizeof(jmp_trampoline), 0, 0, NULL); + if (Mdl == NULL) + { + DBGPRINT("[ HookSSDT ] IoAllocateMdl failed!\n"); + return false; + } + + MmProbeAndLockPages(Mdl, KernelMode, IoWriteAccess); + + auto Mapping = MmMapLockedPagesSpecifyCache(Mdl, KernelMode, MmCached, NULL, FALSE, NormalPagePriority); + if (Mapping == NULL) + { + MmUnlockPages(Mdl); + IoFreeMdl(Mdl); + DBGPRINT("[ HookSSDT ] MmMapLockedPagesSpecifyCache failed!\n"); + return false; + } + + // + // Modify SSDT table + // + auto ServiceTableBase = (PULONG)g_KeServiceDescriptorTable->ServiceTableBase; + + // auto irql = utils::WPOFF(); + + RtlCopyMemory(Mapping, jmp_trampoline, sizeof(jmp_trampoline)); + + auto SsdtEntry = GetOffsetAddress(ULONG64(pCodeCave)); + SsdtEntry &= 0xFFFFFFF0; + SsdtEntry += ServiceTableBase[SyscallNum] & 0x0F; + ServiceTableBase[SyscallNum] = SsdtEntry; + + // utils::WPON(irql); + + // + // Restore protection + // + MmUnmapLockedPages(Mapping, Mdl); + MmUnlockPages(Mdl); + IoFreeMdl(Mdl); + + return true; } -bool UnhookSSDT( PVOID pFunction, ULONG SyscallNum ) +bool UnhookSSDT(PVOID pFunction, ULONG SyscallNum) { - if ( !pFunction || SyscallNum <= 0 ) - return false; + if (!pFunction || SyscallNum <= 0) + return false; - auto ServiceTableBase = ( PULONG )g_KeServiceDescriptorTable->ServiceTableBase; + auto ServiceTableBase = (PULONG)g_KeServiceDescriptorTable->ServiceTableBase; - auto irql = utils::WPOFF(); + // auto irql = utils::WPOFF(); - auto SsdtEntry = GetOffsetAddress( ULONG64( pFunction ) ); - SsdtEntry &= 0xFFFFFFF0; - SsdtEntry += ServiceTableBase[ SyscallNum ] & 0x0F; - ServiceTableBase[ SyscallNum ] = SsdtEntry; + auto SsdtEntry = GetOffsetAddress(ULONG64(pFunction)); + SsdtEntry &= 0xFFFFFFF0; + SsdtEntry += ServiceTableBase[SyscallNum] & 0x0F; + ServiceTableBase[SyscallNum] = SsdtEntry; - utils::WPON( irql ); + // utils::WPON(irql); - return true; + return true; } -void ssdt::Init() +bool ssdt::Init() { #ifndef USE_KASPERSKY - g_KeServiceDescriptorTable = PSYSTEM_SERVICE_TABLE( GetKeServiceDescriptorTable64() ); - DBGPRINT( "KeServiceDescriptorTable: 0x%p\n", g_KeServiceDescriptorTable ); - if ( !g_KeServiceDescriptorTable ) - return; - - auto KiServiceTable = PULONG( g_KeServiceDescriptorTable->ServiceTableBase ); - DBGPRINT( "KeServiceDescriptorTable->ServiceTableBase: 0x%p\n", KiServiceTable ); - if ( !KiServiceTable ) - return; - - DBGPRINT( "KeServiceDescriptorTable->NumberOfServices: %lld\n", g_KeServiceDescriptorTable->NumberOfServices ); - - auto ntoskrnl = ULONG64( tools::GetNtKernelBase() ); - DBGPRINT( "ntoskrnl: 0x%llx\n", ntoskrnl ); - if ( !ntoskrnl ) - return; - - ULONG ulCodeSize = 0; - auto pCode = PUCHAR( tools::GetImageTextSection( ntoskrnl, &ulCodeSize ) ); - if ( pCode ) - { - DBGPRINT( "ntoskrnl.exe .text section %p\n", pCode ); - - if ( HookSSDT( pCode, ulCodeSize, &hkNtQuerySystemInformation, reinterpret_cast< PVOID* >( &oNtQuerySystemInformation ), SYSCALL_NTQUERYSYSINFO ) ) - { - DBGPRINT( "NtQuerySystemInformation hooked successfully!\n" ); - } - else - DBGPRINT( "Failed to hook NtQuerySystemInformation!\n" ); - - if ( HookSSDT( pCode, ulCodeSize, &hkNtOpenProcess, reinterpret_cast< PVOID* >( &oNtOpenProcess ), SYSCALL_NTOPENPROCESS ) ) - { - DBGPRINT( "NtOpenProcess hooked successfully!\n" ); - } - else - DBGPRINT( "Failed to hook NtOpenProcess!\n" ); - - if ( HookSSDT( pCode, ulCodeSize, &hkNtAllocateVirtualMemory, reinterpret_cast< PVOID* >( &oNtAllocateVirtualMemory ), SYSCALL_NTALLOCVIRTUALMEM ) ) - { - DBGPRINT( "NtAllocateVirtualMemory hooked successfully!\n" ); - } - else - DBGPRINT( "Failed to hook NtAllocateVirtualMemory!\n" ); - - if ( HookSSDT( pCode, ulCodeSize, &hkNtFreeVirtualMemory, reinterpret_cast< PVOID* >( &oNtFreeVirtualMemory ), SYSCALL_NTFREEVIRTUALMEM ) ) - { - DBGPRINT( "NtFreeVirtualMemory hooked successfully!\n" ); - } - else - DBGPRINT( "Failed to hook NtFreeVirtualMemory!\n" ); - - if ( HookSSDT( pCode, ulCodeSize, &hkNtWriteVirtualMemory, reinterpret_cast< PVOID* >( &oNtWriteVirtualMemory ), SYSCALL_NTWRITEVIRTUALMEM ) ) - { - DBGPRINT( "NtWriteVirtualMemory hooked successfully!\n" ); - } - else - DBGPRINT( "Failed to hook NtWriteVirtualMemory!\n" ); - - if ( HookSSDT( pCode, ulCodeSize, &hkNtDeviceIoControlFile, reinterpret_cast< PVOID* >( &oNtDeviceIoControlFile ), SYSCALL_NTDEVICEIOCTRLFILE ) ) - { - DBGPRINT( "NtDeviceIoControlFile hooked successfully!\n" ); - } - else - DBGPRINT( "Failed to hook NtDeviceIoControlFile!\n" ); - } + g_KeServiceDescriptorTable = PSYSTEM_SERVICE_TABLE(GetKeServiceDescriptorTable64()); + DBGPRINT("KeServiceDescriptorTable: 0x%p\n", g_KeServiceDescriptorTable); + if (!g_KeServiceDescriptorTable) + return; + + auto KiServiceTable = PULONG(g_KeServiceDescriptorTable->ServiceTableBase); + DBGPRINT("KeServiceDescriptorTable->ServiceTableBase: 0x%p\n", KiServiceTable); + if (!KiServiceTable) + return; + + DBGPRINT("KeServiceDescriptorTable->NumberOfServices: %lld\n", g_KeServiceDescriptorTable->NumberOfServices); + + auto ntoskrnl = ULONG64(tools::GetNtKernelBase()); + DBGPRINT("ntoskrnl: 0x%llx\n", ntoskrnl); + if (!ntoskrnl) + return; + + ULONG ulCodeSize = 0; + auto pCode = PUCHAR(tools::GetImageTextSection(ntoskrnl, &ulCodeSize)); + if (pCode) + { + DBGPRINT("ntoskrnl.exe .text section %p\n", pCode); + + if (HookSSDT(pCode, ulCodeSize, &hkNtQuerySystemInformation, + reinterpret_cast(&oNtQuerySystemInformation), SYSCALL_NTQUERYSYSINFO)) + { + DBGPRINT("NtQuerySystemInformation hooked successfully!\n"); + } + else + DBGPRINT("Failed to hook NtQuerySystemInformation!\n"); + + if (HookSSDT(pCode, ulCodeSize, &hkNtOpenProcess, reinterpret_cast(&oNtOpenProcess), + SYSCALL_NTOPENPROCESS)) + { + DBGPRINT("NtOpenProcess hooked successfully!\n"); + } + else + DBGPRINT("Failed to hook NtOpenProcess!\n"); + + if (HookSSDT(pCode, ulCodeSize, &hkNtAllocateVirtualMemory, + reinterpret_cast(&oNtAllocateVirtualMemory), SYSCALL_NTALLOCVIRTUALMEM)) + { + DBGPRINT("NtAllocateVirtualMemory hooked successfully!\n"); + } + else + DBGPRINT("Failed to hook NtAllocateVirtualMemory!\n"); + + if (HookSSDT(pCode, ulCodeSize, &hkNtFreeVirtualMemory, reinterpret_cast(&oNtFreeVirtualMemory), + SYSCALL_NTFREEVIRTUALMEM)) + { + DBGPRINT("NtFreeVirtualMemory hooked successfully!\n"); + } + else + DBGPRINT("Failed to hook NtFreeVirtualMemory!\n"); + + if (HookSSDT(pCode, ulCodeSize, &hkNtWriteVirtualMemory, reinterpret_cast(&oNtWriteVirtualMemory), + SYSCALL_NTWRITEVIRTUALMEM)) + { + DBGPRINT("NtWriteVirtualMemory hooked successfully!\n"); + } + else + DBGPRINT("Failed to hook NtWriteVirtualMemory!\n"); + + if (HookSSDT(pCode, ulCodeSize, &hkNtDeviceIoControlFile, reinterpret_cast(&oNtDeviceIoControlFile), + SYSCALL_NTDEVICEIOCTRLFILE)) + { + DBGPRINT("NtDeviceIoControlFile hooked successfully!\n"); + } + else + DBGPRINT("Failed to hook NtDeviceIoControlFile!\n"); + } #else - if ( kaspersky::hook_ssdt_routine( SYSCALL_NTOPENPROCESS, hkNtOpenProcess, reinterpret_cast< PVOID* >( &oNtOpenProcess ) ) ) - { - DBGPRINT( "NtOpenProcess ( 0x%X ) hooked successfully!\n", SYSCALL_NTOPENPROCESS ); -} - else - DBGPRINT( "Failed to hook NtOpenProcess!\n" ); - - if ( kaspersky::hook_ssdt_routine( SYSCALL_NTDEVICEIOCTRLFILE, hkNtDeviceIoControlFile, reinterpret_cast< PVOID* >( &oNtDeviceIoControlFile ) ) ) - { - DBGPRINT( "NtDeviceIoControlFile ( 0x%X ) hooked successfully!\n", SYSCALL_NTDEVICEIOCTRLFILE ); - } - else - DBGPRINT( "Failed to hook NtDeviceIoControlFile!\n" ); - - if ( kaspersky::hook_ssdt_routine( SYSCALL_NTQUERYSYSINFO, hkNtQuerySystemInformation, reinterpret_cast< PVOID* >( &oNtQuerySystemInformation ) ) ) - { - DBGPRINT( "NtQuerySystemInformation ( 0x%X ) hooked successfully!\n", SYSCALL_NTQUERYSYSINFO ); - } - else - DBGPRINT( "Failed to hook NtQuerySystemInformation!\n" ); - - if ( kaspersky::hook_ssdt_routine( SYSCALL_NTALLOCVIRTUALMEM, hkNtAllocateVirtualMemory, reinterpret_cast< PVOID* >( &oNtAllocateVirtualMemory ) ) ) - { - DBGPRINT( "NtAllocateVirtualMemory ( 0x%X ) hooked successfully!\n", SYSCALL_NTALLOCVIRTUALMEM ); - } - else - DBGPRINT( "Failed to hook NtAllocateVirtualMemory!\n" ); - - if ( kaspersky::hook_ssdt_routine( SYSCALL_NTFREEVIRTUALMEM, hkNtFreeVirtualMemory, reinterpret_cast< PVOID* >( &oNtFreeVirtualMemory ) ) ) - { - DBGPRINT( "NtFreeVirtualMemory ( 0x%X ) hooked successfully!\n", SYSCALL_NTFREEVIRTUALMEM ); - } - else - DBGPRINT( "Failed to hook NtFreeVirtualMemory!\n" ); - - if ( kaspersky::hook_ssdt_routine( SYSCALL_NTWRITEVIRTUALMEM, hkNtWriteVirtualMemory, reinterpret_cast< PVOID* >( &oNtWriteVirtualMemory ) ) ) - { - DBGPRINT( "NtWriteVirtualMemory ( 0x%X ) hooked successfully!\n", SYSCALL_NTWRITEVIRTUALMEM ); - } - else - DBGPRINT( "Failed to hook NtWriteVirtualMemory!\n" ); - - if ( kaspersky::hook_ssdt_routine( SYSCALL_NTLOADDRIVER, hkNtLoadDriver, reinterpret_cast< PVOID* >( &oNtLoadDriver ) ) ) - { - DBGPRINT( "NtLoadDriver ( 0x%X ) hooked successfully!\n", SYSCALL_NTLOADDRIVER ); - } - else - DBGPRINT( "Failed to hook NtLoadDriver!\n" ); +#define KASPERSKY_HOOK_ROUTINE(name) \ + if (!kaspersky::hook_ssdt_routine(syscalls::GetSyscallIndexByName(#name), hooks::hk##name, \ + reinterpret_cast(&hooks::o##name))) \ + { \ + DBGPRINT("Failed to hook " #name); \ + return false; \ + } \ + else \ + { \ + DBGPRINT(#name " hooked successfully!"); \ + } + + KASPERSKY_HOOK_ROUTINE(NtOpenProcess); + KASPERSKY_HOOK_ROUTINE(NtDeviceIoControlFile); + KASPERSKY_HOOK_ROUTINE(NtQuerySystemInformation); + KASPERSKY_HOOK_ROUTINE(NtAllocateVirtualMemory); + KASPERSKY_HOOK_ROUTINE(NtFreeVirtualMemory); + KASPERSKY_HOOK_ROUTINE(NtWriteVirtualMemory); + KASPERSKY_HOOK_ROUTINE(NtLoadDriver); + #endif + return true; } void ssdt::Destroy() { #ifndef USE_KASPERSKY - if ( !g_KeServiceDescriptorTable ) - return; + if (!g_KeServiceDescriptorTable) + return; - if ( !UnhookSSDT( oNtQuerySystemInformation, SYSCALL_NTQUERYSYSINFO ) ) - DBGPRINT( "Failed to unhook NtQuerySystemInformation!\n" ); + if (!UnhookSSDT(oNtQuerySystemInformation, SYSCALL_NTQUERYSYSINFO)) + DBGPRINT("Failed to unhook NtQuerySystemInformation!\n"); - if ( !UnhookSSDT( oNtOpenProcess, SYSCALL_NTOPENPROCESS ) ) - DBGPRINT( "Failed to unhook NtOpenProcess!\n" ); + if (!UnhookSSDT(oNtOpenProcess, SYSCALL_NTOPENPROCESS)) + DBGPRINT("Failed to unhook NtOpenProcess!\n"); - if ( !UnhookSSDT( oNtAllocateVirtualMemory, SYSCALL_NTALLOCVIRTUALMEM ) ) - DBGPRINT( "Failed to unhook NtAllocateVirtualMemory!\n" ); + if (!UnhookSSDT(oNtAllocateVirtualMemory, SYSCALL_NTALLOCVIRTUALMEM)) + DBGPRINT("Failed to unhook NtAllocateVirtualMemory!\n"); - if ( !UnhookSSDT( oNtFreeVirtualMemory, SYSCALL_NTFREEVIRTUALMEM ) ) - DBGPRINT( "Failed to unhook NtFreeVirtualMemory!\n" ); + if (!UnhookSSDT(oNtFreeVirtualMemory, SYSCALL_NTFREEVIRTUALMEM)) + DBGPRINT("Failed to unhook NtFreeVirtualMemory!\n"); - if ( !UnhookSSDT( oNtWriteVirtualMemory, SYSCALL_NTWRITEVIRTUALMEM ) ) - DBGPRINT( "Failed to unhook NtWriteVirtualMemory!\n" ); + if (!UnhookSSDT(oNtWriteVirtualMemory, SYSCALL_NTWRITEVIRTUALMEM)) + DBGPRINT("Failed to unhook NtWriteVirtualMemory!\n"); - if ( !UnhookSSDT( oNtDeviceIoControlFile, SYSCALL_NTDEVICEIOCTRLFILE ) ) - DBGPRINT( "Failed to unhook NtDeviceIoControlFile!\n" ); + if (!UnhookSSDT(oNtDeviceIoControlFile, SYSCALL_NTDEVICEIOCTRLFILE)) + DBGPRINT("Failed to unhook NtDeviceIoControlFile!\n"); #else - if ( !kaspersky::is_klhk_loaded() ) - return; - - if ( !kaspersky::unhook_ssdt_routine( SYSCALL_NTQUERYSYSINFO, oNtQuerySystemInformation ) ) - DBGPRINT( "Failed to unhook NtQuerySystemInformation" ); - - if ( !kaspersky::unhook_ssdt_routine( SYSCALL_NTOPENPROCESS, oNtOpenProcess ) ) - DBGPRINT( "Failed to unhook NtOpenProcess" ); - - if ( !kaspersky::unhook_ssdt_routine( SYSCALL_NTALLOCVIRTUALMEM, oNtAllocateVirtualMemory ) ) - DBGPRINT( "Failed to unhook NtAllocateVirtualMemory" ); - - if ( !kaspersky::unhook_ssdt_routine( SYSCALL_NTFREEVIRTUALMEM, oNtFreeVirtualMemory ) ) - DBGPRINT( "Failed to unhook NtFreeVirtualMemory" ); - - if ( !kaspersky::unhook_ssdt_routine( SYSCALL_NTWRITEVIRTUALMEM, oNtWriteVirtualMemory ) ) - DBGPRINT( "Failed to unhook NtWriteVirtualMemory" ); - - if ( !kaspersky::unhook_ssdt_routine( SYSCALL_NTDEVICEIOCTRLFILE, oNtDeviceIoControlFile ) ) - DBGPRINT( "Failed to unhook NtDeviceIoControlFile" ); - - if ( !kaspersky::unhook_ssdt_routine( SYSCALL_NTLOADDRIVER, oNtLoadDriver ) ) - DBGPRINT( "Failed to unhook NtLoadDriver" ); + if (!kaspersky::is_klhk_loaded()) + return; + +#define KASPERSKY_UNHOOK_ROUTINE(name) \ + if (!kaspersky::unhook_ssdt_routine(syscalls::GetSyscallIndexByName(#name), hooks::o##name)) \ + { \ + DBGPRINT("Failed to unhook " #name); \ + } \ + else \ + { \ + DBGPRINT(#name " unhooked successfully!"); \ + } + + KASPERSKY_UNHOOK_ROUTINE(NtOpenProcess); + KASPERSKY_UNHOOK_ROUTINE(NtDeviceIoControlFile); + KASPERSKY_UNHOOK_ROUTINE(NtQuerySystemInformation); + KASPERSKY_UNHOOK_ROUTINE(NtAllocateVirtualMemory); + KASPERSKY_UNHOOK_ROUTINE(NtFreeVirtualMemory); + KASPERSKY_UNHOOK_ROUTINE(NtWriteVirtualMemory); + KASPERSKY_UNHOOK_ROUTINE(NtLoadDriver); + +#undef KASPERSKY_UNHOOK_ROUTINE #endif } \ No newline at end of file diff --git a/MasterHide/ssdt.h b/MasterHide/ssdt.h deleted file mode 100644 index 0d50338..0000000 --- a/MasterHide/ssdt.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -static UCHAR jmp_trampoline[] = { 0x50, 0x48, 0xB8, 0xEF, 0xBE, 0xAD, 0xDE, 0xEF, 0xBE, 0xAD, 0xDE, 0x48, 0x87, 0x04, 0x24, 0xC3 }; - -namespace masterhide -{ - namespace ssdt - { - extern void Init(); - extern void Destroy(); - } -}; \ No newline at end of file diff --git a/MasterHide/ssdt.hpp b/MasterHide/ssdt.hpp new file mode 100644 index 0000000..d6de12a --- /dev/null +++ b/MasterHide/ssdt.hpp @@ -0,0 +1,13 @@ +#pragma once + +static UCHAR jmp_trampoline[] = {0x50, 0x48, 0xB8, 0xEF, 0xBE, 0xAD, 0xDE, 0xEF, + 0xBE, 0xAD, 0xDE, 0x48, 0x87, 0x04, 0x24, 0xC3}; + +namespace masterhide +{ +namespace ssdt +{ +extern bool Init(); +extern void Destroy(); +} // namespace ssdt +}; // namespace masterhide \ No newline at end of file diff --git a/MasterHide/stdafx.h b/MasterHide/stdafx.h deleted file mode 100644 index 675c6ed..0000000 --- a/MasterHide/stdafx.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define TAG 'gtHM' -#define DBGPRINT( x, ... ) DbgPrintEx( NULL, NULL, "[ MasterHide ] " x, __VA_ARGS__ ); - -// -// Uncomment that to use ordinary SSDT/SSSDT hooking -// -#define USE_KASPERSKY - -#include "winnt.h" -#include "globals.hpp" -#include "tools.h" -#include "kaspersky.hpp" -#include "ssdt.h" -#include "shadow_ssdt.h" -#include "mh_hooks.h" - -using namespace masterhide; \ No newline at end of file diff --git a/MasterHide/syscalls.cpp b/MasterHide/syscalls.cpp new file mode 100644 index 0000000..ba19cf3 --- /dev/null +++ b/MasterHide/syscalls.cpp @@ -0,0 +1,333 @@ +#include "includes.hpp" + +namespace masterhide +{ +namespace syscalls +{ +UNICODE_STRING g_NtdllPath = RTL_CONSTANT_STRING(L"\\SystemRoot\\System32\\ntdll.dll"); +UNICODE_STRING g_Win32UPath = RTL_CONSTANT_STRING(L"\\SystemRoot\\System32\\win32u.dll"); + +bool g_initialized = false; + +/// +/// Dynamic hash table pointer +/// +PRTL_DYNAMIC_HASH_TABLE g_hashTable = nullptr; + +/// +/// Dynamic hash table context +/// +RTL_DYNAMIC_HASH_TABLE_CONTEXT g_hashTableContext{}; + +void ClearAndDeleteHashTable(); + +typedef struct _SYSCALL_TABLE_ENTRY +{ + RTL_DYNAMIC_HASH_TABLE_ENTRY hashTableEntry; + USHORT serviceIndex; + +} SYSCALL_TABLE_ENTRY, *PSYSCALL_TABLE_ENTRY; + +/// +/// This function will try to map and extract syscalls from provided file name and finally add them to dynamic hash +/// table if possible. +/// +/// File name to extract syscalls from +/// NTSTATUS value +static NTSTATUS FillSyscallTable(_In_ PUNICODE_STRING fileName, _In_ bool win32k = false) +{ + PVOID mappedBase = nullptr; + SIZE_T mappedSize = 0; + + NTSTATUS status = tools::MapFileInSystemSpace(fileName, &mappedBase, &mappedSize); + if (!NT_SUCCESS(status)) + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "Failed to map %wZ into system space!", fileName); + return STATUS_UNSUCCESSFUL; + } + + SCOPE_EXIT + { + MmUnmapViewInSystemSpace(mappedBase); + }; + + __try + { + PIMAGE_NT_HEADERS nth = RtlImageNtHeader(mappedBase); + if (!nth) + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "Invalid NT header!"); + return STATUS_UNSUCCESSFUL; + } + + ULONG exportDirSize = 0; + const auto exportDirectory = reinterpret_cast( + RtlImageDirectoryEntryToData(mappedBase, TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT, &exportDirSize)); + if (!exportDirectory) + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "Invalid image export directory!"); + return STATUS_UNSUCCESSFUL; + } + + auto moduleBase = reinterpret_cast(mappedBase); + + const auto addressOfNames = reinterpret_cast(moduleBase + exportDirectory->AddressOfNames); + const auto addressOfNameOrdinals = + reinterpret_cast(moduleBase + exportDirectory->AddressOfNameOrdinals); + const auto addressOfFunctions = reinterpret_cast(moduleBase + exportDirectory->AddressOfFunctions); + + for (auto i = 0ul; i < exportDirectory->NumberOfNames; i++) + { + auto exportName = reinterpret_cast(moduleBase + addressOfNames[i]); + auto procedureAddress = reinterpret_cast(moduleBase + addressOfFunctions[addressOfNameOrdinals[i]]); + + auto IsSyscall = [&]() -> BOOLEAN { + return (procedureAddress[0] == 0x4C && procedureAddress[1] == 0x8B && procedureAddress[2] == 0xD1 && + procedureAddress[3] == 0xB8); + }; + + // Check if the export is possibly a syscall + if (strlen(exportName) > 2 && (exportName[0] == 'N' && exportName[1] == 't') && IsSyscall()) + { + ULONG64 functionData = *(ULONG64 *)procedureAddress; + ULONG syscallNum = (functionData >> 8 * 4); + syscallNum = syscallNum & 0xfff; + + // Allocate new entry and insert to hash table. + auto entry = tools::AllocatePoolZero(NonPagedPool, sizeof(SYSCALL_TABLE_ENTRY), + tags::TAG_HASH_TABLE_ENTRY); + if (entry) + { + const FNV1A_t serviceHash = FNV1A::Hash(exportName); + entry->serviceIndex = + win32k ? static_cast(syscallNum) + 0x1000 : static_cast(syscallNum); + + InitializeListHead(&entry->hashTableEntry.Linkage); + RtlInsertEntryHashTable(g_hashTable, &entry->hashTableEntry, serviceHash, &g_hashTableContext); + } + } + } + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + status = GetExceptionCode(); + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "Exception on FillSyscallTable %!STATUS!", status); + } + + return status; +} + +struct WIN32K_TABLE +{ + char Name[64]; + USHORT Index; + + WIN32K_TABLE(const char *name, USHORT index) : Index(index) + { + strcpy(Name, name); + } +}; + +void FillWin32SyscallTableLegacy() +{ + USHORT NtUserWindowFromPoint = MAXUSHORT; + USHORT NtUserQueryWindow = MAXUSHORT; + USHORT NtUserFindWindowEx = MAXUSHORT; + USHORT NtUserBuildHwndList = MAXUSHORT; + USHORT NtUserGetForegroundWindow = MAXUSHORT; + USHORT NtUserGetThreadState = MAXUSHORT; + + switch (KERNEL_BUILD_VERSION) + { + case WINDOWS_7_SP1: + NtUserWindowFromPoint = 0x1014; + NtUserQueryWindow = 0x1010; + NtUserFindWindowEx = 0x106e; + NtUserBuildHwndList = 0x101c; + NtUserGetForegroundWindow = 0x103c; + NtUserGetThreadState = 0x1000; + break; + case WINDOWS_8: + NtUserWindowFromPoint = 4117; + NtUserQueryWindow = 4113; + NtUserFindWindowEx = 4206; + NtUserBuildHwndList = 4125; + NtUserGetForegroundWindow = 4157; + NtUserGetThreadState = 4097; + break; + case WINDOWS_8_1: + NtUserWindowFromPoint = 5130; + NtUserQueryWindow = 4114; + NtUserFindWindowEx = 4206; + NtUserBuildHwndList = 4207; + NtUserGetForegroundWindow = 4158; + NtUserGetThreadState = 4098; + break; + } + + const WIN32K_TABLE win32kTable[] = {{"NtUserWindowFromPoint", NtUserWindowFromPoint}, + {"NtUserQueryWindow", NtUserQueryWindow}, + {"NtUserFindWindowEx", NtUserFindWindowEx}, + {"NtUserBuildHwndList", NtUserBuildHwndList}, + {"NtUserGetForegroundWindow", NtUserGetForegroundWindow}, + {"NtUserGetThreadState", NtUserGetThreadState}}; + + for (auto &tableEntry : win32kTable) + { + auto entry = tools::AllocatePoolZero(NonPagedPool, sizeof(SYSCALL_TABLE_ENTRY), + tags::TAG_HASH_TABLE_ENTRY); + if (entry) + { + FNV1A_t serviceHash = FNV1A::Hash(tableEntry.Name); + entry->serviceIndex = tableEntry.Index; + + InitializeListHead(&entry->hashTableEntry.Linkage); + RtlInsertEntryHashTable(g_hashTable, &entry->hashTableEntry, serviceHash, &g_hashTableContext); + } + } +} + +NTSTATUS Initialize() +{ + PAGED_CODE(); + NT_ASSERT(!g_initialized); + + if (g_initialized) + { + return STATUS_ALREADY_INITIALIZED; + } + + g_hashTable = tools::AllocatePoolZero(NonPagedPool, sizeof(RTL_DYNAMIC_HASH_TABLE), + tags::TAG_HASH_TABLE); + if (!g_hashTable) + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "Failed to allocate memory for dynamic hash table!"); + return STATUS_INSUFFICIENT_RESOURCES; + } + + if (!RtlCreateHashTable(&g_hashTable, 0, 0)) + { + ExFreePool(g_hashTable); + + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "Failed to create hash table!"); + return STATUS_UNSUCCESSFUL; + } + + RtlInitHashTableContext(&g_hashTableContext); + + NTSTATUS status = FillSyscallTable(&g_NtdllPath); + if (!NT_SUCCESS(status)) + { + ClearAndDeleteHashTable(); + + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "Failed to fill ntdll.dll syscall table!"); + return STATUS_UNSUCCESSFUL; + } + + // win32u.dll is only exported starting Windows 10 + // + if (KERNEL_BUILD_VERSION > WINDOWS_8_1) + { + status = FillSyscallTable(&g_Win32UPath, true); + if (!NT_SUCCESS(status)) + { + ClearAndDeleteHashTable(); + + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "Failed to fill win32u.dll syscall table!"); + return STATUS_UNSUCCESSFUL; + } + } + else + { + FillWin32SyscallTableLegacy(); + } + + g_initialized = true; + + return STATUS_SUCCESS; +} + +void Deinitialize() +{ + PAGED_CODE(); + + if (!g_initialized) + { + return; + } + + ClearAndDeleteHashTable(); + g_initialized = false; + + WppTracePrint(TRACE_LEVEL_VERBOSE, GENERAL, "Successfully de-initialized syscalls interface!"); + return; +} + +void ClearAndDeleteHashTable() +{ + RTL_DYNAMIC_HASH_TABLE_ENUMERATOR hashTableEnumerator{}; + + if (RtlInitEnumerationHashTable(g_hashTable, &hashTableEnumerator)) + { + while (true) + { + PRTL_DYNAMIC_HASH_TABLE_ENTRY hashTableEntry = + RtlEnumerateEntryHashTable(g_hashTable, &hashTableEnumerator); + if (!hashTableEntry) + { + break; + } + + RtlRemoveEntryHashTable(g_hashTable, hashTableEntry, &g_hashTableContext); + + PSYSCALL_TABLE_ENTRY entry = CONTAINING_RECORD(hashTableEntry, SYSCALL_TABLE_ENTRY, hashTableEntry); + ExFreePool(entry); + } + RtlEndEnumerationHashTable(g_hashTable, &hashTableEnumerator); + } + + RtlDeleteHashTable(g_hashTable); + RtlReleaseHashTableContext(&g_hashTableContext); + ExFreePool(g_hashTable); +} + +USHORT GetSyscallIndexByName(_In_ LPCSTR serviceName) +{ + PAGED_CODE(); + NT_ASSERT(g_initialized); + + USHORT serviceIndex = MAXUSHORT; + FNV1A_t signature = FNV1A::Hash(serviceName); + + RTL_DYNAMIC_HASH_TABLE_ENUMERATOR hashTableEnumerator{}; + if (RtlInitEnumerationHashTable(g_hashTable, &hashTableEnumerator)) + { + while (true) + { + PRTL_DYNAMIC_HASH_TABLE_ENTRY hashTableEntry = + RtlEnumerateEntryHashTable(g_hashTable, &hashTableEnumerator); + if (!hashTableEntry) + { + break; + } + + if (hashTableEntry->Signature == signature) + { + PSYSCALL_TABLE_ENTRY entry = CONTAINING_RECORD(hashTableEntry, SYSCALL_TABLE_ENTRY, hashTableEntry); + serviceIndex = entry->serviceIndex; + break; + } + } + RtlEndEnumerationHashTable(g_hashTable, &hashTableEnumerator); + } + + if (serviceIndex == MAXUSHORT) + { + WppTracePrint(TRACE_LEVEL_ERROR, GENERAL, "Service %s not found in hash table list!", serviceName); + NT_ASSERT(FALSE); + } + + return serviceIndex; +} +} // namespace syscalls +} // namespace masterhide \ No newline at end of file diff --git a/MasterHide/syscalls.hpp b/MasterHide/syscalls.hpp new file mode 100644 index 0000000..8da80f4 --- /dev/null +++ b/MasterHide/syscalls.hpp @@ -0,0 +1,25 @@ +#pragma once + +namespace masterhide +{ +namespace syscalls +{ +/// +/// Initialize and fill the syscall dynamic hash table. +/// +/// STATUS_SUCCESS on succes, otherwise any NTSTATUS value +NTSTATUS Initialize(); + +/// +/// De-initialize the syscall dynamic hash table if initialized. +/// +void Deinitialize(); + +/// +/// Obtain syscall index by service name +/// +/// Service name +/// MAXUSHORT on failure, otherwise syscall index +USHORT GetSyscallIndexByName(_In_ LPCSTR serviceName); +} // namespace syscalls +} // namespace masterhide \ No newline at end of file diff --git a/MasterHide/thirdparty/phnt b/MasterHide/thirdparty/phnt new file mode 160000 index 0000000..1f91f26 --- /dev/null +++ b/MasterHide/thirdparty/phnt @@ -0,0 +1 @@ +Subproject commit 1f91f263a2b47b1fa646421a7b3fb976ed7286a8 diff --git a/MasterHide/thirdparty/scope_guard/.github/workflows/macos.yml b/MasterHide/thirdparty/scope_guard/.github/workflows/macos.yml new file mode 100644 index 0000000..859bd70 --- /dev/null +++ b/MasterHide/thirdparty/scope_guard/.github/workflows/macos.yml @@ -0,0 +1,37 @@ +name: macos + +on: [push, pull_request] + +permissions: read-all + +jobs: + build: + runs-on: ${{ matrix.config.os }} + strategy: + fail-fast: false + matrix: + config: + - { os: macos-11 } # https://github.com/actions/virtual-environments/blob/main/images/macos/macos-11-Readme.md#xcode + - { os: macos-12 } # https://github.com/actions/virtual-environments/blob/main/images/macos/macos-12-Readme.md#xcode + + name: "${{ matrix.config.os }}" + steps: + - uses: actions/checkout@v4 + + - name: Build Release + run: | + rm -rf build + mkdir build + cd build + cmake .. -DCMAKE_BUILD_TYPE=Release + cmake --build . -j 4 --config Release + ctest --output-on-failure -C Release + + - name: Build Debug + run: | + rm -rf build + mkdir build + cd build + cmake .. -DCMAKE_BUILD_TYPE=Debug + cmake --build . -j 4 --config Debug + ctest --output-on-failure -C Debug diff --git a/MasterHide/thirdparty/scope_guard/.github/workflows/ubuntu.yml b/MasterHide/thirdparty/scope_guard/.github/workflows/ubuntu.yml new file mode 100644 index 0000000..b416d9f --- /dev/null +++ b/MasterHide/thirdparty/scope_guard/.github/workflows/ubuntu.yml @@ -0,0 +1,74 @@ +name: ubuntu + +on: [push, pull_request] + +permissions: read-all + +jobs: + ubuntu: + strategy: + fail-fast: false + matrix: + compiler: + - { cc: "gcc-9", cxx: "g++-9", os: "ubuntu-20.04" } + - { cc: "gcc-10", cxx: "g++-10", os: "ubuntu-20.04" } + - { cc: "gcc-10", cxx: "g++-10", os: "ubuntu-20.04" } + - { cc: "gcc-11", cxx: "g++-11", os: "ubuntu-20.04" } + - { cc: "gcc-11", cxx: "g++-11", os: "ubuntu-20.04" } + - { cc: "gcc-12", cxx: "g++-12", os: "ubuntu-22.04" } + - { cc: "clang-9", cxx: "clang++-9", os: "ubuntu-20.04" } + - { cc: "clang-10", cxx: "clang++-10", os: "ubuntu-20.04" } + - { cc: "clang-11", cxx: "clang++-11", os: "ubuntu-20.04" } + - { cc: "clang-12", cxx: "clang++-12", os: "ubuntu-20.04" } + - { cc: "clang-13", cxx: "clang++-13", os: "ubuntu-20.04" } + - { cc: "clang-14", cxx: "clang++-14", os: "ubuntu-20.04" } + - { cc: "clang-15", cxx: "clang++-15", os: "ubuntu-20.04" } + - { cc: "clang-16", cxx: "clang++-16", os: "ubuntu-20.04" } + + name: "${{ matrix.compiler.cc }}" + runs-on: ${{ matrix.compiler.os }} + steps: + - uses: actions/checkout@v4 + + - name: Configure clang + run: | + if [[ "${{ matrix.compiler.cc }}" == "clang"* ]]; then + wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key|sudo apt-key add - + sudo apt-add-repository "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-9 main" + sudo apt-add-repository "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-10 main" + sudo apt-add-repository "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-11 main" + sudo apt-add-repository "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-12 main" + sudo apt-add-repository "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-13 main" + sudo apt-add-repository "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-14 main" + sudo apt-add-repository "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-15 main" + sudo apt-add-repository "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-16 main" + sudo apt-add-repository "deb http://apt.llvm.org/focal/ llvm-toolchain-focal main" + sudo apt update + sudo apt install ${{ matrix.compiler.cc }} -y + fi + + - name: Configure gcc + run: | + if [[ "${{ matrix.compiler.cc }}" == "gcc"* ]]; then + sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y + sudo apt update + sudo apt install ${{ matrix.compiler.cxx }} -y + fi + + - name: Build Release + run: | + rm -rf build + mkdir build + cd build + cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER=${{ matrix.compiler.cxx }} + cmake --build . -j 4 --config Release + ctest --output-on-failure -C Release + + - name: Build Debug + run: | + rm -rf build + mkdir build + cd build + cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_COMPILER=${{ matrix.compiler.cxx }} + cmake --build . -j 4 --config Debug + ctest --output-on-failure -C Debug diff --git a/MasterHide/thirdparty/scope_guard/.github/workflows/windows.yml b/MasterHide/thirdparty/scope_guard/.github/workflows/windows.yml new file mode 100644 index 0000000..66cc74e --- /dev/null +++ b/MasterHide/thirdparty/scope_guard/.github/workflows/windows.yml @@ -0,0 +1,43 @@ +name: windows + +on: [push, pull_request] + +permissions: read-all + +jobs: + build: + runs-on: ${{ matrix.config.os }} + strategy: + fail-fast: false + matrix: + config: + - { os: windows-2019, vs: "Visual Studio 2019" } # https://github.com/actions/virtual-environments/blob/main/images/win/Windows2019-Readme.md#visual-studio-enterprise-2019 + - { os: windows-2022, vs: "Visual Studio 2022" } # https://github.com/actions/virtual-environments/blob/main/images/win/Windows2022-Readme.md#visual-studio-enterprise-2022 + + name: "${{ matrix.config.vs }}" + steps: + - uses: actions/checkout@v4 + + - name: Build Win32 + shell: bash + run: | + rm -rf build + mkdir build + cd build + cmake .. -A Win32 + cmake --build . -j 4 --config Release + ctest --output-on-failure -C Release + cmake --build . -j 4 --config Debug + ctest --output-on-failure -C Debug + + - name: Build x64 + shell: bash + run: | + rm -rf build + mkdir build + cd build + cmake .. -A x64 + cmake --build . -j 4 --config Release + ctest --output-on-failure -C Release + cmake --build . -j 4 --config Debug + ctest --output-on-failure -C Debug diff --git a/MasterHide/thirdparty/scope_guard/.gitignore b/MasterHide/thirdparty/scope_guard/.gitignore new file mode 100644 index 0000000..ef6cd27 --- /dev/null +++ b/MasterHide/thirdparty/scope_guard/.gitignore @@ -0,0 +1,50 @@ +build/ +.vscode/ +.vs/ + +### C++ gitignore ### +# Prerequisites +*.d + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app + +### CMake gitignore ### +CMakeLists.txt.user +CMakeCache.txt +CMakeFiles +CMakeScripts +Testing +Makefile +cmake_install.cmake +install_manifest.txt +compile_commands.json +CTestTestfile.cmake +_deps diff --git a/MasterHide/thirdparty/scope_guard/CMakeLists.txt b/MasterHide/thirdparty/scope_guard/CMakeLists.txt new file mode 100644 index 0000000..40d4255 --- /dev/null +++ b/MasterHide/thirdparty/scope_guard/CMakeLists.txt @@ -0,0 +1,54 @@ +cmake_minimum_required(VERSION 3.14) + +project(scope_guard VERSION "0.9.1" LANGUAGES CXX) + +if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME) + set(IS_TOPLEVEL_PROJECT TRUE) +else() + set(IS_TOPLEVEL_PROJECT FALSE) +endif() + +option(SCOPE_GUARD_OPT_BUILD_EXAMPLES "Build scope_guard examples" ${IS_TOPLEVEL_PROJECT}) +option(SCOPE_GUARD_OPT_BUILD_TESTS "Build and perform scope_guard tests" ${IS_TOPLEVEL_PROJECT}) +option(SCOPE_GUARD_OPT_INSTALL "Generate and install scope_guard target" ${IS_TOPLEVEL_PROJECT}) + +if(SCOPE_GUARD_OPT_BUILD_EXAMPLES) + add_subdirectory(example) +endif() + +if(SCOPE_GUARD_OPT_BUILD_TESTS) + enable_testing() + add_subdirectory(test) +endif() + +include(CMakePackageConfigHelpers) + +add_library(${PROJECT_NAME} INTERFACE) +add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME}) +target_include_directories(${PROJECT_NAME} + INTERFACE + $ + $) + +write_basic_package_version_file(${PROJECT_NAME}ConfigVersion.cmake + VERSION ${PROJECT_VERSION} + COMPATIBILITY AnyNewerVersion + ARCH_INDEPENDENT) + +if(SCOPE_GUARD_OPT_INSTALL) + install(TARGETS ${PROJECT_NAME} + EXPORT ${PROJECT_NAME}Config) + + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake + DESTINATION lib/cmake/${PROJECT_NAME}) + + install(EXPORT ${PROJECT_NAME}Config + NAMESPACE ${PROJECT_NAME}:: + DESTINATION lib/cmake/${PROJECT_NAME}) + + install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include + DESTINATION .) + + export(EXPORT ${PROJECT_NAME}Config + NAMESPACE ${PROJECT_NAME}::) +endif() diff --git a/MasterHide/thirdparty/scope_guard/LICENSE b/MasterHide/thirdparty/scope_guard/LICENSE new file mode 100644 index 0000000..e18368c --- /dev/null +++ b/MasterHide/thirdparty/scope_guard/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 - 2024 Daniil Goncharov + +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/MasterHide/thirdparty/scope_guard/README.md b/MasterHide/thirdparty/scope_guard/README.md new file mode 100644 index 0000000..815151b --- /dev/null +++ b/MasterHide/thirdparty/scope_guard/README.md @@ -0,0 +1,155 @@ +[![Github Releases](https://img.shields.io/github/release/Neargye/scope_guard.svg)](https://github.com/Neargye/scope_guard/releases) +[![License](https://img.shields.io/github/license/Neargye/scope_guard.svg)](LICENSE) + +# Scope Guard & Defer C++ + +Scope Guard statement invokes a function with deferred execution until surrounding function returns in cases: + +* scope_exit - executing action on scope exit. + +* scope_fail - executing action on scope exit when an exception has been thrown. + +* scope_success - executing action on scope exit when no exceptions have been thrown. + +Program control transferring does not influence Scope Guard statement execution. Hence, Scope Guard statement can be used to perform manual resource management, such as file descriptors closing, and to perform actions even if an error occurs. + +## Features + +* C++11 +* Header-only +* Dependency-free +* Thin callback wrapping, no added std::function or virtual table penalties +* No implicitly ignored return, check callback return void +* Defer or Scope Guard syntax and "With" syntax + +## [Examples](example) + +* [Scope Guard on exit](example/scope_exit_example.cpp) + + ```cpp + std::fstream file("test.txt"); + SCOPE_EXIT{ file.close(); }; // File closes when exit the enclosing scope or errors occur. + ``` + +* [Scope Guard on fail](example/scope_fail_example.cpp) + + ```cpp + persons.push_back(person); // Add the person to db. + SCOPE_FAIL{ persons.pop_back(); }; // If errors occur, we should roll back. + ``` + +* [Scope Guard on success](example/scope_success_example.cpp) + + ```cpp + person = new Person{/*...*/}; + // ... + SCOPE_SUCCESS{ persons.push_back(person); }; // If no errors occur, we should add the person to db. + ``` + +* Custom Scope Guard + + ```cpp + persons.push_back(person); // Add the person to db. + + MAKE_SCOPE_EXIT(scope_exit) { // Following block is executed when exit the enclosing scope or errors occur. + persons.pop_back(); // If the db insertion fails, we should roll back. + }; + // MAKE_SCOPE_EXIT(name) {action} - macro is used to create a new scope_exit object. + scope_exit.dismiss(); // An exception was not thrown, so don't execute the scope_exit. + ``` + + ```cpp + persons.push_back(person); // Add the person to db. + + auto scope_exit = make_scope_exit([]() { persons.pop_back(); }); + // make_scope_exit(A&& action) - function is used to create a new scope_exit object. It can be instantiated with a lambda function, a std::function, a functor, or a void(*)() function pointer. + // ... + scope_exit.dismiss(); // An exception was not thrown, so don't execute the scope_exit. + ``` + +* With Scope Guard + + ```cpp + std::fstream file("test.txt"); + WITH_SCOPE_EXIT({ file.close(); }) { // File closes when exit the enclosing with scope or errors occur. + // ... + }; + ``` + +## Synopsis + +### Reference + +#### scope_exit + +* `scope_exit make_scope_exit(F&& action);` - return scope_exit with the action. +* `SCOPE_EXIT{action};` - macro for creating scope_exit with the action. +* `MAKE_SCOPE_EXIT(name) {action};` - macro for creating named scope_exit with the action. +* `WITH_SCOPE_EXIT({action}) {/*...*/};` - macro for creating scope with scope_exit with the action. + +#### scope_fail + +* `scope_fail make_scope_fail(F&& action);` - return scope_fail with the action. +* `SCOPE_FAIL{action};` - macro for creating scope_fail with the action. +* `MAKE_SCOPE_FAIL(name) {action};` - macro for creating named scope_fail with the action. +* `WITH_SCOPE_FAIL({action}) {/*...*/};` - macro for creating scope with scope_fail with the action. + +#### scope_success + +* `scope_success make_scope_success(F&& action);` - return scope_success with the action. +* `SCOPE_SUCCESS{action};` - macro for creating scope_success with the action. +* `MAKE_SCOPE_SUCCESS(name) {action};` - macro for creating named scope_success with the action. +* `WITH_SCOPE_SUCCESS({action}) {/*...*/};` - macro for creating scope with scope_success with the action. + +#### defer + +* `DEFER{action};` - macro for creating defer with the action. +* `MAKE_DEFER(name) {action};` - macro for creating named defer with the action. +* `WITH_DEFER({action}) {/*...*/};` - macro for creating scope with defer with the action. + +### Interface of scope_guard + +scope_exit, scope_fail, scope_success implement scope_guard interface. + +* `dismiss()` - dismiss executing action on scope exit. + +#### Throwable settings + +* `SCOPE_GUARD_NOTHROW_CONSTRUCTIBLE` define this to require nothrow constructible action. + +* `SCOPE_GUARD_MAY_THROW_ACTION` define this to action may throw exceptions. + +* `SCOPE_GUARD_NO_THROW_ACTION` define this to require noexcept action. + +* `SCOPE_GUARD_SUPPRESS_THROW_ACTIONS` define this to exceptions during action will be suppressed. + +* By default using `SCOPE_GUARD_MAY_THROW_ACTION`. + +* `SCOPE_GUARD_CATCH_HANDLER` define this to add exceptions handler. If `SCOPE_GUARD_SUPPRESS_THROW_ACTIONS` is not defined, it will do nothing. + +### Remarks + +* If multiple Scope Guard statements appear in the same scope, the order they appear is the reverse of the order they are executed. + + ```cpp + void f() { + SCOPE_EXIT{ std::cout << "First" << std::endl; }; + SCOPE_EXIT{ std::cout << "Second" << std::endl; }; + SCOPE_EXIT{ std::cout << "Third" << std::endl; }; + ... // Other code. + // Prints "Third". + // Prints "Second". + // Prints "First". + } + ``` + +## Integration + +You should add required file [scope_guard.hpp](include/scope_guard.hpp). + +## References + +* [Andrei Alexandrescu "Systematic Error Handling in C++"](https://channel9.msdn.com/Shows/Going+Deep/C-and-Beyond-2012-Andrei-Alexandrescu-Systematic-Error-Handling-in-C) +* [Andrei Alexandrescu “Declarative Control Flow"](https://youtu.be/WjTrfoiB0MQ) + +## Licensed under the [MIT License](LICENSE) diff --git a/MasterHide/thirdparty/scope_guard/example/CMakeLists.txt b/MasterHide/thirdparty/scope_guard/example/CMakeLists.txt new file mode 100644 index 0000000..9bdacdc --- /dev/null +++ b/MasterHide/thirdparty/scope_guard/example/CMakeLists.txt @@ -0,0 +1,25 @@ +include(CheckCXXCompilerFlag) + +if((CMAKE_CXX_COMPILER_ID MATCHES "GNU") OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang")) + set(CMAKE_VERBOSE_MAKEFILE ON) + set(OPTIONS -Wall -Wextra -pedantic-errors -Werror) +elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") + set(OPTIONS /W4 /WX) + check_cxx_compiler_flag(/permissive HAS_PERMISSIVE_FLAG) + if(HAS_PERMISSIVE_FLAG) + set(OPTIONS ${OPTIONS} /permissive-) + endif() + set(OPTIONS ${OPTIONS} /wd4702) # Disable warning C4702: unreachable code +endif() + +function(make_example target) + add_executable(${target} ${target}.cpp ${CMAKE_SOURCE_DIR}/include/${CMAKE_PROJECT_NAME}.hpp) + set_target_properties(${target} PROPERTIES CXX_EXTENSIONS OFF) + target_compile_features(${target} PRIVATE cxx_std_11) + target_compile_options(${target} PRIVATE ${OPTIONS}) + target_link_libraries(${target} PRIVATE ${CMAKE_PROJECT_NAME}) +endfunction() + +make_example(scope_exit_example) +make_example(scope_fail_example) +make_example(scope_success_example) diff --git a/MasterHide/thirdparty/scope_guard/example/scope_exit_example.cpp b/MasterHide/thirdparty/scope_guard/example/scope_exit_example.cpp new file mode 100644 index 0000000..5afed2b --- /dev/null +++ b/MasterHide/thirdparty/scope_guard/example/scope_exit_example.cpp @@ -0,0 +1,91 @@ +// Licensed under the MIT License . +// SPDX-License-Identifier: MIT +// Copyright (c) 2018 - 2024 Daniil Goncharov . +// +// 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. + +#include +#include +#include + +#define SCOPE_GUARD_SUPPRESS_THROW_ACTION +#define SCOPE_GUARD_CATCH_HANDLER std::cout << "exception in scope_guard!" << std::endl; + +#include + +int main() { + try { + std::fstream file; + file.open("test.txt", std::fstream::out | std::fstream::trunc); + SCOPE_EXIT{ + file.close(); + std::cout << "[1] close file" << std::endl; + throw std::runtime_error{"error close file"}; + }; + + MAKE_SCOPE_EXIT(scope_exit_1) { + file.close(); + std::cout << "[1] close file #1" << std::endl; + }; + + auto scope_exit_2 = scope_guard::make_scope_exit([&]() { + file.close(); + std::cout << "[1] close file #2" << std::endl; + }); + + WITH_SCOPE_EXIT({ std::cout << "[1] leave WITH_SCOPE_EXIT" << std::endl; }) { + std::cout << "[1] inside WITH_SCOPE_EXIT" << std::endl; + } + + file << "example" << std::endl; + std::cout << "[1] write to file" << std::endl; + + scope_exit_1.dismiss(); + + throw std::runtime_error{"error"}; + + scope_exit_2.dismiss(); + + file.close(); + } + catch (...) { + std::cout << "[1] error" << std::endl; + } + + std::fstream file; + SCOPE_EXIT{ + file.close(); + std::cout << "[2] close file" << std::endl; + }; + file.open("test.txt", std::fstream::out | std::fstream::trunc); + file << "[2] example" << std::endl; + std::cout << "[2] write to file" << std::endl; + file.close(); + + return 0; + + // prints "[1] inside WITH_SCOPE_EXIT". + // prints "[1] leave WITH_SCOPE_EXIT". + // prints "[1] write to file". + // prints "[1] close file #2". + // prints "[1] close file". + // prints "[1] error". + // prints "[2] write to file". + // prints "[2] close file". +} diff --git a/MasterHide/thirdparty/scope_guard/example/scope_fail_example.cpp b/MasterHide/thirdparty/scope_guard/example/scope_fail_example.cpp new file mode 100644 index 0000000..3d404aa --- /dev/null +++ b/MasterHide/thirdparty/scope_guard/example/scope_fail_example.cpp @@ -0,0 +1,83 @@ +// Licensed under the MIT License . +// SPDX-License-Identifier: MIT +// Copyright (c) 2018 - 2024 Daniil Goncharov . +// +// 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. + +#include + +#include +#include +#include + +int main() { + try { + std::fstream file; + file.open("test.txt", std::fstream::out | std::fstream::trunc); + SCOPE_FAIL{ + file.close(); + std::cout << "[1] error write file" << std::endl; + }; + + MAKE_SCOPE_FAIL(scope_fail_1) { + std::cout << "[1] error write file #1" << std::endl; + }; + + auto scope_fail_2 = scope_guard::make_scope_fail([&]() { + std::cout << "[1] error write file #2" << std::endl; + }); + + WITH_SCOPE_FAIL({ std::cout << "[1] leave WITH_SCOPE_FAIL" << std::endl; }) { + std::cout << "[1] inside WITH_SCOPE_FAIL" << std::endl; + } + + file << "example" << std::endl; + std::cout << "[1] write to file" << std::endl; + + scope_fail_1.dismiss(); + + throw std::runtime_error{"error"}; + + scope_fail_2.dismiss(); + + file.close(); + } + catch (...) { + std::cout << "[1] error" << std::endl; + } + + std::fstream file; + SCOPE_FAIL{ + file.close(); + std::cout << "[2] error write file" << std::endl; + }; + file.open("test.txt", std::fstream::out | std::fstream::trunc); + file << "[2] example" << std::endl; + std::cout << "[2] write to file" << std::endl; + file.close(); + + return 0; + + // prints "[1] inside WITH_SCOPE_FAIL". + // prints "[1] write to file". + // prints "[1] error write file #2". + // prints "[1] error write file". + // prints "[1] error". + // prints "[2] write to file". +} diff --git a/MasterHide/thirdparty/scope_guard/example/scope_success_example.cpp b/MasterHide/thirdparty/scope_guard/example/scope_success_example.cpp new file mode 100644 index 0000000..71a405d --- /dev/null +++ b/MasterHide/thirdparty/scope_guard/example/scope_success_example.cpp @@ -0,0 +1,81 @@ +// Licensed under the MIT License . +// SPDX-License-Identifier: MIT +// Copyright (c) 2018 - 2024 Daniil Goncharov . +// +// 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. + +#include + +#include +#include +#include + +int main() { + try { + std::fstream file; + file.open("test.txt", std::fstream::out | std::fstream::trunc); + SCOPE_SUCCESS{ + file.close(); + std::cout << "[1] file write success" << std::endl; + }; + + MAKE_SCOPE_SUCCESS(scope_success_1) { + std::cout << "[1] file write success" << std::endl; + }; + + auto scope_success_2 = scope_guard::make_scope_success([&]() { + std::cout << "[1] file write success" << std::endl; + }); + + WITH_SCOPE_SUCCESS({ std::cout << "[1] leave WITH_SCOPE_SUCCESS" << std::endl; }) { + std::cout << "[1] inside WITH_SCOPE_SUCCESS" << std::endl; + } + + file << "example" << std::endl; + std::cout << "[1] write to file" << std::endl; + file.close(); + + scope_success_1.dismiss(); + + throw std::runtime_error{"error"}; + + scope_success_2.dismiss(); + } + catch (...) { + std::cout << "[1] error" << std::endl; + } + + std::fstream file; + SCOPE_SUCCESS{ + file.close(); + std::cout << "[2] file write success" << std::endl; + }; + file.open("test.txt", std::fstream::out | std::fstream::trunc); + file << "[2] example" << std::endl; + std::cout << "[2] write to file" << std::endl; + + return 0; + + // prints "[1] inside WITH_SCOPE_SUCCESS". + // prints "[1] leave WITH_SCOPE_SUCCESS". + // prints "[1] write to file". + // prints "[1] error". + // prints "[2] write to file". + // prints "[2] file write success". +} diff --git a/MasterHide/thirdparty/scope_guard/include/scope_guard.hpp b/MasterHide/thirdparty/scope_guard/include/scope_guard.hpp new file mode 100644 index 0000000..5a21452 --- /dev/null +++ b/MasterHide/thirdparty/scope_guard/include/scope_guard.hpp @@ -0,0 +1,369 @@ +// _____ _____ _ _____ +// / ____| / ____| | | / ____|_ _ +// | (___ ___ ___ _ __ ___ | | __ _ _ __ _ _ __ __| | | | _| |_ _| |_ +// \___ \ / __/ _ \| '_ \ / _ \ | | |_ | | | |/ _` | '__/ _` | | | |_ _|_ _| +// ____) | (_| (_) | |_) | __/ | |__| | |_| | (_| | | | (_| | | |____|_| |_| +// |_____/ \___\___/| .__/ \___| \_____|\__,_|\__,_|_| \__,_| \_____| +// | | https://github.com/Neargye/scope_guard +// |_| version 0.9.1 +// +// Licensed under the MIT License . +// SPDX-License-Identifier: MIT +// Copyright (c) 2018 - 2024 Daniil Goncharov . +// +// 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. + +#ifndef NEARGYE_SCOPE_GUARD_HPP +#define NEARGYE_SCOPE_GUARD_HPP + +#define SCOPE_GUARD_VERSION_MAJOR 0 +#define SCOPE_GUARD_VERSION_MINOR 9 +#define SCOPE_GUARD_VERSION_PATCH 1 + +#include +#if (defined(_MSC_VER) && _MSC_VER >= 1900) || ((defined(__clang__) || defined(__GNUC__)) && __cplusplus >= 201700L) +#include +#endif + +// scope_guard throwable settings: +// SCOPE_GUARD_NO_THROW_CONSTRUCTIBLE requires nothrow constructible action. +// SCOPE_GUARD_MAY_THROW_ACTION action may throw exceptions. +// SCOPE_GUARD_NO_THROW_ACTION requires noexcept action. +// SCOPE_GUARD_SUPPRESS_THROW_ACTION exceptions during action will be suppressed. +// SCOPE_GUARD_CATCH_HANDLER exceptions handler. If SCOPE_GUARD_SUPPRESS_THROW_ACTIONS is not defined, it will do nothing. + +#if !defined(SCOPE_GUARD_MAY_THROW_ACTION) && !defined(SCOPE_GUARD_NO_THROW_ACTION) && !defined(SCOPE_GUARD_SUPPRESS_THROW_ACTION) +# define SCOPE_GUARD_MAY_THROW_ACTION +#elif (defined(SCOPE_GUARD_MAY_THROW_ACTION) + defined(SCOPE_GUARD_NO_THROW_ACTION) + defined(SCOPE_GUARD_SUPPRESS_THROW_ACTION)) > 1 +# error Only one of SCOPE_GUARD_MAY_THROW_ACTION and SCOPE_GUARD_NO_THROW_ACTION and SCOPE_GUARD_SUPPRESS_THROW_ACTION may be defined. +#endif + +#if !defined(SCOPE_GUARD_CATCH_HANDLER) +# define SCOPE_GUARD_CATCH_HANDLER /* Suppress exception.*/ +#endif + +namespace scope_guard { + +namespace detail { + +#if defined(SCOPE_GUARD_SUPPRESS_THROW_ACTION) && (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || (_HAS_EXCEPTIONS)) +# define NEARGYE_NOEXCEPT(...) noexcept +# define NEARGYE_TRY try { +# define NEARGYE_CATCH } catch (...) { SCOPE_GUARD_CATCH_HANDLER } +#else +# define NEARGYE_NOEXCEPT(...) noexcept(__VA_ARGS__) +# define NEARGYE_TRY +# define NEARGYE_CATCH +#endif + +#define NEARGYE_MOV(...) static_cast::type&&>(__VA_ARGS__) +#define NEARGYE_FWD(...) static_cast(__VA_ARGS__) + +// NEARGYE_NODISCARD encourages the compiler to issue a warning if the return value is discarded. +#if !defined(NEARGYE_NODISCARD) +# if defined(__clang__) +# if (__clang_major__ * 10 + __clang_minor__) >= 39 && __cplusplus >= 201703L +# define NEARGYE_NODISCARD [[nodiscard]] +# else +# define NEARGYE_NODISCARD __attribute__((__warn_unused_result__)) +# endif +# elif defined(__GNUC__) +# if __GNUC__ >= 7 && __cplusplus >= 201703L +# define NEARGYE_NODISCARD [[nodiscard]] +# else +# define NEARGYE_NODISCARD __attribute__((__warn_unused_result__)) +# endif +# elif defined(_MSC_VER) +# if _MSC_VER >= 1911 && defined(_MSVC_LANG) && _MSVC_LANG >= 201703L +# define NEARGYE_NODISCARD [[nodiscard]] +# elif defined(_Check_return_) +# define NEARGYE_NODISCARD _Check_return_ +# else +# define NEARGYE_NODISCARD +# endif +# else +# define NEARGYE_NODISCARD +# endif +#endif + +#if defined(_MSC_VER) && _MSC_VER < 1900 +inline int uncaught_exceptions() noexcept { + return *(reinterpret_cast(static_cast(static_cast(_getptd())) + (sizeof(void*) == 8 ? 0x100 : 0x90))); +} +#elif (defined(__clang__) || defined(__GNUC__)) && __cplusplus < 201700L +struct __cxa_eh_globals; +extern "C" __cxa_eh_globals* __cxa_get_globals() noexcept; +inline int uncaught_exceptions() noexcept { + return static_cast(*(reinterpret_cast(static_cast(static_cast(__cxa_get_globals())) + sizeof(void*)))); +} +#else +inline int uncaught_exceptions() noexcept { + return std::uncaught_exceptions(); +} +#endif + +class on_exit_policy { + bool execute_; + + public: + explicit on_exit_policy(bool execute) noexcept : execute_{execute} {} + + void dismiss() noexcept { + execute_ = false; + } + + bool should_execute() const noexcept { + return execute_; + } +}; + +class on_fail_policy { + int ec_; + + public: + explicit on_fail_policy(bool execute) noexcept : ec_{execute ? uncaught_exceptions() : -1} {} + + void dismiss() noexcept { + ec_ = -1; + } + + bool should_execute() const noexcept { + return ec_ != -1 && ec_ < uncaught_exceptions(); + } +}; + +class on_success_policy { + int ec_; + + public: + explicit on_success_policy(bool execute) noexcept : ec_{execute ? uncaught_exceptions() : -1} {} + + void dismiss() noexcept { + ec_ = -1; + } + + bool should_execute() const noexcept { + return ec_ != -1 && ec_ >= uncaught_exceptions(); + } +}; + +template +struct is_noarg_returns_void_action + : std::false_type {}; + +template +struct is_noarg_returns_void_action())())> + : std::true_type {}; + +template ::value> +struct is_nothrow_invocable_action + : std::false_type {}; + +template +struct is_nothrow_invocable_action + : std::integral_constant())())> {}; + +template +class scope_guard { + using A = typename std::decay::type; + + static_assert(is_noarg_returns_void_action::value, + "scope_guard requires no-argument action, that returns void."); + static_assert(std::is_same::value || std::is_same::value || std::is_same::value, + "scope_guard requires on_exit_policy, on_fail_policy or on_success_policy."); +#if defined(SCOPE_GUARD_NO_THROW_ACTION) + static_assert(is_nothrow_invocable_action::value, + "scope_guard requires noexcept invocable action."); +#endif +#if defined(SCOPE_GUARD_NO_THROW_CONSTRUCTIBLE) + static_assert(std::is_nothrow_move_constructible::value, + "scope_guard requires nothrow constructible action."); +#endif + + P policy_; + A action_; + + void* operator new(std::size_t) = delete; + void operator delete(void*) = delete; + + public: + scope_guard() = delete; + scope_guard(const scope_guard&) = delete; + scope_guard& operator=(const scope_guard&) = delete; + scope_guard& operator=(scope_guard&&) = delete; + + scope_guard(scope_guard&& other) noexcept(std::is_nothrow_move_constructible::value) + : policy_{false}, + action_{NEARGYE_MOV(other.action_)} { + policy_ = NEARGYE_MOV(other.policy_); + other.policy_.dismiss(); + } + + scope_guard(const A& action) = delete; + scope_guard(A& action) = delete; + + explicit scope_guard(A&& action) noexcept(std::is_nothrow_move_constructible::value) + : policy_{true}, + action_{NEARGYE_MOV(action)} {} + + void dismiss() noexcept { + policy_.dismiss(); + } + + ~scope_guard() NEARGYE_NOEXCEPT(is_nothrow_invocable_action::value) { + if (policy_.should_execute()) { + NEARGYE_TRY + action_(); + NEARGYE_CATCH + } + } +}; + +template +using scope_exit = scope_guard; + +template ::value, int>::type = 0> +NEARGYE_NODISCARD scope_exit make_scope_exit(F&& action) noexcept(noexcept(scope_exit{NEARGYE_FWD(action)})) { + return scope_exit{NEARGYE_FWD(action)}; +} + +template +using scope_fail = scope_guard; + +template ::value, int>::type = 0> +NEARGYE_NODISCARD scope_fail make_scope_fail(F&& action) noexcept(noexcept(scope_fail{NEARGYE_FWD(action)})) { + return scope_fail{NEARGYE_FWD(action)}; +} + +template +using scope_success = scope_guard; + +template ::value, int>::type = 0> +NEARGYE_NODISCARD scope_success make_scope_success(F&& action) noexcept(noexcept(scope_success{NEARGYE_FWD(action)})) { + return scope_success{NEARGYE_FWD(action)}; +} + +struct scope_exit_tag {}; + +template ::value, int>::type = 0> +scope_exit operator<<(scope_exit_tag, F&& action) noexcept(noexcept(scope_exit{NEARGYE_FWD(action)})) { + return scope_exit{NEARGYE_FWD(action)}; +} + +struct scope_fail_tag {}; + +template ::value, int>::type = 0> +scope_fail operator<<(scope_fail_tag, F&& action) noexcept(noexcept(scope_fail{NEARGYE_FWD(action)})) { + return scope_fail{NEARGYE_FWD(action)}; +} + +struct scope_success_tag {}; + +template ::value, int>::type = 0> +scope_success operator<<(scope_success_tag, F&& action) noexcept(noexcept(scope_success{NEARGYE_FWD(action)})) { + return scope_success{NEARGYE_FWD(action)}; +} + +#undef NEARGYE_MOV +#undef NEARGYE_FWD +#undef NEARGYE_NOEXCEPT +#undef NEARGYE_TRY +#undef NEARGYE_CATCH +#undef NEARGYE_NODISCARD + +} // namespace scope_guard::detail + +using detail::make_scope_exit; +using detail::make_scope_fail; +using detail::make_scope_success; + +} // namespace scope_guard + +// NEARGYE_MAYBE_UNUSED suppresses compiler warnings on unused entities, if any. +#if !defined(NEARGYE_MAYBE_UNUSED) +# if defined(__clang__) +# if (__clang_major__ * 10 + __clang_minor__) >= 39 && __cplusplus >= 201703L +# define NEARGYE_MAYBE_UNUSED [[maybe_unused]] +# else +# define NEARGYE_MAYBE_UNUSED __attribute__((__unused__)) +# endif +# elif defined(__GNUC__) +# if __GNUC__ >= 7 && __cplusplus >= 201703L +# define NEARGYE_MAYBE_UNUSED [[maybe_unused]] +# else +# define NEARGYE_MAYBE_UNUSED __attribute__((__unused__)) +# endif +# elif defined(_MSC_VER) +# if _MSC_VER >= 1911 && defined(_MSVC_LANG) && _MSVC_LANG >= 201703L +# define NEARGYE_MAYBE_UNUSED [[maybe_unused]] +# else +# define NEARGYE_MAYBE_UNUSED __pragma(warning(suppress : 4100 4101 4189)) +# endif +# else +# define NEARGYE_MAYBE_UNUSED +# endif +#endif + +#if !defined(NEARGYE_STR_CONCAT) +# define NEARGYE_STR_CONCAT_(s1, s2) s1##s2 +# define NEARGYE_STR_CONCAT(s1, s2) NEARGYE_STR_CONCAT_(s1, s2) +#endif + +#if !defined(NEARGYE_COUNTER) +# if defined(__COUNTER__) +# define NEARGYE_COUNTER __COUNTER__ +# elif defined(__LINE__) +# define NEARGYE_COUNTER __LINE__ +# endif +#endif + +#if defined(SCOPE_GUARD_NO_THROW_ACTION) +# define NEARGYE_MAKE_SCOPE_GUARD_ACTION [&]() noexcept -> void +#else +# define NEARGYE_MAKE_SCOPE_GUARD_ACTION [&]() -> void +#endif + +#define NEARGYE_MAKE_SCOPE_EXIT ::scope_guard::detail::scope_exit_tag{} << NEARGYE_MAKE_SCOPE_GUARD_ACTION +#define NEARGYE_MAKE_SCOPE_FAIL ::scope_guard::detail::scope_fail_tag{} << NEARGYE_MAKE_SCOPE_GUARD_ACTION +#define NEARGYE_MAKE_SCOPE_SUCCESS ::scope_guard::detail::scope_success_tag{} << NEARGYE_MAKE_SCOPE_GUARD_ACTION + +#define NEARGYE_SCOPE_GUARD_WITH_(g, i) for (int i = 1; i--; g) +#define NEARGYE_SCOPE_GUARD_WITH(g) NEARGYE_SCOPE_GUARD_WITH_(g, NEARGYE_STR_CONCAT(NEARGYE_INTERNAL_OBJECT_, NEARGYE_COUNTER)) + +// SCOPE_EXIT executing action on scope exit. +#define MAKE_SCOPE_EXIT(name) auto name = NEARGYE_MAKE_SCOPE_EXIT +#define SCOPE_EXIT NEARGYE_MAYBE_UNUSED const MAKE_SCOPE_EXIT(NEARGYE_STR_CONCAT(NEARGYE_SCOPE_EXIT_, NEARGYE_COUNTER)) +#define WITH_SCOPE_EXIT(guard) NEARGYE_SCOPE_GUARD_WITH(NEARGYE_MAKE_SCOPE_EXIT{ guard }) + +// SCOPE_FAIL executing action on scope exit when an exception has been thrown before scope exit. +#define MAKE_SCOPE_FAIL(name) auto name = NEARGYE_MAKE_SCOPE_FAIL +#define SCOPE_FAIL NEARGYE_MAYBE_UNUSED const MAKE_SCOPE_FAIL(NEARGYE_STR_CONCAT(NEARGYE_SCOPE_FAIL_, NEARGYE_COUNTER)) +#define WITH_SCOPE_FAIL(guard) NEARGYE_SCOPE_GUARD_WITH(NEARGYE_MAKE_SCOPE_FAIL{ guard }) + +// SCOPE_SUCCESS executing action on scope exit when no exceptions have been thrown before scope exit. +#define MAKE_SCOPE_SUCCESS(name) auto name = NEARGYE_MAKE_SCOPE_SUCCESS +#define SCOPE_SUCCESS NEARGYE_MAYBE_UNUSED const MAKE_SCOPE_SUCCESS(NEARGYE_STR_CONCAT(NEARGYE_SCOPE_SUCCESS_, NEARGYE_COUNTER)) +#define WITH_SCOPE_SUCCESS(guard) NEARGYE_SCOPE_GUARD_WITH(NEARGYE_MAKE_SCOPE_SUCCESS{ guard }) + +// DEFER executing action on scope exit. +#define MAKE_DEFER(name) MAKE_SCOPE_EXIT(name) +#define DEFER SCOPE_EXIT +#define WITH_DEFER(guard) WITH_SCOPE_EXIT(guard) + +#endif // NEARGYE_SCOPE_GUARD_HPP diff --git a/MasterHide/thirdparty/scope_guard/test/3rdparty/Catch2/LICENSE b/MasterHide/thirdparty/scope_guard/test/3rdparty/Catch2/LICENSE new file mode 100644 index 0000000..36b7cd9 --- /dev/null +++ b/MasterHide/thirdparty/scope_guard/test/3rdparty/Catch2/LICENSE @@ -0,0 +1,23 @@ +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +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, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN 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/MasterHide/thirdparty/scope_guard/test/3rdparty/Catch2/catch.hpp b/MasterHide/thirdparty/scope_guard/test/3rdparty/Catch2/catch.hpp new file mode 100644 index 0000000..9c1c854 --- /dev/null +++ b/MasterHide/thirdparty/scope_guard/test/3rdparty/Catch2/catch.hpp @@ -0,0 +1,17937 @@ +/* + * Catch v2.13.5 + * Generated: 2021-04-10 23:43:17.560525 + * ---------------------------------------------------------- + * This file has been merged from multiple headers. Please don't edit it directly + * Copyright (c) 2021 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED +#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED +// start catch.hpp + + +#define CATCH_VERSION_MAJOR 2 +#define CATCH_VERSION_MINOR 13 +#define CATCH_VERSION_PATCH 5 + +#ifdef __clang__ +# pragma clang system_header +#elif defined __GNUC__ +# pragma GCC system_header +#endif + +// start catch_suppress_warnings.h + +#ifdef __clang__ +# ifdef __ICC // icpc defines the __clang__ macro +# pragma warning(push) +# pragma warning(disable: 161 1682) +# else // __ICC +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wpadded" +# pragma clang diagnostic ignored "-Wswitch-enum" +# pragma clang diagnostic ignored "-Wcovered-switch-default" +# endif +#elif defined __GNUC__ + // Because REQUIREs trigger GCC's -Wparentheses, and because still + // supported version of g++ have only buggy support for _Pragmas, + // Wparentheses have to be suppressed globally. +# pragma GCC diagnostic ignored "-Wparentheses" // See #674 for details + +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wunused-variable" +# pragma GCC diagnostic ignored "-Wpadded" +#endif +// end catch_suppress_warnings.h +#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER) +# define CATCH_IMPL +# define CATCH_CONFIG_ALL_PARTS +#endif + +// In the impl file, we want to have access to all parts of the headers +// Can also be used to sanely support PCHs +#if defined(CATCH_CONFIG_ALL_PARTS) +# define CATCH_CONFIG_EXTERNAL_INTERFACES +# if defined(CATCH_CONFIG_DISABLE_MATCHERS) +# undef CATCH_CONFIG_DISABLE_MATCHERS +# endif +# if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER) +# define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER +# endif +#endif + +#if !defined(CATCH_CONFIG_IMPL_ONLY) +// start catch_platform.h + +// See e.g.: +// https://opensource.apple.com/source/CarbonHeaders/CarbonHeaders-18.1/TargetConditionals.h.auto.html +#ifdef __APPLE__ +# include +# if (defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1) || \ + (defined(TARGET_OS_MAC) && TARGET_OS_MAC == 1) +# define CATCH_PLATFORM_MAC +# elif (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE == 1) +# define CATCH_PLATFORM_IPHONE +# endif + +#elif defined(linux) || defined(__linux) || defined(__linux__) +# define CATCH_PLATFORM_LINUX + +#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__) +# define CATCH_PLATFORM_WINDOWS +#endif + +// end catch_platform.h + +#ifdef CATCH_IMPL +# ifndef CLARA_CONFIG_MAIN +# define CLARA_CONFIG_MAIN_NOT_DEFINED +# define CLARA_CONFIG_MAIN +# endif +#endif + +// start catch_user_interfaces.h + +namespace Catch { + unsigned int rngSeed(); +} + +// end catch_user_interfaces.h +// start catch_tag_alias_autoregistrar.h + +// start catch_common.h + +// start catch_compiler_capabilities.h + +// Detect a number of compiler features - by compiler +// The following features are defined: +// +// CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported? +// CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported? +// CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported? +// CATCH_CONFIG_DISABLE_EXCEPTIONS : Are exceptions enabled? +// **************** +// Note to maintainers: if new toggles are added please document them +// in configuration.md, too +// **************** + +// In general each macro has a _NO_ form +// (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature. +// Many features, at point of detection, define an _INTERNAL_ macro, so they +// can be combined, en-mass, with the _NO_ forms later. + +#ifdef __cplusplus + +# if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L) +# define CATCH_CPP14_OR_GREATER +# endif + +# if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) +# define CATCH_CPP17_OR_GREATER +# endif + +#endif + +// Only GCC compiler should be used in this block, so other compilers trying to +// mask themselves as GCC should be ignored. +#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && !defined(__CUDACC__) && !defined(__LCC__) +# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic push" ) +# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic pop" ) + +# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) + +#endif + +#if defined(__clang__) + +# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic push" ) +# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic pop" ) + +// As of this writing, IBM XL's implementation of __builtin_constant_p has a bug +// which results in calls to destructors being emitted for each temporary, +// without a matching initialization. In practice, this can result in something +// like `std::string::~string` being called on an uninitialized value. +// +// For example, this code will likely segfault under IBM XL: +// ``` +// REQUIRE(std::string("12") + "34" == "1234") +// ``` +// +// Therefore, `CATCH_INTERNAL_IGNORE_BUT_WARN` is not implemented. +# if !defined(__ibmxl__) && !defined(__CUDACC__) +# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) /* NOLINT(cppcoreguidelines-pro-type-vararg, hicpp-vararg) */ +# endif + +# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \ + _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"") + +# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wparentheses\"" ) + +# define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" ) + +# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"" ) + +# define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wunused-template\"" ) + +#endif // __clang__ + +//////////////////////////////////////////////////////////////////////////////// +// Assume that non-Windows platforms support posix signals by default +#if !defined(CATCH_PLATFORM_WINDOWS) + #define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS +#endif + +//////////////////////////////////////////////////////////////////////////////// +// We know some environments not to support full POSIX signals +#if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__) + #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS +#endif + +#ifdef __OS400__ +# define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS +# define CATCH_CONFIG_COLOUR_NONE +#endif + +//////////////////////////////////////////////////////////////////////////////// +// Android somehow still does not support std::to_string +#if defined(__ANDROID__) +# define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING +# define CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE +#endif + +//////////////////////////////////////////////////////////////////////////////// +// Not all Windows environments support SEH properly +#if defined(__MINGW32__) +# define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH +#endif + +//////////////////////////////////////////////////////////////////////////////// +// PS4 +#if defined(__ORBIS__) +# define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE +#endif + +//////////////////////////////////////////////////////////////////////////////// +// Cygwin +#ifdef __CYGWIN__ + +// Required for some versions of Cygwin to declare gettimeofday +// see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin +# define _BSD_SOURCE +// some versions of cygwin (most) do not support std::to_string. Use the libstd check. +// https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a01053_source.html line 2812-2813 +# if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \ + && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF)) + +# define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING + +# endif +#endif // __CYGWIN__ + +//////////////////////////////////////////////////////////////////////////////// +// Visual C++ +#if defined(_MSC_VER) + +# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) ) +# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma( warning(pop) ) + +// Universal Windows platform does not support SEH +// Or console colours (or console at all...) +# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) +# define CATCH_CONFIG_COLOUR_NONE +# else +# define CATCH_INTERNAL_CONFIG_WINDOWS_SEH +# endif + +// MSVC traditional preprocessor needs some workaround for __VA_ARGS__ +// _MSVC_TRADITIONAL == 0 means new conformant preprocessor +// _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor +# if !defined(__clang__) // Handle Clang masquerading for msvc +# if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL) +# define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +# endif // MSVC_TRADITIONAL +# endif // __clang__ + +#endif // _MSC_VER + +#if defined(_REENTRANT) || defined(_MSC_VER) +// Enable async processing, as -pthread is specified or no additional linking is required +# define CATCH_INTERNAL_CONFIG_USE_ASYNC +#endif // _MSC_VER + +//////////////////////////////////////////////////////////////////////////////// +// Check if we are compiled with -fno-exceptions or equivalent +#if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND) +# define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED +#endif + +//////////////////////////////////////////////////////////////////////////////// +// DJGPP +#ifdef __DJGPP__ +# define CATCH_INTERNAL_CONFIG_NO_WCHAR +#endif // __DJGPP__ + +//////////////////////////////////////////////////////////////////////////////// +// Embarcadero C++Build +#if defined(__BORLANDC__) + #define CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN +#endif + +//////////////////////////////////////////////////////////////////////////////// + +// Use of __COUNTER__ is suppressed during code analysis in +// CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly +// handled by it. +// Otherwise all supported compilers support COUNTER macro, +// but user still might want to turn it off +#if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L ) + #define CATCH_INTERNAL_CONFIG_COUNTER +#endif + +//////////////////////////////////////////////////////////////////////////////// + +// RTX is a special version of Windows that is real time. +// This means that it is detected as Windows, but does not provide +// the same set of capabilities as real Windows does. +#if defined(UNDER_RTSS) || defined(RTX64_BUILD) + #define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH + #define CATCH_INTERNAL_CONFIG_NO_ASYNC + #define CATCH_CONFIG_COLOUR_NONE +#endif + +#if !defined(_GLIBCXX_USE_C99_MATH_TR1) +#define CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER +#endif + +// Various stdlib support checks that require __has_include +#if defined(__has_include) + // Check if string_view is available and usable + #if __has_include() && defined(CATCH_CPP17_OR_GREATER) + # define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW + #endif + + // Check if optional is available and usable + # if __has_include() && defined(CATCH_CPP17_OR_GREATER) + # define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL + # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) + + // Check if byte is available and usable + # if __has_include() && defined(CATCH_CPP17_OR_GREATER) + # include + # if __cpp_lib_byte > 0 + # define CATCH_INTERNAL_CONFIG_CPP17_BYTE + # endif + # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) + + // Check if variant is available and usable + # if __has_include() && defined(CATCH_CPP17_OR_GREATER) + # if defined(__clang__) && (__clang_major__ < 8) + // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852 + // fix should be in clang 8, workaround in libstdc++ 8.2 + # include + # if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9) + # define CATCH_CONFIG_NO_CPP17_VARIANT + # else + # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT + # endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9) + # else + # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT + # endif // defined(__clang__) && (__clang_major__ < 8) + # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) +#endif // defined(__has_include) + +#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER) +# define CATCH_CONFIG_COUNTER +#endif +#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH) && !defined(CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH) +# define CATCH_CONFIG_WINDOWS_SEH +#endif +// This is set by default, because we assume that unix compilers are posix-signal-compatible by default. +#if defined(CATCH_INTERNAL_CONFIG_POSIX_SIGNALS) && !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS) +# define CATCH_CONFIG_POSIX_SIGNALS +#endif +// This is set by default, because we assume that compilers with no wchar_t support are just rare exceptions. +#if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR) +# define CATCH_CONFIG_WCHAR +#endif + +#if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING) +# define CATCH_CONFIG_CPP11_TO_STRING +#endif + +#if defined(CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_NO_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_CPP17_OPTIONAL) +# define CATCH_CONFIG_CPP17_OPTIONAL +#endif + +#if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW) +# define CATCH_CONFIG_CPP17_STRING_VIEW +#endif + +#if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && !defined(CATCH_CONFIG_CPP17_VARIANT) +# define CATCH_CONFIG_CPP17_VARIANT +#endif + +#if defined(CATCH_INTERNAL_CONFIG_CPP17_BYTE) && !defined(CATCH_CONFIG_NO_CPP17_BYTE) && !defined(CATCH_CONFIG_CPP17_BYTE) +# define CATCH_CONFIG_CPP17_BYTE +#endif + +#if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT) +# define CATCH_INTERNAL_CONFIG_NEW_CAPTURE +#endif + +#if defined(CATCH_INTERNAL_CONFIG_NEW_CAPTURE) && !defined(CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NEW_CAPTURE) +# define CATCH_CONFIG_NEW_CAPTURE +#endif + +#if !defined(CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) +# define CATCH_CONFIG_DISABLE_EXCEPTIONS +#endif + +#if defined(CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_NO_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_POLYFILL_ISNAN) +# define CATCH_CONFIG_POLYFILL_ISNAN +#endif + +#if defined(CATCH_INTERNAL_CONFIG_USE_ASYNC) && !defined(CATCH_INTERNAL_CONFIG_NO_ASYNC) && !defined(CATCH_CONFIG_NO_USE_ASYNC) && !defined(CATCH_CONFIG_USE_ASYNC) +# define CATCH_CONFIG_USE_ASYNC +#endif + +#if defined(CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_NO_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_ANDROID_LOGWRITE) +# define CATCH_CONFIG_ANDROID_LOGWRITE +#endif + +#if defined(CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_NO_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_GLOBAL_NEXTAFTER) +# define CATCH_CONFIG_GLOBAL_NEXTAFTER +#endif + +// Even if we do not think the compiler has that warning, we still have +// to provide a macro that can be used by the code. +#if !defined(CATCH_INTERNAL_START_WARNINGS_SUPPRESSION) +# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION +#endif +#if !defined(CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION) +# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION +#endif +#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS +#endif +#if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS +#endif +#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS +#endif +#if !defined(CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS +#endif + +// The goal of this macro is to avoid evaluation of the arguments, but +// still have the compiler warn on problems inside... +#if !defined(CATCH_INTERNAL_IGNORE_BUT_WARN) +# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) +#endif + +#if defined(__APPLE__) && defined(__apple_build_version__) && (__clang_major__ < 10) +# undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS +#elif defined(__clang__) && (__clang_major__ < 5) +# undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS +#endif + +#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS +#endif + +#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) +#define CATCH_TRY if ((true)) +#define CATCH_CATCH_ALL if ((false)) +#define CATCH_CATCH_ANON(type) if ((false)) +#else +#define CATCH_TRY try +#define CATCH_CATCH_ALL catch (...) +#define CATCH_CATCH_ANON(type) catch (type) +#endif + +#if defined(CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_NO_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) +#define CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +#endif + +// end catch_compiler_capabilities.h +#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line +#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) +#ifdef CATCH_CONFIG_COUNTER +# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ ) +#else +# define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ ) +#endif + +#include +#include +#include + +// We need a dummy global operator<< so we can bring it into Catch namespace later +struct Catch_global_namespace_dummy {}; +std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy); + +namespace Catch { + + struct CaseSensitive { enum Choice { + Yes, + No + }; }; + + class NonCopyable { + NonCopyable( NonCopyable const& ) = delete; + NonCopyable( NonCopyable && ) = delete; + NonCopyable& operator = ( NonCopyable const& ) = delete; + NonCopyable& operator = ( NonCopyable && ) = delete; + + protected: + NonCopyable(); + virtual ~NonCopyable(); + }; + + struct SourceLineInfo { + + SourceLineInfo() = delete; + SourceLineInfo( char const* _file, std::size_t _line ) noexcept + : file( _file ), + line( _line ) + {} + + SourceLineInfo( SourceLineInfo const& other ) = default; + SourceLineInfo& operator = ( SourceLineInfo const& ) = default; + SourceLineInfo( SourceLineInfo&& ) noexcept = default; + SourceLineInfo& operator = ( SourceLineInfo&& ) noexcept = default; + + bool empty() const noexcept { return file[0] == '\0'; } + bool operator == ( SourceLineInfo const& other ) const noexcept; + bool operator < ( SourceLineInfo const& other ) const noexcept; + + char const* file; + std::size_t line; + }; + + std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ); + + // Bring in operator<< from global namespace into Catch namespace + // This is necessary because the overload of operator<< above makes + // lookup stop at namespace Catch + using ::operator<<; + + // Use this in variadic streaming macros to allow + // >> +StreamEndStop + // as well as + // >> stuff +StreamEndStop + struct StreamEndStop { + std::string operator+() const; + }; + template + T const& operator + ( T const& value, StreamEndStop ) { + return value; + } +} + +#define CATCH_INTERNAL_LINEINFO \ + ::Catch::SourceLineInfo( __FILE__, static_cast( __LINE__ ) ) + +// end catch_common.h +namespace Catch { + + struct RegistrarForTagAliases { + RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ); + }; + +} // end namespace Catch + +#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) \ + CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \ + CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION + +// end catch_tag_alias_autoregistrar.h +// start catch_test_registry.h + +// start catch_interfaces_testcase.h + +#include + +namespace Catch { + + class TestSpec; + + struct ITestInvoker { + virtual void invoke () const = 0; + virtual ~ITestInvoker(); + }; + + class TestCase; + struct IConfig; + + struct ITestCaseRegistry { + virtual ~ITestCaseRegistry(); + virtual std::vector const& getAllTests() const = 0; + virtual std::vector const& getAllTestsSorted( IConfig const& config ) const = 0; + }; + + bool isThrowSafe( TestCase const& testCase, IConfig const& config ); + bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ); + std::vector filterTests( std::vector const& testCases, TestSpec const& testSpec, IConfig const& config ); + std::vector const& getAllTestCasesSorted( IConfig const& config ); + +} + +// end catch_interfaces_testcase.h +// start catch_stringref.h + +#include +#include +#include +#include + +namespace Catch { + + /// A non-owning string class (similar to the forthcoming std::string_view) + /// Note that, because a StringRef may be a substring of another string, + /// it may not be null terminated. + class StringRef { + public: + using size_type = std::size_t; + using const_iterator = const char*; + + private: + static constexpr char const* const s_empty = ""; + + char const* m_start = s_empty; + size_type m_size = 0; + + public: // construction + constexpr StringRef() noexcept = default; + + StringRef( char const* rawChars ) noexcept; + + constexpr StringRef( char const* rawChars, size_type size ) noexcept + : m_start( rawChars ), + m_size( size ) + {} + + StringRef( std::string const& stdString ) noexcept + : m_start( stdString.c_str() ), + m_size( stdString.size() ) + {} + + explicit operator std::string() const { + return std::string(m_start, m_size); + } + + public: // operators + auto operator == ( StringRef const& other ) const noexcept -> bool; + auto operator != (StringRef const& other) const noexcept -> bool { + return !(*this == other); + } + + auto operator[] ( size_type index ) const noexcept -> char { + assert(index < m_size); + return m_start[index]; + } + + public: // named queries + constexpr auto empty() const noexcept -> bool { + return m_size == 0; + } + constexpr auto size() const noexcept -> size_type { + return m_size; + } + + // Returns the current start pointer. If the StringRef is not + // null-terminated, throws std::domain_exception + auto c_str() const -> char const*; + + public: // substrings and searches + // Returns a substring of [start, start + length). + // If start + length > size(), then the substring is [start, size()). + // If start > size(), then the substring is empty. + auto substr( size_type start, size_type length ) const noexcept -> StringRef; + + // Returns the current start pointer. May not be null-terminated. + auto data() const noexcept -> char const*; + + constexpr auto isNullTerminated() const noexcept -> bool { + return m_start[m_size] == '\0'; + } + + public: // iterators + constexpr const_iterator begin() const { return m_start; } + constexpr const_iterator end() const { return m_start + m_size; } + }; + + auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&; + auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&; + + constexpr auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef { + return StringRef( rawChars, size ); + } +} // namespace Catch + +constexpr auto operator "" _catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef { + return Catch::StringRef( rawChars, size ); +} + +// end catch_stringref.h +// start catch_preprocessor.hpp + + +#define CATCH_RECURSION_LEVEL0(...) __VA_ARGS__ +#define CATCH_RECURSION_LEVEL1(...) CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(__VA_ARGS__))) +#define CATCH_RECURSION_LEVEL2(...) CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(__VA_ARGS__))) +#define CATCH_RECURSION_LEVEL3(...) CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(__VA_ARGS__))) +#define CATCH_RECURSION_LEVEL4(...) CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(__VA_ARGS__))) +#define CATCH_RECURSION_LEVEL5(...) CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(__VA_ARGS__))) + +#ifdef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +#define INTERNAL_CATCH_EXPAND_VARGS(...) __VA_ARGS__ +// MSVC needs more evaluations +#define CATCH_RECURSION_LEVEL6(...) CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(__VA_ARGS__))) +#define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL6(CATCH_RECURSION_LEVEL6(__VA_ARGS__)) +#else +#define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL5(__VA_ARGS__) +#endif + +#define CATCH_REC_END(...) +#define CATCH_REC_OUT + +#define CATCH_EMPTY() +#define CATCH_DEFER(id) id CATCH_EMPTY() + +#define CATCH_REC_GET_END2() 0, CATCH_REC_END +#define CATCH_REC_GET_END1(...) CATCH_REC_GET_END2 +#define CATCH_REC_GET_END(...) CATCH_REC_GET_END1 +#define CATCH_REC_NEXT0(test, next, ...) next CATCH_REC_OUT +#define CATCH_REC_NEXT1(test, next) CATCH_DEFER ( CATCH_REC_NEXT0 ) ( test, next, 0) +#define CATCH_REC_NEXT(test, next) CATCH_REC_NEXT1(CATCH_REC_GET_END test, next) + +#define CATCH_REC_LIST0(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ ) +#define CATCH_REC_LIST1(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0) ) ( f, peek, __VA_ARGS__ ) +#define CATCH_REC_LIST2(f, x, peek, ...) f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ ) + +#define CATCH_REC_LIST0_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ ) +#define CATCH_REC_LIST1_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0_UD) ) ( f, userdata, peek, __VA_ARGS__ ) +#define CATCH_REC_LIST2_UD(f, userdata, x, peek, ...) f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ ) + +// Applies the function macro `f` to each of the remaining parameters, inserts commas between the results, +// and passes userdata as the first parameter to each invocation, +// e.g. CATCH_REC_LIST_UD(f, x, a, b, c) evaluates to f(x, a), f(x, b), f(x, c) +#define CATCH_REC_LIST_UD(f, userdata, ...) CATCH_RECURSE(CATCH_REC_LIST2_UD(f, userdata, __VA_ARGS__, ()()(), ()()(), ()()(), 0)) + +#define CATCH_REC_LIST(f, ...) CATCH_RECURSE(CATCH_REC_LIST2(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0)) + +#define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param) +#define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__ +#define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__ +#define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF +#define INTERNAL_CATCH_STRINGIZE(...) INTERNAL_CATCH_STRINGIZE2(__VA_ARGS__) +#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +#define INTERNAL_CATCH_STRINGIZE2(...) #__VA_ARGS__ +#define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) +#else +// MSVC is adding extra space and needs another indirection to expand INTERNAL_CATCH_NOINTERNAL_CATCH_DEF +#define INTERNAL_CATCH_STRINGIZE2(...) INTERNAL_CATCH_STRINGIZE3(__VA_ARGS__) +#define INTERNAL_CATCH_STRINGIZE3(...) #__VA_ARGS__ +#define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) (INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) + 1) +#endif + +#define INTERNAL_CATCH_MAKE_NAMESPACE2(...) ns_##__VA_ARGS__ +#define INTERNAL_CATCH_MAKE_NAMESPACE(name) INTERNAL_CATCH_MAKE_NAMESPACE2(name) + +#define INTERNAL_CATCH_REMOVE_PARENS(...) INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF __VA_ARGS__) + +#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) decltype(get_wrapper()) +#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)) +#else +#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) INTERNAL_CATCH_EXPAND_VARGS(decltype(get_wrapper())) +#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))) +#endif + +#define INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(...)\ + CATCH_REC_LIST(INTERNAL_CATCH_MAKE_TYPE_LIST,__VA_ARGS__) + +#define INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_0) INTERNAL_CATCH_REMOVE_PARENS(_0) +#define INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_0, _1) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_1) +#define INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_0, _1, _2) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_1, _2) +#define INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_0, _1, _2, _3) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_1, _2, _3) +#define INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_0, _1, _2, _3, _4) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_1, _2, _3, _4) +#define INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_0, _1, _2, _3, _4, _5) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_1, _2, _3, _4, _5) +#define INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_0, _1, _2, _3, _4, _5, _6) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_1, _2, _3, _4, _5, _6) +#define INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_0, _1, _2, _3, _4, _5, _6, _7) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_1, _2, _3, _4, _5, _6, _7) +#define INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_1, _2, _3, _4, _5, _6, _7, _8) +#define INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9) +#define INTERNAL_CATCH_REMOVE_PARENS_11_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10) + +#define INTERNAL_CATCH_VA_NARGS_IMPL(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N + +#define INTERNAL_CATCH_TYPE_GEN\ + template struct TypeList {};\ + template\ + constexpr auto get_wrapper() noexcept -> TypeList { return {}; }\ + template class...> struct TemplateTypeList{};\ + template class...Cs>\ + constexpr auto get_wrapper() noexcept -> TemplateTypeList { return {}; }\ + template\ + struct append;\ + template\ + struct rewrap;\ + template class, typename...>\ + struct create;\ + template class, typename>\ + struct convert;\ + \ + template \ + struct append { using type = T; };\ + template< template class L1, typename...E1, template class L2, typename...E2, typename...Rest>\ + struct append, L2, Rest...> { using type = typename append, Rest...>::type; };\ + template< template class L1, typename...E1, typename...Rest>\ + struct append, TypeList, Rest...> { using type = L1; };\ + \ + template< template class Container, template class List, typename...elems>\ + struct rewrap, List> { using type = TypeList>; };\ + template< template class Container, template class List, class...Elems, typename...Elements>\ + struct rewrap, List, Elements...> { using type = typename append>, typename rewrap, Elements...>::type>::type; };\ + \ + template