jsarmor 1.0.4 → 1.0.6
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/LICENSE +76 -0
- package/README.md +217 -0
- package/cli/index.js +176 -176
- package/core/antidebug.js +15 -15
- package/docs/banner.jpg +0 -0
- package/docs/shitpost +1 -0
- package/package.json +25 -16
- package/readme.md +0 -163
package/LICENSE
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
JSArmor License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Swp-dev
|
|
4
|
+
|
|
5
|
+
This license governs the use of the JSArmor software.
|
|
6
|
+
|
|
7
|
+
Permission is granted to use, modify, and distribute this software for
|
|
8
|
+
personal, educational, and non-commercial purposes under the following
|
|
9
|
+
conditions.
|
|
10
|
+
|
|
11
|
+
1. Attribution Required
|
|
12
|
+
|
|
13
|
+
Any use, modification, or redistribution of this software must clearly
|
|
14
|
+
credit the original author.
|
|
15
|
+
|
|
16
|
+
Author: Swp-dev
|
|
17
|
+
Project: JSArmor
|
|
18
|
+
|
|
19
|
+
The credit must appear in:
|
|
20
|
+
|
|
21
|
+
* documentation
|
|
22
|
+
* repository
|
|
23
|
+
* distributed binaries
|
|
24
|
+
* CLI output (if applicable)
|
|
25
|
+
|
|
26
|
+
2. Non-Commercial Restriction
|
|
27
|
+
|
|
28
|
+
This software may NOT be sold, sublicensed, or included in any paid
|
|
29
|
+
software, service, or product without explicit written permission
|
|
30
|
+
from the author.
|
|
31
|
+
|
|
32
|
+
This includes but is not limited to:
|
|
33
|
+
|
|
34
|
+
* selling modified versions
|
|
35
|
+
* bundling with commercial software
|
|
36
|
+
* offering it as a paid obfuscation service
|
|
37
|
+
|
|
38
|
+
3. No Removal of Author Signature
|
|
39
|
+
|
|
40
|
+
You may not remove or alter:
|
|
41
|
+
|
|
42
|
+
* author credits
|
|
43
|
+
* runtime signatures
|
|
44
|
+
* watermark identifiers
|
|
45
|
+
* protection markers embedded in the software
|
|
46
|
+
|
|
47
|
+
4. Redistribution Requirements
|
|
48
|
+
|
|
49
|
+
If you distribute this software or modified versions, you must:
|
|
50
|
+
|
|
51
|
+
* include this license
|
|
52
|
+
* clearly indicate that the project is derived from JSArmor
|
|
53
|
+
* provide attribution to the original author
|
|
54
|
+
|
|
55
|
+
5. No False Representation
|
|
56
|
+
|
|
57
|
+
You may not claim that you are the original creator of this software.
|
|
58
|
+
|
|
59
|
+
6. Disclaimer of Warranty
|
|
60
|
+
|
|
61
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
62
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
63
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
|
|
64
|
+
NONINFRINGEMENT.
|
|
65
|
+
|
|
66
|
+
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES,
|
|
67
|
+
OR OTHER LIABILITY ARISING FROM THE USE OF THIS SOFTWARE.
|
|
68
|
+
|
|
69
|
+
7. Violations
|
|
70
|
+
|
|
71
|
+
Any violation of these terms automatically revokes permission to
|
|
72
|
+
use this software.
|
|
73
|
+
|
|
74
|
+
For commercial licensing inquiries contact:
|
|
75
|
+
|
|
76
|
+
https://eboy.asia/p.n
|
package/README.md
ADDED
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="docs/banner.jpg" width="300">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">JSArmor</h1>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
Advanced JavaScript Obfuscator for protecting source code.
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
<p align="center">
|
|
12
|
+
|
|
13
|
+

|
|
14
|
+

|
|
15
|
+

|
|
16
|
+

|
|
17
|
+
|
|
18
|
+
</p>
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Overview
|
|
23
|
+
|
|
24
|
+
**JSArmor** is a lightweight JavaScript obfuscator designed to protect source code from reverse engineering.
|
|
25
|
+
|
|
26
|
+
It transforms readable JavaScript into a more complex and difficult-to-analyze form while preserving runtime behavior.
|
|
27
|
+
|
|
28
|
+
The goal of JSArmor is to provide **simple CLI usage with strong code protection techniques.**
|
|
29
|
+
> The idea for this project was taken from [Pyarmor](https://github.com/dashingsoft/pyarmor)
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Features
|
|
34
|
+
|
|
35
|
+
* String encryption
|
|
36
|
+
* Variable and function renaming
|
|
37
|
+
* Control flow obfuscation
|
|
38
|
+
* Dead code injection
|
|
39
|
+
* Unicode encoding
|
|
40
|
+
* Anti-debugging protection
|
|
41
|
+
* Self-defending runtime
|
|
42
|
+
|
|
43
|
+
These techniques increase the difficulty of reverse engineering and static analysis.
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Installation
|
|
48
|
+
|
|
49
|
+
Install globally using npm.
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
npm install jsarmor
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Quick Start
|
|
58
|
+
|
|
59
|
+
Obfuscate a JavaScript file:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
jsarmor gen <main file>
|
|
63
|
+
Ex: jsarmor gen index.js
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Output will be generated in:
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
dist/obf.js
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Run the protected file normally with Node.js.
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
node dist/obf.js
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Demo
|
|
81
|
+
|
|
82
|
+
### Before Obfuscation
|
|
83
|
+
|
|
84
|
+
```javascript
|
|
85
|
+
function greet(name) {
|
|
86
|
+
const message = "Hello " + name
|
|
87
|
+
console.log(message)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
greet("world")
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
### After Obfuscation
|
|
96
|
+
|
|
97
|
+
```javascript
|
|
98
|
+
(function(_0x2a41c2,_0x3e8f7a){
|
|
99
|
+
const _0x5f3b=['log','Hello','world']
|
|
100
|
+
(function(_0x11b2c3,_0x58e0f1){
|
|
101
|
+
while(!![]){
|
|
102
|
+
try{
|
|
103
|
+
const _0x12c8d9=parseInt(_0x11b2c3())+parseInt(_0x11b2c3())
|
|
104
|
+
if(_0x12c8d9===_0x58e0f1)break
|
|
105
|
+
else _0x5f3b.push(_0x5f3b.shift())
|
|
106
|
+
}catch(_0x1c7b45){
|
|
107
|
+
_0x5f3b.push(_0x5f3b.shift())
|
|
108
|
+
}}
|
|
109
|
+
})(function(){return _0x5f3b.shift()},0x1234)
|
|
110
|
+
|
|
111
|
+
console[_0x5f3b[0]](_0x5f3b[1]+' '+_0x5f3b[2])
|
|
112
|
+
})()
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Project Structure
|
|
118
|
+
|
|
119
|
+
```
|
|
120
|
+
jsarmor
|
|
121
|
+
├ cli/
|
|
122
|
+
│ └ index.js
|
|
123
|
+
├ core/
|
|
124
|
+
│ ├ antidebug.js
|
|
125
|
+
│ ├ beautifyGuard.js
|
|
126
|
+
│ ├ controlflow.js
|
|
127
|
+
│ ├ deadcode.js
|
|
128
|
+
│ ├ junkcode.js
|
|
129
|
+
│ ├ parser.js
|
|
130
|
+
│ ├ rc4.js
|
|
131
|
+
│ ├ renamer.js
|
|
132
|
+
│ ├ runtime.js
|
|
133
|
+
│ ├ selfdefend.js
|
|
134
|
+
│ ├ stringArray.js
|
|
135
|
+
│ └ unicode.js
|
|
136
|
+
└ utils/
|
|
137
|
+
└ random.js
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## Roadmap
|
|
143
|
+
|
|
144
|
+
### Version 2 (unlock at ⭐ 15 stars)
|
|
145
|
+
|
|
146
|
+
Planned features:
|
|
147
|
+
|
|
148
|
+
* Multiple obfuscation levels (low / medium / high)
|
|
149
|
+
* Stronger string encryption
|
|
150
|
+
* CLI output customization
|
|
151
|
+
* Improved dead code generation
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
### Version 3 (unlock at ⭐ 100 stars)
|
|
156
|
+
|
|
157
|
+
Planned advanced protection:
|
|
158
|
+
|
|
159
|
+
* JavaScript VM-based obfuscation
|
|
160
|
+
* Advanced anti-debugging techniques
|
|
161
|
+
* Anti-tamper protection
|
|
162
|
+
* Runtime integrity checks
|
|
163
|
+
* Code virtualization
|
|
164
|
+
* Web Dashboard
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## Contributing
|
|
169
|
+
|
|
170
|
+
Contributions are welcome.
|
|
171
|
+
|
|
172
|
+
You can help by:
|
|
173
|
+
|
|
174
|
+
* Reporting bugs
|
|
175
|
+
* Suggesting new obfuscation techniques
|
|
176
|
+
* Improving performance
|
|
177
|
+
* Opening pull requests
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
## Support
|
|
182
|
+
|
|
183
|
+
If you encounter issues or have questions:
|
|
184
|
+
|
|
185
|
+
Open an issue on GitHub in [here](https://github.com/Swp-dev/JavascriptArmor/issues).
|
|
186
|
+
|
|
187
|
+
For direct contact:
|
|
188
|
+
|
|
189
|
+
Link Bio
|
|
190
|
+
|
|
191
|
+
```
|
|
192
|
+
https://eboy.asia/p.n
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
GitHub
|
|
196
|
+
|
|
197
|
+
```
|
|
198
|
+
https://github.com/Swp-dev/JavascriptArmor
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Follow me on the tiktok
|
|
202
|
+
|
|
203
|
+
```
|
|
204
|
+
https://tiktok.com/@niemtinthatxaxi
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## License
|
|
210
|
+
|
|
211
|
+
MIT License
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
<p align="center">
|
|
216
|
+
Built for developers who want to protect JavaScript code.
|
|
217
|
+
</p>
|
package/cli/index.js
CHANGED
|
@@ -1,177 +1,177 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import fs from "fs";
|
|
4
|
-
import path from "path";
|
|
5
|
-
import chalk from "chalk";
|
|
6
|
-
import gradient from "gradient-string";
|
|
7
|
-
import cliProgress from "cli-progress";
|
|
8
|
-
import generate from "@babel/generator";
|
|
9
|
-
|
|
10
|
-
import { parseCode } from "../core/parser.js";
|
|
11
|
-
import { renameVariables } from "../core/renamer.js";
|
|
12
|
-
import { encodeStrings } from "../core/stringArray.js";
|
|
13
|
-
import { flattenControlFlow } from "../core/controlflow.js";
|
|
14
|
-
import { unicodeEscape } from "../core/unicode.js";
|
|
15
|
-
import { generateJunk } from "../core/junkcode.js";
|
|
16
|
-
|
|
17
|
-
import { injectDeadCode, generateDeadRuntime } from "../core/deadcode.js";
|
|
18
|
-
|
|
19
|
-
import { injectAntiDebug } from "../core/antidebug.js";
|
|
20
|
-
import { antiBeautify } from "../core/beautifyGuard.js";
|
|
21
|
-
import { selfDefend } from "../core/selfdefend.js";
|
|
22
|
-
|
|
23
|
-
const neon = gradient(["#00ffff","#ff00ff","#00ff9f"]);
|
|
24
|
-
|
|
25
|
-
try{
|
|
26
|
-
|
|
27
|
-
const args = process.argv.slice(2);
|
|
28
|
-
|
|
29
|
-
const command = args[0];
|
|
30
|
-
const file = args[1];
|
|
31
|
-
|
|
32
|
-
let outputName = "obf.js";
|
|
33
|
-
|
|
34
|
-
const outIndex = args.indexOf("-o");
|
|
35
|
-
|
|
36
|
-
if(outIndex !== -1 && args[outIndex+1]){
|
|
37
|
-
outputName = args[outIndex+1];
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
if(!command || command === "help"){
|
|
41
|
-
|
|
42
|
-
console.log(neon(`
|
|
43
|
-
JSArmor - JavaScript Obfuscator
|
|
44
|
-
|
|
45
|
-
Usage:
|
|
46
|
-
|
|
47
|
-
jsarmor gen input.js
|
|
48
|
-
jsarmor gen input.js -o output.js
|
|
49
|
-
|
|
50
|
-
`));
|
|
51
|
-
|
|
52
|
-
process.exit(0);
|
|
53
|
-
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
if(command !== "gen"){
|
|
57
|
-
|
|
58
|
-
console.log(chalk.red("Unknown command"));
|
|
59
|
-
console.log("Use: jsarmor gen input.js");
|
|
60
|
-
|
|
61
|
-
process.exit(1);
|
|
62
|
-
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
if(!file){
|
|
66
|
-
|
|
67
|
-
console.log(chalk.red("Please provide input file"));
|
|
68
|
-
console.log("Usage: jsarmor gen input.js");
|
|
69
|
-
|
|
70
|
-
process.exit(1);
|
|
71
|
-
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
if(!fs.existsSync(file)){
|
|
75
|
-
console.log(chalk.red(`File not found: ${file}`));
|
|
76
|
-
process.exit(1);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
let code = fs.readFileSync(file,"utf8");
|
|
80
|
-
|
|
81
|
-
let shebang = "";
|
|
82
|
-
|
|
83
|
-
if(code.startsWith("#!")){
|
|
84
|
-
const end = code.indexOf("\n");
|
|
85
|
-
shebang = code.slice(0,end);
|
|
86
|
-
code = code.slice(end);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
console.log(
|
|
90
|
-
neon(`┌──────────────────────────────┐
|
|
91
|
-
│ NodeJS Obfuscator v3 │
|
|
92
|
-
└──────────────────────────────┘`)
|
|
93
|
-
);
|
|
94
|
-
|
|
95
|
-
const bar = new cliProgress.SingleBar({
|
|
96
|
-
format:"progress [{bar}] {percentage}% | {value}/{total}",
|
|
97
|
-
barCompleteChar:"█",
|
|
98
|
-
barIncompleteChar:"░"
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
bar.start(6,0);
|
|
102
|
-
|
|
103
|
-
const ast = parseCode(code);
|
|
104
|
-
bar.increment();
|
|
105
|
-
|
|
106
|
-
renameVariables(ast);
|
|
107
|
-
bar.increment();
|
|
108
|
-
|
|
109
|
-
const pool = encodeStrings(ast);
|
|
110
|
-
bar.increment();
|
|
111
|
-
|
|
112
|
-
/* dead code transform */
|
|
113
|
-
injectDeadCode(ast);
|
|
114
|
-
bar.increment();
|
|
115
|
-
|
|
116
|
-
flattenControlFlow(ast);
|
|
117
|
-
bar.increment();
|
|
118
|
-
|
|
119
|
-
unicodeEscape(ast);
|
|
120
|
-
bar.increment();
|
|
121
|
-
|
|
122
|
-
bar.stop();
|
|
123
|
-
|
|
124
|
-
const output = generate.default(ast,{
|
|
125
|
-
jsescOption:{
|
|
126
|
-
minimal:true
|
|
127
|
-
}
|
|
128
|
-
}).code;
|
|
129
|
-
|
|
130
|
-
const runtimeJunk = generateDeadRuntime();
|
|
131
|
-
|
|
132
|
-
const final =
|
|
133
|
-
(shebang ? shebang + "\n" : "") +
|
|
134
|
-
injectAntiDebug() +
|
|
135
|
-
antiBeautify() +
|
|
136
|
-
selfDefend() +
|
|
137
|
-
`var _STRINGS=${JSON.stringify(pool)};\n` +
|
|
138
|
-
runtimeJunk +
|
|
139
|
-
generateJunk() +
|
|
140
|
-
output;
|
|
141
|
-
|
|
142
|
-
const distDir = path.join(process.cwd(),"dist");
|
|
143
|
-
|
|
144
|
-
if(!fs.existsSync(distDir)){
|
|
145
|
-
fs.mkdirSync(distDir,{recursive:true});
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
const outFile = path.join(distDir,"obf.js");
|
|
149
|
-
|
|
150
|
-
fs.writeFileSync(outFile,final);
|
|
151
|
-
|
|
152
|
-
console.log();
|
|
153
|
-
console.log(chalk.green("✔ Parsing AST"));
|
|
154
|
-
console.log(chalk.green("✔ Variables renamed"));
|
|
155
|
-
console.log(chalk.green("✔ Strings encoded"));
|
|
156
|
-
console.log(chalk.green("✔ Dead code injected"));
|
|
157
|
-
console.log(chalk.green("✔ Control flow flattened"));
|
|
158
|
-
console.log(chalk.green("✔ Unicode escape applied"));
|
|
159
|
-
console.log();
|
|
160
|
-
console.log(chalk.bold.green("✔ Obfuscation Complete"));
|
|
161
|
-
console.log(chalk.cyan(`Output: ${outFile}`));
|
|
162
|
-
|
|
163
|
-
const originalSize = code.length;
|
|
164
|
-
const newSize = final.length;
|
|
165
|
-
|
|
166
|
-
console.log(
|
|
167
|
-
chalk.yellow(
|
|
168
|
-
`Size: ${(originalSize/1024).toFixed(2)} KB → ${(newSize/1024).toFixed(2)} KB`
|
|
169
|
-
)
|
|
170
|
-
);
|
|
171
|
-
|
|
172
|
-
}catch(err){
|
|
173
|
-
|
|
174
|
-
console.log(chalk.red("Obfuscation failed"));
|
|
175
|
-
console.error(err);
|
|
176
|
-
|
|
177
|
-
}
|
|
2
|
+
|
|
3
|
+
import fs from "fs";
|
|
4
|
+
import path from "path";
|
|
5
|
+
import chalk from "chalk";
|
|
6
|
+
import gradient from "gradient-string";
|
|
7
|
+
import cliProgress from "cli-progress";
|
|
8
|
+
import generate from "@babel/generator";
|
|
9
|
+
|
|
10
|
+
import { parseCode } from "../core/parser.js";
|
|
11
|
+
import { renameVariables } from "../core/renamer.js";
|
|
12
|
+
import { encodeStrings } from "../core/stringArray.js";
|
|
13
|
+
import { flattenControlFlow } from "../core/controlflow.js";
|
|
14
|
+
import { unicodeEscape } from "../core/unicode.js";
|
|
15
|
+
import { generateJunk } from "../core/junkcode.js";
|
|
16
|
+
|
|
17
|
+
import { injectDeadCode, generateDeadRuntime } from "../core/deadcode.js";
|
|
18
|
+
|
|
19
|
+
import { injectAntiDebug } from "../core/antidebug.js";
|
|
20
|
+
import { antiBeautify } from "../core/beautifyGuard.js";
|
|
21
|
+
import { selfDefend } from "../core/selfdefend.js";
|
|
22
|
+
|
|
23
|
+
const neon = gradient(["#00ffff","#ff00ff","#00ff9f"]);
|
|
24
|
+
|
|
25
|
+
try{
|
|
26
|
+
|
|
27
|
+
const args = process.argv.slice(2);
|
|
28
|
+
|
|
29
|
+
const command = args[0];
|
|
30
|
+
const file = args[1];
|
|
31
|
+
|
|
32
|
+
let outputName = "obf.js";
|
|
33
|
+
|
|
34
|
+
const outIndex = args.indexOf("-o");
|
|
35
|
+
|
|
36
|
+
if(outIndex !== -1 && args[outIndex+1]){
|
|
37
|
+
outputName = args[outIndex+1];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if(!command || command === "help"){
|
|
41
|
+
|
|
42
|
+
console.log(neon(`
|
|
43
|
+
JSArmor - JavaScript Obfuscator
|
|
44
|
+
|
|
45
|
+
Usage:
|
|
46
|
+
|
|
47
|
+
jsarmor gen input.js
|
|
48
|
+
jsarmor gen input.js -o output.js
|
|
49
|
+
|
|
50
|
+
`));
|
|
51
|
+
|
|
52
|
+
process.exit(0);
|
|
53
|
+
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if(command !== "gen"){
|
|
57
|
+
|
|
58
|
+
console.log(chalk.red("Unknown command"));
|
|
59
|
+
console.log("Use: jsarmor gen input.js");
|
|
60
|
+
|
|
61
|
+
process.exit(1);
|
|
62
|
+
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if(!file){
|
|
66
|
+
|
|
67
|
+
console.log(chalk.red("Please provide input file"));
|
|
68
|
+
console.log("Usage: jsarmor gen input.js");
|
|
69
|
+
|
|
70
|
+
process.exit(1);
|
|
71
|
+
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if(!fs.existsSync(file)){
|
|
75
|
+
console.log(chalk.red(`File not found: ${file}`));
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
let code = fs.readFileSync(file,"utf8");
|
|
80
|
+
|
|
81
|
+
let shebang = "";
|
|
82
|
+
|
|
83
|
+
if(code.startsWith("#!")){
|
|
84
|
+
const end = code.indexOf("\n");
|
|
85
|
+
shebang = code.slice(0,end);
|
|
86
|
+
code = code.slice(end);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
console.log(
|
|
90
|
+
neon(`┌──────────────────────────────┐
|
|
91
|
+
│ NodeJS Obfuscator v3 │
|
|
92
|
+
└──────────────────────────────┘`)
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
const bar = new cliProgress.SingleBar({
|
|
96
|
+
format:"progress [{bar}] {percentage}% | {value}/{total}",
|
|
97
|
+
barCompleteChar:"█",
|
|
98
|
+
barIncompleteChar:"░"
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
bar.start(6,0);
|
|
102
|
+
|
|
103
|
+
const ast = parseCode(code);
|
|
104
|
+
bar.increment();
|
|
105
|
+
|
|
106
|
+
renameVariables(ast);
|
|
107
|
+
bar.increment();
|
|
108
|
+
|
|
109
|
+
const pool = encodeStrings(ast);
|
|
110
|
+
bar.increment();
|
|
111
|
+
|
|
112
|
+
/* dead code transform */
|
|
113
|
+
injectDeadCode(ast);
|
|
114
|
+
bar.increment();
|
|
115
|
+
|
|
116
|
+
flattenControlFlow(ast);
|
|
117
|
+
bar.increment();
|
|
118
|
+
|
|
119
|
+
unicodeEscape(ast);
|
|
120
|
+
bar.increment();
|
|
121
|
+
|
|
122
|
+
bar.stop();
|
|
123
|
+
|
|
124
|
+
const output = generate.default(ast,{
|
|
125
|
+
jsescOption:{
|
|
126
|
+
minimal:true
|
|
127
|
+
}
|
|
128
|
+
}).code;
|
|
129
|
+
|
|
130
|
+
const runtimeJunk = generateDeadRuntime();
|
|
131
|
+
|
|
132
|
+
const final =
|
|
133
|
+
(shebang ? shebang + "\n" : "") +
|
|
134
|
+
injectAntiDebug() +
|
|
135
|
+
antiBeautify() +
|
|
136
|
+
selfDefend() +
|
|
137
|
+
`var _STRINGS=${JSON.stringify(pool)};\n` +
|
|
138
|
+
runtimeJunk +
|
|
139
|
+
generateJunk() +
|
|
140
|
+
output;
|
|
141
|
+
|
|
142
|
+
const distDir = path.join(process.cwd(),"dist");
|
|
143
|
+
|
|
144
|
+
if(!fs.existsSync(distDir)){
|
|
145
|
+
fs.mkdirSync(distDir,{recursive:true});
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const outFile = path.join(distDir,"obf.js");
|
|
149
|
+
|
|
150
|
+
fs.writeFileSync(outFile,final);
|
|
151
|
+
|
|
152
|
+
console.log();
|
|
153
|
+
console.log(chalk.green("✔ Parsing AST"));
|
|
154
|
+
console.log(chalk.green("✔ Variables renamed"));
|
|
155
|
+
console.log(chalk.green("✔ Strings encoded"));
|
|
156
|
+
console.log(chalk.green("✔ Dead code injected"));
|
|
157
|
+
console.log(chalk.green("✔ Control flow flattened"));
|
|
158
|
+
console.log(chalk.green("✔ Unicode escape applied"));
|
|
159
|
+
console.log();
|
|
160
|
+
console.log(chalk.bold.green("✔ Obfuscation Complete"));
|
|
161
|
+
console.log(chalk.cyan(`Output: ${outFile}`));
|
|
162
|
+
|
|
163
|
+
const originalSize = code.length;
|
|
164
|
+
const newSize = final.length;
|
|
165
|
+
|
|
166
|
+
console.log(
|
|
167
|
+
chalk.yellow(
|
|
168
|
+
`Size: ${(originalSize/1024).toFixed(2)} KB → ${(newSize/1024).toFixed(2)} KB`
|
|
169
|
+
)
|
|
170
|
+
);
|
|
171
|
+
|
|
172
|
+
}catch(err){
|
|
173
|
+
|
|
174
|
+
console.log(chalk.red("Obfuscation failed"));
|
|
175
|
+
console.error(err);
|
|
176
|
+
|
|
177
|
+
}
|
package/core/antidebug.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
export function injectAntiDebug(){
|
|
2
|
-
|
|
3
|
-
return `
|
|
4
|
-
|
|
5
|
-
(function(){
|
|
6
|
-
setInterval(function(){
|
|
7
|
-
try{
|
|
8
|
-
(function(){debugger})()
|
|
9
|
-
}catch(e){}
|
|
10
|
-
},2000)
|
|
11
|
-
})();
|
|
12
|
-
|
|
13
|
-
`;
|
|
14
|
-
|
|
15
|
-
}
|
|
1
|
+
export function injectAntiDebug(){
|
|
2
|
+
|
|
3
|
+
return `
|
|
4
|
+
|
|
5
|
+
(function(){
|
|
6
|
+
setInterval(function(){
|
|
7
|
+
try{
|
|
8
|
+
(function(){debugger})()
|
|
9
|
+
}catch(e){}
|
|
10
|
+
},2000)
|
|
11
|
+
})();
|
|
12
|
+
|
|
13
|
+
`;
|
|
14
|
+
|
|
15
|
+
}
|
package/docs/banner.jpg
CHANGED
|
Binary file
|
package/docs/shitpost
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jsarmor",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
4
4
|
"description": "Advanced JavaScript Obfuscator",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "cli/index.js",
|
|
@@ -10,27 +10,36 @@
|
|
|
10
10
|
"scripts": {
|
|
11
11
|
"start": "node cli/index.js"
|
|
12
12
|
},
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
"
|
|
20
|
-
"cli-progress": "^3.12.0"
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "https://github.com/Swp-dev/JavascriptArmor.git"
|
|
16
|
+
},
|
|
17
|
+
"homepage": "https://github.com/Swp-dev/JavascriptArmor",
|
|
18
|
+
"bugs": {
|
|
19
|
+
"url": "https://github.com/Swp-dev/JavascriptArmor/issues"
|
|
21
20
|
},
|
|
22
|
-
"keywords": [
|
|
23
|
-
"obfuscator",
|
|
24
|
-
"javascript",
|
|
25
|
-
"security",
|
|
26
|
-
"jsarmor"
|
|
27
|
-
],
|
|
28
21
|
"files": [
|
|
29
22
|
"cli",
|
|
30
23
|
"core",
|
|
31
24
|
"utils",
|
|
32
25
|
"docs"
|
|
33
26
|
],
|
|
27
|
+
"keywords": [
|
|
28
|
+
"javascript",
|
|
29
|
+
"obfuscator",
|
|
30
|
+
"security",
|
|
31
|
+
"protection",
|
|
32
|
+
"jsarmor"
|
|
33
|
+
],
|
|
34
34
|
"author": "_kingktn",
|
|
35
|
-
"license": "
|
|
35
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"@babel/parser": "^7.26.0",
|
|
38
|
+
"@babel/traverse": "^7.26.0",
|
|
39
|
+
"@babel/types": "^7.26.0",
|
|
40
|
+
"@babel/generator": "^7.26.0",
|
|
41
|
+
"chalk": "^5.3.0",
|
|
42
|
+
"gradient-string": "^2.0.2",
|
|
43
|
+
"cli-progress": "^3.12.0"
|
|
44
|
+
}
|
|
36
45
|
}
|
package/readme.md
DELETED
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
<p align="center">
|
|
2
|
-
<img src="docs/banner.jpg" width="300">
|
|
3
|
-
</p>
|
|
4
|
-
|
|
5
|
-
<h1 align="center">JSArmor</h1>
|
|
6
|
-
|
|
7
|
-
<p align="center">
|
|
8
|
-
A lightweight JavaScript obfuscator for protecting source code from reverse engineering.
|
|
9
|
-
</p>
|
|
10
|
-
|
|
11
|
-
<p align="center">
|
|
12
|
-
|
|
13
|
-

|
|
14
|
-

|
|
15
|
-

|
|
16
|
-

|
|
17
|
-
|
|
18
|
-
</p>
|
|
19
|
-
|
|
20
|
-
---
|
|
21
|
-
|
|
22
|
-
## Overview
|
|
23
|
-
|
|
24
|
-
JSArmor transforms readable JavaScript into a more complex form while preserving runtime behavior.
|
|
25
|
-
|
|
26
|
-
It is designed for developers who want a **simple CLI tool to protect their code** from reverse engineering.
|
|
27
|
-
|
|
28
|
-
---
|
|
29
|
-
|
|
30
|
-
# Installation
|
|
31
|
-
|
|
32
|
-
Install globally using npm
|
|
33
|
-
|
|
34
|
-
```bash
|
|
35
|
-
npm install -g jsarmor
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
Or use it inside a project:
|
|
39
|
-
|
|
40
|
-
```bash
|
|
41
|
-
npm install jsarmor
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
---
|
|
45
|
-
|
|
46
|
-
# Quick Start
|
|
47
|
-
|
|
48
|
-
Obfuscate a JavaScript file:
|
|
49
|
-
|
|
50
|
-
```bash
|
|
51
|
-
jsarmor gen input.js
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
Output will be generated in:
|
|
55
|
-
|
|
56
|
-
```
|
|
57
|
-
dist/obf.js
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
Run it normally:
|
|
61
|
-
|
|
62
|
-
```bash
|
|
63
|
-
node dist/obf.js
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
---
|
|
67
|
-
|
|
68
|
-
# Example
|
|
69
|
-
|
|
70
|
-
## Input
|
|
71
|
-
|
|
72
|
-
```javascript
|
|
73
|
-
function greet(name) {
|
|
74
|
-
const message = "Hello " + name
|
|
75
|
-
console.log(message)
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
greet("world")
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
---
|
|
82
|
-
|
|
83
|
-
## Output (obfuscated)
|
|
84
|
-
|
|
85
|
-
```javascript
|
|
86
|
-
(function(_0x1a2b){
|
|
87
|
-
const _0x3f21=['log','Hello','world'];
|
|
88
|
-
console[_0x3f21[0]](_0x3f21[1]+' '+_0x3f21[2]);
|
|
89
|
-
})();
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
The output code becomes significantly harder to understand and analyze.
|
|
93
|
-
|
|
94
|
-
---
|
|
95
|
-
|
|
96
|
-
# Features
|
|
97
|
-
|
|
98
|
-
* String encryption
|
|
99
|
-
* Variable renaming
|
|
100
|
-
* Control flow obfuscation
|
|
101
|
-
* Dead code injection
|
|
102
|
-
* Unicode encoding
|
|
103
|
-
* Anti-debug protection
|
|
104
|
-
* Self defending runtime
|
|
105
|
-
|
|
106
|
-
---
|
|
107
|
-
|
|
108
|
-
# CLI
|
|
109
|
-
|
|
110
|
-
Basic command:
|
|
111
|
-
|
|
112
|
-
```bash
|
|
113
|
-
jsarmor gen <input.js>
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
Example:
|
|
117
|
-
|
|
118
|
-
```bash
|
|
119
|
-
jsarmor gen app.js
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
Result:
|
|
123
|
-
|
|
124
|
-
```
|
|
125
|
-
dist/obf.js
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
---
|
|
129
|
-
|
|
130
|
-
# Use Cases
|
|
131
|
-
|
|
132
|
-
JSArmor can be used for:
|
|
133
|
-
|
|
134
|
-
* protecting commercial JavaScript code
|
|
135
|
-
* distributing protected CLI tools
|
|
136
|
-
* hiding business logic
|
|
137
|
-
* making reverse engineering harder
|
|
138
|
-
|
|
139
|
-
---
|
|
140
|
-
|
|
141
|
-
# Support
|
|
142
|
-
|
|
143
|
-
If you encounter problems or have questions:
|
|
144
|
-
|
|
145
|
-
GitHub Issues
|
|
146
|
-
|
|
147
|
-
```
|
|
148
|
-
https://github.com/Swp-dev/JavascriptArmor
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
Contact
|
|
152
|
-
|
|
153
|
-
```
|
|
154
|
-
https://eboy.asia/p.n
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
---
|
|
158
|
-
|
|
159
|
-
# License
|
|
160
|
-
|
|
161
|
-
MIT License
|
|
162
|
-
|
|
163
|
-
This project is licensed under the MIT License – you are free to use, modify and distribute it.
|