title: Viewing export table on an unmanaged dll in C#
body: <p>I am currently trying to create a C# application that will allow me to view the export table from an unmanaged DLL. My problem is, once I have all the pointers I need, I have no idea how to loop through the information that the API has provided me. Here is what I have right now:</p>
  
  <pre><code>using System;
  using System.ComponentModel;
  using System.Runtime.InteropServices;
  
  namespace DLLMapper
  {
  class DLLExportViewer
  {
          #region APIs
          [DllImport("imagehlp.dll")]
          public static extern Boolean MapAndLoad(String ImageName, String DllPath, ref LOADED_IMAGE LoadedImage, Boolean DotDll, Boolean ReadOnly);
  
          [DllImport("imagehlp.dll")]
          public static extern Boolean UnMapAndLoad(ref LOADED_IMAGE LoadedImage);
  
          [DllImport("dbghelp.dll")]
          public static extern IntPtr ImageDirectoryEntryToData(IntPtr Base, Boolean MappedAsImage, UInt16 DirectoryEntry, ref Int32 Size);
  
          [DllImport("dbghelp.dll")]
          public static extern IntPtr ImageRvaToVa(ref IMAGE_NT_HEADERS NtHeaders, IntPtr Base, UInt32 Rva, ref IMAGE_SECTION_HEADER LastRvaSection);
          #endregion
  
          #region Structures
          [StructLayout(LayoutKind.Sequential, Pack = 4)]
          public struct LOADED_IMAGE
          {
              public String ModuleName;
              public IntPtr hFile;
              public IntPtr MappedAddress;
              public IMAGE_NT_HEADERS FileHeader;
              public IMAGE_SECTION_HEADER LastRvaSection;
              public Int32 NumberOfSections;
              public IMAGE_SECTION_HEADER Sections;
              public Int32 Characteristics;
              public Boolean fSystemImage;
              public Boolean fDOSImage;
              public LIST_ENTRY Links;
              public Int32 SizeOfImage;
          }
  
          [StructLayout(LayoutKind.Sequential, Pack = 4)]
          public struct IMAGE_EXPORT_DIRECTORY
          {
              public UInt32 Characteristics;
              public UInt32 TimeDateStamp;
              public UInt16 MajorVersion;
              public UInt16 MinorVersion;
              public UInt32 Name;
              public UInt32 Base;
              public UInt32 NumberOfFunctions;
              public UInt32 NumberOfNames;
              public UInt32 AddressOfFunctions;
              public UInt32 AddressOfNames;
              public UInt32 AddressOfOrdinals;
          }
  
          [StructLayout(LayoutKind.Sequential, Pack = 4)]
          public struct IMAGE_NT_HEADERS
          {
              public Int32 Signature;
              public IMAGE_FILE_HEADER FileHeader;
              public IMAGE_OPTIONAL_HEADER OptionalHeader;
          }
  
          [StructLayout(LayoutKind.Sequential, Pack = 4)]
          public struct LIST_ENTRY
          {
              public IntPtr Flink;
              public IntPtr Blink;
          }
  
          [StructLayout(LayoutKind.Sequential, Pack = 4)]
          public struct IMAGE_SECTION_HEADER
          {
              [MarshalAs(UnmanagedType.ByValArray, SizeConst = IMAGE_SIZEOF_SHORT_NAME)]
              public Byte[] Name;
              public Misc Misc;
              public UInt32 PhysicalAddress;
              public UInt32 VirtualAddress;
              public UInt32 SizeOfRawData;
              public UInt32 PointerToRawData;
              public UInt32 PointerToRelocations;
              public UInt32 PointerToLinenumbers;
              public Int16 NumberOfRelocations;
              public Int16 NumberOfLinenumbers;
              public UInt32 Characteristics;
          }
  
          [StructLayout(LayoutKind.Sequential, Pack = 4)]
          public struct IMAGE_FILE_HEADER
          {
              public UInt16 Machine;
              public UInt16 NumberOfSections;
              public UInt32 TimeDateStamp;
              public UInt32 PointerToSymbolTable;
              public UInt32 NumberOfSymbols;
              public UInt16 SizeOfOptionalHeader;
              public UInt16 Characteristics;
          }
  
          [StructLayout(LayoutKind.Sequential, Pack = 4)]
          public struct IMAGE_OPTIONAL_HEADER
          {
              public UInt16 Magic;
              public Byte MajorLinkerVersion;
              public Byte MinorLinkerVersion;
              public UInt32 SizeOfCode;
              public UInt32 SizeOfInitializedData;
              public UInt32 SizeOfUninitializedData;
              public UInt32 AddressOfEntryPoint;
              public UInt32 BaseOfCode;
              public UInt32 BaseOfData;
              public UInt32 ImageBase;
              public UInt32 SectionAlignment;
              public UInt32 FileAlignment;
              public UInt16 MajorOperatingSystemVersion;
              public UInt16 MinorOperatingSystemVersion;
              public UInt16 MajorImageVersion;
              public UInt16 MinorImageVersion;
              public UInt16 MajorSubsystemVersion;
              public UInt16 MinorSubsystemVersion;
              public UInt32 Win32VersionValue;
              public UInt32 SizeOfImage;
              public UInt32 SizeOfHeaders;
              public UInt32 CheckSum;
              public UInt16 Subsystem;
              public UInt16 DllCharacteristics;
              public UInt32 SizeOfStackReserve;
              public UInt32 SizeOfStackCommit;
              public UInt32 SizeOfHeapReserve;
              public UInt32 SizeOfHeapCommit;
              public UInt32 LoaderFlags;
              public UInt32 NumberOfRvaAndSizes;
              [MarshalAs(UnmanagedType.ByValArray, SizeConst = IMAGE_NUMBEROF_DIRECTORY_ENTRIES)]
              public IMAGE_DATA_DIRECTORY[] DataDirectory;
          }
  
          [StructLayout(LayoutKind.Sequential, Pack = 4)]
          public struct IMAGE_DATA_DIRECTORY
          {
              public UInt32 VirtualAddress;
              public UInt32 Size;
          }
  
          [StructLayout(LayoutKind.Explicit)]
          public struct Misc
          {
              [FieldOffset(0)]
              public UInt32 PhysicalAddress;
              [FieldOffset(0)]
              public UInt32 VirtualSize;
          }
          #endregion
  
          #region Variables &amp; Constants
          public const Int32 IMAGE_SIZEOF_SHORT_NAME = 8;
          public const Int32 IMAGE_NUMBEROF_DIRECTORY_ENTRIES = 16;
          public const UInt16 IMAGE_DIRECTORY_ENTRY_EXPORT = 0;
  
          /// &lt;summary&gt;
          /// String value holding the path to the DLL file. This value is also returned by the FileName property.
          /// &lt;/summary&gt;
          private String sDLLFilePath;
  
          /// &lt;summary&gt;
          /// Boolean value that is return by the LibraryLoaded property.
          /// &lt;/summary&gt;
          private Boolean bLibraryLoaded;
  
          /// &lt;summary&gt;
          /// Int32 value that is returned by the FunctionCount property.
          /// &lt;/summary&gt;
          private Int32 iFunctionCount;
  
          /// &lt;summary&gt;
          /// Int32 value that is returned by the SizeOfImage property.
          /// &lt;/summary&gt;
          private Int32 iSizeOfCode;
  
          /// &lt;summary&gt;
          /// String array value that is returned by the ImageFunctions property.
          /// &lt;/summary&gt;
          private String[] sFunctions;
          #endregion
  
          #region Properties
          /// &lt;summary&gt;
          /// Gets a boolean value indicating if the library has been loaded successfully.
          /// &lt;/summary&gt;
          public Boolean LibraryLoaded { get { return bLibraryLoaded; } }
  
          /// &lt;summary&gt;
          /// Gets a string value indicating what file the class was initialized with.
          /// &lt;/summary&gt;
          public String FileName { get { return sDLLFilePath; } }
  
          /// &lt;summary&gt;
          /// Gets a string array of the functions within the image.
          /// &lt;/summary&gt;
          public String[] ImageFunctions { get { return sFunctions; } }
  
          /// &lt;summary&gt;
          /// Gets an Int32 value indicating the number of functions within the image.
          /// &lt;/summary&gt;
          public Int32 FunctionCount { get { return iFunctionCount; } }
          #endregion
  
          /// &lt;summary&gt;
          /// Initilizes the DLLExportViewer class.
          /// &lt;/summary&gt;
          /// &lt;param name="sFilePath"&gt;Path to the DLL file to initilize the class with.&lt;/param&gt;
          public DLLExportViewer(String sFilePath)
          {
              IMAGE_SECTION_HEADER ishSectionHeader = new IMAGE_SECTION_HEADER();
              LOADED_IMAGE liLoadedImage = new LOADED_IMAGE();
              IMAGE_EXPORT_DIRECTORY iedExportDirectory;
              IntPtr pImageExportDirectory;
              IntPtr pVirtualAddressOfNames;
              Int32 iDirectoryExportSize = 0;
  
              sDLLFilePath = sFilePath;
  
              if (MapAndLoad(sDLLFilePath, null, ref liLoadedImage, true, true))
              {
                  bLibraryLoaded = true;
  
                  pImageExportDirectory = ImageDirectoryEntryToData(liLoadedImage.MappedAddress, false, IMAGE_DIRECTORY_ENTRY_EXPORT, ref iDirectoryExportSize);
                  iedExportDirectory = (IMAGE_EXPORT_DIRECTORY)Marshal.PtrToStructure(pImageExportDirectory, typeof(IMAGE_EXPORT_DIRECTORY));
  
                  iFunctionCount = (Int32)iedExportDirectory.NumberOfFunctions;
  
                  pVirtualAddressOfNames = ImageRvaToVa(ref liLoadedImage.FileHeader, liLoadedImage.MappedAddress, iedExportDirectory.AddressOfNames, ref ishSectionHeader);
              }
              else
              {
                  throw new Exception(String.Format("Failed to load library {0}\n\nError Number:{1]\nError:{2}", sDLLFilePath, Marshal.GetLastWin32Error(), new Win32Exception(Marshal.GetLastWin32Error()).Message));
              }
          }
      }
  }
  </code></pre>
  
  <p>My biggest concern is that I may have some of the marshalling on the structures wrong. But, all in all, I'm not sure where to go from here. Can anyone offer me some assistance?</p>