2011-01-05 23 views
3

現在、アンマネージDLLからエクスポートテーブルを表示できるようにするC#アプリケーションを作成しようとしています。私の問題は、必要なすべてのポインタがあれば、APIが私に提供した情報をどのようにループするか分かりません。ここで私が今持っているものです。C#のアンマネージdllでエクスポートテーブルを表示

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 & 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; 

     /// <summary> 
     /// String value holding the path to the DLL file. This value is also returned by the FileName property. 
     /// </summary> 
     private String sDLLFilePath; 

     /// <summary> 
     /// Boolean value that is return by the LibraryLoaded property. 
     /// </summary> 
     private Boolean bLibraryLoaded; 

     /// <summary> 
     /// Int32 value that is returned by the FunctionCount property. 
     /// </summary> 
     private Int32 iFunctionCount; 

     /// <summary> 
     /// Int32 value that is returned by the SizeOfImage property. 
     /// </summary> 
     private Int32 iSizeOfCode; 

     /// <summary> 
     /// String array value that is returned by the ImageFunctions property. 
     /// </summary> 
     private String[] sFunctions; 
     #endregion 

     #region Properties 
     /// <summary> 
     /// Gets a boolean value indicating if the library has been loaded successfully. 
     /// </summary> 
     public Boolean LibraryLoaded { get { return bLibraryLoaded; } } 

     /// <summary> 
     /// Gets a string value indicating what file the class was initialized with. 
     /// </summary> 
     public String FileName { get { return sDLLFilePath; } } 

     /// <summary> 
     /// Gets a string array of the functions within the image. 
     /// </summary> 
     public String[] ImageFunctions { get { return sFunctions; } } 

     /// <summary> 
     /// Gets an Int32 value indicating the number of functions within the image. 
     /// </summary> 
     public Int32 FunctionCount { get { return iFunctionCount; } } 
     #endregion 

     /// <summary> 
     /// Initilizes the DLLExportViewer class. 
     /// </summary> 
     /// <param name="sFilePath">Path to the DLL file to initilize the class with.</param> 
     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)); 
      } 
     } 
    } 
} 

私の最大の懸念は、私が間違っている構造上のマーシャリングのいくつかを持っているかもしれないということです。しかし、まったく、私はここからどこに行くのかは分かりません。誰か私に援助を提供することはできますか?

+2

ホイールを再発明しています。 Dumpbin.exe/exportsを使用 –

+0

私はホイールを再発明していることを知っています。私はそれをする方法を学び、別のユーティリティを使用するだけではありません。 – QuantumPhysGuy

+0

@dotNetNin​​jaあなたのユーザー名を変更してください - もしあなたがdotNetNin​​jaなら、あなたはこの質問に尋ねるのではなく答えるでしょう! ;-) –

答えて

0

APIを使用する代わりに、エクスポートテーブルの場所を見つけるためにPEヘッダーを解析するクラスを作成しました。私はこれを行うためにMicrosoftのPEファイルフォーマット仕様を使用しました。

Microsoft Portable Executable and Common Object File Format Specification

+0

それはあなたにとってとてもいいですが、他の人には役に立たないです。 –

2

以下は、pを使用して、それを行う方法を示しています/ dbghelpに起動します。私はpinvoke.netからいくつかの宣言を使用したことに注意してください。

using System; 
using System.Text; 
using System.Runtime.InteropServices; 
using Microsoft.Win32.SafeHandles; 
using System.ComponentModel; 

internal static class NativeMethods 
{ 
    [Flags] 
    public enum EFileAccess : uint 
    { 
     // 
     // Standard Section 
     // 

     AccessSystemSecurity = 0x1000000, // AccessSystemAcl access type 
     MaximumAllowed = 0x2000000,  // MaximumAllowed access type 

     Delete = 0x10000, 
     ReadControl = 0x20000, 
     WriteDAC = 0x40000, 
     WriteOwner = 0x80000, 
     Synchronize = 0x100000, 

     StandardRightsRequired = 0xF0000, 
     StandardRightsRead = ReadControl, 
     StandardRightsWrite = ReadControl, 
     StandardRightsExecute = ReadControl, 
     StandardRightsAll = 0x1F0000, 
     SpecificRightsAll = 0xFFFF, 

     FILE_READ_DATA = 0x0001,  // file & pipe 
     FILE_LIST_DIRECTORY = 0x0001,  // directory 
     FILE_WRITE_DATA = 0x0002,  // file & pipe 
     FILE_ADD_FILE = 0x0002,   // directory 
     FILE_APPEND_DATA = 0x0004,  // file 
     FILE_ADD_SUBDIRECTORY = 0x0004,  // directory 
     FILE_CREATE_PIPE_INSTANCE = 0x0004, // named pipe 
     FILE_READ_EA = 0x0008,   // file & directory 
     FILE_WRITE_EA = 0x0010,   // file & directory 
     FILE_EXECUTE = 0x0020,   // file 
     FILE_TRAVERSE = 0x0020,   // directory 
     FILE_DELETE_CHILD = 0x0040,  // directory 
     FILE_READ_ATTRIBUTES = 0x0080,  // all 
     FILE_WRITE_ATTRIBUTES = 0x0100,  // all 

     // 
     // Generic Section 
     // 

     GenericRead = 0x80000000, 
     GenericWrite = 0x40000000, 
     GenericExecute = 0x20000000, 
     GenericAll = 0x10000000, 

     SPECIFIC_RIGHTS_ALL = 0x00FFFF, 
     FILE_ALL_ACCESS = 
     StandardRightsRequired | 
     Synchronize | 
     0x1FF, 

     FILE_GENERIC_READ = 
     StandardRightsRead | 
     FILE_READ_DATA | 
     FILE_READ_ATTRIBUTES | 
     FILE_READ_EA | 
     Synchronize, 

     FILE_GENERIC_WRITE = 
     StandardRightsWrite | 
     FILE_WRITE_DATA | 
     FILE_WRITE_ATTRIBUTES | 
     FILE_WRITE_EA | 
     FILE_APPEND_DATA | 
     Synchronize, 

     FILE_GENERIC_EXECUTE = 
     StandardRightsExecute | 
      FILE_READ_ATTRIBUTES | 
      FILE_EXECUTE | 
      Synchronize 
    } 

    [Flags] 
    public enum EFileShare : uint 
    { 
     /// <summary> 
     /// 
     /// </summary> 
     None = 0x00000000, 
     /// <summary> 
     /// Enables subsequent open operations on an object to request read access. 
     /// Otherwise, other processes cannot open the object if they request read access. 
     /// If this flag is not specified, but the object has been opened for read access, the function fails. 
     /// </summary> 
     Read = 0x00000001, 
     /// <summary> 
     /// Enables subsequent open operations on an object to request write access. 
     /// Otherwise, other processes cannot open the object if they request write access. 
     /// If this flag is not specified, but the object has been opened for write access, the function fails. 
     /// </summary> 
     Write = 0x00000002, 
     /// <summary> 
     /// Enables subsequent open operations on an object to request delete access. 
     /// Otherwise, other processes cannot open the object if they request delete access. 
     /// If this flag is not specified, but the object has been opened for delete access, the function fails. 
     /// </summary> 
     Delete = 0x00000004 
    } 

    public enum ECreationDisposition : uint 
    { 
     /// <summary> 
     /// Creates a new file. The function fails if a specified file exists. 
     /// </summary> 
     New = 1, 
     /// <summary> 
     /// Creates a new file, always. 
     /// If a file exists, the function overwrites the file, clears the existing attributes, combines the specified file attributes, 
     /// and flags with FILE_ATTRIBUTE_ARCHIVE, but does not set the security descriptor that the SECURITY_ATTRIBUTES structure specifies. 
     /// </summary> 
     CreateAlways = 2, 
     /// <summary> 
     /// Opens a file. The function fails if the file does not exist. 
     /// </summary> 
     OpenExisting = 3, 
     /// <summary> 
     /// Opens a file, always. 
     /// If a file does not exist, the function creates a file as if dwCreationDisposition is CREATE_NEW. 
     /// </summary> 
     OpenAlways = 4, 
     /// <summary> 
     /// Opens a file and truncates it so that its size is 0 (zero) bytes. The function fails if the file does not exist. 
     /// The calling process must open the file with the GENERIC_WRITE access right. 
     /// </summary> 
     TruncateExisting = 5 
    } 

    [Flags] 
    public enum EFileAttributes : uint 
    { 
     Readonly = 0x00000001, 
     Hidden = 0x00000002, 
     System = 0x00000004, 
     Directory = 0x00000010, 
     Archive = 0x00000020, 
     Device = 0x00000040, 
     Normal = 0x00000080, 
     Temporary = 0x00000100, 
     SparseFile = 0x00000200, 
     ReparsePoint = 0x00000400, 
     Compressed = 0x00000800, 
     Offline = 0x00001000, 
     NotContentIndexed = 0x00002000, 
     Encrypted = 0x00004000, 
     Write_Through = 0x80000000, 
     Overlapped = 0x40000000, 
     NoBuffering = 0x20000000, 
     RandomAccess = 0x10000000, 
     SequentialScan = 0x08000000, 
     DeleteOnClose = 0x04000000, 
     BackupSemantics = 0x02000000, 
     PosixSemantics = 0x01000000, 
     OpenReparsePoint = 0x00200000, 
     OpenNoRecall = 0x00100000, 
     FirstPipeInstance = 0x00080000 
    } 

    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 
    public static extern SafeFileHandle CreateFile(
     string lpFileName, 
     EFileAccess dwDesiredAccess, 
     EFileShare dwShareMode, 
     IntPtr lpSecurityAttributes, 
     ECreationDisposition dwCreationDisposition, 
     EFileAttributes dwFlagsAndAttributes, 
     IntPtr hTemplateFile 
    ); 

    [Flags] 
    public enum FileMapProtection : uint 
    { 
     PageReadonly = 0x02, 
     PageReadWrite = 0x04, 
     PageWriteCopy = 0x08, 
     PageExecuteRead = 0x20, 
     PageExecuteReadWrite = 0x40, 
     SectionCommit = 0x8000000, 
     SectionImage = 0x1000000, 
     SectionNoCache = 0x10000000, 
     SectionReserve = 0x4000000, 
    } 

    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 
    public static extern SafeFileHandle CreateFileMapping(
     SafeFileHandle hFile, 
     IntPtr lpFileMappingAttributes, 
     FileMapProtection flProtect, 
     uint dwMaximumSizeHigh, 
     uint dwMaximumSizeLow, 
     string lpName 
    ); 

    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 
    public static extern SafeFileHandle CreateFileMapping(
     SafeFileHandle hFile, 
     IntPtr lpFileMappingAttributes, 
     FileMapProtection flProtect, 
     uint dwMaximumSizeHigh, 
     uint dwMaximumSizeLow, 
     IntPtr lpName 
    ); 

    [Flags] 
    public enum FileMapAccess : uint 
    { 
     FileMapCopy = 0x0001, 
     FileMapWrite = 0x0002, 
     FileMapRead = 0x0004, 
     FileMapAllAccess = 0x001f, 
     FileMapExecute = 0x0020, 
    } 

    [DllImport("kernel32.dll", SetLastError = true)] 
    public static extern IntPtr MapViewOfFile(
     SafeFileHandle hFileMappingObject, 
     FileMapAccess dwDesiredAccess, 
     UInt32 dwFileOffsetHigh, 
     UInt32 dwFileOffsetLow, 
     UIntPtr dwNumberOfBytesToMap 
    ); 

    [DllImport("kernel32.dll", SetLastError = true)] 
    public static extern bool UnmapViewOfFile(IntPtr lpBaseAddress); 

    [StructLayout(LayoutKind.Sequential)] 
    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)] 
    public struct IMAGE_DATA_DIRECTORY 
    { 
     public UInt32 VirtualAddress; 
     public UInt32 Size; 
    } 

    [StructLayout(LayoutKind.Sequential)] 
    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 = 16)] 
     public IMAGE_DATA_DIRECTORY[] DataDirectory; 
    } 

    [StructLayout(LayoutKind.Sequential)] 
    public struct IMAGE_NT_HEADERS 
    { 
     public UInt32 Signature; 
     public IMAGE_FILE_HEADER FileHeader; 
     public IMAGE_OPTIONAL_HEADER OptionalHeader; 
    } 

    [DllImport("dbghelp.dll", SetLastError = true)] 
    public static extern IntPtr ImageNtHeader(
     IntPtr ImageBase 
    ); 

    [StructLayout(LayoutKind.Sequential)] 
    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;  // RVA from base of image 
     public UInt32 AddressOfNames;  // RVA from base of image 
     public UInt32 AddressOfNameOrdinals; // RVA from base of image 
    } 

    [DllImport("dbghelp.dll", SetLastError = true)] 
    public static extern IntPtr ImageRvaToVa(
     IntPtr NtHeaders, 
     IntPtr Base, 
     UInt32 Rva, 
     IntPtr LastRvaSection 
    ); 
} 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     private static string[] GetExports(string ModuleFileName) 
     { 
      SafeFileHandle FileHandle = NativeMethods.CreateFile(
       ModuleFileName, 
       NativeMethods.EFileAccess.GenericRead, 
       NativeMethods.EFileShare.Read, 
       IntPtr.Zero, 
       NativeMethods.ECreationDisposition.OpenExisting, 
       NativeMethods.EFileAttributes.Normal, 
       IntPtr.Zero 
      ); 
      if (FileHandle.IsInvalid) 
       throw new Win32Exception(); 

      try 
      { 
       SafeFileHandle ImageHandle = NativeMethods.CreateFileMapping(
        FileHandle, 
        IntPtr.Zero, 
        NativeMethods.FileMapProtection.PageReadonly, 
        0, 
        0, 
        IntPtr.Zero 
       ); 
       if (ImageHandle.IsInvalid) 
        throw new Win32Exception(); 

       try 
       { 
        IntPtr ImagePointer = NativeMethods.MapViewOfFile(
         ImageHandle, 
         NativeMethods.FileMapAccess.FileMapRead, 
         0, 
         0, 
         UIntPtr.Zero 
        ); 
        if (ImagePointer == IntPtr.Zero) 
         throw new Win32Exception(); 

        try 
        { 
         IntPtr HeaderPointer = NativeMethods.ImageNtHeader(ImagePointer); 
         if (HeaderPointer == IntPtr.Zero) 
          throw new Win32Exception(); 

         NativeMethods.IMAGE_NT_HEADERS Header = (NativeMethods.IMAGE_NT_HEADERS)Marshal.PtrToStructure(
          HeaderPointer, 
          typeof(NativeMethods.IMAGE_NT_HEADERS) 
         ); 
         if (Header.Signature != 0x00004550)// "PE\0\0" as a DWORD 
          throw new Exception(ModuleFileName + " is not a valid PE file"); 

         IntPtr ExportTablePointer = NativeMethods.ImageRvaToVa(
          HeaderPointer, 
          ImagePointer, 
          Header.OptionalHeader.DataDirectory[0].VirtualAddress, 
          IntPtr.Zero 
         ); 
         if (ExportTablePointer == IntPtr.Zero) 
          throw new Win32Exception(); 
         NativeMethods.IMAGE_EXPORT_DIRECTORY ExportTable = (NativeMethods.IMAGE_EXPORT_DIRECTORY)Marshal.PtrToStructure(
          ExportTablePointer, 
          typeof(NativeMethods.IMAGE_EXPORT_DIRECTORY) 
         ); 

         IntPtr NamesPointer = NativeMethods.ImageRvaToVa(
          HeaderPointer, 
          ImagePointer, 
          ExportTable.AddressOfNames, 
          IntPtr.Zero 
         ); 
         if (NamesPointer == IntPtr.Zero) 
          throw new Win32Exception(); 

         NamesPointer = NativeMethods.ImageRvaToVa(
          HeaderPointer, 
          ImagePointer, 
          (UInt32)Marshal.ReadInt32(NamesPointer), 
          IntPtr.Zero 
         ); 
         if (NamesPointer == IntPtr.Zero) 
          throw new Win32Exception(); 

         string[] exports = new string[ExportTable.NumberOfNames]; 
         for (int i = 0; i < exports.Length; i++) 
         { 
          exports[i] = Marshal.PtrToStringAnsi(NamesPointer); 
          NamesPointer += exports[i].Length + 1; 
         } 

         return exports; 
        } 
        finally 
        { 
         if (!NativeMethods.UnmapViewOfFile(ImagePointer)) 
          throw new Win32Exception(); 
        } 
       } 
       finally 
       { 
        ImageHandle.Close(); 
       } 
      } 
      finally 
      { 
       FileHandle.Close(); 
      } 
     } 

     static void Main(string[] args) 
     { 
      foreach (string s in GetExports(@"C:\Windows\System32\kernel32.dll")) 
      { 
       Console.WriteLine(s); 
      } 
      Console.ReadLine(); 
     } 
    } 
} 
+0

私のためにうまくいかない、ImageRvaToVaは例外の結果、IntPtr.Zeroを返します。 – TarmoPikaro

関連する問題