// // Image.cs // // Author: // Jb Evain (jbevain@gmail.com) // // (C) 2005 - 2007 Jb Evain // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // namespace Mono.Cecil.Binary { using System; using System.IO; using Mono.Cecil.Metadata; internal sealed class Image : IBinaryVisitable { DOSHeader m_dosHeader; PEFileHeader m_peFileHeader; PEOptionalHeader m_peOptionalHeader; SectionCollection m_sections; Section m_textSection; ImportAddressTable m_importAddressTable; CLIHeader m_cliHeader; ImportTable m_importTable; ImportLookupTable m_importLookupTable; HintNameTable m_hintNameTable; ExportTable m_exportTable; DebugHeader m_debugHeader; MetadataRoot m_mdRoot; ResourceDirectoryTable m_rsrcRoot; FileInfo m_img; public DOSHeader DOSHeader { get { return m_dosHeader; } } public PEFileHeader PEFileHeader { get { return m_peFileHeader; } } public PEOptionalHeader PEOptionalHeader { get { return m_peOptionalHeader; } } public SectionCollection Sections { get { return m_sections; } } public Section TextSection { get { return m_textSection; } set { m_textSection = value; } } public ImportAddressTable ImportAddressTable { get { return m_importAddressTable; } } public CLIHeader CLIHeader { get { return m_cliHeader; } set { m_cliHeader = value; } } public DebugHeader DebugHeader { get { return m_debugHeader; } set { m_debugHeader = value; } } public MetadataRoot MetadataRoot { get { return m_mdRoot; } } public ImportTable ImportTable { get { return m_importTable; } } public ImportLookupTable ImportLookupTable { get { return m_importLookupTable; } } public HintNameTable HintNameTable { get { return m_hintNameTable; } } public ExportTable ExportTable { get { return m_exportTable; } set { m_exportTable = value; } } internal ResourceDirectoryTable ResourceDirectoryRoot { get { return m_rsrcRoot; } set { m_rsrcRoot = value; } } public FileInfo FileInformation { get { return m_img; } } internal Image () { m_dosHeader = new DOSHeader (); m_peFileHeader = new PEFileHeader (); m_peOptionalHeader = new PEOptionalHeader (); m_sections = new SectionCollection (); m_importAddressTable = new ImportAddressTable (); m_importTable = new ImportTable (); m_importLookupTable = new ImportLookupTable (); m_hintNameTable = new HintNameTable (); m_mdRoot = new MetadataRoot (this); } internal Image (FileInfo img) : this () { m_img = img; } public long ResolveVirtualAddress (RVA rva) { foreach (Section sect in this.Sections) { if (rva >= sect.VirtualAddress && rva < sect.VirtualAddress + sect.SizeOfRawData) return rva + sect.PointerToRawData - sect.VirtualAddress; } throw new ArgumentOutOfRangeException ("Cannot map the rva to any section"); } internal Section GetSectionAtVirtualAddress (RVA rva) { foreach (Section sect in this.Sections) { if (rva >= sect.VirtualAddress && rva < sect.VirtualAddress + sect.SizeOfRawData) { return sect; } } return null; } public BinaryReader GetReaderAtVirtualAddress (RVA rva) { Section sect = GetSectionAtVirtualAddress (rva); if (sect == null) return null; BinaryReader br = new BinaryReader (new MemoryStream (sect.Data)); br.BaseStream.Position = rva - sect.VirtualAddress; return br; } public void AddDebugHeader () { m_debugHeader = new DebugHeader (); m_debugHeader.SetDefaultValues (); } internal void SetFileInfo (FileInfo file) { m_img = file; } public void Accept (IBinaryVisitor visitor) { visitor.VisitImage (this); m_dosHeader.Accept (visitor); m_peFileHeader.Accept (visitor); m_peOptionalHeader.Accept (visitor); m_sections.Accept (visitor); m_importAddressTable.Accept (visitor); AcceptIfNotNull (m_cliHeader, visitor); AcceptIfNotNull (m_debugHeader, visitor); m_importTable.Accept (visitor); m_importLookupTable.Accept (visitor); m_hintNameTable.Accept (visitor); AcceptIfNotNull (m_exportTable, visitor); visitor.TerminateImage (this); } static void AcceptIfNotNull (IBinaryVisitable visitable, IBinaryVisitor visitor) { if (visitable == null) return; visitable.Accept (visitor); } public static Image CreateImage () { Image img = new Image (); ImageInitializer init = new ImageInitializer (img); img.Accept (init); return img; } public static Image GetImage (string file) { return ImageReader.Read (file).Image; } public static Image GetImage (byte [] image) { return ImageReader.Read (image).Image; } public static Image GetImage (Stream stream) { return ImageReader.Read (stream).Image; } } }