BearParser
Portable Executable parsing library (from PE-bear)
Loading...
Searching...
No Matches
LdConfigDirWrapper.cpp
Go to the documentation of this file.
2
3// offset from the beginning of the structure
4#define getStructFieldOffset(STRUCT, FIELD) ((ULONGLONG) &(STRUCT.FIELD) - (ULONGLONG)&STRUCT)
5
6bufsize_t LdConfigDirWrapper::getLdConfigDirSize()
7{
9
11 dirSize = sizeof(pe::IMAGE_LOAD_CONFIG_DIRECTORY32);
12 } else if (m_Exe->getBitMode() == Executable::BITS_64) {
13 dirSize = sizeof(pe::IMAGE_LOAD_CONFIG_DIRECTORY64);
14 }
15 return dirSize;
16}
17
18bufsize_t LdConfigDirWrapper::getHdrDefinedSize()
19{
22 try {
24 } catch (CustomException &e) {
26 }
27 if (raw == INVALID_ADDR) return 0;
28
29 offset_t offset = INVALID_ADDR;
30
32 pe::IMAGE_LOAD_CONFIG_DIRECTORY32 ld = { 0 };
33 offset = getStructFieldOffset(ld, Size);
34
35 } else if (m_Exe->getBitMode() == Executable::BITS_64) {
36 pe::IMAGE_LOAD_CONFIG_DIRECTORY64 ld = { 0 };
37 offset = getStructFieldOffset(ld, Size);
38 }
39 DWORD* sizePtr = (DWORD*) m_Exe->getContentAt((raw + offset), sizeof(DWORD));
40 if (!sizePtr) return 0;
41 return bufsize_t(*sizePtr);
42}
43
44void* LdConfigDirWrapper::getLdConfigDirPtr()
45{
48 return ptr;
49}
50
51bool LdConfigDirWrapper::wrapSubentriesTable(size_t parentFieldId, size_t counterFieldId)
52{
53 bool isOk = false;
54 size_t count = this->getNumValue(counterFieldId, &isOk);
55 if (!isOk) {
56 return false;
57 }
58 for (size_t i = 0 ; i < count; i++) {
59 LdConfigEntryWrapper *entry = new LdConfigEntryWrapper(m_Exe, this, i, parentFieldId);
60 if (!entry || !entry->getPtr()) {
61 delete entry;
62 break;
63 }
64 this->entries.push_back(entry);
65 this->subEntriesMap[parentFieldId].push_back(entry);
66 }
67 return isOk;
68}
69
71{
72 clear();
73 if (!getPtr()) return false;
74 //SEHandlerTable:
75 wrapSubentriesTable(SEH_TABLE, SEH_COUNT);
76
77 //GuardCFFunctionTable:
78 wrapSubentriesTable(GUARD_TABLE, GUARD_COUNT);
79
80 wrapSubentriesTable(GUARD_LONG_JUMP_TABLE, GUARD_LONG_JUMP_COUNT);
82
83 wrapSubentriesTable(GUARD_EH_CONT_TABLE, GUARD_EH_CONT_COUNT);
84 return true;
85}
86
88{
89 return getLdConfigDirPtr();
90}
91
93{
94 std::map<uint32_t, std::vector<ExeNodeWrapper*> >::iterator mapItr;
95 for (mapItr = this->subEntriesMap.begin(); mapItr != this->subEntriesMap.end(); ++mapItr) {
96 std::vector<ExeNodeWrapper*> &vec = mapItr->second;
97 vec.clear();
98 }
100}
101
103{
104 bool isOk = false;
105 offset_t offset = this->getNumValue(parentId, &isOk);
106 if (!isOk) return NULL;
107
109 if (aT == Executable::NOT_ADDR) return NULL;
110
111 bufsize_t handlerSize = static_cast<bufsize_t>(this->firstSubEntrySize(parentId));
112 char *ptr = (char*) m_Exe->getContentAt(offset, aT, handlerSize);
113 if (!ptr) return NULL;
114
115 return ptr;
116}
117
119{
120 //validate the offset
123 return 0;
124 }
125 const bufsize_t hdrSize = this->getHdrDefinedSize();
126 const bufsize_t structSize = getLdConfigDirSize();
128 // is the size correct
129 const offset_t rvaEnd = rva + totalSize - 1;
131 return 0;
132 }
133 return totalSize;
134}
135
136offset_t LdConfigDirWrapper::_getFieldDelta(bool is32b, size_t fId)
137{
138 static pe::IMAGE_LOAD_CONFIG_DIRECTORY32 ld32 = { 0 };
139 static pe::IMAGE_LOAD_CONFIG_DIRECTORY64 ld64 = { 0 };
140
141 //offset from the beginning of the IMAGE_LOAD_CONFIG_DIRECTORY_T strucure
143 switch (fId) {
144 case SIZE :
146 break;
147 case TIMEST :
149 break;
150 case MAJOR_VER :
152 break;
153 case MINOR_VER :
155 break;
156 case GLOBAL_FLAGS_CLEAR :
158 break;
159 case GLOBAL_FLAGS_SET :
161 break;
164 break;
165 case DECOMMIT_FREE :
167 break;
168
169 case DECOMMIT_TOTAL :
171 break;
172 case LOCK_PREFIX :
174 break;
175 case MAX_ALLOC :
177 break;
178 case VIRTUAL_MEM :
180 break;
181 case PROC_HEAP_FLAGS32 : //PROC_AFF_MASK64
182 {
184 break;
185 }
186 case PROC_AFF_MASK32 : // PROC_HEAP_FLAGS64
187 {
189 break;
190 }
191 case CSD_VER :
193 break;
196 break;
197 case EDIT_LIST :
199 break;
200 case SEC_COOKIE :
202 break;
203 case SEH_TABLE :
205 break;
206 case SEH_COUNT :
208 break;
209
210 // W8.1 part:
211 case GUARD_CHECK :
213 break;
214 case GUARD_DISPATCH :
216 break;
217 case GUARD_TABLE:
219 break;
220 case GUARD_COUNT:
222 break;
223 case GUARD_FLAGS:
225 break;
226
227 // W10 part:
230 break;
233 break;
236 break;
239 break;
242 break;
245 break;
248 break;
251 break;
254 break;
255 case CHPE_METADATA_PTR:
257 break;
260 break;
263 break;
266 break;
269 break;
270 case RESERVED2:
272 break;
275 break;
278 break;
279 case RESERVED3:
281 break;
284 break;
287 break;
290 break;
293 break;
294 }
295 return fieldOffset;
296}
297
299{
300 const bool is32b = (m_Exe->getBitMode() == Executable::BITS_32) ? true : false;
301
302 offset_t fieldDelta = _getFieldDelta(is32b, fId);
303 if (fieldDelta != INVALID_ADDR) {
304 const offset_t hdrSize = this->getHdrDefinedSize();
305 if (fieldDelta >= hdrSize) {
306 return NULL;
307 }
308 return m_Exe->getContentAt(this->getOffset() + fieldDelta, 1);
309 }
310 return NULL;
311}
312
314{
315 if (!m_Exe) return "";
316 const bool is32bit = (m_Exe->getBitMode() == Executable::BITS_32);
317 switch (fieldId) {
318 case SIZE : return "Size";
319 case TIMEST : return "TimeDateStamp";
320 case MAJOR_VER : return "MajorVersion";
321 case MINOR_VER : return "MinorVersion";
322 case GLOBAL_FLAGS_CLEAR : return "GlobalFlagsClear";
323 case GLOBAL_FLAGS_SET : return "GlobalFlagsSet";
324 case CRITICAT_SEC_TIMEOUT : return "CriticalSectionDefaultTimeout";
325 case DECOMMIT_FREE : return "DeCommitFreeBlockThreshold";
326 case DECOMMIT_TOTAL : return "DeCommitTotalFreeThreshold";
327 case LOCK_PREFIX : return "LockPrefixTable";
328 case MAX_ALLOC : return "MaximumAllocationSize";
329 case VIRTUAL_MEM : return "VirtualMemoryThreshold";
330 case PROC_HEAP_FLAGS32 : //PROC_AFF_MASK64
331 {
332 return (is32bit) ? "ProcessHeapFlags" : "ProcessAffinityMask";
333 }
334 case PROC_AFF_MASK32 : // PROC_HEAP_FLAGS64
335 {
336 return (is32bit) ? "ProcessAffinityMask" : "ProcessHeapFlags";
337 }
338 case CSD_VER : return "CSDVersion";
339 case DEPENDENT_LOAD_FLAGS : return "DependentLoadFlags";
340 case EDIT_LIST : return "EditList";
341 case SEC_COOKIE : return "SecurityCookie";
342 case SEH_TABLE : return "SEHandlerTable";
343 case SEH_COUNT : return "SEHandlerCount";
344 // W8.1 part :
345 case GUARD_CHECK : return "GuardCFCheckFunctionPtr";
346 case GUARD_DISPATCH : return "GuardCFDispatchFunctionPointer";
347 case GUARD_TABLE: return "GuardCFFunctionTable";
348 case GUARD_COUNT: return "GuardCFFunctionCount";
349 case GUARD_FLAGS: return "GuardFlags";
350 // W10 part:
351 case CODE_INTEGRITY_FLAGS: return "CodeIntegrity.Flags"; //IMAGE_LOAD_CONFIG_CODE_INTEGRITY.Flags
352 case CODE_INTEGRITY_CATALOG: return "CodeIntegrity.Catalog"; //IMAGE_LOAD_CONFIG_CODE_INTEGRITY.Catalog
353 case CODE_INTEGRITY_CATALOG_OFFSET: return "CodeIntegrity.CatalogOffset"; //IMAGE_LOAD_CONFIG_CODE_INTEGRITY.CatalogOffset
354 case CODE_INTEGRITY_RESERVED: return "CodeIntegrity.Reserved"; //IMAGE_LOAD_CONFIG_CODE_INTEGRITY.Reserved
355
356 case GUARD_ADDR_IAT_ENTRY_TABLE: return "GuardAddressTakenIatEntryTable";
357 case GUARD_ADDR_IAT_ENTRY_COUNT: return "GuardAddressTakenIatEntryCount";
358 case GUARD_LONG_JUMP_TABLE: return "GuardLongJumpTargetTable";
359 case GUARD_LONG_JUMP_COUNT: return "GuardLongJumpTargetCount";
360
361 case DYNAMIC_VAL_RELOC: return "DynamicValueRelocTable";
362 case CHPE_METADATA_PTR: return "CHPEMetadataPointer";
363 case GUARD_FAILURE_ROUTINE: return "GuardRFFailureRoutine";
364 case GUARD_FAILURE_ROUTINE_FUNC_PTR: return "GuardRFFailureRoutineFunctionPointer";
365 case DYNAMIC_VAL_RELOC_TABLE_OFFSET: return "DynamicValueRelocTableOffset";
366 case DYNAMIC_VAL_RELOC_TABLE_SECTION: return "DynamicValueRelocTableSection";
367 case RESERVED2: return "Reserved2";
368 case GUARD_VERIFY_STACK_PTR: return "GuardRFVerifyStackPointerFunctionPointer";
369 case HOT_PATCH_TABLE_OFFSET: return "HotPatchTableOffset";
370 case RESERVED3: return "Reserved3";
371 case ENCLAVE_CONFIG_PTR: return "EnclaveConfigurationPointer";
372 case VOLATILE_METADATA_PTR: return "VolatileMetadataPointer";
373 case GUARD_EH_CONT_TABLE: return "GuardEHContinuationTable";
374 case GUARD_EH_CONT_COUNT: return "GuardEHContinuationCount";
375 }
376 return getName();
377}
378
380{
381 switch (fieldId) {
382 case LOCK_PREFIX :
383 case EDIT_LIST :
384 case SEC_COOKIE :
385 case SEH_TABLE :
386 case GUARD_CHECK :
387 case GUARD_DISPATCH :
388 case GUARD_TABLE :
398 return Executable::VA;
399 }
401}
402
430
432{
434 return ("CF_INSTRUMENTED");
435 }
437 return ("CFW_INSTRUMENTED");
438 }
440 return ("CF_FUNCTION_TABLE_PRESENT");
441 }
443 return ("SECURITY_COOKIE_UNUSED");
444 }
446 return ("PROTECT_DELAYLOAD_IAT");
447 }
449 return ("DELAYLOAD_IAT_IN_ITS_OWN_SECTION");
450 }
452 return ("CF_EXPORT_SUPPRESSION_INFO_PRESENT");
453 }
455 return ("CF_ENABLE_EXPORT_SUPPRESSION");
456 }
458 return ("CF_LONGJUMP_TABLE_PRESENT");
459 }
461 return ("RF_INSTRUMENTED");
462 }
464 return ("RF_ENABLE");
465 }
467 return ("RF_STRICT");
468 }
470 return ("RETPOLINE_PRESENT");
471 }
472 return "";
473}
474
476{
477 bool isOk = false;
478 DWORD GuardFlags = this->getNumValue(GUARD_FLAGS, &isOk);
479 if (!isOk) {
480 return "-";
481 }
483 std::set<DWORD>::iterator itr;
485 for (itr = flagsSet.begin() ; itr != flagsSet.end(); ++itr) {
486 const DWORD nextFlag = *itr;
488 if (flagInfo.length() == 0) continue;
489 list.append(flagInfo);
490 }
491 return list.join(delim);
492}
493
495{
496 if (fieldId == GUARD_FLAGS) {
497 return translateGuardFlagsContent(";");;
498 }
499 return "";
500}
501//----------------
502
504{
505 if (this->parentDir == NULL) return NULL;
506
507 void* first = parentDir->firstSubEntryPtr(this->parentFieldId);
508 if (first == NULL) return NULL;
509 bufsize_t fieldSize = static_cast<bufsize_t>(parentDir->firstSubEntrySize(this->parentFieldId));
510 if (fieldSize == 0) return NULL;
511
512 offset_t offset = this->getOffset(first);
513 if (offset == INVALID_ADDR) return NULL;
514
515 //offset from the beginning:
517 offset += fieldOffset;
518 void *ptr = m_Exe->getContentAt(offset, Executable::RAW, fieldSize);
519 return ptr;
520}
521
523{
524 if (this->parentDir == NULL) return 0;
525 if (!getPtr()) return 0;
526 bufsize_t size = static_cast<bufsize_t>(parentDir->firstSubEntrySize(this->parentFieldId));
527 return size;
528}
529
531{
532 void* ptr = getPtr();
533 if (!ptr) return NULL;
534
535 if (fieldId == NONE) {
536 return ptr;
537 }
538 size_t counter = getFieldsCount();
539 if (fieldId >= counter) return NULL;
540 if (fieldId == HANDLER_ADDR) {
541 return ptr;
542 }
543 return (void*)((ULONGLONG)ptr + sizeof(DWORD));
544}
545
547{
548 size_t count = this->getFieldsCount();
549 if (fieldId >= count) {
550 return 0;
551 }
552 if (fieldId == HANDLER_ADDR) {
553 return sizeof(DWORD);
554 }
555 return sizeof(BYTE);
556}
INT_TYPE _getNumValue(void *ptr)
uint32_t bufsize_t
const offset_t INVALID_ADDR
uint64_t offset_t
#define getStructFieldOffset(STRUCT, FIELD)
offset_t getDirEntryAddress()
virtual offset_t getOffset()
virtual uint64_t getNumValue(size_t fieldId, size_t subField, bool *isOk)
std::vector< ExeNodeWrapper * > entries
virtual void clear()
virtual exe_bits getBitMode()
Definition Executable.h:49
virtual bool isValidAddr(offset_t addr, addr_type addrType)
BYTE * getContentAt(offset_t offset, bufsize_t size, bool allowExceptions=false)
Definition Executable.h:57
virtual offset_t rvaToRaw(offset_t rva)=0
virtual void * getFieldPtr(size_t fieldId, size_t subField)
virtual bufsize_t getSize()
size_t firstSubEntrySize(size_t parentId)
static QString translateGuardFlag(DWORD flags)
QString translateGuardFlagsContent(const QString &delim)
static std::set< DWORD > getGuardFlagsSet(DWORD flags)
virtual void * getPtr()
virtual QString getFieldName(size_t fieldId)
void * firstSubEntryPtr(size_t parentId)
virtual QString getName()
virtual QString translateFieldContent(size_t fieldId)
virtual Executable::addr_type containsAddrType(size_t fieldId, size_t subField=FIELD_NONE)
friend class LdConfigEntryWrapper
virtual void * getFieldPtr(size_t fieldId, size_t subField=FIELD_NONE)
virtual bufsize_t getSize()
virtual size_t getFieldsCount()
bufsize_t getFieldSize(size_t fieldId, size_t subField)
@ HANDLER_ADDR
@ NONE
virtual void * getPtr()