[Add] FishNet
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
//
|
||||
// Author:
|
||||
// Jb Evain (jbevain@gmail.com)
|
||||
//
|
||||
// Copyright (c) 2008 - 2015 Jb Evain
|
||||
// Copyright (c) 2008 - 2011 Novell, Inc.
|
||||
//
|
||||
// Licensed under the MIT/X11 license.
|
||||
//
|
||||
|
||||
using System.IO;
|
||||
|
||||
namespace MonoFN.Cecil.PE
|
||||
{
|
||||
internal class BinaryStreamReader : BinaryReader
|
||||
{
|
||||
public int Position
|
||||
{
|
||||
get { return (int)BaseStream.Position; }
|
||||
set { BaseStream.Position = value; }
|
||||
}
|
||||
public int Length
|
||||
{
|
||||
get { return (int)BaseStream.Length; }
|
||||
}
|
||||
public BinaryStreamReader(Stream stream) : base(stream) { }
|
||||
|
||||
public void Advance(int bytes)
|
||||
{
|
||||
BaseStream.Seek(bytes, SeekOrigin.Current);
|
||||
}
|
||||
|
||||
public void MoveTo(uint position)
|
||||
{
|
||||
BaseStream.Seek(position, SeekOrigin.Begin);
|
||||
}
|
||||
|
||||
public void Align(int align)
|
||||
{
|
||||
align--;
|
||||
int position = Position;
|
||||
Advance(((position + align) & ~align) - position);
|
||||
}
|
||||
|
||||
public DataDirectory ReadDataDirectory()
|
||||
{
|
||||
return new(ReadUInt32(), ReadUInt32());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7492ed3a048237443b99d7a25e806ce6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 207815
|
||||
packageName: 'FishNet: Networking Evolved'
|
||||
packageVersion: 4.6.22R
|
||||
assetPath: Assets/FishNet/CodeGenerating/cecil-0.11.4/Mono.Cecil.PE/BinaryStreamReader.cs
|
||||
uploadId: 866910
|
||||
@@ -0,0 +1,85 @@
|
||||
//
|
||||
// Author:
|
||||
// Jb Evain (jbevain@gmail.com)
|
||||
//
|
||||
// Copyright (c) 2008 - 2015 Jb Evain
|
||||
// Copyright (c) 2008 - 2011 Novell, Inc.
|
||||
//
|
||||
// Licensed under the MIT/X11 license.
|
||||
//
|
||||
|
||||
using System.IO;
|
||||
|
||||
namespace MonoFN.Cecil.PE
|
||||
{
|
||||
internal class BinaryStreamWriter : BinaryWriter
|
||||
{
|
||||
public int Position
|
||||
{
|
||||
get { return (int)BaseStream.Position; }
|
||||
set { BaseStream.Position = value; }
|
||||
}
|
||||
public BinaryStreamWriter(Stream stream) : base(stream) { }
|
||||
|
||||
public void WriteByte(byte value)
|
||||
{
|
||||
Write(value);
|
||||
}
|
||||
|
||||
public void WriteUInt16(ushort value)
|
||||
{
|
||||
Write(value);
|
||||
}
|
||||
|
||||
public void WriteInt16(short value)
|
||||
{
|
||||
Write(value);
|
||||
}
|
||||
|
||||
public void WriteUInt32(uint value)
|
||||
{
|
||||
Write(value);
|
||||
}
|
||||
|
||||
public void WriteInt32(int value)
|
||||
{
|
||||
Write(value);
|
||||
}
|
||||
|
||||
public void WriteUInt64(ulong value)
|
||||
{
|
||||
Write(value);
|
||||
}
|
||||
|
||||
public void WriteBytes(byte[] bytes)
|
||||
{
|
||||
Write(bytes);
|
||||
}
|
||||
|
||||
public void WriteDataDirectory(DataDirectory directory)
|
||||
{
|
||||
Write(directory.VirtualAddress);
|
||||
Write(directory.Size);
|
||||
}
|
||||
|
||||
public void WriteBuffer(ByteBuffer buffer)
|
||||
{
|
||||
Write(buffer.buffer, 0, buffer.length);
|
||||
}
|
||||
|
||||
protected void Advance(int bytes)
|
||||
{
|
||||
BaseStream.Seek(bytes, SeekOrigin.Current);
|
||||
}
|
||||
|
||||
public void Align(int align)
|
||||
{
|
||||
align--;
|
||||
int position = Position;
|
||||
int bytes = ((position + align) & ~align) - position;
|
||||
|
||||
for (int i = 0; i < bytes; i++)
|
||||
WriteByte(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 26d384e0dd0e44549a9faf09adbd0a41
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 207815
|
||||
packageName: 'FishNet: Networking Evolved'
|
||||
packageVersion: 4.6.22R
|
||||
assetPath: Assets/FishNet/CodeGenerating/cecil-0.11.4/Mono.Cecil.PE/BinaryStreamWriter.cs
|
||||
uploadId: 866910
|
||||
@@ -0,0 +1,336 @@
|
||||
//
|
||||
// Author:
|
||||
// Jb Evain (jbevain@gmail.com)
|
||||
//
|
||||
// Copyright (c) 2008 - 2015 Jb Evain
|
||||
// Copyright (c) 2008 - 2011 Novell, Inc.
|
||||
//
|
||||
// Licensed under the MIT/X11 license.
|
||||
//
|
||||
|
||||
using System;
|
||||
|
||||
namespace MonoFN.Cecil.PE
|
||||
{
|
||||
internal class ByteBuffer
|
||||
{
|
||||
internal byte[] buffer;
|
||||
internal int length;
|
||||
internal int position;
|
||||
|
||||
public ByteBuffer()
|
||||
{
|
||||
buffer = Empty<byte>.Array;
|
||||
}
|
||||
|
||||
public ByteBuffer(int length)
|
||||
{
|
||||
buffer = new byte [length];
|
||||
}
|
||||
|
||||
public ByteBuffer(byte[] buffer)
|
||||
{
|
||||
this.buffer = buffer ?? Empty<byte>.Array;
|
||||
length = this.buffer.Length;
|
||||
}
|
||||
|
||||
public void Advance(int length)
|
||||
{
|
||||
position += length;
|
||||
}
|
||||
|
||||
public byte ReadByte()
|
||||
{
|
||||
return buffer[position++];
|
||||
}
|
||||
|
||||
public sbyte ReadSByte()
|
||||
{
|
||||
return (sbyte)ReadByte();
|
||||
}
|
||||
|
||||
public byte[] ReadBytes(int length)
|
||||
{
|
||||
byte[] bytes = new byte [length];
|
||||
Buffer.BlockCopy(buffer, position, bytes, 0, length);
|
||||
position += length;
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public ushort ReadUInt16()
|
||||
{
|
||||
ushort value = (ushort)(buffer[position] | (buffer[position + 1] << 8));
|
||||
position += 2;
|
||||
return value;
|
||||
}
|
||||
|
||||
public short ReadInt16()
|
||||
{
|
||||
return (short)ReadUInt16();
|
||||
}
|
||||
|
||||
public uint ReadUInt32()
|
||||
{
|
||||
uint value = (uint)(buffer[position] | (buffer[position + 1] << 8) | (buffer[position + 2] << 16) | (buffer[position + 3] << 24));
|
||||
position += 4;
|
||||
return value;
|
||||
}
|
||||
|
||||
public int ReadInt32()
|
||||
{
|
||||
return (int)ReadUInt32();
|
||||
}
|
||||
|
||||
public ulong ReadUInt64()
|
||||
{
|
||||
uint low = ReadUInt32();
|
||||
uint high = ReadUInt32();
|
||||
|
||||
return ((ulong)high << 32) | low;
|
||||
}
|
||||
|
||||
public long ReadInt64()
|
||||
{
|
||||
return (long)ReadUInt64();
|
||||
}
|
||||
|
||||
public uint ReadCompressedUInt32()
|
||||
{
|
||||
byte first = ReadByte();
|
||||
if ((first & 0x80) == 0)
|
||||
return first;
|
||||
|
||||
if ((first & 0x40) == 0)
|
||||
return ((uint)(first & ~0x80) << 8) | ReadByte();
|
||||
|
||||
return ((uint)(first & ~0xc0) << 24) | ((uint)ReadByte() << 16) | ((uint)ReadByte() << 8) | ReadByte();
|
||||
}
|
||||
|
||||
public int ReadCompressedInt32()
|
||||
{
|
||||
byte b = buffer[position];
|
||||
int u = (int)ReadCompressedUInt32();
|
||||
int v = u >> 1;
|
||||
if ((u & 1) == 0)
|
||||
return v;
|
||||
|
||||
switch (b & 0xc0)
|
||||
{
|
||||
case 0:
|
||||
case 0x40:
|
||||
return v - 0x40;
|
||||
case 0x80:
|
||||
return v - 0x2000;
|
||||
default:
|
||||
return v - 0x10000000;
|
||||
}
|
||||
}
|
||||
|
||||
public float ReadSingle()
|
||||
{
|
||||
if (!BitConverter.IsLittleEndian)
|
||||
{
|
||||
byte[] bytes = ReadBytes(4);
|
||||
Array.Reverse(bytes);
|
||||
return BitConverter.ToSingle(bytes, 0);
|
||||
}
|
||||
|
||||
float value = BitConverter.ToSingle(buffer, position);
|
||||
position += 4;
|
||||
return value;
|
||||
}
|
||||
|
||||
public double ReadDouble()
|
||||
{
|
||||
if (!BitConverter.IsLittleEndian)
|
||||
{
|
||||
byte[] bytes = ReadBytes(8);
|
||||
Array.Reverse(bytes);
|
||||
return BitConverter.ToDouble(bytes, 0);
|
||||
}
|
||||
|
||||
double value = BitConverter.ToDouble(buffer, position);
|
||||
position += 8;
|
||||
return value;
|
||||
}
|
||||
|
||||
public void WriteByte(byte value)
|
||||
{
|
||||
if (position == buffer.Length)
|
||||
Grow(1);
|
||||
|
||||
buffer[position++] = value;
|
||||
|
||||
if (position > length)
|
||||
length = position;
|
||||
}
|
||||
|
||||
public void WriteSByte(sbyte value)
|
||||
{
|
||||
WriteByte((byte)value);
|
||||
}
|
||||
|
||||
public void WriteUInt16(ushort value)
|
||||
{
|
||||
if (position + 2 > buffer.Length)
|
||||
Grow(2);
|
||||
|
||||
buffer[position++] = (byte)value;
|
||||
buffer[position++] = (byte)(value >> 8);
|
||||
|
||||
if (position > length)
|
||||
length = position;
|
||||
}
|
||||
|
||||
public void WriteInt16(short value)
|
||||
{
|
||||
WriteUInt16((ushort)value);
|
||||
}
|
||||
|
||||
public void WriteUInt32(uint value)
|
||||
{
|
||||
if (position + 4 > buffer.Length)
|
||||
Grow(4);
|
||||
|
||||
buffer[position++] = (byte)value;
|
||||
buffer[position++] = (byte)(value >> 8);
|
||||
buffer[position++] = (byte)(value >> 16);
|
||||
buffer[position++] = (byte)(value >> 24);
|
||||
|
||||
if (position > length)
|
||||
length = position;
|
||||
}
|
||||
|
||||
public void WriteInt32(int value)
|
||||
{
|
||||
WriteUInt32((uint)value);
|
||||
}
|
||||
|
||||
public void WriteUInt64(ulong value)
|
||||
{
|
||||
if (position + 8 > buffer.Length)
|
||||
Grow(8);
|
||||
|
||||
buffer[position++] = (byte)value;
|
||||
buffer[position++] = (byte)(value >> 8);
|
||||
buffer[position++] = (byte)(value >> 16);
|
||||
buffer[position++] = (byte)(value >> 24);
|
||||
buffer[position++] = (byte)(value >> 32);
|
||||
buffer[position++] = (byte)(value >> 40);
|
||||
buffer[position++] = (byte)(value >> 48);
|
||||
buffer[position++] = (byte)(value >> 56);
|
||||
|
||||
if (position > length)
|
||||
length = position;
|
||||
}
|
||||
|
||||
public void WriteInt64(long value)
|
||||
{
|
||||
WriteUInt64((ulong)value);
|
||||
}
|
||||
|
||||
public void WriteCompressedUInt32(uint value)
|
||||
{
|
||||
if (value < 0x80)
|
||||
{
|
||||
WriteByte((byte)value);
|
||||
}
|
||||
else if (value < 0x4000)
|
||||
{
|
||||
WriteByte((byte)(0x80 | (value >> 8)));
|
||||
WriteByte((byte)(value & 0xff));
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteByte((byte)((value >> 24) | 0xc0));
|
||||
WriteByte((byte)((value >> 16) & 0xff));
|
||||
WriteByte((byte)((value >> 8) & 0xff));
|
||||
WriteByte((byte)(value & 0xff));
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteCompressedInt32(int value)
|
||||
{
|
||||
if (value >= 0)
|
||||
{
|
||||
WriteCompressedUInt32((uint)(value << 1));
|
||||
return;
|
||||
}
|
||||
|
||||
if (value > -0x40)
|
||||
value = 0x40 + value;
|
||||
else if (value >= -0x2000)
|
||||
value = 0x2000 + value;
|
||||
else if (value >= -0x20000000)
|
||||
value = 0x20000000 + value;
|
||||
|
||||
WriteCompressedUInt32((uint)((value << 1) | 1));
|
||||
}
|
||||
|
||||
public void WriteBytes(byte[] bytes)
|
||||
{
|
||||
int length = bytes.Length;
|
||||
if (position + length > buffer.Length)
|
||||
Grow(length);
|
||||
|
||||
Buffer.BlockCopy(bytes, 0, buffer, position, length);
|
||||
position += length;
|
||||
|
||||
if (position > this.length)
|
||||
this.length = position;
|
||||
}
|
||||
|
||||
public void WriteBytes(int length)
|
||||
{
|
||||
if (position + length > buffer.Length)
|
||||
Grow(length);
|
||||
|
||||
position += length;
|
||||
|
||||
if (position > this.length)
|
||||
this.length = position;
|
||||
}
|
||||
|
||||
public void WriteBytes(ByteBuffer buffer)
|
||||
{
|
||||
if (position + buffer.length > this.buffer.Length)
|
||||
Grow(buffer.length);
|
||||
|
||||
Buffer.BlockCopy(buffer.buffer, 0, this.buffer, position, buffer.length);
|
||||
position += buffer.length;
|
||||
|
||||
if (position > length)
|
||||
length = position;
|
||||
}
|
||||
|
||||
public void WriteSingle(float value)
|
||||
{
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
|
||||
if (!BitConverter.IsLittleEndian)
|
||||
Array.Reverse(bytes);
|
||||
|
||||
WriteBytes(bytes);
|
||||
}
|
||||
|
||||
public void WriteDouble(double value)
|
||||
{
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
|
||||
if (!BitConverter.IsLittleEndian)
|
||||
Array.Reverse(bytes);
|
||||
|
||||
WriteBytes(bytes);
|
||||
}
|
||||
|
||||
private void Grow(int desired)
|
||||
{
|
||||
byte[] current = this.buffer;
|
||||
int current_length = current.Length;
|
||||
|
||||
byte[] buffer = new byte [Math.Max(current_length + desired, current_length * 2)];
|
||||
Buffer.BlockCopy(current, 0, buffer, 0, current_length);
|
||||
this.buffer = buffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3752816249ea16e4aba70adb03f01673
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 207815
|
||||
packageName: 'FishNet: Networking Evolved'
|
||||
packageVersion: 4.6.22R
|
||||
assetPath: Assets/FishNet/CodeGenerating/cecil-0.11.4/Mono.Cecil.PE/ByteBuffer.cs
|
||||
uploadId: 866910
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
//
|
||||
// Author:
|
||||
// Jb Evain (jbevain@gmail.com)
|
||||
//
|
||||
// Copyright (c) 2008 - 2015 Jb Evain
|
||||
// Copyright (c) 2008 - 2011 Novell, Inc.
|
||||
//
|
||||
// Licensed under the MIT/X11 license.
|
||||
//
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MonoFN.Cecil.PE
|
||||
{
|
||||
internal sealed class ByteBufferEqualityComparer : IEqualityComparer<ByteBuffer>
|
||||
{
|
||||
public bool Equals(ByteBuffer x, ByteBuffer y)
|
||||
{
|
||||
if (x.length != y.length)
|
||||
return false;
|
||||
|
||||
byte[] x_buffer = x.buffer;
|
||||
byte[] y_buffer = y.buffer;
|
||||
|
||||
for (int i = 0; i < x.length; i++)
|
||||
if (x_buffer[i] != y_buffer[i])
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public int GetHashCode(ByteBuffer buffer)
|
||||
{
|
||||
// See http://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
|
||||
const int fnv_offset_bias = unchecked((int)2166136261);
|
||||
const int fnv_prime = 16777619;
|
||||
|
||||
int hash_code = fnv_offset_bias;
|
||||
byte[] bytes = buffer.buffer;
|
||||
|
||||
for (int i = 0; i < buffer.length; i++)
|
||||
hash_code = unchecked((hash_code ^ bytes[i]) * fnv_prime);
|
||||
|
||||
return hash_code;
|
||||
}
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0db5f2f7f9a349d4d89e2329ffd563b2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 207815
|
||||
packageName: 'FishNet: Networking Evolved'
|
||||
packageVersion: 4.6.22R
|
||||
assetPath: Assets/FishNet/CodeGenerating/cecil-0.11.4/Mono.Cecil.PE/ByteBufferEqualityComparer.cs
|
||||
uploadId: 866910
|
||||
@@ -0,0 +1,30 @@
|
||||
//
|
||||
// Author:
|
||||
// Jb Evain (jbevain@gmail.com)
|
||||
//
|
||||
// Copyright (c) 2008 - 2015 Jb Evain
|
||||
// Copyright (c) 2008 - 2011 Novell, Inc.
|
||||
//
|
||||
// Licensed under the MIT/X11 license.
|
||||
//
|
||||
|
||||
using RVA = System.UInt32;
|
||||
|
||||
namespace MonoFN.Cecil.PE
|
||||
{
|
||||
internal struct DataDirectory
|
||||
{
|
||||
public readonly RVA VirtualAddress;
|
||||
public readonly uint Size;
|
||||
public bool IsZero
|
||||
{
|
||||
get { return VirtualAddress == 0 && Size == 0; }
|
||||
}
|
||||
|
||||
public DataDirectory(RVA rva, uint size)
|
||||
{
|
||||
VirtualAddress = rva;
|
||||
Size = size;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7cd272a7ff953734bbacab398dfc9fe8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 207815
|
||||
packageName: 'FishNet: Networking Evolved'
|
||||
packageVersion: 4.6.22R
|
||||
assetPath: Assets/FishNet/CodeGenerating/cecil-0.11.4/Mono.Cecil.PE/DataDirectory.cs
|
||||
uploadId: 866910
|
||||
@@ -0,0 +1,158 @@
|
||||
//
|
||||
// Author:
|
||||
// Jb Evain (jbevain@gmail.com)
|
||||
//
|
||||
// Copyright (c) 2008 - 2015 Jb Evain
|
||||
// Copyright (c) 2008 - 2011 Novell, Inc.
|
||||
//
|
||||
// Licensed under the MIT/X11 license.
|
||||
//
|
||||
|
||||
using MonoFN.Cecil.Cil;
|
||||
using MonoFN.Cecil.Metadata;
|
||||
using System;
|
||||
using System.IO;
|
||||
using RVA = System.UInt32;
|
||||
|
||||
namespace MonoFN.Cecil.PE
|
||||
{
|
||||
internal sealed class Image : IDisposable
|
||||
{
|
||||
public Disposable<Stream> Stream;
|
||||
public string FileName;
|
||||
public ModuleKind Kind;
|
||||
public uint Characteristics;
|
||||
public string RuntimeVersion;
|
||||
public TargetArchitecture Architecture;
|
||||
public ModuleCharacteristics DllCharacteristics;
|
||||
public ushort LinkerVersion;
|
||||
public ushort SubSystemMajor;
|
||||
public ushort SubSystemMinor;
|
||||
public ImageDebugHeader DebugHeader;
|
||||
public Section[] Sections;
|
||||
public Section MetadataSection;
|
||||
public uint EntryPointToken;
|
||||
public uint Timestamp;
|
||||
public ModuleAttributes Attributes;
|
||||
public DataDirectory Win32Resources;
|
||||
public DataDirectory Debug;
|
||||
public DataDirectory Resources;
|
||||
public DataDirectory StrongName;
|
||||
public StringHeap StringHeap;
|
||||
public BlobHeap BlobHeap;
|
||||
public UserStringHeap UserStringHeap;
|
||||
public GuidHeap GuidHeap;
|
||||
public TableHeap TableHeap;
|
||||
public PdbHeap PdbHeap;
|
||||
private readonly int[] coded_index_sizes = new int [14];
|
||||
private readonly Func<Table, int> counter;
|
||||
|
||||
public Image()
|
||||
{
|
||||
counter = GetTableLength;
|
||||
}
|
||||
|
||||
public bool HasTable(Table table)
|
||||
{
|
||||
return GetTableLength(table) > 0;
|
||||
}
|
||||
|
||||
public int GetTableLength(Table table)
|
||||
{
|
||||
return (int)TableHeap[table].Length;
|
||||
}
|
||||
|
||||
public int GetTableIndexSize(Table table)
|
||||
{
|
||||
return GetTableLength(table) < 65536 ? 2 : 4;
|
||||
}
|
||||
|
||||
public int GetCodedIndexSize(CodedIndex coded_index)
|
||||
{
|
||||
int index = (int)coded_index;
|
||||
int size = coded_index_sizes[index];
|
||||
if (size != 0)
|
||||
return size;
|
||||
|
||||
return coded_index_sizes[index] = coded_index.GetSize(counter);
|
||||
}
|
||||
|
||||
public uint ResolveVirtualAddress(RVA rva)
|
||||
{
|
||||
Section section = GetSectionAtVirtualAddress(rva);
|
||||
if (section == null)
|
||||
throw new ArgumentOutOfRangeException();
|
||||
|
||||
return ResolveVirtualAddressInSection(rva, section);
|
||||
}
|
||||
|
||||
public uint ResolveVirtualAddressInSection(RVA rva, Section section)
|
||||
{
|
||||
return rva + section.PointerToRawData - section.VirtualAddress;
|
||||
}
|
||||
|
||||
public Section GetSection(string name)
|
||||
{
|
||||
Section[] sections = Sections;
|
||||
for (int i = 0; i < sections.Length; i++)
|
||||
{
|
||||
Section section = sections[i];
|
||||
if (section.Name == name)
|
||||
return section;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public Section GetSectionAtVirtualAddress(RVA rva)
|
||||
{
|
||||
Section[] sections = Sections;
|
||||
for (int i = 0; i < sections.Length; i++)
|
||||
{
|
||||
Section section = sections[i];
|
||||
if (rva >= section.VirtualAddress && rva < section.VirtualAddress + section.SizeOfRawData)
|
||||
return section;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private BinaryStreamReader GetReaderAt(RVA rva)
|
||||
{
|
||||
Section section = GetSectionAtVirtualAddress(rva);
|
||||
if (section == null)
|
||||
return null;
|
||||
|
||||
BinaryStreamReader reader = new(Stream.value);
|
||||
reader.MoveTo(ResolveVirtualAddressInSection(rva, section));
|
||||
return reader;
|
||||
}
|
||||
|
||||
public TRet GetReaderAt<TItem, TRet>(RVA rva, TItem item, Func<TItem, BinaryStreamReader, TRet> read) where TRet : class
|
||||
{
|
||||
long position = Stream.value.Position;
|
||||
try
|
||||
{
|
||||
BinaryStreamReader reader = GetReaderAt(rva);
|
||||
if (reader == null)
|
||||
return null;
|
||||
|
||||
return read(item, reader);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Stream.value.Position = position;
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasDebugTables()
|
||||
{
|
||||
return HasTable(Table.Document) || HasTable(Table.MethodDebugInformation) || HasTable(Table.LocalScope) || HasTable(Table.LocalVariable) || HasTable(Table.LocalConstant) || HasTable(Table.StateMachineMethod) || HasTable(Table.CustomDebugInformation);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Stream.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: be7f3ca6a9f5ad34db68702bd99778fd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 207815
|
||||
packageName: 'FishNet: Networking Evolved'
|
||||
packageVersion: 4.6.22R
|
||||
assetPath: Assets/FishNet/CodeGenerating/cecil-0.11.4/Mono.Cecil.PE/Image.cs
|
||||
uploadId: 866910
|
||||
@@ -0,0 +1,812 @@
|
||||
//
|
||||
// Author:
|
||||
// Jb Evain (jbevain@gmail.com)
|
||||
//
|
||||
// Copyright (c) 2008 - 2015 Jb Evain
|
||||
// Copyright (c) 2008 - 2011 Novell, Inc.
|
||||
//
|
||||
// Licensed under the MIT/X11 license.
|
||||
//
|
||||
|
||||
using MonoFN.Cecil.Cil;
|
||||
using MonoFN.Cecil.Metadata;
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace MonoFN.Cecil.PE
|
||||
{
|
||||
internal sealed class ImageReader : BinaryStreamReader
|
||||
{
|
||||
private readonly Image image;
|
||||
private DataDirectory cli;
|
||||
private DataDirectory metadata;
|
||||
private uint table_heap_offset;
|
||||
|
||||
public ImageReader(Disposable<Stream> stream, string file_name) : base(stream.value)
|
||||
{
|
||||
image = new();
|
||||
image.Stream = stream;
|
||||
image.FileName = file_name;
|
||||
}
|
||||
|
||||
private void MoveTo(DataDirectory directory)
|
||||
{
|
||||
BaseStream.Position = image.ResolveVirtualAddress(directory.VirtualAddress);
|
||||
}
|
||||
|
||||
private void ReadImage()
|
||||
{
|
||||
if (BaseStream.Length < 128)
|
||||
throw new BadImageFormatException();
|
||||
|
||||
// - DOSHeader
|
||||
|
||||
// PE 2
|
||||
// Start 58
|
||||
// Lfanew 4
|
||||
// End 64
|
||||
|
||||
if (ReadUInt16() != 0x5a4d)
|
||||
throw new BadImageFormatException();
|
||||
|
||||
Advance(58);
|
||||
|
||||
MoveTo(ReadUInt32());
|
||||
|
||||
if (ReadUInt32() != 0x00004550)
|
||||
throw new BadImageFormatException();
|
||||
|
||||
// - PEFileHeader
|
||||
|
||||
// Machine 2
|
||||
image.Architecture = ReadArchitecture();
|
||||
|
||||
// NumberOfSections 2
|
||||
ushort sections = ReadUInt16();
|
||||
|
||||
// TimeDateStamp 4
|
||||
image.Timestamp = ReadUInt32();
|
||||
// PointerToSymbolTable 4
|
||||
// NumberOfSymbols 4
|
||||
// OptionalHeaderSize 2
|
||||
Advance(10);
|
||||
|
||||
// Characteristics 2
|
||||
ushort characteristics = ReadUInt16();
|
||||
|
||||
ushort subsystem, dll_characteristics;
|
||||
ReadOptionalHeaders(out subsystem, out dll_characteristics);
|
||||
ReadSections(sections);
|
||||
ReadCLIHeader();
|
||||
ReadMetadata();
|
||||
ReadDebugHeader();
|
||||
|
||||
image.Characteristics = characteristics;
|
||||
image.Kind = GetModuleKind(characteristics, subsystem);
|
||||
image.DllCharacteristics = (ModuleCharacteristics)dll_characteristics;
|
||||
}
|
||||
|
||||
private TargetArchitecture ReadArchitecture()
|
||||
{
|
||||
return (TargetArchitecture)ReadUInt16();
|
||||
}
|
||||
|
||||
private static ModuleKind GetModuleKind(ushort characteristics, ushort subsystem)
|
||||
{
|
||||
if ((characteristics & 0x2000) != 0) // ImageCharacteristics.Dll
|
||||
return ModuleKind.Dll;
|
||||
|
||||
if (subsystem == 0x2 || subsystem == 0x9) // SubSystem.WindowsGui || SubSystem.WindowsCeGui
|
||||
return ModuleKind.Windows;
|
||||
|
||||
return ModuleKind.Console;
|
||||
}
|
||||
|
||||
private void ReadOptionalHeaders(out ushort subsystem, out ushort dll_characteristics)
|
||||
{
|
||||
// - PEOptionalHeader
|
||||
// - StandardFieldsHeader
|
||||
|
||||
// Magic 2
|
||||
bool pe64 = ReadUInt16() == 0x20b;
|
||||
|
||||
// pe32 || pe64
|
||||
|
||||
image.LinkerVersion = ReadUInt16();
|
||||
// CodeSize 4
|
||||
// InitializedDataSize 4
|
||||
// UninitializedDataSize4
|
||||
// EntryPointRVA 4
|
||||
// BaseOfCode 4
|
||||
// BaseOfData 4 || 0
|
||||
|
||||
// - NTSpecificFieldsHeader
|
||||
|
||||
// ImageBase 4 || 8
|
||||
// SectionAlignment 4
|
||||
// FileAlignement 4
|
||||
// OSMajor 2
|
||||
// OSMinor 2
|
||||
// UserMajor 2
|
||||
// UserMinor 2
|
||||
// SubSysMajor 2
|
||||
// SubSysMinor 2
|
||||
Advance(44);
|
||||
|
||||
image.SubSystemMajor = ReadUInt16();
|
||||
image.SubSystemMinor = ReadUInt16();
|
||||
|
||||
// Reserved 4
|
||||
// ImageSize 4
|
||||
// HeaderSize 4
|
||||
// FileChecksum 4
|
||||
Advance(16);
|
||||
|
||||
// SubSystem 2
|
||||
subsystem = ReadUInt16();
|
||||
|
||||
// DLLFlags 2
|
||||
dll_characteristics = ReadUInt16();
|
||||
// StackReserveSize 4 || 8
|
||||
// StackCommitSize 4 || 8
|
||||
// HeapReserveSize 4 || 8
|
||||
// HeapCommitSize 4 || 8
|
||||
// LoaderFlags 4
|
||||
// NumberOfDataDir 4
|
||||
|
||||
// - DataDirectoriesHeader
|
||||
|
||||
// ExportTable 8
|
||||
// ImportTable 8
|
||||
|
||||
Advance(pe64 ? 56 : 40);
|
||||
|
||||
// ResourceTable 8
|
||||
|
||||
image.Win32Resources = ReadDataDirectory();
|
||||
|
||||
// ExceptionTable 8
|
||||
// CertificateTable 8
|
||||
// BaseRelocationTable 8
|
||||
|
||||
Advance(24);
|
||||
|
||||
// Debug 8
|
||||
image.Debug = ReadDataDirectory();
|
||||
|
||||
// Copyright 8
|
||||
// GlobalPtr 8
|
||||
// TLSTable 8
|
||||
// LoadConfigTable 8
|
||||
// BoundImport 8
|
||||
// IAT 8
|
||||
// DelayImportDescriptor8
|
||||
Advance(56);
|
||||
|
||||
// CLIHeader 8
|
||||
cli = ReadDataDirectory();
|
||||
|
||||
if (cli.IsZero)
|
||||
throw new BadImageFormatException();
|
||||
|
||||
// Reserved 8
|
||||
Advance(8);
|
||||
}
|
||||
|
||||
private string ReadAlignedString(int length)
|
||||
{
|
||||
int read = 0;
|
||||
char[] buffer = new char [length];
|
||||
while (read < length)
|
||||
{
|
||||
byte current = ReadByte();
|
||||
if (current == 0)
|
||||
break;
|
||||
|
||||
buffer[read++] = (char)current;
|
||||
}
|
||||
|
||||
Advance(-1 + ((read + 4) & ~3) - read);
|
||||
|
||||
return new(buffer, 0, read);
|
||||
}
|
||||
|
||||
private string ReadZeroTerminatedString(int length)
|
||||
{
|
||||
int read = 0;
|
||||
char[] buffer = new char [length];
|
||||
byte[] bytes = ReadBytes(length);
|
||||
while (read < length)
|
||||
{
|
||||
byte current = bytes[read];
|
||||
if (current == 0)
|
||||
break;
|
||||
|
||||
buffer[read++] = (char)current;
|
||||
}
|
||||
|
||||
return new(buffer, 0, read);
|
||||
}
|
||||
|
||||
private void ReadSections(ushort count)
|
||||
{
|
||||
Section[] sections = new Section [count];
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
Section section = new();
|
||||
|
||||
// Name
|
||||
section.Name = ReadZeroTerminatedString(8);
|
||||
|
||||
// VirtualSize 4
|
||||
Advance(4);
|
||||
|
||||
// VirtualAddress 4
|
||||
section.VirtualAddress = ReadUInt32();
|
||||
// SizeOfRawData 4
|
||||
section.SizeOfRawData = ReadUInt32();
|
||||
// PointerToRawData 4
|
||||
section.PointerToRawData = ReadUInt32();
|
||||
|
||||
// PointerToRelocations 4
|
||||
// PointerToLineNumbers 4
|
||||
// NumberOfRelocations 2
|
||||
// NumberOfLineNumbers 2
|
||||
// Characteristics 4
|
||||
Advance(16);
|
||||
|
||||
sections[i] = section;
|
||||
}
|
||||
|
||||
image.Sections = sections;
|
||||
}
|
||||
|
||||
private void ReadCLIHeader()
|
||||
{
|
||||
MoveTo(cli);
|
||||
|
||||
// - CLIHeader
|
||||
|
||||
// Cb 4
|
||||
// MajorRuntimeVersion 2
|
||||
// MinorRuntimeVersion 2
|
||||
Advance(8);
|
||||
|
||||
// Metadata 8
|
||||
metadata = ReadDataDirectory();
|
||||
// Flags 4
|
||||
image.Attributes = (ModuleAttributes)ReadUInt32();
|
||||
// EntryPointToken 4
|
||||
image.EntryPointToken = ReadUInt32();
|
||||
// Resources 8
|
||||
image.Resources = ReadDataDirectory();
|
||||
// StrongNameSignature 8
|
||||
image.StrongName = ReadDataDirectory();
|
||||
// CodeManagerTable 8
|
||||
// VTableFixups 8
|
||||
// ExportAddressTableJumps 8
|
||||
// ManagedNativeHeader 8
|
||||
}
|
||||
|
||||
private void ReadMetadata()
|
||||
{
|
||||
MoveTo(metadata);
|
||||
|
||||
if (ReadUInt32() != 0x424a5342)
|
||||
throw new BadImageFormatException();
|
||||
|
||||
// MajorVersion 2
|
||||
// MinorVersion 2
|
||||
// Reserved 4
|
||||
Advance(8);
|
||||
|
||||
image.RuntimeVersion = ReadZeroTerminatedString(ReadInt32());
|
||||
|
||||
// Flags 2
|
||||
Advance(2);
|
||||
|
||||
ushort streams = ReadUInt16();
|
||||
|
||||
Section section = image.GetSectionAtVirtualAddress(metadata.VirtualAddress);
|
||||
if (section == null)
|
||||
throw new BadImageFormatException();
|
||||
|
||||
image.MetadataSection = section;
|
||||
|
||||
for (int i = 0; i < streams; i++)
|
||||
ReadMetadataStream(section);
|
||||
|
||||
if (image.PdbHeap != null)
|
||||
ReadPdbHeap();
|
||||
|
||||
if (image.TableHeap != null)
|
||||
ReadTableHeap();
|
||||
}
|
||||
|
||||
private void ReadDebugHeader()
|
||||
{
|
||||
if (image.Debug.IsZero)
|
||||
{
|
||||
image.DebugHeader = new(Empty<ImageDebugHeaderEntry>.Array);
|
||||
return;
|
||||
}
|
||||
|
||||
MoveTo(image.Debug);
|
||||
|
||||
ImageDebugHeaderEntry[] entries = new ImageDebugHeaderEntry [(int)image.Debug.Size / ImageDebugDirectory.Size];
|
||||
|
||||
for (int i = 0; i < entries.Length; i++)
|
||||
{
|
||||
ImageDebugDirectory directory = new()
|
||||
{
|
||||
Characteristics = ReadInt32(),
|
||||
TimeDateStamp = ReadInt32(),
|
||||
MajorVersion = ReadInt16(),
|
||||
MinorVersion = ReadInt16(),
|
||||
Type = (ImageDebugType)ReadInt32(),
|
||||
SizeOfData = ReadInt32(),
|
||||
AddressOfRawData = ReadInt32(),
|
||||
PointerToRawData = ReadInt32()
|
||||
};
|
||||
|
||||
if (directory.PointerToRawData == 0 || directory.SizeOfData < 0)
|
||||
{
|
||||
entries[i] = new(directory, Empty<byte>.Array);
|
||||
continue;
|
||||
}
|
||||
|
||||
int position = Position;
|
||||
try
|
||||
{
|
||||
MoveTo((uint)directory.PointerToRawData);
|
||||
byte[] data = ReadBytes(directory.SizeOfData);
|
||||
entries[i] = new(directory, data);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Position = position;
|
||||
}
|
||||
}
|
||||
|
||||
image.DebugHeader = new(entries);
|
||||
}
|
||||
|
||||
private void ReadMetadataStream(Section section)
|
||||
{
|
||||
// Offset 4
|
||||
uint offset = metadata.VirtualAddress - section.VirtualAddress + ReadUInt32(); // relative to the section start
|
||||
|
||||
// Size 4
|
||||
uint size = ReadUInt32();
|
||||
|
||||
byte[] data = ReadHeapData(offset, size);
|
||||
|
||||
string name = ReadAlignedString(16);
|
||||
switch (name)
|
||||
{
|
||||
case "#~":
|
||||
case "#-":
|
||||
image.TableHeap = new(data);
|
||||
table_heap_offset = offset;
|
||||
break;
|
||||
case "#Strings":
|
||||
image.StringHeap = new(data);
|
||||
break;
|
||||
case "#Blob":
|
||||
image.BlobHeap = new(data);
|
||||
break;
|
||||
case "#GUID":
|
||||
image.GuidHeap = new(data);
|
||||
break;
|
||||
case "#US":
|
||||
image.UserStringHeap = new(data);
|
||||
break;
|
||||
case "#Pdb":
|
||||
image.PdbHeap = new(data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] ReadHeapData(uint offset, uint size)
|
||||
{
|
||||
long position = BaseStream.Position;
|
||||
MoveTo(offset + image.MetadataSection.PointerToRawData);
|
||||
byte[] data = ReadBytes((int)size);
|
||||
BaseStream.Position = position;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
private void ReadTableHeap()
|
||||
{
|
||||
TableHeap heap = image.TableHeap;
|
||||
|
||||
MoveTo(table_heap_offset + image.MetadataSection.PointerToRawData);
|
||||
|
||||
// Reserved 4
|
||||
// MajorVersion 1
|
||||
// MinorVersion 1
|
||||
Advance(6);
|
||||
|
||||
// HeapSizes 1
|
||||
byte sizes = ReadByte();
|
||||
|
||||
// Reserved2 1
|
||||
Advance(1);
|
||||
|
||||
// Valid 8
|
||||
heap.Valid = ReadInt64();
|
||||
|
||||
// Sorted 8
|
||||
heap.Sorted = ReadInt64();
|
||||
|
||||
if (image.PdbHeap != null)
|
||||
{
|
||||
for (int i = 0; i < Mixin.TableCount; i++)
|
||||
{
|
||||
if (!image.PdbHeap.HasTable((Table)i))
|
||||
continue;
|
||||
|
||||
heap.Tables[i].Length = image.PdbHeap.TypeSystemTableRows[i];
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < Mixin.TableCount; i++)
|
||||
{
|
||||
if (!heap.HasTable((Table)i))
|
||||
continue;
|
||||
|
||||
heap.Tables[i].Length = ReadUInt32();
|
||||
}
|
||||
|
||||
SetIndexSize(image.StringHeap, sizes, 0x1);
|
||||
SetIndexSize(image.GuidHeap, sizes, 0x2);
|
||||
SetIndexSize(image.BlobHeap, sizes, 0x4);
|
||||
|
||||
ComputeTableInformations();
|
||||
}
|
||||
|
||||
private static void SetIndexSize(Heap heap, uint sizes, byte flag)
|
||||
{
|
||||
if (heap == null)
|
||||
return;
|
||||
|
||||
heap.IndexSize = (sizes & flag) > 0 ? 4 : 2;
|
||||
}
|
||||
|
||||
private int GetTableIndexSize(Table table)
|
||||
{
|
||||
return image.GetTableIndexSize(table);
|
||||
}
|
||||
|
||||
private int GetCodedIndexSize(CodedIndex index)
|
||||
{
|
||||
return image.GetCodedIndexSize(index);
|
||||
}
|
||||
|
||||
private void ComputeTableInformations()
|
||||
{
|
||||
uint offset = (uint)BaseStream.Position - table_heap_offset - image.MetadataSection.PointerToRawData; // header
|
||||
|
||||
int stridx_size = image.StringHeap != null ? image.StringHeap.IndexSize : 2;
|
||||
int guididx_size = image.GuidHeap != null ? image.GuidHeap.IndexSize : 2;
|
||||
int blobidx_size = image.BlobHeap != null ? image.BlobHeap.IndexSize : 2;
|
||||
|
||||
TableHeap heap = image.TableHeap;
|
||||
TableInformation[] tables = heap.Tables;
|
||||
|
||||
for (int i = 0; i < Mixin.TableCount; i++)
|
||||
{
|
||||
Table table = (Table)i;
|
||||
if (!heap.HasTable(table))
|
||||
continue;
|
||||
|
||||
int size;
|
||||
switch (table)
|
||||
{
|
||||
case Table.Module:
|
||||
size = 2 // Generation
|
||||
+ stridx_size // Name
|
||||
+ guididx_size * 3; // Mvid, EncId, EncBaseId
|
||||
break;
|
||||
case Table.TypeRef:
|
||||
size = GetCodedIndexSize(CodedIndex.ResolutionScope) // ResolutionScope
|
||||
+ stridx_size * 2; // Name, Namespace
|
||||
break;
|
||||
case Table.TypeDef:
|
||||
size = 4 // Flags
|
||||
+ stridx_size * 2 // Name, Namespace
|
||||
+ GetCodedIndexSize(CodedIndex.TypeDefOrRef) // BaseType
|
||||
+ GetTableIndexSize(Table.Field) // FieldList
|
||||
+ GetTableIndexSize(Table.Method); // MethodList
|
||||
break;
|
||||
case Table.FieldPtr:
|
||||
size = GetTableIndexSize(Table.Field); // Field
|
||||
break;
|
||||
case Table.Field:
|
||||
size = 2 // Flags
|
||||
+ stridx_size // Name
|
||||
+ blobidx_size; // Signature
|
||||
break;
|
||||
case Table.MethodPtr:
|
||||
size = GetTableIndexSize(Table.Method); // Method
|
||||
break;
|
||||
case Table.Method:
|
||||
size = 8 // Rva 4, ImplFlags 2, Flags 2
|
||||
+ stridx_size // Name
|
||||
+ blobidx_size // Signature
|
||||
+ GetTableIndexSize(Table.Param); // ParamList
|
||||
break;
|
||||
case Table.ParamPtr:
|
||||
size = GetTableIndexSize(Table.Param); // Param
|
||||
break;
|
||||
case Table.Param:
|
||||
size = 4 // Flags 2, Sequence 2
|
||||
+ stridx_size; // Name
|
||||
break;
|
||||
case Table.InterfaceImpl:
|
||||
size = GetTableIndexSize(Table.TypeDef) // Class
|
||||
+ GetCodedIndexSize(CodedIndex.TypeDefOrRef); // Interface
|
||||
break;
|
||||
case Table.MemberRef:
|
||||
size = GetCodedIndexSize(CodedIndex.MemberRefParent) // Class
|
||||
+ stridx_size // Name
|
||||
+ blobidx_size; // Signature
|
||||
break;
|
||||
case Table.Constant:
|
||||
size = 2 // Type
|
||||
+ GetCodedIndexSize(CodedIndex.HasConstant) // Parent
|
||||
+ blobidx_size; // Value
|
||||
break;
|
||||
case Table.CustomAttribute:
|
||||
size = GetCodedIndexSize(CodedIndex.HasCustomAttribute) // Parent
|
||||
+ GetCodedIndexSize(CodedIndex.CustomAttributeType) // Type
|
||||
+ blobidx_size; // Value
|
||||
break;
|
||||
case Table.FieldMarshal:
|
||||
size = GetCodedIndexSize(CodedIndex.HasFieldMarshal) // Parent
|
||||
+ blobidx_size; // NativeType
|
||||
break;
|
||||
case Table.DeclSecurity:
|
||||
size = 2 // Action
|
||||
+ GetCodedIndexSize(CodedIndex.HasDeclSecurity) // Parent
|
||||
+ blobidx_size; // PermissionSet
|
||||
break;
|
||||
case Table.ClassLayout:
|
||||
size = 6 // PackingSize 2, ClassSize 4
|
||||
+ GetTableIndexSize(Table.TypeDef); // Parent
|
||||
break;
|
||||
case Table.FieldLayout:
|
||||
size = 4 // Offset
|
||||
+ GetTableIndexSize(Table.Field); // Field
|
||||
break;
|
||||
case Table.StandAloneSig:
|
||||
size = blobidx_size; // Signature
|
||||
break;
|
||||
case Table.EventMap:
|
||||
size = GetTableIndexSize(Table.TypeDef) // Parent
|
||||
+ GetTableIndexSize(Table.Event); // EventList
|
||||
break;
|
||||
case Table.EventPtr:
|
||||
size = GetTableIndexSize(Table.Event); // Event
|
||||
break;
|
||||
case Table.Event:
|
||||
size = 2 // Flags
|
||||
+ stridx_size // Name
|
||||
+ GetCodedIndexSize(CodedIndex.TypeDefOrRef); // EventType
|
||||
break;
|
||||
case Table.PropertyMap:
|
||||
size = GetTableIndexSize(Table.TypeDef) // Parent
|
||||
+ GetTableIndexSize(Table.Property); // PropertyList
|
||||
break;
|
||||
case Table.PropertyPtr:
|
||||
size = GetTableIndexSize(Table.Property); // Property
|
||||
break;
|
||||
case Table.Property:
|
||||
size = 2 // Flags
|
||||
+ stridx_size // Name
|
||||
+ blobidx_size; // Type
|
||||
break;
|
||||
case Table.MethodSemantics:
|
||||
size = 2 // Semantics
|
||||
+ GetTableIndexSize(Table.Method) // Method
|
||||
+ GetCodedIndexSize(CodedIndex.HasSemantics); // Association
|
||||
break;
|
||||
case Table.MethodImpl:
|
||||
size = GetTableIndexSize(Table.TypeDef) // Class
|
||||
+ GetCodedIndexSize(CodedIndex.MethodDefOrRef) // MethodBody
|
||||
+ GetCodedIndexSize(CodedIndex.MethodDefOrRef); // MethodDeclaration
|
||||
break;
|
||||
case Table.ModuleRef:
|
||||
size = stridx_size; // Name
|
||||
break;
|
||||
case Table.TypeSpec:
|
||||
size = blobidx_size; // Signature
|
||||
break;
|
||||
case Table.ImplMap:
|
||||
size = 2 // MappingFlags
|
||||
+ GetCodedIndexSize(CodedIndex.MemberForwarded) // MemberForwarded
|
||||
+ stridx_size // ImportName
|
||||
+ GetTableIndexSize(Table.ModuleRef); // ImportScope
|
||||
break;
|
||||
case Table.FieldRVA:
|
||||
size = 4 // RVA
|
||||
+ GetTableIndexSize(Table.Field); // Field
|
||||
break;
|
||||
case Table.EncLog:
|
||||
size = 8;
|
||||
break;
|
||||
case Table.EncMap:
|
||||
size = 4;
|
||||
break;
|
||||
case Table.Assembly:
|
||||
size = 16 // HashAlgId 4, Version 4 * 2, Flags 4
|
||||
+ blobidx_size // PublicKey
|
||||
+ stridx_size * 2; // Name, Culture
|
||||
break;
|
||||
case Table.AssemblyProcessor:
|
||||
size = 4; // Processor
|
||||
break;
|
||||
case Table.AssemblyOS:
|
||||
size = 12; // Platform 4, Version 2 * 4
|
||||
break;
|
||||
case Table.AssemblyRef:
|
||||
size = 12 // Version 2 * 4 + Flags 4
|
||||
+ blobidx_size * 2 // PublicKeyOrToken, HashValue
|
||||
+ stridx_size * 2; // Name, Culture
|
||||
break;
|
||||
case Table.AssemblyRefProcessor:
|
||||
size = 4 // Processor
|
||||
+ GetTableIndexSize(Table.AssemblyRef); // AssemblyRef
|
||||
break;
|
||||
case Table.AssemblyRefOS:
|
||||
size = 12 // Platform 4, Version 2 * 4
|
||||
+ GetTableIndexSize(Table.AssemblyRef); // AssemblyRef
|
||||
break;
|
||||
case Table.File:
|
||||
size = 4 // Flags
|
||||
+ stridx_size // Name
|
||||
+ blobidx_size; // HashValue
|
||||
break;
|
||||
case Table.ExportedType:
|
||||
size = 8 // Flags 4, TypeDefId 4
|
||||
+ stridx_size * 2 // Name, Namespace
|
||||
+ GetCodedIndexSize(CodedIndex.Implementation); // Implementation
|
||||
break;
|
||||
case Table.ManifestResource:
|
||||
size = 8 // Offset, Flags
|
||||
+ stridx_size // Name
|
||||
+ GetCodedIndexSize(CodedIndex.Implementation); // Implementation
|
||||
break;
|
||||
case Table.NestedClass:
|
||||
size = GetTableIndexSize(Table.TypeDef) // NestedClass
|
||||
+ GetTableIndexSize(Table.TypeDef); // EnclosingClass
|
||||
break;
|
||||
case Table.GenericParam:
|
||||
size = 4 // Number, Flags
|
||||
+ GetCodedIndexSize(CodedIndex.TypeOrMethodDef) // Owner
|
||||
+ stridx_size; // Name
|
||||
break;
|
||||
case Table.MethodSpec:
|
||||
size = GetCodedIndexSize(CodedIndex.MethodDefOrRef) // Method
|
||||
+ blobidx_size; // Instantiation
|
||||
break;
|
||||
case Table.GenericParamConstraint:
|
||||
size = GetTableIndexSize(Table.GenericParam) // Owner
|
||||
+ GetCodedIndexSize(CodedIndex.TypeDefOrRef); // Constraint
|
||||
break;
|
||||
case Table.Document:
|
||||
size = blobidx_size // Name
|
||||
+ guididx_size // HashAlgorithm
|
||||
+ blobidx_size // Hash
|
||||
+ guididx_size; // Language
|
||||
break;
|
||||
case Table.MethodDebugInformation:
|
||||
size = GetTableIndexSize(Table.Document) // Document
|
||||
+ blobidx_size; // SequencePoints
|
||||
break;
|
||||
case Table.LocalScope:
|
||||
size = GetTableIndexSize(Table.Method) // Method
|
||||
+ GetTableIndexSize(Table.ImportScope) // ImportScope
|
||||
+ GetTableIndexSize(Table.LocalVariable) // VariableList
|
||||
+ GetTableIndexSize(Table.LocalConstant) // ConstantList
|
||||
+ 4 * 2; // StartOffset, Length
|
||||
break;
|
||||
case Table.LocalVariable:
|
||||
size = 2 // Attributes
|
||||
+ 2 // Index
|
||||
+ stridx_size; // Name
|
||||
break;
|
||||
case Table.LocalConstant:
|
||||
size = stridx_size // Name
|
||||
+ blobidx_size; // Signature
|
||||
break;
|
||||
case Table.ImportScope:
|
||||
size = GetTableIndexSize(Table.ImportScope) // Parent
|
||||
+ blobidx_size;
|
||||
break;
|
||||
case Table.StateMachineMethod:
|
||||
size = GetTableIndexSize(Table.Method) // MoveNextMethod
|
||||
+ GetTableIndexSize(Table.Method); // KickOffMethod
|
||||
break;
|
||||
case Table.CustomDebugInformation:
|
||||
size = GetCodedIndexSize(CodedIndex.HasCustomDebugInformation) // Parent
|
||||
+ guididx_size // Kind
|
||||
+ blobidx_size; // Value
|
||||
break;
|
||||
default:
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
tables[i].RowSize = (uint)size;
|
||||
tables[i].Offset = offset;
|
||||
|
||||
offset += (uint)size * tables[i].Length;
|
||||
}
|
||||
}
|
||||
|
||||
private void ReadPdbHeap()
|
||||
{
|
||||
PdbHeap heap = image.PdbHeap;
|
||||
|
||||
ByteBuffer buffer = new(heap.data);
|
||||
|
||||
heap.Id = buffer.ReadBytes(20);
|
||||
heap.EntryPoint = buffer.ReadUInt32();
|
||||
heap.TypeSystemTables = buffer.ReadInt64();
|
||||
heap.TypeSystemTableRows = new uint [Mixin.TableCount];
|
||||
|
||||
for (int i = 0; i < Mixin.TableCount; i++)
|
||||
{
|
||||
Table table = (Table)i;
|
||||
if (!heap.HasTable(table))
|
||||
continue;
|
||||
|
||||
heap.TypeSystemTableRows[i] = buffer.ReadUInt32();
|
||||
}
|
||||
}
|
||||
|
||||
public static Image ReadImage(Disposable<Stream> stream, string file_name)
|
||||
{
|
||||
try
|
||||
{
|
||||
ImageReader reader = new(stream, file_name);
|
||||
reader.ReadImage();
|
||||
return reader.image;
|
||||
}
|
||||
catch (EndOfStreamException e)
|
||||
{
|
||||
throw new BadImageFormatException(stream.value.GetFileName(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public static Image ReadPortablePdb(Disposable<Stream> stream, string file_name)
|
||||
{
|
||||
try
|
||||
{
|
||||
ImageReader reader = new(stream, file_name);
|
||||
uint length = (uint)stream.value.Length;
|
||||
|
||||
reader.image.Sections = new[]
|
||||
{
|
||||
new Section
|
||||
{
|
||||
PointerToRawData = 0,
|
||||
SizeOfRawData = length,
|
||||
VirtualAddress = 0,
|
||||
VirtualSize = length
|
||||
}
|
||||
};
|
||||
|
||||
reader.metadata = new(0, length);
|
||||
reader.ReadMetadata();
|
||||
return reader.image;
|
||||
}
|
||||
catch (EndOfStreamException e)
|
||||
{
|
||||
throw new BadImageFormatException(stream.value.GetFileName(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ba04d4e3389423e47b35aaccee205576
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 207815
|
||||
packageName: 'FishNet: Networking Evolved'
|
||||
packageVersion: 4.6.22R
|
||||
assetPath: Assets/FishNet/CodeGenerating/cecil-0.11.4/Mono.Cecil.PE/ImageReader.cs
|
||||
uploadId: 866910
|
||||
@@ -0,0 +1,874 @@
|
||||
//
|
||||
// Author:
|
||||
// Jb Evain (jbevain@gmail.com)
|
||||
//
|
||||
// Copyright (c) 2008 - 2015 Jb Evain
|
||||
// Copyright (c) 2008 - 2011 Novell, Inc.
|
||||
//
|
||||
// Licensed under the MIT/X11 license.
|
||||
//
|
||||
|
||||
using MonoFN.Cecil.Cil;
|
||||
using MonoFN.Cecil.Metadata;
|
||||
using System;
|
||||
using System.IO;
|
||||
using RVA = System.UInt32;
|
||||
|
||||
namespace MonoFN.Cecil.PE
|
||||
{
|
||||
internal sealed class ImageWriter : BinaryStreamWriter
|
||||
{
|
||||
private readonly ModuleDefinition module;
|
||||
private readonly MetadataBuilder metadata;
|
||||
private readonly TextMap text_map;
|
||||
internal readonly Disposable<Stream> stream;
|
||||
private readonly string runtime_version;
|
||||
private ImageDebugHeader debug_header;
|
||||
private ByteBuffer win32_resources;
|
||||
private const uint pe_header_size = 0x98u;
|
||||
private const uint section_header_size = 0x28u;
|
||||
private const uint file_alignment = 0x200;
|
||||
private const uint section_alignment = 0x2000;
|
||||
private const ulong image_base = 0x00400000;
|
||||
internal const RVA text_rva = 0x2000;
|
||||
private readonly bool pe64;
|
||||
private readonly bool has_reloc;
|
||||
internal Section text;
|
||||
internal Section rsrc;
|
||||
internal Section reloc;
|
||||
private ushort sections;
|
||||
|
||||
private ImageWriter(ModuleDefinition module, string runtime_version, MetadataBuilder metadata, Disposable<Stream> stream, bool metadataOnly = false) : base(stream.value)
|
||||
{
|
||||
this.module = module;
|
||||
this.runtime_version = runtime_version;
|
||||
text_map = metadata.text_map;
|
||||
this.stream = stream;
|
||||
this.metadata = metadata;
|
||||
if (metadataOnly)
|
||||
return;
|
||||
|
||||
pe64 = module.Architecture == TargetArchitecture.AMD64 || module.Architecture == TargetArchitecture.IA64 || module.Architecture == TargetArchitecture.ARM64;
|
||||
has_reloc = module.Architecture == TargetArchitecture.I386;
|
||||
GetDebugHeader();
|
||||
GetWin32Resources();
|
||||
BuildTextMap();
|
||||
sections = (ushort)(has_reloc ? 2 : 1); // text + reloc?
|
||||
}
|
||||
|
||||
private void GetDebugHeader()
|
||||
{
|
||||
ISymbolWriter symbol_writer = metadata.symbol_writer;
|
||||
if (symbol_writer != null)
|
||||
debug_header = symbol_writer.GetDebugHeader();
|
||||
|
||||
if (module.HasDebugHeader)
|
||||
{
|
||||
ImageDebugHeader header = module.GetDebugHeader();
|
||||
ImageDebugHeaderEntry deterministic = header.GetDeterministicEntry();
|
||||
if (deterministic == null)
|
||||
return;
|
||||
|
||||
debug_header = debug_header.AddDeterministicEntry();
|
||||
}
|
||||
}
|
||||
|
||||
private void GetWin32Resources()
|
||||
{
|
||||
if (!module.HasImage)
|
||||
return;
|
||||
|
||||
DataDirectory win32_resources_directory = module.Image.Win32Resources;
|
||||
uint size = win32_resources_directory.Size;
|
||||
|
||||
if (size > 0)
|
||||
{
|
||||
win32_resources = module.Image.GetReaderAt(win32_resources_directory.VirtualAddress, size, (s, reader) => new ByteBuffer(reader.ReadBytes((int)s)));
|
||||
}
|
||||
}
|
||||
|
||||
public static ImageWriter CreateWriter(ModuleDefinition module, MetadataBuilder metadata, Disposable<Stream> stream)
|
||||
{
|
||||
ImageWriter writer = new(module, module.runtime_version, metadata, stream);
|
||||
writer.BuildSections();
|
||||
return writer;
|
||||
}
|
||||
|
||||
public static ImageWriter CreateDebugWriter(ModuleDefinition module, MetadataBuilder metadata, Disposable<Stream> stream)
|
||||
{
|
||||
ImageWriter writer = new(module, "PDB v1.0", metadata, stream, metadataOnly: true);
|
||||
uint length = metadata.text_map.GetLength();
|
||||
writer.text = new() { SizeOfRawData = length, VirtualSize = length };
|
||||
return writer;
|
||||
}
|
||||
|
||||
private void BuildSections()
|
||||
{
|
||||
bool has_win32_resources = win32_resources != null;
|
||||
if (has_win32_resources)
|
||||
sections++;
|
||||
|
||||
text = CreateSection(".text", text_map.GetLength(), null);
|
||||
Section previous = text;
|
||||
|
||||
if (has_win32_resources)
|
||||
{
|
||||
rsrc = CreateSection(".rsrc", (uint)win32_resources.length, previous);
|
||||
|
||||
PatchWin32Resources(win32_resources);
|
||||
previous = rsrc;
|
||||
}
|
||||
|
||||
if (has_reloc)
|
||||
reloc = CreateSection(".reloc", 12u, previous);
|
||||
}
|
||||
|
||||
private Section CreateSection(string name, uint size, Section previous)
|
||||
{
|
||||
return new()
|
||||
{
|
||||
Name = name,
|
||||
VirtualAddress = previous != null ? previous.VirtualAddress + Align(previous.VirtualSize, section_alignment) : text_rva,
|
||||
VirtualSize = size,
|
||||
PointerToRawData = previous != null ? previous.PointerToRawData + previous.SizeOfRawData : Align(GetHeaderSize(), file_alignment),
|
||||
SizeOfRawData = Align(size, file_alignment)
|
||||
};
|
||||
}
|
||||
|
||||
private static uint Align(uint value, uint align)
|
||||
{
|
||||
align--;
|
||||
return (value + align) & ~align;
|
||||
}
|
||||
|
||||
private void WriteDOSHeader()
|
||||
{
|
||||
Write(new byte[]
|
||||
{
|
||||
// dos header start
|
||||
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
|
||||
0x80, 0x00, 0x00, 0x00,
|
||||
// dos header end
|
||||
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
|
||||
});
|
||||
}
|
||||
|
||||
private ushort SizeOfOptionalHeader()
|
||||
{
|
||||
return (ushort)(!pe64 ? 0xe0 : 0xf0);
|
||||
}
|
||||
|
||||
private void WritePEFileHeader()
|
||||
{
|
||||
WriteUInt32(0x00004550); // Magic
|
||||
WriteUInt16((ushort)module.Architecture); // Machine
|
||||
WriteUInt16(sections); // NumberOfSections
|
||||
WriteUInt32(metadata.timestamp);
|
||||
WriteUInt32(0); // PointerToSymbolTable
|
||||
WriteUInt32(0); // NumberOfSymbols
|
||||
WriteUInt16(SizeOfOptionalHeader()); // SizeOfOptionalHeader
|
||||
|
||||
const ushort LargeAddressAware = 0x0020;
|
||||
|
||||
// ExecutableImage | (!pe64 ? 32BitsMachine : LargeAddressAware)
|
||||
ushort characteristics = (ushort)(0x0002 | (!pe64 ? 0x0100 : LargeAddressAware));
|
||||
if (module.Kind == ModuleKind.Dll || module.Kind == ModuleKind.NetModule)
|
||||
characteristics |= 0x2000;
|
||||
|
||||
if (module.Image != null && (module.Image.Characteristics & LargeAddressAware) != 0)
|
||||
characteristics |= LargeAddressAware;
|
||||
|
||||
WriteUInt16(characteristics); // Characteristics
|
||||
}
|
||||
|
||||
private Section LastSection()
|
||||
{
|
||||
if (reloc != null)
|
||||
return reloc;
|
||||
|
||||
if (rsrc != null)
|
||||
return rsrc;
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
private void WriteOptionalHeaders()
|
||||
{
|
||||
WriteUInt16((ushort)(!pe64 ? 0x10b : 0x20b)); // Magic
|
||||
WriteUInt16(module.linker_version);
|
||||
WriteUInt32(text.SizeOfRawData); // CodeSize
|
||||
WriteUInt32((reloc != null ? reloc.SizeOfRawData : 0) + (rsrc != null ? rsrc.SizeOfRawData : 0)); // InitializedDataSize
|
||||
WriteUInt32(0); // UninitializedDataSize
|
||||
|
||||
Range startub_stub = text_map.GetRange(TextSegment.StartupStub);
|
||||
WriteUInt32(startub_stub.Length > 0 ? startub_stub.Start : 0); // EntryPointRVA
|
||||
WriteUInt32(text_rva); // BaseOfCode
|
||||
|
||||
if (!pe64)
|
||||
{
|
||||
WriteUInt32(0); // BaseOfData
|
||||
WriteUInt32((uint)image_base); // ImageBase
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteUInt64(image_base); // ImageBase
|
||||
}
|
||||
|
||||
WriteUInt32(section_alignment); // SectionAlignment
|
||||
WriteUInt32(file_alignment); // FileAlignment
|
||||
|
||||
WriteUInt16(4); // OSMajor
|
||||
WriteUInt16(0); // OSMinor
|
||||
WriteUInt16(0); // UserMajor
|
||||
WriteUInt16(0); // UserMinor
|
||||
WriteUInt16(module.subsystem_major); // SubSysMajor
|
||||
WriteUInt16(module.subsystem_minor); // SubSysMinor
|
||||
WriteUInt32(0); // Reserved
|
||||
|
||||
Section last_section = LastSection();
|
||||
WriteUInt32(last_section.VirtualAddress + Align(last_section.VirtualSize, section_alignment)); // ImageSize
|
||||
WriteUInt32(text.PointerToRawData); // HeaderSize
|
||||
|
||||
WriteUInt32(0); // Checksum
|
||||
WriteUInt16(GetSubSystem()); // SubSystem
|
||||
WriteUInt16((ushort)module.Characteristics); // DLLFlags
|
||||
|
||||
if (!pe64)
|
||||
{
|
||||
const uint stack_reserve = 0x100000;
|
||||
const uint stack_commit = 0x1000;
|
||||
const uint heap_reserve = 0x100000;
|
||||
const uint heap_commit = 0x1000;
|
||||
|
||||
WriteUInt32(stack_reserve);
|
||||
WriteUInt32(stack_commit);
|
||||
WriteUInt32(heap_reserve);
|
||||
WriteUInt32(heap_commit);
|
||||
}
|
||||
else
|
||||
{
|
||||
const ulong stack_reserve = 0x400000;
|
||||
const ulong stack_commit = 0x4000;
|
||||
const ulong heap_reserve = 0x100000;
|
||||
const ulong heap_commit = 0x2000;
|
||||
|
||||
WriteUInt64(stack_reserve);
|
||||
WriteUInt64(stack_commit);
|
||||
WriteUInt64(heap_reserve);
|
||||
WriteUInt64(heap_commit);
|
||||
}
|
||||
|
||||
WriteUInt32(0); // LoaderFlags
|
||||
WriteUInt32(16); // NumberOfDataDir
|
||||
|
||||
WriteZeroDataDirectory(); // ExportTable
|
||||
WriteDataDirectory(text_map.GetDataDirectory(TextSegment.ImportDirectory)); // ImportTable
|
||||
if (rsrc != null)
|
||||
{
|
||||
// ResourceTable
|
||||
WriteUInt32(rsrc.VirtualAddress);
|
||||
WriteUInt32(rsrc.VirtualSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteZeroDataDirectory();
|
||||
}
|
||||
|
||||
WriteZeroDataDirectory(); // ExceptionTable
|
||||
WriteZeroDataDirectory(); // CertificateTable
|
||||
WriteUInt32(reloc != null ? reloc.VirtualAddress : 0); // BaseRelocationTable
|
||||
WriteUInt32(reloc != null ? reloc.VirtualSize : 0);
|
||||
|
||||
if (text_map.GetLength(TextSegment.DebugDirectory) > 0)
|
||||
{
|
||||
WriteUInt32(text_map.GetRVA(TextSegment.DebugDirectory));
|
||||
WriteUInt32((uint)(debug_header.Entries.Length * ImageDebugDirectory.Size));
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteZeroDataDirectory();
|
||||
}
|
||||
|
||||
WriteZeroDataDirectory(); // Copyright
|
||||
WriteZeroDataDirectory(); // GlobalPtr
|
||||
WriteZeroDataDirectory(); // TLSTable
|
||||
WriteZeroDataDirectory(); // LoadConfigTable
|
||||
WriteZeroDataDirectory(); // BoundImport
|
||||
WriteDataDirectory(text_map.GetDataDirectory(TextSegment.ImportAddressTable)); // IAT
|
||||
WriteZeroDataDirectory(); // DelayImportDesc
|
||||
WriteDataDirectory(text_map.GetDataDirectory(TextSegment.CLIHeader)); // CLIHeader
|
||||
WriteZeroDataDirectory(); // Reserved
|
||||
}
|
||||
|
||||
private void WriteZeroDataDirectory()
|
||||
{
|
||||
WriteUInt32(0);
|
||||
WriteUInt32(0);
|
||||
}
|
||||
|
||||
private ushort GetSubSystem()
|
||||
{
|
||||
switch (module.Kind)
|
||||
{
|
||||
case ModuleKind.Console:
|
||||
case ModuleKind.Dll:
|
||||
case ModuleKind.NetModule:
|
||||
return 0x3;
|
||||
case ModuleKind.Windows:
|
||||
return 0x2;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteSectionHeaders()
|
||||
{
|
||||
WriteSection(text, 0x60000020);
|
||||
|
||||
if (rsrc != null)
|
||||
WriteSection(rsrc, 0x40000040);
|
||||
|
||||
if (reloc != null)
|
||||
WriteSection(reloc, 0x42000040);
|
||||
}
|
||||
|
||||
private void WriteSection(Section section, uint characteristics)
|
||||
{
|
||||
byte[] name = new byte [8];
|
||||
string sect_name = section.Name;
|
||||
for (int i = 0; i < sect_name.Length; i++)
|
||||
name[i] = (byte)sect_name[i];
|
||||
|
||||
WriteBytes(name);
|
||||
WriteUInt32(section.VirtualSize);
|
||||
WriteUInt32(section.VirtualAddress);
|
||||
WriteUInt32(section.SizeOfRawData);
|
||||
WriteUInt32(section.PointerToRawData);
|
||||
WriteUInt32(0); // PointerToRelocations
|
||||
WriteUInt32(0); // PointerToLineNumbers
|
||||
WriteUInt16(0); // NumberOfRelocations
|
||||
WriteUInt16(0); // NumberOfLineNumbers
|
||||
WriteUInt32(characteristics);
|
||||
}
|
||||
|
||||
private uint GetRVAFileOffset(Section section, RVA rva)
|
||||
{
|
||||
return section.PointerToRawData + rva - section.VirtualAddress;
|
||||
}
|
||||
|
||||
private void MoveTo(uint pointer)
|
||||
{
|
||||
BaseStream.Seek(pointer, SeekOrigin.Begin);
|
||||
}
|
||||
|
||||
private void MoveToRVA(Section section, RVA rva)
|
||||
{
|
||||
BaseStream.Seek(GetRVAFileOffset(section, rva), SeekOrigin.Begin);
|
||||
}
|
||||
|
||||
private void MoveToRVA(TextSegment segment)
|
||||
{
|
||||
MoveToRVA(text, text_map.GetRVA(segment));
|
||||
}
|
||||
|
||||
private void WriteRVA(RVA rva)
|
||||
{
|
||||
if (!pe64)
|
||||
WriteUInt32(rva);
|
||||
else
|
||||
WriteUInt64(rva);
|
||||
}
|
||||
|
||||
private void PrepareSection(Section section)
|
||||
{
|
||||
MoveTo(section.PointerToRawData);
|
||||
|
||||
const int buffer_size = 4096;
|
||||
|
||||
if (section.SizeOfRawData <= buffer_size)
|
||||
{
|
||||
Write(new byte [section.SizeOfRawData]);
|
||||
MoveTo(section.PointerToRawData);
|
||||
return;
|
||||
}
|
||||
|
||||
int written = 0;
|
||||
byte[] buffer = new byte [buffer_size];
|
||||
while (written != section.SizeOfRawData)
|
||||
{
|
||||
int write_size = Math.Min((int)section.SizeOfRawData - written, buffer_size);
|
||||
Write(buffer, 0, write_size);
|
||||
written += write_size;
|
||||
}
|
||||
|
||||
MoveTo(section.PointerToRawData);
|
||||
}
|
||||
|
||||
private void WriteText()
|
||||
{
|
||||
PrepareSection(text);
|
||||
|
||||
// ImportAddressTable
|
||||
|
||||
if (has_reloc)
|
||||
{
|
||||
WriteRVA(text_map.GetRVA(TextSegment.ImportHintNameTable));
|
||||
WriteRVA(0);
|
||||
}
|
||||
|
||||
// CLIHeader
|
||||
|
||||
WriteUInt32(0x48);
|
||||
WriteUInt16(2);
|
||||
WriteUInt16((ushort)(module.Runtime <= TargetRuntime.Net_1_1 ? 0 : 5));
|
||||
|
||||
WriteUInt32(text_map.GetRVA(TextSegment.MetadataHeader));
|
||||
WriteUInt32(GetMetadataLength());
|
||||
WriteUInt32((uint)module.Attributes);
|
||||
WriteUInt32(metadata.entry_point.ToUInt32());
|
||||
WriteDataDirectory(text_map.GetDataDirectory(TextSegment.Resources));
|
||||
WriteDataDirectory(text_map.GetDataDirectory(TextSegment.StrongNameSignature));
|
||||
WriteZeroDataDirectory(); // CodeManagerTable
|
||||
WriteZeroDataDirectory(); // VTableFixups
|
||||
WriteZeroDataDirectory(); // ExportAddressTableJumps
|
||||
WriteZeroDataDirectory(); // ManagedNativeHeader
|
||||
|
||||
// Code
|
||||
|
||||
MoveToRVA(TextSegment.Code);
|
||||
WriteBuffer(metadata.code);
|
||||
|
||||
// Resources
|
||||
|
||||
MoveToRVA(TextSegment.Resources);
|
||||
WriteBuffer(metadata.resources);
|
||||
|
||||
// Data
|
||||
|
||||
if (metadata.data.length > 0)
|
||||
{
|
||||
MoveToRVA(TextSegment.Data);
|
||||
WriteBuffer(metadata.data);
|
||||
}
|
||||
|
||||
// StrongNameSignature
|
||||
// stays blank
|
||||
|
||||
// MetadataHeader
|
||||
|
||||
MoveToRVA(TextSegment.MetadataHeader);
|
||||
WriteMetadataHeader();
|
||||
|
||||
WriteMetadata();
|
||||
|
||||
// DebugDirectory
|
||||
if (text_map.GetLength(TextSegment.DebugDirectory) > 0)
|
||||
{
|
||||
MoveToRVA(TextSegment.DebugDirectory);
|
||||
WriteDebugDirectory();
|
||||
}
|
||||
|
||||
if (!has_reloc)
|
||||
return;
|
||||
|
||||
// ImportDirectory
|
||||
MoveToRVA(TextSegment.ImportDirectory);
|
||||
WriteImportDirectory();
|
||||
|
||||
// StartupStub
|
||||
MoveToRVA(TextSegment.StartupStub);
|
||||
WriteStartupStub();
|
||||
}
|
||||
|
||||
private uint GetMetadataLength()
|
||||
{
|
||||
return text_map.GetRVA(TextSegment.DebugDirectory) - text_map.GetRVA(TextSegment.MetadataHeader);
|
||||
}
|
||||
|
||||
public void WriteMetadataHeader()
|
||||
{
|
||||
WriteUInt32(0x424a5342); // Signature
|
||||
WriteUInt16(1); // MajorVersion
|
||||
WriteUInt16(1); // MinorVersion
|
||||
WriteUInt32(0); // Reserved
|
||||
|
||||
byte[] version = GetZeroTerminatedString(runtime_version);
|
||||
WriteUInt32((uint)version.Length);
|
||||
WriteBytes(version);
|
||||
WriteUInt16(0); // Flags
|
||||
WriteUInt16(GetStreamCount());
|
||||
|
||||
uint offset = text_map.GetRVA(TextSegment.TableHeap) - text_map.GetRVA(TextSegment.MetadataHeader);
|
||||
|
||||
WriteStreamHeader(ref offset, TextSegment.TableHeap, "#~");
|
||||
WriteStreamHeader(ref offset, TextSegment.StringHeap, "#Strings");
|
||||
WriteStreamHeader(ref offset, TextSegment.UserStringHeap, "#US");
|
||||
WriteStreamHeader(ref offset, TextSegment.GuidHeap, "#GUID");
|
||||
WriteStreamHeader(ref offset, TextSegment.BlobHeap, "#Blob");
|
||||
WriteStreamHeader(ref offset, TextSegment.PdbHeap, "#Pdb");
|
||||
}
|
||||
|
||||
private ushort GetStreamCount()
|
||||
{
|
||||
return (ushort)(1 // #~
|
||||
+ 1 // #Strings
|
||||
+ (metadata.user_string_heap.IsEmpty ? 0 : 1) // #US
|
||||
+ (metadata.guid_heap.IsEmpty ? 0 : 1) // GUID
|
||||
+ (metadata.blob_heap.IsEmpty ? 0 : 1) + (metadata.pdb_heap == null ? 0 : 1)); // #Blob
|
||||
}
|
||||
|
||||
private void WriteStreamHeader(ref uint offset, TextSegment heap, string name)
|
||||
{
|
||||
uint length = (uint)text_map.GetLength(heap);
|
||||
if (length == 0)
|
||||
return;
|
||||
|
||||
WriteUInt32(offset);
|
||||
WriteUInt32(length);
|
||||
WriteBytes(GetZeroTerminatedString(name));
|
||||
offset += length;
|
||||
}
|
||||
|
||||
private static int GetZeroTerminatedStringLength(string @string)
|
||||
{
|
||||
return (@string.Length + 1 + 3) & ~3;
|
||||
}
|
||||
|
||||
private static byte[] GetZeroTerminatedString(string @string)
|
||||
{
|
||||
return GetString(@string, GetZeroTerminatedStringLength(@string));
|
||||
}
|
||||
|
||||
private static byte[] GetSimpleString(string @string)
|
||||
{
|
||||
return GetString(@string, @string.Length);
|
||||
}
|
||||
|
||||
private static byte[] GetString(string @string, int length)
|
||||
{
|
||||
byte[] bytes = new byte [length];
|
||||
for (int i = 0; i < @string.Length; i++)
|
||||
bytes[i] = (byte)@string[i];
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public void WriteMetadata()
|
||||
{
|
||||
WriteHeap(TextSegment.TableHeap, metadata.table_heap);
|
||||
WriteHeap(TextSegment.StringHeap, metadata.string_heap);
|
||||
WriteHeap(TextSegment.UserStringHeap, metadata.user_string_heap);
|
||||
WriteHeap(TextSegment.GuidHeap, metadata.guid_heap);
|
||||
WriteHeap(TextSegment.BlobHeap, metadata.blob_heap);
|
||||
WriteHeap(TextSegment.PdbHeap, metadata.pdb_heap);
|
||||
}
|
||||
|
||||
private void WriteHeap(TextSegment heap, HeapBuffer buffer)
|
||||
{
|
||||
if (buffer == null || buffer.IsEmpty)
|
||||
return;
|
||||
|
||||
MoveToRVA(heap);
|
||||
WriteBuffer(buffer);
|
||||
}
|
||||
|
||||
private void WriteDebugDirectory()
|
||||
{
|
||||
int data_start = (int)BaseStream.Position + debug_header.Entries.Length * ImageDebugDirectory.Size;
|
||||
|
||||
for (int i = 0; i < debug_header.Entries.Length; i++)
|
||||
{
|
||||
ImageDebugHeaderEntry entry = debug_header.Entries[i];
|
||||
ImageDebugDirectory directory = entry.Directory;
|
||||
WriteInt32(directory.Characteristics);
|
||||
WriteInt32(directory.TimeDateStamp);
|
||||
WriteInt16(directory.MajorVersion);
|
||||
WriteInt16(directory.MinorVersion);
|
||||
WriteInt32((int)directory.Type);
|
||||
WriteInt32(directory.SizeOfData);
|
||||
WriteInt32(directory.AddressOfRawData);
|
||||
WriteInt32(data_start);
|
||||
|
||||
data_start += entry.Data.Length;
|
||||
}
|
||||
|
||||
for (int i = 0; i < debug_header.Entries.Length; i++)
|
||||
{
|
||||
ImageDebugHeaderEntry entry = debug_header.Entries[i];
|
||||
WriteBytes(entry.Data);
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteImportDirectory()
|
||||
{
|
||||
WriteUInt32(text_map.GetRVA(TextSegment.ImportDirectory) + 40); // ImportLookupTable
|
||||
WriteUInt32(0); // DateTimeStamp
|
||||
WriteUInt32(0); // ForwarderChain
|
||||
WriteUInt32(text_map.GetRVA(TextSegment.ImportHintNameTable) + 14);
|
||||
WriteUInt32(text_map.GetRVA(TextSegment.ImportAddressTable));
|
||||
Advance(20);
|
||||
|
||||
// ImportLookupTable
|
||||
WriteUInt32(text_map.GetRVA(TextSegment.ImportHintNameTable));
|
||||
|
||||
// ImportHintNameTable
|
||||
MoveToRVA(TextSegment.ImportHintNameTable);
|
||||
|
||||
WriteUInt16(0); // Hint
|
||||
WriteBytes(GetRuntimeMain());
|
||||
WriteByte(0);
|
||||
WriteBytes(GetSimpleString("mscoree.dll"));
|
||||
WriteUInt16(0);
|
||||
}
|
||||
|
||||
private byte[] GetRuntimeMain()
|
||||
{
|
||||
return module.Kind == ModuleKind.Dll || module.Kind == ModuleKind.NetModule ? GetSimpleString("_CorDllMain") : GetSimpleString("_CorExeMain");
|
||||
}
|
||||
|
||||
private void WriteStartupStub()
|
||||
{
|
||||
switch (module.Architecture)
|
||||
{
|
||||
case TargetArchitecture.I386:
|
||||
WriteUInt16(0x25ff);
|
||||
WriteUInt32((uint)image_base + text_map.GetRVA(TextSegment.ImportAddressTable));
|
||||
return;
|
||||
default:
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteRsrc()
|
||||
{
|
||||
PrepareSection(rsrc);
|
||||
WriteBuffer(win32_resources);
|
||||
}
|
||||
|
||||
private void WriteReloc()
|
||||
{
|
||||
PrepareSection(reloc);
|
||||
|
||||
uint reloc_rva = text_map.GetRVA(TextSegment.StartupStub);
|
||||
reloc_rva += module.Architecture == TargetArchitecture.IA64 ? 0x20u : 2;
|
||||
uint page_rva = reloc_rva & ~0xfffu;
|
||||
|
||||
WriteUInt32(page_rva); // PageRVA
|
||||
WriteUInt32(0x000c); // Block Size
|
||||
|
||||
switch (module.Architecture)
|
||||
{
|
||||
case TargetArchitecture.I386:
|
||||
WriteUInt32(0x3000 + reloc_rva - page_rva);
|
||||
break;
|
||||
default:
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteImage()
|
||||
{
|
||||
WriteDOSHeader();
|
||||
WritePEFileHeader();
|
||||
WriteOptionalHeaders();
|
||||
WriteSectionHeaders();
|
||||
WriteText();
|
||||
if (rsrc != null)
|
||||
WriteRsrc();
|
||||
if (reloc != null)
|
||||
WriteReloc();
|
||||
Flush();
|
||||
}
|
||||
|
||||
private void BuildTextMap()
|
||||
{
|
||||
TextMap map = text_map;
|
||||
|
||||
map.AddMap(TextSegment.Code, metadata.code.length, !pe64 ? 4 : 16);
|
||||
map.AddMap(TextSegment.Resources, metadata.resources.length, 8);
|
||||
map.AddMap(TextSegment.Data, metadata.data.length, 4);
|
||||
if (metadata.data.length > 0)
|
||||
metadata.table_heap.FixupData(map.GetRVA(TextSegment.Data));
|
||||
map.AddMap(TextSegment.StrongNameSignature, GetStrongNameLength(), 4);
|
||||
|
||||
BuildMetadataTextMap();
|
||||
|
||||
int debug_dir_len = 0;
|
||||
if (debug_header != null && debug_header.HasEntries)
|
||||
{
|
||||
int directories_len = debug_header.Entries.Length * ImageDebugDirectory.Size;
|
||||
int data_address = (int)map.GetNextRVA(TextSegment.BlobHeap) + directories_len;
|
||||
int data_len = 0;
|
||||
|
||||
for (int i = 0; i < debug_header.Entries.Length; i++)
|
||||
{
|
||||
ImageDebugHeaderEntry entry = debug_header.Entries[i];
|
||||
ImageDebugDirectory directory = entry.Directory;
|
||||
|
||||
directory.AddressOfRawData = entry.Data.Length == 0 ? 0 : data_address;
|
||||
entry.Directory = directory;
|
||||
|
||||
data_len += entry.Data.Length;
|
||||
data_address += data_len;
|
||||
}
|
||||
|
||||
debug_dir_len = directories_len + data_len;
|
||||
}
|
||||
|
||||
map.AddMap(TextSegment.DebugDirectory, debug_dir_len, 4);
|
||||
|
||||
if (!has_reloc)
|
||||
{
|
||||
uint start = map.GetNextRVA(TextSegment.DebugDirectory);
|
||||
map.AddMap(TextSegment.ImportDirectory, new Range(start, 0));
|
||||
map.AddMap(TextSegment.ImportHintNameTable, new Range(start, 0));
|
||||
map.AddMap(TextSegment.StartupStub, new Range(start, 0));
|
||||
return;
|
||||
}
|
||||
|
||||
RVA import_dir_rva = map.GetNextRVA(TextSegment.DebugDirectory);
|
||||
RVA import_hnt_rva = import_dir_rva + 48u;
|
||||
import_hnt_rva = (import_hnt_rva + 15u) & ~15u;
|
||||
uint import_dir_len = import_hnt_rva - import_dir_rva + 27u;
|
||||
|
||||
RVA startup_stub_rva = import_dir_rva + import_dir_len;
|
||||
startup_stub_rva = module.Architecture == TargetArchitecture.IA64 ? (startup_stub_rva + 15u) & ~15u : 2 + ((startup_stub_rva + 3u) & ~3u);
|
||||
|
||||
map.AddMap(TextSegment.ImportDirectory, new Range(import_dir_rva, import_dir_len));
|
||||
map.AddMap(TextSegment.ImportHintNameTable, new Range(import_hnt_rva, 0));
|
||||
map.AddMap(TextSegment.StartupStub, new Range(startup_stub_rva, GetStartupStubLength()));
|
||||
}
|
||||
|
||||
public void BuildMetadataTextMap()
|
||||
{
|
||||
TextMap map = text_map;
|
||||
|
||||
map.AddMap(TextSegment.MetadataHeader, GetMetadataHeaderLength(module.RuntimeVersion));
|
||||
map.AddMap(TextSegment.TableHeap, metadata.table_heap.length, 4);
|
||||
map.AddMap(TextSegment.StringHeap, metadata.string_heap.length, 4);
|
||||
map.AddMap(TextSegment.UserStringHeap, metadata.user_string_heap.IsEmpty ? 0 : metadata.user_string_heap.length, 4);
|
||||
map.AddMap(TextSegment.GuidHeap, metadata.guid_heap.length, 4);
|
||||
map.AddMap(TextSegment.BlobHeap, metadata.blob_heap.IsEmpty ? 0 : metadata.blob_heap.length, 4);
|
||||
map.AddMap(TextSegment.PdbHeap, metadata.pdb_heap == null ? 0 : metadata.pdb_heap.length, 4);
|
||||
}
|
||||
|
||||
private uint GetStartupStubLength()
|
||||
{
|
||||
switch (module.Architecture)
|
||||
{
|
||||
case TargetArchitecture.I386:
|
||||
return 6;
|
||||
default:
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
|
||||
private int GetMetadataHeaderLength(string runtimeVersion)
|
||||
{
|
||||
return
|
||||
// MetadataHeader
|
||||
20 + GetZeroTerminatedStringLength(runtimeVersion)
|
||||
// #~ header
|
||||
+ 12
|
||||
// #Strings header
|
||||
+ 20
|
||||
// #US header
|
||||
+ (metadata.user_string_heap.IsEmpty ? 0 : 12)
|
||||
// #GUID header
|
||||
+ 16
|
||||
// #Blob header
|
||||
+ (metadata.blob_heap.IsEmpty ? 0 : 16)
|
||||
//
|
||||
+ (metadata.pdb_heap == null ? 0 : 16);
|
||||
}
|
||||
|
||||
private int GetStrongNameLength()
|
||||
{
|
||||
if (module.kind == ModuleKind.NetModule || module.Assembly == null)
|
||||
return 0;
|
||||
|
||||
byte[] public_key = module.Assembly.Name.PublicKey;
|
||||
if (public_key.IsNullOrEmpty())
|
||||
return 0;
|
||||
|
||||
// in fx 2.0 the key may be from 384 to 16384 bits
|
||||
// so we must calculate the signature size based on
|
||||
// the size of the public key (minus the 32 byte header)
|
||||
int size = public_key.Length;
|
||||
if (size > 32)
|
||||
return size - 32;
|
||||
|
||||
// note: size == 16 for the ECMA "key" which is replaced
|
||||
// by the runtime with a 1024 bits key (128 bytes)
|
||||
|
||||
return 128; // default strongname signature size
|
||||
}
|
||||
|
||||
public DataDirectory GetStrongNameSignatureDirectory()
|
||||
{
|
||||
return text_map.GetDataDirectory(TextSegment.StrongNameSignature);
|
||||
}
|
||||
|
||||
public uint GetHeaderSize()
|
||||
{
|
||||
return pe_header_size + SizeOfOptionalHeader() + sections * section_header_size;
|
||||
}
|
||||
|
||||
private void PatchWin32Resources(ByteBuffer resources)
|
||||
{
|
||||
PatchResourceDirectoryTable(resources);
|
||||
}
|
||||
|
||||
private void PatchResourceDirectoryTable(ByteBuffer resources)
|
||||
{
|
||||
resources.Advance(12);
|
||||
|
||||
int entries = resources.ReadUInt16() + resources.ReadUInt16();
|
||||
|
||||
for (int i = 0; i < entries; i++)
|
||||
PatchResourceDirectoryEntry(resources);
|
||||
}
|
||||
|
||||
private void PatchResourceDirectoryEntry(ByteBuffer resources)
|
||||
{
|
||||
resources.Advance(4);
|
||||
uint child = resources.ReadUInt32();
|
||||
|
||||
int position = resources.position;
|
||||
resources.position = (int)child & 0x7fffffff;
|
||||
|
||||
if ((child & 0x80000000) != 0)
|
||||
PatchResourceDirectoryTable(resources);
|
||||
else
|
||||
PatchResourceDataEntry(resources);
|
||||
|
||||
resources.position = position;
|
||||
}
|
||||
|
||||
private void PatchResourceDataEntry(ByteBuffer resources)
|
||||
{
|
||||
uint rva = resources.ReadUInt32();
|
||||
resources.position -= 4;
|
||||
|
||||
resources.WriteUInt32(rva - module.Image.Win32Resources.VirtualAddress + rsrc.VirtualAddress);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 88ebae078ed1c8346be0a945ce3b03b0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 207815
|
||||
packageName: 'FishNet: Networking Evolved'
|
||||
packageVersion: 4.6.22R
|
||||
assetPath: Assets/FishNet/CodeGenerating/cecil-0.11.4/Mono.Cecil.PE/ImageWriter.cs
|
||||
uploadId: 866910
|
||||
@@ -0,0 +1,23 @@
|
||||
//
|
||||
// Author:
|
||||
// Jb Evain (jbevain@gmail.com)
|
||||
//
|
||||
// Copyright (c) 2008 - 2015 Jb Evain
|
||||
// Copyright (c) 2008 - 2011 Novell, Inc.
|
||||
//
|
||||
// Licensed under the MIT/X11 license.
|
||||
//
|
||||
|
||||
using RVA = System.UInt32;
|
||||
|
||||
namespace MonoFN.Cecil.PE
|
||||
{
|
||||
internal sealed class Section
|
||||
{
|
||||
public string Name;
|
||||
public RVA VirtualAddress;
|
||||
public uint VirtualSize;
|
||||
public uint SizeOfRawData;
|
||||
public uint PointerToRawData;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dc33915bdaaf42a428f8a4694e9611a8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 207815
|
||||
packageName: 'FishNet: Networking Evolved'
|
||||
packageVersion: 4.6.22R
|
||||
assetPath: Assets/FishNet/CodeGenerating/cecil-0.11.4/Mono.Cecil.PE/Section.cs
|
||||
uploadId: 866910
|
||||
@@ -0,0 +1,106 @@
|
||||
//
|
||||
// Author:
|
||||
// Jb Evain (jbevain@gmail.com)
|
||||
//
|
||||
// Copyright (c) 2008 - 2015 Jb Evain
|
||||
// Copyright (c) 2008 - 2011 Novell, Inc.
|
||||
//
|
||||
// Licensed under the MIT/X11 license.
|
||||
//
|
||||
|
||||
using RVA = System.UInt32;
|
||||
|
||||
namespace MonoFN.Cecil.PE
|
||||
{
|
||||
internal enum TextSegment
|
||||
{
|
||||
ImportAddressTable,
|
||||
CLIHeader,
|
||||
Code,
|
||||
Resources,
|
||||
Data,
|
||||
StrongNameSignature,
|
||||
|
||||
// Metadata
|
||||
MetadataHeader,
|
||||
TableHeap,
|
||||
StringHeap,
|
||||
UserStringHeap,
|
||||
GuidHeap,
|
||||
BlobHeap,
|
||||
PdbHeap,
|
||||
// End Metadata
|
||||
DebugDirectory,
|
||||
ImportDirectory,
|
||||
ImportHintNameTable,
|
||||
StartupStub
|
||||
}
|
||||
|
||||
internal sealed class TextMap
|
||||
{
|
||||
private readonly Range[] map = new Range [17 /*Enum.GetValues (typeof (TextSegment)).Length*/];
|
||||
|
||||
public void AddMap(TextSegment segment, int length)
|
||||
{
|
||||
map[(int)segment] = new(GetStart(segment), (uint)length);
|
||||
}
|
||||
|
||||
public void AddMap(TextSegment segment, int length, int align)
|
||||
{
|
||||
align--;
|
||||
|
||||
AddMap(segment, (length + align) & ~align);
|
||||
}
|
||||
|
||||
public void AddMap(TextSegment segment, Range range)
|
||||
{
|
||||
map[(int)segment] = range;
|
||||
}
|
||||
|
||||
public Range GetRange(TextSegment segment)
|
||||
{
|
||||
return map[(int)segment];
|
||||
}
|
||||
|
||||
public DataDirectory GetDataDirectory(TextSegment segment)
|
||||
{
|
||||
Range range = map[(int)segment];
|
||||
|
||||
return new(range.Length == 0 ? 0 : range.Start, range.Length);
|
||||
}
|
||||
|
||||
public RVA GetRVA(TextSegment segment)
|
||||
{
|
||||
return map[(int)segment].Start;
|
||||
}
|
||||
|
||||
public RVA GetNextRVA(TextSegment segment)
|
||||
{
|
||||
int i = (int)segment;
|
||||
return map[i].Start + map[i].Length;
|
||||
}
|
||||
|
||||
public int GetLength(TextSegment segment)
|
||||
{
|
||||
return (int)map[(int)segment].Length;
|
||||
}
|
||||
|
||||
private RVA GetStart(TextSegment segment)
|
||||
{
|
||||
int index = (int)segment;
|
||||
return index == 0 ? ImageWriter.text_rva : ComputeStart(index);
|
||||
}
|
||||
|
||||
private RVA ComputeStart(int index)
|
||||
{
|
||||
index--;
|
||||
return map[index].Start + map[index].Length;
|
||||
}
|
||||
|
||||
public uint GetLength()
|
||||
{
|
||||
Range range = map[(int)TextSegment.StartupStub];
|
||||
return range.Start - ImageWriter.text_rva + range.Length;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1d36ca0589eb8014fa28bc58a88ae85f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 207815
|
||||
packageName: 'FishNet: Networking Evolved'
|
||||
packageVersion: 4.6.22R
|
||||
assetPath: Assets/FishNet/CodeGenerating/cecil-0.11.4/Mono.Cecil.PE/TextMap.cs
|
||||
uploadId: 866910
|
||||
Reference in New Issue
Block a user