/Mono.Cecil.PE/ImageReader.cs

http://github.com/jbevain/cecil · C# · 793 lines · 560 code · 126 blank · 107 comment · 50 complexity · d686551c2e1bb0a02d4e5356741f1a6a 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. 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 ImageReader : BinaryStreamReader {
  18. readonly Image image;
  19. DataDirectory cli;
  20. DataDirectory metadata;
  21. uint table_heap_offset;
  22. public ImageReader (Disposable<Stream> stream, string file_name)
  23. : base (stream.value)
  24. {
  25. image = new Image ();
  26. image.Stream = stream;
  27. image.FileName = file_name;
  28. }
  29. void MoveTo (DataDirectory directory)
  30. {
  31. BaseStream.Position = image.ResolveVirtualAddress (directory.VirtualAddress);
  32. }
  33. void ReadImage ()
  34. {
  35. if (BaseStream.Length < 128)
  36. throw new BadImageFormatException ();
  37. // - DOSHeader
  38. // PE 2
  39. // Start 58
  40. // Lfanew 4
  41. // End 64
  42. if (ReadUInt16 () != 0x5a4d)
  43. throw new BadImageFormatException ();
  44. Advance (58);
  45. MoveTo (ReadUInt32 ());
  46. if (ReadUInt32 () != 0x00004550)
  47. throw new BadImageFormatException ();
  48. // - PEFileHeader
  49. // Machine 2
  50. image.Architecture = ReadArchitecture ();
  51. // NumberOfSections 2
  52. ushort sections = ReadUInt16 ();
  53. // TimeDateStamp 4
  54. image.Timestamp = ReadUInt32 ();
  55. // PointerToSymbolTable 4
  56. // NumberOfSymbols 4
  57. // OptionalHeaderSize 2
  58. Advance (10);
  59. // Characteristics 2
  60. ushort characteristics = ReadUInt16 ();
  61. ushort subsystem, dll_characteristics;
  62. ReadOptionalHeaders (out subsystem, out dll_characteristics);
  63. ReadSections (sections);
  64. ReadCLIHeader ();
  65. ReadMetadata ();
  66. ReadDebugHeader ();
  67. image.Kind = GetModuleKind (characteristics, subsystem);
  68. image.Characteristics = (ModuleCharacteristics) dll_characteristics;
  69. }
  70. TargetArchitecture ReadArchitecture ()
  71. {
  72. return (TargetArchitecture) ReadUInt16 ();
  73. }
  74. static ModuleKind GetModuleKind (ushort characteristics, ushort subsystem)
  75. {
  76. if ((characteristics & 0x2000) != 0) // ImageCharacteristics.Dll
  77. return ModuleKind.Dll;
  78. if (subsystem == 0x2 || subsystem == 0x9) // SubSystem.WindowsGui || SubSystem.WindowsCeGui
  79. return ModuleKind.Windows;
  80. return ModuleKind.Console;
  81. }
  82. void ReadOptionalHeaders (out ushort subsystem, out ushort dll_characteristics)
  83. {
  84. // - PEOptionalHeader
  85. // - StandardFieldsHeader
  86. // Magic 2
  87. bool pe64 = ReadUInt16 () == 0x20b;
  88. // pe32 || pe64
  89. image.LinkerVersion = ReadUInt16 ();
  90. // CodeSize 4
  91. // InitializedDataSize 4
  92. // UninitializedDataSize4
  93. // EntryPointRVA 4
  94. // BaseOfCode 4
  95. // BaseOfData 4 || 0
  96. // - NTSpecificFieldsHeader
  97. // ImageBase 4 || 8
  98. // SectionAlignment 4
  99. // FileAlignement 4
  100. // OSMajor 2
  101. // OSMinor 2
  102. // UserMajor 2
  103. // UserMinor 2
  104. // SubSysMajor 2
  105. // SubSysMinor 2
  106. Advance(44);
  107. image.SubSystemMajor = ReadUInt16 ();
  108. image.SubSystemMinor = ReadUInt16 ();
  109. // Reserved 4
  110. // ImageSize 4
  111. // HeaderSize 4
  112. // FileChecksum 4
  113. Advance (16);
  114. // SubSystem 2
  115. subsystem = ReadUInt16 ();
  116. // DLLFlags 2
  117. dll_characteristics = ReadUInt16 ();
  118. // StackReserveSize 4 || 8
  119. // StackCommitSize 4 || 8
  120. // HeapReserveSize 4 || 8
  121. // HeapCommitSize 4 || 8
  122. // LoaderFlags 4
  123. // NumberOfDataDir 4
  124. // - DataDirectoriesHeader
  125. // ExportTable 8
  126. // ImportTable 8
  127. Advance (pe64 ? 56 : 40);
  128. // ResourceTable 8
  129. image.Win32Resources = ReadDataDirectory ();
  130. // ExceptionTable 8
  131. // CertificateTable 8
  132. // BaseRelocationTable 8
  133. Advance (24);
  134. // Debug 8
  135. image.Debug = ReadDataDirectory ();
  136. // Copyright 8
  137. // GlobalPtr 8
  138. // TLSTable 8
  139. // LoadConfigTable 8
  140. // BoundImport 8
  141. // IAT 8
  142. // DelayImportDescriptor8
  143. Advance (56);
  144. // CLIHeader 8
  145. cli = ReadDataDirectory ();
  146. if (cli.IsZero)
  147. throw new BadImageFormatException ();
  148. // Reserved 8
  149. Advance (8);
  150. }
  151. string ReadAlignedString (int length)
  152. {
  153. int read = 0;
  154. var buffer = new char [length];
  155. while (read < length) {
  156. var current = ReadByte ();
  157. if (current == 0)
  158. break;
  159. buffer [read++] = (char) current;
  160. }
  161. Advance (-1 + ((read + 4) & ~3) - read);
  162. return new string (buffer, 0, read);
  163. }
  164. string ReadZeroTerminatedString (int length)
  165. {
  166. int read = 0;
  167. var buffer = new char [length];
  168. var bytes = ReadBytes (length);
  169. while (read < length) {
  170. var current = bytes [read];
  171. if (current == 0)
  172. break;
  173. buffer [read++] = (char) current;
  174. }
  175. return new string (buffer, 0, read);
  176. }
  177. void ReadSections (ushort count)
  178. {
  179. var sections = new Section [count];
  180. for (int i = 0; i < count; i++) {
  181. var section = new Section ();
  182. // Name
  183. section.Name = ReadZeroTerminatedString (8);
  184. // VirtualSize 4
  185. Advance (4);
  186. // VirtualAddress 4
  187. section.VirtualAddress = ReadUInt32 ();
  188. // SizeOfRawData 4
  189. section.SizeOfRawData = ReadUInt32 ();
  190. // PointerToRawData 4
  191. section.PointerToRawData = ReadUInt32 ();
  192. // PointerToRelocations 4
  193. // PointerToLineNumbers 4
  194. // NumberOfRelocations 2
  195. // NumberOfLineNumbers 2
  196. // Characteristics 4
  197. Advance (16);
  198. sections [i] = section;
  199. }
  200. image.Sections = sections;
  201. }
  202. void ReadCLIHeader ()
  203. {
  204. MoveTo (cli);
  205. // - CLIHeader
  206. // Cb 4
  207. // MajorRuntimeVersion 2
  208. // MinorRuntimeVersion 2
  209. Advance (8);
  210. // Metadata 8
  211. metadata = ReadDataDirectory ();
  212. // Flags 4
  213. image.Attributes = (ModuleAttributes) ReadUInt32 ();
  214. // EntryPointToken 4
  215. image.EntryPointToken = ReadUInt32 ();
  216. // Resources 8
  217. image.Resources = ReadDataDirectory ();
  218. // StrongNameSignature 8
  219. image.StrongName = ReadDataDirectory ();
  220. // CodeManagerTable 8
  221. // VTableFixups 8
  222. // ExportAddressTableJumps 8
  223. // ManagedNativeHeader 8
  224. }
  225. void ReadMetadata ()
  226. {
  227. MoveTo (metadata);
  228. if (ReadUInt32 () != 0x424a5342)
  229. throw new BadImageFormatException ();
  230. // MajorVersion 2
  231. // MinorVersion 2
  232. // Reserved 4
  233. Advance (8);
  234. image.RuntimeVersion = ReadZeroTerminatedString (ReadInt32 ());
  235. // Flags 2
  236. Advance (2);
  237. var streams = ReadUInt16 ();
  238. var section = image.GetSectionAtVirtualAddress (metadata.VirtualAddress);
  239. if (section == null)
  240. throw new BadImageFormatException ();
  241. image.MetadataSection = section;
  242. for (int i = 0; i < streams; i++)
  243. ReadMetadataStream (section);
  244. if (image.PdbHeap != null)
  245. ReadPdbHeap ();
  246. if (image.TableHeap != null)
  247. ReadTableHeap ();
  248. }
  249. void ReadDebugHeader ()
  250. {
  251. if (image.Debug.IsZero) {
  252. image.DebugHeader = new ImageDebugHeader (Empty<ImageDebugHeaderEntry>.Array);
  253. return;
  254. }
  255. MoveTo (image.Debug);
  256. var entries = new ImageDebugHeaderEntry [(int) image.Debug.Size / ImageDebugDirectory.Size];
  257. for (int i = 0; i < entries.Length; i++) {
  258. var directory = new ImageDebugDirectory {
  259. Characteristics = ReadInt32 (),
  260. TimeDateStamp = ReadInt32 (),
  261. MajorVersion = ReadInt16 (),
  262. MinorVersion = ReadInt16 (),
  263. Type = (ImageDebugType) ReadInt32 (),
  264. SizeOfData = ReadInt32 (),
  265. AddressOfRawData = ReadInt32 (),
  266. PointerToRawData = ReadInt32 (),
  267. };
  268. if (directory.PointerToRawData == 0 || directory.SizeOfData < 0) {
  269. entries [i] = new ImageDebugHeaderEntry (directory, Empty<byte>.Array);
  270. continue;
  271. }
  272. var position = Position;
  273. try {
  274. MoveTo ((uint) directory.PointerToRawData);
  275. var data = ReadBytes (directory.SizeOfData);
  276. entries [i] = new ImageDebugHeaderEntry (directory, data);
  277. } finally {
  278. Position = position;
  279. }
  280. }
  281. image.DebugHeader = new ImageDebugHeader (entries);
  282. }
  283. void ReadMetadataStream (Section section)
  284. {
  285. // Offset 4
  286. uint offset = metadata.VirtualAddress - section.VirtualAddress + ReadUInt32 (); // relative to the section start
  287. // Size 4
  288. uint size = ReadUInt32 ();
  289. var data = ReadHeapData (offset, size);
  290. var name = ReadAlignedString (16);
  291. switch (name) {
  292. case "#~":
  293. case "#-":
  294. image.TableHeap = new TableHeap (data);
  295. table_heap_offset = offset;
  296. break;
  297. case "#Strings":
  298. image.StringHeap = new StringHeap (data);
  299. break;
  300. case "#Blob":
  301. image.BlobHeap = new BlobHeap (data);
  302. break;
  303. case "#GUID":
  304. image.GuidHeap = new GuidHeap (data);
  305. break;
  306. case "#US":
  307. image.UserStringHeap = new UserStringHeap (data);
  308. break;
  309. case "#Pdb":
  310. image.PdbHeap = new PdbHeap (data);
  311. break;
  312. }
  313. }
  314. byte [] ReadHeapData (uint offset, uint size)
  315. {
  316. var position = BaseStream.Position;
  317. MoveTo (offset + image.MetadataSection.PointerToRawData);
  318. var data = ReadBytes ((int) size);
  319. BaseStream.Position = position;
  320. return data;
  321. }
  322. void ReadTableHeap ()
  323. {
  324. var heap = image.TableHeap;
  325. MoveTo (table_heap_offset + image.MetadataSection.PointerToRawData);
  326. // Reserved 4
  327. // MajorVersion 1
  328. // MinorVersion 1
  329. Advance (6);
  330. // HeapSizes 1
  331. var sizes = ReadByte ();
  332. // Reserved2 1
  333. Advance (1);
  334. // Valid 8
  335. heap.Valid = ReadInt64 ();
  336. // Sorted 8
  337. heap.Sorted = ReadInt64 ();
  338. if (image.PdbHeap != null) {
  339. for (int i = 0; i < Mixin.TableCount; i++) {
  340. if (!image.PdbHeap.HasTable ((Table) i))
  341. continue;
  342. heap.Tables [i].Length = image.PdbHeap.TypeSystemTableRows [i];
  343. }
  344. }
  345. for (int i = 0; i < Mixin.TableCount; i++) {
  346. if (!heap.HasTable ((Table) i))
  347. continue;
  348. heap.Tables [i].Length = ReadUInt32 ();
  349. }
  350. SetIndexSize (image.StringHeap, sizes, 0x1);
  351. SetIndexSize (image.GuidHeap, sizes, 0x2);
  352. SetIndexSize (image.BlobHeap, sizes, 0x4);
  353. ComputeTableInformations ();
  354. }
  355. static void SetIndexSize (Heap heap, uint sizes, byte flag)
  356. {
  357. if (heap == null)
  358. return;
  359. heap.IndexSize = (sizes & flag) > 0 ? 4 : 2;
  360. }
  361. int GetTableIndexSize (Table table)
  362. {
  363. return image.GetTableIndexSize (table);
  364. }
  365. int GetCodedIndexSize (CodedIndex index)
  366. {
  367. return image.GetCodedIndexSize (index);
  368. }
  369. void ComputeTableInformations ()
  370. {
  371. uint offset = (uint) BaseStream.Position - table_heap_offset - image.MetadataSection.PointerToRawData; // header
  372. int stridx_size = image.StringHeap.IndexSize;
  373. int guididx_size = image.GuidHeap != null ? image.GuidHeap.IndexSize : 2;
  374. int blobidx_size = image.BlobHeap != null ? image.BlobHeap.IndexSize : 2;
  375. var heap = image.TableHeap;
  376. var tables = heap.Tables;
  377. for (int i = 0; i < Mixin.TableCount; i++) {
  378. var table = (Table) i;
  379. if (!heap.HasTable (table))
  380. continue;
  381. int size;
  382. switch (table) {
  383. case Table.Module:
  384. size = 2 // Generation
  385. + stridx_size // Name
  386. + (guididx_size * 3); // Mvid, EncId, EncBaseId
  387. break;
  388. case Table.TypeRef:
  389. size = GetCodedIndexSize (CodedIndex.ResolutionScope) // ResolutionScope
  390. + (stridx_size * 2); // Name, Namespace
  391. break;
  392. case Table.TypeDef:
  393. size = 4 // Flags
  394. + (stridx_size * 2) // Name, Namespace
  395. + GetCodedIndexSize (CodedIndex.TypeDefOrRef) // BaseType
  396. + GetTableIndexSize (Table.Field) // FieldList
  397. + GetTableIndexSize (Table.Method); // MethodList
  398. break;
  399. case Table.FieldPtr:
  400. size = GetTableIndexSize (Table.Field); // Field
  401. break;
  402. case Table.Field:
  403. size = 2 // Flags
  404. + stridx_size // Name
  405. + blobidx_size; // Signature
  406. break;
  407. case Table.MethodPtr:
  408. size = GetTableIndexSize (Table.Method); // Method
  409. break;
  410. case Table.Method:
  411. size = 8 // Rva 4, ImplFlags 2, Flags 2
  412. + stridx_size // Name
  413. + blobidx_size // Signature
  414. + GetTableIndexSize (Table.Param); // ParamList
  415. break;
  416. case Table.ParamPtr:
  417. size = GetTableIndexSize (Table.Param); // Param
  418. break;
  419. case Table.Param:
  420. size = 4 // Flags 2, Sequence 2
  421. + stridx_size; // Name
  422. break;
  423. case Table.InterfaceImpl:
  424. size = GetTableIndexSize (Table.TypeDef) // Class
  425. + GetCodedIndexSize (CodedIndex.TypeDefOrRef); // Interface
  426. break;
  427. case Table.MemberRef:
  428. size = GetCodedIndexSize (CodedIndex.MemberRefParent) // Class
  429. + stridx_size // Name
  430. + blobidx_size; // Signature
  431. break;
  432. case Table.Constant:
  433. size = 2 // Type
  434. + GetCodedIndexSize (CodedIndex.HasConstant) // Parent
  435. + blobidx_size; // Value
  436. break;
  437. case Table.CustomAttribute:
  438. size = GetCodedIndexSize (CodedIndex.HasCustomAttribute) // Parent
  439. + GetCodedIndexSize (CodedIndex.CustomAttributeType) // Type
  440. + blobidx_size; // Value
  441. break;
  442. case Table.FieldMarshal:
  443. size = GetCodedIndexSize (CodedIndex.HasFieldMarshal) // Parent
  444. + blobidx_size; // NativeType
  445. break;
  446. case Table.DeclSecurity:
  447. size = 2 // Action
  448. + GetCodedIndexSize (CodedIndex.HasDeclSecurity) // Parent
  449. + blobidx_size; // PermissionSet
  450. break;
  451. case Table.ClassLayout:
  452. size = 6 // PackingSize 2, ClassSize 4
  453. + GetTableIndexSize (Table.TypeDef); // Parent
  454. break;
  455. case Table.FieldLayout:
  456. size = 4 // Offset
  457. + GetTableIndexSize (Table.Field); // Field
  458. break;
  459. case Table.StandAloneSig:
  460. size = blobidx_size; // Signature
  461. break;
  462. case Table.EventMap:
  463. size = GetTableIndexSize (Table.TypeDef) // Parent
  464. + GetTableIndexSize (Table.Event); // EventList
  465. break;
  466. case Table.EventPtr:
  467. size = GetTableIndexSize (Table.Event); // Event
  468. break;
  469. case Table.Event:
  470. size = 2 // Flags
  471. + stridx_size // Name
  472. + GetCodedIndexSize (CodedIndex.TypeDefOrRef); // EventType
  473. break;
  474. case Table.PropertyMap:
  475. size = GetTableIndexSize (Table.TypeDef) // Parent
  476. + GetTableIndexSize (Table.Property); // PropertyList
  477. break;
  478. case Table.PropertyPtr:
  479. size = GetTableIndexSize (Table.Property); // Property
  480. break;
  481. case Table.Property:
  482. size = 2 // Flags
  483. + stridx_size // Name
  484. + blobidx_size; // Type
  485. break;
  486. case Table.MethodSemantics:
  487. size = 2 // Semantics
  488. + GetTableIndexSize (Table.Method) // Method
  489. + GetCodedIndexSize (CodedIndex.HasSemantics); // Association
  490. break;
  491. case Table.MethodImpl:
  492. size = GetTableIndexSize (Table.TypeDef) // Class
  493. + GetCodedIndexSize (CodedIndex.MethodDefOrRef) // MethodBody
  494. + GetCodedIndexSize (CodedIndex.MethodDefOrRef); // MethodDeclaration
  495. break;
  496. case Table.ModuleRef:
  497. size = stridx_size; // Name
  498. break;
  499. case Table.TypeSpec:
  500. size = blobidx_size; // Signature
  501. break;
  502. case Table.ImplMap:
  503. size = 2 // MappingFlags
  504. + GetCodedIndexSize (CodedIndex.MemberForwarded) // MemberForwarded
  505. + stridx_size // ImportName
  506. + GetTableIndexSize (Table.ModuleRef); // ImportScope
  507. break;
  508. case Table.FieldRVA:
  509. size = 4 // RVA
  510. + GetTableIndexSize (Table.Field); // Field
  511. break;
  512. case Table.EncLog:
  513. size = 8;
  514. break;
  515. case Table.EncMap:
  516. size = 4;
  517. break;
  518. case Table.Assembly:
  519. size = 16 // HashAlgId 4, Version 4 * 2, Flags 4
  520. + blobidx_size // PublicKey
  521. + (stridx_size * 2); // Name, Culture
  522. break;
  523. case Table.AssemblyProcessor:
  524. size = 4; // Processor
  525. break;
  526. case Table.AssemblyOS:
  527. size = 12; // Platform 4, Version 2 * 4
  528. break;
  529. case Table.AssemblyRef:
  530. size = 12 // Version 2 * 4 + Flags 4
  531. + (blobidx_size * 2) // PublicKeyOrToken, HashValue
  532. + (stridx_size * 2); // Name, Culture
  533. break;
  534. case Table.AssemblyRefProcessor:
  535. size = 4 // Processor
  536. + GetTableIndexSize (Table.AssemblyRef); // AssemblyRef
  537. break;
  538. case Table.AssemblyRefOS:
  539. size = 12 // Platform 4, Version 2 * 4
  540. + GetTableIndexSize (Table.AssemblyRef); // AssemblyRef
  541. break;
  542. case Table.File:
  543. size = 4 // Flags
  544. + stridx_size // Name
  545. + blobidx_size; // HashValue
  546. break;
  547. case Table.ExportedType:
  548. size = 8 // Flags 4, TypeDefId 4
  549. + (stridx_size * 2) // Name, Namespace
  550. + GetCodedIndexSize (CodedIndex.Implementation); // Implementation
  551. break;
  552. case Table.ManifestResource:
  553. size = 8 // Offset, Flags
  554. + stridx_size // Name
  555. + GetCodedIndexSize (CodedIndex.Implementation); // Implementation
  556. break;
  557. case Table.NestedClass:
  558. size = GetTableIndexSize (Table.TypeDef) // NestedClass
  559. + GetTableIndexSize (Table.TypeDef); // EnclosingClass
  560. break;
  561. case Table.GenericParam:
  562. size = 4 // Number, Flags
  563. + GetCodedIndexSize (CodedIndex.TypeOrMethodDef) // Owner
  564. + stridx_size; // Name
  565. break;
  566. case Table.MethodSpec:
  567. size = GetCodedIndexSize (CodedIndex.MethodDefOrRef) // Method
  568. + blobidx_size; // Instantiation
  569. break;
  570. case Table.GenericParamConstraint:
  571. size = GetTableIndexSize (Table.GenericParam) // Owner
  572. + GetCodedIndexSize (CodedIndex.TypeDefOrRef); // Constraint
  573. break;
  574. case Table.Document:
  575. size = blobidx_size // Name
  576. + guididx_size // HashAlgorithm
  577. + blobidx_size // Hash
  578. + guididx_size; // Language
  579. break;
  580. case Table.MethodDebugInformation:
  581. size = GetTableIndexSize (Table.Document) // Document
  582. + blobidx_size; // SequencePoints
  583. break;
  584. case Table.LocalScope:
  585. size = GetTableIndexSize (Table.Method) // Method
  586. + GetTableIndexSize (Table.ImportScope) // ImportScope
  587. + GetTableIndexSize (Table.LocalVariable) // VariableList
  588. + GetTableIndexSize (Table.LocalConstant) // ConstantList
  589. + 4 * 2; // StartOffset, Length
  590. break;
  591. case Table.LocalVariable:
  592. size = 2 // Attributes
  593. + 2 // Index
  594. + stridx_size; // Name
  595. break;
  596. case Table.LocalConstant:
  597. size = stridx_size // Name
  598. + blobidx_size; // Signature
  599. break;
  600. case Table.ImportScope:
  601. size = GetTableIndexSize (Table.ImportScope) // Parent
  602. + blobidx_size;
  603. break;
  604. case Table.StateMachineMethod:
  605. size = GetTableIndexSize (Table.Method) // MoveNextMethod
  606. + GetTableIndexSize (Table.Method); // KickOffMethod
  607. break;
  608. case Table.CustomDebugInformation:
  609. size = GetCodedIndexSize (CodedIndex.HasCustomDebugInformation) // Parent
  610. + guididx_size // Kind
  611. + blobidx_size; // Value
  612. break;
  613. default:
  614. throw new NotSupportedException ();
  615. }
  616. tables [i].RowSize = (uint) size;
  617. tables [i].Offset = offset;
  618. offset += (uint) size * tables [i].Length;
  619. }
  620. }
  621. void ReadPdbHeap ()
  622. {
  623. var heap = image.PdbHeap;
  624. var buffer = new ByteBuffer (heap.data);
  625. heap.Id = buffer.ReadBytes (20);
  626. heap.EntryPoint = buffer.ReadUInt32 ();
  627. heap.TypeSystemTables = buffer.ReadInt64 ();
  628. heap.TypeSystemTableRows = new uint [Mixin.TableCount];
  629. for (int i = 0; i < Mixin.TableCount; i++) {
  630. var table = (Table) i;
  631. if (!heap.HasTable (table))
  632. continue;
  633. heap.TypeSystemTableRows [i] = buffer.ReadUInt32 ();
  634. }
  635. }
  636. public static Image ReadImage (Disposable<Stream> stream, string file_name)
  637. {
  638. try {
  639. var reader = new ImageReader (stream, file_name);
  640. reader.ReadImage ();
  641. return reader.image;
  642. } catch (EndOfStreamException e) {
  643. throw new BadImageFormatException (stream.value.GetFileName (), e);
  644. }
  645. }
  646. public static Image ReadPortablePdb (Disposable<Stream> stream, string file_name)
  647. {
  648. try {
  649. var reader = new ImageReader (stream, file_name);
  650. var length = (uint) stream.value.Length;
  651. reader.image.Sections = new[] {
  652. new Section {
  653. PointerToRawData = 0,
  654. SizeOfRawData = length,
  655. VirtualAddress = 0,
  656. VirtualSize = length,
  657. }
  658. };
  659. reader.metadata = new DataDirectory (0, length);
  660. reader.ReadMetadata ();
  661. return reader.image;
  662. } catch (EndOfStreamException e) {
  663. throw new BadImageFormatException (stream.value.GetFileName (), e);
  664. }
  665. }
  666. }
  667. }