Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# get the list of unmanaged C dll exports

Tags:

c

c#

interop

dll

cdecl

I have a C dll with exported functions

I can use the command-line tool dumpbin.exe /EXPORTS to extract the list of exported functions, and then use them in my C# code to (successfully) call these functions.

Is there a way to get this exported-functions-list directly from .NET, without having to use an external command-line tool?

Thanks

like image 775
ZivF Avatar asked Aug 15 '13 09:08

ZivF


1 Answers

As far as I know there is no class in the .Net Framework that provides the information you need.

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.

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);
}

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.

like image 167
Hans Avatar answered Sep 20 '22 17:09

Hans