javascript-obfuscator
Advanced tools
Comparing version
"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)); |
57
index.ts
"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": [ |
282992
6.01%107
13.83%7067
5.6%137
20.18%