-
Notifications
You must be signed in to change notification settings - Fork 26
/
Copy pathPEFileResources.h
212 lines (161 loc) · 6.82 KB
/
PEFileResources.h
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
209
210
211
212
// pe-file: library for reading and manipulating pe-files
// Copyright (C) 2012 Jeffrey Bush [email protected]
//
// This library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// Implements the classes and functions for dealing with resources in PE files or RES files
#ifndef PE_FILE_RESOURCES_H
#define PE_FILE_RESOURCES_H
#ifdef EXPOSE_DIRECT_RESOURCES
#define _DECLARE_ALL_PE_FILE_RESOURCES_
#endif
#ifndef _DECLARE_ALL_PE_FILE_RESOURCES_
class Rsrc;
#else
#include "PEDataTypes.h"
#include <map>
#include <vector>
namespace PE {
// A comparator for resource names
struct ResCmp { bool operator()(const_resid a, const_resid b) const; };
// A resource (directory) entry
class Resource {
public:
virtual const_resid getId() const = 0;
private:
virtual size_t getDataSize() const = 0;
virtual size_t getHeaderSize() const = 0;
virtual size_t getThisHeaderSize() const = 0;
};
// The final resource directory, contains the data for the resource
class ResourceLang : Resource {
friend class ResourceName;
uint16_t lang;
void* data;
size_t length;
ResourceLang(uint16_t lang, const_bytes data, size_t size, uint32_t start, uint32_t startVA, Image::ResourceDirectoryEntry entry);
ResourceLang(uint16_t lang, const void* data, size_t size);
public:
~ResourceLang();
const_resid getId() const;
bool isLoaded() const;
void* get(size_t* size) const; // must be freed
bool set(const void* data, size_t size);
private:
virtual size_t getDataSize() const;
virtual size_t getHeaderSize() const;
virtual size_t getThisHeaderSize() const;
void writeData(bytes data, size_t& posDataEntry, size_t& posData, size_t startVA) const;
virtual size_t getRESSize(size_t addl_hdr_size) const;
void writeRESData(bytes data, size_t& pos, const_resid type, const_resid name) const;
};
// The named resource directory, the second level
class ResourceName : Resource {
friend class ResourceType;
resid name;
typedef std::map<uint16_t, ResourceLang*> LangMap;
LangMap langs;
ResourceName(const_resid name, const_bytes data, size_t size, uint32_t start, uint32_t startVA, Image::ResourceDirectoryEntry entry);
ResourceName(const_resid name, uint16_t lang, const void* data, size_t size);
public:
~ResourceName();
const_resid getId() const;
bool exists(uint16_t lang) const;
bool exists(uint16_t* lang) const;
void* get(uint16_t lang, size_t* size) const;
void* get(uint16_t* lang, size_t* size) const;
bool remove(uint16_t lang);
bool add(uint16_t lang, const void* data, size_t size, Overwrite overwrite = ALWAYS);
bool isEmpty() const;
ResourceLang* operator[](uint16_t lang);
const ResourceLang* operator[](uint16_t lang) const;
std::vector<uint16_t> getLangs() const;
private:
bool cleanup();
virtual size_t getDataSize() const;
virtual size_t getHeaderSize() const;
virtual size_t getThisHeaderSize() const;
void writeLangDirs(bytes data, size_t& pos, size_t& posDir) const;
void writeData(bytes data, size_t& posDataEntry, size_t& posData, uint32_t startVA) const;
virtual size_t getRESSize(size_t addl_hdr_size) const;
void writeRESData(bytes data, size_t& pos, const_resid type) const;
};
// The typed resource directory, the first level
class ResourceType : Resource {
friend class Rsrc;
resid type;
typedef std::map<resid, ResourceName*, ResCmp> NameMap;
NameMap names;
ResourceType(const_resid type, const_bytes data, size_t size, uint32_t start, uint32_t startVA, Image::ResourceDirectoryEntry entry);
ResourceType(const_resid type, const_resid name, uint16_t lang, const void* data, size_t size);
public:
~ResourceType();
const_resid getId() const;
bool exists(const_resid name, uint16_t lang) const;
bool exists(const_resid name, uint16_t* lang) const;
void* get (const_resid name, uint16_t lang, size_t* size) const;
void* get (const_resid name, uint16_t* lang, size_t* size) const;
bool remove(const_resid name, uint16_t lang);
bool add(const_resid name, uint16_t lang, const void* data, size_t size, Overwrite overwrite = ALWAYS);
bool isEmpty() const;
ResourceName* operator[](const_resid name);
const ResourceName* operator[](const_resid name) const;
std::vector<const_resid> getNames() const;
std::vector<uint16_t> getLangs(const_resid name) const;
private:
bool cleanup();
virtual size_t getDataSize() const;
virtual size_t getHeaderSize() const;
virtual size_t getThisHeaderSize() const;
void writeNameDirs(bytes data, size_t& pos, size_t& posDir, size_t& posData) const;
void writeLangDirs(bytes data, size_t& pos, size_t& posDir) const;
void writeData(bytes data, size_t& posDataEntry, size_t& posData, uint32_t startVA) const;
virtual size_t getRESSize() const;
void writeRESData(bytes data, size_t& pos) const;
};
class Rsrc : Resource {
typedef std::map<resid, ResourceType*, ResCmp> TypeMap;
TypeMap types;
Rsrc(const_bytes data, size_t size, Image::SectionHeader *section); // creates from ".rsrc" section in PE file
Rsrc(const_bytes data, size_t size); // creates from RES file
Rsrc(); // creates empty
public:
~Rsrc();
static Rsrc* createFromRSRCSection(const_bytes data, size_t size, Image::SectionHeader *section);
static Rsrc* createFromRESFile(const_bytes data, size_t size);
static Rsrc* createEmpty();
const_resid getId() const;
bool exists(const_resid type, const_resid name, uint16_t lang) const;
bool exists(const_resid type, const_resid name, uint16_t* lang) const;
void* get (const_resid type, const_resid name, uint16_t lang, size_t* size) const;
void* get (const_resid type, const_resid name, uint16_t* lang, size_t* size) const;
bool remove(const_resid type, const_resid name, uint16_t lang);
bool add(const_resid type, const_resid name, uint16_t lang, const void* data, size_t size, Overwrite overwrite = ALWAYS);
bool isEmpty() const;
ResourceType* operator[](const_resid type);
const ResourceType* operator[](const_resid type) const;
std::vector<const_resid> getTypes() const;
std::vector<const_resid> getNames(const_resid type) const;
std::vector<uint16_t> getLangs(const_resid type, const_resid name) const;
bool cleanup();
void* compile(size_t* size, uint32_t startVA); // calls cleanup
void* compileRES(size_t* size); // calls cleanup
private:
virtual size_t getDataSize() const;
virtual size_t getHeaderSize() const;
virtual size_t getThisHeaderSize() const;
virtual size_t getRESSize() const;
};
}
#endif
#endif