LIEF: Library to Instrument Executable Formats Version 0.17.6
Loading...
Searching...
No Matches
PE/Parser.hpp
Go to the documentation of this file.
1/* Copyright 2017 - 2025 R. Thomas
2 * Copyright 2017 - 2025 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>
20#include <vector>
21#include <map>
22
23#include "LIEF/visibility.h"
24#include "LIEF/utils.hpp"
25#include "LIEF/errors.hpp"
26
28#include "LIEF/PE/enums.hpp"
30#include "LIEF/COFF/String.hpp"
31
32namespace LIEF {
33class BinaryStream;
34class SpanStream;
35
36namespace PE {
37class Debug;
38class ResourceNode;
39class Binary;
40class DelayImport;
41class Section;
42class ExceptionInfo;
44class RelocationEntry;
45
46namespace details {
47struct pe_debug;
48}
49
53 public:
54
56 static constexpr size_t MAX_DATA_SIZE = 3_GB;
57
58 static constexpr size_t MAX_TLS_CALLBACKS = 3000;
59
60 // Bounds the import thunk loop to prevent hangs on malformed IATs
61 static constexpr size_t MAX_IMPORT_ENTRIES = 0x10000;
62
63 // Bounds peek_string_at to prevent multi-megabyte reads on invalid RVAs
64 // According to https://stackoverflow.com/a/23340781
65 static constexpr size_t MAX_IMPORT_NAME_SIZE = 0x1000;
66
67 // According to https://stackoverflow.com/a/265782/87207
68 static constexpr size_t MAX_DLL_NAME_SIZE = 255;
69
71 static constexpr size_t MAX_PADDING_SIZE = 1_GB;
72
73 public:
79 static bool is_valid_import_name(const std::string& name);
80
86 static bool is_valid_dll_name(const std::string& name);
87
88 public:
90 static std::unique_ptr<Binary> parse(const std::string& filename,
92
94 static std::unique_ptr<Binary> parse(std::vector<uint8_t> data,
96
97 static std::unique_ptr<Binary> parse(const uint8_t* buffer, size_t size,
99
101 static std::unique_ptr<Binary> parse(std::unique_ptr<BinaryStream> stream,
103
104 Parser& operator=(const Parser& copy) = delete;
105 Parser(const Parser& copy) = delete;
106
107 COFF::String* find_coff_string(uint32_t offset) const;
108
109 ExceptionInfo* find_exception_info(uint32_t rva) const {
110 auto it = memoize_exception_info_.find(rva);
111 return it == memoize_exception_info_.end() ? nullptr : it->second;
112 }
113
114 const Binary& bin() const {
115 return *binary_;
116 }
117
119 return *binary_;
120 }
121
123 return *stream_;
124 }
125
126 const ParserConfig& config() const {
127 return config_;
128 }
129
132
133 void add_non_resolved(ExceptionInfo& info, uint32_t target) {
134 unresolved_chains_.emplace_back(&info, target);
135 }
136
137 std::unique_ptr<SpanStream> stream_from_rva(uint32_t rva, size_t size = 0);
138
139 void record_relocation(uint32_t rva, span<const uint8_t> data);
140 ok_error_t record_delta_relocation(uint32_t rva, int64_t delta, size_t size);
141
142 private:
143 struct relocation_t {
144 uint64_t size = 0;
145 uint64_t value = 0;
146 };
147 Parser(const std::string& file);
148 Parser(std::vector<uint8_t> data);
149 Parser(std::unique_ptr<BinaryStream> stream);
150
151 ~Parser() override;
152 Parser();
153
154 ok_error_t init(const ParserConfig& config);
155
156 template<typename PE_T>
157 ok_error_t parse();
158
159 ok_error_t parse_exports();
160 ok_error_t parse_sections();
161
162 template<typename PE_T>
163 ok_error_t parse_headers();
164
165 ok_error_t parse_configuration();
166
167 template<typename PE_T>
168 ok_error_t parse_data_directories();
169
170 template<typename PE_T>
171 ok_error_t parse_import_table();
172
173 template<typename PE_T>
174 ok_error_t parse_delay_imports();
175
176 template<typename PE_T>
177 ok_error_t parse_delay_names_table(DelayImport& import, uint32_t names_offset,
178 uint32_t iat_offset);
179
180 ok_error_t parse_export_table();
181 ok_error_t parse_debug();
182
183 ok_error_t parse_exceptions();
184
185 std::unique_ptr<Debug> parse_code_view(const details::pe_debug& debug_info,
186 Section* sec, span<uint8_t> payload);
187 std::unique_ptr<Debug> parse_pogo(const details::pe_debug& debug_info,
188 Section* sec, span<uint8_t> payload);
189 std::unique_ptr<Debug> parse_repro(const details::pe_debug& debug_info,
190 Section* sec, span<uint8_t> payload);
191
192 template<typename PE_T>
193 ok_error_t parse_tls();
194
195 template<typename PE_T>
196 ok_error_t parse_load_config();
197
198 template<typename PE_T>
199 ok_error_t process_load_config(LoadConfiguration& config);
200
201 template<typename PE_T>
202 ok_error_t parse_nested_relocated();
203
204 ok_error_t parse_relocations();
205 ok_error_t parse_resources();
206 ok_error_t parse_string_table();
207 ok_error_t parse_symbols();
208 ok_error_t parse_signature();
209 ok_error_t parse_overlay();
210 ok_error_t parse_dos_stub();
211 ok_error_t parse_rich_header();
212 ok_error_t parse_chpe_exceptions();
213
215 std::unique_ptr<Binary> binary_;
216 std::unique_ptr<BinaryStream> stream_;
217 std::map<uint32_t, size_t> memoize_coff_str_;
218 std::map<uint32_t, ExceptionInfo*> memoize_exception_info_;
219 std::map<uint32_t, relocation_t> dyn_hdr_relocs_;
220 std::vector<std::pair<ExceptionInfo*, uint32_t>> unresolved_chains_;
221 ParserConfig config_;
222};
223
224
225}
226}
227#endif
Class that is used to a read stream of data from different sources.
Definition BinaryStream.hpp:33
This class represents a string located in the COFF string table.
Definition String.hpp:33
Class which represents a PE binary This is the main interface to manage and modify a PE executable.
Definition PE/Binary.hpp:57
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:37
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:46
Main interface to parse PE binaries. In particular the static functions: Parser::parse should be used...
Definition PE/Parser.hpp:52
static constexpr size_t MAX_IMPORT_ENTRIES
Definition PE/Parser.hpp:61
static constexpr size_t MAX_DLL_NAME_SIZE
Definition PE/Parser.hpp:68
static bool is_valid_import_name(const std::string &name)
Check if the given name is a valid import.
static constexpr size_t MAX_IMPORT_NAME_SIZE
Definition PE/Parser.hpp:65
static bool is_valid_dll_name(const std::string &name)
Check if the given name is a valid DLL name.
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:118
const Binary & bin() const
Definition PE/Parser.hpp:114
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:109
static std::unique_ptr< Binary > parse(const std::string &filename, const ParserConfig &conf=ParserConfig::default_conf())
Parse a PE binary from the given filename.
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:122
void record_relocation(uint32_t rva, span< const uint8_t > data)
static constexpr size_t MAX_DATA_SIZE
Maximum size of the data read.
Definition PE/Parser.hpp:56
const ParserConfig & config() const
Definition PE/Parser.hpp:126
void add_non_resolved(ExceptionInfo &info, uint32_t target)
Definition PE/Parser.hpp:133
static constexpr size_t MAX_PADDING_SIZE
Max size of the padding section.
Definition PE/Parser.hpp:71
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:58
Class which represents an entry of the PE relocation table.
Definition RelocationEntry.hpp:36
Class which represents a Node in the resource tree.
Definition ResourceNode.hpp:46
Class which represents a PE section.
Definition PE/Section.hpp:46
Main interface to parse an executable regardless of its format.
Definition Abstract/Parser.hpp:30
Definition SpanStream.hpp:32
Opaque structure that is used by LIEF to avoid writing result<void> f(...). Instead,...
Definition errors.hpp:112
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:40
tcb::span< ElementType, Extent > span
Definition span.hpp:22
This structure is used to tweak the PE Parser (PE::Parser).
Definition PE/ParserConfig.hpp:26
static const ParserConfig & default_conf()
Definition PE/ParserConfig.hpp:27
#define LIEF_API
Definition visibility.h:41