jsarmor 1.0.7 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli/index.js +9 -2
- package/core/antidebug.js +3 -5
- package/core/antivm.js +19 -0
- package/core/beautifyGuard.js +3 -7
- package/core/controlflow.js +7 -18
- package/core/deadcode.js +12 -6
- package/core/junkcode.js +11 -10
- package/core/rc4.js +15 -24
- package/core/renamer.js +100 -22
- package/core/selfdefend.js +6 -9
- package/core/stringArray.js +105 -45
- package/core/stringRuntime.js +56 -0
- package/core/unicode.js +1 -5
- package/core/unicodeIdentifier.js +67 -0
- package/package.json +1 -1
- /package/core/{runtime.js → rumtime.js} +0 -0
package/cli/index.js
CHANGED
|
@@ -19,6 +19,9 @@ import { injectDeadCode, generateDeadRuntime } from "../core/deadcode.js";
|
|
|
19
19
|
import { injectAntiDebug } from "../core/antidebug.js";
|
|
20
20
|
import { antiBeautify } from "../core/beautifyGuard.js";
|
|
21
21
|
import { selfDefend } from "../core/selfdefend.js";
|
|
22
|
+
import { unicodeIdentifiers } from "../core/unicodeIdentifier.js";
|
|
23
|
+
import { buildStringRuntime } from "../core/stringRuntime.js";
|
|
24
|
+
import { antiVM } from "../core/antivm.js";
|
|
22
25
|
|
|
23
26
|
import { watermark } from "../utils/watermark.js";
|
|
24
27
|
|
|
@@ -107,7 +110,7 @@ barCompleteChar:"█",
|
|
|
107
110
|
barIncompleteChar:"░"
|
|
108
111
|
});
|
|
109
112
|
|
|
110
|
-
bar.start(
|
|
113
|
+
bar.start(7,0);
|
|
111
114
|
|
|
112
115
|
const ast = parseCode(code);
|
|
113
116
|
bar.increment();
|
|
@@ -115,6 +118,9 @@ bar.increment();
|
|
|
115
118
|
renameVariables(ast);
|
|
116
119
|
bar.increment();
|
|
117
120
|
|
|
121
|
+
unicodeIdentifiers(ast);
|
|
122
|
+
bar.increment();
|
|
123
|
+
|
|
118
124
|
const pool = encodeStrings(ast);
|
|
119
125
|
bar.increment();
|
|
120
126
|
|
|
@@ -143,8 +149,9 @@ const final =
|
|
|
143
149
|
watermark(user) +
|
|
144
150
|
injectAntiDebug() +
|
|
145
151
|
antiBeautify() +
|
|
152
|
+
antiVM() +
|
|
146
153
|
selfDefend() +
|
|
147
|
-
|
|
154
|
+
buildStringRuntime(pool) +
|
|
148
155
|
runtimeJunk +
|
|
149
156
|
generateJunk() +
|
|
150
157
|
output;
|
package/core/antidebug.js
CHANGED
package/core/antivm.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export function antiVM(){
|
|
2
|
+
return `
|
|
3
|
+
|
|
4
|
+
;(function(){
|
|
5
|
+
|
|
6
|
+
var s=(typeof navigator!="undefined"?navigator.userAgent:"node").toLowerCase()
|
|
7
|
+
|
|
8
|
+
if(
|
|
9
|
+
s.includes("vmware")||
|
|
10
|
+
s.includes("virtualbox")||
|
|
11
|
+
s.includes("qemu")
|
|
12
|
+
){
|
|
13
|
+
console.warn("VM detected");
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
})()
|
|
17
|
+
|
|
18
|
+
`
|
|
19
|
+
}
|
package/core/beautifyGuard.js
CHANGED
|
@@ -1,21 +1,17 @@
|
|
|
1
1
|
export function antiBeautify(){
|
|
2
|
-
|
|
3
2
|
return `
|
|
4
3
|
|
|
5
|
-
(function(){
|
|
4
|
+
;(function(){
|
|
6
5
|
|
|
7
6
|
const start=Date.now()
|
|
8
|
-
|
|
9
7
|
debugger
|
|
10
|
-
|
|
11
8
|
const end=Date.now()
|
|
12
9
|
|
|
13
|
-
if(end-start>
|
|
14
|
-
|
|
10
|
+
if(end-start>1000){
|
|
11
|
+
console.warn("Debug detected")
|
|
15
12
|
}
|
|
16
13
|
|
|
17
14
|
})();
|
|
18
15
|
|
|
19
16
|
`;
|
|
20
|
-
|
|
21
17
|
}
|
package/core/controlflow.js
CHANGED
|
@@ -93,24 +93,13 @@ Function(path){
|
|
|
93
93
|
});
|
|
94
94
|
|
|
95
95
|
const whileLoop = t.whileStatement(
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
t.
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
t.ifStatement(
|
|
105
|
-
t.binaryExpression(
|
|
106
|
-
">=",
|
|
107
|
-
t.identifier("_s"),
|
|
108
|
-
t.numericLiteral(body.length)
|
|
109
|
-
),
|
|
110
|
-
t.breakStatement()
|
|
111
|
-
)
|
|
112
|
-
|
|
113
|
-
])
|
|
96
|
+
t.binaryExpression("<", t.identifier("_s"), t.numericLiteral(body.length)),
|
|
97
|
+
t.blockStatement([
|
|
98
|
+
t.switchStatement(
|
|
99
|
+
t.identifier("_s"),
|
|
100
|
+
cases
|
|
101
|
+
)
|
|
102
|
+
])
|
|
114
103
|
);
|
|
115
104
|
|
|
116
105
|
const newBody = [];
|
package/core/deadcode.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import
|
|
1
|
+
import traverseModule from "@babel/traverse";
|
|
2
2
|
import * as t from "@babel/types";
|
|
3
3
|
import { randomInt } from "../utils/random.js";
|
|
4
4
|
|
|
5
|
+
const traverse = traverseModule.default;
|
|
6
|
+
|
|
5
7
|
const patterns = [
|
|
6
8
|
|
|
7
9
|
"var _a=Math.random();if(_a>2){console.log(_a)}",
|
|
@@ -17,7 +19,9 @@ const patterns = [
|
|
|
17
19
|
|
|
18
20
|
];
|
|
19
21
|
|
|
20
|
-
|
|
22
|
+
/* generate nhiều pattern */
|
|
23
|
+
|
|
24
|
+
for(let i=0;i<20;i++){
|
|
21
25
|
|
|
22
26
|
patterns.push(`
|
|
23
27
|
var _junk${i}=Math.random()*${randomInt(1,999)};
|
|
@@ -34,9 +38,11 @@ return patterns[Math.floor(Math.random()*patterns.length)];
|
|
|
34
38
|
|
|
35
39
|
}
|
|
36
40
|
|
|
41
|
+
/* AST deadcode */
|
|
42
|
+
|
|
37
43
|
export function injectDeadCode(ast){
|
|
38
44
|
|
|
39
|
-
traverse
|
|
45
|
+
traverse(ast,{
|
|
40
46
|
|
|
41
47
|
BlockStatement(path){
|
|
42
48
|
|
|
@@ -76,14 +82,14 @@ path.node.body.unshift(fake);
|
|
|
76
82
|
|
|
77
83
|
}
|
|
78
84
|
|
|
85
|
+
/* runtime deadcode */
|
|
86
|
+
|
|
79
87
|
export function generateDeadRuntime(){
|
|
80
88
|
|
|
81
89
|
let out="";
|
|
82
90
|
|
|
83
|
-
for(let i=0;i<
|
|
84
|
-
|
|
91
|
+
for(let i=0;i<10;i++){
|
|
85
92
|
out+=randomPattern()+"\n";
|
|
86
|
-
|
|
87
93
|
}
|
|
88
94
|
|
|
89
95
|
return out;
|
package/core/junkcode.js
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
|
-
export function generateJunk()
|
|
1
|
+
export function generateJunk(){
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
return `
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
var _假=Math.random()
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
function _伪(){
|
|
8
|
+
try{
|
|
9
|
+
return Function("return 1+1")()
|
|
10
|
+
}catch(e){}
|
|
11
11
|
}
|
|
12
|
-
`);
|
|
13
12
|
|
|
14
|
-
|
|
13
|
+
if(_假>2){
|
|
14
|
+
console.log(_伪())
|
|
15
|
+
}
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
`
|
|
17
18
|
|
|
18
19
|
}
|
package/core/rc4.js
CHANGED
|
@@ -1,42 +1,33 @@
|
|
|
1
1
|
export function rc4(key, str){
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
let j=0
|
|
5
|
-
let x
|
|
6
|
-
let res=""
|
|
3
|
+
if(!key) throw new Error("RC4 key empty")
|
|
7
4
|
|
|
8
|
-
|
|
9
|
-
s[i]=i
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
for(let i=0;i<256;i++){
|
|
13
|
-
|
|
14
|
-
j=(j+s[i]+key.charCodeAt(i%key.length))%256
|
|
5
|
+
let s=[],j=0,x,res=""
|
|
15
6
|
|
|
16
|
-
|
|
17
|
-
s[i]=s[j]
|
|
18
|
-
s[j]=x
|
|
7
|
+
for(let i=0;i<256;i++) s[i]=i
|
|
19
8
|
|
|
9
|
+
for(let i=0;i<256;i++){
|
|
10
|
+
j=(j+s[i]+key.charCodeAt(i%key.length))&255
|
|
11
|
+
x=s[i]
|
|
12
|
+
s[i]=s[j]
|
|
13
|
+
s[j]=x
|
|
20
14
|
}
|
|
21
15
|
|
|
22
16
|
let i=0
|
|
23
17
|
j=0
|
|
24
18
|
|
|
25
19
|
for(let y=0;y<str.length;y++){
|
|
20
|
+
i=(i+1)&255
|
|
21
|
+
j=(j+s[i])&255
|
|
26
22
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
x=s[i]
|
|
31
|
-
s[i]=s[j]
|
|
32
|
-
s[j]=x
|
|
23
|
+
x=s[i]
|
|
24
|
+
s[i]=s[j]
|
|
25
|
+
s[j]=x
|
|
33
26
|
|
|
34
|
-
let k=s[(s[i]+s[j])
|
|
35
|
-
|
|
36
|
-
res+=String.fromCharCode(str.charCodeAt(y)^k)
|
|
27
|
+
let k=s[(s[i]+s[j])&255]
|
|
37
28
|
|
|
29
|
+
res += String.fromCharCode(str.charCodeAt(y) ^ k)
|
|
38
30
|
}
|
|
39
31
|
|
|
40
32
|
return res
|
|
41
|
-
|
|
42
33
|
}
|
package/core/renamer.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import traverseModule from "@babel/traverse";
|
|
2
|
+
import * as t from "@babel/types";
|
|
2
3
|
|
|
3
4
|
const traverse = traverseModule.default;
|
|
4
5
|
|
|
@@ -15,50 +16,127 @@ const reserved = new Set([
|
|
|
15
16
|
"setInterval"
|
|
16
17
|
]);
|
|
17
18
|
|
|
19
|
+
/* multilingual identifier */
|
|
20
|
+
|
|
21
|
+
const jp = "あいうえおかきくけこさしすせそたちつてと";
|
|
22
|
+
const kr = "가나다라마바사아자차카타파하";
|
|
23
|
+
const cn = "的一是在不了有和人这中大为上个国我以要他";
|
|
24
|
+
const latin = "abcdefghijklmnopqrstuvwxyz";
|
|
25
|
+
|
|
26
|
+
const pool = jp + kr + cn + latin;
|
|
27
|
+
|
|
18
28
|
function randomName(){
|
|
19
|
-
|
|
20
|
-
let name="_";
|
|
29
|
+
let name="_0x";
|
|
21
30
|
for(let i=0;i<6;i++){
|
|
22
|
-
name+=
|
|
31
|
+
name+=pool[Math.floor(Math.random()*pool.length)];
|
|
23
32
|
}
|
|
24
33
|
return name;
|
|
25
34
|
}
|
|
26
35
|
|
|
27
36
|
export function renameVariables(ast){
|
|
28
37
|
|
|
38
|
+
const renamed = new Map();
|
|
39
|
+
|
|
29
40
|
traverse(ast,{
|
|
30
|
-
Program(path){
|
|
31
41
|
|
|
32
|
-
|
|
42
|
+
Identifier(path){
|
|
43
|
+
|
|
44
|
+
// chỉ rename binding identifier
|
|
45
|
+
if(!path.isBindingIdentifier()) return;
|
|
46
|
+
|
|
47
|
+
const name = path.node.name;
|
|
48
|
+
|
|
49
|
+
// skip reserved
|
|
50
|
+
if(reserved.has(name)) return;
|
|
51
|
+
|
|
52
|
+
// skip already obfuscated
|
|
53
|
+
if(name.startsWith("_0x")) return;
|
|
33
54
|
|
|
34
|
-
|
|
55
|
+
// skip short names (tránh phá scope nhỏ)
|
|
56
|
+
if(name.length < 3) return;
|
|
35
57
|
|
|
36
|
-
|
|
58
|
+
const binding = path.scope.getBinding(name);
|
|
59
|
+
if(!binding) return;
|
|
37
60
|
|
|
38
|
-
|
|
61
|
+
// skip params
|
|
62
|
+
if(binding.kind === "param") return;
|
|
39
63
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
if(binding.path.isImportDefaultSpecifier?.()) continue;
|
|
43
|
-
if(binding.path.isImportNamespaceSpecifier?.()) continue;
|
|
64
|
+
// skip global scope
|
|
65
|
+
if(!binding.scope.parent) return;
|
|
44
66
|
|
|
45
|
-
|
|
46
|
-
|
|
67
|
+
// skip mutated variables (tránh break logic)
|
|
68
|
+
if(binding.constantViolations && binding.constantViolations.length > 0){
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// skip if already renamed
|
|
73
|
+
if(renamed.has(binding)){
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const newName = randomName();
|
|
47
78
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
79
|
+
try{
|
|
80
|
+
path.scope.rename(name,newName);
|
|
81
|
+
renamed.set(binding,newName);
|
|
82
|
+
}catch{}
|
|
51
83
|
|
|
52
|
-
|
|
53
|
-
if(!binding.scope.parent) continue;
|
|
84
|
+
},
|
|
54
85
|
|
|
55
|
-
|
|
86
|
+
FunctionDeclaration(path){
|
|
56
87
|
|
|
57
|
-
|
|
88
|
+
if(!path.node.id) return;
|
|
58
89
|
|
|
59
|
-
|
|
90
|
+
const name = path.node.id.name;
|
|
60
91
|
|
|
92
|
+
if(reserved.has(name)) return;
|
|
93
|
+
if(name.startsWith("_0x")) return;
|
|
94
|
+
|
|
95
|
+
const binding = path.scope.getBinding(name);
|
|
96
|
+
if(!binding) return;
|
|
97
|
+
|
|
98
|
+
if(binding.constantViolations && binding.constantViolations.length > 0){
|
|
99
|
+
return;
|
|
61
100
|
}
|
|
101
|
+
|
|
102
|
+
if(renamed.has(binding)) return;
|
|
103
|
+
|
|
104
|
+
const newName = randomName();
|
|
105
|
+
|
|
106
|
+
try{
|
|
107
|
+
path.scope.rename(name,newName);
|
|
108
|
+
renamed.set(binding,newName);
|
|
109
|
+
}catch{}
|
|
110
|
+
|
|
111
|
+
},
|
|
112
|
+
|
|
113
|
+
ClassDeclaration(path){
|
|
114
|
+
|
|
115
|
+
if(!path.node.id) return;
|
|
116
|
+
|
|
117
|
+
const name = path.node.id.name;
|
|
118
|
+
|
|
119
|
+
if(reserved.has(name)) return;
|
|
120
|
+
if(name.startsWith("_0x")) return;
|
|
121
|
+
|
|
122
|
+
const binding = path.scope.getBinding(name);
|
|
123
|
+
if(!binding) return;
|
|
124
|
+
|
|
125
|
+
if(binding.constantViolations && binding.constantViolations.length > 0){
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if(renamed.has(binding)) return;
|
|
130
|
+
|
|
131
|
+
const newName = randomName();
|
|
132
|
+
|
|
133
|
+
try{
|
|
134
|
+
path.scope.rename(name,newName);
|
|
135
|
+
renamed.set(binding,newName);
|
|
136
|
+
}catch{}
|
|
137
|
+
|
|
138
|
+
}
|
|
139
|
+
|
|
62
140
|
});
|
|
63
141
|
|
|
64
142
|
}
|
package/core/selfdefend.js
CHANGED
|
@@ -1,23 +1,20 @@
|
|
|
1
1
|
export function selfDefend(){
|
|
2
|
-
|
|
3
2
|
return `
|
|
4
3
|
|
|
5
|
-
(function(){
|
|
4
|
+
;(function(){
|
|
6
5
|
|
|
7
6
|
function guard(){
|
|
8
|
-
|
|
9
|
-
const src=guard.toString()
|
|
10
|
-
|
|
7
|
+
try{
|
|
8
|
+
const src = guard.toString()
|
|
11
9
|
if(!src.includes("guard")){
|
|
12
|
-
|
|
10
|
+
console.warn("Tamper detected")
|
|
13
11
|
}
|
|
14
|
-
|
|
12
|
+
}catch(e){}
|
|
15
13
|
}
|
|
16
14
|
|
|
17
|
-
setInterval(guard,
|
|
15
|
+
setInterval(guard,5000)
|
|
18
16
|
|
|
19
17
|
})();
|
|
20
18
|
|
|
21
19
|
`;
|
|
22
|
-
|
|
23
20
|
}
|
package/core/stringArray.js
CHANGED
|
@@ -8,15 +8,52 @@ export function encodeStrings(ast){
|
|
|
8
8
|
const pool = [];
|
|
9
9
|
const map = new Map();
|
|
10
10
|
|
|
11
|
+
function rand(a,b){
|
|
12
|
+
return Math.floor(Math.random()*(b-a))+a;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function buildIndexExpression(index){
|
|
16
|
+
|
|
17
|
+
const mode = rand(0,3);
|
|
18
|
+
|
|
19
|
+
if(mode===0){
|
|
20
|
+
|
|
21
|
+
const key = rand(1,50);
|
|
22
|
+
|
|
23
|
+
return t.binaryExpression(
|
|
24
|
+
"^",
|
|
25
|
+
t.numericLiteral(index ^ key),
|
|
26
|
+
t.numericLiteral(key)
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if(mode===1){
|
|
32
|
+
|
|
33
|
+
const key = rand(1,20);
|
|
34
|
+
|
|
35
|
+
return t.binaryExpression(
|
|
36
|
+
"-",
|
|
37
|
+
t.numericLiteral(index + key),
|
|
38
|
+
t.numericLiteral(key)
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return t.numericLiteral(index);
|
|
44
|
+
|
|
45
|
+
}
|
|
46
|
+
|
|
11
47
|
function getIndex(value){
|
|
12
48
|
|
|
13
49
|
if(map.has(value)){
|
|
14
|
-
|
|
50
|
+
return map.get(value);
|
|
15
51
|
}
|
|
16
52
|
|
|
17
53
|
const index = pool.length;
|
|
18
54
|
|
|
19
55
|
pool.push(value);
|
|
56
|
+
|
|
20
57
|
map.set(value,index);
|
|
21
58
|
|
|
22
59
|
return index;
|
|
@@ -24,52 +61,75 @@ return index;
|
|
|
24
61
|
}
|
|
25
62
|
|
|
26
63
|
traverse(ast,{
|
|
64
|
+
|
|
27
65
|
StringLiteral(path){
|
|
28
66
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
67
|
+
const value = path.node.value;
|
|
68
|
+
|
|
69
|
+
if(!value) return;
|
|
70
|
+
|
|
71
|
+
/* skip directives */
|
|
72
|
+
|
|
73
|
+
if(path.parent.type === "Directive") return;
|
|
74
|
+
|
|
75
|
+
if(value === "use strict") return;
|
|
76
|
+
|
|
77
|
+
/* skip require */
|
|
78
|
+
|
|
79
|
+
if(
|
|
80
|
+
path.parent.type === "CallExpression" &&
|
|
81
|
+
path.parent.callee &&
|
|
82
|
+
path.parent.callee.name === "require"
|
|
83
|
+
){
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/* skip import */
|
|
88
|
+
|
|
89
|
+
if(path.parent.type === "ImportDeclaration") return;
|
|
90
|
+
|
|
91
|
+
/* skip object key */
|
|
92
|
+
|
|
93
|
+
if(
|
|
94
|
+
path.parent.type === "ObjectProperty" &&
|
|
95
|
+
path.parent.key === path.node
|
|
96
|
+
){
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/* skip member property */
|
|
101
|
+
|
|
102
|
+
if(
|
|
103
|
+
path.parent.type === "MemberExpression" &&
|
|
104
|
+
path.parent.property === path.node
|
|
105
|
+
){
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/* skip template */
|
|
110
|
+
|
|
111
|
+
if(path.parent.type === "TemplateLiteral") return;
|
|
112
|
+
|
|
113
|
+
/* skip inside decrypt runtime */
|
|
114
|
+
|
|
115
|
+
if(path.findParent(p =>
|
|
116
|
+
p.isCallExpression() &&
|
|
117
|
+
p.node.callee &&
|
|
118
|
+
p.node.callee.name === "_解密"
|
|
119
|
+
)){
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const index = getIndex(value);
|
|
124
|
+
|
|
125
|
+
const expr = buildIndexExpression(index);
|
|
126
|
+
|
|
127
|
+
path.replaceWith(
|
|
128
|
+
t.callExpression(
|
|
129
|
+
t.identifier("_解密"),
|
|
130
|
+
[expr]
|
|
131
|
+
)
|
|
132
|
+
);
|
|
73
133
|
|
|
74
134
|
}
|
|
75
135
|
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { rc4 } from "./rc4.js"
|
|
2
|
+
|
|
3
|
+
export function buildStringRuntime(pool){
|
|
4
|
+
|
|
5
|
+
const key = Math.random().toString(36).slice(2)
|
|
6
|
+
|
|
7
|
+
const encrypted = pool.map(s=>{
|
|
8
|
+
const enc = rc4(key, s)
|
|
9
|
+
return Buffer.from(enc, "binary").toString("base64")
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
return `
|
|
13
|
+
|
|
14
|
+
var _池 = ${JSON.stringify(encrypted)};
|
|
15
|
+
var _缓存 = {};
|
|
16
|
+
|
|
17
|
+
function _解密(i){
|
|
18
|
+
|
|
19
|
+
if(_缓存[i]) return _缓存[i];
|
|
20
|
+
|
|
21
|
+
var b64 = _池[i];
|
|
22
|
+
|
|
23
|
+
var data = typeof atob === "function"
|
|
24
|
+
? atob(b64)
|
|
25
|
+
: Buffer.from(b64,"base64").toString("binary");
|
|
26
|
+
|
|
27
|
+
var s=[],j=0,x,res="";
|
|
28
|
+
|
|
29
|
+
for(var k=0;k<256;k++) s[k]=k;
|
|
30
|
+
|
|
31
|
+
for(k=0;k<256;k++){
|
|
32
|
+
j=(j+s[k]+"${key}".charCodeAt(k%"${key}".length))%256;
|
|
33
|
+
x=s[k];s[k]=s[j];s[j]=x;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
k=0;j=0;
|
|
37
|
+
|
|
38
|
+
for(var y=0;y<data.length;y++){
|
|
39
|
+
|
|
40
|
+
k=(k+1)%256;
|
|
41
|
+
j=(j+s[k])%256;
|
|
42
|
+
|
|
43
|
+
x=s[k];s[k]=s[j];s[j]=x;
|
|
44
|
+
|
|
45
|
+
var t=s[(s[k]+s[j])%256];
|
|
46
|
+
|
|
47
|
+
res+=String.fromCharCode(data.charCodeAt(y)^t);
|
|
48
|
+
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
_缓存[i]=res;
|
|
52
|
+
return res;
|
|
53
|
+
|
|
54
|
+
}
|
|
55
|
+
`
|
|
56
|
+
}
|
package/core/unicode.js
CHANGED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import traverseModule from "@babel/traverse";
|
|
2
|
+
|
|
3
|
+
const traverse = traverseModule.default;
|
|
4
|
+
|
|
5
|
+
const reserved = new Set([
|
|
6
|
+
"require",
|
|
7
|
+
"module",
|
|
8
|
+
"exports",
|
|
9
|
+
"console",
|
|
10
|
+
"process",
|
|
11
|
+
"Buffer"
|
|
12
|
+
]);
|
|
13
|
+
|
|
14
|
+
const jp="あいうえおかきくけこ";
|
|
15
|
+
const kr="가나다라마바사";
|
|
16
|
+
const cn="的一是在不了有和";
|
|
17
|
+
|
|
18
|
+
const pool = jp + kr + cn;
|
|
19
|
+
|
|
20
|
+
function randChar(){
|
|
21
|
+
return pool[Math.floor(Math.random()*pool.length)];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function randomName(){
|
|
25
|
+
|
|
26
|
+
let name="_0x";
|
|
27
|
+
|
|
28
|
+
for(let i=0;i<4;i++){
|
|
29
|
+
name+=randChar();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return name;
|
|
33
|
+
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function unicodeIdentifiers(ast){
|
|
37
|
+
|
|
38
|
+
traverse(ast,{
|
|
39
|
+
|
|
40
|
+
Identifier(path){
|
|
41
|
+
|
|
42
|
+
if(!path.isBindingIdentifier()) return;
|
|
43
|
+
|
|
44
|
+
const name = path.node.name;
|
|
45
|
+
|
|
46
|
+
if(name.length < 3) return;
|
|
47
|
+
if(name.startsWith("_0x")) return;
|
|
48
|
+
if(reserved.has(name)) return;
|
|
49
|
+
|
|
50
|
+
const binding = path.scope.getBinding(name);
|
|
51
|
+
|
|
52
|
+
if(!binding) return;
|
|
53
|
+
if(binding.identifier !== path.node) return;
|
|
54
|
+
|
|
55
|
+
if(binding.constantViolations.length > 0) return;
|
|
56
|
+
|
|
57
|
+
const newName = randomName();
|
|
58
|
+
|
|
59
|
+
try{
|
|
60
|
+
path.scope.rename(name,newName);
|
|
61
|
+
}catch{}
|
|
62
|
+
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
}
|
package/package.json
CHANGED
|
File without changes
|