Overview of JSFuck
main[]()!+) to write and execute code. It is environment-agnostic and can be run in both browsers and Node.js.repository·main·Indexed 27 days ago
https://github.com/aemkei/jsfuckAn esoteric programming style and library (version 0.5.0) that allows writing valid JavaScript using only six characters: []()!+. It is used for educational purposes and obfuscation, providing a way to execute arbitrary code in both browsers and Node.js by leveraging JavaScript's atomic parts, type casting, and the Function constructor.
[]()!+) to write and execute code. It is environment-agnostic and can be run in both browsers and Node.js.The Function constructor is the primary mechanism for executing arbitrary code in JSFuck. It takes a string as an argument and returns a new function. You can access the constructor via []["find"]["constructor"].
To get a reference to the global scope (window in browsers), evaluate return this:
[]["find"]["constructor"]("return this")() // returns windowBy wrapping an expression in an array and accessing index zero [X][0], you can use brackets to replace parentheses () to isolate expressions and apply operators.
[X][0] // X
++[ ++[ ++[X][0] ][0] ][0] // X + 3Array.prototype.find, you can concatenate characters to form the string "find" and use []["find"].To chain multiple method calls where each subsequent call uses the result of the previous one (simulating obj.method1().method2()), use a combination of .split(), .concat(), and .reduce() with .apply().
For strings, to achieve "truefalse".replace("true","1").replace("false","0"):
"truefalse"
["split"]()["concat"]([["true"]["concat"]("1")])["reduce"](""["replace"]["apply"]["bind"](""["replace"]))
["split"]()["concat"]([["false"]["concat"]("0")])["reduce"](""["replace"]["apply"]["bind"](""["replace"]))For arrays, the technique is more complex and requires wrapping the initial array to allow for chaining. To achieve [3,4,5].slice(1,2).concat(6):
["3"]["concat"](4)["concat"](5)
["map"]([""["constructor"]])["concat"]([[""[""]]])["0"]["slice"](-1)
["concat"]([[1]["concat"](2)])["reduce"]([""["slice"]["apply"]["bind"]([""["slice"]])])
["concat"](6)"truefalse"
["split"]()["concat"]([["true"]["concat"]("1")])["reduce"](""["replace"]["apply"]["bind"](""["replace"]))
["split"]()["concat"]([["false"]["concat"]("0")])["reduce"](""["replace"]["apply"]["bind"](""["replace"]))To call a method with more than one argument using only JSFuck symbols, use the .reduce() and .bind() technique. This allows you to pass arguments by binding the method to its context and then reducing over an array of arguments.
For example, to call [1,2,3].slice(1,2), you can use:
[1,2].reduce([].slice.bind([1,2,3]))To call a string method like "truefalse".replace("true", "1"):
["true", "1"].reduce("".replace.bind("truefalse"))["true", "1"].reduce("".replace.bind("truefalse"))The + operator is used for casting, addition, and concatenation.
Casting and Math:
+[] casts to the number 0.++[ 0 ][ 0 ] increments a value (results in 1).+[][[]] casts undefined to NaN.String Operations:
[]+[] results in an empty string "".+[] results in the string "0".[][[]]+[] results in the string "undefined".++[][[]]+[] results in the string "NaN".++[[]][+[]]+[] results in the string "1".+[] // 0
++[ 0 ][ 0 ] // 1
+[][[]] // NaN
[] +[] // ""
+[] +[] // "0"The ! operator is used to cast values to booleans.
![] results in false.!![] results in true.Booleans can then be cast to strings using +[] to get "false" or "true", providing access to additional characters like a, e, f, l, r, s, t, u.
![] // false
!![] // true
![] +[] // "false".constructor property on a primitive allows you to access its corresponding built-in wrapper (e.g., Number, String, Boolean). Casting these constructors to strings with +[] allows you to extract even more characters.Brackets are used to create arrays and access properties or methods.
Array Literals:
[] creates an empty array.[[]] creates an array containing another array.Property/Method Access:
[X][i] allows accessing properties or methods (e.g., []["length"] or []["fill"]).[][[]] returns undefined (equivalent to [][""]).[] // an empty array
[[]] // an array with one element (another array)
[][[]] // undefined"undefined", "NaN", or "Infinity", you can extract individual characters using bracket notation [i] to build new words.You can retrieve any lowercase letter from a to z by using the toString method on a number with a base of 36.
Example:
10["toString"](36) // "a"
35["toString"](36) // "z"10["toString"](36) // "a"