BearParser
Portable Executable parsing library (from PE-bear)
Toggle main menu visibility
Loading...
Searching...
No Matches
parser
pe
ResourceDirWrapper.cpp
Go to the documentation of this file.
1
#include "
pe/ResourceDirWrapper.h
"
2
#include "
pe/PEFile.h
"
3
4
#define MAX_ENTRIES (-1)
5
#define MAX_DEPTH 5
6
7
/*
8
typedef struct _IMAGE_RESOURCE_DIRECTORY {
9
DWORD Characteristics;
10
DWORD TimeDateStamp;
11
WORD MajorVersion;
12
WORD MinorVersion;
13
WORD NumberOfNamedEntries;
14
WORD NumberOfIdEntries;
15
// IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[];
16
} IMAGE_RESOURCE_DIRECTORY, *PIMAGE_RESOURCE_DIRECTORY;
17
18
19
// Each directory contains the 32-bit Name of the entry and an offset,
20
// relative to the beginning of the resource directory of the data associated
21
// with this directory entry. If the name of the entry is an actual text
22
// string instead of an integer Id, then the high order bit of the name field
23
// is set to one and the low order 31-bits are an offset, relative to the
24
// beginning of the resource directory of the string, which is of type
25
// IMAGE_RESOURCE_DIRECTORY_STRING. Otherwise the high bit is clear and the
26
// low-order 16-bits are the integer Id that identify this resource directory
27
// entry. If the directory entry is yet another resource directory (i.e. a
28
// subdirectory), then the high order bit of the offset field will be
29
// set to indicate this. Otherwise the high bit is clear and the offset
30
// field points to a resource data entry.
31
32
#define RESOURCE_NAME_IS_STRING 0x80000000
33
#define RESOURCE_DATA_IS_DIRECTORY 0x80000000
34
35
36
typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY {
37
union {
38
struct {
39
DWORD NameOffset:31;
40
DWORD NameIsString:1;
41
} name;
42
DWORD Name;
43
WORD Id;
44
};
45
union {
46
DWORD OffsetToData;
47
struct {
48
DWORD OffsetToDirectory:31;
49
DWORD DataIsDirectory:1;
50
} dir;
51
};
52
} IMAGE_RESOURCE_DIRECTORY_ENTRY, *PIMAGE_RESOURCE_DIRECTORY_ENTRY;
53
54
*/
55
//-------------
56
57
IMAGE_RESOURCE_DIRECTORY*
ResourceDirWrapper::mainResourceDir
()
58
{
59
offset_t
rva =
getDirEntryAddress
();
60
61
BYTE *ptr =
m_Exe
->getContentAt(rva,
Executable::RVA
,
sizeof
(IMAGE_RESOURCE_DIRECTORY));
62
return
(IMAGE_RESOURCE_DIRECTORY*) ptr;
63
}
64
65
IMAGE_RESOURCE_DIRECTORY* ResourceDirWrapper::resourceDir()
66
{
67
if
(this->rawOff == 0)
return
mainResourceDir
();
68
69
BYTE *ptr =
m_Exe
->
getContentAt
(this->rawOff,
Executable::RAW
,
sizeof
(IMAGE_RESOURCE_DIRECTORY));
70
return
(IMAGE_RESOURCE_DIRECTORY*) ptr;
71
}
72
73
bool
ResourceDirWrapper::wrap
()
74
{
75
clear
();
76
if
(this->topEntryID ==
TOP_ENTRY_ROOT
&& this->album != NULL) {
77
this->album->clear();
78
}
79
IMAGE_RESOURCE_DIRECTORY* dir = resourceDir();
80
if
(dir == NULL)
return
false
;
81
size_t
namesNum = dir->NumberOfNamedEntries;
82
size_t
idsNum = dir->NumberOfIdEntries;
83
84
size_t
totalEntries = namesNum + idsNum;
85
for
(
size_t
i = 0; i < totalEntries && i <
MAX_ENTRIES
; i++ ) {
86
87
long
topDirId = (this->topEntryID !=
TOP_ENTRY_ROOT
) ? this->topEntryID : long(i) ;
88
89
//ResourceEntryWrapper(PEFile *pe, ResourceDirWrapper *parentDir, size_t entryNumber, long topEntryId, ResourcesAlbum *resAlbum)
90
ResourceEntryWrapper
* entry =
new
ResourceEntryWrapper
(this->
m_PE
,
this
, i, topDirId, this->album);
91
92
if
(entry->
getPtr
() == NULL) {
93
delete
entry;
94
break
;
95
}
96
if
(this->topEntryID ==
TOP_ENTRY_ROOT
&& this->album != NULL) {
97
pe::resource_type typeId =
static_cast<
pe::resource_type
>
(entry->
getID
());
98
this->album->mapIdToLeafType(i, typeId);
99
}
100
//this->parsedSize += val;
101
this->
entries
.push_back(entry);
102
}
103
//printf("Entries: %d\n", getEntriesCount());
104
return
true
;
105
}
106
107
108
bufsize_t
ResourceDirWrapper::getSize
()
109
{
110
if
(
getPtr
() == NULL)
return
0;
111
bufsize_t
size =
sizeof
(IMAGE_RESOURCE_DIRECTORY);
112
size +=
getEntriesAreaSize
();
113
return
size;
114
}
115
116
void
*
ResourceDirWrapper::getFieldPtr
(
size_t
fId,
size_t
subField)
117
{
118
IMAGE_RESOURCE_DIRECTORY* d = resourceDir();
119
if
(d == NULL)
return
NULL;
120
121
switch
(fId) {
122
case
CHARACTERISTIC
:
return
&d->Characteristics;
123
case
TIMESTAMP
:
return
&d->TimeDateStamp;
124
case
MAJOR_VER
:
return
&d->MajorVersion;
125
case
MINOR_VER
:
return
&d->MinorVersion;
126
case
NAMED_ENTRIES_NUM
:
return
&d->NumberOfNamedEntries;
127
case
ID_ENTRIES_NUM
:
return
&d->NumberOfIdEntries;
128
}
129
return
this->
getPtr
();
130
}
131
132
bufsize_t
ResourceDirWrapper::getFieldSize
(
size_t
fId,
size_t
subField)
133
{
134
IMAGE_RESOURCE_DIRECTORY* d = resourceDir();
135
if
(d == NULL)
return
0;
136
137
// calculate size of the last field separately:
138
if
(fId ==
ID_ENTRIES_NUM
) {
139
void
*nextPtr = (&d->NumberOfIdEntries) + 1;
140
void
*argPtr = &d->NumberOfIdEntries;
141
return
(BYTE*) nextPtr - (BYTE*)argPtr;
142
}
143
return
DataDirEntryWrapper::getFieldSize
(fId, subField);
144
}
145
146
QString
ResourceDirWrapper::getFieldName
(
size_t
fieldId)
147
{
148
switch
(fieldId) {
149
case
CHARACTERISTIC
:
return
"Characteristics"
;
150
case
TIMESTAMP
: {
151
PEFile
* myPe =
dynamic_cast<
PEFile
*
>
(this->
m_Exe
);
152
if
(myPe && myPe->
isReproBuild
()) {
153
return
"ReproChecksum"
;
154
}
155
return
"TimeDateStamp"
;
156
}
157
case
MAJOR_VER
:
return
"MajorVersion"
;
158
case
MINOR_VER
:
return
"MinorVersion"
;
159
case
NAMED_ENTRIES_NUM
:
return
"NumberOfNamedEntries"
;
160
case
ID_ENTRIES_NUM
:
return
"NumberOfIdEntries"
;
161
}
162
return
getName
();
163
}
164
165
//-----------------------------------------------------------------
166
167
void
ResourceEntryWrapper::clear
()
168
{
169
delete
childDir;
170
this->childDir = NULL;
171
//---
172
delete
childLeaf;
173
this->childLeaf = NULL;
174
}
175
176
bool
ResourceEntryWrapper::wrap
()
177
{
178
clear
();
179
//---
180
offset_t
childRaw =
getChildAddress
();
181
if
(childRaw == 0 || childRaw ==
INVALID_ADDR
)
return
false
;
182
183
if
(this->
isDir
()) {
184
long
depth = this->parentDir->getDepth() + 1;
185
if
(depth >=
MAX_DEPTH
)
return
false
;
186
this->childDir =
new
ResourceDirWrapper
(this->
m_PE
, this->album, childRaw, depth, topEntryID);
187
}
else
{
188
this->childLeaf =
new
ResourceLeafWrapper
(
m_Exe
, childRaw, topEntryID);
189
if
(this->album != NULL) {
190
album->putLeaf(childLeaf, topEntryID);
191
}
192
}
193
return
true
;
194
}
195
196
197
IMAGE_RESOURCE_DIRECTORY_ENTRY*
ResourceEntryWrapper::getEntryPtr
()
198
{
199
if
(this->parentDir == NULL)
return
NULL;
200
uint64_t offset = parentDir->getFieldOffset(
ResourceDirWrapper::ID_ENTRIES_NUM
);
201
if
(offset ==
INVALID_ADDR
)
return
NULL;
202
203
size_t
lastSize = parentDir->getFieldSize(
ResourceDirWrapper::ID_ENTRIES_NUM
,
FIELD_NONE
);
204
offset += lastSize;
205
offset += (this->
entryNum
*
sizeof
(IMAGE_RESOURCE_DIRECTORY_ENTRY));
206
207
void
*ptr =
m_Exe
->getContentAt(offset,
Executable::RAW
,
sizeof
(IMAGE_RESOURCE_DIRECTORY_ENTRY));
208
return
(IMAGE_RESOURCE_DIRECTORY_ENTRY*) ptr;
209
}
210
211
//IMAGE_RESOURCE_DIRECTORY_ENTRY
212
void
*
ResourceEntryWrapper::getFieldPtr
(
size_t
fieldId,
size_t
subField)
213
{
214
IMAGE_RESOURCE_DIRECTORY_ENTRY* entry =
getEntryPtr
();
215
if
(entry == NULL)
return
NULL;
216
217
switch
(fieldId) {
218
case
NAME_ID_ADDR
:
219
return
&entry->Name;
220
case
OFFSET_TO_DATA
:
221
return
&entry->OffsetToData;
222
}
223
return
getPtr
();
224
}
225
226
QString
ResourceEntryWrapper::getFieldName
(
size_t
fieldId)
227
{
228
switch
(fieldId) {
229
case
NAME_ID_ADDR
:
230
return
(
isByName
()) ?
"Name"
:
"ID"
;
231
case
OFFSET_TO_DATA
:
232
return
"Offset To Data"
;
233
}
234
return
getName
();
235
}
236
237
bool
ResourceEntryWrapper::isByName
()
238
{
239
IMAGE_RESOURCE_DIRECTORY_ENTRY* entry =
getEntryPtr
();
240
if
(entry == NULL)
return
false
;
241
if
(entry->NameIsString == 1)
return
true
;
242
return
false
;
243
}
244
245
bool
ResourceEntryWrapper::isDir
()
246
{
247
IMAGE_RESOURCE_DIRECTORY_ENTRY* entry =
getEntryPtr
();
248
if
(entry == NULL)
return
false
;
249
if
(entry->DataIsDirectory == 1)
return
true
;
250
return
false
;
251
}
252
253
offset_t
ResourceEntryWrapper::getNameOffset
()
254
{
255
IMAGE_RESOURCE_DIRECTORY_ENTRY* entry =
getEntryPtr
();
256
if
(entry == NULL)
return
INVALID_ADDR
;
257
258
if
(this->parentDir == NULL)
return
INVALID_ADDR
;
259
offset_t
fOff = this->parentDir->getOffset(this->parentDir->getPtr());
260
if
(fOff ==
INVALID_ADDR
)
return
INVALID_ADDR
;
261
262
if
(entry->NameIsString != 1)
return
INVALID_ADDR
;
263
return
fOff + entry->NameOffset;
264
}
265
266
IMAGE_RESOURCE_DIRECTORY_STRING*
ResourceEntryWrapper::getNameStr
()
267
{
268
offset_t
nameOff =
getNameOffset
();
269
if
(nameOff ==
INVALID_ADDR
)
return
NULL;
270
271
const
size_t
BASIC_SIZE =
sizeof
(IMAGE_RESOURCE_DIRECTORY_STRING);
272
IMAGE_RESOURCE_DIRECTORY_STRING *ptr = (IMAGE_RESOURCE_DIRECTORY_STRING*) this->
m_Exe
->getContentAt(nameOff,
Executable::RAW
, BASIC_SIZE);
273
return
ptr;
274
}
275
276
QString
ResourceEntryWrapper::translateType
(WORD
id
)
277
{
278
switch
(
id
) {
279
case
pe::RESTYPE_CURSOR :
return
"Cursor"
;
280
case
pe::RESTYPE_FONT :
return
"Font"
;
281
case
pe::RESTYPE_BITMAP :
return
"Bitmap"
;
282
case
pe::RESTYPE_ICON :
return
"Icon"
;
283
case
pe::RESTYPE_MENU :
return
"Menu"
;
284
case
pe::RESTYPE_DIALOG :
return
"Dialog"
;
285
case
pe::RESTYPE_STRING :
return
"String"
;
286
case
pe::RESTYPE_FONTDIR :
return
"Font Dir"
;
287
case
pe::RESTYPE_ACCELERATOR :
return
"Accelerator"
;
288
case
pe::RESTYPE_RCDATA :
return
"RC Data"
;
289
case
pe::RESTYPE_MESSAGETABLE :
return
"Message Table"
;
290
291
case
pe::RESTYPE_GROUP_CURSOR :
return
"Cursors Group"
;
292
case
pe::RESTYPE_GROUP_ICON :
return
"Icons Group"
;
293
case
pe::RESTYPE_VERSION :
return
"Version"
;
294
case
pe::RESTYPE_DLGINCLUDE :
return
"Dlg Include"
;
295
case
pe::RESTYPE_PLUGPLAY :
return
"Plug & Play"
;
296
case
pe::RESTYPE_VXD :
return
"VXD"
;
297
case
pe::RESTYPE_ANICURSOR :
return
"Animated Cursor"
;
298
case
pe::RESTYPE_ANIICON :
return
"Animated Icon"
;
299
case
pe::RESTYPE_HTML :
return
"HTML"
;
300
case
pe::RESTYPE_MANIFEST :
return
"Manifest"
;
301
}
302
return
""
;
303
}
304
305
WORD
ResourceEntryWrapper::getID
()
306
{
307
IMAGE_RESOURCE_DIRECTORY_ENTRY* entry =
getEntryPtr
();
308
if
(entry == NULL)
return
0;
309
if
(this->
isByName
())
return
0;
310
311
return
entry->Id;
312
}
313
314
offset_t
ResourceEntryWrapper::getChildOffsetToDirectory
()
315
{
316
const
IMAGE_RESOURCE_DIRECTORY_ENTRY* entry =
getEntryPtr
();
317
if
(!entry) {
318
return
INVALID_ADDR
;
319
}
320
if
(entry->DataIsDirectory) {
321
return
entry->OffsetToDirectory;
322
}
323
return
entry->OffsetToData;
324
}
325
326
offset_t
ResourceEntryWrapper::getChildAddress
()
327
{
328
if
(!this->parentDir)
return
INVALID_ADDR
;
329
330
const
offset_t
fOff = this->parentDir->getOffset(this->parentDir->mainResourceDir());
331
if
(fOff ==
INVALID_ADDR
)
return
INVALID_ADDR
;
332
333
const
offset_t
childOff =
getChildOffsetToDirectory
();
334
if
(childOff ==
INVALID_ADDR
)
return
INVALID_ADDR
;
335
336
return
fOff + childOff;
337
}
338
339
//-------------------------------------------------------------------------
340
341
IMAGE_RESOURCE_DATA_ENTRY*
ResourceLeafWrapper::leafEntryPtr
()
342
{
343
if
(this->
offset
== 0 || this->
offset
==
INVALID_ADDR
)
return
NULL;
344
345
IMAGE_RESOURCE_DATA_ENTRY* leaf = (IMAGE_RESOURCE_DATA_ENTRY*) this->
m_Exe
->getContentAt(this->offset,
Executable::RAW
,
sizeof
(IMAGE_RESOURCE_DATA_ENTRY));
346
return
leaf;
347
}
348
349
void
*
ResourceLeafWrapper::getFieldPtr
(
size_t
fieldId,
size_t
subField)
350
{
351
IMAGE_RESOURCE_DATA_ENTRY* leaf =
leafEntryPtr
();
352
if
(!leaf)
return
NULL;
353
354
switch
(fieldId) {
355
case
OFFSET_TO_DATA
:
return
&leaf->OffsetToData;
356
case
DATA_SIZE
:
return
&leaf->Size;
357
case
CODE_PAGE
:
return
&leaf->CodePage;
358
case
RESERVED
:
return
&leaf->Reserved;
359
}
360
return
NULL;
361
}
362
363
QString
ResourceLeafWrapper::getFieldName
(
size_t
fieldId)
364
{
365
switch
(fieldId) {
366
case
OFFSET_TO_DATA
:
return
"OffsetToData"
;
367
case
DATA_SIZE
:
return
"DataSize"
;
368
case
CODE_PAGE
:
return
"CodePage"
;
369
case
RESERVED
:
return
"Reserved"
;
370
}
371
return
""
;
372
}
373
374
INVALID_ADDR
const offset_t INVALID_ADDR
Definition
AbstractByteBuffer.h:21
offset_t
uint64_t offset_t
Definition
AbstractByteBuffer.h:20
bufsize_t
size_t bufsize_t
Definition
AbstractByteBuffer.h:17
FIELD_NONE
#define FIELD_NONE
Definition
ExeElementWrapper.h:9
PEFile.h
MAX_DEPTH
#define MAX_DEPTH
Definition
ResourceDirWrapper.cpp:5
MAX_ENTRIES
#define MAX_ENTRIES
Definition
ResourceDirWrapper.cpp:4
ResourceDirWrapper.h
TOP_ENTRY_ROOT
#define TOP_ENTRY_ROOT
Definition
ResourcesAlbum.h:3
DataDirEntryWrapper::PEFile
friend class PEFile
Definition
DataDirEntryWrapper.h:22
DataDirEntryWrapper::getDirEntryAddress
offset_t getDirEntryAddress()
Definition
DataDirEntryWrapper.cpp:19
ExeElementWrapper::getFieldSize
virtual bufsize_t getFieldSize(size_t fieldId, size_t subField=FIELD_NONE)
Definition
ExeElementWrapper.cpp:12
ExeElementWrapper::m_Exe
Executable * m_Exe
Definition
ExeElementWrapper.h:65
ExeNodeWrapper::entries
std::vector< ExeNodeWrapper * > entries
Definition
ExeNodeWrapper.h:56
ExeNodeWrapper::entryNum
size_t entryNum
Definition
ExeNodeWrapper.h:54
ExeNodeWrapper::clear
virtual void clear()
Definition
ExeNodeWrapper.cpp:30
Executable::RVA
@ RVA
Definition
Executable.h:45
Executable::RAW
@ RAW
Definition
Executable.h:44
Executable::getContentAt
BYTE * getContentAt(offset_t offset, bufsize_t size, bool allowExceptions=false)
Definition
Executable.h:67
PEFile::isReproBuild
bool isReproBuild()
Definition
PEFile.h:360
PENodeWrapper::m_PE
PEFile * m_PE
Definition
PENodeWrapper.h:36
ResourceDirWrapper
Definition
ResourceDirWrapper.h:14
ResourceDirWrapper::getSize
virtual bufsize_t getSize()
Definition
ResourceDirWrapper.cpp:108
ResourceDirWrapper::TIMESTAMP
@ TIMESTAMP
Definition
ResourceDirWrapper.h:20
ResourceDirWrapper::ID_ENTRIES_NUM
@ ID_ENTRIES_NUM
Definition
ResourceDirWrapper.h:24
ResourceDirWrapper::CHARACTERISTIC
@ CHARACTERISTIC
Definition
ResourceDirWrapper.h:19
ResourceDirWrapper::MAJOR_VER
@ MAJOR_VER
Definition
ResourceDirWrapper.h:21
ResourceDirWrapper::MINOR_VER
@ MINOR_VER
Definition
ResourceDirWrapper.h:22
ResourceDirWrapper::NAMED_ENTRIES_NUM
@ NAMED_ENTRIES_NUM
Definition
ResourceDirWrapper.h:23
ResourceDirWrapper::wrap
bool wrap()
Definition
ResourceDirWrapper.cpp:73
ResourceDirWrapper::getFieldName
virtual QString getFieldName(size_t fieldId)
Definition
ResourceDirWrapper.cpp:146
ResourceDirWrapper::getFieldPtr
virtual void * getFieldPtr(size_t fieldId, size_t subField)
Definition
ResourceDirWrapper.cpp:116
ResourceDirWrapper::getPtr
virtual void * getPtr()
Definition
ResourceDirWrapper.h:37
ResourceDirWrapper::mainResourceDir
IMAGE_RESOURCE_DIRECTORY * mainResourceDir()
Definition
ResourceDirWrapper.cpp:57
ResourceDirWrapper::getFieldSize
virtual bufsize_t getFieldSize(size_t fieldId, size_t subField)
Definition
ResourceDirWrapper.cpp:132
ResourceDirWrapper::getName
virtual QString getName()
Definition
ResourceDirWrapper.h:40
ResourceDirWrapper::getEntriesAreaSize
bufsize_t getEntriesAreaSize()
Definition
ResourceDirWrapper.h:48
ResourceEntryWrapper
Definition
ResourceDirWrapper.h:67
ResourceEntryWrapper::getID
WORD getID()
Definition
ResourceDirWrapper.cpp:305
ResourceEntryWrapper::getFieldName
virtual QString getFieldName(size_t fieldId)
Definition
ResourceDirWrapper.cpp:226
ResourceEntryWrapper::getChildAddress
offset_t getChildAddress()
Definition
ResourceDirWrapper.cpp:326
ResourceEntryWrapper::getEntryPtr
IMAGE_RESOURCE_DIRECTORY_ENTRY * getEntryPtr()
Definition
ResourceDirWrapper.cpp:197
ResourceEntryWrapper::getNameOffset
offset_t getNameOffset()
Definition
ResourceDirWrapper.cpp:253
ResourceEntryWrapper::clear
virtual void clear()
Definition
ResourceDirWrapper.cpp:167
ResourceEntryWrapper::isDir
bool isDir()
Definition
ResourceDirWrapper.cpp:245
ResourceEntryWrapper::translateType
static QString translateType(WORD id)
Definition
ResourceDirWrapper.cpp:276
ResourceEntryWrapper::isByName
bool isByName()
Definition
ResourceDirWrapper.cpp:237
ResourceEntryWrapper::getName
virtual QString getName()
Definition
ResourceDirWrapper.h:93
ResourceEntryWrapper::wrap
bool wrap()
Definition
ResourceDirWrapper.cpp:176
ResourceEntryWrapper::getNameStr
IMAGE_RESOURCE_DIRECTORY_STRING * getNameStr()
Definition
ResourceDirWrapper.cpp:266
ResourceEntryWrapper::getChildOffsetToDirectory
offset_t getChildOffsetToDirectory()
Definition
ResourceDirWrapper.cpp:314
ResourceEntryWrapper::NAME_ID_ADDR
@ NAME_ID_ADDR
Definition
ResourceDirWrapper.h:72
ResourceEntryWrapper::OFFSET_TO_DATA
@ OFFSET_TO_DATA
Definition
ResourceDirWrapper.h:73
ResourceEntryWrapper::getPtr
virtual void * getPtr()
Definition
ResourceDirWrapper.h:90
ResourceEntryWrapper::getFieldPtr
virtual void * getFieldPtr(size_t fieldId, size_t subField=FIELD_NONE)
Definition
ResourceDirWrapper.cpp:212
ResourceLeafWrapper
Definition
ResourceLeafWrapper.h:10
ResourceLeafWrapper::leafEntryPtr
IMAGE_RESOURCE_DATA_ENTRY * leafEntryPtr()
Definition
ResourceDirWrapper.cpp:341
ResourceLeafWrapper::getFieldPtr
virtual void * getFieldPtr(size_t fieldId, size_t subField)
Definition
ResourceDirWrapper.cpp:349
ResourceLeafWrapper::offset
offset_t offset
Definition
ResourceLeafWrapper.h:45
ResourceLeafWrapper::getFieldName
virtual QString getFieldName(size_t fieldId)
Definition
ResourceDirWrapper.cpp:363
ResourceLeafWrapper::DATA_SIZE
@ DATA_SIZE
Definition
ResourceLeafWrapper.h:16
ResourceLeafWrapper::RESERVED
@ RESERVED
Definition
ResourceLeafWrapper.h:18
ResourceLeafWrapper::CODE_PAGE
@ CODE_PAGE
Definition
ResourceLeafWrapper.h:17
ResourceLeafWrapper::OFFSET_TO_DATA
@ OFFSET_TO_DATA
Definition
ResourceLeafWrapper.h:15
Generated by
1.17.0