1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Fix the PE parser

This commit is contained in:
Alain Magloire 2004-02-29 07:11:49 +00:00
parent e1140e486b
commit 07f291d778
5 changed files with 94 additions and 27 deletions

View file

@ -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 2004-02-28 Alain Magloire
New method in ICElement New method in ICElement

View file

@ -44,9 +44,25 @@ public class Exe {
byte[] hdr = new byte[EXEHDRSZ]; byte[] hdr = new byte[EXEHDRSZ];
file.readFully(hdr); file.readFully(hdr);
ReadMemoryAccess memory = new ReadMemoryAccess(hdr, true); 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); memory.getBytes(e_signature);
if (e_signature[0] != 'M' || e_signature[1] != 'Z') { 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_lastsize = memory.getShort();
e_nblocks = memory.getShort(); e_nblocks = memory.getShort();

View file

@ -119,6 +119,22 @@ public class PE {
byte[] hdr = new byte[DOSHDRSZ]; byte[] hdr = new byte[DOSHDRSZ];
file.readFully(hdr); file.readFully(hdr);
ReadMemoryAccess memory = new ReadMemoryAccess(hdr, true); 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_res);
memory.getBytes(e_oemid); memory.getBytes(e_oemid);
memory.getBytes(e_oeminfo); memory.getBytes(e_oeminfo);
@ -306,7 +322,25 @@ public class PE {
fileHeader = new Coff.FileHeader(rfile, rfile.getFilePointer()); fileHeader = new Coff.FileHeader(rfile, rfile.getFilePointer());
// Check if this a valid machine. // Check if this a valid machine.
switch (fileHeader.f_magic) { if (!isValidMachine(fileHeader.f_magic)) {
throw new IOException("Unknow machine/format");
}
if (fileHeader.f_opthdr > 0) {
optionalHeader = new Coff.OptionalHeader(rfile, rfile.getFilePointer());
ntHeader = new NTOptionalHeader(rfile, rfile.getFilePointer());
}
} finally {
if (rfile != null) {
rfile.close();
rfile = null;
}
}
}
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_ALPHA:
case PEConstants.IMAGE_FILE_MACHINE_ARM: case PEConstants.IMAGE_FILE_MACHINE_ARM:
case PEConstants.IMAGE_FILE_MACHINE_ALPHA64: case PEConstants.IMAGE_FILE_MACHINE_ALPHA64:
@ -324,22 +358,10 @@ public class PE {
case PEConstants.IMAGE_FILE_MACHINE_SH4: case PEConstants.IMAGE_FILE_MACHINE_SH4:
case PEConstants.IMAGE_FILE_MACHINE_THUMB: case PEConstants.IMAGE_FILE_MACHINE_THUMB:
// Ok; // Ok;
break; return true;
//throw new IOException("Unknow machine/format");
default:
throw new IOException("Unknow machine/format");
}
if (fileHeader.f_opthdr > 0) {
optionalHeader = new Coff.OptionalHeader(rfile, rfile.getFilePointer());
ntHeader = new NTOptionalHeader(rfile, rfile.getFilePointer());
}
} finally {
if (rfile != null) {
rfile.close();
rfile = null;
}
} }
return false;
} }
public static Attribute getAttributes(FileHeader filhdr) { public static Attribute getAttributes(FileHeader filhdr) {
@ -447,9 +469,26 @@ public class PE {
} }
public static Attribute getAttribute(byte[] data) throws IOException { public static Attribute getAttribute(byte[] data) throws IOException {
if (isExeHeader(data)) { ReadMemoryAccess memory = new ReadMemoryAccess(data, true);
Coff.FileHeader filehdr; int idx = 0;
filehdr = new Coff.FileHeader(data, true); 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); return getAttributes(filehdr);
} }
throw new IOException("not a PE format"); throw new IOException("not a PE format");

View file

@ -22,6 +22,10 @@ public class ReadMemoryAccess {
isle = le; isle = le;
} }
public int getSize() {
return bytes.length - memOffset;
}
public void getBytes(byte[] octets) { public void getBytes(byte[] octets) {
getBytes(octets, memOffset); getBytes(octets, memOffset);
memOffset += octets.length; memOffset += octets.length;

View file

@ -129,7 +129,7 @@ public class PEParser extends AbstractCExtension implements IBinaryParser {
* @see org.eclipse.cdt.core.IBinaryParser#getHintBufferSize() * @see org.eclipse.cdt.core.IBinaryParser#getHintBufferSize()
*/ */
public int getHintBufferSize() { public int getHintBufferSize() {
return 128; return 512;
} }
} }