diff --git a/src/client/component/arxan.cpp b/src/client/component/arxan.cpp index 8d0eaf90..a578df85 100644 --- a/src/client/component/arxan.cpp +++ b/src/client/component/arxan.cpp @@ -2,6 +2,7 @@ #include "loader/component_loader.hpp" #include "scheduler.hpp" +#include "game/game.hpp" #include "steam/steam.hpp" #include @@ -479,7 +480,7 @@ namespace arxan uint32_t adjust_integrity_checksum(const uint64_t return_address, uint8_t* stack_frame, const uint32_t current_checksum) { - const auto handler_address = reverse_g(return_address - 5); + const auto handler_address = game::derelocate(return_address - 5); const auto* context = search_handler_context(stack_frame, current_checksum); if (!context) diff --git a/src/client/component/console.cpp b/src/client/component/console.cpp index 1dc94c9a..6493ccc2 100644 --- a/src/client/component/console.cpp +++ b/src/client/component/console.cpp @@ -124,9 +124,7 @@ namespace console void sys_create_console_stub(const HINSTANCE h_instance) { - // C6262 - char text[CONSOLE_BUFFER_SIZE]; - char clean_console_buffer[CONSOLE_BUFFER_SIZE]; + char text[CONSOLE_BUFFER_SIZE]{0}; const auto* class_name = "BOIII WinConsole"; const auto* window_name = "BOIII Console"; @@ -206,9 +204,8 @@ namespace console 0); SetFocus(*game::s_wcd::hwndInputLine); - game::Con_GetTextCopy(text, 0x4000); - game::Conbuf_CleanText(text, clean_console_buffer); - SetWindowTextA(*game::s_wcd::hwndBuffer, clean_console_buffer); + game::Con_GetTextCopy(text, std::min(0x4000, static_cast(sizeof(text)))); + SetWindowTextA(*game::s_wcd::hwndBuffer, text); } } diff --git a/src/client/component/exception.cpp b/src/client/component/exception.cpp index eea66cde..4bd95e69 100644 --- a/src/client/component/exception.cpp +++ b/src/client/component/exception.cpp @@ -71,7 +71,7 @@ namespace exception const std::string error_str = utils::string::va("Fatal error (0x%08X) at 0x%p (0x%p).\n" "A minidump has been written.\n", exception_data.code, exception_data.address, - reverse_g(reinterpret_cast(exception_data.address))); + game::derelocate(reinterpret_cast(exception_data.address))); utils::thread::suspend_other_threads(); show_mouse_cursor(); @@ -92,7 +92,7 @@ namespace exception "Make sure to update your graphics card drivers and install operating system updates!\n" "Closing or restarting Steam might also help.", exception_data.code, exception_data.address, - reverse_g(reinterpret_cast(exception_data.address))); + game::derelocate(reinterpret_cast(exception_data.address))); } else { @@ -139,7 +139,7 @@ namespace exception line("Timestamp: "s + get_timestamp()); line(utils::string::va("Exception: 0x%08X", exceptioninfo->ExceptionRecord->ExceptionCode)); line(utils::string::va("Address: 0x%llX", exceptioninfo->ExceptionRecord->ExceptionAddress)); - line(utils::string::va("Base: 0x%llX", get_base())); + line(utils::string::va("Base: 0x%llX", game::get_base())); #pragma warning(push) #pragma warning(disable: 4996) diff --git a/src/client/component/scheduler.cpp b/src/client/component/scheduler.cpp index 491d73ad..23978d64 100644 --- a/src/client/component/scheduler.cpp +++ b/src/client/component/scheduler.cpp @@ -3,6 +3,8 @@ #include "scheduler.hpp" +#include "game/game.hpp" + #include #include #include diff --git a/src/client/game/game.cpp b/src/client/game/game.cpp index 0ea62173..7250a2dd 100644 --- a/src/client/game/game.cpp +++ b/src/client/game/game.cpp @@ -1,49 +1,22 @@ #include -#include "loader/component_loader.hpp" #include "game.hpp" +#include namespace game { - // inlined in cod, functionality stolen from https://github.com/id-Software/Quake-III-Arena/blob/master/code/win32/win_syscon.c#L520 - int Conbuf_CleanText(const char* source, char* target) + size_t get_base() { - char* b = target; - int i = 0; - while (source[i] && ((b - target) < sizeof(target) - 1)) + static auto base = [] { - if (source[i] == '\n' && source[i + 1] == '\r') + const utils::nt::library host{}; + if (!host || host == utils::nt::library::get_by_address(get_base)) { - b[0] = '\r'; - b[1] = '\n'; - b += 2; - i++; + throw std::runtime_error("Invalid host application"); } - else if (source[i] == '\r' || source[i] == '\n') - { - b[0] = '\r'; - b[1] = '\n'; - b += 2; - } - else if (source && source[0] == '^' && source[1] && source[1] != '^' && source[1] >= 48 && source[1] <= 64) - // Q_IsColorString - { - i++; - } - else - { - *b = source[i]; // C6011 here, should we be worried? - b++; - } - i++; - } - *b = 0; - return static_cast(b - target); - } - - game::eModes Com_SessionMode_GetMode() - { - return game::eModes(*reinterpret_cast(0x1568EF7F4_g) << 28 >> 28); + return size_t(host.get_ptr()); + }(); + return base; } } diff --git a/src/client/game/game.hpp b/src/client/game/game.hpp index 29f4ee50..77a61919 100644 --- a/src/client/game/game.hpp +++ b/src/client/game/game.hpp @@ -1,15 +1,27 @@ #pragma once #include "structs.hpp" -#include "loader/component_loader.hpp" namespace game { -#define Com_Error(code, fmt, ...) \ - Com_Error_(__FILE__, __LINE__, code, fmt, ##__VA_ARGS__) + size_t get_base(); - int Conbuf_CleanText(const char* source, char* target); - game::eModes Com_SessionMode_GetMode(); + inline size_t relocate(const size_t val) + { + const auto base = get_base(); + return base + (val - 0x140000000); + } + + inline size_t derelocate(const size_t val) + { + const auto base = get_base(); + return (val - base) + 0x140000000; + } + + inline size_t derelocate(const void* val) + { + return derelocate(reinterpret_cast(val)); + } template class symbol @@ -22,7 +34,7 @@ namespace game T* get() const { - return reinterpret_cast(get_game_address(this->address_)); + return reinterpret_cast(relocate(this->address_)); } operator T*() const @@ -43,4 +55,9 @@ namespace game constexpr auto CMD_MAX_NESTING = 8; } +inline size_t operator"" _g(const size_t val) +{ + return game::relocate(val); +} + #include "symbols.hpp" diff --git a/src/client/game/symbols.cpp b/src/client/game/symbols.cpp new file mode 100644 index 00000000..2edede21 --- /dev/null +++ b/src/client/game/symbols.cpp @@ -0,0 +1,11 @@ +#include + +#include "game.hpp" + +namespace game +{ + eModes Com_SessionMode_GetMode() + { + return eModes(*reinterpret_cast(0x1568EF7F4_g) << 28 >> 28); + } +} diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index 5d979adf..091dfabc 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -6,6 +6,9 @@ namespace game { +#define Com_Error(code, fmt, ...) \ + Com_Error_(__FILE__, __LINE__, code, fmt, ##__VA_ARGS__) + // CL WEAK symbol CL_ConnectFromLobby @@ -77,4 +80,7 @@ namespace game WEAK symbol windowWidth{0x157E78068}; WEAK symbol SysInputLineWndProc{0x157E78070}; } + + // Reimplementations + eModes Com_SessionMode_GetMode(); } diff --git a/src/client/loader/component_loader.cpp b/src/client/loader/component_loader.cpp index 614c9fd9..8176866e 100644 --- a/src/client/loader/component_loader.cpp +++ b/src/client/loader/component_loader.cpp @@ -163,40 +163,3 @@ namespace component_loader throw premature_shutdown_trigger(); } } - -size_t get_base() -{ - static auto base = [] - { - const utils::nt::library host{}; - if (!host || host == utils::nt::library::get_by_address(get_base)) - { - throw std::runtime_error("Invalid host application"); - } - - return size_t(host.get_ptr()); - }(); - return base; -} - -size_t get_game_address(const size_t val) -{ - static auto base = get_base(); - return base + (val - 0x140000000); -} - -size_t operator"" _g(const size_t val) -{ - return get_game_address(val); -} - -size_t reverse_g(const size_t val) -{ - static auto base = get_base(); - return (val - base) + 0x140000000; -} - -size_t reverse_g(const void* val) -{ - return reverse_g(reinterpret_cast(val)); -} diff --git a/src/client/loader/component_loader.hpp b/src/client/loader/component_loader.hpp index b743bd0e..f4abb11b 100644 --- a/src/client/loader/component_loader.hpp +++ b/src/client/loader/component_loader.hpp @@ -43,9 +43,3 @@ namespace \ { \ static component_loader::installer __component; \ } - -size_t get_base(); -size_t get_game_address(size_t val); -size_t operator"" _g(size_t val); -size_t reverse_g(size_t val); -size_t reverse_g(const void* val);