做油猴插件时,有些功能需要通过覆盖源程序的代码实现,不过有些程序比较鸡贼,会通过调用函数的 toString()
属性以检测函数是否覆盖 w(゚Д゚)w
于是就有了这段代码,通过直接覆盖 Function.prototype.toString
,彻底阻断这种检测方式。
https://github.com/SolomonLeon/toString_hack
alert.toString() // 'function alert() { [native code] }'
alert = disguisef(alert, ()=>{return "0"}) // 覆盖原函数
alert.toString() // 'function alert() { [native code] }'
alert.toString.toString() // 'function toString() { [native code] }'
chrome 和 firefox 均可用。
1
codehz 2023-03-06 12:06:05 +08:00 via iPhone
你 bind 一下就是[native code]了(
|
2
codehz 2023-03-06 12:09:54 +08:00 via iPhone
不过对于自定义函数确实需要 hack 一下(
然而,toLocaleString 是不是也得考虑下 |
3
Leon6868 OP @codehz #2 toLocalString 考虑了,在 chrome 和 Firefox 下都没问题。其实 toString 和 toLocalString 在实现上好像有关联,直接重写 toString 会导致 toLocalString 不可用(( 所以才写出那么奇怪的代码
|
4
codehz 2023-03-06 12:48:44 +08:00 via iPhone
这里为啥需要__to_string__绕一圈调用,不可以用 Reflect.apply(realToString, this, [])的方式调用吗,
仔细想整个 disguisef 实现直接用 new Proxy(fn, { apply() { } })的方式做似乎就够了,hook 的地方直接 proxy call disguisef = (targetfn, realfn) => new Proxy(targetfn, { apply(target, thisArg, argumentsList) { return Reflect.apply(realfn, thisArg, argumentsList); } }); |
5
Leon6868 OP @codehz 不知道有没有其他方法检测函数被修改,不过用这个代码的话 toString 和 toLocalString 是没法检测的了((也许?
|
7
1t1y1ILnW0x5nt47 2023-03-06 13:42:06 +08:00
直接开启严格模式,在对需要冻结的对象,Object.freeze(obj)
|
8
1t1y1ILnW0x5nt47 2023-03-06 13:43:50 +08:00
@3000codes 看错标题了,不好意思
|
10
centralpark 2023-03-06 14:36:34 +08:00
其实这个问题还有一个更简单的解决方法:重新编译一下 Chrome 不就得了(逃
|
12
codehz 2023-03-06 20:42:08 +08:00 via iPhone
@Leon6868 哦,也好修,再套一层 proxy
const disguisef = (targetfn, realfn) => new Proxy(targetfn, { apply(target, thisArg, argumentsList) { return Reflect.apply(realfn, thisArg, argumentsList); }, get() { return new Proxy(Reflect.get(...arguments), { apply(target, _, argumentsList) { return Reflect.apply(target, targetfn, argumentsList); }, }); }, }); |