Obfuscation & Deobfuscation · 1 min read

Unpacking eval() in Malicious JavaScript

eval() takes a string and executes it as JavaScript. Malware authors use it to hide their real code inside an encoded string that only becomes visible at runtime. The encoded payload might use Base64, hex escapes, String.fromCharCode, or custom encoding functions. Unpacking means intercepting the string before eval() runs it.

Try it now

JS Deobfuscator

Runs in your browser, nothing leaves your device.

The simplest unpacking method: replace `eval(` with `console.log(` or assign the result to a variable. This captures the decoded string without executing it. For nested eval (eval inside eval), repeat the process on each layer. Some scripts check if eval is the real function by comparing `eval.toString()`. Automated deobfuscators handle these anti-tampering checks.

Advanced packers nest 3-5 layers of eval wrapping, each with different encoding. Layer 1 might use Base64, layer 2 uses hex escapes, layer 3 uses String.fromCharCode. Each layer decodes to reveal the next eval() call. The actual malicious payload is only in the innermost layer. You need to unwrap each layer sequentially.

Simple eval wrapper

Input
eval(atob('ZG9jdW1lbnQud3JpdGUoJ3B3bmVkJyk='))
Result
document.write('pwned')

Security context

eval() is the most common execution sink in JavaScript malware. Any time you see eval() with a non-obvious string argument, treat it as suspicious. The encoded string is where the real payload lives.

eval() lets them ship encrypted or encoded payloads that signature-based scanners can't match. The malicious code only exists in readable form for a brief moment at runtime, making static detection much harder.

Go deeper

Continue in the Web Security Academy

Related techniques

Comparing (/4):

Tool Comparison

Feature
Type
Pricing
Platforms
Description