PageRenderTime 40ms CodeModel.GetById 21ms app.highlight 15ms RepoModel.GetById 1ms app.codeStats 0ms

/Mono.Cecil.PE/Image.cs

http://github.com/jbevain/cecil
C# | 170 lines | 127 code | 34 blank | 9 comment | 20 complexity | 38292a70530ac694fc01d67b171749a6 MD5 | raw file
  1//
  2// Author:
  3//   Jb Evain (jbevain@gmail.com)
  4//
  5// Copyright (c) 2008 - 2015 Jb Evain
  6// Copyright (c) 2008 - 2011 Novell, Inc.
  7//
  8// Licensed under the MIT/X11 license.
  9//
 10
 11using System;
 12using System.IO;
 13
 14using Mono.Cecil.Cil;
 15using Mono.Cecil.Metadata;
 16using Mono.Collections.Generic;
 17
 18using RVA = System.UInt32;
 19
 20namespace Mono.Cecil.PE {
 21
 22	sealed class Image : IDisposable {
 23
 24		public Disposable<Stream> Stream;
 25		public string FileName;
 26
 27		public ModuleKind Kind;
 28		public string RuntimeVersion;
 29		public TargetArchitecture Architecture;
 30		public ModuleCharacteristics Characteristics;
 31		public ushort LinkerVersion;
 32		public ushort SubSystemMajor;
 33		public ushort SubSystemMinor;
 34
 35		public ImageDebugHeader DebugHeader;
 36
 37		public Section [] Sections;
 38
 39		public Section MetadataSection;
 40
 41		public uint EntryPointToken;
 42		public uint Timestamp;
 43		public ModuleAttributes Attributes;
 44
 45		public DataDirectory Win32Resources;
 46		public DataDirectory Debug;
 47		public DataDirectory Resources;
 48		public DataDirectory StrongName;
 49
 50		public StringHeap StringHeap;
 51		public BlobHeap BlobHeap;
 52		public UserStringHeap UserStringHeap;
 53		public GuidHeap GuidHeap;
 54		public TableHeap TableHeap;
 55		public PdbHeap PdbHeap;
 56
 57		readonly int [] coded_index_sizes = new int [14];
 58
 59		readonly Func<Table, int> counter;
 60
 61		public Image ()
 62		{
 63			counter = GetTableLength;
 64		}
 65
 66		public bool HasTable (Table table)
 67		{
 68			return GetTableLength (table) > 0;
 69		}
 70
 71		public int GetTableLength (Table table)
 72		{
 73			return (int) TableHeap [table].Length;
 74		}
 75
 76		public int GetTableIndexSize (Table table)
 77		{
 78			return GetTableLength (table) < 65536 ? 2 : 4;
 79		}
 80
 81		public int GetCodedIndexSize (CodedIndex coded_index)
 82		{
 83			var index = (int) coded_index;
 84			var size = coded_index_sizes [index];
 85			if (size != 0)
 86				return size;
 87
 88			return coded_index_sizes [index] = coded_index.GetSize (counter);
 89		}
 90
 91		public uint ResolveVirtualAddress (RVA rva)
 92		{
 93			var section = GetSectionAtVirtualAddress (rva);
 94			if (section == null)
 95				throw new ArgumentOutOfRangeException ();
 96
 97			return ResolveVirtualAddressInSection (rva, section);
 98		}
 99
100		public uint ResolveVirtualAddressInSection (RVA rva, Section section)
101		{
102			return rva + section.PointerToRawData - section.VirtualAddress;
103		}
104
105		public Section GetSection (string name)
106		{
107			var sections = this.Sections;
108			for (int i = 0; i < sections.Length; i++) {
109				var section = sections [i];
110				if (section.Name == name)
111					return section;
112			}
113
114			return null;
115		}
116
117		public Section GetSectionAtVirtualAddress (RVA rva)
118		{
119			var sections = this.Sections;
120			for (int i = 0; i < sections.Length; i++) {
121				var section = sections [i];
122				if (rva >= section.VirtualAddress && rva < section.VirtualAddress + section.SizeOfRawData)
123					return section;
124			}
125
126			return null;
127		}
128
129		BinaryStreamReader GetReaderAt (RVA rva)
130		{
131			var section = GetSectionAtVirtualAddress (rva);
132			if (section == null)
133				return null;
134
135			var reader = new BinaryStreamReader (Stream.value);
136			reader.MoveTo (ResolveVirtualAddressInSection (rva, section));
137			return reader;
138		}
139
140		public TRet GetReaderAt<TItem, TRet> (RVA rva, TItem item, Func<TItem, BinaryStreamReader, TRet> read) where TRet : class
141		{
142			var position = Stream.value.Position;
143			try {
144				var reader = GetReaderAt (rva);
145				if (reader == null)
146					return null;
147
148				return read (item, reader);
149			} finally {
150				Stream.value.Position = position;
151			}
152		}
153
154		public bool HasDebugTables ()
155		{
156			return HasTable (Table.Document)
157				|| HasTable (Table.MethodDebugInformation)
158				|| HasTable (Table.LocalScope)
159				|| HasTable (Table.LocalVariable)
160				|| HasTable (Table.LocalConstant)
161				|| HasTable (Table.StateMachineMethod)
162				|| HasTable (Table.CustomDebugInformation);
163		}
164
165		public void Dispose ()
166		{
167			Stream.Dispose ();
168		}
169	}
170}