From 511086598ae3169f3143f1e495884a98eefe7318 Mon Sep 17 00:00:00 2001 From: Serge Lamikhov-Center Date: Sun, 19 Sep 2021 23:26:58 +0300 Subject: [PATCH] Implement address translation for segments --- elfio/elfio.hpp | 32 ++++++++++++++++++-------------- elfio/elfio_section.hpp | 9 +++++++-- elfio/elfio_segment.hpp | 33 ++++++++++++++++++++------------- elfio/elfio_utils.hpp | 2 ++ examples/proc_mem/proc_mem.cpp | 3 +-- 5 files changed, 48 insertions(+), 31 deletions(-) diff --git a/elfio/elfio.hpp b/elfio/elfio.hpp index 5d38065..acdf7c1 100644 --- a/elfio/elfio.hpp +++ b/elfio/elfio.hpp @@ -77,11 +77,11 @@ class elfio elfio( elfio&& other ) noexcept : sections( this ), segments( this ) { - header = std::move(other.header); - sections_ = std::move(other.sections_); - segments_ = std::move(other.segments_); - convertor = std::move(other.convertor); - current_file_pos = std::move(other.current_file_pos); + header = std::move( other.header ); + sections_ = std::move( other.sections_ ); + segments_ = std::move( other.segments_ ); + convertor = std::move( other.convertor ); + current_file_pos = std::move( other.current_file_pos ); other.header = nullptr; other.sections_.clear(); @@ -93,11 +93,11 @@ class elfio if ( this != &other ) { clean(); - header = std::move(other.header); - sections_ = std::move(other.sections_); - segments_ = std::move(other.segments_); - convertor = std::move(other.convertor); - current_file_pos = std::move(other.current_file_pos); + header = std::move( other.header ); + sections_ = std::move( other.sections_ ); + segments_ = std::move( other.segments_ ); + convertor = std::move( other.convertor ); + current_file_pos = std::move( other.current_file_pos ); other.header = nullptr; other.sections_.clear(); @@ -445,10 +445,12 @@ class elfio unsigned char file_class = header->get_class(); if ( file_class == ELFCLASS64 ) { - new_segment = new segment_impl( &convertor ); + new_segment = + new segment_impl( &convertor, &addr_translator ); } else if ( file_class == ELFCLASS32 ) { - new_segment = new segment_impl( &convertor ); + new_segment = + new segment_impl( &convertor, &addr_translator ); } else { return nullptr; @@ -539,10 +541,12 @@ class elfio unsigned char file_class = header->get_class(); if ( file_class == ELFCLASS64 ) { - seg = new segment_impl( &convertor ); + seg = new segment_impl( &convertor, + &addr_translator ); } else if ( file_class == ELFCLASS32 ) { - seg = new segment_impl( &convertor ); + seg = new segment_impl( &convertor, + &addr_translator ); } else { return false; diff --git a/elfio/elfio_section.hpp b/elfio/elfio_section.hpp index 2097e0b..8095b82 100644 --- a/elfio/elfio_section.hpp +++ b/elfio/elfio_section.hpp @@ -193,8 +193,13 @@ template class section_impl : public section std::fill_n( reinterpret_cast( &header ), sizeof( header ), '\0' ); - // stream.seekg( 0, stream.end ); - set_stream_size( 0xFFFFFFFF /*stream.tellg()*/ ); + if ( translator->empty() ) { + stream.seekg( 0, stream.end ); + set_stream_size( stream.tellg() ); + } + else { + set_stream_size( 0xFFFFFFFFFFFFFFFF ); + } stream.seekg( ( *translator )( header_offset ) ); stream.read( reinterpret_cast( &header ), sizeof( header ) ); diff --git a/elfio/elfio_segment.hpp b/elfio/elfio_segment.hpp index 89ec2f1..eb532d0 100644 --- a/elfio/elfio_segment.hpp +++ b/elfio/elfio_segment.hpp @@ -71,8 +71,10 @@ template class segment_impl : public segment { public: //------------------------------------------------------------------------------ - segment_impl( endianess_convertor* convertor ) - : stream_size( 0 ), index( 0 ), data( nullptr ), convertor( convertor ) + segment_impl( const endianess_convertor* convertor, + const address_translator* translator ) + : convertor( convertor ), translator( translator ), stream_size( 0 ), + index( 0 ), data( nullptr ) { is_offset_set = false; std::fill_n( reinterpret_cast( &ph ), sizeof( ph ), '\0' ); @@ -166,16 +168,20 @@ template class segment_impl : public segment //------------------------------------------------------------------------------ void load( std::istream& stream, std::streampos header_offset ) override { + if ( translator->empty() ) { + stream.seekg( 0, stream.end ); + set_stream_size( stream.tellg() ); + } + else { + set_stream_size( 0xFFFFFFFFFFFFFFFF ); + } - stream.seekg( 0, stream.end ); - set_stream_size( stream.tellg() ); - - stream.seekg( header_offset ); + stream.seekg( ( *translator )( header_offset ) ); stream.read( reinterpret_cast( &ph ), sizeof( ph ) ); is_offset_set = true; if ( PT_NULL != get_type() && 0 != get_file_size() ) { - stream.seekg( ( *convertor )( ph.p_offset ) ); + stream.seekg( ( *translator )( ( *convertor )( ph.p_offset ) ) ); Elf_Xword size = get_file_size(); if ( size > get_stream_size() ) { @@ -205,12 +211,13 @@ template class segment_impl : public segment //------------------------------------------------------------------------------ private: - T ph; - Elf_Half index; - char* data; - std::vector sections; - endianess_convertor* convertor; - bool is_offset_set; + T ph; + Elf_Half index; + char* data; + std::vector sections; + const endianess_convertor* convertor; + const address_translator* translator; + bool is_offset_set; }; } // namespace ELFIO diff --git a/elfio/elfio_utils.hpp b/elfio/elfio_utils.hpp index 287a058..0b2f49e 100644 --- a/elfio/elfio_utils.hpp +++ b/elfio/elfio_utils.hpp @@ -199,6 +199,8 @@ class address_translator return value; } + bool empty() const { return translation.empty(); } + private: std::vector translation; }; diff --git a/examples/proc_mem/proc_mem.cpp b/examples/proc_mem/proc_mem.cpp index 3f35122..0b290a1 100644 --- a/examples/proc_mem/proc_mem.cpp +++ b/examples/proc_mem/proc_mem.cpp @@ -88,9 +88,8 @@ int main( int argc, char** argv ) if ( elffile.load( std::string( "/proc/" ) + argv[1] + "/mem" ) ) { dump::header( std::cout, elffile ); - dump::section_headers( std::cout, elffile ); dump::segment_headers( std::cout, elffile ); - dump::symbol_tables( std::cout, elffile ); + dump::segment_datas( std::cout, elffile ); } else { std::cout << "Can't open " << std::string( "/proc/" ) + argv[1] + "/mem"