93 votes

Comment fonctionne cette obfuscation JavaScript ?

Comment fonctionne le code JavaScript suivant le travail?

Je comprends qu'il est minimisé code, mais j'ai essayé de d'obscurcir un peu, mais je ne peux pas obtenir un concept clair de la façon dont il atteint cet effet. Je peux voir que c'est à l'aide de Cordes pour l'itération d'une certaine sorte, l'utilisation de l'objet Date, étrange manipulation de chaîne, les fonctions Mathématiques, puis le code imprime lui-même.

Comment peut-il le même effet être réécrite avec un exemple minimal?

eval(z='p="<"+"pre>"/* ,.oq#+     ,._, */;for(y in n="zw24l6k\
4e3t4jnt4qj24xh2 x/* =<,m#F^    A W###q. */42kty24wrt413n243n\
9h243pdxt41csb yz/* #K       q##H######Am */43iyb6k43pk7243nm\
r24".split(4)){/* dP      cpq#q##########b, */for(a in t=pars\
eInt(n[y],36)+/*         p##@###YG=[#######y */(e=x=r=[]))for\
(r=!r,i=0;t[a/*         d#qg `*PWo##q#######D */]>i;i+=.05)wi\
th(Math)x-= /*        aem1k.com Q###KWR#### W[ */.05,0>cos(o=\
new Date/1e3/*      .Q#########Md#.###OP  A@ , */+x/PI)&&(e[~\
~(32*sin(o)*/* ,    (W#####Xx######.P^     T % */sin(.5+y/7))\
+60] =-~ r);/* #y    `^TqW####P###BP           */for(x=0;122>\
x;)p+="   *#"/* b.        OQ####x#K           */[e[x++]+e[x++\
]]||(S=("eval"/* l         `X#####D  ,       */+"(z=\'"+z.spl\
it(B = "\\\\")./*           G####B" #       */join(B+B).split\
(Q="\'").join(B+Q/*          VQBP`        */)+Q+")//m1k")[x/2\
+61*y-1]).fontcolor/*         TP         */(/\\w/.test(S)&&"#\
03B");document.body.innerHTML=p+=B+"\\n"}setTimeout(z)')//

JSFiddle

69voto

apsillers Points 29372

Avant-propos: j'ai embelli et annoté le code intensivement à la http://jsfiddle.net/WZXYr/2/

Envisager la couche la plus externe:

eval(z = '...');

Une chaîne de code est stocké dans la variable z. L'opérateur d'affectation renvoie la valeur affectée, de sorte que la chaîne de code aussi est passé comme un argument en eval.

La chaîne de code z s'exécute à l'intérieur d' eval. Le code est très obtus, même lorsque nettoyé, mais il me semble:

  1. Analyser une chaîne de base-36 numéros, délimitées par le caractère 4.
  2. Remplir une carte de valeurs, en utilisant les variables globales e, x, et y de détenir la carte de l'état. Carte de l'état est, en partie, fonction de la seconde sur l'horloge murale (new Date / 1e3).
  3. En utilisant les valeurs de la carte, le code génère une chaîne de sortie, p
    • le code utilise p += " *#"[index] de décider si l'utilisation d'un espace, astérisque, ou marque de hachage, où index est en fait e[x++] + e[x++] (comme il est dit ci-dessus, e et x sont responsables de carte de l'état)
    • si l'index est plus grande que la longueur d' " *#", il n'y a de secours code qui remplit la sortie p avec des personnages de la z. Intérieure des personnages sont peuplées de personnages d'animation, tandis que l'extérieur personnages sont tirés à partir de z.

À la fin du code, il est un appel à l' setTimeout(z), de manière asynchrone évalue la chaîne de code z. Cette répétez l'invocation de l' z permet le code de la boucle.

Exemple Simple:

Voici une super version simple (http://jsfiddle.net/5QXn8/):

eval(z='p="<"+"pre>";for(i=0;i<172;++i)if(i > 62 && i < 67)p+="!---"[~~(new Date/1e2 + i)%4];else p += ("eval(z=\'" + z + "\')")[i];document.body.innerHTML = p;setTimeout(z)')
  1. L' for boucle ajoute chaque caractère de la chaîne de sortie p (la chaîne est 172 caractères):

    for(i=0;i<172;++i)
    
  2. L'intérieur conditionnelle décide si nous sommes sur un personnage entre la position de 62 à 67 ans, qui sont les personnages animés:

    if(i > 62 && i < 67)
    
  3. Si nous sommes, ensuite, imprimez !---, déplacée sur le dixième de la deuxième horloge murale valeur. Cela donne l'effet d'animation.

    p+="!---"[~~(new Date/1e2 + i)%4]
    

    (Toutes les ignominies autour de new Date est vraiment juste là pour transformer une valeur de date dans un nombre entre 0 et 3.)

  4. Sinon, si nous ne sommes pas sur un personnage de dessin animé, puis imprimer l'index-i caractère de la chaîne définie par

    "eval(z='" + z + "')"
    

    Qui est, la chaîne de code z entouré par eval(' et ').

  5. Enfin, la chaîne de sortie et d'utiliser setTimeout de la queue de l'autre l'exécution d' z:

    document.body.innerHTML = p;setTimeout(z)
    

Notez que ma dernière sortie n'est pas tout à fait à droite -- je n'ai pas comptabilisé les barres obliques inverses vers la fin, mais il devrait quand même vous donner une assez bonne idée de comment fonctionne la technique en général.

36voto

aemkei Points 4602

Voici la source annotée. PS : je suis l’auteur  ;)

21voto

Bergi Points 104242

Voici un autre manuellement deobfuscated version, le déplacement de l'initialisation de l'expression dans les propres déclarations:

z='p="<"+"pre>"/* ,.oq#+     ,._, */;for(y in n="zw24l6k\
4e3t4jnt4qj24xh2 x/* =<,m#F^    A W###q. */42kty24wrt413n243n\
9h243pdxt41csb yz/* #K       q##H######Am */43iyb6k43pk7243nm\
r24".split(4)){/* dP      cpq#q##########b, */for(a in t=pars\
eInt(n[y],36)+/*         p##@###YG=[#######y */(e=x=r=[]))for\
(r=!r,i=0;t[a/*         d#qg `*PWo##q#######D */]>i;i+=.05)wi\
th(Math)x-= /*        aem1k.com Q###KWR#### W[ */.05,0>cos(o=\
new Date/1e3/*      .Q#########Md#.###OP  A@ , */+x/PI)&&(e[~\
~(32*sin(o)*/* ,    (W#####Xx######.P^     T % */sin(.5+y/7))\
+60] =-~ r);/* #y    `^TqW####P###BP           */for(x=0;122>\
x;)p+="   *#"/* b.        OQ####x#K           */[e[x++]+e[x++\
]]||(S=("eval"/* l         `X#####D  ,       */+"(z=\'"+z.spl\
it(B = "\\\\")./*           G####B" #       */join(B+B).split\
(Q="\'").join(B+Q/*          VQBP`        */)+Q+")//m1k")[x/2\
+61*y-1]).fontcolor/*         TP         */(/\\w/.test(S)&&"#\
03B");document.body.innerHTML=p+=B+"\\n"}setTimeout(z)';

p = "<" + "pre>";
n = ["zw2", "l6k", "e3t", "jnt", "qj2", "xh2 x/* =<,m#F^    A W###q. */", "2kty2", "wrt", "13n2", "3n9h2", "3pdxt", "1csb yz/* #K       q##H######Am */", "3iyb6k", "3pk72", "3nmr2", ""]
for (y in n) {
    e = [];
    x = 0;
    r = true;
    t = parseInt(n[y], 36) + "";
    for (a in t) {
        r = !r
        for (i = 0; i < t[a]; i += 0.05) {
             x -= 0.05;
             o = new Date / 1e3 + x / Math.PI
             if (Math.cos(o) < 0)
                 e[~~(32 * Math.sin(o) * Math.sin(0.5 + y / 7)) + 60] = -~r;
        }
    for (x = 0; x < 122;) {
        S = "eval" + "(z='" + z.split(B = "\\").join(B + B).split(Q = "'").join(B + Q) + Q + ")//m1k"
        p += "   *#"[e[x++] + e[x++]] || S[x/2+61*y-1]).fontcolor(/\w/.test(S[x/2+61*y-1]) && "#03B");
    }
    p += B + "\n";
    document.body.innerHTML = p;
}
setTimeout(z)

Voici ce qui arrive:

  • z est une multiligne chaîne de caractères contenant tout le code. C'est - evaled.
  • À la fin du code, z est passé de setTimeout. Il fonctionne comme requestAnimationFrame et eval ensemble, de les évaluer dans un intervalle au plus haut taux possible.
  • Le code lui-même initialise p, le tampon de chaîne sur laquelle le code HTML sera ajouté, et n, un tableau de base-36-codé en chiffres (et les relier en une chaîne de caractères en "4", les commentaires étant sans pertinence des ordures qui n'est pas considéré par parseInt).
  • chaque nombre en n ne coder une seule ligne (n.length == 16). Il est maintenant énumérés.
  • Un tas de variables est initialisé, certains déguisés en e littéral de tableau mais ils sont ensuite exprimés par des chiffres (x) ou des valeurs booléennes (r) ou de chaînes de caractères (t).
  • Chaque chiffre dans le nombre t est énuméré, l'inversion de la boolean r à chaque tour. Pour des angles différents, x, et en fonction de l' heure actuelle new Date / 1000 (de sorte qu'il donne une animation), la matrice e est remplie à l'aide de certains opérateurs au niveau du bit - avec 1 lorsque r est faux et 2s en r qui est vrai à l'époque.
  • Puis une boucle ne itérer l'61 colonnes de l'image, à partir d' x=0 à 122 en double étapes, avec l'ajout de caractères unique pour p.
  • B étant la barre oblique inverse, la chaîne S est construit à partir de la chaîne de code z par la fuite des barres obliques inverses et les apostrophes, pour obtenir une représentation précise de ce qu'il a regardé dans la source.
  • Tous les deux nombres consécutifs de e sont ajoutés et utilisés pour accéder à un personnage de l' " *#", pour construire l'image animée. Si l'un des indices n'est pas défini, l' NaN de l'indice correspond à un caractère indéfini et, au lieu des caractères correspondants de l' S chaîne de caractères est pris (découvrez la formule x/2+61*y-1). Si le personnage doit être un caractère de mot, c'est coloré différemment à l'aide de l' fontcolor Chaîne de méthode.
  • Après chaque ligne, l'arrière de la touche retour arrière et un saut de ligne sont ajoutés p, et la chaîne HTML est affectée dans le corps du document.

Comment le même effet peut être réécrite pour un exemple minimal?

Voici un autre exemple:

setInterval(z='s=("setInterval(z=\'"+\
z.replace(/[\\\\\']/g,"\\\\$&")+"\')"\
).match(/.{1,37}/g).join("\\\\\\n");d\
ocument.body.innerHTML=\"<\\pre>"+s.s\
lice(0, 175)+String( + new Date()).fo\
ntcolor("red")+s.slice(188)')

(démonstration à l'jsfiddle.net)

Il dispose de toutes les choses pertinentes dont vous avez besoin pour ce type d'animation:

  • setInterval et Date pour l'animation
  • Une reconstruction de son propre code (quine), ici:

    s = ( "setInterval(z='" // the outer invokation
          + z.replace(/[\\\']/g,"\\$&") // the escaped version
        + "\')" ) // the end of the assignment
        .match(/.{1,37}/g).join("\\\n"); // chunked into lines
    
  • La sortie via document.body.innerHTML et <pre> élément

  • Le remplacement de certaines parties du code, à l'animation de la chaîne

5voto

rafaelcastrocouto Points 2931

Une chaîne contenant l’intégralité du code est évaluée, et un délai d’attente fait la boucle ; La chaîne est stockée dans une variable nommée et au milieu du code, entre commentaires et `` il y a une « terre ASCII Art ». Le code analyse les commentaires et modifie le contenu du document, gardant la js et mise à jour de l’art. Ci-dessous est juste le code en tranches :

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X