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