| // Copyright 2017 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef COMPONENTS_ZUCCHINI_TYPE_WIN_PE_H_ |
| #define COMPONENTS_ZUCCHINI_TYPE_WIN_PE_H_ |
| |
| #include <stddef.h> |
| #include <stdint.h> |
| |
| namespace zucchini { |
| |
| // Structures and constants taken from WINNT.h and following identical layout. |
| // This is used for parsing of Portable Executable (PE) file format. |
| namespace pe { |
| // Supported by MSVC, g++, and clang++. Ensures no gaps in packing. |
| #pragma pack(push, 1) |
| |
| // IMAGE_NUMBEROF_DIRECTORY_ENTRIES |
| constexpr size_t kImageNumberOfDirectoryEntries = 16; |
| |
| // IMAGE_FILE_BASE_RELOCATION_TABLE |
| constexpr size_t kIndexOfBaseRelocationTable = 5; |
| |
| constexpr uint32_t kImageScnMemExecute = 0x20000000; // IMAGE_SCN_MEM_EXECUTE |
| constexpr uint32_t kImageScnMemRead = 0x40000000; // IMAGE_SCN_MEM_READ |
| |
| // IMAGE_DOS_HEADER |
| struct ImageDOSHeader { |
| uint16_t e_magic; // 0x00 |
| uint16_t e_cblp; |
| uint16_t e_cp; |
| uint16_t e_crlc; |
| uint16_t e_cparhdr; |
| uint16_t e_minalloc; |
| uint16_t e_maxalloc; |
| uint16_t e_ss; |
| uint16_t e_sp; // 0x10 |
| uint16_t e_csum; |
| uint16_t e_ip; |
| uint16_t e_cs; |
| uint16_t e_lfarlc; |
| uint16_t e_ovno; |
| uint16_t e_res[4]; |
| uint16_t e_oemid; // 0x24 |
| uint16_t e_oeminfo; |
| uint16_t e_res2[10]; |
| uint32_t e_lfanew; // 0x3C |
| }; |
| static_assert(sizeof(ImageDOSHeader) == 0x40, |
| "DOS header size should be 0x40 bytes"); |
| |
| // IMAGE_SECTION_HEADER |
| struct ImageSectionHeader { |
| char name[8]; |
| uint32_t virtual_size; |
| uint32_t virtual_address; |
| uint32_t size_of_raw_data; |
| uint32_t file_offset_of_raw_data; |
| uint32_t pointer_to_relocations; // Always zero in an image. |
| uint32_t pointer_to_line_numbers; // Always zero in an image. |
| uint16_t number_of_relocations; // Always zero in an image. |
| uint16_t number_of_line_numbers; // Always zero in an image. |
| uint32_t characteristics; |
| }; |
| static_assert(sizeof(ImageSectionHeader) == 0x28, |
| "Section header size should be 0x28 bytes"); |
| |
| // IMAGE_DATA_DIRECTORY |
| struct ImageDataDirectory { |
| uint32_t virtual_address; |
| uint32_t size; |
| }; |
| static_assert(sizeof(ImageDataDirectory) == 0x08, |
| "Data directory size should be 0x08 bytes"); |
| |
| // IMAGE_FILE_HEADER |
| struct ImageFileHeader { |
| uint16_t machine; |
| uint16_t number_of_sections; |
| uint32_t time_date_stamp; |
| uint32_t pointer_to_symbol_table; |
| uint32_t number_of_symbols; |
| uint16_t size_of_optional_header; |
| uint16_t characteristics; |
| }; |
| static_assert(sizeof(ImageFileHeader) == 0x14, |
| "File header size should be 0x14 bytes"); |
| |
| // IMAGE_OPTIONAL_HEADER |
| struct ImageOptionalHeader { |
| uint16_t magic; // 0x00: 0x10B |
| uint8_t major_linker_version; |
| uint8_t minor_linker_version; |
| uint32_t size_of_code; |
| uint32_t size_of_initialized_data; |
| uint32_t size_of_uninitialized_data; |
| uint32_t address_of_entry_point; // 0x10 |
| uint32_t base_of_code; |
| uint32_t base_of_data; |
| |
| uint32_t image_base; |
| uint32_t section_alignment; // 0x20 |
| uint32_t file_alignment; |
| uint16_t major_operating_system_version; |
| uint16_t minor_operating_system_version; |
| uint16_t major_image_version; |
| uint16_t minor_image_version; |
| uint16_t major_subsystem_version; // 0x30 |
| uint16_t minor_subsystem_version; |
| uint32_t win32_version_value; |
| uint32_t size_of_image; |
| uint32_t size_of_headers; |
| uint32_t check_sum; // 0x40 |
| uint16_t subsystem; |
| uint16_t dll_characteristics; |
| uint32_t size_of_stack_reserve; |
| uint32_t size_of_stack_commit; |
| uint32_t size_of_heap_reserve; // 0x50 |
| uint32_t size_of_heap_commit; |
| uint32_t loader_flags; |
| uint32_t number_of_rva_and_sizes; |
| |
| // The number of elements is actually |number_of_rva_and_sizes|, so accesses |
| // to |data_directory| should be checked against the bound. |
| ImageDataDirectory data_directory[kImageNumberOfDirectoryEntries]; // 0x60 |
| /* 0xE0 */ |
| }; |
| static_assert(sizeof(ImageOptionalHeader) == 0xE0, |
| "Optional header (32) size should be 0xE0 bytes"); |
| |
| // IMAGE_OPTIONAL_HEADER64 |
| struct ImageOptionalHeader64 { |
| uint16_t magic; // 0x00: 0x20B |
| uint8_t major_linker_version; |
| uint8_t minor_linker_version; |
| uint32_t size_of_code; |
| uint32_t size_of_initialized_data; |
| uint32_t size_of_uninitialized_data; |
| uint32_t address_of_entry_point; // 0x10 |
| uint32_t base_of_code; |
| |
| uint64_t image_base; |
| uint32_t section_alignment; // 0x20 |
| uint32_t file_alignment; |
| uint16_t major_operating_system_version; |
| uint16_t minor_operating_system_version; |
| uint16_t major_image_version; |
| uint16_t minor_image_version; |
| uint16_t major_subsystem_version; // 0x30 |
| uint16_t minor_subsystem_version; |
| uint32_t win32_version_value; |
| uint32_t size_of_image; |
| uint32_t size_of_headers; |
| uint32_t check_sum; // 0x40 |
| uint16_t subsystem; |
| uint16_t dll_characteristics; |
| uint64_t size_of_stack_reserve; |
| uint64_t size_of_stack_commit; // 0x50 |
| uint64_t size_of_heap_reserve; |
| uint64_t size_of_heap_commit; // 0x60 |
| uint32_t loader_flags; |
| uint32_t number_of_rva_and_sizes; |
| ImageDataDirectory data_directory[kImageNumberOfDirectoryEntries]; // 0x70 |
| /* 0xF0 */ |
| }; |
| static_assert(sizeof(ImageOptionalHeader64) == 0xF0, |
| "Optional header (64) size should be 0xF0 bytes"); |
| |
| struct RelocHeader { |
| uint32_t rva_hi; |
| uint32_t size; |
| }; |
| static_assert(sizeof(RelocHeader) == 8, "RelocHeader size should be 8 bytes"); |
| |
| #pragma pack(pop) |
| |
| } // namespace pe |
| |
| // Constants and offsets gleaned from WINNT.h and various articles on the |
| // format of Windows PE executables. |
| |
| constexpr char const* kTextSectionName = ".text"; |
| |
| // Bitfield with characteristics usually associated with code sections. |
| const uint32_t kCodeCharacteristics = |
| pe::kImageScnMemExecute | pe::kImageScnMemRead; |
| |
| } // namespace zucchini |
| |
| #endif // COMPONENTS_ZUCCHINI_TYPE_WIN_PE_H_ |