Skip to content

Commit 4f04461

Browse files
gHashTagona-agent
andcommitted
feat(extension): Add Firefox port of NeoDetect extension
- Create Firefox-compatible manifest.json (Manifest V2) - Adapt background script (service worker → background script) - Replace chrome.* API calls with browser.* for Firefox - Copy shared assets (icons, WASM, popup) - Firefox user agent strings in fallback profiles Firefox extension uses same WASM module and fingerprint protection as Chrome version. Requires Firefox 109+. Co-authored-by: Ona <no-reply@ona.com>
1 parent 2e0def1 commit 4f04461

10 files changed

Lines changed: 3054 additions & 0 deletions

File tree

Lines changed: 387 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,387 @@
1+
// NeoDetect Background Script (Firefox)
2+
// WASM-powered antidetect browser extension
3+
// φ² + 1/φ² = 3 = TRINITY
4+
5+
const PHI = 1.6180339887;
6+
const TRINITY = 3.0;
7+
8+
// NeoDetect state
9+
let neodetectState = {
10+
enabled: true,
11+
similarity: 0.85,
12+
profile: null,
13+
lastEvolution: null,
14+
aiMode: false,
15+
wasmReady: false,
16+
osType: 0,
17+
hwType: 1,
18+
gpuType: 1,
19+
// Core protections
20+
canvasProtect: true,
21+
webglProtect: true,
22+
audioProtect: true,
23+
navigatorProtect: true,
24+
// Advanced protections
25+
webrtcProtect: true,
26+
batteryProtect: true,
27+
bluetoothProtect: true,
28+
permissionsProtect: true,
29+
storageProtect: true,
30+
autoEvolve: true
31+
};
32+
33+
// WASM module
34+
let wasmModule = null;
35+
let wasmExports = null;
36+
37+
// Languages
38+
const LANGUAGES = [
39+
'en-US', 'en-GB', 'de-DE', 'fr-FR', 'es-ES',
40+
'it-IT', 'pt-BR', 'ru-RU', 'zh-CN', 'ja-JP'
41+
];
42+
43+
// Version info
44+
const CURRENT_VERSION = '2.0.0';
45+
const UPDATE_CHECK_URL = 'https://raw.githubusercontent.com/gHashTag/trinity/main/extension/version.json';
46+
47+
// Initialize on install
48+
browser.runtime.onInstalled.addListener(async (details) => {
49+
console.log('🔥 NeoDetect Anti-Detect installed (Firefox)');
50+
console.log(`φ² + 1/φ² = ${PHI * PHI + 1 / (PHI * PHI)} = TRINITY`);
51+
console.log(`Version: ${CURRENT_VERSION}`);
52+
53+
if (details.reason === 'update') {
54+
console.log(`🔥 Updated from ${details.previousVersion} to ${CURRENT_VERSION}`);
55+
}
56+
57+
// Load saved state
58+
const result = await browser.storage.local.get(['neodetectState']);
59+
if (result.neodetectState) {
60+
neodetectState = { ...neodetectState, ...result.neodetectState };
61+
}
62+
63+
// Initialize WASM module
64+
await initWasm();
65+
66+
// Generate initial profile if needed
67+
if (!neodetectState.profile) {
68+
await createProfile();
69+
}
70+
71+
// Check for updates
72+
await checkForUpdates();
73+
});
74+
75+
// Initialize on startup
76+
browser.runtime.onStartup.addListener(async () => {
77+
console.log('🔥 NeoDetect starting (Firefox)...');
78+
79+
const result = await browser.storage.local.get(['neodetectState']);
80+
if (result.neodetectState) {
81+
neodetectState = { ...neodetectState, ...result.neodetectState };
82+
}
83+
84+
await initWasm();
85+
86+
if (!neodetectState.profile) {
87+
await createProfile();
88+
}
89+
});
90+
91+
// Initialize WASM module
92+
async function initWasm() {
93+
try {
94+
const wasmUrl = browser.runtime.getURL('wasm/neodetect.wasm');
95+
const response = await fetch(wasmUrl);
96+
97+
if (!response.ok) {
98+
console.log('🔥 NeoDetect WASM not found, using fallback');
99+
neodetectState.wasmReady = false;
100+
return;
101+
}
102+
103+
const wasmBuffer = await response.arrayBuffer();
104+
const wasmResult = await WebAssembly.instantiate(wasmBuffer, {
105+
env: {}
106+
});
107+
108+
wasmModule = wasmResult.module;
109+
wasmExports = wasmResult.instance.exports;
110+
111+
// Initialize module
112+
const seed = Date.now();
113+
const result = wasmExports.wasm_neodetect_init(BigInt(seed));
114+
115+
if (result === 0) {
116+
neodetectState.wasmReady = true;
117+
console.log('🔥 NeoDetect WASM initialized');
118+
}
119+
} catch (e) {
120+
console.log('🔥 WASM init failed:', e.message);
121+
neodetectState.wasmReady = false;
122+
}
123+
}
124+
125+
// Read string from WASM memory
126+
function readWasmString(ptr, maxLen = 1024) {
127+
if (!wasmExports || !wasmExports.memory) return '';
128+
const memory = new Uint8Array(wasmExports.memory.buffer);
129+
let str = '';
130+
for (let i = 0; i < maxLen; i++) {
131+
const char = memory[ptr + i];
132+
if (char === 0) break;
133+
str += String.fromCharCode(char);
134+
}
135+
return str;
136+
}
137+
138+
// Create browser profile
139+
async function createProfile(config = {}) {
140+
const seed = BigInt(config.seed || Date.now());
141+
const osType = config.osType ?? neodetectState.osType;
142+
const hwType = config.hwType ?? neodetectState.hwType;
143+
const gpuType = config.gpuType ?? neodetectState.gpuType;
144+
145+
if (neodetectState.wasmReady && wasmExports) {
146+
// Use WASM
147+
wasmExports.wasm_create_profile(seed, osType, hwType, gpuType);
148+
149+
// Get profile data
150+
wasmExports.wasm_get_platform();
151+
const platform = readWasmString(wasmExports.wasm_get_string_buffer());
152+
153+
wasmExports.wasm_get_user_agent();
154+
const userAgent = readWasmString(wasmExports.wasm_get_string_buffer());
155+
156+
wasmExports.wasm_get_gpu_vendor();
157+
const gpuVendor = readWasmString(wasmExports.wasm_get_string_buffer());
158+
159+
wasmExports.wasm_get_gpu_renderer();
160+
const gpuRenderer = readWasmString(wasmExports.wasm_get_string_buffer());
161+
162+
const langIndex = wasmExports.wasm_get_language_index();
163+
164+
neodetectState.profile = {
165+
platform,
166+
userAgent,
167+
screenWidth: wasmExports.wasm_get_screen_width(),
168+
screenHeight: wasmExports.wasm_get_screen_height(),
169+
pixelRatio: wasmExports.wasm_get_pixel_ratio(),
170+
colorDepth: wasmExports.wasm_get_color_depth(),
171+
hardwareConcurrency: wasmExports.wasm_get_hardware_concurrency(),
172+
deviceMemory: wasmExports.wasm_get_device_memory(),
173+
timezoneOffset: wasmExports.wasm_get_timezone_offset(),
174+
language: LANGUAGES[langIndex] || 'en-US',
175+
languages: [LANGUAGES[langIndex] || 'en-US'],
176+
gpuVendor,
177+
gpuRenderer,
178+
canvasHash: wasmExports.wasm_get_canvas_hash().toString(),
179+
webglHash: wasmExports.wasm_get_webgl_hash().toString(),
180+
audioHash: wasmExports.wasm_get_audio_hash().toString()
181+
};
182+
183+
neodetectState.similarity = wasmExports.wasm_get_similarity();
184+
} else {
185+
// Fallback profile
186+
neodetectState.profile = generateFallbackProfile(Number(seed), osType, hwType, gpuType);
187+
neodetectState.similarity = 0.7;
188+
}
189+
190+
neodetectState.osType = osType;
191+
neodetectState.hwType = hwType;
192+
neodetectState.gpuType = gpuType;
193+
194+
await saveState();
195+
await notifyAllTabs();
196+
197+
return neodetectState.profile;
198+
}
199+
200+
// Generate fallback profile (when WASM not available)
201+
function generateFallbackProfile(seed, osType, hwType, gpuType) {
202+
const platforms = ['Win32', 'Win32', 'MacIntel', 'Linux x86_64'];
203+
const userAgents = [
204+
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:125.0) Gecko/20100101 Firefox/125.0',
205+
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:125.0) Gecko/20100101 Firefox/125.0',
206+
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:125.0) Gecko/20100101 Firefox/125.0',
207+
'Mozilla/5.0 (X11; Linux x86_64; rv:125.0) Gecko/20100101 Firefox/125.0'
208+
];
209+
const gpuVendors = ['NVIDIA Corporation', 'NVIDIA Corporation', 'NVIDIA Corporation', 'AMD', 'AMD', 'Intel Inc.', 'Apple Inc.', 'Apple Inc.', 'Apple Inc.'];
210+
const gpuRenderers = ['NVIDIA GeForce RTX 3060/PCIe/SSE2', 'NVIDIA GeForce RTX 4070/PCIe/SSE2', 'NVIDIA GeForce RTX 4090/PCIe/SSE2', 'AMD Radeon RX 6700 XT', 'AMD Radeon RX 7900 XTX', 'Intel(R) UHD Graphics 770', 'Apple M1', 'Apple M2', 'Apple M3'];
211+
const screens = [[1920, 1080], [2560, 1440], [3840, 2160], [1366, 768], [2560, 1600]];
212+
const hwConfigs = [[6, 8], [8, 16], [16, 32], [6, 8], [8, 16], [16, 32], [8, 8], [8, 16], [8, 24]];
213+
214+
const screenIdx = seed % screens.length;
215+
const langIdx = seed % LANGUAGES.length;
216+
217+
return {
218+
platform: platforms[osType % platforms.length],
219+
userAgent: userAgents[osType % userAgents.length],
220+
screenWidth: screens[screenIdx][0],
221+
screenHeight: screens[screenIdx][1],
222+
pixelRatio: osType >= 2 ? 2.0 : 1.0,
223+
colorDepth: 24,
224+
hardwareConcurrency: hwConfigs[hwType % hwConfigs.length][0],
225+
deviceMemory: hwConfigs[hwType % hwConfigs.length][1],
226+
timezoneOffset: [-480, -420, -360, -300, -240, 0, 60, 120, 180, 480][seed % 10],
227+
language: LANGUAGES[langIdx],
228+
languages: [LANGUAGES[langIdx]],
229+
gpuVendor: gpuVendors[gpuType % gpuVendors.length],
230+
gpuRenderer: gpuRenderers[gpuType % gpuRenderers.length],
231+
canvasHash: (seed * 31337).toString(),
232+
webglHash: (seed * 65537).toString(),
233+
audioHash: (seed * 131071).toString()
234+
};
235+
}
236+
237+
// Evolve fingerprint
238+
async function evolveFingerprint(targetSimilarity = 0.85, useAI = false) {
239+
if (neodetectState.wasmReady && wasmExports) {
240+
let similarity;
241+
242+
if (useAI) {
243+
similarity = wasmExports.wasm_ai_evolve(targetSimilarity);
244+
} else {
245+
similarity = wasmExports.wasm_evolve_fingerprint(targetSimilarity, 100);
246+
}
247+
248+
neodetectState.similarity = similarity;
249+
neodetectState.lastEvolution = Date.now();
250+
251+
// Update profile hashes
252+
if (neodetectState.profile) {
253+
neodetectState.profile.canvasHash = wasmExports.wasm_get_canvas_hash().toString();
254+
neodetectState.profile.webglHash = wasmExports.wasm_get_webgl_hash().toString();
255+
neodetectState.profile.audioHash = wasmExports.wasm_get_audio_hash().toString();
256+
}
257+
} else {
258+
// Fallback evolution
259+
neodetectState.similarity = Math.min(targetSimilarity, neodetectState.similarity + 0.05);
260+
neodetectState.lastEvolution = Date.now();
261+
}
262+
263+
await saveState();
264+
await notifyAllTabs();
265+
266+
return {
267+
similarity: neodetectState.similarity,
268+
profile: neodetectState.profile
269+
};
270+
}
271+
272+
// Initialize AI model
273+
async function initAIModel() {
274+
if (neodetectState.wasmReady && wasmExports) {
275+
const result = wasmExports.wasm_init_ai_model(256, 64, 2, BigInt(Date.now()));
276+
return result === 0;
277+
}
278+
return false;
279+
}
280+
281+
// Message handler
282+
browser.runtime.onMessage.addListener((message, sender) => {
283+
return handleMessage(message, sender);
284+
});
285+
286+
async function handleMessage(message, sender) {
287+
switch (message.action) {
288+
case 'getState':
289+
return {
290+
...neodetectState,
291+
wasmReady: neodetectState.wasmReady
292+
};
293+
294+
case 'setState':
295+
neodetectState = { ...neodetectState, ...message.state };
296+
await saveState();
297+
await notifyAllTabs();
298+
return { success: true };
299+
300+
case 'evolve':
301+
return await evolveFingerprint(message.targetSimilarity || 0.85, message.useAI || false);
302+
303+
case 'aiEvolve':
304+
return await evolveFingerprint(message.targetSimilarity || 0.90, true);
305+
306+
case 'reset':
307+
return await createProfile({
308+
seed: message.seed || Date.now(),
309+
osType: message.osType ?? neodetectState.osType,
310+
hwType: message.hwType ?? neodetectState.hwType,
311+
gpuType: message.gpuType ?? neodetectState.gpuType
312+
});
313+
314+
case 'initAI':
315+
const aiResult = await initAIModel();
316+
return { success: aiResult };
317+
318+
case 'getProfile':
319+
return neodetectState.profile;
320+
321+
default:
322+
return { error: 'Unknown action' };
323+
}
324+
}
325+
326+
// Save state to storage
327+
async function saveState() {
328+
await browser.storage.local.set({ neodetectState });
329+
}
330+
331+
// Notify all tabs of state change
332+
async function notifyAllTabs() {
333+
const tabs = await browser.tabs.query({});
334+
for (const tab of tabs) {
335+
try {
336+
await browser.tabs.sendMessage(tab.id, {
337+
action: 'profileUpdated',
338+
profile: neodetectState.profile,
339+
similarity: neodetectState.similarity,
340+
wasmReady: neodetectState.wasmReady
341+
});
342+
} catch (e) {
343+
// Tab might not have content script
344+
}
345+
}
346+
}
347+
348+
// Check for updates
349+
async function checkForUpdates() {
350+
try {
351+
const response = await fetch(UPDATE_CHECK_URL, { cache: 'no-store' });
352+
if (!response.ok) return;
353+
354+
const data = await response.json();
355+
if (data.version && data.version !== CURRENT_VERSION) {
356+
console.log(`🔥 New version available: ${data.version}`);
357+
neodetectState.updateAvailable = data.version;
358+
neodetectState.updateUrl = data.downloadUrl || 'https://github.com/gHashTag/trinity/releases';
359+
await saveState();
360+
361+
browser.browserAction.setBadgeText({ text: '!' });
362+
browser.browserAction.setBadgeBackgroundColor({ color: '#f39c12' });
363+
}
364+
} catch (e) {
365+
console.log('Update check failed:', e.message);
366+
}
367+
}
368+
369+
// Schedule update check
370+
browser.alarms.create('updateCheck', { periodInMinutes: 1440 });
371+
372+
// Auto-evolve check
373+
browser.alarms.create('autoEvolve', { periodInMinutes: 30 });
374+
375+
browser.alarms.onAlarm.addListener(async (alarm) => {
376+
if (alarm.name === 'updateCheck') {
377+
await checkForUpdates();
378+
} else if (alarm.name === 'autoEvolve') {
379+
const result = await browser.storage.local.get(['neodetectState']);
380+
if (result.neodetectState?.autoEvolve) {
381+
console.log('🔥 Auto-evolving fingerprint...');
382+
await evolveFingerprint(0.85);
383+
}
384+
}
385+
});
386+
387+
console.log('🔥 NeoDetect background script started (Firefox)');

0 commit comments

Comments
 (0)