LIEF: Library to Instrument Executable Formats Version 0.15.0
Loading...
Searching...
No Matches
DyldInfo.hpp
1/* Copyright 2017 - 2024 R. Thomas
2 * Copyright 2017 - 2024 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#ifndef LIEF_MACHO_DYLD_INFO_COMMAND_H
17#define LIEF_MACHO_DYLD_INFO_COMMAND_H
18#include <string>
19#include <set>
20#include <vector>
21#include <ostream>
22#include <memory>
23
24#include "LIEF/visibility.h"
25#include "LIEF/span.hpp"
26
27#include "LIEF/MachO/LoadCommand.hpp"
28#include "LIEF/MachO/type_traits.hpp"
29#include "LIEF/iterators.hpp"
30
31namespace LIEF {
32class vector_iostream;
33class BinaryStream;
34namespace MachO {
35
36class Binary;
37class BinaryParser;
38class Builder;
39class DyldBindingInfo;
40class ExportInfo;
41class LinkEdit;
42class RelocationDyld;
43
44namespace details {
45struct dyld_info_command;
46}
47
49class LIEF_API DyldInfo : public LoadCommand {
50
51 friend class BinaryParser;
52 friend class Binary;
53 friend class Builder;
54 friend class LinkEdit;
55
56 public:
58 using info_t = std::pair<uint32_t, uint32_t>;
59
61 using binding_info_t = std::vector<std::unique_ptr<DyldBindingInfo>>;
62
65
68
70 using export_info_t = std::vector<std::unique_ptr<ExportInfo>>;
71
74
77
78 enum class BINDING_ENCODING_VERSION {
79 UNKNOWN = 0,
80 V1,
81 V2
82 };
83
84 enum class REBASE_TYPE: uint64_t {
85 POINTER = 1u,
86 TEXT_ABSOLUTE32 = 2u,
87 TEXT_PCREL32 = 3u,
88 THREADED = 102u,
89 };
90
91 enum class REBASE_OPCODES: uint8_t {
92 DONE = 0x00u,
93 SET_TYPE_IMM = 0x10u,
94 SET_SEGMENT_AND_OFFSET_ULEB = 0x20u,
95 ADD_ADDR_ULEB = 0x30u,
96 ADD_ADDR_IMM_SCALED = 0x40u,
97 DO_REBASE_IMM_TIMES = 0x50u,
98 DO_REBASE_ULEB_TIMES = 0x60u,
99 DO_REBASE_ADD_ADDR_ULEB = 0x70u,
100 DO_REBASE_ULEB_TIMES_SKIPPING_ULEB = 0x80u
101 };
102
104 enum class BIND_OPCODES: uint8_t {
105 DONE = 0x00u,
106 SET_DYLIB_ORDINAL_IMM = 0x10u,
107 SET_DYLIB_ORDINAL_ULEB = 0x20u,
108 SET_DYLIB_SPECIAL_IMM = 0x30u,
109 SET_SYMBOL_TRAILING_FLAGS_IMM = 0x40u,
110 SET_TYPE_IMM = 0x50u,
111 SET_ADDEND_SLEB = 0x60u,
112 SET_SEGMENT_AND_OFFSET_ULEB = 0x70u,
113 ADD_ADDR_ULEB = 0x80u,
114 DO_BIND = 0x90u,
115 DO_BIND_ADD_ADDR_ULEB = 0xA0u,
116 DO_BIND_ADD_ADDR_IMM_SCALED = 0xB0u,
117 DO_BIND_ULEB_TIMES_SKIPPING_ULEB = 0xC0u,
118 THREADED = 0xD0u,
119
120 THREADED_APPLY = 0xD0u | 0x01u,
121 THREADED_SET_BIND_ORDINAL_TABLE_SIZE_ULEB = 0xD0u | 0x00u,
122 };
123
124 enum class BIND_SUBOPCODE_THREADED: uint8_t {
125 SET_BIND_ORDINAL_TABLE_SIZE_ULEB = 0x00u,
126 APPLY = 0x01u,
127 };
128
129 enum BIND_SYMBOL_FLAGS {
130 WEAK_IMPORT = 0x1u,
131 NON_WEAK_DEFINITION = 0x8u,
132 };
133
134 static constexpr auto OPCODE_MASK = uint32_t(0xF0);
135 static constexpr auto IMMEDIATE_MASK = uint32_t(0x0F);
136
137 DyldInfo();
138 DyldInfo(const details::dyld_info_command& dyld_info_cmd);
139
140 DyldInfo& operator=(DyldInfo other);
141 DyldInfo(const DyldInfo& copy);
142
143 void swap(DyldInfo& other) noexcept;
144
145 std::unique_ptr<LoadCommand> clone() const override {
146 return std::unique_ptr<DyldInfo>(new DyldInfo(*this));
147 }
148
149 ~DyldInfo() override;
150
164 const info_t& rebase() const {
165 return rebase_;
166 }
167
169 span<const uint8_t> rebase_opcodes() const {
170 return rebase_opcodes_;
171 }
172 span<uint8_t> rebase_opcodes() {
173 return rebase_opcodes_;
174 }
175
177 void rebase_opcodes(buffer_t raw);
178
180 std::string show_rebases_opcodes() const;
181
196 const info_t& bind() const {
197 return bind_;
198 }
199
201 span<const uint8_t> bind_opcodes() const {
202 return bind_opcodes_;
203 }
204 span<uint8_t> bind_opcodes() {
205 return bind_opcodes_;
206 }
207
209 void bind_opcodes(buffer_t raw);
210
212 std::string show_bind_opcodes() const;
213
231 const info_t& weak_bind() const {
232 return weak_bind_;
233 }
234
236 span<const uint8_t> weak_bind_opcodes() const {
237 return weak_bind_opcodes_;
238 }
239 span<uint8_t> weak_bind_opcodes() {
240 return weak_bind_opcodes_;
241 }
242
244 void weak_bind_opcodes(buffer_t raw);
245
247 std::string show_weak_bind_opcodes() const;
248
263 const info_t& lazy_bind() const {
264 return lazy_bind_;
265 }
266
268 span<const uint8_t> lazy_bind_opcodes() const {
269 return lazy_bind_opcodes_;
270 }
271 span<uint8_t> lazy_bind_opcodes() {
272 return lazy_bind_opcodes_;
273 }
274
276 void lazy_bind_opcodes(buffer_t raw);
277
279 std::string show_lazy_bind_opcodes() const;
280
283 return binding_info_;
284 }
285
286 it_const_binding_info bindings() const {
287 return binding_info_;
288 }
289
316 const info_t& export_info() const {
317 return export_;
318 }
319
322 return export_info_;
323 }
324 it_const_export_info exports() const {
325 return export_info_;
326 }
327
329 span<const uint8_t> export_trie() const {
330 return export_trie_;
331 }
332 span<uint8_t> export_trie() {
333 return export_trie_;
334 }
335
337 void export_trie(buffer_t raw);
338
340 std::string show_export_trie() const;
341
342 void rebase(const info_t& info) {
343 rebase_ = info;
344 }
345 void bind(const info_t& info) {
346 bind_ = info;
347 }
348 void weak_bind(const info_t& info) {
349 weak_bind_ = info;
350 }
351 void lazy_bind(const info_t& info) {
352 lazy_bind_ = info;
353 }
354 void export_info(const info_t& info) {
355 export_ = info;
356 }
357
358 void set_rebase_offset(uint32_t offset) {
359 rebase_ = {offset, std::get<1>(rebase())};
360 }
361 void set_rebase_size(uint32_t size) {
362 rebase_ = {std::get<0>(rebase()), size};
363 }
364
365 void set_bind_offset(uint32_t offset) {
366 bind_ = {offset, std::get<1>(bind())};
367 }
368 void set_bind_size(uint32_t size) {
369 bind_ = {std::get<0>(bind()), size};
370 }
371
372 void set_weak_bind_offset(uint32_t offset) {
373 weak_bind_ = {offset, std::get<1>(weak_bind())};
374 }
375 void set_weak_bind_size(uint32_t size) {
376 weak_bind_ = {std::get<0>(weak_bind()), size};
377 }
378
379 void set_lazy_bind_offset(uint32_t offset) {
380 lazy_bind_ = {offset, std::get<1>(lazy_bind())};
381 }
382 void set_lazy_bind_size(uint32_t size) {
383 lazy_bind_ = {std::get<0>(lazy_bind()), size};
384 }
385
386 void set_export_offset(uint32_t offset) {
387 export_ = {offset, std::get<1>(export_info())};
388 }
389
390 void set_export_size(uint32_t size) {
391 export_ = {std::get<0>(export_info()), size};
392 }
393
394 void add(std::unique_ptr<ExportInfo> info);
395
396 void accept(Visitor& visitor) const override;
397
398 std::ostream& print(std::ostream& os) const override;
399
400 static bool classof(const LoadCommand* cmd) {
401 const LoadCommand::TYPE type = cmd->command();
402 return type == LoadCommand::TYPE::DYLD_INFO ||
403 type == LoadCommand::TYPE::DYLD_INFO_ONLY;
404 }
405
406 private:
407 using bind_container_t = std::set<DyldBindingInfo*, std::function<bool(DyldBindingInfo*, DyldBindingInfo*)>>;
408
409 void show_bindings(std::ostream& os, span<const uint8_t> buffer, bool is_lazy = false) const;
410
411 void show_trie(std::ostream& output, std::string output_prefix, BinaryStream& stream, uint64_t start, uint64_t end, const std::string& prefix) const;
412
413 LIEF_LOCAL DyldInfo& update_standard_bindings(const bind_container_t& bindings, vector_iostream& stream);
414 LIEF_LOCAL DyldInfo& update_standard_bindings_v1(const bind_container_t& bindings, vector_iostream& stream);
415 LIEF_LOCAL DyldInfo& update_standard_bindings_v2(const bind_container_t& bindings,
416 std::vector<RelocationDyld*> rebases, vector_iostream& stream);
417
418 LIEF_LOCAL DyldInfo& update_weak_bindings(const bind_container_t& bindings, vector_iostream& stream);
419 LIEF_LOCAL DyldInfo& update_lazy_bindings(const bind_container_t& bindings, vector_iostream& stream);
420
421 LIEF_LOCAL DyldInfo& update_rebase_info(vector_iostream& stream);
422 LIEF_LOCAL DyldInfo& update_binding_info(vector_iostream& stream, details::dyld_info_command& cmd);
423 LIEF_LOCAL DyldInfo& update_export_trie(vector_iostream& stream);
424
425 info_t rebase_;
426 span<uint8_t> rebase_opcodes_;
427
428 info_t bind_;
429 span<uint8_t> bind_opcodes_;
430
431 info_t weak_bind_;
432 span<uint8_t> weak_bind_opcodes_;
433
434 info_t lazy_bind_;
435 span<uint8_t> lazy_bind_opcodes_;
436
437 info_t export_;
438 span<uint8_t> export_trie_;
439
440 export_info_t export_info_;
441 binding_info_t binding_info_;
442
443 BINDING_ENCODING_VERSION binding_encoding_version_ = BINDING_ENCODING_VERSION::UNKNOWN;
444
445 Binary* binary_ = nullptr;
446};
447
448LIEF_API const char* to_string(DyldInfo::REBASE_TYPE e);
449LIEF_API const char* to_string(DyldInfo::REBASE_OPCODES e);
450LIEF_API const char* to_string(DyldInfo::BIND_OPCODES e);
451LIEF_API const char* to_string(DyldInfo::BIND_SUBOPCODE_THREADED e);
452
453
454}
455}
456#endif
Class used to parse a single binary (i.e. non-FAT)
Definition BinaryParser.hpp:73
Class which represents a MachO binary.
Definition MachO/Binary.hpp:73
Class used to rebuild a Mach-O file.
Definition MachO/Builder.hpp:54
Class that represents the LC_DYLD_INFO and LC_DYLD_INFO_ONLY commands.
Definition DyldInfo.hpp:49
span< const uint8_t > bind_opcodes() const
Return Binding's opcodes as raw data.
Definition DyldInfo.hpp:201
std::string show_lazy_bind_opcodes() const
Return the lazy opcodes in a humman-readable way.
BIND_OPCODES
Opcodes used by Dyld info to bind symbols.
Definition DyldInfo.hpp:104
span< const uint8_t > rebase_opcodes() const
Return Rebase's opcodes as raw data.
Definition DyldInfo.hpp:169
void lazy_bind_opcodes(buffer_t raw)
Set new opcodes.
const info_t & export_info() const
Export information
Definition DyldInfo.hpp:316
REBASE_OPCODES
Definition DyldInfo.hpp:91
std::string show_export_trie() const
Return the export trie in a humman-readable way.
const info_t & bind() const
Bind information
Definition DyldInfo.hpp:196
const info_t & rebase() const
Rebase information
Definition DyldInfo.hpp:164
std::vector< std::unique_ptr< DyldBindingInfo > > binding_info_t
Internal container for storing DyldBindingInfo.
Definition DyldInfo.hpp:61
void rebase_opcodes(buffer_t raw)
Set new opcodes.
const info_t & weak_bind() const
Weak Bind information
Definition DyldInfo.hpp:231
it_binding_info bindings()
Iterator over BindingInfo entries.
Definition DyldInfo.hpp:282
void weak_bind_opcodes(buffer_t raw)
Set new opcodes.
it_export_info exports()
Iterator over ExportInfo entries.
Definition DyldInfo.hpp:321
void bind_opcodes(buffer_t raw)
Set new opcodes.
std::pair< uint32_t, uint32_t > info_t
Tuple of offset and size
Definition DyldInfo.hpp:58
std::string show_bind_opcodes() const
Return the bind opcodes in a humman-readable way.
std::string show_rebases_opcodes() const
Return the rebase opcodes in a humman-readable way.
void export_trie(buffer_t raw)
Set new trie.
span< const uint8_t > lazy_bind_opcodes() const
Return Lazy Binding's opcodes as raw data.
Definition DyldInfo.hpp:268
const info_t & lazy_bind() const
Lazy Bind information
Definition DyldInfo.hpp:263
std::vector< std::unique_ptr< ExportInfo > > export_info_t
Internal container for storing ExportInfo.
Definition DyldInfo.hpp:70
span< const uint8_t > export_trie() const
Return Export's trie as raw data.
Definition DyldInfo.hpp:329
span< const uint8_t > weak_bind_opcodes() const
Return Weak Binding's opcodes as raw data.
Definition DyldInfo.hpp:236
std::string show_weak_bind_opcodes() const
Return the bind opcodes in a humman-readable way.
Definition LinkEdit.hpp:42
Based class for the Mach-O load commands.
Definition LoadCommand.hpp:36
Iterator which returns reference on container's values.
Definition iterators.hpp:48
LIEF namespace.
Definition Abstract/Binary.hpp:32