diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
new file mode 100644
index 0000000..fc955b1
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -0,0 +1,32 @@
+---
+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
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
new file mode 100644
index 0000000..1857548
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -0,0 +1,20 @@
+---
+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.
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..d1d96e7
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,405 @@
+# 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
+
+# End of https://www.toptal.com/developers/gitignore/api/visualstudio
\ No newline at end of file
diff --git a/Extensions/Extension1/JonMon-Ext1/JonMon-Ext1.vcxproj b/Extensions/Extension1/JonMon-Ext1/JonMon-Ext1.vcxproj
new file mode 100644
index 0000000..0957984
--- /dev/null
+++ b/Extensions/Extension1/JonMon-Ext1/JonMon-Ext1.vcxproj
@@ -0,0 +1,158 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ 16.0
+ Win32Proj
+ {bd72f0c3-dbd8-4ba2-8ff9-7f357f9232b1}
+ JonMonExt1
+ 10.0
+
+
+
+ DynamicLibrary
+ true
+ v143
+ Unicode
+
+
+ DynamicLibrary
+ false
+ v143
+ true
+ Unicode
+
+
+ DynamicLibrary
+ true
+ v143
+ Unicode
+
+
+ DynamicLibrary
+ false
+ v143
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Level3
+ true
+ WIN32;_DEBUG;JONMONEXT1_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
+ true
+ Use
+ pch.h
+
+
+ Windows
+ true
+ false
+
+
+
+
+ Level3
+ true
+ true
+ true
+ WIN32;NDEBUG;JONMONEXT1_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
+ true
+ Use
+ pch.h
+
+
+ Windows
+ true
+ true
+ true
+ false
+
+
+
+
+ Level3
+ true
+ _DEBUG;JONMONEXT1_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
+ true
+ Use
+ pch.h
+
+
+ Windows
+ true
+ false
+
+
+
+
+ Level3
+ true
+ true
+ true
+ NDEBUG;JONMONEXT1_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
+ true
+ Use
+ pch.h
+
+
+ Windows
+ true
+ true
+ true
+ false
+
+
+
+
+
+
+
+
+
+
+ Create
+ Create
+ Create
+ Create
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Extensions/Extension1/JonMon-Ext1/JonMon-Ext1.vcxproj.filters b/Extensions/Extension1/JonMon-Ext1/JonMon-Ext1.vcxproj.filters
new file mode 100644
index 0000000..0db63f1
--- /dev/null
+++ b/Extensions/Extension1/JonMon-Ext1/JonMon-Ext1.vcxproj.filters
@@ -0,0 +1,36 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+
\ No newline at end of file
diff --git a/Extensions/Extension1/JonMon-Ext1/dllmain.cpp b/Extensions/Extension1/JonMon-Ext1/dllmain.cpp
new file mode 100644
index 0000000..dea87b4
--- /dev/null
+++ b/Extensions/Extension1/JonMon-Ext1/dllmain.cpp
@@ -0,0 +1,410 @@
+//
+// 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
+#include
+#include
+#include "tlhelp32.h"
+#include "sddl.h"
+#include "dllmain.h"
+
+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, std::wstring *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
+
+ //ConvertSidToStringSidW(pIntegritySid, pStringSid);
+
+ //
+ // switch statement to determine integrity level
+ //
+ switch (*GetSidSubAuthority(pIntegritySid, (DWORD)(UCHAR)(*GetSidSubAuthorityCount(pIntegritySid) - 1)))
+ {
+ case SECURITY_MANDATORY_UNTRUSTED_RID:
+ {
+ *IntegrityLevel = L"UNTRUSTED";
+ break;
+ }
+ case SECURITY_MANDATORY_LOW_RID:
+ {
+ *IntegrityLevel = L"LOW";
+ break;
+ }
+ case SECURITY_MANDATORY_MEDIUM_RID:
+ {
+ *IntegrityLevel = L"MEDIUM";
+ break;
+ }
+ case SECURITY_MANDATORY_HIGH_RID:
+ {
+ *IntegrityLevel = L"HIGH";
+ break;
+ }
+ case SECURITY_MANDATORY_SYSTEM_RID:
+ {
+ *IntegrityLevel = L"SYSTEM";
+ break;
+ }
+ default:
+ {
+ *IntegrityLevel = L"UNKNOWN";
+ break;
+ }
+ }
+
+Exit:
+ //
+ // Free resources
+ //
+ if (pIntegrityLabel != nullptr)
+ {
+ LocalFree(pIntegrityLabel);
+ }
+
+ return retValue;
+}
+
+DWORD TokenUserName(HANDLE hToken, LPWSTR* pStringSid)
+{
+ DWORD retValue = 0;
+ PTOKEN_USER pTokenUser = 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;
+ //
+ // pull thread tokens user
+ //
+
+ 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
+ pTokenUser = (PTOKEN_USER)LocalAlloc(LPTR, dwTokenInfoSize);
+ if (pTokenUser == NULL)
+ {
+ printf("Memory allocation failed\n");
+ retValue = 1;
+ goto Exit;
+ }
+
+ // Get the TOKEN_USER structure
+ if (!GetTokenInformation(hToken, TokenUser, pTokenUser, dwTokenInfoSize, &dwTokenInfoSize))
+ {
+ printf("GetTokenInformation failed (%d)\n", GetLastError());
+ retValue = 1;
+ goto Exit;
+ }
+
+ // Extract the user SID from the TOKEN_USER structure
+ pUserSid = pTokenUser->User.Sid;
+
+ //
+ // Convert SID to actual username
+ //
+
+
+ // 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 (pTokenUser != NULL)
+ {
+ LocalFree(pTokenUser);
+ }
+ if (lpName != NULL)
+ {
+ LocalFree(lpName);
+ }
+ if (lpDomain != NULL)
+ {
+ LocalFree(lpDomain);
+ }
+ return retValue;
+}
+
+extern "C" void TokenImpersonationCheck()
+{
+ //
+ // 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 pToken = NULL;
+ HANDLE pHandle = NULL;
+ DWORD retValue = 0;
+ TOKEN_STATISTICS tokenStats;
+ DWORD dwReturnLength;
+ LPWSTR uTokenUser = NULL;
+ LPWSTR pTokenUser = NULL;
+ std::wstring tIntegrityLevel;
+ std::wstring prIntegrityLevel;
+ SYSTEMTIME filetime;
+ 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))
+ {
+ //printf("OpenThreadToken failed (%d)\n", GetLastError());
+ goto Exit;
+ }
+
+ retValue = IntegritySID(hToken, &tIntegrityLevel);
+ 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, &uTokenUser);
+ if (retValue != 0 || uTokenUser == 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, &pToken);
+ if (pToken == NULL) {
+ printf("OpenProcessToken failed (%d) ProcessId: %d\n", GetLastError(), te32.th32OwnerProcessID);
+ goto Exit;
+ }
+
+ retValue = IntegritySID(pToken, &prIntegrityLevel);
+ if (retValue != 0)
+ {
+ printf("IntegritySID failed (%d)\n", GetLastError());
+ goto Exit;
+ }
+
+ retValue = TokenUserName(pToken, &pTokenUser);
+ if (retValue != 0 || pTokenUser == NULL)
+ {
+ goto Exit;
+ }
+
+ if ((prIntegrityLevel != L"SYSTEM") && (wcscmp(pTokenUser, uTokenUser) != 0)) {
+
+ FILETIME st;
+ GetSystemTimeAsFileTime(&st);
+
+ EventRegister(&JonMonProvider,
+ NULL,
+ NULL,
+ &RegistrationHandle
+ );
+ EVENT_DATA_DESCRIPTOR EventData[7];
+ //
+ //Write events
+ //
+ EventDataDescCreate(&EventData[0], &st, sizeof(st));
+ EventDataDescCreate(&EventData[1], &te32.th32OwnerProcessID, sizeof(DWORD));
+ EventDataDescCreate(&EventData[2], &te32.th32ThreadID, sizeof(DWORD));
+ EventDataDescCreate(&EventData[3], uTokenUser, (wcslen(uTokenUser) + 1) * sizeof(WCHAR));
+ EventDataDescCreate(&EventData[4], tIntegrityLevel.c_str(), (wcslen(tIntegrityLevel.c_str()) + 1) * sizeof(WCHAR));
+ EventDataDescCreate(&EventData[5], pTokenUser, (wcslen(pTokenUser) + 1) * sizeof(WCHAR));
+ EventDataDescCreate(&EventData[6], prIntegrityLevel.c_str(), (wcslen(prIntegrityLevel.c_str()) + 1) * sizeof(WCHAR));
+ EventWrite(RegistrationHandle, &ThreadTokenImpersonation, 7, EventData);
+ EventUnregister(RegistrationHandle);
+ CloseHandle(&RegistrationHandle);
+ }
+
+
+ Exit:
+ if (uTokenUser != NULL)
+ {
+ LocalFree(uTokenUser);
+ }
+ if (pTokenUser != NULL)
+ {
+ LocalFree(pTokenUser);
+ }
+ if (hThread != NULL)
+ {
+ CloseHandle(hThread);
+ }
+ if (hToken != NULL)
+ {
+ CloseHandle(hToken);
+ }
+ if (pHandle != NULL)
+ {
+ CloseHandle(pHandle);
+ }
+ if (pToken != NULL)
+ {
+ CloseHandle(pToken);
+ }
+
+
+ } while (Thread32Next(hThreadSnap, &te32));
+
+ CloseHandle(hThreadSnap);
+
+ Sleep(5000);
+ }
+
+}
+
diff --git a/Extensions/Extension1/JonMon-Ext1/dllmain.h b/Extensions/Extension1/JonMon-Ext1/dllmain.h
new file mode 100644
index 0000000..4f8f737
--- /dev/null
+++ b/Extensions/Extension1/JonMon-Ext1/dllmain.h
@@ -0,0 +1,19 @@
+#ifdef JONMON_EXPORTS
+#define JONMON_EXPORTS __declspec(dllexport)
+#else
+#define JONMON_EXPORTS __declspec(dllimport)
+#endif
+
+#include "Windows.h"
+#include "evntprov.h"
+#include "stdio.h"
+
+//
+// Export function that will query process tokens
+//
+extern "C" JONMON_EXPORTS void TokenImpersonationCheck();
+
+static GUID JonMonProvider = { 0xd8909c24, 0x5be9, 0x4502, { 0x98, 0xca, 0xab, 0x7b, 0xdc, 0x24, 0x89, 0x9d } };
+
+const EVENT_DESCRIPTOR ThreadTokenImpersonation = { 0x1f, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8000000000000000 };
+#define ThreadTokenImpersonation_value 0x1f
\ No newline at end of file
diff --git a/Extensions/Extension1/JonMon-Ext1/framework.h b/Extensions/Extension1/JonMon-Ext1/framework.h
new file mode 100644
index 0000000..54b83e9
--- /dev/null
+++ b/Extensions/Extension1/JonMon-Ext1/framework.h
@@ -0,0 +1,5 @@
+#pragma once
+
+#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
+// Windows Header Files
+#include
diff --git a/Extensions/Extension1/JonMon-Ext1/pch.cpp b/Extensions/Extension1/JonMon-Ext1/pch.cpp
new file mode 100644
index 0000000..64b7eef
--- /dev/null
+++ b/Extensions/Extension1/JonMon-Ext1/pch.cpp
@@ -0,0 +1,5 @@
+// pch.cpp: source file corresponding to the pre-compiled header
+
+#include "pch.h"
+
+// When you are using pre-compiled headers, this source file is necessary for compilation to succeed.
diff --git a/Extensions/Extension1/JonMon-Ext1/pch.h b/Extensions/Extension1/JonMon-Ext1/pch.h
new file mode 100644
index 0000000..885d5d6
--- /dev/null
+++ b/Extensions/Extension1/JonMon-Ext1/pch.h
@@ -0,0 +1,13 @@
+// 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
diff --git a/JonMon-Service/JonMon-Service.vcxproj b/JonMon-Service/JonMon-Service.vcxproj
new file mode 100644
index 0000000..f286287
--- /dev/null
+++ b/JonMon-Service/JonMon-Service.vcxproj
@@ -0,0 +1,147 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ 16.0
+ Win32Proj
+ {bf810292-3774-41a4-b51e-cef92e26894a}
+ JonMonService
+ 10.0
+
+
+
+ Application
+ true
+ v143
+ Unicode
+
+
+ Application
+ false
+ v143
+ true
+ Unicode
+
+
+ Application
+ true
+ v143
+ Unicode
+
+
+ Application
+ false
+ v143
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Level3
+ true
+ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+
+
+
+
+ Level3
+ true
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+ true
+ true
+
+
+
+
+ Level3
+ true
+ _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+
+
+
+
+ Level3
+ true
+ true
+ true
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ MultiThreadedDebug
+
+
+ Console
+ true
+ true
+ true
+ %(AdditionalDependencies)
+ UseLinkTimeCodeGeneration
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/JonMon-Service/JonMon-Service.vcxproj.filters b/JonMon-Service/JonMon-Service.vcxproj.filters
new file mode 100644
index 0000000..3eda5b0
--- /dev/null
+++ b/JonMon-Service/JonMon-Service.vcxproj.filters
@@ -0,0 +1,45 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
\ No newline at end of file
diff --git a/JonMon-Service/JonMonService.cpp b/JonMon-Service/JonMonService.cpp
new file mode 100644
index 0000000..cd0862e
--- /dev/null
+++ b/JonMon-Service/JonMonService.cpp
@@ -0,0 +1,140 @@
+#include
+#include
+#include
+#include "service.h"
+#include "etwMain.h"
+#pragma comment(lib, "setupapi.lib")
+
+int wmain(int argc, wchar_t* argv[])
+{
+ std::wstring VariantString(argv[1]);
+ 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();
+ }
+ if (VariantString == L"-i") {
+ //Copying resource file to C:\Windows and installing manifest
+ printf("[*] Starting JonMon Installation Process....\n");
+
+ 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();
+
+ LPWSTR CurrentDirectory = new WCHAR[MAX_PATH];
+
+ //Installing JonMonDrv Service:
+ 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");
+ }
+ else {
+ printf("[*] JonMon.sys copied\n");
+ }
+
+ FileCopy = CopyFileW(L"JonMon.inf", L"C:\\Windows\\JonMon.inf", FALSE);
+ if (FileCopy != TRUE) {
+ printf("[-] JonMon.inf did not copy to C:\\Windows\\JonMon.inf\n");
+ }
+ else {
+ printf("[*] JonMon.inf copied\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");
+ InstallHinfSectionW(NULL, NULL, TEXT("DefaultInstall 132 C:\\Windows\\JonMon.inf"), 0);
+ printf("[*] JonMonDrv Service Installed\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");
+ }
+ else {
+ printf("[*] JonMon-Service.exe copied\n");
+ }
+ status = CreateCustomService(L"JonMon", L"C:\\Windows\\JonMon-Service.exe -s", SERVICE_WIN32_OWN_PROCESS); //Need to change this to the actual path of the service
+ if (status != 0) {
+ printf("[-] InstallService Failed");
+ }
+ status = StartCustomService(L"JonMon");
+ if (status != 0) {
+ printf("[-] Failed to start JonMon\n");
+ }
+
+ }
+ 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 (L""), (LPSERVICE_MAIN_FUNCTIONW)ServiceMain },
+ { NULL, NULL }
+ };
+ 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");
+ }
+
+ 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.inf");
+ DeleteFileW(L"C:\\Windows\\System32\\drivers\\JonMon.sys");
+
+ 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");
+ }
+
+ return 0;
+}
\ No newline at end of file
diff --git a/JonMon-Service/context.cpp b/JonMon-Service/context.cpp
new file mode 100644
index 0000000..55f9bba
--- /dev/null
+++ b/JonMon-Service/context.cpp
@@ -0,0 +1,139 @@
+#include
+#include
+#include "context.h"
+#include
+#include
+
+int GetTokenUser(
+ _In_ DWORD ProcessId,
+ _Out_ wchar_t** Username
+) {
+ HANDLE hToken = NULL;
+ HANDLE hProcess = NULL;
+ PTOKEN_USER pTokenUser = NULL;
+ int dwErrorCode = ERROR_SUCCESS;
+ SID_NAME_USE SidType;
+ wchar_t Name[128];
+ wchar_t Domain[128];
+ DWORD cchName = 128;
+ DWORD cchDomain = 128;
+ DWORD dwSize = 0;
+
+ hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, ProcessId);
+ if (hProcess == NULL) {
+ std::cout << "OpenProcess Failed" << std::endl;
+ dwErrorCode = GetLastError();
+ goto Exit;
+ }
+ if (!OpenProcessToken(hProcess, TOKEN_QUERY, &hToken)) {
+ OutputDebugStringW(L"OpenProcessTokenFailed\n");
+ dwErrorCode = GetLastError();
+ goto Exit;
+ }
+
+ GetTokenInformation(hToken, TokenUser, NULL, 0, &dwSize);
+ if (dwSize == 0) {
+ OutputDebugStringW(L"GetTokenInformation Failed\n");
+ dwErrorCode = GetLastError();
+ goto Exit;
+ }
+ pTokenUser = (PTOKEN_USER)LocalAlloc(LPTR, dwSize);
+ if (pTokenUser == NULL) {
+ OutputDebugStringW(L"LocalAlloc Failed\n");
+ dwErrorCode = GetLastError();
+ goto Exit;
+ }
+ if (!GetTokenInformation(hToken, TokenUser, pTokenUser, dwSize, &dwSize)) {
+ OutputDebugStringW(L"GetTokenInformation Failed\n");
+ dwErrorCode = GetLastError();
+ goto Exit;
+ }
+
+ if (!LookupAccountSidW(NULL, pTokenUser->User.Sid, Name, &cchName, Domain, &cchDomain, &SidType)) {
+ OutputDebugStringW(L"LookupAccountSidW Failed\n");
+ dwErrorCode = GetLastError();
+ goto Exit;
+
+ }
+ *Username = new wchar_t[256]; // Adjust the size as needed (512 in this case)
+ wsprintfW(*Username, L"%s\\%s", Domain, Name);
+ if (sizeof(*Username) > 256) {
+ OutputDebugStringW(L"Username is too long\n");
+ goto Exit;
+ }
+
+Exit:
+ if (hToken != NULL) {
+ CloseHandle(hToken);
+ }
+ if (pTokenUser != NULL)
+ {
+ LocalFree(pTokenUser);
+ }
+ if (hProcess != NULL)
+ {
+ CloseHandle(hProcess);
+ }
+ return dwErrorCode;
+}
+
+int GetImagePath(
+ _In_ DWORD ProcessId,
+ _Out_ wchar_t** ImagePath
+) {
+ int dwErrorCode = ERROR_SUCCESS;
+ wchar_t* pImagePath = new wchar_t[MAX_PATH];
+ DWORD dwSize = MAX_PATH;
+
+ HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, ProcessId);
+ if (hProcess == NULL) {
+ std::wcout << L"OpenProcess Failed\n";
+ std::wcout << L"ProcessID " << ProcessId << std::endl;
+ return ERROR_INVALID_HANDLE;
+ }
+
+ // getting image path via GetModuleFileNameEx
+ while (true) {
+ if (GetModuleFileNameEx(hProcess, NULL, pImagePath, MAX_PATH) == 0) {
+ dwErrorCode = GetLastError();
+ if (dwErrorCode == ERROR_INSUFFICIENT_BUFFER) {
+ // The buffer was too small, double the size and try again
+ delete[] pImagePath;
+ dwSize *= 2;
+ pImagePath = new wchar_t[dwSize];
+ if (pImagePath == nullptr) {
+ dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
+ break;
+ }
+ }
+ else {
+ dwErrorCode = GetLastError();
+ break;
+ }
+ }
+ else {
+ break;
+ }
+ }
+
+ if (dwErrorCode == ERROR_SUCCESS) {
+ // Allocate memory for the image path and copy the value to the output parameter
+ size_t nLength = wcslen(pImagePath) + 1;
+ *ImagePath = new wchar_t[nLength];
+ if (*ImagePath == nullptr) {
+ dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
+ }
+ else {
+ wcscpy_s(*ImagePath, nLength, pImagePath);
+ }
+ }
+
+ // Clean up resources
+ if (hProcess != NULL) {
+ CloseHandle(hProcess);
+ }
+ if (pImagePath != NULL) {
+ delete[] pImagePath;
+ }
+ return dwErrorCode;
+}
diff --git a/JonMon-Service/context.h b/JonMon-Service/context.h
new file mode 100644
index 0000000..8897742
--- /dev/null
+++ b/JonMon-Service/context.h
@@ -0,0 +1,12 @@
+#pragma once
+#include
+
+int GetTokenUser(
+ _In_ DWORD ProcessId,
+ _Out_ wchar_t** Username
+);
+
+int GetImagePath(
+ _In_ DWORD ProcessId,
+ _Out_ wchar_t** ImagePath
+);
\ No newline at end of file
diff --git a/JonMon-Service/etwMain.cpp b/JonMon-Service/etwMain.cpp
new file mode 100644
index 0000000..046512b
--- /dev/null
+++ b/JonMon-Service/etwMain.cpp
@@ -0,0 +1,1762 @@
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "global.h"
+#include "context.h"
+#include "etwMain.h"
+#include
+#include
+#include "tlhelp32.h"
+#include
+
+
+#pragma comment(lib, "Ws2_32.lib")
+#pragma comment(lib, "Ws2_32.lib")
+#pragma comment(lib, "tdh.lib")
+#pragma comment(lib, "dbghelp.lib")
+
+DWORD lsassPID = 0;
+
+//
+// Used to process ETW event properties. Plan to remove these and move to TDH functions in the future.
+//
+template
+inline auto GetData(byte*& data) {
+ auto value{ reinterpret_cast(data) };
+ data += sizeof(*value);
+ return value;
+}
+
+inline auto GetWideString(byte*& data) {
+ auto wideString{ reinterpret_cast(data) };
+ data += (wcslen(wideString) + 1) * sizeof(WCHAR);
+ return wideString;
+}
+
+int 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 ProtectionCheck()
+{
+ DWORD protectionLevel = 0;
+ do {
+ PROCESS_PROTECTION_LEVEL_INFORMATION protectionInfo = { 0 };
+ if (GetProcessInformation(GetCurrentProcess(), ProcessProtectionLevelInfo, &protectionInfo, sizeof(protectionInfo))) {
+ if (protectionInfo.ProtectionLevel != 5) {
+ protectionLevel = 1;
+ }
+ }
+ else {
+ printf("Failed to retrieve PPL. Error code: %lu\n", GetLastError());
+ return 1;
+ }
+ } while (protectionLevel == 0);
+ return 0;
+}
+
+void ChangePPL() {
+
+ HANDLE hDevice = CreateFile(L"\\\\.\\JonMon", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
+ if (hDevice == INVALID_HANDLE_VALUE) {
+ printf("Error %u\n", GetLastError());
+ return;
+ }
+ DWORD bytes;
+ HANDLE hProcess;
+ if (DeviceIoControl(hDevice, IOCTL_CHANGE_PROTECTION_LEVEL_PROCESS, NULL, NULL, NULL, NULL, NULL, NULL)) {
+ OutputDebugStringW(L"Protection Level Changed\n");
+ }
+ else {
+ printf("Error: %u\n", GetLastError());
+ }
+
+ CloseHandle(hDevice);
+}
+
+DWORD CheckLSASSPID() {
+ HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
+ PROCESSENTRY32 processEntry = {};
+ processEntry.dwSize = sizeof(PROCESSENTRY32);
+ LPCWSTR processName = L"";
+ DWORD PID = 0;
+
+ if (Process32First(snapshot, &processEntry)) {
+ while (_wcsicmp(processName, L"lsass.exe") != 0) {
+ Process32Next(snapshot, &processEntry);
+ processName = processEntry.szExeFile;
+ PID = processEntry.th32ProcessID;
+
+ }
+ return PID;
+
+ }
+ CloseHandle(snapshot);
+}
+
+int TraceEvent() {
+ //
+ // Changing PPL level
+ //
+ ChangePPL();
+
+ //
+ // check to see if current process is protected
+ //
+ DWORD retValue = ProtectionCheck();
+ if (retValue != 0) {
+ printf("Process is not protected\n");
+ ChangePPL();
+ }
+ lsassPID = CheckLSASSPID();
+ const char name[] = "JonMon";
+ TRACEHANDLE hTrace = 0;
+ ULONG result, bufferSize;
+ EVENT_TRACE_LOGFILEA trace;
+ EVENT_TRACE_PROPERTIES* traceProp;
+
+ memset(&trace, 0, sizeof(EVENT_TRACE_LOGFILEA));
+ trace.ProcessTraceMode = PROCESS_TRACE_MODE_REAL_TIME | PROCESS_TRACE_MODE_EVENT_RECORD;
+ trace.LoggerName = (LPSTR)name;
+ trace.EventRecordCallback = (PEVENT_RECORD_CALLBACK)ProcessEvent;
+
+ bufferSize = sizeof(EVENT_TRACE_PROPERTIES) + sizeof(name) + sizeof(WCHAR);
+
+ traceProp = (EVENT_TRACE_PROPERTIES*)LocalAlloc(LPTR, bufferSize);
+ traceProp->Wnode.BufferSize = bufferSize;
+ traceProp->Wnode.ClientContext = 2;
+ traceProp->Wnode.Guid = JonMonGuid;
+ 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);
+
+ if ((result = StartTraceA(&hTrace, (LPCSTR)name, traceProp)) != ERROR_SUCCESS) {
+ OutputDebugStringW(L"Error starting trace\n");
+ return GetLastError();
+ }
+
+ ENABLE_TRACE_PARAMETERS enableTraceParameters;
+ ZeroMemory(&enableTraceParameters, sizeof(ENABLE_TRACE_PARAMETERS));
+
+ enableTraceParameters.Version = ENABLE_TRACE_PARAMETERS_VERSION_2;
+ enableTraceParameters.EnableProperty = EVENT_ENABLE_PROPERTY_STACK_TRACE;
+
+ OutputDebugString(L"[+] JonMon Trace started\n");
+
+ //RPC Events
+ if ((result = EnableTraceEx2(
+ hTrace,
+ &RPC,
+ EVENT_CONTROL_CODE_ENABLE_PROVIDER,
+ TRACE_LEVEL_INFORMATION,
+ 0,
+ 0,
+ 0,
+ &enableTraceParameters
+ )) != ERROR_SUCCESS) {
+ OutputDebugString(L"[!] Error EnableTraceEx - RPC\n");
+ }
+
+ //Threat Intel
+ if ((result = EnableTraceEx2(
+ hTrace,
+ &ThreatIntel,
+ EVENT_CONTROL_CODE_ENABLE_PROVIDER,
+ TRACE_LEVEL_INFORMATION,
+ 0,
+ 0,
+ 0,
+ &enableTraceParameters
+ )) != ERROR_SUCCESS) {
+ OutputDebugString(L"[!] Error EnableTraceEx - Threat Intel\n");
+ }
+
+ //WMI Events
+ if ((result = EnableTraceEx2(
+ hTrace,
+ &WMIActivty,
+ EVENT_CONTROL_CODE_ENABLE_PROVIDER,
+ TRACE_LEVEL_INFORMATION,
+ 0,
+ 0,
+ 0,
+ &enableTraceParameters
+ )) != ERROR_SUCCESS) {
+ OutputDebugString(L"[!] Error EnableTraceEx - WMI\n");
+ }
+
+ //DotNet Events
+ if ((result = EnableTraceEx2(
+ hTrace,
+ &DotNet,
+ EVENT_CONTROL_CODE_ENABLE_PROVIDER,
+ TRACE_LEVEL_INFORMATION,
+ 0x8,
+ 0,
+ 0,
+ NULL
+ )) != ERROR_SUCCESS) {
+ OutputDebugString(L"[!] Error EnableTraceEx - DotNet\n");
+ }
+
+ //Network Events
+ if ((result = EnableTraceEx(
+ &Network,
+ nullptr,
+ hTrace,
+ TRUE,
+ TRACE_LEVEL_INFORMATION,
+ 0,
+ 0,
+ 0,
+ NULL
+ )) != ERROR_SUCCESS) {
+ OutputDebugString(L"[!] Error EnableTraceEx - Network\n");
+ }
+
+ //Task Scheduler Events
+ if ((result = EnableTraceEx(
+ &TaskSched,
+ nullptr,
+ hTrace,
+ TRUE,
+ TRACE_LEVEL_INFORMATION,
+ 0,
+ 0,
+ 0,
+ NULL
+ )) != ERROR_SUCCESS) {
+ OutputDebugString(L"[!] Error EnableTraceEx - TaskSched\n");
+ }
+
+ //AMSI Events
+ if ((result = EnableTraceEx(
+ &AMSI,
+ nullptr,
+ hTrace,
+ TRUE,
+ TRACE_LEVEL_INFORMATION,
+ 0,
+ 0,
+ 0,
+ NULL
+ )) != ERROR_SUCCESS) {
+ OutputDebugString(L"[!] Error EnableTraceEx - AMSI\n");
+ }
+
+ if ((result = EnableTraceEx(
+ &DPAPI,
+ nullptr,
+ hTrace,
+ TRUE,
+ TRACE_LEVEL_INFORMATION,
+ 0,
+ 0,
+ 0,
+ NULL
+ )) != ERROR_SUCCESS) {
+ OutputDebugString(L"[!] Error EnableTraceEx - DPAPI\n");
+ }
+
+ hTrace = OpenTraceA(&trace);
+ if (hTrace == INVALID_PROCESSTRACE_HANDLE) {
+ OutputDebugString(L"[!] Error OpenTrace\n");
+ return 1;
+ }
+
+ result = ProcessTrace(&hTrace, 1, NULL, NULL);
+ if (result != ERROR_SUCCESS) {
+ printf("[!] Error ProcessTrace\n");
+ return 1;
+ }
+}
+
+/*
+* -----------------------------
+* Event Processessing Functions
+* -----------------------------
+*/
+
+void ProcessEvent(
+ _In_ PEVENT_RECORD EventRecord
+) {
+ PEVENT_HEADER eventHeader = &EventRecord->EventHeader;
+ PEVENT_DESCRIPTOR eventDescriptor = &eventHeader->EventDescriptor;
+ NTSTATUS status;
+
+ if (eventHeader->ProviderId == ThreatIntel) {
+ status = WriteThreatIntelEvents(EventRecord, eventHeader);
+ }
+ if (eventHeader->ProviderId == RPC) {
+ switch (eventDescriptor->Id) {
+ case 5:
+ {
+ auto data{ reinterpret_cast(EventRecord->UserData) };
+ BOOL result = RpcEvent(EventRecord, eventHeader, RPCClientCall);
+
+ break;
+ }
+ case 6:
+ {
+ auto data{ reinterpret_cast(EventRecord->UserData) };
+ BOOL result = RpcEvent(EventRecord, eventHeader, RPCServerCall);
+ break;
+ }
+ default: {
+ break;
+ }
+
+ }
+ }
+ if (eventHeader->ProviderId == Network) {
+ switch (eventDescriptor->Id) {
+ case 10:
+ {
+ auto data{ reinterpret_cast(EventRecord->UserData) };
+ const wchar_t* Initiated = L"True";
+ BOOL result = WriteNetworkEvents(EventRecord, eventHeader, (wchar_t*)Initiated);
+ break;
+ }
+ case 11:
+ {
+ const wchar_t* Initiated = L"False";
+ auto data{ reinterpret_cast(EventRecord->UserData) };
+ BOOL result = WriteNetworkEvents(EventRecord, eventHeader, (wchar_t*)Initiated);
+ break;
+ }
+ default: {
+ break;
+ }
+
+ }
+ }
+ if (eventHeader->ProviderId == DotNet) {
+ switch (eventDescriptor->Id) {
+ case 154: {
+ auto data{ reinterpret_cast(EventRecord->UserData) };
+ //printf("DotNet AssemblyLoad Event from PID %d\n", eventHeader->ProcessId);
+ WriteDotNetEvents(EventRecord, eventHeader);
+ }
+
+ default: {
+ break;
+ }
+ }
+ }
+ if (eventHeader->ProviderId == AMSI) {
+ BOOL res = WriteAMSIEvents(EventRecord, eventHeader);
+
+ }
+ if (eventHeader->ProviderId == TaskSched) {
+ BOOL res = WriteTaskSchedEvents(EventRecord, eventHeader);
+ }
+ if (eventHeader->ProviderId == WMIActivty) {
+ BOOL res = WriteWMIEvents(EventRecord, eventHeader);
+ }
+ if (eventHeader->ProviderId == DPAPI) {
+ BOOL res = DPAPIEvents(EventRecord, eventHeader);
+ }
+}
+
+NTSTATUS WriteETWEvents(
+ _In_ PEVENT_DATA_DESCRIPTOR eventData,
+ _In_ EVENT_DESCRIPTOR eventDescriptor,
+ _In_ int metaDataSize
+) {
+ REGHANDLE RegistrationHandle = NULL;
+ NTSTATUS status = EventRegister(
+ &JonMonGuid,
+ NULL,
+ NULL,
+ &RegistrationHandle
+ );
+ if (status != ERROR_SUCCESS)
+ {
+ return status;
+ }
+ status = EventWrite(
+ RegistrationHandle,
+ &eventDescriptor,
+ metaDataSize,
+ eventData
+ );
+ if (status != ERROR_SUCCESS)
+ {
+ EventUnregister(RegistrationHandle);
+ return status;
+ }
+
+ //CleanUp
+ EventUnregister(RegistrationHandle);
+}
+
+NTSTATUS WriteThreatIntelEvents(
+ _In_ PEVENT_RECORD EventRecord,
+ _In_ PEVENT_HEADER EventHeader
+) {
+ PEVENT_HEADER eventHeader = &EventRecord->EventHeader;
+ PEVENT_HEADER_EXTENDED_DATA_ITEM extendedData = EventRecord->ExtendedData;
+ PEVENT_DESCRIPTOR eventDescriptor = &eventHeader->EventDescriptor;
+ NTSTATUS status = ERROR_SUCCESS;
+ REGHANDLE RegistrationHandle = NULL;
+ HANDLE hProcess = GetCurrentProcess();
+ wchar_t* sourceImagePath = nullptr;
+ wchar_t* targetImagePath = nullptr;
+ std::wstring ImagePath_str;
+ std::wstring targetImagePath_str;
+ wchar_t* CallStack = nullptr;
+ static UINT32 prevCallingProcessId = 0;
+ static UINT32 prevTargetProcessId = 0;
+ switch (eventHeader->EventDescriptor.Id) {
+ case 1:
+ {
+ auto data{ reinterpret_cast(EventRecord->UserData) };
+ auto CallingProcessId{ GetData(data) };
+ auto CallingProcessCreationTime{ GetData(data) };
+ auto CallingProcessStartKey{ GetData(data) };
+ auto CallingProcessSignatureLevel{ GetData(data) };
+ auto CallingProcessSectionSignatureLevel{ GetData(data) };
+ auto CallingProcessProtection{ GetData(data) };
+ auto CallingThreadId{ GetData(data) };
+ auto CallingThreadCreationTime{ GetData(data) };
+ auto TargetProcessId{ GetData(data) };
+ auto TargetProcessCreateTime{ GetData(data) };
+ auto TargetProcessStartKey{ GetData(data) };
+ auto TargetProcessSignatureLevel{ GetData(data) };
+ auto TargetProcessSectionSignatureLevel{ GetData(data) };
+ auto TargetProcessProtection{ GetData(data) };
+ auto OriginalProcessId{ GetData(data) };
+ auto OriginalProcessCreateTime{ GetData(data) };
+ auto OriginalProcessStartKey{ GetData(data) };
+ auto OriginalProcessSignatureLevel{ GetData(data) };
+ auto OriginalProcessProtection{ GetData(data) };
+ auto BaseAddress{ GetData(data) };
+
+ if (*CallingProcessId == *TargetProcessId) {
+ goto Exit;
+ }
+
+ if (GetImagePath(*CallingProcessId, &sourceImagePath) != ERROR_SUCCESS) {
+ ImagePath_str = L"Unknown";
+ }
+ else {
+ ImagePath_str = sourceImagePath;
+ }
+ if (GetImagePath(*TargetProcessId, &targetImagePath) != ERROR_SUCCESS) {
+ targetImagePath_str = L"Unknown";
+ }
+ else {
+ targetImagePath_str = targetImagePath;
+ }
+
+ CallStack = GetCallStack(EventRecord, extendedData, hProcess);
+
+ FILETIME st;
+ GetSystemTimeAsFileTime(&st);
+
+ EVENT_DATA_DESCRIPTOR EventData[11];
+ EventDataDescCreate(&EventData[0], &st, sizeof(st));
+ EventDataDescCreate(&EventData[1], CallingThreadId, 4);
+ EventDataDescCreate(&EventData[2], CallingProcessId, 4);
+ EventDataDescCreate(&EventData[3], TargetProcessId, 4);
+ EventDataDescCreate(&EventData[4], CallingProcessStartKey, 8);
+ EventDataDescCreate(&EventData[5], TargetProcessStartKey, 8);
+ EventDataDescCreate(&EventData[6], OriginalProcessId, 4);
+ EventDataDescCreate(&EventData[7], BaseAddress, sizeof(BaseAddress));
+ EventDataDescCreate(&EventData[8], ImagePath_str.c_str(), (wcslen(ImagePath_str.c_str()) + 1) * sizeof(WCHAR));
+ EventDataDescCreate(&EventData[9], targetImagePath_str.c_str(), (wcslen(targetImagePath_str.c_str()) + 1) * sizeof(WCHAR));
+ EventDataDescCreate(&EventData[10], CallStack, (wcslen(CallStack) + 1) * sizeof(WCHAR));
+
+
+
+ status = WriteETWEvents(EventData, TIRemoteAllocateVirtualMemory, 11);
+ goto Exit;
+ }
+ case 4:
+ {
+
+ FILETIME st;
+ GetSystemTimeAsFileTime(&st);
+
+ PTRACE_EVENT_INFO pInfo = NULL;
+ DWORD bufferSize = 0;
+
+ UINT32 CallingThreadId, CallingProcessId, TargetProcessId, OriginalProcessId, TargetThreadId;
+ UINT64 CallingProcessStartKey, TargetProcessStartKey, ApcRoutine, ApcArgument1;
+ DWORD status = ERROR_SUCCESS;
+
+ //
+ // Testing out TDH APIs
+ //
+
+ status = TdhGetEventInformation(EventRecord, 0, NULL, pInfo, &bufferSize);
+ if (ERROR_INSUFFICIENT_BUFFER == status) {
+ pInfo = (PTRACE_EVENT_INFO)malloc(bufferSize);
+ if (pInfo == NULL) {
+ // Handle allocation failure
+ OutputDebugString(L"[!] Error allocating memory for event info\n");
+ goto Exit;
+ }
+
+ // Get the event info
+ status = TdhGetEventInformation(EventRecord, 0, NULL, pInfo, &bufferSize);
+ }
+
+ if (ERROR_SUCCESS != status) {
+ // Handle error (could not obtain event info)
+ free(pInfo);
+ OutputDebugString(L"[!] Error getting event info\n");
+ goto Exit;
+ }
+ 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) {
+ // Handle error
+ wprintf(L"Error getting size for property %ls\n", propertyName);
+ continue;
+ }
+
+ BYTE* propertyData = (BYTE*)malloc(propertySize);
+ if (!propertyData) {
+ // Handle allocation failure
+ wprintf(L"Error allocating memory for property %ls\n", propertyName);
+ continue;
+ }
+
+ // Get the property data
+ status = TdhGetProperty(EventRecord, 0, NULL, 1, &dataDescriptor, propertySize, propertyData);
+ if (status != ERROR_SUCCESS) {
+ // Handle error
+ wprintf(L"Error getting data for property %ls\n", propertyName);
+ free(propertyData);
+ continue;
+ }
+ switch (i) {
+ case 0:
+ {
+ CallingProcessId = *(UINT32*)propertyData;
+ break;
+ }
+ case 2:
+ {
+ CallingProcessStartKey = *(UINT64*)propertyData;
+ break;
+ }
+ case 6:
+ {
+ CallingThreadId = *(UINT32*)propertyData;
+ break;
+ }
+ case 8:
+ {
+ TargetProcessId = *(UINT32*)propertyData;
+ break;
+ }
+ case 10:
+ {
+ TargetProcessStartKey = *(UINT64*)propertyData;
+ break;
+ }
+ case 14:
+ {
+ TargetThreadId = *(UINT32*)propertyData;
+ }
+ case 16:
+ {
+ OriginalProcessId = *(UINT32*)propertyData;
+ break;
+ }
+ case 21:
+ {
+ ApcRoutine = *(UINT64*)propertyData;
+ break;
+ }
+ case 22:
+ {
+ ApcArgument1 = *(UINT64*)propertyData;
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ free(propertyData);
+
+ }
+
+ if (GetImagePath(CallingProcessId, &sourceImagePath) != ERROR_SUCCESS) {
+ ImagePath_str = L"Unknown";
+ }
+ else {
+ ImagePath_str = sourceImagePath;
+ }
+ if (GetImagePath(TargetProcessId, &targetImagePath) != ERROR_SUCCESS) {
+ targetImagePath_str = L"Unknown";
+ }
+ else {
+ targetImagePath_str = targetImagePath;
+ }
+
+ CallStack = GetCallStack(EventRecord, extendedData, hProcess);
+
+ EVENT_DATA_DESCRIPTOR EventData[13];
+ EventDataDescCreate(&EventData[0], &st, sizeof(st));
+ EventDataDescCreate(&EventData[1], &CallingThreadId, 4);
+ EventDataDescCreate(&EventData[2], &CallingProcessId, 4);
+ EventDataDescCreate(&EventData[3], &TargetProcessId, 4);
+ EventDataDescCreate(&EventData[4], &TargetThreadId, 4);
+ EventDataDescCreate(&EventData[5], &CallingProcessStartKey, 8);
+ EventDataDescCreate(&EventData[6], &TargetProcessStartKey, 8);
+ EventDataDescCreate(&EventData[7], &OriginalProcessId, 4);
+ EventDataDescCreate(&EventData[8], &ApcRoutine, sizeof(ApcRoutine));
+ EventDataDescCreate(&EventData[9], &ApcArgument1, sizeof(ApcArgument1));
+ EventDataDescCreate(&EventData[10], ImagePath_str.c_str(), (wcslen(ImagePath_str.c_str()) + 1) * sizeof(WCHAR));
+ EventDataDescCreate(&EventData[11], targetImagePath_str.c_str(), (wcslen(targetImagePath_str.c_str()) + 1) * sizeof(WCHAR));
+ EventDataDescCreate(&EventData[12], CallStack, (wcslen(CallStack) + 1) * sizeof(WCHAR));
+
+
+ status = WriteETWEvents(EventData, TIQueueUserAPCEvent, 13);
+ goto Exit;
+ }
+ case 6:
+ {
+ auto data{ reinterpret_cast(EventRecord->UserData) };
+ auto CallingProcessId{ GetData(data) };
+ auto CallingProcessCreationTime{ GetData(data) };
+ auto CallingProcessStartKey{ GetData(data) };
+ auto CallingProcessSignatureLevel{ GetData(data) };
+ auto CallingProcessSectionSignatureLevel{ GetData(data) };
+ auto CallingProcessProtection{ GetData(data) };
+ auto CallingThreadId{ GetData(data) };
+ auto CallingThreadCreationTime{ GetData(data) };
+ auto TargetProcessId{ GetData(data) };
+ auto TargetProcessCreateTime{ GetData(data) };
+ auto TargetProcessStartKey{ GetData(data) };
+ auto TargetProcessSignatureLevel{ GetData(data) };
+ auto TargetProcessSectionSignatureLevel{ GetData(data) };
+ auto TargetProcessProtection{ GetData(data) };
+ auto OriginalProcessId{ GetData(data) };
+ auto OriginalProcessCreateTime{ GetData(data) };
+ auto OriginalProcessStartKey{ GetData(data) };
+ auto OriginalProcessSignatureLevel{ GetData(data) };
+ auto OriginalProcessProtection{ GetData(data) };
+ auto BaseAddress{ GetData(data) };
+
+ if (*CallingProcessId == *TargetProcessId) {
+ goto Exit;
+ }
+
+ if (GetImagePath(*CallingProcessId, &sourceImagePath) != ERROR_SUCCESS) {
+ ImagePath_str = L"Unknown";
+ }
+ else {
+ ImagePath_str = sourceImagePath;
+ }
+ if (GetImagePath(*TargetProcessId, &targetImagePath) != ERROR_SUCCESS) {
+ targetImagePath_str = L"Unknown";
+ }
+ else {
+ targetImagePath_str = targetImagePath;
+ }
+
+ CallStack = GetCallStack(EventRecord, extendedData, hProcess);
+
+ FILETIME st;
+ GetSystemTimeAsFileTime(&st);
+
+
+ EVENT_DATA_DESCRIPTOR EventData[11];
+ EventDataDescCreate(&EventData[0], &st, sizeof(st));
+ EventDataDescCreate(&EventData[1], CallingThreadId, 4);
+ EventDataDescCreate(&EventData[2], CallingProcessId, 4);
+ EventDataDescCreate(&EventData[3], TargetProcessId, 4);
+ EventDataDescCreate(&EventData[4], CallingProcessStartKey, 8);
+ EventDataDescCreate(&EventData[5], TargetProcessStartKey, 8);
+ EventDataDescCreate(&EventData[6], OriginalProcessId, 4);
+ EventDataDescCreate(&EventData[7], BaseAddress, sizeof(BaseAddress));
+ EventDataDescCreate(&EventData[8], ImagePath_str.c_str(), (wcslen(ImagePath_str.c_str()) + 1) * sizeof(WCHAR));
+ EventDataDescCreate(&EventData[9], targetImagePath_str.c_str(), (wcslen(targetImagePath_str.c_str()) + 1) * sizeof(WCHAR));
+ EventDataDescCreate(&EventData[10], CallStack, (wcslen(CallStack) + 1) * sizeof(WCHAR));
+
+
+
+ status = WriteETWEvents(EventData, TIRemoteAllocateVirtualMemory, 11);
+ goto Exit;
+ }
+ case 13:
+ {
+ auto data{ reinterpret_cast(EventRecord->UserData) };
+ auto OperationStatus{ GetData(data) };
+ auto CallingProcessId{ GetData(data) };
+ auto CallingProcessCreationTime{ GetData(data) };
+ auto CallingProcessStartKey{ GetData(data) };
+ auto CallingProcessSignatureLevel{ GetData(data) };
+ auto CallingProcessSectionSignatureLevel{ GetData(data) };
+ auto CallingProcessProtection{ GetData(data) };
+ auto CallingThreadId{ GetData(data) };
+ auto CallingThreadCreationTime{ GetData(data) };
+ auto TargetProcessId{ GetData(data) };
+ auto TargetProcessCreationTime{ GetData(data) };
+ auto TargetProcessStartKey{ GetData(data) };
+
+ FILETIME st;
+ GetSystemTimeAsFileTime(&st);
+
+ CallStack = GetCallStack(EventRecord, extendedData, hProcess);
+
+ //
+ //Getting ImagePath
+ //
+ if (GetImagePath(*CallingProcessId, &sourceImagePath) != ERROR_SUCCESS) {
+ ImagePath_str = L"Unknown";
+ }
+ else {
+ ImagePath_str = sourceImagePath;
+ }
+
+ //
+ //Put C:\Windows\System32\lsass.exe in a variable
+ //
+ std::wstring lsassPath = L"C:\\Windows\\System32\\lsass.exe";
+
+ EVENT_DATA_DESCRIPTOR EventData[9];
+ EventDataDescCreate(&EventData[0], &st, sizeof(st));
+ EventDataDescCreate(&EventData[1], CallingProcessId, 4);
+ EventDataDescCreate(&EventData[2], CallingThreadId, 4);
+ EventDataDescCreate(&EventData[3], ImagePath_str.c_str(), (wcslen(ImagePath_str.c_str()) + 1) * sizeof(WCHAR));
+ EventDataDescCreate(&EventData[4], TargetProcessId, 4);
+ EventDataDescCreate(&EventData[5], lsassPath.c_str(), (wcslen(lsassPath.c_str()) + 1) * sizeof(WCHAR));
+ EventDataDescCreate(&EventData[6], CallingProcessStartKey, sizeof(CallingProcessStartKey));
+ EventDataDescCreate(&EventData[7], TargetProcessStartKey, sizeof(TargetProcessStartKey));
+ EventDataDescCreate(&EventData[8], CallStack, (wcslen(CallStack) + 1) * sizeof(WCHAR));
+
+ NTSTATUS status = WriteETWEvents(EventData, TIReadProcessMemory, 9);
+
+ goto Exit;
+ }
+ case 14:
+ {
+ auto data{ reinterpret_cast(EventRecord->UserData) };
+ auto OperationStatus{ GetData(data) };
+ auto CallingProcessId{ GetData(data) };
+ auto CallingProcessCreationTime{ GetData(data) };
+ auto CallingProcessStartKey{ GetData(data) };
+ auto CallingProcessSignatureLevel{ GetData(data) };
+ auto CallingProcessSectionSignatureLevel{ GetData(data) };
+ auto CallingProcessProtection{ GetData(data) };
+ auto CallingThreadId{ GetData(data) };
+ auto CallingThreadCreationTime{ GetData(data) };
+ auto TargetProcessId{ GetData(data) };
+ auto TargetProcessCreationTime{ GetData(data) };
+ auto TargetProcessStartKey{ GetData(data) };
+
+ FILETIME st;
+ GetSystemTimeAsFileTime(&st);
+
+ CallStack = GetCallStack(EventRecord, extendedData, hProcess);
+
+ if (GetImagePath(*CallingProcessId, &sourceImagePath) != ERROR_SUCCESS) {
+ ImagePath_str = L"Unknown";
+ }
+ else {
+ ImagePath_str = sourceImagePath;
+ }
+
+ if (GetImagePath(*TargetProcessId, &targetImagePath) != ERROR_SUCCESS) {
+ targetImagePath_str = L"Unknown";
+ }
+ else {
+ targetImagePath_str = targetImagePath;
+ }
+
+ EVENT_DATA_DESCRIPTOR EventData[9];
+ EventDataDescCreate(&EventData[0], &st, sizeof(st));
+ EventDataDescCreate(&EventData[1], CallingProcessId, 4);
+ EventDataDescCreate(&EventData[2], CallingThreadId, 4);
+ EventDataDescCreate(&EventData[3], ImagePath_str.c_str(), (wcslen(ImagePath_str.c_str()) + 1) * sizeof(WCHAR));
+ EventDataDescCreate(&EventData[4], TargetProcessId, 4);
+ EventDataDescCreate(&EventData[5], targetImagePath_str.c_str(), (wcslen(targetImagePath_str.c_str()) + 1) * sizeof(WCHAR));
+ EventDataDescCreate(&EventData[6], CallingProcessStartKey, sizeof(CallingProcessStartKey));
+ EventDataDescCreate(&EventData[7], TargetProcessStartKey, sizeof(TargetProcessStartKey));
+ EventDataDescCreate(&EventData[8], CallStack, (wcslen(CallStack) + 1) * sizeof(WCHAR));
+ NTSTATUS status = WriteETWEvents(EventData, TIWriteProcessMemory, 9);
+ goto Exit;
+ }
+ case 21:
+ {
+ auto data{ reinterpret_cast(EventRecord->UserData) };
+ auto CallingProcessId{ GetData(data) };
+ auto CallingProcessCreationTime{ GetData(data) };
+ auto CallingProcessStartKey{ GetData(data) };
+ auto CallingProcessSignatureLevel{ GetData(data) };
+ auto CallingProcessSectionSignatureLevel{ GetData(data) };
+ auto CallingProcessProtection{ GetData(data) };
+ auto CallingThreadId{ GetData(data) };
+ auto CallingThreadCreationTime{ GetData(data) };
+ auto TargetProcessId{ GetData(data) };
+ auto TargetProcessCreateTime{ GetData(data) };
+ auto TargetProcessStartKey{ GetData(data) };
+ auto TargetProcessSignatureLevel{ GetData(data) };
+ auto TargetProcessSectionSignatureLevel{ GetData(data) };
+ auto TargetProcessProtection{ GetData(data) };
+ auto OriginalProcessId{ GetData(data) };
+ auto OriginalProcessCreateTime{ GetData(data) };
+ auto OriginalProcessStartKey{ GetData(data) };
+ auto OriginalProcessSignatureLevel{ GetData(data) };
+ auto OriginalProcessProtection{ GetData(data) };
+ auto BaseAddress{ GetData(data) };
+
+ if (*CallingProcessId == *TargetProcessId) {
+ goto Exit;
+ }
+
+ if (GetImagePath(*CallingProcessId, &sourceImagePath) != ERROR_SUCCESS) {
+ ImagePath_str = L"Unknown";
+ }
+ else {
+ ImagePath_str = sourceImagePath;
+ }
+ if (GetImagePath(*TargetProcessId, &targetImagePath) != ERROR_SUCCESS) {
+ targetImagePath_str = L"Unknown";
+ }
+ else {
+ targetImagePath_str = targetImagePath;
+ }
+
+ CallStack = GetCallStack(EventRecord, extendedData, hProcess);
+ FILETIME st;
+ GetSystemTimeAsFileTime(&st);
+ EVENT_DATA_DESCRIPTOR EventData[11];
+ EventDataDescCreate(&EventData[0], &st, sizeof(st));
+ EventDataDescCreate(&EventData[1], CallingThreadId, 4);
+ EventDataDescCreate(&EventData[2], CallingProcessId, 4);
+ EventDataDescCreate(&EventData[3], TargetProcessId, 4);
+ EventDataDescCreate(&EventData[4], CallingProcessStartKey, 8);
+ EventDataDescCreate(&EventData[5], TargetProcessStartKey, 8);
+ EventDataDescCreate(&EventData[6], OriginalProcessId, 4);
+ EventDataDescCreate(&EventData[7], BaseAddress, sizeof(BaseAddress));
+ EventDataDescCreate(&EventData[8], ImagePath_str.c_str(), (wcslen(ImagePath_str.c_str()) + 1) * sizeof(WCHAR));
+ EventDataDescCreate(&EventData[9], targetImagePath_str.c_str(), (wcslen(targetImagePath_str.c_str()) + 1) * sizeof(WCHAR));
+ EventDataDescCreate(&EventData[10], CallStack, (wcslen(CallStack) + 1) * sizeof(WCHAR));
+
+
+
+ status = WriteETWEvents(EventData, TIRemoteAllocateVirtualMemory, 11);
+ goto Exit;
+ }
+ case 24:
+ {
+ FILETIME st;
+ GetSystemTimeAsFileTime(&st);
+
+ PTRACE_EVENT_INFO pInfo = NULL;
+ DWORD bufferSize = 0;
+
+ UINT32 CallingThreadId, CallingProcessId, TargetProcessId, OriginalProcessId, TargetThreadId;
+ UINT64 CallingProcessStartKey, TargetProcessStartKey, ApcRoutine, ApcArgument1;
+ DWORD status = ERROR_SUCCESS;
+
+ //
+ // Testing out TDH APIs
+ //
+ status = TdhGetEventInformation(EventRecord, 0, NULL, pInfo, &bufferSize);
+ if (ERROR_INSUFFICIENT_BUFFER == status) {
+ pInfo = (PTRACE_EVENT_INFO)malloc(bufferSize);
+ if (pInfo == NULL) {
+ // Handle allocation failure
+ OutputDebugString(L"[!] Error allocating memory for event info\n");
+ goto Exit;
+ }
+
+ // Get the event info
+ status = TdhGetEventInformation(EventRecord, 0, NULL, pInfo, &bufferSize);
+ }
+
+ if (ERROR_SUCCESS != status) {
+ // Handle error (could not obtain event info)
+ free(pInfo);
+ OutputDebugString(L"[!] Error getting event info\n");
+ goto Exit;
+ }
+ 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) {
+ // Handle error
+ wprintf(L"Error getting size for property %ls\n", propertyName);
+ continue;
+ }
+
+ BYTE* propertyData = (BYTE*)malloc(propertySize);
+ if (!propertyData) {
+ // Handle allocation failure
+ wprintf(L"Error allocating memory for property %ls\n", propertyName);
+ continue;
+ }
+
+ // Get the property data
+ status = TdhGetProperty(EventRecord, 0, NULL, 1, &dataDescriptor, propertySize, propertyData);
+ if (status != ERROR_SUCCESS) {
+ // Handle error
+ wprintf(L"Error getting data for property %ls\n", propertyName);
+ free(propertyData);
+ continue;
+ }
+ switch (i) {
+ case 0:
+ {
+ CallingProcessId = *(UINT32*)propertyData;
+ break;
+ }
+ case 2:
+ {
+ CallingProcessStartKey = *(UINT64*)propertyData;
+ break;
+ }
+ case 6:
+ {
+ CallingThreadId = *(UINT32*)propertyData;
+ break;
+ }
+ case 8:
+ {
+ TargetProcessId = *(UINT32*)propertyData;
+ break;
+ }
+ case 10:
+ {
+ TargetProcessStartKey = *(UINT64*)propertyData;
+ break;
+ }
+ case 14:
+ {
+ TargetThreadId = *(UINT32*)propertyData;
+ }
+ case 16:
+ {
+ OriginalProcessId = *(UINT32*)propertyData;
+ break;
+ }
+ case 21:
+ {
+ ApcRoutine = *(UINT64*)propertyData;
+ break;
+ }
+ case 22:
+ {
+ ApcArgument1 = *(UINT64*)propertyData;
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ free(propertyData);
+
+ }
+
+ if (GetImagePath(CallingProcessId, &sourceImagePath) != ERROR_SUCCESS) {
+ ImagePath_str = L"Unknown";
+ }
+ else {
+ ImagePath_str = sourceImagePath;
+ }
+ if (GetImagePath(TargetProcessId, &targetImagePath) != ERROR_SUCCESS) {
+ targetImagePath_str = L"Unknown";
+ }
+ else {
+ targetImagePath_str = targetImagePath;
+ }
+
+ CallStack = GetCallStack(EventRecord, extendedData, hProcess);
+
+ EVENT_DATA_DESCRIPTOR EventData[13];
+ EventDataDescCreate(&EventData[0], &st, sizeof(st));
+ EventDataDescCreate(&EventData[1], &CallingThreadId, 4);
+ EventDataDescCreate(&EventData[2], &CallingProcessId, 4);
+ EventDataDescCreate(&EventData[3], &TargetProcessId, 4);
+ EventDataDescCreate(&EventData[4], &TargetThreadId, 4);
+ EventDataDescCreate(&EventData[5], &CallingProcessStartKey, 8);
+ EventDataDescCreate(&EventData[6], &TargetProcessStartKey, 8);
+ EventDataDescCreate(&EventData[7], &OriginalProcessId, 4);
+ EventDataDescCreate(&EventData[8], &ApcRoutine, sizeof(ApcRoutine));
+ EventDataDescCreate(&EventData[9], &ApcArgument1, sizeof(ApcArgument1));
+ EventDataDescCreate(&EventData[10], ImagePath_str.c_str(), (wcslen(ImagePath_str.c_str()) + 1) * sizeof(WCHAR));
+ EventDataDescCreate(&EventData[11], targetImagePath_str.c_str(), (wcslen(targetImagePath_str.c_str()) + 1) * sizeof(WCHAR));
+ EventDataDescCreate(&EventData[12], CallStack, (wcslen(CallStack) + 1) * sizeof(WCHAR));
+
+
+ status = WriteETWEvents(EventData, TIQueueUserAPCEvent, 13);
+ goto Exit;
+ }
+ case 26:
+ {
+ auto data{ reinterpret_cast(EventRecord->UserData) };
+ auto CallingProcessId{ GetData(data) };
+ auto CallingProcessCreationTime{ GetData(data) };
+ auto CallingProcessStartKey{ GetData(data) };
+ auto CallingProcessSignatureLevel{ GetData(data) };
+ auto CallingProcessSectionSignatureLevel{ GetData(data) };
+ auto CallingProcessProtection{ GetData(data) };
+ auto CallingThreadId{ GetData(data) };
+ auto CallingThreadCreationTime{ GetData(data) };
+ auto TargetProcessId{ GetData(data) };
+ auto TargetProcessCreateTime{ GetData(data) };
+ auto TargetProcessStartKey{ GetData(data) };
+ auto TargetProcessSignatureLevel{ GetData(data) };
+ auto TargetProcessSectionSignatureLevel{ GetData(data) };
+ auto TargetProcessProtection{ GetData(data) };
+ auto OriginalProcessId{ GetData(data) };
+ auto OriginalProcessCreateTime{ GetData(data) };
+ auto OriginalProcessStartKey{ GetData(data) };
+ auto OriginalProcessSignatureLevel{ GetData(data) };
+ auto OriginalProcessProtection{ GetData(data) };
+ auto BaseAddress{ GetData(data) };
+
+ if (*CallingProcessId == *TargetProcessId) {
+ goto Exit;
+ }
+
+ if (GetImagePath(*CallingProcessId, &sourceImagePath) != ERROR_SUCCESS) {
+ ImagePath_str = L"Unknown";
+ }
+ else {
+ ImagePath_str = sourceImagePath;
+ }
+ if (GetImagePath(*TargetProcessId, &targetImagePath) != ERROR_SUCCESS) {
+ targetImagePath_str = L"Unknown";
+ }
+ else {
+ targetImagePath_str = targetImagePath;
+ }
+
+ CallStack = GetCallStack(EventRecord, extendedData, hProcess);
+ FILETIME st;
+ GetSystemTimeAsFileTime(&st);
+ EVENT_DATA_DESCRIPTOR EventData[11];
+ EventDataDescCreate(&EventData[0], &st, sizeof(st));
+ EventDataDescCreate(&EventData[1], CallingThreadId, 4);
+ EventDataDescCreate(&EventData[2], CallingProcessId, 4);
+ EventDataDescCreate(&EventData[3], TargetProcessId, 4);
+ EventDataDescCreate(&EventData[4], CallingProcessStartKey, 8);
+ EventDataDescCreate(&EventData[5], TargetProcessStartKey, 8);
+ EventDataDescCreate(&EventData[6], OriginalProcessId, 4);
+ EventDataDescCreate(&EventData[7], BaseAddress, sizeof(BaseAddress));
+ EventDataDescCreate(&EventData[8], ImagePath_str.c_str(), (wcslen(ImagePath_str.c_str()) + 1) * sizeof(WCHAR));
+ EventDataDescCreate(&EventData[9], targetImagePath_str.c_str(), (wcslen(targetImagePath_str.c_str()) + 1) * sizeof(WCHAR));
+ EventDataDescCreate(&EventData[10], CallStack, (wcslen(CallStack) + 1) * sizeof(WCHAR));
+
+
+
+ status = WriteETWEvents(EventData, TIRemoteAllocateVirtualMemory, 11);
+ goto Exit;
+ }
+ default:
+ {
+ goto Exit;
+ }
+ }
+Exit:
+ if (sourceImagePath != nullptr) {
+ delete[] sourceImagePath;
+ }
+ if (targetImagePath != nullptr) {
+ delete[] targetImagePath;
+ }
+ if (CallStack != nullptr) {
+ delete[] CallStack;
+ }
+ return 0;
+}
+
+BOOL WriteNetworkEvents(
+ _In_ PEVENT_RECORD EventRecord,
+ _In_ PEVENT_HEADER EventHeader,
+ _In_ wchar_t* Initiated
+) {
+ WCHAR wide_deststring_ip[INET_ADDRSTRLEN];
+ WCHAR wide_sourcestring_ip[INET_ADDRSTRLEN];
+ struct in_addr srceaddr = {};
+ struct in_addr destaddr = {};
+ UINT16 sourcePort, destPort;
+ wchar_t* username = nullptr;
+ wchar_t* pImagePath = nullptr;
+ std::wstring ImagePath_str;
+ std::wstring username_str;
+ std::wstring sourcePort_str;
+ std::wstring destPort_str;
+ BOOL status = FALSE;
+ REGHANDLE RegistrationHandle = NULL;
+
+ auto data{ reinterpret_cast(EventRecord->UserData) };
+ auto PID{ GetData(data) };
+ auto size{ GetData(data) };
+ auto daddr{ GetData(data) };
+ auto saddr{ GetData(data) };
+ auto dport{ GetData(data) };
+ auto sport{ GetData(data) };
+
+ if (*PID == 4) {
+ goto Exit;
+ }
+
+ if (Initiated == L"True") {
+
+ destaddr.s_addr = *daddr;
+ srceaddr.s_addr = *saddr;
+ sourcePort == *sport;
+ destPort == *dport;
+ sourcePort_str = std::to_wstring(*sport);
+ destPort_str = std::to_wstring(*dport);
+ }
+ if (Initiated == L"False") {
+ destaddr.s_addr = *saddr;
+ srceaddr.s_addr = *daddr;
+ sourcePort = *dport;
+ destPort = *sport;
+ sourcePort_str = std::to_wstring(*dport);
+ destPort_str = std::to_wstring(*sport);
+ }
+
+ //
+ // convert port to widestring
+ //
+
+
+ //
+ // add null terminator to wide string
+ //
+ sourcePort_str += L'\0';
+ destPort_str += L'\0';
+
+ if (&destaddr == NULL) {
+ wide_deststring_ip[0] = '\0';
+ }
+ else {
+ InetNtop(AF_INET, &destaddr, wide_deststring_ip, INET_ADDRSTRLEN);
+ }
+
+ if (&srceaddr == NULL) {
+ wide_sourcestring_ip[0] = '\0';
+ }
+ else {
+ InetNtop(AF_INET, &srceaddr, wide_sourcestring_ip, INET_ADDRSTRLEN);
+ }
+ //
+ // removing ip addr 127.0.0.1
+ //
+ if (wcscmp(wide_deststring_ip, L"127.0.0.1") == 0) {
+ goto Exit;
+ }
+
+ //
+ //Getting UserName
+ //
+ if (GetTokenUser(*PID, &username) != 0) {
+ username_str = L"Unknown";
+ }
+ else {
+ username_str = username;
+ }
+
+ //
+ //Getting ImagePath
+ //
+ if (GetImagePath(*PID, &pImagePath) != ERROR_SUCCESS) {
+ ImagePath_str = L"Unknown";
+ }
+ else {
+ ImagePath_str = pImagePath;
+ }
+
+ FILETIME st;
+ GetSystemTimeAsFileTime(&st);
+
+ EVENT_DATA_DESCRIPTOR EventData[9];
+ EventDataDescCreate(&EventData[0], &st, sizeof(st));
+ EventDataDescCreate(&EventData[1], PID, 4);
+ EventDataDescCreate(&EventData[2], &wide_sourcestring_ip, (wcslen(wide_sourcestring_ip) + 1) * sizeof(WCHAR));
+ EventDataDescCreate(&EventData[3], &wide_deststring_ip, (wcslen(wide_deststring_ip) + 1) * sizeof(WCHAR));
+ EventDataDescCreate(&EventData[4], &sourcePort, sizeof(UINT16));
+ EventDataDescCreate(&EventData[5], &destPort, sizeof(UINT16));
+ EventDataDescCreate(&EventData[6], Initiated, (wcslen(Initiated) + 1) * sizeof(WCHAR));
+ EventDataDescCreate(&EventData[7], username_str.c_str(), (wcslen(username_str.c_str()) + 1) * sizeof(WCHAR));
+ EventDataDescCreate(&EventData[8], ImagePath_str.c_str(), (wcslen(ImagePath_str.c_str()) + 1) * sizeof(WCHAR));
+
+ status = WriteETWEvents(EventData, NetworkConnectionAccepted, 9);
+
+
+Exit:
+ if (pImagePath != nullptr) {
+ delete[] pImagePath;
+ }
+ if (username != nullptr) {
+ delete[] username;
+ }
+ return status;
+}
+
+BOOL WriteAMSIEvents(
+ _In_ PEVENT_RECORD EventRecord,
+ _In_ PEVENT_HEADER EventHeader
+) {
+ auto data{ reinterpret_cast(EventRecord->UserData) };
+ auto Session{ GetData(data) };
+ auto ScanStatus = GetData(data);
+ auto ScanResult = GetData(data);
+ auto AppName{ GetWideString(data) };
+ auto ContentName = GetData(data);
+ auto ContentSize = GetData(data);
+ auto OriginalSize = GetData(data);
+ auto Content = GetData(data);
+
+ FILETIME st;
+ GetSystemTimeAsFileTime(&st);
+
+ //Writing Event to ETW
+ EVENT_DATA_DESCRIPTOR EventData[5];
+ EventDataDescCreate(&EventData[0], &st, sizeof(st));
+ EventDataDescCreate(&EventData[1], &EventHeader->ProcessId, 4);
+ EventDataDescCreate(&EventData[2], AppName, (wcslen(AppName) + 1) * sizeof(WCHAR));
+ EventDataDescCreate(&EventData[3], ScanResult, 4);
+ EventDataDescCreate(&EventData[4], ContentSize, 4);
+
+ NTSTATUS status = WriteETWEvents(EventData, AMSIEvents, 5);
+
+ return TRUE;
+}
+
+BOOL WriteDotNetEvents(
+ _In_ PEVENT_RECORD EventRecord,
+ _In_ PEVENT_HEADER EventHeader
+) {
+ auto data{ reinterpret_cast(EventRecord->UserData) };
+ auto AssemblyID{ GetData(data) };
+ auto AppDomainID{ GetData(data) };
+ auto BindingID{ GetData(data) };
+ auto AssemblyFlags{ GetData(data) };
+ auto FullyQualifiedAssemblyName{ GetWideString(data) };
+ auto ClrInstanceID{ GetData(data) };
+
+ wchar_t* username = nullptr;
+ wchar_t* pImagePath = nullptr;
+ std::wstring ImagePath_str;
+ std::wstring username_str;
+ REGHANDLE RegistrationHandle = NULL;
+
+ if (EventHeader->ProcessId == 4)
+ {
+ return FALSE;
+ }
+
+ std::wistringstream wiss(FullyQualifiedAssemblyName);
+ std::vector tokens;
+ std::wstring token;
+ while (std::getline(wiss, token, L',')) {
+ tokens.push_back(token);
+ }
+
+ //Getting UserName
+ if (GetTokenUser(EventHeader->ProcessId, &username) != 0) {
+ username_str = L"Unknown - process potentially died";
+ }
+ else {
+ username_str = username;
+ }
+
+ //Getting ImagePath
+ if (GetImagePath(EventHeader->ProcessId, &pImagePath) != ERROR_SUCCESS) {
+ ImagePath_str = L"Unknown - process potentially died";
+ }
+ else {
+ ImagePath_str = pImagePath;
+ }
+
+ FILETIME st;
+ GetSystemTimeAsFileTime(&st);
+
+
+ //Writing Event to ETW
+ EVENT_DATA_DESCRIPTOR EventData[6];
+ EventDataDescCreate(&EventData[0], &st, sizeof(st));
+ EventDataDescCreate(&EventData[1], &EventHeader->ProcessId, sizeof(ULONG));
+ EventDataDescCreate(&EventData[2], tokens[0].c_str(), (wcslen(tokens[0].c_str()) + 1) * sizeof(WCHAR));
+ EventDataDescCreate(&EventData[3], username_str.c_str(), (wcslen(username_str.c_str()) + 1) * sizeof(WCHAR));
+ EventDataDescCreate(&EventData[4], ImagePath_str.c_str(), (wcslen(ImagePath_str.c_str()) + 1) * sizeof(WCHAR));
+ EventDataDescCreate(&EventData[5], ClrInstanceID, sizeof(ClrInstanceID));
+
+ NTSTATUS status = WriteETWEvents(EventData, DotNetLoad, 6);
+
+Exit:
+ if (pImagePath != nullptr) {
+ delete[] pImagePath;
+ }
+ if (username != nullptr) {
+ delete[] username;
+ }
+ return TRUE;
+}
+
+BOOL WriteTaskSchedEvents(
+ _In_ PEVENT_RECORD EventRecord,
+ _In_ PEVENT_HEADER EventHeader
+) {
+ switch (EventHeader->EventDescriptor.Id) {
+ case 106: {
+ auto data{ reinterpret_cast(EventRecord->UserData) };
+ auto TaskName{ GetWideString(data) };
+ auto UserContext{ GetWideString(data) };
+
+ FILETIME st;
+ GetSystemTimeAsFileTime(&st);
+
+ EVENT_DATA_DESCRIPTOR EventData[4];
+ EventDataDescCreate(&EventData[0], &st, sizeof(st));
+ EventDataDescCreate(&EventData[1], TaskName, (wcslen(TaskName) + 1) * sizeof(WCHAR));
+ EventDataDescCreate(&EventData[2], UserContext, (wcslen(UserContext) + 1) * sizeof(WCHAR));
+ EventDataDescCreate(&EventData[3], &EventHeader->ProcessId, 4);
+
+ NTSTATUS status = WriteETWEvents(EventData, SchedTaskCreation, 4);
+
+ break;
+ }
+ case 129: {
+ auto data{ reinterpret_cast(EventRecord->UserData) };
+ auto TaskName{ GetWideString(data) };
+ auto Path{ GetWideString(data) };
+ auto ProcessId = GetData(data);
+ FILETIME st;
+ GetSystemTimeAsFileTime(&st);
+ EVENT_DATA_DESCRIPTOR EventData[4];
+ EventDataDescCreate(&EventData[0], &st, sizeof(st));
+ EventDataDescCreate(&EventData[1], TaskName, (wcslen(TaskName) + 1) * sizeof(WCHAR));
+ EventDataDescCreate(&EventData[2], Path, (wcslen(Path) + 1) * sizeof(WCHAR));
+ EventDataDescCreate(&EventData[3], ProcessId, 4);
+
+ NTSTATUS status = WriteETWEvents(EventData, SchedTaskStarted, 4);
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ return TRUE;
+}
+
+BOOL WriteWMIEvents(
+ _In_ PEVENT_RECORD EventRecord,
+ _In_ PEVENT_HEADER EventHeader
+) {
+ switch (EventHeader->EventDescriptor.Id) {
+ case 5861:
+ {
+ auto data{ reinterpret_cast(EventRecord->UserData) };
+ auto Namespace{ GetWideString(data) };
+ auto ESS{ GetWideString(data) };
+ auto Consumer{ GetWideString(data) };
+ auto PossibleCause{ GetWideString(data) };
+
+ FILETIME st;
+ GetSystemTimeAsFileTime(&st);
+
+ EVENT_DATA_DESCRIPTOR EventData[5];
+ EventDataDescCreate(&EventData[0], &st, sizeof(st));
+ EventDataDescCreate(&EventData[1], Namespace, (wcslen(Namespace) + 1) * sizeof(WCHAR));
+ EventDataDescCreate(&EventData[2], ESS, (wcslen(ESS) + 1) * sizeof(WCHAR));
+ EventDataDescCreate(&EventData[3], Consumer, (wcslen(Consumer) + 1) * sizeof(WCHAR));
+ EventDataDescCreate(&EventData[4], PossibleCause, (wcslen(PossibleCause) + 1) * sizeof(WCHAR));
+
+ NTSTATUS status = WriteETWEvents(EventData, WMIFilterToConsumerBinding, 5);
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+wchar_t* GetCallStack(
+ _In_ PEVENT_RECORD EventRecord,
+ _In_ PEVENT_HEADER_EXTENDED_DATA_ITEM extendedData,
+ _In_ HANDLE hProcess
+) {
+ std::string sSymSearchPathBuf;
+ const char* szSymSearchPath = nullptr;
+ szSymSearchPath = "srv*http://msdl.microsoft.com/download/symbols";
+ SymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS | SYMOPT_INCLUDE_32BIT_MODULES | SYMOPT_CASE_INSENSITIVE | SYMOPT_ALLOW_ZERO_ADDRESS | SYMOPT_ALLOW_ABSOLUTE_SYMBOLS);
+ BOOL ret = SymInitialize(hProcess, szSymSearchPath, TRUE);
+ if (!ret) {
+ printf("[!] SymInitialize failed: %d\n", GetLastError());
+ }
+ if (EventRecord->ExtendedDataCount != 0) {
+ const int MAX_SYM_NAME_LEN = 1024;
+ std::wstring wtext;
+ for (USHORT i = 0; i < EventRecord->ExtendedDataCount; i++) {
+ if (extendedData[i].ExtType == EVENT_HEADER_EXT_TYPE_STACK_TRACE64) {
+ auto stacktrace = reinterpret_cast(extendedData[i].DataPtr);
+ int stack_length = extendedData[i].DataSize / sizeof(ULONG64);
+ for (int j = 0; j < stack_length; j++) {
+ DWORD64 dwDisplacement;
+ DWORD temp;
+ DWORD64 dwAddress = stacktrace->Address[j];
+ char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME_LEN * sizeof(TCHAR)];
+ PSYMBOL_INFOW pSymbol = (PSYMBOL_INFOW)buffer;
+ pSymbol->SizeOfStruct = sizeof(SYMBOL_INFOW);
+ pSymbol->MaxNameLen = MAX_SYM_NAME_LEN;
+ if (SymFromAddrW(hProcess, dwAddress, &dwDisplacement, pSymbol)) {
+ wtext += pSymbol->Name;
+ }
+ else {
+ wtext += L"";
+ }
+ wtext += L" ";
+ }
+ }
+ }
+
+ wtext.erase(wtext.size() - 2);
+ size_t wtext_len = wtext.length() + 1;
+ wchar_t* result = new wchar_t[wtext_len];
+ wcscpy_s(result, wtext_len, wtext.c_str());
+ return result;
+ }
+ SymCleanup(hProcess);
+}
+
+BOOL WriteRPCEvent(
+ _In_ PEVENT_RECORD EventRecord,
+ _In_ PEVENT_HEADER EventHeader,
+ _In_ EVENT_DESCRIPTOR RPCEvent,
+ _In_ wchar_t* InterfaceString,
+ _In_ wchar_t* MethodString,
+ _In_ wchar_t* szInterfaceUUID,
+ _In_ wchar_t* CallStack
+) {
+ //Getting Data
+ wchar_t* username = nullptr;
+ std::wstring username_str;
+ wchar_t* pImagePath = nullptr;
+ std::wstring ImagePath_str;
+ PEVENT_HEADER_EXTENDED_DATA_ITEM extendedData = EventRecord->ExtendedData;
+ HANDLE hProcess = GetCurrentProcess();
+
+ auto data{ reinterpret_cast(EventRecord->UserData) };
+ auto interfaceUUID{ GetData(data) };
+ auto procNum{ GetData(data) };
+ auto protocol{ GetData(data) };
+ auto networkAddress{ GetWideString(data) };
+ auto endpoint{ GetWideString(data) };
+ auto options{ GetWideString(data) };
+ auto authenticationLevel{ GetData(data) };
+ auto authenticationService{ GetData(data) };
+ auto impersonationLevel{ GetData(data) };
+
+ //Getting UserName
+ if (GetTokenUser(EventHeader->ProcessId, &username) != 0) {
+ username_str = L"Unknown";
+ }
+ else {
+ username_str = username;
+ }
+
+ //Getting ImagePath
+ if (GetImagePath((DWORD)EventHeader->ProcessId, &pImagePath) != 0) {
+ ImagePath_str = L"Unknown - process potentially died";
+ }
+ else {
+ ImagePath_str = pImagePath;
+ }
+
+ FILETIME st;
+ GetSystemTimeAsFileTime(&st);
+
+ //Writing Event to ETW
+ EVENT_DATA_DESCRIPTOR EventData[12];
+ EventDataDescCreate(&EventData[0], &st, sizeof(st));
+ EventDataDescCreate(&EventData[1], szInterfaceUUID, (wcslen(szInterfaceUUID) + 1) * sizeof(WCHAR));
+ EventDataDescCreate(&EventData[2], procNum, 4);
+ EventDataDescCreate(&EventData[3], protocol, 4);
+ EventDataDescCreate(&EventData[4], &EventHeader->ProcessId, 4);
+ EventDataDescCreate(&EventData[5], networkAddress, (wcslen(networkAddress) + 1) * sizeof(WCHAR));
+ EventDataDescCreate(&EventData[6], endpoint, (wcslen(endpoint) + 1) * sizeof(WCHAR));
+ EventDataDescCreate(&EventData[7], InterfaceString, (wcslen(InterfaceString) + 1) * sizeof(WCHAR));
+ EventDataDescCreate(&EventData[8], MethodString, (wcslen(MethodString) + 1) * sizeof(WCHAR));
+ EventDataDescCreate(&EventData[9], username_str.c_str(), (wcslen(username_str.c_str()) + 1) * sizeof(WCHAR));
+ EventDataDescCreate(&EventData[10], ImagePath_str.c_str(), (wcslen(ImagePath_str.c_str()) + 1) * sizeof(WCHAR));
+ EventDataDescCreate(&EventData[11], CallStack, (wcslen(CallStack) + 1) * sizeof(WCHAR));
+
+ NTSTATUS status = WriteETWEvents(EventData, RPCEvent, 12);
+
+ return TRUE;
+}
+
+BOOL RpcEvent(
+ _In_ PEVENT_RECORD EventRecord,
+ _In_ PEVENT_HEADER EventHeader,
+ _In_ EVENT_DESCRIPTOR RPCEvent
+) {
+ PEVENT_HEADER_EXTENDED_DATA_ITEM extendedData = EventRecord->ExtendedData;
+ HANDLE hProcess = GetCurrentProcess();
+ auto data{ reinterpret_cast(EventRecord->UserData) };
+ auto interfaceUUID{ GetData(data) };
+ auto procNum{ GetData(data) };
+ wchar_t szInterfaceUUID[64] = { 0 };
+ StringFromGUID2(*interfaceUUID, szInterfaceUUID, 64);
+
+
+ //MS-SCMR {367ABB81-9844-35F1-AD32-98F038001003}
+ if (wcscmp(szInterfaceUUID, L"{367ABB81-9844-35F1-AD32-98F038001003}") == 0) {
+ const wchar_t* InterfaceString = L"MS-SCMR";
+ switch (*procNum)
+ {
+ case 12:
+ {
+ const wchar_t* MethodString = L"RCreateServiceW";
+ wchar_t* CallStack = GetCallStack(EventRecord, extendedData, hProcess);
+ BOOL WriteEvent = WriteRPCEvent(EventRecord, EventHeader, RPCEvent, (wchar_t*)InterfaceString, (wchar_t*)MethodString, szInterfaceUUID, CallStack);
+ delete[] CallStack;
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ return TRUE;
+ }
+ //MS-DRSR {E3514235-4B06-11D1-AB04-00C04FC2DCD2}
+ if (wcscmp(szInterfaceUUID, L"{E3514235-4B06-11D1-AB04-00C04FC2DCD2}") == 0) {
+ const wchar_t* InterfaceString = L"MS-DRSR";
+ switch (*procNum) {
+ case 3:
+ {
+ const wchar_t* MethodString = L"GetNCChanges";
+ wchar_t* CallStack = GetCallStack(EventRecord, extendedData, hProcess);
+ BOOL WriteEvent = WriteRPCEvent(EventRecord, EventHeader, RPCEvent, (wchar_t*)InterfaceString, (wchar_t*)MethodString, szInterfaceUUID, CallStack);
+ delete[] CallStack;
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ return TRUE;
+ }
+ //MS-RRP {338CD001-2244-31F1-AAAA-900038001003}
+ if (wcscmp(szInterfaceUUID, L"{338CD001-2244-31F1-AAAA-900038001003}") == 0) {
+ const wchar_t* InterfaceString = L"MS-RRP";
+ switch (*procNum) {
+ case 6:
+ {
+ const wchar_t* MethodString = L"BaseRegCreateKey";
+ wchar_t* CallStack = GetCallStack(EventRecord, extendedData, hProcess);
+ BOOL WriteEvent = WriteRPCEvent(EventRecord, EventHeader, RPCEvent, (wchar_t*)InterfaceString, (wchar_t*)MethodString, szInterfaceUUID, CallStack);
+ delete[] CallStack;
+ break;
+ }
+ case 22:
+ {
+ const wchar_t* MethodString = L"BaseRegSetValue";
+ wchar_t* CallStack = GetCallStack(EventRecord, extendedData, hProcess);
+ BOOL WriteEvent = WriteRPCEvent(EventRecord, EventHeader, RPCEvent, (wchar_t*)InterfaceString, (wchar_t*)MethodString, szInterfaceUUID, CallStack);
+ delete[] CallStack;
+ break;
+ }
+ default:
+ {
+ break;
+ }
+
+ }
+ return TRUE;
+ }
+ //MS-SRVS {4B324FC8-1670-01D3-1278-5A47BF6EE188}
+ if (wcscmp(szInterfaceUUID, L"{4B324FC8-1670-01D3-1278-5A47BF6EE188}") == 0) {
+ const wchar_t* InterfaceString = L"MS-SRVS";
+ switch (*procNum) {
+ case 12:
+ {
+ const wchar_t* MethodString = L"NetrSessionEnum";
+ wchar_t* CallStack = GetCallStack(EventRecord, extendedData, hProcess);
+ BOOL WriteEvent = WriteRPCEvent(EventRecord, EventHeader, RPCEvent, (wchar_t*)InterfaceString, (wchar_t*)MethodString, szInterfaceUUID, CallStack);
+ delete[] CallStack;
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ return TRUE;
+ }
+ //MS-RPRN {12345678-1234-ABCD-EF00-0123456789AB}
+ if (wcscmp(szInterfaceUUID, L"{12345678-1234-ABCD-EF00-0123456789AB}") == 0) {
+ const wchar_t* InterfaceString = L"MS-RPRN";
+ switch (*procNum) {
+ case 89:
+ {
+ const wchar_t* MethodString = L"RpcAddPrinterDriverEx";
+ wchar_t* CallStack = GetCallStack(EventRecord, extendedData, hProcess);
+ BOOL WriteEvent = WriteRPCEvent(EventRecord, EventHeader, RPCEvent, (wchar_t*)InterfaceString, (wchar_t*)MethodString, szInterfaceUUID, CallStack);
+ delete[] CallStack;
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ return TRUE;
+ }
+
+ //MS-PAR 76F03F96-CDFD-44FC-A22C-64950A001209
+ if (wcscmp(szInterfaceUUID, L"{76F03F96-CDFD-44FC-A22C-64950A001209}") == 0) {
+ const wchar_t* InterfaceString = L"MS-PAR";
+ switch (*procNum) {
+ case 39:
+ {
+ const wchar_t* MethodString = L"RpcAsyncAddPrinterDriver";
+ wchar_t* CallStack = GetCallStack(EventRecord, extendedData, hProcess);
+ BOOL WriteEvent = WriteRPCEvent(EventRecord, EventHeader, RPCEvent, (wchar_t*)InterfaceString, (wchar_t*)MethodString, szInterfaceUUID, CallStack);
+ delete[] CallStack;
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ return TRUE;
+ }
+ // MS-EFSR {D9A0A0C0-150F-11D1-8C7A-00C04FC297EB} || {C681D488-D850-11D0-8C52-00C04FD90F7E}"
+ if ((wcscmp(szInterfaceUUID, L"{C681D488-D850-11D0-8C52-00C04FD90F7E}") == 0) || (wcscmp(szInterfaceUUID, L"{DF1941C5-FE89-4E79-BF10-463657ACF44D}") == 0)) {
+ const wchar_t* InterfaceString = L"MS-EFSR";
+ switch (*procNum) {
+ case 0:
+ {
+ const wchar_t* MethodString = L"EfsRpcOpenFileRaw";
+ wchar_t* CallStack = GetCallStack(EventRecord, extendedData, hProcess);
+ BOOL WriteEvent = WriteRPCEvent(EventRecord, EventHeader, RPCEvent, (wchar_t*)InterfaceString, (wchar_t*)MethodString, szInterfaceUUID, CallStack);
+ delete[] CallStack;
+ break;
+ }
+ case 4:
+ {
+ const wchar_t* MethodString = L"EfsRpcEncryptFileSrv";
+ wchar_t* CallStack = GetCallStack(EventRecord, extendedData, hProcess);
+ BOOL WriteEvent = WriteRPCEvent(EventRecord, EventHeader, RPCEvent, (wchar_t*)InterfaceString, (wchar_t*)MethodString, szInterfaceUUID, CallStack);
+ delete[] CallStack;
+ break;
+ }
+ case 5:
+ {
+ const wchar_t* MethodString = L"EfsRpcDecryptFileSrv";
+ wchar_t* CallStack = GetCallStack(EventRecord, extendedData, hProcess);
+ BOOL WriteEvent = WriteRPCEvent(EventRecord, EventHeader, RPCEvent, (wchar_t*)InterfaceString, (wchar_t*)MethodString, szInterfaceUUID, CallStack);
+ delete[] CallStack;
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ return TRUE;
+ }
+
+}
+
+BOOL DPAPIEvents(
+ _In_ PEVENT_RECORD EventRecord,
+ _In_ PEVENT_HEADER EventHeader
+) {
+ switch (EventHeader->EventDescriptor.Id) {
+ case 16385:
+ {
+ auto data{ reinterpret_cast(EventRecord->UserData) };
+ auto OperationType{ GetWideString(data) };
+ auto DataDescription{ GetWideString(data) };
+ auto MasterKeyGUID = GetData(data);
+ auto Flags = GetData(data);
+ auto ProtectionFlags = GetData(data);
+ auto ReturnValue = GetData(data);
+ auto CallerProcessStartKey = GetData(data);
+ auto CallerProcessID = GetData(data);
+ auto CallerProcessCreationTime = GetData(data);
+ auto PlainTextDataSize = GetData(data);
+
+ FILETIME st;
+ GetSystemTimeAsFileTime(&st);
+
+ //
+ //Seeing if OperationType == SPCryptUnprotect
+ //
+ if (wcscmp(OperationType, L"SPCryptUnprotect") == 0) {
+
+ EVENT_DATA_DESCRIPTOR EventData[6];
+ EventDataDescCreate(&EventData[0], &st, sizeof(st));
+ EventDataDescCreate(&EventData[1], OperationType, (wcslen(OperationType) + 1) * sizeof(WCHAR));
+ EventDataDescCreate(&EventData[2], DataDescription, (wcslen(DataDescription) + 1) * sizeof(WCHAR));
+ EventDataDescCreate(&EventData[3], CallerProcessID, 4);
+ EventDataDescCreate(&EventData[4], Flags, 4);
+ EventDataDescCreate(&EventData[5], ProtectionFlags, 4);
+
+ NTSTATUS status = WriteETWEvents(EventData, DPAPIEvent, 6);
+ break;
+ }
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+Exit:
+ return TRUE;
+}
\ No newline at end of file
diff --git a/JonMon-Service/etwMain.h b/JonMon-Service/etwMain.h
new file mode 100644
index 0000000..a9fe31f
--- /dev/null
+++ b/JonMon-Service/etwMain.h
@@ -0,0 +1,83 @@
+#pragma once
+#include
+
+struct ProcessData {
+ ULONG ProcessId;
+ ULONG ValueOption;
+};
+#define JonMon_DEVICE 0x8010
+
+#define IOCTL_CHANGE_PROTECTION_LEVEL_PROCESS CTL_CODE(JonMon_DEVICE, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+void NTAPI ProcessEvent(
+ _In_ PEVENT_RECORD EventRecord
+);
+
+int StopETWTrace();
+
+int TraceEvent();
+
+NTSTATUS WriteETWEvents(
+ _In_ PEVENT_DATA_DESCRIPTOR eventData,
+ _In_ EVENT_DESCRIPTOR eventDescriptor,
+ _In_ int metaDataSize
+);
+
+BOOL WriteDotNetEvents(
+ _In_ PEVENT_RECORD EventRecord,
+ _In_ PEVENT_HEADER EventHeader
+);
+
+BOOL WriteAMSIEvents(
+ _In_ PEVENT_RECORD EventRecord,
+ _In_ PEVENT_HEADER EventHeader
+);
+
+BOOL WriteTaskSchedEvents(
+ _In_ PEVENT_RECORD EventRecord,
+ _In_ PEVENT_HEADER EventHeader
+);
+
+BOOL WriteWMIEvents(
+ _In_ PEVENT_RECORD EventRecord,
+ _In_ PEVENT_HEADER EventHeader
+);
+
+BOOL WriteNetworkEvents(
+ _In_ PEVENT_RECORD EventRecord,
+ _In_ PEVENT_HEADER EventHeader,
+ _In_ wchar_t* Initiated
+);
+
+NTSTATUS WriteThreatIntelEvents(
+ _In_ PEVENT_RECORD EventRecord,
+ _In_ PEVENT_HEADER EventHeader
+);
+
+#pragma warning(disable: 4996)
+wchar_t* GetCallStack(
+ _In_ PEVENT_RECORD EventRecord,
+ _In_ PEVENT_HEADER_EXTENDED_DATA_ITEM extendedData,
+ _In_ HANDLE hProcess
+);
+
+BOOL WriteRPCEvent(
+ _In_ PEVENT_RECORD EventRecord,
+ _In_ PEVENT_HEADER EventHeader,
+ _In_ EVENT_DESCRIPTOR RPCEvent,
+ _In_ wchar_t* InterfaceString,
+ _In_ wchar_t* MethodString,
+ _In_ wchar_t* szInterfaceUUID,
+ _In_ wchar_t* CallStack
+);
+
+BOOL RpcEvent(
+ _In_ PEVENT_RECORD EventRecord,
+ _In_ PEVENT_HEADER EventHeader,
+ _In_ EVENT_DESCRIPTOR RPCEvent
+);
+
+BOOL DPAPIEvents(
+ _In_ PEVENT_RECORD EventRecord,
+ _In_ PEVENT_HEADER EventHeader
+);
\ No newline at end of file
diff --git a/JonMon-Service/global.h b/JonMon-Service/global.h
new file mode 100644
index 0000000..aa07a02
--- /dev/null
+++ b/JonMon-Service/global.h
@@ -0,0 +1,41 @@
+#pragma once
+#include
+
+//ETW GUIDS
+static GUID JonMonGuid = { 0xd8909c24, 0x5be9, 0x4502, { 0x98, 0xca, 0xab, 0x7b, 0xdc, 0x24, 0x89, 0x9d } };
+static GUID RPC = { 0x6ad52b32, 0xd609, 0x4be9, { 0xae, 0x07, 0xce, 0x8d, 0xae, 0x93, 0x7e, 0x39 } };
+static GUID Network = { 0x7DD42A49,0x5329,0x4832,{0x8D, 0xFD, 0x43, 0xD9, 0x79, 0x15, 0x3A, 0x88} };
+static GUID DotNet = { 0xe13c0d23, 0xccbc, 0x4e12, { 0x93, 0x1b, 0xd9, 0xcc, 0x2e, 0xee, 0x27, 0xe4 } };
+static GUID AMSI = { 0x2a576b87, 0x09a7, 0x520e, { 0xc2, 0x1a, 0x49, 0x42, 0xf0, 0x27, 0x1d, 0x67 } };
+static GUID TaskSched = { 0xde7b24ea, 0x73c8, 0x4a09, { 0x98, 0x5d, 0x5b, 0xda, 0xdc, 0xfa, 0x90, 0x17 } };
+static GUID WMIActivty = { 0x1418ef04, 0xb0b4, 0x4623, { 0xbf, 0x7e, 0xd7, 0x4a, 0xb4, 0x7b, 0xbd, 0xaa } };
+static GUID ThreatIntel = { 0xf4e1897c, 0xbb5d, 0x5668, { 0xf1, 0xd8, 0x04, 0x0f, 0x4d, 0x8d, 0xd3, 0x44 } };
+static GUID DPAPI = { 0x89fe8f40, 0xcdce, 0x464e, { 0x82, 0x17, 0x15, 0xef, 0x97, 0xd4, 0xc7, 0xc3 } };
+
+
+
+// EVENT DESCRIPTORS
+const EVENT_DESCRIPTOR RPCClientCall = { 0xb, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8000000000000000 };
+const EVENT_DESCRIPTOR RPCServerCall = { 0xc, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8000000000000000 };
+const EVENT_DESCRIPTOR ProcessTest = { 0xa, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8000000000000000 };
+const EVENT_DESCRIPTOR NetworkConnectionAccepted = { 0xd, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8000000000000000 };
+const EVENT_DESCRIPTOR DotNetLoad = { 0xf, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8000000000000000 };
+const EVENT_DESCRIPTOR SchedTaskCreation = { 0x13, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8000000000000000 };
+const EVENT_DESCRIPTOR SchedTaskStarted = { 0x14, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8000000000000000 };
+const EVENT_DESCRIPTOR WMIFilterToConsumerBinding = { 0x19, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8000000000000000 };
+const EVENT_DESCRIPTOR TIReadProcessMemory = { 0x1e, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8000000000000000 };
+const EVENT_DESCRIPTOR TIWriteProcessMemory = { 0x1d, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8000000000000000 };
+const EVENT_DESCRIPTOR AMSIEvents = { 0x10, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8000000000000000 };
+const EVENT_DESCRIPTOR DPAPIEvent = { 0x1c, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8000000000000000 };
+const EVENT_DESCRIPTOR TIQueueUserAPCEvent = { 0x1a, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8000000000000000 };
+const EVENT_DESCRIPTOR TIRemoteAllocateVirtualMemory = { 0x20, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8000000000000000 };
+
+typedef struct _UNICODE_STRING {
+ USHORT Length;
+ USHORT MaximumLength;
+ PWSTR Buffer;
+} UNICODE_STRING, * PUNICODE_STRING;
+
+
+
+
diff --git a/JonMon-Service/service.cpp b/JonMon-Service/service.cpp
new file mode 100644
index 0000000..334294b
--- /dev/null
+++ b/JonMon-Service/service.cpp
@@ -0,0 +1,334 @@
+#include
+#include
+#include "service.h"
+#include "etwMain.h"
+
+
+SERVICE_STATUS_HANDLE g_hServiceStatus = NULL;
+SERVICE_STATUS g_ServiceStatus = { 0 };
+
+VOID LoadExtensions();
+
+VOID WINAPI ServiceCtrlHandler(
+ _In_ DWORD dwCtrl
+)
+{
+ switch (dwCtrl)
+ {
+ case SERVICE_CONTROL_STOP:
+ // Update the service status
+ g_ServiceStatus.dwControlsAccepted = 0;
+ g_ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
+ g_ServiceStatus.dwWin32ExitCode = 0;
+ g_ServiceStatus.dwCheckPoint = 0;
+ g_ServiceStatus.dwWaitHint = 0;
+ SetServiceStatus(g_hServiceStatus, &g_ServiceStatus);
+
+ // Perform service-specific cleanup here
+
+ // Update the service status
+ g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
+ g_ServiceStatus.dwWin32ExitCode = 0;
+ g_ServiceStatus.dwCheckPoint = 0;
+ g_ServiceStatus.dwWaitHint = 0;
+ SetServiceStatus(g_hServiceStatus, &g_ServiceStatus);
+ break;
+
+ case SERVICE_CONTROL_PAUSE:
+ // Update the service status
+ g_ServiceStatus.dwCurrentState = SERVICE_PAUSE_PENDING;
+ g_ServiceStatus.dwWin32ExitCode = 0;
+ g_ServiceStatus.dwCheckPoint = 0;
+ g_ServiceStatus.dwWaitHint = 0;
+ SetServiceStatus(g_hServiceStatus, &g_ServiceStatus);
+
+ // Perform service-specific pause here
+
+ // Update the service status
+ g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
+ g_ServiceStatus.dwCurrentState = SERVICE_PAUSED;
+ g_ServiceStatus.dwWin32ExitCode = 0;
+ g_ServiceStatus.dwCheckPoint = 0;
+ g_ServiceStatus.dwWaitHint = 0;
+ SetServiceStatus(g_hServiceStatus, &g_ServiceStatus);
+ break;
+
+ case SERVICE_CONTROL_CONTINUE:
+ // Update the service status
+ g_ServiceStatus.dwCurrentState = SERVICE_CONTINUE_PENDING;
+ g_ServiceStatus.dwWin32ExitCode = 0;
+ g_ServiceStatus.dwCheckPoint = 0;
+ g_ServiceStatus.dwWaitHint = 0;
+ SetServiceStatus(g_hServiceStatus, &g_ServiceStatus);
+
+ // Perform service-specific continue here
+
+ // Update the service status
+ g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
+ g_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
+ g_ServiceStatus.dwWin32ExitCode = 0;
+ g_ServiceStatus.dwCheckPoint = 0;
+ g_ServiceStatus.dwWaitHint = 0;
+ SetServiceStatus(g_hServiceStatus, &g_ServiceStatus);
+ break;
+
+ case SERVICE_CONTROL_SHUTDOWN:
+ // Perform service-specific shutdown here
+ g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_SHUTDOWN;
+ g_ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
+ g_ServiceStatus.dwWin32ExitCode = 0;
+ g_ServiceStatus.dwCheckPoint = 0;
+ g_ServiceStatus.dwWaitHint = 0;
+ SetServiceStatus(g_hServiceStatus, &g_ServiceStatus);
+ break;
+
+ default:
+ // Update the service status
+ g_ServiceStatus.dwWin32ExitCode = ERROR_CALL_NOT_IMPLEMENTED;
+ g_ServiceStatus.dwCheckPoint = 0;
+ g_ServiceStatus.dwWaitHint = 0;
+ SetServiceStatus(g_hServiceStatus, &g_ServiceStatus);
+ break;
+ }
+
+}
+
+void WINAPI ServiceMain(
+ _In_ DWORD argc,
+ _In_ LPTSTR* argv
+) {
+
+ g_hServiceStatus = RegisterServiceCtrlHandlerExA("JonMon", (LPHANDLER_FUNCTION_EX)ServiceCtrlHandler, NULL);
+ if (g_hServiceStatus == NULL) {
+ return;
+ }
+
+ g_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
+ g_ServiceStatus.dwCheckPoint = 0;
+ g_ServiceStatus.dwWaitHint = 0;
+ g_ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
+ g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
+ g_ServiceStatus.dwWin32ExitCode = 0;
+ g_ServiceStatus.dwServiceSpecificExitCode = 0;
+
+ if (!SetServiceStatus(g_hServiceStatus, &g_ServiceStatus)) {
+ return;
+ }
+
+
+ LoadExtensions();
+ TraceEvent();
+}
+
+//
+// Load extension DLLs
+//
+VOID LoadExtensions()
+{
+
+ //
+ // Loading JonMon-Ext1.dll to capture token impersonation events
+ //
+ typedef VOID(__stdcall* TokenImpersonationCheck)();
+
+ HMODULE hModule = LoadLibrary(L"JonMon-Ext1.dll");
+ if (hModule == NULL) {
+ OutputDebugString(L"Failed to load JonMon-Ext1.dll");
+ return;
+ }
+
+ //
+ // Execute the TokenImpersonationCheck function
+ //
+ TokenImpersonationCheck TokenImpersonationCheckFunc = (TokenImpersonationCheck)GetProcAddress(hModule, "TokenImpersonationCheck");
+ if (TokenImpersonationCheckFunc == NULL)
+ {
+ OutputDebugString(L"Failed to get TokenImpersonationCheck function address");
+ return;
+ }
+
+ //
+ // Call the TokenImpersonationCheck function and give it a thread
+ //
+ std::thread tokenImpersonationCheckThread(TokenImpersonationCheckFunc);
+ tokenImpersonationCheckThread.detach();
+}
+
+DWORD CreateCustomService(
+ _In_ LPCWSTR ServiceName,
+ _In_ LPCWSTR ImagePath,
+ _In_ DWORD dwServiceType
+) {
+
+ SC_HANDLE hSCManager = nullptr;
+ SC_HANDLE hService = nullptr;
+ DWORD dwError = 0;
+
+ printf("[*] Creating Service %ws....\n", ServiceName);
+
+ hSCManager = OpenSCManager(nullptr, nullptr, SC_MANAGER_CONNECT | SC_MANAGER_CREATE_SERVICE);
+ if (hSCManager == nullptr) {
+ printf("[-] Service creation failed on OpenSCManager\n");
+ dwError = GetLastError();
+ goto Exit;
+ }
+ hService = CreateService(hSCManager, ServiceName, ServiceName, SC_MANAGER_CREATE_SERVICE, dwServiceType, SERVICE_DEMAND_START, SERVICE_ERROR_IGNORE, ImagePath, nullptr, nullptr, nullptr, nullptr, nullptr);
+ if (hService == nullptr) {
+ printf("[-] Service creation failed on CreateService\n");
+ dwError = GetLastError();
+ goto Exit;
+ }
+ printf("[*] Service %ws created successfully\n", ServiceName);
+Exit:
+ if(hSCManager != nullptr)
+ {
+ CloseServiceHandle(hSCManager);
+ }
+ if(hService != nullptr)
+ {
+ CloseServiceHandle(hService);
+ }
+ return 0;
+}
+
+DWORD StartCustomService(
+ _In_ LPCWSTR ServiceName
+) {
+ SC_HANDLE hSCManager = nullptr;
+ SC_HANDLE hService = nullptr;
+ DWORD dwError = 0;
+
+ printf("[*] Starting Service %ws....\n", ServiceName);
+ hSCManager = OpenSCManager(nullptr, nullptr, SERVICE_START);
+ if (hSCManager == nullptr) {
+ printf("[-] Start service failed on OpenSCManager\n");
+ dwError = GetLastError();
+ goto Exit;
+ }
+ hService = OpenService(hSCManager, ServiceName, SERVICE_START);
+ if (hService == nullptr) {
+ printf("[-] Start service failed on OpenService\n");
+ dwError = GetLastError();
+ goto Exit;
+ }
+ if (!StartService(hService, 0, nullptr)) {
+ printf("[-] Start service failed on StartService\n");
+ dwError = GetLastError();
+ goto Exit;
+ }
+ printf("[*] Service %ws started successfully\n", ServiceName);
+
+Exit:
+ if (hSCManager != nullptr)
+ {
+ CloseServiceHandle(hSCManager);
+ }
+ if (hService != nullptr)
+ {
+ CloseServiceHandle(hService);
+ }
+ return 0;
+}
+
+DWORD StopCustomService(
+ _In_ LPCWSTR ServiceName
+) {
+ printf("[*] Stopping Service %ws....\n", ServiceName);
+ SC_HANDLE hSCManager = nullptr;
+ hSCManager = OpenSCManager(nullptr, nullptr, SERVICE_STOP);
+ if (hSCManager == nullptr) {
+ printf("[-] OpenSCManager Failed");
+ return GetLastError();
+ }
+ SC_HANDLE hService = OpenService(hSCManager, ServiceName, SERVICE_STOP);
+ if (hService == nullptr) {
+ printf("[-] OpenService Failed");
+ CloseServiceHandle(hSCManager);
+ return GetLastError();
+ }
+ SERVICE_STATUS status;
+ if (!ControlService(hService, SERVICE_CONTROL_STOP, &status)) {
+ printf("[-] ControlService Failed\n");
+ CloseServiceHandle(hSCManager);
+ CloseServiceHandle(hService);
+ return GetLastError();
+ }
+ CloseServiceHandle(hSCManager);
+ CloseServiceHandle(hService);
+
+ printf("[*] Service %ws stopped successfully\n", ServiceName);
+ return 0;
+}
+
+DWORD DeleteCustomService(
+ _In_ LPCWSTR ServiceName
+) {
+ printf("[*] Deleting Service %ws....\n", ServiceName);
+ SC_HANDLE hSCManager = nullptr;
+ hSCManager = OpenSCManager(nullptr, nullptr, SC_MANAGER_CONNECT | SC_MANAGER_CREATE_SERVICE);
+ if (hSCManager == nullptr) {
+ printf("[-] OpenSCManager Failed");
+ return GetLastError();
+ }
+ SC_HANDLE hService = OpenService(hSCManager, ServiceName, DELETE);
+ if (hService == nullptr) {
+ printf("[-] OpenService Failed");
+ CloseServiceHandle(hSCManager);
+ return GetLastError();
+ }
+ if (!DeleteService(hService)) {
+ printf("[-] DeleteService Failed");
+ CloseServiceHandle(hSCManager);
+ CloseServiceHandle(hService);
+ return GetLastError();
+ }
+ CloseServiceHandle(hSCManager);
+ CloseServiceHandle(hService);
+ printf("[*] Service %ws deleted successfully\n", ServiceName);
+ return 0;
+}
+
+DWORD UninstallManifest() {
+
+ printf("[*] Uninstalling Manifest....\n");
+ STARTUPINFOW si;
+ PROCESS_INFORMATION pi;
+
+ ZeroMemory(&si, sizeof(si));
+ si.cb = sizeof(si);
+ ZeroMemory(&pi, sizeof(pi));
+ wchar_t cmdLine[] = L"C:\\Windows\\System32\\wevtutil.exe um JonMon.man";
+ if (!CreateProcessW(NULL, cmdLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
+ printf("CreateProcess Failed");
+ return GetLastError();
+ }
+ WaitForSingleObject(pi.hProcess, INFINITE);
+ CloseHandle(pi.hProcess);
+ CloseHandle(pi.hThread);
+
+ printf("[*] Manifest Uninstalled....\n");
+
+ return 0;
+}
+
+DWORD InstallManifest() {
+ printf("[*] Installing Manifest....\n");
+ DWORD dwRet = UninstallManifest();
+ STARTUPINFOW si;
+ PROCESS_INFORMATION pi;
+
+ ZeroMemory(&si, sizeof(si));
+ si.cb = sizeof(si);
+ ZeroMemory(&pi, sizeof(pi));
+ wchar_t cmdLine[] = L"C:\\Windows\\System32\\wevtutil.exe im JonMon.man";
+ if (!CreateProcessW(NULL, cmdLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
+ printf("[-] CreateProcess Failed");
+ return GetLastError();
+ }
+ WaitForSingleObject(pi.hProcess, INFINITE);
+ CloseHandle(pi.hProcess);
+ CloseHandle(pi.hThread);
+ printf("[*] Manifest Installed....\n");
+
+ return 0;
+}
\ No newline at end of file
diff --git a/JonMon-Service/service.h b/JonMon-Service/service.h
new file mode 100644
index 0000000..9c4c4b6
--- /dev/null
+++ b/JonMon-Service/service.h
@@ -0,0 +1,37 @@
+#pragma once
+
+VOID WINAPI ServiceCtrlHandler(
+ _In_ DWORD dwCtrl
+);
+
+void WINAPI ServiceMain(
+ _In_ DWORD argc,
+ _In_ LPTSTR* argv
+);
+
+DWORD CreateCustomService(
+ _In_ LPCWSTR ServiceName,
+ _In_ LPCWSTR ImagePath,
+ _In_ DWORD dwServiceType
+);
+
+DWORD StartCustomService(
+ _In_ LPCWSTR ServiceName
+);
+
+DWORD StopCustomService(
+ _In_ LPCWSTR ServiceName
+);
+
+DWORD DeleteCustomService(
+ _In_ LPCWSTR ServiceName
+);
+
+DWORD UninstallManifest();
+
+DWORD InstallManifest();
+
+
+
+
+
diff --git a/JonMon/JonMon.inf b/JonMon/JonMon.inf
new file mode 100644
index 0000000..6dc6698
--- /dev/null
+++ b/JonMon/JonMon.inf
@@ -0,0 +1,68 @@
+[Version]
+Signature = "$WINDOWS NT$"
+Class = "ActivityMonitor" ;Check devguid.h
+ClassGuid = {b86dff51-a31e-4bac-b3cf-e8cfe75c9fc2}
+Provider = %ManufacturerName%
+DriverVer = 3/1/2023,1.0.0.0
+CatalogFile = JonMon.cat
+;https://learn.microsoft.com/en-us/windows-hardware/drivers/install/inf-classinstall32-section
+
+;This template is supported for OS version 17763 (Windows 10 version 1809) and after.
+;For Windows OS prior to Windows 10 1809 set DefaultDestDir = 12
+[DestinationDirs]
+DefaultDestDir = 12
+JonMon.DriverFiles = 12
+;https://learn.microsoft.com/en-us/windows-hardware/drivers/install/inf-destinationdirs-section
+
+[DefaultInstall]
+OptionDesc = %ServiceDescription%
+CopyFiles = JonMon.DriverFiles
+
+[DefaultInstall.Services]
+AddService = %ServiceName%,,JonMon.Service
+
+[DefaultUninstall]
+DelFiles = JonMon.DriverFiles
+
+[DefaultUninstall.Services]
+DelService = %ServiceName%
+
+[JonMon.Service]
+DisplayName = %ServiceDescription%
+Description = %ServiceDescription%
+ServiceType = 1
+StartType = 3
+ErrorControl = 1
+ServiceBinary = %12%\JonMon.sys
+AddReg = JonMon.AddRegsitry
+
+[JonMon.AddRegsitry]
+HKR,,"DebugFlags",0x00010001 ,0x0
+HKR,,"SupportedFeatures",0x00010001,0x3
+HKR,"Instances","DefaultInstance",0x00000000,%DefaultInstance%
+HKR,"Instances\"%Instance1.Name%,"Altitude",0x00000000,%Instance1.Altitude%
+HKR,"Instances\"%Instance1.Name%,"Flags",0x00010001,%Instance1.Flags%
+
+
+[JonMon.DriverFiles]
+%DriverName%.sys
+
+[SourceDisksFiles]
+JonMon.sys = 1,,
+
+[SourceDisksNames]
+1 = %DiskId1%,,,
+
+[Strings]
+; TODO - Add your manufacturer
+ManufacturerName = "jsecurity101"
+ServiceDescription = "JonMon Driver"
+ServiceName = "JonMonDrv"
+DriverName = "JonMon"
+DiskId1 = "JonMon Disk"
+
+;Instances specific information.
+DefaultInstance = "JonMon Instance"
+Instance1.Name = "JonMon Instance"
+Instance1.Altitude = "385202"
+Instance1.Flags = 0x0 ; Allow all attachments
diff --git a/JonMon/JonMon.sln b/JonMon/JonMon.sln
new file mode 100644
index 0000000..a3244d5
--- /dev/null
+++ b/JonMon/JonMon.sln
@@ -0,0 +1,71 @@
+
+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|ARM64.Deploy.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
diff --git a/JonMon/JonMon.vcxproj b/JonMon/JonMon.vcxproj
new file mode 100644
index 0000000..2f68ee3
--- /dev/null
+++ b/JonMon/JonMon.vcxproj
@@ -0,0 +1,128 @@
+
+
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+ Debug
+ ARM64
+
+
+ Release
+ ARM64
+
+
+
+ {27DCE7FD-EC60-49F7-9245-A39DE05E7056}
+ {dd38f7fc-d7bd-488b-9242-7d8754cde80d}
+ v4.5
+ 12.0
+ Debug
+ x64
+ JonMon
+
+
+
+ Windows10
+ true
+ WindowsKernelModeDriver10.0
+ Driver
+ WDM
+ false
+
+
+ Windows10
+ false
+ WindowsKernelModeDriver10.0
+ Driver
+ WDM
+ false
+
+
+ Windows10
+ true
+ WindowsKernelModeDriver10.0
+ Driver
+ WDM
+
+
+ Windows10
+ false
+ WindowsKernelModeDriver10.0
+ Driver
+ WDM
+
+
+
+
+
+
+
+
+
+
+ DbgengKernelDebugger
+
+
+ DbgengKernelDebugger
+
+
+ DbgengKernelDebugger
+
+
+ DbgengKernelDebugger
+
+
+
+ sha256
+
+
+ Ksecdd.lib;FltMgr.lib;Setupapi.lib;%(AdditionalDependencies)
+ /INTEGRITYCHECK %(AdditionalOptions)
+
+
+
+
+ sha256
+
+
+ Ksecdd.lib;FltMgr.lib;%(AdditionalDependencies)
+ /INTEGRITYCHECK %(AdditionalOptions)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/JonMon/JonMon.vcxproj.filters b/JonMon/JonMon.vcxproj.filters
new file mode 100644
index 0000000..e4a2774
--- /dev/null
+++ b/JonMon/JonMon.vcxproj.filters
@@ -0,0 +1,78 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hpp;hxx;hm;inl;inc;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+ {8E41214B-6785-4CFE-B992-037D68949A14}
+ inf;inv;inx;mof;mc;
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
+
+ Driver Files
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
\ No newline at end of file
diff --git a/JonMon/callbacks.cpp b/JonMon/callbacks.cpp
new file mode 100644
index 0000000..af87f77
--- /dev/null
+++ b/JonMon/callbacks.cpp
@@ -0,0 +1,1090 @@
+#include "callbacks.h"
+#include "process.h"
+#include "thread.h"
+#include "token.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;
+
+//
+// Registering callbacks for log collection
+//
+_IRQL_requires_max_(PASSIVE_LEVEL)
+NTSTATUS RegisterCallbacks(
+ _In_ PDRIVER_OBJECT DriverObject,
+ _In_ PDEVICE_OBJECT DeviceObject
+) {
+ UNREFERENCED_PARAMETER(DeviceObject);
+ UNREFERENCED_PARAMETER(DriverObject);
+ PAGED_CODE();
+ NTSTATUS status = STATUS_SUCCESS;
+
+ 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");
+
+ 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");
+
+ 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");
+
+ 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");
+
+ UNICODE_STRING Altitude;
+ RtlInitUnicodeString(&Altitude, L"385202");
+
+ //
+ //Setting up callback for PsProcessType
+ //
+ OB_CALLBACK_REGISTRATION CallbackRegistration;
+ OB_OPERATION_REGISTRATION OperationRegistration;
+ OperationRegistration.ObjectType = PsProcessType;
+ OperationRegistration.Operations = OB_OPERATION_HANDLE_DUPLICATE | OB_OPERATION_HANDLE_CREATE;
+ 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");
+
+ status = FltCallbackStart(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");
+
+ status = CmRegisterCallbackEx(RegistryCallback, &Altitude, 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");
+
+ return status;
+}
+
+// [DONE]
+// LoadImage callback worker thread. This function will perform the appropriate processing and then terminate.
+//
+_IRQL_requires_max_(PASSIVE_LEVEL)
+VOID LoadImageWorkerThread(
+ _In_ PVOID StartContext
+) {
+ PLOAD_IMAGE_CALLBACK_INFO callbackInfo = NULL;
+ UNICODE_STRING imagePath{ 0 };
+ UNICODE_STRING sourceFullUserName{};
+ NTSTATUS status;
+ ULONG systemModeImage;
+
+ PAGED_CODE();
+
+ callbackInfo = (PLOAD_IMAGE_CALLBACK_INFO)StartContext;
+
+ FILETIME filetime = callbackInfo->FileTime;
+ HANDLE sourcePID = callbackInfo->SourceProcessId;
+ ULONGLONG uSourcePID = HandleToULong(sourcePID);
+ ULONGLONG sourceThreadID = HandleToULong(callbackInfo->SourceThread);
+
+ systemModeImage = callbackInfo->SystemModeImage;
+
+ PEPROCESS sourceProcess;
+
+ if (systemModeImage == 1)
+ {
+ EventWriteDriverLoad(NULL, &filetime, callbackInfo->ModuleName.Buffer);
+ goto Exit;
+ }
+
+ status = PsLookupProcessByProcessId(sourcePID, &sourceProcess);
+ if (!NT_SUCCESS(status))
+ {
+ goto Exit;
+ }
+ ULONGLONG sourceProcessStartKey = PsGetProcessStartKey(sourceProcess);
+ imagePath.Length = 0;
+ imagePath.MaximumLength = MAX_ALLOC;
+ imagePath.Buffer = (PWSTR)ExAllocatePool2(POOL_FLAG_PAGED, MAX_ALLOC, CALBACK_TAG);
+ status = GetProcessImageName(sourcePID, &imagePath);
+ if (!NT_SUCCESS(status) || imagePath.Buffer == NULL) {
+ goto Exit;
+ }
+
+ sourceFullUserName.Length = 0;
+ sourceFullUserName.MaximumLength = MAX_ALLOC;
+ sourceFullUserName.Buffer = (PWCH)ExAllocatePool2(POOL_FLAG_PAGED, sourceFullUserName.MaximumLength, CALBACK_TAG);
+ if (sourceFullUserName.Buffer == NULL) {
+ goto Exit;
+ }
+
+ DWORD SourceAuthenticationId = 0;
+ status = GetProcessUserName(&sourceFullUserName, sourcePID, &SourceAuthenticationId);
+ if (!NT_SUCCESS(status))
+ {
+ goto Exit;
+ }
+
+
+ EventWriteImageLoaded(NULL, &filetime, imagePath.Buffer, uSourcePID, sourceThreadID, sourceProcessStartKey, callbackInfo->ModuleName.Buffer, sourceFullUserName.Buffer, SourceAuthenticationId);
+
+
+Exit:
+ if (sourceFullUserName.Buffer != NULL) {
+ ExFreePoolWithTag(sourceFullUserName.Buffer, CALBACK_TAG);
+ }
+ if (imagePath.Buffer != NULL) {
+ ExFreePoolWithTag(imagePath.Buffer, CALBACK_TAG);
+ }
+ if (callbackInfo->ModuleName.Buffer != NULL)
+ {
+ ExFreePoolWithTag(callbackInfo->ModuleName.Buffer, CALBACK_TAG);
+ }
+ if (callbackInfo != NULL) {
+ ExFreePoolWithTag(callbackInfo, SYSTEM_THREAD_TAG);
+ }
+
+ PsTerminateSystemThread(STATUS_SUCCESS);
+}
+
+// [DONE]
+// LoadImage callback. Routine will capture when an image is loaded into a process and will create a worker thread to perform the appropriate processing.
+//
+_IRQL_requires_max_(PASSIVE_LEVEL)
+VOID
+LoadImageRoutine(
+ _In_ PUNICODE_STRING FullImageName,
+ _In_ HANDLE ProcessId,
+ _In_ PIMAGE_INFO ImageInfo
+) {
+ NTSTATUS status;
+ FILETIME fileTime;
+ HANDLE hLoadImageThread = NULL;
+ UNICODE_STRING imagePath{ 0 };
+ KeQuerySystemTime(&fileTime);
+ PAGED_CODE();
+
+ auto callbackInfo = (PLOAD_IMAGE_CALLBACK_INFO)ExAllocatePool2(POOL_FLAG_PAGED, sizeof(LOAD_IMAGE_CALLBACK_INFO), SYSTEM_THREAD_TAG);
+ if (callbackInfo == NULL) {
+ goto Exit;
+ }
+
+ imagePath.Length = FullImageName->Length + sizeof(UNICODE_NULL);
+ imagePath.MaximumLength = FullImageName->Length + sizeof(UNICODE_NULL);
+ imagePath.Buffer = (PWSTR)ExAllocatePool2(POOL_FLAG_PAGED, imagePath.MaximumLength, CALBACK_TAG);
+ if (imagePath.Buffer == NULL) {
+ goto Exit;
+ }
+ //
+ // Copy the image path into the callback info structure.
+ //
+ RtlCopyUnicodeString(&imagePath, FullImageName);
+
+ //
+ //null terminate the string
+ //
+ imagePath.Buffer[imagePath.Length / sizeof(UNICODE_NULL)] = UNICODE_NULL;
+
+
+ //
+ //setting the callback info structure
+ //
+ callbackInfo->ModuleName = imagePath;
+
+
+ callbackInfo->FileTime = fileTime;
+ callbackInfo->SourceProcessId = ProcessId;
+ callbackInfo->SourceThread = NtCurrentThread();
+ callbackInfo->SourceEThread = PsGetCurrentThread();
+ callbackInfo->SystemModeImage = ImageInfo->SystemModeImage;
+
+
+ OBJECT_ATTRIBUTES objectAttributes;
+ InitializeObjectAttributes(&objectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
+
+ status = PsCreateSystemThread(&hLoadImageThread, THREAD_ALL_ACCESS, &objectAttributes, NULL, NULL, (PKSTART_ROUTINE)LoadImageWorkerThread, callbackInfo);
+ if (!NT_SUCCESS(status)) {
+ DbgPrint("PsCreateSystemThread failed: %x\n", status);
+ ExFreePoolWithTag(imagePath.Buffer, CALBACK_TAG);
+ ExFreePoolWithTag(callbackInfo, SYSTEM_THREAD_TAG);
+ goto Exit;
+ }
+
+Exit:
+ if(hLoadImageThread != NULL)
+ {
+ ZwClose(hLoadImageThread);
+ }
+
+ return;
+}
+
+// [DONE]
+// Registry callback to capture registry actions and create a worker thread to perform the appropriate processing.
+//
+_IRQL_requires_max_(PASSIVE_LEVEL)
+NTSTATUS RegistryCallback(
+ _In_ PVOID CallbackContext,
+ _In_ PVOID RegNotifyClass,
+ _In_ PVOID RegObject
+) {
+ NTSTATUS status = STATUS_SUCCESS;
+ PCWSTR keyPath = NULL;
+ HANDLE registryThreadHandle = NULL;
+ REG_NOTIFY_CLASS notifyClass;
+ notifyClass = (REG_NOTIFY_CLASS)(ULONG_PTR)RegNotifyClass;
+
+
+ PAGED_CODE();
+ UNREFERENCED_PARAMETER(CallbackContext);
+
+ if (RegObject == NULL)
+ {
+ DbgPrint("Callback RegObject is NULL. \n");
+ status = STATUS_UNSUCCESSFUL;
+ goto Exit;
+ }
+ switch (notifyClass) {
+ case RegNtPostCreateKeyEx:
+ {
+ PREG_POST_OPERATION_INFORMATION postObject = (PREG_POST_OPERATION_INFORMATION)RegObject;
+ if (postObject->Status == STATUS_SUCCESS) {
+ PREG_CREATE_KEY_INFORMATION_V1 info = (PREG_CREATE_KEY_INFORMATION_V1)postObject->PreInformation;
+ if (*info->Disposition == REG_CREATED_NEW_KEY) {
+ if (info->CompleteName->Buffer != NULL)
+ {
+ PCUNICODE_STRING registryPath = NULL;
+ status = CmCallbackGetKeyObjectIDEx(&Cookie, info->RootObject, NULL, ®istryPath, 0);
+ if (!NT_SUCCESS(status)) {
+ DbgPrint("CmCallbackGetKeyObjectIDEx failed. Status 0x%x", status);
+ goto Exit;
+ }
+
+ UNICODE_STRING regPath;
+ regPath.Length = registryPath->Length + info->RemainingName->Length + sizeof(L"\\") + sizeof(UNICODE_NULL);
+ regPath.MaximumLength = registryPath->Length + info->RemainingName->Length + sizeof(L"\\") + sizeof(UNICODE_NULL);
+ regPath.Buffer = (PWSTR)ExAllocatePool2(POOL_FLAG_PAGED, regPath.Length, REGISTRY_TAG);
+
+ RtlCopyUnicodeString(®Path, registryPath);
+ RtlAppendUnicodeToString(®Path, L"\\");
+ RtlAppendUnicodeStringToString(®Path, info->RemainingName);
+
+ //
+ //adding null terminator
+ //
+ regPath.Buffer[regPath.Length / sizeof(UNICODE_NULL)] = UNICODE_NULL;
+
+ auto callbackInfo = (PREG_CREATE_KEY_CALLBACK_INFO)ExAllocatePool2(POOL_FLAG_PAGED, sizeof(REG_CREATE_KEY_CALLBACK_INFO), SYSTEM_THREAD_TAG);
+ if (callbackInfo == NULL) {
+ goto Exit;
+ }
+ callbackInfo->DesiredAccess = info->DesiredAccess;
+ callbackInfo->ProcStartKey = PsGetProcessStartKey(PsGetCurrentProcess());
+ callbackInfo->SourceProcessId = PsGetCurrentProcessId();
+ callbackInfo->KeyPath = regPath;
+ callbackInfo->SourceThread = PsGetCurrentThread();
+ callbackInfo->SourceThreadId = PsGetCurrentThreadId();
+
+ CmCallbackReleaseKeyObjectIDEx(registryPath);
+
+ OBJECT_ATTRIBUTES objectAttributes;
+ InitializeObjectAttributes(&objectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
+ status = PsCreateSystemThread(®istryThreadHandle, THREAD_ALL_ACCESS, &objectAttributes, NULL, NULL, (PKSTART_ROUTINE)CreateKey, callbackInfo);
+ if (!NT_SUCCESS(status))
+ {
+ DbgPrint("PsCreateSystemThread failed: %x\n", status);
+ ExFreePoolWithTag(regPath.Buffer, REGISTRY_TAG);
+ ExFreePoolWithTag(callbackInfo, SYSTEM_THREAD_TAG);
+ goto Exit;
+ }
+ goto Exit;
+ }
+ }
+ goto Exit;
+ }
+ goto Exit;
+ break;
+ }
+ case RegNtPostSaveKey:
+ {
+ PREG_POST_OPERATION_INFORMATION postObject = (PREG_POST_OPERATION_INFORMATION)RegObject;
+ if (postObject->Status == STATUS_SUCCESS) {
+ SaveKey(CallbackContext, (PREG_SAVE_KEY_INFORMATION)postObject->PreInformation);
+ }
+ //goto Exit;
+ break;
+ }
+ case RegNtPreDeleteKey:
+ {
+ PREG_DELETE_KEY_INFORMATION DeleteObject = (PREG_DELETE_KEY_INFORMATION)RegObject;
+ if (DeleteObject->Object != NULL)
+ {
+ DeleteKey(CallbackContext, (PREG_DELETE_KEY_INFORMATION)RegObject);
+ }
+ //goto Exit;
+ break;
+ }
+ case RegNtPostSetValueKey:
+ {
+ 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;
+
+
+ //
+ // creating a copy of the value name, otherwise it will be cleared by the callback
+ //
+ if (info->ValueName == NULL || info->ValueName->Length == 0) {
+ goto Exit;
+ }
+
+ status = GetRegistryKeyPath(info->Object, SYSTEM_THREAD_TAG, &keyPath);
+ if (status != STATUS_SUCCESS || keyPath == NULL) {
+ DbgPrint("[RegNtPostSetValueKey] - GetRegistryKeyPath failed. Status 0x%x", status);
+ goto Exit;
+ }
+
+ //
+ // Allocating memory for the callback info structure
+ //
+ auto callbackInfo = (PREG_SET_VALUE_CALLBACK_INFO)ExAllocatePool2(POOL_FLAG_PAGED, sizeof(REG_SET_VALUE_CALLBACK_INFO), SYSTEM_THREAD_TAG);
+ if (callbackInfo == NULL) {
+ goto Exit;
+ }
+ if (info->DataSize <= 0) {
+ ExFreePoolWithTag((PVOID)keyPath, SYSTEM_THREAD_TAG);
+ ExFreePoolWithTag(callbackInfo, SYSTEM_THREAD_TAG);
+ goto Exit;
+ }
+ PVOID Data = ExAllocatePool2(POOL_FLAG_PAGED, info->DataSize, SYSTEM_THREAD_TAG);
+ if (Data == NULL) {
+ ExFreePoolWithTag((PVOID)keyPath, SYSTEM_THREAD_TAG);
+ ExFreePoolWithTag(callbackInfo, SYSTEM_THREAD_TAG);
+ goto Exit;
+ }
+
+ RtlCopyMemory(Data, info->Data, info->DataSize);
+
+ UNICODE_STRING valueName;
+ valueName.Length = info->ValueName->Length + sizeof(UNICODE_NULL); // Compensate for NULL terminator.
+ valueName.MaximumLength = info->ValueName->Length + sizeof(UNICODE_NULL);
+ valueName.Buffer = (PWSTR)ExAllocatePool2(POOL_FLAG_PAGED, valueName.Length, SYSTEM_THREAD_TAG); // Use valueName.Length here.
+ if (valueName.Buffer == NULL || valueName.Length == 0) {
+ ExFreePoolWithTag((PVOID)keyPath, SYSTEM_THREAD_TAG);
+ ExFreePoolWithTag(callbackInfo, SYSTEM_THREAD_TAG);
+ goto Exit;
+ }
+
+ //
+ // Copy and NULL terminate the string. The Length member of the UNICODE_STRING doesn't compensate for the NULL terminator.
+ //
+ RtlCopyUnicodeString(&valueName, info->ValueName);
+ valueName.Buffer[valueName.Length / sizeof(UNICODE_NULL)] = UNICODE_NULL;
+
+ callbackInfo->Data = Data;
+ callbackInfo->KeyPath = keyPath;
+ callbackInfo->Type = info->Type;
+ callbackInfo->ValueName = valueName;
+ callbackInfo->SourceProcessId = PsGetCurrentProcessId();
+ callbackInfo->SourceThreadId = PsGetCurrentThreadId();
+ callbackInfo->SourceProcess = PsGetCurrentProcess();
+ callbackInfo->SourceThread = PsGetCurrentThread();
+ callbackInfo->DataSize = info->DataSize;
+ OBJECT_ATTRIBUTES objectAttributes;
+ InitializeObjectAttributes(&objectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
+
+ status = PsCreateSystemThread(®istryThreadHandle, GENERIC_ALL, &objectAttributes, NULL, NULL, (PKSTART_ROUTINE)SendSetValueRegistryInfo, callbackInfo);
+ if (!NT_SUCCESS(status))
+ {
+ DbgPrint("[RegNtPostSetValueKey] - PsCreateSystemThread failed. Status 0x%x", status);
+ ExFreePoolWithTag((PVOID)keyPath, SYSTEM_THREAD_TAG);
+ ExFreePoolWithTag(callbackInfo, SYSTEM_THREAD_TAG);
+ ExFreePoolWithTag(valueName.Buffer, SYSTEM_THREAD_TAG);
+ //goto Exit;
+ }
+ //goto Exit;
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+Exit:
+
+ if (registryThreadHandle != NULL) {
+ ZwClose(registryThreadHandle);
+ }
+ return status;
+}
+
+// [DONE]
+// Thread Creation routine that captures remote thread creation
+//
+_IRQL_requires_max_(PASSIVE_LEVEL)
+void PsCreateThreadNotifyRoutine(
+ _In_ HANDLE ProcessId,
+ _In_ HANDLE ThreadId,
+ _In_ BOOLEAN Create
+) {
+ NTSTATUS status;
+ PEPROCESS sourceProcess;
+ PEPROCESS targetProcess;
+ UNICODE_STRING sourceImage = { 0 };
+ UNICODE_STRING sourceUserName = { 0 };
+ UNICODE_STRING targetImage = { 0 };
+ UNICODE_STRING targetUserName = { 0 };
+ UNICODE_STRING sIntegrityLevel = { 0 };
+ UNICODE_STRING tIntegrityLevel = { 0 };
+ DWORD sourceAuthenticationId, targetAuthenticationId = 0;
+ HANDLE tToken = NULL;
+ HANDLE sToken = NULL;
+
+
+ PAGED_CODE();
+ //Checking for thread creation
+ 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);
+ return;
+ }
+ status = PsLookupProcessByProcessId(CurrentPID, &sourceProcess);
+ if (status != STATUS_SUCCESS) {
+ DbgPrint("Failed to get source process, status: %d", status);
+ return;
+ }
+ ULONGLONG sourceProcStartKey = PsGetProcessStartKey(sourceProcess);
+ ULONGLONG targetProcStartKey = PsGetProcessStartKey(targetProcess);
+ //Source Process Information
+
+ sourceImage.Length = 0;
+ sourceImage.MaximumLength = MAX_ALLOC;
+ sourceImage.Buffer = (PWSTR)ExAllocatePool2(POOL_FLAG_PAGED, MAX_ALLOC, CALBACK_TAG);
+
+ status = GetProcessImageName(CurrentPID, &sourceImage);
+ if (status != STATUS_SUCCESS) {
+ DbgPrint("Error getting source image name: %d", status);
+ sourceImage.Buffer = L"Unknown";
+ }
+
+
+ sourceUserName.Length = 0;
+ sourceUserName.MaximumLength = MAX_ALLOC;
+ sourceUserName.Buffer = (PWSTR)ExAllocatePool2(POOL_FLAG_PAGED, MAX_ALLOC, CALBACK_TAG);
+ status = GetProcessUserName(&sourceUserName, CurrentPID, &sourceAuthenticationId);
+ if (status != STATUS_SUCCESS) {
+ DbgPrint("Error getting source user name: %d", status);
+ goto Exit;
+ }
+
+ if (sourceUserName.Length == 0)
+ {
+ goto Exit;
+ }
+
+ //Create unicode string that holds "SYSTEM"
+ UNICODE_STRING SystemName;
+ RtlInitUnicodeString(&SystemName, L"NT AUTHORITY\\SYSTEM");
+ if (RtlCompareUnicodeString(&sourceUserName, &SystemName, TRUE) == 0)
+ {
+ goto Exit;
+ }
+
+ status = GetProcessToken(CurrentPID, &sToken);
+ if (status != STATUS_SUCCESS) {
+ DbgPrint("Error getting source token: %d", status);
+ sToken = NULL;
+ }
+
+ status = GetTokenIntegrityLevel(sToken, &sIntegrityLevel);
+ if (status != STATUS_SUCCESS) {
+ DbgPrint("Error getting source integrity level: %d", status);
+ sIntegrityLevel.Buffer = L"Unknown";
+ }
+
+ //Target Process Information
+ targetImage.Length = 0;
+ targetImage.MaximumLength = MAX_ALLOC;
+ targetImage.Buffer = (PWSTR)ExAllocatePool2(POOL_FLAG_PAGED, MAX_ALLOC, CALBACK_TAG);
+ status = GetProcessImageName(ProcessId, &targetImage);
+ if (status != STATUS_SUCCESS) {
+ goto Exit;
+ }
+
+ targetUserName.Length = 0;
+ targetUserName.MaximumLength = MAX_ALLOC;
+ targetUserName.Buffer = (PWSTR)ExAllocatePool2(POOL_FLAG_PAGED, MAX_ALLOC, CALBACK_TAG);
+ status = GetProcessUserName(&targetUserName, ProcessId, &targetAuthenticationId);
+ if (status != STATUS_SUCCESS) {
+ DbgPrint("Error getting target user name: %d", status);
+ goto Exit;
+ }
+
+ status = GetProcessToken(ProcessId, &tToken);
+ if (status != STATUS_SUCCESS) {
+ DbgPrint("Error getting target token: %d", status);
+ tToken = NULL;
+ }
+
+ status = GetTokenIntegrityLevel(tToken, &tIntegrityLevel);
+ if (status != STATUS_SUCCESS) {
+ DbgPrint("Error getting target integrity level: %d", status);
+ tIntegrityLevel.Buffer = L"Unknown";
+ }
+
+ FILETIME filetime;
+ KeQuerySystemTime(&filetime);
+
+ EventWriteRemoteThreadCreation(NULL, &filetime, sourceImage.Buffer, reinterpret_cast(CurrentPID), reinterpret_cast(sourceThreadId), sourceProcStartKey, sourceUserName.Buffer, sourceAuthenticationId, sIntegrityLevel.Buffer, targetImage.Buffer, reinterpret_cast(ProcessId), targetProcStartKey, reinterpret_cast(ThreadId), targetUserName.Buffer, targetAuthenticationId, tIntegrityLevel.Buffer);
+
+Exit:
+ if (sourceUserName.Buffer != NULL && sourceUserName.Length != 0) {
+ ExFreePoolWithTag(sourceUserName.Buffer, CALBACK_TAG);
+ }
+ if (targetUserName.Buffer != NULL && targetUserName.Length != 0) {
+ ExFreePoolWithTag(targetUserName.Buffer, CALBACK_TAG);
+ }
+ if (sourceImage.Buffer != NULL && sourceImage.Length != 0) {
+ ExFreePoolWithTag(sourceImage.Buffer, CALBACK_TAG);
+ }
+ if (targetImage.Buffer != NULL && targetImage.Length != 0) {
+ ExFreePoolWithTag(targetImage.Buffer, CALBACK_TAG);
+ }
+ if (sToken != NULL) {
+ ZwClose(sToken);
+ }
+ if (tToken != NULL) {
+ ZwClose(tToken);
+ }
+
+}
+
+// [DONE]
+// Create Process Worker Thread
+//
+VOID CreateProcessWorkerThread(
+ _In_ PVOID StartContext
+) {
+ PPROCESS_CREATE_CALLBACK_INFO callbackInfo = NULL;
+ UNICODE_STRING processImagePath{};
+ UNICODE_STRING parentImagePath{};
+ UNICODE_STRING parentUserName{};
+ UNICODE_STRING creatorUserName{};
+ UNICODE_STRING creatorImagePath{};
+ UNICODE_STRING childUserName{};
+ DWORD parentAuthenticationId = 0;
+ DWORD childAuthenticationId = 0;
+ DWORD creatorAuthenticationId = 0;
+ NTSTATUS status;
+
+ PAGED_CODE();
+
+ callbackInfo = (PPROCESS_CREATE_CALLBACK_INFO)StartContext;
+
+ HANDLE sourcePID = callbackInfo->ParentProcessId;
+ HANDLE targetPID = callbackInfo->ProcessId;
+ PEPROCESS targetProcess = callbackInfo->Process;
+ FILETIME fileTime = callbackInfo->FileTime;
+ CLIENT_ID creatorId = callbackInfo->CreatorId;
+
+ ULONGLONG sourceThreadId = HandleToULong(creatorId.UniqueThread);
+
+ ULONGLONG procStartKey = PsGetProcessStartKey(targetProcess);
+ ULONGLONG procStartTime = PsGetProcessCreateTimeQuadPart(targetProcess);
+
+ parentImagePath.Length = 0;
+ parentImagePath.MaximumLength = MAX_ALLOC;
+ parentImagePath.Buffer = (PWSTR)ExAllocatePool2(POOL_FLAG_PAGED, MAX_ALLOC, SYSTEM_THREAD_TAG);
+ status = GetProcessImageName(sourcePID, &parentImagePath);
+ if (status != STATUS_SUCCESS) {
+ goto Exit;
+ }
+
+ parentUserName.Length = 0;
+ parentUserName.MaximumLength = MAX_ALLOC;
+ parentUserName.Buffer = (PWSTR)ExAllocatePool2(POOL_FLAG_PAGED, MAX_ALLOC, SYSTEM_THREAD_TAG);
+ status = GetProcessUserName(&parentUserName, sourcePID, &parentAuthenticationId);
+ if (status != STATUS_SUCCESS) {
+ goto Exit;
+ }
+
+ processImagePath.Length = 0;
+ processImagePath.MaximumLength = MAX_ALLOC;
+ processImagePath.Buffer = (PWSTR)ExAllocatePool2(POOL_FLAG_PAGED, MAX_ALLOC, SYSTEM_THREAD_TAG);
+ status = GetProcessImageName(targetPID, &processImagePath);
+ if (status != STATUS_SUCCESS) {
+ goto Exit;
+ }
+
+ childUserName.Length = 0;
+ childUserName.MaximumLength = MAX_ALLOC;
+ childUserName.Buffer = (PWSTR)ExAllocatePool2(POOL_FLAG_PAGED, MAX_ALLOC, SYSTEM_THREAD_TAG);
+ status = GetProcessUserName(&childUserName, targetPID, &childAuthenticationId);
+ if (status != STATUS_SUCCESS) {
+ goto Exit;
+ }
+
+ ULONGLONG uParentPID = HandleToULong(sourcePID);
+ ULONGLONG uTargetPID = HandleToULong(targetPID);
+ ULONGLONG uCreatorPID = HandleToULong(creatorId.UniqueProcess);
+
+ EventWriteProcessCreation(NULL, &fileTime, processImagePath.Buffer, callbackInfo->CommandLine.Buffer, uTargetPID, procStartKey, procStartTime, parentUserName.Buffer, childAuthenticationId, uParentPID, sourceThreadId, parentImagePath.Buffer, uCreatorPID, childUserName.Buffer, parentAuthenticationId);
+
+
+ if (uParentPID != uCreatorPID) {
+ creatorUserName.Length = 0;
+ creatorUserName.MaximumLength = MAX_ALLOC;
+ creatorUserName.Buffer = (PWSTR)ExAllocatePool2(POOL_FLAG_PAGED, MAX_ALLOC, SYSTEM_THREAD_TAG);
+ status = GetProcessUserName(&creatorUserName, creatorId.UniqueProcess, &creatorAuthenticationId);
+ if (status != STATUS_SUCCESS) {
+ goto Exit;
+ }
+
+ creatorImagePath.Length = 0;
+ creatorImagePath.MaximumLength = MAX_ALLOC;
+ creatorImagePath.Buffer = (PWSTR)ExAllocatePool2(POOL_FLAG_PAGED, MAX_ALLOC, SYSTEM_THREAD_TAG);
+ status = GetProcessImageName(creatorId.UniqueProcess, &creatorImagePath);
+ if (status != STATUS_SUCCESS) {
+ goto Exit;
+ }
+ EventWriteProcessReparenting(NULL, &fileTime, processImagePath.Buffer, callbackInfo->CommandLine.Buffer, uParentPID, sourceThreadId, uTargetPID, procStartKey, procStartTime, parentImagePath.Buffer, uCreatorPID, creatorImagePath.Buffer, creatorUserName.Buffer, parentUserName.Buffer, childUserName.Buffer, parentAuthenticationId, childAuthenticationId, creatorAuthenticationId);
+ goto Exit;
+ }
+
+
+Exit:
+ if (processImagePath.Buffer != NULL) {
+ ExFreePoolWithTag(processImagePath.Buffer, SYSTEM_THREAD_TAG);
+ }
+ if (parentImagePath.Buffer != NULL) {
+ ExFreePoolWithTag(parentImagePath.Buffer, SYSTEM_THREAD_TAG);
+ }
+ if (parentUserName.Buffer != NULL) {
+ ExFreePoolWithTag(parentUserName.Buffer, SYSTEM_THREAD_TAG);
+ }
+ if (childUserName.Buffer != NULL) {
+ ExFreePoolWithTag(childUserName.Buffer, SYSTEM_THREAD_TAG);
+ }
+ if (creatorUserName.Buffer != NULL) {
+ ExFreePoolWithTag(creatorUserName.Buffer, SYSTEM_THREAD_TAG);
+ }
+ if (creatorImagePath.Buffer != NULL) {
+ ExFreePoolWithTag(creatorImagePath.Buffer, SYSTEM_THREAD_TAG);
+ }
+ if (callbackInfo->CommandLine.Buffer != NULL) {
+ ExFreePoolWithTag(callbackInfo->CommandLine.Buffer, SYSTEM_THREAD_TAG);
+ }
+ if (callbackInfo != NULL) {
+ ExFreePoolWithTag(callbackInfo, SYSTEM_THREAD_TAG);
+ }
+
+ PsTerminateSystemThread(STATUS_SUCCESS);
+}
+
+//
+// Callback routine to capture process creation events
+//
+_IRQL_requires_max_(PASSIVE_LEVEL)
+void CreateProcessNotifyRoutineEx(
+ _In_ PEPROCESS Process,
+ _In_ HANDLE ProcessId,
+ _In_ PPS_CREATE_NOTIFY_INFO CreateInfo
+)
+{
+ NTSTATUS status;
+ FILETIME fileTime;
+ HANDLE hCreateProcessThread = NULL;
+ UNICODE_STRING commandLine{ 0 };
+
+ PAGED_CODE();
+
+ if (CreateInfo == NULL)
+ {
+ goto Exit;
+
+ }
+ KeQuerySystemTime(&fileTime);
+ auto callbackInfo = (PPROCESS_CREATE_CALLBACK_INFO)ExAllocatePool2(POOL_FLAG_PAGED, sizeof(PROCESS_CREATE_CALLBACK_INFO), SYSTEM_THREAD_TAG);
+ if (callbackInfo == NULL) {
+ return;
+ }
+
+ callbackInfo->ParentProcessId = CreateInfo->ParentProcessId;
+ callbackInfo->FileTime = fileTime;
+ callbackInfo->CreatorId = CreateInfo->CreatingThreadId;
+ callbackInfo->ProcessId = ProcessId;
+ callbackInfo->Process = Process;
+ //callbackInfo->CommandLine = CreateInfo->CommandLine->Buffer;
+
+ //
+ //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)
+ {
+ ExFreePoolWithTag(commandLine.Buffer, SYSTEM_THREAD_TAG);
+ ExFreePoolWithTag(callbackInfo, SYSTEM_THREAD_TAG);
+ 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);
+ }
+
+ callbackInfo->CommandLine = commandLine;
+
+
+ OBJECT_ATTRIBUTES objectAttributes;
+ InitializeObjectAttributes(&objectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
+
+ status = PsCreateSystemThread(&hCreateProcessThread, THREAD_ALL_ACCESS, &objectAttributes, NULL, NULL, (PKSTART_ROUTINE)CreateProcessWorkerThread, callbackInfo);
+ if (!NT_SUCCESS(status)) {
+ DbgPrint("PsCreateSystemThread failed: %x\n", status);
+ ExFreePoolWithTag(callbackInfo, SYSTEM_THREAD_TAG);
+ return;
+ }
+
+Exit:
+ if (hCreateProcessThread != NULL)
+ {
+ ZwClose(hCreateProcessThread);
+ }
+}
+
+
+// [DONE]
+// Post Handle (Open/Duplication) Worker Thread
+//
+VOID PostHandleWorkerThread(PVOID StartContext) {
+ PHANDLE_CREATION_CALLBACK_INFO callbackInfo = NULL;
+ UNICODE_STRING TargetImagePath{}, RequestorImagePath{}, SourceFullUserName{};
+ NTSTATUS status;
+
+ PAGED_CODE();
+
+ callbackInfo = (PHANDLE_CREATION_CALLBACK_INFO)StartContext;
+ if (callbackInfo == NULL)
+ {
+ goto Exit;
+ }
+
+ FILETIME filetime = callbackInfo->FileTime;
+ HANDLE targetPID = callbackInfo->TargetProcessId;
+ HANDLE sourcePID = callbackInfo->SourceProcessId;
+ ULONGLONG UTargetPID = HandleToULong(targetPID);
+ ULONGLONG USourcePID = HandleToULong(sourcePID);
+ ULONGLONG sourceThreadId = HandleToULong(callbackInfo->SourceThreadId);
+ ULONGLONG sourceProcessStartKey = callbackInfo->SourceProcessStartKey;
+ ULONGLONG targetProcessStartKey = callbackInfo->TargetProcessStartKey;
+ DWORD OperationType = callbackInfo->OperationType;
+ ACCESS_MASK DesiredAccess = callbackInfo->DesiredAccess;
+
+
+ RequestorImagePath.Length = 0;
+ RequestorImagePath.MaximumLength = MAX_ALLOC;
+ RequestorImagePath.Buffer = (PWSTR)ExAllocatePool2(POOL_FLAG_PAGED, MAX_ALLOC, SYSTEM_THREAD_TAG);
+ status = GetProcessImageName(sourcePID, &RequestorImagePath);
+ if (!NT_SUCCESS(status)) {
+ goto Exit;
+ }
+
+ SourceFullUserName.Length = 0;
+ SourceFullUserName.MaximumLength = MAX_ALLOC;
+ SourceFullUserName.Buffer = (PWCH)ExAllocatePool2(POOL_FLAG_PAGED, SourceFullUserName.MaximumLength, SYSTEM_THREAD_TAG);
+ if (SourceFullUserName.Buffer == NULL) {
+ goto Exit;
+ }
+
+ DWORD SourceAuthenticationId = 0;
+ status = GetProcessUserName(&SourceFullUserName, sourcePID, &SourceAuthenticationId);
+ if (!NT_SUCCESS(status))
+ {
+ goto Exit;
+ }
+
+ TargetImagePath.Length = 0;
+ TargetImagePath.MaximumLength = MAX_ALLOC;
+ TargetImagePath.Buffer = (PWSTR)ExAllocatePool2(POOL_FLAG_PAGED, MAX_ALLOC, SYSTEM_THREAD_TAG);
+ status = GetProcessImageName(targetPID, &TargetImagePath);
+ if (!NT_SUCCESS(status)) {
+ goto Exit;
+ }
+ if (OperationType == 1) {
+ EventWriteProcessAccess(NULL, &filetime, DesiredAccess, UTargetPID, targetProcessStartKey, TargetImagePath.Buffer, USourcePID, sourceThreadId, sourceProcessStartKey, RequestorImagePath.Buffer, SourceFullUserName.Buffer, SourceAuthenticationId);
+
+
+ //
+ // Grabbing impersonation data
+ //
+ HANDLE hToken = NULL;
+ status = GetProcessToken(sourcePID, &hToken);
+ if (!NT_SUCCESS(status)) {
+ goto Exit;
+ }
+ DWORD SessionId = GetSessionIdFromToken(hToken);
+ if (SessionId != 0) {
+ status = ThreadImpersonationEvent(hToken, callbackInfo->SourceThread, L"OpenProcess", RequestorImagePath.Buffer, USourcePID, sourceProcessStartKey, UTargetPID, targetProcessStartKey);
+ }
+ if (hToken != NULL) {
+ ZwClose(hToken);
+ }
+ //
+ // End of querying for impersonation
+ //
+ goto Exit;
+ }
+ if (OperationType == 2) {
+ EventWriteProcessAccessDuplicated(NULL, &filetime, DesiredAccess, UTargetPID, targetProcessStartKey, TargetImagePath.Buffer, USourcePID, sourceThreadId, sourceProcessStartKey, RequestorImagePath.Buffer, SourceFullUserName.Buffer, SourceAuthenticationId);
+ goto Exit;
+ }
+
+Exit:
+ if (TargetImagePath.Buffer != NULL) {
+ ExFreePoolWithTag(TargetImagePath.Buffer, SYSTEM_THREAD_TAG);
+ }
+ if (SourceFullUserName.Buffer != NULL) {
+ ExFreePoolWithTag(SourceFullUserName.Buffer, SYSTEM_THREAD_TAG);
+ }
+ if (RequestorImagePath.Buffer != NULL) {
+ ExFreePoolWithTag(RequestorImagePath.Buffer, SYSTEM_THREAD_TAG);
+ }
+ ExFreePoolWithTag(StartContext, SYSTEM_THREAD_TAG);
+
+
+ PsTerminateSystemThread(STATUS_SUCCESS);
+}
+
+_IRQL_requires_max_(PASSIVE_LEVEL)
+void PostProcessHandleCallback(
+ _In_ PVOID RegistrationContext,
+ _In_ POB_POST_OPERATION_INFORMATION OperationInformation
+) {
+ UNREFERENCED_PARAMETER(RegistrationContext);
+ HANDLE hPostHandleWorkerThread = NULL;
+ NTSTATUS status;
+ FILETIME filetime;
+
+ PAGED_CODE();
+
+ PEPROCESS targetProcess = (PEPROCESS)OperationInformation->Object;
+
+ HANDLE TargetProcessId = PsGetProcessId(targetProcess);
+ HANDLE SourceProcessId = PsGetCurrentProcessId();
+
+ if ((HANDLE)g_ServicePID == SourceProcessId) {
+ goto Exit;
+ }
+
+ ACCESS_MASK CreatedGrantedAccess = OperationInformation->Parameters->CreateHandleInformation.GrantedAccess;
+
+ KeQuerySystemTime(&filetime);
+
+ if (CreatedGrantedAccess == 0x0) {
+ goto Exit;
+ }
+
+ if (SourceProcessId == TargetProcessId) {
+ goto Exit;
+ }
+
+ if (SourceProcessId == (HANDLE)0x4 || TargetProcessId == (HANDLE)0x4) {
+ goto Exit;
+ }
+
+ PHANDLE_CREATION_CALLBACK_INFO callbackInfo = NULL;
+ callbackInfo = (PHANDLE_CREATION_CALLBACK_INFO)ExAllocatePool2(POOL_FLAG_PAGED, sizeof(HANDLE_CREATION_CALLBACK_INFO), SYSTEM_THREAD_TAG);
+ if (callbackInfo == NULL) {
+ DbgPrint("ExAllocatePool2 failed\n");
+ goto Exit;
+ }
+
+ callbackInfo->SourceProcessId = SourceProcessId;
+ callbackInfo->SourceThreadId = PsGetCurrentThreadId();
+ callbackInfo->TargetProcessId = TargetProcessId;
+ callbackInfo->SourceProcessStartKey = PsGetProcessStartKey(PsGetCurrentProcess());
+ callbackInfo->TargetProcessStartKey = PsGetProcessStartKey(targetProcess);
+ callbackInfo->FileTime = filetime;
+ callbackInfo->SourceThread = PsGetCurrentThread();
+
+ switch (OperationInformation->Operation)
+ {
+ case OB_OPERATION_HANDLE_CREATE:
+ {
+ callbackInfo->DesiredAccess = CreatedGrantedAccess;
+ callbackInfo->OperationType = 1;
+ break;
+ }
+ case OB_OPERATION_HANDLE_DUPLICATE:
+ {
+ if ((CreatedGrantedAccess & 0x40) != 0x40) {
+ if(callbackInfo != NULL)
+ {
+ ExFreePoolWithTag(callbackInfo, SYSTEM_THREAD_TAG);
+ }
+ return;
+ }
+ ACCESS_MASK DuplicatedRights = OperationInformation->Parameters->DuplicateHandleInformation.GrantedAccess;
+ callbackInfo->DesiredAccess = DuplicatedRights;
+ callbackInfo->OperationType = 2;
+ break;
+ }
+ }
+
+ OBJECT_ATTRIBUTES objectAttributes;
+ InitializeObjectAttributes(&objectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
+
+ status = PsCreateSystemThread(&hPostHandleWorkerThread, THREAD_ALL_ACCESS, &objectAttributes, NULL, NULL, (PKSTART_ROUTINE)PostHandleWorkerThread, callbackInfo);
+ if (!NT_SUCCESS(status)) {
+ DbgPrint("PsCreateSystemThread failed: %x\n", status);
+ ExFreePoolWithTag(callbackInfo, SYSTEM_THREAD_TAG);
+ goto Exit;
+ }
+Exit:
+ if(hPostHandleWorkerThread != NULL)
+ {
+ ZwClose(hPostHandleWorkerThread);
+ }
+ return;
+}
+
+// [DONE]
+// Callback to capture process termination events
+//
+_IRQL_requires_max_(PASSIVE_LEVEL)
+void TerminateProcessNotifyRoutine(
+ _In_ HANDLE ParentProcessId,
+ _In_ HANDLE ProcessId,
+ _In_ BOOLEAN Create
+)
+{
+ NTSTATUS status;
+ UNICODE_STRING targetImagePath{};
+ UNICODE_STRING sourceImagePath{};
+
+ HANDLE sourcePID = NULL;
+ HANDLE targetPID = NULL;
+ FILETIME fileTime;
+
+ PAGED_CODE();
+ UNREFERENCED_PARAMETER(ParentProcessId);
+ UNREFERENCED_PARAMETER(ProcessId);
+
+ if (!Create)
+ {
+ KeQuerySystemTime(&fileTime);
+
+ targetPID = ProcessId;
+ sourcePID = ParentProcessId;
+
+ ULONGLONG uTargetPID = HandleToULong(targetPID);
+ ULONGLONG uSourcePID = HandleToULong(sourcePID);
+ ULONGLONG sourceThreadId = HandleToULong(PsGetCurrentThreadId());
+
+ sourceImagePath.Length = 0;
+ sourceImagePath.MaximumLength = MAX_ALLOC;
+ sourceImagePath.Buffer = (PWCH)ExAllocatePool2(POOL_FLAG_PAGED, sourceImagePath.MaximumLength, CALBACK_TAG);
+ status = GetProcessImageName(sourcePID, &sourceImagePath);
+ if (status != STATUS_SUCCESS) {
+ sourceImagePath.Buffer = NULL;
+ }
+
+ targetImagePath.Length = 0;
+ targetImagePath.MaximumLength = MAX_ALLOC;
+ targetImagePath.Buffer = (PWCH)ExAllocatePool2(POOL_FLAG_PAGED, targetImagePath.MaximumLength, CALBACK_TAG);
+ status = GetProcessImageName(targetPID, &targetImagePath);
+ if (status != STATUS_SUCCESS) {
+ targetImagePath.Buffer = NULL;
+ }
+
+ EventWriteProcessTerminate(NULL, &fileTime, sourceImagePath.Buffer, uSourcePID, sourceThreadId, targetImagePath.Buffer, uTargetPID);
+ goto Exit;
+ }
+Exit:
+ if (targetImagePath.Buffer != NULL) {
+ ExFreePoolWithTag(targetImagePath.Buffer, CALBACK_TAG);
+ }
+
+ if (sourceImagePath.Buffer != NULL) {
+ ExFreePoolWithTag(sourceImagePath.Buffer, CALBACK_TAG);
+ }
+}
\ No newline at end of file
diff --git a/JonMon/callbacks.h b/JonMon/callbacks.h
new file mode 100644
index 0000000..0078665
--- /dev/null
+++ b/JonMon/callbacks.h
@@ -0,0 +1,107 @@
+#ifndef _CALLBACK_
+#define _CALLBACK_
+#include "shared.h"
+
+extern ULONG g_ServicePID;
+
+extern PVOID ProcessRegistrationHandle;
+extern PVOID ThreadRegistrationHandle;
+
+_IRQL_requires_max_(PASSIVE_LEVEL)
+NTSTATUS RegisterCallbacks(
+ _In_ PDRIVER_OBJECT DriverObject,
+ _In_ PDEVICE_OBJECT DeviceObject
+);
+
+_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
+);
+
+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;
+
+#endif // !_CALLBACK_
diff --git a/JonMon/driver.cpp b/JonMon/driver.cpp
new file mode 100644
index 0000000..d02f47b
--- /dev/null
+++ b/JonMon/driver.cpp
@@ -0,0 +1,225 @@
+#include "driver.h"
+#include "callbacks.h"
+#include "process.h"
+
+extern "C"
+NTSTATUS DriverEntry(
+ _In_ PDRIVER_OBJECT DriverObject,
+ _In_ PUNICODE_STRING RegistryPath
+)
+{
+ EventRegisterJonMon();
+ 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;
+ }
+
+ g_RegPath.Length = g_RegPath.MaximumLength = RegistryPath->Length;
+ memcpy(g_RegPath.Buffer, RegistryPath->Buffer, g_RegPath.Length);
+
+ DbgPrint("JonMon Driver Entry Called 0x%p\n", DriverObject);
+ DbgPrint("Registry Path %wZ\n", g_RegPath);
+
+ 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;
+ }
+
+ status = RegisterCallbacks(DriverObject, DeviceObject);
+ if (!NT_SUCCESS(status)) {
+ DbgPrint("Error registering callbacks: 0x%X\n", status);
+ ExFreePool(g_RegPath.Buffer);
+ 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();
+ }
+ return CompleteRequest(Irp, status, len);
+}
+
+VOID AlterPPL(
+ _In_ ULONG PID,
+ _In_ ULONG value
+) {
+ 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) + 0x878);
+ 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();
+ EventUnregisterJonMon();
+
+ AlterPPL(g_ServicePID, 0);
+
+ CmUnRegisterCallback(Cookie);
+
+ ObUnRegisterCallbacks(ProcessRegistrationHandle);
+ DbgPrint((DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "PostProcessHandleCallback Unloaded\n"));
+
+ PsSetCreateProcessNotifyRoutineEx(CreateProcessNotifyRoutineEx, TRUE);
+ DbgPrint((DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "PsSetCreateProcessNotifyRoutineEx Unloaded\n"));
+
+ PsRemoveLoadImageNotifyRoutine(LoadImageRoutine);
+ DbgPrint((DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "PsSetLoadImageNotifyRoutine Unloaded\n"));
+
+ PsRemoveCreateThreadNotifyRoutine(PsCreateThreadNotifyRoutine);
+ DbgPrint((DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "PsSetCreateThreadNotifyRoutine Unloaded\n"));
+
+
+ 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);
+}
\ No newline at end of file
diff --git a/JonMon/driver.h b/JonMon/driver.h
new file mode 100644
index 0000000..1a854cf
--- /dev/null
+++ b/JonMon/driver.h
@@ -0,0 +1,100 @@
+#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)
+
+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_
\ No newline at end of file
diff --git a/JonMon/jtime.h b/JonMon/jtime.h
new file mode 100644
index 0000000..fcc2afe
--- /dev/null
+++ b/JonMon/jtime.h
@@ -0,0 +1,22 @@
+#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_
\ No newline at end of file
diff --git a/JonMon/minifilter.cpp b/JonMon/minifilter.cpp
new file mode 100644
index 0000000..b493183
--- /dev/null
+++ b/JonMon/minifilter.cpp
@@ -0,0 +1,520 @@
+#include "minifilter.h"
+#include "thread.h"
+#include "process.h"
+#include "token.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;
+}
+
+
+/*
+From: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/fltkernel/nc-fltkernel-pflt_post_operation_callback
+Post-operation callback routines are called in an arbitrary thread context, at IRQL <= DISPATCH_LEVEL. Because this callback routine can be called at IRQL DISPATCH_LEVEL, it is subject to the following constraints:
+
+It cannot safely call any kernel-mode routine that must run at a lower IRQL.
+Any data structures used in this routine must be allocated from nonpaged pool.
+It cannot be made pageable.
+It cannot acquire resources, mutexes, or fast mutexes. However, it can acquire spin locks.
+It cannot get, set, or delete contexts, but it can release contexts.
+Any I/O completion processing that needs to be performed at IRQL < DISPATCH_LEVEL cannot be performed directly in the postoperation callback routine. Instead, it must be posted to a work queue by calling a routine such as FltDoCompletionProcessingWhenSafe or FltQueueDeferredIoWorkItem.
+
+
+All memory allocation needs to be non-paged pool.
+
+To-Do: Update all functions to use non-paged pool.
+*/
+_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);
+ HANDLE currentProcessId = PsGetCurrentProcessId();
+ UNICODE_STRING sourceImage{}, sourceUserName{}, sourceIntegrityLevel{};
+ ULONGLONG sourceProcStartKey = PsGetProcessStartKey(PsGetCurrentProcess());
+ FILETIME filetime;
+ HANDLE sToken = NULL;
+ NTSTATUS status;
+ DWORD sourceAuthenticationId = 0;
+ PFLT_FILE_NAME_INFORMATION fileNameInfo = NULL;
+
+
+ if (Data->RequestorMode != UserMode) {
+ goto Exit;
+ }
+
+ //
+ //Checking IRQL for now until functions are using non-paged pool
+ //
+
+ if (KeGetCurrentIrql() == DISPATCH_LEVEL) {
+ goto Exit;
+ }
+
+ if (currentProcessId == (HANDLE)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 = GetProcessToken(currentProcessId, &sToken);
+ if (!NT_SUCCESS(status) || sToken == NULL)
+ {
+ DbgPrint("[IRP_MJ_SET_INFORMATION] Failed to get process token\n");
+ goto Exit;
+ }
+
+ status = GetTokenIntegrityLevel(sToken, &sourceIntegrityLevel);
+ if (!NT_SUCCESS(status) || sourceIntegrityLevel.Buffer == NULL)
+ {
+ DbgPrint("[IRP_MJ_SET_INFORMATION] Failed to get token integrity level\n");
+ goto Exit;
+ }
+
+ //
+ // Check to make sure integrity level == System
+ //
+ if (wcscmp(sourceIntegrityLevel.Buffer, L"System") == 0)
+ {
+ goto Exit;
+ }
+
+ sourceImage.Length = 0;
+ sourceImage.MaximumLength = MAX_ALLOC;
+ sourceImage.Buffer = (PWSTR)ExAllocatePool2(POOL_FLAG_PAGED, MAX_ALLOC, FILE_TAG);
+ status = GetProcessImageName(currentProcessId, &sourceImage);
+ if (!NT_SUCCESS(status)) {
+ DbgPrint("[IRP_MJ_CREATE] Failed to get process image name\n");
+ goto Exit;
+ }
+
+ sourceUserName.Length = 0;
+ sourceUserName.MaximumLength = MAX_ALLOC;
+ sourceUserName.Buffer = (PWSTR)ExAllocatePool2(POOL_FLAG_PAGED, MAX_ALLOC, FILE_TAG);
+
+ status = GetProcessUserName(&sourceUserName, currentProcessId, &sourceAuthenticationId);
+ if (!NT_SUCCESS(status))
+ {
+ DbgPrint("[IRP_MJ_CREATE] Failed to get process username\n");
+ goto Exit;
+
+ }
+
+ status = FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP, &fileNameInfo);
+ if (!NT_SUCCESS(status)) {
+ goto Exit;
+ }
+
+ EventWriteFileCreate(NULL, &filetime, sourceImage.Buffer, reinterpret_cast(currentProcessId), sourceProcStartKey, reinterpret_cast(sourceThreadId), sourceUserName.Buffer, sourceAuthenticationId, sourceIntegrityLevel.Buffer, fileNameInfo->Name.Buffer);
+ goto Exit;
+
+ }
+
+ default:
+ {
+ goto Exit;
+ }
+
+ }
+ goto Exit;
+ }
+ 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)
+ {
+ sourceImage.Length = 0;
+ sourceImage.MaximumLength = MAX_ALLOC;
+ sourceImage.Buffer = (PWSTR)ExAllocatePool2(POOL_FLAG_PAGED, MAX_ALLOC, FILE_TAG);
+ status = GetProcessImageName(currentProcessId, &sourceImage);
+ if (!NT_SUCCESS(status))
+ {
+ DbgPrint("[IRP_MJ_CREATE_NAMED_PIPE] Failed to get process image name\n");
+ goto Exit;
+ }
+
+ sourceUserName.Length = 0;
+ sourceUserName.MaximumLength = MAX_ALLOC;
+ sourceUserName.Buffer = (PWSTR)ExAllocatePool2(POOL_FLAG_PAGED, MAX_ALLOC, FILE_TAG);
+
+ status = GetProcessUserName(&sourceUserName, currentProcessId, &sourceAuthenticationId);
+ if (!NT_SUCCESS(status))
+ {
+ DbgPrint("[IRP_MJ_CREATE_NAMED_PIPE] Failed to get process username\n");
+ goto Exit;
+
+ }
+
+ status = GetProcessToken(currentProcessId, &sToken);
+ if (!NT_SUCCESS(status)) {
+ DbgPrint("[IRP_MJ_CREATE_NAMED_PIPE] Failed to get process token\n");
+ goto Exit;
+ }
+
+ status = GetTokenIntegrityLevel(sToken, &sourceIntegrityLevel);
+ if (!NT_SUCCESS(status)) {
+ DbgPrint("[IRP_MJ_CREATE_NAMED_PIPE] Failed to get token integrity level\n");
+ goto Exit;
+ }
+
+ 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;
+ }
+ EventWriteNamedPipeCreate(NULL, &filetime, sourceImage.Buffer, reinterpret_cast(currentProcessId), sourceProcStartKey, reinterpret_cast(sourceThreadId), sourceUserName.Buffer, sourceAuthenticationId, sourceIntegrityLevel.Buffer, fileNameInfo->Name.Buffer, RemoteCreation, RequestedRights);
+ goto Exit;
+ }
+ case FILE_OPENED:
+ {
+ EventWriteNamedPipeOpen(NULL, &filetime, sourceImage.Buffer, reinterpret_cast(currentProcessId), sourceProcStartKey, reinterpret_cast(sourceThreadId), sourceUserName.Buffer, sourceAuthenticationId, sourceIntegrityLevel.Buffer, fileNameInfo->Name.Buffer, RequestedRights, GrantedRights);
+ goto Exit;
+ }
+ default:
+ {
+ goto Exit;
+ }
+ }
+ }
+ goto Exit;
+ }
+ case IRP_MJ_SET_INFORMATION:
+ {
+ if (Data->Iopb->TargetFileObject->FileName.Buffer == NULL) {
+ goto Exit;
+ }
+ switch (Data->Iopb->Parameters.SetFileInformation.FileInformationClass) {
+ //
+ // File Deletes
+ //
+ case FileDispositionInformation:
+ {
+
+ status = GetProcessToken(currentProcessId, &sToken);
+ if (!NT_SUCCESS(status) || sToken == NULL)
+ {
+ DbgPrint("[IRP_MJ_SET_INFORMATION] Failed to get process token\n");
+ goto Exit;
+ }
+
+ status = GetTokenIntegrityLevel(sToken, &sourceIntegrityLevel);
+ if (!NT_SUCCESS(status) || sourceIntegrityLevel.Buffer == NULL)
+ {
+ DbgPrint("[IRP_MJ_SET_INFORMATION] Failed to get token integrity level\n");
+ goto Exit;
+ }
+
+ //
+ // Check to make sure integrity level == System
+ //
+ if (wcscmp(sourceIntegrityLevel.Buffer, L"System") == 0)
+ {
+ goto Exit;
+ }
+
+ sourceUserName.Length = 0;
+ sourceUserName.MaximumLength = MAX_ALLOC;
+ sourceUserName.Buffer = (PWSTR)ExAllocatePool2(POOL_FLAG_PAGED, MAX_ALLOC, FILE_TAG);
+
+ status = GetProcessUserName(&sourceUserName, currentProcessId, &sourceAuthenticationId);
+ if (!NT_SUCCESS(status))
+ {
+ DbgPrint("[IRP_MJ_SET_INFORMATION] Failed to get process username\n");
+ goto Exit;
+
+ }
+
+ sourceImage.Length = 0;
+ sourceImage.MaximumLength = MAX_ALLOC;
+ sourceImage.Buffer = (PWSTR)ExAllocatePool2(POOL_FLAG_PAGED, MAX_ALLOC, FILE_TAG);
+ status = GetProcessImageName(currentProcessId, &sourceImage);
+ if (!NT_SUCCESS(status)) {
+ DbgPrint("[IRP_MJ_SET_INFORMATION] Failed to get process image name\n");
+ goto Exit;
+ }
+
+
+
+ status = FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP, &fileNameInfo);
+ if (!NT_SUCCESS(status)) {
+ goto Exit;
+ }
+
+ EventWriteFileDelete(NULL, &filetime, sourceImage.Buffer, reinterpret_cast(currentProcessId), sourceProcStartKey, reinterpret_cast(sourceThreadId), sourceUserName.Buffer, sourceAuthenticationId, sourceIntegrityLevel.Buffer, fileNameInfo->Name.Buffer);
+ goto Exit;
+ }
+ //
+ // File Deletes
+ //
+ case FileDispositionInformationEx:
+ {
+ status = GetProcessToken(currentProcessId, &sToken);
+ if (!NT_SUCCESS(status) || sToken == NULL)
+ {
+ DbgPrint("[IRP_MJ_SET_INFORMATION] Failed to get process token\n");
+ goto Exit;
+ }
+
+ status = GetTokenIntegrityLevel(sToken, &sourceIntegrityLevel);
+ if (!NT_SUCCESS(status) || sourceIntegrityLevel.Buffer == NULL)
+ {
+ DbgPrint("[IRP_MJ_SET_INFORMATION] Failed to get token integrity level\n");
+ goto Exit;
+ }
+
+ //
+ // Check to make sure integrity level == System
+ //
+ if (wcscmp(sourceIntegrityLevel.Buffer, L"System") == 0)
+ {
+ goto Exit;
+ }
+ sourceImage.Length = 0;
+ sourceImage.MaximumLength = MAX_ALLOC;
+ sourceImage.Buffer = (PWSTR)ExAllocatePool2(POOL_FLAG_PAGED, MAX_ALLOC, FILE_TAG);
+ status = GetProcessImageName(currentProcessId, &sourceImage);
+ if (!NT_SUCCESS(status)) {
+ DbgPrint("[IRP_MJ_SET_INFORMATION] Failed to get process image name\n");
+ goto Exit;
+ }
+
+ sourceUserName.Length = 0;
+ sourceUserName.MaximumLength = MAX_ALLOC;
+ sourceUserName.Buffer = (PWSTR)ExAllocatePool2(POOL_FLAG_PAGED, MAX_ALLOC, FILE_TAG);
+
+ status = GetProcessUserName(&sourceUserName, currentProcessId, &sourceAuthenticationId);
+ if (!NT_SUCCESS(status))
+ {
+ DbgPrint("[IRP_MJ_SET_INFORMATION] Failed to get process username\n");
+ goto Exit;
+
+ }
+
+ status = FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP, &fileNameInfo);
+ if (!NT_SUCCESS(status)) {
+ goto Exit;
+ }
+
+ EventWriteFileDelete(NULL, &filetime, sourceImage.Buffer, reinterpret_cast(currentProcessId), sourceProcStartKey, reinterpret_cast(sourceThreadId), sourceUserName.Buffer, sourceAuthenticationId, sourceIntegrityLevel.Buffer, fileNameInfo->Name.Buffer);
+ goto Exit;
+ }
+ //
+ // File Renames
+ //
+ case FileRenameInformation:
+ {
+ sourceImage.Length = 0;
+ sourceImage.MaximumLength = MAX_ALLOC;
+ sourceImage.Buffer = (PWSTR)ExAllocatePool2(POOL_FLAG_PAGED, MAX_ALLOC, FILE_TAG);
+ status = GetProcessImageName(currentProcessId, &sourceImage);
+ if (!NT_SUCCESS(status)) {
+ DbgPrint("[IRP_MJ_SET_INFORMATION] Failed to get process image name\n");
+ }
+
+ sourceUserName.Length = 0;
+ sourceUserName.MaximumLength = MAX_ALLOC;
+ sourceUserName.Buffer = (PWSTR)ExAllocatePool2(POOL_FLAG_PAGED, MAX_ALLOC, FILE_TAG);
+
+ status = GetProcessUserName(&sourceUserName, currentProcessId, &sourceAuthenticationId);
+ if (!NT_SUCCESS(status))
+ {
+ DbgPrint("[IRP_MJ_SET_INFORMATION] Failed to get process username\n");
+ goto Exit;
+
+ }
+
+ status = GetProcessToken(currentProcessId, &sToken);
+ if (!NT_SUCCESS(status) || sToken == NULL)
+ {
+ DbgPrint("[IRP_MJ_SET_INFORMATION] Failed to get process token\n");
+ goto Exit;
+ }
+
+ status = GetTokenIntegrityLevel(sToken, &sourceIntegrityLevel);
+ if (!NT_SUCCESS(status))
+ {
+ DbgPrint("[IRP_MJ_SET_INFORMATION] Failed to get token integrity level\n");
+ goto Exit;
+ }
+
+ status = FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP, &fileNameInfo);
+ if (!NT_SUCCESS(status)) {
+ goto Exit;
+ }
+ EventWriteFileRename(NULL, &filetime, sourceImage.Buffer, reinterpret_cast(currentProcessId), sourceProcStartKey, reinterpret_cast(sourceThreadId), sourceUserName.Buffer, sourceAuthenticationId, sourceIntegrityLevel.Buffer, fileNameInfo->Name.Buffer);
+ goto Exit;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+Exit:
+ if (sourceImage.Buffer != NULL) {
+ ExFreePool(sourceImage.Buffer);
+ }
+ if (sourceUserName.Buffer != NULL) {
+ ExFreePool(sourceUserName.Buffer);
+ }
+ if (sToken != NULL)
+ {
+ ZwClose(sToken);
+ }
+ 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_SET_INFORMATION,
+ 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;
+}
\ No newline at end of file
diff --git a/JonMon/minifilter.h b/JonMon/minifilter.h
new file mode 100644
index 0000000..27a6f85
--- /dev/null
+++ b/JonMon/minifilter.h
@@ -0,0 +1,41 @@
+#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_
\ No newline at end of file
diff --git a/JonMon/process.cpp b/JonMon/process.cpp
new file mode 100644
index 0000000..a31f391
--- /dev/null
+++ b/JonMon/process.cpp
@@ -0,0 +1,132 @@
+#include "process.h"
+#include "token.h"
+
+PAGED_FILE();
+
+ZWQUERYINFORMATIONPROCESS ZwQueryInformationProcess;
+
+NTSTATUS GetProcessImageName(HANDLE processId, PUNICODE_STRING ProcessImageName)
+{
+ //Add NtQueryInformationProcess - https://stackoverflow.com/questions/3707133/how-to-use-zwqueryinformationprocess-to-get-processimagefilename-in-a-kernel-dri
+ PAGED_CODE();
+ NTSTATUS status;
+ ULONG returnedLength;
+ ULONG bufferLength;
+ HANDLE hProcess = NULL;
+ PVOID buffer{};
+ PEPROCESS eProcess;
+ //PUNICODE_STRING imageName;
+ 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;
+ }
+ //imageName = (PUNICODE_STRING)buffer;
+ 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;
+}
+NTSTATUS GetProcessToken(HANDLE processId, PHANDLE hToken) {
+ PAGED_CODE();
+ NTSTATUS status;
+ PEPROCESS eProcess;
+ HANDLE hProcess = NULL;
+ HANDLE htok = NULL;
+ 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))
+ {
+ DbgPrint("ObOpenObjectByPointer Failed: %08x\n", status);
+ goto Exit;
+ }
+ ObDereferenceObject(eProcess);
+ status = ZwOpenProcessTokenEx(hProcess, TOKEN_QUERY, OBJ_KERNEL_HANDLE, &htok);
+ if (!NT_SUCCESS(status) || htok == NULL) {
+ DbgPrint("ZwOpenProcessTokenEx Failed: %08x\n", status);
+ goto Exit;
+ }
+
+Exit:
+ if (htok == NULL) {
+ status = STATUS_UNSUCCESSFUL;
+ }
+ *hToken = htok;
+ if (hProcess != NULL)
+ {
+ ZwClose(hProcess);
+ }
+ return status;
+}
\ No newline at end of file
diff --git a/JonMon/process.h b/JonMon/process.h
new file mode 100644
index 0000000..ecc0beb
--- /dev/null
+++ b/JonMon/process.h
@@ -0,0 +1,17 @@
+#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_
diff --git a/JonMon/registry.cpp b/JonMon/registry.cpp
new file mode 100644
index 0000000..1712b97
--- /dev/null
+++ b/JonMon/registry.cpp
@@ -0,0 +1,484 @@
+#include "registry.h"
+#include "shared.h"
+#include "token.h"
+#include "process.h"
+#include "thread.h"
+#include
+
+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("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;
+}
+
+NTSTATUS
+GetRegistryEventInfo(
+ _In_ HANDLE pid,
+ _In_ PUNICODE_STRING pRequestorImagePath,
+ _In_ PUNICODE_STRING pFullUserName,
+ _In_ PULONG pLogonId
+) {
+ // Get process image name
+ pRequestorImagePath->Length = 0;
+ pRequestorImagePath->MaximumLength = MAX_ALLOC;
+ pRequestorImagePath->Buffer = (PWSTR)ExAllocatePool2(POOL_FLAG_PAGED, MAX_ALLOC, REGISTRY_TAG);
+ NTSTATUS status = GetProcessImageName(pid, pRequestorImagePath);
+ if (!NT_SUCCESS(status)) {
+ DbgPrint("GetProcessImageName failed. Status 0x%x", status);
+ pRequestorImagePath->Buffer = L"Unknown";
+ }
+
+ // Get process username and logon ID
+ pFullUserName->Length = 0;
+ pFullUserName->MaximumLength = MAX_ALLOC;
+ pFullUserName->Buffer = (PWSTR)ExAllocatePool2(POOL_FLAG_PAGED, MAX_ALLOC, REGISTRY_TAG);
+ *pLogonId = 0;
+ status = GetProcessUserName(pFullUserName, pid, pLogonId);
+ if (!NT_SUCCESS(status)) {
+ DbgPrint("GetProcessUserName failed. Status 0x%x", status);
+ pFullUserName->Buffer = L"Unknown";
+ }
+
+ return status;
+}
+
+VOID
+DeleteKey(
+ _In_ PVOID context,
+ _In_ PREG_DELETE_KEY_INFORMATION info
+) {
+ UNREFERENCED_PARAMETER(context);
+ HANDLE Requestorpid = PsGetCurrentProcessId();
+ UNICODE_STRING RequestorImagePath{};
+ UNICODE_STRING FullUserName{};
+ ULONG LogonId;
+ ULONGLONG sourceProcStartKey = PsGetProcessStartKey(PsGetCurrentProcess());
+ ULONGLONG USourceProcessId = HandleToULong(Requestorpid);
+ ULONGLONG sourceThreadId = HandleToULong(PsGetCurrentThreadId());
+ FILETIME fileTime;
+ PCWSTR keyPath = NULL;
+ NTSTATUS status;
+
+ PAGED_CODE();
+
+ status = GetRegistryKeyPath(info->Object, REGISTRY_TAG, &keyPath);
+ if (keyPath == NULL) {
+ goto Exit;
+ }
+
+ RequestorImagePath.Length = 0;
+ RequestorImagePath.MaximumLength = MAX_ALLOC;
+ RequestorImagePath.Buffer = (PWSTR)ExAllocatePool2(POOL_FLAG_PAGED, MAX_ALLOC, REGISTRY_TAG);
+ status = GetProcessImageName(Requestorpid, &RequestorImagePath);
+ if (RequestorImagePath.Length == 0 || RequestorImagePath.Buffer == NULL)
+ {
+ //
+ // fatal
+ //
+ if (keyPath != NULL) {
+ ExFreePoolWithTag((PVOID)keyPath, REGISTRY_TAG);
+ }
+ return;
+ }
+ //
+ // get the username and logon id of the process that is deleting the key
+ //
+ FullUserName.Length = 0;
+ FullUserName.MaximumLength = MAX_ALLOC;
+ FullUserName.Buffer = (PWSTR)ExAllocatePool2(POOL_FLAG_PAGED, MAX_ALLOC, REGISTRY_TAG);
+ LogonId = 0;
+ status = GetProcessUserName(&FullUserName, Requestorpid, &LogonId);
+ if (FullUserName.Length == 0 || FullUserName.Buffer == NULL)
+ {
+ //
+ // fatal
+ //
+ if (keyPath != NULL) {
+ ExFreePoolWithTag((PVOID)keyPath, REGISTRY_TAG);
+ }
+ if (RequestorImagePath.Buffer != NULL) {
+ ExFreePoolWithTag(RequestorImagePath.Buffer, REGISTRY_TAG);
+ }
+ return;
+ }
+
+ KeQuerySystemTime(&fileTime);
+
+
+ EventWriteRegistryDeleteKey(0, &fileTime, RequestorImagePath.Buffer, USourceProcessId, sourceThreadId, sourceProcStartKey, keyPath, FullUserName.Buffer, LogonId);
+
+Exit:
+
+ if (RequestorImagePath.Buffer != NULL) {
+ ExFreePoolWithTag(RequestorImagePath.Buffer, REGISTRY_TAG);
+ }
+ if (FullUserName.Buffer != NULL) {
+ ExFreePoolWithTag(FullUserName.Buffer, REGISTRY_TAG);
+ }
+ if (keyPath != NULL) {
+ ExFreePoolWithTag((PVOID)keyPath, REGISTRY_TAG);
+ }
+ return;
+}
+
+VOID
+SendSetValueRegistryInfo(
+ _In_ PVOID StartContext
+) {
+
+ NTSTATUS status = STATUS_SUCCESS;
+ PCWSTR keyPath = NULL;
+ UNICODE_STRING RequestorImagePath = { 0 };
+ UNICODE_STRING FullUserName = { 0 };
+ ULONG LogonId;
+ HANDLE hToken = NULL;
+ FILETIME fileTime;
+ KeQuerySystemTime(&fileTime);
+
+ PAGED_CODE();
+ PREG_SET_VALUE_CALLBACK_INFO callbackInfo = (PREG_SET_VALUE_CALLBACK_INFO)StartContext;
+ ULONGLONG sourceProcessId = HandleToULong(callbackInfo->SourceProcessId);
+ ULONGLONG sourceThreadId = HandleToULong(callbackInfo->SourceThreadId);
+ ULONGLONG sourceProcStartKey = PsGetProcessStartKey(callbackInfo->SourceProcess);
+ keyPath = callbackInfo->KeyPath;
+ PVOID data = callbackInfo->Data;
+
+ if (data == NULL)
+ {
+ status = STATUS_UNSUCCESSFUL;
+ goto Exit;
+ }
+
+ //
+ //reducing loud noise
+ //
+ if (wcsstr(keyPath, L"DeliveryOptimization\\Usage") != NULL) {
+ goto Exit;
+ }
+ if (wcsstr(keyPath, L"\\DeliveryOptimization\\Config") != NULL) {
+ goto Exit;
+ }
+
+ //
+ //source image path
+ //
+ RequestorImagePath.Length = 0;
+ RequestorImagePath.MaximumLength = MAX_ALLOC;
+ RequestorImagePath.Buffer = (PWSTR)ExAllocatePool2(POOL_FLAG_PAGED, MAX_ALLOC, REGISTRY_TAG);
+ status = GetProcessImageName(callbackInfo->SourceProcessId, &RequestorImagePath);
+ if (RequestorImagePath.Buffer == NULL)
+ {
+ goto Exit;
+ }
+ //
+ // get the username and logon id of the process that is deleting the key
+ //
+ FullUserName.Length = 0;
+ FullUserName.MaximumLength = MAX_ALLOC;
+ FullUserName.Buffer = (PWSTR)ExAllocatePool2(POOL_FLAG_PAGED, MAX_ALLOC, REGISTRY_TAG);
+ LogonId = 0;
+ status = GetProcessUserName(&FullUserName, callbackInfo->SourceProcessId, &LogonId);
+ if (FullUserName.Buffer == NULL)
+ {
+ goto Exit;
+ }
+
+ //
+ // Grabbing impersonation data
+ //
+
+ status = GetProcessToken((HANDLE)sourceProcessId, &hToken);
+ if (!NT_SUCCESS(status)) {
+ goto Exit;
+ }
+ DWORD SessionId = GetSessionIdFromToken(hToken);
+ if (SessionId != 0) {
+ status = ThreadImpersonationEvent(hToken, callbackInfo->SourceThread, L"RegSetValue", RequestorImagePath.Buffer, sourceProcessId, sourceProcStartKey, NULL, NULL);
+ }
+
+ //
+ // End of querying for impersonation
+ //
+
+ switch (callbackInfo->Type) {
+ case REG_DWORD:
+ {
+ ////
+ //// DWORD is 32-bits / 4 bytes
+ ////
+ WCHAR buffer[11]; // Allocate space for up to 10 digits plus the null-terminator
+ swprintf(buffer, L"%u", *(PULONG)data);
+
+ EventWriteRegistrySetValue(0, &fileTime, RequestorImagePath.Buffer, sourceProcessId, sourceThreadId, sourceProcStartKey, keyPath, callbackInfo->ValueName.Buffer, buffer, L"REG_DWORD", FullUserName.Buffer, LogonId);
+
+ goto Exit;
+ }
+ case REG_QWORD:
+ {
+ ////
+ //// QWORD is 64-bits / 8 bytes
+ ////
+ WCHAR buffer[21]; // Allocate space for up to 20 digits plus the null-terminator
+ swprintf(buffer, L"%llu", *(PULONGLONG)data);
+
+
+ EventWriteRegistrySetValue(0, &fileTime, RequestorImagePath.Buffer, sourceProcessId, sourceThreadId, sourceProcStartKey, keyPath, callbackInfo->ValueName.Buffer, buffer, L"REG_QWORD", FullUserName.Buffer, LogonId);
+ goto Exit;
+ }
+ case REG_SZ:
+ {
+ //
+ // Create a buffer to hold the string from data and null-terminate it
+ //
+ PWSTR buffer = (PWSTR)ExAllocatePool2(POOL_FLAG_PAGED, callbackInfo->DataSize + sizeof(WCHAR), REGISTRY_TAG);
+ if (buffer == NULL)
+ {
+ status = STATUS_UNSUCCESSFUL;
+ goto Exit;
+ }
+ RtlCopyMemory(buffer, data, callbackInfo->DataSize);
+ buffer[callbackInfo->DataSize / sizeof(WCHAR)] = L'\0';
+ EventWriteRegistrySetValue(0, &fileTime, RequestorImagePath.Buffer, sourceProcessId, sourceThreadId, sourceProcStartKey, keyPath, callbackInfo->ValueName.Buffer, buffer, L"REG_SZ", FullUserName.Buffer, LogonId);
+
+ //
+ // Free the buffer
+ //
+ ExFreePoolWithTag(buffer, REGISTRY_TAG);
+
+ goto Exit;
+ }
+ default:
+ {
+ goto Exit;
+ }
+ }
+
+Exit:
+ if (RequestorImagePath.Buffer != NULL)
+ {
+ ExFreePoolWithTag(RequestorImagePath.Buffer, REGISTRY_TAG);
+ }
+ if (FullUserName.Buffer != NULL)
+ {
+ ExFreePoolWithTag(FullUserName.Buffer, REGISTRY_TAG);
+ }
+ if (keyPath != NULL)
+ {
+ ExFreePoolWithTag((PVOID)keyPath, SYSTEM_THREAD_TAG);
+ }
+ if (callbackInfo->ValueName.Buffer != NULL)
+ {
+ ExFreePoolWithTag(callbackInfo->ValueName.Buffer, SYSTEM_THREAD_TAG);
+ }
+ if (callbackInfo->Data != NULL) {
+ ExFreePoolWithTag((PVOID)callbackInfo->Data, SYSTEM_THREAD_TAG);
+ }
+ if (callbackInfo != NULL)
+ {
+ ExFreePoolWithTag(StartContext, SYSTEM_THREAD_TAG);
+ }
+
+ PsTerminateSystemThread(STATUS_SUCCESS);
+ return;
+}
+
+VOID
+CreateKey(
+ _In_ PVOID StartContext
+)
+{
+ NTSTATUS status;
+ UNICODE_STRING fullUserName{};
+ UNICODE_STRING sourceImagePath{};
+ ULONG LogonId;
+ FILETIME fileTime;
+ KeQuerySystemTime(&fileTime);
+
+ PAGED_CODE();
+
+ PREG_CREATE_KEY_CALLBACK_INFO callbackInfo = (PREG_CREATE_KEY_CALLBACK_INFO)StartContext;
+ if (callbackInfo == NULL)
+ {
+ goto Exit;
+ }
+
+ ULONGLONG sourceProcessId = HandleToULong(callbackInfo->SourceProcessId);
+ ULONGLONG sourceThreadId = HandleToULong(callbackInfo->SourceThreadId);
+
+ sourceImagePath.Length = 0;
+ sourceImagePath.MaximumLength = MAX_ALLOC;
+ sourceImagePath.Buffer = (PWSTR)ExAllocatePool2(POOL_FLAG_PAGED, MAX_ALLOC, REGISTRY_TAG);
+ status = GetProcessImageName(callbackInfo->SourceProcessId, &sourceImagePath);
+ if (!NT_SUCCESS(status) || sourceImagePath.Buffer == NULL || sourceImagePath.Length == 0) {
+ DbgPrint("GetProcessImageName failed. Status 0x%x", status);
+ goto Exit;
+ }
+
+ fullUserName.Length = 0;
+ fullUserName.MaximumLength = 520;
+ fullUserName.Buffer = (PWSTR)ExAllocatePool2(POOL_FLAG_PAGED, 520, REGISTRY_TAG);
+ status = GetProcessUserName(&fullUserName, callbackInfo->SourceProcessId, &LogonId);
+ if (!NT_SUCCESS(status) || fullUserName.Buffer == NULL || fullUserName.Length == 0) {
+ DbgPrint("GetProcessUserName failed. Status 0x%x", status);
+ goto Exit;
+ }
+
+ EventWriteRegistryCreateKey(0, &fileTime, sourceImagePath.Buffer, sourceProcessId, sourceThreadId, callbackInfo->ProcStartKey, callbackInfo->KeyPath.Buffer, callbackInfo->DesiredAccess, fullUserName.Buffer, LogonId);
+
+
+ //
+ // Grabbing impersonation data
+ //
+ HANDLE hToken = NULL;
+ status = GetProcessToken((HANDLE)sourceProcessId, &hToken);
+ if (NT_SUCCESS(status)) {
+ DWORD SessionId = GetSessionIdFromToken(hToken);
+ if (SessionId != 0) {
+ status = ThreadImpersonationEvent(hToken, callbackInfo->SourceThread, L"RegCreateValue", sourceImagePath.Buffer, sourceProcessId, callbackInfo->ProcStartKey, NULL, NULL);
+
+ }
+ ZwClose(hToken);
+ }
+ //
+ // End of querying for impersonation
+ //
+
+
+Exit:
+ if (sourceImagePath.Buffer != NULL)
+ {
+ ExFreePoolWithTag(sourceImagePath.Buffer, REGISTRY_TAG);
+ }
+ if (fullUserName.Buffer != NULL)
+ {
+ ExFreePoolWithTag(fullUserName.Buffer, REGISTRY_TAG);
+ }
+ if (callbackInfo->KeyPath.Buffer != NULL) {
+ ExFreePoolWithTag(callbackInfo->KeyPath.Buffer, REGISTRY_TAG);
+ }
+ if (callbackInfo != NULL)
+ {
+ ExFreePoolWithTag(callbackInfo, SYSTEM_THREAD_TAG);
+ }
+ return;
+}
+
+VOID
+SaveKey(
+ _In_ PVOID context,
+ _In_ PREG_SAVE_KEY_INFORMATION info
+) {
+ HANDLE Requestorpid = PsGetCurrentProcessId();
+ ULONGLONG sourceProcStartKey = PsGetProcessStartKey(PsGetCurrentProcess());
+ UNICODE_STRING RequestorImagePath{};
+ UNICODE_STRING FullUserName{};
+ ULONG LogonId;
+ ULONGLONG sourceProcessId = HandleToULong(Requestorpid);
+ ULONGLONG sourceThreadId = HandleToULong(PsGetCurrentThreadId());
+ FILETIME fileTime;
+ PCWSTR keyPath = NULL;
+ KeQuerySystemTime(&fileTime);
+ NTSTATUS status;
+ PAGED_CODE();
+ UNREFERENCED_PARAMETER(context);
+
+
+ if (info->Object != NULL && info->FileHandle != NULL) {
+ status = GetRegistryKeyPath(info->Object, REGISTRY_TAG, &keyPath);
+ if (keyPath == NULL) {
+ goto Exit;
+ }
+
+ RequestorImagePath.Length = 0;
+ RequestorImagePath.MaximumLength = MAX_ALLOC;
+ RequestorImagePath.Buffer = (PWSTR)ExAllocatePool2(POOL_FLAG_PAGED, MAX_ALLOC, REGISTRY_TAG);
+ status = GetProcessImageName(Requestorpid, &RequestorImagePath);
+ if (RequestorImagePath.Length == 0 || RequestorImagePath.Buffer == NULL)
+ {
+ //
+ // fatal
+ //
+ if (keyPath != NULL) {
+ ExFreePoolWithTag((PVOID)keyPath, REGISTRY_TAG);
+ }
+ return;
+ }
+ //
+ // get the username and logon id of the process that is deleting the key
+ //
+ FullUserName.Length = 0;
+ FullUserName.MaximumLength = MAX_ALLOC;
+ FullUserName.Buffer = (PWSTR)ExAllocatePool2(POOL_FLAG_PAGED, MAX_ALLOC, REGISTRY_TAG);
+ LogonId = 0;
+ status = GetProcessUserName(&FullUserName, Requestorpid, &LogonId);
+ if (FullUserName.Length == 0 || FullUserName.Buffer == NULL)
+ {
+ //
+ // fatal
+ //
+ if (keyPath != NULL) {
+ ExFreePoolWithTag((PVOID)keyPath, REGISTRY_TAG);
+ }
+ if (RequestorImagePath.Buffer != NULL) {
+ ExFreePoolWithTag(RequestorImagePath.Buffer, REGISTRY_TAG);
+ }
+ return;
+ }
+
+ EventWriteRegistrySaveKey(NULL, &fileTime, RequestorImagePath.Buffer, sourceProcessId, sourceThreadId, sourceProcStartKey, keyPath, FullUserName.Buffer, LogonId);
+
+ }
+
+Exit:
+ if (RequestorImagePath.Buffer != NULL)
+ {
+ ExFreePoolWithTag(RequestorImagePath.Buffer, REGISTRY_TAG);
+ }
+ if (FullUserName.Buffer != NULL)
+ {
+ ExFreePoolWithTag(FullUserName.Buffer, REGISTRY_TAG);
+ }
+ if (keyPath != NULL) {
+ ExFreePoolWithTag((PVOID)keyPath, REGISTRY_TAG);
+ }
+ return;
+}
\ No newline at end of file
diff --git a/JonMon/registry.h b/JonMon/registry.h
new file mode 100644
index 0000000..dbd158c
--- /dev/null
+++ b/JonMon/registry.h
@@ -0,0 +1,76 @@
+#ifndef _REGISTRY_
+#define _REGISTRY_
+#include
+
+//
+// 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
+);
+
+NTSTATUS
+GetRegistryEventInfo(
+ _In_ HANDLE pid,
+ _In_ PUNICODE_STRING pRequestorImagePath,
+ _In_ PUNICODE_STRING pFullUserName,
+ _In_ PULONG pLogonId
+);
+
+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_
\ No newline at end of file
diff --git a/JonMon/shared.h b/JonMon/shared.h
new file mode 100644
index 0000000..309de65
--- /dev/null
+++ b/JonMon/shared.h
@@ -0,0 +1,71 @@
+#ifndef _SHARED_
+#define _SHARED_
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "../JonMonProvider/jonmon.h"
+#define INVALID_HANDLE_VALUE ((HANDLE)(LONG_PTR)-1)
+
+//
+// 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_
\ No newline at end of file
diff --git a/JonMon/thread.cpp b/JonMon/thread.cpp
new file mode 100644
index 0000000..55443b0
--- /dev/null
+++ b/JonMon/thread.cpp
@@ -0,0 +1,198 @@
+#include "thread.h"
+#include "token.h"
+
+PAGED_FILE();
+
+NTSTATUS GetThreadHandle(CLIENT_ID ThreadId, PHANDLE hToken) {
+ HANDLE handleToken = NULL;
+ HANDLE hThread = NULL;
+ NTSTATUS status;
+ OBJECT_ATTRIBUTES attr = { 0 };
+
+ PAGED_CODE();
+ status = ZwOpenThread(&hThread, 0x0040, &attr, &ThreadId);
+ status = ZwOpenThreadTokenEx(hThread, TOKEN_ALL_ACCESS, TRUE, OBJ_KERNEL_HANDLE, &handleToken);
+ if (!NT_SUCCESS(status)) {
+ goto Exit;
+ }
+Exit:
+ *hToken = handleToken;
+ if(hThread != NULL)
+ {
+ ZwClose(hThread);
+ }
+ return status;
+}
+
+// Define the process object and thread object structures
+VOID GetThreadToken(HANDLE hThread) {
+ HANDLE hToken = NULL;
+ NTSTATUS status;
+ PTOKEN_STATISTICS pTokenInfo = NULL;
+ ULONG returnLength;
+
+ PAGED_CODE();
+
+ //DbgPrint("Getting Thread Token\n");
+ status = ZwOpenProcessTokenEx(hThread, TOKEN_QUERY, OBJ_KERNEL_HANDLE, &hToken);
+ if (!NT_SUCCESS(status)) {
+ goto Exit;
+ }
+
+ status = ZwQueryInformationToken(hToken, TokenStatistics, NULL, 0, &returnLength);
+ pTokenInfo = (PTOKEN_STATISTICS)ExAllocatePool2(POOL_FLAG_PAGED, returnLength, THREAD_TAG);
+
+ if (pTokenInfo == NULL)
+ {
+ DbgPrint("ExAllocatePoolWithTag Failed: %08x\n", status);
+ goto Exit;
+ }
+ status = ZwQueryInformationToken(hToken, TokenStatistics, pTokenInfo, returnLength, &returnLength);
+ if (!NT_SUCCESS(status))
+ {
+ DbgPrint("ZwQueryInformationToken Failed: %08x\n", status);
+ goto Exit;
+ }
+ DbgPrint("Token Type: %d\n", pTokenInfo->TokenType);
+
+
+Exit:
+ if (pTokenInfo != NULL) {
+ ExFreePoolWithTag(pTokenInfo, THREAD_TAG);
+ }
+ if (hToken != NULL) {
+ ZwClose(hToken);
+ }
+
+ return;
+
+}
+
+//Crashing for some reason here - debug.
+NTSTATUS GetThreadImpersonationLevel(PETHREAD thread, PSECURITY_IMPERSONATION_LEVEL ImpersonationLevel, PUNICODE_STRING ImpersonationName) {
+ PAGED_CODE();
+ PACCESS_TOKEN token = NULL;
+ BOOLEAN copyOnOpen;
+ BOOLEAN effectiveOnly;
+ SECURITY_IMPERSONATION_LEVEL impersonationLevel;
+ NTSTATUS status = STATUS_ABANDONED;
+ token = PsReferenceImpersonationToken(thread, ©OnOpen, &effectiveOnly, &impersonationLevel);
+ if (token == NULL) {
+ return STATUS_NO_TOKEN;
+ }
+ else {
+ *ImpersonationLevel = impersonationLevel;
+ UNICODE_STRING ImpersonationString{};
+ switch (impersonationLevel) {
+ case SecurityImpersonation:
+ {
+ RtlInitUnicodeString(&ImpersonationString, L"SecurityImpersonation");
+ break;
+ }
+ case SecurityDelegation:
+ {
+ RtlInitUnicodeString(&ImpersonationString, L"SecurityDelegation");
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ if (ImpersonationString.Buffer != NULL) {
+ RtlCopyUnicodeString(ImpersonationName, &ImpersonationString);
+ status = STATUS_SUCCESS;
+ }
+
+ PsDereferenceImpersonationToken(token);
+ return status;
+ }
+}
+
+//
+// JonMonToDo: Update unicode_strings to properly clear. Also need to re-write because I am doing SourceThreadId and passing in CLIENT_ID.
+//
+
+NTSTATUS ThreadImpersonationEvent(HANDLE hToken, PETHREAD eThread, PCWSTR OperationType, WCHAR* RequestorImagePath, ULONGLONG USourceProcessId, ULONGLONG sourceProcStartKey, ULONGLONG UTargetProcessId, ULONGLONG targetProcStartKey) {
+ UNREFERENCED_PARAMETER(OperationType);
+ UNREFERENCED_PARAMETER(UTargetProcessId);
+ UNREFERENCED_PARAMETER(targetProcStartKey);
+ UNICODE_STRING SourceFullUserName{}, ProcessIntegrityLevel{}, ThreadIntegrityLevel{}, ImpersonatedUser{}, ImpersonationString{};
+ SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
+ FILETIME fileTime;
+ ULONGLONG SourceThreadId = HandleToULong(PsGetThreadId(eThread));
+ CLIENT_ID sourceClientId;
+ sourceClientId.UniqueProcess = (HANDLE)USourceProcessId;
+ sourceClientId.UniqueThread = (HANDLE)SourceThreadId;
+ HANDLE hThreadToken = NULL;
+ PAGED_CODE();
+
+ /*
+ * Update function to only write event if the target and source user are different or the integrity levels are different
+ */
+ SourceFullUserName.Length = 0;
+ SourceFullUserName.MaximumLength = MAX_ALLOC;
+ SourceFullUserName.Buffer = (PWSTR)ExAllocatePool2(POOL_FLAG_PAGED, MAX_ALLOC, THREAD_TAG);
+ NTSTATUS status = GetTokenUserName(hToken, &SourceFullUserName);
+ if (!NT_SUCCESS(status)) {
+ DbgPrint("GetTokenUserName Failed: %08x\n", status);
+ goto Exit;
+ }
+
+ status = GetTokenIntegrityLevel(hToken, &ProcessIntegrityLevel);
+ if (!NT_SUCCESS(status)) {
+ DbgPrint("GetTokenIntegrityLevel Failed: %08x\n", status);
+ goto Exit;
+ }
+
+ KeQuerySystemTime(&fileTime);
+ if (eThread != NULL) {
+ status = GetThreadHandle(sourceClientId, &hThreadToken);
+ if (!NT_SUCCESS(status) || hThreadToken == NULL) {
+ goto Exit;
+ }
+
+ ImpersonatedUser.Length = 0;
+ ImpersonatedUser.MaximumLength = MAX_ALLOC;
+ ImpersonatedUser.Buffer = (PWSTR)ExAllocatePool2(POOL_FLAG_PAGED, MAX_ALLOC, THREAD_TAG);
+ status = GetTokenUserName(hThreadToken, &ImpersonatedUser);
+ if (!NT_SUCCESS(status)) {
+ DbgPrint("GetTokenUserName Failed: %08x\n", status);
+ ImpersonatedUser.Buffer = NULL;
+ }
+
+ status = GetTokenIntegrityLevel(hThreadToken, &ThreadIntegrityLevel);
+ if (!NT_SUCCESS(status)) {
+ DbgPrint("GetTokenIntegrityLevel Failed: %08x\n", status);
+ ImpersonatedUser.Buffer = NULL;
+ }
+ ImpersonationString.Length = 0;
+ ImpersonationString.MaximumLength = MAX_ALLOC;
+ ImpersonationString.Buffer = (PWSTR)ExAllocatePool2(POOL_FLAG_PAGED, MAX_ALLOC, THREAD_TAG);
+ status = GetThreadImpersonationLevel(eThread, &ImpersonationLevel, &ImpersonationString);
+ if (!NT_SUCCESS(status)) {
+ goto Exit;
+ }
+ EventWriteImpersonationAction(NULL, &fileTime, RequestorImagePath, USourceProcessId, sourceProcStartKey, ProcessIntegrityLevel.Buffer, SourceFullUserName.Buffer, SourceThreadId, ImpersonationLevel, ImpersonationString.Buffer, ImpersonatedUser.Buffer, ThreadIntegrityLevel.Buffer, OperationType);
+ }
+
+
+Exit:
+ if (SourceFullUserName.Buffer != NULL)
+ {
+ ExFreePoolWithTag(SourceFullUserName.Buffer, THREAD_TAG);
+ }
+ if (ImpersonationString.Buffer != NULL)
+ {
+ ExFreePoolWithTag(ImpersonationString.Buffer, THREAD_TAG);
+ }
+ if (ImpersonatedUser.Buffer != NULL)
+ {
+ ExFreePoolWithTag(ImpersonatedUser.Buffer, THREAD_TAG);
+ }
+ if (hThreadToken != NULL)
+ {
+ ZwClose(hThreadToken);
+ }
+ return status;
+}
diff --git a/JonMon/thread.h b/JonMon/thread.h
new file mode 100644
index 0000000..60c36d6
--- /dev/null
+++ b/JonMon/thread.h
@@ -0,0 +1,24 @@
+#ifndef _THREAD_
+#define _THREAD_
+#include "shared.h"
+
+//
+// Grabbed from: https://github.com/zodiacon/SystemExplorer/blob/f5d51f63581807dbd2a8957bc4bc9dae4aa001cc/KObjExp/KObjExp.cpp#L15
+//
+extern "C" NTSTATUS ZwOpenThread(
+ _Out_ PHANDLE ThreadHandle,
+ _In_ ACCESS_MASK DesiredAccess,
+ _In_ POBJECT_ATTRIBUTES ObjectAttributes,
+ _In_opt_ PCLIENT_ID ClientId);
+
+
+NTSTATUS GetThreadHandle(CLIENT_ID ThreadId, PHANDLE hToken);
+
+// Define the process object and thread object structures
+VOID GetThreadToken(HANDLE hThread);
+
+NTSTATUS GetThreadImpersonationLevel(PETHREAD thread, PSECURITY_IMPERSONATION_LEVEL ImpersonationLevel, PUNICODE_STRING ImpersonationName);
+
+NTSTATUS ThreadImpersonationEvent(HANDLE hToken, PETHREAD eThread, PCWSTR OperationType, WCHAR* RequestorImagePath, ULONGLONG USourceProcessId, ULONGLONG sourceProcStartKey, ULONGLONG UTargetProcessId, ULONGLONG targetProcStartkey);
+
+#endif // !_THREAD_
\ No newline at end of file
diff --git a/JonMon/token.cpp b/JonMon/token.cpp
new file mode 100644
index 0000000..0fa65f9
--- /dev/null
+++ b/JonMon/token.cpp
@@ -0,0 +1,271 @@
+#include "token.h"
+
+PAGED_FILE();
+
+NTSTATUS GetTokenUserName(HANDLE hToken, PUNICODE_STRING pFullName) {
+ ULONG returnLength;
+ UNICODE_STRING SidString;
+ WCHAR SidStringBuffer[64];
+ PTOKEN_USER pTokenInfo = NULL;
+ ULONG NameLength;
+ ULONG DomainLength;
+ UNICODE_STRING DomainName = { 0 };
+ DomainName.Length = 0;
+ DomainName.MaximumLength = MAX_ALLOC;
+ UNICODE_STRING UserName = { 0 };
+ UserName.Length = 0;
+ UserName.MaximumLength = MAX_ALLOC;
+ NTSTATUS status;
+ PVOID domainBuffer{};
+ PVOID userBuffer{};
+ SID_NAME_USE SidNameUse;
+ PSID pSid = NULL;
+
+ domainBuffer = ExAllocatePool2(POOL_FLAG_PAGED, MAX_ALLOC, TOKEN_TAG);
+ if (domainBuffer == NULL)
+ {
+ status = STATUS_INSUFFICIENT_RESOURCES;
+ goto Exit;
+ }
+ DomainName.Buffer = (PWSTR)domainBuffer;
+
+ userBuffer = ExAllocatePool2(POOL_FLAG_PAGED, MAX_ALLOC, TOKEN_TAG);
+ if (userBuffer == NULL)
+ {
+ status = STATUS_INSUFFICIENT_RESOURCES;
+ goto Exit;
+ }
+ UserName.Buffer = (PWSTR)userBuffer;
+
+ if (hToken == NULL)
+ {
+ status = STATUS_INVALID_PARAMETER;
+ goto Exit;
+ }
+ status = ZwQueryInformationToken(hToken, TokenUser, NULL, 0, &returnLength);
+
+ pTokenInfo = (PTOKEN_USER)ExAllocatePool2(POOL_FLAG_PAGED, returnLength, TOKEN_TAG);
+ if (pTokenInfo == NULL)
+ {
+ goto Exit;
+ }
+ status = ZwQueryInformationToken(hToken, TokenUser, pTokenInfo, returnLength, &returnLength);
+ if (!NT_SUCCESS(status))
+ {
+ goto Exit;
+ }
+
+ pSid = pTokenInfo->User.Sid;
+
+ RtlZeroMemory(SidStringBuffer, sizeof(SidStringBuffer));
+ SidString.Buffer = (PWCHAR)SidStringBuffer;
+ SidString.MaximumLength = sizeof(SidStringBuffer);
+
+ status = RtlConvertSidToUnicodeString(&SidString, pSid, FALSE);
+ if (!NT_SUCCESS(status))
+ {
+ goto Exit;
+ }
+
+ status = SecLookupAccountSid(pSid, &NameLength, &UserName, &DomainLength, &DomainName, &SidNameUse);
+ if (!NT_SUCCESS(status))
+ {
+ goto Exit;
+ }
+ RtlCopyUnicodeString(pFullName, &DomainName);
+ RtlAppendUnicodeToString(pFullName, L"\\");
+ RtlAppendUnicodeStringToString(pFullName, &UserName);
+ //Adding null terminator
+ pFullName->Buffer[pFullName->Length / sizeof(UNICODE_NULL)] = UNICODE_NULL;
+
+Exit:
+ if (pTokenInfo != NULL) {
+ ExFreePoolWithTag(pTokenInfo, TOKEN_TAG);
+ }
+ if (domainBuffer != NULL) {
+ ExFreePoolWithTag(domainBuffer, TOKEN_TAG);
+ }
+ if (userBuffer != NULL) {
+ ExFreePoolWithTag(userBuffer, TOKEN_TAG);
+ }
+
+
+ return status;
+}
+
+NTSTATUS GetUserTokenStatistics(HANDLE hToken, DWORD* AuthenticationId) {
+ PAGED_CODE();
+ PTOKEN_STATISTICS pTokenInfo = NULL;
+ ULONG returnLength;
+
+ NTSTATUS status = ZwQueryInformationToken(hToken, TokenStatistics, NULL, 0, &returnLength);
+
+ pTokenInfo = (PTOKEN_STATISTICS)ExAllocatePool2(POOL_FLAG_PAGED, returnLength, TOKEN_TAG);
+ if (pTokenInfo == NULL)
+ {
+ goto Exit;
+ }
+ status = ZwQueryInformationToken(hToken, TokenStatistics, pTokenInfo, returnLength, &returnLength);
+ if (!NT_SUCCESS(status))
+ {
+ DbgPrint("ZwQueryInformationToken Failed: %08x\n", status);
+ ExFreePoolWithTag(pTokenInfo, TOKEN_TAG);
+ return status;
+ }
+ LUID LogonId = pTokenInfo->AuthenticationId;
+ *AuthenticationId = LogonId.LowPart;
+
+
+Exit:
+ if (pTokenInfo != NULL) {
+ ExFreePoolWithTag(pTokenInfo, TOKEN_TAG);
+ }
+ return status;
+}
+
+NTSTATUS GetProcessUserName(PUNICODE_STRING pFullName, HANDLE ProcessId, DWORD* AuthenticationId) {
+ PAGED_CODE();
+ HANDLE hToken = NULL;
+ HANDLE hProcess = NULL;
+ PEPROCESS eProcess = NULL;
+
+ if (pFullName == NULL)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ NTSTATUS status = PsLookupProcessByProcessId(ProcessId, &eProcess);
+ if (!NT_SUCCESS(status))
+ {
+ goto Exit;
+ }
+ status = ObOpenObjectByPointer(eProcess, OBJ_KERNEL_HANDLE, NULL, 0x1000, 0, KernelMode, &hProcess);
+ if (!NT_SUCCESS(status))
+ {
+ goto Exit;
+ }
+ status = ZwOpenProcessTokenEx(hProcess, TOKEN_QUERY, OBJ_KERNEL_HANDLE, &hToken);
+ if (!NT_SUCCESS(status)) {
+ goto Exit;
+ }
+ status = GetTokenUserName(hToken, pFullName);
+ if (!NT_SUCCESS(status))
+ {
+ goto Exit;
+ }
+ status = GetUserTokenStatistics(hToken, AuthenticationId);
+ if (!NT_SUCCESS(status))
+ {
+ goto Exit;
+ }
+
+Exit:
+ if (eProcess != NULL) {
+ ObDereferenceObject(eProcess);
+ }
+ if (hToken != NULL) {
+ ZwClose(hToken);
+ }
+ if (hProcess != NULL) {
+ ObCloseHandle(hProcess, KernelMode);
+ }
+ return status;
+}
+
+DWORD GetSessionIdFromToken(HANDLE hToken) {
+ NTSTATUS status;
+ DWORD sessionId;
+ DWORD returnLength = 0;
+
+ status = ZwQueryInformationToken(hToken, TokenSessionId, &sessionId, sizeof(sessionId), &returnLength);
+ if (NT_SUCCESS(status)) {
+ return sessionId;
+ }
+ return 0;
+}
+
+NTSTATUS GetImpersonationLevelFromToken(HANDLE hToken) {
+ PTOKEN_STATISTICS pTokenInfo = NULL;
+ ULONG returnLength;
+
+ NTSTATUS status = ZwQueryInformationToken(hToken, TokenStatistics, NULL, 0, &returnLength);
+
+ pTokenInfo = (PTOKEN_STATISTICS)ExAllocatePool2(POOL_FLAG_PAGED, returnLength, TOKEN_TAG);
+
+ if (pTokenInfo == NULL)
+ {
+ DbgPrint("ExAllocatePoolWithTag Failed: %08x\n", status);
+ return status;
+ }
+ status = ZwQueryInformationToken(hToken, TokenStatistics, pTokenInfo, returnLength, &returnLength);
+ if (!NT_SUCCESS(status))
+ {
+ DbgPrint("ZwQueryInformationToken Failed: %08x\n", status);
+ ExFreePoolWithTag(pTokenInfo, TOKEN_TAG);
+ return status;
+ }
+ else
+ {
+ TOKEN_TYPE TokenType = pTokenInfo->TokenType;
+ if (TokenType == TokenImpersonation) {
+ DbgPrint("Token Type: %d\n", TokenType);
+ }
+ else {
+ DbgPrint("Token Type: %d\n", TokenType);
+ }
+ ExFreePoolWithTag(pTokenInfo, TOKEN_TAG);
+ status = STATUS_SUCCESS;
+ return status;
+ }
+}
+
+NTSTATUS GetTokenIntegrityLevel(HANDLE hToken, PUNICODE_STRING IntegrityLevel) {
+ NTSTATUS status;
+ PTOKEN_MANDATORY_LABEL pTIL = NULL;
+ ULONG returnLength;
+
+ status = ZwQueryInformationToken(hToken, TokenIntegrityLevel, NULL, 0, &returnLength);
+
+ pTIL = (PTOKEN_MANDATORY_LABEL)ExAllocatePool2(POOL_FLAG_PAGED, returnLength, TOKEN_TAG);
+
+ if (pTIL == NULL)
+ {
+ goto Exit;
+ }
+ status = ZwQueryInformationToken(hToken, TokenIntegrityLevel, pTIL, returnLength, &returnLength);
+ if (!NT_SUCCESS(status))
+ {
+ DbgPrint("ZwQueryInformationToken Failed: %08x\n", status);
+ goto Exit;
+ }
+
+ ULONG IntegrityLevelValue = *RtlSubAuthoritySid(pTIL->Label.Sid, (DWORD)(UCHAR)(*RtlSubAuthorityCountSid(pTIL->Label.Sid) - 1));
+ switch (IntegrityLevelValue) {
+ case SECURITY_MANDATORY_UNTRUSTED_RID:
+ RtlInitUnicodeString(IntegrityLevel, L"Untrusted");
+ break;
+ case SECURITY_MANDATORY_LOW_RID:
+ RtlInitUnicodeString(IntegrityLevel, L"Low");
+ break;
+ case SECURITY_MANDATORY_MEDIUM_RID:
+ RtlInitUnicodeString(IntegrityLevel, L"Medium");
+ break;
+ case SECURITY_MANDATORY_HIGH_RID:
+ RtlInitUnicodeString(IntegrityLevel, L"High");
+ break;
+ case SECURITY_MANDATORY_SYSTEM_RID:
+ RtlInitUnicodeString(IntegrityLevel, L"System");
+ break;
+ default:
+ RtlInitUnicodeString(IntegrityLevel, L"Unknown");
+ break;
+ }
+ status = STATUS_SUCCESS;
+
+Exit:
+ if(pTIL != NULL)
+ {
+ ExFreePoolWithTag(pTIL, TOKEN_TAG);
+ }
+ return status;
+}
\ No newline at end of file
diff --git a/JonMon/token.h b/JonMon/token.h
new file mode 100644
index 0000000..93b75af
--- /dev/null
+++ b/JonMon/token.h
@@ -0,0 +1,17 @@
+#ifndef _TOKEN_
+#define _TOKEN_
+#include "shared.h"
+
+NTSTATUS GetTokenUserName(HANDLE hToken, PUNICODE_STRING pFullName);
+
+NTSTATUS GetUserTokenStatistics(HANDLE hToken, DWORD* AuthenticationId);
+
+NTSTATUS GetProcessUserName(PUNICODE_STRING pFullName, HANDLE ProcessId, DWORD* AuthenticationId);
+
+DWORD GetSessionIdFromToken(HANDLE hToken);
+
+NTSTATUS GetImpersonationLevelFromToken(HANDLE hToken);
+
+NTSTATUS GetTokenIntegrityLevel(HANDLE hToken, PUNICODE_STRING IntegrityLevel);
+
+#endif // !_TOKEN_
\ No newline at end of file
diff --git a/JonMonProvider/MSG00001.bin b/JonMonProvider/MSG00001.bin
new file mode 100644
index 0000000..e2a949f
Binary files /dev/null and b/JonMonProvider/MSG00001.bin differ
diff --git a/JonMonProvider/jonmon.dll b/JonMonProvider/jonmon.dll
new file mode 100644
index 0000000..da31667
Binary files /dev/null and b/JonMonProvider/jonmon.dll differ
diff --git a/JonMonProvider/jonmon.h b/JonMonProvider/jonmon.h
new file mode 100644
index 0000000..d1970b1
--- /dev/null
+++ b/JonMonProvider/jonmon.h
@@ -0,0 +1,3050 @@
+//**********************************************************************`
+//* This is an include file generated by Message Compiler. *`
+//* *`
+//* Copyright (c) Microsoft Corporation. All Rights Reserved. *`
+//**********************************************************************`
+#pragma once
+
+//*****************************************************************************
+//
+// Notes on the ETW event code generated by MC:
+//
+// - Structures and arrays of structures are treated as an opaque binary blob.
+// The caller is responsible for packing the data for the structure into a
+// single region of memory, with no padding between values. The macro will
+// have an extra parameter for the length of the blob.
+// - Arrays of nul-terminated strings must be packed by the caller into a
+// single binary blob containing the correct number of strings, with a nul
+// after each string. The size of the blob is specified in characters, and
+// includes the final nul.
+// - Arrays of SID are treated as a single binary blob. The caller is
+// responsible for packing the SID values into a single region of memory with
+// no padding.
+// - The length attribute on the data element in the manifest is significant
+// for values with intype win:UnicodeString, win:AnsiString, or win:Binary.
+// The length attribute must be specified for win:Binary, and is optional for
+// win:UnicodeString and win:AnsiString (if no length is given, the strings
+// are assumed to be nul-terminated). For win:UnicodeString, the length is
+// measured in characters, not bytes.
+// - For an array of win:UnicodeString, win:AnsiString, or win:Binary, the
+// length attribute applies to every value in the array, so every value in
+// the array must have the same length. The values in the array are provided
+// to the macro via a single pointer -- the caller is responsible for packing
+// all of the values into a single region of memory with no padding between
+// values.
+// - Values of type win:CountedUnicodeString, win:CountedAnsiString, and
+// win:CountedBinary can be generated and collected on Vista or later.
+// However, they may not decode properly without the Windows 10 2018 Fall
+// Update.
+// - Arrays of type win:CountedUnicodeString, win:CountedAnsiString, and
+// win:CountedBinary must be packed by the caller into a single region of
+// memory. The format for each item is a UINT16 byte-count followed by that
+// many bytes of data. When providing the array to the generated macro, you
+// must provide the total size of the packed array data, including the UINT16
+// sizes for each item. In the case of win:CountedUnicodeString, the data
+// size is specified in WCHAR (16-bit) units. In the case of
+// win:CountedAnsiString and win:CountedBinary, the data size is specified in
+// bytes.
+//
+//*****************************************************************************
+
+#include
+#include
+#include
+#include "../JonMon/jtime.h"
+#ifndef ETW_INLINE
+ #ifdef _ETW_KM_
+ // In kernel mode, save stack space by never inlining templates.
+ #define ETW_INLINE DECLSPEC_NOINLINE __inline
+ #else
+ // In user mode, save code size by inlining templates as appropriate.
+ #define ETW_INLINE __inline
+ #endif
+#endif // ETW_INLINE
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+//
+// MCGEN_DISABLE_PROVIDER_CODE_GENERATION macro:
+// Define this macro to have the compiler skip the generated functions in this
+// header.
+//
+#ifndef MCGEN_DISABLE_PROVIDER_CODE_GENERATION
+
+//
+// MCGEN_USE_KERNEL_MODE_APIS macro:
+// Controls whether the generated code uses kernel-mode or user-mode APIs.
+// - Set to 0 to use Windows user-mode APIs such as EventRegister.
+// - Set to 1 to use Windows kernel-mode APIs such as EtwRegister.
+// Default is based on whether the _ETW_KM_ macro is defined (i.e. by wdm.h).
+// Note that the APIs can also be overridden directly, e.g. by setting the
+// MCGEN_EVENTWRITETRANSFER or MCGEN_EVENTREGISTER macros.
+//
+#ifndef MCGEN_USE_KERNEL_MODE_APIS
+ #ifdef _ETW_KM_
+ #define MCGEN_USE_KERNEL_MODE_APIS 1
+ #else
+ #define MCGEN_USE_KERNEL_MODE_APIS 0
+ #endif
+#endif // MCGEN_USE_KERNEL_MODE_APIS
+
+//
+// MCGEN_HAVE_EVENTSETINFORMATION macro:
+// Controls how McGenEventSetInformation uses the EventSetInformation API.
+// - Set to 0 to disable the use of EventSetInformation
+// (McGenEventSetInformation will always return an error).
+// - Set to 1 to directly invoke MCGEN_EVENTSETINFORMATION.
+// - Set to 2 to to locate EventSetInformation at runtime via GetProcAddress
+// (user-mode) or MmGetSystemRoutineAddress (kernel-mode).
+// Default is determined as follows:
+// - If MCGEN_EVENTSETINFORMATION has been customized, set to 1
+// (i.e. use MCGEN_EVENTSETINFORMATION).
+// - Else if the target OS version has EventSetInformation, set to 1
+// (i.e. use MCGEN_EVENTSETINFORMATION).
+// - Else set to 2 (i.e. try to dynamically locate EventSetInformation).
+// Note that an McGenEventSetInformation function will only be generated if one
+// or more provider in a manifest has provider traits.
+//
+#ifndef MCGEN_HAVE_EVENTSETINFORMATION
+ #ifdef MCGEN_EVENTSETINFORMATION // if MCGEN_EVENTSETINFORMATION has been customized,
+ #define MCGEN_HAVE_EVENTSETINFORMATION 1 // directly invoke MCGEN_EVENTSETINFORMATION(...).
+ #elif MCGEN_USE_KERNEL_MODE_APIS // else if using kernel-mode APIs,
+ #if NTDDI_VERSION >= 0x06040000 // if target OS is Windows 10 or later,
+ #define MCGEN_HAVE_EVENTSETINFORMATION 1 // directly invoke MCGEN_EVENTSETINFORMATION(...).
+ #else // else
+ #define MCGEN_HAVE_EVENTSETINFORMATION 2 // find "EtwSetInformation" via MmGetSystemRoutineAddress.
+ #endif // else (using user-mode APIs)
+ #else // if target OS and SDK is Windows 8 or later,
+ #if WINVER >= 0x0602 && defined(EVENT_FILTER_TYPE_SCHEMATIZED)
+ #define MCGEN_HAVE_EVENTSETINFORMATION 1 // directly invoke MCGEN_EVENTSETINFORMATION(...).
+ #else // else
+ #define MCGEN_HAVE_EVENTSETINFORMATION 2 // find "EventSetInformation" via GetModuleHandleExW/GetProcAddress.
+ #endif
+ #endif
+#endif // MCGEN_HAVE_EVENTSETINFORMATION
+
+//
+// MCGEN Override Macros
+//
+// The following override macros may be defined before including this header
+// to control the APIs used by this header:
+//
+// - MCGEN_EVENTREGISTER
+// - MCGEN_EVENTUNREGISTER
+// - MCGEN_EVENTSETINFORMATION
+// - MCGEN_EVENTWRITETRANSFER
+//
+// If the the macro is undefined, the MC implementation will default to the
+// corresponding ETW APIs. For example, if the MCGEN_EVENTREGISTER macro is
+// undefined, the EventRegister[MyProviderName] macro will use EventRegister
+// in user mode and will use EtwRegister in kernel mode.
+//
+// To prevent issues from conflicting definitions of these macros, the value
+// of the override macro will be used as a suffix in certain internal function
+// names. Because of this, the override macros must follow certain rules:
+//
+// - The macro must be defined before any MC-generated header is included and
+// must not be undefined or redefined after any MC-generated header is
+// included. Different translation units (i.e. different .c or .cpp files)
+// may set the macros to different values, but within a translation unit
+// (within a single .c or .cpp file), the macro must be set once and not
+// changed.
+// - The override must be an object-like macro, not a function-like macro
+// (i.e. the override macro must not have a parameter list).
+// - The override macro's value must be a simple identifier, i.e. must be
+// something that starts with a letter or '_' and contains only letters,
+// numbers, and '_' characters.
+// - If the override macro's value is the name of a second object-like macro,
+// the second object-like macro must follow the same rules. (The override
+// macro's value can also be the name of a function-like macro, in which
+// case the function-like macro does not need to follow the same rules.)
+//
+// For example, the following will cause compile errors:
+//
+// #define MCGEN_EVENTWRITETRANSFER MyNamespace::MyClass::MyFunction // Value has non-identifier characters (colon).
+// #define MCGEN_EVENTWRITETRANSFER GetEventWriteFunctionPointer(7) // Value has non-identifier characters (parentheses).
+// #define MCGEN_EVENTWRITETRANSFER(h,e,a,r,c,d) EventWrite(h,e,c,d) // Override is defined as a function-like macro.
+// #define MY_OBJECT_LIKE_MACRO MyNamespace::MyClass::MyEventWriteFunction
+// #define MCGEN_EVENTWRITETRANSFER MY_OBJECT_LIKE_MACRO // Evaluates to something with non-identifier characters (colon).
+//
+// The following would be ok:
+//
+// #define MCGEN_EVENTWRITETRANSFER MyEventWriteFunction1 // OK, suffix will be "MyEventWriteFunction1".
+// #define MY_OBJECT_LIKE_MACRO MyEventWriteFunction2
+// #define MCGEN_EVENTWRITETRANSFER MY_OBJECT_LIKE_MACRO // OK, suffix will be "MyEventWriteFunction2".
+// #define MY_FUNCTION_LIKE_MACRO(h,e,a,r,c,d) MyNamespace::MyClass::MyEventWriteFunction3(h,e,c,d)
+// #define MCGEN_EVENTWRITETRANSFER MY_FUNCTION_LIKE_MACRO // OK, suffix will be "MY_FUNCTION_LIKE_MACRO".
+//
+#ifndef MCGEN_EVENTREGISTER
+ #if MCGEN_USE_KERNEL_MODE_APIS
+ #define MCGEN_EVENTREGISTER EtwRegister
+ #else
+ #define MCGEN_EVENTREGISTER EventRegister
+ #endif
+#endif // MCGEN_EVENTREGISTER
+#ifndef MCGEN_EVENTUNREGISTER
+ #if MCGEN_USE_KERNEL_MODE_APIS
+ #define MCGEN_EVENTUNREGISTER EtwUnregister
+ #else
+ #define MCGEN_EVENTUNREGISTER EventUnregister
+ #endif
+#endif // MCGEN_EVENTUNREGISTER
+#ifndef MCGEN_EVENTSETINFORMATION
+ #if MCGEN_USE_KERNEL_MODE_APIS
+ #define MCGEN_EVENTSETINFORMATION EtwSetInformation
+ #else
+ #define MCGEN_EVENTSETINFORMATION EventSetInformation
+ #endif
+#endif // MCGEN_EVENTSETINFORMATION
+#ifndef MCGEN_EVENTWRITETRANSFER
+ #if MCGEN_USE_KERNEL_MODE_APIS
+ #define MCGEN_EVENTWRITETRANSFER EtwWriteTransfer
+ #else
+ #define MCGEN_EVENTWRITETRANSFER EventWriteTransfer
+ #endif
+#endif // MCGEN_EVENTWRITETRANSFER
+
+//
+// MCGEN_EVENT_ENABLED macro:
+// Override to control how the EventWrite[EventName] macros determine whether
+// an event is enabled. The default behavior is for EventWrite[EventName] to
+// use the EventEnabled[EventName] macros.
+//
+#ifndef MCGEN_EVENT_ENABLED
+#define MCGEN_EVENT_ENABLED(EventName) EventEnabled##EventName()
+#endif
+
+//
+// MCGEN_EVENT_ENABLED_FORCONTEXT macro:
+// Override to control how the EventWrite[EventName]_ForContext macros
+// determine whether an event is enabled. The default behavior is for
+// EventWrite[EventName]_ForContext to use the
+// EventEnabled[EventName]_ForContext macros.
+//
+#ifndef MCGEN_EVENT_ENABLED_FORCONTEXT
+#define MCGEN_EVENT_ENABLED_FORCONTEXT(pContext, EventName) EventEnabled##EventName##_ForContext(pContext)
+#endif
+
+//
+// MCGEN_ENABLE_CHECK macro:
+// Determines whether the specified event would be considered as enabled
+// based on the state of the specified context. Slightly faster than calling
+// McGenEventEnabled directly.
+//
+#ifndef MCGEN_ENABLE_CHECK
+#define MCGEN_ENABLE_CHECK(Context, Descriptor) (Context.IsEnabled && McGenEventEnabled(&Context, &Descriptor))
+#endif
+
+#if !defined(MCGEN_TRACE_CONTEXT_DEF)
+#define MCGEN_TRACE_CONTEXT_DEF
+// This structure is for use by MC-generated code and should not be used directly.
+typedef struct _MCGEN_TRACE_CONTEXT
+{
+ TRACEHANDLE RegistrationHandle;
+ TRACEHANDLE Logger; // Used as pointer to provider traits.
+ ULONGLONG MatchAnyKeyword;
+ ULONGLONG MatchAllKeyword;
+ ULONG Flags;
+ ULONG IsEnabled;
+ UCHAR Level;
+ UCHAR Reserve;
+ USHORT EnableBitsCount;
+ PULONG EnableBitMask;
+ const ULONGLONG* EnableKeyWords;
+ const UCHAR* EnableLevel;
+} MCGEN_TRACE_CONTEXT, *PMCGEN_TRACE_CONTEXT;
+#endif // MCGEN_TRACE_CONTEXT_DEF
+
+#if !defined(MCGEN_LEVEL_KEYWORD_ENABLED_DEF)
+#define MCGEN_LEVEL_KEYWORD_ENABLED_DEF
+//
+// Determines whether an event with a given Level and Keyword would be
+// considered as enabled based on the state of the specified context.
+// Note that you may want to use MCGEN_ENABLE_CHECK instead of calling this
+// function directly.
+//
+FORCEINLINE
+BOOLEAN
+McGenLevelKeywordEnabled(
+ _In_ PMCGEN_TRACE_CONTEXT EnableInfo,
+ _In_ UCHAR Level,
+ _In_ ULONGLONG Keyword
+ )
+{
+ //
+ // Check if the event Level is lower than the level at which
+ // the channel is enabled.
+ // If the event Level is 0 or the channel is enabled at level 0,
+ // all levels are enabled.
+ //
+
+ if ((Level <= EnableInfo->Level) || // This also covers the case of Level == 0.
+ (EnableInfo->Level == 0)) {
+
+ //
+ // Check if Keyword is enabled
+ //
+
+ if ((Keyword == (ULONGLONG)0) ||
+ ((Keyword & EnableInfo->MatchAnyKeyword) &&
+ ((Keyword & EnableInfo->MatchAllKeyword) == EnableInfo->MatchAllKeyword))) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+#endif // MCGEN_LEVEL_KEYWORD_ENABLED_DEF
+
+#if !defined(MCGEN_EVENT_ENABLED_DEF)
+#define MCGEN_EVENT_ENABLED_DEF
+//
+// Determines whether the specified event would be considered as enabled based
+// on the state of the specified context. Note that you may want to use
+// MCGEN_ENABLE_CHECK instead of calling this function directly.
+//
+FORCEINLINE
+BOOLEAN
+McGenEventEnabled(
+ _In_ PMCGEN_TRACE_CONTEXT EnableInfo,
+ _In_ PCEVENT_DESCRIPTOR EventDescriptor
+ )
+{
+ return McGenLevelKeywordEnabled(EnableInfo, EventDescriptor->Level, EventDescriptor->Keyword);
+}
+#endif // MCGEN_EVENT_ENABLED_DEF
+
+#if !defined(MCGEN_CONTROL_CALLBACK)
+#define MCGEN_CONTROL_CALLBACK
+
+// This function is for use by MC-generated code and should not be used directly.
+DECLSPEC_NOINLINE __inline
+VOID
+__stdcall
+McGenControlCallbackV2(
+ _In_ LPCGUID SourceId,
+ _In_ ULONG ControlCode,
+ _In_ UCHAR Level,
+ _In_ ULONGLONG MatchAnyKeyword,
+ _In_ ULONGLONG MatchAllKeyword,
+ _In_opt_ PEVENT_FILTER_DESCRIPTOR FilterData,
+ _Inout_opt_ PVOID CallbackContext
+ )
+/*++
+
+Routine Description:
+
+ This is the notification callback for Windows Vista and later.
+
+Arguments:
+
+ SourceId - The GUID that identifies the session that enabled the provider.
+
+ ControlCode - The parameter indicates whether the provider
+ is being enabled or disabled.
+
+ Level - The level at which the event is enabled.
+
+ MatchAnyKeyword - The bitmask of keywords that the provider uses to
+ determine the category of events that it writes.
+
+ MatchAllKeyword - This bitmask additionally restricts the category
+ of events that the provider writes.
+
+ FilterData - The provider-defined data.
+
+ CallbackContext - The context of the callback that is defined when the provider
+ called EtwRegister to register itself.
+
+Remarks:
+
+ ETW calls this function to notify provider of enable/disable
+
+--*/
+{
+ PMCGEN_TRACE_CONTEXT Ctx = (PMCGEN_TRACE_CONTEXT)CallbackContext;
+ ULONG Ix;
+#ifndef MCGEN_PRIVATE_ENABLE_CALLBACK_V2
+ UNREFERENCED_PARAMETER(SourceId);
+ UNREFERENCED_PARAMETER(FilterData);
+#endif
+
+ if (Ctx == NULL) {
+ return;
+ }
+
+ switch (ControlCode) {
+
+ case EVENT_CONTROL_CODE_ENABLE_PROVIDER:
+ Ctx->Level = Level;
+ Ctx->MatchAnyKeyword = MatchAnyKeyword;
+ Ctx->MatchAllKeyword = MatchAllKeyword;
+ Ctx->IsEnabled = EVENT_CONTROL_CODE_ENABLE_PROVIDER;
+
+ for (Ix = 0; Ix < Ctx->EnableBitsCount; Ix += 1) {
+ if (McGenLevelKeywordEnabled(Ctx, Ctx->EnableLevel[Ix], Ctx->EnableKeyWords[Ix]) != FALSE) {
+ Ctx->EnableBitMask[Ix >> 5] |= (1 << (Ix % 32));
+ } else {
+ Ctx->EnableBitMask[Ix >> 5] &= ~(1 << (Ix % 32));
+ }
+ }
+ break;
+
+ case EVENT_CONTROL_CODE_DISABLE_PROVIDER:
+ Ctx->IsEnabled = EVENT_CONTROL_CODE_DISABLE_PROVIDER;
+ Ctx->Level = 0;
+ Ctx->MatchAnyKeyword = 0;
+ Ctx->MatchAllKeyword = 0;
+ if (Ctx->EnableBitsCount > 0) {
+#pragma warning(suppress: 26451) // Arithmetic overflow cannot occur, no matter the value of EnableBitCount
+ RtlZeroMemory(Ctx->EnableBitMask, (((Ctx->EnableBitsCount - 1) / 32) + 1) * sizeof(ULONG));
+ }
+ break;
+
+ default:
+ break;
+ }
+
+#ifdef MCGEN_PRIVATE_ENABLE_CALLBACK_V2
+ //
+ // Call user defined callback
+ //
+ MCGEN_PRIVATE_ENABLE_CALLBACK_V2(
+ SourceId,
+ ControlCode,
+ Level,
+ MatchAnyKeyword,
+ MatchAllKeyword,
+ FilterData,
+ CallbackContext
+ );
+#endif // MCGEN_PRIVATE_ENABLE_CALLBACK_V2
+
+ return;
+}
+
+#endif // MCGEN_CONTROL_CALLBACK
+
+#ifndef _mcgen_PENABLECALLBACK
+ #if MCGEN_USE_KERNEL_MODE_APIS
+ #define _mcgen_PENABLECALLBACK PETWENABLECALLBACK
+ #else
+ #define _mcgen_PENABLECALLBACK PENABLECALLBACK
+ #endif
+#endif // _mcgen_PENABLECALLBACK
+
+#if !defined(_mcgen_PASTE2)
+// This macro is for use by MC-generated code and should not be used directly.
+#define _mcgen_PASTE2(a, b) _mcgen_PASTE2_imp(a, b)
+#define _mcgen_PASTE2_imp(a, b) a##b
+#endif // _mcgen_PASTE2
+
+#if !defined(_mcgen_PASTE3)
+// This macro is for use by MC-generated code and should not be used directly.
+#define _mcgen_PASTE3(a, b, c) _mcgen_PASTE3_imp(a, b, c)
+#define _mcgen_PASTE3_imp(a, b, c) a##b##_##c
+#endif // _mcgen_PASTE3
+
+//
+// Macro validation
+//
+
+// Validate MCGEN_EVENTREGISTER:
+
+// Trigger an error if MCGEN_EVENTREGISTER is not an unqualified (simple) identifier:
+struct _mcgen_PASTE2(MCGEN_EVENTREGISTER_definition_must_be_an_unqualified_identifier_, MCGEN_EVENTREGISTER);
+
+// Trigger an error if MCGEN_EVENTREGISTER is redefined:
+typedef struct _mcgen_PASTE2(MCGEN_EVENTREGISTER_definition_must_be_an_unqualified_identifier_, MCGEN_EVENTREGISTER)
+ MCGEN_EVENTREGISTER_must_not_be_redefined_between_headers;
+
+// Trigger an error if MCGEN_EVENTREGISTER is defined as a function-like macro:
+typedef void MCGEN_EVENTREGISTER_must_not_be_a_functionLike_macro_MCGEN_EVENTREGISTER;
+typedef int _mcgen_PASTE2(MCGEN_EVENTREGISTER_must_not_be_a_functionLike_macro_, MCGEN_EVENTREGISTER);
+
+// Validate MCGEN_EVENTUNREGISTER:
+
+// Trigger an error if MCGEN_EVENTUNREGISTER is not an unqualified (simple) identifier:
+struct _mcgen_PASTE2(MCGEN_EVENTUNREGISTER_definition_must_be_an_unqualified_identifier_, MCGEN_EVENTUNREGISTER);
+
+// Trigger an error if MCGEN_EVENTUNREGISTER is redefined:
+typedef struct _mcgen_PASTE2(MCGEN_EVENTUNREGISTER_definition_must_be_an_unqualified_identifier_, MCGEN_EVENTUNREGISTER)
+ MCGEN_EVENTUNREGISTER_must_not_be_redefined_between_headers;
+
+// Trigger an error if MCGEN_EVENTUNREGISTER is defined as a function-like macro:
+typedef void MCGEN_EVENTUNREGISTER_must_not_be_a_functionLike_macro_MCGEN_EVENTUNREGISTER;
+typedef int _mcgen_PASTE2(MCGEN_EVENTUNREGISTER_must_not_be_a_functionLike_macro_, MCGEN_EVENTUNREGISTER);
+
+// Validate MCGEN_EVENTSETINFORMATION:
+
+// Trigger an error if MCGEN_EVENTSETINFORMATION is not an unqualified (simple) identifier:
+struct _mcgen_PASTE2(MCGEN_EVENTSETINFORMATION_definition_must_be_an_unqualified_identifier_, MCGEN_EVENTSETINFORMATION);
+
+// Trigger an error if MCGEN_EVENTSETINFORMATION is redefined:
+typedef struct _mcgen_PASTE2(MCGEN_EVENTSETINFORMATION_definition_must_be_an_unqualified_identifier_, MCGEN_EVENTSETINFORMATION)
+ MCGEN_EVENTSETINFORMATION_must_not_be_redefined_between_headers;
+
+// Trigger an error if MCGEN_EVENTSETINFORMATION is defined as a function-like macro:
+typedef void MCGEN_EVENTSETINFORMATION_must_not_be_a_functionLike_macro_MCGEN_EVENTSETINFORMATION;
+typedef int _mcgen_PASTE2(MCGEN_EVENTSETINFORMATION_must_not_be_a_functionLike_macro_, MCGEN_EVENTSETINFORMATION);
+
+// Validate MCGEN_EVENTWRITETRANSFER:
+
+// Trigger an error if MCGEN_EVENTWRITETRANSFER is not an unqualified (simple) identifier:
+struct _mcgen_PASTE2(MCGEN_EVENTWRITETRANSFER_definition_must_be_an_unqualified_identifier_, MCGEN_EVENTWRITETRANSFER);
+
+// Trigger an error if MCGEN_EVENTWRITETRANSFER is redefined:
+typedef struct _mcgen_PASTE2(MCGEN_EVENTWRITETRANSFER_definition_must_be_an_unqualified_identifier_, MCGEN_EVENTWRITETRANSFER)
+ MCGEN_EVENTWRITETRANSFER_must_not_be_redefined_between_headers;;
+
+// Trigger an error if MCGEN_EVENTWRITETRANSFER is defined as a function-like macro:
+typedef void MCGEN_EVENTWRITETRANSFER_must_not_be_a_functionLike_macro_MCGEN_EVENTWRITETRANSFER;
+typedef int _mcgen_PASTE2(MCGEN_EVENTWRITETRANSFER_must_not_be_a_functionLike_macro_, MCGEN_EVENTWRITETRANSFER);
+
+#ifndef McGenEventWrite_def
+#define McGenEventWrite_def
+
+// This macro is for use by MC-generated code and should not be used directly.
+#define McGenEventWrite _mcgen_PASTE2(McGenEventWrite_, MCGEN_EVENTWRITETRANSFER)
+
+// This function is for use by MC-generated code and should not be used directly.
+DECLSPEC_NOINLINE __inline
+ULONG __stdcall
+McGenEventWrite(
+ _In_ PMCGEN_TRACE_CONTEXT Context,
+ _In_ PCEVENT_DESCRIPTOR Descriptor,
+ _In_opt_ LPCGUID ActivityId,
+ _In_range_(1, 128) ULONG EventDataCount,
+ _Pre_cap_(EventDataCount) EVENT_DATA_DESCRIPTOR* EventData
+ )
+{
+ const USHORT UNALIGNED* Traits;
+
+ // Some customized MCGEN_EVENTWRITETRANSFER macros might ignore ActivityId.
+ UNREFERENCED_PARAMETER(ActivityId);
+
+ Traits = (const USHORT UNALIGNED*)(UINT_PTR)Context->Logger;
+
+ if (Traits == NULL) {
+ EventData[0].Ptr = 0;
+ EventData[0].Size = 0;
+ EventData[0].Reserved = 0;
+ } else {
+ EventData[0].Ptr = (ULONG_PTR)Traits;
+ EventData[0].Size = *Traits;
+ EventData[0].Reserved = 2; // EVENT_DATA_DESCRIPTOR_TYPE_PROVIDER_METADATA
+ }
+
+ return MCGEN_EVENTWRITETRANSFER(
+ Context->RegistrationHandle,
+ Descriptor,
+ ActivityId,
+ NULL,
+ EventDataCount,
+ EventData);
+}
+#endif // McGenEventWrite_def
+
+#if !defined(McGenEventRegisterUnregister)
+#define McGenEventRegisterUnregister
+
+// This macro is for use by MC-generated code and should not be used directly.
+#define McGenEventRegister _mcgen_PASTE2(McGenEventRegister_, MCGEN_EVENTREGISTER)
+
+#pragma warning(push)
+#pragma warning(disable:6103)
+// This function is for use by MC-generated code and should not be used directly.
+DECLSPEC_NOINLINE __inline
+ULONG __stdcall
+McGenEventRegister(
+ _In_ LPCGUID ProviderId,
+ _In_opt_ _mcgen_PENABLECALLBACK EnableCallback,
+ _In_opt_ PVOID CallbackContext,
+ _Inout_ PREGHANDLE RegHandle
+ )
+/*++
+
+Routine Description:
+
+ This function registers the provider with ETW.
+
+Arguments:
+
+ ProviderId - Provider ID to register with ETW.
+
+ EnableCallback - Callback to be used.
+
+ CallbackContext - Context for the callback.
+
+ RegHandle - Pointer to registration handle.
+
+Remarks:
+
+ Should not be called if the provider is already registered (i.e. should not
+ be called if *RegHandle != 0). Repeatedly registering a provider is a bug
+ and may indicate a race condition. However, for compatibility with previous
+ behavior, this function will return SUCCESS in this case.
+
+--*/
+{
+ ULONG Error;
+
+ if (*RegHandle != 0)
+ {
+ Error = 0; // ERROR_SUCCESS
+ }
+ else
+ {
+ Error = MCGEN_EVENTREGISTER(ProviderId, EnableCallback, CallbackContext, RegHandle);
+ }
+
+ return Error;
+}
+#pragma warning(pop)
+
+// This macro is for use by MC-generated code and should not be used directly.
+#define McGenEventUnregister _mcgen_PASTE2(McGenEventUnregister_, MCGEN_EVENTUNREGISTER)
+
+// This function is for use by MC-generated code and should not be used directly.
+DECLSPEC_NOINLINE __inline
+ULONG __stdcall
+McGenEventUnregister(_Inout_ PREGHANDLE RegHandle)
+/*++
+
+Routine Description:
+
+ Unregister from ETW and set *RegHandle = 0.
+
+Arguments:
+
+ RegHandle - the pointer to the provider registration handle
+
+Remarks:
+
+ If provider has not been registered (i.e. if *RegHandle == 0),
+ return SUCCESS. It is safe to call McGenEventUnregister even if the
+ call to McGenEventRegister returned an error.
+
+--*/
+{
+ ULONG Error;
+
+ if(*RegHandle == 0)
+ {
+ Error = 0; // ERROR_SUCCESS
+ }
+ else
+ {
+ Error = MCGEN_EVENTUNREGISTER(*RegHandle);
+ *RegHandle = (REGHANDLE)0;
+ }
+
+ return Error;
+}
+
+#endif // McGenEventRegisterUnregister
+
+#ifndef _mcgen_EVENT_BIT_SET
+ #if defined(_M_IX86) || defined(_M_X64)
+ // This macro is for use by MC-generated code and should not be used directly.
+ #define _mcgen_EVENT_BIT_SET(EnableBits, BitPosition) ((((const unsigned char*)EnableBits)[BitPosition >> 3] & (1u << (BitPosition & 7))) != 0)
+ #else // CPU type
+ // This macro is for use by MC-generated code and should not be used directly.
+ #define _mcgen_EVENT_BIT_SET(EnableBits, BitPosition) ((EnableBits[BitPosition >> 5] & (1u << (BitPosition & 31))) != 0)
+ #endif // CPU type
+#endif // _mcgen_EVENT_BIT_SET
+
+#endif // MCGEN_DISABLE_PROVIDER_CODE_GENERATION
+
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+// Provider "JonMon" event count 32
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+// Provider GUID = d8909c24-5be9-4502-98ca-ab7bdc24899d
+EXTERN_C __declspec(selectany) const GUID JonMonProvider = {0xd8909c24, 0x5be9, 0x4502, {0x98, 0xca, 0xab, 0x7b, 0xdc, 0x24, 0x89, 0x9d}};
+
+#ifndef JonMonProvider_Traits
+#define JonMonProvider_Traits NULL
+#endif // JonMonProvider_Traits
+
+//
+// Channel
+//
+#define JonMonProvider_CHANNEL_JonMon 0x10
+#define JonMonProvider_CHANNEL_JonMon_KEYWORD 0x8000000000000000
+
+//
+// Event Descriptors
+//
+EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR ProcessCreation = {0x1, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8000000000000000};
+#define ProcessCreation_value 0x1
+EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR ProcessAccess = {0x2, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8000000000000000};
+#define ProcessAccess_value 0x2
+EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR ProcessAccessDuplicated = {0x3, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8000000000000000};
+#define ProcessAccessDuplicated_value 0x3
+EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR ImageLoaded = {0x4, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8000000000000000};
+#define ImageLoaded_value 0x4
+EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR RegistryCreateKey = {0x5, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8000000000000000};
+#define RegistryCreateKey_value 0x5
+EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR RegistryDeleteKey = {0x6, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8000000000000000};
+#define RegistryDeleteKey_value 0x6
+EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR RegistrySetValue = {0x7, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8000000000000000};
+#define RegistrySetValue_value 0x7
+EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR ProcessReparenting = {0x8, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8000000000000000};
+#define ProcessReparenting_value 0x8
+EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR ProcessTerminate = {0x9, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8000000000000000};
+#define ProcessTerminate_value 0x9
+EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR FileRename = {0xa, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8000000000000000};
+#define FileRename_value 0xa
+EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR RPCClientCall = {0xb, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8000000000000000};
+#define RPCClientCall_value 0xb
+EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR RPCServerCall = {0xc, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8000000000000000};
+#define RPCServerCall_value 0xc
+EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR NetworkConnectionAccepted = {0xd, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8000000000000000};
+#define NetworkConnectionAccepted_value 0xd
+EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR RegistrySaveKey = {0xe, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8000000000000000};
+#define RegistrySaveKey_value 0xe
+EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR DotNetLoad = {0xf, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8000000000000000};
+#define DotNetLoad_value 0xf
+EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR AMSI = {0x10, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8000000000000000};
+#define AMSI_value 0x10
+EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR ImpersonationAction = {0x11, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8000000000000000};
+#define ImpersonationAction_value 0x11
+EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR RemoteThreadCreation = {0x12, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8000000000000000};
+#define RemoteThreadCreation_value 0x12
+EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR SchedTaskCreation = {0x13, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8000000000000000};
+#define SchedTaskCreation_value 0x13
+EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR SchedTaskStarted = {0x14, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8000000000000000};
+#define SchedTaskStarted_value 0x14
+EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR FileCreate = {0x15, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8000000000000000};
+#define FileCreate_value 0x15
+EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR FileDelete = {0x16, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8000000000000000};
+#define FileDelete_value 0x16
+EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR NamedPipeCreate = {0x17, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8000000000000000};
+#define NamedPipeCreate_value 0x17
+EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR NamedPipeOpen = {0x18, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8000000000000000};
+#define NamedPipeOpen_value 0x18
+EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR WMIFilterToConsumerBinding = {0x19, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8000000000000000};
+#define WMIFilterToConsumerBinding_value 0x19
+EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR TIQueueUserAPCEvent = {0x1a, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8000000000000000};
+#define TIQueueUserAPCEvent_value 0x1a
+EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR DriverLoad = {0x1b, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8000000000000000};
+#define DriverLoad_value 0x1b
+EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR DPAPI = {0x1c, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8000000000000000};
+#define DPAPI_value 0x1c
+EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR TIWriteProcessMemory = {0x1d, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8000000000000000};
+#define TIWriteProcessMemory_value 0x1d
+EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR TIReadProcessMemory = {0x1e, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8000000000000000};
+#define TIReadProcessMemory_value 0x1e
+EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR ThreadTokenImpersonation = {0x1f, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8000000000000000};
+#define ThreadTokenImpersonation_value 0x1f
+EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR TIRemoteAllocateVirtualMemory = {0x20, 0x0, 0x10, 0x4, 0x0, 0x0, 0x8000000000000000};
+#define TIRemoteAllocateVirtualMemory_value 0x20
+
+//
+// MCGEN_DISABLE_PROVIDER_CODE_GENERATION macro:
+// Define this macro to have the compiler skip the generated functions in this
+// header.
+//
+#ifndef MCGEN_DISABLE_PROVIDER_CODE_GENERATION
+
+//
+// Event Enablement Bits
+// These variables are for use by MC-generated code and should not be used directly.
+//
+EXTERN_C __declspec(selectany) DECLSPEC_CACHEALIGN ULONG JonMonEnableBits[1];
+EXTERN_C __declspec(selectany) const ULONGLONG JonMonKeywords[1] = {0x8000000000000000};
+EXTERN_C __declspec(selectany) const unsigned char JonMonLevels[1] = {4};
+
+//
+// Provider context
+//
+EXTERN_C __declspec(selectany) MCGEN_TRACE_CONTEXT JonMonProvider_Context = {0, (ULONG_PTR)JonMonProvider_Traits, 0, 0, 0, 0, 0, 0, 1, JonMonEnableBits, JonMonKeywords, JonMonLevels};
+
+//
+// Provider REGHANDLE
+//
+#define JonMonHandle (JonMonProvider_Context.RegistrationHandle)
+
+//
+// This macro is set to 1, indicating that the EventWrite[Name] macros
+// have an Activity parameter. This is controlled by the -km and -um options.
+//
+#define JonMonProvider_EventWriteActivity 1
+
+//
+// Register with ETW using the control GUID specified in the manifest.
+// Invoke this macro during module initialization (i.e. program startup,
+// DLL process attach, or driver load) to initialize the provider.
+// Note that if this function returns an error, the error means that
+// will not work, but no action needs to be taken -- even if EventRegister
+// returns an error, it is generally safe to use EventWrite and
+// EventUnregister macros (they will be no-ops if EventRegister failed).
+//
+#ifndef EventRegisterJonMon
+#define EventRegisterJonMon() McGenEventRegister(&JonMonProvider, McGenControlCallbackV2, &JonMonProvider_Context, &JonMonHandle)
+#endif
+
+//
+// Register with ETW using a specific control GUID (i.e. a GUID other than what
+// is specified in the manifest). Advanced scenarios only.
+//
+#ifndef EventRegisterByGuidJonMon
+#define EventRegisterByGuidJonMon(Guid) McGenEventRegister(&(Guid), McGenControlCallbackV2, &JonMonProvider_Context, &JonMonHandle)
+#endif
+
+//
+// Unregister with ETW and close the provider.
+// Invoke this macro during module shutdown (i.e. program exit, DLL process
+// detach, or driver unload) to unregister the provider.
+// Note that you MUST call EventUnregister before DLL or driver unload
+// (not optional): failure to unregister a provider before DLL or driver unload
+// will result in crashes.
+//
+#ifndef EventUnregisterJonMon
+#define EventUnregisterJonMon() McGenEventUnregister(&JonMonHandle)
+#endif
+
+//
+// MCGEN_ENABLE_FORCONTEXT_CODE_GENERATION macro:
+// Define this macro to enable support for caller-allocated provider context.
+//
+#ifdef MCGEN_ENABLE_FORCONTEXT_CODE_GENERATION
+
+//
+// Advanced scenarios: Caller-allocated provider context.
+// Use when multiple differently-configured provider handles are needed,
+// e.g. for container-aware drivers, one context per container.
+//
+// Usage:
+//
+// - Caller enables the feature before including this header, e.g.
+// #define MCGEN_ENABLE_FORCONTEXT_CODE_GENERATION 1
+// - Caller allocates memory, e.g. pContext = malloc(sizeof(McGenContext_JonMon));
+// - Caller registers the provider, e.g. EventRegisterJonMon_ForContext(pContext);
+// - Caller writes events, e.g. EventWriteMyEvent_ForContext(pContext, ...);
+// - Caller unregisters, e.g. EventUnregisterJonMon_ForContext(pContext);
+// - Caller frees memory, e.g. free(pContext);
+//
+
+typedef struct tagMcGenContext_JonMon {
+ // The fields of this structure are subject to change and should
+ // not be accessed directly. To access the provider's REGHANDLE,
+ // use JonMonHandle_ForContext(pContext).
+ MCGEN_TRACE_CONTEXT Context;
+ ULONG EnableBits[1];
+} McGenContext_JonMon;
+
+#define EventRegisterJonMon_ForContext(pContext) _mcgen_PASTE2(_mcgen_RegisterForContext_JonMon_, MCGEN_EVENTREGISTER)(&JonMonProvider, pContext)
+#define EventRegisterByGuidJonMon_ForContext(Guid, pContext) _mcgen_PASTE2(_mcgen_RegisterForContext_JonMon_, MCGEN_EVENTREGISTER)(&(Guid), pContext)
+#define EventUnregisterJonMon_ForContext(pContext) McGenEventUnregister(&(pContext)->Context.RegistrationHandle)
+
+//
+// Provider REGHANDLE for caller-allocated context.
+//
+#define JonMonHandle_ForContext(pContext) ((pContext)->Context.RegistrationHandle)
+
+// This function is for use by MC-generated code and should not be used directly.
+// Initialize and register the caller-allocated context.
+__inline
+ULONG __stdcall
+_mcgen_PASTE2(_mcgen_RegisterForContext_JonMon_, MCGEN_EVENTREGISTER)(
+ _In_ LPCGUID pProviderId,
+ _Out_ McGenContext_JonMon* pContext)
+{
+ RtlZeroMemory(pContext, sizeof(*pContext));
+ pContext->Context.Logger = (ULONG_PTR)JonMonProvider_Traits;
+ pContext->Context.EnableBitsCount = 1;
+ pContext->Context.EnableBitMask = pContext->EnableBits;
+ pContext->Context.EnableKeyWords = JonMonKeywords;
+ pContext->Context.EnableLevel = JonMonLevels;
+ return McGenEventRegister(
+ pProviderId,
+ McGenControlCallbackV2,
+ &pContext->Context,
+ &pContext->Context.RegistrationHandle);
+}
+
+// This function is for use by MC-generated code and should not be used directly.
+// Trigger a compile error if called with the wrong parameter type.
+FORCEINLINE
+_Ret_ McGenContext_JonMon*
+_mcgen_CheckContextType_JonMon(_In_ McGenContext_JonMon* pContext)
+{
+ return pContext;
+}
+
+#endif // MCGEN_ENABLE_FORCONTEXT_CODE_GENERATION
+
+//
+// Enablement check macro for event "ProcessCreation"
+//
+#define EventEnabledProcessCreation() _mcgen_EVENT_BIT_SET(JonMonEnableBits, 0)
+#define EventEnabledProcessCreation_ForContext(pContext) _mcgen_EVENT_BIT_SET(_mcgen_CheckContextType_JonMon(pContext)->EnableBits, 0)
+
+//
+// Event write macros for event "ProcessCreation"
+//
+#define EventWriteProcessCreation(Activity, EventTime_, NewProcessFilePath, NewProcessCommandLine, NewProcessId, NewProcessStartKey, NewProcessStartTime, NewProcessProcessUser, NewProcessUserLogonId, ParentProcessId, ParentProcessThreadId, ParentProcessFilePath, CreatorProcessId, ParentProcessUser, ParentProcessUserLogonId) \
+ MCGEN_EVENT_ENABLED(ProcessCreation) \
+ ? _mcgen_TEMPLATE_FOR_ProcessCreation(&JonMonProvider_Context, &ProcessCreation, Activity, EventTime_, NewProcessFilePath, NewProcessCommandLine, NewProcessId, NewProcessStartKey, NewProcessStartTime, NewProcessProcessUser, NewProcessUserLogonId, ParentProcessId, ParentProcessThreadId, ParentProcessFilePath, CreatorProcessId, ParentProcessUser, ParentProcessUserLogonId) : 0
+#define EventWriteProcessCreation_AssumeEnabled(EventTime_, NewProcessFilePath, NewProcessCommandLine, NewProcessId, NewProcessStartKey, NewProcessStartTime, NewProcessProcessUser, NewProcessUserLogonId, ParentProcessId, ParentProcessThreadId, ParentProcessFilePath, CreatorProcessId, ParentProcessUser, ParentProcessUserLogonId) \
+ _mcgen_TEMPLATE_FOR_ProcessCreation(&JonMonProvider_Context, &ProcessCreation, NULL, EventTime_, NewProcessFilePath, NewProcessCommandLine, NewProcessId, NewProcessStartKey, NewProcessStartTime, NewProcessProcessUser, NewProcessUserLogonId, ParentProcessId, ParentProcessThreadId, ParentProcessFilePath, CreatorProcessId, ParentProcessUser, ParentProcessUserLogonId)
+#define EventWriteProcessCreation_ForContext(pContext, Activity, EventTime_, NewProcessFilePath, NewProcessCommandLine, NewProcessId, NewProcessStartKey, NewProcessStartTime, NewProcessProcessUser, NewProcessUserLogonId, ParentProcessId, ParentProcessThreadId, ParentProcessFilePath, CreatorProcessId, ParentProcessUser, ParentProcessUserLogonId) \
+ MCGEN_EVENT_ENABLED_FORCONTEXT(pContext, ProcessCreation) \
+ ? _mcgen_TEMPLATE_FOR_ProcessCreation(&(pContext)->Context, &ProcessCreation, Activity, EventTime_, NewProcessFilePath, NewProcessCommandLine, NewProcessId, NewProcessStartKey, NewProcessStartTime, NewProcessProcessUser, NewProcessUserLogonId, ParentProcessId, ParentProcessThreadId, ParentProcessFilePath, CreatorProcessId, ParentProcessUser, ParentProcessUserLogonId) : 0
+#define EventWriteProcessCreation_ForContextAssumeEnabled(pContext, EventTime_, NewProcessFilePath, NewProcessCommandLine, NewProcessId, NewProcessStartKey, NewProcessStartTime, NewProcessProcessUser, NewProcessUserLogonId, ParentProcessId, ParentProcessThreadId, ParentProcessFilePath, CreatorProcessId, ParentProcessUser, ParentProcessUserLogonId) \
+ _mcgen_TEMPLATE_FOR_ProcessCreation(&_mcgen_CheckContextType_JonMon(pContext)->Context, &ProcessCreation, NULL, EventTime_, NewProcessFilePath, NewProcessCommandLine, NewProcessId, NewProcessStartKey, NewProcessStartTime, NewProcessProcessUser, NewProcessUserLogonId, ParentProcessId, ParentProcessThreadId, ParentProcessFilePath, CreatorProcessId, ParentProcessUser, ParentProcessUserLogonId)
+
+// This macro is for use by MC-generated code and should not be used directly.
+#define _mcgen_TEMPLATE_FOR_ProcessCreation _mcgen_PASTE2(McTemplateK0mzzxxxzqxxzxzq_, MCGEN_EVENTWRITETRANSFER)
+
+//
+// Enablement check macro for event "ProcessAccess"
+//
+#define EventEnabledProcessAccess() _mcgen_EVENT_BIT_SET(JonMonEnableBits, 0)
+#define EventEnabledProcessAccess_ForContext(pContext) _mcgen_EVENT_BIT_SET(_mcgen_CheckContextType_JonMon(pContext)->EnableBits, 0)
+
+//
+// Event write macros for event "ProcessAccess"
+//
+#define EventWriteProcessAccess(Activity, EventTime_, SourceProcessGrantedAccess, TargetProcessId, TargetProcessStartKey, TargetImagePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, SourceProcessFilePath, SourceProcessUser, SourceProcessUserLogonId) \
+ MCGEN_EVENT_ENABLED(ProcessAccess) \
+ ? _mcgen_TEMPLATE_FOR_ProcessAccess(&JonMonProvider_Context, &ProcessAccess, Activity, EventTime_, SourceProcessGrantedAccess, TargetProcessId, TargetProcessStartKey, TargetImagePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, SourceProcessFilePath, SourceProcessUser, SourceProcessUserLogonId) : 0
+#define EventWriteProcessAccess_AssumeEnabled(EventTime_, SourceProcessGrantedAccess, TargetProcessId, TargetProcessStartKey, TargetImagePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, SourceProcessFilePath, SourceProcessUser, SourceProcessUserLogonId) \
+ _mcgen_TEMPLATE_FOR_ProcessAccess(&JonMonProvider_Context, &ProcessAccess, NULL, EventTime_, SourceProcessGrantedAccess, TargetProcessId, TargetProcessStartKey, TargetImagePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, SourceProcessFilePath, SourceProcessUser, SourceProcessUserLogonId)
+#define EventWriteProcessAccess_ForContext(pContext, Activity, EventTime_, SourceProcessGrantedAccess, TargetProcessId, TargetProcessStartKey, TargetImagePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, SourceProcessFilePath, SourceProcessUser, SourceProcessUserLogonId) \
+ MCGEN_EVENT_ENABLED_FORCONTEXT(pContext, ProcessAccess) \
+ ? _mcgen_TEMPLATE_FOR_ProcessAccess(&(pContext)->Context, &ProcessAccess, Activity, EventTime_, SourceProcessGrantedAccess, TargetProcessId, TargetProcessStartKey, TargetImagePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, SourceProcessFilePath, SourceProcessUser, SourceProcessUserLogonId) : 0
+#define EventWriteProcessAccess_ForContextAssumeEnabled(pContext, EventTime_, SourceProcessGrantedAccess, TargetProcessId, TargetProcessStartKey, TargetImagePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, SourceProcessFilePath, SourceProcessUser, SourceProcessUserLogonId) \
+ _mcgen_TEMPLATE_FOR_ProcessAccess(&_mcgen_CheckContextType_JonMon(pContext)->Context, &ProcessAccess, NULL, EventTime_, SourceProcessGrantedAccess, TargetProcessId, TargetProcessStartKey, TargetImagePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, SourceProcessFilePath, SourceProcessUser, SourceProcessUserLogonId)
+
+// This macro is for use by MC-generated code and should not be used directly.
+#define _mcgen_TEMPLATE_FOR_ProcessAccess _mcgen_PASTE2(McTemplateK0mdxxzxxxzzq_, MCGEN_EVENTWRITETRANSFER)
+
+//
+// Enablement check macro for event "ProcessAccessDuplicated"
+//
+#define EventEnabledProcessAccessDuplicated() _mcgen_EVENT_BIT_SET(JonMonEnableBits, 0)
+#define EventEnabledProcessAccessDuplicated_ForContext(pContext) _mcgen_EVENT_BIT_SET(_mcgen_CheckContextType_JonMon(pContext)->EnableBits, 0)
+
+//
+// Event write macros for event "ProcessAccessDuplicated"
+//
+#define EventWriteProcessAccessDuplicated(Activity, EventTime_, SourceProcessDuplicatedGrantedAccess, TargetProcessId, TargetProcessStartKey, TargetImagePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, SourceProcessFilePath, SourceProcessUser, SourceProcessUserLogonId) \
+ MCGEN_EVENT_ENABLED(ProcessAccessDuplicated) \
+ ? _mcgen_TEMPLATE_FOR_ProcessAccessDuplicated(&JonMonProvider_Context, &ProcessAccessDuplicated, Activity, EventTime_, SourceProcessDuplicatedGrantedAccess, TargetProcessId, TargetProcessStartKey, TargetImagePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, SourceProcessFilePath, SourceProcessUser, SourceProcessUserLogonId) : 0
+#define EventWriteProcessAccessDuplicated_AssumeEnabled(EventTime_, SourceProcessDuplicatedGrantedAccess, TargetProcessId, TargetProcessStartKey, TargetImagePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, SourceProcessFilePath, SourceProcessUser, SourceProcessUserLogonId) \
+ _mcgen_TEMPLATE_FOR_ProcessAccessDuplicated(&JonMonProvider_Context, &ProcessAccessDuplicated, NULL, EventTime_, SourceProcessDuplicatedGrantedAccess, TargetProcessId, TargetProcessStartKey, TargetImagePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, SourceProcessFilePath, SourceProcessUser, SourceProcessUserLogonId)
+#define EventWriteProcessAccessDuplicated_ForContext(pContext, Activity, EventTime_, SourceProcessDuplicatedGrantedAccess, TargetProcessId, TargetProcessStartKey, TargetImagePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, SourceProcessFilePath, SourceProcessUser, SourceProcessUserLogonId) \
+ MCGEN_EVENT_ENABLED_FORCONTEXT(pContext, ProcessAccessDuplicated) \
+ ? _mcgen_TEMPLATE_FOR_ProcessAccessDuplicated(&(pContext)->Context, &ProcessAccessDuplicated, Activity, EventTime_, SourceProcessDuplicatedGrantedAccess, TargetProcessId, TargetProcessStartKey, TargetImagePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, SourceProcessFilePath, SourceProcessUser, SourceProcessUserLogonId) : 0
+#define EventWriteProcessAccessDuplicated_ForContextAssumeEnabled(pContext, EventTime_, SourceProcessDuplicatedGrantedAccess, TargetProcessId, TargetProcessStartKey, TargetImagePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, SourceProcessFilePath, SourceProcessUser, SourceProcessUserLogonId) \
+ _mcgen_TEMPLATE_FOR_ProcessAccessDuplicated(&_mcgen_CheckContextType_JonMon(pContext)->Context, &ProcessAccessDuplicated, NULL, EventTime_, SourceProcessDuplicatedGrantedAccess, TargetProcessId, TargetProcessStartKey, TargetImagePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, SourceProcessFilePath, SourceProcessUser, SourceProcessUserLogonId)
+
+// This macro is for use by MC-generated code and should not be used directly.
+#define _mcgen_TEMPLATE_FOR_ProcessAccessDuplicated _mcgen_PASTE2(McTemplateK0mdxxzxxxzzq_, MCGEN_EVENTWRITETRANSFER)
+
+//
+// Enablement check macro for event "ImageLoaded"
+//
+#define EventEnabledImageLoaded() _mcgen_EVENT_BIT_SET(JonMonEnableBits, 0)
+#define EventEnabledImageLoaded_ForContext(pContext) _mcgen_EVENT_BIT_SET(_mcgen_CheckContextType_JonMon(pContext)->EnableBits, 0)
+
+//
+// Event write macros for event "ImageLoaded"
+//
+#define EventWriteImageLoaded(Activity, EventTime_, SourceProcessFilePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, ModulePath, SourceProcessUser, SourceProcessUserLogonId) \
+ MCGEN_EVENT_ENABLED(ImageLoaded) \
+ ? _mcgen_TEMPLATE_FOR_ImageLoaded(&JonMonProvider_Context, &ImageLoaded, Activity, EventTime_, SourceProcessFilePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, ModulePath, SourceProcessUser, SourceProcessUserLogonId) : 0
+#define EventWriteImageLoaded_AssumeEnabled(EventTime_, SourceProcessFilePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, ModulePath, SourceProcessUser, SourceProcessUserLogonId) \
+ _mcgen_TEMPLATE_FOR_ImageLoaded(&JonMonProvider_Context, &ImageLoaded, NULL, EventTime_, SourceProcessFilePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, ModulePath, SourceProcessUser, SourceProcessUserLogonId)
+#define EventWriteImageLoaded_ForContext(pContext, Activity, EventTime_, SourceProcessFilePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, ModulePath, SourceProcessUser, SourceProcessUserLogonId) \
+ MCGEN_EVENT_ENABLED_FORCONTEXT(pContext, ImageLoaded) \
+ ? _mcgen_TEMPLATE_FOR_ImageLoaded(&(pContext)->Context, &ImageLoaded, Activity, EventTime_, SourceProcessFilePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, ModulePath, SourceProcessUser, SourceProcessUserLogonId) : 0
+#define EventWriteImageLoaded_ForContextAssumeEnabled(pContext, EventTime_, SourceProcessFilePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, ModulePath, SourceProcessUser, SourceProcessUserLogonId) \
+ _mcgen_TEMPLATE_FOR_ImageLoaded(&_mcgen_CheckContextType_JonMon(pContext)->Context, &ImageLoaded, NULL, EventTime_, SourceProcessFilePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, ModulePath, SourceProcessUser, SourceProcessUserLogonId)
+
+// This macro is for use by MC-generated code and should not be used directly.
+#define _mcgen_TEMPLATE_FOR_ImageLoaded _mcgen_PASTE2(McTemplateK0mzxxxzzq_, MCGEN_EVENTWRITETRANSFER)
+
+//
+// Enablement check macro for event "RegistryCreateKey"
+//
+#define EventEnabledRegistryCreateKey() _mcgen_EVENT_BIT_SET(JonMonEnableBits, 0)
+#define EventEnabledRegistryCreateKey_ForContext(pContext) _mcgen_EVENT_BIT_SET(_mcgen_CheckContextType_JonMon(pContext)->EnableBits, 0)
+
+//
+// Event write macros for event "RegistryCreateKey"
+//
+#define EventWriteRegistryCreateKey(Activity, EventTime_, SourceProcessFilePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, SourceRegistryKeyPath, SourceProcessGrantedAccess, SourceProcessUser, SourceProcessUserLogonId) \
+ MCGEN_EVENT_ENABLED(RegistryCreateKey) \
+ ? _mcgen_TEMPLATE_FOR_RegistryCreateKey(&JonMonProvider_Context, &RegistryCreateKey, Activity, EventTime_, SourceProcessFilePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, SourceRegistryKeyPath, SourceProcessGrantedAccess, SourceProcessUser, SourceProcessUserLogonId) : 0
+#define EventWriteRegistryCreateKey_AssumeEnabled(EventTime_, SourceProcessFilePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, SourceRegistryKeyPath, SourceProcessGrantedAccess, SourceProcessUser, SourceProcessUserLogonId) \
+ _mcgen_TEMPLATE_FOR_RegistryCreateKey(&JonMonProvider_Context, &RegistryCreateKey, NULL, EventTime_, SourceProcessFilePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, SourceRegistryKeyPath, SourceProcessGrantedAccess, SourceProcessUser, SourceProcessUserLogonId)
+#define EventWriteRegistryCreateKey_ForContext(pContext, Activity, EventTime_, SourceProcessFilePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, SourceRegistryKeyPath, SourceProcessGrantedAccess, SourceProcessUser, SourceProcessUserLogonId) \
+ MCGEN_EVENT_ENABLED_FORCONTEXT(pContext, RegistryCreateKey) \
+ ? _mcgen_TEMPLATE_FOR_RegistryCreateKey(&(pContext)->Context, &RegistryCreateKey, Activity, EventTime_, SourceProcessFilePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, SourceRegistryKeyPath, SourceProcessGrantedAccess, SourceProcessUser, SourceProcessUserLogonId) : 0
+#define EventWriteRegistryCreateKey_ForContextAssumeEnabled(pContext, EventTime_, SourceProcessFilePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, SourceRegistryKeyPath, SourceProcessGrantedAccess, SourceProcessUser, SourceProcessUserLogonId) \
+ _mcgen_TEMPLATE_FOR_RegistryCreateKey(&_mcgen_CheckContextType_JonMon(pContext)->Context, &RegistryCreateKey, NULL, EventTime_, SourceProcessFilePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, SourceRegistryKeyPath, SourceProcessGrantedAccess, SourceProcessUser, SourceProcessUserLogonId)
+
+// This macro is for use by MC-generated code and should not be used directly.
+#define _mcgen_TEMPLATE_FOR_RegistryCreateKey _mcgen_PASTE2(McTemplateK0mzxxxzdzq_, MCGEN_EVENTWRITETRANSFER)
+
+//
+// Enablement check macro for event "RegistryDeleteKey"
+//
+#define EventEnabledRegistryDeleteKey() _mcgen_EVENT_BIT_SET(JonMonEnableBits, 0)
+#define EventEnabledRegistryDeleteKey_ForContext(pContext) _mcgen_EVENT_BIT_SET(_mcgen_CheckContextType_JonMon(pContext)->EnableBits, 0)
+
+//
+// Event write macros for event "RegistryDeleteKey"
+//
+#define EventWriteRegistryDeleteKey(Activity, EventTime_, SourceProcessFilePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, RegistryKeyPath, SourceProcessUser, SourceProcessUserLogonId) \
+ MCGEN_EVENT_ENABLED(RegistryDeleteKey) \
+ ? _mcgen_TEMPLATE_FOR_RegistryDeleteKey(&JonMonProvider_Context, &RegistryDeleteKey, Activity, EventTime_, SourceProcessFilePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, RegistryKeyPath, SourceProcessUser, SourceProcessUserLogonId) : 0
+#define EventWriteRegistryDeleteKey_AssumeEnabled(EventTime_, SourceProcessFilePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, RegistryKeyPath, SourceProcessUser, SourceProcessUserLogonId) \
+ _mcgen_TEMPLATE_FOR_RegistryDeleteKey(&JonMonProvider_Context, &RegistryDeleteKey, NULL, EventTime_, SourceProcessFilePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, RegistryKeyPath, SourceProcessUser, SourceProcessUserLogonId)
+#define EventWriteRegistryDeleteKey_ForContext(pContext, Activity, EventTime_, SourceProcessFilePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, RegistryKeyPath, SourceProcessUser, SourceProcessUserLogonId) \
+ MCGEN_EVENT_ENABLED_FORCONTEXT(pContext, RegistryDeleteKey) \
+ ? _mcgen_TEMPLATE_FOR_RegistryDeleteKey(&(pContext)->Context, &RegistryDeleteKey, Activity, EventTime_, SourceProcessFilePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, RegistryKeyPath, SourceProcessUser, SourceProcessUserLogonId) : 0
+#define EventWriteRegistryDeleteKey_ForContextAssumeEnabled(pContext, EventTime_, SourceProcessFilePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, RegistryKeyPath, SourceProcessUser, SourceProcessUserLogonId) \
+ _mcgen_TEMPLATE_FOR_RegistryDeleteKey(&_mcgen_CheckContextType_JonMon(pContext)->Context, &RegistryDeleteKey, NULL, EventTime_, SourceProcessFilePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, RegistryKeyPath, SourceProcessUser, SourceProcessUserLogonId)
+
+// This macro is for use by MC-generated code and should not be used directly.
+#define _mcgen_TEMPLATE_FOR_RegistryDeleteKey _mcgen_PASTE2(McTemplateK0mzxxxzzq_, MCGEN_EVENTWRITETRANSFER)
+
+//
+// Enablement check macro for event "RegistrySetValue"
+//
+#define EventEnabledRegistrySetValue() _mcgen_EVENT_BIT_SET(JonMonEnableBits, 0)
+#define EventEnabledRegistrySetValue_ForContext(pContext) _mcgen_EVENT_BIT_SET(_mcgen_CheckContextType_JonMon(pContext)->EnableBits, 0)
+
+//
+// Event write macros for event "RegistrySetValue"
+//
+#define EventWriteRegistrySetValue(Activity, EventTime_, SourceProcessFilePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, RegistryKeyPath, RegistryValueName, RegistryValueData, RegistryValueDataType, SourceProcessUser, SourceProcessUserLogonId) \
+ MCGEN_EVENT_ENABLED(RegistrySetValue) \
+ ? _mcgen_TEMPLATE_FOR_RegistrySetValue(&JonMonProvider_Context, &RegistrySetValue, Activity, EventTime_, SourceProcessFilePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, RegistryKeyPath, RegistryValueName, RegistryValueData, RegistryValueDataType, SourceProcessUser, SourceProcessUserLogonId) : 0
+#define EventWriteRegistrySetValue_AssumeEnabled(EventTime_, SourceProcessFilePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, RegistryKeyPath, RegistryValueName, RegistryValueData, RegistryValueDataType, SourceProcessUser, SourceProcessUserLogonId) \
+ _mcgen_TEMPLATE_FOR_RegistrySetValue(&JonMonProvider_Context, &RegistrySetValue, NULL, EventTime_, SourceProcessFilePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, RegistryKeyPath, RegistryValueName, RegistryValueData, RegistryValueDataType, SourceProcessUser, SourceProcessUserLogonId)
+#define EventWriteRegistrySetValue_ForContext(pContext, Activity, EventTime_, SourceProcessFilePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, RegistryKeyPath, RegistryValueName, RegistryValueData, RegistryValueDataType, SourceProcessUser, SourceProcessUserLogonId) \
+ MCGEN_EVENT_ENABLED_FORCONTEXT(pContext, RegistrySetValue) \
+ ? _mcgen_TEMPLATE_FOR_RegistrySetValue(&(pContext)->Context, &RegistrySetValue, Activity, EventTime_, SourceProcessFilePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, RegistryKeyPath, RegistryValueName, RegistryValueData, RegistryValueDataType, SourceProcessUser, SourceProcessUserLogonId) : 0
+#define EventWriteRegistrySetValue_ForContextAssumeEnabled(pContext, EventTime_, SourceProcessFilePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, RegistryKeyPath, RegistryValueName, RegistryValueData, RegistryValueDataType, SourceProcessUser, SourceProcessUserLogonId) \
+ _mcgen_TEMPLATE_FOR_RegistrySetValue(&_mcgen_CheckContextType_JonMon(pContext)->Context, &RegistrySetValue, NULL, EventTime_, SourceProcessFilePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, RegistryKeyPath, RegistryValueName, RegistryValueData, RegistryValueDataType, SourceProcessUser, SourceProcessUserLogonId)
+
+// This macro is for use by MC-generated code and should not be used directly.
+#define _mcgen_TEMPLATE_FOR_RegistrySetValue _mcgen_PASTE2(McTemplateK0mzxxxzzzzzq_, MCGEN_EVENTWRITETRANSFER)
+
+//
+// Enablement check macro for event "ProcessReparenting"
+//
+#define EventEnabledProcessReparenting() _mcgen_EVENT_BIT_SET(JonMonEnableBits, 0)
+#define EventEnabledProcessReparenting_ForContext(pContext) _mcgen_EVENT_BIT_SET(_mcgen_CheckContextType_JonMon(pContext)->EnableBits, 0)
+
+//
+// Event write macros for event "ProcessReparenting"
+//
+#define EventWriteProcessReparenting(Activity, EventTime_, NewProcessFilePath, NewProcessCommandLine, ParentProcessId, ParentThreadId, NewProcessId, NewProcessStartKey, NewProcessStartTime, ParentProcessFilePath, CreatorProcessId, CreatorProcessFilePath, CreatorProcessUser, ParentProcessUser, NewProcessUser, ParentProcessLogonId, NewProcessUserLogonId, CreatorProcessLogonId) \
+ MCGEN_EVENT_ENABLED(ProcessReparenting) \
+ ? _mcgen_TEMPLATE_FOR_ProcessReparenting(&JonMonProvider_Context, &ProcessReparenting, Activity, EventTime_, NewProcessFilePath, NewProcessCommandLine, ParentProcessId, ParentThreadId, NewProcessId, NewProcessStartKey, NewProcessStartTime, ParentProcessFilePath, CreatorProcessId, CreatorProcessFilePath, CreatorProcessUser, ParentProcessUser, NewProcessUser, ParentProcessLogonId, NewProcessUserLogonId, CreatorProcessLogonId) : 0
+#define EventWriteProcessReparenting_AssumeEnabled(EventTime_, NewProcessFilePath, NewProcessCommandLine, ParentProcessId, ParentThreadId, NewProcessId, NewProcessStartKey, NewProcessStartTime, ParentProcessFilePath, CreatorProcessId, CreatorProcessFilePath, CreatorProcessUser, ParentProcessUser, NewProcessUser, ParentProcessLogonId, NewProcessUserLogonId, CreatorProcessLogonId) \
+ _mcgen_TEMPLATE_FOR_ProcessReparenting(&JonMonProvider_Context, &ProcessReparenting, NULL, EventTime_, NewProcessFilePath, NewProcessCommandLine, ParentProcessId, ParentThreadId, NewProcessId, NewProcessStartKey, NewProcessStartTime, ParentProcessFilePath, CreatorProcessId, CreatorProcessFilePath, CreatorProcessUser, ParentProcessUser, NewProcessUser, ParentProcessLogonId, NewProcessUserLogonId, CreatorProcessLogonId)
+#define EventWriteProcessReparenting_ForContext(pContext, Activity, EventTime_, NewProcessFilePath, NewProcessCommandLine, ParentProcessId, ParentThreadId, NewProcessId, NewProcessStartKey, NewProcessStartTime, ParentProcessFilePath, CreatorProcessId, CreatorProcessFilePath, CreatorProcessUser, ParentProcessUser, NewProcessUser, ParentProcessLogonId, NewProcessUserLogonId, CreatorProcessLogonId) \
+ MCGEN_EVENT_ENABLED_FORCONTEXT(pContext, ProcessReparenting) \
+ ? _mcgen_TEMPLATE_FOR_ProcessReparenting(&(pContext)->Context, &ProcessReparenting, Activity, EventTime_, NewProcessFilePath, NewProcessCommandLine, ParentProcessId, ParentThreadId, NewProcessId, NewProcessStartKey, NewProcessStartTime, ParentProcessFilePath, CreatorProcessId, CreatorProcessFilePath, CreatorProcessUser, ParentProcessUser, NewProcessUser, ParentProcessLogonId, NewProcessUserLogonId, CreatorProcessLogonId) : 0
+#define EventWriteProcessReparenting_ForContextAssumeEnabled(pContext, EventTime_, NewProcessFilePath, NewProcessCommandLine, ParentProcessId, ParentThreadId, NewProcessId, NewProcessStartKey, NewProcessStartTime, ParentProcessFilePath, CreatorProcessId, CreatorProcessFilePath, CreatorProcessUser, ParentProcessUser, NewProcessUser, ParentProcessLogonId, NewProcessUserLogonId, CreatorProcessLogonId) \
+ _mcgen_TEMPLATE_FOR_ProcessReparenting(&_mcgen_CheckContextType_JonMon(pContext)->Context, &ProcessReparenting, NULL, EventTime_, NewProcessFilePath, NewProcessCommandLine, ParentProcessId, ParentThreadId, NewProcessId, NewProcessStartKey, NewProcessStartTime, ParentProcessFilePath, CreatorProcessId, CreatorProcessFilePath, CreatorProcessUser, ParentProcessUser, NewProcessUser, ParentProcessLogonId, NewProcessUserLogonId, CreatorProcessLogonId)
+
+// This macro is for use by MC-generated code and should not be used directly.
+#define _mcgen_TEMPLATE_FOR_ProcessReparenting _mcgen_PASTE2(McTemplateK0mzzxxxxxzxzzzzqqq_, MCGEN_EVENTWRITETRANSFER)
+
+//
+// Enablement check macro for event "ProcessTerminate"
+//
+#define EventEnabledProcessTerminate() _mcgen_EVENT_BIT_SET(JonMonEnableBits, 0)
+#define EventEnabledProcessTerminate_ForContext(pContext) _mcgen_EVENT_BIT_SET(_mcgen_CheckContextType_JonMon(pContext)->EnableBits, 0)
+
+//
+// Event write macros for event "ProcessTerminate"
+//
+#define EventWriteProcessTerminate(Activity, EventTime_, SourceProcessFilePath, SourceProcessId, SourceThreadId, TargetProcessFilePath, TargetProcessId) \
+ MCGEN_EVENT_ENABLED(ProcessTerminate) \
+ ? _mcgen_TEMPLATE_FOR_ProcessTerminate(&JonMonProvider_Context, &ProcessTerminate, Activity, EventTime_, SourceProcessFilePath, SourceProcessId, SourceThreadId, TargetProcessFilePath, TargetProcessId) : 0
+#define EventWriteProcessTerminate_AssumeEnabled(EventTime_, SourceProcessFilePath, SourceProcessId, SourceThreadId, TargetProcessFilePath, TargetProcessId) \
+ _mcgen_TEMPLATE_FOR_ProcessTerminate(&JonMonProvider_Context, &ProcessTerminate, NULL, EventTime_, SourceProcessFilePath, SourceProcessId, SourceThreadId, TargetProcessFilePath, TargetProcessId)
+#define EventWriteProcessTerminate_ForContext(pContext, Activity, EventTime_, SourceProcessFilePath, SourceProcessId, SourceThreadId, TargetProcessFilePath, TargetProcessId) \
+ MCGEN_EVENT_ENABLED_FORCONTEXT(pContext, ProcessTerminate) \
+ ? _mcgen_TEMPLATE_FOR_ProcessTerminate(&(pContext)->Context, &ProcessTerminate, Activity, EventTime_, SourceProcessFilePath, SourceProcessId, SourceThreadId, TargetProcessFilePath, TargetProcessId) : 0
+#define EventWriteProcessTerminate_ForContextAssumeEnabled(pContext, EventTime_, SourceProcessFilePath, SourceProcessId, SourceThreadId, TargetProcessFilePath, TargetProcessId) \
+ _mcgen_TEMPLATE_FOR_ProcessTerminate(&_mcgen_CheckContextType_JonMon(pContext)->Context, &ProcessTerminate, NULL, EventTime_, SourceProcessFilePath, SourceProcessId, SourceThreadId, TargetProcessFilePath, TargetProcessId)
+
+// This macro is for use by MC-generated code and should not be used directly.
+#define _mcgen_TEMPLATE_FOR_ProcessTerminate _mcgen_PASTE2(McTemplateK0mzxxzx_, MCGEN_EVENTWRITETRANSFER)
+
+//
+// Enablement check macro for event "FileRename"
+//
+#define EventEnabledFileRename() _mcgen_EVENT_BIT_SET(JonMonEnableBits, 0)
+#define EventEnabledFileRename_ForContext(pContext) _mcgen_EVENT_BIT_SET(_mcgen_CheckContextType_JonMon(pContext)->EnableBits, 0)
+
+//
+// Event write macros for event "FileRename"
+//
+#define EventWriteFileRename(Activity, EventTime_, SourceImagePath, SourceProcessId, SourceProcessStartKey, SourceThreadId, SourceUserName, SourceUserLogonId, SourceProcessIntegrityLevel, TargetFile) \
+ MCGEN_EVENT_ENABLED(FileRename) \
+ ? _mcgen_TEMPLATE_FOR_FileRename(&JonMonProvider_Context, &FileRename, Activity, EventTime_, SourceImagePath, SourceProcessId, SourceProcessStartKey, SourceThreadId, SourceUserName, SourceUserLogonId, SourceProcessIntegrityLevel, TargetFile) : 0
+#define EventWriteFileRename_AssumeEnabled(EventTime_, SourceImagePath, SourceProcessId, SourceProcessStartKey, SourceThreadId, SourceUserName, SourceUserLogonId, SourceProcessIntegrityLevel, TargetFile) \
+ _mcgen_TEMPLATE_FOR_FileRename(&JonMonProvider_Context, &FileRename, NULL, EventTime_, SourceImagePath, SourceProcessId, SourceProcessStartKey, SourceThreadId, SourceUserName, SourceUserLogonId, SourceProcessIntegrityLevel, TargetFile)
+#define EventWriteFileRename_ForContext(pContext, Activity, EventTime_, SourceImagePath, SourceProcessId, SourceProcessStartKey, SourceThreadId, SourceUserName, SourceUserLogonId, SourceProcessIntegrityLevel, TargetFile) \
+ MCGEN_EVENT_ENABLED_FORCONTEXT(pContext, FileRename) \
+ ? _mcgen_TEMPLATE_FOR_FileRename(&(pContext)->Context, &FileRename, Activity, EventTime_, SourceImagePath, SourceProcessId, SourceProcessStartKey, SourceThreadId, SourceUserName, SourceUserLogonId, SourceProcessIntegrityLevel, TargetFile) : 0
+#define EventWriteFileRename_ForContextAssumeEnabled(pContext, EventTime_, SourceImagePath, SourceProcessId, SourceProcessStartKey, SourceThreadId, SourceUserName, SourceUserLogonId, SourceProcessIntegrityLevel, TargetFile) \
+ _mcgen_TEMPLATE_FOR_FileRename(&_mcgen_CheckContextType_JonMon(pContext)->Context, &FileRename, NULL, EventTime_, SourceImagePath, SourceProcessId, SourceProcessStartKey, SourceThreadId, SourceUserName, SourceUserLogonId, SourceProcessIntegrityLevel, TargetFile)
+
+// This macro is for use by MC-generated code and should not be used directly.
+#define _mcgen_TEMPLATE_FOR_FileRename _mcgen_PASTE2(McTemplateK0mzxxxzqzz_, MCGEN_EVENTWRITETRANSFER)
+
+//
+// Enablement check macro for event "RPCClientCall"
+//
+#define EventEnabledRPCClientCall() _mcgen_EVENT_BIT_SET(JonMonEnableBits, 0)
+#define EventEnabledRPCClientCall_ForContext(pContext) _mcgen_EVENT_BIT_SET(_mcgen_CheckContextType_JonMon(pContext)->EnableBits, 0)
+
+//
+// Event write macros for event "RPCClientCall"
+//
+#define EventWriteRPCClientCall(Activity, EventTime_, Interface_UUID, ProcNum, Protocol, ProcessId, NetworkAddress, Endpoint, InterfaceString, MethodString, ProcessUser, ProcessFilePath, CallStack) \
+ MCGEN_EVENT_ENABLED(RPCClientCall) \
+ ? _mcgen_TEMPLATE_FOR_RPCClientCall(&JonMonProvider_Context, &RPCClientCall, Activity, EventTime_, Interface_UUID, ProcNum, Protocol, ProcessId, NetworkAddress, Endpoint, InterfaceString, MethodString, ProcessUser, ProcessFilePath, CallStack) : 0
+#define EventWriteRPCClientCall_AssumeEnabled(EventTime_, Interface_UUID, ProcNum, Protocol, ProcessId, NetworkAddress, Endpoint, InterfaceString, MethodString, ProcessUser, ProcessFilePath, CallStack) \
+ _mcgen_TEMPLATE_FOR_RPCClientCall(&JonMonProvider_Context, &RPCClientCall, NULL, EventTime_, Interface_UUID, ProcNum, Protocol, ProcessId, NetworkAddress, Endpoint, InterfaceString, MethodString, ProcessUser, ProcessFilePath, CallStack)
+#define EventWriteRPCClientCall_ForContext(pContext, Activity, EventTime_, Interface_UUID, ProcNum, Protocol, ProcessId, NetworkAddress, Endpoint, InterfaceString, MethodString, ProcessUser, ProcessFilePath, CallStack) \
+ MCGEN_EVENT_ENABLED_FORCONTEXT(pContext, RPCClientCall) \
+ ? _mcgen_TEMPLATE_FOR_RPCClientCall(&(pContext)->Context, &RPCClientCall, Activity, EventTime_, Interface_UUID, ProcNum, Protocol, ProcessId, NetworkAddress, Endpoint, InterfaceString, MethodString, ProcessUser, ProcessFilePath, CallStack) : 0
+#define EventWriteRPCClientCall_ForContextAssumeEnabled(pContext, EventTime_, Interface_UUID, ProcNum, Protocol, ProcessId, NetworkAddress, Endpoint, InterfaceString, MethodString, ProcessUser, ProcessFilePath, CallStack) \
+ _mcgen_TEMPLATE_FOR_RPCClientCall(&_mcgen_CheckContextType_JonMon(pContext)->Context, &RPCClientCall, NULL, EventTime_, Interface_UUID, ProcNum, Protocol, ProcessId, NetworkAddress, Endpoint, InterfaceString, MethodString, ProcessUser, ProcessFilePath, CallStack)
+
+// This macro is for use by MC-generated code and should not be used directly.
+#define _mcgen_TEMPLATE_FOR_RPCClientCall _mcgen_PASTE2(McTemplateK0mzqqqzzzzzzz_, MCGEN_EVENTWRITETRANSFER)
+
+//
+// Enablement check macro for event "RPCServerCall"
+//
+#define EventEnabledRPCServerCall() _mcgen_EVENT_BIT_SET(JonMonEnableBits, 0)
+#define EventEnabledRPCServerCall_ForContext(pContext) _mcgen_EVENT_BIT_SET(_mcgen_CheckContextType_JonMon(pContext)->EnableBits, 0)
+
+//
+// Event write macros for event "RPCServerCall"
+//
+#define EventWriteRPCServerCall(Activity, EventTime_, Interface_UUID, ProcNum, Protocol, ProcessId, NetworkAddress, Endpoint, InterfaceString, MethodString, ProcessUser, ProcessFilePath, CallStack) \
+ MCGEN_EVENT_ENABLED(RPCServerCall) \
+ ? _mcgen_TEMPLATE_FOR_RPCServerCall(&JonMonProvider_Context, &RPCServerCall, Activity, EventTime_, Interface_UUID, ProcNum, Protocol, ProcessId, NetworkAddress, Endpoint, InterfaceString, MethodString, ProcessUser, ProcessFilePath, CallStack) : 0
+#define EventWriteRPCServerCall_AssumeEnabled(EventTime_, Interface_UUID, ProcNum, Protocol, ProcessId, NetworkAddress, Endpoint, InterfaceString, MethodString, ProcessUser, ProcessFilePath, CallStack) \
+ _mcgen_TEMPLATE_FOR_RPCServerCall(&JonMonProvider_Context, &RPCServerCall, NULL, EventTime_, Interface_UUID, ProcNum, Protocol, ProcessId, NetworkAddress, Endpoint, InterfaceString, MethodString, ProcessUser, ProcessFilePath, CallStack)
+#define EventWriteRPCServerCall_ForContext(pContext, Activity, EventTime_, Interface_UUID, ProcNum, Protocol, ProcessId, NetworkAddress, Endpoint, InterfaceString, MethodString, ProcessUser, ProcessFilePath, CallStack) \
+ MCGEN_EVENT_ENABLED_FORCONTEXT(pContext, RPCServerCall) \
+ ? _mcgen_TEMPLATE_FOR_RPCServerCall(&(pContext)->Context, &RPCServerCall, Activity, EventTime_, Interface_UUID, ProcNum, Protocol, ProcessId, NetworkAddress, Endpoint, InterfaceString, MethodString, ProcessUser, ProcessFilePath, CallStack) : 0
+#define EventWriteRPCServerCall_ForContextAssumeEnabled(pContext, EventTime_, Interface_UUID, ProcNum, Protocol, ProcessId, NetworkAddress, Endpoint, InterfaceString, MethodString, ProcessUser, ProcessFilePath, CallStack) \
+ _mcgen_TEMPLATE_FOR_RPCServerCall(&_mcgen_CheckContextType_JonMon(pContext)->Context, &RPCServerCall, NULL, EventTime_, Interface_UUID, ProcNum, Protocol, ProcessId, NetworkAddress, Endpoint, InterfaceString, MethodString, ProcessUser, ProcessFilePath, CallStack)
+
+// This macro is for use by MC-generated code and should not be used directly.
+#define _mcgen_TEMPLATE_FOR_RPCServerCall _mcgen_PASTE2(McTemplateK0mzqqqzzzzzzz_, MCGEN_EVENTWRITETRANSFER)
+
+//
+// Enablement check macro for event "NetworkConnectionAccepted"
+//
+#define EventEnabledNetworkConnectionAccepted() _mcgen_EVENT_BIT_SET(JonMonEnableBits, 0)
+#define EventEnabledNetworkConnectionAccepted_ForContext(pContext) _mcgen_EVENT_BIT_SET(_mcgen_CheckContextType_JonMon(pContext)->EnableBits, 0)
+
+//
+// Event write macros for event "NetworkConnectionAccepted"
+//
+#define EventWriteNetworkConnectionAccepted(Activity, EventTime_, ProcessId, SrcIpAddressIpv4, DestIpAddressIpv4, SrcPort, DestPort, Initiated, ProcessUser, ProcessFilePath) \
+ MCGEN_EVENT_ENABLED(NetworkConnectionAccepted) \
+ ? _mcgen_TEMPLATE_FOR_NetworkConnectionAccepted(&JonMonProvider_Context, &NetworkConnectionAccepted, Activity, EventTime_, ProcessId, SrcIpAddressIpv4, DestIpAddressIpv4, SrcPort, DestPort, Initiated, ProcessUser, ProcessFilePath) : 0
+#define EventWriteNetworkConnectionAccepted_AssumeEnabled(EventTime_, ProcessId, SrcIpAddressIpv4, DestIpAddressIpv4, SrcPort, DestPort, Initiated, ProcessUser, ProcessFilePath) \
+ _mcgen_TEMPLATE_FOR_NetworkConnectionAccepted(&JonMonProvider_Context, &NetworkConnectionAccepted, NULL, EventTime_, ProcessId, SrcIpAddressIpv4, DestIpAddressIpv4, SrcPort, DestPort, Initiated, ProcessUser, ProcessFilePath)
+#define EventWriteNetworkConnectionAccepted_ForContext(pContext, Activity, EventTime_, ProcessId, SrcIpAddressIpv4, DestIpAddressIpv4, SrcPort, DestPort, Initiated, ProcessUser, ProcessFilePath) \
+ MCGEN_EVENT_ENABLED_FORCONTEXT(pContext, NetworkConnectionAccepted) \
+ ? _mcgen_TEMPLATE_FOR_NetworkConnectionAccepted(&(pContext)->Context, &NetworkConnectionAccepted, Activity, EventTime_, ProcessId, SrcIpAddressIpv4, DestIpAddressIpv4, SrcPort, DestPort, Initiated, ProcessUser, ProcessFilePath) : 0
+#define EventWriteNetworkConnectionAccepted_ForContextAssumeEnabled(pContext, EventTime_, ProcessId, SrcIpAddressIpv4, DestIpAddressIpv4, SrcPort, DestPort, Initiated, ProcessUser, ProcessFilePath) \
+ _mcgen_TEMPLATE_FOR_NetworkConnectionAccepted(&_mcgen_CheckContextType_JonMon(pContext)->Context, &NetworkConnectionAccepted, NULL, EventTime_, ProcessId, SrcIpAddressIpv4, DestIpAddressIpv4, SrcPort, DestPort, Initiated, ProcessUser, ProcessFilePath)
+
+// This macro is for use by MC-generated code and should not be used directly.
+#define _mcgen_TEMPLATE_FOR_NetworkConnectionAccepted _mcgen_PASTE2(McTemplateK0mqzzhhzzz_, MCGEN_EVENTWRITETRANSFER)
+
+//
+// Enablement check macro for event "RegistrySaveKey"
+//
+#define EventEnabledRegistrySaveKey() _mcgen_EVENT_BIT_SET(JonMonEnableBits, 0)
+#define EventEnabledRegistrySaveKey_ForContext(pContext) _mcgen_EVENT_BIT_SET(_mcgen_CheckContextType_JonMon(pContext)->EnableBits, 0)
+
+//
+// Event write macros for event "RegistrySaveKey"
+//
+#define EventWriteRegistrySaveKey(Activity, EventTime_, SourceProcessFilePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, RegistryKeyPath, SourceProcessUser, SourceProcessUserLogonId) \
+ MCGEN_EVENT_ENABLED(RegistrySaveKey) \
+ ? _mcgen_TEMPLATE_FOR_RegistrySaveKey(&JonMonProvider_Context, &RegistrySaveKey, Activity, EventTime_, SourceProcessFilePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, RegistryKeyPath, SourceProcessUser, SourceProcessUserLogonId) : 0
+#define EventWriteRegistrySaveKey_AssumeEnabled(EventTime_, SourceProcessFilePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, RegistryKeyPath, SourceProcessUser, SourceProcessUserLogonId) \
+ _mcgen_TEMPLATE_FOR_RegistrySaveKey(&JonMonProvider_Context, &RegistrySaveKey, NULL, EventTime_, SourceProcessFilePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, RegistryKeyPath, SourceProcessUser, SourceProcessUserLogonId)
+#define EventWriteRegistrySaveKey_ForContext(pContext, Activity, EventTime_, SourceProcessFilePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, RegistryKeyPath, SourceProcessUser, SourceProcessUserLogonId) \
+ MCGEN_EVENT_ENABLED_FORCONTEXT(pContext, RegistrySaveKey) \
+ ? _mcgen_TEMPLATE_FOR_RegistrySaveKey(&(pContext)->Context, &RegistrySaveKey, Activity, EventTime_, SourceProcessFilePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, RegistryKeyPath, SourceProcessUser, SourceProcessUserLogonId) : 0
+#define EventWriteRegistrySaveKey_ForContextAssumeEnabled(pContext, EventTime_, SourceProcessFilePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, RegistryKeyPath, SourceProcessUser, SourceProcessUserLogonId) \
+ _mcgen_TEMPLATE_FOR_RegistrySaveKey(&_mcgen_CheckContextType_JonMon(pContext)->Context, &RegistrySaveKey, NULL, EventTime_, SourceProcessFilePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, RegistryKeyPath, SourceProcessUser, SourceProcessUserLogonId)
+
+// This macro is for use by MC-generated code and should not be used directly.
+#define _mcgen_TEMPLATE_FOR_RegistrySaveKey _mcgen_PASTE2(McTemplateK0mzxxxzzq_, MCGEN_EVENTWRITETRANSFER)
+
+//
+// Enablement check macro for event "DotNetLoad"
+//
+#define EventEnabledDotNetLoad() _mcgen_EVENT_BIT_SET(JonMonEnableBits, 0)
+#define EventEnabledDotNetLoad_ForContext(pContext) _mcgen_EVENT_BIT_SET(_mcgen_CheckContextType_JonMon(pContext)->EnableBits, 0)
+
+//
+// Event write macros for event "DotNetLoad"
+//
+#define EventWriteDotNetLoad(Activity, EventTime_, ProcessId, AssemblyName, ProcessUser, ProcessFilePath, ClrInstanceID) \
+ MCGEN_EVENT_ENABLED(DotNetLoad) \
+ ? _mcgen_TEMPLATE_FOR_DotNetLoad(&JonMonProvider_Context, &DotNetLoad, Activity, EventTime_, ProcessId, AssemblyName, ProcessUser, ProcessFilePath, ClrInstanceID) : 0
+#define EventWriteDotNetLoad_AssumeEnabled(EventTime_, ProcessId, AssemblyName, ProcessUser, ProcessFilePath, ClrInstanceID) \
+ _mcgen_TEMPLATE_FOR_DotNetLoad(&JonMonProvider_Context, &DotNetLoad, NULL, EventTime_, ProcessId, AssemblyName, ProcessUser, ProcessFilePath, ClrInstanceID)
+#define EventWriteDotNetLoad_ForContext(pContext, Activity, EventTime_, ProcessId, AssemblyName, ProcessUser, ProcessFilePath, ClrInstanceID) \
+ MCGEN_EVENT_ENABLED_FORCONTEXT(pContext, DotNetLoad) \
+ ? _mcgen_TEMPLATE_FOR_DotNetLoad(&(pContext)->Context, &DotNetLoad, Activity, EventTime_, ProcessId, AssemblyName, ProcessUser, ProcessFilePath, ClrInstanceID) : 0
+#define EventWriteDotNetLoad_ForContextAssumeEnabled(pContext, EventTime_, ProcessId, AssemblyName, ProcessUser, ProcessFilePath, ClrInstanceID) \
+ _mcgen_TEMPLATE_FOR_DotNetLoad(&_mcgen_CheckContextType_JonMon(pContext)->Context, &DotNetLoad, NULL, EventTime_, ProcessId, AssemblyName, ProcessUser, ProcessFilePath, ClrInstanceID)
+
+// This macro is for use by MC-generated code and should not be used directly.
+#define _mcgen_TEMPLATE_FOR_DotNetLoad _mcgen_PASTE2(McTemplateK0mqzzzh_, MCGEN_EVENTWRITETRANSFER)
+
+//
+// Enablement check macro for event "AMSI"
+//
+#define EventEnabledAMSI() _mcgen_EVENT_BIT_SET(JonMonEnableBits, 0)
+#define EventEnabledAMSI_ForContext(pContext) _mcgen_EVENT_BIT_SET(_mcgen_CheckContextType_JonMon(pContext)->EnableBits, 0)
+
+//
+// Event write macros for event "AMSI"
+//
+#define EventWriteAMSI(Activity, EventTime_, ProcessId, AppName, ScanResults, ContentSize) \
+ MCGEN_EVENT_ENABLED(AMSI) \
+ ? _mcgen_TEMPLATE_FOR_AMSI(&JonMonProvider_Context, &AMSI, Activity, EventTime_, ProcessId, AppName, ScanResults, ContentSize) : 0
+#define EventWriteAMSI_AssumeEnabled(EventTime_, ProcessId, AppName, ScanResults, ContentSize) \
+ _mcgen_TEMPLATE_FOR_AMSI(&JonMonProvider_Context, &AMSI, NULL, EventTime_, ProcessId, AppName, ScanResults, ContentSize)
+#define EventWriteAMSI_ForContext(pContext, Activity, EventTime_, ProcessId, AppName, ScanResults, ContentSize) \
+ MCGEN_EVENT_ENABLED_FORCONTEXT(pContext, AMSI) \
+ ? _mcgen_TEMPLATE_FOR_AMSI(&(pContext)->Context, &AMSI, Activity, EventTime_, ProcessId, AppName, ScanResults, ContentSize) : 0
+#define EventWriteAMSI_ForContextAssumeEnabled(pContext, EventTime_, ProcessId, AppName, ScanResults, ContentSize) \
+ _mcgen_TEMPLATE_FOR_AMSI(&_mcgen_CheckContextType_JonMon(pContext)->Context, &AMSI, NULL, EventTime_, ProcessId, AppName, ScanResults, ContentSize)
+
+// This macro is for use by MC-generated code and should not be used directly.
+#define _mcgen_TEMPLATE_FOR_AMSI _mcgen_PASTE2(McTemplateK0mqzqq_, MCGEN_EVENTWRITETRANSFER)
+
+//
+// Enablement check macro for event "ImpersonationAction"
+//
+#define EventEnabledImpersonationAction() _mcgen_EVENT_BIT_SET(JonMonEnableBits, 0)
+#define EventEnabledImpersonationAction_ForContext(pContext) _mcgen_EVENT_BIT_SET(_mcgen_CheckContextType_JonMon(pContext)->EnableBits, 0)
+
+//
+// Event write macros for event "ImpersonationAction"
+//
+#define EventWriteImpersonationAction(Activity, EventTime_, ProcessName, ProcessId, ProcessStartKey, ProcessIntegrityLevel, ProcessUserName, ThreadId, ImpersonationLevel, ImpersonationLevelName, ImpersonatedUserName, ThreadIntegrityLevel, OperationType) \
+ MCGEN_EVENT_ENABLED(ImpersonationAction) \
+ ? _mcgen_TEMPLATE_FOR_ImpersonationAction(&JonMonProvider_Context, &ImpersonationAction, Activity, EventTime_, ProcessName, ProcessId, ProcessStartKey, ProcessIntegrityLevel, ProcessUserName, ThreadId, ImpersonationLevel, ImpersonationLevelName, ImpersonatedUserName, ThreadIntegrityLevel, OperationType) : 0
+#define EventWriteImpersonationAction_AssumeEnabled(EventTime_, ProcessName, ProcessId, ProcessStartKey, ProcessIntegrityLevel, ProcessUserName, ThreadId, ImpersonationLevel, ImpersonationLevelName, ImpersonatedUserName, ThreadIntegrityLevel, OperationType) \
+ _mcgen_TEMPLATE_FOR_ImpersonationAction(&JonMonProvider_Context, &ImpersonationAction, NULL, EventTime_, ProcessName, ProcessId, ProcessStartKey, ProcessIntegrityLevel, ProcessUserName, ThreadId, ImpersonationLevel, ImpersonationLevelName, ImpersonatedUserName, ThreadIntegrityLevel, OperationType)
+#define EventWriteImpersonationAction_ForContext(pContext, Activity, EventTime_, ProcessName, ProcessId, ProcessStartKey, ProcessIntegrityLevel, ProcessUserName, ThreadId, ImpersonationLevel, ImpersonationLevelName, ImpersonatedUserName, ThreadIntegrityLevel, OperationType) \
+ MCGEN_EVENT_ENABLED_FORCONTEXT(pContext, ImpersonationAction) \
+ ? _mcgen_TEMPLATE_FOR_ImpersonationAction(&(pContext)->Context, &ImpersonationAction, Activity, EventTime_, ProcessName, ProcessId, ProcessStartKey, ProcessIntegrityLevel, ProcessUserName, ThreadId, ImpersonationLevel, ImpersonationLevelName, ImpersonatedUserName, ThreadIntegrityLevel, OperationType) : 0
+#define EventWriteImpersonationAction_ForContextAssumeEnabled(pContext, EventTime_, ProcessName, ProcessId, ProcessStartKey, ProcessIntegrityLevel, ProcessUserName, ThreadId, ImpersonationLevel, ImpersonationLevelName, ImpersonatedUserName, ThreadIntegrityLevel, OperationType) \
+ _mcgen_TEMPLATE_FOR_ImpersonationAction(&_mcgen_CheckContextType_JonMon(pContext)->Context, &ImpersonationAction, NULL, EventTime_, ProcessName, ProcessId, ProcessStartKey, ProcessIntegrityLevel, ProcessUserName, ThreadId, ImpersonationLevel, ImpersonationLevelName, ImpersonatedUserName, ThreadIntegrityLevel, OperationType)
+
+// This macro is for use by MC-generated code and should not be used directly.
+#define _mcgen_TEMPLATE_FOR_ImpersonationAction _mcgen_PASTE2(McTemplateK0mzxxzzxdzzzz_, MCGEN_EVENTWRITETRANSFER)
+
+//
+// Enablement check macro for event "RemoteThreadCreation"
+//
+#define EventEnabledRemoteThreadCreation() _mcgen_EVENT_BIT_SET(JonMonEnableBits, 0)
+#define EventEnabledRemoteThreadCreation_ForContext(pContext) _mcgen_EVENT_BIT_SET(_mcgen_CheckContextType_JonMon(pContext)->EnableBits, 0)
+
+//
+// Event write macros for event "RemoteThreadCreation"
+//
+#define EventWriteRemoteThreadCreation(Activity, EventTime_, SourceImagePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, SourceUserName, SourceUserLogonId, SourceProcessIntegrityLevel, TargetImagePath, TargetProcessId, TargetProcessStartKey, TargetThreadId, TargetUserName, TargetUserLogonId, TargetProcessIntegrityLevel) \
+ MCGEN_EVENT_ENABLED(RemoteThreadCreation) \
+ ? _mcgen_TEMPLATE_FOR_RemoteThreadCreation(&JonMonProvider_Context, &RemoteThreadCreation, Activity, EventTime_, SourceImagePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, SourceUserName, SourceUserLogonId, SourceProcessIntegrityLevel, TargetImagePath, TargetProcessId, TargetProcessStartKey, TargetThreadId, TargetUserName, TargetUserLogonId, TargetProcessIntegrityLevel) : 0
+#define EventWriteRemoteThreadCreation_AssumeEnabled(EventTime_, SourceImagePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, SourceUserName, SourceUserLogonId, SourceProcessIntegrityLevel, TargetImagePath, TargetProcessId, TargetProcessStartKey, TargetThreadId, TargetUserName, TargetUserLogonId, TargetProcessIntegrityLevel) \
+ _mcgen_TEMPLATE_FOR_RemoteThreadCreation(&JonMonProvider_Context, &RemoteThreadCreation, NULL, EventTime_, SourceImagePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, SourceUserName, SourceUserLogonId, SourceProcessIntegrityLevel, TargetImagePath, TargetProcessId, TargetProcessStartKey, TargetThreadId, TargetUserName, TargetUserLogonId, TargetProcessIntegrityLevel)
+#define EventWriteRemoteThreadCreation_ForContext(pContext, Activity, EventTime_, SourceImagePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, SourceUserName, SourceUserLogonId, SourceProcessIntegrityLevel, TargetImagePath, TargetProcessId, TargetProcessStartKey, TargetThreadId, TargetUserName, TargetUserLogonId, TargetProcessIntegrityLevel) \
+ MCGEN_EVENT_ENABLED_FORCONTEXT(pContext, RemoteThreadCreation) \
+ ? _mcgen_TEMPLATE_FOR_RemoteThreadCreation(&(pContext)->Context, &RemoteThreadCreation, Activity, EventTime_, SourceImagePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, SourceUserName, SourceUserLogonId, SourceProcessIntegrityLevel, TargetImagePath, TargetProcessId, TargetProcessStartKey, TargetThreadId, TargetUserName, TargetUserLogonId, TargetProcessIntegrityLevel) : 0
+#define EventWriteRemoteThreadCreation_ForContextAssumeEnabled(pContext, EventTime_, SourceImagePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, SourceUserName, SourceUserLogonId, SourceProcessIntegrityLevel, TargetImagePath, TargetProcessId, TargetProcessStartKey, TargetThreadId, TargetUserName, TargetUserLogonId, TargetProcessIntegrityLevel) \
+ _mcgen_TEMPLATE_FOR_RemoteThreadCreation(&_mcgen_CheckContextType_JonMon(pContext)->Context, &RemoteThreadCreation, NULL, EventTime_, SourceImagePath, SourceProcessId, SourceThreadId, SourceProcessStartKey, SourceUserName, SourceUserLogonId, SourceProcessIntegrityLevel, TargetImagePath, TargetProcessId, TargetProcessStartKey, TargetThreadId, TargetUserName, TargetUserLogonId, TargetProcessIntegrityLevel)
+
+// This macro is for use by MC-generated code and should not be used directly.
+#define _mcgen_TEMPLATE_FOR_RemoteThreadCreation _mcgen_PASTE2(McTemplateK0mzxxxzqzzxxxzqz_, MCGEN_EVENTWRITETRANSFER)
+
+//
+// Enablement check macro for event "SchedTaskCreation"
+//
+#define EventEnabledSchedTaskCreation() _mcgen_EVENT_BIT_SET(JonMonEnableBits, 0)
+#define EventEnabledSchedTaskCreation_ForContext(pContext) _mcgen_EVENT_BIT_SET(_mcgen_CheckContextType_JonMon(pContext)->EnableBits, 0)
+
+//
+// Event write macros for event "SchedTaskCreation"
+//
+#define EventWriteSchedTaskCreation(Activity, EventTime_, TaskName, UserName, SourceProcessId) \
+ MCGEN_EVENT_ENABLED(SchedTaskCreation) \
+ ? _mcgen_TEMPLATE_FOR_SchedTaskCreation(&JonMonProvider_Context, &SchedTaskCreation, Activity, EventTime_, TaskName, UserName, SourceProcessId) : 0
+#define EventWriteSchedTaskCreation_AssumeEnabled(EventTime_, TaskName, UserName, SourceProcessId) \
+ _mcgen_TEMPLATE_FOR_SchedTaskCreation(&JonMonProvider_Context, &SchedTaskCreation, NULL, EventTime_, TaskName, UserName, SourceProcessId)
+#define EventWriteSchedTaskCreation_ForContext(pContext, Activity, EventTime_, TaskName, UserName, SourceProcessId) \
+ MCGEN_EVENT_ENABLED_FORCONTEXT(pContext, SchedTaskCreation) \
+ ? _mcgen_TEMPLATE_FOR_SchedTaskCreation(&(pContext)->Context, &SchedTaskCreation, Activity, EventTime_, TaskName, UserName, SourceProcessId) : 0
+#define EventWriteSchedTaskCreation_ForContextAssumeEnabled(pContext, EventTime_, TaskName, UserName, SourceProcessId) \
+ _mcgen_TEMPLATE_FOR_SchedTaskCreation(&_mcgen_CheckContextType_JonMon(pContext)->Context, &SchedTaskCreation, NULL, EventTime_, TaskName, UserName, SourceProcessId)
+
+// This macro is for use by MC-generated code and should not be used directly.
+#define _mcgen_TEMPLATE_FOR_SchedTaskCreation _mcgen_PASTE2(McTemplateK0mzzq_, MCGEN_EVENTWRITETRANSFER)
+
+//
+// Enablement check macro for event "SchedTaskStarted"
+//
+#define EventEnabledSchedTaskStarted() _mcgen_EVENT_BIT_SET(JonMonEnableBits, 0)
+#define EventEnabledSchedTaskStarted_ForContext(pContext) _mcgen_EVENT_BIT_SET(_mcgen_CheckContextType_JonMon(pContext)->EnableBits, 0)
+
+//
+// Event write macros for event "SchedTaskStarted"
+//
+#define EventWriteSchedTaskStarted(Activity, EventTime_, TaskName, ImagePath, SourceProcessId) \
+ MCGEN_EVENT_ENABLED(SchedTaskStarted) \
+ ? _mcgen_TEMPLATE_FOR_SchedTaskStarted(&JonMonProvider_Context, &SchedTaskStarted, Activity, EventTime_, TaskName, ImagePath, SourceProcessId) : 0
+#define EventWriteSchedTaskStarted_AssumeEnabled(EventTime_, TaskName, ImagePath, SourceProcessId) \
+ _mcgen_TEMPLATE_FOR_SchedTaskStarted(&JonMonProvider_Context, &SchedTaskStarted, NULL, EventTime_, TaskName, ImagePath, SourceProcessId)
+#define EventWriteSchedTaskStarted_ForContext(pContext, Activity, EventTime_, TaskName, ImagePath, SourceProcessId) \
+ MCGEN_EVENT_ENABLED_FORCONTEXT(pContext, SchedTaskStarted) \
+ ? _mcgen_TEMPLATE_FOR_SchedTaskStarted(&(pContext)->Context, &SchedTaskStarted, Activity, EventTime_, TaskName, ImagePath, SourceProcessId) : 0
+#define EventWriteSchedTaskStarted_ForContextAssumeEnabled(pContext, EventTime_, TaskName, ImagePath, SourceProcessId) \
+ _mcgen_TEMPLATE_FOR_SchedTaskStarted(&_mcgen_CheckContextType_JonMon(pContext)->Context, &SchedTaskStarted, NULL, EventTime_, TaskName, ImagePath, SourceProcessId)
+
+// This macro is for use by MC-generated code and should not be used directly.
+#define _mcgen_TEMPLATE_FOR_SchedTaskStarted _mcgen_PASTE2(McTemplateK0mzzq_, MCGEN_EVENTWRITETRANSFER)
+
+//
+// Enablement check macro for event "FileCreate"
+//
+#define EventEnabledFileCreate() _mcgen_EVENT_BIT_SET(JonMonEnableBits, 0)
+#define EventEnabledFileCreate_ForContext(pContext) _mcgen_EVENT_BIT_SET(_mcgen_CheckContextType_JonMon(pContext)->EnableBits, 0)
+
+//
+// Event write macros for event "FileCreate"
+//
+#define EventWriteFileCreate(Activity, EventTime_, SourceImagePath, SourceProcessId, SourceProcessStartKey, SourceThreadId, SourceUserName, SourceUserLogonId, SourceProcessIntegrityLevel, TargetFile) \
+ MCGEN_EVENT_ENABLED(FileCreate) \
+ ? _mcgen_TEMPLATE_FOR_FileCreate(&JonMonProvider_Context, &FileCreate, Activity, EventTime_, SourceImagePath, SourceProcessId, SourceProcessStartKey, SourceThreadId, SourceUserName, SourceUserLogonId, SourceProcessIntegrityLevel, TargetFile) : 0
+#define EventWriteFileCreate_AssumeEnabled(EventTime_, SourceImagePath, SourceProcessId, SourceProcessStartKey, SourceThreadId, SourceUserName, SourceUserLogonId, SourceProcessIntegrityLevel, TargetFile) \
+ _mcgen_TEMPLATE_FOR_FileCreate(&JonMonProvider_Context, &FileCreate, NULL, EventTime_, SourceImagePath, SourceProcessId, SourceProcessStartKey, SourceThreadId, SourceUserName, SourceUserLogonId, SourceProcessIntegrityLevel, TargetFile)
+#define EventWriteFileCreate_ForContext(pContext, Activity, EventTime_, SourceImagePath, SourceProcessId, SourceProcessStartKey, SourceThreadId, SourceUserName, SourceUserLogonId, SourceProcessIntegrityLevel, TargetFile) \
+ MCGEN_EVENT_ENABLED_FORCONTEXT(pContext, FileCreate) \
+ ? _mcgen_TEMPLATE_FOR_FileCreate(&(pContext)->Context, &FileCreate, Activity, EventTime_, SourceImagePath, SourceProcessId, SourceProcessStartKey, SourceThreadId, SourceUserName, SourceUserLogonId, SourceProcessIntegrityLevel, TargetFile) : 0
+#define EventWriteFileCreate_ForContextAssumeEnabled(pContext, EventTime_, SourceImagePath, SourceProcessId, SourceProcessStartKey, SourceThreadId, SourceUserName, SourceUserLogonId, SourceProcessIntegrityLevel, TargetFile) \
+ _mcgen_TEMPLATE_FOR_FileCreate(&_mcgen_CheckContextType_JonMon(pContext)->Context, &FileCreate, NULL, EventTime_, SourceImagePath, SourceProcessId, SourceProcessStartKey, SourceThreadId, SourceUserName, SourceUserLogonId, SourceProcessIntegrityLevel, TargetFile)
+
+// This macro is for use by MC-generated code and should not be used directly.
+#define _mcgen_TEMPLATE_FOR_FileCreate _mcgen_PASTE2(McTemplateK0mzxxxzqzz_, MCGEN_EVENTWRITETRANSFER)
+
+//
+// Enablement check macro for event "FileDelete"
+//
+#define EventEnabledFileDelete() _mcgen_EVENT_BIT_SET(JonMonEnableBits, 0)
+#define EventEnabledFileDelete_ForContext(pContext) _mcgen_EVENT_BIT_SET(_mcgen_CheckContextType_JonMon(pContext)->EnableBits, 0)
+
+//
+// Event write macros for event "FileDelete"
+//
+#define EventWriteFileDelete(Activity, EventTime_, SourceImagePath, SourceProcessId, SourceProcessStartKey, SourceThreadId, SourceUserName, SourceUserLogonId, SourceProcessIntegrityLevel, TargetFile) \
+ MCGEN_EVENT_ENABLED(FileDelete) \
+ ? _mcgen_TEMPLATE_FOR_FileDelete(&JonMonProvider_Context, &FileDelete, Activity, EventTime_, SourceImagePath, SourceProcessId, SourceProcessStartKey, SourceThreadId, SourceUserName, SourceUserLogonId, SourceProcessIntegrityLevel, TargetFile) : 0
+#define EventWriteFileDelete_AssumeEnabled(EventTime_, SourceImagePath, SourceProcessId, SourceProcessStartKey, SourceThreadId, SourceUserName, SourceUserLogonId, SourceProcessIntegrityLevel, TargetFile) \
+ _mcgen_TEMPLATE_FOR_FileDelete(&JonMonProvider_Context, &FileDelete, NULL, EventTime_, SourceImagePath, SourceProcessId, SourceProcessStartKey, SourceThreadId, SourceUserName, SourceUserLogonId, SourceProcessIntegrityLevel, TargetFile)
+#define EventWriteFileDelete_ForContext(pContext, Activity, EventTime_, SourceImagePath, SourceProcessId, SourceProcessStartKey, SourceThreadId, SourceUserName, SourceUserLogonId, SourceProcessIntegrityLevel, TargetFile) \
+ MCGEN_EVENT_ENABLED_FORCONTEXT(pContext, FileDelete) \
+ ? _mcgen_TEMPLATE_FOR_FileDelete(&(pContext)->Context, &FileDelete, Activity, EventTime_, SourceImagePath, SourceProcessId, SourceProcessStartKey, SourceThreadId, SourceUserName, SourceUserLogonId, SourceProcessIntegrityLevel, TargetFile) : 0
+#define EventWriteFileDelete_ForContextAssumeEnabled(pContext, EventTime_, SourceImagePath, SourceProcessId, SourceProcessStartKey, SourceThreadId, SourceUserName, SourceUserLogonId, SourceProcessIntegrityLevel, TargetFile) \
+ _mcgen_TEMPLATE_FOR_FileDelete(&_mcgen_CheckContextType_JonMon(pContext)->Context, &FileDelete, NULL, EventTime_, SourceImagePath, SourceProcessId, SourceProcessStartKey, SourceThreadId, SourceUserName, SourceUserLogonId, SourceProcessIntegrityLevel, TargetFile)
+
+// This macro is for use by MC-generated code and should not be used directly.
+#define _mcgen_TEMPLATE_FOR_FileDelete _mcgen_PASTE2(McTemplateK0mzxxxzqzz_, MCGEN_EVENTWRITETRANSFER)
+
+//
+// Enablement check macro for event "NamedPipeCreate"
+//
+#define EventEnabledNamedPipeCreate() _mcgen_EVENT_BIT_SET(JonMonEnableBits, 0)
+#define EventEnabledNamedPipeCreate_ForContext(pContext) _mcgen_EVENT_BIT_SET(_mcgen_CheckContextType_JonMon(pContext)->EnableBits, 0)
+
+//
+// Event write macros for event "NamedPipeCreate"
+//
+#define EventWriteNamedPipeCreate(Activity, EventTime_, SourceImagePath, SourceProcessId, SourceProcessStartKey, SourceThreadId, SourceUserName, SourceUserLogonId, SourceProcessIntegrityLevel, PipeName, RemoteCreation, PipeCreationAccess) \
+ MCGEN_EVENT_ENABLED(NamedPipeCreate) \
+ ? _mcgen_TEMPLATE_FOR_NamedPipeCreate(&JonMonProvider_Context, &NamedPipeCreate, Activity, EventTime_, SourceImagePath, SourceProcessId, SourceProcessStartKey, SourceThreadId, SourceUserName, SourceUserLogonId, SourceProcessIntegrityLevel, PipeName, RemoteCreation, PipeCreationAccess) : 0
+#define EventWriteNamedPipeCreate_AssumeEnabled(EventTime_, SourceImagePath, SourceProcessId, SourceProcessStartKey, SourceThreadId, SourceUserName, SourceUserLogonId, SourceProcessIntegrityLevel, PipeName, RemoteCreation, PipeCreationAccess) \
+ _mcgen_TEMPLATE_FOR_NamedPipeCreate(&JonMonProvider_Context, &NamedPipeCreate, NULL, EventTime_, SourceImagePath, SourceProcessId, SourceProcessStartKey, SourceThreadId, SourceUserName, SourceUserLogonId, SourceProcessIntegrityLevel, PipeName, RemoteCreation, PipeCreationAccess)
+#define EventWriteNamedPipeCreate_ForContext(pContext, Activity, EventTime_, SourceImagePath, SourceProcessId, SourceProcessStartKey, SourceThreadId, SourceUserName, SourceUserLogonId, SourceProcessIntegrityLevel, PipeName, RemoteCreation, PipeCreationAccess) \
+ MCGEN_EVENT_ENABLED_FORCONTEXT(pContext, NamedPipeCreate) \
+ ? _mcgen_TEMPLATE_FOR_NamedPipeCreate(&(pContext)->Context, &NamedPipeCreate, Activity, EventTime_, SourceImagePath, SourceProcessId, SourceProcessStartKey, SourceThreadId, SourceUserName, SourceUserLogonId, SourceProcessIntegrityLevel, PipeName, RemoteCreation, PipeCreationAccess) : 0
+#define EventWriteNamedPipeCreate_ForContextAssumeEnabled(pContext, EventTime_, SourceImagePath, SourceProcessId, SourceProcessStartKey, SourceThreadId, SourceUserName, SourceUserLogonId, SourceProcessIntegrityLevel, PipeName, RemoteCreation, PipeCreationAccess) \
+ _mcgen_TEMPLATE_FOR_NamedPipeCreate(&_mcgen_CheckContextType_JonMon(pContext)->Context, &NamedPipeCreate, NULL, EventTime_, SourceImagePath, SourceProcessId, SourceProcessStartKey, SourceThreadId, SourceUserName, SourceUserLogonId, SourceProcessIntegrityLevel, PipeName, RemoteCreation, PipeCreationAccess)
+
+// This macro is for use by MC-generated code and should not be used directly.
+#define _mcgen_TEMPLATE_FOR_NamedPipeCreate _mcgen_PASTE2(McTemplateK0mzxxxzqzztd_, MCGEN_EVENTWRITETRANSFER)
+
+//
+// Enablement check macro for event "NamedPipeOpen"
+//
+#define EventEnabledNamedPipeOpen() _mcgen_EVENT_BIT_SET(JonMonEnableBits, 0)
+#define EventEnabledNamedPipeOpen_ForContext(pContext) _mcgen_EVENT_BIT_SET(_mcgen_CheckContextType_JonMon(pContext)->EnableBits, 0)
+
+//
+// Event write macros for event "NamedPipeOpen"
+//
+#define EventWriteNamedPipeOpen(Activity, EventTime_, SourceImagePath, SourceProcessId, SourceProcessStartKey, SourceThreadId, SourceUserName, SourceUserLogonId, SourceProcessIntegrityLevel, PipeName, PipeRequestedAccess, PipeGrantedAccess) \
+ MCGEN_EVENT_ENABLED(NamedPipeOpen) \
+ ? _mcgen_TEMPLATE_FOR_NamedPipeOpen(&JonMonProvider_Context, &NamedPipeOpen, Activity, EventTime_, SourceImagePath, SourceProcessId, SourceProcessStartKey, SourceThreadId, SourceUserName, SourceUserLogonId, SourceProcessIntegrityLevel, PipeName, PipeRequestedAccess, PipeGrantedAccess) : 0
+#define EventWriteNamedPipeOpen_AssumeEnabled(EventTime_, SourceImagePath, SourceProcessId, SourceProcessStartKey, SourceThreadId, SourceUserName, SourceUserLogonId, SourceProcessIntegrityLevel, PipeName, PipeRequestedAccess, PipeGrantedAccess) \
+ _mcgen_TEMPLATE_FOR_NamedPipeOpen(&JonMonProvider_Context, &NamedPipeOpen, NULL, EventTime_, SourceImagePath, SourceProcessId, SourceProcessStartKey, SourceThreadId, SourceUserName, SourceUserLogonId, SourceProcessIntegrityLevel, PipeName, PipeRequestedAccess, PipeGrantedAccess)
+#define EventWriteNamedPipeOpen_ForContext(pContext, Activity, EventTime_, SourceImagePath, SourceProcessId, SourceProcessStartKey, SourceThreadId, SourceUserName, SourceUserLogonId, SourceProcessIntegrityLevel, PipeName, PipeRequestedAccess, PipeGrantedAccess) \
+ MCGEN_EVENT_ENABLED_FORCONTEXT(pContext, NamedPipeOpen) \
+ ? _mcgen_TEMPLATE_FOR_NamedPipeOpen(&(pContext)->Context, &NamedPipeOpen, Activity, EventTime_, SourceImagePath, SourceProcessId, SourceProcessStartKey, SourceThreadId, SourceUserName, SourceUserLogonId, SourceProcessIntegrityLevel, PipeName, PipeRequestedAccess, PipeGrantedAccess) : 0
+#define EventWriteNamedPipeOpen_ForContextAssumeEnabled(pContext, EventTime_, SourceImagePath, SourceProcessId, SourceProcessStartKey, SourceThreadId, SourceUserName, SourceUserLogonId, SourceProcessIntegrityLevel, PipeName, PipeRequestedAccess, PipeGrantedAccess) \
+ _mcgen_TEMPLATE_FOR_NamedPipeOpen(&_mcgen_CheckContextType_JonMon(pContext)->Context, &NamedPipeOpen, NULL, EventTime_, SourceImagePath, SourceProcessId, SourceProcessStartKey, SourceThreadId, SourceUserName, SourceUserLogonId, SourceProcessIntegrityLevel, PipeName, PipeRequestedAccess, PipeGrantedAccess)
+
+// This macro is for use by MC-generated code and should not be used directly.
+#define _mcgen_TEMPLATE_FOR_NamedPipeOpen _mcgen_PASTE2(McTemplateK0mzxxxzqzzdd_, MCGEN_EVENTWRITETRANSFER)
+
+//
+// Enablement check macro for event "WMIFilterToConsumerBinding"
+//
+#define EventEnabledWMIFilterToConsumerBinding() _mcgen_EVENT_BIT_SET(JonMonEnableBits, 0)
+#define EventEnabledWMIFilterToConsumerBinding_ForContext(pContext) _mcgen_EVENT_BIT_SET(_mcgen_CheckContextType_JonMon(pContext)->EnableBits, 0)
+
+//
+// Event write macros for event "WMIFilterToConsumerBinding"
+//
+#define EventWriteWMIFilterToConsumerBinding(Activity, EventTime_, Namespace, ESS, Consumer, PossibleCause) \
+ MCGEN_EVENT_ENABLED(WMIFilterToConsumerBinding) \
+ ? _mcgen_TEMPLATE_FOR_WMIFilterToConsumerBinding(&JonMonProvider_Context, &WMIFilterToConsumerBinding, Activity, EventTime_, Namespace, ESS, Consumer, PossibleCause) : 0
+#define EventWriteWMIFilterToConsumerBinding_AssumeEnabled(EventTime_, Namespace, ESS, Consumer, PossibleCause) \
+ _mcgen_TEMPLATE_FOR_WMIFilterToConsumerBinding(&JonMonProvider_Context, &WMIFilterToConsumerBinding, NULL, EventTime_, Namespace, ESS, Consumer, PossibleCause)
+#define EventWriteWMIFilterToConsumerBinding_ForContext(pContext, Activity, EventTime_, Namespace, ESS, Consumer, PossibleCause) \
+ MCGEN_EVENT_ENABLED_FORCONTEXT(pContext, WMIFilterToConsumerBinding) \
+ ? _mcgen_TEMPLATE_FOR_WMIFilterToConsumerBinding(&(pContext)->Context, &WMIFilterToConsumerBinding, Activity, EventTime_, Namespace, ESS, Consumer, PossibleCause) : 0
+#define EventWriteWMIFilterToConsumerBinding_ForContextAssumeEnabled(pContext, EventTime_, Namespace, ESS, Consumer, PossibleCause) \
+ _mcgen_TEMPLATE_FOR_WMIFilterToConsumerBinding(&_mcgen_CheckContextType_JonMon(pContext)->Context, &WMIFilterToConsumerBinding, NULL, EventTime_, Namespace, ESS, Consumer, PossibleCause)
+
+// This macro is for use by MC-generated code and should not be used directly.
+#define _mcgen_TEMPLATE_FOR_WMIFilterToConsumerBinding _mcgen_PASTE2(McTemplateK0mzzzz_, MCGEN_EVENTWRITETRANSFER)
+
+//
+// Enablement check macro for event "TIQueueUserAPCEvent"
+//
+#define EventEnabledTIQueueUserAPCEvent() _mcgen_EVENT_BIT_SET(JonMonEnableBits, 0)
+#define EventEnabledTIQueueUserAPCEvent_ForContext(pContext) _mcgen_EVENT_BIT_SET(_mcgen_CheckContextType_JonMon(pContext)->EnableBits, 0)
+
+//
+// Event write macros for event "TIQueueUserAPCEvent"
+//
+#define EventWriteTIQueueUserAPCEvent(Activity, EventTime_, SourceThreadId, SourceProcessId, TargetProcessId, TargetThreadId, SourceProcessStartKey, TargetProcessStartKey, OriginalProcessId, APCRoutine, APCArgument, SourceProcessFilePath, TargetProcessFilePath, CallStack) \
+ MCGEN_EVENT_ENABLED(TIQueueUserAPCEvent) \
+ ? _mcgen_TEMPLATE_FOR_TIQueueUserAPCEvent(&JonMonProvider_Context, &TIQueueUserAPCEvent, Activity, EventTime_, SourceThreadId, SourceProcessId, TargetProcessId, TargetThreadId, SourceProcessStartKey, TargetProcessStartKey, OriginalProcessId, APCRoutine, APCArgument, SourceProcessFilePath, TargetProcessFilePath, CallStack) : 0
+#define EventWriteTIQueueUserAPCEvent_AssumeEnabled(EventTime_, SourceThreadId, SourceProcessId, TargetProcessId, TargetThreadId, SourceProcessStartKey, TargetProcessStartKey, OriginalProcessId, APCRoutine, APCArgument, SourceProcessFilePath, TargetProcessFilePath, CallStack) \
+ _mcgen_TEMPLATE_FOR_TIQueueUserAPCEvent(&JonMonProvider_Context, &TIQueueUserAPCEvent, NULL, EventTime_, SourceThreadId, SourceProcessId, TargetProcessId, TargetThreadId, SourceProcessStartKey, TargetProcessStartKey, OriginalProcessId, APCRoutine, APCArgument, SourceProcessFilePath, TargetProcessFilePath, CallStack)
+#define EventWriteTIQueueUserAPCEvent_ForContext(pContext, Activity, EventTime_, SourceThreadId, SourceProcessId, TargetProcessId, TargetThreadId, SourceProcessStartKey, TargetProcessStartKey, OriginalProcessId, APCRoutine, APCArgument, SourceProcessFilePath, TargetProcessFilePath, CallStack) \
+ MCGEN_EVENT_ENABLED_FORCONTEXT(pContext, TIQueueUserAPCEvent) \
+ ? _mcgen_TEMPLATE_FOR_TIQueueUserAPCEvent(&(pContext)->Context, &TIQueueUserAPCEvent, Activity, EventTime_, SourceThreadId, SourceProcessId, TargetProcessId, TargetThreadId, SourceProcessStartKey, TargetProcessStartKey, OriginalProcessId, APCRoutine, APCArgument, SourceProcessFilePath, TargetProcessFilePath, CallStack) : 0
+#define EventWriteTIQueueUserAPCEvent_ForContextAssumeEnabled(pContext, EventTime_, SourceThreadId, SourceProcessId, TargetProcessId, TargetThreadId, SourceProcessStartKey, TargetProcessStartKey, OriginalProcessId, APCRoutine, APCArgument, SourceProcessFilePath, TargetProcessFilePath, CallStack) \
+ _mcgen_TEMPLATE_FOR_TIQueueUserAPCEvent(&_mcgen_CheckContextType_JonMon(pContext)->Context, &TIQueueUserAPCEvent, NULL, EventTime_, SourceThreadId, SourceProcessId, TargetProcessId, TargetThreadId, SourceProcessStartKey, TargetProcessStartKey, OriginalProcessId, APCRoutine, APCArgument, SourceProcessFilePath, TargetProcessFilePath, CallStack)
+
+// This macro is for use by MC-generated code and should not be used directly.
+#define _mcgen_TEMPLATE_FOR_TIQueueUserAPCEvent _mcgen_PASTE2(McTemplateK0mqqqqxxqppzzz_, MCGEN_EVENTWRITETRANSFER)
+
+//
+// Enablement check macro for event "DriverLoad"
+//
+#define EventEnabledDriverLoad() _mcgen_EVENT_BIT_SET(JonMonEnableBits, 0)
+#define EventEnabledDriverLoad_ForContext(pContext) _mcgen_EVENT_BIT_SET(_mcgen_CheckContextType_JonMon(pContext)->EnableBits, 0)
+
+//
+// Event write macros for event "DriverLoad"
+//
+#define EventWriteDriverLoad(Activity, EventTime_, ModulePath) \
+ MCGEN_EVENT_ENABLED(DriverLoad) \
+ ? _mcgen_TEMPLATE_FOR_DriverLoad(&JonMonProvider_Context, &DriverLoad, Activity, EventTime_, ModulePath) : 0
+#define EventWriteDriverLoad_AssumeEnabled(EventTime_, ModulePath) \
+ _mcgen_TEMPLATE_FOR_DriverLoad(&JonMonProvider_Context, &DriverLoad, NULL, EventTime_, ModulePath)
+#define EventWriteDriverLoad_ForContext(pContext, Activity, EventTime_, ModulePath) \
+ MCGEN_EVENT_ENABLED_FORCONTEXT(pContext, DriverLoad) \
+ ? _mcgen_TEMPLATE_FOR_DriverLoad(&(pContext)->Context, &DriverLoad, Activity, EventTime_, ModulePath) : 0
+#define EventWriteDriverLoad_ForContextAssumeEnabled(pContext, EventTime_, ModulePath) \
+ _mcgen_TEMPLATE_FOR_DriverLoad(&_mcgen_CheckContextType_JonMon(pContext)->Context, &DriverLoad, NULL, EventTime_, ModulePath)
+
+// This macro is for use by MC-generated code and should not be used directly.
+#define _mcgen_TEMPLATE_FOR_DriverLoad _mcgen_PASTE2(McTemplateK0mz_, MCGEN_EVENTWRITETRANSFER)
+
+//
+// Enablement check macro for event "DPAPI"
+//
+#define EventEnabledDPAPI() _mcgen_EVENT_BIT_SET(JonMonEnableBits, 0)
+#define EventEnabledDPAPI_ForContext(pContext) _mcgen_EVENT_BIT_SET(_mcgen_CheckContextType_JonMon(pContext)->EnableBits, 0)
+
+//
+// Event write macros for event "DPAPI"
+//
+#define EventWriteDPAPI(Activity, EventTime_, Operation, DataDescription, SourceProcessId, Flags, ProtectionFlags) \
+ MCGEN_EVENT_ENABLED(DPAPI) \
+ ? _mcgen_TEMPLATE_FOR_DPAPI(&JonMonProvider_Context, &DPAPI, Activity, EventTime_, Operation, DataDescription, SourceProcessId, Flags, ProtectionFlags) : 0
+#define EventWriteDPAPI_AssumeEnabled(EventTime_, Operation, DataDescription, SourceProcessId, Flags, ProtectionFlags) \
+ _mcgen_TEMPLATE_FOR_DPAPI(&JonMonProvider_Context, &DPAPI, NULL, EventTime_, Operation, DataDescription, SourceProcessId, Flags, ProtectionFlags)
+#define EventWriteDPAPI_ForContext(pContext, Activity, EventTime_, Operation, DataDescription, SourceProcessId, Flags, ProtectionFlags) \
+ MCGEN_EVENT_ENABLED_FORCONTEXT(pContext, DPAPI) \
+ ? _mcgen_TEMPLATE_FOR_DPAPI(&(pContext)->Context, &DPAPI, Activity, EventTime_, Operation, DataDescription, SourceProcessId, Flags, ProtectionFlags) : 0
+#define EventWriteDPAPI_ForContextAssumeEnabled(pContext, EventTime_, Operation, DataDescription, SourceProcessId, Flags, ProtectionFlags) \
+ _mcgen_TEMPLATE_FOR_DPAPI(&_mcgen_CheckContextType_JonMon(pContext)->Context, &DPAPI, NULL, EventTime_, Operation, DataDescription, SourceProcessId, Flags, ProtectionFlags)
+
+// This macro is for use by MC-generated code and should not be used directly.
+#define _mcgen_TEMPLATE_FOR_DPAPI _mcgen_PASTE2(McTemplateK0mzzqqq_, MCGEN_EVENTWRITETRANSFER)
+
+//
+// Enablement check macro for event "TIWriteProcessMemory"
+//
+#define EventEnabledTIWriteProcessMemory() _mcgen_EVENT_BIT_SET(JonMonEnableBits, 0)
+#define EventEnabledTIWriteProcessMemory_ForContext(pContext) _mcgen_EVENT_BIT_SET(_mcgen_CheckContextType_JonMon(pContext)->EnableBits, 0)
+
+//
+// Event write macros for event "TIWriteProcessMemory"
+//
+#define EventWriteTIWriteProcessMemory(Activity, EventTime_, SourceProcessId, SourceThreadId, SourceProcessFilePath, TargetProcessId, TargetProcessFilePath, SourceProcessStartKey, TargetProcessStartKey, CallStack) \
+ MCGEN_EVENT_ENABLED(TIWriteProcessMemory) \
+ ? _mcgen_TEMPLATE_FOR_TIWriteProcessMemory(&JonMonProvider_Context, &TIWriteProcessMemory, Activity, EventTime_, SourceProcessId, SourceThreadId, SourceProcessFilePath, TargetProcessId, TargetProcessFilePath, SourceProcessStartKey, TargetProcessStartKey, CallStack) : 0
+#define EventWriteTIWriteProcessMemory_AssumeEnabled(EventTime_, SourceProcessId, SourceThreadId, SourceProcessFilePath, TargetProcessId, TargetProcessFilePath, SourceProcessStartKey, TargetProcessStartKey, CallStack) \
+ _mcgen_TEMPLATE_FOR_TIWriteProcessMemory(&JonMonProvider_Context, &TIWriteProcessMemory, NULL, EventTime_, SourceProcessId, SourceThreadId, SourceProcessFilePath, TargetProcessId, TargetProcessFilePath, SourceProcessStartKey, TargetProcessStartKey, CallStack)
+#define EventWriteTIWriteProcessMemory_ForContext(pContext, Activity, EventTime_, SourceProcessId, SourceThreadId, SourceProcessFilePath, TargetProcessId, TargetProcessFilePath, SourceProcessStartKey, TargetProcessStartKey, CallStack) \
+ MCGEN_EVENT_ENABLED_FORCONTEXT(pContext, TIWriteProcessMemory) \
+ ? _mcgen_TEMPLATE_FOR_TIWriteProcessMemory(&(pContext)->Context, &TIWriteProcessMemory, Activity, EventTime_, SourceProcessId, SourceThreadId, SourceProcessFilePath, TargetProcessId, TargetProcessFilePath, SourceProcessStartKey, TargetProcessStartKey, CallStack) : 0
+#define EventWriteTIWriteProcessMemory_ForContextAssumeEnabled(pContext, EventTime_, SourceProcessId, SourceThreadId, SourceProcessFilePath, TargetProcessId, TargetProcessFilePath, SourceProcessStartKey, TargetProcessStartKey, CallStack) \
+ _mcgen_TEMPLATE_FOR_TIWriteProcessMemory(&_mcgen_CheckContextType_JonMon(pContext)->Context, &TIWriteProcessMemory, NULL, EventTime_, SourceProcessId, SourceThreadId, SourceProcessFilePath, TargetProcessId, TargetProcessFilePath, SourceProcessStartKey, TargetProcessStartKey, CallStack)
+
+// This macro is for use by MC-generated code and should not be used directly.
+#define _mcgen_TEMPLATE_FOR_TIWriteProcessMemory _mcgen_PASTE2(McTemplateK0mqqzqzxxz_, MCGEN_EVENTWRITETRANSFER)
+
+//
+// Enablement check macro for event "TIReadProcessMemory"
+//
+#define EventEnabledTIReadProcessMemory() _mcgen_EVENT_BIT_SET(JonMonEnableBits, 0)
+#define EventEnabledTIReadProcessMemory_ForContext(pContext) _mcgen_EVENT_BIT_SET(_mcgen_CheckContextType_JonMon(pContext)->EnableBits, 0)
+
+//
+// Event write macros for event "TIReadProcessMemory"
+//
+#define EventWriteTIReadProcessMemory(Activity, EventTime_, SourceProcessId, SourceThreadId, SourceProcessFilePath, TargetProcessId, TargetProcessFilePath, SourceProcessStartKey, TargetProcessStartKey, CallStack) \
+ MCGEN_EVENT_ENABLED(TIReadProcessMemory) \
+ ? _mcgen_TEMPLATE_FOR_TIReadProcessMemory(&JonMonProvider_Context, &TIReadProcessMemory, Activity, EventTime_, SourceProcessId, SourceThreadId, SourceProcessFilePath, TargetProcessId, TargetProcessFilePath, SourceProcessStartKey, TargetProcessStartKey, CallStack) : 0
+#define EventWriteTIReadProcessMemory_AssumeEnabled(EventTime_, SourceProcessId, SourceThreadId, SourceProcessFilePath, TargetProcessId, TargetProcessFilePath, SourceProcessStartKey, TargetProcessStartKey, CallStack) \
+ _mcgen_TEMPLATE_FOR_TIReadProcessMemory(&JonMonProvider_Context, &TIReadProcessMemory, NULL, EventTime_, SourceProcessId, SourceThreadId, SourceProcessFilePath, TargetProcessId, TargetProcessFilePath, SourceProcessStartKey, TargetProcessStartKey, CallStack)
+#define EventWriteTIReadProcessMemory_ForContext(pContext, Activity, EventTime_, SourceProcessId, SourceThreadId, SourceProcessFilePath, TargetProcessId, TargetProcessFilePath, SourceProcessStartKey, TargetProcessStartKey, CallStack) \
+ MCGEN_EVENT_ENABLED_FORCONTEXT(pContext, TIReadProcessMemory) \
+ ? _mcgen_TEMPLATE_FOR_TIReadProcessMemory(&(pContext)->Context, &TIReadProcessMemory, Activity, EventTime_, SourceProcessId, SourceThreadId, SourceProcessFilePath, TargetProcessId, TargetProcessFilePath, SourceProcessStartKey, TargetProcessStartKey, CallStack) : 0
+#define EventWriteTIReadProcessMemory_ForContextAssumeEnabled(pContext, EventTime_, SourceProcessId, SourceThreadId, SourceProcessFilePath, TargetProcessId, TargetProcessFilePath, SourceProcessStartKey, TargetProcessStartKey, CallStack) \
+ _mcgen_TEMPLATE_FOR_TIReadProcessMemory(&_mcgen_CheckContextType_JonMon(pContext)->Context, &TIReadProcessMemory, NULL, EventTime_, SourceProcessId, SourceThreadId, SourceProcessFilePath, TargetProcessId, TargetProcessFilePath, SourceProcessStartKey, TargetProcessStartKey, CallStack)
+
+// This macro is for use by MC-generated code and should not be used directly.
+#define _mcgen_TEMPLATE_FOR_TIReadProcessMemory _mcgen_PASTE2(McTemplateK0mqqzqzxxz_, MCGEN_EVENTWRITETRANSFER)
+
+//
+// Enablement check macro for event "ThreadTokenImpersonation"
+//
+#define EventEnabledThreadTokenImpersonation() _mcgen_EVENT_BIT_SET(JonMonEnableBits, 0)
+#define EventEnabledThreadTokenImpersonation_ForContext(pContext) _mcgen_EVENT_BIT_SET(_mcgen_CheckContextType_JonMon(pContext)->EnableBits, 0)
+
+//
+// Event write macros for event "ThreadTokenImpersonation"
+//
+#define EventWriteThreadTokenImpersonation(Activity, EventTime_, ProcessId, ImpersonatedThreadId, ThreadUserName, ThreadIntegrityLevel, ProcessUserName, ProcessIntegrityLevel) \
+ MCGEN_EVENT_ENABLED(ThreadTokenImpersonation) \
+ ? _mcgen_TEMPLATE_FOR_ThreadTokenImpersonation(&JonMonProvider_Context, &ThreadTokenImpersonation, Activity, EventTime_, ProcessId, ImpersonatedThreadId, ThreadUserName, ThreadIntegrityLevel, ProcessUserName, ProcessIntegrityLevel) : 0
+#define EventWriteThreadTokenImpersonation_AssumeEnabled(EventTime_, ProcessId, ImpersonatedThreadId, ThreadUserName, ThreadIntegrityLevel, ProcessUserName, ProcessIntegrityLevel) \
+ _mcgen_TEMPLATE_FOR_ThreadTokenImpersonation(&JonMonProvider_Context, &ThreadTokenImpersonation, NULL, EventTime_, ProcessId, ImpersonatedThreadId, ThreadUserName, ThreadIntegrityLevel, ProcessUserName, ProcessIntegrityLevel)
+#define EventWriteThreadTokenImpersonation_ForContext(pContext, Activity, EventTime_, ProcessId, ImpersonatedThreadId, ThreadUserName, ThreadIntegrityLevel, ProcessUserName, ProcessIntegrityLevel) \
+ MCGEN_EVENT_ENABLED_FORCONTEXT(pContext, ThreadTokenImpersonation) \
+ ? _mcgen_TEMPLATE_FOR_ThreadTokenImpersonation(&(pContext)->Context, &ThreadTokenImpersonation, Activity, EventTime_, ProcessId, ImpersonatedThreadId, ThreadUserName, ThreadIntegrityLevel, ProcessUserName, ProcessIntegrityLevel) : 0
+#define EventWriteThreadTokenImpersonation_ForContextAssumeEnabled(pContext, EventTime_, ProcessId, ImpersonatedThreadId, ThreadUserName, ThreadIntegrityLevel, ProcessUserName, ProcessIntegrityLevel) \
+ _mcgen_TEMPLATE_FOR_ThreadTokenImpersonation(&_mcgen_CheckContextType_JonMon(pContext)->Context, &ThreadTokenImpersonation, NULL, EventTime_, ProcessId, ImpersonatedThreadId, ThreadUserName, ThreadIntegrityLevel, ProcessUserName, ProcessIntegrityLevel)
+
+// This macro is for use by MC-generated code and should not be used directly.
+#define _mcgen_TEMPLATE_FOR_ThreadTokenImpersonation _mcgen_PASTE2(McTemplateK0mqqzzzz_, MCGEN_EVENTWRITETRANSFER)
+
+//
+// Enablement check macro for event "TIRemoteAllocateVirtualMemory"
+//
+#define EventEnabledTIRemoteAllocateVirtualMemory() _mcgen_EVENT_BIT_SET(JonMonEnableBits, 0)
+#define EventEnabledTIRemoteAllocateVirtualMemory_ForContext(pContext) _mcgen_EVENT_BIT_SET(_mcgen_CheckContextType_JonMon(pContext)->EnableBits, 0)
+
+//
+// Event write macros for event "TIRemoteAllocateVirtualMemory"
+//
+#define EventWriteTIRemoteAllocateVirtualMemory(Activity, EventTime_, SourceThreadId, SourceProcessId, TargetProcessId, SourceProcessStartKey, TargetProcessStartKey, OriginalProcessId, BaseAddress, SourceProcessFilePath, TargetProcessFilePath, CallStack) \
+ MCGEN_EVENT_ENABLED(TIRemoteAllocateVirtualMemory) \
+ ? _mcgen_TEMPLATE_FOR_TIRemoteAllocateVirtualMemory(&JonMonProvider_Context, &TIRemoteAllocateVirtualMemory, Activity, EventTime_, SourceThreadId, SourceProcessId, TargetProcessId, SourceProcessStartKey, TargetProcessStartKey, OriginalProcessId, BaseAddress, SourceProcessFilePath, TargetProcessFilePath, CallStack) : 0
+#define EventWriteTIRemoteAllocateVirtualMemory_AssumeEnabled(EventTime_, SourceThreadId, SourceProcessId, TargetProcessId, SourceProcessStartKey, TargetProcessStartKey, OriginalProcessId, BaseAddress, SourceProcessFilePath, TargetProcessFilePath, CallStack) \
+ _mcgen_TEMPLATE_FOR_TIRemoteAllocateVirtualMemory(&JonMonProvider_Context, &TIRemoteAllocateVirtualMemory, NULL, EventTime_, SourceThreadId, SourceProcessId, TargetProcessId, SourceProcessStartKey, TargetProcessStartKey, OriginalProcessId, BaseAddress, SourceProcessFilePath, TargetProcessFilePath, CallStack)
+#define EventWriteTIRemoteAllocateVirtualMemory_ForContext(pContext, Activity, EventTime_, SourceThreadId, SourceProcessId, TargetProcessId, SourceProcessStartKey, TargetProcessStartKey, OriginalProcessId, BaseAddress, SourceProcessFilePath, TargetProcessFilePath, CallStack) \
+ MCGEN_EVENT_ENABLED_FORCONTEXT(pContext, TIRemoteAllocateVirtualMemory) \
+ ? _mcgen_TEMPLATE_FOR_TIRemoteAllocateVirtualMemory(&(pContext)->Context, &TIRemoteAllocateVirtualMemory, Activity, EventTime_, SourceThreadId, SourceProcessId, TargetProcessId, SourceProcessStartKey, TargetProcessStartKey, OriginalProcessId, BaseAddress, SourceProcessFilePath, TargetProcessFilePath, CallStack) : 0
+#define EventWriteTIRemoteAllocateVirtualMemory_ForContextAssumeEnabled(pContext, EventTime_, SourceThreadId, SourceProcessId, TargetProcessId, SourceProcessStartKey, TargetProcessStartKey, OriginalProcessId, BaseAddress, SourceProcessFilePath, TargetProcessFilePath, CallStack) \
+ _mcgen_TEMPLATE_FOR_TIRemoteAllocateVirtualMemory(&_mcgen_CheckContextType_JonMon(pContext)->Context, &TIRemoteAllocateVirtualMemory, NULL, EventTime_, SourceThreadId, SourceProcessId, TargetProcessId, SourceProcessStartKey, TargetProcessStartKey, OriginalProcessId, BaseAddress, SourceProcessFilePath, TargetProcessFilePath, CallStack)
+
+// This macro is for use by MC-generated code and should not be used directly.
+#define _mcgen_TEMPLATE_FOR_TIRemoteAllocateVirtualMemory _mcgen_PASTE2(McTemplateK0mqqqxxqpzzz_, MCGEN_EVENTWRITETRANSFER)
+
+#endif // MCGEN_DISABLE_PROVIDER_CODE_GENERATION
+
+//
+// MCGEN_DISABLE_PROVIDER_CODE_GENERATION macro:
+// Define this macro to have the compiler skip the generated functions in this
+// header.
+//
+#ifndef MCGEN_DISABLE_PROVIDER_CODE_GENERATION
+
+//
+// Template Functions
+//
+
+//
+// Function for template "EID2" (and possibly others).
+// This function is for use by MC-generated code and should not be used directly.
+//
+#ifndef McTemplateK0mdxxzxxxzzq_def
+#define McTemplateK0mdxxzxxxzzq_def
+ETW_INLINE
+ULONG
+_mcgen_PASTE2(McTemplateK0mdxxzxxxzzq_, MCGEN_EVENTWRITETRANSFER)(
+ _In_ PMCGEN_TRACE_CONTEXT Context,
+ _In_ PCEVENT_DESCRIPTOR Descriptor,
+ _In_opt_ const GUID* Activity,
+ _In_ const FILETIME* _Arg0,
+ _In_ const signed int _Arg1,
+ _In_ const unsigned __int64 _Arg2,
+ _In_ const unsigned __int64 _Arg3,
+ _In_opt_ PCWSTR _Arg4,
+ _In_ const unsigned __int64 _Arg5,
+ _In_ const unsigned __int64 _Arg6,
+ _In_ const unsigned __int64 _Arg7,
+ _In_opt_ PCWSTR _Arg8,
+ _In_opt_ PCWSTR _Arg9,
+ _In_ const unsigned int _Arg10
+ )
+{
+#define McTemplateK0mdxxzxxxzzq_ARGCOUNT 11
+
+ EVENT_DATA_DESCRIPTOR EventData[McTemplateK0mdxxzxxxzzq_ARGCOUNT + 1];
+
+ EventDataDescCreate(&EventData[1],_Arg0, sizeof(FILETIME) );
+
+ EventDataDescCreate(&EventData[2],&_Arg1, sizeof(const signed int) );
+
+ EventDataDescCreate(&EventData[3],&_Arg2, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[4],&_Arg3, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[5],
+ (_Arg4 != NULL) ? _Arg4 : L"NULL",
+ (_Arg4 != NULL) ? (ULONG)((wcslen(_Arg4) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[6],&_Arg5, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[7],&_Arg6, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[8],&_Arg7, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[9],
+ (_Arg8 != NULL) ? _Arg8 : L"NULL",
+ (_Arg8 != NULL) ? (ULONG)((wcslen(_Arg8) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[10],
+ (_Arg9 != NULL) ? _Arg9 : L"NULL",
+ (_Arg9 != NULL) ? (ULONG)((wcslen(_Arg9) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[11],&_Arg10, sizeof(const unsigned int) );
+
+ return McGenEventWrite(Context, Descriptor, Activity, McTemplateK0mdxxzxxxzzq_ARGCOUNT + 1, EventData);
+}
+#endif // McTemplateK0mdxxzxxxzzq_def
+
+//
+// Function for template "EID26" (and possibly others).
+// This function is for use by MC-generated code and should not be used directly.
+//
+#ifndef McTemplateK0mqqqqxxqppzzz_def
+#define McTemplateK0mqqqqxxqppzzz_def
+ETW_INLINE
+ULONG
+_mcgen_PASTE2(McTemplateK0mqqqqxxqppzzz_, MCGEN_EVENTWRITETRANSFER)(
+ _In_ PMCGEN_TRACE_CONTEXT Context,
+ _In_ PCEVENT_DESCRIPTOR Descriptor,
+ _In_opt_ const GUID* Activity,
+ _In_ const FILETIME* _Arg0,
+ _In_ const unsigned int _Arg1,
+ _In_ const unsigned int _Arg2,
+ _In_ const unsigned int _Arg3,
+ _In_ const unsigned int _Arg4,
+ _In_ const unsigned __int64 _Arg5,
+ _In_ const unsigned __int64 _Arg6,
+ _In_ const unsigned int _Arg7,
+ _In_opt_ const void* _Arg8,
+ _In_opt_ const void* _Arg9,
+ _In_opt_ PCWSTR _Arg10,
+ _In_opt_ PCWSTR _Arg11,
+ _In_opt_ PCWSTR _Arg12
+ )
+{
+#define McTemplateK0mqqqqxxqppzzz_ARGCOUNT 13
+
+ EVENT_DATA_DESCRIPTOR EventData[McTemplateK0mqqqqxxqppzzz_ARGCOUNT + 1];
+
+ EventDataDescCreate(&EventData[1],_Arg0, sizeof(FILETIME) );
+
+ EventDataDescCreate(&EventData[2],&_Arg1, sizeof(const unsigned int) );
+
+ EventDataDescCreate(&EventData[3],&_Arg2, sizeof(const unsigned int) );
+
+ EventDataDescCreate(&EventData[4],&_Arg3, sizeof(const unsigned int) );
+
+ EventDataDescCreate(&EventData[5],&_Arg4, sizeof(const unsigned int) );
+
+ EventDataDescCreate(&EventData[6],&_Arg5, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[7],&_Arg6, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[8],&_Arg7, sizeof(const unsigned int) );
+
+ EventDataDescCreate(&EventData[9],&_Arg8, sizeof(const void*) );
+
+ EventDataDescCreate(&EventData[10],&_Arg9, sizeof(const void*) );
+
+ EventDataDescCreate(&EventData[11],
+ (_Arg10 != NULL) ? _Arg10 : L"NULL",
+ (_Arg10 != NULL) ? (ULONG)((wcslen(_Arg10) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[12],
+ (_Arg11 != NULL) ? _Arg11 : L"NULL",
+ (_Arg11 != NULL) ? (ULONG)((wcslen(_Arg11) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[13],
+ (_Arg12 != NULL) ? _Arg12 : L"NULL",
+ (_Arg12 != NULL) ? (ULONG)((wcslen(_Arg12) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ return McGenEventWrite(Context, Descriptor, Activity, McTemplateK0mqqqqxxqppzzz_ARGCOUNT + 1, EventData);
+}
+#endif // McTemplateK0mqqqqxxqppzzz_def
+
+//
+// Function for template "EID32" (and possibly others).
+// This function is for use by MC-generated code and should not be used directly.
+//
+#ifndef McTemplateK0mqqqxxqpzzz_def
+#define McTemplateK0mqqqxxqpzzz_def
+ETW_INLINE
+ULONG
+_mcgen_PASTE2(McTemplateK0mqqqxxqpzzz_, MCGEN_EVENTWRITETRANSFER)(
+ _In_ PMCGEN_TRACE_CONTEXT Context,
+ _In_ PCEVENT_DESCRIPTOR Descriptor,
+ _In_opt_ const GUID* Activity,
+ _In_ const FILETIME* _Arg0,
+ _In_ const unsigned int _Arg1,
+ _In_ const unsigned int _Arg2,
+ _In_ const unsigned int _Arg3,
+ _In_ const unsigned __int64 _Arg4,
+ _In_ const unsigned __int64 _Arg5,
+ _In_ const unsigned int _Arg6,
+ _In_opt_ const void* _Arg7,
+ _In_opt_ PCWSTR _Arg8,
+ _In_opt_ PCWSTR _Arg9,
+ _In_opt_ PCWSTR _Arg10
+ )
+{
+#define McTemplateK0mqqqxxqpzzz_ARGCOUNT 11
+
+ EVENT_DATA_DESCRIPTOR EventData[McTemplateK0mqqqxxqpzzz_ARGCOUNT + 1];
+
+ EventDataDescCreate(&EventData[1],_Arg0, sizeof(FILETIME) );
+
+ EventDataDescCreate(&EventData[2],&_Arg1, sizeof(const unsigned int) );
+
+ EventDataDescCreate(&EventData[3],&_Arg2, sizeof(const unsigned int) );
+
+ EventDataDescCreate(&EventData[4],&_Arg3, sizeof(const unsigned int) );
+
+ EventDataDescCreate(&EventData[5],&_Arg4, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[6],&_Arg5, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[7],&_Arg6, sizeof(const unsigned int) );
+
+ EventDataDescCreate(&EventData[8],&_Arg7, sizeof(const void*) );
+
+ EventDataDescCreate(&EventData[9],
+ (_Arg8 != NULL) ? _Arg8 : L"NULL",
+ (_Arg8 != NULL) ? (ULONG)((wcslen(_Arg8) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[10],
+ (_Arg9 != NULL) ? _Arg9 : L"NULL",
+ (_Arg9 != NULL) ? (ULONG)((wcslen(_Arg9) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[11],
+ (_Arg10 != NULL) ? _Arg10 : L"NULL",
+ (_Arg10 != NULL) ? (ULONG)((wcslen(_Arg10) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ return McGenEventWrite(Context, Descriptor, Activity, McTemplateK0mqqqxxqpzzz_ARGCOUNT + 1, EventData);
+}
+#endif // McTemplateK0mqqqxxqpzzz_def
+
+//
+// Function for template "EID29" (and possibly others).
+// This function is for use by MC-generated code and should not be used directly.
+//
+#ifndef McTemplateK0mqqzqzxxz_def
+#define McTemplateK0mqqzqzxxz_def
+ETW_INLINE
+ULONG
+_mcgen_PASTE2(McTemplateK0mqqzqzxxz_, MCGEN_EVENTWRITETRANSFER)(
+ _In_ PMCGEN_TRACE_CONTEXT Context,
+ _In_ PCEVENT_DESCRIPTOR Descriptor,
+ _In_opt_ const GUID* Activity,
+ _In_ const FILETIME* _Arg0,
+ _In_ const unsigned int _Arg1,
+ _In_ const unsigned int _Arg2,
+ _In_opt_ PCWSTR _Arg3,
+ _In_ const unsigned int _Arg4,
+ _In_opt_ PCWSTR _Arg5,
+ _In_ const unsigned __int64 _Arg6,
+ _In_ const unsigned __int64 _Arg7,
+ _In_opt_ PCWSTR _Arg8
+ )
+{
+#define McTemplateK0mqqzqzxxz_ARGCOUNT 9
+
+ EVENT_DATA_DESCRIPTOR EventData[McTemplateK0mqqzqzxxz_ARGCOUNT + 1];
+
+ EventDataDescCreate(&EventData[1],_Arg0, sizeof(FILETIME) );
+
+ EventDataDescCreate(&EventData[2],&_Arg1, sizeof(const unsigned int) );
+
+ EventDataDescCreate(&EventData[3],&_Arg2, sizeof(const unsigned int) );
+
+ EventDataDescCreate(&EventData[4],
+ (_Arg3 != NULL) ? _Arg3 : L"NULL",
+ (_Arg3 != NULL) ? (ULONG)((wcslen(_Arg3) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[5],&_Arg4, sizeof(const unsigned int) );
+
+ EventDataDescCreate(&EventData[6],
+ (_Arg5 != NULL) ? _Arg5 : L"NULL",
+ (_Arg5 != NULL) ? (ULONG)((wcslen(_Arg5) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[7],&_Arg6, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[8],&_Arg7, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[9],
+ (_Arg8 != NULL) ? _Arg8 : L"NULL",
+ (_Arg8 != NULL) ? (ULONG)((wcslen(_Arg8) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ return McGenEventWrite(Context, Descriptor, Activity, McTemplateK0mqqzqzxxz_ARGCOUNT + 1, EventData);
+}
+#endif // McTemplateK0mqqzqzxxz_def
+
+//
+// Function for template "EID31" (and possibly others).
+// This function is for use by MC-generated code and should not be used directly.
+//
+#ifndef McTemplateK0mqqzzzz_def
+#define McTemplateK0mqqzzzz_def
+ETW_INLINE
+ULONG
+_mcgen_PASTE2(McTemplateK0mqqzzzz_, MCGEN_EVENTWRITETRANSFER)(
+ _In_ PMCGEN_TRACE_CONTEXT Context,
+ _In_ PCEVENT_DESCRIPTOR Descriptor,
+ _In_opt_ const GUID* Activity,
+ _In_ const FILETIME* _Arg0,
+ _In_ const unsigned int _Arg1,
+ _In_ const unsigned int _Arg2,
+ _In_opt_ PCWSTR _Arg3,
+ _In_opt_ PCWSTR _Arg4,
+ _In_opt_ PCWSTR _Arg5,
+ _In_opt_ PCWSTR _Arg6
+ )
+{
+#define McTemplateK0mqqzzzz_ARGCOUNT 7
+
+ EVENT_DATA_DESCRIPTOR EventData[McTemplateK0mqqzzzz_ARGCOUNT + 1];
+
+ EventDataDescCreate(&EventData[1],_Arg0, sizeof(FILETIME) );
+
+ EventDataDescCreate(&EventData[2],&_Arg1, sizeof(const unsigned int) );
+
+ EventDataDescCreate(&EventData[3],&_Arg2, sizeof(const unsigned int) );
+
+ EventDataDescCreate(&EventData[4],
+ (_Arg3 != NULL) ? _Arg3 : L"NULL",
+ (_Arg3 != NULL) ? (ULONG)((wcslen(_Arg3) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[5],
+ (_Arg4 != NULL) ? _Arg4 : L"NULL",
+ (_Arg4 != NULL) ? (ULONG)((wcslen(_Arg4) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[6],
+ (_Arg5 != NULL) ? _Arg5 : L"NULL",
+ (_Arg5 != NULL) ? (ULONG)((wcslen(_Arg5) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[7],
+ (_Arg6 != NULL) ? _Arg6 : L"NULL",
+ (_Arg6 != NULL) ? (ULONG)((wcslen(_Arg6) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ return McGenEventWrite(Context, Descriptor, Activity, McTemplateK0mqqzzzz_ARGCOUNT + 1, EventData);
+}
+#endif // McTemplateK0mqqzzzz_def
+
+//
+// Function for template "EID16" (and possibly others).
+// This function is for use by MC-generated code and should not be used directly.
+//
+#ifndef McTemplateK0mqzqq_def
+#define McTemplateK0mqzqq_def
+ETW_INLINE
+ULONG
+_mcgen_PASTE2(McTemplateK0mqzqq_, MCGEN_EVENTWRITETRANSFER)(
+ _In_ PMCGEN_TRACE_CONTEXT Context,
+ _In_ PCEVENT_DESCRIPTOR Descriptor,
+ _In_opt_ const GUID* Activity,
+ _In_ const FILETIME* _Arg0,
+ _In_ const unsigned int _Arg1,
+ _In_opt_ PCWSTR _Arg2,
+ _In_ const unsigned int _Arg3,
+ _In_ const unsigned int _Arg4
+ )
+{
+#define McTemplateK0mqzqq_ARGCOUNT 5
+
+ EVENT_DATA_DESCRIPTOR EventData[McTemplateK0mqzqq_ARGCOUNT + 1];
+
+ EventDataDescCreate(&EventData[1],_Arg0, sizeof(FILETIME) );
+
+ EventDataDescCreate(&EventData[2],&_Arg1, sizeof(const unsigned int) );
+
+ EventDataDescCreate(&EventData[3],
+ (_Arg2 != NULL) ? _Arg2 : L"NULL",
+ (_Arg2 != NULL) ? (ULONG)((wcslen(_Arg2) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[4],&_Arg3, sizeof(const unsigned int) );
+
+ EventDataDescCreate(&EventData[5],&_Arg4, sizeof(const unsigned int) );
+
+ return McGenEventWrite(Context, Descriptor, Activity, McTemplateK0mqzqq_ARGCOUNT + 1, EventData);
+}
+#endif // McTemplateK0mqzqq_def
+
+//
+// Function for template "EID13" (and possibly others).
+// This function is for use by MC-generated code and should not be used directly.
+//
+#ifndef McTemplateK0mqzzhhzzz_def
+#define McTemplateK0mqzzhhzzz_def
+ETW_INLINE
+ULONG
+_mcgen_PASTE2(McTemplateK0mqzzhhzzz_, MCGEN_EVENTWRITETRANSFER)(
+ _In_ PMCGEN_TRACE_CONTEXT Context,
+ _In_ PCEVENT_DESCRIPTOR Descriptor,
+ _In_opt_ const GUID* Activity,
+ _In_ const FILETIME* _Arg0,
+ _In_ const unsigned int _Arg1,
+ _In_opt_ PCWSTR _Arg2,
+ _In_opt_ PCWSTR _Arg3,
+ _In_ const unsigned short _Arg4,
+ _In_ const unsigned short _Arg5,
+ _In_opt_ PCWSTR _Arg6,
+ _In_opt_ PCWSTR _Arg7,
+ _In_opt_ PCWSTR _Arg8
+ )
+{
+#define McTemplateK0mqzzhhzzz_ARGCOUNT 9
+
+ EVENT_DATA_DESCRIPTOR EventData[McTemplateK0mqzzhhzzz_ARGCOUNT + 1];
+
+ EventDataDescCreate(&EventData[1],_Arg0, sizeof(FILETIME) );
+
+ EventDataDescCreate(&EventData[2],&_Arg1, sizeof(const unsigned int) );
+
+ EventDataDescCreate(&EventData[3],
+ (_Arg2 != NULL) ? _Arg2 : L"NULL",
+ (_Arg2 != NULL) ? (ULONG)((wcslen(_Arg2) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[4],
+ (_Arg3 != NULL) ? _Arg3 : L"NULL",
+ (_Arg3 != NULL) ? (ULONG)((wcslen(_Arg3) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[5],&_Arg4, sizeof(const unsigned short) );
+
+ EventDataDescCreate(&EventData[6],&_Arg5, sizeof(const unsigned short) );
+
+ EventDataDescCreate(&EventData[7],
+ (_Arg6 != NULL) ? _Arg6 : L"NULL",
+ (_Arg6 != NULL) ? (ULONG)((wcslen(_Arg6) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[8],
+ (_Arg7 != NULL) ? _Arg7 : L"NULL",
+ (_Arg7 != NULL) ? (ULONG)((wcslen(_Arg7) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[9],
+ (_Arg8 != NULL) ? _Arg8 : L"NULL",
+ (_Arg8 != NULL) ? (ULONG)((wcslen(_Arg8) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ return McGenEventWrite(Context, Descriptor, Activity, McTemplateK0mqzzhhzzz_ARGCOUNT + 1, EventData);
+}
+#endif // McTemplateK0mqzzhhzzz_def
+
+//
+// Function for template "EID15" (and possibly others).
+// This function is for use by MC-generated code and should not be used directly.
+//
+#ifndef McTemplateK0mqzzzh_def
+#define McTemplateK0mqzzzh_def
+ETW_INLINE
+ULONG
+_mcgen_PASTE2(McTemplateK0mqzzzh_, MCGEN_EVENTWRITETRANSFER)(
+ _In_ PMCGEN_TRACE_CONTEXT Context,
+ _In_ PCEVENT_DESCRIPTOR Descriptor,
+ _In_opt_ const GUID* Activity,
+ _In_ const FILETIME* _Arg0,
+ _In_ const unsigned int _Arg1,
+ _In_opt_ PCWSTR _Arg2,
+ _In_opt_ PCWSTR _Arg3,
+ _In_opt_ PCWSTR _Arg4,
+ _In_ const unsigned short _Arg5
+ )
+{
+#define McTemplateK0mqzzzh_ARGCOUNT 6
+
+ EVENT_DATA_DESCRIPTOR EventData[McTemplateK0mqzzzh_ARGCOUNT + 1];
+
+ EventDataDescCreate(&EventData[1],_Arg0, sizeof(FILETIME) );
+
+ EventDataDescCreate(&EventData[2],&_Arg1, sizeof(const unsigned int) );
+
+ EventDataDescCreate(&EventData[3],
+ (_Arg2 != NULL) ? _Arg2 : L"NULL",
+ (_Arg2 != NULL) ? (ULONG)((wcslen(_Arg2) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[4],
+ (_Arg3 != NULL) ? _Arg3 : L"NULL",
+ (_Arg3 != NULL) ? (ULONG)((wcslen(_Arg3) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[5],
+ (_Arg4 != NULL) ? _Arg4 : L"NULL",
+ (_Arg4 != NULL) ? (ULONG)((wcslen(_Arg4) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[6],&_Arg5, sizeof(const unsigned short) );
+
+ return McGenEventWrite(Context, Descriptor, Activity, McTemplateK0mqzzzh_ARGCOUNT + 1, EventData);
+}
+#endif // McTemplateK0mqzzzh_def
+
+//
+// Function for template "EID27" (and possibly others).
+// This function is for use by MC-generated code and should not be used directly.
+//
+#ifndef McTemplateK0mz_def
+#define McTemplateK0mz_def
+ETW_INLINE
+ULONG
+_mcgen_PASTE2(McTemplateK0mz_, MCGEN_EVENTWRITETRANSFER)(
+ _In_ PMCGEN_TRACE_CONTEXT Context,
+ _In_ PCEVENT_DESCRIPTOR Descriptor,
+ _In_opt_ const GUID* Activity,
+ _In_ const FILETIME* _Arg0,
+ _In_opt_ PCWSTR _Arg1
+ )
+{
+#define McTemplateK0mz_ARGCOUNT 2
+
+ EVENT_DATA_DESCRIPTOR EventData[McTemplateK0mz_ARGCOUNT + 1];
+
+ EventDataDescCreate(&EventData[1],_Arg0, sizeof(FILETIME) );
+
+ EventDataDescCreate(&EventData[2],
+ (_Arg1 != NULL) ? _Arg1 : L"NULL",
+ (_Arg1 != NULL) ? (ULONG)((wcslen(_Arg1) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ return McGenEventWrite(Context, Descriptor, Activity, McTemplateK0mz_ARGCOUNT + 1, EventData);
+}
+#endif // McTemplateK0mz_def
+
+//
+// Function for template "EID11" (and possibly others).
+// This function is for use by MC-generated code and should not be used directly.
+//
+#ifndef McTemplateK0mzqqqzzzzzzz_def
+#define McTemplateK0mzqqqzzzzzzz_def
+ETW_INLINE
+ULONG
+_mcgen_PASTE2(McTemplateK0mzqqqzzzzzzz_, MCGEN_EVENTWRITETRANSFER)(
+ _In_ PMCGEN_TRACE_CONTEXT Context,
+ _In_ PCEVENT_DESCRIPTOR Descriptor,
+ _In_opt_ const GUID* Activity,
+ _In_ const FILETIME* _Arg0,
+ _In_opt_ PCWSTR _Arg1,
+ _In_ const unsigned int _Arg2,
+ _In_ const unsigned int _Arg3,
+ _In_ const unsigned int _Arg4,
+ _In_opt_ PCWSTR _Arg5,
+ _In_opt_ PCWSTR _Arg6,
+ _In_opt_ PCWSTR _Arg7,
+ _In_opt_ PCWSTR _Arg8,
+ _In_opt_ PCWSTR _Arg9,
+ _In_opt_ PCWSTR _Arg10,
+ _In_opt_ PCWSTR _Arg11
+ )
+{
+#define McTemplateK0mzqqqzzzzzzz_ARGCOUNT 12
+
+ EVENT_DATA_DESCRIPTOR EventData[McTemplateK0mzqqqzzzzzzz_ARGCOUNT + 1];
+
+ EventDataDescCreate(&EventData[1],_Arg0, sizeof(FILETIME) );
+
+ EventDataDescCreate(&EventData[2],
+ (_Arg1 != NULL) ? _Arg1 : L"NULL",
+ (_Arg1 != NULL) ? (ULONG)((wcslen(_Arg1) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[3],&_Arg2, sizeof(const unsigned int) );
+
+ EventDataDescCreate(&EventData[4],&_Arg3, sizeof(const unsigned int) );
+
+ EventDataDescCreate(&EventData[5],&_Arg4, sizeof(const unsigned int) );
+
+ EventDataDescCreate(&EventData[6],
+ (_Arg5 != NULL) ? _Arg5 : L"NULL",
+ (_Arg5 != NULL) ? (ULONG)((wcslen(_Arg5) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[7],
+ (_Arg6 != NULL) ? _Arg6 : L"NULL",
+ (_Arg6 != NULL) ? (ULONG)((wcslen(_Arg6) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[8],
+ (_Arg7 != NULL) ? _Arg7 : L"NULL",
+ (_Arg7 != NULL) ? (ULONG)((wcslen(_Arg7) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[9],
+ (_Arg8 != NULL) ? _Arg8 : L"NULL",
+ (_Arg8 != NULL) ? (ULONG)((wcslen(_Arg8) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[10],
+ (_Arg9 != NULL) ? _Arg9 : L"NULL",
+ (_Arg9 != NULL) ? (ULONG)((wcslen(_Arg9) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[11],
+ (_Arg10 != NULL) ? _Arg10 : L"NULL",
+ (_Arg10 != NULL) ? (ULONG)((wcslen(_Arg10) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[12],
+ (_Arg11 != NULL) ? _Arg11 : L"NULL",
+ (_Arg11 != NULL) ? (ULONG)((wcslen(_Arg11) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ return McGenEventWrite(Context, Descriptor, Activity, McTemplateK0mzqqqzzzzzzz_ARGCOUNT + 1, EventData);
+}
+#endif // McTemplateK0mzqqqzzzzzzz_def
+
+//
+// Function for template "EID5" (and possibly others).
+// This function is for use by MC-generated code and should not be used directly.
+//
+#ifndef McTemplateK0mzxxxzdzq_def
+#define McTemplateK0mzxxxzdzq_def
+ETW_INLINE
+ULONG
+_mcgen_PASTE2(McTemplateK0mzxxxzdzq_, MCGEN_EVENTWRITETRANSFER)(
+ _In_ PMCGEN_TRACE_CONTEXT Context,
+ _In_ PCEVENT_DESCRIPTOR Descriptor,
+ _In_opt_ const GUID* Activity,
+ _In_ const FILETIME* _Arg0,
+ _In_opt_ PCWSTR _Arg1,
+ _In_ const unsigned __int64 _Arg2,
+ _In_ const unsigned __int64 _Arg3,
+ _In_ const unsigned __int64 _Arg4,
+ _In_opt_ PCWSTR _Arg5,
+ _In_ const signed int _Arg6,
+ _In_opt_ PCWSTR _Arg7,
+ _In_ const unsigned int _Arg8
+ )
+{
+#define McTemplateK0mzxxxzdzq_ARGCOUNT 9
+
+ EVENT_DATA_DESCRIPTOR EventData[McTemplateK0mzxxxzdzq_ARGCOUNT + 1];
+
+ EventDataDescCreate(&EventData[1],_Arg0, sizeof(FILETIME) );
+
+ EventDataDescCreate(&EventData[2],
+ (_Arg1 != NULL) ? _Arg1 : L"NULL",
+ (_Arg1 != NULL) ? (ULONG)((wcslen(_Arg1) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[3],&_Arg2, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[4],&_Arg3, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[5],&_Arg4, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[6],
+ (_Arg5 != NULL) ? _Arg5 : L"NULL",
+ (_Arg5 != NULL) ? (ULONG)((wcslen(_Arg5) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[7],&_Arg6, sizeof(const signed int) );
+
+ EventDataDescCreate(&EventData[8],
+ (_Arg7 != NULL) ? _Arg7 : L"NULL",
+ (_Arg7 != NULL) ? (ULONG)((wcslen(_Arg7) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[9],&_Arg8, sizeof(const unsigned int) );
+
+ return McGenEventWrite(Context, Descriptor, Activity, McTemplateK0mzxxxzdzq_ARGCOUNT + 1, EventData);
+}
+#endif // McTemplateK0mzxxxzdzq_def
+
+//
+// Function for template "EID10" (and possibly others).
+// This function is for use by MC-generated code and should not be used directly.
+//
+#ifndef McTemplateK0mzxxxzqzz_def
+#define McTemplateK0mzxxxzqzz_def
+ETW_INLINE
+ULONG
+_mcgen_PASTE2(McTemplateK0mzxxxzqzz_, MCGEN_EVENTWRITETRANSFER)(
+ _In_ PMCGEN_TRACE_CONTEXT Context,
+ _In_ PCEVENT_DESCRIPTOR Descriptor,
+ _In_opt_ const GUID* Activity,
+ _In_ const FILETIME* _Arg0,
+ _In_opt_ PCWSTR _Arg1,
+ _In_ const unsigned __int64 _Arg2,
+ _In_ const unsigned __int64 _Arg3,
+ _In_ const unsigned __int64 _Arg4,
+ _In_opt_ PCWSTR _Arg5,
+ _In_ const unsigned int _Arg6,
+ _In_opt_ PCWSTR _Arg7,
+ _In_opt_ PCWSTR _Arg8
+ )
+{
+#define McTemplateK0mzxxxzqzz_ARGCOUNT 9
+
+ EVENT_DATA_DESCRIPTOR EventData[McTemplateK0mzxxxzqzz_ARGCOUNT + 1];
+
+ EventDataDescCreate(&EventData[1],_Arg0, sizeof(FILETIME) );
+
+ EventDataDescCreate(&EventData[2],
+ (_Arg1 != NULL) ? _Arg1 : L"NULL",
+ (_Arg1 != NULL) ? (ULONG)((wcslen(_Arg1) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[3],&_Arg2, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[4],&_Arg3, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[5],&_Arg4, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[6],
+ (_Arg5 != NULL) ? _Arg5 : L"NULL",
+ (_Arg5 != NULL) ? (ULONG)((wcslen(_Arg5) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[7],&_Arg6, sizeof(const unsigned int) );
+
+ EventDataDescCreate(&EventData[8],
+ (_Arg7 != NULL) ? _Arg7 : L"NULL",
+ (_Arg7 != NULL) ? (ULONG)((wcslen(_Arg7) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[9],
+ (_Arg8 != NULL) ? _Arg8 : L"NULL",
+ (_Arg8 != NULL) ? (ULONG)((wcslen(_Arg8) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ return McGenEventWrite(Context, Descriptor, Activity, McTemplateK0mzxxxzqzz_ARGCOUNT + 1, EventData);
+}
+#endif // McTemplateK0mzxxxzqzz_def
+
+//
+// Function for template "EID24" (and possibly others).
+// This function is for use by MC-generated code and should not be used directly.
+//
+#ifndef McTemplateK0mzxxxzqzzdd_def
+#define McTemplateK0mzxxxzqzzdd_def
+ETW_INLINE
+ULONG
+_mcgen_PASTE2(McTemplateK0mzxxxzqzzdd_, MCGEN_EVENTWRITETRANSFER)(
+ _In_ PMCGEN_TRACE_CONTEXT Context,
+ _In_ PCEVENT_DESCRIPTOR Descriptor,
+ _In_opt_ const GUID* Activity,
+ _In_ const FILETIME* _Arg0,
+ _In_opt_ PCWSTR _Arg1,
+ _In_ const unsigned __int64 _Arg2,
+ _In_ const unsigned __int64 _Arg3,
+ _In_ const unsigned __int64 _Arg4,
+ _In_opt_ PCWSTR _Arg5,
+ _In_ const unsigned int _Arg6,
+ _In_opt_ PCWSTR _Arg7,
+ _In_opt_ PCWSTR _Arg8,
+ _In_ const signed int _Arg9,
+ _In_ const signed int _Arg10
+ )
+{
+#define McTemplateK0mzxxxzqzzdd_ARGCOUNT 11
+
+ EVENT_DATA_DESCRIPTOR EventData[McTemplateK0mzxxxzqzzdd_ARGCOUNT + 1];
+
+ EventDataDescCreate(&EventData[1],_Arg0, sizeof(FILETIME) );
+
+ EventDataDescCreate(&EventData[2],
+ (_Arg1 != NULL) ? _Arg1 : L"NULL",
+ (_Arg1 != NULL) ? (ULONG)((wcslen(_Arg1) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[3],&_Arg2, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[4],&_Arg3, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[5],&_Arg4, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[6],
+ (_Arg5 != NULL) ? _Arg5 : L"NULL",
+ (_Arg5 != NULL) ? (ULONG)((wcslen(_Arg5) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[7],&_Arg6, sizeof(const unsigned int) );
+
+ EventDataDescCreate(&EventData[8],
+ (_Arg7 != NULL) ? _Arg7 : L"NULL",
+ (_Arg7 != NULL) ? (ULONG)((wcslen(_Arg7) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[9],
+ (_Arg8 != NULL) ? _Arg8 : L"NULL",
+ (_Arg8 != NULL) ? (ULONG)((wcslen(_Arg8) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[10],&_Arg9, sizeof(const signed int) );
+
+ EventDataDescCreate(&EventData[11],&_Arg10, sizeof(const signed int) );
+
+ return McGenEventWrite(Context, Descriptor, Activity, McTemplateK0mzxxxzqzzdd_ARGCOUNT + 1, EventData);
+}
+#endif // McTemplateK0mzxxxzqzzdd_def
+
+//
+// Function for template "EID23" (and possibly others).
+// This function is for use by MC-generated code and should not be used directly.
+//
+#ifndef McTemplateK0mzxxxzqzztd_def
+#define McTemplateK0mzxxxzqzztd_def
+ETW_INLINE
+ULONG
+_mcgen_PASTE2(McTemplateK0mzxxxzqzztd_, MCGEN_EVENTWRITETRANSFER)(
+ _In_ PMCGEN_TRACE_CONTEXT Context,
+ _In_ PCEVENT_DESCRIPTOR Descriptor,
+ _In_opt_ const GUID* Activity,
+ _In_ const FILETIME* _Arg0,
+ _In_opt_ PCWSTR _Arg1,
+ _In_ const unsigned __int64 _Arg2,
+ _In_ const unsigned __int64 _Arg3,
+ _In_ const unsigned __int64 _Arg4,
+ _In_opt_ PCWSTR _Arg5,
+ _In_ const unsigned int _Arg6,
+ _In_opt_ PCWSTR _Arg7,
+ _In_opt_ PCWSTR _Arg8,
+ _In_ const signed int _Arg9,
+ _In_ const signed int _Arg10
+ )
+{
+#define McTemplateK0mzxxxzqzztd_ARGCOUNT 11
+
+ EVENT_DATA_DESCRIPTOR EventData[McTemplateK0mzxxxzqzztd_ARGCOUNT + 1];
+
+ EventDataDescCreate(&EventData[1],_Arg0, sizeof(FILETIME) );
+
+ EventDataDescCreate(&EventData[2],
+ (_Arg1 != NULL) ? _Arg1 : L"NULL",
+ (_Arg1 != NULL) ? (ULONG)((wcslen(_Arg1) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[3],&_Arg2, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[4],&_Arg3, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[5],&_Arg4, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[6],
+ (_Arg5 != NULL) ? _Arg5 : L"NULL",
+ (_Arg5 != NULL) ? (ULONG)((wcslen(_Arg5) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[7],&_Arg6, sizeof(const unsigned int) );
+
+ EventDataDescCreate(&EventData[8],
+ (_Arg7 != NULL) ? _Arg7 : L"NULL",
+ (_Arg7 != NULL) ? (ULONG)((wcslen(_Arg7) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[9],
+ (_Arg8 != NULL) ? _Arg8 : L"NULL",
+ (_Arg8 != NULL) ? (ULONG)((wcslen(_Arg8) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[10],&_Arg9, sizeof(const signed int) );
+
+ EventDataDescCreate(&EventData[11],&_Arg10, sizeof(const signed int) );
+
+ return McGenEventWrite(Context, Descriptor, Activity, McTemplateK0mzxxxzqzztd_ARGCOUNT + 1, EventData);
+}
+#endif // McTemplateK0mzxxxzqzztd_def
+
+//
+// Function for template "EID18" (and possibly others).
+// This function is for use by MC-generated code and should not be used directly.
+//
+#ifndef McTemplateK0mzxxxzqzzxxxzqz_def
+#define McTemplateK0mzxxxzqzzxxxzqz_def
+ETW_INLINE
+ULONG
+_mcgen_PASTE2(McTemplateK0mzxxxzqzzxxxzqz_, MCGEN_EVENTWRITETRANSFER)(
+ _In_ PMCGEN_TRACE_CONTEXT Context,
+ _In_ PCEVENT_DESCRIPTOR Descriptor,
+ _In_opt_ const GUID* Activity,
+ _In_ const FILETIME* _Arg0,
+ _In_opt_ PCWSTR _Arg1,
+ _In_ const unsigned __int64 _Arg2,
+ _In_ const unsigned __int64 _Arg3,
+ _In_ const unsigned __int64 _Arg4,
+ _In_opt_ PCWSTR _Arg5,
+ _In_ const unsigned int _Arg6,
+ _In_opt_ PCWSTR _Arg7,
+ _In_opt_ PCWSTR _Arg8,
+ _In_ const unsigned __int64 _Arg9,
+ _In_ const unsigned __int64 _Arg10,
+ _In_ const unsigned __int64 _Arg11,
+ _In_opt_ PCWSTR _Arg12,
+ _In_ const unsigned int _Arg13,
+ _In_opt_ PCWSTR _Arg14
+ )
+{
+#define McTemplateK0mzxxxzqzzxxxzqz_ARGCOUNT 15
+
+ EVENT_DATA_DESCRIPTOR EventData[McTemplateK0mzxxxzqzzxxxzqz_ARGCOUNT + 1];
+
+ EventDataDescCreate(&EventData[1],_Arg0, sizeof(FILETIME) );
+
+ EventDataDescCreate(&EventData[2],
+ (_Arg1 != NULL) ? _Arg1 : L"NULL",
+ (_Arg1 != NULL) ? (ULONG)((wcslen(_Arg1) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[3],&_Arg2, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[4],&_Arg3, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[5],&_Arg4, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[6],
+ (_Arg5 != NULL) ? _Arg5 : L"NULL",
+ (_Arg5 != NULL) ? (ULONG)((wcslen(_Arg5) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[7],&_Arg6, sizeof(const unsigned int) );
+
+ EventDataDescCreate(&EventData[8],
+ (_Arg7 != NULL) ? _Arg7 : L"NULL",
+ (_Arg7 != NULL) ? (ULONG)((wcslen(_Arg7) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[9],
+ (_Arg8 != NULL) ? _Arg8 : L"NULL",
+ (_Arg8 != NULL) ? (ULONG)((wcslen(_Arg8) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[10],&_Arg9, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[11],&_Arg10, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[12],&_Arg11, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[13],
+ (_Arg12 != NULL) ? _Arg12 : L"NULL",
+ (_Arg12 != NULL) ? (ULONG)((wcslen(_Arg12) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[14],&_Arg13, sizeof(const unsigned int) );
+
+ EventDataDescCreate(&EventData[15],
+ (_Arg14 != NULL) ? _Arg14 : L"NULL",
+ (_Arg14 != NULL) ? (ULONG)((wcslen(_Arg14) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ return McGenEventWrite(Context, Descriptor, Activity, McTemplateK0mzxxxzqzzxxxzqz_ARGCOUNT + 1, EventData);
+}
+#endif // McTemplateK0mzxxxzqzzxxxzqz_def
+
+//
+// Function for template "EID4" (and possibly others).
+// This function is for use by MC-generated code and should not be used directly.
+//
+#ifndef McTemplateK0mzxxxzzq_def
+#define McTemplateK0mzxxxzzq_def
+ETW_INLINE
+ULONG
+_mcgen_PASTE2(McTemplateK0mzxxxzzq_, MCGEN_EVENTWRITETRANSFER)(
+ _In_ PMCGEN_TRACE_CONTEXT Context,
+ _In_ PCEVENT_DESCRIPTOR Descriptor,
+ _In_opt_ const GUID* Activity,
+ _In_ const FILETIME* _Arg0,
+ _In_opt_ PCWSTR _Arg1,
+ _In_ const unsigned __int64 _Arg2,
+ _In_ const unsigned __int64 _Arg3,
+ _In_ const unsigned __int64 _Arg4,
+ _In_opt_ PCWSTR _Arg5,
+ _In_opt_ PCWSTR _Arg6,
+ _In_ const unsigned int _Arg7
+ )
+{
+#define McTemplateK0mzxxxzzq_ARGCOUNT 8
+
+ EVENT_DATA_DESCRIPTOR EventData[McTemplateK0mzxxxzzq_ARGCOUNT + 1];
+
+ EventDataDescCreate(&EventData[1],_Arg0, sizeof(FILETIME) );
+
+ EventDataDescCreate(&EventData[2],
+ (_Arg1 != NULL) ? _Arg1 : L"NULL",
+ (_Arg1 != NULL) ? (ULONG)((wcslen(_Arg1) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[3],&_Arg2, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[4],&_Arg3, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[5],&_Arg4, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[6],
+ (_Arg5 != NULL) ? _Arg5 : L"NULL",
+ (_Arg5 != NULL) ? (ULONG)((wcslen(_Arg5) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[7],
+ (_Arg6 != NULL) ? _Arg6 : L"NULL",
+ (_Arg6 != NULL) ? (ULONG)((wcslen(_Arg6) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[8],&_Arg7, sizeof(const unsigned int) );
+
+ return McGenEventWrite(Context, Descriptor, Activity, McTemplateK0mzxxxzzq_ARGCOUNT + 1, EventData);
+}
+#endif // McTemplateK0mzxxxzzq_def
+
+//
+// Function for template "EID7" (and possibly others).
+// This function is for use by MC-generated code and should not be used directly.
+//
+#ifndef McTemplateK0mzxxxzzzzzq_def
+#define McTemplateK0mzxxxzzzzzq_def
+ETW_INLINE
+ULONG
+_mcgen_PASTE2(McTemplateK0mzxxxzzzzzq_, MCGEN_EVENTWRITETRANSFER)(
+ _In_ PMCGEN_TRACE_CONTEXT Context,
+ _In_ PCEVENT_DESCRIPTOR Descriptor,
+ _In_opt_ const GUID* Activity,
+ _In_ const FILETIME* _Arg0,
+ _In_opt_ PCWSTR _Arg1,
+ _In_ const unsigned __int64 _Arg2,
+ _In_ const unsigned __int64 _Arg3,
+ _In_ const unsigned __int64 _Arg4,
+ _In_opt_ PCWSTR _Arg5,
+ _In_opt_ PCWSTR _Arg6,
+ _In_opt_ PCWSTR _Arg7,
+ _In_opt_ PCWSTR _Arg8,
+ _In_opt_ PCWSTR _Arg9,
+ _In_ const unsigned int _Arg10
+ )
+{
+#define McTemplateK0mzxxxzzzzzq_ARGCOUNT 11
+
+ EVENT_DATA_DESCRIPTOR EventData[McTemplateK0mzxxxzzzzzq_ARGCOUNT + 1];
+
+ EventDataDescCreate(&EventData[1],_Arg0, sizeof(FILETIME) );
+
+ EventDataDescCreate(&EventData[2],
+ (_Arg1 != NULL) ? _Arg1 : L"NULL",
+ (_Arg1 != NULL) ? (ULONG)((wcslen(_Arg1) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[3],&_Arg2, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[4],&_Arg3, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[5],&_Arg4, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[6],
+ (_Arg5 != NULL) ? _Arg5 : L"NULL",
+ (_Arg5 != NULL) ? (ULONG)((wcslen(_Arg5) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[7],
+ (_Arg6 != NULL) ? _Arg6 : L"NULL",
+ (_Arg6 != NULL) ? (ULONG)((wcslen(_Arg6) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[8],
+ (_Arg7 != NULL) ? _Arg7 : L"NULL",
+ (_Arg7 != NULL) ? (ULONG)((wcslen(_Arg7) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[9],
+ (_Arg8 != NULL) ? _Arg8 : L"NULL",
+ (_Arg8 != NULL) ? (ULONG)((wcslen(_Arg8) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[10],
+ (_Arg9 != NULL) ? _Arg9 : L"NULL",
+ (_Arg9 != NULL) ? (ULONG)((wcslen(_Arg9) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[11],&_Arg10, sizeof(const unsigned int) );
+
+ return McGenEventWrite(Context, Descriptor, Activity, McTemplateK0mzxxxzzzzzq_ARGCOUNT + 1, EventData);
+}
+#endif // McTemplateK0mzxxxzzzzzq_def
+
+//
+// Function for template "EID9" (and possibly others).
+// This function is for use by MC-generated code and should not be used directly.
+//
+#ifndef McTemplateK0mzxxzx_def
+#define McTemplateK0mzxxzx_def
+ETW_INLINE
+ULONG
+_mcgen_PASTE2(McTemplateK0mzxxzx_, MCGEN_EVENTWRITETRANSFER)(
+ _In_ PMCGEN_TRACE_CONTEXT Context,
+ _In_ PCEVENT_DESCRIPTOR Descriptor,
+ _In_opt_ const GUID* Activity,
+ _In_ const FILETIME* _Arg0,
+ _In_opt_ PCWSTR _Arg1,
+ _In_ const unsigned __int64 _Arg2,
+ _In_ const unsigned __int64 _Arg3,
+ _In_opt_ PCWSTR _Arg4,
+ _In_ const unsigned __int64 _Arg5
+ )
+{
+#define McTemplateK0mzxxzx_ARGCOUNT 6
+
+ EVENT_DATA_DESCRIPTOR EventData[McTemplateK0mzxxzx_ARGCOUNT + 1];
+
+ EventDataDescCreate(&EventData[1],_Arg0, sizeof(FILETIME) );
+
+ EventDataDescCreate(&EventData[2],
+ (_Arg1 != NULL) ? _Arg1 : L"NULL",
+ (_Arg1 != NULL) ? (ULONG)((wcslen(_Arg1) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[3],&_Arg2, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[4],&_Arg3, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[5],
+ (_Arg4 != NULL) ? _Arg4 : L"NULL",
+ (_Arg4 != NULL) ? (ULONG)((wcslen(_Arg4) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[6],&_Arg5, sizeof(const unsigned __int64) );
+
+ return McGenEventWrite(Context, Descriptor, Activity, McTemplateK0mzxxzx_ARGCOUNT + 1, EventData);
+}
+#endif // McTemplateK0mzxxzx_def
+
+//
+// Function for template "EID17" (and possibly others).
+// This function is for use by MC-generated code and should not be used directly.
+//
+#ifndef McTemplateK0mzxxzzxdzzzz_def
+#define McTemplateK0mzxxzzxdzzzz_def
+ETW_INLINE
+ULONG
+_mcgen_PASTE2(McTemplateK0mzxxzzxdzzzz_, MCGEN_EVENTWRITETRANSFER)(
+ _In_ PMCGEN_TRACE_CONTEXT Context,
+ _In_ PCEVENT_DESCRIPTOR Descriptor,
+ _In_opt_ const GUID* Activity,
+ _In_ const FILETIME* _Arg0,
+ _In_opt_ PCWSTR _Arg1,
+ _In_ const unsigned __int64 _Arg2,
+ _In_ const unsigned __int64 _Arg3,
+ _In_opt_ PCWSTR _Arg4,
+ _In_opt_ PCWSTR _Arg5,
+ _In_ const unsigned __int64 _Arg6,
+ _In_ const signed int _Arg7,
+ _In_opt_ PCWSTR _Arg8,
+ _In_opt_ PCWSTR _Arg9,
+ _In_opt_ PCWSTR _Arg10,
+ _In_opt_ PCWSTR _Arg11
+ )
+{
+#define McTemplateK0mzxxzzxdzzzz_ARGCOUNT 12
+
+ EVENT_DATA_DESCRIPTOR EventData[McTemplateK0mzxxzzxdzzzz_ARGCOUNT + 1];
+
+ EventDataDescCreate(&EventData[1],_Arg0, sizeof(FILETIME) );
+
+ EventDataDescCreate(&EventData[2],
+ (_Arg1 != NULL) ? _Arg1 : L"NULL",
+ (_Arg1 != NULL) ? (ULONG)((wcslen(_Arg1) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[3],&_Arg2, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[4],&_Arg3, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[5],
+ (_Arg4 != NULL) ? _Arg4 : L"NULL",
+ (_Arg4 != NULL) ? (ULONG)((wcslen(_Arg4) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[6],
+ (_Arg5 != NULL) ? _Arg5 : L"NULL",
+ (_Arg5 != NULL) ? (ULONG)((wcslen(_Arg5) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[7],&_Arg6, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[8],&_Arg7, sizeof(const signed int) );
+
+ EventDataDescCreate(&EventData[9],
+ (_Arg8 != NULL) ? _Arg8 : L"NULL",
+ (_Arg8 != NULL) ? (ULONG)((wcslen(_Arg8) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[10],
+ (_Arg9 != NULL) ? _Arg9 : L"NULL",
+ (_Arg9 != NULL) ? (ULONG)((wcslen(_Arg9) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[11],
+ (_Arg10 != NULL) ? _Arg10 : L"NULL",
+ (_Arg10 != NULL) ? (ULONG)((wcslen(_Arg10) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[12],
+ (_Arg11 != NULL) ? _Arg11 : L"NULL",
+ (_Arg11 != NULL) ? (ULONG)((wcslen(_Arg11) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ return McGenEventWrite(Context, Descriptor, Activity, McTemplateK0mzxxzzxdzzzz_ARGCOUNT + 1, EventData);
+}
+#endif // McTemplateK0mzxxzzxdzzzz_def
+
+//
+// Function for template "EID19" (and possibly others).
+// This function is for use by MC-generated code and should not be used directly.
+//
+#ifndef McTemplateK0mzzq_def
+#define McTemplateK0mzzq_def
+ETW_INLINE
+ULONG
+_mcgen_PASTE2(McTemplateK0mzzq_, MCGEN_EVENTWRITETRANSFER)(
+ _In_ PMCGEN_TRACE_CONTEXT Context,
+ _In_ PCEVENT_DESCRIPTOR Descriptor,
+ _In_opt_ const GUID* Activity,
+ _In_ const FILETIME* _Arg0,
+ _In_opt_ PCWSTR _Arg1,
+ _In_opt_ PCWSTR _Arg2,
+ _In_ const unsigned int _Arg3
+ )
+{
+#define McTemplateK0mzzq_ARGCOUNT 4
+
+ EVENT_DATA_DESCRIPTOR EventData[McTemplateK0mzzq_ARGCOUNT + 1];
+
+ EventDataDescCreate(&EventData[1],_Arg0, sizeof(FILETIME) );
+
+ EventDataDescCreate(&EventData[2],
+ (_Arg1 != NULL) ? _Arg1 : L"NULL",
+ (_Arg1 != NULL) ? (ULONG)((wcslen(_Arg1) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[3],
+ (_Arg2 != NULL) ? _Arg2 : L"NULL",
+ (_Arg2 != NULL) ? (ULONG)((wcslen(_Arg2) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[4],&_Arg3, sizeof(const unsigned int) );
+
+ return McGenEventWrite(Context, Descriptor, Activity, McTemplateK0mzzq_ARGCOUNT + 1, EventData);
+}
+#endif // McTemplateK0mzzq_def
+
+//
+// Function for template "EID28" (and possibly others).
+// This function is for use by MC-generated code and should not be used directly.
+//
+#ifndef McTemplateK0mzzqqq_def
+#define McTemplateK0mzzqqq_def
+ETW_INLINE
+ULONG
+_mcgen_PASTE2(McTemplateK0mzzqqq_, MCGEN_EVENTWRITETRANSFER)(
+ _In_ PMCGEN_TRACE_CONTEXT Context,
+ _In_ PCEVENT_DESCRIPTOR Descriptor,
+ _In_opt_ const GUID* Activity,
+ _In_ const FILETIME* _Arg0,
+ _In_opt_ PCWSTR _Arg1,
+ _In_opt_ PCWSTR _Arg2,
+ _In_ const unsigned int _Arg3,
+ _In_ const unsigned int _Arg4,
+ _In_ const unsigned int _Arg5
+ )
+{
+#define McTemplateK0mzzqqq_ARGCOUNT 6
+
+ EVENT_DATA_DESCRIPTOR EventData[McTemplateK0mzzqqq_ARGCOUNT + 1];
+
+ EventDataDescCreate(&EventData[1],_Arg0, sizeof(FILETIME) );
+
+ EventDataDescCreate(&EventData[2],
+ (_Arg1 != NULL) ? _Arg1 : L"NULL",
+ (_Arg1 != NULL) ? (ULONG)((wcslen(_Arg1) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[3],
+ (_Arg2 != NULL) ? _Arg2 : L"NULL",
+ (_Arg2 != NULL) ? (ULONG)((wcslen(_Arg2) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[4],&_Arg3, sizeof(const unsigned int) );
+
+ EventDataDescCreate(&EventData[5],&_Arg4, sizeof(const unsigned int) );
+
+ EventDataDescCreate(&EventData[6],&_Arg5, sizeof(const unsigned int) );
+
+ return McGenEventWrite(Context, Descriptor, Activity, McTemplateK0mzzqqq_ARGCOUNT + 1, EventData);
+}
+#endif // McTemplateK0mzzqqq_def
+
+//
+// Function for template "EID8" (and possibly others).
+// This function is for use by MC-generated code and should not be used directly.
+//
+#ifndef McTemplateK0mzzxxxxxzxzzzzqqq_def
+#define McTemplateK0mzzxxxxxzxzzzzqqq_def
+ETW_INLINE
+ULONG
+_mcgen_PASTE2(McTemplateK0mzzxxxxxzxzzzzqqq_, MCGEN_EVENTWRITETRANSFER)(
+ _In_ PMCGEN_TRACE_CONTEXT Context,
+ _In_ PCEVENT_DESCRIPTOR Descriptor,
+ _In_opt_ const GUID* Activity,
+ _In_ const FILETIME* _Arg0,
+ _In_opt_ PCWSTR _Arg1,
+ _In_opt_ PCWSTR _Arg2,
+ _In_ const unsigned __int64 _Arg3,
+ _In_ const unsigned __int64 _Arg4,
+ _In_ const unsigned __int64 _Arg5,
+ _In_ const unsigned __int64 _Arg6,
+ _In_ const unsigned __int64 _Arg7,
+ _In_opt_ PCWSTR _Arg8,
+ _In_ const unsigned __int64 _Arg9,
+ _In_opt_ PCWSTR _Arg10,
+ _In_opt_ PCWSTR _Arg11,
+ _In_opt_ PCWSTR _Arg12,
+ _In_opt_ PCWSTR _Arg13,
+ _In_ const unsigned int _Arg14,
+ _In_ const unsigned int _Arg15,
+ _In_ const unsigned int _Arg16
+ )
+{
+#define McTemplateK0mzzxxxxxzxzzzzqqq_ARGCOUNT 17
+
+ EVENT_DATA_DESCRIPTOR EventData[McTemplateK0mzzxxxxxzxzzzzqqq_ARGCOUNT + 1];
+
+ EventDataDescCreate(&EventData[1],_Arg0, sizeof(FILETIME) );
+
+ EventDataDescCreate(&EventData[2],
+ (_Arg1 != NULL) ? _Arg1 : L"NULL",
+ (_Arg1 != NULL) ? (ULONG)((wcslen(_Arg1) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[3],
+ (_Arg2 != NULL) ? _Arg2 : L"NULL",
+ (_Arg2 != NULL) ? (ULONG)((wcslen(_Arg2) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[4],&_Arg3, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[5],&_Arg4, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[6],&_Arg5, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[7],&_Arg6, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[8],&_Arg7, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[9],
+ (_Arg8 != NULL) ? _Arg8 : L"NULL",
+ (_Arg8 != NULL) ? (ULONG)((wcslen(_Arg8) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[10],&_Arg9, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[11],
+ (_Arg10 != NULL) ? _Arg10 : L"NULL",
+ (_Arg10 != NULL) ? (ULONG)((wcslen(_Arg10) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[12],
+ (_Arg11 != NULL) ? _Arg11 : L"NULL",
+ (_Arg11 != NULL) ? (ULONG)((wcslen(_Arg11) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[13],
+ (_Arg12 != NULL) ? _Arg12 : L"NULL",
+ (_Arg12 != NULL) ? (ULONG)((wcslen(_Arg12) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[14],
+ (_Arg13 != NULL) ? _Arg13 : L"NULL",
+ (_Arg13 != NULL) ? (ULONG)((wcslen(_Arg13) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[15],&_Arg14, sizeof(const unsigned int) );
+
+ EventDataDescCreate(&EventData[16],&_Arg15, sizeof(const unsigned int) );
+
+ EventDataDescCreate(&EventData[17],&_Arg16, sizeof(const unsigned int) );
+
+ return McGenEventWrite(Context, Descriptor, Activity, McTemplateK0mzzxxxxxzxzzzzqqq_ARGCOUNT + 1, EventData);
+}
+#endif // McTemplateK0mzzxxxxxzxzzzzqqq_def
+
+//
+// Function for template "EID1" (and possibly others).
+// This function is for use by MC-generated code and should not be used directly.
+//
+#ifndef McTemplateK0mzzxxxzqxxzxzq_def
+#define McTemplateK0mzzxxxzqxxzxzq_def
+ETW_INLINE
+ULONG
+_mcgen_PASTE2(McTemplateK0mzzxxxzqxxzxzq_, MCGEN_EVENTWRITETRANSFER)(
+ _In_ PMCGEN_TRACE_CONTEXT Context,
+ _In_ PCEVENT_DESCRIPTOR Descriptor,
+ _In_opt_ const GUID* Activity,
+ _In_ const FILETIME* _Arg0,
+ _In_opt_ PCWSTR _Arg1,
+ _In_opt_ PCWSTR _Arg2,
+ _In_ const unsigned __int64 _Arg3,
+ _In_ const unsigned __int64 _Arg4,
+ _In_ const unsigned __int64 _Arg5,
+ _In_opt_ PCWSTR _Arg6,
+ _In_ const unsigned int _Arg7,
+ _In_ const unsigned __int64 _Arg8,
+ _In_ const unsigned __int64 _Arg9,
+ _In_opt_ PCWSTR _Arg10,
+ _In_ const unsigned __int64 _Arg11,
+ _In_opt_ PCWSTR _Arg12,
+ _In_ const unsigned int _Arg13
+ )
+{
+#define McTemplateK0mzzxxxzqxxzxzq_ARGCOUNT 14
+
+ EVENT_DATA_DESCRIPTOR EventData[McTemplateK0mzzxxxzqxxzxzq_ARGCOUNT + 1];
+
+ EventDataDescCreate(&EventData[1],_Arg0, sizeof(FILETIME) );
+
+ EventDataDescCreate(&EventData[2],
+ (_Arg1 != NULL) ? _Arg1 : L"NULL",
+ (_Arg1 != NULL) ? (ULONG)((wcslen(_Arg1) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[3],
+ (_Arg2 != NULL) ? _Arg2 : L"NULL",
+ (_Arg2 != NULL) ? (ULONG)((wcslen(_Arg2) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[4],&_Arg3, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[5],&_Arg4, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[6],&_Arg5, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[7],
+ (_Arg6 != NULL) ? _Arg6 : L"NULL",
+ (_Arg6 != NULL) ? (ULONG)((wcslen(_Arg6) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[8],&_Arg7, sizeof(const unsigned int) );
+
+ EventDataDescCreate(&EventData[9],&_Arg8, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[10],&_Arg9, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[11],
+ (_Arg10 != NULL) ? _Arg10 : L"NULL",
+ (_Arg10 != NULL) ? (ULONG)((wcslen(_Arg10) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[12],&_Arg11, sizeof(const unsigned __int64) );
+
+ EventDataDescCreate(&EventData[13],
+ (_Arg12 != NULL) ? _Arg12 : L"NULL",
+ (_Arg12 != NULL) ? (ULONG)((wcslen(_Arg12) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[14],&_Arg13, sizeof(const unsigned int) );
+
+ return McGenEventWrite(Context, Descriptor, Activity, McTemplateK0mzzxxxzqxxzxzq_ARGCOUNT + 1, EventData);
+}
+#endif // McTemplateK0mzzxxxzqxxzxzq_def
+
+//
+// Function for template "EID25" (and possibly others).
+// This function is for use by MC-generated code and should not be used directly.
+//
+#ifndef McTemplateK0mzzzz_def
+#define McTemplateK0mzzzz_def
+ETW_INLINE
+ULONG
+_mcgen_PASTE2(McTemplateK0mzzzz_, MCGEN_EVENTWRITETRANSFER)(
+ _In_ PMCGEN_TRACE_CONTEXT Context,
+ _In_ PCEVENT_DESCRIPTOR Descriptor,
+ _In_opt_ const GUID* Activity,
+ _In_ const FILETIME* _Arg0,
+ _In_opt_ PCWSTR _Arg1,
+ _In_opt_ PCWSTR _Arg2,
+ _In_opt_ PCWSTR _Arg3,
+ _In_opt_ PCWSTR _Arg4
+ )
+{
+#define McTemplateK0mzzzz_ARGCOUNT 5
+
+ EVENT_DATA_DESCRIPTOR EventData[McTemplateK0mzzzz_ARGCOUNT + 1];
+
+ EventDataDescCreate(&EventData[1],_Arg0, sizeof(FILETIME) );
+
+ EventDataDescCreate(&EventData[2],
+ (_Arg1 != NULL) ? _Arg1 : L"NULL",
+ (_Arg1 != NULL) ? (ULONG)((wcslen(_Arg1) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[3],
+ (_Arg2 != NULL) ? _Arg2 : L"NULL",
+ (_Arg2 != NULL) ? (ULONG)((wcslen(_Arg2) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[4],
+ (_Arg3 != NULL) ? _Arg3 : L"NULL",
+ (_Arg3 != NULL) ? (ULONG)((wcslen(_Arg3) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ EventDataDescCreate(&EventData[5],
+ (_Arg4 != NULL) ? _Arg4 : L"NULL",
+ (_Arg4 != NULL) ? (ULONG)((wcslen(_Arg4) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL"));
+
+ return McGenEventWrite(Context, Descriptor, Activity, McTemplateK0mzzzz_ARGCOUNT + 1, EventData);
+}
+#endif // McTemplateK0mzzzz_def
+
+#endif // MCGEN_DISABLE_PROVIDER_CODE_GENERATION
+
+#if defined(__cplusplus)
+}
+#endif
+
+#define MSG_ProcessCreation_EventMessage 0xB0000001L
+#define MSG_ProcessAccess_EventMessage 0xB0000002L
+#define MSG_ProcessAccessDuplicated_EventMessage 0xB0000003L
+#define MSG_ImageLoaded_EventMessage 0xB0000004L
+#define MSG_RegistryCreateKey_EventMessage 0xB0000005L
+#define MSG_RegistryDeleteKey_EventMessage 0xB0000006L
+#define MSG_RegistrySetValue_EventMessage 0xB0000007L
+#define MSG_ProcessReparenting_EventMessage 0xB0000008L
+#define MSG_ProcessTerminate_EventMessage 0xB0000009L
+#define MSG_FileRename_EventMessage 0xB000000AL
+#define MSG_RPCClientCall_EventMessage 0xB000000BL
+#define MSG_RPCServerCall_EventMessage 0xB000000CL
+#define MSG_NetworkConnectionAccepted_EventMessage 0xB000000DL
+#define MSG_RegistrySaveKey_EventMessage 0xB000000EL
+#define MSG_DotNetLoad_EventMessage 0xB000000FL
+#define MSG_AMSI_EventMessage 0xB0000010L
+#define MSG_ImpersonationAction_EventMessage 0xB0000011L
+#define MSG_RemoteThreadCreation_EventMessage 0xB0000012L
+#define MSG_SchedTaskCreation_EventMessage 0xB0000013L
+#define MSG_SchedTaskStarted_EventMessage 0xB0000014L
+#define MSG_FileCreate_EventMessage 0xB0000015L
+#define MSG_FileDelete_EventMessage 0xB0000016L
+#define MSG_NamedPipeCreate_EventMessage 0xB0000017L
+#define MSG_NamedPipeOpen_EventMessage 0xB0000018L
+#define MSG_WMIFilterToConsumerBinding_EventMessage 0xB0000019L
+#define MSG_TIQueueUserAPCEvent_EventMessage 0xB000001AL
+#define MSG_DriverLoad_EventMessage 0xB000001BL
+#define MSG_DPAPI_EventMessage 0xB000001CL
+#define MSG_TIWriteProcessMemory_EventMessage 0xB000001DL
+#define MSG_TIReadProcessMemory_EventMessage 0xB000001EL
+#define MSG_ThreadTokenImpersonation_EventMessage 0xB000001FL
+#define MSG_TIRemoteAllocateVirtualMemory_EventMessage 0xB0000020L
diff --git a/JonMonProvider/jonmon.man b/JonMonProvider/jonmon.man
new file mode 100644
index 0000000..13396c3
--- /dev/null
+++ b/JonMonProvider/jonmon.man
@@ -0,0 +1,1845 @@
+
+
+
+
+
+
+
+
+ 67112660
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/JonMonProvider/jonmon.rc b/JonMonProvider/jonmon.rc
new file mode 100644
index 0000000..e444710
--- /dev/null
+++ b/JonMonProvider/jonmon.rc
@@ -0,0 +1,3 @@
+LANGUAGE 0x9,0x1
+1 11 "MSG00001.bin"
+1 WEVT_TEMPLATE "jonmonTEMP.BIN"
diff --git a/JonMonProvider/jonmon.res b/JonMonProvider/jonmon.res
new file mode 100644
index 0000000..8a02b4c
Binary files /dev/null and b/JonMonProvider/jonmon.res differ
diff --git a/JonMonProvider/jonmonTEMP.BIN b/JonMonProvider/jonmonTEMP.BIN
new file mode 100644
index 0000000..265db30
Binary files /dev/null and b/JonMonProvider/jonmonTEMP.BIN differ
diff --git a/README.md b/README.md
index 9f266e8..6bb9589 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,39 @@
-# JonMon
\ No newline at end of file
+# JonMon (Beta)
+JonMon is a research project I started to help me learn how to code and understand telemetry mechanisms. It is a collection of open-source telemetry sensors designed to provide users with visibility into the operations and activity of their Windows systems. JonMon has a kernel-level driver component, which is designed to collect information related to system operations such as process creation, registry operations, file creates and more.
+
+In addition to the kernel-level driver component, JonMon also features a user-mode component that collects information about .NET, RPC, network activity, and other important system events. By combining data from both the kernel-level and user-mode components, JonMon provides users with a comprehensive view of their security activity.
+
+The data collected by both components is made easily accessible to users through the Windows event log, allowing users to quickly and easily query the data and gain insights into their system operations.
+
+JonMon started and will continue to be a researech project that allows for easy telemetry testing and verification.
+
+## Disclaimer
+JonMon is currently in Beta release. The project is stable enough to release, but there may be improvements and bugs to fix before V1 is released. Please submit any bug issues as they arise!
+
+This code is not meant to be ran in production environments and is not guaranteed to work. This is an educational/research project only.
+
+Being that this is a project to help me learn how to code, I understand some things will not be perfect and there will be bugs. Issues are welcome, but may not always be addressed.
+
+# JonMon Guide
+For all things on JonMon, please visit the [wiki](https://github.com/jsecurity101/JonMon/wiki#installation).
+
+# Credit
+This project wouldn't be possible without many great people and projects. A special thank you to the following who had direct impact on this project:
+* Coding Help/Understanding:
+ * [Pavel Yosifovich](https://twitter.com/zodiacon)
+ * Helping me understand different coding concepts
+ * [Evan McBroom](https://twitter.com/mcbroom_evan)
+ * General coding help
+ * [Connor McGarr](https://twitter.com/33y0re)
+ * Helping me understand proper coding practices (especially in the kernel)
+ * [Yarden Shafir](https://twitter.com/yarden_shafir)
+ * Answering random questions and also hyping me up
+* Beta Testers
+ * [Roberto Rodriguez](https://twitter.com/Cyb3rWard0g)
+ * [Olaf Hartong](https://twitter.com/olafhartong)
+ * [Andrew Schwartz](https://twitter.com/4ndr3w6S)
+* Courses/Books
+ * [Pavel Yosifovich](https://twitter.com/zodiacon)
+ * Kernel Programming Book and Course
+ * Pavel's course is what got me interested in this project. A big thank you to him for his teaching!
+