Skip to content
Permalink
Browse files
Parse the MachO LC_RPATH command
  • Loading branch information
0xbf00 committed Dec 14, 2017
1 parent 23d4e82 commit 196994d
Show file tree
Hide file tree
Showing 13 changed files with 237 additions and 1 deletion.
@@ -22,6 +22,7 @@ set(LIEF_PYTHON_MACHO_SRC
"${CMAKE_CURRENT_LIST_DIR}/objects/pyBindingInfo.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyExportInfo.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyThreadCommand.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyRPathCommand.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyParserConfig.cpp"
"${CMAKE_CURRENT_LIST_DIR}/pyMachOStructures.cpp"
)
@@ -0,0 +1,61 @@
/* Copyright 2017 J.Rieck (based on R. Thomas's work)
* Copyright 2017 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <algorithm>

#include <string>
#include <sstream>

#include "LIEF/visitors/Hash.hpp"
#include "LIEF/MachO/RPathCommand.hpp"

#include "pyMachO.hpp"

template<class T>
using getter_t = T (RPathCommand::*)(void) const;

template<class T>
using setter_t = void (RPathCommand::*)(T);


void init_MachO_RPathCommand_class(py::module& m) {

py::class_<RPathCommand, LoadCommand>(m, "RPathCommand")

.def_property("path",
static_cast<getter_t<const std::string&>>(&RPathCommand::path),
static_cast<setter_t<const std::string&>>(&RPathCommand::path),
"@rpath path",
py::return_value_policy::reference_internal)


.def("__eq__", &RPathCommand::operator==)
.def("__ne__", &RPathCommand::operator!=)
.def("__hash__",
[] (const RPathCommand& rpath_command) {
return LIEF::Hash::hash(rpath_command);
})


.def("__str__",
[] (const RPathCommand& rpath_command)
{
std::ostringstream stream;
stream << rpath_command;
std::string str = stream.str();
return str;
});

}
@@ -47,7 +47,7 @@ void init_MachO_module(py::module& m) {
init_MachO_BindingInfo_class(LIEF_MachO_module);
init_MachO_ExportInfo_class(LIEF_MachO_module);
init_MachO_ThreadCommand_class(LIEF_MachO_module);

init_MachO_RPathCommand_class(LIEF_MachO_module);

// Enums
init_MachO_Structures_enum(LIEF_MachO_module);
@@ -49,6 +49,7 @@ void init_MachO_RelocationDyld_class(py::module&);
void init_MachO_BindingInfo_class(py::module&);
void init_MachO_ExportInfo_class(py::module&);
void init_MachO_ThreadCommand_class(py::module&);
void init_MachO_RPathCommand_class(py::module&);

// Enums
void init_MachO_Structures_enum(py::module&);
@@ -217,6 +217,14 @@ Thread Command

----------

RPath Command
*************

.. doxygenclass:: LIEF::MachO::RPathCommand
:project: lief

----------

Utilities
*********

@@ -251,6 +251,17 @@ Thread Command

----------

RPath Command
*************

.. autoclass:: lief.MachO.RPathCommand
:members:
:inherited-members:
:undoc-members:

----------


Enums
*****

@@ -40,6 +40,7 @@
#include "LIEF/MachO/SourceVersion.hpp"
#include "LIEF/MachO/VersionMin.hpp"
#include "LIEF/MachO/ThreadCommand.hpp"
#include "LIEF/MachO/RPathCommand.hpp"

namespace LIEF {
namespace MachO {
@@ -0,0 +1,55 @@
/* Copyright 2017 J. Rieck (based on R. Thomas's work)
* Copyright 2017 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LIEF_MACHO_RPATH_COMMAND_H_
#define LIEF_MACHO_RPATH_COMMAND_H_
#include <string>
#include <iostream>

#include "LIEF/visibility.h"
#include "LIEF/types.hpp"

#include "LIEF/MachO/LoadCommand.hpp"

namespace LIEF {
namespace MachO {

class DLL_PUBLIC RPathCommand : public LoadCommand {
public:
RPathCommand(void);
RPathCommand(const rpath_command *rpathCmd);

RPathCommand& operator=(const RPathCommand& copy);
RPathCommand(const RPathCommand& copy);

virtual ~RPathCommand(void);

const std::string& path(void) const;
void path(const std::string& path);

bool operator==(const RPathCommand& rhs) const;
bool operator!=(const RPathCommand& rhs) const;

virtual void accept(Visitor& visitor) const override;

virtual std::ostream& print(std::ostream& os) const override;

private:
std::string path_;
};

}
}
#endif
@@ -146,6 +146,7 @@ class DynamicSymbolCommand;
class DylinkerCommand;
class DylibCommand;
class ThreadCommand;
class RPathCommand;

class Symbol;
class Relocation;
@@ -481,6 +482,9 @@ class DLL_PUBLIC Visitor {

//! @brief Method to visit a LIEF::MachO::ThreadCommand
virtual void visit(const MachO::ThreadCommand& thread);

//! @brief Method to visit a LIEF::MachO::RPathCommand
virtual void visit(const MachO::RPathCommand& rpath_command);
#endif

template<class T>
@@ -158,6 +158,23 @@ void BinaryParser::parse_load_commands(void) {
break;
}

// =============
// RPath Command
// =============
case LOAD_COMMAND_TYPES::LC_RPATH:
{
const rpath_command* cmd =
reinterpret_cast<const rpath_command*>(
this->stream_->read(loadcommands_offset, sizeof(rpath_command)));

load_command = std::unique_ptr<RPathCommand>{new RPathCommand{cmd}};
const uint32_t str_path_offset = cmd->path;
std::string path = this->stream_->get_string(loadcommands_offset + str_path_offset);

dynamic_cast<RPathCommand*>(load_command.get())->path(path);
break;
}

// ====
// UUID
// ====
@@ -45,6 +45,7 @@ set(LIEF_MACHO_SRC
"${CMAKE_CURRENT_LIST_DIR}/BindingInfo.cpp"
"${CMAKE_CURRENT_LIST_DIR}/ExportInfo.cpp"
"${CMAKE_CURRENT_LIST_DIR}/ThreadCommand.cpp"
"${CMAKE_CURRENT_LIST_DIR}/RPathCommand.cpp"
"${CMAKE_CURRENT_LIST_DIR}/ParserConfig.cpp"
"${CMAKE_CURRENT_LIST_DIR}/Visitor.cpp"
)
@@ -79,6 +80,7 @@ set(LIEF_MACHO_INCLUDE_FILES
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/MachO/RelocationDyld.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/MachO/BindingInfo.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/MachO/ExportInfo.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/MachO/RPathCommand.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/MachO/ThreadCommand.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/MachO/ParserConfig.hpp"
)
@@ -0,0 +1,71 @@
/* Copyright 2017 J.Rieck (based on R. Thomas's work)
* Copyright 2017 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <numeric>
#include <iomanip>

#include "LIEF/visitors/Hash.hpp"

#include "LIEF/MachO/RPathCommand.hpp"

namespace LIEF {
namespace MachO {

RPathCommand::RPathCommand(void) = default;
RPathCommand& RPathCommand::operator=(const RPathCommand&) = default;
RPathCommand::RPathCommand(const RPathCommand&) = default;
RPathCommand::~RPathCommand(void) = default;

RPathCommand::RPathCommand(const rpath_command *rpathCmd) :
LoadCommand::LoadCommand{static_cast<LOAD_COMMAND_TYPES>(rpathCmd->cmd), rpathCmd->cmdsize}
{
}

const std::string& RPathCommand::path(void) const {
return this->path_;
}

void RPathCommand::path(const std::string& path) {
this->path_ = path;
}


void RPathCommand::accept(Visitor& visitor) const {
LoadCommand::accept(visitor);
visitor.visit(this->path());
}


bool RPathCommand::operator==(const RPathCommand& rhs) const {
size_t hash_lhs = Hash::hash(*this);
size_t hash_rhs = Hash::hash(rhs);
return hash_lhs == hash_rhs;
}

bool RPathCommand::operator!=(const RPathCommand& rhs) const {
return not (*this == rhs);
}


std::ostream& RPathCommand::print(std::ostream& os) const {
LoadCommand::print(os);
os << std::left
<< std::setw(10) << "Path: " << this->path();
return os;
}


}
}
@@ -93,4 +93,8 @@ void Visitor::visit(const MachO::ThreadCommand& thread) {
thread.accept(*this);
}

void Visitor::visit(const MachO::RPathCommand& rpath_command) {
rpath_command.accept(*this);
}

}

0 comments on commit 196994d

Please sign in to comment.