BearParser
Portable Executable parsing library (from PE-bear)
OptHdrWrapper.cpp
Go to the documentation of this file.
1#include "pe/OptHdrWrapper.h"
2#include "pe/PEFile.h"
3
4using namespace std;
5
6std::map<DWORD, QString> OptHdrWrapper::s_optMagic;
7std::map<std::pair<WORD,WORD>, QString> OptHdrWrapper::s_osVersion;
8std::map<DWORD, QString> OptHdrWrapper::s_dllCharact;
9std::map<DWORD, QString> OptHdrWrapper::s_subsystem;
10
12{
13 if (s_dllCharact.size() == 0) {
14 s_dllCharact[pe::DLL_DYNAMIC_BASE] = "DLL can move";
15 s_dllCharact[pe::DLL_FORCE_INTEGRITY] = "Code Integrity Image";
16 s_dllCharact[pe::DLL_NX_COMPAT] = "Image is NX compatible";
17 s_dllCharact[pe::DLL_NO_ISOLATION] = "Image understands isolation and doesn't want it";
18 s_dllCharact[pe::DLL_NO_SEH] = "Image does not use SEH";
19 s_dllCharact[pe::DLL_NO_BIND] = "Do not bind this image";
20 s_dllCharact[pe::DLL_APPCONTAINER] = "AppContainer";
21 s_dllCharact[pe::DLL_WDM_DRIVER] = "Driver uses WDM model";
22 s_dllCharact[pe::DLL_GUARD_CF] = "Guard CF";
23 s_dllCharact[pe::DLL_TERMINAL_SERVER_AWARE] = "TerminalServer aware";
24 }
25}
26
28{
29 if (s_dllCharact.size() == 0) initDllCharact();
30
31 if (s_dllCharact.find(charact) == s_dllCharact.end()) return "";
32 return s_dllCharact[charact];
33}
34
35std::vector<DWORD> OptHdrWrapper::splitDllCharact(DWORD characteristics)
36{
37 if (s_dllCharact.size() == 0) initDllCharact();
38
39 std::vector<DWORD> chSet;
40 map<DWORD, QString>::iterator iter;
41 for (iter = s_dllCharact.begin(); iter != s_dllCharact.end(); iter++) {
42 if (characteristics & iter->first) {
43 chSet.push_back(iter->first);
44 }
45 }
46 return chSet;
47}
48
50{
51 if (s_optMagic.size() == 0) {
52 s_optMagic[pe::OH_NT32] = "NT32";
53 s_optMagic[pe::OH_NT64] = "NT64";
54 s_optMagic[pe::OH_ROM] = "ROM";
55 }
56 if (s_optMagic.find(p) == s_optMagic.end()) return "";
57 return s_optMagic[p];
58}
59
60QString OptHdrWrapper::translateOSVersion(WORD major, WORD minor)
61{
62 if (s_osVersion.size() == 0) {
63 s_osVersion[pair<WORD,WORD>(8, 0)] = "Windows 8";
64 s_osVersion[pair<WORD,WORD>(7, 0)] = "Windows 7";
65 s_osVersion[pair<WORD,WORD>(6, 0)] = "Windows Vista / Server 2008";
66
67 s_osVersion[pair<WORD,WORD>(5, 2)] = "Windows Server 2003";
68 s_osVersion[pair<WORD,WORD>(5, 1)] = "Windows XP";
69 s_osVersion[pair<WORD,WORD>(5, 0)] = "Windows 2000 / XP";
70
71 s_osVersion[pair<WORD,WORD>(4, 90)] = "Windows ME";
72 s_osVersion[pair<WORD,WORD>(4, 10)] = "Windows 98";
73 s_osVersion[pair<WORD,WORD>(4, 0)] = "Windows 95 / NT 4.0";
74
75 s_osVersion[pair<WORD,WORD>(3, 51)] = "Windows NT 4.51";
76 s_osVersion[pair<WORD,WORD>(3, 10)] = "Windows NT 3.1";
77 }
78 pair<WORD,WORD> p(major, minor);
79 if (s_osVersion.find(p) == s_osVersion.end()) return "";
80 return s_osVersion[p];
81}
82
83QString OptHdrWrapper::translateSubsystem(DWORD subsystem)
84{
85 if (s_subsystem.size() == 0) {
86 s_subsystem[pe::SUB_UNKNOWN] = "Unknown subsystem";
87 s_subsystem[pe::SUB_NATIVE] = "Driver";
88 s_subsystem[pe::SUB_WINDOWS_GUI] = "Windows GUI";
89 s_subsystem[pe::SUB_WINDOWS_CUI] = "Windows console";
90 s_subsystem[pe::SUB_OS2_CUI] = "OS/2 console";
91 s_subsystem[pe::SUB_POSIX_CUI] = "Posix console";
92 s_subsystem[pe::SUB_NATIVE_WINDOWS] = "Native Win9x driver";
93 s_subsystem[pe::SUB_WINDOWS_CE_GUI] = "Windows CE subsystem";
94 s_subsystem[pe::SUB_EFI_APPLICATION] = "EFI_APPLICATION";
95 s_subsystem[pe::SUB_EFI_BOOT_SERVICE_DRIVER] = "EFI_BOOT_SERVICE_DRIVER";
96 s_subsystem[pe::SUB_EFI_RUNTIME_DRIVER] = "EFI_RUNTIME_DRIVER";
97 s_subsystem[pe::SUB_EFI_ROM] = "EFI_ROM";
98 s_subsystem[pe::SUB_XBOX] = "XBOX";
99 s_subsystem[pe::SUB_WINDOWS_BOOT_APP] = "WINDOWS_BOOT_APPLICATION";
100 }
101 if (s_subsystem.find(subsystem) == s_subsystem.end()) return "";
102 return s_subsystem[subsystem];
103}
104//-------------------------------------------
106{
107 opt32 = NULL;
108 opt64 = NULL;
109 getPtr();
110 bool isOk = false;
111 DWORD charact = static_cast<DWORD>(this->getNumValue(DLL_CHARACT, &isOk));
112 this->dllCharact.clear();
113 if (isOk) {
114 this->dllCharact = this->splitDllCharact(charact);
115 }
116 return true;
117}
118
120{
121 if (m_PE == NULL) {
122 return Executable::BITS_32; // default
123 }
124 return m_PE->getHdrBitMode();
125}
126
127IMAGE_NT_HEADERS32* OptHdrWrapper::nt32()
128{
129 if (m_PE == NULL) return NULL;
130 if (getHdrBitMode() != Executable::BITS_32) return NULL;
131
132 offset_t myOff = m_PE->peNtHdrOffset();
133 IMAGE_NT_HEADERS32* hdr = (IMAGE_NT_HEADERS32*) m_Exe->getContentAt(myOff, sizeof(IMAGE_NT_HEADERS32));
134 return hdr;
135}
136
137IMAGE_NT_HEADERS64* OptHdrWrapper::nt64()
138{
139 if (m_PE == NULL) return NULL;
140 if (getHdrBitMode() != Executable::BITS_64) return NULL;
141
142 offset_t myOff = m_PE->peNtHdrOffset();
143 IMAGE_NT_HEADERS64* hdr = (IMAGE_NT_HEADERS64*) m_Exe->getContentAt(myOff, sizeof(IMAGE_NT_HEADERS64));
144 return hdr;
145}
146
147
149{
150 if (opt32 == NULL && opt64 == NULL) {
151 IMAGE_NT_HEADERS32* ntHdr32 = nt32();
152 if (ntHdr32 != NULL) {
153 this->opt32 = ntHdr32 ? &(ntHdr32->OptionalHeader) : NULL;
154 } else {
155 IMAGE_NT_HEADERS64* ntHdr64 = nt64();
156 this->opt64 = (ntHdr64) ? &(ntHdr64->OptionalHeader) : NULL;
157 }
158 }
159 void *ptr = (opt32) ? (void*) opt32 : (void*) opt64;
160 return ptr;
161}
162
164{
165 IMAGE_OPTIONAL_HEADER32* opt32 = (nt32()) ? &(nt32()->OptionalHeader) : NULL;
166 IMAGE_OPTIONAL_HEADER64* opt64 = (nt64()) ? &(nt64()->OptionalHeader) : NULL;
167 if (opt32 == NULL && opt64 == NULL) return 0;
168
169 bufsize_t size = opt32 ? sizeof(IMAGE_OPTIONAL_HEADER32) : sizeof(IMAGE_OPTIONAL_HEADER64);
170 return size;
171}
172
173bufsize_t OptHdrWrapper::getFieldSize(size_t fId, size_t subField)
174{
175 IMAGE_OPTIONAL_HEADER64* opt64 = (nt64()) ? &(nt64()->OptionalHeader) : NULL;
176 if (opt64 != NULL) {
177 if (fId == CODE_BASE) return sizeof (opt64->BaseOfCode);
178 if (fId == DATA_BASE) return 0;
179 }
180 return ExeElementWrapper::getFieldSize(fId, subField);
181}
182
183void* OptHdrWrapper::getFieldPtr(size_t fId, size_t subField)
184{
185 IMAGE_OPTIONAL_HEADER32* opt32 = (nt32()) ? &(nt32()->OptionalHeader) : NULL;
186 IMAGE_OPTIONAL_HEADER64* opt64 = (nt64()) ? &(nt64()->OptionalHeader) : NULL;
187
188 switch (fId) {
189 case MAGIC :
190 return opt32 ? (void*)&opt32->Magic : (void*)&opt64->Magic;
191
192 case LINKER_MAJOR :
193 return opt32 ? (void*)&opt32->MajorLinkerVersion : (void*)&opt64->MajorLinkerVersion;
194 case LINKER_MINOR :
195 return opt32 ? (void*)&opt32->MinorLinkerVersion : (void*)&opt64->MinorLinkerVersion;
196
197 case CODE_SIZE :
198 return opt32 ? (void*)&opt32->SizeOfCode : (void*)&opt64->SizeOfCode;
199 case INITDATA_SIZE :
200 return opt32 ? (void*)&opt32->SizeOfInitializedData : (void*)&opt64->SizeOfInitializedData;
201 case UNINITDATA_SIZE :
202 return opt32 ? (void*)&opt32->SizeOfUninitializedData : (void*)&opt64->SizeOfUninitializedData;
203 case EP :
204 return opt32 ? &opt32->AddressOfEntryPoint : (void*)&opt64->AddressOfEntryPoint;
205 case CODE_BASE :
206 return opt32 ? (void*)&opt32->BaseOfCode : (void*)&opt64->BaseOfCode;
207
208 case DATA_BASE :
209 return opt32 ? (void*)&opt32->BaseOfData : NULL;
210
211 case IMAGE_BASE :
212 return opt32 ? (void*)&opt32->ImageBase : (void*)&opt64->ImageBase;
213 case SEC_ALIGN :
214 return opt32 ? (void*)&opt32->SectionAlignment : (void*)&opt64->SectionAlignment;
215 case FILE_ALIGN :
216 return opt32 ? (void*)&opt32->FileAlignment : (void*)&opt64->FileAlignment;
217
218 case OSVER_MAJOR :
219 return opt32 ? (void*)&opt32->MajorOperatingSystemVersion : (void*)&opt64->MajorOperatingSystemVersion;
220 case OSVER_MINOR :
221 return opt32 ? (void*)&opt32->MinorOperatingSystemVersion : (void*)&opt64->MinorOperatingSystemVersion;
222
223 case IMGVER_MAJOR :
224 return opt32 ? (void*)&opt32->MajorImageVersion : (void*)&opt64->MajorImageVersion;
225 case IMGVER_MINOR:
226 return opt32 ? (void*)&opt32->MinorImageVersion : (void*)&opt64->MinorImageVersion;
227
228 case SUBSYSVER_MAJOR :
229 return opt32 ? (void*)&opt32->MajorSubsystemVersion : (void*)&opt64->MajorSubsystemVersion;
230 case SUBSYSVER_MINOR:
231 return opt32 ? (void*)&opt32->MinorSubsystemVersion : (void*)&opt64->MinorSubsystemVersion;
232
233 case WIN32_VER :
234 return opt32 ? (void*)&opt32->Win32VersionValue : (void*)&opt64->Win32VersionValue;
235 case IMAGE_SIZE :
236 return opt32 ? (void*)&opt32->SizeOfImage : (void*)&opt64->SizeOfImage;
237 case HDRS_SIZE:
238 return opt32 ? (void*)&opt32->SizeOfHeaders : (void*)&opt64->SizeOfHeaders;
239 case CHECKSUM:
240 return opt32 ? (void*)&opt32->CheckSum : (void*)&opt64->CheckSum;
241 case SUBSYS:
242 return opt32 ? (void*)&opt32->Subsystem : (void*)&opt64->Subsystem;
243 case DLL_CHARACT :
244 return opt32 ? (void*)&opt32->DllCharacteristics : (void*)&opt64->DllCharacteristics;
245 case STACK_RSRV_SIZE :
246 return opt32 ? (void*)&opt32->SizeOfStackReserve : (void*)&opt64->SizeOfStackReserve;
247 case STACK_COMMIT_SIZE :
248 return opt32 ? (void*)&opt32->SizeOfStackCommit : (void*)&opt64->SizeOfStackCommit;
249 case HEAP_RSRV_SIZE:
250 return opt32 ? (void*)&opt32->SizeOfHeapReserve : (void*)&opt64->SizeOfHeapReserve;
251 case HEAP_COMMIT_SIZE :
252 return opt32 ? (void*)&opt32->SizeOfHeapCommit : (void*)&opt64->SizeOfHeapCommit;
253 case LDR_FLAGS :
254 return opt32 ? (void*)&opt32->LoaderFlags : (void*)&opt64->LoaderFlags;
255 case RVAS_SIZES_NUM:
256 return opt32 ? (void*)&opt32->NumberOfRvaAndSizes : (void*)&opt64->NumberOfRvaAndSizes;
257 case DATA_DIR:
258 return opt32 ? (void*)&opt32->DataDirectory : (void*)&opt64->DataDirectory;
259 }
260 return this->getPtr();
261}
262
264{
265 bool isOk = false;
266 uint32_t num = -1;
267
268 switch (fieldId) {
269 case MAGIC :
270 num = static_cast<uint32_t>(this->getNumValue(fieldId, &isOk));
271 if (!isOk) return "";
272 return this->translateOptMagic(num);
273 case SUBSYS :
274 num = static_cast<uint32_t>(this->getNumValue(fieldId, &isOk));
275 if (!isOk) return "";
276 return this->translateSubsystem(num);
277 }
278 return "";
279}
280
281QString OptHdrWrapper::getFieldName(size_t fieldId)
282{
283 switch (fieldId) {
284 case MAGIC: return ("Magic");
285 case LINKER_MAJOR: return ("Linker Ver. (Major)");
286 case LINKER_MINOR: return ("Linker Ver. (Minor)");
287
288 case CODE_SIZE: return ("Size of Code");
289 case INITDATA_SIZE: return ("Size of Initialized Data");
290 case UNINITDATA_SIZE: return ("Size of Uninitialized Data");
291 case EP: return ("Entry Point");
292 case CODE_BASE: return ("Base of Code");
293 case DATA_BASE:
294 {
295 if (getHdrBitMode() == Executable::BITS_32) return ("Base of Data");
296 return "";
297 }
298 case IMAGE_BASE: return ("Image Base");
299 case SEC_ALIGN: return ("Section Alignment");
300 case FILE_ALIGN: return ("File Alignment");
301
302 case OSVER_MAJOR: return ("OS Ver. (Major)");
303 case OSVER_MINOR: return ("OS Ver. (Minor)");
304
305 case IMGVER_MAJOR: return ("Image Ver. (Major)");
306 case IMGVER_MINOR: return ("Image Ver. (Minor)");
307
308 case SUBSYSVER_MAJOR: return ("Subsystem Ver. (Major)");
309 case SUBSYSVER_MINOR: return ("Subsystem Ver. Minor)");
310
311 case WIN32_VER: return ("Win32 Version Value");
312 case IMAGE_SIZE: return ("Size of Image");
313 case HDRS_SIZE: return ("Size of Headers");
314 case CHECKSUM: return ("Checksum");
315 case SUBSYS: return ("Subsystem");
316
317 case DLL_CHARACT: return ("Dll Characteristics");
318
319 case STACK_RSRV_SIZE: return ("Size of Stack Reserve");
320 case STACK_COMMIT_SIZE: return ("Size of Stack Commit");
321 case HEAP_RSRV_SIZE: return ("Size of Heap Reserve");
322 case HEAP_COMMIT_SIZE: return ("Size of Heap Commit");
323 case LDR_FLAGS: return ("Loader Flags");
324 case RVAS_SIZES_NUM: return ("Number of RVAs and Sizes");
325 case DATA_DIR: return "Data Dir.";
326 }
327 return "";
328}
329
331{
332 switch (fieldId) {
333 case EP:
334 case CODE_BASE:
335 case DATA_BASE:
336 return Executable::RVA;
337 }
338 if (fieldId == IMAGE_BASE) {
339 return Executable::VA;
340 }
342}
343
344//-----------------------
uint32_t bufsize_t
uint64_t offset_t
virtual bufsize_t getFieldSize(size_t fieldId, size_t subField=FIELD_NONE)
virtual uint64_t getNumValue(size_t fieldId, size_t subField, bool *isOk)
BYTE * getContentAt(offset_t offset, bufsize_t size, bool allowExceptions=false)
Definition: Executable.h:57
virtual Executable::addr_type containsAddrType(size_t fieldId, size_t subField=FIELD_NONE)
static QString translateOptMagic(DWORD magic)
IMAGE_NT_HEADERS64 * nt64()
static QString translateSubsystem(DWORD subsystem)
virtual QString translateFieldContent(size_t fieldId)
static void initDllCharact()
Executable::exe_bits getHdrBitMode()
IMAGE_OPTIONAL_HEADER64 * opt64
Definition: OptHdrWrapper.h:84
static std::map< DWORD, QString > s_optMagic
Definition: OptHdrWrapper.h:45
IMAGE_OPTIONAL_HEADER32 * opt32
Definition: OptHdrWrapper.h:83
static QString translateDllCharacteristics(DWORD charact)
static QString translateOSVersion(WORD major, WORD minor)
std::vector< DWORD > dllCharact
Definition: OptHdrWrapper.h:85
IMAGE_NT_HEADERS32 * nt32()
virtual bufsize_t getFieldSize(size_t fieldId, size_t subField=FIELD_NONE)
virtual QString getFieldName(size_t fieldId)
virtual void * getPtr()
virtual bufsize_t getSize()
static std::map< DWORD, QString > s_dllCharact
Definition: OptHdrWrapper.h:47
virtual void * getFieldPtr(size_t fieldId, size_t subField=FIELD_NONE)
static std::vector< DWORD > splitDllCharact(DWORD characteristics)
static std::map< std::pair< WORD, WORD >, QString > s_osVersion
Definition: OptHdrWrapper.h:46
static std::map< DWORD, QString > s_subsystem
Definition: OptHdrWrapper.h:48
offset_t peNtHdrOffset()
Definition: PEFile.h:76
exe_bits getHdrBitMode()
Definition: PEFile.h:93