Parse entries of import section
authorAmy Yu <amycmyu@gmail.com>
Tue, 19 Jun 2018 21:42:05 +0000 (14:42 -0700)
committerAmy Yu <amycmyu@gmail.com>
Tue, 19 Jun 2018 21:42:05 +0000 (14:42 -0700)
src/tools/r2rdump/R2RDump.cs
src/tools/r2rdump/R2RImportSection.cs
src/tools/r2rdump/R2RReader.cs

index 6a5cc34..ccc736a 100644 (file)
@@ -286,7 +286,31 @@ namespace R2RDump
                 case R2RSection.SectionType.READYTORUN_SECTION_IMPORT_SECTIONS:
                     foreach (R2RImportSection importSection in r2r.ImportSections)
                     {
-                        _writer.WriteLine(importSection.ToString());
+                        _writer.Write(importSection.ToString());
+                        if (_raw && importSection.Entries.Count != 0)
+                        {
+                            if (importSection.SectionRVA != 0)
+                            {
+                                _writer.WriteLine("Section Bytes:");
+                                DumpBytes(r2r, importSection.SectionRVA, (uint)importSection.SectionSize);
+                            }
+                            if (importSection.SignatureRVA != 0)
+                            {
+                                _writer.WriteLine("Signature Bytes:");
+                                DumpBytes(r2r, importSection.SignatureRVA, (uint)importSection.Entries.Count * sizeof(int));
+                            }
+                            if (importSection.AuxiliaryDataRVA != 0)
+                            {
+                                _writer.WriteLine("AuxiliaryData Bytes:");
+                                DumpBytes(r2r, importSection.AuxiliaryDataRVA, (uint)importSection.AuxiliaryData.Size);
+                            }
+                        }
+                        foreach (R2RImportSection.ImportSectionEntry entry in importSection.Entries)
+                        {
+                            _writer.WriteLine();
+                            _writer.WriteLine(entry.ToString());
+                        }
+                        _writer.WriteLine();
                     }
                     break;
             }
index 39f816b..aa567d5 100644 (file)
@@ -3,22 +3,54 @@
 // See the LICENSE file in the project root for more information.
 
 using System;
+using System.Collections.Generic;
+using System.Reflection.PortableExecutable;
 using System.Text;
 
 namespace R2RDump
 {
     struct R2RImportSection
     {
-        public enum ImportSectionType
+        public enum CorCompileImportType
         {
-            READYTORUN_IMPORT_SECTION_TYPE_UNKNOWN = 0,
+            CORCOMPILE_IMPORT_TYPE_UNKNOWN = 0,
+            CORCOMPILE_IMPORT_TYPE_EXTERNAL_METHOD = 1,
+            CORCOMPILE_IMPORT_TYPE_STUB_DISPATCH = 2,
+            CORCOMPILE_IMPORT_TYPE_STRING_HANDLE = 3,
+            CORCOMPILE_IMPORT_TYPE_TYPE_HANDLE = 4,
+            CORCOMPILE_IMPORT_TYPE_METHOD_HANDLE = 5,
+            CORCOMPILE_IMPORT_TYPE_VIRTUAL_METHOD = 6,
         };
 
-        public enum ImportSectionFlags
+        public enum CorCompileImportFlags
         {
-            READYTORUN_IMPORT_SECTION_FLAGS_EAGER = 0x0001,
+            CORCOMPILE_IMPORT_FLAGS_EAGER = 0x0001,   // Section at module load time.
+            CORCOMPILE_IMPORT_FLAGS_CODE = 0x0002,   // Section contains code.
+            CORCOMPILE_IMPORT_FLAGS_PCODE = 0x0004,   // Section contains pointers to code.
         };
 
+        public struct ImportSectionEntry
+        {
+            public long Section { get; }
+            public uint SignatureRVA { get; }
+            public uint Signature { get; }
+            public ImportSectionEntry(long section, uint signatureRVA, uint signature)
+            {
+                Section = section;
+                SignatureRVA = signatureRVA;
+                Signature = signature;
+            }
+
+            public override string ToString()
+            {
+                StringBuilder sb = new StringBuilder();
+                sb.AppendLine($"\tSection: 0x{Section:X8} ({Section})");
+                sb.AppendLine($"\tSignatureRVA: 0x{SignatureRVA:X8} ({SignatureRVA})");
+                sb.AppendLine($"\tSection: 0x{Signature:X8} ({Signature})");
+                return sb.ToString();
+            }
+        }
+
         /// <summary>
         /// Section containing values to be fixed up
         /// </summary>
@@ -28,12 +60,12 @@ namespace R2RDump
         /// <summary>
         /// One or more of ImportSectionFlags
         /// </summary>
-        public ushort Flags { get; }
+        public CorCompileImportFlags Flags { get; }
 
         /// <summary>
         /// One of ImportSectionType
         /// </summary>
-        public ImportSectionType Type { get; }
+        public CorCompileImportType Type { get; }
 
         /// <summary>
         /// 
@@ -43,34 +75,49 @@ namespace R2RDump
         /// <summary>
         /// RVA of optional signature descriptors
         /// </summary>
-        public int Signatures { get; }
+        public int SignatureRVA { get; }
+        public List<ImportSectionEntry> Entries { get; }
 
         /// <summary>
         /// RVA of optional auxiliary data (typically GC info)
         /// </summary>
-        public int AuxiliaryData { get; }
+        public int AuxiliaryDataRVA { get; }
+        public GcInfo AuxiliaryData { get; }
 
-        public R2RImportSection(int rva, int size, ushort flags, byte type, byte entrySize, int sig, int data)
+        public R2RImportSection(byte[] image, int rva, int size, CorCompileImportFlags flags, byte type, byte entrySize, int signatureRVA, List<ImportSectionEntry> entries, int auxDataRVA, int auxDataOffset, Machine machine, ushort majorVersion)
         {
             SectionRVA = rva;
             SectionSize = size;
             Flags = flags;
-            Type = (ImportSectionType)type;
+            Type = (CorCompileImportType)type;
             EntrySize = entrySize;
-            Signatures = sig;
-            AuxiliaryData = data;
+
+            SignatureRVA = signatureRVA;
+            Entries = entries;
+
+            AuxiliaryDataRVA = auxDataRVA;
+            AuxiliaryData = null;
+            if (AuxiliaryDataRVA != 0)
+            {
+                AuxiliaryData = new GcInfo(image, auxDataOffset, machine, majorVersion);
+            }
         }
 
         public override string ToString()
         {
             StringBuilder sb = new StringBuilder();
-            sb.AppendLine($"SectionRVA: 0x{SectionRVA:X8}");
+            sb.AppendLine($"SectionRVA: 0x{SectionRVA:X8} ({SectionRVA})");
             sb.AppendLine($"SectionSize: {SectionSize} bytes");
-            sb.AppendLine($"Flags: {Enum.GetName(typeof(ImportSectionFlags), Flags)}({Flags})");
+            sb.AppendLine($"Flags: {Flags}");
             sb.AppendLine($"Type: {Type}");
             sb.AppendLine($"EntrySize: {EntrySize}");
-            sb.AppendLine($"Signatures: 0x{Signatures:X8}");
-            sb.AppendLine($"AuxiliaryData: {AuxiliaryData}");
+            sb.AppendLine($"SignatureRVA: 0x{SignatureRVA:X8} ({SignatureRVA})");
+            sb.AppendLine($"AuxiliaryDataRVA: 0x{AuxiliaryDataRVA:X8} ({AuxiliaryDataRVA})");
+            if (AuxiliaryDataRVA != 0)
+            {
+                sb.AppendLine("AuxiliaryData:");
+                sb.AppendLine(AuxiliaryData.ToString());
+            }
             return sb.ToString();
         }
     }
index 7e32a7e..eeced9e 100644 (file)
@@ -301,13 +301,61 @@ namespace R2RDump
             while (offset < endOffset)
             {
                 int rva = NativeReader.ReadInt32(Image, ref offset);
+                int sectionOffset = GetOffset(rva);
                 int size = NativeReader.ReadInt32(Image, ref offset);
-                ushort flags = NativeReader.ReadUInt16(Image, ref offset);
+                R2RImportSection.CorCompileImportFlags flags = (R2RImportSection.CorCompileImportFlags)NativeReader.ReadUInt16(Image, ref offset);
                 byte type = NativeReader.ReadByte(Image, ref offset);
                 byte entrySize = NativeReader.ReadByte(Image, ref offset);
-                int sig = NativeReader.ReadInt32(Image, ref offset);
-                int data = NativeReader.ReadInt32(Image, ref offset);
-                ImportSections.Add(new R2RImportSection(rva, size, flags, type, entrySize, sig, data));
+                int entryCount = 0;
+                if (entrySize != 0)
+                {
+                    entryCount = size / entrySize;
+                }
+                int signatureRVA = NativeReader.ReadInt32(Image, ref offset);
+
+                int signatureOffset = 0;
+                if (signatureRVA != 0)
+                {
+                    signatureOffset = GetOffset(signatureRVA);
+                }
+                List<R2RImportSection.ImportSectionEntry> entries = new List<R2RImportSection.ImportSectionEntry>();
+                switch (flags)
+                {
+                    case R2RImportSection.CorCompileImportFlags.CORCOMPILE_IMPORT_FLAGS_EAGER:
+                        {
+                            int tempSignatureOffset = signatureOffset;
+                            int firstSigRva = NativeReader.ReadInt32(Image, ref tempSignatureOffset);
+                            uint sigRva = 0;
+                            while (sigRva != firstSigRva)
+                            {
+                                sigRva = NativeReader.ReadUInt32(Image, ref signatureOffset);
+                                long section = NativeReader.ReadInt64(Image, ref sectionOffset);
+                                int sigOff = GetOffset((int)sigRva);
+                                uint signature = NativeReader.ReadUInt32(Image, ref sigOff);
+                                entries.Add(new R2RImportSection.ImportSectionEntry(section, sigRva, signature));
+                            }
+                        }
+                        break;
+                    case R2RImportSection.CorCompileImportFlags.CORCOMPILE_IMPORT_FLAGS_CODE:
+                    case R2RImportSection.CorCompileImportFlags.CORCOMPILE_IMPORT_FLAGS_PCODE:
+                        for (int i = 0; i < entryCount; i++)
+                        {
+                            long section = NativeReader.ReadInt64(Image, ref sectionOffset);
+                            uint sigRva = NativeReader.ReadUInt32(Image, ref signatureOffset);
+                            int sigOff = GetOffset((int)sigRva);
+                            uint signature = NativeReader.ReadUInt32(Image, ref sigOff);
+                            entries.Add(new R2RImportSection.ImportSectionEntry(section, sigRva, signature));
+                        }
+                        break;
+                }
+
+                int auxDataRVA = NativeReader.ReadInt32(Image, ref offset);
+                int auxDataOffset = 0;
+                if (auxDataRVA != 0)
+                {
+                    auxDataOffset = GetOffset(auxDataRVA);
+                }
+                ImportSections.Add(new R2RImportSection(Image, rva, size, flags, type, entrySize, signatureRVA, entries, auxDataRVA, auxDataOffset, Machine, R2RHeader.MajorVersion));
             }
         }