Advertisement
leomaster

JSfuck

Jul 23rd, 2021
1,471
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*! JSFuck 0.5.0 - http://jsfuck.com */
  2.  
  3. (function(self){
  4.   const MIN = 32, MAX = 126;
  5.  
  6.   const SIMPLE = {
  7.     'false':      '![]',
  8.     'true':       '!![]',
  9.     'undefined':  '[][[]]',
  10.     'NaN':        '+[![]]',
  11.     'Infinity':   '+(+!+[]+(!+[]+[])[!+[]+!+[]+!+[]]+[+!+[]]+[+[]]+[+[]]+[+[]])' // +"1e1000"
  12.   };
  13.  
  14.   const CONSTRUCTORS = {
  15.     'Array':    '[]',
  16.     'Number':   '(+[])',
  17.     'String':   '([]+[])',
  18.     'Boolean':  '(![])',
  19.     'Function': '[]["flat"]',
  20.     'RegExp':   'Function("return/"+false+"/")()',
  21.     'Object':   '[]["entries"]()'
  22.   };
  23.  
  24.   const MAPPING = {
  25.     'a':   '(false+"")[1]',
  26.     'b':   '([]["entries"]()+"")[2]',
  27.     'c':   '([]["flat"]+"")[3]',
  28.     'd':   '(undefined+"")[2]',
  29.     'e':   '(true+"")[3]',
  30.     'f':   '(false+"")[0]',
  31.     'g':   '(false+[0]+String)[20]',
  32.     'h':   '(+(101))["to"+String["name"]](21)[1]',
  33.     'i':   '([false]+undefined)[10]',
  34.     'j':   '([]["entries"]()+"")[3]',
  35.     'k':   '(+(20))["to"+String["name"]](21)',
  36.     'l':   '(false+"")[2]',
  37.     'm':   '(Number+"")[11]',
  38.     'n':   '(undefined+"")[1]',
  39.     'o':   '(true+[]["flat"])[10]',
  40.     'p':   '(+(211))["to"+String["name"]](31)[1]',
  41.     'q':   '("")["fontcolor"]([0]+false+")[20]',
  42.     'r':   '(true+"")[1]',
  43.     's':   '(false+"")[3]',
  44.     't':   '(true+"")[0]',
  45.     'u':   '(undefined+"")[0]',
  46.     'v':   '(+(31))["to"+String["name"]](32)',
  47.     'w':   '(+(32))["to"+String["name"]](33)',
  48.     'x':   '(+(101))["to"+String["name"]](34)[1]',
  49.     'y':   '(NaN+[Infinity])[10]',
  50.     'z':   '(+(35))["to"+String["name"]](36)',
  51.  
  52.     'A':   '(NaN+[]["entries"]())[11]',
  53.     'B':   '(+[]+Boolean)[10]',
  54.     'C':   'Function("return escape")()(("")["italics"]())[2]',
  55.     'D':   'Function("return escape")()([]["flat"])["slice"]("-1")',
  56.     'E':   '(RegExp+"")[12]',
  57.     'F':   '(+[]+Function)[10]',
  58.     'G':   '(false+Function("return Date")()())[30]',
  59.     'H':   null,
  60.     'I':   '(Infinity+"")[0]',
  61.     'J':   null,
  62.     'K':   null,
  63.     'L':   null,
  64.     'M':   '(true+Function("return Date")()())[30]',
  65.     'N':   '(NaN+"")[0]',
  66.     'O':   '(+[]+Object)[10]',
  67.     'P':   null,
  68.     'Q':   null,
  69.     'R':   '(+[]+RegExp)[10]',
  70.     'S':   '(+[]+String)[10]',
  71.     'T':   '(NaN+Function("return Date")()())[30]',
  72.     'U':   '(NaN+Object()["to"+String["name"]]["call"]())[11]',
  73.     'V':   null,
  74.     'W':   null,
  75.     'X':   null,
  76.     'Y':   null,
  77.     'Z':   null,
  78.  
  79.     ' ':   '(NaN+[]["flat"])[11]',
  80.     '!':   null,
  81.     '"':   '("")["fontcolor"]()[12]',
  82.     '#':   null,
  83.     '$':   null,
  84.     '%':   'Function("return escape")()([]["flat"])[21]',
  85.     '&':   '("")["fontcolor"](")[13]',
  86.     '\'':  null,
  87.     '(':   '([]["flat"]+"")[13]',
  88.     ')':   '([0]+false+[]["flat"])[20]',
  89.     '*':   null,
  90.     '+':   '(+(+!+[]+(!+[]+[])[!+[]+!+[]+!+[]]+[+!+[]]+[+[]]+[+[]])+[])[2]',
  91.     ',':   '[[]]["concat"]([[]])+""',
  92.     '-':   '(+(.+[0000001])+"")[2]',
  93.     '.':   '(+(+!+[]+[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+[!+[]+!+[]]+[+[]])+[])[+!+[]]',
  94.     '/':   '(false+[0])["italics"]()[10]',
  95.     ':':   '(RegExp()+"")[3]',
  96.     ';':   '("")["fontcolor"](NaN+")[21]',
  97.     '<':   '("")["italics"]()[0]',
  98.     '=':   '("")["fontcolor"]()[11]',
  99.     '>':   '("")["italics"]()[2]',
  100.     '?':   '(RegExp()+"")[2]',
  101.     '@':   null,
  102.     '[':   '([]["entries"]()+"")[0]',
  103.     '\\':  '(RegExp("/")+"")[1]',
  104.     ']':   '([]["entries"]()+"")[22]',
  105.     '^':   null,
  106.     '_':   null,
  107.     '`':   null,
  108.     '{':   '(true+[]["flat"])[20]',
  109.     '|':   null,
  110.     '}':   '([]["flat"]+"")["slice"]("-1")',
  111.     '~':   null
  112.   };
  113.  
  114.   const GLOBAL = 'Function("return this")()';
  115.  
  116.   function fillMissingDigits(){
  117.     var output, number, i;
  118.  
  119.     for (number = 0; number < 10; number++){
  120.  
  121.       output = "+[]";
  122.  
  123.       if (number > 0){ output = "+!" + output; }
  124.       for (i = 1; i < number; i++){ output = "+!+[]" + output; }
  125.       if (number > 1){ output = output.substr(1); }
  126.  
  127.       MAPPING[number] = "[" + output + "]";
  128.     }
  129.   }
  130.  
  131.   function replaceMap(){
  132.     var character = "", value, i, key;
  133.  
  134.     function replace(pattern, replacement){
  135.       value = value.replace(
  136.         new RegExp(pattern, "gi"),
  137.         replacement
  138.       );
  139.     }
  140.  
  141.     function digitReplacer(_,x) { return MAPPING[x]; }
  142.  
  143.     function numberReplacer(_,y) {
  144.       var values = y.split("");
  145.       var head = +(values.shift());
  146.       var output = "+[]";
  147.  
  148.       if (head > 0){ output = "+!" + output; }
  149.       for (i = 1; i < head; i++){ output = "+!+[]" + output; }
  150.       if (head > 1){ output = output.substr(1); }
  151.  
  152.       return [output].concat(values).join("+").replace(/(\d)/g, digitReplacer);
  153.     }
  154.  
  155.     for (i = MIN; i <= MAX; i++){
  156.       character = String.fromCharCode(i);
  157.       value = MAPPING[character];
  158.       if(!value) {continue;}
  159.  
  160.       for (key in CONSTRUCTORS){
  161.         replace("\\b" + key, CONSTRUCTORS[key] + '["constructor"]');
  162.       }
  163.  
  164.       for (key in SIMPLE){
  165.         replace(key, SIMPLE[key]);
  166.       }
  167.  
  168.       replace('(\\d\\d+)', numberReplacer);
  169.       replace('\\((\\d)\\)', digitReplacer);
  170.       replace('\\[(\\d)\\]', digitReplacer);
  171.  
  172.       replace("GLOBAL", GLOBAL);
  173.       replace('\\+""', "+[]");
  174.       replace('""', "[]+[]");
  175.  
  176.       MAPPING[character] = value;
  177.     }
  178.   }
  179.  
  180.   function replaceStrings(){
  181.     var regEx = /[^\[\]\(\)\!\+]{1}/g,
  182.       all, value, missing,
  183.       count = MAX - MIN;
  184.  
  185.     function findMissing(){
  186.       var all, value, done = false;
  187.  
  188.       missing = {};
  189.  
  190.       for (all in MAPPING){
  191.  
  192.         value = MAPPING[all];
  193.  
  194.         if (value && value.match(regEx)){
  195.           missing[all] = value;
  196.           done = true;
  197.         }
  198.       }
  199.  
  200.       return done;
  201.     }
  202.  
  203.     function mappingReplacer(a, b) {
  204.       return b.split("").join("+");
  205.     }
  206.  
  207.     function valueReplacer(c) {
  208.       return missing[c] ? c : MAPPING[c];
  209.     }
  210.  
  211.     for (all in MAPPING){
  212.       if (MAPPING[all]){
  213.         MAPPING[all] = MAPPING[all].replace(/\"([^\"]+)\"/gi, mappingReplacer);
  214.       }
  215.     }
  216.  
  217.     while (findMissing()){
  218.       for (all in missing){
  219.         value = MAPPING[all];
  220.         value = value.replace(regEx, valueReplacer);
  221.  
  222.         MAPPING[all] = value;
  223.         missing[all] = value;
  224.       }
  225.  
  226.       if (count-- === 0){
  227.         console.error("Could not compile the following chars:", missing);
  228.       }
  229.     }
  230.   }
  231.  
  232.   function escapeSequence(c) {
  233.     var cc = c.charCodeAt(0);
  234.     if (cc < 256) {
  235.       return '\\' + cc.toString(8);
  236.     } else {
  237.       var cc16 = cc.toString(16);
  238.       return '\\u' + ('0000' + cc16).substring(cc16.length);  
  239.     }
  240.   }
  241.  
  242.   function escapeSequenceForReplace(c) {
  243.     return escapeSequence(c).replace('\\', 't');
  244.   }
  245.  
  246.   function encode(input, wrapWithEval, runInParentScope){
  247.     var output = [];
  248.  
  249.     if (!input){
  250.       return "";
  251.     }
  252.  
  253.     var unmappped = ''
  254.     for(var k in MAPPING) {
  255.       if (MAPPING[k]){
  256.         unmappped += k;
  257.       }
  258.     }
  259.     unmappped = unmappped.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
  260.     unmappped = new RegExp('[^' + unmappped + ']','g');
  261.     var unmappedCharactersCount = (input.match(unmappped) || []).length;
  262.     if (unmappedCharactersCount > 1) {
  263.       // Without this optimization one unmapped caracter has encoded length
  264.       // of about 3600 characters. Every additional unmapped character adds
  265.       // 2000 to the total length. For example, the lenght of `~` is 3605,
  266.       // `~~` is 5600, and `~~~` is 7595.
  267.       //
  268.       // The loader with replace has encoded length of about 5300 characters
  269.       // and every additional character adds 100 to the total length.
  270.       // In the same example the length of `~~` becomes 5371 and `~~~` -- 5463.
  271.       //
  272.       // So, when we have more than one unmapped character we want to encode whole input
  273.       // except select characters (that have encoded length less than about 70)
  274.       // into an escape sequence.
  275.       //
  276.       // NOTE: `t` should be escaped!
  277.       input = input.replace(/[^0123456789.adefilnrsuN]/g, escapeSequenceForReplace);
  278.     } else if (unmappedCharactersCount > 0) {
  279.       //Because we will wrap the input into a string we need to escape Backslash
  280.       // and Double quote characters (we do not need to worry about other characters
  281.       // because they are not mapped explicitly).
  282.       // The JSFuck-encoded representation of `\` is 2121 symbols,
  283.       // so esacped `\` is 4243 symbols and escaped `"` is 2261 symbols
  284.       // however the escape sequence of that characters are
  285.       // 2168 and 2155 symbols respectively, so it's more practical to
  286.       // rewrite them as escape sequences.
  287.       input = input.replace(/["\\]/g, escapeSequence);
  288.       //Convert all unmapped characters to escape sequence
  289.       input = input.replace(unmappped, escapeSequence);
  290.     }
  291.  
  292.     var r = "";
  293.     for (var i in SIMPLE) {
  294.       r += i + "|";
  295.     }
  296.     r+= ".";
  297.  
  298.     input.replace(new RegExp(r, 'g'), function(c) {
  299.       var replacement = SIMPLE[c];
  300.       if (replacement) {
  301.         output.push("(" + replacement + "+[])");
  302.       } else {
  303.         replacement = MAPPING[c];
  304.         if (replacement){
  305.           output.push(replacement);
  306.         } else {
  307.           throw new Error('Found unmapped character: ' + c);
  308.         }
  309.       }
  310.     });
  311.  
  312.     output = output.join("+");
  313.  
  314.     if (/^\d$/.test(input)){
  315.       output += "+[]";
  316.     }
  317.  
  318.     if (unmappedCharactersCount > 1) {
  319.       // replace `t` with `\\`
  320.       output = "(" + output + ")[" + encode("split") + "](" + encode ("t") + ")[" + encode("join") +"](" + encode("\\") + ")";
  321.     }
  322.  
  323.     if (unmappedCharactersCount > 0) {
  324.       output = "[][" + encode("flat") + "]"+
  325.       "[" + encode("constructor") + "]" +
  326.       "(" + encode("return\"") + "+" + output + "+" + encode("\"") + ")()";
  327.     }
  328.  
  329.     if (wrapWithEval){
  330.       if (runInParentScope){
  331.         output = "[][" + encode("flat") + "]" +
  332.           "[" + encode("constructor") + "]" +
  333.           "(" + encode("return eval") + ")()" +
  334.           "(" + output + ")";
  335.       } else {
  336.         output = "[][" + encode("flat") + "]" +
  337.           "[" + encode("constructor") + "]" +
  338.           "(" + output + ")()";
  339.       }
  340.     }
  341.  
  342.     return output;
  343.   }
  344.  
  345.   fillMissingDigits();
  346.   replaceMap();
  347.   replaceStrings();
  348.  
  349.   self.JSFuck = {
  350.     encode: encode
  351.   };
  352. })(typeof(exports) === "undefined" ? window : exports);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement