Full Code of paradoxwastaken/Poseidon for AI

main 0e08674b01d6 cached
21 files
65.7 KB
18.4k tokens
67 symbols
1 requests
Download .txt
Repository: paradoxwastaken/Poseidon
Branch: main
Commit: 0e08674b01d6
Files: 21
Total size: 65.7 KB

Directory structure:
gitextract__tzj7agv/

├── .gitignore
├── Poseidon/
│   ├── Poseidon.sln
│   ├── Poseidon.vcxproj
│   ├── Poseidon.vcxproj.filters
│   ├── global.h
│   ├── main.cpp
│   ├── memory.h
│   ├── process.h
│   ├── sdk.h
│   ├── sharedmemory.h
│   ├── system.h
│   └── utils.h
├── PoseidonClient/
│   ├── PoseidonClient.vcxproj
│   ├── PoseidonClient.vcxproj.filters
│   ├── global.h
│   ├── main.cpp
│   ├── memory.h
│   ├── process.h
│   ├── sdk.h
│   └── sharedmemory.h
└── README.md

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

================================================
FILE: .gitignore
================================================

# Created by https://www.toptal.com/developers/gitignore/api/visualstudio
# Edit at https://www.toptal.com/developers/gitignore?templates=visualstudio

### VisualStudio ###
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore

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

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

# Mono auto generated files
mono_crash.*

# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[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
*.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*.[ji][sn][of][no]
coverage*.xml

# Visual Studio code coverage results
*.coverage
*.coveragexml

# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*

# MightyMoose
*.mm.*
AutoTest.Net/

# Web workbench (sass)
.sass-cache/

# Installshield output folder
[Ee]xpress/

# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html

# Click-Once directory
publish/

# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj

# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/

# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets

# Microsoft Azure Build Output
csx/
*.build.csdef

# Microsoft Azure Emulator
ecf/
rcf/

# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload

# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/

# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs

# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk

# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/

# RIA/Silverlight projects
Generated_Code/

# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak

# SQL Server files
*.mdf
*.ldf
*.ndf

# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl

# Microsoft Fakes
FakesAssemblies/

# GhostDoc plugin setting file
*.GhostDoc.xml

# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/

# Visual Studio 6 build log
*.plg

# Visual Studio 6 workspace options file
*.opt

# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw

# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions

# Paket dependency manager
.paket/paket.exe
paket-files/

# FAKE - F# Make
.fake/

# CodeRush personal settings
.cr/personal

# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc

# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config

# Tabs Studio
*.tss

# Telerik's JustMock configuration file
*.jmconfig

# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs

# OpenCover UI analysis results
OpenCover/

# Azure Stream Analytics local run output
ASALocalRun/

# MSBuild Binary and Structured Log
*.binlog

# NVidia Nsight GPU debugger configuration file
*.nvuser

# MFractors (Xamarin productivity tool) working folder
.mfractor/

# Local History for Visual Studio
.localhistory/

# BeatPulse healthcheck temp database
healthchecksdb

# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/

# Ionide (cross platform F# VS Code tools) working folder
.ionide/

# Fody - auto-generated XML schema
FodyWeavers.xsd

### VisualStudio Patch ###
# Additional files built by Visual Studio
*.tlog

# End of https://www.toptal.com/developers/gitignore/api/visualstudio

================================================
FILE: Poseidon/Poseidon.sln
================================================

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30711.63
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Poseidon", "Poseidon.vcxproj", "{A941F3A1-C164-4A34-94B4-9577B7CD5FE2}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PoseidonClient", "..\PoseidonClient\PoseidonClient.vcxproj", "{46A9D08D-4962-4434-BC75-C60339512252}"
EndProject
Global
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
		Debug|x64 = Debug|x64
		Release|x64 = Release|x64
	EndGlobalSection
	GlobalSection(ProjectConfigurationPlatforms) = postSolution
		{A941F3A1-C164-4A34-94B4-9577B7CD5FE2}.Debug|x64.ActiveCfg = Debug|x64
		{A941F3A1-C164-4A34-94B4-9577B7CD5FE2}.Debug|x64.Build.0 = Debug|x64
		{A941F3A1-C164-4A34-94B4-9577B7CD5FE2}.Debug|x64.Deploy.0 = Debug|x64
		{A941F3A1-C164-4A34-94B4-9577B7CD5FE2}.Release|x64.ActiveCfg = Release|x64
		{A941F3A1-C164-4A34-94B4-9577B7CD5FE2}.Release|x64.Build.0 = Release|x64
		{A941F3A1-C164-4A34-94B4-9577B7CD5FE2}.Release|x64.Deploy.0 = Release|x64
		{46A9D08D-4962-4434-BC75-C60339512252}.Debug|x64.ActiveCfg = Debug|x64
		{46A9D08D-4962-4434-BC75-C60339512252}.Debug|x64.Build.0 = Debug|x64
		{46A9D08D-4962-4434-BC75-C60339512252}.Release|x64.ActiveCfg = Release|x64
		{46A9D08D-4962-4434-BC75-C60339512252}.Release|x64.Build.0 = Release|x64
	EndGlobalSection
	GlobalSection(SolutionProperties) = preSolution
		HideSolutionNode = FALSE
	EndGlobalSection
	GlobalSection(ExtensibilityGlobals) = postSolution
		SolutionGuid = {A7CE4DCC-6D4C-4C0F-A15F-3D65EBEA3C6F}
	EndGlobalSection
EndGlobal


================================================
FILE: Poseidon/Poseidon.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|x64">
      <Configuration>Debug</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
    <ProjectConfiguration Include="Release|x64">
      <Configuration>Release</Configuration>
      <Platform>x64</Platform>
    </ProjectConfiguration>
  </ItemGroup>
  <PropertyGroup Label="Globals">
    <ProjectGuid>{A941F3A1-C164-4A34-94B4-9577B7CD5FE2}</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>Poseidon</RootNamespace>
    <WindowsTargetPlatformVersion>$(LatestTargetPlatformVersion)</WindowsTargetPlatformVersion>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
  <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>
    <Driver_SpectreMitigation>false</Driver_SpectreMitigation>
  </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|x64'">
    <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
    <TargetName>driver</TargetName>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
    <EnableInf2cat>false</EnableInf2cat>
    <TargetName>driver</TargetName>
  </PropertyGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <ClCompile>
      <LanguageStandard>stdcpp17</LanguageStandard>
      <BufferSecurityCheck>false</BufferSecurityCheck>
      <ControlFlowGuard>false</ControlFlowGuard>
      <TreatWarningAsError>false</TreatWarningAsError>
    </ClCompile>
    <Link>
      <EntryPointSymbol>DriverEntry</EntryPointSymbol>
    </Link>
    <Inf>
      <SpecifyArchitecture>false</SpecifyArchitecture>
    </Inf>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    <ClCompile>
      <TreatWarningAsError>false</TreatWarningAsError>
      <LanguageStandard>stdcpp17</LanguageStandard>
    </ClCompile>
  </ItemDefinitionGroup>
  <ItemGroup>
    <FilesToPackage Include="$(TargetPath)" />
  </ItemGroup>
  <ItemGroup>
    <ClCompile Include="main.cpp" />
  </ItemGroup>
  <ItemGroup>
    <ClInclude Include="sdk.h" />
    <ClInclude Include="system.h" />
    <ClInclude Include="global.h" />
    <ClInclude Include="sharedmemory.h" />
    <ClInclude Include="memory.h" />
    <ClInclude Include="process.h" />
    <ClInclude Include="utils.h" />
  </ItemGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
  <ImportGroup Label="ExtensionTargets">
  </ImportGroup>
</Project>

================================================
FILE: Poseidon/Poseidon.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>
    <Filter Include="Header Files\sdk">
      <UniqueIdentifier>{877b8484-960c-4f48-978f-d985dc5a098a}</UniqueIdentifier>
    </Filter>
  </ItemGroup>
  <ItemGroup>
    <ClCompile Include="main.cpp">
      <Filter>Source Files</Filter>
    </ClCompile>
  </ItemGroup>
  <ItemGroup>
    <ClInclude Include="system.h">
      <Filter>Header Files\sdk</Filter>
    </ClInclude>
    <ClInclude Include="global.h">
      <Filter>Header Files\sdk</Filter>
    </ClInclude>
    <ClInclude Include="memory.h">
      <Filter>Header Files\sdk</Filter>
    </ClInclude>
    <ClInclude Include="process.h">
      <Filter>Header Files\sdk</Filter>
    </ClInclude>
    <ClInclude Include="utils.h">
      <Filter>Header Files\sdk</Filter>
    </ClInclude>
    <ClInclude Include="sharedmemory.h">
      <Filter>Header Files\sdk</Filter>
    </ClInclude>
    <ClInclude Include="sdk.h">
      <Filter>Header Files</Filter>
    </ClInclude>
  </ItemGroup>
</Project>

================================================
FILE: Poseidon/global.h
================================================
#pragma once
#include <ntifs.h>
#include <ntddk.h>
#include <IntSafe.h>
#include <ntimage.h>

enum Code {
	Complete,
	BaseRequest,
	SizeRequest,
	PebRequest,
	QIPRequest,
	CopyRequest,
	AVMRequest,
	FVMRequest,
	PVMRequest,
	QVMRequest,
	ModuleRequest,
	IndexRequest,
};

enum Status {
	Inactive,	// We'll use this status to let the driver know it can sleep for a while
	Active,		// We'll use this status to let the driver know we may be sending requests any second
	Waiting,	// We'll use this status to let the driver know we sent a request and are waiting for completion
	Exit		// We'll use this status to let the driver know it can exit the shared memory loop and untrap our thread
};

typedef struct OperationData {

	struct {
		char* Name;
		DWORD	Id;
		PVOID	BaseAddress;
		SIZE_T  Size;
		PPEB	Peb;
		PROCESS_BASIC_INFORMATION PBI;
	} Process;

	struct {
		SIZE_T Size;
		SIZE_T ReturnLength;

		struct {
			PVOID Address;
			PVOID Buffer;
			BOOLEAN	ReadOperation;
		} Copy;

		PVOID Base;
		DWORD AllocType;
		DWORD FreeType;
		DWORD Protect;
		DWORD OldProtect;
		MEMORY_BASIC_INFORMATION MBI;
	} Memory;

	struct {
		PVOID BaseAddress;
		SIZE_T SizeOfImage;
		int Index;
	} Module;
};

typedef struct CommunicationData {

	DWORD	ProcessId;
	PVOID	SharedMemory;
	DWORD*	pCode;
	SHORT*	pStatus;
	DWORD	Magic;
};

INT64(NTAPI *EnumerateDebuggingDevicesOriginal)(PVOID, PVOID);
CommunicationData gData{};
PEPROCESS gProcess{};
DWORD64 gFunc{};
CHAR* gKernelBase{};
DWORD ActiveThreadsOffset{ 0x5F0 };

typedef enum _SYSTEM_INFORMATION_CLASS 
{
	SystemBasicInformation,
	SystemProcessorInformation,
	SystemPerformanceInformation,
	SystemTimeOfDayInformation,
	SystemPathInformation,
	SystemProcessInformation,
	SystemCallCountInformation,
	SystemDeviceInformation,
	SystemProcessorPerformanceInformation,
	SystemFlagsInformation,
	SystemCallTimeInformation,
	SystemModuleInformation,
	SystemLocksInformation,
	SystemStackTraceInformation,
	SystemPagedPoolInformation,
	SystemNonPagedPoolInformation,
	SystemHandleInformation,
	SystemObjectInformation,
	SystemPageFileInformation,
	SystemVdmInstemulInformation,
	SystemVdmBopInformation,
	SystemFileCacheInformation,
	SystemPoolTagInformation,
	SystemInterruptInformation,
	SystemDpcBehaviorInformation,
	SystemFullMemoryInformation,
	SystemLoadGdiDriverInformation,
	SystemUnloadGdiDriverInformation,
	SystemTimeAdjustmentInformation,
	SystemSummaryMemoryInformation,
	SystemNextEventIdInformation,
	SystemEventIdsInformation,
	SystemCrashDumpInformation,
	SystemExceptionInformation,
	SystemCrashDumpStateInformation,
	SystemKernelDebuggerInformation,
	SystemContextSwitchInformation,
	SystemRegistryQuotaInformation,
	SystemExtendServiceTableInformation,
	SystemPrioritySeperation,
	SystemPlugPlayBusInformation,
	SystemDockInformation,
	SystemProcessorSpeedInformation,
	SystemCurrentTimeZoneInformation,
	SystemLookasideInformation
} SYSTEM_INFORMATION_CLASS, * PSYSTEM_INFORMATION_CLASS;

typedef struct _PEB_LDR_DATA 
{
	ULONG Length;
	UCHAR Initialized;
	PVOID SsHandle;
	LIST_ENTRY InLoadOrderModuleList;
	LIST_ENTRY InMemoryOrderModuleList;
	LIST_ENTRY InInitializationOrderModuleList;
} PEB_LDR_DATA, * PPEB_LDR_DATA;

typedef struct _LDR_DATA_TABLE_ENTRY 
{
	LIST_ENTRY InLoadOrderLinks;
	LIST_ENTRY InMemoryOrderLinks;
	LIST_ENTRY InInitializationOrderLinks;
	PVOID DllBase;
	PVOID EntryPoint;
	ULONG SizeOfImage;
	UNICODE_STRING FullDllName;
	UNICODE_STRING BaseDllName;
	ULONG Flags;
	USHORT LoadCount;
	USHORT TlsIndex;
	LIST_ENTRY HashLinks;
	ULONG TimeDateStamp;
} LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY;

typedef struct _PEB 
{
	UCHAR InheritedAddressSpace;
	UCHAR ReadImageFileExecOptions;
	UCHAR BeingDebugged;
	UCHAR BitField;
	PVOID Mutant;
	PVOID ImageBaseAddress;
	PPEB_LDR_DATA Ldr;
	PVOID ProcessParameters;
	PVOID SubSystemData;
	PVOID ProcessHeap;
	PVOID FastPebLock;
	PVOID AtlThunkSListPtr;
	PVOID IFEOKey;
	PVOID CrossProcessFlags;
	PVOID KernelCallbackTable;
	ULONG SystemReserved;
	ULONG AtlThunkSListPtr32;
	PVOID ApiSetMap;
} PEB, * PPEB;

typedef struct _SYSTEM_MODULE 
{
	HANDLE Section;
	PVOID MappedBase;
	PVOID ImageBase;
	ULONG ImageSize;
	ULONG Flags;
	USHORT LoadOrderIndex;
	USHORT InitOrderIndex;
	USHORT LoadCount;
	USHORT OffsetToFileName;
	UCHAR  FullPathName[MAXIMUM_FILENAME_LENGTH];
} SYSTEM_MODULE, *PSYSTEM_MODULE;

typedef struct _SYSTEM_MODULE_INFORMATION 
{
	ULONG NumberOfModules;
	SYSTEM_MODULE Modules[1];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;

typedef struct _RTL_PROCESS_MODULE_INFORMATION
{
	HANDLE Section;
	PVOID MappedBase;
	PVOID ImageBase;
	ULONG ImageSize;
	ULONG Flags;
	USHORT LoadOrderIndex;
	USHORT InitOrderIndex;
	USHORT LoadCount;
	USHORT OffsetToFileName;
	UCHAR  FullPathName[MAXIMUM_FILENAME_LENGTH];
} RTL_PROCESS_MODULE_INFORMATION, *PRTL_PROCESS_MODULE_INFORMATION;

typedef struct _RTL_PROCESS_MODULES
{
	ULONG NumberOfModules;
	RTL_PROCESS_MODULE_INFORMATION Modules[1];
} RTL_PROCESS_MODULES, *PRTL_PROCESS_MODULES;

typedef struct PiDDBCache
{
	LIST_ENTRY		List;
	UNICODE_STRING	DriverName;
	ULONG			TimeDateStamp;
	NTSTATUS		LoadStatus;
	char			_0x0028[16];
};

extern "C" 
{
	NTKERNELAPI
	PVOID
	PsGetProcessSectionBaseAddress(
		PEPROCESS Process
	);

	NTKERNELAPI
	PPEB
	NTAPI
	PsGetProcessPeb(
		PEPROCESS Process
	);

	NTKERNELAPI
	NTSTATUS
	MmCopyVirtualMemory(
		PEPROCESS SourceProcess,
		PVOID SourceAddress,
		PEPROCESS TarGet,
		PVOID TargetAddress,
		SIZE_T BufferSize,
		KPROCESSOR_MODE PreviousMode,
		PSIZE_T ReturnSize
	);

	NTSYSCALLAPI 
	NTSTATUS 
	NTAPI 
	ZwQuerySystemInformation(
		ULONG InfoClass,
		PVOID Buffer, 
		ULONG Length,
		PULONG ReturnLength
	);

	NTSYSCALLAPI
	NTSTATUS 
	ZwQueryInformationProcess(
		HANDLE ProcessHandle,
		PROCESSINFOCLASS ProcessInformationClass,
		PVOID ProcessInformation,
		ULONG ProcessInformationLength,
		PULONG ReturnLength
	);

	NTSYSCALLAPI 
	NTSTATUS 
	NTAPI 
	ZwProtectVirtualMemory(
		HANDLE ProcessHandle, 
		PVOID *BaseAddress, 
		PSIZE_T RegionSize,
		ULONG NewAccessProtection, 
		PULONG OldAccessProtection
	);
}

================================================
FILE: Poseidon/main.cpp
================================================
#include "sdk.h"

NTSTATUS DriverEntry(DRIVER_OBJECT* DriverObject, UNICODE_STRING* RegistryPath) {
	return Driver::Initialize();
}

================================================
FILE: Poseidon/memory.h
================================================
#pragma once
#include "process.h"

namespace Memory {

	template <typename T = PVOID> 
	T Allocate(SIZE_T Size) {
		return reinterpret_cast<T>(ExAllocatePool(NonPagedPool, Size));
	}

	VOID Free(PVOID Buffer) {
		ExFreePool(Buffer);
	}

	BOOLEAN Copy(PVOID Destination, PVOID Source, SIZE_T Size) {
		SIZE_T BytesRead{ 0 };
		return NT_SUCCESS(MmCopyVirtualMemory(IoGetCurrentProcess(), 
						      Source, 
						      IoGetCurrentProcess(), 
						      Destination, 
						      Size, 
						      KernelMode, 
						      &BytesRead)) && BytesRead == Size;
	}

	NTSTATUS CopyVirtualMemory(OperationData* Data) {
		NTSTATUS Status{ STATUS_SUCCESS };
		PEPROCESS eProcess{ Process::GetProcess(Data->Process.Id) };

		if (eProcess == nullptr) {
			return STATUS_UNSUCCESSFUL;
		}

		if (Data->Memory.Copy.ReadOperation) {
			Status = MmCopyVirtualMemory(eProcess, 
						     Data->Memory.Copy.Address, 
						     IoGetCurrentProcess(), 
						     Data->Memory.Copy.Buffer, 
						     Data->Memory.Size, 
						     UserMode, 
						     &Data->Memory.ReturnLength);
		} else {
			Status = MmCopyVirtualMemory(IoGetCurrentProcess(), 
						     Data->Memory.Copy.Buffer,
						     eProcess, 
						     Data->Memory.Copy.Address, 
						     Data->Memory.Size, 
						     UserMode, 
						     &Data->Memory.ReturnLength);
		}

		ObfDereferenceObject(eProcess);
		return Status;
	}

	NTSTATUS AllocateVirtualMemory(OperationData* Data) {
		KAPC_STATE Apc{ NULL };
		PEPROCESS eProcess{ Process::GetProcess(Data->Process.Id) };

		if (eProcess == nullptr) {
			return STATUS_UNSUCCESSFUL;
		}

		KeStackAttachProcess(eProcess, &Apc);

		NTSTATUS Status{ ZwAllocateVirtualMemory(ZwCurrentProcess(), 
							 &Data->Memory.Base, 
							 NULL, 
							 &Data->Memory.Size,
							 Data->Memory.AllocType,
							 Data->Memory.Protect) };

		KeUnstackDetachProcess(&Apc);
		ObfDereferenceObject(eProcess);
		return Status;
	}

	NTSTATUS FreeVirtualMemory(OperationData* Data) {
		KAPC_STATE Apc{ NULL };
		PEPROCESS eProcess{ Process::GetProcess(Data->Process.Id) };

		if (eProcess == nullptr) {
			return STATUS_UNSUCCESSFUL;
		}

		KeStackAttachProcess(eProcess, &Apc);

		NTSTATUS Status{ ZwFreeVirtualMemory(ZwCurrentProcess(),
						     &Data->Memory.Base,
						     &Data->Memory.Size,
						     Data->Memory.FreeType) };

		KeUnstackDetachProcess(&Apc);
		ObfDereferenceObject(eProcess);
		return Status;
	}

	NTSTATUS ProtectVirtualMemory(OperationData* Data) {
		KAPC_STATE Apc{ NULL };
		PEPROCESS eProcess{ Process::GetProcess(Data->Process.Id) };

		if (eProcess == nullptr) {
			return STATUS_UNSUCCESSFUL;
		}

		KeStackAttachProcess(eProcess, &Apc);

		NTSTATUS Status{ ZwProtectVirtualMemory(ZwCurrentProcess(), 
							&Data->Memory.Base, 
							&Data->Memory.Size,
							Data->Memory.Protect,
							&Data->Memory.OldProtect) };

		KeUnstackDetachProcess(&Apc);
		ObfDereferenceObject(eProcess);
		return Status;
	}

	NTSTATUS QueryVirtualMemory(OperationData* Data) {
		NTSTATUS Status{ STATUS_SUCCESS };
		KAPC_STATE Apc{ 0 };
		PEPROCESS eProcess{ Process::GetProcess(Data->Process.Id) };

		if (eProcess == nullptr) {
			return STATUS_UNSUCCESSFUL;
		}

		KeStackAttachProcess(eProcess, &Apc);

		Status = ZwQueryVirtualMemory(ZwCurrentProcess(), 
					      Data->Memory.Base,
					      MemoryBasicInformation, 
					      &Data->Memory.MBI, 
					      sizeof(Data->Memory.MBI),
					      &Data->Memory.ReturnLength);

		KeUnstackDetachProcess(&Apc);
		ObfDereferenceObject(eProcess);
		return Status;
	}
}


================================================
FILE: Poseidon/process.h
================================================
#pragma once
#include "global.h"

namespace Process {

	PEPROCESS GetProcess(DWORD ProcessId) {
		PEPROCESS eProcess{ nullptr };
		PsLookupProcessByProcessId(reinterpret_cast<HANDLE>(ProcessId), &eProcess);
		return eProcess;
	}

	NTSTATUS GetBaseAddress(OperationData* Data) {
		PEPROCESS eProcess{ GetProcess(Data->Process.Id) };

		if (eProcess == nullptr) {
			return STATUS_UNSUCCESSFUL;
		}

		Data->Process.BaseAddress = PsGetProcessSectionBaseAddress(eProcess);

		ObfDereferenceObject(eProcess);
		return Data->Process.BaseAddress ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
	}

	NTSTATUS GetMainModuleSize(OperationData* Data) {
		KAPC_STATE Apc{ 0 };
		DWORD Size{ NULL };
		PEPROCESS eProcess{ GetProcess(Data->Process.Id) };

		if (eProcess == nullptr) {
			return STATUS_UNSUCCESSFUL;
		}

		KeStackAttachProcess(eProcess, &Apc);

		if (LIST_ENTRY* ModuleEntry{ PsGetProcessPeb(eProcess)->Ldr->InLoadOrderModuleList.Flink }) {
			Data->Process.Size = CONTAINING_RECORD(ModuleEntry, 
							       LDR_DATA_TABLE_ENTRY, 
							       InLoadOrderLinks)->SizeOfImage;
		}

		KeUnstackDetachProcess(&Apc);
		ObfDereferenceObject(eProcess);

		return Data->Process.Size ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
	}

	NTSTATUS GetPeb(OperationData* Data) {
		PEPROCESS eProcess{ GetProcess(Data->Process.Id) };

		if (eProcess == nullptr) {
			return STATUS_UNSUCCESSFUL;
		}

		Data->Process.Peb = PsGetProcessPeb(eProcess);

		ObfDereferenceObject(eProcess);
		return Data->Process.Peb ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
	}

	NTSTATUS QueryInformation(OperationData* Data) {
		KAPC_STATE Apc{ 0 };
		PEPROCESS eProcess{ GetProcess(Data->Process.Id) };

		if (eProcess == nullptr) {
			return STATUS_UNSUCCESSFUL;
		}

		KeStackAttachProcess(eProcess, &Apc);

		NTSTATUS Status{ ZwQueryInformationProcess(ZwCurrentProcess(), 
							   ProcessBasicInformation, 
							   &Data->Process.PBI, 
							   sizeof(Data->Process.PBI),
							   nullptr) };

		KeUnstackDetachProcess(&Apc);
		ObfDereferenceObject(eProcess);
		return Status;
	}

	NTSTATUS GetModuleInfo(OperationData* Data) {
		KAPC_STATE Apc{ 0 };
		PVOID Base{ nullptr };
		DWORD Size{ NULL};
		UNICODE_STRING usModule{ 0 };

		if (Data->Process.Name) {
			ANSI_STRING asModule{ 0 };

			RtlInitAnsiString(&asModule, Data->Process.Name);
			if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(&usModule, &asModule, TRUE))) {
				return STATUS_UNSUCCESSFUL;
			}
		}

		PEPROCESS eProcess{ GetProcess(Data->Process.Id) };

		if (eProcess == nullptr) {
			return STATUS_UNSUCCESSFUL;
		}

		KeStackAttachProcess(eProcess, &Apc);

		LIST_ENTRY* List = &(PsGetProcessPeb(eProcess)->Ldr->InLoadOrderModuleList);

		for (LIST_ENTRY* Entry = List->Flink; Entry != List;) {
			auto Module{ CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks) };

			if (Module) {
				++Data->Module.Index;

				if (Data->Process.Name && !RtlCompareUnicodeString(&Module->BaseDllName, &usModule, TRUE)) {
					Data->Module.BaseAddress = Module->DllBase;
					Data->Module.SizeOfImage = Module->SizeOfImage;
				}
			}

			Entry = Module->InLoadOrderLinks.Flink;
		}

		KeUnstackDetachProcess(&Apc);
		RtlFreeUnicodeString(&usModule);
		ObfDereferenceObject(eProcess);
		return Data->Module.SizeOfImage ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
	}

	NTSTATUS GetModuleInfoByIndex(OperationData* Data) {
		KAPC_STATE Apc{ 0 };
		int Count{ 0 };
		PEPROCESS eProcess{ GetProcess(Data->Process.Id) };

		if (eProcess == nullptr) {
			return STATUS_UNSUCCESSFUL;
		}

		KeStackAttachProcess(eProcess, &Apc);

		LIST_ENTRY* List = &(PsGetProcessPeb(eProcess)->Ldr->InLoadOrderModuleList);

		for (LIST_ENTRY* Entry = List->Flink; Entry != List;) {
			auto Module{ CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks) };
		
			if (Module && Count == Data->Module.Index) {
				Data->Module.BaseAddress = Module->DllBase;
				Data->Module.SizeOfImage = Module->SizeOfImage;
				break;
			}

			Count += 1;
			Entry = Module->InLoadOrderLinks.Flink;
		}

		KeUnstackDetachProcess(&Apc);
		ObfDereferenceObject(eProcess);
		return STATUS_SUCCESS;
	}
}


================================================
FILE: Poseidon/sdk.h
================================================
#pragma once
#include "sharedmemory.h"

#define RVA(addr, size) (BYTE*)addr + *(INT*)((BYTE*)addr + ((size) - 4)) + size

namespace Driver {

	INT64 NTAPI EnumerateDebuggingDevicesHook(PVOID A1, PINT64 A2) {
		if (ExGetPreviousMode() != UserMode
		    || A1 == nullptr 
		    || !Utils::ProbeUserAddress(A1, sizeof(gData), sizeof(DWORD)) 
		    || !Memory::Copy(&gData, A1, sizeof(CommunicationData))
		    || gData.Magic != 0x999) {

			// NtConvertBetweenAuxiliaryCounterAndPerformanceCounter() was not called by our usermode client
			// Call the original EnumerateDebuggingDevices() for whoever called

			return EnumerateDebuggingDevicesOriginal(A1, A2);
		} 

		// NtConvertBetweenAuxiliaryCounterAndPerformanceCounter() was called by the usermode client
		// We're only able to execute code right now because the usermode thread within the client transitioned into the kernel to complete the system call
		// We can take advantage of this and execute code in our driver for as long as we want by simply never returning

		InterlockedExchangePointer((PVOID*)gFunc, (PVOID)EnumerateDebuggingDevicesOriginal); // Unhook EnumerateDebuggingDevices() - it can be detected easily
		
		SharedMemory::Loop();
	}

	NTSTATUS Initialize() {
		auto OSInfo{ System::GetOSVersion() };

		if (OSInfo.dwBuildNumber < 19041) {
			ActiveThreadsOffset = OSInfo.dwBuildNumber == 10240 ? 0x490 : 0x498;
		}

		if (gKernelBase = System::GetModuleInfo<char*>("ntoskrnl.exe")) {
			if (auto Func = Utils::FindPatternImage(gKernelBase, 
								"\x48\x8B\x05\x00\x00\x00\x00\x75\x07\x48\x8B\x05\x00\x00\x00\x00\xE8\x00\x00\x00\x00", 
								"xxx????xxxxx????x????")) {

				gFunc = (DWORD64)(Func = RVA(Func, 7));
				*(PVOID*)&EnumerateDebuggingDevicesOriginal = InterlockedExchangePointer((PVOID*)Func, (PVOID)EnumerateDebuggingDevicesHook); // Hook EnumerateDebuggingDevices()
				return STATUS_SUCCESS;
			}
		}

		return STATUS_UNSUCCESSFUL;
	}
}


================================================
FILE: Poseidon/sharedmemory.h
================================================
#pragma once
#include "memory.h"
#include "system.h"

namespace SharedMemory {

	BOOLEAN ReadSharedMemory(PVOID Address, PVOID Buffer, SIZE_T Size) {
		SIZE_T Bytes{ 0 };

		if (NT_SUCCESS(MmCopyVirtualMemory(gProcess, Address, IoGetCurrentProcess(), Buffer, Size, KernelMode, &Bytes))) {
			return TRUE;
		} return FALSE;
	}

	template <typename T>
	BOOLEAN WriteSharedMemory(PVOID Address, T Buffer, SIZE_T Size = sizeof(T)) {
		SIZE_T Bytes{ 0 };

		if (NT_SUCCESS(MmCopyVirtualMemory(IoGetCurrentProcess(), (PVOID)&Buffer, gProcess, Address, Size, KernelMode, &Bytes))) {
			return TRUE;
		} return FALSE;
	}

	BYTE GetStatus() {
		BYTE CurStatus{ 0 };
		ReadSharedMemory(gData.pStatus, &CurStatus, sizeof(SHORT));
		return CurStatus;
	}

	DWORD GetCode() {
		DWORD CurCode{ 0 };
		ReadSharedMemory(gData.pCode, &CurCode, sizeof(DWORD));
		return CurCode;
	}

	OperationData GetBuffer() {
		OperationData CurBuffer{ 0 };
		ReadSharedMemory(gData.SharedMemory, &CurBuffer, sizeof(OperationData));
		return CurBuffer;
	}

	BOOLEAN SetStatus(Status DesiredStatus) {
		return WriteSharedMemory<SHORT>(gData.pStatus, DesiredStatus);
	}

	BOOLEAN SetCode() {
		return WriteSharedMemory<DWORD>(gData.pCode, Complete);
	}

	BOOLEAN SetBuffer(OperationData Buffer) {
		return WriteSharedMemory<OperationData>(gData.SharedMemory, Buffer);
	}

	VOID Respond() {
		DWORD Code{ GetCode() };
		OperationData Params{ GetBuffer() };

		switch (Code) {

			case BaseRequest: {
				Process::GetBaseAddress(&Params);
				SetBuffer(Params);
				SetCode();
				SetStatus(Active);
			} break;

			case SizeRequest: {
				Process::GetMainModuleSize(&Params);
				SetBuffer(Params);
				SetCode();
				SetStatus(Active);
			} break;

			case PebRequest: {
				Process::GetPeb(&Params);
				SetBuffer(Params);
				SetCode();
				SetStatus(Active);
			} break;

			case QIPRequest: {
				Process::QueryInformation(&Params);
				SetBuffer(Params);
				SetCode();
				SetStatus(Active);
			} break;

			case CopyRequest: {
				Memory::CopyVirtualMemory(&Params);
				SetBuffer(Params);
				SetCode();
				SetStatus(Active);
			} break;

			case AVMRequest: {
				Memory::AllocateVirtualMemory(&Params);
				SetBuffer(Params);
				SetCode();
				SetStatus(Active);
			} break;

			case FVMRequest: {
				Memory::FreeVirtualMemory(&Params);
				SetBuffer(Params);
				SetCode();
				SetStatus(Active);
			} break;

			case PVMRequest: {
				Memory::ProtectVirtualMemory(&Params);
				SetBuffer(Params);
				SetCode();
				SetStatus(Active);
			} break;

			case QVMRequest: {
				Memory::QueryVirtualMemory(&Params);
				SetBuffer(Params);
				SetCode();
				SetStatus(Active);
			} break;

			case ModuleRequest: {
				Process::GetModuleInfo(&Params);
				SetBuffer(Params);
				SetCode();
				SetStatus(Active);
			} break;

			case IndexRequest: {
				Process::GetModuleInfoByIndex(&Params);
				SetBuffer(Params);
				SetCode();
				SetStatus(Active);
			} break;

			default: {
			} break;
		}
	}

	VOID Loop() {
		gProcess = Process::GetProcess(gData.ProcessId);

		if (gProcess == nullptr) {
			return;
		}

		for (;;) {

			if (*(DWORD*)((BYTE*)gProcess + ActiveThreadsOffset) == 1) {
				// We're the only active thread - the client must be trying to terminate
				ObfDereferenceObject(gProcess);
				return;
			}

			DWORD Status{ GetStatus() };

			switch (Status) {
				case Inactive: {
					Utils::Sleep(50);
				} break;

				case Active: {
					Utils::Sleep(1);
				} break;

				case Waiting: {
					Respond();
				} break;

				case Exit: {
					SetStatus(Inactive);
					ObfDereferenceObject(gProcess);
					return;
				} break;

				default: {
					Utils::Sleep(50);
				} break;
			}
		} 
	}
}

================================================
FILE: Poseidon/system.h
================================================
#pragma once
#include "global.h"
#include "utils.h"

namespace System {

	template <typename T = PVOID>
	T GetModuleInfo(const char* Name, DWORD* OutSize = nullptr) {
		PVOID Base{ nullptr };
		DWORD RequiredSize{ 0 };

		if (ZwQuerySystemInformation(SystemModuleInformation, 
				             nullptr,
					     NULL,
					     &RequiredSize) != STATUS_INFO_LENGTH_MISMATCH) {

			return reinterpret_cast<T>(nullptr);
		}

		auto Modules{ Memory::Allocate<SYSTEM_MODULE_INFORMATION*>(RequiredSize) };

		if (!Modules) {
			return reinterpret_cast<T>(nullptr);
		}

		if (!NT_SUCCESS(ZwQuerySystemInformation(SystemModuleInformation, 
							 Modules, 
							 RequiredSize, 
							 nullptr))) {
			Memory::Free(Modules);
			return reinterpret_cast<T>(nullptr);
		}

		for (DWORD i = 0; i < Modules->NumberOfModules; ++i) {
			SYSTEM_MODULE CurModule{ Modules->Modules[i] };

			if (strstr(Utils::LowerStr((CHAR*)CurModule.FullPathName), Name)) 
			{
				Base = CurModule.ImageBase;

				if (OutSize) {
					*OutSize = CurModule.ImageSize;
				}

				break;
			}
		}

		Memory::Free(Modules);
		return reinterpret_cast<T>(Base);
	}

	OSVERSIONINFOW GetOSVersion() {
		OSVERSIONINFOW OSInfo{ 0 };
		RtlGetVersion(&OSInfo);
		return OSInfo;
	}
}


================================================
FILE: Poseidon/utils.h
================================================
#pragma once
#include "global.h"

namespace Utils {

	VOID Sleep(INT ms) {
		LARGE_INTEGER li{ 0 };
		li.QuadPart = -10000;

		for (INT i{ 0 }; i < ms; i++) {
			KeDelayExecutionThread(KernelMode, FALSE, &li);
		}
	}

	BOOLEAN ProbeUserAddress(PVOID Address, SIZE_T Size, DWORD Alignment) {
		if (Size == 0) {
			return TRUE;
		}
		
		DWORD64 Current = (DWORD64)Address;
		if (((DWORD64)Address & (Alignment - 1)) != 0) {
			return FALSE;
		}

		DWORD64 Last{ Current + Size - 1 };

		if ((Last < Current) || (Last >= MmUserProbeAddress)) {
			return FALSE;
		}

		return TRUE;
	}

	CHAR* LowerStr(CHAR* Str) {
		for (CHAR* S = Str; *S; ++S) {
			*S = (CHAR)tolower(*S);
		}
		return Str;
	}

	BOOLEAN CheckMask(CHAR* Base, CHAR* Pattern, CHAR* Mask) {
		for (; *Mask; ++Base, ++Pattern, ++Mask) {
			if (*Mask == 'x' && *Base != *Pattern) {
				return FALSE;
			}
		}

		return TRUE;
	}

	PVOID FindPattern(CHAR* Base, DWORD Length, CHAR* Pattern, CHAR* Mask) {
		Length -= (DWORD)strlen(Mask);

		for (DWORD i = 0; i <= Length; ++i) {
			PVOID Addr{ &Base[i] };

			if (CheckMask(static_cast<PCHAR>(Addr), Pattern, Mask)) {
				return Addr;
			}
		}

		return 0;
	}

	PVOID FindPatternImage(CHAR* Base, CHAR* Pattern, CHAR* Mask) {
		PVOID Match{ 0 };

		IMAGE_NT_HEADERS* Headers{ (PIMAGE_NT_HEADERS)(Base + ((PIMAGE_DOS_HEADER)Base)->e_lfanew) };
		IMAGE_SECTION_HEADER* Sections{ IMAGE_FIRST_SECTION(Headers) };

		for (DWORD i = 0; i < Headers->FileHeader.NumberOfSections; ++i) {
			IMAGE_SECTION_HEADER* Section{ &Sections[i] };

			if (*(INT*)Section->Name == 'EGAP' || memcmp(Section->Name, ".text", 5) == 0) {
				Match = FindPattern(Base + Section->VirtualAddress, Section->Misc.VirtualSize, Pattern, Mask);

				if (Match) {
					break;
				}
			}
		}

		return Match;
	}
}


================================================
FILE: PoseidonClient/PoseidonClient.vcxproj
================================================
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" 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>
  </ItemGroup>
  <PropertyGroup Label="Globals">
    <VCProjectVersion>16.0</VCProjectVersion>
    <Keyword>Win32Proj</Keyword>
    <ProjectGuid>{46a9d08d-4962-4434-bc75-c60339512252}</ProjectGuid>
    <RootNamespace>PoseidonClient</RootNamespace>
    <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
    <ConfigurationType>Application</ConfigurationType>
    <UseDebugLibraries>true</UseDebugLibraries>
    <PlatformToolset>v142</PlatformToolset>
    <CharacterSet>Unicode</CharacterSet>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
    <ConfigurationType>Application</ConfigurationType>
    <UseDebugLibraries>false</UseDebugLibraries>
    <PlatformToolset>v142</PlatformToolset>
    <WholeProgramOptimization>true</WholeProgramOptimization>
    <CharacterSet>Unicode</CharacterSet>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
    <ConfigurationType>Application</ConfigurationType>
    <UseDebugLibraries>true</UseDebugLibraries>
    <PlatformToolset>v142</PlatformToolset>
    <CharacterSet>Unicode</CharacterSet>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
    <ConfigurationType>Application</ConfigurationType>
    <UseDebugLibraries>false</UseDebugLibraries>
    <PlatformToolset>v142</PlatformToolset>
    <WholeProgramOptimization>true</WholeProgramOptimization>
    <CharacterSet>Unicode</CharacterSet>
  </PropertyGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
  <ImportGroup Label="ExtensionSettings">
  </ImportGroup>
  <ImportGroup Label="Shared">
  </ImportGroup>
  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  </ImportGroup>
  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  </ImportGroup>
  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  </ImportGroup>
  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  </ImportGroup>
  <PropertyGroup Label="UserMacros" />
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
    <LinkIncremental>true</LinkIncremental>
    <TargetName>Client</TargetName>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    <LinkIncremental>false</LinkIncremental>
    <TargetName>Client</TargetName>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    <LinkIncremental>true</LinkIncremental>
    <TargetName>Client</TargetName>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <LinkIncremental>false</LinkIncremental>
    <TargetName>Client</TargetName>
  </PropertyGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
    <ClCompile>
      <WarningLevel>Level3</WarningLevel>
      <SDLCheck>true</SDLCheck>
      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <ConformanceMode>true</ConformanceMode>
      <LanguageStandard>stdcpp17</LanguageStandard>
    </ClCompile>
    <Link>
      <SubSystem>Console</SubSystem>
      <GenerateDebugInformation>true</GenerateDebugInformation>
    </Link>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    <ClCompile>
      <WarningLevel>Level3</WarningLevel>
      <FunctionLevelLinking>true</FunctionLevelLinking>
      <IntrinsicFunctions>true</IntrinsicFunctions>
      <SDLCheck>true</SDLCheck>
      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <ConformanceMode>true</ConformanceMode>
      <LanguageStandard>stdcpp17</LanguageStandard>
    </ClCompile>
    <Link>
      <SubSystem>Console</SubSystem>
      <EnableCOMDATFolding>true</EnableCOMDATFolding>
      <OptimizeReferences>true</OptimizeReferences>
      <GenerateDebugInformation>true</GenerateDebugInformation>
    </Link>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
    <ClCompile>
      <WarningLevel>Level3</WarningLevel>
      <SDLCheck>true</SDLCheck>
      <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <ConformanceMode>true</ConformanceMode>
      <LanguageStandard>stdcpp17</LanguageStandard>
    </ClCompile>
    <Link>
      <SubSystem>Console</SubSystem>
      <GenerateDebugInformation>true</GenerateDebugInformation>
    </Link>
  </ItemDefinitionGroup>
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <ClCompile>
      <WarningLevel>Level3</WarningLevel>
      <FunctionLevelLinking>true</FunctionLevelLinking>
      <IntrinsicFunctions>true</IntrinsicFunctions>
      <SDLCheck>true</SDLCheck>
      <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
      <ConformanceMode>true</ConformanceMode>
      <LanguageStandard>stdcpp17</LanguageStandard>
    </ClCompile>
    <Link>
      <SubSystem>Console</SubSystem>
      <EnableCOMDATFolding>true</EnableCOMDATFolding>
      <OptimizeReferences>true</OptimizeReferences>
      <GenerateDebugInformation>true</GenerateDebugInformation>
    </Link>
  </ItemDefinitionGroup>
  <ItemGroup>
    <ClCompile Include="main.cpp" />
  </ItemGroup>
  <ItemGroup>
    <ClInclude Include="global.h" />
    <ClInclude Include="memory.h" />
    <ClInclude Include="process.h" />
    <ClInclude Include="sdk.h" />
    <ClInclude Include="sharedmemory.h" />
  </ItemGroup>
  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
  <ImportGroup Label="ExtensionTargets">
  </ImportGroup>
</Project>

================================================
FILE: PoseidonClient/PoseidonClient.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;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
    </Filter>
    <Filter Include="Header Files">
      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
      <Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;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="Header Files\sdk">
      <UniqueIdentifier>{a1d20eea-b682-43a7-8ec6-07bcaa3f318a}</UniqueIdentifier>
    </Filter>
  </ItemGroup>
  <ItemGroup>
    <ClCompile Include="main.cpp">
      <Filter>Source Files</Filter>
    </ClCompile>
  </ItemGroup>
  <ItemGroup>
    <ClInclude Include="sdk.h">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="global.h">
      <Filter>Header Files\sdk</Filter>
    </ClInclude>
    <ClInclude Include="memory.h">
      <Filter>Header Files\sdk</Filter>
    </ClInclude>
    <ClInclude Include="process.h">
      <Filter>Header Files\sdk</Filter>
    </ClInclude>
    <ClInclude Include="sharedmemory.h">
      <Filter>Header Files\sdk</Filter>
    </ClInclude>
  </ItemGroup>
</Project>

================================================
FILE: PoseidonClient/global.h
================================================
#pragma once
#include <Windows.h>
#include <winternl.h>
#include <TlHelp32.h>
#include <iostream>
#include <vector>

PVOID(NTAPI *NtConvertBetweenAuxiliaryCounterAndPerformanceCounter)(PVOID, PVOID, PVOID, PVOID);

enum Code {
	Complete,
	BaseRequest,
	SizeRequest,
	PebRequest,
	QIPRequest,
	CopyRequest,
	AVMRequest,
	FVMRequest,
	PVMRequest,
	QVMRequest,
	ModuleRequest,
	IndexRequest,
};

enum Status {
	Inactive,
	Active,
	Waiting,
	Exit
};

typedef struct OperationData {

	struct {
		char* Name;
		DWORD	Id;
		PVOID	BaseAddress;
		SIZE_T  Size;
		PPEB	Peb;
		PROCESS_BASIC_INFORMATION PBI;
	} Process;

	struct {
		SIZE_T Size;
		SIZE_T ReturnLength;

		struct {
			PVOID Address;
			PVOID Buffer;
			BOOLEAN	ReadOperation;
		} Copy;

		PVOID Base;
		DWORD AllocType;
		DWORD FreeType;
		DWORD Protect;
		DWORD OldProtect;
		MEMORY_BASIC_INFORMATION MBI;
	} Memory;

	struct {
		PVOID BaseAddress;
		SIZE_T SizeOfImage;
		int Index;
	} Module;
};

typedef struct CommunicationData {

	DWORD	ProcessId;
	PVOID	SharedMemory;
	DWORD*	pCode;
	SHORT*	pStatus;
	DWORD	Magic;
};

typedef struct MODULE {
	PVOID BaseAddress;
	DWORD SizeOfImage;
};

================================================
FILE: PoseidonClient/main.cpp
================================================
#include "sdk.h"
#include <iomanip>

int main() {
	Client::Connect();

	// Manually calling the functions in process.h and memory.h

	DWORD ProcessId{ Process::GetProcessId(L"notepad.exe") };
	PVOID BaseAddress{ Process::GetBase(ProcessId) };
	int ExampleValue{ Memory::Read<int>(ProcessId, BaseAddress) };

	std::cout << "0x" << std::hex << BaseAddress << std::endl;
	std::cout << std::dec << ExampleValue << std::endl;

	getchar();

	// Or using a KProcess object

	auto Notepad{ KProcess(L"notepad.exe") };
	int ExampleValue2{ Notepad.Read<int>(Notepad.BaseAddress) };
	std::cout << "0x" << std::hex << Notepad.BaseAddress << std::endl;
	std::cout << std::dec << ExampleValue2 << std::endl;

	getchar();

	Client::Disconnect(); // Once this is called or usermode closed / crashed, we can never reobtain a connection to the driver without remapping it
}

================================================
FILE: PoseidonClient/memory.h
================================================
#pragma once
#include "process.h"

namespace Memory {

	bool Read(DWORD ProcessId, PVOID Address, PVOID Buffer, SIZE_T Size) {
		OperationData Data{ 0 };

		Data.Process.Id = ProcessId;
		Data.Memory.Copy.Address = Address;
		Data.Memory.Copy.Buffer = Buffer;
		Data.Memory.Size = Size;
		Data.Memory.Copy.ReadOperation = true;

		return SharedMemory::SendRequest(CopyRequest, Data);
	}
	
	template <typename T>
	T Read(DWORD ProcessId, PVOID Address, SIZE_T Size = sizeof(T)) {
		T Buffer{};
		Read(ProcessId, Address, static_cast<PVOID>(&Buffer), Size);
		return Buffer; 
	}

	bool Write(DWORD ProcessId, PVOID Address, PVOID Buffer, SIZE_T Size) {
		OperationData Data{ 0 };

		Data.Process.Id = ProcessId;
		Data.Memory.Copy.Address = Address;
		Data.Memory.Copy.Buffer = Buffer;
		Data.Memory.Size = Size;
		Data.Memory.Copy.ReadOperation = false;

		return SharedMemory::SendRequest(CopyRequest, Data);
	}

	template <typename T>
	bool Write(DWORD ProcessId, PVOID Address, T Value, SIZE_T Size = sizeof(T)) {
		OperationData Data{ 0 };

		Data.Process.Id = ProcessId;
		Data.Memory.Copy.Address = Address;
		Data.Memory.Copy.Buffer = &Value;
		Data.Memory.Size = Size;
		Data.Memory.Copy.ReadOperation = false;

		return SharedMemory::SendRequest(CopyRequest, Data);
	}

	PVOID AllocateVirtualMemory(DWORD ProcessId, PVOID Base, SIZE_T Size, DWORD AllocType, DWORD Protect) {
		OperationData Data{ 0 };

		Data.Process.Id = ProcessId;
		Data.Memory.Base = Base;
		Data.Memory.Size = Size;
		Data.Memory.AllocType = AllocType;
		Data.Memory.Protect = Protect;

		SharedMemory::SendRequest(AVMRequest, Data);
		return SharedMemory::GetBuffer().Memory.Base;
	}

	bool FreeVirtualMemory(DWORD ProcessId, PVOID Base, SIZE_T Size, DWORD FreeType) {
		OperationData Data{ 0 };

		Data.Process.Id = ProcessId;
		Data.Memory.Base = Base;
		Data.Memory.Size = Size;
		Data.Memory.AllocType = FreeType;

		return SharedMemory::SendRequest(FVMRequest, Data);
	}
	
	DWORD ProtectVirtualMemory(DWORD ProcessId, PVOID Base, SIZE_T Size, DWORD Protect, DWORD* OldProtect = nullptr) {
		OperationData Data{ 0 };

		Data.Process.Id = ProcessId;
		Data.Memory.Base = Base;
		Data.Memory.Size = Size;
		Data.Memory.Protect = Protect;

		if (SharedMemory::SendRequest(PVMRequest, Data)) {
			OperationData Buffer{ SharedMemory::GetBuffer() };

			if (OldProtect) {
				*OldProtect = Buffer.Memory.OldProtect;
			}

			return Buffer.Memory.Protect;
		}
	}

	bool QueryVirtualMemory(DWORD ProcessId, PVOID Address, MEMORY_BASIC_INFORMATION& MemoryBasicInfo, SIZE_T Size) {
		OperationData Data{ 0 };

		Data.Process.Id = ProcessId;
		Data.Memory.Base = Address;
		Data.Memory.Size = Size;

		if (SharedMemory::SendRequest(QVMRequest, Data)) {
			MemoryBasicInfo = SharedMemory::GetBuffer().Memory.MBI;
		}

		return MemoryBasicInfo.Protect ? true : false;
	}
}

================================================
FILE: PoseidonClient/process.h
================================================
#pragma once
#include "global.h"
#include "sharedmemory.h"

namespace Process {

	DWORD GetProcessId(const wchar_t* ImageName) {
		HANDLE Snapshot{ CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) };
		PROCESSENTRY32W Process{ sizeof(PROCESSENTRY32W) };

		if (Process32FirstW(Snapshot, &Process)) {
			do {
				if (!wcscmp(ImageName, Process.szExeFile)) {
					CloseHandle(Snapshot);
					return Process.th32ProcessID;
				}
			} while (Process32NextW(Snapshot, &Process));
		}

		CloseHandle(Snapshot);
		return NULL;
	}

	PVOID GetBase(DWORD ProcessId) {
		OperationData Data{ 0 };
		Data.Process.Id = ProcessId;
		
		if (SharedMemory::SendRequest(BaseRequest, Data)) {
			return SharedMemory::GetBuffer().Process.BaseAddress;
		} return nullptr;
	}

	DWORD GetSize(DWORD ProcessId) {
		OperationData Data{ 0 };
		Data.Process.Id = ProcessId;

		if (SharedMemory::SendRequest(SizeRequest, Data)) {
			return SharedMemory::GetBuffer().Process.Size;
		} return NULL;
	}

	template <typename T = PVOID>
	T GetModuleInfo(DWORD ProcessId, const char* ModuleName, DWORD &OutSize) {
		OperationData Data{ 0 };

		Data.Process.Id = ProcessId;
		Data.Process.Name = const_cast<char*>(ModuleName);

		if (SharedMemory::SendRequest(ModuleRequest, Data)) {
			OperationData Buffer{ SharedMemory::GetBuffer() };
			OutSize = Buffer.Module.SizeOfImage;
			return reinterpret_cast<T>(Buffer.Module.BaseAddress);
		}

		return {};
	}

	bool QueryInformation(DWORD ProcessId, PROCESS_BASIC_INFORMATION& PBI) {
		OperationData Data{ 0 };

		Data.Process.Id = ProcessId;

		if (SharedMemory::SendRequest(QIPRequest, Data)) {
			PBI = SharedMemory::GetBuffer().Process.PBI;
		}

		return PBI.PebBaseAddress ? true : false;
	}

	PPEB GetPeb(DWORD ProcessId) {
		OperationData Data{ 0 };
		Data.Process.Id = ProcessId;

		if (SharedMemory::SendRequest(PebRequest, Data)) {
			return SharedMemory::GetBuffer().Process.Peb;
		} return nullptr;
	}

	DWORD GetModuleCount(DWORD ProcessId) {
		OperationData Data{ 0 };

		Data.Process.Id = ProcessId;

		if (SharedMemory::SendRequest(ModuleRequest, Data)) {
			return SharedMemory::GetBuffer().Module.Index;
		} return NULL;
	}

	PVOID GetModuleByIndex(DWORD ProcessId, DWORD Index, DWORD& OutSize) {
		PVOID Base{ nullptr };
		OperationData Data{ 0 };

		Data.Process.Id = ProcessId;
		Data.Module.Index = Index;

		if (SharedMemory::SendRequest(IndexRequest, Data)) {
			OperationData Buffer{ SharedMemory::GetBuffer() };
			Base = Buffer.Module.BaseAddress;
			OutSize = Buffer.Module.SizeOfImage;
		}

		return Base;
	}
}


================================================
FILE: PoseidonClient/sdk.h
================================================
#pragma once
#include "memory.h"

namespace Client {
	bool ErrorFlag{ false };

	void KernelThread(PVOID LParam) {
		INT64 Status{ 0 };

		CommunicationData Data{ *(CommunicationData*)LParam };
		PVOID pData{ &Data };

		HMODULE Module{ LoadLibrary(L"ntdll.dll") };

		if (!Module) {
			return;
		}

		*(PVOID*)&NtConvertBetweenAuxiliaryCounterAndPerformanceCounter = GetProcAddress(Module, "NtConvertBetweenAuxiliaryCounterAndPerformanceCounter");

		if (!NtConvertBetweenAuxiliaryCounterAndPerformanceCounter) {
			return;
		}

		NtConvertBetweenAuxiliaryCounterAndPerformanceCounter((PVOID)1, &pData, &Status, nullptr);
		ErrorFlag = true; // NtConvertBetweenAuxiliaryCounterAndPerformanceCounter() is the call that transitions this thread into the kernel, and as such should not return until Client::Disconnect() is called.
	}

	void Connect() {
		CommunicationData Data{ 0 };

		PVOID Memory{ VirtualAlloc(nullptr, 
					   sizeof(OperationData) * 2, 
					   MEM_COMMIT | MEM_RESERVE, 
					   PAGE_READWRITE) };

		if (!Memory) {
			return;
		}

		Data.ProcessId = GetCurrentProcessId();
		Data.SharedMemory = Memory;
		Data.pCode = (DWORD*)Memory + sizeof(OperationData);
		Data.pStatus = (SHORT*)Data.pCode + 8;
		Data.Magic = 0x999;

		CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)KernelThread, &Data, 0, nullptr);

		Sleep(500);

		if (ErrorFlag) {
			std::cout << "Error Connecting";
			getchar();
			exit(0);
		}

		SharedMemory::Connect(Data);
	}

	void Disconnect() {
		SharedMemory::Disconnect();
	}
}

class KProcess {
public:

	wchar_t* ImageName{};
	DWORD ProcessId{};
	PVOID BaseAddress{};
	DWORD Size{};
	PPEB Peb{};
	DWORD ModuleCount{};
	std::vector <MODULE> ModuleList{};

	KProcess(const wchar_t* ImageName) {
		this->ImageName = const_cast<wchar_t*>(ImageName);
		this->ProcessId = Process::GetProcessId(ImageName);
		this->BaseAddress = Process::GetBase(this->ProcessId);
		this->Size = Process::GetSize(this->ProcessId);
		this->Peb = Process::GetPeb(this->ProcessId);
		this->ModuleCount = Process::GetModuleCount(this->ProcessId);

		for (int i = 0; i < this->ModuleCount; i++) {
			DWORD SizeOfImage{ 0 };
			PVOID BaseAddress{ Process::GetModuleByIndex(this->ProcessId, i, SizeOfImage) };
			ModuleList.push_back({ BaseAddress, SizeOfImage });
		}
	}

	template <typename T>
	T GetModuleInfo(const char* ModuleName, DWORD &OutSize) {
		return Process::GetModuleInfo<T>(this->ProcessId, ModuleName, OutSize);
	}

	PROCESS_BASIC_INFORMATION QueryInformationProcess() {
		PROCESS_BASIC_INFORMATION Pbi{ 0 };
		Process::QueryInformation(this->ProcessId, Pbi);
		return Pbi;
	}

	bool Read(PVOID Address, PVOID Buffer, SIZE_T Size) {
		return Memory::Read(this->ProcessId, Address, Buffer, Size);
	}
	
	template <typename T>
	T Read(PVOID Address, SIZE_T Size = sizeof(T)) {
		return Memory::Read<T>(this->ProcessId, Address, Size);
	}

	bool Write(PVOID Address, PVOID Buffer, SIZE_T Size) {
		return Memory::Write(this->ProcessId, Address, Buffer, Size);
	}

	template <typename T>
	bool Write(PVOID Address, T Value, SIZE_T Size = sizeof(T)) {
		return Memory::Write<T>(this->ProcessId, Address, Value, Size);
	}

	PVOID AllocateVirtualMemory(PVOID Base, SIZE_T Size, DWORD AllocType, DWORD Protect) {
		return Memory::AllocateVirtualMemory(this->ProcessId, Base, Size, AllocType, Protect);
	}

	bool FreeVirtualMemory(PVOID Base, SIZE_T Size, DWORD FreeType) {
		return Memory::FreeVirtualMemory(this->ProcessId, Base, Size, FreeType);
	}
	
	DWORD ProtectVirtualMemory(PVOID Base, SIZE_T Size, DWORD Protect, DWORD* OldProtect) {
		return Memory::ProtectVirtualMemory(this->ProcessId, Base, Size, Protect, OldProtect);
	}

	bool QueryVirtualMemory(PVOID Address, MEMORY_BASIC_INFORMATION& MemoryBasicInfo, SIZE_T Size) {
		return Memory::QueryVirtualMemory(this->ProcessId, Address, MemoryBasicInfo, Size);
	}

	MEMORY_BASIC_INFORMATION QueryVirtualMemory(PVOID Address, SIZE_T Size) {
		MEMORY_BASIC_INFORMATION Mbi{ 0 };
		this->QueryVirtualMemory(Address, Mbi, Size);
		return Mbi;
	}

	BYTE* PatternFinder(BYTE* Start, DWORD Size, const char* Signature, const char* Mask) {
		auto CompareData = [] (const char* Data, const char* Signature, const char* Mask) -> BOOL {
			for (; *Mask; ++Mask, ++Data, ++Signature) {
				if (*Mask == 'x' && *Data != *Signature) {
					return FALSE;
				}
			}
			return (*Mask == NULL);
		};

		auto Buffer{ static_cast<char*>(VirtualAlloc(nullptr, Size, MEM_COMMIT, PAGE_READWRITE)) };
		this->Read(Start, Buffer, Size);

		for (DWORD64 i = 0; i < Size; i++) {
			if (CompareData(Buffer + i, Signature, Mask)) {
				VirtualFree(Buffer, 0, MEM_RELEASE);
				return Start + i;
			}
		}

		VirtualFree(Buffer, NULL, MEM_RELEASE);
		return NULL;
	}

	BYTE* AbsoluteAddress(BYTE* Rip, DWORD InstructionLength) {
		DWORD RelativeOffset{ 0 };
		this->Read(Rip + InstructionLength - 4, &RelativeOffset, sizeof(DWORD));
		return Rip + InstructionLength + RelativeOffset;
	}

	BYTE* RelativeAddress(BYTE* DestinationAddress, BYTE* SourceAddress, DWORD InstructionLength) {
		return reinterpret_cast<BYTE*>(reinterpret_cast<uint64_t>(SourceAddress) 
					       - InstructionLength 
					       - reinterpret_cast<uint64_t>(DestinationAddress));
	}
};


================================================
FILE: PoseidonClient/sharedmemory.h
================================================
#pragma once
#include "global.h"

namespace SharedMemory {

	CommunicationData Data{ 0 };
	INT Queue{ 0 };


	void PushQueue() {
		Queue += 1;
	}

	void PopQueue() {
		Queue -= 1;
	}

	BOOL WriteSharedMemory(PVOID Address, PVOID Value, SIZE_T Size) {
		return reinterpret_cast<BOOL>(memcpy(Address, Value, Size));
	}

	template <typename T>
	T ReadSharedMemory(PVOID Address, SIZE_T Size = sizeof(T)) {
		T Ret{ 0 };
		memcpy(static_cast<PVOID>(&Ret), Address, Size);
		return Ret;
	}

	BOOL SetStatus(Status Status) {
		return WriteSharedMemory(Data.pStatus, &Status, sizeof(SHORT));
	}

	BOOL SetCode(DWORD Code) {
		return WriteSharedMemory(Data.pCode, &Code, sizeof(DWORD));
	}

	BOOL SetBuffer(OperationData Buffer) {
		return WriteSharedMemory(Data.SharedMemory, &Buffer, sizeof(OperationData));
	}

	Status GetStatus() {
		return static_cast<Status>(ReadSharedMemory<SHORT>(Data.pStatus));
	}

	DWORD GetCode() {
		return ReadSharedMemory<DWORD>(Data.pCode);
	}

	OperationData GetBuffer() {
		return ReadSharedMemory<OperationData>(Data.SharedMemory);
	}

	BOOL SendRequest(Code Request, OperationData Data) {

		do {
			Sleep(10);
		} while (GetCode() != Complete 
			 || GetStatus() != Active 
			 || Queue >= 1);

		PushQueue();

		if (SetBuffer(Data)) {
			if (SetCode(Request)) {
				if (SetStatus(Waiting)) {

					do {
						Sleep(10);
					} while (GetCode() != Complete || GetStatus() != Active);

					PopQueue();
					return true;
				}
			}
		}

		PopQueue();
		return false;
	}

	void Connect(CommunicationData InitData) {
		Data = InitData;
		SetStatus(Active);
		SetCode(Complete);
	}

	void Disconnect() {
		SetStatus(Exit);
	}
};

================================================
FILE: README.md
================================================
# KM-UM-Communication

Stealthy UM <-> KM communication system without creating any system threads, permanent hooks, driver objects, section objects or device objects.

Process:

- In our driver, we hook a function in ntoskrnl (.data pointer swap)
- In usermode, we manually allocate memory and index it via custom data structures
- We then create a thread in usermode and call the hooked function's corresponding usermode-accessible function
- When the correct magic number is passed to the function, the driver will know it's us, and will then unhook and enter a shared memory loop, trapping our usermode thread in the kernel until we choose to break out of the loop

As long as this is set up prior to any anti-cheat being active on your system, you can communicate with the driver without being detected by most of the various security measures employed by invasive anti-cheat technologies such as BattlEye and EasyAntiCheat.

2023 Update: There are quite a few detection vectors that can be identified by BE and EAC, some of which are discussed in (now closed) issues. Most are easy to bypass, but others are a bit more tricky. Having said that, I still have never had any action taken against me for using this for relatively licit purposes (i.e. no aimbot, ESP, or any other blatant violative use), nor has anyone I know who's used it. Regardless, steps should be taken to mitigate any potential detection vectors. I will not be providing any updates or revisions, as this is nearly four years old and there are far superior options to accomplish stealthy communication. This is mainly meant to serve as an interesting, novel communication method that demostrates the potential creativity that can be employed to get around invasive security software, mainly anti-cheat software.

Limitations:

- Dodgy synchronization
- Not many kernel features, just basic remote-process operability
- Not designed with safety as a priority (i.e. you may well BSOD)
- Only tested on Windows 10 20H2
- The client can only be used once. If you terminate it or call Client::Disconnect(), you'll need to remap the driver

The driver is intended to be manually mapped by exploiting Intel's vulnerable network adapter diagnostic driver, iqvw64e.sys (or any other suitable vulnerable driver).

This was created for fun, I do not condone the use of this code in any program that violates the integrity of any online game, nor do I condone the use of this in any malicious software. This should only be used for learning purposes or to prevent custom software from being falsely detected as an illicit program.

Usage:

- Map the driver
- Start the client
- Start the target process
- Do stuff

You have to modify the client to sleep until your target process is running (since it must be set up prior to any anti-cheat being active). Basic example of how main.cpp in the client should typically look:

```
int main() {
	Client::Connect();

	for (;;) {
		Sleep(100);

		if (YourTargetProcessIsRunning) {
			break;
		}
	}

	// Do stuff
  
        Client::Disconnect();
  }
  ```
  
You can either call the functions in memory.h and process.h manually, or you can just create a KProcess object for easier use. KProcess features are as follows:

```

	// Make a process object for your target process
	
	KProcess Notepad(L"notepad.exe");
	
	
        // Read Memory

	int Value = Notepad.Read<int>((PVOID)0xDEADBEEF);
	Notepad.Read((PVOID)0xDEADBEEF, &Value, sizeof(int)); // Overload


	// Write Memory

	Notepad.Write<int>((PVOID)0xDEADBEEF, 2);
	Notepad.Write((PVOID)0xDEADBEEF, &Value, sizeof(int)); // Overload


	// Allocate Virtual Memory

	Notepad.AllocateVirtualMemory(PVOID Base, SIZE_T Size, DWORD AllocType, DWORD Protect);


	// Free Virtual Memory

	Notepad.FreeVirtualMemory(PVOID Base, SIZE_T Size, DWORD FreeType);


	// Change Virtual Memory Protection

	Notepad.ProtectVirtualMemory(PVOID Base, SIZE_T Size, DWORD Protect, DWORD* OldProtect);


	// Query Virtual Memory. MEMORY_BASIC_INFORMATION only.

	MEMORY_BASIC_INFORMATION MBI{ 0 };

	bool bResult = Notepad.QueryVirtualMemory(PVOID Address, MEMORY_BASIC_INFORMATION& MemoryBasicInfo, SIZE_T Size);
	MBI = Notepad.QueryVirtualMemory(PVOID Address, SIZE_T Size); // Overload


	// Query Process Information

	Notepad.QueryInformationProcess();


	// Get module info by name

	Notepad.GetModuleInfo(const char* ModuleName, DWORD& ModuleSize);


	// Pattern finder

	Notepad.PatternFinder(BYTE* Start, DWORD Size, const char* Signature, const char* Mask);


	// Get absolute address within specified asm instruction

	Notepad.AbsoluteAddress(BYTE* Rip, DWORD InstructionLength);


	// Get relative address within specified asm instruction

	Notepad.RelativeAddress(BYTE* DestinationAddress, BYTE* SourceAddress, DWORD InstructionLength);


	Notepad.BaseAddress;     // Base Address
	Notepad.ImageName;	 // Name
	Notepad.ModuleCount;     // Number of modules
	Notepad.ModuleList;      // std::vector containing all modules' base address and size
	Notepad.Peb;		 // Process Environment Block
	Notepad.ProcessId;	 // Process Id
	Notepad.Size;		 // Main module size
  ```
Download .txt
gitextract__tzj7agv/

├── .gitignore
├── Poseidon/
│   ├── Poseidon.sln
│   ├── Poseidon.vcxproj
│   ├── Poseidon.vcxproj.filters
│   ├── global.h
│   ├── main.cpp
│   ├── memory.h
│   ├── process.h
│   ├── sdk.h
│   ├── sharedmemory.h
│   ├── system.h
│   └── utils.h
├── PoseidonClient/
│   ├── PoseidonClient.vcxproj
│   ├── PoseidonClient.vcxproj.filters
│   ├── global.h
│   ├── main.cpp
│   ├── memory.h
│   ├── process.h
│   ├── sdk.h
│   └── sharedmemory.h
└── README.md
Download .txt
SYMBOL INDEX (67 symbols across 14 files)

FILE: Poseidon/global.h
  type Code (line 7) | enum Code {
  type Status (line 22) | enum Status {
  type OperationData (line 29) | struct OperationData {
  type CommunicationData (line 65) | struct CommunicationData {
  function CommunicationData (line 75) | CommunicationData gData{}
  function PEPROCESS (line 76) | PEPROCESS gProcess{}
  function DWORD64 (line 77) | DWORD64 gFunc{}
  function CHAR (line 78) | CHAR* gKernelBase{}
  function DWORD (line 79) | DWORD ActiveThreadsOffset{ 0x5F0 };

FILE: Poseidon/main.cpp
  function NTSTATUS (line 3) | NTSTATUS DriverEntry(DRIVER_OBJECT* DriverObject, UNICODE_STRING* Regist...

FILE: Poseidon/memory.h
  function namespace (line 4) | namespace Memory {
  function VOID (line 11) | VOID Free(PVOID Buffer) {
  function BOOLEAN (line 15) | BOOLEAN Copy(PVOID Destination, PVOID Source, SIZE_T Size) {
  function PEPROCESS (line 28) | PEPROCESS eProcess{ Process::GetProcess(Data->Process.Id) };
  function NTSTATUS (line 66) | NTSTATUS Status{ ZwAllocateVirtualMemory(ZwCurrentProcess(),
  function NTSTATUS (line 88) | NTSTATUS Status{ ZwFreeVirtualMemory(ZwCurrentProcess(),
  function NTSTATUS (line 108) | NTSTATUS Status{ ZwProtectVirtualMemory(ZwCurrentProcess(),
  function NTSTATUS (line 120) | NTSTATUS Status{ STATUS_SUCCESS };

FILE: Poseidon/process.h
  function PEPROCESS (line 7) | PEPROCESS eProcess{ nullptr };
  function PEPROCESS (line 13) | PEPROCESS eProcess{ GetProcess(Data->Process.Id) };
  function KAPC_STATE (line 26) | KAPC_STATE Apc{ 0 }
  function PEPROCESS (line 49) | PEPROCESS eProcess{ GetProcess(Data->Process.Id) };
  function KAPC_STATE (line 62) | KAPC_STATE Apc{ 0 }
  function NTSTATUS (line 71) | NTSTATUS Status{ ZwQueryInformationProcess(ZwCurrentProcess(),
  function KAPC_STATE (line 83) | KAPC_STATE Apc{ 0 }
  function PVOID (line 84) | PVOID Base{ nullptr };

FILE: Poseidon/sdk.h
  function namespace (line 6) | namespace Driver {

FILE: Poseidon/sharedmemory.h
  function BOOLEAN (line 7) | BOOLEAN ReadSharedMemory(PVOID Address, PVOID Buffer, SIZE_T Size) {
  function SIZE_T (line 17) | SIZE_T Bytes{ 0 }
  function BYTE (line 24) | BYTE GetStatus() {
  function DWORD (line 30) | DWORD GetCode() {
  function OperationData (line 36) | OperationData GetBuffer() {
  function BOOLEAN (line 42) | BOOLEAN SetStatus(Status DesiredStatus) {
  function BOOLEAN (line 46) | BOOLEAN SetCode() {
  function BOOLEAN (line 50) | BOOLEAN SetBuffer(OperationData Buffer) {
  function OperationData (line 56) | OperationData Params{ GetBuffer() };
  function VOID (line 142) | VOID Loop() {

FILE: Poseidon/system.h
  function DWORD (line 10) | DWORD RequiredSize{ 0 }
  function Modules (line 20) | auto Modules{ Memory::Allocate<SYSTEM_MODULE_INFORMATION*>(RequiredSize) };

FILE: Poseidon/utils.h
  function VOID (line 6) | VOID Sleep(INT ms) {
  function DWORD64 (line 25) | DWORD64 Last{ Current + Size - 1 };
  function CHAR (line 34) | CHAR* LowerStr(CHAR* Str) {
  function BOOLEAN (line 41) | BOOLEAN CheckMask(CHAR* Base, CHAR* Pattern, CHAR* Mask) {
  function PVOID (line 55) | PVOID Addr{ &Base[i] };
  function PVOID (line 66) | PVOID Match{ 0 }
  function IMAGE_NT_HEADERS (line 68) | IMAGE_NT_HEADERS* Headers{ (PIMAGE_NT_HEADERS)(Base + ((PIMAGE_DOS_HEADE...

FILE: PoseidonClient/global.h
  type Code (line 10) | enum Code {
  type Status (line 25) | enum Status {
  type OperationData (line 32) | struct OperationData {
  type CommunicationData (line 68) | struct CommunicationData {
  type MODULE (line 77) | struct MODULE {

FILE: PoseidonClient/main.cpp
  function main (line 4) | int main() {

FILE: PoseidonClient/memory.h
  function namespace (line 4) | namespace Memory {

FILE: PoseidonClient/process.h
  function HANDLE (line 8) | HANDLE Snapshot{ CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) };
  function PVOID (line 24) | PVOID GetBase(DWORD ProcessId) {
  function DWORD (line 33) | DWORD GetSize(DWORD ProcessId) {
  function OperationData (line 44) | OperationData Data{ 0 }
  function OperationData (line 50) | OperationData Buffer{ SharedMemory::GetBuffer() };
  function QueryInformation (line 58) | bool QueryInformation(DWORD ProcessId, PROCESS_BASIC_INFORMATION& PBI) {
  function PPEB (line 70) | PPEB GetPeb(DWORD ProcessId) {
  function DWORD (line 79) | DWORD GetModuleCount(DWORD ProcessId) {
  function PVOID (line 90) | PVOID Base{ nullptr };

FILE: PoseidonClient/sdk.h
  function INT64 (line 8) | INT64 Status{ 0 }
  function HMODULE (line 13) | HMODULE Module{ LoadLibrary(L"ntdll.dll") };
  function Connect (line 29) | void Connect() {
  function class (line 65) | class KProcess {

FILE: PoseidonClient/sharedmemory.h
  function namespace (line 4) | namespace SharedMemory {
Condensed preview — 21 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (76K chars).
[
  {
    "path": ".gitignore",
    "chars": 6534,
    "preview": "\n# Created by https://www.toptal.com/developers/gitignore/api/visualstudio\n# Edit at https://www.toptal.com/developers/g"
  },
  {
    "path": "Poseidon/Poseidon.sln",
    "chars": 1689,
    "preview": "\r\nMicrosoft Visual Studio Solution File, Format Version 12.00\r\n# Visual Studio Version 16\r\nVisualStudioVersion = 16.0.3"
  },
  {
    "path": "Poseidon/Poseidon.vcxproj",
    "chars": 4286,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project DefaultTargets=\"Build\" ToolsVersion=\"12.0\" xmlns=\"http://schemas.micro"
  },
  {
    "path": "Poseidon/Poseidon.vcxproj.filters",
    "chars": 1972,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbui"
  },
  {
    "path": "Poseidon/global.h",
    "chars": 6336,
    "preview": "#pragma once\r\n#include <ntifs.h>\r\n#include <ntddk.h>\r\n#include <IntSafe.h>\r\n#include <ntimage.h>\r\n\r\nenum Code {\r\n\tComple"
  },
  {
    "path": "Poseidon/main.cpp",
    "chars": 135,
    "preview": "#include \"sdk.h\"\r\n\r\nNTSTATUS DriverEntry(DRIVER_OBJECT* DriverObject, UNICODE_STRING* RegistryPath) {\r\n\treturn Driver::I"
  },
  {
    "path": "Poseidon/memory.h",
    "chars": 3683,
    "preview": "#pragma once\r\n#include \"process.h\"\r\n\r\nnamespace Memory {\r\n\r\n\ttemplate <typename T = PVOID> \r\n\tT Allocate(SIZE_T Size) {\r"
  },
  {
    "path": "Poseidon/process.h",
    "chars": 4261,
    "preview": "#pragma once\r\n#include \"global.h\"\r\n\r\nnamespace Process {\r\n\r\n\tPEPROCESS GetProcess(DWORD ProcessId) {\r\n\t\tPEPROCESS eProce"
  },
  {
    "path": "Poseidon/sdk.h",
    "chars": 1984,
    "preview": "#pragma once\r\n#include \"sharedmemory.h\"\r\n\r\n#define RVA(addr, size) (BYTE*)addr + *(INT*)((BYTE*)addr + ((size) - 4)) + s"
  },
  {
    "path": "Poseidon/sharedmemory.h",
    "chars": 3870,
    "preview": "#pragma once\r\n#include \"memory.h\"\r\n#include \"system.h\"\r\n\r\nnamespace SharedMemory {\r\n\r\n\tBOOLEAN ReadSharedMemory(PVOID Ad"
  },
  {
    "path": "Poseidon/system.h",
    "chars": 1303,
    "preview": "#pragma once\r\n#include \"global.h\"\r\n#include \"utils.h\"\r\n\r\nnamespace System {\r\n\r\n\ttemplate <typename T = PVOID>\r\n\tT GetMod"
  },
  {
    "path": "Poseidon/utils.h",
    "chars": 1872,
    "preview": "#pragma once\r\n#include \"global.h\"\r\n\r\nnamespace Utils {\r\n\r\n\tVOID Sleep(INT ms) {\r\n\t\tLARGE_INTEGER li{ 0 };\r\n\t\tli.QuadPart"
  },
  {
    "path": "PoseidonClient/PoseidonClient.vcxproj",
    "chars": 7782,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/ms"
  },
  {
    "path": "PoseidonClient/PoseidonClient.vcxproj.filters",
    "chars": 1620,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbui"
  },
  {
    "path": "PoseidonClient/global.h",
    "chars": 1225,
    "preview": "#pragma once\r\n#include <Windows.h>\r\n#include <winternl.h>\r\n#include <TlHelp32.h>\r\n#include <iostream>\r\n#include <vector>"
  },
  {
    "path": "PoseidonClient/main.cpp",
    "chars": 882,
    "preview": "#include \"sdk.h\"\r\n#include <iomanip>\r\n\r\nint main() {\r\n\tClient::Connect();\r\n\r\n\t// Manually calling the functions in proce"
  },
  {
    "path": "PoseidonClient/memory.h",
    "chars": 2949,
    "preview": "#pragma once\r\n#include \"process.h\"\r\n\r\nnamespace Memory {\r\n\r\n\tbool Read(DWORD ProcessId, PVOID Address, PVOID Buffer, SIZ"
  },
  {
    "path": "PoseidonClient/process.h",
    "chars": 2655,
    "preview": "#pragma once\r\n#include \"global.h\"\r\n#include \"sharedmemory.h\"\r\n\r\nnamespace Process {\r\n\r\n\tDWORD GetProcessId(const wchar_t"
  },
  {
    "path": "PoseidonClient/sdk.h",
    "chars": 5391,
    "preview": "#pragma once\r\n#include \"memory.h\"\r\n\r\nnamespace Client {\r\n\tbool ErrorFlag{ false };\r\n\r\n\tvoid KernelThread(PVOID LParam) {"
  },
  {
    "path": "PoseidonClient/sharedmemory.h",
    "chars": 1743,
    "preview": "#pragma once\r\n#include \"global.h\"\r\n\r\nnamespace SharedMemory {\r\n\r\n\tCommunicationData Data{ 0 };\r\n\tINT Queue{ 0 };\r\n\r\n\r\n\tv"
  },
  {
    "path": "README.md",
    "chars": 5119,
    "preview": "# KM-UM-Communication\n\nStealthy UM <-> KM communication system without creating any system threads, permanent hooks, dri"
  }
]

About this extraction

This page contains the full source code of the paradoxwastaken/Poseidon GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 21 files (65.7 KB), approximately 18.4k tokens, and a symbol index with 67 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!