How does this obfuscated JavaScript work?

前端 未结 4 1806
清歌不尽
清歌不尽 2021-01-29 17:31

How does the following JavaScript work?

I understand that it is minified code. I have tried de-obfuscating it a little, but I can\'t get a clear concept of how it achiev

4条回答
  •  遇见更好的自我
    2021-01-29 18:10

    Foreword: I beautified and annotated the code extensively at http://jsfiddle.net/WZXYr/2/

    Consider the outermost layer:

    eval(z = '...');
    

    A code string is stored in the variable z. The assignment operator returns the value assigned, so the code string also is passed as an argument into eval.

    The code string z runs inside of eval. The code is extremely obtuse, even when cleaned up, but it seems to:

    1. Parse a string of base-36 numbers, delineated by the character 4.
    2. Populate a map of values, using the global variables e, x, and y to hold map state. Map state is, in part, a function of the current second on the wall clock (new Date / 1e3).
    3. Using the map values, the code generates an output string, p
      • the code uses p += " *#"[index] to decide whether to use a space, asterisk, or hash mark, where index is actually e[x++] + e[x++] (as said above, e and x are responsible for map state)
      • if the index is larger than the length of " *#", there is fallback code that populates the output p with characters from z. Inner characters are populated with animation characters, while outer characters are pulled from z.

    At the end of the code, there is a call to setTimeout(z), which asynchronously evaluates the code string z. This repeat invocation of z allows the code to loop.

    Simple example:

    Here's a super-simple version (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. The for loop adds each character to the output string p (the string is 172 characters long):

      for(i=0;i<172;++i)
      
    2. The inner conditional decides if we're on a character between position 62 to 67, which are the animated characters:

      if(i > 62 && i < 67)
      
    3. If we are, then print out !---, shifted based on the tenth of the second wall-clock value. This provides the animation effect.

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

      (All the nastiness around new Date is really just there to transform a date value into a number between 0 and 3.)

    4. Otherwise, if we're not on an animated character, then print the index-i character from the string defined by

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

      That is, the code string z surrounded by eval(' and ').

    5. Finally, output the string and use setTimeout to queue up another execution of z:

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

    Note that my final output isn't quite right -- I haven't accounted for the backslashes toward the end -- but it should still give you a pretty good idea of how the technique works generally.

提交回复
热议问题