Add .NET metadata reader (ported from C++)

This commit is contained in:
de4dot 2011-10-29 02:20:44 +02:00
parent 89f90d3e75
commit 0e70d020b4
8 changed files with 654 additions and 26 deletions

View File

@ -33,13 +33,15 @@ namespace de4dot.PE {
public DataDirectory vtableFixups;
public DataDirectory exportAddressTableJumps;
public DataDirectory managedNativeHeader;
public Metadata metadata;
BinaryReader reader;
uint mdOffset, mdHeaderLength;
public uint MetadataOffset {
get { return mdOffset; }
get { return metadata.Offset; }
}
public uint MetadataHeaderLength {
get { return mdHeaderLength; }
get { return metadata.HeaderLength; }
}
uint offset;
@ -52,6 +54,7 @@ namespace de4dot.PE {
}
public Cor20Header(BinaryReader reader) {
this.reader = reader;
offset = (uint)reader.BaseStream.Position;
cb = reader.ReadUInt32();
majorRuntimeVersion = reader.ReadUInt16();
@ -67,30 +70,12 @@ namespace de4dot.PE {
managedNativeHeader.read(reader);
}
public void initMetadataTable(BinaryReader reader) {
if (reader.ReadUInt32() != 0x424A5342)
return;
mdOffset = (uint)reader.BaseStream.Position - 4;
reader.ReadUInt16(); // major version
reader.ReadUInt16(); // minor version
reader.ReadUInt32(); // reserved
int slen = reader.ReadInt32();
reader.BaseStream.Position += slen;
reader.ReadUInt16(); // flags
int streams = reader.ReadUInt16();
for (int i = 0; i < streams; i++) {
uint offset = reader.ReadUInt32();
uint size = reader.ReadUInt32();
skipString(reader);
}
mdHeaderLength = (uint)reader.BaseStream.Position - mdOffset;
public void initMetadataTable() {
metadata = new Metadata(reader);
}
void skipString(BinaryReader reader) {
while (reader.ReadByte() != 0) {
// nothing
}
reader.BaseStream.Position = (reader.BaseStream.Position + 3) & ~3;
public MetadataTables createMetadataTables() {
return new MetadataTables(reader, metadata);
}
}
}

View File

@ -0,0 +1,46 @@
/*
Copyright (C) 2011 de4dot@gmail.com
This file is part of de4dot.
de4dot is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
de4dot is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
*/
using System.IO;
namespace de4dot.PE {
class DotNetStream : IFileLocation {
public string name;
public uint fileOffset;
public uint length;
public uint Offset {
get { return fileOffset; }
}
public uint Length {
get { return length; }
}
public DotNetStream(string name, uint fileOffset, uint length) {
this.name = name;
this.fileOffset = fileOffset;
this.length = length;
}
public override string ToString() {
return string.Format("{0:X8} {1:X8} {2}", fileOffset, length, name);
}
}
}

110
de4dot.code/PE/Metadata.cs Normal file
View File

@ -0,0 +1,110 @@
/*
Copyright (C) 2011 de4dot@gmail.com
This file is part of de4dot.
de4dot is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
de4dot is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.IO;
using System.Text;
namespace de4dot.PE {
class Metadata : IFileLocation {
uint magic;
ushort majorVersion, minorVersion;
uint reserved;
string versionString;
ushort flags;
DotNetStream[] streams;
uint offset, headerLength, length;
public uint Offset {
get { return offset; }
}
public uint Length {
get { return length; }
}
public uint HeaderLength {
get { return headerLength; }
}
public uint HeaderEnd {
get { return offset + headerLength; }
}
public Metadata(BinaryReader reader) {
magic = reader.ReadUInt32();
if (magic != 0x424A5342)
return;
offset = (uint)reader.BaseStream.Position - 4;
majorVersion = reader.ReadUInt16();
minorVersion = reader.ReadUInt16();
reserved = reader.ReadUInt32();
versionString = readString(reader, reader.ReadInt32());
flags = reader.ReadUInt16();
int numStreams = reader.ReadUInt16();
streams = new DotNetStream[numStreams];
uint lastOffset = offset;
for (int i = 0; i < numStreams; i++) {
uint fileOffset = offset + reader.ReadUInt32();
uint size = reader.ReadUInt32();
string name = readAsciizString(reader);
streams[i] = new DotNetStream(name, fileOffset, size);
lastOffset = Math.Max(lastOffset, fileOffset + size);
}
lastOffset = Math.Max(lastOffset, (uint)reader.BaseStream.Position);
length = lastOffset - offset;
headerLength = (uint)reader.BaseStream.Position - offset;
}
public DotNetStream getStream(string name) {
foreach (var stream in streams) {
if (stream.name == name)
return stream;
}
return null;
}
string readString(BinaryReader reader, int len) {
var sb = new StringBuilder(len);
var nextPos = reader.BaseStream.Position + len;
for (int i = 0; i < len; i++) {
byte b = reader.ReadByte();
if (b == 0)
break;
sb.Append((char)b);
}
reader.BaseStream.Position = nextPos;
return sb.ToString();
}
string readAsciizString(BinaryReader reader) {
var sb = new StringBuilder();
while (true) {
byte b = reader.ReadByte();
if (b == 0)
break;
sb.Append((char)b);
}
reader.BaseStream.Position = (reader.BaseStream.Position + 3) & ~3;
return sb.ToString();
}
}
}

View File

@ -0,0 +1,151 @@
/*
Copyright (C) 2011 de4dot@gmail.com
This file is part of de4dot.
de4dot is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
de4dot is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.IO;
namespace de4dot.PE {
using MVT = MetadataVarType;
class MetadataTables {
BinaryReader reader;
Metadata metadata;
byte heapOffsetSizes;
MetadataType[] metadataTypes = new MetadataType[64];
public MetadataTables(BinaryReader reader, Metadata metadata) {
this.reader = reader;
this.metadata = metadata;
init();
}
public MetadataType getMetadataType(MetadataIndex index) {
return metadataTypes[(int)index];
}
void seek(uint fileOffset) {
reader.BaseStream.Position = fileOffset;
}
static MetadataVarType[] metadataVarType = new MetadataVarType[] {
MVT.byte2, MVT.stringIndex, MVT.guidIndex, MVT.guidIndex, MVT.guidIndex, MVT.end, // 0
MVT.resolutionScope, MVT.stringIndex, MVT.stringIndex, MVT.end, // 1
MVT.byte4, MVT.stringIndex, MVT.stringIndex, MVT.typeDefOrRef, MVT.fieldIndex, MVT.methodDefIndex, MVT.end, // 2
MVT.end, // 3
MVT.byte2, MVT.stringIndex, MVT.blobIndex, MVT.end, // 4
MVT.end, // 5
MVT.byte4, MVT.byte2, MVT.byte2, MVT.stringIndex, MVT.blobIndex, MVT.paramIndex, MVT.end, // 6
MVT.end, // 7
MVT.byte2, MVT.byte2, MVT.stringIndex, MVT.end, // 8
MVT.typeDefIndex, MVT.typeDefOrRef, MVT.end, // 9
MVT.memberRefParent, MVT.stringIndex, MVT.blobIndex, MVT.end, // 10
MVT.byte1, MVT.byte1, MVT.hasConstant, MVT.blobIndex, MVT.end, // 11
MVT.hasCustomAttribute, MVT.customAttributeType, MVT.blobIndex, MVT.end,// 12
MVT.hasFieldMarshal, MVT.blobIndex, MVT.end, // 13
MVT.byte2, MVT.hasDeclSecurity, MVT.blobIndex, MVT.end, // 14
MVT.byte2, MVT.byte4, MVT.typeDefIndex, MVT.end, // 15
MVT.byte4, MVT.fieldIndex, MVT.end, // 16
MVT.blobIndex, MVT.end, // 17
MVT.typeDefIndex, MVT.eventIndex, MVT.end, // 18
MVT.end, // 19
MVT.byte2, MVT.stringIndex, MVT.typeDefOrRef, MVT.end, // 20
MVT.typeDefIndex, MVT.propertyIndex, MVT.end, // 21
MVT.end, // 22
MVT.byte2, MVT.stringIndex, MVT.blobIndex, MVT.end, // 23
MVT.byte2, MVT.methodDefIndex, MVT.hasSemantics, MVT.end, // 24
MVT.typeDefIndex, MVT.methodDefOrRef, MVT.methodDefOrRef, MVT.end, // 25
MVT.stringIndex, MVT.end, // 26
MVT.blobIndex, MVT.end, // 27
MVT.byte2, MVT.memberForwarded, MVT.stringIndex, MVT.moduleRefIndex, MVT.end, // 28
MVT.byte4, MVT.fieldIndex, MVT.end, // 29
MVT.end, // 30
MVT.end, // 31
MVT.byte4, MVT.byte2, MVT.byte2, MVT.byte2, MVT.byte2, MVT.byte4, MVT.blobIndex, MVT.stringIndex, MVT.stringIndex, MVT.end, // 32
MVT.byte4, MVT.end, // 33
MVT.byte4, MVT.byte4, MVT.byte4, MVT.end, // 34
MVT.byte2, MVT.byte2, MVT.byte2, MVT.byte2, MVT.byte4, MVT.blobIndex, MVT.stringIndex, MVT.stringIndex, MVT.blobIndex, MVT.end, // 35
MVT.byte4, MVT.assemblyRefIndex, MVT.end, // 36
MVT.byte4, MVT.byte4, MVT.byte4, MVT.assemblyRefIndex, MVT.end, // 37
MVT.byte4, MVT.stringIndex, MVT.blobIndex, MVT.end, // 38
MVT.byte4, MVT.byte4, MVT.stringIndex, MVT.stringIndex, MVT.implementation, MVT.end,// 39
MVT.byte4, MVT.byte4, MVT.stringIndex, MVT.implementation, MVT.end, // 40
MVT.typeDefIndex, MVT.typeDefIndex, MVT.end, // 41
MVT.byte2, MVT.byte2, MVT.typeOrMethodDef, MVT.stringIndex, MVT.end, // 42
MVT.end, // 43
MVT.genericParamIndex, MVT.typeDefOrRef, MVT.end, // 44
MVT.end, // 45
MVT.end, // 46
MVT.end, // 47
MVT.end, // 48
MVT.end, // 49
MVT.end, // 50
MVT.end, // 51
MVT.end, // 52
MVT.end, // 53
MVT.end, // 54
MVT.end, // 55
MVT.end, // 56
MVT.end, // 57
MVT.end, // 58
MVT.end, // 59
MVT.end, // 60
MVT.end, // 61
MVT.end, // 62
MVT.end, // 63
MVT.stop
};
void init() {
var streamTable = metadata.getStream("#~");
if (streamTable == null)
throw new ApplicationException("Could not find #~ stream");
seek(streamTable.Offset);
reader.ReadUInt32(); // reserved
reader.ReadUInt16(); // major + minor version
heapOffsetSizes = reader.ReadByte();
reader.ReadByte(); // always 1
ulong validMask = reader.ReadUInt64();
reader.ReadUInt64(); // sorted
var numRows = new uint[64];
for (int i = 0; validMask != 0; i++, validMask >>= 1) {
if ((validMask & 1) != 0)
numRows[i] = reader.ReadUInt32();
}
var builder = new MetadataTypeBuilder(heapOffsetSizes, numRows);
uint fileOffset = (uint)reader.BaseStream.Position;
for (int i = 0, j = 0; ; i++) {
if (metadataVarType[i] == MVT.end) {
var mdType = builder.create();
mdType.rows = numRows[j];
mdType.fileOffset = fileOffset;
fileOffset += mdType.rows * mdType.totalSize;
metadataTypes[j++] = mdType;
}
else if (metadataVarType[i] == MVT.stop)
break;
else
builder.field(metadataVarType[i]);
}
}
}
}

View File

@ -0,0 +1,89 @@
/*
Copyright (C) 2011 de4dot@gmail.com
This file is part of de4dot.
de4dot is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
de4dot is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
*/
using System.Collections.Generic;
namespace de4dot.PE {
enum MetadataIndex {
iModule = 0,
iTypeRef = 1,
iTypeDef = 2,
iField = 4,
iMethodDef = 6,
iParam = 8,
iInterfaceImpl = 9,
iMemberRef = 10,
iConstant = 11,
iCustomAttribute = 12,
iFieldMarshal = 13,
iDeclSecurity = 14,
iClassLayout = 15,
iFieldLayout = 16,
iStandAloneSig = 17,
iEventMap = 18,
iEvent = 20,
iPropertyMap = 21,
iProperty = 23,
iMethodSemantics = 24,
iMethodImpl = 25,
iModuleRef = 26,
iTypeSpec = 27,
iImplMap = 28,
iFieldRVA = 29,
iAssembly = 32,
iAssemblyProcessor = 33,
iAssemblyOS = 34,
iAssemblyRef = 35,
iAssemblyRefProcessor = 36,
iAssemblyRefOS = 37,
iFile = 38,
iExportedType = 39,
iManifestResource = 40,
iNestedClass = 41,
iGenericParam = 42,
iGenericParamConstraint = 44,
};
class MetadataType {
public uint fileOffset;
public uint rows;
public uint totalSize;
public List<MetadataField> fields;
public MetadataType(List<MetadataField> fields) {
this.fields = fields;
totalSize = 0;
foreach (var field in fields)
totalSize += (uint)field.size;
}
public override string ToString() {
return string.Format("MDType: {0:X8}, {1} rows, {2} bytes, {3} fields", fileOffset, rows, totalSize, fields.Count);
}
}
struct MetadataField {
public int offset;
public int size;
public override string ToString() {
return string.Format("offset: {0}, size {1}", offset, size);
}
}
}

View File

@ -0,0 +1,203 @@
/*
Copyright (C) 2011 de4dot@gmail.com
This file is part of de4dot.
de4dot is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
de4dot is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with de4dot. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
namespace de4dot.PE {
enum MetadataVarType {
end,
stop,
byte1,
byte2,
byte4,
stringIndex, // index into #String heap
guidIndex, // index into #GUID heap
blobIndex, // index into #Blob heap
resolutionScope,
typeDefOrRef,
fieldIndex,
methodDefIndex,
paramIndex,
typeDefIndex,
eventIndex,
propertyIndex,
moduleRefIndex,
assemblyRefIndex,
genericParamIndex,
memberRefParent,
hasConstant,
hasCustomAttribute,
customAttributeType,
hasFieldMarshal,
hasDeclSecurity,
hasSemantics,
methodDefOrRef,
memberForwarded,
implementation,
typeOrMethodDef,
};
class MetadataTypeBuilder {
byte heapOffsetSizes;
uint[] numRows;
List<MetadataField> fields;
int offset;
public MetadataTypeBuilder(byte heapOffsetSizes, uint[] numRows) {
this.heapOffsetSizes = heapOffsetSizes;
this.numRows = numRows;
reset();
}
void reset() {
offset = 0;
fields = new List<MetadataField>();
}
public MetadataType create() {
var type = new MetadataType(fields);
reset();
return type;
}
public void field(MetadataVarType type) {
int size;
switch (type) {
case MetadataVarType.byte1:
size = 1;
break;
case MetadataVarType.byte2:
size = 2;
break;
case MetadataVarType.byte4:
size = 4;
break;
case MetadataVarType.stringIndex:
size = (heapOffsetSizes & 1) != 0 ? 4 : 2;
break;
case MetadataVarType.guidIndex:
size = (heapOffsetSizes & 2) != 0 ? 4 : 2;
break;
case MetadataVarType.blobIndex:
size = (heapOffsetSizes & 4) != 0 ? 4 : 2;
break;
case MetadataVarType.resolutionScope:
size = getSize(14, new MetadataIndex[] { MetadataIndex.iModule, MetadataIndex.iModuleRef, MetadataIndex.iAssemblyRef, MetadataIndex.iTypeRef });
break;
case MetadataVarType.typeDefOrRef:
size = getSize(14, new MetadataIndex[] { MetadataIndex.iTypeDef, MetadataIndex.iTypeRef, MetadataIndex.iTypeSpec });
break;
case MetadataVarType.memberRefParent:
size = getSize(13, new MetadataIndex[] { MetadataIndex.iTypeDef, MetadataIndex.iTypeRef, MetadataIndex.iModuleRef, MetadataIndex.iMethodDef, MetadataIndex.iTypeSpec });
break;
case MetadataVarType.hasConstant:
size = getSize(14, new MetadataIndex[] { MetadataIndex.iField, MetadataIndex.iParam, MetadataIndex.iProperty });
break;
case MetadataVarType.hasCustomAttribute:
size = getSize(11, new MetadataIndex[] {
MetadataIndex.iMethodDef, MetadataIndex.iField, MetadataIndex.iTypeRef,
MetadataIndex.iTypeDef, MetadataIndex.iParam, MetadataIndex.iInterfaceImpl,
MetadataIndex.iMemberRef, MetadataIndex.iModule /*TODO:, MetadataIndex.iPermission*/,
MetadataIndex.iProperty, MetadataIndex.iEvent, MetadataIndex.iStandAloneSig,
MetadataIndex.iModuleRef, MetadataIndex.iTypeSpec, MetadataIndex.iAssembly,
MetadataIndex.iAssemblyRef, MetadataIndex.iFile, MetadataIndex.iExportedType,
MetadataIndex.iManifestResource,
});
break;
case MetadataVarType.customAttributeType:
size = getSize(13, new MetadataIndex[] { MetadataIndex.iMethodDef, MetadataIndex.iMemberRef }); // others aren't used
break;
case MetadataVarType.hasFieldMarshal:
size = getSize(15, new MetadataIndex[] { MetadataIndex.iField, MetadataIndex.iParam });
break;
case MetadataVarType.hasDeclSecurity:
size = getSize(14, new MetadataIndex[] { MetadataIndex.iTypeDef, MetadataIndex.iMethodDef, MetadataIndex.iAssembly });
break;
case MetadataVarType.hasSemantics:
size = getSize(15, new MetadataIndex[] { MetadataIndex.iEvent, MetadataIndex.iProperty });
break;
case MetadataVarType.methodDefOrRef:
size = getSize(15, new MetadataIndex[] { MetadataIndex.iMethodDef, MetadataIndex.iMemberRef });
break;
case MetadataVarType.memberForwarded:
size = getSize(15, new MetadataIndex[] { MetadataIndex.iField, MetadataIndex.iMethodDef });
break;
case MetadataVarType.implementation:
size = getSize(14, new MetadataIndex[] { MetadataIndex.iFile, MetadataIndex.iAssemblyRef, MetadataIndex.iExportedType });
break;
case MetadataVarType.typeOrMethodDef:
size = getSize(15, new MetadataIndex[] { MetadataIndex.iTypeDef, MetadataIndex.iMethodDef });
break;
case MetadataVarType.fieldIndex:
size = getSize(MetadataIndex.iField);
break;
case MetadataVarType.methodDefIndex:
size = getSize(MetadataIndex.iMethodDef);
break;
case MetadataVarType.paramIndex:
size = getSize(MetadataIndex.iParam);
break;
case MetadataVarType.typeDefIndex:
size = getSize(MetadataIndex.iTypeDef);
break;
case MetadataVarType.eventIndex:
size = getSize(MetadataIndex.iEvent);
break;
case MetadataVarType.propertyIndex:
size = getSize(MetadataIndex.iProperty);
break;
case MetadataVarType.moduleRefIndex:
size = getSize(MetadataIndex.iModuleRef);
break;
case MetadataVarType.assemblyRefIndex:
size = getSize(MetadataIndex.iAssemblyRef);
break;
case MetadataVarType.genericParamIndex:
size = getSize(MetadataIndex.iGenericParam);
break;
default:
throw new ApplicationException("Unknown type");
}
var field = new MetadataField();
field.offset = offset;
field.size = size;
fields.Add(field);
offset += size;
}
uint getMaxRows(MetadataIndex[] indexes) {
uint maxRows = 0;
for (int i = 0; i < indexes.Length; i++)
maxRows = Math.Max(maxRows, numRows[(int)indexes[i]]);
return maxRows;
}
int getSize(int bits, MetadataIndex[] indexes) {
uint maxNum = 1U << bits;
uint maxRows = getMaxRows(indexes);
return maxRows <= maxNum ? 2 : 4;
}
int getSize(MetadataIndex index) {
return getSize(16, new MetadataIndex[] { index });
}
}
}

View File

@ -30,6 +30,14 @@ namespace de4dot.PE {
Cor20Header cor20Header;
SectionHeader dotNetSection;
public BinaryReader Reader {
get { return reader; }
}
public Cor20Header Cor20Header {
get { return cor20Header; }
}
public PeImage(byte[] data)
: this(new MemoryStream(data)) {
}
@ -75,7 +83,7 @@ namespace de4dot.PE {
cor20Header = new Cor20Header(reader);
dotNetSection = getSectionHeader(netOffset);
seekRva(cor20Header.metaData.virtualAddress);
cor20Header.initMetadataTable(reader);
cor20Header.initMetadataTable();
}
}
@ -125,6 +133,21 @@ namespace de4dot.PE {
writer.Write(data);
}
public byte readByte(uint rva) {
seekRva(rva);
return reader.ReadByte();
}
public ushort readUInt16(uint rva) {
seekRva(rva);
return reader.ReadUInt16();
}
public uint readUInt32(uint rva) {
seekRva(rva);
return reader.ReadUInt32();
}
public int readInt32(uint rva) {
seekRva(rva);
return reader.ReadInt32();
@ -134,5 +157,21 @@ namespace de4dot.PE {
seekRva(rva);
return reader.ReadBytes(size);
}
public uint offsetRead(uint offset, int size) {
if (size == 2) return offsetReadUInt16(offset);
if (size == 4) return offsetReadUInt32(offset);
throw new NotImplementedException();
}
public ushort offsetReadUInt16(uint offset) {
seek(offset);
return reader.ReadUInt16();
}
public uint offsetReadUInt32(uint offset) {
seek(offset);
return reader.ReadUInt32();
}
}
}

View File

@ -113,9 +113,14 @@
<Compile Include="PE\DataDirectory.cs" />
<Compile Include="PE\FileHeader.cs" />
<Compile Include="PE\IFileLocation.cs" />
<Compile Include="PE\Metadata.cs" />
<Compile Include="PE\MetadataTables.cs" />
<Compile Include="PE\MetadataType.cs" />
<Compile Include="PE\MetadataTypeBuilder.cs" />
<Compile Include="PE\OptionalHeader.cs" />
<Compile Include="PE\PeImage.cs" />
<Compile Include="PE\SectionHeader.cs" />
<Compile Include="PE\DotNetStream.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="renamer\DefinitionsRenamer.cs" />