2020-11-05 21:36:24 +00:00
|
|
|
/* eslint-disable no-extend-native */
|
|
|
|
/* eslint-disable @typescript-eslint/ban-types */
|
|
|
|
|
|
|
|
/**
|
|
|
|
* make hooked methods "native"
|
|
|
|
*/
|
|
|
|
export const makeNative = (() => {
|
2020-11-08 02:03:26 +00:00
|
|
|
const l = new Map<Function, Function>()
|
2020-11-05 21:36:24 +00:00
|
|
|
|
2020-11-05 21:54:07 +00:00
|
|
|
hookNative(Function.prototype, 'toString', (_toString) => {
|
|
|
|
return function () {
|
|
|
|
if (l.has(this)) {
|
2020-11-08 02:03:26 +00:00
|
|
|
const _fn = l.get(this) || parseInt // "function () {\n [native code]\n}"
|
2020-11-08 20:48:54 +00:00
|
|
|
if (l.has(_fn)) { // nested
|
|
|
|
return _fn.toString()
|
|
|
|
} else {
|
|
|
|
return _toString.call(_fn) as string
|
|
|
|
}
|
2020-11-05 21:54:07 +00:00
|
|
|
}
|
|
|
|
return _toString.call(this) as string
|
2020-11-05 21:36:24 +00:00
|
|
|
}
|
2020-11-06 04:27:51 +00:00
|
|
|
}, true)
|
2020-11-05 21:36:24 +00:00
|
|
|
|
2020-11-08 02:03:26 +00:00
|
|
|
return (fn: Function, original: Function) => {
|
|
|
|
l.set(fn, original)
|
2020-11-05 21:36:24 +00:00
|
|
|
}
|
|
|
|
})()
|
2020-11-05 21:47:50 +00:00
|
|
|
|
2020-11-05 21:54:07 +00:00
|
|
|
export function hookNative<T extends object, M extends (keyof T)> (
|
2020-11-05 21:47:50 +00:00
|
|
|
target: T,
|
|
|
|
method: M,
|
|
|
|
hook: (originalFn: T[M], detach: () => void) => T[M],
|
2020-11-06 04:27:51 +00:00
|
|
|
async = false,
|
2020-11-05 21:54:07 +00:00
|
|
|
): void {
|
2020-11-05 21:47:50 +00:00
|
|
|
// reserve for future hook update
|
|
|
|
const _fn = target[method]
|
|
|
|
const detach = () => {
|
|
|
|
target[method] = _fn // detach
|
|
|
|
}
|
|
|
|
|
|
|
|
// This script can run before anything on the page,
|
|
|
|
// so setting this function to be non-configurable and non-writable is no use.
|
|
|
|
const hookedFn = hook(_fn, detach)
|
|
|
|
target[method] = hookedFn
|
|
|
|
|
2020-11-06 04:27:51 +00:00
|
|
|
if (!async) {
|
2020-11-08 02:03:26 +00:00
|
|
|
makeNative(hookedFn as any, _fn as any)
|
2020-11-06 04:27:51 +00:00
|
|
|
} else {
|
|
|
|
setTimeout(() => {
|
2020-11-08 02:03:26 +00:00
|
|
|
makeNative(hookedFn as any, _fn as any)
|
2020-11-06 04:27:51 +00:00
|
|
|
})
|
|
|
|
}
|
2020-11-05 21:47:50 +00:00
|
|
|
}
|