mirror of
https://github.com/javascript-obfuscator/javascript-obfuscator
synced 2026-08-09 12:42:29 +00:00
Merge branch 'master' into minification-transformers
# Conflicts: # CHANGELOG.md # dist/index.browser.js # dist/index.cli.js # dist/index.js # src/custom-code-helpers/string-array/templates/string-array-calls-wrapper/AtobTemplate.ts # src/utils/CryptUtils.ts # test/dev/dev.ts
This commit is contained in:
@@ -1,6 +1,16 @@
|
||||
import * as path from 'path';
|
||||
|
||||
import { TDictionary } from '../../types/TDictionary';
|
||||
|
||||
export class CLIUtils {
|
||||
/**
|
||||
* @type {string[]}
|
||||
*/
|
||||
public static readonly allowedConfigFileExtensions: string[] = [
|
||||
'.js',
|
||||
'.json'
|
||||
];
|
||||
|
||||
/**
|
||||
* @param {string} configPath
|
||||
* @returns {TDictionary}
|
||||
@@ -8,13 +18,20 @@ export class CLIUtils {
|
||||
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('Given config path must be a valid `.js` or `.json` file path');
|
||||
throw new ReferenceError(`Cannot open config file with path: ${configPath}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,13 +10,11 @@ import { IEscapeSequenceEncoder } from '../../interfaces/utils/IEscapeSequenceEn
|
||||
import { IOptions } from '../../interfaces/options/IOptions';
|
||||
import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
|
||||
|
||||
import { ObfuscationTarget } from '../../enums/ObfuscationTarget';
|
||||
import { StringArrayEncoding } from '../../enums/StringArrayEncoding';
|
||||
|
||||
import { initializable } from '../../decorators/Initializable';
|
||||
|
||||
import { AtobTemplate } from './templates/string-array-calls-wrapper/AtobTemplate';
|
||||
import { GlobalVariableNoEvalTemplate } from '../common/templates/GlobalVariableNoEvalTemplate';
|
||||
import { Rc4Template } from './templates/string-array-calls-wrapper/Rc4Template';
|
||||
import { SelfDefendingTemplate } from './templates/string-array-calls-wrapper/SelfDefendingTemplate';
|
||||
import { StringArrayBase64DecodeTemplate } from './templates/string-array-calls-wrapper/StringArrayBase64DecodeTemplate';
|
||||
@@ -28,6 +26,12 @@ import { NodeUtils } from '../../node/NodeUtils';
|
||||
|
||||
@injectable()
|
||||
export class StringArrayCallsWrapperCodeHelper extends AbstractCustomCodeHelper {
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
@initializable()
|
||||
private atobFunctionName!: string;
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
@@ -76,13 +80,16 @@ export class StringArrayCallsWrapperCodeHelper extends AbstractCustomCodeHelper
|
||||
/**
|
||||
* @param {string} stringArrayName
|
||||
* @param {string} stringArrayCallsWrapperName
|
||||
* @param {string} atobFunctionName
|
||||
*/
|
||||
public initialize (
|
||||
stringArrayName: string,
|
||||
stringArrayCallsWrapperName: string
|
||||
stringArrayCallsWrapperName: string,
|
||||
atobFunctionName: string
|
||||
): void {
|
||||
this.stringArrayName = stringArrayName;
|
||||
this.stringArrayCallsWrapperName = stringArrayCallsWrapperName;
|
||||
this.atobFunctionName = atobFunctionName;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -117,10 +124,12 @@ export class StringArrayCallsWrapperCodeHelper extends AbstractCustomCodeHelper
|
||||
* @returns {string}
|
||||
*/
|
||||
private getDecodeStringArrayTemplate (): string {
|
||||
const globalVariableTemplate: string = this.options.target !== ObfuscationTarget.BrowserNoEval
|
||||
? this.getGlobalVariableTemplate()
|
||||
: GlobalVariableNoEvalTemplate();
|
||||
const atobPolyfill: string = this.customCodeHelperFormatter.formatTemplate(AtobTemplate(), { globalVariableTemplate });
|
||||
const atobPolyfill: string = this.customCodeHelperFormatter.formatTemplate(AtobTemplate(), {
|
||||
atobFunctionName: this.atobFunctionName
|
||||
});
|
||||
const rc4Polyfill: string = this.customCodeHelperFormatter.formatTemplate(Rc4Template(), {
|
||||
atobFunctionName: this.atobFunctionName
|
||||
});
|
||||
|
||||
let decodeStringArrayTemplate: string = '';
|
||||
let selfDefendingCode: string = '';
|
||||
@@ -144,8 +153,8 @@ export class StringArrayCallsWrapperCodeHelper extends AbstractCustomCodeHelper
|
||||
StringArrayRC4DecodeTemplate(this.randomGenerator),
|
||||
{
|
||||
atobPolyfill,
|
||||
rc4Polyfill,
|
||||
selfDefendingCode,
|
||||
rc4Polyfill: Rc4Template(),
|
||||
stringArrayCallsWrapperName: this.stringArrayCallsWrapperName
|
||||
}
|
||||
);
|
||||
@@ -157,6 +166,7 @@ export class StringArrayCallsWrapperCodeHelper extends AbstractCustomCodeHelper
|
||||
StringArrayBase64DecodeTemplate(this.randomGenerator),
|
||||
{
|
||||
atobPolyfill,
|
||||
atobFunctionName: this.atobFunctionName,
|
||||
selfDefendingCode,
|
||||
stringArrayCallsWrapperName: this.stringArrayCallsWrapperName
|
||||
}
|
||||
|
||||
@@ -118,9 +118,10 @@ export class StringArrayCodeHelperGroup extends AbstractCustomCodeHelperGroup {
|
||||
const stringArrayName: string = this.stringArrayStorage.getStorageName();
|
||||
const stringArrayCallsWrapperName: string = this.stringArrayStorage.getStorageCallsWrapperName();
|
||||
const stringArrayRotationAmount: number = this.stringArrayStorage.getRotationAmount();
|
||||
const atobFunctionName: string = this.randomGenerator.getRandomString(6);
|
||||
|
||||
stringArrayCodeHelper.initialize(this.stringArrayStorage, stringArrayName);
|
||||
stringArrayCallsWrapperCodeHelper.initialize(stringArrayName, stringArrayCallsWrapperName);
|
||||
stringArrayCallsWrapperCodeHelper.initialize(stringArrayName, stringArrayCallsWrapperName, atobFunctionName);
|
||||
stringArrayRotateFunctionCodeHelper.initialize(stringArrayName, stringArrayRotationAmount);
|
||||
|
||||
this.customCodeHelpers.set(CustomCodeHelper.StringArray, stringArrayCodeHelper);
|
||||
|
||||
+15
-20
@@ -6,27 +6,22 @@ import { numbersString } from '../../../../constants/NumbersString';
|
||||
* @returns {string}
|
||||
*/
|
||||
export function AtobTemplate (): string {
|
||||
// swapped lowercase and uppercase groups of alphabet to prevent easy decode!!!!
|
||||
return `
|
||||
(function () {
|
||||
{globalVariableTemplate}
|
||||
|
||||
const chars = '${alphabetStringUppercase}${alphabetString}${numbersString}+/=';
|
||||
var {atobFunctionName} = function (input) {
|
||||
const chars = '${alphabetString}${alphabetStringUppercase}${numbersString}+/=';
|
||||
|
||||
that.atob || (
|
||||
that.atob = function(input) {
|
||||
const str = String(input).replace(/=+$/, '');
|
||||
let output = '';
|
||||
for (
|
||||
let bc = 0, bs, buffer, idx = 0;
|
||||
buffer = str.charAt(idx++);
|
||||
~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer,
|
||||
bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0
|
||||
) {
|
||||
buffer = chars.indexOf(buffer);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
);
|
||||
})();
|
||||
const str = String(input).replace(/=+$/, '');
|
||||
let output = '';
|
||||
for (
|
||||
let bc = 0, bs, buffer, idx = 0;
|
||||
buffer = str.charAt(idx++);
|
||||
~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer,
|
||||
bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0
|
||||
) {
|
||||
buffer = chars.indexOf(buffer);
|
||||
}
|
||||
return output;
|
||||
};
|
||||
`;
|
||||
}
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ export function Rc4Template (): string {
|
||||
const rc4 = function (str, key) {
|
||||
let s = [], j = 0, x, res = '', newStr = '';
|
||||
|
||||
str = atob(str);
|
||||
str = {atobFunctionName}(str);
|
||||
|
||||
for (let k = 0, length = str.length; k < length; k++) {
|
||||
newStr += '%' + ('00' + str.charCodeAt(k).toString(16)).slice(-2);
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ export function StringArrayBase64DecodeTemplate (
|
||||
{atobPolyfill}
|
||||
|
||||
{stringArrayCallsWrapperName}.${base64DecodeFunctionIdentifier} = function (str) {
|
||||
const string = atob(str);
|
||||
const string = {atobFunctionName}(str);
|
||||
let newStringChars = [];
|
||||
|
||||
for (let i = 0, length = string.length; i < length; i++) {
|
||||
|
||||
+2
-1
@@ -100,7 +100,8 @@ export class DeadCodeInjectionTransformer extends AbstractNodeTransformer {
|
||||
* @returns {boolean}
|
||||
*/
|
||||
private static isProhibitedNodeInsideCollectedBlockStatement (targetNode: ESTree.Node): boolean {
|
||||
return NodeGuards.isBreakStatementNode(targetNode)
|
||||
return NodeGuards.isFunctionDeclarationNode(targetNode) // can break code on strict mode
|
||||
|| NodeGuards.isBreakStatementNode(targetNode)
|
||||
|| NodeGuards.isContinueStatementNode(targetNode)
|
||||
|| NodeGuards.isAwaitExpressionNode(targetNode)
|
||||
|| NodeGuards.isSuperNode(targetNode);
|
||||
|
||||
@@ -32,7 +32,8 @@ export class CryptUtils implements ICryptUtils {
|
||||
* @returns {string}
|
||||
*/
|
||||
public btoa (string: string): string {
|
||||
const chars: string = `${alphabetStringUppercase}${alphabetString}${numbersString}+/=`;
|
||||
// swapped lowercase and uppercase groups of alphabet to prevent easy decode!!!!
|
||||
const chars: string = `${alphabetString}${alphabetStringUppercase}${numbersString}+/=`;
|
||||
|
||||
let output: string = '';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user