8 private void seek(long l) throws IOException {
9 if (image instanceof RandomAccessFile) {
10 ((RandomAccessFile)image).seek(l);
11 } else if (image instanceof byte[]) {
12 ByteArrayInputStream bais = new ByteArrayInputStream((byte[])image);
14 fd = new DataInputStream(bais);
18 public ELFHeader header;
19 public PHeader[] pheaders;
20 public SHeader[] sheaders;
22 private boolean sectionReaderActive;
24 private static void skipFully(DataInput fd, int n) throws IOException {
25 while(n>0) n -= fd.skipBytes(n);
28 public class ELFHeader {
34 public static final short ET_EXEC = 2;
36 public static final short EM_MIPS = 8;
44 public short phentsize;
46 public short shentsize;
48 public short shstrndx;
50 private static final int ELF_MAGIC = 0x7f454c46; // '\177', 'E', 'L', 'F'
51 ELFHeader() throws IOException {
52 if(fd.readInt() != ELF_MAGIC) throw new ELFException("Bad Magic (is: " );
53 klass = fd.readByte();
55 skipFully(fd, 1); // version
56 osabi = fd.readByte();
57 abiversion = fd.readByte();
59 type = fd.readShort();
60 machine = fd.readShort();
61 version = fd.readInt();
66 ehsize = fd.readShort();
67 phentsize = fd.readShort();
68 phnum = fd.readShort();
69 shentsize = fd.readShort();
70 shnum = fd.readShort();
71 shstrndx = fd.readShort();
75 public class PHeader {
85 public static final int PF_X = 0x1;
86 public static final int PF_W = 0x2;
87 public static final int PF_R = 0x4;
89 public static final int PT_LOAD = 1;
91 PHeader() throws IOException {
93 offset = fd.readInt();
96 filesz = fd.readInt();
100 if(filesz > memsz) throw new ELFException("ELF inconsistency: filesz > memsz");
103 public boolean writable() { return (flags & PF_W) != 0; }
105 public InputStream getInputStream() throws IOException {
106 return new BufferedInputStream(new SectionInputStream(
107 offset,offset+filesz));
111 public class SHeader {
121 public int addralign;
124 public static final int T_NOBITS = 8;
126 SHeader() throws IOException {
127 nameidx = fd.readInt();
129 flags = fd.readInt();
131 offset = fd.readInt();
135 addralign = fd.readInt();
136 entsize = fd.readInt();
139 public InputStream getInputStream() throws IOException {
140 return new BufferedInputStream(new SectionInputStream(
141 offset, type == T_NOBITS ? 0 : offset+size));
145 public ELF(Object img) throws IOException, ELFException {
148 header = new ELFHeader();
149 pheaders = new PHeader[header.phnum];
150 for(int i=0;i<header.phnum;i++) {
151 seek(header.phoff+i*header.phentsize);
152 pheaders[i] = new PHeader();
154 sheaders = new SHeader[header.shnum];
155 for(int i=0;i<header.shnum;i++) {
156 seek(header.shoff+i*header.shentsize);
157 sheaders[i] = new SHeader();
159 if(header.shstrndx < 0 || header.shstrndx >= header.shnum) throw new ELFException("Bad shstrndx");
160 seek(sheaders[header.shstrndx].offset);
161 byte[] a = new byte[sheaders[header.shstrndx].size];
163 for(int i=0;i<header.shnum;i++) {
164 SHeader s = sheaders[i];
165 StringBuffer sb = new StringBuffer();
166 for(int off = s.nameidx;off < a.length && a[off] != 0; off++) sb.append((char)a[off]);
167 s.name = sb.toString();
171 public SHeader sectionWithName(String name) {
172 for(int i=0;i<sheaders.length;i++)
173 if(sheaders[i].name.equals(name))
178 public class ELFException extends IOException { ELFException(String s) { super(s); } }
180 private class SectionInputStream extends InputStream {
183 SectionInputStream(int start, int end) throws IOException {
184 if(sectionReaderActive)
185 throw new IOException("Section reader already active");
186 sectionReaderActive = true;
192 private int bytesLeft() { return maxpos - pos; }
193 public int read() throws IOException {
194 if(bytesLeft()==0) return -1;
196 byte b = fd.readByte();
199 } catch (EOFException e) {
203 public int read(byte[] b, int off, int len) throws IOException {
204 fd.readFully(b, off, len);
207 public void close() { sectionReaderActive = false; }
210 private static String toHex(int n) { return "0x" + Long.toString(n & 0xffffffffL, 16); }
212 public static void main(String[] args) throws IOException {
213 ELF elf = new ELF(args[0]);
214 System.out.println("Type: " + toHex(elf.header.type));
215 System.out.println("Machine: " + toHex(elf.header.machine));
216 for(int i=0;i<elf.pheaders.length;i++) {
217 ELF.PHeader ph = elf.pheaders[i];
218 System.out.println("PHeader " + toHex(i));
219 System.out.println("\tOffset: " + ph.offset);
220 System.out.println("\tVaddr: " + toHex(ph.vaddr));
221 System.out.println("\tFile Size: " + ph.filesz);
222 System.out.println("\tMem Size: " + ph.memsz);
224 for(int i=0;i<elf.sheaders.length;i++) {
225 ELF.SHeader sh = elf.sheaders[i];
226 System.out.println("SHeader " + toHex(i));
227 System.out.println("\tName: " + sh.name);
228 System.out.println("\tOffset: " + sh.offset);
229 System.out.println("\tAddr: " + toHex(sh.addr));
230 System.out.println("\tSize: " + sh.size);
231 System.out.println("\tType: " + toHex(sh.type));