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; }
104 public boolean executable() { return (flags & PF_X) != 0; }
106 public InputStream getInputStream() throws IOException {
107 return new BufferedInputStream(new SectionInputStream(
108 offset,offset+filesz));
112 public class SHeader {
122 public int addralign;
125 public static final int T_NOBITS = 8;
127 SHeader() throws IOException {
128 nameidx = fd.readInt();
130 flags = fd.readInt();
132 offset = fd.readInt();
136 addralign = fd.readInt();
137 entsize = fd.readInt();
140 public InputStream getInputStream() throws IOException {
141 return new BufferedInputStream(new SectionInputStream(
142 offset, type == T_NOBITS ? 0 : offset+size));
146 public ELF(Object img) throws IOException, ELFException {
149 header = new ELFHeader();
150 pheaders = new PHeader[header.phnum];
151 for(int i=0;i<header.phnum;i++) {
152 seek(header.phoff+i*header.phentsize);
153 pheaders[i] = new PHeader();
155 sheaders = new SHeader[header.shnum];
156 for(int i=0;i<header.shnum;i++) {
157 seek(header.shoff+i*header.shentsize);
158 sheaders[i] = new SHeader();
160 if(header.shstrndx < 0 || header.shstrndx >= header.shnum) throw new ELFException("Bad shstrndx");
161 seek(sheaders[header.shstrndx].offset);
162 byte[] a = new byte[sheaders[header.shstrndx].size];
164 for(int i=0;i<header.shnum;i++) {
165 SHeader s = sheaders[i];
166 StringBuffer sb = new StringBuffer();
167 for(int off = s.nameidx;off < a.length && a[off] != 0; off++) sb.append((char)a[off]);
168 s.name = sb.toString();
172 public SHeader sectionWithName(String name) {
173 for(int i=0;i<sheaders.length;i++)
174 if(sheaders[i].name.equals(name))
179 public class ELFException extends IOException { ELFException(String s) { super(s); } }
181 private class SectionInputStream extends InputStream {
184 SectionInputStream(int start, int end) throws IOException {
185 if(sectionReaderActive)
186 throw new IOException("Section reader already active");
187 sectionReaderActive = true;
193 private int bytesLeft() { return maxpos - pos; }
194 public int read() throws IOException {
195 if(bytesLeft()==0) return -1;
197 byte b = fd.readByte();
200 } catch (EOFException e) {
204 public int read(byte[] b, int off, int len) throws IOException {
205 fd.readFully(b, off, len);
208 public void close() { sectionReaderActive = false; }
211 private static String toHex(int n) { return "0x" + Long.toString(n & 0xffffffffL, 16); }
213 public static void main(String[] args) throws IOException {
214 ELF elf = new ELF(args[0]);
215 System.out.println("Type: " + toHex(elf.header.type));
216 System.out.println("Machine: " + toHex(elf.header.machine));
217 for(int i=0;i<elf.pheaders.length;i++) {
218 ELF.PHeader ph = elf.pheaders[i];
219 System.out.println("PHeader " + toHex(i));
220 System.out.println("\tOffset: " + ph.offset);
221 System.out.println("\tVaddr: " + toHex(ph.vaddr));
222 System.out.println("\tFile Size: " + ph.filesz);
223 System.out.println("\tMem Size: " + ph.memsz);
225 for(int i=0;i<elf.sheaders.length;i++) {
226 ELF.SHeader sh = elf.sheaders[i];
227 System.out.println("SHeader " + toHex(i));
228 System.out.println("\tName: " + sh.name);
229 System.out.println("\tOffset: " + sh.offset);
230 System.out.println("\tAddr: " + toHex(sh.addr));
231 System.out.println("\tSize: " + sh.size);
232 System.out.println("\tType: " + toHex(sh.type));