diff --git a/ELFIOTest/ELFIOTest1.cpp b/ELFIOTest/ELFIOTest1.cpp index 48d6a18..88ab2f4 100644 --- a/ELFIOTest/ELFIOTest1.cpp +++ b/ELFIOTest/ELFIOTest1.cpp @@ -133,7 +133,7 @@ BOOST_AUTO_TEST_CASE( write_obj_i386_64 ) BOOST_CHECK( output.match_pattern() ); } -bool write_exe_i386( bool is64bit ) +bool write_exe_i386( bool is64bit, bool set_addr = false, Elf64_Addr addr = 0 ) { elfio writer; @@ -147,6 +147,9 @@ bool write_exe_i386( bool is64bit ) text_sec->set_type( SHT_PROGBITS ); text_sec->set_flags( SHF_ALLOC | SHF_EXECINSTR ); text_sec->set_addr_align( 0x10 ); + if ( set_addr ) { + text_sec->set_address( addr ); + } // Add data into it char text[] = { '\xB8', '\x04', '\x00', '\x00', '\x00', // mov eax, 4 @@ -316,3 +319,24 @@ BOOST_AUTO_TEST_CASE( elf_exe_copy_32 ) checkExeAreEqual( "../elf_examples/test_ppc", "../elf_examples/test_ppc_copy" ); } + + +//////////////////////////////////////////////////////////////////////////////// +BOOST_AUTO_TEST_CASE( section_header_address_update ) +{ + elfio reader; + + write_exe_i386( false, true, 0x0100 ); + + reader.load( "../elf_examples/write_exe_i386_32" ); + section* sec = reader.sections[".text"]; + BOOST_REQUIRE_NE( sec, (section*)0 ); + BOOST_CHECK_EQUAL( sec->get_address(), 0x00000100 ); + + write_exe_i386( false, false, 0 ); + + reader.load( "../elf_examples/write_exe_i386_32" ); + sec = reader.sections[".text"]; + BOOST_REQUIRE_NE( sec, (section*)0 ); + BOOST_CHECK_EQUAL( sec->get_address(), 0x08048000 ); +} diff --git a/elfio/elfio.hpp b/elfio/elfio.hpp index 00f3f46..705dae2 100644 --- a/elfio/elfio.hpp +++ b/elfio/elfio.hpp @@ -471,8 +471,9 @@ class elfio std::streampos headerPosition = (std::streamoff)header->get_sections_offset() + header->get_section_entry_size()*sec->get_index(); - // TODO: Fix this - sec->set_address( segments[i]->get_virtual_address() ); + if ( !sec->is_address_initialized() ) { + sec->set_address( segments[i]->get_virtual_address() ); + } sec->save( f, headerPosition, (std::streamoff)current_data_pos ); current_data_pos += sec->get_size(); } diff --git a/elfio/elfio_section.hpp b/elfio/elfio_section.hpp index 10f4759..9c1f0ef 100644 --- a/elfio/elfio_section.hpp +++ b/elfio/elfio_section.hpp @@ -72,6 +72,7 @@ class section virtual void save( std::ofstream& f, std::streampos header_offset, std::streampos data_offset ) = 0; + virtual bool is_address_initialized() = 0; }; @@ -83,8 +84,9 @@ class section_impl : public section section_impl( const endianess_convertor* convertor_ ) : convertor( convertor_ ) { std::fill_n( reinterpret_cast( &header ), sizeof( header ), '\0' ); - data = 0; - data_size = 0; + is_address_set = false; + data = 0; + data_size = 0; } //------------------------------------------------------------------------------ @@ -95,15 +97,15 @@ class section_impl : public section //------------------------------------------------------------------------------ // Section info functions - ELFIO_GET_SET_ACCESS( Elf_Word, type, header.sh_type ) - ELFIO_GET_SET_ACCESS( Elf_Xword, flags, header.sh_flags ) - ELFIO_GET_SET_ACCESS( Elf64_Addr, address, header.sh_addr ) - ELFIO_GET_SET_ACCESS( Elf_Xword, size, header.sh_size ) - ELFIO_GET_SET_ACCESS( Elf_Word, link, header.sh_link ) - ELFIO_GET_SET_ACCESS( Elf_Word, info, header.sh_info ) - ELFIO_GET_SET_ACCESS( Elf_Xword, addr_align, header.sh_addralign ) - ELFIO_GET_SET_ACCESS( Elf_Xword, entry_size, header.sh_entsize ) - ELFIO_GET_SET_ACCESS( Elf_Word, name_string_offset, header.sh_name ) + ELFIO_GET_SET_ACCESS( Elf_Word, type, header.sh_type ); + ELFIO_GET_SET_ACCESS( Elf_Xword, flags, header.sh_flags ); + ELFIO_GET_SET_ACCESS( Elf_Xword, size, header.sh_size ); + ELFIO_GET_SET_ACCESS( Elf_Word, link, header.sh_link ); + ELFIO_GET_SET_ACCESS( Elf_Word, info, header.sh_info ); + ELFIO_GET_SET_ACCESS( Elf_Xword, addr_align, header.sh_addralign ); + ELFIO_GET_SET_ACCESS( Elf_Xword, entry_size, header.sh_entsize ); + ELFIO_GET_SET_ACCESS( Elf_Word, name_string_offset, header.sh_name ); + ELFIO_GET_ACCESS ( Elf64_Addr, address, header.sh_addr ); //------------------------------------------------------------------------------ Elf_Half @@ -127,6 +129,22 @@ class section_impl : public section name = name_; } +//------------------------------------------------------------------------------ + void + set_address( Elf64_Addr value ) + { + header.sh_addr = value; + header.sh_addr = (*convertor)( header.sh_addr ); + is_address_set = true; + } + +//------------------------------------------------------------------------------ + bool + is_address_initialized() + { + return is_address_set; + } + //------------------------------------------------------------------------------ const char* get_data() const @@ -225,7 +243,8 @@ class section_impl : public section } save_header( f, header_offset ); - if ( get_type() != SHT_NOBITS && get_type() != SHT_NULL && get_size() != 0 && data != 0 ) { + if ( get_type() != SHT_NOBITS && get_type() != SHT_NULL && + get_size() != 0 && data != 0 ) { save_data( f, data_offset ); } } @@ -258,6 +277,7 @@ class section_impl : public section mutable char* data; Elf_Word data_size; const endianess_convertor* convertor; + bool is_address_set; }; } // namespace ELFIO diff --git a/elfio/elfio_segment.hpp b/elfio/elfio_segment.hpp index 41483a9..e8c3004 100644 --- a/elfio/elfio_segment.hpp +++ b/elfio/elfio_segment.hpp @@ -88,13 +88,13 @@ class segment_impl : public segment //------------------------------------------------------------------------------ // Section info functions - ELFIO_GET_SET_ACCESS( Elf_Word, type, ph.p_type ) - ELFIO_GET_SET_ACCESS( Elf_Word, flags, ph.p_flags ) - ELFIO_GET_SET_ACCESS( Elf_Xword, align, ph.p_align ) - ELFIO_GET_SET_ACCESS( Elf64_Addr, virtual_address, ph.p_vaddr ) - ELFIO_GET_SET_ACCESS( Elf64_Addr, physical_address, ph.p_paddr ) - ELFIO_GET_SET_ACCESS( Elf_Xword, file_size, ph.p_filesz ) - ELFIO_GET_SET_ACCESS( Elf_Xword, memory_size, ph.p_memsz ) + ELFIO_GET_SET_ACCESS( Elf_Word, type, ph.p_type ); + ELFIO_GET_SET_ACCESS( Elf_Word, flags, ph.p_flags ); + ELFIO_GET_SET_ACCESS( Elf_Xword, align, ph.p_align ); + ELFIO_GET_SET_ACCESS( Elf64_Addr, virtual_address, ph.p_vaddr ); + ELFIO_GET_SET_ACCESS( Elf64_Addr, physical_address, ph.p_paddr ); + ELFIO_GET_SET_ACCESS( Elf_Xword, file_size, ph.p_filesz ); + ELFIO_GET_SET_ACCESS( Elf_Xword, memory_size, ph.p_memsz ); //------------------------------------------------------------------------------ Elf_Half