Maison >interface Web >js tutoriel >Introduction détaillée à l'obfuscation et à la désobfuscation Javascript (avec code)
Cet article vous apporte une introduction détaillée à l'obfuscation et à la désobfuscation Javascript (avec code). Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer.
Comme le cryptage et le décryptage logiciel, l'obfuscation et la désobfuscation JavaScript appartiennent à la même catégorie. Le Tao mesure un pied de haut et le diable mesure un pied de haut. Il n’y a ni noir éternel ni blanc éternel. Tout est déterminé par le marché des capitaux, et le concept des problèmes que l'on peut résoudre pour les gens est désormais populaire. Alors, combien d’acteurs le marché peut-il accueillir pour résoudre ce problème ? Il n'y a pas de secrets pour JS.
En fait, je ne suis pas d'accord avec l'obscurcissement du hachage en JavaScript. Premièrement, cela ralentit l'exécution, et deuxièmement, c'est volumineux. Le frontal du code JS est disponible et est intrinsèquement « open source » et peut être consulté sous Chrome devTools. L'obscurcissement non compressible JS viole complètement les principes d'optimisation frontale.
Les outils d'obscurcissement JS actuellement consultables sur Internet ne sont rien de plus que les suivants :
l'obscurcissement eval est également le premier cryptage d'obscurcissement apparu dans JS. On dit qu'il a été craqué sur le. premier jour. Veuillez modifier le code, il peut être piraté avec une seule alerte. Cette méthode perd son sens à partir du jour de la naissance. En fait, le cryptage JS (obscurcissement) est relatif à la lisibilité. En fait, ce qui est vraiment significatif, c'est le type d'obfuscation compressé qui peut réduire le poids et la lisibilité.
Cependant, il ne peut être exclu que certains codes sources commerciaux utilisent un type de hachage pour obscurcir le code source, comme le cryptage JSA utilisé par miniui et l'obfuscateur javascript utilisé par fundebug.
Ce qui suit utilise du code pour illustrer la différence entre le cryptage JSA et javascript-obfuscator :
Code à obscurcir :
function logG(message) { console.log('\x1b[32m%s\x1b[0m', message); } function logR(message) { console.log('\x1b[41m%s\x1b[0m', message); } logG('logR'); logR('logG');
Code généré par l'obscurcissement du cryptage JSA
function o00($){console.log("\x1b[32m%s\x1b[0m",$)}function o01($){console.log("\x1b[41m%s\x1b[0m",$)}o00("logR");o01("logG")
Puis embellir à nouveau :
function o00($) { console.log("\x1b[32m%s\x1b[0m", $) } function o01($) { console.log("\x1b[41m%s\x1b[0m", $) } o00("logR"); o01("logG")
Vous pouvez constater qu'en fait, aucune modification n'a été apportée, seules quelques substitutions de variables ont été effectuées. C'est relativement facile à restaurer. Je ne l’utiliserai pas comme représentant ici, et personne ne l’utilise.
Le code généré après avoir été obscurci par javascript-obfuscator
var _0xd6ac=['[41m%s[0m','logG','log'];(function(_0x203a66,_0x6dd4f4){var _0x3c5c81=function(_0x4f427c){while(--_0x4f427c){_0x203a66['push'](_0x203a66['shift']());}};_0x3c5c81(++_0x6dd4f4);}(_0xd6ac,0x6e));var _0x5b26=function(_0x2d8f05,_0x4b81bb){_0x2d8f05=_0x2d8f05-0x0;var _0x4d74cb=_0xd6ac[_0x2d8f05];return _0x4d74cb;};function logG(_0x4f1daa){console[_0x5b26('0x0')]('[32m%s[0m',_0x4f1daa);}function logR(_0x38b325){console[_0x5b26('0x0')](_0x5b26('0x1'),_0x38b325);}logG('logR');logR(_0x5b26('0x2'));
Embellisseur à nouveau :
var _0xd6ac = ['[41m%s[0m', 'logG', 'log']; (function(_0x203a66, _0x6dd4f4) { var _0x3c5c81 = function(_0x4f427c) { while (--_0x4f427c) { _0x203a66['push'](_0x203a66['shift']()); } }; _0x3c5c81(++_0x6dd4f4); }(_0xd6ac, 0x6e)); var _0x5b26 = function(_0x2d8f05, _0x4b81bb) { _0x2d8f05 = _0x2d8f05 - 0x0; var _0x4d74cb = _0xd6ac[_0x2d8f05]; return _0x4d74cb; }; function logG(_0x4f1daa) { console[_0x5b26('0x0')]('[32m%s[0m', _0x4f1daa); } function logR(_0x38b325) { console[_0x5b26('0x0')](_0x5b26('0x1'), _0x38b325); } logG('logR'); logR(_0x5b26('0x2'));
C'est beaucoup plus compliqué, mais après analyse vous constaterez que , en fait Avec un dictionnaire supplémentaire, toutes les variables de méthode peuvent exister dans le dictionnaire Lors de l'appel, appelez d'abord le dictionnaire pour restaurer la variable de nom de méthode, puis exécutez-la.
En fait, les entrées sont toutes des règles de variables.
Fonction de dictionnaire :
var _0xd6ac = ['[41m%s[0m', 'logG', 'log']; (function(_0x203a66, _0x6dd4f4) { var _0x3c5c81 = function(_0x4f427c) { while (--_0x4f427c) { _0x203a66['push'](_0x203a66['shift']()); } }; _0x3c5c81(++_0x6dd4f4); }(_0xd6ac, 0x6e)); var _0x5b26 = function(_0x2d8f05, _0x4b81bb) { _0x2d8f05 = _0x2d8f05 - 0x0; var _0x4d74cb = _0xd6ac[_0x2d8f05]; return _0x4d74cb; };
Grâce aux résultats ci-dessus, nous pouvons classer la confusion JS en trois catégories, à savoir le type d'évaluation, le type de hachage et le type de compression. Le type de compression est un outil couramment utilisé pour l'optimisation des performances frontales, représenté par uglify.
Outils d'optimisation de la compression frontale couramment utilisés :
JavaScript :
CSS :
HTML :
Du point de vue du flux d'outils (workflow), qu'il s'agisse de webpack ou de gulp, l'outil JavaScript le plus populaire à l'heure actuelle est uglify.
L'outil de désobfuscation correspondant :
La stratégie de désobfuscation est en fait générée en fonction de L'écriture régulière de code n'est rien d'autre que l'observation de l'analyse des fonctionnalités, puis l'observation de l'analyse des fonctionnalités et la réalisation d'ajustements constants. Ce sont tous des chiffres faciles à voir.
Il n'y a aucune difficulté, tout ce dont vous avez besoin c'est de patience. Par exemple, l'outil de désobscurcissement correspondant à javascript-obfuscator peut
être décomposé en un problème à facteur N :
Comment interroger la portée d'une fonction ?
Types possibles pour la substitution de variables de pré-exécution ?
...
Par exemple :
var _0xd6ac = ['[41m%s[0m', 'logG', 'log']; (function(_0x203a66, _0x6dd4f4) { var _0x3c5c81 = function(_0x4f427c) { while (--_0x4f427c) { _0x203a66['push'](_0x203a66['shift']()); } }; _0x3c5c81(++_0x6dd4f4); }(_0xd6ac, 0x6e)); var _0x5b26 = function(_0x2d8f05, _0x4b81bb) { _0x2d8f05 = _0x2d8f05 - 0x0; var _0x4d74cb = _0xd6ac[_0x2d8f05]; return _0x4d74cb; }; function logG(_0x4f1daa) { console[_0x5b26('0x0')]('[32m%s[0m', _0x4f1daa); } function logR(_0x38b325) { console[_0x5b26('0x0')](_0x5b26('0x1'), _0x38b325); } logG('logR'); logR(_0x5b26('0x2'));
Pour restaurer vers
function logG(message) { console.log('\x1b[32m%s\x1b[0m', message); } function logR(message) { console.log('\x1b[41m%s\x1b[0m', message); } logG('logR'); logR('logG');
la première étape consiste à connaître la fonction dictionnaire, puis à exécuter la fonction dictionnaire _0x5b26('0x0')
Restaurez-le sur log
.
Il sera alors plus facile d'écrire du code.
Par exemple, https://github.com/jscck/crac...
Comment reconstruire le code après restauration, alors vous devez également savoir quel outil webpack a été utilisé pour empaqueter le code avant le générer ?
Par exemple, divers en-têtes et queues d'encapsulation de webpack
https://webpack.js.org/config...
(function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if(typeof define === 'function' && define.amd) define([], factory); else if(typeof exports === 'object') exports['MyLibrary'] = factory(); else root['MyLibrary'] = factory(); })(typeof self !== 'undefined' ? self : this, function() { return _entry_return_; });
Si vous allez plus loin, cela peut être interpréteur de syntaxe JS impliqué, arbre de syntaxe abstraite AST
Implique actuellement l'interpréteur de syntaxe JS, les fonctions de l'arbre de syntaxe abstraite AST sont les suivantes :
prepack, esprima, babel
ou vous pouvez lire "Modèles d'implémentation du langage de programmation", impliquant antlr4.
Bien sûr, vous pouvez également utiliser des outils tels qu'Esprima pour désobscurcir, mais c'est juste un peu plus de travail et si cela en vaut la peine.
Pour l'avenir, l'orientation du cryptage du code source commercial JS pourrait être le webassembly. Commencez par le compiler dans wasm côté serveur, et le code source pourra être véritablement fermé.
Là où il y a des gens, il y a une route, et là où il y a de la confusion, il y a de la désobscurcissement. Les outils de désobscurcissement actuels pour la programmation d'apprentissage automatique sont également très bons, comme
Machine Learning pour les produits de programmation
nice2predict, jsnice...
Voir https://www.sri.inf.ethz.ch/r...
Pourquoi parler également de l'arbre de syntaxe abstraite AST, car vous pouvez saisir->
Par exemple, si vous convertissez jsx en syntaxe de modèle de mini-programme, vous pouvez utiliser la syntaxe de réaction pour écrire des mini-programmes, tels que Taro.
mpvue, wepy, postcss... Ce sont tous des outils de construction et de conversion via AST es6 -> es5, babel utilise tous AST.
Le processus général de l'arbre de syntaxe abstraite AST :
L'entrée génère l'arbre AST
puis effectue la conversion correspondante via l'assertion de type AST
[Recommandations associées : Tutoriel vidéo JavaScript】
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!