summaryrefslogtreecommitdiff
path: root/tools/pe_bliss/pe_imports.h
blob: 681b5b59bdeec1a5d67400fa64e48aae214123a8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
/*************************************************************************/
/* Copyright (c) 2015 dx, http://kaimi.ru                                */
/*                                                                       */
/* Permission is hereby granted, free of charge, to any person           */
/* obtaining a copy of this software and associated documentation        */
/* files (the "Software"), to deal in the Software without               */
/* restriction, including without limitation the rights to use,          */
/* copy, modify, merge, publish, distribute, sublicense, and/or          */
/* sell copies of the Software, and to permit persons to whom the        */
/* Software is furnished to do so, subject to the following conditions:  */
/* The above copyright notice and this permission notice shall be        */
/* included in all copies or substantial portions of the Software.       */
/*                                                                       */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
/*************************************************************************/
#pragma once
#include <vector>
#include <string>
#include "pe_structures.h"
#include "pe_directory.h"
#include "pe_base.h"

namespace pe_bliss
{
//Class representing imported function
class imported_function
{
public:
	//Default constructor
	imported_function();

	//Returns true if imported function has name (and hint)
	bool has_name() const;
	//Returns name of function
	const std::string& get_name() const;
	//Returns hint
	uint16_t get_hint() const;
	//Returns ordinal of function
	uint16_t get_ordinal() const;

	//Returns IAT entry VA (usable if image has both IAT and original IAT and is bound)
	uint64_t get_iat_va() const;

public: //Setters do not change everything inside image, they are used by PE class
	//You also can use them to rebuild image imports
	//Sets name of function
	void set_name(const std::string& name);
	//Sets hint
	void set_hint(uint16_t hint);
	//Sets ordinal
	void set_ordinal(uint16_t ordinal);

	//Sets IAT entry VA (usable if image has both IAT and original IAT and is bound)
	void set_iat_va(uint64_t rva);

private:
	std::string name_; //Function name
	uint16_t hint_; //Hint
	uint16_t ordinal_; //Ordinal
	uint64_t iat_va_;
};

//Class representing imported library information
class import_library
{
public:
	typedef std::vector<imported_function> imported_list;

public:
	//Default constructor
	import_library();

	//Returns name of library
	const std::string& get_name() const;
	//Returns RVA to Import Address Table (IAT)
	uint32_t get_rva_to_iat() const;
	//Returns RVA to Original Import Address Table (Original IAT)
	uint32_t get_rva_to_original_iat() const;
	//Returns timestamp
	uint32_t get_timestamp() const;

	//Returns imported functions list
	const imported_list& get_imported_functions() const;

public: //Setters do not change everything inside image, they are used by PE class
	//You also can use them to rebuild image imports
	//Sets name of library
	void set_name(const std::string& name);
	//Sets RVA to Import Address Table (IAT)
	void set_rva_to_iat(uint32_t rva_to_iat);
	//Sets RVA to Original Import Address Table (Original IAT)
	void set_rva_to_original_iat(uint32_t rva_to_original_iat);
	//Sets timestamp
	void set_timestamp(uint32_t timestamp);

	//Adds imported function
	void add_import(const imported_function& func);
	//Clears imported functions list
	void clear_imports();

private:
	std::string name_; //Library name
	uint32_t rva_to_iat_; //RVA to IAT
	uint32_t rva_to_original_iat_; //RVA to original IAT
	uint32_t timestamp_; //DLL TimeStamp

	imported_list imports_;
};

//Simple import directory rebuilder
//Class representing import rebuilder advanced settings
class import_rebuilder_settings
{
public:
	//Default constructor
	//Default constructor
	//If set_to_pe_headers = true, IMAGE_DIRECTORY_ENTRY_IMPORT entry will be reset
	//to new value after import rebuilding
	//If auto_zero_directory_entry_iat = true, IMAGE_DIRECTORY_ENTRY_IAT will be set to zero
	//IMAGE_DIRECTORY_ENTRY_IAT is used by loader to temporarily make section, where IMAGE_DIRECTORY_ENTRY_IAT RVA points, writeable
	//to be able to modify IAT thunks
	explicit import_rebuilder_settings(bool set_to_pe_headers = true, bool auto_zero_directory_entry_iat = false);

	//Returns offset from section start where import directory data will be placed
	uint32_t get_offset_from_section_start() const;
	//Returns true if Original import address table (IAT) will be rebuilt
	bool build_original_iat() const;

	//Returns true if Original import address and import address tables will not be rebuilt,
	//works only if import descriptor IAT (and orig.IAT, if present) RVAs are not zero
	bool save_iat_and_original_iat_rvas() const;
	//Returns true if Original import address and import address tables contents will be rewritten
	//works only if import descriptor IAT (and orig.IAT, if present) RVAs are not zero
	//and save_iat_and_original_iat_rvas is true
	bool rewrite_iat_and_original_iat_contents() const;

	//Returns true if original missing IATs will be rebuilt
	//(only if IATs are saved)
	bool fill_missing_original_iats() const;
	//Returns true if PE headers should be updated automatically after rebuilding of imports
	bool auto_set_to_pe_headers() const;
	//Returns true if IMAGE_DIRECTORY_ENTRY_IAT must be zeroed, works only if auto_set_to_pe_headers = true
	bool zero_directory_entry_iat() const;

	//Returns true if the last section should be stripped automatically, if imports are inside it
	bool auto_strip_last_section_enabled() const;

public: //Setters
	//Sets offset from section start where import directory data will be placed
	void set_offset_from_section_start(uint32_t offset);
	//Sets if Original import address table (IAT) will be rebuilt
	void build_original_iat(bool enable);
	//Sets if Original import address and import address tables will not be rebuilt,
	//works only if import descriptor IAT (and orig.IAT, if present) RVAs are not zero
	//enable_rewrite_iat_and_original_iat_contents sets if Original import address and import address tables contents will be rewritten
	//works only if import descriptor IAT (and orig.IAT, if present) RVAs are not zero
	//and save_iat_and_original_iat_rvas is true
	void save_iat_and_original_iat_rvas(bool enable, bool enable_rewrite_iat_and_original_iat_contents = false);
	//Sets if original missing IATs will be rebuilt
	//(only if IATs are saved)
	void fill_missing_original_iats(bool enable);
	//Sets if PE headers should be updated automatically after rebuilding of imports
	void auto_set_to_pe_headers(bool enable);
	//Sets if IMAGE_DIRECTORY_ENTRY_IAT must be zeroed, works only if auto_set_to_pe_headers = true
	void zero_directory_entry_iat(bool enable);

	//Sets if the last section should be stripped automatically, if imports are inside it, default true
	void enable_auto_strip_last_section(bool enable);

private:
	uint32_t offset_from_section_start_;
	bool build_original_iat_;
	bool save_iat_and_original_iat_rvas_;
	bool fill_missing_original_iats_;
	bool set_to_pe_headers_;
	bool zero_directory_entry_iat_;
	bool rewrite_iat_and_original_iat_contents_;
	bool auto_strip_last_section_;
};

typedef std::vector<import_library> imported_functions_list;


//Returns imported functions list with related libraries info
const imported_functions_list get_imported_functions(const pe_base& pe);

template<typename PEClassType>
const imported_functions_list get_imported_functions_base(const pe_base& pe);


//You can get all image imports with get_imported_functions() function
//You can use returned value to, for example, add new imported library with some functions
//to the end of list of imported libraries
//To keep PE file working, rebuild its imports with save_iat_and_original_iat_rvas = true (default)
//Don't add new imported functions to existing imported library entries, because this can cause
//rewriting of some used memory (or other IAT/orig.IAT fields) by system loader
//The safest way is just adding import libraries with functions to the end of imported_functions_list array
const image_directory rebuild_imports(pe_base& pe, const imported_functions_list& imports, section& import_section, const import_rebuilder_settings& import_settings = import_rebuilder_settings());

template<typename PEClassType>
const image_directory rebuild_imports_base(pe_base& pe, const imported_functions_list& imports, section& import_section, const import_rebuilder_settings& import_settings = import_rebuilder_settings());
}