diff options
author | jmpoep <OriginalEntryPoint@qq.com> | 2023-12-07 16:51:07 +0800 |
---|---|---|
committer | jmpoep <OriginalEntryPoint@qq.com> | 2023-12-07 16:51:07 +0800 |
commit | 28008a746a31abb7909dd86cb0cd413ac8943b0b (patch) | |
tree | a30b74b8cad548048c3c1551d652828ab76fa9bd /core/macfile.h | |
download | vmprotect-3.5.1-master.tar vmprotect-3.5.1-master.tar.gz vmprotect-3.5.1-master.tar.bz2 vmprotect-3.5.1-master.zip |
Diffstat (limited to 'core/macfile.h')
-rw-r--r-- | core/macfile.h | 755 |
1 files changed, 755 insertions, 0 deletions
diff --git a/core/macfile.h b/core/macfile.h new file mode 100644 index 0000000..294aaf8 --- /dev/null +++ b/core/macfile.h @@ -0,0 +1,755 @@ +/** + * Support of Mach-O executable files. + */ + +#ifndef MACFILE_H +#define MACFILE_H + +class MacFile; +class MacArchitecture; +class MacLoadCommandList; +class MacSegmentList; +class MacSectionList; +class MacImport; +class MacImportList; +class MacFixup; +class MacFixupList; +class MacRuntimeFunctionList; +class CommonInformationEntry; +class CommonInformationEntryList; +class EncodedData; + +class MacLoadCommand : public BaseLoadCommand +{ +public: + explicit MacLoadCommand(MacLoadCommandList *owner); + explicit MacLoadCommand(MacLoadCommandList *owner, uint64_t address, uint32_t size, uint32_t type); + explicit MacLoadCommand(MacLoadCommandList *owner, uint32_t type, IObject *object); + explicit MacLoadCommand(MacLoadCommandList *owner, const MacLoadCommand &src); + virtual uint64_t address() const { return address_; } + virtual uint32_t size() const { return size_; } + virtual uint32_t type() const { return type_; } + virtual std::string name() const; + void ReadFromFile(MacArchitecture &file); + void WriteToFile(MacArchitecture &file); + virtual MacLoadCommand *Clone(ILoadCommandList *owner) const; + void Rebase(uint64_t delta_base); + void set_offset(uint32_t offset) { offset_ = offset; } + void *object() const { return object_; } +private: + uint64_t address_; + uint32_t size_; + uint32_t type_; + IObject *object_; + uint32_t offset_; +}; + +class MacLoadCommandList : public BaseCommandList +{ +public: + explicit MacLoadCommandList(MacArchitecture *owner); + explicit MacLoadCommandList(MacArchitecture *owner, const MacLoadCommandList &src); + virtual MacLoadCommandList *Clone(MacArchitecture *owner) const; + void ReadFromFile(MacArchitecture &file, size_t count); + void WriteToFile(MacArchitecture &file); + MacLoadCommand *item(size_t index) const; + void Pack(); + void Add(uint32_t type, IObject *object); + MacLoadCommand *GetCommandByObject(void *object) const; +}; + +class MacSegment : public BaseSection +{ +public: + explicit MacSegment(MacSegmentList *owner); + explicit MacSegment(MacSegmentList *owner, uint64_t address, uint64_t size, uint32_t physical_offset, + uint32_t physical_size, uint32_t initprot, const std::string &name); + explicit MacSegment(MacSegmentList *owner, const MacSegment &src); + virtual MacSegment *Clone(ISectionList *owner) const; + void ReadFromFile(MacArchitecture &file); + void WriteToFile(MacArchitecture &file); + virtual uint64_t address() const { return address_; } + virtual uint64_t size() const { return size_; } + virtual uint32_t physical_offset() const { return physical_offset_; } + virtual uint32_t physical_size() const { return physical_size_; } + virtual std::string name() const { return name_; } + void set_name(const std::string &name) { name_ = name; } + virtual uint32_t memory_type() const; + virtual void update_type(uint32_t mt); + void set_address(uint64_t address) { address_ = address; } + void set_size(uint64_t size) { size_ = size; } + void set_physical_offset(uint32_t offset) { physical_offset_ = offset; } + void set_physical_size(uint32_t size) { physical_size_ = size; } + virtual uint32_t flags() const { return initprot_; } + void set_flags(uint32_t flags) { initprot_ = flags; } + virtual void Rebase(uint64_t delta_base); + void include_maxprot(vm_prot_t value) { maxprot_ |= value; } +private: + uint64_t address_; + uint64_t size_; + uint32_t physical_offset_; + uint32_t physical_size_; + uint32_t nsects_; + vm_prot_t maxprot_; + vm_prot_t initprot_; + std::string name_; +}; + +class MacSegmentList : public BaseSectionList +{ +public: + explicit MacSegmentList(MacArchitecture *owner); + explicit MacSegmentList(MacArchitecture *owner, const MacSegmentList &src); + virtual MacSegmentList *Clone(MacArchitecture *owner) const; + MacSegment *GetSectionByAddress(uint64_t address) const; + void ReadFromFile(MacArchitecture &file); + void WriteToFile(MacArchitecture &file); + MacSegment *item(size_t index) const; + MacSegment *last() const; + MacSegment *Add(uint64_t address, uint64_t size, uint32_t physical_offset, uint32_t physical_size, uint32_t initprot, const std::string &name); + MacSegment *GetSectionByName(const std::string &name) const; + MacSegment *GetBaseSegment() const; +private: + MacSegment *Add(); +}; + +class MacStringTable +{ +public: + std::string GetString(uint32_t pos) const; + uint32_t AddString(const std::string &str); + void clear(); + void ReadFromFile(MacArchitecture &file); + void WriteToFile(MacArchitecture &file); +private: + std::vector<char> data_; +}; + +class MacSymbolList; + +class MacSymbol : public IObject +{ +public: + explicit MacSymbol(MacSymbolList *owner); + explicit MacSymbol(MacSymbolList *owner, const MacSymbol &src); + ~MacSymbol(); + virtual MacSymbol *Clone(MacSymbolList *owner) const; + void ReadFromFile(MacArchitecture &file); + void WriteToFile(MacArchitecture &file); + uint8_t type() const { return type_; } + uint8_t sect() const { return sect_; } + uint16_t desc() const { return desc_; } + uint64_t value() const { return value_; } + std::string name() const { return name_; } + bool is_deleted() const { return is_deleted_; } + void set_deleted(bool value) { is_deleted_ = value; } + uint8_t library_ordinal() const; + void set_library_ordinal(uint8_t library_ordinal); + void set_value(uint64_t value) { value_ = value; } +private: + MacSymbolList *owner_; + uint8_t type_; + uint8_t sect_; + uint16_t desc_; + uint64_t value_; + std::string name_; + bool is_deleted_; +}; + +class MacSymbolList : public ObjectList<MacSymbol> +{ +public: + explicit MacSymbolList(); + explicit MacSymbolList(const MacSymbolList &src); + virtual MacSymbolList *Clone() const; + void ReadFromFile(MacArchitecture &file, size_t count); + void WriteToFile(MacArchitecture &file); + MacSymbol *GetSymbol(const std::string &name, int library_ordinal) const; + void Pack(); +private: + // no assignment op + MacSymbolList &operator =(const MacSymbolList &); +}; + +class MacSection : public BaseSection +{ +public: + explicit MacSection(MacSectionList *owner, MacSegment *parent); + explicit MacSection(MacSectionList *owner, MacSegment *parent, uint64_t address, uint32_t size, uint32_t offset, uint32_t flags, const std::string &name, const std::string &segment_name); + explicit MacSection(MacSectionList *owner, const MacSection &src); + ~MacSection(); + uint32_t type() const { return flags_ & SECTION_TYPE; } + uint32_t reserved1() const { return reserved1_; } + uint32_t reserved2() const { return reserved2_; } + virtual uint64_t address() const { return address_; } + virtual uint64_t size() const { return size_; } + virtual uint32_t physical_offset() const { return offset_; } + virtual uint32_t physical_size() const { return size_; } + virtual std::string name() const { return name_; } + virtual uint32_t memory_type() const { return parent_->memory_type(); } + virtual MacSegment *parent() const { return parent_; } + void ReadFromFile(MacArchitecture &file); + void WriteToFile(MacArchitecture &file); + virtual MacSection *Clone(ISectionList *owner) const; + void set_parent(MacSegment *parent) { parent_ = parent; } + virtual void update_type(uint32_t mt) { } + virtual uint32_t flags() const { return flags_; } + void set_name(const std::string &name) { name_ = name; } + void set_address(uint64_t address) { address_ = address; } + void set_physical_offset(uint32_t physical_offset) { offset_ = physical_offset; } + void set_physical_size(uint32_t physical_size) { size_ = physical_size; } + void set_flags(uint32_t flags) { flags_ = flags; } + void set_reserved1(uint32_t reserved1) { reserved1_ = reserved1; } + void set_reserved2(uint32_t reserved2) { reserved2_ = reserved2; } + void set_alignment(size_t value); + virtual void Rebase(uint64_t delta_base); + std::string segment_name() const { return segment_name_; } +private: + std::string name_; + std::string segment_name_; + uint64_t address_; + uint32_t size_; + uint32_t offset_; + uint32_t align_; + uint32_t reloff_; + uint32_t nreloc_; + uint32_t flags_; + uint32_t reserved1_; + uint32_t reserved2_; + MacSegment *parent_; +}; + +class MacSectionList : public BaseSectionList +{ +public: + explicit MacSectionList(MacArchitecture *owner); + explicit MacSectionList(MacArchitecture *owner, const MacSectionList &src); + virtual MacSectionList *Clone(MacArchitecture *owner) const; + void ReadFromFile(MacArchitecture &file, size_t count, MacSegment *segment); + MacSection *item(size_t index) const; + MacSection *GetSectionByAddress(uint64_t address) const; + MacSection *GetSectionByName(const std::string &name) const; + MacSection *GetSectionByName(ISection *segment, const std::string &name) const; + MacSection *Add(MacSegment *segment, uint64_t address, uint32_t size, uint32_t offset, uint32_t flags, const std::string &name, const std::string &segment_name); +}; + +class MacImportFunction : public BaseImportFunction +{ +public: + explicit MacImportFunction(IImport *owner, uint64_t address, APIType type, MapFunction *map_function); + explicit MacImportFunction(IImport *owner, uint64_t address, uint8_t bind_type, size_t bind_offset, + const std::string &name, uint32_t flags, int64_t addend, bool is_lazy, MacSymbol *symbol); + explicit MacImportFunction(IImport *owner, const MacImportFunction &src); + virtual MacImportFunction *Clone(IImport *owner) const; + virtual uint64_t address() const { return address_; } + virtual std::string name() const { return name_; } + uint32_t flags() const { return flags_; } + int64_t addend() const { return addend_; } + MacSymbol *symbol() const { return symbol_; } + void set_symbol(MacSymbol *symbol) { symbol_ = symbol; } + uint8_t bind_type() const { return bind_type_; } + bool is_lazy() const { return is_lazy_; } + bool is_weak() const; + virtual void Rebase(uint64_t delta_base); + int library_ordinal() const; + size_t bind_offset() const { return bind_offset_; } + virtual std::string display_name(bool show_ret = true) const; + void set_address(uint64_t address) { address_ = address; } + void set_bind_offset(size_t bind_offset) { bind_offset_ = bind_offset; } +private: + uint64_t address_; + uint8_t bind_type_; + std::string name_; + uint32_t flags_; + int64_t addend_; + bool is_lazy_; + MacSymbol *symbol_; + size_t bind_offset_; +}; + +class MacImport : public BaseImport +{ +public: + explicit MacImport(MacImportList *owner, int library_ordinal, bool is_sdk = false); + explicit MacImport(MacImportList *owner, int library_ordinal, const std::string &name, uint32_t current_version, uint32_t compatibility_version); + explicit MacImport(MacImportList *owner, const MacImport &src); + virtual MacImport *Clone(IImportList *owner) const; + virtual std::string name() const { return name_; } + virtual bool is_sdk() const { return is_sdk_; } + void set_is_sdk(bool is_sdk) { is_sdk_ = is_sdk; } + int library_ordinal() const { return library_ordinal_; } + void ReadFromFile(MacArchitecture &file); + void WriteToFile(MacArchitecture &file); + MacImportFunction *Add(uint64_t address, uint8_t bind_type, size_t bind_offset, const std::string &name, uint32_t flags, int64_t addend, bool is_lazy, MacSymbol *symbol); + MacImportFunction *item(size_t index) const; + virtual MacImportFunction *GetFunctionByAddress(uint64_t address) const; + uint32_t current_version() const { return current_version_; } + uint32_t compatibility_version() const { return compatibility_version_; } + void set_library_ordinal(int library_ordinal) { library_ordinal_ = library_ordinal; } + void set_name(const std::string &name) { name_ = name; } + bool is_weak() const { return is_weak_; } + void set_is_weak(bool is_weak) { is_weak_ = is_weak; } +protected: + virtual MacImportFunction *Add(uint64_t address, APIType type, MapFunction *map_function); +private: + int library_ordinal_; + bool is_weak_; + std::string name_; + bool is_sdk_; + uint32_t timestamp_; + uint32_t current_version_; + uint32_t compatibility_version_; +}; + +class MacImportList : public BaseImportList +{ +public: + explicit MacImportList(MacArchitecture *owner); + explicit MacImportList(MacArchitecture *owner, const MacImportList &src); + virtual MacImportList *Clone(MacArchitecture *owner) const; + void ReadFromFile(MacArchitecture &file); + void WriteToFile(MacArchitecture &file); + MacImport *item(size_t index) const; + MacImportFunction *GetFunctionByAddress(uint64_t address) const; + void Pack(); + MacImport *GetLibraryByOrdinal(int library_ordinal) const; + virtual MacImport *GetImportByName(const std::string &name) const; + void RebaseBindInfo(MacArchitecture &file, size_t delta_base); + virtual const ImportInfo *GetSDKInfo(const std::string &name) const; + int GetMaxLibraryOrdinal() const; +protected: + virtual MacImport *AddSDK(); +private: + void ReadBindInfo(MacArchitecture &file, uint32_t bind_off, uint32_t bind_size); + void ReadLazyBindInfo(MacArchitecture &file, uint32_t lazy_bind_off, uint32_t lazy_bind_size); + size_t WriteBindInfo(MacArchitecture &file); + size_t WriteWeakBindInfo(MacArchitecture &file); + size_t WriteLazyBindInfo(MacArchitecture &file); + MacImport *Add(int library_ordinal); + + struct BindInfoHelper { + bool operator () (const MacImportFunction *left, const MacImportFunction *right) const + { + // sort by library, symbol, type, then address + if (left->library_ordinal() != right->library_ordinal()) + return (left->library_ordinal() < right->library_ordinal()); + if (left->name() != right->name()) + return (left->name() < right->name()); + if (left->bind_type() != right->bind_type()) + return (left->bind_type() < right->bind_type()); + return (left->address() < right->address()); + } + }; + + struct WeakBindInfoHelper { + bool operator () (const MacImportFunction *left, const MacImportFunction *right) const + { + // sort by symbol, type, address + if (left->name() != right->name()) + return (left->name() < right->name()); + if (left->bind_type() != right->bind_type()) + return (left->bind_type() < right->bind_type()); + return (left->address() < right->address()); + } + }; + + struct LazyBindInfoHelper { + bool operator () (const MacImportFunction *left, const MacImportFunction *right) const + { + return (left->bind_offset() < right->bind_offset()); + } + }; + +}; + +class MacIndirectSymbolList; + +class MacIndirectSymbol : public IObject +{ +public: + explicit MacIndirectSymbol(MacIndirectSymbolList *owner, uint64_t address, uint32_t value, MacSymbol *symbol); + explicit MacIndirectSymbol(MacIndirectSymbolList *owner, const MacIndirectSymbol &src); + ~MacIndirectSymbol(); + virtual MacIndirectSymbol *Clone(MacIndirectSymbolList *owner) const; + uint64_t address() const { return address_; } + uint32_t value() const { return value_; } + MacSymbol *symbol() const { return symbol_; } + void set_symbol(MacSymbol *symbol) { symbol_ = symbol; } + void set_value(uint32_t value) { value_ = value; } + void Rebase(uint64_t delta_base); +private: + MacIndirectSymbolList *owner_; + uint64_t address_; + uint32_t value_; + MacSymbol *symbol_; +}; + +class MacIndirectSymbolList : public ObjectList<MacIndirectSymbol> +{ +public: + explicit MacIndirectSymbolList(); + explicit MacIndirectSymbolList(const MacIndirectSymbolList &src); + virtual MacIndirectSymbolList *Clone() const; + void ReadFromFile(MacArchitecture &file); + void WriteToFile(MacArchitecture &file); + void Pack(); + MacIndirectSymbol *Add(uint64_t address, uint32_t value, MacSymbol *symbol); + MacIndirectSymbol *GetSymbol(MacSymbol *symbol) const; + void Rebase(uint64_t delta_base); +private: + // no assignment op + MacIndirectSymbolList &operator =(const MacIndirectSymbolList &); +}; + +class MacExtRefSymbolList; + +class MacExtRefSymbol : public IObject +{ +public: + explicit MacExtRefSymbol(MacExtRefSymbolList *owner, MacSymbol *symbol, uint8_t flags); + explicit MacExtRefSymbol(MacExtRefSymbolList *owner, const MacExtRefSymbol &src); + ~MacExtRefSymbol(); + virtual MacExtRefSymbol *Clone(MacExtRefSymbolList *owner) const; + MacSymbol *symbol() const { return symbol_; } + uint8_t flags() const { return flags_; } + void set_symbol(MacSymbol *symbol) { symbol_ = symbol; } +private: + MacExtRefSymbolList *owner_; + MacSymbol *symbol_; + uint8_t flags_; +}; + +class MacExtRefSymbolList : public ObjectList<MacExtRefSymbol> +{ +public: + explicit MacExtRefSymbolList(); + explicit MacExtRefSymbolList(const MacExtRefSymbolList &src); + virtual MacExtRefSymbolList *Clone() const; + void ReadFromFile(MacArchitecture &file); + void WriteToFile(MacArchitecture &file); + void Pack(); + MacExtRefSymbol *Add(MacSymbol *symbol, uint8_t flags); + MacExtRefSymbol *GetSymbol(MacSymbol *symbol) const; +private: + // no assignment op + MacExtRefSymbolList &operator =(const MacExtRefSymbolList &); +}; + +class MacExport : public BaseExport +{ +public: + explicit MacExport(IExportList *parent, uint64_t address, const std::string &name, uint64_t flags, uint64_t other); + explicit MacExport(IExportList *parent, MacSymbol *symbol); + explicit MacExport(IExportList *parent, const MacExport &src); + virtual MacExport *Clone(IExportList *parent) const; + virtual uint64_t address() const { return address_; } + void set_address(uint64_t address); + virtual std::string name() const { return name_; } + virtual std::string forwarded_name() const { return forwarded_name_; } + uint64_t flags() const { return flags_; } + uint64_t other() const { return other_; } + void set_forwarded_name(const std::string &forwarded_name) { forwarded_name_ = forwarded_name; } + virtual std::string display_name(bool show_ret = true) const; + MacSymbol *symbol() const { return symbol_; } + void set_symbol(MacSymbol *symbol) { symbol_ = symbol; } + virtual void Rebase(uint64_t delta_base); +private: + MacSymbol *symbol_; + uint64_t address_; + std::string name_; + std::string forwarded_name_; + uint64_t flags_; + uint64_t other_; +}; + +class MacExportList : public BaseExportList +{ +public: + explicit MacExportList(MacArchitecture *owner); + explicit MacExportList(MacArchitecture *owner, const MacExportList &src); + virtual MacExportList *Clone(MacArchitecture *owner) const; + virtual std::string name() const { return name_; } + void set_name(const std::string &name) { name_ = name; } + MacExport *item(size_t index) const; + void ReadFromFile(MacArchitecture &file); + void Pack(); + void WriteToFile(MacArchitecture &file); + virtual void ReadFromBuffer(Buffer &buffer, IArchitecture &file); + MacExport *GetExportByAddress(uint64_t address) const; +protected: + virtual MacExport *Add(uint64_t address) { return Add(address, std::string(), 0, 0); } +private: + MacExport *Add(uint64_t address, const std::string &name, uint64_t flags, uint64_t other); + MacExport *Add(MacSymbol *symbol); + void ParseExportNode(const EncodedData &buf, size_t pos, const std::string &name, uint64_t base_address); + + std::string name_; +}; + +class MacExportNode : public ObjectList<MacExportNode> +{ +public: + explicit MacExportNode(MacExportNode *owner = NULL); + explicit MacExportNode(MacExportNode *owner, MacExport *symbol, const std::string &cummulative_string_); + ~MacExportNode(); + void set_owner(MacExportNode *owner); + void AddSymbol(MacExport *symbol); + std::string cummulative_string() const { return cummulative_string_; } + void WriteToData(EncodedData &data, uint64_t base_address); + uint32_t offset() const { return offset_; } +private: + MacExportNode *Add(MacExport *symbol, const std::string &cummulative_string_); + + MacExportNode *owner_; + MacExport *symbol_; + std::string cummulative_string_; + uint32_t offset_; +}; + +class MacFixup : public BaseFixup +{ +public: + explicit MacFixup(MacFixupList *owner, uint64_t address, uint32_t data, OperandSize size, bool is_relocation); + explicit MacFixup(MacFixupList *owner, const MacFixup &src); + virtual MacFixup *Clone(IFixupList *owner) const; + virtual uint64_t address() const { return address_; } + virtual FixupType type() const; + uint8_t internal_type() const; + virtual OperandSize size() const { return size_; } + virtual void set_address(uint64_t address) { address_ = address; } + uint8_t bind_type() const { return static_cast<uint8_t>(data_); } + relocation_info relocation() const; + bool is_relocation() const { return is_relocation_; } + void set_is_relocation(bool is_relocation); + MacSymbol *symbol() const { return symbol_; } + void set_symbol(MacSymbol *symbol) { symbol_ = symbol; } + virtual void Rebase(IArchitecture &file, uint64_t delta_base); +private: + uint64_t address_; + MacSymbol *symbol_; + uint32_t data_; + OperandSize size_; + bool is_relocation_; +}; + +class MacFixupList : public BaseFixupList +{ +public: + explicit MacFixupList(); + explicit MacFixupList(const MacFixupList &src); + virtual MacFixupList *Clone() const; + MacFixup *item(size_t index) const; + void ReadFromFile(MacArchitecture &file); + void WriteToFile(MacArchitecture &file); + virtual MacFixup *AddDefault(OperandSize cpu_address_size, bool is_code); + virtual size_t Pack(); + void WriteToData(Data &data, uint64_t image_base); + MacFixup *AddRelocation(uint64_t address, MacSymbol *symbol, OperandSize size); +private: + MacFixup *Add(uint64_t address, uint32_t data, OperandSize size, bool is_relocation); + void ReadRebaseInfo(MacArchitecture &file, uint32_t rebase_off, uint32_t rebase_size); + void ReadRelocations(MacArchitecture &file, uint32_t offset, uint32_t count, bool need_external); + size_t WriteRebaseInfo(MacArchitecture &file); + size_t WriteRelocations(MacArchitecture &file, bool need_external); + + // no assignment op + MacFixupList &operator =(const MacFixupList &); + + struct RebaseInfoHelper { + bool operator () (const MacFixup *left, const MacFixup *right) const; + }; + + struct RebaseInfo { + uint8_t opcode; + uint64_t operand1; + uint64_t operand2; + RebaseInfo(uint8_t opcode_, uint64_t operand1_, uint64_t operand2_ = 0) + { + opcode = opcode_; + operand1 = operand1_; + operand2 = operand2_; + } + }; +}; + +class MacRuntimeFunction : public BaseRuntimeFunction +{ +public: + explicit MacRuntimeFunction(MacRuntimeFunctionList *owner, uint64_t address, uint64_t begin, uint64_t end, uint64_t unwind_address, CommonInformationEntry *cie, + const std::vector<uint8_t> &call_frame_instructions, uint32_t compact_encoding); + explicit MacRuntimeFunction(MacRuntimeFunctionList *owner, const MacRuntimeFunction &src); + virtual MacRuntimeFunction *Clone(IRuntimeFunctionList *owner) const; + virtual uint64_t address() const { return address_; } + virtual uint64_t begin() const { return begin_; } + virtual uint64_t end() const { return end_; } + virtual uint64_t unwind_address() const { return unwind_address_; } + uint32_t compact_encoding() const { return compact_encoding_; } + virtual void set_begin(uint64_t begin) { begin_ = begin; } + virtual void set_end(uint64_t end) { end_ = end; } + virtual void set_unwind_address(uint64_t unwind_address) { unwind_address_ = unwind_address; } + CommonInformationEntry *cie() const { return cie_; } + void set_cie(CommonInformationEntry *cie) { cie_ = cie; } + std::vector<uint8_t> call_frame_instructions() const { return call_frame_instructions_; } + virtual void Parse(IArchitecture &file, IFunction &dest); + void Rebase(uint64_t delta_base); +private: + void ParseBorland(IArchitecture &file, IFunction &func); + void ParseDwarf(IArchitecture &file, IFunction &func); + + uint64_t address_; + uint64_t begin_; + uint64_t end_; + uint64_t unwind_address_; + uint32_t compact_encoding_; + CommonInformationEntry *cie_; + std::vector<uint8_t> call_frame_instructions_; +}; + +class MacRuntimeFunctionList : public BaseRuntimeFunctionList +{ +public: + explicit MacRuntimeFunctionList(); + explicit MacRuntimeFunctionList(const MacRuntimeFunctionList &src); + ~MacRuntimeFunctionList(); + virtual void clear(); + MacRuntimeFunctionList *Clone() const; + MacRuntimeFunction *item(size_t index) const; + void ReadFromFile(MacArchitecture &file); + size_t WriteToFile(MacArchitecture &file, bool compact_info); + void Rebase(uint64_t delta_base); + virtual MacRuntimeFunction *Add(uint64_t address, uint64_t begin, uint64_t end, uint64_t unwind_address, IRuntimeFunction *source, const std::vector<uint8_t> &call_frame_instructions); + virtual MacRuntimeFunction *GetFunctionByAddress(uint64_t address) const; + CommonInformationEntryList *cie_list() const { return cie_list_; } +private: + void ReadBorlandInfo(MacArchitecture &file, uint64_t address); + void ReadCompactInfo(MacArchitecture &file, uint64_t address, uint32_t size); + void ReadDwarfInfo(MacArchitecture &file, uint64_t address, uint32_t size); + MacRuntimeFunction *Add(uint64_t address, uint64_t begin, uint64_t end, uint64_t unwind_address, CommonInformationEntry *cie, const std::vector<uint8_t> &call_frame_instructions, uint32_t compact_encoding); + + size_t WriteDwarfInfo(MacArchitecture &file); + size_t WriteCompactInfo(MacArchitecture &file); + uint64_t address_; + CommonInformationEntryList *cie_list_; + + // no assignment op + MacRuntimeFunctionList &operator =(const MacRuntimeFunctionList &); +}; + +class MacArchitecture : public BaseArchitecture +{ +public: + explicit MacArchitecture(MacFile *owner, uint64_t offset, uint64_t size); + explicit MacArchitecture(MacFile *owner, const MacArchitecture &src); + virtual ~MacArchitecture(); + virtual std::string name() const; + virtual uint32_t type() const { return cpu_type_; } + uint32_t cpu_subtype() const { return cpu_subtype_; } + virtual OperandSize cpu_address_size() const { return cpu_address_size_; } + uint32_t flags() const { return flags_; } + virtual uint64_t entry_point() const; + virtual uint64_t image_base() const { return image_base_; } + uint32_t segment_alignment() const { return 0x1000; } + uint32_t file_alignment() const { return 0x1000; } + virtual MacLoadCommandList *command_list() const { return command_list_; } + virtual MacSegmentList *segment_list() const { return segment_list_; } + virtual MacImportList *import_list() const { return import_list_; } + virtual MacExportList *export_list() const { return export_list_; } + virtual MacFixupList *fixup_list() const { return fixup_list_; } + virtual IRelocationList *relocation_list() const { return NULL; } + virtual IResourceList *resource_list() const { return NULL; } + virtual ISEHandlerList *seh_handler_list() const { return NULL; } + virtual MacRuntimeFunctionList *runtime_function_list() const { return runtime_function_list_; } + virtual IFunctionList *function_list() const { return function_list_; } + virtual IVirtualMachineList *virtual_machine_list() const { return virtual_machine_list_; } + virtual MacSectionList *section_list() const { return section_list_; } + MacSymbolList *symbol_list() const { return symbol_list_; } + MacIndirectSymbolList *indirect_symbol_list() const { return indirect_symbol_list_; } + OpenStatus ReadFromFile(uint32_t mode); + virtual bool WriteToFile(); + virtual MacArchitecture *Clone(IFile *file) const; + virtual bool Compile(CompileOptions &options, IArchitecture *runtime); + virtual void Save(CompileContext &ctx); + virtual bool is_executable() const; + MacStringTable *string_table() { return &string_table_; } + symtab_command *symtab() { return &symtab_; } + dysymtab_command *dysymtab() { return &dysymtab_; } + dyld_info_command *dyld_info() { return &dyld_info_; } + uint64_t GetRelocBase() const; + virtual CallingConvention calling_convention() const { return cpu_address_size() == osDWord ? ccCdecl : ccABIx64; } + void Rebase(uint64_t delta_base, size_t delta_bind_info); + MacSegment *header_segment() const { return header_segment_; } + uint32_t max_header_size() const { return max_header_size_; } + uint32_t file_type() const { return file_type_; } + MacSection *runtime_functions_section() const { return runtime_functions_section_; } + MacSection *unwind_info_section() const { return unwind_info_section_; } +protected: + virtual bool Prepare(CompileContext &ctx); +private: + MacLoadCommandList *command_list_; + MacSegmentList *segment_list_; + MacSectionList *section_list_; + MacSymbolList *symbol_list_; + MacImportList *import_list_; + MacExportList *export_list_; + MacIndirectSymbolList *indirect_symbol_list_; + MacExtRefSymbolList *ext_ref_symbol_list_; + MacFixupList *fixup_list_; + MacRuntimeFunctionList *runtime_function_list_; + IFunctionList *function_list_; + IVirtualMachineList *virtual_machine_list_; + + cpu_type_t cpu_type_; + cpu_subtype_t cpu_subtype_; + OperandSize cpu_address_size_; + uint64_t image_base_; + symtab_command symtab_; + dysymtab_command dysymtab_; + dyld_info_command dyld_info_; + MacStringTable string_table_; + uint64_t entry_point_; + uint32_t file_type_; + uint32_t cmds_size_; + uint32_t flags_; + uint32_t header_size_; + uint32_t segment_alignment_; + uint32_t file_alignment_; + uint32_t sdk_; + MacSegment *linkedit_segment_; + size_t optimized_segment_count_; + MacSegment *header_segment_; + uint32_t max_header_size_; + MacSection *runtime_functions_section_; + MacSection *unwind_info_section_; + + // no copy ctr or assignment op + MacArchitecture(const MacArchitecture &); + MacArchitecture &operator =(const MacArchitecture &); +}; + +class MacFile : public IFile +{ +public: + explicit MacFile(ILog *log); + explicit MacFile(const MacFile &src, const char *file_name); + virtual ~MacFile(); + virtual std::string format_name() const; + MacArchitecture *item(size_t index) const; + MacFile *Clone(const char *file_name) const; + virtual bool Compile(CompileOptions &options); + virtual bool is_executable() const; + virtual uint32_t disable_options() const; +protected: + virtual OpenStatus ReadHeader(uint32_t open_mode); + virtual IFile *runtime() const { return runtime_; } +private: + MacArchitecture *Add(uint64_t offset, uint64_t size); + + uint32_t fat_magic_; + MacFile *runtime_; + + // no copy ctr or assignment op + MacFile(const MacFile &); + MacFile &operator =(const MacFile &); +}; + +#endif
\ No newline at end of file |