Android Open Source - strip-elf-section-header Elf32 File






From Project

Back to project page strip-elf-section-header.

License

The source code is released under:

MIT License

If you think the Android project strip-elf-section-header listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * The MIT License/*from w w  w  . j  ava2 s . c  o m*/
 * 
 * Copyright (C) 2013 Kiyofumi Kondoh
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package jp.ne.sakura.kkkon.StripElfSectionHeader.ElfFile;

import java.io.RandomAccessFile;
import java.io.IOException;

/**
 *
 * @author Kiyofumi Kondoh
 */
public class Elf32File
    implements IElfFile
{

    static final class ElfHeader
    {
        byte[]  e_ident = new byte[IElfFile.EI_NINDENT];
        short   e_type;
        short   e_machine;
        int     e_version;
        int     e_entry;
        int     e_phoff;
        int     e_shoff;
        int     e_flags;
        short   e_ehsize;
        short   e_phentsize;
        short   e_phnum;
        short   e_shentsize;
        short   e_shnum;
        short   e_shstrndx;

        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();
            for ( int index = 0; index < e_ident.length; ++index )
            {
                sb.append( String.format( "0x%02X ", e_ident[index] & 0xFF ) );
            }
            return "Header{"
                    + "e_ident=" + sb.toString() + System.getProperty("line.separator")
                    + ", e_type=0x" + Integer.toHexString(e_type & 0xFFFF)
                    + ", e_machine=0x" + Integer.toHexString(e_machine & 0xFFFF)
                    + ", e_version=0x" + Integer.toHexString(e_version)
                    + ", e_entry=0x" + Integer.toHexString(e_entry)
                    + ", e_phoff=0x" + Integer.toHexString(e_phoff)
                    + ", e_shoff=0x" + Integer.toHexString(e_shoff)
                    + ", e_flags=0x" + Integer.toHexString(e_flags)
                    + ", e_ehsize=0x" + Integer.toHexString(e_ehsize & 0xFFFF)
                    + ", e_phentsize=0x" + Integer.toHexString(e_phentsize & 0xFFFF)
                    + ", e_phnum=0x" + Integer.toHexString(e_phnum & 0xFFFF)
                    + ", e_shentsize=0x" + Integer.toHexString(e_shentsize & 0xFFFF)
                    + ", e_shnum=0x" + Integer.toHexString(e_shnum & 0xFFFF)
                    + ", e_shstrndx=0x" + Integer.toHexString(e_shstrndx & 0xFFFF)
                    + '}';
        }
        
    }

    static final class ProgramHeader
    {
        int     p_type;
        int     p_offset;
        int     p_vaddr;
        int     p_paddr;
        int     p_filesz;
        int     p_memsz;
        int     p_flags;
        int     p_align;

        @Override
        public String toString() {
            return "ProgramHeader{"
                    + "p_type=" + Integer.toHexString(p_type)
                    + ", p_offset=" + Integer.toHexString(p_offset)
                    + ", p_vaddr=" + Integer.toHexString(p_vaddr)
                    + ", p_paddr=" + Integer.toHexString(p_paddr)
                    + ", p_filesz=" + Integer.toHexString(p_filesz)
                    + ", p_memsz=" + Integer.toHexString(p_memsz)
                    + ", p_flags=" + Integer.toHexString(p_flags)
                    + ", p_align=" + Integer.toHexString(p_align)
                    + '}';
        }
        
    }

    static final class SectionHeader
    {
        int     sh_name;
        int     sh_type;
        int     sh_flags;
        int     sh_addr;
        int     sh_offset;
        int     sh_size;
        int     sh_link;
        int     sh_info;
        int     sh_addralign;
        int     sh_entsize;

        @Override
        public String toString() {
            return "SectionHeader{"
                    + "sh_name=" + Integer.toHexString(sh_name)
                    + ", sh_type=" + Integer.toHexString(sh_type)
                    + ", sh_flags=" + Integer.toHexString(sh_flags)
                    + ", sh_addr=" + Integer.toHexString(sh_addr)
                    + ", sh_offset=" + Integer.toHexString(sh_offset)
                    + ", sh_size=" + Integer.toHexString(sh_size)
                    + ", sh_link=" + Integer.toHexString(sh_link)
                    + ", sh_info=" + Integer.toHexString(sh_info)
                    + ", sh_addralign=" + Integer.toHexString(sh_addralign)
                    + ", sh_entsize=" + Integer.toHexString(sh_entsize)
                    + '}';
        }
        
    }

    public boolean isElfMagic()
    {
        return ElfFile.isElfMagic(  header.e_ident );
    }

    public boolean isElf32()
    {
        return ElfFile.isElf32(  header.e_ident );
    }

    public boolean isElf64()
    {
        return ElfFile.isElf64(  header.e_ident );
    }

    public boolean isElfLittleEndian()
    {
        return ElfFile.isElfLittleEndian(  header.e_ident );
    }

    public boolean isElfBigEndian()
    {
        return ElfFile.isElfBigEndian(  header.e_ident );
    }
    
    
    
    protected ElfHeader  header = new ElfHeader();
    public boolean readElfHeader( final RandomAccessFile input )
            throws IOException
    {
        {
            final long current = input.getFilePointer();
            if ( 0 != current )
            {
                input.seek( 0 );
            }

            final int result = input.read( header.e_ident );
            if ( header.e_ident.length != result )
            {
                return false;
            }
        }
        
        if ( ! isElfMagic() )
        {
            return false;
        }
        
        if ( ! isElf32() )
        {
            return false;
        }

        final boolean isBigEndian = isElfBigEndian();
        final boolean isLittleEndian = isElfLittleEndian();
        {
            if ( isBigEndian || isLittleEndian )
            {
            }
            else
            {
                throw new RuntimeException("unknown endian");
            }
        }
        
        final long current = input.getFilePointer();
        if ( IElfFile.EI_NINDENT != current )
        {
            input.seek( IElfFile.EI_NINDENT );
        }
        
        {
            if ( isBigEndian || isLittleEndian )
            {
                byte[] byte4 = new byte[4];

                header.e_type       = Util.read2byte( byte4, input, isLittleEndian );
                header.e_machine    = Util.read2byte( byte4, input, isLittleEndian );
                header.e_version    = Util.read4byte( byte4, input, isLittleEndian );
                header.e_entry      = Util.read4byte( byte4, input, isLittleEndian );
                header.e_phoff      = Util.read4byte( byte4, input, isLittleEndian );
                header.e_shoff      = Util.read4byte( byte4, input, isLittleEndian );
                header.e_flags      = Util.read4byte( byte4, input, isLittleEndian );
                header.e_ehsize     = Util.read2byte( byte4, input, isLittleEndian );
                header.e_phentsize  = Util.read2byte( byte4, input, isLittleEndian );
                header.e_phnum      = Util.read2byte( byte4, input, isLittleEndian );
                header.e_shentsize  = Util.read2byte( byte4, input, isLittleEndian );
                header.e_shnum      = Util.read2byte( byte4, input, isLittleEndian );
                header.e_shstrndx   = Util.read2byte( byte4, input, isLittleEndian );
            }
            //System.out.println( header.toString() );
        }
        return true;
    }

    protected   ProgramHeader[] programHeaders = null;
    public boolean readProgramHeader( final RandomAccessFile input )
            throws IOException
    {
        if ( ! isElfMagic() )
        {
            return false;
        }
        
        if ( ! isElf32() )
        {
            return false;
        }

        final boolean isBigEndian = isElfBigEndian();
        final boolean isLittleEndian = isElfLittleEndian();
        {
            if ( isBigEndian || isLittleEndian )
            {
            }
            else
            {
                throw new RuntimeException("unknown endian");
            }
        }

        if ( 0 < header.e_phnum )
        {
            programHeaders = new ProgramHeader[header.e_phnum];
        }
        else
        {
            programHeaders = new ProgramHeader[0];
        }

        input.seek( header.e_phoff );
        if ( 0 < header.e_phentsize )
        {
            for ( int index = 0; index < header.e_phnum; ++index )
            {
                ProgramHeader   programHeader = new ProgramHeader();
                {
                    byte[] byte4 = new byte[4];

                    programHeader.p_type = Util.read4byte( byte4, input, isLittleEndian );
                    programHeader.p_offset = Util.read4byte( byte4, input, isLittleEndian );
                    programHeader.p_vaddr = Util.read4byte( byte4, input, isLittleEndian );
                    programHeader.p_paddr = Util.read4byte( byte4, input, isLittleEndian );
                    programHeader.p_filesz = Util.read4byte( byte4, input, isLittleEndian );
                    programHeader.p_memsz = Util.read4byte( byte4, input, isLittleEndian );
                    programHeader.p_flags = Util.read4byte( byte4, input, isLittleEndian );
                    programHeader.p_align = Util.read4byte( byte4, input, isLittleEndian );
                }
                //System.out.println( programHeader.toString() );
                programHeaders[index] = programHeader;
            } // for

        }

        return true;
    }

    protected   SectionHeader[] sectionHeaders = null;
    protected   String[] sectionHeaderStrings = null;
    protected   int offsetSectionHeader_StringTable = -1;
    public boolean readSectionHeader( final RandomAccessFile input )
            throws IOException
    {
        if ( ! isElfMagic() )
        {
            return false;
        }
        
        if ( ! isElf32() )
        {
            return false;
        }

        final boolean isBigEndian = isElfBigEndian();
        final boolean isLittleEndian = isElfLittleEndian();
        {
            if ( isBigEndian || isLittleEndian )
            {
            }
            else
            {
                throw new RuntimeException("unknown endian");
            }
        }

        if ( 0 < header.e_shnum )
        {
            sectionHeaders = new SectionHeader[header.e_shnum];
        }
        else
        {
            sectionHeaders = new SectionHeader[0];
        }

        input.seek( header.e_shoff );
        if ( 0 < header.e_shentsize )
        {
            for ( int index = 0; index < header.e_shnum; ++index )
            {
                SectionHeader   sectionHeader = new SectionHeader();
                {
                    byte[] byte4 = new byte[4];

                    sectionHeader.sh_name = Util.read4byte( byte4, input, isLittleEndian );
                    sectionHeader.sh_type = Util.read4byte( byte4, input, isLittleEndian );
                    sectionHeader.sh_flags = Util.read4byte( byte4, input, isLittleEndian );
                    sectionHeader.sh_addr = Util.read4byte( byte4, input, isLittleEndian );
                    sectionHeader.sh_offset = Util.read4byte( byte4, input, isLittleEndian );
                    sectionHeader.sh_size = Util.read4byte( byte4, input, isLittleEndian );
                    sectionHeader.sh_link = Util.read4byte( byte4, input, isLittleEndian );
                    sectionHeader.sh_info = Util.read4byte( byte4, input, isLittleEndian );
                    sectionHeader.sh_addralign = Util.read4byte( byte4, input, isLittleEndian );
                    sectionHeader.sh_entsize = Util.read4byte( byte4, input, isLittleEndian );
                }
                //System.out.println( sectionHeader.toString() );
                sectionHeaders[index] = sectionHeader;
            } // for

        }

        if ( 0 < header.e_shnum )
        {
            sectionHeaderStrings = new String[header.e_shnum];
        }
        else
        {
            sectionHeaderStrings = new String[0];
        }

        input.seek( 0 );
        {
            byte[] stringTable = null;
            {
                final int index = header.e_shstrndx;
                if ( 0 <= index && index < sectionHeaders.length )
                {
                    stringTable = new byte[sectionHeaders[index].sh_size];
                    input.seek( sectionHeaders[index].sh_offset );
                    input.read(stringTable);
                }
            }

            if ( null != stringTable )
            {
                final int sectionHeadersLength = sectionHeaders.length;
                for ( int index = 0; index < sectionHeadersLength; ++index )
                {
                    final int indexStart = sectionHeaders[index].sh_name;
                    StringBuilder sb = new StringBuilder(128);
                    final int stringTableLength = stringTable.length;
                    for ( int i = 0; indexStart+i < stringTableLength; i++ )
                    {
                       final byte c = stringTable[indexStart+i];
                       if ( '\0' == c )
                       {
                           break;
                       }
                       sb.append((char)c);
                    }
                    sectionHeaderStrings[index] = sb.toString();
                    //System.out.println(sectionHeaderStrings[index]);
                }
            }

        }

        {
            {
                final int count = sectionHeaders.length;
                final int index = header.e_shstrndx;
                if ( 0 <= index && index < count )
                {
                    final SectionHeader sectionHeader = sectionHeaders[index];
                    if ( ElfFile.SHT_STRTAB == sectionHeader.sh_type )
                    {
                        if ( 0 == ElfFile.ELF_SHSTRTAB.compareTo( sectionHeaderStrings[index] ) )
                        {
                            if ( offsetSectionHeader_StringTable < sectionHeader.sh_offset )
                            {
                                offsetSectionHeader_StringTable = sectionHeader.sh_offset;
                            }
                        }

                    }
                }
                else
                {
                    throw new IndexOutOfBoundsException("e_shstrndx out of bounds");
                }
            }
        }
        
        return true;
    }


    public boolean writeElfHeader( final RandomAccessFile output )
            throws IOException
    {
        if ( ! isElfMagic() )
        {
            return false;
        }
        
        if ( ! isElf32() )
        {
            return false;
        }

        final boolean isBigEndian = isElfBigEndian();
        final boolean isLittleEndian = isElfLittleEndian();
        {
            if ( isBigEndian || isLittleEndian )
            {
            }
            else
            {
                throw new RuntimeException("unknown endian");
            }
        }

        {
            byte[] byte4 = new byte[4];

            Util.write2byte( byte4, header.e_type, output, isLittleEndian );
            Util.write2byte( byte4, header.e_machine, output, isLittleEndian );
            Util.write4byte( byte4, header.e_version, output, isLittleEndian );
            Util.write4byte( byte4, header.e_entry, output, isLittleEndian );
            Util.write4byte( byte4, header.e_phoff, output, isLittleEndian );
            Util.write4byte( byte4, header.e_shoff, output, isLittleEndian );
            Util.write4byte( byte4, header.e_flags, output, isLittleEndian );
            Util.write2byte( byte4, header.e_ehsize, output, isLittleEndian );
            Util.write2byte( byte4, header.e_phentsize, output, isLittleEndian );
            Util.write2byte( byte4, header.e_phnum, output, isLittleEndian );
            Util.write2byte( byte4, header.e_shentsize, output, isLittleEndian );
            Util.write2byte( byte4, header.e_shnum, output, isLittleEndian );
            Util.write2byte( byte4, header.e_shstrndx, output, isLittleEndian );
        }
        
        return true;
    }

    public boolean writeProgramHeader( final RandomAccessFile output )
            throws IOException
    {
        return false;
    }

    public boolean writeSectionHeader( final RandomAccessFile output )
            throws IOException
    {
        return false;
    }

    @Override
    public long getElfHeaderHeaderSize() {
        return header.e_ehsize;
    }

    @Override
    public long getElfHeaderSectionHeaderOffset() {
        return header.e_shoff;
    }

    @Override
    public long getElfHeaderSectionHeaderStringTableOffset() {
        return this.offsetSectionHeader_StringTable;
    }

    @Override
    public void setElfHeaderSectionHeaderOffset(long offset) {
        header.e_shoff = (int)offset;
    }

    @Override
    public void setElfHeaderSectionHeaderNumber(int number) {
        header.e_shnum = (short)number;
    }

    @Override
    public void setElfHeaderSectionHeaderSize(int size) {
        header.e_shentsize = (short)size;
    }

    @Override
    public void setElfHeaderSectionHeaderStringTableIndex(int index) {
        header.e_shstrndx = (short)index;
    }

    public boolean hasSectionDebug()
    {
        boolean haveDebug = false;
        {
            final int sectionHeaderStringsLength = sectionHeaderStrings.length;
            for ( int index = 0; index < sectionHeaderStringsLength; ++index )
            {
                final String str = sectionHeaderStrings[index];
                if ( null != str )
                {
                    if ( str.startsWith( ElfFile.ELF_DEBUG ) )
                    {
                        haveDebug = true;
                        break;
                    }
                }
            }
        }

        return haveDebug;
    }

}




Java Source Code List

com.example.hellojni.HelloJni.java
com.example.hellojni.HelloJni.java
jp.ne.sakura.kkkon.StripElfSectionHeader.AppOption.java
jp.ne.sakura.kkkon.StripElfSectionHeader.App.java
jp.ne.sakura.kkkon.StripElfSectionHeader.ElfFile.Elf32File.java
jp.ne.sakura.kkkon.StripElfSectionHeader.ElfFile.ElfFileUtil.java
jp.ne.sakura.kkkon.StripElfSectionHeader.ElfFile.ElfFile.java
jp.ne.sakura.kkkon.StripElfSectionHeader.ElfFile.IElfFile.java
jp.ne.sakura.kkkon.StripElfSectionHeader.ElfFile.Util.java