diff --git a/src/core/logger/LogSink.cpp b/src/core/logger/LogSink.cpp index d8cfa57..97b2532 100644 --- a/src/core/logger/LogSink.cpp +++ b/src/core/logger/LogSink.cpp @@ -4,6 +4,8 @@ #include +#include "core/util/Wine.hpp" + namespace YimMenu { LogColor LogSink::GetColor(const eLogLevel level) @@ -29,6 +31,12 @@ namespace YimMenu { std::stringstream out; + static std::optional simplified = std::nullopt; + if (!simplified.has_value()) + simplified = InWine(); + if (simplified.value_or(false)) + return FormatFile(msg); + const auto timestamp = std::format("{0:%H:%M:%S}", msg->Timestamp()); const auto& location = msg->Location(); const auto level = msg->Level(); diff --git a/src/core/memory/Module.hpp b/src/core/memory/Module.hpp index a75b9f0..2aeb268 100644 --- a/src/core/memory/Module.hpp +++ b/src/core/memory/Module.hpp @@ -2,10 +2,15 @@ #include "PointerCalculator.hpp" #include "common.hpp" +#include + #include namespace YimMenu { + template + concept Symbol = std::is_convertible_v || std::is_convertible_v; + class Module { public: @@ -18,15 +23,39 @@ namespace YimMenu inline const std::uintptr_t End() const; /** - * @brief Parses the EAT of the module for the requested symbolname + * @brief Parses the EAT of the module for the requested symbol name * - * @param symbolName + * @param symbolName The function name * @return void* Function address of the exported function */ - template - T GetExport(const std::string_view symbolName) const; - template - T GetExport(int ordinal) const; + template + R GetExport(const std::string_view symbolName) const; + /** + * @brief Parses the EAT of the module for the requested symbol ordinal + * + * @param ordinal The function ordinal + * @return void* Function address of the exported function + */ + template + R GetExport(const int ordinal) const; + /** + * @brief Checks if the module exports a function with the given name + * + * @param symbolName The function name + * @return true If the function is exported + * @return false If the function is not exported + */ + [[nodiscard]] + bool IsExported(const std::string_view symbolName) const; + /** + * @brief Checks if the module exports a function with the given ordinal + * + * @param ordinal The function ordinal + * @return true If the function is exported + * @return false If the function is not exported + */ + [[nodiscard]] + bool IsExported(const int ordinal) const; /** * @brief Gets the address of the import function * @@ -40,6 +69,10 @@ namespace YimMenu IMAGE_NT_HEADERS* GetNtHeader() const; + private: + template + R GetExportImpl(const T symbol) const; + private: const std::filesystem::path m_Path; const std::string m_Name; @@ -62,8 +95,40 @@ namespace YimMenu return Base() + m_Size; } - template - inline T Module::GetExport(const std::string_view symbolName) const + template + inline R Module::GetExport(const std::string_view name) const + { + auto result = GetExportImpl(name); + if (result) + return result; + + LOG(FATAL) << "Cannot find export: " << name; + return nullptr; + } + + template + inline R Module::GetExport(const int ordinal) const + { + auto result = GetExportImpl(ordinal); + if (result) + return result; + + LOG(FATAL) << "Cannot find export: " << ordinal; + return nullptr; + } + + inline bool Module::IsExported(const std::string_view symbolName) const + { + return GetExportImpl(symbolName) != nullptr; + } + + inline bool Module::IsExported(const int ordinal) const + { + return GetExportImpl(ordinal) != nullptr; + } + + template + inline R Module::GetExportImpl(const T symbol) const { const auto ntHeader = GetNtHeader(); if (!ntHeader) @@ -72,42 +137,32 @@ namespace YimMenu const auto imageDataDirectory = ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; const auto exportDirectory = m_Base.Add(imageDataDirectory.VirtualAddress).As(); const auto namesOffsets = m_Base.Add(exportDirectory->AddressOfNames).As(); - const auto funcOffsets = m_Base.Add(exportDirectory->AddressOfFunctions).As(); - - for (std::size_t i = 0; i < exportDirectory->NumberOfFunctions; i++) - { - const auto functionName = m_Base.Add(namesOffsets[i]).As(); - if (strcmp(functionName, symbolName.data())) - continue; - - return m_Base.Add(funcOffsets[i]).As(); - } - - LOG(FATAL) << "Cannot find export: " << symbolName; - return nullptr; - } - - template - inline T Module::GetExport(int ordinal) const - { - const auto ntHeader = GetNtHeader(); - if (!ntHeader) - return nullptr; - - const auto imageDataDirectory = ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; - const auto exportDirectory = m_Base.Add(imageDataDirectory.VirtualAddress).As(); const auto ordinalOffsets = m_Base.Add(exportDirectory->AddressOfNameOrdinals).As(); const auto funcOffsets = m_Base.Add(exportDirectory->AddressOfFunctions).As(); for (std::size_t i = 0; i < exportDirectory->NumberOfFunctions; i++) { - if (ordinalOffsets[i] != ordinal) - continue; + if constexpr (std::is_convertible_v) + { + if (ordinalOffsets[i] != symbol) + continue; - return m_Base.Add(funcOffsets[i]).As(); + return m_Base.Add(funcOffsets[i]).As(); + } + else if constexpr (std::is_convertible_v) + { + const auto functionName = m_Base.Add(namesOffsets[i]).As(); + if (strcmp(functionName, symbol.data())) + continue; + + return m_Base.Add(funcOffsets[i]).As(); + } + else + { + static_assert(false, "Unsupported symbol type"); + } } - LOG(FATAL) << "Cannot find export: " << ordinal; return nullptr; } } \ No newline at end of file diff --git a/src/core/util/Wine.hpp b/src/core/util/Wine.hpp new file mode 100644 index 0000000..fa8eb3b --- /dev/null +++ b/src/core/util/Wine.hpp @@ -0,0 +1,14 @@ +#include "core/memory/ModuleMgr.hpp" +#include "Joaat.hpp" + +#include + +namespace YimMenu { + inline std::optional InWine() + { + auto module = ModuleMgr.Get("ntdll.dll"_J); + if (!module) + return std::nullopt; + return module->IsExported("wine_get_version"); + } +} \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index d7cd07d..b4b6265 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -10,6 +10,7 @@ #include "core/hooking/CallHook.hpp" #include "core/memory/ModuleMgr.hpp" #include "core/renderer/Renderer.hpp" +#include "core/util/Wine.hpp" #include "core/scripting/LuaManager.hpp" #include "game/backend/AnticheatBypass.hpp" #include "game/backend/Players.hpp" @@ -84,6 +85,9 @@ namespace YimMenu Notifications::Show("YimMenuV2", "Loaded succesfully", NotificationType::Success); + if (InWine().value_or(false)) + LOG(INFO) << "Running in Wine!"; + while (g_Running) { Settings::Tick();