Retransformer une DLL en projet compilable avec Glass.NET
Lire du C# décompilé dans une fenêtre est une chose ; obtenir un .csproj que vous pouvez ouvrir, grepper, refactoriser et compiler en est une autre. Voici comment l'export de projet de Glass.NET reconstruit un assembly entier — source, références, ressources —, ce qu'il gère proprement, où le code généré par le compilateur a besoin d'un coup de main, et comment le scripter depuis la CLI.
Un décompilateur qui ne vous montre que du code dans un panneau vous garde touriste. Vous pouvez regarder, vous pouvez défiler, mais vous ne pouvez pas travailler. Au moment où vous voulez grepper un assembly pour chaque appel à File.Delete, exécuter un analyseur statique dessus, poser un point d’arrêt dans une reproduction locale, ou refactoriser une bibliothèque perdue pour la remettre en forme, vous avez besoin de la chose sur disque sous forme de vrai projet — un .csproj que votre chaîne d’outils comprend. Ce saut, de « une fenêtre pleine de C# » à « une solution que je peux ouvrir », est ce à quoi sert l’export de projet de Glass.NET.
Cet article est une plongée pratique dans cet export : ce que Glass reconstruit, comment le piloter depuis l’interface comme depuis la CLI, ce qui compile proprement, où apparaissent les limites honnêtes de la décompilation, et comment combler l’écart.
D’un panneau en lecture seule à un projet sur disque
Ouvrez un assembly dans Glass et vous obtenez du C# décompilé, de la navigation, et une vue d’informations d’assembly — tout ce dont vous avez besoin pour le lire. L’export transforme cette reconstruction en fichiers :
Un projet, pas un dépotoir : le .csproj porte le framework cible et les références d’assembly que Glass a lues dans les métadonnées, les espaces de noms deviennent une disposition sensée de fichiers/dossiers, et les ressources embarquées sont extraites à côté. Ouvrez le dossier dans n’importe quel IDE et vos outils habituels — recherche, aller-à-la-définition, analyseurs, le compilateur — sont de nouveau sur la table.
Les deux façons d’exporter
Depuis l’interface, chargez l’assembly et choisissez File ▸ Export to Project. Glass écrit le .csproj et les fichiers .cs reconstruits (plus les ressources extraites) dans le dossier que vous choisissez. C’est la bonne voie quand vous explorez : vous avez navigué dans l’assembly, vous savez que c’est celui que vous voulez, et vous aimeriez l’avoir dans votre éditeur.
Depuis la CLI, la sous-commande glass export fait la même chose sans interface, ce que vous voulez dans un script, un lot sur de nombreux fichiers, ou un pipeline d’analyse :
glass export MyLibrary.dll --output ./MyLibrary.Source
Cela écrit un projet compilable sous ./MyLibrary.Source. Et comme c’est une simple commande, vous pouvez la déployer en éventail — récupérez un dossier d’assemblies orphelins en une passe :
for dll in ./legacy-bin/*.dll; do
name=$(basename "$dll" .dll)
glass export "$dll" --output "./recovered/$name"
done
Et comme Glass n’exécute jamais l’assembly — c’est strictement de l’analyse statique sur métadonnées et IL — exporter un binaire non fiable ou suspect est sûr. Vous obtenez la source sur disque pour grepper sans que le binaire ne s’exécute jamais, ce qui est précisément la situation où vous la voulez le plus : auditer quelque chose en quoi vous n’avez pas assez confiance pour l’exécuter.
Ce qui revient proprement
Pour une large classe d’assemblies réels, l’export compile avec peu ou pas de difficulté, parce que le moteur de décompilation moderne gère les constructions qui produisaient autrefois de la bouillie :
- La logique métier ordinaire — classes, interfaces, génériques, propriétés, événements, LINQ — se reconstruit fidèlement.
- Le C# moderne que le moteur comprend — machines à états
async/await, blocs itérateurs (yield), filtrage par motif et expressions switch, records, lambdas et closures — revient sous forme de construction de haut niveau, pas de la plomberie générée brute. Le moteur reconnaît l’abaissement du compilateur et le renverse. - Les références et le ciblage de framework sont portés dans le
.csproj, donc le projet sait contre quoi il compile. - Les ressources embarquées sont écrites et câblées, donc une bibliothèque qui distribue des chaînes adossées à
.resxou des blobs binaires les conserve.
Pour une petite bibliothèque utilitaire ou un unique assembly dont vous avez perdu la source, « exporter, ouvrir, compiler » fonctionne souvent tout simplement.
Où apparaissent les limites honnêtes de la décompilation
L’export est de la reconstruction, pas du voyage dans le temps, et il vaut la peine d’être franc sur ce que l’IL préserve et ne préserve pas. L’IL encode le comportement exactement ; il n’encode pas chaque détail au niveau source, donc certaines choses sont reconstruites plutôt que récupérées :
- Les noms de variables locales ont généralement disparu (l’IL identifie les locales par emplacement, pas par nom), donc vous verrez des noms reconstruits. Les champs, méthodes, types et paramètres gardent leurs noms sauf si l’assembly a été obfusqué.
- Certaines constructions générées par le compilateur se reconstruisent en C# valide-mais-ingrat, et le motif exotique occasionnel ne retournera pas à une source compilable sans un coup de pouce.
- Le code
unsafe, les signatures P/Invoke, et certaine interopérabilité peuvent nécessiter d’activer leAllowUnsafeBlocksdu projet ou un nettoyage manuel. - Les références manquantes — si l’assembly dépend de quelque chose que vous n’avez pas, l’export peut reconstruire les sites d’appel mais ne peut pas invoquer la dépendance ; vous la fournissez avant que la compilation ne passe au vert.
- L’entrée obfusquée est le cas le plus difficile : si les noms ont été charcutés par un obfuscateur, Glass reproduit fidèlement les noms charcutés — il décompile ce qui est là, il ne dés-obfusque pas.
Donc l’attente réaliste pour un assembly gros ou inhabituel est : Glass vous obtient un projet et la grande majorité de la source ; fermer la poignée finale d’erreurs de compilation est une courte passe manuelle ciblée. C’est quand même une transformation — de « je ne peux que regarder ça dans une visionneuse » à « j’ai un projet sur lequel toute ma chaîne d’outils peut travailler ».
Pourquoi un projet bat un panneau
Une fois l’assembly devenu un .csproj, tout ce que vous savez déjà faire revient :
- Grep et analyse statique. Cherchez dans la source reconstruite les API qui comptent — chaque
Process.Start, chaque appel de réflexion, chaque puits réseau — et pointez des analyseurs Roslyn ou vos propres règles dessus. C’est l’épine dorsale de l’audit d’une dépendance dont vous n’êtes pas sûr : exportez, puis lisez systématiquement les parties qui peuvent faire des dégâts. - Une reproduction locale. Récupéré une bibliothèque dont la source était perdue ? Le projet exporté vous laisse la compiler, la référencer, et — là où les références se résolvent — déboguer une reproduction au lieu de deviner depuis une trace de pile.
- Comparer entre versions. Exportez deux builds du même assembly et comparez les arbres pour voir exactement ce qui a changé entre les versions — pratique quand une montée de dépendance vous a cassé et que le changelog ne l’expliquait pas. (Glass offre aussi une comparaison d’assemblies in-app avec un diff ligne pour la version rapide.)
- Refactoriser vers un état maintenable. Pour du code véritablement perdu, un projet exporté est le point de départ pour renommer les locales reconstruites, re-ajouter les docs XML, et ramener à la vie une bibliothèque morte.
Où ça s’insère
L’export de projet est l’étape qui transforme Glass.NET d’une visionneuse en un établi. Lisez un assembly avec le modèle de navigation, confirmez que c’est le bon avec la vue d’informations d’assembly, puis File ▸ Export to Project — ou scriptez glass export MyLibrary.dll --output ./src — pour obtenir un .csproj que votre chaîne d’outils comprend. Attendez-vous à une compilation propre pour les assemblies directs et à une courte passe manuelle pour les gros ou inhabituels ; attendez-vous à la source sur disque dans tous les cas, sans jamais exécuter le binaire. Voyez les guides de prise en main et de navigation pour le flux de lecture qui mène à un export, ou la page produit Glass.NET pour l’ensemble complet des outils. C’est gratuit — pas de licence, pas de postes, pas d’inscription.
Essayez Nebula.NET
Renforcez votre code .NET en quelques minutes — commencez avec l'édition gratuite.