【问题标题】:Is it possible to tell whether or not some javascript code call particular function?是否可以判断某些 javascript 代码是否调用特定函数?
【发布时间】:2011-04-02 10:26:31
【问题描述】:

我正在尝试构建某种 javascript“防病毒软件”来尝试捕获特定的函数调用。

假设我有一些随机的 javascript 文件,我可以检查它是否在任何地方都没有使用函数 jQuery.trim()(只是为了举例)?

这似乎是一项相当复杂的任务,此外还有eval 和基本编码,可以将任何代码转换为一堆字符。

是否可以在 PHP 中编写类似的内容?是否有任何库和工具可以提供帮助?

【问题讨论】:

    标签: php javascript parsing static-analysis


    【解决方案1】:

    没有。一般情况下,您不能仅通过检查代码来做出此决定。

    即使您忽略 eval(说起来容易做起来难——隐藏函数调用的方法有很多),它仍然无法确定。

    例如:<pre>somestring[data_from_remote_server](...)</pre> 其中data_from_remote_server 是“indexOf”。该代码可以调用 indexOf。有可能吗?谁知道。

    即使没有远程服务器,也不难想象编写代码来计算字符串“indexOf”而不实际包含字符串“indexOf”。

    【讨论】:

      【解决方案2】:

      JavaScript 是一种动态语言,即使没有像 eval 这样的函数,也很难判断脚本是否正在调用特定的函数。我能想到的最佳解决方案类似于@pixl coer 的方法来覆盖函数本身,并有选择地调用它而不是总是阻塞它。

      考虑这个例子,它间接调用数组上的pop 方法,将其称为损坏的字符串。

      var p = 'p';
      var o = 'o'
      [2,3,4][p + o + p]();
      

      通过包装实际方法,您可以有选择地决定是让方法通过还是在运行时阻塞它。

      但是,请注意,即使这样也不是万无一失的。每个 iframe 都有自己的方法副本,例如 eval。有人可以创建一个一次性的iframe,从那里获取eval 方法,然后执行它。

      简而言之,这个判断根本无法静态做出。即使是动态的,您也必须修补很多东西以确保永远不会调用特定函数。

      【讨论】:

        【解决方案3】:

        在任何脚本运行之前,您可以将不想运行的每个函数设置为您自己的函数,例如,可以记录脚本尝试运行此函数 假设您不希望脚本使用 eval:

        window.eval = function(){
             console.log("The script tried to call eval");  
        };
        

        或者如果你不希望它在字符串上调用 indexOf

        String.prototype.indexOf = function(){
             console.log("The script tried to call indexOf on the string" + this);
        }
        

        编辑: 如果您想继续使用这些函数,您可以创建副本,然后在替换函数中执行它们,如下所示:

            var evalCopy = window.eval;
            window.eval = function () {
                console.log("Eval was called again");
                return evalCopy.apply(this,arguments);
            }
        

        【讨论】:

        • 谢谢,但我正在尝试做一些不同的事情——不是阻止脚本使用函数,而是回答一个问题——这个函数是否被调用。
        • 这样做的缺点是它会禁用所有脚本的功能,而不仅仅是他想要禁止它们的那些。听起来他想接受用户创建的脚本并禁止某些功能,但不是全局的(包括他自己的脚本)。
        • @serg 那么一旦你确定了这些信息,你会怎么做?仍然允许它执行吗?
        • @Alex 我只需要它来进行统计 - 所以我可以显示这段代码是否正在使用特定的功能。
        • 你能这样做吗:var evalCopy = window.eval; window.eval = function(input){ console.log("Eval 再次被调用");返回 evalCopy(输入); }。抱歉,这不是很可读。我编辑了我的答案:-)
        【解决方案4】:

        有一个 PHP Javascript 解析器和标记器可能会有所帮助。您可以查看函数调用的解析树以及别名,以确保用户不会将函数分配给另一个名称,然后使用该新名称。一旦您禁止 eval 和类似功能(例如,FunctionsetTimeout 等),编码内容就不会有问题,因为执行代码需要 eval。

        http://web.2point1.com/2009/11/14/jparser-and-jtokenizer-released/

        解析树示例:http://timwhitlock.info/plug/examples/JavaScript/JParser.php

        编辑:没关系,即使这样也无法捕捉到一些边缘情况。我唯一能想到的另一件事是通过 Javascript 引擎运行代码并监视任何恶意函数调用。但即使这样也无法捕获所有内容(来自远程服务器的数据就是一个例子)。

        【讨论】:

        • 谢谢。唯一的问题是它不处理 eval。我通过打包程序运行他们的示例代码,它无法提取函数名称。
        • @serg:你能发布缩小的代码吗?您可以将其添加到某种 pastebin 或将其编辑到您的帖子中。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-09-10
        • 1970-01-01
        • 2023-04-02
        • 1970-01-01
        • 2014-06-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多