Implement address translation for segments

This commit is contained in:
Serge Lamikhov-Center 2021-09-19 23:26:58 +03:00
parent b527ea992a
commit 511086598a
5 changed files with 48 additions and 31 deletions

View File

@ -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<Elf64_Phdr>( &convertor );
new_segment =
new segment_impl<Elf64_Phdr>( &convertor, &addr_translator );
}
else if ( file_class == ELFCLASS32 ) {
new_segment = new segment_impl<Elf32_Phdr>( &convertor );
new_segment =
new segment_impl<Elf32_Phdr>( &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<Elf64_Phdr>( &convertor );
seg = new segment_impl<Elf64_Phdr>( &convertor,
&addr_translator );
}
else if ( file_class == ELFCLASS32 ) {
seg = new segment_impl<Elf32_Phdr>( &convertor );
seg = new segment_impl<Elf32_Phdr>( &convertor,
&addr_translator );
}
else {
return false;

View File

@ -193,8 +193,13 @@ template <class T> class section_impl : public section
std::fill_n( reinterpret_cast<char*>( &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<char*>( &header ), sizeof( header ) );

View File

@ -71,8 +71,10 @@ template <class T> 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<char*>( &ph ), sizeof( ph ), '\0' );
@ -166,16 +168,20 @@ template <class T> 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<char*>( &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 T> class segment_impl : public segment
//------------------------------------------------------------------------------
private:
T ph;
Elf_Half index;
char* data;
std::vector<Elf_Half> sections;
endianess_convertor* convertor;
bool is_offset_set;
T ph;
Elf_Half index;
char* data;
std::vector<Elf_Half> sections;
const endianess_convertor* convertor;
const address_translator* translator;
bool is_offset_set;
};
} // namespace ELFIO

View File

@ -199,6 +199,8 @@ class address_translator
return value;
}
bool empty() const { return translation.empty(); }
private:
std::vector<address_translation> translation;
};

View File

@ -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"