mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-30 20:35:38 +02:00
New implementation of a COFF/EXE/PE parser
This commit is contained in:
parent
8ad962852c
commit
5f1db41a0c
5 changed files with 1499 additions and 0 deletions
|
@ -0,0 +1,529 @@
|
|||
/*
|
||||
* (c) Copyright QNX Software Systems Ltd. 2002.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
package org.eclipse.cdt.utils.coff;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.text.DateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
public class Coff {
|
||||
|
||||
public static final String NL = System.getProperty("line.separator", "\n");
|
||||
FileHeader filehdr;
|
||||
OptionalHeader opthdr;
|
||||
RandomAccessFile rfile;
|
||||
long startingOffset;
|
||||
byte[] string_table;
|
||||
SectionHeader[] scnhdrs;
|
||||
Symbol[] symbols;
|
||||
|
||||
public static class FileHeader {
|
||||
public final static int FILHSZ = 20;
|
||||
|
||||
public final static int F_RELFLG = 0x0001; // relocation info stripped from file
|
||||
public final static int F_EXEC = 0x0002; // file is executable
|
||||
// (no unresolved external references)
|
||||
public final static int F_LNNO = 0x0004; // line numbers stripped from file
|
||||
public final static int F_LSYMS = 0x0008; // local symbols stripped from file
|
||||
public final static int F_AR16WR = 0x0080; // file is 16-bit little-endian
|
||||
public final static int F_AR32WR = 0x0100; // file is 32-bit little-endian
|
||||
public final static int F_AR32W = 0x0200; // file is 32-bit big-endian
|
||||
public final static int F_DYNLOAD = 0x1000;// rs/6000 aix: dynamically
|
||||
// loadable w/imports & exports
|
||||
public final static int F_SHROBJ = 0x2000; // rs/6000 aix: file is a shared object
|
||||
public final static int F_DLL = 0x2000; // PE format DLL.
|
||||
|
||||
public int f_magic; /* 00-01 2 bytes: magic number */
|
||||
public int f_nscns; /* 02-03 2 bytes: number of sections: 2 bytes */
|
||||
public int f_timdat; /* 04-07 4 bytes: time & date stamp */
|
||||
public int f_symptr; /* 08-11 4 bytes: file pointer to symtab */
|
||||
public int f_nsyms; /* 12-15 4 bytes: number of symtab entries */
|
||||
public int f_opthdr; /* 16-17 2 bytes: sizeof(optional hdr) */
|
||||
public int f_flags; /* 18-19 2 bytes: flags */
|
||||
|
||||
public FileHeader (RandomAccessFile file) throws IOException {
|
||||
this(file, file.getFilePointer());
|
||||
}
|
||||
|
||||
public FileHeader (RandomAccessFile file, long offset) throws IOException {
|
||||
file.seek(offset);
|
||||
byte[] hdr = new byte[FILHSZ];
|
||||
file.readFully(hdr);
|
||||
ReadMemoryAccess memory = new ReadMemoryAccess(hdr, true);
|
||||
f_magic = memory.getUnsignedShort();
|
||||
f_nscns = memory.getUnsignedShort();
|
||||
f_timdat = memory.getInt();
|
||||
f_symptr = memory.getInt();
|
||||
f_nsyms = memory.getInt();
|
||||
f_opthdr = memory.getUnsignedShort();
|
||||
f_flags = memory.getUnsignedShort();
|
||||
}
|
||||
|
||||
public boolean isStrip() {
|
||||
return (f_flags & F_RELFLG) == F_RELFLG;
|
||||
}
|
||||
|
||||
public boolean isExec() {
|
||||
return (f_flags & F_EXEC) == F_EXEC;
|
||||
}
|
||||
|
||||
public boolean isDebug() {
|
||||
return !((f_flags & F_LNNO) == F_LNNO);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("FILE HEADER VALUES").append(NL);
|
||||
|
||||
buffer.append("f_magic = ").append(f_magic).append(NL);
|
||||
buffer.append("f_nscns = ").append(f_nscns).append(NL);
|
||||
|
||||
buffer.append("f_timdat = ");
|
||||
buffer.append(DateFormat.getDateInstance().format(new Date(f_timdat)));
|
||||
buffer.append(NL);
|
||||
|
||||
buffer.append("f_symptr = ").append(f_symptr).append(NL);
|
||||
buffer.append("f_nsyms = ").append(f_nsyms).append(NL);
|
||||
buffer.append("f_opthdr = ").append(f_opthdr).append(NL);
|
||||
buffer.append("f_flags = ").append(f_flags).append(NL);
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public static class OptionalHeader {
|
||||
public final static int AOUTHDRSZ = 28;
|
||||
|
||||
public short magic; /* 2 bytes: type of file */
|
||||
public short vstamp; /* 2 bytes: version stamp */
|
||||
public int tsize; /* 4 bytes: text size in bytes, padded to FW bdry*/
|
||||
public int dsize; /* 4 bytes: initialized data " " */
|
||||
public int bsize; /* 4 bytes: uninitialized data " " */
|
||||
public int entry; /* 4 bytes: entry pt. */
|
||||
public int text_start; /* 4 bytes: base of text used for this file */
|
||||
public int data_start; /* 4 bytes: base of data used for this file */
|
||||
|
||||
public OptionalHeader(RandomAccessFile file) throws IOException {
|
||||
this(file, file.getFilePointer() + FileHeader.FILHSZ);
|
||||
}
|
||||
|
||||
public OptionalHeader(RandomAccessFile file, long offset) throws IOException {
|
||||
file.seek(offset);
|
||||
byte[] hdr = new byte[AOUTHDRSZ];
|
||||
file.readFully(hdr);
|
||||
ReadMemoryAccess memory = new ReadMemoryAccess(hdr, true);
|
||||
magic = memory.getShort();
|
||||
vstamp = memory.getShort();
|
||||
tsize = memory.getInt();
|
||||
dsize = memory.getInt();
|
||||
bsize = memory.getInt();
|
||||
entry = memory.getInt();
|
||||
text_start = memory.getInt();
|
||||
data_start = memory.getInt();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("OPTIONAL HEADER VALUES").append(NL);
|
||||
buffer.append("magic = ").append(magic).append(NL);
|
||||
buffer.append("vstamp = ").append(vstamp).append(NL);
|
||||
buffer.append("tsize = ").append(tsize).append(NL);
|
||||
buffer.append("dsize = ").append(dsize).append(NL);
|
||||
buffer.append("bsize = ").append(bsize).append(NL);
|
||||
buffer.append("entry = ").append(entry).append(NL);
|
||||
buffer.append("text_start = ").append(text_start).append(NL);
|
||||
buffer.append("data_start = ").append(data_start).append(NL);
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public static class SectionHeader {
|
||||
|
||||
public final static int SCNHSZ = 40;
|
||||
|
||||
/* names of "special" sections */
|
||||
public final static String _TEXT = ".text";
|
||||
public final static String _DATA = ".data";
|
||||
public final static String _BSS = ".bss";
|
||||
public final static String _COMMENT = ".comment";
|
||||
public final static String _LIB = ".lib";
|
||||
|
||||
/* s_flags "type". */
|
||||
public final static int STYP_REG = 0x0000; /* "regular": allocated, relocated,
|
||||
loaded */
|
||||
public final static int STYP_DSECT = 0x0001; /* "dummy": relocated only */
|
||||
public final static int STYP_NOLOAD = 0x0002; /* "noload": allocated, relocated,
|
||||
not loaded */
|
||||
public final static int STYP_GROUP = 0x0004; /* "grouped": formed of input
|
||||
sections */
|
||||
public final static int STYP_PAD = 0x0008; /* "padding": not allocated, not
|
||||
relocated, loaded */
|
||||
public final static int STYP_COPY = 0x0010; /* "copy": for decision function
|
||||
used by field update;
|
||||
not allocated, not relocated,
|
||||
loaded; reloc & lineno entries
|
||||
processed normally */
|
||||
public final static int STYP_TEXT = 0x0020; /* section contains text only. */
|
||||
public final static int S_SHRSEG = 0x0020; /* In 3b Update files (output of
|
||||
ogen), sections which appear in
|
||||
SHARED segments of the Pfile
|
||||
will have the S_SHRSEG flag set
|
||||
by ogen, to inform dufr that
|
||||
updating 1 copy of the proc. will
|
||||
update all process invocations. */
|
||||
public final static int STYP_DATA = 0x0040; /* section contains data only */
|
||||
public final static int STYP_BSS = 0x0080; /* section contains bss only */
|
||||
public final static int S_NEWFCN = 0x0100; /* In a minimal file or an update
|
||||
file, a new function (as
|
||||
compared with a replaced
|
||||
function) */
|
||||
public final static int STYP_INFO = 0x0200; /* comment: not allocated not
|
||||
relocated, not loaded */
|
||||
public final static int STYP_OVER = 0x0400; /* overlay: relocated not allocated
|
||||
or loaded */
|
||||
public final static int STYP_LIB = 0x0800; /* for .lib: same as INFO */
|
||||
public final static int STYP_MERGE = 0x2000; /* merge section -- combines with
|
||||
text, data or bss sections only */
|
||||
public final static int STYP_REVERSE_PAD = 0x4000; /* section will be padded
|
||||
with no-op instructions
|
||||
wherever padding is necessary
|
||||
and there is a word of
|
||||
contiguous bytes beginning on a
|
||||
word boundary. */
|
||||
|
||||
public final static int STYP_LIT = 0x8020; /* Literal data (like STYP_TEXT) */
|
||||
|
||||
|
||||
public byte[] s_name= new byte[8]; // 8 bytes: section name
|
||||
public int s_paddr; // 4 bytes: physical address, aliased s_nlib
|
||||
public int s_vaddr; // 4 bytes: virtual address
|
||||
public int s_size; // 4 bytes: section size
|
||||
public int s_scnptr; // 4 bytes: file ptr to raw data for section
|
||||
public int s_relptr; // 4 bytes: file ptr to relocation
|
||||
public int s_lnnoptr; // 4 bytes: file ptr to line numbers
|
||||
public int s_nreloc; // 2 bytes: number of relocation entries
|
||||
public int s_nlnno; // 2 bytes: number of line number entries
|
||||
public int s_flags; // 4 bytes: flags
|
||||
|
||||
RandomAccessFile sfile;
|
||||
|
||||
public SectionHeader(RandomAccessFile file, long offset) throws IOException {
|
||||
sfile = file;
|
||||
file.seek(offset);
|
||||
byte[] hdr = new byte[SCNHSZ];
|
||||
file.readFully(hdr);
|
||||
ReadMemoryAccess memory = new ReadMemoryAccess(hdr, true);
|
||||
memory.getBytes(s_name);
|
||||
s_paddr = memory.getInt();
|
||||
s_vaddr = memory.getInt();
|
||||
s_size = memory.getInt();
|
||||
s_scnptr = memory.getInt();
|
||||
s_relptr = memory.getInt();
|
||||
s_lnnoptr = memory.getInt();
|
||||
s_nreloc = memory.getUnsignedShort();
|
||||
s_nlnno = memory.getUnsignedShort();
|
||||
s_flags = memory.getInt();
|
||||
}
|
||||
|
||||
public byte[] getRawData() throws IOException {
|
||||
byte[] data = new byte[s_size];
|
||||
sfile.seek(s_scnptr);
|
||||
sfile.readFully(data);
|
||||
return data;
|
||||
}
|
||||
|
||||
public Reloc[] getRelocs() throws IOException {
|
||||
Reloc[] relocs = new Reloc[s_nreloc];
|
||||
sfile.seek(s_relptr);
|
||||
for (int i = 0; i < s_nreloc; i++) {
|
||||
relocs[i] = new Reloc(sfile);
|
||||
}
|
||||
return relocs;
|
||||
}
|
||||
|
||||
public Lineno[] getLinenos() throws IOException {
|
||||
Lineno[] lines = new Lineno[s_nlnno];
|
||||
sfile.seek(s_lnnoptr);
|
||||
for (int i = 0; i < s_nlnno; i++) {
|
||||
lines[i] = new Lineno(sfile);
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("SECTION HEADER VALUES").append(NL);
|
||||
buffer.append(new String(s_name)).append(NL);
|
||||
buffer.append("s_paddr = ").append(s_paddr).append(NL);
|
||||
buffer.append("s_vaddr = ").append(s_vaddr).append(NL);
|
||||
buffer.append("s_size = ").append(s_size).append(NL);
|
||||
buffer.append("s_scnptr = ").append(s_scnptr).append(NL);
|
||||
buffer.append("s_relptr = ").append(s_relptr).append(NL);
|
||||
buffer.append("s_lnnoptr = ").append(s_lnnoptr).append(NL);
|
||||
buffer.append("s_nreloc = ").append(s_nreloc).append(NL);
|
||||
buffer.append("s_nlnno = ").append(s_nlnno).append(NL);
|
||||
buffer.append("s_flags = ").append(s_flags).append(NL);
|
||||
/*
|
||||
try {
|
||||
Reloc[] rcs = getRelocs();
|
||||
for (int i = 0; i < rcs.length; i++) {
|
||||
buffer.append(rcs[i]);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
}
|
||||
try {
|
||||
Lineno[] nos = getLinenos();
|
||||
for (int i = 0; i < nos.length; i++) {
|
||||
buffer.append(nos[i]);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
}
|
||||
*/
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public static class Reloc {
|
||||
public static final int RELSZ = 16;
|
||||
public int r_vaddr; /* 4 byte: Pointer to an area in raw data that represents a
|
||||
referenced address. */
|
||||
public int r_symndx; /* 4 byte: Index into symbol table. */
|
||||
public int r_type; /* 2 byte(unsigned short): Type of address reference. */
|
||||
|
||||
public Reloc(RandomAccessFile file) throws IOException {
|
||||
this(file, file.getFilePointer());
|
||||
}
|
||||
|
||||
public Reloc(RandomAccessFile file, long offset) throws IOException {
|
||||
file.seek(offset);
|
||||
byte[] bytes = new byte[RELSZ];
|
||||
file.readFully(bytes);
|
||||
ReadMemoryAccess memory = new ReadMemoryAccess(bytes, true);
|
||||
r_vaddr = memory.getInt();
|
||||
r_symndx = memory.getInt();
|
||||
r_type = memory.getUnsignedShort();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("RELOC VALUES").append(NL);
|
||||
buffer.append("r_vaddr = ").append(r_vaddr);
|
||||
buffer.append(" r_symndx = ").append(r_symndx).append(NL);
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public static class Lineno {
|
||||
public final static int LINESZ = 6;
|
||||
public int l_addr; /* long. Index into symbol table if l_linn0 == 0.
|
||||
Break-pointable address if l_lnno > 0. */
|
||||
public int l_lnno; /* unsigned short. Line number */
|
||||
|
||||
public Lineno(RandomAccessFile file) throws IOException {
|
||||
this(file, file.getFilePointer());
|
||||
}
|
||||
|
||||
public Lineno(RandomAccessFile file, long offset) throws IOException {
|
||||
file.seek(offset);
|
||||
byte[] bytes = new byte[LINESZ];
|
||||
file.readFully(bytes);
|
||||
ReadMemoryAccess memory = new ReadMemoryAccess(bytes, true);
|
||||
l_addr = memory.getInt();
|
||||
l_lnno = memory.getUnsignedShort();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
if (l_lnno == 0) {
|
||||
buffer.append("Function address = ").append(l_addr).append(NL);
|
||||
} else {
|
||||
buffer.append("line# ").append(l_lnno);
|
||||
buffer.append(" at address = ").append(l_addr).append(NL);
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public static class Symbol {
|
||||
public final static int SYMSZ = 18;
|
||||
public final static int SYMNMLEN = 8;
|
||||
public byte[] _n_name = new byte[SYMNMLEN]; /* Symbol name, or pointer into
|
||||
string table if symbol name
|
||||
is greater than SYMNMLEN. */
|
||||
public int n_value; /* long. Symbol;s value: dependent on section number,
|
||||
storage class and type. */
|
||||
public short n_scnum; /* short, Section number. */
|
||||
public int n_type; /* Unsigned short. Symbolic type. */
|
||||
public byte n_sclass; /* char, Storage class. */
|
||||
public byte n_numaux; /* char. Nuymber of auxiliary enties. */
|
||||
|
||||
public Symbol(RandomAccessFile file) throws IOException {
|
||||
this(file, file.getFilePointer());
|
||||
}
|
||||
|
||||
public Symbol(RandomAccessFile file, long offset) throws IOException {
|
||||
file.seek(offset);
|
||||
byte[] bytes = new byte[SYMSZ];
|
||||
file.readFully(bytes);
|
||||
ReadMemoryAccess memory = new ReadMemoryAccess(bytes, true);
|
||||
memory.getBytes(_n_name);
|
||||
n_value = memory.getInt();
|
||||
n_scnum = memory.getShort();
|
||||
n_type = memory.getUnsignedShort();
|
||||
n_sclass = memory.getByte();
|
||||
n_numaux = memory.getByte();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("SYMBOL VALUES");
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public FileHeader getFileHeader() throws IOException {
|
||||
return filehdr;
|
||||
}
|
||||
|
||||
public OptionalHeader getOptionalHeader() throws IOException {
|
||||
return opthdr;
|
||||
}
|
||||
|
||||
public SectionHeader[] getSectionHeaders() throws IOException {
|
||||
if (scnhdrs == null) {
|
||||
scnhdrs = new SectionHeader[getFileHeader().f_nscns];
|
||||
long sec = getFileHeader().FILHSZ + getFileHeader().f_opthdr;
|
||||
for (int i = 0; i < scnhdrs.length; i++, sec += SectionHeader.SCNHSZ) {
|
||||
scnhdrs[i] = new SectionHeader(rfile, sec);
|
||||
}
|
||||
}
|
||||
return scnhdrs;
|
||||
}
|
||||
|
||||
public Symbol[] getSymbols() throws IOException {
|
||||
if (symbols == null) {
|
||||
long offset = getFileHeader().f_symptr;
|
||||
rfile.seek(offset);
|
||||
symbols = new Symbol[getFileHeader().f_nsyms];
|
||||
for (int i = 0; i < symbols.length; i++) {
|
||||
symbols[i] = new Symbol(rfile);
|
||||
}
|
||||
}
|
||||
return symbols;
|
||||
}
|
||||
|
||||
public byte[] getStringTable() throws IOException {
|
||||
if (string_table == null) {
|
||||
long symbolsize = Symbol.SYMSZ * getFileHeader().f_nsyms;
|
||||
long offset = getFileHeader().f_symptr + symbolsize;
|
||||
rfile.seek(offset);
|
||||
byte[] bytes = new byte[4];
|
||||
rfile.readFully(bytes);
|
||||
int str_len = ReadMemoryAccess.getIntLE(bytes);
|
||||
if (str_len > 4) {
|
||||
str_len -= 4;
|
||||
string_table = new byte[str_len];
|
||||
rfile.seek(offset + 4);
|
||||
rfile.readFully(string_table);
|
||||
} else {
|
||||
string_table = new byte[0];
|
||||
}
|
||||
}
|
||||
return string_table;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
try {
|
||||
FileHeader header = null;
|
||||
header = getFileHeader();
|
||||
if (header != null) {
|
||||
buffer.append(header);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
OptionalHeader opt = null;
|
||||
opt = getOptionalHeader();
|
||||
if (opt != null) {
|
||||
buffer.append(opt);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
SectionHeader[] sections = getSectionHeaders();
|
||||
for (int i = 0; i < sections.length; i++) {
|
||||
buffer.append(sections[i]);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
}
|
||||
|
||||
try {
|
||||
Symbol[] table = getSymbols();
|
||||
for (int i = 0; i < table.length; i++) {
|
||||
buffer.append(table[i]);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
}
|
||||
|
||||
try {
|
||||
String[] strings = getStringTable(getStringTable());
|
||||
for (int i = 0; i < strings.length; i++) {
|
||||
buffer.append(strings[i]);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
public static String[] getStringTable(byte[] bytes) {
|
||||
List aList = new ArrayList();
|
||||
int offset = 0;
|
||||
for (int i = 0; i < bytes.length; i++) {
|
||||
if (bytes[i] == '\0') {
|
||||
aList.add(new String(bytes, offset, (i + 1) - offset));
|
||||
offset = i;
|
||||
}
|
||||
}
|
||||
return (String[])aList.toArray(new String[0]);
|
||||
}
|
||||
|
||||
public Coff(String filename) throws IOException {
|
||||
this(new RandomAccessFile(filename, "r"), 0);
|
||||
}
|
||||
|
||||
public Coff(RandomAccessFile file, long offset) throws IOException {
|
||||
commonSetup(file, offset);
|
||||
}
|
||||
|
||||
void commonSetup(RandomAccessFile file, long offset) throws IOException {
|
||||
startingOffset = offset;
|
||||
rfile = file;
|
||||
try {
|
||||
filehdr = new FileHeader(rfile, offset);
|
||||
if (filehdr.f_opthdr > 0) {
|
||||
opthdr = new OptionalHeader(rfile, startingOffset + 20);
|
||||
}
|
||||
} finally {
|
||||
if (filehdr == null) {
|
||||
rfile.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
Coff coff = new Coff(args[0]);
|
||||
System.out.println(coff);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
* (c) Copyright QNX Software Systems Ltd. 2002.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
package org.eclipse.cdt.utils.coff;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
|
||||
public class Exe {
|
||||
|
||||
public static final String NL = System.getProperty("line.separator", "\n");
|
||||
protected RandomAccessFile rfile;
|
||||
ExeHeader ehdr;
|
||||
|
||||
static public class ExeHeader {
|
||||
|
||||
public final static int EXEHDRSZ = 28;
|
||||
public byte[] e_signature = new byte[2]; // 00-01 "MZ" - Link file .EXE signature
|
||||
public short e_lastsize; // 02-03 Length of EXE file modulo 512
|
||||
public short e_nblocks; // 04-05 Number of 512 pages (including the last page)
|
||||
public short e_nreloc; // 06-07 Number of relocation entries
|
||||
public short e_hdrsize; // 08-09 Size of header in 16 byte paragraphs,
|
||||
// occupied by "EXE" header and relo table.
|
||||
|
||||
public short e_minalloc; // 0A-0B Minimum paragraphs of memory allocated
|
||||
public short e_maxalloc; // 0C-0D Maximum number of paragraphs allocated
|
||||
// in addition to the code size
|
||||
public short e_ss; // 0E-0F Initial SS relative to start of executable
|
||||
public short e_sp; // 10-11 Initial SP
|
||||
public short e_checksum; // 12-13 Checksum (or 0) of executable
|
||||
public short e_ip; // 14-15 CS:IP relative to start of executable
|
||||
public short e_cs; // 16-17 CS:IP relative to start of executable
|
||||
public short e_relocoffs; // 18-19 Offset of relocation table;
|
||||
// 40h for new-(NE,LE,LX,W3,PE etc.) executable
|
||||
public short e_noverlay; // 1A-1B Overlay number (0h = main program)
|
||||
|
||||
protected ExeHeader(RandomAccessFile file) throws IOException {
|
||||
this(file, file.getFilePointer());
|
||||
}
|
||||
|
||||
protected ExeHeader(RandomAccessFile file, long offset) throws IOException {
|
||||
file.seek(offset);
|
||||
byte[] hdr = new byte[EXEHDRSZ];
|
||||
file.readFully(hdr);
|
||||
ReadMemoryAccess memory = new ReadMemoryAccess(hdr, true);
|
||||
memory.getBytes(e_signature);
|
||||
if (e_signature[0] != 'M' || e_signature[1] != 'Z') {
|
||||
throw new IOException("Not DOS EXE format");
|
||||
}
|
||||
e_lastsize = memory.getShort();
|
||||
e_nblocks = memory.getShort();
|
||||
e_nreloc = memory.getShort();
|
||||
e_hdrsize = memory.getShort();
|
||||
e_minalloc = memory.getShort();
|
||||
e_maxalloc = memory.getShort();
|
||||
e_ss = memory.getShort();
|
||||
e_sp = memory.getShort();
|
||||
e_checksum = memory.getShort();
|
||||
e_ip = memory.getShort();
|
||||
e_cs = memory.getShort();
|
||||
e_relocoffs = memory.getShort();
|
||||
e_noverlay = memory.getShort();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
|
||||
buffer.append("EXE HEADER VALUES").append(NL);
|
||||
buffer.append("signature ");
|
||||
buffer.append((char)e_signature[0] + " " + (char)e_signature[1]);
|
||||
buffer.append(NL);
|
||||
|
||||
buffer.append("lastsize: 0x");
|
||||
buffer.append(Long.toHexString(new Short(e_lastsize).longValue()));
|
||||
buffer.append(NL);
|
||||
|
||||
buffer.append("nblocks: 0x");
|
||||
buffer.append(Long.toHexString(new Short(e_nblocks).longValue()));
|
||||
buffer.append(NL);
|
||||
|
||||
buffer.append("nreloc: 0x");
|
||||
buffer.append(Long.toHexString(new Short(e_nreloc).longValue()));
|
||||
buffer.append(NL);
|
||||
|
||||
buffer.append("hdrsize: 0x");
|
||||
buffer.append(Long.toHexString(new Short(e_hdrsize).longValue()));
|
||||
buffer.append(NL);
|
||||
|
||||
buffer.append("minalloc: 0x");
|
||||
buffer.append(Long.toHexString(new Short(e_minalloc).longValue()));
|
||||
buffer.append(NL);
|
||||
|
||||
buffer.append("maxalloc: 0x");
|
||||
buffer.append(Long.toHexString(new Short(e_maxalloc).longValue()));
|
||||
buffer.append(NL);
|
||||
buffer.append("ss: 0x");
|
||||
buffer.append(Long.toHexString(new Short(e_ss).longValue()));
|
||||
buffer.append(NL);
|
||||
|
||||
buffer.append("sp: 0x");
|
||||
buffer.append(Long.toHexString(new Short(e_sp).longValue()));
|
||||
buffer.append(NL);
|
||||
|
||||
buffer.append("checksum: 0x");
|
||||
buffer.append(Long.toHexString(new Short(e_checksum).longValue()));
|
||||
buffer.append(NL);
|
||||
|
||||
buffer.append("ip: 0x");
|
||||
buffer.append(Long.toHexString(new Short(e_ip).longValue()));
|
||||
buffer.append(NL);
|
||||
|
||||
buffer.append("cs: 0x");
|
||||
buffer.append(Long.toHexString(new Short(e_cs).longValue()));
|
||||
buffer.append(NL);
|
||||
|
||||
buffer.append("relocoffs: 0x");
|
||||
buffer.append(Long.toHexString(new Short(e_relocoffs).longValue()));
|
||||
buffer.append(NL);
|
||||
|
||||
buffer.append("overlay: 0x");
|
||||
buffer.append(Long.toHexString(new Short(e_noverlay).longValue()));
|
||||
buffer.append(NL);
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public ExeHeader getExeHeader() throws IOException {
|
||||
return ehdr;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append(rfile).append(NL);
|
||||
buffer.append(ehdr);
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
public Exe(String file) throws IOException {
|
||||
rfile = new RandomAccessFile(file, "r");
|
||||
try {
|
||||
ehdr = new ExeHeader(rfile);
|
||||
} finally {
|
||||
if (ehdr == null) {
|
||||
rfile.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
Exe exe = new Exe(args[0]);
|
||||
System.out.println(exe);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,407 @@
|
|||
/*
|
||||
* (c) Copyright QNX Software Systems Ltd. 2002.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
package org.eclipse.cdt.utils.coff;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
|
||||
import org.eclipse.cdt.utils.coff.Coff.FileHeader;
|
||||
import org.eclipse.cdt.utils.coff.Coff.OptionalHeader;
|
||||
import org.eclipse.cdt.utils.coff.Coff.SectionHeader;
|
||||
import org.eclipse.cdt.utils.coff.Coff.Symbol;
|
||||
import org.eclipse.cdt.utils.coff.Exe.ExeHeader;
|
||||
|
||||
/**
|
||||
* The PE file header consists of an MS-DOS stub, the PE signalture, the COFF file Header
|
||||
* and an Optional Header.
|
||||
* <pre>
|
||||
* +-------------------+
|
||||
* | DOS-stub |
|
||||
* +-------------------+
|
||||
* | file-header |
|
||||
* +-------------------+
|
||||
* | optional header |
|
||||
* |- - - - - - - - - -|
|
||||
* | |
|
||||
* | data directories |
|
||||
* | |
|
||||
* +-------------------+
|
||||
* | |
|
||||
* | section headers |
|
||||
* | |
|
||||
* +-------------------+
|
||||
* | |
|
||||
* | section 1 |
|
||||
* | |
|
||||
* +-------------------+
|
||||
* | |
|
||||
* | section 2 |
|
||||
* | |
|
||||
* +-------------------+
|
||||
* | |
|
||||
* | ... |
|
||||
* | |
|
||||
* +-------------------+
|
||||
* | |
|
||||
* | section n |
|
||||
* | |
|
||||
* +-------------------+
|
||||
* </pre>
|
||||
*/
|
||||
public class PE {
|
||||
|
||||
public static final String NL = System.getProperty("line.separator", "\n");
|
||||
RandomAccessFile rfile;
|
||||
ExeHeader exeHeader;
|
||||
DOSHeader dosHeader;
|
||||
FileHeader fileHeader;
|
||||
OptionalHeader optionalHeader;
|
||||
NTOptionalHeader ntHeader;
|
||||
ImageDataDirectory[] dataDirectories;
|
||||
SectionHeader[] scnhdrs;
|
||||
Symbol[] symbolTable;
|
||||
byte[] stringTable;
|
||||
|
||||
/**
|
||||
*/
|
||||
public static class DOSHeader {
|
||||
final static int DOSHDRSZ = 100;
|
||||
byte[] e_res = new byte[8]; /* Reserved words, all 0x0. */
|
||||
byte[] e_oemid = new byte[2]; /* OEM identifier (for e_oeminfo), 0x0. */
|
||||
byte[] e_oeminfo = new byte[2]; /* OEM information; e_oemid specific, 0x0. */
|
||||
byte[] e_res2 = new byte[20]; /* Reserved words, all 0x0. */
|
||||
int e_lfanew; /* 4 byte File address of new exe header, offset 60(0x3c), 0x80. */
|
||||
byte[] dos_message = new byte[64]; /* Other stuff, always follow DOS header. */
|
||||
|
||||
public DOSHeader(RandomAccessFile file) throws IOException {
|
||||
this(file, file.getFilePointer());
|
||||
}
|
||||
|
||||
public DOSHeader(RandomAccessFile file, long offset) throws IOException {
|
||||
file.seek(offset);
|
||||
byte[] hdr = new byte[DOSHDRSZ];
|
||||
file.readFully(hdr);
|
||||
ReadMemoryAccess memory = new ReadMemoryAccess(hdr, true);
|
||||
memory.getBytes(e_res);
|
||||
memory.getBytes(e_oemid);
|
||||
memory.getBytes(e_oeminfo);
|
||||
memory.getBytes(e_res2);
|
||||
e_lfanew = memory.getInt();
|
||||
memory.getBytes(dos_message);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("DOS STUB VALUES").append(NL);
|
||||
buffer.append("e_lfanew = ").append(e_lfanew).append(NL);
|
||||
buffer.append(new String(dos_message)).append(NL);
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public static class NTOptionalHeader {
|
||||
|
||||
public final static int NTHDRSZ = 68;
|
||||
public int ImageBase; // 4 bytes.
|
||||
public int SectionAlignment; // 4 bytes.
|
||||
public int FileAlignment; // 4 bytes.
|
||||
public short MajorOperatingSystemVersion; // 2 bytes.
|
||||
public short MinorOperatingSystemVersion; // 2 bytes.
|
||||
public short MajorImageVersion; // 2 bytes.
|
||||
public short MinorImageVersion; // 2 bytes.
|
||||
public short MajorSubsystemVersion; // 2 bytes.
|
||||
public short MinorSubsystemVersion; // 2 bytes.
|
||||
public byte[] Reserved = new byte[4]; // 4 bytes.
|
||||
public int SizeOfImage; // 4 bytes.
|
||||
public int SizeOfHeaders; // 4 bytes.
|
||||
public int CheckSum; // 4 bytes.
|
||||
public short Subsystem; // 2 bytes.
|
||||
public short DLLCharacteristics; // 2 bytes.
|
||||
public int SizeOfStackReserve; // 4 bytes.
|
||||
public int SizeOfStackCommit; // 4 bytes.
|
||||
public int SizeOfHeapReserve; // 4 bytes.
|
||||
public int SizeOfHeapCommit; // 4 bytes.
|
||||
public int LoaderFlags; // 4 bytes.
|
||||
public int NumberOfRvaAndSizes; // 4 bytes.
|
||||
|
||||
public NTOptionalHeader(RandomAccessFile file) throws IOException {
|
||||
this(file, file.getFilePointer());
|
||||
}
|
||||
|
||||
public NTOptionalHeader(RandomAccessFile file, long offset) throws IOException {
|
||||
file.seek(offset);
|
||||
byte[] hdr = new byte[NTHDRSZ];
|
||||
file.readFully(hdr);
|
||||
ReadMemoryAccess memory = new ReadMemoryAccess(hdr, true);
|
||||
ImageBase = memory.getInt();
|
||||
SectionAlignment = memory.getInt();
|
||||
FileAlignment = memory.getInt();
|
||||
MajorOperatingSystemVersion = memory.getShort();
|
||||
MinorOperatingSystemVersion = memory.getShort();
|
||||
MajorImageVersion = memory.getShort();
|
||||
MinorImageVersion = memory.getShort();
|
||||
MajorSubsystemVersion = memory.getShort();
|
||||
MinorSubsystemVersion = memory.getShort();
|
||||
memory.getBytes(Reserved);
|
||||
SizeOfImage = memory.getInt();
|
||||
SizeOfHeaders = memory.getInt();
|
||||
CheckSum = memory.getInt();
|
||||
Subsystem = memory.getShort();
|
||||
DLLCharacteristics = memory.getShort();
|
||||
SizeOfStackReserve = memory.getInt();
|
||||
SizeOfStackCommit = memory.getInt();
|
||||
SizeOfHeapReserve = memory.getInt();
|
||||
SizeOfHeapCommit = memory.getInt();
|
||||
LoaderFlags = memory.getInt();
|
||||
NumberOfRvaAndSizes = memory.getInt();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("NT OPTIONAL HEADER VALUES").append(NL);
|
||||
buffer.append("ImageBase = ").append(ImageBase).append(NL);
|
||||
buffer.append("SexctionAlignement = ").append(SectionAlignment).append(NL);
|
||||
buffer.append("FileAlignment = ").append(FileAlignment).append(NL);
|
||||
buffer.append("MajorOSVersion = ").append(MajorOperatingSystemVersion).append(NL);
|
||||
buffer.append("MinorOSVersion = ").append(MinorOperatingSystemVersion).append(NL);
|
||||
buffer.append("MajorImageVersion = ").append(MajorImageVersion).append(NL);
|
||||
buffer.append("MinorImageVersion = ").append(MinorImageVersion).append(NL);
|
||||
buffer.append("MajorSubVersion = ").append(MajorSubsystemVersion).append(NL);
|
||||
buffer.append("MinorSubVersion = ").append(MinorSubsystemVersion).append(NL);
|
||||
buffer.append("Reserved = ").append(Reserved).append(NL);
|
||||
buffer.append("SizeOfImage = ").append(SizeOfImage).append(NL);
|
||||
buffer.append("SizeOfHeaders = ").append(SizeOfHeaders).append(NL);
|
||||
buffer.append("CheckSum = ").append(CheckSum).append(NL);
|
||||
buffer.append("Subsystem = ").append(Subsystem).append(NL);
|
||||
buffer.append("DLL = ").append(DLLCharacteristics).append(NL);
|
||||
buffer.append("StackReserve = ").append(SizeOfStackReserve).append(NL);
|
||||
buffer.append("StackCommit = ").append(SizeOfStackCommit).append(NL);
|
||||
buffer.append("HeapReserve = ").append(SizeOfHeapReserve).append(NL);
|
||||
buffer.append("HeapCommit = ").append(SizeOfHeapCommit).append(NL);
|
||||
buffer.append("LoaderFlags = ").append(LoaderFlags).append(NL);;
|
||||
buffer.append("#Rva size = ").append(NumberOfRvaAndSizes).append(NL);
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public class ImageDataDirectory {
|
||||
public int rva;
|
||||
public int size;
|
||||
|
||||
public ImageDataDirectory(int r, int s) {
|
||||
rva = r;
|
||||
size = s;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("rva = ").append(rva).append(" ");
|
||||
buffer.append("size = ").append(size).append(NL);
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public class ImportDirectoryEntry {
|
||||
public final static int ENTRYSZ = 20;
|
||||
public int rva;
|
||||
public int timestamp;
|
||||
public int forwarder;
|
||||
public int name;
|
||||
public int thunk;
|
||||
|
||||
public ImportDirectoryEntry(RandomAccessFile file) throws IOException {
|
||||
this(file, file.getFilePointer());
|
||||
}
|
||||
|
||||
public ImportDirectoryEntry(RandomAccessFile file, long offset) throws IOException {
|
||||
file.seek(offset);
|
||||
byte[] bytes = new byte[ENTRYSZ];
|
||||
file.readFully(bytes);
|
||||
ReadMemoryAccess memory = new ReadMemoryAccess(bytes, true);
|
||||
rva = memory.getInt();
|
||||
timestamp = memory.getInt();
|
||||
forwarder = memory.getInt();
|
||||
name = memory.getInt();
|
||||
thunk = memory.getInt();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("rva = ").append(rva);
|
||||
buffer.append(" timestamp = ").append(timestamp);
|
||||
buffer.append(" forwarder = ").append(forwarder);
|
||||
buffer.append(" name = ").append(name);
|
||||
buffer.append(" thunk = ").append(thunk).append(NL);
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public PE (String filename) throws IOException {
|
||||
|
||||
rfile = new RandomAccessFile(filename, "r");
|
||||
|
||||
exeHeader = new ExeHeader(rfile);
|
||||
|
||||
dosHeader = new DOSHeader(rfile);
|
||||
|
||||
// Jump the Coff header, and Check the sig.
|
||||
rfile.seek(dosHeader.e_lfanew);
|
||||
byte[] sig = new byte[4];
|
||||
rfile.readFully(sig);
|
||||
if (!((sig[0] == 'P') && (sig[1] == 'E')
|
||||
&& (sig[2] == '\0') && (sig[3] == '\0'))) {
|
||||
throw new IOException("Not a PE format");
|
||||
}
|
||||
|
||||
fileHeader = new Coff.FileHeader(rfile, rfile.getFilePointer());
|
||||
|
||||
optionalHeader = new Coff.OptionalHeader(rfile, rfile.getFilePointer());
|
||||
|
||||
ntHeader = new NTOptionalHeader(rfile, rfile.getFilePointer());
|
||||
|
||||
}
|
||||
|
||||
public ExeHeader getExeHeader() {
|
||||
return exeHeader;
|
||||
}
|
||||
|
||||
public DOSHeader getDOSHeader() {
|
||||
return dosHeader;
|
||||
}
|
||||
|
||||
public FileHeader getFileHeader() {
|
||||
return fileHeader;
|
||||
}
|
||||
|
||||
public OptionalHeader getOptionalHeader() {
|
||||
return optionalHeader;
|
||||
}
|
||||
|
||||
public NTOptionalHeader getNTOptionalHeader() {
|
||||
return ntHeader;
|
||||
}
|
||||
|
||||
public ImageDataDirectory[] getImageDataDirectories() throws IOException {
|
||||
if (dataDirectories == null) {
|
||||
long offset = dosHeader.e_lfanew + FileHeader.FILHSZ +
|
||||
OptionalHeader.AOUTHDRSZ + NTOptionalHeader.NTHDRSZ + 4/*NT SIG*/;
|
||||
rfile.seek(offset);
|
||||
dataDirectories = new ImageDataDirectory[PEConstants.IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
|
||||
byte[] data = new byte[dataDirectories.length * (4 + 4)];
|
||||
rfile.readFully(data);
|
||||
ReadMemoryAccess memory = new ReadMemoryAccess(data, true);
|
||||
for (int i = 0; i < dataDirectories.length; i++) {
|
||||
int rva = memory.getInt();
|
||||
int size = memory.getInt();
|
||||
dataDirectories[i] = new ImageDataDirectory(rva, size);
|
||||
}
|
||||
}
|
||||
return dataDirectories;
|
||||
}
|
||||
public SectionHeader[] getSectionHeaders() throws IOException {
|
||||
if (scnhdrs == null) {
|
||||
scnhdrs = new SectionHeader[fileHeader.f_nscns];
|
||||
long offset = dosHeader.e_lfanew +
|
||||
FileHeader.FILHSZ + fileHeader.f_opthdr + 4 /* NT SIG */;
|
||||
for (int i = 0; i < scnhdrs.length; i++, offset += SectionHeader.SCNHSZ) {
|
||||
scnhdrs[i] = new SectionHeader(rfile, offset);
|
||||
}
|
||||
}
|
||||
return scnhdrs;
|
||||
}
|
||||
|
||||
public Symbol[] getSymbols() throws IOException {
|
||||
if (symbolTable == null) {
|
||||
long offset = fileHeader.f_symptr;
|
||||
symbolTable = new Symbol[fileHeader.f_nsyms];
|
||||
for (int i = 0; i < symbolTable.length; i++, offset += Symbol.SYMSZ) {
|
||||
symbolTable[i] = new Symbol(rfile, offset);
|
||||
}
|
||||
}
|
||||
return symbolTable;
|
||||
}
|
||||
|
||||
public byte[] getStringTable() throws IOException {
|
||||
if (stringTable == null) {
|
||||
if (fileHeader.f_nsyms > 0) {
|
||||
long symbolsize = Symbol.SYMSZ * fileHeader.f_nsyms;
|
||||
long offset = fileHeader.f_symptr + symbolsize;
|
||||
rfile.seek(offset);
|
||||
byte[] bytes = new byte[4];
|
||||
rfile.readFully(bytes);
|
||||
int str_len = ReadMemoryAccess.getIntLE(bytes);
|
||||
if (str_len > 4) {
|
||||
str_len -= 4;
|
||||
stringTable = new byte[str_len];
|
||||
rfile.seek(offset + 4);
|
||||
rfile.readFully(stringTable);
|
||||
} else {
|
||||
stringTable = new byte[0];
|
||||
}
|
||||
} else {
|
||||
stringTable = new byte[0];
|
||||
}
|
||||
}
|
||||
return stringTable;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append(exeHeader);
|
||||
buffer.append(dosHeader);
|
||||
buffer.append(fileHeader);
|
||||
buffer.append(optionalHeader);
|
||||
buffer.append(ntHeader);
|
||||
try {
|
||||
ImageDataDirectory[] dirs = getImageDataDirectories();
|
||||
for (int i = 0; i < dirs.length; i++) {
|
||||
buffer.append("Entry ").append(i);
|
||||
buffer.append(" ").append(dirs[i]);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
SectionHeader[] sections = getSectionHeaders();
|
||||
for (int i = 0; i < sections.length; i++) {
|
||||
buffer.append(sections[i]);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
Symbol[] symbols = getSymbols();
|
||||
for (int i = 0; i < symbols.length; i++) {
|
||||
buffer.append(symbols[i]);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
byte[] bytes = getStringTable();
|
||||
String[] strings = Coff.getStringTable(bytes);
|
||||
for (int i = 0; i < strings.length; i++) {
|
||||
buffer.append(strings[i]);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
PE pe = new PE(args[0]);
|
||||
System.out.println(pe);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* (c) Copyright QNX Software Systems Ltd. 2002.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
package org.eclipse.cdt.utils.coff;
|
||||
|
||||
public class PEConstants {
|
||||
|
||||
/* PE characteristics, FileHeader.f_flags. */
|
||||
public final static int IMAGE_FILE_RELOCS_STRIPPED = 0x0001;
|
||||
public final static int IMAGE_FILE_EXECUTABLE_IMAGE = 0x0002;
|
||||
public final static int IMAGE_FILE_LINE_NUMS_STRIPPED = 0x0004;
|
||||
public final static int IMAGE_FILE_LOCAL_SYMS_STRIPPED = 0x0008;
|
||||
public final static int IMAGE_FILE_AGGRESSIVE_WS_TRIM = 0x0010;
|
||||
public final static int IMAGE_FILE_LARGE_ADDRESS_AWARE = 0x0020;
|
||||
public final static int IMAGE_FILE_16BIT_MACHINE = 0x0040;
|
||||
public final static int IMAGE_FILE_BYTES_REVERSED_LO = 0x0080;
|
||||
public final static int IMAGE_FILE_32BIT_MACHINE = 0x0100;
|
||||
public final static int IMAGE_FILE_DEBUG_STRIPPED = 0x0200;
|
||||
public final static int IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP = 0x0400;
|
||||
public final static int IMAGE_FILE_SYSTEM = 0x1000;
|
||||
public final static int IMAGE_FILE_DLL = 0x2000;
|
||||
public final static int IMAGE_FILE_UP_SYSTEM_ONLY = 0x4000;
|
||||
public final static int IMAGE_FILE_BYTES_REVERSED_HI = 0x8000;
|
||||
|
||||
/* FileHader.f_magic. Indicate the machine numbers. */
|
||||
public final static int IMAGE_FILE_MACHINE_UNKNOWN = 0x0;
|
||||
public final static int IMAGE_FILE_MACHINE_ALPHA = 0x184;
|
||||
public final static int IMAGE_FILE_MACHINE_ARM = 0x1c0;
|
||||
public final static int IMAGE_FILE_MACHINE_ALPHA64 = 0x284;
|
||||
public final static int IMAGE_FILE_MACHINE_I386 = 0x14c;
|
||||
public final static int IMAGE_FILE_MACHINE_IA64 = 0x200;
|
||||
public final static int IMAGE_FILE_MACHINE_M68K = 0x268;
|
||||
public final static int IMAGE_FILE_MACHINE_MIPS16 = 0x266;
|
||||
public final static int IMAGE_FILE_MACHINE_MIPSFPU = 0x366;
|
||||
public final static int IMAGE_FILE_MACHINE_MIPSFPU16 = 0x466;
|
||||
public final static int IMAGE_FILE_MACHINE_POWERPC = 0x1f0;
|
||||
public final static int IMAGE_FILE_MACHINE_R3000 = 0x162;
|
||||
public final static int IMAGE_FILE_MACHINE_R4000 = 0x166;
|
||||
public final static int IMAGE_FILE_MACHINE_R10000 = 0x168;
|
||||
public final static int IMAGE_FILE_MACHINE_SH3 = 0x1a2;
|
||||
public final static int IMAGE_FILE_MACHINE_SH4 = 0x1a6;
|
||||
public final static int IMAGE_FILE_MACHINE_THUMB = 0x1c2;
|
||||
|
||||
/* OptionalHeader.magic */
|
||||
public final static int PE32 = 0x10b;
|
||||
public final static int PE32PLUS = 0x20b;
|
||||
|
||||
/* Windows NT Subsystem. NTOptionalHeader.Subsystem */
|
||||
public final static int IMAGE_SUBSYSTEM_UNKNOWN = 0;
|
||||
public final static int IMAGE_SUBSYSTEM_NATIVE = 1;
|
||||
public final static int IMAGE_SUBSYSTEM_WINDOWS_GUI = 2;
|
||||
public final static int IMAGE_SUBSYSTEM_WINDOWS_CUI = 3;
|
||||
public final static int IMAGE_SUBSYSTEM_POSIX_CUI = 7;
|
||||
public final static int IMAGE_SUBSYSTEM_WINDOWS_CE_GUI = 9;
|
||||
public final static int IMAGE_SUBSYSTEM_EFI_APPLICATION = 10;
|
||||
public final static int IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER = 11;
|
||||
public final static int IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER = 12;
|
||||
|
||||
/* DLL CHarcteristics, NTOptionalHeader.DLLCharcteristics */
|
||||
public final static int IMAGE_DLLCHARACTERISTICS_NO_BIND = 0x0800; // Do not bind image.
|
||||
// Driver is a WDM Driver.
|
||||
public final static int IMAGE_DLLCHARACTERISTICS_WDM_DRIVER = 0x2000;
|
||||
// Image is Terminal Sever aware.
|
||||
public final static int IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER = 0x2000;
|
||||
|
||||
/* Array of Directories */
|
||||
public final static int IMAGE_NUMBEROF_DIRECTORY_ENTRIES = 16;
|
||||
|
||||
/* The directory of exported symbols; mostly used for DLLs.
|
||||
Described below. */
|
||||
public final static int IMAGE_DIRECTORY_ENTRY_EXPORT = 0;
|
||||
|
||||
/* The directory of imported symbols; see below. */
|
||||
public final static int IMAGE_DIRECTORY_ENTRY_IMPORT = 1;
|
||||
|
||||
/* Directory of resources. Described below. */
|
||||
public final static int IMAGE_DIRECTORY_ENTRY_RESOURCE = 2;
|
||||
|
||||
/* Exception directory - structure and purpose unknown. */
|
||||
public final static int IMAGE_DIRECTORY_ENTRY_EXCEPTION = 3;
|
||||
|
||||
/* Security directory - structure and purpose unknown. */
|
||||
public final static int IMAGE_DIRECTORY_ENTRY_SECURITY = 4;
|
||||
|
||||
/* Base relocation table - see below. */
|
||||
public final static int IMAGE_DIRECTORY_ENTRY_BASERELOC = 5;
|
||||
|
||||
/* Debug directory - contents is compiler dependent. Moreover, many
|
||||
compilers stuff the debug information into the code section and
|
||||
don't create a separate section for it. */
|
||||
public final static int IMAGE_DIRECTORY_ENTRY_DEBUG = 6;
|
||||
|
||||
/* Description string - some arbitrary copyright note or the like. */
|
||||
public final static int IMAGE_DIRECTORY_ENTRY_COPYRIGHT = 7;
|
||||
|
||||
/* Machine Value (MIPS GP) - structure and purpose unknown. */
|
||||
public final static int IMAGE_DIRECTORY_ENTRY_GLOBALPTR = 8;
|
||||
|
||||
/* Thread local storage directory - structure unknown; contains
|
||||
variables that are declared "__declspec(thread)", i.e.
|
||||
per-thread global variables. */
|
||||
public final static int IMAGE_DIRECTORY_ENTRY_TLS = 9;
|
||||
|
||||
/* Load configuration directory - structure and purpose unknown. */
|
||||
public final static int IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG = 10;
|
||||
|
||||
/* Bound import directory - see description of import directory. */
|
||||
public final static int IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT = 11;
|
||||
|
||||
/* Import Address Table - see description of import directory. */
|
||||
public final static int IMAGE_DIRECTORY_ENTRY_IAT = 12;
|
||||
|
||||
}
|
|
@ -0,0 +1,289 @@
|
|||
/*
|
||||
* (c) Copyright QNX Software Systems Ltd. 2002.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
package org.eclipse.cdt.utils.coff;
|
||||
|
||||
public class ReadMemoryAccess {
|
||||
|
||||
byte[] bytes;
|
||||
int memOffset;
|
||||
byte[] val = new byte[8];
|
||||
boolean isle;
|
||||
|
||||
public ReadMemoryAccess(byte[] octets) {
|
||||
this(octets, true);
|
||||
}
|
||||
|
||||
public ReadMemoryAccess(byte[] octets, boolean le) {
|
||||
bytes = octets;
|
||||
memOffset = 0;
|
||||
isle = le;
|
||||
}
|
||||
|
||||
public void getBytes(byte[] octets) {
|
||||
getBytes(octets, memOffset);
|
||||
memOffset += octets.length;
|
||||
}
|
||||
|
||||
public void getBytes(byte[] octets, int offset) {
|
||||
getBytes(octets, offset, octets.length);
|
||||
}
|
||||
|
||||
public void getBytes(byte[] octets, int offset, int length) {
|
||||
System.arraycopy(bytes, offset, octets, 0, length);
|
||||
}
|
||||
|
||||
public byte getByte() {
|
||||
return getByte(memOffset++);
|
||||
}
|
||||
|
||||
public short getUnsignedByte() {
|
||||
return getUnsignedByte(memOffset++);
|
||||
}
|
||||
|
||||
public byte getByte(int offset) {
|
||||
return bytes[offset];
|
||||
}
|
||||
|
||||
public short getUnsignedByte(int offset) {
|
||||
return (short)bytes[offset];
|
||||
}
|
||||
|
||||
public short getShort() {
|
||||
if (isle) {
|
||||
return getShortLE();
|
||||
}
|
||||
return getShortBE();
|
||||
}
|
||||
|
||||
public int getUnsignedShort() {
|
||||
if (isle) {
|
||||
return getUnsignedShortLE();
|
||||
}
|
||||
return getUnsignedShortBE();
|
||||
}
|
||||
|
||||
public short getShortLE() {
|
||||
short s = getShortLE(memOffset);
|
||||
memOffset +=2;
|
||||
return s;
|
||||
}
|
||||
|
||||
public int getUnsignedShortLE() {
|
||||
int i = getUnsignedShortLE(memOffset);
|
||||
memOffset +=2;
|
||||
return i;
|
||||
}
|
||||
|
||||
public short getShortLE(int offset) {
|
||||
val[0] = getByte(offset);
|
||||
val[1] = getByte(offset + 1);
|
||||
return getShortLE(val);
|
||||
}
|
||||
|
||||
public static short getShortLE(byte[] b) {
|
||||
return (short)(((b[1]&0xff) << 8) | (b[0]&0xff));
|
||||
}
|
||||
|
||||
public int getUnsignedShortLE(int offset) {
|
||||
val[0] = getByte(offset);
|
||||
val[1] = getByte(offset + 1);
|
||||
return getUnsignedShortLE(val);
|
||||
}
|
||||
|
||||
public static int getUnsignedShortLE(byte[] b) {
|
||||
return (((b[1] & 0xff) << 8) | (b[0] & 0xff));
|
||||
}
|
||||
|
||||
public short getShortBE() {
|
||||
short s = getShortBE(memOffset);
|
||||
memOffset +=2;
|
||||
return s;
|
||||
}
|
||||
|
||||
public int getUnsignedShortBE() {
|
||||
int i = getUnsignedShortBE(memOffset);
|
||||
memOffset +=2;
|
||||
return i;
|
||||
}
|
||||
|
||||
public short getShortBE(int offset) {
|
||||
val[0] = getByte(offset);
|
||||
val[1] = getByte(offset + 1);
|
||||
return getShortBE(val);
|
||||
}
|
||||
|
||||
public static short getShortBE(byte[] b) {
|
||||
return (short)(((b[0] & 0xff) << 8) | (b[1] & 0xff));
|
||||
}
|
||||
|
||||
public int getUnsignedShortBE(int offset) {
|
||||
val[0] = getByte(offset);
|
||||
val[1] = getByte(offset + 1);
|
||||
return getUnsignedShortBE(val);
|
||||
}
|
||||
|
||||
public static int getUnsignedShortBE(byte[] b) {
|
||||
return (((b[0] & 0xff) << 8) + (b[1] & 0xff));
|
||||
}
|
||||
|
||||
public int getInt() {
|
||||
if (isle) {
|
||||
return getIntLE();
|
||||
}
|
||||
return getIntBE();
|
||||
}
|
||||
|
||||
public int getIntLE() {
|
||||
int i = getIntLE(memOffset);
|
||||
memOffset += 4;
|
||||
return i;
|
||||
}
|
||||
|
||||
public long getUnsignedIntLE() {
|
||||
long l = getUnsignedIntLE(memOffset);
|
||||
memOffset += 4;
|
||||
return l;
|
||||
}
|
||||
|
||||
public long getUnsignedIntLE(int offset) {
|
||||
val[0] = getByte(offset);
|
||||
val[1] = getByte(offset + 1);
|
||||
val[2] = getByte(offset + 2);
|
||||
val[3] = getByte(offset + 3);
|
||||
return getUnsignedIntLE(val);
|
||||
}
|
||||
|
||||
public static long getUnsignedIntLE(byte[] b) {
|
||||
return (long)(((b[3] & 0xff) << 24) |
|
||||
((b[2] & 0xff) << 16) |
|
||||
((b[1] & 0xff) << 8) |
|
||||
(b[0] & 0xff));
|
||||
}
|
||||
|
||||
public int getIntLE(int offset) {
|
||||
val[0] = getByte(offset);
|
||||
val[1] = getByte(offset + 1);
|
||||
val[2] = getByte(offset + 2);
|
||||
val[3] = getByte(offset + 3);
|
||||
return getIntLE(val);
|
||||
}
|
||||
|
||||
public static int getIntLE(byte[] b) {
|
||||
return (int)(((b[3] & 0xff) << 24) |
|
||||
((b[2] & 0xff) << 16) |
|
||||
((b[1] & 0xff) << 8) |
|
||||
(b[0] & 0xff));
|
||||
}
|
||||
|
||||
public int getIntBE() {
|
||||
int i = getIntBE(memOffset);
|
||||
memOffset += 4;
|
||||
return i;
|
||||
}
|
||||
|
||||
public long getUnsignedIntBE() {
|
||||
long l = getUnsignedIntBE(memOffset);
|
||||
memOffset += 4;
|
||||
return l;
|
||||
}
|
||||
|
||||
public int getIntBE(int offset) {
|
||||
val[0] = getByte(offset);
|
||||
val[1] = getByte(offset + 1);
|
||||
val[2] = getByte(offset + 2);
|
||||
val[3] = getByte(offset + 3);
|
||||
return getIntBE(val);
|
||||
}
|
||||
|
||||
public static int getIntBE(byte[] b) {
|
||||
return (int)(((b[0] & 0xff) << 24) |
|
||||
((b[1] & 0xff) << 16) |
|
||||
((b[2] & 0xff) << 8) |
|
||||
(b[3] & 0xff));
|
||||
}
|
||||
|
||||
public long getUnsignedIntBE(int offset) {
|
||||
val[0] = getByte(offset);
|
||||
val[1] = getByte(offset + 1);
|
||||
val[2] = getByte(offset + 2);
|
||||
val[3] = getByte(offset + 3);
|
||||
return getUnsignedIntBE(val);
|
||||
}
|
||||
|
||||
public static long getUnsignedIntBE(byte[] b) {
|
||||
return (long)(((b[0] & 0xff) << 24) |
|
||||
((b[1] & 0xff) << 16) |
|
||||
((b[2] & 0xff) << 8) |
|
||||
(b[3] & 0xff));
|
||||
}
|
||||
|
||||
public long getLong() {
|
||||
if (isle) {
|
||||
return getLongLE();
|
||||
}
|
||||
return getLongBE();
|
||||
}
|
||||
|
||||
public long getLongLE() {
|
||||
long l = getLongLE(memOffset);
|
||||
memOffset += 8;
|
||||
return l;
|
||||
}
|
||||
|
||||
public long getLongLE(int offset) {
|
||||
val[0] = getByte(offset);
|
||||
val[1] = getByte(offset + 1);
|
||||
val[2] = getByte(offset + 2);
|
||||
val[3] = getByte(offset + 3);
|
||||
val[4] = getByte(offset + 4);
|
||||
val[5] = getByte(offset + 5);
|
||||
val[6] = getByte(offset + 6);
|
||||
val[7] = getByte(offset + 7);
|
||||
return getLongLE(val);
|
||||
}
|
||||
|
||||
public long getLongLE(byte[] b) {
|
||||
return ((long)(b[7] & 0xff) << 56) |
|
||||
((long)(b[6] & 0xff) << 48) |
|
||||
((long)(b[5] & 0xff) << 40) |
|
||||
((long)(b[4] & 0xff) << 32) |
|
||||
((long)(b[3] & 0xff) << 24) |
|
||||
((long)(b[2] & 0xff) << 16) |
|
||||
((long)(b[1] & 0xff) << 8) |
|
||||
((long)(b[0] & 0xff));
|
||||
}
|
||||
|
||||
|
||||
public long getLongBE() {
|
||||
long l = getLongBE(memOffset);
|
||||
memOffset += 8;
|
||||
return l;
|
||||
}
|
||||
|
||||
public long getLongBE(int offset) {
|
||||
val[0] = getByte(offset);
|
||||
val[1] = getByte(offset + 1);
|
||||
val[2] = getByte(offset + 2);
|
||||
val[3] = getByte(offset + 3);
|
||||
val[4] = getByte(offset + 4);
|
||||
val[5] = getByte(offset + 5);
|
||||
val[6] = getByte(offset + 6);
|
||||
val[7] = getByte(offset + 7);
|
||||
return getLongBE(val);
|
||||
}
|
||||
|
||||
public long getLongBE(byte[] b) {
|
||||
return ((long)(b[0] & 0xff) << 56) |
|
||||
((long)(b[1] & 0xff) << 48) |
|
||||
((long)(b[2] & 0xff) << 40) |
|
||||
((long)(b[3] & 0xff) << 32) |
|
||||
((long)(b[4] & 0xff) << 24) |
|
||||
((long)(b[5] & 0xff) << 16) |
|
||||
((long)(b[6] & 0xff) << 8) |
|
||||
((long)(b[7] & 0xff));
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Reference in a new issue