Hé, avez-vous déjà pensé à quel point vos algorithmes sont cool et uniques ? ? De nombreux programmeurs et entreprises le font, c'est pourquoi ils pourraient hésiter à partager leur travail avec tout le monde. Ce problème s'améliore un peu si une partie du code est déplacée vers le serveur (pour les applications client-serveur), mais cette approche n'est pas toujours possible. Parfois, nous devons laisser des sections de code sensibles à l'air libre.
Dans cet article, nous allons examiner l'obscurcissement dans JavaScript, en créant des moyens de masquer les algorithmes et de rendre plus difficile l'étude du code. Nous explorerons également ce qu'est l'AST et fournirons des outils qui peuvent être utilisés pour interagir avec lui afin de mettre en œuvre l'obscurcissement.
Voici un exemple idiot. Imaginons cette situation :
let w = screen.width, h = screen.height; // Let's say there's a logic with some check. console.info(w, h);
Malheureusement, Bob ne peut pas accéder à la page des cadeaux, et il en est assez contrarié. Il ne comprend pas pourquoi. Puis il apprend dans les règles du concours que les utilisateurs équipés de grands et bons moniteurs ne sont pas autorisés.
Heureusement, Bob avait suivi des cours d'informatique au lycée. Il ouvre la console développeur de manière décisive en appuyant sur F12, étudie le script et se rend compte que les organisateurs vérifient la résolution de l'écran. Il décide alors de participer depuis son téléphone et réussit le test.
Une histoire fictive avec une fin heureuse - mais cela n'aurait pas pu être aussi bon si le personnage principal avait vu ceci au lieu du code précédent :
l=~[];l={___:++l,$$$$:(![]+"")[l],__$:++l,$_$_:(![]+"")[l],_$_:++l,$_$$:({}+"")[l],$$_$:(l[l]+"")[l],_$$:++l,$$$_:(!""+"")[l],$__:++l,$_$:++l,$$__:({}+"")[l],$$_:++l,$$$:++l,$___:++l,$__$:++l};l.$_=(l.$_=l+"")[l.$_$]+(l._$=l.$_[l.__$])+(l.$$=(l.$+"")[l.__$])+((!l)+"")[l._$$]+(l.__=l.$_[l.$$_])+(l.$=(!""+"")[l.__$])+(l._=(!""+"")[l._$_])+l.$_[l.$_$]+l.__+l._$+l.$;l.$$=l.$+(!""+"")[l._$$]+l.__+l._+l.$+l.$$;l.$=(l.___)[l.$_][l.$_];l.$(l.$(l.$$+"\""+(![]+"")[l._$_]+l.$$$_+l.__+"\"+l.$__+l.___+"\"+l.__$+l.$$_+l.$$$+"\"+l.$__+l.___+"=\"+l.$__+l.___+"\"+l.__$+l.$$_+l._$$+l.$$__+"\"+l.__$+l.$$_+l._$_+l.$$$_+l.$$$_+"\"+l.__$+l.$_$+l.$$_+".\"+l.__$+l.$$_+l.$$$+"\"+l.__$+l.$_$+l.__$+l.$$_$+l.__+"\"+l.__$+l.$_$+l.___+",\"+l.$__+l.___+"\"+l.__$+l.$_$+l.___+"\"+l.$__+l.___+"=\"+l.$__+l.___+"\"+l.__$+l.$$_+l._$$+l.$$__+"\"+l.__$+l.$$_+l._$_+l.$$$_+l.$$$_+"\"+l.__$+l.$_$+l.$$_+".\"+l.__$+l.$_$+l.___+l.$$$_+"\"+l.__$+l.$_$+l.__$+"\"+l.__$+l.$__+l.$$$+"\"+l.__$+l.$_$+l.___+l.__+";\"+l.__$+l._$_+l.$$__+l._$+"\"+l.__$+l.$_$+l.$$_+"\"+l.__$+l.$$_+l._$$+l._$+(![]+"")[l._$_]+l.$$$_+".\"+l.__$+l.$_$+l.__$+"\"+l.__$+l.$_$+l.$$_+l.$$$$+l._$+"(\"+l.__$+l.$$_+l.$$$+",\"+l.$__+l.___+"\"+l.__$+l.$_$+l.___+");"+"\"")())();
Je vous rassure, ce n'est pas du charabia, c'est du JavaScript ! Et il effectue les mêmes actions. Vous pouvez essayer d'exécuter le code dans la console ici.
Je suppose que dans ce cas, notre héros aurait simplement accepté son sort en ne participant pas au concours, et les organisateurs auraient tenu leur plan.
Alors, à quoi ça sert ici ? Félicitations : vous avez découvert l'outil jjencode, ce qu'est l'obscurcissement et quel rôle il peut jouer.
En résumé, l'obscurcissement est le processus de conversion du code ou des données d'un programme en une forme difficile à comprendre pour les humains mais qui fonctionne toujours pour une machine ou un programme.
Assez de théories, passons à des exemples plus pratiques ??. Essayons maintenant de convertir le code à l'aide d'obscurcissements que vous êtes plus susceptible de trouver sur Internet. Prenons un code plus intéressant qui contient nos opérations de « savoir-faire ». Et il n'est fortement pas souhaitable que tous ceux qui ne sont pas trop paresseux pour atteindre la F12 puissent les découvrir :
let w = screen.width, h = screen.height; // Let's say there's a logic with some check. console.info(w, h);
Ce code collecte les données de l'appareil et du navigateur et affiche le résultat sur la console, par exemple (nous utiliserons la sortie comme mesure des performances du code) :
l=~[];l={___:++l,$$$$:(![]+"")[l],__$:++l,$_$_:(![]+"")[l],_$_:++l,$_$$:({}+"")[l],$$_$:(l[l]+"")[l],_$$:++l,$$$_:(!""+"")[l],$__:++l,$_$:++l,$$__:({}+"")[l],$$_:++l,$$$:++l,$___:++l,$__$:++l};l.$_=(l.$_=l+"")[l.$_$]+(l._$=l.$_[l.__$])+(l.$$=(l.$+"")[l.__$])+((!l)+"")[l._$$]+(l.__=l.$_[l.$$_])+(l.$=(!""+"")[l.__$])+(l._=(!""+"")[l._$_])+l.$_[l.$_$]+l.__+l._$+l.$;l.$$=l.$+(!""+"")[l._$$]+l.__+l._+l.$+l.$$;l.$=(l.___)[l.$_][l.$_];l.$(l.$(l.$$+"\""+(![]+"")[l._$_]+l.$$$_+l.__+"\"+l.$__+l.___+"\"+l.__$+l.$$_+l.$$$+"\"+l.$__+l.___+"=\"+l.$__+l.___+"\"+l.__$+l.$$_+l._$$+l.$$__+"\"+l.__$+l.$$_+l._$_+l.$$$_+l.$$$_+"\"+l.__$+l.$_$+l.$$_+".\"+l.__$+l.$$_+l.$$$+"\"+l.__$+l.$_$+l.__$+l.$$_$+l.__+"\"+l.__$+l.$_$+l.___+",\"+l.$__+l.___+"\"+l.__$+l.$_$+l.___+"\"+l.$__+l.___+"=\"+l.$__+l.___+"\"+l.__$+l.$$_+l._$$+l.$$__+"\"+l.__$+l.$$_+l._$_+l.$$$_+l.$$$_+"\"+l.__$+l.$_$+l.$$_+".\"+l.__$+l.$_$+l.___+l.$$$_+"\"+l.__$+l.$_$+l.__$+"\"+l.__$+l.$__+l.$$$+"\"+l.__$+l.$_$+l.___+l.__+";\"+l.__$+l._$_+l.$$__+l._$+"\"+l.__$+l.$_$+l.$$_+"\"+l.__$+l.$$_+l._$$+l._$+(![]+"")[l._$_]+l.$$$_+".\"+l.__$+l.$_$+l.__$+"\"+l.__$+l.$_$+l.$$_+l.$$$$+l._$+"(\"+l.__$+l.$$_+l.$$$+",\"+l.$__+l.___+"\"+l.__$+l.$_$+l.___+");"+"\"")())();
Prenons maintenant le code ci-dessus et modifions-le avec un obfuscateur populaire pour JS - obfuscator.io. En conséquence, nous obtiendrons un code comme celui-ci :
function getGpuData(){ let cnv = document.createElement("canvas"); let ctx = cnv.getContext("webgl"); const rendererInfo = ctx.getParameter(ctx.RENDERER); const vendorInfo = ctx.getParameter(ctx.VENDOR); return [rendererInfo, vendorInfo] } function getLanguages(){ return window.navigator.languages; } let data = {}; data.gpu = getGpuData(); data.langs = getLanguages(); console.log(JSON.stringify(data))
Voila ! Désormais, seule une machine se fera un plaisir d'analyser ce code (vous et moi n'en faisons probablement pas partie ?). Néanmoins, cela fonctionne toujours et produit le même résultat. Notez les changements :
La dernière technique est peut-être la plus désagréable dans ce cas, en termes de surcharge de l'analyse de code statique.
Très bien, on dirait que tous les secrets sont cachés. Devons-nous déployer le code en production ?
Attendez... S'il existe des services pour l'obscurcissement du code, peut-être y en a-t-il qui peuvent retirer ce genre de choses ? Absolument ?, et plus d'un ! Essayons d'en utiliser un - webcrack. Et voyons si nous pouvons obtenir le code original et lisible. Vous trouverez ci-dessous le résultat de l'utilisation de ce désobfuscateur :
{"gpu":["ANGLE (NVIDIA, NVIDIA GeForce GTX 980 Direct3D11 vs_5_0 ps_5_0), or similar","Mozilla"],"langs":["en-US","en"]}
Oups ?. Bien sûr, il n'a pas renvoyé les noms des variables, mais merci pour cela.
Il s'avère donc que le seul obstacle pour étudier sereinement notre code dans ce cas est la volonté du chercheur d'utiliser le désobfuscateur. Sans aucun doute, il est également possible d'utiliser d'autres solutions et personnalisations, mais pour toute obfuscation populaire, il faut très probablement s'attendre à une désobfuscation populaire.
Devrions-nous désespérer et abandonner nos secrets sans combattre ? Bien sûr que non! Voyons ce que nous pouvons faire de plus....
Un obfuscateur - cela ressemble à une sorte de mage d'un univers fantastique, n'est-ce pas ? ??♂️
Décidément, quelqu'un peut obscurcir le code en l'écrivant et est un magicien né. Il se peut même que vous ayez involontairement pu lancer de tels sorts vous-même pendant un certain temps. Mais que faire maintenant si les compétences ont disparu à cause des critiques des « programmeurs seniors » et que vous avez une idée qui vous permet potentiellement de rendre le programme difficile à étudier ? Dans ce cas, il est logique de se tourner vers des outils qui interagissent avec la structure du code elle-même et permettent de la modifier. Jetons un coup d'œil à eux.
Il est également possible d'essayer de modifier le code en interagissant avec lui simplement comme avec du texte, en remplaçant certaines constructions par des expressions régulières etc. Mais je dirais qu'en suivant cette méthode, vous avez plus de chances de ruiner votre code et votre temps que de l'obscurcir.
Pour une modification plus fiable et contrôlée, il est logique de l'amener à une structure abstraite, un arbre (AST - arbre de syntaxe abstraite), en passant par lequel on peut changer les éléments et les constructions qui nous intéressent .
Il existe différentes solutions pour travailler avec du code JS, avec des différences dans l'AST final. Dans cet article, nous utiliserons babel à cet effet. Vous n'avez rien besoin d'installer, vous pouvez tout expérimenter sur une ressource telle qu'astexplorer.
(Si vous ne voulez pas jouer avec Babel, consultez shift-refactor. Il vous permet d'interagir avec AST à l'aide de **sélecteurs CSS. Approche assez minimaliste et pratique pour l'apprentissage et modifier le code. Mais il utilise une version spécifique d'AST, différente de babel. Vous pouvez tester vos requêtes CSS pour cet outil sur la démo interactive shift-query).
.Voyons maintenant comment ces outils peuvent être facilement utilisés sans quitter le navigateur, sur la base d'un exemple simple. Supposons que nous devions changer le nom de la variable de test dans la fonction du même nom en modifié :
let w = screen.width, h = screen.height; // Let's say there's a logic with some check. console.info(w, h);
Collez ce code dans astexplorer (sélectionnez JavaScript et @babel/parser ci-dessus), il devrait y apparaître comme un AST. Vous pouvez cliquer sur la variable de test pour voir la syntaxe de cette section de code dans la fenêtre de droite :
Pour résoudre notre problème, nous pouvons écrire le plugin babel suivant, qui analysera notre code et y recherchera tous les noms et identifiants et les renommera si certaines conditions sont remplies. Collons-le dans la fenêtre en bas à gauche d'astexplorer (activez le curseur transform et sélectionnez babelv7 pour le faire apparaître) :
let w = screen.width, h = screen.height; // Let's say there's a logic with some check. console.info(w, h);
La sortie console est incluse dans ce plugin pour une raison. Cela nous permet de déboguer notre plugin en examinant la sortie dans la console du navigateur. Dans ce cas, nous générons des informations sur tous les nœuds de type Identifiant. Ces informations contiennent des données sur le nœud lui-même (nœud), le nœud parent (parent) et l'environnement (portée - contient des variables créées dans le contexte actuel et des références à celles-ci) :
Ainsi, dans la fenêtre en bas à droite, nous pouvons remarquer que la variable dans notre code source a été modifiée avec succès sans affecter les autres identifiants :
l=~[];l={___:++l,$$$$:(![]+"")[l],__$:++l,$_$_:(![]+"")[l],_$_:++l,$_$$:({}+"")[l],$$_$:(l[l]+"")[l],_$$:++l,$$$_:(!""+"")[l],$__:++l,$_$:++l,$$__:({}+"")[l],$$_:++l,$$$:++l,$___:++l,$__$:++l};l.$_=(l.$_=l+"")[l.$_$]+(l._$=l.$_[l.__$])+(l.$$=(l.$+"")[l.__$])+((!l)+"")[l._$$]+(l.__=l.$_[l.$$_])+(l.$=(!""+"")[l.__$])+(l._=(!""+"")[l._$_])+l.$_[l.$_$]+l.__+l._$+l.$;l.$$=l.$+(!""+"")[l._$$]+l.__+l._+l.$+l.$$;l.$=(l.___)[l.$_][l.$_];l.$(l.$(l.$$+"\""+(![]+"")[l._$_]+l.$$$_+l.__+"\"+l.$__+l.___+"\"+l.__$+l.$$_+l.$$$+"\"+l.$__+l.___+"=\"+l.$__+l.___+"\"+l.__$+l.$$_+l._$$+l.$$__+"\"+l.__$+l.$$_+l._$_+l.$$$_+l.$$$_+"\"+l.__$+l.$_$+l.$$_+".\"+l.__$+l.$$_+l.$$$+"\"+l.__$+l.$_$+l.__$+l.$$_$+l.__+"\"+l.__$+l.$_$+l.___+",\"+l.$__+l.___+"\"+l.__$+l.$_$+l.___+"\"+l.$__+l.___+"=\"+l.$__+l.___+"\"+l.__$+l.$$_+l._$$+l.$$__+"\"+l.__$+l.$$_+l._$_+l.$$$_+l.$$$_+"\"+l.__$+l.$_$+l.$$_+".\"+l.__$+l.$_$+l.___+l.$$$_+"\"+l.__$+l.$_$+l.__$+"\"+l.__$+l.$__+l.$$$+"\"+l.__$+l.$_$+l.___+l.__+";\"+l.__$+l._$_+l.$$__+l._$+"\"+l.__$+l.$_$+l.$$_+"\"+l.__$+l.$$_+l._$$+l._$+(![]+"")[l._$_]+l.$$$_+".\"+l.__$+l.$_$+l.__$+"\"+l.__$+l.$_$+l.$$_+l.$$$$+l._$+"(\"+l.__$+l.$$_+l.$$$+",\"+l.$__+l.___+"\"+l.__$+l.$_$+l.___+");"+"\"")())();
J'espère que, sur la base de cet exemple, il est devenu un peu plus clair comment nous pouvons analyser et modifier le code. Quoi qu'il en soit, permettez-moi de résumer le travail effectué :
Il est désormais clair comment modifier le code. Essayons quelque chose de plus utile, que nous pourrons appeler l'obscurcissement :) Nous prendrons un code plus complexe que nous avons essayé d'obscurcir dans la section précédente. Nous allons maintenant remplacer tous les noms de variables et de fonctions par des noms aléatoires. Ainsi, un potentiel ingénieur inverse aurait moins d’informations sur le but de certains éléments de code.
N'hésitez pas non plus à utiliser n'importe quel code JS pour déboguer les problèmes. Comme on dit, il n'y a pas de meilleur professeur que la douleur ?.
Le plugin suivant nous aidera à faire le travail :
function getGpuData(){ let cnv = document.createElement("canvas"); let ctx = cnv.getContext("webgl"); const rendererInfo = ctx.getParameter(ctx.RENDERER); const vendorInfo = ctx.getParameter(ctx.VENDOR); return [rendererInfo, vendorInfo] } function getLanguages(){ return window.navigator.languages; } let data = {}; data.gpu = getGpuData(); data.langs = getLanguages(); console.log(JSON.stringify(data))
À quoi sert ce code ? À peu près la même chose que dans l'exemple précédent :
À la suite de l'exécution de notre plugin, nous obtenons le code suivant avec des noms de variables aléatoires et des fonctions :
{"gpu":["ANGLE (NVIDIA, NVIDIA GeForce GTX 980 Direct3D11 vs_5_0 ps_5_0), or similar","Mozilla"],"langs":["en-US","en"]}
Vous pouvez le vérifier en exécutant le code en console - après nos manipulations, cela fonctionne toujours ! Et c'est la principale qualité d'un bon obfuscateur ✨.
Mais qu’en est-il de la qualité de notre obscurcissement ? Quant à moi, le mal n'est pas encore trop fort : même en remplaçant les noms, il sera facile pour un programmeur expérimenté de comprendre le but de ce code. Et à quoi ça sert si n'importe quel minificateur JS peut gérer cette tâche. Est-il possible maintenant de faire quelque chose de plus pratique et plus gênant pour un inverseur ? Il y a encore un sort...
J'étais peut-être un peu confiant lorsque j'ai écrit « tout », mais ce que nous allons faire maintenant cachera les actions de notre code dans la mesure du possible. Dans cette section, nous allons dissimuler les chaînes et diverses propriétés d'objets afin de compliquer l'analyse statique et potentiellement empêcher le « client » de fouiller dans notre code !
Reprenons le code aux noms cachés obtenu à l'étape précédente et appliquons-lui le plugin suivant :
let w = screen.width, h = screen.height; // Let's say there's a logic with some check. console.info(w, h);
J'ai déjà décrit un peu le travail de ce plugin dans les commentaires du code, mais décrivons brièvement étape par étape ce qu'il fait :
Il convient de mentionner que les opérations d'analyse ne sont pas effectuées séquentiellement, mais au fur et à mesure que le nœud nécessaire est trouvé lors du traitement AST.
À la suite de l'exécution de ce plugin, nous obtiendrons le code suivant :
l=~[];l={___:++l,$$$$:(![]+"")[l],__$:++l,$_$_:(![]+"")[l],_$_:++l,$_$$:({}+"")[l],$$_$:(l[l]+"")[l],_$$:++l,$$$_:(!""+"")[l],$__:++l,$_$:++l,$$__:({}+"")[l],$$_:++l,$$$:++l,$___:++l,$__$:++l};l.$_=(l.$_=l+"")[l.$_$]+(l._$=l.$_[l.__$])+(l.$$=(l.$+"")[l.__$])+((!l)+"")[l._$$]+(l.__=l.$_[l.$$_])+(l.$=(!""+"")[l.__$])+(l._=(!""+"")[l._$_])+l.$_[l.$_$]+l.__+l._$+l.$;l.$$=l.$+(!""+"")[l._$$]+l.__+l._+l.$+l.$$;l.$=(l.___)[l.$_][l.$_];l.$(l.$(l.$$+"\""+(![]+"")[l._$_]+l.$$$_+l.__+"\"+l.$__+l.___+"\"+l.__$+l.$$_+l.$$$+"\"+l.$__+l.___+"=\"+l.$__+l.___+"\"+l.__$+l.$$_+l._$$+l.$$__+"\"+l.__$+l.$$_+l._$_+l.$$$_+l.$$$_+"\"+l.__$+l.$_$+l.$$_+".\"+l.__$+l.$$_+l.$$$+"\"+l.__$+l.$_$+l.__$+l.$$_$+l.__+"\"+l.__$+l.$_$+l.___+",\"+l.$__+l.___+"\"+l.__$+l.$_$+l.___+"\"+l.$__+l.___+"=\"+l.$__+l.___+"\"+l.__$+l.$$_+l._$$+l.$$__+"\"+l.__$+l.$$_+l._$_+l.$$$_+l.$$$_+"\"+l.__$+l.$_$+l.$$_+".\"+l.__$+l.$_$+l.___+l.$$$_+"\"+l.__$+l.$_$+l.__$+"\"+l.__$+l.$__+l.$$$+"\"+l.__$+l.$_$+l.___+l.__+";\"+l.__$+l._$_+l.$$__+l._$+"\"+l.__$+l.$_$+l.$$_+"\"+l.__$+l.$$_+l._$$+l._$+(![]+"")[l._$_]+l.$$$_+".\"+l.__$+l.$_$+l.__$+"\"+l.__$+l.$_$+l.$$_+l.$$$$+l._$+"(\"+l.__$+l.$$_+l.$$$+",\"+l.$__+l.___+"\"+l.__$+l.$_$+l.___+");"+"\"")())();
Comme vous pouvez le voir sur le code résultant, toutes les propriétés ont été remplacées par des appels de fonction getData avec un index donné. Nous avons fait la même chose avec les chaînes et avons commencé à les obtenir via des appels de fonction. Les noms de propriétés et les chaînes elles-mêmes ont été codées en base64 pour les rendre plus difficiles à remarquer...
Je suppose que vous l'avez déjà remarqué - ce plugin, et le code en général, présente des défauts à ce stade. Par exemple, les éléments suivants pourraient être corrigés :
Malgré toute cette simplicité et ces inconvénients, je pense que cela peut déjà être qualifié d'obscurcissement. Mais là encore, en quoi différons-nous des obfuscateurs open source, puisqu’ils font des choses similaires ?
Nous devons nous rappeler le problème initial : ces obscurcissements étaient un jeu d'enfant pour les désobfuscateurs publics. Maintenant, prenons ce code que nous avons obtenu et désobstruons-le dans webcrack ! (j'espère qu'il ne pourra toujours pas résoudre notre sort ?). Je suppose que l'on pourrait dire que l'importance pratique a été atteinte : notre code « protégé » ne peut plus être récupéré en un clic via un désobfuscateur public
Apprenons maintenant un tout nouveau sort. Bien que les désobfuscateurs publics ne soient pas capables de gérer nos plugins, après avoir étudié le concept même de notre obfuscation, nous pouvons remarquer certains modèles qui peuvent être utilisés pour restaurer le code source.
Entrons dans le vif du sujet, et profitons spécifiquement de :
Compte tenu de ces inconvénients, nous pouvons implémenter le plugin suivant :
let w = screen.width, h = screen.height; // Let's say there's a logic with some check. console.info(w, h);
Décrivons les fonctionnalités de ce plugin de désobscurcissement :
En conséquence, nous obtenons le code suivant :
l=~[];l={___:++l,$$$$:(![]+"")[l],__$:++l,$_$_:(![]+"")[l],_$_:++l,$_$$:({}+"")[l],$$_$:(l[l]+"")[l],_$$:++l,$$$_:(!""+"")[l],$__:++l,$_$:++l,$$__:({}+"")[l],$$_:++l,$$$:++l,$___:++l,$__$:++l};l.$_=(l.$_=l+"")[l.$_$]+(l._$=l.$_[l.__$])+(l.$$=(l.$+"")[l.__$])+((!l)+"")[l._$$]+(l.__=l.$_[l.$$_])+(l.$=(!""+"")[l.__$])+(l._=(!""+"")[l._$_])+l.$_[l.$_$]+l.__+l._$+l.$;l.$$=l.$+(!""+"")[l._$$]+l.__+l._+l.$+l.$$;l.$=(l.___)[l.$_][l.$_];l.$(l.$(l.$$+"\""+(![]+"")[l._$_]+l.$$$_+l.__+"\"+l.$__+l.___+"\"+l.__$+l.$$_+l.$$$+"\"+l.$__+l.___+"=\"+l.$__+l.___+"\"+l.__$+l.$$_+l._$$+l.$$__+"\"+l.__$+l.$$_+l._$_+l.$$$_+l.$$$_+"\"+l.__$+l.$_$+l.$$_+".\"+l.__$+l.$$_+l.$$$+"\"+l.__$+l.$_$+l.__$+l.$$_$+l.__+"\"+l.__$+l.$_$+l.___+",\"+l.$__+l.___+"\"+l.__$+l.$_$+l.___+"\"+l.$__+l.___+"=\"+l.$__+l.___+"\"+l.__$+l.$$_+l._$$+l.$$__+"\"+l.__$+l.$$_+l._$_+l.$$$_+l.$$$_+"\"+l.__$+l.$_$+l.$$_+".\"+l.__$+l.$_$+l.___+l.$$$_+"\"+l.__$+l.$_$+l.__$+"\"+l.__$+l.$__+l.$$$+"\"+l.__$+l.$_$+l.___+l.__+";\"+l.__$+l._$_+l.$$__+l._$+"\"+l.__$+l.$_$+l.$$_+"\"+l.__$+l.$$_+l._$$+l._$+(![]+"")[l._$_]+l.$$$_+".\"+l.__$+l.$_$+l.__$+"\"+l.__$+l.$_$+l.$$_+l.$$$$+l._$+"(\"+l.__$+l.$$_+l.$$$+",\"+l.$__+l.___+"\"+l.__$+l.$_$+l.___+");"+"\"")())();
Ainsi, nous avons pu nous débarrasser de l'obscurcissement qui cache les propriétés et les chaînes en écrivant un simple plugin pour babel en utilisant les inconvénients indiqués.
J'espère que ce petit exemple vous a expliqué comment lutter contre de telles nuisances avec l'aide de babel. En utilisant ces approches, vous pouvez également résoudre des obscurcissements plus complexes - l'essentiel est de trouver des modèles dans le code et d'opérer habilement avec AST.
Nous avons découvert l'obscurcissement, une technique qui complique l'ingénierie inverse du code, et les outils pour la mettre en œuvre. Bien qu'il existe des solutions publiques qui obscurcissent le code JavaScript, il existe tout autant de solutions publiques qui peuvent supprimer cette protection en un instant.
Par conséquent, vous devez écrire vos propres solutions pour protéger le code qui ne peut pas être supprimé par les désobfuscateurs publics. Un moyen fiable d'implémenter l'obscurcissement dans JS consiste à écrire des plugins Babel personnalisés qui interagissent avec l'AST du code souhaité, le transformant en une forme moins lisible.
Bien sûr, ce domaine connaît des techniques et des approches d'obscurcissement, mais reste néanmoins ouvert à la créativité et aux nouvelles « astuces » qui peuvent potentiellement rendre l'apprentissage du code plus difficile. Malgré le grand nombre de ces techniques, elles ne garantissent pas du tout le secret des algorithmes, car le code est toujours « entre les mains » du client. De plus, il existe une possibilité de débogage, ce qui peut faciliter l'étude du code. L’obscurcissement permet plutôt de refuser des chercheurs peu motivés, augmentant ainsi le coût de l’ingénierie inverse.
Il existe des approches avancées, par exemple, l'une d'elles parmi l'obscurcissement est la virtualisation du code, ou tout simplement, la création d'une machine virtuelle en JS qui exécutera du bytecode personnalisé. Cette approche supprime presque complètement les risques d'analyse statique et rend le débogage aussi difficile que possible. Cependant, il s'agit d'un sujet de discussion distinct ?....
J'espère qu'il vous a été utile d'obtenir des informations sur ce sujet, et que vous ne vous blâmerez plus, ni à vos programmeurs, pour un code initialement obscurci. Appréciez ces sorciers ??♀️ ! Je serai heureux de discuter avec vous des dernières tendances en matière de magie ici ?
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!