BearParser
Portable Executable parsing library (from PE-bear)
Toggle main menu visibility
Loading...
Searching...
No Matches
parser
pe
ImportDirWrapper.cpp
Go to the documentation of this file.
1
#include "
pe/ImportDirWrapper.h
"
2
#include "
pe/PEFile.h
"
3
4
using namespace
imports_util
;
5
6
void
*
ImportedFuncWrapper::getPtr
()
7
{
8
void
*ptr =
getValuePtr
(
ImportEntryWrapper::ORIG_FIRST_THUNK
);
9
if
(!ptr) ptr =
getValuePtr
(
ImportEntryWrapper::FIRST_THUNK
);
10
return
ptr;
11
}
12
13
IMAGE_IMPORT_BY_NAME*
ImportedFuncWrapper::getImportByNamePtr
()
14
{
15
bool
isOk =
false
;
16
uint64_t offset = this->
getNumValue
(
ImportedFuncWrapper::ORIG_THUNK
, &isOk);
17
if
(!isOk || offset ==
INVALID_ADDR
) {
18
offset = this->
getNumValue
(
ImportedFuncWrapper::THUNK
, &isOk);
19
}
20
if
(!isOk)
return
NULL;
21
BYTE *ptr = this->
m_Exe
->getContentAt(offset,
Executable::RVA
,
sizeof
(IMAGE_IMPORT_BY_NAME));
22
return
(IMAGE_IMPORT_BY_NAME*) ptr;
23
}
24
25
offset_t
ImportedFuncWrapper::getFieldRVA
(
ImportEntryWrapper::FieldID
fId)
26
{
27
if
(!
parentNode
)
return
0;
28
bool
is32 =
isBit32
();
29
30
bool
isOk;
31
uint64_t thunkRva =
parentNode
->getNumValue(fId, &isOk);
32
if
(!isOk)
return
0;
//TODO
33
34
if
(is32) thunkRva = (int32_t)(thunkRva);
35
if
(thunkRva == 0 || thunkRva == (-1))
return
0;
//TODO
36
37
size_t
thunkValSize = this->
getThunkValSize
();
38
offset_t
offset = this->
entryNum
* thunkValSize;
39
40
offset_t
fieldRVA = thunkRva + offset;
41
return
fieldRVA;
42
}
43
44
void
*
ImportedFuncWrapper::getValuePtr
(
ImportEntryWrapper::FieldID
fId)
45
{
46
if
(!
parentNode
)
return
NULL;
47
bool
is64 =
isBit64
();
48
49
bool
isOk;
50
uint64_t thunkRva =
parentNode
->getNumValue(fId, &isOk);
51
if
(!isOk) {
52
//printf("Failed getting value!\n");
53
return
NULL;
54
}
55
if
(!is64) thunkRva = (int32_t)(thunkRva);
56
if
(thunkRva == 0 || thunkRva == -1)
return
NULL;
57
58
bufsize_t
thunkValSize = this->
getThunkValSize
();
59
offset_t
offset =
static_cast<
offset_t
>
(this->
entryNum
) * thunkValSize;
60
61
offset_t
thunkAddr =
m_Exe
->toRaw(thunkRva + offset,
Executable::RVA
);
62
void
* thunkPtr =
m_Exe
->getContentAt(thunkAddr, thunkValSize);
63
return
thunkPtr;
64
}
65
66
uint64_t
ImportedFuncWrapper::getThunkValue
()
67
{
68
bool
is64 = (
m_Exe
->getBitMode() ==
Executable::BITS_64
) ? true :
false
;
69
70
uint64_t ordinal = 0;
71
void
* thunkPtr =
getPtr
();
72
if
(!thunkPtr)
return
0;
73
74
if
(is64) {
75
uint64_t* ptr = (uint64_t*) thunkPtr;
76
ordinal = *ptr;
77
if
(ordinal & ORDINAL_FLAG64) ordinal ^= ORDINAL_FLAG64;
78
79
}
else
{
80
uint32_t* ptr = (uint32_t*) thunkPtr;
81
ordinal = *ptr;
82
if
(uint32_t(ordinal) & ORDINAL_FLAG32) ordinal ^= ORDINAL_FLAG32;
83
}
84
85
return
ordinal;
86
}
87
88
bool
ImportedFuncWrapper::isByOrdinal
()
89
{
90
void
*p =
getValuePtr
(
ImportEntryWrapper::ORIG_FIRST_THUNK
);
91
if
(!p) p =
getValuePtr
(
ImportEntryWrapper::FIRST_THUNK
);
92
if
(!p)
return
false
;
93
94
if
(
isBit64
()) {
95
uint64_t* ptr = (uint64_t*) p;
96
if
((*ptr) & ORDINAL_FLAG64)
return
true
;
97
98
}
else
{
99
uint32_t* ptr = (uint32_t*) p;
100
if
((*ptr) & ORDINAL_FLAG32)
return
true
;
101
}
102
return
false
;
103
}
104
105
106
char
*
ImportedFuncWrapper::getFunctionName
()
107
{
108
if
(
isByOrdinal
())
return
NULL;
109
110
IMAGE_IMPORT_BY_NAME* dataPtr = this->
getImportByNamePtr
();
111
if
(!dataPtr)
return
NULL;
112
char
*name = (
char
*) dataPtr->Name;
113
return
name;
114
}
115
116
bufsize_t
ImportedFuncWrapper::getSize
()
117
{
118
return
getAddrSize
();
119
}
120
121
void
*
ImportedFuncWrapper::getFieldPtr
(
size_t
fId,
size_t
subField)
122
{
123
void
*entryPtr = this->
getPtr
();
124
if
(entryPtr == NULL)
return
NULL;
125
126
switch
(fId) {
127
case
ORIG_THUNK
:
return
(
void
*)
getValuePtr
(
ImportEntryWrapper::ORIG_FIRST_THUNK
);
128
case
THUNK
:
return
(
void
*)
getValuePtr
(
ImportEntryWrapper::FIRST_THUNK
);
129
case
FORWARDER
:
return
(
void
*)
getValuePtr
(
ImportEntryWrapper::FORWARDER
);
130
case
HINT
:
131
{
132
if
(
isByOrdinal
())
return
NULL;
133
IMAGE_IMPORT_BY_NAME* dataPtr = this->
getImportByNamePtr
();
134
return
(
void
*) &dataPtr->Hint;
135
}
136
};
137
return
entryPtr;
138
}
139
140
bufsize_t
ImportedFuncWrapper::getFieldSize
(
size_t
fieldId,
size_t
subField)
141
{
142
if
(fieldId ==
HINT
)
return
sizeof
(WORD);
143
bufsize_t
entrySize = (
isBit64
()) ?
sizeof
(uint64_t) :
sizeof
(uint32_t);
144
return
entrySize;
145
}
146
147
QString
ImportedFuncWrapper::getFieldName
(
size_t
fId)
148
{
149
switch
(fId) {
150
case
ORIG_THUNK
:
return
"Original Thunk"
;
151
case
THUNK
:
return
"Thunk"
;
152
case
FORWARDER
:
return
"Forwarder"
;
153
case
HINT
:
return
"Hint"
;
154
};
155
return
""
;
156
}
157
158
Executable::addr_type
ImportedFuncWrapper::containsAddrType
(
size_t
fId,
size_t
subField)
159
{
160
if
(this->
isByOrdinal
()) {
161
return
Executable::NOT_ADDR
;
162
}
163
switch
(fId) {
164
case
ORIG_THUNK
:
165
case
THUNK
:
166
return
Executable::RVA
;
167
}
168
return
Executable::NOT_ADDR
;
169
}
170
//-------------------------------------------------------------------------------
171
172
173
bool
ImportEntryWrapper::loadNextEntry
(
size_t
entryNum
)
174
{
175
ImportedFuncWrapper
* func =
new
ImportedFuncWrapper
(
m_PE
,
this
,
entryNum
);
176
offset_t
thunk = func->
getThunkValue
();
177
178
if
(thunk == 0 || thunk ==
INVALID_ADDR
) {
179
delete
func;
180
func = NULL;
181
return
false
;
182
}
else
{
183
entries
.push_back(func);
184
addMapping
(func);
185
}
186
return
true
;
187
}
188
189
190
void
*
ImportEntryWrapper::getPtr
()
191
{
192
if
(
m_PE
== NULL)
return
NULL;
193
IMAGE_DATA_DIRECTORY *d =
m_PE
->getDataDirectory();
194
if
(!d)
return
NULL;
195
196
offset_t
importRva =
static_cast<
offset_t
>
(d[pe::DIR_IMPORT].VirtualAddress);
197
if
(importRva == 0)
return
NULL;
198
199
offset_t
descAddr = this->
m_PE
->toRaw(importRva,
Executable::RVA
);
200
if
(descAddr ==
INVALID_ADDR
) {
201
return
NULL;
// address invalid
202
}
203
BYTE *dirPtr = this->
m_PE
->getContentAt(descAddr,
Executable::RAW
,
sizeof
(IMAGE_IMPORT_DESCRIPTOR));
204
if
(dirPtr == NULL)
return
NULL;
// address invalid
205
206
offset_t
entryOffset = descAddr + (this->
entryNum
*
sizeof
(IMAGE_IMPORT_DESCRIPTOR));
207
208
BYTE *content = this->
m_PE
->getContentAt(entryOffset,
Executable::RAW
,
sizeof
(IMAGE_IMPORT_DESCRIPTOR));
209
if
(!content)
return
NULL;
210
return
(
void
*) content;
211
}
212
213
bufsize_t
ImportEntryWrapper::getSize
()
214
{
215
return
sizeof
(IMAGE_IMPORT_DESCRIPTOR);
216
}
217
218
QString
ImportEntryWrapper::getName
()
219
{
220
char
*name =
getLibraryName
();
221
if
(!name)
return
""
;
222
return
name;
223
}
224
225
bool
ImportEntryWrapper::isBound
()
226
{
227
void
*ptr = this->
getPtr
();
228
IMAGE_IMPORT_DESCRIPTOR* desc = (IMAGE_IMPORT_DESCRIPTOR*) ptr;
229
if
(!desc)
return
false
;
230
231
if
(desc->TimeDateStamp == (-1))
return
true
;
232
return
false
;
233
}
234
235
void
*
ImportEntryWrapper::getFieldPtr
(
size_t
fId,
size_t
subField)
236
{
237
void
*ptr = this->
getPtr
();
238
IMAGE_IMPORT_DESCRIPTOR* desc = (IMAGE_IMPORT_DESCRIPTOR*) ptr;
239
if
(!desc)
return
NULL;
240
241
switch
(fId) {
242
case
ORIG_FIRST_THUNK
:
return
(
void
*) &desc->OriginalFirstThunk;
243
case
TIMESTAMP
:
return
(
void
*) &desc->TimeDateStamp;
244
case
FORWARDER
:
return
(
void
*) &desc->ForwarderChain;
245
case
NAME
:
return
(
void
*) &desc->Name;
246
case
FIRST_THUNK
:
return
(
void
*) &desc->FirstThunk;
247
}
248
return
desc;
249
}
250
251
QString
ImportEntryWrapper::getFieldName
(
size_t
fId)
252
{
253
switch
(fId) {
254
case
ORIG_FIRST_THUNK
:
return
"OriginalFirstThunk"
;
255
case
TIMESTAMP
:
return
"TimeDateStamp"
;
256
case
FORWARDER
:
return
"Forwarder"
;
257
case
NAME
:
return
"NameRVA"
;
258
case
FIRST_THUNK
:
return
"FirstThunk"
;
259
}
260
return
this->
getName
();
261
}
262
263
Executable::addr_type
ImportEntryWrapper::containsAddrType
(
size_t
fId,
size_t
subField)
264
{
265
switch
(fId) {
266
case
ORIG_FIRST_THUNK
:
267
case
NAME
:
268
case
FIRST_THUNK
:
269
return
Executable::RVA
;
270
}
271
return
Executable::NOT_ADDR
;
272
}
273
274
char
*
ImportEntryWrapper::getLibraryName
()
275
{
276
IMAGE_IMPORT_DESCRIPTOR* desc = (IMAGE_IMPORT_DESCRIPTOR*)
getPtr
();
277
if
(!desc) {
278
return
NULL;
279
}
280
281
offset_t
nameRVA = desc->Name;
282
offset_t
nAddr =
m_Exe
->toRaw(nameRVA,
Executable::RVA
);
283
if
(nAddr ==
INVALID_ADDR
)
return
NULL;
284
285
//TODO: reimplement it:
286
char
*name = (
char
*)
m_Exe
->getContentAt(nAddr,
sizeof
(
char
));
287
offset_t
peSize =
m_Exe
->getRawSize();
288
289
bufsize_t
upperLimit =
m_Exe
->getMaxSizeFromPtr((BYTE*) name);
290
bufsize_t
HARD_LIMIT =
ImportEntryWrapper::NameLenLimit
;
291
size_t
limit = (size_t) upperLimit < HARD_LIMIT ? upperLimit : HARD_LIMIT;
292
293
if
(
pe_util::isStrLonger
(name, limit)) {
294
if
(upperLimit < HARD_LIMIT) {
295
return
name;
// Name at the end of File. FileBuffer secures it with appended \0
296
}
297
return
NULL;
298
}
299
return
name;
300
}
301
302
//---------------------------------
303
304
IMAGE_DATA_DIRECTORY*
ImportDirWrapper::getDataDirectory
()
305
{
306
PEFile
*pe =
dynamic_cast<
PEFile
*
>
(this->
m_Exe
);
307
if
(pe == NULL)
return
NULL;
308
309
IMAGE_DATA_DIRECTORY *d = pe->getDataDirectory();
310
return
d;
311
}
312
313
IMAGE_IMPORT_DESCRIPTOR*
ImportDirWrapper::firstDescriptor
()
314
{
315
IMAGE_DATA_DIRECTORY *d =
getDataDirectory
();
316
if
(!d)
return
NULL;
317
318
uint32_t importRva = d[pe::DIR_IMPORT].VirtualAddress;
319
if
(importRva == 0)
return
NULL;
320
321
offset_t
descAddr = this->
m_Exe
->toRaw(importRva,
Executable::RVA
);
322
if
(descAddr ==
INVALID_ADDR
)
return
NULL;
// address invalid
323
324
BYTE *dirPtr = this->
m_Exe
->getContentAt(descAddr,
Executable::RAW
,
sizeof
(IMAGE_IMPORT_DESCRIPTOR));
325
if
(dirPtr == NULL)
return
NULL;
// address invalid
326
return
(IMAGE_IMPORT_DESCRIPTOR*) dirPtr;
327
}
328
329
bool
ImportDirWrapper::loadNextEntry
(
size_t
cntr)
330
{
331
ImportEntryWrapper
* imp =
new
ImportEntryWrapper
(
m_PE
,
this
, cntr);
332
if
(!imp || !imp->
getPtr
()) {
333
delete
imp;
334
return
false
;
335
}
336
bool
isOk =
false
;
337
uint64_t thunk = imp->
getNumValue
(
ImportEntryWrapper::FIRST_THUNK
, &isOk);
338
if
(!isOk) {
339
delete
imp;
340
return
false
;
341
}
342
uint64_t oThunk = imp->
getNumValue
(
ImportEntryWrapper::ORIG_FIRST_THUNK
, &isOk);
343
if
(!isOk) {
344
delete
imp;
345
return
false
;
346
}
347
if
(!thunk && !oThunk) {
348
delete
imp;
349
return
false
;
350
}
351
entries
.push_back(imp);
352
return
true
;
353
}
354
355
bufsize_t
ImportDirWrapper::getSize
()
356
{
357
size_t
fields =
getFieldsCount
() + 1;
//fields + terminating field
358
return
static_cast<
bufsize_t
>
(fields) *
sizeof
(IMAGE_IMPORT_DESCRIPTOR);
359
}
360
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
ImportDirWrapper.h
PEFile.h
DataDirEntryWrapper::PEFile
friend class PEFile
Definition
DataDirEntryWrapper.h:22
ExeElementWrapper::isBit32
bool isBit32()
Definition
ExeElementWrapper.h:59
ExeElementWrapper::isBit64
bool isBit64()
Definition
ExeElementWrapper.h:58
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::parentNode
ExeNodeWrapper * parentNode
Definition
ExeNodeWrapper.h:53
ExeNodeWrapper::entryNum
size_t entryNum
Definition
ExeNodeWrapper.h:54
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::BITS_64
@ BITS_64
Definition
Executable.h:32
ImportBaseDirWrapper::getFieldsCount
virtual size_t getFieldsCount()
Definition
ImportBaseDirWrapper.h:25
ImportBaseEntryWrapper::NameLenLimit
static bufsize_t NameLenLimit
Definition
ImportBaseDirWrapper.h:69
ImportBaseEntryWrapper::addMapping
void addMapping(ExeNodeWrapper *func)
Definition
ImportBaseDirWrapper.h:83
ImportBaseFuncWrapper::getThunkValSize
bufsize_t getThunkValSize()
Definition
ImportBaseDirWrapper.h:117
ImportBaseFuncWrapper::getAddrSize
bufsize_t getAddrSize()
Definition
ImportBaseDirWrapper.h:111
ImportDirWrapper::getDataDirectory
IMAGE_DATA_DIRECTORY * getDataDirectory()
Definition
ImportDirWrapper.cpp:304
ImportDirWrapper::getSize
virtual bufsize_t getSize()
Definition
ImportDirWrapper.cpp:355
ImportDirWrapper::loadNextEntry
virtual bool loadNextEntry(size_t cntr)
Definition
ImportDirWrapper.cpp:329
ImportDirWrapper::firstDescriptor
IMAGE_IMPORT_DESCRIPTOR * firstDescriptor()
Definition
ImportDirWrapper.cpp:313
ImportDirWrapper::ImportEntryWrapper
friend class ImportEntryWrapper
Definition
ImportDirWrapper.h:46
ImportEntryWrapper::isBound
bool isBound()
Definition
ImportDirWrapper.cpp:225
ImportEntryWrapper::FieldID
FieldID
Definition
ImportDirWrapper.h:54
ImportEntryWrapper::FIRST_THUNK
@ FIRST_THUNK
Definition
ImportDirWrapper.h:60
ImportEntryWrapper::FORWARDER
@ FORWARDER
Definition
ImportDirWrapper.h:58
ImportEntryWrapper::ORIG_FIRST_THUNK
@ ORIG_FIRST_THUNK
Definition
ImportDirWrapper.h:56
ImportEntryWrapper::NAME
@ NAME
Definition
ImportDirWrapper.h:59
ImportEntryWrapper::TIMESTAMP
@ TIMESTAMP
Definition
ImportDirWrapper.h:57
ImportEntryWrapper::getName
virtual QString getName()
Definition
ImportDirWrapper.cpp:218
ImportEntryWrapper::getLibraryName
char * getLibraryName()
Definition
ImportDirWrapper.cpp:274
ImportEntryWrapper::getFieldName
virtual QString getFieldName(size_t fieldId)
Definition
ImportDirWrapper.cpp:251
ImportEntryWrapper::loadNextEntry
bool loadNextEntry(size_t entryNum)
Definition
ImportDirWrapper.cpp:173
ImportEntryWrapper::getPtr
virtual void * getPtr()
Definition
ImportDirWrapper.cpp:190
ImportEntryWrapper::containsAddrType
virtual Executable::addr_type containsAddrType(size_t fieldId, size_t subField=FIELD_NONE)
Definition
ImportDirWrapper.cpp:263
ImportEntryWrapper::getFieldPtr
virtual void * getFieldPtr(size_t fieldId, size_t subField=FIELD_NONE)
Definition
ImportDirWrapper.cpp:235
ImportEntryWrapper::getSize
virtual bufsize_t getSize()
Definition
ImportDirWrapper.cpp:213
ImportedFuncWrapper
Definition
ImportDirWrapper.h:117
ImportedFuncWrapper::getFieldPtr
virtual void * getFieldPtr(size_t fieldId, size_t subField=FIELD_NONE)
Definition
ImportDirWrapper.cpp:121
ImportedFuncWrapper::getPtr
virtual void * getPtr()
Definition
ImportDirWrapper.cpp:6
ImportedFuncWrapper::FORWARDER
@ FORWARDER
Definition
ImportDirWrapper.h:124
ImportedFuncWrapper::HINT
@ HINT
Definition
ImportDirWrapper.h:125
ImportedFuncWrapper::ORIG_THUNK
@ ORIG_THUNK
Definition
ImportDirWrapper.h:122
ImportedFuncWrapper::THUNK
@ THUNK
Definition
ImportDirWrapper.h:123
ImportedFuncWrapper::getSize
virtual bufsize_t getSize()
Definition
ImportDirWrapper.cpp:116
ImportedFuncWrapper::containsAddrType
virtual Executable::addr_type containsAddrType(size_t fieldId, size_t subField=FIELD_NONE)
Definition
ImportDirWrapper.cpp:158
ImportedFuncWrapper::isByOrdinal
bool isByOrdinal()
Definition
ImportDirWrapper.cpp:88
ImportedFuncWrapper::getFieldName
virtual QString getFieldName(size_t fieldId)
Definition
ImportDirWrapper.cpp:147
ImportedFuncWrapper::getFunctionName
char * getFunctionName()
Definition
ImportDirWrapper.cpp:106
ImportedFuncWrapper::getValuePtr
void * getValuePtr(ImportEntryWrapper::FieldID fId)
Definition
ImportDirWrapper.cpp:44
ImportedFuncWrapper::getFieldRVA
offset_t getFieldRVA(ImportEntryWrapper::FieldID fId)
Definition
ImportDirWrapper.cpp:25
ImportedFuncWrapper::getThunkValue
uint64_t getThunkValue()
Definition
ImportDirWrapper.cpp:66
ImportedFuncWrapper::getImportByNamePtr
virtual IMAGE_IMPORT_BY_NAME * getImportByNamePtr()
Definition
ImportDirWrapper.cpp:13
ImportedFuncWrapper::getFieldSize
virtual bufsize_t getFieldSize(size_t fieldId, size_t subField=FIELD_NONE)
Definition
ImportDirWrapper.cpp:140
PENodeWrapper::m_PE
PEFile * m_PE
Definition
PENodeWrapper.h:36
imports_util
Definition
ImportBaseDirWrapper.h:10
pe_util::isStrLonger
bool isStrLonger(const char *inp, size_t maxLen)
Definition
Util.cpp:38
Generated by
1.17.0