-
Notifications
You must be signed in to change notification settings - Fork 0
/
optionhdr.c
149 lines (126 loc) · 6.37 KB
/
optionhdr.c
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
///////////////////////////////////////////////////////////////////////////////
// University of Hawaii, College of Engineering
// Lab 6 - Readpe - SRE - Spring 2023
//
// readcoff Gets the Optional_Header information in a Windows PE file
///
/// @see https://linuxcommandlibrary.com/man/readpe
///
/// @file optionhdr.c
/// @author Hubert Liang <[email protected]>
///////////////////////////////////////////////////////////////////////////////
#include <stdio.h> // For printf, perror, FILE, fopen, fread, fclose
#include <stdint.h> // For uint16_t, uint32_t
#include <string.h> // For memset
#include <assert.h> // For assert
#include "coffhdr.h" // For COFF_Header struct and function
#include "doshdr.h" // For DOS_Header struct and function
#include "optionhdr.h" // For Optional_Header struct
// Define DLL characteristics for the Optional/Image Header
#define IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE 0x0040
#define IMAGE_DLLCHARACTERISTICS_NX_COMPAT 0x0100
#define IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE 0x8000
// Validation for the Optional_Header data
void validate_optional_header(Optional_Header *opt_header) {
assert(opt_header != NULL);
// Verify the magic number (0x10b for PE32, 0x20b for PE32+)
// 0x10b (PE32) is for 32-bit executables
// 0x20b (PE32+) is for 64-bit executables
// If there are multiple... it would throw an error
assert(opt_header->Magic == 0x10b || opt_header->Magic == 0x20b);
// Additional checks for values in the Optional header
assert(opt_header->SizeOfCode > 0);
assert(opt_header->AddressOfEntryPoint > 0);
assert(opt_header->BaseOfCode > 0);
assert(opt_header->ImageBase > 0);
assert(opt_header->SectionAlignment > 0);
assert(opt_header->FileAlignment > 0);
assert(opt_header->Win32VersionValue == 0); // This field is reserved and should be 0
assert(opt_header->SizeOfImage > 0);
assert(opt_header->SizeOfHeaders > 0);
assert(opt_header->Subsystem > 0);
assert(opt_header->SizeOfStackReserve > 0);
assert(opt_header->SizeOfStackCommit > 0);
assert(opt_header->SizeOfHeapReserve > 0);
}
/* Define a function to read the Optional/Image Header */
int readoptionhdr(char *filename) {
FILE *fp;
Optional_Header optionalhdr;
COFF_Header coffhdr;
DOS_Header doshdr;
// Zero out structs for consistency
memset(&optionalhdr, 0, sizeof(optionalhdr));
memset(&doshdr, 0, sizeof(doshdr));
memset(&coffhdr, 0, sizeof(coffhdr));
fp = fopen(filename, "rb");
if (fp == NULL) {
perror("Error opening file");
return 1;
}
// Read the DOS header
if (fread(&doshdr, sizeof(doshdr), 1, fp) != 1) {
perror("Error reading DOS header");
return 1;
}
// Read the COFF header
fseek(fp, doshdr.PEOffset + 4, SEEK_SET);
if (fread(&coffhdr, sizeof(coffhdr), 1, fp) != 1) {
perror("Error reading COFF header");
return 1;
}
// Read the optional header
if (fread(&optionalhdr, sizeof(optionalhdr), 1, fp) != 1) {
perror("Error reading optional header");
return 1;
}
// Print the optional header information
// Print the optional header information
printf("Optional/Image header\n");
printf(" Magic number: 0x%x (PE32)\n", optionalhdr.Magic);
printf(" Linker major version: %d\n", optionalhdr.MajorLinkerVersion);
printf(" Linker minor version: %d\n", optionalhdr.MinorLinkerVersion);
printf(" Size of .text section: 0x%x\n", optionalhdr.SizeOfCode);
printf(" Size of .data section: 0x%x\n", optionalhdr.SizeOfInitializedData);
printf(" Size of .bss section: 0x%x\n", optionalhdr.SizeOfUninitializedData);
printf(" Entrypoint: 0x%x\n", optionalhdr.AddressOfEntryPoint);
printf(" Address of .text section: 0x%x\n", optionalhdr.BaseOfCode);
printf(" Address of .data section: 0x%x\n", optionalhdr.BaseOfData);
printf(" ImageBase: 0x%x\n", optionalhdr.ImageBase);
printf(" Alignment of sections: 0x%x\n", optionalhdr.SectionAlignment);
printf(" Alignment factor: 0x%x\n", optionalhdr.FileAlignment);
printf(" Major version of required OS: %d\n", optionalhdr.MajorOperatingSystemVersion);
printf(" Minor version of required OS: %d\n", optionalhdr.MinorOperatingSystemVersion);
printf(" Major version of image: %d\n", optionalhdr.MajorImageVersion);
printf(" Minor version of image: %d\n", optionalhdr.MinorImageVersion);
printf(" Major version of subsystem: %d\n", optionalhdr.MajorSubsystemVersion);
printf(" Minor version of subsystem: %d\n", optionalhdr.MinorSubsystemVersion);
printf(" Size of image: 0x%x\n", optionalhdr.SizeOfImage);
printf(" Size of headers: 0x%x\n", optionalhdr.SizeOfHeaders);
printf(" Checksum: 0x%x\n", optionalhdr.CheckSum);
printf(" Subsystem required: 0x%x", optionalhdr.Subsystem);
if (optionalhdr.Subsystem == 0x3) {
printf(" (IMAGE_SUBSYSTEM_WINDOWS_CUI)\n");
}
printf(" DLL characteristics: 0x%x\n", optionalhdr.DllCharacteristics);
printf(" DLL characteristics names\n");
// Print the DLL characteristics names
uint16_t dll_characteristics = optionalhdr.DllCharacteristics;
if (dll_characteristics & IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE) {
printf(" IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE\n");
}
if (dll_characteristics & IMAGE_DLLCHARACTERISTICS_NX_COMPAT) {
printf(" IMAGE_DLLCHARACTERISTICS_NX_COMPAT\n");
}
if (dll_characteristics & IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE) {
printf(" IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE\n");
}
printf(" Size of stack to reserve: 0x%x\n", optionalhdr.SizeOfStackReserve);
printf(" Size of stack to commit: 0x%x\n", optionalhdr.SizeOfStackCommit);
printf(" Size of heap space to reserve: 0x%x\n", optionalhdr.SizeOfHeapReserve);
printf(" Size of heap space to commit: 0x%x\n", optionalhdr.SizeOfHeapCommit);
// Close the file
fclose(fp);
return 0;
}
/// readoptionhdr