Skip to content

Commit

Permalink
Add Mach-O encryption info command
Browse files Browse the repository at this point in the history
  • Loading branch information
romainthomas committed Jun 8, 2018
1 parent 311c795 commit f4e2d81
Show file tree
Hide file tree
Showing 21 changed files with 355 additions and 14 deletions.
1 change: 1 addition & 0 deletions api/python/MachO/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ set(LIEF_PYTHON_MACHO_SRC
"${CMAKE_CURRENT_LIST_DIR}/objects/pyDataCodeEntry.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pySubFramework.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyDyldEnvironment.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyEncryptionInfo.cpp"
"${CMAKE_CURRENT_LIST_DIR}/pyEnums.cpp"
)

Expand Down
10 changes: 10 additions & 0 deletions api/python/MachO/objects/pyBinary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,16 @@ void create<Binary>(py::module& m) {
"Return binary's " RST_CLASS_REF(lief.MachO.DyldEnvironment) " if any.",
py::return_value_policy::reference)

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

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


.def("virtual_address_to_offset",
&Binary::virtual_address_to_offset,
Expand Down
80 changes: 80 additions & 0 deletions api/python/MachO/objects/pyEncryptionInfo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/* 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/EncryptionInfo.hpp"

#include "pyMachO.hpp"

namespace LIEF {
namespace MachO {

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

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


template<>
void create<EncryptionInfo>(py::module& m) {

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

.def_property("crypt_offset",
static_cast<getter_t<uint32_t>>(&EncryptionInfo::crypt_offset),
static_cast<setter_t<uint32_t>>(&EncryptionInfo::crypt_offset),
"File offset of encrypted range",
py::return_value_policy::reference_internal)

.def_property("crypt_size",
static_cast<getter_t<uint32_t>>(&EncryptionInfo::crypt_size),
static_cast<setter_t<uint32_t>>(&EncryptionInfo::crypt_size),
"File size of encrypted range",
py::return_value_policy::reference_internal)

.def_property("crypt_id",
static_cast<getter_t<uint32_t>>(&EncryptionInfo::crypt_id),
static_cast<setter_t<uint32_t>>(&EncryptionInfo::crypt_id),
"Which enryption system, 0 means not-encrypted yet",
py::return_value_policy::reference_internal)



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


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

}
}
1 change: 1 addition & 0 deletions api/python/MachO/pyMachO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ void init_objects(py::module& m) {
CREATE(SegmentSplitInfo, m);
CREATE(SubFramework, m);
CREATE(DyldEnvironment, m);
CREATE(EncryptionInfo, m);
}

}
Expand Down
1 change: 1 addition & 0 deletions api/python/MachO/pyMachO.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ SPECIALIZE_CREATE(VersionMin);
SPECIALIZE_CREATE(SegmentSplitInfo);
SPECIALIZE_CREATE(SubFramework);
SPECIALIZE_CREATE(DyldEnvironment);
SPECIALIZE_CREATE(EncryptionInfo);

}
}
Expand Down
8 changes: 8 additions & 0 deletions doc/sphinx/api/cpp/macho.rst
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,14 @@ Dyld Environment

----------

Encryption Info
***************

.. doxygenclass:: LIEF::MachO::EncryptionInfo
:project: lief

----------

Utilities
*********

Expand Down
11 changes: 11 additions & 0 deletions doc/sphinx/api/python/macho.rst
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,17 @@ Dyld Environment

----------

Encryption Info
***************

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

----------



Enums
*****
Expand Down
24 changes: 24 additions & 0 deletions examples/python/macho_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -615,6 +615,23 @@ def print_relocations(binary):

print("")

@exceptions_handler(Exception)
def print_encryption_info(binary):

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

print("== Encryption Info ==")
cmd = binary.encryption_info

print(format_hex.format("Offset:", cmd.crypt_offset))
print(format_hex.format("Size:", cmd.crypt_size))
print(format_dec.format("ID:", cmd.crypt_id))

print("")



def main():
parser = argparse.ArgumentParser(usage='%(prog)s [options] <macho-file>')
Expand Down Expand Up @@ -714,6 +731,10 @@ def main():
action='store_true', dest='show_dyld_env',
help="Display the 'Dyld Environment' command")

parser.add_argument('--encryption-info',
action='store_true', dest='show_encrypt_info',
help="Display the 'Encryption Info' command")

parser.add_argument('--bind-opcodes',
action='store_true', dest='show_bind_opcodes',
help='Display the "Bind" opcodes')
Expand Down Expand Up @@ -817,6 +838,9 @@ def main():
if (args.show_dyld_env or args.show_all) and binary.has_dyld_environment:
print_dyld_environment(binary)

if (args.show_encrypt_info or args.show_all) and binary.has_encryption_info:
print_encryption_info(binary)

if (args.show_rpath_command or args.show_all) and binary.has_rpath:
print_rpath_command(binary)

Expand Down
8 changes: 8 additions & 0 deletions include/LIEF/MachO/Binary.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
#include "LIEF/MachO/SegmentSplitInfo.hpp"
#include "LIEF/MachO/SubFramework.hpp"
#include "LIEF/MachO/DyldEnvironment.hpp"
#include "LIEF/MachO/EncryptionInfo.hpp"

namespace LIEF {
namespace MachO {
Expand Down Expand Up @@ -330,6 +331,13 @@ class LIEF_API Binary : public LIEF::Binary {
DyldEnvironment& dyld_environment(void);
const DyldEnvironment& dyld_environment(void) const;

//! @brief ``true`` if the binary has Encryption Info.
bool has_encryption_info(void) const;

//! @brief Return the MachO::DyldEnvironment
EncryptionInfo& encryption_info(void);
const EncryptionInfo& encryption_info(void) const;

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

Expand Down
64 changes: 64 additions & 0 deletions include/LIEF/MachO/EncryptionInfo.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/* 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_ENCRYPTION_INFO_COMMAND_H_
#define LIEF_MACHO_ENCRYPTION_INFO_COMMAND_H_
#include <string>
#include <vector>
#include <iostream>
#include <array>

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

#include "LIEF/MachO/LoadCommand.hpp"

namespace LIEF {
namespace MachO {

class LIEF_API EncryptionInfo : public LoadCommand {
public:
EncryptionInfo(void);
EncryptionInfo(const encryption_info_command *cmd);

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

virtual ~EncryptionInfo(void);

uint32_t crypt_offset(void) const;
uint32_t crypt_size(void) const;
uint32_t crypt_id(void) const;

void crypt_offset(uint32_t offset);
void crypt_size(uint32_t size);
void crypt_id(uint32_t id);

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

virtual void accept(Visitor& visitor) const override;

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

private:
uint32_t coff_;
uint32_t csize_;
uint32_t cid_;
};

}
}
#endif
2 changes: 0 additions & 2 deletions include/LIEF/MachO/Structures.hpp.in
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ namespace MachO {
using section = section_32;
using routines_command = routines_command_32;
using dylib_module = dylib_module_32;
using encryption_info_command = encryption_info_command_32;
using nlist = nlist_32;

using uint = uint32_t;
Expand All @@ -81,7 +80,6 @@ namespace MachO {
using section = section_64;
using routines_command = routines_command_64;
using dylib_module = dylib_module_64;
using encryption_info_command = encryption_info_command_64;
using nlist = nlist_64;

using uint = uint64_t;
Expand Down
3 changes: 2 additions & 1 deletion include/LIEF/MachO/hash.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ class LIEF_API Hash : public LIEF::Hash {
virtual void visit(const SourceVersion& sv) override;
virtual void visit(const SegmentSplitInfo& ssi) override;
virtual void visit(const SubFramework& sf) override;
virtual void visit(const DyldEnvironment& sf) override;
virtual void visit(const DyldEnvironment& sf) override;
virtual void visit(const EncryptionInfo& e) override;

virtual ~Hash(void);
};
Expand Down
3 changes: 2 additions & 1 deletion include/LIEF/MachO/json.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ class LIEF_API JsonVisitor : public LIEF::JsonVisitor {
virtual void visit(const VersionMin& vmin) override;
virtual void visit(const SegmentSplitInfo& ssi) override;
virtual void visit(const SubFramework& sf) override;
virtual void visit(const DyldEnvironment& sf) override;
virtual void visit(const DyldEnvironment& sf) override;
virtual void visit(const EncryptionInfo& e) override;
};

}
Expand Down
11 changes: 1 addition & 10 deletions include/LIEF/MachO/structures.inc
Original file line number Diff line number Diff line change
Expand Up @@ -302,23 +302,14 @@ struct source_version_command {
uint64_t version;
};

struct encryption_info_command_32 {
struct encryption_info_command {
uint32_t cmd;
uint32_t cmdsize;
uint32_t cryptoff;
uint32_t cryptsize;
uint32_t cryptid;
};

struct encryption_info_command_64 {
uint32_t cmd;
uint32_t cmdsize;
uint32_t cryptoff;
uint32_t cryptsize;
uint32_t cryptid;
uint32_t pad;
};

struct version_min_command {
uint32_t cmd; // LC_VERSION_MIN_MACOSX or
// LC_VERSION_MIN_IPHONEOS
Expand Down
4 changes: 4 additions & 0 deletions include/LIEF/Visitor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ LIEF_MACHO_FORWARD(VersionMin)
LIEF_MACHO_FORWARD(SegmentSplitInfo)
LIEF_MACHO_FORWARD(SubFramework)
LIEF_MACHO_FORWARD(DyldEnvironment)
LIEF_MACHO_FORWARD(EncryptionInfo)

// OAT
// ===============================
Expand Down Expand Up @@ -461,6 +462,9 @@ class LIEF_API Visitor {
//! @brief Method to visit a LIEF::MachO::DyldEnvironment
LIEF_MACHO_VISITABLE(DyldEnvironment)

//! @brief Method to visit a LIEF::MachO::DyldEnvironment
LIEF_MACHO_VISITABLE(EncryptionInfo)

// OAT part
// ========

Expand Down
15 changes: 15 additions & 0 deletions src/MachO/Binary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -872,6 +872,21 @@ const DyldEnvironment& Binary::dyld_environment(void) const {
return this->command<DyldEnvironment>();
}

// EncryptionInfo command
// +++++++++++++++++++++++
bool Binary::has_encryption_info(void) const {
return this->has_command<EncryptionInfo>();
}

EncryptionInfo& Binary::encryption_info(void) {
return this->command<EncryptionInfo>();
}

const EncryptionInfo& Binary::encryption_info(void) const {
return this->command<EncryptionInfo>();
}





Expand Down
Loading

0 comments on commit f4e2d81

Please sign in to comment.