BearParser
Portable Executable parsing library (from PE-bear)
Loading...
Searching...
No Matches
ImportDirWrapper.cpp
Go to the documentation of this file.
2#include "pe/PEFile.h"
3
4using namespace imports_util;
5
12
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
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
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
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
89{
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
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
120
121void* ImportedFuncWrapper::getFieldPtr(size_t fId, size_t subField)
122{
123 void *entryPtr = this->getPtr();
124 if (entryPtr == NULL) return NULL;
125
126 switch (fId) {
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
140bufsize_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
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
159{
160 if (this->isByOrdinal()) {
162 }
163 switch (fId) {
164 case ORIG_THUNK:
165 case THUNK:
166 return Executable::RVA;
167 }
169}
170//-------------------------------------------------------------------------------
171
172
174 {
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
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
214{
215 return sizeof(IMAGE_IMPORT_DESCRIPTOR);
216}
217
219{
220 char *name = getLibraryName();
221 if (!name) return "";
222 return name;
223}
224
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
235void* 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
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
264{
265 switch (fId) {
266 case ORIG_FIRST_THUNK:
267 case NAME:
268 case FIRST_THUNK:
269 return Executable::RVA;
270 }
272}
273
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);
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
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
313IMAGE_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
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
356{
357 size_t fields = getFieldsCount() + 1; //fields + terminating field
358 return static_cast<bufsize_t>(fields) * sizeof(IMAGE_IMPORT_DESCRIPTOR);
359}
360
uint32_t bufsize_t
const offset_t INVALID_ADDR
uint64_t offset_t
bufsize_t getMaxSizeFromPtr(BYTE *ptr)
virtual uint64_t getNumValue(size_t fieldId, size_t subField, bool *isOk)
std::vector< ExeNodeWrapper * > entries
ExeNodeWrapper * parentNode
virtual exe_bits getBitMode()
Definition Executable.h:56
virtual offset_t toRaw(offset_t offset, addr_type addrType, bool allowExceptions=false)
BYTE * getContentAt(offset_t offset, bufsize_t size, bool allowExceptions=false)
Definition Executable.h:65
virtual offset_t getRawSize() const
Definition Executable.h:62
virtual size_t getFieldsCount()
static bufsize_t NameLenLimit
void addMapping(ExeNodeWrapper *func)
IMAGE_DATA_DIRECTORY * getDataDirectory()
virtual bufsize_t getSize()
virtual bool loadNextEntry(size_t cntr)
IMAGE_IMPORT_DESCRIPTOR * firstDescriptor()
friend class ImportEntryWrapper
bool isBound()
FieldID
@ FIRST_THUNK
@ FORWARDER
@ ORIG_FIRST_THUNK
@ NAME
@ TIMESTAMP
virtual QString getName()
char * getLibraryName()
virtual QString getFieldName(size_t fieldId)
bool loadNextEntry(size_t entryNum)
virtual void * getPtr()
virtual Executable::addr_type containsAddrType(size_t fieldId, size_t subField=FIELD_NONE)
virtual void * getFieldPtr(size_t fieldId, size_t subField=FIELD_NONE)
virtual bufsize_t getSize()
virtual void * getFieldPtr(size_t fieldId, size_t subField=FIELD_NONE)
virtual void * getPtr()
virtual bufsize_t getSize()
virtual Executable::addr_type containsAddrType(size_t fieldId, size_t subField=FIELD_NONE)
virtual QString getFieldName(size_t fieldId)
void * getValuePtr(ImportEntryWrapper::FieldID fId)
offset_t getFieldRVA(ImportEntryWrapper::FieldID fId)
virtual IMAGE_IMPORT_BY_NAME * getImportByNamePtr()
virtual bufsize_t getFieldSize(size_t fieldId, size_t subField=FIELD_NONE)
IMAGE_DATA_DIRECTORY * getDataDirectory()
Definition PEFile.cpp:292
bool isStrLonger(const char *inp, size_t maxLen)
Definition Util.cpp:38