BearParser
Portable Executable parsing library (from PE-bear)
Toggle main menu visibility
Loading...
Searching...
No Matches
parser
pe
RelocDirWrapper.cpp
Go to the documentation of this file.
1
#include "
pe/RelocDirWrapper.h
"
2
#include "
pe/PEFile.h
"
3
4
/*
5
// Based relocation format.
6
7
typedef struct _IMAGE_BASE_RELOCATION {
8
DWORD VirtualAddress;
9
DWORD SizeOfBlock;
10
// WORD TypeOffset[1];
11
} IMAGE_BASE_RELOCATION;
12
typedef IMAGE_BASE_RELOCATION UNALIGNED * PIMAGE_BASE_RELOCATION;
13
14
15
//Based relocation types.
16
17
enum reloc_based {
18
RELB_ABSOLUTE = 0,
19
RELB_HIGH = 1,
20
RELB_LOW = 2,
21
RELB_HIGHLOW = 3,
22
RELB_HIGHADJ = 4,
23
RELB_MIPS_JMPADDR = 5,
24
RELB_SECTION = 6,
25
RELB_REL32 = 7,
26
RELB_MIPS_JMPADDR16 = 9,
27
RELB_IA64_IMM64 = 9,
28
RELB_DIR64 = 10,
29
RELB_HIGH3ADJ = 11
30
};
31
32
*/
33
34
bool
RelocDirWrapper::wrap
()
35
{
36
clear
();
37
this->parsedSize = 0;
38
39
bufsize_t
maxSize =
getDirEntrySize
(
true
);
40
size_t
entryId = 0;
41
while
(parsedSize < maxSize) {
42
RelocBlockWrapper
* entry =
new
RelocBlockWrapper
(this->
m_Exe
,
this
, entryId++);
43
if
(!entry)
break
;
44
45
bool
isOk1 =
false
;
46
const
bufsize_t
blockSize = (
bufsize_t
) entry->
getNumValue
(
RelocBlockWrapper::BLOCK_SIZE
, &isOk1);
47
if
(!isOk1 || !blockSize || !entry->
getPtr
()) {
48
delete
entry;
49
break
;
50
}
51
this->parsedSize += blockSize;
52
this->
entries
.push_back(entry);
53
if
(!entry->
isValid
()) {
54
break
;
55
}
56
}
57
return
true
;
58
}
59
60
61
62
IMAGE_BASE_RELOCATION*
RelocDirWrapper::reloc
()
63
{
64
offset_t
rva =
getDirEntryAddress
();
65
66
BYTE *ptr =
m_Exe
->getContentAt(rva,
Executable::RVA
,
sizeof
(IMAGE_BASE_RELOCATION));
67
if
(ptr == NULL)
return
NULL;
68
69
IMAGE_BASE_RELOCATION *
reloc
= (IMAGE_BASE_RELOCATION*) ptr;
70
return
reloc
;
71
}
72
73
//----------------
74
75
bool
RelocBlockWrapper::wrap
()
76
{
77
clear
();
78
parsedSize = 0;
79
80
IMAGE_BASE_RELOCATION* reloc =
myReloc
();
81
if
(!reloc)
return
false
;
82
83
validatePage();
84
if
(!this->isValidPage)
return
false
;
85
86
size_t
maxSize = reloc->SizeOfBlock;
87
parsedSize =
sizeof
(IMAGE_BASE_RELOCATION);
// the block begins with IMAGE_BASE_RELOCATION record
88
size_t
entryId = 0;
89
90
while
(parsedSize < maxSize) {
91
RelocEntryWrapper
* entry =
new
RelocEntryWrapper
(this->
m_Exe
,
this
, entryId++);
92
93
if
(!entry->
getPtr
()) {
94
delete
entry;
95
break
;
96
}
97
this->parsedSize +=
sizeof
(pe::BASE_RELOCATION_ENTRY);
98
this->
entries
.push_back(entry);
99
}
100
return
true
;
101
}
102
103
void
RelocBlockWrapper::validatePage()
104
{
105
this->isValidPage =
false
;
106
if
(!parentDir)
return
;
107
PEFile
*m_PE = parentDir->
m_PE
;
108
if
(!m_PE)
return
;
109
110
bool
isOk =
false
;
111
const
offset_t
pageRva = this->
getNumValue
(
RelocBlockWrapper::PAGE_VA
, &isOk);
112
if
(!isOk)
return
;
113
114
this->isValidPage = (pageRva < m_PE->
getImageSize
()) ? true :
false
;
115
}
116
117
bool
RelocBlockWrapper::isValid
()
118
{
119
return
this->isValidPage;
120
}
121
122
void
*
RelocBlockWrapper::getPtr
()
123
{
124
if
(this->parentDir == NULL)
return
NULL;
125
IMAGE_BASE_RELOCATION* reloc = this->parentDir->reloc();
126
if
(!reloc)
return
NULL;
127
128
offset_t
raw =
INVALID_ADDR
;
129
BYTE *ptr = NULL;
130
131
// use my cached:
132
if
(this->cachedRaw !=
INVALID_ADDR
) {
133
ptr =
m_Exe
->getContentAt(this->cachedRaw,
Executable::RAW
,
sizeof
(IMAGE_BASE_RELOCATION));
134
return
ptr;
135
}
136
137
// use previous cached to calculate my cached
138
size_t
prevNum = this->
entryNum
- 1;
139
140
RelocBlockWrapper
*prevEntry =
dynamic_cast<
RelocBlockWrapper
*
>
(this->parentDir->getEntryAt(prevNum));
141
if
(prevEntry) {
142
offset_t
prevRaw = prevEntry->cachedRaw;
143
144
IMAGE_BASE_RELOCATION* prevReloc = (IMAGE_BASE_RELOCATION*) prevEntry->
getPtr
();
145
raw = prevRaw + prevReloc->SizeOfBlock;
146
147
if
(prevRaw !=
INVALID_ADDR
) {
148
ptr =
m_Exe
->getContentAt(raw,
Executable::RAW
,
sizeof
(IMAGE_BASE_RELOCATION));
149
150
if
(ptr != NULL) {
151
this->cachedRaw = raw;
152
return
ptr;
153
}
154
}
155
}
156
// previous cached not avaliable, calculate...
157
offset_t
firstRaw = this->
getOffset
(reloc);
158
offset_t
blockSize = reloc->SizeOfBlock;
159
160
raw = firstRaw;
161
ptr = (BYTE*) reloc;
162
163
for
(
size_t
i = 0; i < this->
entryNum
; i++) {
//TODO: make caching
164
raw += blockSize;
165
166
ptr =
m_Exe
->getContentAt(raw,
Executable::RAW
,
sizeof
(IMAGE_BASE_RELOCATION));
167
if
(!ptr)
return
NULL;
168
169
reloc = (IMAGE_BASE_RELOCATION*) ptr;
170
blockSize = reloc->SizeOfBlock;
171
}
172
173
this->cachedRaw = raw;
174
return
ptr;
175
}
176
177
bufsize_t
RelocBlockWrapper::getSize
()
178
{
179
if
(this->parentDir == NULL)
return
0;
180
IMAGE_BASE_RELOCATION* reloc = (IMAGE_BASE_RELOCATION*) this->
getPtr
();
181
if
(!reloc)
return
0;
182
183
if
(reloc->SizeOfBlock > 0)
return
reloc->SizeOfBlock;
184
185
return
sizeof
(IMAGE_BASE_RELOCATION);
186
}
187
188
void
*
RelocBlockWrapper::getFieldPtr
(
size_t
fieldId,
size_t
subField)
189
{
190
IMAGE_BASE_RELOCATION* reloc = (IMAGE_BASE_RELOCATION*) this->
getPtr
();
191
if
(!reloc)
return
NULL;
192
193
switch
(fieldId) {
194
case
PAGE_VA
:
return
(
void
*) &reloc->VirtualAddress;
195
case
BLOCK_SIZE
:
return
(
void
*) &reloc->SizeOfBlock;
196
case
ENTRIES_PTR
:
197
{
198
BYTE *blockSizePtr = (BYTE*) &reloc->SizeOfBlock;
199
return
blockSizePtr +
sizeof
(DWORD);
200
}
201
}
202
return
getPtr
();
203
}
204
205
QString
RelocBlockWrapper::getFieldName
(
size_t
fieldId)
206
{
207
switch
(fieldId) {
208
case
BLOCK_SIZE
:
return
"Block Size"
;
209
case
PAGE_VA
:
return
"Page RVA"
;
210
case
ENTRIES_PTR
:
return
"Entries"
;
211
}
212
return
getName
();
213
}
214
215
Executable::addr_type
RelocBlockWrapper::containsAddrType
(
size_t
fieldId,
size_t
subField)
216
{
217
switch
(fieldId) {
218
case
PAGE_VA
:
219
return
Executable::RVA
;
220
}
221
return
Executable::NOT_ADDR
;
222
}
223
224
WrappedValue::data_type
RelocBlockWrapper::containsDataType
(
size_t
fieldId,
size_t
subField)
225
{
226
if
(fieldId ==
ENTRIES_PTR
){
227
return
WrappedValue::COMPLEX
;
228
}
229
return
WrappedValue::INT
;
230
}
231
232
void
*
RelocBlockWrapper::getEntriesPtr
()
233
{
234
void
*entriesPtr =
getFieldPtr
(
ENTRIES_PTR
);
235
size_t
entriesSize =
getFieldSize
(
ENTRIES_PTR
);
236
237
if
(entriesPtr == NULL || entriesSize == 0)
return
NULL;
238
239
offset_t
entriesOffset =
getFieldOffset
(
ENTRIES_PTR
);
240
void
*ptr = this->
m_Exe
->getContentAt(entriesOffset,
Executable::RAW
,
sizeof
(WORD));
241
242
return
ptr;
243
}
244
245
size_t
RelocBlockWrapper::maxEntriesNumInBlock
()
246
{
247
if
(this->cachedMaxNum > 0)
return
this->cachedMaxNum;
248
249
IMAGE_BASE_RELOCATION* reloc = (IMAGE_BASE_RELOCATION*) this->
getPtr
();
250
if
(!reloc)
return
0;
251
252
bufsize_t
entriesSize =
getFieldSize
(
ENTRIES_PTR
);
253
offset_t
entriesOffset =
getFieldOffset
(
ENTRIES_PTR
);
254
255
offset_t
fileSize =
m_Exe
->getRawSize();
256
if
(entriesOffset + entriesSize > fileSize) {
257
entriesSize = fileSize - entriesOffset;
// truncate to fileSize
258
}
259
260
void
*ptr = this->
m_Exe
->getContentAt(entriesOffset,
Executable::RAW
, entriesSize);
261
262
bufsize_t
entriesNum = 0;
263
if
(ptr) {
264
entriesNum = entriesSize /
sizeof
(WORD);
//sizeof(BASE_RELOCATION_ENTRY);
265
}
266
this->cachedMaxNum = entriesNum;
267
return
entriesNum;
268
}
269
//-------------------------------------------------------------------------------------------------
270
271
void
*
RelocEntryWrapper::getPtr
()
272
{
273
if
(this->parentDir == NULL)
return
NULL;
274
275
size_t
maxNum = this->parentDir->maxEntriesNumInBlock();
276
if
(this->
entryNum
>= maxNum)
return
NULL;
277
278
WORD* entriesPtr = (WORD* ) parentDir->getEntriesPtr();
279
if
(entriesPtr == NULL)
return
NULL;
280
281
WORD* ptr = &entriesPtr[this->
entryNum
];
282
return
ptr;
283
}
284
285
bufsize_t
RelocEntryWrapper::getSize
()
286
{
287
if
(this->parentDir == NULL)
return
0;
288
return
sizeof
(WORD);
289
}
290
291
WORD
RelocEntryWrapper::getType
(WORD relocEntryVal)
292
{
293
pe::BASE_RELOCATION_ENTRY* entry = (pe::BASE_RELOCATION_ENTRY*) &relocEntryVal;
294
return
entry->Type;
295
}
296
297
WORD
RelocEntryWrapper::getDelta
(WORD relocEntryVal)
298
{
299
pe::BASE_RELOCATION_ENTRY* entry = (pe::BASE_RELOCATION_ENTRY*) &relocEntryVal;
300
return
entry->Offset;
301
}
302
303
QString
RelocEntryWrapper::translateType
(WORD type)
304
{
305
switch
(type) {
306
case
0 :
return
"Padding (skipped)"
;
307
case
1 :
return
"High WORD of 32-bit field"
;
308
case
2 :
return
"Low WORD of 32-bit field"
;
309
case
3 :
return
"32 bit field"
;
310
case
4 :
return
"HighAdj"
;
311
case
5 :
return
"MIPS JumpAddr"
;
312
case
6 :
case
7 :
return
"Reserved"
;
313
case
9 :
return
"MIPS16 JumpAddr"
;
314
case
10 :
return
"64 bit field"
;
315
}
316
return
""
;
317
}
318
319
offset_t
RelocEntryWrapper::deltaToRVA
(WORD delta)
320
{
321
if
(this->parentDir == NULL)
return
INVALID_ADDR
;
322
323
IMAGE_BASE_RELOCATION* reloc = parentDir->myReloc();
324
if
(reloc == NULL)
return
INVALID_ADDR
;
325
326
offset_t
offset =
static_cast<
offset_t
>
(reloc->VirtualAddress + delta);
327
return
offset;
328
}
329
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
PEFile.h
RelocDirWrapper.h
DataDirEntryWrapper::getDirEntrySize
bufsize_t getDirEntrySize(bool trimToExeSize=false)
Definition
DataDirEntryWrapper.cpp:33
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::getFieldOffset
virtual offset_t getFieldOffset(size_t fieldId, size_t subField=FIELD_NONE)
Definition
ExeElementWrapper.cpp:51
ExeElementWrapper::getOffset
virtual offset_t getOffset()
Definition
ExeElementWrapper.cpp:39
ExeElementWrapper::m_Exe
Executable * m_Exe
Definition
ExeElementWrapper.h:65
ExeElementWrapper::getNumValue
virtual uint64_t getNumValue(size_t fieldId, size_t subField, bool *isOk)
Definition
ExeElementWrapper.cpp:73
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::addr_type
addr_type
Definition
Executable.h:42
Executable::NOT_ADDR
@ NOT_ADDR
Definition
Executable.h:43
Executable::RVA
@ RVA
Definition
Executable.h:45
Executable::RAW
@ RAW
Definition
Executable.h:44
Executable::getImageSize
virtual bufsize_t getImageSize()
Definition
Executable.h:76
PEFile
Definition
PEFile.h:45
PENodeWrapper::m_PE
PEFile * m_PE
Definition
PENodeWrapper.h:36
RelocBlockWrapper::getFieldName
virtual QString getFieldName(size_t fieldId)
Definition
RelocDirWrapper.cpp:205
RelocBlockWrapper::containsDataType
virtual WrappedValue::data_type containsDataType(size_t fieldId, size_t subField)
Definition
RelocDirWrapper.cpp:224
RelocBlockWrapper::getFieldPtr
virtual void * getFieldPtr(size_t fieldId, size_t subField=FIELD_NONE)
Definition
RelocDirWrapper.cpp:188
RelocBlockWrapper::RelocBlockWrapper
RelocBlockWrapper(Executable *pe, RelocDirWrapper *parentDir, size_t entryNumber)
Definition
RelocDirWrapper.h:54
RelocBlockWrapper::wrap
bool wrap()
Definition
RelocDirWrapper.cpp:75
RelocBlockWrapper::getPtr
virtual void * getPtr()
Definition
RelocDirWrapper.cpp:122
RelocBlockWrapper::getName
virtual QString getName()
Definition
RelocDirWrapper.h:68
RelocBlockWrapper::getSize
virtual bufsize_t getSize()
Definition
RelocDirWrapper.cpp:177
RelocBlockWrapper::maxEntriesNumInBlock
size_t maxEntriesNumInBlock()
Definition
RelocDirWrapper.cpp:245
RelocBlockWrapper::getEntriesPtr
void * getEntriesPtr()
Definition
RelocDirWrapper.cpp:232
RelocBlockWrapper::PAGE_VA
@ PAGE_VA
Definition
RelocDirWrapper.h:48
RelocBlockWrapper::ENTRIES_PTR
@ ENTRIES_PTR
Definition
RelocDirWrapper.h:50
RelocBlockWrapper::BLOCK_SIZE
@ BLOCK_SIZE
Definition
RelocDirWrapper.h:49
RelocBlockWrapper::containsAddrType
virtual Executable::addr_type containsAddrType(size_t fieldId, size_t subField)
Definition
RelocDirWrapper.cpp:215
RelocBlockWrapper::isValid
bool isValid()
Definition
RelocDirWrapper.cpp:117
RelocBlockWrapper::myReloc
IMAGE_BASE_RELOCATION * myReloc()
Definition
RelocDirWrapper.h:80
RelocDirWrapper::wrap
bool wrap()
Definition
RelocDirWrapper.cpp:34
RelocDirWrapper::RelocBlockWrapper
friend class RelocBlockWrapper
Definition
RelocDirWrapper.h:38
RelocDirWrapper::reloc
IMAGE_BASE_RELOCATION * reloc()
Definition
RelocDirWrapper.cpp:62
RelocEntryWrapper
Definition
RelocDirWrapper.h:97
RelocEntryWrapper::deltaToRVA
offset_t deltaToRVA(WORD delta)
Definition
RelocDirWrapper.cpp:319
RelocEntryWrapper::translateType
static QString translateType(WORD type)
Definition
RelocDirWrapper.cpp:303
RelocEntryWrapper::getPtr
virtual void * getPtr()
Definition
RelocDirWrapper.cpp:271
RelocEntryWrapper::getSize
virtual bufsize_t getSize()
Definition
RelocDirWrapper.cpp:285
RelocEntryWrapper::getDelta
static WORD getDelta(WORD relocEntryVal)
Definition
RelocDirWrapper.cpp:297
RelocEntryWrapper::getType
static WORD getType(WORD relocEntryVal)
Definition
RelocDirWrapper.cpp:291
WrappedValue::data_type
data_type
Definition
WrappedValue.h:15
WrappedValue::INT
@ INT
Definition
WrappedValue.h:17
WrappedValue::COMPLEX
@ COMPLEX
Definition
WrappedValue.h:20
Generated by
1.17.0