LIEF: Library to Instrument Executable Formats Version 2.0.0
Loading...
Searching...
No Matches
PE/Parser.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_PE_PARSER_H
17#define LIEF_PE_PARSER_H
18
19#include <string_view>
20#include <map>
21#include <vector>
22
23#include "LIEF/errors.hpp"
24#include "LIEF/path.hpp"
25#include "LIEF/utils.hpp"
26#include "LIEF/visibility.h"
27
29#include "LIEF/COFF/String.hpp"
31#include "LIEF/PE/enums.hpp"
32
33namespace LIEF {
34class BinaryStream;
35class SpanStream;
36
37namespace PE {
38class Debug;
39class ResourceNode;
40class Binary;
41class DelayImport;
42class Section;
43class ExceptionInfo;
45class RelocationEntry;
46
47namespace details {
48struct pe_debug;
49struct pe_section;
50}
51
55 public:
57 static constexpr size_t MAX_DATA_SIZE = 3_GB;
58
59 static constexpr size_t MAX_TLS_CALLBACKS = 3000;
60
61 // Bounds the import thunk loop to prevent hangs on malformed IATs
62 static constexpr size_t MAX_IMPORT_ENTRIES = 0x10000;
63
64 // Bounds peek_string_at to prevent multi-megabyte reads on invalid RVAs
65 // According to https://stackoverflow.com/a/23340781
66 static constexpr size_t MAX_IMPORT_NAME_SIZE = 0x1000;
67
68 // According to https://stackoverflow.com/a/265782/87207
69 static constexpr size_t MAX_DLL_NAME_SIZE = 255;
70
72 static constexpr size_t MAX_PADDING_SIZE = 1_GB;
73
74 public:
81 static bool is_valid_import_name(std::string_view name);
82
88 static bool is_valid_dll_name(std::string_view name);
89
90 public:
92 static std::unique_ptr<Binary>
93 parse(std::string_view filename,
95
98 template<class PathT, enable_if_path_t<PathT> = 0>
99 static std::unique_ptr<Binary>
100 parse(const PathT& filename,
102 return parse(filename.string(), conf);
103 }
104
106 static std::unique_ptr<Binary>
107 parse(std::vector<uint8_t> data,
109
110 static std::unique_ptr<Binary>
111 parse(const uint8_t* buffer, size_t size,
113
115 static std::unique_ptr<Binary>
116 parse(std::unique_ptr<BinaryStream> stream,
118
120 static std::unique_ptr<Binary>
121 parse_from_memory(uintptr_t address,
123
125 static std::unique_ptr<Binary>
126 parse_from_memory(uintptr_t address, size_t size,
128
138 static std::unique_ptr<Binary>
139 parse_from_dump(std::string_view filepath, uint64_t addr,
141
144 template<class PathT, enable_if_path_t<PathT> = 0>
145 static std::unique_ptr<Binary>
146 parse_from_dump(const PathT& filepath, uint64_t addr,
148 return parse_from_dump(filepath.string(), addr, config);
149 }
150
153 static std::unique_ptr<Binary>
156
159 static std::unique_ptr<Binary>
160 parse_from_dump(std::unique_ptr<BinaryStream> stream, uint64_t addr,
162
163 Parser& operator=(const Parser& copy) = delete;
164 Parser(const Parser& copy) = delete;
165
166 COFF::String* find_coff_string(uint32_t offset) const;
167
168 ExceptionInfo* find_exception_info(uint32_t rva) const {
169 auto it = memoize_exception_info_.find(rva);
170 return it == memoize_exception_info_.end() ? nullptr : it->second;
171 }
172
173 const Binary& bin() const {
174 return *binary_;
175 }
176
178 return *binary_;
179 }
180
182 return *stream_;
183 }
184
185 const ParserConfig& config() const {
186 return config_;
187 }
188
191
192 void add_non_resolved(ExceptionInfo& info, uint32_t target) {
193 unresolved_chains_.emplace_back(&info, target);
194 }
195
196 std::unique_ptr<SpanStream> stream_from_rva(uint32_t rva, size_t size = 0);
197
198 void record_relocation(uint32_t rva, span<const uint8_t> data);
199 ok_error_t record_delta_relocation(uint32_t rva, int64_t delta, size_t size);
200
201 private:
202 struct relocation_t {
203 uint64_t size = 0;
204 uint64_t value = 0;
205 };
206 Parser(std::string_view file);
207 Parser(std::vector<uint8_t> data);
208 Parser(std::unique_ptr<BinaryStream> stream);
209
210 ~Parser();
211 Parser();
212
213 ok_error_t init(const ParserConfig& config);
214
215 template<typename PE_T>
216 ok_error_t parse();
217
218 ok_error_t parse_exports();
219 ok_error_t parse_sections();
220
221 ok_error_t read_section_content(const details::pe_section& raw_sec,
222 uint32_t index, Section& section);
223
224 template<typename PE_T>
225 ok_error_t parse_headers();
226
227 ok_error_t parse_configuration();
228
229 template<typename PE_T>
230 ok_error_t parse_data_directories();
231
232 template<typename PE_T>
233 ok_error_t parse_import_table();
234
235 template<typename PE_T>
236 ok_error_t parse_delay_imports();
237
238 template<typename PE_T>
239 ok_error_t parse_delay_names_table(DelayImport& import, uint32_t names_offset,
240 uint32_t iat_offset);
241
242 ok_error_t parse_export_table();
243 ok_error_t parse_debug();
244
245 ok_error_t parse_exceptions();
246
247 std::unique_ptr<Debug> parse_code_view(const details::pe_debug& debug_info,
248 Section* sec, span<uint8_t> payload);
249 std::unique_ptr<Debug> parse_pogo(const details::pe_debug& debug_info,
250 Section* sec, span<uint8_t> payload);
251 std::unique_ptr<Debug> parse_repro(const details::pe_debug& debug_info,
252 Section* sec, span<uint8_t> payload);
253
254 template<typename PE_T>
255 ok_error_t parse_tls();
256
257 template<typename PE_T>
258 ok_error_t parse_load_config();
259
260 template<typename PE_T>
261 ok_error_t process_load_config(LoadConfiguration& config);
262
263 template<typename PE_T>
264 ok_error_t parse_nested_relocated();
265
266 ok_error_t parse_relocations();
267 ok_error_t parse_resources();
268 ok_error_t parse_string_table();
269 ok_error_t parse_symbols();
270 ok_error_t parse_signature();
271 ok_error_t parse_overlay();
272 ok_error_t parse_dos_stub();
273 ok_error_t parse_rich_header();
274 ok_error_t parse_chpe_exceptions();
275
276 template<typename PE_T>
277 ok_error_t undo_relocations();
278
279 template<typename PE_T>
280 ok_error_t fix_iat();
281
282 template<typename PE_T>
283 ok_error_t fix_tls();
284
285 template<typename PE_T>
286 ok_error_t fix_load_config();
287
289 std::unique_ptr<Binary> binary_;
290 std::unique_ptr<BinaryStream> stream_;
291 std::map<uint32_t, size_t> memoize_coff_str_;
292 std::map<uint32_t, ExceptionInfo*> memoize_exception_info_;
293 std::map<uint32_t, relocation_t> dyn_hdr_relocs_;
294 std::vector<std::pair<ExceptionInfo*, uint32_t>> unresolved_chains_;
295 ParserConfig config_;
296};
297
298
299}
300}
301#endif
Class that is used to a read stream of data from different sources.
Definition BinaryStream.hpp:35
This class represents a string located in the COFF string table.
Definition String.hpp:35
Class which represents a PE binary This is the main interface to manage and modify a PE executable.
Definition PE/Binary.hpp:58
This class represents a generic entry in the debug data directory. For known types,...
Definition debug/Debug.hpp:40
Class that represents a PE delayed import.
Definition DelayImport.hpp:38
This class is the base class for any exception or runtime function entry.
Definition ExceptionInfo.hpp:33
This class represents the load configuration data associated with the IMAGE_LOAD_CONFIG_DIRECTORY.
Definition LoadConfiguration.hpp:49
Main interface to parse PE binaries. In particular, the static Parser::parse functions should be used...
Definition PE/Parser.hpp:54
static std::unique_ptr< Binary > parse_from_dump(BinaryStream &stream, uint64_t addr, const ParserConfig &config=ParserConfig::default_conf())
Same as parse_from_dump(std::string_view, uint64_t, const ParserConfig&) but the dump is wrapped in t...
static constexpr size_t MAX_IMPORT_ENTRIES
Definition PE/Parser.hpp:62
static constexpr size_t MAX_DLL_NAME_SIZE
Definition PE/Parser.hpp:69
static constexpr size_t MAX_IMPORT_NAME_SIZE
Definition PE/Parser.hpp:66
static std::unique_ptr< Binary > parse_from_dump(std::string_view filepath, uint64_t addr, const ParserConfig &config=ParserConfig::default_conf())
Parse a PE binary from a memory dump located on disk.
static std::unique_ptr< Binary > parse_from_memory(uintptr_t address, const ParserConfig &config=ParserConfig::default_conf())
Parse the PE binary at the given memory address.
void memoize(ExceptionInfo &info)
static std::unique_ptr< Binary > parse(std::unique_ptr< BinaryStream > stream, const ParserConfig &conf=ParserConfig::default_conf())
Parse a PE binary from the given BinaryStream.
Binary & bin()
Definition PE/Parser.hpp:177
const Binary & bin() const
Definition PE/Parser.hpp:173
static bool is_valid_import_name(std::string_view name)
Check if the given name is a valid import.
static std::unique_ptr< Binary > parse(const uint8_t *buffer, size_t size, const ParserConfig &conf=ParserConfig::default_conf())
COFF::String * find_coff_string(uint32_t offset) const
ExceptionInfo * find_exception_info(uint32_t rva) const
Definition PE/Parser.hpp:168
std::unique_ptr< SpanStream > stream_from_rva(uint32_t rva, size_t size=0)
Parser(const Parser &copy)=delete
void memoize(COFF::String str)
BinaryStream & stream()
Definition PE/Parser.hpp:181
void record_relocation(uint32_t rva, span< const uint8_t > data)
static bool is_valid_dll_name(std::string_view name)
Check if the given name is a valid DLL name.
static constexpr size_t MAX_DATA_SIZE
Maximum size of the data read.
Definition PE/Parser.hpp:57
static std::unique_ptr< Binary > parse(std::string_view filename, const ParserConfig &conf=ParserConfig::default_conf())
Parse a PE binary from the given filename.
static std::unique_ptr< Binary > parse_from_dump(std::unique_ptr< BinaryStream > stream, uint64_t addr, const ParserConfig &config=ParserConfig::default_conf())
Same as parse_from_dump(std::string_view, uint64_t, const ParserConfig&) but the dump is wrapped in t...
const ParserConfig & config() const
Definition PE/Parser.hpp:185
static std::unique_ptr< Binary > parse(const PathT &filename, const ParserConfig &conf=ParserConfig::default_conf())
Same as parse(std::string_view, const ParserConfig&) but the file is given as a std::filesystem::path...
Definition PE/Parser.hpp:100
static std::unique_ptr< Binary > parse_from_memory(uintptr_t address, size_t size, const ParserConfig &config=ParserConfig::default_conf())
Parse the PE binary at the given memory address and with the given size.
void add_non_resolved(ExceptionInfo &info, uint32_t target)
Definition PE/Parser.hpp:192
static constexpr size_t MAX_PADDING_SIZE
Max size of the padding section.
Definition PE/Parser.hpp:72
static std::unique_ptr< Binary > parse_from_dump(const PathT &filepath, uint64_t addr, const ParserConfig &config=ParserConfig::default_conf())
Same as parse_from_dump(std::string_view, uint64_t, const ParserConfig&) but the dump file is given a...
Definition PE/Parser.hpp:146
Parser & operator=(const Parser &copy)=delete
static std::unique_ptr< Binary > parse(std::vector< uint8_t > data, const ParserConfig &conf=ParserConfig::default_conf())
Parse a PE binary from a data buffer.
ok_error_t record_delta_relocation(uint32_t rva, int64_t delta, size_t size)
static constexpr size_t MAX_TLS_CALLBACKS
Definition PE/Parser.hpp:59
Class which represents an entry of the PE relocation table.
Definition RelocationEntry.hpp:37
Class which represents a Node in the resource tree.
Definition ResourceNode.hpp:46
Class which represents a PE section.
Definition PE/Section.hpp:47
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
Definition DataDirectory.hpp:37
Namespace related to the LIEF's PE module.
Definition Abstract/Header.hpp:32
PE_TYPE
Definition PE/enums.hpp:22
@ PE32_PLUS
64 bits
Definition PE/enums.hpp:24
LIEF namespace.
Definition Abstract/Binary.hpp:41
tcb::span< ElementType, Extent > span
Definition span.hpp:22
This structure is used to configure the behavior of the PE Parser (PE::Parser).
Definition PE/ParserConfig.hpp:28
static const ParserConfig & default_conf()
Returns the default configuration for the PE Parser.
Definition PE/ParserConfig.hpp:30
#define LIEF_API
Definition visibility.h:45