Back to project page strip-elf-section-header.
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.
/* * 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; } }