【问题标题】:Hooking Websockets from a Chrome Extension从 Chrome 扩展中挂钩 Websocket
【发布时间】:2018-10-04 15:32:55
【问题描述】:

我正在尝试创建一个可以挂钩特定页面的 WebSocket 的 Chrome 扩展内容脚本。当前,当页面被访问时,内容脚本会像这样将另一个脚本注入页面:

    var s = document.createElement('script');
    s.src = chrome.extension.getURL('Script.js');
    s.onload = function () {
        this.remove();
    };
    (document.head || document.documentElement).appendChild(s);

然后我的 Script.js 包含 websocket 的 addEventListener。

Window.WebSocket.addEventListener("message",function(event){
console.log("Websocket read");
})

但是当我运行扩展时,我收到一个错误,无法读取未定义的属性 addEventListener。所以我不完全确定这是否是正确的方法。我已经验证脚本确实被注入了页面,但是我将如何在页面的原始 onmessage WebSocket 之上覆盖或创建自己的侦听器。有可能吗?

【问题讨论】:

  • 你能试试像window.WebSocket.addEventListener这样的小写窗口吗?
  • 您好,当我将其更改为 window.WebSocket.addEventListener 时,我收到此错误:Uncaught TypeError: window.WebSocket.addEventListener is not a function
  • 使用onmessage 代替window.WebSocket.onmessage = function(event) { console.debug("WebSocket message received:", event); };
  • 你在哪里定义了Window.WebSocket?我不是 chrome 扩展的专家,但我认为这是错误的。在 javascript 中,您应该首先使用 new 关键字创建一个 websocket 实例。
  • 这能回答你的问题吗? stackoverflow.com/questions/22868897/…

标签: javascript google-chrome-extension websocket hook addeventlistener


【解决方案1】:

您可以使用 wshook 覆盖原来的 WebSocket 类并添加可用于任务的回调

您可以直接复制脚本wsHookjs并粘贴到您的代码之前,或者像普通的javascript一样导入然后开始使用它。

导入库

<script src='wsHook.js'></script>

那么你可以只为之前或之后或两者添加回调来拦截 websocket 发送请求:

wsHook.before = function(data, url, wsObject) {
    console.log("Sending message to " + url + " : " + data);
}

// Make sure your program calls `wsClient.onmessage` event handler somewhere.
wsHook.after = function(messageEvent, url, wsObject) {
    console.log("Received message from " + url + " : " + messageEvent.data);
    return messageEvent;
}

注意:内容脚本可以在页面加载之前加载。有关如何在页面加载之前加载内容脚本的更多信息,您可以查看此post

【讨论】:

  • 这似乎不是我正在寻找的解决方案,因为我不是部署或发布网站或页面的人。相反,我试图将通用脚本注入其他网站或页面,这些网站或页面利用 websockets 并挂钩该特定实例。
  • @Akali 您可以在页面加载之前注入脚本,有关如何在页面加载之前加载内容脚本的更多信息,请查看here
  • 你是在暗示我注入了 wsHook.js 的完整性?
  • 即使我的内容脚本在页面加载之前运行,然后我是否会将
  • @Akali 您不需要在任何网站中注入脚本标签,只需覆盖WebSocket,这是在您加载内容脚本后由wshook 脚本完成的WebSocket 将由库包装,然后将加载页面,该页面将使用更新后的WebSocket
【解决方案2】:

WebSocket 是一个类。 addEventListener 函数仅在类的实例中可用。因此,您必须找到网页创建的变量并将侦听器添加到该变量中。例如:

var mySocket = new WebSocket("wss://127.0.0.1:8080");

你会做这样的事情:

mySocket.addEventListener("message", (e) => console.log(e));

但是,这会丢失所有初始消息,这取决于您是否能够访问变量,这在所有情况下可能都不可能。

相反,您可以用自己的类覆盖该类,这样当他们创建 WebSocket 实例时,它实际上就是您的类。

一个例子是这样的:

class MyWebSocket extends WebSocket
{
    __constructor()
    {
        super(...arguments);
    }

    addEventListener(name, callback)
    {
        // call the original event listener
        super.addEventListener(name, function()
        {
            console.log("Im sneakily listening in here", arguments);

            // call their callback
            callback(...arguments);
        });
    }
}

// Override the real web socket with your version
window.WebSocket = MyWebSocket;

请记住,上面的代码是伪代码,未经测试。

如果您只想查看套接字数据。您可以打开 chrome 开发工具,单击“ws”过滤器。然后单击列出的 Web 套接字并查看正在传输的原始数据。

这是一个可以在您的上下文脚本中使用的工作示例。

while(document == null || document.head == null);

var s = document.createElement("script");

function hookWebSocket()
{
    window.RealWebSocket = window.WebSocket;

    window.WebSocket = function()
    {
        var socket = new window.RealWebSocket(...arguments);

        socket.addEventListener("message", (e) =>
        {
            console.log("The message is: ", e);
        });

        return socket;
    }
}

s.innerHTML = `
    ${hookWebSocket.toString()}

    hookWebSocket();
`;

document.head.prepend(s);

【讨论】:

  • 是的,我知道如果您找到该变量,则可以这样做,但这不是为依赖它的每个可能站点查找 websocket 变量的通用解决方案。这就是为什么我希望有一种方法可以在内部挂钩它。但我确实认为覆盖 WebSocket 类以便我的实例化而不是原始类可能是唯一的解决方案。
  • @Akali 我添加了一个工作示例供您使用。
  • 所以这实际上是在文档头部附加或插入脚本标签,然后从那里挂钩 websocket?
  • @Akali 这是一个宾果游戏
【解决方案3】:

你可以试试这个吗?

s.onload = function () {
  this.parentNode.removeChild(this);
};

【讨论】:

  • 脚本的注入部分不能正常工作。
猜你喜欢
  • 1970-01-01
  • 2011-08-05
  • 2016-10-01
  • 1970-01-01
  • 2011-10-16
  • 1970-01-01
  • 1970-01-01
  • 2021-03-11
  • 1970-01-01
相关资源
最近更新 更多