VMProtect/core/macfile.h

755 lines
29 KiB
C++

/**
* 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