Lister les fonctions d'une DLL inconnue grâce à dumpbin.exe

Tutoriel pour apprendre à lister les fonctions d'une DLL inconnue avec dumpbin.exe puis appel de référence et intégration dans un appel direct en Csharp

  Publié le

Il arrive (parfois) de devoir lister les fonctions d'une bibliothèque (mal documentée) pour pouvoir les utiliser.

Pour lister (sur windows avec une installation de visual studio 2017 ou de community 2019) :

Ouvrir un invite de commande (ou une console powershell)

Se placer dans :

C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.13.26128\bin\Hostx64\x64

ou pour la dernière version 2019 :

C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.25.28610\bin\Hostx64\x64

Appeler dumpbin.exe de la manière suivante :

.\dumpbin.exe /exports D:\DLL\maDll.dll

Le retour du programme dumpbin sera une tableau à 4 colonnes ordinal, hint, RVA, name.

Notre intérêt se portera sur le contenu de la colonne name.

 

Pour en faire usage directement dans du C# :

Il suffit d'ajouter le nom de la DLL cible puis de définir en point d'entrée le nom de l'une des fonctions d'accessibilité publique remontées par le rapport de dumpbin.exe.

[DllImport("maDll.dll", EntryPoint = "nameFunction", CallingConvention = CallingConvention.Cdecl)]
public static extern void aliasNameFunction(IntPtr context, Int32 device, Int32 Precedence);

Mise en application pratique de listage des fonctions d'une DLL et intégration dans un code en C# :

Supposons une DLL Morrigan_x64.dll dont nous ignorons les fonctions accessibles.

Cette DLL se trouve dans J:\Mods arma3\Morrigan.

Nous ouvrons un nouveau terminal (Win+R puis taper cmd) ensuite, nous nous plaçons dans le répertoire parent de dumbin :

cd C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.25.28610\bin\Hostx64\x64

Nous appelons dumpbin en lui passant pour paramètre /exports ainsi que l'emplacement relatif de la DLL par rapport au répertoire où nous nous trouvons.

C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.25.28610\bin\Hostx64\x64>.\dumpbin.exe /exports "J:\Mods arma3\Morrigan\Morrigan_x64.dll"

Le résultat nous permet de constater 4 fonctions d'accéssibilités publiques RVEtension,RVEtensionArgs,RVEtensionRegisterCallback,RVEtensionVersion :

Microsoft (R) COFF/PE Dumper Version 14.25.28614.0
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file J:\Mods arma3\Morrigan\Morrigan_x64.dll

File Type: DLL

  Section contains the following exports for \Morrigan_x64.dll

    00000000 characteristics
    5F89692B time date stamp Fri Oct 16 11:34:35 2020
        0.00 version
           0 ordinal base
           4 number of functions
           4 number of names

    ordinal hint RVA      name

          2    0 000054A6 RVExtension
          3    1 000054B2 RVExtensionArgs
          0    2 0000548E RVExtensionRegisterCallback
          1    3 0000549A RVExtensionVersion

  Summary

        2000 .reloc
        2000 .rsrc
        2000 .sdata
        4000 .text

À partir de là, nous pouvons créer une nouvelle solution de type console en C# dans visual studio. Nous assignons une nouvelle référence (Référence > Clique droit > Ajouter une référence > Parcourir > Trouver J:\Mods arma3\Morrigan\Morrigan_x64.dll > Ok).

Nous ajoutons un appel à la librairie et constatons qu'elles possibilités nous offrent l'IDE, ici DllEntry et Orders_Functions. Nous saisons à tour de rôle les deux classes et effectuons un CTRL+Clique gauche sur le nom de la classe.

var test1 = new Morrigan.DllEntry();

Nous constatons une nouvelle fois la présence des classes découvertent par dumpbin.

namespace Morrigan
{
    public class DllEntry
    {
        public static ExtensionCallback callback;

        public DllEntry();

        public static void RvExtension(StringBuilder output, int outputSize, string function);
        public static int RvExtensionArgs(StringBuilder output, int outputSize, string function, string[] args, int argCount);
        public static void RVExtensionRegisterCallback(ExtensionCallback func);
        public static void RvExtensionVersion(StringBuilder output, int outputSize);

        public delegate int ExtensionCallback(string name, string function, string data);
    }
}

Puis sur Orders_Functions :

var test2 = new Morrigan.Orders_Functions(null,null);
namespace Morrigan
{
    public class Orders_Functions
    {
        public Orders_Functions(string in_function, string[] in_args = null);

        public int Auto_Execute(StringBuilder in_output);
    }
}

Il est interessant de constater que dumbin n'à découvert que les fonctions public et static.

La suite du processus n'est qu'une série de tests pour découvrir ce que produit chaque fonction ou bien vous pouvez utiliser des outils de décompilation de DLL comme JetBrains dotPeek qui permet carrement de lire le contenu d'une DLL et d'accèder à sa logique métier.