Protégez, optimisez et contrôlez votre code avec {smartassembly}

MORAND Louis-Guillaume

Découverte et présentation du logiciel {smartassembly}, un must-have pour tout développeur, qui permet d'optimiser, obfusquer et déboguer son code, le plus simplement et le plus efficacement possible.

N'hésitez pas à commenter cet article ! Commentez ♪

- Titre : Protégez, optimisez et contrôlez votre code avec {smartassembly}

- Auteur : MORAND Louis-Guillaume

- Parution : 26 mars 2005

- Licence : Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright ® 2006 MORAND Louis-Guillaume. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- Introduction

- I. Présentation de {smartassembly}

- II. Utilisation

- II-A. Choix de l'assembly

- II-B. Fusion des assemblies

- II-C. Nettoyage du code

- II-D. L'obfuscation du code

- II-E. Encodage des chaines de caractères

- II-F. Gestion des exceptions oubliées

- II-G. Sceller les classes

- II-H. Signer l'assembly

- III. La gestion des exceptions

- IV. Comparatifs

- V. Conclusion

- VI. Liens

- Remerciements

Introduction

Chaque jour, de très nombreux programmes voient le jour à l'aide des nouveaux langages. Néanmoins, en sus de la politique sur les brevets logiciels, le respect des droits d'auteur est toujours aussi présent et il nécessite de pouvoir, si on le désire, protéger son code source. Ceci se pose notamment sous Dotnet, où le principe de langage intermédiaire permet de récupérer totalement le code source d'origine. Le seul moyen de se protéger de ce type de piratage est d'obsfusquer (« obscurcir » : rendre illisible) son code. C'est en cela qu'entrent en jeu ces logiciels bien particuliers que sont les obfuscateurs.

Il existe deux logiciels très connus pour lire le code intermédiaire (Common Intermediate Language) : ILDASM et Reflector. L'utilisation de {smartassembly}, vous permettra de vous protéger du vol de code via ces logiciels. Attention, cette solution n'est pas parfaitement sûre, cependant elle permet de mieux protéger le code qu'il ne l'est par défaut.

I - Présentation de {smartassembly}

{smartassembly}, développée par la société Cachupa, vient de sortir dans sa version 1.0. Cette dernière est une application qui permet à la fois de gérer la protection de votre code, l'optimisation de celui-ci et la gestion des exceptions lors de son utilisation.
Ses fonctionnalités sont les suivantes :
- fusion des assemblies ;
- obfuscation du code ;
- obfuscation des chaines de caractères ;
- suppression du code inutile ;
- ajout d'une gestion des exceptions.

Ce sont ces fonctionnalités que je vais tenter de vous présenter le plus clairement possible.

II - Utilisation

Des nombreux logiciels d'osbfuscation que j'ai utilisés (Salamander, Xenocode, etc.), {smartassembly} est au premier abord (et par la suite également), l'application la plus user-friendly, la plus claire et la plus simple à utiliser. L'interaction de l'utilisateur peut être limitée au minimum si ce dernier en a le désir. Nous allons découvrir les différentes fonctionnalités au fil des différentes étapes de l'utilisation de {smartassembly}.

II-A - Choix de l'assembly

La première étape consiste à choisir l'assembly à obfusquer. Une assembly DotNet peut être un exécutable ou une assembly satellite (un fichier *.dll), les deux doivent bien sûr être compilés en Dotnet.

II-B - Fusion des assemblies

Pour des questions de facilité de développement ou simplement de réutilisation de composants, les développeurs sont tentés de séparer les différentes parties de leur programme en différentes assemblies. Dans cette étape, {smartassembly} propose de les fusionner en un seul exécutable.
La première question est: « pourquoi fusionner quand on a tout fait pour séparer le code ? ». Plusieurs bonnes raisons à cela :
- avec moins de fichiers, il vous sera plus facile de distribuer l'application ;
- la gestion des fichiers, que ce soit le versionning ou la présence des assemblies, est réglée ;
- les performances sont accrues dans le sens où le CLR a moins d'assembly à chercher et à charger. Les appels intermodules sont également remplacés par des appels internes, plus rapides.

II-C - Nettoyage du code

Nous constatons que déjà {smartassembly} réduit la taille de l'application, améliore ses performances et accélère son chargement. En plus d'enlever des bouts de code inutiles pouvant révéler dans le pire des cas, des informations gênantes.

Le nettoyage du code a d'autres avantages :
- l'exécutable sera allégé et plus rapide à charger ;
- en cas de non-obsfucation, le code non utilisé pourra donner des informations sur des fonctionnalités non implémentées.

II-D - L'obfuscation du code

Nous en arrivons à la fonctionnalité principale de l'application :l'obfuscation du code. Celle-ci consiste à remplacer chaque nom de variable, nom de méthode, nom de classe, etc. par une chaine de caractères souvent illisible par des logiciels de récupération de code comme Reflector.

Voici l'affichage que vous auriez avec l'aide du logiciel Reflector.

Comme vous pouvez le constater, il est dorénavant très difficile de voler votre code source. Pour ceux qui se posent des questions, même si les objets semblent tous avoir le même nom (un carré), il n'en est point et l'application reste 100 % fonctionnelle à l'exception de certaines parties qui font appel à la réflexion et pourraient ne plus marcher selon la façon que vous avez développée. Il est possible d'exclure ces parties de l'obfuscation.

II-E - Encodage des chaines de caractères

Nous avons, à l'étape précédente, obfusquer notre code en modifiant les noms de chaque objet tout en laissant l'application fonctionnelle. Sachez cependant que cette étape n'a pas modifié les chaines de caractères, car celles-ci ne sont pas propres au langage. Ainsi, en obfusquant le code :

monObjet.maMethode("password");

Vous obtiendrez après obfuscation du code :

???.???("password");

Comme vous pouvez le constater, ne pas encoder les chaines de caractères peut s'avérer encore plus dangereux que de ne pas obfusquer le code. Il nous faut donc encoder ces chaines de caractères.

Pour un résultat final qui se rapprocherait du code suivant, tout en laissant l'application totalement fonctionnelle :

???.???("????");

II-F - Gestion des exceptions oubliées

Il peut arriver que votre application contienne ou plutôt lève des exceptions que vous n'aurez pas pensé à gérer. {smartassembly} permet d'insérer au sein de votre application, un mécanisme permettant de récupérer ces exceptions et d'émettre un rapport détaillé en ligne, rapport que pourrez récupérer par la suite, pour corriger votre application.
Je décris cette fonctionnalité plus en profondeur un peu plus loin dans l'article (chapitre 3).

II-G - Sceller les classes

Vous n'êtes pas sans connaitre le mot clé « sealed » qui permet d'empêcher que l'une de vos classes soit dérivée par une autre, permettant ainsi de garder ses méthodes dans une version « finale » (et définie selon vos soins).
{smartassembly} peut s'occuper de cette gestion si vous le souhaitez, il vous suffit de cocher la case correspondante :

II-H - Signer l'assembly

Lorsque vous déployez une application, principalement dans un milieu professionnel, il est fortement conseillé de signer votre application. La signature d'une application se réalisera en créant un fichier contenant la clé (à l'aide de l'utilitaire sn.exe) puis en effectuant une modification du fichier AssemblyInfo avant de compiler l'application. Même si ce n'est pas spécialement long à faire, c'est parfois rébarbatif et il peut être intéressant d'éviter cette tâche ingrate.
En réalité, nous allons effectuer cette tâche, mais plus rapidement à l'aide de {smartassembly}.

Vous pouvez ainsi à l'aide de deux simples boutons, créer la clé et signer votre application.

III - La gestion des exceptions

{smartassembly} possède une toute dernière fonctionnalité qui mérite un chapitre à elle seule. Car il est étonnant de la trouver dans une application d'obfuscation ou autre, gérée de la façon suivante.
Les exceptions non gérées sont la plaie de tout développeur. Déjà difficiles à cerner lors du développement, elles le sont d'autant plus en production lorsque l'application se trouve chez le client. Même si vous avez pensé à les propager jusqu'à la couche présentation, il sera difficile d'en avoir un retour jusqu'au poste de développement afin d'apporter des corrections.

Une solution existe! Et aussi incroyable que cela puisse paraitre, son implémentation se fait en moins d'une seconde sur tout type d'application winform.

Comment cela marche ? Vous n'avez qu'à
- choisir votre application ;
- définir le nom du projet et de l'entreprise (qui apparaîtront lors de l'exception) ;
- de générer votre projet.

L'application se verra inclure un module complet de gestion d'exception, qui affichera un formulaire d'erreur en cas d'exception et proposera de l'envoyer en ligne sur votre compte {smartassembly}.

L'image précédente montre le panneau qui apparaît chez l'utilisateur si une exception se déclenche. L'utilisateur peut ou non décider de vous envoyer ce rapport.
Comment récupérer ce rapport ? Lancez simplement {smartassembly} et dans la partie droite cliquez sur Download new reports. Ceci a pour effet de rapatrier en local tous vos rapports d'exception stockés sur un serveur de {smartassembly}.

Une fois ceux-ci téléchargés, vous pouvez les visualiser comme une boîte eMail et afficher les détails de l'exception de façon complète et pourtant lisible.

Si vous n'êtes pas convaincu, testez-le! Et vous vous rendrez vite compte que c'est sûrement la solution la plus simple à mettre en place pour suivre et réaliser le suivi technique de vos applications.

IV - Comparatifs

Il faut savoir que l'obfuscation d'un logiciel a une influence sur les performances de l'application. Ceci est la conséquence de l'obfuscation ou de l'ajout de routine de protection, l'application peut s'en trouver moins performante.
Je n'ai pu réaliser tous les tests de performance avant et après obfuscation, pour savoir si les performances de l'application en étaient grandement réduites. Néanmoins j'ai pris le temps d'analyser la taille de l'application obfusquée, selon différents paramètres. Cela peut paraitre non significatif à certains, mais lors d'un déploiement en milieu professionnel, via ClickOnce par exemple, la taille de l'exécutable n'est pas négligeable.

Option

Taille après génération

Incidence sur la taille

Génération par VS2005

(2,28Mo) 2 396 160 octets

Non applicable

Génération par {smartassembly} sans options

(2,27Mo) 2 384 896 octets

Non applicable

Fusion des assemblies

Non testé

Non testé

Suppression du code inutile

(2,26Mo) 2 374 656 octets

Diminution

Obfuscation du code

(2,26Mo) 2 376 704 octets

Diminution

Encodage des chaines de caractères

(2,29Mo) 2 406 400 octets

Augmentation

Gestion des exceptions

(2,36Mo) 2 476 032 octets

Augmentation

Toutes les options

(2,35Mo) 2 471 424 octets

Augmentation ici, mais variable

Ces petits tests avaient pour but de satisfaire ma curiosité quant aux effets secondaires que génère l'utilisation de telles fonctionnalités. J'ai constaté que l'application a sa taille augmentée de 3 % (70 ko), sachant que plus l'application est lourde de base, moins la différence se fera sentir. L'utilisation d'un tel produit n'a, semble-t-il, aucune incidence significative sur la taille de votre application.

V - Conclusion

J'ai eu la chance de tester plusieurs logiciels dans différents domaines et je pensais à priori que {smartassembly} était un simple utilitaire permettant d'obfusquer le code à l'instar du Refractoring de Visual Studio 2005. Depuis cet article, je peux aujourd'hui reconnaitre que {smartassembly} se trouve être un logiciel esthétique, très facile d'utilisation et surtout offrant des fonctionnalités plus intéressantes les unes que les autres.
Je considère maintenant {smartassembly} comme un must-have que devrait posséder tout développeur soucieux de fournir une application sûre, fiable et garantissant un suivi adapté des éventuelles exceptions que pourrait produire le comportement utilisateur final.

Quant à l'intérêt des différentes fonctionnalités, je dirai qu'aucune n'est moins intéressante qu'une autre. Leur facilité d'utilisation sans réel inconvénient (y compris la taille de l'exécutable), est la raison pour laquelle je n'hésiterai pas utiliser {smartassembly} dans le cadre de mes développements applicatifs.

VI - Liens

Si vous souhaitez plus d'informations sur {smartassembly}, je vous encourage à vous rendre sur le site officiel afin d'y télécharger la version d'évaluation et d'y trouver les réponses aux questions que vous pourriez vous poser.

Télécharger une version d'essai

Remerciements

Un grand merci à Neguib et Xo pour leurs corrections/conseils.