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 size_t entrySize = 0;
78 if (this->m_Exe->getArch() == Executable::ARCH_INTEL) {
79 entrySize = sizeof(IMAGE_IA64_RUNTIME_FUNCTION_ENTRY);
80 }
81 else if (this->m_Exe->getArch() == Executable::ARCH_ARM && this->m_Exe->getBitMode() == 64) {
82 entrySize = 8;
83 }
84 void* first = parentDir->getPtr();
85 if (!first || !entrySize) {
86 return NULL;
87 }
88
89 uint64_t firstOffset = this->getOffset(first);
90 uint64_t myOffset = firstOffset + this->entryNum * entrySize;
91
92 BYTE* ptr = m_Exe->getContentAt(myOffset, Executable::RAW, entrySize);
93 return ptr;
94}
95
97{
98 if (!this->parentDir) return 0;
99 if (!this->getPtr()) return 0;
100
101 if (this->m_Exe->getArch() == Executable::ARCH_INTEL) {
102 return sizeof(IMAGE_IA64_RUNTIME_FUNCTION_ENTRY);
103 }
104 if (this->m_Exe->getArch() == Executable::ARCH_ARM && this->m_Exe->getBitMode() == 64) {
105 return 8;
106 }
107 return 0;
108}
109
111{
112 if (this->m_Exe->getArch() == Executable::ARCH_INTEL) {
114 }
115 else if (this->m_Exe->getArch() == Executable::ARCH_ARM && this->m_Exe->getBitMode() == 64) {
117 }
118 return 0;
119}
120
121void* ExceptionEntryWrapper::getFieldPtr(size_t fieldId, size_t subField)
122{
123 void *ptr = this->getPtr();
124 if (!ptr) return nullptr;
125
126 if (this->m_Exe->getArch() == Executable::ARCH_INTEL) {
127 IMAGE_IA64_RUNTIME_FUNCTION_ENTRY* exc = (IMAGE_IA64_RUNTIME_FUNCTION_ENTRY*) ptr;
128 if (!exc) return NULL;
129
130 switch (fieldId) {
131 case BEGIN_ADDR : return &exc->BeginAddress;
132 case END_ADDR : return &exc->EndAddress;
133 case UNWIND_INFO_ADDR : return &exc->UnwindInfoAddress;
134 }
135 }
136 else if (this->m_Exe->getArch() == Executable::ARCH_ARM && this->m_Exe->getBitMode() == 64) {
138 if (!rec) return NULL;
139
140 switch (fieldId) {
141 case ARM_EXCEPT_START : return &rec->Start;
142 case ARM_EXCEPT_XDATA : return &rec->Xdata;
143 }
144 }
145 return ptr;
146}
147
149{
150 if (this->m_Exe->getArch() == Executable::ARCH_INTEL) {
151 switch (fieldId) {
152 case BEGIN_ADDR : return "BeginAddress";
153 case END_ADDR : return "EndAddress";
154 case UNWIND_INFO_ADDR : return "UnwindInfoAddress";
155 }
156 return "";
157 }
158 else if (this->m_Exe->getArch() == Executable::ARCH_ARM && this->m_Exe->getBitMode() == 64) {
159 switch (fieldId) {
160 case ARM_EXCEPT_START : return "Start";
161 case ARM_EXCEPT_XDATA : return "XData";
162 }
163 }
164 return getName();
165}
166
168{
169 if (this->m_Exe->getArch() == Executable::ARCH_INTEL) {
170 switch (fieldId) {
171 case BEGIN_ADDR :
172 case END_ADDR :
173 case UNWIND_INFO_ADDR :
174 return Executable::RVA;
175 }
176 }
177 else if (this->m_Exe->getArch() == Executable::ARCH_ARM && this->m_Exe->getBitMode() == 64) {
178
179 if (fieldId == ARM_EXCEPT_START) return Executable::RVA;
180 if (fieldId == ARM_EXCEPT_XDATA) {
182 if (!rec) return Executable::NOT_ADDR;
183
184 if (rec->Xdata & ARM_XDATA_FLAG) {
186 }
187 return Executable::RVA;
188 }
189
190 }
192}
193
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_bits getBitMode()
Definition Executable.h:56
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