5 private MyRandomAccessFile fd;
7 public ELFHeader header;
8 public PHeader[] pheaders;
9 public SHeader[] sheaders;
11 private boolean sectionReaderActive;
13 public class ELFHeader {
19 public static final short ET_EXEC = 2;
21 public static final short EM_MIPS = 8;
29 public short phentsize;
31 public short shentsize;
33 public short shstrndx;
35 private static final int ELF_MAGIC = 0x7f454c46; // '\177', 'E', 'L', 'F'
36 ELFHeader() throws IOException {
37 if(fd.readInt() != ELF_MAGIC) throw new ELFException("Bad Magic (is: " );
38 klass = fd.readByte();
40 fd.skipFully(1); // version
41 osabi = fd.readByte();
42 abiversion = fd.readByte();
44 type = fd.readShort();
45 machine = fd.readShort();
46 version = fd.readInt();
51 ehsize = fd.readShort();
52 phentsize = fd.readShort();
53 phnum = fd.readShort();
54 shentsize = fd.readShort();
55 shnum = fd.readShort();
56 shstrndx = fd.readShort();
60 public class PHeader {
70 public static final int PF_X = 0x1;
71 public static final int PF_W = 0x2;
72 public static final int PF_R = 0x4;
74 public static final int PT_LOAD = 1;
76 PHeader() throws IOException {
78 offset = fd.readInt();
81 filesz = fd.readInt();
85 if(filesz > memsz) throw new ELFException("ELF inconsistency: filesz > memsz");
88 public boolean writable() { return (flags & PF_W) != 0; }
90 public InputStream getInputStream() throws IOException {
91 return new BufferedInputStream(new SectionInputStream(
92 offset,offset+filesz));
96 public class SHeader {
106 public int addralign;
109 public static final int T_NOBITS = 8;
111 SHeader() throws IOException {
112 nameidx = fd.readInt();
114 flags = fd.readInt();
116 offset = fd.readInt();
120 addralign = fd.readInt();
121 entsize = fd.readInt();
124 public InputStream getInputStream() throws IOException {
125 return new BufferedInputStream(new SectionInputStream(
126 offset, type == T_NOBITS ? 0 : offset+size));
130 public ELF(String file) throws IOException, ELFException {
131 fd = new MyRandomAccessFile(file,"r");
132 header = new ELFHeader();
133 pheaders = new PHeader[header.phnum];
134 for(int i=0;i<header.phnum;i++) {
135 fd.seek(header.phoff+i*header.phentsize);
136 pheaders[i] = new PHeader();
138 sheaders = new SHeader[header.shnum];
139 for(int i=0;i<header.shnum;i++) {
140 fd.seek(header.shoff+i*header.shentsize);
141 sheaders[i] = new SHeader();
143 if(header.shstrndx < 0 || header.shstrndx >= header.shnum) throw new ELFException("Bad shstrndx");
144 fd.seek(sheaders[header.shstrndx].offset);
145 byte[] a = new byte[sheaders[header.shstrndx].size];
147 for(int i=0;i<header.shnum;i++) {
148 SHeader s = sheaders[i];
149 StringBuffer sb = new StringBuffer();
150 for(int off = s.nameidx;off < a.length && a[off] != 0; off++) sb.append((char)a[off]);
151 s.name = sb.toString();
155 public SHeader sectionWithName(String name) {
156 for(int i=0;i<sheaders.length;i++)
157 if(sheaders[i].name.equals(name))
162 public class ELFException extends IOException { ELFException(String s) { super(s); } }
164 private class MyRandomAccessFile extends RandomAccessFile {
165 MyRandomAccessFile(String f,String m) throws IOException { super(f,m); }
166 public void skipFully(int n) throws IOException {
167 while(n>0) n-= skipBytes(n);
171 private class SectionInputStream extends InputStream {
174 SectionInputStream(int start, int end) throws IOException {
175 if(sectionReaderActive)
176 throw new IOException("Section reader already active");
177 sectionReaderActive = true;
183 private int bytesLeft() { return maxpos - pos; }
184 public int read() throws IOException { if(bytesLeft()==0) return -1; int b = fd.read(); if(b >= 0) pos++; return b; }
185 public int read(byte[] b, int off, int len) throws IOException {
186 int n = fd.read(b,off,Math.min(len,bytesLeft())); if(n > 0) pos += n; return n;
188 public void close() { sectionReaderActive = false; }
191 private static String toHex(int n) { return "0x" + Long.toString(n & 0xffffffffL, 16); }
193 public static void main(String[] args) throws IOException {
194 ELF elf = new ELF(args[0]);
195 System.out.println("Type: " + toHex(elf.header.type));
196 System.out.println("Machine: " + toHex(elf.header.machine));
197 for(int i=0;i<elf.pheaders.length;i++) {
198 ELF.PHeader ph = elf.pheaders[i];
199 System.out.println("PHeader " + toHex(i));
200 System.out.println("\tOffset: " + ph.offset);
201 System.out.println("\tVaddr: " + toHex(ph.vaddr));
202 System.out.println("\tFile Size: " + ph.filesz);
203 System.out.println("\tMem Size: " + ph.memsz);
205 for(int i=0;i<elf.sheaders.length;i++) {
206 ELF.SHeader sh = elf.sheaders[i];
207 System.out.println("SHeader " + toHex(i));
208 System.out.println("\tName: " + sh.name);
209 System.out.println("\tOffset: " + sh.offset);
210 System.out.println("\tAddr: " + toHex(sh.addr));
211 System.out.println("\tSize: " + sh.size);
212 System.out.println("\tType: " + toHex(sh.type));