seabox 0.1.0-beta.1
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/.mocharc.json +6 -0
- package/LICENSE.MD +21 -0
- package/README.md +209 -0
- package/bin/seabox-rebuild.js +395 -0
- package/bin/seabox.js +81 -0
- package/lib/bindings.js +31 -0
- package/lib/blob.js +109 -0
- package/lib/bootstrap.js +655 -0
- package/lib/build.js +283 -0
- package/lib/config.js +117 -0
- package/lib/crypto-assets.js +160 -0
- package/lib/fetch-node.js +177 -0
- package/lib/index.js +27 -0
- package/lib/inject.js +81 -0
- package/lib/manifest.js +98 -0
- package/lib/obfuscate.js +73 -0
- package/lib/scanner.js +153 -0
- package/lib/unsign.js +184 -0
- package/package.json +47 -0
package/lib/unsign.js
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* unsign.js
|
|
3
|
+
* Remove code signatures from executables before injection.
|
|
4
|
+
* This prevents signature corruption during postject injection.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const { execFile } = require('child_process');
|
|
8
|
+
const { promisify } = require('util');
|
|
9
|
+
|
|
10
|
+
const execFileAsync = promisify(execFile);
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Check if a signing tool is available on the system.
|
|
14
|
+
* @param {string} platform - Target platform (win32, linux, darwin)
|
|
15
|
+
* @returns {Promise<{available: boolean, tool: string|null}>}
|
|
16
|
+
*/
|
|
17
|
+
async function checkSignToolAvailability(platform) {
|
|
18
|
+
const tools = {
|
|
19
|
+
win32: 'signtool.exe',
|
|
20
|
+
darwin: 'codesign',
|
|
21
|
+
linux: 'osslsigncode'
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const tool = tools[platform];
|
|
25
|
+
if (!tool) {
|
|
26
|
+
return { available: false, tool: null };
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
try {
|
|
30
|
+
// Try to execute the tool with a version/help flag to check availability
|
|
31
|
+
if (platform === 'win32') {
|
|
32
|
+
await execFileAsync('where', ['signtool.exe']);
|
|
33
|
+
} else if (platform === 'darwin') {
|
|
34
|
+
await execFileAsync('which', ['codesign']);
|
|
35
|
+
} else if (platform === 'linux') {
|
|
36
|
+
await execFileAsync('which', ['osslsigncode']);
|
|
37
|
+
}
|
|
38
|
+
return { available: true, tool };
|
|
39
|
+
} catch (error) {
|
|
40
|
+
return { available: false, tool };
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Remove signature from a Windows executable using signtool.
|
|
46
|
+
* @param {string} exePath - Path to the executable
|
|
47
|
+
* @returns {Promise<{success: boolean, message: string}>}
|
|
48
|
+
*/
|
|
49
|
+
async function removeWindowsSignature(exePath) {
|
|
50
|
+
try {
|
|
51
|
+
const { stdout, stderr } = await execFileAsync('signtool.exe', ['remove', '/s', exePath]);
|
|
52
|
+
|
|
53
|
+
const output = (stdout + stderr).toLowerCase();
|
|
54
|
+
|
|
55
|
+
// Check if successfully removed
|
|
56
|
+
if (output.includes('successfully')) {
|
|
57
|
+
return { success: true, message: 'Signature removed successfully' };
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Check if there was no signature
|
|
61
|
+
if (output.includes('no signature') || output.includes('not signed')) {
|
|
62
|
+
return { success: true, message: 'Binary was not signed (no signature to remove)' };
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return { success: true, message: stdout || 'Signature removal completed' };
|
|
66
|
+
} catch (error) {
|
|
67
|
+
const errorMsg = error.message || error.stderr || '';
|
|
68
|
+
|
|
69
|
+
// Not an error if there was no signature to begin with
|
|
70
|
+
if (errorMsg.includes('No signature') || errorMsg.includes('not signed')) {
|
|
71
|
+
return { success: true, message: 'Binary was not signed (no signature to remove)' };
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return { success: false, message: `Failed to remove signature: ${errorMsg}` };
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Remove signature from a macOS executable using codesign.
|
|
80
|
+
* @param {string} exePath - Path to the executable
|
|
81
|
+
* @returns {Promise<{success: boolean, message: string}>}
|
|
82
|
+
*/
|
|
83
|
+
async function removeMacSignature(exePath) {
|
|
84
|
+
try {
|
|
85
|
+
// On macOS, use --remove-signature flag
|
|
86
|
+
const { stdout, stderr } = await execFileAsync('codesign', ['--remove-signature', exePath]);
|
|
87
|
+
|
|
88
|
+
return { success: true, message: 'Signature removed successfully' };
|
|
89
|
+
} catch (error) {
|
|
90
|
+
const errorMsg = error.message || error.stderr || '';
|
|
91
|
+
|
|
92
|
+
// Not an error if there was no signature
|
|
93
|
+
if (errorMsg.includes('not signed') || errorMsg.includes('no signature')) {
|
|
94
|
+
return { success: true, message: 'Binary was not signed (no signature to remove)' };
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return { success: false, message: `Failed to remove signature: ${errorMsg}` };
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Remove signature from a Linux executable.
|
|
103
|
+
* Note: Linux binaries are rarely signed, but osslsigncode can handle Authenticode signatures.
|
|
104
|
+
* @param {string} exePath - Path to the executable
|
|
105
|
+
* @returns {Promise<{success: boolean, message: string}>}
|
|
106
|
+
*/
|
|
107
|
+
async function removeLinuxSignature(exePath) {
|
|
108
|
+
try {
|
|
109
|
+
// osslsigncode can remove Authenticode signatures (used for cross-platform PE files)
|
|
110
|
+
const { stdout, stderr } = await execFileAsync('osslsigncode', ['remove-signature', exePath]);
|
|
111
|
+
|
|
112
|
+
return { success: true, message: 'Signature removed successfully' };
|
|
113
|
+
} catch (error) {
|
|
114
|
+
const errorMsg = error.message || error.stderr || '';
|
|
115
|
+
|
|
116
|
+
// Not an error if there was no signature
|
|
117
|
+
if (errorMsg.includes('not signed') || errorMsg.includes('no signature')) {
|
|
118
|
+
return { success: true, message: 'Binary was not signed (no signature to remove)' };
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return { success: false, message: `Failed to remove signature: ${errorMsg}` };
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Remove code signature from an executable before injection.
|
|
127
|
+
* This is critical to prevent signature corruption during postject injection.
|
|
128
|
+
* @param {string} exePath - Path to the executable
|
|
129
|
+
* @param {string} platform - Target platform (win32, linux, darwin)
|
|
130
|
+
* @returns {Promise<void>}
|
|
131
|
+
*/
|
|
132
|
+
async function removeSignature(exePath, platform) {
|
|
133
|
+
//console.log('Checking for code signature removal tools...');
|
|
134
|
+
|
|
135
|
+
const { available, tool } = await checkSignToolAvailability(platform);
|
|
136
|
+
|
|
137
|
+
if (!available) {
|
|
138
|
+
console.warn(`⚠️ Warning: Signature removal tool not found for ${platform}`);
|
|
139
|
+
console.warn(` Tool needed: ${tool || 'unknown'}`);
|
|
140
|
+
console.warn(` The binary may have an existing signature that will be corrupted during injection.`);
|
|
141
|
+
|
|
142
|
+
if (platform === 'win32') {
|
|
143
|
+
console.warn(` Install Windows SDK to get signtool.exe`);
|
|
144
|
+
console.warn(` Download from: https://developer.microsoft.com/en-us/windows/downloads/windows-sdk/`);
|
|
145
|
+
} else if (platform === 'darwin') {
|
|
146
|
+
console.warn(` Install Xcode Command Line Tools to get codesign`);
|
|
147
|
+
console.warn(` Run: xcode-select --install`);
|
|
148
|
+
} else if (platform === 'linux') {
|
|
149
|
+
console.warn(` Install osslsigncode: apt-get install osslsigncode (Debian/Ubuntu)`);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
console.warn('');
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
console.log(`Found ${tool}, attempting to remove signature...`);
|
|
157
|
+
|
|
158
|
+
let result;
|
|
159
|
+
if (platform === 'win32') {
|
|
160
|
+
result = await removeWindowsSignature(exePath);
|
|
161
|
+
} else if (platform === 'darwin') {
|
|
162
|
+
result = await removeMacSignature(exePath);
|
|
163
|
+
} else if (platform === 'linux') {
|
|
164
|
+
result = await removeLinuxSignature(exePath);
|
|
165
|
+
} else {
|
|
166
|
+
console.warn(`⚠️ Warning: Unsupported platform for signature removal: ${platform}`);
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (result.success) {
|
|
171
|
+
console.log(`✓ ${result.message}`);
|
|
172
|
+
} else {
|
|
173
|
+
console.warn(`⚠️ Warning: ${result.message}`);
|
|
174
|
+
console.warn(` Continuing anyway, but the executable may have signature issues.`);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
module.exports = {
|
|
179
|
+
removeSignature,
|
|
180
|
+
checkSignToolAvailability,
|
|
181
|
+
removeWindowsSignature,
|
|
182
|
+
removeMacSignature,
|
|
183
|
+
removeLinuxSignature
|
|
184
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "seabox",
|
|
3
|
+
"version": "0.1.0-beta.1",
|
|
4
|
+
"description": "Node.js Single Executable Application (SEA) builder tool with native and library extraction",
|
|
5
|
+
"main": "lib/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"bin": {
|
|
8
|
+
"seabox": "bin/seabox.js",
|
|
9
|
+
"seabox-rebuild": "bin/seabox-rebuild.js"
|
|
10
|
+
},
|
|
11
|
+
"scripts": {
|
|
12
|
+
"clean": "rimraf dist",
|
|
13
|
+
"prepublishOnly": "",
|
|
14
|
+
"test": "mocha"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"sea",
|
|
18
|
+
"build",
|
|
19
|
+
"builder",
|
|
20
|
+
"single-executable",
|
|
21
|
+
"SEA",
|
|
22
|
+
"native",
|
|
23
|
+
"module",
|
|
24
|
+
"dll",
|
|
25
|
+
"packaging",
|
|
26
|
+
"node",
|
|
27
|
+
"postject"
|
|
28
|
+
],
|
|
29
|
+
"author": "Meirion Hughes",
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"adm-zip": "^0.5.16",
|
|
33
|
+
"glob": "^10.0.0",
|
|
34
|
+
"postject": "^1.0.0-alpha.6",
|
|
35
|
+
"tar": "^6.2.1"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"chai": "^6.2.1",
|
|
39
|
+
"javascript-obfuscator": "^4.1.1",
|
|
40
|
+
"mocha": "^11.7.5",
|
|
41
|
+
"node-api-headers": "^1.2.0",
|
|
42
|
+
"rimraf": "^6.0.1"
|
|
43
|
+
},
|
|
44
|
+
"engines": {
|
|
45
|
+
"node": ">=18.0.0"
|
|
46
|
+
}
|
|
47
|
+
}
|