diff --git a/core/org.eclipse.cdt.core/ChangeLog b/core/org.eclipse.cdt.core/ChangeLog index 9a825bb600f..2f2f796eadb 100644 --- a/core/org.eclipse.cdt.core/ChangeLog +++ b/core/org.eclipse.cdt.core/ChangeLog @@ -1,3 +1,11 @@ +2004-02-28 Alain Magloire + Fix PE Parser + + * utils/org/eclipse/cdt/utils/coff/Exe.jva + * utils/org/eclipse/cdt/utils/coff/PE.java + * utils/org/eclipse/cdt/utils/coff/ReadMemoryAccess.java + * utils/rg/eclipse/cdt/utils/coff/parser/PEParser.java + 2004-02-28 Alain Magloire New method in ICElement diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/Exe.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/Exe.java index 6e4896031f7..aec0d1f4674 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/Exe.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/Exe.java @@ -44,9 +44,25 @@ public class Exe { byte[] hdr = new byte[EXEHDRSZ]; file.readFully(hdr); ReadMemoryAccess memory = new ReadMemoryAccess(hdr, true); + commonSetup(memory); + } + + public ExeHeader(byte[] hdr, boolean little) throws IOException { + ReadMemoryAccess memory = new ReadMemoryAccess(hdr, true); + commonSetup(memory); + } + + public ExeHeader(ReadMemoryAccess memory) throws IOException { + commonSetup(memory); + } + + void commonSetup(ReadMemoryAccess memory) throws IOException { + if (memory.getSize() < EXEHDRSZ) { + throw new IOException("Not DOS EXE format"); //$NON-NLS-1$ + } memory.getBytes(e_signature); if (e_signature[0] != 'M' || e_signature[1] != 'Z') { - throw new IOException("Not DOS EXE format"); + throw new IOException("Not DOS EXE format"); //$NON-NLS-1$ } e_lastsize = memory.getShort(); e_nblocks = memory.getShort(); diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/PE.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/PE.java index f8da87bab84..b0fe410cae9 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/PE.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/PE.java @@ -119,6 +119,22 @@ public class PE { byte[] hdr = new byte[DOSHDRSZ]; file.readFully(hdr); ReadMemoryAccess memory = new ReadMemoryAccess(hdr, true); + commonSetup(memory); + } + + public DOSHeader(byte[] hdr, boolean little) throws IOException { + ReadMemoryAccess memory = new ReadMemoryAccess(hdr, little); + commonSetup(memory); + } + + public DOSHeader(ReadMemoryAccess memory) throws IOException { + commonSetup(memory); + } + + public void commonSetup(ReadMemoryAccess memory) throws IOException { + if (memory.getSize() < DOSHDRSZ) { + throw new IOException("Not a Dos Header"); //$NON-NLS-1$ + } memory.getBytes(e_res); memory.getBytes(e_oemid); memory.getBytes(e_oeminfo); @@ -306,28 +322,8 @@ public class PE { fileHeader = new Coff.FileHeader(rfile, rfile.getFilePointer()); // Check if this a valid machine. - switch (fileHeader.f_magic) { - case PEConstants.IMAGE_FILE_MACHINE_ALPHA: - case PEConstants.IMAGE_FILE_MACHINE_ARM: - case PEConstants.IMAGE_FILE_MACHINE_ALPHA64: - case PEConstants.IMAGE_FILE_MACHINE_I386: - case PEConstants.IMAGE_FILE_MACHINE_IA64: - case PEConstants.IMAGE_FILE_MACHINE_M68K: - case PEConstants.IMAGE_FILE_MACHINE_MIPS16: - case PEConstants.IMAGE_FILE_MACHINE_MIPSFPU: - case PEConstants.IMAGE_FILE_MACHINE_MIPSFPU16: - case PEConstants.IMAGE_FILE_MACHINE_POWERPC: - case PEConstants.IMAGE_FILE_MACHINE_R3000: - case PEConstants.IMAGE_FILE_MACHINE_R4000: - case PEConstants.IMAGE_FILE_MACHINE_R10000: - case PEConstants.IMAGE_FILE_MACHINE_SH3: - case PEConstants.IMAGE_FILE_MACHINE_SH4: - case PEConstants.IMAGE_FILE_MACHINE_THUMB: - // Ok; - break; - - default: - throw new IOException("Unknow machine/format"); + if (!isValidMachine(fileHeader.f_magic)) { + throw new IOException("Unknow machine/format"); } if (fileHeader.f_opthdr > 0) { @@ -342,6 +338,32 @@ public class PE { } } + public static boolean isValidMachine(int magic) { + // Check if this a valid machine. + switch (magic) { + case PEConstants.IMAGE_FILE_MACHINE_ALPHA: + case PEConstants.IMAGE_FILE_MACHINE_ARM: + case PEConstants.IMAGE_FILE_MACHINE_ALPHA64: + case PEConstants.IMAGE_FILE_MACHINE_I386: + case PEConstants.IMAGE_FILE_MACHINE_IA64: + case PEConstants.IMAGE_FILE_MACHINE_M68K: + case PEConstants.IMAGE_FILE_MACHINE_MIPS16: + case PEConstants.IMAGE_FILE_MACHINE_MIPSFPU: + case PEConstants.IMAGE_FILE_MACHINE_MIPSFPU16: + case PEConstants.IMAGE_FILE_MACHINE_POWERPC: + case PEConstants.IMAGE_FILE_MACHINE_R3000: + case PEConstants.IMAGE_FILE_MACHINE_R4000: + case PEConstants.IMAGE_FILE_MACHINE_R10000: + case PEConstants.IMAGE_FILE_MACHINE_SH3: + case PEConstants.IMAGE_FILE_MACHINE_SH4: + case PEConstants.IMAGE_FILE_MACHINE_THUMB: + // Ok; + return true; + //throw new IOException("Unknow machine/format"); + } + return false; + } + public static Attribute getAttributes(FileHeader filhdr) { Attribute attrib = new Attribute(); // Machine type. @@ -447,9 +469,26 @@ public class PE { } public static Attribute getAttribute(byte[] data) throws IOException { - if (isExeHeader(data)) { - Coff.FileHeader filehdr; - filehdr = new Coff.FileHeader(data, true); + ReadMemoryAccess memory = new ReadMemoryAccess(data, true); + int idx = 0; + try { + Exe.ExeHeader exeHdr = new Exe.ExeHeader(memory); + DOSHeader dosHdr = new DOSHeader(memory); + // Jump the Coff header, and Check the sig. + idx = dosHdr.e_lfanew; + if (idx + 4 < data.length) { + if (!((data[idx + 0] == 'P') && (data[idx + 1] == 'E') + && (data[idx + 2] == '\0') && (data[idx + 3] == '\0'))) { + throw new IOException("Not a PE format"); + } + idx += 4; + } + } catch (IOException e) { + } + byte[] bytes = new byte[data.length - idx]; + System.arraycopy(data, idx, bytes, 0, data.length - idx); + Coff.FileHeader filehdr = new Coff.FileHeader(bytes, true); + if (isValidMachine(filehdr.f_magic)) { return getAttributes(filehdr); } throw new IOException("not a PE format"); diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/ReadMemoryAccess.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/ReadMemoryAccess.java index 75318e38a66..0755f3ad6f4 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/ReadMemoryAccess.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/ReadMemoryAccess.java @@ -22,6 +22,10 @@ public class ReadMemoryAccess { isle = le; } + public int getSize() { + return bytes.length - memOffset; + } + public void getBytes(byte[] octets) { getBytes(octets, memOffset); memOffset += octets.length; diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEParser.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEParser.java index c02c0b590c5..4b8fbe9b993 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEParser.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEParser.java @@ -129,7 +129,7 @@ public class PEParser extends AbstractCExtension implements IBinaryParser { * @see org.eclipse.cdt.core.IBinaryParser#getHintBufferSize() */ public int getHintBufferSize() { - return 128; + return 512; } }