6. Correlating Metadata Tables

 

In all the previous chapters that we presented, we had elucidated all the concepts and tables through distinct programs. In this chapter, we have endeavored to inscribe a single program, which encompasses all the tables and displays meaningful output. In lieu of displaying references to various tables, such as typeDef[1],  MethodRef[2] etc., we shall display the actual values existent at these locations. Thus, we have essayed to resolve all the cross-references and to display the metadata information in a comprehensive manner.

 

But, prior to embarking on the explanation of this gargantuan program, which cross-references all the tables, we wish to shed light on a few crucial aspects.

 

Every table in the metadata world is constituted of fields. Moreover, even a structure is essentially a collection of fields. Therefore, in the C# program, we have represented the metadata tables in a structure.

 

For instance, we have created an ExportedTypeTable as a structure tag, which contains multiple fields. The structure in essence, is a logical entity, which has no physical existence. Hence, we generate an actual structure by creating a variable of the structure tag named ExportedTypeTableStruct. A structure is a value type, and hence, it does not have to be instantiated.

The variable ExportedTypeTableStruct is declared as an array of structures.

 

public struct ExportedTypeTable

{

            public int flags ;

            public int typedefindex ;

            public int name ;

            public int nspace ;

            public int coded ;

}

 

public ExportedTypeTable [] ExportedTypeStruct;

 

The program gets underway by creating a structure tag for every table in the metadata.  We have proffered the entire program to you, despite being aware of the fact that it would run into reams of pages.  Before you get going with the main program, compile b.cs in the c:\mdata subdirectory and generate the file b.exe. The metadata information of this executable will be displayed in the output.

 

b.cs

using System.Runtime.InteropServices;

using System;

public class zzz

{

static int i;

const int j=2;

public event EventHandler a;

public event EventHandler b;

[DllImport("user32.dll")]

public static extern int MessageBox(int hWnd, String text, String caption, uint type);

 

public static void Main ()

{

i=10;

Console.WriteLine("hell {0}",i);

}

public int abc(float k)

{

return 0;

}

public long pqr( int[] i ,  char j)

{

return 0;

}

public void xyz()

{

}

}

public class yyy:iii

{

public int aa

{

set

{

}

get

{

return 10;

}

}

public string bb

{

set

{

}

get

{

return "hi";

}

}

public long uuu( int i , char[] j)

{

return 0;

}

void iii.xxx()

{

Console.WriteLine("hello");

}

public unsafe void aaa()

{

}

 

}

interface iii

{

void xxx();

}

public class uuu:yyy

{

class a1

{

}

}

 

a.txt

author=vijay

book=metadata

 

>resgen a.txt

>csc b.cs /res:a.resources /unsafe

 

a.cs

using System;

using System.IO;

using System.Reflection;

using System.Reflection.Emit;

using System.Configuration.Assemblies;

using  System.Globalization;

public struct ExportedTypeTable

{

            public int flags ;

            public int typedefindex ;

            public int name ;

            public int nspace ;

            public int coded ;

}

public struct NestedClassTable

{

            public int nestedclass;

            public int enclosingclass;

}

public struct MethodImpTable

{

            public int classindex;

            public int codedbody;

            public int codeddef;

}

public struct ClassLayoutTable

{

            public short packingsize ;

            public int classsize ;

            public int parent ;

}

public struct ManifestResourceTable

{

            public int offset;

            public int flags;

            public int name;

            public int coded; 

}

public struct ModuleRefTable

{

            public int name;

}

public struct FileTable

{

            public int flags;

            public int name;

            public int index;

}

public struct EventTable

{

            public short attr;

            public int name;

            public int coded;  

}

public struct EventMapTable

{

            public int index;

            public int eindex; 

}

public struct MethodSemanticsTable

{

            public short methodsemanticsattributes;

            public int methodindex;

            public int association;  

}

public struct PropertyMapTable

{

            public int parent;

            public int propertylist;

}

public struct PropertyTable

{

            public int flags;

            public int name;

            public int type;

}

public struct ConstantsTable

{

            public short dtype;

            public int parent;

            public int value ;

}

public struct FieldLayoutTable

{

            public int offset;

            public int fieldindex; 

}

public struct FieldRVATable

{

            public int rva ;

            public int fieldi;

}

public struct FieldMarshalTable

{

            public int coded;

            public int index; 

}

public struct FieldTable

{

            public int flags;

            public int name;

            public int sig;

}

public struct ParamTable

{

            public short pattr;

            public int sequence;

            public int name;

}

public struct TypeSpecTable

{

            public int signature;

}

public struct MemberRefTable

{

            public int clas;

            public int name;

            public int sig;  

}

public struct StandAloneSigTable

{

            public int index;

}

public struct InterfaceImplTable

{

            public int classindex;

            public int interfaceindex;

}

public struct TypeDefTable

{

            public int flags;

            public int name;

            public int nspace;

            public int cindex;

            public int findex;

            public int mindex;

}

public struct CustomAttributeTable

{

            public int parent;

            public int type;

            public int value;

}

public struct AssemblyRefTable

{

            public short major,minor,build,revision;

            public int flags ;

            public int publickey ;

            public int name ;

            public int culture ;

            public int hashvalue ;

}

public struct AssemblyTable

{

            public int HashAlgId;

            public int major, minor,build,revision ;

            public int flags ;

            public int publickey ;

            public int name ;

            public int culture ;

}

public struct ModuleTable

{

            public int Generation;

            public int Name;

            public int Mvid;

            public int EncId;

            public int EncBaseId;

}

public struct TypeRefTable

{

            public int resolutionscope;

            public int name;

            public int nspace;

}

public struct MethodTable

{

            public int rva;

            public int impflags;

            public int flags;

            public int name;

            public int signature;

            public int param;

}

public struct DeclSecurityTable

{

            public int action;

            public int coded;

            public int bindex; 

}

public struct ImplMapTable

{

            public short attr;

            public int cindex;

            public int name;

            public int scope;

}

public class zzz

{

            string [] typerefnames; 

            string [] typedefnames; 

           

            public static void Main (string [] args)

            {

                        zzz a = new zzz();

                        a.abc(args);

            }

            public void abc(string [] args)

            {

                        InitializeObjects(args);

                        ReadPEStructures();

                        DisplayPEStructures();

                        ImportAdressTable();

                        CLRHeader();

                        ReadStreamsData();

                        FillTableSizes();

                        ReadTablesIntoStructures();

                        DisplayTableForDebugging();

            }

            public AssemblyTable [] AssemblyStruct;

            public AssemblyRefTable [] AssemblyRefStruct ;

            public CustomAttributeTable [] CustomAttributeStruct;

            public ModuleTable[] ModuleStruct;

            public TypeDefTable [] TypeDefStruct;

            public TypeRefTable [] TypeRefStruct;

            public InterfaceImplTable [] InterfaceImplStruct;

            public MethodTable [] MethodStruct;

            public StandAloneSigTable [] StandAloneSigStruct;

            public MemberRefTable [] MemberRefStruct;

            public TypeSpecTable [] TypeSpecStruct;

            public ParamTable [] ParamStruct;

            public FieldTable [] FieldStruct;

            public FieldMarshalTable [] FieldMarshalStruct;

            public FieldRVATable [] FieldRVAStruct;

            public FieldLayoutTable [] FieldLayoutStruct;

            public ConstantsTable [] ConstantsStruct;

            public PropertyMapTable [] PropertyMapStruct;

            public PropertyTable [] PropertyStruct;

            public MethodSemanticsTable [] MethodSemanticsStruct;

            public EventTable [] EventStruct;

            public EventMapTable [] EventMapStruct;

            public FileTable [] FileStruct;

            public ModuleRefTable [] ModuleRefStruct;

            public ManifestResourceTable [] ManifestResourceStruct;

            public ClassLayoutTable [] ClassLayoutStruct;

            public MethodImpTable [] MethodImpStruct;

            public NestedClassTable [] NestedClassStruct;

            public ExportedTypeTable [] ExportedTypeStruct;

            public DeclSecurityTable [] DeclSecurityStruct;

            public ImplMapTable [] ImplMapStruct;

            int [] sizes;

            FileStream s ;

            BinaryReader r ;

            int subsystem;

            int stackreserve ;

            int stackcommit;

            int datad;

            int entrypoint;

            int ImageBase;

            int sectiona;

            int filea;

            int [] datadirectoryrva;

            int [] datadirectorysize;

            long sectionoffset;

            short sections ;

            int metadatarva;

            int entrypointtoken;

            int [] SVirtualAddress ;

            int [] SSizeOfRawData;

            int [] SPointerToRawData ;

            long startofmetadata;

            string [] streamnames;

            int tableoffset ;

            int [] rows;

            long valid ;

            byte [] metadata;

            byte [] strings;

            byte [] us;

            byte [] guid;

            byte [] blob;

            int [] offset;

            int [] ssize ;

            byte [][] names;

            int offsetstring = 2;

            int offsetblob = 2;

            int offsetguid = 2;

            int vtablerva;

            int vtablesize;

            int exportaddressrva;

            int exportaddresssize;

            int corflags;

            string [] tablenames;

            string filename;

            public void InitializeObjects(string [] args)

            {

                        tablenames = new String[]{"Module" , "TypeRef" ,            "TypeDef" ,"FieldPtr","Field", "MethodPtr","Method","ParamPtr" , "Param", "InterfaceImpl", "MemberRef", "Constant", "CustomAttribute", "FieldMarshal", "DeclSecurity", "ClassLayout", "FieldLayout", "StandAloneSig" , "EventMap","EventPtr", "Event", "PropertyMap", "PropertyPtr", "Properties","MethodSemantics","MethodImpl","ModuleRef","TypeSpec","Imp

lMap","FieldRVA","ENCLog","ENCMap","Assembly",

"AssemblyProcessor","AssemblyOS","AssemblyRef","AssemblyRefProcessor",

"AssemblyRefOS","File","ExportedType","ManifestResource",

"NestedClass","TypeTyPar","MethodTyPar"};

 

if ( args.Length == 0)

            filename = "C:\\mdata\\b.exe";

else

            filename = args[0];

}

public void ReadPEStructures()

{

            s = new FileStream(filename ,FileMode.Open);

            r = new BinaryReader (s);

            s.Seek(60, SeekOrigin.Begin);

            int ii = r.ReadInt32();

            s.Seek(ii, SeekOrigin.Begin);

            byte sig1,sig2,sig3,sig4;

            sig1 = r.ReadByte();

            sig2 = r.ReadByte();

            sig3 = r.ReadByte();

            sig4 = r.ReadByte();

            //First Structure

            short machine = r.ReadInt16();

            sections = r.ReadInt16();

            int time = r.ReadInt32();

            int pointer = r.ReadInt32();

            int symbols = r.ReadInt32();

            int headersize= r.ReadInt16();

            int characteristics = r.ReadInt16();

            sectionoffset = s.Position + headersize;

            //Second Structure

            int magic = r.ReadInt16();

            int major = r.ReadByte();

            int minor = r.ReadByte();

            int sizeofcode = r.ReadInt32();

            int sizeofdata = r.ReadInt32();

            int sizeofudata = r.ReadInt32();

            entrypoint = r.ReadInt32();

            int baseofcode = r.ReadInt32();

            int baseofdata = r.ReadInt32();

            ImageBase = r.ReadInt32();

            sectiona= r.ReadInt32();

            filea = r.ReadInt32();

            int majoros = r.ReadInt16();

            int minoros = r.ReadInt16();

            int majorimage = r.ReadInt16();

            int minorimage = r.ReadInt16();

            int majorsubsystem= r.ReadInt16();

            int minorsubsystem = r.ReadInt16();

            int verison = r.ReadInt32();

            int imagesize = r.ReadInt32();

            int sizeofheaders= r.ReadInt32();

            int checksum = r.ReadInt32();

            subsystem = r.ReadInt16();

            int dllflags = r.ReadInt16();

            stackreserve = r.ReadInt32();

            stackcommit = r.ReadInt32();

            int heapreserve = r.ReadInt32();

            int heapcommit = r.ReadInt32();

            int loader = r.ReadInt32();

            datad = r.ReadInt32();

            datadirectoryrva = new int[16];

            datadirectorysize = new int[16];

            for ( int i = 0 ; i <=15 ; i++)

            {

                        datadirectoryrva[i] = r.ReadInt32();

                        datadirectorysize[i] = r.ReadInt32();

            }

            if ( datadirectorysize[14] == 0)

                        throw new System.Exception("Not a valid CLR file");

            s.Position = sectionoffset ;

            SVirtualAddress = new int[sections ];

            SSizeOfRawData = new int[sections ];

            SPointerToRawData = new int[sections ];

            for ( int i = 0 ; i < sections ; i++)

            {

                        r.ReadBytes(12);

                        SVirtualAddress[i] = r.ReadInt32();

                        SSizeOfRawData[i] = r.ReadInt32();

                        SPointerToRawData[i] = r.ReadInt32();

                        r.ReadBytes(16);

            }

}

public void DisplayPEStructures()

{

Console.WriteLine();

Console.WriteLine("//  Microsoft (R) .NET Framework IL Disassembler.  Version 1.0.3705.0");

Console.WriteLine("//  Copyright (C) Microsoft Corporation 1998-2001. All rights reserved.");

Console.WriteLine();

Console.WriteLine("// PE Header:");

Console.WriteLine("// Subsystem:                      {0}",subsystem.ToString("x8"));

Console.WriteLine("// Native entry point address:     {0}",entrypoint.ToString("x8"));

Console.WriteLine("// Image base:                     {0}",ImageBase.ToString("x8"));

Console.WriteLine("// Section alignment:              {0}",sectiona.ToString("x8"));

Console.WriteLine("// File alignment:                 {0}",filea.ToString("x8"));

Console.WriteLine("// Stack reserve size:             {0}",stackreserve.ToString("x8"));

Console.WriteLine("// Stack commit size:              {0}",stackcommit.ToString("x8"));

Console.WriteLine("// Directories:                    {0}",datad.ToString("x8"));

DisplayDataDirectory(datadirectoryrva[0] , datadirectorysize[0] , "Export Directory");

DisplayDataDirectory(datadirectoryrva[1] , datadirectorysize[1] , "Import Directory");

DisplayDataDirectory(datadirectoryrva[2] , datadirectorysize[2] , "Resource Directory");

DisplayDataDirectory(datadirectoryrva[3] , datadirectorysize[3] , "Exception Directory");

DisplayDataDirectory(datadirectoryrva[4] , datadirectorysize[4] , "Security Directory");

DisplayDataDirectory(datadirectoryrva[5] , datadirectorysize[5] , "Base Relocation Table");

DisplayDataDirectory(datadirectoryrva[6] , datadirectorysize[6] , "Debug Directory");

DisplayDataDirectory(datadirectoryrva[7] , datadirectorysize[7] , "Architecture Specific");

DisplayDataDirectory(datadirectoryrva[8] , datadirectorysize[8] , "Global Pointer");

DisplayDataDirectory(datadirectoryrva[9] , datadirectorysize[9] , "TLS Directory");

DisplayDataDirectory(datadirectoryrva[10] , datadirectorysize[10] , "Load Config Directory");

DisplayDataDirectory(datadirectoryrva[11] , datadirectorysize[11] , "Bound Import Directory");

DisplayDataDirectory(datadirectoryrva[12] , datadirectorysize[12] , "Import Address Table");

DisplayDataDirectory(datadirectoryrva[13] , datadirectorysize[13] , "Delay Load IAT");

DisplayDataDirectory(datadirectoryrva[14] , datadirectorysize[14] , "CLR Header");

Console.WriteLine();

}

public void DisplayDataDirectory(int rva, int size , string ss)

{

string sfinal =  "";

sfinal = String.Format("// {0:x}" , rva);

sfinal = sfinal.PadRight(12);

sfinal = sfinal + String.Format("[{0:x}" , size);

sfinal = sfinal.PadRight(21);

sfinal = sfinal + String.Format("] address [size] of {0}:" , ss);

if (ss == "CLR Header")

sfinal = sfinal.PadRight(67);

else

sfinal = sfinal.PadRight(68);

Console.WriteLine(sfinal);

}

public void ImportAdressTable()

{

long stratofimports = ConvertRVA(datadirectoryrva[1]);

s.Position = stratofimports;

Console.WriteLine("// Import Address Table");

int j = 0;

while (true)

{

int rvaimportlookuptable = r.ReadInt32();

if ( rvaimportlookuptable == 0)

break;

int datetimestamp = r.ReadInt32();

int forwarderchain = r.ReadInt32();

int name = r.ReadInt32();

int rvaiat = r.ReadInt32();

s.Position = ConvertRVA(name);

Console.Write("//     ");

DisplayStringFromFile();

Console.WriteLine("//              {0} Import Address Table" , rvaiat.ToString("x8"));

Console.WriteLine("//              {0} Import Name Table" , name.ToString("x8"));

Console.WriteLine("//              {0}        time date stamp" , datetimestamp);

Console.WriteLine("//              {0}        Index of first forwarder reference" , forwarderchain);

Console.WriteLine("//");

int jj = 0;

while ( true )

{

long  pos = ConvertRVA(rvaimportlookuptable ) ;

if ( pos == -1)

break;

s.Position = pos + jj * 4;

int pos1 = r.ReadInt32();

if ( pos1 == 0)

break;

pos = ConvertRVA(rvaimportlookuptable ) ;

if ( pos == -1)

break;

s.Position = pos;

short hint = r.ReadInt16();

Console.Write("//                  ");

if ( hint.ToString("X").Length == 1)

Console.Write("  {0}" , hint.ToString("x"));

if ( hint.ToString("X").Length == 2)

Console.Write(" {0}" , hint.ToString("x"));

if ( hint.ToString("X").Length == 3)

Console.Write("{0}" , hint.ToString("x"));

Console.Write("  ");

DisplayStringFromFile();

jj++;

}

Console.WriteLine();

j++;

s.Position = stratofimports + j * 20;

}

Console.WriteLine("// Delay Load Import Address Table");

if (datadirectoryrva[13] == 0)

Console.WriteLine("// No data.");

}

public void DisplayStringFromFile()

{

while ( true )

{

byte b = (byte )s.ReadByte();

if ( b == 0)

break;

Console.Write("{0}" , (char)b);

}

Console.WriteLine();

}

public void FillTableSizes()

{

int modulesize = 2 + offsetstring + offsetguid + offsetguid + offsetguid ;

int typerefsize  = GetCodedIndexSize("ResolutionScope") + offsetstring + offsetstring ;

int typedefsize = 4 + offsetstring + offsetstring + GetCodedIndexSize("TypeDefOrRef") + GetTableSize() + GetTableSize();

int fieldsize = 2 + offsetstring + offsetblob ;

int methodsize = 4 + 2 + 2 + offsetstring + offsetblob + GetTableSize();

int paramsize = 2 + 2 + offsetstring;

int interfaceimplsize = GetTableSize() + GetCodedIndexSize("TypeDefOrRef");

int memberrefsize = GetCodedIndexSize("MemberRefParent") + offsetstring  + offsetblob ;

int constantsize = 2 + GetCodedIndexSize("HasConst") + offsetblob;

int customattributesize = GetCodedIndexSize("HasCustomAttribute") + GetCodedIndexSize("HasCustomAttributeType") + offsetblob;

int fieldmarshallsize = GetCodedIndexSize("HasFieldMarshal") + offsetblob;

int declsecuritysize = 2 + GetCodedIndexSize("HasDeclSecurity") + offsetblob;

int classlayoutsize = 2 + 4 + GetTableSize();

int fieldlayoutsize = 4 + GetTableSize();

int stanalonssigsize = offsetblob;

int eventmapsize = GetTableSize() +  GetTableSize();

int eventsize = 2 + offsetstring + GetCodedIndexSize("TypeDefOrRef");

int propertymapsize = GetTableSize() + GetTableSize() ;

int propertysize = 2 + offsetstring + offsetblob;

int methodsemantics = 2 + GetTableSize() + GetCodedIndexSize("HasSemantics");

int methodimplsize = GetTableSize() + GetCodedIndexSize("MethodDefOrRef") + GetCodedIndexSize("MethodDefOrRef");

int modulerefsize = offsetstring;

int typespecsize = offsetblob;

int implmapsize = 2 + GetCodedIndexSize("MemberForwarded") + offsetstring + GetTableSize();

int fieldrvasize = 4  + GetTableSize();

int assemblysize = 4 + 2 + 2 + 2 + 2 + 4 +  offsetblob + offsetstring + offsetstring ;

int assemblyrefsize = 2 + 2 + 2 + 2 + 4 +  offsetblob + offsetstring + offsetstring + offsetblob;

int filesize = 4 + offsetstring + offsetblob;

int exportedtype = 4 + 4 + offsetstring + offsetstring + GetCodedIndexSize("Implementation");

int manifestresourcesize = 4 + 4 + offsetstring + GetCodedIndexSize("Implementation");

int nestedclasssize = GetTableSize() + GetTableSize() ;

sizes = new int[]{ modulesize, typerefsize , typedefsize ,2, fieldsize ,2,methodsize ,2,paramsize ,interfaceimplsize,memberrefsize ,constantsize ,customattributesize ,fieldmarshallsize ,declsecuritysize ,classlayoutsize ,fieldlayoutsize,stanalonssigsize ,eventmapsize ,2,eventsize ,propertymapsize ,2,propertysize ,methodsemantics ,methodimplsize ,modulerefsize ,typespecsize ,implmapsize ,fieldrvasize ,2 , 2 , assemblysize ,4,12,assemblyrefsize ,6,14,filesize ,exportedtype ,manifestresourcesize ,nestedclasssize };

}

public int GetCodedIndexSize(string i)

{

if ( i == "Implementation")

{

if ( rows[0x26] >= 16384 || rows[0x23] >= 16384 || rows[0x27] >= 16384 )

return 4;

else

return 2;

}

else if ( i == "MemberForwarded")

{

if ( rows[0x04] >= 32768 || rows[0x06] >= 32768)

return 4;

else

return 2;

}

else if ( i == "MethodDefOrRef")

{

if ( rows[0x06] >= 32768 || rows[0x0A] >= 32768)

return 4;

else

return 2;

}

else if ( i == "HasSemantics")

{

if ( rows[0x14] >= 32768 || rows[0x17] >= 32768)

return 4;

else

return 2;

}

else if ( i == "HasDeclSecurity")

{

if ( rows[0x02] >= 16384 || rows[0x06] >= 16384 || rows[0x20] >= 16384)

return 4;

else

return 2;

}

else if ( i == "HasFieldMarshal")

{

if ( rows[0x04] >= 32768|| rows[0x08] >= 32768)

return 4;

else

return 2;

}

else if ( i == "TypeDefOrRef")

{

if ( rows[0x02] >= 16384 || rows[0x01] >= 16384  || rows[0x1B] >= 16384   )

return 4;

else

return 2;

}

else if ( i == "ResolutionScope")

{

if ( rows[0x00] >= 8192 || rows[0x1a] >= 8192  || rows[0x23] >= 8192  || rows[0x01] >= 8192 )

return 4;

else

return 2;

}

else if ( i == "HasConst")

{

if ( rows[4] >= 16384 || rows[8] >= 16384 || rows[0x17] >= 16384 )

return 4;

else

return 2;

}

else if ( i == "MemberRefParent")

{

if ( rows[0x01] >= 8192 || rows[0x1a] >= 8192 || rows[0x06] >= 8192 || rows[0x1b] >= 8192  )

return 4;

else

return 2;

}

else if ( i == "HasCustomAttribute")

{

if ( rows[0x06] >= 2048 || rows[0x04] >= 2048 || rows[0x01] >= 2048 || rows[0x02] >= 2048 || rows[0x08] >= 2048 || rows[0x09] >= 2048 || rows[0x0a] >= 2048 || rows[0x00] >= 2048 || rows[0x0e] >= 2048 || rows[0x17] >= 2048 || rows[0x14] >= 2048 || rows[0x11] >= 2048 || rows[0x1a] >= 2048 || rows[0x1b] >= 2048 || rows[0x20] >= 2048 || rows[0x23] >= 2048 || rows[0x26] >= 2048 || rows[0x27] >= 2048 || rows[0x28] >= 2048 )

return 4;

else

return 2;

}

else if ( i == "HasCustomAttributeType")

{

if ( rows[0x06] >= 8192 || rows[0x0a] >= 8192)

return 4;

else

return 2;

}

else

return 2;

}

public int ReadCodedIndex(byte [] a , int o , string i)

{

int z = 0;

int z1 = GetCodedIndexSize(i);

if ( z1 == 2)

z = BitConverter.ToUInt16 (a , o );

if ( z1 == 4)

z = (int)BitConverter.ToUInt32 (a , o );

return z;

}

public bool tablepresent(byte i)

{

int p = (int)(valid >> i) & 1;

for ( int j = 0 ; j < i ; j++)

{

int o = sizes[j] * rows[j];

tableoffset = tableoffset + o;

}

if ( p == 1)

return true;

else

return false;

}

public void ReadTablesIntoStructures()

{

//Module

int old = tableoffset;

bool b = tablepresent(0);

int offs = tableoffset;

Console.WriteLine("\n    Table Details   \n\n");

Console.WriteLine("Module Table Offset {0} Size {1}" , offs , sizes[0]);

tableoffset = old;

if ( b )

{

ModuleStruct = new ModuleTable[rows[0] + 1];

for ( int k = 1 ; k <= rows[0] ; k++)

{

ModuleStruct[k].Generation = BitConverter.ToUInt16 (metadata, offs);

offs += 2;

ModuleStruct[k].Name = ReadStringIndex(metadata, offs);

offs += offsetstring;

ModuleStruct[k].Mvid = ReadGuidIndex(metadata, offs);

offs += offsetguid;

ModuleStruct[k].EncId = ReadGuidIndex(metadata, offs);

offs += offsetguid;

ModuleStruct[k].EncBaseId = ReadGuidIndex(metadata, offs);

offs += offsetguid;

}

}

//TypeRef

old = tableoffset;

b = tablepresent(1);

offs = tableoffset;

Console.WriteLine("TypeRef Table Offset {0} Size {1}" , offs ,  sizes[1]);

tableoffset = old;

if ( b )

{

typerefnames = new string[rows[1]+1];

TypeRefStruct = new TypeRefTable[rows[1] + 1];

for ( int k = 1 ; k <=rows[1] ; k++)

{

TypeRefStruct[k].resolutionscope = ReadCodedIndex(metadata , offs , "ResolutionScope");

offs = offs + GetCodedIndexSize("ResolutionScope");

TypeRefStruct[k].name = ReadStringIndex(metadata , offs);

typerefnames[k] = GetString(TypeRefStruct[k].name);

offs = offs + offsetstring;

TypeRefStruct[k].nspace = ReadStringIndex(metadata , offs);

offs = offs + offsetstring;

}

}

//TypeDef

old = tableoffset;

b = tablepresent(2);

offs = tableoffset;

Console.WriteLine("TypeDef Table Offset {0} Size {1}" , offs , sizes[2]);

tableoffset = old;

if ( b )

{

typedefnames = new string[rows[2]+1];

TypeDefStruct = new TypeDefTable[rows[2] + 1];

for ( int k = 1 ; k <= rows[2] ; k++)

{

TypeDefStruct[k].flags = BitConverter.ToInt32 (metadata, offs);

offs += 4;

TypeDefStruct[k].name = ReadStringIndex(metadata, offs);

typedefnames[k] = GetString(TypeDefStruct[k].name);

offs += offsetstring;

TypeDefStruct[k].nspace = ReadStringIndex(metadata, offs);

offs += offsetstring;

TypeDefStruct[k].cindex = ReadCodedIndex(metadata , offs , "TypeDefOrRef");

offs += GetCodedIndexSize("TypeDefOrRef");

TypeDefStruct[k].findex = ReadTableIndex(metadata, offs);

offs += GetTableSize();

TypeDefStruct[k].mindex = ReadTableIndex(metadata, offs);

offs += GetTableSize();

}

}

//Field

old = tableoffset;

b = tablepresent(4);

offs = tableoffset;

Console.WriteLine("Field Table Offset {0} Size {1}" , offs , sizes[4]);

tableoffset = old;

if ( b )

{

FieldStruct = new FieldTable[rows[4] + 1];

for ( int k = 1 ; k <= rows[4] ; k++)

{

FieldStruct[k].flags = BitConverter.ToInt16 (metadata, offs);

offs += 2;

FieldStruct[k].name = ReadStringIndex(metadata, offs);

offs += offsetstring;

FieldStruct[k].sig = ReadBlobIndex(metadata, offs);

offs += offsetblob;

}

}

//Method

old = tableoffset;

b = tablepresent(6);

offs = tableoffset;

Console.WriteLine("Method Table Offset {0} Size {1}" , offs , sizes[6]);

tableoffset = old;

if ( b )

{

MethodStruct = new MethodTable[rows[6] + 1];

for ( int k = 1 ; k <= rows[6] ; k++)

{

MethodStruct[k].rva = BitConverter.ToInt32 (metadata, offs);

offs += 4;

MethodStruct[k].impflags = BitConverter.ToInt16 (metadata, offs);

offs += 2;

MethodStruct[k].flags = (int)BitConverter.ToInt16 (metadata, offs);

offs += 2;

MethodStruct[k].name = ReadStringIndex(metadata, offs);

offs += offsetstring;

MethodStruct[k].signature = ReadBlobIndex(metadata, offs);

offs += offsetblob;

MethodStruct[k].param = ReadTableIndex(metadata, offs);

offs += GetTableSize();

}

}

//Param

old = tableoffset;

b = tablepresent(8);

offs = tableoffset;

Console.WriteLine("Param Table Offset {0} Size {1}" , offs , sizes[8]);

tableoffset = old;

if ( b )

{

ParamStruct = new ParamTable[rows[8] + 1];

for ( int k = 1 ; k <= rows[8] ; k++)

{

ParamStruct[k].pattr = BitConverter.ToInt16 (metadata, offs);

offs += 2;

ParamStruct[k].sequence = BitConverter.ToInt16 (metadata, offs);

offs += 2;

ParamStruct[k].name = ReadStringIndex(metadata, offs);

offs += offsetstring;

}

}

//InterfaceImpl

old = tableoffset;

b = tablepresent(9);

offs = tableoffset;

Console.WriteLine("InterfaceImpl Table Offset {0} Size {1}" , offs , sizes[9]);

tableoffset = old;

if ( b )

{

InterfaceImplStruct = new InterfaceImplTable[rows[9] + 1];

for ( int k = 1 ; k <= rows[9] ; k++)

{

InterfaceImplStruct[k].classindex = ReadCodedIndex(metadata , offs , "TypeDefOrRef");

offs += GetCodedIndexSize("TypeDefOrRef");

InterfaceImplStruct[k].interfaceindex = ReadTableIndex(metadata, offs);

offs += GetTableSize();

}

}

//MemberRef

old = tableoffset;

b = tablepresent(10);

offs = tableoffset;

Console.WriteLine("MemberRef Table Offset {0} Size {1}" , offs, sizes[10]);

tableoffset = old;

if ( b )

{

MemberRefStruct = new MemberRefTable[rows[10] + 1];

for ( int k = 1 ; k <= rows[10] ; k++)

{

MemberRefStruct[k].clas = ReadCodedIndex(metadata , offs , "MemberRefParent");

offs += GetCodedIndexSize("MemberRefParent");

MemberRefStruct[k].name = ReadStringIndex(metadata, offs);

offs += offsetstring;

MemberRefStruct[k].sig = ReadBlobIndex(metadata, offs);

offs += offsetblob;

}

}

//Constants

old = tableoffset;

b = tablepresent(11);

offs = tableoffset;

Console.WriteLine("Constant Table Offset {0} Size {1}" , offs, sizes[11]);

tableoffset = old;

if ( b )

{

ConstantsStruct = new ConstantsTable[rows[11] + 1];

for ( int k = 1 ; k <= rows[11] ; k++)

{

ConstantsStruct[k].dtype = metadata[offs];

offs += 2;

ConstantsStruct[k].parent = ReadCodedIndex(metadata , offs , "HasConst");

offs += GetCodedIndexSize("HasConst");

ConstantsStruct[k].value = ReadBlobIndex(metadata, offs);

offs += offsetblob;

}

}

//CustomAttribute

old = tableoffset;

b = tablepresent(12);

offs = tableoffset;

Console.WriteLine("CustomAttribute Table Offset {0} Size {1}" , offs , sizes[12]);

tableoffset = old;

if ( b )

{

CustomAttributeStruct = new CustomAttributeTable[rows[12] + 1];

for ( int k = 1 ; k <= rows[12] ; k++)

{

CustomAttributeStruct[k].parent = ReadCodedIndex(metadata , offs , "HasCustomAttribute");

offs += GetCodedIndexSize("HasCustomAttribute");

CustomAttributeStruct[k].type = ReadCodedIndex(metadata , offs , "HasCustomAttributeType");

offs += GetCodedIndexSize("HasCustomAttributeType");

CustomAttributeStruct[k].value = ReadBlobIndex(metadata, offs);

offs += offsetblob;

}

}

//FieldMarshal

old = tableoffset;

b = tablepresent(13);

offs = tableoffset;

Console.WriteLine("FieldMarshal Table Offset {0}" , offs);

tableoffset = old;

if ( b )

{

FieldMarshalStruct = new FieldMarshalTable[rows[13] + 1];

for ( int k = 1 ; k <= rows[13] ; k++)

{

FieldMarshalStruct[k].coded = ReadCodedIndex(metadata , offs , "HasFieldMarshal");

offs += GetCodedIndexSize("HasFieldMarshal");

FieldMarshalStruct[k].index = ReadBlobIndex(metadata, offs);

offs += offsetblob;

}

}

//DeclSecurity

old = tableoffset;

b = tablepresent(14);

offs = tableoffset;

Console.WriteLine("DeclSecurity Table Offset {0}" , offs);

tableoffset = old;

if ( b )

{

DeclSecurityStruct = new DeclSecurityTable[rows[14] + 1];

for ( int k = 1 ; k <= rows[14] ; k++)

{

DeclSecurityStruct[k].action = BitConverter.ToInt16 (metadata, offs);

offs += 2;

DeclSecurityStruct[k].coded = ReadCodedIndex(metadata , offs , "HasDeclSecurity");

offs += GetCodedIndexSize("HasDeclSecurity");

DeclSecurityStruct[k].bindex = ReadBlobIndex(metadata, offs);

offs += offsetblob;

}

}

//ClassLayout

old = tableoffset;

b = tablepresent(15);

offs = tableoffset;

Console.WriteLine("ClassLayout Table Offset {0}" , offs);

tableoffset = old;

if ( b )

{

ClassLayoutStruct = new ClassLayoutTable[rows[15] + 1];

for ( int k = 1 ; k <= rows[15] ; k++)

{

ClassLayoutStruct[k].packingsize = BitConverter.ToInt16 (metadata, offs);

offs += 2;

ClassLayoutStruct[k].classsize = BitConverter.ToInt32 (metadata, offs);

offs += 4;

ClassLayoutStruct[k].parent = ReadTableIndex(metadata, offs);

offs += GetTableSize();

}

}

//FieldLayout

old = tableoffset;

b = tablepresent(16);

offs = tableoffset;

Console.WriteLine("FieldLayout Table Offset {0}" , offs);

tableoffset = old;

if ( b )

{

FieldLayoutStruct = new FieldLayoutTable[rows[16] + 1];

for ( int k = 1 ; k <= rows[16] ; k++)

{

FieldLayoutStruct[k].offset = BitConverter.ToInt32 (metadata, offs);

offs += 4;

FieldLayoutStruct[k].fieldindex = ReadTableIndex(metadata, offs);

offs += GetTableSize();

}

}

//StandAloneSig

old = tableoffset;

b = tablepresent(17);

offs = tableoffset;

Console.WriteLine("StandAloneSig Table Offset {0}" , offs);

tableoffset = old;

if ( b )

{

StandAloneSigStruct = new StandAloneSigTable[rows[17] + 1];

for ( int k = 1 ; k <= rows[17] ; k++)

{

StandAloneSigStruct[k].index = ReadBlobIndex(metadata, offs);

offs += offsetblob;

}

}

//EventMap

old = tableoffset ;

b = tablepresent(18);

offs = tableoffset;

Console.WriteLine("EventMap Table Offset {0}" , offs);

tableoffset = old;

if ( b )

{

EventMapStruct = new EventMapTable [rows[18] + 1];

for ( int k = 1 ; k <= rows[18] ; k++)

{

EventMapStruct[k].index = ReadTableIndex(metadata, offs);

offs += GetTableSize();

EventMapStruct[k].eindex = ReadTableIndex(metadata, offs);

offs += GetTableSize();

}

}

//Event

old = tableoffset;

b = tablepresent(20);

offs = tableoffset;

Console.WriteLine("Event Table Offset {0}" , offs);

tableoffset = old;

if ( b )

{

EventStruct = new EventTable[rows[20] + 1];

for ( int k = 1 ; k <= rows[20] ; k++)

{

EventStruct[k].attr = BitConverter.ToInt16 (metadata, offs);

offs += 2;

EventStruct[k].name = ReadStringIndex(metadata, offs);

offs += offsetstring;

EventStruct[k].coded = ReadCodedIndex(metadata , offs , "TypeDefOrRef");

offs += GetCodedIndexSize("TypeDefOrRef");

}

}

//PropertyMap

old = tableoffset;

b = tablepresent(21);

offs = tableoffset;

Console.WriteLine("PropertyMap Table Offset {0}" , offs);

tableoffset = old;

if ( b )

{

PropertyMapStruct = new PropertyMapTable[rows[21] + 1];

for ( int k = 1 ; k <= rows[21] ; k++)

{

PropertyMapStruct[k].parent = ReadTableIndex(metadata, offs);

offs += GetTableSize();

PropertyMapStruct[k].propertylist = ReadTableIndex(metadata, offs);

offs += GetTableSize();

}

}

//Property

old = tableoffset;

b = tablepresent(23);

offs = tableoffset;

Console.WriteLine("Property Table Offset {0}" , offs);

tableoffset = old;

if ( b )

{

PropertyStruct = new PropertyTable[rows[23] + 1];

for ( int k = 1 ; k <= rows[23] ; k++)

{

PropertyStruct[k].flags = BitConverter.ToInt16 (metadata, offs);

offs += 2;

PropertyStruct[k].name= ReadStringIndex(metadata, offs);

offs += offsetstring;

PropertyStruct[k].type = ReadBlobIndex(metadata, offs);

offs += offsetblob;

}

}

//MethodSemantics

old = tableoffset ;

b = tablepresent(24);

offs = tableoffset;

Console.WriteLine("MethodSemantics Table Offset {0}" , offs);

tableoffset = old;

if ( b )

{

MethodSemanticsStruct = new MethodSemanticsTable[rows[24] + 1];

for ( int k = 1 ; k <= rows[24] ; k++)

{

MethodSemanticsStruct[k].methodsemanticsattributes  = BitConverter.ToInt16 (metadata, offs);

offs += 2;

MethodSemanticsStruct[k].methodindex = ReadTableIndex(metadata, offs);

offs += GetTableSize();

MethodSemanticsStruct[k].association = ReadCodedIndex(metadata , offs , "HasSemantics");

offs += GetCodedIndexSize("HasSemantics");

}

}

//MethodImpl

old = tableoffset;

b = tablepresent(25);

offs = tableoffset;

Console.WriteLine("MethodImpl Table Offset {0}" , offs);

tableoffset = old;

if ( b )

{

MethodImpStruct = new MethodImpTable[rows[25] + 1];

for ( int k = 1 ; k <= rows[25] ; k++)

{

MethodImpStruct[k].classindex = ReadTableIndex(metadata, offs);

offs += GetTableSize();

MethodImpStruct[k].codedbody = ReadCodedIndex(metadata , offs , "MethodDefOrRef");

offs += GetCodedIndexSize("MethodDefOrRef");

MethodImpStruct[k].codeddef = ReadCodedIndex(metadata , offs , "MethodDefOrRef");

offs += GetCodedIndexSize("MethodDefOrRef");

}

}

//ModuleRef

old = tableoffset;

b = tablepresent(26);

offs = tableoffset;

Console.WriteLine("ModuleRef Table Offset {0}" , offs);

tableoffset = old;

if ( b )

{

ModuleRefStruct = new ModuleRefTable[rows[26] + 1];

for ( int k = 1 ; k <= rows[26] ; k++)

{

ModuleRefStruct[k].name = ReadStringIndex(metadata, offs);

offs += offsetstring;

}

}

//TypeSpec

old = tableoffset;

b = tablepresent(27);

offs = tableoffset;

Console.WriteLine("TypeSpec Table Offset {0} size={1}" , offs , rows[27]);

tableoffset = old;

if ( b )

{

TypeSpecStruct = new TypeSpecTable[rows[27] + 1];

for ( int k = 1 ; k <= rows[27] ; k++)

{

TypeSpecStruct[k].signature = ReadBlobIndex(metadata, offs);

offs += offsetblob;

}

}

//ImplMap

old = tableoffset;

b = tablepresent(28);

offs = tableoffset;

Console.WriteLine("ImplMap Table Offset offs={0} rows={1} len={2}" , offs , rows[28] , metadata.Length);

tableoffset = old;

if ( b )

{

ImplMapStruct = new ImplMapTable[rows[28] + 1];

for ( int k = 1 ; k <= rows[28] ; k++)

{

ImplMapStruct[k].attr = BitConverter.ToInt16 (metadata, offs);

offs += 2;

ImplMapStruct[k].cindex = ReadCodedIndex(metadata , offs , "MemberForwarded");

offs += GetCodedIndexSize("MemberForwarded");

ImplMapStruct[k].name = ReadStringIndex(metadata, offs);

offs += offsetstring;

ImplMapStruct[k].scope = ReadTableIndex(metadata, offs);

offs += GetTableSize();

}

}

//FieldRVA

old = tableoffset;

b = tablepresent(29);

offs = tableoffset;

Console.WriteLine("FieldRVA Table Offset {0}" , offs);

tableoffset = old;

if ( b )

{

FieldRVAStruct = new FieldRVATable[rows[29] + 1];

for ( int k = 1 ; k <= rows[29] ; k++)

{

FieldRVAStruct[k].rva = BitConverter.ToInt32 (metadata, offs);

offs += 4;

FieldRVAStruct[k].fieldi = ReadTableIndex(metadata, offs);

offs += GetTableSize();

}

}

//Assembly

old = tableoffset;

b = tablepresent(32);

offs = tableoffset;

Console.WriteLine("Assembly Table Offset {0}" , offs);

tableoffset = old;

AssemblyStruct = new AssemblyTable[rows[32] + 1];

if ( b )

{

for ( int k = 1 ; k <= rows[32] ; k++)

{

AssemblyStruct[k].HashAlgId = BitConverter.ToInt32 (metadata, offs);

offs += 4;

AssemblyStruct[k].major = BitConverter.ToInt16 (metadata, offs);

offs += 2;

AssemblyStruct[k].minor = BitConverter.ToInt16 (metadata, offs);

offs += 2;

AssemblyStruct[k].build= BitConverter.ToInt16 (metadata, offs);

offs += 2;

AssemblyStruct[k].revision = BitConverter.ToInt16 (metadata, offs);

offs += 2;

AssemblyStruct[k].flags = BitConverter.ToInt32 (metadata, offs);

offs += 4;

AssemblyStruct[k].publickey = ReadBlobIndex(metadata, offs);

offs += offsetblob;

AssemblyStruct[k].name = ReadStringIndex(metadata, offs);

offs += offsetstring;

AssemblyStruct[k].culture = ReadStringIndex(metadata, offs);

offs += offsetstring;

}

}

//AssemblyRef

old = tableoffset;

b = tablepresent(35);

offs = tableoffset;

Console.WriteLine("AssembleyRef Table Offset {0}" , offs);

tableoffset = old;

if ( b )

{

AssemblyRefStruct = new AssemblyRefTable[rows[35] + 1];

for ( int k = 1 ; k <= rows[35]; k++)

{

AssemblyRefStruct[k].major = BitConverter.ToInt16 (metadata, offs);

offs += 2;

AssemblyRefStruct[k].minor = BitConverter.ToInt16 (metadata, offs);

offs += 2;

AssemblyRefStruct[k].build= BitConverter.ToInt16 (metadata, offs);

offs += 2;

AssemblyRefStruct[k].revision = BitConverter.ToInt16 (metadata, offs);

offs += 2;

AssemblyRefStruct[k].flags = BitConverter.ToInt32 (metadata, offs);

offs += 4;

AssemblyRefStruct[k].publickey = ReadBlobIndex(metadata, offs);

offs += offsetblob;

AssemblyRefStruct[k].name = ReadStringIndex(metadata, offs);

offs += offsetstring;

AssemblyRefStruct[k].culture = ReadStringIndex(metadata, offs);

offs += offsetstring;

AssemblyRefStruct[k].hashvalue = ReadBlobIndex(metadata, offs);

offs += offsetblob;

}

}

//File

old = tableoffset;

b = tablepresent(38);

offs = tableoffset;

Console.WriteLine("File Table Offset {0}" , offs);

tableoffset = old;

if ( b )

{

FileStruct = new FileTable[rows[38] + 1];

for ( int k = 1 ; k <= rows[38] ; k++)

{

FileStruct[k].flags = BitConverter.ToInt32 (metadata, offs);

offs += 4;

FileStruct[k].name = ReadStringIndex(metadata, offs);

offs += offsetstring;

FileStruct[k].index = ReadBlobIndex(metadata, offs);

offs += offsetblob;

}

}

//ExportedType

old = tableoffset;

b = tablepresent(39);

offs = tableoffset;

Console.WriteLine("ExportedType Table Offset {0}" , offs);

tableoffset = old;

if ( b )

{

ExportedTypeStruct = new ExportedTypeTable[rows[39] + 1];

for ( int k = 1 ; k <= rows[39] ; k++)

{

ExportedTypeStruct[k].flags = BitConverter.ToInt32 (metadata, offs);

offs += 4;

ExportedTypeStruct[k].typedefindex = BitConverter.ToInt32 (metadata, offs);

offs += 4;

ExportedTypeStruct[k].name = ReadStringIndex(metadata, offs);

offs += offsetstring;

ExportedTypeStruct[k].nspace = ReadStringIndex(metadata, offs);

offs += offsetstring;

ExportedTypeStruct[k].coded = ReadCodedIndex ( metadata, offs , "Implementation");

offs += GetCodedIndexSize("Implementation");

}

}

//ManifestResource

old = tableoffset;

b = tablepresent(40);

offs = tableoffset;

Console.WriteLine("ManifestResource Table Offset {0}" , offs);

tableoffset = old;

if ( b )

{

ManifestResourceStruct = new ManifestResourceTable[rows[40] + 1];

for ( int k = 1 ; k <= rows[40] ; k++)

{

ManifestResourceStruct[k].offset = BitConverter.ToInt32 (metadata, offs);

offs += 4;

ManifestResourceStruct[k].flags = BitConverter.ToInt32 (metadata, offs);

offs += 4;

ManifestResourceStruct[k].name = ReadStringIndex(metadata, offs);

offs += offsetstring;

ManifestResourceStruct[k].coded = ReadCodedIndex(metadata , offs , "Implementation");

offs += GetCodedIndexSize("");

}

}

//Nested Classes

old = tableoffset;

b = tablepresent(41);

offs = tableoffset;

Console.WriteLine("Nested Classes Offset {0}" , offs);

tableoffset = old;

if ( b )

{

NestedClassStruct = new NestedClassTable[rows[41] + 1];

for ( int k = 1 ; k <= rows[41] ; k++)

{

NestedClassStruct[k].nestedclass= ReadTableIndex(metadata, offs);

offs += GetTableSize();

NestedClassStruct[k].enclosingclass= ReadTableIndex(metadata, offs);

offs += GetTableSize();

}

}

}

public long ConvertRVA(long rva)

{

int i;

for ( i = 0 ; i < sections ; i++)

{

if ( rva >= SVirtualAddress[i]  && ( rva <  SVirtualAddress[i] + SSizeOfRawData[i] ))

break ;

}

if ( i >= SPointerToRawData.Length)

return -1;

return SPointerToRawData[i] + ( rva - SVirtualAddress[i] );

}

public void CLRHeader()

{

Console.WriteLine("// CLR Header:");

s.Position = ConvertRVA(datadirectoryrva[14]);

int size = r.ReadInt32();

int majorruntimeversion = r.ReadInt16();

int minorruntimeversion = r.ReadInt16();

metadatarva = r.ReadInt32();

int metadatasize = r.ReadInt32();

corflags = r.ReadInt32();

entrypointtoken = r.ReadInt32();

int resourcesrva = r.ReadInt32();

int resourcessize = r.ReadInt32();

int strongnamesigrva = r.ReadInt32();

int strongnamesigsize = r.ReadInt32();

int codemanagerrva = r.ReadInt32();

int codemanagersize = r.ReadInt32();

vtablerva = r.ReadInt32();

vtablesize = r.ReadInt32();

exportaddressrva = r.ReadInt32();

exportaddresssize = r.ReadInt32();

int managednativeheaderrva = r.ReadInt32();

int managednativeheadersize = r.ReadInt32();

Console.WriteLine("// {0}       Header Size", size);

Console.WriteLine("// {0}        Major Runtime Version", majorruntimeversion);

Console.WriteLine("// {0}        Minor Runtime Version", minorruntimeversion);

Console.WriteLine("// {0}        Flags", corflags);

string dummy = "// " + entrypointtoken.ToString("x");

dummy = dummy.PadRight(12) + "Entrypoint Token";

Console.WriteLine(dummy);

DisplayDataDirectory(metadatarva , metadatasize , "Metadata Directory");

DisplayDataDirectory(resourcesrva, resourcessize, "Resources Directory");

DisplayDataDirectory(strongnamesigrva, strongnamesigsize, "Strong Name Signature");

DisplayDataDirectory(codemanagerrva, codemanagersize, "CodeManager Table");

DisplayDataDirectory(vtablerva, vtablesize, "VTableFixups Directory");

DisplayDataDirectory(exportaddressrva, exportaddresssize , "Export Address Table");

DisplayDataDirectory(managednativeheaderrva, managednativeheadersize, "Precompile Header");

Console.WriteLine("// Code Manager Table:");

if ( codemanagerrva == 0)

Console.WriteLine("//  default");

}

public void DisplayStrings()

{

Console.WriteLine("\n Strings Stream\n");

for ( int k = 0 ; k < ssize[1] ; k ++ )

{

Console.Write("{0}" , (char) strings[k]);

if ( strings[k] == 0 )

Console.WriteLine();

}

}

public void DisplayUS()

{

Console.WriteLine("\n US Stream\n");

for ( int k = 0 ; k < ssize[2] ; k +=2 )

{

Console.Write("{0}" , (char) us[k]);

if ( us[k] == 0 )

Console.WriteLine();

}

}

public void DisplayGuid()

{

int st=1;

Console.WriteLine("\n GUID Stream\n");

Console.Write("{");

Console.Write("{0}{1}{2}{3}", guid[st+2].ToString("X") , guid[st+1].ToString("X") , guid[st].ToString("X") , guid[st-1].ToString("X"));

Console.Write("-{0}{1}-",guid[st+3].ToString("X") , guid[st+4].ToString("X"));

Console.Write("{0}{1}-",guid[st+6].ToString("X") , guid[st+5].ToString("X"));

Console.Write("{0}{1}-",guid[st+7].ToString("X") , guid[st+8].ToString("X"));

Console.Write("{0}{1}{2}{3}{4}{5}",guid[st+9].ToString("X"),guid[st+10].ToString("X"),guid[st+11].ToString("X"),guid[st+12].ToString("X"),guid[st+13].ToString("X"),guid[st+14].ToString("X"));

Console.Write("}\n");

}

public void ReadStreamsData()

{

startofmetadata = ConvertRVA(metadatarva);

Console.WriteLine("\nMetadata Details\n");

Console.WriteLine("Start of Metadata {0} rva={1}" , metadatarva , startofmetadata );

s.Position = startofmetadata ;

s.Seek(4 + 2 + 2 + 4 , SeekOrigin.Current);

int lengthofstring = r.ReadInt32();

Console.WriteLine("Length of String {0}" , lengthofstring );

s.Seek(lengthofstring , SeekOrigin.Current);

long padding = s.Position % 4 ;

padding = 4 - padding;

s.Seek(2 , SeekOrigin.Current);

int streams = r.ReadInt16();

Console.WriteLine("No of streams {0} Position={1}" , streams , s.Position);

streamnames = new string[5];

offset = new int[5];

ssize  = new int[5];

names = new byte[5][];

names[0] = new byte[10];

names[1] = new byte[10];

names[2] = new byte[10];

names[3] = new byte[10];

names[4] = new byte[10];

int j ;

Console.WriteLine("\n Stream Details\n");

for ( int i = 0 ; i < streams ; i++)

{

offset[i] = r.ReadInt32();

ssize[i] = r.ReadInt32();

Console.WriteLine("offset={0} size={1} Position={2}" , offset[i] , ssize[i] , s.Position);

j = 0;

byte bb ;

while ( true )

{

bb = r.ReadByte();

if ( bb == 0)

            break;

names[i][j] = bb;

            j++;

}

names[i][j] = bb;

streamnames[i] = GetStreamNames(names[i]);

while ( true )

{

if ( s.Position % 4 == 0 )

break;

byte  b = r.ReadByte();

if ( b != 0)

{

s.Seek(-1, SeekOrigin.Current);

break;

}

}

}

for ( int i = 0 ; i < streams ; i++)

{

if ( streamnames[i]  == "#~" )

{

metadata = new byte[ssize[i]];

s.Seek(startofmetadata + offset[i] , SeekOrigin.Begin);

for ( int k = 0 ; k < ssize[i] ; k ++)

metadata[k] = r.ReadByte();

}

if ( streamnames[i]  == "#Strings" )

{

strings = new byte[ssize[i]];

s.Seek(startofmetadata + offset[i] , SeekOrigin.Begin);

for ( int k = 0 ; k < ssize[i] ; k ++)

strings[k] = r.ReadByte();

DisplayStrings();

}

if ( streamnames[i]  == "#US" )

{

us = new byte[ssize[i]];

s.Seek(startofmetadata  + offset[i] , SeekOrigin.Begin);

for ( int k = 0 ; k < ssize[i] ; k ++)

us[k] = r.ReadByte();

DisplayUS();

}

if ( streamnames[i]  == "#GUID" )

{

guid = new byte[ssize[i]];

s.Seek(startofmetadata  + offset[i] , SeekOrigin.Begin);

for ( int k = 0 ; k < ssize[i] ; k ++)

guid[k] = r.ReadByte();

DisplayGuid();

}

if ( streamnames[i]  == "#Blob" )

{

blob = new byte[ssize[i]];

s.Seek(startofmetadata  + offset[i] , SeekOrigin.Begin);

for ( int k = 0 ; k < ssize[i] ; k ++)

blob[k] = r.ReadByte();

}

}

Console.WriteLine("\n Stream offset and stream size\n");

for ( int i = 0 ; i < streams ; i++)

{

Console.WriteLine("{0}...offset: {1} size:{2}" , streamnames[i] ,  offset[i] , ssize[i]);

}

int heapsizes = metadata[6];

if ( (heapsizes & 0x01) == 0x01)

offsetstring  = 4;

if ( (heapsizes & 0x02) == 0x02)

offsetguid = 4;

if ( (heapsizes & 0x04) == 0x04)

offsetblob = 4;

valid = BitConverter.ToInt64(metadata, 8);

tableoffset = 24;

rows = new int[64];

Array.Clear (rows, 0, rows.Length);

for ( int k = 0 ; k <= 63 ; k++)

{

int tablepresent = (int)(valid >> k ) & 1;

if ( tablepresent == 1)

{

rows[k] = BitConverter.ToInt32(metadata , tableoffset);

tableoffset += 4;

}

}

Console.WriteLine("\nNumber of Rows in the tables: \n");

for ( int k = 62 ; k >= 0 ; k--)

{

int tablepresent = (int)(valid >> k ) & 1;

if ( tablepresent == 1)

{

Console.WriteLine("{0}  :  {1}" , tablenames[k] , rows[k]);

}

}

}

public string GetStreamNames(byte [] b)

{

int i = 0;

while (b[i] != 0 )

{

i++;

}

System.Text.Encoding e = System.Text.Encoding.UTF8;

string  s = e.GetString(b , 0 , i  );

return s;

}

public int GetTableSize()

{

return 2;

}

public int ReadStringIndex(byte [] a , int o)

{

int z = 0;

if ( offsetstring == 2)

z = BitConverter.ToUInt16 (a , o );

if ( offsetstring == 4)

z = (int)BitConverter.ToUInt32 (a , o );

return z;

}

public int ReadBlobIndex(byte [] a , int o)

{

int z = 0;

if ( offsetblob == 2)

z = BitConverter.ToUInt16 (a , o );

if ( offsetblob == 4)

z = (int)BitConverter.ToUInt32 (a , o );

return z;

}

public int ReadGuidIndex(byte [] a , int o)

{

int z = 0;

if ( offsetguid == 2)

z = BitConverter.ToUInt16 (a , o );

if ( offsetguid == 4)

z = (int)BitConverter.ToUInt32 (a , o );

return z;

}

public int ReadTableIndex(byte [] a , int o)

{

int z = 0;

int z1 = GetTableSize();

if ( z1 == 2)

z = BitConverter.ToUInt16 (a , o );

if ( z1 == 4)

z = (int)BitConverter.ToUInt32 (a , o );

return z;

}

public void DisplayAllMethods (int i)

{

int start , startofnext=0;

start =  TypeDefStruct[i].mindex ;

if ( i == (TypeDefStruct.Length -1) )

{

startofnext= MethodStruct.Length;

}

else

startofnext = TypeDefStruct[i+1].mindex ;

Console.WriteLine("Number Of Methods {0}" , startofnext - start);

for ( int j = start ; j < startofnext ; j++)

{

Console.WriteLine("{0}. {1}", j , GetString(MethodStruct[j].name));

}

}

public void DisplayAllFields (int i)

{

if ( FieldStruct == null)

            return;

int start , startofnext=0;

start =  TypeDefStruct[i].findex ;

if ( i == (TypeDefStruct.Length -1) )

{

startofnext= FieldStruct.Length;

}

else

startofnext = TypeDefStruct[i+1].findex ;

Console.WriteLine("Number Of Fields {0}" , startofnext - start);

for ( int j = start ; j < startofnext ; j++)

{

Console.WriteLine("{0}. {1}", j , GetString(FieldStruct[j].name));

}

}

public void DisplayAllParams (int i)

{

if ( ParamStruct== null)

return;

int start , startofnext=0;

start =  MethodStruct[i].param;

if ( i == (MethodStruct.Length -1) )

{

startofnext= ParamStruct.Length;

}

else

startofnext = MethodStruct[i+1].param ;

Console.WriteLine("Number Of Params {0}" , startofnext - start);

for ( int j = start ; j < startofnext ; j++)

{

Console.WriteLine("{0}. {1}", j , GetString(ParamStruct[j].name));

}

}

public void DisplayAllEvents(int i)

{

int ii;

if ( EventMapStruct == null )

return;

for ( ii = 1 ; ii < EventMapStruct.Length ; ii++)

{

if ( i == (EventMapStruct[ii].index ) )

break;

}

if ( ii == EventMapStruct.Length)

return;

int start = EventMapStruct[ii].eindex;

int end;

if ( ii == EventMapStruct.Length -1 )

end = EventStruct.Length - 1;

else

end =  EventMapStruct[ii + 1].eindex -1;

Console.WriteLine("Number of Events {0}" , end - start + 1);

for ( int jj = start ; jj <= end ; jj++)

{

Console.WriteLine("{0}. {1}" , jj , GetString(EventStruct[jj].name));

}

}

public void DisplayAllProperties(int i)

{

int ii;

if ( PropertyMapStruct == null || PropertyMapStruct.Length == 1 )

return;

for ( ii = 1 ; ii < PropertyMapStruct.Length ; ii++)

{

if ( i == (PropertyMapStruct[ii].parent) )

break;

}

if ( ii == PropertyMapStruct.Length)

return;

int start = PropertyMapStruct[ii].propertylist;

int end;

if ( ii+1 == PropertyMapStruct.Length )

end = PropertyStruct.Length - 1;

else

end =  PropertyMapStruct[ii + 1].propertylist -1;

Console.WriteLine("Number of Properties {0}" , end - start + 1);

for ( int jj = start ; jj <= end ; jj++)

{

Console.WriteLine("{0}. {1}" , jj , GetString(PropertyStruct[jj].name));

}

}

public string GetString(int starting)

{

int i = starting;

while (strings[i] != 0 )

{

i++;

}

System.Text.Encoding e = System.Text.Encoding.UTF8;

string  s = e.GetString(strings, starting , i - starting  );

if ( s.Length == 0)

return "";

else

return s;

}

public int CorSigUncompressData( byte [] b , int index , out int answer)

{

int cb = 0;

answer = 0;

if ( (b[index] & 0x80) == 0x00)

{

cb = 1;

answer = b[index];

}

if ( (b[index] & 0xC0) == 0x80)

{

cb = 2;

answer = ((b[index] & 0x3f) <<8 ) |  b[index+1];

}

if ( (b[index] & 0xE0) == 0xC0)

{

cb = 3;

answer = ((b[index] & 0x1f) <<24 ) |  (b[index+1] << 16) |  (b[index+2] << 8) | b[index+3];

}

return cb;

}

public string GetType(int b)

{

if ( b == 0x01)

return "void";

if ( b == 0x02)

return "bool";

if ( b == 0x03)

return "char";

if ( b == 0x04)

return "int8";

if ( b == 0x05)

return "unsigned int8";

if ( b == 0x06)

return "int16";

if ( b == 0x07)

return "unsigned int16";

if ( b == 0x08)

return "int32";

if ( b == 0x09)

return "unsigned int32";

if ( b == 0x0a)

return "int64";

if ( b == 0x0b)

return "unsigned int64";

if ( b == 0x0c)

return "float32";

if ( b == 0x0d)

return "float64";

if ( b == 0x0e)

return "string";

if ( b == 0x0f)

return "pointer";

if ( b == 0x10)

return "referencetype";

if ( b== 0x11)

return "valuetype";

if ( b== 0x12)

return "class";

if ( b== 0x14)

return "array";

if ( b== 0x16)

return "typed byref";

if ( b== 0x18)

return "intptr";

if ( b== 0x19)

return "uintptr";

if ( b== 0x1b)

return "function ptr";

if ( b== 0x1c)

return "object";

if ( b== 0x1d)

return "sd array";

if ( b== 0x1f)

return "reqd mod";

if ( b== 0x20)

return "opt mod";

if ( b== 0x21)

return "internal";

if ( b== 0x40)

return "typed mod";

if ( b== 0x41)

return "sentinel";

if ( b== 0x45)

return "pinned";

return "user defined...unknown";

}

public string GetCustomAttributeTypeTable( int a)

{

string s = "";

int tag = a &  0x07;

if ( tag == 0)

s = s + "NotUsed";

if ( tag == 1)

s = s + "NotUsed";

if ( tag == 2)

s = s + "MethodDef";

if ( tag == 3)

s = s + "MethodRef";

if ( tag == 4)

s = s + "NotUsed";

return s;

}

public int GetResolutionScopeValue(int a)

{

return a >> 2;

}

public string GetResolutionScopeTable(int a)

{

string s = "";

int tag = a & 0x03;

if ( tag == 0 )

s = s + "Module"  ;

if ( tag == 1 )

s = s + "ModuleRef"  ;

if ( tag == 2 )

s = s + "AssemblyRef"  ;

if ( tag == 3 )

s = s + "TypeRef"  ;

return s;

}

public void DisplayModuleTable()

{

if( ModuleStruct != null)

{

Console.WriteLine("\nModule Table\n");

for ( int ii = 1 ; ii <= ModuleStruct.Length-1 ; ii++)

{

Console.WriteLine("Generation: {0}" ,ModuleStruct[ii].Generation );

Console.WriteLine("Name      :{0} {1}" ,  GetString(ModuleStruct[ii].Name) , ModuleStruct[ii].Name.ToString("X"));

Console.WriteLine("Mvid      :#GUID[{0}]" , ModuleStruct[ii].Mvid);

Console.WriteLine("EncId     :#GUID[{0}]" , ModuleStruct[ii].EncId );

Console.WriteLine("EncBaseId :#GUID[{0}]" , ModuleStruct[ii].EncBaseId);

Console.WriteLine();

}

}

}

public void DisplayTypeRefTable()

{

if ( TypeRefStruct != null)

{

Console.WriteLine("\nTypeRef Table\n");

for ( int ii = 1 ; ii <= TypeRefStruct.Length-1 ; ii++)

{

Console.WriteLine("Row[{0}]" , ii);

string tablename = GetResolutionScopeTable(TypeRefStruct[ii].resolutionscope) ;

int index = GetResolutionScopeValue(TypeRefStruct[ii].resolutionscope);

string s = DisplayTable(tablename ,index );

Console.WriteLine("ResolutionScope:{0}[{1}]...{2} " , tablename , index,s );

Console.WriteLine("Name           :{0}",GetString(TypeRefStruct[ii].name));

Console.WriteLine("Namespace      :{0}",GetString(TypeRefStruct[ii].nspace));

Console.WriteLine("\n");

}

}

}

public void DisplayTypeDefTable()

{

if (TypeDefStruct != null)

{

Console.WriteLine("TypeDefTable\n");

for ( int ii = 1 ; ii <= TypeDefStruct.Length -1 ; ii++)

{

Console.WriteLine("Row:{0}" , ii);

TypeAttributes flags = (TypeAttributes)TypeDefStruct[ii].flags;

Console.WriteLine("Flags     : {0}" , flags);

Console.WriteLine("Name      : {0}" , GetString(TypeDefStruct[ii].name));

Console.WriteLine("