【反爬】 破解shadow-root(closed)

一、 源代码

浏览器安全策略原因,只能使用插件或扩展破解,这里推荐油猴脚本,具体使用不过多赘述。

脚本1:

// ==UserScript==
// @name         shadow-root
// @namespace    http://tampermonkey.net/
// @version      2024-07-10
// @description  try to take over the world!
// @author       Vdoi
// @match        *://*/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=gdzwfw.gov.cn
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // Your code here...


    Element.prototype._attachShadow = Element.prototype.attachShadow;
    Element.prototype.attachShadow = function () {
        //console.log('attachShadow');
        return this._attachShadow( { mode: "open" } );
    };


})();

脚本2:

// ==UserScript==
// @name         shadow-root(closed)2
// @namespace    http://tampermonkey.net/
// @version      2025-02-21
// @description  try to take over the world!
// @author       Vdoi
// @match        *://*/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=gdzwfw.gov.cn
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // Your code here...
    // 保存原始 attachShadow 方法
    const originalAttachShadow = Element.prototype.attachShadow;

    // 覆盖 attachShadow
    Element.prototype.attachShadow = function(options) {
        // 强制设置为 open 模式
        options.mode = 'open';

        // 调用原始方法并保存 shadowRoot
        const shadowRoot = originalAttachShadow.call(this, options);

        // 将 shadowRoot 绑定到元素上
        this._shadowRoot = shadowRoot;
        return shadowRoot;
    };



})();

脚本3:

// ==UserScript==
// @name         shadow-root(closed)3
// @namespace    http://tampermonkey.net/
// @version      2025-02-26
// @description  try to take over the world!
// @author       Vdoi
// @match        *://*/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=gdzwfw.gov.cn
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // Your code here...
    // 劫持元素原型链方法
    let oldAttach = Element.prototype.attachShadow;
    Element.prototype.attachShadow = function(...args) {
        // 强制修改闭包模式为open
        if (args[0]?.mode === 'closed') {
            args[0].mode = 'open';
            console.log('[Hook] ShadowRoot模式已强制开放');
        }
        return oldAttach.apply(this, args);
    };
})();

脚本4:

// ==UserScript==
// @name         Shadow-root(closed)4
// @namespace    http://your-domain.com
// @version      1.2
// @description  强制解除shadow-root(closed)限制
// @author       Vdoi
// @match        *://*/*
// @run-at       document-start
// @grant        unsafeWindow
// @grant        GM_addStyle
// ==/UserScript==

(function() {
    'use strict';

    // ================== 核心破解逻辑 ==================
    const hijackShadowDOM = () => {
        // 劫持原生API
        const nativeAttachShadow = Element.prototype.attachShadow;
        Element.prototype.attachShadow = function(config) {
            // 强制修改closed模式为open
            if (config?.mode === 'closed') {
                console.debug('[破解] 检测到closed模式,已强制开启');
                config.mode = 'open';
            }
            return nativeAttachShadow.call(this, config);
        };

        // 框架级破解(Vue/React)
        if (unsafeWindow.Vue) {
            const originalVueMount = unsafeWindow.Vue.prototype.$mount;
            unsafeWindow.Vue.prototype.$mount = function(el) {
                this.$el = el;
                return originalVueMount.call(this, el);
            };
            console.debug('[破解] Vue组件Shadow DOM限制已解除');
        }
    };

    // ================== 反检测机制 ==================
    const antiDetection = () => {
        // 屏蔽控制台特征
        const originalConsoleLog = console.log;
        console.log = function(...args) {
            if (!args.some(str => str.includes('shadow'))) {
                originalConsoleLog.apply(console, args);
            }
        };

        // 阻断异常检测
        const originalAddEventListener = EventTarget.prototype.addEventListener;
        EventTarget.prototype.addEventListener = function(type, listener, options) {
            if (type === 'securitypolicyviolation') return;
            originalAddEventListener.call(this, type, listener, options);
        };
    };

    // ================== DOM监控模块 ==================
    const startDOMObserver = () => {
        const observer = new MutationObserver(mutations => {
            mutations.forEach(mutation => {
                mutation.addedNodes.forEach(node => {
                    if (node.nodeType === 1 && node.shadowRoot) {
                        node.shadowRoot.innerHTML +=
                            '<style>:host { display: block !important; }</style>';
                    }
                });
            });
        });

        observer.observe(document.documentElement, {
            childList: true,
            subtree: true,
            attributes: false,
            characterData: false
        });
    };

    // ================== 执行入口 ==================
    hijackShadowDOM();
    antiDetection();
    startDOMObserver();

    // 注入辅助样式
    GM_addStyle(`
        #shadow-root (closed) {
            display: block !important;
            border: 1px dashed red !important;
        }
    `);

    // 调试模式开关(生产环境注释掉)
    // unsafeWindow.__DEBUG_SHADOW__ = true;
})();

二、 前后对比

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值