Skip to content
Permalink
Browse files
Parse the MachO LC_THREAD/LC_UNIXTHREAD command
New object: MachO::ThreadCommand

Resolve: #89
  • Loading branch information
romainthomas committed Sep 13, 2017
1 parent 81440ce commit 2325783
Show file tree
Hide file tree
Showing 19 changed files with 486 additions and 551 deletions.
@@ -20,6 +20,7 @@ set(LIEF_PYTHON_MACHO_SRC
"${CMAKE_CURRENT_LIST_DIR}/objects/pyRelocationDyld.cpp"
"${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}/pyMachOStructures.cpp"
)

@@ -188,6 +188,16 @@ void init_MachO_Binary_class(py::module& m) {
"Return binary's " RST_CLASS_REF(lief.MachO.VersionMin) " if any.",
py::return_value_policy::reference)

.def_property_readonly("has_thread_command",
&Binary::has_thread_command,
"``True`` if the binary has a " RST_CLASS_REF(lief.MachO.ThreadCommand) " command.",
py::return_value_policy::reference_internal)

.def_property_readonly("thread_command",
static_cast<no_const_getter<ThreadCommand&>>(&Binary::thread_command),
"Return binary's " RST_CLASS_REF(lief.MachO.ThreadCommand) " if any.",
py::return_value_policy::reference)

.def("virtual_address_to_offset",
&Binary::virtual_address_to_offset,
"Convert the virtual address to an offset in the binary",
@@ -0,0 +1,78 @@
/* 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/visitors/Hash.hpp"
#include "LIEF/MachO/ThreadCommand.hpp"

#include "pyMachO.hpp"

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

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


void init_MachO_ThreadCommand_class(py::module& m) {

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

.def_property("flavor",
static_cast<getter_t<uint32_t>>(&ThreadCommand::flavor),
static_cast<setter_t<uint32_t>>(&ThreadCommand::flavor),
"",
py::return_value_policy::reference_internal)


.def_property("state",
static_cast<getter_t<const std::vector<uint8_t>&>>(&ThreadCommand::state),
static_cast<setter_t<const std::vector<uint8_t>&>>(&ThreadCommand::state),
"",
py::return_value_policy::reference_internal)


.def_property("count",
static_cast<getter_t<uint32_t>>(&ThreadCommand::count),
static_cast<setter_t<uint32_t>>(&ThreadCommand::count),
"",
py::return_value_policy::reference_internal)

.def_property_readonly("pc",
static_cast<getter_t<uint64_t>>(&ThreadCommand::pc),
py::return_value_policy::reference_internal)

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


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

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


// Enums
@@ -46,6 +46,7 @@ void init_MachO_RelocationObject_class(py::module&);
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&);

// Enums
void init_MachO_Structures_enum(py::module&);
@@ -196,6 +196,15 @@ Export Info

----------


Thread Command
**************

.. doxygenclass:: LIEF::MachO::ThreadCommand
:project: lief

----------

Utilities
*********

@@ -218,6 +218,17 @@ Export Info
----------


Thread Command
**************

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

----------


Enums
*****

@@ -13,7 +13,7 @@
from lief import MachO

from lief import Logger
Logger.set_level(lief.LOGGING_LEVEL.GLOBAL)
Logger.set_level(lief.LOGGING_LEVEL.INFO)

terminal_rows, terminal_columns = 100, 100
try:
@@ -252,6 +252,23 @@ def print_main_command(binary):
print("")


@exceptions_handler(Exception)
def print_thread_command(binary):

format_str = "{:<13} {:<30}"
format_hex = "{:<13} 0x{:<28x}"
format_dec = "{:<13} {:<30d}"

print("== Thread Command ==")
cmd = binary.thread_command

print(format_hex.format("Flavor:", cmd.flavor))
print(format_hex.format("Count:", cmd.count))
print(format_hex.format("PC:", cmd.pc))

print("")


@exceptions_handler(Exception)
def print_dylinker(binary):
print("== Dylinker ==")
@@ -483,6 +500,10 @@ def main():
action='store_true', dest='show_version_min',
help="Display the 'Version Min' command")

parser.add_argument('--thread-command',
action='store_true', dest='show_thread_command',
help="Display the 'Thread Command' command")

parser.add_argument("binary",
metavar="<macho-file>",
help='Target Mach-O File')
@@ -542,6 +563,9 @@ def main():
if (args.show_relocs or args.show_all) and len(binary.relocations) > 0:
print_relocations(binary)

if (args.show_thread_command or args.show_all) and binary.has_thread_command:
print_thread_command(binary)


if __name__ == "__main__":
main()
@@ -39,6 +39,7 @@
#include "LIEF/MachO/FunctionStarts.hpp"
#include "LIEF/MachO/SourceVersion.hpp"
#include "LIEF/MachO/VersionMin.hpp"
#include "LIEF/MachO/ThreadCommand.hpp"

namespace LIEF {
namespace MachO {
@@ -247,6 +248,14 @@ class DLL_PUBLIC Binary : public LIEF::Binary {
VersionMin& version_min(void);
const VersionMin& version_min(void) const;


//! @brief ``true`` if the binary has a MachO::ThreadCommand command.
bool has_thread_command(void) const;

//! @brief Return the MachO::ThreadCommand command
ThreadCommand& thread_command(void);
const ThreadCommand& thread_command(void) const;

template<class T>
bool has_command(void) const;

0 comments on commit 2325783

Please sign in to comment.