如何使用代理捕获对象创建?

How do I catch object creation using a proxy?

感谢您花时间阅读我的问题。一个网站的 javascript I'm reverse engineering 执行以下行:

this.socket = new WebSocket(o.host)

该行被其他函数的函数等埋没了,所以我在运行时无法正常访问它。我想在调用 new Websocket() 时使用 Proxy 对象“注入”代码,以便通知我它的创建并将其保存到我之前准备的全局变量中。

我的 greasemonkey 脚本看起来像这样:

var caught_socket; // prepare variable

handler = {
  apply: function(target, thisArg, argumentsList) {
    console.log("WebSocket was created!");
    caught_socket = target;
  }
}

WebSocket = new Proxy(WebSocket, handler);

这显然行不通,如果您能提供任何帮助或演示代理实际如何工作,我将不胜感激!

改用Proxy.construct(),调用new时会执行

// Create a new WebSocket proxy
WebSocket = new Proxy(WebSocket, {
  construct: (target, args) => {
    console.log('New WebSocket Instance!')
    return new target(...args)
  }
})

// Test the WebSocket proxy by connecting to a remote server
const ws = new WebSocket('wss://echo.websocket.org')

// Listen for an open connection
// Send a message to the connection
ws.addEventListener('open', () => {
  console.log('Connection Open!')
  ws.send('hello')
})

// Listen for messages from the remote server
ws.addEventListener('message', msg => console.log('Response:', msg.data))

如果您添加第二个代理,两个代理都执行:

// Create a new WebSocket proxy
WebSocket = new Proxy(WebSocket, {
  construct: (target, args) => {
    console.log('New WebSocket Instance!')
    return new target(...args)
  }
})

WebSocket = new Proxy(WebSocket, {
  construct: (target, args) => {
    console.log('New WebSocket Override!')
    return new target(...args)
  }
})

// Test the WebSocket proxy by connecting to a remote server
const ws = new WebSocket('wss://echo.websocket.org')

// Listen for an open connection
// Send a message to the connection
ws.addEventListener('open', () => {
  console.log('Connection Open!')
  ws.send('hello')
})

// Listen for messages from the remote server
ws.addEventListener('message', msg => console.log('Response:', msg.data))

你甚至可以return一个完全不同的class:

class MyCoolWebSocket {
  addEventListener(event, callback) {
    console.log('override event:', event)
  }
}


// Create a new WebSocket proxy
WebSocket = new Proxy(WebSocket, {
  construct: (target, args) => {
    console.log('New WebSocket Instance!')
    return new WebSocket(...args)
  }
})

// Create a new WebSocket proxy
WebSocket = new Proxy(WebSocket, {
  construct: (target, args) => {
    console.log('Greasemonkey override!')
    return new MyCoolWebSocket(...args)
  }
})

// Test the WebSocket proxy by connecting to a remote server
const ws = new WebSocket('wss://echo.websocket.org')

// Listen for an open connection
// Send a message to the connection
ws.addEventListener('open', () => {
  console.log('Connection Open!')
  ws.send('hello')
})

// Listen for messages from the remote server
ws.addEventListener('message', msg => console.log('Response:', msg.data))