Image.cs 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  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. using System;
  11. using System.IO;
  12. using Mono.Cecil.Cil;
  13. using Mono.Cecil.Metadata;
  14. using Mono.Collections.Generic;
  15. using RVA = System.UInt32;
  16. namespace Mono.Cecil.PE {
  17. sealed class Image : IDisposable {
  18. public Disposable<Stream> Stream;
  19. public string FileName;
  20. public ModuleKind Kind;
  21. public string RuntimeVersion;
  22. public TargetArchitecture Architecture;
  23. public ModuleCharacteristics Characteristics;
  24. public ushort LinkerVersion;
  25. public ImageDebugHeader DebugHeader;
  26. public Section [] Sections;
  27. public Section MetadataSection;
  28. public uint EntryPointToken;
  29. public uint Timestamp;
  30. public ModuleAttributes Attributes;
  31. public DataDirectory Win32Resources;
  32. public DataDirectory Debug;
  33. public DataDirectory Resources;
  34. public DataDirectory StrongName;
  35. public StringHeap StringHeap;
  36. public BlobHeap BlobHeap;
  37. public UserStringHeap UserStringHeap;
  38. public GuidHeap GuidHeap;
  39. public TableHeap TableHeap;
  40. public PdbHeap PdbHeap;
  41. readonly int [] coded_index_sizes = new int [14];
  42. readonly Func<Table, int> counter;
  43. public Image ()
  44. {
  45. counter = GetTableLength;
  46. }
  47. public bool HasTable (Table table)
  48. {
  49. return GetTableLength (table) > 0;
  50. }
  51. public int GetTableLength (Table table)
  52. {
  53. return (int) TableHeap [table].Length;
  54. }
  55. public int GetTableIndexSize (Table table)
  56. {
  57. return GetTableLength (table) < 65536 ? 2 : 4;
  58. }
  59. public int GetCodedIndexSize (CodedIndex coded_index)
  60. {
  61. var index = (int) coded_index;
  62. var size = coded_index_sizes [index];
  63. if (size != 0)
  64. return size;
  65. return coded_index_sizes [index] = coded_index.GetSize (counter);
  66. }
  67. public uint ResolveVirtualAddress (RVA rva)
  68. {
  69. var section = GetSectionAtVirtualAddress (rva);
  70. if (section == null)
  71. throw new ArgumentOutOfRangeException ();
  72. return ResolveVirtualAddressInSection (rva, section);
  73. }
  74. public uint ResolveVirtualAddressInSection (RVA rva, Section section)
  75. {
  76. return rva + section.PointerToRawData - section.VirtualAddress;
  77. }
  78. public Section GetSection (string name)
  79. {
  80. var sections = this.Sections;
  81. for (int i = 0; i < sections.Length; i++) {
  82. var section = sections [i];
  83. if (section.Name == name)
  84. return section;
  85. }
  86. return null;
  87. }
  88. public Section GetSectionAtVirtualAddress (RVA rva)
  89. {
  90. var sections = this.Sections;
  91. for (int i = 0; i < sections.Length; i++) {
  92. var section = sections [i];
  93. if (rva >= section.VirtualAddress && rva < section.VirtualAddress + section.SizeOfRawData)
  94. return section;
  95. }
  96. return null;
  97. }
  98. BinaryStreamReader GetReaderAt (RVA rva)
  99. {
  100. var section = GetSectionAtVirtualAddress (rva);
  101. if (section == null)
  102. return null;
  103. var reader = new BinaryStreamReader (Stream.value);
  104. reader.MoveTo (ResolveVirtualAddressInSection (rva, section));
  105. return reader;
  106. }
  107. public TRet GetReaderAt<TItem, TRet> (RVA rva, TItem item, Func<TItem, BinaryStreamReader, TRet> read) where TRet : class
  108. {
  109. var position = Stream.value.Position;
  110. try {
  111. var reader = GetReaderAt (rva);
  112. if (reader == null)
  113. return null;
  114. return read (item, reader);
  115. } finally {
  116. Stream.value.Position = position;
  117. }
  118. }
  119. public bool HasDebugTables ()
  120. {
  121. return HasTable (Table.Document)
  122. || HasTable (Table.MethodDebugInformation)
  123. || HasTable (Table.LocalScope)
  124. || HasTable (Table.LocalVariable)
  125. || HasTable (Table.LocalConstant)
  126. || HasTable (Table.StateMachineMethod)
  127. || HasTable (Table.CustomDebugInformation);
  128. }
  129. public void Dispose ()
  130. {
  131. Stream.Dispose ();
  132. }
  133. }
  134. }