• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // 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 
11 namespace 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.
15 namespace pe {
16 // Supported by MSVC, g++, and clang++. Ensures no gaps in packing.
17 #pragma pack(push, 1)
18 
19 // IMAGE_NUMBEROF_DIRECTORY_ENTRIES
20 constexpr size_t kImageNumberOfDirectoryEntries = 16;
21 
22 // IMAGE_FILE_BASE_RELOCATION_TABLE
23 constexpr size_t kIndexOfBaseRelocationTable = 5;
24 
25 constexpr uint32_t kImageScnMemExecute = 0x20000000;  // IMAGE_SCN_MEM_EXECUTE
26 constexpr uint32_t kImageScnMemRead = 0x40000000;     // IMAGE_SCN_MEM_READ
27 
28 // IMAGE_DOS_HEADER
29 struct 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 };
50 static_assert(sizeof(ImageDOSHeader) == 0x40,
51               "DOS header size should be 0x40 bytes");
52 
53 // IMAGE_SECTION_HEADER
54 struct 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 };
66 static_assert(sizeof(ImageSectionHeader) == 0x28,
67               "Section header size should be 0x28 bytes");
68 
69 // IMAGE_DATA_DIRECTORY
70 struct ImageDataDirectory {
71   uint32_t virtual_address;
72   uint32_t size;
73 };
74 static_assert(sizeof(ImageDataDirectory) == 0x08,
75               "Data directory size should be 0x08 bytes");
76 
77 // IMAGE_FILE_HEADER
78 struct 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 };
87 static_assert(sizeof(ImageFileHeader) == 0x14,
88               "File header size should be 0x14 bytes");
89 
90 // IMAGE_OPTIONAL_HEADER
91 struct 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;
123 
124   // The number of elements is actually |number_of_rva_and_sizes|, so accesses
125   // to |data_directory| should be checked against the bound.
126   ImageDataDirectory data_directory[kImageNumberOfDirectoryEntries];  // 0x60
127   /* 0xE0 */
128 };
129 static_assert(sizeof(ImageOptionalHeader) == 0xE0,
130               "Optional header (32) size should be 0xE0 bytes");
131 
132 // IMAGE_OPTIONAL_HEADER64
133 struct 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 };
167 static_assert(sizeof(ImageOptionalHeader64) == 0xF0,
168               "Optional header (64) size should be 0xF0 bytes");
169 
170 struct RelocHeader {
171   uint32_t rva_hi;
172   uint32_t size;
173 };
174 static_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 
183 constexpr char const* kTextSectionName = ".text";
184 
185 // Bitfield with characteristics usually associated with code sections.
186 const uint32_t kCodeCharacteristics =
187     pe::kImageScnMemExecute | pe::kImageScnMemRead;
188 
189 }  // namespace zucchini
190 
191 #endif  // COMPONENTS_ZUCCHINI_TYPE_WIN_PE_H_
192