Appels internes et externes
Le proxy dynamique peut s’appliquer à deux catégories d’appels, sélectionnées par le mode de proxy :
| Mode | Fait passer par proxy les appels vers… |
|---|---|
external | les méthodes et constructeurs définis en dehors de l’assembly en cours d’obfuscation : la bibliothèque de classes de base .NET et les assemblies référencés |
internal | les méthodes et constructeurs définis dans l’assembly en cours d’obfuscation |
all | les appels internes et les appels externes |
Voir Configuration pour sélectionner un mode depuis la ligne de commande, MSBuild ou Babel Desktop.
Appels internes par proxy
L’utilisation du proxy dynamique pour les appels de méthodes internes présente plusieurs avantages pour l’obfuscation et la protection du code. En voici les principaux :
- Masquer les détails d’implémentation : lorsque des proxys dynamiques sont générés pour les types internes, les détails d’implémentation réels de ces types sont cachés au code externe et aux attaquants potentiels. Les proxys dynamiques servent d’intermédiaires et protègent la logique interne et la structure des types, ce qui rend votre code plus difficile à comprendre et à manipuler pour des acteurs malveillants.
- Faire écran aux appels de méthodes : lorsque des proxys dynamiques sont utilisés pour les types internes, les décompilateurs peinent à reconstruire le flux d’appels d’une méthode. Les décompilateurs analysent le code compilé pour produire une représentation de haut niveau du code source d’origine. Les proxys dynamiques introduisent toutefois une couche d’indirection supplémentaire, qui empêche les décompilateurs de retracer avec précision la séquence des appels de méthodes.
- Obfuscation renforcée : l’utilisation de proxys dynamiques pour les types internes ajoute une couche d’obfuscation supplémentaire à votre code. Les proxys introduisent de la complexité et de l’indirection, et il devient plus difficile, pour qui pratique la rétro-ingénierie, de comprendre la structure sous-jacente et les relations de votre code. Cela peut décourager les tentatives de rétro-ingénierie et protéger votre propriété intellectuelle.
En utilisant le proxy dynamique pour les appels internes, vous créez une barrière qui empêche les décompilateurs de reconstruire avec précision le flux d’appels de votre code. Vous ajoutez ainsi une couche de protection supplémentaire, et il devient plus difficile, pour des attaquants ou des spécialistes de la rétro-ingénierie, de comprendre la logique sous-jacente et le comportement de votre application.
Appels externes par proxy
Les appels externes par proxy de Babel Obfuscator constituent un mécanisme de défense efficace contre les décompilateurs qui tentent de reconstruire les noms des variables locales à partir de leurs types inférés. Les décompilateurs s’appuient souvent sur les métadonnées disponibles, comme les types des variables, pour reconstruire les noms d’origine des variables.
Par exemple, dans le code décompilé ci-dessous, l’outil a déduit les noms de variables list1 et count respectivement de l’appel au constructeur d’instance du type List<string> et de la méthode get_Count().
var list1 = new List<string>();
int count = list1.Count;Lorsque les appels externes par proxy sont activés, Babel Obfuscator remplace les appels directs de méthodes vers du code externe par des appels à des classes proxy générées dynamiquement. Ces classes proxy servent d’intermédiaires : elles interceptent et redirigent les appels de méthodes. Les appels de méthodes d’origine et les noms de variables locales associés sont ainsi masqués et obfusqués.
Avec le proxy dynamique activé, le code ci-dessus devient le suivant :
var local1 = new a();
int local2 = local1.b();Les décompilateurs qui s’appuient uniquement sur les métadonnées pour reconstruire les noms de variables se heurtent à des difficultés face aux appels externes par proxy. Comme les appels de méthodes d’origine sont remplacés par des appels par proxy, les types de variables inférés ne fournissent à eux seuls aucune information utile sur les noms d’origine des variables. Le décompilateur ne peut donc plus reconstruire les noms d’origine à partir de la seule inférence de types.