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

Image.cs « Mono.Cecil.PE - github.com/mono/cecil.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 97e69c0101b71f61ef04889ccda2a61691e641ed (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
//
// 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;
using System.IO;

using Mono.Cecil.Cil;
using Mono.Cecil.Metadata;
using Mono.Collections.Generic;

using RVA = System.UInt32;

namespace Mono.Cecil.PE {

	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;

		readonly int [] coded_index_sizes = new int [14];

		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)
		{
			var index = (int) coded_index;
			var size = coded_index_sizes [index];
			if (size != 0)
				return size;

			return coded_index_sizes [index] = coded_index.GetSize (counter);
		}

		public uint ResolveVirtualAddress (RVA rva)
		{
			var 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)
		{
			var sections = this.Sections;
			for (int i = 0; i < sections.Length; i++) {
				var section = sections [i];
				if (section.Name == name)
					return section;
			}

			return null;
		}

		public Section GetSectionAtVirtualAddress (RVA rva)
		{
			var sections = this.Sections;
			for (int i = 0; i < sections.Length; i++) {
				var section = sections [i];
				if (rva >= section.VirtualAddress && rva < section.VirtualAddress + section.SizeOfRawData)
					return section;
			}

			return null;
		}

		BinaryStreamReader GetReaderAt (RVA rva)
		{
			var section = GetSectionAtVirtualAddress (rva);
			if (section == null)
				return null;

			var reader = new BinaryStreamReader (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
		{
			var position = Stream.value.Position;
			try {
				var 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 ();
		}
	}
}