diff --git a/include/LIEF/PE/enums.hpp.in b/include/LIEF/PE/enums.hpp.in index 3ba5cec3e2..3f58087a9e 100644 --- a/include/LIEF/PE/enums.hpp.in +++ b/include/LIEF/PE/enums.hpp.in @@ -23,7 +23,8 @@ enum class PE_SECTION_TYPES : uint8_t { EXPORT = 7, DEBUG = 8, LOAD_CONFIG = 9, - UNKNOWN = 10 + UNKNOWN = 10, + OLD_IMPORT = 100 }; enum class PE_TYPE : uint16_t { diff --git a/src/PE/Builder.tcc b/src/PE/Builder.tcc index 65d9db7d92..bf20272438 100644 --- a/src/PE/Builder.tcc +++ b/src/PE/Builder.tcc @@ -168,20 +168,32 @@ void Builder::build_import_table(void) { // Remove 'import' type from the original section if (it_import_section != std::end(this->binary_->sections_)) { (*it_import_section)->remove_type(PE_SECTION_TYPES::IMPORT); + (*it_import_section)->add_type(PE_SECTION_TYPES::OLD_IMPORT); } // As add_section will change DATA_DIRECTORY::IMPORT_TABLE we have to save it before uint32_t offset_imports = this->binary_->rva_to_offset(this->binary_->data_directory(DATA_DIRECTORY::IMPORT_TABLE).RVA()); + auto offset_imports_in_section = offset_imports - this->binary_->section_from_offset(offset_imports).offset(); Section& import_section = this->binary_->add_section(new_import_section, PE_SECTION_TYPES::IMPORT); - // Patch the original IAT with the address of the associated trampoline if (this->patch_imports_) { - Section& original_import = this->binary_->section_from_offset(offset_imports); + auto&& original_import_section = std::find_if( + std::begin(this->binary_->sections_), + std::end(this->binary_->sections_), + [] (const Section* section) { + return section != nullptr and section->is_type(PE_SECTION_TYPES::OLD_IMPORT); + }); + // fallback mechanism + const auto is_found = original_import_section != std::end(this->binary_->sections_); + if (is_found) { + (*original_import_section)->remove_type(PE_SECTION_TYPES::OLD_IMPORT); + } + auto original_import_offset = is_found ? (*original_import_section)->pointerto_raw_data() : 0; + Section& original_import = this->binary_->section_from_offset(is_found ? original_import_offset: offset_imports); std::vector import_content = original_import.content(); - uint32_t roffset_import = offset_imports - original_import.offset(); - pe_import *import_header = reinterpret_cast(import_content.data() + roffset_import); + pe_import *import_header = reinterpret_cast(import_content.data() + offset_imports_in_section); uint32_t jumpOffsetTmp = trampolines_offset; while (import_header->ImportAddressTableRVA != 0) { uint32_t offsetTable = this->binary_->rva_to_offset(import_header->ImportLookupTableRVA) - original_import.pointerto_raw_data();