You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
516 lines
12 KiB
516 lines
12 KiB
/* Copyright 2017 - 2021 R. Thomas |
|
* Copyright 2017 - 2021 Quarkslab |
|
* |
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
* you may not use this file except in compliance with the License. |
|
* You may obtain a copy of the License at |
|
* |
|
* http://www.apache.org/licenses/LICENSE-2.0 |
|
* |
|
* Unless required by applicable law or agreed to in writing, software |
|
* distributed under the License is distributed on an "AS IS" BASIS, |
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
* See the License for the specific language governing permissions and |
|
* limitations under the License. |
|
*/ |
|
|
|
|
|
//! The maximum number of sections that a COFF object can have (inclusive). |
|
static const int32_t MaxNumberOfSections16 = 65279; |
|
|
|
//! The PE signature bytes that follows the DOS stub header. |
|
static const char PE_Magic[] = { 'P', 'E', '\0', '\0' }; |
|
|
|
static const char Rich_Magic[] = {'R', 'i', 'c', 'h'}; |
|
static const char DanS_Magic[] = {'D', 'a', 'n', 'S'}; |
|
|
|
static const uint32_t DanS_Magic_number = 0x536E6144; |
|
|
|
static const char BigObjMagic[] = { |
|
'\xc7', '\xa1', '\xba', '\xd1', '\xee', '\xba', '\xa9', '\x4b', |
|
'\xaf', '\x20', '\xfa', '\xf6', '\x6a', '\xa4', '\xdc', '\xb8', |
|
}; |
|
|
|
static const uint8_t DEFAULT_NUMBER_DATA_DIRECTORIES = 15; |
|
|
|
#pragma pack(push,1) |
|
struct pe_header { |
|
char signature[sizeof(PE_Magic)]; |
|
uint16_t Machine; |
|
uint16_t NumberOfSections; |
|
uint32_t TimeDateStamp; |
|
uint32_t PointerToSymbolTable; |
|
uint32_t NumberOfSymbols; |
|
uint16_t SizeOfOptionalHeader; |
|
uint16_t Characteristics; |
|
}; |
|
|
|
|
|
struct pe_relocation { |
|
uint32_t VirtualAddress; |
|
uint32_t SymbolTableIndex; |
|
uint16_t Type; |
|
}; |
|
|
|
struct pe_base_relocation_block { |
|
uint32_t PageRVA; |
|
uint32_t BlockSize; |
|
}; |
|
|
|
|
|
struct pe_symbol { |
|
union { |
|
char ShortName[8]; |
|
struct |
|
{ |
|
uint32_t Zeroes; |
|
uint32_t Offset; |
|
} Name; |
|
} Name; |
|
uint32_t Value; |
|
int16_t SectionNumber; |
|
uint16_t Type; |
|
uint8_t StorageClass; |
|
uint8_t NumberOfAuxSymbols; |
|
}; |
|
|
|
|
|
struct pe_section { |
|
char Name[8]; |
|
uint32_t VirtualSize; |
|
uint32_t VirtualAddress; |
|
uint32_t SizeOfRawData; |
|
uint32_t PointerToRawData; |
|
uint32_t PointerToRelocations; |
|
uint32_t PointerToLineNumbers; |
|
uint16_t NumberOfRelocations; |
|
uint16_t NumberOfLineNumbers; |
|
uint32_t Characteristics; |
|
}; |
|
|
|
struct AuxiliaryFunctionDefinition { |
|
uint32_t TagIndex; |
|
uint32_t TotalSize; |
|
uint32_t PointerToLinenumber; |
|
uint32_t PointerToNextFunction; |
|
char unused[2]; |
|
}; |
|
|
|
struct AuxiliarybfAndefSymbol { |
|
uint8_t unused1[4]; |
|
uint16_t Linenumber; |
|
uint8_t unused2[6]; |
|
uint32_t PointerToNextFunction; |
|
uint8_t unused3[2]; |
|
}; |
|
|
|
struct AuxiliaryWeakExternal { |
|
uint32_t TagIndex; |
|
uint32_t Characteristics; |
|
uint8_t unused[10]; |
|
}; |
|
|
|
|
|
struct AuxiliarySectionDefinition { |
|
uint32_t Length; |
|
uint16_t NumberOfRelocations; |
|
uint16_t NumberOfLinenumbers; |
|
uint32_t CheckSum; |
|
uint32_t Number; |
|
uint8_t Selection; |
|
char unused; |
|
}; |
|
|
|
struct AuxiliaryCLRToken { |
|
uint8_t AuxType; |
|
uint8_t unused1; |
|
uint32_t SymbolTableIndex; |
|
char unused2[12]; |
|
}; |
|
|
|
union Auxiliary { |
|
AuxiliaryFunctionDefinition FunctionDefinition; |
|
AuxiliarybfAndefSymbol bfAndefSymbol; |
|
AuxiliaryWeakExternal WeakExternal; |
|
AuxiliarySectionDefinition SectionDefinition; |
|
}; |
|
|
|
|
|
/// The Import Directory Table. |
|
/// |
|
/// There is a single array of these and one entry per imported DLL. |
|
struct pe_import { |
|
uint32_t ImportLookupTableRVA; |
|
uint32_t TimeDateStamp; |
|
uint32_t ForwarderChain; |
|
uint32_t NameRVA; |
|
uint32_t ImportAddressTableRVA; |
|
}; |
|
|
|
|
|
struct ImportLookupTableEntry32 { |
|
uint32_t data; |
|
}; |
|
|
|
struct ImportLookupTableEntry64 { |
|
uint64_t data; |
|
}; |
|
|
|
|
|
struct pe32_tls { |
|
uint32_t RawDataStartVA; |
|
uint32_t RawDataEndVA; |
|
uint32_t AddressOfIndex; |
|
uint32_t AddressOfCallback; |
|
uint32_t SizeOfZeroFill; |
|
uint32_t Characteristics; |
|
}; |
|
|
|
|
|
struct pe64_tls { |
|
uint64_t RawDataStartVA; |
|
uint64_t RawDataEndVA; |
|
uint64_t AddressOfIndex; |
|
uint64_t AddressOfCallback; |
|
uint32_t SizeOfZeroFill; |
|
uint32_t Characteristics; |
|
}; |
|
|
|
|
|
/// The DOS compatible header at the front of all PEs. |
|
struct pe_dos_header { |
|
uint16_t Magic; |
|
uint16_t UsedBytesInTheLastPage; |
|
uint16_t FileSizeInPages; |
|
uint16_t NumberOfRelocationItems; |
|
uint16_t HeaderSizeInParagraphs; |
|
uint16_t MinimumExtraParagraphs; |
|
uint16_t MaximumExtraParagraphs; |
|
uint16_t InitialRelativeSS; |
|
uint16_t InitialSP; |
|
uint16_t Checksum; |
|
uint16_t InitialIP; |
|
uint16_t InitialRelativeCS; |
|
uint16_t AddressOfRelocationTable; |
|
uint16_t OverlayNumber; |
|
uint16_t Reserved[4]; |
|
uint16_t OEMid; |
|
uint16_t OEMinfo; |
|
uint16_t Reserved2[10]; |
|
uint32_t AddressOfNewExeHeader; |
|
}; |
|
|
|
struct pe64_optional_header { |
|
uint16_t Magic; |
|
uint8_t MajorLinkerVersion; |
|
uint8_t MinorLinkerVersion; |
|
uint32_t SizeOfCode; |
|
uint32_t SizeOfInitializedData; |
|
uint32_t SizeOfUninitializedData; |
|
uint32_t AddressOfEntryPoint; // RVA |
|
uint32_t BaseOfCode; // RVA |
|
//uint32_t BaseOfData; // RVA |
|
uint64_t ImageBase; |
|
uint32_t SectionAlignment; |
|
uint32_t FileAlignment; |
|
uint16_t MajorOperatingSystemVersion; |
|
uint16_t MinorOperatingSystemVersion; |
|
uint16_t MajorImageVersion; |
|
uint16_t MinorImageVersion; |
|
uint16_t MajorSubsystemVersion; |
|
uint16_t MinorSubsystemVersion; |
|
uint32_t Win32VersionValue; |
|
uint32_t SizeOfImage; |
|
uint32_t SizeOfHeaders; |
|
uint32_t CheckSum; |
|
uint16_t Subsystem; |
|
uint16_t DLLCharacteristics; |
|
uint64_t SizeOfStackReserve; |
|
uint64_t SizeOfStackCommit; |
|
uint64_t SizeOfHeapReserve; |
|
uint64_t SizeOfHeapCommit; |
|
uint32_t LoaderFlags; |
|
uint32_t NumberOfRvaAndSize; |
|
}; |
|
|
|
|
|
struct pe32_optional_header { |
|
uint16_t Magic; |
|
uint8_t MajorLinkerVersion; |
|
uint8_t MinorLinkerVersion; |
|
uint32_t SizeOfCode; |
|
uint32_t SizeOfInitializedData; |
|
uint32_t SizeOfUninitializedData; |
|
uint32_t AddressOfEntryPoint; // RVA |
|
uint32_t BaseOfCode; // RVA |
|
uint32_t BaseOfData; // RVA |
|
uint32_t ImageBase; |
|
uint32_t SectionAlignment; |
|
uint32_t FileAlignment; |
|
uint16_t MajorOperatingSystemVersion; |
|
uint16_t MinorOperatingSystemVersion; |
|
uint16_t MajorImageVersion; |
|
uint16_t MinorImageVersion; |
|
uint16_t MajorSubsystemVersion; |
|
uint16_t MinorSubsystemVersion; |
|
uint32_t Win32VersionValue; |
|
uint32_t SizeOfImage; |
|
uint32_t SizeOfHeaders; |
|
uint32_t CheckSum; |
|
uint16_t Subsystem; |
|
uint16_t DLLCharacteristics; |
|
uint32_t SizeOfStackReserve; |
|
uint32_t SizeOfStackCommit; |
|
uint32_t SizeOfHeapReserve; |
|
uint32_t SizeOfHeapCommit; |
|
uint32_t LoaderFlags; |
|
uint32_t NumberOfRvaAndSize; |
|
}; |
|
|
|
|
|
struct pe_data_directory { |
|
uint32_t RelativeVirtualAddress; |
|
uint32_t Size; |
|
}; |
|
|
|
|
|
struct pe_debug { |
|
uint32_t Characteristics; |
|
uint32_t TimeDateStamp; |
|
uint16_t MajorVersion; |
|
uint16_t MinorVersion; |
|
uint32_t Type; |
|
uint32_t SizeOfData; |
|
uint32_t AddressOfRawData; |
|
uint32_t PointerToRawData; |
|
}; |
|
|
|
|
|
struct pe_pdb_70 { |
|
uint32_t cv_signature; |
|
uint8_t signature[16]; |
|
uint32_t age; |
|
char* filename; |
|
}; |
|
|
|
struct pe_pdb_20 { |
|
uint32_t cv_signature; |
|
uint32_t offset; |
|
uint32_t signature; |
|
uint32_t age; |
|
char* filename; |
|
}; |
|
|
|
struct pe_pogo { |
|
uint32_t start_rva; |
|
uint32_t size; |
|
char name[1]; |
|
}; |
|
|
|
|
|
struct pe_resource_directory_table { |
|
uint32_t Characteristics; |
|
uint32_t TimeDateStamp; |
|
uint16_t MajorVersion; |
|
uint16_t MinorVersion; |
|
uint16_t NumberOfNameEntries; |
|
uint16_t NumberOfIDEntries; |
|
}; |
|
|
|
struct pe_resource_directory_entries { |
|
union { |
|
uint32_t NameRVA; |
|
uint32_t IntegerID; |
|
} NameID; |
|
uint32_t RVA; |
|
}; |
|
|
|
struct pe_resource_data_entry { |
|
uint32_t DataRVA; |
|
uint32_t Size; |
|
uint32_t Codepage; |
|
uint32_t Reserved; |
|
}; |
|
|
|
struct pe_resource_string { |
|
int16_t Length; |
|
uint16_t Name[1]; |
|
}; |
|
|
|
struct pe_resource_acceltableentry { |
|
int16_t fFlags; |
|
int16_t wAnsi; |
|
int16_t wId; |
|
int16_t padding; |
|
}; |
|
|
|
// |
|
// Export structures |
|
// |
|
struct pe_export_directory_table { |
|
uint32_t ExportFlags; ///< Reserverd must be 0 |
|
uint32_t Timestamp; ///< The time and date that the export data was created |
|
uint16_t MajorVersion; ///< The Major version number |
|
uint16_t MinorVersion; ///< The Minor version number |
|
uint32_t NameRVA; ///< The address of the ASCII DLL's name (RVA) |
|
uint32_t OrdinalBase; ///< The starting ordinal number for exports. (Usually 1) |
|
uint32_t AddressTableEntries; ///< Number of entries in the export address table |
|
uint32_t NumberOfNamePointers; ///< Number of entries in the name pointer table |
|
uint32_t ExportAddressTableRVA; ///< Address of the export address table (RVA) |
|
uint32_t NamePointerRVA; ///< Address of the name pointer table (RVA) |
|
uint32_t OrdinalTableRVA; ///< Address of the ordinal table (RVA) |
|
}; |
|
|
|
|
|
struct pe_resource_fixed_file_info { |
|
uint32_t signature; // e.g. 0xfeef04bd |
|
uint32_t struct_version; // e.g. 0x00000042 = "0.42" |
|
uint32_t file_version_MS; // e.g. 0x00030075 = "3.75" |
|
uint32_t file_version_LS; // e.g. 0x00000031 = "0.31" |
|
uint32_t product_version_MS; // e.g. 0x00030010 = "3.10" |
|
uint32_t product_version_LS; // e.g. 0x00000031 = "0.31" |
|
uint32_t file_flags_mask; // = 0x3F for version "0.42" |
|
uint32_t file_flags; // e.g. VFF_DEBUG | VFF_PRERELEASE |
|
uint32_t file_OS; // e.g. VOS_DOS_WINDOWS16 |
|
uint32_t file_type; // e.g. VFT_DRIVER |
|
uint32_t file_subtype; // e.g. VFT2_DRV_KEYBOARD |
|
uint32_t file_date_MS; // e.g. 0 |
|
uint32_t file_date_LS; // e.g. 0 |
|
}; |
|
|
|
|
|
struct pe_resource_version_info { |
|
uint16_t length; |
|
uint16_t sizeof_value; |
|
uint16_t type; |
|
char16_t key[16]; |
|
// uint16_t padding; |
|
// |
|
// uint16_t padding; |
|
// uint16_t children |
|
}; |
|
|
|
//! Resource icons directory structure |
|
//! Based on https://docs.microsoft.com/en-us/windows/win32/menurc/resources-reference |
|
//! |
|
//! This is the begining of the RESOURCE_TYPES::GROUP_ICON content |
|
struct pe_resource_icon_dir { |
|
uint16_t reserved; ///< Reserved |
|
uint16_t type; ///< Resource type (1 for icons) |
|
uint16_t count; ///< Number of icons |
|
}; |
|
|
|
|
|
//! Structure that follows pe_resource_icon_dir in a resource entry |
|
struct pe_resource_icon_group { |
|
uint8_t width; ///< Width, in pixels, of the image |
|
uint8_t height; ///< Height, in pixels, of the image |
|
uint8_t color_count; ///< Number of colors in image (0 if >=8bpp) |
|
uint8_t reserved; ///< Reserved (must be 0) |
|
uint16_t planes; ///< Color Planes |
|
uint16_t bit_count; ///< Bits per pixel |
|
uint32_t size; ///< Size of the image in bytes |
|
uint16_t ID; ///< The associated ID |
|
}; |
|
|
|
//! Structure that follows pe_resource_icon_dir in a icon **file** |
|
struct pe_icon_header { |
|
uint8_t width; ///< Width, in pixels, of the image |
|
uint8_t height; ///< Height, in pixels, of the image |
|
uint8_t color_count; ///< Number of colors in image (0 if >=8bpp) |
|
uint8_t reserved; ///< Reserved (must be 0) |
|
uint16_t planes; ///< Color Planes |
|
uint16_t bit_count; ///< Bits per pixel |
|
uint32_t size; ///< Size of the image in bytes |
|
uint32_t offset; ///< Offset to the pixels |
|
}; |
|
|
|
//! Extended dialog box template |
|
struct pe_dialog_template_ext { |
|
uint16_t version; |
|
uint16_t signature; |
|
uint32_t help_id; |
|
uint32_t ext_style; |
|
uint32_t style; |
|
uint16_t nbof_items; |
|
int16_t x; |
|
int16_t y; |
|
int16_t cx; |
|
int16_t cy; |
|
// sz_Or_Ord menu; |
|
// sz_Or_Ord windowClass; |
|
// char16_t title[titleLen]; |
|
// uint16_t pointsize; |
|
// uint16_t weight; |
|
// uint8_t italic; |
|
// uint8_t charset; |
|
// char16_t typeface[stringLen]; |
|
}; |
|
|
|
//! Dialog box template |
|
struct pe_dialog_template { |
|
uint32_t style; |
|
uint32_t ext_style; |
|
uint16_t nbof_items; |
|
int16_t x; |
|
int16_t y; |
|
int16_t cx; |
|
int16_t cy; |
|
}; |
|
|
|
|
|
//! Extended dialog box template item |
|
struct pe_dialog_item_template_ext { |
|
uint32_t help_id; |
|
uint32_t ext_style; |
|
uint32_t style; |
|
int16_t x; |
|
int16_t y; |
|
int16_t cx; |
|
int16_t cy; |
|
uint32_t id; |
|
// sz_Or_Ord windowClass; |
|
// sz_Or_Ord title; |
|
// uint16_t extra_count; |
|
}; |
|
|
|
|
|
//! Dialog box template item |
|
struct pe_dialog_item_template { |
|
uint32_t style; |
|
uint32_t ext_style; |
|
int16_t x; |
|
int16_t y; |
|
int16_t cx; |
|
int16_t cy; |
|
uint16_t id; |
|
}; |
|
|
|
struct pe_code_integrity { |
|
uint16_t Flags; |
|
uint16_t Catalog; |
|
uint32_t CatalogOffset; |
|
uint32_t Reserved; |
|
}; |
|
|
|
struct pe_exception_entry_x64 { |
|
uint32_t address_start_rva; |
|
uint32_t address_end_rva; |
|
uint32_t unwind_info_rva; |
|
}; |
|
|
|
|
|
struct pe_exception_entry_mips { |
|
uint32_t address_start_va; |
|
uint32_t address_end_va; |
|
uint32_t exception_handler; |
|
uint32_t handler_data; |
|
uint32_t prolog_end_address; |
|
}; |
|
|
|
struct pe_exception_entry_arm { |
|
uint32_t address_start_va; |
|
uint32_t data; |
|
}; |
|
|
|
#pragma pack(pop)
|
|
|