From 5f02e5b9ff833ae8cee7feb4c67a06f11c4adc2f Mon Sep 17 00:00:00 2001 From: hfiref0x Date: Sun, 26 Jul 2026 11:50:04 +0700 Subject: [PATCH 1/5] Update RTLs Remove ntsup tests as they are now part of dedicated project --- Source/Shared/ntos/ntos.h | 275 ++++- Source/Shared/ntos/ntsup.c | 1102 ++++++++++++++++-- Source/Shared/ntos/ntsup.h | 199 +++- Source/WinObjEx64/Resource.rc | Bin 168014 -> 168014 bytes Source/WinObjEx64/WinObjEx64.vcxproj | 7 +- Source/WinObjEx64/WinObjEx64.vcxproj.filters | 6 - Source/WinObjEx64/aboutDlg.c | 2 +- Source/WinObjEx64/extras/extrasCallbacks.c | 10 +- Source/WinObjEx64/extras/extrasSSDT.c | 7 +- Source/WinObjEx64/kldbg.c | 66 +- Source/WinObjEx64/kldbg.h | 10 +- Source/WinObjEx64/sup/sup.c | 90 +- Source/WinObjEx64/sup/sup.h | 14 +- Source/WinObjEx64/sup/w32k.c | 59 +- Source/WinObjEx64/sup/w32k.h | 7 +- Source/WinObjEx64/tests/ntsup_tests.c | 897 -------------- Source/WinObjEx64/tests/ntsup_tests.h | 25 - Source/WinObjEx64/tests/testunit.c | 10 +- Source/WinObjEx64/ui.h | 8 +- 19 files changed, 1608 insertions(+), 1186 deletions(-) delete mode 100644 Source/WinObjEx64/tests/ntsup_tests.c delete mode 100644 Source/WinObjEx64/tests/ntsup_tests.h diff --git a/Source/Shared/ntos/ntos.h b/Source/Shared/ntos/ntos.h index ec050c5..0378ff5 100644 --- a/Source/Shared/ntos/ntos.h +++ b/Source/Shared/ntos/ntos.h @@ -5,9 +5,9 @@ * * TITLE: NTOS.H * -* VERSION: 1.247 +* VERSION: 1.250 * -* DATE: 12 Jul 2026 +* DATE: 23 Jul 2026 * * Common header file for the ntos API functions and definitions. * @@ -512,6 +512,11 @@ char _RTL_CONSTANT_STRING_type_check(const void *s); #define MAX_USTRING ( sizeof(WCHAR) * (MAXUSHORT/sizeof(WCHAR)) ) #endif +#ifndef __PCSID_DEFINED__ +#define __PCSID_DEFINED__ +typedef const SID* PCSID; +#endif /* __PCSID_DEFINED__ */ + typedef struct _EX_RUNDOWN_REF { union { @@ -938,7 +943,8 @@ typedef struct _SYSTEM_ISOLATED_USER_MODE_INFORMATION { BOOLEAN HardwareEnforcedHvpt : 1; BOOLEAN HardwareHvptAvailable : 1; BOOLEAN SpareFlags2 : 1; - BOOLEAN Spare0[6]; + BOOLEAN EncryptionKeyTpmBound : 1; + BOOLEAN Spare0[5]; ULONGLONG Spare1; } SYSTEM_ISOLATED_USER_MODE_INFORMATION, *PSYSTEM_ISOLATED_USER_MODE_INFORMATION; @@ -10641,6 +10647,8 @@ RtlWow64SetThreadContext( * ************************************************************************************/ +#define RtlProcessHeap() (NtCurrentPeb()->ProcessHeap) + typedef NTSTATUS(NTAPI * PRTL_HEAP_COMMIT_ROUTINE)( _In_ PVOID Base, _Inout_ PVOID *CommitAddress, @@ -10765,6 +10773,33 @@ RtlEnumProcessHeaps( _In_ PRTL_ENUM_HEAPS_ROUTINE EnumRoutine, _In_ PVOID Parameter); +NTSYSAPI +BOOLEAN +NTAPI +RtlValidateHeap( + _In_opt_ HANDLE HeapHandle, + _In_ ULONG Flags, + _In_opt_ PVOID BaseAddress); + +NTSYSAPI +SIZE_T +NTAPI +RtlCompactHeap( + _In_ HANDLE HeapHandle, + _In_ ULONG Flags); + +NTSYSAPI +BOOLEAN +NTAPI +RtlLockHeap( + _In_ HANDLE HeapHandle); + +NTSYSAPI +BOOLEAN +NTAPI +RtlUnlockHeap( + _In_ HANDLE HeapHandle); + /************************************************************************************ * * RTL Compression API. @@ -11485,6 +11520,123 @@ RtlSetIoCompletionCallback( _In_ APC_CALLBACK_FUNCTION CompletionProc, _In_ ULONG Flags); +/************************************************************************************ +* +* RTL WNF (Windows Notification Facility support. +* +************************************************************************************/ + +#define WNF_STATE_KEY 0x41C64E6DA3BC0074 + +typedef ULONG WNF_CHANGE_STAMP, * PWNF_CHANGE_STAMP; + +typedef enum _WNF_STATE_NAME_INFORMATION { + WnfInfoStateNameExist, + WnfInfoSubscribersPresent, + WnfInfoIsQuiescent +} WNF_STATE_NAME_INFORMATION; + +typedef struct _WNF_STATE_NAME { + union + { + ULONGLONG Value; + ULONG Data[2]; + struct + { + ULONG64 Version : 4; + ULONG64 NameLifetime : 2; + ULONG64 DataScope : 4; + ULONG64 PermanentData : 1; + ULONG64 Unique : 53; + }; + }; +} WNF_STATE_NAME, * PWNF_STATE_NAME; +typedef const WNF_STATE_NAME* PCWNF_STATE_NAME; + +typedef enum _WNF_STATE_NAME_LIFETIME { + WnfWellKnownStateName, + WnfPermanentStateName, + WnfPersistentStateName, + WnfTemporaryStateName +} WNF_STATE_NAME_LIFETIME; + +typedef enum _WNF_DATA_SCOPE { + WnfDataScopeSystem, + WnfDataScopeSession, + WnfDataScopeUser, + WnfDataScopeProcess, + WnfDataScopeMachine, + WnfDataScopePhysicalMachine, +} WNF_DATA_SCOPE; + +typedef struct _WNF_TYPE_ID { + GUID TypeId; +} WNF_TYPE_ID, * PWNF_TYPE_ID; +typedef const WNF_TYPE_ID* PCWNF_TYPE_ID; + +_Must_inspect_result_ +NTSYSAPI +BOOLEAN +NTAPI +RtlEqualWnfChangeStamps( + _In_ WNF_CHANGE_STAMP ChangeStamp1, + _In_ WNF_CHANGE_STAMP ChangeStamp2); + +_Always_(_Post_satisfies_(return == STATUS_NO_MEMORY || return == STATUS_RETRY || return == STATUS_SUCCESS)) +typedef _Function_class_(WNF_USER_CALLBACK) +NTSTATUS NTAPI WNF_USER_CALLBACK( + _In_ WNF_STATE_NAME StateName, + _In_ WNF_CHANGE_STAMP ChangeStamp, + _In_opt_ PWNF_TYPE_ID TypeId, + _In_opt_ PVOID CallbackContext, + _In_reads_bytes_opt_(Length) const VOID* Buffer, + _In_ ULONG Length); + +typedef WNF_USER_CALLBACK* PWNF_USER_CALLBACK; + +NTSYSAPI +NTSTATUS +NTAPI +RtlQueryWnfStateData( + _Out_ PWNF_CHANGE_STAMP ChangeStamp, + _In_ WNF_STATE_NAME StateName, + _In_ PWNF_USER_CALLBACK Callback, + _In_opt_ PVOID CallbackContext, + _In_opt_ PWNF_TYPE_ID TypeId); + +NTSYSAPI +NTSTATUS +NTAPI +RtlPublishWnfStateData( + _In_ WNF_STATE_NAME StateName, + _In_opt_ PCWNF_TYPE_ID TypeId, + _In_reads_bytes_opt_(Length) const VOID * Buffer, + _In_opt_ ULONG Length, + _In_opt_ const VOID * ExplicitScope); + +typedef struct WNF_USER_SUBSCRIPTION* PWNF_USER_SUBSCRIPTION; + +#define WNF_CREATE_SERIALIZATION_GROUP_FLAG 0x00000001L + +NTSYSAPI +NTSTATUS +NTAPI +RtlSubscribeWnfStateChangeNotification( + _Out_ PWNF_USER_SUBSCRIPTION * SubscriptionHandle, + _In_ WNF_STATE_NAME StateName, + _In_ WNF_CHANGE_STAMP ChangeStamp, + _In_ PWNF_USER_CALLBACK Callback, + _In_opt_ PVOID CallbackContext, + _In_opt_ PCWNF_TYPE_ID TypeId, + _In_opt_ ULONG SerializationGroup, + _In_ ULONG Flags); + +NTSYSAPI +NTSTATUS +NTAPI +RtlUnsubscribeWnfStateChangeNotification( + _In_ PWNF_USER_SUBSCRIPTION SubscriptionHandle); + /************************************************************************************ * * RTL data exports. @@ -11509,13 +11661,31 @@ NTSYSAPI UNICODE_STRING RtlNtPathSeperatorString; * ************************************************************************************/ +#ifndef EVENT_DESCRIPTOR_DEF +#define EVENT_DESCRIPTOR_DEF +typedef struct _EVENT_DESCRIPTOR { + USHORT Id; + UCHAR Version; + UCHAR Channel; + UCHAR Level; + UCHAR Opcode; + USHORT Task; + ULONGLONG Keyword; +} EVENT_DESCRIPTOR, * PEVENT_DESCRIPTOR; +typedef const EVENT_DESCRIPTOR* PCEVENT_DESCRIPTOR; +#endif + +typedef struct _EVENT_FILTER_DESCRIPTOR* PEVENT_FILTER_DESCRIPTOR; +typedef struct _EVENT_DATA_DESCRIPTOR EVENT_DATA_DESCRIPTOR, * PEVENT_DATA_DESCRIPTOR; +typedef enum _EVENT_INFO_CLASS EVENT_INFO_CLASS; + typedef VOID(NTAPI *PETWENABLECALLBACK)( _In_ LPCGUID SourceId, _In_ ULONG IsEnabled, _In_ UCHAR Level, _In_ ULONGLONG MatchAnyKeyword, _In_ ULONGLONG MatchAllKeyword, - _In_opt_ /*EVENT_FILTER_DESCRIPTOR*/ PVOID FilterData, + _In_opt_ PEVENT_FILTER_DESCRIPTOR FilterData, _Inout_opt_ PVOID CallbackContext ); @@ -11528,15 +11698,29 @@ EtwEventRegister( _In_opt_ PVOID CallbackContext, _Out_ PREGHANDLE RegHandle); +NTSYSAPI +ULONG +NTAPI +EtwEventUnregister( + _In_ REGHANDLE RegHandle); + NTSYSAPI ULONG NTAPI EtwEventWriteNoRegistration( _In_ LPCGUID ProviderId, - _In_ /*PCEVENT_DESCRIPTOR*/ PVOID EventDescriptor, + _In_ PCEVENT_DESCRIPTOR EventDescriptor, _In_ ULONG UserDataCount, - _In_reads_opt_(UserDataCount) /*PEVENT_DATA_DESCRIPTOR*/PVOID UserData); + _In_reads_opt_(UserDataCount) PEVENT_DATA_DESCRIPTOR UserData); +NTSYSAPI +ULONG +NTAPI +EtwEventSetInformation( + _In_ REGHANDLE RegHandle, + _In_ EVENT_INFO_CLASS InformationClass, + _In_reads_bytes_(InformationLength) PVOID EventInformation, + _In_ ULONG InformationLength); /* ** Runtime Library API END @@ -12022,6 +12206,85 @@ NtReleaseSemaphore( _In_ LONG ReleaseCount, _Out_opt_ PLONG PreviousCount); +/************************************************************************************ +* +* WNF API. +* +************************************************************************************/ + +NTSYSAPI +NTSTATUS +NTAPI +NtCreateWnfStateName( + _Out_ PWNF_STATE_NAME StateName, + _In_ WNF_STATE_NAME_LIFETIME NameLifetime, + _In_ WNF_DATA_SCOPE DataScope, + _In_ BOOLEAN PersistData, + _In_opt_ PCWNF_TYPE_ID TypeId, + _In_ ULONG MaximumStateSize, + _In_ PSECURITY_DESCRIPTOR SecurityDescriptor); + +NTSYSAPI +NTSTATUS +NTAPI +NtDeleteWnfStateName( + _In_ PCWNF_STATE_NAME StateName); + +NTSYSAPI +NTSTATUS +NTAPI +NtUpdateWnfStateData( + _In_ PCWNF_STATE_NAME StateName, + _In_reads_bytes_opt_(Length) const VOID* Buffer, + _In_opt_ ULONG Length, + _In_opt_ PCWNF_TYPE_ID TypeId, + _In_opt_ PCSID ExplicitScope, + _In_ WNF_CHANGE_STAMP MatchingChangeStamp, + _In_ LOGICAL CheckStamp); + +NTSYSAPI +NTSTATUS +NTAPI +NtDeleteWnfStateData( + _In_ PCWNF_STATE_NAME StateName, + _In_opt_ PCSID ExplicitScope); + +NTSYSAPI +NTSTATUS +NTAPI +NtQueryWnfStateData( + _In_ PCWNF_STATE_NAME StateName, + _In_opt_ PCWNF_TYPE_ID TypeId, + _In_opt_ PCSID ExplicitScope, + _Out_ PWNF_CHANGE_STAMP ChangeStamp, + _Out_writes_bytes_opt_(*BufferLength) PVOID Buffer, + _Inout_ PULONG BufferLength); + +NTSYSAPI +NTSTATUS +NTAPI +NtQueryWnfStateNameInformation( + _In_ PCWNF_STATE_NAME StateName, + _In_ WNF_STATE_NAME_INFORMATION NameInfoClass, + _In_opt_ PCSID ExplicitScope, + _Out_writes_bytes_(BufferLength) PVOID Buffer, + _In_ ULONG BufferLength); + +NTSYSAPI +NTSTATUS +NTAPI +NtSubscribeWnfStateChange( + _In_ PCWNF_STATE_NAME StateName, + _In_opt_ WNF_CHANGE_STAMP ChangeStamp, + _In_ ULONG EventMask, + _Out_opt_ PULONG64 SubscriptionId); + +NTSYSAPI +NTSTATUS +NTAPI +NtUnsubscribeWnfStateChange( + _In_ PCWNF_STATE_NAME StateName); + /************************************************************************************ * * Object and Handle API. diff --git a/Source/Shared/ntos/ntsup.c b/Source/Shared/ntos/ntsup.c index a625d26..5ec293a 100644 --- a/Source/Shared/ntos/ntsup.c +++ b/Source/Shared/ntos/ntsup.c @@ -4,9 +4,9 @@ * * TITLE: NTSUP.C * -* VERSION: 2.28 +* VERSION: 2.30 * -* DATE: 11 Jul 2026 +* DATE: 25 Jul 2026 * * Native API support functions. * @@ -23,20 +23,13 @@ #pragma warning(push) #pragma warning(disable: 26812) // Prefer 'enum class' over 'enum' -#pragma warning(disable: 6320) // exception may mask +#pragma warning(disable: 6320) // exception may mask /* -* -* SHA256 algo (used by Ronova so keep it here). -* +* Ronova port start. +* SHA256 algo. */ -typedef struct _NTSUP_SHA256_CTX { - ULONG State[8]; - ULONG64 BitCount; - UCHAR Buffer[64]; -} NTSUP_SHA256_CTX, * PNTSUP_SHA256_CTX; - #define NTSUP_ROTR32(v,b) _rotr(v,b) #define NTSUP_CH(x,y,z) (((x) & (y)) ^ ((~x) & (z))) #define NTSUP_MAJ(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) @@ -209,6 +202,645 @@ VOID ntsupSha256Final( RtlSecureZeroMemory(len, sizeof(len)); } +/* +* ntsupIsAddressValid +* +* Purpose: +* +* Validates that a given virtual memory address range is accessible +* in the current process address space. +* +* The routine checks: +* +* - Address is not NULL. +* - Memory region can be queried using NtQueryVirtualMemory. +* - Memory state is committed (MEM_COMMIT). +* - Memory protection does not include PAGE_NOACCESS. +* - Memory protection does not include PAGE_GUARD. +* - Requested size fits completely inside the queried memory region. +* +*/ +BOOLEAN ntsupIsAddressValid( + _In_ PVOID Address, + _In_ SIZE_T Size +) +{ + MEMORY_BASIC_INFORMATION mbi; + NTSTATUS status; + + if (Address == NULL) + return FALSE; + + status = NtQueryVirtualMemory( + NtCurrentProcess(), + Address, + MemoryBasicInformation, + &mbi, + sizeof(mbi), + NULL); + + if (!NT_SUCCESS(status)) + return FALSE; + + if (mbi.State != MEM_COMMIT) + return FALSE; + + if (mbi.Protect & PAGE_NOACCESS) + return FALSE; + + if (mbi.Protect & PAGE_GUARD) + return FALSE; + + if (Size != 0) { + + if ((ULONG_PTR)Address < (ULONG_PTR)mbi.BaseAddress) + return FALSE; + + if (((ULONG_PTR)Address + Size) > + ((ULONG_PTR)mbi.BaseAddress + mbi.RegionSize)) + { + return FALSE; + } + } + + return TRUE; +} + +/* +* Ronova port end. +*/ + +SIZE_T ntsupStrLenA( + _In_opt_ LPCSTR String +) +{ + LPCSTR String0 = String; + + if (String == NULL) + return 0; + + while (*String != ANSI_NULL) + String++; + + return (SIZE_T)(String - String0); +} + +SIZE_T ntsupStrLenW( + _In_opt_ LPCWSTR String +) +{ + LPCWSTR String0 = String; + + if (String == NULL) + return 0; + + while (*String != UNICODE_NULL) + String++; + + return (SIZE_T)(String - String0); +} + +INT ntsupStrCmpA( + _In_opt_ LPCSTR String1, + _In_opt_ LPCSTR String2 +) +{ + CHAR c1, c2; + + if (String1 == String2) + return 0; + + if (String1 == NULL) + return -1; + + if (String2 == NULL) + return 1; + + do { + c1 = *String1; + c2 = *String2; + String1++; + String2++; + } while ((c1 != ANSI_NULL) && (c1 == c2)); + + return (INT)(c1 - c2); +} + +INT ntsupStrCmpW( + _In_opt_ LPCWSTR String1, + _In_opt_ LPCWSTR String2 +) +{ + WCHAR c1, c2; + + if (String1 == String2) + return 0; + + if (String1 == NULL) + return -1; + + if (String2 == NULL) + return 1; + + do { + c1 = *String1; + c2 = *String2; + String1++; + String2++; + } while ((c1 != UNICODE_NULL) && (c1 == c2)); + + return (INT)(c1 - c2); +} + +INT ntsupStrCmpIA( + _In_opt_ LPCSTR String1, + _In_opt_ LPCSTR String2 +) +{ + CHAR c1, c2; + + if (String1 == String2) + return 0; + + if (String1 == NULL) + return -1; + + if (String2 == NULL) + return 1; + + do { + c1 = ntsupLowerCharA(*String1); + c2 = ntsupLowerCharA(*String2); + String1++; + String2++; + } while ((c1 != ANSI_NULL) && (c1 == c2)); + + return (INT)(c1 - c2); +} + +INT ntsupStrCmpIW( + _In_opt_ LPCWSTR String1, + _In_opt_ LPCWSTR String2 +) +{ + WCHAR c1, c2; + + if (String1 == String2) + return 0; + + if (String1 == NULL) + return -1; + + if (String2 == NULL) + return 1; + + do { + c1 = ntsupLowerCharW(*String1); + c2 = ntsupLowerCharW(*String2); + String1++; + String2++; + } while ((c1 != UNICODE_NULL) && (c1 == c2)); + + return (INT)(c1 - c2); +} + +#pragma warning(push) +#pragma warning(disable: 6101 6054) +LPSTR ntsupStrNCopyA( + _Out_writes_(DestinationCount) LPSTR Destination, + _In_ SIZE_T DestinationCount, + _In_reads_(SourceCount) LPCSTR Source, + _In_ SIZE_T SourceCount +) +{ + LPSTR p; + + if ((Destination == NULL) || (Source == NULL) || (DestinationCount == 0)) + return Destination; + + if (Destination == Source) + return Destination; + + DestinationCount--; + p = Destination; + + while ((*Source != ANSI_NULL) && + (DestinationCount > 0) && + (SourceCount > 0)) + { + *p = *Source; + p++; + Source++; + DestinationCount--; + SourceCount--; + } + + *p = ANSI_NULL; + + return Destination; +} + +LPWSTR ntsupStrNCopyW( + _Out_writes_(DestinationCount) LPWSTR Destination, + _In_ SIZE_T DestinationCount, + _In_reads_(SourceCount) LPCWSTR Source, + _In_ SIZE_T SourceCount +) +{ + LPWSTR p; + + if ((Destination == NULL) || (Source == NULL) || (DestinationCount == 0)) + return Destination; + + if (Destination == Source) + return Destination; + + DestinationCount--; + p = Destination; + + while ((*Source != UNICODE_NULL) && + (DestinationCount > 0) && + (SourceCount > 0)) + { + *p = *Source; + p++; + Source++; + DestinationCount--; + SourceCount--; + } + + *p = UNICODE_NULL; + + return Destination; +} +#pragma warning(pop) + +INT ntsupStrNCmpA( + _In_opt_ LPCSTR String1, + _In_opt_ LPCSTR String2, + _In_ SIZE_T Count +) +{ + CHAR c1, c2; + + if (String1 == String2) + return 0; + + if (String1 == NULL) + return -1; + + if (String2 == NULL) + return 1; + + if (Count == 0) + return 0; + + do { + c1 = *String1; + c2 = *String2; + String1++; + String2++; + Count--; + } while ((c1 != ANSI_NULL) && + (c1 == c2) && + (Count > 0)); + + return (INT)(c1 - c2); +} + +INT ntsupStrNCmpW( + _In_opt_ LPCWSTR String1, + _In_opt_ LPCWSTR String2, + _In_ SIZE_T Count +) +{ + WCHAR c1, c2; + + if (String1 == String2) + return 0; + + if (String1 == NULL) + return -1; + + if (String2 == NULL) + return 1; + + if (Count == 0) + return 0; + + do { + c1 = *String1; + c2 = *String2; + String1++; + String2++; + Count--; + } while ((c1 != UNICODE_NULL) && + (c1 == c2) && + (Count > 0)); + + return (INT)(c1 - c2); +} + +/* +* ntsupStrStrIA +* +* Purpose: +* +* Case insensitive string search. +* +*/ +LPCSTR ntsupStrStrIA( + _In_ LPCSTR String, + _In_ LPCSTR SubString +) +{ + CHAR c0, c1, c2; + LPCSTR tmpString; + LPCSTR tmpSubString; + + if (String == SubString) + return String; + + if (String == NULL) + return NULL; + + if (SubString == NULL) + return NULL; + + // + // Empty substring matches at beginning. + // + if (*SubString == 0) + return String; + + c0 = ntsupLowerCharA(*SubString); + + while (c0 != 0) { + + while (*String != 0) { + + c2 = ntsupLowerCharA(*String); + + if (c2 == c0) + break; + + String++; + } + + if (*String == 0) + return NULL; + + tmpString = String; + tmpSubString = SubString; + + do { + + c1 = ntsupLowerCharA(*tmpString); + c2 = ntsupLowerCharA(*tmpSubString); + + tmpString++; + tmpSubString++; + + } while ((c1 == c2) && (c2 != 0)); + + + if (c2 == 0) + return String; + + String++; + } + + return NULL; +} + + +/* +* ntsupStrStrIW +* +* Purpose: +* +* Case insensitive string search. +* +*/ +LPCWSTR ntsupStrStrIW( + _In_ LPCWSTR String, + _In_ LPCWSTR SubString +) +{ + WCHAR c0, c1, c2; + LPCWSTR tmpString; + LPCWSTR tmpSubString; + + if (String == SubString) + return String; + + if (String == NULL) + return NULL; + + if (SubString == NULL) + return NULL; + + // + // Empty substring matches at beginning. + // + if (*SubString == 0) + return String; + + c0 = ntsupLowerCharW(*SubString); + + while (c0 != 0) { + + while (*String != 0) { + + c2 = ntsupLowerCharW(*String); + + if (c2 == c0) + break; + + String++; + } + + if (*String == 0) + return NULL; + + tmpString = String; + tmpSubString = SubString; + + do { + + c1 = ntsupLowerCharW(*tmpString); + c2 = ntsupLowerCharW(*tmpSubString); + + tmpString++; + tmpSubString++; + + } while ((c1 == c2) && (c2 != 0)); + + + if (c2 == 0) + return String; + + String++; + } + + return NULL; +} + +/* +* ntsupStrCatA +* +* Purpose: +* +* Append source string to destination string. +* +*/ +LPSTR ntsupStrCatA( + _Inout_ LPSTR Destination, + _In_ LPCSTR Source +) +{ + if ((Destination == NULL) || (Source == NULL)) + return Destination; + + while (*Destination != 0) + Destination++; + + while (*Source != 0) { + + *Destination = *Source; + + Destination++; + Source++; + } + + *Destination = 0; + + return Destination; +} + + +/* +* ntsupStrCatW +* +* Purpose: +* +* Append source string to destination string. +* +*/ +LPWSTR ntsupStrCatW( + _Inout_ LPWSTR Destination, + _In_ LPCWSTR Source +) +{ + if ((Destination == NULL) || (Source == NULL)) + return Destination; + + while (*Destination != 0) + Destination++; + + while (*Source != 0) { + + *Destination = *Source; + + Destination++; + Source++; + } + + *Destination = 0; + + return Destination; +} + +/* +* ntsupStrCatExA +* +* Purpose: +* +* Append source string to destination string. +* +* Destination buffer is always NULL terminated if size permits. +* +*/ +LPSTR ntsupStrCatExA( + _Inout_updates_z_(DestinationCount) LPSTR Destination, + _In_ SIZE_T DestinationCount, + _In_ LPCSTR Source +) +{ + LPSTR p; + + if ((Destination == NULL) || + (Source == NULL) || + (DestinationCount == 0)) + { + return Destination; + } + + p = Destination; + while ((*p != 0) && (DestinationCount > 1)) { + p++; + DestinationCount--; + } + + while ((*Source != 0) && (DestinationCount > 1)) { + + *p = *Source; + + p++; + Source++; + + DestinationCount--; + } + + *p = 0; + return Destination; +} + +/* +* ntsupStrCatExW +* +* Purpose: +* +* Append source string to destination string. +* +* Destination buffer is always NULL terminated if size permits. +* +*/ +LPWSTR ntsupStrCatExW( + _Inout_updates_z_(DestinationCount) LPWSTR Destination, + _In_ SIZE_T DestinationCount, + _In_ LPCWSTR Source +) +{ + LPWSTR p; + + if ((Destination == NULL) || + (Source == NULL) || + (DestinationCount == 0)) + { + return Destination; + } + + p = Destination; + while ((*p != 0) && (DestinationCount > 1)) { + p++; + DestinationCount--; + } + + while ((*Source != 0) && (DestinationCount > 1)) { + + *p = *Source; + + p++; + Source++; + + DestinationCount--; + } + + *p = 0; + return Destination; +} + /* * ntsupHeapAlloc * @@ -221,7 +853,23 @@ PVOID ntsupHeapAlloc( _In_ SIZE_T Size ) { - return RtlAllocateHeap(ntsupProcessHeap(), HEAP_ZERO_MEMORY, Size); + return RtlAllocateHeap(RtlProcessHeap(), HEAP_ZERO_MEMORY, Size); +} + +/* + * ntsupHeapReAlloc + * + * Purpose: + * + * Wrapper for RtlReAllocateHeap with process heap. + * + */ +PVOID ntsupHeapReAlloc( + _In_ PVOID BaseAddress, + _In_ SIZE_T Size +) +{ + return RtlReAllocateHeap(RtlProcessHeap(), HEAP_ZERO_MEMORY, BaseAddress, Size); } /* @@ -236,7 +884,82 @@ BOOL ntsupHeapFree( _In_ PVOID BaseAddress ) { - return RtlFreeHeap(ntsupProcessHeap(), 0, BaseAddress); + return RtlFreeHeap(RtlProcessHeap(), 0, BaseAddress); +} + +/* + * ntsupHeapSize + * + * Purpose: + * + * Wrapper for RtlSizeHeap with process heap. + * + */ +SIZE_T ntsupHeapSize( + _In_ PVOID BaseAddress +) +{ + return RtlSizeHeap(RtlProcessHeap(), 0, BaseAddress); +} + +/* + * ntsupHeapValidate + * + * Purpose: + * + * Wrapper for RtlValidateHeap with process heap. + * + */ +BOOL ntsupHeapValidate( + _In_ PVOID BaseAddress +) +{ + return RtlValidateHeap(RtlProcessHeap(), 0, BaseAddress); +} + +/* + * ntsupHeapCompact + * + * Purpose: + * + * Wrapper for RtlCompactHeap with process heap. + * + */ +SIZE_T ntsupHeapCompact( + VOID +) +{ + return RtlCompactHeap(RtlProcessHeap(), 0); +} + +/* + * ntsupHeapLock + * + * Purpose: + * + * Wrapper for RtlLockHeap with process heap. + * + */ +BOOL ntsupHeapLock( + VOID +) +{ + return RtlLockHeap(RtlProcessHeap()); +} + +/* + * ntsupHeapUnlock + * + * Purpose: + * + * Wrapper for RtlUnlockHeap with process heap. + * + */ +BOOL ntsupHeapUnlock( + VOID +) +{ + return RtlUnlockHeap(RtlProcessHeap()); } /* @@ -497,7 +1220,7 @@ PVOID ntsupFindModuleEntryByName( moduleEntry = &ModulesList->Modules[i]; fnameOffset = moduleEntry->OffsetToFileName; entryName = (LPSTR)&moduleEntry->FullPathName[fnameOffset]; - if (_strcmpi_a(entryName, ModuleName) == 0) + if (ntsupStrCmpIA(entryName, ModuleName) == 0) return moduleEntry; } @@ -534,7 +1257,7 @@ PVOID ntsupFindModuleEntryByName_U( moduleEntry = &ModulesList->Modules[i]; fnameOffset = moduleEntry->OffsetToFileName; entryName = (LPSTR)&moduleEntry->FullPathName[fnameOffset]; - if (_strcmpi_a(entryName, moduleName.Buffer) == 0) { + if (ntsupStrCmpIA(entryName, moduleName.Buffer) == 0) { result = moduleEntry; break; } @@ -597,7 +1320,7 @@ PVOID ntsupGetModuleEntryByAddress( if (IN_REGION(Address, ModulesList->Modules[i].ImageBase, ModulesList->Modules[i].ImageSize)) - { + { return &ModulesList->Modules[i]; } } @@ -643,12 +1366,12 @@ PVOID ntsupFindModuleNameByAddress( (LPSTR)&moduleEntry->FullPathName[moduleEntry->OffsetToFileName], &usConvertedName); - if (NT_SUCCESS(ntStatus)) { + if (NT_SUCCESS(ntStatus) && (usConvertedName.Buffer != NULL)) { copyLength = usConvertedName.Length / sizeof(WCHAR); copyLength = MIN(copyLength, (SIZE_T)ccBuffer - 1); - _strncpy( + ntsupStrNCopy( Buffer, ccBuffer, usConvertedName.Buffer, @@ -1370,7 +2093,7 @@ BOOL ntsupQueryProcessName( if ((ULONG_PTR)List.Process->UniqueProcessId == dwProcessId) { - _strncpy( + ntsupStrNCopy( Buffer, ccBuffer, List.Process->ImageName.Buffer, @@ -1401,7 +2124,7 @@ BOOL ntsupQueryProcessName( BOOL ntsupQueryProcessEntryById( _In_ HANDLE UniqueProcessId, _In_ PVOID ProcessList, - _Out_ PSYSTEM_PROCESS_INFORMATION* Entry + _Out_ PSYSTEM_PROCESS_INFORMATION * Entry ) { ULONG NextEntryDelta = 0, iteration = 0; @@ -1495,7 +2218,7 @@ NTSTATUS ntsupQuerySystemObjectInformationVariableSize( _In_ PFN_NTQUERYROUTINE QueryRoutine, _In_opt_ HANDLE ObjectHandle, _In_ DWORD InformationClass, - _Out_ PVOID* Buffer, + _Out_ PVOID * Buffer, _Out_opt_ PULONG ReturnLength, _In_ PNTSUPMEMALLOC AllocMem, _In_ PNTSUPMEMFREE FreeMem @@ -1548,6 +2271,93 @@ NTSTATUS ntsupQuerySystemObjectInformationVariableSize( return ntStatus; } +/* +* ntsupQuerySystemObjectInformationVariableSizeEx +* +* Purpose: +* +* Generic object information query routine with automatic buffer growth. +* +* Use FreeMem to release allocated buffer. +* +*/ +NTSTATUS ntsupQuerySystemObjectInformationVariableSizeEx( + _In_ PFN_NTQUERYROUTINE QueryRoutine, + _In_opt_ HANDLE ObjectHandle, + _In_ DWORD InformationClass, + _Out_ PVOID* Buffer, + _Out_opt_ PULONG ReturnLength, + _In_ ULONG InitialBufferSize, + _In_ PNTSUPMEMALLOC AllocMem, + _In_ PNTSUPMEMFREE FreeMem +) +{ + NTSTATUS ntStatus; + PVOID queryBuffer; + ULONG bufferSize; + ULONG returnLengthLocal = 0; + + if (Buffer == NULL) + return STATUS_INVALID_PARAMETER; + + *Buffer = NULL; + + if (ReturnLength) + *ReturnLength = 0; + + bufferSize = (InitialBufferSize != 0) ? + InitialBufferSize : PAGE_SIZE; + + queryBuffer = AllocMem(bufferSize); + if (queryBuffer == NULL) + return STATUS_INSUFFICIENT_RESOURCES; + + while ((ntStatus = QueryRoutine( + ObjectHandle, + InformationClass, + queryBuffer, + bufferSize, + &returnLengthLocal)) == STATUS_INFO_LENGTH_MISMATCH || + ntStatus == STATUS_BUFFER_TOO_SMALL || + ntStatus == STATUS_BUFFER_OVERFLOW) + { + FreeMem(queryBuffer); + + // + // Prefer the returned size if available, + // otherwise grow exponentially. + // + if (returnLengthLocal > bufferSize) + bufferSize = returnLengthLocal; + else + bufferSize <<= 1; + + if (bufferSize == 0 || + bufferSize > MAX_NTSUP_BUFFER_SIZE) + { + return STATUS_INVALID_BUFFER_SIZE; + } + + queryBuffer = AllocMem(bufferSize); + if (queryBuffer == NULL) + return STATUS_INSUFFICIENT_RESOURCES; + } + + if (NT_SUCCESS(ntStatus)) { + + *Buffer = queryBuffer; + + if (ReturnLength) + *ReturnLength = returnLengthLocal; + + return ntStatus; + } + + FreeMem(queryBuffer); + + return ntStatus; +} + /* * ntsupQueryVsmProtectionInformation * @@ -1595,28 +2405,36 @@ BOOLEAN ntsupQueryVsmProtectionInformation( } /* -* ntsupQueryHVCIState +* ntsupQueryVBSState * * Purpose: * -* Query HVCI/IUM state. +* Query VBS/HVCI state. * */ -BOOLEAN ntsupQueryHVCIState( +BOOLEAN ntsupQueryVBSState( + _Out_ PBOOLEAN pbVBSRunning, _Out_ PBOOLEAN pbHVCIEnabled, - _Out_ PBOOLEAN pbHVCIStrictMode, - _Out_ PBOOLEAN pbHVCIIUMEnabled + _Out_ PBOOLEAN pbHVCIStrictMode ) { - BOOLEAN hvciEnabled; ULONG returnLength; NTSTATUS ntStatus; SYSTEM_CODEINTEGRITY_INFORMATION ci; + SYSTEM_ISOLATED_USER_MODE_INFORMATION iumi; - if (pbHVCIEnabled) *pbHVCIEnabled = FALSE; - if (pbHVCIStrictMode) *pbHVCIStrictMode = FALSE; - if (pbHVCIIUMEnabled) *pbHVCIIUMEnabled = FALSE; + if (pbVBSRunning) + *pbVBSRunning = FALSE; + if (pbHVCIEnabled) + *pbHVCIEnabled = FALSE; + + if (pbHVCIStrictMode) + *pbHVCIStrictMode = FALSE; + + // + // Query Code Integrity configuration. + // ci.Length = sizeof(ci); ntStatus = NtQuerySystemInformation( @@ -1625,50 +2443,76 @@ BOOLEAN ntsupQueryHVCIState( sizeof(ci), &returnLength); - if (NT_SUCCESS(ntStatus)) { + if (!NT_SUCCESS(ntStatus)) { + RtlSetLastWin32Error(RtlNtStatusToDosError(ntStatus)); + return FALSE; + } - hvciEnabled = ((ci.CodeIntegrityOptions & CODEINTEGRITY_OPTION_ENABLED) && + if (pbHVCIEnabled) { + *pbHVCIEnabled = ((ci.CodeIntegrityOptions & CODEINTEGRITY_OPTION_ENABLED) && (ci.CodeIntegrityOptions & CODEINTEGRITY_OPTION_HVCI_KMCI_ENABLED)); + } - if (pbHVCIEnabled) - *pbHVCIEnabled = hvciEnabled; + if (pbHVCIStrictMode) { + *pbHVCIStrictMode = ((ci.CodeIntegrityOptions & CODEINTEGRITY_OPTION_HVCI_KMCI_STRICTMODE_ENABLED) != 0); + } - if (pbHVCIStrictMode) - *pbHVCIStrictMode = (hvciEnabled == TRUE) && - (ci.CodeIntegrityOptions & CODEINTEGRITY_OPTION_HVCI_KMCI_STRICTMODE_ENABLED); + // + // Query VBS / Isolated User Mode state. + // + RtlSecureZeroMemory(&iumi, sizeof(iumi)); - if (pbHVCIIUMEnabled) - *pbHVCIIUMEnabled = (ci.CodeIntegrityOptions & CODEINTEGRITY_OPTION_HVCI_IUM_ENABLED) > 0; + ntStatus = NtQuerySystemInformation( + SystemIsolatedUserModeInformation, + &iumi, + sizeof(iumi), + &returnLength); - return TRUE; - } - else { + if (!NT_SUCCESS(ntStatus)) { RtlSetLastWin32Error(RtlNtStatusToDosError(ntStatus)); + return FALSE; } - return FALSE; + if (pbVBSRunning) + *pbVBSRunning = iumi.SecureKernelRunning; + + // + // Prefer the isolated user mode information for HVCI state. + // It reflects the actual VBS-backed HVCI status. + // + if (pbHVCIEnabled) *pbHVCIEnabled = iumi.HvciEnabled; + + if (pbHVCIStrictMode) *pbHVCIStrictMode = iumi.HvciStrictMode; + + return TRUE; } /* -* ntsupLookupImageSectionByName +* ntsupLookupImageSectionByNameEx * * Purpose: * -* Lookup section pointer and size for section name. +* Lookup PE image section by name. * +* If ImageSize is non-zero, the image is range-checked by +* RtlImageNtHeaderEx. Otherwise, range checking is disabled. +* */ -PVOID ntsupLookupImageSectionByName( +PVOID ntsupLookupImageSectionByNameEx( _In_ CHAR* SectionName, _In_ ULONG SectionNameLength, _In_ PVOID DllBase, - _Out_ PULONG SectionSize + _In_ SIZE_T ImageSize, + _Out_opt_ PULONG SectionSize ) { - BOOLEAN bFound = FALSE; + NTSTATUS ntStatus; ULONG i; + SIZE_T cbSectionTable; + ULONG ntHeaderFlags; PVOID Section; - IMAGE_NT_HEADERS* NtHeaders = RtlImageNtHeader(DllBase); - IMAGE_SECTION_HEADER* SectionTableEntry; + PIMAGE_NT_HEADERS NtHeaders; + PIMAGE_SECTION_HEADER SectionTableEntry; // // Assume failure. @@ -1676,44 +2520,89 @@ PVOID ntsupLookupImageSectionByName( if (SectionSize) *SectionSize = 0; - if (NtHeaders == NULL) + if (DllBase == NULL || + SectionName == NULL || + SectionNameLength == 0) + { return NULL; + } - SectionTableEntry = (PIMAGE_SECTION_HEADER)((PCHAR)NtHeaders + - sizeof(ULONG) + - sizeof(IMAGE_FILE_HEADER) + - NtHeaders->FileHeader.SizeOfOptionalHeader); + if (SectionNameLength > IMAGE_SIZEOF_SHORT_NAME) + SectionNameLength = IMAGE_SIZEOF_SHORT_NAME; + + // + // Determine whether image range checking is possible. + // + ntHeaderFlags = (ImageSize == 0) ? RTL_IMAGE_NT_HEADER_EX_FLAG_NO_RANGE_CHECK : 0; + + ntStatus = RtlImageNtHeaderEx(ntHeaderFlags, DllBase, ImageSize, &NtHeaders); + if (!NT_SUCCESS(ntStatus)) + return NULL; + + if (NtHeaders->FileHeader.NumberOfSections == 0) + return NULL; + + cbSectionTable = (SIZE_T)NtHeaders->FileHeader.NumberOfSections * + sizeof(IMAGE_SECTION_HEADER); + + // + // Overflow check. + // + if ((cbSectionTable / sizeof(IMAGE_SECTION_HEADER)) != + NtHeaders->FileHeader.NumberOfSections) + { + return NULL; + } + + SectionTableEntry = IMAGE_FIRST_SECTION(NtHeaders); + if (!ntsupIsAddressValid(SectionTableEntry, cbSectionTable)) + return NULL; // // Locate section. // - i = NtHeaders->FileHeader.NumberOfSections; - while (i > 0) { + for (i = 0; i < NtHeaders->FileHeader.NumberOfSections; i++, SectionTableEntry++) { - if (_strncmp_a( + if (ntsupStrNCmpA( (CHAR*)SectionTableEntry->Name, SectionName, SectionNameLength) == 0) { - bFound = TRUE; - break; - } + Section = RtlOffsetToPointer( + DllBase, + SectionTableEntry->VirtualAddress); - i -= 1; - SectionTableEntry += 1; - } + if (SectionSize) + *SectionSize = SectionTableEntry->Misc.VirtualSize; - // - // Section not found, abort scan. - // - if (!bFound) - return NULL; + return Section; + } + } - Section = (PVOID)((ULONG_PTR)DllBase + SectionTableEntry->VirtualAddress); - if (SectionSize) - *SectionSize = SectionTableEntry->Misc.VirtualSize; + return NULL; +} - return Section; +/* +* ntsupLookupImageSectionByName +* +* Purpose: +* +* Lookup PE image section by name. +* +*/ +PVOID ntsupLookupImageSectionByName( + _In_ CHAR* SectionName, + _In_ ULONG SectionNameLength, + _In_ PVOID DllBase, + _Out_ PULONG SectionSize +) +{ + return ntsupLookupImageSectionByNameEx( + SectionName, + SectionNameLength, + DllBase, + 0, // Unknown image size. + SectionSize); } /* @@ -1768,7 +2657,7 @@ PVOID ntsupFindPattern( * */ DWORD ntsupFindPatternEx( - _In_ PATTERN_SEARCH_PARAMS* SearchParams + _In_ PATTERN_SEARCH_PARAMS * SearchParams ) { PBYTE p; @@ -1952,6 +2841,52 @@ NTSTATUS ntsupPrivilegeEnabled( return status; } +/* +* ntsupSetEnvironmentVariable +* +* Purpose: +* +* Set environment variable. +* +*/ +BOOLEAN ntsupSetEnvironmentVariable( + _In_ LPCWSTR Name, + _In_opt_ LPCWSTR Value +) +{ + UNICODE_STRING usName; + UNICODE_STRING usValue; + NTSTATUS status; + + if (Name == NULL) + return FALSE; + + RtlInitUnicodeString( + &usName, + Name); + + if (Value != NULL) { + + RtlInitUnicodeString( + &usValue, + Value); + + status = RtlSetEnvironmentVariable( + NULL, + &usName, + &usValue); + } + else { + + status = RtlSetEnvironmentVariable( + NULL, + &usName, + NULL); + } + + return NT_SUCCESS(status); +} + /* * ntsupQueryEnvironmentVariableOffset * @@ -1968,6 +2903,9 @@ LPWSTR ntsupQueryEnvironmentVariableOffset( PWCHAR ptrEnvironment; ULONG scanCount = 0; + if (Value == NULL || Value->Buffer == NULL) + return NULL; + ptrEnvironment = (PWCHAR)RtlGetCurrentPeb()->ProcessParameters->Environment; do { @@ -1978,7 +2916,7 @@ LPWSTR ntsupQueryEnvironmentVariableOffset( if (RtlPrefixUnicodeString(Value, &str1, TRUE)) break; - ptrEnvironment += _strlen(ptrEnvironment) + 1; + ptrEnvironment += ntsupStrLen(ptrEnvironment) + 1; } while (1); @@ -2003,7 +2941,7 @@ DWORD ntsupExpandEnvironmentStrings( SIZE_T srcLength = 0, returnLength = 0, dstLength = (SIZE_T)nSize; if (lpSrc) { - srcLength = _strlen(lpSrc); + srcLength = ntsupStrLen(lpSrc); } ntStatus = RtlExpandEnvironmentStrings( @@ -2531,7 +3469,7 @@ NTSTATUS NTAPI ntsupDetectObjectCallback( } if (Entry->Name.Buffer) { - if (_strcmpi_w(Entry->Name.Buffer, Param->Buffer) == 0) { + if (ntsupStrCmpIW(Entry->Name.Buffer, Param->Buffer) == 0) { return STATUS_SUCCESS; } } @@ -2640,7 +3578,7 @@ BOOLEAN ntsupIsObjectExists( OBJSCANPARAM Param; Param.Buffer = ObjectName; - Param.BufferSize = (ULONG)_strlen(ObjectName); + Param.BufferSize = (ULONG)ntsupStrLen(ObjectName); return NT_SUCCESS(ntsupEnumSystemObjects(RootDirectory, NULL, ntsupDetectObjectCallback, &Param)); } @@ -2949,7 +3887,7 @@ NTSTATUS ntsupHashImageSections( if (!NT_SUCCESS(RtlImageNtHeaderEx(0, ImageBase, ImageSize, - (PIMAGE_NT_HEADERS*)&ntHeaders)) || ntHeaders == NULL) + (PIMAGE_NT_HEADERS*)&ntHeaders)) || ntHeaders == NULL) { return STATUS_INVALID_IMAGE_FORMAT; } @@ -2961,7 +3899,7 @@ NTSTATUS ntsupHashImageSections( // Validate image size matches reported size. // if (ntHeaders->OptionalHeader.SizeOfImage > ImageSize && - ImageType == ImageTypeLoaded) + ImageType == ImageTypeLoaded) { return STATUS_INVALID_IMAGE_FORMAT; } @@ -3052,7 +3990,7 @@ NTSTATUS ntsupHashImageSections( } if (sectionStart < baseAddress || - sectionStart >= baseAddress + ImageSize) + sectionStart >= baseAddress + ImageSize) { continue; } diff --git a/Source/Shared/ntos/ntsup.h b/Source/Shared/ntos/ntsup.h index 916560a..85a7f62 100644 --- a/Source/Shared/ntos/ntsup.h +++ b/Source/Shared/ntos/ntsup.h @@ -4,14 +4,13 @@ * * TITLE: NTSUP.H * -* VERSION: 2.27 +* VERSION: 2.30 * -* DATE: 27 Jun 2026 +* DATE: 25 Jul 2026 * * Common header file for the NT API support functions and definitions. * * Depends on: ntos.h -* minirtl * * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED @@ -49,8 +48,6 @@ #include #undef _NTDEF_ -#include "minirtl/minirtl.h" - #ifdef ENABLE_C_EXTERN #if defined(__cplusplus) extern "C" { @@ -70,8 +67,6 @@ typedef PVOID(CALLBACK* PNTSUPMEMALLOC)( typedef BOOL(CALLBACK* PNTSUPMEMFREE)( _In_ PVOID Memory); -#define ntsupProcessHeap() NtCurrentPeb()->ProcessHeap - #define NTSUPHASH_SHA256_SIZE 32 #define MAX_NTSUP_BUFFER_SIZE (512 * 1024 * 1024) //512MB @@ -109,12 +104,169 @@ typedef enum _NTSUP_IMAGE_TYPE { ImageTypeLoaded // Loaded module (PEB/LdrEntry) } NTSUP_IMAGE_TYPE; +typedef struct _NTSUP_SHA256_CTX { + ULONG State[8]; + ULONG64 BitCount; + UCHAR Buffer[64]; +} NTSUP_SHA256_CTX, * PNTSUP_SHA256_CTX; + +VOID ntsupSha256Init( + _Out_ PNTSUP_SHA256_CTX Ctx); + +VOID ntsupSha256Update( + _Inout_ PNTSUP_SHA256_CTX Ctx, + _In_reads_bytes_(Length) const UCHAR* Data, + _In_ SIZE_T Length); + +VOID ntsupSha256Final( + _Inout_ PNTSUP_SHA256_CTX Ctx, + _Out_writes_bytes_all_(32) UCHAR Digest[32]); + +// +// Ronova requires get rid of minirtl. +// + +// +// Minirtl section START +// +FORCEINLINE CHAR ntsupLowerCharA( + _In_ CHAR c +) +{ + if ((c >= 'A') && (c <= 'Z')) + return c + 0x20; + else + return c; +} + +FORCEINLINE WCHAR ntsupLowerCharW( + _In_ WCHAR c +) +{ + if ((c >= L'A') && (c <= L'Z')) + return c + 0x20; + else + return c; +} + +SIZE_T ntsupStrLenA( + _In_opt_ LPCSTR String); +SIZE_T ntsupStrLenW( + _In_opt_ LPCWSTR String); + +INT ntsupStrCmpA( + _In_opt_ LPCSTR String1, + _In_opt_ LPCSTR String2); +INT ntsupStrCmpW( + _In_opt_ LPCWSTR String1, + _In_opt_ LPCWSTR String2); + +INT ntsupStrCmpIA( + _In_opt_ LPCSTR String1, + _In_opt_ LPCSTR String2); +INT ntsupStrCmpIW( + _In_opt_ LPCWSTR String1, + _In_opt_ LPCWSTR String2); + +LPSTR ntsupStrNCopyA( + _Out_writes_(DestinationCount) LPSTR Destination, + _In_ SIZE_T DestinationCount, + _In_reads_(SourceCount) LPCSTR Source, + _In_ SIZE_T SourceCount); + +LPWSTR ntsupStrNCopyW( + _Out_writes_(DestinationCount) LPWSTR Destination, + _In_ SIZE_T DestinationCount, + _In_reads_(SourceCount) LPCWSTR Source, + _In_ SIZE_T SourceCount); + +INT ntsupStrNCmpA( + _In_opt_ LPCSTR String1, + _In_opt_ LPCSTR String2, + _In_ SIZE_T Count); +INT ntsupStrNCmpW( + _In_opt_ LPCWSTR String1, + _In_opt_ LPCWSTR String2, + _In_ SIZE_T Count); + +LPCSTR ntsupStrStrIA( + _In_ LPCSTR String, + _In_ LPCSTR SubString); +LPCWSTR ntsupStrStrIW( + _In_ LPCWSTR String, + _In_ LPCWSTR SubString); + +LPSTR ntsupStrCatA( + _Inout_ LPSTR Destination, + _In_ LPCSTR Source); +LPWSTR ntsupStrCatW( + _Inout_ LPWSTR Destination, + _In_ LPCWSTR Source); + +LPSTR ntsupStrCatExA( + _Inout_updates_z_(DestinationCount) LPSTR Destination, + _In_ SIZE_T DestinationCount, + _In_ LPCSTR Source); +LPWSTR ntsupStrCatExW( + _Inout_updates_z_(DestinationCount) LPWSTR Destination, + _In_ SIZE_T DestinationCount, + _In_ LPCWSTR Source); + +#ifdef _UNICODE +#define ntsupLowerChar ntsupLowerCharW +#define ntsupStrLen ntsupStrLenW +#define ntsupStrCmp ntsupStrCmpW +#define ntsupStrCmpI ntsupStrCmpIW +#define ntsupStrNCopy ntsupStrNCopyW +#define ntsupStrNCmp ntsupStrNCmpW +#define ntsupStrStrI ntsupStrStrIW +#define ntsupStrCat ntsupStrCatW +#define ntsupStrCatEx ntsupStrCatExW +#else +#define ntsupLowerChar ntsupLowerCharA +#define ntsupStrLen ntsupStrLenA +#define ntsupStrCmp ntsupStrCmpA +#define ntsupStrCmpI ntsupStrCmpIA +#define ntsupStrNCopy ntsupStrNCopyA +#define ntsupStrNCmp ntsupStrNCmpA +#define ntsupStrStrI ntsupStrStrIA +#define ntsupStrCat ntsupStrCatA +#define ntsupStrCatEx ntsupStrCatExA +#endif + +// +// Minirtl section END +// + PVOID ntsupHeapAlloc( _In_ SIZE_T Size); +PVOID ntsupHeapReAlloc( + _In_ PVOID BaseAddress, + _In_ SIZE_T Size); + BOOL ntsupHeapFree( _In_ PVOID BaseAddress); +SIZE_T ntsupHeapSize( + _In_ PVOID BaseAddress); + +BOOL ntsupHeapValidate( + _In_ PVOID BaseAddress); + +SIZE_T ntsupHeapCompact( + VOID); + +BOOL ntsupHeapLock( + VOID); + +BOOL ntsupHeapUnlock( + VOID); + +BOOLEAN ntsupIsAddressValid( + _In_ PVOID Address, + _In_ SIZE_T Size); + PVOID ntsupVirtualAllocEx( _In_ SIZE_T Size, _In_ ULONG AllocationType, @@ -280,16 +432,33 @@ NTSTATUS ntsupQuerySystemObjectInformationVariableSize( _In_ PNTSUPMEMALLOC AllocMem, _In_ PNTSUPMEMFREE FreeMem); +NTSTATUS ntsupQuerySystemObjectInformationVariableSizeEx( + _In_ PFN_NTQUERYROUTINE QueryRoutine, + _In_opt_ HANDLE ObjectHandle, + _In_ DWORD InformationClass, + _Out_ PVOID * Buffer, + _Out_opt_ PULONG ReturnLength, + _In_ ULONG InitialBufferSize, + _In_ PNTSUPMEMALLOC AllocMem, + _In_ PNTSUPMEMFREE FreeMem); + BOOLEAN ntsupQueryVsmProtectionInformation( _Out_ PBOOLEAN pbDmaProtectionsAvailable, _Out_ PBOOLEAN pbDmaProtectionsInUse, _Out_ PBOOLEAN pbHardwareMbecAvailable, _Out_ PBOOLEAN pbApicVirtualizationAvailable); -BOOLEAN ntsupQueryHVCIState( +BOOLEAN ntsupQueryVBSState( + _Out_ PBOOLEAN pbVBSRunning, _Out_ PBOOLEAN pbHVCIEnabled, - _Out_ PBOOLEAN pbHVCIStrictMode, - _Out_ PBOOLEAN pbHVCIIUMEnabled); + _Out_ PBOOLEAN pbHVCIStrictMode); + +PVOID ntsupLookupImageSectionByNameEx( + _In_ CHAR * SectionName, + _In_ ULONG SectionNameLength, + _In_ PVOID DllBase, + _In_ SIZE_T ImageSize, + _Out_opt_ PULONG SectionSize); PVOID ntsupLookupImageSectionByName( _In_ CHAR* SectionName, @@ -327,6 +496,10 @@ NTSTATUS ntsupPrivilegeEnabled( LPWSTR ntsupQueryEnvironmentVariableOffset( _In_ PUNICODE_STRING Value); +BOOLEAN ntsupSetEnvironmentVariable( + _In_ LPCWSTR Name, + _In_opt_ LPCWSTR Value); + DWORD ntsupExpandEnvironmentStrings( _In_ LPCWSTR lpSrc, _Out_writes_to_opt_(nSize, return) LPWSTR lpDst, @@ -409,6 +582,12 @@ ntsupQuerySystemObjectInformationVariableSize((PFN_NTQUERYROUTINE)NtQueryObject, ObjectHandle, ObjectInformationClass, (PVOID*)Buffer, ReturnLength, \ (PNTSUPMEMALLOC)AllocMem, (PNTSUPMEMFREE)FreeMem) +#define ntsupQueryObjectInformationEx(\ + ObjectHandle, ObjectInformationClass, Buffer, ReturnLength, InitialBufferSize, AllocMem, FreeMem) \ +ntsupQuerySystemObjectInformationVariableSizeEx((PFN_NTQUERYROUTINE)NtQueryObject, \ + ObjectHandle, ObjectInformationClass, (PVOID*)Buffer, ReturnLength, InitialBufferSize, \ + (PNTSUPMEMALLOC)AllocMem, (PNTSUPMEMFREE)FreeMem) + #define ntsupQueryThreadInformation(\ ThreadHandle, ThreadInformationClass, Buffer, ReturnLength, AllocMem, FreeMem) \ ntsupQuerySystemObjectInformationVariableSize((PFN_NTQUERYROUTINE)NtQueryInformationThread, \ diff --git a/Source/WinObjEx64/Resource.rc b/Source/WinObjEx64/Resource.rc index 4f66c8ec5e634e30773524d3c3bb2f8d7c985873..a5d735d007fcff6a6e32fad4221082f60fed477c 100644 GIT binary patch delta 94 zcmX@Nfa}}>t_?i4+(ryK3`PuQ3t_?i4+=dJ~3`PuQ3false rsrc\obex.manifest true + true false @@ -178,6 +179,7 @@ false rsrc\obex.manifest true + true false @@ -230,6 +232,7 @@ false rsrc\obex.manifest true + true false @@ -279,6 +282,7 @@ false rsrc\obex.manifest true + true false @@ -331,6 +335,7 @@ false rsrc\obex.manifest true + true false @@ -418,7 +423,6 @@ - @@ -473,7 +477,6 @@ - diff --git a/Source/WinObjEx64/WinObjEx64.vcxproj.filters b/Source/WinObjEx64/WinObjEx64.vcxproj.filters index b42f146..202c545 100644 --- a/Source/WinObjEx64/WinObjEx64.vcxproj.filters +++ b/Source/WinObjEx64/WinObjEx64.vcxproj.filters @@ -264,9 +264,6 @@ Minirtl - - Source Files\tests - Source Files\tests @@ -418,9 +415,6 @@ Minirtl - - Source Files\tests - Source Files\tests diff --git a/Source/WinObjEx64/aboutDlg.c b/Source/WinObjEx64/aboutDlg.c index ac5d7c2..5c8eb98 100644 --- a/Source/WinObjEx64/aboutDlg.c +++ b/Source/WinObjEx64/aboutDlg.c @@ -193,7 +193,7 @@ VOID AboutDialogInit( } g_kdctx.IsSecureBoot = bSecureBoot; - if (supQueryHVCIState(&bHVCIEnabled, &bHVCIStrict, &bHVCIIUMEnabled)) { + if (supQueryVBSState(&bHVCIIUMEnabled, &bHVCIEnabled, &bHVCIStrict)) { if (bHVCIEnabled) { _strcat(szBuffer, TEXT(", HVCI")); if (bHVCIStrict) diff --git a/Source/WinObjEx64/extras/extrasCallbacks.c b/Source/WinObjEx64/extras/extrasCallbacks.c index d6275c0..9c76173 100644 --- a/Source/WinObjEx64/extras/extrasCallbacks.c +++ b/Source/WinObjEx64/extras/extrasCallbacks.c @@ -4,9 +4,9 @@ * * TITLE: EXTRASCALLBACKS.C * -* VERSION: 2.11 +* VERSION: 2.12 * -* DATE: 11 Jul 2026 +* DATE: 26 Jul 2026 * * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED @@ -1067,10 +1067,11 @@ OBEX_FINDCALLBACK_ROUTINE(FindCiCallbacks) // // Locate PAGE image section as required variable is always in PAGE. // - SectionBase = supLookupImageSectionByName( + SectionBase = supLookupImageSectionByNameEx( PAGE_SECTION, PAGE_SECTION_LENGTH, g_kdctx.NtOsImageMap, + g_kdctx.NtOsImageSize, &SectionSize); if ((SectionBase == 0) || (SectionSize == 0)) @@ -3222,10 +3223,11 @@ OBEX_FINDCALLBACK_ROUTINE(FindEmpCallbackListHead) // // Locate PAGE image section as required variable is always in PAGE. // - SectionBase = supLookupImageSectionByName( + SectionBase = supLookupImageSectionByNameEx( PAGE_SECTION, PAGE_SECTION_LENGTH, g_kdctx.NtOsImageMap, + g_kdctx.NtOsImageSize, &SectionSize); if ((SectionBase == 0) || (SectionSize == 0)) diff --git a/Source/WinObjEx64/extras/extrasSSDT.c b/Source/WinObjEx64/extras/extrasSSDT.c index 002cb90..806f0de 100644 --- a/Source/WinObjEx64/extras/extrasSSDT.c +++ b/Source/WinObjEx64/extras/extrasSSDT.c @@ -4,9 +4,9 @@ * * TITLE: EXTRASSSDT.C * -* VERSION: 2.11 +* VERSION: 2.12 * -* DATE: 12 Jul 2026 +* DATE: 26 Jul 2026 * * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED @@ -206,6 +206,7 @@ BOOL SdtListCreateTable( { if (!kdFindKiServiceTable( (ULONG_PTR)g_kdctx.NtOsImageMap, + g_kdctx.NtOsImageSize, (ULONG_PTR)g_kdctx.NtOsBase, &g_kdctx.Data->KeServiceDescriptorTable)) { @@ -579,7 +580,7 @@ BOOL SdtListCreateTableShadow( lpFunctionName = tableEntry->Name; tableEntry->KernelStubAddress = g_SDTCtx.W32pServiceTableUserBase[i]; - functionPtr = (PBYTE)g_SDTCtx.KernelModule + tableEntry->KernelStubAddress; + functionPtr = (PBYTE)g_SDTCtx.MappedKernelModule + tableEntry->KernelStubAddress; tableEntry->KernelStubAddress += g_SDTCtx.KernelBaseAddress; sdtFn.ServiceName = tableEntry->Name; diff --git a/Source/WinObjEx64/kldbg.c b/Source/WinObjEx64/kldbg.c index 3cf5a90..9204c1f 100644 --- a/Source/WinObjEx64/kldbg.c +++ b/Source/WinObjEx64/kldbg.c @@ -4,9 +4,9 @@ * * TITLE: KLDBG.C, based on KDSubmarine by Evilcry * -* VERSION: 2.10 +* VERSION: 2.12 * -* DATE: 27 Feb 2026 +* DATE: 25 Jul 2026 * * MINIMUM SUPPORTED OS WINDOWS 7 * @@ -1295,7 +1295,8 @@ PVOID ObFindPrivateNamespaceLookupTable2( ESERVERSILO_GLOBALS PspHostSiloGlobals; - HMODULE hNtOs = (HMODULE)Context->NtOsImageMap; + HMODULE hLoadedNtOs = (HMODULE)Context->NtOsImageMap; + ULONG hLoadedNtOsSize = Context->NtOsImageSize; do { @@ -1319,9 +1320,10 @@ PVOID ObFindPrivateNamespaceLookupTable2( // // Locate .text image section. // - SectionBase = supLookupImageSectionByName(TEXT_SECTION, + SectionBase = supLookupImageSectionByNameEx(TEXT_SECTION, TEXT_SECTION_LENGTH, - (PVOID)hNtOs, + (PVOID)hLoadedNtOs, + hLoadedNtOsSize, &SectionSize); if (SectionBase == NULL || SectionSize == 0) @@ -1333,7 +1335,7 @@ PVOID ObFindPrivateNamespaceLookupTable2( // if (g_NtBuildNumber >= NT_WIN10_REDSTONE4) { - ptrCode = (PBYTE)GetProcAddress(hNtOs, "PsGetServerSiloServiceSessionId"); + ptrCode = (PBYTE)GetProcAddress(hLoadedNtOs, "PsGetServerSiloServiceSessionId"); } else { @@ -1369,7 +1371,7 @@ PVOID ObFindPrivateNamespaceLookupTable2( // Find address to PspHostSiloGlobals in code. // varAddress = ObFindAddress((ULONG_PTR)Context->NtOsBase, - (ULONG_PTR)hNtOs, + (ULONG_PTR)hLoadedNtOs, IL_PspHostSiloGlobals, ptrCode, DA_ScanBytesPNSVariant1, @@ -1427,7 +1429,8 @@ PVOID ObFindPrivateNamespaceLookupTable( PVOID SectionBase; ULONG SectionSize = 0; - HMODULE hNtOs = (HMODULE)Context->NtOsImageMap; + HMODULE hLoadedNtOs = (HMODULE)Context->NtOsImageMap; + ULONG hLoadedNtOsSize = Context->NtOsImageSize; if (g_NtBuildNumber > NT_WIN10_THRESHOLD2) return ObFindPrivateNamespaceLookupTable2(Context); @@ -1437,9 +1440,10 @@ PVOID ObFindPrivateNamespaceLookupTable( // // Locate PAGE image section. // - SectionBase = supLookupImageSectionByName(PAGE_SECTION, + SectionBase = supLookupImageSectionByNameEx(PAGE_SECTION, PAGE_SECTION_LENGTH, - (PVOID)hNtOs, + (PVOID)hLoadedNtOs, + hLoadedNtOsSize, &SectionSize); if ((SectionBase == 0) || (SectionSize == 0)) @@ -1467,7 +1471,7 @@ PVOID ObFindPrivateNamespaceLookupTable( break; Address = ObFindAddress((ULONG_PTR)Context->NtOsBase, - (ULONG_PTR)hNtOs, + (ULONG_PTR)hLoadedNtOs, IL_PspHostSiloGlobals, ptrCode, DA_ScanBytesPNSVariant2, @@ -1521,6 +1525,7 @@ PVOID ObGetCallbackBlockRoutine( */ BOOL kdpFindKiServiceTableByPattern( _In_ ULONG_PTR MappedImageBase, + _In_ ULONG MappedImageSize, _In_ ULONG_PTR KernelImageBase, _Out_ ULONG_PTR * Address ) @@ -1534,9 +1539,10 @@ BOOL kdpFindKiServiceTableByPattern( // // Locate .text image section. // - sectionBase = (ULONG_PTR)supLookupImageSectionByName(TEXT_SECTION, + sectionBase = (ULONG_PTR)supLookupImageSectionByNameEx(TEXT_SECTION, TEXT_SECTION_LENGTH, (PVOID)MappedImageBase, + MappedImageSize, §ionSize); if (sectionBase == 0) @@ -1589,6 +1595,7 @@ BOOL kdpFindKiServiceTableByPattern( */ BOOL kdFindKiServiceTable( _In_ ULONG_PTR MappedImageBase, + _In_ ULONG MappedImageSize, _In_ ULONG_PTR KernelImageBase, _Inout_ KSERVICE_TABLE_DESCRIPTOR * ServiceTable ) @@ -1622,7 +1629,9 @@ BOOL kdFindKiServiceTable( // if (varAddress == 0) { - if (!kdpFindKiServiceTableByPattern(MappedImageBase, + if (!kdpFindKiServiceTableByPattern( + MappedImageBase, + MappedImageSize, KernelImageBase, &varAddress)) { @@ -2945,6 +2954,7 @@ BOOL kdLoadNtKernelImage( { PUCHAR pModuleName; PRTL_PROCESS_MODULES pModulesList = NULL; + PLDR_DATA_TABLE_ENTRY pModuleEntry = NULL; WCHAR szFileName[(4 + MAX_PATH) * 2]; @@ -2976,16 +2986,16 @@ BOOL kdLoadNtKernelImage( DONT_RESOLVE_DLL_REFERENCES); if (Context->NtOsImageMap) { - - supLoadSymbolsForNtImage( - (PSYMCONTEXT)g_kdctx.NtOsSymContext, - szFileName, - Context->NtOsImageMap, - 0, - NULL); - + if (NT_SUCCESS(LdrFindEntryForAddress(Context->NtOsImageMap, &pModuleEntry))) { + Context->NtOsImageSize = pModuleEntry->SizeOfImage; + supLoadSymbolsForNtImage( + (PSYMCONTEXT)g_kdctx.NtOsSymContext, + szFileName, + Context->NtOsImageMap, + 0, + NULL); + } } - } return (Context->NtOsImageMap != NULL); @@ -3086,14 +3096,14 @@ BOOLEAN kdpQueryMmUnloadedDrivers( _In_ PKLDBGCONTEXT Context ) { - HMODULE hNtOs; + HMODULE hLoadedNtOs; ULONG_PTR NtOsBase, lookupAddress = 0; PBYTE ptrCode, sigPattern; PVOID SectionBase; ULONG SectionSize = 0; - ULONG sigSize; + ULONG sigSize, hLoadedNtOsSize; ULONG Index = 0, instLength = 0, tempOffset; LONG relativeValue = 0; @@ -3105,7 +3115,8 @@ BOOLEAN kdpQueryMmUnloadedDrivers( return TRUE; NtOsBase = (ULONG_PTR)g_kdctx.NtOsBase; - hNtOs = (HMODULE)g_kdctx.NtOsImageMap; + hLoadedNtOs = (HMODULE)g_kdctx.NtOsImageMap; + hLoadedNtOsSize = g_kdctx.NtOsImageSize; do { @@ -3129,9 +3140,10 @@ BOOLEAN kdpQueryMmUnloadedDrivers( // // Locate PAGE image section. // - SectionBase = supLookupImageSectionByName(PAGE_SECTION, + SectionBase = supLookupImageSectionByNameEx(PAGE_SECTION, PAGE_SECTION_LENGTH, - (PVOID)hNtOs, + (PVOID)hLoadedNtOs, + hLoadedNtOsSize, &SectionSize); if ((SectionBase == 0) || (SectionSize == 0)) diff --git a/Source/WinObjEx64/kldbg.h b/Source/WinObjEx64/kldbg.h index d080dba..95109df 100644 --- a/Source/WinObjEx64/kldbg.h +++ b/Source/WinObjEx64/kldbg.h @@ -1,12 +1,12 @@ /******************************************************************************* * -* (C) COPYRIGHT AUTHORS, 2015 - 2025 +* (C) COPYRIGHT AUTHORS, 2015 - 2026 * * TITLE: KLDBG.H * -* VERSION: 2.09 +* VERSION: 2.12 * -* DATE: 19 Aug 2025 +* DATE: 24 Jul 2026 * * Common header file for the Kernel Debugger Driver support. * @@ -263,8 +263,9 @@ typedef struct _KLDBGCONTEXT { PVOID NtOsBase; ULONG NtOsSize; - //ntoskrnl mapped image + //ntoskrnl mapped image and size PVOID NtOsImageMap; + ULONG NtOsImageSize; //system range start ULONG_PTR SystemRangeStart; @@ -577,6 +578,7 @@ PVOID kdQueryIopInvalidDeviceRequest( BOOL kdFindKiServiceTable( _In_ ULONG_PTR MappedImageBase, + _In_ ULONG MappedImageSize, _In_ ULONG_PTR KernelImageBase, _Inout_ KSERVICE_TABLE_DESCRIPTOR* ServiceTable); diff --git a/Source/WinObjEx64/sup/sup.c b/Source/WinObjEx64/sup/sup.c index 5461d68..9797e79 100644 --- a/Source/WinObjEx64/sup/sup.c +++ b/Source/WinObjEx64/sup/sup.c @@ -4,9 +4,9 @@ * * TITLE: SUP.C * -* VERSION: 2.11 +* VERSION: 2.12 * -* DATE: 11 Jul 2026 +* DATE: 25 Jul 2026 * * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED @@ -1128,37 +1128,17 @@ PVOID supGetTokenInfo( ) { PVOID Buffer = NULL; - ULONG returnLength = 0; - - if (ReturnLength) - *ReturnLength = 0; - NtQueryInformationToken(TokenHandle, + if (NT_SUCCESS(supQueryTokenInformation( + TokenHandle, TokenInformationClass, - NULL, - 0, - &returnLength); - - Buffer = supHeapAlloc((SIZE_T)returnLength); - if (Buffer) { - - if (NT_SUCCESS(NtQueryInformationToken(TokenHandle, - TokenInformationClass, - Buffer, - returnLength, - &returnLength))) - { - if (ReturnLength) - *ReturnLength = returnLength; - return Buffer; - } - else { - supHeapFree(Buffer); - return NULL; - } + &Buffer, + ReturnLength))) + { + return Buffer; } - return Buffer; + return NULL; } /* @@ -1223,24 +1203,6 @@ PVOID supGetSystemInfo( (PNTSUPMEMFREE)supHeapFree); } -/* -* supxFreeObjectTypes -* -* Purpose: -* -* Free object types memory callback. -* -*/ -BOOL CALLBACK supxFreeObjectTypes( - _In_opt_ PVOID Context -) -{ - if (Context) - supHeapFree(Context); - - return TRUE; -} - /* * supGetObjectTypesInfo * @@ -1255,38 +1217,16 @@ PVOID supGetObjectTypesInfo( VOID ) { - PVOID buffer = NULL; - ULONG bufferSize = 1024 * 16; - NTSTATUS ntStatus; - ULONG returnedLength = 0; - - buffer = supHeapAlloc((SIZE_T)bufferSize); - if (buffer == NULL) - return NULL; + PVOID buffer = NULL; + ULONG returnedLength = 0; - while ((ntStatus = NtQueryObject( - NULL, - ObjectTypesInformation, - buffer, - bufferSize, - &returnedLength)) == STATUS_INFO_LENGTH_MISMATCH) + if (NT_SUCCESS(supQueryObjectTypesInformation(&buffer, + &returnedLength, + 1024 * 16))) { - supHeapFree(buffer); - bufferSize *= 2; - - if (bufferSize > (16 * 1024 * 1024)) - return NULL; - - buffer = supHeapAlloc((SIZE_T)bufferSize); - } - - if (NT_SUCCESS(ntStatus)) { return buffer; } - - if (buffer) - supHeapFree(buffer); - + return NULL; } diff --git a/Source/WinObjEx64/sup/sup.h b/Source/WinObjEx64/sup/sup.h index 05ce70d..1ae3aee 100644 --- a/Source/WinObjEx64/sup/sup.h +++ b/Source/WinObjEx64/sup/sup.h @@ -4,9 +4,9 @@ * * TITLE: SUP.H * -* VERSION: 2.11 +* VERSION: 2.12 * -* DATE: 12 Jul 2026 +* DATE: 25 Jul 2026 * * Common header file for the program support routines. * @@ -425,8 +425,8 @@ BOOL supHeapFree( #define supQueryProcessEntryById ntsupQueryProcessEntryById #define supWriteBufferToFile ntsupWriteBufferToFile #define supQueryVsmProtectionInformation ntsupQueryVsmProtectionInformation -#define supQueryHVCIState ntsupQueryHVCIState -#define supLookupImageSectionByName ntsupLookupImageSectionByName +#define supQueryVBSState ntsupQueryVBSState +#define supLookupImageSectionByNameEx ntsupLookupImageSectionByNameEx #define supFindPattern ntsupFindPattern #define supFindPatternEx ntsupFindPatternEx #define supOpenProcess ntsupOpenProcess @@ -457,6 +457,12 @@ BOOL supHeapFree( #define supQueryThreadInformation(ThreadHandle, ThreadInformationClass, Buffer, ReturnLength) \ ntsupQueryThreadInformation(ThreadHandle, ThreadInformationClass, Buffer, ReturnLength, supHeapAlloc, supHeapFree) +#define supQueryTokenInformation(TokenHandle, TokenInformationClass, Buffer, ReturnLength) \ + ntsupQueryTokenInformation(TokenHandle, TokenInformationClass, Buffer, ReturnLength, supHeapAlloc, supHeapFree) + +#define supQueryObjectTypesInformation(Buffer, ReturnLength, InitialBufferSize) \ + ntsupQueryObjectInformationEx(NULL, ObjectTypesInformation, Buffer, ReturnLength, InitialBufferSize, supHeapAlloc, supHeapFree) + FORCEINLINE BOOLEAN supUnicodeStringValid( _In_ PUNICODE_STRING SourceString ) diff --git a/Source/WinObjEx64/sup/w32k.c b/Source/WinObjEx64/sup/w32k.c index 8eca5a2..99cecba 100644 --- a/Source/WinObjEx64/sup/w32k.c +++ b/Source/WinObjEx64/sup/w32k.c @@ -4,9 +4,9 @@ * * TITLE: W32K.C * -* VERSION: 2.11 +* VERSION: 2.12 * -* DATE: 22 Jun 2026 +* DATE: 25 Jul 2026 * * Win32k syscall table actual handlers resolving routines. * @@ -110,7 +110,8 @@ PBYTE ApiSetFindWin32kApiSetTableRef( * */ ULONG_PTR SdtpQueryWin32kApiSetTable( - _In_ HMODULE hModule, + _In_ HMODULE Win32kModule, + _In_ ULONG Win32kModuleSize, _In_ PVOID ImageBase, _In_ ULONG_PTR ImageSize, _In_opt_ SYMCONTEXT* SymContext @@ -118,7 +119,7 @@ ULONG_PTR SdtpQueryWin32kApiSetTable( { LONG relativeValue = 0; ULONG SectionSize = 0, Index; - PBYTE ptrCode = (PBYTE)hModule; + PBYTE ptrCode = (PBYTE)Win32kModule; PVOID SectionBase; ULONG_PTR tableAddress = 0, instructionLength = 0; hde64s hs; @@ -131,7 +132,7 @@ ULONG_PTR SdtpQueryWin32kApiSetTable( ImageSize, &tableAddress)) { - tableAddress = tableAddress - (ULONG_PTR)ImageBase + (ULONG_PTR)hModule; + tableAddress = tableAddress - (ULONG_PTR)ImageBase + (ULONG_PTR)Win32kModule; } } @@ -141,9 +142,10 @@ ULONG_PTR SdtpQueryWin32kApiSetTable( // // Locate .text image section as required variable is always in .text. // - SectionBase = supLookupImageSectionByName(TEXT_SECTION, + SectionBase = supLookupImageSectionByNameEx(TEXT_SECTION, TEXT_SECTION_LENGTH, - (PVOID)hModule, + (PVOID)Win32kModule, + Win32kModuleSize, &SectionSize); if (SectionBase == 0 || SectionSize == 0) @@ -192,8 +194,8 @@ ULONG_PTR SdtpQueryWin32kApiSetTable( // Sanity check. // tableAddress = (ULONG_PTR)ptrCode + Index + instructionLength + relativeValue; - if (tableAddress < (ULONG_PTR)hModule || - tableAddress >= ((ULONG_PTR)hModule + ImageSize)) + if (tableAddress < (ULONG_PTR)Win32kModule || + tableAddress >= ((ULONG_PTR)Win32kModule + ImageSize)) { return 0; } @@ -725,22 +727,22 @@ NTSTATUS SdtResolveModuleFromImportThunk( pFuncThunk = (PIMAGE_THUNK_DATA)((ULONG_PTR)FunctionPtr + hs.len + rel); pImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)RtlImageDirectoryEntryToData( - Context->KernelModule, + Context->MappedKernelModule, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &importSize); for (pIID = pImportDescriptor; pIID->Name != 0; pIID++) { - pOrigFirstThunk = (PIMAGE_THUNK_DATA)RtlOffsetToPointer(Context->KernelModule, pIID->OriginalFirstThunk); - pFirstThunk = (PIMAGE_THUNK_DATA)RtlOffsetToPointer(Context->KernelModule, pIID->FirstThunk); + pOrigFirstThunk = (PIMAGE_THUNK_DATA)RtlOffsetToPointer(Context->MappedKernelModule, pIID->OriginalFirstThunk); + pFirstThunk = (PIMAGE_THUNK_DATA)RtlOffsetToPointer(Context->MappedKernelModule, pIID->FirstThunk); for (; pOrigFirstThunk->u1.AddressOfData; ++pOrigFirstThunk, ++pFirstThunk) { - pImageImportByName = (PIMAGE_IMPORT_BY_NAME)RtlOffsetToPointer(Context->KernelModule, + pImageImportByName = (PIMAGE_IMPORT_BY_NAME)RtlOffsetToPointer(Context->MappedKernelModule, pOrigFirstThunk->u1.AddressOfData); if (pFirstThunk == pFuncThunk) { - pszDllName = (LPCSTR)RtlOffsetToPointer(Context->KernelModule, pIID->Name); + pszDllName = (LPCSTR)RtlOffsetToPointer(Context->MappedKernelModule, pIID->Name); return SdtMapModuleFromImportThunkWithResolve( pszDllName, @@ -1118,6 +1120,7 @@ ULONG SdtWin32kInitializeOnce( ULONG ulResult = 0, schemaVersion; ULONG_PTR varAddress; PULONG pKernelLimit; + PLDR_DATA_TABLE_ENTRY pMappedModule; PRTL_PROCESS_MODULE_INFORMATION pModule; HANDLE heapHandle; HMODULE hModule; @@ -1189,7 +1192,12 @@ ULONG SdtWin32kInitializeOnce( ulResult = ErrShadowWin32kLoadFail; break; } - Context->KernelModule = hModule; + Context->MappedKernelModule = hModule; + if (!NT_SUCCESS(LdrFindEntryForAddress(hModule, &pMappedModule))) { + ulResult = ErrShadowWin32kLoadFail; + break; + } + Context->MappedKernelModuleSize = pMappedModule->SizeOfImage; // // Check whatever win32u is compatible with win32k data, compare number of services. @@ -1209,7 +1217,7 @@ ULONG SdtWin32kInitializeOnce( // Query win32k!W32pServiceTable, calculate it kernel address. // RtlSecureZeroMemory(&resolveInfo, sizeof(RESOLVE_INFO)); - if (!NT_SUCCESS(NtRawGetProcAddress(Context->KernelModule, "W32pServiceTable", &resolveInfo))) { + if (!NT_SUCCESS(NtRawGetProcAddress(Context->MappedKernelModule, "W32pServiceTable", &resolveInfo))) { ulResult = ErrShadowW32pServiceTableNotFound; break; } @@ -1217,7 +1225,7 @@ ULONG SdtWin32kInitializeOnce( Context->W32pServiceTableUserBase = (PULONG)resolveInfo.Function; Context->W32pServiceTableKernelBase = - Context->KernelBaseAddress + (ULONG_PTR)resolveInfo.Function - (ULONG_PTR)Context->KernelModule; + Context->KernelBaseAddress + (ULONG_PTR)resolveInfo.Function - (ULONG_PTR)Context->MappedKernelModule; // // Find Win32kApiSetTable where needed. @@ -1260,7 +1268,6 @@ ULONG SdtWin32kInitializeOnce( logAdd(EntryTypeInformation, TEXT("Session aware ApiSet parsing expected")); - Context->W32GetSessionStatePtr = (ULONG_PTR)GetProcAddress(hModule, "W32GetSessionState"); if (Context->W32GetSessionStatePtr == 0) { ulResult = ErrShadowWin32kGetStateNotFound; @@ -1310,7 +1317,7 @@ ULONG SdtWin32kInitializeOnce( // // Remember table offset. // - Context->Win32kApiSetTableOffset = SdtpQueryW32GetWin32kApiSetTableOffset(Context->KernelModule); + Context->Win32kApiSetTableOffset = SdtpQueryW32GetWin32kApiSetTableOffset(Context->MappedKernelModule); if (Context->Win32kApiSetTableOffset == 0) { ulResult = ErrShadowWin32kOffsetNotFound; break; @@ -1324,7 +1331,9 @@ ULONG SdtWin32kInitializeOnce( // This is old win32k layout. // Locate Win32kApiSetTable variable. Failure will result in unresolved apiset adapters. // - Context->Win32kApiSetTable = SdtpQueryWin32kApiSetTable(Context->KernelModule, + Context->Win32kApiSetTable = SdtpQueryWin32kApiSetTable( + Context->MappedKernelModule, + Context->MappedKernelModuleSize, (PVOID)Context->KernelBaseAddress, Context->KernelImageSize, symContext); @@ -1363,13 +1372,13 @@ ULONG SdtWin32kInitializeOnce( if (ulResult != ErrShadowApiSetNotFound) { - if (Context->KernelModule) - FreeLibrary(Context->KernelModule); + if (Context->MappedKernelModule) + FreeLibrary(Context->MappedKernelModule); if (Context->ExportsEnumHeap) supDestroyHeap(Context->ExportsEnumHeap); - Context->KernelModule = NULL; + Context->MappedKernelModule = NULL; Context->ExportsEnumHeap = NULL; } @@ -1389,8 +1398,8 @@ ULONG SdtWin32kInitializeOnce( VOID SdtWin32kUninitialize( _In_ PSDT_CONTEXT Context) { - if (Context->KernelModule) - FreeLibrary(Context->KernelModule); + if (Context->MappedKernelModule) + FreeLibrary(Context->MappedKernelModule); if (Context->ExportsEnumHeap) supDestroyHeap(Context->ExportsEnumHeap); diff --git a/Source/WinObjEx64/sup/w32k.h b/Source/WinObjEx64/sup/w32k.h index b511278..c25d389 100644 --- a/Source/WinObjEx64/sup/w32k.h +++ b/Source/WinObjEx64/sup/w32k.h @@ -4,9 +4,9 @@ * * TITLE: W32K.H * -* VERSION: 2.11 +* VERSION: 2.12 * -* DATE: 22 Jun 2026 +* DATE: 24 Jul 2026 * * Common header file for the win32k support routines. * @@ -147,7 +147,8 @@ typedef struct _SDT_CONTEXT { HANDLE ExportsEnumHeap; //heap handle for enum HMODULE UserModule; //win32u.dll hmodule - HMODULE KernelModule; //win32k.sys hmodule + HMODULE MappedKernelModule; //win32k.sys hmodule + ULONG MappedKernelModuleSize; //win32k.sys hmodule size PRAW_SYSCALL_ENTRY UserTable; //win32u syscalls exports dump ULONG UserLimit; //win32u syscalls count diff --git a/Source/WinObjEx64/tests/ntsup_tests.c b/Source/WinObjEx64/tests/ntsup_tests.c deleted file mode 100644 index 4f05978..0000000 --- a/Source/WinObjEx64/tests/ntsup_tests.c +++ /dev/null @@ -1,897 +0,0 @@ -/******************************************************************************* -* -* (C) COPYRIGHT AUTHORS, 2015 - 2026 UGN/HE -* -* TITLE: NTSUP_TESTS.C -* -* VERSION: 2.10 -* -* DATE: 10 Jan 2026 -* -* NTSup test code used while debug. -* -* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF -* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED -* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A -* PARTICULAR PURPOSE. -* -*******************************************************************************/ -#define OEMRESOURCE - -#include "global.h" -#include "ntos\ntsup.h" -#pragma warning(push) -#pragma warning(disable:28251) //Inconsistent annotation for any intrin, "feature" of the latest MSVC -#pragma warning(disable: 6387) //_Param_(1) could be '0' -#pragma warning(disable: 28159) //GetTickCount -#include - -static ULONG g_FailCount = 0; -static BOOL g_Verbose = TRUE; - -#define TEST_ASSERT(expr) do { if (!(expr)) { ++g_FailCount; if (g_Verbose) DbgPrint("ASSERT FAILED: %s (%s:%d)\n", #expr, __FUNCTION__, __LINE__); } } while (0) - -PVOID CALLBACK TestAlloc(_In_ SIZE_T NumberOfBytes) -{ - return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, NumberOfBytes); -} - -BOOL CALLBACK TestFree(_In_ PVOID Memory) -{ - if (Memory) HeapFree(GetProcessHeap(), 0, Memory); - return TRUE; -} - -PVOID CALLBACK FailAlloc(_In_ SIZE_T NumberOfBytes) -{ - (void)NumberOfBytes; - return NULL; -} - -BOOL ReadFileContent( - _In_ LPCWSTR FileName, - _Out_ PBYTE* Buffer, - _Out_ DWORD* Size -) -{ - HANDLE hFile; - DWORD fileSize, bytesRead; - PBYTE data; - - *Buffer = NULL; - *Size = 0; - - hFile = CreateFile(FileName, - GENERIC_READ, - FILE_SHARE_READ, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL); - - if (hFile == INVALID_HANDLE_VALUE) - return FALSE; - - fileSize = GetFileSize(hFile, NULL); - if (fileSize == INVALID_FILE_SIZE) { - CloseHandle(hFile); - return FALSE; - } - - data = (PBYTE)ntsupHeapAlloc(fileSize ? fileSize : 1); - if (data == NULL) { - CloseHandle(hFile); - return FALSE; - } - - bytesRead = 0; - if (fileSize) { - if (!ReadFile(hFile, data, fileSize, &bytesRead, NULL) || bytesRead != fileSize) { - ntsupHeapFree(data); - CloseHandle(hFile); - return FALSE; - } - } - - CloseHandle(hFile); - - *Buffer = data; - *Size = fileSize; - return TRUE; -} - -VOID WriteBufferToFile_WriteNewFile(VOID) -{ - WCHAR tempPath[MAX_PATH]; - WCHAR filePath[MAX_PATH]; - NTSTATUS resultStatus; - SIZE_T written; - BYTE const data1[] = { 1,2,3,4,5 }; - PBYTE fileData; - DWORD fileSize; - ULONG i; - - RtlSecureZeroMemory(tempPath, sizeof(tempPath)); - RtlSecureZeroMemory(filePath, sizeof(filePath)); - - GetTempPath(MAX_PATH, tempPath); - wsprintfW(filePath, L"%sntsup_test_%lu.bin", tempPath, GetTickCount()); - - written = ntsupWriteBufferToFile( - filePath, - (PVOID)data1, - sizeof(data1), - TRUE, - FALSE, - &resultStatus); - - TEST_ASSERT(written == sizeof(data1)); - TEST_ASSERT(NT_SUCCESS(resultStatus)); - - fileData = NULL; - fileSize = 0; - TEST_ASSERT(ReadFileContent(filePath, &fileData, &fileSize)); - if (fileData) { - TEST_ASSERT(fileSize == sizeof(data1)); - for (i = 0; i < fileSize; i++) - TEST_ASSERT(fileData[i] == data1[i]); - ntsupHeapFree(fileData); - } - - DeleteFile(filePath); -} - -VOID WriteBufferToFile_AppendFile(VOID) -{ - WCHAR tempPath[MAX_PATH]; - WCHAR filePath[MAX_PATH]; - NTSTATUS resultStatus; - SIZE_T written; - BYTE const data1[] = { 0x10,0x11,0x12 }; - BYTE const data2[] = { 0xAA,0xBB }; - PBYTE fileData; - DWORD fileSize; - ULONG i; - - RtlSecureZeroMemory(tempPath, sizeof(tempPath)); - RtlSecureZeroMemory(filePath, sizeof(filePath)); - - GetTempPath(MAX_PATH, tempPath); - wsprintfW(filePath, L"%sntsup_test_append_%lu.bin", tempPath, GetTickCount()); - - written = ntsupWriteBufferToFile( - filePath, - (PVOID)data1, - sizeof(data1), - TRUE, - FALSE, - &resultStatus); - - TEST_ASSERT(written == sizeof(data1)); - TEST_ASSERT(NT_SUCCESS(resultStatus)); - - written = ntsupWriteBufferToFile( - filePath, - (PVOID)data2, - sizeof(data2), - TRUE, - TRUE, - &resultStatus); - - TEST_ASSERT(written == sizeof(data2)); - TEST_ASSERT(NT_SUCCESS(resultStatus)); - - fileData = NULL; - fileSize = 0; - TEST_ASSERT(ReadFileContent(filePath, &fileData, &fileSize)); - if (fileData) { - TEST_ASSERT(fileSize == sizeof(data1) + sizeof(data2)); - for (i = 0; i < sizeof(data1); i++) - TEST_ASSERT(fileData[i] == data1[i]); - for (i = 0; i < sizeof(data2); i++) - TEST_ASSERT(fileData[sizeof(data1) + i] == data2[i]); - ntsupHeapFree(fileData); - } - - DeleteFile(filePath); -} - -VOID WriteBufferToFile_InvalidPath(VOID) -{ - NTSTATUS resultStatus; - SIZE_T written; - BYTE dummy[4] = { 0 }; - - written = ntsupWriteBufferToFile( - L"", - dummy, - sizeof(dummy), - FALSE, - FALSE, - &resultStatus); - - TEST_ASSERT(written == 0); - TEST_ASSERT(!NT_SUCCESS(resultStatus)); -} - -VOID WriteBufferToFile_ZeroSizeWrite(VOID) -{ - WCHAR tempPath[MAX_PATH]; - WCHAR filePath[MAX_PATH]; - NTSTATUS resultStatus; - SIZE_T written; - PBYTE fileData; - DWORD fileSize; - - RtlSecureZeroMemory(tempPath, sizeof(tempPath)); - RtlSecureZeroMemory(filePath, sizeof(filePath)); - - GetTempPath(MAX_PATH, tempPath); - wsprintfW(filePath, L"%sntsup_test_zero_%lu.bin", tempPath, GetTickCount()); - - written = ntsupWriteBufferToFile( - filePath, - (PVOID)"", - 0, - TRUE, - FALSE, - &resultStatus); - - TEST_ASSERT(written == 0); - TEST_ASSERT(NT_SUCCESS(resultStatus) || written == 0); // Accept success with zero write - - fileData = NULL; - fileSize = 0; - if (ReadFileContent(filePath, &fileData, &fileSize)) { - TEST_ASSERT(fileSize == 0); - if (fileData) ntsupHeapFree(fileData); - } - - DeleteFile(filePath); -} - -VOID FindModuleNameByAddress_ValidModuleName(VOID) -{ - PRTL_PROCESS_MODULES modules; - ULONG returnLength; - PRTL_PROCESS_MODULE_INFORMATION modInfo; - WCHAR nameBuffer[260]; - PVOID foundEntry; - PVOID testAddress; - ANSI_STRING ansiExpected; - UNICODE_STRING usExpected; - SIZE_T expectedLen; - - modules = (PRTL_PROCESS_MODULES)ntsupGetLoadedModulesList(&returnLength); - TEST_ASSERT(modules != NULL); - if (modules == NULL) - return; - - if (modules->NumberOfModules == 0) { - ntsupHeapFree(modules); - TEST_ASSERT(FALSE); - return; - } - - modInfo = &modules->Modules[0]; - testAddress = (PBYTE)modInfo->ImageBase + (modInfo->ImageSize / 2); - - RtlSecureZeroMemory(nameBuffer, sizeof(nameBuffer)); - - foundEntry = ntsupFindModuleNameByAddress( - modules, - testAddress, - nameBuffer, - _countof(nameBuffer)); - - TEST_ASSERT(foundEntry != NULL); - TEST_ASSERT(nameBuffer[0] != 0); - - if (foundEntry) { - RtlInitString(&ansiExpected, - (PCSZ)&modInfo->FullPathName[modInfo->OffsetToFileName]); - usExpected.Buffer = NULL; - usExpected.Length = usExpected.MaximumLength = 0; - if (NT_SUCCESS(RtlAnsiStringToUnicodeString(&usExpected, &ansiExpected, TRUE))) { - expectedLen = usExpected.Length / sizeof(WCHAR); - TEST_ASSERT(_strlen(nameBuffer) <= expectedLen); - TEST_ASSERT(_strcmp(nameBuffer, usExpected.Buffer) == 0); - RtlFreeUnicodeString(&usExpected); - } - } - - ntsupHeapFree(modules); -} - -VOID FindModuleNameByAddress_TruncatedBuffer(VOID) -{ - PRTL_PROCESS_MODULES modules; - ULONG returnLength; - PRTL_PROCESS_MODULE_INFORMATION modInfo; - WCHAR tinyBuffer[4]; - PVOID testAddress; - PVOID foundEntry; - SIZE_T lenCaptured; - - modules = (PRTL_PROCESS_MODULES)ntsupGetLoadedModulesList(&returnLength); - TEST_ASSERT(modules != NULL); - if (modules == NULL) - return; - - if (modules->NumberOfModules == 0) { - ntsupHeapFree(modules); - TEST_ASSERT(FALSE); - return; - } - - modInfo = &modules->Modules[0]; - testAddress = modInfo->ImageBase; - - RtlSecureZeroMemory(tinyBuffer, sizeof(tinyBuffer)); - - foundEntry = ntsupFindModuleNameByAddress( - modules, - testAddress, - tinyBuffer, - _countof(tinyBuffer)); - - TEST_ASSERT(foundEntry != NULL); - lenCaptured = _strlen(tinyBuffer); - TEST_ASSERT(lenCaptured <= (_countof(tinyBuffer) - 1)); - TEST_ASSERT(tinyBuffer[_countof(tinyBuffer) - 1] == 0); - - ntsupHeapFree(modules); -} - -VOID FindModuleNameByAddress_InvalidAddress(VOID) -{ - PRTL_PROCESS_MODULES modules; - ULONG returnLength; - WCHAR buffer[32]; - PVOID foundEntry; - - modules = (PRTL_PROCESS_MODULES)ntsupGetLoadedModulesList(&returnLength); - TEST_ASSERT(modules != NULL); - if (modules == NULL) - return; - - RtlSecureZeroMemory(buffer, sizeof(buffer)); - - foundEntry = ntsupFindModuleNameByAddress( - modules, - ULongToPtr(0x1), // very low address, should not belong to system module range - buffer, - _countof(buffer)); - - TEST_ASSERT(foundEntry == NULL); - TEST_ASSERT(buffer[0] == 0); - - ntsupHeapFree(modules); -} - -VOID FindModuleNameByAddress_InvalidBufferArgs(VOID) -{ - PRTL_PROCESS_MODULES modules; - ULONG returnLength; - PRTL_PROCESS_MODULE_INFORMATION modInfo; - PVOID testAddress; - PVOID foundEntry; - WCHAR nameBuffer[8]; - - modules = (PRTL_PROCESS_MODULES)ntsupGetLoadedModulesList(&returnLength); - TEST_ASSERT(modules != NULL); - if (modules == NULL) - return; - - if (modules->NumberOfModules == 0) { - ntsupHeapFree(modules); - TEST_ASSERT(FALSE); - return; - } - - modInfo = &modules->Modules[0]; - testAddress = modInfo->ImageBase; - - foundEntry = ntsupFindModuleNameByAddress( - modules, - testAddress, - NULL, - 0); - TEST_ASSERT(foundEntry == NULL); - - RtlSecureZeroMemory(nameBuffer, sizeof(nameBuffer)); - foundEntry = ntsupFindModuleNameByAddress( - modules, - testAddress, - nameBuffer, - 0); - TEST_ASSERT(foundEntry == NULL); - TEST_ASSERT(nameBuffer[0] == 0); - - ntsupHeapFree(modules); -} - -VOID GetLoadedModulesListEx_BasicList(VOID) -{ - PRTL_PROCESS_MODULES modules; - ULONG returnLength = 0; - ULONG count, i; - BOOLEAN haveNonZero = FALSE; - - modules = (PRTL_PROCESS_MODULES)ntsupGetLoadedModulesListEx( - FALSE, - &returnLength, - (PNTSUPMEMALLOC)ntsupHeapAlloc, - (PNTSUPMEMFREE)ntsupHeapFree); - - TEST_ASSERT(modules != NULL); - if (modules == NULL) - return; - - count = modules->NumberOfModules; - TEST_ASSERT(count > 0); - TEST_ASSERT(returnLength > 0); - - if (count > 0) { - TEST_ASSERT(modules->Modules[0].ImageBase != NULL); - TEST_ASSERT(modules->Modules[0].ImageSize > 0); - } - - for (i = 0; i < count && i < 32; i++) { - if (modules->Modules[i].FullPathName[0] != 0) { - haveNonZero = TRUE; - break; - } - } - TEST_ASSERT(haveNonZero); - - ntsupHeapFree(modules); -} - -VOID GetLoadedModulesListEx_ExtendedList(VOID) -{ - PRTL_PROCESS_MODULES modules; - ULONG returnLength = 0; - - modules = (PRTL_PROCESS_MODULES)ntsupGetLoadedModulesListEx( - TRUE, - &returnLength, - (PNTSUPMEMALLOC)ntsupHeapAlloc, - (PNTSUPMEMFREE)ntsupHeapFree); - - if (modules == NULL) { - if (g_Verbose) DbgPrint("Extended module list not available (SystemModuleInformationEx unsupported?) - skipping related assertions.\n"); - return; - } - - TEST_ASSERT(returnLength > 0); - TEST_ASSERT(modules->NumberOfModules > 0); - TEST_ASSERT(modules->Modules[0].ImageBase != NULL); - - ntsupHeapFree(modules); -} - -VOID GetLoadedModulesListEx_NullReturnLength(VOID) -{ - PRTL_PROCESS_MODULES modules; - - modules = (PRTL_PROCESS_MODULES)ntsupGetLoadedModulesListEx( - FALSE, - NULL, - (PNTSUPMEMALLOC)ntsupHeapAlloc, - (PNTSUPMEMFREE)ntsupHeapFree); - - TEST_ASSERT(modules != NULL); - if (modules) - ntsupHeapFree(modules); -} - -VOID GetLoadedModulesListEx_AllocFailure(VOID) -{ - PVOID modules; - ULONG returnLength = 0; - - modules = ntsupGetLoadedModulesListEx( - FALSE, - &returnLength, - (PNTSUPMEMALLOC)FailAlloc, - (PNTSUPMEMFREE)TestFree); - - TEST_ASSERT(modules == NULL); - TEST_ASSERT(returnLength == 0); -} - -VOID GetSystemInfoEx_SystemProcessInformation(VOID) -{ - PVOID buffer; - ULONG retLen = 0; - ULONG safeCheck = 0; - ULONG bytesWalked = 0; - - buffer = ntsupGetSystemInfoEx( - SystemProcessInformation, - &retLen, - (PNTSUPMEMALLOC)TestAlloc, - (PNTSUPMEMFREE)TestFree); - - if (buffer == NULL) { - if (g_Verbose) DbgPrint("SystemProcessInformation unsupported or allocation failed, skipping.\n"); - return; - } - - TEST_ASSERT(retLen > 0); - - if (retLen > sizeof(SYSTEM_PROCESS_INFORMATION)) { - - PSYSTEM_PROCESS_INFORMATION spi = (PSYSTEM_PROCESS_INFORMATION)buffer; - - while (TRUE) { - TEST_ASSERT(spi->NextEntryDelta % sizeof(ULONG) == 0); - bytesWalked += spi->NextEntryDelta; - safeCheck++; - - if (spi->NextEntryDelta == 0) - break; - - if (safeCheck > 0x100000) { - TEST_ASSERT(FALSE); - break; - } - - spi = (PSYSTEM_PROCESS_INFORMATION)((PUCHAR)spi + spi->NextEntryDelta); - } - } - - TestFree(buffer); -} - -VOID GetSystemInfoEx_NullReturnLength(VOID) -{ - PVOID buffer; - - buffer = ntsupGetSystemInfoEx( - SystemBasicInformation, - NULL, - (PNTSUPMEMALLOC)TestAlloc, - (PNTSUPMEMFREE)TestFree); - - TEST_ASSERT(buffer == NULL); - if (buffer) - TestFree(buffer); -} - -VOID GetSystemInfoEx_AllocFailure(VOID) -{ - PVOID buffer; - ULONG retLen = 0; - - buffer = ntsupGetSystemInfoEx( - SystemBasicInformation, - &retLen, - (PNTSUPMEMALLOC)FailAlloc, - (PNTSUPMEMFREE)TestFree); - - TEST_ASSERT(buffer == NULL); - TEST_ASSERT(retLen == 0); -} - -VOID GetSystemInfoEx_InvalidClass(VOID) -{ - PVOID buffer; - ULONG retLen = 0; - - buffer = ntsupGetSystemInfoEx( - (SYSTEM_INFORMATION_CLASS)0xFFFFFFFF, //-V1016 - &retLen, - (PNTSUPMEMALLOC)TestAlloc, - (PNTSUPMEMFREE)TestFree); - - TEST_ASSERT(buffer == NULL); - TEST_ASSERT(retLen == 0); -} - -VOID HashImageSections_LoadedImage(VOID) -{ - HMODULE hMod; - PIMAGE_NT_HEADERS nth; - BYTE hash[NTSUPHASH_SHA256_SIZE]; - NTSTATUS status; - SIZE_T imageSize; - - hMod = GetModuleHandle(NULL); - TEST_ASSERT(hMod != NULL); - if (hMod == NULL) return; - - nth = RtlImageNtHeader(hMod); - TEST_ASSERT(nth != NULL); - if (nth == NULL) return; - - imageSize = nth->OptionalHeader.SizeOfImage; - RtlSecureZeroMemory(hash, sizeof(hash)); - - status = ntsupHashImageSections( - (PVOID)hMod, - imageSize, - hash, - sizeof(hash), - ImageTypeLoaded); - - TEST_ASSERT(NT_SUCCESS(status)); - if (NT_SUCCESS(status)) { - SIZE_T i, zeroCount = 0; - for (i = 0; i < sizeof(hash); i++) - if (hash[i] == 0) zeroCount++; - TEST_ASSERT(zeroCount != sizeof(hash)); - } -} - -VOID HashImageSections_RawFileMapping(VOID) -{ - WCHAR path[MAX_PATH]; - HANDLE hFile, hMapping; - LARGE_INTEGER fsz; - PVOID mapBase; - BYTE hash[NTSUPHASH_SHA256_SIZE]; - NTSTATUS status; - - RtlSecureZeroMemory(path, sizeof(path)); - if (!GetModuleFileName(NULL, path, MAX_PATH)) - return; - - hFile = CreateFile(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); - TEST_ASSERT(hFile != INVALID_HANDLE_VALUE); - if (hFile == INVALID_HANDLE_VALUE) return; - - fsz.LowPart = GetFileSize(hFile, (LPDWORD)&fsz.HighPart); - TEST_ASSERT(fsz.QuadPart > 0); - - hMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL); - TEST_ASSERT(hMapping != NULL); - if (hMapping == NULL) { - CloseHandle(hFile); - return; - } - - mapBase = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0); - TEST_ASSERT(mapBase != NULL); - if (mapBase == NULL) { - CloseHandle(hMapping); - CloseHandle(hFile); - return; - } - - RtlSecureZeroMemory(hash, sizeof(hash)); - status = ntsupHashImageSections( - mapBase, - (SIZE_T)fsz.QuadPart, - hash, - sizeof(hash), - ImageTypeRaw); - - TEST_ASSERT(NT_SUCCESS(status)); - - UnmapViewOfFile(mapBase); - CloseHandle(hMapping); - CloseHandle(hFile); -} - -VOID BuildMinimalImage( - _Out_ PVOID* Buffer, - _Out_ SIZE_T* BufferSize, - _In_ BOOL ExecutableSection -) -{ - PBYTE base; - IMAGE_DOS_HEADER* dos; - IMAGE_NT_HEADERS64* nth; - IMAGE_SECTION_HEADER* sh; - SIZE_T bufSize; - ULONG optSize; - - bufSize = 0x1000; - *BufferSize = bufSize; - base = (PBYTE)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, bufSize); - *Buffer = base; - if (base == NULL) return; - - dos = (IMAGE_DOS_HEADER*)base; - dos->e_magic = IMAGE_DOS_SIGNATURE; - dos->e_lfanew = 0x80; - - nth = (IMAGE_NT_HEADERS64*)(base + dos->e_lfanew); - nth->Signature = IMAGE_NT_SIGNATURE; - nth->FileHeader.Machine = IMAGE_FILE_MACHINE_AMD64; - nth->FileHeader.NumberOfSections = 1; - optSize = sizeof(IMAGE_OPTIONAL_HEADER64); - nth->FileHeader.SizeOfOptionalHeader = (WORD)optSize; - nth->OptionalHeader.Magic = IMAGE_NT_OPTIONAL_HDR64_MAGIC; - nth->OptionalHeader.SectionAlignment = 0x200; - nth->OptionalHeader.FileAlignment = 0x200; - nth->OptionalHeader.SizeOfImage = (DWORD)bufSize; - nth->OptionalHeader.SizeOfHeaders = 0x200; - - sh = (IMAGE_SECTION_HEADER*)((PBYTE)&nth->OptionalHeader + optSize); - RtlCopyMemory(sh->Name, ".data", 5); - sh->Misc.VirtualSize = 0x100; - sh->VirtualAddress = 0x200; - sh->SizeOfRawData = 0x200; - sh->PointerToRawData = 0x200; - sh->Characteristics = - IMAGE_SCN_CNT_INITIALIZED_DATA | - IMAGE_SCN_MEM_READ | - (ExecutableSection ? (IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_CNT_CODE) : 0); -} - -VOID HashImageSections_NoExecutableSections(VOID) -{ - PVOID image; - SIZE_T imageSize; - BYTE hash[NTSUPHASH_SHA256_SIZE]; - NTSTATUS status; - - image = NULL; - imageSize = 0; - BuildMinimalImage(&image, &imageSize, FALSE); - TEST_ASSERT(image != NULL); - if (image == NULL) return; - - RtlSecureZeroMemory(hash, sizeof(hash)); - status = ntsupHashImageSections( - image, - imageSize, - hash, - sizeof(hash), - ImageTypeLoaded); - - TEST_ASSERT(status == STATUS_NOT_FOUND); - - HeapFree(GetProcessHeap(), 0, image); -} - -VOID HashImageSections_ExecutableSectionPresent(VOID) -{ - PVOID image; - SIZE_T imageSize; - BYTE hash[NTSUPHASH_SHA256_SIZE]; - NTSTATUS status; - - image = NULL; - imageSize = 0; - BuildMinimalImage(&image, &imageSize, TRUE); - TEST_ASSERT(image != NULL); - if (image == NULL) return; - - RtlSecureZeroMemory(hash, sizeof(hash)); - status = ntsupHashImageSections( - image, - imageSize, - hash, - sizeof(hash), - ImageTypeLoaded); - - TEST_ASSERT(NT_SUCCESS(status)); - - HeapFree(GetProcessHeap(), 0, image); -} - -VOID HashImageSections_InvalidParams(VOID) -{ - BYTE hash[NTSUPHASH_SHA256_SIZE]; - NTSTATUS status; - PVOID image; - SIZE_T imageSize; - - RtlSecureZeroMemory(hash, sizeof(hash)); - - status = ntsupHashImageSections(NULL, 100, hash, sizeof(hash), ImageTypeLoaded); - TEST_ASSERT(status == STATUS_INVALID_PARAMETER); - - status = ntsupHashImageSections(ULongToPtr(0x1), 0, hash, sizeof(hash), ImageTypeLoaded); - TEST_ASSERT(status == STATUS_INVALID_PARAMETER); - - status = ntsupHashImageSections(ULongToPtr(0x1), 100, hash, 1, ImageTypeLoaded); - TEST_ASSERT(status == STATUS_BUFFER_TOO_SMALL); - - image = NULL; - imageSize = 0; - BuildMinimalImage(&image, &imageSize, TRUE); - if (image) { - PIMAGE_NT_HEADERS nth = (PIMAGE_NT_HEADERS)RtlImageNtHeader(image); - if (nth) { - SIZE_T smaller = nth->OptionalHeader.SizeOfImage / 2; - status = ntsupHashImageSections( - image, - smaller, - hash, - sizeof(hash), - ImageTypeLoaded); - TEST_ASSERT(status == STATUS_INVALID_IMAGE_FORMAT); - } - HeapFree(GetProcessHeap(), 0, image); - } -} - -VOID Test_WriteBufferToFile() -{ - g_FailCount = 0; - WriteBufferToFile_WriteNewFile(); - WriteBufferToFile_AppendFile(); - WriteBufferToFile_InvalidPath(); - WriteBufferToFile_ZeroSizeWrite(); - - if (g_Verbose) { - if (g_FailCount == 0) - DbgPrint("[TEST] ntsupWriteBufferToFile PASSED.\n"); - else - DbgPrint("[TEST] ntsupWriteBufferToFile %lu tests FAILED.\n", g_FailCount); - } -} - -VOID Test_FindModuleNameByAddress() -{ - g_FailCount = 0; - FindModuleNameByAddress_ValidModuleName(); - FindModuleNameByAddress_TruncatedBuffer(); - FindModuleNameByAddress_InvalidAddress(); - FindModuleNameByAddress_InvalidBufferArgs(); - - if (g_Verbose) { - if (g_FailCount == 0) - DbgPrint("[TEST] ntsupFindModuleNameByAddress PASSED.\n"); - else - DbgPrint("[TST] ntsupFindModuleNameByAddress %lu tests FAILED.\n", g_FailCount); - } -} - -VOID Test_GetLoadedModulesListEx() -{ - g_FailCount = 0; - - GetLoadedModulesListEx_BasicList(); - GetLoadedModulesListEx_ExtendedList(); - GetLoadedModulesListEx_NullReturnLength(); - GetLoadedModulesListEx_AllocFailure(); - - if (g_Verbose) { - if (g_FailCount == 0) - DbgPrint("[TEST] ntsupGetLoadedModulesListEx PASSED.\n"); - else - DbgPrint("[TEST] ntsupGetLoadedModulesListEx %lu tests FAILED.\n", g_FailCount); - } -} - -VOID Test_GetSystemInfoEx() -{ - g_FailCount = 0; - - GetSystemInfoEx_SystemProcessInformation(); - GetSystemInfoEx_NullReturnLength(); - GetSystemInfoEx_AllocFailure(); - GetSystemInfoEx_InvalidClass(); - - if (g_Verbose) { - if (g_FailCount == 0) - DbgPrint("[TEST] ntsupGetSystemInfoEx tests PASSED.\n"); - else - DbgPrint("[TEST] ntsupGetSystemInfoEx %lu tests FAILED.\n", g_FailCount); - } -} - -VOID Test_HashImageSections() -{ - g_FailCount = 0; - - HashImageSections_LoadedImage(); - HashImageSections_RawFileMapping(); - HashImageSections_NoExecutableSections(); - HashImageSections_ExecutableSectionPresent(); - HashImageSections_InvalidParams(); - - if (g_Verbose) { - if (g_FailCount == 0) - DbgPrint("[TEST] ntsupHashImageSections tests PASSED.\n"); - else - DbgPrint("[TEST] ntsupHashImageSections%lu tests FAILED.\n", g_FailCount); - } -} -#pragma warning(pop) diff --git a/Source/WinObjEx64/tests/ntsup_tests.h b/Source/WinObjEx64/tests/ntsup_tests.h deleted file mode 100644 index f7e92c0..0000000 --- a/Source/WinObjEx64/tests/ntsup_tests.h +++ /dev/null @@ -1,25 +0,0 @@ -/******************************************************************************* -* -* (C) COPYRIGHT AUTHORS, 2015 - 2025 UGN/HE -* -* TITLE: NTSUP_TESTS.H -* -* VERSION: 2.09 -* -* DATE: 10 Aug 2025 -* -* Common header file for NTSUP test code. -* -* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF -* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED -* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A -* PARTICULAR PURPOSE. -* -*******************************************************************************/ -#pragma once - -VOID Test_WriteBufferToFile(); -VOID Test_FindModuleNameByAddress(); -VOID Test_GetLoadedModulesListEx(); -VOID Test_GetSystemInfoEx(); -VOID Test_HashImageSections(); diff --git a/Source/WinObjEx64/tests/testunit.c b/Source/WinObjEx64/tests/testunit.c index 9120880..b9afdd0 100644 --- a/Source/WinObjEx64/tests/testunit.c +++ b/Source/WinObjEx64/tests/testunit.c @@ -4,9 +4,9 @@ * * TITLE: TESTUNIT.C * -* VERSION: 2.10 +* VERSION: 2.12 * -* DATE: 10 Feb 2026 +* DATE: 25 Jul 2026 * * Test code used while debug. * @@ -25,7 +25,6 @@ #include #pragma warning(pop) #include -#include "ntsup_tests.h" HANDLE g_TestNamespace = NULL, g_TestMutex = NULL; HANDLE g_TestMailslot = NULL; @@ -1577,11 +1576,6 @@ VOID TestStart( PreHashTypes(); //TestJob(); //TestDefineDosDevice(); - Test_WriteBufferToFile(); - Test_FindModuleNameByAddress(); - Test_GetLoadedModulesListEx(); - Test_GetSystemInfoEx(); - Test_HashImageSections(); //Test_RegDeleteKeyTree(); } diff --git a/Source/WinObjEx64/ui.h b/Source/WinObjEx64/ui.h index 6e97a88..e3aff0c 100644 --- a/Source/WinObjEx64/ui.h +++ b/Source/WinObjEx64/ui.h @@ -4,9 +4,9 @@ * * TITLE: UI.H * -* VERSION: 2.11 +* VERSION: 2.12 * -* DATE: 12 Jul 2026 +* DATE: 25 Jul 2026 * * Common header file for the user interface. * @@ -49,8 +49,8 @@ typedef HWND(WINAPI *pfnHtmlHelpW)( #define PROGRAM_MAJOR_VERSION 2 #define PROGRAM_MINOR_VERSION 1 -#define PROGRAM_REVISION_NUMBER 1 -#define PROGRAM_BUILD_NUMBER 2607 +#define PROGRAM_REVISION_NUMBER 2 +#define PROGRAM_BUILD_NUMBER 2608 #ifdef _USE_OWN_DRIVER #define PROGRAM_NAME L"Windows Object Explorer 64-bit (Non-public version)" From 5847e2711aa091c454e5a17d962d66053c5f6c0f Mon Sep 17 00:00:00 2001 From: hfiref0x Date: Tue, 28 Jul 2026 21:13:32 +0700 Subject: [PATCH 2/5] 2.1.2 Remember main window upon shutdown and restore upon startup Update RTLs --- Source/Shared/ntos/ntsup.c | 390 ++++++++++++++++++++++++++++++++++-- Source/Shared/ntos/ntsup.h | 61 +++++- Source/WinObjEx64/main.c | 16 +- Source/WinObjEx64/sup/sup.c | 266 ++++++++++++++++++++++-- Source/WinObjEx64/sup/sup.h | 14 +- Source/WinObjEx64/ui.h | 5 +- 6 files changed, 706 insertions(+), 46 deletions(-) diff --git a/Source/Shared/ntos/ntsup.c b/Source/Shared/ntos/ntsup.c index 5ec293a..3b8f123 100644 --- a/Source/Shared/ntos/ntsup.c +++ b/Source/Shared/ntos/ntsup.c @@ -4,9 +4,9 @@ * * TITLE: NTSUP.C * -* VERSION: 2.30 +* VERSION: 2.31 * -* DATE: 25 Jul 2026 +* DATE: 26 Jul 2026 * * Native API support functions. * @@ -270,6 +270,66 @@ BOOLEAN ntsupIsAddressValid( * Ronova port end. */ +/* +* ntsupStrChrW +* +* Purpose: +* +* Returns a pointer to the first occurrence of Character in String +* (including the terminator if Character is 0), or NULL if not found. +* +*/ +LPWSTR ntsupStrChrW( + _In_z_ LPCWSTR String, + _In_ WCHAR Character +) +{ + while (*String != UNICODE_NULL) { + if (*String == Character) + return (LPWSTR)String; + String++; + } + + if (Character == UNICODE_NULL) + return (LPWSTR)String; + + return NULL; +} + +/* +* ntsupStrChrA +* +* Purpose: +* +* Returns a pointer to the first occurrence of Character in String +* (including the terminator if Character is 0), or NULL if not found. +* +*/ +LPSTR ntsupStrChrA( + _In_z_ LPCSTR String, + _In_ CHAR Character +) +{ + while (*String != ANSI_NULL) { + if (*String == Character) + return (LPSTR)String; + String++; + } + + if (Character == ANSI_NULL) + return (LPSTR)String; + + return NULL; +} + +/* +* ntsupStrLenA +* +* Purpose: +* +* Returns the length, in characters, of a null-terminated ANSI string, or 0 if the pointer is NULL. +* +*/ SIZE_T ntsupStrLenA( _In_opt_ LPCSTR String ) @@ -285,6 +345,14 @@ SIZE_T ntsupStrLenA( return (SIZE_T)(String - String0); } +/* +* ntsupStrLenW +* +* Purpose: +* +* Returns the length, in characters, of a null-terminated UTF-16 string, or 0 if the pointer is NULL. +* +*/ SIZE_T ntsupStrLenW( _In_opt_ LPCWSTR String ) @@ -300,6 +368,14 @@ SIZE_T ntsupStrLenW( return (SIZE_T)(String - String0); } +/* +* ntsupStrCmpA +* +* Purpose: +* +* Performs a case-sensitive comparison of two null-terminated ANSI strings. +* +*/ INT ntsupStrCmpA( _In_opt_ LPCSTR String1, _In_opt_ LPCSTR String2 @@ -326,6 +402,14 @@ INT ntsupStrCmpA( return (INT)(c1 - c2); } +/* +* ntsupStrCmpW +* +* Purpose: +* +* Performs a case-sensitive comparison of two null-terminated UTF-16 strings. +* +*/ INT ntsupStrCmpW( _In_opt_ LPCWSTR String1, _In_opt_ LPCWSTR String2 @@ -352,6 +436,14 @@ INT ntsupStrCmpW( return (INT)(c1 - c2); } +/* +* ntsupStrCmpIA +* +* Purpose: +* +* Performs a case-insensitive comparison of two null-terminated ANSI strings. +* +*/ INT ntsupStrCmpIA( _In_opt_ LPCSTR String1, _In_opt_ LPCSTR String2 @@ -378,6 +470,14 @@ INT ntsupStrCmpIA( return (INT)(c1 - c2); } +/* +* ntsupStrCmpIW +* +* Purpose: +* +* Performs a case-insensitive comparison of two null-terminated UTF-16 strings. +* +*/ INT ntsupStrCmpIW( _In_opt_ LPCWSTR String1, _In_opt_ LPCWSTR String2 @@ -404,10 +504,81 @@ INT ntsupStrCmpIW( return (INT)(c1 - c2); } -#pragma warning(push) -#pragma warning(disable: 6101 6054) +/* +* ntsupStrCopyA +* +* Purpose: +* +* Copies a null-terminated ANSI string from Source to Destination +* (unbounded, caller-guaranteed capacity). +* +*/ +LPSTR ntsupStrCopyA( + _Out_writes_z_(_String_length_(Source) + 1) LPSTR Destination, + _In_z_ LPCSTR Source +) +{ + LPSTR p; + + if ((Destination == NULL) || (Source == NULL)) + return Destination; + + p = Destination; + + while (*Source != ANSI_NULL) { + *p = *Source; + p++; + Source++; + } + + *p = ANSI_NULL; + + return Destination; +} + +/* +* ntsupStrCopyW +* +* Purpose: +* +* Copies a null-terminated wide-character (UTF-16) string from Source to Destination +* (unbounded, caller-guaranteed capacity) +* +*/ +LPWSTR ntsupStrCopyW( + _Out_writes_z_(_String_length_(Source) + 1) LPWSTR Destination, + _In_z_ LPCWSTR Source +) +{ + LPWSTR p; + + if ((Destination == NULL) || (Source == NULL)) + return Destination; + + p = Destination; + + while (*Source != UNICODE_NULL) { + *p = *Source; + p++; + Source++; + } + + *p = UNICODE_NULL; + + return Destination; +} + +/* +* ntsupStrNCopyA +* +* Purpose: +* +* Copies up to SourceCount characters from an ANSI source string +* into a fixed-size destination buffer, always null-terminating. +* +*/ LPSTR ntsupStrNCopyA( - _Out_writes_(DestinationCount) LPSTR Destination, + _Out_writes_z_(DestinationCount) LPSTR Destination, _In_ SIZE_T DestinationCount, _In_reads_(SourceCount) LPCSTR Source, _In_ SIZE_T SourceCount @@ -418,9 +589,6 @@ LPSTR ntsupStrNCopyA( if ((Destination == NULL) || (Source == NULL) || (DestinationCount == 0)) return Destination; - if (Destination == Source) - return Destination; - DestinationCount--; p = Destination; @@ -440,8 +608,17 @@ LPSTR ntsupStrNCopyA( return Destination; } +/* +* ntsupStrNCopyW +* +* Purpose: +* +* Copies up to SourceCount characters from a UTF-16 source string +* into a fixed-size destination buffer, always null-terminating. +* +*/ LPWSTR ntsupStrNCopyW( - _Out_writes_(DestinationCount) LPWSTR Destination, + _Out_writes_z_(DestinationCount) LPWSTR Destination, _In_ SIZE_T DestinationCount, _In_reads_(SourceCount) LPCWSTR Source, _In_ SIZE_T SourceCount @@ -452,9 +629,6 @@ LPWSTR ntsupStrNCopyW( if ((Destination == NULL) || (Source == NULL) || (DestinationCount == 0)) return Destination; - if (Destination == Source) - return Destination; - DestinationCount--; p = Destination; @@ -473,7 +647,6 @@ LPWSTR ntsupStrNCopyW( return Destination; } -#pragma warning(pop) INT ntsupStrNCmpA( _In_opt_ LPCSTR String1, @@ -613,7 +786,6 @@ LPCSTR ntsupStrStrIA( return NULL; } - /* * ntsupStrStrIW * @@ -841,6 +1013,193 @@ LPWSTR ntsupStrCatExW( return Destination; } +/* +* ntsupStrToUInt64A +* +* Purpose: +* +* Converts a decimal ANSI string to its ULONGLONG value. +* +*/ +BOOL ntsupStrToUInt64A( + _In_ LPCSTR String, + _Out_ PULONGLONG Value +) +{ + ULONGLONG result = 0; + ULONGLONG digit; + + *Value = 0; + + if (!String || !*String) + return FALSE; + + while (*String) { + + if (!ntsupIsDigitA(*String)) + return FALSE; + + digit = (ULONGLONG)(*String - '0'); + + if (result > (ULLONG_MAX - digit) / 10) + return FALSE; + + result = result * 10 + digit; + String++; + } + + *Value = result; + + return TRUE; +} + +/* +* ntsupStrToUInt64W +* +* Purpose: +* +* Converts a UTF-16 string to its ULONGLONG value. +* +*/ +BOOL ntsupStrToUInt64W( + _In_ LPCWSTR String, + _Out_ PULONGLONG Value +) +{ + ULONGLONG result = 0; + ULONGLONG digit; + + *Value = 0; + + if (!String || !*String) + return FALSE; + + while (*String) { + + if (!ntsupIsDigitW(*String)) + return FALSE; + + digit = (ULONGLONG)(*String - L'0'); + + if (result > (ULLONG_MAX - digit) / 10) + return FALSE; + + result = result * 10 + digit; + String++; + } + + *Value = result; + + return TRUE; +} + +/* +* ntsupUInt64ToStrW +* +* Purpose: +* +* Converts a ULONGLONG value to its UTF-16 string representation. +* +*/ +SIZE_T ntsupUInt64ToStrW( + _In_ ULONGLONG Value, + _Out_writes_z_(BufferCount) LPWSTR Buffer, + _In_ SIZE_T BufferCount +) +{ + WCHAR temp[21]; + SIZE_T length; + SIZE_T i; + + if (!Buffer || BufferCount == 0) + return 0; + + Buffer[0] = 0; + + if (Value == 0) { + if (BufferCount < 2) + return 0; + + Buffer[0] = L'0'; + Buffer[1] = 0; + return 1; + } + + length = 0; + + while (Value != 0 && length < RTL_NUMBER_OF(temp)) { + temp[length++] = (WCHAR)(L'0' + (Value % 10)); + Value /= 10; + } + + if (Value != 0) //msvc shut up + return 0; + + if ((length + 1) > BufferCount) + return 0; + + for (i = 0; i < length; i++) + Buffer[i] = temp[length - i - 1]; + + Buffer[length] = 0; + + return length; +} + +/* +* ntsupUInt64ToStrA +* +* Purpose: +* +* Converts a ULONGLONG value to its ANSI string representation. +* +*/ +SIZE_T ntsupUInt64ToStrA( + _In_ ULONGLONG Value, + _Out_writes_z_(BufferCount) LPSTR Buffer, + _In_ SIZE_T BufferCount +) +{ + CHAR temp[21]; + SIZE_T length; + SIZE_T i; + + if (!Buffer || BufferCount == 0) + return 0; + + Buffer[0] = 0; + + if (Value == 0) { + if (BufferCount < 2) + return 0; + + Buffer[0] = '0'; + Buffer[1] = 0; + + return 1; + } + + length = 0; + + while (Value != 0 && length < RTL_NUMBER_OF(temp)) { + temp[length++] = (CHAR)('0' + (Value % 10)); + Value /= 10; + } + + if (Value != 0) //msvc shut up + return 0; + + if ((length + 1) > BufferCount) + return 0; + + for (i = 0; i < length; i++) + Buffer[i] = temp[length - i - 1]; + + Buffer[length] = 0; + + return length; +} + /* * ntsupHeapAlloc * @@ -869,6 +1228,9 @@ PVOID ntsupHeapReAlloc( _In_ SIZE_T Size ) { + if (BaseAddress == NULL) + return ntsupHeapAlloc(Size); + return RtlReAllocateHeap(RtlProcessHeap(), HEAP_ZERO_MEMORY, BaseAddress, Size); } diff --git a/Source/Shared/ntos/ntsup.h b/Source/Shared/ntos/ntsup.h index 85a7f62..816f853 100644 --- a/Source/Shared/ntos/ntsup.h +++ b/Source/Shared/ntos/ntsup.h @@ -4,9 +4,9 @@ * * TITLE: NTSUP.H * -* VERSION: 2.30 +* VERSION: 2.31 * -* DATE: 25 Jul 2026 +* DATE: 26 Jul 2026 * * Common header file for the NT API support functions and definitions. * @@ -126,6 +126,20 @@ VOID ntsupSha256Final( // Ronova requires get rid of minirtl. // +FORCEINLINE BOOLEAN ntsupIsDigitA( + _In_ CHAR Ch +) +{ + return (BOOLEAN)(Ch >= '0' && Ch <= '9'); +} + +FORCEINLINE BOOLEAN ntsupIsDigitW( + _In_ WCHAR Ch +) +{ + return (BOOLEAN)(Ch >= L'0' && Ch <= L'9'); +} + // // Minirtl section START // @@ -149,6 +163,13 @@ FORCEINLINE WCHAR ntsupLowerCharW( return c; } +LPWSTR ntsupStrChrW( + _In_z_ LPCWSTR String, + _In_ WCHAR Character); +LPSTR ntsupStrChrA( + _In_z_ LPCSTR String, + _In_ CHAR Character); + SIZE_T ntsupStrLenA( _In_opt_ LPCSTR String); SIZE_T ntsupStrLenW( @@ -168,14 +189,20 @@ INT ntsupStrCmpIW( _In_opt_ LPCWSTR String1, _In_opt_ LPCWSTR String2); +LPSTR ntsupStrCopyA( + _Out_writes_z_(_String_length_(Source) + 1) LPSTR Destination, + _In_z_ LPCSTR Source); +LPWSTR ntsupStrCopyW( + _Out_writes_z_(_String_length_(Source) + 1) LPWSTR Destination, + _In_z_ LPCWSTR Source); + LPSTR ntsupStrNCopyA( - _Out_writes_(DestinationCount) LPSTR Destination, + _Out_writes_z_(DestinationCount) LPSTR Destination, _In_ SIZE_T DestinationCount, _In_reads_(SourceCount) LPCSTR Source, _In_ SIZE_T SourceCount); - LPWSTR ntsupStrNCopyW( - _Out_writes_(DestinationCount) LPWSTR Destination, + _Out_writes_z_(DestinationCount) LPWSTR Destination, _In_ SIZE_T DestinationCount, _In_reads_(SourceCount) LPCWSTR Source, _In_ SIZE_T SourceCount); @@ -212,26 +239,50 @@ LPWSTR ntsupStrCatExW( _In_ SIZE_T DestinationCount, _In_ LPCWSTR Source); +BOOL ntsupStrToUInt64A( + _In_ LPCSTR String, + _Out_ PULONGLONG Value); +BOOL ntsupStrToUInt64W( + _In_ LPCWSTR String, + _Out_ PULONGLONG Value); + +SIZE_T ntsupUInt64ToStrW( + _In_ ULONGLONG Value, + _Out_writes_z_(BufferCount) LPWSTR Buffer, + _In_ SIZE_T BufferCount); +SIZE_T ntsupUInt64ToStrA( + _In_ ULONGLONG Value, + _Out_writes_z_(BufferCount) LPSTR Buffer, + _In_ SIZE_T BufferCount); + #ifdef _UNICODE #define ntsupLowerChar ntsupLowerCharW +#define ntsupStrChr ntsupStrChrW #define ntsupStrLen ntsupStrLenW #define ntsupStrCmp ntsupStrCmpW #define ntsupStrCmpI ntsupStrCmpIW +#define ntsupStrCopy ntsupStrCopyW #define ntsupStrNCopy ntsupStrNCopyW #define ntsupStrNCmp ntsupStrNCmpW #define ntsupStrStrI ntsupStrStrIW #define ntsupStrCat ntsupStrCatW #define ntsupStrCatEx ntsupStrCatExW +#define ntsupStrToUInt64 ntsupStrToUInt64W +#define ntsupUInt64ToStr ntsupUInt64ToStrW #else #define ntsupLowerChar ntsupLowerCharA +#define ntsupStrChr ntsupStrChrA #define ntsupStrLen ntsupStrLenA #define ntsupStrCmp ntsupStrCmpA #define ntsupStrCmpI ntsupStrCmpIA +#define ntsupStrCopy ntsupStrCopyA #define ntsupStrNCopy ntsupStrNCopyA #define ntsupStrNCmp ntsupStrNCmpA #define ntsupStrStrI ntsupStrStrIA #define ntsupStrCat ntsupStrCatA #define ntsupStrCatEx ntsupStrCatExA +#define ntsupStrToUInt64 ntsupStrToUInt64A +#define ntsupUInt64ToStr ntsupUInt64ToStrA #endif // diff --git a/Source/WinObjEx64/main.c b/Source/WinObjEx64/main.c index 405a8c9..6ce7b8f 100644 --- a/Source/WinObjEx64/main.c +++ b/Source/WinObjEx64/main.c @@ -1071,11 +1071,8 @@ LRESULT CALLBACK MainWindowProc( } break; - case WM_CLOSE: - DestroyWindow(hwnd); - return TRUE; - case WM_DESTROY: + supWriteObexConfiguration(hwnd); PostQuitMessage(0); return 0; @@ -1511,6 +1508,7 @@ DWORD guiCreateMainWindowAndComponents( HIMAGELIST treeViewImages; INITCOMMONCONTROLSEX iccx; WNDCLASSEX wndClass; + POBEX_CONFIG pObexConfig; HINSTANCE hInstance = Globals->hInstance; WCHAR szWindowTitle[100]; @@ -1569,6 +1567,8 @@ DWORD guiCreateMainWindowAndComponents( _strcat(szWindowTitle, TEXT(" (Wine)")); } + pObexConfig = supGetParametersBlock(); + // // Create main window. // @@ -1577,10 +1577,10 @@ DWORD guiCreateMainWindowAndComponents( MAKEINTATOM(classAtom), szWindowTitle, WS_VISIBLE | WS_OVERLAPPEDWINDOW, - CW_USEDEFAULT, - CW_USEDEFAULT, - SCALE_DPI_VALUE(800, Globals->CurrentDPI), - SCALE_DPI_VALUE(600, Globals->CurrentDPI), + pObexConfig->X, + pObexConfig->Y, + SCALE_DPI_VALUE(pObexConfig->Width, Globals->CurrentDPI), + SCALE_DPI_VALUE(pObexConfig->Height, Globals->CurrentDPI), NULL, NULL, hInstance, diff --git a/Source/WinObjEx64/sup/sup.c b/Source/WinObjEx64/sup/sup.c index 9797e79..99fd50f 100644 --- a/Source/WinObjEx64/sup/sup.c +++ b/Source/WinObjEx64/sup/sup.c @@ -6,7 +6,7 @@ * * VERSION: 2.12 * -* DATE: 25 Jul 2026 +* DATE: 28 Jul 2026 * * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED @@ -1220,13 +1220,13 @@ PVOID supGetObjectTypesInfo( PVOID buffer = NULL; ULONG returnedLength = 0; - if (NT_SUCCESS(supQueryObjectTypesInformation(&buffer, - &returnedLength, - 1024 * 16))) + if (NT_SUCCESS(supQueryObjectTypesInformation(&buffer, + &returnedLength, + 1024 * 16))) { return buffer; } - + return NULL; } @@ -9819,6 +9819,228 @@ VOID supCloseKnownPropertiesDialog( SendMessage(hwndDlg, WM_CLOSE, 0, 0); } +/* +* supxReadDwordValue +* +* Purpose: +* +* Tiny helper to read from Registry DWORD value. +* +*/ +BOOL supxReadDwordValue( + _In_ HKEY hKey, + _In_ LPCWSTR lpValueName, + _Out_ PDWORD Value +) +{ + DWORD cbData = sizeof(DWORD); + DWORD dwType = REG_DWORD; + + if (ERROR_SUCCESS == RegQueryValueEx(hKey, + lpValueName, + NULL, + &dwType, + (LPBYTE)Value, + &cbData)) + { + return (dwType == REG_DWORD && cbData == sizeof(DWORD)); + } + + return FALSE; +} + +/* +* supxWriteDwordValue +* +* Purpose: +* +* Tiny helper to write into Registry DWORD value. +* +*/ +BOOL supxWriteDwordValue( + _In_ HKEY hKey, + _In_ LPCWSTR lpValueName, + _In_ DWORD Value +) +{ + return (ERROR_SUCCESS == RegSetValueEx(hKey, + lpValueName, + 0, + REG_DWORD, + (LPBYTE)&Value, + sizeof(DWORD))); +} + +/* +* supWriteObexConfiguration +* +* Purpose: +* +* Writes program configuration data to the registry. +* +*/ +_Success_(return) +BOOL supWriteObexConfiguration( + _In_ HWND hwnd +) +{ + HKEY hKey; + DWORD value; + WINDOWPLACEMENT wp; + RECT rc; + POBEX_CONFIG config = supGetParametersBlock(); + + if (ERROR_SUCCESS != RegCreateKeyEx(HKEY_CURRENT_USER, + supObexConfiguration, + 0, + NULL, + REG_OPTION_NON_VOLATILE, + KEY_WRITE, + NULL, + &hKey, + NULL)) + { + return FALSE; + } + + // + // Window position and size + // + RtlSecureZeroMemory(&wp, sizeof(wp)); + wp.length = sizeof(wp); + GetWindowPlacement(hwnd, &wp); + rc = wp.rcNormalPosition; + + value = (DWORD)rc.left; + supxWriteDwordValue(hKey, supObexWindowX, value); + + value = (DWORD)rc.top; + supxWriteDwordValue(hKey, supObexWindowY, value); + + value = (DWORD)(rc.right - rc.left); + supxWriteDwordValue(hKey, supObexWindowW, value); + + value = (DWORD)(rc.bottom - rc.top); + supxWriteDwordValue(hKey, supObexWindowH, value); + + // + // Normalization symbol + // + supxWriteDwordValue(hKey, + supObexNormalizationSymbol, + (DWORD)config->szNormalizationSymbol); + + // + // Symbol path + // + if (config->SymbolsPathValid) { + + RegSetValueEx(hKey, + supObexSymPath, + 0, + REG_SZ, + (LPBYTE)config->szSymbolsPath, + ((DWORD)_strlen(config->szSymbolsPath) + 1) * sizeof(WCHAR)); + } + + // + // DbgHelp.dll path + // + if (config->SymbolsDbgHelpDllValid) { + + RegSetValueEx(hKey, + supObexSymDbgHelpDll, + 0, + REG_SZ, + (LPBYTE)config->szSymbolsDbgHelpDll, + ((DWORD)_strlen(config->szSymbolsDbgHelpDll) + 1) * sizeof(WCHAR)); + } + + RegCloseKey(hKey); + + return TRUE; +} + +/* +* supxValidateWindowPlacement +* +* Purpose: +* +* Sanitizes a WinObjEx64 main window size and position in place. +* +* The target monitor is the one nearest to the window's +* saved rect (primary monitor if position is not yet set). +* +*/ +VOID supxValidateWindowPlacement( + _Inout_ POBEX_CONFIG Configuration +) +{ + BOOL xDefault, yDefault; + LONG cxWorkArea, cyWorkArea; + LONGLONG right, bottom; + HMONITOR hMonitor; + POINT pt; + MONITORINFO mi; + RECT rcWindow; + + // + // CW_USEDEFAULT must be consistent for X and Y together. + // + xDefault = (Configuration->X == CW_USEDEFAULT); + yDefault = (Configuration->Y == CW_USEDEFAULT); + + if (xDefault != yDefault) { + Configuration->X = CW_USEDEFAULT; + Configuration->Y = CW_USEDEFAULT; + xDefault = yDefault = TRUE; + } + + if (xDefault && yDefault) { + pt.x = 0; + pt.y = 0; + hMonitor = MonitorFromPoint(pt, MONITOR_DEFAULTTOPRIMARY); + } + else { + rcWindow.left = Configuration->X; + rcWindow.top = Configuration->Y; + rcWindow.right = Configuration->X + Configuration->Width; + rcWindow.bottom = Configuration->Y + Configuration->Height; + + hMonitor = MonitorFromRect(&rcWindow, MONITOR_DEFAULTTONEAREST); + } + + mi.cbSize = sizeof(mi); + if (!GetMonitorInfo(hMonitor, &mi)) { + return; + } + + cxWorkArea = mi.rcWork.right - mi.rcWork.left; + cyWorkArea = mi.rcWork.bottom - mi.rcWork.top; + + if (Configuration->Width <= 0 || Configuration->Width > cxWorkArea) { + Configuration->Width = OBEX_DEFAULT_WIDTH; + } + if (Configuration->Height <= 0 || Configuration->Height > cyWorkArea) { + Configuration->Height = OBEX_DEFAULT_HEIGHT; + } + + if (!xDefault && !yDefault) { + + right = (LONGLONG)Configuration->X + Configuration->Width; + bottom = (LONGLONG)Configuration->Y + Configuration->Height; + + if (right < mi.rcWork.left || + bottom < mi.rcWork.top || + Configuration->X > mi.rcWork.right || + Configuration->Y > mi.rcWork.bottom) + { + Configuration->X = CW_USEDEFAULT; + Configuration->Y = CW_USEDEFAULT; + } + } +} + /* * supReadObexConfiguration * @@ -9845,24 +10067,32 @@ BOOL supReadObexConfiguration( '@', ']', '[', '^', '_', '`', '{', '}', '~' }; + // + // Default values. + // Configuration->SymbolsPathValid = FALSE; Configuration->SymbolsDbgHelpDllValid = FALSE; + Configuration->szNormalizationSymbol = OBJ_NAME_NORMALIZATION_SYMBOL; + Configuration->X = CW_USEDEFAULT; + Configuration->Y = CW_USEDEFAULT; + Configuration->Width = OBEX_DEFAULT_WIDTH; + Configuration->Height = OBEX_DEFAULT_HEIGHT; + if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, supObexConfiguration, 0, KEY_READ, &hKey)) { - cbData = sizeof(DWORD); - dwType = REG_DWORD; - if (ERROR_SUCCESS == RegQueryValueEx(hKey, supObexNormalizationSymbol, - NULL, &dwType, (LPBYTE)&data, &cbData)) - { - if (dwType == REG_DWORD && cbData == sizeof(DWORD)) { - symbol = (WCHAR)data; - for (i = 0; i < RTL_NUMBER_OF(szValidSymbols); i++) { - if (szValidSymbols[i] == symbol) { - Configuration->szNormalizationSymbol = symbol; - break; - } + supxReadDwordValue(hKey, supObexWindowX, (PDWORD)&Configuration->X); + supxReadDwordValue(hKey, supObexWindowY, (PDWORD)&Configuration->Y); + supxReadDwordValue(hKey, supObexWindowW, (PDWORD)&Configuration->Width); + supxReadDwordValue(hKey, supObexWindowH, (PDWORD)&Configuration->Height); + + if (supxReadDwordValue(hKey, supObexNormalizationSymbol, &data)) { + symbol = (WCHAR)data; + for (i = 0; i < RTL_NUMBER_OF(szValidSymbols); i++) { + if (szValidSymbols[i] == symbol) { + Configuration->szNormalizationSymbol = symbol; + break; } } } @@ -9892,9 +10122,11 @@ BOOL supReadObexConfiguration( } RegCloseKey(hKey); + supxValidateWindowPlacement(Configuration); return TRUE; } + supxValidateWindowPlacement(Configuration); return FALSE; } diff --git a/Source/WinObjEx64/sup/sup.h b/Source/WinObjEx64/sup/sup.h index 1ae3aee..7781835 100644 --- a/Source/WinObjEx64/sup/sup.h +++ b/Source/WinObjEx64/sup/sup.h @@ -6,7 +6,7 @@ * * VERSION: 2.12 * -* DATE: 25 Jul 2026 +* DATE: 28 Jul 2026 * * Common header file for the program support routines. * @@ -51,11 +51,19 @@ #define supObexSymPath L"SymPath" #define supObexSymDbgHelpDll L"SymDbgHelpDll" #define supObexNormalizationSymbol L"NormalizationSymbol" +#define supObexWindowX L"WindowX" +#define supObexWindowY L"WindowY" +#define supObexWindowH L"WindowH" +#define supObexWindowW L"WindowW" // All relatives to supObexConfiguration typedef struct _OBEX_CONFIG { BOOLEAN SymbolsPathValid; BOOLEAN SymbolsDbgHelpDllValid; + INT X; + INT Y; + INT Width; + INT Height; WCHAR szNormalizationSymbol; //supObexNormalizationSymbol WCHAR szSymbolsPath[MAX_PATH + 1]; //supObexSymbolsPath WCHAR szSymbolsDbgHelpDll[MAX_PATH + 1]; //supObexSymbolsDbgHelpDll @@ -1275,6 +1283,10 @@ BOOL supImageFixSections( VOID supCloseKnownPropertiesDialog( _In_opt_ HWND hwndDlg); +_Success_(return) +BOOL supWriteObexConfiguration( + _In_ HWND hwnd); + _Success_(return) BOOL supReadObexConfiguration( _Out_ POBEX_CONFIG Configuration); diff --git a/Source/WinObjEx64/ui.h b/Source/WinObjEx64/ui.h index e3aff0c..89f8e01 100644 --- a/Source/WinObjEx64/ui.h +++ b/Source/WinObjEx64/ui.h @@ -6,7 +6,7 @@ * * VERSION: 2.12 * -* DATE: 25 Jul 2026 +* DATE: 28 Jul 2026 * * Common header file for the user interface. * @@ -198,6 +198,9 @@ typedef struct _LVCOLUMNS_DATA { #define ErrShadowWin32kOffsetNotFound 11 #define ErrShadowWin32kGetStateNotFound 12 +#define OBEX_DEFAULT_WIDTH 800 +#define OBEX_DEFAULT_HEIGHT 600 + // // Common Dialog handlers. // From 49f1b7dd21f443e54984b95f96c4ca2992605250 Mon Sep 17 00:00:00 2001 From: hfiref0x Date: Sat, 8 Aug 2026 10:42:44 +0700 Subject: [PATCH 3/5] RTLs update ntos 1.251 ntsup 2.32 --- Source/Shared/ntos/ntos.h | 26 +++++++++++++-- Source/Shared/ntos/ntsup.c | 66 ++++++++++++++++++++++++++++++++++++-- Source/Shared/ntos/ntsup.h | 25 +++++++++++++-- 3 files changed, 111 insertions(+), 6 deletions(-) diff --git a/Source/Shared/ntos/ntos.h b/Source/Shared/ntos/ntos.h index 0378ff5..267409c 100644 --- a/Source/Shared/ntos/ntos.h +++ b/Source/Shared/ntos/ntos.h @@ -5,9 +5,9 @@ * * TITLE: NTOS.H * -* VERSION: 1.250 +* VERSION: 1.251 * -* DATE: 23 Jul 2026 +* DATE: 08 Aug 2026 * * Common header file for the ntos API functions and definitions. * @@ -5790,6 +5790,7 @@ typedef enum _MEMORY_INFORMATION_CLASS { MemoryPhysicalContiguityInformation, MemoryBadInformation, MemoryBadInformationAllProcesses, + MemoryImageExtensionInformation, MaxMemoryInfoClass } MEMORY_INFORMATION_CLASS, *PMEMORY_INFORMATION_CLASS; @@ -5968,6 +5969,19 @@ typedef struct _MEMORY_WORKING_SET_EX_INFORMATION { } u1; } MEMORY_WORKING_SET_EX_INFORMATION, * PMEMORY_WORKING_SET_EX_INFORMATION; +typedef enum _MEMORY_IMAGE_EXTENSION_TYPE { + MemoryImageExtensionCfgScp, + MemoryImageExtensionCfgEmulatedScp, + MemoryImageExtensionTypeMax, +} MEMORY_IMAGE_EXTENSION_TYPE; + +typedef struct _MEMORY_IMAGE_EXTENSION_INFORMATION { + MEMORY_IMAGE_EXTENSION_TYPE ExtensionType; + ULONG Flags; + PVOID ExtensionImageBaseRva; + SIZE_T ExtensionSize; +} MEMORY_IMAGE_EXTENSION_INFORMATION, * PMEMORY_IMAGE_EXTENSION_INFORMATION; + #define MM_ZERO_ACCESS 0 // this value is not used. #define MM_READONLY 1 #define MM_EXECUTE 2 @@ -11673,6 +11687,14 @@ typedef struct _EVENT_DESCRIPTOR { ULONGLONG Keyword; } EVENT_DESCRIPTOR, * PEVENT_DESCRIPTOR; typedef const EVENT_DESCRIPTOR* PCEVENT_DESCRIPTOR; + +typedef enum _EVENT_INFO_CLASS { + EventProviderBinaryTrackInfo, + EventProviderSetReserved1, + EventProviderSetTraits, + EventProviderUseDescriptorType, + MaxEventInfo +} EVENT_INFO_CLASS; #endif typedef struct _EVENT_FILTER_DESCRIPTOR* PEVENT_FILTER_DESCRIPTOR; diff --git a/Source/Shared/ntos/ntsup.c b/Source/Shared/ntos/ntsup.c index 3b8f123..c059be0 100644 --- a/Source/Shared/ntos/ntsup.c +++ b/Source/Shared/ntos/ntsup.c @@ -4,9 +4,9 @@ * * TITLE: NTSUP.C * -* VERSION: 2.31 +* VERSION: 2.32 * -* DATE: 26 Jul 2026 +* DATE: 28 Jul 2026 * * Native API support functions. * @@ -1200,6 +1200,68 @@ SIZE_T ntsupUInt64ToStrA( return length; } +/* +* ntsupHexToUInt64A +* +* Purpose: +* +* Converts a ANSI hexademical string to the ULONGLONG value. +* +*/ +ULONGLONG ntsupHexToUInt64A( + _In_opt_ LPCSTR String +) +{ + INT digit; + ULONGLONG value = 0; + + if (!String) + return 0; + + while (*String) { + + digit = ntsupHexDigitToInt((UCHAR)*String); + if (digit < 0) + break; + + value = (value << 4) | (ULONG)digit; + String++; + } + + return value; +} + +/* +* ntsupHexToUInt64W +* +* Purpose: +* +* Converts a UTF-16 hexademical string to the ULONGLONG value. +* +*/ +ULONGLONG ntsupHexToUInt64W( + _In_opt_ LPCWSTR String +) +{ + INT digit; + ULONGLONG value = 0; + + if (!String) + return 0; + + while (*String) { + + digit = ntsupHexDigitToInt((WCHAR)*String); + if (digit < 0) + break; + + value = (value << 4) | (ULONG)digit; + String++; + } + + return value; +} + /* * ntsupHeapAlloc * diff --git a/Source/Shared/ntos/ntsup.h b/Source/Shared/ntos/ntsup.h index 816f853..fbf25e2 100644 --- a/Source/Shared/ntos/ntsup.h +++ b/Source/Shared/ntos/ntsup.h @@ -4,9 +4,9 @@ * * TITLE: NTSUP.H * -* VERSION: 2.31 +* VERSION: 2.32 * -* DATE: 26 Jul 2026 +* DATE: 28 Jul 2026 * * Common header file for the NT API support functions and definitions. * @@ -125,6 +125,20 @@ VOID ntsupSha256Final( // // Ronova requires get rid of minirtl. // +FORCEINLINE INT ntsupHexDigitToInt( + _In_ UINT ch +) +{ + if ((ch >= '0') && (ch <= '9')) + return (INT)(ch - '0'); + + ch = (UINT)((ch >= 'A' && ch <= 'Z') ? (ch + ('a' - 'A')) : ch); + + if ((ch >= 'a') && (ch <= 'f')) + return (INT)(ch - 'a' + 10); + + return -1; +} FORCEINLINE BOOLEAN ntsupIsDigitA( _In_ CHAR Ch @@ -255,6 +269,11 @@ SIZE_T ntsupUInt64ToStrA( _Out_writes_z_(BufferCount) LPSTR Buffer, _In_ SIZE_T BufferCount); +ULONGLONG ntsupHexToUInt64A( + _In_opt_ LPCSTR String); +ULONGLONG ntsupHexToUInt64W( + _In_opt_ LPCWSTR String); + #ifdef _UNICODE #define ntsupLowerChar ntsupLowerCharW #define ntsupStrChr ntsupStrChrW @@ -269,6 +288,7 @@ SIZE_T ntsupUInt64ToStrA( #define ntsupStrCatEx ntsupStrCatExW #define ntsupStrToUInt64 ntsupStrToUInt64W #define ntsupUInt64ToStr ntsupUInt64ToStrW +#define ntsupHexToUInt64 ntsupHexToUInt64W #else #define ntsupLowerChar ntsupLowerCharA #define ntsupStrChr ntsupStrChrA @@ -283,6 +303,7 @@ SIZE_T ntsupUInt64ToStrA( #define ntsupStrCatEx ntsupStrCatExA #define ntsupStrToUInt64 ntsupStrToUInt64A #define ntsupUInt64ToStr ntsupUInt64ToStrA +#define ntsupHexToUInt64 ntsupHexToUInt64A #endif // From b116b817eac5769b627be4173139f52cc801173e Mon Sep 17 00:00:00 2001 From: hfiref0x Date: Sun, 16 Aug 2026 09:45:33 +0700 Subject: [PATCH 4/5] RTLs update ntos 1.252 ntsup 2.33 ntbuilds 1.30 --- Source/Shared/ntos/ntbuilds.h | 39 +- Source/Shared/ntos/ntos.h | 296 ++++++++- Source/Shared/ntos/ntsup.c | 346 ++++++----- Source/Shared/ntos/ntsup.h | 1071 +++++++++++++++++---------------- 4 files changed, 1077 insertions(+), 675 deletions(-) diff --git a/Source/Shared/ntos/ntbuilds.h b/Source/Shared/ntos/ntbuilds.h index 4af6980..4a7ddd2 100644 --- a/Source/Shared/ntos/ntbuilds.h +++ b/Source/Shared/ntos/ntbuilds.h @@ -4,9 +4,9 @@ * * TITLE: NTBUILDS.H * -* VERSION: 1.29 +* VERSION: 1.30 * -* DATE: 21 May 2026 +* DATE: 31 Jul 2026 * * Windows NT builds definition file. * @@ -22,6 +22,41 @@ // Defines for Major Windows NT release builds // +// +// Archeology part START +// + +// Windows NT 3.51 +#define NT_WIN_NT351 1057 + +// Windows NT 4.0 +#define NT_WIN_NT4 1381 + +// Windows 2000 +#define NT_WIN_2K 2195 + +// Windows XP +#define NT_WIN_XP 2600 + +// Windows XP 64 uses same build as server +#define NT_WIN_XP_64 3790 + +// Windows 2003 (RTM/SP1) +#define NT_WINSRV_2003 3790 + +// +// Archeology part END +// + +// Windows Vista RTM +#define NT_WIN_VISTA_RTM 6000 + +// Windows Vista SP1 +#define NT_WIN_VISTA_SP1 6001 + +// Windows Vista SP2 +#define NT_WIN_VISTA_SP2 6002 + // Windows 7 RTM #define NT_WIN7_RTM 7600 diff --git a/Source/Shared/ntos/ntos.h b/Source/Shared/ntos/ntos.h index 267409c..f2ad8b4 100644 --- a/Source/Shared/ntos/ntos.h +++ b/Source/Shared/ntos/ntos.h @@ -5,9 +5,9 @@ * * TITLE: NTOS.H * -* VERSION: 1.251 +* VERSION: 1.252 * -* DATE: 08 Aug 2026 +* DATE: 12 Aug 2026 * * Common header file for the ntos API functions and definitions. * @@ -759,8 +759,46 @@ typedef struct _VM_COUNTERS { SIZE_T QuotaNonPagedPoolUsage; SIZE_T PagefileUsage; SIZE_T PeakPagefileUsage; - SIZE_T PrivatePageCount; -} VM_COUNTERS; +} VM_COUNTERS, *PVM_COUNTERS; + +typedef struct _VM_COUNTERS_EX { + SIZE_T PeakVirtualSize; + SIZE_T VirtualSize; + ULONG PageFaultCount; + SIZE_T PeakWorkingSetSize; + SIZE_T WorkingSetSize; + SIZE_T QuotaPeakPagedPoolUsage; + SIZE_T QuotaPagedPoolUsage; + SIZE_T QuotaPeakNonPagedPoolUsage; + SIZE_T QuotaNonPagedPoolUsage; + SIZE_T PagefileUsage; + SIZE_T PeakPagefileUsage; + SIZE_T PrivateUsage; +} VM_COUNTERS_EX, * PVM_COUNTERS_EX; + +typedef struct _VM_COUNTERS_EX2 { + union + { + VM_COUNTERS_EX CountersEx; + struct + { + SIZE_T PeakVirtualSize; + SIZE_T VirtualSize; + ULONG PageFaultCount; + SIZE_T PeakWorkingSetSize; + SIZE_T WorkingSetSize; + SIZE_T QuotaPeakPagedPoolUsage; + SIZE_T QuotaPagedPoolUsage; + SIZE_T QuotaPeakNonPagedPoolUsage; + SIZE_T QuotaNonPagedPoolUsage; + SIZE_T PagefileUsage; + SIZE_T PeakPagefileUsage; + SIZE_T PrivateUsage; + }; + }; + SIZE_T PrivateWorkingSetSize; + SIZE_T SharedCommitUsage; +} VM_COUNTERS_EX2, * PVM_COUNTERS_EX2; typedef struct _SYSTEM_THREAD_INFORMATION { LARGE_INTEGER KernelTime; @@ -804,8 +842,24 @@ typedef struct _SYSTEM_PROCESS_INFORMATION { ULONG HandleCount; ULONG SessionId; ULONG_PTR UniqueProcessKey; - VM_COUNTERS VmCounters; - IO_COUNTERS IoCounters; + SIZE_T PeakVirtualSize; + SIZE_T VirtualSize; + ULONG PageFaultCount; + SIZE_T PeakWorkingSetSize; + SIZE_T WorkingSetSize; + SIZE_T QuotaPeakPagedPoolUsage; + SIZE_T QuotaPagedPoolUsage; + SIZE_T QuotaPeakNonPagedPoolUsage; + SIZE_T QuotaNonPagedPoolUsage; + SIZE_T PagefileUsage; + SIZE_T PeakPagefileUsage; + SIZE_T PrivatePageCount; + LARGE_INTEGER ReadOperationCount; + LARGE_INTEGER WriteOperationCount; + LARGE_INTEGER OtherOperationCount; + LARGE_INTEGER ReadTransferCount; + LARGE_INTEGER WriteTransferCount; + LARGE_INTEGER OtherTransferCount; SYSTEM_THREAD_INFORMATION Threads[1]; //not a part of this structure } SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION; @@ -927,6 +981,91 @@ typedef struct _SYSTEM_BASIC_INFORMATION { CCHAR NumberOfProcessors; } SYSTEM_BASIC_INFORMATION, *PSYSTEM_BASIC_INFORMATION; +typedef struct _SYSTEM_PERFORMANCE_INFORMATION { + LARGE_INTEGER IdleProcessTime; + LARGE_INTEGER IoReadTransferCount; + LARGE_INTEGER IoWriteTransferCount; + LARGE_INTEGER IoOtherTransferCount; + ULONG IoReadOperationCount; + ULONG IoWriteOperationCount; + ULONG IoOtherOperationCount; + ULONG AvailablePages; + ULONG CommittedPages; + ULONG CommitLimit; + ULONG PeakCommitment; + ULONG PageFaultCount; + ULONG CopyOnWriteCount; + ULONG TransitionCount; + ULONG CacheTransitionCount; + ULONG DemandZeroCount; + ULONG PageReadCount; + ULONG PageReadIoCount; + ULONG CacheReadCount; + ULONG CacheIoCount; + ULONG DirtyPagesWriteCount; + ULONG DirtyWriteIoCount; + ULONG MappedPagesWriteCount; + ULONG MappedWriteIoCount; + ULONG PagedPoolPages; + ULONG NonPagedPoolPages; + ULONG PagedPoolAllocs; + ULONG PagedPoolFrees; + ULONG NonPagedPoolAllocs; + ULONG NonPagedPoolFrees; + ULONG FreeSystemPtes; + ULONG ResidentSystemCodePage; + ULONG TotalSystemDriverPages; + ULONG TotalSystemCodePages; + ULONG NonPagedPoolLookasideHits; + ULONG PagedPoolLookasideHits; + ULONG AvailablePagedPoolPages; + ULONG ResidentSystemCachePage; + ULONG ResidentPagedPoolPage; + ULONG ResidentSystemDriverPage; + ULONG CcFastReadNoWait; + ULONG CcFastReadWait; + ULONG CcFastReadResourceMiss; + ULONG CcFastReadNotPossible; + ULONG CcFastMdlReadNoWait; + ULONG CcFastMdlReadWait; + ULONG CcFastMdlReadResourceMiss; + ULONG CcFastMdlReadNotPossible; + ULONG CcMapDataNoWait; + ULONG CcMapDataWait; + ULONG CcMapDataNoWaitMiss; + ULONG CcMapDataWaitMiss; + ULONG CcPinMappedDataCount; + ULONG CcPinReadNoWait; + ULONG CcPinReadWait; + ULONG CcPinReadNoWaitMiss; + ULONG CcPinReadWaitMiss; + ULONG CcCopyReadNoWait; + ULONG CcCopyReadWait; + ULONG CcCopyReadNoWaitMiss; + ULONG CcCopyReadWaitMiss; + ULONG CcMdlReadNoWait; + ULONG CcMdlReadWait; + ULONG CcMdlReadNoWaitMiss; + ULONG CcMdlReadWaitMiss; + ULONG CcReadAheadIos; + ULONG CcLazyWriteIos; + ULONG CcLazyWritePages; + ULONG CcDataFlushes; + ULONG CcDataPages; + ULONG ContextSwitches; + ULONG FirstLevelTbFills; + ULONG SecondLevelTbFills; + ULONG SystemCalls; + ULONGLONG CcTotalDirtyPages; + ULONGLONG CcDirtyPageThreshold; + LONGLONG ResidentAvailablePages; + ULONGLONG SharedCommittedPages; + ULONGLONG MdlPagesAllocated; + ULONGLONG PfnDatabaseCommittedPages; + ULONGLONG SystemPageTableCommittedPages; + ULONGLONG ContiguousPagesAllocated; +} SYSTEM_PERFORMANCE_INFORMATION, * PSYSTEM_PERFORMANCE_INFORMATION; + typedef struct _SYSTEM_ISOLATED_USER_MODE_INFORMATION { BOOLEAN SecureKernelRunning : 1; BOOLEAN HvciEnabled : 1; @@ -1021,6 +1160,25 @@ typedef struct _SYSTEM_FIRMWARE_PARTITION_INFORMATION { UNICODE_STRING FirmwarePartition; // \Device\HarddiskX } SYSTEM_FIRMWARE_PARTITION_INFORMATION, * PSYSTEM_FIRMWARE_PARTITION_INFORMATION; +typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION { + LARGE_INTEGER IdleTime; + LARGE_INTEGER KernelTime; + LARGE_INTEGER UserTime; + LARGE_INTEGER DpcTime; + LARGE_INTEGER InterruptTime; + ULONG InterruptCount; + ULONG Spare0; +} SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION, * PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION; + +_Struct_size_bytes_(NextEntryOffset) +typedef struct _SYSTEM_PAGEFILE_INFORMATION { + ULONG NextEntryOffset; + ULONG TotalSize; + ULONG TotalInUse; + ULONG PeakUsage; + UNICODE_STRING PageFileName; +} SYSTEM_PAGEFILE_INFORMATION, * PSYSTEM_PAGEFILE_INFORMATION; + typedef struct _RTL_PROCESS_BACKTRACE_INFORMATION { PCHAR SymbolicBackTrace; ULONG TraceCount; @@ -11123,6 +11281,132 @@ RtlCaptureStackBackTrace( _Out_writes_to_(FramesToCapture, return) PVOID* BackTrace, _Out_opt_ PULONG BackTraceHash); +typedef struct _RTL_PROCESS_MODULES* PRTL_PROCESS_MODULES; +typedef struct _RTL_PROCESS_MODULE_INFORMATION_EX* PRTL_PROCESS_MODULE_INFORMATION_EX; +typedef struct _RTL_PROCESS_BACKTRACES* PRTL_PROCESS_BACKTRACES; +typedef struct _RTL_PROCESS_LOCKS* PRTL_PROCESS_LOCKS; + +typedef struct _RTL_PROCESS_VERIFIER_OPTIONS { + ULONG SizeStruct; + ULONG Option; + UCHAR OptionData[1]; +} RTL_PROCESS_VERIFIER_OPTIONS, * PRTL_PROCESS_VERIFIER_OPTIONS; + +typedef struct _RTL_DEBUG_INFORMATION { + HANDLE SectionHandleClient; + PVOID ViewBaseClient; + PVOID ViewBaseTarget; + ULONG_PTR ViewBaseDelta; + HANDLE EventPairClient; + HANDLE EventPairTarget; + HANDLE TargetProcessId; + HANDLE TargetThreadHandle; + ULONG Flags; + SIZE_T OffsetFree; + SIZE_T CommitSize; + SIZE_T ViewSize; + union + { + PRTL_PROCESS_MODULES Modules; + PRTL_PROCESS_MODULE_INFORMATION_EX ModulesEx; + }; + PRTL_PROCESS_BACKTRACES BackTraces; + PVOID Heaps; + PRTL_PROCESS_LOCKS Locks; + PVOID SpecificHeap; + HANDLE TargetProcessHandle; + PRTL_PROCESS_VERIFIER_OPTIONS VerifierOptions; + PVOID ProcessHeap; + HANDLE CriticalSectionHandle; + HANDLE CriticalSectionOwnerThread; + PVOID Reserved[4]; +} RTL_DEBUG_INFORMATION, * PRTL_DEBUG_INFORMATION; + +NTSYSAPI +PRTL_DEBUG_INFORMATION +NTAPI +RtlCreateQueryDebugBuffer( + _In_opt_ ULONG MaximumCommit, + _In_ BOOLEAN UseEventPair); + +NTSYSAPI +NTSTATUS +NTAPI +RtlDestroyQueryDebugBuffer( + _In_ PRTL_DEBUG_INFORMATION Buffer); + +#define RTL_QUERY_PROCESS_MODULES 0x00000001 +#define RTL_QUERY_PROCESS_BACKTRACES 0x00000002 +#define RTL_QUERY_PROCESS_HEAP_SUMMARY 0x00000004 +#define RTL_QUERY_PROCESS_HEAP_TAGS 0x00000008 +#define RTL_QUERY_PROCESS_HEAP_ENTRIES 0x00000010 +#define RTL_QUERY_PROCESS_LOCKS 0x00000020 +#define RTL_QUERY_PROCESS_MODULES32 0x00000040 +#define RTL_QUERY_PROCESS_VERIFIER_OPTIONS 0x00000080 +#define RTL_QUERY_PROCESS_MODULESEX 0x00000100 +#define RTL_QUERY_PROCESS_HEAP_SEGMENTS 0x00000200 +#define RTL_QUERY_PROCESS_CS_OWNER 0x00000400 +#define RTL_QUERY_PROCESS_USE_CURRENT_PROCESS 0x40000000 +#define RTL_QUERY_PROCESS_NONINVASIVE 0x80000000 +#define RTL_QUERY_PROCESS_NONINVASIVE_CS_OWNER 0x80000800 + +NTSYSAPI +NTSTATUS +NTAPI +RtlQueryProcessDebugInformation( + _In_ HANDLE UniqueProcessId, + _In_ ULONG Flags, + _Inout_ PRTL_DEBUG_INFORMATION Buffer); + +// Windows 7/8/10 +typedef struct _RTL_HEAP_INFORMATION_V1 { + PVOID BaseAddress; + ULONG Flags; + USHORT EntryOverhead; + USHORT CreatorBackTraceIndex; + SIZE_T BytesAllocated; + SIZE_T BytesCommitted; + ULONG NumberOfTags; + ULONG NumberOfEntries; + ULONG NumberOfPseudoTags; + ULONG PseudoTagGranularity; + ULONG Reserved[5]; + PVOID Tags; + PVOID Entries; +} RTL_HEAP_INFORMATION_V1, * PRTL_HEAP_INFORMATION_V1; + +// Windows 11 > 22000 +typedef struct _RTL_HEAP_INFORMATION_V2 { + PVOID BaseAddress; + ULONG Flags; + USHORT EntryOverhead; + USHORT CreatorBackTraceIndex; + SIZE_T BytesAllocated; + SIZE_T BytesCommitted; + ULONG NumberOfTags; + ULONG NumberOfEntries; + ULONG NumberOfPseudoTags; + ULONG PseudoTagGranularity; + ULONG Reserved[5]; + PVOID Tags; + PVOID Entries; + ULONG64 HeapTag; +} RTL_HEAP_INFORMATION_V2, * PRTL_HEAP_INFORMATION_V2; + +#define RTL_HEAP_SIGNATURE 0xFFEEFFEEUL +#define RTL_HEAP_SEGMENT_SIGNATURE 0xDDEEDDEEUL + +typedef struct _RTL_PROCESS_HEAPS_V1 { + ULONG NumberOfHeaps; + _Field_size_(NumberOfHeaps) RTL_HEAP_INFORMATION_V1 Heaps[1]; +} RTL_PROCESS_HEAPS_V1, * PRTL_PROCESS_HEAPS_V1; + +typedef struct _RTL_PROCESS_HEAPS_V2 { + ULONG NumberOfHeaps; + _Field_size_(NumberOfHeaps) RTL_HEAP_INFORMATION_V2 Heaps[1]; +} RTL_PROCESS_HEAPS_V2, * PRTL_PROCESS_HEAPS_V2; + + /************************************************************************************ * * RTL AVL Tree API. diff --git a/Source/Shared/ntos/ntsup.c b/Source/Shared/ntos/ntsup.c index c059be0..a9763cb 100644 --- a/Source/Shared/ntos/ntsup.c +++ b/Source/Shared/ntos/ntsup.c @@ -4,9 +4,9 @@ * * TITLE: NTSUP.C * -* VERSION: 2.32 +* VERSION: 2.33 * -* DATE: 28 Jul 2026 +* DATE: 12 Aug 2026 * * Native API support functions. * @@ -220,7 +220,7 @@ VOID ntsupSha256Final( * - Requested size fits completely inside the queried memory region. * */ -BOOLEAN ntsupIsAddressValid( +BOOLEAN NTAPI ntsupIsAddressValid( _In_ PVOID Address, _In_ SIZE_T Size ) @@ -301,7 +301,7 @@ LPWSTR ntsupStrChrW( * * Purpose: * -* Returns a pointer to the first occurrence of Character in String +* Returns a pointer to the first occurrence of Character in String * (including the terminator if Character is 0), or NULL if not found. * */ @@ -509,7 +509,7 @@ INT ntsupStrCmpIW( * * Purpose: * -* Copies a null-terminated ANSI string from Source to Destination +* Copies a null-terminated ANSI string from Source to Destination * (unbounded, caller-guaranteed capacity). * */ @@ -573,7 +573,7 @@ LPWSTR ntsupStrCopyW( * * Purpose: * -* Copies up to SourceCount characters from an ANSI source string +* Copies up to SourceCount characters from an ANSI source string * into a fixed-size destination buffer, always null-terminating. * */ @@ -1270,7 +1270,7 @@ ULONGLONG ntsupHexToUInt64W( * Wrapper for RtlAllocateHeap with process heap. * */ -PVOID ntsupHeapAlloc( +PVOID NTAPI ntsupHeapAlloc( _In_ SIZE_T Size ) { @@ -1278,14 +1278,14 @@ PVOID ntsupHeapAlloc( } /* - * ntsupHeapReAlloc - * - * Purpose: - * - * Wrapper for RtlReAllocateHeap with process heap. - * - */ -PVOID ntsupHeapReAlloc( +* ntsupHeapReAlloc +* +* Purpose: +* +* Wrapper for RtlReAllocateHeap with process heap. +* +*/ +PVOID NTAPI ntsupHeapReAlloc( _In_ PVOID BaseAddress, _In_ SIZE_T Size ) @@ -1304,7 +1304,7 @@ PVOID ntsupHeapReAlloc( * Wrapper for RtlFreeHeap with process heap. * */ -BOOL ntsupHeapFree( +BOOL NTAPI ntsupHeapFree( _In_ PVOID BaseAddress ) { @@ -1312,14 +1312,14 @@ BOOL ntsupHeapFree( } /* - * ntsupHeapSize - * - * Purpose: - * - * Wrapper for RtlSizeHeap with process heap. - * - */ -SIZE_T ntsupHeapSize( +* ntsupHeapSize +* +* Purpose: +* +* Wrapper for RtlSizeHeap with process heap. +* +*/ +SIZE_T NTAPI ntsupHeapSize( _In_ PVOID BaseAddress ) { @@ -1327,14 +1327,14 @@ SIZE_T ntsupHeapSize( } /* - * ntsupHeapValidate - * - * Purpose: - * - * Wrapper for RtlValidateHeap with process heap. - * - */ -BOOL ntsupHeapValidate( +* ntsupHeapValidate +* +* Purpose: +* +* Wrapper for RtlValidateHeap with process heap. +* +*/ +BOOL NTAPI ntsupHeapValidate( _In_ PVOID BaseAddress ) { @@ -1342,14 +1342,14 @@ BOOL ntsupHeapValidate( } /* - * ntsupHeapCompact - * - * Purpose: - * - * Wrapper for RtlCompactHeap with process heap. - * - */ -SIZE_T ntsupHeapCompact( +* ntsupHeapCompact +* +* Purpose: +* +* Wrapper for RtlCompactHeap with process heap. +* +*/ +SIZE_T NTAPI ntsupHeapCompact( VOID ) { @@ -1357,14 +1357,14 @@ SIZE_T ntsupHeapCompact( } /* - * ntsupHeapLock - * - * Purpose: - * - * Wrapper for RtlLockHeap with process heap. - * - */ -BOOL ntsupHeapLock( +* ntsupHeapLock +* +* Purpose: +* +* Wrapper for RtlLockHeap with process heap. +* +*/ +BOOL NTAPI ntsupHeapLock( VOID ) { @@ -1372,14 +1372,14 @@ BOOL ntsupHeapLock( } /* - * ntsupHeapUnlock - * - * Purpose: - * - * Wrapper for RtlUnlockHeap with process heap. - * - */ -BOOL ntsupHeapUnlock( +* ntsupHeapUnlock +* +* Purpose: +* +* Wrapper for RtlUnlockHeap with process heap. +* +*/ +BOOL NTAPI ntsupHeapUnlock( VOID ) { @@ -1394,7 +1394,7 @@ BOOL ntsupHeapUnlock( * Wrapper for ntsupVirtualAllocEx with standard parameters. * */ -PVOID ntsupVirtualAllocEx( +PVOID NTAPI ntsupVirtualAllocEx( _In_ SIZE_T Size, _In_ ULONG AllocationType, _In_ ULONG Protect) @@ -1428,7 +1428,7 @@ PVOID ntsupVirtualAllocEx( * Wrapper for supVirtualAllocEx. * */ -PVOID ntsupVirtualAlloc( +PVOID NTAPI ntsupVirtualAlloc( _In_ SIZE_T Size) { return ntsupVirtualAllocEx(Size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); @@ -1442,7 +1442,7 @@ PVOID ntsupVirtualAlloc( * Wrapper for NtLockVirtualMemory. * */ -BOOL ntsupVirtualLock( +BOOL NTAPI ntsupVirtualLock( _In_ LPVOID lpAddress, _In_ SIZE_T dwSize ) @@ -1461,7 +1461,7 @@ BOOL ntsupVirtualLock( * Wrapper for NtUnlockVirtualMemory. * */ -BOOL ntsupVirtualUnlock( +BOOL NTAPI ntsupVirtualUnlock( _In_ LPVOID lpAddress, _In_ SIZE_T dwSize ) @@ -1480,7 +1480,7 @@ BOOL ntsupVirtualUnlock( * Wrapper for NtFreeVirtualMemory. * */ -BOOL ntsupVirtualFree( +BOOL NTAPI ntsupVirtualFree( _In_ PVOID Memory) { NTSTATUS ntStatus = STATUS_UNSUCCESSFUL; @@ -1510,7 +1510,7 @@ BOOL ntsupVirtualFree( * Create new file (or open existing) and write buffer to it. * */ -SIZE_T ntsupWriteBufferToFile( +SIZE_T NTAPI ntsupWriteBufferToFile( _In_ PCWSTR FileName, _In_ PVOID Buffer, _In_ SIZE_T Size, @@ -1617,7 +1617,7 @@ SIZE_T ntsupWriteBufferToFile( NtClose(hFile); } RtlFreeUnicodeString(&ntFileName); - if (Result) *Result = ntStatus; + if (Result)*Result = ntStatus; } return bytesWritten; } @@ -1630,7 +1630,7 @@ SIZE_T ntsupWriteBufferToFile( * Find Module entry for given name. * */ -PVOID ntsupFindModuleEntryByName( +PVOID NTAPI ntsupFindModuleEntryByName( _In_ PRTL_PROCESS_MODULES ModulesList, _In_ LPCSTR ModuleName ) @@ -1659,7 +1659,7 @@ PVOID ntsupFindModuleEntryByName( * Find Module entry for given name. * */ -PVOID ntsupFindModuleEntryByName_U( +PVOID NTAPI ntsupFindModuleEntryByName_U( _In_ PRTL_PROCESS_MODULES ModulesList, _In_ LPCWSTR ModuleName ) @@ -1703,7 +1703,7 @@ PVOID ntsupFindModuleEntryByName_U( * Returns module entry if found, NULL otherwise. * */ -BOOL ntsupFindModuleEntryByAddress( +BOOL NTAPI ntsupFindModuleEntryByAddress( _In_ PRTL_PROCESS_MODULES ModulesList, _In_ PVOID Address, _Out_ PULONG ModuleIndex @@ -1733,7 +1733,7 @@ BOOL ntsupFindModuleEntryByAddress( * Get Module Entry for given Address. * */ -PVOID ntsupGetModuleEntryByAddress( +PVOID NTAPI ntsupGetModuleEntryByAddress( _In_ PRTL_PROCESS_MODULES ModulesList, _In_ PVOID Address ) @@ -1759,7 +1759,7 @@ PVOID ntsupGetModuleEntryByAddress( * Find Module Name for given Address. * */ -PVOID ntsupFindModuleNameByAddress( +PVOID NTAPI ntsupFindModuleNameByAddress( _In_ PRTL_PROCESS_MODULES ModulesList, _In_ PVOID Address, _Inout_ LPWSTR Buffer, @@ -1824,7 +1824,7 @@ PVOID ntsupFindModuleNameByAddress( * If function succeeded - use RtlFreeUnicodeString to release allocated string. * */ -NTSTATUS ntsupConvertToUnicode( +NTSTATUS NTAPI ntsupConvertToUnicode( _In_ LPCSTR AnsiString, _Inout_ PUNICODE_STRING UnicodeString) { @@ -1845,7 +1845,7 @@ NTSTATUS ntsupConvertToUnicode( * If function succeeded - use RtlFreeAnsiString to release allocated string. * */ -NTSTATUS ntsupConvertToAnsi( +NTSTATUS NTAPI ntsupConvertToAnsi( _In_ LPCWSTR UnicodeString, _Inout_ PANSI_STRING AnsiString) { @@ -1863,7 +1863,7 @@ NTSTATUS ntsupConvertToAnsi( * Adjust privilege for the token. * */ -NTSTATUS ntsupSetPrivilege( +NTSTATUS NTAPI ntsupSetPrivilege( _In_ HANDLE TokenHandle, _In_ DWORD Privilege, _In_ BOOLEAN Enable, @@ -1914,7 +1914,7 @@ NTSTATUS ntsupSetPrivilege( * Return FALSE on any error. * */ -BOOLEAN ntsupEnablePrivilege( +BOOLEAN NTAPI ntsupEnablePrivilege( _In_ DWORD Privilege, _In_ BOOLEAN Enable ) @@ -1954,7 +1954,7 @@ BOOLEAN ntsupEnablePrivilege( * Return current process token value with TOKEN_QUERY access right. * */ -HANDLE ntsupGetCurrentProcessToken( +HANDLE NTAPI ntsupGetCurrentProcessToken( VOID) { HANDLE tokenHandle = NULL; @@ -1977,7 +1977,7 @@ HANDLE ntsupGetCurrentProcessToken( * Return MmSystemRangeStart value. * */ -ULONG_PTR ntsupQuerySystemRangeStart( +ULONG_PTR NTAPI ntsupQuerySystemRangeStart( VOID ) { @@ -2005,7 +2005,7 @@ ULONG_PTR ntsupQuerySystemRangeStart( * Return user mode applications accessible address range. * */ -BOOLEAN ntsupQueryUserModeAccessibleRange( +BOOLEAN NTAPI ntsupQueryUserModeAccessibleRange( _Out_ PULONG_PTR MinimumUserModeAddress, _Out_ PULONG_PTR MaximumUserModeAddress ) @@ -2047,7 +2047,7 @@ BOOLEAN ntsupQueryUserModeAccessibleRange( * Perform check if the kernel debugger active. * */ -BOOLEAN ntsupIsKdEnabled( +BOOLEAN NTAPI ntsupIsKdEnabled( _Out_opt_ PBOOLEAN DebuggerAllowed, _Out_opt_ PBOOLEAN DebuggerNotPresent ) @@ -2114,7 +2114,7 @@ BOOLEAN ntsupIsKdEnabled( * Return TRUE if process is wow64. * */ -BOOL ntsupIsProcess32bit( +BOOL NTAPI ntsupIsProcess32bit( _In_ HANDLE hProcess ) { @@ -2145,7 +2145,7 @@ BOOL ntsupIsProcess32bit( * Read list of loaded kernel modules. * */ -PVOID ntsupGetLoadedModulesListEx( +PVOID NTAPI ntsupGetLoadedModulesListEx( _In_ BOOL ExtendedOutput, _Out_opt_ PULONG ReturnLength, _In_ PNTSUPMEMALLOC AllocMem, @@ -2229,7 +2229,7 @@ PVOID ntsupGetLoadedModulesListEx( * Returned buffer must be freed with ntsupHeapFree after usage. * */ -PVOID ntsupGetLoadedModulesList( +PVOID NTAPI ntsupGetLoadedModulesList( _Out_opt_ PULONG ReturnLength ) { @@ -2250,7 +2250,7 @@ PVOID ntsupGetLoadedModulesList( * Returned buffer must be freed with ntsupHeapFree after usage. * */ -PVOID ntsupGetLoadedModulesList2( +PVOID NTAPI ntsupGetLoadedModulesList2( _Out_opt_ PULONG ReturnLength ) { @@ -2271,7 +2271,7 @@ PVOID ntsupGetLoadedModulesList2( * Returned buffer must be freed with FreeMem function after usage. * */ -PVOID ntsupGetSystemInfoEx( +PVOID NTAPI ntsupGetSystemInfoEx( _In_ SYSTEM_INFORMATION_CLASS SystemInformationClass, _Out_opt_ PULONG ReturnLength, _In_ PNTSUPMEMALLOC AllocMem, @@ -2328,7 +2328,7 @@ PVOID ntsupGetSystemInfoEx( * Returned buffer must be freed with ntsupHeapFree after usage. * */ -PVOID ntsupGetSystemInfo( +PVOID NTAPI ntsupGetSystemInfo( _In_ SYSTEM_INFORMATION_CLASS SystemInformationClass, _Out_opt_ PULONG ReturnLength ) @@ -2350,7 +2350,7 @@ PVOID ntsupGetSystemInfo( * Return FALSE on any error. * */ -BOOL ntsupResolveSymbolicLink( +BOOL NTAPI ntsupResolveSymbolicLink( _In_opt_ HANDLE RootDirectoryHandle, _In_ PUNICODE_STRING LinkName, _Inout_ LPWSTR Buffer, @@ -2410,7 +2410,7 @@ BOOL ntsupResolveSymbolicLink( * Lookups thread win32 start address. * */ -BOOL ntsupQueryThreadWin32StartAddress( +BOOL NTAPI ntsupQueryThreadWin32StartAddress( _In_ HANDLE ThreadHandle, _Out_opt_ PULONG_PTR Win32StartAddress ) @@ -2441,7 +2441,7 @@ BOOL ntsupQueryThreadWin32StartAddress( * */ _Success_(return) -NTSTATUS ntsupOpenDirectoryEx( +NTSTATUS NTAPI ntsupOpenDirectoryEx( _Out_ PHANDLE DirectoryHandle, _In_opt_ HANDLE RootDirectoryHandle, _In_ PUNICODE_STRING DirectoryName, @@ -2472,7 +2472,7 @@ NTSTATUS ntsupOpenDirectoryEx( * Open directory handle with DIRECTORY_QUERY access, with root directory support. * */ -NTSTATUS ntsupOpenDirectory( +NTSTATUS NTAPI ntsupOpenDirectory( _Out_ PHANDLE DirectoryHandle, _In_opt_ HANDLE RootDirectoryHandle, _In_ LPCWSTR DirectoryName, @@ -2495,7 +2495,7 @@ NTSTATUS ntsupOpenDirectory( * If nothing found return FALSE. * */ -BOOL ntsupQueryProcessName( +BOOL NTAPI ntsupQueryProcessName( _In_ ULONG_PTR dwProcessId, _In_ PVOID ProcessList, _Inout_ LPWSTR Buffer, @@ -2545,7 +2545,7 @@ BOOL ntsupQueryProcessName( * If nothing found return FALSE. * */ -BOOL ntsupQueryProcessEntryById( +BOOL NTAPI ntsupQueryProcessEntryById( _In_ HANDLE UniqueProcessId, _In_ PVOID ProcessList, _Out_ PSYSTEM_PROCESS_INFORMATION * Entry @@ -2590,7 +2590,7 @@ BOOL ntsupQueryProcessEntryById( * Use FreeMem to release allocated buffer. * */ -NTSTATUS ntsupQueryProcessImageFileNameByProcessId( +NTSTATUS NTAPI ntsupQueryProcessImageFileNameByProcessId( _In_ HANDLE UniqueProcessId, _Out_ PUNICODE_STRING ProcessImageFileName, _In_ PNTSUPMEMALLOC AllocMem, @@ -2638,7 +2638,7 @@ NTSTATUS ntsupQueryProcessImageFileNameByProcessId( * Use FreeMem to release allocated buffer. * */ -NTSTATUS ntsupQuerySystemObjectInformationVariableSize( +NTSTATUS NTAPI ntsupQuerySystemObjectInformationVariableSize( _In_ PFN_NTQUERYROUTINE QueryRoutine, _In_opt_ HANDLE ObjectHandle, _In_ DWORD InformationClass, @@ -2653,7 +2653,7 @@ NTSTATUS ntsupQuerySystemObjectInformationVariableSize( ULONG returnLengthLocal = 0; *Buffer = NULL; - if (ReturnLength) *ReturnLength = 0; + if (ReturnLength)*ReturnLength = 0; ntStatus = QueryRoutine(ObjectHandle, InformationClass, @@ -2686,7 +2686,7 @@ NTSTATUS ntsupQuerySystemObjectInformationVariableSize( if (NT_SUCCESS(ntStatus)) { *Buffer = queryBuffer; - if (ReturnLength) *ReturnLength = returnLengthLocal; + if (ReturnLength)*ReturnLength = returnLengthLocal; } else { FreeMem(queryBuffer); @@ -2705,11 +2705,11 @@ NTSTATUS ntsupQuerySystemObjectInformationVariableSize( * Use FreeMem to release allocated buffer. * */ -NTSTATUS ntsupQuerySystemObjectInformationVariableSizeEx( +NTSTATUS NTAPI ntsupQuerySystemObjectInformationVariableSizeEx( _In_ PFN_NTQUERYROUTINE QueryRoutine, _In_opt_ HANDLE ObjectHandle, _In_ DWORD InformationClass, - _Out_ PVOID* Buffer, + _Out_ PVOID * Buffer, _Out_opt_ PULONG ReturnLength, _In_ ULONG InitialBufferSize, _In_ PNTSUPMEMALLOC AllocMem, @@ -2790,7 +2790,7 @@ NTSTATUS ntsupQuerySystemObjectInformationVariableSizeEx( * Query VSM protection information. * */ -BOOLEAN ntsupQueryVsmProtectionInformation( +BOOLEAN NTAPI ntsupQueryVsmProtectionInformation( _Out_ PBOOLEAN pbDmaProtectionsAvailable, _Out_ PBOOLEAN pbDmaProtectionsInUse, _Out_ PBOOLEAN pbHardwareMbecAvailable, @@ -2801,10 +2801,10 @@ BOOLEAN ntsupQueryVsmProtectionInformation( ULONG returnLength; SYSTEM_VSM_PROTECTION_INFORMATION svpi; - if (pbDmaProtectionsAvailable) *pbDmaProtectionsAvailable = FALSE; - if (pbDmaProtectionsInUse) *pbDmaProtectionsInUse = FALSE; - if (pbHardwareMbecAvailable) *pbHardwareMbecAvailable = FALSE; - if (pbApicVirtualizationAvailable) *pbApicVirtualizationAvailable = FALSE; + if (pbDmaProtectionsAvailable)*pbDmaProtectionsAvailable = FALSE; + if (pbDmaProtectionsInUse)*pbDmaProtectionsInUse = FALSE; + if (pbHardwareMbecAvailable)*pbHardwareMbecAvailable = FALSE; + if (pbApicVirtualizationAvailable)*pbApicVirtualizationAvailable = FALSE; RtlSecureZeroMemory(&svpi, sizeof(SYSTEM_VSM_PROTECTION_INFORMATION)); @@ -2815,10 +2815,10 @@ BOOLEAN ntsupQueryVsmProtectionInformation( &returnLength); if (NT_SUCCESS(ntStatus)) { - if (pbDmaProtectionsAvailable) *pbDmaProtectionsAvailable = svpi.DmaProtectionsAvailable; - if (pbDmaProtectionsInUse) *pbDmaProtectionsInUse = svpi.DmaProtectionsInUse; - if (pbHardwareMbecAvailable) *pbHardwareMbecAvailable = svpi.HardwareMbecAvailable; - if (pbApicVirtualizationAvailable) *pbApicVirtualizationAvailable = svpi.ApicVirtualizationAvailable; + if (pbDmaProtectionsAvailable)*pbDmaProtectionsAvailable = svpi.DmaProtectionsAvailable; + if (pbDmaProtectionsInUse)*pbDmaProtectionsInUse = svpi.DmaProtectionsInUse; + if (pbHardwareMbecAvailable)*pbHardwareMbecAvailable = svpi.HardwareMbecAvailable; + if (pbApicVirtualizationAvailable)*pbApicVirtualizationAvailable = svpi.ApicVirtualizationAvailable; return TRUE; } else { @@ -2836,7 +2836,7 @@ BOOLEAN ntsupQueryVsmProtectionInformation( * Query VBS/HVCI state. * */ -BOOLEAN ntsupQueryVBSState( +BOOLEAN NTAPI ntsupQueryVBSState( _Out_ PBOOLEAN pbVBSRunning, _Out_ PBOOLEAN pbHVCIEnabled, _Out_ PBOOLEAN pbHVCIStrictMode @@ -2904,9 +2904,9 @@ BOOLEAN ntsupQueryVBSState( // Prefer the isolated user mode information for HVCI state. // It reflects the actual VBS-backed HVCI status. // - if (pbHVCIEnabled) *pbHVCIEnabled = iumi.HvciEnabled; + if (pbHVCIEnabled)*pbHVCIEnabled = iumi.HvciEnabled; - if (pbHVCIStrictMode) *pbHVCIStrictMode = iumi.HvciStrictMode; + if (pbHVCIStrictMode)*pbHVCIStrictMode = iumi.HvciStrictMode; return TRUE; } @@ -2920,10 +2920,10 @@ BOOLEAN ntsupQueryVBSState( * * If ImageSize is non-zero, the image is range-checked by * RtlImageNtHeaderEx. Otherwise, range checking is disabled. -* +* */ -PVOID ntsupLookupImageSectionByNameEx( - _In_ CHAR* SectionName, +PVOID NTAPI ntsupLookupImageSectionByNameEx( + _In_ CHAR * SectionName, _In_ ULONG SectionNameLength, _In_ PVOID DllBase, _In_ SIZE_T ImageSize, @@ -3014,8 +3014,8 @@ PVOID ntsupLookupImageSectionByNameEx( * Lookup PE image section by name. * */ -PVOID ntsupLookupImageSectionByName( - _In_ CHAR* SectionName, +PVOID NTAPI ntsupLookupImageSectionByName( + _In_ CHAR * SectionName, _In_ ULONG SectionNameLength, _In_ PVOID DllBase, _Out_ PULONG SectionSize @@ -3037,7 +3037,7 @@ PVOID ntsupLookupImageSectionByName( * Lookup pattern in buffer. * */ -PVOID ntsupFindPattern( +PVOID NTAPI ntsupFindPattern( _In_ CONST PBYTE Buffer, _In_ SIZE_T BufferSize, _In_ CONST PBYTE Pattern, @@ -3080,7 +3080,7 @@ PVOID ntsupFindPattern( * Lookup pattern in buffer with specified mask. * */ -DWORD ntsupFindPatternEx( +DWORD NTAPI ntsupFindPatternEx( _In_ PATTERN_SEARCH_PARAMS * SearchParams ) { @@ -3151,7 +3151,7 @@ DWORD ntsupFindPatternEx( * NtOpenProcess wrapper. * */ -NTSTATUS ntsupOpenProcess( +NTSTATUS NTAPI ntsupOpenProcess( _In_ HANDLE UniqueProcessId, _In_ ACCESS_MASK DesiredAccess, _Out_ PHANDLE ProcessHandle @@ -3176,22 +3176,23 @@ NTSTATUS ntsupOpenProcess( } /* -* ntsupOpenThread +* ntsupOpenThreadEx * * Purpose: * * NtOpenThread wrapper. * */ -NTSTATUS ntsupOpenThread( +NTSTATUS NTAPI ntsupOpenThreadEx( _In_ PCLIENT_ID ClientId, _In_ ACCESS_MASK DesiredAccess, + _In_ ULONG ObjectAttributes, _Out_ PHANDLE ThreadHandle ) { NTSTATUS ntStatus; HANDLE threadHandle = NULL; - OBJECT_ATTRIBUTES objectAttributes = RTL_INIT_OBJECT_ATTRIBUTES((PUNICODE_STRING)NULL, 0); + OBJECT_ATTRIBUTES objectAttributes = RTL_INIT_OBJECT_ATTRIBUTES((PUNICODE_STRING)NULL, ObjectAttributes); ntStatus = NtOpenThread( &threadHandle, @@ -3204,6 +3205,26 @@ NTSTATUS ntsupOpenThread( return ntStatus; } +/* +* ntsupOpenThread +* +* Purpose: +* +* NtOpenThread wrapper. +* +*/ +NTSTATUS NTAPI ntsupOpenThread( + _In_ PCLIENT_ID ClientId, + _In_ ACCESS_MASK DesiredAccess, + _Out_ PHANDLE ThreadHandle +) +{ + return ntsupOpenThreadEx(ClientId, + DesiredAccess, + 0, + ThreadHandle); +} + /* * ntsupCICustomKernelSignersAllowed * @@ -3212,7 +3233,7 @@ NTSTATUS ntsupOpenThread( * Return license state if present (EnterpriseG). * */ -NTSTATUS ntsupCICustomKernelSignersAllowed( +NTSTATUS NTAPI ntsupCICustomKernelSignersAllowed( _Out_ PBOOLEAN bAllowed) { NTSTATUS ntStatus; @@ -3242,7 +3263,7 @@ NTSTATUS ntsupCICustomKernelSignersAllowed( * Tests if the given token has the given privilege enabled/enabled by default. * */ -NTSTATUS ntsupPrivilegeEnabled( +NTSTATUS NTAPI ntsupPrivilegeEnabled( _In_ HANDLE ClientToken, _In_ ULONG Privilege, _Out_ LPBOOL pfResult @@ -3273,7 +3294,7 @@ NTSTATUS ntsupPrivilegeEnabled( * Set environment variable. * */ -BOOLEAN ntsupSetEnvironmentVariable( +BOOLEAN NTAPI ntsupSetEnvironmentVariable( _In_ LPCWSTR Name, _In_opt_ LPCWSTR Value ) @@ -3319,7 +3340,7 @@ BOOLEAN ntsupSetEnvironmentVariable( * Return offset to the given environment variable. * */ -LPWSTR ntsupQueryEnvironmentVariableOffset( +LPWSTR NTAPI ntsupQueryEnvironmentVariableOffset( _In_ PUNICODE_STRING Value ) { @@ -3355,7 +3376,7 @@ LPWSTR ntsupQueryEnvironmentVariableOffset( * Reimplemented ExpandEnvironmentStrings. * */ -DWORD ntsupExpandEnvironmentStrings( +DWORD NTAPI ntsupExpandEnvironmentStrings( _In_ LPCWSTR lpSrc, _Out_writes_to_opt_(nSize, return) LPWSTR lpDst, _In_ DWORD nSize @@ -3397,7 +3418,7 @@ DWORD ntsupExpandEnvironmentStrings( * Function return operation status code. * */ -NTSTATUS ntsupIsUserHasInteractiveSid( +NTSTATUS NTAPI ntsupIsUserHasInteractiveSid( _In_ HANDLE hToken, _Out_ PBOOL pbInteractiveSid) { @@ -3487,7 +3508,7 @@ NTSTATUS ntsupIsUserHasInteractiveSid( * Function return operation status code. * */ -NTSTATUS ntsupIsLocalSystem( +NTSTATUS NTAPI ntsupIsLocalSystem( _Out_ PBOOL pbResult) { BOOL bResult = FALSE; @@ -3574,7 +3595,7 @@ NTSTATUS ntsupIsLocalSystem( * Returns process elevation type. * */ -BOOL ntsupGetProcessElevationType( +BOOL NTAPI ntsupGetProcessElevationType( _In_opt_ HANDLE ProcessHandle, _Out_ TOKEN_ELEVATION_TYPE * lpType ) @@ -3615,7 +3636,7 @@ BOOL ntsupGetProcessElevationType( * Returns process elevation state. * */ -NTSTATUS ntsupIsProcessElevated( +NTSTATUS NTAPI ntsupIsProcessElevated( _In_ ULONG ProcessId, _Out_ PBOOL Elevated) { @@ -3624,7 +3645,7 @@ NTSTATUS ntsupIsProcessElevated( HANDLE processHandle = NULL, tokenHandle = NULL; TOKEN_ELEVATION tokenInfo; - if (Elevated) *Elevated = FALSE; + if (Elevated)*Elevated = FALSE; ntStatus = ntsupOpenProcess( UlongToHandle(ProcessId), @@ -3667,7 +3688,7 @@ NTSTATUS ntsupIsProcessElevated( * Flush file cache and memory standby list. * */ -VOID ntsupPurgeSystemCache( +VOID NTAPI ntsupPurgeSystemCache( VOID ) { @@ -3771,7 +3792,7 @@ VOID ntsupPurgeSystemCache( * Return system root directory silo session aware. * */ -PWSTR ntsupGetSystemRoot( +PWSTR NTAPI ntsupGetSystemRoot( VOID ) { @@ -3791,7 +3812,7 @@ PWSTR ntsupGetSystemRoot( * Reference process debug object. * */ -NTSTATUS ntsupGetProcessDebugObject( +NTSTATUS NTAPI ntsupGetProcessDebugObject( _In_ HANDLE ProcessHandle, _Out_ PHANDLE DebugObjectHandle ) @@ -3812,7 +3833,7 @@ NTSTATUS ntsupGetProcessDebugObject( * Load resource by given id (win32 FindResource, SizeofResource, LockResource). * */ -PBYTE ntsupQueryResourceData( +PBYTE NTAPI ntsupQueryResourceData( _In_ ULONG_PTR ResourceId, _In_ PVOID DllHandle, _In_ PULONG DataSize @@ -3855,7 +3876,7 @@ PBYTE ntsupQueryResourceData( * Enable/Disable Wow64 redirection. * */ -NTSTATUS ntsupEnableWow64Redirection( +NTSTATUS NTAPI ntsupEnableWow64Redirection( _In_ BOOLEAN bEnable ) { @@ -3994,7 +4015,7 @@ NTSTATUS NTAPI ntsupEnumSystemObjects( * Return TRUE if the given object exists, FALSE otherwise. * */ -BOOLEAN ntsupIsObjectExists( +BOOLEAN NTAPI ntsupIsObjectExists( _In_ LPCWSTR RootDirectory, _In_ LPCWSTR ObjectName ) @@ -4015,7 +4036,7 @@ BOOLEAN ntsupIsObjectExists( * Tests if the current user is admin with full access token. * */ -BOOLEAN ntsupUserIsFullAdmin( +BOOLEAN NTAPI ntsupUserIsFullAdmin( VOID ) { @@ -4085,7 +4106,7 @@ BOOLEAN ntsupUserIsFullAdmin( * Allocated memory must be freed by called with supHeapFree. * */ -NTSTATUS ntsupDuplicateUnicodeString( +NTSTATUS NTAPI ntsupDuplicateUnicodeString( _In_ PCUNICODE_STRING SourceString, _Out_ PUNICODE_STRING DestinationString ) @@ -4144,7 +4165,7 @@ NTSTATUS ntsupDuplicateUnicodeString( * Allocated memory must be freed by called with supHeapFree. * */ -NTSTATUS ntsupDuplicateAnsiString( +NTSTATUS NTAPI ntsupDuplicateAnsiString( _In_ PCANSI_STRING SourceString, _Out_ PANSI_STRING DestinationString ) @@ -4203,7 +4224,7 @@ NTSTATUS ntsupDuplicateAnsiString( * Allocated string must be freed by caller with RtlFreeUnicodeString. * */ -NTSTATUS ntsupQueryProcessCommandLine( +NTSTATUS NTAPI ntsupQueryProcessCommandLine( _In_ HANDLE ProcessHandle, _Out_ PUNICODE_STRING CommandLine, _In_ PNTSUPMEMALLOC AllocMem, @@ -4276,7 +4297,7 @@ NTSTATUS ntsupQueryProcessCommandLine( * executable section. * */ -NTSTATUS ntsupHashImageSections( +NTSTATUS NTAPI ntsupHashImageSections( _In_ PVOID ImageBase, _In_ SIZE_T ImageSize, // Size of image mapping _Out_writes_bytes_(HashBufferSize) PBYTE HashBuffer, @@ -4438,4 +4459,53 @@ NTSTATUS ntsupHashImageSections( return STATUS_SUCCESS; } +/* +* ntsupQueryProcessDebugInformation +* +* Purpose: +* +* Allocate process debug information buffer. +* +*/ +PRTL_DEBUG_INFORMATION NTAPI ntsupQueryProcessDebugInformation( + _In_ HANDLE ProcessId, + _In_ ULONG Flags +) +{ + PRTL_DEBUG_INFORMATION debugBuffer; + NTSTATUS ntStatus; + + debugBuffer = RtlCreateQueryDebugBuffer(0, FALSE); + if (debugBuffer == NULL) + return NULL; + + ntStatus = RtlQueryProcessDebugInformation( + ProcessId, + Flags, + debugBuffer); + + if (!NT_SUCCESS(ntStatus)) { + RtlDestroyQueryDebugBuffer(debugBuffer); + return NULL; + } + + return debugBuffer; +} + +/* +* ntsupFreeProcessDebugInformation +* +* Purpose: +* +* Free process debug information buffer. +* +*/ +VOID NTAPI ntsupFreeProcessDebugInformation( + _In_opt_ PRTL_DEBUG_INFORMATION DebugInformation +) +{ + if (DebugInformation != NULL) + RtlDestroyQueryDebugBuffer(DebugInformation); +} + #pragma warning(pop) diff --git a/Source/Shared/ntos/ntsup.h b/Source/Shared/ntos/ntsup.h index fbf25e2..038a9ba 100644 --- a/Source/Shared/ntos/ntsup.h +++ b/Source/Shared/ntos/ntsup.h @@ -4,9 +4,9 @@ * * TITLE: NTSUP.H * -* VERSION: 2.32 +* VERSION: 2.33 * -* DATE: 28 Jul 2026 +* DATE: 12 Aug 2026 * * Common header file for the NT API support functions and definitions. * @@ -54,225 +54,225 @@ extern "C" { #endif #endif -typedef NTSTATUS(NTAPI* PFN_NTQUERYROUTINE)( - _In_opt_ HANDLE ObjectHandle, - _In_ DWORD InformationClass, - _Out_writes_bytes_(ObjectInformationLength) PVOID ObjectInformation, - _In_ ULONG ObjectInformationLength, - _Out_opt_ PULONG ReturnLength); + typedef NTSTATUS(NTAPI* PFN_NTQUERYROUTINE)( + _In_opt_ HANDLE ObjectHandle, + _In_ DWORD InformationClass, + _Out_writes_bytes_(ObjectInformationLength) PVOID ObjectInformation, + _In_ ULONG ObjectInformationLength, + _Out_opt_ PULONG ReturnLength); -typedef PVOID(CALLBACK* PNTSUPMEMALLOC)( - _In_ SIZE_T NumberOfBytes); + typedef PVOID(CALLBACK* PNTSUPMEMALLOC)( + _In_ SIZE_T NumberOfBytes); -typedef BOOL(CALLBACK* PNTSUPMEMFREE)( - _In_ PVOID Memory); + typedef BOOL(CALLBACK* PNTSUPMEMFREE)( + _In_ PVOID Memory); #define NTSUPHASH_SHA256_SIZE 32 -#define MAX_NTSUP_BUFFER_SIZE (512 * 1024 * 1024) //512MB +#define MAX_NTSUP_BUFFER_SIZE (512* 1024* 1024) //512MB #define MAX_NTSUP_ENV_SCAN 4096 -#define MAX_NTSUP_PROCESS_ENUM_ITER (1024 * 1024) +#define MAX_NTSUP_PROCESS_ENUM_ITER (1024* 1024) #define MAX_NTSUP_WRITE_CHUNK 0x7FFFFFFF -typedef struct _OBJSCANPARAM { - PCWSTR Buffer; - ULONG BufferSize; -} OBJSCANPARAM, * POBJSCANPARAM; - -typedef NTSTATUS(NTAPI* PENUMOBJECTSCALLBACK)( - _In_ POBJECT_DIRECTORY_INFORMATION Entry, - _In_opt_ PVOID CallbackParam); - -typedef BOOL(CALLBACK* pfnPatternSearchCallback)( - _In_ PBYTE Buffer, - _In_ ULONG PatternSize, - _In_opt_ PVOID CallbackContext - ); - -typedef struct _PATTERN_SEARCH_PARAMS { - PBYTE Buffer; - DWORD BufferSize; - PBYTE Pattern; - DWORD PatternSize; - PBYTE Mask; - pfnPatternSearchCallback Callback; - PVOID CallbackContext; -} PATTERN_SEARCH_PARAMS, * PPATTERN_SEARCH_PARAMS; - -typedef enum _NTSUP_IMAGE_TYPE { - ImageTypeRaw, // Raw file mapping (CreateFileMapping) - ImageTypeLoaded // Loaded module (PEB/LdrEntry) -} NTSUP_IMAGE_TYPE; - -typedef struct _NTSUP_SHA256_CTX { - ULONG State[8]; - ULONG64 BitCount; - UCHAR Buffer[64]; -} NTSUP_SHA256_CTX, * PNTSUP_SHA256_CTX; - -VOID ntsupSha256Init( - _Out_ PNTSUP_SHA256_CTX Ctx); - -VOID ntsupSha256Update( - _Inout_ PNTSUP_SHA256_CTX Ctx, - _In_reads_bytes_(Length) const UCHAR* Data, - _In_ SIZE_T Length); - -VOID ntsupSha256Final( - _Inout_ PNTSUP_SHA256_CTX Ctx, - _Out_writes_bytes_all_(32) UCHAR Digest[32]); - -// -// Ronova requires get rid of minirtl. -// -FORCEINLINE INT ntsupHexDigitToInt( - _In_ UINT ch -) -{ - if ((ch >= '0') && (ch <= '9')) - return (INT)(ch - '0'); - - ch = (UINT)((ch >= 'A' && ch <= 'Z') ? (ch + ('a' - 'A')) : ch); - - if ((ch >= 'a') && (ch <= 'f')) - return (INT)(ch - 'a' + 10); - - return -1; -} - -FORCEINLINE BOOLEAN ntsupIsDigitA( - _In_ CHAR Ch -) -{ - return (BOOLEAN)(Ch >= '0' && Ch <= '9'); -} - -FORCEINLINE BOOLEAN ntsupIsDigitW( - _In_ WCHAR Ch -) -{ - return (BOOLEAN)(Ch >= L'0' && Ch <= L'9'); -} - -// -// Minirtl section START -// -FORCEINLINE CHAR ntsupLowerCharA( - _In_ CHAR c -) -{ - if ((c >= 'A') && (c <= 'Z')) - return c + 0x20; - else - return c; -} - -FORCEINLINE WCHAR ntsupLowerCharW( - _In_ WCHAR c -) -{ - if ((c >= L'A') && (c <= L'Z')) - return c + 0x20; - else - return c; -} - -LPWSTR ntsupStrChrW( - _In_z_ LPCWSTR String, - _In_ WCHAR Character); -LPSTR ntsupStrChrA( - _In_z_ LPCSTR String, - _In_ CHAR Character); - -SIZE_T ntsupStrLenA( - _In_opt_ LPCSTR String); -SIZE_T ntsupStrLenW( - _In_opt_ LPCWSTR String); - -INT ntsupStrCmpA( - _In_opt_ LPCSTR String1, - _In_opt_ LPCSTR String2); -INT ntsupStrCmpW( - _In_opt_ LPCWSTR String1, - _In_opt_ LPCWSTR String2); - -INT ntsupStrCmpIA( - _In_opt_ LPCSTR String1, - _In_opt_ LPCSTR String2); -INT ntsupStrCmpIW( - _In_opt_ LPCWSTR String1, - _In_opt_ LPCWSTR String2); - -LPSTR ntsupStrCopyA( - _Out_writes_z_(_String_length_(Source) + 1) LPSTR Destination, - _In_z_ LPCSTR Source); -LPWSTR ntsupStrCopyW( - _Out_writes_z_(_String_length_(Source) + 1) LPWSTR Destination, - _In_z_ LPCWSTR Source); - -LPSTR ntsupStrNCopyA( - _Out_writes_z_(DestinationCount) LPSTR Destination, - _In_ SIZE_T DestinationCount, - _In_reads_(SourceCount) LPCSTR Source, - _In_ SIZE_T SourceCount); -LPWSTR ntsupStrNCopyW( - _Out_writes_z_(DestinationCount) LPWSTR Destination, - _In_ SIZE_T DestinationCount, - _In_reads_(SourceCount) LPCWSTR Source, - _In_ SIZE_T SourceCount); - -INT ntsupStrNCmpA( - _In_opt_ LPCSTR String1, - _In_opt_ LPCSTR String2, - _In_ SIZE_T Count); -INT ntsupStrNCmpW( - _In_opt_ LPCWSTR String1, - _In_opt_ LPCWSTR String2, - _In_ SIZE_T Count); - -LPCSTR ntsupStrStrIA( - _In_ LPCSTR String, - _In_ LPCSTR SubString); -LPCWSTR ntsupStrStrIW( - _In_ LPCWSTR String, - _In_ LPCWSTR SubString); - -LPSTR ntsupStrCatA( - _Inout_ LPSTR Destination, - _In_ LPCSTR Source); -LPWSTR ntsupStrCatW( - _Inout_ LPWSTR Destination, - _In_ LPCWSTR Source); - -LPSTR ntsupStrCatExA( - _Inout_updates_z_(DestinationCount) LPSTR Destination, - _In_ SIZE_T DestinationCount, - _In_ LPCSTR Source); -LPWSTR ntsupStrCatExW( - _Inout_updates_z_(DestinationCount) LPWSTR Destination, - _In_ SIZE_T DestinationCount, - _In_ LPCWSTR Source); - -BOOL ntsupStrToUInt64A( - _In_ LPCSTR String, - _Out_ PULONGLONG Value); -BOOL ntsupStrToUInt64W( - _In_ LPCWSTR String, - _Out_ PULONGLONG Value); - -SIZE_T ntsupUInt64ToStrW( - _In_ ULONGLONG Value, - _Out_writes_z_(BufferCount) LPWSTR Buffer, - _In_ SIZE_T BufferCount); -SIZE_T ntsupUInt64ToStrA( - _In_ ULONGLONG Value, - _Out_writes_z_(BufferCount) LPSTR Buffer, - _In_ SIZE_T BufferCount); - -ULONGLONG ntsupHexToUInt64A( - _In_opt_ LPCSTR String); -ULONGLONG ntsupHexToUInt64W( - _In_opt_ LPCWSTR String); + typedef struct _OBJSCANPARAM { + PCWSTR Buffer; + ULONG BufferSize; + } OBJSCANPARAM, * POBJSCANPARAM; + + typedef NTSTATUS(NTAPI* PENUMOBJECTSCALLBACK)( + _In_ POBJECT_DIRECTORY_INFORMATION Entry, + _In_opt_ PVOID CallbackParam); + + typedef BOOL(CALLBACK* pfnPatternSearchCallback)( + _In_ PBYTE Buffer, + _In_ ULONG PatternSize, + _In_opt_ PVOID CallbackContext + ); + + typedef struct _PATTERN_SEARCH_PARAMS { + PBYTE Buffer; + DWORD BufferSize; + PBYTE Pattern; + DWORD PatternSize; + PBYTE Mask; + pfnPatternSearchCallback Callback; + PVOID CallbackContext; + } PATTERN_SEARCH_PARAMS, * PPATTERN_SEARCH_PARAMS; + + typedef enum _NTSUP_IMAGE_TYPE { + ImageTypeRaw, // Raw file mapping (CreateFileMapping) + ImageTypeLoaded // Loaded module (PEB/LdrEntry) + } NTSUP_IMAGE_TYPE; + + typedef struct _NTSUP_SHA256_CTX { + ULONG State[8]; + ULONG64 BitCount; + UCHAR Buffer[64]; + } NTSUP_SHA256_CTX, * PNTSUP_SHA256_CTX; + + VOID ntsupSha256Init( + _Out_ PNTSUP_SHA256_CTX Ctx); + + VOID ntsupSha256Update( + _Inout_ PNTSUP_SHA256_CTX Ctx, + _In_reads_bytes_(Length) const UCHAR* Data, + _In_ SIZE_T Length); + + VOID ntsupSha256Final( + _Inout_ PNTSUP_SHA256_CTX Ctx, + _Out_writes_bytes_all_(32) UCHAR Digest[32]); + + // + // Ronova requires get rid of minirtl. + // + FORCEINLINE INT ntsupHexDigitToInt( + _In_ UINT ch + ) + { + if ((ch >= '0') && (ch <= '9')) + return (INT)(ch - '0'); + + ch = (UINT)((ch >= 'A' && ch <= 'Z') ? (ch + ('a' - 'A')) : ch); + + if ((ch >= 'a') && (ch <= 'f')) + return (INT)(ch - 'a' + 10); + + return -1; + } + + FORCEINLINE BOOLEAN ntsupIsDigitA( + _In_ CHAR Ch + ) + { + return (BOOLEAN)(Ch >= '0' && Ch <= '9'); + } + + FORCEINLINE BOOLEAN ntsupIsDigitW( + _In_ WCHAR Ch + ) + { + return (BOOLEAN)(Ch >= L'0' && Ch <= L'9'); + } + + // + // Minirtl section START + // + FORCEINLINE CHAR ntsupLowerCharA( + _In_ CHAR c + ) + { + if ((c >= 'A') && (c <= 'Z')) + return c + 0x20; + else + return c; + } + + FORCEINLINE WCHAR ntsupLowerCharW( + _In_ WCHAR c + ) + { + if ((c >= L'A') && (c <= L'Z')) + return c + 0x20; + else + return c; + } + + LPWSTR ntsupStrChrW( + _In_z_ LPCWSTR String, + _In_ WCHAR Character); + LPSTR ntsupStrChrA( + _In_z_ LPCSTR String, + _In_ CHAR Character); + + SIZE_T ntsupStrLenA( + _In_opt_ LPCSTR String); + SIZE_T ntsupStrLenW( + _In_opt_ LPCWSTR String); + + INT ntsupStrCmpA( + _In_opt_ LPCSTR String1, + _In_opt_ LPCSTR String2); + INT ntsupStrCmpW( + _In_opt_ LPCWSTR String1, + _In_opt_ LPCWSTR String2); + + INT ntsupStrCmpIA( + _In_opt_ LPCSTR String1, + _In_opt_ LPCSTR String2); + INT ntsupStrCmpIW( + _In_opt_ LPCWSTR String1, + _In_opt_ LPCWSTR String2); + + LPSTR ntsupStrCopyA( + _Out_writes_z_(_String_length_(Source) + 1) LPSTR Destination, + _In_z_ LPCSTR Source); + LPWSTR ntsupStrCopyW( + _Out_writes_z_(_String_length_(Source) + 1) LPWSTR Destination, + _In_z_ LPCWSTR Source); + + LPSTR ntsupStrNCopyA( + _Out_writes_z_(DestinationCount) LPSTR Destination, + _In_ SIZE_T DestinationCount, + _In_reads_(SourceCount) LPCSTR Source, + _In_ SIZE_T SourceCount); + LPWSTR ntsupStrNCopyW( + _Out_writes_z_(DestinationCount) LPWSTR Destination, + _In_ SIZE_T DestinationCount, + _In_reads_(SourceCount) LPCWSTR Source, + _In_ SIZE_T SourceCount); + + INT ntsupStrNCmpA( + _In_opt_ LPCSTR String1, + _In_opt_ LPCSTR String2, + _In_ SIZE_T Count); + INT ntsupStrNCmpW( + _In_opt_ LPCWSTR String1, + _In_opt_ LPCWSTR String2, + _In_ SIZE_T Count); + + LPCSTR ntsupStrStrIA( + _In_ LPCSTR String, + _In_ LPCSTR SubString); + LPCWSTR ntsupStrStrIW( + _In_ LPCWSTR String, + _In_ LPCWSTR SubString); + + LPSTR ntsupStrCatA( + _Inout_ LPSTR Destination, + _In_ LPCSTR Source); + LPWSTR ntsupStrCatW( + _Inout_ LPWSTR Destination, + _In_ LPCWSTR Source); + + LPSTR ntsupStrCatExA( + _Inout_updates_z_(DestinationCount) LPSTR Destination, + _In_ SIZE_T DestinationCount, + _In_ LPCSTR Source); + LPWSTR ntsupStrCatExW( + _Inout_updates_z_(DestinationCount) LPWSTR Destination, + _In_ SIZE_T DestinationCount, + _In_ LPCWSTR Source); + + BOOL ntsupStrToUInt64A( + _In_ LPCSTR String, + _Out_ PULONGLONG Value); + BOOL ntsupStrToUInt64W( + _In_ LPCWSTR String, + _Out_ PULONGLONG Value); + + SIZE_T ntsupUInt64ToStrW( + _In_ ULONGLONG Value, + _Out_writes_z_(BufferCount) LPWSTR Buffer, + _In_ SIZE_T BufferCount); + SIZE_T ntsupUInt64ToStrA( + _In_ ULONGLONG Value, + _Out_writes_z_(BufferCount) LPSTR Buffer, + _In_ SIZE_T BufferCount); + + ULONGLONG ntsupHexToUInt64A( + _In_opt_ LPCSTR String); + ULONGLONG ntsupHexToUInt64W( + _In_opt_ LPCWSTR String); #ifdef _UNICODE #define ntsupLowerChar ntsupLowerCharW @@ -306,335 +306,348 @@ ULONGLONG ntsupHexToUInt64W( #define ntsupHexToUInt64 ntsupHexToUInt64A #endif -// -// Minirtl section END -// + // + // Minirtl section END + // + + PVOID NTAPI ntsupHeapAlloc( + _In_ SIZE_T Size); + + PVOID NTAPI ntsupHeapReAlloc( + _In_ PVOID BaseAddress, + _In_ SIZE_T Size); -PVOID ntsupHeapAlloc( - _In_ SIZE_T Size); + BOOL NTAPI ntsupHeapFree( + _In_ PVOID BaseAddress); -PVOID ntsupHeapReAlloc( - _In_ PVOID BaseAddress, - _In_ SIZE_T Size); + SIZE_T NTAPI ntsupHeapSize( + _In_ PVOID BaseAddress); -BOOL ntsupHeapFree( - _In_ PVOID BaseAddress); + BOOL NTAPI ntsupHeapValidate( + _In_ PVOID BaseAddress); -SIZE_T ntsupHeapSize( - _In_ PVOID BaseAddress); + SIZE_T NTAPI ntsupHeapCompact( + VOID); -BOOL ntsupHeapValidate( - _In_ PVOID BaseAddress); + BOOL NTAPI ntsupHeapLock( + VOID); -SIZE_T ntsupHeapCompact( - VOID); + BOOL NTAPI ntsupHeapUnlock( + VOID); -BOOL ntsupHeapLock( - VOID); + BOOLEAN NTAPI ntsupIsAddressValid( + _In_ PVOID Address, + _In_ SIZE_T Size); -BOOL ntsupHeapUnlock( - VOID); + PVOID NTAPI ntsupVirtualAllocEx( + _In_ SIZE_T Size, + _In_ ULONG AllocationType, + _In_ ULONG Protect); -BOOLEAN ntsupIsAddressValid( - _In_ PVOID Address, - _In_ SIZE_T Size); + PVOID NTAPI ntsupVirtualAlloc( + _In_ SIZE_T Size); -PVOID ntsupVirtualAllocEx( - _In_ SIZE_T Size, - _In_ ULONG AllocationType, - _In_ ULONG Protect); + BOOL NTAPI ntsupVirtualFree( + _In_ PVOID Memory); -PVOID ntsupVirtualAlloc( - _In_ SIZE_T Size); + BOOL NTAPI ntsupVirtualLock( + _In_ LPVOID lpAddress, + _In_ SIZE_T dwSize); + + BOOL NTAPI ntsupVirtualUnlock( + _In_ LPVOID lpAddress, + _In_ SIZE_T dwSize); + + SIZE_T NTAPI ntsupWriteBufferToFile( + _In_ PCWSTR FileName, + _In_ PVOID Buffer, + _In_ SIZE_T Size, + _In_ BOOL Flush, + _In_ BOOL Append, + _Out_opt_ NTSTATUS* Result); + + PVOID NTAPI ntsupGetModuleEntryByAddress( + _In_ PRTL_PROCESS_MODULES ModulesList, + _In_ PVOID Address); + + PVOID NTAPI ntsupFindModuleEntryByName( + _In_ PRTL_PROCESS_MODULES ModulesList, + _In_ LPCSTR ModuleName); + + PVOID NTAPI ntsupFindModuleEntryByName_U( + _In_ PRTL_PROCESS_MODULES ModulesList, + _In_ LPCWSTR ModuleName); + + BOOL NTAPI ntsupFindModuleEntryByAddress( + _In_ PRTL_PROCESS_MODULES ModulesList, + _In_ PVOID Address, + _Out_ PULONG ModuleIndex); + + PVOID NTAPI ntsupFindModuleNameByAddress( + _In_ PRTL_PROCESS_MODULES ModulesList, + _In_ PVOID Address, + _Inout_ LPWSTR Buffer, + _In_ DWORD ccBuffer); + + NTSTATUS NTAPI ntsupConvertToUnicode( + _In_ LPCSTR AnsiString, + _Inout_ PUNICODE_STRING UnicodeString); + + NTSTATUS NTAPI ntsupConvertToAnsi( + _In_ LPCWSTR UnicodeString, + _Inout_ PANSI_STRING AnsiString); + + NTSTATUS NTAPI ntsupSetPrivilege( + _In_ HANDLE TokenHandle, + _In_ DWORD Privilege, + _In_ BOOLEAN Enable, + _Out_opt_ PTOKEN_PRIVILEGES PreviousState, + _Out_opt_ PULONG ReturnLength); + + BOOLEAN NTAPI ntsupEnablePrivilege( + _In_ DWORD Privilege, + _In_ BOOLEAN Enable); + + HANDLE NTAPI ntsupGetCurrentProcessToken( + VOID); + + ULONG_PTR NTAPI ntsupQuerySystemRangeStart( + VOID); + + BOOLEAN NTAPI ntsupQueryUserModeAccessibleRange( + _Out_ PULONG_PTR MinimumUserModeAddress, + _Out_ PULONG_PTR MaximumUserModeAddress); + + BOOL NTAPI ntsupIsProcess32bit( + _In_ HANDLE hProcess); + + PVOID NTAPI ntsupGetLoadedModulesListEx( + _In_ BOOL ExtendedOutput, + _Out_opt_ PULONG ReturnLength, + _In_ PNTSUPMEMALLOC AllocMem, + _In_ PNTSUPMEMFREE FreeMem); + + PVOID NTAPI ntsupGetLoadedModulesList( + _Out_opt_ PULONG ReturnLength); + + PVOID NTAPI ntsupGetLoadedModulesList2( + _Out_opt_ PULONG ReturnLength); + + PVOID NTAPI ntsupGetSystemInfoEx( + _In_ SYSTEM_INFORMATION_CLASS SystemInformationClass, + _Out_opt_ PULONG ReturnLength, + _In_ PNTSUPMEMALLOC AllocMem, + _In_ PNTSUPMEMFREE FreeMem); + + PVOID NTAPI ntsupGetSystemInfo( + _In_ SYSTEM_INFORMATION_CLASS SystemInformationClass, + _Out_opt_ PULONG ReturnLength); + + NTSTATUS NTAPI ntsupEnumSystemObjects( + _In_opt_ LPCWSTR RootDirectory, + _In_opt_ HANDLE RootDirectoryHandle, + _In_ PENUMOBJECTSCALLBACK CallbackProc, + _In_opt_ PVOID CallbackParam); + + BOOL NTAPI ntsupResolveSymbolicLink( + _In_opt_ HANDLE RootDirectoryHandle, + _In_ PUNICODE_STRING LinkName, + _Inout_ LPWSTR Buffer, + _In_ DWORD cbBuffer); + + BOOL NTAPI ntsupQueryThreadWin32StartAddress( + _In_ HANDLE ThreadHandle, + _Out_opt_ PULONG_PTR Win32StartAddress); + + NTSTATUS NTAPI ntsupQueryProcessCommandLine( + _In_ HANDLE ProcessHandle, + _Out_ PUNICODE_STRING CommandLine, + _In_ PNTSUPMEMALLOC AllocMem, + _In_ PNTSUPMEMFREE FreeMem); + + _Success_(return) + NTSTATUS NTAPI ntsupOpenDirectoryEx( + _Out_ PHANDLE DirectoryHandle, + _In_opt_ HANDLE RootDirectoryHandle, + _In_ PUNICODE_STRING DirectoryName, + _In_ ACCESS_MASK DesiredAccess); + + NTSTATUS NTAPI ntsupOpenDirectory( + _Out_ PHANDLE DirectoryHandle, + _In_opt_ HANDLE RootDirectoryHandle, + _In_ LPCWSTR DirectoryName, + _In_ ACCESS_MASK DesiredAccess); + + BOOL NTAPI ntsupQueryProcessName( + _In_ ULONG_PTR dwProcessId, + _In_ PVOID ProcessList, + _Inout_ LPWSTR Buffer, + _In_ DWORD ccBuffer); + + BOOL NTAPI ntsupQueryProcessEntryById( + _In_ HANDLE UniqueProcessId, + _In_ PVOID ProcessList, + _Out_ PSYSTEM_PROCESS_INFORMATION* Entry); + + NTSTATUS NTAPI ntsupQueryProcessImageFileNameByProcessId( + _In_ HANDLE UniqueProcessId, + _Out_ PUNICODE_STRING ProcessImageFileName, + _In_ PNTSUPMEMALLOC AllocMem, + _In_ PNTSUPMEMFREE FreeMem); + + NTSTATUS NTAPI ntsupQuerySystemObjectInformationVariableSize( + _In_ PFN_NTQUERYROUTINE QueryRoutine, + _In_opt_ HANDLE ObjectHandle, + _In_ DWORD InformationClass, + _Out_ PVOID* Buffer, + _Out_opt_ PULONG ReturnLength, + _In_ PNTSUPMEMALLOC AllocMem, + _In_ PNTSUPMEMFREE FreeMem); + + NTSTATUS NTAPI ntsupQuerySystemObjectInformationVariableSizeEx( + _In_ PFN_NTQUERYROUTINE QueryRoutine, + _In_opt_ HANDLE ObjectHandle, + _In_ DWORD InformationClass, + _Out_ PVOID* Buffer, + _Out_opt_ PULONG ReturnLength, + _In_ ULONG InitialBufferSize, + _In_ PNTSUPMEMALLOC AllocMem, + _In_ PNTSUPMEMFREE FreeMem); + + BOOLEAN NTAPI ntsupQueryVsmProtectionInformation( + _Out_ PBOOLEAN pbDmaProtectionsAvailable, + _Out_ PBOOLEAN pbDmaProtectionsInUse, + _Out_ PBOOLEAN pbHardwareMbecAvailable, + _Out_ PBOOLEAN pbApicVirtualizationAvailable); + + BOOLEAN NTAPI ntsupQueryVBSState( + _Out_ PBOOLEAN pbVBSRunning, + _Out_ PBOOLEAN pbHVCIEnabled, + _Out_ PBOOLEAN pbHVCIStrictMode); + + PVOID NTAPI ntsupLookupImageSectionByNameEx( + _In_ CHAR* SectionName, + _In_ ULONG SectionNameLength, + _In_ PVOID DllBase, + _In_ SIZE_T ImageSize, + _Out_opt_ PULONG SectionSize); + + PVOID NTAPI ntsupLookupImageSectionByName( + _In_ CHAR* SectionName, + _In_ ULONG SectionNameLength, + _In_ PVOID DllBase, + _Out_ PULONG SectionSize); + + PVOID NTAPI ntsupFindPattern( + _In_ CONST PBYTE Buffer, + _In_ SIZE_T BufferSize, + _In_ CONST PBYTE Pattern, + _In_ SIZE_T PatternSize); + + DWORD NTAPI ntsupFindPatternEx( + _In_ PATTERN_SEARCH_PARAMS* SearchParams); + + NTSTATUS NTAPI ntsupOpenProcess( + _In_ HANDLE UniqueProcessId, + _In_ ACCESS_MASK DesiredAccess, + _Out_ PHANDLE ProcessHandle); + + NTSTATUS NTAPI ntsupOpenThreadEx( + _In_ PCLIENT_ID ClientId, + _In_ ACCESS_MASK DesiredAccess, + _In_ ULONG ObjectAttributes, + _Out_ PHANDLE ThreadHandle); + + NTSTATUS NTAPI ntsupOpenThread( + _In_ PCLIENT_ID ClientId, + _In_ ACCESS_MASK DesiredAccess, + _Out_ PHANDLE ThreadHandle); + + NTSTATUS NTAPI ntsupCICustomKernelSignersAllowed( + _Out_ PBOOLEAN bAllowed); + + NTSTATUS NTAPI ntsupPrivilegeEnabled( + _In_ HANDLE ClientToken, + _In_ ULONG Privilege, + _Out_ LPBOOL pfResult); + + LPWSTR NTAPI ntsupQueryEnvironmentVariableOffset( + _In_ PUNICODE_STRING Value); + + BOOLEAN NTAPI ntsupSetEnvironmentVariable( + _In_ LPCWSTR Name, + _In_opt_ LPCWSTR Value); + + DWORD NTAPI ntsupExpandEnvironmentStrings( + _In_ LPCWSTR lpSrc, + _Out_writes_to_opt_(nSize, return) LPWSTR lpDst, + _In_ DWORD nSize); + + NTSTATUS NTAPI ntsupIsLocalSystem( + _Out_ PBOOL pbResult); + + NTSTATUS NTAPI ntsupIsUserHasInteractiveSid( + _In_ HANDLE hToken, + _Out_ PBOOL pbInteractiveSid); + + BOOL NTAPI ntsupGetProcessElevationType( + _In_opt_ HANDLE ProcessHandle, + _Out_ TOKEN_ELEVATION_TYPE* lpType); + + NTSTATUS NTAPI ntsupIsProcessElevated( + _In_ ULONG ProcessId, + _Out_ PBOOL Elevated); + + VOID NTAPI ntsupPurgeSystemCache( + VOID); + + PWSTR NTAPI ntsupGetSystemRoot( + VOID); + + NTSTATUS NTAPI ntsupGetProcessDebugObject( + _In_ HANDLE ProcessHandle, + _Out_ PHANDLE DebugObjectHandle); + + PBYTE NTAPI ntsupQueryResourceData( + _In_ ULONG_PTR ResourceId, + _In_ PVOID DllHandle, + _In_ PULONG DataSize); + + NTSTATUS NTAPI ntsupEnableWow64Redirection( + _In_ BOOLEAN bEnable); + + BOOLEAN NTAPI ntsupIsKdEnabled( + _Out_opt_ PBOOLEAN DebuggerAllowed, + _Out_opt_ PBOOLEAN DebuggerNotPresent); + + BOOLEAN NTAPI ntsupIsObjectExists( + _In_ LPCWSTR RootDirectory, + _In_ LPCWSTR ObjectName); + + BOOLEAN NTAPI ntsupUserIsFullAdmin( + VOID); + + NTSTATUS NTAPI ntsupDuplicateUnicodeString( + _In_ PCUNICODE_STRING SourceString, + _Out_ PUNICODE_STRING DestinationString); + + NTSTATUS NTAPI ntsupDuplicateAnsiString( + _In_ PCANSI_STRING SourceString, + _Out_ PANSI_STRING DestinationString); + + NTSTATUS NTAPI ntsupHashImageSections( + _In_ PVOID ImageBase, + _In_ SIZE_T ImageSize, + _Out_writes_bytes_(HashBufferSize) PBYTE HashBuffer, + _In_ SIZE_T HashBufferSize, + _In_ NTSUP_IMAGE_TYPE ImageType); -BOOL ntsupVirtualFree( - _In_ PVOID Memory); + PRTL_DEBUG_INFORMATION NTAPI ntsupQueryProcessDebugInformation( + _In_ HANDLE ProcessId, + _In_ ULONG Flags); -BOOL ntsupVirtualLock( - _In_ LPVOID lpAddress, - _In_ SIZE_T dwSize); - -BOOL ntsupVirtualUnlock( - _In_ LPVOID lpAddress, - _In_ SIZE_T dwSize); - -SIZE_T ntsupWriteBufferToFile( - _In_ PCWSTR FileName, - _In_ PVOID Buffer, - _In_ SIZE_T Size, - _In_ BOOL Flush, - _In_ BOOL Append, - _Out_opt_ NTSTATUS* Result); - -PVOID ntsupGetModuleEntryByAddress( - _In_ PRTL_PROCESS_MODULES ModulesList, - _In_ PVOID Address); - -PVOID ntsupFindModuleEntryByName( - _In_ PRTL_PROCESS_MODULES ModulesList, - _In_ LPCSTR ModuleName); - -PVOID ntsupFindModuleEntryByName_U( - _In_ PRTL_PROCESS_MODULES ModulesList, - _In_ LPCWSTR ModuleName); - -BOOL ntsupFindModuleEntryByAddress( - _In_ PRTL_PROCESS_MODULES ModulesList, - _In_ PVOID Address, - _Out_ PULONG ModuleIndex); - -PVOID ntsupFindModuleNameByAddress( - _In_ PRTL_PROCESS_MODULES ModulesList, - _In_ PVOID Address, - _Inout_ LPWSTR Buffer, - _In_ DWORD ccBuffer); - -NTSTATUS ntsupConvertToUnicode( - _In_ LPCSTR AnsiString, - _Inout_ PUNICODE_STRING UnicodeString); - -NTSTATUS ntsupConvertToAnsi( - _In_ LPCWSTR UnicodeString, - _Inout_ PANSI_STRING AnsiString); - -NTSTATUS ntsupSetPrivilege( - _In_ HANDLE TokenHandle, - _In_ DWORD Privilege, - _In_ BOOLEAN Enable, - _Out_opt_ PTOKEN_PRIVILEGES PreviousState, - _Out_opt_ PULONG ReturnLength); - -BOOLEAN ntsupEnablePrivilege( - _In_ DWORD Privilege, - _In_ BOOLEAN Enable); - -HANDLE ntsupGetCurrentProcessToken( - VOID); - -ULONG_PTR ntsupQuerySystemRangeStart( - VOID); - -BOOLEAN ntsupQueryUserModeAccessibleRange( - _Out_ PULONG_PTR MinimumUserModeAddress, - _Out_ PULONG_PTR MaximumUserModeAddress); - -BOOL ntsupIsProcess32bit( - _In_ HANDLE hProcess); - -PVOID ntsupGetLoadedModulesListEx( - _In_ BOOL ExtendedOutput, - _Out_opt_ PULONG ReturnLength, - _In_ PNTSUPMEMALLOC AllocMem, - _In_ PNTSUPMEMFREE FreeMem); - -PVOID ntsupGetLoadedModulesList( - _Out_opt_ PULONG ReturnLength); - -PVOID ntsupGetLoadedModulesList2( - _Out_opt_ PULONG ReturnLength); - -PVOID ntsupGetSystemInfoEx( - _In_ SYSTEM_INFORMATION_CLASS SystemInformationClass, - _Out_opt_ PULONG ReturnLength, - _In_ PNTSUPMEMALLOC AllocMem, - _In_ PNTSUPMEMFREE FreeMem); - -PVOID ntsupGetSystemInfo( - _In_ SYSTEM_INFORMATION_CLASS SystemInformationClass, - _Out_opt_ PULONG ReturnLength); - -NTSTATUS NTAPI ntsupEnumSystemObjects( - _In_opt_ LPCWSTR RootDirectory, - _In_opt_ HANDLE RootDirectoryHandle, - _In_ PENUMOBJECTSCALLBACK CallbackProc, - _In_opt_ PVOID CallbackParam); - -BOOL ntsupResolveSymbolicLink( - _In_opt_ HANDLE RootDirectoryHandle, - _In_ PUNICODE_STRING LinkName, - _Inout_ LPWSTR Buffer, - _In_ DWORD cbBuffer); - -BOOL ntsupQueryThreadWin32StartAddress( - _In_ HANDLE ThreadHandle, - _Out_opt_ PULONG_PTR Win32StartAddress); - -NTSTATUS ntsupQueryProcessCommandLine( - _In_ HANDLE ProcessHandle, - _Out_ PUNICODE_STRING CommandLine, - _In_ PNTSUPMEMALLOC AllocMem, - _In_ PNTSUPMEMFREE FreeMem); - -_Success_(return) -NTSTATUS ntsupOpenDirectoryEx( - _Out_ PHANDLE DirectoryHandle, - _In_opt_ HANDLE RootDirectoryHandle, - _In_ PUNICODE_STRING DirectoryName, - _In_ ACCESS_MASK DesiredAccess); - -NTSTATUS ntsupOpenDirectory( - _Out_ PHANDLE DirectoryHandle, - _In_opt_ HANDLE RootDirectoryHandle, - _In_ LPCWSTR DirectoryName, - _In_ ACCESS_MASK DesiredAccess); - -BOOL ntsupQueryProcessName( - _In_ ULONG_PTR dwProcessId, - _In_ PVOID ProcessList, - _Inout_ LPWSTR Buffer, - _In_ DWORD ccBuffer); - -BOOL ntsupQueryProcessEntryById( - _In_ HANDLE UniqueProcessId, - _In_ PVOID ProcessList, - _Out_ PSYSTEM_PROCESS_INFORMATION* Entry); - -NTSTATUS ntsupQueryProcessImageFileNameByProcessId( - _In_ HANDLE UniqueProcessId, - _Out_ PUNICODE_STRING ProcessImageFileName, - _In_ PNTSUPMEMALLOC AllocMem, - _In_ PNTSUPMEMFREE FreeMem); - -NTSTATUS ntsupQuerySystemObjectInformationVariableSize( - _In_ PFN_NTQUERYROUTINE QueryRoutine, - _In_opt_ HANDLE ObjectHandle, - _In_ DWORD InformationClass, - _Out_ PVOID* Buffer, - _Out_opt_ PULONG ReturnLength, - _In_ PNTSUPMEMALLOC AllocMem, - _In_ PNTSUPMEMFREE FreeMem); - -NTSTATUS ntsupQuerySystemObjectInformationVariableSizeEx( - _In_ PFN_NTQUERYROUTINE QueryRoutine, - _In_opt_ HANDLE ObjectHandle, - _In_ DWORD InformationClass, - _Out_ PVOID * Buffer, - _Out_opt_ PULONG ReturnLength, - _In_ ULONG InitialBufferSize, - _In_ PNTSUPMEMALLOC AllocMem, - _In_ PNTSUPMEMFREE FreeMem); - -BOOLEAN ntsupQueryVsmProtectionInformation( - _Out_ PBOOLEAN pbDmaProtectionsAvailable, - _Out_ PBOOLEAN pbDmaProtectionsInUse, - _Out_ PBOOLEAN pbHardwareMbecAvailable, - _Out_ PBOOLEAN pbApicVirtualizationAvailable); - -BOOLEAN ntsupQueryVBSState( - _Out_ PBOOLEAN pbVBSRunning, - _Out_ PBOOLEAN pbHVCIEnabled, - _Out_ PBOOLEAN pbHVCIStrictMode); - -PVOID ntsupLookupImageSectionByNameEx( - _In_ CHAR * SectionName, - _In_ ULONG SectionNameLength, - _In_ PVOID DllBase, - _In_ SIZE_T ImageSize, - _Out_opt_ PULONG SectionSize); - -PVOID ntsupLookupImageSectionByName( - _In_ CHAR* SectionName, - _In_ ULONG SectionNameLength, - _In_ PVOID DllBase, - _Out_ PULONG SectionSize); - -PVOID ntsupFindPattern( - _In_ CONST PBYTE Buffer, - _In_ SIZE_T BufferSize, - _In_ CONST PBYTE Pattern, - _In_ SIZE_T PatternSize); - -DWORD ntsupFindPatternEx( - _In_ PATTERN_SEARCH_PARAMS * SearchParams); - -NTSTATUS ntsupOpenProcess( - _In_ HANDLE UniqueProcessId, - _In_ ACCESS_MASK DesiredAccess, - _Out_ PHANDLE ProcessHandle); - -NTSTATUS ntsupOpenThread( - _In_ PCLIENT_ID ClientId, - _In_ ACCESS_MASK DesiredAccess, - _Out_ PHANDLE ThreadHandle); - -NTSTATUS ntsupCICustomKernelSignersAllowed( - _Out_ PBOOLEAN bAllowed); - -NTSTATUS ntsupPrivilegeEnabled( - _In_ HANDLE ClientToken, - _In_ ULONG Privilege, - _Out_ LPBOOL pfResult); - -LPWSTR ntsupQueryEnvironmentVariableOffset( - _In_ PUNICODE_STRING Value); - -BOOLEAN ntsupSetEnvironmentVariable( - _In_ LPCWSTR Name, - _In_opt_ LPCWSTR Value); - -DWORD ntsupExpandEnvironmentStrings( - _In_ LPCWSTR lpSrc, - _Out_writes_to_opt_(nSize, return) LPWSTR lpDst, - _In_ DWORD nSize); - -NTSTATUS ntsupIsLocalSystem( - _Out_ PBOOL pbResult); - -NTSTATUS ntsupIsUserHasInteractiveSid( - _In_ HANDLE hToken, - _Out_ PBOOL pbInteractiveSid); - -BOOL ntsupGetProcessElevationType( - _In_opt_ HANDLE ProcessHandle, - _Out_ TOKEN_ELEVATION_TYPE * lpType); - -NTSTATUS ntsupIsProcessElevated( - _In_ ULONG ProcessId, - _Out_ PBOOL Elevated); - -VOID ntsupPurgeSystemCache( - VOID); - -PWSTR ntsupGetSystemRoot( - VOID); - -NTSTATUS ntsupGetProcessDebugObject( - _In_ HANDLE ProcessHandle, - _Out_ PHANDLE DebugObjectHandle); - -PBYTE ntsupQueryResourceData( - _In_ ULONG_PTR ResourceId, - _In_ PVOID DllHandle, - _In_ PULONG DataSize); - -NTSTATUS ntsupEnableWow64Redirection( - _In_ BOOLEAN bEnable); - -BOOLEAN ntsupIsKdEnabled( - _Out_opt_ PBOOLEAN DebuggerAllowed, - _Out_opt_ PBOOLEAN DebuggerNotPresent); - -BOOLEAN ntsupIsObjectExists( - _In_ LPCWSTR RootDirectory, - _In_ LPCWSTR ObjectName); - -BOOLEAN ntsupUserIsFullAdmin( - VOID); - -NTSTATUS ntsupDuplicateUnicodeString( - _In_ PCUNICODE_STRING SourceString, - _Out_ PUNICODE_STRING DestinationString); - -NTSTATUS ntsupDuplicateAnsiString( - _In_ PCANSI_STRING SourceString, - _Out_ PANSI_STRING DestinationString); - -NTSTATUS ntsupHashImageSections( - _In_ PVOID ImageBase, - _In_ SIZE_T ImageSize, - _Out_writes_bytes_(HashBufferSize) PBYTE HashBuffer, - _In_ SIZE_T HashBufferSize, - _In_ NTSUP_IMAGE_TYPE ImageType); + VOID NTAPI ntsupFreeProcessDebugInformation( + _In_opt_ PRTL_DEBUG_INFORMATION DebugInformation); #define ntsupQuerySecurityInformation(\ ObjectHandle, SecurityInformationClass, Buffer, ReturnLength, AllocMem, FreeMem) \ From 1226a0978ed01a4ce075409e9605dbf069005455 Mon Sep 17 00:00:00 2001 From: hfiref0x Date: Sun, 30 Aug 2026 08:37:26 +0700 Subject: [PATCH 5/5] RTLs update ntsup 2.34 --- Source/Shared/ntos/ntsup.c | 148 ++++++++++++++++++++++++++++++++++++- Source/Shared/ntos/ntsup.h | 15 +++- 2 files changed, 159 insertions(+), 4 deletions(-) diff --git a/Source/Shared/ntos/ntsup.c b/Source/Shared/ntos/ntsup.c index a9763cb..585da3c 100644 --- a/Source/Shared/ntos/ntsup.c +++ b/Source/Shared/ntos/ntsup.c @@ -4,9 +4,9 @@ * * TITLE: NTSUP.C * -* VERSION: 2.33 +* VERSION: 2.34 * -* DATE: 12 Aug 2026 +* DATE: 18 Aug 2026 * * Native API support functions. * @@ -858,6 +858,150 @@ LPCWSTR ntsupStrStrIW( return NULL; } +/* +* ntsupStrStrA +* +* Purpose: +* +* Case sensitive string search. +* +*/ +LPCSTR ntsupStrStrA( + _In_ LPCSTR String, + _In_ LPCSTR SubString +) +{ + CHAR c0, c1, c2; + LPCSTR tmpString; + LPCSTR tmpSubString; + + if (String == SubString) + return String; + + if (String == NULL) + return NULL; + + if (SubString == NULL) + return NULL; + + // + // Empty substring matches at beginning. + // + if (*SubString == 0) + return String; + + c0 = *SubString; + + while (c0 != 0) { + + while (*String != 0) { + + c2 = *String; + + if (c2 == c0) + break; + + String++; + } + + if (*String == 0) + return NULL; + + tmpString = String; + tmpSubString = SubString; + + do { + + c1 = *tmpString; + c2 = *tmpSubString; + + tmpString++; + tmpSubString++; + + } while ((c1 == c2) && (c2 != 0)); + + + if (c2 == 0) + return String; + + String++; + } + + return NULL; +} + +/* +* ntsupStrStrW +* +* Purpose: +* +* Case sensitive string search. +* +*/ +LPCWSTR ntsupStrStrW( + _In_ LPCWSTR String, + _In_ LPCWSTR SubString +) +{ + WCHAR c0, c1, c2; + LPCWSTR tmpString; + LPCWSTR tmpSubString; + + if (String == SubString) + return String; + + if (String == NULL) + return NULL; + + if (SubString == NULL) + return NULL; + + // + // Empty substring matches at beginning. + // + if (*SubString == 0) + return String; + + c0 = *SubString; + + while (c0 != 0) { + + while (*String != 0) { + + c2 = *String; + + if (c2 == c0) + break; + + String++; + } + + if (*String == 0) + return NULL; + + tmpString = String; + tmpSubString = SubString; + + do { + + c1 = *tmpString; + c2 = *tmpSubString; + + tmpString++; + tmpSubString++; + + } while ((c1 == c2) && (c2 != 0)); + + + if (c2 == 0) + return String; + + String++; + } + + return NULL; +} + /* * ntsupStrCatA * diff --git a/Source/Shared/ntos/ntsup.h b/Source/Shared/ntos/ntsup.h index 038a9ba..bad27b8 100644 --- a/Source/Shared/ntos/ntsup.h +++ b/Source/Shared/ntos/ntsup.h @@ -4,9 +4,9 @@ * * TITLE: NTSUP.H * -* VERSION: 2.33 +* VERSION: 2.34 * -* DATE: 12 Aug 2026 +* DATE: 18 Aug 2026 * * Common header file for the NT API support functions and definitions. * @@ -237,6 +237,13 @@ extern "C" { _In_ LPCWSTR String, _In_ LPCWSTR SubString); + LPCSTR ntsupStrStrA( + _In_ LPCSTR String, + _In_ LPCSTR SubString); + LPCWSTR ntsupStrStrW( + _In_ LPCWSTR String, + _In_ LPCWSTR SubString); + LPSTR ntsupStrCatA( _Inout_ LPSTR Destination, _In_ LPCSTR Source); @@ -284,11 +291,13 @@ extern "C" { #define ntsupStrNCopy ntsupStrNCopyW #define ntsupStrNCmp ntsupStrNCmpW #define ntsupStrStrI ntsupStrStrIW +#define ntsupStrStr ntsupStrStrW #define ntsupStrCat ntsupStrCatW #define ntsupStrCatEx ntsupStrCatExW #define ntsupStrToUInt64 ntsupStrToUInt64W #define ntsupUInt64ToStr ntsupUInt64ToStrW #define ntsupHexToUInt64 ntsupHexToUInt64W +#define ntsupIsDigit ntsupIsDigitW #else #define ntsupLowerChar ntsupLowerCharA #define ntsupStrChr ntsupStrChrA @@ -299,11 +308,13 @@ extern "C" { #define ntsupStrNCopy ntsupStrNCopyA #define ntsupStrNCmp ntsupStrNCmpA #define ntsupStrStrI ntsupStrStrIA +#define ntsupStrStr ntsupStrStrA #define ntsupStrCat ntsupStrCatA #define ntsupStrCatEx ntsupStrCatExA #define ntsupStrToUInt64 ntsupStrToUInt64A #define ntsupUInt64ToStr ntsupUInt64ToStrA #define ntsupHexToUInt64 ntsupHexToUInt64A +#define ntsupIsDigit ntsupIsDigitA #endif //