Imported Upstream version 3.6.0

Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
This commit is contained in:
Jo Shields
2014-08-13 10:39:27 +01:00
commit a575963da9
50588 changed files with 8155799 additions and 0 deletions

View File

@@ -0,0 +1,221 @@
//
// AssemblyStripper.cs
//
// Author:
// Jb Evain (jbevain@novell.com)
//
// (C) 2008 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System.Collections;
using System.IO;
using Mono.Cecil;
using Mono.Cecil.Binary;
using Mono.Cecil.Cil;
using Mono.Cecil.Metadata;
namespace Mono.CilStripper {
class AssemblyStripper {
AssemblyDefinition assembly;
BinaryWriter writer;
Image original;
Image stripped;
ReflectionWriter reflection_writer;
MetadataWriter metadata_writer;
TablesHeap original_tables;
TablesHeap stripped_tables;
AssemblyStripper (AssemblyDefinition assembly, BinaryWriter writer)
{
this.assembly = assembly;
this.writer = writer;
}
void Strip ()
{
FullLoad ();
ClearMethodBodies ();
CopyOriginalImage ();
PatchMethods ();
PatchFields ();
PatchResources ();
Write ();
}
void FullLoad ()
{
assembly.MainModule.FullLoad ();
}
void ClearMethodBodies ()
{
foreach (TypeDefinition type in assembly.MainModule.Types) {
ClearMethodBodies (type.Constructors);
ClearMethodBodies (type.Methods);
}
}
static void ClearMethodBodies (ICollection methods)
{
foreach (MethodDefinition method in methods) {
if (!method.HasBody)
continue;
MethodBody body = new MethodBody (method);
body.CilWorker.Emit (OpCodes.Ret);
method.Body = body;
}
}
void CopyOriginalImage ()
{
original = assembly.MainModule.Image;
stripped = Image.CreateImage();
stripped.Accept (new CopyImageVisitor (original));
assembly.MainModule.Image = stripped;
original_tables = original.MetadataRoot.Streams.TablesHeap;
stripped_tables = stripped.MetadataRoot.Streams.TablesHeap;
TableCollection tables = original_tables.Tables;
foreach (IMetadataTable table in tables)
stripped_tables.Tables.Add(table);
stripped_tables.Valid = original_tables.Valid;
stripped_tables.Sorted = original_tables.Sorted;
reflection_writer = new ReflectionWriter (assembly.MainModule);
reflection_writer.StructureWriter = new StructureWriter (assembly, writer);
reflection_writer.CodeWriter.Stripped = true;
metadata_writer = reflection_writer.MetadataWriter;
PatchHeap (metadata_writer.StringWriter, original.MetadataRoot.Streams.StringsHeap);
PatchHeap (metadata_writer.GuidWriter, original.MetadataRoot.Streams.GuidHeap);
PatchHeap (metadata_writer.UserStringWriter, original.MetadataRoot.Streams.UserStringsHeap);
PatchHeap (metadata_writer.BlobWriter, original.MetadataRoot.Streams.BlobHeap);
if (assembly.EntryPoint != null)
metadata_writer.EntryPointToken = assembly.EntryPoint.MetadataToken.ToUInt ();
}
static void PatchHeap (MemoryBinaryWriter heap_writer, MetadataHeap heap)
{
if (heap == null)
return;
heap_writer.BaseStream.Position = 0;
heap_writer.Write (heap.Data);
}
void PatchMethods ()
{
MethodTable methodTable = (MethodTable) stripped_tables [MethodTable.RId];
if (methodTable == null)
return;
RVA method_rva = RVA.Zero;
for (int i = 0; i < methodTable.Rows.Count; i++) {
MethodRow methodRow = methodTable[i];
MetadataToken methodToken = MetadataToken.FromMetadataRow (TokenType.Method, i);
MethodDefinition method = (MethodDefinition) assembly.MainModule.LookupByToken (methodToken);
if (method.HasBody) {
method_rva = method_rva != RVA.Zero
? method_rva
: reflection_writer.CodeWriter.WriteMethodBody (method);
methodRow.RVA = method_rva;
} else
methodRow.RVA = RVA.Zero;
}
}
void PatchFields ()
{
FieldRVATable fieldRvaTable = (FieldRVATable) stripped_tables [FieldRVATable.RId];
if (fieldRvaTable == null)
return;
for (int i = 0; i < fieldRvaTable.Rows.Count; i++) {
FieldRVARow fieldRvaRow = fieldRvaTable [i];
MetadataToken fieldToken = new MetadataToken (TokenType.Field, fieldRvaRow.Field);
FieldDefinition field = (FieldDefinition) assembly.MainModule.LookupByToken (fieldToken);
fieldRvaRow.RVA = metadata_writer.GetDataCursor ();
metadata_writer.AddData (field.InitialValue.Length + 3 & (~3));
metadata_writer.AddFieldInitData (field.InitialValue);
}
}
void PatchResources ()
{
ManifestResourceTable resourceTable = (ManifestResourceTable) stripped_tables [ManifestResourceTable.RId];
if (resourceTable == null)
return;
for (int i = 0; i < resourceTable.Rows.Count; i++) {
ManifestResourceRow resourceRow = resourceTable [i];
if (resourceRow.Implementation.RID != 0)
continue;
foreach (Resource resource in assembly.MainModule.Resources) {
EmbeddedResource er = resource as EmbeddedResource;
if (er == null)
continue;
if (resource.Name != original.MetadataRoot.Streams.StringsHeap [resourceRow.Name])
continue;
resourceRow.Offset = metadata_writer.AddResource (er.Data);
}
}
}
void Write ()
{
stripped.MetadataRoot.Accept (metadata_writer);
}
public static void StripAssembly (AssemblyDefinition assembly, string file)
{
using (FileStream fs = new FileStream (file, FileMode.Create, FileAccess.Write, FileShare.None)) {
new AssemblyStripper (assembly, new BinaryWriter (fs)).Strip ();
}
}
}
}

View File

@@ -0,0 +1,8 @@
2009-03-12 Jb Evain <jbevain@novell.com>
* cilstrip.cs: unwrap TargetInvocationException.
2008-10-01 Jb Evain <jbevain@novell.com>
* cilstrip.cs: mono-cecil-cil is a tool to empty method bodies for
assemblies that have been AOTed.

View File

@@ -0,0 +1,7 @@
thisdir = tools/cil-strip
SUBDIRS =
include ../../build/rules.make
PROGRAM = mono-cil-strip.exe
include ../../build/executable.make

View File

@@ -0,0 +1,101 @@
//
// BaseImageVisitor.cs
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// (C) 2005 - 2007 Jb Evain
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
namespace Mono.Cecil.Binary {
internal abstract class BaseImageVisitor : IBinaryVisitor {
public virtual void VisitImage (Image img)
{
}
public virtual void VisitDOSHeader (DOSHeader header)
{
}
public virtual void VisitPEFileHeader (PEFileHeader header)
{
}
public virtual void VisitPEOptionalHeader (PEOptionalHeader header)
{
}
public virtual void VisitStandardFieldsHeader (PEOptionalHeader.StandardFieldsHeader header)
{
}
public virtual void VisitNTSpecificFieldsHeader (PEOptionalHeader.NTSpecificFieldsHeader header)
{
}
public virtual void VisitDataDirectoriesHeader (PEOptionalHeader.DataDirectoriesHeader header)
{
}
public virtual void VisitSectionCollection (SectionCollection coll)
{
}
public virtual void VisitSection (Section section)
{
}
public virtual void VisitImportAddressTable (ImportAddressTable iat)
{
}
public virtual void VisitDebugHeader (DebugHeader dh)
{
}
public virtual void VisitCLIHeader (CLIHeader header)
{
}
public virtual void VisitImportTable (ImportTable it)
{
}
public virtual void VisitImportLookupTable (ImportLookupTable ilt)
{
}
public virtual void VisitHintNameTable (HintNameTable hnt)
{
}
public virtual void VisitExportTable (ExportTable et)
{
}
public virtual void TerminateImage (Image img)
{
}
}
}

View File

@@ -0,0 +1,66 @@
//
// CLIHeader.cs
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// (C) 2005 Jb Evain
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
namespace Mono.Cecil.Binary {
internal sealed class CLIHeader : IHeader, IBinaryVisitable {
public uint Cb;
public ushort MajorRuntimeVersion;
public ushort MinorRuntimeVersion;
public DataDirectory Metadata;
public RuntimeImage Flags;
public uint EntryPointToken;
public DataDirectory Resources;
public DataDirectory StrongNameSignature;
public DataDirectory CodeManagerTable;
public DataDirectory VTableFixups;
public DataDirectory ExportAddressTableJumps;
public DataDirectory ManagedNativeHeader;
public byte [] ImageHash;
internal CLIHeader ()
{
}
public void SetDefaultValues ()
{
Cb = 0x48;
Flags = RuntimeImage.ILOnly;
CodeManagerTable = DataDirectory.Zero;
ExportAddressTableJumps = DataDirectory.Zero;
ManagedNativeHeader = DataDirectory.Zero;
}
public void Accept (IBinaryVisitor visitor)
{
visitor.VisitCLIHeader (this);
}
}
}

View File

@@ -0,0 +1,121 @@
//
// CopyImageVisitor.cs
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// (C) 2005 Jb Evain
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
namespace Mono.Cecil.Binary {
sealed class CopyImageVisitor : BaseImageVisitor {
Image m_newImage;
Image m_originalImage;
public CopyImageVisitor (Image originalImage)
{
m_originalImage = originalImage;
}
public override void VisitImage (Image img)
{
m_newImage = img;
if (m_originalImage.DebugHeader != null)
m_newImage.AddDebugHeader ();
m_newImage.CLIHeader.Flags = m_originalImage.CLIHeader.Flags;
}
public override void VisitDebugHeader (DebugHeader dbgHeader)
{
DebugHeader old = m_originalImage.DebugHeader;
dbgHeader.Age = old.Age;
dbgHeader.Characteristics = old.Characteristics;
dbgHeader.FileName = old.FileName;
dbgHeader.Signature = old.Signature;
dbgHeader.TimeDateStamp = ImageInitializer.TimeDateStampFromEpoch();
dbgHeader.Type = old.Type;
}
public override void VisitSectionCollection (SectionCollection sections)
{
Section old = null;
foreach (Section s in m_originalImage.Sections)
if (s.Name == Section.Resources)
old = s;
if (old == null)
return;
Section rsrc = new Section ();
rsrc.Characteristics = old.Characteristics;
rsrc.Name = old.Name;
sections.Add (rsrc);
}
public override void TerminateImage (Image img)
{
if (m_originalImage.ResourceDirectoryRoot == null)
return;
m_newImage.ResourceDirectoryRoot = CloneResourceDirectoryTable (m_originalImage.ResourceDirectoryRoot);
}
ResourceDirectoryTable CloneResourceDirectoryTable (ResourceDirectoryTable old)
{
ResourceDirectoryTable rdt = new ResourceDirectoryTable ();
foreach (ResourceDirectoryEntry oldEntry in old.Entries)
rdt.Entries.Add (CloneResourceDirectoryEntry (oldEntry));
return rdt;
}
ResourceDirectoryEntry CloneResourceDirectoryEntry (ResourceDirectoryEntry old)
{
ResourceDirectoryEntry rde;
if (old.IdentifiedByName)
rde = new ResourceDirectoryEntry(old.Name);
else
rde = new ResourceDirectoryEntry (old.ID);
if (old.Child is ResourceDirectoryTable)
rde.Child = CloneResourceDirectoryTable (old.Child as ResourceDirectoryTable);
else
rde.Child = CloneResourceDataEntry (old.Child as ResourceDataEntry);
return rde;
}
ResourceDataEntry CloneResourceDataEntry (ResourceDataEntry old)
{
ResourceDataEntry rde = new ResourceDataEntry ();
rde.Size = old.Size;
rde.Codepage = old.Codepage;
rde.ResourceData = old.ResourceData;
return rde;
}
}
}

View File

@@ -0,0 +1,75 @@
//
// DOSHeader.cs
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// (C) 2005 Jb Evain
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
namespace Mono.Cecil.Binary {
internal sealed class DOSHeader : IHeader, IBinaryVisitable {
public byte [] Start;
public byte [] End;
public uint Lfanew;
internal DOSHeader ()
{
}
public void SetDefaultValues ()
{
Start = new byte [60] {
0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00, 0x00,
0x00, 0x04, 0x00, 0x00, 0x00, 0xff, 0xff,
0x00, 0x00, 0xb8, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
};
Lfanew = 128;
End = new byte [64] {
0x0e, 0x1f, 0xba, 0x0e, 0x00, 0xb4, 0x09,
0xcd, 0x21, 0xb8, 0x01, 0x4c, 0xcd, 0x21,
0x54, 0x68, 0x69, 0x73, 0x20, 0x70, 0x72,
0x6f, 0x67, 0x72, 0x61, 0x6d, 0x20, 0x63,
0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x20, 0x62,
0x65, 0x20, 0x72, 0x75, 0x6e, 0x20, 0x69,
0x6e, 0x20, 0x44, 0x4f, 0x53, 0x20, 0x6d,
0x6f, 0x64, 0x65, 0x2e, 0x0d, 0x0d, 0x0a,
0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00
};
}
public void Accept (IBinaryVisitor visitor)
{
visitor.VisitDOSHeader (this);
}
}
}

View File

@@ -0,0 +1,84 @@
//
// DataDirectory.cs
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// (C) 2005 Jb Evain
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
namespace Mono.Cecil.Binary {
internal struct DataDirectory {
public static readonly DataDirectory Zero = new DataDirectory (RVA.Zero, 0);
RVA m_virtualAddress;
uint m_size;
public RVA VirtualAddress {
get { return m_virtualAddress; }
set { m_virtualAddress = value; }
}
public uint Size {
get { return m_size; }
set { m_size = value; }
}
public DataDirectory (RVA virtualAddress, uint size)
{
m_virtualAddress = virtualAddress;
m_size = size;
}
public override int GetHashCode ()
{
return (m_virtualAddress.GetHashCode () ^ (int) m_size << 1);
}
public override bool Equals (object other)
{
if (other is DataDirectory) {
DataDirectory odd = (DataDirectory) other;
return this.m_virtualAddress == odd.m_virtualAddress && this.m_size == odd.m_size;
}
return false;
}
public override string ToString ()
{
return string.Format ("{0} [{1}]", m_virtualAddress, m_size.ToString ("X"));
}
public static bool operator == (DataDirectory one, DataDirectory other)
{
return one.m_virtualAddress == other.m_virtualAddress && one.m_size == other.m_size;
}
public static bool operator != (DataDirectory one, DataDirectory other)
{
return one.m_virtualAddress != other.m_virtualAddress || one.m_size != other.m_size;
}
}
}

View File

@@ -0,0 +1,73 @@
//
// DebugHeader.cs
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// (C) 2005 Jb Evain
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
namespace Mono.Cecil.Binary {
using System;
internal sealed class DebugHeader : IHeader, IBinaryVisitable {
public uint Characteristics;
public uint TimeDateStamp;
public ushort MajorVersion;
public ushort MinorVersion;
public DebugStoreType Type;
public uint SizeOfData;
public RVA AddressOfRawData;
public uint PointerToRawData;
public uint Magic;
public Guid Signature;
public uint Age;
public string FileName;
internal DebugHeader ()
{
}
public void SetDefaultValues ()
{
Characteristics = 0;
this.Magic = 0x53445352;
this.Age = 0;
this.Type = DebugStoreType.CodeView;
this.FileName = string.Empty;
}
public uint GetSize ()
{
return 0x34 + (uint) FileName.Length + 1;
}
public void Accept (IBinaryVisitor visitor)
{
visitor.VisitDebugHeader (this);
}
}
}

View File

@@ -0,0 +1,45 @@
//
// DebugStoreType.cs
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// (C) 2005 Jb Evain
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
namespace Mono.Cecil.Binary {
internal enum DebugStoreType : uint {
Unknown = 0x00000000,
COFF = 0x00000001,
CodeView = 0x00000002,
FPO = 0x00000003,
Misc = 0x00000004,
Exception = 0x00000005,
Fixup = 0x00000006,
OMAPToSrc = 0x00000007,
OMAPFromSrc = 0x00000008,
Borland = 0x00000009,
Reserved10 = 0x0000000a,
CLSID = 0x0000000b
}
}

View File

@@ -0,0 +1,59 @@
//
// ExportTable.cs
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// (C) 2007 Jb Evain
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
namespace Mono.Cecil.Binary {
internal sealed class ExportTable : IBinaryVisitable {
public uint Characteristics;
public uint TimeDateStamp;
public ushort MajorVersion;
public ushort MinorVersion;
public string Name;
public uint Base;
public uint NumberOfFunctions;
public uint NumberOfNames;
public RVA AddressOfFunctions;
public RVA AddressOfNames;
public RVA AddressOfNameOrdinals;
public RVA [] AddressesOfFunctions;
public RVA [] AddressesOfNames;
public ushort [] NameOrdinals;
public string [] Names;
internal ExportTable ()
{
}
public void Accept (IBinaryVisitor visitor)
{
visitor.VisitExportTable (this);
}
}
}

View File

@@ -0,0 +1,35 @@
//
// IBinaryVisitable.cs
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// (C) 2005 Jb Evain
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
namespace Mono.Cecil.Binary {
internal interface IBinaryVisitable {
void Accept (IBinaryVisitor visitor);
}
}

View File

@@ -0,0 +1,51 @@
//
// IBinaryVisitor.cs
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// (C) 2005 - 2007 Jb Evain
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
namespace Mono.Cecil.Binary {
internal interface IBinaryVisitor {
void VisitImage (Image img);
void VisitDOSHeader (DOSHeader header);
void VisitPEFileHeader (PEFileHeader header);
void VisitPEOptionalHeader (PEOptionalHeader header);
void VisitStandardFieldsHeader (PEOptionalHeader.StandardFieldsHeader header);
void VisitNTSpecificFieldsHeader (PEOptionalHeader.NTSpecificFieldsHeader header);
void VisitDataDirectoriesHeader (PEOptionalHeader.DataDirectoriesHeader header);
void VisitSectionCollection (SectionCollection coll);
void VisitSection (Section section);
void VisitImportAddressTable (ImportAddressTable iat);
void VisitDebugHeader (DebugHeader dh);
void VisitCLIHeader (CLIHeader header);
void VisitImportTable (ImportTable it);
void VisitImportLookupTable (ImportLookupTable ilt);
void VisitHintNameTable (HintNameTable hnt);
void VisitExportTable (ExportTable et);
void TerminateImage (Image img);
}
}

View File

@@ -0,0 +1,34 @@
//
// IHeader.cs
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// (C) 2005 Jb Evain
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
namespace Mono.Cecil.Binary {
internal interface IHeader {
void SetDefaultValues ();
}
}

View File

@@ -0,0 +1,243 @@
//
// Image.cs
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// (C) 2005 - 2007 Jb Evain
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
namespace Mono.Cecil.Binary {
using System;
using System.IO;
using Mono.Cecil.Metadata;
internal sealed class Image : IBinaryVisitable {
DOSHeader m_dosHeader;
PEFileHeader m_peFileHeader;
PEOptionalHeader m_peOptionalHeader;
SectionCollection m_sections;
Section m_textSection;
ImportAddressTable m_importAddressTable;
CLIHeader m_cliHeader;
ImportTable m_importTable;
ImportLookupTable m_importLookupTable;
HintNameTable m_hintNameTable;
ExportTable m_exportTable;
DebugHeader m_debugHeader;
MetadataRoot m_mdRoot;
ResourceDirectoryTable m_rsrcRoot;
FileInfo m_img;
public DOSHeader DOSHeader {
get { return m_dosHeader; }
}
public PEFileHeader PEFileHeader {
get { return m_peFileHeader; }
}
public PEOptionalHeader PEOptionalHeader {
get { return m_peOptionalHeader; }
}
public SectionCollection Sections {
get { return m_sections; }
}
public Section TextSection {
get { return m_textSection; }
set { m_textSection = value; }
}
public ImportAddressTable ImportAddressTable {
get { return m_importAddressTable; }
}
public CLIHeader CLIHeader {
get { return m_cliHeader; }
set { m_cliHeader = value; }
}
public DebugHeader DebugHeader {
get { return m_debugHeader; }
set { m_debugHeader = value; }
}
public MetadataRoot MetadataRoot {
get { return m_mdRoot; }
}
public ImportTable ImportTable {
get { return m_importTable; }
}
public ImportLookupTable ImportLookupTable {
get { return m_importLookupTable; }
}
public HintNameTable HintNameTable {
get { return m_hintNameTable; }
}
public ExportTable ExportTable {
get { return m_exportTable; }
set { m_exportTable = value; }
}
internal ResourceDirectoryTable ResourceDirectoryRoot {
get { return m_rsrcRoot; }
set { m_rsrcRoot = value; }
}
public FileInfo FileInformation {
get { return m_img; }
}
internal Image ()
{
m_dosHeader = new DOSHeader ();
m_peFileHeader = new PEFileHeader ();
m_peOptionalHeader = new PEOptionalHeader ();
m_sections = new SectionCollection ();
m_importAddressTable = new ImportAddressTable ();
m_importTable = new ImportTable ();
m_importLookupTable = new ImportLookupTable ();
m_hintNameTable = new HintNameTable ();
m_mdRoot = new MetadataRoot (this);
}
internal Image (FileInfo img) : this ()
{
m_img = img;
}
public long ResolveVirtualAddress (RVA rva)
{
foreach (Section sect in this.Sections) {
if (rva >= sect.VirtualAddress &&
rva < sect.VirtualAddress + sect.SizeOfRawData)
return rva + sect.PointerToRawData - sect.VirtualAddress;
}
throw new ArgumentOutOfRangeException ("Cannot map the rva to any section");
}
internal Section GetSectionAtVirtualAddress (RVA rva)
{
foreach (Section sect in this.Sections) {
if (rva >= sect.VirtualAddress &&
rva < sect.VirtualAddress + sect.SizeOfRawData) {
return sect;
}
}
return null;
}
public BinaryReader GetReaderAtVirtualAddress (RVA rva)
{
Section sect = GetSectionAtVirtualAddress (rva);
if (sect == null)
return null;
BinaryReader br = new BinaryReader (new MemoryStream (sect.Data));
br.BaseStream.Position = rva - sect.VirtualAddress;
return br;
}
public void AddDebugHeader ()
{
m_debugHeader = new DebugHeader ();
m_debugHeader.SetDefaultValues ();
}
internal void SetFileInfo (FileInfo file)
{
m_img = file;
}
public void Accept (IBinaryVisitor visitor)
{
visitor.VisitImage (this);
m_dosHeader.Accept (visitor);
m_peFileHeader.Accept (visitor);
m_peOptionalHeader.Accept (visitor);
m_sections.Accept (visitor);
m_importAddressTable.Accept (visitor);
AcceptIfNotNull (m_cliHeader, visitor);
AcceptIfNotNull (m_debugHeader, visitor);
m_importTable.Accept (visitor);
m_importLookupTable.Accept (visitor);
m_hintNameTable.Accept (visitor);
AcceptIfNotNull (m_exportTable, visitor);
visitor.TerminateImage (this);
}
static void AcceptIfNotNull (IBinaryVisitable visitable, IBinaryVisitor visitor)
{
if (visitable == null)
return;
visitable.Accept (visitor);
}
public static Image CreateImage ()
{
Image img = new Image ();
ImageInitializer init = new ImageInitializer (img);
img.Accept (init);
return img;
}
public static Image GetImage (string file)
{
return ImageReader.Read (file).Image;
}
public static Image GetImage (byte [] image)
{
return ImageReader.Read (image).Image;
}
public static Image GetImage (Stream stream)
{
return ImageReader.Read (stream).Image;
}
}
}

View File

@@ -0,0 +1,57 @@
//
// ImageCharacteristics.cs
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// (C) 2005 Jb Evain
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
namespace Mono.Cecil.Binary {
using System;
[Flags]
internal enum ImageCharacteristics : ushort {
RelocsStripped = 0x0001,
ExecutableImage = 0x0002,
LineNumsStripped = 0x0004,
LocalSymsStripped = 0x0008,
AggressiveWSTrim = 0x0010,
LargeAddressAware = 0x0020,
ReservedForFutureUse = 0x0040,
BytesReversedLo = 0x0080,
_32BitsMachine = 0x0100,
DebugStripped = 0x0200,
RemovableRunFromSwap = 0x0400,
NetRunFromSwap = 0x0800,
System = 0x1000,
Dll = 0x2000,
UPSystemOnly = 0x4000,
BytesReversedHI = 0x8000,
__flags = 0x0002 | 0x0004 | 0x0008 | 0x0100,
CILOnlyDll = 0x2000 | (ushort) __flags,
CILOnlyExe = __flags
}
}

View File

@@ -0,0 +1,53 @@
//
// ImageFormatException.cs
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// (C) 2005 Jb Evain
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
namespace Mono.Cecil.Binary {
using System;
internal class ImageFormatException : Exception {
internal ImageFormatException () : base()
{
}
internal ImageFormatException (string message) : base(message)
{
}
internal ImageFormatException (string message, params string[] parameters) :
base(string.Format(message, parameters))
{
}
internal ImageFormatException (string message, Exception inner) :
base(message, inner)
{
}
}
}

View File

@@ -0,0 +1,139 @@
//
// ImageInitializer.cs
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// (C) 2005 Jb Evain
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
namespace Mono.Cecil.Binary {
using System;
using Mono.Cecil.Metadata;
sealed class ImageInitializer : BaseImageVisitor {
Image m_image;
MetadataInitializer m_mdinit;
public Image Image {
get { return m_image; }
}
public MetadataInitializer Metadata {
get { return m_mdinit; }
}
public ImageInitializer (Image image)
{
m_image = image;
m_image.CLIHeader = new CLIHeader ();
m_mdinit = new MetadataInitializer (this);
}
public override void VisitDOSHeader (DOSHeader header)
{
header.SetDefaultValues ();
}
public override void VisitPEOptionalHeader (PEOptionalHeader header)
{
header.SetDefaultValues ();
}
public override void VisitPEFileHeader (PEFileHeader header)
{
header.SetDefaultValues ();
header.TimeDateStamp = TimeDateStampFromEpoch ();
}
public override void VisitNTSpecificFieldsHeader (PEOptionalHeader.NTSpecificFieldsHeader header)
{
header.SetDefaultValues ();
}
public override void VisitStandardFieldsHeader (PEOptionalHeader.StandardFieldsHeader header)
{
header.SetDefaultValues ();
}
public override void VisitDataDirectoriesHeader (PEOptionalHeader.DataDirectoriesHeader header)
{
header.SetDefaultValues ();
}
public override void VisitSectionCollection (SectionCollection coll)
{
Section text = new Section ();
text.Name = Section.Text;
text.Characteristics = SectionCharacteristics.ContainsCode |
SectionCharacteristics.MemoryRead | SectionCharacteristics.MemExecute;
m_image.TextSection = text;
Section reloc = new Section ();
reloc.Name = Section.Relocs;
reloc.Characteristics = SectionCharacteristics.ContainsInitializedData |
SectionCharacteristics.MemDiscardable | SectionCharacteristics.MemoryRead;
coll.Add (text);
coll.Add (reloc);
}
public override void VisitSection (Section sect)
{
sect.SetDefaultValues ();
}
public override void VisitDebugHeader (DebugHeader dh)
{
if (dh != null)
dh.SetDefaultValues ();
}
public override void VisitCLIHeader (CLIHeader header)
{
header.SetDefaultValues ();
m_image.MetadataRoot.Accept (m_mdinit);
}
public override void VisitImportTable (ImportTable it)
{
it.ImportAddressTable = new RVA (0x2000);
}
public override void VisitHintNameTable (HintNameTable hnt)
{
hnt.Hint = 0;
hnt.RuntimeLibrary = HintNameTable.RuntimeCorEE;
hnt.EntryPoint = 0x25ff;
hnt.RVA = new RVA (0x402000);
}
public static uint TimeDateStampFromEpoch ()
{
return (uint) DateTime.UtcNow.Subtract (
new DateTime (1970, 1, 1)).TotalSeconds;
}
}
}

View File

@@ -0,0 +1,485 @@
//
// ImageReader.cs
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// (C) 2005 - 2007 Jb Evain
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
namespace Mono.Cecil.Binary {
using System;
using System.IO;
using System.Text;
using Mono.Cecil.Metadata;
sealed class ImageReader : BaseImageVisitor {
MetadataReader m_mdReader;
BinaryReader m_binaryReader;
Image m_image;
public MetadataReader MetadataReader {
get { return m_mdReader; }
}
public Image Image {
get { return m_image; }
}
ImageReader (Image img, BinaryReader reader)
{
m_image = img;
m_binaryReader = reader;
}
static ImageReader Read (Image img, Stream stream)
{
ImageReader reader = new ImageReader (img, new BinaryReader (stream));
img.Accept (reader);
return reader;
}
public static ImageReader Read (string file)
{
if (file == null)
throw new ArgumentNullException ("file");
FileInfo fi = new FileInfo (file);
if (!File.Exists (fi.FullName))
#if CF_1_0 || CF_2_0
throw new FileNotFoundException (fi.FullName);
#else
throw new FileNotFoundException (string.Format ("File '{0}' not found.", fi.FullName), fi.FullName);
#endif
FileStream stream = null;
try {
stream = new FileStream (fi.FullName, FileMode.Open, FileAccess.Read, FileShare.Read);
return Read (new Image (fi), stream);
} catch (Exception e) {
if (stream != null)
stream.Close ();
#if CF_1_0 || CF_2_0
throw new BadImageFormatException ("Invalid PE file: " + file, e);
#else
throw new BadImageFormatException ("Invalid PE file", file, e);
#endif
}
}
public static ImageReader Read (byte [] image)
{
if (image == null)
throw new ArgumentNullException ("image");
if (image.Length == 0)
throw new ArgumentException ("Empty image array");
return Read (new Image (), new MemoryStream (image));
}
public static ImageReader Read (Stream stream)
{
if (stream == null)
throw new ArgumentNullException ("stream");
if (!stream.CanRead)
throw new ArgumentException ("Can not read from stream");
return Read (new Image (), stream);
}
public BinaryReader GetReader ()
{
return m_binaryReader;
}
public override void VisitImage (Image img)
{
m_mdReader = new MetadataReader (this);
}
void SetPositionToAddress (RVA address)
{
m_binaryReader.BaseStream.Position = m_image.ResolveVirtualAddress (address);
}
public override void VisitDOSHeader (DOSHeader header)
{
header.Start = m_binaryReader.ReadBytes (60);
header.Lfanew = m_binaryReader.ReadUInt32 ();
header.End = m_binaryReader.ReadBytes (64);
m_binaryReader.BaseStream.Position = header.Lfanew;
if (m_binaryReader.ReadUInt16 () != 0x4550 ||
m_binaryReader.ReadUInt16 () != 0)
throw new ImageFormatException ("Invalid PE File Signature");
}
public override void VisitPEFileHeader (PEFileHeader header)
{
header.Machine = m_binaryReader.ReadUInt16 ();
header.NumberOfSections = m_binaryReader.ReadUInt16 ();
header.TimeDateStamp = m_binaryReader.ReadUInt32 ();
header.PointerToSymbolTable = m_binaryReader.ReadUInt32 ();
header.NumberOfSymbols = m_binaryReader.ReadUInt32 ();
header.OptionalHeaderSize = m_binaryReader.ReadUInt16 ();
header.Characteristics = (ImageCharacteristics) m_binaryReader.ReadUInt16 ();
}
ulong ReadIntOrLong ()
{
return m_image.PEOptionalHeader.StandardFields.IsPE64 ?
m_binaryReader.ReadUInt64 () :
m_binaryReader.ReadUInt32 ();
}
RVA ReadRVA ()
{
return m_binaryReader.ReadUInt32 ();
}
DataDirectory ReadDataDirectory ()
{
return new DataDirectory (ReadRVA (), m_binaryReader.ReadUInt32 ());
}
public override void VisitNTSpecificFieldsHeader (PEOptionalHeader.NTSpecificFieldsHeader header)
{
header.ImageBase = ReadIntOrLong ();
header.SectionAlignment = m_binaryReader.ReadUInt32 ();
header.FileAlignment = m_binaryReader.ReadUInt32 ();
header.OSMajor = m_binaryReader.ReadUInt16 ();
header.OSMinor = m_binaryReader.ReadUInt16 ();
header.UserMajor = m_binaryReader.ReadUInt16 ();
header.UserMinor = m_binaryReader.ReadUInt16 ();
header.SubSysMajor = m_binaryReader.ReadUInt16 ();
header.SubSysMinor = m_binaryReader.ReadUInt16 ();
header.Reserved = m_binaryReader.ReadUInt32 ();
header.ImageSize = m_binaryReader.ReadUInt32 ();
header.HeaderSize = m_binaryReader.ReadUInt32 ();
header.FileChecksum = m_binaryReader.ReadUInt32 ();
header.SubSystem = (SubSystem) m_binaryReader.ReadUInt16 ();
header.DLLFlags = m_binaryReader.ReadUInt16 ();
header.StackReserveSize = ReadIntOrLong ();
header.StackCommitSize = ReadIntOrLong ();
header.HeapReserveSize = ReadIntOrLong ();
header.HeapCommitSize = ReadIntOrLong ();
header.LoaderFlags = m_binaryReader.ReadUInt32 ();
header.NumberOfDataDir = m_binaryReader.ReadUInt32 ();
}
public override void VisitStandardFieldsHeader (PEOptionalHeader.StandardFieldsHeader header)
{
header.Magic = m_binaryReader.ReadUInt16 ();
header.LMajor = m_binaryReader.ReadByte ();
header.LMinor = m_binaryReader.ReadByte ();
header.CodeSize = m_binaryReader.ReadUInt32 ();
header.InitializedDataSize = m_binaryReader.ReadUInt32 ();
header.UninitializedDataSize = m_binaryReader.ReadUInt32 ();
header.EntryPointRVA = ReadRVA ();
header.BaseOfCode = ReadRVA ();
if (!header.IsPE64)
header.BaseOfData = ReadRVA ();
}
public override void VisitDataDirectoriesHeader (PEOptionalHeader.DataDirectoriesHeader header)
{
header.ExportTable = ReadDataDirectory ();
header.ImportTable = ReadDataDirectory ();
header.ResourceTable = ReadDataDirectory ();
header.ExceptionTable = ReadDataDirectory ();
header.CertificateTable = ReadDataDirectory ();
header.BaseRelocationTable = ReadDataDirectory ();
header.Debug = ReadDataDirectory ();
header.Copyright = ReadDataDirectory ();
header.GlobalPtr = ReadDataDirectory ();
header.TLSTable = ReadDataDirectory ();
header.LoadConfigTable = ReadDataDirectory ();
header.BoundImport = ReadDataDirectory ();
header.IAT = ReadDataDirectory ();
header.DelayImportDescriptor = ReadDataDirectory ();
header.CLIHeader = ReadDataDirectory ();
header.Reserved = ReadDataDirectory ();
if (header.CLIHeader != DataDirectory.Zero)
m_image.CLIHeader = new CLIHeader ();
if (header.ExportTable != DataDirectory.Zero)
m_image.ExportTable = new ExportTable ();
}
public override void VisitSectionCollection (SectionCollection coll)
{
for (int i = 0; i < m_image.PEFileHeader.NumberOfSections; i++)
coll.Add (new Section ());
}
public override void VisitSection (Section sect)
{
char [] buffer = new char [8];
int read = 0;
while (read < 8) {
char cur = (char) m_binaryReader.ReadSByte ();
if (cur == '\0') {
m_binaryReader.BaseStream.Position += 8 - read - 1;
break;
}
buffer [read++] = cur;
}
sect.Name = read == 0 ? string.Empty : new string (buffer, 0, read);
if (sect.Name == Section.Text)
m_image.TextSection = sect;
sect.VirtualSize = m_binaryReader.ReadUInt32 ();
sect.VirtualAddress = ReadRVA ();
sect.SizeOfRawData = m_binaryReader.ReadUInt32 ();
sect.PointerToRawData = ReadRVA ();
sect.PointerToRelocations = ReadRVA ();
sect.PointerToLineNumbers = ReadRVA ();
sect.NumberOfRelocations = m_binaryReader.ReadUInt16 ();
sect.NumberOfLineNumbers = m_binaryReader.ReadUInt16 ();
sect.Characteristics = (SectionCharacteristics) m_binaryReader.ReadUInt32 ();
long pos = m_binaryReader.BaseStream.Position;
m_binaryReader.BaseStream.Position = sect.PointerToRawData;
sect.Data = m_binaryReader.ReadBytes ((int) sect.SizeOfRawData);
m_binaryReader.BaseStream.Position = pos;
}
public override void VisitImportAddressTable (ImportAddressTable iat)
{
if (m_image.PEOptionalHeader.DataDirectories.IAT.VirtualAddress == RVA.Zero)
return;
SetPositionToAddress (m_image.PEOptionalHeader.DataDirectories.IAT.VirtualAddress);
iat.HintNameTableRVA = ReadRVA ();
}
public override void VisitCLIHeader (CLIHeader header)
{
if (m_image.PEOptionalHeader.DataDirectories.Debug != DataDirectory.Zero) {
m_image.DebugHeader = new DebugHeader ();
VisitDebugHeader (m_image.DebugHeader);
}
SetPositionToAddress (m_image.PEOptionalHeader.DataDirectories.CLIHeader.VirtualAddress);
header.Cb = m_binaryReader.ReadUInt32 ();
header.MajorRuntimeVersion = m_binaryReader.ReadUInt16 ();
header.MinorRuntimeVersion = m_binaryReader.ReadUInt16 ();
header.Metadata = ReadDataDirectory ();
header.Flags = (RuntimeImage) m_binaryReader.ReadUInt32 ();
header.EntryPointToken = m_binaryReader.ReadUInt32 ();
header.Resources = ReadDataDirectory ();
header.StrongNameSignature = ReadDataDirectory ();
header.CodeManagerTable = ReadDataDirectory ();
header.VTableFixups = ReadDataDirectory ();
header.ExportAddressTableJumps = ReadDataDirectory ();
header.ManagedNativeHeader = ReadDataDirectory ();
if (header.StrongNameSignature != DataDirectory.Zero) {
SetPositionToAddress (header.StrongNameSignature.VirtualAddress);
header.ImageHash = m_binaryReader.ReadBytes ((int) header.StrongNameSignature.Size);
} else
header.ImageHash = new byte [0];
SetPositionToAddress (m_image.CLIHeader.Metadata.VirtualAddress);
m_image.MetadataRoot.Accept (m_mdReader);
}
public override void VisitDebugHeader (DebugHeader header)
{
if (m_image.PEOptionalHeader.DataDirectories.Debug == DataDirectory.Zero)
return;
long pos = m_binaryReader.BaseStream.Position;
SetPositionToAddress (m_image.PEOptionalHeader.DataDirectories.Debug.VirtualAddress);
header.Characteristics = m_binaryReader.ReadUInt32 ();
header.TimeDateStamp = m_binaryReader.ReadUInt32 ();
header.MajorVersion = m_binaryReader.ReadUInt16 ();
header.MinorVersion = m_binaryReader.ReadUInt16 ();
header.Type = (DebugStoreType) m_binaryReader.ReadUInt32 ();
header.SizeOfData = m_binaryReader.ReadUInt32 ();
header.AddressOfRawData = ReadRVA ();
header.PointerToRawData = m_binaryReader.ReadUInt32 ();
m_binaryReader.BaseStream.Position = header.PointerToRawData;
header.Magic = m_binaryReader.ReadUInt32 ();
header.Signature = new Guid (m_binaryReader.ReadBytes (16));
header.Age = m_binaryReader.ReadUInt32 ();
header.FileName = ReadZeroTerminatedString ();
m_binaryReader.BaseStream.Position = pos;
}
string ReadZeroTerminatedString ()
{
StringBuilder sb = new StringBuilder ();
while (true) {
byte chr = m_binaryReader.ReadByte ();
if (chr == 0)
break;
sb.Append ((char) chr);
}
return sb.ToString ();
}
public override void VisitImportTable (ImportTable it)
{
if (m_image.PEOptionalHeader.DataDirectories.ImportTable.VirtualAddress == RVA.Zero)
return;
SetPositionToAddress (m_image.PEOptionalHeader.DataDirectories.ImportTable.VirtualAddress);
it.ImportLookupTable = ReadRVA ();
it.DateTimeStamp = m_binaryReader.ReadUInt32 ();
it.ForwardChain = m_binaryReader.ReadUInt32 ();
it.Name = ReadRVA ();
it.ImportAddressTable = ReadRVA ();
}
public override void VisitImportLookupTable (ImportLookupTable ilt)
{
if (m_image.ImportTable.ImportLookupTable == RVA.Zero)
return;
SetPositionToAddress (m_image.ImportTable.ImportLookupTable);
ilt.HintNameRVA = ReadRVA ();
}
public override void VisitHintNameTable (HintNameTable hnt)
{
if (m_image.ImportAddressTable.HintNameTableRVA == RVA.Zero)
return;
if ((m_image.ImportAddressTable.HintNameTableRVA & 0x80000000) != 0)
return;
SetPositionToAddress (m_image.ImportAddressTable.HintNameTableRVA);
hnt.Hint = m_binaryReader.ReadUInt16 ();
byte [] bytes = m_binaryReader.ReadBytes (11);
hnt.RuntimeMain = Encoding.ASCII.GetString (bytes, 0, bytes.Length);
SetPositionToAddress (m_image.ImportTable.Name);
bytes = m_binaryReader.ReadBytes (11);
hnt.RuntimeLibrary = Encoding.ASCII.GetString (bytes, 0, bytes.Length);
SetPositionToAddress (m_image.PEOptionalHeader.StandardFields.EntryPointRVA);
hnt.EntryPoint = m_binaryReader.ReadUInt16 ();
hnt.RVA = ReadRVA ();
}
public override void VisitExportTable (ExportTable et)
{
SetPositionToAddress (m_image.PEOptionalHeader.DataDirectories.ExportTable.VirtualAddress);
et.Characteristics = m_binaryReader.ReadUInt32 ();
et.TimeDateStamp = m_binaryReader.ReadUInt32 ();
et.MajorVersion = m_binaryReader.ReadUInt16 ();
et.MinorVersion = m_binaryReader.ReadUInt16 ();
//et.Name =
m_binaryReader.ReadUInt32 ();
et.Base = m_binaryReader.ReadUInt32 ();
et.NumberOfFunctions = m_binaryReader.ReadUInt32 ();
et.NumberOfNames = m_binaryReader.ReadUInt32 ();
et.AddressOfFunctions = m_binaryReader.ReadUInt32 ();
et.AddressOfNames = m_binaryReader.ReadUInt32 ();
et.AddressOfNameOrdinals = m_binaryReader.ReadUInt32 ();
et.AddressesOfFunctions = ReadArrayOfRVA (et.AddressOfFunctions, et.NumberOfFunctions);
et.AddressesOfNames = ReadArrayOfRVA (et.AddressOfNames, et.NumberOfNames);
et.NameOrdinals = ReadArrayOfUInt16 (et.AddressOfNameOrdinals, et.NumberOfNames);
et.Names = new string [et.NumberOfFunctions];
for (int i = 0; i < et.NumberOfFunctions; i++) {
if (et.AddressesOfFunctions [i] == 0)
continue;
et.Names [i] = ReadFunctionName (et, i);
}
}
string ReadFunctionName (ExportTable et, int index)
{
for (int i = 0; i < et.NumberOfNames; i++) {
if (et.NameOrdinals [i] != index)
continue;
SetPositionToAddress (et.AddressesOfNames [i]);
return ReadZeroTerminatedString ();
}
return string.Empty;
}
ushort [] ReadArrayOfUInt16 (RVA position, uint length)
{
if (position == RVA.Zero)
return new ushort [0];
SetPositionToAddress (position);
ushort [] array = new ushort [length];
for (int i = 0; i < length; i++)
array [i] = m_binaryReader.ReadUInt16 ();
return array;
}
RVA [] ReadArrayOfRVA (RVA position, uint length)
{
if (position == RVA.Zero)
return new RVA [0];
SetPositionToAddress (position);
RVA [] addresses = new RVA [length];
for (int i = 0; i < length; i++)
addresses [i] = m_binaryReader.ReadUInt32 ();
return addresses;
}
public override void TerminateImage(Image img)
{
m_binaryReader.Close ();
try {
ResourceReader resReader = new ResourceReader (img);
img.ResourceDirectoryRoot = resReader.Read ();
} catch {
img.ResourceDirectoryRoot = null;
}
}
}
}

View File

@@ -0,0 +1,434 @@
//
// ImageWriter.cs
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// (C) 2005 Jb Evain
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
namespace Mono.Cecil.Binary {
using System.IO;
using System.Text;
using Mono.Cecil.Metadata;
sealed class ImageWriter : BaseImageVisitor {
Image m_img;
AssemblyKind m_kind;
MetadataWriter m_mdWriter;
BinaryWriter m_binaryWriter;
Section m_textSect;
MemoryBinaryWriter m_textWriter;
Section m_relocSect;
MemoryBinaryWriter m_relocWriter;
Section m_rsrcSect;
MemoryBinaryWriter m_rsrcWriter;
public ImageWriter (MetadataWriter writer, AssemblyKind kind, BinaryWriter bw)
{
m_mdWriter= writer;
m_img = writer.GetMetadataRoot ().GetImage ();
m_kind = kind;
m_binaryWriter = bw;
m_textWriter = new MemoryBinaryWriter ();
m_textWriter.BaseStream.Position = 80;
m_relocWriter = new MemoryBinaryWriter ();
}
public Image GetImage ()
{
return m_img;
}
public MemoryBinaryWriter GetTextWriter ()
{
return m_textWriter;
}
public uint GetAligned (uint integer, uint alignWith)
{
return (integer + alignWith - 1) & ~(alignWith - 1);
}
public void Initialize ()
{
Image img = m_img;
ResourceWriter resWriter = null;
uint sectAlign = img.PEOptionalHeader.NTSpecificFields.SectionAlignment;
uint fileAlign = img.PEOptionalHeader.NTSpecificFields.FileAlignment;
m_textSect = img.TextSection;
foreach (Section s in img.Sections) {
if (s.Name == Section.Relocs)
m_relocSect = s;
else if (s.Name == Section.Resources) {
m_rsrcSect = s;
m_rsrcWriter = new MemoryBinaryWriter ();
resWriter = new ResourceWriter (img, m_rsrcSect, m_rsrcWriter);
resWriter.Write ();
}
}
// size computations, fields setting, etc.
uint nbSects = (uint) img.Sections.Count;
img.PEFileHeader.NumberOfSections = (ushort) nbSects;
// build the reloc section data
uint relocSize = 12;
m_relocWriter.Write ((uint) 0);
m_relocWriter.Write (relocSize);
m_relocWriter.Write ((ushort) 0);
m_relocWriter.Write ((ushort) 0);
m_textSect.VirtualSize = (uint) m_textWriter.BaseStream.Length;
m_relocSect.VirtualSize = (uint) m_relocWriter.BaseStream.Length;
if (m_rsrcSect != null)
m_rsrcSect.VirtualSize = (uint) m_rsrcWriter.BaseStream.Length;
// start counting before sections headers
// section start + section header sixe * number of sections
uint headersEnd = 0x178 + 0x28 * nbSects;
uint fileOffset = headersEnd;
uint sectOffset = sectAlign;
uint imageSize = 0;
foreach (Section sect in img.Sections) {
fileOffset = GetAligned (fileOffset, fileAlign);
sectOffset = GetAligned (sectOffset, sectAlign);
sect.PointerToRawData = new RVA (fileOffset);
sect.VirtualAddress = new RVA (sectOffset);
sect.SizeOfRawData = GetAligned (sect.VirtualSize, fileAlign);
fileOffset += sect.SizeOfRawData;
sectOffset += sect.SizeOfRawData;
imageSize += GetAligned (sect.SizeOfRawData, sectAlign);
}
if (m_textSect.VirtualAddress.Value != 0x2000)
throw new ImageFormatException ("Wrong RVA for .text section");
if (resWriter != null)
resWriter.Patch ();
img.PEOptionalHeader.StandardFields.CodeSize = GetAligned (
m_textSect.SizeOfRawData, fileAlign);
img.PEOptionalHeader.StandardFields.InitializedDataSize = m_textSect.SizeOfRawData;
if (m_rsrcSect != null)
img.PEOptionalHeader.StandardFields.InitializedDataSize += m_rsrcSect.SizeOfRawData;
img.PEOptionalHeader.StandardFields.BaseOfCode = m_textSect.VirtualAddress;
img.PEOptionalHeader.StandardFields.BaseOfData = m_relocSect.VirtualAddress;
imageSize += headersEnd;
img.PEOptionalHeader.NTSpecificFields.ImageSize = GetAligned (imageSize, sectAlign);
img.PEOptionalHeader.DataDirectories.BaseRelocationTable = new DataDirectory (
m_relocSect.VirtualAddress, m_relocSect.VirtualSize);
if (m_rsrcSect != null)
img.PEOptionalHeader.DataDirectories.ResourceTable = new DataDirectory (
m_rsrcSect.VirtualAddress, (uint) m_rsrcWriter.BaseStream.Length);
if (m_kind == AssemblyKind.Dll) {
img.PEFileHeader.Characteristics = ImageCharacteristics.CILOnlyDll;
img.HintNameTable.RuntimeMain = HintNameTable.RuntimeMainDll;
img.PEOptionalHeader.NTSpecificFields.DLLFlags = 0x400;
} else {
img.PEFileHeader.Characteristics = ImageCharacteristics.CILOnlyExe;
img.HintNameTable.RuntimeMain = HintNameTable.RuntimeMainExe;
}
switch (m_kind) {
case AssemblyKind.Dll :
case AssemblyKind.Console :
img.PEOptionalHeader.NTSpecificFields.SubSystem = SubSystem.WindowsCui;
break;
case AssemblyKind.Windows :
img.PEOptionalHeader.NTSpecificFields.SubSystem = SubSystem.WindowsGui;
break;
}
RVA importTable = new RVA (img.TextSection.VirtualAddress + m_mdWriter.ImportTablePosition);
img.PEOptionalHeader.DataDirectories.ImportTable = new DataDirectory (importTable, 0x57);
img.ImportTable.ImportLookupTable = new RVA ((uint) importTable + 0x28);
img.ImportLookupTable.HintNameRVA = img.ImportAddressTable.HintNameTableRVA =
new RVA ((uint) img.ImportTable.ImportLookupTable + 0x14);
img.ImportTable.Name = new RVA ((uint) img.ImportLookupTable.HintNameRVA + 0xe);
}
public override void VisitDOSHeader (DOSHeader header)
{
m_binaryWriter.Write (header.Start);
m_binaryWriter.Write (header.Lfanew);
m_binaryWriter.Write (header.End);
m_binaryWriter.Write ((ushort) 0x4550);
m_binaryWriter.Write ((ushort) 0);
}
public override void VisitPEFileHeader (PEFileHeader header)
{
m_binaryWriter.Write (header.Machine);
m_binaryWriter.Write (header.NumberOfSections);
m_binaryWriter.Write (header.TimeDateStamp);
m_binaryWriter.Write (header.PointerToSymbolTable);
m_binaryWriter.Write (header.NumberOfSymbols);
m_binaryWriter.Write (header.OptionalHeaderSize);
m_binaryWriter.Write ((ushort) header.Characteristics);
}
public override void VisitNTSpecificFieldsHeader (PEOptionalHeader.NTSpecificFieldsHeader header)
{
WriteIntOrLong (header.ImageBase);
m_binaryWriter.Write (header.SectionAlignment);
m_binaryWriter.Write (header.FileAlignment);
m_binaryWriter.Write (header.OSMajor);
m_binaryWriter.Write (header.OSMinor);
m_binaryWriter.Write (header.UserMajor);
m_binaryWriter.Write (header.UserMinor);
m_binaryWriter.Write (header.SubSysMajor);
m_binaryWriter.Write (header.SubSysMinor);
m_binaryWriter.Write (header.Reserved);
m_binaryWriter.Write (header.ImageSize);
m_binaryWriter.Write (header.HeaderSize);
m_binaryWriter.Write (header.FileChecksum);
m_binaryWriter.Write ((ushort) header.SubSystem);
m_binaryWriter.Write (header.DLLFlags);
WriteIntOrLong (header.StackReserveSize);
WriteIntOrLong (header.StackCommitSize);
WriteIntOrLong (header.HeapReserveSize);
WriteIntOrLong (header.HeapCommitSize);
m_binaryWriter.Write (header.LoaderFlags);
m_binaryWriter.Write (header.NumberOfDataDir);
}
public override void VisitStandardFieldsHeader (PEOptionalHeader.StandardFieldsHeader header)
{
m_binaryWriter.Write (header.Magic);
m_binaryWriter.Write (header.LMajor);
m_binaryWriter.Write (header.LMinor);
m_binaryWriter.Write (header.CodeSize);
m_binaryWriter.Write (header.InitializedDataSize);
m_binaryWriter.Write (header.UninitializedDataSize);
m_binaryWriter.Write (header.EntryPointRVA.Value);
m_binaryWriter.Write (header.BaseOfCode.Value);
if (!header.IsPE64)
m_binaryWriter.Write (header.BaseOfData.Value);
}
void WriteIntOrLong (ulong value)
{
if (m_img.PEOptionalHeader.StandardFields.IsPE64)
m_binaryWriter.Write (value);
else
m_binaryWriter.Write ((uint) value);
}
public override void VisitDataDirectoriesHeader (PEOptionalHeader.DataDirectoriesHeader header)
{
m_binaryWriter.Write (header.ExportTable.VirtualAddress);
m_binaryWriter.Write (header.ExportTable.Size);
m_binaryWriter.Write (header.ImportTable.VirtualAddress);
m_binaryWriter.Write (header.ImportTable.Size);
m_binaryWriter.Write (header.ResourceTable.VirtualAddress);
m_binaryWriter.Write (header.ResourceTable.Size);
m_binaryWriter.Write (header.ExceptionTable.VirtualAddress);
m_binaryWriter.Write (header.ExceptionTable.Size);
m_binaryWriter.Write (header.CertificateTable.VirtualAddress);
m_binaryWriter.Write (header.CertificateTable.Size);
m_binaryWriter.Write (header.BaseRelocationTable.VirtualAddress);
m_binaryWriter.Write (header.BaseRelocationTable.Size);
m_binaryWriter.Write (header.Debug.VirtualAddress);
m_binaryWriter.Write (header.Debug.Size);
m_binaryWriter.Write (header.Copyright.VirtualAddress);
m_binaryWriter.Write (header.Copyright.Size);
m_binaryWriter.Write (header.GlobalPtr.VirtualAddress);
m_binaryWriter.Write (header.GlobalPtr.Size);
m_binaryWriter.Write (header.TLSTable.VirtualAddress);
m_binaryWriter.Write (header.TLSTable.Size);
m_binaryWriter.Write (header.LoadConfigTable.VirtualAddress);
m_binaryWriter.Write (header.LoadConfigTable.Size);
m_binaryWriter.Write (header.BoundImport.VirtualAddress);
m_binaryWriter.Write (header.BoundImport.Size);
m_binaryWriter.Write (header.IAT.VirtualAddress);
m_binaryWriter.Write (header.IAT.Size);
m_binaryWriter.Write (header.DelayImportDescriptor.VirtualAddress);
m_binaryWriter.Write (header.DelayImportDescriptor.Size);
m_binaryWriter.Write (header.CLIHeader.VirtualAddress);
m_binaryWriter.Write (header.CLIHeader.Size);
m_binaryWriter.Write (header.Reserved.VirtualAddress);
m_binaryWriter.Write (header.Reserved.Size);
}
public override void VisitSection (Section sect)
{
m_binaryWriter.Write (Encoding.ASCII.GetBytes (sect.Name));
int more = 8 - sect.Name.Length;
for (int i = 0; i < more; i++)
m_binaryWriter.Write ((byte) 0);
m_binaryWriter.Write (sect.VirtualSize);
m_binaryWriter.Write (sect.VirtualAddress.Value);
m_binaryWriter.Write (sect.SizeOfRawData);
m_binaryWriter.Write (sect.PointerToRawData.Value);
m_binaryWriter.Write (sect.PointerToRelocations.Value);
m_binaryWriter.Write (sect.PointerToLineNumbers.Value);
m_binaryWriter.Write (sect.NumberOfRelocations);
m_binaryWriter.Write (sect.NumberOfLineNumbers);
m_binaryWriter.Write ((uint) sect.Characteristics);
}
public override void VisitImportAddressTable (ImportAddressTable iat)
{
m_textWriter.BaseStream.Position = 0;
m_textWriter.Write (iat.HintNameTableRVA.Value);
m_textWriter.Write (new byte [4]);
}
public override void VisitCLIHeader (CLIHeader header)
{
m_textWriter.Write (header.Cb);
if (m_mdWriter.TargetRuntime >= TargetRuntime.NET_2_0) {
m_textWriter.Write ((ushort) 2);
m_textWriter.Write ((ushort) 5);
} else {
m_textWriter.Write ((ushort) 2);
m_textWriter.Write ((ushort) 0);
}
m_textWriter.Write (header.Metadata.VirtualAddress);
m_textWriter.Write (header.Metadata.Size);
m_textWriter.Write ((uint) header.Flags);
m_textWriter.Write (header.EntryPointToken);
m_textWriter.Write (header.Resources.VirtualAddress);
m_textWriter.Write (header.Resources.Size);
m_textWriter.Write (header.StrongNameSignature.VirtualAddress);
m_textWriter.Write (header.StrongNameSignature.Size);
m_textWriter.Write (header.CodeManagerTable.VirtualAddress);
m_textWriter.Write (header.CodeManagerTable.Size);
m_textWriter.Write (header.VTableFixups.VirtualAddress);
m_textWriter.Write (header.VTableFixups.Size);
m_textWriter.Write (header.ExportAddressTableJumps.VirtualAddress);
m_textWriter.Write (header.ExportAddressTableJumps.Size);
m_textWriter.Write (header.ManagedNativeHeader.VirtualAddress);
m_textWriter.Write (header.ManagedNativeHeader.Size);
}
public override void VisitDebugHeader (DebugHeader header)
{
m_textWriter.BaseStream.Position = m_mdWriter.DebugHeaderPosition;
uint sizeUntilData = 0x1c;
header.AddressOfRawData = m_img.TextSection.VirtualAddress + m_mdWriter.DebugHeaderPosition + sizeUntilData;
header.PointerToRawData = 0x200 + m_mdWriter.DebugHeaderPosition + sizeUntilData;
header.SizeOfData = 0x18 + (uint) header.FileName.Length + 1;
m_textWriter.Write (header.Characteristics);
m_textWriter.Write (header.TimeDateStamp);
m_textWriter.Write (header.MajorVersion);
m_textWriter.Write (header.MinorVersion);
m_textWriter.Write ((uint) header.Type);
m_textWriter.Write (header.SizeOfData);
m_textWriter.Write (header.AddressOfRawData.Value);
m_textWriter.Write (header.PointerToRawData);
m_textWriter.Write (header.Magic);
m_textWriter.Write (header.Signature.ToByteArray ());
m_textWriter.Write (header.Age);
m_textWriter.Write (Encoding.ASCII.GetBytes (header.FileName));
m_textWriter.Write ((byte) 0);
}
public override void VisitImportTable (ImportTable it)
{
m_textWriter.BaseStream.Position = m_mdWriter.ImportTablePosition;
m_textWriter.Write (it.ImportLookupTable.Value);
m_textWriter.Write (it.DateTimeStamp);
m_textWriter.Write (it.ForwardChain);
m_textWriter.Write (it.Name.Value);
m_textWriter.Write (it.ImportAddressTable.Value);
m_textWriter.Write (new byte [20]);
}
public override void VisitImportLookupTable (ImportLookupTable ilt)
{
m_textWriter.Write (ilt.HintNameRVA.Value);
m_textWriter.Write (new byte [16]);
}
public override void VisitHintNameTable (HintNameTable hnt)
{
m_textWriter.Write (hnt.Hint);
m_textWriter.Write (Encoding.ASCII.GetBytes (hnt.RuntimeMain));
m_textWriter.Write ('\0');
m_textWriter.Write (Encoding.ASCII.GetBytes (hnt.RuntimeLibrary));
m_textWriter.Write ('\0');
m_textWriter.Write (new byte [4]);
// patch header with ep rva
RVA ep = m_img.TextSection.VirtualAddress +
(uint) m_textWriter.BaseStream.Position;
long pos = m_binaryWriter.BaseStream.Position;
m_binaryWriter.BaseStream.Position = 0xa8;
m_binaryWriter.Write (ep.Value);
m_binaryWriter.BaseStream.Position = pos;
// patch reloc Sect with ep
uint reloc = (ep.Value + 2) % 0x1000;
uint rva = (ep.Value + 2) - reloc;
m_relocWriter.BaseStream.Position = 0;
m_relocWriter.Write (rva);
m_relocWriter.BaseStream.Position = 8;
m_relocWriter.Write ((ushort) ((3 << 12) | reloc));
m_textWriter.Write (hnt.EntryPoint);
m_textWriter.Write (hnt.RVA);
}
public override void TerminateImage (Image img)
{
m_binaryWriter.BaseStream.Position = 0x200;
WriteSection (m_textSect, m_textWriter);
WriteSection (m_relocSect, m_relocWriter);
if (m_rsrcSect != null)
WriteSection (m_rsrcSect, m_rsrcWriter);
}
void WriteSection (Section sect, MemoryBinaryWriter sectWriter)
{
sectWriter.MemoryStream.WriteTo (m_binaryWriter.BaseStream);
m_binaryWriter.Write (new byte [
sect.SizeOfRawData - sectWriter.BaseStream.Length]);
}
}
}

Some files were not shown because too many files have changed in this diff Show More