【问题标题】:How to surreptitiously modify a function in Javascript如何偷偷修改Javascript中的函数
【发布时间】:2021-05-04 22:04:56
【问题描述】:

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

console.error = function() {
  return "fake";
}

但是,只需在其上运行 toString() 即可检测到功能已更改:

> console.error.toString()
'function() {\nreturn "fake";\n}'

如果函数没有被修改,则返回'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 ] }'"

是否有递归地重写 toString() 或任何其他方法,使得无法检测到函数被重写?

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

【问题讨论】:

  • 我认为你唯一的选择是覆盖默认的 Function proptotype 函数 (Function.prototype.toString)。但是你为什么要这么做呢?
  • 听起来像an XY problem。你想做什么?

标签: javascript


【解决方案1】:

您可以覆盖Function.prototype.toString 本身。但是,其他代码仍有可能绕过这一点 - 最简单的方法是在覆盖之前引用该方法,而 restoring a version from a different realm 则相当复杂。

{
    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;
}

【讨论】:

  • 即使你覆盖Function.prototype.toString,如果你在(() => {}).toString()之类的东西上运行它,你也会意识到这是假的,因为那里没有涉及本机代码。
  • @MinusFour 当然,我不会用简单地不断返回 function () { [native code] } 的东西来覆盖它 :-) 另请参阅我添加到答案中的代码
  • 让我认真思考了那个,但仍然可以检测它是否是假的。你可以做new Function.prototype.toString(),它会给你一个不同的错误。但我认为可以肯定地认为这是一个非常牵强的尝试。
  • @MinusFour 好电话。可以使用new.target 检测到,或者更好的是正确创建一个(不可构造的)方法 - 请参阅编辑
  • 好吧,这涵盖了所有内容。最终,如果我真的觉得代码已被取代,我会使用调试器。但没有通过我能想到的 javascript 进行进一步检查。
【解决方案2】:

有没有办法覆盖一个函数,以至于无法检测到这个函数被覆盖了?

我认为这里的答案是“不”。最好的办法是使用Proxy,但总会有一些方法来检测代码是否被猴子补丁。

真正的“解决方案”是更改运行时以防止程序知道它已被修补。

这真的取决于你在做什么,以及对方会花多长时间来检测代码是否被修改。这可能有一个术语(有人知道吗?),但我会称之为对抗性编程,直到有人提出更正确的术语。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-07
    • 1970-01-01
    • 1970-01-01
    • 2018-04-12
    相关资源
    最近更新 更多