From b09d3ca69a7a9c8e31ec8626c42cdb4f150bcc7d Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Sun, 17 Dec 2023 11:41:12 -0600 Subject: [PATCH 1/5] kernel: update RtlAnsiStringToUnicodeString to include error log returns --- src/core/kernel/exports/EmuKrnlRtl.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/core/kernel/exports/EmuKrnlRtl.cpp b/src/core/kernel/exports/EmuKrnlRtl.cpp index 671cca6d5..eced8f70a 100644 --- a/src/core/kernel/exports/EmuKrnlRtl.cpp +++ b/src/core/kernel/exports/EmuKrnlRtl.cpp @@ -108,23 +108,28 @@ XBSYSAPI EXPORTNUM(260) xbox::ntstatus_xt NTAPI xbox::RtlAnsiStringToUnicodeStri dword_xt total = RtlAnsiStringToUnicodeSize(SourceString); if (total > 0xffff) { - return X_STATUS_INVALID_PARAMETER_2; + RETURN(X_STATUS_INVALID_PARAMETER_2); } DestinationString->Length = (USHORT)(total - sizeof(WCHAR)); if (AllocateDestinationString) { DestinationString->MaximumLength = (USHORT)total; if (!(DestinationString->Buffer = (USHORT*)ExAllocatePoolWithTag(total, 'grtS'))) { - return X_STATUS_NO_MEMORY; + RETURN(X_STATUS_NO_MEMORY); } } else { if (total > DestinationString->MaximumLength) { - return X_STATUS_BUFFER_OVERFLOW; + RETURN(X_STATUS_BUFFER_OVERFLOW); } } - RtlMultiByteToUnicodeN((PWSTR)DestinationString->Buffer, (ULONG)DestinationString->Length, NULL, SourceString->Buffer, SourceString->Length); + RtlMultiByteToUnicodeN((PWSTR)DestinationString->Buffer, + (ULONG)DestinationString->Length, + NULL, + SourceString->Buffer, + SourceString->Length); + DestinationString->Buffer[DestinationString->Length / sizeof(WCHAR)] = 0; RETURN(X_STATUS_SUCCESS); From a2fb41856dffbe3dcf84b4f1715307f8997fc49b Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Sun, 17 Dec 2023 19:02:20 -0600 Subject: [PATCH 2/5] kernel: fix RtlWalkFrameChain according to xbox kernel test suite failed test --- src/core/kernel/exports/EmuKrnlRtl.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/core/kernel/exports/EmuKrnlRtl.cpp b/src/core/kernel/exports/EmuKrnlRtl.cpp index eced8f70a..c5991807b 100644 --- a/src/core/kernel/exports/EmuKrnlRtl.cpp +++ b/src/core/kernel/exports/EmuKrnlRtl.cpp @@ -2224,6 +2224,11 @@ XBSYSAPI EXPORTNUM(319) xbox::ulong_xt NTAPI xbox::RtlWalkFrameChain ulong_ptr_xt NewStack = *(ulong_ptr_xt*)Stack; ulong_xt Eip = *(ulong_ptr_xt*)(Stack + sizeof(ulong_ptr_xt)); + /* Check if Eip is not below executable's dos header */ + if (Eip < KiB(64)) { + break; + } + /* Check if the new pointer is above the old one and past the end */ if (!((Stack < NewStack) && (NewStack < StackEnd))) { /* Stop searching after this entry */ From e5043dbc054b7114c5a86550a794d19249b5c4ff Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Sun, 17 Dec 2023 20:49:10 -0600 Subject: [PATCH 3/5] fix UNICODE_STRING's Buffer variable type issue --- src/core/kernel/common/types.h | 2 +- src/core/kernel/exports/EmuKrnlRtl.cpp | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/core/kernel/common/types.h b/src/core/kernel/common/types.h index ab29c23dd..294bfc96b 100644 --- a/src/core/kernel/common/types.h +++ b/src/core/kernel/common/types.h @@ -266,7 +266,7 @@ typedef struct _UNICODE_STRING { ushort_xt Length; ushort_xt MaximumLength; - ushort_xt *Buffer; + wchar_xt *Buffer; } UNICODE_STRING, *PUNICODE_STRING; diff --git a/src/core/kernel/exports/EmuKrnlRtl.cpp b/src/core/kernel/exports/EmuKrnlRtl.cpp index c5991807b..f45785a65 100644 --- a/src/core/kernel/exports/EmuKrnlRtl.cpp +++ b/src/core/kernel/exports/EmuKrnlRtl.cpp @@ -114,7 +114,7 @@ XBSYSAPI EXPORTNUM(260) xbox::ntstatus_xt NTAPI xbox::RtlAnsiStringToUnicodeStri DestinationString->Length = (USHORT)(total - sizeof(WCHAR)); if (AllocateDestinationString) { DestinationString->MaximumLength = (USHORT)total; - if (!(DestinationString->Buffer = (USHORT*)ExAllocatePoolWithTag(total, 'grtS'))) { + if (!(DestinationString->Buffer = (wchar_xt*)ExAllocatePoolWithTag(total, 'grtS'))) { RETURN(X_STATUS_NO_MEMORY); } } @@ -657,7 +657,7 @@ XBSYSAPI EXPORTNUM(274) xbox::boolean_xt NTAPI xbox::RtlCreateUnicodeString BOOLEAN result = TRUE; ULONG bufferSize = (std::u16string(SourceString).length() + 1) * sizeof(WCHAR); - DestinationString->Buffer = (USHORT *)ExAllocatePoolWithTag(bufferSize, 'grtS'); + DestinationString->Buffer = (wchar_xt*)ExAllocatePoolWithTag(bufferSize, 'grtS'); if (!DestinationString->Buffer) { result = FALSE; } @@ -705,7 +705,7 @@ XBSYSAPI EXPORTNUM(276) xbox::ntstatus_xt NTAPI xbox::RtlDowncaseUnicodeString if (AllocateDestinationString) { DestinationString->MaximumLength = SourceString->Length; - DestinationString->Buffer = (USHORT*)ExAllocatePoolWithTag((ULONG)DestinationString->MaximumLength, 'grtS'); + DestinationString->Buffer = (wchar_xt*)ExAllocatePoolWithTag((ULONG)DestinationString->MaximumLength, 'grtS'); if (DestinationString->Buffer == NULL) { return X_STATUS_NO_MEMORY; } @@ -1178,9 +1178,9 @@ XBSYSAPI EXPORTNUM(290) xbox::void_xt NTAPI xbox::RtlInitUnicodeString LOG_FUNC_ARG(SourceString) LOG_FUNC_END; - DestinationString->Buffer = (USHORT*)SourceString; + DestinationString->Buffer = (wchar_xt*)SourceString; if (SourceString != NULL) { - DestinationString->Buffer = (USHORT*)SourceString; + DestinationString->Buffer = (wchar_xt*)SourceString; DestinationString->Length = (USHORT)std::u16string(SourceString).length() * 2; DestinationString->MaximumLength = DestinationString->Length + 2; } @@ -2030,7 +2030,7 @@ XBSYSAPI EXPORTNUM(314) xbox::ntstatus_xt NTAPI xbox::RtlUpcaseUnicodeString if (AllocateDestinationString) { DestinationString->MaximumLength = SourceString->Length; - DestinationString->Buffer = (USHORT*)ExAllocatePoolWithTag((ULONG)DestinationString->MaximumLength, 'grtS'); + DestinationString->Buffer = (wchar_xt*)ExAllocatePoolWithTag((ULONG)DestinationString->MaximumLength, 'grtS'); if (DestinationString->Buffer == NULL) { return X_STATUS_NO_MEMORY; } From 1f1d1ac631d3aa02ef683ff617f16322db2836e0 Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Sun, 17 Dec 2023 20:50:46 -0600 Subject: [PATCH 4/5] rtl: fix RtlCompareString and RtlCompareUnicodeString to match with kernel test suite --- src/core/kernel/exports/EmuKrnlRtl.cpp | 57 +++++++++++++++++--------- 1 file changed, 37 insertions(+), 20 deletions(-) diff --git a/src/core/kernel/exports/EmuKrnlRtl.cpp b/src/core/kernel/exports/EmuKrnlRtl.cpp index f45785a65..99455fb19 100644 --- a/src/core/kernel/exports/EmuKrnlRtl.cpp +++ b/src/core/kernel/exports/EmuKrnlRtl.cpp @@ -526,23 +526,31 @@ XBSYSAPI EXPORTNUM(270) xbox::long_xt NTAPI xbox::RtlCompareString LOG_FUNC_ARG(CaseInSensitive) LOG_FUNC_END; - LONG result; + const USHORT l1 = String1->Length; + const USHORT l2 = String2->Length; + const USHORT maxLen = (l1 <= l2 ? l1 : l2); - USHORT l1 = String1->Length; - USHORT l2 = String2->Length; - USHORT maxLen = l1 <= l2 ? l1 : l2; - - CHAR *str1 = String1->Buffer; - CHAR *str2 = String2->Buffer; + const PCHAR str1 = String1->Buffer; + const PCHAR str2 = String2->Buffer; if (CaseInSensitive) { - result = _strnicmp(str1, str2, maxLen); + for (unsigned i = 0; i < maxLen; i++) { + UCHAR char1 = RtlLowerChar(str1[i]); + UCHAR char2 = RtlLowerChar(str2[i]); + if (char1 != char2) { + RETURN(char1 - char2); + } + } } else { - result = strncmp(str1, str2, maxLen); + for (unsigned i = 0; i < maxLen; i++) { + if (str1[i] != str2[i]) { + RETURN(str1[i] - str2[i]); + } + } } - RETURN(result); + RETURN(l1 - l2); } // ****************************************************************** @@ -561,23 +569,32 @@ XBSYSAPI EXPORTNUM(271) xbox::long_xt NTAPI xbox::RtlCompareUnicodeString LOG_FUNC_ARG(CaseInSensitive) LOG_FUNC_END; - LONG result; + const USHORT l1 = String1->Length; + const USHORT l2 = String2->Length; + const USHORT maxLen = (l1 <= l2 ? l1 : l2) / sizeof(WCHAR); - USHORT l1 = String1->Length; - USHORT l2 = String2->Length; - USHORT maxLen = l1 <= l2 ? l1 : l2; - - WCHAR *str1 = (WCHAR*)(String1->Buffer); - WCHAR *str2 = (WCHAR*)(String2->Buffer); + const wchar_xt* str1 = String1->Buffer; + const wchar_xt* str2 = String2->Buffer; if (CaseInSensitive) { - result = _wcsnicmp(str1, str2, maxLen); + for (unsigned i = 0; i < maxLen; i++) { + wchar_xt char1 = towlower(str1[i]); + wchar_xt char2 = towlower(str2[i]); + + if (char1 != char2) { + RETURN(char1 - char2); + } + } } else { - result = wcsncmp(str1, str2, maxLen); + for (unsigned i = 0; i < maxLen; i++) { + if (str1[i] != str2[i]) { + RETURN(str1[i] - str2[i]); + } + } } - RETURN(result); + RETURN(l1 - l2); } // ****************************************************************** From 4d9151ca261d20a794173116a5e0c8724923c3f3 Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Wed, 20 Dec 2023 09:31:35 -0600 Subject: [PATCH 5/5] rtl: remove unnecessary double setter in RtlInitUnicodeString --- src/core/kernel/exports/EmuKrnlRtl.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/kernel/exports/EmuKrnlRtl.cpp b/src/core/kernel/exports/EmuKrnlRtl.cpp index 99455fb19..96741bfe0 100644 --- a/src/core/kernel/exports/EmuKrnlRtl.cpp +++ b/src/core/kernel/exports/EmuKrnlRtl.cpp @@ -1197,7 +1197,6 @@ XBSYSAPI EXPORTNUM(290) xbox::void_xt NTAPI xbox::RtlInitUnicodeString DestinationString->Buffer = (wchar_xt*)SourceString; if (SourceString != NULL) { - DestinationString->Buffer = (wchar_xt*)SourceString; DestinationString->Length = (USHORT)std::u16string(SourceString).length() * 2; DestinationString->MaximumLength = DestinationString->Length + 2; }