BearParser
Portable Executable parsing library (from PE-bear)
Loading...
Searching...
No Matches
ExceptionDirWrapper.cpp
Go to the documentation of this file.
2#include "pe/PEFile.h"
3
4/*
5typedef struct _IMAGE_IA64_RUNTIME_FUNCTION_ENTRY {
6 DWORD BeginAddress;
7 DWORD EndAddress;
8 DWORD UnwindInfoAddress;
9} IMAGE_IA64_RUNTIME_FUNCTION_ENTRY, *PIMAGE_IA64_RUNTIME_FUNCTION_ENTRY;
10*/
11
16
17
19{
20 clear();
21 parsedSize = 0;
22 bufsize_t maxSize = getDirEntrySize(true);
23 if (maxSize == 0) return false; // nothing to parse
24
25 if (!getPtr()) return false;
26
27 size_t entrySize = 0;
28 if (this->m_Exe->getArch() == Executable::ARCH_INTEL) {
29 entrySize = sizeof(IMAGE_IA64_RUNTIME_FUNCTION_ENTRY);
30 }
31 else if (this->m_Exe->getArch() == Executable::ARCH_ARM && this->m_Exe->getBitMode() == 64) {
32 entrySize = 8;
33 }
34 size_t entryId = 0;
35 while (parsedSize < maxSize) {
36 ExceptionEntryWrapper* entry = new ExceptionEntryWrapper(this->m_Exe, this, entryId++);
37
38 if (entry->getPtr() == NULL) {
39 delete entry;
40 break;
41 }
42 this->parsedSize += entrySize;
43 this->entries.push_back(entry);
44 }
46 "Entries num = %lu, parsedSize = %lX",
47 static_cast<unsigned long>(entries.size()),
48 static_cast<unsigned long>(parsedSize)
49 );
50 return true;
51}
52
54{
55 size_t entrySize = 0;
56 if (this->m_Exe->getArch() == Executable::ARCH_INTEL) {
57 entrySize = sizeof(IMAGE_IA64_RUNTIME_FUNCTION_ENTRY);
58 }
59 else if (this->m_Exe->getArch() == Executable::ARCH_ARM && this->m_Exe->getBitMode() == 64) {
60 entrySize = sizeof(uint64_t);
61 }
62 const offset_t rva = getDirEntryAddress();
63 BYTE* first = m_Exe->getContentAt(rva, Executable::RVA, entrySize);
64 if (!first || !entrySize) {
65 return NULL;
66 }
67 return first;
68}
69
70//----------------
71
73{
74 if (!this->parentDir) {
75 return NULL;
76 }
77 const size_t entrySize = _getSize();
78 void* first = parentDir->getPtr();
79 if (!first || !entrySize) {
80 return NULL;
81 }
82
83 uint64_t firstOffset = this->getOffset(first);
84 uint64_t myOffset = firstOffset + this->entryNum * entrySize;
85
86 BYTE* ptr = m_Exe->getContentAt(myOffset, Executable::RAW, entrySize);
87 return ptr;
88}
89
90bufsize_t ExceptionEntryWrapper::_getSize()
91{
92 if (this->m_Exe) {
93 if (this->m_Exe->getArch() == Executable::ARCH_INTEL) {
94 return sizeof(IMAGE_IA64_RUNTIME_FUNCTION_ENTRY);
95 }
96 if (this->m_Exe->getArch() == Executable::ARCH_ARM && this->m_Exe->getBitMode() == 64) {
97 return 8;
98 }
99 }
100 return 0;
101}
102
104{
105 if (!this->parentDir) return 0;
106 if (!this->getPtr()) return 0;
107
108 return _getSize();
109}
110
112{
113 if (this->m_Exe->getArch() == Executable::ARCH_INTEL) {
115 }
116 else if (this->m_Exe->getArch() == Executable::ARCH_ARM && this->m_Exe->getBitMode() == 64) {
118 }
119 return 0;
120}
121
122void* ExceptionEntryWrapper::getFieldPtr(size_t fieldId, size_t subField)
123{
124 void *ptr = this->getPtr();
125 if (!ptr) return nullptr;
126
127 if (this->m_Exe->getArch() == Executable::ARCH_INTEL) {
128 IMAGE_IA64_RUNTIME_FUNCTION_ENTRY* exc = (IMAGE_IA64_RUNTIME_FUNCTION_ENTRY*) ptr;
129 if (!exc) return NULL;
130
131 switch (fieldId) {
132 case BEGIN_ADDR : return &exc->BeginAddress;
133 case END_ADDR : return &exc->EndAddress;
134 case UNWIND_INFO_ADDR : return &exc->UnwindInfoAddress;
135 }
136 }
137 else if (this->m_Exe->getArch() == Executable::ARCH_ARM && this->m_Exe->getBitMode() == 64) {
139 if (!rec) return NULL;
140
141 switch (fieldId) {
142 case ARM_EXCEPT_START : return &rec->Start;
143 case ARM_EXCEPT_XDATA : return &rec->Xdata;
144 }
145 }
146 return ptr;
147}
148
150{
151 if (this->m_Exe->getArch() == Executable::ARCH_INTEL) {
152 switch (fieldId) {
153 case BEGIN_ADDR : return "BeginAddress";
154 case END_ADDR : return "EndAddress";
155 case UNWIND_INFO_ADDR : return "UnwindInfoAddress";
156 }
157 return "";
158 }
159 else if (this->m_Exe->getArch() == Executable::ARCH_ARM && this->m_Exe->getBitMode() == 64) {
160 switch (fieldId) {
161 case ARM_EXCEPT_START : return "Start";
162 case ARM_EXCEPT_XDATA : return "XData";
163 }
164 }
165 return getName();
166}
167
169{
170 if (this->m_Exe->getArch() == Executable::ARCH_INTEL) {
171 switch (fieldId) {
172 case BEGIN_ADDR :
173 case END_ADDR :
174 case UNWIND_INFO_ADDR :
175 return Executable::RVA;
176 }
177 }
178 else if (this->m_Exe->getArch() == Executable::ARCH_ARM && this->m_Exe->getBitMode() == 64) {
179
180 if (fieldId == ARM_EXCEPT_START) return Executable::RVA;
181 if (fieldId == ARM_EXCEPT_XDATA) {
183 if (!rec) return Executable::NOT_ADDR;
184
185 if (rec->Xdata & ARM_XDATA_FLAG) {
187 }
188 return Executable::RVA;
189 }
190 }
192}
uint32_t bufsize_t
uint64_t offset_t
struct _ARM_EXCEPT_RECORD ARM_EXCEPT_RECORD
#define ARM_XDATA_FLAG
bufsize_t getDirEntrySize(bool trimToExeSize=false)
offset_t getDirEntryAddress()
friend class ExceptionEntryWrapper
virtual void * getPtr()
virtual QString getName()
@ ARM_EXCEPT_FIELD_COUNTER
@ ARM_EXCEPT_XDATA
@ ARM_EXCEPT_START
virtual void * getFieldPtr(size_t fieldId, size_t subField=FIELD_NONE)
virtual size_t getFieldsCount()
virtual Executable::addr_type containsAddrType(size_t fieldId, size_t subField)
virtual QString getFieldName(size_t fieldId)
virtual bufsize_t getSize()
@ BEGIN_ADDR
@ UNWIND_INFO_ADDR
@ FIELD_COUNTER
@ END_ADDR
virtual offset_t getOffset()
std::vector< ExeNodeWrapper * > entries
virtual void clear()
virtual exe_arch getArch()=0
BYTE * getContentAt(offset_t offset, bufsize_t size, bool allowExceptions=false)
Definition Executable.h:65
bool append(dbg_level lvl, const char *format,...)
Definition Util.cpp:8
@ D_INFO
Definition Util.h:26