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);