Skip to content

Commit

Permalink
Bug fix in abstract layer for MachO binaries without entrypoint (libr…
Browse files Browse the repository at this point in the history
…ary)

  * MachO API: add ``has_entrypoint``
  • Loading branch information
romainthomas committed May 6, 2017
1 parent de40c06 commit 957501f
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 12 deletions.
9 changes: 4 additions & 5 deletions api/python/MachO/objects/pyBinary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,10 @@ void init_MachO_Binary_class(py::module& m) {
"Return the " RST_CLASS_REF(lief.MachO.SegmentCommand) " which contains the (relative) virtual address",
py::return_value_policy::reference)



.def_property_readonly("entrypoint",
&Binary::entrypoint,
"Return binary's entrypoint",
.def_property_readonly("has_entrypoint",
&Binary::has_entrypoint,
"``True`` if the binary has an entrypoint.\n"
"Basically for libraries it will return ``false``",
py::return_value_policy::reference_internal)

.def("__str__",
Expand Down
5 changes: 5 additions & 0 deletions include/LIEF/MachO/Binary.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,11 @@ class DLL_PUBLIC Binary : public LIEF::Binary {

virtual uint64_t entrypoint(void) const override;

//! @brief ``true`` if the binary has an entrypoint.
//!
//! Basically for libraries it will return ``false``
bool has_entrypoint(void) const;


private:
//! @brief Default constructor
Expand Down
31 changes: 24 additions & 7 deletions src/MachO/Binary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ std::vector<uint8_t> Binary::get_content_from_virtual_address(uint64_t virtual_a


uint64_t Binary::entrypoint(void) const {
if (not this->has_entrypoint()) {
throw not_found("Entrypoint not found");
}

// TODO: LC_THREAD
auto&& it_main_command = std::find_if(
std::begin(this->commands_),
Expand All @@ -103,14 +107,23 @@ uint64_t Binary::entrypoint(void) const {
return command != nullptr and command->command() == LOAD_COMMAND_TYPES::LC_MAIN;
});

if (it_main_command == std::end(this->commands_)) {
throw not_found("Entrypoint not found");
}
const MainCommand* main_command = dynamic_cast<const MainCommand*>(*it_main_command);

const MainCommand* main_command = static_cast<const MainCommand*>(*it_main_command);
return this->imagebase() + main_command->entrypoint();
}


bool Binary::has_entrypoint(void) const {
auto&& it_main_command = std::find_if(
std::begin(this->commands_),
std::end(this->commands_),
[] (const LoadCommand* command) {
return command != nullptr and command->command() == LOAD_COMMAND_TYPES::LC_MAIN;
});

return it_main_command != std::end(this->commands_);
}

LIEF::symbols_t Binary::get_abstract_symbols(void) {
return {std::begin(this->symbols_), std::end(this->symbols_)};
}
Expand Down Expand Up @@ -449,15 +462,15 @@ uint64_t Binary::imagebase(void) const {


const std::string& Binary::get_loader(void) const {
auto itDylinker = std::find_if(
auto&& itDylinker = std::find_if(
std::begin(this->commands_),
std::end(this->commands_),
[] (const LoadCommand* command) {
return command->command() == LOAD_COMMAND_TYPES::LC_LOAD_DYLINKER;
});

if (itDylinker == std::end(this->commands_)) {
throw LIEF::not_found("LC_LOAD_DYLINKER no found");
throw LIEF::not_found(std::string("") + to_string(LOAD_COMMAND_TYPES::LC_LOAD_DYLINKER) + " no found");
}

const DylinkerCommand* dylinkerCommand = dynamic_cast<const DylinkerCommand*>(*itDylinker);
Expand All @@ -471,7 +484,11 @@ LIEF::Header Binary::get_abstract_header(void) const {
const std::pair<ARCHITECTURES, std::set<MODES>>& am = this->header().abstract_architecture();
header.architecture(am.first);
header.modes(am.second);
header.entrypoint(this->entrypoint());
if (this->has_entrypoint()) {
header.entrypoint(this->entrypoint());
} else {
header.entrypoint(0);
}

return header;
}
Expand Down

0 comments on commit 957501f

Please sign in to comment.