jsfuck.js 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. /*! JSFuck 0.4.0 - http://jsfuck.com */
  2. (function(self){
  3. const USE_CHAR_CODE = Symbol('USE_CHAR_CODE');
  4. const MIN = 32, MAX = 126;
  5. const SIMPLE = {
  6. 'false': '![]',
  7. 'true': '!![]',
  8. 'undefined': '[][[]]',
  9. 'NaN': '+[![]]',
  10. 'Infinity': '+(+!+[]+(!+[]+[])[!+[]+!+[]+!+[]]+[+!+[]]+[+[]]+[+[]]+[+[]])' // +"1e1000"
  11. };
  12. const CONSTRUCTORS = {
  13. 'Array': '[]',
  14. 'Number': '(+[])',
  15. 'String': '([]+[])',
  16. 'Boolean': '(![])',
  17. 'Function': '[]["fill"]',
  18. 'RegExp': 'Function("return/"+false+"/")()',
  19. 'Object': '[]["entries"]()'
  20. };
  21. const MAPPING = {
  22. 'a': '(false+"")[1]',
  23. 'b': '([]["entries"]()+"")[2]',
  24. 'c': '([]["fill"]+"")[3]',
  25. 'd': '(undefined+"")[2]',
  26. 'e': '(true+"")[3]',
  27. 'f': '(false+"")[0]',
  28. 'g': '(false+[0]+String)[20]',
  29. 'h': '(+(101))["to"+String["name"]](21)[1]',
  30. 'i': '([false]+undefined)[10]',
  31. 'j': '([]["entries"]()+"")[3]',
  32. 'k': '(+(20))["to"+String["name"]](21)',
  33. 'l': '(false+"")[2]',
  34. 'm': '(Number+"")[11]',
  35. 'n': '(undefined+"")[1]',
  36. 'o': '(true+[]["fill"])[10]',
  37. 'p': '(+(211))["to"+String["name"]](31)[1]',
  38. 'q': '("")["fontcolor"]([0]+false+")[20]',
  39. 'r': '(true+"")[1]',
  40. 's': '(false+"")[3]',
  41. 't': '(true+"")[0]',
  42. 'u': '(undefined+"")[0]',
  43. 'v': '(+(31))["to"+String["name"]](32)',
  44. 'w': '(+(32))["to"+String["name"]](33)',
  45. 'x': '(+(101))["to"+String["name"]](34)[1]',
  46. 'y': '(NaN+[Infinity])[10]',
  47. 'z': '(+(35))["to"+String["name"]](36)',
  48. 'A': '(+[]+Array)[10]',
  49. 'B': '(+[]+Boolean)[10]',
  50. 'C': 'Function("return escape")()(("")["italics"]())[2]',
  51. 'D': 'Function("return escape")()([]["fill"])["slice"]("-1")',
  52. 'E': '(RegExp+"")[12]',
  53. 'F': '(+[]+Function)[10]',
  54. 'G': '(false+Function("return Date")()())[30]',
  55. 'H': USE_CHAR_CODE,
  56. 'I': '(Infinity+"")[0]',
  57. 'J': USE_CHAR_CODE,
  58. 'K': USE_CHAR_CODE,
  59. 'L': USE_CHAR_CODE,
  60. 'M': '(true+Function("return Date")()())[30]',
  61. 'N': '(NaN+"")[0]',
  62. 'O': '(+[]+Object)[10]',
  63. 'P': USE_CHAR_CODE,
  64. 'Q': USE_CHAR_CODE,
  65. 'R': '(+[]+RegExp)[10]',
  66. 'S': '(+[]+String)[10]',
  67. 'T': '(NaN+Function("return Date")()())[30]',
  68. 'U': '(NaN+Object()["to"+String["name"]]["call"]())[11]',
  69. 'V': USE_CHAR_CODE,
  70. 'W': USE_CHAR_CODE,
  71. 'X': USE_CHAR_CODE,
  72. 'Y': USE_CHAR_CODE,
  73. 'Z': USE_CHAR_CODE,
  74. ' ': '(NaN+[]["fill"])[11]',
  75. '!': USE_CHAR_CODE,
  76. '"': '("")["fontcolor"]()[12]',
  77. '#': USE_CHAR_CODE,
  78. '$': USE_CHAR_CODE,
  79. '%': 'Function("return escape")()([]["fill"])[21]',
  80. '&': '("")["fontcolor"](")[13]',
  81. '\'': USE_CHAR_CODE,
  82. '(': '([]["fill"]+"")[13]',
  83. ')': '([0]+false+[]["fill"])[20]',
  84. '*': USE_CHAR_CODE,
  85. '+': '(+(+!+[]+(!+[]+[])[!+[]+!+[]+!+[]]+[+!+[]]+[+[]]+[+[]])+[])[2]',
  86. ',': '([]["slice"]["call"](false+"")+"")[1]',
  87. '-': '(+(.+[0000000001])+"")[2]',
  88. '.': '(+(+!+[]+[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+[!+[]+!+[]]+[+[]])+[])[+!+[]]',
  89. '/': '(false+[0])["italics"]()[10]',
  90. ':': '(RegExp()+"")[3]',
  91. ';': '("")["fontcolor"](NaN+")[21]',
  92. '<': '("")["italics"]()[0]',
  93. '=': '("")["fontcolor"]()[11]',
  94. '>': '("")["italics"]()[2]',
  95. '?': '(RegExp()+"")[2]',
  96. '@': USE_CHAR_CODE,
  97. '[': '([]["entries"]()+"")[0]',
  98. '\\': '(RegExp("/")+"")[1]',
  99. ']': '([]["entries"]()+"")[22]',
  100. '^': USE_CHAR_CODE,
  101. '_': USE_CHAR_CODE,
  102. '`': USE_CHAR_CODE,
  103. '{': '(true+[]["fill"])[20]',
  104. '|': USE_CHAR_CODE,
  105. '}': '([]["fill"]+"")["slice"]("-1")',
  106. '~': USE_CHAR_CODE
  107. };
  108. const GLOBAL = 'Function("return this")()';
  109. function fillMissingChars(){
  110. var base16code, escape;
  111. for (var key in MAPPING){
  112. if (MAPPING[key] === USE_CHAR_CODE){
  113. //Function('return"\\uXXXX"')()
  114. base16code = key.charCodeAt(0).toString(16);
  115. escape = ('0000'+base16code).substring(base16code.length).split('').join('+');
  116. MAPPING[key] = 'Function("return"+' + MAPPING['"'] + '+"\\u"+' + escape + '+' + MAPPING['"'] + ')()';
  117. }
  118. }
  119. }
  120. function fillMissingDigits(){
  121. var output, number, i;
  122. for (number = 0; number < 10; number++){
  123. output = "+[]";
  124. if (number > 0){ output = "+!" + output; }
  125. for (i = 1; i < number; i++){ output = "+!+[]" + output; }
  126. if (number > 1){ output = output.substr(1); }
  127. MAPPING[number] = "[" + output + "]";
  128. }
  129. }
  130. function replaceMap(){
  131. var character = "", value, original, i, key;
  132. function replace(pattern, replacement){
  133. value = value.replace(
  134. new RegExp(pattern, "gi"),
  135. replacement
  136. );
  137. }
  138. function digitReplacer(_,x) { return MAPPING[x]; }
  139. function numberReplacer(_,y) {
  140. var values = y.split("");
  141. var head = +(values.shift());
  142. var output = "+[]";
  143. if (head > 0){ output = "+!" + output; }
  144. for (i = 1; i < head; i++){ output = "+!+[]" + output; }
  145. if (head > 1){ output = output.substr(1); }
  146. return [output].concat(values).join("+").replace(/(\d)/g, digitReplacer);
  147. }
  148. for (i = MIN; i <= MAX; i++){
  149. character = String.fromCharCode(i);
  150. value = MAPPING[character];
  151. if(!value) {continue;}
  152. original = value;
  153. for (key in CONSTRUCTORS){
  154. replace("\\b" + key, CONSTRUCTORS[key] + '["constructor"]');
  155. }
  156. for (key in SIMPLE){
  157. replace(key, SIMPLE[key]);
  158. }
  159. replace('(\\d\\d+)', numberReplacer);
  160. replace('\\((\\d)\\)', digitReplacer);
  161. replace('\\[(\\d)\\]', digitReplacer);
  162. replace("GLOBAL", GLOBAL);
  163. replace('\\+""', "+[]");
  164. replace('""', "[]+[]");
  165. MAPPING[character] = value;
  166. }
  167. }
  168. function replaceStrings(){
  169. var regEx = /[^\[\]\(\)\!\+]{1}/g,
  170. all, value, missing,
  171. count = MAX - MIN;
  172. function findMissing(){
  173. var all, value, done = false;
  174. missing = {};
  175. for (all in MAPPING){
  176. value = MAPPING[all];
  177. if (value.match(regEx)){
  178. missing[all] = value;
  179. done = true;
  180. }
  181. }
  182. return done;
  183. }
  184. function mappingReplacer(a, b) {
  185. return b.split("").join("+");
  186. }
  187. function valueReplacer(c) {
  188. return missing[c] ? c : MAPPING[c];
  189. }
  190. for (all in MAPPING){
  191. MAPPING[all] = MAPPING[all].replace(/\"([^\"]+)\"/gi, mappingReplacer);
  192. }
  193. while (findMissing()){
  194. for (all in missing){
  195. value = MAPPING[all];
  196. value = value.replace(regEx, valueReplacer);
  197. MAPPING[all] = value;
  198. missing[all] = value;
  199. }
  200. if (count-- === 0){
  201. console.error("Could not compile the following chars:", missing);
  202. }
  203. }
  204. }
  205. function encode(input, wrapWithEval, runInParentScope){
  206. var output = [];
  207. if (!input){
  208. return "";
  209. }
  210. var r = "";
  211. for (var i in SIMPLE) {
  212. r += i + "|";
  213. }
  214. r+= "\n|\r|\u2028|\u2029|.";
  215. input.replace(new RegExp(r, 'g'), function(c) {
  216. var replacement = SIMPLE[c];
  217. if (replacement) {
  218. output.push("(" + replacement + "+[])");
  219. } else {
  220. replacement = MAPPING[c];
  221. if (replacement){
  222. output.push(replacement);
  223. } else {
  224. var cc16 = c.charCodeAt(0).toString(16);
  225. replacement =
  226. "[][" + encode("fill") + "]"+
  227. "[" + encode("constructor") + "]" +
  228. "(" + encode("return\"\\u"+("0000"+cc16).substring(cc16.length)+"\"") + ")()";
  229. output.push(replacement);
  230. MAPPING[c] = replacement;
  231. }
  232. }
  233. });
  234. output = output.join("+");
  235. if (/^\d$/.test(input)){
  236. output += "+[]";
  237. }
  238. if (wrapWithEval){
  239. if (runInParentScope){
  240. output = "[][" + encode("fill") + "]" +
  241. "[" + encode("constructor") + "]" +
  242. "(" + encode("return eval") + ")()" +
  243. "(" + output + ")";
  244. } else {
  245. output = "[][" + encode("fill") + "]" +
  246. "[" + encode("constructor") + "]" +
  247. "(" + output + ")()";
  248. }
  249. }
  250. return output;
  251. }
  252. fillMissingDigits();
  253. fillMissingChars();
  254. replaceMap();
  255. replaceStrings();
  256. self.JSFuck = {
  257. encode: encode
  258. };
  259. })(typeof(exports) === "undefined" ? window : exports);