BearParser
Portable Executable parsing library (from PE-bear)
DelayImpDirWrapper.cpp
Go to the documentation of this file.
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 
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 
97  DelayImpDirWrapper *impDir = dynamic_cast<DelayImpDirWrapper*>(this->parentNode);
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 
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 
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 
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 
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());
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 
309 bufsize_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  }
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 
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 uint64_t getNumValue(size_t fieldId, size_t subField, bool *isOk)
std::vector< ExeNodeWrapper * > entries
ExeNodeWrapper * parentNode
virtual size_t getEntriesCount()
BYTE * getContentAt(offset_t offset, bufsize_t size, bool allowExceptions=false)
Definition: Executable.h:57
virtual exe_bits getBitMode()
Definition: Executable.h:49
Executable::addr_type detectAddrType(offset_t addr, Executable::addr_type hintType)
Definition: Executable.cpp:122
static bool isBit32(Executable *exe)
Definition: Executable.h:42
void addMapping(ExeNodeWrapper *func)
ImportBaseDirWrapper * impDir
PEFile * m_PE
Definition: PENodeWrapper.h:36