⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 elfiimpl.cpp

📁 C++写的,提供操作ELF格式文件的API
💻 CPP
字号:
/*
ELFIImpl.cpp - Implementation of the reader class.
Copyright (C) 2001 Serge Lamikhov-Center <to_serge@users.sourceforge.net>

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#include <iosfwd>
#include <algorithm>
#include "ELFIImpl.h"
#include "ELFIOUtils.h"


ELFI::ELFI()
{
    m_nRefCnt      = 1;
    m_nFileOffset  = 0;
    m_bOwnStream   = false;
    m_bInitialized = false;
    std::fill_n( reinterpret_cast<char*>( &m_header ), sizeof( m_header ), '\0' );
}


ELFI::~ELFI()
{
    std::vector<const IELFISection*>::const_iterator it;
    for ( it = m_sections.begin(); it != m_sections.end(); ++it ) {
        delete const_cast<IELFISection*>( *it );
    }
    std::vector<const IELFISegment*>::const_iterator it1;
    for ( it1 = m_segments.begin(); it1 != m_segments.end(); ++it1 ) {
        delete const_cast<IELFISegment*>( *it1 );
    }
    
    if ( m_bOwnStream ) {
        ((std::ifstream*)m_pStream)->close();
        delete m_pStream;
    }
}


ELFIO_Err
ELFI::Load( const std::string& sFileName )
{
    if ( IsInitialized() ) {         // Already opened?
        return ERR_ELFIO_INITIALIZED;
    }

    // Open binary file
    std::ifstream* pS = new std::ifstream;
    if ( 0 == pS ) {
        return ERR_ELFIO_MEMORY;
    }
    pS->open( sFileName.c_str(), std::ios::in | std::ios::binary );
    if ( !*pS ) {
        return ERR_ELFIO_CANT_OPEN;
    }

    ELFIO_Err err = Load( pS, 0 );

    m_bOwnStream = true;

    return err;
}


ELFIO_Err
ELFI::Load( std::istream* pStream, int startPos )
{
    if ( IsInitialized() ) {         // Already opened?
        return ERR_ELFIO_INITIALIZED;
    }

    m_pStream     = pStream;
    m_bOwnStream  = false;
    m_nFileOffset = startPos;

    // Read ELF header
    m_pStream->seekg( m_nFileOffset );
    m_pStream->read( reinterpret_cast<char*>( &m_header ), sizeof( m_header ) );

    // Is it ELF file?
    if ( m_pStream->gcount() != sizeof( m_header ) ||
         m_header.e_ident[EI_MAG0] != ELFMAG0    ||
         m_header.e_ident[EI_MAG1] != ELFMAG1    ||
         m_header.e_ident[EI_MAG2] != ELFMAG2    ||
         m_header.e_ident[EI_MAG3] != ELFMAG3 ) {

        return ERR_ELFIO_NOT_ELF;
    }

    ELFIO_Err nRet = LoadSections();
    if ( ERR_ELFIO_NO_ERROR != nRet ) {
        return nRet;
    }

    nRet = LoadSegments();
    if ( ERR_ELFIO_NO_ERROR != nRet ) {
        return nRet;
    }

    m_bInitialized = true;

    return ERR_ELFIO_NO_ERROR;
}


ELFIO_Err
ELFI::LoadSections()
{
    Elf32_Shdr buffer;
    Elf32_Half nEntrySize = Convert32Half2Host( m_header.e_shentsize, GetEncoding() );
    Elf32_Half nNum       = Convert32Half2Host( m_header.e_shnum, GetEncoding() );
    Elf32_Off  nOff       = Convert32Off2Host( m_header.e_shoff, GetEncoding() );

#ifdef _MSC_VER 
    unsigned int buflen = std::_MIN( sizeof( Elf32_Shdr ), (size_t)nEntrySize );
#else
    unsigned int buflen = std::min( sizeof( Elf32_Shdr ), (std::size_t)nEntrySize );
#endif

    for ( int i = 0; i < nNum; ++i ) {
        m_pStream->seekg( nOff + i * nEntrySize + m_nFileOffset );
        m_pStream->read( reinterpret_cast<char*>( &buffer ), buflen );
        ELFISection* pSec = new ELFISection( this, m_pStream, m_nFileOffset, &buffer, i );

        // Add section into the section container
        m_sections.push_back( pSec );
    }

    return ERR_ELFIO_NO_ERROR;
}


ELFIO_Err
ELFI::LoadSegments()
{
    Elf32_Phdr buffer;
    Elf32_Half nEntrySize = Convert32Half2Host( m_header.e_phentsize, GetEncoding() );
    Elf32_Half nNum       = Convert32Half2Host( m_header.e_phnum, GetEncoding() );
    Elf32_Off  nOff       = Convert32Off2Host( m_header.e_phoff, GetEncoding() );

#ifdef _MSC_VER 
    int buflen = std::_MIN( sizeof( Elf32_Phdr ), (size_t)nEntrySize );
#else
    int buflen = std::min( sizeof( Elf32_Phdr ), (std::size_t)nEntrySize );
#endif

    for ( int i = 0; i < nNum; ++i ) {
        m_pStream->seekg( nOff + i * nEntrySize + m_nFileOffset );
        m_pStream->read( reinterpret_cast<char*>( &buffer ), buflen );
        ELFISegment* pSeg = new ELFISegment( this, m_pStream, m_nFileOffset, &buffer, i );

        // Add section into the section container
        m_segments.push_back( pSeg );
    }

    return ERR_ELFIO_NO_ERROR;
}


bool
ELFI::IsInitialized() const
{
    return m_bInitialized;
}


int
ELFI::AddRef() const
{
    return ++m_nRefCnt;
}


int
ELFI::Release() const
{
    int nRet = --m_nRefCnt;
    if ( 0 == m_nRefCnt ) {
        delete this;
    }

    return nRet;
}


unsigned char
ELFI::GetClass() const
{
    return m_header.e_ident[EI_CLASS];
}


unsigned char
ELFI::GetEncoding() const
{
    return m_header.e_ident[EI_DATA];
}


unsigned char
ELFI::GetELFVersion() const
{
    return m_header.e_ident[EI_VERSION];
}


Elf32_Half
ELFI::GetType() const
{
    return Convert32Half2Host( m_header.e_type, GetEncoding() );
}


Elf32_Half
ELFI::GetMachine() const
{
    return Convert32Half2Host( m_header.e_machine, GetEncoding() );
}


Elf32_Word
ELFI::GetVersion() const
{
    return Convert32Word2Host( m_header.e_version, GetEncoding() );
}


Elf32_Addr
ELFI::GetEntry() const
{
    return Convert32Addr2Host( m_header.e_entry, GetEncoding() );
}


Elf32_Word
ELFI::GetFlags() const
{
    return Convert32Word2Host( m_header.e_flags, GetEncoding() );
}


Elf32_Half
ELFI::GetSecStrNdx() const
{
    return Convert32Half2Host( m_header.e_shstrndx, GetEncoding() );
}


Elf32_Half
ELFI::GetSectionsNum() const
{
    return m_sections.size();
}


const IELFISection*
ELFI::GetSection( Elf32_Half index ) const
{
    if ( index >= GetSectionsNum() ) {
        return 0;
    }
    
    m_sections[index]->AddRef();
    return m_sections[index];
}


const IELFISection*
ELFI::GetSection( const std::string& name ) const
{
    const IELFISection* pRet = 0;
    std::vector<const IELFISection*>::const_iterator it;
    for ( it = m_sections.begin(); it != m_sections.end(); ++it ) {
        if ( (*it)->GetName() == name ) {
            pRet = *it;
            pRet->AddRef();
            break;
        }
    }

    return pRet;
}


Elf32_Half
ELFI::GetSegmentsNum() const
{
    return m_segments.size();
}


const IELFISegment*
ELFI::GetSegment( Elf32_Half index ) const
{
    if ( index >= GetSegmentsNum() ) {
        return 0;
    }
    m_segments[index]->AddRef();
    return m_segments[index];
}


ELFIO_Err
ELFI::CreateSectionReader( ReaderType type, const IELFISection* pSection,
                           void** ppObj ) const
{
    ELFIO_Err eRet = ERR_ELFIO_NO_ERROR;
    
    switch ( type ) {
    case ELFI_STRING:
        *ppObj = (IELFIStringReader*)( new ELFIStringReader( this, pSection ) );
        break;
    case ELFI_SYMBOL:
        *ppObj = (IELFISymbolTable*)( new ELFISymbolTable( this, pSection ) );
        break;
    case ELFI_RELOCATION:
        *ppObj = (IELFIRelocationTable*)( new ELFIRelocationTable( this, pSection ) );
        break;
    case ELFI_NOTE:
        *ppObj = (IELFINoteReader*)( new ELFINoteReader( this, pSection ) );
        break;
    case ELFI_DYNAMIC:
        *ppObj = (IELFIDynamicReader*)( new ELFIDynamicReader( this, pSection ) );
        break;
    default:
        eRet  = ERR_NO_SUCH_READER;
        ppObj = 0;
    }
    return eRet;
}


ELFIReaderImpl::ELFIReaderImpl( const IELFI* pIELFI, const IELFISection* pSection )
{
    m_nRefCnt  = 1;
    m_pIELFI   = pIELFI;
    m_pSection = pSection;
    m_pIELFI->AddRef();
    m_pSection->AddRef();
}


ELFIReaderImpl::~ELFIReaderImpl()
{
}


int
ELFIReaderImpl::AddRef() const
{
    m_pIELFI->AddRef();
    m_pSection->AddRef();
    return ++m_nRefCnt;
}


int
ELFIReaderImpl::Release() const
{
    m_pSection->Release();
    m_pIELFI->Release();

    int nRet = --m_nRefCnt;
    if ( 0 == m_nRefCnt ) {
        delete this;
    }

    return nRet;
}


Elf32_Half
ELFIReaderImpl::GetIndex() const
{
    return m_pSection->GetIndex();
}


std::string
ELFIReaderImpl::GetName() const
{
    return m_pSection->GetName();
}


Elf32_Word
ELFIReaderImpl::GetType() const
{
    return m_pSection->GetType();
}


Elf32_Word
ELFIReaderImpl::GetFlags() const
{
    return m_pSection->GetFlags();
}


Elf32_Addr
ELFIReaderImpl::GetAddress() const
{
    return m_pSection->GetAddress();
}


Elf32_Word
ELFIReaderImpl::GetSize() const
{
    return m_pSection->GetSize();
}


Elf32_Word
ELFIReaderImpl::GetLink() const
{
    return m_pSection->GetLink();
}


Elf32_Word
ELFIReaderImpl::GetInfo() const
{
    return m_pSection->GetInfo();
}


Elf32_Word
ELFIReaderImpl::GetAddrAlign() const
{
    return m_pSection->GetAddrAlign();
}


Elf32_Word
ELFIReaderImpl::GetEntrySize() const
{
    return m_pSection->GetEntrySize();
}


const char*
ELFIReaderImpl::GetData() const
{
    return m_pSection->GetData();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -