Parcourir la source

Added number numerical expression analyzer

sanex3339 il y a 4 ans
Parent
commit
f07452e139

Fichier diff supprimé car celui-ci est trop grand
+ 0 - 0
dist/index.cli.js


Fichier diff supprimé car celui-ci est trop grand
+ 0 - 0
dist/index.js


+ 3 - 3
package.json

@@ -54,7 +54,7 @@
     "@types/mkdirp": "1.0.1",
     "@types/mocha": "7.0.2",
     "@types/multimatch": "4.0.0",
-    "@types/node": "14.0.20",
+    "@types/node": "14.0.22",
     "@types/rimraf": "3.0.0",
     "@types/sinon": "9.0.4",
     "@types/string-template": "1.0.2",
@@ -65,7 +65,7 @@
     "coveralls": "3.1.0",
     "eslint": "7.4.0",
     "eslint-plugin-import": "2.22.0",
-    "eslint-plugin-jsdoc": "29.1.2",
+    "eslint-plugin-jsdoc": "29.1.3",
     "eslint-plugin-no-null": "1.0.2",
     "eslint-plugin-prefer-arrow": "1.2.1",
     "eslint-plugin-unicorn": "20.1.0",
@@ -83,7 +83,7 @@
     "typescript": "3.9.6",
     "webpack": "4.43.0",
     "webpack-cli": "3.3.12",
-    "webpack-node-externals": "2.3.0"
+    "webpack-node-externals": "2.5.0"
   },
   "repository": {
     "type": "git",

+ 115 - 0
src/analyzers/number-numerical-expression-analyzer/NumberNumericalExpressionAnalyzer.ts

@@ -0,0 +1,115 @@
+import { injectable, inject } from 'inversify';
+
+import { TNumberNumericalExpressionData } from '../../types/analyzers/number-numerical-expression-analyzer/TNumberNumericalExpressionData';
+
+import { INumberNumericalExpressionAnalyzer } from '../../interfaces/analyzers/number-numerical-expression-analyzer/INumberNumericalExpressionAnalyzer';
+import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
+
+import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
+
+/**
+ * Rework of https://gist.github.com/da411d/0e59f79dcf4603cdabf0024a10eeb6fe
+ */
+@injectable()
+export class NumberNumericalExpressionAnalyzer implements INumberNumericalExpressionAnalyzer {
+    /**
+     * @type {number}
+     */
+    private static readonly additionalParts: number = 5;
+
+    /**
+     * @type {IRandomGenerator}
+     */
+    private readonly randomGenerator: IRandomGenerator;
+
+    /**
+     * @param {IRandomGenerator} randomGenerator
+     */
+    public constructor (
+        @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator
+    ) {
+        this.randomGenerator = randomGenerator;
+    }
+
+    /**
+     * @param {number} number
+     * @returns {TNumberNumericalExpressionData}
+     */
+    public analyze (number: number): TNumberNumericalExpressionData {
+        if (isNaN(number)) {
+            throw new Error('Given value is NaN');
+        }
+
+        const additionParts: number[] = this.generateAdditionParts(number);
+
+        return additionParts.map((addition: number) => this.mixWithMultiplyParts(addition));
+    }
+
+    /**
+     * @param {number} number
+     * @returns {number[]}
+     */
+    private generateAdditionParts (number: number): number[] {
+        const additionParts = [];
+
+        const from: number = Math.min(-10000, -Math.abs(number * 2));
+        const to: number = Math.max(10000, Math.abs(number * 2));
+
+        let temporarySum = 0;
+
+        for (let i = 0; i < NumberNumericalExpressionAnalyzer.additionalParts; i++) {
+            if (i < NumberNumericalExpressionAnalyzer.additionalParts - 1) {
+                // trailing parts
+
+                const addition: number = this.randomGenerator.getRandomInteger(from, to);
+
+                additionParts.push(addition);
+                temporarySum += addition;
+            } else {
+                // last part
+
+                additionParts.push(number - temporarySum);
+            }
+        }
+
+        return additionParts;
+    }
+
+    /**
+     * @param {number} number
+     * @returns {number | number[]}
+     */
+    private mixWithMultiplyParts (number: number): number | number[] {
+        const dividers: number[] = this.getDividers(number);
+
+        const shouldMixWithMultiplyParts: boolean = this.randomGenerator.getMathRandom() > 0.5;
+
+        if (!shouldMixWithMultiplyParts || !dividers.length) {
+            return number;
+        }
+
+        const divider = dividers[
+            this.randomGenerator.getRandomInteger(0, dividers.length - 1)
+        ];
+
+        return [divider, number / divider];
+    }
+
+    /**
+     * @param {number} number
+     * @returns {number[]}
+     */
+    private getDividers (number: number): number[] {
+        const dividers: number[] = [];
+
+        number = Math.abs(number);
+
+        for (let i = 2; i < number; i++) {
+            if (number % i === 0){
+                dividers.push(i);
+            }
+        }
+
+        return dividers;
+    }
+}

+ 1 - 0
src/container/ServiceIdentifiers.ts

@@ -37,6 +37,7 @@ export enum ServiceIdentifiers {
     INodeGuard = 'INodeGuard',
     INodeTransformer = 'INodeTransformer',
     INodeTransformerNamesGroupsBuilder = 'INodeTransformerNamesGroupsBuilder',
+    INumberNumericalExpressionAnalyzer = 'INumberNumericalExpressionAnalyzer',
     IObfuscationEventEmitter = 'IObfuscationEventEmitter',
     IObfuscatedCode = 'IObfuscatedCode',
     IOptions = 'IOptions',

+ 7 - 0
src/container/modules/analyzers/AnalyzersModule.ts

@@ -4,6 +4,7 @@ import { ServiceIdentifiers } from '../../ServiceIdentifiers';
 
 import { ICalleeDataExtractor } from '../../../interfaces/analyzers/calls-graph-analyzer/ICalleeDataExtractor';
 import { ICallsGraphAnalyzer } from '../../../interfaces/analyzers/calls-graph-analyzer/ICallsGraphAnalyzer';
+import { INumberNumericalExpressionAnalyzer } from '../../../interfaces/analyzers/number-numerical-expression-analyzer/INumberNumericalExpressionAnalyzer';
 import { IPrevailingKindOfVariablesAnalyzer } from '../../../interfaces/analyzers/calls-graph-analyzer/IPrevailingKindOfVariablesAnalyzer';
 import { IScopeAnalyzer } from '../../../interfaces/analyzers/scope-analyzer/IScopeAnalyzer';
 import { IStringArrayStorageAnalyzer } from '../../../interfaces/analyzers/string-array-storage-analyzer/IStringArrayStorageAnalyzer';
@@ -12,6 +13,7 @@ import { CalleeDataExtractor } from '../../../enums/analyzers/calls-graph-analyz
 import { CallsGraphAnalyzer } from '../../../analyzers/calls-graph-analyzer/CallsGraphAnalyzer';
 import { FunctionDeclarationCalleeDataExtractor } from '../../../analyzers/calls-graph-analyzer/callee-data-extractors/FunctionDeclarationCalleeDataExtractor';
 import { FunctionExpressionCalleeDataExtractor } from '../../../analyzers/calls-graph-analyzer/callee-data-extractors/FunctionExpressionCalleeDataExtractor';
+import { NumberNumericalExpressionAnalyzer } from '../../../analyzers/number-numerical-expression-analyzer/NumberNumericalExpressionAnalyzer';
 import { ObjectExpressionCalleeDataExtractor } from '../../../analyzers/calls-graph-analyzer/callee-data-extractors/ObjectExpressionCalleeDataExtractor';
 import { PrevailingKindOfVariablesAnalyzer } from '../../../analyzers/prevailing-kind-of-variables-analyzer/PrevailingKindOfVariablesAnalyzer';
 import { ScopeAnalyzer } from '../../../analyzers/scope-analyzer/ScopeAnalyzer';
@@ -23,6 +25,11 @@ export const analyzersModule: interfaces.ContainerModule = new ContainerModule((
         .to(CallsGraphAnalyzer)
         .inSingletonScope();
 
+    // number numerical expression analyzer
+    bind<INumberNumericalExpressionAnalyzer>(ServiceIdentifiers.INumberNumericalExpressionAnalyzer)
+        .to(NumberNumericalExpressionAnalyzer)
+        .inSingletonScope();
+
     // prevailing kind of variables analyzer
     bind<IPrevailingKindOfVariablesAnalyzer>(ServiceIdentifiers.IPrevailingKindOfVariablesAnalyzer)
         .to(PrevailingKindOfVariablesAnalyzer)

+ 9 - 0
src/interfaces/analyzers/number-numerical-expression-analyzer/INumberNumericalExpressionAnalyzer.ts

@@ -0,0 +1,9 @@
+import { TNumberNumericalExpressionData } from '../../../types/analyzers/number-numerical-expression-analyzer/TNumberNumericalExpressionData';
+
+export interface INumberNumericalExpressionAnalyzer {
+    /**
+     * @param {number} number
+     * @returns {TNumberNumericalExpressionData}
+     */
+    analyze (number: number): TNumberNumericalExpressionData;
+}

+ 1 - 0
src/types/analyzers/number-numerical-expression-analyzer/TNumberNumericalExpressionData.ts

@@ -0,0 +1 @@
+export type TNumberNumericalExpressionData = (number | number[])[];

+ 11 - 3
test/dev/dev.ts

@@ -8,9 +8,17 @@ import { NO_ADDITIONAL_NODES_PRESET } from '../../src/options/presets/NoCustomNo
 
     let obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
         `
-            function foo (arg1, arg2, arg3) {
-                console.log(arg1, arg2, arg3);
-            }
+            const example1 = 0;
+            const example2 = 1;
+            const example3 = 100;
+            const example4 = 125793;
+            const example5 = -15232103;
+            
+            console.log(example1);
+            console.log(example2);
+            console.log(example3);
+            console.log(example4);
+            console.log(example5);
         `,
         {
             ...NO_ADDITIONAL_NODES_PRESET,

+ 1 - 0
test/index.spec.ts

@@ -6,6 +6,7 @@ require('source-map-support').install();
  * Unit tests
  */
 import './unit-tests/analyzers/calls-graph-analyzer/CallsGraphAnalyzer.spec';
+import './unit-tests/analyzers/number-numerical-expression-analyzer/NumberNumericalExpressionAnalyzer.spec';
 import './unit-tests/analyzers/prevailing-kind-of-variables-analyzer/PrevailingKindOfVariablesAnalyzer.spec';
 import './unit-tests/analyzers/scope-analyzer/ScopeAnalyzer.spec';
 import './unit-tests/analyzers/string-array-storage-analyzer/StringArrayStorageAnalyzer.spec';

+ 97 - 0
test/unit-tests/analyzers/number-numerical-expression-analyzer/NumberNumericalExpressionAnalyzer.spec.ts

@@ -0,0 +1,97 @@
+import 'reflect-metadata';
+
+import { assert } from 'chai';
+
+import { ServiceIdentifiers } from '../../../../src/container/ServiceIdentifiers';
+
+import { TNumberNumericalExpressionData } from '../../../../src/types/analyzers/number-numerical-expression-analyzer/TNumberNumericalExpressionData';
+
+import { IInversifyContainerFacade } from '../../../../src/interfaces/container/IInversifyContainerFacade';
+import { INumberNumericalExpressionAnalyzer } from '../../../../src/interfaces/analyzers/number-numerical-expression-analyzer/INumberNumericalExpressionAnalyzer';
+
+import { InversifyContainerFacade } from '../../../../src/container/InversifyContainerFacade';
+
+/**
+ * @param {TNumberNumericalExpressionData} data
+ * @returns {string}
+ */
+const numberNumericalExpressionDataToString = (data: TNumberNumericalExpressionData) =>
+    data
+        .map((part: number | number[]) => Array.isArray(part) ? part.join('*') : part)
+        .join('+')
+        .replace(/\+-/g, '-');
+
+describe('NumberNumericalExpressionAnalyzer', () => {
+    let numberNumericalExpressionAnalyzer: INumberNumericalExpressionAnalyzer;
+
+    before(() => {
+        const inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade();
+
+        inversifyContainerFacade.load('', '', {});
+        numberNumericalExpressionAnalyzer = inversifyContainerFacade
+            .get<INumberNumericalExpressionAnalyzer>(ServiceIdentifiers.INumberNumericalExpressionAnalyzer);
+    });
+
+    describe('analyze', () => {
+        let evaluatedResult: number;
+
+        describe('Variant #1: positive number', () => {
+            const number: number = 1234;
+
+            before(() => {
+                const numberNumericalExpressionData: TNumberNumericalExpressionData =
+                    numberNumericalExpressionAnalyzer.analyze(number);
+
+                evaluatedResult = eval(numberNumericalExpressionDataToString(numberNumericalExpressionData));
+            });
+
+            it('should return correct number numerical expression data', () => {
+                assert.equal(number, evaluatedResult);
+            });
+        });
+
+        describe('Variant #2: negative number', () => {
+            const number: number = -1234;
+
+            before(() => {
+                const numberNumericalExpressionData: TNumberNumericalExpressionData =
+                    numberNumericalExpressionAnalyzer.analyze(number);
+
+                evaluatedResult = eval(numberNumericalExpressionDataToString(numberNumericalExpressionData));
+            });
+
+            it('should return correct number numerical expression data', () => {
+                assert.equal(number, evaluatedResult);
+            });
+        });
+
+        describe('Variant #3: zero number', () => {
+            const number: number = 0;
+
+            before(() => {
+                const numberNumericalExpressionData: TNumberNumericalExpressionData =
+                    numberNumericalExpressionAnalyzer.analyze(number);
+
+                evaluatedResult = eval(numberNumericalExpressionDataToString(numberNumericalExpressionData));
+            });
+
+            it('should return correct number numerical expression data', () => {
+                assert.equal(number, evaluatedResult);
+            });
+        });
+
+        describe('Variant #4: NaN', () => {
+            const number: number = NaN;
+
+            let testFunc: () => void;
+
+            before(() => {
+                testFunc = () => numberNumericalExpressionAnalyzer.analyze(number);
+            });
+
+            it('should throw error', () => {
+                assert.throw(testFunc, 'Given value is NaN');
+            });
+        });
+    });
+});

+ 12 - 12
yarn.lock

@@ -369,10 +369,10 @@
   resolved "https://registry.yarnpkg.com/@types/node/-/node-13.9.3.tgz#6356df2647de9eac569f9a52eda3480fa9e70b4d"
   integrity sha512-01s+ac4qerwd6RHD+mVbOEsraDHSgUaefQlEdBbUolnQFjKwCr7luvAlEwW1RFojh67u0z4OUTjPn9LEl4zIkA==
 
-"@types/[email protected]0":
-  version "14.0.20"
-  resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.20.tgz#0da05cddbc761e1fa98af88a17244c8c1ff37231"
-  integrity sha512-MRn/NP3dee8yL5QhbSA6riuwkS+UOcsPUMOIOG3KMUQpuor/2TopdRBu8QaaB4fGU+gz/bzyDWt0FtUbeJ8H1A==
+"@types/[email protected]2":
+  version "14.0.22"
+  resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.22.tgz#23ea4d88189cec7d58f9e6b66f786b215eb61bdc"
+  integrity sha512-emeGcJvdiZ4Z3ohbmw93E/64jRzUHAItSHt8nF7M4TGgQTiWqFVGB8KNpLGFmUHmHLvjvBgFwVlqNcq+VuGv9g==
 
 "@types/normalize-package-data@^2.4.0":
   version "2.4.0"
@@ -1923,10 +1923,10 @@ [email protected]:
     resolve "^1.17.0"
     tsconfig-paths "^3.9.0"
 
[email protected].2:
-  version "29.1.2"
-  resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-29.1.2.tgz#542beba99946cb8d184e5261ebc632b24673f825"
-  integrity sha512-s1uJcPcjZQ4Z5i98T3zWkp/gzJ9AtHGXXg0zxd0wCnFzX8RQU6awdUokUlBFMoWZJZxdCAXDtEIQBRfr/Lrsjw==
[email protected].3:
+  version "29.1.3"
+  resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-29.1.3.tgz#288c3faf142fbf78e6abff6a838db23af8d6749f"
+  integrity sha512-HEB8jPsWBGu++LffL4K8VZ7VXz0HELI1I3Qkv/+5oSekgrAo6I0AVgl5abecLbTQQZo0OaEcmTptiIspwDOu1w==
   dependencies:
     comment-parser "^0.7.5"
     debug "^4.1.1"
@@ -5432,10 +5432,10 @@ [email protected]:
     v8-compile-cache "^2.1.1"
     yargs "^13.3.2"
 
-webpack-node-externals@2.3.0:
-  version "2.3.0"
-  resolved "https://registry.yarnpkg.com/webpack-node-externals/-/webpack-node-externals-2.3.0.tgz#c884c07103de080284e17c195fe87c68e2b9c668"
-  integrity sha512-d1scCn/L5hv73GMOlqSTO6ykLWOiUrZfn54xQYf7u0yGLlUSf5trq6HV/Gw8JIpH2NEyXS7bJec1gk9YR/Qdqw==
+webpack-node-externals@2.5.0:
+  version "2.5.0"
+  resolved "https://registry.yarnpkg.com/webpack-node-externals/-/webpack-node-externals-2.5.0.tgz#8d50f3289c71bc2b921a8da228e0b652acc503f1"
+  integrity sha512-g7/Z7Q/gsP8GkJkKZuJggn6RSb5PvxW1YD5vvmRZIxaSxAzkqjfL5n9CslVmNYlSqBVCyiqFgOqVS2IOObCSRg==
 
 webpack-sources@^1.4.0, webpack-sources@^1.4.1:
   version "1.4.3"

Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff