seed option and IE8 fix

This commit is contained in:
sanex3339
2016-11-21 22:05:49 +03:00
parent 22de896cc0
commit 8f3441a4f9
23 changed files with 187 additions and 59 deletions
+5
View File
@@ -1,5 +1,10 @@
Change Log
===
v0.8.1
---
* New option `seed` sets seed for random generator. This is useful for creating repeatable results.
* IE8 runtime error fix.
v0.8.1
---
* `disableConsoleOutput` option now replaces `console.xxx` functions on empty function instead of infinity loop.
+6
View File
@@ -123,6 +123,7 @@ Following options available for the JS Obfuscator:
disableConsoleOutput: true,
reservedNames: [],
rotateStringArray: true,
seed: 0,
selfDefending: true,
sourceMap: false,
sourceMapBaseUrl: '',
@@ -148,6 +149,7 @@ Following options available for the JS Obfuscator:
--disableConsoleOutput <boolean>
--reservedNames <list> (comma separated)
--rotateStringArray <boolean>
--seed <number>
--selfDefending <boolean>
--sourceMap <boolean>
--sourceMapBaseUrl <string>
@@ -218,6 +220,10 @@ Shift the `stringArray` array by a fixed and random (generated at the code obfus
This option is recommended if your original source code isn't small, as the helper function can attract attention.
### `seed`
Type: `number` Default: `0`
This option sets seed for random generator. This is useful for creating repeatable results.
### `selfDefending`
Type: `boolean` Default: `true`
+56 -28
View File
@@ -88,7 +88,7 @@ module.exports =
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 89);
/******/ return __webpack_require__(__webpack_require__.s = 88);
/******/ })
/************************************************************************/
/******/ ([
@@ -167,11 +167,32 @@ var Utils = function () {
domain = domain.split(':')[0];
return domain;
}
}, {
key: 'getRandomFloat',
value: function getRandomFloat(min, max) {
return Utils.getRandomGenerator().floating({
min: min,
max: max,
fixed: 7
});
}
}, {
key: 'getRandomGenerator',
value: function getRandomGenerator() {
var randomGenerator = Utils.randomGenerator;
if (!randomGenerator) {
throw new Error('`randomGenerator` static property is undefined');
}
return Utils.randomGenerator;
}
}, {
key: 'getRandomInteger',
value: function getRandomInteger(min, max) {
return Utils.getRandomGenerator().integer({
min: min,
max: max
});
}
}, {
key: 'getRandomVariableName',
value: function getRandomVariableName() {
@@ -180,10 +201,7 @@ var Utils = function () {
var rangeMinInteger = 10000,
rangeMaxInteger = 99999999,
prefix = '_0x';
return '' + prefix + Utils.decToHex(Utils.getRandomGenerator().integer({
min: rangeMinInteger,
max: rangeMaxInteger
})).substr(0, length);
return '' + prefix + Utils.decToHex(Utils.getRandomInteger(rangeMinInteger, rangeMaxInteger)).substr(0, length);
}
}, {
key: 'hideString',
@@ -196,7 +214,7 @@ var Utils = function () {
i2 = -1,
result = '';
while (i1 < s1.length || i2 < s2.length) {
if (Math.random() < 0.5 && i2 < s2.length) {
if (Utils.getRandomFloat(0, 1) < 0.5 && i2 < s2.length) {
result += s2.charAt(++i2);
} else {
result += s1.charAt(++i1);
@@ -245,6 +263,11 @@ var Utils = function () {
}
return result;
}
}, {
key: 'setRandomGenerator',
value: function setRandomGenerator(randomGenerator) {
Utils.randomGenerator = randomGenerator;
}
}, {
key: 'strEnumify',
value: function strEnumify(obj) {
@@ -640,10 +663,7 @@ var NodeAppender = function () {
}, {
key: 'getRandomStackTraceIndex',
value: function getRandomStackTraceIndex(stackTraceRootLength) {
return Utils_1.Utils.getRandomGenerator().integer({
min: 0,
max: Math.max(0, Math.round(stackTraceRootLength - 1))
});
return Utils_1.Utils.getRandomInteger(0, Math.max(0, Math.round(stackTraceRootLength - 1)));
}
}, {
key: 'insertNodeAtIndex',
@@ -1003,6 +1023,7 @@ exports.NO_CUSTOM_NODES_PRESET = Object.freeze({
domainLock: [],
reservedNames: [],
rotateStringArray: false,
seed: 0,
selfDefending: false,
sourceMap: false,
sourceMapBaseUrl: '',
@@ -1070,7 +1091,9 @@ var NodeCallsControllerFunctionNode = function (_AbstractCustomNode_) {
if (this.appendState === AppendState_1.AppendState.AfterObfuscation) {
return NodeUtils_1.NodeUtils.convertCodeToStructure(JavaScriptObfuscator_1.JavaScriptObfuscator.obfuscate(SingleNodeCallControllerTemplate_1.SingleNodeCallControllerTemplate().formatUnicorn({
singleNodeCallControllerFunctionName: this.callsControllerFunctionName
}), NoCustomNodesPreset_1.NO_CUSTOM_NODES_PRESET).getObfuscatedCode());
}), Object.assign({}, NoCustomNodesPreset_1.NO_CUSTOM_NODES_PRESET, {
seed: this.options.seed
})).getObfuscatedCode());
}
return NodeUtils_1.NodeUtils.convertCodeToStructure(SingleNodeCallControllerTemplate_1.SingleNodeCallControllerTemplate().formatUnicorn({
singleNodeCallControllerFunctionName: this.callsControllerFunctionName
@@ -1127,7 +1150,7 @@ var StringLiteralReplacer = function (_AbstractReplacer_1$A) {
_createClass(StringLiteralReplacer, [{
key: 'replace',
value: function replace(nodeValue) {
var replaceWithStringArrayFlag = nodeValue.length >= StringLiteralReplacer.minimumLengthForStringArray && Math.random() <= this.options.stringArrayThreshold;
var replaceWithStringArrayFlag = nodeValue.length >= StringLiteralReplacer.minimumLengthForStringArray && Utils_1.Utils.getRandomFloat(0, 1) <= this.options.stringArrayThreshold;
if (this.options.stringArray && replaceWithStringArrayFlag) {
return this.replaceStringLiteralWithStringArrayCall(nodeValue);
}
@@ -1233,7 +1256,6 @@ exports.ObfuscationResult = ObfuscationResult;
"use strict";
exports.JSFuck = {
Window: '[]["filter"]["constructor"]("return this")()',
False: '![]',
True: '!![]',
a: '(false+"")[1]',
@@ -1349,6 +1371,7 @@ exports.DEFAULT_PRESET = Object.freeze({
domainLock: [],
reservedNames: [],
rotateStringArray: true,
seed: 0,
selfDefending: true,
sourceMap: false,
sourceMapBaseUrl: '',
@@ -1391,10 +1414,12 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
var esprima = __webpack_require__(24);
var escodegen = __webpack_require__(13);
var chance_1 = __webpack_require__(82);
var ObfuscationResult_1 = __webpack_require__(20);
var Obfuscator_1 = __webpack_require__(28);
var Options_1 = __webpack_require__(57);
var SourceMapCorrector_1 = __webpack_require__(29);
var Utils_1 = __webpack_require__(0);
var JavaScriptObfuscatorInternal = function () {
function JavaScriptObfuscatorInternal(sourceCode) {
@@ -1417,6 +1442,9 @@ var JavaScriptObfuscatorInternal = function () {
var astTree = esprima.parse(this.sourceCode, {
loc: true
});
if (this.options.seed !== 0) {
Utils_1.Utils.setRandomGenerator(new chance_1.Chance(this.options.seed));
}
astTree = new Obfuscator_1.Obfuscator(this.options).obfuscateNode(astTree);
this.generatorOutput = JavaScriptObfuscatorInternal.generateCode(this.sourceCode, astTree, this.options);
}
@@ -1842,7 +1870,7 @@ var JavaScriptObfuscatorCLI = function () {
return val.split(',');
}).option('--reservedNames <list>', 'Disable obfuscation of variable names, function names and names of function parameters that match the passed RegExp patterns (comma separated)', function (val) {
return val.split(',');
}).option('--rotateStringArray <boolean>', 'Disable rotation of unicode array values during obfuscation', JavaScriptObfuscatorCLI.parseBoolean).option('--selfDefending <boolean>', 'Disables self-defending for obfuscated code', JavaScriptObfuscatorCLI.parseBoolean).option('--sourceMap <boolean>', 'Enables source map generation', JavaScriptObfuscatorCLI.parseBoolean).option('--sourceMapBaseUrl <string>', 'Sets base url to the source map import url when `--sourceMapMode=separate`').option('--sourceMapFileName <string>', 'Sets file name for output source map when `--sourceMapMode=separate`').option('--sourceMapMode <string> [inline, separate]', 'Specify source map output mode', JavaScriptObfuscatorCLI.parseSourceMapMode).option('--stringArray <boolean>', 'Disables gathering of all literal strings into an array and replacing every literal string with an array call', JavaScriptObfuscatorCLI.parseBoolean).option('--stringArrayEncoding <boolean|string> [true, false, base64, rc4]', 'Encodes all strings in strings array using base64 or rc4 (this option can slow down your code speed', JavaScriptObfuscatorCLI.parseStringArrayEncoding).option('--stringArrayThreshold <number>', 'The probability that the literal string will be inserted into stringArray (Default: 0.8, Min: 0, Max: 1)', parseFloat).option('--unicodeEscapeSequence <boolean>', 'Allows to enable/disable string conversion to unicode escape sequence', JavaScriptObfuscatorCLI.parseBoolean).parse(this.rawArguments);
}).option('--rotateStringArray <boolean>', 'Disable rotation of unicode array values during obfuscation', JavaScriptObfuscatorCLI.parseBoolean).option('--seed <number>', 'Sets seed for random generator. This is useful for creating repeatable results.', parseFloat).option('--selfDefending <boolean>', 'Disables self-defending for obfuscated code', JavaScriptObfuscatorCLI.parseBoolean).option('--sourceMap <boolean>', 'Enables source map generation', JavaScriptObfuscatorCLI.parseBoolean).option('--sourceMapBaseUrl <string>', 'Sets base url to the source map import url when `--sourceMapMode=separate`').option('--sourceMapFileName <string>', 'Sets file name for output source map when `--sourceMapMode=separate`').option('--sourceMapMode <string> [inline, separate]', 'Specify source map output mode', JavaScriptObfuscatorCLI.parseSourceMapMode).option('--stringArray <boolean>', 'Disables gathering of all literal strings into an array and replacing every literal string with an array call', JavaScriptObfuscatorCLI.parseBoolean).option('--stringArrayEncoding <boolean|string> [true, false, base64, rc4]', 'Encodes all strings in strings array using base64 or rc4 (this option can slow down your code speed', JavaScriptObfuscatorCLI.parseStringArrayEncoding).option('--stringArrayThreshold <number>', 'The probability that the literal string will be inserted into stringArray (Default: 0.8, Min: 0, Max: 1)', parseFloat).option('--unicodeEscapeSequence <boolean>', 'Allows to enable/disable string conversion to unicode escape sequence', JavaScriptObfuscatorCLI.parseBoolean).parse(this.rawArguments);
this.commands.on('--help', function () {
console.log(' Examples:\n');
console.log(' %> javascript-obfuscator in.js --compact true --selfDefending false');
@@ -2131,10 +2159,7 @@ var DebugProtectionFunctionNode = function (_AbstractCustomNode_) {
key: 'appendNode',
value: function appendNode(blockScopeNode) {
var programBodyLength = blockScopeNode.body.length,
randomIndex = Utils_1.Utils.getRandomGenerator().integer({
min: 0,
max: programBodyLength
});
randomIndex = Utils_1.Utils.getRandomInteger(0, programBodyLength);
NodeAppender_1.NodeAppender.insertNodeAtIndex(blockScopeNode, this.getNode(), randomIndex);
}
}, {
@@ -2273,7 +2298,9 @@ var SelfDefendingUnicodeNode = function (_AbstractCustomNode_) {
return NodeUtils_1.NodeUtils.convertCodeToStructure(JavaScriptObfuscator_1.JavaScriptObfuscator.obfuscate(SelfDefendingTemplate_1.SelfDefendingTemplate().formatUnicorn({
selfDefendingFunctionName: Utils_1.Utils.getRandomVariableName(),
singleNodeCallControllerFunctionName: this.callsControllerFunctionName
}), NoCustomNodesPreset_1.NO_CUSTOM_NODES_PRESET).getObfuscatedCode());
}), Object.assign({}, NoCustomNodesPreset_1.NO_CUSTOM_NODES_PRESET, {
seed: this.options.seed
})).getObfuscatedCode());
}
}]);
@@ -2385,7 +2412,9 @@ var StringArrayCallsWrapper = function (_AbstractCustomNode_) {
decodeNodeTemplate: decodeNodeTemplate,
stringArrayCallsWrapperName: this.stringArrayCallsWrapperName,
stringArrayName: this.stringArrayName
}), NoCustomNodesPreset_1.NO_CUSTOM_NODES_PRESET).getObfuscatedCode());
}), Object.assign({}, NoCustomNodesPreset_1.NO_CUSTOM_NODES_PRESET, {
seed: this.options.seed
})).getObfuscatedCode());
}
}]);
@@ -2557,7 +2586,9 @@ var StringArrayRotateFunctionNode = function (_AbstractCustomNode_) {
stringArrayName: this.stringArrayName,
stringArrayRotateValue: Utils_1.Utils.decToHex(this.stringArrayRotateValue),
whileFunctionName: whileFunctionName
}), NoCustomNodesPreset_1.NO_CUSTOM_NODES_PRESET).getObfuscatedCode());
}), Object.assign({}, NoCustomNodesPreset_1.NO_CUSTOM_NODES_PRESET, {
seed: this.options.seed
})).getObfuscatedCode());
}
}]);
@@ -2805,10 +2836,7 @@ var StringArrayNodesGroup = function (_AbstractNodesGroup_) {
return;
}
if (this.options.rotateStringArray) {
this.stringArrayRotateValue = Utils_1.Utils.getRandomGenerator().integer({
min: 100,
max: 500
});
this.stringArrayRotateValue = Utils_1.Utils.getRandomInteger(100, 500);
} else {
this.stringArrayRotateValue = 0;
}
@@ -3593,6 +3621,7 @@ __decorate([class_validator_1.IsArray(), class_validator_1.ArrayUnique(), class_
each: true
}), __metadata('design:type', Array)], Options.prototype, "reservedNames", void 0);
__decorate([class_validator_1.IsBoolean(), __metadata('design:type', Boolean)], Options.prototype, "rotateStringArray", void 0);
__decorate([class_validator_1.IsNumber(), __metadata('design:type', Number)], Options.prototype, "seed", void 0);
__decorate([class_validator_1.IsBoolean(), __metadata('design:type', Boolean)], Options.prototype, "selfDefending", void 0);
__decorate([class_validator_1.IsBoolean(), __metadata('design:type', Boolean)], Options.prototype, "sourceMap", void 0);
__decorate([class_validator_1.IsString(), class_validator_1.ValidateIf(function (options) {
@@ -4271,7 +4300,7 @@ exports.DebugProtectionFunctionIntervalTemplate = DebugProtectionFunctionInterva
var Utils_1 = __webpack_require__(0);
function DebugProtectionFunctionTemplate() {
return '\n var {debugProtectionFunctionName} = function () {\n function debuggerProtection (counter) {\n if ((\'\' + counter / counter)[\'length\'] !== 1 || counter % 20 === 0) {\n (function () {}.constructor(\'debugger\')());\n } else {\n [].filter.constructor(' + Utils_1.Utils.stringToJSFuck('debugger') + ')();\n }\n \n debuggerProtection(++counter);\n }\n \n try {\n debuggerProtection(0);\n } catch (y) {}\n };\n ';
return '\n var {debugProtectionFunctionName} = function () {\n function debuggerProtection (counter) {\n if ((\'\' + counter / counter)[\'length\'] !== 1 || counter % 20 === 0) {\n (function () {}.constructor(' + Utils_1.Utils.stringToJSFuck('debugger') + ')());\n } else {\n (function () {}.constructor(' + Utils_1.Utils.stringToJSFuck('debugger') + ')());\n }\n \n debuggerProtection(++counter);\n }\n \n try {\n debuggerProtection(0);\n } catch (y) {}\n };\n ';
}
exports.DebugProtectionFunctionTemplate = DebugProtectionFunctionTemplate;
@@ -4432,8 +4461,7 @@ module.exports = require("mkdirp");
/***/ },
/* 87 */,
/* 88 */,
/* 89 */
/* 88 */
/***/ function(module, exports, __webpack_require__) {
"use strict";
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "javascript-obfuscator",
"version": "0.8.1",
"version": "0.8.2",
"description": "JavaScript obfuscator",
"keywords": [
"obfuscator",
+7
View File
@@ -2,6 +2,8 @@ import * as esprima from 'esprima';
import * as escodegen from 'escodegen';
import * as ESTree from 'estree';
import { Chance } from 'chance';
import { IObfuscatorOptions } from './interfaces/IObfuscatorOptions';
import { IGeneratorOutput } from './interfaces/IGeneratorOutput';
import { IObfuscationResult } from './interfaces/IObfuscationResult';
@@ -11,6 +13,7 @@ import { ObfuscationResult } from './ObfuscationResult';
import { Obfuscator } from './Obfuscator';
import { Options } from './options/Options';
import { SourceMapCorrector } from './SourceMapCorrector';
import { Utils } from './Utils';
export class JavaScriptObfuscatorInternal {
/**
@@ -91,6 +94,10 @@ export class JavaScriptObfuscatorInternal {
loc: true
});
if (this.options.seed !== 0) {
Utils.setRandomGenerator(new Chance(this.options.seed));
}
astTree = new Obfuscator(this.options).obfuscateNode(astTree);
this.generatorOutput = JavaScriptObfuscatorInternal.generateCode(this.sourceCode, astTree, this.options);
+42 -7
View File
@@ -4,9 +4,9 @@ import { JSFuck } from './enums/JSFuck';
export class Utils {
/**
* @type {Chance.Chance}
* @type {Chance.Chance | Chance.SeededChance}
*/
private static randomGenerator: Chance.Chance = new Chance();
private static randomGenerator: Chance.Chance | Chance.SeededChance = new Chance();
/**
* @param array
@@ -99,13 +99,44 @@ export class Utils {
return domain;
}
/**
* @param min
* @param max
* @returns {number}
*/
public static getRandomFloat (min: number, max: number): number {
return Utils.getRandomGenerator().floating({
min: min,
max: max,
fixed: 7
});
}
/**
* @returns {Chance.Chance}
*/
public static getRandomGenerator (): Chance.Chance {
const randomGenerator: Chance.Chance = Utils.randomGenerator;
if (!randomGenerator) {
throw new Error(`\`randomGenerator\` static property is undefined`);
}
return Utils.randomGenerator;
}
/**
* @param min
* @param max
* @returns {number}
*/
public static getRandomInteger (min: number, max: number): number {
return Utils.getRandomGenerator().integer({
min: min,
max: max
});
}
/**
* @param length
* @returns {string}
@@ -117,10 +148,7 @@ export class Utils {
return `${prefix}${(
Utils.decToHex(
Utils.getRandomGenerator().integer({
min: rangeMinInteger,
max: rangeMaxInteger
})
Utils.getRandomInteger(rangeMinInteger, rangeMaxInteger)
)
).substr(0, length)}`;
}
@@ -140,7 +168,7 @@ export class Utils {
result: string = '';
while (i1 < s1.length || i2 < s2.length) {
if (Math.random() < 0.5 && i2 < s2.length) {
if (Utils.getRandomFloat(0, 1) < 0.5 && i2 < s2.length) {
result += s2.charAt(++i2);
} else {
result += s1.charAt(++i1);
@@ -213,6 +241,13 @@ export class Utils {
return result;
}
/**
* @param randomGenerator
*/
public static setRandomGenerator (randomGenerator: Chance.Chance | Chance.SeededChance): void {
Utils.randomGenerator = randomGenerator;
}
/**
* @param obj
* @returns {T}
+1
View File
@@ -151,6 +151,7 @@ export class JavaScriptObfuscatorCLI {
.option('--domainLock <list>', 'Blocks the execution of the code in domains that do not match the passed RegExp patterns (comma separated)', (val: string) => val.split(','))
.option('--reservedNames <list>', 'Disable obfuscation of variable names, function names and names of function parameters that match the passed RegExp patterns (comma separated)', (val: string) => val.split(','))
.option('--rotateStringArray <boolean>', 'Disable rotation of unicode array values during obfuscation', JavaScriptObfuscatorCLI.parseBoolean)
.option('--seed <number>', 'Sets seed for random generator. This is useful for creating repeatable results.', parseFloat)
.option('--selfDefending <boolean>', 'Disables self-defending for obfuscated code', JavaScriptObfuscatorCLI.parseBoolean)
.option('--sourceMap <boolean>', 'Enables source map generation', JavaScriptObfuscatorCLI.parseBoolean)
.option('--sourceMapBaseUrl <string>', 'Sets base url to the source map import url when `--sourceMapMode=separate`')
@@ -40,10 +40,7 @@ export class DebugProtectionFunctionNode extends AbstractCustomNode {
*/
public appendNode (blockScopeNode: TNodeWithBlockStatement): void {
let programBodyLength: number = blockScopeNode.body.length,
randomIndex: number = Utils.getRandomGenerator().integer({
min: 0,
max: programBodyLength
});
randomIndex: number = Utils.getRandomInteger(0, programBodyLength);
NodeAppender.insertNodeAtIndex(blockScopeNode, this.getNode(), randomIndex);
}
@@ -79,9 +79,14 @@ export class NodeCallsControllerFunctionNode extends AbstractCustomNode {
protected getNodeStructure (): TStatement[] {
if (this.appendState === AppendState.AfterObfuscation) {
return NodeUtils.convertCodeToStructure(
JavaScriptObfuscator.obfuscate(SingleNodeCallControllerTemplate().formatUnicorn({
singleNodeCallControllerFunctionName: this.callsControllerFunctionName
}), NO_CUSTOM_NODES_PRESET).getObfuscatedCode()
JavaScriptObfuscator.obfuscate(
SingleNodeCallControllerTemplate().formatUnicorn({
singleNodeCallControllerFunctionName: this.callsControllerFunctionName
}),
Object.assign({}, NO_CUSTOM_NODES_PRESET, {
seed: this.options.seed
})
).getObfuscatedCode()
);
}
@@ -78,7 +78,9 @@ export class SelfDefendingUnicodeNode extends AbstractCustomNode {
selfDefendingFunctionName: Utils.getRandomVariableName(),
singleNodeCallControllerFunctionName: this.callsControllerFunctionName
}),
NO_CUSTOM_NODES_PRESET
Object.assign({}, NO_CUSTOM_NODES_PRESET, {
seed: this.options.seed
})
).getObfuscatedCode()
);
}
@@ -139,7 +139,9 @@ export class StringArrayCallsWrapper extends AbstractCustomNode {
stringArrayCallsWrapperName: this.stringArrayCallsWrapperName,
stringArrayName: this.stringArrayName
}),
NO_CUSTOM_NODES_PRESET
Object.assign({}, NO_CUSTOM_NODES_PRESET, {
seed: this.options.seed
})
).getObfuscatedCode()
);
}
@@ -103,7 +103,9 @@ export class StringArrayRotateFunctionNode extends AbstractCustomNode {
stringArrayRotateValue: Utils.decToHex(this.stringArrayRotateValue),
whileFunctionName
}),
NO_CUSTOM_NODES_PRESET
Object.assign({}, NO_CUSTOM_NODES_PRESET, {
seed: this.options.seed
})
).getObfuscatedCode()
);
}
-2
View File
@@ -1,6 +1,4 @@
export const JSFuck: any = {
Window: '[]["filter"]["constructor"]("return this")()',
False: '![]',
True: '!![]',
+1
View File
@@ -9,6 +9,7 @@ export interface IObfuscatorOptions {
domainLock?: string[];
reservedNames?: string[];
rotateStringArray?: boolean;
seed?: number;
selfDefending?: boolean;
sourceMap?: boolean;
sourceMapBaseUrl?: string;
+1
View File
@@ -9,6 +9,7 @@ export interface IOptions {
readonly domainLock: string[];
readonly reservedNames: string[];
readonly rotateStringArray: boolean;
readonly seed: number;
readonly selfDefending: boolean;
readonly sourceMap: boolean;
readonly sourceMapBaseUrl: string;
+1 -4
View File
@@ -40,10 +40,7 @@ export class StringArrayNodesGroup extends AbstractNodesGroup {
}
if (this.options.rotateStringArray) {
this.stringArrayRotateValue = Utils.getRandomGenerator().integer({
min: 100,
max: 500
});
this.stringArrayRotateValue = Utils.getRandomInteger(100, 500);
} else {
this.stringArrayRotateValue = 0;
}
@@ -27,7 +27,7 @@ export class StringLiteralReplacer extends AbstractReplacer {
public replace (nodeValue: string): string {
const replaceWithStringArrayFlag: boolean = (
nodeValue.length >= StringLiteralReplacer.minimumLengthForStringArray
&& Math.random() <= this.options.stringArrayThreshold
&& Utils.getRandomFloat(0, 1) <= this.options.stringArrayThreshold
);
if (this.options.stringArray && replaceWithStringArrayFlag) {
+1 -4
View File
@@ -101,10 +101,7 @@ export class NodeAppender {
* @param stackTraceRootLength
*/
public static getRandomStackTraceIndex (stackTraceRootLength: number): number {
return Utils.getRandomGenerator().integer({
min: 0,
max: Math.max(0, Math.round(stackTraceRootLength - 1))
});
return Utils.getRandomInteger(0, Math.max(0, Math.round(stackTraceRootLength - 1)));
}
/**
+6
View File
@@ -85,6 +85,12 @@ export class Options implements IOptions {
@IsBoolean()
public readonly rotateStringArray: boolean;
/**
* @type {number}
*/
@IsNumber()
public readonly seed: number;
/**
* @type {boolean}
*/
+1
View File
@@ -10,6 +10,7 @@ export const DEFAULT_PRESET: IObfuscatorOptions = Object.freeze({
domainLock: [],
reservedNames: [],
rotateStringArray: true,
seed: 0,
selfDefending: true,
sourceMap: false,
sourceMapBaseUrl: '',
@@ -10,6 +10,7 @@ export const NO_CUSTOM_NODES_PRESET: IObfuscatorOptions = Object.freeze({
domainLock: [],
reservedNames: [],
rotateStringArray: false,
seed: 0,
selfDefending: false,
sourceMap: false,
sourceMapBaseUrl: '',
@@ -8,9 +8,9 @@ export function DebugProtectionFunctionTemplate (): string {
var {debugProtectionFunctionName} = function () {
function debuggerProtection (counter) {
if (('' + counter / counter)['length'] !== 1 || counter % 20 === 0) {
(function () {}.constructor('debugger')());
(function () {}.constructor(${Utils.stringToJSFuck('debugger')})());
} else {
[].filter.constructor(${Utils.stringToJSFuck('debugger')})();
(function () {}.constructor(${Utils.stringToJSFuck('debugger')})());
}
debuggerProtection(++counter);
@@ -3,6 +3,7 @@ import { IObfuscationResult } from '../../src/interfaces/IObfuscationResult';
import { JavaScriptObfuscator } from '../../src/JavaScriptObfuscator';
import { NO_CUSTOM_NODES_PRESET } from '../../src/preset-options/NoCustomNodesPreset';
import { readFileAsString } from '../helpers/readFileAsString';
const assert: Chai.AssertStatic = require('chai').assert;
@@ -125,5 +126,40 @@ describe('JavaScriptObfuscator', () => {
assert.match(obfuscatedCode2, pattern1);
assert.match(obfuscatedCode2, pattern2);
});
it('should returns same code every time with same `seed`', () => {
const code: string = readFileAsString('./test/fixtures/sample.js');
const seed: number = 12345;
const obfuscationResult1: IObfuscationResult = JavaScriptObfuscator.obfuscate(
code, { seed: seed }
);
const obfuscationResult2: IObfuscationResult = JavaScriptObfuscator.obfuscate(
code, { seed: seed }
);
assert.equal(obfuscationResult1.getObfuscatedCode(), obfuscationResult2.getObfuscatedCode());
});
it('should returns different code with different `seed` option value', () => {
const code: string = readFileAsString('./test/fixtures/sample.js');
const obfuscationResult1: IObfuscationResult = JavaScriptObfuscator.obfuscate(
code, { seed: 12345 }
);
const obfuscationResult2: IObfuscationResult = JavaScriptObfuscator.obfuscate(
code, { seed: 12346 }
);
const obfuscationResult3: IObfuscationResult = JavaScriptObfuscator.obfuscate(
code, { seed: 0 }
);
const obfuscationResult4: IObfuscationResult = JavaScriptObfuscator.obfuscate(
code, { seed: 0 }
);
assert.notEqual(obfuscationResult1.getObfuscatedCode(), obfuscationResult2.getObfuscatedCode());
assert.notEqual(obfuscationResult3.getObfuscatedCode(), obfuscationResult4.getObfuscatedCode());
});
});
});