Configurer l’obfuscation
Une fois le package installé, toutes les fonctionnalités de Babel Obfuscator se configurent avec des propriétés et des éléments MSBuild dans le fichier de projet. Cette page présente, fonctionnalité par fonctionnalité, les paramètres que vous utiliserez le plus.
Comment les paramètres parviennent à Babel
Le package définit une propriété ou un élément MSBuild pour chaque attribut de la tâche Babel et les transmet à la tâche lorsque la cible CoreObfuscate s’exécute. La plupart des propriétés portent le même nom que l’attribut de la tâche et acceptent les mêmes valeurs que l’option de ligne de commande correspondante. Celles qui diffèrent, comme BabelLicense, MergeInternalize ou BabelRules, figurent dans le tableau Correspondance des propriétés.
Les paramètres se placent dans un PropertyGroup, généralement conditionné à la configuration de build afin que les builds Debug restent lisibles :
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
<StringEncryption>stream</StringEncryption>
<ControlFlowObfuscation>if=on;switch=on;call=on</ControlFlowObfuscation>
<ControlFlowIterations>3</ControlFlowIterations>
<ValueEncryption>true</ValueEncryption>
<ResourceEncryption>true</ResourceEncryption>
<DebuggingProtection>true</DebuggingProtection>
<VerboseLevel>2</VerboseLevel>
</PropertyGroup>Les listes de fichiers s’expriment sous forme d’éléments dans un ItemGroup : BabelRules, MergeAssembly, EmbedAssembly, MapInFile et BabelPlugin.
Les propriétés sont évaluées avant l’exécution de toute cible : une valeur définie dans le corps du projet s’applique donc à tout le build. Pour calculer un paramètre à partir d’une information connue seulement pendant le build, comme le chemin résolu d’une référence de package, définissez-le plutôt dans la cible BeforeObfuscate. Voir Remplacer la configuration de la tâche.
Valeurs par défaut appliquées par le package
Sans aucun paramètre, un projet qui référence le package est obfusqué comme suit :
- Le renommage des symboles est activé pour les types, les méthodes, les propriétés, les champs, les événements et les paramètres, membres virtuels compris, et les espaces de noms sont aplatis. La propriété
SymbolsRenamingactive ou désactive le tout en une fois ; les propriétés individuellesObfuscateTypes,ObfuscateMethods,ObfuscateProperties,ObfuscateFields,ObfuscateEvents,ObfuscateParameters,VirtualFunctionsetFlattenNamespacesla remplacent une à une. - Toutes les autres fonctionnalités sont désactivées tant que vous ne les activez pas.
- Les symboles de débogage sont régénérés lorsque le compilateur a produit un PDB à côté de l’assembly (
GenerateDebugest défini automatiquement) : les builds obfusqués restent ainsi débogables et les traces de pile peuvent être décodées. - Les répertoires de recherche des assemblies sont établis à partir des références du projet, de sorte que Babel résout toutes les dépendances vues par le compilateur.
- Le fichier de configuration de Babel est ignoré (
NoConfigurationvauttrue) : le build ne dépend donc que de ce que le projet déclare. - Un fichier
babelRules.xmlprésent dans le dossier du projet est pris en compte automatiquement. - La clé de nom fort résolue par MSBuild pour le projet (
KeyOriginatorFile, ouKeyContainerName) est transmise à Babel, de sorte que l’assembly obfusqué est signé comme l’original.
Pour désactiver le renommage, pour un projet de test ou pour une passe limitée au chiffrement des chaînes :
<PropertyGroup>
<SymbolsRenaming>false</SymbolsRenaming>
</PropertyGroup>Règles d’obfuscation
Les règles excluent des symboles d’une fonctionnalité ou appliquent une fonctionnalité à un ensemble de symboles. Il existe trois façons de les fournir :
- Ajoutez un fichier
babelRules.xmlau dossier du projet : il est utilisé automatiquement. - Référencez autant de fichiers de règles que nécessaire avec des éléments
BabelRules:
<ItemGroup>
<BabelRules Include="rules\renaming.xml" />
<BabelRules Include="rules\encryption.xml" />
</ItemGroup>- Écrivez des règles intégrées dans la propriété
XmlRules, ce qui est pratique pour un petit ensemble de règles propre au projet :
<PropertyGroup>
<XmlRules>
<Rules>
<Rule name="rename public types" feature="renaming" exclude="false">
<Access>Public</Access>
<Pattern>*</Pattern>
</Rule>
</Rules>
</XmlRules>
</PropertyGroup>L’exemple Application Android utilise une règle intégrée pour renommer les types publics, et l’exemple Application web Blazor utilise un fichier de règles pour obfusquer les classes sur lesquelles reposent les pages Razor. Les règles peuvent aussi être rattachées au code avec des attributs personnalisés.
Chiffrement des chaînes
StringEncryption active le chiffrement des chaînes et sélectionne l’algorithme, exactement comme l’option --stringencryption : true utilise l’algorithme par défaut, tandis que xor, hash, stream ou custom en sélectionne un. Voir Algorithmes standard pour une comparaison.
<PropertyGroup>
<StringEncryption>stream</StringEncryption>
</PropertyGroup>STREAM Ultimate est l’algorithme à privilégier pour les cibles modernes : il est entièrement managé, donc compatible avec le découpage (trimming), avec NativeAOT et avec les hôtes soumis à FIPS, et il est vérifié de .NET Framework à .NET 10, y compris Android, iOS et .NET MAUI. Dans les projets Android, iOS et MAUI, le package exécute déjà Babel après la compilation et avant l’empaquetage, moment où le chiffrement des chaînes doit avoir lieu pour que l’application empaquetée contienne les chaînes chiffrées. Les chaînes déclarées const ne peuvent pas être chiffrées ; voir Chiffrement des chaînes const.
Obfuscation du flux de contrôle
ControlFlowObfuscation prend la même liste de paires clé-valeur que --controlflow, et ControlFlowIterations le nombre de passes (ILIterations est accepté comme alias) :
<PropertyGroup>
<ControlFlowObfuscation>goto=on;if=on;switch=on;case=on;call=on</ControlFlowObfuscation>
<ControlFlowIterations>3</ControlFlowIterations>
</PropertyGroup>La version 12 ajoute l’algorithme d’état chaîné Ultimate, une transformation d’aplatissement renforcée contre les désobfuscateurs automatisés. Activez-le avec chain=on, seul ou avec les autres algorithmes :
<PropertyGroup>
<ControlFlowObfuscation>switch=on;case=on;chain=on</ControlFlowObfuscation>
</PropertyGroup>L’aplatissement a un coût à l’exécution. Utilisez des règles pour en dispenser les méthodes critiques pour les performances, comme expliqué dans Performances et réglages.
Chiffrement du code
MsilEncryption chiffre les corps de méthode. true chiffre toutes les méthodes éligibles, tandis qu’une expression régulière restreint le chiffrement aux méthodes dont le nom complet lui correspond :
<PropertyGroup>
<MsilEncryption>MyApp\.Licensing\..*</MsilEncryption>
</PropertyGroup>Voir Chiffrement du code pour le comportement à l’exécution, le code protégé par mot de passe et les méthodes qui ne peuvent pas être chiffrées.
Protection des valeurs, des ressources et des appels
<PropertyGroup>
<ValueEncryption>array=true;true</ValueEncryption>
<ResourceEncryption>true</ResourceEncryption>
<DynamicProxy>all</DynamicProxy>
<SuppressIldasm>true</SuppressIldasm>
<SuppressReflection>true</SuppressReflection>
</PropertyGroup>Chaque propriété accepte les valeurs de l’option correspondante : voir Chiffrement des valeurs et des tableaux, Chiffrement des ressources et Proxy dynamique.
Détection de falsification et protection contre le débogage
<PropertyGroup>
<TamperingDetection>true</TamperingDetection>
<DebuggingProtection>true</DebuggingProtection>
</PropertyGroup>Sur les cibles de bureau, le contrôle de falsification calcule le hachage de l’image chargée en mémoire : il est donc inopérant dans les applications publiées en fichier unique, avec découpage ou en AOT. Le package transmet à Babel le paramètre PublishSingleFile du projet, et Babel émet un avertissement lorsque la détection de falsification est demandée pour une telle publication. Voir Détection de falsification et Protection contre le débogage.
Intégrité du paquet Android et iOS Ultimate
À partir de la version 12, sur les cibles .NET pour Android et iOS (.NET MAUI compris), la détection de falsification vérifie l’intégrité du paquet au lieu de celle de l’image : le certificat de signature de l’APK sous Android, l’identifiant de bundle et l’identifiant d’équipe Apple (Team ID) sous iOS. Épinglez les valeurs attendues avec les propriétés ajoutées dans cette version :
<!-- Android: SHA-256 fingerprint of the release signing certificate -->
<PropertyGroup Condition="$(TargetFramework.Contains('-android'))">
<TamperingDetection>true</TamperingDetection>
<TrustedSigner>2924C53EE9C511E9F26E0720FD8151064F7621681667D7AB1899E551CDB25104</TrustedSigner>
</PropertyGroup>
<!-- iOS: bundle identifier and Apple Team ID -->
<PropertyGroup Condition="$(TargetFramework.Contains('-ios'))">
<TamperingDetection>true</TamperingDetection>
<TrustedBundle>com.mycompany.myapp</TrustedBundle>
<TrustedTeam>ABCDE12345</TrustedTeam>
</PropertyGroup>TrustedSigner accepte plusieurs empreintes séparées par des points-virgules, par exemple celle d’une clé d’importation et celle de la clé de signature d’application de Google Play. La manière d’obtenir chaque valeur et ce qui se passe lorsqu’un épinglage manque sont expliqués dans Intégrité du paquet Android (MAUI) et Intégrité du paquet iOS (MAUI). L’exemple Application Android montre un fichier de projet Android complet.
AES managé pour les hôtes FIPS
Les déchiffreurs injectés à l’exécution pour le chiffrement du code, des chaînes (XOR et HASH), des valeurs et des ressources utilisent le fournisseur cryptographique de la plateforme, et un hôte dont la configuration FIPS d’OpenSSL est défaillante ne peut pas démarrer un tel assembly. Depuis la version 11.8, encryption=aesmanaged sélectionne à la place un déchiffreur managé autonome :
<PropertyGroup>
<MsilEncryption>true</MsilEncryption>
<Use>encryption=aesmanaged</Use>
</PropertyGroup>Use accepte toutes les paires clé-valeur admises par l’option --use, séparées par des points-virgules, par exemple tagassembly=on. Voir Conformité FIPS pour les compromis du déchiffreur managé.
Fusionner et incorporer des assemblies
Les éléments MergeAssembly et EmbedAssembly énumèrent les assemblies à fusionner ou à incorporer dans l’assembly cible. MergeInternalize rend internes les types publics fusionnés, et MergeCopyAttributes détermine si leurs attributs de niveau assembly sont copiés :
<ItemGroup>
<MergeAssembly Include="$(TargetDir)Acme.View.dll" />
<MergeAssembly Include="$(TargetDir)Acme.ViewModel.dll" />
<EmbedAssembly Include="$(TargetDir)Framework.Mvvm.dll" />
</ItemGroup>
<PropertyGroup>
<MergeInternalize>true</MergeInternalize>
</PropertyGroup>Babel s’exécute juste après la compilation, avant que le build ne copie les dépendances dans le dossier de sortie : lors d’un build à partir de zéro, un chemin sous $(TargetDir) peut donc ne pas encore exister. La source fiable est la liste des références résolues pour le compilateur, que vous pouvez filtrer dans la cible BeforeObfuscate :
<Target Name="BeforeObfuscate">
<ItemGroup>
<MergeAssembly Include="@(ReferencePathWithRefAssemblies)"
Condition="'%(Filename)' == 'Acme.View' Or '%(Filename)' == 'Acme.ViewModel'" />
</ItemGroup>
</Target>Le package retire aussi les assemblies fusionnés et incorporés du fichier .deps.json et de l’ensemble des fichiers à publier, de sorte que dotnet publish ne les livre pas deux fois. Voir Fusion et incorporation pour la fonctionnalité et Publication pour les détails côté build.
Fichiers de mappage et renommage entre assemblies
GenerateMapOutFile écrit le fichier de mappage XML de l’assembly obfusqué, qui sert à décoder les traces de pile et à renommer de façon cohérente l’interface publique d’une bibliothèque d’un assembly à l’autre. Les éléments MapInFile fournissent à Babel les fichiers de mappage d’assemblies déjà obfusqués :
<PropertyGroup>
<GenerateMapOutFile>true</GenerateMapOutFile>
<BabelMapOutFile>$(SolutionDir)MapOut\$(TargetFileName).map.xml</BabelMapOutFile>
</PropertyGroup>
<ItemGroup>
<MapInFile Include="$(SolutionDir)MapOut\Acme.Core.dll.map.xml" />
</ItemGroup>Voir Fichiers de mappage XML et Renommage entre assemblies. L’exemple Tests unitaires utilise un fichier de mappage pour exécuter des tests sur une bibliothèque obfusquée, et l’exemple Publier une application .NET obfusque l’interface publique d’une dépendance NuGet et fournit son fichier de mappage à l’application.
Optimisations
<PropertyGroup>
<DeadCodeElimination>true</DeadCodeElimination>
<SealClasses>true</SealClasses>
<EnumRemoval>true</EnumRemoval>
<ConstRemoval>true</ConstRemoval>
<DisgregateRemoval>true</DisgregateRemoval>
<InlineExpansion>true</InlineExpansion>
<CleanAttributes>true</CleanAttributes>
</PropertyGroup>Chaque optimisation est décrite dans Optimisations.
Plugins
Les éléments BabelPlugin référencent les assemblies de plugins à charger, et PluginsArguments leur transmet des arguments sous forme de paires clé-valeur. Le plugin BabelEncrypt est fourni dans le package, dans le même dossier que les outils de build :
<ItemGroup>
<BabelPlugin Include="$(BabelTaskDir)BabelEncrypt.dll" />
</ItemGroup>
<PropertyGroup>
<PluginsArguments>dictionary=exclusionlist.txt</PluginsArguments>
</PropertyGroup>Voir Plugins Babel Obfuscator et l’Encrypt Plugin.
Journalisation et diagnostics
<PropertyGroup>
<VerboseLevel>3</VerboseLevel>
<GenerateLogFile>true</GenerateLogFile>
<BabelLogFile>$(IntermediateOutputPath)babel.log</BabelLogFile>
<BabelProvideCommandLineArgs>true</BabelProvideCommandLineArgs>
<ShowStatistics>true</ShowStatistics>
<Trace>MyApp\.Services\..*</Trace>
<BabelWarningsToIgnore>W00008</BabelWarningsToIgnore>
<BabelWarningsAsErrors>W00000</BabelWarningsAsErrors>
</PropertyGroup>VerboseLeveldétermine quelle part du journal de Babel atteint la sortie du build ;GenerateLogFileetBabelLogFileenregistrent le journal complet dans un fichier.BabelProvideCommandLineArgsaffiche la ligne de commande que le package passe à Babel et l’enregistre dans l’élément@(BabelCommandLineArgs).Traceprend une expression régulière et explique, symbole par symbole, pourquoi une correspondance a été obfusquée ou non : c’est le moyen le plus rapide de déboguer des règles.BabelWarningsToIgnore,BabelWarningsAsErrorsetBabelWarningsAsInfosprennent des listes de codes d’avertissement et modifient la façon dont ils sont signalés.MakeBabelProjectFileécrit un projet MSBuild équivalent à la configuration actuelle, ce qui est utile pour reproduire un build avec la tâche Babel ou l’outil en ligne de commande.
Toutes les propriétés acceptées par le package figurent dans la Référence du package.