Jo Shields a575963da9 Imported Upstream version 3.6.0
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
2014-08-13 10:39:27 +01:00

244 lines
5.7 KiB
C#

//
// 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;
}
}
}