Comment ces obscurcisseurs javascript génèrent-ils du code de travail réel?
Il y a celui-ci et celui-ci et ils génèrent tous les deux du code complètement illisible, l'un étant plus adorable que l'autre.
Maintenant, je ne suis pas expert en Javascript, mais je ne vois pas comment
゚ω゚ノ= /`m´)ノ ~┻━┻ //*´∇`*/ ['_']; o=(゚ー゚) =_=3; c=(゚Θ゚) =(゚ー゚)-(゚ー゚); (゚Д゚) =(゚Θ゚)= (o^_^o)/ (o^_^o);(゚Д゚)={゚Θ゚: '_' ,゚ω゚ノ : ((゚ω゚ノ==3) +'_') [゚Θ゚] ,゚ー゚ノ :(゚ω゚ノ+ '_')[o^_^o -(゚Θ゚)] ,゚Д゚ノ:((゚ー゚==3) +'_')[゚ー゚] }; (゚Д゚) [゚Θ゚] =((゚ω゚ノ==3) +'_') [c^_^o];(゚Д゚) ['c'] = ((゚Д゚)+'_') [ (゚ー゚)+(゚ー゚)-(゚Θ゚) ];(゚Д゚) ['o'] = ((゚Д゚)+'_') [゚Θ゚];(゚o゚)=(゚Д゚) ['c']+(゚Д゚) ['o']+(゚ω゚ノ +'_')[゚Θ゚]+ ((゚ω゚ノ==3) +'_') [゚ー゚] + ((゚Д゚) +'_') [(゚ー゚)+(゚ー゚)]+ ((゚ー゚==3) +'_') [゚Θ゚]+((゚ー゚==3) +'_') [(゚ー゚) - (゚Θ゚)]+(゚Д゚) ['c']+((゚Д゚)+'_') [(゚ー゚)+(゚ー゚)]+ (゚Д゚) ['o']+((゚ー゚==3) +'_') [゚Θ゚];(゚Д゚) ['_'] =(o^_^o) [゚o゚] [゚o゚];(゚ε゚)=((゚ー゚==3) +'_') [゚Θ゚]+ (゚Д゚) .゚Д゚ノ+((゚Д゚)+'_') [(゚ー゚) + (゚ー゚)]+((゚ー゚==3) +'_') [o^_^o -゚Θ゚]+((゚ー゚==3) +'_') [゚Θ゚]+ (゚ω゚ノ +'_') [゚Θ゚]; (゚ー゚)+=(゚Θ゚); (゚Д゚)[゚ε゚]='\'; (゚Д゚).゚Θ゚ノ=(゚Д゚+ ゚ー゚)[o^_^o -(゚Θ゚)];(o゚ー゚o)=(゚ω゚ノ +'_')[c^_^o];(゚Д゚) [゚o゚]='"';(゚Д゚) ['_'] ( (゚Д゚) ['_'] (゚ε゚+(゚Д゚)[゚o゚]+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚o゚]) (゚Θ゚)) ('_');
Et
$=~[];$={___:++$,$$$$:(![]+"")[$],__$:++$,$_$_:(![]+"")[$],_$_:++$,$_$$:({}+"")[$],$$_$:($[$]+"")[$],_$$:++$,$$$_:(!""+"")[$],$__:++$,$_$:++$,$$__:({}+"")[$],$$_:++$,$$$:++$,$___:++$,$__$:++$};$.$_=($.$_=$+"")[$.$_$]+($._$=$.$_[$.__$])+($.$$=($.$+"")[$.__$])+((!$)+"")[$._$$]+($.__=$.$_[$.$$_])+($.$=(!""+"")[$.__$])+($._=(!""+"")[$._$_])+$.$_[$.$_$]+$.__+$._$+$.$;$.$$=$.$+(!""+"")[$._$$]+$.__+$._+$.$+$.$$;$.$=($.___)[$.$_][$.$_];$.$($.$($.$$+"""+$.$_$_+(![]+"")[$._$_]+$.$$$_+"\"+$.__$+$.$$_+$._$_+$.__+"(\"\"+$.__$+$._$_+$._$$+$.__+$.$_$_+$.$$__+"\"+$.__$+$.$_$+$._$$+"\"+$.__$+$.__$+$.$$$+"\"+$.__$+$.$$_+$.$$_+$.$$$_+"\"+$.__$+$.$$_+$._$_+$.$$$$+(![]+"")[$._$_]+$._$+"\"+$.__$+$.$$_+$.$$$+"\")"+""")())();
Sont des javascript valides réels qui font comme prévu. Sérieusement, les exécuter. Ils sont tous les deux alert("StackOverflow")
. Je pourrais comprendre l'obscurcissement d'une logique ou d'une chaîne, mais il n'y a pas d'instructions de contrôle visibles. Est ce que cet obfuscateur tire un peu de magie le style de la langue qui ne doit pas être nommée ? Je suis heureux avec mon code qui semble heureux aussi, mais je ne comprends complètement pas la magie derrière elle.
J'ai essayé de sélectionner le code source des deux pages, et elles sont aussi déroutantes pour moi que le code qu'elles génèrent.
Comment ça marche?
4 réponses
Comme mon exercice javascript de la journée, une ligne par ligne se décompose. Remarque, j'ai généré le mien avec alert("Hello")
$ = ~[]; // var $ = -1
$ =
{
___ : ++$, // ++(-1) == 0
$$$$:(![]+"")[$], // ![] == false, false + "" == "false", "false"[0] == "f"
__$:++$, // ++(0) == 1
$_$_:(![]+"")[$], // ![] == false, false + "" == "false", "false"[1] == "a"
_$_:++$, // ++(1) == 2
$_$$:({}+"")[$], // {} + "" == "[object Object]", "[object Object]"[2] == "b"
$$_$:($[$]+"")[$], // 2[2] == undefined + "" == "undefined", "undefined"[2] == "d"
_$$:++$, // ++(2) == 3
$$$_:(!""+"")[$], // !"" == true + "" == "true", "true"[3] == "e"
$__:++$, // ++(3) == 4
$_$:++$, // ++(4) == 5
$$__:({}+"")[$], // ({} + "") == [object Object]", "[object Object]"[5] == "c"
$$_:++$, // ++(5) == 6
$$$:++$, // ++(6) == 7
$___:++$, // ++(7) == 8
$__$:++$ // ++(8) == 9
};
$.$_ =
($.$_=$+"")[$.$_$] + // "[object Object]"[5] == "c" + (also $.$_ = "[object Object]")
($._$=$.$_[$.__$]) + // "[object Object]"[1] == "o" + (also $._$ = "o")
($.$$=($.$+"")[$.__$]) + // $.$+"" == "undefined", "undefined"[1] == "n" + (also $.$$ = "n")
((!$)+"")[$._$$] + // !$ == false, false+"" == "false", "false"[3] == "s" +
($.__=$.$_[$.$$_]) + // "[object Object]"[6] == "t" (also $.__ = "t") +
($.$=(!""+"")[$.__$]) + // !"" == true, true + "" == "true", "true"[2] == "r" +(also $.$="r")
($._=(!""+"")[$._$_]) + // !"" == true, true + "" == "true", "true"[3] == "u" +(also $._="u")
$.$_[$.$_$] + // "[object Object]"[5] == "c" +
$.__ + // "t" +
$._$ + // "o" +
$.$; // "r"
// $.$_ = "constructor"
$.$$ =
$.$ + // "r" +
(!""+"")[$._$$] + // "true"[3] == "e" +
$.__ + // "t" +
$._ + // "u" +
$.$ + // "r" +
$.$$; // "n"
// $.$$ = "return"
$.$ = ($.___)[$.$_][$.$_]; // (0)["constructor"]["constructor"]
// $.$ = Function
// This is the part that changes when you change the input string.
$.$( // Function(
$.$( // Function (
$.$$ + // "return"+
"\""+ // '"' +
$.$_$_ + // "a" +
(![]+"")[$._$_]+ // "l" +
$.$$$_+ // "e" +
"\\"+ // "\" +
$.__$+ // "1" +
$.$$_+ // "6" +
$._$_+ // "2" + (note '\162' = 'r')
$.__+ // "t" +
"(\\\"\\"+ // '(\"\' +
$.__$+ // 1 +
$.__$+ // 1 +
$.___+ // 0 + (note '\110' = 'H')
$.$$$_+ // e +
(![]+"")[$._$_]+ // "false"[2] == "l", "l" +
(![]+"")[$._$_]+ // "false"[2] == "l", "l" +
$._$+ // "o" +
"\\\")"+ // '\")' +
"\"" // '"''
)() // invoke
)(); // invoke
Am not I am est à peu près sur place, il crée une chaîne et l'invoque ensuite.
Edit-et je n'ai pas le temps de décoder l'autre version, mais j'imagine que cela fait quelque chose de similaire, mais avec des caractères non latins.
Quel plaisir! Voici mon aller à elle. Fondamentalement, ce qui se passe ici, c'est qu'un tas de nombres et de chaînes sont assignés aux variables. Ces variables sont concaténées pour former une chaîne codée. Cette chaîne codée est décodée pour former une chaîne de code JavaScript. Ce code est défini comme le corps d'une fonction, qui est ensuite exécuté.
Prenons ligne par ligne:
Ligne 1:
゚ω゚ノ = /`m´)ノ ~┻━┻ //*´∇`*/['_'];
゚ω゚ノ
- une variable globale/`m´)ノ ~┻━┻ /
- régulièrement expression/*´∇`*/
- un commentaire de plusieurs lignes['_']
- obtenir la propriété _
de l'expression régulière.
Comme une expression rationnelle n'a pas de propriété _
, la variable ゚ω゚ノ
contient la valeur undefined
.
Ligne 2:
o = (゚ー゚) = _ = 3;
Définir les variables o
, ゚ー゚
, et _
, et l'ensemble de chacun de leurs valeurs dans 3
.
Ligne 3:
c = (゚Θ゚) = (゚ー゚) - (゚ー゚);
Définir les variables c
et ゚Θ゚
et définissez les valeurs 0
. (゚ー゚
est 3
, donc (゚ー゚) - (゚ー゚)
est le même que ゚ー゚ - ゚ー゚
est le même que 3 - 3
. Maintenant c
et ゚Θ゚
contiennent tous les deux 1
;
Ligne 4:
(゚Д゚) = (゚Θ゚) = (o ^ _ ^ o) / (o ^ _ ^ o);
Définissez la variable ゚Д゚
et redéfinissez la variable ゚Θ゚
. {[46] } est l'opérateur XOR bit à bit et o
et _
sont tous les deux 3
.o ^ _ ^ o
est le même que 3 ^ 3 ^ 3
.3 ^ 3
est 0
, 3 ^ 0
est 3
.
Alors 3 / 3
est 1
.゚Д゚
et ゚Θ゚
, maintenant contenir 1
.
Ligne 5:
(゚Д゚) = { ゚Θ゚: '_', ゚ω゚ノ: ((゚ω゚ノ == 3) + '_')[゚Θ゚], ゚ー゚ノ: (゚ω゚ノ + '_')[o ^ _ ^ o - (゚Θ゚)], ゚Д゚ノ: ((゚ー゚ == 3) + '_')[゚ー゚] };
Avec sauts de ligne et indentation:
(゚Д゚) = {
゚Θ゚: '_',
゚ω゚ノ: ((゚ω゚ノ == 3) + '_')[゚Θ゚],
゚ー゚ノ: (゚ω゚ノ + '_')[o ^ _ ^ o - (゚Θ゚)],
゚Д゚ノ: ((゚ー゚ == 3) + '_')[゚ー゚]
};
Redéfinir ゚Д゚
comme un objet littéral, avec des propriétés ゚Θ゚
, ゚ω゚ノ
, ゚ー゚ノ
, et ゚Д゚ノ
.゚Д゚.゚Θ゚
est "_".゚Д゚.゚ω゚ノ
est ((undefined == 3) + "_")[1]
, qui est "false_"[1]
, qui est "a"
.゚Д゚.゚ー゚ノ
est (undefined + "_")[3 ^ 3 ^ 3 - 1]
, qui est "undefined_"[2]
, qui est "d"
.゚Д゚.゚Д゚ノ
est ((3 == 3) + "_")[3]
, qui est "true_"[3]
, qui est "u"
.
Ligne 6:
(゚Д゚)[゚Θ゚] = ((゚ω゚ノ == 3) + '_')[c ^ _ ^ o];
Est le même que:
゚Д゚.゚Θ゚ = ((undefined == 3) + "_")[1 ^ 3 ^ 3];
Qui est le même que:
゚Д゚.゚Θ゚ = "false_"[1];
Donc ゚Д゚.゚Θ゚
est "a"
.
Lignes 7 - 16:
Et ainsi il continue, attribuant des chaînes et des nombres aux variables et aux propriétés de l'objet. Jusqu'à la dernière ligne:
Ligne 17:
(゚Д゚)['_']((゚Д゚)['_'](゚ε゚ + (゚Д゚)[゚o゚] + (゚Д゚)[゚ε゚] + (゚Θ゚) + (゚ー゚) + (゚Θ゚) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((゚ー゚) + (゚Θ゚)) + (゚ー゚) + (゚Д゚)[゚ε゚] + (゚Θ゚) + (゚ー゚) + ((゚ー゚) + (゚Θ゚)) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((o ^ _ ^ o) + (o ^ _ ^ o)) + ((o ^ _ ^ o) - (゚Θ゚)) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((o ^ _ ^ o) + (o ^ _ ^ o)) + (゚ー゚) + (゚Д゚)[゚ε゚] + ((゚ー゚) + (゚Θ゚)) + (c ^ _ ^ o) + (゚Д゚)[゚ε゚] + (゚ー゚) + ((o ^ _ ^ o) - (゚Θ゚)) + (゚Д゚)[゚ε゚] + (゚Θ゚) + (゚Θ゚) + (c ^ _ ^ o) + (゚Д゚)[゚ε゚] + (゚Θ゚) + (゚ー゚) + ((゚ー゚) + (゚Θ゚)) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((゚ー゚) + (゚Θ゚)) + (゚ー゚) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((゚ー゚) + (゚Θ゚)) + (゚ー゚) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((゚ー゚) + (゚Θ゚)) + ((゚ー゚) + (o ^ _ ^ o)) + (゚Д゚)[゚ε゚] + ((゚ー゚) + (゚Θ゚)) + (゚ー゚) + (゚Д゚)[゚ε゚] + (゚ー゚) + (c ^ _ ^ o) + (゚Д゚)[゚ε゚] + (゚Θ゚) + (゚Θ゚) + ((o ^ _ ^ o) - (゚Θ゚)) + (゚Д゚)[゚ε゚] + (゚Θ゚) + (゚ー゚) + (゚Θ゚) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((o ^ _ ^ o) + (o ^ _ ^ o)) + ((o ^ _ ^ o) + (o ^ _ ^ o)) + (゚Д゚)[゚ε゚] + (゚Θ゚) + (゚ー゚) + (゚Θ゚) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((o ^ _ ^ o) - (゚Θ゚)) + (o ^ _ ^ o) + (゚Д゚)[゚ε゚] + (゚Θ゚) + (゚ー゚) + (o ^ _ ^ o) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((o ^ _ ^ o) + (o ^ _ ^ o)) + ((o ^ _ ^ o) - (゚Θ゚)) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((゚ー゚) + (゚Θ゚)) + (゚Θ゚) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((o ^ _ ^ o) + (o ^ _ ^ o)) + (c ^ _ ^ o) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((o ^ _ ^ o) + (o ^ _ ^ o)) + (゚ー゚) + (゚Д゚)[゚ε゚] + (゚ー゚) + ((o ^ _ ^ o) - (゚Θ゚)) + (゚Д゚)[゚ε゚] + ((゚ー゚) + (゚Θ゚)) + (゚Θ゚) + (゚Д゚)[゚o゚])(゚Θ゚))('_');
À ce moment-là, nous avons les variables suivantes:
゚ω゚ノ // undefined
o // 3
゚ー゚ // 4
_ // 3
c // 0
゚Θ゚ // 1
゚Д゚ /* {
"1": "f",
゚Θ゚: "_",
゚ω゚ノ: "a",
゚ー゚ノ: "d",
゚Д゚ノ: "e",
c: "c",
o: "o",
return: "\\",
゚Θ゚ノ: "b",
constructor: "\"",
_: Function
} */
゚o゚ // "constructor"
゚ε゚ // "return"
o゚ー゚o // "u"
Cette ligne est principalement une grosse concaténation de chaîne. Nous pouvons le rendrelégèrement plus lisible en supprimant les parenthèses inutiles et en ajoutant des sauts de ligne:
゚Д゚['_'](
゚Д゚['_'](
゚ε゚ +
゚Д゚[゚o゚] +
゚Д゚[゚ε゚] +
゚Θ゚ +
゚ー゚ +
゚Θ゚ +
゚Д゚[゚ε゚] +
゚Θ゚ +
(゚ー゚ + ゚Θ゚) +
゚ー゚ +
゚Д゚[゚ε゚] +
゚Θ゚ +
゚ー゚ +
(゚ー゚ + ゚Θ゚) +
゚Д゚[゚ε゚] +
゚Θ゚ +
((o ^ _ ^ o) + (o ^ _ ^ o)) +
((o ^ _ ^ o) - ゚Θ゚) +
゚Д゚[゚ε゚] +
゚Θ゚ +
((o ^ _ ^ o) + (o ^ _ ^ o)) +
゚ー゚ +
゚Д゚[゚ε゚] +
(゚ー゚ + ゚Θ゚) +
(c ^ _ ^ o) +
゚Д゚[゚ε゚] +
゚ー゚ +
((o ^ _ ^ o) - ゚Θ゚) +
゚Д゚[゚ε゚] +
゚Θ゚ +
゚Θ゚ +
(c ^ _ ^ o) +
゚Д゚[゚ε゚] +
゚Θ゚ +
゚ー゚ +
(゚ー゚ + ゚Θ゚) +
゚Д゚[゚ε゚] +
゚Θ゚ +
(゚ー゚ + ゚Θ゚) +
゚ー゚ +
゚Д゚[゚ε゚] +
゚Θ゚ +
(゚ー゚ + ゚Θ゚) +
゚ー゚ +
゚Д゚[゚ε゚] +
゚Θ゚ +
(゚ー゚ + ゚Θ゚) +
(゚ー゚ + (o ^ _ ^ o)) +
゚Д゚[゚ε゚] +
(゚ー゚ + ゚Θ゚) +
゚ー゚ +
゚Д゚[゚ε゚] +
゚ー゚ +
(c ^ _ ^ o) +
゚Д゚[゚ε゚] +
゚Θ゚ +
゚Θ゚ +
((o ^ _ ^ o) - ゚Θ゚) +
゚Д゚[゚ε゚] +
゚Θ゚ +
゚ー゚ +
゚Θ゚ +
゚Д゚[゚ε゚] +
゚Θ゚ +
((o ^ _ ^ o) + (o ^ _ ^ o)) +
((o ^ _ ^ o) + (o ^ _ ^ o)) +
゚Д゚[゚ε゚] +
゚Θ゚ +
゚ー゚ +
゚Θ゚ +
゚Д゚[゚ε゚] +
゚Θ゚ +
((o ^ _ ^ o) - ゚Θ゚) +
(o ^ _ ^ o) +
゚Д゚[゚ε゚] +
゚Θ゚ +
゚ー゚ +
(o ^ _ ^ o) +
゚Д゚[゚ε゚] +
゚Θ゚ +
((o ^ _ ^ o) + (o ^ _ ^ o)) +
((o ^ _ ^ o) - ゚Θ゚) +
゚Д゚[゚ε゚] +
゚Θ゚ +
(゚ー゚ + ゚Θ゚) +
゚Θ゚ +
゚Д゚[゚ε゚] +
゚Θ゚ +
((o ^ _ ^ o) + (o ^ _ ^ o)) +
(c ^ _ ^ o) +
゚Д゚[゚ε゚] +
゚Θ゚ +
((o ^ _ ^ o) + (o ^ _ ^ o)) +
゚ー゚ +
゚Д゚[゚ε゚] +
゚ー゚ +
((o ^ _ ^ o) - ゚Θ゚) +
゚Д゚[゚ε゚] +
(゚ー゚ + ゚Θ゚) +
゚Θ゚ +
゚Д゚[゚o゚]
)(゚Θ゚)
)("_");
La valeur de cette chaîne concaténée est:
return"\141\154\145\162\164\50\42\110\145\154\154\157\54\40\112\141\166\141\123\143\162\151\160\164\42\51"
Donc, en remplaçant toutes les variables par des littéraux, nous nous retrouvons avec le JavaScript suivant qui est exécuté sur cette dernière ligne:
Function(Function("return\"\\141\\154\\145\\162\\164\\50\\42\\110\\145\\154\\154\\157\\54\\40\\112\\141\\166\\141\\123\\143\\162\\151\\160\\164\\42\\51\"")(1))("_")
En cassant cette ligne, au milieu, nous voyons que la chaîne concaténée est passée à un constructeur Function
, faisant de la chaîne le corps de la fonction:
Function("return\"\\141\\154\\145\\162\\164\\50\\42\\110\\145\\154\\154\\157\\54\\40\\112\\141\\166\\141\\123\\143\\162\\151\\160\\164\\42\\51\"")
Donc, cette chaîne est évaluée comme JavaScript, et le constructeur Function
renvoie cette fonction:
function () {
return"\141\154\145\162\164\50\42\110\145\154\154\157\54\40\112\141\166\141\123\143\162\151\160\164\42\51";
}
Cette fonction est immédiatement exécuté:
Function("return\"\\141\\154\\145\\...\\51\"")(1)
Et renvoie la chaîne:
alert("Hello, JavaScript")
Hé, ça ressemble à du JavaScript! Mais il n'est pas encore de. C'est juste une chaîne de caractères. Mais cette chaîne est passée à un autre constructeur Function
, nous donnant une fonction qui exécute la chaîne en JavaScript:
Function("alert(\"Hello, JavaScript\")")
C'est la même chose que:
function () {
alert("Hello, JavaScript");
}
Cette fonction est immédiatement exécutée:
Function("alert(\"Hello, JavaScript\")")("_")
Et notre code non masqué est finalement appelé.
Tapez $
dans la console (après avoir exécuté le code) et développez l'objet. Vous pouvez ensuite plus facilement les analyser.
Ils saisissent suffisamment de mots / caractères en utilisant des moyens sournois, et les référencent dans l'objet$, puis les utilisent pour construire le programme et eval
ing probablement dans un appel Function(...)()
.
Il devrait donc se résumer à...
Function('alert("StackOverflow")')();
...ou quelque chose de similaire.
Commence à le dérouler, ...
$=~[]; // -1
$={
0:++$, // 0
f:(![]+"")[$], // "f", (![]+"") is "false", and [$] gives index 0, or "f"
1:++$, // 1
a:(![]+"")[$], // "a", (![]+"") is "false", and [$] gives index 1, or "a"
2:++$, // 2
b:({}+"")[$], // "b", ({}+"") is "[object Object]", and [$] gives index 2, or "b"
d:($[$]+"")[$],// "d", ($[$]+"") is "undefined", and [$] gives index 2, or "d"
3:++$, // 3
e:(!""+"")[$], // "e", (!""+"") is "true", and [$] gives index 3, or "e"
4:++$, // 4
5:++$, // 5
c:({}+"")[$], // "c", ({}+"") is "[object Object]", and [$] gives index 5, or "c"
6:++$, // 6
7:++$, // 7
8:++$, // 8
9:++$ // 9
};
$.constructor=($.constructor=$+"")[$[5]]+($.o=$.constructor[$[1]])+($.return=($.$+"")[$[1]])+((!$)+"")[$[3]]+($.t=$.constructor[$[6]])+($.$=(!""+"")[$[1]])+($.u=(!""+"")[$[2]])+$.constructor[$[5]]+$.t+$.o+$.$;
$.return=$.$+(!""+"")[$[3]]+$.t+$.u+$.$+$.return;
$.$=($[0])[$.constructor][$.constructor];
$.$($.$($.return+"\""+$.a+(![]+"")[$[2]]+$.e+"\\"+$[1]+$[6]+$[2]+$.t+"(\\\"\\"+$[1]+$[2]+$[3]+$.t+$.a+$.c+"\\"+$[1]+$[5]+$[3]+"\\"+$[1]+$[1]+$[7]+"\\"+$[1]+$[6]+$[6]+$.e+"\\"+$[1]+$[6]+$[2]+$.f+(![]+"")[$[2]]+$.o+"\\"+$[1]+$[6]+$[7]+"\\\")"+"\"")())();
Alors...
$.constructor=($.constructor=$+"")[5]+($.o=$.constructor[1])+($.return=($.$+"")[1])+((!$)+"")[3]+($.t=$.constructor[6])+($.$=(!""+"")[1])+($.u=(!""+"")[2])+$.constructor[5]+$.t+$.o+$.$;
$.return=$.$+(!""+"")[3]+$.t+$.u+$.$+$.return;
$.$=(0)[$.constructor][$.constructor];
$.$($.$($.return+"\""+$.a+(![]+"")[2]+$.e+"\\"+$[1]+$[6]+$[2]+$.t+"(\\\"\\"+$[1]+$[2]+$[3]+$.t+$.a+$.c+"\\"+$[1]+$[5]+$[3]+"\\"+$[1]+$[1]+$[7]+"\\"+$[1]+$[6]+$[6]+$.e+"\\"+$[1]+$[6]+$[2]+$.f+(![]+"")[2]+$.o+"\\"+$[1]+$[6]+$[7]+"\\\")"+"\"")())();
...eh, perdu de son intérêt.
Puisque toutes les autres réponses ne sont que des analyses du code que vous avez donné, je vais développer comment vous pouvez les générer par vous-même (sans outils). Je crois que cela vous donnera un meilleur aperçu de la façon dont il fonctionne.
La Plupart de ces obscurcissements sont basés sur quelques fonctionnalités / principes de JavaScript. La première est que le nom de la variable pouvez utiliser Unicode Lettre (Lu, Ll, Lt, Lm, Lo, Nl) et Nombre Unicode ( Nd ). Dans le premier exemple que vous avez donné, le caractère peut ressembler à des symboles, mais il s'agit d'une lettre Unicode ou D'un numéro Unicode.
Le second est que l'ajout d'une chaîne vide à N'importe quoi en JavaScript la convertira en une chaîne. Si vous utilisez également le fait que les chaînes sont une structure de type tableau en JavaScript, vous pouvez facilement faire des choses comme: (false+"")[0]
, qui peut également être écrit a (!1+"")[0]
. À partir de ce point, vous pouvez composer votre propre lettre de chaîne en lettre.
Le troisième est que chaque propriété d'objet est accessible avec la notation []
. Par exemple: window["alert"]("test")
est identique à window.alert("test")
. Si vous mélangez cela avec le paragraphe précédent, je pense que vous pouvez facilement voir où il peut aller.
La seule chose qui nous manque pour commencer, c'est soit une référence à window
ou Function
. Les autres réponses, vous fournissent déjà un moyen d'accéder à Function
qui peut être utilisé comme eval
. Pour obtenir window
difficile, le plus simple est de fuite à travers Array.concat
ce façon :
t= [].concat;
a = t()[0]; // "a" now contains window
Une Fois que vous avez window
, vous pouvez utiliser window["eval"]
, ou appeler directement window["alert"]
.
C'est tout pour la base de la façon dont vous faites réellement ce genre d'obscurcissement. Le reste est juste variation des points précédents. Si vous voulez des informations supplémentaires, j'ai fait quelques articles de blog à ce sujet, vous pouvez les trouver ici: http://holyvier.blogspot.com/2011/10/javascript-obfuscation-introduction.html