LIEF: Library to Instrument Executable Formats Version 0.15.0
Loading...
Searching...
No Matches
BinaryParser.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_BINARY_PARSER_H
17#define LIEF_MACHO_BINARY_PARSER_H
18#include <memory>
19#include <string>
20#include <vector>
21#include <limits>
22#include <set>
23#include <map>
24
25#include "LIEF/visibility.h"
26#include "LIEF/errors.hpp"
27
28#include "LIEF/Abstract/Parser.hpp"
29
30#include "LIEF/MachO/enums.hpp"
31#include "LIEF/MachO/DyldChainedFormat.hpp"
32#include "LIEF/MachO/ParserConfig.hpp"
33#include "LIEF/MachO/DyldBindingInfo.hpp"
34
35namespace LIEF {
36class BinaryStream;
37class SpanStream;
38
39namespace MachO {
40class ChainedBindingInfo;
41class CodeSignature;
42class CodeSignatureDir;
43class DataInCode;
44class DyldChainedFixups;
45class DylibCommand;
46class DynamicSymbolCommand;
47class ExportInfo;
48class FunctionStarts;
49class LinkerOptHint;
50class Parser;
51class Section;
52class SegmentCommand;
53class SegmentSplitInfo;
54class Symbol;
55class SymbolCommand;
56class TwoLevelHints;
57struct ParserConfig;
58
59
60namespace details {
61struct dyld_chained_starts_in_segment;
62struct dyld_chained_fixups_header;
63union dyld_chained_ptr_arm64e;
64union dyld_chained_ptr_generic64;
65union dyld_chained_ptr_generic32;
66}
67
73class LIEF_API BinaryParser : public LIEF::Parser {
74
75 friend class MachO::Parser;
76
78 constexpr static size_t MAX_RELOCATIONS = (std::numeric_limits<uint16_t>::max)();
79
81 constexpr static size_t MAX_COMMANDS = (std::numeric_limits<uint16_t>::max)();
82
83 public:
84 static std::unique_ptr<Binary> parse(const std::string& file);
85 static std::unique_ptr<Binary> parse(const std::string& file, const ParserConfig& conf);
86 static std::unique_ptr<Binary> parse(const std::vector<uint8_t>& data,
87 const ParserConfig& conf = ParserConfig::deep());
88
89 static std::unique_ptr<Binary> parse(const std::vector<uint8_t>& data, uint64_t fat_offset,
90 const ParserConfig& conf = ParserConfig::deep());
91
92 static std::unique_ptr<Binary> parse(std::unique_ptr<BinaryStream> stream, uint64_t fat_offset,
93 const ParserConfig& conf);
94
95 BinaryParser& operator=(const BinaryParser& copy) = delete;
96 BinaryParser(const BinaryParser& copy) = delete;
97
98 ~BinaryParser() override;
99
100 private:
101 using exports_list_t = std::vector<std::unique_ptr<ExportInfo>>;
102 BinaryParser();
103
104 ok_error_t init_and_parse();
105
106 template<class MACHO_T>
107 ok_error_t parse();
108
109 template<class MACHO_T>
110 ok_error_t parse_header();
111
112 template<class MACHO_T>
113 ok_error_t parse_load_commands();
114
115 template<class MACHO_T>
116 ok_error_t parse_relocations(Section& section);
117
118 // Dyld info parser
119 // ================
120
121 // Rebase
122 // ------
123 template<class MACHO_T>
124 ok_error_t parse_dyldinfo_rebases();
125
126 // Bindings
127 // --------
128 template<class MACHO_T>
129 ok_error_t parse_dyldinfo_binds();
130
131 template<class MACHO_T>
132 ok_error_t parse_dyldinfo_generic_bind();
133
134 template<class MACHO_T>
135 ok_error_t parse_dyldinfo_weak_bind();
136
137 template<class MACHO_T>
138 ok_error_t parse_dyldinfo_lazy_bind();
139
140 using it_opaque_segments = void*; // To avoid including Binary.hpp. It must contains it_opaque_segments
141
142 template<class MACHO_T>
143 ok_error_t do_bind(DyldBindingInfo::CLASS cls, uint8_t type, uint8_t segment_idx,
144 uint64_t segment_offset, const std::string& symbol_name,
145 int32_t ord, int64_t addend, bool is_weak,
146 bool is_non_weak_definition, it_opaque_segments segments_ptr, uint64_t offset = 0);
147
148
149 template<class MACHO_T>
150 ok_error_t do_rebase(uint8_t type, uint8_t segment_idx, uint64_t segment_offset,
151 it_opaque_segments segments);
152
153 /*
154 * This set of functions are related to the parsing of LC_DYLD_CHAINED_FIXUPS
155 */
156
157 template<class MACHO_T>
158 ok_error_t parse_chained_payload(SpanStream& stream);
159
160 template<class MACHO_T>
161 ok_error_t parse_chained_import(const details::dyld_chained_fixups_header& header,
162 SpanStream& stream, SpanStream& symbol_pool);
163 template<class MACHO_T>
164 ok_error_t parse_chained_fixup(const details::dyld_chained_fixups_header& header,
165 SpanStream& stream);
166
167 template<class MACHO_T>
168 ok_error_t parse_fixup_seg(SpanStream& stream, uint32_t seg_info_offset,
169 uint64_t offset, uint32_t seg_idx);
170
171 template<class MACHO_T>
172 ok_error_t do_fixup(DYLD_CHAINED_FORMAT fmt, int32_t ord, const std::string& symbol_name,
173 int64_t addend, bool is_weak);
174
175 template<class MACHO_T>
176 ok_error_t process_fixup(SegmentCommand& segment, uint64_t chain_offset,
177 const details::dyld_chained_starts_in_segment& seg_info);
178
179 template<class MACHO_T>
180 result<uint64_t> next_chain(uint64_t chain_offset, const details::dyld_chained_starts_in_segment& seg_info);
181
182 template<class MACHO_T>
183 ok_error_t walk_chain(SegmentCommand& segment, uint64_t chain_offset,
184 const details::dyld_chained_starts_in_segment& seg_info);
185
186 ok_error_t do_chained_fixup(SegmentCommand& segment, uint32_t chain_offset,
187 const details::dyld_chained_starts_in_segment& seg_info,
188 const details::dyld_chained_ptr_arm64e& fixup);
189
190 ok_error_t do_chained_fixup(SegmentCommand& segment, uint32_t chain_offset,
191 const details::dyld_chained_starts_in_segment& seg_info,
192 const details::dyld_chained_ptr_generic64& fixup);
193
194 ok_error_t do_chained_fixup(SegmentCommand& segment, uint32_t chain_offset,
195 const details::dyld_chained_starts_in_segment& seg_info,
196 const details::dyld_chained_ptr_generic32 & fixup);
197
198 template<class MACHO_T>
199 ok_error_t post_process(SymbolCommand& cmd);
200
201 template<class MACHO_T>
202 ok_error_t post_process(FunctionStarts& cmd);
203
204 template<class MACHO_T>
205 ok_error_t post_process(DataInCode& cmd);
206
207 template<class MACHO_T>
208 ok_error_t post_process(SegmentSplitInfo& cmd);
209
210 template<class MACHO_T>
211 ok_error_t post_process(DynamicSymbolCommand& cmd);
212
213 template<class MACHO_T>
214 ok_error_t post_process(LinkerOptHint& cmd);
215
216 template<class MACHO_T>
217 ok_error_t post_process(TwoLevelHints& cmd);
218
219 template<class MACHO_T>
220 ok_error_t post_process(CodeSignature& cmd);
221
222 template<class MACHO_T>
223 ok_error_t post_process(CodeSignatureDir& cmd);
224
225 ok_error_t parse_overlay();
226
227 // Exports
228 // -------
229 ok_error_t parse_dyldinfo_export();
230 ok_error_t parse_dyld_exports();
231
232 ok_error_t parse_export_trie(exports_list_t& exports, uint64_t start,
233 uint64_t end, const std::string& prefix,
234 bool* invalid_names);
235
236 void copy_from(ChainedBindingInfo& to, ChainedBindingInfo& from);
237
238 std::unique_ptr<BinaryStream> stream_;
239 std::unique_ptr<Binary> binary_;
240 MACHO_TYPES type_ = MACHO_TYPES::MH_MAGIC_64;
241 bool is64_ = true;
242 ParserConfig config_;
243 std::set<uint64_t> visited_;
244 std::map<std::string, Symbol*> memoized_symbols_;
245 std::map<uint64_t, Symbol*> memoized_symbols_by_address_;
246
247 std::vector<DylibCommand*> binding_libs_;
248 std::set<uint64_t> dyld_reloc_addrs_;
249
250 // Cache of DyldChainedFixups
251 DyldChainedFixups* chained_fixups_ = nullptr;
252};
253
254
255} // namespace MachO
256} // namespace LIEF
257#endif
Class used to parse a single binary (i.e. non-FAT)
Definition BinaryParser.hpp:73
This class represents a symbol binding operation associated with the LC_DYLD_CHAINED_FIXUPS command.
Definition ChainedBindingInfo.hpp:46
Definition CodeSignatureDir.hpp:36
Definition CodeSignature.hpp:37
Interface of the LC_DATA_IN_CODE command This command is used to list slices of code sections that co...
Definition DataInCode.hpp:42
Class that represents the LC_DYLD_CHAINED_FIXUPS command.
Definition DyldChainedFixups.hpp:46
Class that represents the LC_DYSYMTAB command.
Definition DynamicSymbolCommand.hpp:39
Class which represents the LC_FUNCTION_STARTS command.
Definition FunctionStarts.hpp:39
Class which represents the LC_LINKER_OPTIMIZATION_HINT command.
Definition LinkerOptHint.hpp:37
The main interface to parse a Mach-O binary.
Definition MachO/Parser.hpp:42
Class that represents a Mach-O section.
Definition MachO/Section.hpp:44
Class which represents a LoadCommand::TYPE::SEGMENT / LoadCommand::TYPE::SEGMENT_64 command.
Definition SegmentCommand.hpp:48
Class that represents the LoadCommand::TYPE::SEGMENT_SPLIT_INFO command.
Definition SegmentSplitInfo.hpp:35
Class that represents the LC_SYMTAB command.
Definition SymbolCommand.hpp:35
Class which represents the LC_TWOLEVEL_HINTS command.
Definition TwoLevelHints.hpp:39
Main interface to parse an executable regardless of its format.
Definition Abstract/Parser.hpp:30
Definition SpanStream.hpp:26
MACHO_TYPES
Definition MachO/enums.hpp:24
LIEF namespace.
Definition Abstract/Binary.hpp:32
result< ok_t > ok_error_t
Opaque structure that is used by LIEF to avoid writing result<void> f(...). Instead,...
Definition errors.hpp:106
tl::expected< T, lief_errors > result
Wrapper that contains an Object (T) or an error.
Definition errors.hpp:72
This structure is used to tweak the MachO Parser (MachO::Parser)
Definition MachO/ParserConfig.hpp:24