Skip to Content
Nouvelle version 12 disponible 🎉
ObfuscatorRenommage des symbolesRenommage entre assemblies

Renommage entre assemblies

Pendant l’obfuscation, Babel Obfuscator renomme tous les symboles qui ne sont pas visibles de l’extérieur de l’assembly, c’est-à-dire les symboles privés et internes. Babel modifie donc les noms des champs, des méthodes, des classes et des autres éléments de code qui ne sont pas destinés à être utilisés en dehors de l’assembly.

Babel ne renomme pas les symboles visibles de l’extérieur de l’assembly, comme les symboles publics. En effet, ces symboles sont destinés à être utilisés par d’autres assemblies, et les renommer empêcherait l’application de fonctionner. Babel ne renomme donc que les symboles qui ne sont pas destinés à être utilisés par d’autres assemblies, de sorte que l’application continue de fonctionner comme prévu.

Babel permet toutefois d’obfusquer les membres publics et internes dans plusieurs assemblies à la fois. Pour cela, il corrige les noms des symboles obfusqués référencés dans chaque assembly à l’aide de fichiers de mappage XML.

En effet, lorsqu’un assembly est obfusqué, les noms de ses symboles changent. Toute référence à ces symboles faite par un autre assembly doit donc être mise à jour avec les nouveaux noms. Lorsque vous indiquez ces fichiers de mappage XML d’entrée et de sortie, Babel Obfuscator s’en sert pour corriger les références de noms croisées entre tous les assemblies concernés. Le code obfusqué fonctionne ainsi correctement, sans erreur due à des noms de symboles incorrects.

Il est important de garder les fichiers de mappage privés et de ne jamais les déployer avec l’application obfusquée : ils peuvent servir à annuler l’obfuscation par rétro-ingénierie et à compromettre la sécurité de l’application.

Configurer le renommage entre assemblies

Pour configurer le renommage entre assemblies, il faut prendre en compte tous les assemblies qui participent au renommage. Considérez l’assembly principal de l’application, MainAssembly.dll, qui utilise l’interface publique de deux composants externes : Library1.dll et Library2.dll. Library1.dll doit lui aussi accéder à l’interface publique de Library2.dll, selon le schéma suivant :

  • MainAssembly.dll
    1. Library1.dll
    2. Library2.dll
  • Library1.dll
    1. Library2.dll

Cette configuration montre les relations entre les assemblies qui participent à l’obfuscation. La première étape consiste à configurer Babel pour qu’il obfusque les symboles publics de Library1.dll et de Library2.dll. Pour cela, ajoutez l’attribut personnalisé de niveau assembly suivant au code source des deux bibliothèques :

[assembly: System.Reflection.ObfuscateAssembly(true)]

Cet attribut demande à Babel d’obfusquer les symboles publics de l’assembly concerné, sans fichier de règles XML externe. Lorsque le paramètre booléen vaut true, l’interface publique de l’assembly est traitée comme privée, ce qui permet d’obfusquer sans risque les noms des membres publics.

Vous pouvez aussi configurer Babel pour qu’il renomme l’interface publique d’un assembly à l’aide d’un fichier de règles XML. Cette méthode offre plus de souplesse et de maîtrise, car elle permet d’obfusquer de manière sélective certaines parties de l’interface publique. Voici un exemple de fichier de règles XML, nommé public.xml, qui impose l’obfuscation de tous les noms de membres publics :

<Rules> <Rule name="obfuscate public" exclude="false"> <Access>Public</Access> <Pattern isRegEx="false">*</Pattern> <Description>Obfuscate all public symbols.</Description> </Rule> </Rules>

Par rapport à l’attribut ObfuscateAssembly, les règles XML permettent de choisir plus finement les symboles publics à obfusquer. L’expression de l’élément Pattern vous permet d’indiquer quelles parties de l’interface publique doivent être obfusquées, et donc d’adapter la stratégie d’obfuscation.

À ce stade, Library1.dll et Library2.dll sont configurés pour utiliser soit l’attribut ObfuscateAssembly, soit le fichier de règles XML (ici, public.xml) :

  • MainAssembly.dll
  • Library1.dll (configurĂ© avec public.xml)
  • Library2.dll (configurĂ© avec public.xml)

Pour chaque assembly configuré pour renommer son interface publique, il faut activer la génération d’un fichier de mappage XML.

Ce fichier contient la correspondance entre les noms d’origine des symboles et leurs noms obfusqués. Le fichier de mappage XML est utilisé par tous les assemblies participant à l’obfuscation qui référencent au moins un assembly dont l’interface publique a été renommée. La résolution des noms est ainsi correcte entre les assemblies obfusqués.

Pour obfusquer Library1.dll et Library2.dll, utilisez la syntaxe CLI suivante :

babel Library2.dll --rules public.xml --mapout

Cette première commande obfusque Library2.dll et génère un fichier de mappage XML nommé Library2.map.xml, qui contient la correspondance entre les noms d’origine des symboles et les noms obfusqués.

Comme Library1.dll référence Library2.dll et utilise son interface publique, il faut, pour obfusquer Library1.dll, fournir en entrée le fichier Library2.map.xml, afin que les symboles obfusqués de Library2.dll soient correctement mis en correspondance. De plus, comme l’interface publique de Library1.dll doit elle aussi être obfusquée, Babel est configuré pour charger le fichier de règles public.xml et générer le fichier de mappage XML correspondant pour Library1.dll.

La commande CLI de cette étape est la suivante :

babel Library1.dll --rules public.xml --mapout --mapin Library2.map.xml

Ainsi, Library1.dll référence correctement les symboles obfusqués de Library2.dll et génère son propre fichier de mappage, qui servira dans la suite de l’obfuscation.

Enfin, pour obfusquer MainAssembly.dll, il faut configurer Babel pour qu’il charge les fichiers de mappage XML de Library1.dll et de Library2.dll, puisque ces assemblies sont référencés par MainAssembly. MainAssembly peut ainsi résoudre correctement, pendant l’obfuscation, les symboles obfusqués des bibliothèques dont il dépend.

La commande CLI de cette étape est :

babel MainAssembly.dll --mapin Library1.map.xml --mapin Library2.map.xml

Cette commande reçoit en entrée les fichiers de mappage générés précédemment (Library1.map.xml et Library2.map.xml), afin que les références aux symboles obfusqués de ces bibliothèques soient correctement traitées dans MainAssembly.

Il est essentiel d’obfusquer les assemblies dans le bon ordre. Les bibliothèques référencées par d’autres assemblies, comme Library2.dll et Library1.dll, doivent être obfusquées en premier pour générer les fichiers de mappage nécessaires. Les assemblies qui en dépendent, comme Library1.dll et MainAssembly.dll, peuvent ensuite être obfusqués à l’aide de ces fichiers de mappage.

Configurer depuis la tâche MSBuild

Pour configurer le renommage entre assemblies avec MSBuild, il faut indiquer, pour chaque assembly du projet d’obfuscation, les fichiers de mappage XML d’entrée et de sortie ainsi que le fichier de règles XML. Chaque assembly obfusqué doit générer un fichier de mappage XML, qui est ensuite fourni en entrée à tous les autres assemblies obfusqués qui référencent cet assembly cible.

Voici un exemple de configuration du renommage entre assemblies pour un assembly principal et deux assemblies référencés, organisés selon le schéma suivant.

  • MainAssembly.dll
    1. Library1.dll
    2. Library2.dll
  • Library1.dll
    1. Library2.dll

Commencez par le projet Library2, qui n’a aucune dépendance. Comme il ne repose sur aucun autre assembly, il peut être obfusqué séparément, sans fichier de mappage XML d’entrée.

Projet de l’assembly Library2

<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <GenerateMapOutFile>true</GenerateMapOutFile> </PropertyGroup> <Target Name="Obfuscate" AfterTargets="CoreCompile"> <ItemGroup> <RulesFile Include="path\to\referenced\public.xml" /> </ItemGroup> <Babel Input="$(TargetPath)" RulesFiles="@(RulesFile)" GenerateMapOutFile="$(GenerateMapOutFile)" /> </Target> </Project>

Notez que, comme Library1 référence Library2, le projet d’obfuscation doit non seulement générer le fichier de mappage XML avec GenerateMapOutFile=true, mais aussi référencer le fichier de mappage généré pour Library2.

Projet de l’assembly Library1

<Project Sdk="Microsoft.NET.Sdk"> <ItemGroup> <Reference Include="path\to\referenced\Library2.dll" /> </ItemGroup> <PropertyGroup> <GenerateMapOutFile>true</GenerateMapOutFile> </PropertyGroup> <Target Name="Obfuscate" AfterTargets="CoreCompile"> <ItemGroup> <MapInFile Include="path\to\referenced\Library2.dll.map.xml" /> </ItemGroup> <ItemGroup> <RulesFile Include="path\to\referenced\public.xml" /> </ItemGroup> <Babel Input="$(TargetPath)" MapInFiles="@(MapInFile)" RulesFiles="@(RulesFile)" GenerateMapOutFile="$(GenerateMapOutFile)" /> </Target> </Project>

Comme le projet MainAssembly référence les deux bibliothèques, Library1 et Library2, dont l’interface publique a été obfusquée, la tâche Babel doit être configurée pour charger les deux fichiers de mappage XML générés pour ces bibliothèques.

Projet de l’assembly principal

<Project Sdk="Microsoft.NET.Sdk"> <ItemGroup> <Reference Include="path\to\referenced\Library1.dll" /> <Reference Include="path\to\referenced\Library2.dll" /> </ItemGroup> <Target Name="Obfuscate" AfterTargets="CoreCompile"> <ItemGroup> <MapInFile Include="path\to\referenced\Library1.dll.map.xml" /> <MapInFile Include="path\to\referenced\Library2.dll.map.xml" /> </ItemGroup> <Babel Input="$(TargetPath)" MapInFiles="@(MapInFile)" /> </Target> </Project>

Les références croisées entre Library1 et Library2 sont ainsi correctement traitées pendant l’obfuscation. Si le fichier de mappage XML généré pour Library2 n’est pas référencé, l’obfuscation de Library1 risque de mal traiter les références croisées entre les deux bibliothèques, ce qui peut provoquer des problèmes à l’exécution. Lorsque vous configurez le renommage entre assemblies, veillez donc à ce que tous les fichiers de mappage XML nécessaires soient générés et correctement référencés.

Configurer depuis Babel Desktop

Un projet Babel Desktop peut contenir tous les assemblies concernés. Sur le canevas du projet, reliez chaque bibliothèque à l’assembly qui l’utilise et choisissez Transmettre le fichier de map : la bibliothèque écrit alors son fichier de mappage, l’assembly qui l’utilise le lit, et la bibliothèque est obfusquée en premier. Dans l’exemple ci-dessus, reliez Library2 à Library1 et à MainAssembly, et Library1 à MainAssembly. Une connexion de type Ordre d’exécution uniquement fixe l’ordre, mais ne transmet aucun fichier de mappage.

Vous devez toujours ajouter les règles de renommage public à chaque bibliothèque, avec des règles XML ou RulesFiles. Le groupe Fichiers map des propriétés de la cible affiche les fichiers de mappage que chaque cible écrit et lit, et permet d’ajouter des fichiers de mappage issus de builds précédents. Voir Ordre d’exécution et fichiers de mappage.

Last updated on