JavaScript Magic Tricks: Undocumented Usage of Eval
In JavaScript programming, Eval is typically used to execute JavaScript code, perform computations, and output results. However, there is an undocumented usage of Eval that few people are probably familiar with.
Here is an example:
var a = eval(['g', 'o', 'l', '.', 'e', 'l', 'o', 's', 'n', 'o', 'c'].reverse().join(""));
var b = ['m', 'o', 'c', '.', 'n', 'a', 'm', 'a', 'h', 's', 'j'].reverse().join("");
a(b);
Can you guess what the output of the function a(b) will be if you only look at the syntax of this JS code? The answer is surprisingly unexpected. Here it is:
The ability to produce such an output relies on an undocumented usage of Eval that allows converting strings into syntactic keywords. The simplified version of the Eval statement mentioned above would be:
eval("console.log");
Use reverse and join to hide the plaintext of console.log.
This method is used for encrypting JavaScript code and works quite well. When it comes to obfuscating and encrypting JS code, some signature words are difficult to hide, like console.log. Typically, console.log might be changed to console["log"] or console["\x6c\x6f\x67"], where the "log" characters can be transformed, but console as a syntax keyword cannot be changed, making it easy to be identified. However, this usage of eval can solve this issue and effectively hide many syntax keywords.
Or for example, for encrypting JSON data:
var abc ={a:'This is a', b:'This is b', c:'This is c'};
console.log(abc.a);
console.log(abc.b);
console.log(abc.c);
JSON data, due to its unique format, is notoriously difficult to obfuscate and encrypt with JavaScript, as it is often difficult to hide key names. However, using the method described in this article, you can modify the code to:
eval("var abc ={a:'This is a', b:'This is b', c:'This is c'};");
console.log(abc.a);
console.log(abc.b);
console.log(abc.c);
Encrypt the content inside the eval statement, and the encrypted code can become:
Note: This is done using JShaman JavaScript Obfuscator, the same applies below.
eval("\u0076\u0061\u0072\u0020\u0061\u0062\u0063\u0020\u003d\u007b\u0061\u003a\u0027\u0054\u0068\u0069\u0073\u0020\u0069\u0073\u0020\u0061\u0027\u002c\u0020\u0062\u003a\u0027\u0054\u0068\u0069\u0073\u0020\u0069\u0073\u0020\u0062\u0027\u002c\u0020\u0063\u003a\u0027\u0054\u0068\u0069\u0073\u0020\u0069\u0073\u0020\u0063\u0027\u007d\u003b");
console.log(abc.a);
console.log(abc.b);
console.log(abc.c);
output:
Top comments (0)