1010 lines
27 KiB
C++
Executable File
1010 lines
27 KiB
C++
Executable File
#pragma once
|
|
|
|
//
|
|
// Windows
|
|
//
|
|
#define WIN32_LEAN_AND_MEAN
|
|
#define WIN32_NO_STATUS
|
|
#include <Windows.h>
|
|
#undef WIN32_NO_STATUS
|
|
#include <ntstatus.h>
|
|
#include <strsafe.h>
|
|
#include <winioctl.h>
|
|
#include <bcrypt.h>
|
|
|
|
//
|
|
// STL
|
|
//
|
|
#include <iomanip>
|
|
#include <sstream>
|
|
#include <vector>
|
|
#include <optional>
|
|
#include <span>
|
|
|
|
//
|
|
// Common Macros/Defines/Usings
|
|
//
|
|
#define SCAST(_X_) static_cast<_X_>
|
|
#define RCAST(_X_) reinterpret_cast<_X_>
|
|
#define Add2Ptr(_P_, _X_) RCAST(void*)(RCAST(uintptr_t)(_P_) + _X_)
|
|
|
|
using handle_t = HANDLE;
|
|
|
|
#define _REPORT(msg, err) dprintf(msg " (%S)", Utils::FormatError(err).c_str())
|
|
#define REPORT_AND_RETURN_WIN32(message, win32err) _REPORT(message, win32err); return HRESULT_FROM_WIN32(win32err);
|
|
#define REPORT_AND_RETURN_NT(message, status) _REPORT(message, status); return HRESULT_FROM_NT(status);
|
|
#define REPORT_AND_RETURN_HR(message, hr) _REPORT(message, hr); return hr;
|
|
//
|
|
// prefast suppression
|
|
//
|
|
#pragma warning(disable : 6319) // prefast: use of the comma-operator in a tested expression
|
|
|
|
#ifdef DEBUGTRACE
|
|
#define dprintf(...) real_dprintf(__VA_ARGS__)
|
|
static void real_dprintf(const char* format, ...)
|
|
{
|
|
va_list args;
|
|
char buffer[1024];
|
|
va_start(args, format);
|
|
vsnprintf_s(buffer, sizeof(buffer), sizeof(buffer) - 3, format, args);
|
|
strcat_s(buffer, sizeof(buffer), "\r\n");
|
|
OutputDebugStringA(buffer);
|
|
va_end(args); // Needed as according to http://www.cplusplus.com/reference/cstdarg/va_start/
|
|
// one should always call va_end in the same function one calls va_start.
|
|
}
|
|
#else
|
|
#define dprintf(...)
|
|
#endif
|
|
|
|
#define FILE_MAX_PATH 260
|
|
|
|
#pragma warning(push)
|
|
#pragma warning(disable : 4201) // nameless struct/union
|
|
#pragma warning(disable : 4324) // structure was padded due to __declspec(align())
|
|
#pragma warning(disable : 4471) // a forward declaration of an unscoped enumeration
|
|
#pragma warning(disable : 28253) // prefast: inconsistent annotation
|
|
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
|
|
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
|
|
|
|
typedef struct _UNICODE_STRING
|
|
{
|
|
USHORT Length;
|
|
USHORT MaximumLength;
|
|
_Field_size_bytes_part_(MaximumLength, Length) PWCH Buffer;
|
|
} UNICODE_STRING, * PUNICODE_STRING;
|
|
|
|
typedef struct _OBJECT_ATTRIBUTES
|
|
{
|
|
ULONG Length;
|
|
HANDLE RootDirectory;
|
|
PUNICODE_STRING ObjectName;
|
|
ULONG Attributes;
|
|
PVOID SecurityDescriptor; // PSECURITY_DESCRIPTOR;
|
|
PVOID SecurityQualityOfService; // PSECURITY_QUALITY_OF_SERVICE
|
|
} OBJECT_ATTRIBUTES, * POBJECT_ATTRIBUTES;
|
|
|
|
typedef LONG KPRIORITY;
|
|
|
|
typedef struct _PEB_LDR_DATA
|
|
{
|
|
ULONG Length;
|
|
BOOLEAN Initialized;
|
|
HANDLE SsHandle;
|
|
LIST_ENTRY InLoadOrderModuleList;
|
|
LIST_ENTRY InMemoryOrderModuleList;
|
|
LIST_ENTRY InInitializationOrderModuleList;
|
|
PVOID EntryInProgress;
|
|
BOOLEAN ShutdownInProgress;
|
|
HANDLE ShutdownThreadId;
|
|
} PEB_LDR_DATA, * PPEB_LDR_DATA;
|
|
|
|
typedef struct _STRING
|
|
{
|
|
USHORT Length;
|
|
USHORT MaximumLength;
|
|
_Field_size_bytes_part_opt_(MaximumLength, Length) PCHAR Buffer;
|
|
} STRING, * PSTRING, ANSI_STRING, * PANSI_STRING, OEM_STRING, * POEM_STRING;
|
|
|
|
typedef struct _RTL_DRIVE_LETTER_CURDIR
|
|
{
|
|
USHORT Flags;
|
|
USHORT Length;
|
|
ULONG TimeStamp;
|
|
STRING DosPath;
|
|
} RTL_DRIVE_LETTER_CURDIR, * PRTL_DRIVE_LETTER_CURDIR;
|
|
|
|
typedef struct _CURDIR
|
|
{
|
|
UNICODE_STRING DosPath;
|
|
HANDLE Handle;
|
|
} CURDIR, * PCURDIR;
|
|
|
|
#define RTL_MAX_DRIVE_LETTERS 32
|
|
|
|
typedef struct _RTL_USER_PROCESS_PARAMETERS
|
|
{
|
|
ULONG MaximumLength;
|
|
ULONG Length;
|
|
|
|
ULONG Flags;
|
|
ULONG DebugFlags;
|
|
|
|
HANDLE ConsoleHandle;
|
|
ULONG ConsoleFlags;
|
|
HANDLE StandardInput;
|
|
HANDLE StandardOutput;
|
|
HANDLE StandardError;
|
|
|
|
CURDIR CurrentDirectory;
|
|
UNICODE_STRING DllPath;
|
|
UNICODE_STRING ImagePathName;
|
|
UNICODE_STRING CommandLine;
|
|
PVOID Environment;
|
|
|
|
ULONG StartingX;
|
|
ULONG StartingY;
|
|
ULONG CountX;
|
|
ULONG CountY;
|
|
ULONG CountCharsX;
|
|
ULONG CountCharsY;
|
|
ULONG FillAttribute;
|
|
|
|
ULONG WindowFlags;
|
|
ULONG ShowWindowFlags;
|
|
UNICODE_STRING WindowTitle;
|
|
UNICODE_STRING DesktopInfo;
|
|
UNICODE_STRING ShellInfo;
|
|
UNICODE_STRING RuntimeData;
|
|
RTL_DRIVE_LETTER_CURDIR CurrentDirectories[RTL_MAX_DRIVE_LETTERS];
|
|
|
|
ULONG_PTR EnvironmentSize;
|
|
ULONG_PTR EnvironmentVersion;
|
|
PVOID PackageDependencyData;
|
|
ULONG ProcessGroupId;
|
|
ULONG LoaderThreads;
|
|
|
|
UNICODE_STRING RedirectionDllName; // REDSTONE4
|
|
UNICODE_STRING HeapPartitionName; // 19H1
|
|
ULONG_PTR DefaultThreadpoolCpuSetMasks;
|
|
ULONG DefaultThreadpoolCpuSetMaskCount;
|
|
} RTL_USER_PROCESS_PARAMETERS, * PRTL_USER_PROCESS_PARAMETERS;
|
|
|
|
typedef struct _API_SET_NAMESPACE
|
|
{
|
|
ULONG Version;
|
|
ULONG Size;
|
|
ULONG Flags;
|
|
ULONG Count;
|
|
ULONG EntryOffset;
|
|
ULONG HashOffset;
|
|
ULONG HashFactor;
|
|
} API_SET_NAMESPACE, * PAPI_SET_NAMESPACE;
|
|
|
|
#define GDI_HANDLE_BUFFER_SIZE32 34
|
|
#define GDI_HANDLE_BUFFER_SIZE64 60
|
|
|
|
#ifndef _WIN64
|
|
#define GDI_HANDLE_BUFFER_SIZE GDI_HANDLE_BUFFER_SIZE32
|
|
#else
|
|
#define GDI_HANDLE_BUFFER_SIZE GDI_HANDLE_BUFFER_SIZE64
|
|
#endif
|
|
|
|
typedef ULONG GDI_HANDLE_BUFFER[GDI_HANDLE_BUFFER_SIZE];
|
|
|
|
typedef struct _PEB
|
|
{
|
|
BOOLEAN InheritedAddressSpace;
|
|
BOOLEAN ReadImageFileExecOptions;
|
|
BOOLEAN BeingDebugged;
|
|
union
|
|
{
|
|
BOOLEAN BitField;
|
|
struct
|
|
{
|
|
BOOLEAN ImageUsesLargePages : 1;
|
|
BOOLEAN IsProtectedProcess : 1;
|
|
BOOLEAN IsImageDynamicallyRelocated : 1;
|
|
BOOLEAN SkipPatchingUser32Forwarders : 1;
|
|
BOOLEAN IsPackagedProcess : 1;
|
|
BOOLEAN IsAppContainer : 1;
|
|
BOOLEAN IsProtectedProcessLight : 1;
|
|
BOOLEAN IsLongPathAwareProcess : 1;
|
|
};
|
|
};
|
|
|
|
HANDLE Mutant;
|
|
|
|
PVOID ImageBaseAddress;
|
|
PPEB_LDR_DATA Ldr;
|
|
PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
|
|
PVOID SubSystemData;
|
|
PVOID ProcessHeap;
|
|
PRTL_CRITICAL_SECTION FastPebLock;
|
|
PVOID IFEOKey;
|
|
PSLIST_HEADER AtlThunkSListPtr;
|
|
union
|
|
{
|
|
ULONG CrossProcessFlags;
|
|
struct
|
|
{
|
|
ULONG ProcessInJob : 1;
|
|
ULONG ProcessInitializing : 1;
|
|
ULONG ProcessUsingVEH : 1;
|
|
ULONG ProcessUsingVCH : 1;
|
|
ULONG ProcessUsingFTH : 1;
|
|
ULONG ProcessPreviouslyThrottled : 1;
|
|
ULONG ProcessCurrentlyThrottled : 1;
|
|
ULONG ProcessImagesHotPatched : 1; // REDSTONE5
|
|
ULONG ReservedBits0 : 24;
|
|
};
|
|
};
|
|
union
|
|
{
|
|
PVOID KernelCallbackTable;
|
|
PVOID UserSharedInfoPtr;
|
|
};
|
|
ULONG SystemReserved;
|
|
ULONG AtlThunkSListPtr32;
|
|
PAPI_SET_NAMESPACE ApiSetMap;
|
|
ULONG TlsExpansionCounter;
|
|
PVOID TlsBitmap;
|
|
ULONG TlsBitmapBits[2];
|
|
|
|
PVOID ReadOnlySharedMemoryBase;
|
|
PVOID SharedData; // HotpatchInformation
|
|
PVOID* ReadOnlyStaticServerData;
|
|
|
|
PVOID AnsiCodePageData; // PCPTABLEINFO
|
|
PVOID OemCodePageData; // PCPTABLEINFO
|
|
PVOID UnicodeCaseTableData; // PNLSTABLEINFO
|
|
|
|
ULONG NumberOfProcessors;
|
|
ULONG NtGlobalFlag;
|
|
|
|
ULARGE_INTEGER CriticalSectionTimeout;
|
|
SIZE_T HeapSegmentReserve;
|
|
SIZE_T HeapSegmentCommit;
|
|
SIZE_T HeapDeCommitTotalFreeThreshold;
|
|
SIZE_T HeapDeCommitFreeBlockThreshold;
|
|
|
|
ULONG NumberOfHeaps;
|
|
ULONG MaximumNumberOfHeaps;
|
|
PVOID* ProcessHeaps; // PHEAP
|
|
|
|
PVOID GdiSharedHandleTable;
|
|
PVOID ProcessStarterHelper;
|
|
ULONG GdiDCAttributeList;
|
|
|
|
PRTL_CRITICAL_SECTION LoaderLock;
|
|
|
|
ULONG OSMajorVersion;
|
|
ULONG OSMinorVersion;
|
|
USHORT OSBuildNumber;
|
|
USHORT OSCSDVersion;
|
|
ULONG OSPlatformId;
|
|
ULONG ImageSubsystem;
|
|
ULONG ImageSubsystemMajorVersion;
|
|
ULONG ImageSubsystemMinorVersion;
|
|
ULONG_PTR ActiveProcessAffinityMask;
|
|
GDI_HANDLE_BUFFER GdiHandleBuffer;
|
|
PVOID PostProcessInitRoutine;
|
|
|
|
PVOID TlsExpansionBitmap;
|
|
ULONG TlsExpansionBitmapBits[32];
|
|
|
|
ULONG SessionId;
|
|
|
|
ULARGE_INTEGER AppCompatFlags;
|
|
ULARGE_INTEGER AppCompatFlagsUser;
|
|
PVOID pShimData;
|
|
PVOID AppCompatInfo; // APPCOMPAT_EXE_DATA
|
|
|
|
UNICODE_STRING CSDVersion;
|
|
|
|
PVOID ActivationContextData; // ACTIVATION_CONTEXT_DATA
|
|
PVOID ProcessAssemblyStorageMap; // ASSEMBLY_STORAGE_MAP
|
|
PVOID SystemDefaultActivationContextData; // ACTIVATION_CONTEXT_DATA
|
|
PVOID SystemAssemblyStorageMap; // ASSEMBLY_STORAGE_MAP
|
|
|
|
SIZE_T MinimumStackCommit;
|
|
|
|
PVOID SparePointers[4]; // 19H1 (previously FlsCallback to FlsHighIndex)
|
|
ULONG SpareUlongs[5]; // 19H1
|
|
//PVOID* FlsCallback;
|
|
//LIST_ENTRY FlsListHead;
|
|
//PVOID FlsBitmap;
|
|
//ULONG FlsBitmapBits[FLS_MAXIMUM_AVAILABLE / (sizeof(ULONG) * 8)];
|
|
//ULONG FlsHighIndex;
|
|
|
|
PVOID WerRegistrationData;
|
|
PVOID WerShipAssertPtr;
|
|
PVOID pUnused; // pContextData
|
|
PVOID pImageHeaderHash;
|
|
union
|
|
{
|
|
ULONG TracingFlags;
|
|
struct
|
|
{
|
|
ULONG HeapTracingEnabled : 1;
|
|
ULONG CritSecTracingEnabled : 1;
|
|
ULONG LibLoaderTracingEnabled : 1;
|
|
ULONG SpareTracingBits : 29;
|
|
};
|
|
};
|
|
ULONGLONG CsrServerReadOnlySharedMemoryBase;
|
|
PRTL_CRITICAL_SECTION TppWorkerpListLock;
|
|
LIST_ENTRY TppWorkerpList;
|
|
PVOID WaitOnAddressHashTable[128];
|
|
PVOID TelemetryCoverageHeader; // REDSTONE3
|
|
ULONG CloudFileFlags;
|
|
ULONG CloudFileDiagFlags; // REDSTONE4
|
|
CHAR PlaceholderCompatibilityMode;
|
|
CHAR PlaceholderCompatibilityModeReserved[7];
|
|
struct _LEAP_SECOND_DATA* LeapSecondData; // REDSTONE5
|
|
union
|
|
{
|
|
ULONG LeapSecondFlags;
|
|
struct
|
|
{
|
|
ULONG SixtySecondEnabled : 1;
|
|
ULONG Reserved : 31;
|
|
};
|
|
};
|
|
ULONG NtGlobalFlag2;
|
|
} PEB, * PPEB;
|
|
|
|
typedef struct _PROCESS_BASIC_INFORMATION
|
|
{
|
|
NTSTATUS ExitStatus;
|
|
PPEB PebBaseAddress;
|
|
ULONG_PTR AffinityMask;
|
|
KPRIORITY BasePriority;
|
|
HANDLE UniqueProcessId;
|
|
HANDLE InheritedFromUniqueProcessId;
|
|
} PROCESS_BASIC_INFORMATION, * PPROCESS_BASIC_INFORMATION;
|
|
|
|
typedef struct _PS_ATTRIBUTE
|
|
{
|
|
ULONG_PTR Attribute;
|
|
SIZE_T Size;
|
|
union
|
|
{
|
|
ULONG_PTR Value;
|
|
PVOID ValuePtr;
|
|
};
|
|
PSIZE_T ReturnLength;
|
|
} PS_ATTRIBUTE, * PPS_ATTRIBUTE;
|
|
|
|
typedef struct _PS_ATTRIBUTE_LIST
|
|
{
|
|
SIZE_T TotalLength;
|
|
PS_ATTRIBUTE Attributes[1];
|
|
} PS_ATTRIBUTE_LIST, * PPS_ATTRIBUTE_LIST;
|
|
|
|
typedef struct _CLIENT_ID
|
|
{
|
|
HANDLE UniqueProcess;
|
|
HANDLE UniqueThread;
|
|
} CLIENT_ID, * PCLIENT_ID;
|
|
|
|
typedef struct _ACTIVATION_CONTEXT_STACK
|
|
{
|
|
struct _RTL_ACTIVATION_CONTEXT_STACK_FRAME* ActiveFrame;
|
|
LIST_ENTRY FrameListCache;
|
|
ULONG Flags;
|
|
ULONG NextCookieSequenceNumber;
|
|
ULONG StackId;
|
|
} ACTIVATION_CONTEXT_STACK, * PACTIVATION_CONTEXT_STACK;
|
|
|
|
#define GDI_BATCH_BUFFER_SIZE 310
|
|
|
|
typedef struct _GDI_TEB_BATCH
|
|
{
|
|
ULONG Offset;
|
|
ULONG_PTR HDC;
|
|
ULONG Buffer[GDI_BATCH_BUFFER_SIZE];
|
|
} GDI_TEB_BATCH, * PGDI_TEB_BATCH;
|
|
|
|
typedef struct _TEB_ACTIVE_FRAME_CONTEXT
|
|
{
|
|
ULONG Flags;
|
|
PSTR FrameName;
|
|
} TEB_ACTIVE_FRAME_CONTEXT, * PTEB_ACTIVE_FRAME_CONTEXT;
|
|
|
|
typedef struct _TEB_ACTIVE_FRAME
|
|
{
|
|
ULONG Flags;
|
|
struct _TEB_ACTIVE_FRAME* Previous;
|
|
PTEB_ACTIVE_FRAME_CONTEXT Context;
|
|
} TEB_ACTIVE_FRAME, * PTEB_ACTIVE_FRAME;
|
|
|
|
typedef struct _TEB
|
|
{
|
|
NT_TIB NtTib;
|
|
|
|
PVOID EnvironmentPointer;
|
|
CLIENT_ID ClientId;
|
|
PVOID ActiveRpcHandle;
|
|
PVOID ThreadLocalStoragePointer;
|
|
PPEB ProcessEnvironmentBlock;
|
|
|
|
ULONG LastErrorValue;
|
|
ULONG CountOfOwnedCriticalSections;
|
|
PVOID CsrClientThread;
|
|
PVOID Win32ThreadInfo;
|
|
ULONG User32Reserved[26];
|
|
ULONG UserReserved[5];
|
|
PVOID WOW32Reserved;
|
|
LCID CurrentLocale;
|
|
ULONG FpSoftwareStatusRegister;
|
|
PVOID ReservedForDebuggerInstrumentation[16];
|
|
#ifdef _WIN64
|
|
PVOID SystemReserved1[30];
|
|
#else
|
|
PVOID SystemReserved1[26];
|
|
#endif
|
|
|
|
CHAR PlaceholderCompatibilityMode;
|
|
CHAR PlaceholderReserved[11];
|
|
ULONG ProxiedProcessId;
|
|
ACTIVATION_CONTEXT_STACK ActivationStack;
|
|
|
|
UCHAR WorkingOnBehalfTicket[8];
|
|
NTSTATUS ExceptionCode;
|
|
|
|
PACTIVATION_CONTEXT_STACK ActivationContextStackPointer;
|
|
ULONG_PTR InstrumentationCallbackSp;
|
|
ULONG_PTR InstrumentationCallbackPreviousPc;
|
|
ULONG_PTR InstrumentationCallbackPreviousSp;
|
|
#ifdef _WIN64
|
|
ULONG TxFsContext;
|
|
#endif
|
|
|
|
BOOLEAN InstrumentationCallbackDisabled;
|
|
#ifndef _WIN64
|
|
UCHAR SpareBytes[23];
|
|
ULONG TxFsContext;
|
|
#endif
|
|
GDI_TEB_BATCH GdiTebBatch;
|
|
CLIENT_ID RealClientId;
|
|
HANDLE GdiCachedProcessHandle;
|
|
ULONG GdiClientPID;
|
|
ULONG GdiClientTID;
|
|
PVOID GdiThreadLocalInfo;
|
|
ULONG_PTR Win32ClientInfo[62];
|
|
PVOID glDispatchTable[233];
|
|
ULONG_PTR glReserved1[29];
|
|
PVOID glReserved2;
|
|
PVOID glSectionInfo;
|
|
PVOID glSection;
|
|
PVOID glTable;
|
|
PVOID glCurrentRC;
|
|
PVOID glContext;
|
|
|
|
NTSTATUS LastStatusValue;
|
|
UNICODE_STRING StaticUnicodeString;
|
|
WCHAR StaticUnicodeBuffer[261];
|
|
|
|
PVOID DeallocationStack;
|
|
PVOID TlsSlots[64];
|
|
LIST_ENTRY TlsLinks;
|
|
|
|
PVOID Vdm;
|
|
PVOID ReservedForNtRpc;
|
|
PVOID DbgSsReserved[2];
|
|
|
|
ULONG HardErrorMode;
|
|
#ifdef _WIN64
|
|
PVOID Instrumentation[11];
|
|
#else
|
|
PVOID Instrumentation[9];
|
|
#endif
|
|
GUID ActivityId;
|
|
|
|
PVOID SubProcessTag;
|
|
PVOID PerflibData;
|
|
PVOID EtwTraceData;
|
|
PVOID WinSockData;
|
|
ULONG GdiBatchCount;
|
|
|
|
union
|
|
{
|
|
PROCESSOR_NUMBER CurrentIdealProcessor;
|
|
ULONG IdealProcessorValue;
|
|
struct
|
|
{
|
|
UCHAR ReservedPad0;
|
|
UCHAR ReservedPad1;
|
|
UCHAR ReservedPad2;
|
|
UCHAR IdealProcessor;
|
|
};
|
|
};
|
|
|
|
ULONG GuaranteedStackBytes;
|
|
PVOID ReservedForPerf;
|
|
PVOID ReservedForOle;
|
|
ULONG WaitingOnLoaderLock;
|
|
PVOID SavedPriorityState;
|
|
ULONG_PTR ReservedForCodeCoverage;
|
|
PVOID ThreadPoolData;
|
|
PVOID* TlsExpansionSlots;
|
|
#ifdef _WIN64
|
|
PVOID DeallocationBStore;
|
|
PVOID BStoreLimit;
|
|
#endif
|
|
ULONG MuiGeneration;
|
|
ULONG IsImpersonating;
|
|
PVOID NlsCache;
|
|
PVOID pShimData;
|
|
USHORT HeapVirtualAffinity;
|
|
USHORT LowFragHeapDataSlot;
|
|
HANDLE CurrentTransactionHandle;
|
|
PTEB_ACTIVE_FRAME ActiveFrame;
|
|
PVOID FlsData;
|
|
|
|
PVOID PreferredLanguages;
|
|
PVOID UserPrefLanguages;
|
|
PVOID MergedPrefLanguages;
|
|
ULONG MuiImpersonation;
|
|
|
|
union
|
|
{
|
|
USHORT CrossTebFlags;
|
|
USHORT SpareCrossTebBits : 16;
|
|
};
|
|
union
|
|
{
|
|
USHORT SameTebFlags;
|
|
struct
|
|
{
|
|
USHORT SafeThunkCall : 1;
|
|
USHORT InDebugPrint : 1;
|
|
USHORT HasFiberData : 1;
|
|
USHORT SkipThreadAttach : 1;
|
|
USHORT WerInShipAssertCode : 1;
|
|
USHORT RanProcessInit : 1;
|
|
USHORT ClonedThread : 1;
|
|
USHORT SuppressDebugMsg : 1;
|
|
USHORT DisableUserStackWalk : 1;
|
|
USHORT RtlExceptionAttached : 1;
|
|
USHORT InitialThread : 1;
|
|
USHORT SessionAware : 1;
|
|
USHORT LoadOwner : 1;
|
|
USHORT LoaderWorker : 1;
|
|
USHORT SkipLoaderInit : 1;
|
|
USHORT SpareSameTebBits : 1;
|
|
};
|
|
};
|
|
|
|
PVOID TxnScopeEnterCallback;
|
|
PVOID TxnScopeExitCallback;
|
|
PVOID TxnScopeContext;
|
|
ULONG LockCount;
|
|
LONG WowTebOffset;
|
|
PVOID ResourceRetValue;
|
|
PVOID ReservedForWdf;
|
|
ULONGLONG ReservedForCrt;
|
|
GUID EffectiveContainerId;
|
|
} TEB, * PTEB;
|
|
|
|
#define NtCurrentProcess() ((HANDLE)(LONG_PTR)-1)
|
|
#define NtCurrentPeb() (NtCurrentTeb()->ProcessEnvironmentBlock)
|
|
|
|
#define PROCESS_CREATE_FLAGS_INHERIT_HANDLES 0x00000004
|
|
|
|
typedef enum _PROCESSINFOCLASS
|
|
{
|
|
ProcessBasicInformation, // q: PROCESS_BASIC_INFORMATION, PROCESS_EXTENDED_BASIC_INFORMATION
|
|
ProcessQuotaLimits, // qs: QUOTA_LIMITS, QUOTA_LIMITS_EX
|
|
ProcessIoCounters, // q: IO_COUNTERS
|
|
ProcessVmCounters, // q: VM_COUNTERS, VM_COUNTERS_EX, VM_COUNTERS_EX2
|
|
ProcessTimes, // q: KERNEL_USER_TIMES
|
|
ProcessBasePriority, // s: KPRIORITY
|
|
ProcessRaisePriority, // s: ULONG
|
|
ProcessDebugPort, // q: HANDLE
|
|
ProcessExceptionPort, // s: PROCESS_EXCEPTION_PORT
|
|
ProcessAccessToken, // s: PROCESS_ACCESS_TOKEN
|
|
ProcessLdtInformation, // qs: PROCESS_LDT_INFORMATION // 10
|
|
ProcessLdtSize, // s: PROCESS_LDT_SIZE
|
|
ProcessDefaultHardErrorMode, // qs: ULONG
|
|
ProcessIoPortHandlers, // (kernel-mode only)
|
|
ProcessPooledUsageAndLimits, // q: POOLED_USAGE_AND_LIMITS
|
|
ProcessWorkingSetWatch, // q: PROCESS_WS_WATCH_INFORMATION[]; s: void
|
|
ProcessUserModeIOPL,
|
|
ProcessEnableAlignmentFaultFixup, // s: BOOLEAN
|
|
ProcessPriorityClass, // qs: PROCESS_PRIORITY_CLASS
|
|
ProcessWx86Information,
|
|
ProcessHandleCount, // q: ULONG, PROCESS_HANDLE_INFORMATION // 20
|
|
ProcessAffinityMask, // s: KAFFINITY
|
|
ProcessPriorityBoost, // qs: ULONG
|
|
ProcessDeviceMap, // qs: PROCESS_DEVICEMAP_INFORMATION, PROCESS_DEVICEMAP_INFORMATION_EX
|
|
ProcessSessionInformation, // q: PROCESS_SESSION_INFORMATION
|
|
ProcessForegroundInformation, // s: PROCESS_FOREGROUND_BACKGROUND
|
|
ProcessWow64Information, // q: ULONG_PTR
|
|
ProcessImageFileName, // q: UNICODE_STRING
|
|
ProcessLUIDDeviceMapsEnabled, // q: ULONG
|
|
ProcessBreakOnTermination, // qs: ULONG
|
|
ProcessDebugObjectHandle, // q: HANDLE // 30
|
|
ProcessDebugFlags, // qs: ULONG
|
|
ProcessHandleTracing, // q: PROCESS_HANDLE_TRACING_QUERY; s: size 0 disables, otherwise enables
|
|
ProcessIoPriority, // qs: IO_PRIORITY_HINT
|
|
ProcessExecuteFlags, // qs: ULONG
|
|
ProcessResourceManagement, // ProcessTlsInformation // PROCESS_TLS_INFORMATION
|
|
ProcessCookie, // q: ULONG
|
|
ProcessImageInformation, // q: SECTION_IMAGE_INFORMATION
|
|
ProcessCycleTime, // q: PROCESS_CYCLE_TIME_INFORMATION // since VISTA
|
|
ProcessPagePriority, // q: PAGE_PRIORITY_INFORMATION
|
|
ProcessInstrumentationCallback, // qs: PROCESS_INSTRUMENTATION_CALLBACK_INFORMATION // 40
|
|
ProcessThreadStackAllocation, // s: PROCESS_STACK_ALLOCATION_INFORMATION, PROCESS_STACK_ALLOCATION_INFORMATION_EX
|
|
ProcessWorkingSetWatchEx, // q: PROCESS_WS_WATCH_INFORMATION_EX[]
|
|
ProcessImageFileNameWin32, // q: UNICODE_STRING
|
|
ProcessImageFileMapping, // q: HANDLE (input)
|
|
ProcessAffinityUpdateMode, // qs: PROCESS_AFFINITY_UPDATE_MODE
|
|
ProcessMemoryAllocationMode, // qs: PROCESS_MEMORY_ALLOCATION_MODE
|
|
ProcessGroupInformation, // q: USHORT[]
|
|
ProcessTokenVirtualizationEnabled, // s: ULONG
|
|
ProcessConsoleHostProcess, // q: ULONG_PTR // ProcessOwnerInformation
|
|
ProcessWindowInformation, // q: PROCESS_WINDOW_INFORMATION // 50
|
|
ProcessHandleInformation, // q: PROCESS_HANDLE_SNAPSHOT_INFORMATION // since WIN8
|
|
ProcessMitigationPolicy, // s: PROCESS_MITIGATION_POLICY_INFORMATION
|
|
ProcessDynamicFunctionTableInformation,
|
|
ProcessHandleCheckingMode, // qs: ULONG; s: 0 disables, otherwise enables
|
|
ProcessKeepAliveCount, // q: PROCESS_KEEPALIVE_COUNT_INFORMATION
|
|
ProcessRevokeFileHandles, // s: PROCESS_REVOKE_FILE_HANDLES_INFORMATION
|
|
ProcessWorkingSetControl, // s: PROCESS_WORKING_SET_CONTROL
|
|
ProcessHandleTable, // q: ULONG[] // since WINBLUE
|
|
ProcessCheckStackExtentsMode,
|
|
ProcessCommandLineInformation, // q: UNICODE_STRING // 60
|
|
ProcessProtectionInformation, // q: PS_PROTECTION
|
|
ProcessMemoryExhaustion, // PROCESS_MEMORY_EXHAUSTION_INFO // since THRESHOLD
|
|
ProcessFaultInformation, // PROCESS_FAULT_INFORMATION
|
|
ProcessTelemetryIdInformation, // PROCESS_TELEMETRY_ID_INFORMATION
|
|
ProcessCommitReleaseInformation, // PROCESS_COMMIT_RELEASE_INFORMATION
|
|
ProcessDefaultCpuSetsInformation,
|
|
ProcessAllowedCpuSetsInformation,
|
|
ProcessSubsystemProcess,
|
|
ProcessJobMemoryInformation, // PROCESS_JOB_MEMORY_INFO
|
|
ProcessInPrivate, // since THRESHOLD2 // 70
|
|
ProcessRaiseUMExceptionOnInvalidHandleClose, // qs: ULONG; s: 0 disables, otherwise enables
|
|
ProcessIumChallengeResponse,
|
|
ProcessChildProcessInformation, // PROCESS_CHILD_PROCESS_INFORMATION
|
|
ProcessHighGraphicsPriorityInformation,
|
|
ProcessSubsystemInformation, // q: SUBSYSTEM_INFORMATION_TYPE // since REDSTONE2
|
|
ProcessEnergyValues, // PROCESS_ENERGY_VALUES, PROCESS_EXTENDED_ENERGY_VALUES
|
|
ProcessActivityThrottleState, // PROCESS_ACTIVITY_THROTTLE_STATE
|
|
ProcessActivityThrottlePolicy, // PROCESS_ACTIVITY_THROTTLE_POLICY
|
|
ProcessWin32kSyscallFilterInformation,
|
|
ProcessDisableSystemAllowedCpuSets, // 80
|
|
ProcessWakeInformation, // PROCESS_WAKE_INFORMATION
|
|
ProcessEnergyTrackingState, // PROCESS_ENERGY_TRACKING_STATE
|
|
ProcessManageWritesToExecutableMemory, // MANAGE_WRITES_TO_EXECUTABLE_MEMORY // since REDSTONE3
|
|
ProcessCaptureTrustletLiveDump,
|
|
ProcessTelemetryCoverage,
|
|
ProcessEnclaveInformation,
|
|
ProcessEnableReadWriteVmLogging, // PROCESS_READWRITEVM_LOGGING_INFORMATION
|
|
ProcessUptimeInformation, // PROCESS_UPTIME_INFORMATION
|
|
ProcessImageSection, // q: HANDLE
|
|
ProcessDebugAuthInformation, // since REDSTONE4 // 90
|
|
ProcessSystemResourceManagement, // PROCESS_SYSTEM_RESOURCE_MANAGEMENT
|
|
ProcessSequenceNumber, // q: ULONGLONG
|
|
ProcessLoaderDetour, // since REDSTONE5
|
|
ProcessSecurityDomainInformation, // PROCESS_SECURITY_DOMAIN_INFORMATION
|
|
ProcessCombineSecurityDomainsInformation, // PROCESS_COMBINE_SECURITY_DOMAINS_INFORMATION
|
|
ProcessEnableLogging, // PROCESS_LOGGING_INFORMATION
|
|
ProcessLeapSecondInformation, // PROCESS_LEAP_SECOND_INFORMATION
|
|
ProcessFiberShadowStackAllocation, // PROCESS_FIBER_SHADOW_STACK_ALLOCATION_INFORMATION // since 19H1
|
|
ProcessFreeFiberShadowStackAllocation, // PROCESS_FREE_FIBER_SHADOW_STACK_ALLOCATION_INFORMATION
|
|
MaxProcessInfoClass
|
|
} PROCESSINFOCLASS;
|
|
|
|
|
|
NTSYSCALLAPI
|
|
NTSTATUS
|
|
NTAPI
|
|
NtCreateSection(
|
|
_Out_ PHANDLE SectionHandle,
|
|
_In_ ACCESS_MASK DesiredAccess,
|
|
_In_opt_ POBJECT_ATTRIBUTES ObjectAttributes,
|
|
_In_opt_ PLARGE_INTEGER MaximumSize,
|
|
_In_ ULONG SectionPageProtection,
|
|
_In_ ULONG AllocationAttributes,
|
|
_In_opt_ HANDLE FileHandle
|
|
);
|
|
|
|
NTSYSCALLAPI
|
|
NTSTATUS
|
|
NTAPI
|
|
NtCreateProcessEx(
|
|
_Out_ PHANDLE ProcessHandle,
|
|
_In_ ACCESS_MASK DesiredAccess,
|
|
_In_opt_ POBJECT_ATTRIBUTES ObjectAttributes,
|
|
_In_ HANDLE ParentProcess,
|
|
_In_ ULONG Flags,
|
|
_In_opt_ HANDLE SectionHandle,
|
|
_In_opt_ HANDLE DebugPort,
|
|
_In_opt_ HANDLE ExceptionPort,
|
|
_In_ ULONG JobMemberLevel
|
|
);
|
|
|
|
NTSYSCALLAPI
|
|
NTSTATUS
|
|
NTAPI
|
|
NtQueryInformationProcess(
|
|
_In_ HANDLE ProcessHandle,
|
|
_In_ PROCESSINFOCLASS ProcessInformationClass,
|
|
_Out_writes_bytes_(ProcessInformationLength) PVOID ProcessInformation,
|
|
_In_ ULONG ProcessInformationLength,
|
|
_Out_opt_ PULONG ReturnLength
|
|
);
|
|
|
|
NTSYSCALLAPI
|
|
NTSTATUS
|
|
NTAPI
|
|
NtClose(
|
|
_In_ HANDLE Handle
|
|
);
|
|
|
|
NTSYSCALLAPI
|
|
NTSTATUS
|
|
NTAPI
|
|
NtCreateThreadEx(
|
|
_Out_ PHANDLE ThreadHandle,
|
|
_In_ ACCESS_MASK DesiredAccess,
|
|
_In_opt_ POBJECT_ATTRIBUTES ObjectAttributes,
|
|
_In_ HANDLE ProcessHandle,
|
|
_In_ PVOID StartRoutine, // PUSER_THREAD_START_ROUTINE
|
|
_In_opt_ PVOID Argument,
|
|
_In_ ULONG CreateFlags, // THREAD_CREATE_FLAGS_*
|
|
_In_ SIZE_T ZeroBits,
|
|
_In_ SIZE_T StackSize,
|
|
_In_ SIZE_T MaximumStackSize,
|
|
_In_opt_ PPS_ATTRIBUTE_LIST AttributeList
|
|
);
|
|
|
|
FORCEINLINE VOID RtlInitUnicodeString(
|
|
_Out_ PUNICODE_STRING DestinationString,
|
|
_In_opt_ PCWSTR SourceString
|
|
)
|
|
{
|
|
if (SourceString)
|
|
DestinationString->MaximumLength = (DestinationString->Length = (USHORT)(wcslen(SourceString) * sizeof(WCHAR))) + sizeof(UNICODE_NULL);
|
|
else
|
|
DestinationString->MaximumLength = DestinationString->Length = 0;
|
|
|
|
DestinationString->Buffer = (PWCH)SourceString;
|
|
}
|
|
|
|
NTSYSAPI
|
|
NTSTATUS
|
|
NTAPI
|
|
RtlCreateProcessParametersEx(
|
|
_Out_ PRTL_USER_PROCESS_PARAMETERS* pProcessParameters,
|
|
_In_ PUNICODE_STRING ImagePathName,
|
|
_In_opt_ PUNICODE_STRING DllPath,
|
|
_In_opt_ PUNICODE_STRING CurrentDirectory,
|
|
_In_opt_ PUNICODE_STRING CommandLine,
|
|
_In_opt_ PVOID Environment,
|
|
_In_opt_ PUNICODE_STRING WindowTitle,
|
|
_In_opt_ PUNICODE_STRING DesktopInfo,
|
|
_In_opt_ PUNICODE_STRING ShellInfo,
|
|
_In_opt_ PUNICODE_STRING RuntimeData,
|
|
_In_ ULONG Flags // pass RTL_USER_PROC_PARAMS_NORMALIZED to keep parameters normalized
|
|
);
|
|
|
|
NTSYSAPI
|
|
NTSTATUS
|
|
NTAPI
|
|
RtlDestroyProcessParameters(
|
|
_In_ _Post_invalid_ PRTL_USER_PROCESS_PARAMETERS ProcessParameters
|
|
);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#pragma warning(pop)
|
|
|
|
class AutoCloseHandle
|
|
{
|
|
public:
|
|
AutoCloseHandle(BOOL isNTHandle = FALSE) :
|
|
m_handle(INVALID_HANDLE_VALUE),
|
|
m_isNTHandle(isNTHandle)
|
|
{}
|
|
|
|
~AutoCloseHandle()
|
|
{
|
|
if (!valid())
|
|
{
|
|
return;
|
|
}
|
|
if (m_isNTHandle)
|
|
{
|
|
NTSTATUS status = NtClose(m_handle);
|
|
if (!NT_SUCCESS(status))
|
|
{
|
|
dprintf("[AutoCloseHandle] Error when closing the NT handle (NTSTATUS: %d)", status);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (CloseHandle(m_handle) == 0)
|
|
{
|
|
dprintf("[AutoCloseHandle] Error when closing handle (%d)", GetLastError());
|
|
}
|
|
}
|
|
m_handle = INVALID_HANDLE_VALUE;
|
|
}
|
|
|
|
HANDLE& get()
|
|
{
|
|
return m_handle;
|
|
}
|
|
|
|
void close()
|
|
{
|
|
this->~AutoCloseHandle();
|
|
}
|
|
|
|
BOOL valid()
|
|
{
|
|
return (m_handle != NULL) && (m_handle != INVALID_HANDLE_VALUE);
|
|
}
|
|
private:
|
|
HANDLE m_handle;
|
|
BOOL m_isNTHandle;
|
|
};
|
|
|
|
|
|
class ProcessHandle
|
|
{
|
|
public:
|
|
ProcessHandle() :
|
|
m_processHandle(),
|
|
m_terminate(TRUE)
|
|
{}
|
|
|
|
~ProcessHandle()
|
|
{
|
|
if (m_processHandle.valid())
|
|
{
|
|
if (m_terminate)
|
|
{
|
|
if (TerminateProcess(m_processHandle.get(), 0) == 0)
|
|
{
|
|
dprintf("Error when terminating process (%d)", GetLastError());
|
|
}
|
|
m_terminate = FALSE;
|
|
}
|
|
m_processHandle.close();
|
|
}
|
|
}
|
|
|
|
BOOL& terminate()
|
|
{
|
|
return m_terminate;
|
|
}
|
|
|
|
HANDLE& get()
|
|
{
|
|
return m_processHandle.get();
|
|
}
|
|
|
|
BOOL valid()
|
|
{
|
|
return m_processHandle.valid();
|
|
}
|
|
|
|
private:
|
|
AutoCloseHandle m_processHandle;
|
|
BOOL m_terminate;
|
|
};
|
|
|
|
class FileHandle
|
|
{
|
|
public:
|
|
FileHandle(std::wstring fileName = L"", BOOL p_remove = FALSE) :
|
|
m_fileHandle(),
|
|
m_fileName(fileName),
|
|
m_remove(p_remove)
|
|
{}
|
|
|
|
~FileHandle()
|
|
{
|
|
if (m_fileHandle.valid())
|
|
{
|
|
m_fileHandle.close();
|
|
}
|
|
if (m_remove)
|
|
{
|
|
dprintf("[FileHandle] Remove file %S", m_fileName.c_str());
|
|
if (DeleteFileW(m_fileName.c_str()) == 0)
|
|
{
|
|
dprintf("[FileHandle] Failed to delete the file %S (0x%d)", m_fileName.c_str(), GetLastError());
|
|
}
|
|
m_remove = FALSE;
|
|
}
|
|
}
|
|
|
|
BOOL& remove()
|
|
{
|
|
return m_remove;
|
|
}
|
|
|
|
HANDLE& get()
|
|
{
|
|
return m_fileHandle.get();
|
|
}
|
|
|
|
BOOL valid()
|
|
{
|
|
return m_fileHandle.valid();
|
|
}
|
|
|
|
void close()
|
|
{
|
|
m_fileHandle.close();
|
|
}
|
|
private:
|
|
AutoCloseHandle m_fileHandle;
|
|
BOOL m_remove;
|
|
std::wstring m_fileName;
|
|
};
|
|
|
|
|
|
class MappingHandle
|
|
{
|
|
public:
|
|
MappingHandle() :
|
|
m_mappingHandle(),
|
|
m_view(nullptr)
|
|
{}
|
|
|
|
~MappingHandle()
|
|
{
|
|
if (m_view != nullptr)
|
|
{
|
|
dprintf("[MappingHandle] Unmapping view");
|
|
if (UnmapViewOfFile(m_view) == 0)
|
|
{
|
|
dprintf("[MappingHandle] Unmap view error (0x%x)", GetLastError());
|
|
}
|
|
m_view = nullptr;
|
|
}
|
|
if (m_mappingHandle.valid())
|
|
{
|
|
m_mappingHandle.close();
|
|
}
|
|
}
|
|
|
|
HANDLE& get()
|
|
{
|
|
return m_mappingHandle.get();
|
|
}
|
|
|
|
BOOL valid()
|
|
{
|
|
return m_mappingHandle.valid();
|
|
}
|
|
|
|
void close()
|
|
{
|
|
this->~MappingHandle();
|
|
}
|
|
|
|
LPVOID& view()
|
|
{
|
|
return m_view;
|
|
}
|
|
|
|
private:
|
|
AutoCloseHandle m_mappingHandle;
|
|
LPVOID m_view;
|
|
};
|