LIEF: Library to Instrument Executable Formats Version 2.0.0
Loading...
Searching...
No Matches
BinaryParser.hpp
Go to the documentation of this file.
1/* Copyright 2017 - 2026 R. Thomas
2 * Copyright 2017 - 2026 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_BINARY_PARSER_H
17#define LIEF_MACHO_BINARY_PARSER_H
18#include <string_view>
19#include <unordered_map>
20#include <limits>
21#include <map>
22#include <memory>
23#include <set>
24#include <string>
25#include <vector>
26
27#include "LIEF/errors.hpp"
28#include "LIEF/path.hpp"
29#include "LIEF/visibility.h"
30
32
36#include "LIEF/MachO/enums.hpp"
37
38namespace LIEF {
39class BinaryStream;
40class SpanStream;
41
42namespace MachO {
43class AtomInfo;
45class CodeSignature;
47class DataInCode;
49class DylibCommand;
51class ExportInfo;
52class FunctionStarts;
56class LinkerOptHint;
57class Parser;
58class Section;
59class SegmentCommand;
61class Symbol;
62class SymbolCommand;
63class TwoLevelHints;
64struct ParserConfig;
65
66
67namespace details {
68struct dyld_chained_starts_in_segment;
69struct dyld_chained_fixups_header;
70union dyld_chained_ptr_arm64e;
71union dyld_chained_ptr_generic64;
72union dyld_chained_ptr_generic32;
73union dyld_chained_ptr_arm64e_segmented;
74}
75
82
83 friend class MachO::Parser;
84
86 constexpr static size_t MAX_RELOCATIONS = (std::numeric_limits<uint16_t>::max)();
87
89 constexpr static size_t MAX_COMMANDS = (std::numeric_limits<uint16_t>::max)();
90
91 public:
92 static std::unique_ptr<Binary> parse(std::string_view file);
93 static std::unique_ptr<Binary> parse(std::string_view file,
94 const ParserConfig& conf);
95
98 template<class PathT, enable_if_path_t<PathT> = 0>
99 static std::unique_ptr<Binary>
100 parse(const PathT& file, const ParserConfig& conf = ParserConfig::deep()) {
101 return parse(file.string(), conf);
102 }
103
104 static std::unique_ptr<Binary>
105 parse(const std::vector<uint8_t>& data,
106 const ParserConfig& conf = ParserConfig::deep());
107
108 static std::unique_ptr<Binary>
109 parse(const std::vector<uint8_t>& data, uint64_t fat_offset,
110 const ParserConfig& conf = ParserConfig::deep());
111
112 static std::unique_ptr<Binary> parse(std::unique_ptr<BinaryStream> stream,
113 uint64_t fat_offset,
114 const ParserConfig& conf);
115
116 BinaryParser& operator=(const BinaryParser& copy) = delete;
117 BinaryParser(const BinaryParser& copy) = delete;
118
120
121 private:
122 using exports_list_t = std::vector<std::unique_ptr<ExportInfo>>;
124
125 LIEF_LOCAL ok_error_t init_and_parse();
126
127 template<class MACHO_T>
129
130 template<class MACHO_T>
131 LIEF_LOCAL ok_error_t parse_header();
132
133 template<class MACHO_T>
134 LIEF_LOCAL ok_error_t parse_load_commands();
135
136 template<class MACHO_T>
137 LIEF_LOCAL ok_error_t parse_relocations(Section& section);
138
139 // Dyld info parser
140 // ================
141
142 // Rebase
143 // ------
144 template<class MACHO_T>
145 LIEF_LOCAL ok_error_t parse_dyldinfo_rebases();
146
147 // Bindings
148 // --------
149 template<class MACHO_T>
150 LIEF_LOCAL ok_error_t parse_dyldinfo_binds();
151
152 template<class MACHO_T>
153 LIEF_LOCAL ok_error_t parse_dyldinfo_generic_bind();
154
155 template<class MACHO_T>
156 LIEF_LOCAL ok_error_t parse_dyldinfo_weak_bind();
157
158 template<class MACHO_T>
159 LIEF_LOCAL ok_error_t parse_dyldinfo_lazy_bind();
160
161 template<class MACHO_T>
162 LIEF_LOCAL ok_error_t infer_indirect_bindings();
163
164 template<class MACHO_T>
165 LIEF_LOCAL ok_error_t parse_symtab(SymbolCommand& cmd, SpanStream& nlist_s,
166 SpanStream& string_s);
167
168 LIEF_LOCAL ok_error_t parse_indirect_symbols(DynamicSymbolCommand& cmd,
169 std::vector<Symbol*>& symtab,
170 BinaryStream& indirect_stream);
171
172
173 template<class MACHO_T>
174 LIEF_LOCAL ok_error_t parse_data_in_code(DataInCode& cmd, BinaryStream& stream);
175
176 using it_opaque_segments =
177 void*; // To avoid including Binary.hpp. It must contains it_opaque_segments
178
179 template<class MACHO_T>
180 LIEF_LOCAL ok_error_t do_bind(DyldBindingInfo::CLASS cls, uint8_t type,
181 uint8_t segment_idx, uint64_t segment_offset,
182 const std::string& symbol_name, int32_t ord,
183 int64_t addend, bool is_weak,
184 bool is_non_weak_definition,
185 it_opaque_segments segments_ptr,
186 uint64_t offset = 0);
187
188
189 template<class MACHO_T>
190 LIEF_LOCAL ok_error_t do_rebase(uint8_t type, uint8_t segment_idx,
191 uint64_t segment_offset,
192 it_opaque_segments segments);
193
194 /*
195 * This set of functions are related to the parsing of LC_DYLD_CHAINED_FIXUPS
196 */
197 template<class MACHO_T>
198 LIEF_LOCAL ok_error_t parse_chained_payload(SpanStream& stream);
199
200 template<class MACHO_T>
202 parse_chained_import(const details::dyld_chained_fixups_header& header,
203 SpanStream& stream, SpanStream& symbol_pool);
204
205 template<class MACHO_T>
207 parse_chained_fixup(const details::dyld_chained_fixups_header& header,
208 SpanStream& stream);
209
210 template<class MACHO_T>
211 LIEF_LOCAL ok_error_t parse_fixup_seg(SpanStream& stream,
212 uint32_t seg_info_offset, uint64_t offset,
213 uint32_t seg_idx);
214
215 template<class MACHO_T>
216 LIEF_LOCAL ok_error_t do_fixup(DYLD_CHAINED_FORMAT fmt, int32_t ord,
217 const std::string& symbol_name, int64_t addend,
218 bool is_weak);
219
220 template<class MACHO_T>
222 process_fixup(SegmentCommand& segment, uint64_t chain_address,
223 uint64_t chain_offset,
224 const details::dyld_chained_starts_in_segment& seg_info);
225
226 template<class MACHO_T>
228 next_chain(uint64_t& chain_address, uint64_t chain_offset,
229 const details::dyld_chained_starts_in_segment& seg_info);
230
231 template<class MACHO_T>
233 walk_chain(SegmentCommand& segment, uint64_t chain_address,
234 uint64_t chain_offset,
235 const details::dyld_chained_starts_in_segment& seg_info);
236
238 do_chained_fixup(SegmentCommand& segment, uint64_t chain_address,
239 uint32_t chain_offset,
240 const details::dyld_chained_starts_in_segment& seg_info,
241 const details::dyld_chained_ptr_arm64e& fixup);
242
244 do_chained_fixup(SegmentCommand& segment, uint64_t chain_address,
245 uint32_t chain_offset,
246 const details::dyld_chained_starts_in_segment& seg_info,
247 const details::dyld_chained_ptr_generic64& fixup);
248
250 do_chained_fixup(SegmentCommand& segment, uint64_t chain_address,
251 uint32_t chain_offset,
252 const details::dyld_chained_starts_in_segment& seg_info,
253 const details::dyld_chained_ptr_generic32& fixup);
254
256 do_chained_fixup(SegmentCommand& segment, uint64_t chain_address,
257 uint32_t chain_offset,
258 const details::dyld_chained_starts_in_segment& seg_info,
259 const details::dyld_chained_ptr_arm64e_segmented& fixup);
260
261 template<class MACHO_T>
262 LIEF_LOCAL ok_error_t post_process(SymbolCommand& cmd);
263
264 template<class MACHO_T>
265 LIEF_LOCAL ok_error_t post_process(FunctionStarts& cmd);
266
267 template<class MACHO_T>
268 LIEF_LOCAL ok_error_t post_process(DataInCode& cmd);
269
270 template<class MACHO_T>
271 LIEF_LOCAL ok_error_t post_process(SegmentSplitInfo& cmd);
272
273 template<class MACHO_T>
274 LIEF_LOCAL ok_error_t post_process(DynamicSymbolCommand& cmd);
275
276 template<class MACHO_T>
277 LIEF_LOCAL ok_error_t post_process(LinkerOptHint& cmd);
278
279 template<class MACHO_T>
280 LIEF_LOCAL ok_error_t post_process(AtomInfo& cmd);
281
282 template<class MACHO_T>
283 LIEF_LOCAL ok_error_t post_process(TwoLevelHints& cmd);
284
285 template<class MACHO_T>
286 LIEF_LOCAL ok_error_t post_process(CodeSignature& cmd);
287
288 template<class MACHO_T>
289 LIEF_LOCAL ok_error_t post_process(CodeSignatureDir& cmd);
290
291 template<class MACHO_T>
292 LIEF_LOCAL ok_error_t post_process(FunctionVariants& cmd);
293
294 template<class MACHO_T>
296
297 template<class MACHO_T>
298 LIEF_LOCAL ok_error_t post_process(LazyLoadDylibInfo& cmd);
299
300 LIEF_LOCAL ok_error_t parse_overlay();
301
302 // Exports
303 // -------
304 LIEF_LOCAL ok_error_t parse_dyldinfo_export();
305 LIEF_LOCAL ok_error_t parse_dyld_exports();
306
307 LIEF_LOCAL result<exports_list_t> parse_export_trie(BinaryStream& stream,
308 uint64_t start,
309 const std::string& prefix,
310 uint32_t depth,
311 bool* invalid_names);
312
313 LIEF_LOCAL void copy_from(ChainedBindingInfo& to, ChainedBindingInfo& from);
314
315 std::unique_ptr<BinaryStream> stream_;
316 std::unique_ptr<Binary> binary_;
318 bool is64_ = true;
319 ParserConfig config_;
320 std::set<uint64_t> visited_;
321 std::unordered_map<std::string, Symbol*> memoized_symbols_;
322 std::map<uint64_t, Symbol*> memoized_symbols_by_address_;
323
324 std::vector<DylibCommand*> binding_libs_;
325 std::set<uint64_t> dyld_reloc_addrs_;
326
327 // Cache of DyldChainedFixups
328 DyldChainedFixups* chained_fixups_ = nullptr;
329};
330
331
332}
333}
334#endif
Class that is used to a read stream of data from different sources.
Definition BinaryStream.hpp:35
Class which represents the LC_ATOM_INFO command.
Definition AtomInfo.hpp:37
BinaryParser(const BinaryParser &copy)=delete
static std::unique_ptr< Binary > parse(std::string_view file)
static std::unique_ptr< Binary > parse(const PathT &file, const ParserConfig &conf=ParserConfig::deep())
Same as parse(std::string_view, const ParserConfig&) but the file is given as a std::filesystem::path...
Definition BinaryParser.hpp:100
BinaryParser & operator=(const BinaryParser &copy)=delete
static std::unique_ptr< Binary > parse(std::unique_ptr< BinaryStream > stream, uint64_t fat_offset, const ParserConfig &conf)
static std::unique_ptr< Binary > parse(const std::vector< uint8_t > &data, uint64_t fat_offset, const ParserConfig &conf=ParserConfig::deep())
static std::unique_ptr< Binary > parse(std::string_view file, const ParserConfig &conf)
static std::unique_ptr< Binary > parse(const std::vector< uint8_t > &data, const ParserConfig &conf=ParserConfig::deep())
This class represents a symbol binding operation associated with the LC_DYLD_CHAINED_FIXUPS command.
Definition ChainedBindingInfo.hpp:48
Definition CodeSignatureDir.hpp:38
Definition CodeSignature.hpp:39
Interface of the LC_DATA_IN_CODE command This command is used to list slices of code sections that co...
Definition DataInCode.hpp:44
CLASS
Definition DyldBindingInfo.hpp:39
Class that represents the LC_DYLD_CHAINED_FIXUPS command.
Definition DyldChainedFixups.hpp:50
Class which represents a library dependency.
Definition DylibCommand.hpp:36
Class that represents the LC_DYSYMTAB command.
Definition DynamicSymbolCommand.hpp:41
Class that provides an interface over the Dyld export info.
Definition ExportInfo.hpp:38
Class which represents the LC_FUNCTION_STARTS command.
Definition FunctionStarts.hpp:41
Class which represents the LC_FUNCTION_VARIANT_FIXUPS command.
Definition FunctionVariantFixups.hpp:61
Class representing the LC_FUNCTION_VARIANTS load command.
Definition FunctionVariants.hpp:70
Class representing the LC_LAZY_LOAD_DYLIB_INFO load command.
Definition LazyLoadDylibInfo.hpp:51
Class which represents the LC_LINKER_OPTIMIZATION_HINT command.
Definition LinkerOptHint.hpp:39
The main interface to parse a Mach-O binary.
Definition MachO/Parser.hpp:43
Class that represents a Mach-O section.
Definition MachO/Section.hpp:49
Class which represents a LoadCommand::TYPE::SEGMENT / LoadCommand::TYPE::SEGMENT_64 command.
Definition SegmentCommand.hpp:54
Class that represents the LoadCommand::TYPE::SEGMENT_SPLIT_INFO command.
Definition SegmentSplitInfo.hpp:37
Class that represents the LC_SYMTAB command.
Definition SymbolCommand.hpp:37
Class that represents a Symbol in a Mach-O file.
Definition MachO/Symbol.hpp:47
Class which represents the LC_TWOLEVEL_HINTS command.
Definition TwoLevelHints.hpp:41
Main interface to parse an executable regardless of its format.
Definition Abstract/Parser.hpp:32
Definition SpanStream.hpp:32
Opaque structure that is used by LIEF to avoid writing result<void> f(...). Instead,...
Definition errors.hpp:119
Wrapper that contains an Object (T) or an error.
Definition errors.hpp:79
Definition endianness_support.hpp:59
Namespace related to the LIEF's Mach-O module.
Definition Abstract/Header.hpp:36
DYLD_CHAINED_FORMAT
Definition DyldChainedFormat.hpp:22
MACHO_TYPES
Definition MachO/enums.hpp:23
@ MAGIC_64
64-bit big-endian magic
Definition MachO/enums.hpp:28
LIEF namespace.
Definition Abstract/Binary.hpp:41
This structure is used to tweak the MachO Parser (MachO::Parser).
Definition MachO/ParserConfig.hpp:24
static ParserConfig deep()
Return a parser configuration such as all the objects supported by LIEF are parsed.
#define LIEF_API
Definition visibility.h:45
#define LIEF_LOCAL
Definition visibility.h:46