Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/cecil.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJb Evain <jbevain@gmail.com>2011-10-27 16:53:07 +0400
committerJb Evain <jbevain@gmail.com>2011-10-27 16:53:07 +0400
commit8771de6415d3fa5e34b12fd90519a5405c02e8b2 (patch)
tree0a1707ab3fc77c49d3f5f6f51628089ccffb1d19 /Mono.Cecil.PE
parentecdd7454b53a4d6b57c9eb2a500b91025a63b401 (diff)
First pass at a branch with reduced memory usage; Keeps an open handle on the file, dispose your modules
Diffstat (limited to 'Mono.Cecil.PE')
-rw-r--r--Mono.Cecil.PE/BinaryStreamReader.cs18
-rw-r--r--Mono.Cecil.PE/ByteBuffer.cs6
-rw-r--r--Mono.Cecil.PE/Image.cs50
-rw-r--r--Mono.Cecil.PE/ImageReader.cs61
-rw-r--r--Mono.Cecil.PE/ImageWriter.cs5
-rw-r--r--Mono.Cecil.PE/Section.cs1
6 files changed, 74 insertions, 67 deletions
diff --git a/Mono.Cecil.PE/BinaryStreamReader.cs b/Mono.Cecil.PE/BinaryStreamReader.cs
index ec2477c..77a8b44 100644
--- a/Mono.Cecil.PE/BinaryStreamReader.cs
+++ b/Mono.Cecil.PE/BinaryStreamReader.cs
@@ -33,17 +33,31 @@ namespace Mono.Cecil.PE {
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)
{
}
- protected void Advance (int bytes)
+ public void Advance (int bytes)
{
BaseStream.Seek (bytes, SeekOrigin.Current);
}
- protected DataDirectory ReadDataDirectory ()
+ public void MoveTo (uint position)
+ {
+ BaseStream.Seek (position, SeekOrigin.Begin);
+ }
+
+ public DataDirectory ReadDataDirectory ()
{
return new DataDirectory (ReadUInt32 (), ReadUInt32 ());
}
diff --git a/Mono.Cecil.PE/ByteBuffer.cs b/Mono.Cecil.PE/ByteBuffer.cs
index c7ae7ae..4f32c09 100644
--- a/Mono.Cecil.PE/ByteBuffer.cs
+++ b/Mono.Cecil.PE/ByteBuffer.cs
@@ -52,12 +52,6 @@ namespace Mono.Cecil.PE {
this.length = this.buffer.Length;
}
- public void Reset (byte [] buffer)
- {
- this.buffer = buffer ?? Empty<byte>.Array;
- this.length = this.buffer.Length;
- }
-
public void Advance (int length)
{
position += length;
diff --git a/Mono.Cecil.PE/Image.cs b/Mono.Cecil.PE/Image.cs
index 9a04494..8971b13 100644
--- a/Mono.Cecil.PE/Image.cs
+++ b/Mono.Cecil.PE/Image.cs
@@ -27,8 +27,8 @@
//
using System;
+using System.IO;
-using Mono;
using Mono.Cecil.Cil;
using Mono.Cecil.Metadata;
@@ -36,12 +36,13 @@ using RVA = System.UInt32;
namespace Mono.Cecil.PE {
- sealed class Image {
+ sealed class Image : IDisposable {
+
+ public Stream Stream;
public ModuleKind Kind;
public TargetRuntime Runtime;
public TargetArchitecture Architecture;
- public string FileName;
public Section [] Sections;
@@ -131,29 +132,42 @@ namespace Mono.Cecil.PE {
return null;
}
+ public BinaryStreamReader GetReaderAt (RVA rva)
+ {
+ var reader = new BinaryStreamReader (Stream);
+ reader.MoveTo (ResolveVirtualAddress (rva));
+ return reader;
+ }
+
public ImageDebugDirectory GetDebugHeader (out byte [] header)
{
- var section = GetSectionAtVirtualAddress (Debug.VirtualAddress);
- var buffer = new ByteBuffer (section.Data);
- buffer.position = (int) (Debug.VirtualAddress - section.VirtualAddress);
+ var reader = GetReaderAt (Debug.VirtualAddress);
var directory = new ImageDebugDirectory {
- Characteristics = buffer.ReadInt32 (),
- TimeDateStamp = buffer.ReadInt32 (),
- MajorVersion = buffer.ReadInt16 (),
- MinorVersion = buffer.ReadInt16 (),
- Type = buffer.ReadInt32 (),
- SizeOfData = buffer.ReadInt32 (),
- AddressOfRawData = buffer.ReadInt32 (),
- PointerToRawData = buffer.ReadInt32 (),
+ Characteristics = reader.ReadInt32 (),
+ TimeDateStamp = reader.ReadInt32 (),
+ MajorVersion = reader.ReadInt16 (),
+ MinorVersion = reader.ReadInt16 (),
+ Type = reader.ReadInt32 (),
+ SizeOfData = reader.ReadInt32 (),
+ AddressOfRawData = reader.ReadInt32 (),
+ PointerToRawData = reader.ReadInt32 (),
};
- buffer.position = (int) (directory.PointerToRawData - section.PointerToRawData);
+ reader = GetReaderAt ((uint) directory.AddressOfRawData);
+ header = reader.ReadBytes (directory.SizeOfData);
+ return directory;
+ }
- header = new byte [directory.SizeOfData];
- Buffer.BlockCopy (buffer.buffer, buffer.position, header, 0, header.Length);
+ ~Image ()
+ {
+ if (Stream != null)
+ Stream.Dispose ();
+ }
- return directory;
+ public void Dispose ()
+ {
+ Stream.Dispose ();
}
}
}
diff --git a/Mono.Cecil.PE/ImageReader.cs b/Mono.Cecil.PE/ImageReader.cs
index 734b00a..1205e0b 100644
--- a/Mono.Cecil.PE/ImageReader.cs
+++ b/Mono.Cecil.PE/ImageReader.cs
@@ -42,12 +42,13 @@ namespace Mono.Cecil.PE {
DataDirectory cli;
DataDirectory metadata;
+ uint table_heap_offset;
+
public ImageReader (Stream stream)
: base (stream)
{
image = new Image ();
-
- image.FileName = stream.GetFullyQualifiedName ();
+ image.Stream = stream;
}
void MoveTo (DataDirectory directory)
@@ -55,11 +56,6 @@ namespace Mono.Cecil.PE {
BaseStream.Position = image.ResolveVirtualAddress (directory.VirtualAddress);
}
- void MoveTo (uint position)
- {
- BaseStream.Position = position;
- }
-
void ReadImage ()
{
if (BaseStream.Length < 128)
@@ -275,31 +271,11 @@ namespace Mono.Cecil.PE {
Advance (16);
sections [i] = section;
-
- ReadSectionData (section);
}
image.Sections = sections;
}
- void ReadSectionData (Section section)
- {
- var position = BaseStream.Position;
-
- MoveTo (section.PointerToRawData);
-
- var length = (int) section.SizeOfRawData;
- var data = new byte [length];
- int offset = 0, read;
-
- while ((read = Read (data, offset, length - offset)) > 0)
- offset += read;
-
- section.Data = data;
-
- BaseStream.Position = position;
- }
-
void ReadCLIHeader ()
{
MoveTo (cli);
@@ -362,39 +338,50 @@ namespace Mono.Cecil.PE {
void ReadMetadataStream (Section section)
{
// Offset 4
- uint start = metadata.VirtualAddress - section.VirtualAddress + ReadUInt32 (); // relative to the section start
+ uint offset = metadata.VirtualAddress - section.VirtualAddress + ReadUInt32 (); // relative to the section start
// Size 4
uint size = ReadUInt32 ();
+ var data = ReadHeapData (offset, size);
+
var name = ReadAlignedString (16);
switch (name) {
case "#~":
case "#-":
- image.TableHeap = new TableHeap (section, start, size);
+ image.TableHeap = new TableHeap (data);
+ table_heap_offset = offset;
break;
case "#Strings":
- image.StringHeap = new StringHeap (section, start, size);
+ image.StringHeap = new StringHeap (data);
break;
case "#Blob":
- image.BlobHeap = new BlobHeap (section, start, size);
+ image.BlobHeap = new BlobHeap (data);
break;
case "#GUID":
- image.GuidHeap = new GuidHeap (section, start, size);
+ image.GuidHeap = new GuidHeap (data);
break;
case "#US":
- image.UserStringHeap = new UserStringHeap (section, start, size);
+ image.UserStringHeap = new UserStringHeap (data);
break;
}
}
+ byte [] ReadHeapData (uint offset, uint size)
+ {
+ var position = BaseStream.Position;
+ MoveTo (offset + image.MetadataSection.PointerToRawData);
+ var data = ReadBytes ((int) size);
+ BaseStream.Position = position;
+
+ return data;
+ }
+
void ReadTableHeap ()
{
var heap = image.TableHeap;
- uint start = heap.Section.PointerToRawData;
-
- MoveTo (heap.Offset + start);
+ MoveTo (table_heap_offset + image.MetadataSection.PointerToRawData);
// Reserved 4
// MajorVersion 1
@@ -447,7 +434,7 @@ namespace Mono.Cecil.PE {
void ComputeTableInformations ()
{
- uint offset = (uint) BaseStream.Position - image.MetadataSection.PointerToRawData; // header
+ uint offset = (uint) BaseStream.Position - table_heap_offset - image.MetadataSection.PointerToRawData; // header
int stridx_size = image.StringHeap.IndexSize;
int blobidx_size = image.BlobHeap != null ? image.BlobHeap.IndexSize : 2;
diff --git a/Mono.Cecil.PE/ImageWriter.cs b/Mono.Cecil.PE/ImageWriter.cs
index 6f921d9..b5cdbe9 100644
--- a/Mono.Cecil.PE/ImageWriter.cs
+++ b/Mono.Cecil.PE/ImageWriter.cs
@@ -95,9 +95,8 @@ namespace Mono.Cecil.PE {
if (rsrc == null)
return;
- var raw_resources = new byte [rsrc.Data.Length];
- Buffer.BlockCopy (rsrc.Data, 0, raw_resources, 0, rsrc.Data.Length);
- win32_resources = new ByteBuffer (raw_resources);
+ var reader = module.Image.GetReaderAt (rsrc.VirtualAddress);
+ win32_resources = new ByteBuffer (reader.ReadBytes ((int) rsrc.SizeOfRawData));
}
Section GetImageResourceSection ()
diff --git a/Mono.Cecil.PE/Section.cs b/Mono.Cecil.PE/Section.cs
index 6a4c7ba..938d1a2 100644
--- a/Mono.Cecil.PE/Section.cs
+++ b/Mono.Cecil.PE/Section.cs
@@ -38,6 +38,5 @@ namespace Mono.Cecil.PE {
public uint VirtualSize;
public uint SizeOfRawData;
public uint PointerToRawData;
- public byte [] Data;
}
}