From c809b0d01b9f700d9ecdc98cd0ebaa9fa58372af Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Fri, 16 Apr 2021 12:14:39 -0500 Subject: [PATCH 1/2] kernel: fix RtlUnicodeStringToAnsiString --- src/core/kernel/exports/EmuKrnlRtl.cpp | 32 ++++++++++++++++---------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/src/core/kernel/exports/EmuKrnlRtl.cpp b/src/core/kernel/exports/EmuKrnlRtl.cpp index da4c41c36..63fa1b38d 100644 --- a/src/core/kernel/exports/EmuKrnlRtl.cpp +++ b/src/core/kernel/exports/EmuKrnlRtl.cpp @@ -1677,10 +1677,9 @@ XBSYSAPI EXPORTNUM(307) xbox::ulong_xt FASTCALL xbox::RtlUlongByteSwap RETURN(ret); } -xbox::dword_xt WINAPI RtlUnicodeStringToAnsiSize(const xbox::UNICODE_STRING *str) +static xbox::dword_xt RtlUnicodeStringToAnsiSize(const xbox::UNICODE_STRING *str) { - const wchar_t *src = (const wchar_t *)(str->Buffer); - xbox::dword_xt ret = wcsrtombs(nullptr, &src, (size_t)str->Length, nullptr); + xbox::dword_xt ret = str->Length / sizeof(xbox::ushort_xt); return ret + 1; // +1 for the terminating null character } @@ -1691,7 +1690,7 @@ XBSYSAPI EXPORTNUM(308) xbox::ntstatus_xt NTAPI xbox::RtlUnicodeStringToAnsiStri ( IN OUT PSTRING DestinationString, IN PUNICODE_STRING SourceString, - IN boolean_xt AllocateDestinationString + IN boolean_xt AllocateDestinationString ) { LOG_FUNC_BEGIN @@ -1700,26 +1699,35 @@ XBSYSAPI EXPORTNUM(308) xbox::ntstatus_xt NTAPI xbox::RtlUnicodeStringToAnsiStri LOG_FUNC_ARG(AllocateDestinationString) LOG_FUNC_END; - NTSTATUS ret = xbox::status_success; - dword_xt len = RtlUnicodeStringToAnsiSize(SourceString); + ntstatus_xt ret = xbox::status_success; + dword_xt len = RtlUnicodeStringToAnsiSize(SourceString); DestinationString->Length = (USHORT)(len - 1); - if (AllocateDestinationString) { + if (AllocateDestinationString) { DestinationString->MaximumLength = (USHORT)len; if (!(DestinationString->Buffer = (PCHAR)ExAllocatePoolWithTag(len, 'grtS'))) { return xbox::status_no_memory; } - } - else if (DestinationString->MaximumLength < len) { + } + else if (DestinationString->MaximumLength < len) { if (!DestinationString->MaximumLength) { return xbox::status_buffer_overflow; } DestinationString->Length = DestinationString->MaximumLength - 1; - ret = xbox::status_buffer_overflow; - } + ret = xbox::status_buffer_overflow; + } + + ntstatus_xt result = RtlUnicodeToMultiByteN(DestinationString->Buffer, DestinationString->Length, NULL, (PWSTR)SourceString->Buffer, (ULONG)SourceString->Length); + + if (!nt_success(result)) { + if (AllocateDestinationString) { + ExFreePool(DestinationString->Buffer); + DestinationString->Buffer = zeroptr; + } + RETURN(ret); + } - RtlUnicodeToMultiByteN(DestinationString->Buffer, DestinationString->Length, NULL, (PWSTR)SourceString->Buffer, (ULONG)SourceString->Length); DestinationString->Buffer[DestinationString->Length] = 0; RETURN(ret); From 3b43c081e4fb3aed3221c4a1679277d8d22a8d83 Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Sat, 17 Apr 2021 15:02:01 -0500 Subject: [PATCH 2/2] review remarks --- src/core/kernel/exports/EmuKrnlRtl.cpp | 31 +++++++++++++++----------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/src/core/kernel/exports/EmuKrnlRtl.cpp b/src/core/kernel/exports/EmuKrnlRtl.cpp index 63fa1b38d..0c5ae3848 100644 --- a/src/core/kernel/exports/EmuKrnlRtl.cpp +++ b/src/core/kernel/exports/EmuKrnlRtl.cpp @@ -1700,36 +1700,41 @@ XBSYSAPI EXPORTNUM(308) xbox::ntstatus_xt NTAPI xbox::RtlUnicodeStringToAnsiStri LOG_FUNC_END; ntstatus_xt ret = xbox::status_success; - dword_xt len = RtlUnicodeStringToAnsiSize(SourceString); + dword_xt AnsiMaxLength = RtlUnicodeStringToAnsiSize(SourceString); - DestinationString->Length = (USHORT)(len - 1); + DestinationString->Length = (ushort_xt)(AnsiMaxLength - 1); if (AllocateDestinationString) { - DestinationString->MaximumLength = (USHORT)len; - if (!(DestinationString->Buffer = (PCHAR)ExAllocatePoolWithTag(len, 'grtS'))) { - return xbox::status_no_memory; + DestinationString->MaximumLength = (ushort_xt)AnsiMaxLength; + if (!(DestinationString->Buffer = (PCHAR)ExAllocatePoolWithTag(AnsiMaxLength, 'grtS'))) { + ret = xbox::status_no_memory; + goto forceReturn; } } - else if (DestinationString->MaximumLength < len) { + else if (DestinationString->MaximumLength < AnsiMaxLength) { + ret = xbox::status_buffer_overflow; + if (!DestinationString->MaximumLength) { - return xbox::status_buffer_overflow; + goto forceReturn; } DestinationString->Length = DestinationString->MaximumLength - 1; - ret = xbox::status_buffer_overflow; } - ntstatus_xt result = RtlUnicodeToMultiByteN(DestinationString->Buffer, DestinationString->Length, NULL, (PWSTR)SourceString->Buffer, (ULONG)SourceString->Length); + xbox::ulong_xt index = 0; + ntstatus_xt result = RtlUnicodeToMultiByteN(DestinationString->Buffer, DestinationString->Length, &index, (PWSTR)SourceString->Buffer, SourceString->Length); - if (!nt_success(result)) { + if (nt_success(result)) { + DestinationString->Buffer[index] = 0; + } + else { if (AllocateDestinationString) { ExFreePool(DestinationString->Buffer); DestinationString->Buffer = zeroptr; } - RETURN(ret); + ret = result; } - DestinationString->Buffer[DestinationString->Length] = 0; - + forceReturn: RETURN(ret); }