From 8f46263c17671022beb5be448f5aebd130ccb86e Mon Sep 17 00:00:00 2001 From: Andrew Chow Date: Tue, 5 Jan 2021 23:05:42 -0500 Subject: [PATCH] Calculate MachO binary available_command_space_ This value was always set to 0, so space would always be allocated in the binary for more commands. However it is not necessary to do this as there will often be space available. This commit adds a simple way to calculate that during parsing. This method is taken from Apple's cctools package, specifically the codesign_allocate tool. See https://github.com/tpoechtrager/cctools-port/blob/466063c7f7486762a5a8f0d98c48dc5ffbe42f74/cctools/misc/codesign_allocate.c#L861 --- src/MachO/BinaryParser.tcc | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/MachO/BinaryParser.tcc b/src/MachO/BinaryParser.tcc index e64ebea..5f782d5 100644 --- a/src/MachO/BinaryParser.tcc +++ b/src/MachO/BinaryParser.tcc @@ -120,6 +120,7 @@ void BinaryParser::parse_load_commands(void) { LIEF_WARN("Only the first #{:d} will be parsed", nbcmds); } + uint32_t low_fileoff = -1U; for (size_t i = 0; i < nbcmds; ++i) { if (not this->stream_->can_read(loadcommands_offset)) { break; @@ -158,10 +159,22 @@ void BinaryParser::parse_load_commands(void) { for (size_t j = 0; j < segment->numberof_sections(); ++j) { const section_t* section_header = &this->stream_->peek(local_offset); std::unique_ptr
section{new Section{section_header}}; + if (section->size_ > 0 and + section->type() != MACHO_SECTION_TYPES::S_ZEROFILL and + section->type() != MACHO_SECTION_TYPES::S_THREAD_LOCAL_ZEROFILL and + section->offset_ < low_fileoff) { + low_fileoff = section->offset_; + } section->segment_ = segment; segment->sections_.push_back(section.release()); local_offset += sizeof(section_t); } + if (segment->numberof_sections() == 0 and + segment->file_offset() != 0 and + segment->file_size() != 0 and + segment->file_offset() < low_fileoff) { + low_fileoff = segment->file_offset(); + } break; } @@ -599,6 +612,7 @@ void BinaryParser::parse_load_commands(void) { } loadcommands_offset += command.cmdsize; } + this->binary_->available_command_space_ = low_fileoff - loadcommands_offset; }