Image.cs 3.8 KB

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