From 453ed0d431ceec371e15d64eecf47a0fcab6c3a9 Mon Sep 17 00:00:00 2001 From: Mark Rowe Date: Wed, 13 Nov 2024 15:48:14 -0800 Subject: [PATCH] [SharedCache] Rework metadata serialization to reduce memory overhead api/MetadataSerializable.hpp is removed in favor of including core/MetadataSerializable.hpp. Both headers defined types with the same name leading to One Definition Rule violations and surprising behavior. The serialization and deserialization context are now created on-demand during serialization rather than being a member of `MetadataSerializable`. This reduces the size of every serializable object by ~220 bytes. The context is passed explicitly as an argument to `Serialize` / `Deserialize`. As a result, `Serialize` / `Deserialize` can now be free functions rather than member functions. Since `MetadataSerializable` is not used for dynamic dispatch, the virtual methods are removed and the class is updated to be a class template using CRTP. This allows delegating to the derived class's `Load` and `Store` methods without the additional size overhead of the vtable pointer in every serializable object. These changes reduce the memory footprint of Binary Ninja after loading the macOS shared cache and loading a single dylib from it from 8.3GB to 4.6GB. --- view/sharedcache/api/MetadataSerializable.hpp | 500 ----------- view/sharedcache/api/sharedcache.cpp | 395 +++++++++ view/sharedcache/api/sharedcacheapi.h | 439 +--------- .../sharedcache/core/MetadataSerializable.hpp | 820 +++++++++--------- view/sharedcache/core/SharedCache.cpp | 404 +++++++++ view/sharedcache/core/SharedCache.h | 573 ++---------- 6 files changed, 1325 insertions(+), 1806 deletions(-) delete mode 100644 view/sharedcache/api/MetadataSerializable.hpp diff --git a/view/sharedcache/api/MetadataSerializable.hpp b/view/sharedcache/api/MetadataSerializable.hpp deleted file mode 100644 index dd3951ea7f..0000000000 --- a/view/sharedcache/api/MetadataSerializable.hpp +++ /dev/null @@ -1,500 +0,0 @@ -// -// Created by kat on 5/31/23. -// - -/* - * Welcome to, this file. - * - * This is a metadata serialization helper. - * - * Have you ever wished turning a complex datastructure into a Metadata object was as easy in C++ as it is in python? - * Do you like macros and templates? - * - * Great news. - * - * Implement these on your `public MetadataSerializable` subclass: - * ``` - void Store() override { - MSS(m_someVariable); - MSS(m_someOtherVariable); - } - void Load() override { - MSL(m_someVariable); - MSL(m_someOtherVariable); - } - ``` - * Then, you can turn your object into a Metadata object with `AsMetadata()`, and load it back with - `LoadFromMetadata()`. - * - * Serialized fields will be automatically repopulated. - * - * Other ser/deser formats (rapidjson objects, strings) also exist. You can use these to achieve nesting, but probably - avoid that. - * */ - -#include "binaryninjaapi.h" -#include "rapidjson/document.h" -#include "rapidjson/stringbuffer.h" -#include "rapidjson/prettywriter.h" - -#ifndef SHAREDCACHE_METADATASERIALIZABLE_HPP -#define SHAREDCACHE_METADATASERIALIZABLE_HPP - -#define MSS(name) store(#name, name) -#define MSS_CAST(name, type) store(#name, (type) name) -#define MSS_SUBCLASS(name) Serialize(#name, name) -#define MSL(name) name = load(#name, name) -#define MSL_CAST(name, storedType, type) name = (type)load(#name, (storedType) name) -#define MSL_SUBCLASS(name) Deserialize(#name, name) - -using namespace BinaryNinja; - -class MetadataSerializable -{ -protected: - struct SerialContext - { - rapidjson::Document doc; - rapidjson::Document::AllocatorType allocator; - }; - struct DeserContext - { - rapidjson::Document doc; - }; - - DeserContext m_activeDeserContext; - SerialContext m_activeContext; - -public: - MetadataSerializable() - { - m_activeContext.doc.SetObject(); - m_activeContext.allocator = m_activeContext.doc.GetAllocator(); - } - - // copy constructor - MetadataSerializable(const MetadataSerializable& other) - { - m_activeContext.doc.CopyFrom(other.m_activeContext.doc, m_activeContext.doc.GetAllocator()); - } - - // copy assignment - MetadataSerializable& operator=(const MetadataSerializable& other) - { - m_activeContext.doc.CopyFrom(other.m_activeContext.doc, m_activeContext.doc.GetAllocator()); - return *this; - } - - virtual ~MetadataSerializable() - { - } - - void SetupSerContext(rapidjson::Document::AllocatorType* alloc = nullptr) - { - m_activeContext.doc.SetObject(); - m_activeContext.allocator = m_activeContext.doc.GetAllocator(); - } - void S() - { - // fixme factor out - } - void Serialize(std::string& name, bool b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - m_activeContext.doc.AddMember(key, b, m_activeContext.allocator); - } - void Deserialize(std::string& name, bool& b) { b = m_activeDeserContext.doc[name.c_str()].GetBool(); } - - void Serialize(std::string& name, uint8_t b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - m_activeContext.doc.AddMember(key, b, m_activeContext.allocator); - } - void Deserialize(std::string& name, uint8_t& b) - { - b = static_cast(m_activeDeserContext.doc[name.c_str()].GetUint64()); - } - - void Serialize(std::string& name, uint16_t b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - m_activeContext.doc.AddMember(key, b, m_activeContext.allocator); - } - void Deserialize(std::string& name, uint16_t& b) - { - b = static_cast(m_activeDeserContext.doc[name.c_str()].GetUint64()); - } - - void Serialize(std::string& name, uint32_t b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - m_activeContext.doc.AddMember(key, b, m_activeContext.allocator); - } - void Deserialize(std::string& name, uint32_t& b) - { - b = static_cast(m_activeDeserContext.doc[name.c_str()].GetUint64()); - } - - void Serialize(std::string& name, uint64_t b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - m_activeContext.doc.AddMember(key, b, m_activeContext.allocator); - } - void Deserialize(std::string& name, uint64_t& b) - { - b = m_activeDeserContext.doc[name.c_str()].GetUint64(); - } - - void Serialize(std::string& name, int8_t b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - m_activeContext.doc.AddMember(key, b, m_activeContext.allocator); - } - void Deserialize(std::string& name, int8_t& b) - { - b = m_activeDeserContext.doc[name.c_str()].GetInt64(); - } - - void Serialize(std::string& name, int16_t b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - m_activeContext.doc.AddMember(key, b, m_activeContext.allocator); - } - void Deserialize(std::string& name, int16_t& b) - { - b = m_activeDeserContext.doc[name.c_str()].GetInt64(); - } - - void Serialize(std::string& name, int32_t b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - m_activeContext.doc.AddMember(key, b, m_activeContext.allocator); - } - void Deserialize(std::string& name, int32_t& b) - { - b = m_activeDeserContext.doc[name.c_str()].GetInt(); - } - - void Serialize(std::string& name, int64_t b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - m_activeContext.doc.AddMember(key, b, m_activeContext.allocator); - } - void Deserialize(std::string& name, int64_t& b) - { - b = m_activeDeserContext.doc[name.c_str()].GetInt64(); - } - - void Serialize(std::string& name, std::string b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value value(b.c_str(), m_activeContext.allocator); - m_activeContext.doc.AddMember(key, value, m_activeContext.allocator); - } - void Deserialize(std::string& name, std::string& b) - { - b = m_activeDeserContext.doc[name.c_str()].GetString(); - } - - void Serialize(std::string& name, std::map b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& i : b) - { - rapidjson::Value p(rapidjson::kArrayType); - p.PushBack(i.first, m_activeContext.allocator); - rapidjson::Value value(i.second.c_str(), m_activeContext.allocator); - p.PushBack(value, m_activeContext.allocator); - bArr.PushBack(p, m_activeContext.allocator); - } - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); - } - void Deserialize(std::string& name, std::map& b) - { - for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray()) - b[i.GetArray()[0].GetUint64()] = i.GetArray()[1].GetString(); - } - - void Serialize(std::string& name, std::unordered_map b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& i : b) - { - rapidjson::Value p(rapidjson::kArrayType); - p.PushBack(i.first, m_activeContext.allocator); - rapidjson::Value value(i.second.c_str(), m_activeContext.allocator); - p.PushBack(value, m_activeContext.allocator); - bArr.PushBack(p, m_activeContext.allocator); - } - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); - } - - void Serialize(std::string& name, std::unordered_map b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& i : b) - { - rapidjson::Value p(rapidjson::kArrayType); - rapidjson::Value key(i.first.c_str(), m_activeContext.allocator); - rapidjson::Value value(i.second.c_str(), m_activeContext.allocator); - p.PushBack(key, m_activeContext.allocator); - p.PushBack(value, m_activeContext.allocator); - bArr.PushBack(p, m_activeContext.allocator); - } - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); - } - void Deserialize(std::string& name, std::unordered_map& b) - { - for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray()) - b[i.GetArray()[0].GetUint64()] = i.GetArray()[1].GetString(); - } - - void Serialize(std::string& name, std::unordered_map b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& i : b) - { - rapidjson::Value p(rapidjson::kArrayType); - p.PushBack(i.first, m_activeContext.allocator); - p.PushBack(i.second, m_activeContext.allocator); - bArr.PushBack(p, m_activeContext.allocator); - } - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); - } - void Deserialize(std::string& name, std::unordered_map& b) - { - for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray()) - b[i.GetArray()[0].GetUint64()] = i.GetArray()[1].GetUint64(); - } - - // std::unordered_map> - void Serialize(std::string& name, std::unordered_map> b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value classes(rapidjson::kArrayType); - for (auto& i : b) - { - rapidjson::Value classArr(rapidjson::kArrayType); - rapidjson::Value classKey(i.first.c_str(), m_activeContext.allocator); - classArr.PushBack(classKey, m_activeContext.allocator); - rapidjson::Value membersArr(rapidjson::kArrayType); - for (auto& j : i.second) - { - rapidjson::Value member(rapidjson::kArrayType); - member.PushBack(j.first, m_activeContext.allocator); - member.PushBack(j.second, m_activeContext.allocator); - membersArr.PushBack(member, m_activeContext.allocator); - } - classArr.PushBack(membersArr, m_activeContext.allocator); - classes.PushBack(classArr, m_activeContext.allocator); - } - m_activeContext.doc.AddMember(key, classes, m_activeContext.allocator); - } - void Deserialize(std::string& name, std::unordered_map>& b) - { - for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray()) - { - std::string key = i.GetArray()[0].GetString(); - std::unordered_map memArray; - for (auto& member : i.GetArray()[1].GetArray()) - { - memArray[member.GetArray()[0].GetUint64()] = member.GetArray()[1].GetUint64(); - } - b[key] = memArray; - } - } - - void Deserialize(std::string& name, std::unordered_map& b) - { - for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray()) - b[i.GetArray()[0].GetString()] = i.GetArray()[1].GetString(); - } - - void Serialize(std::string& name, std::vector b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (const auto& s : b) - { - rapidjson::Value value(s.c_str(), m_activeContext.allocator); - bArr.PushBack(value, m_activeContext.allocator); - } - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); - } - void Deserialize(std::string& name, std::vector& b) - { - for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray()) - b.emplace_back(i.GetString()); - } - - void Serialize(std::string& name, std::vector>> b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& i : b) - { - rapidjson::Value segV(rapidjson::kArrayType); - segV.PushBack(i.first, m_activeContext.allocator); - segV.PushBack(i.second.first, m_activeContext.allocator); - segV.PushBack(i.second.second, m_activeContext.allocator); - bArr.PushBack(segV, m_activeContext.allocator); - } - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); - } - void Deserialize(std::string& name, std::vector>>& b) - { - for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray()) - { - std::pair> j; - j.first = i.GetArray()[0].GetUint64(); - j.second.first = i.GetArray()[1].GetUint64(); - j.second.second = i.GetArray()[2].GetUint64(); - b.push_back(j); - } - } - - void Serialize(std::string& name, std::vector> b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& i : b) - { - rapidjson::Value segV(rapidjson::kArrayType); - segV.PushBack(i.first, m_activeContext.allocator); - segV.PushBack(i.second, m_activeContext.allocator); - bArr.PushBack(segV, m_activeContext.allocator); - } - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); - } - void Deserialize(std::string& name, std::vector>& b) - { - for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray()) - { - std::pair j; - j.first = i.GetArray()[0].GetUint64(); - j.second = i.GetArray()[1].GetBool(); - b.push_back(j); - } - } - - void Serialize(std::string& name, std::vector b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& i : b) - { - bArr.PushBack(i, m_activeContext.allocator); - } - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); - } - void Deserialize(std::string& name, std::vector& b) - { - for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray()) - { - b.push_back(i.GetUint64()); - } - } - - // std::unordered_map - void Serialize(std::string& name, std::unordered_map b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& i : b) - { - rapidjson::Value p(rapidjson::kArrayType); - rapidjson::Value key(i.first.c_str(), m_activeContext.allocator); - p.PushBack(key, m_activeContext.allocator); - p.PushBack(i.second, m_activeContext.allocator); - bArr.PushBack(p, m_activeContext.allocator); - } - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); - } - void Deserialize(std::string& name, std::unordered_map& b) - { - for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray()) - { - b[i.GetArray()[0].GetString()] = i.GetArray()[1].GetUint64(); - } - } - - template - void store(std::string x, T y) - { - Serialize(x, y); - } - - template - T load(std::string x, T y) - { - T val; - Deserialize(x, val); - return val; - } - - rapidjson::Document& GetDoc() - { - S(); - Store(); - return m_activeContext.doc; - } - -public: - virtual void Store() = 0; - virtual void Load() = 0; - - std::string AsString() - { - rapidjson::StringBuffer strbuf; - rapidjson::PrettyWriter writer(strbuf); - GetDoc().Accept(writer); - - std::string s = strbuf.GetString(); - return s; - } - rapidjson::Document& AsDocument() { return GetDoc(); } - void LoadFromString(const std::string& s) - { - m_activeDeserContext.doc.Parse(s.c_str()); - Load(); - } - void LoadFromValue(rapidjson::Value& s) - { - m_activeDeserContext.doc.CopyFrom(s, m_activeDeserContext.doc.GetAllocator()); - Load(); - } - Ref AsMetadata() { return new Metadata(AsString()); } - bool LoadFromMetadata(const Ref& meta) - { - if (!meta->IsString()) - return false; - LoadFromString(meta->GetString()); - return true; - } -}; - -#endif // SHAREDCACHE_METADATASERIALIZABLE_HPP diff --git a/view/sharedcache/api/sharedcache.cpp b/view/sharedcache/api/sharedcache.cpp index 5ca7c480eb..45ca6377f6 100644 --- a/view/sharedcache/api/sharedcache.cpp +++ b/view/sharedcache/api/sharedcache.cpp @@ -221,4 +221,399 @@ namespace SharedCacheAPI { { BNDSCFindSymbolAtAddressAndApplyToAddress(m_object, symbolLocation, targetLocation, triggerReanalysis); } + + +void Serialize(SharedCacheCore::SerializationContext& context, std::string_view name, const mach_header_64& b) +{ + rapidjson::Value key(name.data(), context.allocator); + rapidjson::Value bArr(rapidjson::kArrayType); + bArr.PushBack(b.magic, context.allocator); + bArr.PushBack(b.cputype, context.allocator); + bArr.PushBack(b.cpusubtype, context.allocator); + bArr.PushBack(b.filetype, context.allocator); + bArr.PushBack(b.ncmds, context.allocator); + bArr.PushBack(b.sizeofcmds, context.allocator); + bArr.PushBack(b.flags, context.allocator); + bArr.PushBack(b.reserved, context.allocator); + context.doc.AddMember(key, bArr, context.allocator); +} + +void Deserialize(SharedCacheCore::DeserializationContext& context, std::string_view name, mach_header_64& b) +{ + auto bArr = context.doc[name.data()].GetArray(); + b.magic = bArr[0].GetInt64(); + b.cputype = bArr[1].GetInt64(); + b.cpusubtype = bArr[2].GetInt64(); + b.filetype = bArr[3].GetInt64(); + b.ncmds = bArr[4].GetInt64(); + b.sizeofcmds = bArr[5].GetInt64(); + b.flags = bArr[6].GetInt64(); + b.reserved = bArr[7].GetInt64(); +} + +void Serialize(SharedCacheCore::SerializationContext& context, std::string_view name, const symtab_command& b) +{ + rapidjson::Value key(name.data(), context.allocator); + rapidjson::Value bArr(rapidjson::kArrayType); + bArr.PushBack(b.cmd, context.allocator); + bArr.PushBack(b.cmdsize, context.allocator); + bArr.PushBack(b.symoff, context.allocator); + bArr.PushBack(b.nsyms, context.allocator); + bArr.PushBack(b.stroff, context.allocator); + bArr.PushBack(b.strsize, context.allocator); + context.doc.AddMember(key, bArr, context.allocator); +} + +void Deserialize(SharedCacheCore::DeserializationContext& context, std::string_view name, symtab_command& b) +{ + auto bArr = context.doc[name.data()].GetArray(); + b.cmd = bArr[0].GetUint(); + b.cmdsize = bArr[1].GetUint(); + b.symoff = bArr[2].GetUint(); + b.nsyms = bArr[3].GetUint(); + b.stroff = bArr[4].GetUint(); + b.strsize = bArr[5].GetUint(); +} + +void Serialize(SharedCacheCore::SerializationContext& context, std::string_view name, const dysymtab_command& b) +{ + rapidjson::Value key(name.data(), context.allocator); + rapidjson::Value bArr(rapidjson::kArrayType); + bArr.PushBack(b.cmd, context.allocator); + bArr.PushBack(b.cmdsize, context.allocator); + bArr.PushBack(b.ilocalsym, context.allocator); + bArr.PushBack(b.nlocalsym, context.allocator); + bArr.PushBack(b.iextdefsym, context.allocator); + bArr.PushBack(b.nextdefsym, context.allocator); + bArr.PushBack(b.iundefsym, context.allocator); + bArr.PushBack(b.nundefsym, context.allocator); + bArr.PushBack(b.tocoff, context.allocator); + bArr.PushBack(b.ntoc, context.allocator); + bArr.PushBack(b.modtaboff, context.allocator); + bArr.PushBack(b.nmodtab, context.allocator); + bArr.PushBack(b.extrefsymoff, context.allocator); + bArr.PushBack(b.nextrefsyms, context.allocator); + bArr.PushBack(b.indirectsymoff, context.allocator); + bArr.PushBack(b.nindirectsyms, context.allocator); + bArr.PushBack(b.extreloff, context.allocator); + bArr.PushBack(b.nextrel, context.allocator); + bArr.PushBack(b.locreloff, context.allocator); + bArr.PushBack(b.nlocrel, context.allocator); + context.doc.AddMember(key, bArr, context.allocator); +} + +void Deserialize(SharedCacheCore::DeserializationContext& context, std::string_view name, dysymtab_command& b) +{ + auto bArr = context.doc[name.data()].GetArray(); + b.cmd = bArr[0].GetUint(); + b.cmdsize = bArr[1].GetUint(); + b.ilocalsym = bArr[2].GetUint(); + b.nlocalsym = bArr[3].GetUint(); + b.iextdefsym = bArr[4].GetUint(); + b.nextdefsym = bArr[5].GetUint(); + b.iundefsym = bArr[6].GetUint(); + b.nundefsym = bArr[7].GetUint(); + b.tocoff = bArr[8].GetUint(); + b.ntoc = bArr[9].GetUint(); + b.modtaboff = bArr[10].GetUint(); + b.nmodtab = bArr[11].GetUint(); + b.extrefsymoff = bArr[12].GetUint(); + b.nextrefsyms = bArr[13].GetUint(); + b.indirectsymoff = bArr[14].GetUint(); + b.nindirectsyms = bArr[15].GetUint(); + b.extreloff = bArr[16].GetUint(); + b.nextrel = bArr[17].GetUint(); + b.locreloff = bArr[18].GetUint(); + b.nlocrel = bArr[19].GetUint(); +} + +void Serialize(SharedCacheCore::SerializationContext& context, std::string_view name, const dyld_info_command& b) +{ + rapidjson::Value key(name.data(), context.allocator); + rapidjson::Value bArr(rapidjson::kArrayType); + bArr.PushBack(b.cmd, context.allocator); + bArr.PushBack(b.cmdsize, context.allocator); + bArr.PushBack(b.rebase_off, context.allocator); + bArr.PushBack(b.rebase_size, context.allocator); + bArr.PushBack(b.bind_off, context.allocator); + bArr.PushBack(b.bind_size, context.allocator); + bArr.PushBack(b.weak_bind_off, context.allocator); + bArr.PushBack(b.weak_bind_size, context.allocator); + bArr.PushBack(b.lazy_bind_off, context.allocator); + bArr.PushBack(b.lazy_bind_size, context.allocator); + bArr.PushBack(b.export_off, context.allocator); + bArr.PushBack(b.export_size, context.allocator); + context.doc.AddMember(key, bArr, context.allocator); +} + +void Deserialize(SharedCacheCore::DeserializationContext& context, std::string_view name, dyld_info_command& b) +{ + auto bArr = context.doc[name.data()].GetArray(); + b.cmd = bArr[0].GetUint(); + b.cmdsize = bArr[1].GetUint(); + b.rebase_off = bArr[2].GetUint(); + b.rebase_size = bArr[3].GetUint(); + b.bind_off = bArr[4].GetUint(); + b.bind_size = bArr[5].GetUint(); + b.weak_bind_off = bArr[6].GetUint(); + b.weak_bind_size = bArr[7].GetUint(); + b.lazy_bind_off = bArr[8].GetUint(); + b.lazy_bind_size = bArr[9].GetUint(); + b.export_off = bArr[10].GetUint(); + b.export_size = bArr[11].GetUint(); +} + +void Serialize(SharedCacheCore::SerializationContext& context, std::string_view name, const routines_command_64& b) +{ + rapidjson::Value key(name.data(), context.allocator); + rapidjson::Value bArr(rapidjson::kArrayType); + bArr.PushBack(b.cmd, context.allocator); + bArr.PushBack(b.cmdsize, context.allocator); + bArr.PushBack(b.init_address, context.allocator); + bArr.PushBack(b.init_module, context.allocator); + context.doc.AddMember(key, bArr, context.allocator); +} + +void Deserialize(SharedCacheCore::DeserializationContext& context, std::string_view name, routines_command_64& b) +{ + auto bArr = context.doc[name.data()].GetArray(); + b.cmd = bArr[0].GetUint(); + b.cmdsize = bArr[1].GetUint(); + b.init_address = bArr[2].GetUint(); + b.init_module = bArr[3].GetUint(); +} + +void Serialize(SharedCacheCore::SerializationContext& context, std::string_view name, const function_starts_command& b) +{ + rapidjson::Value key(name.data(), context.allocator); + rapidjson::Value bArr(rapidjson::kArrayType); + bArr.PushBack(b.cmd, context.allocator); + bArr.PushBack(b.cmdsize, context.allocator); + bArr.PushBack(b.funcoff, context.allocator); + bArr.PushBack(b.funcsize, context.allocator); + context.doc.AddMember(key, bArr, context.allocator); +} + +void Deserialize(SharedCacheCore::DeserializationContext& context, std::string_view name, function_starts_command& b) +{ + auto bArr = context.doc[name.data()].GetArray(); + b.cmd = bArr[0].GetUint(); + b.cmdsize = bArr[1].GetUint(); + b.funcoff = bArr[2].GetUint(); + b.funcsize = bArr[3].GetUint(); +} + +void Serialize(SharedCacheCore::SerializationContext& context, std::string_view name, const std::vector& b) +{ + rapidjson::Value key(name.data(), context.allocator); + rapidjson::Value bArr(rapidjson::kArrayType); + for (auto& s : b) + { + rapidjson::Value sArr(rapidjson::kArrayType); + std::string sectNameStr; + char sectName[16]; + memcpy(sectName, s.sectname, 16); + sectName[15] = 0; + sectNameStr = std::string(sectName); + sArr.PushBack(rapidjson::Value(sectNameStr.c_str(), context.allocator), context.allocator); + std::string segNameStr; + char segName[16]; + memcpy(segName, s.segname, 16); + segName[15] = 0; + segNameStr = std::string(segName); + sArr.PushBack(rapidjson::Value(segNameStr.c_str(), context.allocator), context.allocator); + sArr.PushBack(s.addr, context.allocator); + sArr.PushBack(s.size, context.allocator); + sArr.PushBack(s.offset, context.allocator); + sArr.PushBack(s.align, context.allocator); + sArr.PushBack(s.reloff, context.allocator); + sArr.PushBack(s.nreloc, context.allocator); + sArr.PushBack(s.flags, context.allocator); + sArr.PushBack(s.reserved1, context.allocator); + sArr.PushBack(s.reserved2, context.allocator); + sArr.PushBack(s.reserved3, context.allocator); + bArr.PushBack(sArr, context.allocator); + } + context.doc.AddMember(key, bArr, context.allocator); +} + +void Deserialize(SharedCacheCore::DeserializationContext& context, std::string_view name, std::vector& b) +{ + auto bArr = context.doc[name.data()].GetArray(); + for (auto& s : bArr) + { + section_64 sec; + auto s2 = s.GetArray(); + std::string sectNameStr = s2[0].GetString(); + memcpy(sec.sectname, sectNameStr.c_str(), sectNameStr.size()); + std::string segNameStr = s2[1].GetString(); + memcpy(sec.segname, segNameStr.c_str(), segNameStr.size()); + sec.addr = s2[2].GetUint64(); + sec.size = s2[3].GetUint64(); + sec.offset = s2[4].GetUint(); + sec.align = s2[5].GetUint(); + sec.reloff = s2[6].GetUint(); + sec.nreloc = s2[7].GetUint(); + sec.flags = s2[8].GetUint(); + sec.reserved1 = s2[9].GetUint(); + sec.reserved2 = s2[10].GetUint(); + sec.reserved3 = s2[11].GetUint(); + b.push_back(sec); + } +} + +void Serialize(SharedCacheCore::SerializationContext& context, std::string_view name, const linkedit_data_command& b) +{ + rapidjson::Value key(name.data(), context.allocator); + rapidjson::Value bArr(rapidjson::kArrayType); + bArr.PushBack(b.cmd, context.allocator); + bArr.PushBack(b.cmdsize, context.allocator); + bArr.PushBack(b.dataoff, context.allocator); + bArr.PushBack(b.datasize, context.allocator); + context.doc.AddMember(key, bArr, context.allocator); +} + +void Deserialize(SharedCacheCore::DeserializationContext& context, std::string_view name, linkedit_data_command& b) +{ + auto bArr = context.doc[name.data()].GetArray(); + b.cmd = bArr[0].GetUint(); + b.cmdsize = bArr[1].GetUint(); + b.dataoff = bArr[2].GetUint(); + b.datasize = bArr[3].GetUint(); +} + +void Serialize(SharedCacheCore::SerializationContext& context, std::string_view name, const segment_command_64& b) +{ + rapidjson::Value key(name.data(), context.allocator); + rapidjson::Value bArr(rapidjson::kArrayType); + std::string segNameStr; + char segName[16]; + memcpy(segName, b.segname, 16); + segName[15] = 0; + segNameStr = std::string(segName); + bArr.PushBack(rapidjson::Value(segNameStr.c_str(), context.allocator), context.allocator); + bArr.PushBack(b.vmaddr, context.allocator); + bArr.PushBack(b.vmsize, context.allocator); + bArr.PushBack(b.fileoff, context.allocator); + bArr.PushBack(b.filesize, context.allocator); + bArr.PushBack(b.maxprot, context.allocator); + bArr.PushBack(b.initprot, context.allocator); + bArr.PushBack(b.nsects, context.allocator); + bArr.PushBack(b.flags, context.allocator); + context.doc.AddMember(key, bArr, context.allocator); +} + +void Deserialize(SharedCacheCore::DeserializationContext& context, std::string_view name, segment_command_64& b) +{ + auto bArr = context.doc[name.data()].GetArray(); + std::string segNameStr = bArr[0].GetString(); + memcpy(b.segname, segNameStr.c_str(), segNameStr.size()); + b.vmaddr = bArr[1].GetUint64(); + b.vmsize = bArr[2].GetUint64(); + b.fileoff = bArr[3].GetUint64(); + b.filesize = bArr[4].GetUint64(); + b.maxprot = bArr[5].GetUint(); + b.initprot = bArr[6].GetUint(); + b.nsects = bArr[7].GetUint(); + b.flags = bArr[8].GetUint(); +} + +void Serialize(SharedCacheCore::SerializationContext& context, std::string_view name, const std::vector& b) +{ + rapidjson::Value key(name.data(), context.allocator); + rapidjson::Value bArr(rapidjson::kArrayType); + for (auto& s : b) + { + rapidjson::Value sArr(rapidjson::kArrayType); + std::string segNameStr; + char segName[16]; + memcpy(segName, s.segname, 16); + segName[15] = 0; + segNameStr = std::string(segName); + sArr.PushBack(rapidjson::Value(segNameStr.c_str(), context.allocator), context.allocator); + sArr.PushBack(s.vmaddr, context.allocator); + sArr.PushBack(s.vmsize, context.allocator); + sArr.PushBack(s.fileoff, context.allocator); + sArr.PushBack(s.filesize, context.allocator); + sArr.PushBack(s.maxprot, context.allocator); + sArr.PushBack(s.initprot, context.allocator); + sArr.PushBack(s.nsects, context.allocator); + sArr.PushBack(s.flags, context.allocator); + bArr.PushBack(sArr, context.allocator); + } + context.doc.AddMember(key, bArr, context.allocator); +} + +void Deserialize(SharedCacheCore::DeserializationContext& context, std::string_view name, std::vector& b) +{ + auto bArr = context.doc[name.data()].GetArray(); + for (auto& s : bArr) + { + segment_command_64 sec; + auto s2 = s.GetArray(); + std::string segNameStr = s2[0].GetString(); + memcpy(sec.segname, segNameStr.c_str(), segNameStr.size()); + sec.vmaddr = s2[1].GetUint64(); + sec.vmsize = s2[2].GetUint64(); + sec.fileoff = s2[3].GetUint64(); + sec.filesize = s2[4].GetUint64(); + sec.maxprot = s2[5].GetUint(); + sec.initprot = s2[6].GetUint(); + sec.nsects = s2[7].GetUint(); + sec.flags = s2[8].GetUint(); + b.push_back(sec); + } +} + +void Serialize(SharedCacheCore::SerializationContext& context, std::string_view name, const build_version_command& b) +{ + rapidjson::Value key(name.data(), context.allocator); + rapidjson::Value bArr(rapidjson::kArrayType); + bArr.PushBack(b.cmd, context.allocator); + bArr.PushBack(b.cmdsize, context.allocator); + bArr.PushBack(b.platform, context.allocator); + bArr.PushBack(b.minos, context.allocator); + bArr.PushBack(b.sdk, context.allocator); + bArr.PushBack(b.ntools, context.allocator); + context.doc.AddMember(key, bArr, context.allocator); +} + +void Deserialize(SharedCacheCore::DeserializationContext& context, std::string_view name, build_version_command& b) +{ + auto bArr = context.doc[name.data()].GetArray(); + b.cmd = bArr[0].GetUint(); + b.cmdsize = bArr[1].GetUint(); + b.platform = bArr[2].GetUint(); + b.minos = bArr[3].GetUint(); + b.sdk = bArr[4].GetUint(); + b.ntools = bArr[5].GetUint(); +} + +void Serialize(SharedCacheCore::SerializationContext& context, std::string_view name, const std::vector& b) +{ + rapidjson::Value key(name.data(), context.allocator); + rapidjson::Value bArr(rapidjson::kArrayType); + for (auto& s : b) + { + rapidjson::Value sArr(rapidjson::kArrayType); + sArr.PushBack(s.tool, context.allocator); + sArr.PushBack(s.version, context.allocator); + bArr.PushBack(sArr, context.allocator); + } + context.doc.AddMember(key, bArr, context.allocator); +} + +void Deserialize(SharedCacheCore::DeserializationContext& context, std::string_view name, std::vector& b) +{ + auto bArr = context.doc[name.data()].GetArray(); + for (auto& s : bArr) + { + build_tool_version sec; + auto s2 = s.GetArray(); + sec.tool = s2[0].GetUint(); + sec.version = s2[1].GetUint(); + b.push_back(sec); + } +} + } // namespace SharedCacheAPI diff --git a/view/sharedcache/api/sharedcacheapi.h b/view/sharedcache/api/sharedcacheapi.h index 19f021e7c4..a9a67a29f4 100644 --- a/view/sharedcache/api/sharedcacheapi.h +++ b/view/sharedcache/api/sharedcacheapi.h @@ -1,13 +1,39 @@ #pragma once #include -#include "MetadataSerializable.hpp" +#include "../core/MetadataSerializable.hpp" #include "view/macho/machoview.h" #include "sharedcachecore.h" using namespace BinaryNinja; namespace SharedCacheAPI { + + void Serialize(SharedCacheCore::SerializationContext&, std::string_view name, const mach_header_64& b); + void Deserialize(SharedCacheCore::DeserializationContext&, std::string_view name, mach_header_64& b); + void Serialize(SharedCacheCore::SerializationContext&, std::string_view name, const symtab_command& b); + void Deserialize(SharedCacheCore::DeserializationContext&, std::string_view name, symtab_command& b); + void Serialize(SharedCacheCore::SerializationContext&, std::string_view name, const dysymtab_command& b); + void Deserialize(SharedCacheCore::DeserializationContext&, std::string_view name, dysymtab_command& b); + void Serialize(SharedCacheCore::SerializationContext&, std::string_view name, const dyld_info_command& b); + void Deserialize(SharedCacheCore::DeserializationContext&, std::string_view name, dyld_info_command& b); + void Serialize(SharedCacheCore::SerializationContext&, std::string_view name, const routines_command_64& b); + void Deserialize(SharedCacheCore::DeserializationContext&, std::string_view name, routines_command_64& b); + void Serialize(SharedCacheCore::SerializationContext&, std::string_view name, const function_starts_command& b); + void Deserialize(SharedCacheCore::DeserializationContext&, std::string_view name, function_starts_command& b); + void Serialize(SharedCacheCore::SerializationContext&, std::string_view name, const std::vector& b); + void Deserialize(SharedCacheCore::DeserializationContext&, std::string_view name, std::vector& b); + void Serialize(SharedCacheCore::SerializationContext&, std::string_view name, const linkedit_data_command& b); + void Deserialize(SharedCacheCore::DeserializationContext&, std::string_view name, linkedit_data_command& b); + void Serialize(SharedCacheCore::SerializationContext&, std::string_view name, const segment_command_64& b); + void Deserialize(SharedCacheCore::DeserializationContext&, std::string_view name, segment_command_64& b); + void Serialize(SharedCacheCore::SerializationContext&, std::string_view name, const std::vector& b); + void Deserialize(SharedCacheCore::DeserializationContext&, std::string_view name, std::vector& b); + void Serialize(SharedCacheCore::SerializationContext&, std::string_view name, const build_version_command& b); + void Deserialize(SharedCacheCore::DeserializationContext&, std::string_view name, build_version_command& b); + void Serialize(SharedCacheCore::SerializationContext&, std::string_view name, const std::vector& b); + void Deserialize(SharedCacheCore::DeserializationContext&, std::string_view name, std::vector& b); + template class SCRefCountObject { void AddRefInternal() { m_refs.fetch_add(1); } @@ -131,7 +157,7 @@ namespace SharedCacheAPI { }; using namespace BinaryNinja; - struct SharedCacheMachOHeader : public MetadataSerializable { + struct SharedCacheMachOHeader : public SharedCacheCore::MetadataSerializable { uint64_t textBase = 0; uint64_t loadCommandOffset = 0; mach_header_64 ident; @@ -174,412 +200,8 @@ namespace SharedCacheAPI { bool routinesPresent = false; bool functionStartsPresent = false; bool relocatable = false; - void Serialize(const std::string& name, mach_header_64 b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - bArr.PushBack(b.magic, m_activeContext.allocator); - bArr.PushBack(b.cputype, m_activeContext.allocator); - bArr.PushBack(b.cpusubtype, m_activeContext.allocator); - bArr.PushBack(b.filetype, m_activeContext.allocator); - bArr.PushBack(b.ncmds, m_activeContext.allocator); - bArr.PushBack(b.sizeofcmds, m_activeContext.allocator); - bArr.PushBack(b.flags, m_activeContext.allocator); - bArr.PushBack(b.reserved, m_activeContext.allocator); - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); - } - - void Deserialize(const std::string& name, mach_header_64& b) - { - auto bArr = m_activeDeserContext.doc[name.c_str()].GetArray(); - b.magic = bArr[0].GetInt64(); - b.cputype = bArr[1].GetInt64(); - b.cpusubtype = bArr[2].GetInt64(); - b.filetype = bArr[3].GetInt64(); - b.ncmds = bArr[4].GetInt64(); - b.sizeofcmds = bArr[5].GetInt64(); - b.flags = bArr[6].GetInt64(); - b.reserved = bArr[7].GetInt64(); - } - - void Serialize(const std::string& name, symtab_command b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - bArr.PushBack(b.cmd, m_activeContext.allocator); - bArr.PushBack(b.cmdsize, m_activeContext.allocator); - bArr.PushBack(b.symoff, m_activeContext.allocator); - bArr.PushBack(b.nsyms, m_activeContext.allocator); - bArr.PushBack(b.stroff, m_activeContext.allocator); - bArr.PushBack(b.strsize, m_activeContext.allocator); - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); - } - - void Deserialize(const std::string& name, symtab_command& b) - { - auto bArr = m_activeDeserContext.doc[name.c_str()].GetArray(); - b.cmd = bArr[0].GetUint(); - b.cmdsize = bArr[1].GetUint(); - b.symoff = bArr[2].GetUint(); - b.nsyms = bArr[3].GetUint(); - b.stroff = bArr[4].GetUint(); - b.strsize = bArr[5].GetUint(); - } - - void Serialize(const std::string& name, dysymtab_command b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - bArr.PushBack(b.cmd, m_activeContext.allocator); - bArr.PushBack(b.cmdsize, m_activeContext.allocator); - bArr.PushBack(b.ilocalsym, m_activeContext.allocator); - bArr.PushBack(b.nlocalsym, m_activeContext.allocator); - bArr.PushBack(b.iextdefsym, m_activeContext.allocator); - bArr.PushBack(b.nextdefsym, m_activeContext.allocator); - bArr.PushBack(b.iundefsym, m_activeContext.allocator); - bArr.PushBack(b.nundefsym, m_activeContext.allocator); - bArr.PushBack(b.tocoff, m_activeContext.allocator); - bArr.PushBack(b.ntoc, m_activeContext.allocator); - bArr.PushBack(b.modtaboff, m_activeContext.allocator); - bArr.PushBack(b.nmodtab, m_activeContext.allocator); - bArr.PushBack(b.extrefsymoff, m_activeContext.allocator); - bArr.PushBack(b.nextrefsyms, m_activeContext.allocator); - bArr.PushBack(b.indirectsymoff, m_activeContext.allocator); - bArr.PushBack(b.nindirectsyms, m_activeContext.allocator); - bArr.PushBack(b.extreloff, m_activeContext.allocator); - bArr.PushBack(b.nextrel, m_activeContext.allocator); - bArr.PushBack(b.locreloff, m_activeContext.allocator); - bArr.PushBack(b.nlocrel, m_activeContext.allocator); - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); - } - - void Deserialize(const std::string& name, dysymtab_command& b) - { - auto bArr = m_activeDeserContext.doc[name.c_str()].GetArray(); - b.cmd = bArr[0].GetUint(); - b.cmdsize = bArr[1].GetUint(); - b.ilocalsym = bArr[2].GetUint(); - b.nlocalsym = bArr[3].GetUint(); - b.iextdefsym = bArr[4].GetUint(); - b.nextdefsym = bArr[5].GetUint(); - b.iundefsym = bArr[6].GetUint(); - b.nundefsym = bArr[7].GetUint(); - b.tocoff = bArr[8].GetUint(); - b.ntoc = bArr[9].GetUint(); - b.modtaboff = bArr[10].GetUint(); - b.nmodtab = bArr[11].GetUint(); - b.extrefsymoff = bArr[12].GetUint(); - b.nextrefsyms = bArr[13].GetUint(); - b.indirectsymoff = bArr[14].GetUint(); - b.nindirectsyms = bArr[15].GetUint(); - b.extreloff = bArr[16].GetUint(); - b.nextrel = bArr[17].GetUint(); - b.locreloff = bArr[18].GetUint(); - b.nlocrel = bArr[19].GetUint(); - } - - void Serialize(const std::string& name, dyld_info_command b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - bArr.PushBack(b.cmd, m_activeContext.allocator); - bArr.PushBack(b.cmdsize, m_activeContext.allocator); - bArr.PushBack(b.rebase_off, m_activeContext.allocator); - bArr.PushBack(b.rebase_size, m_activeContext.allocator); - bArr.PushBack(b.bind_off, m_activeContext.allocator); - bArr.PushBack(b.bind_size, m_activeContext.allocator); - bArr.PushBack(b.weak_bind_off, m_activeContext.allocator); - bArr.PushBack(b.weak_bind_size, m_activeContext.allocator); - bArr.PushBack(b.lazy_bind_off, m_activeContext.allocator); - bArr.PushBack(b.lazy_bind_size, m_activeContext.allocator); - bArr.PushBack(b.export_off, m_activeContext.allocator); - bArr.PushBack(b.export_size, m_activeContext.allocator); - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); - } - - void Deserialize(const std::string& name, dyld_info_command& b) - { - auto bArr = m_activeDeserContext.doc[name.c_str()].GetArray(); - b.cmd = bArr[0].GetUint(); - b.cmdsize = bArr[1].GetUint(); - b.rebase_off = bArr[2].GetUint(); - b.rebase_size = bArr[3].GetUint(); - b.bind_off = bArr[4].GetUint(); - b.bind_size = bArr[5].GetUint(); - b.weak_bind_off = bArr[6].GetUint(); - b.weak_bind_size = bArr[7].GetUint(); - b.lazy_bind_off = bArr[8].GetUint(); - b.lazy_bind_size = bArr[9].GetUint(); - b.export_off = bArr[10].GetUint(); - b.export_size = bArr[11].GetUint(); - } - - void Serialize(const std::string& name, routines_command_64 b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - bArr.PushBack(b.cmd, m_activeContext.allocator); - bArr.PushBack(b.cmdsize, m_activeContext.allocator); - bArr.PushBack(b.init_address, m_activeContext.allocator); - bArr.PushBack(b.init_module, m_activeContext.allocator); - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); - } - - void Deserialize(const std::string& name, routines_command_64& b) - { - auto bArr = m_activeDeserContext.doc[name.c_str()].GetArray(); - b.cmd = bArr[0].GetUint(); - b.cmdsize = bArr[1].GetUint(); - b.init_address = bArr[2].GetUint(); - b.init_module = bArr[3].GetUint(); - } - - void Serialize(const std::string& name, function_starts_command b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - bArr.PushBack(b.cmd, m_activeContext.allocator); - bArr.PushBack(b.cmdsize, m_activeContext.allocator); - bArr.PushBack(b.funcoff, m_activeContext.allocator); - bArr.PushBack(b.funcsize, m_activeContext.allocator); - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); - } - - void Deserialize(const std::string& name, function_starts_command& b) - { - auto bArr = m_activeDeserContext.doc[name.c_str()].GetArray(); - b.cmd = bArr[0].GetUint(); - b.cmdsize = bArr[1].GetUint(); - b.funcoff = bArr[2].GetUint(); - b.funcsize = bArr[3].GetUint(); - } - - void Serialize(const std::string& name, std::vector b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& s : b) - { - rapidjson::Value sArr(rapidjson::kArrayType); - std::string sectNameStr; - char sectName[16]; - memcpy(sectName, s.sectname, 16); - sectName[15] = 0; - sectNameStr = std::string(sectName); - sArr.PushBack(rapidjson::Value(sectNameStr.c_str(), m_activeContext.allocator), m_activeContext.allocator); - std::string segNameStr; - char segName[16]; - memcpy(segName, s.segname, 16); - segName[15] = 0; - segNameStr = std::string(segName); - sArr.PushBack(rapidjson::Value(segNameStr.c_str(), m_activeContext.allocator), m_activeContext.allocator); - sArr.PushBack(s.addr, m_activeContext.allocator); - sArr.PushBack(s.size, m_activeContext.allocator); - sArr.PushBack(s.offset, m_activeContext.allocator); - sArr.PushBack(s.align, m_activeContext.allocator); - sArr.PushBack(s.reloff, m_activeContext.allocator); - sArr.PushBack(s.nreloc, m_activeContext.allocator); - sArr.PushBack(s.flags, m_activeContext.allocator); - sArr.PushBack(s.reserved1, m_activeContext.allocator); - sArr.PushBack(s.reserved2, m_activeContext.allocator); - sArr.PushBack(s.reserved3, m_activeContext.allocator); - bArr.PushBack(sArr, m_activeContext.allocator); - } - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); - } - void Deserialize(const std::string& name, std::vector& b) - { - auto bArr = m_activeDeserContext.doc[name.c_str()].GetArray(); - for (auto& s : bArr) - { - section_64 sec; - auto s2 = s.GetArray(); - std::string sectNameStr = s2[0].GetString(); - memcpy(sec.sectname, sectNameStr.c_str(), sectNameStr.size()); - std::string segNameStr = s2[1].GetString(); - memcpy(sec.segname, segNameStr.c_str(), segNameStr.size()); - sec.addr = s2[2].GetUint64(); - sec.size = s2[3].GetUint64(); - sec.offset = s2[4].GetUint(); - sec.align = s2[5].GetUint(); - sec.reloff = s2[6].GetUint(); - sec.nreloc = s2[7].GetUint(); - sec.flags = s2[8].GetUint(); - sec.reserved1 = s2[9].GetUint(); - sec.reserved2 = s2[10].GetUint(); - sec.reserved3 = s2[11].GetUint(); - b.push_back(sec); - } - } - - void Serialize(const std::string& name, linkedit_data_command b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - bArr.PushBack(b.cmd, m_activeContext.allocator); - bArr.PushBack(b.cmdsize, m_activeContext.allocator); - bArr.PushBack(b.dataoff, m_activeContext.allocator); - bArr.PushBack(b.datasize, m_activeContext.allocator); - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); - } - - void Deserialize(const std::string& name, linkedit_data_command& b) - { - auto bArr = m_activeDeserContext.doc[name.c_str()].GetArray(); - b.cmd = bArr[0].GetUint(); - b.cmdsize = bArr[1].GetUint(); - b.dataoff = bArr[2].GetUint(); - b.datasize = bArr[3].GetUint(); - } - - void Serialize(const std::string& name, segment_command_64 b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - std::string segNameStr; - char segName[16]; - memcpy(segName, b.segname, 16); - segName[15] = 0; - segNameStr = std::string(segName); - bArr.PushBack(rapidjson::Value(segNameStr.c_str(), m_activeContext.allocator), m_activeContext.allocator); - bArr.PushBack(b.vmaddr, m_activeContext.allocator); - bArr.PushBack(b.vmsize, m_activeContext.allocator); - bArr.PushBack(b.fileoff, m_activeContext.allocator); - bArr.PushBack(b.filesize, m_activeContext.allocator); - bArr.PushBack(b.maxprot, m_activeContext.allocator); - bArr.PushBack(b.initprot, m_activeContext.allocator); - bArr.PushBack(b.nsects, m_activeContext.allocator); - bArr.PushBack(b.flags, m_activeContext.allocator); - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); - } - - void Deserialize(const std::string& name, segment_command_64& b) - { - auto bArr = m_activeDeserContext.doc[name.c_str()].GetArray(); - std::string segNameStr = bArr[0].GetString(); - memcpy(b.segname, segNameStr.c_str(), segNameStr.size()); - b.vmaddr = bArr[1].GetUint64(); - b.vmsize = bArr[2].GetUint64(); - b.fileoff = bArr[3].GetUint64(); - b.filesize = bArr[4].GetUint64(); - b.maxprot = bArr[5].GetUint(); - b.initprot = bArr[6].GetUint(); - b.nsects = bArr[7].GetUint(); - b.flags = bArr[8].GetUint(); - } - - void Serialize(const std::string& name, std::vector b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& s : b) - { - rapidjson::Value sArr(rapidjson::kArrayType); - std::string segNameStr; - char segName[16]; - memcpy(segName, s.segname, 16); - segName[15] = 0; - segNameStr = std::string(segName); - sArr.PushBack(rapidjson::Value(segNameStr.c_str(), m_activeContext.allocator), m_activeContext.allocator); - sArr.PushBack(s.vmaddr, m_activeContext.allocator); - sArr.PushBack(s.vmsize, m_activeContext.allocator); - sArr.PushBack(s.fileoff, m_activeContext.allocator); - sArr.PushBack(s.filesize, m_activeContext.allocator); - sArr.PushBack(s.maxprot, m_activeContext.allocator); - sArr.PushBack(s.initprot, m_activeContext.allocator); - sArr.PushBack(s.nsects, m_activeContext.allocator); - sArr.PushBack(s.flags, m_activeContext.allocator); - bArr.PushBack(sArr, m_activeContext.allocator); - } - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); - } - - void Deserialize(const std::string& name, std::vector& b) - { - auto bArr = m_activeDeserContext.doc[name.c_str()].GetArray(); - for (auto& s : bArr) - { - segment_command_64 sec; - auto s2 = s.GetArray(); - std::string segNameStr = s2[0].GetString(); - memcpy(sec.segname, segNameStr.c_str(), segNameStr.size()); - sec.vmaddr = s2[1].GetUint64(); - sec.vmsize = s2[2].GetUint64(); - sec.fileoff = s2[3].GetUint64(); - sec.filesize = s2[4].GetUint64(); - sec.maxprot = s2[5].GetUint(); - sec.initprot = s2[6].GetUint(); - sec.nsects = s2[7].GetUint(); - sec.flags = s2[8].GetUint(); - b.push_back(sec); - } - } - - void Serialize(const std::string& name, build_version_command b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - bArr.PushBack(b.cmd, m_activeContext.allocator); - bArr.PushBack(b.cmdsize, m_activeContext.allocator); - bArr.PushBack(b.platform, m_activeContext.allocator); - bArr.PushBack(b.minos, m_activeContext.allocator); - bArr.PushBack(b.sdk, m_activeContext.allocator); - bArr.PushBack(b.ntools, m_activeContext.allocator); - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); - } - - void Deserialize(const std::string& name, build_version_command& b) - { - auto bArr = m_activeDeserContext.doc[name.c_str()].GetArray(); - b.cmd = bArr[0].GetUint(); - b.cmdsize = bArr[1].GetUint(); - b.platform = bArr[2].GetUint(); - b.minos = bArr[3].GetUint(); - b.sdk = bArr[4].GetUint(); - b.ntools = bArr[5].GetUint(); - } - - void Serialize(const std::string& name, std::vector b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& s : b) - { - rapidjson::Value sArr(rapidjson::kArrayType); - sArr.PushBack(s.tool, m_activeContext.allocator); - sArr.PushBack(s.version, m_activeContext.allocator); - bArr.PushBack(sArr, m_activeContext.allocator); - } - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); - } - - void Deserialize(const std::string& name, std::vector& b) - { - auto bArr = m_activeDeserContext.doc[name.c_str()].GetArray(); - for (auto& s : bArr) - { - build_tool_version sec; - auto s2 = s.GetArray(); - sec.tool = s2[0].GetUint(); - sec.version = s2[1].GetUint(); - b.push_back(sec); - } - } - - void Store() override { + void Store(SharedCacheCore::SerializationContext& context) const { MSS(textBase); MSS(loadCommandOffset); MSS_SUBCLASS(ident); @@ -614,7 +236,8 @@ namespace SharedCacheAPI { MSS(functionStartsPresent); MSS(relocatable); } - void Load() override { + + void Load(SharedCacheCore::DeserializationContext& context) { MSL(textBase); MSL(loadCommandOffset); MSL_SUBCLASS(ident); diff --git a/view/sharedcache/core/MetadataSerializable.hpp b/view/sharedcache/core/MetadataSerializable.hpp index c49a9e8c47..1b7a03d0df 100644 --- a/view/sharedcache/core/MetadataSerializable.hpp +++ b/view/sharedcache/core/MetadataSerializable.hpp @@ -12,15 +12,17 @@ * * Great news. * - * Implement these on your `public MetadataSerializable` subclass: + * Implement these on your `public MetadataSerializable` subclass: * ``` - void Store() override { - MSS(m_someVariable); - MSS(m_someOtherVariable); - } - void Load() override { - MSL(m_someVariable); - MSL(m_someOtherVariable); + class MyClass : public MetadataSerializable { + void Store(SerializationContext& context) const { + MSS(m_someVariable); + MSS(m_someOtherVariable); + } + void Load(DeserializationContext& context) { + MSL(m_someVariable); + MSL(m_someOtherVariable); + } } ``` * Then, you can turn your object into a Metadata object with `AsMetadata()`, and load it back with @@ -37,501 +39,481 @@ #include "rapidjson/stringbuffer.h" #include "rapidjson/prettywriter.h" -#ifndef SHAREDCACHE_METADATASERIALIZABLE_HPP -#define SHAREDCACHE_METADATASERIALIZABLE_HPP +#ifndef SHAREDCACHE_CORE_METADATASERIALIZABLE_HPP +#define SHAREDCACHE_CORE_METADATASERIALIZABLE_HPP + +namespace SharedCacheCore { -#define MSS(name) store(#name, name) -#define MSS_CAST(name, type) store(#name, (type) name) -#define MSS_SUBCLASS(name) Serialize(#name, name) -#define MSL(name) name = load(#name, name) -#define MSL_CAST(name, storedType, type) name = (type)load(#name, (storedType) name) -#define MSL_SUBCLASS(name) Deserialize(#name, name) +#define MSS(name) context.store(#name, name) +#define MSS_CAST(name, type) context.store(#name, (type) name) +#define MSS_SUBCLASS(name) Serialize(context, #name, name) +#define MSL(name) name = context.load(#name) +#define MSL_CAST(name, storedType, type) name = (type)context.load(#name) +#define MSL_SUBCLASS(name) Deserialize(context, #name, name) using namespace BinaryNinja; -class MetadataSerializable -{ -protected: - struct SerialContext - { - rapidjson::Document doc; - rapidjson::Document::AllocatorType allocator; - }; - struct DeserContext - { - rapidjson::Document doc; - }; +struct DeserializationContext; - DeserContext m_activeDeserContext; - SerialContext m_activeContext; +struct SerializationContext { + rapidjson::Document doc; + rapidjson::Document::AllocatorType allocator; -public: - MetadataSerializable() - { - m_activeContext.doc.SetObject(); - m_activeContext.allocator = m_activeContext.doc.GetAllocator(); + SerializationContext() { + doc.SetObject(); + allocator = doc.GetAllocator(); } - // copy constructor - MetadataSerializable(const MetadataSerializable& other) + template + void store(std::string_view x, const T& y) { - m_activeContext.doc.CopyFrom(other.m_activeContext.doc, m_activeContext.doc.GetAllocator()); + Serialize(*this, x, y); } +}; - // copy assignment - MetadataSerializable& operator=(const MetadataSerializable& other) - { - m_activeContext.doc.CopyFrom(other.m_activeContext.doc, m_activeContext.doc.GetAllocator()); - return *this; - } +struct DeserializationContext { + rapidjson::Document doc; - virtual ~MetadataSerializable() + template + T load(std::string_view x) { + T value; + Deserialize(*this, x, value); + return value; } +}; - void SetupSerContext(rapidjson::Document::AllocatorType* alloc = nullptr) - { - m_activeContext.doc.SetObject(); - m_activeContext.allocator = m_activeContext.doc.GetAllocator(); - } - void S() - { - // fixme factor out - } - void Serialize(std::string& name, bool b) +template +class MetadataSerializable +{ +public: + std::string AsString() const { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - m_activeContext.doc.AddMember(key, b, m_activeContext.allocator); - } - void Deserialize(std::string& name, bool& b) { b = m_activeDeserContext.doc[name.c_str()].GetBool(); } + rapidjson::StringBuffer strbuf; + rapidjson::PrettyWriter writer(strbuf); + AsDocument().Accept(writer); - void Serialize(std::string& name, uint8_t b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - m_activeContext.doc.AddMember(key, b, m_activeContext.allocator); - } - void Deserialize(std::string& name, uint8_t& b) - { - b = static_cast(m_activeDeserContext.doc[name.c_str()].GetUint64()); + return strbuf.GetString(); } - void Serialize(std::string& name, uint16_t b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - m_activeContext.doc.AddMember(key, b, m_activeContext.allocator); - } - void Deserialize(std::string& name, uint16_t& b) - { - b = static_cast(m_activeDeserContext.doc[name.c_str()].GetUint64()); + rapidjson::Document AsDocument() const { + SerializationContext context; + AsDerived().Store(context); + return std::move(context.doc); } - void Serialize(std::string& name, uint32_t b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - m_activeContext.doc.AddMember(key, b, m_activeContext.allocator); - } - void Deserialize(std::string& name, uint32_t& b) + void LoadFromString(const std::string& s) { - b = static_cast(m_activeDeserContext.doc[name.c_str()].GetUint64()); + DeserializationContext context; + context.doc.Parse(s.c_str()); + AsDerived().Load(context); } - void Serialize(std::string& name, uint64_t b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - m_activeContext.doc.AddMember(key, b, m_activeContext.allocator); - } - void Deserialize(std::string& name, uint64_t& b) + void LoadFromValue(rapidjson::Value& s) { - b = m_activeDeserContext.doc[name.c_str()].GetUint64(); + DeserializationContext context; + context.doc.CopyFrom(s, context.doc.GetAllocator()); + AsDerived().Load(context); } - void Serialize(std::string& name, int8_t b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - m_activeContext.doc.AddMember(key, b, m_activeContext.allocator); - } - void Deserialize(std::string& name, int8_t& b) - { - b = m_activeDeserContext.doc[name.c_str()].GetInt64(); - } + Ref AsMetadata() { return new Metadata(AsString()); } - void Serialize(std::string& name, int16_t b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - m_activeContext.doc.AddMember(key, b, m_activeContext.allocator); - } - void Deserialize(std::string& name, int16_t& b) + bool LoadFromMetadata(const Ref& meta) { - b = m_activeDeserContext.doc[name.c_str()].GetInt64(); + if (!meta->IsString()) + return false; + LoadFromString(meta->GetString()); + return true; } - void Serialize(std::string& name, int32_t b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - m_activeContext.doc.AddMember(key, b, m_activeContext.allocator); - } - void Deserialize(std::string& name, int32_t& b) - { - b = m_activeDeserContext.doc[name.c_str()].GetInt(); - } +private: + const Derived& AsDerived() const { return static_cast(*this); } + Derived& AsDerived() { return static_cast(*this); } +}; - void Serialize(std::string& name, int64_t b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - m_activeContext.doc.AddMember(key, b, m_activeContext.allocator); - } - void Deserialize(std::string& name, int64_t& b) - { - b = m_activeDeserContext.doc[name.c_str()].GetInt64(); - } +inline void Serialize(SerializationContext& context, std::string_view name, bool b) +{ + rapidjson::Value key(name.data(), context.allocator); + context.doc.AddMember(key, b, context.allocator); +} - void Serialize(std::string& name, std::string b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value value(b.c_str(), m_activeContext.allocator); - m_activeContext.doc.AddMember(key, value, m_activeContext.allocator); - } - void Deserialize(std::string& name, std::string& b) - { - b = m_activeDeserContext.doc[name.c_str()].GetString(); - } +inline void Deserialize(DeserializationContext& context, std::string_view name, bool& b) { + b = context.doc[name.data()].GetBool(); +} - void Serialize(std::string& name, std::map b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& i : b) - { - rapidjson::Value p(rapidjson::kArrayType); - p.PushBack(i.first, m_activeContext.allocator); - rapidjson::Value value(i.second.c_str(), m_activeContext.allocator); - p.PushBack(value, m_activeContext.allocator); - bArr.PushBack(p, m_activeContext.allocator); - } - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); - } - void Deserialize(std::string& name, std::map& b) - { - for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray()) - b[i.GetArray()[0].GetUint64()] = i.GetArray()[1].GetString(); - } +inline void Serialize(SerializationContext& context, std::string_view name, uint8_t b) +{ + rapidjson::Value key(name.data(), context.allocator); + context.doc.AddMember(key, b, context.allocator); +} - void Serialize(std::string& name, std::unordered_map b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& i : b) - { - rapidjson::Value p(rapidjson::kArrayType); - p.PushBack(i.first, m_activeContext.allocator); - rapidjson::Value value(i.second.c_str(), m_activeContext.allocator); - p.PushBack(value, m_activeContext.allocator); - bArr.PushBack(p, m_activeContext.allocator); - } - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); - } +inline void Deserialize(DeserializationContext& context, std::string_view name, uint8_t& b) +{ + b = static_cast(context.doc[name.data()].GetUint64()); +} + +inline void Serialize(SerializationContext& context, std::string_view name, uint16_t b) +{ + rapidjson::Value key(name.data(), context.allocator); + context.doc.AddMember(key, b, context.allocator); +} + +inline void Deserialize(DeserializationContext& context, std::string_view name, uint16_t& b) +{ + b = static_cast(context.doc[name.data()].GetUint64()); +} + +inline void Serialize(SerializationContext& context, std::string_view name, uint32_t b) +{ + rapidjson::Value key(name.data(), context.allocator); + context.doc.AddMember(key, b, context.allocator); +} + +inline void Deserialize(DeserializationContext& context, std::string_view name, uint32_t& b) +{ + b = static_cast(context.doc[name.data()].GetUint64()); +} + +inline void Serialize(SerializationContext& context, std::string_view name, uint64_t b) +{ + rapidjson::Value key(name.data(), context.allocator); + context.doc.AddMember(key, b, context.allocator); +} + +inline void Deserialize(DeserializationContext& context, std::string_view name, uint64_t& b) +{ + b = context.doc[name.data()].GetUint64(); +} + +inline void Serialize(SerializationContext& context, std::string_view name, int8_t b) +{ + rapidjson::Value key(name.data(), context.allocator); + context.doc.AddMember(key, b, context.allocator); +} + +inline void Deserialize(DeserializationContext& context, std::string_view name, int8_t& b) +{ + b = context.doc[name.data()].GetInt64(); +} + +inline void Serialize(SerializationContext& context, std::string_view name, int16_t b) +{ + rapidjson::Value key(name.data(), context.allocator); + context.doc.AddMember(key, b, context.allocator); +} + +inline void Deserialize(DeserializationContext& context, std::string_view name, int16_t& b) +{ + b = context.doc[name.data()].GetInt64(); +} + +inline void Serialize(SerializationContext& context, std::string_view name, int32_t b) +{ + rapidjson::Value key(name.data(), context.allocator); + context.doc.AddMember(key, b, context.allocator); +} + +inline void Deserialize(DeserializationContext& context, std::string_view name, int32_t& b) +{ + b = context.doc[name.data()].GetInt(); +} + +inline void Serialize(SerializationContext& context, std::string_view name, int64_t b) +{ + rapidjson::Value key(name.data(), context.allocator); + context.doc.AddMember(key, b, context.allocator); +} - void Serialize(std::string& name, std::unordered_map b) +inline void Deserialize(DeserializationContext& context, std::string_view name, int64_t& b) +{ + b = context.doc[name.data()].GetInt64(); +} + +inline void Serialize(SerializationContext& context, std::string_view name, std::string_view b) +{ + rapidjson::Value key(name.data(), context.allocator); + rapidjson::Value value(b.data(), context.allocator); + context.doc.AddMember(key, value, context.allocator); +} + +inline void Deserialize(DeserializationContext& context, std::string_view name, std::string& b) +{ + b = context.doc[name.data()].GetString(); +} + +inline void Serialize(SerializationContext& context, std::string_view name, const std::map& b) +{ + rapidjson::Value key(name.data(), context.allocator); + rapidjson::Value bArr(rapidjson::kArrayType); + for (auto& i : b) { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& i : b) - { - rapidjson::Value p(rapidjson::kArrayType); - rapidjson::Value _key(i.first.c_str(), m_activeContext.allocator); - rapidjson::Value value(i.second.c_str(), m_activeContext.allocator); - p.PushBack(_key, m_activeContext.allocator); - p.PushBack(value, m_activeContext.allocator); - bArr.PushBack(p, m_activeContext.allocator); - } - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); + rapidjson::Value p(rapidjson::kArrayType); + p.PushBack(i.first, context.allocator); + rapidjson::Value value(i.second.c_str(), context.allocator); + p.PushBack(value, context.allocator); + bArr.PushBack(p, context.allocator); } - void Deserialize(std::string& name, std::unordered_map& b) + context.doc.AddMember(key, bArr, context.allocator); +} + +inline void Deserialize(DeserializationContext& context, std::string_view name, std::map& b) +{ + for (auto& i : context.doc[name.data()].GetArray()) + b[i.GetArray()[0].GetUint64()] = i.GetArray()[1].GetString(); +} + +inline void Serialize(SerializationContext& context, std::string_view name, const std::unordered_map& b) +{ + rapidjson::Value key(name.data(), context.allocator); + rapidjson::Value bArr(rapidjson::kArrayType); + for (auto& i : b) { - for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray()) - b[i.GetArray()[0].GetUint64()] = i.GetArray()[1].GetString(); + rapidjson::Value p(rapidjson::kArrayType); + p.PushBack(i.first, context.allocator); + rapidjson::Value value(i.second.c_str(), context.allocator); + p.PushBack(value, context.allocator); + bArr.PushBack(p, context.allocator); } + context.doc.AddMember(key, bArr, context.allocator); +} - void Serialize(std::string& name, std::unordered_map b) +inline void Serialize(SerializationContext& context, std::string_view name, const std::unordered_map& b) +{ + rapidjson::Value key(name.data(), context.allocator); + rapidjson::Value bArr(rapidjson::kArrayType); + for (auto& i : b) { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& i : b) - { - rapidjson::Value p(rapidjson::kArrayType); - p.PushBack(i.first, m_activeContext.allocator); - p.PushBack(i.second, m_activeContext.allocator); - bArr.PushBack(p, m_activeContext.allocator); - } - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); + rapidjson::Value p(rapidjson::kArrayType); + rapidjson::Value _key(i.first.c_str(), context.allocator); + rapidjson::Value value(i.second.c_str(), context.allocator); + p.PushBack(_key, context.allocator); + p.PushBack(value, context.allocator); + bArr.PushBack(p, context.allocator); } - void Deserialize(std::string& name, std::unordered_map& b) + context.doc.AddMember(key, bArr, context.allocator); +} + +inline void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map& b) +{ + for (auto& i : context.doc[name.data()].GetArray()) + b[i.GetArray()[0].GetUint64()] = i.GetArray()[1].GetString(); +} + +inline void Serialize(SerializationContext& context, std::string_view name, const std::unordered_map& b) +{ + rapidjson::Value key(name.data(), context.allocator); + rapidjson::Value bArr(rapidjson::kArrayType); + for (auto& i : b) { - for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray()) - b[i.GetArray()[0].GetUint64()] = i.GetArray()[1].GetUint64(); + rapidjson::Value p(rapidjson::kArrayType); + p.PushBack(i.first, context.allocator); + p.PushBack(i.second, context.allocator); + bArr.PushBack(p, context.allocator); } + context.doc.AddMember(key, bArr, context.allocator); +} - // std::unordered_map> - void Serialize(std::string& name, std::unordered_map> b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value classes(rapidjson::kArrayType); - for (auto& i : b) +inline void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map& b) +{ + for (auto& i : context.doc[name.data()].GetArray()) + b[i.GetArray()[0].GetUint64()] = i.GetArray()[1].GetUint64(); +} + +// std::unordered_map> +inline void Serialize(SerializationContext& context, std::string_view name, const std::unordered_map>& b) +{ + rapidjson::Value key(name.data(), context.allocator); + rapidjson::Value classes(rapidjson::kArrayType); + for (auto& i : b) + { + rapidjson::Value classArr(rapidjson::kArrayType); + rapidjson::Value classKey(i.first.c_str(), context.allocator); + classArr.PushBack(classKey, context.allocator); + rapidjson::Value membersArr(rapidjson::kArrayType); + for (auto& j : i.second) { - rapidjson::Value classArr(rapidjson::kArrayType); - rapidjson::Value classKey(i.first.c_str(), m_activeContext.allocator); - classArr.PushBack(classKey, m_activeContext.allocator); - rapidjson::Value membersArr(rapidjson::kArrayType); - for (auto& j : i.second) - { - rapidjson::Value member(rapidjson::kArrayType); - member.PushBack(j.first, m_activeContext.allocator); - member.PushBack(j.second, m_activeContext.allocator); - membersArr.PushBack(member, m_activeContext.allocator); - } - classArr.PushBack(membersArr, m_activeContext.allocator); - classes.PushBack(classArr, m_activeContext.allocator); + rapidjson::Value member(rapidjson::kArrayType); + member.PushBack(j.first, context.allocator); + member.PushBack(j.second, context.allocator); + membersArr.PushBack(member, context.allocator); } - m_activeContext.doc.AddMember(key, classes, m_activeContext.allocator); + classArr.PushBack(membersArr, context.allocator); + classes.PushBack(classArr, context.allocator); } - void Deserialize(std::string& name, std::unordered_map>& b) + context.doc.AddMember(key, classes, context.allocator); +} + +inline void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map>& b) +{ + for (auto& i : context.doc[name.data()].GetArray()) { - for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray()) + std::string key = i.GetArray()[0].GetString(); + std::unordered_map memArray; + for (auto& member : i.GetArray()[1].GetArray()) { - std::string key = i.GetArray()[0].GetString(); - std::unordered_map memArray; - for (auto& member : i.GetArray()[1].GetArray()) - { - memArray[member.GetArray()[0].GetUint64()] = member.GetArray()[1].GetUint64(); - } - b[key] = memArray; + memArray[member.GetArray()[0].GetUint64()] = member.GetArray()[1].GetUint64(); } + b[key] = memArray; } +} - void Deserialize(std::string& name, std::unordered_map& b) - { - for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray()) - b[i.GetArray()[0].GetString()] = i.GetArray()[1].GetString(); - } +inline void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map& b) +{ + for (auto& i : context.doc[name.data()].GetArray()) + b[i.GetArray()[0].GetString()] = i.GetArray()[1].GetString(); +} - void Serialize(std::string& name, std::vector b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (const auto& s : b) - { - rapidjson::Value value(s.c_str(), m_activeContext.allocator); - bArr.PushBack(value, m_activeContext.allocator); - } - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); - } - void Deserialize(std::string& name, std::vector& b) +inline void Serialize(SerializationContext& context, std::string_view name, const std::vector& b) +{ + rapidjson::Value key(name.data(), context.allocator); + rapidjson::Value bArr(rapidjson::kArrayType); + for (const auto& s : b) { - for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray()) - b.emplace_back(i.GetString()); + rapidjson::Value value(s.c_str(), context.allocator); + bArr.PushBack(value, context.allocator); } + context.doc.AddMember(key, bArr, context.allocator); +} + +inline void Deserialize(DeserializationContext& context, std::string_view name, std::vector& b) +{ + for (auto& i : context.doc[name.data()].GetArray()) + b.emplace_back(i.GetString()); +} - void Serialize(std::string& name, std::vector>> b) +inline void Serialize(SerializationContext& context, std::string_view name, const std::vector>>& b) +{ + rapidjson::Value key(name.data(), context.allocator); + rapidjson::Value bArr(rapidjson::kArrayType); + for (auto& i : b) { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& i : b) - { - rapidjson::Value segV(rapidjson::kArrayType); - segV.PushBack(i.first, m_activeContext.allocator); - segV.PushBack(i.second.first, m_activeContext.allocator); - segV.PushBack(i.second.second, m_activeContext.allocator); - bArr.PushBack(segV, m_activeContext.allocator); - } - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); + rapidjson::Value segV(rapidjson::kArrayType); + segV.PushBack(i.first, context.allocator); + segV.PushBack(i.second.first, context.allocator); + segV.PushBack(i.second.second, context.allocator); + bArr.PushBack(segV, context.allocator); } - void Deserialize(std::string& name, std::vector>>& b) + context.doc.AddMember(key, bArr, context.allocator); +} + +inline void Deserialize(DeserializationContext& context, std::string_view name, std::vector>>& b) +{ + for (auto& i : context.doc[name.data()].GetArray()) { - for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray()) - { - std::pair> j; - j.first = i.GetArray()[0].GetUint64(); - j.second.first = i.GetArray()[1].GetUint64(); - j.second.second = i.GetArray()[2].GetUint64(); - b.push_back(j); - } + std::pair> j; + j.first = i.GetArray()[0].GetUint64(); + j.second.first = i.GetArray()[1].GetUint64(); + j.second.second = i.GetArray()[2].GetUint64(); + b.push_back(j); } +} - void Serialize(std::string& name, std::vector> b) +inline void Serialize(SerializationContext& context, std::string_view name, const std::vector>& b) +{ + rapidjson::Value key(name.data(), context.allocator); + rapidjson::Value bArr(rapidjson::kArrayType); + for (auto& i : b) { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& i : b) - { - rapidjson::Value segV(rapidjson::kArrayType); - segV.PushBack(i.first, m_activeContext.allocator); - segV.PushBack(i.second, m_activeContext.allocator); - bArr.PushBack(segV, m_activeContext.allocator); - } - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); + rapidjson::Value segV(rapidjson::kArrayType); + segV.PushBack(i.first, context.allocator); + segV.PushBack(i.second, context.allocator); + bArr.PushBack(segV, context.allocator); } - void Deserialize(std::string& name, std::vector>& b) + context.doc.AddMember(key, bArr, context.allocator); +} + +inline void Deserialize(DeserializationContext& context, std::string_view name, std::vector>& b) +{ + for (auto& i : context.doc[name.data()].GetArray()) { - for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray()) - { - std::pair j; - j.first = i.GetArray()[0].GetUint64(); - j.second = i.GetArray()[1].GetBool(); - b.push_back(j); - } + std::pair j; + j.first = i.GetArray()[0].GetUint64(); + j.second = i.GetArray()[1].GetBool(); + b.push_back(j); } +} - void Serialize(std::string& name, std::vector b) +inline void Serialize(SerializationContext& context, std::string_view name, const std::vector& b) +{ + rapidjson::Value key(name.data(), context.allocator); + rapidjson::Value bArr(rapidjson::kArrayType); + for (auto& i : b) { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& i : b) - { - bArr.PushBack(i, m_activeContext.allocator); - } - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); + bArr.PushBack(i, context.allocator); } - void Deserialize(std::string& name, std::vector& b) + context.doc.AddMember(key, bArr, context.allocator); +} + +inline void Deserialize(DeserializationContext& context, std::string_view name, std::vector& b) +{ + for (auto& i : context.doc[name.data()].GetArray()) { - for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray()) - { - b.push_back(i.GetUint64()); - } + b.push_back(i.GetUint64()); } +} - // std::unordered_map - void Serialize(std::string& name, std::unordered_map b) +// std::unordered_map +inline void Serialize(SerializationContext& context, std::string_view name, const std::unordered_map& b) +{ + rapidjson::Value key(name.data(), context.allocator); + rapidjson::Value bArr(rapidjson::kArrayType); + for (auto& i : b) { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& i : b) - { - rapidjson::Value p(rapidjson::kArrayType); - rapidjson::Value _key(i.first.c_str(), m_activeContext.allocator); - p.PushBack(_key, m_activeContext.allocator); - p.PushBack(i.second, m_activeContext.allocator); - bArr.PushBack(p, m_activeContext.allocator); - } - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); + rapidjson::Value p(rapidjson::kArrayType); + rapidjson::Value _key(i.first.c_str(), context.allocator); + p.PushBack(_key, context.allocator); + p.PushBack(i.second, context.allocator); + bArr.PushBack(p, context.allocator); } - void Deserialize(std::string& name, std::unordered_map& b) + context.doc.AddMember(key, bArr, context.allocator); +} + +inline void Deserialize(DeserializationContext& context, std::string_view name, std::unordered_map& b) +{ + for (auto& i : context.doc[name.data()].GetArray()) { - for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray()) - { - b[i.GetArray()[0].GetString()] = i.GetArray()[1].GetUint64(); - } + b[i.GetArray()[0].GetString()] = i.GetArray()[1].GetUint64(); } - // std::vector>>> - void Serialize(std::string& name, std::vector>>> b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& i : b) +} + +// std::vector>>> +inline void Serialize(SerializationContext& context, std::string_view name, const std::vector>>>& b) +{ + rapidjson::Value key(name.data(), context.allocator); + rapidjson::Value bArr(rapidjson::kArrayType); + for (auto& i : b) + { + rapidjson::Value segV(rapidjson::kArrayType); + segV.PushBack(i.first, context.allocator); + rapidjson::Value segArr(rapidjson::kArrayType); + for (auto& j : i.second) { - rapidjson::Value segV(rapidjson::kArrayType); - segV.PushBack(i.first, m_activeContext.allocator); - rapidjson::Value segArr(rapidjson::kArrayType); - for (auto& j : i.second) - { - rapidjson::Value segPair(rapidjson::kArrayType); - segPair.PushBack(j.first, m_activeContext.allocator); - rapidjson::Value segStr(j.second.c_str(), m_activeContext.allocator); - segPair.PushBack(segStr, m_activeContext.allocator); - segArr.PushBack(segPair, m_activeContext.allocator); - } - segV.PushBack(segArr, m_activeContext.allocator); - bArr.PushBack(segV, m_activeContext.allocator); + rapidjson::Value segPair(rapidjson::kArrayType); + segPair.PushBack(j.first, context.allocator); + rapidjson::Value segStr(j.second.c_str(), context.allocator); + segPair.PushBack(segStr, context.allocator); + segArr.PushBack(segPair, context.allocator); } - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); + segV.PushBack(segArr, context.allocator); + bArr.PushBack(segV, context.allocator); } - void Deserialize(std::string& name, std::vector>>>& b) + context.doc.AddMember(key, bArr, context.allocator); +} + +inline void Deserialize(DeserializationContext& context, std::string_view name, std::vector>>>& b) +{ + for (auto& i : context.doc[name.data()].GetArray()) { - for (auto& i : m_activeDeserContext.doc[name.c_str()].GetArray()) + std::pair>> j; + j.first = i.GetArray()[0].GetUint64(); + for (auto& k : i.GetArray()[1].GetArray()) { - std::pair>> j; - j.first = i.GetArray()[0].GetUint64(); - for (auto& k : i.GetArray()[1].GetArray()) - { - j.second.push_back({k.GetArray()[0].GetUint64(), k.GetArray()[1].GetString()}); - } - b.push_back(j); + j.second.push_back({k.GetArray()[0].GetUint64(), k.GetArray()[1].GetString()}); } + b.push_back(j); } +} - template - void store(std::string x, T y) - { - Serialize(x, y); - } - - template - T load(std::string x, T y) - { - T val; - Deserialize(x, val); - return val; - } - - rapidjson::Document& GetDoc() - { - S(); - Store(); - return m_activeContext.doc; - } - -public: - virtual void Store() = 0; - virtual void Load() = 0; - - std::string AsString() - { - rapidjson::StringBuffer strbuf; - rapidjson::PrettyWriter writer(strbuf); - GetDoc().Accept(writer); - - std::string s = strbuf.GetString(); - return s; - } - rapidjson::Document& AsDocument() { return GetDoc(); } - void LoadFromString(const std::string& s) - { - m_activeDeserContext.doc.Parse(s.c_str()); - Load(); - } - void LoadFromValue(rapidjson::Value& s) - { - m_activeDeserContext.doc.CopyFrom(s, m_activeDeserContext.doc.GetAllocator()); - Load(); - } - Ref AsMetadata() { return new Metadata(AsString()); } - bool LoadFromMetadata(const Ref& meta) - { - if (!meta->IsString()) - return false; - LoadFromString(meta->GetString()); - return true; - } -}; +} // namespace SharedCacheCore #endif // SHAREDCACHE_METADATASERIALIZABLE_HPP diff --git a/view/sharedcache/core/SharedCache.cpp b/view/sharedcache/core/SharedCache.cpp index a7c7ffb016..16056827a6 100644 --- a/view/sharedcache/core/SharedCache.cpp +++ b/view/sharedcache/core/SharedCache.cpp @@ -3320,3 +3320,407 @@ void InitDSCViewType() g_dscViewType = &type; g_dscRawViewType = &rawType; } + +namespace SharedCacheCore { + +void Serialize(SerializationContext& context, std::string_view name, const mach_header_64& b) +{ + rapidjson::Value key(name.data(), context.allocator); + rapidjson::Value bArr(rapidjson::kArrayType); + bArr.PushBack(b.magic, context.allocator); + bArr.PushBack(b.cputype, context.allocator); + bArr.PushBack(b.cpusubtype, context.allocator); + bArr.PushBack(b.filetype, context.allocator); + bArr.PushBack(b.ncmds, context.allocator); + bArr.PushBack(b.sizeofcmds, context.allocator); + bArr.PushBack(b.flags, context.allocator); + bArr.PushBack(b.reserved, context.allocator); + context.doc.AddMember(key, bArr, context.allocator); +} + +void Deserialize(DeserializationContext& context, std::string_view name, mach_header_64& b) +{ + auto bArr = context.doc[name.data()].GetArray(); + b.magic = bArr[0].GetUint(); + b.cputype = bArr[1].GetUint(); + b.cpusubtype = bArr[2].GetUint(); + b.filetype = bArr[3].GetUint(); + b.ncmds = bArr[4].GetUint(); + b.sizeofcmds = bArr[5].GetUint(); + b.flags = bArr[6].GetUint(); + b.reserved = bArr[7].GetUint(); +} + +void Serialize(SerializationContext& context, std::string_view name, const symtab_command& b) +{ + rapidjson::Value key(name.data(), context.allocator); + rapidjson::Value bArr(rapidjson::kArrayType); + bArr.PushBack(b.cmd, context.allocator); + bArr.PushBack(b.cmdsize, context.allocator); + bArr.PushBack(b.symoff, context.allocator); + bArr.PushBack(b.nsyms, context.allocator); + bArr.PushBack(b.stroff, context.allocator); + bArr.PushBack(b.strsize, context.allocator); + context.doc.AddMember(key, bArr, context.allocator); +} + +void Deserialize(DeserializationContext& context, std::string_view name, symtab_command& b) +{ + auto bArr = context.doc[name.data()].GetArray(); + b.cmd = bArr[0].GetUint(); + b.cmdsize = bArr[1].GetUint(); + b.symoff = bArr[2].GetUint(); + b.nsyms = bArr[3].GetUint(); + b.stroff = bArr[4].GetUint(); + b.strsize = bArr[5].GetUint(); +} + +void Serialize(SerializationContext& context, std::string_view name, const dysymtab_command& b) +{ + rapidjson::Value key(name.data(), context.allocator); + rapidjson::Value bArr(rapidjson::kArrayType); + bArr.PushBack(b.cmd, context.allocator); + bArr.PushBack(b.cmdsize, context.allocator); + bArr.PushBack(b.ilocalsym, context.allocator); + bArr.PushBack(b.nlocalsym, context.allocator); + bArr.PushBack(b.iextdefsym, context.allocator); + bArr.PushBack(b.nextdefsym, context.allocator); + bArr.PushBack(b.iundefsym, context.allocator); + bArr.PushBack(b.nundefsym, context.allocator); + bArr.PushBack(b.tocoff, context.allocator); + bArr.PushBack(b.ntoc, context.allocator); + bArr.PushBack(b.modtaboff, context.allocator); + bArr.PushBack(b.nmodtab, context.allocator); + bArr.PushBack(b.extrefsymoff, context.allocator); + bArr.PushBack(b.nextrefsyms, context.allocator); + bArr.PushBack(b.indirectsymoff, context.allocator); + bArr.PushBack(b.nindirectsyms, context.allocator); + bArr.PushBack(b.extreloff, context.allocator); + bArr.PushBack(b.nextrel, context.allocator); + bArr.PushBack(b.locreloff, context.allocator); + bArr.PushBack(b.nlocrel, context.allocator); + context.doc.AddMember(key, bArr, context.allocator); +} + +void Deserialize(DeserializationContext& context, std::string_view name, dysymtab_command& b) +{ + auto bArr = context.doc[name.data()].GetArray(); + b.cmd = bArr[0].GetUint(); + b.cmdsize = bArr[1].GetUint(); + b.ilocalsym = bArr[2].GetUint(); + b.nlocalsym = bArr[3].GetUint(); + b.iextdefsym = bArr[4].GetUint(); + b.nextdefsym = bArr[5].GetUint(); + b.iundefsym = bArr[6].GetUint(); + b.nundefsym = bArr[7].GetUint(); + b.tocoff = bArr[8].GetUint(); + b.ntoc = bArr[9].GetUint(); + b.modtaboff = bArr[10].GetUint(); + b.nmodtab = bArr[11].GetUint(); + b.extrefsymoff = bArr[12].GetUint(); + b.nextrefsyms = bArr[13].GetUint(); + b.indirectsymoff = bArr[14].GetUint(); + b.nindirectsyms = bArr[15].GetUint(); + b.extreloff = bArr[16].GetUint(); + b.nextrel = bArr[17].GetUint(); + b.locreloff = bArr[18].GetUint(); + b.nlocrel = bArr[19].GetUint(); +} + +void Serialize(SerializationContext& context, std::string_view name, const dyld_info_command& b) +{ + rapidjson::Value key(name.data(), context.allocator); + rapidjson::Value bArr(rapidjson::kArrayType); + bArr.PushBack(b.cmd, context.allocator); + bArr.PushBack(b.cmdsize, context.allocator); + bArr.PushBack(b.rebase_off, context.allocator); + bArr.PushBack(b.rebase_size, context.allocator); + bArr.PushBack(b.bind_off, context.allocator); + bArr.PushBack(b.bind_size, context.allocator); + bArr.PushBack(b.weak_bind_off, context.allocator); + bArr.PushBack(b.weak_bind_size, context.allocator); + bArr.PushBack(b.lazy_bind_off, context.allocator); + bArr.PushBack(b.lazy_bind_size, context.allocator); + bArr.PushBack(b.export_off, context.allocator); + bArr.PushBack(b.export_size, context.allocator); + context.doc.AddMember(key, bArr, context.allocator); +} + +void Deserialize(DeserializationContext& context, std::string_view name, dyld_info_command& b) +{ + auto bArr = context.doc[name.data()].GetArray(); + b.cmd = bArr[0].GetUint(); + b.cmdsize = bArr[1].GetUint(); + b.rebase_off = bArr[2].GetUint(); + b.rebase_size = bArr[3].GetUint(); + b.bind_off = bArr[4].GetUint(); + b.bind_size = bArr[5].GetUint(); + b.weak_bind_off = bArr[6].GetUint(); + b.weak_bind_size = bArr[7].GetUint(); + b.lazy_bind_off = bArr[8].GetUint(); + b.lazy_bind_size = bArr[9].GetUint(); + b.export_off = bArr[10].GetUint(); + b.export_size = bArr[11].GetUint(); +} + +void Serialize(SerializationContext& context, std::string_view name, const routines_command_64& b) +{ + rapidjson::Value key(name.data(), context.allocator); + rapidjson::Value bArr(rapidjson::kArrayType); + bArr.PushBack(b.cmd, context.allocator); + bArr.PushBack(b.cmdsize, context.allocator); + bArr.PushBack(b.init_address, context.allocator); + bArr.PushBack(b.init_module, context.allocator); + context.doc.AddMember(key, bArr, context.allocator); +} + +void Deserialize(DeserializationContext& context, std::string_view name, routines_command_64& b) +{ + auto bArr = context.doc[name.data()].GetArray(); + b.cmd = bArr[0].GetUint(); + b.cmdsize = bArr[1].GetUint(); + b.init_address = bArr[2].GetUint(); + b.init_module = bArr[3].GetUint(); +} + +void Serialize(SerializationContext& context, std::string_view name, const function_starts_command& b) +{ + rapidjson::Value key(name.data(), context.allocator); + rapidjson::Value bArr(rapidjson::kArrayType); + bArr.PushBack(b.cmd, context.allocator); + bArr.PushBack(b.cmdsize, context.allocator); + bArr.PushBack(b.funcoff, context.allocator); + bArr.PushBack(b.funcsize, context.allocator); + context.doc.AddMember(key, bArr, context.allocator); +} + +void Deserialize(DeserializationContext& context, std::string_view name, function_starts_command& b) +{ + auto bArr = context.doc[name.data()].GetArray(); + b.cmd = bArr[0].GetUint(); + b.cmdsize = bArr[1].GetUint(); + b.funcoff = bArr[2].GetUint(); + b.funcsize = bArr[3].GetUint(); +} + +void Serialize(SerializationContext& context, std::string_view name, const std::vector& b) +{ + rapidjson::Value key(name.data(), context.allocator); + rapidjson::Value bArr(rapidjson::kArrayType); + for (auto& s : b) + { + rapidjson::Value sArr(rapidjson::kArrayType); + std::string sectNameStr; + char sectName[16]; + memcpy(sectName, s.sectname, 16); + sectName[15] = 0; + sectNameStr = std::string(sectName); + sArr.PushBack( + rapidjson::Value(sectNameStr.c_str(), context.allocator), context.allocator); + std::string segNameStr; + char segName[16]; + memcpy(segName, s.segname, 16); + segName[15] = 0; + segNameStr = std::string(segName); + sArr.PushBack( + rapidjson::Value(segNameStr.c_str(), context.allocator), context.allocator); + sArr.PushBack(s.addr, context.allocator); + sArr.PushBack(s.size, context.allocator); + sArr.PushBack(s.offset, context.allocator); + sArr.PushBack(s.align, context.allocator); + sArr.PushBack(s.reloff, context.allocator); + sArr.PushBack(s.nreloc, context.allocator); + sArr.PushBack(s.flags, context.allocator); + sArr.PushBack(s.reserved1, context.allocator); + sArr.PushBack(s.reserved2, context.allocator); + sArr.PushBack(s.reserved3, context.allocator); + bArr.PushBack(sArr, context.allocator); + } + context.doc.AddMember(key, bArr, context.allocator); +} + +void Deserialize(DeserializationContext& context, std::string_view name, std::vector& b) +{ + auto bArr = context.doc[name.data()].GetArray(); + for (auto& s : bArr) + { + section_64 sec; + auto s2 = s.GetArray(); + std::string sectNameStr = s2[0].GetString(); + memset(sec.sectname, 0, 16); + memcpy(sec.sectname, sectNameStr.c_str(), sectNameStr.size()); + std::string segNameStr = s2[1].GetString(); + memset(sec.segname, 0, 16); + memcpy(sec.segname, segNameStr.c_str(), segNameStr.size()); + sec.addr = s2[2].GetUint64(); + sec.size = s2[3].GetUint64(); + sec.offset = s2[4].GetUint(); + sec.align = s2[5].GetUint(); + sec.reloff = s2[6].GetUint(); + sec.nreloc = s2[7].GetUint(); + sec.flags = s2[8].GetUint(); + sec.reserved1 = s2[9].GetUint(); + sec.reserved2 = s2[10].GetUint(); + sec.reserved3 = s2[11].GetUint(); + b.push_back(sec); + } +} + +void Serialize(SerializationContext& context, std::string_view name, const linkedit_data_command& b) +{ + rapidjson::Value key(name.data(), context.allocator); + rapidjson::Value bArr(rapidjson::kArrayType); + bArr.PushBack(b.cmd, context.allocator); + bArr.PushBack(b.cmdsize, context.allocator); + bArr.PushBack(b.dataoff, context.allocator); + bArr.PushBack(b.datasize, context.allocator); + context.doc.AddMember(key, bArr, context.allocator); +} + +void Deserialize(DeserializationContext& context, std::string_view name, linkedit_data_command& b) +{ + auto bArr = context.doc[name.data()].GetArray(); + b.cmd = bArr[0].GetUint(); + b.cmdsize = bArr[1].GetUint(); + b.dataoff = bArr[2].GetUint(); + b.datasize = bArr[3].GetUint(); +} + +void Serialize(SerializationContext& context, std::string_view name, const segment_command_64& b) +{ + rapidjson::Value key(name.data(), context.allocator); + rapidjson::Value bArr(rapidjson::kArrayType); + std::string segNameStr; + char segName[16]; + memcpy(segName, b.segname, 16); + segName[15] = 0; + segNameStr = std::string(segName); + bArr.PushBack(rapidjson::Value(segNameStr.c_str(), context.allocator), context.allocator); + bArr.PushBack(b.vmaddr, context.allocator); + bArr.PushBack(b.vmsize, context.allocator); + bArr.PushBack(b.fileoff, context.allocator); + bArr.PushBack(b.filesize, context.allocator); + bArr.PushBack(b.maxprot, context.allocator); + bArr.PushBack(b.initprot, context.allocator); + bArr.PushBack(b.nsects, context.allocator); + bArr.PushBack(b.flags, context.allocator); + context.doc.AddMember(key, bArr, context.allocator); +} + +void Deserialize(DeserializationContext& context, std::string_view name, segment_command_64& b) +{ + auto bArr = context.doc[name.data()].GetArray(); + std::string segNameStr = bArr[0].GetString(); + memset(b.segname, 0, 16); + memcpy(b.segname, segNameStr.c_str(), segNameStr.size()); + b.vmaddr = bArr[1].GetUint64(); + b.vmsize = bArr[2].GetUint64(); + b.fileoff = bArr[3].GetUint64(); + b.filesize = bArr[4].GetUint64(); + b.maxprot = bArr[5].GetUint(); + b.initprot = bArr[6].GetUint(); + b.nsects = bArr[7].GetUint(); + b.flags = bArr[8].GetUint(); +} + +void Serialize(SerializationContext& context, std::string_view name, const std::vector& b) +{ + rapidjson::Value key(name.data(), context.allocator); + rapidjson::Value bArr(rapidjson::kArrayType); + for (auto& s : b) + { + rapidjson::Value sArr(rapidjson::kArrayType); + std::string segNameStr; + char segName[16]; + memcpy(segName, s.segname, 16); + segName[15] = 0; + segNameStr = std::string(segName); + sArr.PushBack( + rapidjson::Value(segNameStr.c_str(), context.allocator), context.allocator); + sArr.PushBack(s.vmaddr, context.allocator); + sArr.PushBack(s.vmsize, context.allocator); + sArr.PushBack(s.fileoff, context.allocator); + sArr.PushBack(s.filesize, context.allocator); + sArr.PushBack(s.maxprot, context.allocator); + sArr.PushBack(s.initprot, context.allocator); + sArr.PushBack(s.nsects, context.allocator); + sArr.PushBack(s.flags, context.allocator); + bArr.PushBack(sArr, context.allocator); + } + context.doc.AddMember(key, bArr, context.allocator); +} + +void Deserialize(DeserializationContext& context, std::string_view name, std::vector& b) +{ + auto bArr = context.doc[name.data()].GetArray(); + for (auto& s : bArr) + { + segment_command_64 sec; + auto s2 = s.GetArray(); + std::string segNameStr = s2[0].GetString(); + memset(sec.segname, 0, 16); + memcpy(sec.segname, segNameStr.c_str(), segNameStr.size()); + sec.vmaddr = s2[1].GetUint64(); + sec.vmsize = s2[2].GetUint64(); + sec.fileoff = s2[3].GetUint64(); + sec.filesize = s2[4].GetUint64(); + sec.maxprot = s2[5].GetUint(); + sec.initprot = s2[6].GetUint(); + sec.nsects = s2[7].GetUint(); + sec.flags = s2[8].GetUint(); + b.push_back(sec); + } +} + +void Serialize(SerializationContext& context, std::string_view name, const build_version_command& b) +{ + rapidjson::Value key(name.data(), context.allocator); + rapidjson::Value bArr(rapidjson::kArrayType); + bArr.PushBack(b.cmd, context.allocator); + bArr.PushBack(b.cmdsize, context.allocator); + bArr.PushBack(b.platform, context.allocator); + bArr.PushBack(b.minos, context.allocator); + bArr.PushBack(b.sdk, context.allocator); + bArr.PushBack(b.ntools, context.allocator); + context.doc.AddMember(key, bArr, context.allocator); +} + +void Deserialize(DeserializationContext& context, std::string_view name, build_version_command& b) +{ + auto bArr = context.doc[name.data()].GetArray(); + b.cmd = bArr[0].GetUint(); + b.cmdsize = bArr[1].GetUint(); + b.platform = bArr[2].GetUint(); + b.minos = bArr[3].GetUint(); + b.sdk = bArr[4].GetUint(); + b.ntools = bArr[5].GetUint(); +} + +void Serialize(SerializationContext& context, std::string_view name, const std::vector& b) +{ + rapidjson::Value key(name.data(), context.allocator); + rapidjson::Value bArr(rapidjson::kArrayType); + for (auto& s : b) + { + rapidjson::Value sArr(rapidjson::kArrayType); + sArr.PushBack(s.tool, context.allocator); + sArr.PushBack(s.version, context.allocator); + bArr.PushBack(sArr, context.allocator); + } + context.doc.AddMember(key, bArr, context.allocator); +} + +void Deserialize(DeserializationContext& context, std::string_view name, std::vector& b) +{ + auto bArr = context.doc[name.data()].GetArray(); + for (auto& s : bArr) + { + build_tool_version sec; + auto s2 = s.GetArray(); + sec.tool = s2[0].GetUint(); + sec.version = s2[1].GetUint(); + b.push_back(sec); + } +} + +} // namespace SharedCacheCore diff --git a/view/sharedcache/core/SharedCache.h b/view/sharedcache/core/SharedCache.h index 81c0262039..934cd093f6 100644 --- a/view/sharedcache/core/SharedCache.h +++ b/view/sharedcache/core/SharedCache.h @@ -16,6 +16,31 @@ DECLARE_SHAREDCACHE_API_OBJECT(BNSharedCache, SharedCache); namespace SharedCacheCore { + void Serialize(SerializationContext&, std::string_view name, const mach_header_64& b); + void Deserialize(DeserializationContext&, std::string_view name, mach_header_64& b); + void Serialize(SerializationContext&, std::string_view name, const symtab_command& b); + void Deserialize(DeserializationContext&, std::string_view name, symtab_command& b); + void Serialize(SerializationContext&, std::string_view name, const dysymtab_command& b); + void Deserialize(DeserializationContext&, std::string_view name, dysymtab_command& b); + void Serialize(SerializationContext&, std::string_view name, const dyld_info_command& b); + void Deserialize(DeserializationContext&, std::string_view name, dyld_info_command& b); + void Serialize(SerializationContext&, std::string_view name, const routines_command_64& b); + void Deserialize(DeserializationContext&, std::string_view name, routines_command_64& b); + void Serialize(SerializationContext&, std::string_view name, const function_starts_command& b); + void Deserialize(DeserializationContext&, std::string_view name, function_starts_command& b); + void Serialize(SerializationContext&, std::string_view name, const std::vector& b); + void Deserialize(DeserializationContext&, std::string_view name, std::vector& b); + void Serialize(SerializationContext&, std::string_view name, const linkedit_data_command& b); + void Deserialize(DeserializationContext&, std::string_view name, linkedit_data_command& b); + void Serialize(SerializationContext&, std::string_view name, const segment_command_64& b); + void Deserialize(DeserializationContext&, std::string_view name, segment_command_64& b); + void Serialize(SerializationContext&, std::string_view name, const std::vector& b); + void Deserialize(DeserializationContext&, std::string_view name, std::vector& b); + void Serialize(SerializationContext&, std::string_view name, const build_version_command& b); + void Deserialize(DeserializationContext&, std::string_view name, build_version_command& b); + void Serialize(SerializationContext&, std::string_view name, const std::vector& b); + void Deserialize(DeserializationContext&, std::string_view name, std::vector& b); + enum DSCViewState { DSCViewStateUnloaded, @@ -26,7 +51,7 @@ namespace SharedCacheCore { const std::string SharedCacheMetadataTag = "SHAREDCACHE-SharedCacheData"; - struct MemoryRegion : public MetadataSerializable + struct MemoryRegion : public MetadataSerializable { std::string prettyName; uint64_t start; @@ -36,7 +61,7 @@ namespace SharedCacheCore { bool headerInitialized = false; BNSegmentFlag flags; - void Store() override + void Store(SerializationContext& context) const { MSS(prettyName); MSS(start); @@ -46,7 +71,7 @@ namespace SharedCacheCore { MSS_CAST(flags, uint64_t); } - void Load() override + void Load(DeserializationContext& context) { MSL(prettyName); MSL(start); @@ -57,30 +82,30 @@ namespace SharedCacheCore { } }; - struct CacheImage : public MetadataSerializable + struct CacheImage : public MetadataSerializable { std::string installName; uint64_t headerLocation; std::vector regions; - void Store() override + void Store(SerializationContext& context) const { MSS(installName); MSS(headerLocation); - rapidjson::Value key("regions", m_activeContext.allocator); + rapidjson::Value key("regions", context.allocator); rapidjson::Value bArr(rapidjson::kArrayType); for (auto& region : regions) { - bArr.PushBack(rapidjson::Value(region.AsString().c_str(), m_activeContext.allocator), m_activeContext.allocator); + bArr.PushBack(rapidjson::Value(region.AsString().c_str(), context.allocator), context.allocator); } - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); + context.doc.AddMember(key, bArr, context.allocator); } - void Load() override + void Load(DeserializationContext& context) { MSL(installName); MSL(headerLocation); - auto bArr = m_activeDeserContext.doc["regions"].GetArray(); + auto bArr = context.doc["regions"].GetArray(); regions.clear(); for (auto& region : bArr) { @@ -91,19 +116,19 @@ namespace SharedCacheCore { } }; - struct BackingCache : public MetadataSerializable + struct BackingCache : public MetadataSerializable { std::string path; bool isPrimary = false; std::vector>> mappings; - void Store() override + void Store(SerializationContext& context) const { MSS(path); MSS(isPrimary); MSS(mappings); } - void Load() override + void Load(DeserializationContext& context) { MSL(path); MSL(isPrimary); @@ -357,7 +382,7 @@ namespace SharedCacheCore { #endif using namespace BinaryNinja; - struct SharedCacheMachOHeader : public MetadataSerializable + struct SharedCacheMachOHeader : public MetadataSerializable { uint64_t textBase = 0; uint64_t loadCommandOffset = 0; @@ -402,419 +427,8 @@ namespace SharedCacheCore { bool routinesPresent = false; bool functionStartsPresent = false; bool relocatable = false; - void Serialize(const std::string& name, mach_header_64 b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - bArr.PushBack(b.magic, m_activeContext.allocator); - bArr.PushBack(b.cputype, m_activeContext.allocator); - bArr.PushBack(b.cpusubtype, m_activeContext.allocator); - bArr.PushBack(b.filetype, m_activeContext.allocator); - bArr.PushBack(b.ncmds, m_activeContext.allocator); - bArr.PushBack(b.sizeofcmds, m_activeContext.allocator); - bArr.PushBack(b.flags, m_activeContext.allocator); - bArr.PushBack(b.reserved, m_activeContext.allocator); - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); - } - - void Deserialize(const std::string& name, mach_header_64& b) - { - auto bArr = m_activeDeserContext.doc[name.c_str()].GetArray(); - b.magic = bArr[0].GetUint(); - b.cputype = bArr[1].GetUint(); - b.cpusubtype = bArr[2].GetUint(); - b.filetype = bArr[3].GetUint(); - b.ncmds = bArr[4].GetUint(); - b.sizeofcmds = bArr[5].GetUint(); - b.flags = bArr[6].GetUint(); - b.reserved = bArr[7].GetUint(); - } - - void Serialize(const std::string& name, symtab_command b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - bArr.PushBack(b.cmd, m_activeContext.allocator); - bArr.PushBack(b.cmdsize, m_activeContext.allocator); - bArr.PushBack(b.symoff, m_activeContext.allocator); - bArr.PushBack(b.nsyms, m_activeContext.allocator); - bArr.PushBack(b.stroff, m_activeContext.allocator); - bArr.PushBack(b.strsize, m_activeContext.allocator); - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); - } - - void Deserialize(const std::string& name, symtab_command& b) - { - auto bArr = m_activeDeserContext.doc[name.c_str()].GetArray(); - b.cmd = bArr[0].GetUint(); - b.cmdsize = bArr[1].GetUint(); - b.symoff = bArr[2].GetUint(); - b.nsyms = bArr[3].GetUint(); - b.stroff = bArr[4].GetUint(); - b.strsize = bArr[5].GetUint(); - } - - void Serialize(const std::string& name, dysymtab_command b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - bArr.PushBack(b.cmd, m_activeContext.allocator); - bArr.PushBack(b.cmdsize, m_activeContext.allocator); - bArr.PushBack(b.ilocalsym, m_activeContext.allocator); - bArr.PushBack(b.nlocalsym, m_activeContext.allocator); - bArr.PushBack(b.iextdefsym, m_activeContext.allocator); - bArr.PushBack(b.nextdefsym, m_activeContext.allocator); - bArr.PushBack(b.iundefsym, m_activeContext.allocator); - bArr.PushBack(b.nundefsym, m_activeContext.allocator); - bArr.PushBack(b.tocoff, m_activeContext.allocator); - bArr.PushBack(b.ntoc, m_activeContext.allocator); - bArr.PushBack(b.modtaboff, m_activeContext.allocator); - bArr.PushBack(b.nmodtab, m_activeContext.allocator); - bArr.PushBack(b.extrefsymoff, m_activeContext.allocator); - bArr.PushBack(b.nextrefsyms, m_activeContext.allocator); - bArr.PushBack(b.indirectsymoff, m_activeContext.allocator); - bArr.PushBack(b.nindirectsyms, m_activeContext.allocator); - bArr.PushBack(b.extreloff, m_activeContext.allocator); - bArr.PushBack(b.nextrel, m_activeContext.allocator); - bArr.PushBack(b.locreloff, m_activeContext.allocator); - bArr.PushBack(b.nlocrel, m_activeContext.allocator); - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); - } - - void Deserialize(const std::string& name, dysymtab_command& b) - { - auto bArr = m_activeDeserContext.doc[name.c_str()].GetArray(); - b.cmd = bArr[0].GetUint(); - b.cmdsize = bArr[1].GetUint(); - b.ilocalsym = bArr[2].GetUint(); - b.nlocalsym = bArr[3].GetUint(); - b.iextdefsym = bArr[4].GetUint(); - b.nextdefsym = bArr[5].GetUint(); - b.iundefsym = bArr[6].GetUint(); - b.nundefsym = bArr[7].GetUint(); - b.tocoff = bArr[8].GetUint(); - b.ntoc = bArr[9].GetUint(); - b.modtaboff = bArr[10].GetUint(); - b.nmodtab = bArr[11].GetUint(); - b.extrefsymoff = bArr[12].GetUint(); - b.nextrefsyms = bArr[13].GetUint(); - b.indirectsymoff = bArr[14].GetUint(); - b.nindirectsyms = bArr[15].GetUint(); - b.extreloff = bArr[16].GetUint(); - b.nextrel = bArr[17].GetUint(); - b.locreloff = bArr[18].GetUint(); - b.nlocrel = bArr[19].GetUint(); - } - - void Serialize(const std::string& name, dyld_info_command b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - bArr.PushBack(b.cmd, m_activeContext.allocator); - bArr.PushBack(b.cmdsize, m_activeContext.allocator); - bArr.PushBack(b.rebase_off, m_activeContext.allocator); - bArr.PushBack(b.rebase_size, m_activeContext.allocator); - bArr.PushBack(b.bind_off, m_activeContext.allocator); - bArr.PushBack(b.bind_size, m_activeContext.allocator); - bArr.PushBack(b.weak_bind_off, m_activeContext.allocator); - bArr.PushBack(b.weak_bind_size, m_activeContext.allocator); - bArr.PushBack(b.lazy_bind_off, m_activeContext.allocator); - bArr.PushBack(b.lazy_bind_size, m_activeContext.allocator); - bArr.PushBack(b.export_off, m_activeContext.allocator); - bArr.PushBack(b.export_size, m_activeContext.allocator); - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); - } - void Deserialize(const std::string& name, dyld_info_command& b) - { - auto bArr = m_activeDeserContext.doc[name.c_str()].GetArray(); - b.cmd = bArr[0].GetUint(); - b.cmdsize = bArr[1].GetUint(); - b.rebase_off = bArr[2].GetUint(); - b.rebase_size = bArr[3].GetUint(); - b.bind_off = bArr[4].GetUint(); - b.bind_size = bArr[5].GetUint(); - b.weak_bind_off = bArr[6].GetUint(); - b.weak_bind_size = bArr[7].GetUint(); - b.lazy_bind_off = bArr[8].GetUint(); - b.lazy_bind_size = bArr[9].GetUint(); - b.export_off = bArr[10].GetUint(); - b.export_size = bArr[11].GetUint(); - } - - void Serialize(const std::string& name, routines_command_64 b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - bArr.PushBack(b.cmd, m_activeContext.allocator); - bArr.PushBack(b.cmdsize, m_activeContext.allocator); - bArr.PushBack(b.init_address, m_activeContext.allocator); - bArr.PushBack(b.init_module, m_activeContext.allocator); - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); - } - - void Deserialize(const std::string& name, routines_command_64& b) - { - auto bArr = m_activeDeserContext.doc[name.c_str()].GetArray(); - b.cmd = bArr[0].GetUint(); - b.cmdsize = bArr[1].GetUint(); - b.init_address = bArr[2].GetUint(); - b.init_module = bArr[3].GetUint(); - } - - void Serialize(const std::string& name, function_starts_command b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - bArr.PushBack(b.cmd, m_activeContext.allocator); - bArr.PushBack(b.cmdsize, m_activeContext.allocator); - bArr.PushBack(b.funcoff, m_activeContext.allocator); - bArr.PushBack(b.funcsize, m_activeContext.allocator); - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); - } - - void Deserialize(const std::string& name, function_starts_command& b) - { - auto bArr = m_activeDeserContext.doc[name.c_str()].GetArray(); - b.cmd = bArr[0].GetUint(); - b.cmdsize = bArr[1].GetUint(); - b.funcoff = bArr[2].GetUint(); - b.funcsize = bArr[3].GetUint(); - } - - void Serialize(const std::string& name, std::vector b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& s : b) - { - rapidjson::Value sArr(rapidjson::kArrayType); - std::string sectNameStr; - char sectName[16]; - memcpy(sectName, s.sectname, 16); - sectName[15] = 0; - sectNameStr = std::string(sectName); - sArr.PushBack( - rapidjson::Value(sectNameStr.c_str(), m_activeContext.allocator), m_activeContext.allocator); - std::string segNameStr; - char segName[16]; - memcpy(segName, s.segname, 16); - segName[15] = 0; - segNameStr = std::string(segName); - sArr.PushBack( - rapidjson::Value(segNameStr.c_str(), m_activeContext.allocator), m_activeContext.allocator); - sArr.PushBack(s.addr, m_activeContext.allocator); - sArr.PushBack(s.size, m_activeContext.allocator); - sArr.PushBack(s.offset, m_activeContext.allocator); - sArr.PushBack(s.align, m_activeContext.allocator); - sArr.PushBack(s.reloff, m_activeContext.allocator); - sArr.PushBack(s.nreloc, m_activeContext.allocator); - sArr.PushBack(s.flags, m_activeContext.allocator); - sArr.PushBack(s.reserved1, m_activeContext.allocator); - sArr.PushBack(s.reserved2, m_activeContext.allocator); - sArr.PushBack(s.reserved3, m_activeContext.allocator); - bArr.PushBack(sArr, m_activeContext.allocator); - } - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); - } - - void Deserialize(const std::string& name, std::vector& b) - { - auto bArr = m_activeDeserContext.doc[name.c_str()].GetArray(); - for (auto& s : bArr) - { - section_64 sec; - auto s2 = s.GetArray(); - std::string sectNameStr = s2[0].GetString(); - memset(sec.sectname, 0, 16); - memcpy(sec.sectname, sectNameStr.c_str(), sectNameStr.size()); - std::string segNameStr = s2[1].GetString(); - memset(sec.segname, 0, 16); - memcpy(sec.segname, segNameStr.c_str(), segNameStr.size()); - sec.addr = s2[2].GetUint64(); - sec.size = s2[3].GetUint64(); - sec.offset = s2[4].GetUint(); - sec.align = s2[5].GetUint(); - sec.reloff = s2[6].GetUint(); - sec.nreloc = s2[7].GetUint(); - sec.flags = s2[8].GetUint(); - sec.reserved1 = s2[9].GetUint(); - sec.reserved2 = s2[10].GetUint(); - sec.reserved3 = s2[11].GetUint(); - b.push_back(sec); - } - } - - void Serialize(const std::string& name, linkedit_data_command b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - bArr.PushBack(b.cmd, m_activeContext.allocator); - bArr.PushBack(b.cmdsize, m_activeContext.allocator); - bArr.PushBack(b.dataoff, m_activeContext.allocator); - bArr.PushBack(b.datasize, m_activeContext.allocator); - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); - } - - void Deserialize(const std::string& name, linkedit_data_command& b) - { - auto bArr = m_activeDeserContext.doc[name.c_str()].GetArray(); - b.cmd = bArr[0].GetUint(); - b.cmdsize = bArr[1].GetUint(); - b.dataoff = bArr[2].GetUint(); - b.datasize = bArr[3].GetUint(); - } - - void Serialize(const std::string& name, segment_command_64 b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - std::string segNameStr; - char segName[16]; - memcpy(segName, b.segname, 16); - segName[15] = 0; - segNameStr = std::string(segName); - bArr.PushBack(rapidjson::Value(segNameStr.c_str(), m_activeContext.allocator), m_activeContext.allocator); - bArr.PushBack(b.vmaddr, m_activeContext.allocator); - bArr.PushBack(b.vmsize, m_activeContext.allocator); - bArr.PushBack(b.fileoff, m_activeContext.allocator); - bArr.PushBack(b.filesize, m_activeContext.allocator); - bArr.PushBack(b.maxprot, m_activeContext.allocator); - bArr.PushBack(b.initprot, m_activeContext.allocator); - bArr.PushBack(b.nsects, m_activeContext.allocator); - bArr.PushBack(b.flags, m_activeContext.allocator); - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); - } - - void Deserialize(const std::string& name, segment_command_64& b) - { - auto bArr = m_activeDeserContext.doc[name.c_str()].GetArray(); - std::string segNameStr = bArr[0].GetString(); - memset(b.segname, 0, 16); - memcpy(b.segname, segNameStr.c_str(), segNameStr.size()); - b.vmaddr = bArr[1].GetUint64(); - b.vmsize = bArr[2].GetUint64(); - b.fileoff = bArr[3].GetUint64(); - b.filesize = bArr[4].GetUint64(); - b.maxprot = bArr[5].GetUint(); - b.initprot = bArr[6].GetUint(); - b.nsects = bArr[7].GetUint(); - b.flags = bArr[8].GetUint(); - } - - void Serialize(const std::string& name, std::vector b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& s : b) - { - rapidjson::Value sArr(rapidjson::kArrayType); - std::string segNameStr; - char segName[16]; - memcpy(segName, s.segname, 16); - segName[15] = 0; - segNameStr = std::string(segName); - sArr.PushBack( - rapidjson::Value(segNameStr.c_str(), m_activeContext.allocator), m_activeContext.allocator); - sArr.PushBack(s.vmaddr, m_activeContext.allocator); - sArr.PushBack(s.vmsize, m_activeContext.allocator); - sArr.PushBack(s.fileoff, m_activeContext.allocator); - sArr.PushBack(s.filesize, m_activeContext.allocator); - sArr.PushBack(s.maxprot, m_activeContext.allocator); - sArr.PushBack(s.initprot, m_activeContext.allocator); - sArr.PushBack(s.nsects, m_activeContext.allocator); - sArr.PushBack(s.flags, m_activeContext.allocator); - bArr.PushBack(sArr, m_activeContext.allocator); - } - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); - } - - void Deserialize(const std::string& name, std::vector& b) - { - auto bArr = m_activeDeserContext.doc[name.c_str()].GetArray(); - for (auto& s : bArr) - { - segment_command_64 sec; - auto s2 = s.GetArray(); - std::string segNameStr = s2[0].GetString(); - memset(sec.segname, 0, 16); - memcpy(sec.segname, segNameStr.c_str(), segNameStr.size()); - sec.vmaddr = s2[1].GetUint64(); - sec.vmsize = s2[2].GetUint64(); - sec.fileoff = s2[3].GetUint64(); - sec.filesize = s2[4].GetUint64(); - sec.maxprot = s2[5].GetUint(); - sec.initprot = s2[6].GetUint(); - sec.nsects = s2[7].GetUint(); - sec.flags = s2[8].GetUint(); - b.push_back(sec); - } - } - - void Serialize(const std::string& name, build_version_command b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - bArr.PushBack(b.cmd, m_activeContext.allocator); - bArr.PushBack(b.cmdsize, m_activeContext.allocator); - bArr.PushBack(b.platform, m_activeContext.allocator); - bArr.PushBack(b.minos, m_activeContext.allocator); - bArr.PushBack(b.sdk, m_activeContext.allocator); - bArr.PushBack(b.ntools, m_activeContext.allocator); - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); - } - - void Deserialize(const std::string& name, build_version_command& b) - { - auto bArr = m_activeDeserContext.doc[name.c_str()].GetArray(); - b.cmd = bArr[0].GetUint(); - b.cmdsize = bArr[1].GetUint(); - b.platform = bArr[2].GetUint(); - b.minos = bArr[3].GetUint(); - b.sdk = bArr[4].GetUint(); - b.ntools = bArr[5].GetUint(); - } - - void Serialize(const std::string& name, std::vector b) - { - S(); - rapidjson::Value key(name.c_str(), m_activeContext.allocator); - rapidjson::Value bArr(rapidjson::kArrayType); - for (auto& s : b) - { - rapidjson::Value sArr(rapidjson::kArrayType); - sArr.PushBack(s.tool, m_activeContext.allocator); - sArr.PushBack(s.version, m_activeContext.allocator); - bArr.PushBack(sArr, m_activeContext.allocator); - } - m_activeContext.doc.AddMember(key, bArr, m_activeContext.allocator); - } - - void Deserialize(const std::string& name, std::vector& b) - { - auto bArr = m_activeDeserContext.doc[name.c_str()].GetArray(); - for (auto& s : bArr) - { - build_tool_version sec; - auto s2 = s.GetArray(); - sec.tool = s2[0].GetUint(); - sec.version = s2[1].GetUint(); - b.push_back(sec); - } - } - - void Store() override + void Store(SerializationContext& context) const { MSS(textBase); MSS(loadCommandOffset); @@ -851,7 +465,7 @@ namespace SharedCacheCore { MSS(functionStartsPresent); MSS(relocatable); } - void Load() override + void Load(DeserializationContext& context) { MSL(textBase); MSL(loadCommandOffset); @@ -906,7 +520,7 @@ namespace SharedCacheCore { static std::atomic sharedCacheReferences = 0; - class SharedCache : public MetadataSerializable + class SharedCache : public MetadataSerializable { IMPLEMENT_SHAREDCACHE_API_OBJECT(BNSharedCache); @@ -938,20 +552,20 @@ namespace SharedCacheCore { iOS16CacheFormat, }; - void Store() override + void Store(SerializationContext& context) const { - m_activeContext.doc.AddMember("metadataVersion", METADATA_VERSION, m_activeContext.allocator); + context.doc.AddMember("metadataVersion", METADATA_VERSION, context.allocator); MSS(m_viewState); MSS_CAST(m_cacheFormat, uint8_t); MSS(m_imageStarts); MSS(m_baseFilePath); rapidjson::Value headers(rapidjson::kArrayType); - for (auto [k, v] : m_headers) + for (auto& [k, v] : m_headers) { - headers.PushBack(v.AsDocument(), m_activeContext.allocator); + headers.PushBack(v.AsDocument(), context.allocator); } - m_activeContext.doc.AddMember("headers", headers, m_activeContext.allocator); + context.doc.AddMember("headers", headers, context.allocator); // std::vector>>>> m_exportInfos // std::vector>>>> exportInfos; rapidjson::Document exportInfos(rapidjson::kArrayType); @@ -963,61 +577,62 @@ namespace SharedCacheCore { for (const auto& pair2 : pair1.second) { rapidjson::Value subSubObj(rapidjson::kObjectType); - subSubObj.AddMember("key", pair2.first, m_activeContext.allocator); - subSubObj.AddMember("val1", pair2.second.first, m_activeContext.allocator); - subSubObj.AddMember("val2", pair2.second.second, m_activeContext.allocator); - subArr.PushBack(subSubObj, m_activeContext.allocator); + subSubObj.AddMember("key", pair2.first, context.allocator); + subSubObj.AddMember("val1", pair2.second.first, context.allocator); + subSubObj.AddMember("val2", pair2.second.second, context.allocator); + subArr.PushBack(subSubObj, context.allocator); } - subObj.AddMember("key", pair1.first, m_activeContext.allocator); - subObj.AddMember("value", subArr, m_activeContext.allocator); + subObj.AddMember("key", pair1.first, context.allocator); + subObj.AddMember("value", subArr, context.allocator); - exportInfos.PushBack(subObj, m_activeContext.allocator); + exportInfos.PushBack(subObj, context.allocator); } - m_activeContext.doc.AddMember("exportInfos", exportInfos, m_activeContext.allocator); + context.doc.AddMember("exportInfos", exportInfos, context.allocator); rapidjson::Value backingCaches(rapidjson::kArrayType); - for (auto bc : m_backingCaches) + for (auto& bc : m_backingCaches) { - backingCaches.PushBack(bc.AsDocument(), m_activeContext.allocator); + backingCaches.PushBack(bc.AsDocument(), context.allocator); } - m_activeContext.doc.AddMember("backingCaches", backingCaches, m_activeContext.allocator); + context.doc.AddMember("backingCaches", backingCaches, context.allocator); rapidjson::Value stubIslands(rapidjson::kArrayType); - for (auto si : m_stubIslandRegions) + for (auto& si : m_stubIslandRegions) { - stubIslands.PushBack(si.AsDocument(), m_activeContext.allocator); + stubIslands.PushBack(si.AsDocument(), context.allocator); } rapidjson::Value images(rapidjson::kArrayType); - for (auto img : m_images) + for (auto& img : m_images) { - images.PushBack(img.AsDocument(), m_activeContext.allocator); + images.PushBack(img.AsDocument(), context.allocator); } - m_activeContext.doc.AddMember("images", images, m_activeContext.allocator); + context.doc.AddMember("images", images, context.allocator); rapidjson::Value regionsMappedIntoMemory(rapidjson::kArrayType); - for (auto r : m_regionsMappedIntoMemory) + for (auto& r : m_regionsMappedIntoMemory) { - regionsMappedIntoMemory.PushBack(r.AsDocument(), m_activeContext.allocator); + regionsMappedIntoMemory.PushBack(r.AsDocument(), context.allocator); } - m_activeContext.doc.AddMember("regionsMappedIntoMemory", regionsMappedIntoMemory, m_activeContext.allocator); - m_activeContext.doc.AddMember("stubIslands", stubIslands, m_activeContext.allocator); + context.doc.AddMember("regionsMappedIntoMemory", regionsMappedIntoMemory, context.allocator); + context.doc.AddMember("stubIslands", stubIslands, context.allocator); rapidjson::Value dyldDataSections(rapidjson::kArrayType); - for (auto si : m_dyldDataRegions) + for (auto& si : m_dyldDataRegions) { - dyldDataSections.PushBack(si.AsDocument(), m_activeContext.allocator); + dyldDataSections.PushBack(si.AsDocument(), context.allocator); } - m_activeContext.doc.AddMember("dyldDataSections", dyldDataSections, m_activeContext.allocator); + context.doc.AddMember("dyldDataSections", dyldDataSections, context.allocator); rapidjson::Value nonImageRegions(rapidjson::kArrayType); - for (auto si : m_nonImageRegions) + for (auto& si : m_nonImageRegions) { - nonImageRegions.PushBack(si.AsDocument(), m_activeContext.allocator); + nonImageRegions.PushBack(si.AsDocument(), context.allocator); } - m_activeContext.doc.AddMember("nonImageRegions", nonImageRegions, m_activeContext.allocator); + context.doc.AddMember("nonImageRegions", nonImageRegions, context.allocator); } - void Load() override + + void Load(DeserializationContext& context) { - if (m_activeDeserContext.doc.HasMember("metadataVersion")) + if (context.doc.HasMember("metadataVersion")) { - if (m_activeDeserContext.doc["metadataVersion"].GetUint() != METADATA_VERSION) + if (context.doc["metadataVersion"].GetUint() != METADATA_VERSION) { m_logger->LogError("Shared Cache metadata version mismatch"); return; @@ -1031,7 +646,7 @@ namespace SharedCacheCore { m_viewState = MSL_CAST(m_viewState, uint8_t, DSCViewState); m_cacheFormat = MSL_CAST(m_cacheFormat, uint8_t, SharedCacheFormat); m_headers.clear(); - for (auto& startAndHeader : m_activeDeserContext.doc["headers"].GetArray()) + for (auto& startAndHeader : context.doc["headers"].GetArray()) { SharedCacheMachOHeader header; header.LoadFromValue(startAndHeader); @@ -1040,7 +655,7 @@ namespace SharedCacheCore { MSL(m_imageStarts); MSL(m_baseFilePath); m_exportInfos.clear(); - for (const auto& obj1 : m_activeDeserContext.doc["exportInfos"].GetArray()) + for (const auto& obj1 : context.doc["exportInfos"].GetArray()) { std::vector>> innerVec; for (const auto& obj2 : obj1["value"].GetArray()) @@ -1052,7 +667,7 @@ namespace SharedCacheCore { m_exportInfos[obj1["key"].GetUint64()] = innerVec; } m_symbolInfos.clear(); - for (auto& symbolInfo : m_activeDeserContext.doc["symbolInfos"].GetArray()) + for (auto& symbolInfo : context.doc["symbolInfos"].GetArray()) { std::vector>> symbolInfoVec; for (auto& symbolInfoPair : symbolInfo.GetArray()) @@ -1060,49 +675,49 @@ namespace SharedCacheCore { symbolInfoVec.push_back({symbolInfoPair[0].GetUint64(), {(BNSymbolType)symbolInfoPair[1].GetUint(), symbolInfoPair[2].GetString()}}); } - m_symbolInfos[symbolInfo[0].GetUint64()] = symbolInfoVec; + m_symbolInfos[symbolInfo[0].GetUint64()] = std::move(symbolInfoVec); } m_backingCaches.clear(); - for (auto& bcV : m_activeDeserContext.doc["backingCaches"].GetArray()) + for (auto& bcV : context.doc["backingCaches"].GetArray()) { BackingCache bc; bc.LoadFromValue(bcV); - m_backingCaches.push_back(bc); + m_backingCaches.push_back(std::move(bc)); } m_images.clear(); - for (auto& imgV : m_activeDeserContext.doc["images"].GetArray()) + for (auto& imgV : context.doc["images"].GetArray()) { CacheImage img; img.LoadFromValue(imgV); - m_images.push_back(img); + m_images.push_back(std::move(img)); } m_regionsMappedIntoMemory.clear(); - for (auto& rV : m_activeDeserContext.doc["regionsMappedIntoMemory"].GetArray()) + for (auto& rV : context.doc["regionsMappedIntoMemory"].GetArray()) { MemoryRegion r; r.LoadFromValue(rV); - m_regionsMappedIntoMemory.push_back(r); + m_regionsMappedIntoMemory.push_back(std::move(r)); } m_stubIslandRegions.clear(); - for (auto& siV : m_activeDeserContext.doc["stubIslands"].GetArray()) + for (auto& siV : context.doc["stubIslands"].GetArray()) { MemoryRegion si; si.LoadFromValue(siV); - m_stubIslandRegions.push_back(si); + m_stubIslandRegions.push_back(std::move(si)); } m_dyldDataRegions.clear(); - for (auto& siV : m_activeDeserContext.doc["dyldDataSections"].GetArray()) + for (auto& siV : context.doc["dyldDataSections"].GetArray()) { MemoryRegion si; si.LoadFromValue(siV); - m_dyldDataRegions.push_back(si); + m_dyldDataRegions.push_back(std::move(si)); } m_nonImageRegions.clear(); - for (auto& siV : m_activeDeserContext.doc["nonImageRegions"].GetArray()) + for (auto& siV : context.doc["nonImageRegions"].GetArray()) { MemoryRegion si; si.LoadFromValue(siV); - m_nonImageRegions.push_back(si); + m_nonImageRegions.push_back(std::move(si)); } m_metadataValid = true; @@ -1186,7 +801,7 @@ namespace SharedCacheCore { DSCViewState State() const { return m_viewState; } explicit SharedCache(BinaryNinja::Ref rawView); - ~SharedCache() override; + virtual ~SharedCache(); std::optional LoadHeaderForAddress( std::shared_ptr vm, uint64_t address, std::string installName);