Skip to content

Commit 412ecb3

Browse files
authored
Merge pull request #133 from MichaelXF/dev
1.7.2
2 parents b1fcb1d + ffe6c4c commit 412ecb3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1853
-584
lines changed

CHANGELOG.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,41 @@
1+
# `1.7.2`
2+
Updates
3+
4+
- `Anti Tooling` & `Expression Obfuscation` improvements
5+
- - No longer expanded by [webcrack](https://github.com/j4k0xb/webcrack), [synchrony](https://github.com/relative/synchrony) & [REstringer](https://github.com/PerimeterX/restringer)
6+
7+
- `String Concealing` improvements
8+
- - Randomizes the charset for each obfuscation
9+
- - Place multiple decryption functions throughout the code
10+
- - These changes aim to defeat [JSConfuser-String-Decryptor](https://github.com/0v41n/JSConfuser-String-Decryptor) and any other RegEx-based decoders
11+
12+
- `Moved Declarations` improvements
13+
- - Now moves some variables as unused parameters on certain functions
14+
15+
- `RGF` improvements
16+
- - More likely to transform functions containing functions
17+
18+
- Fixed [#96](https://github.com/MichaelXF/js-confuser/issues/96)
19+
- - Removed hardcoded limits on `String Concealing`, `String Compression`, and `Duplicate Literals Removal`
20+
21+
- Fixed [#106](https://github.com/MichaelXF/js-confuser/issues/106)
22+
- - Final fix with const variables for `Object Extraction`
23+
24+
- Fixed [#131](https://github.com/MichaelXF/js-confuser/issues/131)
25+
- - __dirname is no longer changed by `Global Concealing`
26+
27+
**New Option**
28+
29+
### `preserveFunctionLength`
30+
- Modified functions will retain the correct `function.length` property. (`true/false`)
31+
Enabled by default.
32+
33+
Minor improvements
34+
- Preserve `function.length`
35+
- Preserve Strict Mode behaviors
36+
- Preserve indirect vs. direct [`eval`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval) use
37+
38+
139
# `1.7.1`
240
Updates
341

README.md

Lines changed: 12 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,8 @@ Converts output to ES5-compatible code. (`true/false`)
131131

132132
Does not cover all cases such as Promises or Generator functions. Use [Babel](https://babel.dev/).
133133

134+
[Learn more here.](https://github.com/MichaelXF/js-confuser/blob/master/docs/ES5.md)
135+
134136
### `renameVariables`
135137

136138
Determines if variables should be renamed. (`true/false`)
@@ -185,29 +187,6 @@ qFaI6S();
185187

186188
Renames top-level variables, turn this off for web-related scripts. Enabled by default. (`true/false`)
187189

188-
```js
189-
// Output (Same input from above)
190-
var twoSum = function (Oc4nmjB, Fk3nptX) {
191-
var on_KnCm = {};
192-
var lqAauc = Oc4nmjB["length"];
193-
for (var mALijp8 = 0; mALijp8 < lqAauc; mALijp8++) {
194-
if (Oc4nmjB[mALijp8] in on_KnCm) {
195-
return [on_KnCm[Oc4nmjB[mALijp8]], mALijp8];
196-
}
197-
on_KnCm[Fk3nptX - Oc4nmjB[mALijp8]] = mALijp8;
198-
}
199-
return [-1, -1];
200-
};
201-
var test = function () {
202-
var y5ySeZ = [2, 7, 11, 15];
203-
var gHYMOm = 9;
204-
var aAdj3v = [0, 1];
205-
var GnLVHX = twoSum(y5ySeZ, gHYMOm);
206-
!(ok(GnLVHX[0] === aAdj3v[0]), ok(GnLVHX[1] === aAdj3v[1]));
207-
};
208-
test();
209-
```
210-
211190
### `identifierGenerator`
212191

213192
Determines how variables are renamed.
@@ -392,8 +371,11 @@ yAt1T_y(-93)["log"]("Hello World");
392371
```
393372

394373
### `stringCompression`
374+
395375
String Compression uses LZW's compression algorithm to compress strings. (`true/false/0-1`)
396376

377+
Use a number to control the percentage of strings.
378+
397379
`"console"` -> `inflate('replaĕ!ğğuģģ<~@')`
398380

399381
### `stringConcealing`
@@ -666,9 +648,8 @@ function getAreaOfCircle(radius) {
666648
}
667649

668650
// Output
669-
function getAreaOfCircle(yLu5YB1) {
670-
var eUf7Wle, XVYH4D;
671-
var F8QuPL = Math["PI"];
651+
function getAreaOfCircle(yLu5YB1, eUf7Wle, XVYH4D, F8QuPL) {
652+
F8QuPL = Math["PI"];
672653
typeof ((eUf7Wle = Math["pow"](yLu5YB1, 2)), (XVYH4D = F8QuPL * eUf7Wle));
673654
return XVYH4D;
674655
}
@@ -835,7 +816,11 @@ These features are experimental or a security concern.
835816
// experimental
836817
identifierGenerator: function(){
837818
return "myvar_" + (counter++);
838-
}
819+
},
820+
821+
// Modified functions will retain the correct `function.length` property.
822+
// Enabled by default.
823+
preserveFunctionLength: false
839824
}
840825
```
841826

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@
2222
"author": "MichaelXF",
2323
"license": "MIT",
2424
"dependencies": {
25-
"acorn": "^8.10.0",
26-
"escodegen": "^2.0.0"
25+
"acorn": "^8.12.1",
26+
"escodegen": "^2.1.0"
2727
},
2828
"devDependencies": {
2929
"@babel/cli": "^7.17.6",

src/constants.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,15 @@ export const reservedIdentifiers = new Set([
8282

8383
export const noRenameVariablePrefix = "__NO_JS_CONFUSER_RENAME__";
8484
export const placeholderVariablePrefix = "__p_";
85+
86+
/**
87+
* Tells the obfuscator this function is predictable:
88+
* - Never called with extraneous parameters
89+
*/
90+
export const predictableFunctionTag = "__JS_PREDICT__";
91+
92+
/**
93+
* Tells the obfuscator this function is critical for the Obfuscated code.
94+
* - Example: string decryption function
95+
*/
96+
export const criticalFunctionTag = "__JS_CRITICAL__";

src/options.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,15 @@ export interface ObfuscateOptions {
585585
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
586586
*/
587587
debugComments?: boolean;
588+
589+
/**
590+
* ### `preserveFunctionLength`
591+
*
592+
* Modified functions will retain the correct `function.length` property. Enabled by default. (`true/false`)
593+
*
594+
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
595+
*/
596+
preserveFunctionLength?: boolean;
588597
}
589598

590599
const validProperties = new Set([
@@ -619,6 +628,7 @@ const validProperties = new Set([
619628
"verbose",
620629
"globalVariables",
621630
"debugComments",
631+
"preserveFunctionLength",
622632
]);
623633

624634
const validOses = new Set(["windows", "linux", "osx", "ios", "android"]);
@@ -764,6 +774,9 @@ export async function correctOptions(
764774
if (!options.hasOwnProperty("renameGlobals")) {
765775
options.renameGlobals = true; // RenameGlobals is on by default
766776
}
777+
if (!options.hasOwnProperty("preserveFunctionLength")) {
778+
options.preserveFunctionLength = true; // preserveFunctionLength is on by default
779+
}
767780

768781
if (options.globalVariables && !(options.globalVariables instanceof Set)) {
769782
options.globalVariables = new Set(Object.keys(options.globalVariables));

src/order.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,11 @@ export enum ObfuscateOrder {
4646

4747
Minify = 28,
4848

49+
AntiTooling = 29,
50+
4951
RenameVariables = 30,
5052

5153
ES5 = 31,
5254

53-
AntiTooling = 34,
54-
5555
Finalizer = 35,
5656
}

src/templates/bufferToString.ts

Lines changed: 49 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,59 @@
1+
import {
2+
placeholderVariablePrefix,
3+
predictableFunctionTag,
4+
} from "../constants";
15
import Template from "./template";
26

3-
export const BufferToStringTemplate = Template(`
4-
function __getGlobal(){
7+
export const GetGlobalTemplate = Template(`
8+
function ${placeholderVariablePrefix}CFG__getGlobalThis${predictableFunctionTag}(){
9+
return globalThis
10+
}
11+
12+
function ${placeholderVariablePrefix}CFG__getGlobal${predictableFunctionTag}(){
13+
return global
14+
}
15+
16+
function ${placeholderVariablePrefix}CFG__getWindow${predictableFunctionTag}(){
17+
return window
18+
}
19+
20+
function ${placeholderVariablePrefix}CFG__getThisFunction${predictableFunctionTag}(){
21+
return new Function("return this")()
22+
}
23+
24+
function {getGlobalFnName}(array = [
25+
${placeholderVariablePrefix}CFG__getGlobalThis${predictableFunctionTag},
26+
${placeholderVariablePrefix}CFG__getGlobal${predictableFunctionTag},
27+
${placeholderVariablePrefix}CFG__getWindow${predictableFunctionTag},
28+
${placeholderVariablePrefix}CFG__getThisFunction${predictableFunctionTag}
29+
]){
30+
var bestMatch
31+
var itemsToSearch = []
532
try {
6-
return global||window|| ( new Function("return this") )();
7-
} catch ( e ) {
33+
bestMatch = Object
34+
itemsToSearch["push"](("")["__proto__"]["constructor"]["name"])
35+
} catch(e) {
36+
37+
}
38+
A: for(var i = 0; i < array["length"]; i++) {
839
try {
9-
return this;
10-
} catch ( e ) {
11-
return {};
12-
}
40+
bestMatch = array[i]()
41+
for(var j = 0; j < itemsToSearch["length"]; j++) {
42+
if(typeof bestMatch[itemsToSearch[j]] === "undefined") continue A;
43+
}
44+
return bestMatch
45+
} catch(e) {}
1346
}
47+
48+
return bestMatch || this;
1449
}
50+
`);
1551

16-
var __globalObject = __getGlobal() || {};
52+
export const BufferToStringTemplate = Template(`
53+
54+
${GetGlobalTemplate.source}
55+
56+
var __globalObject = {getGlobalFnName}() || {};
1757
var __TextDecoder = __globalObject["TextDecoder"];
1858
var __Uint8Array = __globalObject["Uint8Array"];
1959
var __Buffer = __globalObject["Buffer"];
@@ -63,6 +103,4 @@ export const BufferToStringTemplate = Template(`
63103
return utf8ArrayToStr(buffer);
64104
}
65105
}
66-
67-
68106
`);

src/templates/functionLength.ts

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,30 @@ import Template from "./template";
33
/**
44
* Helper function to set `function.length` property.
55
*/
6-
export const FunctionLengthTemplate = Template(`
6+
export const FunctionLengthTemplate = Template(
7+
`
78
function {name}(functionObject, functionLength){
8-
Object["defineProperty"](functionObject, "length", {
9+
{ObjectDefineProperty}(functionObject, "length", {
910
"value": functionLength,
1011
"configurable": true
1112
});
1213
return functionObject;
1314
}
14-
`);
15+
`,
16+
`
17+
function {name}(functionObject, functionLength){
18+
return {ObjectDefineProperty}(functionObject, "length", {
19+
"value": functionLength,
20+
"configurable": true
21+
});
22+
}
23+
`,
24+
`
25+
function {name}(functionObject, functionLength){
26+
return {ObjectDefineProperty}["call"](null, functionObject, "length", {
27+
"value": functionLength,
28+
"configurable": true
29+
});
30+
}
31+
`
32+
);

src/templates/globals.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import Template from "./template";
2+
3+
export const ObjectDefineProperty = Template(`Object["defineProperty"]`);

0 commit comments

Comments
 (0)