(function() {
'use strict';
// ==================== 设备数据库 ====================
// 安卓手机品牌和型号
const ANDROID_DEVICES = [
// OPPO
{ brand: 'OPPO', model: 'PGJM10', name: 'OPPO Find X5 Pro' },
{ brand: 'OPPO', model: 'PGBM10', name: 'OPPO Find X5' },
{ brand: 'OPPO', model: 'PHM110', name: 'OPPO Find N2' },
{ brand: 'OPPO', model: 'CPH2451', name: 'OPPO Reno10 Pro+' },
{ brand: 'OPPO', model: 'CPH2413', name: 'OPPO Reno9 Pro+' },
{ brand: 'OPPO', model: 'PFTM10', name: 'OPPO Find X6 Pro' },
// vivo
{ brand: 'vivo', model: 'V2227A', name: 'vivo X90 Pro+' },
{ brand: 'vivo', model: 'V2229A', name: 'vivo X90 Pro' },
{ brand: 'vivo', model: 'V2231A', name: 'vivo X90' },
{ brand: 'vivo', model: 'V2285A', name: 'vivo X100 Pro' },
{ brand: 'vivo', model: 'V2309A', name: 'vivo S17 Pro' },
{ brand: 'vivo', model: 'V2199A', name: 'vivo X Fold+' },
// 小米
{ brand: 'Xiaomi', model: '2211133C', name: 'Xiaomi 13 Pro' },
{ brand: 'Xiaomi', model: '2210132C', name: 'Xiaomi 13' },
{ brand: 'Xiaomi', model: '2304FPN6DC', name: 'Xiaomi 13 Ultra' },
{ brand: 'Xiaomi', model: '23078PND5C', name: 'Xiaomi 14 Pro' },
{ brand: 'Xiaomi', model: '23127PN0CC', name: 'Xiaomi 14' },
{ brand: 'Xiaomi', model: '2211133G', name: 'Xiaomi MIX Fold 3' },
// Redmi
{ brand: 'Redmi', model: '23013RK75C', name: 'Redmi K60 Pro' },
{ brand: 'Redmi', model: '22127RK46C', name: 'Redmi K60' },
{ brand: 'Redmi', model: '23078RKD5C', name: 'Redmi K60 Ultra' },
{ brand: 'Redmi', model: '23090RA98C', name: 'Redmi K70 Pro' },
{ brand: 'Redmi', model: '2312DRA50C', name: 'Redmi Note 13 Pro+' },
// realme 真我
{ brand: 'realme', model: 'RMX3708', name: 'realme GT5 Pro' },
{ brand: 'realme', model: 'RMX3706', name: 'realme GT5' },
{ brand: 'realme', model: 'RMX3663', name: 'realme GT Neo5' },
{ brand: 'realme', model: 'RMX3710', name: 'realme GT Neo6' },
{ brand: 'realme', model: 'RMX3031', name: 'realme GT2 Pro' },
// Google Pixel
{ brand: 'Google', model: 'Pixel 7 Pro', name: 'Pixel 7 Pro' },
{ brand: 'Google', model: 'Pixel 7', name: 'Pixel 7' },
{ brand: 'Google', model: 'Pixel 8 Pro', name: 'Pixel 8 Pro' },
{ brand: 'Google', model: 'Pixel 8', name: 'Pixel 8' },
{ brand: 'Google', model: 'Pixel Fold', name: 'Pixel Fold' },
// 荣耀
{ brand: 'HONOR', model: 'PGT-AN10', name: 'HONOR Magic5 Pro' },
{ brand: 'HONOR', model: 'PGT-AN20', name: 'HONOR Magic5' },
{ brand: 'HONOR', model: 'LGE-AN00', name: 'HONOR Magic6 Pro' },
{ brand: 'HONOR', model: 'BVL-AN16', name: 'HONOR Magic V2' },
// 一加
{ brand: 'OnePlus', model: 'PHB110', name: 'OnePlus 11' },
{ brand: 'OnePlus', model: 'PJD110', name: 'OnePlus 12' },
{ brand: 'OnePlus', model: 'CPH2449', name: 'OnePlus Ace 2 Pro' },
];
// 骁龙778及以后的GPU型号
const ADRENO_GPUS = [
// 骁龙7系列
{ soc: 'Snapdragon 778G', gpu: 'Adreno 642L', cores: 8 },
{ soc: 'Snapdragon 780G', gpu: 'Adreno 642', cores: 8 },
{ soc: 'Snapdragon 782G', gpu: 'Adreno 642L', cores: 8 },
{ soc: 'Snapdragon 7+ Gen 2', gpu: 'Adreno 725', cores: 8 },
{ soc: 'Snapdragon 7 Gen 3', gpu: 'Adreno 720', cores: 8 },
// 骁龙8系列
{ soc: 'Snapdragon 888', gpu: 'Adreno 660', cores: 8 },
{ soc: 'Snapdragon 888+', gpu: 'Adreno 660', cores: 8 },
{ soc: 'Snapdragon 8 Gen 1', gpu: 'Adreno 730', cores: 8 },
{ soc: 'Snapdragon 8+ Gen 1', gpu: 'Adreno 730', cores: 8 },
{ soc: 'Snapdragon 8 Gen 2', gpu: 'Adreno 740', cores: 8 },
{ soc: 'Snapdragon 8 Gen 3', gpu: 'Adreno 750', cores: 8 },
// 天玑系列
{ soc: 'Dimensity 8100', gpu: 'Mali-G610 MC6', cores: 8 },
{ soc: 'Dimensity 8200', gpu: 'Mali-G610 MC6', cores: 8 },
{ soc: 'Dimensity 9000', gpu: 'Mali-G710 MC10', cores: 8 },
{ soc: 'Dimensity 9000+', gpu: 'Mali-G710 MC10', cores: 8 },
{ soc: 'Dimensity 9200', gpu: 'Mali-G715 MC11', cores: 8 },
{ soc: 'Dimensity 9200+', gpu: 'Mali-G715 MC11', cores: 8 },
{ soc: 'Dimensity 9300', gpu: 'Mali-G720 MC12', cores: 8 },
];
// 屏幕分辨率
const SCREEN_RESOLUTIONS = [
{ width: 1080, height: 2400, density: 2.75 },
{ width: 1080, height: 2412, density: 2.75 },
{ width: 1200, height: 2670, density: 3.0 },
{ width: 1260, height: 2800, density: 3.0 },
{ width: 1440, height: 3200, density: 3.5 },
{ width: 1440, height: 3216, density: 3.5 },
];
// ==================== 随机生成函数 ====================
function randomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function randomFloat(min, max, decimals = 2) {
return parseFloat((Math.random() * (max - min) + min).toFixed(decimals));
}
function randomChoice(array) {
return array[randomInt(0, array.length - 1)];
}
// ==================== 生成设备配置 ====================
function generateDeviceConfig() {
const device = randomChoice(ANDROID_DEVICES);
const gpu = randomChoice(ADRENO_GPUS);
const screen = randomChoice(SCREEN_RESOLUTIONS);
const ramOptions = [6, 8, 12, 16];
const deviceMemory = randomChoice(ramOptions);
const batteryLevel = randomFloat(0.2, 1.0, 2);
const batteryCharging = Math.random() > 0.5;
return {
device,
gpu,
screen,
deviceMemory,
batteryLevel,
batteryCharging,
deviceId: Math.random().toString(36).substring(2, 15)
};
}
// 生成配置
const CONFIG = generateDeviceConfig();
// ==================== 工具函数 ====================
function overrideProperty(obj, prop, value) {
try {
Object.defineProperty(obj, prop, {
get: function() { return value; },
configurable: true,
enumerable: true
});
} catch(e) {
console.warn('Failed to override:', prop, e);
}
}
// ==================== 劫持 XMLHttpRequest ====================
const originalXHROpen = XMLHttpRequest.prototype.open;
const originalXHRSend = XMLHttpRequest.prototype.send;
const originalXHRSetRequestHeader = XMLHttpRequest.prototype.setRequestHeader;
XMLHttpRequest.prototype._customHeaders = {};
XMLHttpRequest.prototype.setRequestHeader = function(header, value) {
this._customHeaders = this._customHeaders || {};
this._customHeaders[header.toLowerCase()] = value;
// 修改可能泄露设备信息的请求头
const headerLower = header.toLowerCase();
// 拦截 sec-ch-ua-model (设备型号)
if (headerLower === 'sec-ch-ua-model') {
value = `"${CONFIG.device.model}"`;
console.log(`%c[XHR] 修改 sec-ch-ua-model: ${value}`, 'color: #ff6b6b;');
}
// 拦截 sec-ch-ua-platform-version (系统版本)
if (headerLower === 'sec-ch-ua-platform-version') {
value = `"${randomInt(10, 14)}.0.0"`;
console.log(`%c[XHR] 修改 sec-ch-ua-platform-version: ${value}`, 'color: #ff6b6b;');
}
// 拦截 sec-ch-ua-full-version-list (完整版本列表)
if (headerLower === 'sec-ch-ua-full-version-list') {
value = `"Microsoft Edge";v="129.0.0.0", "Chromium";v="129.0.0.0", "Not=A?Brand";v="24.0.0.0"`;
console.log(`%c[XHR] 修改 sec-ch-ua-full-version-list`, 'color: #ff6b6b;');
}
return originalXHRSetRequestHeader.call(this, header, value);
};
XMLHttpRequest.prototype.open = function(method, url, async, user, password) {
this._url = url;
this._method = method;
return originalXHROpen.apply(this, arguments);
};
XMLHttpRequest.prototype.send = function(data) {
// 只添加不会暴露的Client Hints
const safeHeaders = {
'sec-ch-ua-mobile': '?1',
'sec-ch-ua-platform': '"Android"',
};
for (const [header, value] of Object.entries(safeHeaders)) {
try {
if (!this._customHeaders || !this._customHeaders[header.toLowerCase()]) {
originalXHRSetRequestHeader.call(this, header, value);
}
} catch(e) {}
}
return originalXHRSend.apply(this, arguments);
};
// ==================== 劫持 Fetch API ====================
const originalFetch = window.fetch;
window.fetch = function(resource, init) {
init = init || {};
init.headers = init.headers || {};
if (init.headers instanceof Headers) {
const headersObj = {};
for (const [key, value] of init.headers.entries()) {
headersObj[key] = value;
}
init.headers = headersObj;
}
// 修改可能泄露设备信息的请求头
const headersToModify = {
'sec-ch-ua-model': `"${CONFIG.device.model}"`,
'sec-ch-ua-platform-version': `"${randomInt(10, 14)}.0.0"`,
'sec-ch-ua-mobile': '?1',
'sec-ch-ua-platform': '"Android"',
};
// 检查并修改现有的敏感请求头
for (const [key, value] of Object.entries(init.headers)) {
const keyLower = key.toLowerCase();
if (keyLower === 'sec-ch-ua-model') {
init.headers[key] = headersToModify['sec-ch-ua-model'];
console.log(`%c[Fetch] 修改 sec-ch-ua-model: ${init.headers[key]}`, 'color: #4ecdc4;');
}
if (keyLower === 'sec-ch-ua-platform-version') {
init.headers[key] = headersToModify['sec-ch-ua-platform-version'];
console.log(`%c[Fetch] 修改 sec-ch-ua-platform-version: ${init.headers[key]}`, 'color: #4ecdc4;');
}
}
return originalFetch.apply(this, [resource, init]);
};
// ==================== Navigator 伪装 ====================
// 不修改 userAgent,保持 Edge 的统一 UA
// 只修改其他可能泄露的信息
overrideProperty(Navigator.prototype, 'platform', 'Linux armv8l');
overrideProperty(Navigator.prototype, 'language', 'zh-CN');
overrideProperty(Navigator.prototype, 'languages', ['zh-CN', 'zh', 'en-US', 'en']);
overrideProperty(Navigator.prototype, 'hardwareConcurrency', CONFIG.gpu.cores);
overrideProperty(Navigator.prototype, 'deviceMemory', CONFIG.deviceMemory);
overrideProperty(Navigator.prototype, 'maxTouchPoints', 5);
overrideProperty(Navigator.prototype, 'doNotTrack', null);
// 插件和MIME类型
overrideProperty(Navigator.prototype, 'plugins', {
length: 0,
item: () => null,
namedItem: () => null,
refresh: () => {}
});
overrideProperty(Navigator.prototype, 'mimeTypes', {
length: 0,
item: () => null,
namedItem: () => null
});
// 网络连接信息
if (navigator.connection) {
const connectionTypes = ['4g', '5g'];
const effectiveType = randomChoice(connectionTypes);
overrideProperty(Navigator.prototype, 'connection', {
effectiveType: effectiveType,
downlink: randomFloat(5, 50, 1),
rtt: randomInt(20, 100),
saveData: false,
type: 'cellular'
});
}
// User Agent Data - 这个很重要!
if (navigator.userAgentData) {
const originalGetHighEntropyValues = navigator.userAgentData.getHighEntropyValues;
overrideProperty(Navigator.prototype, 'userAgentData', {
brands: navigator.userAgentData.brands, // 保持原样
mobile: true,
platform: 'Android',
getHighEntropyValues: function(hints) {
// 劫持高熵值,返回伪造的设备信息
return Promise.resolve({
architecture: 'arm',
bitness: '64',
brands: navigator.userAgentData.brands,
fullVersionList: navigator.userAgentData.brands,
mobile: true,
model: CONFIG.device.model, // 伪造设备型号
platform: 'Android',
platformVersion: randomInt(10, 14).toString(), // 随机安卓版本
uaFullVersion: '129.0.0.0',
wow64: false
});
}
});
console.log(`%c[UserAgentData] 劫持 getHighEntropyValues,伪造设备型号: ${CONFIG.device.model}`, 'color: #95e1d3; font-weight: bold;');
}
// ==================== 屏幕信息伪装 ====================
overrideProperty(Screen.prototype, 'width', CONFIG.screen.width);
overrideProperty(Screen.prototype, 'height', CONFIG.screen.height);
overrideProperty(Screen.prototype, 'availWidth', CONFIG.screen.width);
overrideProperty(Screen.prototype, 'availHeight', CONFIG.screen.height - randomInt(50, 100));
overrideProperty(Screen.prototype, 'colorDepth', 24);
overrideProperty(Screen.prototype, 'pixelDepth', 24);
overrideProperty(window, 'devicePixelRatio', CONFIG.screen.density);
// ==================== 时区伪装 ====================
Date.prototype.getTimezoneOffset = function() {
return -480; // UTC+8
};
const originalToString = Date.prototype.toString;
Date.prototype.toString = function() {
return originalToString.call(this).replace(/\(.*\)/, '(中国标准时间)');
};
// ==================== 电池API伪装 ====================
if (navigator.getBattery) {
navigator.getBattery = function() {
return Promise.resolve({
charging: CONFIG.batteryCharging,
chargingTime: CONFIG.batteryCharging ? randomInt(1800, 7200) : Infinity,
dischargingTime: CONFIG.batteryCharging ? Infinity : randomInt(3600, 28800),
level: CONFIG.batteryLevel,
addEventListener: () => {},
removeEventListener: () => {},
dispatchEvent: () => true
});
};
}
// ==================== Canvas指纹伪装 ====================
const originalToDataURL = HTMLCanvasElement.prototype.toDataURL;
HTMLCanvasElement.prototype.toDataURL = function(type) {
const context = this.getContext('2d');
if (context) {
const imageData = context.getImageData(0, 0, this.width, this.height);
const seed = CONFIG.deviceId.split('').reduce((a, b) => a + b.charCodeAt(0), 0);
for (let i = 0; i < imageData.data.length; i += 4) {
const noise = ((seed + i) % 100) / 100000;
imageData.data[i] += noise;
imageData.data[i + 1] += noise;
imageData.data[i + 2] += noise;
}
context.putImageData(imageData, 0, 0);
}
return originalToDataURL.apply(this, arguments);
};
const originalToBlob = HTMLCanvasElement.prototype.toBlob;
HTMLCanvasElement.prototype.toBlob = function(callback, type, quality) {
const context = this.getContext('2d');
if (context) {
const imageData = context.getImageData(0, 0, this.width, this.height);
const seed = CONFIG.deviceId.split('').reduce((a, b) => a + b.charCodeAt(0), 0);
for (let i = 0; i < imageData.data.length; i += 4) {
const noise = ((seed + i) % 100) / 100000;
imageData.data[i] += noise;
imageData.data[i + 1] += noise;
imageData.data[i + 2] += noise;
}
context.putImageData(imageData, 0, 0);
}
return originalToBlob.apply(this, arguments);
};
// ==================== WebGL指纹伪装 ====================
const webglVendor = CONFIG.gpu.gpu.includes('Adreno') ? 'Qualcomm' : 'ARM';
const webglRenderer = `${CONFIG.gpu.gpu}`;
const getParameterProxyHandler = {
apply: function(target, thisArg, args) {
const param = args[0];
if (param === 37445) return webglVendor;
if (param === 37446) return webglRenderer;
return target.apply(thisArg, args);
}
};
if (typeof WebGLRenderingContext !== 'undefined') {
const originalGetParameter = WebGLRenderingContext.prototype.getParameter;
WebGLRenderingContext.prototype.getParameter = new Proxy(originalGetParameter, getParameterProxyHandler);
}
if (typeof WebGL2RenderingContext !== 'undefined') {
const originalGetParameter2 = WebGL2RenderingContext.prototype.getParameter;
WebGL2RenderingContext.prototype.getParameter = new Proxy(originalGetParameter2, getParameterProxyHandler);
}
// ==================== 音频指纹伪装 ====================
if (typeof AudioContext !== 'undefined') {
const originalCreateAnalyser = AudioContext.prototype.createAnalyser;
AudioContext.prototype.createAnalyser = function() {
const analyser = originalCreateAnalyser.call(this);
const originalGetFloatFrequencyData = analyser.getFloatFrequencyData;
const seed = CONFIG.deviceId.split('').reduce((a, b) => a + b.charCodeAt(0), 0);
analyser.getFloatFrequencyData = function(array) {
originalGetFloatFrequencyData.call(this, array);
for (let i = 0; i < array.length; i++) {
array[i] += ((seed + i) % 100) / 100000;
}
};
return analyser;
};
}
// ==================== WebRTC防护 ====================
if (typeof RTCPeerConnection !== 'undefined') {
window.RTCPeerConnection = function() {
throw new Error('RTCPeerConnection is not supported');
};
}
if (typeof webkitRTCPeerConnection !== 'undefined') {
window.webkitRTCPeerConnection = function() {
throw new Error('webkitRTCPeerConnection is not supported');
};
}
// ==================== 其他防护 ====================
if (document.fonts) {
document.fonts.check = function() { return false; };
}
if (window.performance && window.performance.memory) {
const memorySize = CONFIG.deviceMemory * 1024 * 1024 * 1024;
overrideProperty(performance, 'memory', {
jsHeapSizeLimit: memorySize,
totalJSHeapSize: Math.floor(memorySize * 0.3),
usedJSHeapSize: Math.floor(memorySize * 0.2)
});
}
overrideProperty(window, 'ontouchstart', null);
overrideProperty(window, 'ontouchmove', null);
overrideProperty(window, 'ontouchend', null);
// ==================== 日志输出 ====================
console.log('%c╔════════════════════════════════════════════════════════════╗', 'color: #00ff00; font-weight: bold;');
console.log('%c║ 🛡️ 安卓设备指纹伪装 (保持Edge UA) 已启动 🛡️ ║', 'color: #00ff00; font-weight: bold;');
console.log('%c╚════════════════════════════════════════════════════════════╝', 'color: #00ff00; font-weight: bold;');
console.log('%c\n📱 当前伪装设备信息:', 'color: #00bfff; font-weight: bold; font-size: 14px;');
console.table({
'品牌': CONFIG.device.brand,
'型号': CONFIG.device.model,
'设备名': CONFIG.device.name,
'处理器': CONFIG.gpu.soc,
'GPU': CONFIG.gpu.gpu,
'CPU核心': CONFIG.gpu.cores,
'内存': `${CONFIG.deviceMemory}GB`,
'屏幕分辨率': `${CONFIG.screen.width}x${CONFIG.screen.height}`,
'像素密度': CONFIG.screen.density,
'电池电量': `${(CONFIG.batteryLevel * 100).toFixed(0)}%`,
'充电状态': CONFIG.batteryCharging ? '充电中' : '未充电'
});
console.log('%c\n⚠️ User-Agent 保持不变 (Edge统一UA):', 'color: #ffa500; font-weight: bold;');
console.log('%c' + navigator.userAgent, 'color: #888;');
console.log('%c\n🔒 已启用的防护功能:', 'color: #ff6b6b; font-weight: bold;');
console.log('%c✅ 劫持 navigator.userAgentData.getHighEntropyValues()', 'color: #4ecdc4;');
console.log('%c✅ 劫持 XMLHttpRequest 敏感请求头', 'color: #4ecdc4;');
console.log('%c✅ 劫持 Fetch API 敏感请求头', 'color: #4ecdc4;');
console.log('%c✅ 伪装屏幕分辨率和像素密度', 'color: #4ecdc4;');
console.log('%c✅ 伪装硬件信息 (CPU/内存)', 'color: #4ecdc4;');
console.log('%c✅ 伪装电池信息', 'color: #4ecdc4;');
console.log('%c✅ 伪装Canvas指纹', 'color: #4ecdc4;');
console.log('%c✅ 伪装WebGL指纹', 'color: #4ecdc4;');
console.log('%c✅ 伪装音频指纹', 'color: #4ecdc4;');
console.log('%c✅ 禁用WebRTC (防止IP泄露)', 'color: #4ecdc4;');
console.log('%c✅ 隐藏插件和字体信息', 'color: #4ecdc4;');
})();
37 个赞
我看看怎么个事
2 个赞
别的浏览器可以吗
不行,因为这边不是油猴脚本,而是普通的用户脚本
轮子批发商![]()
有没有网站可以测试一下
目前这个脚本还比较初级,只能解决一些小问题,后续版本已在调试中
我给我浏览器加上脚本了,也不知道成没成
1 个赞
点赞支持
脚本上新了
// ==UserScript==
// @name 终极随机指纹防护
// @namespace http://tampermonkey.net/
// @version 1.0
// @description 修复刷新后失效的问题
// @match *://*/*
// @run-at document-start
// @grant none
// ==/UserScript==
(function() {
'use strict';
const ANDROID_DEVICES = [
{ brand: 'OPPO', model: 'PGJM10', name: 'OPPO Find X5 Pro' },
{ brand: 'OPPO', model: 'PGBM10', name: 'OPPO Find X5' },
{ brand: 'OPPO', model: 'PHM110', name: 'OPPO Find N2' },
{ brand: 'OPPO', model: 'CPH2451', name: 'OPPO Reno10 Pro+' },
{ brand: 'OPPO', model: 'CPH2413', name: 'OPPO Reno9 Pro+' },
{ brand: 'OPPO', model: 'PFTM10', name: 'OPPO Find X6 Pro' },
{ brand: 'OPPO', model: 'CPH2525', name: 'OPPO Find X7 Ultra' },
{ brand: 'vivo', model: 'V2227A', name: 'vivo X90 Pro+' },
{ brand: 'vivo', model: 'V2229A', name: 'vivo X90 Pro' },
{ brand: 'vivo', model: 'V2231A', name: 'vivo X90' },
{ brand: 'vivo', model: 'V2285A', name: 'vivo X100 Pro' },
{ brand: 'vivo', model: 'V2309A', name: 'vivo S17 Pro' },
{ brand: 'vivo', model: 'V2199A', name: 'vivo X Fold+' },
{ brand: 'vivo', model: 'V2324A', name: 'vivo X100 Ultra' },
{ brand: 'Xiaomi', model: '2211133C', name: 'Xiaomi 13 Pro' },
{ brand: 'Xiaomi', model: '2210132C', name: 'Xiaomi 13' },
{ brand: 'Xiaomi', model: '2304FPN6DC', name: 'Xiaomi 13 Ultra' },
{ brand: 'Xiaomi', model: '23078PND5C', name: 'Xiaomi 14 Pro' },
{ brand: 'Xiaomi', model: '23127PN0CC', name: 'Xiaomi 14' },
{ brand: 'Xiaomi', model: '2211133G', name: 'Xiaomi MIX Fold 3' },
{ brand: 'Xiaomi', model: '24031PN0DC', name: 'Xiaomi 14 Ultra' },
{ brand: 'Redmi', model: '23013RK75C', name: 'Redmi K60 Pro' },
{ brand: 'Redmi', model: '22127RK46C', name: 'Redmi K60' },
{ brand: 'Redmi', model: '23078RKD5C', name: 'Redmi K60 Ultra' },
{ brand: 'Redmi', model: '23090RA98C', name: 'Redmi K70 Pro' },
{ brand: 'Redmi', model: '2312DRA50C', name: 'Redmi Note 13 Pro+' },
{ brand: 'Redmi', model: '23117RK66C', name: 'Redmi K70' },
{ brand: 'realme', model: 'RMX3708', name: 'realme GT5 Pro' },
{ brand: 'realme', model: 'RMX3706', name: 'realme GT5' },
{ brand: 'realme', model: 'RMX3663', name: 'realme GT Neo5' },
{ brand: 'realme', model: 'RMX3710', name: 'realme GT Neo6' },
{ brand: 'realme', model: 'RMX3031', name: 'realme GT2 Pro' },
{ brand: 'realme', model: 'RMX3700', name: 'realme GT3' },
{ brand: 'Google', model: 'Pixel 7 Pro', name: 'Pixel 7 Pro' },
{ brand: 'Google', model: 'Pixel 7', name: 'Pixel 7' },
{ brand: 'Google', model: 'Pixel 8 Pro', name: 'Pixel 8 Pro' },
{ brand: 'Google', model: 'Pixel 8', name: 'Pixel 8' },
{ brand: 'Google', model: 'Pixel Fold', name: 'Pixel Fold' },
{ brand: 'Google', model: 'Pixel 8a', name: 'Pixel 8a' },
{ brand: 'HONOR', model: 'PGT-AN10', name: 'HONOR Magic5 Pro' },
{ brand: 'HONOR', model: 'PGT-AN20', name: 'HONOR Magic5' },
{ brand: 'HONOR', model: 'LGE-AN00', name: 'HONOR Magic6 Pro' },
{ brand: 'HONOR', model: 'BVL-AN16', name: 'HONOR Magic V2' },
{ brand: 'HONOR', model: 'LRA-AN00', name: 'HONOR Magic6' },
{ brand: 'OnePlus', model: 'PHB110', name: 'OnePlus 11' },
{ brand: 'OnePlus', model: 'PJD110', name: 'OnePlus 12' },
{ brand: 'OnePlus', model: 'CPH2449', name: 'OnePlus Ace 2 Pro' },
{ brand: 'OnePlus', model: 'CPH2581', name: 'OnePlus Ace 3 Pro' },
{ brand: 'Samsung', model: 'SM-S9180', name: 'Samsung Galaxy S23 Ultra' },
{ brand: 'Samsung', model: 'SM-S9110', name: 'Samsung Galaxy S23+' },
{ brand: 'Samsung', model: 'SM-S9280', name: 'Samsung Galaxy S24 Ultra' },
{ brand: 'Samsung', model: 'SM-F9460', name: 'Samsung Galaxy Z Fold5' },
];
const GPU_DATABASE = [
{ soc: 'Snapdragon 778G', gpu: 'Adreno 642L', cores: 8, vendor: 'Qualcomm' },
{ soc: 'Snapdragon 780G', gpu: 'Adreno 642', cores: 8, vendor: 'Qualcomm' },
{ soc: 'Snapdragon 782G', gpu: 'Adreno 642L', cores: 8, vendor: 'Qualcomm' },
{ soc: 'Snapdragon 7+ Gen 2', gpu: 'Adreno 725', cores: 8, vendor: 'Qualcomm' },
{ soc: 'Snapdragon 7 Gen 3', gpu: 'Adreno 720', cores: 8, vendor: 'Qualcomm' },
{ soc: 'Snapdragon 888', gpu: 'Adreno 660', cores: 8, vendor: 'Qualcomm' },
{ soc: 'Snapdragon 888+', gpu: 'Adreno 660', cores: 8, vendor: 'Qualcomm' },
{ soc: 'Snapdragon 8 Gen 1', gpu: 'Adreno 730', cores: 8, vendor: 'Qualcomm' },
{ soc: 'Snapdragon 8+ Gen 1', gpu: 'Adreno 730', cores: 8, vendor: 'Qualcomm' },
{ soc: 'Snapdragon 8 Gen 2', gpu: 'Adreno 740', cores: 8, vendor: 'Qualcomm' },
{ soc: 'Snapdragon 8 Gen 3', gpu: 'Adreno 750', cores: 8, vendor: 'Qualcomm' },
{ soc: 'Dimensity 8100', gpu: 'Mali-G610 MC6', cores: 8, vendor: 'ARM' },
{ soc: 'Dimensity 8200', gpu: 'Mali-G610 MC6', cores: 8, vendor: 'ARM' },
{ soc: 'Dimensity 8300', gpu: 'Mali-G615 MC6', cores: 8, vendor: 'ARM' },
{ soc: 'Dimensity 9000', gpu: 'Mali-G710 MC10', cores: 8, vendor: 'ARM' },
{ soc: 'Dimensity 9000+', gpu: 'Mali-G710 MC10', cores: 8, vendor: 'ARM' },
{ soc: 'Dimensity 9200', gpu: 'Mali-G715 MC11', cores: 8, vendor: 'ARM' },
{ soc: 'Dimensity 9200+', gpu: 'Mali-G715 MC11', cores: 8, vendor: 'ARM' },
{ soc: 'Dimensity 9300', gpu: 'Mali-G720 MC12', cores: 8, vendor: 'ARM' },
{ soc: 'Exynos 2200', gpu: 'Xclipse 920', cores: 8, vendor: 'Samsung' },
{ soc: 'Exynos 2400', gpu: 'Xclipse 940', cores: 8, vendor: 'Samsung' },
{ soc: 'Google Tensor G2', gpu: 'Mali-G710 MC10', cores: 8, vendor: 'ARM' },
{ soc: 'Google Tensor G3', gpu: 'Mali-G715 MC10', cores: 8, vendor: 'ARM' },
];
const SCREEN_RESOLUTIONS = [
{ width: 1080, height: 2340, density: 2.5 },
{ width: 1080, height: 2400, density: 2.625 },
{ width: 1080, height: 2412, density: 2.75 },
{ width: 1080, height: 2460, density: 2.8 },
{ width: 1200, height: 2670, density: 3.0 },
{ width: 1220, height: 2712, density: 3.0 },
{ width: 1260, height: 2800, density: 3.0 },
{ width: 1440, height: 3120, density: 3.5 },
{ width: 1440, height: 3200, density: 3.5 },
{ width: 1440, height: 3216, density: 3.5 },
{ width: 1440, height: 3088, density: 3.5 },
];
function randomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function randomFloat(min, max, decimals = 2) {
return parseFloat((Math.random() * (max - min) + min).toFixed(decimals));
}
function randomChoice(array) {
return array[randomInt(0, array.length - 1)];
}
const CONFIG = {
device: randomChoice(ANDROID_DEVICES),
gpu: randomChoice(GPU_DATABASE),
screen: randomChoice(SCREEN_RESOLUTIONS),
memory: randomChoice([6, 8, 12, 16, 18, 24]),
battery: {
level: randomFloat(0.20, 0.95, 2),
charging: Math.random() > 0.7
},
network: {
type: randomChoice(['4g', '5g']),
downlink: randomFloat(5, 100, 1),
rtt: randomInt(20, 150)
},
androidVersion: randomInt(11, 14),
canvasSeed: Math.random() * 100000,
audioSeed: Math.random() * 100000,
deviceId: Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15)
};
const fakeBrands = [
{ brand: "Microsoft Edge", version: "129" },
{ brand: "Chromium", version: "129" },
{ brand: "Not=A?Brand", version: "24" }
];
Object.defineProperty(navigator, 'userAgentData', {
get: () => ({
brands: fakeBrands,
mobile: true,
platform: 'Android',
getHighEntropyValues: (hints) => Promise.resolve({
architecture: 'arm',
bitness: '64',
brands: fakeBrands,
fullVersionList: fakeBrands,
mobile: true,
model: CONFIG.device.model,
platform: 'Android',
platformVersion: CONFIG.androidVersion.toString(),
uaFullVersion: '129.0.0.0',
wow64: false
}),
toJSON: () => ({ brands: fakeBrands, mobile: true, platform: 'Android' })
}),
configurable: true
});
delete window.RTCPeerConnection;
delete window.webkitRTCPeerConnection;
delete window.mozRTCPeerConnection;
delete window.RTCSessionDescription;
delete window.RTCIceCandidate;
delete window.RTCDataChannel;
delete window.RTCStatsReport;
Object.defineProperty(window, 'RTCPeerConnection', {
get: () => undefined,
set: () => {},
configurable: false
});
Object.defineProperty(window, 'webkitRTCPeerConnection', {
get: () => undefined,
set: () => {},
configurable: false
});
const originalToDataURL = HTMLCanvasElement.prototype.toDataURL;
const originalToBlob = HTMLCanvasElement.prototype.toBlob;
const originalGetImageData = CanvasRenderingContext2D.prototype.getImageData;
function addCanvasNoise(imageData, seed) {
const data = imageData.data;
for (let i = 0; i < data.length; i += 4) {
const noise = (Math.sin(seed + i * 0.01) * Math.cos(seed + i * 0.02)) * 3;
data[i] = Math.min(255, Math.max(0, data[i] + noise));
data[i + 1] = Math.min(255, Math.max(0, data[i + 1] + noise));
data[i + 2] = Math.min(255, Math.max(0, data[i + 2] + noise));
}
return imageData;
}
HTMLCanvasElement.prototype.toDataURL = function(...args) {
const context = this.getContext('2d');
if (context && this.width > 0 && this.height > 0) {
try {
const imageData = context.getImageData(0, 0, this.width, this.height);
const noisyData = addCanvasNoise(imageData, CONFIG.canvasSeed);
context.putImageData(noisyData, 0, 0);
} catch(e) {}
}
return originalToDataURL.apply(this, args);
};
HTMLCanvasElement.prototype.toBlob = function(...args) {
const context = this.getContext('2d');
if (context && this.width > 0 && this.height > 0) {
try {
const imageData = context.getImageData(0, 0, this.width, this.height);
const noisyData = addCanvasNoise(imageData, CONFIG.canvasSeed);
context.putImageData(noisyData, 0, 0);
} catch(e) {}
}
return originalToBlob.apply(this, args);
};
CanvasRenderingContext2D.prototype.getImageData = function(...args) {
const imageData = originalGetImageData.apply(this, args);
return addCanvasNoise(imageData, CONFIG.canvasSeed);
};
if (typeof AudioContext !== 'undefined' || typeof webkitAudioContext !== 'undefined') {
const AudioContextConstructor = window.AudioContext || window.webkitAudioContext;
const OriginalAudioContext = AudioContextConstructor;
window.AudioContext = window.webkitAudioContext = function() {
const context = new OriginalAudioContext();
const originalCreateOscillator = context.createOscillator.bind(context);
context.createOscillator = function() {
const oscillator = originalCreateOscillator();
const originalFrequency = oscillator.frequency;
const noise = (Math.sin(CONFIG.audioSeed) + Math.cos(CONFIG.audioSeed * 0.5)) * 0.01;
Object.defineProperty(oscillator, 'frequency', {
get: () => {
const freq = originalFrequency;
return new Proxy(freq, {
get(target, prop) {
if (prop === 'value') {
return target.value + noise;
}
if (prop === 'setValueAtTime') {
return function(value, time) {
return target.setValueAtTime(value + noise, time);
};
}
return target[prop];
}
});
},
configurable: true
});
return oscillator;
};
const originalCreateDynamicsCompressor = context.createDynamicsCompressor.bind(context);
context.createDynamicsCompressor = function() {
const compressor = originalCreateDynamicsCompressor();
const noise = (Math.sin(CONFIG.audioSeed) + Math.cos(CONFIG.audioSeed * 0.7)) * 0.01;
['threshold', 'knee', 'ratio', 'attack', 'release'].forEach(param => {
const original = compressor[param];
Object.defineProperty(compressor, param, {
get: () => {
return new Proxy(original, {
get(target, prop) {
if (prop === 'value') {
return target.value + noise;
}
if (prop === 'setValueAtTime') {
return function(value, time) {
return target.setValueAtTime(value + noise, time);
};
}
return target[prop];
}
});
},
configurable: true
});
});
return compressor;
};
const originalCreateAnalyser = context.createAnalyser.bind(context);
context.createAnalyser = function() {
const analyser = originalCreateAnalyser();
const originalGetFloatFrequencyData = analyser.getFloatFrequencyData.bind(analyser);
analyser.getFloatFrequencyData = function(array) {
originalGetFloatFrequencyData(array);
for (let i = 0; i < array.length; i++) {
const noise = (Math.sin(CONFIG.audioSeed + i * 0.1) + Math.cos(CONFIG.audioSeed + i * 0.2)) * 0.01;
array[i] += noise;
}
};
const originalGetByteFrequencyData = analyser.getByteFrequencyData.bind(analyser);
analyser.getByteFrequencyData = function(array) {
originalGetByteFrequencyData(array);
for (let i = 0; i < array.length; i++) {
const noise = Math.sin(CONFIG.audioSeed + i) * 0.5;
array[i] = Math.min(255, Math.max(0, array[i] + noise));
}
};
const originalGetFloatTimeDomainData = analyser.getFloatTimeDomainData.bind(analyser);
analyser.getFloatTimeDomainData = function(array) {
originalGetFloatTimeDomainData(array);
for (let i = 0; i < array.length; i++) {
const noise = Math.sin(CONFIG.audioSeed + i) * 0.001;
array[i] += noise;
}
};
const originalGetByteTimeDomainData = analyser.getByteTimeDomainData.bind(analyser);
analyser.getByteTimeDomainData = function(array) {
originalGetByteTimeDomainData(array);
for (let i = 0; i < array.length; i++) {
const noise = Math.sin(CONFIG.audioSeed + i) * 0.5;
array[i] = Math.min(255, Math.max(0, array[i] + noise));
}
};
return analyser;
};
return context;
};
window.AudioContext.prototype = OriginalAudioContext.prototype;
if (window.webkitAudioContext) {
window.webkitAudioContext.prototype = OriginalAudioContext.prototype;
}
}
Object.defineProperty(screen, 'width', {
get: () => CONFIG.screen.width,
configurable: true
});
Object.defineProperty(screen, 'height', {
get: () => CONFIG.screen.height,
configurable: true
});
Object.defineProperty(screen, 'availWidth', {
get: () => CONFIG.screen.width,
configurable: true
});
Object.defineProperty(screen, 'availHeight', {
get: () => CONFIG.screen.height - 80,
configurable: true
});
Object.defineProperty(screen, 'colorDepth', {
get: () => 24,
configurable: true
});
Object.defineProperty(screen, 'pixelDepth', {
get: () => 24,
configurable: true
});
Object.defineProperty(window, 'devicePixelRatio', {
get: () => CONFIG.screen.density,
configurable: true
});
Object.defineProperty(navigator, 'hardwareConcurrency', {
get: () => CONFIG.gpu.cores,
configurable: true
});
Object.defineProperty(navigator, 'deviceMemory', {
get: () => CONFIG.memory,
configurable: true
});
Object.defineProperty(navigator, 'maxTouchPoints', {
get: () => 5,
configurable: true
});
if (performance.memory) {
const memorySize = CONFIG.memory * 1024 * 1024 * 1024;
Object.defineProperty(performance, 'memory', {
get: () => ({
jsHeapSizeLimit: memorySize,
totalJSHeapSize: Math.floor(memorySize * randomFloat(0.25, 0.35)),
usedJSHeapSize: Math.floor(memorySize * randomFloat(0.15, 0.25))
}),
configurable: true
});
}
if (navigator.storage && navigator.storage.estimate) {
const originalEstimate = navigator.storage.estimate.bind(navigator.storage);
navigator.storage.estimate = function() {
const quota = CONFIG.memory * randomInt(14, 18) * 1024 * 1024 * 1024;
return Promise.resolve({
quota: quota,
usage: Math.floor(quota * randomFloat(0.001, 0.005)),
usageDetails: {}
});
};
}
const webglVendor = CONFIG.gpu.vendor;
const webglRenderer = CONFIG.gpu.gpu;
const originalGetParameter = WebGLRenderingContext.prototype.getParameter;
WebGLRenderingContext.prototype.getParameter = function(param) {
if (param === 37445) return webglVendor;
if (param === 37446) return webglRenderer;
if (param === 7936) return 'WebKit';
if (param === 7937) return 'WebKit WebGL';
return originalGetParameter.call(this, param);
};
if (typeof WebGL2RenderingContext !== 'undefined') {
const originalGetParameter2 = WebGL2RenderingContext.prototype.getParameter;
WebGL2RenderingContext.prototype.getParameter = function(param) {
if (param === 37445) return webglVendor;
if (param === 37446) return webglRenderer;
if (param === 7936) return 'WebKit';
if (param === 7937) return 'WebKit WebGL';
return originalGetParameter2.call(this, param);
};
}
const fakeBattery = {
charging: CONFIG.battery.charging,
chargingTime: CONFIG.battery.charging ? randomInt(1800, 7200) : Infinity,
dischargingTime: CONFIG.battery.charging ? Infinity : randomInt(10800, 28800),
level: CONFIG.battery.level,
addEventListener: () => {},
removeEventListener: () => {},
dispatchEvent: () => true,
onchargingchange: null,
onchargingtimechange: null,
ondischargingtimechange: null,
onlevelchange: null
};
Object.defineProperty(navigator, 'getBattery', {
value: () => Promise.resolve(fakeBattery),
configurable: true
});
const fakeConnection = {
effectiveType: CONFIG.network.type,
downlink: CONFIG.network.downlink,
rtt: CONFIG.network.rtt,
saveData: false,
type: 'wifi',
addEventListener: () => {},
removeEventListener: () => {},
dispatchEvent: () => true
};
Object.defineProperty(navigator, 'connection', {
get: () => fakeConnection,
configurable: true
});
Object.defineProperty(navigator, 'mozConnection', {
get: () => fakeConnection,
configurable: true
});
Object.defineProperty(navigator, 'webkitConnection', {
get: () => fakeConnection,
configurable: true
});
delete window.DeviceMotionEvent;
delete window.DeviceOrientationEvent;
delete window.Gyroscope;
delete window.Accelerometer;
delete window.LinearAccelerationSensor;
delete window.GravitySensor;
delete window.Magnetometer;
delete window.AmbientLightSensor;
delete window.AbsoluteOrientationSensor;
delete window.RelativeOrientationSensor;
const originalAddEventListener = EventTarget.prototype.addEventListener;
EventTarget.prototype.addEventListener = function(type, listener, options) {
const blockedEvents = [
'devicemotion',
'deviceorientation',
'deviceorientationabsolute',
'devicelight',
'deviceproximity',
'userproximity'
];
if (blockedEvents.includes(type.toLowerCase())) {
return;
}
return originalAddEventListener.call(this, type, listener, options);
};
Object.defineProperty(window, 'ondevicemotion', {
get: () => null,
set: () => {},
configurable: true
});
Object.defineProperty(window, 'ondeviceorientation', {
get: () => null,
set: () => {},
configurable: true
});
Object.defineProperty(window, 'ondeviceorientationabsolute', {
get: () => null,
set: () => {},
configurable: true
});
if (navigator.mediaDevices) {
Object.defineProperty(navigator.mediaDevices, 'enumerateDevices', {
value: () => Promise.resolve([]),
configurable: true
});
Object.defineProperty(navigator.mediaDevices, 'getUserMedia', {
value: () => Promise.reject(new DOMException('Permission denied', 'NotAllowedError')),
configurable: true
});
Object.defineProperty(navigator.mediaDevices, 'getDisplayMedia', {
value: () => Promise.reject(new DOMException('Permission denied', 'NotAllowedError')),
configurable: true
});
}
Object.defineProperty(navigator, 'getUserMedia', {
value: (constraints, success, error) => {
if (error) error(new DOMException('Permission denied', 'NotAllowedError'));
},
configurable: true
});
Object.defineProperty(navigator, 'webkitGetUserMedia', {
value: (constraints, success, error) => {
if (error) error(new DOMException('Permission denied', 'NotAllowedError'));
},
configurable: true
});
Object.defineProperty(navigator, 'mozGetUserMedia', {
value: (constraints, success, error) => {
if (error) error(new DOMException('Permission denied', 'NotAllowedError'));
},
configurable: true
});
if (navigator.geolocation) {
Object.defineProperty(navigator.geolocation, 'getCurrentPosition', {
value: (success, error) => {
if (error) error({ code: 1, message: 'User denied Geolocation' });
},
configurable: true
});
Object.defineProperty(navigator.geolocation, 'watchPosition', {
value: (success, error) => {
if (error) error({ code: 1, message: 'User denied Geolocation' });
return 0;
},
configurable: true
});
Object.defineProperty(navigator.geolocation, 'clearWatch', {
value: () => {},
configurable: true
});
}
Object.defineProperty(navigator, 'plugins', {
get: () => ({
length: 0,
item: () => null,
namedItem: () => null,
refresh: () => {},
[Symbol.iterator]: function* () {}
}),
configurable: true
});
Object.defineProperty(navigator, 'mimeTypes', {
get: () => ({
length: 0,
item: () => null,
namedItem: () => null,
[Symbol.iterator]: function* () {}
}),
configurable: true
});
if (document.fonts) {
const originalCheck = document.fonts.check;
const originalLoad = document.fonts.load;
document.fonts.check = function() { return false; };
document.fonts.load = function() { return Promise.resolve([]); };
Object.defineProperty(document.fonts, 'size', {
get: () => 0,
configurable: true
});
Object.defineProperty(document.fonts, 'ready', {
get: () => Promise.resolve(document.fonts),
configurable: true
});
}
if (window.Notification) {
Object.defineProperty(window, 'Notification', {
value: function() {
throw new Error('Notification is not supported');
},
configurable: true
});
Object.defineProperty(window.Notification, 'permission', {
get: () => 'denied',
configurable: true
});
}
Object.defineProperty(navigator, 'vibrate', {
value: () => false,
configurable: true
});
Object.defineProperty(navigator, 'getGamepads', {
value: () => [],
configurable: true
});
if (navigator.bluetooth) {
Object.defineProperty(navigator.bluetooth, 'requestDevice', {
value: () => Promise.reject(new Error('Bluetooth not available')),
configurable: true
});
Object.defineProperty(navigator.bluetooth, 'getAvailability', {
value: () => Promise.resolve(false),
configurable: true
});
}
if (navigator.usb) {
Object.defineProperty(navigator.usb, 'requestDevice', {
value: () => Promise.reject(new Error('USB not available')),
configurable: true
});
Object.defineProperty(navigator.usb, 'getDevices', {
value: () => Promise.resolve([]),
configurable: true
});
}
delete window.NDEFReader;
if (navigator.serial) {
Object.defineProperty(navigator.serial, 'requestPort', {
value: () => Promise.reject(new Error('Serial not available')),
configurable: true
});
Object.defineProperty(navigator.serial, 'getPorts', {
value: () => Promise.resolve([]),
configurable: true
});
}
if (navigator.hid) {
Object.defineProperty(navigator.hid, 'requestDevice', {
value: () => Promise.reject(new Error('HID not available')),
configurable: true
});
Object.defineProperty(navigator.hid, 'getDevices', {
value: () => Promise.resolve([]),
configurable: true
});
}
const timezoneOffset = -480;
Date.prototype.getTimezoneOffset = function() {
return timezoneOffset;
};
const originalToString = Date.prototype.toString;
Date.prototype.toString = function() {
return originalToString.call(this).replace(/\(.*\)/, '(中国标准时间)');
};
const originalToTimeString = Date.prototype.toTimeString;
Date.prototype.toTimeString = function() {
return originalToTimeString.call(this).replace(/\(.*\)/, '(中国标准时间)');
};
if (window.Intl && window.Intl.DateTimeFormat) {
const OriginalDateTimeFormat = Intl.DateTimeFormat;
Intl.DateTimeFormat = function(locales, options) {
return new OriginalDateTimeFormat('zh-CN', options);
};
Intl.DateTimeFormat.prototype = OriginalDateTimeFormat.prototype;
Intl.DateTimeFormat.supportedLocalesOf = OriginalDateTimeFormat.supportedLocalesOf;
}
const originalXHRSetRequestHeader = XMLHttpRequest.prototype.setRequestHeader;
XMLHttpRequest.prototype.setRequestHeader = function(header, value) {
const headerLower = header.toLowerCase();
const blockedHeaders = [
'sec-ch-ua-model',
'sec-ch-ua-platform-version',
'sec-ch-ua-full-version-list',
'sec-ch-ua-arch',
'sec-ch-ua-bitness',
'sec-ch-ua-wow64',
'sec-ch-device-memory',
'sec-ch-dpr',
'sec-ch-viewport-width',
'sec-ch-viewport-height',
'sec-ch-ua-mobile'
];
if (blockedHeaders.includes(headerLower)) {
return;
}
return originalXHRSetRequestHeader.call(this, header, value);
};
const originalFetch = window.fetch;
window.fetch = function(resource, init) {
init = init || {};
init.headers = init.headers || {};
if (init.headers instanceof Headers) {
const headersObj = {};
for (const [key, value] of init.headers.entries()) {
headersObj[key] = value;
}
init.headers = headersObj;
}
const blockedHeaders = [
'sec-ch-ua-model',
'sec-ch-ua-platform-version',
'sec-ch-ua-full-version-list',
'sec-ch-ua-arch',
'sec-ch-ua-bitness',
'sec-ch-ua-wow64',
'sec-ch-device-memory',
'sec-ch-dpr',
'sec-ch-viewport-width',
'sec-ch-viewport-height'
];
for (const header of blockedHeaders) {
delete init.headers[header];
delete init.headers[header.toLowerCase()];
}
return originalFetch.apply(this, [resource, init]);
};
const originalFunctionToString = Function.prototype.toString;
const originalToStringString = originalFunctionToString.toString();
Function.prototype.toString = new Proxy(originalFunctionToString, {
apply(target, thisArg, args) {
const modifiedFunctions = [
HTMLCanvasElement.prototype.toDataURL,
HTMLCanvasElement.prototype.toBlob,
CanvasRenderingContext2D.prototype.getImageData,
WebGLRenderingContext.prototype.getParameter,
navigator.getBattery,
EventTarget.prototype.addEventListener,
Function.prototype.toString,
XMLHttpRequest.prototype.setRequestHeader,
window.fetch
];
if (modifiedFunctions.includes(thisArg)) {
return 'function () { [native code] }';
}
if (thisArg === Function.prototype.toString) {
return originalToStringString;
}
return target.apply(thisArg, args);
}
});
const OriginalProxy = window.Proxy;
window.Proxy = new OriginalProxy(OriginalProxy, {
construct(target, args) {
const proxy = new target(...args);
try {
proxy.toString = function() { return '[object Object]'; };
} catch(e) {}
return proxy;
}
});
const originalDefineProperty = Object.defineProperty;
Object.defineProperty = new OriginalProxy(originalDefineProperty, {
apply(target, thisArg, args) {
return target.apply(thisArg, args);
}
});
const originalGetOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
Object.getOwnPropertyDescriptor = new OriginalProxy(originalGetOwnPropertyDescriptor, {
apply(target, thisArg, args) {
const descriptor = target.apply(thisArg, args);
if (descriptor && descriptor.get) {
descriptor.get.toString = function() { return 'function get() { [native code] }'; };
}
if (descriptor && descriptor.set) {
descriptor.set.toString = function() { return 'function set() { [native code] }'; };
}
return descriptor;
}
});
const windowWidth = Math.floor(CONFIG.screen.width / CONFIG.screen.density);
const windowHeight = randomInt(700, 900);
Object.defineProperty(window, 'innerWidth', {
get: () => windowWidth,
configurable: true
});
Object.defineProperty(window, 'innerHeight', {
get: () => windowHeight,
configurable: true
});
Object.defineProperty(window, 'outerWidth', {
get: () => windowWidth + randomInt(0, 2),
configurable: true
});
Object.defineProperty(window, 'outerHeight', {
get: () => windowHeight + randomInt(0, 2),
configurable: true
});
if (window.performance && window.performance.timing) {
const now = Date.now();
const navigationStart = now - randomInt(100, 500);
Object.defineProperty(performance.timing, 'navigationStart', {
get: () => navigationStart,
configurable: true
});
Object.defineProperty(performance.timing, 'fetchStart', {
get: () => navigationStart + randomInt(1, 10),
configurable: true
});
Object.defineProperty(performance.timing, 'domainLookupStart', {
get: () => navigationStart + randomInt(1, 10),
configurable: true
});
Object.defineProperty(performance.timing, 'domainLookupEnd', {
get: () => navigationStart + randomInt(10, 20),
configurable: true
});
Object.defineProperty(performance.timing, 'connectStart', {
get: () => navigationStart + randomInt(10, 20),
configurable: true
});
Object.defineProperty(performance.timing, 'connectEnd', {
get: () => navigationStart + randomInt(20, 40),
configurable: true
});
Object.defineProperty(performance.timing, 'requestStart', {
get: () => navigationStart + randomInt(40, 60),
configurable: true
});
Object.defineProperty(performance.timing, 'responseStart', {
get: () => navigationStart + randomInt(60, 100),
configurable: true
});
Object.defineProperty(performance.timing, 'responseEnd', {
get: () => navigationStart + randomInt(100, 150),
configurable: true
});
Object.defineProperty(performance.timing, 'domLoading', {
get: () => navigationStart + randomInt(100, 150),
configurable: true
});
Object.defineProperty(performance.timing, 'domInteractive', {
get: () => navigationStart + randomInt(150, 250),
configurable: true
});
Object.defineProperty(performance.timing, 'domContentLoadedEventStart', {
get: () => navigationStart + randomInt(250, 350),
configurable: true
});
Object.defineProperty(performance.timing, 'domContentLoadedEventEnd', {
get: () => navigationStart + randomInt(350, 400),
configurable: true
});
Object.defineProperty(performance.timing, 'domComplete', {
get: () => navigationStart + randomInt(400, 500),
configurable: true
});
Object.defineProperty(performance.timing, 'loadEventStart', {
get: () => navigationStart + randomInt(400, 500),
configurable: true
});
Object.defineProperty(performance.timing, 'loadEventEnd', {
get: () => navigationStart + randomInt(500, 600),
configurable: true
});
}
Object.defineProperty(navigator, 'platform', {
get: () => 'Linux aarch64',
configurable: true
});
Object.defineProperty(navigator, 'vendor', {
get: () => 'Google Inc.',
configurable: true
});
Object.defineProperty(navigator, 'vendorSub', {
get: () => '',
configurable: true
});
Object.defineProperty(navigator, 'productSub', {
get: () => '20030107',
configurable: true
});
Object.defineProperty(navigator, 'appCodeName', {
get: () => 'Mozilla',
configurable: true
});
Object.defineProperty(navigator, 'appName', {
get: () => 'Netscape',
configurable: true
});
Object.defineProperty(navigator, 'product', {
get: () => 'Gecko',
configurable: true
});
const languages = ['zh-CN', 'en-US'];
Object.defineProperty(navigator, 'language', {
get: () => 'zh-CN',
configurable: true
});
Object.defineProperty(navigator, 'languages', {
get: () => languages,
configurable: true
});
})();
1 个赞
这就去试试
这就更新
抗阻指紋識別mini
谢谢大佬分享
大佬牛逼!
// ==UserScript==
// @name 安卓浏览器防检测脚本
// @namespace https://linux.do/t/topic/1131864
// @version 1.1
// @icon https://linux-do.deno.dev/user_avatar/linux.do/f-droid/288/228666_2.png
// @description 🎉 全网首个安卓浏览器防检测脚本 | X浏览器·Edge浏览器 | 指纹防护·隐私保护
// @match *://*/*
// @run-at document-start
// @grant none
// ==/UserScript==
(function() {
'use strict';
const ANDROID_DEVICES = [
{ brand: 'OPPO', model: 'PGJM10', name: 'OPPO Find X5 Pro' },
{ brand: 'OPPO', model: 'PGBM10', name: 'OPPO Find X5' },
{ brand: 'OPPO', model: 'PHM110', name: 'OPPO Find N2' },
{ brand: 'OPPO', model: 'CPH2451', name: 'OPPO Reno10 Pro+' },
{ brand: 'OPPO', model: 'CPH2413', name: 'OPPO Reno9 Pro+' },
{ brand: 'OPPO', model: 'PFTM10', name: 'OPPO Find X6 Pro' },
{ brand: 'OPPO', model: 'CPH2525', name: 'OPPO Find X7 Ultra' },
{ brand: 'vivo', model: 'V2227A', name: 'vivo X90 Pro+' },
{ brand: 'vivo', model: 'V2229A', name: 'vivo X90 Pro' },
{ brand: 'vivo', model: 'V2231A', name: 'vivo X90' },
{ brand: 'vivo', model: 'V2285A', name: 'vivo X100 Pro' },
{ brand: 'vivo', model: 'V2309A', name: 'vivo S17 Pro' },
{ brand: 'vivo', model: 'V2199A', name: 'vivo X Fold+' },
{ brand: 'vivo', model: 'V2324A', name: 'vivo X100 Ultra' },
{ brand: 'Xiaomi', model: '2211133C', name: 'Xiaomi 13 Pro' },
{ brand: 'Xiaomi', model: '2210132C', name: 'Xiaomi 13' },
{ brand: 'Xiaomi', model: '2304FPN6DC', name: 'Xiaomi 13 Ultra' },
{ brand: 'Xiaomi', model: '23078PND5C', name: 'Xiaomi 14 Pro' },
{ brand: 'Xiaomi', model: '23127PN0CC', name: 'Xiaomi 14' },
{ brand: 'Xiaomi', model: '2211133G', name: 'Xiaomi MIX Fold 3' },
{ brand: 'Xiaomi', model: '24031PN0DC', name: 'Xiaomi 14 Ultra' },
{ brand: 'Redmi', model: '23013RK75C', name: 'Redmi K60 Pro' },
{ brand: 'Redmi', model: '22127RK46C', name: 'Redmi K60' },
{ brand: 'Redmi', model: '23078RKD5C', name: 'Redmi K60 Ultra' },
{ brand: 'Redmi', model: '23090RA98C', name: 'Redmi K70 Pro' },
{ brand: 'Redmi', model: '2312DRA50C', name: 'Redmi Note 13 Pro+' },
{ brand: 'Redmi', model: '23117RK66C', name: 'Redmi K70' },
{ brand: 'realme', model: 'RMX3708', name: 'realme GT5 Pro' },
{ brand: 'realme', model: 'RMX3706', name: 'realme GT5' },
{ brand: 'realme', model: 'RMX3663', name: 'realme GT Neo5' },
{ brand: 'realme', model: 'RMX3710', name: 'realme GT Neo6' },
{ brand: 'realme', model: 'RMX3031', name: 'realme GT2 Pro' },
{ brand: 'realme', model: 'RMX3700', name: 'realme GT3' },
{ brand: 'Google', model: 'Pixel 7 Pro', name: 'Pixel 7 Pro' },
{ brand: 'Google', model: 'Pixel 7', name: 'Pixel 7' },
{ brand: 'Google', model: 'Pixel 8 Pro', name: 'Pixel 8 Pro' },
{ brand: 'Google', model: 'Pixel 8', name: 'Pixel 8' },
{ brand: 'Google', model: 'Pixel Fold', name: 'Pixel Fold' },
{ brand: 'Google', model: 'Pixel 8a', name: 'Pixel 8a' },
{ brand: 'HONOR', model: 'PGT-AN10', name: 'HONOR Magic5 Pro' },
{ brand: 'HONOR', model: 'PGT-AN20', name: 'HONOR Magic5' },
{ brand: 'HONOR', model: 'LGE-AN00', name: 'HONOR Magic6 Pro' },
{ brand: 'HONOR', model: 'BVL-AN16', name: 'HONOR Magic V2' },
{ brand: 'HONOR', model: 'LRA-AN00', name: 'HONOR Magic6' },
{ brand: 'OnePlus', model: 'PHB110', name: 'OnePlus 11' },
{ brand: 'OnePlus', model: 'PJD110', name: 'OnePlus 12' },
{ brand: 'OnePlus', model: 'CPH2449', name: 'OnePlus Ace 2 Pro' },
{ brand: 'OnePlus', model: 'CPH2581', name: 'OnePlus Ace 3 Pro' },
{ brand: 'Samsung', model: 'SM-S9180', name: 'Samsung Galaxy S23 Ultra' },
{ brand: 'Samsung', model: 'SM-S9110', name: 'Samsung Galaxy S23+' },
{ brand: 'Samsung', model: 'SM-S9280', name: 'Samsung Galaxy S24 Ultra' },
{ brand: 'Samsung', model: 'SM-F9460', name: 'Samsung Galaxy Z Fold5' },
];
const GPU_DATABASE = [
{ soc: 'Snapdragon 778G', gpu: 'Adreno 642L', cores: 8, vendor: 'Qualcomm' },
{ soc: 'Snapdragon 780G', gpu: 'Adreno 642', cores: 8, vendor: 'Qualcomm' },
{ soc: 'Snapdragon 782G', gpu: 'Adreno 642L', cores: 8, vendor: 'Qualcomm' },
{ soc: 'Snapdragon 7+ Gen 2', gpu: 'Adreno 725', cores: 8, vendor: 'Qualcomm' },
{ soc: 'Snapdragon 7 Gen 3', gpu: 'Adreno 720', cores: 8, vendor: 'Qualcomm' },
{ soc: 'Snapdragon 888', gpu: 'Adreno 660', cores: 8, vendor: 'Qualcomm' },
{ soc: 'Snapdragon 888+', gpu: 'Adreno 660', cores: 8, vendor: 'Qualcomm' },
{ soc: 'Snapdragon 8 Gen 1', gpu: 'Adreno 730', cores: 8, vendor: 'Qualcomm' },
{ soc: 'Snapdragon 8+ Gen 1', gpu: 'Adreno 730', cores: 8, vendor: 'Qualcomm' },
{ soc: 'Snapdragon 8 Gen 2', gpu: 'Adreno 740', cores: 8, vendor: 'Qualcomm' },
{ soc: 'Snapdragon 8 Gen 3', gpu: 'Adreno 750', cores: 8, vendor: 'Qualcomm' },
{ soc: 'Dimensity 8100', gpu: 'Mali-G610 MC6', cores: 8, vendor: 'ARM' },
{ soc: 'Dimensity 8200', gpu: 'Mali-G610 MC6', cores: 8, vendor: 'ARM' },
{ soc: 'Dimensity 8300', gpu: 'Mali-G615 MC6', cores: 8, vendor: 'ARM' },
{ soc: 'Dimensity 9000', gpu: 'Mali-G710 MC10', cores: 8, vendor: 'ARM' },
{ soc: 'Dimensity 9000+', gpu: 'Mali-G710 MC10', cores: 8, vendor: 'ARM' },
{ soc: 'Dimensity 9200', gpu: 'Mali-G715 MC11', cores: 8, vendor: 'ARM' },
{ soc: 'Dimensity 9200+', gpu: 'Mali-G715 MC11', cores: 8, vendor: 'ARM' },
{ soc: 'Dimensity 9300', gpu: 'Mali-G720 MC12', cores: 8, vendor: 'ARM' },
{ soc: 'Exynos 2200', gpu: 'Xclipse 920', cores: 8, vendor: 'Samsung' },
{ soc: 'Exynos 2400', gpu: 'Xclipse 940', cores: 8, vendor: 'Samsung' },
{ soc: 'Google Tensor G2', gpu: 'Mali-G710 MC10', cores: 8, vendor: 'ARM' },
{ soc: 'Google Tensor G3', gpu: 'Mali-G715 MC10', cores: 8, vendor: 'ARM' },
];
const SCREEN_RESOLUTIONS = [
{ width: 1080, height: 2340, density: 2.5 },
{ width: 1080, height: 2400, density: 2.625 },
{ width: 1080, height: 2412, density: 2.75 },
{ width: 1080, height: 2460, density: 2.8 },
{ width: 1200, height: 2670, density: 3.0 },
{ width: 1220, height: 2712, density: 3.0 },
{ width: 1260, height: 2800, density: 3.0 },
{ width: 1440, height: 3120, density: 3.5 },
{ width: 1440, height: 3200, density: 3.5 },
{ width: 1440, height: 3216, density: 3.5 },
{ width: 1440, height: 3088, density: 3.5 },
];
function randomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function randomFloat(min, max, decimals = 2) {
return parseFloat((Math.random() * (max - min) + min).toFixed(decimals));
}
function randomChoice(array) {
return array[randomInt(0, array.length - 1)];
}
const CONFIG = {
device: randomChoice(ANDROID_DEVICES),
gpu: randomChoice(GPU_DATABASE),
screen: randomChoice(SCREEN_RESOLUTIONS),
memory: randomChoice([6, 8, 12, 16, 18, 24]),
battery: {
level: randomFloat(0.20, 0.95, 2),
charging: Math.random() > 0.7
},
network: {
type: randomChoice(['4g', '5g']),
downlink: randomFloat(5, 100, 1),
rtt: randomInt(20, 150)
},
androidVersion: randomInt(12, 14),
canvasSeed: Math.random() * 100000,
audioSeed: Math.random() * 100000,
deviceId: Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15)
};
// ========== 第一步:清除所有缓存的指纹数据 ==========
function clearFingerprintCache() {
try {
// 清除 localStorage 中的指纹相关数据
const fingerprintKeys = [];
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
if (key && (
key.includes('fingerprint') ||
key.includes('canvas') ||
key.includes('webgl') ||
key.includes('audio') ||
key.includes('device') ||
key.includes('browser') ||
key.includes('visitor') ||
key.includes('client') ||
key.includes('user_id') ||
key.includes('session') ||
key.includes('tracking') ||
key.includes('analytics') ||
key.includes('_fp') ||
key.includes('_id')
)) {
fingerprintKeys.push(key);
}
}
fingerprintKeys.forEach(key => {
try {
localStorage.removeItem(key);
} catch(e) {}
});
// 清除 sessionStorage 中的指纹相关数据
const sessionKeys = [];
for (let i = 0; i < sessionStorage.length; i++) {
const key = sessionStorage.key(i);
if (key && (
key.includes('fingerprint') ||
key.includes('canvas') ||
key.includes('webgl') ||
key.includes('audio') ||
key.includes('device') ||
key.includes('browser') ||
key.includes('visitor') ||
key.includes('client') ||
key.includes('user_id') ||
key.includes('session') ||
key.includes('tracking') ||
key.includes('analytics') ||
key.includes('_fp') ||
key.includes('_id')
)) {
sessionKeys.push(key);
}
}
sessionKeys.forEach(key => {
try {
sessionStorage.removeItem(key);
} catch(e) {}
});
// 清除 IndexedDB
if (window.indexedDB) {
try {
indexedDB.databases().then(databases => {
databases.forEach(db => {
if (db.name && (
db.name.includes('fingerprint') ||
db.name.includes('tracking') ||
db.name.includes('analytics')
)) {
indexedDB.deleteDatabase(db.name);
}
});
}).catch(() => {});
} catch(e) {}
}
console.log('🧹 已清除缓存的指纹数据');
} catch(e) {
console.log('⚠️ 清除缓存时出错:', e);
}
}
// 立即清除缓存
clearFingerprintCache();
// 页面加载完成后再次清除
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', clearFingerprintCache);
}
window.addEventListener('load', clearFingerprintCache);
// 拦截 localStorage 和 sessionStorage 的写入
const originalSetItem = Storage.prototype.setItem;
Storage.prototype.setItem = function(key, value) {
if (key && (
key.includes('fingerprint') ||
key.includes('canvas') ||
key.includes('webgl') ||
key.includes('audio') ||
key.includes('_fp') ||
key.includes('visitor_id') ||
key.includes('client_id')
)) {
console.log('🚫 阻止写入指纹数据:', key);
return;
}
return originalSetItem.call(this, key, value);
};
// ========== 第二步:覆盖品牌信息(不是过滤) ==========
const fakeBrands = [
{ brand: "Microsoft Edge", version: "141" },
{ brand: "Chromium", version: "141" },
{ brand: "Not=A?Brand", version: "24" }
];
const fakeUserAgentData = {
brands: fakeBrands,
mobile: true,
platform: 'Android',
getHighEntropyValues: (hints) => Promise.resolve({
architecture: 'arm',
bitness: '64',
brands: fakeBrands,
fullVersionList: fakeBrands,
mobile: true,
model: CONFIG.device.model,
platform: 'Android',
platformVersion: CONFIG.androidVersion.toString(),
uaFullVersion: '141.0.0.0',
wow64: false
}),
toJSON: () => ({ brands: fakeBrands, mobile: true, platform: 'Android' })
};
Object.defineProperty(navigator, 'userAgentData', {
get: () => fakeUserAgentData,
set: () => {},
configurable: false,
enumerable: true
});
// ========== WebRTC 禁用 ==========
const DisabledRTCPeerConnection = function() {
throw new DOMException('WebRTC is disabled', 'NotSupportedError');
};
DisabledRTCPeerConnection.prototype = {
constructor: DisabledRTCPeerConnection,
createOffer: function() {
return Promise.reject(new DOMException('WebRTC is disabled', 'NotSupportedError'));
},
createAnswer: function() {
return Promise.reject(new DOMException('WebRTC is disabled', 'NotSupportedError'));
},
setLocalDescription: function() {
return Promise.reject(new DOMException('WebRTC is disabled', 'NotSupportedError'));
},
setRemoteDescription: function() {
return Promise.reject(new DOMException('WebRTC is disabled', 'NotSupportedError'));
},
addIceCandidate: function() {
return Promise.reject(new DOMException('WebRTC is disabled', 'NotSupportedError'));
},
close: function() {},
addEventListener: function() {},
removeEventListener: function() {}
};
Object.defineProperty(window, 'RTCPeerConnection', {
value: DisabledRTCPeerConnection,
writable: false,
configurable: false
});
Object.defineProperty(window, 'webkitRTCPeerConnection', {
value: DisabledRTCPeerConnection,
writable: false,
configurable: false
});
Object.defineProperty(window, 'mozRTCPeerConnection', {
value: DisabledRTCPeerConnection,
writable: false,
configurable: false
});
const DisabledRTCSessionDescription = function() {
throw new DOMException('WebRTC is disabled', 'NotSupportedError');
};
Object.defineProperty(window, 'RTCSessionDescription', {
value: DisabledRTCSessionDescription,
writable: false,
configurable: false
});
const DisabledRTCIceCandidate = function() {
throw new DOMException('WebRTC is disabled', 'NotSupportedError');
};
Object.defineProperty(window, 'RTCIceCandidate', {
value: DisabledRTCIceCandidate,
writable: false,
configurable: false
});
// ========== Canvas 指纹随机化 ==========
const originalToDataURL = HTMLCanvasElement.prototype.toDataURL;
const originalToBlob = HTMLCanvasElement.prototype.toBlob;
const originalGetImageData = CanvasRenderingContext2D.prototype.getImageData;
function addCanvasNoise(imageData, seed) {
const data = imageData.data;
for (let i = 0; i < data.length; i += 4) {
const noise = (Math.sin(seed + i * 0.01) * Math.cos(seed + i * 0.02)) * 3;
data[i] = Math.min(255, Math.max(0, data[i] + noise));
data[i + 1] = Math.min(255, Math.max(0, data[i + 1] + noise));
data[i + 2] = Math.min(255, Math.max(0, data[i + 2] + noise));
}
return imageData;
}
HTMLCanvasElement.prototype.toDataURL = function(...args) {
const context = this.getContext('2d');
if (context && this.width > 0 && this.height > 0) {
try {
const imageData = context.getImageData(0, 0, this.width, this.height);
const noisyData = addCanvasNoise(imageData, CONFIG.canvasSeed);
context.putImageData(noisyData, 0, 0);
} catch(e) {}
}
return originalToDataURL.apply(this, args);
};
HTMLCanvasElement.prototype.toBlob = function(...args) {
const context = this.getContext('2d');
if (context && this.width > 0 && this.height > 0) {
try {
const imageData = context.getImageData(0, 0, this.width, this.height);
const noisyData = addCanvasNoise(imageData, CONFIG.canvasSeed);
context.putImageData(noisyData, 0, 0);
} catch(e) {}
}
return originalToBlob.apply(this, args);
};
CanvasRenderingContext2D.prototype.getImageData = function(...args) {
const imageData = originalGetImageData.apply(this, args);
return addCanvasNoise(imageData, CONFIG.canvasSeed);
};
// ========== 音频指纹随机化 ==========
if (typeof AudioContext !== 'undefined' || typeof webkitAudioContext !== 'undefined') {
const AudioContextConstructor = window.AudioContext || window.webkitAudioContext;
const OriginalAudioContext = AudioContextConstructor;
window.AudioContext = window.webkitAudioContext = function() {
const context = new OriginalAudioContext();
const originalCreateOscillator = context.createOscillator.bind(context);
context.createOscillator = function() {
const oscillator = originalCreateOscillator();
const originalFrequency = oscillator.frequency;
const noise = (Math.sin(CONFIG.audioSeed) + Math.cos(CONFIG.audioSeed * 0.5)) * 0.1;
Object.defineProperty(oscillator, 'frequency', {
get: () => {
const freq = originalFrequency;
return new Proxy(freq, {
get(target, prop) {
if (prop === 'value') {
return target.value + noise;
}
if (prop === 'setValueAtTime') {
return function(value, time) {
return target.setValueAtTime(value + noise, time);
};
}
return target[prop];
}
});
},
configurable: true
});
return oscillator;
};
const originalCreateDynamicsCompressor = context.createDynamicsCompressor.bind(context);
context.createDynamicsCompressor = function() {
const compressor = originalCreateDynamicsCompressor();
const noise = (Math.sin(CONFIG.audioSeed) + Math.cos(CONFIG.audioSeed * 0.7)) * 0.1;
['threshold', 'knee', 'ratio', 'attack', 'release'].forEach(param => {
const original = compressor[param];
Object.defineProperty(compressor, param, {
get: () => {
return new Proxy(original, {
get(target, prop) {
if (prop === 'value') {
return target.value + noise;
}
if (prop === 'setValueAtTime') {
return function(value, time) {
return target.setValueAtTime(value + noise, time);
};
}
return target[prop];
}
});
},
configurable: true
});
});
return compressor;
};
const originalCreateAnalyser = context.createAnalyser.bind(context);
context.createAnalyser = function() {
const analyser = originalCreateAnalyser();
const originalGetFloatFrequencyData = analyser.getFloatFrequencyData.bind(analyser);
analyser.getFloatFrequencyData = function(array) {
originalGetFloatFrequencyData(array);
for (let i = 0; i < array.length; i++) {
const noise = (Math.sin(CONFIG.audioSeed + i * 0.1) + Math.cos(CONFIG.audioSeed + i * 0.2)) * 0.5;
array[i] += noise;
}
};
const originalGetByteFrequencyData = analyser.getByteFrequencyData.bind(analyser);
analyser.getByteFrequencyData = function(array) {
originalGetByteFrequencyData(array);
for (let i = 0; i < array.length; i++) {
const noise = Math.sin(CONFIG.audioSeed + i) * 2;
array[i] = Math.min(255, Math.max(0, array[i] + noise));
}
};
const originalGetFloatTimeDomainData = analyser.getFloatTimeDomainData.bind(analyser);
analyser.getFloatTimeDomainData = function(array) {
originalGetFloatTimeDomainData(array);
for (let i = 0; i < array.length; i++) {
const noise = Math.sin(CONFIG.audioSeed + i) * 0.01;
array[i] += noise;
}
};
const originalGetByteTimeDomainData = analyser.getByteTimeDomainData.bind(analyser);
analyser.getByteTimeDomainData = function(array) {
originalGetByteTimeDomainData(array);
for (let i = 0; i < array.length; i++) {
const noise = Math.sin(CONFIG.audioSeed + i) * 2;
array[i] = Math.min(255, Math.max(0, array[i] + noise));
}
};
return analyser;
};
return context;
};
window.AudioContext.prototype = OriginalAudioContext.prototype;
if (window.webkitAudioContext) {
window.webkitAudioContext.prototype = OriginalAudioContext.prototype;
}
}
// ========== 屏幕信息 ==========
Object.defineProperty(screen, 'width', {
get: () => CONFIG.screen.width,
configurable: false,
enumerable: true
});
Object.defineProperty(screen, 'height', {
get: () => CONFIG.screen.height,
configurable: false,
enumerable: true
});
Object.defineProperty(screen, 'availWidth', {
get: () => CONFIG.screen.width,
configurable: false,
enumerable: true
});
Object.defineProperty(screen, 'availHeight', {
get: () => CONFIG.screen.height - 80,
configurable: false,
enumerable: true
});
Object.defineProperty(screen, 'colorDepth', {
get: () => 24,
configurable: false,
enumerable: true
});
Object.defineProperty(screen, 'pixelDepth', {
get: () => 24,
configurable: false,
enumerable: true
});
Object.defineProperty(window, 'devicePixelRatio', {
get: () => CONFIG.screen.density,
configurable: false,
enumerable: true
});
Object.defineProperty(navigator, 'hardwareConcurrency', {
get: () => CONFIG.gpu.cores,
configurable: false,
enumerable: true
});
Object.defineProperty(navigator, 'deviceMemory', {
get: () => CONFIG.memory,
configurable: false,
enumerable: true
});
Object.defineProperty(navigator, 'maxTouchPoints', {
get: () => 5,
configurable: false,
enumerable: true
});
// ========== 内存信息 ==========
if (performance.memory) {
const memorySize = CONFIG.memory * 1024 * 1024 * 1024;
Object.defineProperty(performance, 'memory', {
get: () => ({
jsHeapSizeLimit: memorySize,
totalJSHeapSize: Math.floor(memorySize * randomFloat(0.25, 0.35)),
usedJSHeapSize: Math.floor(memorySize * randomFloat(0.15, 0.25))
}),
configurable: false,
enumerable: true
});
}
if (navigator.storage && navigator.storage.estimate) {
const originalEstimate = navigator.storage.estimate.bind(navigator.storage);
navigator.storage.estimate = function() {
const quota = CONFIG.memory * randomInt(14, 18) * 1024 * 1024 * 1024;
return Promise.resolve({
quota: quota,
usage: Math.floor(quota * randomFloat(0.001, 0.005)),
usageDetails: {}
});
};
}
// ========== WebGL 信息 ==========
const webglVendor = CONFIG.gpu.vendor;
const webglRenderer = CONFIG.gpu.gpu;
const originalGetParameter = WebGLRenderingContext.prototype.getParameter;
WebGLRenderingContext.prototype.getParameter = function(param) {
if (param === 37445) return webglVendor;
if (param === 37446) return webglRenderer;
if (param === 7936) return 'WebKit';
if (param === 7937) return 'WebKit WebGL';
return originalGetParameter.call(this, param);
};
if (typeof WebGL2RenderingContext !== 'undefined') {
const originalGetParameter2 = WebGL2RenderingContext.prototype.getParameter;
WebGL2RenderingContext.prototype.getParameter = function(param) {
if (param === 37445) return webglVendor;
if (param === 37446) return webglRenderer;
if (param === 7936) return 'WebKit';
if (param === 7937) return 'WebKit WebGL';
return originalGetParameter2.call(this, param);
};
}
// ========== 电池信息 ==========
const fakeBattery = {
charging: CONFIG.battery.charging,
chargingTime: CONFIG.battery.charging ? randomInt(1800, 7200) : Infinity,
dischargingTime: CONFIG.battery.charging ? Infinity : randomInt(10800, 28800),
level: CONFIG.battery.level,
addEventListener: () => {},
removeEventListener: () => {},
dispatchEvent: () => true,
onchargingchange: null,
onchargingtimechange: null,
ondischargingtimechange: null,
onlevelchange: null
};
Object.defineProperty(navigator, 'getBattery', {
value: () => Promise.resolve(fakeBattery),
configurable: false,
enumerable: true
});
// ========== 网络信息 ==========
const fakeConnection = {
effectiveType: CONFIG.network.type,
downlink: CONFIG.network.downlink,
rtt: CONFIG.network.rtt,
saveData: false,
type: 'wifi',
addEventListener: () => {},
removeEventListener: () => {},
dispatchEvent: () => true
};
Object.defineProperty(navigator, 'connection', {
get: () => fakeConnection,
configurable: false,
enumerable: true
});
Object.defineProperty(navigator, 'mozConnection', {
get: () => fakeConnection,
configurable: false,
enumerable: true
});
Object.defineProperty(navigator, 'webkitConnection', {
get: () => fakeConnection,
configurable: false,
enumerable: true
});
// ========== 完全禁用传感器 API ==========
delete window.DeviceMotionEvent;
delete window.DeviceOrientationEvent;
delete window.Gyroscope;
delete window.Accelerometer;
delete window.LinearAccelerationSensor;
delete window.GravitySensor;
delete window.Magnetometer;
delete window.AmbientLightSensor;
delete window.AbsoluteOrientationSensor;
delete window.RelativeOrientationSensor;
// 阻止传感器事件监听
const originalAddEventListener = EventTarget.prototype.addEventListener;
EventTarget.prototype.addEventListener = function(type, listener, options) {
const blockedEvents = [
'devicemotion',
'deviceorientation',
'deviceorientationabsolute',
'devicelight',
'deviceproximity',
'userproximity'
];
if (blockedEvents.includes(type.toLowerCase())) {
return;
}
return originalAddEventListener.call(this, type, listener, options);
};
Object.defineProperty(window, 'ondevicemotion', {
get: () => null,
set: () => {},
configurable: false,
enumerable: true
});
Object.defineProperty(window, 'ondeviceorientation', {
get: () => null,
set: () => {},
configurable: false,
enumerable: true
});
Object.defineProperty(window, 'ondeviceorientationabsolute', {
get: () => null,
set: () => {},
configurable: false,
enumerable: true
});
// ========== 媒体设备保护 ==========
if (navigator.mediaDevices) {
Object.defineProperty(navigator.mediaDevices, 'enumerateDevices', {
value: () => Promise.resolve([]),
writable: false,
configurable: false
});
Object.defineProperty(navigator.mediaDevices, 'getUserMedia', {
value: () => Promise.reject(new DOMException('Permission denied', 'NotAllowedError')),
writable: false,
configurable: false
});
Object.defineProperty(navigator.mediaDevices, 'getDisplayMedia', {
value: () => Promise.reject(new DOMException('Permission denied', 'NotAllowedError')),
writable: false,
configurable: false
});
}
Object.defineProperty(navigator, 'getUserMedia', {
value: (constraints, success, error) => {
if (error) error(new DOMException('Permission denied', 'NotAllowedError'));
},
writable: false,
configurable: false
});
Object.defineProperty(navigator, 'webkitGetUserMedia', {
value: (constraints, success, error) => {
if (error) error(new DOMException('Permission denied', 'NotAllowedError'));
},
writable: false,
configurable: false
});
Object.defineProperty(navigator, 'mozGetUserMedia', {
value: (constraints, success, error) => {
if (error) error(new DOMException('Permission denied', 'NotAllowedError'));
},
writable: false,
configurable: false
});
// ========== 地理位置保护 ==========
if (navigator.geolocation) {
Object.defineProperty(navigator.geolocation, 'getCurrentPosition', {
value: (success, error) => {
if (error) error({ code: 1, message: 'User denied Geolocation' });
},
writable: false,
configurable: false
});
Object.defineProperty(navigator.geolocation, 'watchPosition', {
value: (success, error) => {
if (error) error({ code: 1, message: 'User denied Geolocation' });
return 0;
},
writable: false,
configurable: false
});
Object.defineProperty(navigator.geolocation, 'clearWatch', {
value: () => {},
writable: false,
configurable: false
});
}
// ========== 插件和 MIME 类型 ==========
Object.defineProperty(navigator, 'plugins', {
get: () => ({
length: 0,
item: () => null,
namedItem: () => null,
refresh: () => {},
[Symbol.iterator]: function* () {}
}),
configurable: false,
enumerable: true
});
Object.defineProperty(navigator, 'mimeTypes', {
get: () => ({
length: 0,
item: () => null,
namedItem: () => null,
[Symbol.iterator]: function* () {}
}),
configurable: false,
enumerable: true
});
// ========== 字体检测保护 ==========
if (document.fonts) {
document.fonts.check = function() { return false; };
document.fonts.load = function() { return Promise.resolve([]); };
Object.defineProperty(document.fonts, 'size', {
get: () => 0,
configurable: false,
enumerable: true
});
Object.defineProperty(document.fonts, 'ready', {
get: () => Promise.resolve(document.fonts),
configurable: false,
enumerable: true
});
Object.defineProperty(document.fonts, Symbol.iterator, {
value: function* () {},
writable: false,
configurable: false
});
document.fonts.forEach = function() {};
document.fonts.entries = function* () {};
document.fonts.values = function* () {};
document.fonts.keys = function* () {};
}
// ========== 通知 API ==========
if (window.Notification) {
Object.defineProperty(window, 'Notification', {
value: function() {
throw new Error('Notification is not supported');
},
writable: false,
configurable: false
});
Object.defineProperty(window.Notification, 'permission', {
get: () => 'denied',
configurable: false,
enumerable: true
});
}
// ========== 振动 API ==========
Object.defineProperty(navigator, 'vibrate', {
value: () => false,
writable: false,
configurable: false
});
// ========== 游戏手柄 API ==========
Object.defineProperty(navigator, 'getGamepads', {
value: () => [],
writable: false,
configurable: false
});
// ========== 蓝牙 API ==========
if (navigator.bluetooth) {
Object.defineProperty(navigator.bluetooth, 'requestDevice', {
value: () => Promise.reject(new Error('Bluetooth not available')),
writable: false,
configurable: false
});
Object.defineProperty(navigator.bluetooth, 'getAvailability', {
value: () => Promise.resolve(false),
writable: false,
configurable: false
});
}
// ========== USB API ==========
if (navigator.usb) {
Object.defineProperty(navigator.usb, 'requestDevice', {
value: () => Promise.reject(new Error('USB not available')),
writable: false,
configurable: false
});
Object.defineProperty(navigator.usb, 'getDevices', {
value: () => Promise.resolve([]),
writable: false,
configurable: false
});
}
// ========== NFC API ==========
delete window.NDEFReader;
// ========== 串口 API ==========
if (navigator.serial) {
Object.defineProperty(navigator.serial, 'requestPort', {
value: () => Promise.reject(new Error('Serial not available')),
writable: false,
configurable: false
});
Object.defineProperty(navigator.serial, 'getPorts', {
value: () => Promise.resolve([]),
writable: false,
configurable: false
});
}
// ========== HID API ==========
if (navigator.hid) {
Object.defineProperty(navigator.hid, 'requestDevice', {
value: () => Promise.reject(new Error('HID not available')),
writable: false,
configurable: false
});
Object.defineProperty(navigator.hid, 'getDevices', {
value: () => Promise.resolve([]),
writable: false,
configurable: false
});
}
// ========== 时区信息 ==========
const timezoneOffset = -480;
const originalGetTimezoneOffset = Date.prototype.getTimezoneOffset;
Date.prototype.getTimezoneOffset = function() {
return timezoneOffset;
};
const originalToString = Date.prototype.toString;
Date.prototype.toString = function() {
return originalToString.call(this).replace(/\(.*\)/, '(中国标准时间)');
};
const originalToTimeString = Date.prototype.toTimeString;
Date.prototype.toTimeString = function() {
return originalToTimeString.call(this).replace(/\(.*\)/, '(中国标准时间)');
};
if (window.Intl && window.Intl.DateTimeFormat) {
const OriginalDateTimeFormat = Intl.DateTimeFormat;
Intl.DateTimeFormat = function(locales, options) {
return new OriginalDateTimeFormat('zh-CN', options);
};
Intl.DateTimeFormat.prototype = OriginalDateTimeFormat.prototype;
Intl.DateTimeFormat.supportedLocalesOf = OriginalDateTimeFormat.supportedLocalesOf;
}
// ========== HTTP 请求头保护 ==========
const originalXHRSetRequestHeader = XMLHttpRequest.prototype.setRequestHeader;
XMLHttpRequest.prototype.setRequestHeader = function(header, value) {
const headerLower = header.toLowerCase();
const blockedHeaders = [
'sec-ch-ua-model',
'sec-ch-ua-platform-version',
'sec-ch-ua-full-version-list',
'sec-ch-ua-arch',
'sec-ch-ua-bitness',
'sec-ch-ua-wow64',
'sec-ch-device-memory',
'sec-ch-dpr',
'sec-ch-viewport-width',
'sec-ch-viewport-height',
'sec-ch-ua-mobile'
];
if (blockedHeaders.includes(headerLower)) {
return;
}
return originalXHRSetRequestHeader.call(this, header, value);
};
const originalFetch = window.fetch;
window.fetch = function(resource, init) {
init = init || {};
init.headers = init.headers || {};
if (init.headers instanceof Headers) {
const headersObj = {};
for (const [key, value] of init.headers.entries()) {
headersObj[key] = value;
}
init.headers = headersObj;
}
const blockedHeaders = [
'sec-ch-ua-model',
'sec-ch-ua-platform-version',
'sec-ch-ua-full-version-list',
'sec-ch-ua-arch',
'sec-ch-ua-bitness',
'sec-ch-ua-wow64',
'sec-ch-device-memory',
'sec-ch-dpr',
'sec-ch-viewport-width',
'sec-ch-viewport-height'
];
for (const header of blockedHeaders) {
delete init.headers[header];
delete init.headers[header.toLowerCase()];
}
return originalFetch.apply(this, [resource, init]);
};
// ========== 函数 toString 保护 ==========
const originalFunctionToString = Function.prototype.toString;
const originalToStringString = originalFunctionToString.toString();
Function.prototype.toString = new Proxy(originalFunctionToString, {
apply(target, thisArg, args) {
const modifiedFunctions = [
HTMLCanvasElement.prototype.toDataURL,
HTMLCanvasElement.prototype.toBlob,
CanvasRenderingContext2D.prototype.getImageData,
WebGLRenderingContext.prototype.getParameter,
navigator.getBattery,
EventTarget.prototype.addEventListener,
Function.prototype.toString,
XMLHttpRequest.prototype.setRequestHeader,
window.fetch,
Date.prototype.getTimezoneOffset,
Date.prototype.toString,
Date.prototype.toTimeString,
Storage.prototype.setItem
];
if (modifiedFunctions.includes(thisArg)) {
return 'function () { [native code] }';
}
if (thisArg === Function.prototype.toString) {
return originalToStringString;
}
return target.apply(thisArg, args);
}
});
// ========== Proxy 保护 ==========
const OriginalProxy = window.Proxy;
window.Proxy = new OriginalProxy(OriginalProxy, {
construct(target, args) {
const proxy = new target(...args);
try {
proxy.toString = function() { return '[object Object]'; };
} catch(e) {}
return proxy;
}
});
const originalDefineProperty = Object.defineProperty;
Object.defineProperty = new OriginalProxy(originalDefineProperty, {
apply(target, thisArg, args) {
return target.apply(thisArg, args);
}
});
const originalGetOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
Object.getOwnPropertyDescriptor = new OriginalProxy(originalGetOwnPropertyDescriptor, {
apply(target, thisArg, args) {
const descriptor = target.apply(thisArg, args);
if (descriptor && descriptor.get) {
descriptor.get.toString = function() { return 'function get() { [native code] }'; };
}
if (descriptor && descriptor.set) {
descriptor.set.toString = function() { return 'function set() { [native code] }'; };
}
return descriptor;
}
});
// ========== 窗口尺寸 ==========
const windowWidth = Math.floor(CONFIG.screen.width / CONFIG.screen.density);
const windowHeight = randomInt(700, 900);
Object.defineProperty(window, 'innerWidth', {
get: () => windowWidth,
configurable: false,
enumerable: true
});
Object.defineProperty(window, 'innerHeight', {
get: () => windowHeight,
configurable: false,
enumerable: true
});
Object.defineProperty(window, 'outerWidth', {
get: () => windowWidth + randomInt(0, 2),
configurable: false,
enumerable: true
});
Object.defineProperty(window, 'outerHeight', {
get: () => windowHeight + randomInt(0, 2),
configurable: false,
enumerable: true
});
// ========== Performance Timing ==========
if (window.performance && window.performance.timing) {
const now = Date.now();
const navigationStart = now - randomInt(100, 500);
Object.defineProperty(performance.timing, 'navigationStart', {
get: () => navigationStart,
configurable: false,
enumerable: true
});
Object.defineProperty(performance.timing, 'fetchStart', {
get: () => navigationStart + randomInt(1, 10),
configurable: false,
enumerable: true
});
Object.defineProperty(performance.timing, 'domainLookupStart', {
get: () => navigationStart + randomInt(1, 10),
configurable: false,
enumerable: true
});
Object.defineProperty(performance.timing, 'domainLookupEnd', {
get: () => navigationStart + randomInt(10, 20),
configurable: false,
enumerable: true
});
Object.defineProperty(performance.timing, 'connectStart', {
get: () => navigationStart + randomInt(10, 20),
configurable: false,
enumerable: true
});
Object.defineProperty(performance.timing, 'connectEnd', {
get: () => navigationStart + randomInt(20, 40),
configurable: false,
enumerable: true
});
Object.defineProperty(performance.timing, 'requestStart', {
get: () => navigationStart + randomInt(40, 60),
configurable: false,
enumerable: true
});
Object.defineProperty(performance.timing, 'responseStart', {
get: () => navigationStart + randomInt(60, 100),
configurable: false,
enumerable: true
});
Object.defineProperty(performance.timing, 'responseEnd', {
get: () => navigationStart + randomInt(100, 150),
configurable: false,
enumerable: true
});
Object.defineProperty(performance.timing, 'domLoading', {
get: () => navigationStart + randomInt(100, 150),
configurable: false,
enumerable: true
});
Object.defineProperty(performance.timing, 'domInteractive', {
get: () => navigationStart + randomInt(150, 250),
configurable: false,
enumerable: true
});
Object.defineProperty(performance.timing, 'domContentLoadedEventStart', {
get: () => navigationStart + randomInt(250, 350),
configurable: false,
enumerable: true
});
Object.defineProperty(performance.timing, 'domContentLoadedEventEnd', {
get: () => navigationStart + randomInt(350, 400),
configurable: false,
enumerable: true
});
Object.defineProperty(performance.timing, 'domComplete', {
get: () => navigationStart + randomInt(400, 500),
configurable: false,
enumerable: true
});
Object.defineProperty(performance.timing, 'loadEventStart', {
get: () => navigationStart + randomInt(400, 500),
configurable: false,
enumerable: true
});
Object.defineProperty(performance.timing, 'loadEventEnd', {
get: () => navigationStart + randomInt(500, 600),
configurable: false,
enumerable: true
});
}
// ========== Navigator 属性 ==========
Object.defineProperty(navigator, 'platform', {
get: () => 'Linux aarch64',
configurable: false,
enumerable: true
});
Object.defineProperty(navigator, 'vendor', {
get: () => 'Google Inc.',
configurable: false,
enumerable: true
});
Object.defineProperty(navigator, 'vendorSub', {
get: () => '',
configurable: false,
enumerable: true
});
Object.defineProperty(navigator, 'productSub', {
get: () => '20030107',
configurable: false,
enumerable: true
});
Object.defineProperty(navigator, 'appCodeName', {
get: () => 'Mozilla',
configurable: false,
enumerable: true
});
Object.defineProperty(navigator, 'appName', {
get: () => 'Netscape',
configurable: false,
enumerable: true
});
Object.defineProperty(navigator, 'product', {
get: () => 'Gecko',
configurable: false,
enumerable: true
});
const languages = ['zh-CN', 'en-US'];
Object.defineProperty(navigator, 'language', {
get: () => 'zh-CN',
configurable: false,
enumerable: true
});
Object.defineProperty(navigator, 'languages', {
get: () => languages,
configurable: false,
enumerable: true
});
// ========== 持续监控 - 防止属性被重写 ==========
setInterval(() => {
try {
// 持续清除可能新增的指纹缓存
clearFingerprintCache();
// 检查并恢复关键属性
if (navigator.userAgentData && navigator.userAgentData.brands) {
const brands = navigator.userAgentData.brands;
const hasWebView = brands.some(b =>
b.brand.toLowerCase().includes('webview') ||
b.brand.toLowerCase().includes('android webview')
);
if (hasWebView) {
Object.defineProperty(navigator, 'userAgentData', {
get: () => fakeUserAgentData,
set: () => {},
configurable: false,
enumerable: true
});
}
}
} catch(e) {}
}, 100);
console.log('🛡️ 终极随机指纹防护已启用 (持续监控+缓存清除)');
console.log('📱 设备:', CONFIG.device.name);
console.log('🎮 GPU:', CONFIG.gpu.gpu);
console.log('📺 分辨率:', CONFIG.screen.width + 'x' + CONFIG.screen.height);
console.log('💾 内存:', CONFIG.memory + 'GB');
console.log('🔒 品牌信息:', fakeBrands.map(b => b.brand).join(', '));
console.log('🧹 已清除缓存的指纹数据');
})();
时隔一个星期,又更新了,这一次进一步增强了抗检测能力。
1 个赞
Edge Android浏览器可以通过添加篡改猴/脚本猫插件来实现抗检测脚本的安装。
2 个赞
来了来了!更新!
可以过亚马逊的检测吗佬
有被戳中
我也好奇,为啥都这么久了,还没有出现能完全模拟电脑端、带有电脑端功能的浏览器(模拟windows除外