๐Ÿš€ Big News: Socket Acquires Coana to Bring Reachability Analysis to Every Appsec Team.Learn more โ†’
Socket
Book a DemoInstallSign in
Socket

javascript-obfuscator

Package Overview
Dependencies
Maintainers
1
Versions
247
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

javascript-obfuscator - npm Package Compare versions

Comparing version

to
0.5.2

dist/src/custom-nodes/unicode-array-nodes/UnicodeArrayDecodeNode.js

32

dist/index.js
"use strict";
const esprima = require('esprima');
const escodegen = require('escodegen');
const Obfuscator_1 = require('./src/Obfuscator');
class JavaScriptObfuscator {
static obfuscate(sourceCode, customOptions) {
let astTree = esprima.parse(sourceCode), options = Object.assign(JavaScriptObfuscator.defaultOptions, customOptions), obfuscator = new Obfuscator_1.Obfuscator(options);
obfuscator.obfuscateNode(astTree);
return JavaScriptObfuscator.generateCode(astTree, options);
}
static generateCode(astTree, options) {
let escodegenParams = Object.assign({}, JavaScriptObfuscator.escodegenParams);
if (options.hasOwnProperty('compact')) {
escodegenParams.format = {};
escodegenParams.format.compact = options.compact;
}
return escodegen.generate(astTree, escodegenParams);
}
}
JavaScriptObfuscator.defaultOptions = {
compact: true,
debugProtection: false,
debugProtectionInterval: false,
disableConsoleOutput: true,
rotateUnicodeArray: true,
wrapUnicodeArrayCalls: true
};
JavaScriptObfuscator.escodegenParams = {
verbatim: 'x-verbatim-property'
};
module.exports = JavaScriptObfuscator;
const JavaScriptObfuscator_1 = require('./src/JavaScriptObfuscator');
module.exports = JavaScriptObfuscator_1.JavaScriptObfuscator;

@@ -34,2 +34,5 @@ "use strict";

}
updateNodeData(data) {
this.unicodeArray.push(data);
}
getNodeStructure() {

@@ -36,0 +39,0 @@ return {

@@ -8,16 +8,7 @@ "use strict";

class DebugProtectionNodesGroup extends NodesGroup_1.NodesGroup {
constructor(options) {
super();
constructor(options = {}) {
super(options);
this.debugProtectionFunctionIdentifier = Utils_1.Utils.getRandomVariableName();
this.options = options;
this.nodes = new Map([
[
'debugProtectionFunctionNode',
new DebugProtectionFunctionNode_1.DebugProtectionFunctionNode(this.debugProtectionFunctionIdentifier)
],
[
'debugProtectionFunctionCallNode',
new DebugProtectionFunctionCallNode_1.DebugProtectionFunctionCallNode(this.debugProtectionFunctionIdentifier)
]
]);
this.nodes.set('debugProtectionFunctionNode', new DebugProtectionFunctionNode_1.DebugProtectionFunctionNode(this.debugProtectionFunctionIdentifier));
this.nodes.set('debugProtectionFunctionCallNode', new DebugProtectionFunctionCallNode_1.DebugProtectionFunctionCallNode(this.debugProtectionFunctionIdentifier));
if (this.options['debugProtectionInterval']) {

@@ -24,0 +15,0 @@ this.nodes.set('debugProtectionFunctionIntervalNode', new DebugProtectionFunctionIntervalNode_1.DebugProtectionFunctionIntervalNode(this.debugProtectionFunctionIdentifier));

"use strict";
class NodesGroup {
constructor(options = {}) {
this.nodes = new Map();
this.options = options;
}
getNodes() {

@@ -4,0 +8,0 @@ return this.nodes;

"use strict";
const NodesGroup_1 = require('./NodesGroup');
const UnicodeArrayCallsWrapper_1 = require("../custom-nodes/unicode-array-nodes/UnicodeArrayCallsWrapper");
const UnicodeArrayDecodeNode_1 = require("../custom-nodes/unicode-array-nodes/UnicodeArrayDecodeNode");
const UnicodeArrayNode_1 = require('../custom-nodes/unicode-array-nodes/UnicodeArrayNode');

@@ -8,18 +9,15 @@ const UnicodeArrayRotateFunctionNode_1 = require('../custom-nodes/unicode-array-nodes/UnicodeArrayRotateFunctionNode');

class UnicodeArrayNodesGroup extends NodesGroup_1.NodesGroup {
constructor(options) {
super();
constructor(options = {}) {
super(options);
this.unicodeArrayName = Utils_1.Utils.getRandomVariableName(UnicodeArrayNode_1.UnicodeArrayNode.UNICODE_ARRAY_RANDOM_LENGTH);
this.unicodeArrayRotateValue = Utils_1.Utils.getRandomInteger(100, 500);
this.unicodeArrayTranslatorName = Utils_1.Utils.getRandomVariableName(UnicodeArrayNode_1.UnicodeArrayNode.UNICODE_ARRAY_RANDOM_LENGTH);
this.options = options;
this.unicodeArrayRotateValue = this.options['rotateUnicodeArray'] ? Utils_1.Utils.getRandomInteger(100, 500) : 0;
let unicodeArrayNode = new UnicodeArrayNode_1.UnicodeArrayNode(this.unicodeArrayName, this.unicodeArrayRotateValue), unicodeArray = unicodeArrayNode.getNodeData();
this.nodes = new Map([
[
'unicodeArrayNode',
unicodeArrayNode
]
]);
this.nodes.set('unicodeArrayNode', unicodeArrayNode);
if (this.options['wrapUnicodeArrayCalls']) {
this.nodes.set('unicodeArrayCallsWrapper', new UnicodeArrayCallsWrapper_1.UnicodeArrayCallsWrapper(this.unicodeArrayTranslatorName, this.unicodeArrayName, unicodeArray));
}
if (this.options['encodeUnicodeLiterals']) {
this.nodes.set('unicodeArrayDecodeNode', new UnicodeArrayDecodeNode_1.UnicodeArrayDecodeNode(this.unicodeArrayName, unicodeArray));
}
if (this.options['rotateUnicodeArray']) {

@@ -26,0 +24,0 @@ this.nodes.set('unicodeArrayRotateFunctionNode', new UnicodeArrayRotateFunctionNode_1.UnicodeArrayRotateFunctionNode(this.unicodeArrayName, unicodeArray, this.unicodeArrayRotateValue));

@@ -18,3 +18,3 @@ "use strict";

leave: (node, parentNode) => {
if (NodeUtils_1.NodeUtils.isIdentifierNode(node)) {
if (NodeUtils_1.NodeUtils.isIdentifierNode(node) && !this.isReservedName(node.name)) {
this.catchClauseParam.set(node.name, Utils_1.Utils.getRandomVariableName());

@@ -21,0 +21,0 @@ node.name = this.catchClauseParam.get(node.name);

@@ -22,3 +22,3 @@ "use strict";

leave: (node) => {
if (NodeUtils_1.NodeUtils.isIdentifierNode(node)) {
if (NodeUtils_1.NodeUtils.isIdentifierNode(node) && !this.isReservedName(node.name)) {
this.functionName.set(node.name, Utils_1.Utils.getRandomVariableName());

@@ -25,0 +25,0 @@ node.name = this.functionName.get(node.name);

@@ -19,3 +19,3 @@ "use strict";

leave: (node) => {
if (NodeUtils_1.NodeUtils.isIdentifierNode(node)) {
if (NodeUtils_1.NodeUtils.isIdentifierNode(node) && !this.isReservedName(node.name)) {
this.functionParams.set(node.name, Utils_1.Utils.getRandomVariableName());

@@ -22,0 +22,0 @@ node.name = this.functionParams.get(node.name);

@@ -22,3 +22,3 @@ "use strict";

case 'string':
content = this.replaceLiteralStringByUnicodeArrayCall(literalNode.value);
content = this.replaceLiteralValueByUnicodeValue(literalNode.value);
break;

@@ -25,0 +25,0 @@ default:

@@ -29,3 +29,3 @@ "use strict";

'x-verbatim-property': {
content: this.replaceLiteralStringByUnicodeArrayCall(nodeValue),
content: this.replaceLiteralValueByUnicodeValue(nodeValue),
precedence: escodegen.Precedence.Primary

@@ -46,3 +46,3 @@ },

node['x-verbatim-property'] = {
content: this.replaceLiteralStringByUnicodeArrayCall(node.value),
content: this.replaceLiteralValueByUnicodeValue(node.value),
precedence: escodegen.Precedence.Primary

@@ -49,0 +49,0 @@ };

@@ -21,3 +21,3 @@ "use strict";

methodDefinitionNode.computed = true;
node.name = this.replaceLiteralStringByUnicodeArrayCall(node.name);
node.name = this.replaceLiteralValueByUnicodeValue(node.name);
return;

@@ -24,0 +24,0 @@ }

@@ -10,6 +10,14 @@ "use strict";

}
isReservedName(name) {
return this.options['reservedNames'].some((reservedName) => {
return reservedName === name;
});
}
replaceNodeIdentifierByNewValue(node, parentNode, namesMap) {
if (NodeUtils_1.NodeUtils.isIdentifierNode(node) && namesMap.has(node.name)) {
if ((NodeUtils_1.NodeUtils.isPropertyNode(parentNode) && parentNode.key === node) ||
(NodeUtils_1.NodeUtils.isMemberExpressionNode(parentNode) && parentNode.computed === false && parentNode.property === node)) {
const parentNodeIsAPropertyNode = (NodeUtils_1.NodeUtils.isPropertyNode(parentNode) &&
parentNode.key === node), parentNodeIsAMemberExpressionNode = (NodeUtils_1.NodeUtils.isMemberExpressionNode(parentNode) &&
parentNode.computed === false &&
parentNode.property === node);
if (parentNodeIsAPropertyNode || parentNodeIsAMemberExpressionNode) {
return;

@@ -30,11 +38,22 @@ }

}
replaceLiteralStringByUnicodeArrayCall(nodeValue) {
let value = Utils_1.Utils.stringToUnicode(nodeValue), unicodeArray = this.nodes.get('unicodeArrayNode').getNodeData(), sameIndex = unicodeArray.indexOf(value), index, hexadecimalIndex;
if (sameIndex < 0) {
index = unicodeArray.length;
unicodeArray.push(Utils_1.Utils.stringToUnicode(nodeValue));
replaceLiteralValueByUnicodeValue(nodeValue) {
let value = nodeValue;
if (this.options['encodeUnicodeLiterals']) {
value = new Buffer(encodeURI(value)).toString('base64');
}
else {
value = Utils_1.Utils.stringToUnicode(value);
if (!this.options['unicodeArray']) {
return value;
}
return this.replaceLiteralValueByUnicodeArrayCall(value);
}
replaceLiteralValueByUnicodeArrayCall(value) {
let unicodeArrayNode = this.nodes.get('unicodeArrayNode'), unicodeArray = unicodeArrayNode.getNodeData(), sameIndex = unicodeArray.indexOf(value), index, hexadecimalIndex;
if (sameIndex >= 0) {
index = sameIndex;
}
else {
index = unicodeArray.length;
unicodeArrayNode.updateNodeData(value);
}
hexadecimalIndex = this.replaceLiteralNumberByHexadecimalValue(index);

@@ -44,5 +63,5 @@ if (this.options['wrapUnicodeArrayCalls']) {

}
return `${this.nodes.get('unicodeArrayNode').getNodeIdentifier()}[${hexadecimalIndex}]`;
return `${unicodeArrayNode.getNodeIdentifier()}[${hexadecimalIndex}]`;
}
}
exports.NodeObfuscator = NodeObfuscator;

@@ -23,3 +23,3 @@ "use strict";

enter: (node) => {
if (NodeUtils_1.NodeUtils.isIdentifierNode(node)) {
if (NodeUtils_1.NodeUtils.isIdentifierNode(node) && !this.isReservedName(node.name)) {
this.variableNames.set(node.name, Utils_1.Utils.getRandomVariableName());

@@ -26,0 +26,0 @@ node.name = this.variableNames.get(node.name);

@@ -45,2 +45,8 @@ "use strict";

}
static getProgramNode(bodyNode) {
return {
'type': NodeType_1.NodeType.Program,
'body': bodyNode
};
}
static insertNodeAtIndex(blockScopeBody, node, index) {

@@ -77,2 +83,3 @@ if (!NodeUtils.validateNode(node)) {

static parentize(node) {
let isRootNode = true;
estraverse.replace(node, {

@@ -83,5 +90,6 @@ enter: (node, parentNode) => {

enumerable: true,
value: parentNode || node,
value: isRootNode ? NodeUtils.getProgramNode([node]) : parentNode || node,
writable: true
});
isRootNode = false;
}

@@ -88,0 +96,0 @@ });

@@ -43,2 +43,3 @@ "use strict";

this.afterObfuscation(node);
return node;
}

@@ -57,3 +58,3 @@ setNode(nodeName, node) {

if (node.getAppendState() === AppendState_1.AppendState.AfterObfuscation) {
node.appendNode(NodeUtils_1.NodeUtils.getBlockScopeOfNode(astTree));
node.appendNode(astTree);
}

@@ -65,3 +66,3 @@ });

if (node.getAppendState() === AppendState_1.AppendState.BeforeObfuscation) {
node.appendNode(NodeUtils_1.NodeUtils.getBlockScopeOfNode(astTree));
node.appendNode(astTree);
}

@@ -93,5 +94,7 @@ });

}
this.setNodesGroup(new UnicodeArrayNodesGroup_1.UnicodeArrayNodesGroup(this.options));
if (this.options['unicodeArray']) {
this.setNodesGroup(new UnicodeArrayNodesGroup_1.UnicodeArrayNodesGroup(this.options));
}
}
}
exports.Obfuscator = Obfuscator;

@@ -24,3 +24,7 @@ "use strict";

static decToHex(dec) {
return (dec + Math.pow(16, 6)).toString(16).substr(-6).replace(Utils.hexRepetitiveZerosRegExp, '');
const decToHexSliceValue = -6, exponent = 6, radix = 16;
return (dec + Math.pow(radix, exponent))
.toString(radix)
.substr(decToHexSliceValue)
.replace(Utils.hexRepetitiveZerosRegExp, '');
}

@@ -41,4 +45,14 @@ static getRandomInteger(min, max) {

static stringToUnicode(string) {
const radix = 16;
let prefix, regexp = new RegExp('[\x00-\x7F]'), template;
return `'${string.replace(/[\s\S]/g, (escape) => {
return `\\u${('0000' + escape.charCodeAt(0).toString(16)).slice(-4)}`;
if (regexp.test(escape)) {
prefix = '\\x';
template = '0'.repeat(2);
}
else {
prefix = '\\u';
template = '0'.repeat(4);
}
return `${prefix}${(template + escape.charCodeAt(0).toString(radix)).slice(-template.length)}`;
})}'`;

@@ -45,0 +59,0 @@ }

"use strict";
const JavaScriptObfuscator = require("../index");
let obfuscatedCode = JavaScriptObfuscator.obfuscate(`
const JavaScriptObfuscator_1 = require('../src/JavaScriptObfuscator');
let obfuscatedCode = JavaScriptObfuscator_1.JavaScriptObfuscator.obfuscate(`
(function(){

@@ -38,3 +38,3 @@ var result = 1,

console.log('between', abc);
console.log('ั‚ะตัั‚', abc);

@@ -51,5 +51,6 @@ var abc = {};

`, {
disableConsoleOutput: false
disableConsoleOutput: false,
encodeUnicodeLiterals: true
});
console.log(obfuscatedCode);
console.log(eval(obfuscatedCode));
"use strict";
import * as esprima from 'esprima';
import * as escodegen from 'escodegen';
import { JavaScriptObfuscator } from './src/JavaScriptObfuscator';
import { IProgramNode } from './src/interfaces/nodes/IProgramNode';
import { Obfuscator } from './src/Obfuscator';
class JavaScriptObfuscator {
/**
* @type any
*/
private static defaultOptions: any = {
compact: true,
debugProtection: false,
debugProtectionInterval: false,
disableConsoleOutput: true,
rotateUnicodeArray: true,
wrapUnicodeArrayCalls: true
};
/**
* @type any
*/
private static escodegenParams: any = {
verbatim: 'x-verbatim-property'
};
/**
* @param sourceCode
* @param customOptions
*/
public static obfuscate (sourceCode: string, customOptions: any): string {
let astTree: IProgramNode = esprima.parse(sourceCode),
options: any = Object.assign(JavaScriptObfuscator.defaultOptions, customOptions),
obfuscator: Obfuscator = new Obfuscator(options);
obfuscator.obfuscateNode(astTree);
return JavaScriptObfuscator.generateCode(astTree, options);
}
/**
* @param astTree
* @param options
*/
private static generateCode (astTree: IProgramNode, options: any): string {
let escodegenParams: any = Object.assign({}, JavaScriptObfuscator.escodegenParams);
if (options.hasOwnProperty('compact')) {
escodegenParams.format = {};
escodegenParams.format.compact = options.compact;
}
return escodegen.generate(astTree, escodegenParams);
}
}
module.exports = JavaScriptObfuscator;
{
"name": "javascript-obfuscator",
"version": "0.5.1",
"version": "0.5.2",
"description": "JavaScript obfuscator",

@@ -5,0 +5,0 @@ "keywords": [

#JavaScript obfuscator for Node.js
JavaScript obfuscator for Node.js and free alternative of [js-obfuscator](https://github.com/caiguanhao/js-obfuscator) (which uses [javascriptobfuscator.com](https://javascriptobfuscator.com/Javascript-Obfuscator.aspx)) without any limits and sending data on server.
JavaScript obfuscator for Node.js and free alternative to [js-obfuscator](https://github.com/caiguanhao/js-obfuscator) (which uses [javascriptobfuscator.com](https://javascriptobfuscator.com/Javascript-Obfuscator.aspx)) without any limits and sending data on server.
Compatible with ES6.

@@ -67,3 +67,3 @@ Tested on Angular2 bundle.

Compact code output in one line.
Compact code output into one line.

@@ -73,6 +73,6 @@ ####debugProtection

#####This option can cause browser freeze while Developer Tools is enabled! Use at own risk.
#####This option can cause browser freeze if Developer Tools are enabled! Use it at your own risk.
Force enable debug mode in some browsers (mainly based on WebKit) on page load, if Developers Tools panel is enbaled.
With this options using of Debug panel is impossible.
Force enable debug mode in some browsers (mainly based on WebKit) on page load, if Developer Tools panel is enabled.
With this option enabled, using of Debug panel is impossible.

@@ -85,7 +85,7 @@ WebKit based browsers: blocking site window, but you still can navigate through Developers Tools panel.

#####This option can cause browser freeze even while Developer Tools is disabled! Use at own risk.
#####This option can cause browser freeze even if Developer Tools are disabled! Use it at your own risk.
Works if `debugProtection` is enabled.
Force enable debug mode in some browsers (mainly based on WebKit) when Developers Tools panel was enbaled, even after page was loaded.
Force enable debug mode in some browsers (mainly based on WebKit) when Developers Tools panel was enabled, even after page was loaded.

@@ -97,18 +97,41 @@ ####disableConsoleOutput

####encodeUnicodeArray
Type: `boolean` Default: `false`
#####`unicodeArray` option must be enabled
This option can slightly slowdown your code speed.
All strings in unicode array becomes encoded in Base64.
To decode strings, special function will be inserted on page under `unicodeArray` node.
####reservedNames
Type: `string[]` Default: `[]`
Disable obfuscation of given variable names, function names and names of function parameters.
####rotateUnicodeArray
Type: `boolean` Default: `true`
For more hard understanding of code, during each obfuscation all literal values are stored in array as Unicode codes sequence.
This options will rotate all values inside array on a random value during obfuscation of code, and insert inside source code helper function
#####`unicodeArray` option must be enabled
This option will rotate all values inside `unicodeArray` on a random value during obfuscation of code, and insert inside source code helper function
which will rotate array values back to their original indexes.
This option affected only on visual code organisation, because we can easily get original array during debug process.
This option affects only a visual code organisation, because we can easily get original array during debug process.
Not recommended for small source code, because helper function will attract attention.
Usage is not recommended for a small source code, because helper function will attract attention.
####unicodeArray
Type: `boolean` Default: `true`
Put all literal strings into array and replace every literal string by array call.
####wrapUnicodeArrayCalls
Type: `boolean` Default: `true`
#####`unicodeArray` option must be enabled
Instead using direct calls to `unicodeArray` items `var t = _0x43a123[0x0]`,
when index `0x0` can be easy reverted to `0` with few js beautifiers, this option wrap all calls to special function instead.
when index `0x0` can be easily reverted to `0` with few js beautifiers, this option will wrap all calls to special function instead.

@@ -115,0 +138,0 @@ ```javascript

import * as esprima from 'esprima';
import { BlockScopeNode } from "../../types/BlockScopeNode";
import { INode } from "../../interfaces/nodes/INode";
import { TBlockScopeNode } from "../../types/TBlockScopeNode";
import { Node } from '../Node';

@@ -18,3 +20,3 @@ import { NodeUtils } from "../../NodeUtils";

*/
public appendNode (blockScopeNode: BlockScopeNode): void {
public appendNode (blockScopeNode: TBlockScopeNode): void {
NodeUtils.prependNode(blockScopeNode.body, this.getNode());

@@ -37,5 +39,5 @@ }

*
* @returns any
* @returns {INode}
*/
protected getNodeStructure (): any {
protected getNodeStructure (): INode {
return NodeUtils.getBlockScopeNodeByIndex(

@@ -42,0 +44,0 @@ esprima.parse(`

@@ -1,3 +0,5 @@

import { BlockScopeNode } from "../../types/BlockScopeNode";
import { IExpressionStatementNode } from "../../interfaces/nodes/IExpressionStatementNode";
import { TBlockScopeNode } from "../../types/TBlockScopeNode";
import { NodeType } from "../../enums/NodeType";

@@ -28,3 +30,3 @@

*/
public appendNode (blockScopeNode: BlockScopeNode): void {
public appendNode (blockScopeNode: TBlockScopeNode): void {
NodeUtils.appendNode(blockScopeNode.body, this.getNode());

@@ -34,5 +36,5 @@ }

/**
* @returns any
* @returns {IExpressionStatementNode}
*/
protected getNodeStructure (): any {
protected getNodeStructure (): IExpressionStatementNode {
return {

@@ -39,0 +41,0 @@ 'type': NodeType.ExpressionStatement,

@@ -1,3 +0,5 @@

import { BlockScopeNode } from "../../types/BlockScopeNode";
import { IExpressionStatementNode } from "../../interfaces/nodes/IExpressionStatementNode";
import { TBlockScopeNode } from "../../types/TBlockScopeNode";
import { NodeType } from '../../enums/NodeType';

@@ -28,3 +30,3 @@

*/
public appendNode (blockScopeNode: BlockScopeNode): void {
public appendNode (blockScopeNode: TBlockScopeNode): void {
NodeUtils.appendNode(blockScopeNode.body, this.getNode());

@@ -34,5 +36,5 @@ }

/**
* @returns any
* @returns {IExpressionStatementNode}
*/
protected getNodeStructure (): any {
protected getNodeStructure (): IExpressionStatementNode {
return {

@@ -39,0 +41,0 @@ 'type': NodeType.ExpressionStatement,

import * as esprima from 'esprima';
import { BlockScopeNode } from "../../types/BlockScopeNode";
import { INode } from "../../interfaces/nodes/INode";
import { TBlockScopeNode } from "../../types/TBlockScopeNode";
import { Node } from '../Node';

@@ -31,3 +33,3 @@ import { NodeUtils } from '../../NodeUtils';

*/
public appendNode (blockScopeNode: BlockScopeNode): void {
public appendNode (blockScopeNode: TBlockScopeNode): void {
let programBodyLength: number = blockScopeNode.body.length,

@@ -49,5 +51,5 @@ randomIndex: number = Utils.getRandomInteger(0, programBodyLength);

*
* @returns any
* @returns {INode}
*/
protected getNodeStructure (): any {
protected getNodeStructure (): INode {
return NodeUtils.getBlockScopeNodeByIndex(

@@ -54,0 +56,0 @@ esprima.parse(`

@@ -5,3 +5,3 @@ import * as esprima from 'esprima';

import { BlockScopeNode } from "../../types/BlockScopeNode";
import { TBlockScopeNode } from "../../types/TBlockScopeNode";

@@ -57,3 +57,3 @@ import { AppendState } from "../../enums/AppendState";

*/
public appendNode (blockScopeNode: BlockScopeNode): void {
public appendNode (blockScopeNode: TBlockScopeNode): void {
NodeUtils.insertNodeAtIndex(blockScopeNode.body, this.getNode(), 1);

@@ -81,5 +81,5 @@ }

/**
* @returns any
* @returns {INode}
*/
protected getNodeStructure (): any {
protected getNodeStructure (): INode {
let keyName: string = Utils.getRandomVariableName(),

@@ -86,0 +86,0 @@ node: INode = esprima.parse(`

import * as escodegen from 'escodegen';
import { INode } from '../../interfaces/nodes/INode';
import { IVariableDeclarationNode } from "../../interfaces/nodes/IVariableDeclarationNode";
import { BlockScopeNode } from "../../types/BlockScopeNode";
import { TBlockScopeNode } from "../../types/TBlockScopeNode";

@@ -56,3 +57,3 @@ import { AppendState } from '../../enums/AppendState';

*/
public appendNode (blockScopeNode: BlockScopeNode): void {
public appendNode (blockScopeNode: TBlockScopeNode): void {
NodeUtils.prependNode(blockScopeNode.body, this.getNode());

@@ -83,3 +84,3 @@ }

Utils.arrayRotate(this.unicodeArray, this.unicodeArrayRotateValue);
Utils.arrayRotate <string> (this.unicodeArray, this.unicodeArrayRotateValue);

@@ -92,5 +93,12 @@ this.updateNode();

/**
* @returns any
* @param data
*/
protected getNodeStructure (): any {
public updateNodeData (data: string): void {
this.unicodeArray.push(data);
}
/**
* @returns {INode}
*/
protected getNodeStructure (): IVariableDeclarationNode {
return {

@@ -97,0 +105,0 @@ 'type': NodeType.VariableDeclaration,

@@ -5,3 +5,3 @@ import * as esprima from 'esprima';

import { BlockScopeNode } from "../../types/BlockScopeNode";
import { TBlockScopeNode } from "../../types/TBlockScopeNode";

@@ -57,3 +57,3 @@ import { AppendState } from "../../enums/AppendState";

*/
public appendNode (blockScopeNode: BlockScopeNode): void {
public appendNode (blockScopeNode: TBlockScopeNode): void {
NodeUtils.insertNodeAtIndex(blockScopeNode.body, this.getNode(), 1);

@@ -74,5 +74,5 @@ }

/**
* @returns any
* @returns {INode}
*/
protected getNodeStructure (): any {
protected getNodeStructure (): INode {
let arrayName: string = Utils.getRandomVariableName(),

@@ -79,0 +79,0 @@ timesName: string = Utils.getRandomVariableName(),

@@ -37,2 +37,7 @@ import { INode } from '../interfaces/nodes/INode';

updateNode (): void;
/**
* @param data
*/
updateNodeData ? (data: any): void;
}

@@ -1,2 +0,2 @@

import { ICustomNode } from '../interfaces/ICustomNode';
import { IOptions } from "../interfaces/IOptions";

@@ -17,25 +17,16 @@ import { DebugProtectionFunctionCallNode } from "../custom-nodes/debug-protection-nodes/DebugProtectionFunctionCallNode";

/**
* @type {any}
*/
private options: any;
/**
* @param options
*/
constructor (options: any) {
super();
constructor (options: IOptions = {}) {
super(options);
this.options = options;
this.nodes.set(
'debugProtectionFunctionNode',
new DebugProtectionFunctionNode(this.debugProtectionFunctionIdentifier)
);
this.nodes.set(
'debugProtectionFunctionCallNode',
new DebugProtectionFunctionCallNode(this.debugProtectionFunctionIdentifier)
);
this.nodes = new Map <string, ICustomNode> ([
[
'debugProtectionFunctionNode',
new DebugProtectionFunctionNode(this.debugProtectionFunctionIdentifier)
],
[
'debugProtectionFunctionCallNode',
new DebugProtectionFunctionCallNode(this.debugProtectionFunctionIdentifier)
]
]);
if (this.options['debugProtectionInterval']) {

@@ -42,0 +33,0 @@ this.nodes.set(

import { ICustomNode } from '../interfaces/ICustomNode';
import { INodesGroup } from '../interfaces/INodesGroup';
import { IOptions } from "../interfaces/IOptions";

@@ -9,5 +10,14 @@ export abstract class NodesGroup implements INodesGroup {

*/
protected nodes: Map <string, ICustomNode>;
protected nodes: Map <string, ICustomNode> = new Map <string, ICustomNode> ();
/**
* @type {IOptions}
*/
protected options: IOptions;
constructor (options: IOptions = {}) {
this.options = options;
}
/**
* @returns {Map<string, INode>}

@@ -14,0 +24,0 @@ */

@@ -1,5 +0,6 @@

import { ICustomNode } from '../interfaces/ICustomNode';
import { IOptions } from "../interfaces/IOptions";
import { NodesGroup } from './NodesGroup';
import { UnicodeArrayCallsWrapper } from "../custom-nodes/unicode-array-nodes/UnicodeArrayCallsWrapper";
import { UnicodeArrayDecodeNode } from "../custom-nodes/unicode-array-nodes/UnicodeArrayDecodeNode";
import { UnicodeArrayNode } from '../custom-nodes/unicode-array-nodes/UnicodeArrayNode';

@@ -11,7 +12,2 @@ import { UnicodeArrayRotateFunctionNode } from '../custom-nodes/unicode-array-nodes/UnicodeArrayRotateFunctionNode';

/**
* @type {any}
*/
private options: any;
/**
* @type {string}

@@ -24,3 +20,3 @@ */

*/
private unicodeArrayRotateValue: number = Utils.getRandomInteger(100, 500);
private unicodeArrayRotateValue: number;

@@ -35,6 +31,6 @@ /**

*/
constructor (options: any) {
super();
constructor (options: IOptions = {}) {
super(options);
this.options = options;
this.unicodeArrayRotateValue = this.options['rotateUnicodeArray'] ? Utils.getRandomInteger(100, 500) : 0;

@@ -47,8 +43,6 @@ let unicodeArrayNode: UnicodeArrayNode = new UnicodeArrayNode(

this.nodes = new Map <string, ICustomNode> ([
[
'unicodeArrayNode',
unicodeArrayNode
]
]);
this.nodes.set(
'unicodeArrayNode',
unicodeArrayNode
);

@@ -66,2 +60,12 @@ if (this.options['wrapUnicodeArrayCalls']) {

if (this.options['encodeUnicodeLiterals']) {
this.nodes.set(
'unicodeArrayDecodeNode',
new UnicodeArrayDecodeNode (
this.unicodeArrayName,
unicodeArray
)
);
}
if (this.options['rotateUnicodeArray']) {

@@ -68,0 +72,0 @@ this.nodes.set(

@@ -38,3 +38,3 @@ import * as estraverse from 'estraverse';

leave: (node: INode, parentNode: INode): any => {
if (NodeUtils.isIdentifierNode(node)) {
if (NodeUtils.isIdentifierNode(node) && !this.isReservedName(node.name)) {
this.catchClauseParam.set(node.name, Utils.getRandomVariableName());

@@ -41,0 +41,0 @@ node.name = this.catchClauseParam.get(node.name);

@@ -46,3 +46,3 @@ import * as estraverse from 'estraverse';

leave: (node: INode): any => {
if (NodeUtils.isIdentifierNode(node)) {
if (NodeUtils.isIdentifierNode(node) && !this.isReservedName(node.name)) {
this.functionName.set(node.name, Utils.getRandomVariableName());

@@ -49,0 +49,0 @@ node.name = this.functionName.get(node.name);

@@ -39,3 +39,3 @@ import * as estraverse from 'estraverse';

leave: (node: INode): any => {
if (NodeUtils.isIdentifierNode(node)) {
if (NodeUtils.isIdentifierNode(node) && !this.isReservedName(node.name)) {
this.functionParams.set(node.name, Utils.getRandomVariableName());

@@ -42,0 +42,0 @@ node.name = this.functionParams.get(node.name);

@@ -38,3 +38,3 @@ import * as escodegen from 'escodegen';

case 'string':
content = this.replaceLiteralStringByUnicodeArrayCall(<string>literalNode.value);
content = this.replaceLiteralValueByUnicodeValue(<string>literalNode.value);

@@ -41,0 +41,0 @@ break;

@@ -56,3 +56,3 @@ import * as escodegen from 'escodegen';

'x-verbatim-property': {
content : this.replaceLiteralStringByUnicodeArrayCall(nodeValue),
content : this.replaceLiteralValueByUnicodeValue(nodeValue),
precedence: escodegen.Precedence.Primary

@@ -86,3 +86,3 @@ },

node['x-verbatim-property'] = {
content : this.replaceLiteralStringByUnicodeArrayCall(<string>node.value),
content : this.replaceLiteralValueByUnicodeValue(<string>node.value),
precedence: escodegen.Precedence.Primary

@@ -89,0 +89,0 @@ };

@@ -45,3 +45,3 @@ import * as estraverse from 'estraverse';

methodDefinitionNode.computed = true;
node.name = this.replaceLiteralStringByUnicodeArrayCall(node.name);
node.name = this.replaceLiteralValueByUnicodeValue(node.name);

@@ -48,0 +48,0 @@ return;

import { ICustomNode } from '../interfaces/ICustomNode';
import { INodeObfuscator } from '../interfaces/INodeObfuscator';
import { INode } from "../interfaces/nodes/INode";
import { IOptions } from "../interfaces/IOptions";

@@ -9,2 +10,3 @@ import { JSFuck } from "../enums/JSFuck";

import { Utils } from '../Utils';
import {UnicodeArrayNode} from "../custom-nodes/unicode-array-nodes/UnicodeArrayNode";

@@ -18,5 +20,5 @@ export abstract class NodeObfuscator implements INodeObfuscator {

/**
* @type any
* @type {IOptions}
*/
protected options: any;
protected options: IOptions;

@@ -27,3 +29,3 @@ /**

*/
constructor(nodes: Map <string, ICustomNode>, options: any = {}) {
constructor(nodes: Map <string, ICustomNode>, options: IOptions = {}) {
this.nodes = nodes;

@@ -40,2 +42,12 @@ this.options = options;

/**
* @param name
* @returns {boolean}
*/
protected isReservedName (name: string): boolean {
return this.options['reservedNames'].some((reservedName: string) => {
return reservedName === name;
});
}
/**
* @param node

@@ -47,6 +59,13 @@ * @param parentNode

if (NodeUtils.isIdentifierNode(node) && namesMap.has(node.name)) {
if (
(NodeUtils.isPropertyNode(parentNode) && parentNode.key === node) ||
(NodeUtils.isMemberExpressionNode(parentNode) && parentNode.computed === false && parentNode.property === node )
) {
const parentNodeIsAPropertyNode: boolean = (
NodeUtils.isPropertyNode(parentNode) &&
parentNode.key === node
),
parentNodeIsAMemberExpressionNode: boolean = (
NodeUtils.isMemberExpressionNode(parentNode) &&
parentNode.computed === false &&
parentNode.property === node
);
if (parentNodeIsAPropertyNode || parentNodeIsAMemberExpressionNode) {
return;

@@ -85,5 +104,25 @@ }

*/
protected replaceLiteralStringByUnicodeArrayCall (nodeValue: string): string {
let value: string = Utils.stringToUnicode(nodeValue),
unicodeArray: string[] = this.nodes.get('unicodeArrayNode').getNodeData(),
protected replaceLiteralValueByUnicodeValue (nodeValue: string): string {
let value: string = nodeValue;
if (this.options['encodeUnicodeLiterals']) {
value = new Buffer(encodeURI(value)).toString('base64');
}
value = Utils.stringToUnicode(value);
if (!this.options['unicodeArray']) {
return value;
}
return this.replaceLiteralValueByUnicodeArrayCall(value)
}
/**
* @param value
* @returns {string}
*/
protected replaceLiteralValueByUnicodeArrayCall (value: string): string {
let unicodeArrayNode: UnicodeArrayNode = <UnicodeArrayNode> this.nodes.get('unicodeArrayNode'),
unicodeArray: string[] = unicodeArrayNode.getNodeData(),
sameIndex: number = unicodeArray.indexOf(value),

@@ -93,7 +132,7 @@ index: number,

if (sameIndex < 0) {
if (sameIndex >= 0) {
index = sameIndex;
} else {
index = unicodeArray.length;
unicodeArray.push(Utils.stringToUnicode(nodeValue));
} else {
index = sameIndex;
unicodeArrayNode.updateNodeData(value);
}

@@ -107,4 +146,4 @@

return `${this.nodes.get('unicodeArrayNode').getNodeIdentifier()}[${hexadecimalIndex}]`;
return `${unicodeArrayNode.getNodeIdentifier()}[${hexadecimalIndex}]`;
}
}

@@ -49,3 +49,3 @@ import * as estraverse from 'estraverse';

enter: (node: INode): any => {
if (NodeUtils.isIdentifierNode(node)) {
if (NodeUtils.isIdentifierNode(node) && !this.isReservedName(node.name)) {
this.variableNames.set(node.name, Utils.getRandomVariableName());

@@ -52,0 +52,0 @@ node.name = this.variableNames.get(node.name);

@@ -12,3 +12,3 @@ import * as estraverse from 'estraverse';

import { BlockScopeNode } from "./types/BlockScopeNode";
import { TBlockScopeNode } from "./types/TBlockScopeNode";

@@ -73,3 +73,3 @@ import { NodeType } from "./enums/NodeType";

*/
public static getBlockScopeOfNode (node: INode, depth: number = 0): BlockScopeNode {
public static getBlockScopeOfNode (node: INode, depth: number = 0): TBlockScopeNode {
if (!node.parentNode) {

@@ -80,3 +80,3 @@ throw new ReferenceError('`parentNode` property of given node is `undefined`');

if (node.parentNode.type === NodeType.Program) {
return <BlockScopeNode> node.parentNode;
return <TBlockScopeNode> node.parentNode;
}

@@ -96,6 +96,17 @@

return <BlockScopeNode> node; // blocks statement of scopeNodes
return <TBlockScopeNode> node; // blocks statement of scopeNodes
}
/**
* @param bodyNode
* @returns IProgramNode
*/
public static getProgramNode (bodyNode: INode[]): IProgramNode {
return {
'type': NodeType.Program,
'body': bodyNode
};
}
/**
* @param blockScopeBody

@@ -149,3 +160,3 @@ * @param node

*/
public static isNodeHasBlockScope (node: INode): node is BlockScopeNode {
public static isNodeHasBlockScope (node: INode): node is TBlockScopeNode {
return node.hasOwnProperty('body');

@@ -185,2 +196,4 @@ }

public static parentize (node: INode): void {
let isRootNode: boolean = true;
estraverse.replace(node, {

@@ -191,5 +204,7 @@ enter: (node: INode, parentNode: INode): any => {

enumerable: true,
value: parentNode || node,
value: isRootNode ? NodeUtils.getProgramNode([node]) : parentNode || node,
writable: true
});
isRootNode = false;
}

@@ -196,0 +211,0 @@ });

import * as estraverse from 'estraverse';
import { ICustomNode } from './interfaces/ICustomNode';
import { INodeObfuscator } from './interfaces/INodeObfuscator';
import { INodesGroup } from './interfaces/INodesGroup';
import { INode } from './interfaces/nodes/INode';
import { IOptions } from "./interfaces/IOptions";
import { TNodeObfuscator } from "./types/TNodeObfuscator";
import { AppendState } from './enums/AppendState';

@@ -21,5 +23,3 @@ import { NodeType } from './enums/NodeType';

import { ObjectExpressionObfuscator } from './node-obfuscators/ObjectExpressionObfuscator';
import { UnicodeArrayNode } from './custom-nodes/unicode-array-nodes/UnicodeArrayNode';
import { UnicodeArrayNodesGroup } from './node-groups/UnicodeArrayNodesGroup';
import { Utils } from './Utils';
import { VariableDeclarationObfuscator } from './node-obfuscators/VariableDeclarationObfuscator';

@@ -34,5 +34,5 @@

/**
* @type {Map<string, Function[]>}
* @type {Map<string, TNodeObfuscator[]>}
*/
private nodeObfuscators: Map <string, Function[]> = new Map <string, Function[]> ([
private nodeObfuscators: Map <string, TNodeObfuscator[]> = new Map <string, TNodeObfuscator[]> ([
[NodeType.ArrowFunctionExpression, [FunctionObfuscator]],

@@ -54,5 +54,5 @@ [NodeType.ClassDeclaration, [FunctionDeclarationObfuscator]],

/**
* @type any
* @type {IOptions}
*/
private options: any;
private options: IOptions;

@@ -62,3 +62,3 @@ /**

*/
constructor (options: any = {}) {
constructor (options: IOptions = {}) {
this.options = options;

@@ -69,4 +69,5 @@ }

* @param node
* @returns {INode}
*/
public obfuscateNode (node: INode): void {
public obfuscateNode (node: INode): INode {
this.setNewNodes();

@@ -79,2 +80,4 @@

this.afterObfuscation(node);
return node;
}

@@ -107,3 +110,3 @@

if (node.getAppendState() === AppendState.AfterObfuscation) {
node.appendNode(NodeUtils.getBlockScopeOfNode(astTree));
node.appendNode(astTree);
}

@@ -119,3 +122,3 @@ });

if (node.getAppendState() === AppendState.BeforeObfuscation) {
node.appendNode(NodeUtils.getBlockScopeOfNode(astTree));
node.appendNode(astTree);
}

@@ -135,4 +138,4 @@ });

this.nodeObfuscators.get(node.type).forEach((obfuscator: Function) => {
new (<INodeObfuscator> obfuscator(this.nodes, this.options)).obfuscateNode(node, parentNode);
this.nodeObfuscators.get(node.type).forEach((obfuscator: TNodeObfuscator) => {
new obfuscator(this.nodes, this.options).obfuscateNode(node, parentNode);
});

@@ -164,7 +167,9 @@ }

/**
* Important to set this nodes latest to prevent runtime errors cause by `rotateUnicodeArray` option
*/
this.setNodesGroup(new UnicodeArrayNodesGroup(this.options));
if (this.options['unicodeArray']) {
/**
* Important to set this nodes latest to prevent runtime errors caused by `rotateUnicodeArray` option
*/
this.setNodesGroup(new UnicodeArrayNodesGroup(this.options));
}
}
}

@@ -20,5 +20,5 @@ export class Utils {

* @param reverse
* @returns any[]
* @returns {T[]}
*/
public static arrayRotate (array: any[], times: number, reverse: boolean = false): any[] {
public static arrayRotate <T> (array: T[], times: number, reverse: boolean = false): T[] {
if (times < 0) {

@@ -28,4 +28,4 @@ return;

let newArray: any[] = array,
temp: any;
let newArray: T[] = array,
temp: T;

@@ -50,3 +50,10 @@ while (times--) {

public static decToHex(dec: number): string {
return (dec + Math.pow(16, 6)).toString(16).substr(-6).replace(Utils.hexRepetitiveZerosRegExp, '');
const decToHexSliceValue: number = -6,
exponent: number = 6,
radix: number = 16;
return (dec + Math.pow(radix, exponent))
.toString(radix)
.substr(decToHexSliceValue)
.replace(Utils.hexRepetitiveZerosRegExp, '');
}

@@ -96,6 +103,20 @@

public static stringToUnicode (string: string): string {
const radix: number = 16;
let prefix: string,
regexp: RegExp = new RegExp('[\x00-\x7F]'),
template: string;
return `'${string.replace(/[\s\S]/g, (escape: string): string => {
return `\\u${('0000' + escape.charCodeAt(0).toString(16)).slice(-4)}`;
if (regexp.test(escape)) {
prefix = '\\x';
template = '0'.repeat(2);
} else {
prefix = '\\u';
template = '0'.repeat(4);
}
return `${prefix}${(template + escape.charCodeAt(0).toString(radix)).slice(-template.length)}`;
})}'`;
}
}

@@ -1,4 +0,4 @@

import * as JavaScriptObfuscator from "../index";
import { JavaScriptObfuscator } from '../src/JavaScriptObfuscator';
let obfuscatedCode: string = (<any>JavaScriptObfuscator).obfuscate(
let obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
`

@@ -39,3 +39,3 @@ (function(){

console.log('between', abc);
console.log('ั‚ะตัั‚', abc);

@@ -53,3 +53,4 @@ var abc = {};

{
disableConsoleOutput: false
disableConsoleOutput: false,
encodeUnicodeLiterals: true
}

@@ -56,0 +57,0 @@ );

@@ -10,3 +10,3 @@ {

"removeComments": true,
"noImplicitAny": false
"noImplicitAny": true
},

@@ -13,0 +13,0 @@ "exclude": [

@@ -6,3 +6,2 @@ {

"parameters",
"arguments",
"statements"

@@ -74,3 +73,3 @@ ],

"no-reference": true,
"no-require-imports": true,
"no-require-imports": false,
"no-shadowed-variable": false,

@@ -85,3 +84,3 @@ "no-string-literal": false,

"no-var-keyword": true,
"no-var-requires": true,
"no-var-requires": false,
"object-literal-sort-keys": true,

@@ -134,7 +133,3 @@ "one-line": [

"use-isnan": true,
"use-strict": [
true,
"check-module",
"check-function"
],
"use-strict": false,
"variable-name": false,

@@ -141,0 +136,0 @@ "whitespace": [