From 09553e3e2cc2c1f4e93536ce18d3947cb637ca11 Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Sun, 2 Apr 2023 15:16:32 +0200 Subject: [PATCH] /W4: Fix incorrect instantiation of string transformer The case transformation didn't work properly as the char value was not casted to an unsigned char, causing undefined behavior. Added new utility function 'IsEqualNoCase' which allows for comparing 2 strings case insensitively. Code has been tested with module strings containing irregular cases, and was still able to obtain the imported function address correctly. --- r5dev/public/utility/module.cpp | 5 +---- r5dev/public/utility/utility.cpp | 11 +++++++++++ r5dev/public/utility/utility.h | 2 ++ 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/r5dev/public/utility/module.cpp b/r5dev/public/utility/module.cpp index 1ef232de..43ed6557 100644 --- a/r5dev/public/utility/module.cpp +++ b/r5dev/public/utility/module.cpp @@ -343,10 +343,7 @@ CMemory CModule::GetImportedFunction(const string& svModuleName, const string& s // Get virtual relative Address of the imported module name. Then add module base Address to get the actual location. string svImportedModuleName = reinterpret_cast(reinterpret_cast(m_pModuleBase + pIID->Name)); - // Convert all characters to lower case because KERNEL32.DLL sometimes is kernel32.DLL, sometimes KERNEL32.dll. - std::transform(svImportedModuleName.begin(), svImportedModuleName.end(), svImportedModuleName.begin(), static_cast(std::tolower)); - - if (svImportedModuleName.compare(svModuleName) == 0) // Is this our wanted imported module?. + if (IsEqualNoCase(svImportedModuleName, svModuleName)) // Is this our wanted imported module?. { // Original First Thunk to get function name. IMAGE_THUNK_DATA* pOgFirstThunk = reinterpret_cast(m_pModuleBase + pIID->OriginalFirstThunk); diff --git a/r5dev/public/utility/utility.cpp b/r5dev/public/utility/utility.cpp index 9fc7619d..b906a312 100644 --- a/r5dev/public/utility/utility.cpp +++ b/r5dev/public/utility/utility.cpp @@ -426,6 +426,17 @@ string ConvertToUnixPath(const string& svInput) return result; } +/////////////////////////////////////////////////////////////////////////////// +// For comparing two strings (case insensitive). +bool IsEqualNoCase(const string& svInput, const string& svSecond) +{ + return std::equal(svInput.begin(), svInput.end(), svSecond.begin(), svSecond.end(), + [](unsigned char ci, unsigned char cs) + { + return std::toupper(ci) == std::toupper(cs); + }); +} + /////////////////////////////////////////////////////////////////////////////// // For checking if input is a valid Base64. bool IsValidBase64(const string& svInput, string* psvOutput) diff --git a/r5dev/public/utility/utility.h b/r5dev/public/utility/utility.h index b26d7e2e..98234b58 100644 --- a/r5dev/public/utility/utility.h +++ b/r5dev/public/utility/utility.h @@ -35,7 +35,9 @@ void CreateDirectories(string svInput, string* pszOutput = nullptr, bool bWindow string ConvertToWinPath(const string& svInput); string ConvertToUnixPath(const string& svInput); +bool IsEqualNoCase(const string& svInput, const string& svSecond); bool IsValidBase64(const string& svInput, string* psvOutput = nullptr); + string Base64Encode(const string& svInput); string Base64Decode(const string& svInput);