Expose DataInCode

This commit is contained in:
Romain Thomas 2018-04-02 08:20:15 +02:00
parent 9cadce30e7
commit a16e1c4d13
24 changed files with 718 additions and 1 deletions

View File

@ -27,6 +27,8 @@ set(LIEF_PYTHON_MACHO_SRC
"${CMAKE_CURRENT_LIST_DIR}/objects/pyParserConfig.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyDynamicSymbolCommand.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyCodeSignature.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyDataInCode.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyDataCodeEntry.cpp"
"${CMAKE_CURRENT_LIST_DIR}/pyMachOStructures.cpp"
)

View File

@ -236,7 +236,7 @@ void init_MachO_Binary_class(py::module& m) {
py::return_value_policy::reference)
.def_property_readonly("has_code_signature",
&Binary::has_dynamic_symbol_command,
&Binary::has_code_signature,
"``True`` if the binary is signed (i.e. has a " RST_CLASS_REF(lief.MachO.CodeSignature) " command)",
py::return_value_policy::reference_internal)
@ -245,6 +245,16 @@ void init_MachO_Binary_class(py::module& m) {
"Return binary's " RST_CLASS_REF(lief.MachO.CodeSignature) " if any.",
py::return_value_policy::reference)
.def_property_readonly("has_data_in_code",
&Binary::has_data_in_code,
"``True`` if the binary has a " RST_CLASS_REF(lief.MachO.DataInCode) " command",
py::return_value_policy::reference_internal)
.def_property_readonly("data_in_code",
static_cast<no_const_getter<DataInCode&>>(&Binary::data_in_code),
"Return binary's " RST_CLASS_REF(lief.MachO.DataInCode) " if any.",
py::return_value_policy::reference)
.def("virtual_address_to_offset",
&Binary::virtual_address_to_offset,

View File

@ -0,0 +1,86 @@
/* Copyright 2017 R. Thomas
* 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/MachO/hash.hpp"
#include "LIEF/MachO/DataCodeEntry.hpp"
#include "LIEF/MachO/EnumToString.hpp"
#include "enums_wrapper.hpp"
#include "pyMachO.hpp"
#define PY_ENUM(x) LIEF::MachO::to_string(x), x
template<class T>
using getter_t = T (DataCodeEntry::*)(void) const;
template<class T>
using setter_t = void (DataCodeEntry::*)(T);
void init_MachO_DataCodeEntry_class(py::module& m) {
py::class_<DataCodeEntry, LIEF::Object> cls(m, "DataCodeEntry");
cls
.def_property("offset",
static_cast<getter_t<uint32_t>>(&DataCodeEntry::offset),
static_cast<setter_t<uint32_t>>(&DataCodeEntry::offset),
"Offset of the data")
.def_property("length",
static_cast<getter_t<uint16_t>>(&DataCodeEntry::length),
static_cast<setter_t<uint16_t>>(&DataCodeEntry::length),
"Length of the data")
.def_property("type",
static_cast<getter_t<DataCodeEntry::TYPES>>(&DataCodeEntry::type),
static_cast<setter_t<DataCodeEntry::TYPES>>(&DataCodeEntry::type),
"Type of the entry (" RST_CLASS_REF(lief.MachO.DataCodeEntry.TYPES) "")
.def("__eq__", &DataCodeEntry::operator==)
.def("__ne__", &DataCodeEntry::operator!=)
.def("__hash__",
[] (const DataCodeEntry& func) {
return Hash::hash(func);
})
.def("__str__",
[] (const DataCodeEntry& func)
{
std::ostringstream stream;
stream << func;
std::string str = stream.str();
return str;
});
LIEF::enum_<DataCodeEntry::TYPES>(cls, "TYPES")
.value(PY_ENUM(DataCodeEntry::TYPES::UNKNOWN))
.value(PY_ENUM(DataCodeEntry::TYPES::DATA))
.value(PY_ENUM(DataCodeEntry::TYPES::JUMP_TABLE_8))
.value(PY_ENUM(DataCodeEntry::TYPES::JUMP_TABLE_16))
.value(PY_ENUM(DataCodeEntry::TYPES::JUMP_TABLE_32))
.value(PY_ENUM(DataCodeEntry::TYPES::ABS_JUMP_TABLE_32));
}

View File

@ -0,0 +1,76 @@
/* Copyright 2017 R. Thomas
* 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/MachO/hash.hpp"
#include "LIEF/MachO/DataInCode.hpp"
#include "pyMachO.hpp"
template<class T>
using getter_t = T (DataInCode::*)(void) const;
template<class T>
using setter_t = void (DataInCode::*)(T);
void init_MachO_DataInCode_class(py::module& m) {
// Init Iterator
init_ref_iterator<DataInCode::it_entries>(m);
py::class_<DataInCode, LoadCommand>(m, "DataInCode")
.def_property("data_offset",
static_cast<getter_t<uint32_t>>(&DataInCode::data_offset),
static_cast<setter_t<uint32_t>>(&DataInCode::data_offset),
"Offset in the binary where signature starts")
.def_property("data_size",
static_cast<getter_t<uint32_t>>(&DataInCode::data_size),
static_cast<setter_t<uint32_t>>(&DataInCode::data_size),
"Size of the raw signature")
.def_property_readonly("entries",
static_cast<DataInCode::it_entries (DataInCode::*)(void)>(&DataInCode::entries),
"Iterator over " RST_CLASS_REF(lief.MachO.DataCodeEntry) "",
py::return_value_policy::reference_internal)
.def("add",
&DataInCode::add,
"Add an new " RST_CLASS_REF(lief.MachO.DataCodeEntry) "",
"entry"_a)
.def("__eq__", &DataInCode::operator==)
.def("__ne__", &DataInCode::operator!=)
.def("__hash__",
[] (const DataInCode& func) {
return Hash::hash(func);
})
.def("__str__",
[] (const DataInCode& func)
{
std::ostringstream stream;
stream << func;
std::string str = stream.str();
return str;
});
}

View File

@ -52,6 +52,9 @@ void init_MachO_module(py::module& m) {
init_MachO_DynamicSymbolCommand_class(LIEF_MachO_module);
init_MachO_CodeSignature_class(LIEF_MachO_module);
init_MachO_DataInCode_class(LIEF_MachO_module);
init_MachO_DataCodeEntry_class(LIEF_MachO_module);
// Enums
init_MachO_Structures_enum(LIEF_MachO_module);
}

View File

@ -53,6 +53,8 @@ void init_MachO_ThreadCommand_class(py::module&);
void init_MachO_RPathCommand_class(py::module&);
void init_MachO_DynamicSymbolCommand_class(py::module&);
void init_MachO_CodeSignature_class(py::module&);
void init_MachO_DataInCode_class(py::module&);
void init_MachO_DataCodeEntry_class(py::module&);
// Enums
void init_MachO_Structures_enum(py::module&);

View File

@ -20,6 +20,8 @@
#include "LIEF/visibility.h"
namespace py = pybind11;
namespace LIEF {
template <class Type>

View File

@ -234,6 +234,25 @@ Code Signature
----------
Data In Code
************
.. doxygenclass:: LIEF::MachO::DataInCode
:project: lief
----------
Data Code Entry
****************
.. doxygenclass:: LIEF::MachO::DataCodeEntry
:project: lief
.. doxygenenum:: LIEF::MachO::DataCodeEntry::TYPES
:project: lief
----------
Utilities
*********

View File

@ -293,6 +293,35 @@ Code Signature
----------
Data In Code
************
.. autoclass:: lief.MachO.DataInCode
:members:
:inherited-members:
:undoc-members:
----------
Data Code Entry
***************
.. autoclass:: lief.MachO.DataCodeEntry
:members:
:inherited-members:
:undoc-members:
TYPES
~~~~~
.. autoclass:: lief.MachO.DataCodeEntry.TYPES
:members:
:inherited-members:
:undoc-members:
----------
Enums
*****

View File

@ -370,6 +370,25 @@ def print_function_starts(binary):
print("")
@exceptions_handler(Exception)
def print_data_in_code(binary):
format_str = "{:<13} {:<30}"
format_hex = "{:<13} 0x{:<28x}"
format_dec = "{:<13} {:<30d}"
print("== Data In Code ==")
datacode = binary.data_in_code
print(format_hex.format("Offset:", datacode.data_offset))
print(format_hex.format("Size:", datacode.data_size))
print("")
for entry in datacode.entries:
type_str = str(entry.type).split(".")[-1]
print("- {:<14}: 0x{:x} ({:d} bytes)".format(type_str, entry.offset, entry.length))
print("")
@exceptions_handler(Exception)
@ -636,6 +655,10 @@ def main():
action='store_true', dest='show_dynamic_symbol_command',
help="Display the 'Symbol Command' command")
parser.add_argument('--data-in-code',
action='store_true', dest='show_data_in_code',
help="Display the 'Data In Code' command")
parser.add_argument('--bind-opcodes',
action='store_true', dest='show_bind_opcodes',
help='Display the "Bind" opcodes')
@ -727,6 +750,9 @@ def main():
if (args.show_dynamic_symbol_command or args.show_all) and binary.has_dynamic_symbol_command:
print_dynamic_symbol_command(binary)
if (args.show_data_in_code or args.show_all) and binary.has_data_in_code:
print_data_in_code(binary)
if (args.show_rpath_command or args.show_all) and binary.has_rpath:
print_rpath_command(binary)

View File

@ -42,6 +42,7 @@
#include "LIEF/MachO/ThreadCommand.hpp"
#include "LIEF/MachO/RPathCommand.hpp"
#include "LIEF/MachO/CodeSignature.hpp"
#include "LIEF/MachO/DataInCode.hpp"
namespace LIEF {
namespace MachO {
@ -298,6 +299,13 @@ class LIEF_API Binary : public LIEF::Binary {
CodeSignature& code_signature(void);
const CodeSignature& code_signature(void) const;
//! @brief ``true`` if the binaryhas a MachO::DataInCode command.
bool has_data_in_code(void) const;
//! @brief Return the MachO::Signature
DataInCode& data_in_code(void);
const DataInCode& data_in_code(void) const;
template<class T>
LIEF_LOCAL bool has_command(void) const;

View File

@ -0,0 +1,82 @@
/* Copyright 2017 R. Thomas
* 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_DATA_CODE_ENTRY_H_
#define LIEF_MACHO_DATA_CODE_ENTRY_H_
#include <string>
#include <vector>
#include <iostream>
#include "LIEF/visibility.h"
#include "LIEF/types.hpp"
#include "LIEF/Object.hpp"
namespace LIEF {
namespace MachO {
//! Interface of an entry in DataInCode
class DataCodeEntry : public LIEF::Object {
public:
enum class TYPES {
UNKNOWN = 0,
DATA = 1,
JUMP_TABLE_8 = 2,
JUMP_TABLE_16 = 3,
JUMP_TABLE_32 = 4,
ABS_JUMP_TABLE_32 = 5,
};
public:
DataCodeEntry(void);
DataCodeEntry(uint32_t off, uint16_t length, TYPES type);
DataCodeEntry(const data_in_code_entry* entry);
DataCodeEntry& operator=(const DataCodeEntry&);
DataCodeEntry(const DataCodeEntry&);
//! Offset of the data
uint32_t offset(void) const;
//! Length of the data
uint16_t length(void) const;
// Type of the data
TYPES type(void) const;
void offset(uint32_t off);
void length(uint16_t length);
void type(TYPES type);
virtual ~DataCodeEntry(void);
bool operator==(const DataCodeEntry& rhs) const;
bool operator!=(const DataCodeEntry& rhs) const;
virtual void accept(Visitor& visitor) const override;
LIEF_API friend std::ostream& operator<<(std::ostream& os, const DataCodeEntry& entry);
private:
uint32_t offset_;
uint16_t length_;
TYPES type_;
};
}
}
#endif

View File

@ -0,0 +1,77 @@
/* Copyright 2017 R. Thomas
* 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_DATA_IN_CODE_COMMAND_H_
#define LIEF_MACHO_DATA_IN_CODE_COMMAND_H_
#include <string>
#include <vector>
#include <iostream>
#include "LIEF/visibility.h"
#include "LIEF/types.hpp"
#include "LIEF/MachO/LoadCommand.hpp"
#include "LIEF/MachO/DataCodeEntry.hpp"
namespace LIEF {
namespace MachO {
class BinaryParser;
//! Interface of the LC_DATA_IN_CODE command
class LIEF_API DataInCode : public LoadCommand {
friend class BinaryParser;
public:
using entries_t = std::vector<DataCodeEntry>;
using it_const_entries = const_ref_iterator<const entries_t&>;
using it_entries = ref_iterator<entries_t&>;
public:
DataInCode(void);
DataInCode(const linkedit_data_command *cmd);
DataInCode& operator=(const DataInCode&);
DataInCode(const DataInCode&);
uint32_t data_offset(void) const;
uint32_t data_size(void) const;
void data_offset(uint32_t offset);
void data_size(uint32_t size);
DataInCode& add(const DataCodeEntry& entry);
it_const_entries entries(void) const;
it_entries entries(void);
virtual ~DataInCode(void);
bool operator==(const DataInCode& rhs) const;
bool operator!=(const DataInCode& rhs) const;
virtual void accept(Visitor& visitor) const override;
virtual std::ostream& print(std::ostream& os) const override;
private:
uint32_t data_offset_;
uint32_t data_size_;
entries_t entries_;
};
}
}
#endif

View File

@ -18,6 +18,7 @@
#include "LIEF/visibility.h"
#include "LIEF/MachO/Structures.hpp"
#include "LIEF/MachO/DataCodeEntry.hpp"
namespace LIEF {
namespace MachO {
@ -48,6 +49,7 @@ LIEF_API const char* to_string(BIND_OPCODES e);
LIEF_API const char* to_string(EXPORT_SYMBOL_KINDS e);
LIEF_API const char* to_string(VM_PROTECTIONS e);
LIEF_API const char* to_string(SYMBOL_ORIGINS e);
LIEF_API const char* to_string(DataCodeEntry::TYPES e);
} // namespace MachO
} // namespace LIEF

View File

@ -53,6 +53,8 @@ class LIEF_API Hash : public LIEF::Hash {
virtual void visit(const ExportInfo& einfo) override;
virtual void visit(const FunctionStarts& fs) override;
virtual void visit(const CodeSignature& cs) override;
virtual void visit(const DataInCode& dic) override;
virtual void visit(const DataCodeEntry& dce) override;
virtual ~Hash(void);
};

View File

@ -140,6 +140,8 @@ LIEF_MACHO_FORWARD(BindingInfo)
LIEF_MACHO_FORWARD(ExportInfo)
LIEF_MACHO_FORWARD(FunctionStarts)
LIEF_MACHO_FORWARD(CodeSignature)
LIEF_MACHO_FORWARD(DataInCode)
LIEF_MACHO_FORWARD(DataCodeEntry)
class LIEF_API Visitor {
@ -403,6 +405,12 @@ class LIEF_API Visitor {
//! @brief Method to visit a LIEF::MachO::CodeSignature
LIEF_MACHO_VISITABLE(CodeSignature)
//! @brief Method to visit a LIEF::MachO::DataInCode
LIEF_MACHO_VISITABLE(DataInCode)
//! @brief Method to visit a LIEF::MachO::DataCodeEntry
LIEF_MACHO_VISITABLE(DataCodeEntry)
template<class T>
void dispatch(const T& obj);

View File

@ -814,6 +814,21 @@ const CodeSignature& Binary::code_signature(void) const {
}
// DataInCode command
// +++++++++++++++++++++
bool Binary::has_data_in_code(void) const {
return this->has_command<DataInCode>();
}
DataInCode& Binary::data_in_code(void) {
return this->command<DataInCode>();
}
const DataInCode& Binary::data_in_code(void) const {
return this->command<DataInCode>();
}
void Binary::accept(LIEF::Visitor& visitor) const {

View File

@ -411,6 +411,23 @@ void BinaryParser::parse_load_commands(void) {
break;
}
case LOAD_COMMAND_TYPES::LC_DATA_IN_CODE:
{
const linkedit_data_command* cmd =
reinterpret_cast<const linkedit_data_command*>(
this->stream_->read(loadcommands_offset, sizeof(linkedit_data_command)));
load_command = std::unique_ptr<DataInCode>{new DataInCode{cmd}};
DataInCode* datacode = load_command.get()->as<DataInCode>();
const data_in_code_entry* entries = reinterpret_cast<const data_in_code_entry*>(this->stream_->read(datacode->data_offset(), datacode->data_size()));
const size_t nb_entries = datacode->data_size() / sizeof(data_in_code_entry);
for (size_t i = 0; i < nb_entries; ++i) {
datacode->add(&entries[i]);
}
break;
}

View File

@ -49,6 +49,8 @@ set(LIEF_MACHO_SRC
"${CMAKE_CURRENT_LIST_DIR}/ParserConfig.cpp"
"${CMAKE_CURRENT_LIST_DIR}/hash.cpp"
"${CMAKE_CURRENT_LIST_DIR}/CodeSignature.cpp"
"${CMAKE_CURRENT_LIST_DIR}/DataInCode.cpp"
"${CMAKE_CURRENT_LIST_DIR}/DataCodeEntry.cpp"
)
set(LIEF_MACHO_INCLUDE_FILES
@ -86,6 +88,8 @@ set(LIEF_MACHO_INCLUDE_FILES
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/MachO/ParserConfig.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/MachO/hash.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/MachO/CodeSignature.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/MachO/DataInCode.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/MachO/DataCodeEntry.hpp"
)
source_group("Header Files\\MachO" FILES ${LIEF_MACHO_INCLUDE_FILES})

View File

@ -0,0 +1,96 @@
/* Copyright 2017 R. Thomas
* 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/MachO/hash.hpp"
#include "LIEF/MachO/DataCodeEntry.hpp"
namespace LIEF {
namespace MachO {
DataCodeEntry& DataCodeEntry::operator=(const DataCodeEntry&) = default;
DataCodeEntry::DataCodeEntry(const DataCodeEntry&) = default;
DataCodeEntry::~DataCodeEntry(void) = default;
DataCodeEntry::DataCodeEntry(void) :
offset_{0},
length_{0},
type_{TYPES::UNKNOWN}
{}
DataCodeEntry::DataCodeEntry(uint32_t off, uint16_t length, TYPES type) :
offset_{off},
length_{length},
type_{type}
{}
DataCodeEntry::DataCodeEntry(const data_in_code_entry* entry) :
offset_{entry->offset},
length_{entry->length},
type_{static_cast<TYPES>(entry->kind)}
{}
uint32_t DataCodeEntry::offset(void) const {
return this->offset_;
}
uint16_t DataCodeEntry::length(void) const {
return this->length_;
}
DataCodeEntry::TYPES DataCodeEntry::type(void) const {
return this->type_;
}
void DataCodeEntry::offset(uint32_t off) {
this->offset_ = off;
}
void DataCodeEntry::length(uint16_t length) {
this->length_ = length;
}
void DataCodeEntry::type(TYPES type) {
this->type_ = type;
}
void DataCodeEntry::accept(Visitor& visitor) const {
visitor.visit(*this);
}
bool DataCodeEntry::operator==(const DataCodeEntry& rhs) const {
size_t hash_lhs = Hash::hash(*this);
size_t hash_rhs = Hash::hash(rhs);
return hash_lhs == hash_rhs;
}
bool DataCodeEntry::operator!=(const DataCodeEntry& rhs) const {
return not (*this == rhs);
}
std::ostream& operator<<(std::ostream& os, const DataCodeEntry& entry) {
return os;
}
}
}

97
src/MachO/DataInCode.cpp Normal file
View File

@ -0,0 +1,97 @@
/* Copyright 2017 R. Thomas
* 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/MachO/hash.hpp"
#include "LIEF/MachO/DataInCode.hpp"
namespace LIEF {
namespace MachO {
DataInCode::DataInCode(void) = default;
DataInCode& DataInCode::operator=(const DataInCode&) = default;
DataInCode::DataInCode(const DataInCode&) = default;
DataInCode::~DataInCode(void) = default;
DataInCode::DataInCode(const linkedit_data_command *cmd) :
LoadCommand::LoadCommand{static_cast<LOAD_COMMAND_TYPES>(cmd->cmd), cmd->cmdsize},
data_offset_{cmd->dataoff},
data_size_{cmd->datasize}
{}
uint32_t DataInCode::data_offset(void) const {
return this->data_offset_;
}
uint32_t DataInCode::data_size(void) const {
return this->data_size_;
}
void DataInCode::data_offset(uint32_t offset) {
this->data_offset_ = offset;
}
void DataInCode::data_size(uint32_t size) {
this->data_size_ = size;
}
DataInCode& DataInCode::add(const DataCodeEntry& entry) {
this->entries_.push_back(entry);
return *this;
}
DataInCode::it_const_entries DataInCode::entries(void) const {
return this->entries_;
}
DataInCode::it_entries DataInCode::entries(void) {
return this->entries_;
}
void DataInCode::accept(Visitor& visitor) const {
visitor.visit(*this);
}
bool DataInCode::operator==(const DataInCode& rhs) const {
size_t hash_lhs = Hash::hash(*this);
size_t hash_rhs = Hash::hash(rhs);
return hash_lhs == hash_rhs;
}
bool DataInCode::operator!=(const DataInCode& rhs) const {
return not (*this == rhs);
}
std::ostream& DataInCode::print(std::ostream& os) const {
LoadCommand::print(os);
os << std::left;
os << std::endl;
os << "Data location:" << std::endl;
os << std::setw(8) << "Offset" << ": 0x" << this->data_offset() << std::endl;
os << std::setw(8) << "Size" << ": 0x" << this->data_size() << std::endl;
return os;
}
}
}

View File

@ -470,5 +470,19 @@ const char* to_string(SYMBOL_ORIGINS e) {
return it == enumStrings.end() ? "Out of range" : it->second;
}
const char* to_string(DataCodeEntry::TYPES e) {
CONST_MAP(DataCodeEntry::TYPES, const char*, 6) enumStrings {
{ DataCodeEntry::TYPES::UNKNOWN, "UNKNOWN" },
{ DataCodeEntry::TYPES::DATA, "DATA" },
{ DataCodeEntry::TYPES::JUMP_TABLE_8, "JUMP_TABLE_8" },
{ DataCodeEntry::TYPES::JUMP_TABLE_16, "JUMP_TABLE_16" },
{ DataCodeEntry::TYPES::JUMP_TABLE_32, "JUMP_TABLE_32" },
{ DataCodeEntry::TYPES::ABS_JUMP_TABLE_32, "ABS_JUMP_TABLE_32" },
};
auto it = enumStrings.find(e);
return it == enumStrings.end() ? "UNKNOWN" : it->second;
}
}
}

View File

@ -245,6 +245,19 @@ void Hash::visit(const CodeSignature& cs) {
this->process(cs.data_size());
}
void Hash::visit(const DataInCode& dic) {
this->process(dic.data_offset());
this->process(dic.data_size());
this->process(std::begin(dic.entries()), std::end(dic.entries()));
}
void Hash::visit(const DataCodeEntry& dce) {
this->process(dce.offset());
this->process(dce.length());
this->process(dce.type());
}

View File

@ -117,6 +117,33 @@ class TestMachO(TestCase):
self.assertEqual(relocations[0].has_section, True)
self.assertEqual(relocations[0].section.name, "__cstring")
def test_data_in_code(self):
binary = lief.parse(get_sample('MachO/MachO32_ARM_binary_data-in-code-LLVM.bin'))
self.assertTrue(binary.has_data_in_code)
dcode = binary.data_in_code
self.assertEqual(dcode.data_offset, 0x11c)
self.assertEqual(dcode.data_size, 0x20)
self.assertEqual(len(dcode.entries), 4)
self.assertEqual(dcode.entries[0].type, lief.MachO.DataCodeEntry.TYPES.DATA)
self.assertEqual(dcode.entries[0].offset, 0)
self.assertEqual(dcode.entries[0].length, 4)
self.assertEqual(dcode.entries[1].type, lief.MachO.DataCodeEntry.TYPES.JUMP_TABLE_32)
self.assertEqual(dcode.entries[1].offset, 4)
self.assertEqual(dcode.entries[1].length, 4)
self.assertEqual(dcode.entries[2].type, lief.MachO.DataCodeEntry.TYPES.JUMP_TABLE_16)
self.assertEqual(dcode.entries[2].offset, 8)
self.assertEqual(dcode.entries[2].length, 2)
self.assertEqual(dcode.entries[3].type, lief.MachO.DataCodeEntry.TYPES.JUMP_TABLE_8)
self.assertEqual(dcode.entries[3].offset, 10)
self.assertEqual(dcode.entries[3].length, 1)
if __name__ == '__main__':