Pipeline de build
À quel endroit du pipeline MSBuild le package exécute Babel, comment déplacer cette étape, les cibles auxquelles vous pouvez vous raccorder, ce qui se passe à la publication et comment les outils de build sont sélectionnés.
Où s’exécute l’obfuscation
Par défaut, le package exécute Babel juste après CoreCompile, sur l’assembly que le compilateur vient d’écrire dans le dossier intermédiaire, $(IntermediateOutputPath)$(TargetFileName), c’est-à -dire le dossier obj. Toutes les étapes suivantes du build travaillent alors sur l’assembly obfusqué : la copie vers bin, la génération de .deps.json, les assemblies satellites et, à la publication, le découpage (trimming), le regroupement en fichier unique, la compilation ReadyToRun ou NativeAOT et l’empaquetage dans un APK ou un bundle d’application.
C’est cet ordre qui justifie l’utilisation du package dans les projets de style SDK. Le SDK .NET réécrit l’IL après la compilation, et Babel doit voir l’assembly avant lui ; un assembly pris dans bin ou dans le dossier de publication est déjà passé par ces étapes. Placer la tâche à la main après CoreCompile est fragile, car la séquence exacte des cibles dépend du type de projet et de la version du SDK. Le package règle cette question à votre place.
Deux autres règles préservent la réactivité de l’IDE :
- Les builds au moment de la conception sont ignorés. Visual Studio et les analyseurs de code lancent en permanence des builds en arrière-plan ; le package n’y injecte pas l’étape d’obfuscation.
- L’obfuscation ne s’exécute que si le compilateur s’est exécuté. Un build incrémentiel qui trouve l’assembly à jour ignore aussi Babel, si bien que l’assembly déjà obfusqué dans
objn’est jamais traité deux fois.
Déplacer l’étape d’obfuscation
Trois propriétés modifient le point d’injection :
| Propriété | Effet |
|---|---|
RunBabelAfterBuild | Avec la valeur true, Babel s’exécute à la fin du build, une fois la sortie copiée vers bin, et traite $(TargetPath) au lieu de l’assembly intermédiaire. |
BabelAfterTargets | Exécute l’étape d’obfuscation après la cible MSBuild indiquée. |
BabelBeforeTargets | Exécute l’étape d’obfuscation avant la cible MSBuild indiquée. |
Définir l’une d’elles désactive le placement par défaut après CoreCompile. Avec BabelAfterTargets ou BabelBeforeTargets, Babel traite toujours l’assembly intermédiaire ; si la cible choisie s’exécute après la copie de la sortie, faites pointer BabelInputFile et BabelOutputFile vers $(TargetPath).
Un cas d’utilisation courant est celui d’une application Windows Forms avec des ressources localisées, où Babel doit s’exécuter une fois les assemblies satellites générés afin de pouvoir les traiter eux aussi :
<PropertyGroup>
<BabelAfterTargets>CoreGenerateSatelliteAssemblies</BabelAfterTargets>
</PropertyGroup>Tout ce qui s’exécute entre la compilation et l’étape d’obfuscation déplacée voit l’assembly non obfusqué. Conservez le placement par défaut pour les projets publiés avec découpage, en fichier unique ou en AOT, et pour tout projet où une étape du SDK réécrit l’IL après la compilation.
Séquence des cibles et points d’extension
L’étape d’obfuscation est la cible ObfuscateBuild. Elle prépare d’abord la configuration de la tâche Babel, puis l’exécute :
ObfuscateBuild
├─ ObfuscateSettings
│ ├─ ObfuscateDefaultSettings renaming defaults, license lookup, babelRules.xml, search directories
│ ├─ ObfuscateFrameworkSettings selects the assembly to process (obj, or $(TargetPath))
│ ├─ ObfuscateSetupBabelFiles BabelInputFile / BabelOutputFile, GenerateDebug when a PDB exists
│ ├─ ObfuscateCustomSettings empty, yours to redefine
│ ├─ SetupObfuscate empty, yours to redefine
│ └─ ConfigureBabel empty, yours to redefine
└─ Obfuscate
├─ BeforeObfuscate empty, yours to redefine
├─ CoreObfuscate runs the Babel task
└─ AfterObfuscate empty, yours to redefineRedéfinissez une cible vide dans le fichier de projet pour exécuter vos propres étapes à cet endroit :
| Cible | S’exécute | Utilisez-la pour |
|---|---|---|
ObfuscateCustomSettings, SetupObfuscate, ConfigureBabel | Après que le package a calculé ses valeurs par défaut et les fichiers d’entrée et de sortie, avant l’exécution de Babel | Remplacer des propriétés calculées telles que BabelInputFile, BabelOutputFile, GenerateDebug ou les répertoires de recherche. |
BeforeObfuscate | Juste avant la tâche Babel | Obfusquer d’abord une dépendance, calculer des paramètres à partir des références résolues, générer des règles. |
AfterObfuscate | Juste après la tâche Babel | Copier ailleurs le fichier de mappage ou le fichier journal, exécuter un contrôle sur l’assembly obfusqué. |
CoreObfuscate publie deux sorties que vous pouvez lire dans AfterObfuscate : la propriété BabelExitCode, et l’élément @(BabelCommandLineArgs), qui contient la ligne de commande lorsque BabelProvideCommandLineArgs vaut true.
Remplacer la configuration de la tâche
Le package configure la tâche Babel à partir du projet : les répertoires de recherche d’après les références, la clé de nom fort, le PDB, le fichier de règles. Lorsque les valeurs par défaut ne conviennent pas, ajustez-les dans BeforeObfuscate. L’exemple ci-dessous force la génération des symboles de débogage et remplace les répertoires de recherche par le dossier de sortie :
<Target Name="BeforeObfuscate">
<!-- Override computed properties -->
<PropertyGroup>
<GenerateDebug>true</GenerateDebug>
</PropertyGroup>
<!-- Replace the Babel search directories -->
<ItemGroup>
<BabelSearchDirectories Remove="@(BabelSearchDirectories)" />
<BabelSearchDirectories Include="$(TargetDir)" />
</ItemGroup>
</Target>BeforeObfuscate est aussi l’endroit où exécuter une seconde tâche Babel sur une dépendance avant l’obfuscation de l’assembly principal, comme le fait l’exemple Publier une application .NET pour renommer l’interface publique d’un package NuGet avec le renommage entre assemblies.
Une cible AfterObfuscate peut rassembler les artefacts produits par Babel, par exemple le fichier de mappage destiné à un dossier partagé qu’utilise l’exemple Tests unitaires :
<PropertyGroup>
<GenerateMapOutFile>true</GenerateMapOutFile>
<BabelMapOutFile>$(IntermediateOutputPath)$(TargetFileName).map.xml</BabelMapOutFile>
</PropertyGroup>
<Target Name="AfterObfuscate">
<Copy SourceFiles="$(BabelMapOutFile)" DestinationFolder="$(SolutionDir)MapOut" />
</Target>Publication
Comme l’obfuscation a lieu avant les étapes de publication, dotnet publish et les profils de publication de Visual Studio produisent une sortie obfusquée sans configuration supplémentaire. Le package y ajoute trois ajustements :
- Les assemblies fusionnés et incorporés sont retirés de l’ensemble des fichiers à publier. La cible
UpdateBabelFilesToPublish, qui s’exécute aprèsComputeFilesToPublish, retire des fichiers à publier chaque élémentMergeAssemblyetEmbedAssembly, avec ses fichiers.pdbet.xml. RéglezBabelPublishEnabledsurfalsepour les conserver. - Les fichiers
.deps.jsonsont mis à jour. Les ciblesUpdateBabelBuildDependencyFileetUpdateBabelPublishDependencyFileretirent les assemblies fusionnés et incorporés, ainsi que le package lui-même, des manifestes de dépendances du build et de la publication, afin que l’hôte ne recherche pas des assemblies qui n’existent plus sous forme de fichiers distincts. RéglezBabelUpdateDependencyFilesurfalsepour laisser les manifestes inchangés. - Les symboles de débogage ne sont pas publiés en Release. Le package règle
CopyOutputSymbolsToPublishDirectorysurfalsepour la configuration Release, sauf si le projet définit cette propriété, car les fichiers PDB livrent à un attaquant les noms de fichiers et les numéros de ligne du code d’origine. Réglez-la surtruepour les publier malgré tout.
La publication en fichier unique, avec découpage et en AOT fonctionne avec l’assembly obfusqué, à deux réserves près : sur les cibles de bureau, le contrôle de falsification ne peut pas vérifier une image en fichier unique, ce dont Babel avertit (voir Détection de falsification), et, pour .NET MAUI iOS, l’éditeur de liens doit être réglé sur Link SDK assemblies only, comme expliqué dans Obfusquer .NET MAUI.
Sélectionner les outils de build
Le package contient un jeu d’outils de build Babel par hôte MSBuild et le sélectionne d’après l’hôte qui exécute le build :
| HĂ´te MSBuild | Dossier des outils |
|---|---|
SDK .NET 6.0, 7.0, 8.0, 9.0 ou 10.0 (dotnet build, Visual Studio) | tools\net6.0 … tools\net10.0, selon la version du SDK |
| Toute autre version du SDK .NET | tools\net9.0 |
MSBuild pour .NET Framework (MSBuild.exe) | tools\net472 |
| MSBuild pour Mono | tools\Mono |
Le dossier sélectionné est exposé dans BabelTaskDir, et BabelPackageDir pointe vers la racine du package extrait. Pour imposer un autre jeu d’outils, définissez BabelTaskDir dans le fichier de projet :
<PropertyGroup>
<BabelTaskDir>$(BabelPackageDir)tools\net8.0\</BabelTaskDir>
</PropertyGroup>Définissez cette propriété dans le fichier de projet ou dans Directory.Build.targets, et non dans Directory.Build.props : le fichier .props du package est importé après Directory.Build.props et écraserait la valeur.
Pour exécuter un Babel installé en dehors du package, par exemple l’outil en ligne de commande extrait d’une archive zip babel_net*, réglez BabelPath sur son dossier et, si nécessaire, BabelExe sur le nom de l’exécutable (babel.exe ou babel.dll).
Serveurs de build
Rien dans le package n’est propre à une machine : un projet qui se génère obfusqué sur le PC d’un développeur se génère donc obfusqué sur tout agent capable de restaurer le package et d’accéder à une licence. Les exemples couvrent les services courants :
- GitHub Actions : package sur GitHub Packages, clé de licence issue d’un secret du dépôt.
- Azure DevOps : package sur un flux Azure Artifacts, clé de licence issue d’une variable secrète du pipeline.
- AppVeyor : package sur le flux du compte, clé de licence issue d’une variable chiffrée.
- Tests unitaires : test des assemblies obfusqués dans le même pipeline.
Les agents et les conteneurs Linux exécutent le build tools\netX.0 de Babel. Les hôtes dont la configuration FIPS d’OpenSSL est défaillante nécessitent les paramètres décrits dans Conformité FIPS.