我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...

本文做个修改javascript系统函数的尝试,比如最常见的定时器函数setInterval()。思路上比较容易理解,就是先保存老的函数,然后定义同名的目标函数,在定义中再做自己的修改,最后再调用原函数。

苏南大叔:js代码,如何改写系统函数?给系统函数增加钩子函数 - js-hook
js代码,如何改写系统函数?给系统函数增加钩子函数(图3-1)

大家好,这里是被网站备案中心反复折磨的苏南大叔的博客,这里记录苏南大叔和计算机代码的故事。本文以改写javascriptsetInterval()为例,探讨改写系统函数的可能性。测试环境:win10chrome@105.0.5195.102

范例例子

下面的是个改写系统setInterval()的例子。当然,如果要下钩子的话,写法基本类似。

_setInterval = setInterval;
setInterval = function (code, time) {
    code = code.toString();

    // 示例代码,请根据自身情况修改================
    // code = code.replace("debugger", ""); //这种写法只能替换一次
    code = code.replace(new RegExp("原版","gm"), "新版"); //这种写法可以替换多次
    code = code.replace("function()", "function aaa()") + "aaa();"; //new Function不识别匿名函数
    // code = code.replace(new RegExp("function\\(\\)","gm"), "function aaa()") + "aaa();";
    // 示例代码,请根据自身情况修改================

    return _setInterval(new Function(code), time); //注意这里的字母F大写
}
setInterval(function(){                            //注意这里的function和()之间没有空格
    console.log("原版原版原版");
},1000);

这里原版的效果是:每隔一秒输出“原版原版原版”。修改后的效果是:每隔一秒输出“新版新版新版”。

苏南大叔:js代码,如何改写系统函数?给系统函数增加钩子函数 - 运行截图
js代码,如何改写系统函数?给系统函数增加钩子函数(图3-2)

代码解说

原理在文章开头就已经说过了,这里再复述一次,先用个变量保存原函数,然后修改函数逻辑,然后定义同名的函数,在函数内部再去调用原函数,逻辑就是这么清晰。

苏南大叔:js代码,如何改写系统函数?给系统函数增加钩子函数 - 代码
js代码,如何改写系统函数?给系统函数增加钩子函数(图3-3)

replace几次

这里就特别说明一下修改逻辑时的replace函数,因为默认情况下,javascriptreplace函数,只替换一次,这个是个超级大坑。所以想清楚,自己想要的是普通就替换第一个匹配项目的replace。还是需要替换所有内容的正则表达式写法。

普通只替换一次的replace()

code.replace("原版","新版");

替换所有内容的replace()

code.replace(\原版\gm,"新版");

正则表达式的写法,要注意转义,比如代码中常见的“()”都是要进行转义的。"\(\)"。

匿名函数

setInterval()的第一个参数是个匿名函数,但是把它传入到new Function()的话,会报错。

Uncaught SyntaxError: Function statements require a function name

那么,解决方案就是:做个函数名字。因为字符串是个函数模样,又加了一个自执行的代码,再整体放到匿名函数里面了。有点绕对不?

改进写法

实际上上面的代码,存在着一定的瑕疵。比如setInterval()第一个参数传递的是下面这个形式的匿名函数的时候,就会报错了。

()=>{}

所以,上面的setInterval()的改写代码需要再次改进。参考如下:

newsn.net:这里是【评论】可见内容

下面两种写法调用,都可以顺利执行。

setInterval(function() {
  console.log("原版原版原版aaa");
}, 1000);
setInterval(() => {
  console.log("原版原版原版");
}, 1000);

仅供参考的代码

下面的代码,据原版说明,功用是对Function整体进行改写原型链,具体点说就是消灭debugger函数。苏南大叔试了一下,没有效果,改写失败。大家有知道如何使用的,可以留言。

Function.prototype.temp_constructor = Function.prototype.constructor;
Function.prototype.constructor = function () {
    console.log(arguments);
    if (arguments && typeof arguments[0] === "string") {
        if (arguments[0] === "debugger")
            return ""
    }
    return Function.prototype.temp_constructor.apply(this, arguments);
};

debugger这个特殊函数,似乎用本文的这种hook方式也不能被修改。也许,就类似phpeval一样吧。属于特殊的函数。

相关链接

总结

没有啥可总结的,代码逻辑弄明白了,就可以hook了。本文的主要目的是:js的系统函数是可以被改写的!结束!

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。

 【福利】 腾讯云最新爆款活动!1核2G云服务器首年50元!

 【源码】本文代码片段及相关软件,请点此获取更多信息

 【绝密】秘籍文章入口,仅传授于有缘之人   js