by Proze

Full browser fingerprinting evasion suite.

Vous devrez installer une extension telle que Tampermonkey, Greasemonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Userscripts pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey pour installer ce script.

Vous devrez installer une extension de gestionnaire de script utilisateur pour installer ce script.

(J'ai déjà un gestionnaire de scripts utilisateur, laissez-moi l'installer !)

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

(J'ai déjà un gestionnaire de style utilisateur, laissez-moi l'installer!)

// ==UserScript==
// @name        by Proze
// @namespace   Violentmonkey Scripts
// @match       *://*/*
// @grant       none
// @run-at      document-start
// @version     10.0
// @author      .*
// @description Full browser fingerprinting evasion suite.
// @license     MIT
// ==/UserScript==

(function() {
    'use strict';

    const D = {
        os: [
            { n: "Windows NT 10.0; Win64; x64", p: "Win32", v: "Google Inc.", m: "desktop" },
            { n: "Windows NT 10.0; WOW64", p: "Win32", v: "Google Inc.", m: "desktop" },
            { n: "Macintosh; Intel Mac OS X 10_15_7", p: "MacIntel", v: "Apple Computer, Inc.", m: "desktop" },
            { n: "Macintosh; Intel Mac OS X 12_3_1", p: "MacIntel", v: "Apple Computer, Inc.", m: "desktop" },
            { n: "X11; Linux x86_64", p: "Linux x86_64", v: "Google Inc.", m: "desktop" },
            { n: "Linux; Android 13; SM-S908B", p: "Linux armv8l", v: "Google Inc.", m: "mobile" },
            { n: "Linux; Android 12; Pixel 6 Pro", p: "Linux armv8l", v: "Google Inc.", m: "mobile" },
            { n: "iPhone; CPU iPhone OS 16_0 like Mac OS X", p: "iPhone", v: "Apple Computer, Inc.", m: "mobile" },
            { n: "iPad; CPU OS 15_4 like Mac OS X", p: "iPad", v: "Apple Computer, Inc.", m: "mobile" }
        ],
        browser: [
            "Chrome/108.0.0.0", "Chrome/109.0.0.0", "Chrome/110.0.0.0",
            "Safari/605.1.15", "Firefox/109.0", "Firefox/108.0"
        ],
        gpu: [
            "ANGLE (NVIDIA, NVIDIA GeForce RTX 3090 Direct3D11 vs_5_0 ps_5_0, D3D11)",
            "ANGLE (NVIDIA, NVIDIA GeForce RTX 3080 Direct3D11 vs_5_0 ps_5_0, D3D11)",
            "ANGLE (NVIDIA, NVIDIA GeForce GTX 1080 Ti Direct3D11 vs_5_0 ps_5_0, D3D11)",
            "ANGLE (AMD, AMD Radeon RX 6900 XT Direct3D11 vs_5_0 ps_5_0, D3D11)",
            "ANGLE (Intel, Intel(R) Iris(R) Xe Graphics Direct3D11 vs_5_0 ps_5_0, D3D11)",
            "Apple GPU", "Apple A15 GPU", "Apple A16 GPU", "Adreno (TM) 730", "Mali-G710 MC10"
        ],
        tz: [
            { z: "America/New_York", o: 300, l: "en-US" }, { z: "America/Los_Angeles", o: 480, l: "en-US" },
            { z: "Europe/London", o: 0, l: "en-GB" }, { z: "Europe/Berlin", o: -60, l: "de-DE" },
            { z: "Asia/Tokyo", o: -540, l: "ja-JP" }, { z: "Asia/Singapore", o: -480, l: "en-SG" }
        ]
    };

    function r(a) { return a[Math.floor(Math.random() * a.length)]; }
    function ri(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; }
    function rf() { return Math.random() * 0.0000001; }

    const sOS = r(D.os);
    const sBr = r(D.browser);
    const sUA = `Mozilla/5.0 (${sOS.n}) AppleWebKit/537.36 (KHTML, like Gecko) ${sBr} Safari/537.36`;
    const sGpu = r(D.gpu);
    const sTz = r(D.tz);
    const sW = sOS.m === "mobile" ? ri(360, 430) : ri(1366, 2560);
    const sH = sOS.m === "mobile" ? ri(640, 932) : ri(768, 1440);
    const sDPR = sOS.m === "mobile" ? ri(2, 3) : 1;
    const sMem = [4, 8, 12, 16, 32][ri(0, 4)];
    const sCon = [4, 6, 8, 12, 16, 24][ri(0, 5)];
    const sBat = Math.random();
    const sChg = Math.random() > 0.5;

    function inject(scope) {
        function def(o, p, v) {
            try { Object.defineProperty(scope.Object.getPrototypeOf(o), p, { get: () => v, configurable: true, enumerable: true }); } catch(e) {}
            try { Object.defineProperty(o, p, { get: () => v, configurable: true, enumerable: true }); } catch(e) {}
        }

        def(scope.navigator, 'userAgent', sUA);
        def(scope.navigator, 'appVersion', sUA.replace('Mozilla/', ''));
        def(scope.navigator, 'platform', sOS.p);
        def(scope.navigator, 'vendor', sOS.v);
        def(scope.navigator, 'hardwareConcurrency', sCon);
        def(scope.navigator, 'deviceMemory', sMem);
        def(scope.navigator, 'maxTouchPoints', sOS.m === "mobile" ? ri(2, 5) : 0);
        def(scope.navigator, 'webdriver', false);
        def(scope.navigator, 'doNotTrack', "1");
        def(scope.navigator, 'language', sTz.l);
        def(scope.navigator, 'languages', [sTz.l, 'en-US']);
        
        if (scope.navigator.plugins) {
            def(scope.navigator, 'plugins', []);
            def(scope.navigator, 'mimeTypes', []);
        }

        def(scope.screen, 'width', sW);
        def(scope.screen, 'height', sH);
        def(scope.screen, 'availWidth', sW);
        def(scope.screen, 'availHeight', sH - 40);
        def(scope.screen, 'colorDepth', 24);
        def(scope.screen, 'pixelDepth', 24);
        
        def(scope.window, 'devicePixelRatio', sDPR);
        def(scope.window, 'innerWidth', sW);
        def(scope.window, 'innerHeight', sH);
        def(scope.window, 'outerWidth', sW);
        def(scope.window, 'outerHeight', sH);

        try {
            const gP = scope.WebGLRenderingContext.prototype.getParameter;
            scope.WebGLRenderingContext.prototype.getParameter = function(p) {
                if (p === 37445) return "Google Inc. (NVIDIA)";
                if (p === 37446) return sGpu;
                return gP.apply(this, arguments);
            };
        } catch(e) {}

        try {
            const tDU = scope.HTMLCanvasElement.prototype.toDataURL;
            scope.HTMLCanvasElement.prototype.toDataURL = function() {
                const c = this.getContext('2d');
                if (c) {
                    const w = this.width;
                    const h = this.height;
                    const d = c.getImageData(0, 0, w, h);
                    for (let i = 0; i < d.data.length; i += 4) {
                        if (i % ri(500, 2000) === 0) d.data[i] = d.data[i] + (Math.random() > 0.5 ? 1 : -1);
                    }
                    c.putImageData(d, 0, 0);
                }
                return tDU.apply(this, arguments);
            };
        } catch(e) {}

        try {
            const oAC = scope.AudioContext || scope.webkitAudioContext;
            if (oAC) {
                const oAn = oAC.prototype.createAnalyser;
                oAC.prototype.createAnalyser = function() {
                    const a = oAn.apply(this, arguments);
                    const oG = a.getFloatFrequencyData;
                    a.getFloatFrequencyData = function(arr) {
                        const r = oG.apply(this, arguments);
                        for (let i = 0; i < arr.length; i += 10) arr[i] += (Math.random() * 0.1) - 0.05;
                        return r;
                    };
                    return a;
                };
            }
        } catch(e) {}

        try {
            const oRTC = scope.RTCPeerConnection || scope.webkitRTCPeerConnection || scope.mozRTCPeerConnection;
            if (oRTC) {
                scope.RTCPeerConnection = function(c) {
                    if (c && c.iceServers) c.iceServers = [];
                    const p = new oRTC(c);
                    const oO = p.createOffer;
                    p.createOffer = function(o) { return oO.call(this, o).then(f => f); };
                    return p;
                };
                scope.RTCPeerConnection.prototype = oRTC.prototype;
            }
        } catch(e) {}

        try {
            const mTxt = scope.CanvasRenderingContext2D.prototype.measureText;
            scope.CanvasRenderingContext2D.prototype.measureText = function(t) {
                const m = mTxt.apply(this, arguments);
                const n = (Math.random() * 0.01) - 0.005;
                try { Object.defineProperty(m, 'width', { get: () => m.width + n }); } catch(e) { m.width = m.width + n; }
                return m;
            };
        } catch(e) {}

        try {
            const oBCR = scope.Element.prototype.getBoundingClientRect;
            scope.Element.prototype.getBoundingClientRect = function() {
                const r = oBCR.apply(this, arguments);
                const n = rf();
                return { x: r.x + n, y: r.y + n, width: r.width + n, height: r.height + n, top: r.top + n, right: r.right + n, bottom: r.bottom + n, left: r.left + n, toJSON: () => this };
            };
        } catch(e) {}

        try {
            const oNow = scope.performance.now;
            scope.performance.now = function() { return oNow.apply(this) + (Math.random() * 0.02); };
        } catch(e) {}

        if (scope.navigator.getBattery) {
            scope.navigator.getBattery = () => Promise.resolve({ charging: sChg, chargingTime: sChg ? ri(100, 5000) : Infinity, dischargingTime: sChg ? Infinity : ri(100, 50000), level: sBat, addEventListener: () => {}, removeEventListener: () => {} });
        }

        if (scope.navigator.permissions) {
            scope.navigator.permissions.query = p => Promise.resolve({ state: 'prompt', onchange: null });
        }

        const oIntl = scope.Intl.DateTimeFormat;
        scope.Intl.DateTimeFormat = function(l, o) {
            if (!o) o = {};
            if (!o.timeZone) o.timeZone = sTz.z;
            return new oIntl(l, o);
        };
        scope.Intl.DateTimeFormat.prototype = oIntl.prototype;
    }

    inject(window);

    const observer = new MutationObserver(mutations => {
        mutations.forEach(m => {
            m.addedNodes.forEach(n => {
                if (n.tagName === 'IFRAME') {
                    try {
                        if (n.contentWindow) inject(n.contentWindow);
                        n.addEventListener('load', () => inject(n.contentWindow));
                    } catch(e) {}
                }
            });
        });
    });
    observer.observe(document.documentElement, { childList: true, subtree: true });

    delete window.cdc_adoQpoasnfa76pfcZLmcfl_Array;
    delete window.cdc_adoQpoasnfa76pfcZLmcfl_Promise;
    delete window.cdc_adoQpoasnfa76pfcZLmcfl_Symbol;

})();