如何秘密修改 Javascript 中的函数

Nil*_*dré 3 javascript

我正在尝试修改一个函数:

console.error = function() {
  return "fake";
}
Run Code Online (Sandbox Code Playgroud)

但是,只需运行即可检测到该函数已更改toString()

> console.error.toString()
'function() {\nreturn "fake";\n}'
Run Code Online (Sandbox Code Playgroud)

如果函数没有被修改,'function () { [native code] }'则会返回。

解决方案可以是重写 toString(),但是,通过运行 toString 可以看到 toString 已被重写:

> console.error.toString = () => 'function () { [native code] }';
> console.error.toString()
'function () { [native code] }'
> console.error.toString.toString()
"() => 'function () { [ native code ] }'"
Run Code Online (Sandbox Code Playgroud)

无论如何,是否可以递归重写 toString() 或任何其他方法,以便无法检测到函数被重写?

用例是 WebExtension 修改某些功能,同时使网站尽可能难以检测到它。

Ber*_*rgi 5

您可以覆盖Function.prototype.toString自身。然而,其他代码仍然有可能规避这一点 - 最简单的方法是在覆盖该方法之前引用该方法,而通过从不同领域恢复版本则相当复杂。

{
    const Console = console.constructor;
    const origToString = Function.prototype.toString;
    const origError = Console.prototype.error;
    const {error} = {error() { return "fake"; }};
    const {toString} = {toString() {
        let target = this;
        if (this == toString) target = origToString;
        if (this == error) target = origError;
        return origToString.call(target);
    }};
    Function.prototype.toString = toString;
    Console.prototype.error = error;
}
Run Code Online (Sandbox Code Playgroud)

  • @MinusFour当然,我不会用简单地不断返回 `function () { [native code] }` 的东西来覆盖它:-)另请参阅我添加到答案中的代码 (2认同)