Explorar o código

Added Logger and new option `log`

sanex3339 %!s(int64=7) %!d(string=hai) anos
pai
achega
d5e84b1d1c

+ 1 - 0
CHANGELOG.md

@@ -2,6 +2,7 @@ Change Log
 ===
 v0.11.0
 ---
+* **New option:** `--log` enables logging of the information to the console.
 * **New option:** `renameGlobals` allows to enable obfuscation of global variable and function names with declaration.
 
 v0.10.0

+ 10 - 0
README.md

@@ -214,6 +214,7 @@ Following options are available for the JS Obfuscator:
     debugProtection: false,
     debugProtectionInterval: false,
     disableConsoleOutput: false,
+    log: false,
     mangle: false,
     renameGlobals: false,
     reservedNames: [],
@@ -247,6 +248,7 @@ Following options are available for the JS Obfuscator:
     --debugProtection <boolean>
     --debugProtectionInterval <boolean>
     --disableConsoleOutput <boolean>
+    --log <boolean>
     --mangle <boolean>
     --renameGlobals <boolean>
     --reservedNames <list> (comma separated)
@@ -492,6 +494,11 @@ Locks the obfuscated source code so it only runs on specific domains and/or sub-
 ##### Multiple domains and sub-domains
 It's possible to lock your code to more than one domain or sub-domain. For instance, to lock it so the code only runs on **www.example.com** add `www.example.com`, to make it work on any sub-domain from example.com, use `.example.com`.
 
+### `log`
+Type: `boolean` Default: `false`
+
+Enables logging of the information to the console..
+
 ### `mangle`
 Type: `boolean` Default: `false`
 
@@ -640,6 +647,7 @@ Performance will 50-100% slower than without obfuscation
 	debugProtection: true,
 	debugProtectionInterval: true,
 	disableConsoleOutput: true,
+	log: false,
 	mangle: false,
 	renameGlobals: false,
 	rotateStringArray: true,
@@ -665,6 +673,7 @@ Performance will 30-35% slower than without obfuscation
 	debugProtection: false,
 	debugProtectionInterval: false,
 	disableConsoleOutput: true,
+    log: false,
 	mangle: false,
 	renameGlobals: false,
 	rotateStringArray: true,
@@ -688,6 +697,7 @@ Performance will slightly slower than without obfuscation
 	debugProtection: false,
 	debugProtectionInterval: false,
 	disableConsoleOutput: true,
+    log: false,
 	mangle: true,
 	renameGlobals: false,
 	rotateStringArray: true,

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
dist/index.js


+ 2 - 0
package.json

@@ -19,6 +19,7 @@
     "javascript-obfuscator": "./bin/javascript-obfuscator.js"
   },
   "dependencies": {
+    "chalk": "2.0.1",
     "chance": "1.0.10",
     "class-validator": "0.7.2",
     "commander": "2.11.0",
@@ -37,6 +38,7 @@
   },
   "devDependencies": {
     "@types/chai": "4.0.1",
+    "@types/chalk": "0.4.31",
     "@types/chance": "0.7.33",
     "@types/commander": "2.9.1",
     "@types/escodegen": "0.0.6",

+ 17 - 0
src/JavaScriptObfuscatorInternal.ts

@@ -8,11 +8,14 @@ import * as ESTree from 'estree';
 
 import { IGeneratorOutput } from './interfaces/IGeneratorOutput';
 import { IJavaScriptObfuscator } from './interfaces/IJavaScriptObfsucator';
+import { ILogger } from './interfaces/logger/ILogger';
 import { IObfuscationResult } from './interfaces/IObfuscationResult';
 import { IObfuscator } from './interfaces/IObfuscator';
 import { IOptions } from './interfaces/options/IOptions';
 import { ISourceMapCorrector } from './interfaces/ISourceMapCorrector';
 
+import { LoggingMessage } from './enums/logger/LoggingMessage';
+
 @injectable()
 export class JavaScriptObfuscatorInternal implements IJavaScriptObfuscator {
     /**
@@ -23,6 +26,11 @@ export class JavaScriptObfuscatorInternal implements IJavaScriptObfuscator {
         sourceMapWithCode: true
     };
 
+    /**
+     * @type {ILogger}
+     */
+    private readonly logger: ILogger;
+
     /**
      * @type {IObfuscator}
      */
@@ -41,15 +49,18 @@ export class JavaScriptObfuscatorInternal implements IJavaScriptObfuscator {
     /**
      * @param {IObfuscator} obfuscator
      * @param {ISourceMapCorrector} sourceMapCorrector
+     * @param {ILogger} logger
      * @param {IOptions} options
      */
     constructor (
         @inject(ServiceIdentifiers.IObfuscator) obfuscator: IObfuscator,
         @inject(ServiceIdentifiers.ISourceMapCorrector) sourceMapCorrector: ISourceMapCorrector,
+        @inject(ServiceIdentifiers.ILogger) logger: ILogger,
         @inject(ServiceIdentifiers.IOptions) options: IOptions
     ) {
         this.obfuscator = obfuscator;
         this.sourceMapCorrector = sourceMapCorrector;
+        this.logger = logger;
         this.options = options;
     }
 
@@ -58,6 +69,9 @@ export class JavaScriptObfuscatorInternal implements IJavaScriptObfuscator {
      * @returns {IObfuscationResult}
      */
     public obfuscate (sourceCode: string): IObfuscationResult {
+        const timeStart: number = +(new Date());
+        this.logger.logInfo(LoggingMessage.ObfuscationStarted);
+
         // parse AST tree
         const astTree: ESTree.Program = this.parseCode(sourceCode);
 
@@ -67,6 +81,9 @@ export class JavaScriptObfuscatorInternal implements IJavaScriptObfuscator {
         // generate code
         const generatorOutput: IGeneratorOutput = this.generateCode(sourceCode, obfuscatedAstTree);
 
+        const obfuscationTime: number = (+(new Date()) - timeStart) / 1000;
+        this.logger.logSuccess(LoggingMessage.ObfuscationCompleted, String(obfuscationTime));
+
         return this.getObfuscationResult(generatorOutput);
     }
 

+ 21 - 6
src/Obfuscator.ts

@@ -11,6 +11,7 @@ import { TVisitorFunction } from './types/TVisitorFunction';
 import { TVisitorResult } from './types/TVisitorResult';
 
 import { ICustomNodeGroup } from './interfaces/custom-nodes/ICustomNodeGroup';
+import { ILogger } from './interfaces/logger/ILogger';
 import { IObfuscationEventEmitter } from './interfaces/event-emitters/IObfuscationEventEmitter';
 import { IObfuscator } from './interfaces/IObfuscator';
 import { IOptions } from './interfaces/options/IOptions';
@@ -19,6 +20,7 @@ import { IStackTraceData } from './interfaces/stack-trace-analyzer/IStackTraceDa
 import { IStorage } from './interfaces/storages/IStorage';
 import { IVisitor } from './interfaces/IVisitor';
 
+import { LoggingMessage } from './enums/logger/LoggingMessage';
 import { NodeTransformer } from './enums/container/node-transformers/NodeTransformer';
 import { ObfuscationEvent } from './enums/event-emitters/ObfuscationEvent';
 import { VisitorDirection } from './enums/VisitorDirection';
@@ -77,6 +79,11 @@ export class Obfuscator implements IObfuscator {
      */
     private readonly customNodeGroupStorage: IStorage<ICustomNodeGroup>;
 
+    /**
+     * @type {Ilogger}
+     */
+    private readonly logger: ILogger;
+
     /**
      * @type {TNodeTransformerFactory}
      */
@@ -102,6 +109,7 @@ export class Obfuscator implements IObfuscator {
      * @param {IObfuscationEventEmitter} obfuscationEventEmitter
      * @param {IStorage<ICustomNodeGroup>} customNodeGroupStorage
      * @param {TNodeTransformerFactory} nodeTransformerFactory
+     * @param {ILogger} logger
      * @param {IOptions} options
      */
     constructor (
@@ -109,12 +117,14 @@ export class Obfuscator implements IObfuscator {
         @inject(ServiceIdentifiers.IObfuscationEventEmitter) obfuscationEventEmitter: IObfuscationEventEmitter,
         @inject(ServiceIdentifiers.TCustomNodeGroupStorage) customNodeGroupStorage: IStorage<ICustomNodeGroup>,
         @inject(ServiceIdentifiers.Factory__INodeTransformer) nodeTransformerFactory: TNodeTransformerFactory,
+        @inject(ServiceIdentifiers.ILogger) logger: ILogger,
         @inject(ServiceIdentifiers.IOptions) options: IOptions
     ) {
         this.stackTraceAnalyzer = stackTraceAnalyzer;
         this.obfuscationEventEmitter = obfuscationEventEmitter;
         this.customNodeGroupStorage = customNodeGroupStorage;
         this.nodeTransformerFactory = nodeTransformerFactory;
+        this.logger = logger;
         this.options = options;
     }
 
@@ -166,16 +176,21 @@ export class Obfuscator implements IObfuscator {
         this.obfuscationEventEmitter.emit(ObfuscationEvent.BeforeObfuscation, astTree, stackTraceData);
 
         // first pass transformers: dead code injection transformer
-        astTree = this.transformAstTree(astTree, [
-            ...this.options.deadCodeInjection ? Obfuscator.deadCodeInjectionTransformersList : []
-        ]);
+        if (this.options.deadCodeInjection) {
+            this.logger.logInfo(LoggingMessage.StageDeadCodeInjection);
+
+            astTree = this.transformAstTree(astTree, Obfuscator.deadCodeInjectionTransformersList);
+        }
 
         // second pass transformers: control flow flattening transformers
-        astTree = this.transformAstTree(astTree, [
-            ...this.options.controlFlowFlattening ? Obfuscator.controlFlowTransformersList : []
-        ]);
+        if (this.options.controlFlowFlattening) {
+            this.logger.logInfo(LoggingMessage.StageControlFlowFlattening);
+
+            astTree = this.transformAstTree(astTree, Obfuscator.controlFlowTransformersList);
+        }
 
         // third pass: converting and obfuscating transformers
+        this.logger.logInfo(LoggingMessage.StageObfuscation);
         astTree = this.transformAstTree(astTree, [
             ...Obfuscator.convertingTransformersList,
             ...Obfuscator.obfuscatingTransformersList

+ 4 - 0
src/cli/JavaScriptObfuscatorCLI.ts

@@ -166,6 +166,10 @@ export class JavaScriptObfuscatorCLI {
                 'Blocks the execution of the code in domains that do not match the passed RegExp patterns (comma separated)',
                 (value: string) => value.split(',')
             )
+            .option(
+                '--log <boolean>', 'Enables logging of the information to the console',
+                BooleanSanitizer
+            )
             .option(
                 '--mangle <boolean>', 'Enables mangling of variable names',
                 BooleanSanitizer

+ 7 - 0
src/container/InversifyContainerFacade.ts

@@ -13,6 +13,7 @@ import { TInputOptions } from '../types/options/TInputOptions';
 
 import { IInversifyContainerFacade } from '../interfaces/container/IInversifyContainerFacade';
 import { IJavaScriptObfuscator } from '../interfaces/IJavaScriptObfsucator';
+import { ILogger } from '../interfaces/logger/ILogger';
 import { IObfuscationEventEmitter } from '../interfaces/event-emitters/IObfuscationEventEmitter';
 import { IObfuscationResult } from '../interfaces/IObfuscationResult';
 import { IObfuscator } from '../interfaces/IObfuscator';
@@ -21,6 +22,7 @@ import { ISourceCode } from '../interfaces/ISourceCode';
 import { ISourceMapCorrector } from '../interfaces/ISourceMapCorrector';
 
 import { JavaScriptObfuscatorInternal } from '../JavaScriptObfuscatorInternal';
+import { Logger } from '../logger/Logger';
 import { ObfuscationEventEmitter } from '../event-emitters/ObfuscationEventEmitter';
 import { ObfuscationResult } from '../ObfuscationResult';
 import { Obfuscator } from '../Obfuscator';
@@ -145,6 +147,11 @@ export class InversifyContainerFacade implements IInversifyContainerFacade {
             .toDynamicValue(() => new Options(options))
             .inSingletonScope();
 
+        this.container
+            .bind<ILogger>(ServiceIdentifiers.ILogger)
+            .to(Logger)
+            .inSingletonScope();
+
         this.container
             .bind<IJavaScriptObfuscator>(ServiceIdentifiers.IJavaScriptObfuscator)
             .to(JavaScriptObfuscatorInternal)

+ 1 - 0
src/container/ServiceIdentifiers.ts

@@ -19,6 +19,7 @@ export enum ServiceIdentifiers {
     IEscapeSequenceEncoder = 'IEscapeSequenceEncoder',
     IIdentifierObfuscatingReplacer = 'IIdentifierObfuscatingReplacer',
     IJavaScriptObfuscator = 'IJavaScriptObfuscator',
+    ILogger = 'ILogger',
     INodeTransformer = 'INodeTransformer',
     IObfuscationEventEmitter = 'IObfuscationEventEmitter',
     IObfuscationResult = 'IObfuscationResult',

+ 7 - 0
src/enums/logger/LoggingMessage.ts

@@ -0,0 +1,7 @@
+export enum LoggingMessage {
+    ObfuscationStarted = 'Obfuscation started...',
+    StageDeadCodeInjection = 'Stage: dead code injection...',
+    StageControlFlowFlattening = 'Stage: control flow flattening...',
+    StageObfuscation = 'Stage: obfuscation...',
+    ObfuscationCompleted = 'Obfuscation completed, %s sec.'
+}

+ 15 - 0
src/interfaces/logger/ILogger.d.ts

@@ -0,0 +1,15 @@
+import { LoggingMessage } from '../../enums/logger/LoggingMessage';
+
+export interface ILogger {
+    /**
+     * @param {LoggingMessage} loggingMessage
+     * @param {string} value
+     */
+    logInfo (loggingMessage: LoggingMessage, value?: string): void;
+
+    /**
+     * @param {LoggingMessage} loggingMessage
+     * @param {string} value
+     */
+    logSuccess (loggingMessage: LoggingMessage, value?: string): void;
+}

+ 1 - 0
src/interfaces/options/IOptions.d.ts

@@ -11,6 +11,7 @@ export interface IOptions {
     readonly debugProtectionInterval: boolean;
     readonly disableConsoleOutput: boolean;
     readonly domainLock: string[];
+    readonly log: boolean;
     readonly mangle: boolean;
     readonly renameGlobals: boolean;
     readonly reservedNames: string[];

+ 84 - 0
src/logger/Logger.ts

@@ -0,0 +1,84 @@
+import { injectable, inject, postConstruct } from 'inversify';
+import { ServiceIdentifiers } from '../container/ServiceIdentifiers';
+
+import * as chalk from 'chalk';
+
+import { IInitializable } from '../interfaces/IInitializable';
+import { ILogger } from '../interfaces/logger/ILogger';
+import { IOptions } from '../interfaces/options/IOptions';
+
+import { initializable } from '../decorators/Initializable';
+
+import { LoggingMessage } from '../enums/logger/LoggingMessage';
+
+@injectable()
+export class Logger implements ILogger, IInitializable {
+    /**
+     * @type {string}
+     */
+    private static readonly loggingPrefix: string = '[javascript-obfuscator]';
+
+    /**
+     * @type {ChalkChain}
+     */
+    @initializable()
+    private colorInfo: chalk.ChalkChain;
+
+    /**
+     * @type {ChalkChain}
+     */
+    @initializable()
+    private colorSuccess: chalk.ChalkChain;
+
+    /**
+     * @type {IOptions}
+     */
+    private readonly options: IOptions;
+
+    /**
+     * @param {IOptions} options
+     */
+    constructor (
+        @inject(ServiceIdentifiers.IOptions) options: IOptions
+    ) {
+        this.options = options;
+    }
+
+    @postConstruct()
+    public initialize (): void {
+        this.colorInfo = chalk.cyan;
+        this.colorSuccess = chalk.green;
+    }
+
+    /**
+     * @param {LoggingMessage} loggingMessage
+     * @param {string} value
+     */
+    public logInfo (loggingMessage: LoggingMessage, value?: string): void {
+        this.log(this.colorInfo, loggingMessage, value);
+    }
+
+    /**
+     * @param {LoggingMessage} loggingMessage
+     * @param {string} value
+     */
+    public logSuccess (loggingMessage: LoggingMessage, value?: string): void {
+        this.log(this.colorSuccess, loggingMessage, value);
+    }
+
+    /**
+     *
+     * @param loggingLevelColor
+     * @param {LoggingMessage} loggingMessage
+     * @param {string} value
+     */
+    private log (loggingLevelColor: chalk.ChalkChain, loggingMessage: LoggingMessage, value?: string): void {
+        if (!this.options.log) {
+            return;
+        }
+
+        const processedMessage: string = loggingLevelColor(`${Logger.loggingPrefix} ${loggingMessage}`);
+
+        !value ? console.log(processedMessage) : console.log(processedMessage, value);
+    }
+}

+ 6 - 0
src/options/Options.ts

@@ -99,6 +99,12 @@ export class Options implements IOptions {
     })
     public readonly domainLock: string[];
 
+    /**
+     * @type {boolean}
+     */
+    @IsBoolean()
+    public readonly log: boolean;
+
     /**
      * @type {boolean}
      */

+ 1 - 0
src/options/presets/Default.ts

@@ -13,6 +13,7 @@ export const DEFAULT_PRESET: TInputOptions = Object.freeze({
     debugProtectionInterval: false,
     disableConsoleOutput: false,
     domainLock: [],
+    log: false,
     mangle: false,
     renameGlobals: false,
     reservedNames: [],

+ 1 - 0
src/options/presets/NoCustomNodes.ts

@@ -12,6 +12,7 @@ export const NO_CUSTOM_NODES_PRESET: TInputOptions = Object.freeze({
     debugProtectionInterval: false,
     disableConsoleOutput: false,
     domainLock: [],
+    log: false,
     mangle: false,
     renameGlobals: false,
     reservedNames: [],

+ 6 - 6
yarn.lock

@@ -6,6 +6,10 @@
   version "4.0.1"
   resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.0.1.tgz#37fea779617cfec3fd2b19a0247e8bbdd5133bf6"
 
+"@types/chalk@^0.4.31":
+  version "0.4.31"
+  resolved "https://registry.yarnpkg.com/@types/chalk/-/chalk-0.4.31.tgz#a31d74241a6b1edbb973cf36d97a2896834a51f9"
+
 "@types/[email protected]":
   version "0.7.33"
   resolved "https://registry.yarnpkg.com/@types/chance/-/chance-0.7.33.tgz#9666ae5c8f602a14a67e5b608dabf1a7853a1e28"
@@ -52,11 +56,7 @@
   version "2.2.41"
   resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-2.2.41.tgz#e27cf0817153eb9f2713b2d3f6c68f1e1c3ca608"
 
-"@types/node@*":
-  version "8.0.15"
-  resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.15.tgz#8f23f8a4642ced357704d048010876fc0c7f179a"
-
-"@types/[email protected]":
+"@types/node@*", "@types/[email protected]":
   version "8.0.17"
   resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.17.tgz#677bc8c118cfb76013febb62ede1f31d2c7222a1"
 
@@ -933,7 +933,7 @@ [email protected], chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1:
     strip-ansi "^3.0.0"
     supports-color "^2.0.0"
 
-chalk@^2.0.0:
+chalk@^2.0.0, chalk@^2.0.1:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.0.1.tgz#dbec49436d2ae15f536114e76d14656cdbc0f44d"
   dependencies:

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio