Anti-Fingerprinting Shield Plus

Spoofs browser fingerprint data: canvas, WebGL, audio, language, timezone, userAgent, screen size, memory, and more. Spoofed values persist across tabs and expire after 30 minutes to simulate session behavior realistically. Top-frame only execution for stealth and compatibility.

当前为 2025-05-03 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Anti-Fingerprinting Shield Plus
// @namespace    https://365devnet.eu/userscripts
// @version      4.5
// @description  Spoofs browser fingerprint data: canvas, WebGL, audio, language, timezone, userAgent, screen size, memory, and more. Spoofed values persist across tabs and expire after 30 minutes to simulate session behavior realistically. Top-frame only execution for stealth and compatibility.
// @author       Richard B
// @match        *://*/*
// @run-at       document-start
// @grant        none
// @license      MIT
// ==/UserScript==

(function () {
  'use strict';

  if (window.top !== window.self) return;

  const DEBUG_MODE = true;
  const SESSION_TIMEOUT_MINUTES = 30;
  const sessionExpiryKey = '__afs_last_seen';
  const now = Date.now();

  const isExpired = () => {
    const lastSeen = parseInt(localStorage.getItem(sessionExpiryKey), 10);
    return isNaN(lastSeen) || now - lastSeen > SESSION_TIMEOUT_MINUTES * 60 * 1000;
  };

  if (isExpired()) {
    clearStoredSpoofedValues();
    if (DEBUG_MODE) console.log(`[AFS+] New session started (values expired after ${SESSION_TIMEOUT_MINUTES} minutes)`);
  }
  localStorage.setItem(sessionExpiryKey, now.toString());

  const sessionId = getOrCreatePersistent('__afs_session_id', () =>
    Math.random().toString(36).substring(2, 10)
  );

  if (DEBUG_MODE) console.log(`[AFS+] Anti-Fingerprinting Shield v4.5 started. Session ID: ${sessionId}`);

  const platforms = ['Win32', 'Linux x86_64', 'MacIntel', 'FreeBSD'];
  const languages = ['en-US', 'nl-NL', 'fr-FR', 'de-DE', 'sv-SE'];
  const timezones = ['UTC', 'Europe/Amsterdam', 'America/New_York', 'Asia/Tokyo'];
  const userAgents = [
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36',
    'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0 Safari/605.1.15',
    'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
  ];
  const cores = [2, 4, 6, 8];
  const memorySizes = [2, 4, 8];
  const screenWidths = [1920, 1680, 1366];
  const screenHeights = [1080, 1050, 768];

  const spoofed = {
    platform: getOrCreatePersistent('platform', () => pick(platforms)),
    language: getOrCreatePersistent('language', () => pick(languages)),
    languages: () => [spoofed.language, 'en'],
    timezone: getOrCreatePersistent('timezone', () => pick(timezones)),
    userAgent: getOrCreatePersistent('userAgent', () => pick(userAgents)),
    cores: parseInt(getOrCreatePersistent('cores', () => pick(cores))),
    memory: parseInt(getOrCreatePersistent('memory', () => pick(memorySizes))),
    screenWidth: parseInt(getOrCreatePersistent('screenWidth', () => pick(screenWidths))),
    screenHeight: parseInt(getOrCreatePersistent('screenHeight', () => pick(screenHeights))),
    vendor: 'SpoofedVendor',
    doNotTrack: Math.random() > 0.5 ? '1' : '0'
  };

  function pick(arr) {
    return arr[Math.floor(Math.random() * arr.length)];
  }

  function getOrCreatePersistent(key, generator) {
    const fullKey = '__afs_' + key;
    let value = localStorage.getItem(fullKey);
    if (!value) {
      value = generator();
      localStorage.setItem(fullKey, value);
    }
    return value;
  }

  function clearStoredSpoofedValues() {
    Object.keys(localStorage)
      .filter(key => key.startsWith('__afs_'))
      .forEach(key => localStorage.removeItem(key));
  }

  function spoof(obj, prop, valueFn) {
    try {
      Object.defineProperty(obj, prop, {
        get: valueFn,
        configurable: true
      });
    } catch (e) {}
  }

  spoof(navigator, 'language', () => spoofed.language);
  spoof(navigator, 'languages', () => spoofed.languages());
  spoof(navigator, 'platform', () => spoofed.platform);
  spoof(navigator, 'userAgent', () => spoofed.userAgent);
  spoof(navigator, 'hardwareConcurrency', () => spoofed.cores);
  spoof(navigator, 'deviceMemory', () => spoofed.memory);
  spoof(navigator, 'vendor', () => spoofed.vendor);
  spoof(navigator, 'doNotTrack', () => spoofed.doNotTrack);
  spoof(navigator, 'maxTouchPoints', () => 1);
  spoof(navigator, 'plugins', () => []);
  spoof(navigator, 'mimeTypes', () => ({ length: 0 }));
  spoof(navigator, 'mediaDevices', () => ({ enumerateDevices: () => Promise.resolve([]) }));
  spoof(navigator, 'webdriver', () => false);
  spoof(navigator, 'connection', () => ({ downlink: 10, effectiveType: '4g', rtt: 50, saveData: false }));
  spoof(navigator, 'mediaCapabilities', () => undefined);
  spoof(navigator, 'mediaSession', () => undefined);

  if (navigator.permissions && navigator.permissions.query) {
    const originalQuery = navigator.permissions.query;
    navigator.permissions.query = function (params) {
      if (params.name === 'notifications') {
        return Promise.resolve({ state: 'denied' });
      }
      return originalQuery.call(this, params);
    };
  }

  spoof(window.screen, 'width', () => spoofed.screenWidth);
  spoof(window.screen, 'height', () => spoofed.screenHeight);
  spoof(window, 'innerWidth', () => spoofed.screenWidth);
  spoof(window, 'innerHeight', () => spoofed.screenHeight - 40);

  try {
    const original = Intl.DateTimeFormat.prototype.resolvedOptions;
    Intl.DateTimeFormat.prototype.resolvedOptions = function () {
      const options = original.call(this);
      options.timeZone = spoofed.timezone;
      return options;
    };
  } catch (e) {}

  spoof(Date.prototype, 'getTimezoneOffset', () => {
    const offsetMap = { 'UTC': 0, 'Europe/Amsterdam': -120, 'America/New_York': 300, 'Asia/Tokyo': -540 };
    return offsetMap[spoofed.timezone] || 0;
  });

  const AudioContext = window.AudioContext || window.webkitAudioContext;
  if (AudioContext) {
    spoof(AudioContext.prototype, 'sampleRate', () => 44100);
    if (AnalyserNode.prototype.getFloatFrequencyData) {
      const original = AnalyserNode.prototype.getFloatFrequencyData;
      AnalyserNode.prototype.getFloatFrequencyData = function (arr) {
        original.call(this, arr);
        for (let i = 0; i < arr.length; i++) {
          arr[i] += Math.random() * 0.1;
        }
      };
    }
  }

  const originalGetImageData = CanvasRenderingContext2D.prototype.getImageData;
  CanvasRenderingContext2D.prototype.getImageData = function (x, y, w, h) {
    const data = originalGetImageData.call(this, x, y, w, h);
    for (let i = 0; i < data.data.length; i += 4) {
      data.data[i] += Math.floor(Math.random() * 3);
      data.data[i + 1] += Math.floor(Math.random() * 3);
      data.data[i + 2] += Math.floor(Math.random() * 3);
    }
    return data;
  };

  const originalGL = WebGLRenderingContext.prototype.getParameter;
  WebGLRenderingContext.prototype.getParameter = function (param) {
    const spoofMap = { 37445: 'FakeVendor Inc.', 37446: 'Virtual GPU Renderer', 3379: 4096, 35661: 8 };
    return spoofMap[param] || originalGL.call(this, param);
  };

  WebGLRenderingContext.prototype.getShaderPrecisionFormat = function () {
    return { rangeMin: 127, rangeMax: 127, precision: 23 };
  };

  performance.now = () => Math.floor(performance.timeOrigin + Math.random() * 100);

  navigator.storage.estimate = () => Promise.resolve({ usage: 5242880, quota: 1073741824 });

  window.RTCPeerConnection = undefined;
  window.webkitRTCPeerConnection = undefined;
  window.Bluetooth = undefined;
  delete navigator.getBattery;
  delete navigator.bluetooth;

  window.DeviceMotionEvent = undefined;
  window.DeviceOrientationEvent = undefined;

  window.addEventListener('devicemotion', e => e.stopImmediatePropagation(), true);
  window.addEventListener('deviceorientation', e => e.stopImmediatePropagation(), true);

  window.addEventListener('beforeunload', e => {
    e.stopImmediatePropagation();
    e.preventDefault();
    return undefined;
  }, true);

  if (DEBUG_MODE) {
    console.group(`[AFS+] Spoofed Fingerprint for Session: ${sessionId}`);
    console.log('User Agent     :', spoofed.userAgent);
    console.log('Platform       :', spoofed.platform);
    console.log('Language       :', spoofed.language);
    console.log('Languages      :', spoofed.languages().join(', '));
    console.log('Timezone       :', spoofed.timezone);
    console.log('CPU Cores      :', spoofed.cores);
    console.log('Device Memory  :', spoofed.memory);
    console.log('Screen Width   :', spoofed.screenWidth);
    console.log('Screen Height  :', spoofed.screenHeight);
    console.log('Vendor         :', spoofed.vendor);
    console.log('DNT            :', spoofed.doNotTrack);
    console.groupEnd();
  }
})();