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/pefile.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/pefile.h')
-rw-r--r-- | core/pefile.h | 925 |
1 files changed, 925 insertions, 0 deletions
diff --git a/core/pefile.h b/core/pefile.h new file mode 100644 index 0000000..12c847c --- /dev/null +++ b/core/pefile.h @@ -0,0 +1,925 @@ +/** + * Support of PE executable files. + */ + +#ifndef PEFILE_H +#define PEFILE_H + +class PEArchitecture; +class PEDirectoryList; +class PESegmentList; +class PEImportList; +class PEFixupList; +class PERelocationList; +class PELoadConfigDirectory; +class PERuntimeFunctionList; + +class PEDirectory : public BaseLoadCommand +{ +public: + explicit PEDirectory(PEDirectoryList *owner, uint32_t type); + explicit PEDirectory(PEDirectoryList *owner, const PEDirectory &src); + virtual uint64_t address() const { return address_; } + virtual uint32_t size() const { return size_; } + virtual uint32_t type() const { return type_; } + uint32_t physical_size() const { return physical_size_ ? physical_size_ : size_; } + void set_physical_size(uint32_t physical_size) { physical_size_ = physical_size; } + virtual std::string name() const; + void ReadFromFile(PEArchitecture &file); + void WriteToFile(PEArchitecture &file) const; + virtual PEDirectory *Clone(ILoadCommandList *owner) const; + void clear(); + void set_address(uint64_t address) { address_ = address; } + void set_size(uint32_t size) { size_ = size; } + void Rebase(uint64_t delta_base); + virtual bool visible() const { return (address_ || size_); } + void FreeByManager(MemoryManager &manager); +private: + uint64_t address_; + uint32_t size_; + uint32_t type_; + uint32_t physical_size_; +}; + +class PEDirectoryList : public BaseCommandList +{ +public: + explicit PEDirectoryList(PEArchitecture *owner); + explicit PEDirectoryList(PEArchitecture *owner, const PEDirectoryList &src); + PEDirectoryList *Clone(PEArchitecture *owner) const; + PEDirectory *item(size_t index) const; + void ReadFromFile(PEArchitecture &file, uint32_t count); + void WriteToFile(PEArchitecture &file) const; + PEDirectory *GetCommandByType(uint32_t type) const; + PEDirectory *GetCommandByAddress(uint64_t address) const; +private: + PEDirectory *Add(uint32_t type); +}; + +class PESegment : public BaseSection +{ +public: + explicit PESegment(PESegmentList *owner); + explicit PESegment(PESegmentList *owner, uint64_t address, uint32_t size, uint32_t physical_offset, + uint32_t physical_size, uint32_t flags, const std::string &name); + explicit PESegment(PESegmentList *owner, const PESegment &src); + 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_; } + virtual uint32_t memory_type() const; + virtual uint32_t flags() const { return flags_; } + void set_flags(uint32_t flags) { flags_ = flags; } + void set_size(uint32_t size) { size_ = size; } + void set_physical_size(uint32_t size) { physical_size_ = size; } + void set_physical_offset(uint32_t offset) { physical_offset_ = offset; } + void set_name(const std::string &name) { name_ = name; } + void ReadFromFile(PEArchitecture &file); + void WriteToFile(PEArchitecture &file) const; + virtual PESegment *Clone(ISectionList *owner) const; + virtual void update_type(uint32_t mt); + virtual void Rebase(uint64_t delta_base); +private: + std::string name_; + uint64_t address_; + uint32_t size_; + uint32_t physical_offset_; + uint32_t physical_size_; + uint32_t flags_; +}; + +class PESegmentList : public BaseSectionList +{ +public: + explicit PESegmentList(PEArchitecture *owner); + explicit PESegmentList(PEArchitecture *owner, const PESegmentList &src); + ~PESegmentList(); + PESegmentList *Clone(PEArchitecture *owner) const; + PESegment *item(size_t index) const; + PESegment *GetSectionByAddress(uint64_t address) const; + void ReadFromFile(PEArchitecture &file, uint32_t count); + void WriteToFile(PEArchitecture &file) const; + PESegment *last() const; + PESegment *Add(uint64_t address, uint32_t size, uint32_t physical_offset, uint32_t physical_size, uint32_t flags, const std::string &name); + PESegment *header_segment() const { return header_segment_; } +private: + PESegment *Add(); + + PESegment *header_segment_; + + // no copy ctr or assignment op + PESegmentList(const PESegmentList &); + PESegmentList &operator =(const PESegmentList &); +}; + +class PESectionList; + +class PESection : public BaseSection +{ +public: + explicit PESection(PESectionList *owner, PESegment *parent, uint64_t address, uint64_t size, const std::string &name); + explicit PESection(PESectionList *owner, const PESection &src); + virtual std::string name() const { return name_; } + virtual uint64_t address() const { return address_; } + virtual uint64_t size() const { return size_; } + virtual uint32_t physical_offset() const { return parent_->physical_offset() + static_cast<uint32_t>(address_ - parent_->address()); } + virtual uint32_t physical_size() const { return static_cast<uint32_t>(size_); } + virtual uint32_t memory_type() const { return parent_->memory_type(); } + virtual uint32_t flags() const { return 0; } + virtual void update_type(uint32_t mt) {} + virtual PESection *Clone(ISectionList *owner) const; + virtual void Rebase(uint64_t delta_base); + virtual PESegment *parent() const { return parent_; } + void set_parent(PESegment *parent) { parent_ = parent; } +private: + std::string name_; + uint64_t address_; + uint64_t size_; + PESegment *parent_; +}; + +class PESectionList : public BaseSectionList +{ +public: + explicit PESectionList(PEArchitecture *owner); + explicit PESectionList(PEArchitecture *owner, const PESectionList &src); + virtual PESectionList *Clone(PEArchitecture *owner) const; + PESection *item(size_t index) const; + PESection *Add(PESegment *parent, uint64_t address, uint64_t size, const std::string &name); +}; + +class PEImport; + +class PEImportFunction : public BaseImportFunction +{ +public: + explicit PEImportFunction(PEImport *owner); + explicit PEImportFunction(PEImport *owner, const std::string &name); + explicit PEImportFunction(PEImport *owner, uint64_t address, APIType type, MapFunction *map_function); + explicit PEImportFunction(PEImport *owner, const PEImportFunction &src); + virtual PEImportFunction *Clone(IImport *owner) const; + bool ReadFromFile(PEArchitecture &arch, uint32_t &rva); + virtual uint64_t address() const { return address_; } + virtual std::string name() const { return name_; } + bool is_ordinal() const { return is_ordinal_; } + uint32_t ordinal() const { return ordinal_; } + void FreeByManager(MemoryManager &manager, bool free_iat); + virtual void Rebase(uint64_t delta_base); + virtual std::string display_name(bool show_ret = true) const; + bool IsInternal(const CompileContext &ctx) const; +private: + std::string name_; + uint64_t name_address_; + uint64_t address_; + bool is_ordinal_; + uint32_t ordinal_; +}; + +class PEImport : public BaseImport +{ +public: + explicit PEImport(PEImportList *owner); + explicit PEImport(PEImportList *owner, bool is_sdk); + explicit PEImport(PEImportList *owner, const std::string &name); + explicit PEImport(PEImportList *owner, const PEImport &src); + virtual PEImport *Clone(IImportList *owner) const; + PEImportFunction *item(size_t index) const; + bool ReadFromFile(PEArchitecture &file); + void WriteToFile(PEArchitecture &file) const; + virtual std::string name() const { return name_; } + virtual bool is_sdk() const { return is_sdk_; } + bool FreeByManager(MemoryManager &manager, bool free_iat); + virtual void Rebase(uint64_t delta_base); + void set_name(const std::string &name) { name_ = name; } +protected: + virtual PEImportFunction *Add(uint64_t address, APIType type, MapFunction *map_function); +private: + std::string name_; + uint64_t name_address_; + bool is_sdk_; + uint64_t original_first_thunk_address_; + uint64_t first_thunk_address_; + uint32_t time_stamp_; + uint32_t forwarder_chain_; +}; + +class PEImportList : public BaseImportList +{ +public: + explicit PEImportList(PEArchitecture *owner); + explicit PEImportList(PEArchitecture *owner, const PEImportList &src); + virtual PEImportList *Clone(PEArchitecture *owner) const; + PEImport *item(size_t index) const; + virtual PEImportFunction *GetFunctionByAddress(uint64_t address) const; + void ReadFromFile(PEArchitecture &file, PEDirectory &dir); + void FreeByManager(MemoryManager &manager, bool free_iat); + virtual void Rebase(uint64_t delta_base); + void WriteToFile(PEArchitecture &file, bool skip_sdk = false) const; +protected: + virtual PEImport *AddSDK(); +private: + uint64_t address_; +}; + +class PEDelayImport; +class PEDelayImportList; + +class PEDelayImportFunction : public IObject +{ +public: + explicit PEDelayImportFunction(PEDelayImport *owner); + explicit PEDelayImportFunction(PEDelayImport *owner, const PEDelayImportFunction &src); + ~PEDelayImportFunction(); + PEDelayImportFunction *Clone(PEDelayImport *owner) const; + bool ReadFromFile(PEArchitecture &file, uint64_t add_value); + std::string name() const { return name_; } + bool is_ordinal() const { return is_ordinal_; } + uint32_t ordinal() const { return ordinal_; } +private: + PEDelayImport *owner_; + + std::string name_; + bool is_ordinal_; + uint32_t ordinal_; +}; + +class PEDelayImport : public ObjectList<PEDelayImportFunction> +{ +public: + explicit PEDelayImport(PEDelayImportList *owner); + explicit PEDelayImport(PEDelayImportList *owner, const PEDelayImport &src); + ~PEDelayImport(); + PEDelayImport *Clone(PEDelayImportList *owner) const; + bool ReadFromFile(PEArchitecture &file); + virtual std::string name() const { return name_; } + uint32_t flags() const { return flags_; } + uint64_t module() const { return module_; } + uint64_t iat() const { return iat_; } + uint64_t bound_iat() const { return bound_iat_; } + uint64_t unload_iat() const { return unload_iat_; } + uint32_t time_stamp() const { return time_stamp_; } +private: + PEDelayImportList *owner_; + + std::string name_; + uint32_t flags_; + uint64_t module_; + uint64_t iat_; + uint64_t bound_iat_; + uint64_t unload_iat_; + uint32_t time_stamp_; +}; + +class PEDelayImportList : public ObjectList<PEDelayImport> +{ +public: + explicit PEDelayImportList(); + explicit PEDelayImportList(const PEDelayImportList &src); + PEDelayImportList *Clone() const; + void ReadFromFile(PEArchitecture &file, PEDirectory &dir); +}; + +class PEExportList; + +class PEExport : public BaseExport +{ +public: + explicit PEExport(PEExportList *owner, uint64_t address, uint32_t ordinal); + explicit PEExport(PEExportList *owner, const PEExport &src); + virtual uint64_t address() const { return address_; } + virtual std::string name() const { return name_; } + virtual std::string forwarded_name() const { return forwarded_name_; } + virtual std::string display_name(bool show_ret = true) const; + uint32_t ordinal() const { return ordinal_; } + void set_name(const std::string &name) { name_ = name; } + void set_forwarded_name(const std::string &forwarded_name) { forwarded_name_ = forwarded_name; } + virtual PEExport *Clone(IExportList *owner) const; + /*virtual*/ int CompareWith(const IObject &obj) const; + void FreeByManager(MemoryManager &manager); + void ReadFromFile(PEArchitecture &file, uint64_t address_of_name, bool is_forwarded); + virtual void Rebase(uint64_t delta_base); +private: + uint64_t address_; + uint32_t ordinal_; + uint64_t address_of_name_; + std::string name_; + std::string forwarded_name_; +}; + +class PEExportList : public BaseExportList +{ +public: + explicit PEExportList(PEArchitecture *owner); + explicit PEExportList(PEArchitecture *owner, const PEExportList &src); + virtual PEExportList *Clone(PEArchitecture *owner) const; + virtual std::string name() const { return name_; } + void set_name(const std::string &name) { name_ = name; } + uint32_t characteristics() const { return characteristics_; } + uint32_t time_date_stamp() const { return time_date_stamp_; } + uint16_t major_version() const { return major_version_; } + uint16_t minor_version() const { return minor_version_; } + PEExport *item(size_t index) const; + void ReadFromFile(PEArchitecture &arch, PEDirectory &dir); + void FreeByManager(MemoryManager &manager); + virtual void ReadFromBuffer(Buffer &buffer, IArchitecture &file); + uint32_t WriteToData(IFunction &data, uint64_t image_base); + void AddAntidebug(); +protected: + virtual PEExport *Add(uint64_t address) { return Add(address, 0); } +private: + PEExport *Add(uint64_t address, uint32_t ordinal); + PEExport *GetExportByOrdinal(uint32_t ordinal); + + uint64_t address_; + uint64_t name_address_; + uint32_t characteristics_; + uint32_t time_date_stamp_; + uint16_t major_version_; + uint16_t minor_version_; + std::string name_; + uint32_t number_of_functions_; + uint64_t address_of_functions_; + uint32_t number_of_names_; + uint64_t address_of_names_; + uint64_t address_of_name_ordinals_; + + struct NameInfo { + uint32_t ordinal_index; + uint32_t address_of_name; + bool operator == (uint16_t ordinal_index_) const + { + return (ordinal_index == ordinal_index_); + } + }; + + struct ExportInfo { + PEExport *export_function; + ExportInfo(PEExport *export_function_) : export_function(export_function_) {} + bool operator< (const ExportInfo &obj) const + { + return (export_function->name().compare(obj.export_function->name()) < 0); + } + }; + +}; + +class PEFixup : public BaseFixup +{ +public: + explicit PEFixup(PEFixupList *owner, uint64_t address, uint8_t type); + explicit PEFixup(PEFixupList *owner, const PEFixup &src); + virtual uint64_t address() const { return address_; } + virtual FixupType type() const; + virtual OperandSize size() const; + virtual PEFixup *Clone(IFixupList *owner) const; + uint8_t internal_type() const { return type_; } + virtual void set_address(uint64_t address) { address_ = address; } + virtual void Rebase(IArchitecture &file, uint64_t delta_base); +private: + uint64_t address_; + uint8_t type_; +}; + +class PEFixupList : public BaseFixupList +{ +public: + explicit PEFixupList(); + explicit PEFixupList(const PEFixupList &src); + virtual PEFixupList *Clone() const; + PEFixup *item(size_t index) const; + void ReadFromFile(PEArchitecture &file, PEDirectory &dir); + void WriteToData(Data &data, uint64_t image_base); + size_t WriteToFile(PEArchitecture &file); + virtual IFixup *AddDefault(OperandSize cpu_address_size, bool is_code); +private: + PEFixup *Add(uint64_t address, uint8_t type); + + // no assignment op + PEFixupList &operator =(const PEFixupList &); +}; + +class PERelocation : public BaseRelocation +{ +public: + explicit PERelocation(PERelocationList *owner, uint64_t address, uint64_t source, OperandSize size, uint32_t addend); + explicit PERelocation(PERelocationList *owner, const PERelocation &src); + virtual PERelocation *Clone(IRelocationList *owner) const; + uint64_t source() const { return source_; } + uint32_t addend() const { return addend_; } + virtual ISymbol *symbol() const { return NULL; } +private: + uint64_t source_; + uint32_t addend_; +}; + +class PERelocationList : public BaseRelocationList +{ +public: + explicit PERelocationList(); + explicit PERelocationList(const PERelocationList &src); + virtual PERelocationList *Clone() const; + PERelocation *item(size_t index) const; + void ReadFromFile(PEArchitecture &file); + void WriteToData(Data &data, uint64_t image_base); +private: + void ParseMinGW(PEArchitecture &file, uint64_t address, uint64_t start, uint64_t end); + PERelocation *Add(uint64_t address, uint64_t source, OperandSize size, uint32_t addend); + uint64_t address_; + uint64_t mem_address_; + + // no assignment op + PERelocationList &operator =(const PERelocationList &); +}; + +class PESEHandler : public BaseSEHandler +{ +public: + explicit PESEHandler(ISEHandlerList *owner, uint64_t address); + explicit PESEHandler(ISEHandlerList *owner, const PESEHandler &src); + virtual PESEHandler *Clone(ISEHandlerList *owner) const; + virtual uint64_t address() const { return address_; } + virtual void set_address(uint64_t address) { address_ = address; } + virtual bool is_deleted() const { return deleted_; } + virtual void set_deleted(bool deleted) { deleted_ = deleted; } + void Rebase(uint64_t delta_base); +private: + uint64_t address_; + bool deleted_; +}; + +class PESEHandlerList : public BaseSEHandlerList +{ +public: + explicit PESEHandlerList(); + explicit PESEHandlerList(const PESEHandlerList &src); + virtual PESEHandlerList *Clone() const; + PESEHandler *item(size_t index) const; + virtual PESEHandler *Add(uint64_t address); + void Rebase(uint64_t delta_base); + void Pack(); +}; + +class PECFGAddressTable; + +class PECFGAddress : public IObject +{ +public: + explicit PECFGAddress(PECFGAddressTable *owner, uint64_t address); + explicit PECFGAddress(PECFGAddressTable *owner, const PECFGAddress &src); + ~PECFGAddress(); + PECFGAddress *Clone(PECFGAddressTable *owner) const; + void Rebase(uint64_t delta_base); + uint64_t address() const { return address_; } + void set_data(std::vector<uint8_t> value) { data_ = value; } + std::vector<uint8_t> data() const { return data_; } +private: + PECFGAddressTable *owner_; + uint64_t address_; + std::vector<uint8_t> data_; +}; + +class PECFGAddressTable : public ObjectList<PECFGAddress> +{ +public: + explicit PECFGAddressTable(); + explicit PECFGAddressTable(const PECFGAddressTable &src); + PECFGAddressTable *Clone() const; + PECFGAddress *Add(uint64_t address); + void Rebase(uint64_t delta_base); +}; + +class PELoadConfigDirectory : public IObject +{ +public: + explicit PELoadConfigDirectory(); + explicit PELoadConfigDirectory(const PELoadConfigDirectory &src); + ~PELoadConfigDirectory(); + virtual PELoadConfigDirectory *Clone() const; + void ReadFromFile(PEArchitecture &file, PEDirectory &dir); + size_t WriteToFile(PEArchitecture &file); + void FreeByManager(MemoryManager &manager); + void Rebase(uint64_t delta_base); + uint64_t security_cookie() const { return security_cookie_; } + void set_security_cookie(uint64_t value) { security_cookie_ = value; } + uint64_t cfg_check_function() const { return cfg_check_function_; } + void set_cfg_check_function(uint64_t value) { cfg_check_function_ = value; } + PESEHandlerList *seh_handler_list() const { return seh_handler_list_; } + PECFGAddressTable *cfg_address_list() const { return cfg_address_list_; } + uint64_t seh_table_address() const { return seh_table_address_; } + uint64_t cfg_table_address() const { return cfg_table_address_; } +private: + uint64_t seh_table_address_; + uint64_t security_cookie_; + uint64_t cfg_table_address_; + uint64_t cfg_check_function_; + uint32_t guard_flags_; + PESEHandlerList *seh_handler_list_; + PECFGAddressTable *cfg_address_list_; + + // no assignment op + PELoadConfigDirectory &operator =(const PELoadConfigDirectory &); +}; + +enum PEResourceType { + rtUnknown, + rtCursor = 1, + rtBitmap = 2, + rtIcon = 3, + rtMenu = 4, + rtDialog = 5, + rtStringTable = 6, + rtFontDir = 7, + rtFont = 8, + rtAccelerators = 9, + rtRCData = 10, + rtMessageTable = 11, + rtGroupCursor = 12, + rtGroupIcon = 14, + rtVersionInfo = 16, + rtDlgInclude = 17, + rtPlugPlay = 19, + rtVXD = 20, + rtAniCursor = 21, + rtAniIcon = 22, + rtHTML = 23, + rtManifest = 24, + rtDialogInit = 240, + rtToolbar = 241 +}; + +class PEResource : public BaseResource +{ +public: + explicit PEResource(IResource *owner, PEResourceType type, uint32_t name_offset, uint32_t data_offset); + explicit PEResource(IResource *owner, const PEResource &src); + virtual PEResource *Clone(IResource *owner) const; + PEResource *item(size_t index) const; + virtual uint32_t type() const { return type_; } + virtual uint64_t address() const { return is_directory() ? 0 : address_; } + virtual size_t size() const { return is_directory() ? 0 : data_.item.Size; } + virtual std::string name() const { return has_name() ? "\"" + name_ + "\"" : name_; } + virtual bool is_directory() const { return (data_offset_ & IMAGE_RESOURCE_DATA_IS_DIRECTORY) != 0; } + virtual PEResource *GetResourceByName(const std::string &name) const; + void set_name(const std::string &name) { name_ = name; } + bool has_name() const { return (name_offset_ & IMAGE_RESOURCE_NAME_IS_STRING) != 0; } + bool need_store() const; + virtual std::string id() const; + void ReadFromFile(PEArchitecture &file, uint64_t root_address); + // PE format + void WriteHeader(Data &data); + void WriteEntry(Data &data); + void WriteName(Data &data); + size_t WriteData(Data &data, PEArchitecture &file); + // ResourceManager format + void WriteHeader(IFunction &data); + void WriteEntry(IFunction &data); + void WriteName(IFunction &data, size_t root_index, uint32_t key); + void WriteData(IFunction &data, PEArchitecture &file, uint32_t key); +private: + PEResource *Add(PEResourceType type, uint32_t name_offset, uint32_t data_offset); + + PEResourceType type_; + uint32_t name_offset_; + uint32_t data_offset_; + union { + IMAGE_RESOURCE_DIRECTORY dir; + IMAGE_RESOURCE_DATA_ENTRY item; + } data_; + std::string name_; + uint64_t address_; + size_t entry_offset_; + size_t data_entry_offset_; +}; + +class PEResourceList : public BaseResourceList +{ +public: + explicit PEResourceList(PEArchitecture *owner); + explicit PEResourceList(PEArchitecture *owner, const PEResourceList &src); + + using BaseResourceList::Clone; + PEResourceList *Clone(PEArchitecture *owner) const; + PEResource *item(size_t index) const; + void ReadFromFile(PEArchitecture &file, PEDirectory &dir); + size_t WriteToFile(PEArchitecture &file, uint64_t address); + void Compile(PEArchitecture &file, bool for_packing); + size_t size() const { return data_.size(); } + size_t store_size() const { return store_size_; } + void WritePackData(Data &data); + void CreateCommands(PEArchitecture &file, IFunction &data); +private: + PEResource *Add(PEResourceType type, uint32_t name_offset, uint32_t data_offset); + IMAGE_RESOURCE_DIRECTORY dir_; + Data data_; + std::vector<size_t> link_list_; + size_t store_size_; +}; + +class PERuntimeFunction : public BaseRuntimeFunction +{ +public: + explicit PERuntimeFunction(PERuntimeFunctionList *owner, uint64_t address, uint64_t begin, uint64_t end, uint64_t unwind_address); + explicit PERuntimeFunction(PERuntimeFunctionList *owner, const PERuntimeFunction &src); + virtual PERuntimeFunction *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_; } + 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; } + virtual void Rebase(uint64_t delta_base); + virtual void Parse(IArchitecture &file, IFunction &dest); +private: + uint64_t address_; + uint64_t begin_; + uint64_t end_; + uint64_t unwind_address_; +}; + +class PERuntimeFunctionList : public BaseRuntimeFunctionList +{ +public: + explicit PERuntimeFunctionList(); + explicit PERuntimeFunctionList(const PERuntimeFunctionList &src); + PERuntimeFunctionList *Clone() const; + PERuntimeFunction *item(size_t index) const; + void ReadFromFile(PEArchitecture &file, PEDirectory &directory); + size_t WriteToFile(PEArchitecture &file); + virtual PERuntimeFunction *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 PERuntimeFunction *GetFunctionByAddress(uint64_t address) const; + void RebaseByFile(IArchitecture &file, uint64_t target_image_base, uint64_t delta_base); + void FreeByManager(MemoryManager &manager); + uint64_t address() const { return address_; } +private: + uint64_t RebaseDWord(IArchitecture &file, uint32_t delta_base); + uint64_t address_; + + // no assignment op + PERuntimeFunctionList &operator =(const PERuntimeFunctionList &); +}; + +class PETLSDirectory : public ReferenceList +{ +public: + explicit PETLSDirectory(); + explicit PETLSDirectory(const PETLSDirectory &src); + PETLSDirectory *Clone() const; + void ReadFromFile(PEArchitecture &file, PEDirectory &directory); + void FreeByManager(MemoryManager &manager); + uint64_t address() const { return address_; } + uint64_t start_address_of_raw_data() const { return start_address_of_raw_data_; } + uint64_t end_address_of_raw_data() const { return end_address_of_raw_data_; } + uint64_t address_of_index() const { return address_of_index_; } + uint64_t address_of_call_backs() const { return address_of_call_backs_; } + uint32_t size_of_zero_fill() const { return size_of_zero_fill_; } + uint32_t characteristics() const { return characteristics_; } + void set_start_address_of_raw_data(uint64_t value) { start_address_of_raw_data_ = value; } + void set_end_address_of_raw_data(uint64_t value) { end_address_of_raw_data_ = value; } +private: + uint64_t address_; + uint64_t start_address_of_raw_data_; + uint64_t end_address_of_raw_data_; + uint64_t address_of_index_; + uint64_t address_of_call_backs_; + uint32_t size_of_zero_fill_; + uint32_t characteristics_; + + // no assignment op + PETLSDirectory &operator =(const PETLSDirectory &); +}; + +class PEDebugDirectory; + +class PEDebugData : public IObject +{ +public: + explicit PEDebugData(PEDebugDirectory *owner); + explicit PEDebugData(PEDebugDirectory *owner, const PEDebugData &src); + ~PEDebugData(); + PEDebugData *Clone(PEDebugDirectory *owner) const; + void ReadFromFile(PEArchitecture &file); + void WriteToFile(PEArchitecture &file); + uint64_t address() const { return address_; } + uint32_t offset() const { return offset_; } + uint32_t size() const { return size_; } + uint32_t type() const { return type_; } + void set_address(uint64_t address) { address_ = address; } + void set_offset(uint32_t offset) { offset_ = offset; } +private: + PEDebugDirectory *owner_; + uint32_t characteristics_; + uint32_t time_date_stamp_; + uint16_t major_version_; + uint16_t minor_version_; + uint32_t type_; + uint32_t size_; + uint64_t address_; + uint32_t offset_; +}; + +class PEDebugDirectory : public ObjectList<PEDebugData> +{ +public: + explicit PEDebugDirectory(); + explicit PEDebugDirectory(const PEDebugDirectory &src); + PEDebugDirectory *Clone() const; + uint64_t address() const { return address_; } + void ReadFromFile(PEArchitecture &file, PEDirectory &directory); + void WriteToFile(PEArchitecture &file); + void FreeByManager(MemoryManager &manager) const; +private: + PEDebugData *Add(); + uint64_t address_; + + // not impl + PEDebugDirectory &operator =(const PEDebugDirectory &); +}; + +class pdb_reader; + +class PDBFile : public BaseMapFile +{ +public: + explicit PDBFile(); + virtual bool Parse(const char *file_name, const std::vector<uint64_t> &segments); + virtual std::string file_name() const { return file_name_; } + virtual uint64_t time_stamp() const { return time_stamp_; } + std::vector<uint8_t> guid() const { return guid_; } + void set_time_stamp(uint64_t value) { time_stamp_ = value; } +private: + bool ReadSymbols(pdb_reader &reader); + void codeview_dump_symbols(const std::vector<uint8_t> &root, size_t offset); + std::string GetTypeName(size_t type, const std::string &name); + void AddSymbol(size_t segment, size_t offset, const std::string &name); + void AddSection(size_t segment, size_t offset, uint64_t size, const std::string &name); + + std::string file_name_; + uint64_t time_stamp_; + std::vector<uint8_t> guid_; + std::vector<uint64_t> segments_; + size_t types_first_index_; + std::vector<uint8_t> types_data_; + std::vector<const union codeview_type *> types_offset_; + std::set<std::pair<uint64_t, std::string> > map_; +}; + +class COFFStringTable +{ +public: + std::string GetString(uint32_t pos) const; + void ReadFromFile(PEArchitecture &file); + void ReadFromFile(FileStream &file); +private: + std::vector<char> data_; +}; + +class COFFFile : public BaseMapFile +{ +public: + bool Parse(const char *file_name, const std::vector<uint64_t> &segments); + virtual std::string file_name() const { return file_name_; } + virtual uint64_t time_stamp() const { return time_stamp_; } +private: + void AddSymbol(size_t segment, size_t offset, const std::string &name); + uint64_t time_stamp_; + std::string file_name_; + std::vector<uint64_t> segments_; +}; + +class PEFile; + +enum ImageType { + itExe, + itLibrary, + itDriver +}; + +class PEArchitecture : public BaseArchitecture +{ +public: + explicit PEArchitecture(PEFile *owner, uint64_t offset, uint64_t size); + explicit PEArchitecture(PEFile *owner, const PEArchitecture &src); + virtual ~PEArchitecture(); + virtual PEArchitecture *Clone(IFile *file) const; + OpenStatus ReadFromFile(uint32_t mode); + virtual void ReadFromBuffer(Buffer &buffer); + void WriteCheckSum(); + virtual bool WriteToFile(); + virtual bool is_executable() const; + virtual std::string name() const; + virtual uint32_t type() const { return cpu_; } + virtual OperandSize cpu_address_size() const { return cpu_address_size_; } + virtual uint64_t entry_point() const { return entry_point_; } + void set_entry_point(uint64_t entry_point) { entry_point_ = entry_point; } + virtual uint32_t segment_alignment() const { return segment_alignment_; } + virtual uint32_t file_alignment() const { return file_alignment_; } + virtual uint64_t image_base() const { return image_base_; } + virtual PEDirectoryList *command_list() const { return directory_list_; } + virtual PESegmentList *segment_list() const { return segment_list_; } + virtual PESectionList *section_list() const { return section_list_; } + virtual PEImportList *import_list() const { return import_list_; } + virtual PEExportList *export_list() const { return export_list_; } + virtual PEFixupList *fixup_list() const { return fixup_list_; } + virtual PERelocationList *relocation_list() const { return relocation_list_; } + virtual PEResourceList *resource_list() const { return resource_list_; } + virtual PESEHandlerList *seh_handler_list() const { return load_config_directory_->seh_handler_list(); } + PETLSDirectory *tls_directory() const { return tls_directory_; } + PELoadConfigDirectory *load_config_directory() const { return load_config_directory_; } + PEDelayImportList *delay_import_list() const { return delay_import_list_; } + virtual IFunctionList *function_list() const { return function_list_; } + virtual IVirtualMachineList *virtual_machine_list() const { return virtual_machine_list_; } + virtual PERuntimeFunctionList *runtime_function_list() const { return runtime_function_list_; } + virtual bool Compile(CompileOptions &options, IArchitecture *runtime); + virtual void Save(CompileContext &ctx); + ImageType image_type() const { return image_type_; } + void Rebase(uint64_t target_image_base, uint64_t delta_base); + virtual CallingConvention calling_convention() const { return (cpu_address_size() == osDWord) ? ccStdcall : ccMSx64; } + virtual uint64_t time_stamp() const { return time_stamp_; } + PESegment *resource_section() const { return resource_section_; } + PESegment *fixup_section() const { return fixup_section_; } + uint32_t header_offset() const { return header_offset_; } + uint32_t header_size() const { return header_size_; } + virtual std::string ANSIToUTF8(const std::string &str) const; + uint16_t dll_characteristics() const { return dll_characteristics_; } + std::string pdb_file_name() const; + uint32_t operating_system_version() const { return operating_system_version_; } +protected: + virtual bool Prepare(CompileContext &ctx); + virtual bool ReadMapFile(IMapFile &map_file); +private: + enum { + MIN_HEADER_OFFSET = 0x80 + }; + PEDirectoryList *directory_list_; + PESegmentList *segment_list_; + PESectionList *section_list_; + PEImportList *import_list_; + PEExportList *export_list_; + PEFixupList *fixup_list_; + PERelocationList *relocation_list_; + IFunctionList *function_list_; + PEResourceList *resource_list_; + PELoadConfigDirectory *load_config_directory_; + IVirtualMachineList *virtual_machine_list_; + PERuntimeFunctionList *runtime_function_list_; + PETLSDirectory *tls_directory_; + PEDebugDirectory *debug_directory_; + PEDelayImportList *delay_import_list_; + uint32_t cpu_; + OperandSize cpu_address_size_; + uint64_t time_stamp_; + uint64_t entry_point_; + uint64_t image_base_; + uint32_t header_offset_; + uint32_t header_size_; + uint32_t segment_alignment_; + uint32_t file_alignment_; + PESegment *resource_section_; + PESegment *fixup_section_; + size_t optimized_section_count_; + ImageType image_type_; + uint16_t characterictics_; + uint32_t check_sum_; + uint32_t low_resize_header_; + uint32_t resize_header_; + uint32_t operating_system_version_; + uint32_t subsystem_version_; + uint16_t dll_characteristics_; + + // no copy ctr or assignment op + PEArchitecture(const PEArchitecture &); + PEArchitecture &operator =(const PEArchitecture &); +}; + +class NETArchitecture; + +class PEFile : public IFile +{ +public: + explicit PEFile(ILog *log = NULL); + explicit PEFile(const PEFile &src, const char *file_name); + virtual ~PEFile(); + virtual std::string format_name() const; + virtual PEFile *Clone(const char *file_name) const; + virtual bool Compile(CompileOptions &options); + virtual std::string version() const; + virtual bool is_executable() const; + virtual uint32_t disable_options() const; + bool GetCheckSum(uint32_t *check_sum); + PEArchitecture *arch_pe() const { return count() > 0 ? dynamic_cast<PEArchitecture *>(item(0)) : NULL; } + virtual std::string exec_command() const; +protected: + virtual OpenStatus ReadHeader(uint32_t open_mode); + bool WriteHeader(); + virtual IFile *runtime() const { return runtime_; }; +private: + PEFile *runtime_; + + // no copy ctr or assignment op + PEFile(const PEFile &); + PEFile &operator =(const PEFile &); +}; + +#endif
\ No newline at end of file |