-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathExecutable.cpp
More file actions
86 lines (72 loc) · 2.4 KB
/
Executable.cpp
File metadata and controls
86 lines (72 loc) · 2.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include "Executable.hpp"
#include "Buffer.hpp"
#include "AllocationException.hpp"
#include "ParseException.hpp"
#include <string>
Executable::Executable() {
}
Executable::~Executable() {
delete[] msdos_stub;
delete[] signature;
delete coff_header;
delete optional_header;
delete[] section_table;
}
void Executable::parse(Buffer buffer) {
// Find some offsets and sizes
size_t signature_begin = buffer.get<uint32_t>(0x3c);
size_t signature_size = 4;
size_t msdos_begin = 0;
size_t msdos_size = signature_begin - msdos_begin;
// Initialize stub
msdos_stub = new unsigned char[msdos_size];
if(!msdos_stub) {
throw new AllocationException();
}
buffer.copyOut(msdos_begin, msdos_stub, msdos_size);
// Initialize signature
signature = new char[4];
char correct_signature[4] = "PE\0\0";
if(!signature) {
throw new AllocationException();
}
buffer.copyOut(signature_begin, signature, signature_size);
// Validate signature
if(strncmp(signature, correct_signature, 4) != 0) {
throw new ParseException(NO_SIGNATURE);
}
// Initialize coff header
size_t coff_begin = signature_begin + signature_size;
size_t coff_size = sizeof(COFFHeader::nCOFF);
coff_header = new COFFHeader();
if(!coff_header) {
throw new AllocationException();
}
coff_header->parse(buffer, coff_begin);
// Initialize optional header
size_t optional_begin = coff_begin + coff_size;
optional_header = new OptionalHeader();
if(!optional_header) {
throw new AllocationException();
}
optional_header->parse(buffer, optional_begin);
size_t optional_size = optional_header->sizeOf();
// Validate size with previous data
if(optional_size != coff_header->getOptionalHeaderSize()) {
throw new ParseException(NO_OPTSIZE);
}
// Initialize section table
size_t section_begin = optional_begin + optional_size;
size_t section_length = coff_header->getNumberOfSections();
section_table = new SectionEntry[section_length];
if(!section_table) {
throw new AllocationException();
}
// Parse section table
for(uint16_t i = 0; i < section_length; i++) {
section_table[i].parse(buffer, section_begin, &i, coff_header);
print(section_table[i].getName());
}
}
void Executable::relocate(void* address) {
}