Giter VIP home page Giter VIP logo

js-confuser's Introduction

JS Confuser

JS-Confuser is a JavaScript obfuscation tool to make your programs impossible to read. Try the web version.

NPM GitHub Netlify

Key features

Presets

JS-Confuser comes with three presets built into the obfuscator.

Preset Transforms Performance Reduction Sample
High 22/25 98% Sample
Medium 19/25 52% Sample
Low 15/25 30% Sample

You can extend each preset or all go without them entirely.

Installation

$ npm install js-confuser

Usage

var JsConfuser = require("js-confuser");

JsConfuser.obfuscate(`
  function fibonacci(num){   
    var a = 0, b = 1, c = num;
    while (num-- > 1) {
      c = a + b;
      a = b;
      b = c;
    }
    return c;
  }

  for ( var i = 1; i <= 25; i++ ) {
    console.log(i, fibonacci(i))
  }
`, {
  target: "node",
  preset: "high",
  stringEncoding: false, // <- Normally enabled
}).then(obfuscated => {
  console.log(obfuscated)
})

/*
var AF59rI,ZgbbeaU,WDgj3I,gpR2qG,Ox61sk,pTNPNpX;AF59rI=[60,17,25,416,22,23,83,26,27,28,18,382,66,29,30,31,2,5,33,4,13,16,10,11,24,1,3,15,6,7,8,167,50,9,21,35,12,14,116],ZgbbeaU=AF59rI;for(var TlMIASm=62;TlMIASm;TlMIASm--)ZgbbeaU.unshift(ZgbbeaU.pop());WDgj3I=MBh_HcM("length1charCodeAt1slice1replaĕ1!ğğ1uģģ1<~A8bt#D.RU,~>Ħ~E,ol,ATMnijĵ@rH7+DertŀħDKTtlBhE[ŋ~@q]:k6Z6LHŖ6$*Ŗ7n#j;20AŖ;g3Cn<]'Ŗ<Fna!Cii#ŖAU&0.Eb0;TŖ4ƌĴħ3rƍ)eVMBK\\!Ŗ+=M;Q@;]UaŖž=3&.0Ŗ/M2-WEcYr5ŖD?ƯTqŸb>-Q:c8Ŗ?SF2m2*!WQŖ2)RIJƐ~ž<ƿĴmČuĀ1 (local)").split('1');function pprWr0(ZgbbeaU){var WDgj3I,gpR2qG,Ox61sk,pTNPNpX,TlMIASm,pprWr0,M1ClYmT,kHWl72,xw_ohrD,sT8e3fv,bxd0KVG;WDgj3I=void 0,gpR2qG=void 0,Ox61sk=void 0,pTNPNpX=void 0,TlMIASm=void 0,pprWr0=String,M1ClYmT=CVH25o3(0),kHWl72=255,xw_ohrD=CVH25o3(1),sT8e3fv=CVH25o3(AF59rI[0]),bxd0KVG=CVH25o3(3);for('<~'===ZgbbeaU[sT8e3fv](0,AF59rI[0])&&'~>'===ZgbbeaU[sT8e3fv](-AF59rI[0]),ZgbbeaU=ZgbbeaU[sT8e3fv](AF59rI[0],-AF59rI[0])[bxd0KVG](/s/g,'')[bxd0KVG]('z',CVH25o3(AF59rI[3])),WDgj3I=CVH25o3(AF59rI[1])[sT8e3fv](ZgbbeaU[M1ClYmT]%AF59rI[1]||AF59rI[1]),ZgbbeaU+=WDgj3I,Ox61sk=[],pTNPNpX=0,TlMIASm=ZgbbeaU[M1ClYmT];TlMIASm>pTNPNpX;pTNPNpX+=AF59rI[1])gpR2qG=52200625*(ZgbbeaU[xw_ohrD](pTNPNpX)-AF59rI[2])+614125*(ZgbbeaU[xw_ohrD](pTNPNpX+AF59rI[9])-AF59rI[2])+7225*(ZgbbeaU[xw_ohrD](pTNPNpX+AF59rI[0])-AF59rI[2])+85*(ZgbbeaU[xw_ohrD](pTNPNpX+AF59rI[10])-AF59rI[2])+(ZgbbeaU[xw_ohrD](pTNPNpX+AF59rI[3])-AF59rI[2]),Ox61sk.push(kHWl72&gpR2qG>>AF59rI[8],kHWl72&gpR2qG>>AF59rI[5],kHWl72&gpR2qG>>8,kHWl72&gpR2qG);return function(ZgbbeaU,Ox61sk){for(var WDgj3I=Ox61sk;WDgj3I>0;WDgj3I--)ZgbbeaU.pop()}(Ox61sk,WDgj3I[M1ClYmT]),pprWr0.fromCharCode.apply(pprWr0,Ox61sk)}gpR2qG=[CVH25o3(AF59rI[12]),CVH25o3(AF59rI[13]),CVH25o3(8),CVH25o3(AF59rI[17]),CVH25o3(AF59rI[6]),CVH25o3(AF59rI[7]),CVH25o3(AF59rI[20]),'<~AQO1jBl7V~>',CVH25o3(AF59rI[4]),CVH25o3(AF59rI[21]),CVH25o3(AF59rI[4]),CVH25o3(9),CVH25o3(AF59rI[11]),CVH25o3(AF59rI[5]),CVH25o3(AF59rI[24]),CVH25o3(AF59rI[33]),'<~E%u9/13QC~>',CVH25o3(AF59rI[6]),CVH25o3(AF59rI[7]),CVH25o3(19),CVH25o3(20),CVH25o3(AF59rI[18]),CVH25o3(AF59rI[27]),CVH25o3(AF59rI[28]),CVH25o3(AF59rI[8]),'<~?T9_t1,(IC~>','<~1bpf~>',CVH25o3(AF59rI[25]),CVH25o3(AF59rI[30]),CVH25o3(AF59rI[31]),CVH25o3(14),CVH25o3(AF59rI[8])];function M1ClYmT(AF59rI){return pprWr0(gpR2qG[AF59rI])}function kHWl72(){try{return global}catch(AF59rI){return this}}Ox61sk=kHWl72.call(this);function xw_ohrD(ZgbbeaU){switch(ZgbbeaU){case 608:return Ox61sk[M1ClYmT(0)];case-884:return Ox61sk[CVH25o3(AF59rI[32])];case AF59rI[26]:return Ox61sk[M1ClYmT(AF59rI[9])];case-AF59rI[35]:return Ox61sk[M1ClYmT(2)]}}function sT8e3fv(ZgbbeaU,WDgj3I,gpR2qG){var Ox61sk;Ox61sk=11;while(Ox61sk!=51){var pTNPNpX,TlMIASm,pprWr0,kHWl72;pTNPNpX=Ox61sk*-244+217;switch(pTNPNpX){case-2467:TlMIASm=false,Ox61sk+=37;break;case-4175:kHWl72=WDgj3I==M1ClYmT(AF59rI[10])&&ziPI9L.qzUvJu1[M1ClYmT(4)+M1ClYmT(AF59rI[1])](AF59rI[9])==48?function(...WDgj3I){var gpR2qG;gpR2qG=AF59rI[1];while(gpR2qG!=AF59rI[11]){var Ox61sk;Ox61sk=gpR2qG*41+199;switch(Ox61sk){case 732:return pprWr0[ZgbbeaU].call(this,M1ClYmT(AF59rI[12]));case 404:IZftqI=WDgj3I,gpR2qG+=AF59rI[14]}}}:pprWr0[ZgbbeaU](M1ClYmT(AF59rI[13])),Ox61sk-=AF59rI[10];break;case-11495:pprWr0={[M1ClYmT(AF59rI[14])]:function(ZgbbeaU,WDgj3I,gpR2qG){var Ox61sk;Ox61sk=64;while(Ox61sk!=AF59rI[16]){var pTNPNpX,TlMIASm,pprWr0;pTNPNpX=Ox61sk*AF59rI[15]+144;switch(pTNPNpX){case 10832:TlMIASm=822,Ox61sk+=AF59rI[10];break;case 812:pprWr0[AF59rI[10]]=pprWr0[0],Ox61sk+=47;break;case 8661:while(TlMIASm!=772){var kHWl72;kHWl72=TlMIASm*234+191;switch(kHWl72){case 207515:TlMIASm-=528;break;case 129593:pprWr0[3]=bxd0KVG(AF59rI[15],pprWr0[AF59rI[9]],pprWr0[AF59rI[0]]),pprWr0[AF59rI[9]]=pprWr0[AF59rI[0]],pprWr0[AF59rI[0]]=pprWr0[AF59rI[10]],TlMIASm+=333;break;case 83963:TlMIASm+=bxd0KVG(-AF59rI[29],pprWr0[0]--,AF59rI[9])&&ziPI9L.U1LXDgJ()?195:414;break;case 192539:TlMIASm-=464}}Ox61sk-=AF59rI[16];break;case 10999:[...pprWr0]=IZftqI,pprWr0.length=1,Ox61sk-=AF59rI[38];break;case 6824:return[];case 11333:if(!ZgbbeaU){return WDgj3I(this,gpR2qG)}Ox61sk-=AF59rI[0];break;case 311:return[pprWr0[AF59rI[10]]];case 5822:pprWr0[1]=0,pprWr0[AF59rI[0]]=AF59rI[9],Ox61sk-=AF59rI[37]}}},[M1ClYmT(AF59rI[17])]:function(ZgbbeaU,WDgj3I,gpR2qG){var Ox61sk;Ox61sk=AF59rI[18];while(Ox61sk!=38){var pTNPNpX,TlMIASm,pprWr0;pTNPNpX=Ox61sk*182+-139;switch(pTNPNpX){case 4047:pprWr0[AF59rI[9]]=sT8e3fv(M1ClYmT(AF59rI[6]),M1ClYmT(AF59rI[7])).call([],pprWr0[0]),Ox61sk+=AF59rI[19];break;case 3683:TlMIASm=false,Ox61sk+=21;break;case 7505:[...pprWr0]=IZftqI,Ox61sk-=10;break;case 225:return pprWr0[AF59rI[9]].pop();case 10417:if(TlMIASm){var kHWl72=(ZgbbeaU,WDgj3I,gpR2qG)=>{var Ox61sk;Ox61sk=32;while(Ox61sk!=AF59rI[19]){var pTNPNpX,TlMIASm,pprWr0;pTNPNpX=Ox61sk*38+90;switch(pTNPNpX){case 508:TlMIASm=bxd0KVG(AF59rI[15],M1ClYmT(AF59rI[20]),pprWr0.toUTCString()),Ox61sk+=AF59rI[21];break;case 584:pprWr0.setTime(bxd0KVG(AF59rI[15],pprWr0.getTime(),bxd0KVG(AF59rI[22],bxd0KVG(116,bxd0KVG(AF59rI[22],bxd0KVG(116,gpR2qG,AF59rI[8]),AF59rI[23]),AF59rI[23]),1e3))),Ox61sk-=2;break;case 1040:xw_ohrD(608).cookie=bxd0KVG(AF59rI[15],bxd0KVG(AF59rI[15],bxd0KVG(AF59rI[15],bxd0KVG(AF59rI[15],bxd0KVG(AF59rI[15],ZgbbeaU,M1ClYmT(AF59rI[4])),WDgj3I),M1ClYmT(AF59rI[21])),TlMIASm),M1ClYmT(15)),Ox61sk+=AF59rI[6];break;case 1306:pprWr0=new Date,Ox61sk-=19}}}}Ox61sk-=56;break;case 5685:pprWr0.length=1,Ox61sk-=AF59rI[17]}}}},Ox61sk-=43;break;case-14179:kHWl72=void 0;if(WDgj3I==M1ClYmT(AF59rI[5])&&ziPI9L.VNaV0wv[M1ClYmT(AF59rI[24])+M1ClYmT(18)](AF59rI[6])==AF59rI[16]){IZftqI=[]}Ox61sk-=41;break;case-1003:if(TlMIASm){xw_ohrD(-884).exports=async()=>{var ZgbbeaU;ZgbbeaU=33;while(ZgbbeaU!=AF59rI[7]){var WDgj3I,gpR2qG,Ox61sk;WDgj3I=ZgbbeaU*95+-150;switch(WDgj3I){case 3175:gpR2qG=await(async()=>{var ZgbbeaU;ZgbbeaU=14;while(ZgbbeaU!=AF59rI[13]){var WDgj3I;WDgj3I=ZgbbeaU*100+-59;switch(WDgj3I){case 1341:if(isStandaloneExecutable){return M1ClYmT(19)+M1ClYmT(20)}ZgbbeaU+=AF59rI[6];break;case 2341:if(redactedPath===await resolveLocalredactedPath()){return CVH25o3(AF59rI[36])}ZgbbeaU-=AF59rI[13];break;case 1641:return''}}})(),ZgbbeaU-=AF59rI[25];break;case 2985:Ox61sk=new Set(xw_ohrD(AF59rI[26]).argv.slice(2)),ZgbbeaU-=AF59rI[6];break;case 2035:if(!Ox61sk.has(M1ClYmT(AF59rI[18])+M1ClYmT(AF59rI[27]))){var pTNPNpX;pTNPNpX=AF59rI[14];while(pTNPNpX!=9){var TlMIASm;TlMIASm=pTNPNpX*-204+38;switch(TlMIASm){case-1594:if(bxd0KVG(427,Ox61sk.size,1)){return false}pTNPNpX-=AF59rI[3];break;case-778:if(!Ox61sk.has(M1ClYmT(AF59rI[28]))){return false}pTNPNpX+=AF59rI[1]}}}ZgbbeaU+=AF59rI[20];break;case 800:return true}}}}Ox61sk+=54;break;case-3443:return gpR2qG==M1ClYmT(AF59rI[8])&&ziPI9L.U1LXDgJ()?{QVbrqy9:kHWl72}:kHWl72}}}function bxd0KVG(ZgbbeaU,WDgj3I,gpR2qG){switch(ZgbbeaU){case-AF59rI[34]:return WDgj3I<=gpR2qG;case-AF59rI[29]:return WDgj3I>gpR2qG;case AF59rI[15]:return WDgj3I+gpR2qG;case AF59rI[22]:return WDgj3I*gpR2qG;case 427:return WDgj3I!==gpR2qG}}pTNPNpX=AF59rI[12];while(pTNPNpX!=AF59rI[24]){var kBznIi,sCb8UYh,ziPI9L,IZftqI;kBznIi=pTNPNpX*-55+-214;switch(kBznIi){case-544:sCb8UYh=846,pTNPNpX+=AF59rI[0];break;case-654:ziPI9L={wHDYSl:[],U1LXDgJ:function(){if(!ziPI9L.wHDYSl[0]){ziPI9L.wHDYSl.push(87)}return ziPI9L.wHDYSl.length},VNaV0wv:M1ClYmT(AF59rI[25])+M1ClYmT(AF59rI[30]),qzUvJu1:M1ClYmT(AF59rI[31])+M1ClYmT(AF59rI[32])},pTNPNpX+=AF59rI[33];break;case-1644:IZftqI=[],pTNPNpX-=7;break;case-1259:while(sCb8UYh!=316){var XsBuZX,mgjtps2;XsBuZX=sCb8UYh*229+-125;switch(XsBuZX){case 193609:mgjtps2=AF59rI[9],sCb8UYh-=733;break;case 25752:sCb8UYh+=bxd0KVG(-AF59rI[34],mgjtps2,25)&&ziPI9L.U1LXDgJ()?662:203;break;case 177350:xw_ohrD(-AF59rI[35])[M1ClYmT(AF59rI[36])](mgjtps2,(IZftqI=[mgjtps2],new sT8e3fv(M1ClYmT(AF59rI[37]),void 0,M1ClYmT(AF59rI[38])).QVbrqy9)),sCb8UYh-=569;break;case 47049:mgjtps2++,sCb8UYh-=93}}pTNPNpX-=AF59rI[0]}}function CVH25o3(AF59rI){return WDgj3I[AF59rI]}function MBh_HcM(ZgbbeaU){var WDgj3I,gpR2qG,Ox61sk,pTNPNpX,TlMIASm,pprWr0,M1ClYmT,kHWl72;WDgj3I=void 0,gpR2qG=void 0,Ox61sk=void 0,pTNPNpX={},TlMIASm=ZgbbeaU.split(''),pprWr0=gpR2qG=TlMIASm[0],M1ClYmT=[pprWr0],kHWl72=WDgj3I=256;for(ZgbbeaU=AF59rI[9];ZgbbeaU<TlMIASm.length;ZgbbeaU++)Ox61sk=TlMIASm[ZgbbeaU].charCodeAt(0),Ox61sk=kHWl72>Ox61sk?TlMIASm[ZgbbeaU]:pTNPNpX[Ox61sk]?pTNPNpX[Ox61sk]:gpR2qG+pprWr0,M1ClYmT.push(Ox61sk),pprWr0=Ox61sk.charAt(0),pTNPNpX[WDgj3I]=gpR2qG+pprWr0,WDgj3I++,gpR2qG=Ox61sk;return M1ClYmT.join('')}
*/

CLI Usage

<coming soon>

obfuscate(sourceCode, options)

Obfuscates the sourceCode. Returns a Promise that resolves to a string of the obfuscated code.

Parameter Type Description
sourceCode string The JavaScript code to be obfuscated.
options object The obfuscator settings.

obfuscateAST(AST, options)

Obfuscates an ESTree compliant AST. Returns a Promise.

Note: Mutates the object.

Parameter Type Description
AST object The ESTree compliant AST. This object will be mutated.
options object The obfuscator settings.

Options

target

The execution context for your output. Required.

  1. "node"
  2. "browser"

preset

JS-Confuser comes with three presets built into the obfuscator. Optional. ("high"/"medium"/"low")

var JsConfuser = require('js-confuser');

JsConfuser.obfuscate(`<source code>`, {
  target: "node",
  preset: "high" // | "medium" | "low"
}).then(obfuscated=>{
  console.log(obfuscated); // obfuscated is a string
})

compact

Remove's whitespace from the final output. Enabled by default. (true/false)

hexadecimalNumbers

Uses the hexadecimal representation for numbers. (true/false)

minify

Minifies redundant code. (true/false)

es5

Converts output to ES5-compatible code. (true/false)

Does not cover all cases such as Promises or Generator functions. Use Babel.

renameVariables

Determines if variables should be renamed. (true/false)

// Input
var twoSum = function (nums, target) {
  var hash = {};
  var len = nums.length;
  for (var i = 0; i < len; i++) {
    if (nums[i] in hash) return [hash[nums[i]], i];
    hash[target - nums[i]] = i;
  }
  return [-1, -1];
};

var test = function () {
  var inputNums = [2, 7, 11, 15];
  var inputTarget = 9;
  var expectedResult = [0, 1];

  var actualResult = twoSum(inputNums, inputTarget);
  ok(actualResult[0] === expectedResult[0]);
  ok(actualResult[1] === expectedResult[1]);
};

test();

// Output
var _O2mOcF = function (kB4uXM, w_07HXS) {
  var ZLTJcx = {};
  var sXQOaUx = kB4uXM["length"];
  for (var JYYxEk = 0; JYYxEk < sXQOaUx; JYYxEk++) {
    if (kB4uXM[JYYxEk] in ZLTJcx) {
      return [ZLTJcx[kB4uXM[JYYxEk]], JYYxEk];
    }
    ZLTJcx[w_07HXS - kB4uXM[JYYxEk]] = JYYxEk;
  }
  return [-1, -1];
};
var qFaI6S = function () {
  var fZpeOw = [2, 7, 11, 15];
  var UJ62R2c = 9;
  var dG6R0cV = [0, 1];
  var WgYXwn = _O2mOcF(fZpeOw, UJ62R2c);
  void (ok(WgYXwn[0] === dG6R0cV[0]), ok(WgYXwn[1] === dG6R0cV[1]));
};
qFaI6S();

renameGlobals

Renames top-level variables, turn this off for web-related scripts. Enabled by default. (true/false)

// Output (Same input from above)
var twoSum = function (Oc4nmjB, Fk3nptX) {
  var on_KnCm = {};
  var lqAauc = Oc4nmjB["length"];
  for (var mALijp8 = 0; mALijp8 < lqAauc; mALijp8++) {
    if (Oc4nmjB[mALijp8] in on_KnCm) {
      return [on_KnCm[Oc4nmjB[mALijp8]], mALijp8];
    }
    on_KnCm[Fk3nptX - Oc4nmjB[mALijp8]] = mALijp8;
  }
  return [-1, -1];
};
var test = function () {
  var y5ySeZ = [2, 7, 11, 15];
  var gHYMOm = 9;
  var aAdj3v = [0, 1];
  var GnLVHX = twoSum(y5ySeZ, gHYMOm);
  !(ok(GnLVHX[0] === aAdj3v[0]), ok(GnLVHX[1] === aAdj3v[1]));
};
test();

identifierGenerator

Determines how variables are renamed.

Mode Description Example
"hexadecimal" Random hex strings _0xa8db5
"randomized" Random characters w$Tsu4G
"zeroWidth" Invisible characters U+200D
"mangled" Alphabet sequence a, b, c
"number" Numbered sequence var_1, var_2
<function> Write a custom name generator See Below
// Custom implementation
JsConfuser.obfuscate(code, {
  target: "node",
  renameVariables: true,
  identifierGenerator: function () {
    return "$" + Math.random().toString(36).substring(7);
  },
});

// Numbered variables
var counter = 0;
JsConfuser.obfuscate(code, {
  target: "node",
  renameVariables: true,
  identifierGenerator: function () {
    return "var_" + (counter++);
  },
});

JSConfuser tries to reuse names when possible, creating very potent code.

controlFlowFlattening

⚠️ Significantly impacts performance, use sparingly!

Control-flow Flattening hinders program comprehension by creating convoluted switch statements. (true/false/0-1)

Use a number to control the percentage from 0 to 1.

Learn more here.

// Input
function countTo(num){
  for ( var i = 1; i <= num; i++ ) {
    console.log(i);
  }
}

var number = 10;
countTo(number); // 1,2,3,4,5,6,7,8,9,10

// Output
var n2DUka,
  O7yZ0oU,
  mJMdMhJ = -337,
  A1Nyvv = -94,
  xDwpOk6 = 495,
  uKcJl2 = {
    TGCpW6t: "log",
    qUrjFe: function () {
      return xDwpOk6 == (126 > mJMdMhJ ? -16 : 34);
    },
    YN20IBx: function () {
      return (A1Nyvv -= 53);
    },
    CTW4vwx: -73,
    PLzWYDx: function () {
      return (O7yZ0oU = [[385, -94, -282], [10]]);
    },
    bW2FK2: function () {
      return (mJMdMhJ *= 2), (mJMdMhJ += 366);
    },
    AfOoRT: function () {
      return xDwpOk6 == xDwpOk6 + 867;
    },
    KTNMdj: function () {
      if (uKcJl2.AfOoRT()) {
        typeof ((mJMdMhJ += 0), uKcJl2.Q0I6e4f(), (xDwpOk6 += 0));
        return "cobTe8G";
      }
      typeof (uKcJl2.htRXYx(),
      (mJMdMhJ += 59),
      (A1Nyvv -= 537),
      (xDwpOk6 += uKcJl2.mLuSzZ < mJMdMhJ ? 449 : -33));
      return "cobTe8G";
    },
  };
while (mJMdMhJ + A1Nyvv + xDwpOk6 != 83) {
  var yQNDJh = (mJMdMhJ + A1Nyvv + xDwpOk6) * 58 + 54;
  switch (yQNDJh) {
    case 750:
      if (A1Nyvv == 24) {
        uKcJl2.FxREGd6();
        break;
      }
    case 1214:
      if (uKcJl2.qUrjFe()) {
        typeof ((mJMdMhJ *= -8 > xDwpOk6 ? -109 : 2),
        (mJMdMhJ += 1168),
        (xDwpOk6 += xDwpOk6 - 1290));
        break;
      }
      function _VSsIw() {
        var [yQNDJh, _VSsIw] = O7yZ0oU,
          [L9B14E] = _VSsIw,
          uTyFFb = 322;
        while (uTyFFb != 23) {
          var cBx3ysg = uTyFFb * 48 - 77;
          switch (cBx3ysg) {
            case 15379:
              var IOoqIZ = 1;
              uTyFFb -= 306;
              break;
            case 691:
              uTyFFb += IOoqIZ <= L9B14E ? 976 : 7;
              break;
            case 47539:
              typeof (console[uKcJl2.TGCpW6t](IOoqIZ), (uTyFFb -= 795));
              break;
            case 9379:
              !(IOoqIZ++, (uTyFFb -= 181));
          }
        }
        return ([mJMdMhJ, A1Nyvv, xDwpOk6] = yQNDJh), (n2DUka = void 0);
      }
      (xDwpOk6 == -73 ? parseInt : _VSsIw)();
      break;
    case 576:
      typeof (mJMdMhJ == -4 ? clearImmediate : void 0,
      uKcJl2.bky8kL(),
      (xDwpOk6 -= 463));
      break;
    case 4172:
      var L9B14E = 10;
      void ((O7yZ0oU = [[385, -94, -282], [10]]),
      (mJMdMhJ -= 187),
      uKcJl2.YN20IBx(),
      (xDwpOk6 += 189));
      break;
    case 3766:
      !((uKcJl2.Fpp8x5 = -167),
      (uKcJl2.mLuSzZ = 144),
      (uKcJl2.FxREGd6 = function () {
        return (mJMdMhJ += uKcJl2.Fpp8x5), (xDwpOk6 += 164);
      }),
      (uKcJl2.bky8kL = function () {
        return (A1Nyvv += 537);
      }),
      (uKcJl2.Q0I6e4f = function () {
        return (A1Nyvv += 0);
      }),
      (uKcJl2.htRXYx = function () {
        return (xDwpOk6 = -82);
      }));
      var L9B14E = 10;
      void (uKcJl2.PLzWYDx(), uKcJl2.bW2FK2(), (xDwpOk6 += uKcJl2.CTW4vwx));
      break;
    default:
      if (uKcJl2.KTNMdj() == "cobTe8G") {
        break;
      }
  }
}

globalConcealing

Global Concealing hides global variables being accessed. (true/false)

// Input
console.log("Hello World");

// Output
yAt1T_y(-93)["log"]("Hello World");

stringCompression

String Compression uses LZW's compression algorithm to compress strings. (true/false/0-1)

"console" -> inflate('replaĕ!ğğuģģ<~@')

stringConcealing

String Concealing involves encoding strings to conceal plain-text values. (true/false/0-1)

Use a number to control the percentage of strings.

"console" -> decrypt('<~@rH7+Dert~>')

stringEncoding

String Encoding transforms a string into an encoded representation. (true/false/0-1)

Use a number to control the percentage of strings.

"console" -> '\x63\x6f\x6e\x73\x6f\x6c\x65'

stringSplitting

String Splitting splits your strings into multiple expressions. (true/false/0-1)

Use a number to control the percentage of strings.

"console" -> String.fromCharCode(99) + 'ons' + 'ole'

duplicateLiteralsRemoval

Duplicate Literals Removal replaces duplicate literals with a single variable name. (true/false)

dispatcher

Creates a middleman function to process function calls. (true/false/0-1)

// Input
function print(x){
  console.log(x);
}

print("Hello World"); // "Hello World"

// Output
var RfN5Yz = Object.create(null),
  GEMxMoq = [];
typeof ((GEMxMoq = ["Hello World"]), yT9GzM("jlg2V0"));
function yT9GzM(yT9GzM, ChVrLK, b8q2HVZ) {
  var RuH38a = {
      jlg2V0: function (_x5bmV, fslYszl, YbdYYlj) {
        if (!_x5bmV) {
          return fslYszl(this, YbdYYlj);
        }
        var [yT9GzM] = GEMxMoq;
        console.log(yT9GzM);
      },
    },
    JwN3oMY;
  if (ChVrLK == "smHux1f") {
    GEMxMoq = [];
  }
  JwN3oMY =
    ChVrLK == "DiwMvrE"
      ? RfN5Yz[yT9GzM] ||
        (RfN5Yz[yT9GzM] = function (...fslYszl) {
          GEMxMoq = fslYszl;
          return RuH38a[yT9GzM].call(this, "vZWlke7");
        })
      : RuH38a[yT9GzM]("EuVJE6");
  return b8q2HVZ == "ePsy9W" ? { occYQrC: JwN3oMY } : JwN3oMY;
}

rgf

RGF (Runtime-Generated-Functions) uses the new Function(code...) syntax to construct executable code from strings. (true/false/0-1)

  • This can break your code.
  • Due to the security concerns of arbitrary code execution, you must enable this yourself.
  • The arbitrary code is also obfuscated.

Note: RGF will only apply to functions that do not rely on any outside-scoped variables. Enable flatten along with rgf to apply to these functions.

Note: Does not apply to arrow, async, or generator functions.

Use a number to control the percentage of functions changed.

Learn more here.

// Input
function printToConsole(message){
  console.log(message);
}

printToConsole("Hello World"); // "Hello World"

// Output
var Ricvq8s = [new Function('function HIGRHaD(ANVivo_){console[\'log\'](ANVivo_)}return HIGRHaD[\'apply\'](this,arguments)')];
function uhj6obs() {
    return Ricvq8s[0]['apply'](this, arguments);
}
uhj6obs('Hello World'); // "Hello World"

flatten

Brings independent declarations to the highest scope. (true/false/0-1)

This transformation makes functions eligible for the RGF transformation.

Use a number to control the percentage of functions changed.

// Input
(function(){
  var stringToPrint = "Hello World";
  var timesPrinted = 0;

  function printString(){
    timesPrinted++;
    console.log(stringToPrint);
  }

  printString(); // "Hello World"
})();

// Output
var XKlik0N = lP2p9dc(([], pgswImq) => {
  void (pgswImq.rGFfJKd++, console.log(pgswImq.I6NTID));
});
function M5IeIO([], mu63vsS) {
  var p_hOdnM = "Hello World",
    X_bU9rL = 0;
  function Iwe3cJW(...nuTwoiz) {
    var aNxnp94 = {
      set rGFfJKd(C9XSMeD) {
        X_bU9rL = C9XSMeD;
      },
      get I6NTID() {
        return p_hOdnM;
      },
      get rGFfJKd() {
        return X_bU9rL;
      },
    };
    return mu63vsS.PbELcOw(nuTwoiz, aNxnp94);
  }
  Iwe3cJW();
}
lP2p9dc((...AvydL3) => {
  var B6ymQf = {
    get PbELcOw() {
      return XKlik0N;
    },
  };
  return M5IeIO(AvydL3, B6ymQf);
})();
function lP2p9dc(fJxfZW) {
  return function () {
    return fJxfZW(...arguments);
  };
}

objectExtraction

Extracts object properties into separate variables. (true/false)

// Input
var utils = {
  isString: x=>typeof x === "string",
  isBoolean: x=>typeof x === "boolean"
}
if ( utils.isString("Hello") ) {
  // ...
}

// Output
var utils_isString = x=>typeof x === "string";
var utils_isBoolean = x=>typeof x === "boolean";
if ( utils_isString("Hello") ) {
  // ...
}

deadCode

Randomly injects dead code. (true/false/0-1)

Use a number to control the percentage from 0 to 1.

calculator

Creates a calculator function to handle arithmetic and logical expressions. (true/false/0-1)

lock.antiDebug

Adds debugger statements throughout the code. Additionally adds a background function for DevTools detection. (true/false/0-1)

lock.context

Properties that must be present on the window object (or global for NodeJS). (string[])

lock.startDate

When the program is first able to be used. (number or Date)

Number should be in milliseconds.

lock.endDate

When the program is no longer able to be used. (number or Date)

Number should be in milliseconds.

lock.domainLock

Array of regex strings that the window.location.href must follow. (Regex[] or string[])

lock.osLock

Array of operating-systems where the script is allowed to run. (string[])

Allowed values: "linux", "windows", "osx", "android", "ios"

Example: ["linux", "windows"]

lock.browserLock

Array of browsers where the script is allowed to run. (string[])

Allowed values: "firefox", "chrome", "iexplorer", "edge", "safari", "opera"

Example: ["firefox", "chrome"]

lock.selfDefending

Prevents the use of code beautifiers or formatters against your code.

Identical to Obfuscator.io's Self Defending

lock.integrity

Integrity ensures the source code is unchanged. (true/false/0-1)

Learn more here.

lock.countermeasures

A custom callback function to invoke when a lock is triggered. (string/false)

Learn more about the countermeasures function.

Otherwise, the obfuscator falls back to crashing the process.

movedDeclarations

Moves variable declarations to the top of the context. (true/false)

// Input
function getAreaOfCircle(radius) {
  var pi = Math.PI;
  var radiusSquared = Math.pow(radius, 2);
  var area = pi * radiusSquared;

  return area;
}

// Output
function getAreaOfCircle(yLu5YB1) {
  var eUf7Wle, XVYH4D;
  var F8QuPL = Math["PI"];
  typeof ((eUf7Wle = Math["pow"](yLu5YB1, 2)), (XVYH4D = F8QuPL * eUf7Wle));
  return XVYH4D;
}

opaquePredicates

An Opaque Predicate that is evaluated at runtime, this can confuse reverse engineers from understanding your code. (true/false/0-1)

shuffle

Shuffles the initial order of arrays. The order is brought back to the original during runtime. ("hash"/true/false/0-1)

Mode Description
"hash" Array is shifted based on hash of the elements
true Arrays are shifted n elements, unshifted at runtime
false Feature disabled

stack

Local variables are consolidated into a rotating array. (true/false/0-1)

Similar to Jscrambler's Variable Masking

// Input
function add3(x, y, z){
  return x + y + z;
}

// Output
function iVQoGQD(...iVQoGQD){
  ~(iVQoGQD.length = 3, iVQoGQD[215] = iVQoGQD[2], iVQoGQD[75] = 227, iVQoGQD[iVQoGQD[75] - (iVQoGQD[75] - 75)] = iVQoGQD[75] - (iVQoGQD[75] - 239), iVQoGQD[iVQoGQD[iVQoGQD[75] - 164] - 127] = iVQoGQD[iVQoGQD[75] - 238], iVQoGQD[iVQoGQD[75] - 104] = iVQoGQD[75] - 482, iVQoGQD[iVQoGQD[135] + 378] = iVQoGQD[iVQoGQD[135] + 318] - 335, iVQoGQD[21] = iVQoGQD[iVQoGQD[135] + 96], iVQoGQD[iVQoGQD[iVQoGQD[75] - 104] - (iVQoGQD[75] - 502)] = iVQoGQD[iVQoGQD[75] - 164] - 440);
  return iVQoGQD[75] > iVQoGQD[75] + 90 ? iVQoGQD[iVQoGQD[135] - (iVQoGQD[135] + 54)] : iVQoGQD[iVQoGQD[135] + 117] + iVQoGQD[iVQoGQD[iVQoGQD[75] - (iVQoGQD[75] - (iVQoGQD[75] - 104))] - (iVQoGQD[135] - 112)] + iVQoGQD[215];
};

High preset

{
  target: "node",
  preset: "high",

  calculator: true,
  compact: true,
  hexadecimalNumbers: true,
  controlFlowFlattening: 0.75,
  deadCode: 0.2,
  dispatcher: true,
  duplicateLiteralsRemoval: 0.75,
  flatten: true,
  globalConcealing: true,
  identifierGenerator: "randomized",
  minify: true,
  movedDeclarations: true,
  objectExtraction: true,
  opaquePredicates: 0.75,
  renameVariables: true,
  renameGlobals: true,
  shuffle: { hash: 0.5, true: 0.5 },
  stack: true,
  stringConcealing: true,
  stringCompression: true,
  stringEncoding: true,
  stringSplitting: 0.75,

  // Use at own risk
  rgf: false
}

Medium preset

{
  target: "node",
  preset: "medium",

  calculator: true,
  compact: true,
  hexadecimalNumbers: true,
  controlFlowFlattening: 0.5,
  deadCode: 0.025,
  dispatcher: 0.75,
  duplicateLiteralsRemoval: 0.5,
  globalConcealing: true,
  identifierGenerator: "randomized",
  minify: true,
  movedDeclarations: true,
  objectExtraction: true,
  opaquePredicates: 0.5,
  renameVariables: true,
  renameGlobals: true,
  shuffle: true,
  stack: 0.5,
  stringConcealing: true,
  stringSplitting: 0.25
}

Low Preset

{
  target: "node",
  preset: "low",

  calculator: true,
  compact: true,
  hexadecimalNumbers: true,
  controlFlowFlattening: 0.25,
  deadCode: 0.01,
  dispatcher: 0.5,
  duplicateLiteralsRemoval: true,
  identifierGenerator: "randomized",
  minify: true,
  movedDeclarations: true,
  objectExtraction: true,
  opaquePredicates: 0.1,
  renameVariables: true,
  renameGlobals: true,
  stringConcealing: true
}

Locks

You must enable locks yourself, and configure them to your needs.

{
  target: "node",
  lock: {
    integrity: true,
    selfDefending: true,
    domainLock: ["mywebsite.com"],
    osLock: ["windows", "linux"],
    browserLock: ["firefox"],
    startDate: new Date("Feb 1 2021"),
    endDate: new Date("Mar 1 2021"),
    antiDebug: true,

    // crashes browser
    countermeasures: true,

    // or custom callback (pre-obfuscated name)
    countermeasures: "onLockDetected"
  }
}

Optional features

These features are experimental or a security concern.

{
  target: "node",
  rgf: true, // (security concern)

  // set to false for web-related scripts
  renameGlobals: false,

  // experimental
  identifierGenerator: function(){
    return "myvar_" + (counter++);
  }
}

Percentages

Most settings allow percentages to control the frequency of the transformation. Fine-tune the percentages to keep file size down, and performance high.

{
  target: "node",
  controlFlowFlattening: true, // equal to 1, which is 100% (slow)

  controlFlowFlattening: 0.5, // 50%
  controlFlowFlattening: 0.01 // 1%
}

Probabilities

Mix modes using an object with key-value pairs to represent each mode's percentage.

{
  target: "node",
  identifierGenerator: {
    "hexadecimal": 0.25, // 25% each
    "randomized": 0.25,
    "mangled": 0.25,
    "number": 0.25
  },

  shuffle: {hash: 0.5, true: 0.5} // 50% hash, 50% normal
}

Custom Implementations

{
  target: "node",
  
  // avoid renaming a certain variable
  renameVariables: name=>name!="jQuery",

  // custom variable names
  identifierGenerator: ()=>{
    return "_0x" + Math.random().toString(16).slice(2, 8);
  },

  // force encoding on a string
  stringConcealing: (str)=>{
    if (str=="https://mywebsite.com/my-secret-api"){
      return true;
    }

    // 60%
    return Math.random() < 0.6;
  },

  // set limits
  deadCode: ()=>{
    dead++; 

    return dead < 50;
  }
}

Potential Issues

  1. String Encoding can corrupt files. Disable stringEncoding if this happens.
  2. Dead Code can bloat file size. Reduce or disable deadCode.
  3. Rename Globals can break web-scripts. i. Disable renameGlobals or ii. Refactor your code
    // Avoid doing this
    var myGlobalFunction = ()=>console.log("Called");
    
    // Do this instead
    window.myGlobalFunction = ()=>console.log("Called");

File size and Performance

Obfuscation can bloat file size and negatively impact performance. Avoid using the following:

Option Description
deadCode Bloats file size. Use low percentages.
stringSplitting, stringEncoding Bloats file size. Avoid using these altogether.
controlFlowFlattening Significant performance impact. Use very low percentage when source code is large.
dispatcher Slow performance. Use low percentage.

"The obfuscator broke my code!"

Try disabling features in the following order:

  1. flatten
  2. stack
  3. dispatcher

If the error continues then open an issue.

Bug report

Please open an issue with the code and config used.

Feature request

Please open an issue and be descriptive. Don't submit any PRs until approved.

JsConfuser vs. Javascript-obfuscator

Javascript-obfuscator (https://obfuscator.io) is the popular choice for JS obfuscation. This means more attackers are aware of their strategies. JSConfuser provides unique features and is lesser-known.

Automated deobfuscators are aware of https://obfuscator.io's techniques:

https://www.youtube.com/watch?v=_UIqhaYyCMI

However, the dev is quick to fix these. The one above no longer works.

Alternatively, you could go the paid-route with Jscrambler.com (enterprise only) or PreEmptive.com

I've included several alternative obfuscators in the samples/ folder. They are all derived from the input.js file.

Debugging

Enable logs to view the obfuscator's state.

{
  target: "node",
  verbose: true
}

About the internals

This obfuscator depends on two libraries to work: acorn and escodegen

  • acorn is responsible for parsing source code into an AST.
  • escodegen is responsible for generating source from modified AST.

The tree is modified by transformations, which each traverse the entire tree. Properties starting with $ are for saving information (typically circular data), these properties are deleted before output.

js-confuser's People

Contributors

michaelxf avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

js-confuser's Issues

avoid renaming multiple variables

Hello,

To avoid renaming a certain variable with the example is

renameVariables: name=>name!="jQuery",

Can you provide sample for multiple variables to avoid rename ?

String Concealing breaks class constructor

Describe the bug:

String Concealing breaks class constructor

Config and Small code sample

Config:

{
  target: "node",
  stringConcealing: true
}

Code:

class MyClass1 {}
class MyClass2 extends MyClass1 {
  constructor(){
    super();
    this["string1"] = true;
    this["string2"] = true;
    this["string3"] = true;
  }
}

var instance = new MyClass2();

Error:

(node:16224) UnhandledPromiseRejectionWarning: ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor

Object Extraction breaks objects with getter/setter methods

Describe the bug:

Object Extraction breaks the program containing objects with a getter/setter method.

Config and Small code sample

Config:

{
  target: "node",
  objectExtraction: true
}

Code:

var myObject = {
  get key(){
    return 10;
  }
}

console.log(myObject.key); // 10

Expected behavior

The program should output "10"

Actual behavior

var myObject_key = function () {
  return 10;
};
console["log"](myObject_key); // [Function: myObject_key]

The program outputs "[Function: myObject_key]"

Additional context

Object Extraction should not apply to objects with special property kinds.

Object Extraction throws error "Cannot read property 'name' of undefined"

Describe the bug:

Object Extraction throws an error while encountering a spread element node

Config and Small code sample

Config:

{
  target: "node",
  objectExtraction: true
}

Code:

var x = { firstName: "John", lastName: "Doe" }
var y = { ...x };

console.log(y);

Error:

TypeError: Cannot read property 'name' of undefined

TypeError

Describe the bug:

TypeError: Cannot read properties of null (reading 'type')

Config and Small code sample

Too Big

Code:

Too big can't upload

Expected behavior

The Program should be obfuscated successfully

Actual behavior

Not Obfusacting

BigInt literals are converted to normal numbers

Describe the bug:

BigInt literals (like 1n) are converted to normal numbers (1).

Config and Small code sample

Config:

{
    "compact": true,
    "hexadecimalNumbers": true,
    "identifierGenerator": "randomized",
    "minify": true,
    "shuffle": "false",
    "target": "browser"
}

Code:

console.log(1n);

Expected behavior

Compiles to console.log(1n)

Actual behavior

Compiles to console.log(1)

Control Flow Flattening breaks strict-mode redefined function declaration

Config and Small code sample

Config:

{
  target: "node",
  controlFlowFlattening: true
}

Code:

"use strict";
var myFunction = function () {
  console.log("Inner");
};

if (true) {
  function myFunction() {
    console.log("Outer");
  }
}

myFunction();

Expected behavior

The program should output "Inner"

Actual behavior

The program outputs "Outer"

Minify breaks Object constructor

Describe the bug:

Minify breaks Object constructor

Config and Small code sample

Config:

{
  target: "node",
  minify: true
}

Code:

var MyClass = function(){};

var myObject = new MyClass();

Output:

var MyClass=()=>{},myObject=new MyClass

Error:

(node:44533) UnhandledPromiseRejectionWarning: TypeError: MyClass is not a constructor

Minify wants to convert the function to an arrow function, which breaks the new expression.

return in a switch case

Describe the bug:

Using a return statement in a switch case causes a compilation error.

Config and Small code sample

Config:

{
  target: "node",
  preset: "high"
}

Code:

function() {
    switch (1) {
        case 0:
            return;
    }
}

Expected behavior

Successful obfuscation.

Actual behavior

Obfuscation fails with SyntaxError: Unexpected token (1:8).

options.minify bug

use minify.test.ts

var code = function greet(){ if(true){ console.log("return"); return; } var output = "should not show!"; console.log(output); } greet();

options = { target: "browser", minify: true }

output code:

var greet=()=>{if(!0){console.log('return')}var output='should not show';console.log(output)};greet()

The return in the if statement is removed

shuffle != hash is re-using variable x and crashing

Describe the bug:

One of the shuffle variants (for shuffle != hash) is re-using the variables x, z and i.
If they are present before (very likely), it'll compile to invalid JS code.

Config and Small code sample

Code:

let x = -999;
let a = [1, 2, 3, 4, 5, 6];

Expected behavior

Should run.

Actual behavior

Uncaught SyntaxError: Identifier 'x' has already been declared when running.

let x = -999;
let a = [
    2,
    3,
    4,
    5,
    6,
    1
];
var __p_6792745382 = a;
for (var x = 16; x % 4 === 0; x++) {
    var z = 0;
    a = __p_6792745382 = __p_6792745382.concat(function () {
        z++;
        if (z === 1) {
            return [];
        }
        for (var i = 20; i; i--) {
            __p_6792745382.unshift(__p_6792745382.pop());
        }
        return [];
    }());
}
for (var __p_4040364912 = 13; __p_4040364912; __p_4040364912--) {
    __p_6792745382.unshift(__p_6792745382.pop());
}

Control Flow Flattening breaks import statement

Describe the bug:

Control Flow Flattening breaks import statement

Config and Small code sample

Config:

{
  target: "node",
  preset: "high"
}

Code:

import { createHash } from 'node:crypto'

function sha256(content) {  
  return createHash('sha256').update(content).digest('hex')
}

console.log(sha256("Hash this string"));

Output:

function sJbFSiU(sJbFSiU) {
    return createHash('sha256')['update'](sJbFSiU)['digest']('hex');
}
var Q9E2KJx = { 'szuCPqW': 'node:crypto' }, brSMkQ = -53, O9PP06 = -42, UZzbiM = -17, QZSrnGc = 132;
while (brSMkQ + O9PP06 + UZzbiM + QZSrnGc != 16) {
    var eHzf2o = (brSMkQ + O9PP06 + UZzbiM + QZSrnGc) * -121 + -45;
    switch (eHzf2o) {
    case -2465:
        import { createHash } from Q9E2KJx['szuCPqW'];
        typeof (brSMkQ += -53 < O9PP06 ? 95 : 198, O9PP06 *= brSMkQ + (QZSrnGc + -172), O9PP06 -= UZzbiM + (brSMkQ + 83), UZzbiM *= 37 > QZSrnGc ? 32 : 2, UZzbiM -= 35 > QZSrnGc ? 118 < brSMkQ ? 131 : 171 : -199, QZSrnGc += O9PP06 + 76);
        break;
    case -3796:
        !(console['log'](sJbFSiU('Hash this string')), brSMkQ += brSMkQ + -81, O9PP06 *= 33 > QZSrnGc ? 2 : -192, O9PP06 -= -82 < O9PP06 ? 153 : -121, UZzbiM *= O9PP06 + 298 < O9PP06 ? QZSrnGc + -251 : 2, UZzbiM -= UZzbiM + -206, QZSrnGc *= 152 > QZSrnGc ? 2 : 157, QZSrnGc -= QZSrnGc + -202 > UZzbiM ? 161 > brSMkQ ? 122 : 144 : -38);
        break;
    }
}

Error:

      import { createHash } from Q9E2KJx['szuCPqW'];
             ^

SyntaxError: Unexpected token '{'

Anti Tooling breaks Symbols

Describe the bug:

Anti Tooling breaks Symbols

Config and Small code sample

Config:

{
  target: "node",
  preset: "low"
}

Code:

var sym1 = Symbol();

sym1;
sym1;

Output:

var sym1=Symbol();+(sym1,sym1)

Error:

(node:32216) UnhandledPromiseRejectionWarning: TypeError: Cannot convert a Symbol value to a number

The Anti Tooling feature combines expressions and chooses a random unary operator (void, typeof, -, !, +, or ~) which can cause errors with symbols. Anti Tooling, which currently has no option to be turned off, should not use unary operators that perform numeric conversions to avoid this error from occuring. The other operators work correctly.

Rename Variables breaks import statement

Describe the bug:

Rename Variables breaks import statement

Config and Small code sample

Config:

{
  target: "node",
  renameVariables: true
}

Code:

import { createHash } from 'node:crypto'

function sha256(content) {  
  return createHash('sha256').update(content).digest('hex')
}

console.log(sha256("Hash this string"));

Output:

import { hry1E0 } from "node:crypto";
function rwArBvq(rwArBvq) {
  return hry1E0("sha256")["update"](rwArBvq)["digest"]("hex");
}
console["log"](rwArBvq("Hash this string"));

Error:

import { hry1E0 } from "crypto";
         ^^^^^^
SyntaxError: The requested module 'crypto' does not provide an export named 'hry1E0'

String concealing bug

Code:

var code = 'var TEST_STRING = `Hello World`;console.log(TEST_STRING);';
var output = await JsConfuser(code, {
        target: "browser",
        stringCompression: true,
        stringEncoding: true,
        stringSplitting: true,
        stringConcealing: true,

    });
expect(output).not.toContain("Hello World");

Actual behavior

Error: expect(received).not.toContain(expected) // indexOf
Expected substring: not "Hello World"

Question: String splitting

The string splitting is really useful, I actually need to hide a link but any of the string obfuscations methods works on it except string splitting, the issue I face is that string splitting breaks part of my code, this is why I would like to know if would be possible to select strings you want to split !

jsconfuser.com down

I think you need to renew it.(its OK if you dont want to, but wanted to let you know)

Dispatcher causes syntax error

Describe the bug:

Dispatcher breaks code that calls toString() and causes a syntax error

Config and Small code sample

Config:

{
  target: "node",
  dispatcher: true
}

Code:

function myFunction(){
    
}

console.log(toString());

Output:

var ZBMWuM = Object.create(null);
var hSR25k = [];
console['log'](new Uf6LgH(function toString() { [native code] }, 'bVTWgeH', 'dq4mH64').P9dYcG);
function Uf6LgH(Uf6LgH, L2edNvN, LyXMkF) {
    var quyW4n5 = {
        'YjEq1X': function () {
        }
    };
    var pCawCBp;
    if (L2edNvN == 'bVTWgeH') {
        hSR25k = [];
    }
    if (L2edNvN == 'McemI0C') {
        pCawCBp = ZBMWuM[Uf6LgH] || (ZBMWuM[Uf6LgH] = function (...iUqjNIT) {
            hSR25k = iUqjNIT;
            return quyW4n5[Uf6LgH].call(this, 'bEANo3');
        });
    } else {
        pCawCBp = quyW4n5[Uf6LgH]('ga3lyI');
    }
    if (LyXMkF == 'dq4mH64') {
        return { P9dYcG: pCawCBp };
    } else {
        return pCawCBp;
    }
}

Notice the function toString() { [native code] } This is most likely due to Dispatcher using a normal object as a dictionary to map old function names to new function names, which causes generic names like toString and hasOwnProperty to get mapped incorrectly.

Eval and Integrity break the program

Describe the bug:

When Integrity and Eval are enabled together, the obfuscated output leads to a reference error.

Config and Small code sample

Config:

{
  target: "node",
  compact: false,
  eval: true,
  lock: {
    integrity: true,
  },
}

Code:

console.log("Hello World")

Output:

var __p_2990862662 = eval('(function (x) {\n    return x.toString().replace(/ |\\n|;|,|\\{|\\}|\\(|\\)|\\.|\\[|\\]/g, \'\');\n})');
var __p_3728583740 = eval('(function (str, seed) {\n    var h1 = 3735928559 ^ seed;\n    var h2 = 1103547991 ^ seed;\n    for (var i = 0, ch; i < str.length; i++) {\n        !(ch = str.charCodeAt(i), h1 = __p_9764543032(h1 ^ ch, 2654435761), h2 = __p_9764543032(h2 ^ ch, 1597334677));\n    }\n    void (h1 = __p_9764543032(h1 ^ h1 >>> 16, 2246822507) ^ __p_9764543032(h2 ^ h2 >>> 13, 3266489909), h2 = __p_9764543032(h2 ^ h2 >>> 16, 2246822507) ^ __p_9764543032(h1 ^ h1 >>> 13, 3266489909));\n    return 4294967296 * (2097151 & h2) + (h1 >>> 0);\n})');
(function () {
    var __p_9764543032 = Math.imul || eval('(function (opA, opB) {\n    opB |= 0;\n    var result = (opA & 4194303) * opB;\n    if (opA & 4290772992)\n        result += (opA & 4290772992) * opB | 0;\n    return result | 0;\n})');
    function PvW0AzX() {
        console['log'](100);
    }
    var O4fIeB = __p_3728583740(__p_2990862662(PvW0AzX), 907);
    if (O4fIeB == 1092823693876754) {
        return PvW0AzX.apply(this, arguments);
    } else {
        process.exit();
    }
}());

The error:

ReferenceError: __p_9764543032 is not defined

RGF breaks countermeasures function and causes error

Describe the bug:

You can't have a countermeasures function and RGF enabled at the same time.

Config and Small code sample

Config:

{
  target: "node",
  rgf: true,
  lock: {
    countermeasures: "myCountermeasuresFunction",
  },
}

Code:

function myCountermeasuresFunction() {
  console.log("The countermeasures function was called!");
}

Output

(node:21475) UnhandledPromiseRejectionWarning: Error: Countermeasures function named 'myCountermeasuresFunction' was not found.

Minify causes syntax error

Describe the bug:

Minify causes syntax error

Config and Small code sample

Config:

{
  target: "node",
  minify: true
}

Code:

var myObject = {
  "`": true,
  "^": true,
  "]": true,
  "[": true
}

Output:

var myObject = {
    `: !0,
    ^: !0,
    ]: !0,
    [: !0
};

export function isValidIdentifier(name: string): boolean {
if (typeof name !== "string") {
return false;
}
if (name.includes(".") || name.includes(" ")) {
return false;
}
var x = name.match(/^[A-z$_][A-z0-9$_]*/);
return x && x[0] == name;
}

The regex includes char codes 65 to 122 which is incorrect. It should use A-Za-z instead.

default in a switch case

Describe the bug:

Compilation failure.

Config and Small code sample

Config:

{
  target: "node",
  preset: "high"
}

Code:

switch (0) {
    default:
         console.log("hi");
}

Expected behavior

Successful compilation.

Actual behavior

Compilation error with TypeError: Cannot read properties of null (reading 'type').

Name Recycling and String Compression breaks code

Describe the bug:

Name Recycling and String Compression breaks code

Config and Small code sample

Config:

{
  target: "node",
  nameRecycling: true,
  stringCompression: true,
  renameVariables: false,
}

Code:

console.log("Hello World");

Error

(node:17892) UnhandledPromiseRejectionWarning: ReferenceError: __p_8057609245 is not defined

Use hexadecimal representation for numbers

Javascript-Obfuscator (and many other obfuscators as well) does this, Js-confuser should do it too.

// Input
var integer = 10;
var negativeInteger = -10;
var float = 10.1;
var negativeFloat = -10.1;

// Output
var integer = 0xa;
var negativeInteger = -0xa;
var float = 10.1;
var negativeFloat = -10.1;

Notice how only integers get converted.

invalid typings for options

Type defs:

js-confuser/src/options.ts

Lines 456 to 605 in 64a5f6a

lock?: {
/**
* ### `lock.selfDefending`
*
* Prevents the use of code beautifiers or formatters against your code.
*
* [Identical to Obfuscator.io's Self Defending](https://github.com/javascript-obfuscator/javascript-obfuscator#selfdefending)
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
selfDefending?: boolean;
/**
* ### `lock.antiDebug`
*
* Adds `debugger` statements throughout the code. Additionally adds a background function for DevTools detection. (`true/false/0-1`)
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
antiDebug?: ProbabilityMap<boolean>;
/**
* ### `lock.context`
*
* Properties that must be present on the `window` object (or `global` for NodeJS). (`string[]`)
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
context?: string[];
/**
* ### `lock.nativeFunctions`
*
* Set of global functions that are native. Such as `require`, `fetch`. If these variables are modified the program crashes.
* Set to `true` to use the default set of native functions. (`string[]/true/false`)
*
* - Potency Low
* - Resilience Medium
* - Cost Medium
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
nativeFunctions?: string[] | Set<string> | boolean;
/**
* ### `lock.startDate`
*
* When the program is first able to be used. (`number` or `Date`)
*
* Number should be in milliseconds.
*
* - Potency Low
* - Resilience Medium
* - Cost Medium
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
startDate?: number | Date | false;
/**
* ### `lock.endDate`
*
* When the program is no longer able to be used. (`number` or `Date`)
*
* Number should be in milliseconds.
*
* - Potency Low
* - Resilience Medium
* - Cost Medium
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
endDate?: number | Date | false;
/**
* ### `lock.domainLock`
* Array of regex strings that the `window.location.href` must follow. (`Regex[]` or `string[]`)
*
* - Potency Low
* - Resilience Medium
* - Cost Medium
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
domainLock?: RegExp[] | string[] | false;
/**
* ### `lock.osLock`
* Array of operating-systems where the script is allowed to run. (`string[]`)
*
* - Potency Low
* - Resilience Medium
* - Cost Medium
*
* Allowed values: `"linux"`, `"windows"`, `"osx"`, `"android"`, `"ios"`
*
* Example: `["linux", "windows"]`
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
osLock?: ("linux" | "windows" | "osx" | "android" | "ios")[] | false;
/**
* ### `lock.browserLock`
* Array of browsers where the script is allowed to run. (`string[]`)
*
* - Potency Low
* - Resilience Medium
* - Cost Medium
*
* Allowed values: `"firefox"`, `"chrome"`, `"iexplorer"`, `"edge"`, `"safari"`, `"opera"`
*
* Example: `["firefox", "chrome"]`
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
browserLock?:
| ("firefox" | "chrome" | "iexplorer" | "edge" | "safari" | "opera")[]
| false;
/**
* ### `lock.integrity`
*
* Integrity ensures the source code is unchanged. (`true/false/0-1`)
*
* [Learn more here](https://github.com/MichaelXF/js-confuser/blob/master/Integrity.md).
*
* - Potency Medium
* - Resilience High
* - Cost High
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
integrity?: ProbabilityMap<boolean>;
/**
* ### `lock.countermeasures`
*
* A custom callback function to invoke when a lock is triggered. (`string/false`)
*
* This could be due to an invalid domain, incorrect time, or code's integrity changed.
*
* [Learn more about the rules of your countermeasures function](https://github.com/MichaelXF/js-confuser/blob/master/Countermeasures.md).
*
* Otherwise, the obfuscator falls back to crashing the process.
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
countermeasures?: string | boolean;
};

Assertion stmts:

js-confuser/src/options.ts

Lines 772 to 823 in 64a5f6a

// Validate browser-lock option
if (typeof options.lock.browserLock !== "undefined") {
ok(
Array.isArray(options.lock.browserLock),
"browserLock must be an array"
);
ok(
!options.lock.browserLock.find(
(browserName) => !validBrowsers.has(browserName)
),
'Invalid browser name. Allowed: "firefox", "chrome", "iexplorer", "edge", "safari", "opera"'
);
}
// Validate os-lock option
if (typeof options.lock.osLock !== "undefined") {
ok(Array.isArray(options.lock.osLock), "osLock must be an array");
ok(
!options.lock.osLock.find((osName) => !validOses.has(osName)),
'Invalid OS name. Allowed: "windows", "linux", "osx", "ios", "android"'
);
}
// Validate domain-lock option
if (typeof options.lock.domainLock !== "undefined") {
ok(Array.isArray(options.lock.domainLock), "domainLock must be an array");
}
// Validate context option
if (typeof options.lock.context !== "undefined") {
ok(Array.isArray(options.lock.context), "context must be an array");
}
// Validate start-date option
if (
typeof options.lock.startDate !== "undefined" &&
options.lock.startDate
) {
ok(
typeof options.lock.startDate === "number" ||
options.lock.startDate instanceof Date,
"startDate must be Date object or number"
);
}
// Validate end-date option
if (typeof options.lock.endDate !== "undefined" && options.lock.endDate) {
ok(
typeof options.lock.endDate === "number" ||
options.lock.endDate instanceof Date,
"endDate must be Date object or number"
);
}
}

booleans (or false) are specified as valid values for some of the keys in the typedefs however there are assertion statements that will error out when it doesn't receive anything other than an array.

Name Recycling breaks import statement

Describe the bug:

Name Recycling breaks import statement

Config and Small code sample

Config:

{
  target: "node",
  nameRecycling: true,
}

Code:

import crypto from 'node:crypto'

var x = 1;

console.log(x);

Output:

import OuWqJ3u from "node:crypto";
OuWqJ3u = 1;
console["log"](OuWqJ3u);

Error:

OuWqJ3u = 1;
        ^

TypeError: Assignment to constant variable.

Control Flow Flattening breaks typeof expression

Describe the bug:

Control Flow Flattening breaks typeof expression

Config and Small code sample

Config:

{
  target: "node",
  controlFlowFlattening: true
}

Code:

console.log(1); // 1
typeof a; // "undefined"

Output:

typeof (console['log'](1), a);
// Uncaught ReferenceError: a is not defined

The typeof expression is special because when checking a single Identifier node, there will not be an error thrown, even if the variable doesn't exist. This only applies on Identifier nodes, when joined in a sequence expression it will error. The fix is to make Control Flow Flattening not change typeof expressions.

invalid generated js for `(a ?? {}) && ""`

Describe the bug:

Compiles invalid JS

Config and Small code sample

Config:

{
  target: "node",
  preset: "high"
}

Code:

(a ?? {}) && ""

Expected behavior

Compiles to (a??{})&&''

Actual behavior

Compiles to a??{}&&'' which is invalid.

Catch parameter and lexically defined variable

Describe the bug:

Rename Variable fails in the following situation

Code:

try {

} catch (a){
    let b;
} 

Output:

try{}catch(I2W3L20){let I2W3L20}

Error:

(node:17661) UnhandledPromiseRejectionWarning: SyntaxError: Identifier 'I2W3L20' has already been declared

TypeError: Cannot read properties of null (reading 'type')

Describe the bug:

I'm getting TypeError: Cannot read properties of null (reading 'type')

Config and Small code sample

Config:

{
  target: "node",
  preset: "high"
}

Code:

can't post it there, too big

Expected behavior

The program should execute the code correctly

Actual behavior

C:\Users\xxxxxxxxx\Downloads\xxxxxxxxxxxxxxxxxr\Priv\node_modules\js-confuser\dist\transforms\opaquePredicates.js:139
        if (test.type == "Literal") {
                 ^

TypeError: Cannot read properties of null (reading 'type')
    at C:\Users\xxxxxxxxxxx\Downloads\xxxxxxxxxxxxxx\Priv\node_modules\←[4mjs-confuser←[24m\dist\transforms\opaquePredicates.js:139:18
    at C:\Users\xxxxxxxxxxxxxx\Downloads\xxxxxxxxxxxxxx\Priv\node_modules\←[4mjs-confuser←[24m\dist\transforms\transform.js:144:42
    at Array.forEach (<anonymous>)
    at C:\Users\xxxxxxxxxxxxxx\Downloads\xxxxxxxxxxxxxx\Priv\node_modules\←[4mjs-confuser←[24m\dist\transforms\transform.js:144:24
    at walk (C:\Users\xxxxxxxxxxxxxx\Downloads\xxxxxxxxxxxxxx\Priv\node_modules\←[4mjs-confuser←[24m\dist\traverse.js:89:7)
    at walk (C:\Users\xxxxxxxxxxxxxx\Downloads\xxxxxxxxxxxxxx\Priv\node_modules\←[4mjs-confuser←[24m\dist\traverse.js:65:13)
    at walk (C:\Users\xxxxxxxxxxxxxx\Downloads\xxxxxxxxxxxxxx\Priv\node_modules\←[4mjs-confuser←[24m\dist\traverse.js:76:15)
    at walk (C:\Users\xxxxxxxxxxxxxx\Downloads\xxxxxxxxxxxxxx\Priv\node_modules\←[4mjs-confuser←[24m\dist\traverse.js:76:15)
    at walk (C:\Users\xxxxxxxxxxxxxx\Downloads\xxxxxxxxxxxxxx\Priv\node_modules\←[4mjs-confuser←[24m\dist\traverse.js:65:13)
    at walk (C:\Users\xxxxxxxxxxxxxx\Downloads\xxxxxxxxxxxxxx\Priv\node_modules\←[4mjs-confuser←[24m\dist\traverse.js:76:15)

Defining the same variable multiple times

Describe the bug:

Defining the same variable multiple times (has already been declared)

Config and Small code sample

Config:

{
  target: "node",
  preset: "high"
}

Code:

can't post it there, too big

Expected behavior

The program should execute the code correctly

Actual behavior

The program simply return an error, "SyntaxError: Identifier 'xxxxxxxx$xxxxxxxx' has already been declared"

Control Flow Flattening breaks nested redefined function declaration

Config and Small code sample

Config:

{
  target: "node",
  controlFlowFlattening: true
}

Code:

if (true) {
  function myFunction() {
    console.log("Top Function Declaration");
  }

  function myFunction() {
    console.log("Bottom Function Declaration");
  }
}

var filler;

myFunction(); // "Bottom Function Declaration"

Expected behavior

The program should output "Bottom Function Declaration"

Actual behavior

The program outputs "Top Function Declaration"

ES5 fails on class fields

Describe the bug:

The es5 option errors when class fields are encountered

Config and Small code sample

Config:

{
  target: "node",
  es5: true,
}

Code:

class MyClass {
  myField = 1;
}

Error:

Node {
  type: 'PropertyDefinition',
  start: 23,
  end: 35,
  static: false,
  computed: false,
  key: Node { type: 'Identifier', start: 23, end: 30, name: 'myField' },
  value: Node { type: 'Literal', start: 33, end: 34, value: 1, raw: '1' }
}
(node:4288) UnhandledPromiseRejectionWarning: Error: Unsupported method definition

Flatten breaks code with pattern-based assignment expressions

Describe the bug:

Flatten breaks working code when pattern-based assignment expressions are involved.

Config and Small code sample

Config:

{
  target: "node",
  flatten: true,
  compact: false
}

Code:

var i = 0;

function change() {
  [([i] = [1])];
}
  
change();
console.log(i);

Expected behavior

The program should output 1

Actual behavior

The program outputs 0

deconstructuring in for loop

Describe the bug:

It does not compile

Config and Small code sample

Config:

{
  target: "node",
  preset: "high"
}

Code:

// any of these will trigger the error, minimal reproduction example
for(const [] of []) {}
for(const {} of []) {}
for(const [] in []) {}
for(const {} in []) {}

Expected behavior

Should compile.

Actual behavior

Does not compile: TypeError: Cannot read properties of null (reading 'type')

Question: direct run support in browser.

Hi Michael, love this project so much. Got trouble using this repo however, idk if I can do some demo code testing in a bare browser environment. What I did was to first install with npm install js-confuser, and then created a test.js file with the following content:

var JsConfuser = require("js-confuser");

JsConfuser.obfuscate(`
  function fibonacci(num){   
    var a = 0, b = 1, c = num;
    while (num-- > 1) {
      c = a + b;
      a = b;
      b = c;
    }
    return c;
  }

  for ( var i = 1; i <= 25; i++ ) {
    console.log(i, fibonacci(i))
  }
`, {
  target: "browser",
  preset: "high",
  stringEncoding: false, // <- Normally enabled
}).then(obfuscated => {
  console.log(obfuscated)
})

Then I do node test.js > test.txt and finally copy the full content from test.txt and try to paste those codes in Chrome‘s debugging tools and try to make it work. However I got a VM1313:1 Uncaught TypeError: hLcB7T1[NpWOyTI] is not a function error. It looks like I'm doing it all wrong, I'd like to ask if there's any quick start docs for help, thanks.

Control Flow Flattening breaks function declaration in non-executed switch case block

Config and Small code sample

Config:

{
  target: "node",
  controlFlowFlattening: true
}

Code:

switch (true) {
  case false:
    function myFunction() { // This block is never ran, but declaration is still able to be called
      console.log("Hello World!");
    }
    break;

  case true:
    myFunction();
    break;
}

var filler1;
var filler2;
// "Hello World"

Expected behavior

The program should output "Hello World"

Actual behavior

TypeError: (intermediate value)(intermediate value) is not a function

Windows Defender

Describe the bug:

image
image

Config and Small code sample

Config:

{
  target: "node",
  preset: "high"
}

Code:

var affect = 0;
class MyClass{
  constructor(){
    affect = 1;
  }
}

var instance = new MyClass();
console.log(affect)

Sample of Trojan:JS/Foretype.A!ml

var gSLAwMP,e_Izy_w,T5fIY1h,PEagBXy,EddB3Qq,hCj_Dfk,lJFJ64f=[0,8,104,9,10,3,243,136,void 0,22,6,275,282,1,2,60,208,18,68,249,165,346,81,186,196,4,178,284,13,158,56,102,402,17,19,483,25,26,93,194,24,184,197,49,20,238,14,15,108,103,139,169,30,28,255,33,5,85,16,185,298,228,411,217,248,62,293,45];function LxVvRh(gSLAwMP){return lJFJ64f[gSLAwMP-49]}~(gSLAwMP=DKJuJH('\x3c\x7e\x3d\x26\x57\x2b\x22\x32\x67\x2d\x6d\x21\x46\x59\x63\x51\x5c\x7e\x3e\x31Ā\x32\x49\x70\x3b\x6a\x3a\x69\x6cđ\x31\x2b\x26\x2c\x35\x39\x3f\x24\x24\x2a\x3e\x26\x35\x3f\x31\x2e\x2a\x3d\x36\x27\x3b\x33\x28\x30\x26\x23\x28\x25\x3a\x3c\x38ē\x7e\x3a\x65\x22\x41\x5c\x35\x72\x45\x30ĝĀ\x37\x21\x4d\x30\x6c\x42\x34\x61\x61\x6f\x3b\x29\x55\x6d\x61\x33\x41\x43ĝħ\x29\x37\x35\x2d\x2c\x26\x2b\x25Ľ\x37\x3c\x33\x45\x65\x45\x57ň\x7e\x38\x6c\x4a\x4dĐĒ\x2d\x2e\x35\x27\x23\x3d\x33\x24\x2e\x3dĽ\x41\x37\x5c\x26\x4bŮ\x46\x2a\x29\x47\x3a\x44\x4a\x26Ů\x38\x54\x26\x5d\x5b\x43\x68\x5b\x45\x26Ɓ\x39\x51ĝ\x2d\x32\x33\x37\x29\x29\x22\x29\x2e\x3a\x38\x38Ƣ\x24\x35\x30ťĀ\x45\x2b\x4c\x2f\x35\x46\x45\x32\x29\x35\x42\x2e\x33ƏƑƓƕŭĒĀ\x41\x30\x3e\x44\x6b\x46\x43\x3eĝ\x2f\x2aƨ\x2d\x3b\x2c\x25\x2d\x35ĽƵ\x6fŋƵ\x2eŮ\x42\x6c\x37\x51\x34ĝ\x2e\x26\x3eŹ\x3eĦžĽ\x45\x5a\x65\x74\x34ǫ\x62Ůƚ\x52\x67\x2b\x3d\x40Ǣ\x32\x38\x37\x2f\x31\x64\x65\x41\x74\x31\x20\x6b\x65\x79\x20\x70Ǿ\x20\x28\x65\x6dȉ\x66\x72\x6f\x6dƕ\x61\x72\x43\x6fǿ\x31\x61\x70\x70\x6c\x79\x31\x6c\x65\x6e\x67\x74\x68\x31\x63\x68ȕȗǿȁ\x31\x73\x6c\x69\x63\x65\x31\x72\x65ȝ\x61Ȳ\x31\x21ȻȻ\x31\x75ȿȿ'),e_Izy_w=[],T5fIY1h=['\x3c\x7e\x42\x6a\x22\x4f\x6d\x3d\x5c\x31\x3b\x3f\x3d\x5f\x4c\x74\x6f\x3a\x5d\x7e\x3e',H7XykPx(LxVvRh(49)),H7XykPx(1),H7XykPx(LxVvRh(63)),'\x2d\x35\x3c\x34\x25\x3e\x34\x2e\x29\x2e\x2c\x37\x2f\x2d\x2c\x31\x2f\x22\x3a\x31',H7XykPx(LxVvRh(54)),H7XykPx(LxVvRh(74)),H7XykPx(LxVvRh(105)),H7XykPx(LxVvRh(59)),H7XykPx(7),'\u003c\u007e\u0047\u0041\u0031\u0072\u002a\u0044\u0067\u0029\u007e\u003e',H7XykPx(LxVvRh(50)),'\u002d\u002e\u0038\u0037\u003d\u003d\u003c\u0030\u002e\u0031',H7XykPx(LxVvRh(52)),H7XykPx(LxVvRh(53)),H7XykPx(11),H7XykPx(12),'\x2d\x25\x31\x27\x37\x3a\x2c\x3a\x25\x22\x39\x28\x25\x3c\x3c\x37\x2e\x25',H7XykPx(LxVvRh(77)),H7XykPx(LxVvRh(95)),H7XykPx(LxVvRh(96)),H7XykPx(LxVvRh(107)),H7XykPx(LxVvRh(82)),H7XykPx(18),H7XykPx(LxVvRh(83)),'\x2b\x2e\x33\x38\x25\x3b\x2c\x22\x2e\x31',H7XykPx(20),'\u003c\u007e\u0044\u0042\u004e\u004d\u0032\u0045\u0063\u0031\u007e\u003e',H7XykPx(21),H7XykPx(22),H7XykPx(23)],PEagBXy={GjSQoQ:[],LJbwud:function(){if(!PEagBXy.GjSQoQ[LxVvRh(49)]){PEagBXy.GjSQoQ.push(9)}return PEagBXy.GjSQoQ.length},cWu3FK:LxVvRh(66),rmY0jRb:59,rIQT8Uv:iOqQJH(LxVvRh(50))});function Y2aTbT(){try{return global}catch(gSLAwMP){return this}}EddB3Qq=Y2aTbT.call(this);function _I6xtc(...gSLAwMP){var e_Izy_w=gSLAwMP=>lJFJ64f[gSLAwMP+107];~(gSLAwMP.length=e_Izy_w(-94),gSLAwMP[LxVvRh(51)]=gSLAwMP[LxVvRh(49)]);switch(gSLAwMP[e_Izy_w(-105)]){case-e_Izy_w(-75):return EddB3Qq[Ejf7Q4(e_Izy_w(-104))];case PEagBXy.LJbwud()?879:-LxVvRh(73):return EddB3Qq[Ejf7Q4(e_Izy_w(-103))];case!PEagBXy.LJbwud()?202:363:return EddB3Qq[Ejf7Q4(11)];case!PEagBXy.LJbwud()?e_Izy_w(-99):-LxVvRh(100):return EddB3Qq[iOqQJH(12)+'\u0065']}}function kSudPk(...gSLAwMP){var e_Izy_w=gSLAwMP=>lJFJ64f[gSLAwMP-191];+(gSLAwMP.length=e_Izy_w(196),gSLAwMP[e_Izy_w(197)]=LxVvRh(78),gSLAwMP[gSLAwMP[gSLAwMP[e_Izy_w(197)]-(gSLAwMP[LxVvRh(55)]-e_Izy_w(197))]-155]=gSLAwMP[LxVvRh(49)]*-72-211,gSLAwMP[gSLAwMP[e_Izy_w(197)]-LxVvRh(56)]=210);switch(gSLAwMP[gSLAwMP[gSLAwMP[LxVvRh(58)]+33]-(gSLAwMP[gSLAwMP[243]-(gSLAwMP[gSLAwMP[243]-e_Izy_w(198)]-74)]-55)]){case!PEagBXy.LJbwud()?LxVvRh(57):-34987:return gSLAwMP[1]+gSLAwMP[gSLAwMP[gSLAwMP[gSLAwMP[LxVvRh(55)]-(gSLAwMP[e_Izy_w(197)]-22)]-(gSLAwMP[LxVvRh(58)]-22)]-(gSLAwMP[LxVvRh(55)]-(gSLAwMP[gSLAwMP[22]+LxVvRh(104)]-e_Izy_w(207)))]}}function L11Uy2(...gSLAwMP){var e_Izy_w,T5fIY1h;function EddB3Qq(gSLAwMP){return lJFJ64f[gSLAwMP-203]}!(gSLAwMP.length=EddB3Qq(203),gSLAwMP[111]=gSLAwMP[2],e_Izy_w=219,T5fIY1h=-217,gSLAwMP[LxVvRh(51)]=-171);while(e_Izy_w+T5fIY1h!=EddB3Qq(239)&&PEagBXy.cWu3FK>EddB3Qq(213)){var hCj_Dfk=gSLAwMP=>LxVvRh(gSLAwMP-191);gSLAwMP[gSLAwMP[gSLAwMP[104]+EddB3Qq(214)]+LxVvRh(61)]=(e_Izy_w+T5fIY1h)*(gSLAwMP[LxVvRh(51)]+329)-214;switch(gSLAwMP[gSLAwMP[gSLAwMP[LxVvRh(51)]+LxVvRh(60)]+EddB3Qq(215)]){case!(PEagBXy.cWu3FK>LxVvRh(59))?gSLAwMP[104]+324:gSLAwMP[LxVvRh(51)]-(gSLAwMP[hCj_Dfk(242)]-(gSLAwMP[hCj_Dfk(242)]+1695)):~(DCbAaKi=gSLAwMP[gSLAwMP[gSLAwMP[EddB3Qq(205)]+275]+hCj_Dfk(251)]-(gSLAwMP[hCj_Dfk(242)]-LxVvRh(93))>e_Izy_w?gSLAwMP[gSLAwMP[LxVvRh(51)]+275]-(gSLAwMP[hCj_Dfk(242)]-44):hCj_Dfk(253),e_Izy_w*=-(gSLAwMP[104]-(gSLAwMP[LxVvRh(51)]-222))<T5fIY1h?LxVvRh(63):-213,e_Izy_w-=e_Izy_w-LxVvRh(113));break;case PEagBXy.rmY0jRb>-LxVvRh(64)?5948:-(gSLAwMP[EddB3Qq(205)]+172):e_Izy_w+=e_Izy_w-hCj_Dfk(267);break;case gSLAwMP[gSLAwMP[EddB3Qq(205)]-(gSLAwMP[hCj_Dfk(242)]-104)]+4855:return[DCbAaKi];case!(PEagBXy.rmY0jRb>-LxVvRh(64))?-(gSLAwMP[gSLAwMP[gSLAwMP[LxVvRh(51)]-(gSLAwMP[104]-LxVvRh(51))]+LxVvRh(60)]+352):gSLAwMP[gSLAwMP[EddB3Qq(205)]-(gSLAwMP[104]-LxVvRh(51))]+273:var [DCbAaKi]=this;e_Izy_w+=gSLAwMP[gSLAwMP[hCj_Dfk(242)]+EddB3Qq(214)]-(gSLAwMP[gSLAwMP[gSLAwMP[EddB3Qq(205)]+LxVvRh(60)]+hCj_Dfk(251)]-66)>e_Izy_w?-(gSLAwMP[104]+403):gSLAwMP[gSLAwMP[hCj_Dfk(242)]+EddB3Qq(214)]+LxVvRh(65)}}}var DCbAaKi=LxVvRh(49);class xhXldmy{constructor(...gSLAwMP){var e_Izy_w,T5fIY1h,EddB3Qq,hCj_Dfk,Y2aTbT;function xhXldmy(gSLAwMP){return lJFJ64f[gSLAwMP+112]}+(gSLAwMP.length=0,gSLAwMP[xhXldmy(-94)]=-181,e_Izy_w=-(gSLAwMP[68]+306),T5fIY1h=-LxVvRh(66),EddB3Qq=xhXldmy(-89),hCj_Dfk=140,Y2aTbT=-(gSLAwMP[68]-(gSLAwMP[gSLAwMP[xhXldmy(-94)]+LxVvRh(68)]-(gSLAwMP[LxVvRh(67)]+xhXldmy(-58)))),gSLAwMP[gSLAwMP[gSLAwMP[68]+xhXldmy(-93)]-(gSLAwMP[LxVvRh(67)]-(gSLAwMP[LxVvRh(67)]+xhXldmy(-91)))]=gSLAwMP[gSLAwMP[xhXldmy(-94)]+249]+427);while(e_Izy_w+T5fIY1h+EddB3Qq+hCj_Dfk+Y2aTbT!=gSLAwMP[xhXldmy(-94)]-(gSLAwMP[xhXldmy(-92)]-520)){function dyHuutR(gSLAwMP){return LxVvRh(gSLAwMP+140)}gSLAwMP[gSLAwMP[LxVvRh(69)]-241]=(e_Izy_w+T5fIY1h+EddB3Qq+hCj_Dfk+Y2aTbT)*-(gSLAwMP[gSLAwMP[xhXldmy(-92)]-LxVvRh(71)]-7)-(gSLAwMP[165]-(gSLAwMP[gSLAwMP[LxVvRh(67)]+LxVvRh(70)]-(gSLAwMP[LxVvRh(67)]+(gSLAwMP[gSLAwMP[165]-LxVvRh(71)]+67))));switch(gSLAwMP[gSLAwMP[gSLAwMP[dyHuutR(-73)]-(gSLAwMP[LxVvRh(67)]-68)]+xhXldmy(-89)]){case-25466:~(T5fIY1h*=gSLAwMP[xhXldmy(-94)]-(gSLAwMP[gSLAwMP[xhXldmy(-92)]-dyHuutR(-69)]-527)>T5fIY1h?dyHuutR(-77):(152>T5fIY1h?-(gSLAwMP[gSLAwMP[xhXldmy(-92)]-xhXldmy(-86)]+389):-(gSLAwMP[gSLAwMP[LxVvRh(67)]+dyHuutR(-70)]-(gSLAwMP[68]+376)))<EddB3Qq?-(gSLAwMP[gSLAwMP[dyHuutR(-73)]-(gSLAwMP[dyHuutR(-73)]-LxVvRh(67))]-(gSLAwMP[xhXldmy(-94)]-dyHuutR(-42))):gSLAwMP[gSLAwMP[xhXldmy(-92)]-178]+251<Y2aTbT?gSLAwMP[LxVvRh(67)]-(gSLAwMP[xhXldmy(-92)]-444):164,T5fIY1h-=gSLAwMP[165]-96<T5fIY1h?hCj_Dfk-153:-(gSLAwMP[xhXldmy(-92)]-102),e_Izy_w*=(20<e_Izy_w?gSLAwMP[xhXldmy(-92)]-LxVvRh(73):94)<Y2aTbT?gSLAwMP[68]+370:2,e_Izy_w-=e_Izy_w+39);break;case-(gSLAwMP[gSLAwMP[LxVvRh(67)]+LxVvRh(70)]+25937):typeof(e_Izy_w*=T5fIY1h+(gSLAwMP[xhXldmy(-94)]+201),e_Izy_w-=(LxVvRh(74)<EddB3Qq?-67:EddB3Qq-259)>e_Izy_w?gSLAwMP[165]-(gSLAwMP[gSLAwMP[165]-LxVvRh(75)]+273)>Y2aTbT?-163:-6:-xhXldmy(-67),Y2aTbT+=T5fIY1h+(-135>e_Izy_w?gSLAwMP[LxVvRh(69)]-(gSLAwMP[68]+dyHuutR(-30)):-(gSLAwMP[68]+xhXldmy(-85))>hCj_Dfk?gSLAwMP[gSLAwMP[dyHuutR(-73)]+dyHuutR(-72)]-(gSLAwMP[xhXldmy(-92)]-502):-(gSLAwMP[LxVvRh(67)]-(gSLAwMP[68]-97))));break;case PEagBXy.rIQT8Uv[iOqQJH(LxVvRh(77))+Ejf7Q4(gSLAwMP[dyHuutR(-73)]-(gSLAwMP[gSLAwMP[xhXldmy(-92)]-xhXldmy(-90)]-441))](gSLAwMP[dyHuutR(-73)]+xhXldmy(-71))==gSLAwMP[gSLAwMP[dyHuutR(-73)]+dyHuutR(-70)]-xhXldmy(-70)?-(gSLAwMP[68]-(gSLAwMP[gSLAwMP[dyHuutR(-71)]-xhXldmy(-90)]-39516)):null:void(EddB3Qq*=T5fIY1h+(gSLAwMP[gSLAwMP[165]-(gSLAwMP[dyHuutR(-71)]-165)]-(gSLAwMP[gSLAwMP[68]+dyHuutR(-72)]+407)),EddB3Qq-=EddB3Qq+(Y2aTbT+(gSLAwMP[gSLAwMP[xhXldmy(-94)]+249]-(gSLAwMP[165]-471))));break;case!(PEagBXy.rIQT8Uv[iOqQJH(gSLAwMP[68]+dyHuutR(-52))+H7XykPx(LxVvRh(89))](3)==dyHuutR(-48))?null:-10409:if(gSLAwMP[gSLAwMP[LxVvRh(67)]-(gSLAwMP[gSLAwMP[68]+xhXldmy(-91)]-437)]){function FcEfMx(...gSLAwMP){function e_Izy_w(gSLAwMP){return LxVvRh(gSLAwMP-53)}typeof(gSLAwMP.length=e_Izy_w(116),gSLAwMP[dyHuutR(-61)]=LxVvRh(78));if(typeof gSLAwMP[gSLAwMP[gSLAwMP[gSLAwMP[gSLAwMP[gSLAwMP[e_Izy_w(132)]-xhXldmy(-81)]-e_Izy_w(133)]-(gSLAwMP[xhXldmy(-82)]-xhXldmy(-82))]-(gSLAwMP[LxVvRh(79)]-(gSLAwMP[dyHuutR(-61)]-dyHuutR(-60)))]-158]!==Ejf7Q4(15)&&PEagBXy.rmY0jRb>-(gSLAwMP[LxVvRh(79)]-98)){function T5fIY1h(gSLAwMP){return xhXldmy(gSLAwMP+87)}throw new(_I6xtc(-dyHuutR(-59)))(Ejf7Q4(16)+iOqQJH(e_Izy_w(135))+iOqQJH(18)+Ejf7Q4(gSLAwMP[T5fIY1h(-169)]-(gSLAwMP[56]-LxVvRh(83))))}gSLAwMP[gSLAwMP[gSLAwMP[LxVvRh(79)]-xhXldmy(-81)]-(gSLAwMP[gSLAwMP[e_Izy_w(132)]-(gSLAwMP[56]-LxVvRh(79))]-dyHuutR(-53))]=gSLAwMP[gSLAwMP[gSLAwMP[e_Izy_w(132)]-(gSLAwMP[56]-LxVvRh(79))]-156];if(!gSLAwMP[gSLAwMP[gSLAwMP[gSLAwMP[xhXldmy(-82)]-(gSLAwMP[56]-56)]-(gSLAwMP[56]-LxVvRh(79))]-(gSLAwMP[dyHuutR(-61)]-xhXldmy(-112))]&&PEagBXy.rmY0jRb>-LxVvRh(64)){throw new(_I6xtc(-e_Izy_w(134)))(Ejf7Q4(20)+Ejf7Q4(gSLAwMP[gSLAwMP[e_Izy_w(132)]-LxVvRh(80)]-(gSLAwMP[LxVvRh(79)]-21))+H7XykPx(gSLAwMP[gSLAwMP[LxVvRh(79)]-e_Izy_w(133)]-133)+iOqQJH(22)+H7XykPx(xhXldmy(-75))+Ejf7Q4(23)+Ejf7Q4(gSLAwMP[xhXldmy(-82)]-134))}gSLAwMP[gSLAwMP[gSLAwMP[dyHuutR(-61)]-dyHuutR(-60)]-65]=_I6xtc(gSLAwMP[gSLAwMP[gSLAwMP[xhXldmy(-82)]-(gSLAwMP[dyHuutR(-61)]-e_Izy_w(132))]-(gSLAwMP[gSLAwMP[e_Izy_w(132)]-LxVvRh(80)]-56)]+721).localStorage.getItem(gSLAwMP[gSLAwMP[gSLAwMP[gSLAwMP[gSLAwMP[gSLAwMP[LxVvRh(79)]-dyHuutR(-60)]-102]-(gSLAwMP[xhXldmy(-82)]-(gSLAwMP[e_Izy_w(132)]-(gSLAwMP[xhXldmy(-82)]-xhXldmy(-82))))]-(gSLAwMP[gSLAwMP[xhXldmy(-82)]-LxVvRh(80)]-xhXldmy(-82))]-(gSLAwMP[e_Izy_w(132)]-e_Izy_w(102))]);try{gSLAwMP[gSLAwMP[gSLAwMP[gSLAwMP[gSLAwMP[LxVvRh(79)]-dyHuutR(-60)]-(gSLAwMP[e_Izy_w(132)]-56)]-(gSLAwMP[gSLAwMP[xhXldmy(-82)]-dyHuutR(-60)]-56)]-(gSLAwMP[gSLAwMP[56]-LxVvRh(80)]-93)]=_I6xtc(gSLAwMP[56]-(gSLAwMP[gSLAwMP[gSLAwMP[e_Izy_w(132)]-dyHuutR(-60)]-e_Izy_w(133)]-(gSLAwMP[56]-(gSLAwMP[gSLAwMP[e_Izy_w(132)]-e_Izy_w(133)]-363)))).parse(gSLAwMP[gSLAwMP[e_Izy_w(132)]-(gSLAwMP[gSLAwMP[gSLAwMP[dyHuutR(-61)]-dyHuutR(-60)]-(gSLAwMP[gSLAwMP[e_Izy_w(132)]-dyHuutR(-60)]-e_Izy_w(132))]-93)])}catch(EddB3Qq){function hCj_Dfk(gSLAwMP){return xhXldmy(gSLAwMP-149)}gSLAwMP[gSLAwMP[gSLAwMP[gSLAwMP[xhXldmy(-82)]-(gSLAwMP[gSLAwMP[gSLAwMP[e_Izy_w(132)]-dyHuutR(-60)]-dyHuutR(-60)]-56)]-(gSLAwMP[dyHuutR(-61)]-LxVvRh(79))]-157](new(_I6xtc(-e_Izy_w(134)))(kSudPk(dyHuutR(-56),kSudPk(e_Izy_w(137),kSudPk(gSLAwMP[e_Izy_w(132)]-(gSLAwMP[xhXldmy(-82)]-483),iOqQJH(e_Izy_w(138))+iOqQJH(e_Izy_w(139))+Ejf7Q4(27)+Ejf7Q4(gSLAwMP[56]-(gSLAwMP[xhXldmy(-82)]-e_Izy_w(155)))+Ejf7Q4(gSLAwMP[xhXldmy(-82)]-129),gSLAwMP[gSLAwMP[gSLAwMP[56]-xhXldmy(-81)]-(gSLAwMP[56]-(gSLAwMP[LxVvRh(79)]-hCj_Dfk(66)))]),'\x27\x3a\x20'),EddB3Qq.message)))}gSLAwMP[gSLAwMP[gSLAwMP[56]-(gSLAwMP[56]-dyHuutR(-61))]-(gSLAwMP[xhXldmy(-82)]-1)](null,gSLAwMP[gSLAwMP[gSLAwMP[LxVvRh(79)]-(gSLAwMP[gSLAwMP[dyHuutR(-61)]-102]-LxVvRh(79))]-(gSLAwMP[gSLAwMP[e_Izy_w(132)]-e_Izy_w(133)]-e_Izy_w(140))])}}~(T5fIY1h*=EddB3Qq-440,T5fIY1h-=Y2aTbT-(gSLAwMP[dyHuutR(-71)]-xhXldmy(-55)));break;case PEagBXy.rIQT8Uv[iOqQJH(gSLAwMP[gSLAwMP[dyHuutR(-71)]-178]+dyHuutR(-52))+H7XykPx(LxVvRh(89))](gSLAwMP[gSLAwMP[gSLAwMP[gSLAwMP[xhXldmy(-92)]-xhXldmy(-90)]-LxVvRh(71)]-LxVvRh(75)]+LxVvRh(90))==gSLAwMP[68]+230?-(gSLAwMP[dyHuutR(-73)]+34012):null:void(DCbAaKi=gSLAwMP[gSLAwMP[dyHuutR(-71)]-237].pop(),T5fIY1h+=gSLAwMP[xhXldmy(-94)]-(gSLAwMP[LxVvRh(67)]-188)<e_Izy_w?-(gSLAwMP[68]-(gSLAwMP[dyHuutR(-73)]-122)):-(gSLAwMP[gSLAwMP[68]+LxVvRh(70)]-162),EddB3Qq*=T5fIY1h+(e_Izy_w+279),EddB3Qq-=xhXldmy(-70)<hCj_Dfk?-(gSLAwMP[gSLAwMP[gSLAwMP[xhXldmy(-94)]+dyHuutR(-70)]-LxVvRh(71)]-(gSLAwMP[gSLAwMP[dyHuutR(-71)]-(gSLAwMP[xhXldmy(-92)]-dyHuutR(-73))]+188)):385);break;case PEagBXy.rIQT8Uv[iOqQJH(gSLAwMP[gSLAwMP[gSLAwMP[dyHuutR(-73)]+xhXldmy(-91)]-178]+LxVvRh(88))+H7XykPx(gSLAwMP[gSLAwMP[xhXldmy(-94)]+346]-222)](xhXldmy(-107))==dyHuutR(-48)?-(gSLAwMP[xhXldmy(-94)]-(gSLAwMP[xhXldmy(-92)]-4622)):null:typeof(EddB3Qq*=-(gSLAwMP[LxVvRh(69)]-148)>hCj_Dfk?LxVvRh(93):2,EddB3Qq-=-(gSLAwMP[xhXldmy(-94)]+218)>hCj_Dfk?-(gSLAwMP[gSLAwMP[LxVvRh(69)]-dyHuutR(-69)]-(gSLAwMP[68]+357)):-9);break;case!PEagBXy.LJbwud()?null:-41001:!(gSLAwMP[gSLAwMP[xhXldmy(-94)]+190]=L11Uy2.call([DCbAaKi]),hCj_Dfk*=79>e_Izy_w?T5fIY1h+(35<EddB3Qq?xhXldmy(-83):134):-82,hCj_Dfk-=EddB3Qq+(EddB3Qq-(gSLAwMP[gSLAwMP[165]-(gSLAwMP[LxVvRh(69)]-xhXldmy(-94))]+348)),EddB3Qq+=-dyHuutR(-51)<EddB3Qq?143:240,T5fIY1h*=e_Izy_w+41,T5fIY1h-=T5fIY1h+(gSLAwMP[LxVvRh(67)]-(gSLAwMP[LxVvRh(69)]-679)));break;case PEagBXy.LJbwud()?-(gSLAwMP[dyHuutR(-71)]-(gSLAwMP[dyHuutR(-73)]-11655)):null:return gSLAwMP[gSLAwMP[gSLAwMP[LxVvRh(69)]-(gSLAwMP[xhXldmy(-94)]-(gSLAwMP[xhXldmy(-94)]-LxVvRh(71)))]-(gSLAwMP[gSLAwMP[xhXldmy(-94)]-(gSLAwMP[LxVvRh(67)]-dyHuutR(-73))]+418)].pop();case!(PEagBXy.rmY0jRb>-xhXldmy(-97))?dyHuutR(-83):-(gSLAwMP[gSLAwMP[dyHuutR(-73)]+249]-(gSLAwMP[gSLAwMP[gSLAwMP[dyHuutR(-71)]-178]+LxVvRh(70)]-29717)):void(gSLAwMP[gSLAwMP[LxVvRh(67)]+191]=false,T5fIY1h*=e_Izy_w-(gSLAwMP[gSLAwMP[LxVvRh(67)]+LxVvRh(68)]-(gSLAwMP[LxVvRh(67)]-42)),T5fIY1h-=gSLAwMP[LxVvRh(67)]+211<Y2aTbT?12>Y2aTbT?-LxVvRh(94):-(gSLAwMP[xhXldmy(-92)]-xhXldmy(-69)):114,hCj_Dfk*=(-44<Y2aTbT?gSLAwMP[LxVvRh(69)]-221:gSLAwMP[xhXldmy(-92)]-xhXldmy(-62))>hCj_Dfk?-130:gSLAwMP[LxVvRh(67)]+183,hCj_Dfk-=EddB3Qq-121);break;case!(PEagBXy.rIQT8Uv[iOqQJH(dyHuutR(-63))+Ejf7Q4(dyHuutR(-45))](gSLAwMP[dyHuutR(-71)]-243)==49)?null:-27378:+(T5fIY1h*=(-206>EddB3Qq?gSLAwMP[165]-(gSLAwMP[dyHuutR(-73)]-(gSLAwMP[gSLAwMP[dyHuutR(-73)]-(gSLAwMP[gSLAwMP[dyHuutR(-73)]+LxVvRh(68)]-165)]-647)):-LxVvRh(96))>e_Izy_w?gSLAwMP[gSLAwMP[LxVvRh(67)]-(gSLAwMP[xhXldmy(-94)]-LxVvRh(69))]-(gSLAwMP[LxVvRh(67)]+425):-(gSLAwMP[xhXldmy(-94)]+406),T5fIY1h-=e_Izy_w+(-(gSLAwMP[xhXldmy(-92)]-128)<hCj_Dfk?-302:-dyHuutR(-43)),Y2aTbT*=gSLAwMP[xhXldmy(-92)]-150>EddB3Qq?gSLAwMP[dyHuutR(-73)]-(gSLAwMP[gSLAwMP[LxVvRh(67)]+249]-(gSLAwMP[68]+375)):xhXldmy(-98),Y2aTbT-=hCj_Dfk-LxVvRh(98));break;case PEagBXy.cWu3FK>6?-(gSLAwMP[LxVvRh(69)]-(gSLAwMP[68]-7353)):xhXldmy(-104):!(e_Izy_w*=-75>e_Izy_w?Y2aTbT+191:gSLAwMP[gSLAwMP[dyHuutR(-71)]-xhXldmy(-90)]-43,e_Izy_w-=T5fIY1h-(gSLAwMP[68]+277));break;case PEagBXy.rIQT8Uv[iOqQJH(gSLAwMP[68]+194)+Ejf7Q4(gSLAwMP[LxVvRh(67)]+195)](LxVvRh(54))==gSLAwMP[165]-(gSLAwMP[68]+378)?-14233:LxVvRh(57):e_Izy_w+=hCj_Dfk+(Y2aTbT+(161<T5fIY1h?LxVvRh(99):gSLAwMP[gSLAwMP[gSLAwMP[LxVvRh(69)]-81]-dyHuutR(-65)]-(gSLAwMP[dyHuutR(-73)]-153)))}}}}void(hCj_Dfk=new xhXldmy,_I6xtc(-LxVvRh(100))[iOqQJH(LxVvRh(101))](DCbAaKi));function dyHuutR(gSLAwMP,e_Izy_w=[H7XykPx(27),H7XykPx(LxVvRh(102))]){var EddB3Qq,hCj_Dfk,Y2aTbT,_I6xtc,kSudPk,L11Uy2,DCbAaKi,xhXldmy,dyHuutR,Ejf7Q4;function FcEfMx(gSLAwMP){return lJFJ64f[gSLAwMP-15]}var iOqQJH,EddB3Qq,hCj_Dfk,Y2aTbT,_I6xtc,kSudPk=String,L11Uy2=H7XykPx(29),DCbAaKi=LxVvRh(103),xhXldmy=H7XykPx(LxVvRh(101)),dyHuutR=H7XykPx(31),Ejf7Q4=H7XykPx(32);for('\u003c\u007e'===gSLAwMP[dyHuutR](0,LxVvRh(63))&&'\x7e\x3e'===gSLAwMP[dyHuutR](-LxVvRh(63)),gSLAwMP=gSLAwMP[dyHuutR](LxVvRh(63),-LxVvRh(63))[Ejf7Q4](/s/g,'')[Ejf7Q4]('\x7a',H7XykPx(LxVvRh(104))),iOqQJH=H7XykPx(34)[dyHuutR](gSLAwMP[L11Uy2]%5||LxVvRh(105)),gSLAwMP+=iOqQJH,hCj_Dfk=[],Y2aTbT=FcEfMx(15),_I6xtc=gSLAwMP[L11Uy2];_I6xtc>Y2aTbT;Y2aTbT+=LxVvRh(105))EddB3Qq=52200625*(gSLAwMP[xhXldmy](Y2aTbT)-LxVvRh(104))+614125*(gSLAwMP[xhXldmy](Y2aTbT+FcEfMx(28))-33)+7225*(gSLAwMP[xhXldmy](Y2aTbT+LxVvRh(63))-LxVvRh(104))+LxVvRh(106)*(gSLAwMP[xhXldmy](Y2aTbT+3)-LxVvRh(104))+(gSLAwMP[xhXldmy](Y2aTbT+LxVvRh(74))-FcEfMx(70)),hCj_Dfk.push(DCbAaKi&EddB3Qq>>FcEfMx(55),DCbAaKi&EddB3Qq>>FcEfMx(73),DCbAaKi&EddB3Qq>>FcEfMx(16),DCbAaKi&EddB3Qq);return function(gSLAwMP,T5fIY1h){for(var iOqQJH=T5fIY1h;iOqQJH>FcEfMx(15);iOqQJH--)gSLAwMP.pop()}(hCj_Dfk,iOqQJH[L11Uy2]),kSudPk[e_Izy_w[FcEfMx(15)]][e_Izy_w[FcEfMx(28)]](kSudPk,hCj_Dfk)}function Ejf7Q4(...gSLAwMP){var PEagBXy=gSLAwMP=>lJFJ64f[gSLAwMP-54];!(gSLAwMP.length=LxVvRh(54),gSLAwMP[185]=-113);if(gSLAwMP[gSLAwMP[gSLAwMP[LxVvRh(108)]+LxVvRh(109)]-(gSLAwMP[185]-(gSLAwMP[gSLAwMP[185]+298]-(gSLAwMP[LxVvRh(108)]-PEagBXy(68))))]){return gSLAwMP[gSLAwMP[185]-(gSLAwMP[PEagBXy(113)]-1)][e_Izy_w[gSLAwMP[gSLAwMP[LxVvRh(108)]+(gSLAwMP[gSLAwMP[PEagBXy(113)]-(gSLAwMP[gSLAwMP[LxVvRh(108)]+PEagBXy(114)]-PEagBXy(113))]+LxVvRh(110))]]]=Ejf7Q4(gSLAwMP[gSLAwMP[LxVvRh(108)]-(gSLAwMP[LxVvRh(108)]-LxVvRh(49))],gSLAwMP[gSLAwMP[gSLAwMP[PEagBXy(113)]+LxVvRh(109)]+(gSLAwMP[LxVvRh(108)]+227)])}gSLAwMP[104]=gSLAwMP[gSLAwMP[185]+113];if(gSLAwMP[gSLAwMP[PEagBXy(113)]+298]>gSLAwMP[gSLAwMP[LxVvRh(108)]+298]+51){return gSLAwMP[gSLAwMP[gSLAwMP[185]+298]-(gSLAwMP[gSLAwMP[LxVvRh(108)]+298]+LxVvRh(59))]}else{var EddB3Qq=gSLAwMP=>LxVvRh(gSLAwMP+131);return gSLAwMP[gSLAwMP[185]+(gSLAwMP[gSLAwMP[PEagBXy(113)]+298]+227)]?gSLAwMP[gSLAwMP[gSLAwMP[gSLAwMP[185]+PEagBXy(114)]+PEagBXy(114)]-(gSLAwMP[PEagBXy(113)]-PEagBXy(56))][e_Izy_w[gSLAwMP[gSLAwMP[185]-(gSLAwMP[LxVvRh(108)]-(gSLAwMP[185]-(gSLAwMP[PEagBXy(113)]-PEagBXy(67))))]]]:e_Izy_w[gSLAwMP[gSLAwMP[PEagBXy(113)]+EddB3Qq(-19)]]||(gSLAwMP[gSLAwMP[gSLAwMP[gSLAwMP[EddB3Qq(-23)]+LxVvRh(109)]+LxVvRh(109)]-(gSLAwMP[PEagBXy(113)]-(gSLAwMP[LxVvRh(108)]+115))]=dyHuutR,e_Izy_w[gSLAwMP[gSLAwMP[gSLAwMP[gSLAwMP[gSLAwMP[185]+(gSLAwMP[PEagBXy(113)]-(gSLAwMP[LxVvRh(108)]-(gSLAwMP[EddB3Qq(-23)]+LxVvRh(111))))]-(gSLAwMP[LxVvRh(108)]-PEagBXy(113))]+(gSLAwMP[gSLAwMP[gSLAwMP[EddB3Qq(-23)]+PEagBXy(114)]+EddB3Qq(-22)]+LxVvRh(111))]+(gSLAwMP[gSLAwMP[185]+PEagBXy(114)]+330)]]=gSLAwMP[gSLAwMP[gSLAwMP[PEagBXy(113)]+298]+115](T5fIY1h[gSLAwMP[gSLAwMP[LxVvRh(108)]+PEagBXy(117)]]))}}function FcEfMx(gSLAwMP){var e_Izy_w,T5fIY1h,PEagBXy=LxVvRh(49),EddB3Qq='',hCj_Dfk=gSLAwMP.length,lJFJ64f=String,Y2aTbT=H7XykPx(LxVvRh(101)),_I6xtc=H7XykPx(27),kSudPk;for(kSudPk=LxVvRh(49);kSudPk<hCj_Dfk;kSudPk+=1)e_Izy_w=gSLAwMP[Y2aTbT](kSudPk)-LxVvRh(104),e_Izy_w>=0&&e_Izy_w<32?(PEagBXy+=(T5fIY1h=T5fIY1h<<LxVvRh(105)|e_Izy_w,LxVvRh(105)),PEagBXy>=LxVvRh(50)?PEagBXy-=(EddB3Qq+=lJFJ64f[_I6xtc](T5fIY1h>>PEagBXy-LxVvRh(50)&LxVvRh(103)),LxVvRh(50)):0):0;return EddB3Qq}function iOqQJH(...gSLAwMP){var PEagBXy=gSLAwMP=>lJFJ64f[gSLAwMP+9];typeof(gSLAwMP.length=LxVvRh(54),gSLAwMP[LxVvRh(113)]=PEagBXy(56));if(gSLAwMP[LxVvRh(63)]){var EddB3Qq=gSLAwMP=>LxVvRh(gSLAwMP+126);return gSLAwMP[1][e_Izy_w[gSLAwMP[gSLAwMP[248]-(gSLAwMP[gSLAwMP[EddB3Qq(-13)]+EddB3Qq(-54)]-(gSLAwMP[gSLAwMP[LxVvRh(113)]-(gSLAwMP[LxVvRh(113)]-LxVvRh(113))]-(gSLAwMP[gSLAwMP[EddB3Qq(-13)]+EddB3Qq(-54)]-EddB3Qq(-63))))]]]=iOqQJH(gSLAwMP[gSLAwMP[gSLAwMP[248]+LxVvRh(72)]-PEagBXy(56)],gSLAwMP[gSLAwMP[PEagBXy(55)]-(gSLAwMP[PEagBXy(55)]-(gSLAwMP[EddB3Qq(-13)]-61))])}gSLAwMP[gSLAwMP[248]-(gSLAwMP[gSLAwMP[PEagBXy(55)]+186]-PEagBXy(55))]=gSLAwMP[PEagBXy(55)]-107;if(gSLAwMP[gSLAwMP[gSLAwMP[248]-(gSLAwMP[248]-PEagBXy(55))]-(gSLAwMP[LxVvRh(113)]-PEagBXy(55))]>gSLAwMP[LxVvRh(113)]+46){var hCj_Dfk=gSLAwMP=>LxVvRh(gSLAwMP-87);return gSLAwMP[gSLAwMP[gSLAwMP[hCj_Dfk(200)]-(gSLAwMP[248]-248)]-(gSLAwMP[hCj_Dfk(200)]-(gSLAwMP[LxVvRh(113)]-(gSLAwMP[gSLAwMP[248]+PEagBXy(57)]-37)))]}else{var Y2aTbT=gSLAwMP=>LxVvRh(gSLAwMP+198);return gSLAwMP[gSLAwMP[gSLAwMP[248]+PEagBXy(57)]-(gSLAwMP[gSLAwMP[gSLAwMP[gSLAwMP[248]-(gSLAwMP[Y2aTbT(-85)]-LxVvRh(113))]-(gSLAwMP[248]-Y2aTbT(-85))]-(gSLAwMP[gSLAwMP[LxVvRh(113)]-(gSLAwMP[PEagBXy(55)]-Y2aTbT(-85))]-PEagBXy(55))]-(gSLAwMP[Y2aTbT(-85)]-(gSLAwMP[PEagBXy(55)]-(gSLAwMP[gSLAwMP[LxVvRh(113)]-(gSLAwMP[Y2aTbT(-85)]-248)]+46))))]?gSLAwMP[gSLAwMP[gSLAwMP[gSLAwMP[248]+293]+293]+LxVvRh(116)][e_Izy_w[gSLAwMP[gSLAwMP[gSLAwMP[gSLAwMP[gSLAwMP[LxVvRh(113)]+Y2aTbT(-83)]+(gSLAwMP[Y2aTbT(-85)]-(gSLAwMP[PEagBXy(55)]-PEagBXy(57)))]+(gSLAwMP[gSLAwMP[LxVvRh(113)]-(gSLAwMP[gSLAwMP[LxVvRh(113)]+PEagBXy(57)]-(gSLAwMP[LxVvRh(113)]+PEagBXy(57)))]-(gSLAwMP[gSLAwMP[LxVvRh(113)]+PEagBXy(57)]-Y2aTbT(-83)))]-(gSLAwMP[gSLAwMP[Y2aTbT(-85)]+Y2aTbT(-83)]-(gSLAwMP[248]-(gSLAwMP[PEagBXy(55)]-1)))]]]:e_Izy_w[gSLAwMP[gSLAwMP[gSLAwMP[gSLAwMP[gSLAwMP[gSLAwMP[248]+PEagBXy(57)]+PEagBXy(57)]-(gSLAwMP[248]-Y2aTbT(-85))]-(gSLAwMP[LxVvRh(113)]-(gSLAwMP[gSLAwMP[Y2aTbT(-85)]-(gSLAwMP[gSLAwMP[248]+293]-Y2aTbT(-85))]+293))]+LxVvRh(116)]]||(gSLAwMP[gSLAwMP[248]+47]=FcEfMx,e_Izy_w[gSLAwMP[gSLAwMP[Y2aTbT(-85)]+(gSLAwMP[gSLAwMP[LxVvRh(113)]-(gSLAwMP[PEagBXy(55)]-248)]-(gSLAwMP[PEagBXy(55)]-45))]]=gSLAwMP[gSLAwMP[Y2aTbT(-85)]-(gSLAwMP[gSLAwMP[gSLAwMP[gSLAwMP[LxVvRh(113)]+LxVvRh(115)]-(gSLAwMP[PEagBXy(55)]-PEagBXy(55))]+LxVvRh(115)]-2)](T5fIY1h[gSLAwMP[gSLAwMP[gSLAwMP[248]+293]+LxVvRh(116)]]))}}function H7XykPx(...e_Izy_w){~(e_Izy_w.length=LxVvRh(62),e_Izy_w[200]=e_Izy_w[LxVvRh(49)]);return gSLAwMP[e_Izy_w[200]]}function DKJuJH(gSLAwMP){var e_Izy_w,T5fIY1h,PEagBXy,EddB3Qq={},hCj_Dfk=gSLAwMP.split(''),lJFJ64f=T5fIY1h=hCj_Dfk[0],Y2aTbT=[lJFJ64f],_I6xtc=e_Izy_w=256;for(gSLAwMP=LxVvRh(62);gSLAwMP<hCj_Dfk.length;gSLAwMP++)PEagBXy=hCj_Dfk[gSLAwMP].charCodeAt(LxVvRh(49)),PEagBXy=_I6xtc>PEagBXy?hCj_Dfk[gSLAwMP]:EddB3Qq[PEagBXy]?EddB3Qq[PEagBXy]:T5fIY1h+lJFJ64f,Y2aTbT.push(PEagBXy),lJFJ64f=PEagBXy.charAt(0),EddB3Qq[e_Izy_w]=T5fIY1h+lJFJ64f,e_Izy_w++,T5fIY1h=PEagBXy;return Y2aTbT.join('').split('\x31')}

https://www.virustotal.com/gui/file-analysis/MTdjY2RkYjgyNmU5ZWZkZTliZTMyYjY2NDNhZWI0Nzc6MTYyNDM4NjIzMQ==/detection

"1 security vendor flagged this file as malicious"

Additional context

Windows removes file about 1 every 300 obfuscations

Shuffle transform in shift mode breaks program

Describe the bug:

shuffle transform will attempt to assign to arrays that are const

Config and Small code sample

Config:

{
    target: 'browser',
    shuffle: true,
    compact: false,
    minify: false,
}

Code:

const a=[1,2,3];

Expected behavior

it shouldn't try assigning to a const

Actual behavior

it assigns to a const

Additional context

if (varDeclarator.type == "VariableDeclarator") {
var varDec = parents[2];
if (varDec.type == "VariableDeclaration") {
var body = parents[3];
if (
varDec.declarations.length == 1 &&
Array.isArray(body) &&
varDeclarator.id.type === "Identifier" &&
varDeclarator.init === object
) {
inPlaceIndex = body.indexOf(varDec);
inPlaceBody = body;
inPlace = inPlaceIndex !== -1;
inPlaceName = varDeclarator.id.name;
}
}
}

${
inPlace ? `${inPlaceName} = ${name}` : name
} = ${name}.concat((function(){

Dispatcher only applies to the top level of the code

Describe the bug:

Dispatcher should recursively apply to every scope of the code.

Config and Small code sample

Config:

{
  target: "node",
  dispatcher: true,
  compact: false,
}

Code:

function OUTER(){
  function INNER(){
    return 100;
  }
  return INNER();
}

console.log(OUTER());

Expected behavior

Obfuscate the INNER function.

Actual behavior

The INNER function was never obfuscated.

Additional context

var __p_1982331520 = Object.create(null);
var $jsc_d0_payload = [];
console["log"](
  new __p_3269620441_dispatcher_0("dCFVru", "PxkGxg", "I4oY_3").MSq66Q
);
function __p_3269620441_dispatcher_0(
  __p_5135106733,
  __p_4768529421,
  __p_3345282446
) {
  var __p_0667312621 = {
    dCFVru: function () {
      function INNER() { // <- INNER was never obfuscated
        return 100;
      }
      return INNER();
    },
  };
  var z3lXmbn;
  if (__p_4768529421 == "PxkGxg") {
    $jsc_d0_payload = [];
  }
  if (__p_4768529421 == "IRK3x4") {
    z3lXmbn =
      __p_1982331520[__p_5135106733] ||
      (__p_1982331520[__p_5135106733] = function (...__p_7966752171) {
        $jsc_d0_payload = __p_7966752171;
        return __p_0667312621[__p_5135106733].call(this, "Hujjep");
      });
  } else {
    z3lXmbn = __p_0667312621[__p_5135106733]("XpIQpf3");
  }
  if (__p_3345282446 == "I4oY_3") {
    return { MSq66Q: z3lXmbn };
  } else {
    return z3lXmbn;
  }
}

Variable renaming breaks on default parameters

Describe the bug:

Variable renaming breaks working code when default parameters are involved and the identifier generator is set to 'mangled'

Config and Small code sample

Config:

{
  compact: false,
  target: "node",
  renameVariables: true,
  identifierGenerator: "mangled",
}

Code:

function FuncA(param1, param2 = FuncB){
  param2()
}

function FuncB(){
  console.log("Success!");
}

FuncA();

Expected behavior

The program should output "Success!"

Actual behavior

ReferenceError: Cannot access 'b' before initialization

Rename Variables breaks code with var & let in same scope

Describe the bug:

Rename Variables breaks code with var & let in same scope

Config and Small code sample

Config:

{
  target: "node",
  renameVariables: true
}

Code:

function log(param) {
  let message = param;
  var isWarning = false;
  var isError = false;

  console.log(message);
};

Output:

function X5pMbM4(X5pMbM4) {
    let wCSLkl = X5pMbM4;
    var mBglfYB = false;
    var wCSLkl = false;
    console['log'](wCSLkl);
};
// Uncaught SyntaxError: Identifier 'wCSLkl' has already been declared

RGF does not work on Arrow Functions or Function expressions

Config and Small code sample

Config:

{
  target: "node",
  rgf: true,
}

Code:

function double1(num){  // Function declaration works
  return num*2;
}

var double2 = function(num){ // Function expression breaks
  return num*2;
}

var double3 = (num)=>{ // Arrow function breaks
  return num*2;
}

console.log(double1(10));
console.log(double2(10));
console.log(double3(10));

Expected behavior

20
20
20

Actual behavior

20
NaN
NaN

shuffle: false not working

Describe the bug:

Disabling shuffle is impossible

Config and Small code sample

Config:

{
  target: "node",
  shuffle: false
}

Code:

let a = [1, 2, 3, 4, 5, 6]

Expected behavior

let a = [1, 2, 3, 4, 5, 6]

Actual behavior

let a = function (__p_5765612342) {
    for (var x = 16; x % 4 === 0; x++) {
        var z = 0;
        __p_5765612342 = __p_5765612342.concat(function () {
            z++;
            if (z === 1) {
                return [];
            }
            for (var i = 102; i; i--) {
                __p_5765612342.unshift(__p_5765612342.pop());
            }
            return [];
        }());
    }
    for (var __p_7280324068 = 19; __p_7280324068; __p_7280324068--) {
        __p_5765612342.unshift(__p_5765612342.pop());
    }
    return __p_5765612342;
}([
    2,
    3,
    4,
    5,
    6,
    1
]);

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.