BearParser
Portable Executable parsing library (from PE-bear)
Loading...
Searching...
No Matches
DelayImpDirWrapper.cpp
Go to the documentation of this file.
2#include "pe/PEFile.h"
3
4/*
5typedef 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
19{
20 if (m_Exe->isBit32()) return false;
21 return true;
22}
23
25{
27
28 BYTE *ptr = m_Exe->getContentAt(rva, Executable::RVA, size);
29 if (ptr == NULL) return NULL;
30
31 return ptr;
32}
33
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
53{
54 bufsize_t size = getEntrySize();
55 return firstDelayLd(size);
56}
57
59{
60 bufsize_t entriesNum = static_cast<bufsize_t>(this->getEntriesCount()) + 1; //entries + terminating field
61 return getEntrySize() * entriesNum;
62}
63
65{
66 return sizeof(pe::IMAGE_DELAY_LOAD);
67}
68
69//---------------------------------------------------------------------------
70
72{
73 bool isOk = false;
74 uint64_t value = this->getNumValue(INT, &isOk);
75 if(!isOk) return NULL;
76
78 BYTE *ptr = m_Exe->getContentAt(value, aT, sizeof(IMAGE_IMPORT_BY_NAME));
79 return (IMAGE_IMPORT_BY_NAME*) ptr;
80}
81
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
98 if (impDir) impDir->addMapping(entry);
99 return true;
100 }
101
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
126{
127 if (getPtr() == NULL) return 0;
128 return sizeof(pe::IMAGE_DELAY_LOAD);
129}
130
132{
133 char* name = getLibraryName();
134 if (!name) return "";
135 return QString(name);
136}
137
139{
140 bool isOk = false;
141 uint64_t offset = this->getNumValue(DelayImpEntryWrapper::NAME, &isOk);
142 if (!isOk) return NULL;
143
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
153void* 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
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
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 }
204}
205
206//---------------------------------------------------------------------------
207
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
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
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
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
257void* 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());
281 BYTE *ptr = m_Exe->getContentAt(offset, aT, static_cast<bufsize_t>(ptrLen()));
282 return ptr;
283 }
284 return NULL;
285}
286
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
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
309bufsize_t DelayImpFuncWrapper::getFieldSize(size_t fieldId, size_t subField)
310{
311 if (!m_Exe) return 0;
313 return sizeof (ULONGLONG);
314 }
315 return sizeof (DWORD);
316}
317
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
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 }
333}
334
335IMAGE_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
342 BYTE *ptr = m_Exe->getContentAt(addr, aT, sizeof(IMAGE_IMPORT_BY_NAME));
343 return (IMAGE_IMPORT_BY_NAME*) ptr;
344}
uint32_t bufsize_t
const offset_t INVALID_ADDR
uint64_t offset_t
offset_t getDirEntryAddress()
pe::IMAGE_DELAY_LOAD * firstDelayLd()
virtual bool loadNextEntry(size_t cntr)
virtual bufsize_t getSize()
friend class DelayImpEntryWrapper
virtual void * getPtr()
virtual void * getFieldPtr(size_t fieldId, size_t subField)
virtual QString getFieldName(size_t fieldId)
virtual Executable::addr_type containsAddrType(size_t fieldId, size_t subField=FIELD_NONE)
virtual char * getLibraryName()
virtual void * getPtr()
virtual bufsize_t getSize()
virtual IMAGE_IMPORT_BY_NAME * getFirstImpByNamePtr()
@ TIMESTAMP
@ BOUND_IAT
@ UNLOAD_IAT
@ IAT
@ MOD
@ ATTRS
@ NAME
@ INT
bool loadNextEntry(size_t entryNum)
friend class DelayImpFuncWrapper
virtual QString getName()
virtual Executable::addr_type containsAddrType(size_t fieldId, size_t subField)
virtual bufsize_t getFieldSize(size_t fieldId, size_t subField=FIELD_NONE)
virtual uint64_t getOrdinal()
virtual QString getFieldName(size_t fieldId)
virtual void * getFieldPtr(size_t fieldId, size_t subField=FIELD_NONE)
virtual void * getPtr()
virtual offset_t getOffset()
virtual uint64_t getNumValue(size_t fieldId, size_t subField, bool *isOk)
std::vector< ExeNodeWrapper * > entries
ExeNodeWrapper * parentNode
virtual size_t getEntriesCount()
virtual exe_bits getBitMode()
Definition Executable.h:56
BYTE * getContentAt(offset_t offset, bufsize_t size, bool allowExceptions=false)
Definition Executable.h:65
Executable::addr_type detectAddrType(offset_t addr, Executable::addr_type hintType)
static bool isBit32(Executable *exe)
Definition Executable.h:49
void addMapping(ExeNodeWrapper *func)
ImportBaseDirWrapper * impDir