From 55553a40996c97092e03446cfa6b40fe8b2b2e8f Mon Sep 17 00:00:00 2001 From: project-bo4 <127137346+project-bo4@users.noreply.github.com> Date: Sat, 23 Sep 2023 16:17:57 -0700 Subject: [PATCH] some improvements + Improved blackbox's backtracer + Improved json config read/writer --- source/proxy-dll/component/blackbox.cpp | 37 +++--- source/proxy-dll/component/platform.cpp | 2 +- source/shared-code/utils/json_config.cpp | 136 +++++++++++++++++++---- source/shared-code/utils/json_config.hpp | 18 +-- 4 files changed, 149 insertions(+), 44 deletions(-) diff --git a/source/proxy-dll/component/blackbox.cpp b/source/proxy-dll/component/blackbox.cpp index 1308f31..11c08f6 100644 --- a/source/proxy-dll/component/blackbox.cpp +++ b/source/proxy-dll/component/blackbox.cpp @@ -153,12 +153,12 @@ namespace blackbox #undef EXCEPTION_CASE } - std::string get_memory_registers(const LPEXCEPTION_POINTERS exceptioninfo) + std::string get_memory_registers(const LPEXCEPTION_POINTERS exception_info) { - if (IsBadReadPtr(exceptioninfo, sizeof(EXCEPTION_POINTERS))) + if (IsBadReadPtr(exception_info, sizeof(EXCEPTION_POINTERS))) return ""; - const auto* ctx = exceptioninfo->ContextRecord; + const auto* ctx = exception_info->ContextRecord; std::string registers_scroll{}; registers_scroll.append("registers:\r\n{\r\n"); @@ -191,29 +191,36 @@ namespace blackbox return registers_scroll; } - std::string get_callstack_summary(int trace_max_depth = 18) + std::string get_callstack_summary(void* exception_addr, int trace_depth = 32) { std::string callstack_scroll("callstack:\r\n{\r\n"); - void* stack[32]; if (trace_max_depth > 32) trace_max_depth = 32; - uint16_t count = RtlCaptureStackBackTrace(1, trace_max_depth, stack, NULL); - for (uint16_t i = 0; i < count; i++) + void* backtrace_stack[32]; int backtrace_stack_size = ARRAYSIZE(backtrace_stack); + if (trace_depth > backtrace_stack_size) trace_depth = backtrace_stack_size; + + size_t count = RtlCaptureStackBackTrace(0, trace_depth, backtrace_stack, NULL); + + auto itr = std::find(backtrace_stack, backtrace_stack + backtrace_stack_size, exception_addr); + auto exception_start_index = std::distance(backtrace_stack, itr); + + for (size_t i = exception_start_index; i < count; i++) { - const auto prnt = utils::nt::library::get_by_address(stack[i]); - size_t rva = reinterpret_cast(stack[i]) - reinterpret_cast(prnt.get_ptr()); + const auto from = utils::nt::library::get_by_address(backtrace_stack[i]); + size_t rva = reinterpret_cast(backtrace_stack[i]) - reinterpret_cast(from.get_ptr()); - callstack_scroll.append(std::format("\t{}: {:012X}\r\n", prnt.get_name(), rva)); + if (from.get_name() == "BlackOps4.exe"s) rva += 0x140000000; + + callstack_scroll.append(std::format("\t{}: {:012X}\r\n", from.get_name(), rva)); } - callstack_scroll.append("}"); - return callstack_scroll; + return callstack_scroll.append("}"); } std::string generate_crash_info(const LPEXCEPTION_POINTERS exceptioninfo) { - const auto main_module = utils::nt::library{}; const auto& build_info = game::version_string; - const auto thread_id = ::GetCurrentThreadId(); // TODO: Find Thread's Name + const auto main_module = utils::nt::library{}; + const auto rip_address = exceptioninfo->ExceptionRecord->ExceptionAddress; std::string info{}; const auto line = [&info](const std::string& text) @@ -239,7 +246,7 @@ namespace blackbox } line("\r\n"); - line(get_callstack_summary(18)); + line(get_callstack_summary(rip_address)); line(get_memory_registers(exceptioninfo)); line("\r\nTimestamp: "s + get_timestamp()); diff --git a/source/proxy-dll/component/platform.cpp b/source/proxy-dll/component/platform.cpp index cf0f08d..731cf32 100644 --- a/source/proxy-dll/component/platform.cpp +++ b/source/proxy-dll/component/platform.cpp @@ -18,7 +18,7 @@ namespace platform if (!userid) { uint32_t default_xuid = utils::cryptography::xxh32::compute(utils::identity::get_sys_username()); - userid = utils::json_config::ReadUnsignedInteger("identity", "xuid", default_xuid); + userid = utils::json_config::ReadUnsignedInteger64("identity", "xuid", default_xuid); } return userid; diff --git a/source/shared-code/utils/json_config.cpp b/source/shared-code/utils/json_config.cpp index 7f11b5a..9007b6a 100644 --- a/source/shared-code/utils/json_config.cpp +++ b/source/shared-code/utils/json_config.cpp @@ -70,6 +70,41 @@ namespace utils::json_config return section; } + bool ReadBoolean(const char* szSection, const char* szKey, bool bolDefaultValue) + { + rapidjson::Document& doc = get_json_document(); + rapidjson::Value& section = get_json_section(szSection); + + if (!section.HasMember(szKey)) { + section.AddMember(rapidjson::StringRef(szKey), bolDefaultValue, doc.GetAllocator()); + } + else if (!section[szKey].IsBool()) { + section[szKey].SetBool(bolDefaultValue); + } + else { + return section[szKey].GetBool(); + } + + write_json_config(); + return section[szKey].GetBool(); + } + + void WriteBoolean(const char* szSection, const char* szKey, bool bolValue) + { + rapidjson::Document& doc = get_json_document(); + rapidjson::Value& section = get_json_section(szSection); + + if (!section.HasMember(szKey)) { + section.AddMember(rapidjson::StringRef(szKey), bolValue, doc.GetAllocator()); + } + else { + section[szKey].SetBool(bolValue); + } + + write_json_config(); + } + + std::string ReadString(const char* szSection, const char* szKey, const std::string& strDefaultValue) { rapidjson::Document& doc = get_json_document(); @@ -104,7 +139,42 @@ namespace utils::json_config write_json_config(); } - unsigned int ReadUnsignedInteger(const char* szSection, const char* szKey, unsigned int iDefaultValue) + + int32_t ReadInteger(const char* szSection, const char* szKey, int32_t iDefaultValue) + { + rapidjson::Document& doc = get_json_document(); + rapidjson::Value& section = get_json_section(szSection); + + if (!section.HasMember(szKey)) { + section.AddMember(rapidjson::StringRef(szKey), iDefaultValue, doc.GetAllocator()); + } + else if (!section[szKey].IsInt()) { + section[szKey].SetInt(iDefaultValue); + } + else { + return section[szKey].GetInt(); + } + + write_json_config(); + return section[szKey].GetInt(); + } + + void WriteInteger(const char* szSection, const char* szKey, int32_t iValue) + { + rapidjson::Document& doc = get_json_document(); + rapidjson::Value& section = get_json_section(szSection); + + if (!section.HasMember(szKey)) { + section.AddMember(rapidjson::StringRef(szKey), iValue, doc.GetAllocator()); + } + else { + section[szKey].SetInt(iValue); + } + + write_json_config(); + } + + uint32_t ReadUnsignedInteger(const char* szSection, const char* szKey, uint32_t iDefaultValue) { rapidjson::Document& doc = get_json_document(); rapidjson::Value& section = get_json_section(szSection); @@ -123,12 +193,7 @@ namespace utils::json_config return section[szKey].GetUint(); } - int ReadInteger(const char* szSection, const char* szKey, int iDefaultValue) - { - return static_cast(ReadUnsignedInteger(szSection, szKey, static_cast(iDefaultValue))); - } - - void WriteUnsignedInteger(const char* szSection, const char* szKey, unsigned int iValue) + void WriteUnsignedInteger(const char* szSection, const char* szKey, uint32_t iValue) { rapidjson::Document& doc = get_json_document(); rapidjson::Value& section = get_json_section(szSection); @@ -143,40 +208,69 @@ namespace utils::json_config write_json_config(); } - void WriteInteger(const char* szSection, const char* szKey, int iValue) - { - ReadUnsignedInteger(szSection, szKey, static_cast(iValue)); - } - - bool ReadBoolean(const char* szSection, const char* szKey, bool bolDefaultValue) + int64_t ReadInteger64(const char* szSection, const char* szKey, int64_t iDefaultValue) { rapidjson::Document& doc = get_json_document(); rapidjson::Value& section = get_json_section(szSection); if (!section.HasMember(szKey)) { - section.AddMember(rapidjson::StringRef(szKey), bolDefaultValue, doc.GetAllocator()); + section.AddMember(rapidjson::StringRef(szKey), iDefaultValue, doc.GetAllocator()); } - else if (!section[szKey].IsBool()) { - section[szKey].SetBool(bolDefaultValue); + else if (!section[szKey].IsInt64()) { + section[szKey].SetInt64(iDefaultValue); } else { - return section[szKey].GetBool(); + return section[szKey].GetInt64(); } write_json_config(); - return section[szKey].GetBool(); + return section[szKey].GetInt64(); } - void WriteBoolean(const char* szSection, const char* szKey, bool bolValue) + void WriteInteger64(const char* szSection, const char* szKey, int64_t iValue) { rapidjson::Document& doc = get_json_document(); rapidjson::Value& section = get_json_section(szSection); if (!section.HasMember(szKey)) { - section.AddMember(rapidjson::StringRef(szKey), bolValue, doc.GetAllocator()); + section.AddMember(rapidjson::StringRef(szKey), iValue, doc.GetAllocator()); } else { - section[szKey].SetBool(bolValue); + section[szKey].SetInt64(iValue); + } + + write_json_config(); + } + + uint64_t ReadUnsignedInteger64(const char* szSection, const char* szKey, uint64_t iDefaultValue) + { + rapidjson::Document& doc = get_json_document(); + rapidjson::Value& section = get_json_section(szSection); + + if (!section.HasMember(szKey)) { + section.AddMember(rapidjson::StringRef(szKey), iDefaultValue, doc.GetAllocator()); + } + else if (!section[szKey].IsUint64()) { + section[szKey].SetUint64(iDefaultValue); + } + else { + return section[szKey].GetUint64(); + } + + write_json_config(); + return section[szKey].GetUint64(); + } + + void WriteUnsignedInteger64(const char* szSection, const char* szKey, uint64_t iValue) + { + rapidjson::Document& doc = get_json_document(); + rapidjson::Value& section = get_json_section(szSection); + + if (!section.HasMember(szKey)) { + section.AddMember(rapidjson::StringRef(szKey), iValue, doc.GetAllocator()); + } + else { + section[szKey].SetUint64(iValue); } write_json_config(); diff --git a/source/shared-code/utils/json_config.hpp b/source/shared-code/utils/json_config.hpp index 4361e7a..249ed4e 100644 --- a/source/shared-code/utils/json_config.hpp +++ b/source/shared-code/utils/json_config.hpp @@ -3,15 +3,19 @@ namespace utils::json_config { + bool ReadBoolean(const char* szSection, const char* szKey, bool bolDefaultValue); + void WriteBoolean(const char* szSection, const char* szKey, bool bolValue); + std::string ReadString(const char* szSection, const char* szKey, const std::string& strDefaultValue); void WriteString(const char* szSection, const char* szKey, const std::string& strValue); - unsigned int ReadUnsignedInteger(const char* szSection, const char* szKey, unsigned int iDefaultValue); - void WriteUnsignedInteger(const char* szSection, const char* szKey, unsigned int iValue); + int32_t ReadInteger(const char* szSection, const char* szKey, int32_t iDefaultValue); + void WriteInteger(const char* szSection, const char* szKey, int32_t iValue); + uint32_t ReadUnsignedInteger(const char* szSection, const char* szKey, uint32_t iDefaultValue); + void WriteUnsignedInteger(const char* szSection, const char* szKey, uint32_t iValue); - int ReadInteger(const char* szSection, const char* szKey, int iDefaultValue); - void WriteInteger(const char* szSection, const char* szKey, int iValue); - - bool ReadBoolean(const char* szSection, const char* szKey, bool bolDefaultValue); - void WriteBoolean(const char* szSection, const char* szKey, bool bolValue); + int64_t ReadInteger64(const char* szSection, const char* szKey, int64_t iDefaultValue); + void WriteInteger64(const char* szSection, const char* szKey, int64_t iValue); + uint64_t ReadUnsignedInteger64(const char* szSection, const char* szKey, uint64_t iDefaultValue); + void WriteUnsignedInteger64(const char* szSection, const char* szKey, uint64_t iValue); }