且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

C# 获取非托管 C dll 导出列表

更新时间:2023-02-12 16:47:23

据我所知,.Net Framework 中没有任何类提供您需要的信息.

但是您可以使用 .Net 平台的平台调用服务 (PInvoke) 来使用 Win32 dbghelp.dll DLL 的功能.这个 DLL 是Windows 平台的调试工具.dbghelp DLL 提供一个名为 SymEnumerateSymbols64 的函数,它允许您枚举所有动态链接库的导出符号.还有一个较新的函数 SymEnumSymbols 也允许枚举导出的符号.

However you can use the platform invocation services (PInvoke) of the .Net platform to use the functions of the Win32 dbghelp.dll DLL. This DLL is part of the Debugging Tools for the Windows platform. The dbghelp DLL provides a function called SymEnumerateSymbols64 which allows you to enumerate all exported symbols of a dynamic link library. There is also a newer function called SymEnumSymbols which also allows to enumerate exported symbols.

下面的代码展示了一个关于如何使用 SymEnumerateSymbols64 的简单示例功能.

The code below shows a simple example on how to use the SymEnumerateSymbols64 function.

[DllImport("dbghelp.dll", SetLastError = true, CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SymInitialize(IntPtr hProcess, string UserSearchPath, [MarshalAs(UnmanagedType.Bool)]bool fInvadeProcess);

[DllImport("dbghelp.dll", SetLastError = true, CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SymCleanup(IntPtr hProcess);

[DllImport("dbghelp.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern ulong SymLoadModuleEx(IntPtr hProcess, IntPtr hFile,
     string ImageName, string ModuleName, long BaseOfDll, int DllSize, IntPtr Data, int Flags);

[DllImport("dbghelp.dll", SetLastError = true, CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SymEnumerateSymbols64(IntPtr hProcess,
   ulong BaseOfDll, SymEnumerateSymbolsProc64 EnumSymbolsCallback, IntPtr UserContext);

public delegate bool SymEnumerateSymbolsProc64(string SymbolName,
      ulong SymbolAddress, uint SymbolSize, IntPtr UserContext);

public static bool EnumSyms(string name, ulong address, uint size, IntPtr context)
{
  Console.Out.WriteLine(name);
  return true;
}    

static void Main(string[] args)
{
  IntPtr hCurrentProcess = Process.GetCurrentProcess().Handle;

  ulong baseOfDll;
  bool status;

  // Initialize sym.
  // Please read the remarks on MSDN for the hProcess
  // parameter.
  status = SymInitialize(hCurrentProcess, null, false);

  if (status == false)
  {
    Console.Out.WriteLine("Failed to initialize sym.");
    return;
  }

  // Load dll.
  baseOfDll = SymLoadModuleEx(hCurrentProcess,
                              IntPtr.Zero,
                              "c:\windows\system32\user32.dll",
                              null,
                              0,
                              0,
                              IntPtr.Zero,
                              0);

  if (baseOfDll == 0)
  {
    Console.Out.WriteLine("Failed to load module.");
    SymCleanup(hCurrentProcess);
    return;
  }

  // Enumerate symbols. For every symbol the 
  // callback method EnumSyms is called.
  if (SymEnumerateSymbols64(hCurrentProcess,
      BaseOfDll, EnumSyms, IntPtr.Zero) == false)
  {
    Console.Out.WriteLine("Failed to enum symbols.");
  }

  // Cleanup.
  SymCleanup(hCurrentProcess);
}

为了保持示例简单,我没有使用SymEnumSymbols 函数.我也做了这个例子不使用诸如 SafeHandle 类的类.Net 框架.如果你需要一个例子SymEnumSymbols 函数,让我知道.

In order to keep the example simple I did not use the SymEnumSymbols function. I've also did the example without using such classes as the SafeHandle class of the .Net framework. If you need a example for the SymEnumSymbols function, just let me know.