Full Code of AdamOron/PatchGuardBypass for AI

master 125aaf881e50 cached
19 files
46.3 KB
13.8k tokens
50 symbols
1 requests
Download .txt
Repository: AdamOron/PatchGuardBypass
Branch: master
Commit: 125aaf881e50
Files: 19
Total size: 46.3 KB

Directory structure:
gitextract_yx0qudfh/

├── .gitignore
├── PatchGuardBypass/
│   ├── PatchGuardBypass.inf
│   ├── PatchGuardBypass.vcxproj
│   ├── PatchGuardBypass.vcxproj.filters
│   └── src/
│       ├── core/
│       │   ├── PatchGuard.h
│       │   ├── features/
│       │   │   ├── Disable.cpp
│       │   │   ├── Evade.cpp
│       │   │   └── Verify.cpp
│       │   ├── flows/
│       │   │   ├── Flows.cpp
│       │   │   └── Flows.h
│       │   ├── symbols/
│       │   │   ├── Globals.cpp
│       │   │   ├── Globals.h
│       │   │   ├── Offsets.cpp
│       │   │   └── Offsets.h
│       │   └── timers/
│       │       ├── Timer.cpp
│       │       └── Timer.h
│       └── main.cpp
├── PatchGuardBypass.sln
└── README.md

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
## 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

# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates

# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs

# Mono auto generated files
mono_crash.*

# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[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
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.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
*.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


================================================
FILE: PatchGuardBypass/PatchGuardBypass.inf
================================================
;
; PatchGuardBypass.inf
;

[Version]
Signature="$WINDOWS NT$"
Class=Sample ; TODO: edit Class
ClassGuid={78A1C341-4539-11d3-B88D-00C04FAD5171} ; TODO: edit ClassGuid
Provider=%ManufacturerName%
CatalogFile=PatchGuardBypass.cat
DriverVer= ; TODO: set DriverVer in stampinf property pages
PnpLockDown=1

[DestinationDirs]
DefaultDestDir = 12
PatchGuardBypass_Device_CoInstaller_CopyFiles = 11

; ================= Class section =====================

[ClassInstall32]
Addreg=SampleClassReg

[SampleClassReg]
HKR,,,0,%ClassName%
HKR,,Icon,,-5

[SourceDisksNames]
1 = %DiskName%,,,""

[SourceDisksFiles]
PatchGuardBypass.sys  = 1,,
WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll=1 ; make sure the number matches with SourceDisksNames

;*****************************************
; Install Section
;*****************************************

[Manufacturer]
%ManufacturerName%=Standard,NT$ARCH$

[Standard.NT$ARCH$]
%PatchGuardBypass.DeviceDesc%=PatchGuardBypass_Device, Root\PatchGuardBypass ; TODO: edit hw-id

[PatchGuardBypass_Device.NT]
CopyFiles=Drivers_Dir

[Drivers_Dir]
PatchGuardBypass.sys

;-------------- Service installation
[PatchGuardBypass_Device.NT.Services]
AddService = PatchGuardBypass,%SPSVCINST_ASSOCSERVICE%, PatchGuardBypass_Service_Inst

; -------------- PatchGuardBypass driver install sections
[PatchGuardBypass_Service_Inst]
DisplayName    = %PatchGuardBypass.SVCDESC%
ServiceType    = 1               ; SERVICE_KERNEL_DRIVER
StartType      = 3               ; SERVICE_DEMAND_START
ErrorControl   = 1               ; SERVICE_ERROR_NORMAL
ServiceBinary  = %12%\PatchGuardBypass.sys

;
;--- PatchGuardBypass_Device Coinstaller installation ------
;

[PatchGuardBypass_Device.NT.CoInstallers]
AddReg=PatchGuardBypass_Device_CoInstaller_AddReg
CopyFiles=PatchGuardBypass_Device_CoInstaller_CopyFiles

[PatchGuardBypass_Device_CoInstaller_AddReg]
HKR,,CoInstallers32,0x00010000, "WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll,WdfCoInstaller"

[PatchGuardBypass_Device_CoInstaller_CopyFiles]
WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll

[PatchGuardBypass_Device.NT.Wdf]
KmdfService =  PatchGuardBypass, PatchGuardBypass_wdfsect
[PatchGuardBypass_wdfsect]
KmdfLibraryVersion = $KMDFVERSION$

[Strings]
SPSVCINST_ASSOCSERVICE= 0x00000002
ManufacturerName="<Your manufacturer name>" ;TODO: Replace with your manufacturer name
ClassName="Samples" ; TODO: edit ClassName
DiskName = "PatchGuardBypass Installation Disk"
PatchGuardBypass.DeviceDesc = "PatchGuardBypass Device"
PatchGuardBypass.SVCDESC = "PatchGuardBypass Service"


================================================
FILE: PatchGuardBypass/PatchGuardBypass.vcxproj
================================================
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup Label="ProjectConfigurations">
    <ProjectConfiguration Include="Debug|Win32">
      <Configuration>Debug</Configuration>
      <Platform>Win32</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release|Win32">
      <Configuration>Release</Configuration>
      <Platform>Win32</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Debug|x64">
      <Configuration>Debug</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release|x64">
      <Configuration>Release</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Debug|ARM">
      <Configuration>Debug</Configuration>
      <Platform>ARM</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release|ARM">
      <Configuration>Release</Configuration>
      <Platform>ARM</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Debug|ARM64">
      <Configuration>Debug</Configuration>
      <Platform>ARM64</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release|ARM64">
      <Configuration>Release</Configuration>
      <Platform>ARM64</Platform>
    </ProjectConfiguration>
  </ItemGroup>
  <PropertyGroup Label="Globals">
    <ProjectGuid>{57A68F53-C563-405D-B2E1-C66585DA64E4}</ProjectGuid>
    <TemplateGuid>{1bc93793-694f-48fe-9372-81e2b05556fd}</TemplateGuid>
    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
    <MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion>
    <Configuration>Debug</Configuration>
    <Platform Condition="'$(Platform)' == ''">Win32</Platform>
    <RootNamespace>PatchGuardBypass</RootNamespace>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
    <TargetVersion>Windows10</TargetVersion>
    <UseDebugLibraries>true</UseDebugLibraries>
    <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
    <ConfigurationType>Driver</ConfigurationType>
    <DriverType>KMDF</DriverType>
    <DriverTargetPlatform>Universal</DriverTargetPlatform>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
    <TargetVersion>Windows10</TargetVersion>
    <UseDebugLibraries>false</UseDebugLibraries>
    <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
    <ConfigurationType>Driver</ConfigurationType>
    <DriverType>KMDF</DriverType>
    <DriverTargetPlatform>Universal</DriverTargetPlatform>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
    <TargetVersion>Windows10</TargetVersion>
    <UseDebugLibraries>true</UseDebugLibraries>
    <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
    <ConfigurationType>Driver</ConfigurationType>
    <DriverType>KMDF</DriverType>
    <DriverTargetPlatform>Universal</DriverTargetPlatform>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
    <TargetVersion>Windows10</TargetVersion>
    <UseDebugLibraries>false</UseDebugLibraries>
    <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
    <ConfigurationType>Driver</ConfigurationType>
    <DriverType>KMDF</DriverType>
    <DriverTargetPlatform>Universal</DriverTargetPlatform>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
    <TargetVersion>Windows10</TargetVersion>
    <UseDebugLibraries>true</UseDebugLibraries>
    <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
    <ConfigurationType>Driver</ConfigurationType>
    <DriverType>KMDF</DriverType>
    <DriverTargetPlatform>Universal</DriverTargetPlatform>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
    <TargetVersion>Windows10</TargetVersion>
    <UseDebugLibraries>false</UseDebugLibraries>
    <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
    <ConfigurationType>Driver</ConfigurationType>
    <DriverType>KMDF</DriverType>
    <DriverTargetPlatform>Universal</DriverTargetPlatform>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
    <TargetVersion>Windows10</TargetVersion>
    <UseDebugLibraries>true</UseDebugLibraries>
    <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
    <ConfigurationType>Driver</ConfigurationType>
    <DriverType>KMDF</DriverType>
    <DriverTargetPlatform>Universal</DriverTargetPlatform>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
    <TargetVersion>Windows10</TargetVersion>
    <UseDebugLibraries>false</UseDebugLibraries>
    <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
    <ConfigurationType>Driver</ConfigurationType>
    <DriverType>KMDF</DriverType>
    <DriverTargetPlatform>Universal</DriverTargetPlatform>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
  <ImportGroup Label="ExtensionSettings">
  </ImportGroup>
  <ImportGroup Label="PropertySheets">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  </ImportGroup>
  <PropertyGroup Label="UserMacros" />
  <PropertyGroup />
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
    <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
    <Inf2CatUseLocalTime>true</Inf2CatUseLocalTime>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
    <Inf2CatUseLocalTime>true</Inf2CatUseLocalTime>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
    <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
    <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
    <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
    <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
  </PropertyGroup>
  <ItemGroup>
    <Inf Include="PatchGuardBypass.inf" />
  </ItemGroup>
  <ItemGroup>
    <FilesToPackage Include="$(TargetPath)" />
  </ItemGroup>
  <ItemGroup>
    <ClCompile Include="src\core\features\Disable.cpp" />
    <ClCompile Include="src\core\features\Evade.cpp" />
    <ClCompile Include="src\core\flows\Flows.cpp" />
    <ClCompile Include="src\core\symbols\Globals.cpp" />
    <ClCompile Include="src\core\symbols\Offsets.cpp" />
    <ClCompile Include="src\utils\log\Log.cpp" />
    <ClCompile Include="src\main.cpp" />
    <ClCompile Include="src\core\timers\Timer.cpp" />
    <ClCompile Include="src\core\features\Verify.cpp" />
  </ItemGroup>
  <ItemGroup>
    <ClInclude Include="src\core\flows\Flows.h" />
    <ClInclude Include="src\core\symbols\Globals.h" />
    <ClInclude Include="src\utils\log\Log.h" />
    <ClInclude Include="src\core\PatchGuard.h" />
    <ClInclude Include="src\core\timers\Timer.h" />
    <ClInclude Include="src\core\symbols\Offsets.h" />
  </ItemGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
  <ImportGroup Label="ExtensionTargets">
  </ImportGroup>
</Project>

================================================
FILE: PatchGuardBypass/PatchGuardBypass.vcxproj.filters
================================================
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup>
    <Filter Include="Source Files">
      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
    </Filter>
    <Filter Include="Header Files">
      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
    </Filter>
    <Filter Include="Resource Files">
      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
    </Filter>
    <Filter Include="Driver Files">
      <UniqueIdentifier>{8E41214B-6785-4CFE-B992-037D68949A14}</UniqueIdentifier>
      <Extensions>inf;inv;inx;mof;mc;</Extensions>
    </Filter>
  </ItemGroup>
  <ItemGroup>
    <Inf Include="PatchGuardBypass.inf">
      <Filter>Driver Files</Filter>
    </Inf>
  </ItemGroup>
  <ItemGroup>
    <ClCompile Include="src\main.cpp">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="src\utils\log\Log.cpp">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="src\core\timers\Timer.cpp">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="src\core\features\Disable.cpp">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="src\core\flows\Flows.cpp">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="src\core\features\Evade.cpp">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="src\core\features\Verify.cpp">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="src\core\symbols\Globals.cpp">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="src\core\symbols\Offsets.cpp">
      <Filter>Source Files</Filter>
    </ClCompile>
  </ItemGroup>
  <ItemGroup>
    <ClInclude Include="src\utils\log\Log.h">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="src\core\timers\Timer.h">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="src\core\PatchGuard.h">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="src\core\flows\Flows.h">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="src\core\symbols\Offsets.h">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="src\core\symbols\Globals.h">
      <Filter>Header Files</Filter>
    </ClInclude>
  </ItemGroup>
</Project>

================================================
FILE: PatchGuardBypass/src/core/PatchGuard.h
================================================
#pragma once
#include <ntdef.h>

namespace PG
{
	namespace Disable
	{
		BOOLEAN
		Execute(
			VOID
		);

		VOID
		Unload(
			VOID
		);
	};

	namespace Evade
	{
		BOOLEAN
		Execute(
			VOID
		);

		VOID
		Unload(
			VOID
		);
	};

	namespace Verify
	{
		BOOLEAN
		Execute(
			VOID
		);

		VOID
		Unload(
			VOID
		);
	};
};


================================================
FILE: PatchGuardBypass/src/core/features/Disable.cpp
================================================
#include "../PatchGuard.h"
#include "../timers/Timer.h"
#include "../flows/Flows.h"
#include "../../utils/Log/Log.h"
#include <ntddk.h>

/**
For each Timer encountered, checks if it's PG related and removes it if so.
Compatible with the TIMER_CALLBACK signature, passed to SearchSystemTimers.
*/
TIMER_SEARCH_STATUS
RemoveTimer(
	PKTIMER Timer,
	PKDPC DecodedDpc
)
{
    if (Flows::ContextAwareTimer::IsTargetTimer(Timer, DecodedDpc))
    {
        KeCancelTimer(Timer);

        Log("Removed Context-Aware Timer/DPC: %p/%p\n", Timer, DecodedDpc);
    }

    if (Flows::ContextUnawareTimer::IsTargetTimer(Timer, DecodedDpc))
    {
        KeCancelTimer(Timer);

        Log("Removed Context-Unaware Timer/DPC: %p/%p\n", Timer, DecodedDpc);
    }

    return ContinueTimerSearch;
}

/**
Removes the DPC stored in the Prcb structure, i.e. NULLs it.
According to HalpMcaQueueDpc, a NULL DPC does not result in an error.
*/
BOOLEAN
RemovePrcbDpc(
    VOID
)
{
    PKDPC *PrcbDpc = Flows::PrcbDpc::GetTargetDpc();
    
    if (!PrcbDpc)
        return FALSE;

    if (!*PrcbDpc)
        return TRUE;

    Log("Removed Prcb DPC: %p\n", *PrcbDpc);

    *PrcbDpc = NULL;

    return TRUE;
}

BOOLEAN
PG::Disable::Execute(
	VOID
)
{
    /* Disable all PG related Timers (prevents ContextAware/Unaware flows) */
    SearchSystemTimers(&RemoveTimer);

    /* Remove DPC from Prcb (prevents Prcb DPC flow) */
    if (!RemovePrcbDpc())
        return FALSE;

    return TRUE;
}

VOID
PG::Disable::Unload(
    VOID
)
{
    /* Nothing to do here */
}


================================================
FILE: PatchGuardBypass/src/core/features/Evade.cpp
================================================
#include "../PatchGuard.h"
#include "../timers/Timer.h"
#include "../flows/Flows.h"
#include "../../utils/Log/Log.h"
#include <ntddk.h>

/**
Macro to convert milliseconds to hecto-nanoseconds, i.e. 100-nanoseconds.
This is the term for Windows interrupt time units.
*/
#define MS_TO_HNS(x) (x * 10000)

/* Initial StopTimer expiry cooldown (DueTime parameter) */
#define STOP_INITIAL_COOLOWN 1000
/* StopTimer cooldown after initial expiry (Period parameter) */
#define STOP_COOLOWN 500

/**
Global context for the evasion feature.
*/
typedef struct _EVADE_CONTEXT
{
    /*
    Array of PG-related KTIMERs. The array can contain up to 10 entries.
    I'm using an array for this because I'm not 100% confident that only 2 timers
    can exist at a time. If that's the case, this design is redundant and will change.
    */
#define MAX_PG_TIMERS 10
    PKTIMER Timers[MAX_PG_TIMERS];
    UINT32 TimerCount;
    /* The expiration time of the Timer we're currently avoiding */
    ULONGLONG LastAvoidedExpiration;
    /* Define a Timer for starting the evasion process */
    KDPC StartEvasionDpc;
    KTIMER StartEvasionTimer;
    /* Define a Timer for stopping the evasion process */
    KDPC StopEvasionDpc;
    KTIMER StopEvasionTimer;
} EVADE_CONTEXT, PEVADE_CONTEXT;

EVADE_CONTEXT g_EvadeContext = { 0 };

VOID
InsertTimerToContext(
    PKTIMER Timer
)
{
    if (g_EvadeContext.TimerCount >= MAX_PG_TIMERS)
    {
        g_EvadeContext.TimerCount++;
        return;
    }

    g_EvadeContext.Timers[g_EvadeContext.TimerCount++] = Timer;
}

FORCEINLINE
BOOLEAN
TimerOverflow(
    VOID
)
{
    return g_EvadeContext.TimerCount > MAX_PG_TIMERS;
}

/**
For each Timer encountered, checks if it's PG related and saves it if so.
Compatible with the TIMER_CALLBACK signature, passed to IterateSystemTimers.
*/
TIMER_SEARCH_STATUS
FindTimer(
    PKTIMER Timer,
    PKDPC DecodedDpc
)
{
    if (Flows::ContextAwareTimer::IsTargetTimer(Timer, DecodedDpc))
    {
        InsertTimerToContext(Timer);
    }

    if (Flows::ContextUnawareTimer::IsTargetTimer(Timer, DecodedDpc))
    {
        InsertTimerToContext(Timer);
    }

    return ContinueTimerSearch;
}

BOOLEAN
UpdateTimers(
    VOID
)
{
    /* Reset all previously found Timers */
    g_EvadeContext.TimerCount = 0;
    /* Find all PG related Timers */
    SearchSystemTimers(&FindTimer);

    if (TimerOverflow())
        return FALSE;

    return TRUE;
}

ULONGLONG
EarliestTimerExpiration(
    VOID
)
{
    ULONGLONG earliestTime = MAXLONGLONG;

    for (UINT32 i = 0; i < g_EvadeContext.TimerCount; i++)
    {
        PKTIMER currentTimer = g_EvadeContext.Timers[i];

        if (!currentTimer)
            continue;

        ULONGLONG currentTime = currentTimer->DueTime.QuadPart;

        if (currentTimer->Period)
        {
            /* BP if Timer is periodical. Need to figure out how to calculate the DueTime */
            DbgBreakPoint();
        }

        if (currentTime < earliestTime)
            earliestTime = currentTime;
    }

    return earliestTime;
}

/* Start hiding a bit earlier than the Timers expire */
#define EVASION_TIMER_UNDERSHOOT 500

BOOLEAN
SetStopEvasionTimer(
    VOID
);

VOID
StartEvasion(
    PKDPC Dpc,
    PVOID DeferredContext,
    PVOID SystemArgument1,
    PVOID SystemArgument2
)
{
    UNREFERENCED_PARAMETER(Dpc);
    UNREFERENCED_PARAMETER(DeferredContext);
    UNREFERENCED_PARAMETER(SystemArgument1);
    UNREFERENCED_PARAMETER(SystemArgument2);

    // DisableAllPatches();

    SetStopEvasionTimer();
}

#define AVOIDING_TIMER ((PVOID) 0x1)
#define AVOIDING_DPC ((PVOID) 0x0)

BOOLEAN
SetStartEvasionTimer(
    BOOLEAN RequiresUpdate
)
{
    /* If we require an update and the update failed */
    if (RequiresUpdate && !UpdateTimers())
        return FALSE;

    ULONGLONG timerExpiration = EarliestTimerExpiration();
    ULONG dpcExecution = Flows::PrcbDpc::NextExecutionTime();

    if (timerExpiration < dpcExecution)
    {
        g_EvadeContext.LastAvoidedExpiration = timerExpiration;
        /* Indicate to the DPC that we're avoiding a Timer, and not the Prcb DPC */
        g_EvadeContext.StartEvasionDpc.SystemArgument1 = AVOIDING_TIMER;
    }
    else
    {
        g_EvadeContext.LastAvoidedExpiration = dpcExecution;
        /* Indicate to the DPC that we're avoiding the Prcb DPC, and not a Timer */
        g_EvadeContext.StartEvasionDpc.SystemArgument1 = AVOIDING_DPC;
    }

    LARGE_INTEGER startEvasionTime;
    startEvasionTime.QuadPart = g_EvadeContext.LastAvoidedExpiration - EVASION_TIMER_UNDERSHOOT;

    if (KeSetTimer(
        &g_EvadeContext.StartEvasionTimer,
        startEvasionTime,
        &g_EvadeContext.StartEvasionDpc
    ))
        return FALSE;

    return TRUE;
}

VOID
StopEvasion(
    VOID
)
{
    // EnableAllPatches();

    SetStartEvasionTimer(FALSE);
}

VOID
TryStopEvasion(
    PKDPC Dpc,
    PVOID DeferredContext,
    PVOID IsAvoidingTimer,
    PVOID pvAttemptCount
)
{
    UNREFERENCED_PARAMETER(Dpc);
    UNREFERENCED_PARAMETER(DeferredContext);

    /* Convert from PVOID to UINT64 */
    UINT64 attemptCount = (UINT64) pvAttemptCount;

    if (attemptCount >= 5)
    {
        /*
        BP if we've attempted & failed more than 5 times.
        TODO: Better error handling (log error to user, exit program?)
        */
        DbgBreakPoint();
        goto Exit;
    }

    /* Increment attempt count. Why am I using global variables smh */
    g_EvadeContext.StopEvasionDpc.SystemArgument2 = (PVOID) (attemptCount + 1);

    /* Timer count before evasion started */
    UINT32 prevTimerCount = g_EvadeContext.TimerCount;

    /* Search again for all PG related Timers */
    if (!UpdateTimers())
        return;
    
    /* If we're avoiding a Timer, ensure it was actually removed (it's no longer the earliest) */
    if (IsAvoidingTimer == AVOIDING_TIMER &&
        g_EvadeContext.LastAvoidedExpiration == EarliestTimerExpiration())
    {
        /* TODO: Maybe do other stuff, we can sleep longer or something */
        return;
    }

    /* Check that a new replacement Timer was inserted, i.e. execution finished */
    if (prevTimerCount == g_EvadeContext.TimerCount)
    /* && CurrentTime < GetEarliestTimer(), make sure next Timer isn't already executing? not sure if necessary */
    {
        StopEvasion();

        Exit:
        /* If we finished avoiding, cancel the Timer */
        KeCancelTimer(&g_EvadeContext.StopEvasionTimer);
    }
}

BOOLEAN
SetStopEvasionTimer(
    VOID
)
{
    LARGE_INTEGER dueTime;
    dueTime.QuadPart = /* CurrentTime + */ MS_TO_HNS(STOP_INITIAL_COOLOWN);

    /* Notify StopEvasionDpc whether we're avoiding a Timer or the Prcb DPC */
    g_EvadeContext.StopEvasionDpc.SystemArgument1 = g_EvadeContext.StartEvasionDpc.SystemArgument1;
    /* Initialize attempt count to zero */
    g_EvadeContext.StartEvasionDpc.SystemArgument2 = 0;

    if (KeSetTimerEx(
        &g_EvadeContext.StopEvasionTimer,
        dueTime,
        STOP_COOLOWN,
        &g_EvadeContext.StopEvasionDpc
    ))
        return FALSE;

    return TRUE;
}

BOOLEAN
PrepareContext(
    VOID
)
{
    KeInitializeDpc(
        &g_EvadeContext.StartEvasionDpc,
        StartEvasion,
        NULL
    );

    KeInitializeTimerEx(
        &g_EvadeContext.StartEvasionTimer,
        NotificationTimer
    );

    KeInitializeDpc(
        &g_EvadeContext.StopEvasionDpc,
        TryStopEvasion,
        NULL
    );

    KeInitializeTimerEx(
        &g_EvadeContext.StopEvasionTimer,
        NotificationTimer
    );

    return TRUE;
}

BOOLEAN
PG::Evade::Execute(
    VOID
)
{
    if (!PrepareContext())
        return FALSE;

    if (!SetStartEvasionTimer(TRUE))
        return FALSE;

    return TRUE;
}

VOID
PG::Evade::Unload(
    VOID
)
{
    /* Cancel current Timers */
    KeCancelTimer(&g_EvadeContext.StartEvasionTimer);
    KeCancelTimer(&g_EvadeContext.StopEvasionTimer);
}


================================================
FILE: PatchGuardBypass/src/core/features/Verify.cpp
================================================
#include "../PatchGuard.h"
#include "../timers/Timer.h"
#include "../flows/Flows.h"
#include "../../utils/Log/Log.h"
#include <ntddk.h>

typedef struct _VERIFY_CONTEXT
{
    BOOLEAN bContextAwareTimer;
    BOOLEAN bContextUnawareTimer;
    BOOLEAN bPrcbDpc;
} VERIFY_CONTEXT, *PVERIFY_CONTEXT;

VERIFY_CONTEXT g_VerifyContext = { FALSE };

/**
For each Timer encountered, checks if it's PG related and removes it if so.
Compatible with the TIMER_CALLBACK signature, passed to IterateSystemTimers.
*/
TIMER_SEARCH_STATUS
VerifyTimer(
    PKTIMER Timer,
    PKDPC DecodedDpc
)
{
    if (Flows::ContextAwareTimer::IsTargetTimer(Timer, DecodedDpc))
    {
        g_VerifyContext.bContextAwareTimer = TRUE;
    }

    if (Flows::ContextUnawareTimer::IsTargetTimer(Timer, DecodedDpc))
    {
        g_VerifyContext.bContextUnawareTimer = TRUE;
    }

    return ContinueTimerSearch;
}

BOOLEAN
VerifyPrcbDpc(
    VOID
)
{
    PKDPC *PrcbDpc = Flows::PrcbDpc::GetTargetDpc();

    if (!PrcbDpc)
        return FALSE;

    if (!*PrcbDpc)
        return FALSE;

    return TRUE;
}

BOOLEAN
PG::Verify::Execute(
    VOID
)
{
    /* Verify all PG related Timers exist */
    SearchSystemTimers(&VerifyTimer);

    /* TODO: Not loving this global context variable */
    g_VerifyContext.bPrcbDpc = VerifyPrcbDpc();

    return
        g_VerifyContext.bContextAwareTimer &&
        g_VerifyContext.bContextUnawareTimer &&
        g_VerifyContext.bPrcbDpc;
}

VOID
PG::Verify::Unload(
    VOID
)
{
    /* Nothing to do here */
}


================================================
FILE: PatchGuardBypass/src/core/flows/Flows.cpp
================================================
#include "Flows.h"
#include <ntddk.h>
#include "../symbols/Globals.h"
#include "../symbols/Offsets.h"

BOOLEAN
Flows::ContextAwareTimer::IsTargetTimer(
	PKTIMER Timer,
	PKDPC DecodedDpc
)
{
	UNREFERENCED_PARAMETER(Timer);

    if (!MmIsAddressValid(DecodedDpc))
        return FALSE;

    INT64 SpecialBit = (INT64) DecodedDpc->DeferredContext >> 47;
    return SpecialBit != 0 && SpecialBit != -1;
}

BOOLEAN
Flows::ContextUnawareTimer::IsTargetTimer(
	PKTIMER Timer,
	PKDPC DecodedDpc
)
{
	UNREFERENCED_PARAMETER(Timer);

	if (!MmIsAddressValid(DecodedDpc))
		return FALSE;

	return DecodedDpc->DeferredRoutine == Globals::Functions::CcBcbProfiler;
}

ULONG
Flows::PrcbDpc::NextExecutionTime(
	VOID
)
{
	return *reinterpret_cast<PULONG>((PBYTE) *Globals::Variables::HalpClockTimer + Offsets::HalpClockTimer::NextExecutionTime);
}

PKDPC *
Flows::PrcbDpc::GetTargetDpc(
	VOID
)
{
	PKPRCB Prcb = Globals::Functions::KeGetPrcb(0);
	
	if (!Prcb)
		return NULL;

	return reinterpret_cast<PKDPC *>((PBYTE) Prcb + Offsets::Prcb::PatchGuardDpc);
}


================================================
FILE: PatchGuardBypass/src/core/flows/Flows.h
================================================
#pragma once
#include <ntdef.h>

/* Forward declaration of KTIMER struct */
typedef struct _KTIMER
KTIMER, *PKTIMER;
/* Forward declaration of KDPC struct */
typedef struct _KDPC
KDPC, *PKDPC;

/**
Contains sub-namespaces defining each execution flow for PatchGuard checks.
*/
namespace Flows
{
	/**
	PatchGuard issues a check through a Timer inserted to Prcb index 0.
	This Timer receives the PatchGuard Context struct as a parameter and uses it.
	*/
	namespace ContextAwareTimer
	{
		BOOLEAN
		IsTargetTimer(
			PKTIMER Timer,
			PKDPC DecodedDpc
		);
	};

	/**
	PatchGuard issues a check through a Timer inserted to Prcb index 0.
	This Timer does not receive the PatchGuard Context struct as a parameter.
	It is more static & less complex than the context aware Timer.
	*/
	namespace ContextUnawareTimer
	{
		BOOLEAN
		IsTargetTimer(
			PKTIMER Timer,
			PKDPC DecodedDpc
		);
	};

	/**
	PatchGuad issues a check through a DPC saved to Prcb index 0.
	This DPC is inserted to the HalReserved[7] field from FsRtlMdlReadCompleteDevEx.
	It is executed every 2 minutes from HalpMcaQueueDpc.
	*/
	namespace PrcbDpc
	{
		/**
		@return The next execution time of the DPC stored in the Prcb.
		This value is returned as an interrupt timestamp.
		*/
		ULONG
		NextExecutionTime(
			VOID
		);

		/**
		@return Pointer to the target DPC stored in the Prcb.
		This returns a pointer to allow easily overwriting the DPC.
		*/
		PKDPC *
		GetTargetDpc(
			VOID
		);
	};
};


================================================
FILE: PatchGuardBypass/src/core/symbols/Globals.cpp
================================================
#include "Globals.h"

/*
Just grouping together all offsets into a single namespace.
Not necessary, but more convenient for modifying and hiding the vars from global scope.
*/
namespace GlobalOffsets
{
	/* Keys used for decoding/encoding DPCs within KTIMERs */
	constexpr UINT64 KiWaitAlways = 0xCFC9F8;
	constexpr UINT64 KiWaitNever = 0xCFC7F8;
	/* Number of processor on the system. Also indicates number of PRCBs */
	constexpr UINT64 KeNumberProcessors_0 = 0xCFC404;
	constexpr UINT64 HalpClockTimer = 0xC4BFC8;

	/* Offset of some known routine that we can use to calculate ImageBase */
	constexpr UINT64 KeBugCheckEx = 0x3f5210;
	/* Undocumented function that returns the Prcb at the given index */
	constexpr UINT64 KeGetPrcb = 0x32DAD0;
	constexpr UINT64 CcBcbProfiler = 0x3D7330;
};

/**
Template function to return a Global variable.
@param Type is the type of the variable.
@param GlobalOffset is the offset of the variable from the image base.
*/
template <typename Type, UINT64 GlobalOffset>
Type GetGlobal(UINT64 ImageBase)
{
	return reinterpret_cast<Type>(ImageBase + GlobalOffset);
}

/**
Initializes all Globals.
*/
BOOLEAN
Globals::Initialize(
	VOID
)
{
	/* Not sure if this is ok or completely mentally ill */
	UINT64 ImageBase = (UINT64) &KeBugCheckEx - GlobalOffsets::KeBugCheckEx;

	Globals::Variables::KiWaitAlways = GetGlobal<PINT64, GlobalOffsets::KiWaitAlways>(ImageBase);
	Globals::Variables::KiWaitNever = GetGlobal<PINT64, GlobalOffsets::KiWaitNever>(ImageBase);
	Globals::Variables::KeNumberProcessors_0 = GetGlobal<PULONG, GlobalOffsets::KeNumberProcessors_0>(ImageBase);
	Globals::Variables::HalpClockTimer = GetGlobal<PVOID *, GlobalOffsets::HalpClockTimer>(ImageBase);

	Globals::Functions::KeGetPrcb = GetGlobal<PKPRCB (__fastcall *) (ULONG), GlobalOffsets::KeGetPrcb>(ImageBase);
	Globals::Functions::CcBcbProfiler = GetGlobal<PVOID, GlobalOffsets::CcBcbProfiler>(ImageBase);

	return TRUE;
}

/* Define all externs */
PINT64 Globals::Variables::KiWaitAlways = NULL;
PINT64 Globals::Variables::KiWaitNever = NULL;
PULONG Globals::Variables::KeNumberProcessors_0 = NULL;
PVOID *Globals::Variables::HalpClockTimer = NULL;
PKPRCB (__fastcall *Globals::Functions::KeGetPrcb) (ULONG) = NULL;
PVOID Globals::Functions::CcBcbProfiler = NULL;


================================================
FILE: PatchGuardBypass/src/core/symbols/Globals.h
================================================
#pragma once
#include <ntddk.h>

/* The Kernel KPRCB structure is undocumented, so we'll treat it as a void-pointer */
typedef PVOID PKPRCB;

namespace Globals
{
	namespace Variables
	{
		extern PINT64 KiWaitAlways;
		extern PINT64 KiWaitNever;
		extern PULONG KeNumberProcessors_0;
		extern PVOID *HalpClockTimer;
	};

	namespace Functions
	{
		/* Function pointer to KeGetPrcb, which is undocumented */
		extern PKPRCB (__fastcall *KeGetPrcb) (ULONG PrcbNumber);
		/* Invoked by the Context-Unaware Timers */
		extern PVOID CcBcbProfiler;
	};

	BOOLEAN
	Initialize(
		VOID
	);
};


================================================
FILE: PatchGuardBypass/src/core/symbols/Offsets.cpp
================================================
#include "Offsets.h"

UINT32 Offsets::Prcb::TimerTable = 0x3940;
UINT32 Offsets::Prcb::PatchGuardDpc = 0x80;

UINT32 Offsets::HalpClockTimer::NextExecutionTime = 0x3C;


================================================
FILE: PatchGuardBypass/src/core/symbols/Offsets.h
================================================
#pragma once
#include <windef.h>

namespace Offsets
{
	/* Offsets to fields within a Prcb (struct _KPRCB) */
	namespace Prcb
	{
		/* Offset to TimerTable field */
		extern UINT32 TimerTable;
		extern UINT32 PatchGuardDpc;
	};

	namespace HalpClockTimer
	{
		extern UINT32 NextExecutionTime;
	};
};


================================================
FILE: PatchGuardBypass/src/core/timers/Timer.cpp
================================================
#include "Timer.h"
#include <ntifs.h>
#include <ntddk.h>
#include "../symbols/Offsets.h"
#include "../symbols/Globals.h"

/**
* Kernel structure defining an entry within a KTIMER_TABLE.
* Each entry contains a linked-list of KTIMERs.
*/
typedef struct _KTIMER_TABLE_ENTRY
{
    /* Locked used to synchronize access to the entry */
    unsigned __int64 Lock;
    /* Head of a linked-list of KTIMERs */
    LIST_ENTRY Entry;
    /* Earliest expiration time within this entry's Timers (used in insertion process, iirc) */
    ULARGE_INTEGER Time;
} KTIMER_TABLE_ENTRY, *PKTIMER_TABLE_ENTRY;

/* Size of the TimerExpiry array */
#define TIMER_EXPIRY_SIZE 64
/* Size of the TimerEntries array */
#define TIMER_ENTRIES_SIZE 256

typedef struct _KTIMER_TABLE
{
    /* An array of KTIMER pointers, representing all expired Timers that need processing */
    PKTIMER TimerExpiry[TIMER_EXPIRY_SIZE];
    /*
    A 2-dimensional array of KTIMER_TABLE_ENTRIES, containing all user-mode & kernel-mode
    (I think?) non-expired Timers. TimerEntries[0] is for kernel-mode, TimerEntries[1] for user-mode.
    */
    KTIMER_TABLE_ENTRY TimerEntries[2][TIMER_ENTRIES_SIZE];
    /* TimerState structure (size=0x18), we do not care for this */
    char TableState[0x18]; 
} KTIMER_TABLE, *PKTIMER_TABLE;

/* Retrieves the TimerTable field of a KPRCB */
PKTIMER_TABLE
GetTimerTable(
    PKPRCB Prcb
)
{
    return (PKTIMER_TABLE) ((PCHAR) Prcb + Offsets::Prcb::TimerTable);
}

/*
Returns the decoded pointer to the DPC stored in a KTIMER structre.
These DPC pointers are encoded during insertion of the Timers.
The encoding/decoding can be seen in KTIMER-related functions in ntoskrnl.exe.
*/
#define DECODE_TIMER_DPC(Timer) \
    (PKDPC) (*Globals::Variables::KiWaitAlways ^ _byteswap_uint64( \
        (UINT64) Timer ^ _rotl64( \
            (INT64) Timer->Dpc ^ *Globals::Variables::KiWaitNever, \
            (UCHAR) *Globals::Variables::KiWaitNever \
        )))

/** 
Iterates over all entries of a linked-list of KTIMERs.
For each KTIMER, the given callback function is invoked.
@param TimerListHead is the head entry of the list, from a KTIMER_TABLE_ENTRY structure.
@param TimerCallbacks is a fixed array of TIMER_CALLBACK routines, invoked for each KTIMER.
@return search instructions for the caller.
*/
TIMER_SEARCH_STATUS
SearchTimerList(
    PKTIMER_TABLE_ENTRY TimerTableEntry,
    PTIMER_CALLBACK TimerCallback
)
{
    /*
    TODO: Acquire & Release SpinLock of TimerTableEntry.
    */

    PLIST_ENTRY pListEntry = TimerTableEntry->Entry.Flink;

    /* As long as the current entry is valid and we haven't reached the end */
    while (pListEntry && pListEntry != &TimerTableEntry->Entry)
    {
        /* Get the KTIMER that contains the current list entry */
        PKTIMER pTimer = CONTAINING_RECORD(
            pListEntry,
            KTIMER,
            TimerListEntry
        );

        /* Get the decoded DPC */
        PKDPC pDpc = DECODE_TIMER_DPC(pTimer);

        /* Invoke registered callback */
        if (TimerCallback(pTimer, pDpc) == StopTimerSearch)
            return StopTimerSearch;

        /* Advance to the next Timer entry */
        pListEntry = pListEntry->Flink;
    }

    return ContinueTimerSearch;
}

/**
Iterates all pending KTIMERs in the given KTIMER_TABLE.
@param TimerTable is the KTIMER_TABLE we want to iterate.
@param TimerCallbacks is a fixed array of TIMER_CALLBACK routines, invoked for each KTIMER.
*/
VOID
SearchTimerTable(
    PKTIMER_TABLE TimerTable,
    PTIMER_CALLBACK TimerCallback
)
{
    /* Get the array of kernel-mode KTIMER_TABLE_ENTRYs */
    PKTIMER_TABLE_ENTRY pKernelEntries = TimerTable->TimerEntries[KernelMode];
    /* Get the array of user-mode KTIMER_TABLE_ENTRYs */
    PKTIMER_TABLE_ENTRY pUserEntries = TimerTable->TimerEntries[UserMode];

    /* Iterate over all KTIMER_TABLE_ENTRYs in both arrays */
    for (USHORT i = 0; i < TIMER_ENTRIES_SIZE; i++)
    {
        /* Iterate linked-list of KTIMERs within each KTIMER_TABLE_ENTRY */

        if (SearchTimerList(&pKernelEntries[i], TimerCallback) == StopTimerSearch)
            break;

        if (SearchTimerList(&pUserEntries[i], TimerCallback) == StopTimerSearch)
            break;
    }
}

/**
Iterates over all Timers in the system, invokes the given callbacks for each Timer.
@param TimerCallbacks is the fixed array of callbacks to be invoked.
*/
BOOLEAN
SearchSystemTimers(
    PTIMER_CALLBACK TimerCallback
)
{
    /* Get the matching KPRCB struct (current code is wrong, just a placeholder) */
    PKPRCB pPrcb = Globals::Functions::KeGetPrcb(0);

    if (!pPrcb)
        return FALSE;

    /* Get the KPRCB's TimerTable, then iterate its Timers */
    SearchTimerTable(GetTimerTable(pPrcb), TimerCallback);

    return TRUE;
}


================================================
FILE: PatchGuardBypass/src/core/timers/Timer.h
================================================
#pragma once
#include <ntdef.h>

/* Forward declaration of KTIMER struct */
typedef struct _KTIMER
KTIMER, *PKTIMER;
/* Forward declaration of KDPC struct */
typedef struct _KDPC
KDPC, *PKDPC;

/**
Enum returned by TIMER_CALLBACK to indicate how the search should continue.
*/
typedef enum _TIMER_SEARCH_STATUS
{
    StopTimerSearch,
    ContinueTimerSearch,
} TIMER_SEARCH_STATUS, *PTIMER_SEARCH_STATUS;

/**
Signature of a callback routine for each KTIMER encountered.
@param Timer is the KTIMER encountered.
@param DecodedDpc is the decoded DPC used by the Timer.
@return TRUE if execution should continue, FASLE if it should stop.
*/
typedef
TIMER_SEARCH_STATUS
TIMER_CALLBACK(
    PKTIMER Timer,
    PKDPC DecodedDpc
);
typedef TIMER_CALLBACK *PTIMER_CALLBACK;

/**
Iterates over all Timers in the system, invokes the given callbacks for each Timer.
*/
BOOLEAN
SearchSystemTimers(
    PTIMER_CALLBACK TimerCallback
);


================================================
FILE: PatchGuardBypass/src/main.cpp
================================================
#pragma once
#include <ntifs.h>
#include <ntddk.h>
#include "utils/log/Log.h"
#include "core/PatchGuard.h"

VOID
DriverUnload(
    _In_ PDRIVER_OBJECT pDriverObject
)
{
    UNREFERENCED_PARAMETER(pDriverObject);
}

#include "core/symbols/Globals.h"

EXTERN_C
NTSTATUS
DriverEntry(
    _In_ PDRIVER_OBJECT DriverObject,
    _In_ PUNICODE_STRING RegistryPath
)
{
    UNREFERENCED_PARAMETER(DriverObject);
    UNREFERENCED_PARAMETER(RegistryPath);

    DriverObject->DriverUnload = DriverUnload;

    Globals::Initialize();

    PG::Disable::Execute();

    Log("%p\n", Globals::Functions::CcBcbProfiler);

    return STATUS_SUCCESS;
}


================================================
FILE: PatchGuardBypass.sln
================================================

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.32802.440
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PatchGuardBypass", "PatchGuardBypass\PatchGuardBypass.vcxproj", "{57A68F53-C563-405D-B2E1-C66585DA64E4}"
EndProject
Global
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
		Debug|ARM = Debug|ARM
		Debug|ARM64 = Debug|ARM64
		Debug|x64 = Debug|x64
		Debug|x86 = Debug|x86
		Release|ARM = Release|ARM
		Release|ARM64 = Release|ARM64
		Release|x64 = Release|x64
		Release|x86 = Release|x86
	EndGlobalSection
	GlobalSection(ProjectConfigurationPlatforms) = postSolution
		{57A68F53-C563-405D-B2E1-C66585DA64E4}.Debug|ARM.ActiveCfg = Debug|ARM
		{57A68F53-C563-405D-B2E1-C66585DA64E4}.Debug|ARM.Build.0 = Debug|ARM
		{57A68F53-C563-405D-B2E1-C66585DA64E4}.Debug|ARM.Deploy.0 = Debug|ARM
		{57A68F53-C563-405D-B2E1-C66585DA64E4}.Debug|ARM64.ActiveCfg = Debug|ARM64
		{57A68F53-C563-405D-B2E1-C66585DA64E4}.Debug|ARM64.Build.0 = Debug|ARM64
		{57A68F53-C563-405D-B2E1-C66585DA64E4}.Debug|ARM64.Deploy.0 = Debug|ARM64
		{57A68F53-C563-405D-B2E1-C66585DA64E4}.Debug|x64.ActiveCfg = Debug|x64
		{57A68F53-C563-405D-B2E1-C66585DA64E4}.Debug|x64.Build.0 = Debug|x64
		{57A68F53-C563-405D-B2E1-C66585DA64E4}.Debug|x64.Deploy.0 = Debug|x64
		{57A68F53-C563-405D-B2E1-C66585DA64E4}.Debug|x86.ActiveCfg = Debug|Win32
		{57A68F53-C563-405D-B2E1-C66585DA64E4}.Debug|x86.Build.0 = Debug|Win32
		{57A68F53-C563-405D-B2E1-C66585DA64E4}.Debug|x86.Deploy.0 = Debug|Win32
		{57A68F53-C563-405D-B2E1-C66585DA64E4}.Release|ARM.ActiveCfg = Release|ARM
		{57A68F53-C563-405D-B2E1-C66585DA64E4}.Release|ARM.Build.0 = Release|ARM
		{57A68F53-C563-405D-B2E1-C66585DA64E4}.Release|ARM.Deploy.0 = Release|ARM
		{57A68F53-C563-405D-B2E1-C66585DA64E4}.Release|ARM64.ActiveCfg = Release|ARM64
		{57A68F53-C563-405D-B2E1-C66585DA64E4}.Release|ARM64.Build.0 = Release|ARM64
		{57A68F53-C563-405D-B2E1-C66585DA64E4}.Release|ARM64.Deploy.0 = Release|ARM64
		{57A68F53-C563-405D-B2E1-C66585DA64E4}.Release|x64.ActiveCfg = Release|x64
		{57A68F53-C563-405D-B2E1-C66585DA64E4}.Release|x64.Build.0 = Release|x64
		{57A68F53-C563-405D-B2E1-C66585DA64E4}.Release|x64.Deploy.0 = Release|x64
		{57A68F53-C563-405D-B2E1-C66585DA64E4}.Release|x86.ActiveCfg = Release|Win32
		{57A68F53-C563-405D-B2E1-C66585DA64E4}.Release|x86.Build.0 = Release|Win32
		{57A68F53-C563-405D-B2E1-C66585DA64E4}.Release|x86.Deploy.0 = Release|Win32
	EndGlobalSection
	GlobalSection(SolutionProperties) = preSolution
		HideSolutionNode = FALSE
	EndGlobalSection
	GlobalSection(ExtensibilityGlobals) = postSolution
		SolutionGuid = {8AD89A08-9F84-4021-B1FA-0CA109C2D418}
	EndGlobalSection
EndGlobal


================================================
FILE: README.md
================================================
# **PatchGuardBypass**

I've had the delightful opportunity to research PatchGuard for the past couple of weeks, and it was mostly pretty fun.

I'll be writing a paper about my experience and my findings, hopefully it could help anyone else who's hesitant to do something like this :)

In the meantime, I'll also be writing a dynamic PatchGuard bypass for modern Windows 10 systems. **This is still a bit far from done, so please don't expect anything to work at this stage.**
Hopefully when it is finished it'll include 3 main features:

### **Disable**
Disables PatchGuard completely and prevents its execution.

### **Evade** 
Evades PatchGuard detection by reverting patches prior to the PG check times.

### **Verify**
Checks if PatchGuard has been disabled on the system. Basically the opposite of Disabling.

**DISCLAMER: The feature names are work-in-progress, my sincerest apologies for the poor choice <3**

Download .txt
gitextract_yx0qudfh/

├── .gitignore
├── PatchGuardBypass/
│   ├── PatchGuardBypass.inf
│   ├── PatchGuardBypass.vcxproj
│   ├── PatchGuardBypass.vcxproj.filters
│   └── src/
│       ├── core/
│       │   ├── PatchGuard.h
│       │   ├── features/
│       │   │   ├── Disable.cpp
│       │   │   ├── Evade.cpp
│       │   │   └── Verify.cpp
│       │   ├── flows/
│       │   │   ├── Flows.cpp
│       │   │   └── Flows.h
│       │   ├── symbols/
│       │   │   ├── Globals.cpp
│       │   │   ├── Globals.h
│       │   │   ├── Offsets.cpp
│       │   │   └── Offsets.h
│       │   └── timers/
│       │       ├── Timer.cpp
│       │       └── Timer.h
│       └── main.cpp
├── PatchGuardBypass.sln
└── README.md
Download .txt
SYMBOL INDEX (50 symbols across 12 files)

FILE: PatchGuardBypass/src/core/PatchGuard.h
  function namespace (line 4) | namespace PG

FILE: PatchGuardBypass/src/core/features/Disable.cpp
  function TIMER_SEARCH_STATUS (line 11) | TIMER_SEARCH_STATUS
  function BOOLEAN (line 38) | BOOLEAN
  function BOOLEAN (line 58) | BOOLEAN
  function VOID (line 73) | VOID

FILE: PatchGuardBypass/src/core/features/Evade.cpp
  type _EVADE_CONTEXT (line 21) | struct _EVADE_CONTEXT
  function VOID (line 43) | VOID
  function FORCEINLINE (line 57) | FORCEINLINE
  function TIMER_SEARCH_STATUS (line 70) | TIMER_SEARCH_STATUS
  function BOOLEAN (line 89) | BOOLEAN
  function ULONGLONG (line 105) | ULONGLONG
  function VOID (line 142) | VOID
  function BOOLEAN (line 163) | BOOLEAN
  function VOID (line 201) | VOID
  function VOID (line 211) | VOID
  function BOOLEAN (line 265) | BOOLEAN
  function BOOLEAN (line 289) | BOOLEAN
  function BOOLEAN (line 319) | BOOLEAN
  function VOID (line 333) | VOID

FILE: PatchGuardBypass/src/core/features/Verify.cpp
  type _VERIFY_CONTEXT (line 7) | struct _VERIFY_CONTEXT
  function TIMER_SEARCH_STATUS (line 20) | TIMER_SEARCH_STATUS
  function BOOLEAN (line 39) | BOOLEAN
  function BOOLEAN (line 55) | BOOLEAN
  function VOID (line 72) | VOID

FILE: PatchGuardBypass/src/core/flows/Flows.cpp
  function BOOLEAN (line 6) | BOOLEAN
  function BOOLEAN (line 21) | BOOLEAN
  function ULONG (line 35) | ULONG
  function PKDPC (line 43) | PKDPC *

FILE: PatchGuardBypass/src/core/flows/Flows.h
  type KTIMER (line 5) | typedef struct _KTIMER
  type KDPC (line 8) | typedef struct _KDPC
  function namespace (line 14) | namespace Flows

FILE: PatchGuardBypass/src/core/symbols/Globals.cpp
  type GlobalOffsets (line 7) | namespace GlobalOffsets
  function Type (line 29) | Type GetGlobal(UINT64 ImageBase)
  function BOOLEAN (line 37) | BOOLEAN

FILE: PatchGuardBypass/src/core/symbols/Globals.h
  type PVOID (line 5) | typedef PVOID PKPRCB;
  function namespace (line 7) | namespace Globals

FILE: PatchGuardBypass/src/core/symbols/Offsets.h
  function namespace (line 4) | namespace Offsets

FILE: PatchGuardBypass/src/core/timers/Timer.cpp
  type _KTIMER_TABLE_ENTRY (line 11) | struct _KTIMER_TABLE_ENTRY
  type _KTIMER_TABLE (line 26) | struct _KTIMER_TABLE
  function PKTIMER_TABLE (line 40) | PKTIMER_TABLE
  function TIMER_SEARCH_STATUS (line 67) | TIMER_SEARCH_STATUS
  function VOID (line 108) | VOID
  function BOOLEAN (line 136) | BOOLEAN

FILE: PatchGuardBypass/src/core/timers/Timer.h
  type KTIMER (line 5) | typedef struct _KTIMER
  type KDPC (line 8) | typedef struct _KDPC
  type TIMER_SEARCH_STATUS (line 14) | typedef enum _TIMER_SEARCH_STATUS
  type TIMER_SEARCH_STATUS (line 26) | typedef
  type TIMER_CALLBACK (line 32) | typedef TIMER_CALLBACK *PTIMER_CALLBACK;

FILE: PatchGuardBypass/src/main.cpp
  function VOID (line 7) | VOID
  function EXTERN_C (line 17) | EXTERN_C
Condensed preview — 19 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (51K chars).
[
  {
    "path": ".gitignore",
    "chars": 6860,
    "preview": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n##\n## G"
  },
  {
    "path": "PatchGuardBypass/PatchGuardBypass.inf",
    "chars": 2532,
    "preview": ";\n; PatchGuardBypass.inf\n;\n\n[Version]\nSignature=\"$WINDOWS NT$\"\nClass=Sample ; TODO: edit Class\nClassGuid={78A1C341-4539-"
  },
  {
    "path": "PatchGuardBypass/PatchGuardBypass.vcxproj",
    "chars": 8215,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"12.0\" xmlns=\"http://schemas.micros"
  },
  {
    "path": "PatchGuardBypass/PatchGuardBypass.vcxproj.filters",
    "chars": 2730,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuil"
  },
  {
    "path": "PatchGuardBypass/src/core/PatchGuard.h",
    "chars": 323,
    "preview": "#pragma once\n#include <ntdef.h>\n\nnamespace PG\n{\n\tnamespace Disable\n\t{\n\t\tBOOLEAN\n\t\tExecute(\n\t\t\tVOID\n\t\t);\n\n\t\tVOID\n\t\tUnload"
  },
  {
    "path": "PatchGuardBypass/src/core/features/Disable.cpp",
    "chars": 1536,
    "preview": "#include \"../PatchGuard.h\"\n#include \"../timers/Timer.h\"\n#include \"../flows/Flows.h\"\n#include \"../../utils/Log/Log.h\"\n#in"
  },
  {
    "path": "PatchGuardBypass/src/core/features/Evade.cpp",
    "chars": 7859,
    "preview": "#include \"../PatchGuard.h\"\n#include \"../timers/Timer.h\"\n#include \"../flows/Flows.h\"\n#include \"../../utils/Log/Log.h\"\n#in"
  },
  {
    "path": "PatchGuardBypass/src/core/features/Verify.cpp",
    "chars": 1515,
    "preview": "#include \"../PatchGuard.h\"\n#include \"../timers/Timer.h\"\n#include \"../flows/Flows.h\"\n#include \"../../utils/Log/Log.h\"\n#in"
  },
  {
    "path": "PatchGuardBypass/src/core/flows/Flows.cpp",
    "chars": 1042,
    "preview": "#include \"Flows.h\"\n#include <ntddk.h>\n#include \"../symbols/Globals.h\"\n#include \"../symbols/Offsets.h\"\n\nBOOLEAN\nFlows::Co"
  },
  {
    "path": "PatchGuardBypass/src/core/flows/Flows.h",
    "chars": 1461,
    "preview": "#pragma once\n#include <ntdef.h>\n\n/* Forward declaration of KTIMER struct */\ntypedef struct _KTIMER\nKTIMER, *PKTIMER;\n/* "
  },
  {
    "path": "PatchGuardBypass/src/core/symbols/Globals.cpp",
    "chars": 2270,
    "preview": "#include \"Globals.h\"\n\n/*\nJust grouping together all offsets into a single namespace.\nNot necessary, but more convenient "
  },
  {
    "path": "PatchGuardBypass/src/core/symbols/Globals.h",
    "chars": 582,
    "preview": "#pragma once\n#include <ntddk.h>\n\n/* The Kernel KPRCB structure is undocumented, so we'll treat it as a void-pointer */\nt"
  },
  {
    "path": "PatchGuardBypass/src/core/symbols/Offsets.cpp",
    "chars": 168,
    "preview": "#include \"Offsets.h\"\n\nUINT32 Offsets::Prcb::TimerTable = 0x3940;\nUINT32 Offsets::Prcb::PatchGuardDpc = 0x80;\n\nUINT32 Off"
  },
  {
    "path": "PatchGuardBypass/src/core/symbols/Offsets.h",
    "chars": 298,
    "preview": "#pragma once\n#include <windef.h>\n\nnamespace Offsets\n{\n\t/* Offsets to fields within a Prcb (struct _KPRCB) */\n\tnamespace "
  },
  {
    "path": "PatchGuardBypass/src/core/timers/Timer.cpp",
    "chars": 4759,
    "preview": "#include \"Timer.h\"\n#include <ntifs.h>\n#include <ntddk.h>\n#include \"../symbols/Offsets.h\"\n#include \"../symbols/Globals.h\""
  },
  {
    "path": "PatchGuardBypass/src/core/timers/Timer.h",
    "chars": 923,
    "preview": "#pragma once\n#include <ntdef.h>\n\n/* Forward declaration of KTIMER struct */\ntypedef struct _KTIMER\nKTIMER, *PKTIMER;\n/* "
  },
  {
    "path": "PatchGuardBypass/src/main.cpp",
    "chars": 633,
    "preview": "#pragma once\n#include <ntifs.h>\n#include <ntddk.h>\n#include \"utils/log/Log.h\"\n#include \"core/PatchGuard.h\"\n\nVOID\nDriverU"
  },
  {
    "path": "PatchGuardBypass.sln",
    "chars": 2760,
    "preview": "\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 16\nVisualStudioVersion = 16.0.3280"
  },
  {
    "path": "README.md",
    "chars": 918,
    "preview": "# **PatchGuardBypass**\n\nI've had the delightful opportunity to research PatchGuard for the past couple of weeks, and it "
  }
]

About this extraction

This page contains the full source code of the AdamOron/PatchGuardBypass GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 19 files (46.3 KB), approximately 13.8k tokens, and a symbol index with 50 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!