現在、アンマネージDLLからエクスポートテーブルを表示できるC#アプリケーションを作成しようとしています。私の問題は、必要なすべてのポインターを取得すると、APIから提供された情報をループする方法がわからないことです。これが私が今持っているものです:
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));
}
}
}
}
私の最大の懸念は、構造のマーシャリングの一部が間違っている可能性があることです。しかし、全体として、私はここからどこに行くべきかわかりません。誰かが私にいくつかの援助を提供できますか?