
.NET deobfuscator and unpacker.
de4dot est un désobfuscateur et unpacker .NET open source (GPLv3) écrit en C#. Il fera de son mieux pour restaurer un assembly empaqueté et obfusqué pour le ramener presque à l'assembly d'origine. La plupart des obfuscations peuvent être complètement restaurées (par ex. le chiffrement des chaînes), mais le renommage des symboles est impossible à restaurer car les noms d'origine ne font (généralement) pas partie de l'assembly obfusqué.
Il utilise dnlib pour lire et écrire les assemblies, alors assurez-vous de l'obtenir, sinon il ne compilera pas.
Téléchargez les binaires depuis le serveur de build .
Il n'y a aucun support. Ne m'envoyez pas d'e-mail si vous n'arrivez pas à l'utiliser ou s'il échoue à désobfusquer un fichier obfusqué avec un obfuscateur mis à jour.
Essayez plutôt de mettre à jour de4dot vous-même. C'est beaucoup plus facile que vous ne le pensez. Si vous n'y arrivez pas, cherchez sur Internet et vous devriez trouver quelques forums où poser votre question.
Voici une liste pseudo-aléatoire de ce qu'il fera selon l'obfuscateur utilisé pour obfusquer un assembly :
Certains des obfuscateurs ci-dessus sont rarement utilisés (par ex. Goliath.NET), ils ont donc été beaucoup moins testés. Aidez-moi en signalant les bogues ou les problèmes que vous trouvez.
Parfois, l'assembly obfusqué et toutes ses dépendances sont chargés en mémoire pour être exécutés. Utilisez un environnement sandbox sûr si vous soupçonnez que l'assembly ou les assemblies sont des malwares.
Même si la version actuelle de de4dot ne charge pas un assembly donné en mémoire pour l'exécuter, une version future pourrait le faire.
Glissez-déposez le ou les fichiers sur de4dot.exe et attendez quelques secondes.
Lorsque plusieurs assemblies ont été obfusqués, il est très probable que vous deviez tous les désobfusquer en même temps, sauf si vous désactivez le renommage des symboles. La raison est que si l'assembly A a une référence à la classe C dans l'assembly B, et que vous renommez les symboles uniquement dans l'assembly B, la classe C pourrait être renommée en par ex. Class0, mais la référence dans l'assembly A référence toujours une classe nommée C dans l'assembly B. Si vous désobfusquez les deux assemblies en même temps, toutes les références seront également mises à jour.
La ligne de commande suivante désobfusquera tous les assemblies qui ont été obfusqués par un obfuscateur pris en charge et enregistrera les assemblies dans c:\output
de4dot -r c:\input -ru -ro c:\output
-r signifie recherche récursive. -ru signifie qu'il doit ignorer les fichiers inconnus. -ro signifie qu'il doit placer les fichiers de sortie dans le répertoire suivant. En général, vous copiez d'abord c:\input vers c:\output, puis vous exécutez la commande. Ainsi, tous les fichiers seront dans c:\output, même ceux qui ne sont pas des assemblies et les assemblies non traités. Une fois de4dot terminé, il vous suffit de double-cliquer sur l'assembly principal dans c:\output et il devrait, espérons-le, démarrer.
Utilisez l'option -d pour détecter l'obfuscateur sans désobfusquer aucun assembly.
Recherche tous les assemblies .NET et détecte l'obfuscateur. Si c'est un obfuscateur non pris en charge ou s'il n'est pas obfusqué, il affichera « Unknown obfuscator ».
de4dot -d -r c:\input
Identique à la commande précédente, sauf qu'il affichera uniquement les fichiers qui ont été obfusqués par un obfuscateur pris en charge.
de4dot -d -r c:\input -ru
Détecter l'obfuscateur
de4dot -d file1.dll file2.dll file3.dll
Parfois, dans de rares cas, vous pouvez vouloir préserver les jetons de métadonnées. Utilisez --preserve-tokens ou --preserve-table. Pensez également à utiliser --keep-types car cela ne supprimera aucun type ni aucune méthode ajoutés par l'obfuscateur. Une autre option utile est --dont-create-params. Si elle est utilisée, le renommeur ne créera pas de lignes Param pour les paramètres de méthode qui n'ont pas de ligne Param. Ainsi, la table ParamPtr ne sera pas ajoutée à vos assemblies. Peverify a un bug et ne la prend pas en charge (vous verrez beaucoup d'« erreurs »).
Les tas #Strings, #US et #Blob peuvent également être préservés en utilisant respectivement --preserve-strings, --preserve-us et --preserve-blob. De ces trois, --preserve-us est le plus utile car l'instruction ldstr et module.ResolveString() référencent directement le tas #US.
--preserve-sig-data doit être utilisé si l'obfuscateur ajoute des données supplémentaires à la fin des signatures qu'il utilise à ses propres fins, par ex. comme clés de déchiffrement. Confuser est un obfuscateur qui fait cela.
--preserve-tokens préserve tous les jetons importants mais activera également --preserve-us, --preserve-blob et --preserve-sig-data.
S'il est détecté comme un obfuscateur inconnu (non pris en charge) (ou si vous forcez avec -p un), tous les jetons sont préservés, y compris le tas #US et toutes les données supplémentaires à la fin des signatures. De plus, aucun type, champ ou méthode d'obfuscateur n'est supprimé.
Préserve tous les jetons importants, #US, #Blob, les données de signature supplémentaires.
de4dot --preserve-tokens file1.dll
Préserve tous les jetons importants, #US, #Blob, les données de signature supplémentaires et ne supprime pas les types/champs ajoutés par l'obfuscateur.
de4dot --keep-types --preserve-tokens file1.dll
Préserve tous les jetons importants, #US, #Blob, les données de signature supplémentaires et ne crée pas de lignes Param supplémentaires pour empêcher la création de la table ParamPtr.
de4dot --dont-create-params --preserve-tokens file1.dll
Préserve tous les jetons importants sauf les jetons Param.
de4dot --preserve-table all,-pd file1.dll
Bien que de4dot prenne en charge de nombreux obfuscateurs, il en existe encore certains qu'il ne prend pas en charge. Pour déchiffrer les chaînes, vous devez d'abord déterminer quelle méthode ou quelles méthodes déchiffrent les chaînes. Pour obtenir le jeton de méthode de ces déchiffreurs de chaînes, vous pouvez utiliser ILDASM avec l'option « show metadata tokens » activée. Un jeton de méthode est un nombre 32 bits qui commence par 06, par ex. 06012345.
Cette commande chargera l'assembly file1.dll en mémoire en appelant Assembly.Load(). Lorsqu'elle détecte des appels aux deux déchiffreurs de chaînes (06012345 et 060ABCDE), elle les appelle en créant une méthode dynamique, puis enregistre le résultat (la chaîne déchiffrée). L'appel au déchiffreur de chaînes sera supprimé et la chaîne déchiffrée prendra sa place.
de4dot file1.dll --strtyp delegate --strtok 06012345 --strtok 060ABCDE
Étant donné que l'assembly est chargé et exécuté, assurez-vous de l'exécuter dans un sandbox si vous soupçonnez que le fichier est un malware.
de4dot n'est pas parfait. S'il ne parvient pas à détecter un obfuscateur, vous pouvez utiliser l'option -p pour le forcer à supposer que l'assembly a été obfusqué par celui-ci.
Forcer SmartAssembly
de4dot file1.dll -p sa
Forcer un obfuscateur non pris en charge
de4dot file1.dll -p un
Pour les autres types d'obfuscateurs, consultez l'écran d'aide.
Renommer des symboles n'est pas aussi simple que de remplacer A par B lorsque la réflexion est impliquée. de4dot ne prend actuellement pas en charge le renommage XAML, donc si vous soupçonnez qu'il utilise WPF (ou s'il s'agit d'une application Silverlight), vous devez désactiver le renommage si l'assembly ne parvient pas à s'exécuter.
de4dot --dont-rename file1.dll file2.dll
--keep-names peut également être utilisé pour indiquer à de4dot de ne pas renommer certains symboles, par ex. « ne renommez pas les champs ».
Renomme tout ce qui doit être renommé, sauf les propriétés, les événements et les méthodes.
de4dot --keep-names pem file1.dll
Les expressions régulières par défaut devraient suffire, sauf peut-être celle utilisée lorsqu'un obfuscateur non pris en charge est détecté. Pour voir toutes les expressions régulières par défaut, lancez de4dot sans argument et il listera toutes les options et toutes les valeurs par défaut.
Par ex., actuellement l'expression régulière suivante est celle utilisée par défaut lorsque Dotfuscator est détecté
!^[a-z][a-z0-9]{0,2}$&!^A_[0-9]+$&^[\u2E80-\u9FFFa-zA-Z_<{$][\u2E80-\u9FFFa-zA-Z_0-9<>{}$.`-]*$
Comme vous pouvez le voir, ce n'est pas une seule expression régulière, mais plusieurs. Chacune est séparée par & et chaque expression régulière peut être niée en plaçant ! devant elle. Pour le montrer plus clairement, ces expressions régulières sont utilisées :
(negated) ^[a-z][a-z0-9]{0,2}$
(negated) ^A_[0-9]+$
^[\u2E80-\u9FFFa-zA-Z_<{$][\u2E80-\u9FFFa-zA-Z_0-9<>{}$.`-]*$
Pour modifier la ou les expressions régulières, vous devez connaître le nom court du type de l'obfuscateur (voir l'écran d'aide). Par ex., c'est sa pour SmartAssembly, et un pour un obfuscateur non pris en charge/inconnu. L'option à utiliser est --TYPE-name (par ex. --sa-name pour SmartAssembly et --un-name pour les obfuscateurs inconnus/non pris en charge) :
de4dot --un-name "^[a-zA-Z]\w*$" file1.dll
Lancez de4dot sans aucun argument et il affichera toutes les options.