Fix MachO meme leaks (related #99)

This commit is contained in:
Romain Thomas 2017-09-28 20:50:38 +02:00
parent d9b1436730
commit 554fa153af
17 changed files with 169 additions and 97 deletions

View File

@ -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()

View File

@ -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<typename T>
T read_integer(uint64_t offset, bool swap = false) const;

View File

@ -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<uint8_t>& content(void) const;

View File

@ -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<uint8_t>& content);
Handler(std::vector<uint8_t>&& content);
~Handler(void);

View File

@ -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.

View File

@ -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.
//!

View File

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

View File

@ -113,7 +113,7 @@ class DLL_PUBLIC SegmentCommand : public LoadCommand {
std::vector<uint8_t> data_;
std::vector<Section> sections_;
sections_t sections_;
relocations_t relocations_;

View File

@ -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<const char*>(this->read(offset, size));
max_size = std::min<uint64_t>(max_size, size);
}
return reinterpret_cast<const char*>(this->binary_.data() + offset);
return reinterpret_cast<const char*>(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<uint64_t>(max_size, size);
}
std::string tmp{this->read_string(offset, max_size), max_size};
return tmp.c_str();
}

View File

@ -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<MACHO_TYPES>(
*reinterpret_cast<const uint32_t*>(this->stream_->read(0, sizeof(uint32_t))));
try {
MACHO_TYPES type = static_cast<MACHO_TYPES>(
*reinterpret_cast<const uint32_t*>(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<MachO64>();
} else {
this->parse<MachO32>();
if (this->is64_) {
this->parse<MachO64>();
} else {
this->parse<MachO32>();
}
} 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<uint8_t>(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<ExportInfo> 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<uint32_t>(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);
}

View File

@ -99,7 +99,7 @@ void BinaryParser::parse_load_commands(void) {
const load_command* command = reinterpret_cast<const load_command*>(
this->stream_->read(loadcommands_offset, sizeof(load_command)));
LoadCommand* load_command = nullptr;
std::unique_ptr<LoadCommand> 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<SegmentCommand>{new SegmentCommand{
reinterpret_cast<const segment_command_t*>(
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<SegmentCommand*>(load_command);
SegmentCommand* segment = dynamic_cast<SegmentCommand*>(load_command.get());
const uint8_t* content = static_cast<const uint8_t*>(
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<const section_t*>(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<const section_t*>(this->stream_->read(local_offset, sizeof(section_t)));
std::unique_ptr<Section> 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<const dylib_command*>(
this->stream_->read(loadcommands_offset, sizeof(dylib_command)));
load_command = new DylibCommand{cmd};
load_command = std::unique_ptr<DylibCommand>{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<DylibCommand*>(load_command)->name(name);
dynamic_cast<DylibCommand*>(load_command.get())->name(name);
break;
}
@ -166,7 +167,7 @@ void BinaryParser::parse_load_commands(void) {
const uuid_command* cmd =
reinterpret_cast<const uuid_command*>(
this->stream_->read(loadcommands_offset, sizeof(uuid_command)));
load_command = new UUIDCommand{cmd};
load_command = std::unique_ptr<UUIDCommand>{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<DylinkerCommand*>(load_command)->name(name);
load_command = std::unique_ptr<DylinkerCommand>{new DylinkerCommand{cmd}};
dynamic_cast<DylinkerCommand*>(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<LoadCommand>{new LoadCommand{command}};
const prebound_dylib_command* cmd =
reinterpret_cast<const prebound_dylib_command*>(
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<const thread_command*>(
this->stream_->read(loadcommands_offset, sizeof(thread_command)));
load_command = new ThreadCommand{cmd};
dynamic_cast<ThreadCommand*>(load_command)->architecture_ = this->binary_->header().cpu_type();
load_command = std::unique_ptr<ThreadCommand>{new ThreadCommand{cmd}};
ThreadCommand* thread = dynamic_cast<ThreadCommand*>(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<const uint8_t*>(
this->stream_->read(loadcommands_offset + sizeof(thread_command), sizeof(x86_thread_state_t)));
dynamic_cast<ThreadCommand*>(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<const uint8_t*>(
this->stream_->read(loadcommands_offset + sizeof(thread_command), sizeof(x86_thread_state64_t)));
dynamic_cast<ThreadCommand*>(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<const uint8_t*>(
this->stream_->read(loadcommands_offset + sizeof(thread_command), sizeof(arm_thread_state_t)));
dynamic_cast<ThreadCommand*>(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<const uint8_t*>(
this->stream_->read(loadcommands_offset + sizeof(thread_command), sizeof(arm_thread_state64_t)));
dynamic_cast<ThreadCommand*>(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<LoadCommand>{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<SymbolCommand>{new SymbolCommand{cmd}};
const nlist_t* nlist = reinterpret_cast<const nlist_t*>(
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> 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<const dysymtab_command*>(
this->stream_->read(loadcommands_offset, sizeof(dysymtab_command)));
load_command = new DynamicSymbolCommand{cmd};
load_command = std::unique_ptr<DynamicSymbolCommand>{new DynamicSymbolCommand{cmd}};
break;
}
@ -338,7 +341,7 @@ void BinaryParser::parse_load_commands(void) {
reinterpret_cast<const dyld_info_command*>(
this->stream_->read(loadcommands_offset, sizeof(dyld_info_command)));
load_command = new DyldInfo{cmd};
load_command = std::unique_ptr<DyldInfo>{new DyldInfo{cmd}};
break;
}
@ -353,7 +356,7 @@ void BinaryParser::parse_load_commands(void) {
reinterpret_cast<const source_version_command*>(
this->stream_->read(loadcommands_offset, sizeof(version_min_command)));
load_command = new SourceVersion{cmd};
load_command = std::unique_ptr<SourceVersion>{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<VersionMin>{new VersionMin{cmd}};
break;
}
@ -427,7 +430,7 @@ void BinaryParser::parse_load_commands(void) {
reinterpret_cast<const entry_point_command*>(
this->stream_->read(loadcommands_offset, sizeof(entry_point_command)));
load_command = new MainCommand{cmd};
load_command = std::unique_ptr<MainCommand>{new MainCommand{cmd}};
break;
}
@ -440,12 +443,12 @@ void BinaryParser::parse_load_commands(void) {
const linkedit_data_command* cmd =
reinterpret_cast<const linkedit_data_command*>(
this->stream_->read(loadcommands_offset, sizeof(linkedit_data_command)));
load_command = new FunctionStarts{cmd};
load_command = std::unique_ptr<FunctionStarts>{new FunctionStarts{cmd}};
uint64_t offset = cmd->dataoff;
std::pair<uint64_t, uint64_t> value_delta;
uint64_t value = 0;
FunctionStarts* fstart = dynamic_cast<FunctionStarts*>(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<FunctionStarts*>(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<LOAD_COMMAND_TYPES>(command->cmd))
<< "' not parsed";
load_command = new LoadCommand{command};
load_command = std::unique_ptr<LoadCommand>{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<RelocationObject> reloc{nullptr};
for (size_t i = 0; i < numberof_relocations; ++i) {
int32_t address = this->stream_->read_integer<int32_t>(current_reloc_offset);
bool is_scattered = static_cast<bool>(address & R_SCATTERED);
RelocationObject* reloc = nullptr;
if (is_scattered) {
const scattered_relocation_info* reloc_info = reinterpret_cast<const scattered_relocation_info*>(
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<RelocationObject>{new RelocationObject{reloc_info}};
reloc->section_ = &section;
} else {
const relocation_info* reloc_info = reinterpret_cast<const relocation_info*>(
this->stream_->read(current_reloc_offset, sizeof(relocation_info)));
reloc = new RelocationObject{reloc_info};
reloc = std::unique_ptr<RelocationObject>{new RelocationObject{reloc_info}};
reloc->section_ = &section;
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_ = &section;
if (reloc) {
if (not reloc->has_section()) {
reloc->section_ = &section;
}
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<Relocation> 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<Relocation>{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<BIND_TYPES>(type), address, addend, ord, is_weak};
std::unique_ptr<BindingInfo> binding_info{new BindingInfo{cls, static_cast<BIND_TYPES>(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;
}

View File

@ -118,16 +118,20 @@ void Parser::build_fat(void) {
}
void Parser::build(void) {
MACHO_TYPES type = static_cast<MACHO_TYPES>(
*reinterpret_cast<const uint32_t*>(this->stream_->read(0, sizeof(uint32_t))));
try {
MACHO_TYPES type = static_cast<MACHO_TYPES>(
*reinterpret_cast<const uint32_t*>(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();
}
}

View File

@ -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},

View File

@ -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;
}

View File

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

View File

@ -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<Section*>(&s));
}
return it_const_sections{result};
return this->sections_;
}

View File

@ -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();
}