From 554fa153af943b97a16fc4a52ab8459a3d0a9bc7 Mon Sep 17 00:00:00 2001 From: Romain Thomas Date: Thu, 28 Sep 2017 20:50:38 +0200 Subject: [PATCH] Fix MachO meme leaks (related #99) --- CMakeLists.txt | 1 - include/LIEF/BinaryStream/BinaryStream.hpp | 1 + include/LIEF/BinaryStream/VectorStream.hpp | 1 + include/LIEF/ELF/DataHandler/Handler.hpp | 2 +- include/LIEF/MachO/Relocation.hpp | 4 +- include/LIEF/MachO/RelocationDyld.hpp | 2 + include/LIEF/MachO/RelocationObject.hpp | 6 +- include/LIEF/MachO/SegmentCommand.hpp | 2 +- src/BinaryStream/VectorStream.cpp | 19 +++- src/MachO/BinaryParser.cpp | 51 ++++++---- src/MachO/BinaryParser.tcc | 109 ++++++++++++--------- src/MachO/Parser.cpp | 22 +++-- src/MachO/Relocation.cpp | 5 + src/MachO/RelocationDyld.cpp | 5 + src/MachO/RelocationObject.cpp | 18 +++- src/MachO/SegmentCommand.cpp | 16 ++- src/PE/Parser.cpp | 2 +- 17 files changed, 169 insertions(+), 97 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 907d2d2..3c3d0e0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -284,7 +284,6 @@ if (LIEF_FUZZING) set_source_files_properties(${LIBFUZZER_SRC_FILES} PROPERTIES GENERATED TRUE) - add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/fuzzing") endif() diff --git a/include/LIEF/BinaryStream/BinaryStream.hpp b/include/LIEF/BinaryStream/BinaryStream.hpp index e56ed20..f8f7023 100644 --- a/include/LIEF/BinaryStream/BinaryStream.hpp +++ b/include/LIEF/BinaryStream/BinaryStream.hpp @@ -28,6 +28,7 @@ class BinaryStream { virtual uint64_t size(void) const = 0; virtual const void* read(uint64_t offset, uint64_t size) const = 0; virtual const char* read_string(uint64_t offset, uint64_t size) const = 0; + virtual std::string get_string(uint64_t offset, uint64_t size) const = 0; template T read_integer(uint64_t offset, bool swap = false) const; diff --git a/include/LIEF/BinaryStream/VectorStream.hpp b/include/LIEF/BinaryStream/VectorStream.hpp index c7ff2c2..7e30e0c 100644 --- a/include/LIEF/BinaryStream/VectorStream.hpp +++ b/include/LIEF/BinaryStream/VectorStream.hpp @@ -30,6 +30,7 @@ class VectorStream : public BinaryStream { virtual uint64_t size(void) const override; virtual const void* read(uint64_t offset, uint64_t size) const override; virtual const char* read_string(uint64_t offset, uint64_t size = 0) const override; + virtual std::string get_string(uint64_t offset, uint64_t size = 0) const override; const std::vector& content(void) const; diff --git a/include/LIEF/ELF/DataHandler/Handler.hpp b/include/LIEF/ELF/DataHandler/Handler.hpp index 8386349..2dc04e3 100644 --- a/include/LIEF/ELF/DataHandler/Handler.hpp +++ b/include/LIEF/ELF/DataHandler/Handler.hpp @@ -26,7 +26,7 @@ namespace ELF { namespace DataHandler { class DLL_PUBLIC Handler { public: - static constexpr size_t MAX_SIZE = 10_GB; + static constexpr size_t MAX_SIZE = 3_GB; Handler(const std::vector& content); Handler(std::vector&& content); ~Handler(void); diff --git a/include/LIEF/MachO/Relocation.hpp b/include/LIEF/MachO/Relocation.hpp index 8844a24..cf64170 100644 --- a/include/LIEF/MachO/Relocation.hpp +++ b/include/LIEF/MachO/Relocation.hpp @@ -49,12 +49,14 @@ class DLL_PUBLIC Relocation : public LIEF::Relocation { Relocation(void); Relocation(uint64_t address, uint8_t type); - //Relocation& operator=(Relocation other); + //Relocation& operator=(const Relocation& other); Relocation(const Relocation& other); void swap(Relocation& other); virtual ~Relocation(void); + virtual Relocation* clone(void) const = 0; + //! @brief For @link MachO::FILE_TYPES::MH_OBJECT object @endlink this is an //! offset from the start of the @link MachO::Section section @endlink //! to the item containing the address requiring relocation. diff --git a/include/LIEF/MachO/RelocationDyld.hpp b/include/LIEF/MachO/RelocationDyld.hpp index 49ce221..7c2b2fc 100644 --- a/include/LIEF/MachO/RelocationDyld.hpp +++ b/include/LIEF/MachO/RelocationDyld.hpp @@ -45,6 +45,8 @@ class DLL_PUBLIC RelocationDyld : public Relocation { virtual ~RelocationDyld(void); + virtual Relocation* clone(void) const override; + //! @brief Indicates whether the item containing the address to be //! relocated is part of a CPU instruction that uses PC-relative addressing. //! diff --git a/include/LIEF/MachO/RelocationObject.hpp b/include/LIEF/MachO/RelocationObject.hpp index e24c9ca..45bdd36 100644 --- a/include/LIEF/MachO/RelocationObject.hpp +++ b/include/LIEF/MachO/RelocationObject.hpp @@ -42,13 +42,15 @@ class DLL_PUBLIC RelocationObject : public Relocation { RelocationObject(const relocation_info *relocinfo); RelocationObject(const scattered_relocation_info *scattered_relocinfo); - RelocationObject& operator=(const RelocationObject&); - RelocationObject(const RelocationObject&); + RelocationObject& operator=(RelocationObject other); + RelocationObject(const RelocationObject& other); void swap(RelocationObject& other); virtual ~RelocationObject(void); + virtual RelocationObject* clone(void) const override; + virtual bool is_pc_relative(void) const override; virtual size_t size(void) const override; diff --git a/include/LIEF/MachO/SegmentCommand.hpp b/include/LIEF/MachO/SegmentCommand.hpp index 35cd6d7..8ec79dc 100644 --- a/include/LIEF/MachO/SegmentCommand.hpp +++ b/include/LIEF/MachO/SegmentCommand.hpp @@ -113,7 +113,7 @@ class DLL_PUBLIC SegmentCommand : public LoadCommand { std::vector data_; - std::vector
sections_; + sections_t sections_; relocations_t relocations_; diff --git a/src/BinaryStream/VectorStream.cpp b/src/BinaryStream/VectorStream.cpp index e654fe8..d53a9cd 100644 --- a/src/BinaryStream/VectorStream.cpp +++ b/src/BinaryStream/VectorStream.cpp @@ -86,12 +86,27 @@ const char* VectorStream::read_string(uint64_t offset, uint64_t size) const { throw LIEF::read_out_of_bound(offset); } + + uint64_t max_size = this->size() - (offset + size); if (size > 0) { - return reinterpret_cast(this->read(offset, size)); + max_size = std::min(max_size, size); } - return reinterpret_cast(this->binary_.data() + offset); + return reinterpret_cast(this->read(offset, max_size)); +} +std::string VectorStream::get_string(uint64_t offset, uint64_t size) const { + + if ((offset + size) > this->size()) { + throw LIEF::read_out_of_bound(offset); + } + + uint64_t max_size = this->size() - (offset + size); + if (size > 0) { + max_size = std::min(max_size, size); + } + std::string tmp{this->read_string(offset, max_size), max_size}; + return tmp.c_str(); } diff --git a/src/MachO/BinaryParser.cpp b/src/MachO/BinaryParser.cpp index 5dd85cb..7531c41 100644 --- a/src/MachO/BinaryParser.cpp +++ b/src/MachO/BinaryParser.cpp @@ -86,26 +86,30 @@ BinaryParser::BinaryParser(const std::string& file) : void BinaryParser::init(void) { VLOG(VDEBUG) << "Parsing MachO" << std::endl; - MACHO_TYPES type = static_cast( - *reinterpret_cast(this->stream_->read(0, sizeof(uint32_t)))); + try { + MACHO_TYPES type = static_cast( + *reinterpret_cast(this->stream_->read(0, sizeof(uint32_t)))); - if (type == MACHO_TYPES::MH_MAGIC_64 or - type == MACHO_TYPES::MH_CIGAM_64 ) - { - this->is64_ = true; - } - else - { - this->is64_ = false; - } + if (type == MACHO_TYPES::MH_MAGIC_64 or + type == MACHO_TYPES::MH_CIGAM_64 ) + { + this->is64_ = true; + } + else + { + this->is64_ = false; + } - this->binary_->is64_ = this->is64_; - this->type_ = type; + this->binary_->is64_ = this->is64_; + this->type_ = type; - if (this->is64_) { - this->parse(); - } else { - this->parse(); + if (this->is64_) { + this->parse(); + } else { + this->parse(); + } + } catch (const std::exception& e) { + VLOG(VDEBUG) << e.what(); } } @@ -117,6 +121,10 @@ void BinaryParser::parse_export_trie(uint64_t start, uint64_t current_offset, ui return; } + if (start < current_offset) { + return; + } + const uint8_t terminal_size = this->stream_->read_integer(current_offset); current_offset += sizeof(uint8_t); @@ -134,11 +142,11 @@ void BinaryParser::parse_export_trie(uint64_t start, uint64_t current_offset, ui current_offset += std::get<1>(value_delta); const std::string& symbol_name = prefix; - ExportInfo* export_info = new ExportInfo{address, flags, offset}; + std::unique_ptr export_info{new ExportInfo{address, flags, offset}}; if (this->binary_->has_symbol(symbol_name)) { Symbol& symbol = this->binary_->get_symbol(symbol_name); export_info->symbol_ = &symbol; - symbol.export_info_ = export_info; + symbol.export_info_ = export_info.get(); //if (symbol.is_external()) { // //LOG(WARNING) << "FOOOOO " << symbol_name; // //TODO @@ -146,7 +154,7 @@ void BinaryParser::parse_export_trie(uint64_t start, uint64_t current_offset, ui } else { LOG(WARNING) << "'" << symbol_name << "' is not registred"; } - this->binary_->dyld_info().export_info_.push_back(export_info); + this->binary_->dyld_info().export_info_.push_back(export_info.release()); } @@ -161,6 +169,9 @@ void BinaryParser::parse_export_trie(uint64_t start, uint64_t current_offset, ui value_delta = this->stream_->read_uleb128(children_offset); uint32_t child_node_offet = static_cast(std::get<0>(value_delta)); children_offset += std::get<1>(value_delta); + if (start + child_node_offet == start) { + break; + } this->parse_export_trie(start, start + child_node_offet, end, name); } diff --git a/src/MachO/BinaryParser.tcc b/src/MachO/BinaryParser.tcc index 29c8ef7..6b69abf 100644 --- a/src/MachO/BinaryParser.tcc +++ b/src/MachO/BinaryParser.tcc @@ -99,7 +99,7 @@ void BinaryParser::parse_load_commands(void) { const load_command* command = reinterpret_cast( this->stream_->read(loadcommands_offset, sizeof(load_command))); - LoadCommand* load_command = nullptr; + std::unique_ptr load_command{nullptr}; switch (command->cmd) { // =============== @@ -109,13 +109,13 @@ void BinaryParser::parse_load_commands(void) { case LOAD_COMMAND_TYPES::LC_SEGMENT: { uint64_t local_offset = loadcommands_offset; - load_command = new SegmentCommand{ + load_command = std::unique_ptr{new SegmentCommand{ reinterpret_cast( - this->stream_->read(loadcommands_offset, sizeof(segment_command_t)))}; + this->stream_->read(loadcommands_offset, sizeof(segment_command_t)))}}; local_offset += sizeof(segment_command_t); - SegmentCommand* segment = dynamic_cast(load_command); + SegmentCommand* segment = dynamic_cast(load_command.get()); const uint8_t* content = static_cast( this->stream_->read(segment->file_offset(), segment->file_size())); @@ -129,9 +129,10 @@ void BinaryParser::parse_load_commands(void) { // Sections // -------- for (size_t j = 0; j < segment->numberof_sections(); ++j) { - Section section{reinterpret_cast(this->stream_->read(local_offset, sizeof(section_t)))}; - section.segment_ = segment; - segment->sections_.push_back(std::move(section)); + const section_t* section_header = reinterpret_cast(this->stream_->read(local_offset, sizeof(section_t))); + std::unique_ptr
section{new Section{section_header}}; + section->segment_ = segment; + segment->sections_.push_back(section.release()); local_offset += sizeof(section_t); } break; @@ -149,11 +150,11 @@ void BinaryParser::parse_load_commands(void) { reinterpret_cast( this->stream_->read(loadcommands_offset, sizeof(dylib_command))); - load_command = new DylibCommand{cmd}; + load_command = std::unique_ptr{new DylibCommand{cmd}}; const uint32_t str_name_offset = cmd->dylib.name; std::string name = {this->stream_->read_string(loadcommands_offset + str_name_offset)}; - dynamic_cast(load_command)->name(name); + dynamic_cast(load_command.get())->name(name); break; } @@ -166,7 +167,7 @@ void BinaryParser::parse_load_commands(void) { const uuid_command* cmd = reinterpret_cast( this->stream_->read(loadcommands_offset, sizeof(uuid_command))); - load_command = new UUIDCommand{cmd}; + load_command = std::unique_ptr{new UUIDCommand{cmd}}; break; } @@ -185,8 +186,8 @@ void BinaryParser::parse_load_commands(void) { loadcommands_offset + linker_name_offset)}; - load_command = new DylinkerCommand{cmd}; - dynamic_cast(load_command)->name(name); + load_command = std::unique_ptr{new DylinkerCommand{cmd}}; + dynamic_cast(load_command.get())->name(name); break; } @@ -197,7 +198,7 @@ void BinaryParser::parse_load_commands(void) { { VLOG(VDEBUG) << "[+] Parsing LC_PREBOUND_DYLIB"; - load_command = new LoadCommand{command}; + load_command = std::unique_ptr{new LoadCommand{command}}; const prebound_dylib_command* cmd = reinterpret_cast( this->stream_->read(loadcommands_offset, sizeof(prebound_dylib_command))); @@ -223,8 +224,10 @@ void BinaryParser::parse_load_commands(void) { const thread_command* cmd = reinterpret_cast( this->stream_->read(loadcommands_offset, sizeof(thread_command))); - load_command = new ThreadCommand{cmd}; - dynamic_cast(load_command)->architecture_ = this->binary_->header().cpu_type(); + load_command = std::unique_ptr{new ThreadCommand{cmd}}; + + ThreadCommand* thread = dynamic_cast(load_command.get()); + thread->architecture_ = this->binary_->header().cpu_type(); VLOG(VDEBUG) << "FLAVOR: " << cmd->flavor << std::endl << "COUNT: " << cmd->count; switch(this->binary_->header().cpu_type()) { @@ -232,7 +235,7 @@ void BinaryParser::parse_load_commands(void) { { const uint8_t* pstart = reinterpret_cast( this->stream_->read(loadcommands_offset + sizeof(thread_command), sizeof(x86_thread_state_t))); - dynamic_cast(load_command)->state_ = {pstart, pstart + sizeof(x86_thread_state_t)}; + thread->state_ = {pstart, pstart + sizeof(x86_thread_state_t)}; break; } @@ -241,7 +244,7 @@ void BinaryParser::parse_load_commands(void) { { const uint8_t* pstart = reinterpret_cast( this->stream_->read(loadcommands_offset + sizeof(thread_command), sizeof(x86_thread_state64_t))); - dynamic_cast(load_command)->state_ = {pstart, pstart + sizeof(x86_thread_state64_t)}; + thread->state_ = {pstart, pstart + sizeof(x86_thread_state64_t)}; break; } @@ -249,7 +252,7 @@ void BinaryParser::parse_load_commands(void) { { const uint8_t* pstart = reinterpret_cast( this->stream_->read(loadcommands_offset + sizeof(thread_command), sizeof(arm_thread_state_t))); - dynamic_cast(load_command)->state_ = {pstart, pstart + sizeof(arm_thread_state_t)}; + thread->state_ = {pstart, pstart + sizeof(arm_thread_state_t)}; break; } @@ -257,7 +260,7 @@ void BinaryParser::parse_load_commands(void) { { const uint8_t* pstart = reinterpret_cast( this->stream_->read(loadcommands_offset + sizeof(thread_command), sizeof(arm_thread_state64_t))); - dynamic_cast(load_command)->state_ = {pstart, pstart + sizeof(arm_thread_state64_t)}; + thread->state_ = {pstart, pstart + sizeof(arm_thread_state64_t)}; break; } default: @@ -277,7 +280,7 @@ void BinaryParser::parse_load_commands(void) { VLOG(VDEBUG) << "[+] Parsing LC_ROUTINE"; - load_command = new LoadCommand{command}; + load_command = std::unique_ptr{new LoadCommand{command}}; break; } @@ -294,20 +297,20 @@ void BinaryParser::parse_load_commands(void) { this->stream_->read(loadcommands_offset, sizeof(symtab_command))); - load_command = new SymbolCommand{cmd}; + load_command = std::unique_ptr{new SymbolCommand{cmd}}; const nlist_t* nlist = reinterpret_cast( this->stream_->read(cmd->symoff, sizeof(nlist_t))); for (size_t j = 0; j < cmd->nsyms; ++j) { - Symbol* symbol = new Symbol{&nlist[j]}; + std::unique_ptr symbol{new Symbol{&nlist[j]}}; uint32_t idx = nlist[j].n_strx; if (idx > 0) { symbol->name( this->stream_->read_string(cmd->stroff + idx)); } - this->binary_->symbols_.push_back(symbol); + this->binary_->symbols_.push_back(symbol.release()); } break; @@ -323,7 +326,7 @@ void BinaryParser::parse_load_commands(void) { reinterpret_cast( this->stream_->read(loadcommands_offset, sizeof(dysymtab_command))); - load_command = new DynamicSymbolCommand{cmd}; + load_command = std::unique_ptr{new DynamicSymbolCommand{cmd}}; break; } @@ -338,7 +341,7 @@ void BinaryParser::parse_load_commands(void) { reinterpret_cast( this->stream_->read(loadcommands_offset, sizeof(dyld_info_command))); - load_command = new DyldInfo{cmd}; + load_command = std::unique_ptr{new DyldInfo{cmd}}; break; } @@ -353,7 +356,7 @@ void BinaryParser::parse_load_commands(void) { reinterpret_cast( this->stream_->read(loadcommands_offset, sizeof(version_min_command))); - load_command = new SourceVersion{cmd}; + load_command = std::unique_ptr{new SourceVersion{cmd}}; VLOG(VDEBUG) << "Version: " << std::hex << cmd->version; break; } @@ -369,7 +372,7 @@ void BinaryParser::parse_load_commands(void) { VLOG(VDEBUG) << "Version: " << std::hex << cmd->version; VLOG(VDEBUG) << "SDK: " << std::hex << cmd->sdk; - load_command = new VersionMin{cmd}; + load_command = std::unique_ptr{new VersionMin{cmd}}; break; } @@ -427,7 +430,7 @@ void BinaryParser::parse_load_commands(void) { reinterpret_cast( this->stream_->read(loadcommands_offset, sizeof(entry_point_command))); - load_command = new MainCommand{cmd}; + load_command = std::unique_ptr{new MainCommand{cmd}}; break; } @@ -440,12 +443,12 @@ void BinaryParser::parse_load_commands(void) { const linkedit_data_command* cmd = reinterpret_cast( this->stream_->read(loadcommands_offset, sizeof(linkedit_data_command))); - load_command = new FunctionStarts{cmd}; + load_command = std::unique_ptr{new FunctionStarts{cmd}}; uint64_t offset = cmd->dataoff; std::pair value_delta; uint64_t value = 0; - + FunctionStarts* fstart = dynamic_cast(load_command.get()); do { value_delta = this->stream_->read_uleb128(offset); if (std::get<0>(value_delta) == 0) { @@ -455,7 +458,7 @@ void BinaryParser::parse_load_commands(void) { offset += std::get<1>(value_delta); VLOG(VDEBUG) << "Value: " << std::hex << value; - dynamic_cast(load_command)->add_function(value); + fstart->add_function(value); } while(offset < (cmd->dataoff + cmd->datasize) and std::get<0>(value_delta) > 0); break; @@ -473,7 +476,7 @@ void BinaryParser::parse_load_commands(void) { LOG(WARNING) << "Command '" << to_string(static_cast(command->cmd)) << "' not parsed"; - load_command = new LoadCommand{command}; + load_command = std::unique_ptr{new LoadCommand{command}}; } } @@ -487,7 +490,7 @@ void BinaryParser::parse_load_commands(void) { }); load_command->command_offset(loadcommands_offset); - this->binary_->commands_.push_back(load_command); + this->binary_->commands_.push_back(load_command.release()); } loadcommands_offset += command->cmdsize; } @@ -511,20 +514,25 @@ void BinaryParser::parse_relocations(Section& section) { << "Only the first " << std::dec << numberof_relocations << " will be parsed"; } + if (current_reloc_offset + numberof_relocations * 2 * sizeof(uint32_t) > this->stream_->size()) { + LOG(WARNING) << "Relocations corrupted"; + return; + } + std::unique_ptr reloc{nullptr}; for (size_t i = 0; i < numberof_relocations; ++i) { int32_t address = this->stream_->read_integer(current_reloc_offset); bool is_scattered = static_cast(address & R_SCATTERED); - RelocationObject* reloc = nullptr; + if (is_scattered) { const scattered_relocation_info* reloc_info = reinterpret_cast( - this->stream_->read(current_reloc_offset, sizeof(scattered_relocation_info))); - reloc = new RelocationObject{reloc_info}; + this->stream_->read(current_reloc_offset, sizeof(scattered_relocation_info))); + reloc = std::unique_ptr{new RelocationObject{reloc_info}}; reloc->section_ = §ion; } else { const relocation_info* reloc_info = reinterpret_cast( this->stream_->read(current_reloc_offset, sizeof(relocation_info))); - reloc = new RelocationObject{reloc_info}; + reloc = std::unique_ptr{new RelocationObject{reloc_info}}; reloc->section_ = §ion; if (reloc_info->r_extern == 1 and reloc_info->r_symbolnum != R_ABS) { @@ -548,15 +556,20 @@ void BinaryParser::parse_relocations(Section& section) { LOG(WARNING) << "Relocation #" << std::dec << i << " of " << section.name() << " seems corrupted"; } } - } - if (not reloc->has_section()) { - reloc->section_ = §ion; + if (reloc) { + if (not reloc->has_section()) { + reloc->section_ = §ion; + } + reloc->architecture_ = this->binary_->header().cpu_type(); + RelocationObject *r = reloc.release(); + auto&& result = section.relocations_.emplace(r); + if (not result.second) { // Not inserted (Relocation already present) + delete r; + } } - reloc->architecture_ = this->binary_->header().cpu_type(); - section.relocations_.emplace(reloc); current_reloc_offset += 2 * sizeof(uint32_t); } @@ -1355,6 +1368,7 @@ void BinaryParser::do_bind(BINDING_CLASS cls, // Check if a relocation already exists: Relocation* reloc = nullptr; + std::unique_ptr new_relocation{nullptr}; bool reloc_exists = false; auto&& it_reloc = std::find_if( @@ -1368,7 +1382,8 @@ void BinaryParser::do_bind(BINDING_CLASS cls, reloc = *it_reloc; reloc_exists = true; } else { - reloc = new RelocationDyld{address, type}; + new_relocation = std::unique_ptr{new RelocationDyld{address, type}}; + reloc = new_relocation.get(); } reloc->architecture_ = this->binary_->header().cpu_type(); @@ -1404,7 +1419,7 @@ void BinaryParser::do_bind(BINDING_CLASS cls, } // Create a BindingInfo object - BindingInfo* binding_info = new BindingInfo{cls, static_cast(type), address, addend, ord, is_weak}; + std::unique_ptr binding_info{new BindingInfo{cls, static_cast(type), address, addend, ord, is_weak}}; binding_info->segment_ = &segment; @@ -1425,15 +1440,15 @@ void BinaryParser::do_bind(BINDING_CLASS cls, reloc->symbol_ = &symbol; //symbol.value(address); binding_info->symbol_ = &symbol; - symbol.binding_info_ = binding_info; + symbol.binding_info_ = binding_info.get(); } else { LOG(ERROR) << "New symbol found: " << symbol_name; } if (not reloc_exists) { - segment.relocations_.emplace(reloc); + segment.relocations_.emplace(new_relocation.release()); } - this->binary_->dyld_info().binding_info_.push_back(binding_info); + this->binary_->dyld_info().binding_info_.push_back(binding_info.release()); VLOG(VDEBUG) << to_string(cls) << segment.name() << " - " << symbol_name; } diff --git a/src/MachO/Parser.cpp b/src/MachO/Parser.cpp index cc88180..d342ba3 100644 --- a/src/MachO/Parser.cpp +++ b/src/MachO/Parser.cpp @@ -118,16 +118,20 @@ void Parser::build_fat(void) { } void Parser::build(void) { - MACHO_TYPES type = static_cast( - *reinterpret_cast(this->stream_->read(0, sizeof(uint32_t)))); + try { + MACHO_TYPES type = static_cast( + *reinterpret_cast(this->stream_->read(0, sizeof(uint32_t)))); - // Fat binary - if (type == MACHO_TYPES::FAT_MAGIC or - type == MACHO_TYPES::FAT_CIGAM) { - this->build_fat(); - } else { // fit binary - Binary *binary = BinaryParser(std::move(this->stream_)).get_binary(); - this->binaries_.push_back(binary); + // Fat binary + if (type == MACHO_TYPES::FAT_MAGIC or + type == MACHO_TYPES::FAT_CIGAM) { + this->build_fat(); + } else { // fit binary + Binary *binary = BinaryParser(std::move(this->stream_)).get_binary(); + this->binaries_.push_back(binary); + } + } catch (const std::exception& e) { + VLOG(VDEBUG) << e.what(); } } diff --git a/src/MachO/Relocation.cpp b/src/MachO/Relocation.cpp index d86f42d..78e6840 100644 --- a/src/MachO/Relocation.cpp +++ b/src/MachO/Relocation.cpp @@ -45,6 +45,11 @@ Relocation::Relocation(uint64_t address, uint8_t type) : this->type_ = type; } + +//Relocation& Relocation::operator=(const Relocation& other) { +// return *other.clone(); +//} + Relocation::Relocation(const Relocation& other) : LIEF::Relocation{other}, symbol_{nullptr}, diff --git a/src/MachO/RelocationDyld.cpp b/src/MachO/RelocationDyld.cpp index f9fac19..2a5b1c9 100644 --- a/src/MachO/RelocationDyld.cpp +++ b/src/MachO/RelocationDyld.cpp @@ -34,6 +34,11 @@ bool RelocationDyld::is_pc_relative(void) const { } +Relocation* RelocationDyld::clone(void) const { + return new RelocationDyld(*this); +} + + RELOCATION_ORIGINS RelocationDyld::origin(void) const { return RELOCATION_ORIGINS::ORIGIN_DYLDINFO; } diff --git a/src/MachO/RelocationObject.cpp b/src/MachO/RelocationObject.cpp index 3db7571..f03d415 100644 --- a/src/MachO/RelocationObject.cpp +++ b/src/MachO/RelocationObject.cpp @@ -25,8 +25,18 @@ namespace LIEF { namespace MachO { -RelocationObject& RelocationObject::operator=(const RelocationObject&) = default; -RelocationObject::RelocationObject(const RelocationObject&) = default; +RelocationObject& RelocationObject::operator=(RelocationObject other) { + this->swap(other); + return *this; +} + +RelocationObject::RelocationObject(const RelocationObject& other) : + Relocation{other}, + is_pcrel_{other.is_pcrel_}, + is_scattered_{other.is_scattered_}, + value_{other.value_} +{} + RelocationObject::~RelocationObject(void) = default; RelocationObject::RelocationObject(void) : @@ -59,6 +69,10 @@ RelocationObject::RelocationObject(const scattered_relocation_info *scattered_re } +RelocationObject* RelocationObject::clone(void) const { + return new RelocationObject(*this); +} + void RelocationObject::swap(RelocationObject& other) { Relocation::swap(other); diff --git a/src/MachO/SegmentCommand.cpp b/src/MachO/SegmentCommand.cpp index 280218d..8246923 100644 --- a/src/MachO/SegmentCommand.cpp +++ b/src/MachO/SegmentCommand.cpp @@ -29,6 +29,10 @@ SegmentCommand::~SegmentCommand(void) { for (Relocation* reloc : this->relocations_) { delete reloc; } + + for (Section* section : this->sections_) { + delete section; + } } SegmentCommand::SegmentCommand(const segment_command_32 *segmentCmd) : @@ -101,20 +105,12 @@ uint32_t SegmentCommand::flags(void) const { } it_sections SegmentCommand::sections(void) { - sections_t result; - for (Section& s : this->sections_) { - result.push_back(&s); - } - return it_sections{result}; + return this->sections_; } it_const_sections SegmentCommand::sections(void) const { - sections_t result; - for (const Section& s : this->sections_) { - result.push_back(const_cast(&s)); - } - return it_const_sections{result}; + return this->sections_; } diff --git a/src/PE/Parser.cpp b/src/PE/Parser.cpp index 51b1768..9750506 100644 --- a/src/PE/Parser.cpp +++ b/src/PE/Parser.cpp @@ -638,7 +638,7 @@ void Parser::build_exports(void) { uint32_t name_offset = this->binary_->rva_to_offset(name_table[i]); std::string name = ""; try { - name = this->stream_->read_string(name_offset); + name = this->stream_->get_string(name_offset); } catch (const LIEF::read_out_of_bound& e) { LOG(WARNING) << e.what(); }