blob: adf2da08d7581bd7f106ff8cbe5bb160ceb8dc05 [file] [log] [blame] [raw]
//
// StructureDisassembler.cs
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// (C) 2005 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.Disassembler {
using System;
using Mono.Cecil;
class StructureDisassembler : BaseStructureVisitor {
ReflectionDisassembler m_rd;
CilWriter m_writer;
bool m_no_alias = false;
public CilWriter Writer {
get { return m_writer; }
}
public bool NoAlias {
get { return m_no_alias; }
set { m_no_alias = value; }
}
public StructureDisassembler ()
{
m_rd = new ReflectionDisassembler (this);
}
public void DisassembleManifest (AssemblyDefinition asm, CilWriter writer)
{
m_writer = writer;
m_rd.Writer = writer;
VisitModuleReferenceCollection (asm.MainModule.ModuleReferences);
VisitAssemblyNameReferenceCollection (asm.MainModule.AssemblyReferences);
VisitAssemblyDefinition (asm);
VisitModuleDefinition (asm.MainModule);
}
public void DisassembleAssembly (AssemblyDefinition asm, CilWriter writer)
{
writer.WriteLine ("// Mono CIL Disassembler");
writer.WriteLine ("// Prototype using Mono.Cecil");
writer.WriteLine ();
DisassembleManifest (asm, writer);
m_rd.DisassembleModule (asm.MainModule, writer);
}
public override void VisitModuleReferenceCollection (ModuleReferenceCollection modules)
{
foreach (ModuleReference module in modules) {
m_writer.Write (".module extern");
m_writer.WriteLine (Formater.Escape (module.Name));
}
if (modules.Count > 0)
m_writer.WriteLine ();
}
public override void VisitAssemblyNameReferenceCollection (AssemblyNameReferenceCollection references)
{
foreach (AssemblyNameReference reference in references) {
VisitAssemblyNameReference (reference);
m_writer.WriteLine ();
}
}
void AssemblyDetails (AssemblyNameReference name)
{
m_writer.Write (".ver");
if (name.Version == null) {
//m_writer.BaseWriter.WriteLine ("0:0:0:0");
m_writer.WriteLine("0.0.0.0");
} else {
Version ver = name.Version;
//m_writer.BaseWriter.WriteLine ("{0}:{1}:{2}:{3}", ver.Major, ver.Minor, ver.Build, ver.Revision);
m_writer.WriteLine("{0}:{1}:{2}:{3}", ver.Major, ver.Minor, ver.Build, ver.Revision);
}
if (!(name is AssemblyNameDefinition) && name.PublicKeyToken != null && name.PublicKeyToken.Length > 0) {
m_writer.Write (".publickeytoken = ");
m_writer.Write (name.PublicKeyToken);
}
if (name.PublicKey != null && name.PublicKey.Length > 0) {
m_writer.Write (".publickey = ");
m_writer.Write (name.PublicKey);
}
if (name.HashAlgorithm != AssemblyHashAlgorithm.None) {
m_writer.Write (".hash algorithm 0x");
m_writer.BaseWriter.Write(name.HashAlgorithm.ToString ("x"));
m_writer.WriteLine();
}
}
public override void VisitAssemblyNameReference (AssemblyNameReference reference)
{
m_writer.Write (".assembly extern");
if((reference.Flags & AssemblyFlags.Retargetable) == AssemblyFlags.Retargetable) {
m_writer.Write("retargetable");
}
m_writer.WriteLine (Formater.Escape (reference.Name));
m_writer.OpenBlock ();
AssemblyDetails (reference);
m_writer.CloseBlock ();
}
public override void VisitAssemblyDefinition (AssemblyDefinition asm)
{
m_writer.Write (".assembly");
//m_writer.WriteLine(String.Concat("'", Formater.Escape(asm.Name.Name, false), "'"));
m_writer.WriteLine(Formater.Escape(asm.Name.Name, true));
m_writer.OpenBlock ();
AssemblyDetails (asm.Name);
m_rd.VisitCustomAttributeCollection (asm.CustomAttributes);
m_rd.VisitSecurityDeclarationCollection (asm.SecurityDeclarations);
m_writer.CloseBlock ();
m_writer.WriteLine ();
}
public override void VisitModuleDefinition (ModuleDefinition module)
{
m_writer.Write (".module");
m_writer.Write (Formater.Escape (module.Name));
m_writer.Write (" // GUID:");
m_writer.WriteLine (module.Mvid);
m_writer.WriteLine ();
}
public override void VisitResourceCollection (ResourceCollection resources)
{
for (int i = 0; i < resources.Count; i++) {
if (i > 0)
m_writer.WriteLine ();
Resource r = resources [i];
WriteResourceHeader (r);
m_writer.OpenBlock ();
r.Accept (this);
m_writer.CloseBlock ();
}
}
void WriteResourceHeader (Resource r)
{
m_writer.Write ("mresource");
m_writer.BaseWriter.Write ((r.Flags & ManifestResourceAttributes.Public) > 0 ? "public" : "private");
m_writer.BaseWriter.Write (" ");
m_writer.BaseWriter.WriteLine (Formater.Escape (r.Name));
}
public override void VisitAssemblyLinkedResource (AssemblyLinkedResource alr)
{
m_writer.Write (".assembly extern");
m_writer.BaseWriter.WriteLine (Formater.Escape (alr.Assembly.Name));
}
public override void VisitLinkedResource (LinkedResource lr)
{
m_writer.Write (".file");
m_writer.BaseWriter.Write (Formater.Escape (lr.File));
m_writer.BaseWriter.WriteLine (" at 0x0");
}
public override void VisitEmbeddedResource (EmbeddedResource er)
{
// TODO
}
}
}