// Copyright 2014 Renato Tegon Forti, Antony Polukhin. // Copyright 2015-2019 Antony Polukhin. // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) // For more information, see http://www.boost.org #include #include #include #include #include #include #if BOOST_OS_WINDOWS # include #elif BOOST_OS_MACOS || BOOST_OS_IOS # include # include #elif BOOST_OS_QNX // QNX's copy of and reside in sys folder # include #else #include #endif namespace dd = boost::dll::detail; template inline std::size_t get_offset(const T1& v1, const T2& v2) { const unsigned char* p1 = reinterpret_cast(&v1); const unsigned char* p2 = reinterpret_cast(&v2); if (p1 < p2) { return static_cast(p2 - p1); } return static_cast(p1 - p2); } #define CHECK_FIELD(Field) \ BOOST_STATIC_ASSERT(sizeof(v1.Field) == sizeof(v2.Field)); \ BOOST_TEST(get_offset(v1, v1.Field) == get_offset(v2, v2.Field)) \ /**/ // ELF structures template void elf_header_checks(const T1& v1, const T2& v2) { BOOST_STATIC_ASSERT(sizeof(T1) == sizeof(T2)); CHECK_FIELD(e_ident); CHECK_FIELD(e_type); CHECK_FIELD(e_machine); CHECK_FIELD(e_version); CHECK_FIELD(e_entry); CHECK_FIELD(e_phoff); CHECK_FIELD(e_shoff); CHECK_FIELD(e_flags); CHECK_FIELD(e_ehsize); CHECK_FIELD(e_phentsize); CHECK_FIELD(e_phnum); CHECK_FIELD(e_shentsize); CHECK_FIELD(e_shnum); CHECK_FIELD(e_shstrndx); } template void elf_sheader_checks(const T1& v1, const T2& v2) { BOOST_STATIC_ASSERT(sizeof(T1) == sizeof(T2)); CHECK_FIELD(sh_name); CHECK_FIELD(sh_type); CHECK_FIELD(sh_flags); CHECK_FIELD(sh_addr); CHECK_FIELD(sh_offset); CHECK_FIELD(sh_size); CHECK_FIELD(sh_link); CHECK_FIELD(sh_info); CHECK_FIELD(sh_addralign); CHECK_FIELD(sh_entsize); } template void elf_sym_header_checks(const T1& v1, const T2& v2) { BOOST_STATIC_ASSERT(sizeof(T1) == sizeof(T2)); CHECK_FIELD(st_name); CHECK_FIELD(st_value); CHECK_FIELD(st_size); CHECK_FIELD(st_info); CHECK_FIELD(st_other); CHECK_FIELD(st_shndx); } // PE structures template void generic_header_check(const T& v1, const dd::IMAGE_DOS_HEADER_& v2) { BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2)); CHECK_FIELD(e_magic); CHECK_FIELD(e_cblp); CHECK_FIELD(e_cp); CHECK_FIELD(e_crlc); CHECK_FIELD(e_cparhdr); CHECK_FIELD(e_minalloc); CHECK_FIELD(e_maxalloc); CHECK_FIELD(e_ss); CHECK_FIELD(e_sp); CHECK_FIELD(e_csum); CHECK_FIELD(e_ip); CHECK_FIELD(e_cs); CHECK_FIELD(e_lfarlc); CHECK_FIELD(e_ovno); CHECK_FIELD(e_res); CHECK_FIELD(e_oemid); CHECK_FIELD(e_oeminfo); CHECK_FIELD(e_res2); CHECK_FIELD(e_lfanew); } template void generic_header_check(const T& v1, const dd::IMAGE_FILE_HEADER_& v2) { BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2)); CHECK_FIELD(Machine); CHECK_FIELD(NumberOfSections); CHECK_FIELD(TimeDateStamp); CHECK_FIELD(PointerToSymbolTable); CHECK_FIELD(NumberOfSymbols); CHECK_FIELD(SizeOfOptionalHeader); CHECK_FIELD(Characteristics); } template void generic_header_check(const T& v1, const dd::IMAGE_DATA_DIRECTORY_& v2) { BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2)); CHECK_FIELD(VirtualAddress); CHECK_FIELD(Size); } template void generic_header_check(const T& v1, const dd::IMAGE_EXPORT_DIRECTORY_& v2) { BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2)); CHECK_FIELD(Characteristics); CHECK_FIELD(TimeDateStamp); CHECK_FIELD(MajorVersion); CHECK_FIELD(MinorVersion); CHECK_FIELD(Name); CHECK_FIELD(Base); CHECK_FIELD(NumberOfFunctions); CHECK_FIELD(NumberOfNames); CHECK_FIELD(AddressOfFunctions); CHECK_FIELD(AddressOfNames); CHECK_FIELD(AddressOfNameOrdinals); } template void generic_header_check(const T& v1, const dd::IMAGE_SECTION_HEADER_& v2) { BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2)); CHECK_FIELD(Name); CHECK_FIELD(VirtualAddress); CHECK_FIELD(SizeOfRawData); CHECK_FIELD(PointerToRawData); CHECK_FIELD(PointerToRelocations); CHECK_FIELD(PointerToLinenumbers); CHECK_FIELD(NumberOfRelocations); CHECK_FIELD(NumberOfLinenumbers); CHECK_FIELD(Characteristics); } template void generic_header_check(const T& v1, const dd::IMAGE_OPTIONAL_HEADER_template& v2) { BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2)); CHECK_FIELD(Magic); CHECK_FIELD(MajorLinkerVersion); CHECK_FIELD(MinorLinkerVersion); CHECK_FIELD(SizeOfCode); CHECK_FIELD(SizeOfInitializedData); CHECK_FIELD(SizeOfUninitializedData); CHECK_FIELD(AddressOfEntryPoint); CHECK_FIELD(ImageBase); CHECK_FIELD(SectionAlignment); CHECK_FIELD(FileAlignment); CHECK_FIELD(MajorOperatingSystemVersion); CHECK_FIELD(MinorOperatingSystemVersion); CHECK_FIELD(MajorImageVersion); CHECK_FIELD(MinorImageVersion); CHECK_FIELD(MajorSubsystemVersion); CHECK_FIELD(MinorSubsystemVersion); CHECK_FIELD(Win32VersionValue); CHECK_FIELD(SizeOfImage); CHECK_FIELD(SizeOfHeaders); CHECK_FIELD(CheckSum); CHECK_FIELD(Subsystem); CHECK_FIELD(DllCharacteristics); CHECK_FIELD(SizeOfStackReserve); CHECK_FIELD(SizeOfStackCommit); CHECK_FIELD(SizeOfHeapReserve); CHECK_FIELD(SizeOfHeapCommit); CHECK_FIELD(LoaderFlags); CHECK_FIELD(NumberOfRvaAndSizes); CHECK_FIELD(DataDirectory); } template void generic_header_check(const T& v1, const dd::IMAGE_NT_HEADERS_template& v2) { BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2)); CHECK_FIELD(Signature); CHECK_FIELD(FileHeader); CHECK_FIELD(OptionalHeader); } template void generic_header_check(const T& v1, const dd::mach_header_template& v2) { BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2)); CHECK_FIELD(magic); CHECK_FIELD(cputype); CHECK_FIELD(cpusubtype); CHECK_FIELD(filetype); CHECK_FIELD(ncmds); CHECK_FIELD(sizeofcmds); //CHECK_FIELD(flags); } template void generic_header_check(const T& v1, const dd::segment_command_template& v2) { BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2)); CHECK_FIELD(cmd); CHECK_FIELD(cmdsize); CHECK_FIELD(segname); CHECK_FIELD(vmaddr); CHECK_FIELD(vmsize); CHECK_FIELD(fileoff); CHECK_FIELD(filesize); CHECK_FIELD(maxprot); CHECK_FIELD(initprot); CHECK_FIELD(nsects); CHECK_FIELD(flags); } template void generic_header_check(const T& v1, const dd::section_template& v2) { BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2)); CHECK_FIELD(sectname); CHECK_FIELD(segname); CHECK_FIELD(addr); CHECK_FIELD(size); CHECK_FIELD(offset); CHECK_FIELD(align); CHECK_FIELD(reloff); CHECK_FIELD(nreloc); CHECK_FIELD(flags); //CHECK_FIELD(reserved vs reserveed1&reserved2); } template void generic_header_check(const T& v1, const dd::symtab_command_& v2) { BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2)); CHECK_FIELD(cmd); CHECK_FIELD(cmdsize); CHECK_FIELD(symoff); CHECK_FIELD(nsyms); CHECK_FIELD(stroff); CHECK_FIELD(strsize); } template void generic_header_check(const T& v1, const dd::nlist_template& v2) { BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2)); //CHECK_FIELD(n_strx); CHECK_FIELD(n_type); CHECK_FIELD(n_sect); CHECK_FIELD(n_desc); CHECK_FIELD(n_value); } template void generic_header_check(const T& v1, const dd::load_command_& v2) { BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2)); CHECK_FIELD(cmd); CHECK_FIELD(cmdsize); } // Unit Tests int main(int /*argc*/, char* /*argv*/[]) { #if BOOST_OS_WINDOWS generic_header_check(::IMAGE_DOS_HEADER(), dd::IMAGE_DOS_HEADER_()); generic_header_check(::IMAGE_FILE_HEADER(), dd::IMAGE_FILE_HEADER_()); generic_header_check(::IMAGE_DATA_DIRECTORY(), dd::IMAGE_DATA_DIRECTORY_()); generic_header_check(::IMAGE_EXPORT_DIRECTORY(), dd::IMAGE_EXPORT_DIRECTORY_()); generic_header_check(::IMAGE_SECTION_HEADER(), dd::IMAGE_SECTION_HEADER_()); generic_header_check(::IMAGE_OPTIONAL_HEADER32(), dd::IMAGE_OPTIONAL_HEADER32_()); generic_header_check(::IMAGE_OPTIONAL_HEADER64(), dd::IMAGE_OPTIONAL_HEADER64_()); generic_header_check(::IMAGE_NT_HEADERS32(), dd::IMAGE_NT_HEADERS32_()); generic_header_check(::IMAGE_NT_HEADERS64(), dd::IMAGE_NT_HEADERS64_()); #elif BOOST_OS_MACOS || BOOST_OS_IOS generic_header_check(::mach_header(), dd::mach_header_32_()); generic_header_check(::mach_header_64(), dd::mach_header_64_()); generic_header_check(::segment_command(), dd::segment_command_32_()); generic_header_check(::segment_command_64(), dd::segment_command_64_()); generic_header_check(::section(), dd::section_32_()); generic_header_check(::section_64(), dd::section_64_()); generic_header_check(::load_command(), dd::load_command_()); generic_header_check(::symtab_command(), dd::symtab_command_()); struct ::nlist nl32_var; generic_header_check(nl32_var, dd::nlist_32_()); struct ::nlist_64 nl64_var; generic_header_check(nl64_var, dd::nlist_64_()); #else elf_header_checks(::Elf32_Ehdr(), dd::Elf32_Ehdr_()); elf_header_checks(::Elf64_Ehdr(), dd::Elf64_Ehdr_()); elf_sheader_checks(::Elf32_Shdr(), dd::Elf32_Shdr_()); elf_sheader_checks(::Elf64_Shdr(), dd::Elf64_Shdr_()); elf_sym_header_checks(::Elf32_Sym(), dd::Elf32_Sym_()); elf_sym_header_checks(::Elf64_Sym(), dd::Elf64_Sym_()); #endif return boost::report_errors(); }