mirror of
https://github.com/QuasarApp/LIEF.git
synced 2025-04-28 05:14:33 +00:00
Add Mach-O encryption info command
This commit is contained in:
parent
311c7951e6
commit
f4e2d81bfe
@ -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"
|
||||
)
|
||||
|
||||
|
@ -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,
|
||||
|
80
api/python/MachO/objects/pyEncryptionInfo.cpp
Normal file
80
api/python/MachO/objects/pyEncryptionInfo.cpp
Normal file
@ -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;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -63,6 +63,7 @@ void init_objects(py::module& m) {
|
||||
CREATE(SegmentSplitInfo, m);
|
||||
CREATE(SubFramework, m);
|
||||
CREATE(DyldEnvironment, m);
|
||||
CREATE(EncryptionInfo, m);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -76,6 +76,7 @@ SPECIALIZE_CREATE(VersionMin);
|
||||
SPECIALIZE_CREATE(SegmentSplitInfo);
|
||||
SPECIALIZE_CREATE(SubFramework);
|
||||
SPECIALIZE_CREATE(DyldEnvironment);
|
||||
SPECIALIZE_CREATE(EncryptionInfo);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -277,6 +277,14 @@ Dyld Environment
|
||||
|
||||
----------
|
||||
|
||||
Encryption Info
|
||||
***************
|
||||
|
||||
.. doxygenclass:: LIEF::MachO::EncryptionInfo
|
||||
:project: lief
|
||||
|
||||
----------
|
||||
|
||||
Utilities
|
||||
*********
|
||||
|
||||
|
@ -343,6 +343,17 @@ Dyld Environment
|
||||
|
||||
----------
|
||||
|
||||
Encryption Info
|
||||
***************
|
||||
|
||||
.. autoclass:: lief.MachO.EncryptionInfo
|
||||
:members:
|
||||
:inherited-members:
|
||||
:undoc-members:
|
||||
|
||||
----------
|
||||
|
||||
|
||||
|
||||
Enums
|
||||
*****
|
||||
|
@ -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>')
|
||||
@ -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')
|
||||
@ -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)
|
||||
|
||||
|
@ -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 {
|
||||
@ -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;
|
||||
|
||||
|
64
include/LIEF/MachO/EncryptionInfo.hpp
Normal file
64
include/LIEF/MachO/EncryptionInfo.hpp
Normal file
@ -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
|
@ -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;
|
||||
@ -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;
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -302,7 +302,7 @@ 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;
|
||||
@ -310,15 +310,6 @@ struct encryption_info_command_32 {
|
||||
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
|
||||
|
@ -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
|
||||
// ===============================
|
||||
@ -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
|
||||
// ========
|
||||
|
||||
|
@ -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>();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -524,6 +524,19 @@ void BinaryParser::parse_load_commands(void) {
|
||||
}
|
||||
|
||||
|
||||
// ================
|
||||
// Encryption Info
|
||||
// ================
|
||||
case LOAD_COMMAND_TYPES::LC_ENCRYPTION_INFO:
|
||||
case LOAD_COMMAND_TYPES::LC_ENCRYPTION_INFO_64:
|
||||
{
|
||||
VLOG(VDEBUG) << "[+] Parsing " << to_string(static_cast<LOAD_COMMAND_TYPES>(command.cmd));
|
||||
const encryption_info_command* cmd = &this->stream_->peek<encryption_info_command>(loadcommands_offset);
|
||||
load_command = std::unique_ptr<EncryptionInfo>{new EncryptionInfo{cmd}};
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
{
|
||||
LOG(WARNING) << "Command '" << to_string(static_cast<LOAD_COMMAND_TYPES>(command.cmd))
|
||||
|
@ -54,6 +54,7 @@ set(LIEF_MACHO_SRC
|
||||
"${CMAKE_CURRENT_LIST_DIR}/DataCodeEntry.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/SubFramework.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/DyldEnvironment.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/EncryptionInfo.cpp"
|
||||
)
|
||||
|
||||
set(LIEF_MACHO_INCLUDE_FILES
|
||||
@ -96,6 +97,7 @@ set(LIEF_MACHO_INCLUDE_FILES
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/MachO/DataCodeEntry.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/MachO/SubFramework.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/MachO/DyldEnvironment.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/MachO/EncryptionInfo.hpp"
|
||||
)
|
||||
|
||||
# JSON Part
|
||||
|
87
src/MachO/EncryptionInfo.cpp
Normal file
87
src/MachO/EncryptionInfo.cpp
Normal file
@ -0,0 +1,87 @@
|
||||
/* 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/EncryptionInfo.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
namespace MachO {
|
||||
|
||||
EncryptionInfo::EncryptionInfo(void) = default;
|
||||
EncryptionInfo& EncryptionInfo::operator=(const EncryptionInfo&) = default;
|
||||
EncryptionInfo::EncryptionInfo(const EncryptionInfo&) = default;
|
||||
EncryptionInfo::~EncryptionInfo(void) = default;
|
||||
|
||||
EncryptionInfo::EncryptionInfo(const encryption_info_command *cmd) :
|
||||
LoadCommand::LoadCommand{static_cast<LOAD_COMMAND_TYPES>(cmd->cmd), cmd->cmdsize},
|
||||
coff_{cmd->cryptoff},
|
||||
csize_{cmd->cryptsize},
|
||||
cid_{cmd->cryptid}
|
||||
{}
|
||||
|
||||
|
||||
uint32_t EncryptionInfo::crypt_offset(void) const {
|
||||
return this->coff_;
|
||||
}
|
||||
|
||||
uint32_t EncryptionInfo::crypt_size(void) const {
|
||||
return this->csize_;
|
||||
}
|
||||
|
||||
uint32_t EncryptionInfo::crypt_id(void) const {
|
||||
return this->cid_;
|
||||
}
|
||||
|
||||
|
||||
void EncryptionInfo::crypt_offset(uint32_t offset) {
|
||||
this->coff_ = offset;
|
||||
}
|
||||
|
||||
void EncryptionInfo::crypt_size(uint32_t size) {
|
||||
this->csize_ = size;
|
||||
}
|
||||
|
||||
void EncryptionInfo::crypt_id(uint32_t id) {
|
||||
this->cid_ = id;
|
||||
}
|
||||
|
||||
void EncryptionInfo::accept(Visitor& visitor) const {
|
||||
visitor.visit(*this);
|
||||
}
|
||||
|
||||
|
||||
bool EncryptionInfo::operator==(const EncryptionInfo& rhs) const {
|
||||
size_t hash_lhs = Hash::hash(*this);
|
||||
size_t hash_rhs = Hash::hash(rhs);
|
||||
return hash_lhs == hash_rhs;
|
||||
}
|
||||
|
||||
bool EncryptionInfo::operator!=(const EncryptionInfo& rhs) const {
|
||||
return not (*this == rhs);
|
||||
}
|
||||
|
||||
|
||||
std::ostream& EncryptionInfo::print(std::ostream& os) const {
|
||||
LoadCommand::print(os);
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -288,6 +288,13 @@ void Hash::visit(const DyldEnvironment& de) {
|
||||
this->process(de.value());
|
||||
}
|
||||
|
||||
void Hash::visit(const EncryptionInfo& e) {
|
||||
this->visit(*e.as<EncryptionInfo>());
|
||||
this->process(e.crypt_offset());
|
||||
this->process(e.crypt_size());
|
||||
this->process(e.crypt_id());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -167,6 +167,12 @@ void JsonVisitor::visit(const Binary& binary) {
|
||||
v(binary.data_in_code());
|
||||
this->node_["data_in_code"] = v.get();
|
||||
}
|
||||
|
||||
if (binary.has_encryption_info()) {
|
||||
JsonVisitor v;
|
||||
v(binary.encryption_info());
|
||||
this->node_["encryption_info"] = v.get();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -456,6 +462,14 @@ void JsonVisitor::visit(const DyldEnvironment& dv) {
|
||||
}
|
||||
|
||||
|
||||
void JsonVisitor::visit(const EncryptionInfo& e) {
|
||||
this->visit(*e.as<LoadCommand>());
|
||||
this->node_["crypt_offset"] = e.crypt_offset();
|
||||
this->node_["crypt_size"] = e.crypt_size();
|
||||
this->node_["crypt_id"] = e.crypt_id();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace MachO
|
||||
|
Loading…
x
Reference in New Issue
Block a user