completed version info reader with full verification

This commit is contained in:
Dmitry Jemerov
2013-03-27 21:18:26 +01:00
parent bb5daaefcd
commit 8cfc8be969
8 changed files with 134 additions and 22 deletions
+3
View File
@@ -16,6 +16,9 @@
</value>
</option>
<option name="FIELD_NAME_PREFIX" value="my" />
<XML>
<option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
</XML>
<codeStyleSettings language="JAVA">
<indentOptions>
<option name="INDENT_SIZE" value="2" />
@@ -580,6 +580,23 @@ public abstract class Bin {
writer.write(myBuffer.toString());
}
}
public String getAsWChar() {
StringBuilder result = new StringBuilder(myBytes.length/2);
ByteArrayInputStream bis = new ByteArrayInputStream(myBytes);
DataInputStream dis = new DataInputStream(bis);
try {
for (int i = 0; i < myBytes.length / 2 - 1; i++) {
result.append(BitsUtil.readChar(dis));
}
char terminator = BitsUtil.readChar(dis);
assert terminator == '\0';
} catch (IOException e) {
throw new RuntimeException(e);
}
return result.toString();
}
}
public static class ArrayOfBins<T extends Bin> extends Bin {
@@ -79,9 +79,8 @@ public class ExeReader extends Bin.Structure{
}
public SectionReader getSectionReader( String sectionName ){
for (int i = 0; i < mySections.length; i++) {
SectionReader section = mySections[i];
if ( sectionName.equals( section.getSectionName() )){
for (SectionReader section : mySections) {
if (sectionName.equals(section.getSectionName())) {
return section;
}
}
@@ -123,35 +122,26 @@ public class ExeReader extends Bin.Structure{
super.resetOffsets(newOffset);
long mainOffset = myPeHeader.getOffset() + myPeHeader.sizeInBytes() + myBytes.sizeInBytes();
long offset = 0;
for (int i = 0; i < mySections.length; i++) {
Bin section = mySections[i];
section.resetOffsets( mainOffset + offset );
for (SectionReader section : mySections) {
section.resetOffsets(mainOffset + offset);
offset += section.sizeInBytes();
}
}
public void write(DataOutput stream) throws IOException {
super.write(stream);
myBytes.write( stream );
for (int i = 0; i < mySections.length; i++) {
mySections[i].write( stream );
myBytes.write(stream);
for (SectionReader section : mySections) {
section.write(stream);
}
}
public void report(OutputStreamWriter writer) throws IOException {
super.report(writer);
myBytes.report( writer );
mySectionHeaders.report( writer );
for ( int i = 0; i < mySections.length; ++i ){
mySections[i].report( writer );
mySectionHeaders.report(writer);
for (SectionReader section : mySections) {
section.report(writer);
}
}
public static void main(String[] args) throws Throwable {
ExeReader reader = new ExeReader( "SeaShell.exe" );
File file = new File( "C:\\work\\SeaShell.exe" );
RandomAccessFile stream = new RandomAccessFile( file, "r" );
reader.read( stream );
stream.close();
}
}
@@ -19,6 +19,9 @@ package com.pme.exe.res.vi;
import com.pme.exe.Bin;
import java.io.DataInput;
import java.io.IOException;
/**
* Date: May 10, 2006
* Time: 1:35:49 PM
@@ -40,4 +43,11 @@ public class FixedFileInfo extends Bin.Structure {
addMember( new DWord( "dwFileDateMS" ) );
addMember( new DWord( "dwFileDateLS" ) );
}
@Override
public void read(DataInput stream) throws IOException {
super.read(stream);
long signature = getValue("dwSignature");
assert signature == 0xFEEF04BDl : "Incorrect signature; expected " +0xFEEF04BDl + ", found " + signature;
}
}
@@ -29,7 +29,7 @@ public class StringFileInfo extends Bin.Structure {
addMember(new Word("wLength"));
addMember(new Word("wValueLength"));
addMember(new Word("wType"));
addMember(new WChar("szKey"));
addMember(new Bytes("szKey", 30));
addMember(new Padding(4));
}
@@ -38,6 +38,7 @@ public class StringFileInfo extends Bin.Structure {
OffsetTrackingInputStream inputStream = (OffsetTrackingInputStream) stream;
long startOffset = inputStream.getOffset();
super.read(stream);
assert ((Bytes) getMember("szKey")).getAsWChar().equals("StringFileInfo");
long length = getValue("wLength");
int i = 0;
while(inputStream.getOffset() < startOffset + length) {
@@ -0,0 +1,32 @@
package com.pme.exe.res.vi;
import com.pme.exe.Bin;
import com.pme.util.OffsetTrackingInputStream;
import java.io.DataInput;
import java.io.IOException;
/**
* @author yole
*/
public class Var extends Bin.Structure {
public Var(String name) {
super(name);
addMember(new Word("wLength"));
addMember(new Word("wValueLength"));
addMember(new Word("wType"));
addMember(new Bytes("szKey", 24));
addMember(new Padding(4));
addMember(new DWord("Translation"));
}
@Override
public void read(DataInput stream) throws IOException {
OffsetTrackingInputStream inputStream = (OffsetTrackingInputStream) stream;
long startOffset = inputStream.getOffset();
assert startOffset % 4 == 0;
super.read(stream);
String varKey = ((Bytes) getMember("szKey")).getAsWChar();
assert varKey.equals("Translation"): "Expected key name Translation, found " + varKey;
}
}
@@ -0,0 +1,36 @@
package com.pme.exe.res.vi;
import com.pme.exe.Bin;
import com.pme.util.OffsetTrackingInputStream;
import java.io.DataInput;
import java.io.IOException;
/**
* @author yole
*/
public class VarFileInfo extends Bin.Structure {
public VarFileInfo() {
super("VarFileInfo");
addMember(new Word("wLength"));
addMember(new Word("wValueLength"));
addMember(new Word("wType"));
addMember(new Bytes("szKey", 24));
addMember(new Padding(4));
}
@Override
public void read(DataInput stream) throws IOException {
OffsetTrackingInputStream inputStream = (OffsetTrackingInputStream) stream;
long startOffset = inputStream.getOffset();
super.read(stream);
assert ((Bytes) getMember("szKey")).getAsWChar().equals("VarFileInfo");
long length = getValue("wLength");
int i = 0;
while(inputStream.getOffset() < startOffset + length) {
Var varReader = new Var("Var" + (i++));
varReader.read(inputStream);
addMember(varReader);
}
}
}
@@ -18,6 +18,7 @@
package com.pme.exe.res.vi;
import com.pme.exe.Bin;
import com.pme.util.OffsetTrackingInputStream;
import java.io.DataInput;
import java.io.IOException;
@@ -26,8 +27,30 @@ public class VersionInfo extends Bin.Structure {
public VersionInfo() {
super("VersionInfo");
addMember(new Word("wLength"));
addMember(new Bytes("Bytes", 38));
addMember(new Word("wValueLength"));
addMember(new Word("wType"));
addMember(new Bytes("szKey", 32));
addMember(new Padding(4));
addMember(new FixedFileInfo());
addMember(new Padding(4));
addMember(new StringFileInfo());
addMember(new VarFileInfo());
}
@Override
public void read(DataInput stream) throws IOException {
long startOffset = -1;
if (stream instanceof OffsetTrackingInputStream) {
startOffset = ((OffsetTrackingInputStream) stream).getOffset();
}
super.read(stream);
String signature = ((Bytes) getMember("szKey")).getAsWChar();
assert signature.equals("VS_VERSION_INFO"): "Expected signature VS_VERSION_INFO, found '" + signature + "'";
if (stream instanceof OffsetTrackingInputStream) {
long offset = ((OffsetTrackingInputStream) stream).getOffset();
long length = getValue("wLength");
assert startOffset + length == offset: "Length specified in version info header (" + length +
") does not match actual version info length (" + (offset - startOffset) + ")";
}
}
}