Merge pull request #290 from javascript-obfuscator/object-keys-unicode-escape-sequence

Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/…
This commit is contained in:
Timofey Kachalov
2018-07-12 01:34:53 +03:00
committed by GitHub
11 changed files with 866 additions and 590 deletions
+4
View File
@@ -1,5 +1,9 @@
Change Log
===
v0.18.0
---
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/289
v0.17.0
---
* **Browser version**: Added browser version dist
+2 -2
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+12 -12
View File
@@ -1,6 +1,6 @@
{
"name": "javascript-obfuscator",
"version": "0.17.0",
"version": "0.18.0-dev.1",
"description": "JavaScript obfuscator",
"keywords": [
"obfuscator",
@@ -21,11 +21,11 @@
},
"types": "index.d.ts",
"dependencies": {
"@babel/runtime": "7.0.0-beta.51",
"@babel/runtime": "7.0.0-beta.53",
"chalk": "2.4.1",
"chance": "1.0.16",
"class-validator": "0.8.5",
"commander": "2.15.1",
"commander": "2.16.0",
"escodegen-wallaby": "1.6.18",
"espree": "4.0.0",
"estraverse": "4.2.0",
@@ -41,10 +41,10 @@
"tslib": "1.9.3"
},
"devDependencies": {
"@babel/cli": "7.0.0-beta.51",
"@babel/core": "7.0.0-beta.51",
"@babel/plugin-transform-runtime": "7.0.0-beta.51",
"@babel/preset-env": "7.0.0-beta.51",
"@babel/cli": "7.0.0-beta.53",
"@babel/core": "7.0.0-beta.53",
"@babel/plugin-transform-runtime": "7.0.0-beta.53",
"@babel/preset-env": "7.0.0-beta.53",
"@types/chai": "4.1.4",
"@types/chance": "1.0.1",
"@types/escodegen": "0.0.6",
@@ -52,9 +52,9 @@
"@types/estree": "0.0.38",
"@types/md5": "2.1.32",
"@types/mkdirp": "0.5.2",
"@types/mocha": "5.2.3",
"@types/mocha": "5.2.4",
"@types/multimatch": "2.1.2",
"@types/node": "10.3.6",
"@types/node": "10.5.2",
"@types/rimraf": "2.0.2",
"@types/sinon": "5.0.1",
"@types/string-template": "1.0.2",
@@ -62,13 +62,13 @@
"awesome-typescript-loader": "5.2.0",
"babel-loader": "8.0.0-beta.3",
"chai": "4.1.2",
"coveralls": "3.0.1",
"coveralls": "3.0.2",
"istanbul": "1.1.0-alpha.1",
"mocha": "5.2.0",
"pjson": "1.0.9",
"pre-commit": "1.2.2",
"rimraf": "2.6.2",
"sinon": "6.0.1",
"sinon": "6.1.3",
"threads": "0.12.0",
"ts-node": "6.1.0",
"tslint": "5.10.0",
@@ -77,7 +77,7 @@
"tslint-microsoft-contrib": "5.0.3",
"tslint-webpack-plugin": "1.2.2",
"typescript": "2.9.2",
"webpack": "4.12.2",
"webpack": "4.16.0",
"webpack-cli": "3.0.8",
"webpack-node-externals": "1.7.2"
},
+4 -3
View File
@@ -1,7 +1,8 @@
export interface IEscapeSequenceEncoder {
/**
* @param string
* @param usingUnicodeEscapeSequence
* @param {string} string
* @param {boolean} encodeAllSymbols
* @returns {string}
*/
encode (string: string, usingUnicodeEscapeSequence: boolean): string;
encode (string: string, encodeAllSymbols: boolean): string;
}
@@ -12,6 +12,7 @@ import { TransformationStage } from '../../enums/node-transformers/Transformatio
import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
import { NodeFactory } from '../../node/NodeFactory';
import { NodeGuards } from '../../node/NodeGuards';
import { IEscapeSequenceEncoder } from '../../interfaces/utils/IEscapeSequenceEncoder';
/**
* replaces:
@@ -23,14 +24,23 @@ import { NodeGuards } from '../../node/NodeGuards';
@injectable()
export class ObjectExpressionTransformer extends AbstractNodeTransformer {
/**
* @type {IEscapeSequenceEncoder}
*/
private readonly escapeSequenceEncoder: IEscapeSequenceEncoder;
/**
* @param {IEscapeSequenceEncoder} escapeSequenceEncoder
* @param {IRandomGenerator} randomGenerator
* @param {IOptions} options
*/
constructor (
@inject(ServiceIdentifiers.IEscapeSequenceEncoder) escapeSequenceEncoder: IEscapeSequenceEncoder,
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
super(randomGenerator, options);
this.escapeSequenceEncoder = escapeSequenceEncoder;
}
/**
@@ -61,19 +71,53 @@ export class ObjectExpressionTransformer extends AbstractNodeTransformer {
public transformNode (objectExpressionNode: ESTree.ObjectExpression, parentNode: ESTree.Node): ESTree.Node {
objectExpressionNode.properties
.forEach((property: ESTree.Property) => {
if (property.computed || !property.key) {
if (!property.key) {
return;
}
if (property.shorthand) {
property.shorthand = false;
}
if (NodeGuards.isIdentifierNode(property.key)) {
property.key = NodeFactory.literalNode(property.key.name);
if (property.computed) {
this.transformComputedProperty(property);
} else {
this.transformBaseProperty(property);
}
});
return objectExpressionNode;
}
/**
* @param {Property} property
*/
private transformComputedProperty(property: ESTree.Property): void {
if (!NodeGuards.isLiteralNode(property.key) || !(typeof property.key.value === 'string')) {
return;
}
property.key = NodeFactory.literalNode(this.getPropertyKeyValue(property.key.value));
}
/**
* @param {Property} property
*/
private transformBaseProperty(property: ESTree.Property): void {
if (property.shorthand) {
property.shorthand = false;
}
if (!NodeGuards.isIdentifierNode(property.key)) {
return;
}
property.key = NodeFactory.literalNode(this.getPropertyKeyValue(property.key.name));
}
/**
* @param {string} inputValue
* @returns {string}
*/
private getPropertyKeyValue(inputValue: string): string {
return this.options.unicodeEscapeSequence
? this.escapeSequenceEncoder.encode(inputValue, true)
: inputValue;
}
}
@@ -10,24 +10,50 @@ import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFac
describe('ObjectExpressionTransformer', () => {
describe('default behaviour', () => {
const regExp: RegExp = /var *test *= *\{'foo':0x0\};/;
describe('Variant #1: `unicodeEscapeSequence` option is disabled\'', () => {
const regExp: RegExp = /var *test *= *\{'foo':0x0\};/;
let obfuscatedCode: string;
let obfuscatedCode: string;
before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/property-with-identifier-value.js');
const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET
}
);
before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/property-with-identifier-value.js');
const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
unicodeEscapeSequence: false
}
);
obfuscatedCode = obfuscationResult.getObfuscatedCode();
});
obfuscatedCode = obfuscationResult.getObfuscatedCode();
});
it('should replace object expression node `key` property with identifier value by property with literal value', () => {
assert.match(obfuscatedCode, regExp);
it('should replace object expression node `key` property with identifier value by property with literal value', () => {
assert.match(obfuscatedCode, regExp);
});
});
describe('Variant #2: `unicodeEscapeSequence` option is enabled', () => {
const regExp: RegExp = /var *test *= *\{'\\x66\\x6f\\x6f':0x0\};/;
let obfuscatedCode: string;
before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/property-with-identifier-value.js');
const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
unicodeEscapeSequence: true
}
);
obfuscatedCode = obfuscationResult.getObfuscatedCode();
});
it('should replace object expression node `key` property with identifier value by property with encoded literal value', () => {
assert.match(obfuscatedCode, regExp);
});
});
});
@@ -54,24 +80,74 @@ describe('ObjectExpressionTransformer', () => {
});
describe('computed property name', () => {
const regExp: RegExp = /var *_0x[a-f0-9]{4,6} *= *\{\[_0x[a-f0-9]{4,6}\]: *0x1\};/;
describe('Variant #1: computed property name with identifier', () => {
const regExp: RegExp = /var *_0x[a-f0-9]{4,6} *= *\{\[_0x[a-f0-9]{4,6}\]: *0x1\};/;
let obfuscatedCode: string;
let obfuscatedCode: string;
before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/computed-property-name.js');
const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET
}
);
before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/computed-property-name-identifier.js');
const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET
}
);
obfuscatedCode = obfuscationResult.getObfuscatedCode();
obfuscatedCode = obfuscationResult.getObfuscatedCode();
});
it('should ignore computed property identifier', () => {
assert.match(obfuscatedCode, regExp);
});
});
it('should ignore computed property identifier', () => {
assert.match(obfuscatedCode, regExp);
describe('Variant #2: computed property name with literal', () => {
describe('Variant #1: `unicodeEscapeSequence` option is disabled', () => {
const regExp: RegExp = /var *_0x[a-f0-9]{4,6} *= *\{\['foo'\]: *0x1\};/;
let obfuscatedCode: string;
before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/computed-property-name-literal.js');
const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
unicodeEscapeSequence: false
}
);
obfuscatedCode = obfuscationResult.getObfuscatedCode();
});
it('should ignore computed property identifier', () => {
assert.match(obfuscatedCode, regExp);
});
});
describe('Variant #2: `unicodeEscapeSequence` option is enabled', () => {
const regExp: RegExp = /var *_0x[a-f0-9]{4,6} *= *\{\['\\x66\\x6f\\x6f'\]: *0x1\};/;
let obfuscatedCode: string;
before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/computed-property-name-literal.js');
const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
unicodeEscapeSequence: true
}
);
obfuscatedCode = obfuscationResult.getObfuscatedCode();
});
it('should ignore computed property identifier', () => {
assert.match(obfuscatedCode, regExp);
});
});
});
});
@@ -0,0 +1,5 @@
(function () {
var test = {
['foo']: 1
};
})();
+683 -537
View File
File diff suppressed because it is too large Load Diff