SB-6.1-PRE

This commit is contained in:
ItzEmerald committed 2021-02-02 13:50:53 +00:00
1 parent 690169a409
commit 358a25f522
3760 files changed
+300059 -36

No files matched your search

+2
View File
@@ -0,0 +1,2 @@
/test
/webpack
+352
View File
@@ -0,0 +1,352 @@
module.exports = {
"env": {
"browser": true,
"es6": true,
"node": true
},
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": "src/tsconfig.node.json",
"sourceType": "module"
},
"plugins": [
"@typescript-eslint",
"import",
"jsdoc",
"prefer-arrow",
"unicorn"
],
"rules": {
"@typescript-eslint/adjacent-overload-signatures": "error",
"@typescript-eslint/array-type": [
"error",
{
"default": "array"
}
],
"@typescript-eslint/await-thenable": "error",
"@typescript-eslint/ban-ts-comment": "error",
"@typescript-eslint/ban-types": "off",
"@typescript-eslint/brace-style": [
"error",
"1tbs",
{
"allowSingleLine": true
}
],
"@typescript-eslint/camelcase": "off",
"@typescript-eslint/comma-spacing": "error",
"@typescript-eslint/consistent-type-assertions": [
"error",
{
"assertionStyle": "angle-bracket"
}
],
"@typescript-eslint/consistent-type-definitions": "error",
"@typescript-eslint/default-param-last": "error",
"@typescript-eslint/explicit-function-return-type": "error",
"@typescript-eslint/explicit-member-accessibility": [
"error",
{
"accessibility": "explicit"
}
],
"@typescript-eslint/explicit-module-boundary-types": "error",
"@typescript-eslint/func-call-spacing": "error",
"@typescript-eslint/indent": [
"off",
4
],
"@typescript-eslint/member-delimiter-style": [
"error",
{
"multiline": {
"delimiter": "semi",
"requireLast": true
},
"singleline": {
"delimiter": "semi",
"requireLast": false
}
}
],
"@typescript-eslint/member-ordering": "error",
"@typescript-eslint/naming-convention": [
"error",
{
"selector": "default",
"format": ["camelCase", "PascalCase"]
},
{
"selector": "variable",
"format": ["camelCase", "PascalCase", "UPPER_CASE"]
},
{
"selector": "function",
"format": ["camelCase", "PascalCase"]
},
{
"selector": "class",
"format": ["PascalCase"]
},
{
"selector": "interface",
"format": ["PascalCase"],
"prefix": ["I"]
},
{
"selector": "typeAlias",
"format": ["PascalCase"],
"prefix": ["T"]
},
{
"selector": "typeParameter",
"format": ["PascalCase"]
},
{
"selector": "enum",
"format": ["PascalCase"]
},
{
"selector": "enumMember",
"format": null
},
{
"selector": "property",
"format": ["camelCase", "PascalCase", "snake_case"]
}
],
"@typescript-eslint/no-empty-function": "off",
"@typescript-eslint/no-empty-interface": "error",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-extra-parens": "off",
"@typescript-eslint/no-floating-promises": "error",
"@typescript-eslint/no-for-in-array": "error",
"@typescript-eslint/no-inferrable-types": "off",
"@typescript-eslint/no-magic-numbers": "off",
"@typescript-eslint/no-misused-new": "error",
"@typescript-eslint/no-namespace": "error",
"@typescript-eslint/no-non-null-asserted-optional-chain": "error",
"@typescript-eslint/no-non-null-assertion": "error",
"@typescript-eslint/no-param-reassign": "off",
"@typescript-eslint/no-parameter-properties": "error",
"@typescript-eslint/no-require-imports": "off",
"@typescript-eslint/no-shadow": "error",
"@typescript-eslint/no-this-alias": "error",
"@typescript-eslint/no-unnecessary-qualifier": "error",
"@typescript-eslint/no-unnecessary-type-arguments": "error",
"@typescript-eslint/no-unnecessary-type-assertion": "error",
"@typescript-eslint/no-unused-expressions": "error",
"@typescript-eslint/no-use-before-define": "off",
"@typescript-eslint/no-var-requires": "error",
"@typescript-eslint/prefer-for-of": "error",
"@typescript-eslint/prefer-function-type": "error",
"@typescript-eslint/prefer-namespace-keyword": "error",
"@typescript-eslint/prefer-nullish-coalescing": "error",
"@typescript-eslint/prefer-optional-chain": "error",
"@typescript-eslint/prefer-readonly": "error",
"@typescript-eslint/promise-function-async": "error",
"@typescript-eslint/quotes": [
"error",
"single"
],
"@typescript-eslint/require-array-sort-compare": "error",
"@typescript-eslint/restrict-plus-operands": "error",
"@typescript-eslint/semi": [
"error",
"always"
],
"@typescript-eslint/space-before-function-paren": "error",
"@typescript-eslint/strict-boolean-expressions": "off",
"@typescript-eslint/triple-slash-reference": "error",
"@typescript-eslint/type-annotation-spacing": "error",
"@typescript-eslint/typedef": "error",
"@typescript-eslint/unified-signatures": "error",
"arrow-body-style": "off",
"arrow-parens": [
"off",
"as-needed"
],
"brace-style": "off",
"capitalized-comments": "off",
"comma-dangle": "off",
"comma-spacing": "off",
"complexity": [
"error",
{
"max": 10
}
],
"constructor-super": "error",
"curly": "error",
"default-case": "off",
"dot-notation": "error",
"eol-last": "error",
"eqeqeq": [
"error",
"smart"
],
"func-call-spacing": "off",
"guard-for-in": "error",
"id-blacklist": "off",
"id-match": "off",
"import/export": "error",
"import/first": "error",
"import/newline-after-import": "error",
"import/no-absolute-path": "error",
"import/no-cycle": "error",
"import/no-default-export": "error",
"import/no-deprecated": "error",
"import/no-extraneous-dependencies": "error",
"import/no-internal-modules": "error",
"import/no-mutable-exports": "error",
"import/no-unassigned-import": "off",
"import/no-useless-path-segments": "error",
"import/order": "off",
"indent": "off",
"jsdoc/no-types": "off",
"linebreak-style": "off",
"max-classes-per-file": [
"error",
1
],
"max-len": "off",
"max-lines": [
"error",
500
],
"new-parens": "error",
"newline-per-chained-call": "off",
"no-bitwise": "off",
"no-caller": "error",
"no-cond-assign": "error",
"no-console": [
"error",
{
"allow": [
"log",
"warn",
"dir",
"timeLog",
"assert",
"clear",
"count",
"countReset",
"group",
"groupEnd",
"table",
"dirxml",
"error",
"groupCollapsed",
"Console",
"profile",
"profileEnd",
"timeStamp",
"context"
]
}
],
"no-constant-condition": "error",
"no-control-regex": "off",
"no-debugger": "error",
"no-duplicate-case": "error",
"no-duplicate-imports": "error",
"no-empty": "off",
"no-eval": "off",
"no-extra-bind": "error",
"no-extra-parens": "off",
"no-extra-semi": "error",
"no-fallthrough": "error",
"no-invalid-regexp": "error",
"no-invalid-this": "off",
"no-irregular-whitespace": "error",
"no-magic-numbers": "off",
"no-multi-str": "error",
"no-multiple-empty-lines": "error",
"no-new-wrappers": "error",
"no-null/no-null": "off",
"no-octal": "error",
"no-octal-escape": "error",
"no-redeclare": "error",
"no-regex-spaces": "error",
"no-restricted-syntax": [
"error",
"ForInStatement"
],
"no-return-await": "error",
"no-sequences": "error",
"no-shadow": "off",
"no-sparse-arrays": "error",
"no-template-curly-in-string": "error",
"no-throw-literal": "error",
"no-trailing-spaces": [
"error",
{
"skipBlankLines": true
}
],
"no-undef-init": "error",
"no-underscore-dangle": "off",
"no-unsafe-finally": "error",
"no-unused-expressions": "off",
"no-unused-labels": "error",
"no-var": "error",
"no-void": "error",
"object-shorthand": "off",
"one-var": [
"error",
"never"
],
"padding-line-between-statements": [
"error",
{
"blankLine": "always",
"prev": "*",
"next": "return"
}
],
"prefer-arrow/prefer-arrow-functions": "off",
"prefer-const": "error",
"prefer-object-spread": "error",
"prefer-template": "error",
"quote-props": [
"error",
"as-needed"
],
"quotes": "off",
"radix": "error",
"space-before-function-paren": "off",
"spaced-comment": "error",
"space-in-parens": [
"error",
"never"
],
"unicorn/catch-error-name": [
"error",
{
"name": "error"
}
],
"unicorn/no-nested-ternary": "error",
"unicorn/no-unreadable-array-destructuring": "error",
"unicorn/numeric-separators-style": [
"error",
{
number: {
minimumDigits: 7,
groupLength: 3
}
}
],
"unicorn/prefer-array-find": "error",
"unicorn/prefer-includes": "error",
"unicorn/prefer-optional-catch-binding": "error",
"unicorn/prefer-starts-ends-with": "error",
"unicorn/prefer-set-has": "error",
"unicorn/prefer-string-slice": "error",
"unicorn/prefer-trim-start-end": "error",
"use-isnan": "error",
"valid-typeof": "error",
"yoda": "error"
}
};
+3
View File
@@ -0,0 +1,3 @@
{
"reject": []
}
+3
View File
@@ -0,0 +1,3 @@
{
"extends": "@istanbuljs/nyc-config-typescript"
}
+29
View File
@@ -0,0 +1,29 @@
language: node_js
env:
- YARN_GPG=no
jobs:
include:
- os: linux
node_js: "10"
- os: linux
node_js: "12"
- os: linux
node_js: "13"
- os: linux
node_js: "14"
- os: linux
node_js: "stable"
- os: windows
node_js: "14"
cache:
yarn: true
directories:
- node_modules
script: "yarn run travis"
after_success:
- yarn run test:mocha-coverage:report
+747
View File
@@ -0,0 +1,747 @@
Change Log
v2.9.4
---
* Fixed missing prefix of root identifiers added by `stringArrayWrappersCount` option when `identifiersPrefix` option is set
v2.9.3
---
* **CLI**: Fixed wrong name of obfuscated files when input directory path is the `.` symbol. https://github.com/javascript-obfuscator/javascript-obfuscator/issues/816
v2.9.2
---
* Ignore object expressions as body of arrow function expression when `transformObjectKeys` option is enabled. Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/813
v2.9.1
---
* Fixed wrong `stringArrayWrappersParametersMaxCount` CLI option name
v2.9.0
---
* New option: `stringArrayIndexesType` accepts an array of types of string array call indexes
* Changed default type of all string array call indexes from `hexadecimal-numeric-string` to `hexadecimal-number`
* New option: `stringArrayIndexShift` enables additional index shift for all string array calls
* New option: ``stringArrayWrappersParametersMaxCount`` allows to control the maximum number of string array wrappers parameters
* `stringArrayWrappersType: 'function'` option value moved from `high-obfuscation` to `medium-obfuscation` options preset
v2.8.1
---
* Fixed incorrect rename of the identifiers of the added helpers in some rare cases. Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/804
v2.8.0
---
* New option `ignoreRequireImports` prevents obfuscation of `require` imports. Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/801
v2.7.1
---
* Updated `@javascript-obfuscator/escodegen` to `2.1.1`
v2.7.0
---
* Switched form `escodegen` to `@javascript-obfuscator/escodegen`
* Full support of `nullish-coalescing`. Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/604
* Support for `exported` field of `ExportAllDeclaration` node. Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/710
v2.6.4
---
* Added ignoring of all object members previous to `SpreadElement` when `transformObjectKeys` option is enabled. Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/797
v2.6.3
---
* Added `ExportSpecifierTransformer`. Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/791
v2.6.2
---
* Fixed installation in `PowerShell`. Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/783
* Tested under `Node.js@15`
v2.6.1
---
* Fixed missing rename of object pattern properties in some cases. Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/781
v2.6.0
---
* Migration to `webpack@5`
* Optimized performance of `ExpressionStatementsMergeTransformer` when `simplify` option is enabled. Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/777
* Fixed broken `identifierNamesGenerator: 'mangled-shuffled'` after `2.2.0`. Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/778
v2.5.0
---
* Improved hierarchy of generated directories when `--output` is a directory path
* Fixed wrong path generation for obfuscated files for `win32` environment. Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/576
* Fixed wrong path generation under for source map for `win32` environment. Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/760
* `javascript-obfuscator` now can be built under `win32` environment
v2.4.3
---
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/769
v2.4.2
---
* Fixed `URI-malformed` when `splitStrings` and `stringArrayEncoding` options are enabled. https://github.com/javascript-obfuscator/javascript-obfuscator/issues/530
v2.4.1
---
* Small release with some README.md improvements that allow to use it on [obfuscator.io](https://obfuscator.io)
v2.4.0
---
* **New option:** `forceTransformStrings` allows force transform strings even if by `stringArrayThreshold` (or possible other thresholds in the future) they shouldn't be transformed. Implemented https://github.com/javascript-obfuscator/javascript-obfuscator/issues/657
v2.3.1
---
* Fixed a rare bug with `identifierNamesGenerator: 'mangled'` option that causes wrong identifier names generation
v2.3.0
---
* **New option:** `stringArrayWrappersType` allows to select a type of the wrappers that are appending by the `stringArrayWrappersCount` option
* Add force convert of unicode control characters to the unicode escape sequence. Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/747
v2.2.1
---
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/745
v2.2.0
---
* **New option (enabled by default):** `stringArrayWrappersCount` sets the count of wrappers for the `string array` inside each root or function scope
* **New option (enabled by default):** `stringArrayWrappersChainedCalls` enables the chained calls between `string array` wrappers
v2.1.0
---
* **New API:** `getOptionsByPreset` allows to get options for the passed options preset name
v2.0.0
---
* **Breaking change:** `stringArrayEncoding` option now accepts an array of encodings. Each string will be randomly encoded with passed encoding
v1.12.1
---
* Fixed regression bug with combination of `splitStrings` and `renameProperties` option. https://github.com/javascript-obfuscator/javascript-obfuscator/issues/729
v1.12.0
---
* **New option:** `optionsPreset` allows to set options preset
v1.11.0
---
* Improved rename of `deadCodeInjection` dead code identifiers. Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/708
* **Reverted** `TaggedTemplateLiteral` obfuscation. https://github.com/javascript-obfuscator/javascript-obfuscator/issues/716
v1.10.2
---
* Fixed obfuscation of literals of `ExportNamedDeclaration` and `ExportAllDeclaration` nodes
v1.10.1
---
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/707
v1.10.0
---
* **Feature:** Optional chaining support!
* Added `TaggedTemplateLiteral` obfuscation. https://github.com/javascript-obfuscator/javascript-obfuscator/issues/696
* Improved `disableConsoleOutput` template. https://github.com/javascript-obfuscator/javascript-obfuscator/issues/691
v1.9.0
---
* Improved obfuscation of destructured variables. https://github.com/javascript-obfuscator/javascript-obfuscator/issues/688
v1.8.1
---
* Fixed runtime error `Uncaught SyntaxError: yield is a reserved identifier` when `deadCodeInjection` is enabled
v1.8.0
---
* `domainLock` option patterns with leading dot character (`.example.com`) now cover root domains (`example.com`) in addition to all sub-domains (`sub.example.com`). https://github.com/javascript-obfuscator/javascript-obfuscator/issues/640
v1.7.0
---
* `simplify` option now affects all block statements. Improved variable declarations merging.
v1.6.0
---
* **New option:** `numbersToExpressions` enables numbers conversion to expressions
v1.5.2
---
* Prevented mutation of the name sequences of `mangled` identifier name generators
v1.5.1
---
* Fixed runtime error when `IfStatement` contains only single `let` or `const` variable declaration when `simlify` option enabled. https://github.com/javascript-obfuscator/javascript-obfuscator/issues/661
* Fixed wrong `source-map: 'inline'` encoding after `1.3.0`
v1.5.0
---
* New `mangled-shuffled` identifier names generator based on `mangled` identifier names generator
v1.4.0
---
* **New option:** `simplify` enables additional code obfuscation through simplification
v1.3.0
---
* Improvements of `stringArrayEncoding`: `base64` and `rc4`
* **CLI**: added config file extension validation (it still supports `.js` and `.json` extensions)
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/499
v1.2.2
---
* Fixed performance regression of `Initializing` stage after `1.2.0`
v1.2.1
---
* Support of old browsers when `selfDefending` is enabled. https://github.com/javascript-obfuscator/javascript-obfuscator/issues/615
v1.2.0
---
* Conditional comments will be removed from the code after obfuscation. https://github.com/javascript-obfuscator/javascript-obfuscator/issues/641
v1.1.1
---
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/638
v1.1.0
---
* **New option:** `renameProperties` enables renaming of property names
v1.0.1
---
* Fixed .d.ts typings. https://github.com/javascript-obfuscator/javascript-obfuscator/issues/623
v1.0.0
---
* Looks like obfuscator is ready for the first stable release
v0.28.5
---
* Fixed error during code generation for `ObjectPattern` with single `RestElement`. https://github.com/javascript-obfuscator/javascript-obfuscator/issues/607
v0.28.4
---
* Added correct `self-defending` code for `target: 'browser-no-eval'`. https://github.com/javascript-obfuscator/javascript-obfuscator/issues/610
v0.28.3
---
* Removed memory leak with `identifierNamesGenerator: 'mangled'`
v0.28.2
---
* Fixed change of kinds of variables for dead code with `deadCodeInjection` option
v0.28.1
---
* Removed `acorn-import-meta` package
v0.28.0
---
* Added BigInt support. https://github.com/javascript-obfuscator/javascript-obfuscator/issues/588
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/554
v0.27.4
---
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/590
v0.27.3
---
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/593
v0.27.2
---
* Fixed identifiers prefix generation for `obfuscateMultiple` method
v0.27.1
---
* Dependencies update, fixed https://www.npmjs.com/advisories/1488
v0.27.0
---
* **Feature:** new method `obfuscateMultiple` to obfuscation of multiple source codes
v0.26.0
---
* **Internal:** new code transformers mechanism
* Supported obfuscation of files with hashbang operator, https://github.com/javascript-obfuscator/javascript-obfuscator/issues/471
v0.25.5
---
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/575
v0.25.4
---
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/569
v0.25.3
---
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/568
v0.25.2
---
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/563
v0.25.1
---
* Additional fixes of https://github.com/javascript-obfuscator/javascript-obfuscator/issues/550
v0.25.0
---
* Improved `mangled` identifier names generator logic
* Improved `selfDefending` helper logic
* Fixed a bunch of conflicts between generated identifier names. Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/550. Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/549
* Prevented transformation of object keys in sequence expression that has `super` call
* Support of output directory paths with a dot symbol
* Changed `--output` logic. Now `--output` value can describe if it's a file or a directory path. Check README.md for more info
v0.24.6
---
* Fixed support of exponentiation operator. Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/534
* Added file path to the error message during directory obfuscation. Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/513
v0.24.5
---
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/542
v0.24.4
---
* Fixed rc4 encoded value collision: https://github.com/javascript-obfuscator/javascript-obfuscator/issues/538
v0.24.3
---
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/535
v0.24.2
---
* Reverted validation errors under `node` target for `sourceMap*` options
v0.24.1
---
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/531
v0.24.0
---
* **Internal refactoring:** completely new mechanism to rename variable names
* Dynamic import and `import.meta` support. Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/505
* Now usage of some browser-related options with `target: 'node'` will cause a validation error
* Increased `identifierNamesGenerator: 'mangled` speed
* **CLI:** a file path will be displayed on obfuscation error. Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/513
* Fixed many `transformObjectKeys` runtime errors
* Fixed `Maximum call stack size exceeded` error on large strings when `splitString` option is enabled
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/516
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/512
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/496
* **Internal:** switched from `awesome-typescript-loader` on `ts-loader`
v0.23.2
---
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/475
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/326
v0.23.1
---
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/498
v0.23.0
---
* **New option:** `shuffleStringArray` randomly shuffles string array items
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/494
* **Internal change:** switched AST parser from `espree` on `acorn`
* **Internal refactoring:** refactoring of string array storage and related things
v0.22.1
---
* Fixed `TypeError: Assignment to constant variable` when auto-detection of kind of variables is inserted `const` variables for `controlFlowStorage` nodes
v0.22.0
---
* **Breaking:** auto-detection of kind of variables of inserted nodes, based on most prevailing kind of variables of source code
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/486
v0.21.1
---
* Fixed conditional comments in some rare cases
v0.21.0
---
* Improved `transformObjectKeys` transformation to cover more cases
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/406
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/387
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/333
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/328
v0.20.4
---
* Fixed typings. Now string values correctly assignable to enum-like options
v0.20.3
---
* Fixed `for-await-of` statement: https://github.com/javascript-obfuscator/javascript-obfuscator/issues/419
v0.20.2
---
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/pull/442
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/468
* Added funding button
* Internal dependencies update, Happy New Year 2020!
v0.20.1
---
* Fixed identifier names generations for `mangled` and `dictionary` identifier names generators
* Fixed combination of `identifierNamesGenerator: dictionary` and `debugProtection` options
* `seed` option now accepts `string` and `number` values
v0.20.0
---
* **Breaking:** dropped support of Node 8 because of end of maintenance support
* **New option value:** `identifierNamesGenerator` now allows to set new `dictionary` identifier names generator
* **New option:** `identifiersDictionary` sets identifiers dictionary for `identifierNamesGenerator: dictionary` option
Thanks to our contributors!
* [adiantek](https://github.com/adiantek)
v0.19.4
---
* Fixed `reservedNames` option
Thanks to our contributors!
* [kida7](https://github.com/kida7)
v0.19.3
---
* The `splitStrings` option now correctly works with `transformObjectKeys` option
* Internal `TransformersRunner` rework to support topological sort of node transformers
v0.19.2
---
* The `splitStrings` option now correctly splits strings inside objects
v0.19.1
---
* The `splitStrings` option now affects template literal strings
v0.19.0
---
* **New option:** `splitStrings` splits literal strings into chunks with length of `splitStringsChunkLength` option value
* **New option:** `splitStringsChunkLength` sets chunk length of `splitStrings` option
v0.18.8
---
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/452
v0.18.7
---
* Fixed https://github.com/javascript-obfuscator/gulp-javascript-obfuscator/issues/22
v0.18.6
---
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/355
Thanks to our contributors!
* [Zamotkin](https://github.com/zamotkin)
v0.18.5
---
* Breaking: require Node.js 8 after dependencies update
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/321
Thanks to our contributors!
* [Zamotkin](https://github.com/zamotkin)
v0.18.4
---
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/437
Thanks to our contributors!
* [Zamotkin](https://github.com/zamotkin)
v0.18.3
---
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/424
Thanks to our contributors!
* [Zamotkin](https://github.com/zamotkin)
v0.18.2
---
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/320
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/319
v0.18.1
---
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/317
v0.18.0
---
* **New option:** `reservedStrings` disables transformation of string literals, which being matched by passed RegExp patterns
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/313
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/309
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/307
v0.17.3
---
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/303
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/302
v0.17.2
---
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/297
v0.17.1
---
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/293
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/289
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/288
v0.17.0
---
* **Browser version**: Added browser version dist
* **New Node API option:** `inputFileName` allows to set name of the input file with source code. This name will used internally, for example, for source map generation.
* [#274](https://github.com/javascript-obfuscator/javascript-obfuscator/pull/274)`domainLock` now will work in SVG.
<br/>
Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/273
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/271
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/264
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/260
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/252
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/247
v0.16.0
---
* Correct obfuscation of object rest and spread properties
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/243
v0.15.0
---
* **Internal change:** switched AST parser from `esprima` on `espree`
* **Breaking change:** dropped `node@4` and `node@5` support.
* **Breaking change:** renamed `extension` value of `target` option on `browser-no-eval`.
* **Breaking change:** disabled generation of identifiers, which being matched by `reservedName` option. Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/216
* **New CLI option:** `exclude` allows to exclude specific files or directories from obfuscation.
* Correct obfuscation of `import` and `export` declarations.
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/231
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/217
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/210
* Internal: refactoring of many things.
v0.14.3
---
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/195
* Added code preview to `esprima` error messages.
v0.14.2
---
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/181
v0.14.1
---
* Temporary fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/181
v0.14.0
---
* **New option:** `identifiersPrefix` sets prefix for all global identifiers.
* **New option:** `transformObjectKeys` enables object keys transformation and obfuscation.
* **New feature:** `eval` expressions obfuscation.
* **Breaking change:** Now CLI obfuscating directory recursively. Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/157
* Fixed runtime errors when `deadCodeInjection` is enabled and `identifierNamesGenerator` is set to `mangled`.
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/171
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/166
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/156
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/159
v0.13.0
---
* **Breaking change:** `mangle` option was removed.
* **New option:** `identifierNamesGenerator` allows to set identifier names generator (`hexadecimal` or `mangled`).
* **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` and `@preserve` 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
---
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/139
v0.12.4
---
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/136
v0.12.3
---
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/129
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/125 (dead code injection and await expression)
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/123
v0.12.2
---
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/121
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/119
v0.12.1
---
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/117
v0.12.0
---
* **New option:** `target` allows to set target environment for obfuscated code.
* Added ability to disable and enable obfuscation for specific parts of the code by adding conditional comments.
* Added obfuscation of `es2015` class names.
* CLI: added directory obfuscation.
v0.11.2
---
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/98
v0.11.1
---
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/94
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.2
---
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/78
v0.10.1
---
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/76
v0.10.0
---
* **New option:** `deadCodeInjection`. With this option random blocks of dead code will add to the obfuscated code.
* **New option:** `deadCodeInjectionThreshold` allows to set percentage of nodes that will affected by `deadCodeInjection`.
* **New option:** `mangle` enables mangling of variable names.
* **New CLI option:** `--config` allows to set config file with obfuscator options.
* **Breaking change:** `disableConsoleOutput` option now disabled by default.
* **Breaking change:** `escapeUnicodeSequence` option now disabled by default.
* `controlFlowFlattening` now affects string literal nodes.
* Increased runtime performance with `rc4` `stringArrayEncoding`.
* Added support for async functions
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/71
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/65
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/60
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/59
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/54
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/57
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/58
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/58
v0.9.3
---
* Switched from `escodegen` to `escodegen-wallaby`, fixed https://github.com/javascript-obfuscator/javascript-obfuscator/pull/50
v0.9.2
---
* Removed coverage dir from npm package
v0.9.1
---
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/37
v0.9.0
---
* **Breaking change:** dropped `node@0.10` and `node@0.12` support.
* **New option:** `controlFlowFlattening` allows to enable/disable **Control Flow flattening**. Control flow flattening is a structure transformation of the source code that hinders program comprehension.
* **New option:** `controlFlowFlatteningThreshold` allows to set percentage of nodes that will affected by `controlFlowFlattening`.
* Significantly increased obfuscation performance.
* Huge internal refactoring.
* Better `es2015` support: correct obfuscation of `TemplateLiteral`, `ArrayPattern`, `AssignmentPattern` nodes.
* Switched from `npm` to `yarn` internally.
* Various bug fixes.
v0.9.0-beta.5
---
* Increased performance
* Fixed very rare `Cannot read property 'type' of undefined` error, when `RandomGeneratorUtils.getMathRandom()` returned incorrect value `1`.
v0.9.0-beta.4
---
* Increased performance
v0.9.0-beta.3
---
* **Breaking change:** dropped `node@0.10` and `node@0.12` support.
* Switched from `npm` to `yarn` internally.
v0.9.0-beta.2
---
* Transformers refactoring
v0.9.0-beta.1
---
* **New option:** `controlFlowFlattening` allows to enable/disable **Control Flow flattening**. Control flow flattening is a structure transformation of the source code that hinders program comprehension.
* **New option:** `controlFlowFlatteningThreshold` allows to set percentage of nodes that will affected by `controlFlowFlattening`.
* Better `es2015` support: correct obfuscation of `TemplateLiteral`, `ArrayPattern`, `AssignmentPattern` nodes.
* Obfuscation performance boost.
* Huge internal refactoring.
* Various bug fixes.
v0.8.6
---
* Additional fixes for https://github.com/javascript-obfuscator/javascript-obfuscator/issues/29
v0.8.5
---
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/29
v0.8.4
---
* Fixed https://github.com/javascript-obfuscator/webpack-obfuscator/issues/13
v0.8.3
---
* `selfDefending` option now disabled by default.
v0.8.2
---
* 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.
v0.8.0
---
* **Breaking options change:** `unicodeArray` option has been renamed to `stringArray`.
* **Breaking options change:** `unicodeArrayThreshold` option has been renamed to `stringArrayThreshold`.
* **Breaking options change:** `encodeUnicodeArray` option has been renamed to `stringArrayEncoding` and now accepts following values: `true|false|'base64'|'rc4'`.
* **Breaking change:** option `wrapUnicodeArrayCalls` was removed and now all calls to `stringArray` are always wrapped by special wrapper function.
* New option `unicodeEscapeSequence` allows to enable/disable strings conversion to unicode escape sequence.
* New option `domainLock` locks the obfuscated source code so it only runs on specific domains and/or sub-domains.
* New option `sourceMapBaseUrl` sets base url to the source map import url when `sourceMapMode: 'separate'`.
* Custom nodes like `selfDefendingNode` or `consoleOutputNode` now inserted into deepest stack trace function call.
* Fixed obfuscation of global variables and function names in some cases.
* Fixed wrong obfuscation of labels.
* Rewrite of many custom nodes.
v0.7.3
---
* CLI missing polyfill fix [#17](https://github.com/sanex3339/javascript-obfuscator/issues/17)
v0.7.2
---
* Runtime error fix [#7](https://github.com/sanex3339/webpack-obfuscator/issues/7)
* Shorthand object expression fix [#16](https://github.com/sanex3339/javascript-obfuscator/issues/16)
v0.7.1
---
* IE error fix [#14](https://github.com/sanex3339/javascript-obfuscator/issues/14)
v0.7.0-dev.3
---
* Obfuscator now returns an empty string instead of obfuscated code if source code is empty
v0.7.0-dev.2
---
* Fix of incorrect `Utils.decToHex` method
v0.7.0-dev.1
---
* **Breaking API change:** now `obfuscate(sourceCode, options)` returns `ObfuscationResult` object instead `string`. `ObfuscationResult` object contains two public methods: `getObfuscatedCode()` and `getSourceMap()`.
* CLI. Now any code can be obfuscated through CLI `javascript-obfuscator` command. See `README.md` for available options.
* New option `sourceMap` enables source map generation for obfuscated code.
* New option `sourceMapMode` specifies source map generation mode.
+46
View File
@@ -0,0 +1,46 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at sanex3339@yandex.ru. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/
+38
View File
@@ -0,0 +1,38 @@
# Contributing to JavaScript Obfuscator
## Setup
1 Clone your fork of the repository
```
$ git clone https://github.com/YOUR_USERNAME/javascript-obfuscator.git
```
2 Install npm dependencies
```
$ yarn
```
3 Run Dev process
```
$ yarn run watch
```
4 Run Build process
```
$ yarn run build
```
## Guidelines
- Please try to [combine multiple commits before pushing](http://stackoverflow.com/questions/6934752/combining-multiple-commits-before-pushing-in-git)
- Please use `TDD` when fixing bugs. This means that you should write a unit test that fails because it reproduces the issue,
then fix the issue and finally run the test to ensure that the issue has been resolved. This helps us prevent fixed bugs from
happening again in the future
- Please keep the test coverage at 95+%. Write additional unit tests if necessary
- Please keep code style consistent
- Please create an issue before sending a PR if it is going to change the public interface of JavaScript Obfuscator or includes significant architecture changes
+19
View File
@@ -0,0 +1,19 @@
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+1508
View File
File diff suppressed because it is too large. Load diff
+3
View File
@@ -0,0 +1,3 @@
#!/usr/bin/env node
require('../dist/index.cli').obfuscate(process.argv);
+3
View File
@@ -0,0 +1,3 @@
/*! For license information please see index.browser.js.LICENSE.txt */
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.JavaScriptObfuscator=t():e.JavaScriptObfuscator=t()}(self,(function(){return(()=>{var __webpack_modules__={3913:(e,t,r)=>{!function(){"use strict";var e,n,o,i,a,s,u,l,c,d,p,g,f,h,m,y,b,S,_,C,E,A,N,v,T,I;function O(e){return X.Statement.hasOwnProperty(e.type)}a=r(7085),s=r(649),e=a.Syntax,o={"??":(n={Sequence:0,Yield:1,Assignment:1,Conditional:2,ArrowFunction:2,NullishCoalescing:3,LogicalOR:3,LogicalAND:4,BitwiseOR:5,BitwiseXOR:6,BitwiseAND:7,Equality:8,Relational:9,BitwiseSHIFT:10,Additive:11,Multiplicative:12,Exponentiation:13,Await:14,Unary:14,Postfix:15,OptionalChaining:16,Call:17,New:18,TaggedTemplate:19,Member:20,Primary:21}).NullishCoalescing,"||":n.LogicalOR,"&&":n.LogicalAND,"|":n.BitwiseOR,"^":n.BitwiseXOR,"&":n.BitwiseAND,"==":n.Equality,"!=":n.Equality,"===":n.Equality,"!==":n.Equality,is:n.Equality,isnt:n.Equality,"<":n.Relational,">":n.Relational,"<=":n.Relational,">=":n.Relational,in:n.Relational,instanceof:n.Relational,"<<":n.BitwiseSHIFT,">>":n.BitwiseSHIFT,">>>":n.BitwiseSHIFT,"+":n.Additive,"-":n.Additive,"*":n.Multiplicative,"%":n.Multiplicative,"/":n.Multiplicative,"**":n.Exponentiation};var D=32,R=33;function P(e,t){var r="";for(t|=0;t>0;t>>>=1,e+=e)1&t&&(r+=e);return r}function M(e){var t=e.length;return t&&s.code.isLineTerminator(e.charCodeAt(t-1))}function F(e,t){var r;for(r in t)t.hasOwnProperty(r)&&(e[r]=t[r]);return e}function x(e,t){var r,n;function o(e){return"object"==typeof e&&e instanceof Object&&!(e instanceof RegExp)}for(r in t)t.hasOwnProperty(r)&&(o(n=t[r])?o(e[r])?x(e[r],n):e[r]=x({},n):e[r]=n);return e}function L(e,t){return 8232==(-2&e)?(t?"u":"\\u")+(8232===e?"2028":"2029"):10===e||13===e?(t?"":"\\")+(10===e?"n":"r"):String.fromCharCode(e)}function w(e,t){var r;return 8===e?"\\b":12===e?"\\f":9===e?"\\t":(r=e.toString(16).toUpperCase(),c||e>255?"\\u"+"0000".slice(r.length)+r:0!==e||s.code.isDecimalDigit(t)?11===e?"\\x0B":"\\x"+"00".slice(r.length)+r:"\\0")}function $(e){if(92===e)return"\\\\";if(10===e)return"\\n";if(13===e)return"\\r";if(8232===e)return"\\u2028";if(8233===e)return"\\u2029";throw new Error("Incorrectly classified character")}function B(e){var t,r,n,o="";for(t=0,r=e.length;t<r;++t)n=e[t],o+=Array.isArray(n)?B(n):n;return o}function G(e,t){if(!A)return Array.isArray(e)?B(e):e;if(null==t){if(e instanceof i)return e;t={}}return null==t.loc?new i(null,null,A,e,t.name||null):new i(t.loc.start.line,t.loc.start.column,!0===A?t.loc.source||null:A,e,t.name||null)}function j(){return m||" "}function U(e,t){var r,n,o,i;return 0===(r=G(e).toString()).length?[t]:0===(n=G(t).toString()).length?[e]:(o=r.charCodeAt(r.length-1),i=n.charCodeAt(0),(43===o||45===o)&&o===i||s.code.isIdentifierPartES5(o)&&s.code.isIdentifierPartES5(i)||47===o&&105===i?[e,j(),t]:s.code.isWhiteSpace(o)||s.code.isLineTerminator(o)||s.code.isWhiteSpace(i)||s.code.isLineTerminator(i)?[e,t]:[e,m,t])}function k(e){return[u,e]}function V(e){var t;t=u,e(u+=l),u=t}function H(e,t){if("Line"===e.type){if(M(e.value))return"//"+e.value;var r="//"+e.value;return v||(r+="\n"),r}return C.format.indent.adjustMultilineComment&&/[\n\r]/.test(e.value)?function(e,t){var r,n,o,i,a,l,c,d;for(r=e.split(/\r\n|[\r\n]/),l=Number.MAX_VALUE,n=1,o=r.length;n<o;++n){for(i=r[n],a=0;a<i.length&&s.code.isWhiteSpace(i.charCodeAt(a));)++a;l>a&&(l=a)}for(void 0!==t?(c=u,"*"===r[1][l]&&(t+=" "),u=t):(1&l&&--l,c=u),n=1,o=r.length;n<o;++n)d=G(k(r[n].slice(l))),r[n]=A?d.join(""):d;return u=c,r.join("\n")}("/*"+e.value+"*/",t):"/*"+e.value+"*/"}function W(t,r){var n,o,i,a,c,d,p,g,f,h,m,y;if(t.leadingComments&&t.leadingComments.length>0){if(a=r,v){for(r=[],g=(i=t.leadingComments[0]).extendedRange,f=i.range,(y=((m=N.substring(g[0],f[0])).match(/\n/g)||[]).length)>0?(r.push(P("\n",y)),r.push(k(H(i)))):(r.push(m),r.push(H(i))),h=f,n=1,o=t.leadingComments.length;n<o;n++)f=(i=t.leadingComments[n]).range,y=(N.substring(h[1],f[0]).match(/\n/g)||[]).length,r.push(P("\n",y)),r.push(k(H(i))),h=f;y=(N.substring(f[1],g[1]).match(/\n/g)||[]).length,r.push(P("\n",y))}else for(i=t.leadingComments[0],r=[],S&&t.type===e.Program&&0===t.body.length&&r.push("\n"),r.push(H(i)),M(G(r).toString())||r.push("\n"),n=1,o=t.leadingComments.length;n<o;++n)M(G(p=[H(i=t.leadingComments[n])]).toString())||p.push("\n"),r.push(k(p));r.push(k(a))}if(t.trailingComments)if(v)g=(i=t.trailingComments[0]).extendedRange,f=i.range,(y=((m=N.substring(g[0],f[0])).match(/\n/g)||[]).length)>0?(r.push(P("\n",y)),r.push(k(H(i)))):(r.push(m),r.push(H(i)));else for(c=!M(G(r).toString()),d=P(" ",function(e){var t;for(t=e.length-1;t>=0&&!s.code.isLineTerminator(e.charCodeAt(t));--t);return e.length-1-t}(G([u,r,l]).toString())),n=0,o=t.trailingComments.length;n<o;++n)i=t.trailingComments[n],c?(r=0===n?[r,l]:[r,d]).push(H(i,d)):r=[r,k(H(i))],n===o-1||M(G(r).toString())||(r=[r,"\n"]);return r}function K(e,t,r){var n,o=0;fLine truncated
//# sourceMappingURL=index.browser.js.map
+52
View File
@@ -0,0 +1,52 @@
/*!
* Determine if an object is a Buffer
*
* @author Feross Aboukhadijeh <https://feross.org>
* @license MIT
*/
/*!
* The buffer module from node.js, for the browser.
*
* @author Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
* @license MIT
*/
/*!
Copyright (C) 2016-2020 Timofey Kachalov <sanex3339@yandex.ru>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*! *****************************************************************************
Copyright (C) Microsoft. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
+1
View File
@@ -0,0 +1 @@
{"version":3,"sources":["webpack://JavaScriptObfuscator/webpack/universalModuleDefinition","webpack://JavaScriptObfuscator/./node_modules/@javascript-obfuscator/escodegen/escodegen.js","webpack://JavaScriptObfuscator/./node_modules/acorn/dist/acorn.js","webpack://JavaScriptObfuscator/./node_modules/array-filter/index.js","webpack://JavaScriptObfuscator/./node_modules/assert/build/assert.js","webpack://JavaScriptObfuscator/./node_modules/assert/build/internal/assert/assertion_error.js","webpack://JavaScriptObfuscator/./node_modules/assert/build/internal/errors.js","webpack://JavaScriptObfuscator/./node_modules/assert/build/internal/util/comparisons.js","webpack://JavaScriptObfuscator/./node_modules/available-typed-arrays/index.js","webpack://JavaScriptObfuscator/./node_modules/chalk/node_modules/ansi-styles/index.js","webpack://JavaScriptObfuscator/./node_modules/chalk/node_modules/color-convert/conversions.js","webpack://JavaScriptObfuscator/./node_modules/chalk/node_modules/color-convert/index.js","webpack://JavaScriptObfuscator/./node_modules/chalk/node_modules/color-convert/route.js","webpack://JavaScriptObfuscator/./node_modules/chalk/node_modules/color-name/index.js","webpack://JavaScriptObfuscator/./node_modules/chalk/source/index.js","webpack://JavaScriptObfuscator/./node_modules/chalk/source/templates.js","webpack://JavaScriptObfuscator/./node_modules/chalk/source/util.js","webpack://JavaScriptObfuscator/./node_modules/chance/chance.js","webpack://JavaScriptObfuscator/./node_modules/char-regex/index.js","webpack://JavaScriptObfuscator/./node_modules/charenc/charenc.js","webpack://JavaScriptObfuscator/./node_modules/class-validator/esm5/metadata/ValidationMetadata.js","webpack://JavaScriptObfuscator/./node_modules/class-validator/esm5/validation-schema/ValidationSchemaToMetadataTransformer.js","webpack://JavaScriptObfuscator/./node_modules/class-validator/esm5/metadata/MetadataStorage.js","webpack://JavaScriptObfuscator/./node_modules/class-validator/node_modules/tslib/tslib.es6.js","webpack://JavaScriptObfuscator/./node_modules/class-validator/esm5/validation/ValidationError.js","webpack://JavaScriptObfuscator/./node_modules/class-validator/esm5/validation/ValidationTypes.js","webpack://JavaScriptObfuscator/./node_modules/class-validator/esm5/validation/ValidationUtils.js","webpack://JavaScriptObfuscator/./node_modules/class-validator/esm5/utils.js","webpack://JavaScriptObfuscator/./node_modules/class-validator/esm5/validation/ValidationExecutor.js","webpack://JavaScriptObfuscator/./node_modules/class-validator/esm5/container.js","webpack://JavaScriptObfuscator/./node_modules/class-validator/esm5/validation/Validator.js","webpack://JavaScriptObfuscator/./node_modules/class-validator/esm5/decorator/common/Allow.js","webpack://JavaScriptObfuscator/./node_modules/class-validator/esm5/metadata/ConstraintMetadata.js","webpack://JavaScriptObfuscator/./node_modules/class-validator/esm5/register-decorator.js","webpack://JavaScriptObfuscator/./node_modules/class-validator/esm5/decorator/common/ValidateBy.js","webpack://JavaScriptObfuscator/./node_modules/class-validator/esm5/decorator/common/IsDefined.js","webpack://JavaScriptObfuscator/./node_modules/class-validator/esm5/decorator/common/IsOptional.js","webpack://JavaScriptObfuscator/./node_modules/class-validator/esm5/decorator/common/Validate.js","webpack://JavaScriptObfuscator/./node_modules/class-validator/esm5/decorator/common/ValidateIf.js","webpack://JavaScriptObfuscator/./node_modules/class-validator/esm5/decorator/common/ValidateNested.js","webpack://JavaScriptObfuscator/./node_modules/class-validator/esm5/decorator/common/ValidatePromise.js","webpack://JavaScriptObfuscator/./node_modules/class-validator/esm5/decorator/common/IsLatLong.js","webpack://JavaScriptObfuscator/./node_modules/class-validator/esm5/decorator/common/IsLatitude.js","webpack://JavaScriptObfuscator/./node_modules/class-validator/esm5/decorator/common/IsLongitude.js","webpack://JavaScriptObfuscator/./node_modules/class-validator/esm5/decorator/common/Equals.js","webpack://JavaScriptObfuscator/./node_modules/class-validator/esm5/decorator/common/NotEquals.js","webpack://JavaScriptObfuscator/./node_modules/class-validator/esm5/decorator/common/IsEmpty.js","webpack://JavaScriptObfuscator/./node_modules/class-validator/esm5/decorator/common/IsNotEmpty.js","webpack://JavaScriptObfuscator/./node_modules/class-validator/esm5/decorator/common/IsIn.js","webpack://JavaScriptObfuscator/./node_modules/class-validator/esm5/decorator/common/IsNotIn.js","webpack://JavaScriptObfuscator/./node_modules/class-validator/esm5/decorator/number/IsDivisibleBy.js","webpack://JavaScriptObfuscator/./node_modules/class-validator/esm5/decorator/number/IsPositive.js","webpack://JavaScriptObfuscator/./node_modules/class-validator/esm5/decorator/number/IsNegative.js","webpack://JavaScriptObfuscator/./node_modules/class-validator/esm5/decorator/number/Max.js","webpack://JavaScriptObfuscator/./node_modules/clasLine truncated
+3
View File
@@ -0,0 +1,3 @@
/*! For license information please see index.cli.js.LICENSE.txt */
require("source-map-support").install(),module.exports=(()=>{var e={7568:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});const o=r(8206);e.exports=o.JavaScriptObfuscatorCLI},425:function(e,t,r){"use strict";var o=this&&this.__createBinding||(Object.create?function(e,t,r,o){void 0===o&&(o=r),Object.defineProperty(e,o,{enumerable:!0,get:function(){return t[r]}})}:function(e,t,r,o){void 0===o&&(o=r),e[o]=t[r]}),n=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),i=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)"default"!==r&&Object.prototype.hasOwnProperty.call(e,r)&&o(t,e,r);return n(t,e),t},a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.ASTParserFacade=void 0;const s=i(r(6054)),c=a(r(2242));class l{static parse(e,t){const r=l.sourceTypes.length;for(let o=0;o<r;o++)try{return l.parseType(e,t,l.sourceTypes[o])}catch(t){if(o<r-1)continue;throw new Error(l.processParsingError(e,t.message,t.loc))}throw new Error("Acorn parsing error")}static parseType(e,t,r){const o=[],n=Object.assign(Object.assign({},t),{onComment:o,sourceType:r}),i=s.parse(e,n);return o.length&&(i.comments=o),i}static processParsingError(e,t,r){if(!r||!r.line||!r.column)throw new Error(t);const o=e.split(/\r?\n/)[r.line-1];if(!o)throw new Error(t);const n=Math.max(0,r.column-l.nearestSymbolsCount),i=Math.min(o.length,r.column+l.nearestSymbolsCount),a=l.colorError(">"),s=`...${o.slice(n,i).replace(/^\s+/,"")}...`;throw new Error(`ERROR at line ${r.line}: ${t}\n${a} ${s}`)}}t.ASTParserFacade=l,l.colorError=c.default.red,l.nearestSymbolsCount=15,l.sourceTypes=["script","module"]},7086:function(e,t,r){"use strict";var o,n,i,a,s,c,l,d=this&&this.__createBinding||(Object.create?function(e,t,r,o){void 0===o&&(o=r),Object.defineProperty(e,o,{enumerable:!0,get:function(){return t[r]}})}:function(e,t,r,o){void 0===o&&(o=r),e[o]=t[r]}),u=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),p=this&&this.__decorate||function(e,t,r,o){var n,i=arguments.length,a=i<3?t:null===o?o=Object.getOwnPropertyDescriptor(t,r):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)a=Reflect.decorate(e,t,r,o);else for(var s=e.length-1;s>=0;s--)(n=e[s])&&(a=(i<3?n(a):i>3?n(t,r,a):n(t,r))||a);return i>3&&a&&Object.defineProperty(t,r,a),a},f=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)"default"!==r&&Object.prototype.hasOwnProperty.call(e,r)&&d(t,e,r);return u(t,e),t},m=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},g=this&&this.__param||function(e,t){return function(r,o){t(r,o,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.JavaScriptObfuscator=void 0;const S=r(2991),y=r(5350),h=f(r(9385)),N=r(2596),_=r(7673),b=r(5082),O=r(4482),I=r(1403),E=r(698),v=r(7082),C=r(5670),T=r(6221),R=r(4212),A=r(8932),j=r(4941),M=r(425),F=r(4134),P=r(4741);let D=o=class{constructor(e,t,r,o,n,i){this.codeTransformersRunner=e,this.nodeTransformersRunner=t,this.randomGenerator=r,this.obfuscatedCodeFactory=o,this.logger=n,this.options=i}obfuscate(e){"string"!=typeof e&&(e="");const t=Date.now();this.logger.info(T.LoggingMessage.Version,P.Utils.buildVersionMessage("2.9.4",1606121270168)),this.logger.info(T.LoggingMessage.ObfuscationStarted),this.logger.info(T.LoggingMessage.RandomGeneratorSeed,this.randomGenerator.getInputSeed()),e=this.runCodeTransformationStage(e,C.CodeTransformationStage.PreparingTransformers);const r=this.parseCode(e),o=this.transformAstTree(r),n=this.generateCode(e,o);n.code=this.runCodeTransformationStage(n.code,C.CodeTransformationStage.FinalizingTransformers);const i=(Date.now()-t)/1e3;return this.logger.success(T.LoggingMessage.ObfuscationCompleted,i),this.getObfuscatedCode(n)}parseCode(e){return M.ASTParserFacade.parse(e,o.parseOptions)}transformAstTree(e){return e=this.runNodeTransformationStage(e,A.NodeTransformationStage.Initializing),!F.NodeGuards.isProgramNode(e)||e.body.length||e.leadingComments||e.trailingComments?(e=this.runNodeTransformationStage(e,A.NodeTransformationStage.Preparing),this.options.deadCodeInjection&&(e=this.runNodeTransformationStage(e,A.NodeTransformationStage.DeadCodeInjection)),this.options.controlFlowFlattening&&(e=this.runNodeTransformationStage(e,A.NodeTransformationStage.ControlFlowFlattening)),this.options.renameProperties&&(e=this.runNodeTransformationStage(e,A.NodeTransformationStage.RenameProperties)),e=this.runNodeTransformationStage(e,A.NodeTransformationStage.Converting),e=this.runNodeTransformationStage(e,A.NodeTransformationStage.RenameIdentifiers),e=this.runNodeTransformationStage(e,A.NodeTransformationStage.StringArray),this.Line truncated
//# sourceMappingURL=index.cli.js.map
+23
View File
@@ -0,0 +1,23 @@
/*!
Copyright (C) 2016-2020 Timofey Kachalov <sanex3339@yandex.ru>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+1
View File
@@ -0,0 +1 @@
{"version":3,"sources":["webpack://javascript-obfuscator/./index.cli.ts","webpack://javascript-obfuscator/./src/ASTParserFacade.ts","webpack://javascript-obfuscator/./src/JavaScriptObfuscator.ts","webpack://javascript-obfuscator/./src/JavaScriptObfuscatorCLIFacade.ts","webpack://javascript-obfuscator/./src/JavaScriptObfuscatorFacade.ts","webpack://javascript-obfuscator/./src/analyzers/calls-graph-analyzer/CallsGraphAnalyzer.ts","webpack://javascript-obfuscator/./src/analyzers/calls-graph-analyzer/callee-data-extractors/AbstractCalleeDataExtractor.ts","webpack://javascript-obfuscator/./src/analyzers/calls-graph-analyzer/callee-data-extractors/FunctionDeclarationCalleeDataExtractor.ts","webpack://javascript-obfuscator/./src/analyzers/calls-graph-analyzer/callee-data-extractors/FunctionExpressionCalleeDataExtractor.ts","webpack://javascript-obfuscator/./src/analyzers/calls-graph-analyzer/callee-data-extractors/ObjectExpressionCalleeDataExtractor.ts","webpack://javascript-obfuscator/./src/analyzers/number-numerical-expression-analyzer/NumberNumericalExpressionAnalyzer.ts","webpack://javascript-obfuscator/./src/analyzers/prevailing-kind-of-variables-analyzer/PrevailingKindOfVariablesAnalyzer.ts","webpack://javascript-obfuscator/./src/analyzers/scope-analyzer/ScopeAnalyzer.ts","webpack://javascript-obfuscator/./src/analyzers/string-array-storage-analyzer/StringArrayStorageAnalyzer.ts","webpack://javascript-obfuscator/./src/cli/JavaScriptObfuscatorCLI.ts","webpack://javascript-obfuscator/./src/cli/sanitizers/ArraySanitizer.ts","webpack://javascript-obfuscator/./src/cli/sanitizers/BooleanSanitizer.ts","webpack://javascript-obfuscator/./src/cli/utils/CLIUtils.ts","webpack://javascript-obfuscator/./src/cli/utils/ObfuscatedCodeWriter.ts","webpack://javascript-obfuscator/./src/cli/utils/SourceCodeReader.ts","webpack://javascript-obfuscator/./src/code-transformers/AbstractCodeTransformer.ts","webpack://javascript-obfuscator/./src/code-transformers/CodeTransformerNamesGroupsBuilder.ts","webpack://javascript-obfuscator/./src/code-transformers/CodeTransformersRunner.ts","webpack://javascript-obfuscator/./src/code-transformers/preparing-transformers/HashbangOperatorTransformer.ts","webpack://javascript-obfuscator/./src/constants/AlphabetString.ts","webpack://javascript-obfuscator/./src/constants/AlphabetStringUppercase.ts","webpack://javascript-obfuscator/./src/constants/Base64Alphabet.ts","webpack://javascript-obfuscator/./src/constants/Base64AlphabetSwapped.ts","webpack://javascript-obfuscator/./src/constants/EcmaVersion.ts","webpack://javascript-obfuscator/./src/constants/NumbersString.ts","webpack://javascript-obfuscator/./src/container/InversifyContainerFacade.ts","webpack://javascript-obfuscator/./src/container/ServiceIdentifiers.ts","webpack://javascript-obfuscator/./src/container/modules/analyzers/AnalyzersModule.ts","webpack://javascript-obfuscator/./src/container/modules/code-transformers/CodeTransformersModule.ts","webpack://javascript-obfuscator/./src/container/modules/custom-code-helpers/CustomCodeHelpersModule.ts","webpack://javascript-obfuscator/./src/container/modules/custom-nodes/CustomNodesModule.ts","webpack://javascript-obfuscator/./src/container/modules/generators/GeneratorsModule.ts","webpack://javascript-obfuscator/./src/container/modules/node-transformers/ControlFlowTransformersModule.ts","webpack://javascript-obfuscator/./src/container/modules/node-transformers/ConvertingTransformersModule.ts","webpack://javascript-obfuscator/./src/container/modules/node-transformers/DeadCodeInjectionTransformersModule.ts","webpack://javascript-obfuscator/./src/container/modules/node-transformers/FinalizingTransformersModule.ts","webpack://javascript-obfuscator/./src/container/modules/node-transformers/InitializingTransformersModule.ts","webpack://javascript-obfuscator/./src/container/modules/node-transformers/NodeTransformersModule.ts","webpack://javascript-obfuscator/./src/container/modules/node-transformers/PreparingTransformersModule.ts","webpack://javascript-obfuscator/./src/container/modules/node-transformers/RenameIdentifiersTransformersModule.ts","webpack://javascript-obfuscator/./src/container/modules/node-transformers/RenamePropertiesTransformersModule.ts","webpack://javascript-obfuscator/./src/container/modules/node-transformers/SimplifyingTransformersModule.ts","webpack://javascript-obfuscator/./src/container/modules/node-transformers/StringArrayTransformersModule.ts","webpack://javascript-obfuscator/./src/container/modules/node/NodeModule.ts","webpack://javascript-obfuscator/./src/container/modules/options/OptionsModule.ts","webpack://javascript-obfuscator/./src/container/modules/storages/StoragesModule.ts","webpack://javascript-obfuscator/./src/container/modules/utils/UtilsModule.ts","webpack://javascript-obfuscator/./src/custom-code-helpers/AbstractCustomCodeHelper.ts","webpack://javascript-obfuscator/./src/custom-code-helpers/AbstractCustomCodeHelperGroup.ts","webpack://javascript-obfuscator/./src/cLine truncated
+3
View File
@@ -0,0 +1,3 @@
/*! For license information please see index.js.LICENSE.txt */
require("source-map-support").install(),module.exports=(()=>{"use strict";var e={3254:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0});const o=r(2895);e.exports=o.JavaScriptObfuscator},425:function(e,t,r){var o=this&&this.__createBinding||(Object.create?function(e,t,r,o){void 0===o&&(o=r),Object.defineProperty(e,o,{enumerable:!0,get:function(){return t[r]}})}:function(e,t,r,o){void 0===o&&(o=r),e[o]=t[r]}),n=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),i=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)"default"!==r&&Object.prototype.hasOwnProperty.call(e,r)&&o(t,e,r);return n(t,e),t},a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.ASTParserFacade=void 0;const s=i(r(6054)),c=a(r(2242));class d{static parse(e,t){const r=d.sourceTypes.length;for(let o=0;o<r;o++)try{return d.parseType(e,t,d.sourceTypes[o])}catch(t){if(o<r-1)continue;throw new Error(d.processParsingError(e,t.message,t.loc))}throw new Error("Acorn parsing error")}static parseType(e,t,r){const o=[],n=Object.assign(Object.assign({},t),{onComment:o,sourceType:r}),i=s.parse(e,n);return o.length&&(i.comments=o),i}static processParsingError(e,t,r){if(!r||!r.line||!r.column)throw new Error(t);const o=e.split(/\r?\n/)[r.line-1];if(!o)throw new Error(t);const n=Math.max(0,r.column-d.nearestSymbolsCount),i=Math.min(o.length,r.column+d.nearestSymbolsCount),a=d.colorError(">"),s=`...${o.slice(n,i).replace(/^\s+/,"")}...`;throw new Error(`ERROR at line ${r.line}: ${t}\n${a} ${s}`)}}t.ASTParserFacade=d,d.colorError=c.default.red,d.nearestSymbolsCount=15,d.sourceTypes=["script","module"]},7086:function(e,t,r){var o,n,i,a,s,c,d,l=this&&this.__createBinding||(Object.create?function(e,t,r,o){void 0===o&&(o=r),Object.defineProperty(e,o,{enumerable:!0,get:function(){return t[r]}})}:function(e,t,r,o){void 0===o&&(o=r),e[o]=t[r]}),u=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),f=this&&this.__decorate||function(e,t,r,o){var n,i=arguments.length,a=i<3?t:null===o?o=Object.getOwnPropertyDescriptor(t,r):o;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)a=Reflect.decorate(e,t,r,o);else for(var s=e.length-1;s>=0;s--)(n=e[s])&&(a=(i<3?n(a):i>3?n(t,r,a):n(t,r))||a);return i>3&&a&&Object.defineProperty(t,r,a),a},p=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)"default"!==r&&Object.prototype.hasOwnProperty.call(e,r)&&l(t,e,r);return u(t,e),t},m=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},g=this&&this.__param||function(e,t){return function(r,o){t(r,o,e)}};Object.defineProperty(t,"__esModule",{value:!0}),t.JavaScriptObfuscator=void 0;const S=r(2991),y=r(5350),N=p(r(9385)),h=r(2596),_=r(7673),b=r(5082),I=r(4482),O=r(1403),E=r(698),v=r(7082),C=r(5670),T=r(6221),R=r(4212),A=r(8932),j=r(4941),M=r(425),F=r(4134),P=r(4741);let D=o=class{constructor(e,t,r,o,n,i){this.codeTransformersRunner=e,this.nodeTransformersRunner=t,this.randomGenerator=r,this.obfuscatedCodeFactory=o,this.logger=n,this.options=i}obfuscate(e){"string"!=typeof e&&(e="");const t=Date.now();this.logger.info(T.LoggingMessage.Version,P.Utils.buildVersionMessage("2.9.4",1606121270168)),this.logger.info(T.LoggingMessage.ObfuscationStarted),this.logger.info(T.LoggingMessage.RandomGeneratorSeed,this.randomGenerator.getInputSeed()),e=this.runCodeTransformationStage(e,C.CodeTransformationStage.PreparingTransformers);const r=this.parseCode(e),o=this.transformAstTree(r),n=this.generateCode(e,o);n.code=this.runCodeTransformationStage(n.code,C.CodeTransformationStage.FinalizingTransformers);const i=(Date.now()-t)/1e3;return this.logger.success(T.LoggingMessage.ObfuscationCompleted,i),this.getObfuscatedCode(n)}parseCode(e){return M.ASTParserFacade.parse(e,o.parseOptions)}transformAstTree(e){return e=this.runNodeTransformationStage(e,A.NodeTransformationStage.Initializing),!F.NodeGuards.isProgramNode(e)||e.body.length||e.leadingComments||e.trailingComments?(e=this.runNodeTransformationStage(e,A.NodeTransformationStage.Preparing),this.options.deadCodeInjection&&(e=this.runNodeTransformationStage(e,A.NodeTransformationStage.DeadCodeInjection)),this.options.controlFlowFlattening&&(e=this.runNodeTransformationStage(e,A.NodeTransformationStage.ControlFlowFlattening)),this.options.renameProperties&&(e=this.runNodeTransformationStage(e,A.NodeTransformationStage.RenameProperties)),e=this.runNodeTransformationStage(e,A.NodeTransformationStage.Converting),e=this.runNodeTransformationStage(e,A.NodeTransformationStage.RenameIdentifiers),e=this.runNodeTransformationStage(e,A.NodeTransformationStage.StringArray),this.options.simplify&&(e=this.runLine truncated
//# sourceMappingURL=index.js.map
+23
View File
@@ -0,0 +1,23 @@
/*!
Copyright (C) 2016-2020 Timofey Kachalov <sanex3339@yandex.ru>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+1
View File
@@ -0,0 +1 @@
{"version":3,"sources":["webpack://javascript-obfuscator/./index.ts","webpack://javascript-obfuscator/./src/ASTParserFacade.ts","webpack://javascript-obfuscator/./src/JavaScriptObfuscator.ts","webpack://javascript-obfuscator/./src/JavaScriptObfuscatorFacade.ts","webpack://javascript-obfuscator/./src/analyzers/calls-graph-analyzer/CallsGraphAnalyzer.ts","webpack://javascript-obfuscator/./src/analyzers/calls-graph-analyzer/callee-data-extractors/AbstractCalleeDataExtractor.ts","webpack://javascript-obfuscator/./src/analyzers/calls-graph-analyzer/callee-data-extractors/FunctionDeclarationCalleeDataExtractor.ts","webpack://javascript-obfuscator/./src/analyzers/calls-graph-analyzer/callee-data-extractors/FunctionExpressionCalleeDataExtractor.ts","webpack://javascript-obfuscator/./src/analyzers/calls-graph-analyzer/callee-data-extractors/ObjectExpressionCalleeDataExtractor.ts","webpack://javascript-obfuscator/./src/analyzers/number-numerical-expression-analyzer/NumberNumericalExpressionAnalyzer.ts","webpack://javascript-obfuscator/./src/analyzers/prevailing-kind-of-variables-analyzer/PrevailingKindOfVariablesAnalyzer.ts","webpack://javascript-obfuscator/./src/analyzers/scope-analyzer/ScopeAnalyzer.ts","webpack://javascript-obfuscator/./src/analyzers/string-array-storage-analyzer/StringArrayStorageAnalyzer.ts","webpack://javascript-obfuscator/./src/code-transformers/AbstractCodeTransformer.ts","webpack://javascript-obfuscator/./src/code-transformers/CodeTransformerNamesGroupsBuilder.ts","webpack://javascript-obfuscator/./src/code-transformers/CodeTransformersRunner.ts","webpack://javascript-obfuscator/./src/code-transformers/preparing-transformers/HashbangOperatorTransformer.ts","webpack://javascript-obfuscator/./src/constants/AlphabetString.ts","webpack://javascript-obfuscator/./src/constants/AlphabetStringUppercase.ts","webpack://javascript-obfuscator/./src/constants/Base64Alphabet.ts","webpack://javascript-obfuscator/./src/constants/Base64AlphabetSwapped.ts","webpack://javascript-obfuscator/./src/constants/EcmaVersion.ts","webpack://javascript-obfuscator/./src/constants/NumbersString.ts","webpack://javascript-obfuscator/./src/container/InversifyContainerFacade.ts","webpack://javascript-obfuscator/./src/container/ServiceIdentifiers.ts","webpack://javascript-obfuscator/./src/container/modules/analyzers/AnalyzersModule.ts","webpack://javascript-obfuscator/./src/container/modules/code-transformers/CodeTransformersModule.ts","webpack://javascript-obfuscator/./src/container/modules/custom-code-helpers/CustomCodeHelpersModule.ts","webpack://javascript-obfuscator/./src/container/modules/custom-nodes/CustomNodesModule.ts","webpack://javascript-obfuscator/./src/container/modules/generators/GeneratorsModule.ts","webpack://javascript-obfuscator/./src/container/modules/node-transformers/ControlFlowTransformersModule.ts","webpack://javascript-obfuscator/./src/container/modules/node-transformers/ConvertingTransformersModule.ts","webpack://javascript-obfuscator/./src/container/modules/node-transformers/DeadCodeInjectionTransformersModule.ts","webpack://javascript-obfuscator/./src/container/modules/node-transformers/FinalizingTransformersModule.ts","webpack://javascript-obfuscator/./src/container/modules/node-transformers/InitializingTransformersModule.ts","webpack://javascript-obfuscator/./src/container/modules/node-transformers/NodeTransformersModule.ts","webpack://javascript-obfuscator/./src/container/modules/node-transformers/PreparingTransformersModule.ts","webpack://javascript-obfuscator/./src/container/modules/node-transformers/RenameIdentifiersTransformersModule.ts","webpack://javascript-obfuscator/./src/container/modules/node-transformers/RenamePropertiesTransformersModule.ts","webpack://javascript-obfuscator/./src/container/modules/node-transformers/SimplifyingTransformersModule.ts","webpack://javascript-obfuscator/./src/container/modules/node-transformers/StringArrayTransformersModule.ts","webpack://javascript-obfuscator/./src/container/modules/node/NodeModule.ts","webpack://javascript-obfuscator/./src/container/modules/options/OptionsModule.ts","webpack://javascript-obfuscator/./src/container/modules/storages/StoragesModule.ts","webpack://javascript-obfuscator/./src/container/modules/utils/UtilsModule.ts","webpack://javascript-obfuscator/./src/custom-code-helpers/AbstractCustomCodeHelper.ts","webpack://javascript-obfuscator/./src/custom-code-helpers/AbstractCustomCodeHelperGroup.ts","webpack://javascript-obfuscator/./src/custom-code-helpers/CustomCodeHelperFormatter.ts","webpack://javascript-obfuscator/./src/custom-code-helpers/CustomCodeHelperObfuscator.ts","webpack://javascript-obfuscator/./src/custom-code-helpers/calls-controller/CallsControllerFunctionCodeHelper.ts","webpack://javascript-obfuscator/./src/custom-code-helpers/common/templates/GlobalVariableNoEvalTemplate.ts","webpack://javascript-obfuscator/./src/custom-code-helpers/common/templates/GlobalVariableTemplate1.ts","webpack://javascript-obfuscator/./sLine truncated
+5
View File
@@ -0,0 +1,5 @@
"use strict";
import { JavaScriptObfuscatorCLI } from './src/JavaScriptObfuscatorCLIFacade';
module.exports = JavaScriptObfuscatorCLI;
+38
View File
@@ -0,0 +1,38 @@
import { TDictionary } from './src/types/TDictionary';
import { TInputOptions } from './src/types/options/TInputOptions';
import { TObfuscationResultsObject } from './src/types/TObfuscationResultsObject';
import { TOptionsPreset } from './src/types/options/TOptionsPreset';
import { IObfuscatedCode } from './src/interfaces/source-code/IObfuscatedCode';
export type ObfuscatorOptions = TInputOptions;
export interface ObfuscatedCode extends IObfuscatedCode {}
/**
* @param {string} sourceCode
* @param {ObfuscatorOptions} inputOptions
* @returns {ObfuscatedCode}
*/
export function obfuscate (sourceCode: string, inputOptions?: ObfuscatorOptions): ObfuscatedCode;
/**
* @param {TSourceCodesObject} sourceCodesObject
* @param {TInputOptions} inputOptions
* @returns {TObfuscationResultsObject<TSourceCodesObject>}
*/
export function obfuscateMultiple <TSourceCodesObject extends TDictionary<string>> (
sourceCodesObject: TSourceCodesObject,
inputOptions?: TInputOptions
): TObfuscationResultsObject<TSourceCodesObject>;
/**
* @param {TOptionsPreset} optionsPreset
* @returns {TInputOptions}
*/
export function getOptionsByPreset (optionsPreset: TOptionsPreset): TInputOptions;
/**
* @type {string}
*/
export const version: string;
+5
View File
@@ -0,0 +1,5 @@
"use strict";
import { JavaScriptObfuscator } from './src/JavaScriptObfuscatorFacade';
module.exports = JavaScriptObfuscator;
+174
View File
@@ -0,0 +1,174 @@
{
"_args": [
[
"javascript-obfuscator@2.9.4",
"/Users/oliverbarr/Documents/Discord Bots/SupportBot"
]
],
"_from": "javascript-obfuscator@2.9.4",
"_id": "javascript-obfuscator@2.9.4",
"_inBundle": false,
"_integrity": "sha512-isaI1E9BkqUI7cgG7RKmzzqe8GrmIr3E+AJBCJ+Q78dEZk4RByPHq65tkCUdKKRT8pZ1y729prPa5UAme2B4Ug==",
"_location": "/javascript-obfuscator",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "javascript-obfuscator@2.9.4",
"name": "javascript-obfuscator",
"escapedName": "javascript-obfuscator",
"rawSpec": "2.9.4",
"saveSpec": null,
"fetchSpec": "2.9.4"
},
"_requiredBy": [
"/"
],
"_resolved": "https://registry.npmjs.org/javascript-obfuscator/-/javascript-obfuscator-2.9.4.tgz",
"_spec": "2.9.4",
"_where": "/Users/oliverbarr/Documents/Discord Bots/SupportBot",
"author": {
"name": "Timofey Kachalov"
},
"bin": {
"javascript-obfuscator": "bin/javascript-obfuscator"
},
"browser": "dist/index.browser.js",
"bugs": {
"url": "https://github.com/javascript-obfuscator/javascript-obfuscator/issues"
},
"collective": {
"url": "https://opencollective.com/javascript-obfuscator"
},
"contributors": [
{
"name": "Timofey Kachalov",
"url": "https://github.com/sanex3339"
},
{
"name": "Dmitry Zamotkin",
"url": "https://github.com/zamotkin"
}
],
"dependencies": {
"@javascript-obfuscator/escodegen": "2.1.1",
"@nuxtjs/opencollective": "0.3.2",
"acorn": "8.0.4",
"assert": "2.0.0",
"chalk": "4.1.0",
"chance": "1.1.7",
"class-validator": "0.12.2",
"commander": "6.2.0",
"eslint-scope": "5.1.1",
"estraverse": "5.2.0",
"eventemitter3": "4.0.7",
"fast-deep-equal": "3.1.3",
"inversify": "5.0.1",
"js-string-escape": "1.0.1",
"md5": "2.3.0",
"mkdirp": "1.0.4",
"multimatch": "5.0.0",
"process": "0.11.10",
"reflect-metadata": "0.1.13",
"source-map-support": "0.5.19",
"string-template": "1.0.0",
"stringz": "2.1.0",
"tslib": "2.0.3"
},
"description": "JavaScript obfuscator",
"devDependencies": {
"@istanbuljs/nyc-config-typescript": "1.0.1",
"@types/chai": "4.2.14",
"@types/chance": "1.1.0",
"@types/escodegen": "0.0.6",
"@types/eslint-scope": "3.7.0",
"@types/estraverse": "5.1.0",
"@types/estree": "0.0.45",
"@types/js-string-escape": "1.0.0",
"@types/md5": "2.2.1",
"@types/mkdirp": "1.0.1",
"@types/mocha": "8.0.4",
"@types/multimatch": "4.0.0",
"@types/node": "14.14.9",
"@types/rimraf": "3.0.0",
"@types/sinon": "9.0.8",
"@types/string-template": "1.0.2",
"@types/webpack-env": "1.15.3",
"@typescript-eslint/eslint-plugin": "4.8.1",
"@typescript-eslint/parser": "4.8.1",
"chai": "4.2.0",
"chai-exclude": "2.0.2",
"coveralls": "3.1.0",
"cross-env": "7.0.2",
"eslint": "7.14.0",
"eslint-plugin-import": "2.22.1",
"eslint-plugin-jsdoc": "30.7.8",
"eslint-plugin-no-null": "1.0.2",
"eslint-plugin-prefer-arrow": "1.2.2",
"eslint-plugin-unicorn": "23.0.0",
"fork-ts-checker-notifier-webpack-plugin": "3.0.0",
"fork-ts-checker-webpack-plugin": "6.0.3",
"mocha": "8.2.1",
"nyc": "15.1.0",
"pjson": "1.0.9",
"pre-commit": "1.2.2",
"rimraf": "3.0.2",
"sinon": "9.2.1",
"threads": "1.6.3",
"ts-loader": "8.0.11",
"ts-node": "9.0.0",
"typescript": "4.1.2",
"webpack": "5.6.0",
"webpack-cli": "4.2.0",
"webpack-node-externals": "2.5.2"
},
"engines": {
"node": ">=10"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/javascript-obfuscator"
},
"homepage": "https://obfuscator.io/",
"keywords": [
"obfuscator",
"obfuscation",
"uglify",
"crush",
"code protection",
"javascript obfuscator",
"js obfuscator"
],
"license": "BSD-2-Clause",
"main": "dist/index.js",
"name": "javascript-obfuscator",
"pre-commit": [
"build",
"git:addFiles"
],
"repository": {
"type": "git",
"url": "git+https://github.com/javascript-obfuscator/javascript-obfuscator.git"
},
"scripts": {
"build": "yarn run webpack:prod && yarn run eslint && yarn test",
"eslint": "eslint src/**/*.ts",
"git:addFiles": "git add .",
"postinstall": "opencollective",
"start": "yarn run watch",
"test": "yarn run test:full",
"test:dev": "ts-node --type-check test/dev/dev.ts",
"test:devCompilePerformance": "ts-node test/dev/dev-compile-performance.ts",
"test:devRuntimePerformance": "ts-node test/dev/dev-runtime-performance.ts",
"test:full": "yarn run test:dev && yarn run test:mocha-coverage && yarn run test:mocha-memory-performance",
"test:mocha": "mocha --require ts-node/register --require source-map-support/register test/index.spec.ts --exit",
"test:mocha-coverage": "nyc --reporter text-summary --no-clean yarn run test:mocha",
"test:mocha-coverage:report": "nyc report --reporter=text-lcov | coveralls",
"test:mocha-memory-performance": "cross-env NODE_OPTIONS=--max-old-space-size=220 mocha --require ts-node/register test/performance-tests/JavaScriptObfuscatorMemory.spec.ts",
"travis": "yarn run eslint && yarn run test",
"watch": "webpack --config ./webpack/webpack.node.config.js --mode development --watch",
"webpack:prod": "webpack --config ./webpack/webpack.node.config.js --config ./webpack/webpack.browser.config.js --mode production"
},
"types": "index.d.ts",
"version": "2.9.4"
}
+116
View File
@@ -0,0 +1,116 @@
import * as acorn from 'acorn';
import * as ESTree from 'estree';
import chalk, { Chalk } from 'chalk';
/**
* Facade over AST parser `acorn`
*/
export class ASTParserFacade {
/**
* @type {Chalk}
*/
private static readonly colorError: Chalk = chalk.red;
/**
* @type {number}
*/
private static readonly nearestSymbolsCount: number = 15;
/**
* @type {acorn.Options['sourceType'][]}
*/
private static readonly sourceTypes: acorn.Options['sourceType'][] = [
'script',
'module'
];
/**
* @param {string} sourceCode
* @param {Options} config
* @returns {Program}
*/
public static parse (sourceCode: string, config: acorn.Options): ESTree.Program | never {
const sourceTypeLength: number = ASTParserFacade.sourceTypes.length;
for (let i: number = 0; i < sourceTypeLength; i++) {
try {
return ASTParserFacade.parseType(sourceCode, config, ASTParserFacade.sourceTypes[i]);
} catch (error) {
if (i < sourceTypeLength - 1) {
continue;
}
throw new Error(ASTParserFacade.processParsingError(
sourceCode,
error.message,
error.loc
));
}
}
throw new Error('Acorn parsing error');
}
/**
* @param {string} sourceCode
* @param {acorn.Options} inputConfig
* @param {acorn.Options["sourceType"]} sourceType
* @returns {Program}
*/
private static parseType (
sourceCode: string,
inputConfig: acorn.Options,
sourceType: acorn.Options['sourceType']
): ESTree.Program {
const comments: ESTree.Comment[] = [];
const config: acorn.Options = {
...inputConfig,
onComment: comments,
sourceType
};
const program: ESTree.Program = <any>acorn
.parse(sourceCode, config);
if (comments.length) {
program.comments = comments;
}
return program;
}
/**
* @param {string} sourceCode
* @param {string} errorMessage
* @param {Position | null} position
* @returns {never}
*/
private static processParsingError (
sourceCode: string,
errorMessage: string,
position: ESTree.Position | null
): never {
if (!position || !position.line || !position.column) {
throw new Error(errorMessage);
}
const sourceCodeLines: string[] = sourceCode.split(/\r?\n/);
const errorLine: string | undefined = sourceCodeLines[position.line - 1];
if (!errorLine) {
throw new Error(errorMessage);
}
const startErrorIndex: number = Math.max(0, position.column - ASTParserFacade.nearestSymbolsCount);
const endErrorIndex: number = Math.min(errorLine.length, position.column + ASTParserFacade.nearestSymbolsCount);
const formattedPointer: string = ASTParserFacade.colorError('>');
const formattedCodeSlice: string = `...${
errorLine.slice(startErrorIndex, endErrorIndex).replace(/^\s+/, '')
}...`;
throw new Error(
`ERROR at line ${position.line}: ${errorMessage}\n${formattedPointer} ${formattedCodeSlice}`
);
}
}
+304
View File
@@ -0,0 +1,304 @@
import { inject, injectable, } from 'inversify';
import { ServiceIdentifiers } from './container/ServiceIdentifiers';
import * as acorn from 'acorn';
import * as escodegen from '@javascript-obfuscator/escodegen';
import * as ESTree from 'estree';
import { TObfuscatedCodeFactory } from './types/container/source-code/TObfuscatedCodeFactory';
import { ICodeTransformersRunner } from './interfaces/code-transformers/ICodeTransformersRunner';
import { IGeneratorOutput } from './interfaces/IGeneratorOutput';
import { IJavaScriptObfuscator } from './interfaces/IJavaScriptObfsucator';
import { ILogger } from './interfaces/logger/ILogger';
import { IObfuscatedCode } from './interfaces/source-code/IObfuscatedCode';
import { IOptions } from './interfaces/options/IOptions';
import { IRandomGenerator } from './interfaces/utils/IRandomGenerator';
import { INodeTransformersRunner } from './interfaces/node-transformers/INodeTransformersRunner';
import { CodeTransformer } from './enums/code-transformers/CodeTransformer';
import { CodeTransformationStage } from './enums/code-transformers/CodeTransformationStage';
import { LoggingMessage } from './enums/logger/LoggingMessage';
import { NodeTransformer } from './enums/node-transformers/NodeTransformer';
import { NodeTransformationStage } from './enums/node-transformers/NodeTransformationStage';
import { ecmaVersion } from './constants/EcmaVersion';
import { ASTParserFacade } from './ASTParserFacade';
import { NodeGuards } from './node/NodeGuards';
import { Utils } from './utils/Utils';
@injectable()
export class JavaScriptObfuscator implements IJavaScriptObfuscator {
/**
* @type {Options}
*/
private static readonly parseOptions: acorn.Options = {
ecmaVersion,
allowHashBang: true,
allowImportExportEverywhere: true,
allowReturnOutsideFunction: true,
locations: true,
ranges: true
};
/**
* @type {GenerateOptions}
*/
private static readonly escodegenParams: escodegen.GenerateOptions = {
comment: true,
verbatim: 'x-verbatim-property',
sourceMapWithCode: true
};
/**
* @type {CodeTransformer[]}
*/
private static readonly codeTransformersList: CodeTransformer[] = [
CodeTransformer.HashbangOperatorTransformer
];
/**
* @type {NodeTransformer[]}
*/
private static readonly nodeTransformersList: NodeTransformer[] = [
NodeTransformer.BooleanLiteralTransformer,
NodeTransformer.BlockStatementControlFlowTransformer,
NodeTransformer.BlockStatementSimplifyTransformer,
NodeTransformer.CommentsTransformer,
NodeTransformer.CustomCodeHelpersTransformer,
NodeTransformer.DeadCodeInjectionTransformer,
NodeTransformer.EscapeSequenceTransformer,
NodeTransformer.EvalCallExpressionTransformer,
NodeTransformer.ExportSpecifierTransformer,
NodeTransformer.ExpressionStatementsMergeTransformer,
NodeTransformer.FunctionControlFlowTransformer,
NodeTransformer.IfStatementSimplifyTransformer,
NodeTransformer.LabeledStatementTransformer,
NodeTransformer.RenamePropertiesTransformer,
NodeTransformer.MemberExpressionTransformer,
NodeTransformer.MetadataTransformer,
NodeTransformer.MethodDefinitionTransformer,
NodeTransformer.NumberLiteralTransformer,
NodeTransformer.NumberToNumericalExpressionTransformer,
NodeTransformer.ObfuscatingGuardsTransformer,
NodeTransformer.ObjectExpressionKeysTransformer,
NodeTransformer.ObjectExpressionTransformer,
NodeTransformer.ObjectPatternPropertiesTransformer,
NodeTransformer.ParentificationTransformer,
NodeTransformer.ScopeIdentifiersTransformer,
NodeTransformer.SplitStringTransformer,
NodeTransformer.StringArrayScopeCallsWrapperTransformer,
NodeTransformer.StringArrayTransformer,
NodeTransformer.TemplateLiteralTransformer,
NodeTransformer.VariableDeclarationsMergeTransformer,
NodeTransformer.VariablePreserveTransformer
];
/**
* @type {ICodeTransformersRunner}
*/
private readonly codeTransformersRunner: ICodeTransformersRunner;
/**
* @type {ILogger}
*/
private readonly logger: ILogger;
/**
* @type {TObfuscatedCodeFactory}
*/
private readonly obfuscatedCodeFactory: TObfuscatedCodeFactory;
/**
* @type {IOptions}
*/
private readonly options: IOptions;
/**
* @type {IRandomGenerator}
*/
private readonly randomGenerator: IRandomGenerator;
/**
* @type {INodeTransformersRunner}
*/
private readonly nodeTransformersRunner: INodeTransformersRunner;
/**
* @param {ICodeTransformersRunner} codeTransformersRunner
* @param {INodeTransformersRunner} nodeTransformersRunner
* @param {IRandomGenerator} randomGenerator
* @param {TObfuscatedCodeFactory} obfuscatedCodeFactory
* @param {ILogger} logger
* @param {IOptions} options
*/
public constructor (
@inject(ServiceIdentifiers.ICodeTransformersRunner) codeTransformersRunner: ICodeTransformersRunner,
@inject(ServiceIdentifiers.INodeTransformersRunner) nodeTransformersRunner: INodeTransformersRunner,
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
@inject(ServiceIdentifiers.Factory__IObfuscatedCode) obfuscatedCodeFactory: TObfuscatedCodeFactory,
@inject(ServiceIdentifiers.ILogger) logger: ILogger,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
this.codeTransformersRunner = codeTransformersRunner;
this.nodeTransformersRunner = nodeTransformersRunner;
this.randomGenerator = randomGenerator;
this.obfuscatedCodeFactory = obfuscatedCodeFactory;
this.logger = logger;
this.options = options;
}
/**
* @param {string} sourceCode
* @returns {IObfuscatedCode}
*/
public obfuscate (sourceCode: string): IObfuscatedCode {
if (typeof sourceCode !== 'string') {
sourceCode = '';
}
const timeStart: number = Date.now();
this.logger.info(LoggingMessage.Version, Utils.buildVersionMessage(process.env.VERSION, process.env.BUILD_TIMESTAMP));
this.logger.info(LoggingMessage.ObfuscationStarted);
this.logger.info(LoggingMessage.RandomGeneratorSeed, this.randomGenerator.getInputSeed());
// preparing code transformations
sourceCode = this.runCodeTransformationStage(sourceCode, CodeTransformationStage.PreparingTransformers);
// parse AST tree
const astTree: ESTree.Program = this.parseCode(sourceCode);
// obfuscate AST tree
const obfuscatedAstTree: ESTree.Program = this.transformAstTree(astTree);
// generate code
const generatorOutput: IGeneratorOutput = this.generateCode(sourceCode, obfuscatedAstTree);
// finalizing code transformations
generatorOutput.code = this.runCodeTransformationStage(generatorOutput.code, CodeTransformationStage.FinalizingTransformers);
const obfuscationTime: number = (Date.now() - timeStart) / 1000;
this.logger.success(LoggingMessage.ObfuscationCompleted, obfuscationTime);
return this.getObfuscatedCode(generatorOutput);
}
/**
* @param {string} sourceCode
* @returns {Program}
*/
private parseCode (sourceCode: string): ESTree.Program {
return ASTParserFacade.parse(sourceCode, JavaScriptObfuscator.parseOptions);
}
/**
* @param {Program} astTree
* @returns {Program}
*/
private transformAstTree (astTree: ESTree.Program): ESTree.Program {
astTree = this.runNodeTransformationStage(astTree, NodeTransformationStage.Initializing);
const isEmptyAstTree: boolean = NodeGuards.isProgramNode(astTree)
&& !astTree.body.length
&& !astTree.leadingComments
&& !astTree.trailingComments;
if (isEmptyAstTree) {
this.logger.warn(LoggingMessage.EmptySourceCode);
return astTree;
}
astTree = this.runNodeTransformationStage(astTree, NodeTransformationStage.Preparing);
if (this.options.deadCodeInjection) {
astTree = this.runNodeTransformationStage(astTree, NodeTransformationStage.DeadCodeInjection);
}
if (this.options.controlFlowFlattening) {
astTree = this.runNodeTransformationStage(astTree, NodeTransformationStage.ControlFlowFlattening);
}
if (this.options.renameProperties) {
astTree = this.runNodeTransformationStage(astTree, NodeTransformationStage.RenameProperties);
}
astTree = this.runNodeTransformationStage(astTree, NodeTransformationStage.Converting);
astTree = this.runNodeTransformationStage(astTree, NodeTransformationStage.RenameIdentifiers);
astTree = this.runNodeTransformationStage(astTree, NodeTransformationStage.StringArray);
if (this.options.simplify) {
astTree = this.runNodeTransformationStage(astTree, NodeTransformationStage.Simplifying);
}
astTree = this.runNodeTransformationStage(astTree, NodeTransformationStage.Finalizing);
return astTree;
}
/**
* @param {string} sourceCode
* @param {Program} astTree
* @returns {IGeneratorOutput}
*/
private generateCode (sourceCode: string, astTree: ESTree.Program): IGeneratorOutput {
const escodegenParams: escodegen.GenerateOptions = {
...JavaScriptObfuscator.escodegenParams
};
if (this.options.sourceMap) {
escodegenParams.sourceMap = this.options.inputFileName || 'sourceMap';
escodegenParams.sourceContent = sourceCode;
}
const generatorOutput: IGeneratorOutput = escodegen.generate(astTree, {
...escodegenParams,
format: {
compact: this.options.compact
}
});
generatorOutput.map = generatorOutput.map ? generatorOutput.map.toString() : '';
return generatorOutput;
}
/**
* @param {IGeneratorOutput} generatorOutput
* @returns {IObfuscatedCode}
*/
private getObfuscatedCode (generatorOutput: IGeneratorOutput): IObfuscatedCode {
return this.obfuscatedCodeFactory(generatorOutput.code, generatorOutput.map);
}
/**
* @param {string} code
* @param {CodeTransformationStage} codeTransformationStage
* @returns {string}
*/
private runCodeTransformationStage (code: string, codeTransformationStage: CodeTransformationStage): string {
this.logger.info(LoggingMessage.CodeTransformationStage, codeTransformationStage);
return this.codeTransformersRunner.transform(
code,
JavaScriptObfuscator.codeTransformersList,
codeTransformationStage
);
}
/**
* @param {Program} astTree
* @param {NodeTransformationStage} nodeTransformationStage
* @returns {Program}
*/
private runNodeTransformationStage (astTree: ESTree.Program, nodeTransformationStage: NodeTransformationStage): ESTree.Program {
this.logger.info(LoggingMessage.NodeTransformationStage, nodeTransformationStage);
return this.nodeTransformersRunner.transform(
astTree,
JavaScriptObfuscator.nodeTransformersList,
nodeTransformationStage
);
}
}
@@ -0,0 +1,17 @@
import 'reflect-metadata';
import { JavaScriptObfuscatorCLI } from './cli/JavaScriptObfuscatorCLI';
class JavaScriptObfuscatorCLIFacade {
/**
* @param {string[]} argv
*/
public static obfuscate (argv: string[]): void {
const javaScriptObfuscatorCLI: JavaScriptObfuscatorCLI = new JavaScriptObfuscatorCLI(argv);
javaScriptObfuscatorCLI.initialize();
javaScriptObfuscatorCLI.run();
}
}
export { JavaScriptObfuscatorCLIFacade as JavaScriptObfuscatorCLI };
+93
View File
@@ -0,0 +1,93 @@
import 'reflect-metadata';
import { ServiceIdentifiers } from './container/ServiceIdentifiers';
import { TDictionary } from './types/TDictionary';
import { TInputOptions } from './types/options/TInputOptions';
import { TObfuscationResultsObject } from './types/TObfuscationResultsObject';
import { TOptionsPreset } from './types/options/TOptionsPreset';
import { IInversifyContainerFacade } from './interfaces/container/IInversifyContainerFacade';
import { IJavaScriptObfuscator } from './interfaces/IJavaScriptObfsucator';
import { IObfuscatedCode } from './interfaces/source-code/IObfuscatedCode';
import { InversifyContainerFacade } from './container/InversifyContainerFacade';
import { Options } from './options/Options';
import { Utils } from './utils/Utils';
class JavaScriptObfuscatorFacade {
/**
* @type {string | undefined}
*/
public static version: string = process.env.VERSION ?? 'unknown';
/**
* @param {string} sourceCode
* @param {TInputOptions} inputOptions
* @returns {IObfuscatedCode}
*/
public static obfuscate (sourceCode: string, inputOptions: TInputOptions = {}): IObfuscatedCode {
const inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade();
inversifyContainerFacade.load(sourceCode, '', inputOptions);
const javaScriptObfuscator: IJavaScriptObfuscator = inversifyContainerFacade
.get<IJavaScriptObfuscator>(ServiceIdentifiers.IJavaScriptObfuscator);
const obfuscatedCode: IObfuscatedCode = javaScriptObfuscator.obfuscate(sourceCode);
inversifyContainerFacade.unload();
return obfuscatedCode;
}
/**
* @param {TSourceCodesObject} sourceCodesObject
* @param {TInputOptions} inputOptions
* @returns {TObfuscationResultsObject<TSourceCodesObject>}
*/
public static obfuscateMultiple <TSourceCodesObject extends TDictionary<string>> (
sourceCodesObject: TSourceCodesObject,
inputOptions: TInputOptions = {}
): TObfuscationResultsObject<TSourceCodesObject> {
if (typeof sourceCodesObject !== 'object') {
throw new Error('Source codes object should be a plain object');
}
return Object
.keys(sourceCodesObject)
.reduce(
(
acc: TObfuscationResultsObject<TSourceCodesObject>,
sourceCodeIdentifier: keyof TSourceCodesObject,
index: number
) => {
const identifiersPrefix: string = Utils.getIdentifiersPrefixForMultipleSources(
inputOptions.identifiersPrefix,
index
);
const sourceCode: string = sourceCodesObject[sourceCodeIdentifier];
const sourceCodeOptions: TInputOptions = {
...inputOptions,
identifiersPrefix
};
return {
...acc,
[sourceCodeIdentifier]: JavaScriptObfuscatorFacade.obfuscate(sourceCode, sourceCodeOptions)
};
},
<TObfuscationResultsObject<TSourceCodesObject>>{}
);
}
/**
* @param {TOptionsPreset} optionsPreset
* @returns {TInputOptions}
*/
public static getOptionsByPreset (optionsPreset: TOptionsPreset): TInputOptions {
return Options.getOptionsByPreset(optionsPreset);
}
}
export { JavaScriptObfuscatorFacade as JavaScriptObfuscator };
@@ -0,0 +1,170 @@
import { inject, injectable, } from 'inversify';
import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
import * as estraverse from 'estraverse';
import * as ESTree from 'estree';
import { TCalleeDataExtractorFactory } from '../../types/container/calls-graph-analyzer/TCalleeDataExtractorFactory';
import { ICalleeData } from '../../interfaces/analyzers/calls-graph-analyzer/ICalleeData';
import { ICallsGraphAnalyzer } from '../../interfaces/analyzers/calls-graph-analyzer/ICallsGraphAnalyzer';
import { ICallsGraphData } from '../../interfaces/analyzers/calls-graph-analyzer/ICallsGraphData';
import { CalleeDataExtractor } from '../../enums/analyzers/calls-graph-analyzer/CalleeDataExtractor';
import { NodeGuards } from '../../node/NodeGuards';
import { NodeStatementUtils } from '../../node/NodeStatementUtils';
/**
* This class generates a data with a graph of functions calls
*
* For example:
*
* function Foo () {
* var baz = function () {
*
* }
*
* baz();
* }
*
* foo();
*
* Will generate a structure like:
*
* [
* {
* callee: FOO_FUNCTION_NODE
* name: 'Foo',
* trace: [
* {
* callee: BAZ_FUNCTION_NODE,
* name: 'baz,
* trace: []
* }
* ]
* }
* ]
*/
@injectable()
export class CallsGraphAnalyzer implements ICallsGraphAnalyzer {
/**
* @type {CalleeDataExtractor[]}
*/
private static readonly calleeDataExtractorsList: CalleeDataExtractor[] = [
CalleeDataExtractor.FunctionDeclarationCalleeDataExtractor,
CalleeDataExtractor.FunctionExpressionCalleeDataExtractor,
CalleeDataExtractor.ObjectExpressionCalleeDataExtractor
];
/**
* @type {number}
*/
private static readonly limitThresholdActivationLength: number = 25;
/**
* @type {number}
*/
private static readonly limitThreshold: number = 0.002;
/**
* @type {TCalleeDataExtractorFactory}
*/
private readonly calleeDataExtractorFactory: TCalleeDataExtractorFactory;
public constructor (
@inject(ServiceIdentifiers.Factory__ICalleeDataExtractor) calleeDataExtractorFactory: TCalleeDataExtractorFactory
) {
this.calleeDataExtractorFactory = calleeDataExtractorFactory;
}
/**
* @param {number} blockScopeBodyLength
* @returns {number}
*/
public static getLimitIndex (blockScopeBodyLength: number): number {
const lastIndex: number = blockScopeBodyLength - 1;
const limitThresholdActivationIndex: number = CallsGraphAnalyzer.limitThresholdActivationLength - 1;
let limitIndex: number = lastIndex;
if (lastIndex > limitThresholdActivationIndex) {
limitIndex = Math.round(
limitThresholdActivationIndex + (lastIndex * CallsGraphAnalyzer.limitThreshold)
);
if (limitIndex > lastIndex) {
limitIndex = lastIndex;
}
}
return limitIndex;
}
/**
* @param {Program} astTree
* @returns {ICallsGraphData[]}
*/
public analyze (astTree: ESTree.Program): ICallsGraphData[] {
return this.analyzeRecursive(astTree.body);
}
/**
* @param {NodeGuards[]} blockScopeBody
* @returns {ICallsGraphData[]}
*/
private analyzeRecursive (blockScopeBody: ESTree.Node[]): ICallsGraphData[] {
const limitIndex: number = CallsGraphAnalyzer.getLimitIndex(blockScopeBody.length);
const callsGraphData: ICallsGraphData[] = [];
const blockScopeBodyLength: number = blockScopeBody.length;
for (let index: number = 0; index < blockScopeBodyLength; index++) {
if (index > limitIndex) {
break;
}
const blockScopeBodyNode: ESTree.Node = blockScopeBody[index];
estraverse.traverse(blockScopeBodyNode, {
enter: (node: ESTree.Node): estraverse.VisitorOption | void => {
if (!NodeGuards.isCallExpressionNode(node)) {
return;
}
if (blockScopeBodyNode.parentNode !== NodeStatementUtils.getParentNodeWithStatements(node)) {
return estraverse.VisitorOption.Skip;
}
this.analyzeCallExpressionNode(callsGraphData, blockScopeBody, node);
}
});
}
return callsGraphData;
}
/**
* @param {ICallsGraphData[]} callsGraphData
* @param {NodeGuards[]} blockScopeBody
* @param {CallExpression} callExpressionNode
*/
private analyzeCallExpressionNode (
callsGraphData: ICallsGraphData[],
blockScopeBody: ESTree.Node[],
callExpressionNode: ESTree.CallExpression
): void {
CallsGraphAnalyzer.calleeDataExtractorsList.forEach((calleeDataExtractorName: CalleeDataExtractor) => {
const calleeData: ICalleeData | null = this.calleeDataExtractorFactory(calleeDataExtractorName)
.extract(blockScopeBody, callExpressionNode.callee);
if (!calleeData) {
return;
}
callsGraphData.push({
...calleeData,
callsGraph: this.analyzeRecursive(calleeData.callee.body)
});
});
}
}
@@ -0,0 +1,16 @@
import { injectable } from 'inversify';
import * as ESTree from 'estree';
import { ICalleeData } from '../../../interfaces/analyzers/calls-graph-analyzer/ICalleeData';
import { ICalleeDataExtractor } from '../../../interfaces/analyzers/calls-graph-analyzer/ICalleeDataExtractor';
@injectable()
export abstract class AbstractCalleeDataExtractor implements ICalleeDataExtractor {
/**
* @param {Node[]} blockScopeBody
* @param {Node} callee
* @returns {ICalleeData}
*/
public abstract extract (blockScopeBody: ESTree.Node[], callee: ESTree.Node): ICalleeData | null;
}
@@ -0,0 +1,59 @@
import { injectable } from 'inversify';
import * as estraverse from 'estraverse';
import * as ESTree from 'estree';
import { ICalleeData } from '../../../interfaces/analyzers/calls-graph-analyzer/ICalleeData';
import { AbstractCalleeDataExtractor } from './AbstractCalleeDataExtractor';
import { NodeGuards } from '../../../node/NodeGuards';
import { NodeStatementUtils } from '../../../node/NodeStatementUtils';
@injectable()
export class FunctionDeclarationCalleeDataExtractor extends AbstractCalleeDataExtractor {
/**
* @param {NodeGuards[]} blockScopeBody
* @param {Identifier} callee
* @returns {ICalleeData}
*/
public extract (blockScopeBody: ESTree.Node[], callee: ESTree.Identifier): ICalleeData | null {
if (!NodeGuards.isIdentifierNode(callee)) {
return null;
}
const calleeBlockStatement: ESTree.BlockStatement | null = this.getCalleeBlockStatement(
NodeStatementUtils.getParentNodeWithStatements(blockScopeBody[0]),
callee.name
);
if (!calleeBlockStatement) {
return null;
}
return {
callee: calleeBlockStatement,
name: callee.name
};
}
/**
* @param {NodeGuards} targetNode
* @param {string} name
* @returns {BlockStatement}
*/
private getCalleeBlockStatement (targetNode: ESTree.Node, name: string): ESTree.BlockStatement | null {
let calleeBlockStatement: ESTree.BlockStatement | null = null;
estraverse.traverse(targetNode, {
enter: (node: ESTree.Node): estraverse.VisitorOption | void => {
if (NodeGuards.isFunctionDeclarationNode(node) && node.id.name === name) {
calleeBlockStatement = node.body;
return estraverse.VisitorOption.Break;
}
}
});
return calleeBlockStatement;
}
}
@@ -0,0 +1,70 @@
import { injectable } from 'inversify';
import * as estraverse from 'estraverse';
import * as ESTree from 'estree';
import { ICalleeData } from '../../../interfaces/analyzers/calls-graph-analyzer/ICalleeData';
import { AbstractCalleeDataExtractor } from './AbstractCalleeDataExtractor';
import { NodeGuards } from '../../../node/NodeGuards';
import { NodeStatementUtils } from '../../../node/NodeStatementUtils';
@injectable()
export class FunctionExpressionCalleeDataExtractor extends AbstractCalleeDataExtractor {
/**
* @param {NodeGuards[]} blockScopeBody
* @param {Identifier} callee
* @returns {ICalleeData}
*/
public extract (blockScopeBody: ESTree.Node[], callee: ESTree.Identifier | ESTree.FunctionExpression): ICalleeData | null {
let calleeName: string | null = null;
let calleeBlockStatement: ESTree.BlockStatement | null = null;
if (NodeGuards.isIdentifierNode(callee)) {
calleeName = callee.name;
calleeBlockStatement = this.getCalleeBlockStatement(
NodeStatementUtils.getParentNodeWithStatements(blockScopeBody[0]),
callee.name
);
} else if (NodeGuards.isFunctionExpressionNode(callee)) {
calleeName = null;
calleeBlockStatement = callee.body;
}
if (!calleeBlockStatement) {
return null;
}
return {
callee: calleeBlockStatement,
name: calleeName
};
}
/**
* @param {NodeGuards} targetNode
* @param {string} name
* @returns {BlockStatement}
*/
private getCalleeBlockStatement (targetNode: ESTree.Node, name: string): ESTree.BlockStatement | null {
let calleeBlockStatement: ESTree.BlockStatement | null = null;
estraverse.traverse(targetNode, {
enter: (node: ESTree.Node, parentNode: ESTree.Node | null): estraverse.VisitorOption | void => {
if (
NodeGuards.isFunctionExpressionNode(node) &&
parentNode &&
NodeGuards.isVariableDeclaratorNode(parentNode) &&
NodeGuards.isIdentifierNode(parentNode.id) &&
parentNode.id.name === name
) {
calleeBlockStatement = node.body;
return estraverse.VisitorOption.Break;
}
}
});
return calleeBlockStatement;
}
}
@@ -0,0 +1,177 @@
import { injectable } from 'inversify';
import * as estraverse from 'estraverse';
import * as ESTree from 'estree';
import { TObjectMembersCallsChain } from '../../../types/analyzers/calls-graph-analyzer/TObjectMembersCallsChain';
import { ICalleeData } from '../../../interfaces/analyzers/calls-graph-analyzer/ICalleeData';
import { AbstractCalleeDataExtractor } from './AbstractCalleeDataExtractor';
import { NodeGuards } from '../../../node/NodeGuards';
import { NodeStatementUtils } from '../../../node/NodeStatementUtils';
@injectable()
export class ObjectExpressionCalleeDataExtractor extends AbstractCalleeDataExtractor {
/**
* @param {Property} propertyNode
* @param {string | number} nextItemInCallsChain
* @returns {boolean}
*/
private static isValidTargetPropertyNode (propertyNode: ESTree.Property, nextItemInCallsChain: string | number): boolean {
if (!propertyNode.key) {
return false;
}
const isTargetPropertyNodeWithIdentifierKey: boolean =
NodeGuards.isIdentifierNode(propertyNode.key) && propertyNode.key.name === nextItemInCallsChain;
const isTargetPropertyNodeWithLiteralKey: boolean =
NodeGuards.isLiteralNode(propertyNode.key) &&
Boolean(propertyNode.key.value) &&
propertyNode.key.value === nextItemInCallsChain;
return isTargetPropertyNodeWithIdentifierKey || isTargetPropertyNodeWithLiteralKey;
}
/**
* @param {NodeGuards[]} blockScopeBody
* @param {MemberExpression} callee
* @returns {ICalleeData}
*/
public extract (blockScopeBody: ESTree.Node[], callee: ESTree.MemberExpression): ICalleeData | null {
if (!NodeGuards.isMemberExpressionNode(callee)) {
return null;
}
const objectMembersCallsChain: TObjectMembersCallsChain = this.createObjectMembersCallsChain([], callee);
if (!objectMembersCallsChain.length) {
return null;
}
const functionExpressionName: string | number | null = objectMembersCallsChain[objectMembersCallsChain.length - 1];
const calleeBlockStatement: ESTree.BlockStatement | null = this.getCalleeBlockStatement(
NodeStatementUtils.getParentNodeWithStatements(blockScopeBody[0]),
objectMembersCallsChain
);
if (!calleeBlockStatement) {
return null;
}
return {
callee: calleeBlockStatement,
name: functionExpressionName
};
}
/**
* Creates array with MemberExpression calls chain.
*
* Example: object.foo.bar(); // ['object', 'foo', 'bar']
*
* @param {TObjectMembersCallsChain} currentChain
* @param {MemberExpression} memberExpression
* @returns {TObjectMembersCallsChain}
*/
private createObjectMembersCallsChain (
currentChain: TObjectMembersCallsChain,
memberExpression: ESTree.MemberExpression
): TObjectMembersCallsChain {
// first step: processing memberExpression `property` property
if (NodeGuards.isIdentifierNode(memberExpression.property) && !memberExpression.computed) {
currentChain.unshift(memberExpression.property.name);
} else if (
NodeGuards.isLiteralNode(memberExpression.property) &&
(
typeof memberExpression.property.value === 'string' ||
typeof memberExpression.property.value === 'number'
)
) {
currentChain.unshift(memberExpression.property.value);
} else {
return currentChain;
}
// second step: processing memberExpression `object` property
if (NodeGuards.isMemberExpressionNode(memberExpression.object)) {
return this.createObjectMembersCallsChain(currentChain, memberExpression.object);
} else if (NodeGuards.isIdentifierNode(memberExpression.object)) {
currentChain.unshift(memberExpression.object.name);
}
return currentChain;
}
/**
* @param {NodeGuards} targetNode
* @param {TObjectMembersCallsChain} objectMembersCallsChain
* @returns {BlockStatement}
*/
private getCalleeBlockStatement (
targetNode: ESTree.Node,
objectMembersCallsChain: TObjectMembersCallsChain
): ESTree.BlockStatement | null {
const objectName: string | number | undefined = objectMembersCallsChain.shift();
if (!objectName) {
return null;
}
let calleeBlockStatement: ESTree.BlockStatement | null = null;
estraverse.traverse(targetNode, {
enter: (node: ESTree.Node): estraverse.VisitorOption | void => {
if (
NodeGuards.isVariableDeclaratorNode(node) &&
NodeGuards.isIdentifierNode(node.id) &&
node.init &&
NodeGuards.isObjectExpressionNode(node.init) &&
node.id.name === objectName
) {
calleeBlockStatement = this.findCalleeBlockStatement(node.init.properties, objectMembersCallsChain);
return estraverse.VisitorOption.Break;
}
}
});
return calleeBlockStatement;
}
/**
* @param {Property[]} objectExpressionProperties
* @param {TObjectMembersCallsChain} objectMembersCallsChain
* @returns {BlockStatement}
*/
private findCalleeBlockStatement (
objectExpressionProperties: (ESTree.Property | ESTree.SpreadElement)[],
objectMembersCallsChain: TObjectMembersCallsChain
): ESTree.BlockStatement | null {
const nextItemInCallsChain: string | number | undefined = objectMembersCallsChain.shift();
if (!nextItemInCallsChain) {
return null;
}
for (const propertyNode of objectExpressionProperties) {
if (!NodeGuards.isPropertyNode(propertyNode)) {
continue;
}
if (!ObjectExpressionCalleeDataExtractor.isValidTargetPropertyNode(propertyNode, nextItemInCallsChain)) {
continue;
}
if (NodeGuards.isObjectExpressionNode(propertyNode.value)) {
return this.findCalleeBlockStatement(propertyNode.value.properties, objectMembersCallsChain);
}
if (NodeGuards.isFunctionExpressionNode(propertyNode.value)) {
return propertyNode.value.body;
}
}
return null;
}
}
@@ -0,0 +1,130 @@
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';
import { NumberUtils } from '../../utils/NumberUtils';
/**
* Based on https://gist.github.com/da411d/0e59f79dcf4603cdabf0024a10eeb6fe
*/
@injectable()
export class NumberNumericalExpressionAnalyzer implements INumberNumericalExpressionAnalyzer {
/**
* @type {number}
*/
private static readonly additionalParts: number = 3;
/**
* @type {Map<number, number[]>}
*/
private readonly numberFactorsMap: Map<number, number[]> = new Map();
/**
* @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');
}
if (NumberUtils.isUnsafeNumber(number)) {
return [number];
}
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 upperNumberLimit: number = Math.min(Math.abs(number * 2), Number.MAX_SAFE_INTEGER);
const from: number = Math.min(-10000, -upperNumberLimit);
const to: number = Math.max(10000, upperNumberLimit);
let temporarySum = 0;
for (let i = 0; i < NumberNumericalExpressionAnalyzer.additionalParts; i++) {
if (i < NumberNumericalExpressionAnalyzer.additionalParts - 1) {
// trailing parts
let addition: number = this.randomGenerator.getRandomInteger(from, to);
const isUnsafeCombination: boolean = NumberUtils.isUnsafeNumber(temporarySum + addition);
// we have to flip sign if total expression sum overflows over safe integer limits
if (isUnsafeCombination) {
addition = -addition;
}
additionParts.push(addition);
temporarySum += addition;
} else {
const combination: number = number - temporarySum;
const isUnsafeCombination: boolean = NumberUtils.isUnsafeNumber(combination);
// last part
if (isUnsafeCombination) {
additionParts.push(0 - temporarySum);
additionParts.push(number);
} else {
additionParts.push(combination);
}
}
}
return additionParts;
}
/**
* @param {number} number
* @returns {number | number[]}
*/
private mixWithMultiplyParts (number: number): number | number[] {
const shouldMixWithMultiplyParts: boolean = this.randomGenerator.getMathRandom() > 0.5;
if (!shouldMixWithMultiplyParts || number === 0) {
return number;
}
let factors: number[] | null = this.numberFactorsMap.get(number) ?? null;
if (!factors) {
factors = NumberUtils.getFactors(number);
this.numberFactorsMap.set(number, factors);
}
if (!factors.length) {
return number;
}
const factor: number = factors[this.randomGenerator.getRandomInteger(0, factors.length - 1)];
return [factor, number / factor];
}
}
@@ -0,0 +1,61 @@
import { inject, injectable, } from 'inversify';
import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
import * as estraverse from 'estraverse';
import * as ESTree from 'estree';
import { IArrayUtils } from '../../interfaces/utils/IArrayUtils';
import { IPrevailingKindOfVariablesAnalyzer } from '../../interfaces/analyzers/calls-graph-analyzer/IPrevailingKindOfVariablesAnalyzer';
import { NodeGuards } from '../../node/NodeGuards';
@injectable()
export class PrevailingKindOfVariablesAnalyzer implements IPrevailingKindOfVariablesAnalyzer {
/**
* @type {ESTree.VariableDeclaration['kind']}
*/
private static readonly defaultKindOfVariables: ESTree.VariableDeclaration['kind'] = 'var';
/**
* @type {IArrayUtils}
*/
private readonly arrayUtils: IArrayUtils;
/**
* @type {ESTree.VariableDeclaration['kind']}
*/
private prevailingKindOfVariables: ESTree.VariableDeclaration['kind'] = PrevailingKindOfVariablesAnalyzer.defaultKindOfVariables;
public constructor (
@inject(ServiceIdentifiers.IArrayUtils) arrayUtils: IArrayUtils
) {
this.arrayUtils = arrayUtils;
}
/**
* @param {Program} astTree
*/
public analyze (astTree: ESTree.Program): void {
const variableKinds: ESTree.VariableDeclaration['kind'][] = [];
estraverse.traverse(astTree, {
enter: (node: ESTree.Node): estraverse.VisitorOption | void => {
if (!NodeGuards.isVariableDeclarationNode(node)) {
return;
}
variableKinds.push(node.kind);
}
});
this.prevailingKindOfVariables = this.arrayUtils.findMostOccurringElement(variableKinds)
?? PrevailingKindOfVariablesAnalyzer.defaultKindOfVariables;
}
/**
* @returns {VariableDeclaration["kind"]}
*/
public getPrevailingKind (): ESTree.VariableDeclaration['kind'] {
return this.prevailingKindOfVariables;
}
}
@@ -0,0 +1,152 @@
import { injectable, } from 'inversify';
import * as eslintScope from 'eslint-scope';
import * as estraverse from 'estraverse';
import * as ESTree from 'estree';
import { IScopeAnalyzer } from '../../interfaces/analyzers/scope-analyzer/IScopeAnalyzer';
import { ecmaVersion } from '../../constants/EcmaVersion';
import { NodeGuards } from '../../node/NodeGuards';
@injectable()
export class ScopeAnalyzer implements IScopeAnalyzer {
/**
* @type {eslintScope.AnalysisOptions}
*/
private static readonly eslintScopeOptions: eslintScope.AnalysisOptions = {
ecmaVersion,
optimistic: true
};
/**
* @type {acorn.Options['sourceType'][]}
*/
private static readonly sourceTypes: acorn.Options['sourceType'][] = [
'script',
'module'
];
/**
* @type {number}
*/
private static readonly emptyRangeValue: number = 0;
/**
* @type {eslintScope.ScopeManager | null}
*/
private scopeManager: eslintScope.ScopeManager | null = null;
/**
* `eslint-scope` reads `ranges` property of a nodes
* Should attach that property to the some custom nodes
*
* @param {Node} astTree
*/
private static attachMissingRanges (astTree: ESTree.Node): void {
estraverse.replace(astTree, {
enter: (node: ESTree.Node, parentNode: ESTree.Node | null): ESTree.Node => {
if (!node.range) {
node.range = [
parentNode?.range?.[0] ?? ScopeAnalyzer.emptyRangeValue,
parentNode?.range?.[1] ?? ScopeAnalyzer.emptyRangeValue
];
}
return node;
}
});
}
/**
* @param {Node} node
* @returns {boolean}
*/
private static isRootNode (node: ESTree.Node): boolean {
return NodeGuards.isProgramNode(node) || node.parentNode === node;
}
/**
* @param {Program} astTree
*/
public analyze (astTree: ESTree.Node): void {
const sourceTypeLength: number = ScopeAnalyzer.sourceTypes.length;
ScopeAnalyzer.attachMissingRanges(astTree);
for (let i: number = 0; i < sourceTypeLength; i++) {
try {
this.scopeManager = eslintScope.analyze(astTree, {
...ScopeAnalyzer.eslintScopeOptions,
sourceType: ScopeAnalyzer.sourceTypes[i]
});
return;
} catch (error) {
if (i < sourceTypeLength - 1) {
continue;
}
throw new Error(error);
}
}
throw new Error('Scope analyzing error');
}
/**
* @param {Node} node
* @returns {Scope}
*/
public acquireScope (node: ESTree.Node): eslintScope.Scope {
if (!this.scopeManager) {
throw new Error('Scope manager is not defined');
}
const scope: eslintScope.Scope | null = this.scopeManager.acquire(
node,
ScopeAnalyzer.isRootNode(node)
);
if (!scope) {
throw new Error('Cannot acquire scope for node');
}
this.sanitizeScopes(scope);
return scope;
}
/**
* @param {Scope} scope
*/
private sanitizeScopes (scope: eslintScope.Scope): void {
scope.childScopes.forEach((childScope: eslintScope.Scope) => {
// fix of class scopes
// trying to move class scope references to the parent scope
if (childScope.type === 'class' && childScope.upper) {
if (!childScope.variables.length) {
return;
}
// class name variable is always first
const classNameVariable: eslintScope.Variable = childScope.variables[0];
const upperVariable: eslintScope.Variable | undefined = childScope.upper.variables
.find((variable: eslintScope.Variable) => {
const isValidClassNameVariable: boolean = classNameVariable.defs
.some((definition: eslintScope.Definition) => definition.type === 'ClassName');
return isValidClassNameVariable && variable.name === classNameVariable.name;
});
upperVariable?.references.push(...childScope.variables[0].references);
}
});
for (const childScope of scope.childScopes) {
this.sanitizeScopes(childScope);
}
}
}
@@ -0,0 +1,134 @@
import { inject, injectable, } from 'inversify';
import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
import * as estraverse from 'estraverse';
import * as ESTree from 'estree';
import { IOptions } from '../../interfaces/options/IOptions';
import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
import { IStringArrayStorage } from '../../interfaces/storages/string-array-transformers/IStringArrayStorage';
import { IStringArrayStorageAnalyzer } from '../../interfaces/analyzers/string-array-storage-analyzer/IStringArrayStorageAnalyzer';
import { IStringArrayStorageItemData } from '../../interfaces/storages/string-array-transformers/IStringArrayStorageItem';
import { NodeGuards } from '../../node/NodeGuards';
import { NodeLiteralUtils } from '../../node/NodeLiteralUtils';
import { NodeMetadata } from '../../node/NodeMetadata';
/**
* Adds values of literal nodes to the string array storage
*/
@injectable()
export class StringArrayStorageAnalyzer implements IStringArrayStorageAnalyzer {
/**
* @type {number}
*/
private static readonly minimumLengthForStringArray: number = 3;
/**
* @type {IOptions}
*/
private readonly options: IOptions;
/**
* @type {randomGenerator}
*/
private readonly randomGenerator: IRandomGenerator;
/**
* @type {IStringArrayStorage}
*/
private readonly stringArrayStorage: IStringArrayStorage;
/**
* @type {Map<ESTree.Literal, IStringArrayStorageItemData>}
*/
private readonly stringArrayStorageData: Map<ESTree.Literal, IStringArrayStorageItemData> = new Map();
/**
* @param {IStringArrayStorage} stringArrayStorage
* @param {IRandomGenerator} randomGenerator
* @param {IOptions} options
*/
public constructor (
@inject(ServiceIdentifiers.IStringArrayStorage) stringArrayStorage: IStringArrayStorage,
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
@inject(ServiceIdentifiers.IOptions) options: IOptions,
) {
this.stringArrayStorage = stringArrayStorage;
this.randomGenerator = randomGenerator;
this.options = options;
}
/**
* @param {Program} astTree
*/
public analyze (astTree: ESTree.Program): void {
if (!this.options.stringArray) {
return;
}
estraverse.traverse(astTree, {
enter: (node: ESTree.Node, parentNode: ESTree.Node | null): estraverse.VisitorOption | void => {
if (!parentNode) {
return;
}
if (NodeMetadata.isIgnoredNode(node)) {
return estraverse.VisitorOption.Skip;
}
if (!NodeGuards.isLiteralNode(node)) {
return;
}
this.analyzeLiteralNode(node, parentNode);
}
});
}
/**
* @param {Literal} literalNode
* @returns {IStringArrayStorageItemData | undefined}
*/
public getItemDataForLiteralNode (literalNode: ESTree.Literal): IStringArrayStorageItemData | undefined {
return this.stringArrayStorageData.get(literalNode);
}
/**
* @param {Literal} literalNode
* @param {Node} parentNode
*/
private analyzeLiteralNode (literalNode: ESTree.Literal, parentNode: ESTree.Node): void {
if (!NodeLiteralUtils.isStringLiteralNode(literalNode)) {
return;
}
if (NodeLiteralUtils.isProhibitedLiteralNode(literalNode, parentNode)) {
return;
}
if (!this.shouldAddValueToStringArray(literalNode)) {
return;
}
this.stringArrayStorageData.set(
literalNode,
this.stringArrayStorage.getOrThrow(literalNode.value)
);
}
/**
* @param {(SimpleLiteral & {value: string})} literalNode
* @returns {boolean}
*/
private shouldAddValueToStringArray (literalNode: ESTree.Literal & {value: string}): boolean {
const isForceTransformNode: boolean = NodeMetadata.isForceTransformNode(literalNode);
if (isForceTransformNode) {
return true;
}
return literalNode.value.length >= StringArrayStorageAnalyzer.minimumLengthForStringArray
&& this.randomGenerator.getMathRandom() <= this.options.stringArrayThreshold;
}
}
+521
View File
@@ -0,0 +1,521 @@
/* eslint-disable max-lines */
import * as commander from 'commander';
import * as path from 'path';
import { TInputCLIOptions } from '../types/options/TInputCLIOptions';
import { TInputOptions } from '../types/options/TInputOptions';
import { IFileData } from '../interfaces/cli/IFileData';
import { IInitializable } from '../interfaces/IInitializable';
import { IObfuscatedCode } from '../interfaces/source-code/IObfuscatedCode';
import { initializable } from '../decorators/Initializable';
import { IdentifierNamesGenerator } from '../enums/generators/identifier-names-generators/IdentifierNamesGenerator';
import { LoggingPrefix } from '../enums/logger/LoggingPrefix';
import { ObfuscationTarget } from '../enums/ObfuscationTarget';
import { OptionsPreset } from '../enums/options/presets/OptionsPreset';
import { SourceMapMode } from '../enums/source-map/SourceMapMode';
import { StringArrayEncoding } from '../enums/node-transformers/string-array-transformers/StringArrayEncoding';
import { StringArrayWrappersType } from '../enums/node-transformers/string-array-transformers/StringArrayWrappersType';
import { DEFAULT_PRESET } from '../options/presets/Default';
import { ArraySanitizer } from './sanitizers/ArraySanitizer';
import { BooleanSanitizer } from './sanitizers/BooleanSanitizer';
import { CLIUtils } from './utils/CLIUtils';
import { JavaScriptObfuscator } from '../JavaScriptObfuscatorFacade';
import { Logger } from '../logger/Logger';
import { ObfuscatedCodeWriter } from './utils/ObfuscatedCodeWriter';
import { SourceCodeReader } from './utils/SourceCodeReader';
import { Utils } from '../utils/Utils';
import { StringArrayIndexesType } from '../enums/node-transformers/string-array-transformers/StringArrayIndexesType';
export class JavaScriptObfuscatorCLI implements IInitializable {
/**
* @type {string[]}
*/
public static readonly availableInputExtensions: string[] = [
'.js'
];
/**
* @type {BufferEncoding}
*/
public static readonly encoding: BufferEncoding = 'utf8';
/**
* @type {string}
*/
public static readonly obfuscatedFilePrefix: string = '-obfuscated';
/**
* @type {commander.CommanderStatic}
*/
@initializable()
private commands!: commander.CommanderStatic;
/**
* @type {TInputCLIOptions}
*/
@initializable()
private inputCLIOptions!: TInputCLIOptions;
/**
* @type {string}
*/
@initializable()
private inputPath!: string;
/**
* @type {SourceCodeReader}
*/
@initializable()
private sourceCodeReader!: SourceCodeReader;
/**
* @type {ObfuscatedCodeWriter}
*/
@initializable()
private obfuscatedCodeWriter!: ObfuscatedCodeWriter;
/**
* @type {string[]}
*/
private readonly arguments: string[];
/**
* @type {string[]}
*/
private readonly rawArguments: string[];
/**
* @param {string[]} argv
*/
public constructor (argv: string[]) {
this.rawArguments = argv;
this.arguments = argv.slice(2);
}
/**
* @param {TInputCLIOptions} inputOptions
* @returns {TInputOptions}
*/
private static buildOptions (inputOptions: TInputCLIOptions): TInputOptions {
const inputCLIOptions: TInputOptions = JavaScriptObfuscatorCLI.filterOptions(inputOptions);
const configFilePath: string | undefined = inputOptions.config;
const configFileLocation: string = configFilePath ? path.resolve(configFilePath, '.') : '';
const configFileOptions: TInputOptions = configFileLocation ? CLIUtils.getUserConfig(configFileLocation) : {};
return {
...DEFAULT_PRESET,
...configFileOptions,
...inputCLIOptions
};
}
/**
* @param {TObject} options
* @returns {TInputOptions}
*/
private static filterOptions (options: TInputCLIOptions): TInputOptions {
const filteredOptions: TInputOptions = {};
Object
.keys(options)
.forEach((option: keyof TInputCLIOptions) => {
if (options[option] === undefined) {
return;
}
filteredOptions[option] = options[option];
});
return filteredOptions;
}
public initialize (): void {
this.inputPath = path.normalize(this.arguments[0] || '');
this.commands = <commander.CommanderStatic>(new commander.Command());
this.configureCommands();
this.configureHelp();
this.inputCLIOptions = JavaScriptObfuscatorCLI.buildOptions(this.commands.opts());
this.sourceCodeReader = new SourceCodeReader(
this.inputPath,
this.inputCLIOptions
);
this.obfuscatedCodeWriter = new ObfuscatedCodeWriter(
this.inputPath,
this.inputCLIOptions
);
}
public run (): void {
const canShowHelp: boolean = !this.arguments.length || this.arguments.includes('--help');
if (canShowHelp) {
this.commands.outputHelp();
return;
}
const sourceCodeData: IFileData[] = this.sourceCodeReader.readSourceCode();
this.processSourceCodeData(sourceCodeData);
}
private configureCommands (): void {
this.commands
.usage('<inputPath> [options]')
.version(
Utils.buildVersionMessage(process.env.VERSION, process.env.BUILD_TIMESTAMP),
'-v, --version'
)
.option(
'-o, --output <path>',
'Output path for obfuscated code'
)
.option(
'--compact <boolean>',
'Disable one line output code compacting',
BooleanSanitizer
)
.option(
'--config <boolean>',
'Name of js / json config file'
)
.option(
'--control-flow-flattening <boolean>',
'Enables control flow flattening',
BooleanSanitizer
)
.option(
'--control-flow-flattening-threshold <number>',
'The probability that the control flow flattening transformation will be applied to the node',
parseFloat
)
.option(
'--dead-code-injection <boolean>',
'Enables dead code injection',
BooleanSanitizer
)
.option(
'--dead-code-injection-threshold <number>',
'The probability that the dead code injection transformation will be applied to the node',
parseFloat
)
.option(
'--debug-protection <boolean>',
'Disable browser Debug panel (can cause DevTools enabled browser freeze)',
BooleanSanitizer
)
.option(
'--debug-protection-interval <boolean>',
'Disable browser Debug panel even after page was loaded (can cause DevTools enabled browser freeze)',
BooleanSanitizer
)
.option(
'--disable-console-output <boolean>',
'Allow console.log, console.info, console.error and console.warn messages output into browser console',
BooleanSanitizer
)
.option(
'--domain-lock <list> (comma separated, without whitespaces)',
'Allows to run the obfuscated source code only on specific domains and/or sub-domains (comma separated)',
ArraySanitizer
)
.option(
'--exclude <list> (comma separated, without whitespaces)',
'A filename or glob which indicates files to exclude from obfuscation',
ArraySanitizer
)
.option(
'--force-transform-strings <list> (comma separated, without whitespaces)',
'Enables force transformation of string literals, which being matched by passed RegExp patterns (comma separated)',
ArraySanitizer
)
.option(
'--identifier-names-generator <string>',
'Sets identifier names generator. ' +
`Values: ${CLIUtils.stringifyOptionAvailableValues(IdentifierNamesGenerator)}. ` +
`Default: ${IdentifierNamesGenerator.HexadecimalIdentifierNamesGenerator}`
)
.option(
'--identifiers-prefix <string>',
'Sets prefix for all global identifiers'
)
.option(
'--identifiers-dictionary <list> (comma separated, without whitespaces)',
'Identifiers dictionary (comma separated) for `--identifier-names-generator dictionary` option',
ArraySanitizer
)
.option(
'--ignore-require-imports <boolean>', 'Prevents obfuscation of `require` imports',
BooleanSanitizer
)
.option(
'--log <boolean>', 'Enables logging of the information to the console',
BooleanSanitizer
)
.option(
'--numbers-to-expressions <boolean>', 'Enables numbers conversion to expressions',
BooleanSanitizer
)
.option(
'--options-preset <string>',
'Allows to set options preset. ' +
`Values: ${CLIUtils.stringifyOptionAvailableValues(OptionsPreset)}. ` +
`Default: ${OptionsPreset.Default}`
)
.option(
'--reserved-names <list> (comma separated, without whitespaces)',
'Disables obfuscation and generation of identifiers, which being matched by passed RegExp patterns (comma separated)',
ArraySanitizer
)
.option(
'--reserved-strings <list> (comma separated, without whitespaces)',
'Disables transformation of string literals, which being matched by passed RegExp patterns (comma separated)',
ArraySanitizer
)
.option(
'--rename-globals <boolean>', 'Allows to enable obfuscation of global variable and function names with declaration',
BooleanSanitizer
)
.option(
'--rename-properties <boolean>', 'UNSAFE: Enables renaming of property names. This probably WILL break your code',
BooleanSanitizer
)
.option(
'--rotate-string-array <boolean>', 'Enable rotation of string array values during obfuscation',
BooleanSanitizer
)
.option(
'--seed <string|number>',
'Sets seed for random generator. This is useful for creating repeatable results.',
parseFloat
)
.option(
'--self-defending <boolean>',
'Disables self-defending for obfuscated code',
BooleanSanitizer
)
.option(
'--shuffle-string-array <boolean>', 'Randomly shuffles string array items',
BooleanSanitizer
)
.option(
'--simplify <boolean>', 'Enables additional code obfuscation through simplification',
BooleanSanitizer
)
.option(
'--source-map <boolean>',
'Enables source map generation',
BooleanSanitizer
)
.option(
'--source-map-base-url <string>',
'Sets base url to the source map import url when `--source-map-mode=separate`'
)
.option(
'--source-map-file-name <string>',
'Sets file name for output source map when `--source-map-mode=separate`'
)
.option(
'--source-map-mode <string>',
'Specify source map output mode. ' +
`Values: ${CLIUtils.stringifyOptionAvailableValues(SourceMapMode)}. ` +
`Default: ${SourceMapMode.Separate}`
)
.option(
'--split-strings <boolean>',
'Splits literal strings into chunks with length of `splitStringsChunkLength` option value',
BooleanSanitizer
)
.option(
'--split-strings-chunk-length <number>',
'Sets chunk length of `splitStrings` option',
parseFloat
)
.option(
'--string-array <boolean>',
'Disables gathering of all literal strings into an array and replacing every literal string with an array call',
BooleanSanitizer
)
.option(
'--string-array-encoding <list> (comma separated, without whitespaces)',
'Encodes each string in strings array using base64 or rc4 (this option can slow down your code speed). ' +
`Values: ${CLIUtils.stringifyOptionAvailableValues(StringArrayEncoding)}. ` +
`Default: ${StringArrayEncoding.None}`,
ArraySanitizer
)
.option(
'--string-array-indexes-type <list> (comma separated, without whitespaces)',
'Encodes each string in strings array using base64 or rc4 (this option can slow down your code speed). ' +
`Values: ${CLIUtils.stringifyOptionAvailableValues(StringArrayIndexesType)}. ` +
`Default: ${StringArrayIndexesType.HexadecimalNumber}`,
ArraySanitizer
)
.option(
'--string-array-index-shift <boolean>',
'Enables additional index shift for all string array calls',
BooleanSanitizer
)
.option(
'--string-array-wrappers-count <number>',
'Sets the count of wrappers for the string array inside each root or function scope',
parseInt
)
.option(
'--string-array-wrappers-chained-calls <boolean>',
'Enables the chained calls between string array wrappers',
BooleanSanitizer
)
.option(
'--string-array-wrappers-parameters-max-count <number>',
'Allows to control the maximum number of string array wrappers parameters',
parseInt
)
.option(
'--string-array-wrappers-type <string>',
'Allows to select a type of the wrappers that are appending by the `--string-array-wrappers-count` option. ' +
`Values: ${CLIUtils.stringifyOptionAvailableValues(StringArrayWrappersType)}. ` +
`Default: ${StringArrayWrappersType.Variable}`
)
.option(
'--string-array-threshold <number>',
'The probability that the literal string will be inserted into stringArray (Default: 0.8, Min: 0, Max: 1)',
parseFloat
)
.option(
'--target <string>',
'Allows to set target environment for obfuscated code. ' +
`Values: ${CLIUtils.stringifyOptionAvailableValues(ObfuscationTarget)}. ` +
`Default: ${ObfuscationTarget.Browser}`
)
.option(
'--transform-object-keys <boolean>',
'Enables transformation of object keys',
BooleanSanitizer
)
.option(
'--unicode-escape-sequence <boolean>',
'Allows to enable/disable string conversion to unicode escape sequence',
BooleanSanitizer
)
.parse(this.rawArguments);
}
private configureHelp (): void {
this.commands.on('--help', () => {
console.log(' Examples:\n');
console.log(' %> javascript-obfuscator input_file_name.js --compact true --self-defending false');
console.log(' %> javascript-obfuscator input_file_name.js --output output_file_name.js --compact true --self-defending false');
console.log(' %> javascript-obfuscator input_directory_name --compact true --self-defending false');
console.log('');
});
}
/**
* @param {IFileData[]} sourceCodeData
*/
private processSourceCodeData (sourceCodeData: IFileData[]): void {
sourceCodeData.forEach(({ filePath, content }: IFileData, index: number) => {
const outputCodePath: string = this.obfuscatedCodeWriter.getOutputCodePath(filePath);
try {
Logger.log(
Logger.colorInfo,
LoggingPrefix.CLI,
`Obfuscating file: ${filePath}...`
);
this.processSourceCode(content, filePath, outputCodePath, index);
} catch (error) {
Logger.log(
Logger.colorInfo,
LoggingPrefix.CLI,
`Error in file: ${filePath}...`
);
throw error;
}
});
}
/**
* @param {string} sourceCode
* @param {string} inputCodePath
* @param {string} outputCodePath
* @param {number | null} sourceCodeIndex
*/
private processSourceCode (
sourceCode: string,
inputCodePath: string,
outputCodePath: string,
sourceCodeIndex: number | null
): void {
const options: TInputOptions = {
...this.inputCLIOptions,
inputFileName: path.basename(inputCodePath),
...sourceCodeIndex !== null && {
identifiersPrefix: Utils.getIdentifiersPrefixForMultipleSources(
this.inputCLIOptions.identifiersPrefix,
sourceCodeIndex
)
}
};
if (options.sourceMap) {
this.processSourceCodeWithSourceMap(sourceCode, outputCodePath, options);
} else {
this.processSourceCodeWithoutSourceMap(sourceCode, outputCodePath, options);
}
}
/**
* @param {string} sourceCode
* @param {string} outputCodePath
* @param {TInputOptions} options
*/
private processSourceCodeWithoutSourceMap (
sourceCode: string,
outputCodePath: string,
options: TInputOptions
): void {
const obfuscatedCode: string = JavaScriptObfuscator.obfuscate(sourceCode, options).getObfuscatedCode();
this.obfuscatedCodeWriter.writeFile(outputCodePath, obfuscatedCode);
}
/**
* @param {string} sourceCode
* @param {string} outputCodePath
* @param {TInputOptions} options
*/
private processSourceCodeWithSourceMap (
sourceCode: string,
outputCodePath: string,
options: TInputOptions
): void {
const outputSourceMapPath: string = this.obfuscatedCodeWriter.getOutputSourceMapPath(
outputCodePath,
options.sourceMapFileName ?? ''
);
options = {
...options,
sourceMapFileName: path.basename(outputSourceMapPath)
};
const obfuscatedCode: IObfuscatedCode = JavaScriptObfuscator.obfuscate(sourceCode, options);
this.obfuscatedCodeWriter.writeFile(outputCodePath, obfuscatedCode.getObfuscatedCode());
if (options.sourceMapMode === SourceMapMode.Separate && obfuscatedCode.getSourceMap()) {
this.obfuscatedCodeWriter.writeFile(outputSourceMapPath, obfuscatedCode.getSourceMap());
}
}
}
@@ -0,0 +1,13 @@
import { TCLISanitizer } from '../../types/cli/TCLISanitizer';
/**
* @param {string} value
* @returns {string[]}
*/
export const ArraySanitizer: TCLISanitizer <string[]> = (value: string): string[] => {
if (value.endsWith(',')) {
throw new SyntaxError('Multiple <list> values should be wrapped inside quotes: --option-name \'value1\',\'value2\'');
}
return value.split(',').map((string: string) => string.trim());
};
@@ -0,0 +1,9 @@
import { TCLISanitizer } from '../../types/cli/TCLISanitizer';
/**
* @param {string} value
* @returns {boolean}
*/
export const BooleanSanitizer: TCLISanitizer <boolean> = (value: string): boolean => {
return value === 'true' || value === '1';
};
+50
View File
@@ -0,0 +1,50 @@
import * as path from 'path';
import { TDictionary } from '../../types/TDictionary';
import { StringSeparator } from '../../enums/StringSeparator';
export class CLIUtils {
/**
* @type {string[]}
*/
public static readonly allowedConfigFileExtensions: string[] = [
'.js',
'.json'
];
/**
* @param {string} configPath
* @returns {TDictionary}
*/
public static getUserConfig (configPath: string): TDictionary {
let config: TDictionary;
const configFileExtension: string = path.extname(configPath);
const isValidExtension: boolean = CLIUtils.allowedConfigFileExtensions.includes(configFileExtension);
if (!isValidExtension) {
throw new ReferenceError('Given config path must be a valid `.js` or `.json` file path');
}
try {
config = require(configPath);
} catch {
try {
config = __non_webpack_require__(configPath);
} catch {
throw new ReferenceError(`Cannot open config file with path: ${configPath}`);
}
}
return config;
}
/**
* @param {TDictionary} optionEnum
* @returns {string}
*/
public static stringifyOptionAvailableValues (optionEnum: TDictionary): string {
return Object.values(optionEnum).join(`${StringSeparator.Comma} `);
}
}
@@ -0,0 +1,133 @@
import * as fs from 'fs';
import * as mkdirp from 'mkdirp';
import * as path from 'path';
import { TInputCLIOptions } from '../../types/options/TInputCLIOptions';
import { StringSeparator } from '../../enums/StringSeparator';
import { JavaScriptObfuscatorCLI } from '../JavaScriptObfuscatorCLI';
export class ObfuscatedCodeWriter {
/**
* @type {string}
*/
private readonly inputPath: string;
/**
* @type {TInputCLIOptions}
*/
private readonly options: TInputCLIOptions;
/**
* @param {string} inputPath
* @param {TInputCLIOptions} options
*/
public constructor (
inputPath: string,
options: TInputCLIOptions
) {
this.inputPath = path.normalize(inputPath);
this.options = options;
}
/**
* @param {string} filePath
* @returns {string}
*/
public getOutputCodePath (filePath: string): string {
const normalizedFilePath: string = path.normalize(filePath);
const normalizedRawOutputPath: string | null = this.options.output
? path.normalize(this.options.output)
: null;
if (!normalizedRawOutputPath) {
return normalizedFilePath
.split(StringSeparator.Dot)
.map((value: string, index: number) => {
return index === 0 ? `${value}${JavaScriptObfuscatorCLI.obfuscatedFilePrefix}` : value;
})
.join(StringSeparator.Dot);
}
const rawInputPathStats: fs.Stats = fs.lstatSync(this.inputPath);
const outputPathExtName: string = path.extname(normalizedRawOutputPath);
const isDirectoryRawInputPath: boolean = rawInputPathStats.isDirectory();
const isDirectoryRawOutputPath: boolean = !JavaScriptObfuscatorCLI
.availableInputExtensions
.includes(outputPathExtName);
if (isDirectoryRawInputPath) {
if (isDirectoryRawOutputPath) {
const parsedNormalizedFilePath: path.ParsedPath = path.parse(normalizedFilePath);
const baseOutputPath: string = path.join(
parsedNormalizedFilePath.dir.replace(this.inputPath, ''),
parsedNormalizedFilePath.base
);
return path.join(normalizedRawOutputPath, baseOutputPath);
} else {
throw new Error('Output path for directory obfuscation should be a directory path');
}
} else {
if (isDirectoryRawOutputPath) {
return path.join(normalizedRawOutputPath, path.basename(filePath));
} else {
return normalizedRawOutputPath;
}
}
}
/**
* @param {string} outputCodePath
* @param {string} sourceMapFileName
* @returns {string}
*/
public getOutputSourceMapPath (outputCodePath: string, sourceMapFileName: string = ''): string {
if (!outputCodePath) {
throw new Error('Output code path is empty');
}
let normalizedOutputCodePath: string = path.normalize(outputCodePath);
let parsedOutputCodePath: path.ParsedPath = path.parse(normalizedOutputCodePath);
if (!parsedOutputCodePath.ext && !sourceMapFileName) {
throw new Error('Source map file name should be set when output code path is a directory path');
}
if (sourceMapFileName) {
const indexOfLastSeparator: number = normalizedOutputCodePath.lastIndexOf(path.sep);
const sourceMapPath: string = parsedOutputCodePath.ext && indexOfLastSeparator > 0
? normalizedOutputCodePath.slice(0, indexOfLastSeparator)
: normalizedOutputCodePath;
// remove possible drive letter for win32 environment
const normalizedSourceMapFilePath: string = sourceMapFileName.replace(/^[a-zA-Z]:\\*/, '');
normalizedOutputCodePath = path.join(sourceMapPath, normalizedSourceMapFilePath);
}
if (!/\.js\.map$/.test(normalizedOutputCodePath)) {
parsedOutputCodePath = path.parse(normalizedOutputCodePath);
const outputCodePathWithoutExtension: string = path.join(parsedOutputCodePath.dir, parsedOutputCodePath.name);
normalizedOutputCodePath = `${outputCodePathWithoutExtension}.js.map`;
} else if (/\.js$/.test(normalizedOutputCodePath)) {
normalizedOutputCodePath += '.map';
}
return normalizedOutputCodePath;
}
/**
* @param {string} outputPath
* @param {string} data
*/
public writeFile (outputPath: string, data: string): void {
mkdirp.sync(path.dirname(outputPath));
fs.writeFileSync(outputPath, data, {
encoding: JavaScriptObfuscatorCLI.encoding
});
}
}
+167
View File
@@ -0,0 +1,167 @@
import * as fs from 'fs';
import * as path from 'path';
import multimatch from 'multimatch';
import { TInputCLIOptions } from '../../types/options/TInputCLIOptions';
import { IFileData } from '../../interfaces/cli/IFileData';
import { JavaScriptObfuscatorCLI } from '../JavaScriptObfuscatorCLI';
export class SourceCodeReader {
/**
* @type {string}
*/
private readonly inputPath: string;
/**
* @type {TInputCLIOptions}
*/
private readonly options: TInputCLIOptions;
/**
* @param {string} inputPath
* @param {TInputCLIOptions} options
*/
public constructor (
inputPath: string,
options: TInputCLIOptions
) {
this.inputPath = inputPath;
this.options = options;
}
/**
* @param {string} filePath
* @param {string[]} excludePatterns
* @returns {boolean}
*/
private static isExcludedPath (filePath: string, excludePatterns: string[] = []): boolean {
if (!excludePatterns.length) {
return false;
}
const fileName: string = path.basename(filePath);
const isExcludedFilePathByGlobPattern: boolean = !!multimatch([filePath], excludePatterns).length;
const isExcludedFilePathByInclusion: boolean = excludePatterns.some((excludePattern: string) =>
filePath.includes(excludePattern) || fileName.includes(excludePattern)
);
return isExcludedFilePathByInclusion || isExcludedFilePathByGlobPattern;
}
/**
* @param {string} filePath
* @returns {boolean}
*/
private static isDirectoryPath (filePath: string): boolean {
try {
return fs.statSync(filePath).isDirectory();
} catch {
return false;
}
}
/**
* @param {string} filePath
* @returns {boolean}
*/
private static isFilePath (filePath: string): boolean {
try {
return fs.statSync(filePath).isFile();
} catch {
return false;
}
}
/**
* @param {string} directoryPath
* @param {string[]} excludePatterns
* @returns {boolean}
*/
private static isValidDirectory (directoryPath: string, excludePatterns: string[] = []): boolean {
return !SourceCodeReader.isExcludedPath(directoryPath, excludePatterns);
}
/**
* @param {string} filePath
* @param {string[]} excludePatterns
* @returns {boolean}
*/
private static isValidFile (filePath: string, excludePatterns: string[] = []): boolean {
return JavaScriptObfuscatorCLI.availableInputExtensions.includes(path.extname(filePath))
&& !filePath.includes(JavaScriptObfuscatorCLI.obfuscatedFilePrefix)
&& !SourceCodeReader.isExcludedPath(filePath, excludePatterns);
}
/**
* @param {string} filePath
* @returns {string}
*/
private static readFile (filePath: string): IFileData {
return {
filePath: path.normalize(filePath),
content: fs.readFileSync(filePath, JavaScriptObfuscatorCLI.encoding)
};
}
/**
* @returns {IFileData[]}
*/
public readSourceCode (): IFileData[] {
if (
SourceCodeReader.isFilePath(this.inputPath)
&& SourceCodeReader.isValidFile(this.inputPath, this.options.exclude)
) {
return [SourceCodeReader.readFile(this.inputPath)];
}
if (
SourceCodeReader.isDirectoryPath(this.inputPath)
&& SourceCodeReader.isValidDirectory(this.inputPath, this.options.exclude)
) {
return this.readDirectoryRecursive(this.inputPath);
}
const availableFilePaths: string = JavaScriptObfuscatorCLI
.availableInputExtensions
.map((extension: string) => `\`${extension}\``)
.join(', ');
throw new ReferenceError(`Given input path must be a valid ${availableFilePaths} file or directory path`);
}
/**
* @param {string} directoryPath
* @param {IFileData[]} filesData
* @returns {IFileData[]}
*/
private readDirectoryRecursive (directoryPath: string, filesData: IFileData[] = []): IFileData[] {
fs.readdirSync(directoryPath, JavaScriptObfuscatorCLI.encoding)
.forEach((fileName: string) => {
const filePath: string = path.join(directoryPath, fileName);
if (
SourceCodeReader.isDirectoryPath(filePath)
&& SourceCodeReader.isValidDirectory(filePath, this.options.exclude)
) {
filesData.push(...this.readDirectoryRecursive(filePath));
return;
}
if (
SourceCodeReader.isFilePath(filePath)
&& SourceCodeReader.isValidFile(filePath, this.options.exclude)
) {
const fileData: IFileData = SourceCodeReader.readFile(filePath);
filesData.push(fileData);
return;
}
});
return filesData;
}
}
@@ -0,0 +1,46 @@
import { inject, injectable } from 'inversify';
import { ServiceIdentifiers } from '../container/ServiceIdentifiers';
import { ICodeTransformer } from '../interfaces/code-transformers/ICodeTransformer';
import { IOptions } from '../interfaces/options/IOptions';
import { IRandomGenerator } from '../interfaces/utils/IRandomGenerator';
import { CodeTransformer } from '../enums/code-transformers/CodeTransformer';
import { CodeTransformationStage } from '../enums/code-transformers/CodeTransformationStage';
@injectable()
export abstract class AbstractCodeTransformer implements ICodeTransformer {
/**
* @type {CodeTransformer[]}
*/
public readonly runAfter: CodeTransformer[] | undefined;
/**
* @type {IOptions}
*/
protected readonly options: IOptions;
/**
* @type {IRandomGenerator}
*/
protected readonly randomGenerator: IRandomGenerator;
/**
* @param {IRandomGenerator} randomGenerator
* @param {IOptions} options
*/
protected constructor (
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
this.randomGenerator = randomGenerator;
this.options = options;
}
/**
* @param {string} code
* @param {CodeTransformationStage} codeTransformationStage
* @returns {string}
*/
public abstract transformCode (code: string, codeTransformationStage: CodeTransformationStage): string;
}
@@ -0,0 +1,13 @@
import { injectable } from 'inversify';
import { ICodeTransformer } from '../interfaces/code-transformers/ICodeTransformer';
import { CodeTransformer } from '../enums/code-transformers/CodeTransformer';
import { AbstractTransformerNamesGroupsBuilder } from '../utils/AbstractTransformerNamesGroupsBuilder';
@injectable()
export class CodeTransformerNamesGroupsBuilder extends AbstractTransformerNamesGroupsBuilder<
CodeTransformer,
ICodeTransformer
> {}
@@ -0,0 +1,100 @@
import { inject, injectable } from 'inversify';
import { ServiceIdentifiers } from '../container/ServiceIdentifiers';
import { TCodeTransformerFactory } from '../types/container/code-transformers/TCodeTransformerFactory';
import { TDictionary } from '../types/TDictionary';
import { ICodeTransformer } from '../interfaces/code-transformers/ICodeTransformer';
import { ICodeTransformersRunner } from '../interfaces/code-transformers/ICodeTransformersRunner';
import { ITransformerNamesGroupsBuilder } from '../interfaces/utils/ITransformerNamesGroupsBuilder';
import { CodeTransformer } from '../enums/code-transformers/CodeTransformer';
import { CodeTransformationStage } from '../enums/code-transformers/CodeTransformationStage';
@injectable()
export class CodeTransformersRunner implements ICodeTransformersRunner {
/**
* @type {TCodeTransformerFactory}
*/
private readonly codeTransformerFactory: TCodeTransformerFactory;
/**
* @type {ITransformerNamesGroupsBuilder}
*/
private readonly codeTransformerNamesGroupsBuilder: ITransformerNamesGroupsBuilder<
CodeTransformer,
ICodeTransformer
>;
/**
* @param {TNodeTransformerFactory} codeTransformerFactory
* @param {ITransformerNamesGroupsBuilder} codeTransformerNamesGroupsBuilder
*/
public constructor (
@inject(ServiceIdentifiers.Factory__ICodeTransformer)
codeTransformerFactory: TCodeTransformerFactory,
@inject(ServiceIdentifiers.ICodeTransformerNamesGroupsBuilder)
codeTransformerNamesGroupsBuilder: ITransformerNamesGroupsBuilder<
CodeTransformer,
ICodeTransformer
>,
) {
this.codeTransformerFactory = codeTransformerFactory;
this.codeTransformerNamesGroupsBuilder = codeTransformerNamesGroupsBuilder;
}
/**
* @param {string} code
* @param {CodeTransformer[]} codeTransformerNames
* @param {CodeTransformationStage} codeTransformationStage
* @returns {string}
*/
public transform (
code: string,
codeTransformerNames: CodeTransformer[],
codeTransformationStage: CodeTransformationStage
): string {
if (!codeTransformerNames.length) {
return code;
}
const normalizedCodeTransformers: TDictionary<ICodeTransformer> =
this.buildNormalizedCodeTransformers(codeTransformerNames, codeTransformationStage);
const codeTransformerNamesGroups: CodeTransformer[][] =
this.codeTransformerNamesGroupsBuilder.build(normalizedCodeTransformers);
for (const nodeTransformerNamesGroup of codeTransformerNamesGroups) {
for (const nodeTransformerName of nodeTransformerNamesGroup) {
const codeTransformer: ICodeTransformer = normalizedCodeTransformers[nodeTransformerName];
code = codeTransformer.transformCode(code, codeTransformationStage);
}
}
return code;
}
/**
* @param {NodeTransformer[]} codeTransformerNames
* @param {NodeTransformationStage} codeTransformationStage
* @returns {TDictionary<INodeTransformer>}
*/
private buildNormalizedCodeTransformers (
codeTransformerNames: CodeTransformer[],
codeTransformationStage: CodeTransformationStage
): TDictionary<ICodeTransformer> {
return codeTransformerNames
.reduce<TDictionary<ICodeTransformer>>(
(acc: TDictionary<ICodeTransformer>, codeTransformerName: CodeTransformer) => {
const codeTransformer: ICodeTransformer = this.codeTransformerFactory(codeTransformerName);
return {
...acc,
[codeTransformerName]: codeTransformer
};
},
{}
);
}
}
@@ -0,0 +1,72 @@
import { inject, injectable, } from 'inversify';
import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
import { IOptions } from '../../interfaces/options/IOptions';
import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
import { CodeTransformationStage } from '../../enums/code-transformers/CodeTransformationStage';
import { AbstractCodeTransformer } from '../AbstractCodeTransformer';
@injectable()
export class HashbangOperatorTransformer extends AbstractCodeTransformer {
/**
* @type {string | null}
*/
private hashbangOperatorLine: string | null = null;
/**
* @param {IRandomGenerator} randomGenerator
* @param {IOptions} options
*/
public constructor (
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
super(randomGenerator, options);
}
/**
* Removes hashbang operator before AST transformation and appends it back after
*
* @param {string} code
* @param {CodeTransformationStage} codeTransformationStage
* @returns {string}
*/
public transformCode (code: string, codeTransformationStage: CodeTransformationStage): string {
switch (codeTransformationStage) {
case CodeTransformationStage.PreparingTransformers:
return this.removeAndSaveHashbangOperatorLine(code);
case CodeTransformationStage.FinalizingTransformers:
return this.appendSavedHashbangOperatorLine(code);
default:
return code;
}
}
/**
* @param {string} code
* @returns {string}
*/
private removeAndSaveHashbangOperatorLine (code: string): string {
return code
.replace(/^#!.*$(\r?\n)*/m, (substring: string) => {
if (substring) {
this.hashbangOperatorLine = substring;
}
return '';
})
.trim();
}
/**
* @param {string} code
* @returns {string}
*/
private appendSavedHashbangOperatorLine (code: string): string {
return `${this.hashbangOperatorLine ?? ''}${code}`;
}
}
+1
View File
@@ -0,0 +1 @@
export const alphabetString: string = 'abcdefghijklmnopqrstuvwxyz';
@@ -0,0 +1,3 @@
import { alphabetString } from './AlphabetString';
export const alphabetStringUppercase: string = alphabetString.toUpperCase();
+5
View File
@@ -0,0 +1,5 @@
import { alphabetStringUppercase } from './AlphabetStringUppercase';
import { alphabetString } from './AlphabetString';
import { numbersString } from './NumbersString';
export const base64alphabet: string = `${alphabetStringUppercase}${alphabetString}${numbersString}+/=`;
@@ -0,0 +1,8 @@
import { alphabetStringUppercase } from './AlphabetStringUppercase';
import { alphabetString } from './AlphabetString';
import { numbersString } from './NumbersString';
/**
* Swapped lowercase and uppercase groups of alphabet to prevent easy decode
*/
export const base64alphabetSwapped: string = `${alphabetString}${alphabetStringUppercase}${numbersString}+/=`;
+3
View File
@@ -0,0 +1,3 @@
import * as acorn from 'acorn';
export const ecmaVersion: acorn.Options['ecmaVersion'] & number = 12;
+1
View File
@@ -0,0 +1 @@
export const numbersString: string = '0123456789';
@@ -0,0 +1,233 @@
import { Container, interfaces } from 'inversify';
import { ServiceIdentifiers } from './ServiceIdentifiers';
import { analyzersModule } from './modules/analyzers/AnalyzersModule';
import { codeTransformersModule } from './modules/code-transformers/CodeTransformersModule';
import { controlFlowTransformersModule } from './modules/node-transformers/ControlFlowTransformersModule';
import { convertingTransformersModule } from './modules/node-transformers/ConvertingTransformersModule';
import { customCodeHelpersModule } from './modules/custom-code-helpers/CustomCodeHelpersModule';
import { customNodesModule } from './modules/custom-nodes/CustomNodesModule';
import { deadCodeInjectionTransformersModule } from './modules/node-transformers/DeadCodeInjectionTransformersModule';
import { finalizingTransformersModule } from './modules/node-transformers/FinalizingTransformersModule';
import { generatorsModule } from './modules/generators/GeneratorsModule';
import { initializingTransformersModule } from './modules/node-transformers/InitializingTransformersModule';
import { nodeModule } from './modules/node/NodeModule';
import { nodeTransformersModule } from './modules/node-transformers/NodeTransformersModule';
import { optionsModule } from './modules/options/OptionsModule';
import { preparingTransformersModule } from './modules/node-transformers/PreparingTransformersModule';
import { renameIdentifiersTransformersModule } from './modules/node-transformers/RenameIdentifiersTransformersModule';
import { renamePropertiesTransformersModule } from './modules/node-transformers/RenamePropertiesTransformersModule';
import { simplifyingTransformersModule } from './modules/node-transformers/SimplifyingTransformersModule';
import { storagesModule } from './modules/storages/StoragesModule';
import { stringArrayTransformersModule } from './modules/node-transformers/StringArrayTransformersModule';
import { utilsModule } from './modules/utils/UtilsModule';
import { TInputOptions } from '../types/options/TInputOptions';
import { ICodeTransformersRunner } from '../interfaces/code-transformers/ICodeTransformersRunner';
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 { IObfuscatedCode } from '../interfaces/source-code/IObfuscatedCode';
import { ISourceCode } from '../interfaces/source-code/ISourceCode';
import { INodeTransformersRunner } from '../interfaces/node-transformers/INodeTransformersRunner';
import { CodeTransformersRunner } from '../code-transformers/CodeTransformersRunner';
import { JavaScriptObfuscator } from '../JavaScriptObfuscator';
import { Logger } from '../logger/Logger';
import { NodeTransformersRunner } from '../node-transformers/NodeTransformersRunner';
import { ObfuscationEventEmitter } from '../event-emitters/ObfuscationEventEmitter';
import { ObfuscatedCode } from '../source-code/ObfuscatedCode';
import { SourceCode } from '../source-code/SourceCode';
export class InversifyContainerFacade implements IInversifyContainerFacade {
/**
* @type {interfaces.Container}
*/
private readonly container: interfaces.Container;
public constructor () {
this.container = new Container();
}
/**
* @param {interfaces.ServiceIdentifier<U>} serviceIdentifier
* @returns {U}
*/
public static getFactory <T extends string, U> (
serviceIdentifier: interfaces.ServiceIdentifier<U>
): (context: interfaces.Context) => (bindingName: T) => U {
return (context: interfaces.Context): (bindingName: T) => U => {
return (bindingName: T): U => {
return context.container.getNamed<U>(serviceIdentifier, bindingName);
};
};
}
/**
* @param {interfaces.ServiceIdentifier<U>} serviceIdentifier
* @returns {U}
*/
public static getCacheFactory <T extends string, U> (
serviceIdentifier: interfaces.ServiceIdentifier<U>
): (context: interfaces.Context) => (bindingName: T) => U {
return (context: interfaces.Context): (bindingName: T) => U => {
const cache: Map <T, U> = new Map();
return (bindingName: T): U => {
if (cache.has(bindingName)) {
return <U>cache.get(bindingName);
}
const object: U = context.container.getNamed<U>(serviceIdentifier, bindingName);
cache.set(bindingName, object);
return object;
};
};
}
/**
* @param {interfaces.ServiceIdentifier<interfaces.Newable<U>>} serviceIdentifier
* @param {interfaces.ServiceIdentifier<interfaces.Newable<Object>>[]} dependencies
* @returns {U}
*/
public static getConstructorFactory <T extends string, U> (
serviceIdentifier: interfaces.ServiceIdentifier<interfaces.Newable<U>>,
...dependencies: interfaces.ServiceIdentifier<interfaces.Newable<Record<string, any>>>[]
): (context: interfaces.Context) => (bindingName: T) => U {
return (context: interfaces.Context): (bindingName: T) => U => {
const cache: Map<T, interfaces.Newable<U>> = new Map();
const cachedDependencies: Record<string, any>[] = [];
return (bindingName: T): U => {
dependencies.forEach((
dependency: interfaces.ServiceIdentifier<interfaces.Newable<Record<string, any>>>,
index: number
) => {
if (!cachedDependencies[index]) {
cachedDependencies[index] = context.container.get(dependency);
}
});
if (cache.has(bindingName)) {
return new (<interfaces.Newable<U>>cache.get(bindingName))(...cachedDependencies);
}
const constructor: interfaces.Newable<U> = context.container
.getNamed<interfaces.Newable<U>>(
serviceIdentifier,
bindingName
);
cache.set(bindingName, constructor);
return new constructor(...cachedDependencies);
};
};
}
/**
* @param {interfaces.ServiceIdentifier<T>} serviceIdentifier
* @returns {T}
*/
public get <T> (serviceIdentifier: interfaces.ServiceIdentifier<T>): T {
return this.container.get<T>(serviceIdentifier);
}
/**
* @param {interfaces.ServiceIdentifier<T>} serviceIdentifier
* @param {string | number | symbol} named
* @returns {T}
*/
public getNamed <T> (serviceIdentifier: interfaces.ServiceIdentifier<T>, named: string | number | symbol): T {
return this.container.getNamed<T>(serviceIdentifier, named);
}
/**
* @param {string} sourceCode
* @param {string} sourceMap
* @param {TInputOptions} options
*/
public load (sourceCode: string, sourceMap: string, options: TInputOptions): void {
this.container
.bind<ISourceCode>(ServiceIdentifiers.ISourceCode)
.toDynamicValue(() => new SourceCode(sourceCode, sourceMap))
.inSingletonScope();
this.container
.bind<TInputOptions>(ServiceIdentifiers.TInputOptions)
.toDynamicValue(() => options)
.inSingletonScope();
this.container
.bind<ILogger>(ServiceIdentifiers.ILogger)
.to(Logger)
.inSingletonScope();
this.container
.bind<IJavaScriptObfuscator>(ServiceIdentifiers.IJavaScriptObfuscator)
.to(JavaScriptObfuscator)
.inSingletonScope();
this.container
.bind<ICodeTransformersRunner>(ServiceIdentifiers.ICodeTransformersRunner)
.to(CodeTransformersRunner)
.inSingletonScope();
this.container
.bind<INodeTransformersRunner>(ServiceIdentifiers.INodeTransformersRunner)
.to(NodeTransformersRunner)
.inSingletonScope();
this.container
.bind<IObfuscatedCode>(ServiceIdentifiers.IObfuscatedCode)
.to(ObfuscatedCode);
this.container
.bind<IObfuscatedCode>(ServiceIdentifiers.Factory__IObfuscatedCode)
.toFactory<IObfuscatedCode>((context: interfaces.Context) => {
return (obfuscatedCodeAsString: string, sourceMapAsString: string): IObfuscatedCode => {
const obfuscatedCode: IObfuscatedCode = context.container
.get<IObfuscatedCode>(ServiceIdentifiers.IObfuscatedCode);
obfuscatedCode.initialize(obfuscatedCodeAsString, sourceMapAsString);
return obfuscatedCode;
};
});
this.container
.bind<IObfuscationEventEmitter>(ServiceIdentifiers.IObfuscationEventEmitter)
.to(ObfuscationEventEmitter)
.inSingletonScope();
// modules
this.container.load(analyzersModule);
this.container.load(codeTransformersModule);
this.container.load(controlFlowTransformersModule);
this.container.load(convertingTransformersModule);
this.container.load(customCodeHelpersModule);
this.container.load(customNodesModule);
this.container.load(deadCodeInjectionTransformersModule);
this.container.load(finalizingTransformersModule);
this.container.load(generatorsModule);
this.container.load(initializingTransformersModule);
this.container.load(nodeModule);
this.container.load(nodeTransformersModule);
this.container.load(optionsModule);
this.container.load(preparingTransformersModule);
this.container.load(renameIdentifiersTransformersModule);
this.container.load(renamePropertiesTransformersModule);
this.container.load(simplifyingTransformersModule);
this.container.load(storagesModule);
this.container.load(stringArrayTransformersModule);
this.container.load(utilsModule);
}
public unload (): void {
this.container.unbindAll();
}
}
+64
View File
@@ -0,0 +1,64 @@
export enum ServiceIdentifiers {
Factory__ICalleeDataExtractor = 'Factory<ICalleeDataExtractor>',
Factory__ICodeTransformer = 'Factory<ICodeTransformer[]>',
Factory__IControlFlowCustomNode = 'Factory<IControlFlowCustomNode>',
Factory__IControlFlowReplacer = 'Factory<IControlFlowReplacer>',
Factory__ICustomCodeHelper = 'Factory<ICustomCodeHelper>',
Factory__ICustomCodeHelperGroup = 'Factory<ICustomCodeHelperGroup>',
Factory__IDeadCodeInjectionCustomNode = 'Factory<IDeadCodeInjectionCustomNode>',
Factory__IIdentifierNamesGenerator = 'Factory<IIdentifierNamesGenerator>',
Factory__INodeGuard = 'Factory<INodeGuard>',
Factory__INodeTransformer = 'Factory<INodeTransformer[]>',
Factory__IObfuscatedCode = 'Factory<IObfuscatedCode>',
Factory__IObjectExpressionKeysTransformerCustomNode = 'Factory<IObjectExpressionKeysTransformerCustomNode>',
Factory__IObjectExpressionExtractor = 'Factory<IObjectExpressionExtractor>',
Factory__IStringArrayCustomNode = 'Factory<IStringArrayCustomNode>',
Factory__IStringArrayIndexNode = 'Factory<IStringArrayIndexNode>',
Factory__TControlFlowStorage = 'Factory<TControlFlowStorage>',
IArrayUtils = 'IArrayUtils',
ICalleeDataExtractor = 'ICalleeDataExtractor',
ICallsGraphAnalyzer = 'ICallsGraphAnalyzer',
ICodeTransformer = 'ICodeTransformer',
ICodeTransformerNamesGroupsBuilder = 'ICodeTransformerNamesGroupsBuilder',
ICodeTransformersRunner = 'ICodeTransformersRunner',
ICryptUtils = 'ICryptUtils',
ICryptUtilsSwappedAlphabet = 'ICryptUtilsSwappedAlphabet',
ICustomCodeHelper = 'ICustomCodeHelper',
ICustomCodeHelperGroup = 'ICustomCodeHelperGroup',
IControlFlowReplacer = 'IControlFlowReplacer',
ICustomCodeHelperFormatter = 'ICustomCodeHelperFormatter',
ICustomCodeHelperObfuscator = 'ICustomCodeHelperObfuscator',
IEscapeSequenceEncoder = 'IEscapeSequenceEncoder',
IIdentifierNamesGenerator = 'IIdentifierNamesGenerator',
IIdentifierReplacer = 'IIdentifierReplacer',
IJavaScriptObfuscator = 'IJavaScriptObfuscator',
ILevelledTopologicalSorter = 'ILevelledTopologicalSorter',
ILiteralNodesCacheStorage = 'ILiteralNodesCacheStorage',
ILogger = 'ILogger',
INodeGuard = 'INodeGuard',
INodeTransformer = 'INodeTransformer',
INodeTransformerNamesGroupsBuilder = 'INodeTransformerNamesGroupsBuilder',
INodeTransformersRunner = 'INodeTransformersRunner',
INumberNumericalExpressionAnalyzer = 'INumberNumericalExpressionAnalyzer',
IObfuscationEventEmitter = 'IObfuscationEventEmitter',
IObfuscatedCode = 'IObfuscatedCode',
IOptions = 'IOptions',
IOptionsNormalizer = 'IOptionsNormalizer',
IPrevailingKindOfVariablesAnalyzer = 'IPrevailingKindOfVariablesAnalyzer',
IObjectExpressionExtractor = 'IObjectExpressionExtractor',
IRandomGenerator = 'IRandomGenerator',
IRenamePropertiesReplacer = 'IRenamePropertiesReplacer',
IScopeIdentifiersTraverser = 'IScopeIdentifiersTraverser',
ISourceCode = 'ISourceCode',
IScopeAnalyzer = 'IScopeAnalyzer',
IStringArrayIndexNode = 'IStringArrayIndexNode',
IStringArrayScopeCallsWrapperLexicalScopeDataStorage = 'IStringArrayScopeCallsWrapperLexicalScopeDataStorage',
IStringArrayScopeCallsWrapperNamesDataStorage = 'IStringArrayScopeCallsWrapperNamesDataStorage',
IStringArrayStorage = 'IStringArrayStorage',
IStringArrayStorageAnalyzer = 'IStringArrayStorageAnalyzer',
IVisitedLexicalScopeNodesStackStorage = 'IVisitedLexicalScopeNodesStackStorage',
Newable__ICustomNode = 'Newable<ICustomNode>',
Newable__TControlFlowStorage = 'Newable<TControlFlowStorage>',
TCustomNodeGroupStorage = 'TCustomNodeGroupStorage',
TInputOptions = 'TInputOptions'
}
@@ -0,0 +1,67 @@
import { InversifyContainerFacade } from '../../InversifyContainerFacade';
import { ContainerModule, interfaces } from 'inversify';
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';
import { CalleeDataExtractor } from '../../../enums/analyzers/calls-graph-analyzer/CalleeDataExtractor';
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';
import { StringArrayStorageAnalyzer } from '../../../analyzers/string-array-storage-analyzer/StringArrayStorageAnalyzer';
export const analyzersModule: interfaces.ContainerModule = new ContainerModule((bind: interfaces.Bind) => {
// calls graph analyzer
bind<ICallsGraphAnalyzer>(ServiceIdentifiers.ICallsGraphAnalyzer)
.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)
.inSingletonScope();
// scope analyzer
bind<IScopeAnalyzer>(ServiceIdentifiers.IScopeAnalyzer)
.to(ScopeAnalyzer)
.inSingletonScope();
// string array storage analyzer
bind<IStringArrayStorageAnalyzer>(ServiceIdentifiers.IStringArrayStorageAnalyzer)
.to(StringArrayStorageAnalyzer)
.inSingletonScope();
// callee data extractors
bind<ICalleeDataExtractor>(ServiceIdentifiers.ICalleeDataExtractor)
.to(FunctionDeclarationCalleeDataExtractor)
.whenTargetNamed(CalleeDataExtractor.FunctionDeclarationCalleeDataExtractor);
bind<ICalleeDataExtractor>(ServiceIdentifiers.ICalleeDataExtractor)
.to(FunctionExpressionCalleeDataExtractor)
.whenTargetNamed(CalleeDataExtractor.FunctionExpressionCalleeDataExtractor);
bind<ICalleeDataExtractor>(ServiceIdentifiers.ICalleeDataExtractor)
.to(ObjectExpressionCalleeDataExtractor)
.whenTargetNamed(CalleeDataExtractor.ObjectExpressionCalleeDataExtractor);
// callee data extractor factory
bind<ICalleeDataExtractor>(ServiceIdentifiers.Factory__ICalleeDataExtractor)
.toFactory<ICalleeDataExtractor>(InversifyContainerFacade
.getCacheFactory<CalleeDataExtractor, ICalleeDataExtractor>(
ServiceIdentifiers.ICalleeDataExtractor
));
});
@@ -0,0 +1,28 @@
import { InversifyContainerFacade } from '../../InversifyContainerFacade';
import { ContainerModule, interfaces } from 'inversify';
import { ServiceIdentifiers } from '../../ServiceIdentifiers';
import { ICodeTransformer } from '../../../interfaces/code-transformers/ICodeTransformer';
import { ITransformerNamesGroupsBuilder } from '../../../interfaces/utils/ITransformerNamesGroupsBuilder';
import { CodeTransformer } from '../../../enums/code-transformers/CodeTransformer';
import { CodeTransformerNamesGroupsBuilder } from '../../../code-transformers/CodeTransformerNamesGroupsBuilder';
import { HashbangOperatorTransformer } from '../../../code-transformers/preparing-transformers/HashbangOperatorTransformer';
export const codeTransformersModule: interfaces.ContainerModule = new ContainerModule((bind: interfaces.Bind) => {
// code transformers factory
bind<ICodeTransformer>(ServiceIdentifiers.Factory__ICodeTransformer)
.toFactory<ICodeTransformer>(InversifyContainerFacade
.getCacheFactory<CodeTransformer, ICodeTransformer>(ServiceIdentifiers.ICodeTransformer));
// code transformer names groups builder
bind<ITransformerNamesGroupsBuilder<CodeTransformer, ICodeTransformer>>(ServiceIdentifiers.ICodeTransformerNamesGroupsBuilder)
.to(CodeTransformerNamesGroupsBuilder)
.inSingletonScope();
// preparing code transformers
bind<ICodeTransformer>(ServiceIdentifiers.ICodeTransformer)
.to(HashbangOperatorTransformer)
.whenTargetNamed(CodeTransformer.HashbangOperatorTransformer);
});
@@ -0,0 +1,124 @@
import { InversifyContainerFacade } from '../../InversifyContainerFacade';
import { ContainerModule, interfaces } from 'inversify';
import { ServiceIdentifiers } from '../../ServiceIdentifiers';
import { ICustomCodeHelper } from '../../../interfaces/custom-code-helpers/ICustomCodeHelper';
import { ICustomCodeHelperFormatter } from '../../../interfaces/custom-code-helpers/ICustomCodeHelperFormatter';
import { ICustomCodeHelperGroup } from '../../../interfaces/custom-code-helpers/ICustomCodeHelperGroup';
import { ICustomCodeHelperObfuscator } from '../../../interfaces/custom-code-helpers/ICustomCodeHelperObfuscator';
import { CustomCodeHelper } from '../../../enums/custom-code-helpers/CustomCodeHelper';
import { CustomCodeHelperGroup } from '../../../enums/custom-code-helpers/CustomCodeHelperGroup';
import { ConsoleOutputCodeHelperGroup } from '../../../custom-code-helpers/console-output/group/ConsoleOutputCodeHelperGroup';
import { DebugProtectionCodeHelperGroup } from '../../../custom-code-helpers/debug-protection/group/DebugProtectionCodeHelperGroup';
import { DomainLockCustomCodeHelperGroup } from '../../../custom-code-helpers/domain-lock/group/DomainLockCustomCodeHelperGroup';
import { SelfDefendingCodeHelperGroup } from '../../../custom-code-helpers/self-defending/group/SelfDefendingCodeHelperGroup';
import { StringArrayCodeHelperGroup } from '../../../custom-code-helpers/string-array/group/StringArrayCodeHelperGroup';
import { ConsoleOutputDisableCodeHelper } from '../../../custom-code-helpers/console-output/ConsoleOutputDisableCodeHelper';
import { CustomCodeHelperFormatter } from '../../../custom-code-helpers/CustomCodeHelperFormatter';
import { CustomCodeHelperObfuscator } from '../../../custom-code-helpers/CustomCodeHelperObfuscator';
import { DebugProtectionFunctionCallCodeHelper } from '../../../custom-code-helpers/debug-protection/DebugProtectionFunctionCallCodeHelper';
import { DebugProtectionFunctionIntervalCodeHelper } from '../../../custom-code-helpers/debug-protection/DebugProtectionFunctionIntervalCodeHelper';
import { DebugProtectionFunctionCodeHelper } from '../../../custom-code-helpers/debug-protection/DebugProtectionFunctionCodeHelper';
import { DomainLockCodeHelper } from '../../../custom-code-helpers/domain-lock/DomainLockCodeHelper';
import { CallsControllerFunctionCodeHelper } from '../../../custom-code-helpers/calls-controller/CallsControllerFunctionCodeHelper';
import { SelfDefendingUnicodeCodeHelper } from '../../../custom-code-helpers/self-defending/SelfDefendingUnicodeCodeHelper';
import { StringArrayCallsWrapperCodeHelper } from '../../../custom-code-helpers/string-array/StringArrayCallsWrapperCodeHelper';
import { StringArrayCallsWrapperBase64CodeHelper } from '../../../custom-code-helpers/string-array/StringArrayCallsWrapperBase64CodeHelper';
import { StringArrayCallsWrapperRc4CodeHelper } from '../../../custom-code-helpers/string-array/StringArrayCallsWrapperRc4CodeHelper';
import { StringArrayCodeHelper } from '../../../custom-code-helpers/string-array/StringArrayCodeHelper';
import { StringArrayRotateFunctionCodeHelper } from '../../../custom-code-helpers/string-array/StringArrayRotateFunctionCodeHelper';
export const customCodeHelpersModule: interfaces.ContainerModule = new ContainerModule((bind: interfaces.Bind) => {
// custom code helpers
bind<ICustomCodeHelper>(ServiceIdentifiers.ICustomCodeHelper)
.to(ConsoleOutputDisableCodeHelper)
.whenTargetNamed(CustomCodeHelper.ConsoleOutputDisable);
bind<ICustomCodeHelper>(ServiceIdentifiers.ICustomCodeHelper)
.to(DebugProtectionFunctionCallCodeHelper)
.whenTargetNamed(CustomCodeHelper.DebugProtectionFunctionCall);
bind<ICustomCodeHelper>(ServiceIdentifiers.ICustomCodeHelper)
.to(DebugProtectionFunctionIntervalCodeHelper)
.whenTargetNamed(CustomCodeHelper.DebugProtectionFunctionInterval);
bind<ICustomCodeHelper>(ServiceIdentifiers.ICustomCodeHelper)
.to(DebugProtectionFunctionCodeHelper)
.whenTargetNamed(CustomCodeHelper.DebugProtectionFunction);
bind<ICustomCodeHelper>(ServiceIdentifiers.ICustomCodeHelper)
.to(DomainLockCodeHelper)
.whenTargetNamed(CustomCodeHelper.DomainLock);
bind<ICustomCodeHelper>(ServiceIdentifiers.ICustomCodeHelper)
.to(CallsControllerFunctionCodeHelper)
.whenTargetNamed(CustomCodeHelper.CallsControllerFunction);
bind<ICustomCodeHelper>(ServiceIdentifiers.ICustomCodeHelper)
.to(SelfDefendingUnicodeCodeHelper)
.whenTargetNamed(CustomCodeHelper.SelfDefendingUnicode);
bind<ICustomCodeHelper>(ServiceIdentifiers.ICustomCodeHelper)
.to(StringArrayCallsWrapperCodeHelper)
.whenTargetNamed(CustomCodeHelper.StringArrayCallsWrapper);
bind<ICustomCodeHelper>(ServiceIdentifiers.ICustomCodeHelper)
.to(StringArrayCallsWrapperBase64CodeHelper)
.whenTargetNamed(CustomCodeHelper.StringArrayCallsWrapperBase64);
bind<ICustomCodeHelper>(ServiceIdentifiers.ICustomCodeHelper)
.to(StringArrayCallsWrapperRc4CodeHelper)
.whenTargetNamed(CustomCodeHelper.StringArrayCallsWrapperRc4);
bind<ICustomCodeHelper>(ServiceIdentifiers.ICustomCodeHelper)
.to(StringArrayCodeHelper)
.whenTargetNamed(CustomCodeHelper.StringArray);
bind<ICustomCodeHelper>(ServiceIdentifiers.ICustomCodeHelper)
.to(StringArrayRotateFunctionCodeHelper)
.whenTargetNamed(CustomCodeHelper.StringArrayRotateFunction);
// code helper groups
bind<ICustomCodeHelperGroup>(ServiceIdentifiers.ICustomCodeHelperGroup)
.to(ConsoleOutputCodeHelperGroup)
.whenTargetNamed(CustomCodeHelperGroup.ConsoleOutput);
bind<ICustomCodeHelperGroup>(ServiceIdentifiers.ICustomCodeHelperGroup)
.to(DebugProtectionCodeHelperGroup)
.whenTargetNamed(CustomCodeHelperGroup.DebugProtection);
bind<ICustomCodeHelperGroup>(ServiceIdentifiers.ICustomCodeHelperGroup)
.to(DomainLockCustomCodeHelperGroup)
.whenTargetNamed(CustomCodeHelperGroup.DomainLock);
bind<ICustomCodeHelperGroup>(ServiceIdentifiers.ICustomCodeHelperGroup)
.to(SelfDefendingCodeHelperGroup)
.whenTargetNamed(CustomCodeHelperGroup.SelfDefending);
bind<ICustomCodeHelperGroup>(ServiceIdentifiers.ICustomCodeHelperGroup)
.to(StringArrayCodeHelperGroup)
.whenTargetNamed(CustomCodeHelperGroup.StringArray);
// customCodeHelper factory
bind<ICustomCodeHelper>(ServiceIdentifiers.Factory__ICustomCodeHelper)
.toFactory<ICustomCodeHelper>(InversifyContainerFacade
.getFactory<CustomCodeHelper, ICustomCodeHelper>(ServiceIdentifiers.ICustomCodeHelper));
// customCodeHelperGroup factory
bind<ICustomCodeHelperGroup>(ServiceIdentifiers.Factory__ICustomCodeHelperGroup)
.toFactory<ICustomCodeHelperGroup>(InversifyContainerFacade
.getFactory<CustomCodeHelperGroup, ICustomCodeHelperGroup>(ServiceIdentifiers.ICustomCodeHelperGroup));
// custom code helper formatter
bind<ICustomCodeHelperFormatter>(ServiceIdentifiers.ICustomCodeHelperFormatter)
.to(CustomCodeHelperFormatter)
.inSingletonScope();
// custom code helper obfuscator
bind<ICustomCodeHelperObfuscator>(ServiceIdentifiers.ICustomCodeHelperObfuscator)
.to(CustomCodeHelperObfuscator)
.inSingletonScope();
});
@@ -0,0 +1,154 @@
import { InversifyContainerFacade } from '../../InversifyContainerFacade';
import { ContainerModule, interfaces } from 'inversify';
import { ServiceIdentifiers } from '../../ServiceIdentifiers';
import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode';
import { IStringArrayIndexNode } from '../../../interfaces/custom-nodes/string-array-nodes/IStringArrayIndexNode';
import { ControlFlowCustomNode } from '../../../enums/custom-nodes/ControlFlowCustomNode';
import { DeadCodeInjectionCustomNode } from '../../../enums/custom-nodes/DeadCodeInjectionCustomNode';
import { ObjectExpressionKeysTransformerCustomNode } from '../../../enums/custom-nodes/ObjectExpressionKeysTransformerCustomNode';
import { StringArrayCustomNode } from '../../../enums/custom-nodes/StringArrayCustomNode';
import { BinaryExpressionFunctionNode } from '../../../custom-nodes/control-flow-flattening-nodes/BinaryExpressionFunctionNode';
import { BlockStatementControlFlowFlatteningNode } from '../../../custom-nodes/control-flow-flattening-nodes/BlockStatementControlFlowFlatteningNode';
import { BlockStatementDeadCodeInjectionNode } from '../../../custom-nodes/dead-code-injection-nodes/BlockStatementDeadCodeInjectionNode';
import { CallExpressionControlFlowStorageCallNode } from '../../../custom-nodes/control-flow-flattening-nodes/control-flow-storage-nodes/CallExpressionControlFlowStorageCallNode';
import { CallExpressionFunctionNode } from '../../../custom-nodes/control-flow-flattening-nodes/CallExpressionFunctionNode';
import { ControlFlowStorageNode } from '../../../custom-nodes/control-flow-flattening-nodes/control-flow-storage-nodes/ControlFlowStorageNode';
import { ExpressionWithOperatorControlFlowStorageCallNode } from '../../../custom-nodes/control-flow-flattening-nodes/control-flow-storage-nodes/ExpressionWithOperatorControlFlowStorageCallNode';
import { LogicalExpressionFunctionNode } from '../../../custom-nodes/control-flow-flattening-nodes/LogicalExpressionFunctionNode';
import { ObjectExpressionVariableDeclarationHostNode } from '../../../custom-nodes/object-expression-keys-transformer-nodes/ObjectExpressionVariableDeclarationHostNode';
import { StringArrayCallNode } from '../../../custom-nodes/string-array-nodes/StringArrayCallNode';
import { StringArrayHexadecimalNumberIndexNode } from '../../../custom-nodes/string-array-nodes/string-array-index-nodes/StringArrayHexadecimalNumberIndexNode';
import { StringArrayHexadecimalNumericStringIndexNode } from '../../../custom-nodes/string-array-nodes/string-array-index-nodes/StringArrayHexadecimalNumericStringIndexNode';
import { StringArrayIndexNode } from '../../../enums/custom-nodes/string-array-index-nodes/StringArrayIndexNode';
import { StringArrayScopeCallsWrapperFunctionNode } from '../../../custom-nodes/string-array-nodes/StringArrayScopeCallsWrapperFunctionNode';
import { StringArrayScopeCallsWrapperVariableNode } from '../../../custom-nodes/string-array-nodes/StringArrayScopeCallsWrapperVariableNode';
import { StringLiteralControlFlowStorageCallNode } from '../../../custom-nodes/control-flow-flattening-nodes/control-flow-storage-nodes/StringLiteralControlFlowStorageCallNode';
import { StringLiteralNode } from '../../../custom-nodes/control-flow-flattening-nodes/StringLiteralNode';
export const customNodesModule: interfaces.ContainerModule = new ContainerModule((bind: interfaces.Bind) => {
// control flow custom nodes
bind<interfaces.Newable<ICustomNode>>(ServiceIdentifiers.Newable__ICustomNode)
.toConstructor(BinaryExpressionFunctionNode)
.whenTargetNamed(ControlFlowCustomNode.BinaryExpressionFunctionNode);
bind<interfaces.Newable<ICustomNode>>(ServiceIdentifiers.Newable__ICustomNode)
.toConstructor(BlockStatementControlFlowFlatteningNode)
.whenTargetNamed(ControlFlowCustomNode.BlockStatementControlFlowFlatteningNode);
bind<interfaces.Newable<ICustomNode>>(ServiceIdentifiers.Newable__ICustomNode)
.toConstructor(CallExpressionControlFlowStorageCallNode)
.whenTargetNamed(ControlFlowCustomNode.CallExpressionControlFlowStorageCallNode);
bind<interfaces.Newable<ICustomNode>>(ServiceIdentifiers.Newable__ICustomNode)
.toConstructor(CallExpressionFunctionNode)
.whenTargetNamed(ControlFlowCustomNode.CallExpressionFunctionNode);
bind<interfaces.Newable<ICustomNode>>(ServiceIdentifiers.Newable__ICustomNode)
.toConstructor(ControlFlowStorageNode)
.whenTargetNamed(ControlFlowCustomNode.ControlFlowStorageNode);
bind<interfaces.Newable<ICustomNode>>(ServiceIdentifiers.Newable__ICustomNode)
.toConstructor(ExpressionWithOperatorControlFlowStorageCallNode)
.whenTargetNamed(ControlFlowCustomNode.ExpressionWithOperatorControlFlowStorageCallNode);
bind<interfaces.Newable<ICustomNode>>(ServiceIdentifiers.Newable__ICustomNode)
.toConstructor(LogicalExpressionFunctionNode)
.whenTargetNamed(ControlFlowCustomNode.LogicalExpressionFunctionNode);
bind<interfaces.Newable<ICustomNode>>(ServiceIdentifiers.Newable__ICustomNode)
.toConstructor(StringLiteralNode)
.whenTargetNamed(ControlFlowCustomNode.StringLiteralNode);
bind<interfaces.Newable<ICustomNode>>(ServiceIdentifiers.Newable__ICustomNode)
.toConstructor(StringLiteralControlFlowStorageCallNode)
.whenTargetNamed(ControlFlowCustomNode.StringLiteralControlFlowStorageCallNode);
// dead code injection custom nodes
bind<interfaces.Newable<ICustomNode>>(ServiceIdentifiers.Newable__ICustomNode)
.toConstructor(BlockStatementDeadCodeInjectionNode)
.whenTargetNamed(DeadCodeInjectionCustomNode.BlockStatementDeadCodeInjectionNode);
// object expression keys transformer nodes
bind<interfaces.Newable<ICustomNode>>(ServiceIdentifiers.Newable__ICustomNode)
.toConstructor(ObjectExpressionVariableDeclarationHostNode)
.whenTargetNamed(ObjectExpressionKeysTransformerCustomNode.ObjectExpressionVariableDeclarationHostNode);
// string array nodes
bind<interfaces.Newable<ICustomNode>>(ServiceIdentifiers.Newable__ICustomNode)
.toConstructor(StringArrayCallNode)
.whenTargetNamed(StringArrayCustomNode.StringArrayCallNode);
bind<interfaces.Newable<ICustomNode>>(ServiceIdentifiers.Newable__ICustomNode)
.toConstructor(StringArrayScopeCallsWrapperFunctionNode)
.whenTargetNamed(StringArrayCustomNode.StringArrayScopeCallsWrapperFunctionNode);
bind<interfaces.Newable<ICustomNode>>(ServiceIdentifiers.Newable__ICustomNode)
.toConstructor(StringArrayScopeCallsWrapperVariableNode)
.whenTargetNamed(StringArrayCustomNode.StringArrayScopeCallsWrapperVariableNode);
// string array index nodes
bind<IStringArrayIndexNode>(ServiceIdentifiers.IStringArrayIndexNode)
.to(StringArrayHexadecimalNumberIndexNode)
.inSingletonScope()
.whenTargetNamed(StringArrayIndexNode.StringArrayHexadecimalNumberIndexNode);
bind<IStringArrayIndexNode>(ServiceIdentifiers.IStringArrayIndexNode)
.to(StringArrayHexadecimalNumericStringIndexNode)
.inSingletonScope()
.whenTargetNamed(StringArrayIndexNode.StringArrayHexadecimalNumericStringIndexNode);
// control flow customNode constructor factory
bind<ICustomNode>(ServiceIdentifiers.Factory__IControlFlowCustomNode)
.toFactory<ICustomNode>(InversifyContainerFacade
.getConstructorFactory<ControlFlowCustomNode, ICustomNode>(
ServiceIdentifiers.Newable__ICustomNode,
ServiceIdentifiers.Factory__IIdentifierNamesGenerator,
ServiceIdentifiers.ICustomCodeHelperFormatter,
ServiceIdentifiers.IRandomGenerator,
ServiceIdentifiers.IOptions
));
// dead code injection customNode constructor factory
bind<ICustomNode>(ServiceIdentifiers.Factory__IDeadCodeInjectionCustomNode)
.toFactory<ICustomNode>(InversifyContainerFacade
.getConstructorFactory<DeadCodeInjectionCustomNode, ICustomNode>(
ServiceIdentifiers.Newable__ICustomNode,
ServiceIdentifiers.Factory__IIdentifierNamesGenerator,
ServiceIdentifiers.ICustomCodeHelperFormatter,
ServiceIdentifiers.IRandomGenerator,
ServiceIdentifiers.IOptions
));
// object expression keys transformer customNode constructor factory
bind<ICustomNode>(ServiceIdentifiers.Factory__IObjectExpressionKeysTransformerCustomNode)
.toFactory<ICustomNode>(InversifyContainerFacade
.getConstructorFactory<ObjectExpressionKeysTransformerCustomNode, ICustomNode>(
ServiceIdentifiers.Newable__ICustomNode,
ServiceIdentifiers.Factory__IIdentifierNamesGenerator,
ServiceIdentifiers.ICustomCodeHelperFormatter,
ServiceIdentifiers.IRandomGenerator,
ServiceIdentifiers.IOptions
));
// string array customNode constructor factory
bind<ICustomNode>(ServiceIdentifiers.Factory__IStringArrayCustomNode)
.toFactory<ICustomNode>(InversifyContainerFacade
.getConstructorFactory<StringArrayCustomNode, ICustomNode>(
ServiceIdentifiers.Newable__ICustomNode,
ServiceIdentifiers.Factory__IIdentifierNamesGenerator,
ServiceIdentifiers.Factory__IStringArrayIndexNode,
ServiceIdentifiers.ICustomCodeHelperFormatter,
ServiceIdentifiers.IStringArrayStorage,
ServiceIdentifiers.IArrayUtils,
ServiceIdentifiers.IRandomGenerator,
ServiceIdentifiers.IOptions
));
// string array index node factory
bind<IStringArrayIndexNode>(ServiceIdentifiers.Factory__IStringArrayIndexNode)
.toFactory<IStringArrayIndexNode>(InversifyContainerFacade
.getCacheFactory<StringArrayIndexNode, IStringArrayIndexNode>(ServiceIdentifiers.IStringArrayIndexNode));
});
@@ -0,0 +1,87 @@
import { ContainerModule, interfaces } from 'inversify';
import { ServiceIdentifiers } from '../../ServiceIdentifiers';
import { IIdentifierNamesGenerator } from '../../../interfaces/generators/identifier-names-generators/IIdentifierNamesGenerator';
import { IOptions } from '../../../interfaces/options/IOptions';
import { IdentifierNamesGenerator } from '../../../enums/generators/identifier-names-generators/IdentifierNamesGenerator';
import { DictionaryIdentifierNamesGenerator } from '../../../generators/identifier-names-generators/DictionaryIdentifierNamesGenerator';
import { HexadecimalIdentifierNamesGenerator } from '../../../generators/identifier-names-generators/HexadecimalIdentifierNamesGenerator';
import { MangledIdentifierNamesGenerator } from '../../../generators/identifier-names-generators/MangledIdentifierNamesGenerator';
import { MangledShuffledIdentifierNamesGenerator } from '../../../generators/identifier-names-generators/MangledShuffledIdentifierNamesGenerator';
export const generatorsModule: interfaces.ContainerModule = new ContainerModule((bind: interfaces.Bind) => {
// identifier name generators
bind<IIdentifierNamesGenerator>(ServiceIdentifiers.IIdentifierNamesGenerator)
.to(DictionaryIdentifierNamesGenerator)
.inSingletonScope()
.whenTargetNamed(IdentifierNamesGenerator.DictionaryIdentifierNamesGenerator);
bind<IIdentifierNamesGenerator>(ServiceIdentifiers.IIdentifierNamesGenerator)
.to(HexadecimalIdentifierNamesGenerator)
.inSingletonScope()
.whenTargetNamed(IdentifierNamesGenerator.HexadecimalIdentifierNamesGenerator);
bind<IIdentifierNamesGenerator>(ServiceIdentifiers.IIdentifierNamesGenerator)
.to(MangledIdentifierNamesGenerator)
.inSingletonScope()
.whenTargetNamed(IdentifierNamesGenerator.MangledIdentifierNamesGenerator);
bind<IIdentifierNamesGenerator>(ServiceIdentifiers.IIdentifierNamesGenerator)
.to(MangledShuffledIdentifierNamesGenerator)
.inSingletonScope()
.whenTargetNamed(IdentifierNamesGenerator.MangledShuffledIdentifierNamesGenerator);
// identifier name generator factory
function identifierNameGeneratorFactory (): (context: interfaces.Context) => (options: IOptions) => IIdentifierNamesGenerator {
let cachedIdentifierNamesGenerator: IIdentifierNamesGenerator | null = null;
return (context: interfaces.Context): (options: IOptions) => IIdentifierNamesGenerator => (options: IOptions): IIdentifierNamesGenerator => {
if (cachedIdentifierNamesGenerator) {
return cachedIdentifierNamesGenerator;
}
let identifierNamesGenerator: IIdentifierNamesGenerator;
switch (options.identifierNamesGenerator) {
case IdentifierNamesGenerator.DictionaryIdentifierNamesGenerator:
identifierNamesGenerator = context.container.getNamed<IIdentifierNamesGenerator>(
ServiceIdentifiers.IIdentifierNamesGenerator,
IdentifierNamesGenerator.DictionaryIdentifierNamesGenerator
);
break;
case IdentifierNamesGenerator.MangledIdentifierNamesGenerator:
identifierNamesGenerator = context.container.getNamed<IIdentifierNamesGenerator>(
ServiceIdentifiers.IIdentifierNamesGenerator,
IdentifierNamesGenerator.MangledIdentifierNamesGenerator
);
break;
case IdentifierNamesGenerator.MangledShuffledIdentifierNamesGenerator:
identifierNamesGenerator = context.container.getNamed<IIdentifierNamesGenerator>(
ServiceIdentifiers.IIdentifierNamesGenerator,
IdentifierNamesGenerator.MangledShuffledIdentifierNamesGenerator
);
break;
case IdentifierNamesGenerator.HexadecimalIdentifierNamesGenerator:
default:
identifierNamesGenerator = context.container.getNamed<IIdentifierNamesGenerator>(
ServiceIdentifiers.IIdentifierNamesGenerator,
IdentifierNamesGenerator.HexadecimalIdentifierNamesGenerator
);
}
cachedIdentifierNamesGenerator = identifierNamesGenerator;
return identifierNamesGenerator;
};
}
bind<IIdentifierNamesGenerator>(ServiceIdentifiers.Factory__IIdentifierNamesGenerator)
.toFactory<IIdentifierNamesGenerator>(identifierNameGeneratorFactory());
});
@@ -0,0 +1,49 @@
import { InversifyContainerFacade } from '../../InversifyContainerFacade';
import { ContainerModule, interfaces } from 'inversify';
import { ServiceIdentifiers } from '../../ServiceIdentifiers';
import { IControlFlowReplacer } from '../../../interfaces/node-transformers/control-flow-transformers/IControlFlowReplacer';
import { INodeTransformer } from '../../../interfaces/node-transformers/INodeTransformer';
import { ControlFlowReplacer } from '../../../enums/node-transformers/control-flow-transformers/control-flow-replacers/ControlFlowReplacer';
import { NodeTransformer } from '../../../enums/node-transformers/NodeTransformer';
import { BinaryExpressionControlFlowReplacer } from '../../../node-transformers/control-flow-transformers/control-flow-replacers/BinaryExpressionControlFlowReplacer';
import { BlockStatementControlFlowTransformer } from '../../../node-transformers/control-flow-transformers/BlockStatementControlFlowTransformer';
import { CallExpressionControlFlowReplacer } from '../../../node-transformers/control-flow-transformers/control-flow-replacers/CallExpressionControlFlowReplacer';
import { FunctionControlFlowTransformer } from '../../../node-transformers/control-flow-transformers/FunctionControlFlowTransformer';
import { LogicalExpressionControlFlowReplacer } from '../../../node-transformers/control-flow-transformers/control-flow-replacers/LogicalExpressionControlFlowReplacer';
import { StringLiteralControlFlowReplacer } from '../../../node-transformers/control-flow-transformers/control-flow-replacers/StringLiteralControlFlowReplacer';
export const controlFlowTransformersModule: interfaces.ContainerModule = new ContainerModule((bind: interfaces.Bind) => {
// control flow transformers
bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
.to(BlockStatementControlFlowTransformer)
.whenTargetNamed(NodeTransformer.BlockStatementControlFlowTransformer);
bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
.to(FunctionControlFlowTransformer)
.whenTargetNamed(NodeTransformer.FunctionControlFlowTransformer);
// control flow replacers
bind<IControlFlowReplacer>(ServiceIdentifiers.IControlFlowReplacer)
.to(BinaryExpressionControlFlowReplacer)
.whenTargetNamed(ControlFlowReplacer.BinaryExpressionControlFlowReplacer);
bind<IControlFlowReplacer>(ServiceIdentifiers.IControlFlowReplacer)
.to(CallExpressionControlFlowReplacer)
.whenTargetNamed(ControlFlowReplacer.CallExpressionControlFlowReplacer);
bind<IControlFlowReplacer>(ServiceIdentifiers.IControlFlowReplacer)
.to(LogicalExpressionControlFlowReplacer)
.whenTargetNamed(ControlFlowReplacer.LogicalExpressionControlFlowReplacer);
bind<IControlFlowReplacer>(ServiceIdentifiers.IControlFlowReplacer)
.to(StringLiteralControlFlowReplacer)
.whenTargetNamed(ControlFlowReplacer.StringLiteralControlFlowReplacer);
// control flow replacer factory
bind<IControlFlowReplacer>(ServiceIdentifiers.Factory__IControlFlowReplacer)
.toFactory<IControlFlowReplacer>(InversifyContainerFacade
.getCacheFactory<ControlFlowReplacer, IControlFlowReplacer>(ServiceIdentifiers.IControlFlowReplacer));
});
@@ -0,0 +1,86 @@
import { ContainerModule, interfaces } from 'inversify';
import { InversifyContainerFacade } from '../../InversifyContainerFacade';
import { ServiceIdentifiers } from '../../ServiceIdentifiers';
import { INodeTransformer } from '../../../interfaces/node-transformers/INodeTransformer';
import { IObjectExpressionExtractor } from '../../../interfaces/node-transformers/converting-transformers/object-expression-extractors/IObjectExpressionExtractor';
import { NodeTransformer } from '../../../enums/node-transformers/NodeTransformer';
import { ObjectExpressionExtractor } from '../../../enums/node-transformers/converting-transformers/properties-extractors/ObjectExpressionExtractor';
import { BasePropertiesExtractor } from '../../../node-transformers/converting-transformers/object-expression-extractors/BasePropertiesExtractor';
import { BooleanLiteralTransformer } from '../../../node-transformers/converting-transformers/BooleanLiteralTransformer';
import { ExportSpecifierTransformer } from '../../../node-transformers/converting-transformers/ExportSpecifierTransformer';
import { MemberExpressionTransformer } from '../../../node-transformers/converting-transformers/MemberExpressionTransformer';
import { MethodDefinitionTransformer } from '../../../node-transformers/converting-transformers/MethodDefinitionTransformer';
import { NumberLiteralTransformer } from '../../../node-transformers/converting-transformers/NumberLiteralTransformer';
import { NumberToNumericalExpressionTransformer } from '../../../node-transformers/converting-transformers/NumberToNumericalExpressionTransformer';
import { ObjectExpressionKeysTransformer } from '../../../node-transformers/converting-transformers/ObjectExpressionKeysTransformer';
import { ObjectExpressionToVariableDeclarationExtractor } from '../../../node-transformers/converting-transformers/object-expression-extractors/ObjectExpressionToVariableDeclarationExtractor';
import { ObjectExpressionTransformer } from '../../../node-transformers/converting-transformers/ObjectExpressionTransformer';
import { ObjectPatternPropertiesTransformer } from '../../../node-transformers/converting-transformers/ObjectPatternPropertiesTransformer';
import { SplitStringTransformer } from '../../../node-transformers/converting-transformers/SplitStringTransformer';
import { TemplateLiteralTransformer } from '../../../node-transformers/converting-transformers/TemplateLiteralTransformer';
export const convertingTransformersModule: interfaces.ContainerModule = new ContainerModule((bind: interfaces.Bind) => {
// converting transformers
bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
.to(BooleanLiteralTransformer)
.whenTargetNamed(NodeTransformer.BooleanLiteralTransformer);
bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
.to(ExportSpecifierTransformer)
.whenTargetNamed(NodeTransformer.ExportSpecifierTransformer);
bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
.to(MemberExpressionTransformer)
.whenTargetNamed(NodeTransformer.MemberExpressionTransformer);
bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
.to(MethodDefinitionTransformer)
.whenTargetNamed(NodeTransformer.MethodDefinitionTransformer);
bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
.to(NumberLiteralTransformer)
.whenTargetNamed(NodeTransformer.NumberLiteralTransformer);
bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
.to(NumberToNumericalExpressionTransformer)
.whenTargetNamed(NodeTransformer.NumberToNumericalExpressionTransformer);
bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
.to(ObjectExpressionKeysTransformer)
.whenTargetNamed(NodeTransformer.ObjectExpressionKeysTransformer);
bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
.to(ObjectExpressionTransformer)
.whenTargetNamed(NodeTransformer.ObjectExpressionTransformer);
bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
.to(ObjectPatternPropertiesTransformer)
.whenTargetNamed(NodeTransformer.ObjectPatternPropertiesTransformer);
bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
.to(SplitStringTransformer)
.whenTargetNamed(NodeTransformer.SplitStringTransformer);
bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
.to(TemplateLiteralTransformer)
.whenTargetNamed(NodeTransformer.TemplateLiteralTransformer);
// object expression extractors
bind<IObjectExpressionExtractor>(ServiceIdentifiers.IObjectExpressionExtractor)
.to(ObjectExpressionToVariableDeclarationExtractor)
.whenTargetNamed(ObjectExpressionExtractor.ObjectExpressionToVariableDeclarationExtractor);
bind<IObjectExpressionExtractor>(ServiceIdentifiers.IObjectExpressionExtractor)
.to(BasePropertiesExtractor)
.whenTargetNamed(ObjectExpressionExtractor.BasePropertiesExtractor);
// object expression extractor factory
bind<IObjectExpressionExtractor>(ServiceIdentifiers.Factory__IObjectExpressionExtractor)
.toFactory<IObjectExpressionExtractor>(InversifyContainerFacade
.getCacheFactory<ObjectExpressionExtractor, IObjectExpressionExtractor>(
ServiceIdentifiers.IObjectExpressionExtractor
));
});
@@ -0,0 +1,15 @@
import { ContainerModule, interfaces } from 'inversify';
import { ServiceIdentifiers } from '../../ServiceIdentifiers';
import { INodeTransformer } from '../../../interfaces/node-transformers/INodeTransformer';
import { NodeTransformer } from '../../../enums/node-transformers/NodeTransformer';
import { DeadCodeInjectionTransformer } from '../../../node-transformers/dead-code-injection-transformers/DeadCodeInjectionTransformer';
export const deadCodeInjectionTransformersModule: interfaces.ContainerModule = new ContainerModule((bind: interfaces.Bind) => {
// dead code injection
bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
.to(DeadCodeInjectionTransformer)
.whenTargetNamed(NodeTransformer.DeadCodeInjectionTransformer);
});
@@ -0,0 +1,15 @@
import { ContainerModule, interfaces } from 'inversify';
import { ServiceIdentifiers } from '../../ServiceIdentifiers';
import { INodeTransformer } from '../../../interfaces/node-transformers/INodeTransformer';
import { NodeTransformer } from '../../../enums/node-transformers/NodeTransformer';
import { EscapeSequenceTransformer } from '../../../node-transformers/finalizing-transformers/EscapeSequenceTransformer';
export const finalizingTransformersModule: interfaces.ContainerModule = new ContainerModule((bind: interfaces.Bind) => {
// finalizing transformers
bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
.to(EscapeSequenceTransformer)
.whenTargetNamed(NodeTransformer.EscapeSequenceTransformer);
});
@@ -0,0 +1,15 @@
import { ContainerModule, interfaces } from 'inversify';
import { ServiceIdentifiers } from '../../ServiceIdentifiers';
import { INodeTransformer } from '../../../interfaces/node-transformers/INodeTransformer';
import { NodeTransformer } from '../../../enums/node-transformers/NodeTransformer';
import { CommentsTransformer } from '../../../node-transformers/initializing-transformers/CommentsTransformer';
export const initializingTransformersModule: interfaces.ContainerModule = new ContainerModule((bind: interfaces.Bind) => {
// preparing transformers
bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
.to(CommentsTransformer)
.whenTargetNamed(NodeTransformer.CommentsTransformer);
});
@@ -0,0 +1,22 @@
import { InversifyContainerFacade } from '../../InversifyContainerFacade';
import { ContainerModule, interfaces } from 'inversify';
import { ServiceIdentifiers } from '../../ServiceIdentifiers';
import { INodeTransformer } from '../../../interfaces/node-transformers/INodeTransformer';
import { ITransformerNamesGroupsBuilder } from '../../../interfaces/utils/ITransformerNamesGroupsBuilder';
import { NodeTransformer } from '../../../enums/node-transformers/NodeTransformer';
import { NodeTransformerNamesGroupsBuilder } from '../../../node-transformers/NodeTransformerNamesGroupsBuilder';
export const nodeTransformersModule: interfaces.ContainerModule = new ContainerModule((bind: interfaces.Bind) => {
// node transformers factory
bind<INodeTransformer>(ServiceIdentifiers.Factory__INodeTransformer)
.toFactory<INodeTransformer>(InversifyContainerFacade
.getCacheFactory<NodeTransformer, INodeTransformer>(ServiceIdentifiers.INodeTransformer));
// node transformer names groups builder
bind<ITransformerNamesGroupsBuilder<NodeTransformer, INodeTransformer>>(ServiceIdentifiers.INodeTransformerNamesGroupsBuilder)
.to(NodeTransformerNamesGroupsBuilder)
.inSingletonScope();
});
@@ -0,0 +1,81 @@
import { InversifyContainerFacade } from '../../InversifyContainerFacade';
import { ContainerModule, interfaces } from 'inversify';
import { ServiceIdentifiers } from '../../ServiceIdentifiers';
import { INodeTransformer } from '../../../interfaces/node-transformers/INodeTransformer';
import { IObfuscatingGuard } from '../../../interfaces/node-transformers/preparing-transformers/obfuscating-guards/IObfuscatingGuard';
import { NodeTransformer } from '../../../enums/node-transformers/NodeTransformer';
import { ObfuscatingGuard } from '../../../enums/node-transformers/preparing-transformers/obfuscating-guards/ObfuscatingGuard';
import { BlackListObfuscatingGuard } from '../../../node-transformers/preparing-transformers/obfuscating-guards/BlackListObfuscatingGuard';
import { ConditionalCommentObfuscatingGuard } from '../../../node-transformers/preparing-transformers/obfuscating-guards/ConditionalCommentObfuscatingGuard';
import { CustomCodeHelpersTransformer } from '../../../node-transformers/preparing-transformers/CustomCodeHelpersTransformer';
import { EvalCallExpressionTransformer } from '../../../node-transformers/preparing-transformers/EvalCallExpressionTransformer';
import { ForceTransformStringObfuscatingGuard } from '../../../node-transformers/preparing-transformers/obfuscating-guards/ForceTransformStringObfuscatingGuard';
import { IgnoredRequireImportObfuscatingGuard } from '../../../node-transformers/preparing-transformers/obfuscating-guards/IgnoredRequireImportObfuscatingGuard';
import { MetadataTransformer } from '../../../node-transformers/preparing-transformers/MetadataTransformer';
import { ObfuscatingGuardsTransformer } from '../../../node-transformers/preparing-transformers/ObfuscatingGuardsTransformer';
import { ParentificationTransformer } from '../../../node-transformers/preparing-transformers/ParentificationTransformer';
import { ReservedStringObfuscatingGuard } from '../../../node-transformers/preparing-transformers/obfuscating-guards/ReservedStringObfuscatingGuard';
import { VariablePreserveTransformer } from '../../../node-transformers/preparing-transformers/VariablePreserveTransformer';
export const preparingTransformersModule: interfaces.ContainerModule = new ContainerModule((bind: interfaces.Bind) => {
// preparing transformers
bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
.to(CustomCodeHelpersTransformer)
.whenTargetNamed(NodeTransformer.CustomCodeHelpersTransformer);
bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
.to(EvalCallExpressionTransformer)
.whenTargetNamed(NodeTransformer.EvalCallExpressionTransformer);
bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
.to(MetadataTransformer)
.whenTargetNamed(NodeTransformer.MetadataTransformer);
bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
.to(ObfuscatingGuardsTransformer)
.whenTargetNamed(NodeTransformer.ObfuscatingGuardsTransformer);
bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
.to(ParentificationTransformer)
.whenTargetNamed(NodeTransformer.ParentificationTransformer);
bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
.to(VariablePreserveTransformer)
.whenTargetNamed(NodeTransformer.VariablePreserveTransformer);
// obfuscating guards
bind<IObfuscatingGuard>(ServiceIdentifiers.INodeGuard)
.to(BlackListObfuscatingGuard)
.inSingletonScope()
.whenTargetNamed(ObfuscatingGuard.BlackListObfuscatingGuard);
bind<IObfuscatingGuard>(ServiceIdentifiers.INodeGuard)
.to(ConditionalCommentObfuscatingGuard)
.inSingletonScope()
.whenTargetNamed(ObfuscatingGuard.ConditionalCommentObfuscatingGuard);
bind<IObfuscatingGuard>(ServiceIdentifiers.INodeGuard)
.to(ForceTransformStringObfuscatingGuard)
.inSingletonScope()
.whenTargetNamed(ObfuscatingGuard.ForceTransformStringObfuscatingGuard);
bind<IObfuscatingGuard>(ServiceIdentifiers.INodeGuard)
.to(IgnoredRequireImportObfuscatingGuard)
.inSingletonScope()
.whenTargetNamed(ObfuscatingGuard.IgnoredRequireImportObfuscatingGuard);
bind<IObfuscatingGuard>(ServiceIdentifiers.INodeGuard)
.to(ReservedStringObfuscatingGuard)
.inSingletonScope()
.whenTargetNamed(ObfuscatingGuard.ReservedStringObfuscatingGuard);
// obfuscating guards factory
bind<IObfuscatingGuard>(ServiceIdentifiers.Factory__INodeGuard)
.toFactory<IObfuscatingGuard>(InversifyContainerFacade
.getCacheFactory<ObfuscatingGuard, IObfuscatingGuard>(
ServiceIdentifiers.INodeGuard
));
});
@@ -0,0 +1,32 @@
import { ContainerModule, interfaces } from 'inversify';
import { ServiceIdentifiers } from '../../ServiceIdentifiers';
import { IIdentifierReplacer } from '../../../interfaces/node-transformers/rename-identifiers-transformers/replacer/IIdentifierReplacer';
import { INodeTransformer } from '../../../interfaces/node-transformers/INodeTransformer';
import { NodeTransformer } from '../../../enums/node-transformers/NodeTransformer';
import { IdentifierReplacer } from '../../../node-transformers/rename-identifiers-transformers/replacer/IdentifierReplacer';
import { LabeledStatementTransformer } from '../../../node-transformers/rename-identifiers-transformers/LabeledStatementTransformer';
import { ScopeIdentifiersTransformer } from '../../../node-transformers/rename-identifiers-transformers/ScopeIdentifiersTransformer';
import { ScopeThroughIdentifiersTransformer } from '../../../node-transformers/rename-identifiers-transformers/ScopeThroughIdentifiersTransformer';
export const renameIdentifiersTransformersModule: interfaces.ContainerModule = new ContainerModule((bind: interfaces.Bind) => {
// rename identifiers transformers
bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
.to(LabeledStatementTransformer)
.whenTargetNamed(NodeTransformer.LabeledStatementTransformer);
bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
.to(ScopeIdentifiersTransformer)
.whenTargetNamed(NodeTransformer.ScopeIdentifiersTransformer);
bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
.to(ScopeThroughIdentifiersTransformer)
.whenTargetNamed(NodeTransformer.ScopeThroughIdentifiersTransformer);
// identifier replacer
bind<IIdentifierReplacer>(ServiceIdentifiers.IIdentifierReplacer)
.to(IdentifierReplacer)
.inSingletonScope();
});
@@ -0,0 +1,21 @@
import { ContainerModule, interfaces } from 'inversify';
import { ServiceIdentifiers } from '../../ServiceIdentifiers';
import { IRenamePropertiesReplacer } from '../../../interfaces/node-transformers/rename-properties-transformers/replacer/IRenamePropertiesReplacer';
import { INodeTransformer } from '../../../interfaces/node-transformers/INodeTransformer';
import { NodeTransformer } from '../../../enums/node-transformers/NodeTransformer';
import { RenamePropertiesReplacer } from '../../../node-transformers/rename-properties-transformers/replacer/RenamePropertiesReplacer';
import { RenamePropertiesTransformer } from '../../../node-transformers/rename-properties-transformers/RenamePropertiesTransformer';
export const renamePropertiesTransformersModule: interfaces.ContainerModule = new ContainerModule((bind: interfaces.Bind) => {
// rename properties transformers
bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
.to(RenamePropertiesTransformer)
.whenTargetNamed(NodeTransformer.RenamePropertiesTransformer);
// rename properties obfuscating replacer
bind<IRenamePropertiesReplacer>(ServiceIdentifiers.IRenamePropertiesReplacer)
.to(RenamePropertiesReplacer);
});
@@ -0,0 +1,30 @@
import { ContainerModule, interfaces } from 'inversify';
import { ServiceIdentifiers } from '../../ServiceIdentifiers';
import { INodeTransformer } from '../../../interfaces/node-transformers/INodeTransformer';
import { NodeTransformer } from '../../../enums/node-transformers/NodeTransformer';
import { BlockStatementSimplifyTransformer } from '../../../node-transformers/simplifying-transformers/BlockStatementSimplifyTransformer';
import { ExpressionStatementsMergeTransformer } from '../../../node-transformers/simplifying-transformers/ExpressionStatementsMergeTransformer';
import { IfStatementSimplifyTransformer } from '../../../node-transformers/simplifying-transformers/IfStatementSimplifyTransformer';
import { VariableDeclarationsMergeTransformer } from '../../../node-transformers/simplifying-transformers/VariableDeclarationsMergeTransformer';
export const simplifyingTransformersModule: interfaces.ContainerModule = new ContainerModule((bind: interfaces.Bind) => {
// simplifying transformers
bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
.to(BlockStatementSimplifyTransformer)
.whenTargetNamed(NodeTransformer.BlockStatementSimplifyTransformer);
bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
.to(ExpressionStatementsMergeTransformer)
.whenTargetNamed(NodeTransformer.ExpressionStatementsMergeTransformer);
bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
.to(IfStatementSimplifyTransformer)
.whenTargetNamed(NodeTransformer.IfStatementSimplifyTransformer);
bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
.to(VariableDeclarationsMergeTransformer)
.whenTargetNamed(NodeTransformer.VariableDeclarationsMergeTransformer);
});
@@ -0,0 +1,20 @@
import { ContainerModule, interfaces } from 'inversify';
import { ServiceIdentifiers } from '../../ServiceIdentifiers';
import { INodeTransformer } from '../../../interfaces/node-transformers/INodeTransformer';
import { NodeTransformer } from '../../../enums/node-transformers/NodeTransformer';
import { StringArrayScopeCallsWrapperTransformer } from '../../../node-transformers/string-array-transformers/StringArrayScopeCallsWrapperTransformer';
import { StringArrayTransformer } from '../../../node-transformers/string-array-transformers/StringArrayTransformer';
export const stringArrayTransformersModule: interfaces.ContainerModule = new ContainerModule((bind: interfaces.Bind) => {
// strings transformers
bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
.to(StringArrayScopeCallsWrapperTransformer)
.whenTargetNamed(NodeTransformer.StringArrayScopeCallsWrapperTransformer);
bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
.to(StringArrayTransformer)
.whenTargetNamed(NodeTransformer.StringArrayTransformer);
});
@@ -0,0 +1,13 @@
import { ContainerModule, interfaces } from 'inversify';
import { ServiceIdentifiers } from '../../ServiceIdentifiers';
import { IScopeIdentifiersTraverser } from '../../../interfaces/node/IScopeIdentifiersTraverser';
import { ScopeIdentifiersTraverser } from '../../../node/ScopeIdentifiersTraverser';
export const nodeModule: interfaces.ContainerModule = new ContainerModule((bind: interfaces.Bind) => {
// scope identifiers traverser
bind<IScopeIdentifiersTraverser>(ServiceIdentifiers.IScopeIdentifiersTraverser)
.to(ScopeIdentifiersTraverser)
.inSingletonScope();
});
@@ -0,0 +1,18 @@
import { ContainerModule, interfaces } from 'inversify';
import { ServiceIdentifiers } from '../../ServiceIdentifiers';
import { IOptions } from '../../../interfaces/options/IOptions';
import { IOptionsNormalizer } from '../../../interfaces/options/IOptionsNormalizer';
import { Options } from '../../../options/Options';
import { OptionsNormalizer } from '../../../options/OptionsNormalizer';
export const optionsModule: interfaces.ContainerModule = new ContainerModule((bind: interfaces.Bind) => {
bind<IOptions>(ServiceIdentifiers.IOptions)
.to(Options)
.inSingletonScope();
bind<IOptionsNormalizer>(ServiceIdentifiers.IOptionsNormalizer)
.to(OptionsNormalizer)
.inSingletonScope();
});
@@ -0,0 +1,70 @@
import { ContainerModule, interfaces } from 'inversify';
import { ServiceIdentifiers } from '../../ServiceIdentifiers';
import { TControlFlowStorage } from '../../../types/storages/TControlFlowStorage';
import { TCustomCodeHelperGroupStorage } from '../../../types/storages/TCustomCodeHelperGroupStorage';
import { ILiteralNodesCacheStorage } from '../../../interfaces/storages/string-array-transformers/ILiteralNodesCacheStorage';
import { IOptions } from '../../../interfaces/options/IOptions';
import { IRandomGenerator } from '../../../interfaces/utils/IRandomGenerator';
import { IStringArrayScopeCallsWrapperLexicalScopeDataStorage } from '../../../interfaces/storages/string-array-transformers/IStringArrayScopeCallsWrapperLexicalScopeDataStorage';
import { IStringArrayScopeCallsWrapperNamesDataStorage } from '../../../interfaces/storages/string-array-transformers/IStringArrayScopeCallsWrapperNamesDataStorage';
import { IStringArrayStorage } from '../../../interfaces/storages/string-array-transformers/IStringArrayStorage';
import { IVisitedLexicalScopeNodesStackStorage } from '../../../interfaces/storages/string-array-transformers/IVisitedLexicalScopeNodesStackStorage';
import { ControlFlowStorage } from '../../../storages/custom-nodes/ControlFlowStorage';
import { CustomCodeHelperGroupStorage } from '../../../storages/custom-code-helpers/CustomCodeHelperGroupStorage';
import { LiteralNodesCacheStorage } from '../../../storages/string-array-transformers/LiteralNodesCacheStorage';
import { StringArrayScopeCallsWrapperLexicalScopeDataStorage } from '../../../storages/string-array-transformers/StringArrayScopeCallsWrapperLexicalScopeDataStorage';
import { StringArrayScopeCallsWrapperNamesDataStorage } from '../../../storages/string-array-transformers/StringArrayScopeCallsWrapperNamesDataStorage';
import { StringArrayStorage } from '../../../storages/string-array-transformers/StringArrayStorage';
import { VisitedLexicalScopeNodesStackStorage } from '../../../storages/string-array-transformers/VisitedLexicalScopeNodesStackStorage';
export const storagesModule: interfaces.ContainerModule = new ContainerModule((bind: interfaces.Bind) => {
// storages
bind<TCustomCodeHelperGroupStorage>(ServiceIdentifiers.TCustomNodeGroupStorage)
.to(CustomCodeHelperGroupStorage)
.inSingletonScope();
bind<ILiteralNodesCacheStorage>(ServiceIdentifiers.ILiteralNodesCacheStorage)
.to(LiteralNodesCacheStorage)
.inSingletonScope();
bind<IStringArrayStorage>(ServiceIdentifiers.IStringArrayStorage)
.to(StringArrayStorage)
.inSingletonScope();
bind<IStringArrayScopeCallsWrapperLexicalScopeDataStorage>(ServiceIdentifiers.IStringArrayScopeCallsWrapperLexicalScopeDataStorage)
.to(StringArrayScopeCallsWrapperLexicalScopeDataStorage)
.inSingletonScope();
bind<IStringArrayScopeCallsWrapperNamesDataStorage>(ServiceIdentifiers.IStringArrayScopeCallsWrapperNamesDataStorage)
.to(StringArrayScopeCallsWrapperNamesDataStorage)
.inSingletonScope();
bind<IVisitedLexicalScopeNodesStackStorage>(ServiceIdentifiers.IVisitedLexicalScopeNodesStackStorage)
.to(VisitedLexicalScopeNodesStackStorage)
.inSingletonScope();
bind<interfaces.Newable<TControlFlowStorage>>(ServiceIdentifiers.Newable__TControlFlowStorage)
.toConstructor(ControlFlowStorage);
// controlFlowStorage factory
bind<TControlFlowStorage>(ServiceIdentifiers.Factory__TControlFlowStorage)
.toFactory<TControlFlowStorage>((context: interfaces.Context) => {
return (): TControlFlowStorage => {
const constructor: interfaces.Newable<TControlFlowStorage> = context.container
.get<interfaces.Newable<TControlFlowStorage>>(ServiceIdentifiers.Newable__TControlFlowStorage);
const randomGenerator: IRandomGenerator = context.container
.get<IRandomGenerator>(ServiceIdentifiers.IRandomGenerator);
const options: IOptions = context.container
.get<IOptions>(ServiceIdentifiers.IOptions);
const storage: TControlFlowStorage = new constructor(randomGenerator, options);
storage.initialize();
return storage;
};
});
});
@@ -0,0 +1,47 @@
import { ContainerModule, interfaces } from 'inversify';
import { ServiceIdentifiers } from '../../ServiceIdentifiers';
import { IArrayUtils } from '../../../interfaces/utils/IArrayUtils';
import { ICryptUtils } from '../../../interfaces/utils/ICryptUtils';
import { ICryptUtilsSwappedAlphabet } from '../../../interfaces/utils/ICryptUtilsSwappedAlphabet';
import { IEscapeSequenceEncoder } from '../../../interfaces/utils/IEscapeSequenceEncoder';
import { ILevelledTopologicalSorter } from '../../../interfaces/utils/ILevelledTopologicalSorter';
import { IRandomGenerator } from '../../../interfaces/utils/IRandomGenerator';
import { ArrayUtils } from '../../../utils/ArrayUtils';
import { CryptUtils } from '../../../utils/CryptUtils';
import { CryptUtilsSwappedAlphabet } from '../../../utils/CryptUtilsSwappedAlphabet';
import { EscapeSequenceEncoder } from '../../../utils/EscapeSequenceEncoder';
import { LevelledTopologicalSorter } from '../../../utils/LevelledTopologicalSorter';
import { RandomGenerator } from '../../../utils/RandomGenerator';
export const utilsModule: interfaces.ContainerModule = new ContainerModule((bind: interfaces.Bind) => {
// array utils
bind<IArrayUtils>(ServiceIdentifiers.IArrayUtils)
.to(ArrayUtils)
.inSingletonScope();
// random generator
bind<IRandomGenerator>(ServiceIdentifiers.IRandomGenerator)
.to(RandomGenerator)
.inSingletonScope();
// crypt utils
bind<ICryptUtils>(ServiceIdentifiers.ICryptUtils)
.to(CryptUtils)
.inSingletonScope();
// crypt utils with swapped alphabet
bind<ICryptUtilsSwappedAlphabet>(ServiceIdentifiers.ICryptUtilsSwappedAlphabet)
.to(CryptUtilsSwappedAlphabet)
.inSingletonScope();
// escape sequence encoder
bind<IEscapeSequenceEncoder>(ServiceIdentifiers.IEscapeSequenceEncoder)
.to(EscapeSequenceEncoder)
.inSingletonScope();
// levelled topological sorter
bind<ILevelledTopologicalSorter>(ServiceIdentifiers.ILevelledTopologicalSorter)
.to(LevelledTopologicalSorter);
});
@@ -0,0 +1,121 @@
import { inject, injectable } from 'inversify';
import { ServiceIdentifiers } from '../container/ServiceIdentifiers';
import { TIdentifierNamesGeneratorFactory } from '../types/container/generators/TIdentifierNamesGeneratorFactory';
import { TStatement } from '../types/node/TStatement';
import { ICustomCodeHelper } from '../interfaces/custom-code-helpers/ICustomCodeHelper';
import { ICustomCodeHelperFormatter } from '../interfaces/custom-code-helpers/ICustomCodeHelperFormatter';
import { ICustomCodeHelperObfuscator } from '../interfaces/custom-code-helpers/ICustomCodeHelperObfuscator';
import { IIdentifierNamesGenerator } from '../interfaces/generators/identifier-names-generators/IIdentifierNamesGenerator';
import { IOptions } from '../interfaces/options/IOptions';
import { IRandomGenerator } from '../interfaces/utils/IRandomGenerator';
import { GlobalVariableTemplate1 } from './common/templates/GlobalVariableTemplate1';
import { GlobalVariableTemplate2 } from './common/templates/GlobalVariableTemplate2';
@injectable()
export abstract class AbstractCustomCodeHelper <
TInitialData extends unknown[] = unknown[]
> implements ICustomCodeHelper <TInitialData> {
/**
* @type {string[]}
*/
private static readonly globalVariableTemplateFunctions: string[] = [
GlobalVariableTemplate1(),
GlobalVariableTemplate2()
];
/**
* @type {TStatement[] | null}
*/
protected cachedNode: TStatement[] | null = null;
/**
* @type {ICustomCodeHelperFormatter}
*/
protected readonly customCodeHelperFormatter: ICustomCodeHelperFormatter;
/**
* @type {ICustomCodeHelperObfuscator}
*/
protected readonly customCodeHelperObfuscator: ICustomCodeHelperObfuscator;
/**
* @type {IIdentifierNamesGenerator}
*/
protected readonly identifierNamesGenerator: IIdentifierNamesGenerator;
/**
* @type {IOptions}
*/
protected readonly options: IOptions;
/**
* @type {IRandomGenerator}
*/
protected readonly randomGenerator: IRandomGenerator;
/**
* @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
* @param {ICustomCodeHelperFormatter} customCodeHelperFormatter
* @param {ICustomCodeHelperObfuscator} customCodeHelperObfuscator
* @param {IRandomGenerator} randomGenerator
* @param {IOptions} options
*/
protected constructor (
@inject(ServiceIdentifiers.Factory__IIdentifierNamesGenerator)
identifierNamesGeneratorFactory: TIdentifierNamesGeneratorFactory,
@inject(ServiceIdentifiers.ICustomCodeHelperFormatter) customCodeHelperFormatter: ICustomCodeHelperFormatter,
@inject(ServiceIdentifiers.ICustomCodeHelperObfuscator) customCodeHelperObfuscator: ICustomCodeHelperObfuscator,
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
this.identifierNamesGenerator = identifierNamesGeneratorFactory(options);
this.customCodeHelperFormatter = customCodeHelperFormatter;
this.customCodeHelperObfuscator = customCodeHelperObfuscator;
this.randomGenerator = randomGenerator;
this.options = options;
}
/**
* @returns {TStatement[]}
*/
public getNode (): TStatement[] {
if (!this.cachedNode) {
const codeHelperTemplate: string = this.getCodeHelperTemplate();
this.cachedNode = this.customCodeHelperFormatter.formatStructure(
this.getNodeStructure(codeHelperTemplate)
);
}
return this.cachedNode;
}
/**
* @returns {string}
*/
protected getGlobalVariableTemplate (): string {
return this.randomGenerator
.getRandomGenerator()
.pickone(AbstractCustomCodeHelper.globalVariableTemplateFunctions);
}
/**
* @returns {string}
*/
protected getCodeHelperTemplate (): string {
return '';
}
/**
* @param {TInitialData} args
*/
public abstract initialize (...args: TInitialData): void;
/**
* @returns {TStatement[]}
*/
protected abstract getNodeStructure (codeHelperTemplate: string): TStatement[];
}
@@ -0,0 +1,104 @@
import { inject, injectable } from 'inversify';
import { ServiceIdentifiers } from '../container/ServiceIdentifiers';
import { TIdentifierNamesGeneratorFactory } from '../types/container/generators/TIdentifierNamesGeneratorFactory';
import { TNodeWithStatements } from '../types/node/TNodeWithStatements';
import { ICallsGraphData } from '../interfaces/analyzers/calls-graph-analyzer/ICallsGraphData';
import { ICustomCodeHelper } from '../interfaces/custom-code-helpers/ICustomCodeHelper';
import { ICustomCodeHelperGroup } from '../interfaces/custom-code-helpers/ICustomCodeHelperGroup';
import { IIdentifierNamesGenerator } from '../interfaces/generators/identifier-names-generators/IIdentifierNamesGenerator';
import { IOptions } from '../interfaces/options/IOptions';
import { IRandomGenerator } from '../interfaces/utils/IRandomGenerator';
import { CustomCodeHelper } from '../enums/custom-code-helpers/CustomCodeHelper';
import { ObfuscationEvent } from '../enums/event-emitters/ObfuscationEvent';
@injectable()
export abstract class AbstractCustomCodeHelperGroup implements ICustomCodeHelperGroup {
/**
* @type {IIdentifierNamesGenerator}
*/
protected readonly identifierNamesGenerator: IIdentifierNamesGenerator;
/**
* @type {IOptions}
*/
protected readonly options: IOptions;
/**
* @type {IRandomGenerator}
*/
protected readonly randomGenerator: IRandomGenerator;
/**
* @type {ObfuscationEvent}
*/
protected abstract readonly appendEvent: ObfuscationEvent;
/**
* @type {Map<CustomCodeHelper, ICustomCodeHelper>}
*/
protected abstract customCodeHelpers: Map <CustomCodeHelper, ICustomCodeHelper>;
/**
* @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
* @param {IRandomGenerator} randomGenerator
* @param {IOptions} options
*/
public constructor (
@inject(ServiceIdentifiers.Factory__IIdentifierNamesGenerator)
identifierNamesGeneratorFactory: TIdentifierNamesGeneratorFactory,
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
this.identifierNamesGenerator = identifierNamesGeneratorFactory(options);
this.randomGenerator = randomGenerator;
this.options = options;
}
/**
* @returns {ObfuscationEvent}
*/
public getAppendEvent (): ObfuscationEvent {
return this.appendEvent;
}
/**
* @returns {Map<CustomCodeHelper, ICustomCodeHelper>}
*/
public getCustomCodeHelpers (): Map <CustomCodeHelper, ICustomCodeHelper> {
return this.customCodeHelpers;
}
/**
* @param {CustomCodeHelper} customCodeHelperName
* @param {callback} callback
*/
protected appendCustomNodeIfExist (customCodeHelperName: CustomCodeHelper, callback: (customCodeHelper: ICustomCodeHelper) => void): void {
const customCodeHelper: ICustomCodeHelper | undefined = this.customCodeHelpers.get(customCodeHelperName);
if (!customCodeHelper) {
return;
}
callback(customCodeHelper);
}
/**
* @param {number} callsGraphLength
* @returns {number}
*/
protected getRandomCallsGraphIndex (callsGraphLength: number): number {
return this.randomGenerator.getRandomInteger(0, Math.max(0, Math.round(callsGraphLength - 1)));
}
/**
* @param {TNodeWithStatements} nodeWithStatements
* @param {ICallsGraphData[]} callsGraphData
*/
public abstract appendNodes (nodeWithStatements: TNodeWithStatements, callsGraphData: ICallsGraphData[]): void;
public abstract initialize (): void;
}
@@ -0,0 +1,65 @@
import { inject, injectable } from 'inversify';
import { ServiceIdentifiers } from '../container/ServiceIdentifiers';
import * as estraverse from 'estraverse';
import * as ESTree from 'estree';
import format from 'string-template';
import { TDictionary } from '../types/TDictionary';
import { TStatement } from '../types/node/TStatement';
import { ICustomCodeHelperFormatter } from '../interfaces/custom-code-helpers/ICustomCodeHelperFormatter';
import { IPrevailingKindOfVariablesAnalyzer } from '../interfaces/analyzers/calls-graph-analyzer/IPrevailingKindOfVariablesAnalyzer';
import { NodeGuards } from '../node/NodeGuards';
@injectable()
export class CustomCodeHelperFormatter implements ICustomCodeHelperFormatter {
/**
* @type {ESTree.VariableDeclaration['kind']}
*/
private readonly prevailingKindOfVariables: ESTree.VariableDeclaration['kind'];
public constructor (
@inject(ServiceIdentifiers.IPrevailingKindOfVariablesAnalyzer)
prevailingKindOfVariablesAnalyzer: IPrevailingKindOfVariablesAnalyzer
) {
this.prevailingKindOfVariables = prevailingKindOfVariablesAnalyzer.getPrevailingKind();
}
/**
* @param {string} template
* @param {TMapping} mapping
* @returns {string}
*/
public formatTemplate <TMapping extends TDictionary> (
template: string,
mapping: TMapping
): string {
return format(template, mapping);
}
/**
* @param {TStatement[]} statements
* @returns {TStatement[]}
*/
public formatStructure (statements: TStatement[]): TStatement[] {
for (const statement of statements) {
estraverse.replace(statement, {
enter: (node: ESTree.Node): ESTree.Node | void => {
if (!NodeGuards.isVariableDeclarationNode(node)) {
return;
}
if (this.prevailingKindOfVariables === 'var') {
node.kind = 'var';
}
return node;
}
});
}
return statements;
}
}
@@ -0,0 +1,57 @@
import { inject, injectable } from 'inversify';
import { ServiceIdentifiers } from '../container/ServiceIdentifiers';
import { TInputOptions } from '../types/options/TInputOptions';
import { ICustomCodeHelperObfuscator } from '../interfaces/custom-code-helpers/ICustomCodeHelperObfuscator';
import { IOptions } from '../interfaces/options/IOptions';
import { IRandomGenerator } from '../interfaces/utils/IRandomGenerator';
import { NO_ADDITIONAL_NODES_PRESET } from '../options/presets/NoCustomNodes';
import { JavaScriptObfuscator } from '../JavaScriptObfuscatorFacade';
@injectable()
export class CustomCodeHelperObfuscator implements ICustomCodeHelperObfuscator {
/**
* @type {IOptions}
*/
private readonly options: IOptions;
/**
* @type {IRandomGenerator}
*/
private readonly randomGenerator: IRandomGenerator;
/**
* @param {IRandomGenerator} randomGenerator
* @param {IOptions} options
*/
public constructor (
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
this.randomGenerator = randomGenerator;
this.options = options;
}
/**
* @param {string} template
* @param {TInputOptions} additionalOptions
* @returns {string}
*/
public obfuscateTemplate (template: string, additionalOptions: TInputOptions = {}): string {
return JavaScriptObfuscator.obfuscate(
template,
{
...NO_ADDITIONAL_NODES_PRESET,
identifierNamesGenerator: this.options.identifierNamesGenerator,
identifiersDictionary: this.options.identifiersDictionary,
numbersToExpressions: this.options.numbersToExpressions,
simplify: this.options.simplify,
seed: this.randomGenerator.getRawSeed(),
...additionalOptions
}
).getObfuscatedCode();
}
}
@@ -0,0 +1,92 @@
import { inject, injectable, } from 'inversify';
import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
import { TIdentifierNamesGeneratorFactory } from '../../types/container/generators/TIdentifierNamesGeneratorFactory';
import { TStatement } from '../../types/node/TStatement';
import { ICustomCodeHelperObfuscator } from '../../interfaces/custom-code-helpers/ICustomCodeHelperObfuscator';
import { ICustomCodeHelperFormatter } from '../../interfaces/custom-code-helpers/ICustomCodeHelperFormatter';
import { IOptions } from '../../interfaces/options/IOptions';
import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
import { ObfuscationEvent } from '../../enums/event-emitters/ObfuscationEvent';
import { initializable } from '../../decorators/Initializable';
import { SingleCallControllerTemplate } from '../common/templates/SingleCallControllerTemplate';
import { AbstractCustomCodeHelper } from '../AbstractCustomCodeHelper';
import { NodeUtils } from '../../node/NodeUtils';
@injectable()
export class CallsControllerFunctionCodeHelper extends AbstractCustomCodeHelper {
/**
* @type {string}
*/
@initializable()
protected callsControllerFunctionName!: string;
/**
* @type {ObfuscationEvent}
*/
@initializable()
private appendEvent!: ObfuscationEvent;
/**
* @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
* @param {ICustomCodeHelperFormatter} customCodeHelperFormatter
* @param {ICustomCodeHelperObfuscator} customCodeHelperObfuscator
* @param {IRandomGenerator} randomGenerator
* @param {IOptions} options
*/
public constructor (
@inject(ServiceIdentifiers.Factory__IIdentifierNamesGenerator)
identifierNamesGeneratorFactory: TIdentifierNamesGeneratorFactory,
@inject(ServiceIdentifiers.ICustomCodeHelperFormatter) customCodeHelperFormatter: ICustomCodeHelperFormatter,
@inject(ServiceIdentifiers.ICustomCodeHelperObfuscator) customCodeHelperObfuscator: ICustomCodeHelperObfuscator,
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
super(
identifierNamesGeneratorFactory,
customCodeHelperFormatter,
customCodeHelperObfuscator,
randomGenerator,
options
);
}
/**
* @param {ObfuscationEvent} appendEvent
* @param {string} callsControllerFunctionName
*/
public initialize (appendEvent: ObfuscationEvent, callsControllerFunctionName: string): void {
this.appendEvent = appendEvent;
this.callsControllerFunctionName = callsControllerFunctionName;
}
/**
* @param {string} codeHelperTemplate
* @returns {TStatement[]}
*/
protected getNodeStructure (codeHelperTemplate: string): TStatement[] {
return NodeUtils.convertCodeToStructure(codeHelperTemplate);
}
/**
* @returns {string}
*/
protected getCodeHelperTemplate (): string {
if (this.appendEvent === ObfuscationEvent.AfterObfuscation) {
return this.customCodeHelperObfuscator.obfuscateTemplate(
this.customCodeHelperFormatter.formatTemplate(SingleCallControllerTemplate(), {
callControllerFunctionName: this.callsControllerFunctionName
})
);
}
return this.customCodeHelperFormatter.formatTemplate(SingleCallControllerTemplate(), {
callControllerFunctionName: this.callsControllerFunctionName
});
}
}
@@ -0,0 +1,14 @@
/**
* @returns {string}
*/
export function GlobalVariableNoEvalTemplate (): string {
return `
const that = (typeof window !== 'undefined'
? window
: (typeof process === 'object' &&
typeof require === 'function' &&
typeof global === 'object')
? global
: this);
`;
}
@@ -0,0 +1,16 @@
/**
* @returns {string}
*/
export function GlobalVariableTemplate1 (): string {
return `
let that;
try {
const getGlobal = Function('return (function() ' + '{}.constructor("return this")( )' + ');');
that = getGlobal();
} catch (e) {
that = window;
}
`;
}
@@ -0,0 +1,19 @@
/**
* @returns {string}
*/
export function GlobalVariableTemplate2 (): string {
return `
const getGlobal = function () {
let globalObject;
try {
globalObject = Function('return (function() ' + '{}.constructor("return this")( )' + ');')();
} catch (e) {
globalObject = window;
}
return globalObject;
};
const that = getGlobal();
`;
}
@@ -0,0 +1,24 @@
/**
* @returns {string}
*/
export function SingleCallControllerTemplate (): string {
return `
const {callControllerFunctionName} = (function(){
let firstCall = true;
return function (context, fn){
const rfn = firstCall ? function(){
if(fn){
const res = fn.apply(context, arguments);
fn = null;
return res;
}
} : function(){}
firstCall = false;
return rfn;
}
})();
`;
}
@@ -0,0 +1,91 @@
import { inject, injectable, } from 'inversify';
import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
import { TIdentifierNamesGeneratorFactory } from '../../types/container/generators/TIdentifierNamesGeneratorFactory';
import { TStatement } from '../../types/node/TStatement';
import { ICustomCodeHelperFormatter } from '../../interfaces/custom-code-helpers/ICustomCodeHelperFormatter';
import { ICustomCodeHelperObfuscator } from '../../interfaces/custom-code-helpers/ICustomCodeHelperObfuscator';
import { IOptions } from '../../interfaces/options/IOptions';
import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
import { ObfuscationTarget } from '../../enums/ObfuscationTarget';
import { ConsoleOutputDisableTemplate } from './templates/ConsoleOutputDisableTemplate';
import { GlobalVariableNoEvalTemplate } from '../common/templates/GlobalVariableNoEvalTemplate';
import { initializable } from '../../decorators/Initializable';
import { AbstractCustomCodeHelper } from '../AbstractCustomCodeHelper';
import { NodeUtils } from '../../node/NodeUtils';
@injectable()
export class ConsoleOutputDisableCodeHelper extends AbstractCustomCodeHelper {
/**
* @type {string}
*/
@initializable()
private callsControllerFunctionName!: string;
/**
* @type {string}
*/
@initializable()
private consoleOutputDisableFunctionName!: string;
/**
* @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
* @param {ICustomCodeHelperFormatter} customCodeHelperFormatter
* @param {ICustomCodeHelperObfuscator} customCodeHelperObfuscator
* @param {IRandomGenerator} randomGenerator
* @param {IOptions} options
*/
public constructor (
@inject(ServiceIdentifiers.Factory__IIdentifierNamesGenerator)
identifierNamesGeneratorFactory: TIdentifierNamesGeneratorFactory,
@inject(ServiceIdentifiers.ICustomCodeHelperFormatter) customCodeHelperFormatter: ICustomCodeHelperFormatter,
@inject(ServiceIdentifiers.ICustomCodeHelperObfuscator) customCodeHelperObfuscator: ICustomCodeHelperObfuscator,
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
super(
identifierNamesGeneratorFactory,
customCodeHelperFormatter,
customCodeHelperObfuscator,
randomGenerator,
options
);
}
/**
* @param {string} callsControllerFunctionName
* @param {StaticRange} consoleOutputDisableFunctionName
*/
public initialize (callsControllerFunctionName: string, consoleOutputDisableFunctionName: string): void {
this.callsControllerFunctionName = callsControllerFunctionName;
this.consoleOutputDisableFunctionName = consoleOutputDisableFunctionName;
}
/**
* @param {string} codeHelperTemplate
* @returns {TStatement[]}
*/
protected getNodeStructure (codeHelperTemplate: string): TStatement[] {
return NodeUtils.convertCodeToStructure(codeHelperTemplate);
}
/**
* @returns {string}
*/
protected getCodeHelperTemplate (): string {
const globalVariableTemplate: string = this.options.target !== ObfuscationTarget.BrowserNoEval
? this.getGlobalVariableTemplate()
: GlobalVariableNoEvalTemplate();
return this.customCodeHelperFormatter.formatTemplate(ConsoleOutputDisableTemplate(), {
callControllerFunctionName: this.callsControllerFunctionName,
consoleLogDisableFunctionName: this.consoleOutputDisableFunctionName,
globalVariableTemplate
});
}
}
@@ -0,0 +1,126 @@
import { inject, injectable, } from 'inversify';
import { ServiceIdentifiers } from '../../../container/ServiceIdentifiers';
import { TCustomCodeHelperFactory } from '../../../types/container/custom-code-helpers/TCustomCodeHelperFactory';
import { TIdentifierNamesGeneratorFactory } from '../../../types/container/generators/TIdentifierNamesGeneratorFactory';
import { TInitialData } from '../../../types/TInitialData';
import { TNodeWithLexicalScope } from '../../../types/node/TNodeWithLexicalScope';
import { TNodeWithStatements } from '../../../types/node/TNodeWithStatements';
import { ICustomCodeHelper } from '../../../interfaces/custom-code-helpers/ICustomCodeHelper';
import { IOptions } from '../../../interfaces/options/IOptions';
import { IRandomGenerator } from '../../../interfaces/utils/IRandomGenerator';
import { ICallsGraphData } from '../../../interfaces/analyzers/calls-graph-analyzer/ICallsGraphData';
import { initializable } from '../../../decorators/Initializable';
import { CustomCodeHelper } from '../../../enums/custom-code-helpers/CustomCodeHelper';
import { ObfuscationEvent } from '../../../enums/event-emitters/ObfuscationEvent';
import { AbstractCustomCodeHelperGroup } from '../../AbstractCustomCodeHelperGroup';
import { CallsControllerFunctionCodeHelper } from '../../calls-controller/CallsControllerFunctionCodeHelper';
import { ConsoleOutputDisableCodeHelper } from '../ConsoleOutputDisableCodeHelper';
import { NodeAppender } from '../../../node/NodeAppender';
import { NodeLexicalScopeUtils } from '../../../node/NodeLexicalScopeUtils';
@injectable()
export class ConsoleOutputCodeHelperGroup extends AbstractCustomCodeHelperGroup {
/**
* @type {Map<CustomCodeHelper, ICustomCodeHelper>}
*/
@initializable()
protected customCodeHelpers!: Map <CustomCodeHelper, ICustomCodeHelper>;
/**
* @type {ObfuscationEvent}
*/
protected readonly appendEvent: ObfuscationEvent = ObfuscationEvent.BeforeObfuscation;
/**
* @type {TCustomCodeHelperFactory}
*/
private readonly customCodeHelperFactory: TCustomCodeHelperFactory;
/**
* @param {TCustomCodeHelperFactory} customCodeHelperFactory
* @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
* @param {IRandomGenerator} randomGenerator
* @param {IOptions} options
*/
public constructor (
@inject(ServiceIdentifiers.Factory__ICustomCodeHelper) customCodeHelperFactory: TCustomCodeHelperFactory,
@inject(ServiceIdentifiers.Factory__IIdentifierNamesGenerator)
identifierNamesGeneratorFactory: TIdentifierNamesGeneratorFactory,
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
super(identifierNamesGeneratorFactory, randomGenerator, options);
this.customCodeHelperFactory = customCodeHelperFactory;
}
/**
* @param {TNodeWithStatements} nodeWithStatements
* @param {ICallsGraphData[]} callsGraphData
*/
public appendNodes (nodeWithStatements: TNodeWithStatements, callsGraphData: ICallsGraphData[]): void {
if (!this.options.disableConsoleOutput) {
return;
}
const randomCallsGraphIndex: number = this.getRandomCallsGraphIndex(callsGraphData.length);
const consoleOutputDisableHostNode: TNodeWithStatements = callsGraphData.length
? NodeAppender.getOptimalBlockScope(callsGraphData, randomCallsGraphIndex)
: nodeWithStatements;
const callsControllerHostNode: TNodeWithStatements = callsGraphData.length
? NodeAppender.getOptimalBlockScope(callsGraphData, randomCallsGraphIndex, 1)
: nodeWithStatements;
const consoleOutputDisableLexicalScopeNode: TNodeWithLexicalScope | null = NodeLexicalScopeUtils
.getLexicalScope(consoleOutputDisableHostNode) ?? null;
const consoleOutputDisableFunctionName: string = consoleOutputDisableLexicalScopeNode
? this.identifierNamesGenerator.generate(consoleOutputDisableLexicalScopeNode)
: this.identifierNamesGenerator.generateNext();
const callsControllerFunctionName: string = consoleOutputDisableLexicalScopeNode
? this.identifierNamesGenerator.generate(consoleOutputDisableLexicalScopeNode)
: this.identifierNamesGenerator.generateNext();
// consoleOutputDisableExpression helper nodes append
this.appendCustomNodeIfExist(
CustomCodeHelper.ConsoleOutputDisable,
(customCodeHelper: ICustomCodeHelper<TInitialData<ConsoleOutputDisableCodeHelper>>) => {
customCodeHelper.initialize(callsControllerFunctionName, consoleOutputDisableFunctionName);
NodeAppender.prepend(consoleOutputDisableHostNode, customCodeHelper.getNode());
}
);
// nodeCallsControllerFunction helper nodes append
this.appendCustomNodeIfExist(
CustomCodeHelper.CallsControllerFunction,
(customCodeHelper: ICustomCodeHelper<TInitialData<CallsControllerFunctionCodeHelper>>) => {
customCodeHelper.initialize(this.appendEvent, callsControllerFunctionName);
NodeAppender.prepend(callsControllerHostNode, customCodeHelper.getNode());
}
);
}
public initialize (): void {
this.customCodeHelpers = new Map <CustomCodeHelper, ICustomCodeHelper>();
if (!this.options.disableConsoleOutput) {
return;
}
const consoleOutputDisableExpressionCodeHelper: ICustomCodeHelper<TInitialData<ConsoleOutputDisableCodeHelper>> =
this.customCodeHelperFactory(CustomCodeHelper.ConsoleOutputDisable);
const callsControllerFunctionCodeHelper: ICustomCodeHelper<TInitialData<CallsControllerFunctionCodeHelper>> =
this.customCodeHelperFactory(CustomCodeHelper.CallsControllerFunction);
this.customCodeHelpers.set(CustomCodeHelper.ConsoleOutputDisable, consoleOutputDisableExpressionCodeHelper);
this.customCodeHelpers.set(CustomCodeHelper.CallsControllerFunction, callsControllerFunctionCodeHelper);
}
}
@@ -0,0 +1,26 @@
/**
* @returns {string}
*/
export function ConsoleOutputDisableTemplate (): string {
return `
const {consoleLogDisableFunctionName} = {callControllerFunctionName}(this, function () {
{globalVariableTemplate}
const consoleObject = (that.console = that.console || {});
const methods = ['log', 'warn', 'info', 'error', 'exception', 'table', 'trace'];
for (let index = 0; index < methods.length; index++){
const func = {callControllerFunctionName}.constructor.prototype.bind({callControllerFunctionName});
const methodName = methods[index];
const originalFunction = consoleObject[methodName] || func;
func.__proto__ = {callControllerFunctionName}.bind({callControllerFunctionName});
func.toString = originalFunction.toString.bind(originalFunction);
consoleObject[methodName] = func;
}
});
{consoleLogDisableFunctionName}();
`;
}
@@ -0,0 +1,83 @@
import { inject, injectable, } from 'inversify';
import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
import { TIdentifierNamesGeneratorFactory } from '../../types/container/generators/TIdentifierNamesGeneratorFactory';
import { TStatement } from '../../types/node/TStatement';
import { ICustomCodeHelperFormatter } from '../../interfaces/custom-code-helpers/ICustomCodeHelperFormatter';
import { ICustomCodeHelperObfuscator } from '../../interfaces/custom-code-helpers/ICustomCodeHelperObfuscator';
import { IOptions } from '../../interfaces/options/IOptions';
import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
import { initializable } from '../../decorators/Initializable';
import { DebugProtectionFunctionCallTemplate } from './templates/debug-protection-function-call/DebugProtectionFunctionCallTemplate';
import { AbstractCustomCodeHelper } from '../AbstractCustomCodeHelper';
import { NodeUtils } from '../../node/NodeUtils';
@injectable()
export class DebugProtectionFunctionCallCodeHelper extends AbstractCustomCodeHelper {
/**
* @type {string}
*/
@initializable()
private callsControllerFunctionName!: string;
/**
* @type {string}
*/
@initializable()
private debugProtectionFunctionName!: string;
/**
* @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
* @param {ICustomCodeHelperFormatter} customCodeHelperFormatter
* @param {ICustomCodeHelperObfuscator} customCodeHelperObfuscator
* @param {IRandomGenerator} randomGenerator
* @param {IOptions} options
*/
public constructor (
@inject(ServiceIdentifiers.Factory__IIdentifierNamesGenerator)
identifierNamesGeneratorFactory: TIdentifierNamesGeneratorFactory,
@inject(ServiceIdentifiers.ICustomCodeHelperFormatter) customCodeHelperFormatter: ICustomCodeHelperFormatter,
@inject(ServiceIdentifiers.ICustomCodeHelperObfuscator) customCodeHelperObfuscator: ICustomCodeHelperObfuscator,
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
super(
identifierNamesGeneratorFactory,
customCodeHelperFormatter,
customCodeHelperObfuscator,
randomGenerator,
options
);
}
/**
* @param {string} debugProtectionFunctionName
* @param {string} callsControllerFunctionName
*/
public initialize (debugProtectionFunctionName: string, callsControllerFunctionName: string): void {
this.debugProtectionFunctionName = debugProtectionFunctionName;
this.callsControllerFunctionName = callsControllerFunctionName;
}
/**
* @param {string} codeHelperTemplate
* @returns {TStatement[]}
*/
protected getNodeStructure (codeHelperTemplate: string): TStatement[] {
return NodeUtils.convertCodeToStructure(codeHelperTemplate);
}
/**
* @returns {string}
*/
protected getCodeHelperTemplate (): string {
return this.customCodeHelperFormatter.formatTemplate(DebugProtectionFunctionCallTemplate(), {
debugProtectionFunctionName: this.debugProtectionFunctionName,
callControllerFunctionName: this.callsControllerFunctionName
});
}
}
@@ -0,0 +1,83 @@
import { inject, injectable, } from 'inversify';
import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
import { TIdentifierNamesGeneratorFactory } from '../../types/container/generators/TIdentifierNamesGeneratorFactory';
import { TStatement } from '../../types/node/TStatement';
import { ICustomCodeHelperFormatter } from '../../interfaces/custom-code-helpers/ICustomCodeHelperFormatter';
import { ICustomCodeHelperObfuscator } from '../../interfaces/custom-code-helpers/ICustomCodeHelperObfuscator';
import { IOptions } from '../../interfaces/options/IOptions';
import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
import { ObfuscationTarget } from '../../enums/ObfuscationTarget';
import { initializable } from '../../decorators/Initializable';
import { DebuggerTemplate } from './templates/debug-protection-function/DebuggerTemplate';
import { DebuggerTemplateNoEval } from './templates/debug-protection-function/DebuggerTemplateNoEval';
import { DebugProtectionFunctionTemplate } from './templates/debug-protection-function/DebugProtectionFunctionTemplate';
import { AbstractCustomCodeHelper } from '../AbstractCustomCodeHelper';
import { NodeUtils } from '../../node/NodeUtils';
@injectable()
export class DebugProtectionFunctionCodeHelper extends AbstractCustomCodeHelper {
/**
* @type {string}
*/
@initializable()
private debugProtectionFunctionName!: string;
/**
* @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
* @param {ICustomCodeHelperFormatter} customCodeHelperFormatter
* @param {ICustomCodeHelperObfuscator} customCodeHelperObfuscator
* @param {IRandomGenerator} randomGenerator
* @param {IOptions} options
*/
public constructor (
@inject(ServiceIdentifiers.Factory__IIdentifierNamesGenerator)
identifierNamesGeneratorFactory: TIdentifierNamesGeneratorFactory,
@inject(ServiceIdentifiers.ICustomCodeHelperFormatter) customCodeHelperFormatter: ICustomCodeHelperFormatter,
@inject(ServiceIdentifiers.ICustomCodeHelperObfuscator) customCodeHelperObfuscator: ICustomCodeHelperObfuscator,
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
super(
identifierNamesGeneratorFactory,
customCodeHelperFormatter,
customCodeHelperObfuscator,
randomGenerator,
options
);
}
/**
* @param {string} debugProtectionFunctionName
*/
public initialize (debugProtectionFunctionName: string): void {
this.debugProtectionFunctionName = debugProtectionFunctionName;
}
/**
* @param {string} codeHelperTemplate
* @returns {TStatement[]}
*/
protected getNodeStructure (codeHelperTemplate: string): TStatement[] {
return NodeUtils.convertCodeToStructure(codeHelperTemplate);
}
/**
* @returns {string}
*/
protected getCodeHelperTemplate (): string {
const debuggerTemplate: string = this.options.target !== ObfuscationTarget.BrowserNoEval
? DebuggerTemplate()
: DebuggerTemplateNoEval();
return this.customCodeHelperFormatter.formatTemplate(DebugProtectionFunctionTemplate(), {
debuggerTemplate,
debugProtectionFunctionName: this.debugProtectionFunctionName
});
}
}
@@ -0,0 +1,74 @@
import { inject, injectable, } from 'inversify';
import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
import { TIdentifierNamesGeneratorFactory } from '../../types/container/generators/TIdentifierNamesGeneratorFactory';
import { TStatement } from '../../types/node/TStatement';
import { ICustomCodeHelperFormatter } from '../../interfaces/custom-code-helpers/ICustomCodeHelperFormatter';
import { ICustomCodeHelperObfuscator } from '../../interfaces/custom-code-helpers/ICustomCodeHelperObfuscator';
import { IOptions } from '../../interfaces/options/IOptions';
import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
import { initializable } from '../../decorators/Initializable';
import { DebugProtectionFunctionIntervalTemplate } from './templates/debug-protection-function-interval/DebugProtectionFunctionIntervalTemplate';
import { AbstractCustomCodeHelper } from '../AbstractCustomCodeHelper';
import { NodeUtils } from '../../node/NodeUtils';
@injectable()
export class DebugProtectionFunctionIntervalCodeHelper extends AbstractCustomCodeHelper {
/**
* @type {string}
*/
@initializable()
private debugProtectionFunctionName!: string;
/**
* @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
* @param {ICustomCodeHelperFormatter} customCodeHelperFormatter
* @param {ICustomCodeHelperObfuscator} customCodeHelperObfuscator
* @param {IRandomGenerator} randomGenerator
* @param {IOptions} options
*/
public constructor (
@inject(ServiceIdentifiers.Factory__IIdentifierNamesGenerator)
identifierNamesGeneratorFactory: TIdentifierNamesGeneratorFactory,
@inject(ServiceIdentifiers.ICustomCodeHelperFormatter) customCodeHelperFormatter: ICustomCodeHelperFormatter,
@inject(ServiceIdentifiers.ICustomCodeHelperObfuscator) customCodeHelperObfuscator: ICustomCodeHelperObfuscator,
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
super(
identifierNamesGeneratorFactory,
customCodeHelperFormatter,
customCodeHelperObfuscator,
randomGenerator,
options
);
}
/**
* @param {string} debugProtectionFunctionName
*/
public initialize (debugProtectionFunctionName: string): void {
this.debugProtectionFunctionName = debugProtectionFunctionName;
}
/**
* @param {string} codeHelperTemplate
* @returns {TStatement[]}
*/
protected getNodeStructure (codeHelperTemplate: string): TStatement[] {
return NodeUtils.convertCodeToStructure(codeHelperTemplate);
}
/**
* @returns {string}
*/
protected getCodeHelperTemplate (): string {
return this.customCodeHelperFormatter.formatTemplate(DebugProtectionFunctionIntervalTemplate(), {
debugProtectionFunctionName: this.debugProtectionFunctionName
});
}
}
@@ -0,0 +1,164 @@
import { inject, injectable, } from 'inversify';
import { ServiceIdentifiers } from '../../../container/ServiceIdentifiers';
import { TCustomCodeHelperFactory } from '../../../types/container/custom-code-helpers/TCustomCodeHelperFactory';
import { TIdentifierNamesGeneratorFactory } from '../../../types/container/generators/TIdentifierNamesGeneratorFactory';
import { TInitialData } from '../../../types/TInitialData';
import { TNodeWithLexicalScope } from '../../../types/node/TNodeWithLexicalScope';
import { TNodeWithStatements } from '../../../types/node/TNodeWithStatements';
import { ICustomCodeHelper } from '../../../interfaces/custom-code-helpers/ICustomCodeHelper';
import { IOptions } from '../../../interfaces/options/IOptions';
import { IRandomGenerator } from '../../../interfaces/utils/IRandomGenerator';
import { ICallsGraphData } from '../../../interfaces/analyzers/calls-graph-analyzer/ICallsGraphData';
import { initializable } from '../../../decorators/Initializable';
import { CustomCodeHelper } from '../../../enums/custom-code-helpers/CustomCodeHelper';
import { ObfuscationEvent } from '../../../enums/event-emitters/ObfuscationEvent';
import { AbstractCustomCodeHelperGroup } from '../../AbstractCustomCodeHelperGroup';
import { CallsControllerFunctionCodeHelper } from '../../calls-controller/CallsControllerFunctionCodeHelper';
import { DebugProtectionFunctionCodeHelper } from '../DebugProtectionFunctionCodeHelper';
import { DebugProtectionFunctionCallCodeHelper } from '../DebugProtectionFunctionCallCodeHelper';
import { DebugProtectionFunctionIntervalCodeHelper } from '../DebugProtectionFunctionIntervalCodeHelper';
import { NodeAppender } from '../../../node/NodeAppender';
import { NodeGuards } from '../../../node/NodeGuards';
import { NodeLexicalScopeUtils } from '../../../node/NodeLexicalScopeUtils';
@injectable()
export class DebugProtectionCodeHelperGroup extends AbstractCustomCodeHelperGroup {
/**
* @type {Map<CustomCodeHelper, ICustomCodeHelper>}
*/
@initializable()
protected customCodeHelpers!: Map <CustomCodeHelper, ICustomCodeHelper>;
/**
* @type {ObfuscationEvent}
*/
protected readonly appendEvent: ObfuscationEvent = ObfuscationEvent.BeforeObfuscation;
/**
* @type {TCustomCodeHelperFactory}
*/
private readonly customCodeHelperFactory: TCustomCodeHelperFactory;
/**
* @param {TCustomCodeHelperFactory} customCodeHelperFactory
* @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
* @param {IRandomGenerator} randomGenerator
* @param {IOptions} options
*/
public constructor (
@inject(ServiceIdentifiers.Factory__ICustomCodeHelper) customCodeHelperFactory: TCustomCodeHelperFactory,
@inject(ServiceIdentifiers.Factory__IIdentifierNamesGenerator)
identifierNamesGeneratorFactory: TIdentifierNamesGeneratorFactory,
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
super(identifierNamesGeneratorFactory, randomGenerator, options);
this.customCodeHelperFactory = customCodeHelperFactory;
}
/**
* @param {TNodeWithStatements} nodeWithStatements
* @param {ICallsGraphData[]} callsGraphData
*/
public appendNodes (nodeWithStatements: TNodeWithStatements, callsGraphData: ICallsGraphData[]): void {
if (!this.options.debugProtection) {
return;
}
const randomCallsGraphIndex: number = this.getRandomCallsGraphIndex(callsGraphData.length);
const debugProtectionFunctionCallHostNode: TNodeWithStatements = callsGraphData.length
? NodeAppender.getOptimalBlockScope(callsGraphData, randomCallsGraphIndex)
: nodeWithStatements;
const callsControllerHostNode: TNodeWithStatements = callsGraphData.length
? NodeAppender.getOptimalBlockScope(callsGraphData, randomCallsGraphIndex, 1)
: nodeWithStatements;
const debugProtectionFunctionCallScopeNode: TNodeWithLexicalScope | null = NodeLexicalScopeUtils
.getLexicalScope(debugProtectionFunctionCallHostNode) ?? null;
const debugProtectionFunctionName: string = debugProtectionFunctionCallScopeNode
? this.identifierNamesGenerator.generate(debugProtectionFunctionCallScopeNode)
: this.identifierNamesGenerator.generateNext();
const callsControllerFunctionName: string = debugProtectionFunctionCallScopeNode
? this.identifierNamesGenerator.generate(debugProtectionFunctionCallScopeNode)
: this.identifierNamesGenerator.generateNext();
// debugProtectionFunctionCall helper nodes append
this.appendCustomNodeIfExist(
CustomCodeHelper.DebugProtectionFunctionCall,
(customCodeHelper: ICustomCodeHelper<TInitialData<DebugProtectionFunctionCallCodeHelper>>) => {
customCodeHelper.initialize(debugProtectionFunctionName, callsControllerFunctionName);
NodeAppender.prepend(debugProtectionFunctionCallHostNode, customCodeHelper.getNode());
}
);
// nodeCallsControllerFunction helper nodes append
this.appendCustomNodeIfExist(
CustomCodeHelper.CallsControllerFunction,
(customCodeHelper: ICustomCodeHelper<TInitialData<CallsControllerFunctionCodeHelper>>) => {
customCodeHelper.initialize(this.appendEvent, callsControllerFunctionName);
NodeAppender.prepend(callsControllerHostNode, customCodeHelper.getNode());
}
);
// debugProtectionFunction helper nodes append
this.appendCustomNodeIfExist(
CustomCodeHelper.DebugProtectionFunction,
(customCodeHelper: ICustomCodeHelper<TInitialData<DebugProtectionFunctionCodeHelper>>) => {
customCodeHelper.initialize(debugProtectionFunctionName);
NodeAppender.append(nodeWithStatements, customCodeHelper.getNode());
}
);
// debugProtectionFunctionInterval helper nodes append
this.appendCustomNodeIfExist(
CustomCodeHelper.DebugProtectionFunctionInterval,
(customCodeHelper: ICustomCodeHelper<TInitialData<DebugProtectionFunctionIntervalCodeHelper>>) => {
const programBodyLength: number = NodeGuards.isSwitchCaseNode(nodeWithStatements)
? nodeWithStatements.consequent.length
: nodeWithStatements.body.length;
const randomIndex: number = this.randomGenerator.getRandomInteger(0, programBodyLength);
customCodeHelper.initialize(debugProtectionFunctionName);
NodeAppender.insertAtIndex(nodeWithStatements, customCodeHelper.getNode(), randomIndex);
}
);
}
public initialize (): void {
this.customCodeHelpers = new Map <CustomCodeHelper, ICustomCodeHelper>();
if (!this.options.debugProtection) {
return;
}
const debugProtectionFunctionCodeHelper: ICustomCodeHelper<TInitialData<DebugProtectionFunctionCodeHelper>> =
this.customCodeHelperFactory(CustomCodeHelper.DebugProtectionFunction);
const debugProtectionFunctionCallCodeHelper: ICustomCodeHelper<TInitialData<DebugProtectionFunctionCallCodeHelper>> =
this.customCodeHelperFactory(CustomCodeHelper.DebugProtectionFunctionCall);
const debugProtectionFunctionIntervalCodeHelper: ICustomCodeHelper<TInitialData<DebugProtectionFunctionIntervalCodeHelper>> =
this.customCodeHelperFactory(CustomCodeHelper.DebugProtectionFunctionInterval);
const callsControllerFunctionCodeHelper: ICustomCodeHelper<TInitialData<CallsControllerFunctionCodeHelper>> =
this.customCodeHelperFactory(CustomCodeHelper.CallsControllerFunction);
this.customCodeHelpers.set(CustomCodeHelper.DebugProtectionFunction, debugProtectionFunctionCodeHelper);
this.customCodeHelpers.set(CustomCodeHelper.DebugProtectionFunctionCall, debugProtectionFunctionCallCodeHelper);
if (this.options.debugProtectionInterval) {
this.customCodeHelpers.set(CustomCodeHelper.DebugProtectionFunctionInterval, debugProtectionFunctionIntervalCodeHelper);
}
this.customCodeHelpers.set(CustomCodeHelper.CallsControllerFunction, callsControllerFunctionCodeHelper);
}
}
@@ -0,0 +1,24 @@
/**
* @returns {string}
*/
export function DebugProtectionFunctionCallTemplate (): string {
return `
(function () {
{callControllerFunctionName}(
this,
function () {
const regExp1 = new RegExp('function *\\\\( *\\\\)');
const regExp2 = new RegExp('\\\\+\\\\+ *\\(?:[a-zA-Z_$][0-9a-zA-Z_$]*\\)', 'i');
const result = {debugProtectionFunctionName}('init');
if (!regExp1.test(result + 'chain') || !regExp2.test(result + 'input')) {
result('0');
} else {
{debugProtectionFunctionName}();
}
}
)();
})();
`;
}
@@ -0,0 +1,10 @@
/**
* @returns {string}
*/
export function DebugProtectionFunctionIntervalTemplate (): string {
return `
setInterval(function () {
{debugProtectionFunctionName}();
}, 4000);
`;
}
@@ -0,0 +1,23 @@
/**
* @returns {string}
*/
export function DebugProtectionFunctionTemplate (): string {
return `
function {debugProtectionFunctionName} (ret) {
function debuggerProtection (counter) {
{debuggerTemplate}
debuggerProtection(++counter);
}
try {
if (ret) {
return debuggerProtection;
} else {
debuggerProtection(0);
}
} catch (y) {}
}
`;
}
@@ -0,0 +1,17 @@
/**
* @returns {string}
*/
export function DebuggerTemplate (): string {
return `
if (typeof counter === 'string') {
return (function (arg) {}.constructor('while (true) {}').apply('counter'));
} else {
if (('' + counter / counter)['length'] !== 1 || counter % 20 === 0) {
(function () {return true;}.constructor('debu' + 'gger').call('action'));
} else {
(function () {return false;}.constructor('debu' + 'gger').apply('stateObject'));
}
}
`;
}
@@ -0,0 +1,21 @@
/**
* @returns {string}
*/
export function DebuggerTemplateNoEval (): string {
return `
if (typeof counter === 'string') {
const func = function () {
while (true) {}
};
return func();
} else {
if (('' + counter / counter)['length'] !== 1 || counter % 20 === 0) {
debugger;
} else {
debugger;
}
}
`;
}
@@ -0,0 +1,108 @@
import { inject, injectable, } from 'inversify';
import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
import { TIdentifierNamesGeneratorFactory } from '../../types/container/generators/TIdentifierNamesGeneratorFactory';
import { TStatement } from '../../types/node/TStatement';
import { ICustomCodeHelperFormatter } from '../../interfaces/custom-code-helpers/ICustomCodeHelperFormatter';
import { ICustomCodeHelperObfuscator } from '../../interfaces/custom-code-helpers/ICustomCodeHelperObfuscator';
import { ICryptUtils } from '../../interfaces/utils/ICryptUtils';
import { IOptions } from '../../interfaces/options/IOptions';
import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
import { ObfuscationTarget } from '../../enums/ObfuscationTarget';
import { initializable } from '../../decorators/Initializable';
import { DomainLockTemplate } from './templates/DomainLockTemplate';
import { GlobalVariableNoEvalTemplate } from '../common/templates/GlobalVariableNoEvalTemplate';
import { AbstractCustomCodeHelper } from '../AbstractCustomCodeHelper';
import { NodeUtils } from '../../node/NodeUtils';
@injectable()
export class DomainLockCodeHelper extends AbstractCustomCodeHelper {
/**
* @type {string}
*/
@initializable()
private callsControllerFunctionName!: string;
/**
* @type {string}
*/
@initializable()
private domainLockFunctionName!: string;
/**
* @type {ICryptUtils}
*/
private readonly cryptUtils: ICryptUtils;
/**
* @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
* @param {ICustomCodeHelperFormatter} customCodeHelperFormatter
* @param {ICustomCodeHelperObfuscator} customCodeHelperObfuscator
* @param {IRandomGenerator} randomGenerator
* @param {IOptions} options
* @param {ICryptUtils} cryptUtils
*/
public constructor (
@inject(ServiceIdentifiers.Factory__IIdentifierNamesGenerator)
identifierNamesGeneratorFactory: TIdentifierNamesGeneratorFactory,
@inject(ServiceIdentifiers.ICustomCodeHelperFormatter) customCodeHelperFormatter: ICustomCodeHelperFormatter,
@inject(ServiceIdentifiers.ICustomCodeHelperObfuscator) customCodeHelperObfuscator: ICustomCodeHelperObfuscator,
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
@inject(ServiceIdentifiers.IOptions) options: IOptions,
@inject(ServiceIdentifiers.ICryptUtils) cryptUtils: ICryptUtils
) {
super(
identifierNamesGeneratorFactory,
customCodeHelperFormatter,
customCodeHelperObfuscator,
randomGenerator,
options
);
this.cryptUtils = cryptUtils;
}
/**
* @param {string} callsControllerFunctionName
* @param {string} domainLockFunctionName
*/
public initialize (callsControllerFunctionName: string, domainLockFunctionName: string): void {
this.callsControllerFunctionName = callsControllerFunctionName;
this.domainLockFunctionName = domainLockFunctionName;
}
/**
* @param {string} codeHelperTemplate
* @returns {TStatement[]}
*/
protected getNodeStructure (codeHelperTemplate: string): TStatement[] {
return NodeUtils.convertCodeToStructure(codeHelperTemplate);
}
/**
* @returns {string}
*/
protected getCodeHelperTemplate (): string {
const domainsString: string = this.options.domainLock.join(';');
const [hiddenDomainsString, diff]: string[] = this.cryptUtils.hideString(
domainsString,
domainsString.length * 3
);
const globalVariableTemplate: string = this.options.target !== ObfuscationTarget.BrowserNoEval
? this.getGlobalVariableTemplate()
: GlobalVariableNoEvalTemplate();
return this.customCodeHelperFormatter.formatTemplate(DomainLockTemplate(), {
callControllerFunctionName: this.callsControllerFunctionName,
domainLockFunctionName: this.domainLockFunctionName,
diff,
domains: hiddenDomainsString,
globalVariableTemplate
});
}
}
@@ -0,0 +1,126 @@
import { inject, injectable, } from 'inversify';
import { ServiceIdentifiers } from '../../../container/ServiceIdentifiers';
import { TCustomCodeHelperFactory } from '../../../types/container/custom-code-helpers/TCustomCodeHelperFactory';
import { TIdentifierNamesGeneratorFactory } from '../../../types/container/generators/TIdentifierNamesGeneratorFactory';
import { TInitialData } from '../../../types/TInitialData';
import { TNodeWithLexicalScope } from '../../../types/node/TNodeWithLexicalScope';
import { TNodeWithStatements } from '../../../types/node/TNodeWithStatements';
import { ICustomCodeHelper } from '../../../interfaces/custom-code-helpers/ICustomCodeHelper';
import { IOptions } from '../../../interfaces/options/IOptions';
import { IRandomGenerator } from '../../../interfaces/utils/IRandomGenerator';
import { ICallsGraphData } from '../../../interfaces/analyzers/calls-graph-analyzer/ICallsGraphData';
import { initializable } from '../../../decorators/Initializable';
import { CustomCodeHelper } from '../../../enums/custom-code-helpers/CustomCodeHelper';
import { ObfuscationEvent } from '../../../enums/event-emitters/ObfuscationEvent';
import { AbstractCustomCodeHelperGroup } from '../../AbstractCustomCodeHelperGroup';
import { CallsControllerFunctionCodeHelper } from '../../calls-controller/CallsControllerFunctionCodeHelper';
import { DomainLockCodeHelper } from '../DomainLockCodeHelper';
import { NodeAppender } from '../../../node/NodeAppender';
import { NodeLexicalScopeUtils } from '../../../node/NodeLexicalScopeUtils';
@injectable()
export class DomainLockCustomCodeHelperGroup extends AbstractCustomCodeHelperGroup {
/**
* @type {Map<CustomCodeHelper, ICustomCodeHelper>}
*/
@initializable()
protected customCodeHelpers!: Map <CustomCodeHelper, ICustomCodeHelper>;
/**
* @type {ObfuscationEvent}
*/
protected readonly appendEvent: ObfuscationEvent = ObfuscationEvent.BeforeObfuscation;
/**
* @type {TCustomCodeHelperFactory}
*/
private readonly customCodeHelperFactory: TCustomCodeHelperFactory;
/**
* @param {TCustomCodeHelperFactory} customCodeHelperFactory
* @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
* @param {IRandomGenerator} randomGenerator
* @param {IOptions} options
*/
public constructor (
@inject(ServiceIdentifiers.Factory__ICustomCodeHelper) customCodeHelperFactory: TCustomCodeHelperFactory,
@inject(ServiceIdentifiers.Factory__IIdentifierNamesGenerator)
identifierNamesGeneratorFactory: TIdentifierNamesGeneratorFactory,
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
super(identifierNamesGeneratorFactory, randomGenerator, options);
this.customCodeHelperFactory = customCodeHelperFactory;
}
/**
* @param {TNodeWithStatements} nodeWithStatements
* @param {ICallsGraphData[]} callsGraphData
*/
public appendNodes (nodeWithStatements: TNodeWithStatements, callsGraphData: ICallsGraphData[]): void {
if (!this.options.domainLock.length) {
return;
}
const randomCallsGraphIndex: number = this.getRandomCallsGraphIndex(callsGraphData.length);
const domainLockFunctionHostNode: TNodeWithStatements = callsGraphData.length
? NodeAppender.getOptimalBlockScope(callsGraphData, randomCallsGraphIndex)
: nodeWithStatements;
const callsControllerHostNode: TNodeWithStatements = callsGraphData.length
? NodeAppender.getOptimalBlockScope(callsGraphData, randomCallsGraphIndex, 1)
: nodeWithStatements;
const domainLockFunctionLexicalScopeNode: TNodeWithLexicalScope | null = NodeLexicalScopeUtils
.getLexicalScope(domainLockFunctionHostNode) ?? null;
const domainLockFunctionName: string = domainLockFunctionLexicalScopeNode
? this.identifierNamesGenerator.generate(domainLockFunctionLexicalScopeNode)
: this.identifierNamesGenerator.generateNext();
const callsControllerFunctionName: string = domainLockFunctionLexicalScopeNode
? this.identifierNamesGenerator.generate(domainLockFunctionLexicalScopeNode)
: this.identifierNamesGenerator.generateNext();
// domainLock helper nodes append
this.appendCustomNodeIfExist(
CustomCodeHelper.DomainLock,
(customCodeHelper: ICustomCodeHelper<TInitialData<DomainLockCodeHelper>>) => {
customCodeHelper.initialize(callsControllerFunctionName, domainLockFunctionName);
NodeAppender.prepend(domainLockFunctionHostNode, customCodeHelper.getNode());
}
);
// nodeCallsControllerFunction helper nodes append
this.appendCustomNodeIfExist(
CustomCodeHelper.CallsControllerFunction,
(customCodeHelper: ICustomCodeHelper<TInitialData<CallsControllerFunctionCodeHelper>>) => {
customCodeHelper.initialize(this.appendEvent, callsControllerFunctionName);
NodeAppender.prepend(callsControllerHostNode, customCodeHelper.getNode());
}
);
}
public initialize (): void {
this.customCodeHelpers = new Map <CustomCodeHelper, ICustomCodeHelper>();
if (!this.options.domainLock.length) {
return;
}
const domainLockCodeHelper: ICustomCodeHelper<TInitialData<DomainLockCodeHelper>> =
this.customCodeHelperFactory(CustomCodeHelper.DomainLock);
const callsControllerFunctionCodeHelper: ICustomCodeHelper<TInitialData<CallsControllerFunctionCodeHelper>> =
this.customCodeHelperFactory(CustomCodeHelper.CallsControllerFunction);
this.customCodeHelpers.set(CustomCodeHelper.DomainLock, domainLockCodeHelper);
this.customCodeHelpers.set(CustomCodeHelper.CallsControllerFunction, callsControllerFunctionCodeHelper);
}
}
@@ -0,0 +1,111 @@
/**
* @returns {string}
*/
export function DomainLockTemplate (): string {
return `
const {domainLockFunctionName} = {callControllerFunctionName}(this, function () {
{globalVariableTemplate}
const func = function () {
return {
key: 'item',
value: 'attribute',
getAttribute: function () {
for (let i = 0; i < 1000; i--) {
const isPositive = i > 0;
switch (isPositive) {
case true:
return this.item + '_' + this.value + '_' + i;
default:
this.item + '_' + this.value;
}
}
}()
};
};
const regExp = new RegExp("[{diff}]", "g");
const domains = "{domains}".replace(regExp, "").split(";");
let document;
let domain;
let location;
let hostname;
for (let d in that) {
if (d.length == 8 && d.charCodeAt(7) == 116 && d.charCodeAt(5) == 101 && d.charCodeAt(3) == 117 && d.charCodeAt(0) == 100) {
document = d;
break;
}
}
for (let d1 in that[document]) {
if (d1.length == 6 && d1.charCodeAt(5) == 110 && d1.charCodeAt(0) == 100) {
domain = d1;
break;
}
}
if (!("~" > domain)) {
for (let d2 in that[document]) {
if (d2.length == 8 && d2.charCodeAt(7) == 110 && d2.charCodeAt(0) == 108) {
location = d2;
break;
}
}
for (let d3 in that[document][location]) {
if (d3.length == 8 && d3.charCodeAt(7) == 101 && d3.charCodeAt(0) == 104) {
hostname = d3;
break;
}
}
}
if (!document || !that[document]) {
return;
}
const documentDomain = that[document][domain];
const documentLocationHostName = !!that[document][location] && that[document][location][hostname];
const currentDomain = documentDomain || documentLocationHostName;
if (!currentDomain) {
return;
}
let ok = false;
for (let i = 0; i < domains.length; i++) {
const domain = domains[i];
const domainNormalized = domain[0] === String.fromCharCode(46)
? domain.slice(1)
: domain;
const position = currentDomain.length - domainNormalized.length;
const lastIndex = currentDomain.indexOf(domainNormalized, position);
const endsWith = lastIndex !== -1 && lastIndex === position;
if (endsWith) {
if (currentDomain.length == domain.length || domain.indexOf(".") === 0) {
ok = true;
}
}
}
if (!ok) {
data;
} else {
return;
}
func();
});
{domainLockFunctionName}();
`;
}
@@ -0,0 +1,95 @@
import { inject, injectable, } from 'inversify';
import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
import { TIdentifierNamesGeneratorFactory } from '../../types/container/generators/TIdentifierNamesGeneratorFactory';
import { TStatement } from '../../types/node/TStatement';
import { ICustomCodeHelperFormatter } from '../../interfaces/custom-code-helpers/ICustomCodeHelperFormatter';
import { ICustomCodeHelperObfuscator } from '../../interfaces/custom-code-helpers/ICustomCodeHelperObfuscator';
import { IOptions } from '../../interfaces/options/IOptions';
import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
import { ObfuscationTarget } from '../../enums/ObfuscationTarget';
import { initializable } from '../../decorators/Initializable';
import { SelfDefendingTemplate } from './templates/SelfDefendingTemplate';
import { SelfDefendingNoEvalTemplate } from './templates/SelfDefendingNoEvalTemplate';
import { AbstractCustomCodeHelper } from '../AbstractCustomCodeHelper';
import { NodeUtils } from '../../node/NodeUtils';
import { GlobalVariableNoEvalTemplate } from '../common/templates/GlobalVariableNoEvalTemplate';
@injectable()
export class SelfDefendingUnicodeCodeHelper extends AbstractCustomCodeHelper {
/**
* @type {string}
*/
@initializable()
private callsControllerFunctionName!: string;
/**
* @type {string}
*/
@initializable()
private selfDefendingFunctionName!: string;
/**
* @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
* @param {ICustomCodeHelperFormatter} customCodeHelperFormatter
* @param {ICustomCodeHelperObfuscator} customCodeHelperObfuscator
* @param {IRandomGenerator} randomGenerator
* @param {IOptions} options
*/
public constructor (
@inject(ServiceIdentifiers.Factory__IIdentifierNamesGenerator)
identifierNamesGeneratorFactory: TIdentifierNamesGeneratorFactory,
@inject(ServiceIdentifiers.ICustomCodeHelperFormatter) customCodeHelperFormatter: ICustomCodeHelperFormatter,
@inject(ServiceIdentifiers.ICustomCodeHelperObfuscator) customCodeHelperObfuscator: ICustomCodeHelperObfuscator,
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
super(
identifierNamesGeneratorFactory,
customCodeHelperFormatter,
customCodeHelperObfuscator,
randomGenerator,
options
);
}
/**
* @param {string} callsControllerFunctionName
* @param {string} selfDefendingFunctionName
*/
public initialize (callsControllerFunctionName: string, selfDefendingFunctionName: string): void {
this.callsControllerFunctionName = callsControllerFunctionName;
this.selfDefendingFunctionName = selfDefendingFunctionName;
}
/**
* @param {string} codeHelperTemplate
* @returns {TStatement[]}
*/
protected getNodeStructure (codeHelperTemplate: string): TStatement[] {
return NodeUtils.convertCodeToStructure(codeHelperTemplate);
}
/**
* @returns {string}
*/
protected getCodeHelperTemplate (): string {
const globalVariableTemplate: string = this.options.target !== ObfuscationTarget.BrowserNoEval
? this.getGlobalVariableTemplate()
: GlobalVariableNoEvalTemplate();
const selfDefendingTemplate: string = this.options.target !== ObfuscationTarget.BrowserNoEval
? SelfDefendingTemplate()
: SelfDefendingNoEvalTemplate();
return this.customCodeHelperFormatter.formatTemplate(selfDefendingTemplate, {
callControllerFunctionName: this.callsControllerFunctionName,
selfDefendingFunctionName: this.selfDefendingFunctionName,
globalVariableTemplate
});
}
}
Loaded 100 of 3760 files, more files were not shown because too many files have changed in this diff. Show more