Merge pull request #151 from javascript-obfuscator/conditional-comments-and-control-flow-flattening

Conditional comments now affects control flow flattening transformations
This commit is contained in:
Timofey Kachalov
2017-12-15 00:51:03 +03:00
committed by GitHub
11 changed files with 68 additions and 17 deletions
+1
View File
@@ -7,6 +7,7 @@ v0.13.0
* **Breaking change:** all CLI options were renamed to `kebab-case` format (`--disableConsoleOutout` -> `--disable-console-output`).
* Implemented custom `mangle` option algorithm without `esmangle`; fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/110
* Comments with `@license`, `@preserve` and `javascript-obfuscator` words won't be removed from obfuscated code.
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/147
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/149
v0.12.5
+1 -1
View File
File diff suppressed because one or more lines are too long
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "javascript-obfuscator",
"version": "0.13.0-dev.4",
"version": "0.13.0-dev.5",
"description": "JavaScript obfuscator",
"keywords": [
"obfuscator",
@@ -47,7 +47,7 @@
"@types/md5": "2.1.32",
"@types/mkdirp": "0.5.2",
"@types/mocha": "2.2.44",
"@types/node": "8.5.0",
"@types/node": "8.5.1",
"@types/sinon": "4.1.2",
"@types/string-template": "1.0.2",
"@types/webpack-env": "1.13.3",
@@ -53,6 +53,7 @@ export class MangledIdentifierNamesGenerator extends AbstractIdentifierNamesGene
const generateNewMangledName: (name: string) => string = (name: string): string => {
const nameSequence: string[] = MangledIdentifierNamesGenerator.nameSequence;
const zeroSequenceCache: string[] = [];
const nameLength: number = name.length;
const zeroSequence: (num: number) => string = (num: number): string => {
let result: string = zeroSequenceCache[num];
@@ -67,22 +68,25 @@ export class MangledIdentifierNamesGenerator extends AbstractIdentifierNamesGene
return result;
};
let cur: number = name.length - 1;
let index: number = nameLength - 1;
do {
let character: string, index: number;
const character: string = name.charAt(index);
const indexInSequence: number = nameSequence.indexOf(character);
const lastNameSequenceIndex: number = nameSequence.length - 1;
character = name.charAt(cur);
index = nameSequence.indexOf(character);
if (indexInSequence !== lastNameSequenceIndex) {
const previousNamePart: string = name.substring(0, index);
const nextCharacter: string = nameSequence[indexInSequence + 1];
const zeroSequenceCharacters: string = zeroSequence(nameLength - (index + 1));
if (index !== (nameSequence.length - 1)) {
return name.substring(0, cur) + nameSequence[index + 1] + zeroSequence(name.length - (cur + 1));
return previousNamePart + nextCharacter + zeroSequenceCharacters;
}
--cur;
} while (cur >= 0);
--index;
} while (index >= 0);
return `a${zeroSequence(name.length)}`;
return `a${zeroSequence(nameLength)}`;
};
let newMangledName: string = generateNewMangledName(previousMangledName);
@@ -215,6 +215,10 @@ export class FunctionControlFlowTransformer extends AbstractNodeTransformer {
private transformFunctionBody (functionNodeBody: ESTree.BlockStatement, controlFlowStorage: IStorage<ICustomNode>): void {
estraverse.replace(functionNodeBody, {
enter: (node: ESTree.Node, parentNode: ESTree.Node | null): any => {
if (node.ignoredNode) {
return estraverse.VisitorOption.Skip;
}
if (this.isVisitedFunctionNode(node) || !parentNode) {
return estraverse.VisitorOption.Skip;
}
@@ -7,7 +7,7 @@ import * as ESTree from 'estree';
import { TIdentifierObfuscatingReplacerFactory } from "../../types/container/node-transformers/TIdentifierObfuscatingReplacerFactory";
import { TNodeWithBlockStatement } from '../../types/node/TNodeWithBlockStatement';
import { TReplaceableIdentifiers } from '../../types/node-transformers/TReplaceableIdentifiers';
import { TReplaceableIdentifiersNames } from '../../types/node-transformers/TReplaceableIdentifiersNamesMap';
import { TReplaceableIdentifiersNames } from '../../types/node-transformers/TReplaceableIdentifiersNames';
import { IIdentifierObfuscatingReplacer } from '../../interfaces/node-transformers/obfuscating-transformers/obfuscating-replacers/IIdentifierObfuscatingReplacer';
import { IOptions } from '../../interfaces/options/IOptions';
@@ -7,7 +7,7 @@ import * as ESTree from 'estree';
import { TIdentifierObfuscatingReplacerFactory } from '../../types/container/node-transformers/TIdentifierObfuscatingReplacerFactory';
import { TNodeWithBlockStatement } from '../../types/node/TNodeWithBlockStatement';
import { TReplaceableIdentifiers } from '../../types/node-transformers/TReplaceableIdentifiers';
import { TReplaceableIdentifiersNames } from '../../types/node-transformers/TReplaceableIdentifiersNamesMap';
import { TReplaceableIdentifiersNames } from '../../types/node-transformers/TReplaceableIdentifiersNames';
import { IIdentifierObfuscatingReplacer } from '../../interfaces/node-transformers/obfuscating-transformers/obfuscating-replacers/IIdentifierObfuscatingReplacer';
import { IOptions } from '../../interfaces/options/IOptions';
@@ -171,5 +171,34 @@ describe('ConditionalCommentObfuscatingGuard', () => {
assert.equal(obfuscatedFunctionCallMatchesLength, expectedObfuscatedFunctionCallsLength);
});
});
describe('variant #5: `disable` and `enable` conditional comments with control flow flattening', () => {
const obfuscatedVariableDeclarationRegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\['[a-zA-Z0-9]{1,5}'];/;
const ignoredVariableDeclarationRegExp: RegExp = /var *bar *= *'bar';/;
let obfuscatedCode: string;
beforeEach(() => {
const code: string = readFileAsString(__dirname + '/fixtures/control-flow-flattening.js');
const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
code,
{
...NO_CUSTOM_NODES_PRESET,
controlFlowFlattening: true,
controlFlowFlatteningThreshold: 1
}
);
obfuscatedCode = obfuscationResult.getObfuscatedCode();
});
it('match #1: should obfuscate variable declaration before `disable` conditional comment', () => {
assert.match(obfuscatedCode, obfuscatedVariableDeclarationRegExp);
});
it('match #2: should ignore variable declaration after `disable` conditional comment', () => {
assert.match(obfuscatedCode, ignoredVariableDeclarationRegExp);
});
});
});
});
@@ -0,0 +1,9 @@
(function(){
var foo = 'foo';
/* javascript-obfuscator:disable */
var bar = 'bar';
/* javascript-obfuscator:enable */
console.log(foo);
console.log(bar);
})();
+7 -3
View File
@@ -68,7 +68,11 @@
version "8.0.53"
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.53.tgz#396b35af826fa66aad472c8cb7b8d5e277f4e6d8"
"@types/node@8.5.0", "@types/node@^8.0.27":
"@types/node@8.5.1":
version "8.5.1"
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.5.1.tgz#4ec3020bcdfe2abffeef9ba3fbf26fca097514b5"
"@types/node@^8.0.27":
version "8.5.0"
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.5.0.tgz#c5be22ffc84b221466fc8dfc0d6b1f88060808ef"
@@ -94,7 +98,7 @@
version "0.0.30"
resolved "https://registry.yarnpkg.com/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz#9aa30c04db212a9a0649d6ae6fd50accc40748a1"
"@types/v8flags@github:types/npm-v8flags#de224ae1cd5fd7dbb4e7158a6cc7a29e5315930d":
"@types/v8flags@types/npm-v8flags#de224ae1cd5fd7dbb4e7158a6cc7a29e5315930d":
version "2.0.0"
resolved "https://codeload.github.com/types/npm-v8flags/tar.gz/de224ae1cd5fd7dbb4e7158a6cc7a29e5315930d"
@@ -102,7 +106,7 @@
version "1.13.3"
resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.13.3.tgz#0ecbe70f87341767793774d3683b51aa3246434c"
"@types/yn@github:types/npm-yn#ca75f6c82940fae6a06fb41d2d37a6aa9b4ea8e9":
"@types/yn@types/npm-yn#ca75f6c82940fae6a06fb41d2d37a6aa9b4ea8e9":
version "2.0.0"
resolved "https://codeload.github.com/types/npm-yn/tar.gz/ca75f6c82940fae6a06fb41d2d37a6aa9b4ea8e9"