1029 lines
33 KiB
C++
1029 lines
33 KiB
C++
/*************************************************************************/
|
|
/* Copyright (c) 2015 dx, http://kaimi.ru */
|
|
/* */
|
|
/* Permission is hereby granted, free of charge, to any person */
|
|
/* obtaining a copy of this software and associated documentation */
|
|
/* files (the "Software"), to deal in the Software without */
|
|
/* restriction, including without limitation the rights to use, */
|
|
/* copy, modify, merge, publish, distribute, sublicense, and/or */
|
|
/* sell copies of the Software, and to permit persons to whom the */
|
|
/* Software is furnished to do so, subject to the following conditions: */
|
|
/* The above copyright notice and this permission notice shall be */
|
|
/* included in all copies or substantial portions of the Software. */
|
|
/* */
|
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
|
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
|
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
|
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
|
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
|
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
|
/*************************************************************************/
|
|
#pragma once
|
|
#include <string>
|
|
#include <sstream>
|
|
#include "stdint_defs.h"
|
|
#if defined(_MSC_VER) or defined(__MINGW32__)
|
|
#define PE_BLISS_WINDOWS
|
|
#endif
|
|
|
|
namespace pe_bliss
|
|
{
|
|
//Enumeration of PE types
|
|
enum pe_type
|
|
{
|
|
pe_type_32,
|
|
pe_type_64
|
|
};
|
|
|
|
namespace pe_win
|
|
{
|
|
const uint32_t image_numberof_directory_entries = 16;
|
|
const uint32_t image_nt_optional_hdr32_magic = 0x10b;
|
|
const uint32_t image_nt_optional_hdr64_magic = 0x20b;
|
|
const uint32_t image_resource_name_is_string = 0x80000000;
|
|
const uint32_t image_resource_data_is_directory = 0x80000000;
|
|
|
|
const uint32_t image_dllcharacteristics_dynamic_base = 0x0040; // DLL can move.
|
|
const uint32_t image_dllcharacteristics_force_integrity = 0x0080; // Code Integrity Image
|
|
const uint32_t image_dllcharacteristics_nx_compat = 0x0100; // Image is NX compatible
|
|
const uint32_t image_dllcharacteristics_no_isolation = 0x0200; // Image understands isolation and doesn't want it
|
|
const uint32_t image_dllcharacteristics_no_seh = 0x0400; // Image does not use SEH. No SE handler may reside in this image
|
|
const uint32_t image_dllcharacteristics_no_bind = 0x0800; // Do not bind this image.
|
|
const uint32_t image_dllcharacteristics_wdm_driver = 0x2000; // Driver uses WDM model
|
|
const uint32_t image_dllcharacteristics_terminal_server_aware = 0x8000;
|
|
|
|
const uint32_t image_sizeof_file_header = 20;
|
|
|
|
const uint32_t image_file_relocs_stripped = 0x0001; // Relocation info stripped from file.
|
|
const uint32_t image_file_executable_image = 0x0002; // File is executable (i.e. no unresolved externel references).
|
|
const uint32_t image_file_line_nums_stripped = 0x0004; // Line nunbers stripped from file.
|
|
const uint32_t image_file_local_syms_stripped = 0x0008; // Local symbols stripped from file.
|
|
const uint32_t image_file_aggresive_ws_trim = 0x0010; // Agressively trim working set
|
|
const uint32_t image_file_large_address_aware = 0x0020; // App can handle >2gb addresses
|
|
const uint32_t image_file_bytes_reversed_lo = 0x0080; // Bytes of machine word are reversed.
|
|
const uint32_t image_file_32bit_machine = 0x0100; // 32 bit word machine.
|
|
const uint32_t image_file_debug_stripped = 0x0200; // Debugging info stripped from file in .DBG file
|
|
const uint32_t image_file_removable_run_from_swap = 0x0400; // If Image is on removable media, copy and run from the swap file.
|
|
const uint32_t image_file_net_run_from_swap = 0x0800; // If Image is on Net, copy and run from the swap file.
|
|
const uint32_t image_file_system = 0x1000; // System File.
|
|
const uint32_t image_file_dll = 0x2000; // File is a DLL.
|
|
const uint32_t image_file_up_system_only = 0x4000; // File should only be run on a UP machine
|
|
const uint32_t image_file_bytes_reversed_hi = 0x8000; // Bytes of machine word are reversed.
|
|
|
|
const uint32_t image_scn_lnk_nreloc_ovfl = 0x01000000; // Section contains extended relocations.
|
|
const uint32_t image_scn_mem_discardable = 0x02000000; // Section can be discarded.
|
|
const uint32_t image_scn_mem_not_cached = 0x04000000; // Section is not cachable.
|
|
const uint32_t image_scn_mem_not_paged = 0x08000000; // Section is not pageable.
|
|
const uint32_t image_scn_mem_shared = 0x10000000; // Section is shareable.
|
|
const uint32_t image_scn_mem_execute = 0x20000000; // Section is executable.
|
|
const uint32_t image_scn_mem_read = 0x40000000; // Section is readable.
|
|
const uint32_t image_scn_mem_write = 0x80000000; // Section is writeable.
|
|
|
|
const uint32_t image_scn_cnt_code = 0x00000020; // Section contains code.
|
|
const uint32_t image_scn_cnt_initialized_data = 0x00000040; // Section contains initialized data.
|
|
const uint32_t image_scn_cnt_uninitialized_data = 0x00000080; // Section contains uninitialized data.
|
|
|
|
//Directory Entries
|
|
const uint32_t image_directory_entry_export = 0; // Export Directory
|
|
const uint32_t image_directory_entry_import = 1; // Import Directory
|
|
const uint32_t image_directory_entry_resource = 2; // Resource Directory
|
|
const uint32_t image_directory_entry_exception = 3; // Exception Directory
|
|
const uint32_t image_directory_entry_security = 4; // Security Directory
|
|
const uint32_t image_directory_entry_basereloc = 5; // Base Relocation Table
|
|
const uint32_t image_directory_entry_debug = 6; // Debug Directory
|
|
const uint32_t image_directory_entry_architecture = 7; // Architecture Specific Data
|
|
const uint32_t image_directory_entry_globalptr = 8; // RVA of GP
|
|
const uint32_t image_directory_entry_tls = 9; // TLS Directory
|
|
const uint32_t image_directory_entry_load_config = 10; // Load Configuration Directory
|
|
const uint32_t image_directory_entry_bound_import = 11; // Bound Import Directory in headers
|
|
const uint32_t image_directory_entry_iat = 12; // Import Address Table
|
|
const uint32_t image_directory_entry_delay_import = 13; // Delay Load Import Descriptors
|
|
const uint32_t image_directory_entry_com_descriptor = 14; // COM Runtime descriptor
|
|
|
|
//Subsystem Values
|
|
const uint32_t image_subsystem_unknown = 0; // Unknown subsystem.
|
|
const uint32_t image_subsystem_native = 1; // Image doesn't require a subsystem.
|
|
const uint32_t image_subsystem_windows_gui = 2; // Image runs in the Windows GUI subsystem.
|
|
const uint32_t image_subsystem_windows_cui = 3; // Image runs in the Windows character subsystem.
|
|
const uint32_t image_subsystem_os2_cui = 5; // image runs in the OS/2 character subsystem.
|
|
const uint32_t image_subsystem_posix_cui = 7; // image runs in the Posix character subsystem.
|
|
const uint32_t image_subsystem_native_windows = 8; // image is a native Win9x driver.
|
|
const uint32_t image_subsystem_windows_ce_gui = 9; // Image runs in the Windows CE subsystem.
|
|
const uint32_t image_subsystem_efi_application = 10; //
|
|
const uint32_t image_subsystem_efi_boot_service_driver = 11; //
|
|
const uint32_t image_subsystem_efi_runtime_driver = 12; //
|
|
const uint32_t image_subsystem_efi_rom = 13;
|
|
const uint32_t image_subsystem_xbox = 14;
|
|
const uint32_t image_subsystem_windows_boot_application = 16;
|
|
|
|
//Imports
|
|
const uint64_t image_ordinal_flag64 = 0x8000000000000000ull;
|
|
const uint32_t image_ordinal_flag32 = 0x80000000;
|
|
|
|
//Based relocation types
|
|
const uint32_t image_rel_based_absolute = 0;
|
|
const uint32_t image_rel_based_high = 1;
|
|
const uint32_t image_rel_based_low = 2;
|
|
const uint32_t image_rel_based_highlow = 3;
|
|
const uint32_t image_rel_based_highadj = 4;
|
|
const uint32_t image_rel_based_mips_jmpaddr = 5;
|
|
const uint32_t image_rel_based_mips_jmpaddr16 = 9;
|
|
const uint32_t image_rel_based_ia64_imm64 = 9;
|
|
const uint32_t image_rel_based_dir64 = 10;
|
|
|
|
//Exception directory
|
|
//The function has an exception handler that should be called when looking for functions that need to examine exceptions
|
|
const uint32_t unw_flag_ehandler = 0x01;
|
|
//The function has a termination handler that should be called when unwinding an exception
|
|
const uint32_t unw_flag_uhandler = 0x02;
|
|
//This unwind info structure is not the primary one for the procedure.
|
|
//Instead, the chained unwind info entry is the contents of a previous RUNTIME_FUNCTION entry.
|
|
//If this flag is set, then the UNW_FLAG_EHANDLER and UNW_FLAG_UHANDLER flags must be cleared.
|
|
//Also, the frame register and fixed-stack allocation fields must have the same values as in the primary unwind info
|
|
const uint32_t unw_flag_chaininfo = 0x04;
|
|
|
|
//Debug
|
|
const uint32_t image_debug_misc_exename = 1;
|
|
const uint32_t image_debug_type_unknown = 0;
|
|
const uint32_t image_debug_type_coff = 1;
|
|
const uint32_t image_debug_type_codeview = 2;
|
|
const uint32_t image_debug_type_fpo = 3;
|
|
const uint32_t image_debug_type_misc = 4;
|
|
const uint32_t image_debug_type_exception = 5;
|
|
const uint32_t image_debug_type_fixup = 6;
|
|
const uint32_t image_debug_type_omap_to_src = 7;
|
|
const uint32_t image_debug_type_omap_from_src = 8;
|
|
const uint32_t image_debug_type_borland = 9;
|
|
const uint32_t image_debug_type_reserved10 = 10;
|
|
const uint32_t image_debug_type_clsid = 11;
|
|
|
|
|
|
//Storage classes
|
|
const uint32_t image_sym_class_end_of_function = static_cast<uint8_t>(-1);
|
|
const uint32_t image_sym_class_null = 0x0000;
|
|
const uint32_t image_sym_class_automatic = 0x0001;
|
|
const uint32_t image_sym_class_external = 0x0002;
|
|
const uint32_t image_sym_class_static = 0x0003;
|
|
const uint32_t image_sym_class_register = 0x0004;
|
|
const uint32_t image_sym_class_external_def = 0x0005;
|
|
const uint32_t image_sym_class_label = 0x0006;
|
|
const uint32_t image_sym_class_undefined_label = 0x0007;
|
|
const uint32_t image_sym_class_member_of_struct = 0x0008;
|
|
const uint32_t image_sym_class_argument = 0x0009;
|
|
const uint32_t image_sym_class_struct_tag = 0x000a;
|
|
const uint32_t image_sym_class_member_of_union = 0x000b;
|
|
const uint32_t image_sym_class_union_tag = 0x000c;
|
|
const uint32_t image_sym_class_type_definition = 0x000d;
|
|
const uint32_t image_sym_class_undefined_static = 0x000e;
|
|
const uint32_t image_sym_class_enum_tag = 0x000f;
|
|
const uint32_t image_sym_class_member_of_enum = 0x0010;
|
|
const uint32_t image_sym_class_register_param = 0x0011;
|
|
const uint32_t image_sym_class_bit_field = 0x0012;
|
|
|
|
const uint32_t image_sym_class_far_external = 0x0044;
|
|
|
|
const uint32_t image_sym_class_block = 0x0064;
|
|
const uint32_t image_sym_class_function = 0x0065;
|
|
const uint32_t image_sym_class_end_of_struct = 0x0066;
|
|
const uint32_t image_sym_class_file = 0x0067;
|
|
|
|
const uint32_t image_sym_class_section = 0x0068;
|
|
const uint32_t image_sym_class_weak_external = 0x0069;
|
|
|
|
const uint32_t image_sym_class_clr_token = 0x006b;
|
|
|
|
//type packing constants
|
|
const uint32_t n_btmask = 0x000f;
|
|
const uint32_t n_tmask = 0x0030;
|
|
const uint32_t n_tmask1 = 0x00c0;
|
|
const uint32_t n_tmask2 = 0x00f0;
|
|
const uint32_t n_btshft = 4;
|
|
const uint32_t n_tshift = 2;
|
|
|
|
//Type (derived) values.
|
|
const uint32_t image_sym_dtype_null = 0; // no derived type.
|
|
const uint32_t image_sym_dtype_pointer = 1; // pointer.
|
|
const uint32_t image_sym_dtype_function = 2; // function.
|
|
const uint32_t image_sym_dtype_array = 3; // array.
|
|
|
|
// Is x a function?
|
|
//TODO
|
|
#ifndef ISFCN
|
|
#define ISFCN(x) (((x) & n_tmask) == (image_sym_dtype_function << n_btshft))
|
|
#endif
|
|
|
|
//Version info
|
|
const uint32_t vs_ffi_fileflagsmask = 0x0000003FL;
|
|
|
|
const uint32_t vs_ffi_signature = 0xFEEF04BDL;
|
|
const uint32_t vs_ffi_strucversion = 0x00010000L;
|
|
|
|
/* ----- VS_VERSION.dwFileFlags ----- */
|
|
const uint32_t vs_ff_debug = 0x00000001L;
|
|
const uint32_t vs_ff_prerelease = 0x00000002L;
|
|
const uint32_t vs_ff_patched = 0x00000004L;
|
|
const uint32_t vs_ff_privatebuild = 0x00000008L;
|
|
const uint32_t vs_ff_infoinferred = 0x00000010L;
|
|
const uint32_t vs_ff_specialbuild = 0x00000020L;
|
|
|
|
/* ----- VS_VERSION.dwFileOS ----- */
|
|
const uint32_t vos_unknown = 0x00000000L;
|
|
const uint32_t vos_dos = 0x00010000L;
|
|
const uint32_t vos_os216 = 0x00020000L;
|
|
const uint32_t vos_os232 = 0x00030000L;
|
|
const uint32_t vos_nt = 0x00040000L;
|
|
const uint32_t vos_wince = 0x00050000L;
|
|
|
|
const uint32_t vos__base = 0x00000000L;
|
|
const uint32_t vos__windows16 = 0x00000001L;
|
|
const uint32_t vos__pm16 = 0x00000002L;
|
|
const uint32_t vos__pm32 = 0x00000003L;
|
|
const uint32_t vos__windows32 = 0x00000004L;
|
|
|
|
const uint32_t vos_dos_windows16 = 0x00010001L;
|
|
const uint32_t vos_dos_windows32 = 0x00010004L;
|
|
const uint32_t vos_os216_pm16 = 0x00020002L;
|
|
const uint32_t vos_os232_pm32 = 0x00030003L;
|
|
const uint32_t vos_nt_windows32 = 0x00040004L;
|
|
|
|
/* ----- VS_VERSION.dwFileType ----- */
|
|
const uint32_t vft_unknown = 0x00000000L;
|
|
const uint32_t vft_app = 0x00000001L;
|
|
const uint32_t vft_dll = 0x00000002L;
|
|
const uint32_t vft_drv = 0x00000003L;
|
|
const uint32_t vft_font = 0x00000004L;
|
|
const uint32_t vft_vxd = 0x00000005L;
|
|
const uint32_t vft_static_lib = 0x00000007L;
|
|
|
|
const uint32_t message_resource_unicode = 0x0001;
|
|
|
|
#pragma pack(push, 1)
|
|
|
|
//Windows GUID structure
|
|
struct guid
|
|
{
|
|
uint32_t Data1;
|
|
uint16_t Data2;
|
|
uint16_t Data3;
|
|
uint8_t Data4[8];
|
|
};
|
|
|
|
//DOS .EXE header
|
|
struct image_dos_header
|
|
{
|
|
uint16_t e_magic; // Magic number
|
|
uint16_t e_cblp; // Bytes on last page of file
|
|
uint16_t e_cp; // Pages in file
|
|
uint16_t e_crlc; // Relocations
|
|
uint16_t e_cparhdr; // Size of header in paragraphs
|
|
uint16_t e_minalloc; // Minimum extra paragraphs needed
|
|
uint16_t e_maxalloc; // Maximum extra paragraphs needed
|
|
uint16_t e_ss; // Initial (relative) SS value
|
|
uint16_t e_sp; // Initial SP value
|
|
uint16_t e_csum; // Checksum
|
|
uint16_t e_ip; // Initial IP value
|
|
uint16_t e_cs; // Initial (relative) CS value
|
|
uint16_t e_lfarlc; // File address of relocation table
|
|
uint16_t e_ovno; // Overlay number
|
|
uint16_t e_res[4]; // Reserved words
|
|
uint16_t e_oemid; // OEM identifier (for e_oeminfo)
|
|
uint16_t e_oeminfo; // OEM information; e_oemid specific
|
|
uint16_t e_res2[10]; // Reserved words
|
|
int32_t e_lfanew; // File address of new exe header
|
|
};
|
|
|
|
//Directory format
|
|
struct image_data_directory
|
|
{
|
|
uint32_t VirtualAddress;
|
|
uint32_t Size;
|
|
};
|
|
|
|
//Optional header format
|
|
struct image_optional_header32
|
|
{
|
|
//Standard fields
|
|
uint16_t Magic;
|
|
uint8_t MajorLinkerVersion;
|
|
uint8_t MinorLinkerVersion;
|
|
uint32_t SizeOfCode;
|
|
uint32_t SizeOfInitializedData;
|
|
uint32_t SizeOfUninitializedData;
|
|
uint32_t AddressOfEntryPoint;
|
|
uint32_t BaseOfCode;
|
|
uint32_t BaseOfData;
|
|
|
|
//NT additional fields
|
|
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 NumberOfRvaAndSizes;
|
|
image_data_directory DataDirectory[image_numberof_directory_entries];
|
|
};
|
|
|
|
struct image_optional_header64
|
|
{
|
|
uint16_t Magic;
|
|
uint8_t MajorLinkerVersion;
|
|
uint8_t MinorLinkerVersion;
|
|
uint32_t SizeOfCode;
|
|
uint32_t SizeOfInitializedData;
|
|
uint32_t SizeOfUninitializedData;
|
|
uint32_t AddressOfEntryPoint;
|
|
uint32_t BaseOfCode;
|
|
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 NumberOfRvaAndSizes;
|
|
image_data_directory DataDirectory[image_numberof_directory_entries];
|
|
};
|
|
|
|
struct image_file_header
|
|
{
|
|
uint16_t Machine;
|
|
uint16_t NumberOfSections;
|
|
uint32_t TimeDateStamp;
|
|
uint32_t PointerToSymbolTable;
|
|
uint32_t NumberOfSymbols;
|
|
uint16_t SizeOfOptionalHeader;
|
|
uint16_t Characteristics;
|
|
};
|
|
|
|
struct image_nt_headers64
|
|
{
|
|
uint32_t Signature;
|
|
image_file_header FileHeader;
|
|
image_optional_header64 OptionalHeader;
|
|
};
|
|
|
|
struct image_nt_headers32
|
|
{
|
|
uint32_t Signature;
|
|
image_file_header FileHeader;
|
|
image_optional_header32 OptionalHeader;
|
|
};
|
|
|
|
//Section header format
|
|
struct image_section_header
|
|
{
|
|
uint8_t Name[8];
|
|
union
|
|
{
|
|
uint32_t PhysicalAddress;
|
|
uint32_t VirtualSize;
|
|
} Misc;
|
|
|
|
uint32_t VirtualAddress;
|
|
uint32_t SizeOfRawData;
|
|
uint32_t PointerToRawData;
|
|
uint32_t PointerToRelocations;
|
|
uint32_t PointerToLinenumbers;
|
|
uint16_t NumberOfRelocations;
|
|
uint16_t NumberOfLinenumbers;
|
|
uint32_t Characteristics;
|
|
};
|
|
|
|
|
|
/// RESOURCES ///
|
|
struct image_resource_directory
|
|
{
|
|
uint32_t Characteristics;
|
|
uint32_t TimeDateStamp;
|
|
uint16_t MajorVersion;
|
|
uint16_t MinorVersion;
|
|
uint16_t NumberOfNamedEntries;
|
|
uint16_t NumberOfIdEntries;
|
|
// IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[];
|
|
};
|
|
|
|
struct vs_fixedfileinfo
|
|
{
|
|
uint32_t dwSignature; /* e.g. 0xfeef04bd */
|
|
uint32_t dwStrucVersion; /* e.g. 0x00000042 = "0.42" */
|
|
uint32_t dwFileVersionMS; /* e.g. 0x00030075 = "3.75" */
|
|
uint32_t dwFileVersionLS; /* e.g. 0x00000031 = "0.31" */
|
|
uint32_t dwProductVersionMS; /* e.g. 0x00030010 = "3.10" */
|
|
uint32_t dwProductVersionLS; /* e.g. 0x00000031 = "0.31" */
|
|
uint32_t dwFileFlagsMask; /* = 0x3F for version "0.42" */
|
|
uint32_t dwFileFlags; /* e.g. VFF_DEBUG | VFF_PRERELEASE */
|
|
uint32_t dwFileOS; /* e.g. VOS_DOS_WINDOWS16 */
|
|
uint32_t dwFileType; /* e.g. VFT_DRIVER */
|
|
uint32_t dwFileSubtype; /* e.g. VFT2_DRV_KEYBOARD */
|
|
uint32_t dwFileDateMS; /* e.g. 0 */
|
|
uint32_t dwFileDateLS; /* e.g. 0 */
|
|
};
|
|
|
|
struct bitmapinfoheader
|
|
{
|
|
uint32_t biSize;
|
|
int32_t biWidth;
|
|
int32_t biHeight;
|
|
uint16_t biPlanes;
|
|
uint16_t biBitCount;
|
|
uint32_t biCompression;
|
|
uint32_t biSizeImage;
|
|
int32_t biXPelsPerMeter;
|
|
int32_t biYPelsPerMeter;
|
|
uint32_t biClrUsed;
|
|
uint32_t biClrImportant;
|
|
};
|
|
|
|
struct message_resource_entry
|
|
{
|
|
uint16_t Length;
|
|
uint16_t Flags;
|
|
uint8_t Text[1];
|
|
};
|
|
|
|
struct message_resource_block
|
|
{
|
|
uint32_t LowId;
|
|
uint32_t HighId;
|
|
uint32_t OffsetToEntries;
|
|
};
|
|
|
|
struct message_resource_data
|
|
{
|
|
uint32_t NumberOfBlocks;
|
|
message_resource_block Blocks[1];
|
|
};
|
|
|
|
struct image_resource_directory_entry
|
|
{
|
|
union
|
|
{
|
|
struct
|
|
{
|
|
uint32_t NameOffset:31;
|
|
uint32_t NameIsString:1;
|
|
};
|
|
uint32_t Name;
|
|
uint16_t Id;
|
|
};
|
|
|
|
union
|
|
{
|
|
uint32_t OffsetToData;
|
|
struct
|
|
{
|
|
uint32_t OffsetToDirectory:31;
|
|
uint32_t DataIsDirectory:1;
|
|
};
|
|
};
|
|
};
|
|
|
|
struct image_resource_data_entry
|
|
{
|
|
uint32_t OffsetToData;
|
|
uint32_t Size;
|
|
uint32_t CodePage;
|
|
uint32_t Reserved;
|
|
};
|
|
|
|
#pragma pack(push, 2)
|
|
struct bitmapfileheader
|
|
{
|
|
uint16_t bfType;
|
|
uint32_t bfSize;
|
|
uint16_t bfReserved1;
|
|
uint16_t bfReserved2;
|
|
uint32_t bfOffBits;
|
|
};
|
|
#pragma pack(pop)
|
|
|
|
|
|
|
|
//Structure representing ICON file header
|
|
struct ico_header
|
|
{
|
|
uint16_t Reserved;
|
|
uint16_t Type; //1
|
|
uint16_t Count; //Count of icons included in icon group
|
|
};
|
|
|
|
//Structure that is stored in icon group directory in PE resources
|
|
struct icon_group
|
|
{
|
|
uint8_t Width;
|
|
uint8_t Height;
|
|
uint8_t ColorCount;
|
|
uint8_t Reserved;
|
|
uint16_t Planes;
|
|
uint16_t BitCount;
|
|
uint32_t SizeInBytes;
|
|
uint16_t Number; //Represents resource ID in PE icon list
|
|
};
|
|
|
|
//Structure representing ICON directory entry inside ICON file
|
|
struct icondirentry
|
|
{
|
|
uint8_t Width;
|
|
uint8_t Height;
|
|
uint8_t ColorCount;
|
|
uint8_t Reserved;
|
|
uint16_t Planes;
|
|
uint16_t BitCount;
|
|
uint32_t SizeInBytes;
|
|
uint32_t ImageOffset; //Offset from start of header to the image
|
|
};
|
|
|
|
//Structure representing CURSOR file header
|
|
struct cursor_header
|
|
{
|
|
uint16_t Reserved;
|
|
uint16_t Type; //2
|
|
uint16_t Count; //Count of cursors included in cursor group
|
|
};
|
|
|
|
struct cursor_group
|
|
{
|
|
uint16_t Width;
|
|
uint16_t Height; //Divide by 2 to get the actual height.
|
|
uint16_t Planes;
|
|
uint16_t BitCount;
|
|
uint32_t SizeInBytes;
|
|
uint16_t Number; //Represents resource ID in PE icon list
|
|
};
|
|
|
|
//Structure representing CURSOR directory entry inside CURSOR file
|
|
struct cursordirentry
|
|
{
|
|
uint8_t Width; //Set to CURSOR_GROUP::Height/2.
|
|
uint8_t Height;
|
|
uint8_t ColorCount;
|
|
uint8_t Reserved;
|
|
uint16_t HotspotX;
|
|
uint16_t HotspotY;
|
|
uint32_t SizeInBytes;
|
|
uint32_t ImageOffset; //Offset from start of header to the image
|
|
};
|
|
|
|
//Structure representing BLOCK in version info resource
|
|
struct version_info_block //(always aligned on 32-bit (DWORD) boundary)
|
|
{
|
|
uint16_t Length; //Length of this block (doesn't include padding)
|
|
uint16_t ValueLength; //Value length (if any)
|
|
uint16_t Type; //Value type (0 = binary, 1 = text)
|
|
uint16_t Key[1]; //Value name (block key) (always NULL terminated)
|
|
|
|
//////////
|
|
//WORD padding1[]; //Padding, if any (ALIGNMENT)
|
|
//xxxxx Value[]; //Value data, if any (*ALIGNED*)
|
|
//WORD padding2[]; //Padding, if any (ALIGNMENT)
|
|
//xxxxx Child[]; //Child block(s), if any (*ALIGNED*)
|
|
//////////
|
|
};
|
|
|
|
|
|
/// IMPORTS ///
|
|
#pragma pack(push, 8)
|
|
struct image_thunk_data64
|
|
{
|
|
union
|
|
{
|
|
uint64_t ForwarderString; // PBYTE
|
|
uint64_t Function; // PDWORD
|
|
uint64_t Ordinal;
|
|
uint64_t AddressOfData; // PIMAGE_IMPORT_BY_NAME
|
|
} u1;
|
|
};
|
|
#pragma pack(pop)
|
|
|
|
struct image_thunk_data32
|
|
{
|
|
union
|
|
{
|
|
uint32_t ForwarderString; // PBYTE
|
|
uint32_t Function; // PDWORD
|
|
uint32_t Ordinal;
|
|
uint32_t AddressOfData; // PIMAGE_IMPORT_BY_NAME
|
|
} u1;
|
|
};
|
|
|
|
struct image_import_descriptor
|
|
{
|
|
union
|
|
{
|
|
uint32_t Characteristics; // 0 for terminating null import descriptor
|
|
uint32_t OriginalFirstThunk; // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
|
|
};
|
|
|
|
uint32_t TimeDateStamp; // 0 if not bound,
|
|
// -1 if bound, and real date\time stamp
|
|
// in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
|
|
// O.W. date/time stamp of DLL bound to (Old BIND)
|
|
|
|
uint32_t ForwarderChain; // -1 if no forwarders
|
|
uint32_t Name;
|
|
uint32_t FirstThunk; // RVA to IAT (if bound this IAT has actual addresses)
|
|
};
|
|
|
|
|
|
/// TLS ///
|
|
struct image_tls_directory64
|
|
{
|
|
uint64_t StartAddressOfRawData;
|
|
uint64_t EndAddressOfRawData;
|
|
uint64_t AddressOfIndex; // PDWORD
|
|
uint64_t AddressOfCallBacks; // PIMAGE_TLS_CALLBACK *;
|
|
uint32_t SizeOfZeroFill;
|
|
uint32_t Characteristics;
|
|
};
|
|
|
|
struct image_tls_directory32
|
|
{
|
|
uint32_t StartAddressOfRawData;
|
|
uint32_t EndAddressOfRawData;
|
|
uint32_t AddressOfIndex; // PDWORD
|
|
uint32_t AddressOfCallBacks; // PIMAGE_TLS_CALLBACK *
|
|
uint32_t SizeOfZeroFill;
|
|
uint32_t Characteristics;
|
|
};
|
|
|
|
|
|
/// Export Format ///
|
|
struct image_export_directory
|
|
{
|
|
uint32_t Characteristics;
|
|
uint32_t TimeDateStamp;
|
|
uint16_t MajorVersion;
|
|
uint16_t MinorVersion;
|
|
uint32_t Name;
|
|
uint32_t Base;
|
|
uint32_t NumberOfFunctions;
|
|
uint32_t NumberOfNames;
|
|
uint32_t AddressOfFunctions; // RVA from base of image
|
|
uint32_t AddressOfNames; // RVA from base of image
|
|
uint32_t AddressOfNameOrdinals; // RVA from base of image
|
|
};
|
|
|
|
|
|
/// Based relocation format ///
|
|
struct image_base_relocation
|
|
{
|
|
uint32_t VirtualAddress;
|
|
uint32_t SizeOfBlock;
|
|
// uint16_t TypeOffset[1];
|
|
};
|
|
|
|
|
|
/// New format import descriptors pointed to by DataDirectory[ IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT ] ///
|
|
struct image_bound_import_descriptor
|
|
{
|
|
uint32_t TimeDateStamp;
|
|
uint16_t OffsetModuleName;
|
|
uint16_t NumberOfModuleForwarderRefs;
|
|
// Array of zero or more IMAGE_BOUND_FORWARDER_REF follows
|
|
};
|
|
|
|
struct image_bound_forwarder_ref
|
|
{
|
|
uint32_t TimeDateStamp;
|
|
uint16_t OffsetModuleName;
|
|
uint16_t Reserved;
|
|
};
|
|
|
|
|
|
/// Exception directory ///
|
|
struct image_runtime_function_entry
|
|
{
|
|
uint32_t BeginAddress;
|
|
uint32_t EndAddress;
|
|
uint32_t UnwindInfoAddress;
|
|
};
|
|
|
|
enum unwind_op_codes
|
|
{
|
|
uwop_push_nonvol = 0, /* info == register number */
|
|
uwop_alloc_large, /* no info, alloc size in next 2 slots */
|
|
uwop_alloc_small, /* info == size of allocation / 8 - 1 */
|
|
uwop_set_fpreg, /* no info, FP = RSP + UNWIND_INFO.FPRegOffset*16 */
|
|
uwop_save_nonvol, /* info == register number, offset in next slot */
|
|
uwop_save_nonvol_far, /* info == register number, offset in next 2 slots */
|
|
uwop_save_xmm128, /* info == XMM reg number, offset in next slot */
|
|
uwop_save_xmm128_far, /* info == XMM reg number, offset in next 2 slots */
|
|
uwop_push_machframe /* info == 0: no error-code, 1: error-code */
|
|
};
|
|
|
|
union unwind_code
|
|
{
|
|
struct s
|
|
{
|
|
uint8_t CodeOffset;
|
|
uint8_t UnwindOp : 4;
|
|
uint8_t OpInfo : 4;
|
|
};
|
|
|
|
uint16_t FrameOffset;
|
|
};
|
|
|
|
struct unwind_info
|
|
{
|
|
uint8_t Version : 3;
|
|
uint8_t Flags : 5;
|
|
uint8_t SizeOfProlog;
|
|
uint8_t CountOfCodes;
|
|
uint8_t FrameRegister : 4;
|
|
uint8_t FrameOffset : 4;
|
|
unwind_code UnwindCode[1];
|
|
/* unwind_code MoreUnwindCode[((CountOfCodes + 1) & ~1) - 1];
|
|
* union {
|
|
* OPTIONAL ULONG ExceptionHandler;
|
|
* OPTIONAL ULONG FunctionEntry;
|
|
* };
|
|
* OPTIONAL ULONG ExceptionData[]; */
|
|
};
|
|
|
|
|
|
|
|
/// Debug ///
|
|
struct image_debug_misc
|
|
{
|
|
uint32_t DataType; // type of misc data, see defines
|
|
uint32_t Length; // total length of record, rounded to four
|
|
// byte multiple.
|
|
uint8_t Unicode; // TRUE if data is unicode string
|
|
uint8_t Reserved[3];
|
|
uint8_t Data[1]; // Actual data
|
|
};
|
|
|
|
struct image_coff_symbols_header
|
|
{
|
|
uint32_t NumberOfSymbols;
|
|
uint32_t LvaToFirstSymbol;
|
|
uint32_t NumberOfLinenumbers;
|
|
uint32_t LvaToFirstLinenumber;
|
|
uint32_t RvaToFirstByteOfCode;
|
|
uint32_t RvaToLastByteOfCode;
|
|
uint32_t RvaToFirstByteOfData;
|
|
uint32_t RvaToLastByteOfData;
|
|
};
|
|
|
|
struct image_debug_directory
|
|
{
|
|
uint32_t Characteristics;
|
|
uint32_t TimeDateStamp;
|
|
uint16_t MajorVersion;
|
|
uint16_t MinorVersion;
|
|
uint32_t Type;
|
|
uint32_t SizeOfData;
|
|
uint32_t AddressOfRawData;
|
|
uint32_t PointerToRawData;
|
|
};
|
|
|
|
|
|
#pragma pack(push, 2)
|
|
struct image_symbol
|
|
{
|
|
union
|
|
{
|
|
uint8_t ShortName[8];
|
|
struct
|
|
{
|
|
uint32_t Short; // if 0, use LongName
|
|
uint32_t Long; // offset into string table
|
|
} Name;
|
|
uint32_t LongName[2]; // PBYTE [2]
|
|
} N;
|
|
uint32_t Value;
|
|
int16_t SectionNumber;
|
|
uint16_t Type;
|
|
uint8_t StorageClass;
|
|
uint8_t NumberOfAuxSymbols;
|
|
};
|
|
#pragma pack(pop)
|
|
|
|
//CodeView Debug OMF signature. The signature at the end of the file is
|
|
//a negative offset from the end of the file to another signature. At
|
|
//the negative offset (base address) is another signature whose filepos
|
|
//field points to the first OMFDirHeader in a chain of directories.
|
|
//The NB05 signature is used by the link utility to indicated a completely
|
|
//unpacked file. The NB06 signature is used by ilink to indicate that the
|
|
//executable has had CodeView information from an incremental link appended
|
|
//to the executable. The NB08 signature is used by cvpack to indicate that
|
|
//the CodeView Debug OMF has been packed. CodeView will only process
|
|
//executables with the NB08 signature.
|
|
struct OMFSignature
|
|
{
|
|
char Signature[4]; // "NBxx"
|
|
uint32_t filepos; // offset in file
|
|
};
|
|
|
|
struct CV_INFO_PDB20
|
|
{
|
|
OMFSignature CvHeader;
|
|
uint32_t Signature;
|
|
uint32_t Age;
|
|
uint8_t PdbFileName[1];
|
|
};
|
|
|
|
struct CV_INFO_PDB70
|
|
{
|
|
uint32_t CvSignature;
|
|
guid Signature;
|
|
uint32_t Age;
|
|
uint8_t PdbFileName[1];
|
|
};
|
|
|
|
// directory information structure
|
|
// This structure contains the information describing the directory.
|
|
// It is pointed to by the signature at the base address or the directory
|
|
// link field of a preceeding directory. The directory entries immediately
|
|
// follow this structure.
|
|
struct OMFDirHeader
|
|
{
|
|
uint16_t cbDirHeader; // length of this structure
|
|
uint16_t cbDirEntry; // number of bytes in each directory entry
|
|
uint32_t cDir; // number of directorie entries
|
|
int32_t lfoNextDir; // offset from base of next directory
|
|
uint32_t flags; // status flags
|
|
};
|
|
|
|
// directory structure
|
|
// The data in this structure is used to reference the data for each
|
|
// subsection of the CodeView Debug OMF information. Tables that are
|
|
// not associated with a specific module will have a module index of
|
|
// oxffff. These tables are the global types table, the global symbol
|
|
// table, the global public table and the library table.
|
|
struct OMFDirEntry
|
|
{
|
|
uint16_t SubSection; // subsection type (sst...)
|
|
uint16_t iMod; // module index
|
|
int32_t lfo; // large file offset of subsection
|
|
uint32_t cb; // number of bytes in subsection
|
|
};
|
|
|
|
|
|
/// CLR 2.0 header structure ///
|
|
struct image_cor20_header
|
|
{
|
|
//Header versioning
|
|
uint32_t cb;
|
|
uint16_t MajorRuntimeVersion;
|
|
uint16_t MinorRuntimeVersion;
|
|
|
|
// Symbol table and startup information
|
|
image_data_directory MetaData;
|
|
uint32_t Flags;
|
|
|
|
// If COMIMAGE_FLAGS_NATIVE_ENTRYPOINT is not set, EntryPointToken represents a managed entrypoint.
|
|
// If COMIMAGE_FLAGS_NATIVE_ENTRYPOINT is set, EntryPointRVA represents an RVA to a native entrypoint.
|
|
union
|
|
{
|
|
uint32_t EntryPointToken;
|
|
uint32_t EntryPointRVA;
|
|
};
|
|
|
|
// Binding information
|
|
image_data_directory Resources;
|
|
image_data_directory StrongNameSignature;
|
|
|
|
// Regular fixup and binding information
|
|
image_data_directory CodeManagerTable;
|
|
image_data_directory VTableFixups;
|
|
image_data_directory ExportAddressTableJumps;
|
|
|
|
// Precompiled image info (internal use only - set to zero)
|
|
image_data_directory ManagedNativeHeader;
|
|
};
|
|
|
|
enum replaces_cor_hdr_numeric_defines
|
|
{
|
|
// COM+ Header entry point flags.
|
|
comimage_flags_ilonly =0x00000001,
|
|
comimage_flags_32bitrequired =0x00000002,
|
|
comimage_flags_il_library =0x00000004,
|
|
comimage_flags_strongnamesigned =0x00000008,
|
|
comimage_flags_native_entrypoint =0x00000010,
|
|
comimage_flags_trackdebugdata =0x00010000,
|
|
|
|
// Version flags for image.
|
|
cor_version_major_v2 =2,
|
|
cor_version_major =cor_version_major_v2,
|
|
cor_version_minor =0,
|
|
cor_deleted_name_length =8,
|
|
cor_vtablegap_name_length =8,
|
|
|
|
// Maximum size of a NativeType descriptor.
|
|
native_type_max_cb =1,
|
|
cor_ilmethod_sect_small_max_datasize=0xff,
|
|
|
|
// #defines for the MIH FLAGS
|
|
image_cor_mih_methodrva =0x01,
|
|
image_cor_mih_ehrva =0x02,
|
|
image_cor_mih_basicblock =0x08,
|
|
|
|
// V-table constants
|
|
cor_vtable_32bit =0x01, // V-table slots are 32-bits in size.
|
|
cor_vtable_64bit =0x02, // V-table slots are 64-bits in size.
|
|
cor_vtable_from_unmanaged =0x04, // If set, transition from unmanaged.
|
|
cor_vtable_from_unmanaged_retain_appdomain =0x08, // If set, transition from unmanaged with keeping the current appdomain.
|
|
cor_vtable_call_most_derived =0x10, // Call most derived method described by
|
|
|
|
// EATJ constants
|
|
image_cor_eatj_thunk_size =32, // Size of a jump thunk reserved range.
|
|
|
|
// Max name lengths
|
|
//@todo: Change to unlimited name lengths.
|
|
max_class_name =1024,
|
|
max_package_name =1024
|
|
};
|
|
|
|
/// Load Configuration Directory Entry ///
|
|
struct image_load_config_directory32
|
|
{
|
|
uint32_t Size;
|
|
uint32_t TimeDateStamp;
|
|
uint16_t MajorVersion;
|
|
uint16_t MinorVersion;
|
|
uint32_t GlobalFlagsClear;
|
|
uint32_t GlobalFlagsSet;
|
|
uint32_t CriticalSectionDefaultTimeout;
|
|
uint32_t DeCommitFreeBlockThreshold;
|
|
uint32_t DeCommitTotalFreeThreshold;
|
|
uint32_t LockPrefixTable; // VA
|
|
uint32_t MaximumAllocationSize;
|
|
uint32_t VirtualMemoryThreshold;
|
|
uint32_t ProcessHeapFlags;
|
|
uint32_t ProcessAffinityMask;
|
|
uint16_t CSDVersion;
|
|
uint16_t Reserved1;
|
|
uint32_t EditList; // VA
|
|
uint32_t SecurityCookie; // VA
|
|
uint32_t SEHandlerTable; // VA
|
|
uint32_t SEHandlerCount;
|
|
};
|
|
|
|
struct image_load_config_directory64
|
|
{
|
|
uint32_t Size;
|
|
uint32_t TimeDateStamp;
|
|
uint16_t MajorVersion;
|
|
uint16_t MinorVersion;
|
|
uint32_t GlobalFlagsClear;
|
|
uint32_t GlobalFlagsSet;
|
|
uint32_t CriticalSectionDefaultTimeout;
|
|
uint64_t DeCommitFreeBlockThreshold;
|
|
uint64_t DeCommitTotalFreeThreshold;
|
|
uint64_t LockPrefixTable; // VA
|
|
uint64_t MaximumAllocationSize;
|
|
uint64_t VirtualMemoryThreshold;
|
|
uint64_t ProcessAffinityMask;
|
|
uint32_t ProcessHeapFlags;
|
|
uint16_t CSDVersion;
|
|
uint16_t Reserved1;
|
|
uint64_t EditList; // VA
|
|
uint64_t SecurityCookie; // VA
|
|
uint64_t SEHandlerTable; // VA
|
|
uint64_t SEHandlerCount;
|
|
};
|
|
|
|
#pragma pack(pop)
|
|
} //namespace pe_win
|
|
|
|
#ifdef PE_BLISS_WINDOWS
|
|
typedef wchar_t unicode16_t;
|
|
typedef std::basic_string<unicode16_t> u16string;
|
|
#else
|
|
//Instead of wchar_t for windows
|
|
typedef unsigned short unicode16_t;
|
|
typedef std::basic_string<unicode16_t> u16string;
|
|
#endif
|
|
|
|
} //namespace pe_bliss
|