Showing preview only (1,515K chars total). Download the full file or copy to clipboard to get everything.
Repository: jsecurity101/JonMon
Branch: main
Commit: ce5de1c7c647
Files: 87
Total size: 1.4 MB
Directory structure:
gitextract_k5_9flv0/
├── .github/
│ └── ISSUE_TEMPLATE/
│ ├── bug_report.md
│ └── feature_request.md
├── .gitignore
├── Extensions/
│ └── Extension1/
│ └── JonMon-Ext1/
│ ├── JonMon-Ext1.vcxproj
│ ├── dllmain.cpp
│ ├── dllmain.h
│ ├── framework.h
│ ├── pch.cpp
│ └── pch.h
├── JonMon/
│ ├── JonMon.sln
│ ├── JonMon.vcxproj
│ ├── callbacks.cpp
│ ├── callbacks.h
│ ├── driver.cpp
│ ├── driver.h
│ ├── jtime.h
│ ├── minifilter.cpp
│ ├── minifilter.h
│ ├── process.cpp
│ ├── process.h
│ ├── registry.cpp
│ ├── registry.h
│ └── shared.h
├── JonMon-Service/
│ ├── JonMon-Service.vcxproj
│ ├── JonMonService.cpp
│ ├── config.cpp
│ ├── config.h
│ ├── context.cpp
│ ├── context.h
│ ├── etwMain.cpp
│ ├── etwMain.h
│ ├── global.h
│ ├── service.cpp
│ └── service.h
├── JonMonConfig.json
├── JonMonProvider/
│ ├── jonmon.h
│ ├── jonmon.man
│ ├── jonmon.rc
│ └── jonmon.res
├── LICENSE
├── Libs/
│ └── nlohmann/
│ ├── adl_serializer.hpp
│ ├── byte_container_with_subtype.hpp
│ ├── detail/
│ │ ├── abi_macros.hpp
│ │ ├── conversions/
│ │ │ ├── from_json.hpp
│ │ │ ├── to_chars.hpp
│ │ │ └── to_json.hpp
│ │ ├── exceptions.hpp
│ │ ├── hash.hpp
│ │ ├── input/
│ │ │ ├── binary_reader.hpp
│ │ │ ├── input_adapters.hpp
│ │ │ ├── json_sax.hpp
│ │ │ ├── lexer.hpp
│ │ │ ├── parser.hpp
│ │ │ └── position_t.hpp
│ │ ├── iterators/
│ │ │ ├── internal_iterator.hpp
│ │ │ ├── iter_impl.hpp
│ │ │ ├── iteration_proxy.hpp
│ │ │ ├── iterator_traits.hpp
│ │ │ ├── json_reverse_iterator.hpp
│ │ │ └── primitive_iterator.hpp
│ │ ├── json_custom_base_class.hpp
│ │ ├── json_pointer.hpp
│ │ ├── json_ref.hpp
│ │ ├── macro_scope.hpp
│ │ ├── macro_unscope.hpp
│ │ ├── meta/
│ │ │ ├── call_std/
│ │ │ │ ├── begin.hpp
│ │ │ │ └── end.hpp
│ │ │ ├── cpp_future.hpp
│ │ │ ├── detected.hpp
│ │ │ ├── identity_tag.hpp
│ │ │ ├── is_sax.hpp
│ │ │ ├── std_fs.hpp
│ │ │ ├── type_traits.hpp
│ │ │ └── void_t.hpp
│ │ ├── output/
│ │ │ ├── binary_writer.hpp
│ │ │ ├── output_adapters.hpp
│ │ │ └── serializer.hpp
│ │ ├── string_concat.hpp
│ │ ├── string_escape.hpp
│ │ └── value_t.hpp
│ ├── json.hpp
│ ├── json_fwd.hpp
│ ├── ordered_map.hpp
│ └── thirdparty/
│ └── hedley/
│ ├── hedley.hpp
│ └── hedley_undef.hpp
├── README.md
└── deployment/
└── Azure/
└── README.md
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Report to introduce issues within the JonMon code
title: ''
labels: bug
assignees: jsecurity101
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- OS Build [e.g. 22621.2283]
**Additional context**
Add any other context about the problem here.
## Please include dump file if applicable
================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: enhancement
assignees: jsecurity101
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.
================================================
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/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
# 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
### VisualStudio Patch ###
# Additional files built by Visual Studio
*.vcxproj.*
# End of https://www.toptal.com/developers/gitignore/api/visualstudio
================================================
FILE: Extensions/Extension1/JonMon-Ext1/JonMon-Ext1.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|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</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>{bd72f0c3-dbd8-4ba2-8ff9-7f357f9232b1}</ProjectGuid>
<RootNamespace>JonMonExt1</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</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 Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="PropertySheets">
<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>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;JONMONEXT1_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;JONMONEXT1_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;JONMONEXT1_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;JONMONEXT1_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;JONMONEXT1_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;JONMONEXT1_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="dllmain.h" />
<ClInclude Include="framework.h" />
<ClInclude Include="pch.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp" />
<ClCompile Include="pch.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
================================================
FILE: Extensions/Extension1/JonMon-Ext1/dllmain.cpp
================================================
//
// Author: Jonathan Johnson (@jsecurity101)
// JonMon-Ext1.dll. This is the DLL that will be loaded by JonMon-Service.dll and will query threads to see if they are impersonating a token.
//
#include "pch.h"
#include <Windows.h>
#include <iostream>
#include <evntprov.h>
#include "tlhelp32.h"
#include "sddl.h"
#include "dllmain.h"
#include "../../../JonMonProvider/jonmon.h"
//
// JonMon TraceLogging Provider Information
//
TRACELOGGING_DECLARE_PROVIDER(g_hJonMon);
TRACELOGGING_DEFINE_PROVIDER(g_hJonMon, "JonMon",
(0xdd82bf6f, 0x5295, 0x4541, 0x96, 0x8d, 0x8c, 0xac, 0x58, 0xe5, 0x72, 0xe4));
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
DWORD IntegritySID(HANDLE hToken, PDWORD *IntegrityLevel) {
PSID pIntegritySid = NULL;
PTOKEN_MANDATORY_LABEL pIntegrityLabel = NULL;
DWORD retValue = 0;
//
// pull thread tokens integrity level
//
DWORD dwTokenInfoSize = 0;
GetTokenInformation(hToken, TokenIntegrityLevel, NULL, 0, &dwTokenInfoSize);
if (dwTokenInfoSize == 0)
{
printf("GetTokenInformation failed (%d)\n", GetLastError());
retValue = 1;
goto Exit;
}
//
// Allocate memory for the TOKEN_MANDATORY_LABEL structure
//
pIntegrityLabel = (PTOKEN_MANDATORY_LABEL)LocalAlloc(0, dwTokenInfoSize);
if (!pIntegrityLabel)
{
printf("Memory allocation failed\n");
retValue = 1;
goto Exit;
}
//
// Get the TOKEN_MANDATORY_LABEL structure
//
if (!GetTokenInformation(hToken, TokenIntegrityLevel, pIntegrityLabel, dwTokenInfoSize, &dwTokenInfoSize))
{
printf("GetTokenInformation failed (%d)\n", GetLastError());
retValue = 1;
goto Exit;
}
//
// Extract the integrity level SID from the TOKEN_MANDATORY_LABEL structure
//
pIntegritySid = pIntegrityLabel->Label.Sid;
// Convert the integrity level SID to a human-readable string
*IntegrityLevel = GetSidSubAuthority(pIntegritySid, (DWORD)(UCHAR)(*GetSidSubAuthorityCount(pIntegritySid) - 1));
Exit:
//
// Free resources
//
if (pIntegrityLabel != nullptr)
{
LocalFree(pIntegrityLabel);
}
return retValue;
}
DWORD TokenUserName(HANDLE hToken, LPWSTR* pStringSid)
{
DWORD retValue = 0;
PTOKEN_USER processTokenUser = NULL;
DWORD dwTokenInfoSize = 0;
LPWSTR lpName = NULL;
LPWSTR lpDomain = NULL;
DWORD dwNameSize = 0;
DWORD dwDomainSize = 0;
SID_NAME_USE eSidType;
PSID pUserSid = NULL;
DWORD dwSize = 0;
GetTokenInformation(hToken, TokenUser, NULL, 0, &dwTokenInfoSize);
if (dwTokenInfoSize == 0)
{
printf("GetTokenInformation failed (%d)\n", GetLastError());
retValue = 1;
goto Exit;
}
// Allocate memory for the TOKEN_USER structure
processTokenUser = (PTOKEN_USER)LocalAlloc(LPTR, dwTokenInfoSize);
if (processTokenUser == NULL)
{
printf("Memory allocation failed\n");
retValue = 1;
goto Exit;
}
// Get the TOKEN_USER structure
if (!GetTokenInformation(hToken, TokenUser, processTokenUser, dwTokenInfoSize, &dwTokenInfoSize))
{
printf("GetTokenInformation failed (%d)\n", GetLastError());
retValue = 1;
goto Exit;
}
// Extract the user SID from the TOKEN_USER structure
pUserSid = processTokenUser->User.Sid;
// First call to LookupAccountSid to get the buffer sizes
LookupAccountSidW(NULL, pUserSid, NULL, &dwNameSize, NULL, &dwDomainSize, &eSidType);
if (dwNameSize == 0 || dwDomainSize == 0)
{
printf("LookupAccountSidW failed (%d)\n", GetLastError());
retValue = 1;
goto Exit;
}
// Allocate memory for name and domain
lpName = (LPWSTR)LocalAlloc(0, dwNameSize * sizeof(WCHAR));
lpDomain = (LPWSTR)LocalAlloc(0, dwDomainSize * sizeof(WCHAR));
if (!lpName || !lpDomain)
{
printf("Memory allocation failed\n");
retValue = 1;
goto Exit;
}
// Second call to LookupAccountSid to get the account name
if (!LookupAccountSidW(NULL, pUserSid, lpName, &dwNameSize, lpDomain, &dwDomainSize, &eSidType))
{
printf("LookupAccountSidW failed (%d)\n", GetLastError());
retValue = 1;
goto Exit;
}
//
// put together the username and domain into a string
//
dwSize = wcslen(lpName) + wcslen(lpDomain) + 2;
//
// Allocate memory for the string
//
*pStringSid = (LPWSTR)LocalAlloc(0, dwSize * sizeof(WCHAR));
//
// put together the username and domain into a string
//
wsprintf(*pStringSid, L"%s\\%s", lpDomain, lpName);
Exit:
if (processTokenUser != NULL)
{
LocalFree(processTokenUser);
}
if (lpName != NULL)
{
LocalFree(lpName);
}
if (lpDomain != NULL)
{
LocalFree(lpDomain);
}
return retValue;
}
extern "C" void TokenImpersonationCheck()
{
TraceLoggingRegister(g_hJonMon);
//
// Loop every 60s to use message box
//
while (true)
{
//
// Get snapshot of all threads
//
HANDLE hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if (hThreadSnap == INVALID_HANDLE_VALUE)
{
printf("CreateToolhelp32Snapshot failed (%d)\n", GetLastError());
return;
}
//
// for each thread attempt to get access token and print handle
//
THREADENTRY32 te32;
te32.dwSize = sizeof(THREADENTRY32);
if (!Thread32First(hThreadSnap, &te32))
{
printf("Thread32First failed (%d)\n", GetLastError());
CloseHandle(hThreadSnap);
return;
}
do
{
//
// OpenThread with THREAD_QUERY_INFORMATION access right
//
HANDLE hThread = NULL;
HANDLE hToken = NULL;
HANDLE processToken = NULL;
HANDLE pHandle = NULL;
DWORD retValue = 0;
TOKEN_STATISTICS tokenStats;
DWORD dwReturnLength;
LPWSTR threadTokenUser = NULL;
LPWSTR processTokenUser = NULL;
PDWORD threadIntegrityLevel = 0;
PDWORD processIntegrityLevel = 0;
SYSTEMTIME st;
BOOL result;
REGHANDLE RegistrationHandle = NULL;
hThread = OpenThread(THREAD_QUERY_INFORMATION, FALSE, te32.th32ThreadID);
if (hThread == NULL)
{
goto Exit;
}
//
// Get thread access token
//
if (!OpenThreadToken(hThread, TOKEN_QUERY, FALSE, &hToken))
{
goto Exit;
}
retValue = IntegritySID(hToken, &threadIntegrityLevel);
if (retValue != 0)
{
goto Exit;
}
if (!GetTokenInformation(hToken, TokenStatistics, &tokenStats, sizeof(TOKEN_STATISTICS), &dwReturnLength))
{
printf("GetTokenInformation failed (%d)\n", GetLastError());
goto Exit;
}
retValue = TokenUserName(hToken, &threadTokenUser);
if (retValue != 0 || threadTokenUser == NULL)
{
goto Exit;
}
//
// Print token handle and impersonation level
//
if (tokenStats.ImpersonationLevel != SecurityImpersonation && tokenStats.ImpersonationLevel != SecurityDelegation)
{
goto Exit;
}
pHandle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, te32.th32OwnerProcessID);
if (pHandle == NULL) {
printf("OpenProcess failed (%d), ProcessID: %d\n", GetLastError(), te32.th32OwnerProcessID);
goto Exit;
}
result = OpenProcessToken(pHandle, TOKEN_QUERY, &processToken);
if (processToken == NULL) {
printf("OpenProcessToken failed (%d) ProcessId: %d\n", GetLastError(), te32.th32OwnerProcessID);
goto Exit;
}
retValue = IntegritySID(processToken, &processIntegrityLevel);
if (retValue != 0)
{
printf("IntegritySID failed (%d)\n", GetLastError());
goto Exit;
}
retValue = TokenUserName(processToken, &processTokenUser);
if (retValue != 0 || processTokenUser == NULL)
{
goto Exit;
}
if ((*processIntegrityLevel != 16384) && (wcscmp(processTokenUser, threadTokenUser) != 0))
{
GetSystemTime(&st);
TraceLoggingWrite(
g_hJonMon,
"16",
TraceLoggingInt32(16, "EventID"),
TraceLoggingUInt32(te32.th32ThreadID, "ThreadID"),
TraceLoggingUInt32(te32.th32OwnerProcessID, "ProcessID"),
TraceLoggingUInt32(*threadIntegrityLevel, "ThreadIntegrityLevel"),
TraceLoggingSystemTime(st, "EventTime"),
TraceLoggingWideString(threadTokenUser, "ImpersonatedUser")
);
}
Exit:
if (threadTokenUser != NULL)
{
LocalFree(threadTokenUser);
threadTokenUser = NULL;
}
if (processTokenUser != NULL)
{
LocalFree(processTokenUser);
processTokenUser = NULL;
}
if (hThread != NULL)
{
CloseHandle(hThread);
hThread = NULL;
}
if (hToken != NULL)
{
CloseHandle(hToken);
hToken = NULL;
}
if (pHandle != NULL)
{
CloseHandle(pHandle);
pHandle = NULL;
}
if (processToken != NULL)
{
CloseHandle(processToken);
processToken = NULL;
}
} while (Thread32Next(hThreadSnap, &te32));
CloseHandle(hThreadSnap);
Sleep(5000);
}
}
================================================
FILE: Extensions/Extension1/JonMon-Ext1/dllmain.h
================================================
#ifdef JONMON_EXPORTS
#define JONMON_EXPORTS __declspec(dllexport)
#else
#define JONMON_EXPORTS __declspec(dllimport)
#endif
#include "Windows.h"
#include "evntprov.h"
#include "stdio.h"
#include <TraceLoggingProvider.h>
//
// Export function that will query process tokens
//
extern "C" JONMON_EXPORTS void TokenImpersonationCheck();
================================================
FILE: Extensions/Extension1/JonMon-Ext1/framework.h
================================================
#pragma once
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files
#include <windows.h>
================================================
FILE: Extensions/Extension1/JonMon-Ext1/pch.cpp
================================================
// pch.cpp: source file corresponding to the pre-compiled header
#include "pch.h"
// When you are using pre-compiled headers, this source file is necessary for compilation to succeed.
================================================
FILE: Extensions/Extension1/JonMon-Ext1/pch.h
================================================
// pch.h: This is a precompiled header file.
// Files listed below are compiled only once, improving build performance for future builds.
// This also affects IntelliSense performance, including code completion and many code browsing features.
// However, files listed here are ALL re-compiled if any one of them is updated between builds.
// Do not add files here that you will be updating frequently as this negates the performance advantage.
#ifndef PCH_H
#define PCH_H
// add headers that you want to pre-compile here
#include "framework.h"
#endif //PCH_H
================================================
FILE: JonMon/JonMon.sln
================================================
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.4.33205.214
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "JonMon", "JonMon.vcxproj", "{27DCE7FD-EC60-49F7-9245-A39DE05E7056}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "JonMon-Service", "..\JonMon-Service\JonMon-Service.vcxproj", "{BF810292-3774-41A4-B51E-CEF92E26894A}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "JonMon-Ext1", "..\Extensions\Extension1\JonMon-Ext1\JonMon-Ext1.vcxproj", "{BD72F0C3-DBD8-4BA2-8FF9-7F357F9232B1}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM64 = Debug|ARM64
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|ARM64 = Release|ARM64
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{27DCE7FD-EC60-49F7-9245-A39DE05E7056}.Debug|ARM64.ActiveCfg = Debug|ARM64
{27DCE7FD-EC60-49F7-9245-A39DE05E7056}.Debug|ARM64.Build.0 = Debug|ARM64
{27DCE7FD-EC60-49F7-9245-A39DE05E7056}.Debug|ARM64.Deploy.0 = Debug|ARM64
{27DCE7FD-EC60-49F7-9245-A39DE05E7056}.Debug|x64.ActiveCfg = Debug|x64
{27DCE7FD-EC60-49F7-9245-A39DE05E7056}.Debug|x64.Build.0 = Debug|x64
{27DCE7FD-EC60-49F7-9245-A39DE05E7056}.Debug|x64.Deploy.0 = Debug|x64
{27DCE7FD-EC60-49F7-9245-A39DE05E7056}.Debug|x86.ActiveCfg = Debug|x64
{27DCE7FD-EC60-49F7-9245-A39DE05E7056}.Debug|x86.Build.0 = Debug|x64
{27DCE7FD-EC60-49F7-9245-A39DE05E7056}.Debug|x86.Deploy.0 = Debug|x64
{27DCE7FD-EC60-49F7-9245-A39DE05E7056}.Release|ARM64.ActiveCfg = Release|ARM64
{27DCE7FD-EC60-49F7-9245-A39DE05E7056}.Release|ARM64.Build.0 = Release|ARM64
{27DCE7FD-EC60-49F7-9245-A39DE05E7056}.Release|x64.ActiveCfg = Release|x64
{27DCE7FD-EC60-49F7-9245-A39DE05E7056}.Release|x64.Build.0 = Release|x64
{27DCE7FD-EC60-49F7-9245-A39DE05E7056}.Release|x64.Deploy.0 = Release|x64
{27DCE7FD-EC60-49F7-9245-A39DE05E7056}.Release|x86.ActiveCfg = Release|x64
{27DCE7FD-EC60-49F7-9245-A39DE05E7056}.Release|x86.Build.0 = Release|x64
{27DCE7FD-EC60-49F7-9245-A39DE05E7056}.Release|x86.Deploy.0 = Release|x64
{BF810292-3774-41A4-B51E-CEF92E26894A}.Debug|ARM64.ActiveCfg = Debug|x64
{BF810292-3774-41A4-B51E-CEF92E26894A}.Debug|ARM64.Build.0 = Debug|x64
{BF810292-3774-41A4-B51E-CEF92E26894A}.Debug|x64.ActiveCfg = Debug|x64
{BF810292-3774-41A4-B51E-CEF92E26894A}.Debug|x64.Build.0 = Debug|x64
{BF810292-3774-41A4-B51E-CEF92E26894A}.Debug|x86.ActiveCfg = Debug|Win32
{BF810292-3774-41A4-B51E-CEF92E26894A}.Debug|x86.Build.0 = Debug|Win32
{BF810292-3774-41A4-B51E-CEF92E26894A}.Release|ARM64.ActiveCfg = Release|x64
{BF810292-3774-41A4-B51E-CEF92E26894A}.Release|ARM64.Build.0 = Release|x64
{BF810292-3774-41A4-B51E-CEF92E26894A}.Release|x64.ActiveCfg = Release|x64
{BF810292-3774-41A4-B51E-CEF92E26894A}.Release|x64.Build.0 = Release|x64
{BF810292-3774-41A4-B51E-CEF92E26894A}.Release|x86.ActiveCfg = Release|Win32
{BF810292-3774-41A4-B51E-CEF92E26894A}.Release|x86.Build.0 = Release|Win32
{BD72F0C3-DBD8-4BA2-8FF9-7F357F9232B1}.Debug|ARM64.ActiveCfg = Debug|x64
{BD72F0C3-DBD8-4BA2-8FF9-7F357F9232B1}.Debug|ARM64.Build.0 = Debug|x64
{BD72F0C3-DBD8-4BA2-8FF9-7F357F9232B1}.Debug|x64.ActiveCfg = Debug|x64
{BD72F0C3-DBD8-4BA2-8FF9-7F357F9232B1}.Debug|x64.Build.0 = Debug|x64
{BD72F0C3-DBD8-4BA2-8FF9-7F357F9232B1}.Debug|x86.ActiveCfg = Debug|Win32
{BD72F0C3-DBD8-4BA2-8FF9-7F357F9232B1}.Debug|x86.Build.0 = Debug|Win32
{BD72F0C3-DBD8-4BA2-8FF9-7F357F9232B1}.Release|ARM64.ActiveCfg = Release|x64
{BD72F0C3-DBD8-4BA2-8FF9-7F357F9232B1}.Release|ARM64.Build.0 = Release|x64
{BD72F0C3-DBD8-4BA2-8FF9-7F357F9232B1}.Release|x64.ActiveCfg = Release|x64
{BD72F0C3-DBD8-4BA2-8FF9-7F357F9232B1}.Release|x64.Build.0 = Release|x64
{BD72F0C3-DBD8-4BA2-8FF9-7F357F9232B1}.Release|x86.ActiveCfg = Release|Win32
{BD72F0C3-DBD8-4BA2-8FF9-7F357F9232B1}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {EA991FDB-4D7B-4F75-B564-463A826AC12F}
EndGlobalSection
EndGlobal
================================================
FILE: JonMon/JonMon.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|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</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>{27DCE7FD-EC60-49F7-9245-A39DE05E7056}</ProjectGuid>
<TemplateGuid>{dd38f7fc-d7bd-488b-9242-7d8754cde80d}</TemplateGuid>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion>
<Configuration>Debug</Configuration>
<Platform Condition="'$(Platform)' == ''">x64</Platform>
<RootNamespace>JonMon</RootNamespace>
<WindowsTargetPlatformVersion>10.0.26100.0</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>WDM</DriverType>
<Driver_SpectreMitigation>false</Driver_SpectreMitigation>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
<DriverType>WDM</DriverType>
<Driver_SpectreMitigation>false</Driver_SpectreMitigation>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
<DriverType>WDM</DriverType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
<TargetVersion>Windows10</TargetVersion>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>Driver</ConfigurationType>
<DriverType>WDM</DriverType>
</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>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
<EnableInf2cat>false</EnableInf2cat>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<DriverSign>
<FileDigestAlgorithm>sha256</FileDigestAlgorithm>
</DriverSign>
<Link>
<AdditionalDependencies>Ksecdd.lib;FltMgr.lib;Setupapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalOptions>/INTEGRITYCHECK %(AdditionalOptions)</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<DriverSign>
<FileDigestAlgorithm>sha256</FileDigestAlgorithm>
</DriverSign>
<Link>
<AdditionalDependencies>Ksecdd.lib;FltMgr.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalOptions>/INTEGRITYCHECK %(AdditionalOptions)</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<Link>
<AdditionalDependencies>FltMgr.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<Link>
<AdditionalDependencies>FltMgr.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalOptions>/INTEGRITYCHECK %(AdditionalOptions)</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<FilesToPackage Include="$(TargetPath)" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="callbacks.cpp" />
<ClCompile Include="driver.cpp" />
<ClCompile Include="minifilter.cpp" />
<ClCompile Include="process.cpp" />
<ClCompile Include="registry.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="callbacks.h" />
<ClInclude Include="driver.h" />
<ClInclude Include="minifilter.h" />
<ClInclude Include="process.h" />
<ClInclude Include="registry.h" />
<ClInclude Include="shared.h" />
<ClInclude Include="jtime.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
================================================
FILE: JonMon/callbacks.cpp
================================================
#include "callbacks.h"
#include "process.h"
#include "registry.h"
#include "minifilter.h"
PAGED_FILE();
#define MAX_PATH_LENGTH 100
PVOID ProcessRegistrationHandle = NULL;
PVOID ThreadRegistrationHandle = NULL;
LARGE_INTEGER Cookie;
ULONG g_ServicePID = 0;
PDRIVER_OBJECT g_DriverObject = NULL;
EventSchema g_EventSchema = {
FALSE,
FALSE,
FALSE,
FALSE,
FALSE,
FALSE,
FALSE,
FALSE,
FALSE,
0,
0
};
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS RegisterCallbacks(
) {
PAGED_CODE();
NTSTATUS status = STATUS_SUCCESS;
UNICODE_STRING Altitude;
RtlInitUnicodeString(&Altitude, L"385202");
//
// Checks global g_EventSchema to see if ConfigSet is set to false, if it is will sleep and recheck
//
while (g_EventSchema.ConfigSet == FALSE) {
LARGE_INTEGER interval;
interval.QuadPart = -10000000; // 1 second
KeDelayExecutionThread(KernelMode, FALSE, &interval);
}
if(g_EventSchema.ProcessCreation == TRUE)
{
status = PsSetCreateProcessNotifyRoutineEx(CreateProcessNotifyRoutineEx, FALSE);
if (!NT_SUCCESS(status))
{
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "Failed to load PsSetCreateProcessNotifyRoutineEx : 0x%X\n", status);
return status;
}
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "PsSetCreateProcessNotifyRoutineEx Loaded\n");
}
if(g_EventSchema.ProcessTermination == TRUE)
{
status = PsSetCreateProcessNotifyRoutine(TerminateProcessNotifyRoutine, FALSE);
if (!NT_SUCCESS(status))
{
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "Failed to load PsSetCreateProcessNotifyRoutine : 0x%X\n", status);
return status;
}
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "PsSetCreateProcessNotifyRoutine Loaded\n");
}
if(g_EventSchema.RemoteThreadCreation == TRUE)
{
status = PsSetCreateThreadNotifyRoutine(PsCreateThreadNotifyRoutine);
if (!NT_SUCCESS(status)) {
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "Failed to load PsSetCreateThreadNotifyRoutine : 0x%X\n", status);
return status;
}
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "PsSetCreateThreadNotifyRoutine Loaded\n");
}
if(g_EventSchema.ImageLoad == TRUE)
{
status = PsSetLoadImageNotifyRoutine(LoadImageRoutine);
if (!NT_SUCCESS(status))
{
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "Failed to load PsSetLoadImageNotifyRoutine : 0x%X\n", status);
return status;
}
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "PsSetLoadImageNotifyRoutine Loaded\n");
}
if(g_EventSchema.ProcessHandleCreation == TRUE || g_EventSchema.ProcessHandleDuplication == TRUE)
{
//
//Setting up callback for PsProcessType
//
OB_CALLBACK_REGISTRATION CallbackRegistration;
OB_OPERATION_REGISTRATION OperationRegistration;
OperationRegistration.ObjectType = PsProcessType;
if(g_EventSchema.ProcessHandleDuplication == TRUE && g_EventSchema.ProcessHandleCreation == TRUE)
{
OperationRegistration.Operations = OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE;
}
else if(g_EventSchema.ProcessHandleCreation == TRUE && g_EventSchema.ProcessHandleDuplication == FALSE)
{
OperationRegistration.Operations = OB_OPERATION_HANDLE_CREATE;
}
else if(g_EventSchema.ProcessHandleDuplication == TRUE && g_EventSchema.ProcessHandleCreation == FALSE)
{
OperationRegistration.Operations = OB_OPERATION_HANDLE_DUPLICATE;
}
OperationRegistration.PreOperation = NULL;
OperationRegistration.PostOperation = PostProcessHandleCallback;
//
// Setting members
//
CallbackRegistration.Version = OB_FLT_REGISTRATION_VERSION;
CallbackRegistration.OperationRegistrationCount = 1;
CallbackRegistration.Altitude = Altitude;
CallbackRegistration.RegistrationContext = NULL;
CallbackRegistration.OperationRegistration = &OperationRegistration;
status = ObRegisterCallbacks(&CallbackRegistration, &ProcessRegistrationHandle);
if (!NT_SUCCESS(status))
{
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "Failed to load ObRegisterCallbacks : 0x%X\n", status);
return status;
}
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "ObRegisterCallbacks Loaded\n");
}
if(g_EventSchema.File == TRUE)
{
status = FltCallbackStart(g_DriverObject);
if (!NT_SUCCESS(status))
{
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "Failed to load FltCallbackStart : 0x%X\n", status);
return status;
}
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "FltCallbackStart Loaded\n");
}
if (g_EventSchema.Registry == TRUE)
{
status = CmRegisterCallbackEx(RegistryCallback, &Altitude, g_DriverObject, NULL, &Cookie, NULL);
if (!NT_SUCCESS(status))
{
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "Failed to load CmRegisterCallbackEx : 0x%X\n", status);
return status;
}
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "CmRegisterCallbackEx Loaded\n");
}
PsTerminateSystemThread(STATUS_SUCCESS);
return status;
}
_IRQL_requires_max_(PASSIVE_LEVEL)
VOID
LoadImageRoutine(
_In_ PUNICODE_STRING FullImageName,
_In_ HANDLE ProcessId,
_In_ PIMAGE_INFO ImageInfo
) {
FILETIME fileTime;
KeQuerySystemTime(&fileTime);
PAGED_CODE();
ULONGLONG ProcessStartKey = PsGetProcessStartKey(PsGetCurrentProcess());
TraceLoggingWrite(
g_hJonMon,
"ImageLoad",
TraceLoggingInt32(4, "EventID"),
TraceLoggingValue(ProcessId, "ProcessId"),
TraceLoggingValue(ProcessStartKey, "ProcessStartKey"),
TraceLoggingValue(PsGetCurrentThreadId(), "ThreadId"),
TraceLoggingValue(ImageInfo->SystemModeImage, "SystemModeImage"),
TraceLoggingWideString(FullImageName->Buffer, "ImagePath"),
TraceLoggingFileTime(fileTime, "FileTime")
);
}
BOOLEAN ContainsSubstring(PCWSTR keyPath, PCWSTR substring) {
size_t keyPathLen = wcslen(keyPath);
size_t substringLen = wcslen(substring);
if (keyPathLen < substringLen) {
return FALSE;
}
for (PCWSTR p = keyPath; *p != L'\0'; p++) {
if (wcsncmp(p, substring, substringLen) == 0) {
return TRUE;
}
}
return FALSE;
}
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS RegistryCallback(
_In_ PVOID CallbackContext,
_In_ PVOID RegNotifyClass,
_In_ PVOID RegObject
) {
//
//IRQL less == Passive, if not exit
//
if (KeGetCurrentIrql() > PASSIVE_LEVEL) {
return STATUS_UNSUCCESSFUL;
}
PCWSTR keyPath = NULL;
FILETIME fileTime;
REG_NOTIFY_CLASS notifyClass = (REG_NOTIFY_CLASS)(ULONG_PTR)RegNotifyClass;
NTSTATUS status = STATUS_SUCCESS;
PAGED_CODE();
UNREFERENCED_PARAMETER(CallbackContext);
if (RegObject == NULL)
{
DbgPrint("Callback RegObject is NULL. \n");
status = STATUS_UNSUCCESSFUL;
goto Exit;
}
KeQuerySystemTime(&fileTime);
ULONGLONG sourceProcessId = HandleToULong(PsGetCurrentProcessId());
ULONGLONG sourceThreadId = HandleToULong(PsGetCurrentThreadId());
switch (notifyClass) {
case RegNtPostCreateKeyEx:
{
PREG_POST_OPERATION_INFORMATION object = (PREG_POST_OPERATION_INFORMATION)RegObject;
if (object->Status != STATUS_SUCCESS) {
DbgPrint("[RegNtPostCreateKeyEx] - Status is not success. Status 0x%x\n", object->Status);
goto Exit;
}
PREG_CREATE_KEY_INFORMATION_V1 info = (PREG_CREATE_KEY_INFORMATION_V1)object->PreInformation;
if (*info->Disposition != REG_CREATED_NEW_KEY ) {
DbgPrint("[RegNtPostCreateKeyEx] - Disposition is not REG_CREATED_NEW_KEY. Disposition 0x%x\n", *info->Disposition);
goto Exit;
}
status = GetRegistryKeyPath(object->Object, REGISTRY_TAG, &keyPath);
if (status != STATUS_SUCCESS || keyPath == NULL) {
DbgPrint("[RegNtPostCreateKeyEx] - GetRegistryKeyPath failed. Status 0x%x\n", status);
goto Exit;
}
TraceLoggingWrite(
g_hJonMon,
"RegCreateKey",
TraceLoggingInt32(9, "EventID"),
TraceLoggingValue(sourceThreadId, "SourceThreadId"),
TraceLoggingValue(sourceProcessId, "SourceProcessId"),
TraceLoggingValue(PsGetProcessStartKey(PsGetCurrentProcess()), "SourceProcessStartKey"),
TraceLoggingWideString(keyPath, "KeyPath"),
TraceLoggingValue(info->DesiredAccess, "DesiredAccess"),
TraceLoggingFileTime(fileTime, "FileTime")
);
break;
}
case RegNtPostSaveKey:
{
PREG_POST_OPERATION_INFORMATION object = (PREG_POST_OPERATION_INFORMATION)RegObject;
if (object->Status == STATUS_SUCCESS) {
status = GetRegistryKeyPath(object->Object, REGISTRY_TAG, &keyPath);
if (keyPath == NULL) {
goto Exit;
}
TraceLoggingWrite(
g_hJonMon,
"RegSaveKey",
TraceLoggingInt32(6, "EventID"),
TraceLoggingValue(sourceThreadId, "SourceThreadId"),
TraceLoggingValue(sourceProcessId, "SourceProcessId"),
TraceLoggingValue(PsGetProcessStartKey(PsGetCurrentProcess()), "SourceProcessStartKey"),
TraceLoggingWideString(keyPath, "KeyPath"),
TraceLoggingFileTime(fileTime, "FileTime")
);
}
break;
}
case RegNtPreDeleteKey:
{
PREG_DELETE_KEY_INFORMATION object = (PREG_DELETE_KEY_INFORMATION)RegObject;
if (object->Object == NULL)
{
goto Exit;
}
status = GetRegistryKeyPath(object->Object, REGISTRY_TAG, &keyPath);
if (keyPath == NULL) {
goto Exit;
}
TraceLoggingWrite(
g_hJonMon,
"RegDeleteKey",
TraceLoggingInt32(7, "EventID"),
TraceLoggingValue(sourceThreadId, "SourceThreadId"),
TraceLoggingValue(sourceProcessId, "SourceProcessId"),
TraceLoggingValue(PsGetProcessStartKey(PsGetCurrentProcess()), "SourceProcessStartKey"),
TraceLoggingWideString(keyPath, "KeyPath"),
TraceLoggingFileTime(fileTime, "FileTime")
);
break;
}
case RegNtPostSetValueKey:
{
UNICODE_STRING valueData;
PREG_POST_OPERATION_INFORMATION postObject = (PREG_POST_OPERATION_INFORMATION)RegObject;
if (postObject->Status != STATUS_SUCCESS) {
goto Exit;
}
PREG_SET_VALUE_KEY_INFORMATION info = (PREG_SET_VALUE_KEY_INFORMATION)postObject->PreInformation;
if (info->ValueName == NULL || info->ValueName->Length == 0) {
goto Exit;
}
status = GetRegistryKeyPath(info->Object, REGISTRY_TAG, &keyPath);
if (status != STATUS_SUCCESS || keyPath == NULL) {
DbgPrint("[RegNtPostSetValueKey] - GetRegistryKeyPath failed. Status 0x%x", status);
goto Exit;
}
if (info->DataSize <= 0) {
goto Exit;
}
if(info->Data == NULL)
{
goto Exit;
}
//
// Reducing noise
//
if (ContainsSubstring(keyPath, L"DeliveryOptimization\\Usage")) {
goto Exit;
}
if (ContainsSubstring(keyPath, L"\\DeliveryOptimization\\Config")) {
goto Exit;
}
if (ContainsSubstring(keyPath, L"\\Microsoft\\Input\\TypingInsights")) {
goto Exit;
}
if (ContainsSubstring(keyPath, L"\\REGISTRY\\MACHINE\\SYSTEM\\ControlSet001\\Services\\W32Time")) {
goto Exit;
}
if (ContainsSubstring(keyPath, L"\\REGISTRY\\A\\")) {
goto Exit;
}
//
// Fixing valueName buffer
//
UNICODE_STRING valueName;
valueName.Length = info->ValueName->Length;
valueName.MaximumLength = info->ValueName->Length + sizeof(UNICODE_NULL);
valueName.Buffer = (PWSTR)ExAllocatePool2(POOL_FLAG_PAGED, valueName.MaximumLength, SYSTEM_THREAD_TAG); // Use valueName.Length here.
if (valueName.Buffer == NULL || valueName.Length == 0) {
goto Exit;
}
RtlZeroMemory(valueName.Buffer, valueName.MaximumLength);
RtlCopyMemory(valueName.Buffer, info->ValueName->Buffer, info->ValueName->Length);
//
// adding null terminator
//
valueName.Buffer[valueName.Length / sizeof(WCHAR)] = UNICODE_NULL;
//
// Creating a UNICODE_STRING to hold the data information
//
valueData.Length = (USHORT)info->DataSize;
valueData.MaximumLength = valueData.Length + sizeof(WCHAR); // Account for null terminator
valueData.Buffer = (PWSTR)ExAllocatePool2(POOL_FLAG_PAGED, valueData.MaximumLength, SYSTEM_THREAD_TAG);
if (valueData.Buffer == NULL || valueData.MaximumLength == 0) {
goto Exit;
}
RtlZeroMemory(valueData.Buffer, valueData.MaximumLength);
//
// To do: Update REG_MULTI_SZ and REG_BINARY
//
switch (info->Type)
{
case REG_SZ:
{
RtlCopyMemory(valueData.Buffer, info->Data, valueData.Length);
valueData.Buffer[valueData.Length / sizeof(WCHAR)] = UNICODE_NULL; // Set null terminator
break;
}
case REG_EXPAND_SZ:
{
RtlCopyMemory(valueData.Buffer, info->Data, valueData.Length);
valueData.Buffer[valueData.Length / sizeof(WCHAR)] = UNICODE_NULL; // Set null terminator
break;
}
case REG_MULTI_SZ:
{
RtlCopyMemory(valueData.Buffer, info->Data, valueData.Length);
// Ensure the data is properly double-null terminated
if (valueData.Length >= sizeof(WCHAR) && valueData.Buffer[(valueData.Length / sizeof(WCHAR)) - 1] != UNICODE_NULL)
{
// Add an additional null terminator if the last character isn't already a null terminator
valueData.Buffer[valueData.Length / sizeof(WCHAR)] = UNICODE_NULL; // First null terminator
valueData.Buffer[(valueData.Length / sizeof(WCHAR)) + 1] = UNICODE_NULL; // Second null terminator
}
else
{
// If the data already ends with a null, just add another
valueData.Buffer[valueData.Length / sizeof(WCHAR)] = UNICODE_NULL;
}
break;
}
case REG_DWORD:
{
RtlStringCchPrintfW(valueData.Buffer, valueData.MaximumLength / sizeof(WCHAR), L"%d", *(DWORD*)info->Data);
break;
}
case REG_QWORD:
{
RtlStringCchPrintfW(valueData.Buffer, valueData.MaximumLength / sizeof(WCHAR), L"%lld", *(ULONGLONG*)info->Data);
break;
}
case REG_BINARY:
{
RtlStringCchPrintfW(valueData.Buffer, valueData.MaximumLength / sizeof(WCHAR), L"%d", *(DWORD*)info->Data);
break;
}
default:
{
break;
}
}
//
// check each field below to see if it is null lol
//
if (keyPath == NULL)
{
DbgPrint("keyPath is NULL\n");
}
if (valueName.Buffer == NULL)
{
DbgPrint("valueName.Buffer is NULL\n");
}
if (valueData.Buffer == NULL)
{
DbgPrint("valueData.Buffer is NULL\n");
}
if(info->Type == NULL)
{
DbgPrint("info->Type is NULL\n");
}
if(info->DataSize == NULL)
{
DbgPrint("info->DataSize is NULL\n");
}
TraceLoggingWrite(
g_hJonMon,
"RegSetValueKey",
TraceLoggingInt32(8, "EventID"),
TraceLoggingValue(sourceThreadId, "SourceThreadId"),
TraceLoggingValue(sourceProcessId, "SourceProcessId"),
TraceLoggingValue(PsGetProcessStartKey(PsGetCurrentProcess()), "SourceProcessStartKey"),
TraceLoggingWideString(keyPath, "KeyPath"),
TraceLoggingWideString(valueName.Buffer, "ValueName"),
TraceLoggingValue(valueData.Buffer, "Data"),
TraceLoggingValue(info->Type, "Type"),
TraceLoggingValue(info->DataSize, "DataSize"),
TraceLoggingFileTime(fileTime, "FileTime")
);
if(valueName.Buffer != NULL)
{
ExFreePoolWithTag(valueName.Buffer, SYSTEM_THREAD_TAG);
}
if(valueData.Buffer != NULL)
{
ExFreePoolWithTag(valueData.Buffer, SYSTEM_THREAD_TAG);
}
break;
}
default:
{
break;
}
}
Exit:
if (keyPath != NULL) {
ExFreePoolWithTag((PVOID)keyPath, REGISTRY_TAG);
}
return status;
}
_IRQL_requires_max_(PASSIVE_LEVEL)
void PsCreateThreadNotifyRoutine(
_In_ HANDLE ProcessId,
_In_ HANDLE ThreadId,
_In_ BOOLEAN Create
) {
NTSTATUS status;
PEPROCESS sourceProcess;
PEPROCESS targetProcess;
FILETIME filetime;
KeQuerySystemTime(&filetime);
PAGED_CODE();
//
// Check if the thread is being created or deleted
//
if (Create != TRUE) {
goto Exit;
}
HANDLE CurrentPID = PsGetCurrentProcessId();
if (CurrentPID == ProcessId) {
goto Exit;
}
if (CurrentPID == (HANDLE)0x4) {
goto Exit;
}
if (ProcessId == (HANDLE)0x4) {
goto Exit;
}
HANDLE sourceThreadId = PsGetCurrentThreadId();
status = PsLookupProcessByProcessId(ProcessId, &targetProcess);
if (status != STATUS_SUCCESS) {
DbgPrint("Failed to get target process, status: %d", status);
goto Exit;
}
status = PsLookupProcessByProcessId(CurrentPID, &sourceProcess);
if (status != STATUS_SUCCESS) {
DbgPrint("Failed to get source process, status: %d", status);
goto Exit;
}
ULONGLONG sourceProcStartKey = PsGetProcessStartKey(sourceProcess);
ULONGLONG targetProcStartKey = PsGetProcessStartKey(targetProcess);
TraceLoggingWrite(
g_hJonMon,
"RemoteThreadCreation",
TraceLoggingInt32(3, "EventID"),
TraceLoggingValue(sourceThreadId, "SourceThreadId"),
TraceLoggingValue(CurrentPID, "SourceProcessId"),
TraceLoggingValue(sourceProcStartKey, "SourceProcessStartKey"),
TraceLoggingValue(ThreadId, "NewThreadId"),
TraceLoggingValue(ProcessId, "TargetProcessId"),
TraceLoggingValue(targetProcStartKey, "TargetProcessStartKey"),
TraceLoggingFileTime(filetime, "FileTime")
);
Exit:
return;
}
_IRQL_requires_max_(PASSIVE_LEVEL)
void CreateProcessNotifyRoutineEx(
_In_ PEPROCESS Process,
_In_ HANDLE ProcessId,
_In_ PPS_CREATE_NOTIFY_INFO CreateInfo
)
{
FILETIME fileTime;
UNICODE_STRING commandLine{ 0 };
PAGED_CODE();
if (CreateInfo == NULL)
{
goto Exit;
}
KeQuerySystemTime(&fileTime);
ULONGLONG ProcessStartKey = PsGetProcessStartKey(Process);
ULONGLONG parentProcessStartKey = PsGetProcessStartKey(PsGetCurrentProcess());
//
//Checking to see if CommandLine is NULL and if it isn't, creating a buffer
//
if (CreateInfo->CommandLine != NULL) {
//
//create buffer
//
commandLine.Buffer = (PWSTR)ExAllocatePool2(POOL_FLAG_PAGED, CreateInfo->CommandLine->Length + sizeof(UNICODE_NULL), SYSTEM_THREAD_TAG);
if (commandLine.Buffer == NULL)
{
goto Exit;
}
//
//Zero out the buffer
//
RtlZeroMemory(commandLine.Buffer, CreateInfo->CommandLine->Length + sizeof(UNICODE_NULL));
//
//Copy the CommandLine into the buffer
//
RtlCopyMemory(commandLine.Buffer, CreateInfo->CommandLine->Buffer, CreateInfo->CommandLine->Length);
//
//Null terminate the buffer
//
commandLine.Buffer[CreateInfo->CommandLine->Length / sizeof(UNICODE_NULL)] = UNICODE_NULL;
}
else {
commandLine.Buffer = L"NULL";
commandLine.Length = sizeof(L"NULL");
commandLine.MaximumLength = sizeof(L"NULL") + sizeof(UNICODE_NULL);
}
//
// TraceLogging Event
//
TraceLoggingWrite(
g_hJonMon,
"ProcessCreation",
TraceLoggingInt32(1, "EventID"),
TraceLoggingValue(ProcessId, "ProcessId"),
TraceLoggingValue(ProcessStartKey, "ProcessStartKey"),
TraceLoggingValue(CreateInfo->ParentProcessId, "ParentProcessId"),
TraceLoggingValue(parentProcessStartKey, "ParentProcessStartKey"),
TraceLoggingValue(CreateInfo->CreatingThreadId.UniqueProcess, "CreatorProcessId"),
TraceLoggingValue(CreateInfo->CreatingThreadId.UniqueThread, "CreatorThreadId"),
TraceLoggingWideString(commandLine.Buffer, "CommandLine"),
TraceLoggingFileTime(fileTime, "FileTime")
);
Exit:
if (commandLine.Buffer != NULL) {
ExFreePoolWithTag(commandLine.Buffer, SYSTEM_THREAD_TAG);
}
}
_IRQL_requires_max_(PASSIVE_LEVEL)
void PostProcessHandleCallback(
_In_ PVOID RegistrationContext,
_In_ POB_POST_OPERATION_INFORMATION OperationInformation
) {
UNREFERENCED_PARAMETER(RegistrationContext);
FILETIME filetime;
DWORD OperationType;
ACCESS_MASK DesiredAccess;
PAGED_CODE();
KeQuerySystemTime(&filetime);
PEPROCESS targetProcess = (PEPROCESS)OperationInformation->Object;
HANDLE TargetProcessId = PsGetProcessId(targetProcess);
HANDLE SourceProcessId = PsGetCurrentProcessId();
DesiredAccess = OperationInformation->Parameters->CreateHandleInformation.GrantedAccess;
if ((HANDLE)g_ServicePID == SourceProcessId) {
goto Exit;
}
if (DesiredAccess == 0x0) {
goto Exit;
}
if (SourceProcessId == TargetProcessId) {
goto Exit;
}
if (SourceProcessId == (HANDLE)0x4 || TargetProcessId == (HANDLE)0x4) {
goto Exit;
}
switch (OperationInformation->Operation)
{
case OB_OPERATION_HANDLE_CREATE:
{
OperationType = 1;
break;
}
case OB_OPERATION_HANDLE_DUPLICATE:
{
if ((DesiredAccess & 0x40) != 0x40) {
goto Exit;
}
DesiredAccess = OperationInformation->Parameters->DuplicateHandleInformation.GrantedAccess;
OperationType = 2;
break;
}
}
TraceLoggingWrite(
g_hJonMon,
"ProcessHandle",
TraceLoggingInt32(5, "EventID"),
TraceLoggingValue(PsGetCurrentThreadId(), "SourceThreadId"),
TraceLoggingValue(SourceProcessId, "SourceProcessId"),
TraceLoggingValue(PsGetProcessStartKey(PsGetCurrentProcess()), "SourceProcessStartKey"),
TraceLoggingValue(TargetProcessId, "TargetProcessId"),
TraceLoggingValue(PsGetProcessStartKey(targetProcess), "TargetProcessStartKey"),
TraceLoggingValue(OperationType, "OperationType"),
TraceLoggingValue(DesiredAccess, "DesiredAccess"),
TraceLoggingFileTime(filetime, "FileTime")
);
Exit:
return;
}
_IRQL_requires_max_(PASSIVE_LEVEL)
void TerminateProcessNotifyRoutine(
_In_ HANDLE ParentProcessId,
_In_ HANDLE ProcessId,
_In_ BOOLEAN Create
)
{
FILETIME fileTime;
PAGED_CODE();
if (!Create)
{
KeQuerySystemTime(&fileTime);
ULONGLONG sourceProcessStartKey = PsGetProcessStartKey(PsGetCurrentProcess());
ULONGLONG targetProcessStartKey = PsGetProcessStartKey(PsGetCurrentProcess());
TraceLoggingWrite(
g_hJonMon,
"ProcessTermination",
TraceLoggingInt32(2, "EventID"),
TraceLoggingValue(ProcessId, "ProcessId"),
TraceLoggingValue(targetProcessStartKey, "ProcessStartKey"),
TraceLoggingValue(ParentProcessId, "ParentProcessId"),
TraceLoggingValue(sourceProcessStartKey, "ParentProcessStartKey"),
TraceLoggingFileTime(fileTime, "FileTime")
);
goto Exit;
}
Exit:
return;
}
================================================
FILE: JonMon/callbacks.h
================================================
#ifndef _CALLBACK_
#define _CALLBACK_
#include "shared.h"
extern ULONG g_ServicePID;
extern PVOID ProcessRegistrationHandle;
extern PVOID ThreadRegistrationHandle;
extern PDRIVER_OBJECT g_DriverObject;
typedef struct _EventSchema {
BOOLEAN ConfigSet;
BOOLEAN ProcessCreation;
BOOLEAN ProcessTermination;
BOOLEAN ProcessHandleCreation;
BOOLEAN ProcessHandleDuplication;
BOOLEAN RemoteThreadCreation;
BOOLEAN ImageLoad;
BOOLEAN File;
BOOLEAN Registry;
INT ConfigVersion;
INT JonMonVersion;
} EventSchema, * PEventSchema;
typedef struct _HANDLE_CREATION_CALLBACK_INFO {
ULONGLONG SourceProcessStartKey;
HANDLE SourceProcessId;
HANDLE SourceThreadId;
HANDLE TargetProcessId;
PETHREAD SourceThread;
ULONGLONG TargetProcessStartKey;
ACCESS_MASK DesiredAccess;
FILETIME FileTime;
DWORD OperationType;
} HANDLE_CREATION_CALLBACK_INFO, * PHANDLE_CREATION_CALLBACK_INFO;
typedef struct _LOAD_IMAGE_CALLBACK_INFO {
HANDLE SourceProcessId;
HANDLE SourceThread;
PETHREAD SourceEThread;
FILETIME FileTime;
UNICODE_STRING ModuleName;
ULONG SystemModeImage;
} LOAD_IMAGE_CALLBACK_INFO, * PLOAD_IMAGE_CALLBACK_INFO;
typedef struct _PROCESS_CREATE_CALLBACK_INFO {
PEPROCESS Process;
HANDLE ProcessId;
FILETIME FileTime;
HANDLE ParentProcessId;
CLIENT_ID CreatorId;
UNICODE_STRING CommandLine;
} PROCESS_CREATE_CALLBACK_INFO, * PPROCESS_CREATE_CALLBACK_INFO;
typedef struct _THREAD_CREATE_CALLBACK_INFO {
HANDLE SourceProcessId;
HANDLE TargetProcessId;
HANDLE TargetThreadId;
FILETIME FileTime;
} THREAD_CREATE_CALLBACK_INFO, * PTHREAD_CREATE_CALLBACK_INFO;
typedef struct _PROCESS_TERMINATE_CALLBACK_INFO {
FILETIME FileTime;
HANDLE SourceProcessId;
HANDLE TargetProcessId;
} PROCESS_TERMINATE_CALLBACK_INFO, * PPROCESS_TERMINATE_CALLBACK_INFO;
//
// global variable to store the schema
//
extern EventSchema g_EventSchema;
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS RegisterCallbacks(
);
_IRQL_requires_max_(PASSIVE_LEVEL)
VOID CreateProcessNotifyRoutineEx(
_In_ PEPROCESS Process,
_In_ HANDLE ProcessId,
_In_ PPS_CREATE_NOTIFY_INFO CreateInfo
);
_IRQL_requires_max_(PASSIVE_LEVEL)
VOID PsCreateThreadNotifyRoutine(
_In_ HANDLE ProcessId,
_In_ HANDLE ThreadId,
_In_ BOOLEAN Create
);
_IRQL_requires_max_(PASSIVE_LEVEL)
VOID TerminateProcessNotifyRoutine(
_In_ HANDLE ParentProcessId,
_In_ HANDLE ProcessId,
_In_ BOOLEAN Create
);
_IRQL_requires_max_(PASSIVE_LEVEL)
VOID
LoadImageWorkerThread(
_In_ PVOID StartContext
);
_IRQL_requires_max_(PASSIVE_LEVEL)
VOID
LoadImageRoutine(
_In_ PUNICODE_STRING FullImageName,
_In_ HANDLE ProcessId,
_In_ PIMAGE_INFO ImageInfo
);
_IRQL_requires_max_(PASSIVE_LEVEL)
void PostProcessHandleCallback(
_In_ PVOID RegistrationContext,
_In_ POB_POST_OPERATION_INFORMATION OperationInformation
);
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS RegistryCallback(
_In_ PVOID CallbackContext,
_In_ PVOID RegNotifyClass,
_In_ PVOID RegObject
);
#endif // !_CALLBACK_
================================================
FILE: JonMon/driver.cpp
================================================
#include "driver.h"
#include "callbacks.h"
#include "process.h"
TRACELOGGING_DEFINE_PROVIDER(g_hJonMon, "JonMon",
(0xdd82bf6f, 0x5295, 0x4541, 0x96, 0x8d, 0x8c, 0xac, 0x58, 0xe5, 0x72, 0xe4));
extern "C"
NTSTATUS DriverEntry(
_In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
)
{
TraceLoggingRegister(g_hJonMon);
TraceLoggingWrite(
g_hJonMon,
"100",
TraceLoggingInt32(100, "EventID"),
TraceLoggingBool(TRUE, "TraceLogging Provider Registered")
);
g_RegPath.Buffer = (PWSTR)ExAllocatePool2(POOL_FLAG_PAGED,
RegistryPath->Length, DRIVER_TAG);
if (g_RegPath.Buffer == NULL) {
DbgPrint("Failed allocation\n");
return STATUS_INSUFFICIENT_RESOURCES;
}
//
//Copy DriverObject to global variable
//
g_DriverObject = DriverObject;
g_RegPath.Length = g_RegPath.MaximumLength = RegistryPath->Length;
memcpy(g_RegPath.Buffer, RegistryPath->Buffer, g_RegPath.Length);
DriverObject->DriverUnload = JonMonUnload;
DriverObject->MajorFunction[IRP_MJ_CREATE] = JonMonCreateClose;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = JonMonCreateClose;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = JonMonDeviceControl;
UNICODE_STRING name;
RtlInitUnicodeString(&name, L"\\Device\\JonMon");
PDEVICE_OBJECT DeviceObject;
NTSTATUS status = IoCreateDevice(DriverObject, 0, &name, FILE_DEVICE_UNKNOWN, 0, FALSE, &DeviceObject);
if (!NT_SUCCESS(status)) {
DbgPrint("Error creating device: 0x%X\n", status);
ExFreePool(g_RegPath.Buffer);
return status;
}
DriverObject->DeviceObject = DeviceObject;
DeviceObject->Flags |= DO_DIRECT_IO;
UNICODE_STRING symlink;
RtlInitUnicodeString(&symlink, L"\\??\\JonMon");
status = IoCreateSymbolicLink(&symlink, &name);
if (!NT_SUCCESS(status)) {
DbgPrint("Error creating device: 0x%X\n", status);
ExFreePool(g_RegPath.Buffer);
IoDeleteDevice(DeviceObject);
return status;
}
ExFreePool(g_RegPath.Buffer);
return status;
}
NTSTATUS JonMonDeviceControl(
_In_ PDEVICE_OBJECT,
_In_ PIRP Irp
) {
auto irpSp = IoGetCurrentIrpStackLocation(Irp);
auto status = STATUS_INVALID_DEVICE_REQUEST;
auto& dic = irpSp->Parameters.DeviceIoControl;
auto len = 0;
switch (dic.IoControlCode) {
case IOCTL_CHANGE_PROTECTION_LEVEL_PROCESS:
{
ChangePPL();
}
case IOCTL_EVENT_CONFIGURATION:
{
if (dic.InputBufferLength < sizeof(EventSchema)) {
status = STATUS_BUFFER_TOO_SMALL;
break;
}
auto schema = (EventSchema*)Irp->AssociatedIrp.SystemBuffer;
if (schema == nullptr) {
status = STATUS_INVALID_PARAMETER;
break;
}
g_EventSchema.ConfigSet = true;
g_EventSchema.ConfigVersion = schema->ConfigVersion;
g_EventSchema.JonMonVersion = schema->JonMonVersion;
g_EventSchema.ProcessCreation = schema->ProcessCreation;
g_EventSchema.ProcessTermination = schema->ProcessTermination;
g_EventSchema.Registry = schema->Registry;
g_EventSchema.ProcessHandleCreation = schema->ProcessHandleCreation;
g_EventSchema.ProcessHandleDuplication = schema->ProcessHandleDuplication;
g_EventSchema.RemoteThreadCreation = schema->RemoteThreadCreation;
g_EventSchema.ImageLoad = schema->ImageLoad;
g_EventSchema.File = schema->File;
//
// TraceLogging Event
//
TraceLoggingWrite(
g_hJonMon,
"101",
TraceLoggingInt32(101, "EventID"),
TraceLoggingBool(schema->ProcessCreation, "ProcessCreation"),
TraceLoggingBool(schema->ProcessTermination, "ProcessTermination"),
TraceLoggingBool(schema->Registry, "RegistryEvents"),
TraceLoggingBool(schema->ProcessHandleCreation, "ProcessHandleCreation"),
TraceLoggingBool(schema->ProcessHandleDuplication, "ProcessHandleDuplication"),
TraceLoggingBool(schema->RemoteThreadCreation, "RemoteThreadCreation"),
TraceLoggingBool(schema->ImageLoad, "ImageLoad"),
TraceLoggingBool(schema->File, "FileEvents")
);
HANDLE hRegisterCallbackThread = NULL;
OBJECT_ATTRIBUTES objectAttributes;
InitializeObjectAttributes(&objectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
status = PsCreateSystemThread(&hRegisterCallbackThread, THREAD_ALL_ACCESS, &objectAttributes, NULL, NULL, (PKSTART_ROUTINE)RegisterCallbacks, NULL);
if (!NT_SUCCESS(status)) {
DbgPrint("PsCreateSystemThread - RegisterCallback failed: %x\n", status);
}
if (hRegisterCallbackThread != NULL)
{
ZwClose(hRegisterCallbackThread);
}
status = STATUS_SUCCESS;
break;
}
default:
break;
}
return CompleteRequest(Irp, status, len);
}
VOID AlterPPL(
_In_ ULONG PID,
_In_ ULONG value
) {
ULONG offset = 0x0;
RTL_OSVERSIONINFOEXW osInfo = { 0 };
osInfo.dwOSVersionInfoSize = sizeof(osInfo);
RtlGetVersion((POSVERSIONINFOW)&osInfo);
#ifdef _M_ARM64
if (osInfo.dwBuildNumber < 19045 || osInfo.dwBuildNumber > 26100) {
DbgPrint("OS Version is not supported\n");
return;
}
if (osInfo.dwBuildNumber >= 19045 && osInfo.dwBuildNumber <= 22631) {
offset = 0x939;
}
if (osInfo.dwBuildNumber == 26100) {
offset = 0x6b8;
}
#endif
#ifdef _M_X64
if (osInfo.dwBuildNumber < 19045 || osInfo.dwBuildNumber > 26100) {
DbgPrint("OS Version is not supported\n");
return;
}
if (osInfo.dwBuildNumber >= 19045 && osInfo.dwBuildNumber <= 22631) {
offset = 0x878;
}
if (osInfo.dwBuildNumber == 26100) {
offset = 0x5f8;
}
#endif
PEPROCESS pProcess = NULL;
PPROCESS_SIGNATURE_PROTECTION pSignatureProtect = NULL;
ULONG pid = PID;
NTSTATUS status = PsLookupProcessByProcessId((HANDLE)pid, &pProcess);
if (NT_SUCCESS(status)) {
DbgPrint("Changing PPL value for target PROCESS ID: %d\n", PID);
pSignatureProtect = (PPROCESS_SIGNATURE_PROTECTION)(((ULONG_PTR)pProcess) + offset);
if (value == 1) {
pSignatureProtect->SignatureLevel = 0x11;
pSignatureProtect->SectionSignatureLevel = 0x11;
pSignatureProtect->Protection = { 1,0,3 };
}
if (value == 0)
{
pSignatureProtect->SignatureLevel = 0x0;
pSignatureProtect->SectionSignatureLevel = 0x0;
pSignatureProtect->Protection = { 0,0,0 };
}
DbgPrint("Process ID %d 's protection level has changed\n", PID);
ObDereferenceObject(pProcess);
}
}
VOID ChangePPL()
{
UNICODE_STRING functionName;
RtlInitUnicodeString(&functionName, L"ZwQuerySystemInformation");
ZwQuerySystemInformation = (ZWQUERYSYSTEMINFORMATION)MmGetSystemRoutineAddress(&functionName);
NTSTATUS status;
ULONG bufferSize = 0;
UNICODE_STRING processName, processPath;
RtlInitUnicodeString(&processName, L"JonMon-Service.exe");
RtlInitUnicodeString(&processPath, L"\\Windows\\JonMon-Service.exe");
status = ZwQuerySystemInformation(SystemProcessInformation, NULL, 0, &bufferSize);
if (status != STATUS_INFO_LENGTH_MISMATCH) {
return;
}
if (bufferSize) {
PVOID info = ExAllocatePool2(POOL_FLAG_PAGED, bufferSize, DRIVER_TAG);
if (info) {
status = ZwQuerySystemInformation(SystemProcessInformation, info, bufferSize, &bufferSize);
if (NT_SUCCESS(status)) {
PSYSTEM_PROCESSES processInfo = (PSYSTEM_PROCESSES)info;
UNICODE_STRING imagePath;
imagePath.MaximumLength = 1024;
imagePath.Buffer = (PWSTR)ExAllocatePool2(POOL_FLAG_PAGED, 1024, DRIVER_TAG);
if (imagePath.Buffer == NULL) {
DbgPrint("Failed allocation\n");
return;
}
int count = 0;
do {
do {
if (RtlEqualUnicodeString(&processName, &processInfo->ProcessName, TRUE)) {
status = GetProcessImageName((HANDLE)processInfo->ProcessId, &imagePath);
if (wcsstr(imagePath.Buffer, processPath.Buffer) != NULL) {
g_ServicePID = (ULONG)processInfo->ProcessId;
AlterPPL(g_ServicePID, 1);
count++;
DbgPrint("Found JonMon-Service.exe\n");
}
}
processInfo = (PSYSTEM_PROCESSES)((unsigned char*)processInfo + processInfo->NextEntryDelta);
} while (processInfo->NextEntryDelta);
} while (count != 1);
ExFreePoolWithTag(imagePath.Buffer, DRIVER_TAG);
}
ExFreePoolWithTag(info, DRIVER_TAG);
}
}
}
//
//Function unloads the driver
//
VOID JonMonUnload(
_In_ PDRIVER_OBJECT DriverObject
) {
PAGED_CODE();
TraceLoggingWrite(
g_hJonMon,
"100",
TraceLoggingUInt32(100, "EventID"),
TraceLoggingValue(FALSE, "TraceLogging Provider Registered")
);
TraceLoggingUnregister(g_hJonMon);
AlterPPL(g_ServicePID, 0);
if (g_EventSchema.Registry == TRUE)
{
CmUnRegisterCallback(Cookie);
DbgPrint((DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "CmUnRegisterCallback Unloaded\n"));
}
if(g_EventSchema.ProcessCreation == TRUE)
{
PsSetCreateProcessNotifyRoutineEx(CreateProcessNotifyRoutineEx, TRUE);
DbgPrint((DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "PsSetCreateProcessNotifyRoutineEx Unloaded\n"));
}
if (g_EventSchema.ProcessHandleCreation == TRUE || g_EventSchema.ProcessHandleDuplication == TRUE)
{
ObUnRegisterCallbacks(ProcessRegistrationHandle);
DbgPrint((DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "ObUnRegisterCallbacks Unloaded\n"));
}
if (g_EventSchema.ImageLoad == TRUE)
{
PsRemoveLoadImageNotifyRoutine(LoadImageRoutine);
DbgPrint((DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "PsSetLoadImageNotifyRoutine Unloaded\n"));
}
if (g_EventSchema.RemoteThreadCreation == TRUE)
{
PsRemoveCreateThreadNotifyRoutine(PsCreateThreadNotifyRoutine);
DbgPrint((DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "PsSetCreateThreadNotifyRoutine Unloaded\n"));
}
if (g_EventSchema.ProcessTermination == TRUE)
{
PsSetCreateProcessNotifyRoutine(TerminateProcessNotifyRoutine, TRUE);
DbgPrint((DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "PsSetCreateProcessNotifyRoutine Unloaded\n"));
}
//sleep for 5 seconds to allow worker threads to finish
LARGE_INTEGER interval;
interval.QuadPart = -(3 * 10000000);
KeDelayExecutionThread(KernelMode, FALSE, &interval);
UNICODE_STRING symlink;
RtlInitUnicodeString(&symlink, L"\\??\\JonMon");
IoDeleteSymbolicLink(&symlink);
IoDeleteDevice(DriverObject->DeviceObject);
DbgPrint("JonMon Driver Unloaded\n");
}
//Function completes the driver requests
NTSTATUS CompleteRequest(
PIRP Irp,
NTSTATUS status,
ULONG_PTR info
) {
PAGED_CODE();
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = info;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}
//Function handles the create and close requests. Function just points to CompleteRequest.
NTSTATUS JonMonCreateClose(
_In_ PDEVICE_OBJECT,
_In_ PIRP Irp
) {
PAGED_CODE();
return CompleteRequest(Irp);
}
================================================
FILE: JonMon/driver.h
================================================
#ifndef _DRIVER_
#define _DRIVER_
#include "shared.h"
/*
* Global variable to store the registry path
*/
#define JonMon_DEVICE 0x8010
#define IOCTL_CHANGE_PROTECTION_LEVEL_PROCESS CTL_CODE(JonMon_DEVICE, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_EVENT_CONFIGURATION CTL_CODE(JonMon_DEVICE, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS)
UNICODE_STRING g_RegPath;
typedef struct _SYSTEM_THREADS {
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER CreateTime;
ULONG WaitTime;
PVOID StartAddress;
CLIENT_ID ClientId;
KPRIORITY Priority;
KPRIORITY BasePriority;
ULONG ContextSwitchCount;
LONG State;
LONG WaitReason;
} SYSTEM_THREADS, * PSYSTEM_THREADS;
typedef struct _SYSTEM_PROCESSES {
ULONG NextEntryDelta;
ULONG ThreadCount;
ULONG Reserved1[6];
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ProcessName;
KPRIORITY BasePriority;
SIZE_T ProcessId;
SIZE_T InheritedFromProcessId;
ULONG HandleCount;
ULONG Reserved2[2];
VM_COUNTERS VmCounters;
IO_COUNTERS IoCounters;
SYSTEM_THREADS Threads[1];
} SYSTEM_PROCESSES, * PSYSTEM_PROCESSES;
typedef struct _PS_PROTECTION {
UCHAR Type : 3;
UCHAR Audit : 1;
UCHAR Signer : 4;
} PS_PROTECTION, * PPS_PROTECTION;
typedef struct _PROCESS_SIGNATURE_PROTECTION {
UCHAR SignatureLevel;
UCHAR SectionSignatureLevel;
PS_PROTECTION Protection;
} PROCESS_SIGNATURE_PROTECTION, * PPROCESS_SIGNATURE_PROTECTION;
typedef NTSTATUS(NTAPI* ZWQUERYSYSTEMINFORMATION)(
IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength
);
ZWQUERYSYSTEMINFORMATION ZwQuerySystemInformation;
/*
* Driver Function Protoypes
*/
NTSTATUS JonMonCreateClose(
_In_ PDEVICE_OBJECT DeviceObject,
_In_ PIRP Irp
);
NTSTATUS CompleteRequest(
PIRP Irp,
NTSTATUS status = STATUS_SUCCESS,
ULONG_PTR info = 0
);
NTSTATUS JonMonDeviceControl(
_In_ PDEVICE_OBJECT,
_In_ PIRP Irp
);
VOID JonMonUnload(
_In_ PDRIVER_OBJECT DriverObject
);
VOID AlterPPL(
_In_ ULONG PID,
_In_ ULONG value
);
VOID ChangePPL();
#endif // !_DRIVER_
================================================
FILE: JonMon/jtime.h
================================================
#ifndef _JTIME_
#define _JTIME_
typedef unsigned short WORD;
typedef unsigned long DWORD;
typedef struct _SYSTEMTIME {
WORD wYear;
WORD wMonth;
WORD wDayOfWeek;
WORD wDay;
WORD wHour;
WORD wMinute;
WORD wSecond;
WORD wMilliseconds;
} SYSTEMTIME, * PSYSTEMTIME, * LPSYSTEMTIME;
typedef struct _FILETIME {
DWORD dwLowDateTime;
DWORD dwHighDateTime;
} FILETIME, * PFILETIME, * LPFILETIME;
#endif // !_TIME_
================================================
FILE: JonMon/minifilter.cpp
================================================
#include "minifilter.h"
#include "process.h"
PAGED_FILE();
PFLT_FILTER gFilterHandle;
NTSTATUS
JonMonFilterUnload
(
_In_ FLT_FILTER_UNLOAD_FLAGS Flags
)
{
PAGED_CODE();
NTSTATUS status;
DbgPrint("In JonMonFilterUnload\n");
if (Flags == FLTFL_FILTER_UNLOAD_MANDATORY) {
FltUnregisterFilter(gFilterHandle);
status = STATUS_SUCCESS;
}
else {
status = STATUS_FLT_DO_NOT_DETACH;
}
return status;
}
_IRQL_requires_max_(PASSIVE_LEVEL)
FLT_POSTOP_CALLBACK_STATUS
FLTAPI
FilterPostCallback
(
_In_ PFLT_CALLBACK_DATA Data,
_In_ PCFLT_RELATED_OBJECTS FltObjects,
_In_ PVOID CompletionContext,
_In_ FLT_POST_OPERATION_FLAGS Flags
) {
UNREFERENCED_PARAMETER(Flags);
UNREFERENCED_PARAMETER(FltObjects);
UNREFERENCED_PARAMETER(CompletionContext);
HANDLE sourceThreadId = PsGetThreadId(Data->Thread);
ULONG currentProcessId = FltGetRequestorProcessId(Data);
ULONGLONG sourceProcStartKey = PsGetProcessStartKey(PsGetCurrentProcess());
FILETIME filetime;
NTSTATUS status;
PFLT_FILE_NAME_INFORMATION fileNameInfo = NULL;
if (Data->RequestorMode != UserMode) {
goto Exit;
}
if (currentProcessId == 4) {
goto Exit;
}
//
//go to exit if filename is null
//
if (Data->Iopb->TargetFileObject->FileName.Length == 0) {
goto Exit;
}
KeQuerySystemTime(&filetime);
switch (Data->Iopb->MajorFunction) {
case IRP_MJ_CREATE:
{
switch (Data->IoStatus.Information) {
case FILE_CREATED:
{
status = FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP, &fileNameInfo);
if (!NT_SUCCESS(status)) {
goto Exit;
}
TraceLoggingWrite(
g_hJonMon,
"FileCreate",
TraceLoggingInt32(10, "EventID"),
TraceLoggingValue(sourceThreadId, "SourceThreadId"),
TraceLoggingValue(currentProcessId, "SourceProcessId"),
TraceLoggingValue(sourceProcStartKey, "SourceProcStartKey"),
TraceLoggingWideString(fileNameInfo->Name.Buffer, "FileName"),
TraceLoggingFileTime(filetime, "EventTime")
);
break;
}
case FILE_OPENED:
{
if (FltObjects->FileObject->Flags & FO_MAILSLOT)
{
DWORD RequestedRights = Data->Iopb->Parameters.Create.SecurityContext->DesiredAccess;
status = FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP, &fileNameInfo);
if (!NT_SUCCESS(status)) {
goto Exit;
}
TraceLoggingWrite(
g_hJonMon,
"MailslotOpen",
TraceLoggingInt32(14, "EventID"),
TraceLoggingValue(sourceThreadId, "SourceThreadId"),
TraceLoggingValue(currentProcessId, "SourceProcessId"),
TraceLoggingValue(sourceProcStartKey, "SourceProcStartKey"),
TraceLoggingWideString(fileNameInfo->Name.Buffer, "FileName"),
TraceLoggingValue(RequestedRights, "RequestedRights"),
TraceLoggingFileTime(filetime, "EventTime")
);
break;
}
if (FltObjects->FileObject->Flags & FO_NAMED_PIPE)
{
DWORD RequestedRights = Data->Iopb->Parameters.Create.SecurityContext->DesiredAccess;
status = FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP, &fileNameInfo);
if (!NT_SUCCESS(status)) {
goto Exit;
}
TraceLoggingWrite(
g_hJonMon,
"NamedPipeConnection",
TraceLoggingInt32(12, "EventID"),
TraceLoggingValue(sourceThreadId, "SourceThreadId"),
TraceLoggingValue(currentProcessId, "SourceProcessId"),
TraceLoggingValue(sourceProcStartKey, "SourceProcStartKey"),
TraceLoggingWideString(fileNameInfo->Name.Buffer, "FileName"),
TraceLoggingValue(RequestedRights, "RequestedRights"),
TraceLoggingFileTime(filetime, "EventTime")
);
break;
}
break;
}
case FILE_SUPERSEDED:
{
if (Data->Iopb->TargetFileObject->FileName.Length == 0)
{
break;
}
status = FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP, &fileNameInfo);
if (!NT_SUCCESS(status)) {
DbgPrint("[IRP_MJ_CREATE_NAMED_PIPE] Failed to get file info\n");
goto Exit;
}
//
// check to see if FileName is valid before proceeding
//
if (Data->Iopb->Parameters.Create.Options & FO_REMOTE_ORIGIN)
{
//
// only print if fileNameInfo->Name.Buffer contains pipe
//
if (wcsstr(fileNameInfo->Name.Buffer, L"\\pipe\\") != NULL) {
TraceLoggingWrite(
g_hJonMon,
"RemoteNamedPipeConnection",
TraceLoggingInt32(15, "EventID"),
TraceLoggingFileTime(filetime, "EventTime"),
TraceLoggingWideString(fileNameInfo->Name.Buffer, "FileName"),
TraceLoggingValue(currentProcessId, "SourceProcessId"),
TraceLoggingValue(sourceProcStartKey, "SourceProcStartKey"),
TraceLoggingValue(sourceThreadId, "SourceThreadId")
);
break;
}
}
if (Data->Iopb->Parameters.Create.Options == (FO_REMOTE_ORIGIN | FO_SEQUENTIAL_ONLY | FO_CACHE_SUPPORTED)) {
//
// only print if fileNameInfo->Name.Buffer contains mailslot
//
if (wcsstr(fileNameInfo->Name.Buffer, L"mailslot") != NULL) {
TraceLoggingWrite(
g_hJonMon,
"RemoteMailslotConnection",
TraceLoggingInt32(15, "EventID"),
TraceLoggingFileTime(filetime, "EventTime"),
TraceLoggingWideString(Data->Iopb->TargetFileObject->FileName.Buffer, "FileName"),
TraceLoggingValue(currentProcessId, "SourceProcessId"),
TraceLoggingValue(sourceProcStartKey, "SourceProcStartKey"),
TraceLoggingValue(sourceThreadId, "SourceThreadId")
);
break;
}
}
break;
}
default:
{
break;
}
}
break;
}
case IRP_MJ_CREATE_NAMED_PIPE:
{
DWORD RequestedRights = Data->Iopb->Parameters.CreatePipe.SecurityContext->DesiredAccess;
DWORD GrantedRights = Data->Iopb->Parameters.CreatePipe.SecurityContext->AccessState->PreviouslyGrantedAccess;
if (Data->IoStatus.Information == FILE_CREATED || Data->IoStatus.Information == FILE_OPENED)
{
status = FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP, &fileNameInfo);
if (!NT_SUCCESS(status)) {
DbgPrint("[IRP_MJ_CREATE_NAMED_PIPE] Failed to get file info\n");
goto Exit;
}
switch (Data->IoStatus.Information) {
case FILE_CREATED:
{
bool RemoteCreation = FALSE;
if (FltObjects->FileObject->Flags & FO_REMOTE_ORIGIN) {
DbgPrint(" Creation request came from remote machine\n");
RemoteCreation = TRUE;
}
TraceLoggingWrite(
g_hJonMon,
"NamedPipeCreate",
TraceLoggingInt32(11, "EventID"),
TraceLoggingValue(sourceThreadId, "SourceThreadId"),
TraceLoggingValue(currentProcessId, "SourceProcessId"),
TraceLoggingValue(sourceProcStartKey, "SourceProcStartKey"),
TraceLoggingWideString(fileNameInfo->Name.Buffer, "FileName"),
TraceLoggingValue(RequestedRights, "RequestedRights"),
TraceLoggingValue(GrantedRights, "GrantedRights"),
TraceLoggingFileTime(filetime, "EventTime")
);
break;
}
default:
{
break;
}
}
}
break;
}
case IRP_MJ_CREATE_MAILSLOT:
{
if (Data->IoStatus.Information == FILE_CREATED || Data->IoStatus.Information == FILE_OPENED) {
DWORD RequestedRights = Data->Iopb->Parameters.CreateMailslot.SecurityContext->DesiredAccess;
status = FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP, &fileNameInfo);
if (!NT_SUCCESS(status)) {
DbgPrint("[IRP_MJ_CREATE_MAILSLOT] Failed to get file info\n");
goto Exit;
}
switch (Data->IoStatus.Information)
{
case FILE_CREATED:
{
TraceLoggingWrite(
g_hJonMon,
"MailslotCreate",
TraceLoggingInt32(13, "EventID"),
TraceLoggingValue(sourceThreadId, "SourceThreadId"),
TraceLoggingValue(currentProcessId, "SourceProcessId"),
TraceLoggingValue(sourceProcStartKey, "SourceProcStartKey"),
TraceLoggingWideString(fileNameInfo->Name.Buffer, "FileName"),
TraceLoggingValue(RequestedRights, "RequestedRights"),
TraceLoggingFileTime(filetime, "EventTime")
);
break;
}
default:
{
break;
}
}
}
break;
}
default:
{
break;
}
}
Exit:
if(fileNameInfo != NULL)
{
FltReleaseFileNameInformation(fileNameInfo);
}
return FLT_POSTOP_FINISHED_PROCESSING;
};
//
// FilterPreCallback placeholder
//
_IRQL_requires_max_(APC_LEVEL)
FLT_PREOP_CALLBACK_STATUS
FLTAPI
FilterPreCallback
(
_In_ PFLT_CALLBACK_DATA Data,
_In_ PCFLT_RELATED_OBJECTS FltObjects,
_In_ PVOID* CompletionContext
) {
UNREFERENCED_PARAMETER(Data);
UNREFERENCED_PARAMETER(FltObjects);
UNREFERENCED_PARAMETER(CompletionContext);
PAGED_CODE();
return FLT_PREOP_SUCCESS_WITH_CALLBACK;
}
NTSTATUS
FltCallbackStart
(
_In_ PDRIVER_OBJECT DriverObject
)
{
PAGED_CODE();
NTSTATUS status;
CONST FLT_OPERATION_REGISTRATION FileSystemOperationCallbacks[] = {
{
IRP_MJ_CREATE,
0,
NULL,
FilterPostCallback
},
{
IRP_MJ_CREATE_NAMED_PIPE,
0,
NULL,
FilterPostCallback
},
{
IRP_MJ_CREATE_MAILSLOT,
0,
NULL,
FilterPostCallback
},
{
IRP_MJ_OPERATION_END
}
};
CONST FLT_REGISTRATION FilterRegistration = {
sizeof(FLT_REGISTRATION),
FLT_REGISTRATION_VERSION,
FLTFL_REGISTRATION_SUPPORT_NPFS_MSFS,
NULL,
FileSystemOperationCallbacks,
JonMonFilterUnload,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
};
status = FltRegisterFilter(
DriverObject,
&FilterRegistration,
&gFilterHandle
);
if (!NT_SUCCESS(status)) {
DbgPrint("Failed FltRegisterFilter\n");
return status;
}
status = FltStartFiltering(gFilterHandle);
if (!NT_SUCCESS(status)) {
DbgPrint("Failed FltStartFiltering\n");
FltUnregisterFilter(gFilterHandle);
gFilterHandle = nullptr;
}
return status;
}
================================================
FILE: JonMon/minifilter.h
================================================
#ifndef _MINIFILTER_
#define _MINIFILTER_
#include "shared.h"
extern PFLT_FILTER gFilterHandle;
NTSTATUS
JonMonFilterUnload
(
_In_ FLT_FILTER_UNLOAD_FLAGS Flags
);
_IRQL_requires_max_(PASSIVE_LEVEL)
FLT_POSTOP_CALLBACK_STATUS
FLTAPI
FilterPostCallback
(
_In_ PFLT_CALLBACK_DATA Data,
_In_ PCFLT_RELATED_OBJECTS FltObjects,
_In_ PVOID CompletionContext,
_In_ FLT_POST_OPERATION_FLAGS Flags
);
_IRQL_requires_max_(APC_LEVEL)
FLT_PREOP_CALLBACK_STATUS
FLTAPI
FilterPreCallback
(
_In_ PFLT_CALLBACK_DATA Data,
_In_ PCFLT_RELATED_OBJECTS FltObjects,
_In_ PVOID* CompletionContext
);
NTSTATUS
FltCallbackStart
(
_In_ PDRIVER_OBJECT DriverObject
);
#endif // !_MINIFILTER_
================================================
FILE: JonMon/process.cpp
================================================
#include "process.h"
PAGED_FILE();
ZWQUERYINFORMATIONPROCESS ZwQueryInformationProcess;
NTSTATUS GetProcessImageName(HANDLE processId, PUNICODE_STRING ProcessImageName)
{
PAGED_CODE();
NTSTATUS status;
ULONG returnedLength;
ULONG bufferLength;
HANDLE hProcess = NULL;
PVOID buffer{};
PEPROCESS eProcess;
UNICODE_STRING routineName;
status = PsLookupProcessByProcessId(processId, &eProcess);
if (!NT_SUCCESS(status))
{
goto Exit;
}
status = ObOpenObjectByPointer(
eProcess,
OBJ_KERNEL_HANDLE, NULL,
0,
0,
KernelMode,
&hProcess);
if (!NT_SUCCESS(status))
{
goto Exit;
}
ObDereferenceObject(eProcess);
if (!ZwQueryInformationProcess) {
RtlInitUnicodeString(&routineName, L"ZwQueryInformationProcess");
ZwQueryInformationProcess = (ZWQUERYINFORMATIONPROCESS)MmGetSystemRoutineAddress(&routineName);
if (ZwQueryInformationProcess == NULL) {
DbgPrint("Cannot resolve ZwQueryInformationProcess\n");
return STATUS_NOT_FOUND;
}
}
status = ZwQueryInformationProcess(hProcess, ProcessImageFileName, NULL, 0, &returnedLength);
if (status != STATUS_INFO_LENGTH_MISMATCH)
{
goto Exit;
}
bufferLength = returnedLength;
if (ProcessImageName->MaximumLength < bufferLength)
{
ProcessImageName->MaximumLength = (USHORT)bufferLength;
return STATUS_BUFFER_OVERFLOW;
}
buffer = ExAllocatePool2(POOL_FLAG_PAGED, bufferLength, PROCESS_TAG);
if (buffer == NULL)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
status = ZwQueryInformationProcess(hProcess, ProcessImageFileName, buffer, bufferLength, &bufferLength);
if (!NT_SUCCESS(status))
{
goto Exit;
}
RtlCopyUnicodeString(ProcessImageName, (PUNICODE_STRING)buffer);
//Adding null terminator
ProcessImageName->Buffer[ProcessImageName->Length / sizeof(UNICODE_NULL)] = UNICODE_NULL;
Exit:
if(hProcess != NULL)
{
ZwClose(hProcess);
}
if (buffer != NULL)
{
ExFreePoolWithTag(buffer, PROCESS_TAG);
}
return status;
}
================================================
FILE: JonMon/process.h
================================================
#ifndef _PROCESS_
#define _PROCESS_
#include "shared.h"
typedef NTSTATUS(*ZWQUERYINFORMATIONPROCESS) (
__in HANDLE ProcessHandle,
__in PROCESSINFOCLASS ProcessInformationClass,
__out_bcount(ProcessInformationLength) PVOID ProcessInformation,
__in ULONG ProcessInformationLength,
__out_opt PULONG ReturnLength
);
NTSTATUS GetProcessImageName(HANDLE processId, PUNICODE_STRING ProcessImageName);
NTSTATUS GetProcessToken(HANDLE processId, PHANDLE hToken);
#endif // !_PROCESS_
================================================
FILE: JonMon/registry.cpp
================================================
#include "registry.h"
#include "shared.h"
#include "process.h"
#include <winerror.h>
PAGED_FILE();
NTSTATUS
GetRegistryKeyPath(
_In_ PVOID object,
_In_ ULONG tag,
_In_ PCWSTR* keyPath
) {
PCUNICODE_STRING registryPath = NULL;
NTSTATUS status;
PWCHAR buffer = NULL;
ULONG bufferSize;
PAGED_CODE();
status = CmCallbackGetKeyObjectIDEx(&Cookie, object, NULL, ®istryPath, 0);
if (!NT_SUCCESS(status) || registryPath == NULL) {
DbgPrint("CmCallbackGetKeyObjectIDEx failed. Status 0x%x", status);
goto Exit;
}
// Allocate a buffer for the registry path
bufferSize = (registryPath->Length / sizeof(WCHAR)) + 1;
buffer = (PWCHAR)ExAllocatePool2(POOL_FLAG_PAGED, bufferSize * sizeof(WCHAR), tag);
if (buffer == NULL) {
DbgPrint("GetRegistryKeyPath - ExAllocatePool2 failed. Status 0x%x", status);
goto Exit;
}
// Zero the buffer before copying the registry path and adding a null terminator
RtlZeroMemory(buffer, bufferSize + sizeof(UNICODE_NULL));
RtlCopyMemory(buffer, registryPath->Buffer, registryPath->Length);
buffer[bufferSize - 1] = UNICODE_NULL;
*keyPath = buffer;
status = STATUS_SUCCESS;
Exit:
if (registryPath != NULL) {
CmCallbackReleaseKeyObjectIDEx(registryPath);
}
return status;
}
================================================
FILE: JonMon/registry.h
================================================
#ifndef _REGISTRY_
#define _REGISTRY_
#include <ntifs.h>
//
// Structure to hold registry callback info
//
typedef struct _REG_SET_VALUE_CALLBACK_INFO
{
PEPROCESS SourceProcess;
HANDLE SourceProcessId;
HANDLE SourceThreadId;
PETHREAD SourceThread;
ULONG Type;
PCWSTR KeyPath;
PVOID Data;
ULONG DataSize;
UNICODE_STRING ValueName;
} REG_SET_VALUE_CALLBACK_INFO, * PREG_SET_VALUE_CALLBACK_INFO;
typedef struct _REG_CREATE_KEY_CALLBACK_INFO
{
HANDLE SourceProcessId;
ULONGLONG ProcStartKey;
PETHREAD SourceThread;
HANDLE SourceThreadId;
ACCESS_MASK DesiredAccess;
UNICODE_STRING KeyPath;
} REG_CREATE_KEY_CALLBACK_INFO, * PREG_CREATE_KEY_CALLBACK_INFO;
typedef struct _REG_DELETE_KEY_CALLBACK_INFO
{
PEPROCESS SourceProcess;
HANDLE SourceProcessId;
HANDLE SourceThreadId;
PCWSTR KeyPath;
} REG_DELETE_KEY_CALLBACK_INFO, * PREG_DELETE_KEY_CALLBACK_INFO;
NTSTATUS
GetRegistryKeyPath(
_In_ PVOID object,
_In_ ULONG tag,
_In_ PCWSTR* keyPath
);
VOID
SendSetValueRegistryInfo(
_In_ PVOID StartContext
);
VOID
DeleteKey(
_In_ PVOID context,
_In_ PREG_DELETE_KEY_INFORMATION info
);
VOID
CreateKey(
_In_ PVOID StartContext
);
VOID
SaveKey(
_In_ PVOID context,
_In_ PREG_SAVE_KEY_INFORMATION info
);
#endif // !_REGISTRY_
================================================
FILE: JonMon/shared.h
================================================
#ifndef _SHARED_
#define _SHARED_
#include <ntifs.h>
#include <ntddk.h>
#include <ntdef.h>
#include <wdm.h>
#include <Ntstrsafe.h>
#include <fltKernel.h>
#include <time.h>
#include <TraceLoggingProvider.h>
#include <minwindef.h>
#define INVALID_HANDLE_VALUE ((HANDLE)(LONG_PTR)-1)
TRACELOGGING_DECLARE_PROVIDER(g_hJonMon);
/*
TraceLogging Event Schema:
---- Security Events ----
EID 1 - Process Creation
EID 2 - Process Termination
EID 3 - Remote Thread Creation
EID 4 - Load Image
EID 5 - ProcessHandle (OpenProcess/DuplicateHandle)
EID 6 - RegistrySaveKey
EID 7 - RegistryDeleteKey
EID 8 - RegistrySetValue
EID 9 - RegistryCreateKey
EID 10 - FileOperation (CreateFile)
EID 11 - NamedPipeCreation
EID 12 - NamedPipeConnection
EID 13 - MailslotCreation
EID 14 - MailslotConnection
EID 15 - RemoteFileConnection (Named Pipes/Mailslots)
---- Debug/Informational Events ----
EID 100 - TraceLogging Provider Registered (True or False)
EID 101 - Event Schema Configuration
EID 102 - Protection Level Changed
*/
//
// https://github.com/winsiderss/systeminformer/blob/0e3d514e23cf4813ba5895c74b6d596c8966e1b3/KSystemInformer/include/kph.h#L31
//
#define PAGED_PASSIVE()\
PAGED_CODE()\
NT_ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL)
//
// https://github.com/winsiderss/systeminformer/blob/0e3d514e23cf4813ba5895c74b6d596c8966e1b3/KSystemInformer/include/kph.h#L31
//
#define PAGED_FILE() \
__pragma(bss_seg("PAGEBBS"))\
__pragma(code_seg("PAGE"))\
__pragma(data_seg("PAGEDATA"))\
__pragma(const_seg("PAGERO"))
/*
* Creating tags to be used with in different scenerios of memory allocation
*/
#define DRIVER_TAG 'monj'
#define REGISTRY_TAG 'regj'
#define PROCESS_TAG 'prcj'
#define THREAD_TAG 'thrj'
#define TOKEN_TAG 'tknj'
#define FILE_TAG 'flj'
#define CALBACK_TAG 'clkj'
#define SYSTEM_THREAD_TAG 'rhsj'
#define MAX_ALLOC 260
extern LARGE_INTEGER Cookie;
typedef struct _SYSTEM_PROCESS_INFORMATION {
ULONG NextEntryOffset;
ULONG NumberOfThreads;
LARGE_INTEGER Reserved[3];
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ImageName;
KPRIORITY BasePriority;
HANDLE ProcessId;
HANDLE InheritedFromProcessId;
} SYSTEM_PROCESS_INFORMATION, * PSYSTEM_PROCESS_INFORMATION;
typedef enum _SYSTEM_INFORMATION_CLASS {
SystemProcessInformation = 5,
} SYSTEM_INFORMATION_CLASS;
typedef struct _LIST_ENTRY* PLIST_ENTRY;
typedef struct _THREAD_LIST_ENTRY* PTHREAD_LIST_ENTRY;
typedef struct _THREAD_LIST_ENTRY {
PLIST_ENTRY PrevThread;
PLIST_ENTRY NextThread;
PETHREAD Thread;
} THREAD_LIST_ENTRY, * PTHREAD_LIST_ENTRY;
#endif // !_SHARED_
================================================
FILE: JonMon-Service/JonMon-Service.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|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</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>{bf810292-3774-41a4-b51e-cef92e26894a}</ProjectGuid>
<RootNamespace>JonMonService</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>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</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 Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="PropertySheets">
<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" />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</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>
</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>
<AdditionalIncludeDirectories>..\Libs;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</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>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<AdditionalIncludeDirectories>..\Libs;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="config.cpp" />
<ClCompile Include="context.cpp" />
<ClCompile Include="etwMain.cpp" />
<ClCompile Include="JonMonService.cpp" />
<ClCompile Include="service.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="config.h" />
<ClInclude Include="context.h" />
<ClInclude Include="etwMain.h" />
<ClInclude Include="global.h" />
<ClInclude Include="service.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
================================================
FILE: JonMon-Service/JonMonService.cpp
================================================
#include <Windows.h>
#include <iostream>
#include <setupapi.h>
#include "etwMain.h"
#include "service.h"
#include "config.h"
#pragma comment(lib, "setupapi.lib")
int wmain(int argc, wchar_t* argv[])
{
std::wstring VariantString(argv[1]);
std::wstring ConfigPath = L"JonMonConfig.json";
EventSchema_Full eventSchema = { 0 };
if (argc == 3) {
ConfigPath = argv[2];
}
BOOL FileCopy = CopyFileW(ConfigPath.c_str(), L"C:\\Windows\\JonMonConfig.json", FALSE);
if (FileCopy != TRUE) {
printf("[-] JonMonConfig.json did not copy to C:\\Windows\\JonMonConfig.json\n");
}
int result = ConfigFile(L"C:\\Windows\\JonMonConfig.json", &eventSchema);
if (VariantString == L"-etw") {
//Copying resource file to C:\Windows and installing manifest
BOOL FileCopy = CopyFileW(L"JonMon.dll", L"C:\\Windows\\JonMon.dll", FALSE);
if (FileCopy != TRUE) {
printf("[-] JonMon.dll did not copy to C:\\Windows\\JonMon.dll\n");
}
else {
printf("[*] JonMon.dll copied\n");
}
DWORD status = InstallManifest();
TraceEvent(L"JonMonDebug", JonMonDebugGuid, &eventSchema);
}
if (VariantString == L"-c")
{
std::wcout << L"JonMon EventSchema: " << std::endl;
std::wcout << L"ProcessCreationEvents: " << (eventSchema.ProcessCreation_Events ? L"True" : L"False") << std::endl;
std::wcout << L"FileEvents: " << (eventSchema.File_Events ? L"True" : L"False") << std::endl;
std::wcout << L"ProcessTerminationEvents: " << (eventSchema.ProcessTermination_Events ? L"True" : L"False") << std::endl;
std::wcout << L"RegistryEvents: " << (eventSchema.Registry_Events ? L"True" : L"False") << std::endl;
std::wcout << L"ProcessHandleCreationEvents: " << (eventSchema.ProcessHandleCreation_Events ? L"True" : L"False") << std::endl;
std::wcout << L"ProcessHandleDuplicationEvents: " << (eventSchema.ProcessHandleDuplication_Events ? L"True" : L"False") << std::endl;
std::wcout << L"RemoteThreadCreationEvents: " << (eventSchema.RemoteThreadCreation_Events ? L"True" : L"False") << std::endl;
std::wcout << L"ImageLoadEvents: " << (eventSchema.ImageLoad_Events ? L"True" : L"False") << std::endl;
std::wcout << L"RPCEvents: " << (eventSchema.RPC_Events ? L"True" : L"False") << std::endl;
std::wcout << L"NetworkEvents: " << (eventSchema.Network_Events ? L"True" : L"False") << std::endl;
std::wcout << L"DotNetLoadEvents: " << (eventSchema.DotNetLoad_Events ? L"True" : L"False") << std::endl;
std::wcout << L"AMSIEvents: " << (eventSchema.AMSI_Events ? L"True" : L"False") << std::endl;
std::wcout << L"SchedTaskEvents: " << (eventSchema.SchedTask_Events ? L"True" : L"False") << std::endl;
std::wcout << L"WMIEventSubscriptionEvents: " << (eventSchema.WMIEventSubscription_Events ? L"True" : L"False") << std::endl;
std::wcout << L"CryptUnprotectEvents: " << (eventSchema.CryptUnprotect_Events ? L"True" : L"False") << std::endl;
std::wcout << L"ThreatIntelligenceEvents: " << (eventSchema.ThreatIntelligence_Events ? L"True" : L"False") << std::endl;
std::wcout << L"ThreatIntelligenceEvents RemoteReadProcessMemory: " << (eventSchema.ThreatIntelligence_Events_RemoteReadProcessMemory ? L"True" : L"False") << std::endl;
std::wcout << L"ThreatIntelligenceEvents RemoteWriteProcessMemory: " << (eventSchema.ThreatIntelligence_Events_RemoteWriteProcessMemory ? L"True" : L"False") << std::endl;
std::wcout << L"ThreatIntelligenceEvents RemoteVirtualAllocation: " << (eventSchema.ThreatIntelligence_Events_RemoteVirtualAllocation ? L"True" : L"False") << std::endl;
std::wcout << L"ThreatIntelligenceEvents RemoteQueueUserAPC: " << (eventSchema.ThreatIntelligence_Events_RemoteQueueUserAPC ? L"True" : L"False") << std::endl;
std::wcout << L"TokenImpersonationEvents: " << (eventSchema.TokenImpersonation_Events ? L"True" : L"False") << std::endl;
std::wcout << L"ConfigVersion: " << eventSchema.ConfigVersion << std::endl;
std::wcout << L"JonMonVersion: " << eventSchema.JonMonVersion << std::endl;
EventSchema_KM eventSchemaKM = { 0 };
eventSchemaKM.ConfigSet = eventSchema.ConfigSet;
eventSchemaKM.ProcessCreation = eventSchema.ProcessCreation_Events;
eventSchemaKM.ProcessTermination = eventSchema.ProcessTermination_Events;
eventSchemaKM.ProcessHandleCreation = eventSchema.ProcessHandleCreation_Events;
eventSchemaKM.ProcessHandleDuplication = eventSchema.ProcessHandleDuplication_Events;
eventSchemaKM.RemoteThreadCreation = eventSchema.RemoteThreadCreation_Events;
eventSchemaKM.ImageLoad = eventSchema.ImageLoad_Events;
eventSchemaKM.File = eventSchema.File_Events;
eventSchemaKM.Registry = eventSchema.Registry_Events;
eventSchemaKM.ConfigVersion = eventSchema.ConfigVersion;
eventSchemaKM.JonMonVersion = eventSchema.JonMonVersion;
}
if (VariantString == L"-i") {
//Copying resource file to C:\Windows and installing manifest
printf("[*] Starting JonMon Installation Process....\n");
FileCopy = CopyFileW(L"JonMon.dll", L"C:\\Windows\\JonMon.dll", FALSE);
if (FileCopy != TRUE) {
printf("[-] JonMon.dll did not copy to C:\\Windows\\JonMon.dll\n");
}
DWORD status = InstallManifest();
if (status != 0) {
printf("[-] InstallManifest Failed\n");
}
LPWSTR CurrentDirectory = new WCHAR[MAX_PATH];
FileCopy = CopyFileW(L"JonMon.sys", L"C:\\Windows\\JonMon.sys", FALSE);
if (FileCopy != TRUE) {
printf("[-] JonMon.sys did not copy to C:\\Windows\\JonMon.sys\n");
}
FileCopy = CopyFileW(L"JonMon-Service.exe", L"C:\\Windows\\JonMon-Service.exe", FALSE);
if (FileCopy != TRUE) {
printf("[-] JonMon-Service.exe did not copy to C:\\Windows\\JonMon-Service.exe\n");
}
FileCopy = CopyFileW(L".\\Extensions\\JonMon-Ext1.dll", L"C:\\Windows\\JonMon-Ext1.dll", FALSE);
if (FileCopy != TRUE) {
printf("[-] JonMon-Ext1.dlll did not copy to C:\\Windows\\JonMon-Ext1.dlll\n");
}
else {
printf("[*] JonMon-Ext1.dll copied\n");
}
printf("[*] Installing JonMonDrv Service....\n");
status = CreateCustomService(L"JonMonDrv", L"C:\\Windows\\JonMon.sys", SERVICE_KERNEL_DRIVER);
printf("[*] JonMonDrv Service Installed\n");
//
// --- Start Minifilter Settings ---
//
printf("[*] Adding Minifilter registry values....\n");
HKEY hKey;
status = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\JonMonDrv", 0, KEY_SET_VALUE, &hKey);
if (hKey == NULL || status != 0) {
printf("[-] Failed to open registry key to JonMonDrv\n");
}
DWORD value = 3;
status = RegSetKeyValueW(hKey, NULL, L"SupportedFeatures", REG_DWORD, &value, sizeof(value));
if (status != ERROR_SUCCESS) {
printf("[-] Failed to set registry value for SupportedFeatures\n");
}
RegCloseKey(hKey);
hKey = NULL;
LONG lRes = RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\JonMonDrv\\Instances", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL);
if (lRes != ERROR_SUCCESS) {
printf("[-] Failed to create registry key for Instances\n");
}
lRes = RegSetValueExW(hKey, L"DefaultInstance", 0, REG_SZ, (const BYTE*)L"JonMon Instance", sizeof(L"JonMon Instance"));
if (lRes != ERROR_SUCCESS) {
printf("[-] Failed to set registry value for DefaultInstance\n");
}
RegCloseKey(hKey);
hKey = NULL;
lRes = RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\JonMonDrv\\Instances\\JonMon Instance", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL);
if (lRes != ERROR_SUCCESS) {
printf("[-] Failed to create registry key for JonMon Instance\n");
}
lRes = RegSetValueExW(hKey, L"Altitude", 0, REG_SZ, (const BYTE*)L"385202", sizeof(L"385202"));
if (lRes != ERROR_SUCCESS) {
printf("[-] Failed to set registry value for Altitude\n");
}
value = 0;
status = RegSetKeyValueW(hKey,NULL,L"Flags",REG_DWORD,&value,sizeof(value));
if (status != ERROR_SUCCESS) {
printf("[-] Failed to set registry value for Flags\n");
}
RegCloseKey(hKey);
printf("[*] Minifilter registry values added\n");
//
// --- Stop Minifilter Settings ---
//
status = CreateCustomService(L"JonMon", L"C:\\Windows\\JonMon-Service.exe -s", SERVICE_WIN32_OWN_PROCESS);
if (status != 0) {
printf("[-] InstallService Failed\n");
}
status = StartCustomService(L"JonMon");
if (status != 0) {
printf("[-] Failed to start JonMon\n");
}
EventSchema_KM eventSchemaKM = { 0 };
eventSchemaKM.ConfigSet = eventSchema.ConfigSet;
eventSchemaKM.ProcessCreation = eventSchema.ProcessCreation_Events;
eventSchemaKM.ProcessTermination = eventSchema.ProcessTermination_Events;
eventSchemaKM.ProcessHandleCreation = eventSchema.ProcessHandleCreation_Events;
eventSchemaKM.ProcessHandleDuplication = eventSchema.ProcessHandleDuplication_Events;
eventSchemaKM.RemoteThreadCreation = eventSchema.RemoteThreadCreation_Events;
eventSchemaKM.ImageLoad = eventSchema.ImageLoad_Events;
eventSchemaKM.File = eventSchema.File_Events;
eventSchemaKM.Registry = eventSchema.Registry_Events;
eventSchemaKM.ConfigVersion = eventSchema.ConfigVersion;
eventSchemaKM.JonMonVersion = eventSchema.JonMonVersion;
HANDLE hDevice = CreateFile(L"\\\\.\\JonMon", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if (hDevice == INVALID_HANDLE_VALUE) {
printf("Error %u\n", GetLastError());
goto Exit;
}
DeviceIoControl(hDevice, IOCTL_EVENT_CONFIGURATION, &eventSchemaKM, sizeof(eventSchemaKM), NULL, 0, NULL, NULL);
CloseHandle(hDevice);
}
if (VariantString == L"-s") {
DWORD status = StartCustomService(L"JonMonDrv");
if (status != 0) {
printf("[-] Failed to start JonMonDrv\n");
}
//Starting service for JonMon-Service.exe
SERVICE_TABLE_ENTRYW serviceTable[] =
{
{ const_cast <LPWSTR>(L""), (LPSERVICE_MAIN_FUNCTIONW)ServiceMain }
};
if (!StartServiceCtrlDispatcherW(serviceTable))
{
// Failed to start service control dispatcher
return GetLastError();
}
}
if (VariantString == L"-u") {
printf("[*] Starting JonMon Uninstallation Process....\n");
DWORD status = StopCustomService(L"JonMonDrv");
if (status != 0) {
printf("[-] Failed to stop JonMonDrv\n");
}
status = DeleteCustomService(L"JonMonDrv");
if (status != 0) {
printf("[-] Failed to delete JonMonDrv\n");
}
status = StopCustomService(L"JonMon");
if (status != 0) {
printf("[-] Failed to stop JonMon\n");
}
status = DeleteCustomService(L"JonMon");
if (status != 0) {
printf("[-] Failed to delete JonMon\n");
}
printf("[*] Deregestering JonMon Provider\n");
status = StopETWTrace();
printf("[*] Removing Files....\n");
DeleteFileW(L"C:\\Windows\\JonMon.sys");
DeleteFileW(L"C:\\Windows\\JonMon-Service.exe");
DeleteFileW(L"C:\\Windows\\JonMon-Ext1.dll");
DeleteFileW(L"C:\\Windows\\JonMon.dll");
DeleteFileW(L"C:\\Windows\\JonMonConfig.json");
printf("[*] JonMon Uninstallation Complete\n");
}
if (VariantString == L"-h") {
printf("Usage: 'JonMon-Service.exe -etw' will start an ETW trace called JonMon to collect events from various providers\n");
printf("Usage: 'JonMon-Service.exe -i' will install the JonMon Services and Driver\n");
printf("Usage: 'JonMon-Service.exe -s' will start the JonMon Services and Driver\n");
printf("Usage: 'JonMon-Service.exe -u' will stop/uninstall all the JonMon Services\n");
printf("Usage: 'JonMon-Service.exe -c' will read the configuration file\n");
}
Exit:
return 0;
}
================================================
FILE: JonMon-Service/config.cpp
================================================
#include "config.h"
#include <iostream>
#include <fstream>
#include "nlohmann/json.hpp"
using json = nlohmann::json;
int ConfigFile(
_In_ std::wstring ConfigFile,
_Out_ EventSchema_Full* EventSchemaStruct
)
{
//
// Initialize the EventSchema structure
//
EventSchemaStruct->ConfigSet = true;
EventSchemaStruct->ProcessCreation_Events = false;
EventSchemaStruct->ProcessTermination_Events = false;
EventSchemaStruct->File_Events = false;
EventSchemaStruct->Registry_Events = false;
EventSchemaStruct->ProcessHandleCreation_Events = false;
EventSchemaStruct->ProcessHandleDuplication_Events = false;
EventSchemaStruct->RemoteThreadCreation_Events = false;
EventSchemaStruct->ImageLoad_Events = false;
EventSchemaStruct->RPC_Events = false;
EventSchemaStruct->Network_Events = false;
EventSchemaStruct->DotNetLoad_Events = false;
EventSchemaStruct->AMSI_Events = false;
EventSchemaStruct->SchedTask_Events = false;
EventSchemaStruct->WMIEventSubscription_Events = false;
EventSchemaStruct->CryptUnprotect_Events = false;
EventSchemaStruct->ThreatIntelligence_Events = false;
EventSchemaStruct->ThreatIntelligence_Events_RemoteReadProcessMemory = false;
EventSchemaStruct->ThreatIntelligence_Events_RemoteWriteProcessMemory = false;
EventSchemaStruct->ThreatIntelligence_Events_RemoteVirtualAllocation = false;
EventSchemaStruct->ThreatIntelligence_Events_RemoteQueueUserAPC = false;
EventSchemaStruct->TokenImpersonation_Events = false;
EventSchemaStruct->ConfigVersion = 0;
EventSchemaStruct->JonMonVersion = 0;
//
// Open the JSON configuration file
//
std::ifstream jsonFile(ConfigFile);
if (!jsonFile.is_open()) {
std::wcerr << "Failed to open file: " << ConfigFile << std::endl;
return 1;
}
json jsonData;
jsonFile >> jsonData;
if (jsonData.contains("ConfigVersion")) {
std::string ConfigVersion = jsonData["ConfigVersion"];
EventSchemaStruct->ConfigVersion = std::stoi(ConfigVersion);
}
if (jsonData.contains("JonMonVersion")) {
std::string JonMonVersion = jsonData["JonMonVersion"];
EventSchemaStruct->JonMonVersion = std::stoi(JonMonVersion);
}
if (jsonData.contains("ProcessCreation_Events")) {
EventSchemaStruct->ProcessCreation_Events = jsonData["ProcessCreation_Events"];
}
if (jsonData.contains("File_Events")) {
EventSchemaStruct->File_Events = jsonData["File_Events"];
}
if (jsonData.contains("Registry_Events")) {
EventSchemaStruct->Registry_Events = jsonData["Registry_Events"];
}
if (jsonData.contains("ProcessTermination_Events")) {
EventSchemaStruct->ProcessTermination_Events = jsonData["ProcessTermination_Events"];
}
if (jsonData.contains("ProcessHandleCreation_Events")) {
EventSchemaStruct->ProcessHandleCreation_Events = jsonData["ProcessHandleCreation_Events"];
}
if (jsonData.contains("ProcessHandleDuplication_Events")) {
EventSchemaStruct->ProcessHandleDuplication_Events = jsonData["ProcessHandleDuplication_Events"];
}
if (jsonData.contains("RemoteThreadCreation_Events")) {
EventSchemaStruct->RemoteThreadCreation_Events = jsonData["RemoteThreadCreation_Events"];
}
if (jsonData.contains("ImageLoad_Events")) {
EventSchemaStruct->ImageLoad_Events = jsonData["ImageLoad_Events"];
}
if(jsonData.contains("RPC_Events")) {
EventSchemaStruct->RPC_Events = jsonData["RPC_Events"];
}
if(jsonData.contains("Network_Events")) {
EventSchemaStruct->Network_Events = jsonData["Network_Events"];
}
if(jsonData.contains("DotNetLoad_Events")) {
EventSchemaStruct->DotNetLoad_Events = jsonData["DotNetLoad_Events"];
}
if(jsonData.contains("AMSI_Events")) {
EventSchemaStruct->AMSI_Events = jsonData["AMSI_Events"];
}
if(jsonData.contains("SchedTask_Events")) {
EventSchemaStruct->SchedTask_Events = jsonData["SchedTask_Events"];
}
if (jsonData.contains("WMIEventSubscription_Events")) {
EventSchemaStruct->WMIEventSubscription_Events = jsonData["WMIEventSubscription_Events"];
}
if (jsonData.contains("CryptUnprotect_Events")) {
EventSchemaStruct->CryptUnprotect_Events = jsonData["CryptUnprotect_Events"];
}
if (jsonData.contains("ThreatIntelligence_Events")) {
EventSchemaStruct->ThreatIntelligence_Events_RemoteReadProcessMemory = jsonData["ThreatIntelligence_Events"]["RemoteReadProcessMemory"];
EventSchemaStruct->ThreatIntelligence_Events_RemoteWriteProcessMemory = jsonData["ThreatIntelligence_Events"]["RemoteWriteProcessMemory"];
EventSchemaStruct->ThreatIntelligence_Events_RemoteVirtualAllocation = jsonData["ThreatIntelligence_Events"]["RemoteVirtualAllocation"];
EventSchemaStruct->ThreatIntelligence_Events_RemoteQueueUserAPC = jsonData["ThreatIntelligence_Events"]["RemoteQueueUserAPC"];
if (EventSchemaStruct->ThreatIntelligence_Events_RemoteReadProcessMemory || EventSchemaStruct->ThreatIntelligence_Events_RemoteWriteProcessMemory || EventSchemaStruct->ThreatIntelligence_Events_RemoteVirtualAllocation || EventSchemaStruct->ThreatIntelligence_Events_RemoteQueueUserAPC) {
EventSchemaStruct->ThreatIntelligence_Events = true;
}
}
if (jsonData.contains("TokenImpersonation_Events")) {
EventSchemaStruct->TokenImpersonation_Events = jsonData["TokenImpersonation_Events"];
}
return 0;
}
================================================
FILE: JonMon-Service/config.h
================================================
#pragma once
#include <string>
struct EventSchema_KM {
bool ConfigSet;
bool ProcessCreation;
bool ProcessTermination;
bool ProcessHandleCreation;
bool ProcessHandleDuplication;
bool RemoteThreadCreation;
bool ImageLoad;
bool File;
bool Registry;
int ConfigVersion;
int JonMonVersion;
};
struct EventSchema_Full {
bool ConfigSet;
bool ProcessCreation_Events; // KM Event
bool ProcessTermination_Events; // KM Event
bool ProcessHandleCreation_Events; // KM Event
bool ProcessHandleDuplication_Events; // KM Event
bool RemoteThreadCreation_Events; // KM Event
bool ImageLoad_Events; // KM Event
bool File_Events; // KM Event
bool Registry_Events; // KM Event
bool RPC_Events; // UM Event
bool Network_Events; // UM Event
bool DotNetLoad_Events; // UM Event
bool AMSI_Events; // UM Event
bool SchedTask_Events; // UM Event
bool WMIEventSubscription_Events; // UM Event
bool CryptUnprotect_Events; // UM Event
bool ThreatIntelligence_Events; // UM Event
bool ThreatIntelligence_Events_RemoteReadProcessMemory; // UM Event
bool ThreatIntelligence_Events_RemoteWriteProcessMemory; // UM Event
bool ThreatIntelligence_Events_RemoteVirtualAllocation; // UM Event
bool ThreatIntelligence_Events_RemoteQueueUserAPC; // UM Event
bool TokenImpersonation_Events; // UM Event
int ConfigVersion;
int JonMonVersion;
};
int ConfigFile(
_In_ std::wstring ConfigFile,
_Out_ EventSchema_Full* EventSchemaStruct
);
================================================
FILE: JonMon-Service/context.cpp
================================================
#include <Windows.h>
#include <psapi.h>
#include "context.h"
#include <sstream>
#include <vector>
#include <mutex>
#include <psapi.h>
std::vector<ProcessInformation> processList;
std::vector<ProcessInformation> initialProcessList;
//
// Mutexes to protect access to the process lists
//
std::mutex processListMutex; // Mutex to protect access to processList
std::mutex initialProcessListMutex; // Mutex to protect access to initialProcessList
//
// Function to enumerate initial processes running on the system and store them in the initialProcessList
//
void InitialProcesses()
{
PTokenInformation tokenInformation = NULL;
PProcessInformation processInformation = NULL;
HANDLE hProcessSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnapshot == INVALID_HANDLE_VALUE) {
return;
}
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(PROCESSENTRY32);
// Retrieve information about the first process
if (!Process32First(hProcessSnapshot, &pe32)) {
goto Exit;
}
// Loop through the processes in the snapshot
do {
// Get the process ID
DWORD processID = pe32.th32ProcessID;
//
// if PID 4 is found, skip it
//
if (processID == 4)
{
continue;
}
WCHAR processName[MAX_PATH] = L"<unknown>";
// Open the process to get its full path
HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, processID);
if (hProcess != NULL) {
//
// Get token information
//
PTokenInformation tokenInformation = new TokenInformation();
if (tokenInformation == NULL) {
std::wcout << L"Error allocating memory for token information\n";
continue;
}
DWORD status = GetUserInformation(processID, tokenInformation);
if (status != 0) {
std::wcout << L"GetUserInformation failed: " << status << std::endl;
continue;
}
PProcessInformation processInformation = new ProcessInformation();
if (processInformation == NULL) {
std::wcout << L"Error allocating memory for process information\n";
continue;
}
processInformation->processId = processID;
processInformation->authenticationId = tokenInformation->authenticationId;
processInformation->integrityLevel = tokenInformation->integrityLevel;
processInformation->sessionId = tokenInformation->sessionId;
processInformation->tokenType = tokenInformation->tokenType;
processInformation->userName = tokenInformation->userName;
processInformation->linkedAuthenticationId = tokenInformation->linkedAuthenticationId;
// Get the full process image file name
DWORD size = MAX_PATH; // This should be set to the size of the buffer
// Get the full process image file name
if (QueryFullProcessImageName(hProcess, PROCESS_NAME_NATIVE, processName, &size)) {
processInformation->processName = processName;
std::lock_guard<std::mutex> lock(initialProcessListMutex);
initialProcessList.push_back(*processInformation);
}
CloseHandle(hProcess); // Close handle to process
}
} while (Process32Next(hProcessSnapshot, &pe32)); // Continue with the next process
// Clean up the snapshot object
Exit:
if (hProcessSnapshot != NULL)
{
CloseHandle(hProcessSnapshot);
}
if (tokenInformation != NULL)
{
delete(tokenInformation);
}
if (processInformation != NULL)
{
delete(processInformation);
}
return;
}
DWORD GetUserInformation(
_In_ DWORD processId,
_In_ PTokenInformation tokenInformation
)
{
DWORD status = 0;
HANDLE hToken = NULL;
HANDLE hProcess = NULL;
DWORD dwLengthNeeded;
PTOKEN_LINKED_TOKEN pTokenLinkedToken = NULL;
hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, processId);
if (hProcess == NULL)
{
std::wcout << L"OpenProcess failed: " << GetLastError() << std::endl;
return 1;
}
if (!OpenProcessToken(hProcess, TOKEN_QUERY, &hToken))
{
std::wcout << L"OpenProcessToken failed: " << GetLastError() << std::endl;
CloseHandle(hProcess);
return 1;
}
status = GetTokenUserInfo(hToken, tokenInformation->userName);
if (status != 0)
{
std::wcout << L"GetTokenUserInfo failed: " << status << std::endl;
goto Exit;
}
// Get Token Type
dwLengthNeeded = 0;
if (!GetTokenInformation(hToken, TokenType, &tokenInformation->tokenType, sizeof(DWORD), &dwLengthNeeded))
{
status = GetLastError();
std::wcout << L"GetTokenInformation (TokenType) failed: " << status << std::endl;
goto Exit;
}
// Get Authentication ID
status = GetAuthenticationId(hToken, &tokenInformation->authenticationId);
if (status != 0)
{
std::wcout << L"GetAuthenticationId failed: " << status << std::endl;
goto Exit;
}
// Get Session ID
dwLengthNeeded = 0;
if (!GetTokenInformation(hToken, TokenSessionId, &tokenInformation->sessionId, sizeof(DWORD), &dwLengthNeeded))
{
status = GetLastError();
std::wcout << L"GetTokenInformation (SessionId) failed: " << status << std::endl;
goto Exit;
}
// Get Linked Authentication ID
pTokenLinkedToken = (PTOKEN_LINKED_TOKEN)LocalAlloc(LPTR, sizeof(TOKEN_LINKED_TOKEN));
if (pTokenLinkedToken == NULL)
{
status = GetLastError();
std::wcout << L"LocalAlloc for pTokenLinkedToken failed: " << status << std::endl;
goto Exit;
}
if (!GetTokenInformation(hToken, TokenLinkedToken, pTokenLinkedToken, sizeof(TOKEN_LINKED_TOKEN), &dwLengthNeeded))
{
status = GetLastError();
if (status == ERROR_NO_SUCH_LOGON_SESSION)
{
tokenInformation->linkedAuthenticationId.LowPart = 0;
tokenInformation->linkedAuthenticationId.HighPart = 0;
}
else
{
std::wcout << L"GetTokenInformation (LinkedToken) failed: " << status << std::endl;
goto Exit;
}
}
else if (pTokenLinkedToken->LinkedToken != NULL)
{
status = GetAuthenticationId(pTokenLinkedToken->LinkedToken, &tokenInformation->linkedAuthenticationId);
if (status != 0)
{
std::wcout << L"GetAuthenticationId (LinkedToken) failed: " << status << std::endl;
goto Exit;
}
}
else
{
tokenInformation->linkedAuthenticationId.LowPart = 0;
tokenInformation->linkedAuthenticationId.HighPart = 0;
}
// Get Integrity Level
status = GetMandatoryLabel(hToken, tokenInformation->integrityLevel);
if (status != 0)
{
std::wcout << L"GetMandatoryLabel failed: " << status << std::endl;
goto Exit;
}
Exit:
if (pTokenLinkedToken != NULL)
{
if (pTokenLinkedToken->LinkedToken != NULL)
{
CloseHandle(pTokenLinkedToken->LinkedToken);
}
LocalFree(pTokenLinkedToken);
}
if (hToken != NULL)
{
CloseHandle(hToken);
}
if (hProcess != NULL)
{
CloseHandle(hProcess);
}
return status;
}
//
// Query the process list to get the process name of a given process id
//
PProcessInformation GetProcessName(
_In_ DWORD processId) {
{
std::lock_guard<std::mutex> lock(initialProcessListMutex);
for (auto& process : initialProcessList) {
if (process.processId == processId) {
return &process;
}
}
}
{
std::lock_guard<std::mutex> lock(processListMutex);
for (auto& process : processList) {
if (process.processId == processId) {
return &process;
}
}
}
return nullptr;
}
void ClearProcessList() {
//
// lock the process list using a mutex
//
std::lock_guard<std::mutex> lock(processListMutex); // Locks the mutex
//
// Clear the existing processList3 to avoid duplication
//
processList.clear();
}
void GetProcessList() {
// Take a snapshot of all processes in the system
PTokenInformation tokenInformation = NULL;
PProcessInformation processInformation = NULL;
HANDLE hProcessSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnapshot == INVALID_HANDLE_VALUE) {
return;
}
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(PROCESSENTRY32);
// Retrieve information about the first process
if (!Process32First(hProcessSnapshot, &pe32)) {
goto Exit;
}
// Loop through the processes in the snapshot
do {
DWORD processID = pe32.th32ProcessID;
if (processID == 4) // Skip PID 4
continue;
// Check if process already exists in initialProcessList or processList
bool exists = false;
for (const auto& process : initialProcessList) {
if (process.processId == processID) {
exists = true;
break;
}
}
if (exists)
{
continue;
}
for (const auto& process : processList) {
if (process.processId == processID) {
exists = true;
break;
}
}
if (exists)
{
continue;
}
WCHAR processName[MAX_PATH] = L"<unknown>";
HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, processID);
if (hProcess != NULL) {
// Allocate token information
tokenInformation = new TokenInformation();
if (tokenInformation == NULL) {
std::wcout << L"Error allocating memory for token information\n";
CloseHandle(hProcess);
continue;
}
DWORD status = GetUserInformation(processID, tokenInformation);
if (status != 0) {
std::wcout << L"GetUserInformation failed: " << status << std::endl;
delete tokenInformation;
tokenInformation = nullptr;
CloseHandle(hProcess);
continue;
}
// Allocate process information
processInformation = new ProcessInformation();
if (processInformation == NULL) {
std::wcout << L"Error allocating memory for process information\n";
delete tokenInformation;
tokenInformation = nullptr;
CloseHandle(hProcess);
continue;
}
// Populate processInformation
processInformation->processId = processID;
processInformation->authenticationId = tokenInformation->authenticationId;
processInformation->integrityLevel = tokenInformation->integrityLevel;
processInformation->sessionId = tokenInformation->sessionId;
processInformation->tokenType = tokenInformation->tokenType;
processInformation->userName = tokenInformation->userName;
processInformation->linkedAuthenticationId = tokenInformation->linkedAuthenticationId;
// Get the process name
DWORD size = MAX_PATH;
if (QueryFullProcessImageName(hProcess, PROCESS_NAME_NATIVE, processName, &size)) {
processInformation->processName = processName;
std::lock_guard<std::mutex> lock(processListMutex);
processList.push_back(*processInformation);
}
// Free allocated memory for this iteration
delete tokenInformation;
delete processInformation;
tokenInformation = nullptr;
processInformation = nullptr;
CloseHandle(hProcess); // Close handle to process
}
} while (Process32Next(hProcessSnapshot, &pe32)); // Continue with the next process
// Clean up and exit
Exit:
if (hProcessSnapshot != NULL) {
CloseHandle(hProcessSnapshot);
}
}
//
// Function to periodically update the process list every second
//
void UpdateProcessListPeriodically() {
while (true) {
GetProcessList();
std::this_thread::sleep_for(std::chrono::milliseconds(100)); // trying to be fast because of sacraficial processes
}
}
void ClearListPeriodically() {
while (true) {
ClearProcessList();
//
// Pause for 5 seconds to allow the process list to be updated
//
std::this_thread::sleep_for(std::chrono::seconds(5));
}
}
DWORD GetTokenUserInfo(
_In_ HANDLE hToken,
_In_ std::wstring& fullUserName
)
{
PTOKEN_USER pTokenUser = NULL;
DWORD status = 0;
DWORD dwLengthNeeded = 0;
DWORD dwSizeName;
DWORD dwSizeDomain;
WCHAR szName[256];
WCHAR szDomain[256];
WCHAR userName[514];
SID_NAME_USE eUse;
if (!GetTokenInformation(hToken, TokenUser, NULL, 0, &dwLengthNeeded))
{
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
{
std::wcout << L"GetTokenInformation failed: " << GetLastError() << std::endl;
status = GetLastError();
goto Exit;
}
}
pTokenUser = (PTOKEN_USER)LocalAlloc(LPTR, dwLengthNeeded);
if (pTokenUser == NULL)
{
std::wcout << L"LocalAlloc failed: " << GetLastError() << std::endl;
status = GetLastError();
goto Exit;
}
if (!GetTokenInformation(hToken, TokenUser, pTokenUser, dwLengthNeeded, &dwLengthNeeded))
{
std::wcout << L"GetTokenInformation failed: " << GetLastError() << std::endl;
status = GetLastError();
goto Exit;
}
dwSizeName = 256;
dwSizeDomain = 256;
if (!LookupAccountSid(NULL, pTokenUser->User.Sid, szName, &dwSizeName, szDomain, &dwSizeDomain, &eUse))
{
std::wcout << L"LookupAccountSid failed: " << GetLastError() << std::endl;
status = GetLastError();
goto Exit;
}
//
// Combine the domain and user name
//
wcscpy_s(userName, szDomain);
wcscat_s(userName, L"\\");
wcscat_s(userName, szName);
userName[513] = L'\0';
fullUserName.assign(userName);
Exit:
if (pTokenUser != NULL)
{
LocalFree(pTokenUser);
}
return status;
}
DWORD GetAuthenticationId(
_In_ HANDLE hToken,
_In_ PLUID authId
)
{
DWORD status = 0;
DWORD dwLengthNeeded = 0;
PTOKEN_STATISTICS pTokenStatistics = NULL;
*authId = { 0 };
if (!GetTokenInformation(hToken, TokenStatistics, NULL, 0, &dwLengthNeeded))
{
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
{
std::wcout << L"GetTokenInformation failed: " << GetLastError() << std::endl;
status = GetLastError();
goto Exit;
}
}
pTokenStatistics = (PTOKEN_STATISTICS)LocalAlloc(LPTR, dwLengthNeeded);
if (pTokenStatistics == NULL)
{
std::wcout << L"LocalAlloc failed: " << GetLastError() << std::endl;
status = GetLastError();
goto Exit;
}
if (!GetTokenInformation(hToken, TokenStatistics, pTokenStatistics, dwLengthNeeded, &dwLengthNeeded))
{
status = GetLastError();
if (status != ERROR_NO_SUCH_LOGON_SESSION)
{
std::wcout << L"GetTokenInformation failed: " << status << std::endl;
}
goto Exit;
}
// Successfully retrieved token statistics; assign AuthenticationId
*authId = pTokenStatistics->AuthenticationId;
Exit:
if (pTokenStatistics != NULL)
{
LocalFree(pTokenStatistics);
}
return status;
}
DWORD GetMandatoryLabel(
_In_ HANDLE hToken,
_In_ std::wstring& integrityLevel
)
{
DWORD status = 0;
DWORD dwLengthNeeded = 0;
PTOKEN_MANDATORY_LABEL pTokenMandatoryLabel = NULL;
DWORD dwIntegrityLevel = 0;
WCHAR szIntegrityLevel[1024] = L"Unknown"; // Default value for unknown levels
if (!GetTokenInformation(hToken, TokenIntegrityLevel, NULL, 0, &dwLengthNeeded))
{
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
{
std::wcout << L"GetTokenInformation failed: " << GetLastError() << std::endl;
status = GetLastError();
goto Exit;
}
}
pTokenMandatoryLabel = (PTOKEN_MANDATORY_LABEL)LocalAlloc(LPTR, dwLengthNeeded);
if (pTokenMandatoryLabel == NULL)
{
std::wcout << L"LocalAlloc failed: " << GetLastError() << std::endl;
status = GetLastError();
goto Exit;
}
if (!GetTokenInformation(hToken, TokenIntegrityLevel, pTokenMandatoryLabel, dwLengthNeeded, &dwLengthNeeded))
{
std::wcout << L"GetTokenInformation failed: " << GetLastError() << std::endl;
status = GetLastError();
goto Exit;
}
// Get integrity level RID from SID
dwIntegrityLevel = *GetSidSubAuthority(pTokenMandatoryLabel->Label.Sid, 0);
// Determine integrity level description
if (dwIntegrityLevel == SECURITY_MANDATORY_LOW_RID)
{
wcscpy_s(szIntegrityLevel, L"Low");
}
else if (dwIntegrityLevel == SECURITY_MANDATORY_MEDIUM_RID)
{
wcscpy_s(szIntegrityLevel, L"Medium");
}
else if (dwIntegrityLevel == SECURITY_MANDATORY_HIGH_RID)
{
wcscpy_s(szIntegrityLevel, L"High");
}
else if (dwIntegrityLevel == SECURITY_MANDATORY_SYSTEM_RID)
{
wcscpy_s(szIntegrityLevel, L"System");
}
// Assign the integrity level to the output parameter
integrityLevel.assign(szIntegrityLevel);
Exit:
if (pTokenMandatoryLabel != NULL)
{
LocalFree(pTokenMandatoryLabel);
}
return status;
}
================================================
FILE: JonMon-Service/context.h
================================================
#pragma once
#include <evntcons.h>
#include "tlhelp32.h"
#include <iostream>
#include <vector>
#pragma comment(lib, "tdh.lib")
typedef struct _TokenInformation {
std::wstring userName;
DWORD tokenType;
LUID authenticationId;
LUID linkedAuthenticationId;
std::wstring integrityLevel;
DWORD sessionId;
} TokenInformation, * PTokenInformation;
typedef struct _ProcessInformation {
DWORD processId;
std::wstring processName;
std::wstring userName;
DWORD tokenType;
LUID authenticationId;
LUID linkedAuthenticationId;
std::wstring integrityLevel;
DWORD sessionId;
} ProcessInformation, * PProcessInformation;
//
// global variables that hold process ids and process names of every process currently running
//
extern std::vector<ProcessInformation> processList;
extern std::vector<ProcessInformation> initialProcessList;
DWORD GetUserInformation(
_In_ DWORD processId,
_In_ PTokenInformation tokenInformation
);
DWORD GetMandatoryLabel(
_In_ HANDLE hToken,
_In_ std::wstring& integrityLevel
);
DWORD GetAuthenticationId(
_In_ HANDLE hToken,
_In_ PLUID authId
);
DWORD GetTokenUserInfo(
_In_ HANDLE hToken,
_In_ std::wstring& fullUserName
);
void UpdateProcessListPeriodically();
void ClearListPeriodically();
PProcessInformation GetProcessName(
_In_ DWORD processId
);
void InitialProcesses();
================================================
FILE: JonMon-Service/etwMain.cpp
================================================
#include <ws2tcpip.h>
#include <Windows.h>
#include <sstream>
#include <vector>
#include <stdio.h>
#include <DbgHelp.h>
#include <thread>
#include <mutex>
#include <algorithm>
#include <regex>
#include "global.h"
#include "context.h"
#include "etwMain.h"
#include "service.h"
#pragma comment(lib, "Ws2_32.lib")
#pragma comment(lib, "dbghelp.lib")
DWORD lsassPID = 0;
SYSTEMTIME lastEventTime;
DWORD StopETWTrace() {
TRACEHANDLE traceHandle = 0;
ULONG status, bufferSize;
wchar_t traceName[] = L"JonMon";
EVENT_TRACE_PROPERTIES* traceProp;
bufferSize = sizeof(EVENT_TRACE_PROPERTIES) + sizeof(traceName) + sizeof(WCHAR);
traceProp = (EVENT_TRACE_PROPERTIES*)LocalAlloc(LPTR, bufferSize);
traceProp->Wnode.BufferSize = bufferSize;
traceProp->Wnode.Guid = JonMonGuid;
traceProp->LogFileNameOffset = 0;
traceProp->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
status = StopTrace(traceHandle, traceName, traceProp);
if (status != ERROR_SUCCESS) {
OutputDebugStringW(L"StopTrace Failed");
return status;
}
else {
OutputDebugStringW(L"StopTrace Success");
return status;
}
return 0;
}
DWORD CheckLSASSPID() {
//
// Enumerate initialProcessList to find the LSASS PID
//
Sleep(2000);
for (auto& process : initialProcessList) {
//
// print out each process id and process name
//
std::wstring lsassSubstring = L"lsass.exe";
if (process.processName.find(lsassSubstring) != std::wstring::npos) {
return process.processId;
}
}
}
DWORD TraceEvent(
_In_ LPCWSTR Name,
_In_ GUID TraceGuid,
_In_ EventSchema_Full* EventSchemaStruct
) {
std::thread initialProcesses(InitialProcesses);
std::thread updateThread(UpdateProcessListPeriodically);
std::thread clearThread(ClearListPeriodically);
//
// Detach threads
//
initialProcesses.detach();
updateThread.detach();
clearThread.detach();
printf("[+] Starting ETW Trace\n");
TRACEHANDLE hTrace = 0;
ULONG result, bufferSize;
EVENT_TRACE_LOGFILEW trace;
EVENT_TRACE_PROPERTIES* traceProp = nullptr;
lsassPID = CheckLSASSPID();
memset(&trace, 0, sizeof(EVENT_TRACE_LOGFILEW));
trace.ProcessTraceMode = PROCESS_TRACE_MODE_REAL_TIME | PROCESS_TRACE_MODE_EVENT_RECORD;
trace.LoggerName = (LPWSTR)Name;
trace.EventRecordCallback = (PEVENT_RECORD_CALLBACK)ProcessEvent;
//
// Calculate buffer size
//
ULONG nameLength = (ULONG)(wcslen(Name) + 1);
bufferSize = sizeof(EVENT_TRACE_PROPERTIES) + nameLength * sizeof(WCHAR);
//
// Allocate memory for EVENT_TRACE_PROPERTIES and logger name
//
traceProp = (EVENT_TRACE_PROPERTIES*)LocalAlloc(LPTR, bufferSize);
if (traceProp == nullptr) {
printf("Failed to allocate memory for trace properties\n");
return ERROR_OUTOFMEMORY;
}
//
// Initialize EVENT_TRACE_PROPERTIES
//
traceProp->Wnode.BufferSize = bufferSize;
traceProp->Wnode.ClientContext = 2;
traceProp->Wnode.Guid = TraceGuid;
traceProp->Wnode.Flags = WNODE_FLAG_TRACED_GUID;
traceProp->LogFileMode = EVENT_TRACE_REAL_TIME_MODE | EVENT_TRACE_SYSTEM_LOGGER_MODE;
traceProp->LogFileNameOffset = 0;
traceProp->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
//
// Set logger name
//
LPWSTR loggerNamePtr = (LPWSTR)((BYTE*)traceProp + traceProp->LoggerNameOffset);
wcscpy(loggerNamePtr, Name);
//
// Start the trace
//
if ((result = StartTraceW(&hTrace, Name, traceProp)) != ERROR_SUCCESS) {
OutputDebugStringW(L"Error starting trace\n");
LocalFree(traceProp);
return result;
}
//
// Set up and enable trace parameters
//
ENABLE_TRACE_PARAMETERS enableTraceParameters;
ZeroMemory(&enableTraceParameters, sizeof(ENABLE_TRACE_PARAMETERS));
enableTraceParameters.Version = ENABLE_TRACE_PARAMETERS_VERSION_2;
enableTraceParameters.EnableProperty = EVENT_ENABLE_PROPERTY_STACK_TRACE;
printf("[+] JonMon Trace started\n");
if ((result = EnableTraceEx2(
hTrace,
&JonMonTraceLogging,
EVENT_CONTROL_CODE_ENABLE_PROVIDER,
TRACE_LEVEL_VERBOSE,
0,
0,
0,
0
)) != ERROR_SUCCESS) {
OutputDebugStringW(L"Error enabling trace\n");
printf("Error: %lu\n", result);
LocalFree(traceProp); // Ensure traceProp is freed
CloseTrace(hTrace); // Ensure hTrace is closed
return result;
}
//
//DotNet Events
//
if (EventSchemaStruct->DotNetLoad_Events)
{
if ((result = EnableTraceEx2(
hTrace,
&DotNet_Provider,
EVENT_CONTROL_CODE_ENABLE_PROVIDER,
TRACE_LEVEL_INFORMATION,
0x8,
0,
0,
NULL
)) != ERROR_SUCCESS) {
OutputDebugString(L"[!] Error EnableTraceEx - DotNet\n");
}
}
//
// WMI Events
//
if (EventSchemaStruct->WMIEventSubscription_Events)
{
if ((result = EnableTraceEx2(
hTrace,
&WMIActivty_Provider,
EVENT_CONTROL_CODE_ENABLE_PROVIDER,
TRACE_LEVEL_INFORMATION,
0,
0,
0,
&enableTraceParameters
)) != ERROR_SUCCESS) {
OutputDebugString(L"[!] Error EnableTraceEx - WMI\n");
}
}
//
// RPC Events
//
if (EventSchemaStruct->RPC_Events)
{
if ((result = EnableTraceEx2(
hTrace,
&RPC_Provider,
EVENT_CONTROL_CODE_ENABLE_PROVIDER,
TRACE_LEVEL_INFORMATION,
0,
0,
0,
&enableTraceParameters
)) != ERROR_SUCCESS) {
OutputDebugString(L"[!] Error EnableTraceEx - RPC\n");
}
}
//
// AMSI
//
if (EventSchemaStruct->AMSI_Events)
{
if ((result = EnableTraceEx2(
hTrace,
&AMSI_Provider,
EVENT_CONTROL_CODE_ENABLE_PROVIDER,
TRACE_LEVEL_INFORMATION,
0,
0,
0,
&enableTraceParameters
)) != ERROR_SUCCESS) {
OutputDebugString(L"[!] Error EnableTraceEx - RPC\n");
}
}
//
// Network Events
//
if (EventSchemaStruct->Network_Events)
{
if ((result = EnableTraceEx2(
hTrace,
&Network_Provider,
EVENT_CONTROL_CODE_ENABLE_PROVIDER,
TRACE_LEVEL_INFORMATION,
0,
0x10,
0,
&enableTraceParameters
)) != ERROR_SUCCESS) {
OutputDebugString(L"[!] Error EnableTraceEx - RPC\n");
}
}
//
// Threat Intellgiene Events
//
if (EventSchemaStruct->ThreatIntelligence_Events)
{
OutputDebugStringW(L"Threat Intelligence Events Enabled\n");
ULONGLONG matchAnyKeyword = 0x0;
if (EventSchemaStruct->ThreatIntelligence_Events_RemoteReadProcessMemory)
{
OutputDebugStringW(L"RemoteReadProcessMemory Enabled\n");
matchAnyKeyword |= 0x20000;
}
if (EventSchemaStruct->ThreatIntelligence_Events_RemoteWriteProcessMemory)
{
OutputDebugStringW(L"RemoteWriteProcessMemory Enabled\n");
matchAnyKeyword |= 0x80000;
}
if (EventSchemaStruct->ThreatIntelligence_Events_RemoteVirtualAllocation)
{
OutputDebugStringW(L"RemoteVirtualAllocation Enabled\n");
matchAnyKeyword |= (0x4 | 0x8);
}
if (EventSchemaStruct->ThreatIntelligence_Events_RemoteQueueUserAPC)
{
OutputDebugStringW(L"RemoteQueueUserAPC Enabled\n");
matchAnyKeyword |= (0x1000 | 0x2000);
}
if ((result = EnableTraceEx2(
hTrace,
&ThreatIntel_Provider,
EVENT_CONTROL_CODE_ENABLE_PROVIDER,
TRACE_LEVEL_INFORMATION,
matchAnyKeyword,
0,
0,
&enableTraceParameters
)) != ERROR_SUCCESS) {
OutputDebugString(L"[!] Error EnableTraceEx - ThreatIntelligence\n");
}
}
//
// Free traceProp after trace is successfully started
//
LocalFree(traceProp);
hTrace = OpenTraceW(&trace);
if (hTrace == INVALID_PROCESSTRACE_HANDLE) {
OutputDebugString(L"[!] Error OpenTrace\n");
return 1;
}
//
// Process the trace
//
result = ProcessTrace(&hTrace, 1, NULL, NULL);
if (result != ERROR_SUCCESS) {
printf("[!] Error ProcessTrace\n");
CloseTrace(hTrace); // Ensure hTrace is closed
return result;
}
//
// Close trace handle after processing is complete
//
CloseTrace(hTrace);
return 0;
}
void ProcessEvent(
_In_ PEVENT_RECORD EventRecord
) {
PEVENT_HEADER eventHeader = &EventRecord->EventHeader;
PEVENT_DESCRIPTOR eventDescriptor = &eventHeader->EventDescriptor;
NTSTATUS status;
if (eventHeader->ProviderId == JonMonTraceLogging) {
status = WriteJonMonTraceLoggingEvents(EventRecord, eventHeader);
if (status != ERROR_SUCCESS) {
OutputDebugString(L"Error writing JonMon Trace Logging Events\n");
}
}
if (eventHeader->ProviderId == DotNet_Provider) {
switch (eventDescriptor->Id) {
case 154: {
status = WriteDotNetEvents(EventRecord, eventHeader);
if (status != ERROR_SUCCESS) {
OutputDebugString(L"Error writing DotNet Events\n");
}
break;
}
default: {
break;
}
}
}
if (eventHeader->ProviderId == Network_Provider)
{
status = WriteNetworkEvents(EventRecord, eventHeader);
if (status != ERROR_SUCCESS) {
OutputDebugString(L"Error writing Network Events\n");
}
}
if (eventHeader->ProviderId == DPAPI_Provider)
{
switch (eventDescriptor->Id) {
case 16385: {
status = WriteDpapiEvents(EventRecord, eventHeader);
if (status != ERROR_SUCCESS) {
OutputDebugString(L"Error writing DPAPI Events\n");
}
break;
}
default: {
break;
}
}
}
if (eventHeader->ProviderId == WMIActivty_Provider) {
switch (eventDescriptor->Id) {
case 5861:
{
status = WriteWMIEvents(EventRecord, eventHeader);
if (status != ERROR_SUCCESS) {
OutputDebugString(L"Error writing WMI Events\n");
}
break;
}
default:
{
break;
}
}
}
if (eventHeader->ProviderId == RPC_Provider) {
switch (eventDescriptor->Id) {
case 5:
{
status = WriteRpcEvents(EventRecord, eventHeader, 0); // 0 == CLIENT
if (status != ERROR_SUCCESS) {
OutputDebugString(L"Error writing RPC Events\n");
}
break;
}
case 6:
{
status = WriteRpcEvents(EventRecord, eventHeader, 1); // 1 == SERVER
if (status != ERROR_SUCCESS) {
OutputDebugString(L"Error writing RPC Events\n");
}
break;
}
default: {
break;
}
}
}
if (eventHeader->ProviderId == AMSI_Provider) {
switch (eventDescriptor->Id) {
case 1101:
{
status = WriteAMSIEvents(EventRecord, eventHeader);
if (status != ERROR_SUCCESS) {
OutputDebugString(L"Error writing AMSI Events\n");
}
break;
}
default:
{
break;
}
}
}
if (eventHeader->ProviderId == ThreatIntel_Provider) {
status = WriteThreatIntelEvents(EventRecord, eventHeader);
if (status != ERROR_SUCCESS) {
OutputDebugString(L"Error writing Threat Intelligence Events\n");
}
}
}
NTSTATUS WriteJonMonTraceLoggingEvents(
_In_ PEVENT_RECORD EventRecord,
_In_ PEVENT_HEADER EventHeader
) {
NTSTATUS status = ERROR_SUCCESS;
DWORD bufferSize = 0;
PTRACE_EVENT_INFO pInfo = nullptr;
BYTE** propertyDataVector = nullptr;
int vectorCapacity = 10;
int vectorSize = 0;
SYSTEMTIME systemTime;
// Fetch initial event information size
status = TdhGetEventInformation(EventRecord, 0, NULL, NULL, &bufferSize);
if (status == ERROR_INSUFFICIENT_BUFFER) {
pInfo = (PTRACE_EVENT_INFO)malloc(bufferSize);
if (!pInfo) {
OutputDebugString(L"Error allocating memory for event info\n");
status = ERROR_NOT_ENOUGH_MEMORY;
goto Exit;
}
status = TdhGetEventInformation(EventRecord, 0, NULL, pInfo, &bufferSize);
}
if (status != ERROR_SUCCESS) {
OutputDebugString(L"Error fetching event info\n");
goto Exit;
}
// Allocate memory for property data vector
propertyDataVector = (BYTE**)malloc(vectorCapacity * sizeof(BYTE*));
if (!propertyDataVector) {
OutputDebugString(L"Error allocating memory for propertyDataVector\n");
status = ERROR_NOT_ENOUGH_MEMORY;
goto Exit;
}
// Process each property in the event
for (ULONG i = 0; i < pInfo->TopLevelPropertyCount; i++) {
PROPERTY_DATA_DESCRIPTOR dataDescriptor;
DWORD propertySize = 0;
WCHAR* propertyName = (WCHAR*)((BYTE*)pInfo + pInfo->EventPropertyInfoArray[i].NameOffset);
dataDescriptor.PropertyName = (ULONGLONG)propertyName;
dataDescriptor.ArrayIndex = ULONG_MAX;
// Determine the size of the property
status = TdhGetPropertySize(EventRecord, 0, NULL, 1, &dataDescriptor, &propertySize);
if (status != ERROR_SUCCESS) {
wprintf(L"Error getting size for property %ls\n", propertyName);
goto Exit;
}
BYTE* propertyData = (BYTE*)malloc(propertySize);
if (!propertyData) {
wprintf(L"Error allocating memory for property %ls\n", propertyName);
goto Exit;
}
// Get the actual property data
status = TdhGetProperty(EventRecord, 0, NULL, 1, &dataDescriptor, propertySize, propertyData);
if (status != ERROR_SUCCESS) {
wprintf(L"Error getting data for property %ls\n", propertyName);
goto Exit;
}
// Check if we need to resize the vector
if (vectorSize == vectorCapacity) {
BYTE** resizedVector = (BYTE**)realloc(propertyDataVector, 2 * vectorCapacity * sizeof(BYTE*));
if (!resizedVector) {
OutputDebugString(L"Error resizing propertyDataVector\n");
free(propertyData);
status = ERROR_NOT_ENOUGH_MEMORY;
goto Exit;
}
propertyDataVector = resizedVector;
vectorCapacity *= 2;
}
// Add the data to the vector
propertyDataVector[vectorSize++] = propertyData;
}
switch (*(INT32*)propertyDataVector[0])
{
case 1:
{
BOOL ProcessReParented = FALSE;
printf("Process Creation Event\n");
PProcessCreationEvent processCreationEvent = (PProcessCreationEvent)malloc(sizeof(ProcessCreationEvent));
if (processCreationEvent == nullptr) {
OutputDebugString(L"Error allocating memory for processCreationEvent\n");
status = ERROR_NOT_ENOUGH_MEMORY;
goto Exit;
}
processCreationEvent->EventId = *(INT32*)propertyDataVector[0];
processCreationEvent->ProcessId = *(INT64*)propertyDataVector[1];
processCreationEvent->ProcessStartKey = *(UINT64*)propertyDataVector[2];
processCreationEvent->ParentProcessId = *(INT64*)propertyDataVector[3];
processCreationEvent->ParentProcessStartKey = *(UINT64*)propertyDataVector[4];
processCreationEvent->CreatorProcessId = *(INT64*)propertyDataVector[5];
processCreationEvent->CreatorThreadId = *(INT64*)propertyDataVector[6];
processCreationEvent->CommandLine = (WCHAR*)propertyDataVector[7];
processCreationEvent->EventTime = *(FILETIME*)propertyDataVector[8];
if (processCreationEvent->ParentProcessId != processCreationEvent->CreatorProcessId) {
ProcessReParented = TRUE;
}
PProcessInformation processInformation = GetProcessName(processCreationEvent->ProcessId);
// Check if processInformation is not nullptr before dereferencing it
if (processInformation == nullptr) {
printf("Process not found\n");
break;
}
PProcessInformation parentProcessInformation;
parentProcessInformation = GetProcessName(processCreationEvent->ParentProcessId);
// Check if processInformation is not nullptr before dereferencing it
if (parentProcessInformation == nullptr) {
printf("Parent Process not found\n");
break;
}
FileTimeToSystemTime(&processCreationEvent->EventTime, &systemTime);
EventWriteProcessCreation(
&systemTime,
processCreationEvent->CreatorThreadId,
processCreationEvent->CreatorProcessId,
processCreationEvent->ParentProcessId,
processCreationEvent->ParentProcessStartKey,
parentProcessInformation->processName.c_str(),
parentProcessInformation->userName.c_str(),
parentProcessInformation->authenticationId.LowPart,
parentProcessInformation->integrityLevel.c_str(),
parentProcessInformation->sessionId,
parentProcessInformation->tokenType,
processInformation->processName.c_str(),
processCreationEvent->CommandLine,
processCreationEvent->ProcessId,
processCreationEvent->ProcessStartKey,
processInformation->userName.c_str(),
processInformation->authenticationId.LowPart,
processInformation->linkedAuthenticationId.LowPart,
processInformation->integrityLevel.c_str(),
processInformation->sessionId,
processInformation->tokenType,
ProcessReParented
);
free(processCreationEvent);
break;
}
case 2:
{
printf("Process Termination Event\n");
PProcessTerminationEvent processTerminationEvent = (PProcessTerminationEvent)malloc(sizeof(ProcessTerminationEvent));
if (processTerminationEvent == nullptr) {
OutputDebugString(L"Error allocating memory for processTerminationEvent\n");
status = ERROR_NOT_ENOUGH_MEMORY;
goto Exit;
}
processTerminationEvent->EventId = *(INT32*)propertyDataVector[0];
processTerminationEvent->ProcessId = *(INT64*)propertyDataVector[1];
processTerminationEvent->ProcessStartKey = *(UINT64*)propertyDataVector[2];
processTerminationEvent->ParentProcessId = *(INT64*)propertyDataVector[3];
processTerminationEvent->ParentProcessStartKey = *(UINT64*)propertyDataVector[4];
processTerminationEvent->EventTime = *(FILETIME*)propertyDataVector[5];
PProcessInformation processInformation = GetProcessName(processTerminationEvent->ProcessId);
// Check if processInformation is not nullptr before dereferencing it
if (processInformation == nullptr) {
printf("Process not found\n");
break;
}
FileTimeToSystemTime(&processTerminationEvent->EventTime, &systemTime);
EventWriteProcessTerminate(
&systemTime,
processTerminationEvent->ParentProcessId,
processTerminationEvent->ParentProcessStartKey,
processInformation->processName.c_str(),
processTerminationEvent->ProcessId
);
free(processTerminationEvent);
break;
}
case 3:
{
printf("Remote Thread Creation Event\n");
PRemoteThreadCreationEvent remoteThreadCreationEvent = (PRemoteThreadCreationEvent)malloc(sizeof(RemoteThreadCreationEvent));
if (remoteThreadCreationEvent == nullptr) {
OutputDebugString(L"Error allocating memory for remoteThreadCreationEvent\n");
status = ERROR_NOT_ENOUGH_MEMORY;
goto Exit;
}
remoteThreadCreationEvent->EventId = *(INT32*)propertyDataVector[0];
remoteThreadCreationEvent->SourceThreadId = *(INT64*)propertyDataVector[1];
remoteThreadCreationEvent->SourceProcessId = *(INT64*)propertyDataVector[2];
remoteThreadCreationEvent->SourceProcessStartKey = *(UINT64*)propertyDataVector[3];
remoteThreadCreationEvent->NewThreadId = *(INT64*)propertyDataVector[4];
remoteThreadCreationEvent->TargetProcessId = *(INT64*)propertyDataVector[5];
remoteThreadCreationEvent->TargetProcessStartKey = *(UINT64*)propertyDataVector[6];
remoteThreadCreationEvent->EventTime = *(FILETIME*)propertyDataVector[7];
PProcessInformation processInformation = GetProcessName(remoteThreadCreationEvent->TargetProcessId);
// Check if processInformation is not nullptr before dereferencing it
if (processInformation == nullptr) {
printf("Process not found\n");
break;
}
PProcessInformation sourceProcessInformation;
sourceProcessInformation = GetProcessName(remoteThreadCreationEvent->SourceProcessId);
// Check if processInformation is not nullptr before dereferencing it
if (sourceProcessInformation == nullptr) {
printf("Source Process not found\n");
break;
}
FileTimeToSystemTime(&remoteThreadCreationEvent->EventTime, &systemTime);
EventWriteRemoteThreadCreation(
&systemTime,
remoteThreadCreationEvent->SourceProcessId,
remoteThreadCreationEvent->SourceProcessStartKey,
remoteThreadCreationEvent->SourceThreadId,
sourceProcessInformation->processName.c_str(),
sourceProcessInformation->userName.c_str(),
sourceProcessInformation->authenticationId.LowPart,
sourceProcessInformation->integrityLevel.c_str(),
sourceProcessInformation->sessionId,
sourceProcessInformation->tokenType,
processInformation->processName.c_str(),
remoteThreadCreationEvent->TargetProcessId,
remoteThreadCreationEvent->TargetProcessStartKey,
remoteThreadCreationEvent->NewThreadId,
processInformation->userName.c_str(),
processInformation->authenticationId.LowPart,
processInformation->linkedAuthenticationId.LowPart,
processInformation->integrityLevel.c_str(),
processInformation->sessionId
);
//
// Free the memory allocated for the event data
//
free(remoteThreadCreationEvent);
break;
}
case 4:
{
printf("Load Image Event\n");
PLoadImageEvent loadImageEvent = (PLoadImageEvent)malloc(sizeof(LoadImageEvent));
if (loadImageEvent == nullptr) {
OutputDebugString(L"Error allocating memory for loadImageEvent\n");
status = ERROR_NOT_ENOUGH_MEMORY;
goto Exit;
}
loadImageEvent->EventId = *(INT32*)propertyDataVector[0];
loadImageEvent->ProcessId = *(INT64*)propertyDataVector[1];
loadImageEvent->ProcessStartKey = *(UINT64*)propertyDataVector[2];
loadImageEvent->ThreadId = *(INT64*)propertyDataVector[3];
loadImageEvent->SystemModeImage = *(ULONG*)propertyDataVector[4];
loadImageEvent->ImageName = (WCHAR*)propertyDataVector[5];
loadImageEvent->EventTime = *(FILETIME*)propertyDataVector[6];
FileTimeToSystemTime(&loadImageEvent->EventTime, &systemTime);
if (loadImageEvent->SystemModeImage == 1) {
printf("System Mode Image\n");
EventWriteImageLoaded(
&systemTime,
NULL,
loadImageEvent->ProcessId,
loadImageEvent->ThreadId,
loadImageEvent->ProcessStartKey,
NULL,
0,
0,
NULL,
0,
0,
loadImageEvent->ImageName,
loadImageEvent->SystemModeImage,
);
free(loadImageEvent);
break;
}
PProcessInformation processInformation;
processInformation = GetProcessName(loadImageEvent->ProcessId);
// Check if processInformation is not nullptr before dereferencing it
if (processInformation == nullptr) {
printf("Process not found\n");
break;
}
EventWriteImageLoaded(
&systemTime,
processInformation->processName.c_str(),
loadImageEvent->ProcessId,
loadImageEvent->ThreadId,
loadImageEvent->ProcessStartKey,
processInformation->userName.c_str(),
processInformation->authenticationId.LowPart,
processInformation->linkedAuthenticationId.LowPart,
processInformation->integrityLevel.c_str(),
processInformation->sessionId,
processInformation->tokenType,
loadImageEvent->ImageName,
loadImageEvent->SystemModeImage,
);
//
// Free the memory allocated for the event data
//
free(loadImageEvent);
break;
}
case 5:
{
printf("Process Handle Event\n");
PProcessHandleEvent processHandleEvent = (PProcessHandleEvent)malloc(sizeof(ProcessHandleEvent));
if (processHandleEvent == nullptr) {
OutputDebugString(L"Error allocating memory for processHandleEvent\n");
status = ERROR_NOT_ENOUGH_MEMORY;
goto Exit;
}
processHandleEvent->EventId = *(INT32*)propertyDataVector[0];
processHandleEvent->SourceThreadId = *(INT64*)propertyDataVector[1];
processHandleEvent->SourceProcessId = *(INT64*)propertyDataVector[2];
processHandleEvent->SourceProcessStartKey = *(UINT64*)propertyDataVector[3];
processHandleEvent->TargetProcessId = *(INT64*)propertyDataVector[4];
processHandleEvent->TargetProcessStartKey = *(UINT64*)propertyDataVector[5];
processHandleEvent->OperationType = *(INT32*)propertyDataVector[6];
processHandleEvent->DesiredAccess = *(INT32*)propertyDataVector[7];
processHandleEvent->EventTime = *(FILETIME*)propertyDataVector[8];
FileTimeToSystemTime(&processHandleEvent->EventTime, &systemTime);
PProcessInformation sourceProcessInformation;
sourceProcessInformation = GetProcessName(processHandleEvent->SourceProcessId);
// Check if processInformation is not nullptr before dereferencing it
if (sourceProcessInformation == nullptr) {
printf("Source Process not found\n");
break;
}
//
// Check to see if source process contains JonMon-Service.exe
//
if (sourceProcessInformation->processName.find(L"Windows\\JonMon-Service.exe") != std::string::npos) {
printf("Exiting because JonMon-Service is the source process\n");
break;
}
PProcessInformation targetProcessInformation;
targetProcessInformation = GetProcessName(processHandleEvent->TargetProcessId);
// Check if processInformation is not nullptr before dereferencing it
if (targetProcessInformation == nullptr) {
printf("Target Process not found\n");
break;
}
EventWriteProcessAccess(
&systemTime,
processHandleEvent->SourceProcessId,
processHandleEvent->SourceThreadId,
processHandleEvent->SourceProcessStartKey,
sourceProcessInformation->processName.c_str(),
sourceProcessInformation->userName.c_str(),
sourceProcessInformation->authenticationId.LowPart,
sourceProcessInformation->integrityLevel.c_str(),
sourceProcessInformation->sessionId,
sourceProcessInformation->tokenType,
processHandleEvent->TargetProcessId,
processHandleEvent->TargetProcessStartKey,
targetProcessInformation->processName.c_str(),
targetProcessInformation->userName.c_str(),
targetProcessInformation->authenticationId.LowPart,
targetProcessInformation->linkedAuthenticationId.LowPart,
targetProcessInformation->integrityLevel.c_str(),
targetProcessInformation->sessionId,
targetProcessInformation->tokenType,
processHandleEvent->DesiredAccess,
processHandleEvent->OperationType
);
//
// Free the memory allocated for the event data
//
free(processHandleEvent);
break;
}
case 6:
{
printf("Registry Save Key Event\n");
PRegistrySaveKeyEvent registrySaveKeyEvent = (PRegistrySaveKeyEvent)malloc(sizeof(RegistrySaveKeyEvent));
if (registrySaveKeyEvent == nullptr) {
OutputDebugString(L"Error allocating memory for registrySaveKeyEvent\n");
status = ERROR_NOT_ENOUGH_MEMORY;
goto Exit;
}
registrySaveKeyEvent->EventId = *(INT32*)propertyDataVector[0];
registrySaveKeyEvent->SourceThreadId = *(INT64*)propertyDataVector[1];
registrySaveKeyEvent->SourceProcessId = *(INT64*)propertyDataVector[2];
registrySaveKeyEvent->SourceProcessStartKey = *(UINT64*)propertyDataVector[3];
registrySaveKeyEvent->KeyPath = (WCHAR*)propertyDataVector[4];
registrySaveKeyEvent->EventTime = *(FILETIME*)propertyDataVector[5];
FileTimeToSystemTime(®istrySaveKeyEvent->EventTime, &systemTime);
PProcessInformation processInformation;
processInformation = GetProcessName(registrySaveKeyEvent->SourceProcessId);
// Check if processInformation is not nullptr before dereferencing it
if (processInformation == nullptr) {
printf("Process not found\n");
break;
}
EventWriteRegistrySaveKey(
&systemTime,
processInformation->processName.c_str(),
registrySaveKeyEvent->SourceProcessId,
registrySaveKeyEvent->SourceThreadId,
registrySaveKeyEvent->SourceProcessStartKey,
processInformation->userName.c_str(),
processInformation->authenticationId.LowPart,
processInformation->integrityLevel.c_str(),
processInformation->sessionId,
registrySaveKeyEvent->KeyPath
);
//
// Free the memory allocated for the event data
//
free(registrySaveKeyEvent);
break;
}
case 8:
{
printf("Registry Set Value Key Event\n");
PRegistrySetValueKeyEvent registrySetValueKeyEvent = (PRegistrySetValueKeyEvent)malloc(sizeof(RegistrySetValueKeyEvent));
if (registrySetValueKeyEvent == nullptr) {
OutputDebugString(L"Error allocating memory for registrySetValueKeyEvent\n");
status = ERROR_NOT_ENOUGH_MEMORY;
goto Exit;
}
registrySetValueKeyEvent->EventId = *(INT32*)propertyDataVector[0];
registrySetValueKeyEvent->SourceThreadId = *(INT64*)propertyDataVector[1];
registrySetValueKeyEvent->SourceProcessId = *(INT64*)propertyDataVector[2];
registrySetValueKeyEvent->SourceProcessStartKey = *(UINT64*)propertyDataVector[3];
registrySetValueKeyEvent->KeyPath = (WCHAR*)propertyDataVector[4];
registrySetValueKeyEvent->ValueName = (WCHAR*)propertyDataVector[5];
registrySetValueKeyEvent->Data = (WCHAR*)propertyDataVector[6];
registrySetValueKeyEvent->Type = *(INT32*)propertyDataVector[7];
registrySetValueKeyEvent->DataSize = *(INT32*)propertyDataVector[8];
registrySetValueKeyEvent->EventTime = *(FILETIME*)propertyDataVector[9];
FileTimeToSystemTime(®istrySetValueKeyEvent->EventTime, &systemTime);
PProcessInformation processInformation;
processInformation = GetProcessName(registrySetValueKeyEvent->SourceProcessId);
// Check if processInformation is not nullptr before dereferencing it
if (processInformation == nullptr) {
printf("Process not found\n");
break;
}
EventWriteRegistrySetValueKey(
&systemTime,
processInformation->processName.c_str(),
registrySetValueKeyEvent->SourceProcessId,
registrySetValueKeyEvent->SourceThreadId,
registrySetValueKeyEvent->SourceProcessStartKey,
processInformation->userName.c_str(),
processInformation->authenticationId.LowPart,
processInformation->integrityLevel.c_str(),
processInformation->sessionId,
registrySetValueKeyEvent->KeyPath,
registrySetValueKeyEvent->Type,
registrySetValueKeyEvent->Data,
registrySetValueKeyEvent->ValueName
);
//
// Free the memory allocated for the event data
//
free(registrySetValueKeyEvent);
break;
}
case 9:
{
printf("Registry Create Key Event\n");
PRegistryCreateKeyEvent registryCreateKeyEvent = (PRegistryCreateKeyEvent)malloc(sizeof(RegistryCreateKeyEvent));
if (registryCreateKeyEvent == nullptr) {
OutputDebugString(L"Error allocating memory for registryCreateKeyEvent\n");
status = ERROR_NOT_ENOUGH_MEMORY;
goto Exit;
}
registryCreateKeyEvent->EventId = *(INT32*)propertyDataVector[0];
registryCreateKeyEvent->SourceThreadId = *(INT64*)propertyDataVector[1];
registryCreateKeyEvent->SourceProcessId = *(INT64*)propertyDataVector[2];
registryCreateKeyEvent->SourceProcessStartKey = *(UINT64*)propertyDataVector[3];
registryCreateKeyEvent->KeyPath = (WCHAR*)propertyDataVector[4];
registryCreateKeyEvent->DesiredAccess = *(INT32*)propertyDataVector[5];
registryCreateKeyEvent->EventTime = *(FILETIME*)propertyDataVector[6];
FileTimeToSystemTime(®istryCreateKeyEvent->EventTime, &systemTime);
PProcessInformation processInformation;
processInformation = GetProcessName(registryCreateKeyEvent->SourceProcessId);
// Check if processInformation is not nullptr before dereferencing it
if (processInformation == nullptr) {
printf("Process not found\n");
break;
}
EventWriteRegistryCreateKey(
&systemTime,
processInformation->processName.c_str(),
registryCreateKeyEvent->SourceProcessId,
registryCreateKeyEvent->SourceThreadId,
registryCreateKeyEvent->SourceProcessStartKey,
processInformation->userName.c_str(),
processInformation->authenticationId.LowPart,
processInformation->integrityLevel.c_str(),
processInformation->sessionId,
registryCreateKeyEvent->KeyPath
);
//
// Free the memory allocated for the event data
//
free(registryCreateKeyEvent);
break;
}
case 10:
{
printf("File Operation Event\n");
PFileCreationEvent fileCreationEvent = (PFileCreationEvent)malloc(sizeof(FileCreationEvent));
if (fileCreationEvent == nullptr) {
OutputDebugString(L"Error allocating memory for fileCreationEvent\n");
status = ERROR_NOT_ENOUGH_MEMORY;
goto Exit;
}
fileCreationEvent->EventId = *(INT32*)propertyDataVector[0];
fileCreationEvent->SourceThreadId = *(INT64*)propertyDataVector[1];
fileCreationEvent->SourceProcessId = *(INT64*)propertyDataVector[2];
fileCreationEvent->SourceProcessStartKey = *(UINT64*)propertyDataVector[3];
fileCreationEvent->FileName = (WCHAR*)propertyDataVector[4];
fileCreationEvent->EventTime = *(FILETIME*)propertyDataVector[5];
FileTimeToSystemTime(&fileCreationEvent->EventTime, &systemTime);
//
// Filter: Check to see if ending of the file is .exe, .sys, .dll, .js, .vbs, .ps1, .bat, .cmd, .hta, .msi. Set all fileNames to lowercase before checking
//
std::wstring fileName = fileCreationEvent->FileName;
std::transform(fileName.begin(), fileName.end(), fileName.begin(), ::tolower);
std::wregex validExtensions(LR"((\.exe|\.sys|\.dll|\.js|\.vbs|\.ps1|\.bat|\.cmd|\.hta|\.msi)$)");
bool hasValidExtension = std::regex_search(fileName, validExtensions);
if (!hasValidExtension) {
free(fileCreationEvent);
break;
}
PProcessInformation processInformation;
processInformation = GetProcessName(fileCreationEvent->SourceProcessId);
// Check if processInformation is not nullptr before dereferencing it
if (processInformation == nullptr) {
printf("Process not found\n");
break;
}
EventWriteFileCreation(
&systemTime,
processInformation->processName.c_str(),
fileCreationEvent->SourceProcessId,
fileCreationEvent->SourceThreadId,
fileCreationEvent->SourceProcessStartKey,
processInformation->userName.c_str(),
processInformation->authenticationId.LowPart,
processInformation->integrityLevel.c_str(),
processInformation->sessionId,
fileCreationEvent->FileName
);
//
// Free the memory allocated for the event data
//
free(fileCreationEvent);
break;
}
case 11:
{
printf("Named Pipe Creation Event\n");
PNamedPipeCreateEvent namedPipeCreationEvent = (PNamedPipeCreateEvent)malloc(sizeof(NamedPipeCreateEvent));
if (namedPipeCreationEvent == nullptr) {
OutputDebugString(L"Error allocating memory for namedPipeCreationEvent\n");
status = ERROR_NOT_ENOUGH_MEMORY;
goto Exit;
}
namedPipeCreationEvent->EventId = *(INT32*)propertyDataVector[0];
namedPipeCreationEvent->SourceThreadId = *(INT64*)propertyDataVector[1];
namedPipeCreationEvent->SourceProcessId = *(INT64*)propertyDataVector[2];
namedPipeCreationEvent->SourceProcessStartKey = *(UINT64*)propertyDataVector[3];
namedPipeCreationEvent->FileName = (WCHAR*)propertyDataVector[4];
namedPipeCreationEvent->RequestedRights = *(INT32*)propertyDataVector[5];
namedPipeCreationEvent->GrantedRights = *(INT32*)propertyDataVector[6];
namedPipeCreationEvent->EventTime = *(FILETIME*)propertyDataVector[7];
FileTimeToSystemTime(&namedPipeCreationEvent->EventTime, &systemTime);
PProcessInformation processInformation;
processInformation = GetProcessName(namedPipeCreationEvent->SourceProcessId);
// Check if processInformation is not nullptr before dereferencing it
if (processInformation == nullptr) {
printf("Process not found\n");
break;
}
EventWriteNamedPipeCreation(
&systemTime,
processInformation->processName.c_str(),
namedPipeCreationEvent->SourceProcessId,
namedPipeCreationEvent->SourceThreadId,
namedPipeCreationEvent->SourceProcessStartKey,
processInformation->userName.c_str(),
processInformation->authenticationId.LowPart,
processInformation->integrityLevel.c_str(),
processInformation->sessionId,
namedPipeCreationEvent->FileName,
namedPipeCreationEvent->RequestedRights
);
//
// Free the memory allocated for the event data
//
free(namedPipeCreationEvent);
break;
}
case 12:
{
printf("Named Pipe Connection Event\n");
PNamedPipeConnectionEvent namedPipeConnectionEvent = (PNamedPipeConnectionEvent)malloc(sizeof(NamedPipeConnectionEvent));
if (namedPipeConnectionEvent == nullptr) {
OutputDebugString(L"Error allocating memory for namedPipeConnectionEvent\n");
status = ERROR_NOT_ENOUGH_MEMORY;
goto Exit;
}
namedPipeConnectionEvent->EventId = *(INT32*)propertyDataVector[0];
namedPipeConnectionEvent->SourceThreadId = *(INT64*)propertyDataVector[1];
namedPipeConnectionEvent->SourceProcessId = *(INT64*)propertyDataVector[2];
namedPipeConnectionEvent->SourceProcessStartKey = *(UINT64*)propertyDataVector[3];
namedPipeConnectionEvent->FileName = (WCHAR*)propertyDataVector[4];
namedPipeConnectionEvent->RequestedRights = *(INT32*)propertyDataVector[5];
namedPipeConnectionEvent->EventTime = *(FILETIME*)propertyDataVector[6];
FileTimeToSystemTime(&namedPipeConnectionEvent->EventTime, &systemTime);
PProcessInformation processInformation;
processInformation = GetProcessName(namedPipeConnectionEvent->SourceProcessId);
// Check if processInformation is not nullptr before dereferencing it
if (processInformation == nullptr) {
printf("Process not found\n");
break;
}
EventWriteNamedPipeConnection(
&systemTime,
processInformation->processName.c_str(),
namedPipeConnectionEvent->SourceProcessId,
namedPipeConnectionEvent->SourceThreadId,
namedPipeConnectionEvent->SourceProcessStartKey,
processInformation->userName.c_str(),
processInformation->authenticationId.LowPart,
processInformation->integrityLevel.c_str(),
processInformation->sessionId,
namedPipeConnectionEvent->FileName,
namedPipeConnectionEvent->RequestedRights
);
//
// Free the memory allocated for the event data
//
free(namedPipeConnectionEvent);
break;
}
case 13:
{
printf("Mailslot Creation Event\n");
PMailslotCreateEvent mailslotCreationEvent = (PMailslotCreateEvent)malloc(sizeof(MailslotCreateEvent));
if (mailslotCreationEvent == nullptr) {
OutputDebugString(L"Error allocating memory for mailslotCreationEvent\n");
status = ERROR_NOT_ENOUGH_MEMORY;
goto Exit;
}
mailslotCreationEvent->EventId = *(INT32*)propertyDataVector[0];
mailslotCreationEvent->SourceThreadId = *(INT64*)propertyDataVector[1];
mailslotCreationEvent->SourceProcessId = *(INT64*)propertyDataVector[2];
mailslotCreationEvent->SourceProcessStartKey = *(UINT64*)propertyDataVector[3];
mailslotCreationEvent->FileName = (WCHAR*)propertyDataVector[4];
mailslotCreationEvent->RequestedRights = *(INT32*)propertyDataVector[5];
mailslotCreationEvent->EventTime = *(FILETIME*)propertyDataVector[6];
FileTimeToSystemTime(&mailslotCreationEvent->EventTime, &systemTime);
PProcessInformation processInformation;
processInformation = GetProcessName(mailslotCreationEvent->SourceProcessId);
// Check if processInformation is not nullptr before dereferencing it
if (processInformation == nullptr) {
printf("Process not found\n");
break;
}
EventWriteMailslotCreation(
&systemTime,
processInformation->processName.c_str(),
mailslotCreationEvent->SourceProcessId,
mailslotCreationEvent->SourceThreadId,
mailslotCreationEvent->SourceProcessStartKey,
processInformation->userName.c_str(),
processInformation->authenticationId.LowPart,
processInformation->integrityLevel.c_str(),
processInformation->sessionId,
mailslotCreationEvent->FileName,
mailslotCreationEvent->RequestedRights
);
//
// Free the memory allocated for the event data
//
free(mailslotCreationEvent);
}
case 14:
{
printf("Mailslot Connection Event\n");
PMailslotConnectionEvent mailslotConnectionEvent = (PMailslotConnectionEvent)malloc(sizeof(MailslotConnectionEvent));
if (mailslotConnectionEvent == nullptr) {
OutputDebugString(L"Error allocating memory for mailslotConnectionEvent\n");
status = ERROR_NOT_ENOUGH_MEMORY;
goto Exit;
}
mailslotConnectionEvent->EventId = *(INT32*)propertyDataVector[0];
mailslotConnectionEvent->SourceThreadId = *(INT64*)propertyDataVector[1];
mailslotConnectionEvent->SourceProcessId = *(INT64*)propertyDataVector[2];
mailslotConnectionEvent->SourceProcessStartKey = *(UINT64*)propertyDataVector[3];
mailslotConnectionEvent->FileName = (WCHAR*)propertyDataVector[4];
mailslotConnectionEvent->RequestedRights = *(INT32*)propertyDataVector[5];
mailslotConnectionEvent->EventTime = *(FILETIME*)propertyDataVector[6];
FileTimeToSystemTime(&mailslotConnectionEvent->EventTime, &systemTime);
PProcessInformation processInformation;
processInformation = GetProcessName(mailslotConnectionEvent->SourceProcessId);
// Check if processInformation is not nullptr before dereferencing it
if (processInformation == nullptr) {
printf("Process not found\n");
break;
}
EventWriteMailslotConnection(
&systemTime,
processInformation->processName.c_str(),
mailslotConnectionEvent->SourceProcessId,
mailslotConnectionEvent->SourceThreadId,
mailslotConnectionEvent->SourceProcessStartKey,
processInformation->userName.c_str(),
processInformation->authenticationId.LowPart,
processInformation->integrityLevel.c_str(),
processInformation->sessionId,
mailslotConnectionEvent->FileName,
mailslotConnectionEvent->RequestedRights
);
//
// Free the memory allocated for the event data
//
free(mailslotConnectionEvent);
break;
}
case 15:
{
printf("Remote File Connection Event\n");
PRemoteFileConnectionEvent remoteFileConnectionEvent = (PRemoteFileConnectionEvent)malloc(sizeof(RemoteFileConnectionEvent));
remoteFileConnectionEvent->EventId = *(INT32*)propertyDataVector[0];
remoteFileConnectionEvent->SourceThreadId = *(INT64*)propertyDataVector[1];
remoteFileConnectionEvent->SourceProcessId = *(INT64*)propertyDataVector[2];
remoteFileConnectionEvent->SourceProcessStartKey = *(UINT64*)propertyDataVector[3];
remoteFileConnectionEvent->FileName = (WCHAR*)propertyDataVector[4];
remoteFileConnectionEvent->EventTime = *(FILETIME*)propertyDataVector[5];
FileTimeToSystemTime(&remoteFileConnectionEvent->EventTime, &systemTime);
PProcessInformation processInformation;
processInformation = GetProcessName(remoteFileConnectionEvent->SourceProcessId);
// Check if processInformation is not nullptr before dereferencing it
if (processInformation == nullptr) {
printf("Process not found\n");
break;
}
EventWriteRemoteFileConnection(
&systemTime,
processInformation->processName.c_str(),
remoteFileConnectionEvent->SourceProcessId,
remoteFileConnectionEvent->SourceThreadId,
remoteFileConnectionEvent->SourceProcessStartKey,
processInformation->userName.c_str(),
processInformation->authenticationId.LowPart,
processInformation->integrityLevel.c_str(),
processInformation->sessionId,
remoteFileConnectionEvent->FileName
);
//
// Free the memory allocated for the event data
//
free(remoteFileConnectionEvent);
break;
}
case 16:
{
std::wstring integirtyLevelString;
OutputDebugStringW(L"Query - Thread Token Impersonation Event\n");
PThreadImpersonationEvent threadImpersonationEvent = (PThreadImpersonationEvent)malloc(sizeof(ThreadImpersonationEvent));
if (threadImpersonationEvent == nullptr) {
OutputDebugString(L"Error allocating memory for threadImpersonationEvent\n");
status = ERROR_NOT_ENOUGH_MEMORY;
goto Exit;
}
threadImpersonationEvent->EventId = *(INT32*)propertyDataVector[0];
threadImpersonationEvent->ThreadId = *(UINT32*)propertyDataVector[1];
threadImpersonationEvent->ProcessId = *(UINT32*)propertyDataVector[2];
threadImpersonationEvent->threadIntegrityLevel = *(UINT32*)propertyDataVector[3];
threadImpersonationEvent->EventTime = *(SYSTEMTIME*)propertyDataVector[4];
threadImpersonationEvent->ImpersonatedUser = (WCHAR*)propertyDataVector[5];
switch(threadImpersonationEvent->threadIntegrityLevel) {
case 12288:
gitextract_k5_9flv0/
├── .github/
│ └── ISSUE_TEMPLATE/
│ ├── bug_report.md
│ └── feature_request.md
├── .gitignore
├── Extensions/
│ └── Extension1/
│ └── JonMon-Ext1/
│ ├── JonMon-Ext1.vcxproj
│ ├── dllmain.cpp
│ ├── dllmain.h
│ ├── framework.h
│ ├── pch.cpp
│ └── pch.h
├── JonMon/
│ ├── JonMon.sln
│ ├── JonMon.vcxproj
│ ├── callbacks.cpp
│ ├── callbacks.h
│ ├── driver.cpp
│ ├── driver.h
│ ├── jtime.h
│ ├── minifilter.cpp
│ ├── minifilter.h
│ ├── process.cpp
│ ├── process.h
│ ├── registry.cpp
│ ├── registry.h
│ └── shared.h
├── JonMon-Service/
│ ├── JonMon-Service.vcxproj
│ ├── JonMonService.cpp
│ ├── config.cpp
│ ├── config.h
│ ├── context.cpp
│ ├── context.h
│ ├── etwMain.cpp
│ ├── etwMain.h
│ ├── global.h
│ ├── service.cpp
│ └── service.h
├── JonMonConfig.json
├── JonMonProvider/
│ ├── jonmon.h
│ ├── jonmon.man
│ ├── jonmon.rc
│ └── jonmon.res
├── LICENSE
├── Libs/
│ └── nlohmann/
│ ├── adl_serializer.hpp
│ ├── byte_container_with_subtype.hpp
│ ├── detail/
│ │ ├── abi_macros.hpp
│ │ ├── conversions/
│ │ │ ├── from_json.hpp
│ │ │ ├── to_chars.hpp
│ │ │ └── to_json.hpp
│ │ ├── exceptions.hpp
│ │ ├── hash.hpp
│ │ ├── input/
│ │ │ ├── binary_reader.hpp
│ │ │ ├── input_adapters.hpp
│ │ │ ├── json_sax.hpp
│ │ │ ├── lexer.hpp
│ │ │ ├── parser.hpp
│ │ │ └── position_t.hpp
│ │ ├── iterators/
│ │ │ ├── internal_iterator.hpp
│ │ │ ├── iter_impl.hpp
│ │ │ ├── iteration_proxy.hpp
│ │ │ ├── iterator_traits.hpp
│ │ │ ├── json_reverse_iterator.hpp
│ │ │ └── primitive_iterator.hpp
│ │ ├── json_custom_base_class.hpp
│ │ ├── json_pointer.hpp
│ │ ├── json_ref.hpp
│ │ ├── macro_scope.hpp
│ │ ├── macro_unscope.hpp
│ │ ├── meta/
│ │ │ ├── call_std/
│ │ │ │ ├── begin.hpp
│ │ │ │ └── end.hpp
│ │ │ ├── cpp_future.hpp
│ │ │ ├── detected.hpp
│ │ │ ├── identity_tag.hpp
│ │ │ ├── is_sax.hpp
│ │ │ ├── std_fs.hpp
│ │ │ ├── type_traits.hpp
│ │ │ └── void_t.hpp
│ │ ├── output/
│ │ │ ├── binary_writer.hpp
│ │ │ ├── output_adapters.hpp
│ │ │ └── serializer.hpp
│ │ ├── string_concat.hpp
│ │ ├── string_escape.hpp
│ │ └── value_t.hpp
│ ├── json.hpp
│ ├── json_fwd.hpp
│ ├── ordered_map.hpp
│ └── thirdparty/
│ └── hedley/
│ ├── hedley.hpp
│ └── hedley_undef.hpp
├── README.md
└── deployment/
└── Azure/
└── README.md
SYMBOL INDEX (578 symbols across 60 files)
FILE: Extensions/Extension1/JonMon-Ext1/dllmain.cpp
function BOOL (line 23) | BOOL APIENTRY DllMain(HMODULE hModule,
function DWORD (line 39) | DWORD IntegritySID(HANDLE hToken, PDWORD *IntegrityLevel) {
function DWORD (line 102) | DWORD TokenUserName(HANDLE hToken, LPWSTR* pStringSid)
function TokenImpersonationCheck (line 201) | void TokenImpersonationCheck()
FILE: JonMon-Service/JonMonService.cpp
function wmain (line 11) | int wmain(int argc, wchar_t* argv[])
FILE: JonMon-Service/config.cpp
function ConfigFile (line 9) | int ConfigFile(
FILE: JonMon-Service/config.h
type EventSchema_KM (line 4) | struct EventSchema_KM {
type EventSchema_Full (line 18) | struct EventSchema_Full {
FILE: JonMon-Service/context.cpp
function InitialProcesses (line 23) | void InitialProcesses()
function DWORD (line 116) | DWORD GetUserInformation(
function PProcessInformation (line 245) | PProcessInformation GetProcessName(
function ClearProcessList (line 269) | void ClearProcessList() {
function GetProcessList (line 282) | void GetProcessList() {
function UpdateProcessListPeriodically (line 398) | void UpdateProcessListPeriodically() {
function ClearListPeriodically (line 405) | void ClearListPeriodically() {
function DWORD (line 415) | DWORD GetTokenUserInfo(
function DWORD (line 484) | DWORD GetAuthenticationId(
function DWORD (line 535) | DWORD GetMandatoryLabel(
FILE: JonMon-Service/context.h
type TokenInformation (line 10) | typedef struct _TokenInformation {
type ProcessInformation (line 19) | typedef struct _ProcessInformation {
FILE: JonMon-Service/etwMain.cpp
function DWORD (line 22) | DWORD StopETWTrace() {
function DWORD (line 49) | DWORD CheckLSASSPID() {
function DWORD (line 65) | DWORD TraceEvent(
function ProcessEvent (line 329) | void ProcessEvent(
function NTSTATUS (line 449) | NTSTATUS WriteJonMonTraceLoggingEvents(
function NTSTATUS (line 1467) | NTSTATUS WriteThreatIntelEvents(
function BOOL (line 2117) | BOOL WriteNetworkEvents(
function NTSTATUS (line 2410) | NTSTATUS ProcessEtwEvent(
function BOOL (line 2473) | BOOL WriteAMSIEvents(
function NTSTATUS (line 2591) | NTSTATUS WriteDotNetEvents(
function NTSTATUS (line 2690) | NTSTATUS WriteWMIEvents(
function wchar_t (line 2782) | wchar_t* GetCallStack(
function NTSTATUS (line 2840) | NTSTATUS WriteRpcEvents(
function NTSTATUS (line 3619) | NTSTATUS WriteDpapiEvents(
FILE: JonMon-Service/etwMain.h
type ProcessData (line 14) | struct ProcessData {
type TraceLoggingProviderRegistered (line 88) | typedef struct _TraceLoggingProviderRegistered {
type EventSchemaConfiguration (line 96) | typedef struct _EventSchemaConfiguration {
type DebugLog (line 112) | typedef struct _DebugLog {
type ProcessCreationEvent (line 121) | typedef struct _ProcessCreationEvent {
type ProcessTerminationEvent (line 136) | typedef struct _ProcessTerminationEvent {
type RemoteThreadCreationEvent (line 148) | typedef struct _RemoteThreadCreationEvent {
type LoadImageEvent (line 162) | typedef struct _LoadImageEvent {
type ProcessHandleEvent (line 175) | typedef struct _ProcessHandleEvent {
type RegistrySaveKeyEvent (line 190) | typedef struct _RegistrySaveKeyEvent {
type RegistryDeleteKeyEvent (line 202) | typedef struct _RegistryDeleteKeyEvent {
type RegistrySetValueKeyEvent (line 214) | typedef struct _RegistrySetValueKeyEvent {
type RegistryCreateKeyEvent (line 230) | typedef struct _RegistryCreateKeyEvent {
type FileCreationEvent (line 243) | typedef struct _FileCreationEvent {
type NamedPipeCreateEvent (line 255) | typedef struct _NamedPipeCreateEvent {
type NamedPipeConnectionEvent (line 269) | typedef struct _NamedPipeConnectionEvent {
type MailslotCreateEvent (line 282) | typedef struct _MailslotCreateEvent {
type MailslotConnectionEvent (line 295) | typedef struct _MailslotConnectionEvent {
type RemoteFileConnectionEvent (line 308) | typedef struct _RemoteFileConnectionEvent {
type ThreadImpersonationEvent (line 321) | typedef struct _ThreadImpersonationEvent {
FILE: JonMon-Service/service.cpp
function VOID (line 22) | VOID WINAPI ServiceCtrlHandler(
function VOID (line 113) | VOID WINAPI ServiceMain(
function DWORD (line 172) | DWORD ProtectionCheck()
function VOID (line 203) | VOID ChangePPL() {
function VOID (line 222) | VOID LoadExtensions()
function DWORD (line 253) | DWORD CreateCustomService(
function DWORD (line 290) | DWORD StartCustomService(
function DWORD (line 345) | DWORD StopCustomService(
function DWORD (line 382) | DWORD DeleteCustomService(
function DWORD (line 410) | DWORD UninstallManifest() {
function DWORD (line 433) | DWORD InstallManifest() {
FILE: JonMon/callbacks.cpp
function NTSTATUS (line 33) | NTSTATUS RegisterCallbacks(
function VOID (line 161) | VOID
function BOOLEAN (line 189) | BOOLEAN ContainsSubstring(PCWSTR keyPath, PCWSTR substring) {
function NTSTATUS (line 207) | NTSTATUS RegistryCallback(
function PsCreateThreadNotifyRoutine (line 527) | void PsCreateThreadNotifyRoutine(
function CreateProcessNotifyRoutineEx (line 601) | void CreateProcessNotifyRoutineEx(
function PostProcessHandleCallback (line 683) | void PostProcessHandleCallback(
function TerminateProcessNotifyRoutine (line 756) | void TerminateProcessNotifyRoutine(
FILE: JonMon/callbacks.h
type EventSchema (line 12) | typedef struct _EventSchema {
type HANDLE_CREATION_CALLBACK_INFO (line 27) | typedef struct _HANDLE_CREATION_CALLBACK_INFO {
type LOAD_IMAGE_CALLBACK_INFO (line 39) | typedef struct _LOAD_IMAGE_CALLBACK_INFO {
type PROCESS_CREATE_CALLBACK_INFO (line 48) | typedef struct _PROCESS_CREATE_CALLBACK_INFO {
type THREAD_CREATE_CALLBACK_INFO (line 57) | typedef struct _THREAD_CREATE_CALLBACK_INFO {
type PROCESS_TERMINATE_CALLBACK_INFO (line 64) | typedef struct _PROCESS_TERMINATE_CALLBACK_INFO {
FILE: JonMon/driver.cpp
function NTSTATUS (line 9) | NTSTATUS DriverEntry(
function NTSTATUS (line 72) | NTSTATUS JonMonDeviceControl(
function VOID (line 148) | VOID AlterPPL(
function VOID (line 220) | VOID ChangePPL()
function VOID (line 274) | VOID JonMonUnload(
function NTSTATUS (line 340) | NTSTATUS CompleteRequest(
function NTSTATUS (line 353) | NTSTATUS JonMonCreateClose(
FILE: JonMon/driver.h
type SYSTEM_THREADS (line 16) | typedef struct _SYSTEM_THREADS {
type SYSTEM_PROCESSES (line 30) | typedef struct _SYSTEM_PROCESSES {
type PS_PROTECTION (line 49) | typedef struct _PS_PROTECTION {
type PROCESS_SIGNATURE_PROTECTION (line 55) | typedef struct _PROCESS_SIGNATURE_PROTECTION {
FILE: JonMon/jtime.h
type WORD (line 3) | typedef unsigned short WORD;
type DWORD (line 4) | typedef unsigned long DWORD;
type SYSTEMTIME (line 6) | typedef struct _SYSTEMTIME {
type FILETIME (line 17) | typedef struct _FILETIME {
FILE: JonMon/minifilter.cpp
function NTSTATUS (line 8) | NTSTATUS
function FLTAPI (line 29) | FLTAPI
function FLTAPI (line 323) | FLTAPI
function NTSTATUS (line 340) | NTSTATUS
FILE: JonMon/process.cpp
function NTSTATUS (line 7) | NTSTATUS GetProcessImageName(HANDLE processId, PUNICODE_STRING ProcessIm...
FILE: JonMon/process.h
type NTSTATUS (line 5) | typedef NTSTATUS(*ZWQUERYINFORMATIONPROCESS) (
FILE: JonMon/registry.cpp
function NTSTATUS (line 8) | NTSTATUS
FILE: JonMon/registry.h
type REG_SET_VALUE_CALLBACK_INFO (line 8) | typedef struct _REG_SET_VALUE_CALLBACK_INFO
type REG_CREATE_KEY_CALLBACK_INFO (line 21) | typedef struct _REG_CREATE_KEY_CALLBACK_INFO
type REG_DELETE_KEY_CALLBACK_INFO (line 31) | typedef struct _REG_DELETE_KEY_CALLBACK_INFO
FILE: JonMon/shared.h
type SYSTEM_PROCESS_INFORMATION (line 74) | typedef struct _SYSTEM_PROCESS_INFORMATION {
type SYSTEM_INFORMATION_CLASS (line 87) | typedef enum _SYSTEM_INFORMATION_CLASS {
type _LIST_ENTRY (line 91) | struct _LIST_ENTRY
type _THREAD_LIST_ENTRY (line 92) | struct _THREAD_LIST_ENTRY
type THREAD_LIST_ENTRY (line 94) | typedef struct _THREAD_LIST_ENTRY {
FILE: JonMonProvider/jonmon.h
type MCGEN_TRACE_CONTEXT (line 243) | typedef struct _MCGEN_TRACE_CONTEXT
function FORCEINLINE (line 268) | FORCEINLINE
function FORCEINLINE (line 308) | FORCEINLINE
function DECLSPEC_NOINLINE (line 323) | DECLSPEC_NOINLINE __inline
type _mcgen_PASTE2 (line 457) | struct _mcgen_PASTE2
type _mcgen_PASTE2 (line 460) | struct _mcgen_PASTE2
type MCGEN_EVENTREGISTER_must_not_be_a_functionLike_macro_MCGEN_EVENTREGISTER (line 464) | typedef void MCGEN_EVENTREGISTER_must_not_be_a_functionLike_macro_MCGEN_...
type _mcgen_PASTE2 (line 470) | struct _mcgen_PASTE2
type _mcgen_PASTE2 (line 473) | struct _mcgen_PASTE2
type MCGEN_EVENTUNREGISTER_must_not_be_a_functionLike_macro_MCGEN_EVENTUNREGISTER (line 477) | typedef void MCGEN_EVENTUNREGISTER_must_not_be_a_functionLike_macro_MCGE...
type _mcgen_PASTE2 (line 483) | struct _mcgen_PASTE2
type _mcgen_PASTE2 (line 486) | struct _mcgen_PASTE2
type MCGEN_EVENTSETINFORMATION_must_not_be_a_functionLike_macro_MCGEN_EVENTSETINFORMATION (line 490) | typedef void MCGEN_EVENTSETINFORMATION_must_not_be_a_functionLike_macro_...
type _mcgen_PASTE2 (line 496) | struct _mcgen_PASTE2
type _mcgen_PASTE2 (line 499) | struct _mcgen_PASTE2
type MCGEN_EVENTWRITETRANSFER_must_not_be_a_functionLike_macro_MCGEN_EVENTWRITETRANSFER (line 503) | typedef void MCGEN_EVENTWRITETRANSFER_must_not_be_a_functionLike_macro_M...
function DECLSPEC_NOINLINE (line 513) | DECLSPEC_NOINLINE __inline
function DECLSPEC_NOINLINE (line 559) | DECLSPEC_NOINLINE __inline
function DECLSPEC_NOINLINE (line 611) | DECLSPEC_NOINLINE __inline
type McGenContext_JonMon (line 822) | typedef struct tagMcGenContext_JonMon {
function ULONG (line 841) | __inline
function McGenContext_JonMon (line 863) | McGenContext_JonMon*
function ETW_INLINE (line 1511) | ETW_INLINE
function ETW_INLINE (line 1538) | ETW_INLINE
function ETW_INLINE (line 1639) | ETW_INLINE
function ETW_INLINE (line 1735) | ETW_INLINE
function ETW_INLINE (line 1825) | ETW_INLINE
function ETW_INLINE (line 1863) | ETW_INLINE
function ETW_INLINE (line 1930) | ETW_INLINE
function ETW_INLINE (line 1998) | ETW_INLINE
function ETW_INLINE (line 2057) | ETW_INLINE
function ETW_INLINE (line 2119) | ETW_INLINE
function ETW_INLINE (line 2191) | ETW_INLINE
function ETW_INLINE (line 2272) | ETW_INLINE
function ETW_INLINE (line 2356) | ETW_INLINE
function ETW_INLINE (line 2449) | ETW_INLINE
function ETW_INLINE (line 2505) | ETW_INLINE
function ETW_INLINE (line 2589) | ETW_INLINE
function ETW_INLINE (line 2653) | ETW_INLINE
function ETW_INLINE (line 2728) | ETW_INLINE
function ETW_INLINE (line 2796) | ETW_INLINE
FILE: Libs/nlohmann/adl_serializer.hpp
function from_json (line 27) | static auto from_json(BasicJsonType && j, TargetType& val) noexcept(
function from_json (line 37) | static auto from_json(BasicJsonType && j) noexcept(
function to_json (line 47) | static auto to_json(BasicJsonType& j, TargetType && val) noexcept(
FILE: Libs/nlohmann/byte_container_with_subtype.hpp
function set_subtype (line 70) | void set_subtype(subtype_type subtype_) noexcept
function subtype_type (line 78) | constexpr subtype_type subtype() const noexcept
function has_subtype (line 85) | constexpr bool has_subtype() const noexcept
function clear_subtype (line 92) | void clear_subtype() noexcept
FILE: Libs/nlohmann/detail/conversions/from_json.hpp
function NLOHMANN_JSON_NAMESPACE_BEGIN (line 32) | NLOHMANN_JSON_NAMESPACE_BEGIN
FILE: Libs/nlohmann/detail/conversions/to_chars.hpp
function NLOHMANN_JSON_NAMESPACE_BEGIN (line 21) | NLOHMANN_JSON_NAMESPACE_BEGIN
FILE: Libs/nlohmann/detail/conversions/to_json.hpp
function NLOHMANN_JSON_NAMESPACE_BEGIN (line 27) | NLOHMANN_JSON_NAMESPACE_BEGIN
FILE: Libs/nlohmann/detail/exceptions.hpp
function NLOHMANN_JSON_NAMESPACE_BEGIN (line 28) | NLOHMANN_JSON_NAMESPACE_BEGIN
class parse_error (line 136) | class parse_error : public exception
method parse_error (line 149) | static parse_error create(int id_, const position_t& pos, const std::s...
method parse_error (line 157) | static parse_error create(int id_, std::size_t byte_, const std::strin...
method parse_error (line 177) | parse_error(int id_, std::size_t byte_, const char* what_arg)
method position_string (line 180) | static std::string position_string(const position_t& pos)
class invalid_iterator (line 189) | class invalid_iterator : public exception
method invalid_iterator (line 193) | static invalid_iterator create(int id_, const std::string& what_arg, B...
method JSON_HEDLEY_NON_NULL (line 200) | JSON_HEDLEY_NON_NULL(3)
class type_error (line 207) | class type_error : public exception
method type_error (line 211) | static type_error create(int id_, const std::string& what_arg, BasicJs...
method JSON_HEDLEY_NON_NULL (line 218) | JSON_HEDLEY_NON_NULL(3)
class out_of_range (line 224) | class out_of_range : public exception
method out_of_range (line 228) | static out_of_range create(int id_, const std::string& what_arg, Basic...
method JSON_HEDLEY_NON_NULL (line 235) | JSON_HEDLEY_NON_NULL(3)
class other_error (line 241) | class other_error : public exception
method other_error (line 245) | static other_error create(int id_, const std::string& what_arg, BasicJ...
method JSON_HEDLEY_NON_NULL (line 252) | JSON_HEDLEY_NON_NULL(3)
FILE: Libs/nlohmann/detail/hash.hpp
function NLOHMANN_JSON_NAMESPACE_BEGIN (line 18) | NLOHMANN_JSON_NAMESPACE_BEGIN
FILE: Libs/nlohmann/detail/input/binary_reader.hpp
function NLOHMANN_JSON_NAMESPACE_BEGIN (line 34) | NLOHMANN_JSON_NAMESPACE_BEGIN
FILE: Libs/nlohmann/detail/input/input_adapters.hpp
function NLOHMANN_JSON_NAMESPACE_BEGIN (line 30) | NLOHMANN_JSON_NAMESPACE_BEGIN
FILE: Libs/nlohmann/detail/input/json_sax.hpp
function json_sax_dom_parser (line 175) | explicit json_sax_dom_parser(BasicJsonType& r, const bool allow_exceptio...
function json_sax_dom_parser (line 180) | json_sax_dom_parser(const json_sax_dom_parser&) = delete;
function json_sax_dom_parser (line 181) | json_sax_dom_parser(json_sax_dom_parser&&) = default;
function null (line 186) | bool null()
function boolean (line 192) | bool boolean(bool val)
function number_integer (line 198) | bool number_integer(number_integer_t val)
function number_unsigned (line 204) | bool number_unsigned(number_unsigned_t val)
function number_float (line 210) | bool number_float(number_float_t val, const string_t& /*unused*/)
function string (line 216) | bool string(string_t& val)
function binary (line 222) | bool binary(binary_t& val)
function start_object (line 228) | bool start_object(std::size_t len)
function key (line 240) | bool key(string_t& val)
function end_object (line 250) | bool end_object()
function start_array (line 260) | bool start_array(std::size_t len)
function end_array (line 272) | bool end_array()
function parse_error (line 283) | bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
function is_errored (line 295) | constexpr bool is_errored() const
class json_sax_dom_callback_parser (line 344) | class json_sax_dom_callback_parser
method json_sax_dom_callback_parser (line 355) | json_sax_dom_callback_parser(BasicJsonType& r,
method json_sax_dom_callback_parser (line 364) | json_sax_dom_callback_parser(const json_sax_dom_callback_parser&) = de...
method json_sax_dom_callback_parser (line 365) | json_sax_dom_callback_parser(json_sax_dom_callback_parser&&) = default;
method json_sax_dom_callback_parser (line 366) | json_sax_dom_callback_parser& operator=(const json_sax_dom_callback_pa...
method json_sax_dom_callback_parser (line 367) | json_sax_dom_callback_parser& operator=(json_sax_dom_callback_parser&&...
method null (line 370) | bool null()
method boolean (line 376) | bool boolean(bool val)
method number_integer (line 382) | bool number_integer(number_integer_t val)
method number_unsigned (line 388) | bool number_unsigned(number_unsigned_t val)
method number_float (line 394) | bool number_float(number_float_t val, const string_t& /*unused*/)
method string (line 400) | bool string(string_t& val)
method binary (line 406) | bool binary(binary_t& val)
method start_object (line 412) | bool start_object(std::size_t len)
method key (line 430) | bool key(string_t& val)
method end_object (line 447) | bool end_object()
method start_array (line 483) | bool start_array(std::size_t len)
method end_array (line 500) | bool end_array()
method parse_error (line 533) | bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/,
method is_errored (line 545) | constexpr bool is_errored() const
method handle_value (line 567) | std::pair<bool, BasicJsonType*> handle_value(Value&& v, const bool ski...
class json_sax_acceptor (line 651) | class json_sax_acceptor
method null (line 660) | bool null()
method boolean (line 665) | bool boolean(bool /*unused*/)
method number_integer (line 670) | bool number_integer(number_integer_t /*unused*/)
method number_unsigned (line 675) | bool number_unsigned(number_unsigned_t /*unused*/)
method number_float (line 680) | bool number_float(number_float_t /*unused*/, const string_t& /*unused*/)
method string (line 685) | bool string(string_t& /*unused*/)
method binary (line 690) | bool binary(binary_t& /*unused*/)
method start_object (line 695) | bool start_object(std::size_t /*unused*/ = static_cast<std::size_t>(-1))
method key (line 700) | bool key(string_t& /*unused*/)
method end_object (line 705) | bool end_object()
method start_array (line 710) | bool start_array(std::size_t /*unused*/ = static_cast<std::size_t>(-1))
method end_array (line 715) | bool end_array()
method parse_error (line 720) | bool parse_error(std::size_t /*unused*/, const std::string& /*unused*/...
FILE: Libs/nlohmann/detail/input/lexer.hpp
function NLOHMANN_JSON_NAMESPACE_BEGIN (line 26) | NLOHMANN_JSON_NAMESPACE_BEGIN
function reset (line 1321) | void reset() noexcept
function char_int_type (line 1338) | char_int_type get()
function unget (line 1375) | void unget()
function add (line 1402) | void add(char_int_type c)
function number_unsigned_t (line 1419) | constexpr number_unsigned_t get_number_unsigned() const noexcept
function number_float_t (line 1425) | constexpr number_float_t get_number_float() const noexcept
function string_t (line 1431) | string_t& get_string()
function position_t (line 1441) | constexpr position_t get_position() const noexcept
function get_token_string (line 1449) | std::string get_token_string() const
function JSON_HEDLEY_RETURNS_NON_NULL (line 1473) | JSON_HEDLEY_RETURNS_NON_NULL
function skip_bom (line 1487) | bool skip_bom()
function skip_whitespace (line 1501) | void skip_whitespace()
function token_type (line 1510) | token_type scan()
FILE: Libs/nlohmann/detail/input/parser.hpp
function NLOHMANN_JSON_NAMESPACE_BEGIN (line 27) | NLOHMANN_JSON_NAMESPACE_BEGIN
FILE: Libs/nlohmann/detail/input/position_t.hpp
function NLOHMANN_JSON_NAMESPACE_BEGIN (line 15) | NLOHMANN_JSON_NAMESPACE_BEGIN
FILE: Libs/nlohmann/detail/iterators/internal_iterator.hpp
function NLOHMANN_JSON_NAMESPACE_BEGIN (line 14) | NLOHMANN_JSON_NAMESPACE_BEGIN
FILE: Libs/nlohmann/detail/iterators/iter_impl.hpp
function NLOHMANN_JSON_NAMESPACE_BEGIN (line 22) | NLOHMANN_JSON_NAMESPACE_BEGIN
function pointer (line 324) | pointer operator->() const
function iter_impl (line 366) | iter_impl operator++(int)& // NOLINT(cert-dcl21-cpp)
function iter_impl (line 377) | iter_impl& operator++()
function iter_impl (line 417) | iter_impl operator--(int)& // NOLINT(cert-dcl21-cpp)
function iter_impl (line 428) | iter_impl& operator--()
function iter_impl (line 576) | iter_impl& operator+=(difference_type i)
function iter_impl (line 613) | iter_impl& operator-=(difference_type i)
function iter_impl (line 622) | iter_impl operator+(difference_type i) const
function friend (line 633) | friend iter_impl operator+(difference_type i, const iter_impl& it)
function iter_impl (line 644) | iter_impl operator-(difference_type i) const
function difference_type (line 655) | difference_type operator-(const iter_impl& other) const
function reference (line 684) | reference operator[](difference_type n) const
function reference (line 738) | reference value() const
FILE: Libs/nlohmann/detail/iterators/iteration_proxy.hpp
function NLOHMANN_JSON_NAMESPACE_BEGIN (line 25) | NLOHMANN_JSON_NAMESPACE_BEGIN
function NLOHMANN_JSON_NAMESPACE_END (line 207) | NLOHMANN_JSON_NAMESPACE_END
FILE: Libs/nlohmann/detail/iterators/iterator_traits.hpp
function NLOHMANN_JSON_NAMESPACE_BEGIN (line 17) | NLOHMANN_JSON_NAMESPACE_BEGIN
FILE: Libs/nlohmann/detail/iterators/json_reverse_iterator.hpp
function NLOHMANN_JSON_NAMESPACE_BEGIN (line 17) | NLOHMANN_JSON_NAMESPACE_BEGIN
FILE: Libs/nlohmann/detail/iterators/primitive_iterator.hpp
function NLOHMANN_JSON_NAMESPACE_BEGIN (line 16) | NLOHMANN_JSON_NAMESPACE_BEGIN
FILE: Libs/nlohmann/detail/json_custom_base_class.hpp
function NLOHMANN_JSON_NAMESPACE_BEGIN (line 15) | NLOHMANN_JSON_NAMESPACE_BEGIN
FILE: Libs/nlohmann/detail/json_pointer.hpp
function NLOHMANN_JSON_NAMESPACE_BEGIN (line 30) | NLOHMANN_JSON_NAMESPACE_BEGIN
function NLOHMANN_BASIC_JSON_TPL_DECLARATION (line 50) | NLOHMANN_BASIC_JSON_TPL_DECLARATION
function json_pointer (line 62) | explicit json_pointer(const string_t& s = "")
function string_t (line 68) | string_t to_string() const
function friend (line 89) | friend std::ostream& operator<<(std::ostream& o, const json_pointer& ptr)
function json_pointer (line 98) | json_pointer& operator/=(const json_pointer& ptr)
function json_pointer (line 108) | json_pointer& operator/=(string_t token)
function json_pointer (line 116) | json_pointer& operator/=(std::size_t array_idx)
function friend (line 123) | friend json_pointer operator/(const json_pointer& lhs,
function friend (line 131) | friend json_pointer operator/(const json_pointer& lhs, string_t token) /...
function friend (line 138) | friend json_pointer operator/(const json_pointer& lhs, std::size_t array...
function json_pointer (line 145) | json_pointer parent_pointer() const
function pop_back (line 159) | void pop_back()
function string_t (line 171) | const string_t& back() const
function push_back (line 183) | void push_back(const string_t& token)
function push_back (line 190) | void push_back(string_t&& token)
function empty (line 197) | bool empty() const noexcept
function BasicJsonType (line 274) | BasicJsonType& get_and_create(BasicJsonType& j) const
function BasicJsonType (line 354) | BasicJsonType& get_unchecked(BasicJsonType* ptr) const
function BasicJsonType (line 422) | BasicJsonType& get_checked(BasicJsonType* ptr) const
function BasicJsonType (line 480) | const BasicJsonType& get_unchecked(const BasicJsonType* ptr) const
function BasicJsonType (line 529) | const BasicJsonType& get_checked(const BasicJsonType* ptr) const
function contains (line 578) | bool contains(const BasicJsonType* ptr) const
function split (line 666) | static std::vector<string_t> split(const string_t& reference_string)
function BasicJsonType (line 806) | static BasicJsonType
function convert (line 835) | json_pointer<string_t> convert() const&
function convert (line 842) | json_pointer<string_t> convert()&&
FILE: Libs/nlohmann/detail/json_ref.hpp
function NLOHMANN_JSON_NAMESPACE_BEGIN (line 17) | NLOHMANN_JSON_NAMESPACE_BEGIN
FILE: Libs/nlohmann/detail/macro_scope.hpp
type would_call_std_ (line 462) | struct would_call_std_
FILE: Libs/nlohmann/detail/meta/cpp_future.hpp
function NLOHMANN_JSON_NAMESPACE_BEGIN (line 19) | NLOHMANN_JSON_NAMESPACE_BEGIN
FILE: Libs/nlohmann/detail/meta/detected.hpp
function NLOHMANN_JSON_NAMESPACE_BEGIN (line 15) | NLOHMANN_JSON_NAMESPACE_BEGIN
FILE: Libs/nlohmann/detail/meta/identity_tag.hpp
function NLOHMANN_JSON_NAMESPACE_BEGIN (line 13) | NLOHMANN_JSON_NAMESPACE_BEGIN
FILE: Libs/nlohmann/detail/meta/is_sax.hpp
function NLOHMANN_JSON_NAMESPACE_BEGIN (line 19) | NLOHMANN_JSON_NAMESPACE_BEGIN
FILE: Libs/nlohmann/detail/meta/std_fs.hpp
function NLOHMANN_JSON_NAMESPACE_BEGIN (line 15) | NLOHMANN_JSON_NAMESPACE_BEGIN
function NLOHMANN_JSON_NAMESPACE_BEGIN (line 23) | NLOHMANN_JSON_NAMESPACE_BEGIN
FILE: Libs/nlohmann/detail/meta/type_traits.hpp
function NLOHMANN_JSON_NAMESPACE_BEGIN (line 25) | NLOHMANN_JSON_NAMESPACE_BEGIN
FILE: Libs/nlohmann/detail/meta/void_t.hpp
function NLOHMANN_JSON_NAMESPACE_BEGIN (line 13) | NLOHMANN_JSON_NAMESPACE_BEGIN
FILE: Libs/nlohmann/detail/output/binary_writer.hpp
function NLOHMANN_JSON_NAMESPACE_BEGIN (line 27) | NLOHMANN_JSON_NAMESPACE_BEGIN
FILE: Libs/nlohmann/detail/output/output_adapters.hpp
function NLOHMANN_JSON_NAMESPACE_BEGIN (line 25) | NLOHMANN_JSON_NAMESPACE_BEGIN
FILE: Libs/nlohmann/detail/output/serializer.hpp
function NLOHMANN_JSON_NAMESPACE_BEGIN (line 34) | NLOHMANN_JSON_NAMESPACE_BEGIN
function hex_bytes (line 677) | static std::string hex_bytes(std::uint8_t byte)
function is_negative_number (line 688) | bool is_negative_number(NumberType x)
function is_negative_number (line 694) | bool is_negative_number(NumberType /*unused*/)
function dump_integer (line 714) | void dump_integer(NumberType x)
function dump_float (line 799) | void dump_float(number_float_t x)
function dump_float (line 820) | void dump_float(number_float_t x, std::true_type /*is_ieee_single_or_dou...
function dump_float (line 828) | void dump_float(number_float_t x, std::false_type /*is_ieee_single_or_do...
function decode (line 900) | static std::uint8_t decode(std::uint8_t& state, std::uint32_t& codep, co...
function number_unsigned_t (line 940) | number_unsigned_t remove_sign(number_unsigned_t x)
function number_unsigned_t (line 955) | inline number_unsigned_t remove_sign(number_integer_t x) noexcept
FILE: Libs/nlohmann/detail/string_concat.hpp
function NLOHMANN_JSON_NAMESPACE_BEGIN (line 18) | NLOHMANN_JSON_NAMESPACE_BEGIN
FILE: Libs/nlohmann/detail/string_escape.hpp
function NLOHMANN_JSON_NAMESPACE_BEGIN (line 13) | NLOHMANN_JSON_NAMESPACE_BEGIN
FILE: Libs/nlohmann/detail/value_t.hpp
type value_t (line 53) | enum class value_t : std::uint8_t
FILE: Libs/nlohmann/json.hpp
function NLOHMANN_JSON_NAMESPACE_BEGIN (line 76) | NLOHMANN_JSON_NAMESPACE_BEGIN
function set_parents (line 703) | void set_parents()
function iterator (line 740) | iterator set_parents(iterator it, typename iterator::difference_type cou...
function reference (line 753) | reference set_parent(reference j, std::size_t old_capacity = static_cast...
function basic_json (line 815) | basic_json(const value_t v)
function basic_json (line 823) | basic_json(std::nullptr_t = nullptr) noexcept // NOLINT(bugprone-excepti...
function basic_json (line 835) | basic_json(CompatibleType && val) noexcept(noexcept( // NOLINT(bugprone-...
function basic_json (line 849) | basic_json(const BasicJsonType& val)
function basic_json (line 902) | basic_json(initializer_list_t init,
function JSON_HEDLEY_WARN_UNUSED_RESULT (line 960) | JSON_HEDLEY_WARN_UNUSED_RESULT
function JSON_HEDLEY_WARN_UNUSED_RESULT (line 971) | JSON_HEDLEY_WARN_UNUSED_RESULT
function JSON_HEDLEY_WARN_UNUSED_RESULT (line 982) | JSON_HEDLEY_WARN_UNUSED_RESULT
function JSON_HEDLEY_WARN_UNUSED_RESULT (line 993) | JSON_HEDLEY_WARN_UNUSED_RESULT
function JSON_HEDLEY_WARN_UNUSED_RESULT (line 1004) | JSON_HEDLEY_WARN_UNUSED_RESULT
function JSON_HEDLEY_WARN_UNUSED_RESULT (line 1012) | JSON_HEDLEY_WARN_UNUSED_RESULT
function basic_json (line 1020) | basic_json(size_type cnt, const basic_json& val):
function basic_json (line 1032) | basic_json(InputIT first, InputIT last)
function basic_json (line 1141) | basic_json(const JsonRef& ref) : basic_json(ref.moved_or_copied()) {}
function basic_json (line 1145) | basic_json(const basic_json& other)
function basic_json (line 1214) | basic_json(basic_json&& other) noexcept
function basic_json (line 1231) | basic_json& operator=(basic_json other) noexcept (
function value_t (line 1294) | constexpr value_t type() const noexcept
function is_primitive (line 1301) | constexpr bool is_primitive() const noexcept
function is_structured (line 1308) | constexpr bool is_structured() const noexcept
function is_null (line 1315) | constexpr bool is_null() const noexcept
function is_boolean (line 1322) | constexpr bool is_boolean() const noexcept
function is_number (line 1329) | constexpr bool is_number() const noexcept
function is_number_integer (line 1336) | constexpr bool is_number_integer() const noexcept
function is_number_unsigned (line 1343) | constexpr bool is_number_unsigned() const noexcept
function is_number_float (line 1350) | constexpr bool is_number_float() const noexcept
function is_object (line 1357) | constexpr bool is_object() const noexcept
function is_array (line 1364) | constexpr bool is_array() const noexcept
function is_string (line 1371) | constexpr bool is_string() const noexcept
function is_binary (line 1378) | constexpr bool is_binary() const noexcept
function is_discarded (line 1385) | constexpr bool is_discarded() const noexcept
function object_t (line 1416) | object_t* get_impl_ptr(object_t* /*unused*/) noexcept
function object_t (line 1422) | constexpr const object_t* get_impl_ptr(const object_t* /*unused*/) const...
function array_t (line 1428) | array_t* get_impl_ptr(array_t* /*unused*/) noexcept
function array_t (line 1434) | constexpr const array_t* get_impl_ptr(const array_t* /*unused*/) const n...
function string_t (line 1440) | string_t* get_impl_ptr(string_t* /*unused*/) noexcept
function string_t (line 1446) | constexpr const string_t* get_impl_ptr(const string_t* /*unused*/) const...
function boolean_t (line 1452) | boolean_t* get_impl_ptr(boolean_t* /*unused*/) noexcept
function boolean_t (line 1458) | constexpr const boolean_t* get_impl_ptr(const boolean_t* /*unused*/) con...
function number_integer_t (line 1464) | number_integer_t* get_impl_ptr(number_integer_t* /*unused*/) noexcept
function number_integer_t (line 1470) | constexpr const number_integer_t* get_impl_ptr(const number_integer_t* /...
function number_unsigned_t (line 1476) | number_unsigned_t* get_impl_ptr(number_unsigned_t* /*unused*/) noexcept
function number_unsigned_t (line 1482) | constexpr const number_unsigned_t* get_impl_ptr(const number_unsigned_t*...
function number_float_t (line 1488) | number_float_t* get_impl_ptr(number_float_t* /*unused*/) noexcept
function number_float_t (line 1494) | constexpr const number_float_t* get_impl_ptr(const number_float_t* /*unu...
function binary_t (line 1500) | binary_t* get_impl_ptr(binary_t* /*unused*/) noexcept
function binary_t (line 1506) | constexpr const binary_t* get_impl_ptr(const binary_t* /*unused*/) const...
function ReferenceType (line 1523) | static ReferenceType get_ref_impl(ThisType& obj)
function get_ptr (line 1556) | constexpr auto get_ptr() const noexcept -> decltype(std::declval<const b...
function ValueType (line 1648) | ValueType get_impl(detail::priority_tag<1> /*unused*/) const noexcept(no...
function BasicJsonType (line 1673) | BasicJsonType get_impl(detail::priority_tag<2> /*unused*/) const
function basic_json (line 1696) | basic_json get_impl(detail::priority_tag<3> /*unused*/) const
function get_impl (line 1709) | constexpr auto get_impl(detail::priority_tag<4> /*unused*/) const noexcept
function get (line 1785) | auto get() noexcept -> decltype(std::declval<basic_json_t&>().template g...
function ValueType (line 1798) | ValueType & get_to(ValueType& v) const noexcept(noexcept(
function ValueType (line 1811) | ValueType & get_to(ValueType& v) const
function Array (line 1822) | Array get_to(T (&v)[N]) const // NOLINT(cppcoreguidelines-avoid-c-arrays...
function ReferenceType (line 1834) | ReferenceType get_ref()
function ReferenceType (line 1845) | ReferenceType get_ref() const
function binary_t (line 1904) | binary_t& get_binary()
function binary_t (line 1916) | const binary_t& get_binary() const
function reference (line 1938) | reference at(size_type idx)
function const_reference (line 1961) | const_reference at(size_type idx) const
function reference (line 1984) | reference at(const typename object_t::key_type& key)
function reference (line 2004) | reference at(KeyType && key)
function const_reference (line 2022) | const_reference at(const typename object_t::key_type& key) const
function const_reference (line 2042) | const_reference at(KeyType && key) const
function reference (line 2060) | reference operator[](size_type idx)
function const_reference (line 2106) | const_reference operator[](size_type idx) const
function reference (line 2119) | reference operator[](typename object_t::key_type key)
function const_reference (line 2141) | const_reference operator[](const typename object_t::key_type& key) const
function reference (line 2157) | reference operator[](T* key)
function const_reference (line 2163) | const_reference operator[](T* key) const
function reference (line 2172) | reference operator[](KeyType && key)
function const_reference (line 2196) | const_reference operator[](KeyType && key) const
function value (line 2219) | public:
function ReturnType (line 2251) | ReturnType value(const typename object_t::key_type& key, ValueType && de...
function ValueType (line 2277) | ValueType value(KeyType && key, const ValueType& default_value) const
function ReturnType (line 2304) | ReturnType value(KeyType && key, ValueType && default_value) const
function ValueType (line 2327) | ValueType value(const json_pointer& ptr, const ValueType& default_value)...
function ReturnType (line 2352) | ReturnType value(const json_pointer& ptr, ValueType && default_value) const
function ValueType (line 2376) | ValueType value(const ::nlohmann::json_pointer<BasicJsonType>& ptr, cons...
function ReturnType (line 2387) | ReturnType value(const ::nlohmann::json_pointer<BasicJsonType>& ptr, Val...
function reference (line 2394) | reference front()
function const_reference (line 2401) | const_reference front() const
function reference (line 2408) | reference back()
function const_reference (line 2417) | const_reference back() const
function IteratorType (line 2429) | IteratorType erase(IteratorType pos)
function IteratorType (line 2499) | IteratorType erase(IteratorType first, IteratorType last)
function erase_internal (line 2567) | private:
function size_type (line 2583) | size_type erase_internal(KeyType && key)
function size_type (line 2615) | size_type erase(KeyType && key)
function erase (line 2622) | void erase(const size_type idx)
function iterator (line 2651) | iterator find(const typename object_t::key_type& key)
function const_iterator (line 2665) | const_iterator find(const typename object_t::key_type& key) const
function iterator (line 2681) | iterator find(KeyType && key)
function const_iterator (line 2697) | const_iterator find(KeyType && key) const
function size_type (line 2711) | size_type count(const typename object_t::key_type& key) const
function size_type (line 2721) | size_type count(KeyType && key) const
function contains (line 2729) | bool contains(const typename object_t::key_type& key) const
function contains (line 2738) | bool contains(KeyType && key) const
function contains (line 2745) | bool contains(const json_pointer& ptr) const
function contains (line 2752) | bool contains(const typename ::nlohmann::json_pointer<BasicJsonType>& pt...
function iterator (line 2768) | iterator begin() noexcept
function const_iterator (line 2777) | const_iterator begin() const noexcept
function const_iterator (line 2784) | const_iterator cbegin() const noexcept
function iterator (line 2793) | iterator end() noexcept
function const_iterator (line 2802) | const_iterator end() const noexcept
function const_iterator (line 2809) | const_iterator cend() const noexcept
function reverse_iterator (line 2818) | reverse_iterator rbegin() noexcept
function const_reverse_iterator (line 2825) | const_reverse_iterator rbegin() const noexcept
function reverse_iterator (line 2832) | reverse_iterator rend() noexcept
function const_reverse_iterator (line 2839) | const_reverse_iterator rend() const noexcept
function const_reverse_iterator (line 2846) | const_reverse_iterator crbegin() const noexcept
function const_reverse_iterator (line 2853) | const_reverse_iterator crend() const noexcept
function iterator_wrapper (line 2865) | static iteration_proxy<iterator> iterator_wrapper(reference ref) noexcept
function iterator_wrapper (line 2876) | static iteration_proxy<const_iterator> iterator_wrapper(const_reference ...
function items (line 2883) | iteration_proxy<iterator> items() noexcept
function items (line 2890) | iteration_proxy<const_iterator> items() const noexcept
function empty (line 2906) | bool empty() const noexcept
function size_type (line 2945) | size_type size() const noexcept
function size_type (line 2984) | size_type max_size() const noexcept
function clear (line 3027) | void clear() noexcept
function push_back (line 3088) | void push_back(basic_json&& val)
function reference (line 3113) | reference operator+=(basic_json&& val)
function push_back (line 3121) | void push_back(const basic_json& val)
function reference (line 3145) | reference operator+=(const basic_json& val)
function push_back (line 3153) | void push_back(const typename object_t::value_type& val)
function reference (line 3176) | reference operator+=(const typename object_t::value_type& val)
function push_back (line 3184) | void push_back(initializer_list_t init)
function reference (line 3200) | reference operator+=(initializer_list_t init)
function reference (line 3209) | reference emplace_back(Args&& ... args)
function emplace (line 3234) | std::pair<iterator, bool> emplace(Args&& ... args)
function iterator (line 3266) | iterator insert_iterator(const_iterator pos, Args&& ... args)
function iterator (line 3285) | iterator insert(const_iterator pos, const basic_json& val)
function iterator (line 3305) | iterator insert(const_iterator pos, basic_json&& val)
function iterator (line 3312) | iterator insert(const_iterator pos, size_type cnt, const basic_json& val)
function iterator (line 3332) | iterator insert(const_iterator pos, const_iterator first, const_iterator...
function iterator (line 3363) | iterator insert(const_iterator pos, initializer_list_t ilist)
function insert (line 3383) | void insert(const_iterator first, const_iterator last)
function update (line 3408) | void update(const_reference j, bool merge_objects = false)
function update (line 3415) | void update(const_iterator first, const_iterator last, bool merge_object...
function swap (line 3462) | void swap(reference other) noexcept (
function friend (line 3479) | friend void swap(reference left, reference right) noexcept (
function swap (line 3491) | void swap(array_t& other) // NOLINT(bugprone-exception-escape,cppcoregui...
function swap (line 3507) | void swap(object_t& other) // NOLINT(bugprone-exception-escape,cppcoregu...
function swap (line 3523) | void swap(string_t& other) // NOLINT(bugprone-exception-escape,cppcoregu...
function swap (line 3539) | void swap(binary_t& other) // NOLINT(bugprone-exception-escape,cppcoregu...
function swap (line 3555) | void swap(typename binary_t::container_type& other) // NOLINT(bugprone-e...
function else (line 3644) | else if(compares_unordered(lhs, rhs))\
function compares_unordered (line 3673) | bool compares_unordered(const_reference rhs, bool inverse = false) const...
function friend (line 3786) | friend bool operator==(const_reference lhs, const_reference rhs) noexcept
function friend (line 3818) | friend bool operator!=(const_reference lhs, const_reference rhs) noexcept
function friend (line 3875) | friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
function friend (line 3904) | friend bool operator>(const_reference lhs, const_reference rhs) noexcept
function friend (line 3934) | friend bool operator>=(const_reference lhs, const_reference rhs) noexcept
function friend (line 3975) | friend std::ostream& operator<<(std::ostream& o, const basic_json& j)
function JSON_HEDLEY_WARN_UNUSED_RESULT (line 4014) | JSON_HEDLEY_WARN_UNUSED_RESULT
function JSON_HEDLEY_WARN_UNUSED_RESULT (line 4028) | JSON_HEDLEY_WARN_UNUSED_RESULT
function basic_json (line 4042) | static basic_json parse(detail::span_input_adapter&& i,
function accept (line 4055) | static bool accept(InputType&& i,
function accept (line 4064) | static bool accept(IteratorType first, IteratorType last,
function accept (line 4072) | static bool accept(detail::span_input_adapter&& i,
function sax_parse (line 4082) | static bool sax_parse(InputType&& i, SAX* sax,
function sax_parse (line 4097) | static bool sax_parse(IteratorType first, IteratorType last, SAX* sax,
function sax_parse (line 4116) | static bool sax_parse(detail::span_input_adapter&& i, SAX* sax,
function JSON_HEDLEY_RETURNS_NON_NULL (line 4157) | JSON_HEDLEY_RETURNS_NON_NULL
type data (line 4189) | struct data
method data (line 4197) | data(const value_t v)
method data (line 4202) | data(size_type cnt, const basic_json& val)
method data (line 4208) | data() noexcept = default;
method data (line 4209) | data(data&&) noexcept = default;
method data (line 4210) | data(const data&) noexcept = delete;
method data (line 4211) | data& operator=(data&&) noexcept = delete;
method data (line 4212) | data& operator=(const data&) noexcept = delete;
function to_cbor (line 4246) | static void to_cbor(const basic_json& j, detail::output_adapter<std::uin...
function to_cbor (line 4253) | static void to_cbor(const basic_json& j, detail::output_adapter<char> o)
function to_msgpack (line 4260) | static std::vector<std::uint8_t> to_msgpack(const basic_json& j)
function to_msgpack (line 4269) | static void to_msgpack(const basic_json& j, detail::output_adapter<std::...
function to_msgpack (line 4276) | static void to_msgpack(const basic_json& j, detail::output_adapter<char> o)
function to_ubjson (line 4283) | static std::vector<std::uint8_t> to_ubjson(const basic_json& j,
function to_ubjson (line 4294) | static void to_ubjson(const basic_json& j, detail::output_adapter<std::u...
function to_ubjson (line 4302) | static void to_ubjson(const basic_json& j, detail::output_adapter<char> o,
function to_bjdata (line 4310) | static std::vector<std::uint8_t> to_bjdata(const basic_json& j,
function to_bjdata (line 4321) | static void to_bjdata(const basic_json& j, detail::output_adapter<std::u...
function to_bjdata (line 4329) | static void to_bjdata(const basic_json& j, detail::output_adapter<char> o,
function to_bson (line 4337) | static std::vector<std::uint8_t> to_bson(const basic_json& j)
function to_bson (line 4346) | static void to_bson(const basic_json& j, detail::output_adapter<std::uin...
function to_bson (line 4353) | static void to_bson(const basic_json& j, detail::output_adapter<char> o)
function JSON_HEDLEY_WARN_UNUSED_RESULT (line 4361) | JSON_HEDLEY_WARN_UNUSED_RESULT
function JSON_HEDLEY_WARN_UNUSED_RESULT (line 4377) | JSON_HEDLEY_WARN_UNUSED_RESULT
function basic_json (line 4393) | static basic_json from_cbor(const T* ptr, std::size_t len,
function basic_json (line 4403) | static basic_json from_cbor(detail::span_input_adapter&& i,
function JSON_HEDLEY_WARN_UNUSED_RESULT (line 4419) | JSON_HEDLEY_WARN_UNUSED_RESULT
function JSON_HEDLEY_WARN_UNUSED_RESULT (line 4434) | JSON_HEDLEY_WARN_UNUSED_RESULT
function basic_json (line 4449) | static basic_json from_msgpack(const T* ptr, std::size_t len,
function basic_json (line 4458) | static basic_json from_msgpack(detail::span_input_adapter&& i,
function JSON_HEDLEY_WARN_UNUSED_RESULT (line 4473) | JSON_HEDLEY_WARN_UNUSED_RESULT
function JSON_HEDLEY_WARN_UNUSED_RESULT (line 4488) | JSON_HEDLEY_WARN_UNUSED_RESULT
function basic_json (line 4503) | static basic_json from_ubjson(const T* ptr, std::size_t len,
function basic_json (line 4512) | static basic_json from_ubjson(detail::span_input_adapter&& i,
function JSON_HEDLEY_WARN_UNUSED_RESULT (line 4527) | JSON_HEDLEY_WARN_UNUSED_RESULT
function JSON_HEDLEY_WARN_UNUSED_RESULT (line 4542) | JSON_HEDLEY_WARN_UNUSED_RESULT
function JSON_HEDLEY_WARN_UNUSED_RESULT (line 4557) | JSON_HEDLEY_WARN_UNUSED_RESULT
function JSON_HEDLEY_WARN_UNUSED_RESULT (line 4572) | JSON_HEDLEY_WARN_UNUSED_RESULT
function basic_json (line 4587) | static basic_json from_bson(const T* ptr, std::size_t len,
function basic_json (line 4596) | static basic_json from_bson(detail::span_input_adapter&& i,
function reference (line 4618) | reference operator[](const json_pointer& ptr)
function reference (line 4625) | reference operator[](const ::nlohmann::json_pointer<BasicJsonType>& ptr)
function const_reference (line 4632) | const_reference operator[](const json_pointer& ptr) const
function const_reference (line 4639) | const_reference operator[](const ::nlohmann::json_pointer<BasicJsonType>...
function reference (line 4646) | reference at(const json_pointer& ptr)
function reference (line 4653) | reference at(const ::nlohmann::json_pointer<BasicJsonType>& ptr)
function const_reference (line 4660) | const_reference at(const json_pointer& ptr) const
function const_reference (line 4667) | const_reference at(const ::nlohmann::json_pointer<BasicJsonType>& ptr) c...
function basic_json (line 4674) | basic_json flatten() const
function basic_json (line 4683) | basic_json unflatten() const
function patch_inplace (line 4699) | void patch_inplace(const basic_json& json_patch)
function basic_json (line 4970) | basic_json patch(const basic_json& json_patch) const
function JSON_HEDLEY_WARN_UNUSED_RESULT (line 4979) | JSON_HEDLEY_WARN_UNUSED_RESULT
function merge_patch (line 5122) | void merge_patch(const basic_json& apply_patch)
function NLOHMANN_BASIC_JSON_TPL_DECLARATION (line 5153) | NLOHMANN_BASIC_JSON_TPL_DECLARATION
function NLOHMANN_JSON_NAMESPACE_END (line 5190) | NLOHMANN_JSON_NAMESPACE_END
FILE: Libs/nlohmann/json_fwd.hpp
class json_pointer (line 56) | class json_pointer
type ordered_map (line 67) | struct ordered_map
FILE: Libs/nlohmann/ordered_map.hpp
function ordered_map (line 46) | ordered_map() noexcept(noexcept(Container())) : Container{} {}
function ordered_map (line 47) | explicit ordered_map(const Allocator& alloc) noexcept(noexcept(Container...
function ordered_map (line 49) | ordered_map(It first, It last, const Allocator& alloc = Allocator())
function ordered_map (line 51) | ordered_map(std::initializer_list<value_type> init, const Allocator& all...
function emplace (line 54) | std::pair<iterator, bool> emplace(const key_type& key, T&& t)
function emplace (line 69) | std::pair<iterator, bool> emplace(KeyType && key, T && t)
function T (line 82) | T& operator[](const key_type& key)
function T (line 89) | T & operator[](KeyType && key)
function T (line 94) | const T& operator[](const key_type& key) const
function T (line 101) | const T & operator[](KeyType && key) const
function T (line 106) | T& at(const key_type& key)
function T (line 121) | T & at(KeyType && key) // NOLINT(cppcoreguidelines-missing-std-forward)
function T (line 134) | const T& at(const key_type& key) const
function T (line 149) | const T & at(KeyType && key) const // NOLINT(cppcoreguidelines-missing-s...
function size_type (line 162) | size_type erase(const key_type& key)
function size_type (line 183) | size_type erase(KeyType && key) // NOLINT(cppcoreguidelines-missing-std-...
function iterator (line 202) | iterator erase(iterator pos)
function iterator (line 207) | iterator erase(iterator first, iterator last)
function size_type (line 260) | size_type count(const key_type& key) const
function size_type (line 274) | size_type count(KeyType && key) const // NOLINT(cppcoreguidelines-missin...
function iterator (line 286) | iterator find(const key_type& key)
function iterator (line 300) | iterator find(KeyType && key) // NOLINT(cppcoreguidelines-missing-std-fo...
function const_iterator (line 312) | const_iterator find(const key_type& key) const
function insert (line 324) | std::pair<iterator, bool> insert( value_type&& value )
function insert (line 329) | std::pair<iterator, bool> insert( const value_type& value )
function insert (line 347) | void insert(InputIt first, InputIt last)
Condensed preview — 87 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,555K chars).
[
{
"path": ".github/ISSUE_TEMPLATE/bug_report.md",
"chars": 692,
"preview": "---\nname: Bug report\nabout: Report to introduce issues within the JonMon code\ntitle: ''\nlabels: bug\nassignees: jsecurity"
},
{
"path": ".github/ISSUE_TEMPLATE/feature_request.md",
"chars": 614,
"preview": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: enhancement\nassignees: jsecurity101\n"
},
{
"path": ".gitignore",
"chars": 7173,
"preview": "# Created by https://www.toptal.com/developers/gitignore/api/visualstudio\n# Edit at https://www.toptal.com/developers/gi"
},
{
"path": "Extensions/Extension1/JonMon-Ext1/JonMon-Ext1.vcxproj",
"chars": 11119,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msb"
},
{
"path": "Extensions/Extension1/JonMon-Ext1/dllmain.cpp",
"chars": 10536,
"preview": "//\n// Author: Jonathan Johnson (@jsecurity101)\n// JonMon-Ext1.dll. This is the DLL that will be loaded by JonMon-Service"
},
{
"path": "Extensions/Extension1/JonMon-Ext1/dllmain.h",
"chars": 340,
"preview": "#ifdef JONMON_EXPORTS\n#define JONMON_EXPORTS __declspec(dllexport)\n#else\n#define JONMON_EXPORTS __declspec(dllimport)\n#e"
},
{
"path": "Extensions/Extension1/JonMon-Ext1/framework.h",
"chars": 149,
"preview": "#pragma once\n\n#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers\n// Windows Heade"
},
{
"path": "Extensions/Extension1/JonMon-Ext1/pch.cpp",
"chars": 186,
"preview": "// pch.cpp: source file corresponding to the pre-compiled header\n\n#include \"pch.h\"\n\n// When you are using pre-compiled h"
},
{
"path": "Extensions/Extension1/JonMon-Ext1/pch.h",
"chars": 563,
"preview": "// pch.h: This is a precompiled header file.\n// Files listed below are compiled only once, improving build performance f"
},
{
"path": "JonMon/JonMon.sln",
"chars": 4288,
"preview": "\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 17\nVisualStudioVersion = 17.4.3320"
},
{
"path": "JonMon/JonMon.vcxproj",
"chars": 6762,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"12.0\" xmlns=\"http://schemas.micros"
},
{
"path": "JonMon/callbacks.cpp",
"chars": 21288,
"preview": "#include \"callbacks.h\"\n#include \"process.h\"\n#include \"registry.h\"\n#include \"minifilter.h\"\n\n\nPAGED_FILE();\n\n#define MAX_P"
},
{
"path": "JonMon/callbacks.h",
"chars": 2954,
"preview": "#ifndef _CALLBACK_\n#define _CALLBACK_\n#include \"shared.h\"\n\nextern ULONG g_ServicePID;\n\nextern PVOID ProcessRegistrationH"
},
{
"path": "JonMon/driver.cpp",
"chars": 10306,
"preview": "#include \"driver.h\"\n#include \"callbacks.h\"\n#include \"process.h\" \n\nTRACELOGGING_DEFINE_PROVIDER(g_hJonMon, \"JonMon\",\n\t(0x"
},
{
"path": "JonMon/driver.h",
"chars": 2307,
"preview": "#ifndef _DRIVER_\n#define _DRIVER_\n#include \"shared.h\"\n\n/*\n* Global variable to store the registry path\n*/\n\n#define JonMo"
},
{
"path": "JonMon/jtime.h",
"chars": 416,
"preview": "#ifndef _JTIME_\n#define _JTIME_\ntypedef unsigned short WORD;\ntypedef unsigned long DWORD;\n\ntypedef struct _SYSTEMTIME {\n"
},
{
"path": "JonMon/minifilter.cpp",
"chars": 12420,
"preview": "#include \"minifilter.h\"\n#include \"process.h\"\n\nPAGED_FILE();\n\nPFLT_FILTER gFilterHandle;\n\nNTSTATUS \nJonMonFilterUnload\n(\n"
},
{
"path": "JonMon/minifilter.h",
"chars": 718,
"preview": "#ifndef _MINIFILTER_\n#define _MINIFILTER_\n#include \"shared.h\"\n\n\nextern PFLT_FILTER gFilterHandle;\n\nNTSTATUS \nJonMonFilte"
},
{
"path": "JonMon/process.cpp",
"chars": 1947,
"preview": "#include \"process.h\"\n\nPAGED_FILE();\n\nZWQUERYINFORMATIONPROCESS ZwQueryInformationProcess;\n\nNTSTATUS GetProcessImageName("
},
{
"path": "JonMon/process.h",
"chars": 485,
"preview": "#ifndef _PROCESS_\n#define _PROCESS_\n#include \"shared.h\"\n\ntypedef NTSTATUS(*ZWQUERYINFORMATIONPROCESS) (\n\t__in HANDLE Pro"
},
{
"path": "JonMon/registry.cpp",
"chars": 1238,
"preview": "#include \"registry.h\"\n#include \"shared.h\"\n#include \"process.h\"\n#include <winerror.h>\n\nPAGED_FILE();\n\nNTSTATUS \nGetRegist"
},
{
"path": "JonMon/registry.h",
"chars": 1256,
"preview": "#ifndef _REGISTRY_\n#define _REGISTRY_\n#include <ntifs.h>\n\n//\n// Structure to hold registry callback info\n//\ntypedef stru"
},
{
"path": "JonMon/shared.h",
"chars": 2751,
"preview": "#ifndef _SHARED_\n#define _SHARED_\n#include <ntifs.h>\n#include <ntddk.h>\n#include <ntdef.h>\n#include <wdm.h>\n#include <Nt"
},
{
"path": "JonMon-Service/JonMon-Service.vcxproj",
"chars": 8261,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msb"
},
{
"path": "JonMon-Service/JonMonService.cpp",
"chars": 11362,
"preview": "#include <Windows.h>\n#include <iostream>\n#include <setupapi.h>\n#include \"etwMain.h\"\n#include \"service.h\"\n#include \"confi"
},
{
"path": "JonMon-Service/config.cpp",
"chars": 5534,
"preview": "#include \"config.h\"\n#include <iostream>\n#include <fstream>\n#include \"nlohmann/json.hpp\"\n\nusing json = nlohmann::json;\n\n\n"
},
{
"path": "JonMon-Service/config.h",
"chars": 1433,
"preview": "#pragma once\n#include <string>\n\nstruct EventSchema_KM {\n\tbool ConfigSet;\n\tbool ProcessCreation;\n\tbool ProcessTermination"
},
{
"path": "JonMon-Service/context.cpp",
"chars": 18028,
"preview": "#include <Windows.h>\n#include <psapi.h>\n#include \"context.h\"\n#include <sstream>\n#include <vector>\n#include <mutex>\n#incl"
},
{
"path": "JonMon-Service/context.h",
"chars": 1329,
"preview": "#pragma once\n#include <evntcons.h>\n#include \"tlhelp32.h\"\n#include <iostream>\n#include <vector>\n#pragma comment(lib, \"tdh"
},
{
"path": "JonMon-Service/etwMain.cpp",
"chars": 139218,
"preview": "#include <ws2tcpip.h>\n#include <Windows.h>\n#include <sstream>\n#include <vector>\n#include <stdio.h>\n#include <DbgHelp.h>\n"
},
{
"path": "JonMon-Service/etwMain.h",
"chars": 7271,
"preview": "#pragma once\n#include <evntcons.h>\n#include <iostream>\n\n#include <evntrace.h>\n#include <tdh.h>\n\n#include \"../JonMonProvi"
},
{
"path": "JonMon-Service/global.h",
"chars": 1187,
"preview": "#pragma once\n#include <evntprov.h>\n\n\n//\n//ETW GUIDS\n//\nstatic GUID RPC_Provider = { 0x6ad52b32, 0xd609, 0x4be9, { 0xae, "
},
{
"path": "JonMon-Service/service.cpp",
"chars": 13299,
"preview": "#include <Windows.h>\n#include <thread>\n#include \"service.h\"\n#include \"config.h\"\n#include \"etwMain.h\"\n\n\nSERVICE_STATUS_HA"
},
{
"path": "JonMon-Service/service.h",
"chars": 819,
"preview": "#pragma once\n#include <TraceLoggingProvider.h> \n\n#define JonMon_DEVICE 0x8010\n\n#define IOCTL_CHANGE_PROTECTION_LEVEL_PRO"
},
{
"path": "JonMonConfig.json",
"chars": 823,
"preview": "{\n \"ConfigVersion\": \"1.0\",\n \"JonMonVersion\": \"2.0\",\n \"ProcessCreation_Events\": false,\n \"File_Events\": false,"
},
{
"path": "JonMonProvider/jonmon.h",
"chars": 173551,
"preview": "//**********************************************************************`\n//* This is an include file generated by Messa"
},
{
"path": "JonMonProvider/jonmon.man",
"chars": 85791,
"preview": "<?xml version='1.0' encoding='utf-8' standalone='yes'?>\n<instrumentationManifest\n xmlns=\"http://schemas.microsoft.com"
},
{
"path": "JonMonProvider/jonmon.rc",
"chars": 70,
"preview": "LANGUAGE 0x9,0x1\n1 11 \"MSG00001.bin\"\n1 WEVT_TEMPLATE \"jonmonTEMP.BIN\"\n"
},
{
"path": "LICENSE",
"chars": 1073,
"preview": "MIT License\n\nCopyright (c) 2023 Jonathan Johnson\n\nPermission is hereby granted, free of charge, to any person obtaining "
},
{
"path": "Libs/nlohmann/adl_serializer.hpp",
"chars": 2279,
"preview": "// __ _____ _____ _____\n// __| | __| | | | JSON for Modern C++\n// | | |__ | | | | | | version 3.11"
},
{
"path": "Libs/nlohmann/byte_container_with_subtype.hpp",
"chars": 3533,
"preview": "// __ _____ _____ _____\n// __| | __| | | | JSON for Modern C++\n// | | |__ | | | | | | version 3.11"
},
{
"path": "Libs/nlohmann/detail/abi_macros.hpp",
"chars": 3807,
"preview": "// __ _____ _____ _____\n// __| | __| | | | JSON for Modern C++\n// | | |__ | | | | | | version 3.11"
},
{
"path": "Libs/nlohmann/detail/conversions/from_json.hpp",
"chars": 18880,
"preview": "// __ _____ _____ _____\n// __| | __| | | | JSON for Modern C++\n// | | |__ | | | | | | version 3.11"
},
{
"path": "Libs/nlohmann/detail/conversions/to_chars.hpp",
"chars": 38562,
"preview": "// __ _____ _____ _____\n// __| | __| | | | JSON for Modern C++\n// | | |__ | | | | | | version 3.11"
},
{
"path": "Libs/nlohmann/detail/conversions/to_json.hpp",
"chars": 16410,
"preview": "// __ _____ _____ _____\n// __| | __| | | | JSON for Modern C++\n// | | |__ | | | | | | version 3.11"
},
{
"path": "Libs/nlohmann/detail/exceptions.hpp",
"chars": 9267,
"preview": "// __ _____ _____ _____\n// __| | __| | | | JSON for Modern C++\n// | | |__ | | | | | | version 3.11"
},
{
"path": "Libs/nlohmann/detail/hash.hpp",
"chars": 4016,
"preview": "// __ _____ _____ _____\n// __| | __| | | | JSON for Modern C++\n// | | |__ | | | | | | version 3.11"
},
{
"path": "Libs/nlohmann/detail/input/binary_reader.hpp",
"chars": 103146,
"preview": "// __ _____ _____ _____\n// __| | __| | | | JSON for Modern C++\n// | | |__ | | | | | | version 3.11"
},
{
"path": "Libs/nlohmann/detail/input/input_adapters.hpp",
"chars": 17402,
"preview": "// __ _____ _____ _____\n// __| | __| | | | JSON for Modern C++\n// | | |__ | | | | | | version 3.11"
},
{
"path": "Libs/nlohmann/detail/input/json_sax.hpp",
"chars": 21510,
"preview": "// __ _____ _____ _____\n// __| | __| | | | JSON for Modern C++\n// | | |__ | | | | | | version 3.11"
},
{
"path": "Libs/nlohmann/detail/input/lexer.hpp",
"chars": 54569,
"preview": "// __ _____ _____ _____\n// __| | __| | | | JSON for Modern C++\n// | | |__ | | | | | | version 3.11"
},
{
"path": "Libs/nlohmann/detail/input/parser.hpp",
"chars": 19661,
"preview": "// __ _____ _____ _____\n// __| | __| | | | JSON for Modern C++\n// | | |__ | | | | | | version 3.11"
},
{
"path": "Libs/nlohmann/detail/input/position_t.hpp",
"chars": 958,
"preview": "// __ _____ _____ _____\n// __| | __| | | | JSON for Modern C++\n// | | |__ | | | | | | version 3.11"
},
{
"path": "Libs/nlohmann/detail/iterators/internal_iterator.hpp",
"chars": 1071,
"preview": "// __ _____ _____ _____\n// __| | __| | | | JSON for Modern C++\n// | | |__ | | | | | | version 3.11"
},
{
"path": "Libs/nlohmann/detail/iterators/iter_impl.hpp",
"chars": 24046,
"preview": "// __ _____ _____ _____\n// __| | __| | | | JSON for Modern C++\n// | | |__ | | | | | | version 3.11"
},
{
"path": "Libs/nlohmann/detail/iterators/iteration_proxy.hpp",
"chars": 8238,
"preview": "// __ _____ _____ _____\n// __| | __| | | | JSON for Modern C++\n// | | |__ | | | | | | version 3.11"
},
{
"path": "Libs/nlohmann/detail/iterators/iterator_traits.hpp",
"chars": 1757,
"preview": "// __ _____ _____ _____\n// __| | __| | | | JSON for Modern C++\n// | | |__ | | | | | | version 3.11"
},
{
"path": "Libs/nlohmann/detail/iterators/json_reverse_iterator.hpp",
"chars": 3861,
"preview": "// __ _____ _____ _____\n// __| | __| | | | JSON for Modern C++\n// | | |__ | | | | | | version 3.11"
},
{
"path": "Libs/nlohmann/detail/iterators/primitive_iterator.hpp",
"chars": 3227,
"preview": "// __ _____ _____ _____\n// __| | __| | | | JSON for Modern C++\n// | | |__ | | | | | | version 3.11"
},
{
"path": "Libs/nlohmann/detail/json_custom_base_class.hpp",
"chars": 1178,
"preview": "// __ _____ _____ _____\n// __| | __| | | | JSON for Modern C++\n// | | |__ | | | | | | version 3.11"
},
{
"path": "Libs/nlohmann/detail/json_pointer.hpp",
"chars": 37143,
"preview": "// __ _____ _____ _____\n// __| | __| | | | JSON for Modern C++\n// | | |__ | | | | | | version 3.11"
},
{
"path": "Libs/nlohmann/detail/json_ref.hpp",
"chars": 1811,
"preview": "// __ _____ _____ _____\n// __| | __| | | | JSON for Modern C++\n// | | |__ | | | | | | version 3.11"
},
{
"path": "Libs/nlohmann/detail/macro_scope.hpp",
"chars": 43639,
"preview": "// __ _____ _____ _____\n// __| | __| | | | JSON for Modern C++\n// | | |__ | | | | | | version 3.11"
},
{
"path": "Libs/nlohmann/detail/macro_unscope.hpp",
"chars": 1252,
"preview": "// __ _____ _____ _____\n// __| | __| | | | JSON for Modern C++\n// | | |__ | | | | | | version 3.11"
},
{
"path": "Libs/nlohmann/detail/meta/call_std/begin.hpp",
"chars": 453,
"preview": "// __ _____ _____ _____\n// __| | __| | | | JSON for Modern C++\n// | | |__ | | | | | | version 3.11"
},
{
"path": "Libs/nlohmann/detail/meta/call_std/end.hpp",
"chars": 451,
"preview": "// __ _____ _____ _____\n// __| | __| | | | JSON for Modern C++\n// | | |__ | | | | | | version 3.11"
},
{
"path": "Libs/nlohmann/detail/meta/cpp_future.hpp",
"chars": 5178,
"preview": "// __ _____ _____ _____\n// __| | __| | | | JSON for Modern C++\n// | | |__ | | | | | | version 3.11"
},
{
"path": "Libs/nlohmann/detail/meta/detected.hpp",
"chars": 2109,
"preview": "// __ _____ _____ _____\n// __| | __| | | | JSON for Modern C++\n// | | |__ | | | | | | version 3.11"
},
{
"path": "Libs/nlohmann/detail/meta/identity_tag.hpp",
"chars": 526,
"preview": "// __ _____ _____ _____\n// __| | __| | | | JSON for Modern C++\n// | | |__ | | | | | | version 3.11"
},
{
"path": "Libs/nlohmann/detail/meta/is_sax.hpp",
"chars": 6960,
"preview": "// __ _____ _____ _____\n// __| | __| | | | JSON for Modern C++\n// | | |__ | | | | | | version 3.11"
},
{
"path": "Libs/nlohmann/detail/meta/std_fs.hpp",
"chars": 766,
"preview": "// __ _____ _____ _____\n// __| | __| | | | JSON for Modern C++\n// | | |__ | | | | | | version 3.11"
},
{
"path": "Libs/nlohmann/detail/meta/type_traits.hpp",
"chars": 29454,
"preview": "// __ _____ _____ _____\n// __| | __| | | | JSON for Modern C++\n// | | |__ | | | | | | version 3.11"
},
{
"path": "Libs/nlohmann/detail/meta/void_t.hpp",
"chars": 597,
"preview": "// __ _____ _____ _____\n// __| | __| | | | JSON for Modern C++\n// | | |__ | | | | | | version 3.11"
},
{
"path": "Libs/nlohmann/detail/output/binary_writer.hpp",
"chars": 71152,
"preview": "// __ _____ _____ _____\n// __| | __| | | | JSON for Modern C++\n// | | |__ | | | | | | version 3.11"
},
{
"path": "Libs/nlohmann/detail/output/output_adapters.hpp",
"chars": 4067,
"preview": "// __ _____ _____ _____\n// __| | __| | | | JSON for Modern C++\n// | | |__ | | | | | | version 3.11"
},
{
"path": "Libs/nlohmann/detail/output/serializer.hpp",
"chars": 40162,
"preview": "// __ _____ _____ _____\n// __| | __| | | | JSON for Modern C++\n// | | |__ | | | | | | version 3.11"
},
{
"path": "Libs/nlohmann/detail/string_concat.hpp",
"chars": 5951,
"preview": "// __ _____ _____ _____\n// __| | __| | | | JSON for Modern C++\n// | | |__ | | | | | | version 3.11"
},
{
"path": "Libs/nlohmann/detail/string_escape.hpp",
"chars": 2168,
"preview": "// __ _____ _____ _____\n// __| | __| | | | JSON for Modern C++\n// | | |__ | | | | | | version 3.11"
},
{
"path": "Libs/nlohmann/detail/value_t.hpp",
"chars": 4326,
"preview": "// __ _____ _____ _____\n// __| | __| | | | JSON for Modern C++\n// | | |__ | | | | | | version 3.11"
},
{
"path": "Libs/nlohmann/json.hpp",
"chars": 198672,
"preview": "// __ _____ _____ _____\n// __| | __| | | | JSON for Modern C++\n// | | |__ | | | | | | version 3.11"
},
{
"path": "Libs/nlohmann/json_fwd.hpp",
"chars": 2541,
"preview": "// __ _____ _____ _____\n// __| | __| | | | JSON for Modern C++\n// | | |__ | | | | | | version 3.11"
},
{
"path": "Libs/nlohmann/ordered_map.hpp",
"chars": 11692,
"preview": "// __ _____ _____ _____\n// __| | __| | | | JSON for Modern C++\n// | | |__ | | | | | | version 3.11"
},
{
"path": "Libs/nlohmann/thirdparty/hedley/hedley.hpp",
"chars": 86068,
"preview": "#pragma once\n\n// __ _____ _____ _____\n// __| | __| | | | JSON for Modern C++\n// | | |__ | | | | | |"
},
{
"path": "Libs/nlohmann/thirdparty/hedley/hedley_undef.hpp",
"chars": 5500,
"preview": "// __ _____ _____ _____\n// __| | __| | | | JSON for Modern C++\n// | | |__ | | | | | | version 3.11"
},
{
"path": "README.md",
"chars": 2281,
"preview": "# JonMon v2.0\nJonMon is a research project I started to help me learn how to code and understand telemetry mechanisms. I"
},
{
"path": "deployment/Azure/README.md",
"chars": 6800,
"preview": "# Deploy JonMon in Azure\n\n[
About this extraction
This page contains the full source code of the jsecurity101/JonMon GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 87 files (1.4 MB), approximately 367.1k tokens, and a symbol index with 578 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.