-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCOFFHeader.cpp
88 lines (76 loc) · 3.35 KB
/
COFFHeader.cpp
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
87
88
#include "COFFHeader.hpp"
#include "Defines.hpp"
#include "AllocationException.hpp"
COFFHeader::COFFHeader() {
}
COFFHeader::~COFFHeader() {
delete[] symbol_table_ptr;
delete[] string_table_ptr;
free(raw_string_table_ptr);
}
void COFFHeader::parse(Buffer buffer, size_t header_offset) {
// Obtain structure as defined by the documentation
nCOFF coff_struct = buffer.get<nCOFF>(header_offset);
this->machine = coff_struct.machine;
this->number_of_sections = coff_struct.number_of_sections;
this->time_stamp = coff_struct.time_stamp;
this->optional_header_size = coff_struct.optional_header_size;
this->characteristics = coff_struct.characteristics;
this->symbol_amount = coff_struct.symbol_amount;
this->symbol_table_ptr = 0;
if(coff_struct.symbol_amount != 0 && coff_struct.symbol_table_ptr != 0) {
// Initialize the string table only if the symbol table is present
uint32_t string_table_offset = coff_struct.symbol_table_ptr + (symbol_amount * sizeof(COFFSymbol::nSymbol));
uint32_t string_table_size = buffer.get<uint32_t>(string_table_offset);
if(string_table_size != 4) {
// Calculate amount of strings
uint32_t string_count = 0;
for(uint32_t current_offset = string_table_offset + 4; current_offset < string_table_offset + string_table_size;) {
char* str = current_offset + buffer.getData();
uint32_t str_len = strlen(str) + 1;
current_offset += str_len;
string_count++;
}
// Allocate string table
this->string_amount = string_count;
this->string_table_ptr = new char*[string_amount];
if(!string_table_ptr) {
throw new AllocationException();
}
// Copy string table
uint32_t i = 0;
for(uint32_t current_offset = string_table_offset + 4; current_offset < string_table_offset + string_table_size;) {
char* str = current_offset + buffer.getData();
uint32_t str_len = strlen(str) + 1;
current_offset += str_len;
string_table_ptr[i] = new char[str_len];
if(!string_table_ptr[i]) {
throw new AllocationException();
}
memcpy(string_table_ptr[i], str, str_len);
i++;
}
// Copy raw string table too
this->raw_string_table_ptr = malloc(string_table_size);
memcpy(raw_string_table_ptr, buffer.getData() + string_table_offset, string_table_size);
} else {
this->string_amount = 0;
this->string_table_ptr = new char*[0];
this->raw_string_table_ptr = malloc(0);
}
// Debugging information is present, copy it
this->symbol_table_ptr = new COFFSymbol[symbol_amount];
if(!symbol_table_ptr) {
throw new AllocationException();
}
for(uint32_t i = 0; i < symbol_amount; i++) {
symbol_table_ptr[i].parse(buffer, coff_struct.symbol_table_ptr, &i, this);
}
} else {
this->symbol_amount = 0;
this->symbol_table_ptr = new COFFSymbol[0];
this->string_amount = 0;
this->string_table_ptr = new char*[0];
this->raw_string_table_ptr = malloc(0);
}
}