BearParser
Portable Executable parsing library (from PE-bear)
Toggle main menu visibility
Loading...
Searching...
No Matches
parser
pe
DelayImpDirWrapper.cpp
Go to the documentation of this file.
1
#include "
pe/DelayImpDirWrapper.h
"
2
#include "
pe/PEFile.h
"
3
4
/*
5
typedef struct _IMAGE_DELAY_LOAD {
6
DWORD grAttrs; // attributes - must be 0
7
RVA rvaDLLName; // RVA to dll name
8
RVA rvaHmod; // RVA of module handle
9
RVA rvaIAT; // RVA of the IAT
10
RVA rvaINT; // RVA of the INT
11
RVA rvaBoundIAT; // RVA of the optional bound IAT
12
RVA rvaUnloadIAT; // RVA of optional copy of original IAT
13
DWORD dwTimeStamp; // 0 if not bound,
14
// O.W. date/time stamp of DLL bound to (Old BIND)
15
} IMAGE_DELAY_LOAD, *LPIMAGE_DELAY_LOAD;
16
*/
17
18
bool
DelayImpDirWrapper::is64
()
19
{
20
if
(
m_Exe
->isBit32())
return
false
;
21
return
true
;
22
}
23
24
void
*
DelayImpDirWrapper::firstDelayLd
(
bufsize_t
size)
25
{
26
offset_t
rva =
getDirEntryAddress
();
27
28
BYTE *ptr =
m_Exe
->getContentAt(rva,
Executable::RVA
, size);
29
if
(ptr == NULL)
return
NULL;
30
31
return
ptr;
32
}
33
34
bool
DelayImpDirWrapper::loadNextEntry
(
size_t
cntr)
35
{
36
DelayImpEntryWrapper
* imp =
new
DelayImpEntryWrapper
(
m_PE
,
this
, cntr);
37
if
(!imp || !imp->
getPtr
()) {
38
delete
imp;
39
return
false
;
40
}
41
// TODO! do it in proper way!
42
bool
isOk =
false
;
43
uint64_t offset = imp->
getNumValue
(
DelayImpEntryWrapper::NAME
, &isOk);
44
if
(!isOk || offset == 0) {
45
delete
imp;
46
return
false
;
47
}
48
entries
.push_back(imp);
49
return
true
;
50
}
51
52
void
*
DelayImpDirWrapper::getPtr
()
53
{
54
bufsize_t
size =
getEntrySize
();
55
return
firstDelayLd
(size);
56
}
57
58
bufsize_t
DelayImpDirWrapper::getSize
()
59
{
60
bufsize_t
entriesNum =
static_cast<
bufsize_t
>
(this->
getEntriesCount
()) + 1;
//entries + terminating field
61
return
getEntrySize
() * entriesNum;
62
}
63
64
bufsize_t
DelayImpDirWrapper::getEntrySize
()
65
{
66
return
sizeof
(pe::IMAGE_DELAY_LOAD);
67
}
68
69
//---------------------------------------------------------------------------
70
71
IMAGE_IMPORT_BY_NAME*
DelayImpEntryWrapper::getFirstImpByNamePtr
()
72
{
73
bool
isOk =
false
;
74
uint64_t value = this->
getNumValue
(
INT
, &isOk);
75
if
(!isOk)
return
NULL;
76
77
Executable::addr_type
aT =
containsAddrType
(
INT
);
78
BYTE *ptr =
m_Exe
->getContentAt(value, aT,
sizeof
(IMAGE_IMPORT_BY_NAME));
79
return
(IMAGE_IMPORT_BY_NAME*) ptr;
80
}
81
82
bool
DelayImpEntryWrapper::loadNextEntry
(
size_t
entryNum
)
83
{
84
DelayImpFuncWrapper
* entry =
new
DelayImpFuncWrapper
(this->
m_PE
,
this
,
entryNum
);
85
if
(entry->
getPtr
() == NULL) {
86
delete
entry;
87
return
false
;
88
}
89
bool
isOk =
false
;
90
uint64_t thunk = entry->
getNumValue
(
DelayImpFuncWrapper::NAMETHUNK_ADDR
, &isOk);
91
if
(!isOk || thunk ==
INVALID_ADDR
|| thunk == 0) {
92
delete
entry;
93
return
false
;
94
}
95
this->
entries
.push_back(entry);
96
97
DelayImpDirWrapper
*
impDir
=
dynamic_cast<
DelayImpDirWrapper
*
>
(this->
parentNode
);
98
if
(
impDir
)
impDir
->addMapping(entry);
99
return
true
;
100
}
101
102
void
*
DelayImpEntryWrapper::getPtr
()
103
{
104
DelayImpDirWrapper
*parent =
dynamic_cast<
DelayImpDirWrapper
*
>
(this->
parentNode
);
105
if
(!parent) {
106
return
NULL;
107
}
108
109
const
size_t
DL_SIZE =
sizeof
(pe::IMAGE_DELAY_LOAD);
110
pe::IMAGE_DELAY_LOAD* first = (pe::IMAGE_DELAY_LOAD*) parent->
firstDelayLd
(DL_SIZE);
111
if
(!first)
return
NULL;
112
113
uint64_t descAddr = parent->
getOffset
(first);
114
if
(descAddr ==
INVALID_ADDR
)
return
NULL;
115
116
uint64_t entryOffset = descAddr + (this->
entryNum
* DL_SIZE);
117
if
(entryOffset ==
INVALID_ADDR
)
return
NULL;
118
119
BYTE *content = this->
m_Exe
->getContentAt(entryOffset,
Executable::RAW
, DL_SIZE);
120
if
(!content)
return
NULL;
121
122
return
(pe::IMAGE_DELAY_LOAD*) content;
123
}
124
125
bufsize_t
DelayImpEntryWrapper::getSize
()
126
{
127
if
(
getPtr
() == NULL)
return
0;
128
return
sizeof
(pe::IMAGE_DELAY_LOAD);
129
}
130
131
QString
DelayImpEntryWrapper::getName
()
132
{
133
char
* name =
getLibraryName
();
134
if
(!name)
return
""
;
135
return
QString(name);
136
}
137
138
char
*
DelayImpEntryWrapper::getLibraryName
()
139
{
140
bool
isOk =
false
;
141
uint64_t offset = this->
getNumValue
(
DelayImpEntryWrapper::NAME
, &isOk);
142
if
(!isOk)
return
NULL;
143
144
Executable::addr_type
aT =
containsAddrType
(
NAME
);
145
if
(aT ==
Executable::NOT_ADDR
)
return
NULL;
146
147
char
*ptr = (
char
*)
m_Exe
->getContentAt(offset, aT, 1);
148
if
(!ptr)
return
NULL;
149
150
return
ptr;
151
}
152
153
void
*
DelayImpEntryWrapper::getFieldPtr
(
size_t
fId,
size_t
subField)
154
{
155
pe::IMAGE_DELAY_LOAD* dLd = (pe::IMAGE_DELAY_LOAD*) this->
getPtr
();
156
if
(dLd == NULL)
return
NULL;
157
158
switch
(fId) {
159
case
ATTRS
:
return
&dLd->grAttrs;
160
case
NAME
:
return
&dLd->szName;
161
case
MOD
:
return
&dLd->phmod;
162
case
IAT
:
return
&dLd->pIAT;
163
case
INT
:
return
&dLd->pINT;
164
case
BOUND_IAT
:
return
&dLd->pBoundIAT;
165
case
UNLOAD_IAT
:
return
&dLd->pUnloadIAT;
166
case
TIMESTAMP
:
return
&dLd->dwTimestamp;
167
}
168
return
this->
getPtr
();
169
}
170
171
QString
DelayImpEntryWrapper::getFieldName
(
size_t
fieldId)
172
{
173
switch
(fieldId) {
174
case
ATTRS
:
return
"Attributes"
;
175
case
NAME
:
return
"Name Addr."
;
176
case
MOD
:
return
"ModuleHandle"
;
177
case
IAT
:
return
"IAT"
;
178
case
INT
:
return
"ImportNameTable"
;
179
case
BOUND_IAT
:
return
"BoundIAT"
;
180
case
UNLOAD_IAT
:
return
"UnloadIAT"
;
181
case
TIMESTAMP
:
return
"Timestamp"
;
182
}
183
return
getName
();
184
}
185
186
Executable::addr_type
DelayImpEntryWrapper::containsAddrType
(
size_t
fieldId,
size_t
subField)
187
{
188
switch
(fieldId) {
189
case
NAME
:
190
case
MOD
:
191
case
IAT
:
192
case
INT
:
193
case
BOUND_IAT
:
194
case
UNLOAD_IAT
:
195
{
196
bool
isOk =
false
;
197
uint64_t offset = this->
getNumValue
(fieldId, &isOk);
198
if
(!isOk)
return
Executable::NOT_ADDR
;
199
200
return
m_Exe
->detectAddrType(offset,
Executable::RVA
);
201
}
202
}
203
return
Executable::NOT_ADDR
;
204
}
205
206
//---------------------------------------------------------------------------
207
208
bool
DelayImpFuncWrapper::isByOrdinal
()
209
{
210
bool
isOk =
false
;
211
uint64_t addr = this->
getNumValue
(
NAMETHUNK_ADDR
, &isOk);
212
if
(!isOk || addr ==
INVALID_ADDR
)
return
false
;
213
214
if
(
isBit64
()) {
215
if
(addr & ORDINAL_FLAG64)
return
true
;
216
217
}
else
{
218
if
(addr & ORDINAL_FLAG32)
return
true
;
219
}
220
return
false
;
221
}
222
223
uint64_t
DelayImpFuncWrapper::getOrdinal
()
224
{
225
bool
isOk =
false
;
226
uint64_t addr = this->
getNumValue
(
NAMETHUNK_ADDR
, &isOk);
227
if
(!isOk || addr ==
INVALID_ADDR
)
return
INVALID_ADDR
;
228
229
size_t
fieldSize = this->ptrLen() * 8;
// in bits!
230
size_t
shiftSize = (
sizeof
(addr) - fieldSize) + 1;
231
232
uint64_t shiftedVal = (addr << shiftSize) >> shiftSize;
233
return
shiftedVal;
234
}
235
236
char
*
DelayImpFuncWrapper::getFunctionName
()
237
{
238
//check
239
if
(
isByOrdinal
() ==
true
)
return
NULL;
240
241
IMAGE_IMPORT_BY_NAME* ptr = getImportByNamePtr();
242
if
(ptr == NULL)
return
NULL;
243
244
return
(
char
*) &ptr->Name;
245
}
246
247
uint16_t
DelayImpFuncWrapper::getHint
()
248
{
249
if
(
isByOrdinal
() ==
true
)
return
0;
250
251
IMAGE_IMPORT_BY_NAME* ptr = getImportByNamePtr();
252
if
(ptr == NULL)
return
0;
253
254
return
ptr->Hint;
255
}
256
257
void
*
DelayImpFuncWrapper::getFieldPtr
(
size_t
fId,
size_t
subField)
258
{
259
if
(this->parentDir == NULL)
return
NULL;
260
261
if
(parentDir->getPtr() == NULL)
return
NULL;
262
263
uint64_t offset =
INVALID_ADDR
;
264
bool
isOk =
false
;
265
266
switch
(fId) {
267
case
NAMETHUNK_ADDR
:
268
offset = parentDir->getNumValue(
DelayImpEntryWrapper::INT
, &isOk);
break
;
269
case
IAT_ADDR
:
270
offset = parentDir->getNumValue(
DelayImpEntryWrapper::IAT
, &isOk);
break
;
271
case
BOUND_IAT_ADDR
:
272
offset = parentDir->getNumValue(
DelayImpEntryWrapper::BOUND_IAT
, &isOk);
break
;
273
case
UNLOAD_IAT_ADDR
:
274
offset = parentDir->getNumValue(
DelayImpEntryWrapper::UNLOAD_IAT
, &isOk);
break
;
275
default
:
return
getPtr
();
276
}
277
278
if
(isOk && offset !=
INVALID_ADDR
&& offset != 0) {
279
offset += (this->
entryNum
* ptrLen());
280
Executable::addr_type
aT =
m_Exe
->detectAddrType(offset,
Executable::RVA
);
281
BYTE *ptr =
m_Exe
->getContentAt(offset, aT,
static_cast<
bufsize_t
>
(ptrLen()));
282
return
ptr;
283
}
284
return
NULL;
285
}
286
287
offset_t
DelayImpFuncWrapper::callVia
()
288
{
289
bool
isOk =
false
;
290
uint64_t offset = parentDir->getNumValue(
DelayImpEntryWrapper::IAT
, &isOk);
291
if
(isOk && offset !=
INVALID_ADDR
&& offset != 0) {
292
offset += (this->
entryNum
* ptrLen());
293
return
offset;
294
}
295
return
INVALID_ADDR
;
296
}
297
298
QString
DelayImpFuncWrapper::getFieldName
(
size_t
fId)
299
{
300
switch
(fId) {
301
case
NAMETHUNK_ADDR
:
return
"Name Addr."
;
302
case
IAT_ADDR
:
return
"IAT Addr."
;
303
case
BOUND_IAT_ADDR
:
return
"Bound IAT"
;
304
case
UNLOAD_IAT_ADDR
:
return
"Unload IAT"
;
305
}
306
return
""
;
307
}
308
309
bufsize_t
DelayImpFuncWrapper::getFieldSize
(
size_t
fieldId,
size_t
subField)
310
{
311
if
(!
m_Exe
)
return
0;
312
if
(
m_Exe
->getBitMode() ==
Executable::BITS_64
) {
313
return
sizeof
(ULONGLONG);
314
}
315
return
sizeof
(DWORD);
316
}
317
318
Executable::addr_type
DelayImpFuncWrapper::containsAddrType
(
size_t
fId,
size_t
subField)
319
{
320
bool
isOk =
false
;
321
uint64_t offset = this->
getNumValue
(fId, &isOk);
322
if
(!isOk || offset ==
INVALID_ADDR
|| offset == 0)
return
Executable::NOT_ADDR
;
323
324
Executable::addr_type
aT =
m_Exe
->detectAddrType(offset,
Executable::RVA
);
325
switch
(fId) {
326
case
IAT_ADDR
:
327
case
NAMETHUNK_ADDR
:
328
case
BOUND_IAT_ADDR
:
329
case
UNLOAD_IAT_ADDR
:
330
return
aT;
331
}
332
return
Executable::NOT_ADDR
;
333
}
334
335
IMAGE_IMPORT_BY_NAME* DelayImpFuncWrapper::getImportByNamePtr()
336
{
337
bool
isOk =
false
;
338
uint64_t addr = this->
getNumValue
(
NAMETHUNK_ADDR
, &isOk);
339
if
(!isOk || addr ==
INVALID_ADDR
)
return
NULL;
340
341
Executable::addr_type
aT =
m_Exe
->
detectAddrType
(addr,
Executable::RVA
);
342
BYTE *ptr =
m_Exe
->
getContentAt
(addr, aT,
sizeof
(IMAGE_IMPORT_BY_NAME));
343
return
(IMAGE_IMPORT_BY_NAME*) ptr;
344
}
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
DelayImpDirWrapper.h
PEFile.h
DataDirEntryWrapper::getDirEntryAddress
offset_t getDirEntryAddress()
Definition
DataDirEntryWrapper.cpp:19
DelayImpDirWrapper::getEntrySize
bufsize_t getEntrySize()
Definition
DelayImpDirWrapper.cpp:64
DelayImpDirWrapper::firstDelayLd
pe::IMAGE_DELAY_LOAD * firstDelayLd()
Definition
DelayImpDirWrapper.h:24
DelayImpDirWrapper::loadNextEntry
virtual bool loadNextEntry(size_t cntr)
Definition
DelayImpDirWrapper.cpp:34
DelayImpDirWrapper::getSize
virtual bufsize_t getSize()
Definition
DelayImpDirWrapper.cpp:58
DelayImpDirWrapper::DelayImpEntryWrapper
friend class DelayImpEntryWrapper
Definition
DelayImpDirWrapper.h:28
DelayImpDirWrapper::getPtr
virtual void * getPtr()
Definition
DelayImpDirWrapper.cpp:52
DelayImpDirWrapper::is64
bool is64()
Definition
DelayImpDirWrapper.cpp:18
DelayImpEntryWrapper::DelayImpDirWrapper
friend class DelayImpDirWrapper
Definition
DelayImpDirWrapper.h:68
DelayImpEntryWrapper::getFieldPtr
virtual void * getFieldPtr(size_t fieldId, size_t subField)
Definition
DelayImpDirWrapper.cpp:153
DelayImpEntryWrapper::getFieldName
virtual QString getFieldName(size_t fieldId)
Definition
DelayImpDirWrapper.cpp:171
DelayImpEntryWrapper::containsAddrType
virtual Executable::addr_type containsAddrType(size_t fieldId, size_t subField=FIELD_NONE)
Definition
DelayImpDirWrapper.cpp:186
DelayImpEntryWrapper::getLibraryName
virtual char * getLibraryName()
Definition
DelayImpDirWrapper.cpp:138
DelayImpEntryWrapper::getPtr
virtual void * getPtr()
Definition
DelayImpDirWrapper.cpp:102
DelayImpEntryWrapper::getSize
virtual bufsize_t getSize()
Definition
DelayImpDirWrapper.cpp:125
DelayImpEntryWrapper::getFirstImpByNamePtr
virtual IMAGE_IMPORT_BY_NAME * getFirstImpByNamePtr()
Definition
DelayImpDirWrapper.cpp:71
DelayImpEntryWrapper::TIMESTAMP
@ TIMESTAMP
Definition
DelayImpDirWrapper.h:43
DelayImpEntryWrapper::BOUND_IAT
@ BOUND_IAT
Definition
DelayImpDirWrapper.h:41
DelayImpEntryWrapper::UNLOAD_IAT
@ UNLOAD_IAT
Definition
DelayImpDirWrapper.h:42
DelayImpEntryWrapper::IAT
@ IAT
Definition
DelayImpDirWrapper.h:39
DelayImpEntryWrapper::MOD
@ MOD
Definition
DelayImpDirWrapper.h:38
DelayImpEntryWrapper::ATTRS
@ ATTRS
Definition
DelayImpDirWrapper.h:36
DelayImpEntryWrapper::NAME
@ NAME
Definition
DelayImpDirWrapper.h:37
DelayImpEntryWrapper::INT
@ INT
Definition
DelayImpDirWrapper.h:40
DelayImpEntryWrapper::loadNextEntry
bool loadNextEntry(size_t entryNum)
Definition
DelayImpDirWrapper.cpp:82
DelayImpEntryWrapper::DelayImpFuncWrapper
friend class DelayImpFuncWrapper
Definition
DelayImpDirWrapper.h:67
DelayImpEntryWrapper::getName
virtual QString getName()
Definition
DelayImpDirWrapper.cpp:131
DelayImpFuncWrapper::getFunctionName
char * getFunctionName()
Definition
DelayImpDirWrapper.cpp:236
DelayImpFuncWrapper::containsAddrType
virtual Executable::addr_type containsAddrType(size_t fieldId, size_t subField)
Definition
DelayImpDirWrapper.cpp:318
DelayImpFuncWrapper::isByOrdinal
bool isByOrdinal()
Definition
DelayImpDirWrapper.cpp:208
DelayImpFuncWrapper::BOUND_IAT_ADDR
@ BOUND_IAT_ADDR
Definition
DelayImpDirWrapper.h:79
DelayImpFuncWrapper::IAT_ADDR
@ IAT_ADDR
Definition
DelayImpDirWrapper.h:78
DelayImpFuncWrapper::NAMETHUNK_ADDR
@ NAMETHUNK_ADDR
Definition
DelayImpDirWrapper.h:77
DelayImpFuncWrapper::UNLOAD_IAT_ADDR
@ UNLOAD_IAT_ADDR
Definition
DelayImpDirWrapper.h:80
DelayImpFuncWrapper::getFieldSize
virtual bufsize_t getFieldSize(size_t fieldId, size_t subField=FIELD_NONE)
Definition
DelayImpDirWrapper.cpp:309
DelayImpFuncWrapper::getOrdinal
virtual uint64_t getOrdinal()
Definition
DelayImpDirWrapper.cpp:223
DelayImpFuncWrapper::getFieldName
virtual QString getFieldName(size_t fieldId)
Definition
DelayImpDirWrapper.cpp:298
DelayImpFuncWrapper::getFieldPtr
virtual void * getFieldPtr(size_t fieldId, size_t subField=FIELD_NONE)
Definition
DelayImpDirWrapper.cpp:257
DelayImpFuncWrapper::getHint
uint16_t getHint()
Definition
DelayImpDirWrapper.cpp:247
DelayImpFuncWrapper::getPtr
virtual void * getPtr()
Definition
DelayImpDirWrapper.h:88
DelayImpFuncWrapper::callVia
offset_t callVia()
Definition
DelayImpDirWrapper.cpp:287
ExeElementWrapper::isBit64
bool isBit64()
Definition
ExeElementWrapper.h:58
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::parentNode
ExeNodeWrapper * parentNode
Definition
ExeNodeWrapper.h:53
ExeNodeWrapper::getEntriesCount
virtual size_t getEntriesCount()
Definition
ExeNodeWrapper.h:20
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
Executable::getContentAt
BYTE * getContentAt(offset_t offset, bufsize_t size, bool allowExceptions=false)
Definition
Executable.h:67
Executable::detectAddrType
Executable::addr_type detectAddrType(offset_t addr, Executable::addr_type hintType)
Definition
Executable.cpp:125
ImportBaseEntryWrapper::impDir
ImportBaseDirWrapper * impDir
Definition
ImportBaseDirWrapper.h:86
PENodeWrapper::m_PE
PEFile * m_PE
Definition
PENodeWrapper.h:36
Generated by
1.17.0