Skip to content

Commit 6afae6c

Browse files
committed
Enhance Mach-O support
1 parent b4e598c commit 6afae6c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+778
-55
lines changed

api/python/lief/MachO/__init__.pyi

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,15 @@ class Binary(lief.Binary):
681681

682682
def __next__(self) -> SubClient: ...
683683

684+
class it_notes:
685+
def __getitem__(self, arg: int, /) -> NoteCommand: ...
686+
687+
def __len__(self) -> int: ...
688+
689+
def __iter__(self) -> Binary.it_notes: ...
690+
691+
def __next__(self) -> NoteCommand: ...
692+
684693
class range_t:
685694
start: int
686695

@@ -1043,6 +1052,12 @@ class Binary(lief.Binary):
10431052
@property
10441053
def objc_metadata(self) -> Optional[lief.objc.Metadata]: ...
10451054

1055+
@property
1056+
def notes(self) -> Binary.it_notes: ...
1057+
1058+
@property
1059+
def has_notes(self) -> bool: ...
1060+
10461061
def __getitem__(self, arg: LoadCommand.TYPE, /) -> LoadCommand: ...
10471062

10481063
def __contains__(self, arg: LoadCommand.TYPE, /) -> bool: ...
@@ -1138,6 +1153,12 @@ class Header(lief.Object):
11381153

11391154
KEXT_BUNDLE = 11
11401155

1156+
FILESET = 12
1157+
1158+
GPU_EXECUTE = 13
1159+
1160+
GPU_DYLIB = 14
1161+
11411162
class FLAGS(enum.Flag):
11421163
@staticmethod
11431164
def from_value(arg: int, /) -> Header.FLAGS: ...
@@ -1200,6 +1221,14 @@ class Header(lief.Object):
12001221

12011222
APP_EXTENSION_SAFE = 33554432
12021223

1224+
NLIST_OUTOFSYNC_WITH_DYLDINFO = 67108864
1225+
1226+
SIM_SUPPORT = 134217728
1227+
1228+
IMPLICIT_PAGEZERO = 268435456
1229+
1230+
DYLIB_IN_CACHE = 2147483648
1231+
12031232
magic: MACHO_TYPES
12041233

12051234
cpu_type: Header.CPU_TYPE
@@ -1364,6 +1393,12 @@ class LoadCommand(lief.Object):
13641393

13651394
ATOM_INFO = 54
13661395

1396+
FUNCTION_VARIANTS = 55
1397+
1398+
FUNCTION_VARIANT_FIXUPS = 56
1399+
1400+
TARGET_TRIPLE = 57
1401+
13671402
LIEF_UNKNOWN = 4293787649
13681403

13691404
command: LoadCommand.TYPE
@@ -1658,6 +1693,18 @@ class MainCommand(LoadCommand):
16581693

16591694
def __str__(self) -> str: ...
16601695

1696+
class NoteCommand(LoadCommand):
1697+
note_offset: int
1698+
1699+
note_size: int
1700+
1701+
@property
1702+
def owner_str(self) -> str: ...
1703+
1704+
owner: memoryview
1705+
1706+
def __str__(self) -> str: ...
1707+
16611708
class DynamicSymbolCommand(LoadCommand):
16621709
class it_indirect_symbols:
16631710
def __getitem__(self, arg: int, /) -> Symbol: ...
@@ -2580,6 +2627,14 @@ class BuildVersion(LoadCommand):
25802627

25812628
TVOS_EXCLAVE_KIT = 20
25822629

2630+
WATCHOS_EXCLAVE_CORE = 21
2631+
2632+
WATCHOS_EXCLAVE_KIT = 22
2633+
2634+
VISIONOS_EXCLAVE_CORE = 23
2635+
2636+
VISIONOS_EXCLAVE_KIT = 24
2637+
25832638
ANY = 4294967295
25842639

25852640
platform: BuildVersion.PLATFORMS
@@ -2622,6 +2677,20 @@ class BuildToolVersion(lief.Object):
26222677

26232678
LLD = 4
26242679

2680+
METAL = 1024
2681+
2682+
AIRLLD = 1025
2683+
2684+
AIRNT = 1026
2685+
2686+
AIRNT_PLUGIN = 1027
2687+
2688+
AIRPACK = 1028
2689+
2690+
GPUARCHIVER = 1031
2691+
2692+
METAL_FRAMEWORK = 1032
2693+
26252694
class FilesetCommand(LoadCommand):
26262695
name: str
26272696

api/python/src/MachO/init.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
#include <LIEF/MachO/LinkerOptHint.hpp>
4646
#include <LIEF/MachO/LoadCommand.hpp>
4747
#include <LIEF/MachO/MainCommand.hpp>
48+
#include <LIEF/MachO/NoteCommand.hpp>
4849
#include <LIEF/MachO/Parser.hpp>
4950
#include <LIEF/MachO/ParserConfig.hpp>
5051
#include <LIEF/MachO/RPathCommand.hpp>
@@ -87,6 +88,7 @@ void init_objects(nb::module_& m) {
8788
CREATE(SegmentCommand, m);
8889
CREATE(Section, m);
8990
CREATE(MainCommand, m);
91+
CREATE(NoteCommand, m);
9092
CREATE(DynamicSymbolCommand, m);
9193
CREATE(DylinkerCommand, m);
9294
CREATE(DyldInfo, m);

api/python/src/MachO/objects/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ target_sources(pyLIEF PRIVATE
2828
pyLinkerOptHint.cpp
2929
pyLoadCommand.cpp
3030
pyMainCommand.cpp
31+
pyNoteCommand.cpp
3132
pyParser.cpp
3233
pyParserConfig.cpp
3334
pyRPathCommand.cpp

api/python/src/MachO/objects/pyBinary.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
#include "LIEF/MachO/LinkerOptHint.hpp"
4646
#include "LIEF/MachO/AtomInfo.hpp"
4747
#include "LIEF/MachO/MainCommand.hpp"
48+
#include "LIEF/MachO/NoteCommand.hpp"
4849
#include "LIEF/MachO/Routine.hpp"
4950
#include "LIEF/MachO/RPathCommand.hpp"
5051
#include "LIEF/MachO/Relocation.hpp"
@@ -88,6 +89,7 @@ void create<Binary>(nb::module_& m) {
8889
init_ref_iterator<Binary::it_relocations>(bin, "it_relocations");
8990
init_ref_iterator<Binary::it_rpaths>(bin, "it_rpaths");
9091
init_ref_iterator<Binary::it_sub_clients>(bin, "it_sub_clients");
92+
init_ref_iterator<Binary::it_notes>(bin, "it_notes");
9193

9294
nb::class_<Binary::range_t>(bin, "range_t")
9395
.def_rw("start", &Binary::range_t::start)
@@ -778,6 +780,14 @@ void create<Binary>(nb::module_& m) {
778780
)doc"_doc
779781
)
780782

783+
.def_prop_ro("notes",
784+
nb::overload_cast<>(&Binary::notes),
785+
"Iterator over the different ``LC_NOTE`` commands"_doc,
786+
nb::keep_alive<0, 1>())
787+
788+
.def_prop_ro("has_notes", &Binary::has_notes,
789+
"True if the binary contains ``LC_NOTE`` command(s)")
790+
781791
.def("__getitem__",
782792
nb::overload_cast<LoadCommand::TYPE>(&Binary::operator[]),
783793
nb::rv_policy::reference_internal)

api/python/src/MachO/objects/pyBuildVersion.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,14 @@ void create<BuildVersion>(nb::module_& m) {
6060
.value(PY_ENUM(BuildToolVersion::TOOLS::SWIFT))
6161
.value(PY_ENUM(BuildToolVersion::TOOLS::LD))
6262
.value(PY_ENUM(BuildToolVersion::TOOLS::LLD))
63+
64+
.value(PY_ENUM(BuildToolVersion::TOOLS::METAL))
65+
.value(PY_ENUM(BuildToolVersion::TOOLS::AIRLLD))
66+
.value(PY_ENUM(BuildToolVersion::TOOLS::AIRNT))
67+
.value(PY_ENUM(BuildToolVersion::TOOLS::AIRNT_PLUGIN))
68+
.value(PY_ENUM(BuildToolVersion::TOOLS::AIRPACK))
69+
.value(PY_ENUM(BuildToolVersion::TOOLS::GPUARCHIVER))
70+
.value(PY_ENUM(BuildToolVersion::TOOLS::METAL_FRAMEWORK))
6371
;
6472

6573

@@ -85,6 +93,10 @@ void create<BuildVersion>(nb::module_& m) {
8593
.value(PY_ENUM(BuildVersion::PLATFORMS::IOS_EXCLAVE_KIT))
8694
.value(PY_ENUM(BuildVersion::PLATFORMS::TVOS_EXCLAVE_CORE))
8795
.value(PY_ENUM(BuildVersion::PLATFORMS::TVOS_EXCLAVE_KIT))
96+
.value(PY_ENUM(BuildVersion::PLATFORMS::WATCHOS_EXCLAVE_CORE))
97+
.value(PY_ENUM(BuildVersion::PLATFORMS::WATCHOS_EXCLAVE_KIT))
98+
.value(PY_ENUM(BuildVersion::PLATFORMS::VISIONOS_EXCLAVE_CORE))
99+
.value(PY_ENUM(BuildVersion::PLATFORMS::VISIONOS_EXCLAVE_KIT))
88100
.value(PY_ENUM(BuildVersion::PLATFORMS::ANY))
89101
;
90102

api/python/src/MachO/objects/pyHeader.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ void create<Header>(nb::module_& m) {
7171
.value(PY_ENUM(Header::FILE_TYPE::DYLIB_STUB))
7272
.value(PY_ENUM(Header::FILE_TYPE::DSYM))
7373
.value(PY_ENUM(Header::FILE_TYPE::KEXT_BUNDLE))
74+
.value(PY_ENUM(Header::FILE_TYPE::FILESET))
75+
.value(PY_ENUM(Header::FILE_TYPE::GPU_EXECUTE))
76+
.value(PY_ENUM(Header::FILE_TYPE::GPU_DYLIB))
7477
#undef PY_ENUM
7578
;
7679

@@ -102,6 +105,10 @@ void create<Header>(nb::module_& m) {
102105
.value(PY_ENUM(Header::FLAGS::HAS_TLV_DESCRIPTORS))
103106
.value(PY_ENUM(Header::FLAGS::NO_HEAP_EXECUTION))
104107
.value(PY_ENUM(Header::FLAGS::APP_EXTENSION_SAFE))
108+
.value(PY_ENUM(Header::FLAGS::NLIST_OUTOFSYNC_WITH_DYLDINFO))
109+
.value(PY_ENUM(Header::FLAGS::SIM_SUPPORT))
110+
.value(PY_ENUM(Header::FLAGS::IMPLICIT_PAGEZERO))
111+
.value(PY_ENUM(Header::FLAGS::DYLIB_IN_CACHE))
105112
#undef PY_ENUM
106113
;
107114

api/python/src/MachO/objects/pyLoadCommand.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ void create<LoadCommand>(nb::module_& m) {
9494
.value(PY_ENUM(LoadCommand::TYPE::DYLD_CHAINED_FIXUPS))
9595
.value(PY_ENUM(LoadCommand::TYPE::FILESET_ENTRY))
9696
.value(PY_ENUM(LoadCommand::TYPE::ATOM_INFO))
97+
.value(PY_ENUM(LoadCommand::TYPE::FUNCTION_VARIANTS))
98+
.value(PY_ENUM(LoadCommand::TYPE::FUNCTION_VARIANT_FIXUPS))
99+
.value(PY_ENUM(LoadCommand::TYPE::TARGET_TRIPLE))
97100
.value(PY_ENUM(LoadCommand::TYPE::LIEF_UNKNOWN))
98101
#undef PY_ENUM
99102
;
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/* Copyright 2017 - 2025 R. Thomas
2+
* Copyright 2017 - 2025 Quarkslab
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
#include <string>
17+
#include <sstream>
18+
#include <nanobind/stl/string.h>
19+
#include "nanobind/extra/stl/lief_span.h"
20+
#include "nanobind/utils.hpp"
21+
22+
#include "LIEF/MachO/NoteCommand.hpp"
23+
24+
#include "MachO/pyMachO.hpp"
25+
26+
namespace LIEF::MachO::py {
27+
28+
template<>
29+
void create<NoteCommand>(nb::module_& m) {
30+
31+
nb::class_<NoteCommand, LoadCommand>(m, "NoteCommand",
32+
R"delim(
33+
Class that represent the ``LC_NOTE`` command.
34+
35+
This command is used to include arbitrary notes or metadata within a binary.
36+
)delim"_doc)
37+
38+
.def_prop_rw("note_offset",
39+
nb::overload_cast<>(&NoteCommand::note_offset, nb::const_),
40+
nb::overload_cast<uint64_t>(&NoteCommand::note_offset),
41+
"Offset of the data associated with this note"_doc)
42+
43+
.def_prop_rw("note_size",
44+
nb::overload_cast<>(&NoteCommand::note_size, nb::const_),
45+
nb::overload_cast<uint64_t>(&NoteCommand::note_size),
46+
"Size of the data referenced by the :attr:`~.note_offset`"_doc)
47+
48+
.def_prop_ro("owner_str", &NoteCommand::owner_str,
49+
"Owner as a zero-terminated string"_doc)
50+
51+
.def_prop_rw("owner",
52+
nb::overload_cast<>(&NoteCommand::owner, nb::const_),
53+
[] (NoteCommand& self, nb::bytes owner_bytes) {
54+
std::vector<uint8_t> owner = to_vector(owner_bytes);
55+
span<char> note_owner = self.owner();
56+
owner.resize(note_owner.size());
57+
std::copy(owner.begin(), owner.end(), note_owner.begin());
58+
},
59+
"Owner of the note (e.g. ``AIR_METALLIB``)"_doc)
60+
61+
LIEF_DEFAULT_STR(NoteCommand);
62+
63+
}
64+
}

api/python/src/nanobind/extra/stl/lief_span.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ NAMESPACE_BEGIN(detail)
1010

1111
template<class T>
1212
struct type_caster<LIEF::span<T>> {
13-
static_assert(std::is_same_v<uint8_t, std::remove_const_t<T>>,
13+
static_assert(std::is_same_v<uint8_t, std::remove_const_t<T>> ||
14+
std::is_same_v<char, std::remove_const_t<T>>,
1415
"Need uint8_t type");
1516

1617
static constexpr auto IsRO = std::is_const_v<T>;

api/rust/autocxx_ffi.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,8 @@ include_cpp! {
541541
block_constructors!("MachO_Binary_it_libraries")
542542
generate!("MachO_Binary_it_sub_clients")
543543
block_constructors!("MachO_Binary_it_sub_clients")
544+
generate!("MachO_Binary_it_notes")
545+
block_constructors!("MachO_Binary_it_notes")
544546
generate!("MachO_Binary_it_bindings_info")
545547
block_constructors!("MachO_Binary_it_bindings_info")
546548
generate!("MachO_BindingInfo")
@@ -613,6 +615,8 @@ include_cpp! {
613615
block_constructors!("MachO_LinkerOptHint")
614616
generate!("MachO_Main")
615617
block_constructors!("MachO_Main")
618+
generate!("MachO_NoteCommand")
619+
block_constructors!("MachO_NoteCommand")
616620
generate!("MachO_Routine")
617621
block_constructors!("MachO_Routine")
618622
generate!("MachO_RPathCommand")

0 commit comments

Comments
 (0)