Home > database >  chrome.debugger commands doesn't affect iframes
chrome.debugger commands doesn't affect iframes

Time:12-18

I am trying to make a chrome extension that will use the chrome.debugger api, but I found that iframes are not affected by the chrome.debugger commands. For example in this test extension:

manifest.json

{
  "name": "test",
  "version": "1.0",
  "manifest_version": 3,
  "background": {
    "service_worker": "service_worker.js"
  },
  "host_permissions": ["*://*/*"],
  "permissions": ["debugger", "tabs"]
}

service_worker.js

chrome.runtime.onInstalled.addListener(async () => {
    run()
});

chrome.runtime.onStartup.addListener(async () => {
    run()
});

chrome.debugger.onDetach.addListener((source, reason) => {
    console.log("detached", source, reason);
});

chrome.tabs.onCreated.addListener((tab) => {
    console.log("attaching", tab);
    chrome.debugger.attach({
        tabId: tab.id
    }, "1.3", null);
});

async function run() {
    console.log('run');
    chrome.tabs.create({
        url: 'about:blank',
        active: true,
        index: 0
    })
    .then(async (tab) => {
        // wait a few seconds to make sure debugger is attached
        await new Promise(resolve => setTimeout(resolve, 2000));
        
        chrome.debugger.sendCommand({
                tabId: tab.id
            },
            'Emulation.setTimezoneOverride',
            { timezoneId: 'America/Adak'},
            (result) => {
                if (chrome.runtime.lastError) {
                    console.log(chrome.runtime.lastError)
                } else {
                    console.log(result)
                }
            }
        );

        chrome.debugger.sendCommand({
                tabId: tab.id
            },
            'Page.enable',
            { enabled: 'true'},
            (result) => {
                if (chrome.runtime.lastError) {
                    console.log(chrome.runtime.lastError)
                } else {
                    console.log(result)
                }
            }
        );

        chrome.debugger.sendCommand({
                tabId: tab.id
            },
            'Page.addScriptToEvaluateOnNewDocument',
            { source: 'Object.defineProperty(window, "testvar", { get: () => 123123123 })'},
            (result) => {
                if (chrome.runtime.lastError) {
                    console.log(chrome.runtime.lastError)
                } else {
                    console.log(result)
                }
            }
        );

        chrome.tabs.update(tab.id, {
            url: 'https://jsfiddle.net/neaxh173/'
        }, function() { });
    });
}

I am changing the timezone, and injecting a var called testvar, the it opens a jsfiddle that just does:

document.write(new Date().getTimezoneOffset()   ' - '   typeof testvar)

The jsfiddle result iframe shows my original timezone, and testvar is undefined, but if I open the console and run:

console.log(new Date().getTimezoneOffset()   ' - '   typeof testvar)

on the main frame, it shows correctly as "600 - number".

How do I make the chrome.debugger commands work on all the tab frames?

CodePudding user response:

To evaluate a script in a frame, it's executionContextId is required, which you can get from Runtime.executionContextCreated event. To enable reporting of this event you have to send Runtime.enable command.

Here is code snippet which evaluates a function in all frames :-

function evaluateScript(contextId, script) {
    chrome.debugger.sendCommand({ tabId: tabId }, 'Runtime.callFunctionOn', {
        arguments: [],
        awaitPromise: true,
        executionContextId: contextId,
        functionDeclaration: script && script.toString(),
        returnByValue: true,
        userGesture: true
    }, (result) => {
        console.log(result)
    })
}


chrome.debugger.onEvent.addListener((source, method, params) => {
    if (method === 'Runtime.executionContextCreated') {
        // evalute script for every execution context
        evaluateScript(params.context.id, () =>  {
           !window.testvar ? Object.defineProperty(window, "testvar", { get: () => 123123123 }) : null
        })
    }
})

// enable reporting of `Runtime.executionContextCreated` events
chrome.debugger.sendCommand({ tabId: tabId }, 'Runtime.enable')
  • Related