JavaScript - 使代理无法检测

时间:2017-08-15 08:15:16

标签: javascript google-chrome google-chrome-extension v8 ecmascript-7

据我所知,ES规范说Proxy(用于代理对象,函数和类的全局构造函数)是不可检测的。这意味着如果我代理一个函数,那么使用该代理函数的人都无法检测到我使用了代理。但是,显然我误解了它,因为可以检测到代理功能。

例如,new Proxy(a=>a,{apply:a=>a})+''会抛出错误。它说

Uncaught TypeError: Function.prototype.toString requires that 'this' be a Function

但是,typeof new Proxy(a=>a,{apply:a=>a})确实是"function",但它在某种程度上无法对代理进行字符串化。因此,显然,这是一种情况,当代理函数不像非代理函数那样表现时。 Function.prototype.toString能够区分代理和非代理功能。

我的目标是代理一个功能,使其变得简单无法检测。我的第一个想法是按字面意思代理代理,如下:

Proxy.toString = (a => () => a)(Proxy + '');
Proxy = new Proxy(Proxy, {
  construct: (f, args) => {
    if(typeof args[0] == 'function'){
      var a = args[0] + '';
      args[0].toString = () => a;
    }
    return new f(...args);
  }
});

但遗憾的是,这是可以察觉的。如果有人将Function.prototype.toString绑定到我的代理函数,则会发生错误,因此他可以检测到我的函数实际上是代理。所以,我尝试代理FunctionFunction.prototype以及Function.prototype.toString,但后来我意识到我无法代理Function,因为即使我覆盖了全局属性{{1有人可以使用Function访问它。

所以,这就是我在这里问的原因,因为我没有想法。如何代理函数使其完全无法检测?在ES规范中明确指出“代理是不可检测的”,所以作为一个附带问题,为什么然后代理一个可检测的函数?

修改

我试图实现此目的的原因是因为我正在为Chrome增强广告拦截扩展功能。我正在处理非常激进的网站,利用大量的JavaScript技巧来检测我是否正在查看广告。所以,基本上,我删除了一个广告,然后他们的脚本检查是否有特定元素,如果没有,那么我不能访问该网站。所以,我试图代理(a=>a).constructor,但他们检查它是否被代理,如果是,我不能访问该网站,所以我必须让它无法检测。

1 个答案:

答案 0 :(得分:0)

我不认为你可以用Proxies做什么。 Function.prototype.toString的{​​{3}}清楚地定义了TypeError投掷行为。由于无法提供Proxy [[ECMAScriptCode]]“内部广告位”,因此在Proxy上调用时总是会抛出。

我也没有在规范中看到任何“代理是不可检测的”语句;字符串'detectable'不会显示在文档中的任何位置。你在哪里找到这个说法?

也许你可以覆盖函数(以及它们的.toString属性)来实现你的目标?大致是:

var original_getElementById = document.getElementById;
document.getElementById = function(id) {
  if (...) {
    return original_getElementById(id);
  } else {
    // special handling here
  }
}