mirror of
https://github.com/QuasarApp/LIEF.git
synced 2025-04-28 13:24:32 +00:00
Merge pull request #128 from 0xbf00/master
Parse the MachO LC_RPATH command
This commit is contained in:
commit
09f4a4019c
@ -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"
|
||||
)
|
||||
|
61
api/python/MachO/objects/pyRPathCommand.cpp
Normal file
61
api/python/MachO/objects/pyRPathCommand.cpp
Normal file
@ -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 {
|
||||
|
55
include/LIEF/MachO/RPathCommand.hpp
Normal file
55
include/LIEF/MachO/RPathCommand.hpp
Normal file
@ -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"
|
||||
)
|
||||
|
71
src/MachO/RPathCommand.cpp
Normal file
71
src/MachO/RPathCommand.cpp
Normal file
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -62,6 +62,11 @@ class TestMachO(TestCase):
|
||||
self.assertEqual(micromacho.thread_command.count, 16)
|
||||
self.assertEqual(micromacho.entrypoint, 0x68)
|
||||
|
||||
def test_rpath_cmd(self):
|
||||
rpathmacho = lief.parse(get_sample('MachO/MachO64_x86-64_binary_rpathtest.bin'))
|
||||
load_cmds = list(rpathmacho.commands)
|
||||
rpath_cmd = load_cmds[-3]
|
||||
self.assertEqual(rpath_cmd.path, "@executable_path/../lib")
|
||||
|
||||
def test_relocations(self):
|
||||
helloworld = lief.parse(get_sample('MachO/MachO64_x86-64_object_HelloWorld64.o'))
|
||||
|
Loading…
x
Reference in New Issue
Block a user