blob: 56996fee82ee2290d7f42697359b1f56caf8a921 [file] [log] [blame]
Samuel Huang06f1ae92018-03-13 18:19:34 +00001// Copyright 2017 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef COMPONENTS_ZUCCHINI_TYPE_WIN_PE_H_
6#define COMPONENTS_ZUCCHINI_TYPE_WIN_PE_H_
7
8#include <stddef.h>
9#include <stdint.h>
10
11namespace zucchini {
12
13// Structures and constants taken from WINNT.h and following identical layout.
14// This is used for parsing of Portable Executable (PE) file format.
15namespace pe {
16// Supported by MSVC, g++, and clang++. Ensures no gaps in packing.
17#pragma pack(push, 1)
18
19// IMAGE_NUMBEROF_DIRECTORY_ENTRIES
20constexpr size_t kImageNumberOfDirectoryEntries = 16;
21
22// IMAGE_FILE_BASE_RELOCATION_TABLE
23constexpr size_t kIndexOfBaseRelocationTable = 5;
24
25constexpr uint32_t kImageScnMemExecute = 0x20000000; // IMAGE_SCN_MEM_EXECUTE
26constexpr uint32_t kImageScnMemRead = 0x40000000; // IMAGE_SCN_MEM_READ
27
28// IMAGE_DOS_HEADER
29struct ImageDOSHeader {
30 uint16_t e_magic; // 0x00
31 uint16_t e_cblp;
32 uint16_t e_cp;
33 uint16_t e_crlc;
34 uint16_t e_cparhdr;
35 uint16_t e_minalloc;
36 uint16_t e_maxalloc;
37 uint16_t e_ss;
38 uint16_t e_sp; // 0x10
39 uint16_t e_csum;
40 uint16_t e_ip;
41 uint16_t e_cs;
42 uint16_t e_lfarlc;
43 uint16_t e_ovno;
44 uint16_t e_res[4];
45 uint16_t e_oemid; // 0x24
46 uint16_t e_oeminfo;
47 uint16_t e_res2[10];
48 uint32_t e_lfanew; // 0x3C
49};
50static_assert(sizeof(ImageDOSHeader) == 0x40,
51 "DOS header size should be 0x40 bytes");
52
53// IMAGE_SECTION_HEADER
54struct ImageSectionHeader {
55 char name[8];
56 uint32_t virtual_size;
57 uint32_t virtual_address;
58 uint32_t size_of_raw_data;
59 uint32_t file_offset_of_raw_data;
60 uint32_t pointer_to_relocations; // Always zero in an image.
61 uint32_t pointer_to_line_numbers; // Always zero in an image.
62 uint16_t number_of_relocations; // Always zero in an image.
63 uint16_t number_of_line_numbers; // Always zero in an image.
64 uint32_t characteristics;
65};
66static_assert(sizeof(ImageSectionHeader) == 0x28,
67 "Section header size should be 0x28 bytes");
68
69// IMAGE_DATA_DIRECTORY
70struct ImageDataDirectory {
71 uint32_t virtual_address;
72 uint32_t size;
73};
74static_assert(sizeof(ImageDataDirectory) == 0x08,
75 "Data directory size should be 0x08 bytes");
76
77// IMAGE_FILE_HEADER
78struct ImageFileHeader {
79 uint16_t machine;
80 uint16_t number_of_sections;
81 uint32_t time_date_stamp;
82 uint32_t pointer_to_symbol_table;
83 uint32_t number_of_symbols;
84 uint16_t size_of_optional_header;
85 uint16_t characteristics;
86};
87static_assert(sizeof(ImageFileHeader) == 0x14,
88 "File header size should be 0x14 bytes");
89
90// IMAGE_OPTIONAL_HEADER
91struct ImageOptionalHeader {
92 uint16_t magic; // 0x00: 0x10B
93 uint8_t major_linker_version;
94 uint8_t minor_linker_version;
95 uint32_t size_of_code;
96 uint32_t size_of_initialized_data;
97 uint32_t size_of_uninitialized_data;
98 uint32_t address_of_entry_point; // 0x10
99 uint32_t base_of_code;
100 uint32_t base_of_data;
101
102 uint32_t image_base;
103 uint32_t section_alignment; // 0x20
104 uint32_t file_alignment;
105 uint16_t major_operating_system_version;
106 uint16_t minor_operating_system_version;
107 uint16_t major_image_version;
108 uint16_t minor_image_version;
109 uint16_t major_subsystem_version; // 0x30
110 uint16_t minor_subsystem_version;
111 uint32_t win32_version_value;
112 uint32_t size_of_image;
113 uint32_t size_of_headers;
114 uint32_t check_sum; // 0x40
115 uint16_t subsystem;
116 uint16_t dll_characteristics;
117 uint32_t size_of_stack_reserve;
118 uint32_t size_of_stack_commit;
119 uint32_t size_of_heap_reserve; // 0x50
120 uint32_t size_of_heap_commit;
121 uint32_t loader_flags;
122 uint32_t number_of_rva_and_sizes;
Samuel Huang431d1192018-12-31 19:59:22 +0000123
124 // The number of elements is actually |number_of_rva_and_sizes|, so accesses
125 // to |data_directory| should be checked against the bound.
Samuel Huang06f1ae92018-03-13 18:19:34 +0000126 ImageDataDirectory data_directory[kImageNumberOfDirectoryEntries]; // 0x60
127 /* 0xE0 */
128};
129static_assert(sizeof(ImageOptionalHeader) == 0xE0,
130 "Optional header (32) size should be 0xE0 bytes");
131
132// IMAGE_OPTIONAL_HEADER64
133struct ImageOptionalHeader64 {
134 uint16_t magic; // 0x00: 0x20B
135 uint8_t major_linker_version;
136 uint8_t minor_linker_version;
137 uint32_t size_of_code;
138 uint32_t size_of_initialized_data;
139 uint32_t size_of_uninitialized_data;
140 uint32_t address_of_entry_point; // 0x10
141 uint32_t base_of_code;
142
143 uint64_t image_base;
144 uint32_t section_alignment; // 0x20
145 uint32_t file_alignment;
146 uint16_t major_operating_system_version;
147 uint16_t minor_operating_system_version;
148 uint16_t major_image_version;
149 uint16_t minor_image_version;
150 uint16_t major_subsystem_version; // 0x30
151 uint16_t minor_subsystem_version;
152 uint32_t win32_version_value;
153 uint32_t size_of_image;
154 uint32_t size_of_headers;
155 uint32_t check_sum; // 0x40
156 uint16_t subsystem;
157 uint16_t dll_characteristics;
158 uint64_t size_of_stack_reserve;
159 uint64_t size_of_stack_commit; // 0x50
160 uint64_t size_of_heap_reserve;
161 uint64_t size_of_heap_commit; // 0x60
162 uint32_t loader_flags;
163 uint32_t number_of_rva_and_sizes;
164 ImageDataDirectory data_directory[kImageNumberOfDirectoryEntries]; // 0x70
165 /* 0xF0 */
166};
167static_assert(sizeof(ImageOptionalHeader64) == 0xF0,
168 "Optional header (64) size should be 0xF0 bytes");
169
170struct RelocHeader {
171 uint32_t rva_hi;
172 uint32_t size;
173};
174static_assert(sizeof(RelocHeader) == 8, "RelocHeader size should be 8 bytes");
175
176#pragma pack(pop)
177
178} // namespace pe
179
180// Constants and offsets gleaned from WINNT.h and various articles on the
181// format of Windows PE executables.
182
183constexpr char const* kTextSectionName = ".text";
184
185// Bitfield with characteristics usually associated with code sections.
186const uint32_t kCodeCharacteristics =
187 pe::kImageScnMemExecute | pe::kImageScnMemRead;
188
189} // namespace zucchini
190
191#endif // COMPONENTS_ZUCCHINI_TYPE_WIN_PE_H_