Proxy dynamique
La protection par proxy dynamique est une fonctionnalité de Babel Obfuscator qui renforce l’obfuscation et la protection du code de votre application. Elle permet de masquer les appels de méthodes vers du code externe comme vers du code interne en générant des classes proxy dynamiques.
Lorsque la protection par proxy dynamique est activée, Babel Obfuscator crée des types délégués ou des classes proxy qui servent d’intermédiaires pour les appels de méthodes. Ces classes proxy sont construites dynamiquement pendant le processus d’obfuscation et remplacent les appels de méthodes d’origine dans votre code.
Le principal avantage des proxys dynamiques est qu’ils masquent efficacement les appels de méthodes réels : il devient beaucoup plus difficile, pour des attaquants ou des spécialistes de la rétro-ingénierie, de comprendre et d’analyser le flux du code. Les proxys dynamiques permettent d’empêcher l’accès direct aux méthodes sensibles et de masquer la logique de l’application.
Cette section couvre :
- Fonctionnement du proxy dynamique et limites liées aux plateformes
- Appels internes et externes : les modes de proxy et ce qu’ils protègent
- Couverture : les appels qui passent par un proxy et ceux qui restent directs
- Filtres : ne faire passer par un proxy que les appels de votre choix
- Configuration : CLI, MSBuild et Babel Desktop
- Performances et Résistance à la désobfuscation
Fonctionnement du proxy dynamique
À la génération, pour chaque appel protégé, Babel Obfuscator génère un petit type délégué proxy et réécrit l’instruction call, callvirt ou newobj d’origine pour la faire passer par ce proxy. La cible réelle (son type déclarant, la méthode et le champ qui contiendra l’appel résolu) n’est plus référencée directement par le code réécrit. Elle est retrouvée par un minuscule résolveur injecté la première fois que chaque appel par proxy s’exécute, puis mise en cache afin que les appels suivants passent directement.
Deux propriétés découlent de cette conception :
- L’analyse statique est perturbée. Les sites d’appel réécrits ne portent plus de référence de métadonnées directe vers la cible ; les décompilateurs et les désobfuscateurs automatisés ne peuvent donc pas reconstruire le graphe d’appels d’origine à partir des seules métadonnées. La manière dont les cibles sont codées varie aussi d’un build à l’autre, si bien que les outils ne peuvent pas s’appuyer sur des motifs fixes : voir Résistance à la désobfuscation.
- La résolution est différée et mise en cache. Le premier appel à un membre donné passant par proxy paie un petit coût unique pour résoudre la cible et raccorder le délégué ; chaque appel ultérieur passe par le délégué mis en cache avec un surcoût négligeable : voir Performances.
Le passage par proxy est une transformation purement managée, effectuée à la génération : elle ne nécessite pas le .NET Framework, fonctionne sur .NET et .NET Framework et ne modifie pas le comportement observable de votre programme (à l’exception du petit ensemble d’appels répertoriés dans Couverture, qui restent volontairement directs).
Limites de compatibilité AOT et plateforme
Le proxy dynamique n’est actuellement pas pris en charge sur les assemblies .NET MAUI et Blazor, en raison d’une combinaison de limites des plateformes et de restrictions du runtime qui empêchent de générer et d’exécuter les proxys de manière sûre ou cohérente dans ces environnements.
Contraintes des plateformes
- Compilation anticipée (AOT) : des plateformes telles qu’iOS (utilisée par .NET MAUI) et WebAssembly (utilisée par Blazor WebAssembly) imposent la compilation AOT. Celle-ci exclut les fonctionnalités d’exécution comme l’émission de code par réflexion ou la génération de types à l’exécution. Bien que le proxy dynamique de Babel n’utilise pas la génération de code à l’exécution, la logique de proxy qu’il génère peut dépendre de métadonnées et de constructions IL qui sont supprimées ou non prises en charge dans les environnements compilés en AOT.
Limites de compatibilité IL
- Jetons de métadonnées non pris en charge : le mécanisme de proxy dynamique injecte des couches d’appel intermédiaires au moyen de types proxy générés et de stubs de délégués. Ceux-ci reposent sur des jetons de métadonnées et des mécanismes d’indirection qui peuvent ne pas être vérifiables, ou qui ne sont pas du tout pris en charge sur certaines cibles AOT, ce qui entraîne des échecs de validation à l’exécution ou des plantages de l’application.
Limites de Blazor/WebAssembly
- Capacités de réflexion restreintes : dans Blazor WebAssembly, la réflexion est fortement limitée. Comme le proxy dynamique enveloppe ou intercepte souvent des appels de méthodes, il peut produire des chemins d’appel indirects incompatibles avec le processus d’édition de liens et d’élimination du code inutilisé (tree-shaking) des flux de travail de publication WebAssembly.
Recommandation
Pour une compatibilité totale avec les environnements AOT tels que .NET MAUI et Blazor, il est recommandé de définir DynamicProxy=false. Les assemblies générés restent ainsi entièrement vérifiables, conformes à la plateforme et exempts de fonctionnalités susceptibles d’échouer lors de l’édition de liens native ou au démarrage du runtime.