mirror of
https://github.com/QuasarApp/LIEF.git
synced 2025-04-27 21:04:32 +00:00
Expose DataInCode
This commit is contained in:
parent
9cadce30e7
commit
a16e1c4d13
@ -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"
|
||||
)
|
||||
|
||||
|
@ -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,
|
||||
|
86
api/python/MachO/objects/pyDataCodeEntry.cpp
Normal file
86
api/python/MachO/objects/pyDataCodeEntry.cpp
Normal 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));
|
||||
|
||||
}
|
76
api/python/MachO/objects/pyDataInCode.cpp
Normal file
76
api/python/MachO/objects/pyDataInCode.cpp
Normal 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;
|
||||
});
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
@ -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&);
|
||||
|
@ -20,6 +20,8 @@
|
||||
|
||||
#include "LIEF/visibility.h"
|
||||
|
||||
namespace py = pybind11;
|
||||
|
||||
namespace LIEF {
|
||||
|
||||
template <class Type>
|
||||
|
@ -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
|
||||
*********
|
||||
|
||||
|
@ -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
|
||||
*****
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
82
include/LIEF/MachO/DataCodeEntry.hpp
Normal file
82
include/LIEF/MachO/DataCodeEntry.hpp
Normal 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
|
77
include/LIEF/MachO/DataInCode.hpp
Normal file
77
include/LIEF/MachO/DataInCode.hpp
Normal 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
|
@ -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
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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})
|
||||
|
96
src/MachO/DataCodeEntry.cpp
Normal file
96
src/MachO/DataCodeEntry.cpp
Normal 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
97
src/MachO/DataInCode.cpp
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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__':
|
||||
|
Loading…
x
Reference in New Issue
Block a user