From 9de5585f4e67c3a14e810f5f15d7499b0fd5b3f4 Mon Sep 17 00:00:00 2001 From: Peter Repukat Date: Sat, 16 Oct 2021 22:36:30 +0200 Subject: [PATCH] Gnar. --- .gitmodules | 6 ++ GlosSITarget/GlosSITarget.vcxproj | 12 ++- GlosSITarget/GlosSITarget.vcxproj.filters | 12 +++ GlosSITarget/OverlayDetector.cpp | 97 +++++++++++++++++++++++ GlosSITarget/OverlayDetector.h | 45 +++++++++++ GlosSITarget/SteamTarget.cpp | 3 +- GlosSITarget/SteamTarget.h | 3 + GlosSITarget/TargetWindow.cpp | 33 ++++++-- GlosSITarget/TargetWindow.h | 1 + GlosSITarget/main.cpp | 22 ++++- deps/WinReg | 1 + deps/spdlog | 1 + 12 files changed, 221 insertions(+), 15 deletions(-) create mode 100644 GlosSITarget/OverlayDetector.cpp create mode 100644 GlosSITarget/OverlayDetector.h create mode 160000 deps/WinReg create mode 160000 deps/spdlog diff --git a/.gitmodules b/.gitmodules index 3db936f..2761592 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,9 @@ [submodule "deps/SFML"] path = deps/SFML url = https://github.com/Alia5/SFML +[submodule "deps/WinReg"] + path = deps/WinReg + url = https://github.com/GiovanniDicanio/WinReg +[submodule "deps/spdlog"] + path = deps/spdlog + url = https://github.com/gabime/spdlog diff --git a/GlosSITarget/GlosSITarget.vcxproj b/GlosSITarget/GlosSITarget.vcxproj index ec8d5a7..6d60a1e 100644 --- a/GlosSITarget/GlosSITarget.vcxproj +++ b/GlosSITarget/GlosSITarget.vcxproj @@ -80,14 +80,14 @@ true - ..\deps\SFML\include;$(ExternalIncludePath) + ..\deps\SFML\include;..\deps\WinReg;..\deps\spdlog\include;..\deps\subhook;$(ExternalIncludePath) ..\deps\SFML\out\build\x64-Debug\lib;$(LibraryPath) false true false - ..\deps\SFML\include;$(ExternalIncludePath) + ..\deps\SFML\include;..\deps\WinReg;..\deps\spdlog\include;..\deps\subhook;$(ExternalIncludePath) ..\deps\SFML\out\build\x64-Release\lib;$(LibraryPath) @@ -122,7 +122,7 @@ Level3 true - _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _DEBUG;_CONSOLE;SPDLOG_WCHAR_TO_UTF8_SUPPORT;SUBHOOK_STATIC;%(PreprocessorDefinitions) true stdcpp20 @@ -138,7 +138,7 @@ true true true - NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + NDEBUG;_CONSOLE;SPDLOG_WCHAR_TO_UTF8_SUPPORT;SUBHOOK_STATIC;%(PreprocessorDefinitions) true stdcpp20 @@ -150,11 +150,15 @@ + + + + diff --git a/GlosSITarget/GlosSITarget.vcxproj.filters b/GlosSITarget/GlosSITarget.vcxproj.filters index ad2f87d..3b6c633 100644 --- a/GlosSITarget/GlosSITarget.vcxproj.filters +++ b/GlosSITarget/GlosSITarget.vcxproj.filters @@ -24,6 +24,12 @@ Source Files + + Source Files + + + Source Files + @@ -32,6 +38,12 @@ Header Files + + Header Files + + + Header Files + diff --git a/GlosSITarget/OverlayDetector.cpp b/GlosSITarget/OverlayDetector.cpp new file mode 100644 index 0000000..917385e --- /dev/null +++ b/GlosSITarget/OverlayDetector.cpp @@ -0,0 +1,97 @@ +/* +Copyright 2021 Peter Repukat - FlatspotSoftware + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +#include "OverlayDetector.h" + +#include + +#ifdef _WIN32 +#include +#define NOMINMAX +#include +#endif + + +OverlayDetector::OverlayDetector(std::function overlay_changed) + : overlay_changed_(std::move(overlay_changed)) +{ + auto addr_open = findFunctionByPattern(overlay_module_name_, open_func_sig_, open_func_mask_); + auto addr_close = findFunctionByPattern(overlay_module_name_, close_func_sig_, close_func_mask_); + + spdlog::info("Overlay opened function: {0:x}", addr_open); + spdlog::info("Overlay closed function: {0:x}", addr_close); + + +} + +void OverlayDetector::update() +{ +} + +uint64_t OverlayDetector::findFunctionByPattern( + const std::string_view &mod_name, + const char pattern[], + const std::string_view &mask) const +{ +#ifdef _WIN32 + + MODULEINFO mod_info = {NULL}; + const HMODULE mod = GetModuleHandleA(mod_name.data()); + + if (mod == nullptr) { + spdlog::error("{} not found!", overlay_module_name_); + return 0; + } + GetModuleInformation(GetCurrentProcess(), mod, &mod_info, sizeof(MODULEINFO)); + + auto base_addr = reinterpret_cast(mod_info.lpBaseOfDll); + if (base_addr == 0) + return NULL; + + spdlog::debug("overlay module found at: {:x}", base_addr); + + const uint64_t mod_size = mod_info.SizeOfImage; + const auto pat_length = mask.size(); + uint64_t pattern_addr = 0; + + for (uint64_t i = 0; i < mod_size - pat_length; i++) { + bool found = true; + for (uint64_t j = 0; j < pat_length; j++) + found &= mask[j] == '?' || pattern[j] == *reinterpret_cast(base_addr + j + i); + + if (found) + pattern_addr = base_addr + i; + } + if (pattern_addr == 0) + return 0; + + spdlog::debug("signature found at: {:x}", pattern_addr); + + constexpr char start_fn_bytes[] = "\x40\x53"; + + for (auto i = pattern_addr; i > base_addr; i--) { + bool found = true; + for (uint64_t j = 0; j < 2; j++) + found &= start_fn_bytes[j] == *reinterpret_cast(i + j); + + if (found) + return i; + } + return 0; + +#else + +#endif +} diff --git a/GlosSITarget/OverlayDetector.h b/GlosSITarget/OverlayDetector.h new file mode 100644 index 0000000..b383770 --- /dev/null +++ b/GlosSITarget/OverlayDetector.h @@ -0,0 +1,45 @@ +/* +Copyright 2021 Peter Repukat - FlatspotSoftware + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +#pragma once +#include +#include + + +class OverlayDetector { + public: + explicit OverlayDetector(std::function overlay_changed = [](bool) {}); + void update(); + + private: + std::function overlay_changed_; + + + uint64_t findFunctionByPattern( + const std::string_view &mod_name, + const char pattern[], + const std::string_view &mask) const; + +#ifdef _WIN32 + static constexpr std::string_view overlay_module_name_ = "GameOverlayRenderer64.dll"; + static constexpr char open_func_sig_[] = "\xC6\x41\x5C\x01\x48\x8D\x4C\x24\x30"; + static constexpr std::string_view open_func_mask_ = "xxxxxxxxx"; + static constexpr char close_func_sig_[] = "\xC6\x41\x5C\x00\x48\x8D\x4C\x24\x40"; + static constexpr std::string_view close_func_mask_ = "xxxxxxxxx"; + +#else + +#endif +}; diff --git a/GlosSITarget/SteamTarget.cpp b/GlosSITarget/SteamTarget.cpp index 0214a24..c275a9e 100644 --- a/GlosSITarget/SteamTarget.cpp +++ b/GlosSITarget/SteamTarget.cpp @@ -15,8 +15,6 @@ limitations under the License. */ #include "SteamTarget.h" -#include - SteamTarget::SteamTarget(int argc, char *argv[]) : window_([this] { run_ = false; }) { } @@ -26,6 +24,7 @@ int SteamTarget::run() run_ = true; window_.setFpsLimit(90); while (run_) { + detector_.update(); window_.update(); } return 1; diff --git a/GlosSITarget/SteamTarget.h b/GlosSITarget/SteamTarget.h index 7388af1..f075020 100644 --- a/GlosSITarget/SteamTarget.h +++ b/GlosSITarget/SteamTarget.h @@ -15,8 +15,10 @@ limitations under the License. */ #pragma once +#include "OverlayDetector.h" #include "TargetWindow.h" + class SteamTarget { public: explicit SteamTarget(int argc, char *argv[]); @@ -25,4 +27,5 @@ class SteamTarget { private: bool run_ = false; TargetWindow window_; + OverlayDetector detector_; }; diff --git a/GlosSITarget/TargetWindow.cpp b/GlosSITarget/TargetWindow.cpp index c5e5fb8..b9fb3ac 100644 --- a/GlosSITarget/TargetWindow.cpp +++ b/GlosSITarget/TargetWindow.cpp @@ -15,6 +15,7 @@ limitations under the License. */ #include "TargetWindow.h" +#include #include #include @@ -24,9 +25,17 @@ limitations under the License. #include #endif -TargetWindow::TargetWindow(std::function on_close) : on_close_(std::move(on_close)) +static const bool DEV_MODE = true; + +TargetWindow::TargetWindow(std::function on_close) + : on_close_(std::move(on_close)) { - window_.create(sf::VideoMode::getDesktopMode(), "GlosSITarget", sf::Style::None); + if (DEV_MODE) { + window_.create(sf::VideoMode{1920, 1080}, "GlosSITarget", sf::Style::Default); + } + else { + window_.create(sf::VideoMode::getDesktopMode(), "GlosSITarget", sf::Style::None); + } window_.setActive(true); #ifdef _WIN32 @@ -34,12 +43,15 @@ TargetWindow::TargetWindow(std::function on_close) : on_close_(std::move MARGINS margins; margins.cxLeftWidth = -1; DwmExtendFrameIntoClientArea(hwnd, &margins); - - // always on top - SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); + if (!DEV_MODE) { + // always on top + SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); + } #endif - setClickThrough(true); + if (!DEV_MODE) { + setClickThrough(true); + } } void TargetWindow::setFpsLimit(unsigned int fps_limit) @@ -70,8 +82,13 @@ void TargetWindow::update() on_close_(); } } - window_.clear(sf::Color::Transparent); - //window_.clear(sf::Color(255,0,0,1)); + if (DEV_MODE) { + window_.clear(sf::Color(0, 0, 0, 128)); + } + else { + window_.clear(sf::Color::Transparent); + } + window_.display(); } diff --git a/GlosSITarget/TargetWindow.h b/GlosSITarget/TargetWindow.h index ddacd19..2cb850c 100644 --- a/GlosSITarget/TargetWindow.h +++ b/GlosSITarget/TargetWindow.h @@ -30,4 +30,5 @@ class TargetWindow { private: const std::function on_close_; sf::RenderWindow window_; + }; diff --git a/GlosSITarget/main.cpp b/GlosSITarget/main.cpp index e78870a..4f03975 100644 --- a/GlosSITarget/main.cpp +++ b/GlosSITarget/main.cpp @@ -20,6 +20,10 @@ limitations under the License. #include "SteamTarget.h" +#include +#include +#include + //int CALLBACK WinMain( // _In_ HINSTANCE hInstance, // _In_ HINSTANCE hPrevInstance, @@ -34,6 +38,22 @@ limitations under the License. int main(int argc, char *argv[]) { + const auto console_sink = std::make_shared(); + console_sink->set_level(spdlog::level::trace); +#ifdef _WIN32 + const auto file_sink = std::make_shared("./glossitarget.log", true); +#else + auto file_sink = std::make_shared("/tmp/glossitarget.log", true); +#endif + file_sink->set_level(spdlog::level::trace); + std::vector sinks{file_sink, console_sink}; + auto logger = std::make_shared("log", sinks.begin(), sinks.end()); + logger->set_level(spdlog::level::trace); + logger->flush_on(spdlog::level::info); + spdlog::set_default_logger(logger); + SteamTarget target(argc, argv); - return target.run(); + const auto exit = target.run(); + spdlog::shutdown(); + return exit; } \ No newline at end of file diff --git a/deps/WinReg b/deps/WinReg new file mode 160000 index 0000000..023ad61 --- /dev/null +++ b/deps/WinReg @@ -0,0 +1 @@ +Subproject commit 023ad61dc77c83407e7ae061f177a3ba3d3941e6 diff --git a/deps/spdlog b/deps/spdlog new file mode 160000 index 0000000..8826011 --- /dev/null +++ b/deps/spdlog @@ -0,0 +1 @@ +Subproject commit 8826011c81b69e1f8427be520b357c19c74ea480