From 0e92b04ef9bf5982e693f87f8438354d982b105b Mon Sep 17 00:00:00 2001 From: momo5502 Date: Sun, 17 Aug 2025 17:52:50 +0200 Subject: [PATCH] Log overlapping object access --- src/analyzer/object_watching.hpp | 30 ++++++++++--- src/analyzer/reflect_type_info.hpp | 67 +++++++++++++++++++++--------- 2 files changed, 72 insertions(+), 25 deletions(-) diff --git a/src/analyzer/object_watching.hpp b/src/analyzer/object_watching.hpp index dc8eee7f..f2733047 100644 --- a/src/analyzer/object_watching.hpp +++ b/src/analyzer/object_watching.hpp @@ -31,14 +31,34 @@ emulator_hook* watch_object(windows_emulator& emu, const std::setname.c_str() : ""; const auto& type_name = i.get_type_name(); - const auto member_name = i.get_member_name(static_cast(offset)); - emu.log.print(is_main_access ? color::green : color::dark_gray, - "Object access: %s - 0x%" PRIx64 " 0x%zx (%s) at 0x%" PRIx64 " (%s)\n", type_name.c_str(), offset, size, - member_name.c_str(), rip, mod_name); + for (auto offset = start_offset; offset < end_offset;) + { + const auto member_info = i.get_member_info(static_cast(offset)); + if (!member_info.has_value()) + { + const auto remaining_size = end_offset - offset; + emu.log.print(is_main_access ? color::green : color::dark_gray, + "Object access: %s - 0x%" PRIx64 " 0x%" PRIx64 " () at 0x%" PRIx64 " (%s)\n", type_name.c_str(), + offset, remaining_size, rip, mod_name); + break; + } + + const auto remaining_size = end_offset - offset; + const auto member_end = member_info->offset + member_info->size; + const auto member_access_size = member_end - offset; + const auto access_size = std::min(remaining_size, member_access_size); + + emu.log.print(is_main_access ? color::green : color::dark_gray, + "Object access: %s - 0x%" PRIx64 " 0x%" PRIx64 " (%s) at 0x%" PRIx64 " (%s)\n", type_name.c_str(), offset, + access_size, member_info->get_diff_name(static_cast(offset)).c_str(), rip, mod_name); + + offset = member_end; + } }); } diff --git a/src/analyzer/reflect_type_info.hpp b/src/analyzer/reflect_type_info.hpp index 5cb93bc4..001c6e58 100644 --- a/src/analyzer/reflect_type_info.hpp +++ b/src/analyzer/reflect_type_info.hpp @@ -43,34 +43,61 @@ class reflect_type_info reflect::for_each([this](auto I) { const auto member_name = reflect::member_name(); const auto member_offset = reflect::offset_of(); + const auto member_size = reflect::size_of(); - this->members_[member_offset] = member_name; + this->members_[member_offset] = std::make_pair(std::string(member_name), member_size); }); } std::string get_member_name(const size_t offset) const { - size_t last_offset{}; - std::string_view last_member{}; - - for (const auto& member : this->members_) + const auto info = this->get_member_info(offset); + if (!info.has_value()) { - if (offset == member.first) - { - return member.second; - } - - if (offset < member.first) - { - const auto diff = offset - last_offset; - return std::string(last_member) + "+" + std::to_string(diff); - } - - last_offset = member.first; - last_member = member.second; + return ""; } - return ""; + return info->get_diff_name(offset); + } + + struct member_info + { + std::string name{}; + size_t offset{}; + size_t size{}; + + std::string get_diff_name(const size_t access) const + { + const auto diff = access - this->offset; + if (diff == 0) + { + return this->name; + } + + return this->name + "+" + std::to_string(diff); + } + }; + + std::optional get_member_info(const size_t offset) const + { + auto entry = this->members_.upper_bound(offset); + if (entry == this->members_.begin()) + { + return std::nullopt; + } + + --entry; + + if (entry->first + entry->second.second <= offset) + { + return std::nullopt; + } + + return member_info{ + .name = entry->second.first, + .offset = entry->first, + .size = entry->second.second, + }; } const std::string& get_type_name() const @@ -80,5 +107,5 @@ class reflect_type_info private: std::string type_name_{}; - std::map members_{}; + std::map> members_{}; };