BearParser
Portable Executable parsing library (from PE-bear)
Loading...
Searching...
No Matches
SectHdrsWrapper.cpp
Go to the documentation of this file.
2#include "pe/PEFile.h"
3
4using namespace buf_util;
5
6const size_t SECNAME_LEN = 8;
9
10
12{
13 this->clear();
14
15 this->header = NULL;
16 getPtr();
17 reloadName();
18 return true;
19}
20
22{
23 if (m_PE == NULL) return NULL;
24
25 if (header != NULL) {
26 return (void*) this->header;
27 }
28 //validate it above, not here...
29 //if (this->sectNum >= m_PE->hdrSectionsNum()) return NULL;
30
31 offset_t firstSecOffset = m_PE->secHdrsOffset();
32 offset_t secOffset = firstSecOffset + (this->sectNum * sizeof(IMAGE_SECTION_HEADER));
33
34 //cache the header:
35 this->header = (IMAGE_SECTION_HEADER*) m_PE->getContentAt(secOffset, sizeof(IMAGE_SECTION_HEADER));
36 return (void*) this->header;
37}
38
40{
41 IMAGE_SECTION_HEADER* header = (IMAGE_SECTION_HEADER*) getPtr();
42 if (!header) return false;
43
44 if (this->name) {
45 if (memcmp(this->name, header->Name, SECNAME_LEN) == 0) {
46 return true; //no need to reload
47 }
48 }
49 const size_t BUF_LEN = SECNAME_LEN + 2;
50
51 char *buf = new char[BUF_LEN];
52 memset(buf, 0, BUF_LEN);
53 snprintf(buf, BUF_LEN, "%.8s", (char*) header->Name);
54
55 //delete the previous pointer...
56 delete []this->name;
57 //...and set the new:
58 this->name = buf;
59 return true;
60}
61
63{
64 if (m_PE == NULL) return 0;
65 return sizeof(IMAGE_SECTION_HEADER);
66}
67
69{
70 //reloadName();
71 if (!this->name) return ""; //cannot load
72 return this->name;
73}
74
75void* SectionHdrWrapper::getFieldPtr(size_t fieldId, size_t subField)
76{
77 IMAGE_SECTION_HEADER* sec = (IMAGE_SECTION_HEADER*) getPtr();
78 if (!sec) return NULL;
79 if (!this->name) return NULL;
80 switch (fieldId)
81 {
82 case NAME: return (void*) &sec->Name;
83 case VSIZE: return (void*) &sec->Misc.VirtualSize;
84 case VPTR: return (void*) &sec->VirtualAddress;
85 case RSIZE: return (void*) &sec->SizeOfRawData;
86 case RPTR: return(void*) &sec->PointerToRawData;
87
88 case RELOC_PTR: return (void*) &sec->PointerToRelocations;
89 case RELOC_NUM: return (void*) &sec->NumberOfRelocations;
90 case LINENUM_PTR: return (void*) &sec->PointerToLinenumbers;
91 case LINENUM_NUM: return (void*) &sec->NumberOfLinenumbers;
92
93 case CHARACT: return (void*) &sec->Characteristics;
94 }
95 return this->getPtr();
96}
97
98QString SectionHdrWrapper::getFieldName(size_t fieldId)
99{
100 switch (fieldId)
101 {
102 case NAME: return "Name";
103 case VSIZE: return "Virtual Size";
104 case VPTR: return "Virtual Addr.";
105 case RSIZE: return "Raw size";
106 case RPTR: return "Raw Addr.";
107 case CHARACT: return "Characteristics";
108 case RELOC_PTR: return "Ptr to Reloc.";
109 case RELOC_NUM: return "Num. of Reloc.";
110 case LINENUM_PTR: return "Ptr to Linenum.";
111 case LINENUM_NUM: return "Num. of Linenum.";
112 }
113 return "";
114}
115
117{
118 switch (fieldId)
119 {
120 case VPTR: return Executable::RVA;
121 case RPTR: return Executable::RAW;
122 //case RELOC_PTR: return Executable::RAW;
123 }
125}
126
128{
129 if (fieldId == NAME) {
131 }
132 return WrappedValue::INT;
133}
134
135
136// offset that is declared in header
138{
139 if (this->header == NULL) return INVALID_ADDR;
140 offset_t offset = INVALID_ADDR;
141
142 if (aType == Executable::RAW) {
143 offset = static_cast<offset_t>(this->header->PointerToRawData);//(this->getNumValue(RPTR, &isOk));
144 } else if (aType == Executable::VA || aType == Executable::RVA) {
145 offset = static_cast<offset_t>(this->header->VirtualAddress);//this->getNumValue(VPTR, &isOk));
146 }
147 return offset;
148}
149
151{
152 offset_t offset = getContentDeclaredOffset(aType);
153 if (!useMapped) {
154 return offset; //returning as is
155 }
156 if (aType == Executable::RAW) {
157 const size_t peSize = m_PE->getMappedSize(aType);
158 const offset_t minAlign = m_PE->getAlignment(aType);
159 if (offset < minAlign || offset > peSize) {
160 offset = INVALID_ADDR;
161 }
162 }
163 return offset;
164}
165
167{
168 const bool useMapped = true;
169 offset_t startOffset = getContentOffset(addrType, useMapped);
170 if (startOffset == INVALID_ADDR) return INVALID_ADDR;
171
172 offset_t endOffset = static_cast<offset_t>(getContentSize(addrType, roundup)) + startOffset;
173 return endOffset;
174}
175
176// size that is declared in header
178{
179 if (this->header == NULL) return 0;
180 bufsize_t size = 0;
181
182 if (aType == Executable::RAW) {
183 size = static_cast<bufsize_t>(this->header->SizeOfRawData);//this->getNumValue(RSIZE, &isOk));
184 } else if (aType == Executable::VA || aType == Executable::RVA) {
185 size = static_cast<bufsize_t>(this->header->Misc.VirtualSize);//this->getNumValue(VSIZE, &isOk));
186 }
187 return size;
188}
189
190//RAW size that is really mapped
192{
194
195 const offset_t secOffset = getContentOffset(aType);
196 if (secOffset == INVALID_ADDR) {
197 return 0; //invalid addr, nothing is mapped
198 }
199 const bufsize_t dRawSize = getContentDeclaredSize(aType);
200 if (dRawSize == 0) {
201 return 0; // no changes
202 }
203
204 const bufsize_t peSize = m_PE->getRawSize();
205 if (secOffset > peSize) {
206 return 0; //out of scope
207 }
208 bufsize_t roundedUpSize = dRawSize;
209 bufsize_t unit = m_PE->getAlignment(aType);
210 if (unit != 0) {
211 roundedUpSize = roundupToUnit(dRawSize, unit);
212 }
213 const bufsize_t secEnd = secOffset + roundedUpSize;
214
215 //trim to the file size:
216 if (secEnd > peSize) {
217
218 const bufsize_t trimmedSize = peSize - secOffset; // trim to the file size
220
221 if (trimmedSize > virtualSize) {
222 return virtualSize;
223 }
224 return trimmedSize;
225 }
226 return roundedUpSize;
227}
228
229//VirtualSize that is really mapped
231{
233
234 const offset_t startOffset = getContentOffset(aType);
235 if (startOffset == INVALID_ADDR) {
236 return 0; //invalid addr, nothing is mapped
237 }
238
239 bufsize_t dVirtualSize = getContentDeclaredSize(aType);
240 bufsize_t mRawSize = getMappedRawSize();
241 bufsize_t mVirtualSize = (dVirtualSize > mRawSize) ? dVirtualSize : mRawSize;
242
243 bufsize_t unit = m_PE->getAlignment(aType);
244 if (unit == 0) {
245 return mRawSize; // do not roundup
246 }
247 bufsize_t size = roundupToUnit(mVirtualSize, unit);
248 return size;
249}
250
252{
253 if (this->header == NULL) return 0;
254 if (m_PE == NULL) return 0;
255
256 bufsize_t size = 0;
257 if (roundup == false) {
258 size = getContentDeclaredSize(aType);
259 //printf("Declared size = %llx\n---\n", size);
260 return size;
261 }
262 //---
263 if (aType == Executable::RAW) {
264 //printf ("R: ");
265 size = getMappedRawSize();
266 }
267 if (aType == Executable::RVA || aType == Executable::VA) {
268 size = getMappedVirtualSize();
269 //printf ("V: ");
270 }
271 //printf("Mapped size = %llx\n", size);
272 return size;
273}
274
275//-----------------------------------------------------------------------------------
276
278{
279 SectionHdrWrapper* sEntry = dynamic_cast<SectionHdrWrapper*> (entry);
280 if (sEntry == NULL) {
281 return false;
282 }
283 return true;
284}
285
287{
288 offset_t nextOffset = getNextEntryOffset();
289 bufsize_t entrySize = geEntrySize();
290 if (entrySize == 0) return false;
291
292 bufsize_t paddedSize = entrySize;
293 bool haveSpace = this->m_Exe->isAreaEmpty(nextOffset, paddedSize);
294 return haveSpace;
295}
296
298{
299 if (m_PE == NULL) return NULL;
300
301 size_t secCount = m_PE->hdrSectionsNum();
302 if (secCount == SECT_COUNT_MAX) return NULL; //limit exceeded
303
304 if (ExeNodeWrapper::addEntry(entry) == NULL) return NULL;
305
306 size_t count = secCount + 1;
307 if (m_PE->setHdrSectionsNum(count) == false) {
308 return NULL;
309 }
310 return getLastEntry();
311}
312
314{
316 this->rSec.clear();
317 this->vSec.clear();
318}
319
321{
322 SectionHdrWrapper *sec = new SectionHdrWrapper(this->m_PE, entryNum);
323 if (sec == NULL) return false;
324 if (sec->getPtr() == NULL) {
325 Logger::append(Logger::D_WARNING, "Deleting invalid section...");
326 delete sec;
327 sec = NULL;
328 return false;
329 }
330 this->entries.push_back(sec);
331 addMapping(sec);
332 return true;
333}
334
336{
337 if (sec == NULL) return;
338
339 bool roundup = true;
340 if (sec->getContentSize(Executable::RAW, true) == 0) {
341 //printf("skipping empty section..\n");
342 return;
343 }
346
347 offset_t endRVA = sec->getContentEndOffset(Executable::RVA, roundup);
348 offset_t endRaw = sec->getContentEndOffset(Executable::RAW, roundup);
349 vSec[endRVA] = sec;
350
351 if (rSec.find(endRaw) != rSec.end()) { //already exist
352 SectionHdrWrapper* prevSec = rSec[endRaw];
353 if (prevSec == NULL) return;
355 //printf("endRaw = %llX - SKIP\n", endRaw);
356 return; //skip
357 }
358 }
359 rSec[endRaw] = sec;
360 return;
361}
362
364{
365 this->rSec.clear();
366 this->vSec.clear();
367
368 size_t count = this->getEntriesCount();
369 for (size_t i = 0; i < count; i++) {
370 SectionHdrWrapper* sec = dynamic_cast<SectionHdrWrapper*>(this->getEntryAt(i));
371 if (sec == NULL) continue;
372 addMapping(sec);
373 }
374}
375
377{
378 this->clear();
379 if (this->m_PE == NULL) return false;
380
381 size_t count = this->m_PE->hdrSectionsNum();
382
383 for (size_t i = 0; i < count; i++) {
384 if (this->loadNextEntry(i) == false) break;
385 }
386 return true;
387}
388
390{
391 return this->entries.size();
392}
393
395{
396 if (entries.size() == 0) return NULL;
397 return entries[0]->getPtr();
398}
399
401{
402 if (this->m_PE == NULL) return 0;
403
404 size_t secCount = getFieldsCount();
405
406 offset_t hdrOffset = m_PE->secHdrsOffset();
407 offset_t fileSize = m_PE->getRawSize();
408 offset_t endOffset = hdrOffset + (secCount * sizeof(IMAGE_SECTION_HEADER));
409
410 if (endOffset > fileSize) {
411 return bufsize_t (fileSize - hdrOffset);
412 }
413 return bufsize_t (endOffset - hdrOffset);
414}
415/*
416void* SectHdrsWrapper::getFieldPtr(size_t fieldId, size_t subField)
417{
418 if (fieldId >= entries.size()) return NULL;
419 return entries[fieldId]->getFieldPtr(subField);
420}
421*/
422QString SectHdrsWrapper::getFieldName(size_t fieldId)
423{
424 if (fieldId >= entries.size()) return NULL;
425 return entries[fieldId]->getName();
426}
427
429{
430 size_t size = this->entries.size();
431 std::map<offset_t, SectionHdrWrapper*> *secMap = NULL;
432
433 if (addrType == Executable::RAW) {
434 secMap = &this->rSec;
435 } else if (addrType == Executable::RVA || addrType == Executable::VA) {
436 secMap = &this->vSec;
437 }
438 if (secMap == NULL) return NULL;
439
440 std::map<offset_t, SectionHdrWrapper*>::iterator found = secMap->lower_bound(offset);
441 std::map<offset_t, SectionHdrWrapper*>::iterator itr;
442 for (itr = found; itr != secMap->end(); itr++) {
443 SectionHdrWrapper* sec = itr->second;
444 if (sec == NULL) continue; //TODO: check it
445 if (verbose) {
446 printf("found [%llX] key: %llX sec: %llX %llX\n",
447 static_cast<unsigned long long>(offset),
448 static_cast<unsigned long long>(itr->first),
449 static_cast<unsigned long long>(sec->getContentOffset(addrType)),
450 static_cast<unsigned long long>(sec->getContentEndOffset(addrType, false))
451 );
452 }
453
454 offset_t startOffset = sec->getContentOffset(addrType);
455 if (startOffset == INVALID_ADDR) continue;
456
457 offset_t endOffset = sec->getContentEndOffset(addrType, roundup);
458
459 if (offset >= startOffset && offset < endOffset) {
460 return sec;
461 }
462 if (offset < startOffset) break;
463 }
464 return NULL;
465}
466
468{
469 std::map<offset_t, SectionHdrWrapper*> *secMap = NULL;
470
471 if (aType == Executable::RAW) {
472 secMap = &this->rSec;
473 } else if (aType == Executable::RVA || aType == Executable::VA) {
474 secMap = &this->vSec;
475 }
476 if (secMap == NULL) return;
477
478 std::map<offset_t, SectionHdrWrapper*>::iterator itr;
479 for (itr = secMap->begin(); itr != secMap->end(); itr++) {
480 SectionHdrWrapper* sec = itr->second;
481 offset_t secEnd = itr->first;
482
483 printf("[%llX] %s %llX %llX\n",
484 static_cast<unsigned long long>(secEnd),
485 sec->getName().toStdString().c_str(),
486 static_cast<unsigned long long>(sec->getContentOffset(aType)),
487 static_cast<unsigned long long>(sec->getContentEndOffset(aType, true))
488 );
489 }
490 printf("---\n\n");
491}
492
uint32_t bufsize_t
const offset_t INVALID_ADDR
uint64_t offset_t
const size_t SECNAME_LEN
virtual bufsize_t getContentSize()=0
bool isAreaEmpty(offset_t rawOffset, bufsize_t size)
virtual bufsize_t getContentSize()
ExeNodeWrapper * getLastEntry()
virtual ExeNodeWrapper * getEntryAt(size_t fieldId)
virtual bufsize_t geEntrySize()
std::vector< ExeNodeWrapper * > entries
virtual offset_t getNextEntryOffset()
virtual size_t getEntriesCount()
virtual void clear()
virtual ExeNodeWrapper * addEntry(ExeNodeWrapper *entry)
BYTE * getContentAt(offset_t offset, bufsize_t size, bool allowExceptions=false)
Definition: Executable.h:57
virtual offset_t getRawSize() const
Definition: Executable.h:54
virtual bufsize_t getMappedSize(Executable::addr_type aType)
Definition: PEFile.cpp:235
offset_t secHdrsOffset() const
Definition: PEFile.h:81
bool setHdrSectionsNum(size_t newNum)
Definition: PEFile.cpp:284
size_t hdrSectionsNum() const
Definition: PEFile.cpp:275
virtual bufsize_t getAlignment(Executable::addr_type aType)
Definition: PEFile.h:70
PEFile * m_PE
Definition: PENodeWrapper.h:36
std::map< offset_t, SectionHdrWrapper * > rSec
void printSectionsMapping(Executable::addr_type aType)
ExeNodeWrapper * addEntry(ExeNodeWrapper *entry)
virtual bufsize_t getSize()
virtual bool loadNextEntry(size_t entryNum)
virtual QString getFieldName(size_t fieldId)
SectionHdrWrapper * getSecHdrAtOffset(offset_t offset, Executable::addr_type addrType, bool roundup, bool verbose=false)
bool isMyEntryType(ExeNodeWrapper *entry)
virtual void reloadMapping()
virtual void * getPtr()
static size_t SECT_COUNT_MAX
std::map< offset_t, SectionHdrWrapper * > vSec
void addMapping(SectionHdrWrapper *sec)
static size_t SECT_INVALID_INDEX
virtual size_t getFieldsCount()
bufsize_t getMappedVirtualSize()
virtual QString getName()
virtual QString getFieldName(size_t fieldId)
bufsize_t getContentSize(Executable::addr_type aType, bool roundup)
offset_t getContentDeclaredOffset(Executable::addr_type aType)
virtual void * getFieldPtr(size_t fieldId, size_t subField=FIELD_NONE)
bufsize_t getContentDeclaredSize(Executable::addr_type aType)
virtual Executable::addr_type containsAddrType(size_t fieldId, size_t subField=FIELD_NONE)
offset_t getContentEndOffset(Executable::addr_type aType, bool roundup)
offset_t getContentOffset(Executable::addr_type aType, bool useMapped=true)
virtual void * getPtr()
bufsize_t getMappedRawSize()
virtual WrappedValue::data_type containsDataType(size_t fieldId, size_t subField=FIELD_NONE)
virtual bufsize_t getSize()
bool append(dbg_level lvl, const char *format,...)
Definition: Util.cpp:8
@ D_WARNING
Definition: Util.h:26
bufsize_t roundupToUnit(bufsize_t size, bufsize_t unit)