WhatWeb源码分析之lib/plugins.rb

      插件处理在whatweb中占有很重要的地位,这次就来分析lib/plugin.rb。还是按照惯例,一边调试运行一边分析plugins.rb中的代码实现。首先,看到的是关于plugin处理的几个变量的初始化操作。

WhatWeb源码分析之lib/plugins.rb

      注意看,在进入load_plugin之前,如果特定判断条件满足的话,会有一个赋值,这样load_plugin的范围会扩大。在这里我没有指定额外的plugin位置,所以只是加载预设的插件。

WhatWeb源码分析之lib/plugins.rb

      跟进load_plugin函数看一下实现,挑选一些代码片段来讲解下:

WhatWeb源码分析之lib/plugins.rb

      这里是根据预设变量,获取plugins目录的地址。因为我这里load_plugin的传入参数list赋值为nil,所在list判断逻辑中,跳过了if直接到达了else的代码段。

WhatWeb源码分析之lib/plugins.rb

      上面这段代码的作用是加载指定插件目录下所有.rb的文件,也就是各插件识别文件。跟进PluginSupport.load_plugin看一下加载的实现过程。

WhatWeb源码分析之lib/plugins.rb

      这里的关键在load f这一句代码。继续跟进去看一看:

WhatWeb源码分析之lib/plugins.rb

      跳转到插件文件内部,继续跟进Plugin.define函数:

WhatWeb源码分析之lib/plugins.rb

      这里的代码实现,就完成了一个插件的注册过程。看下对应的每个函数实现:

WhatWeb源码分析之lib/plugins.rb

      p.instance_eval(&block)会跳转到下面这个模块实现:

WhatWeb源码分析之lib/plugins.rb

      这里涉及到instance_eval和class_eval的用法,我没太理解清楚,暂时略过。注意,要能保证上面代码的运行顺利,可以看到首先定义了一个模块:

WhatWeb源码分析之lib/plugins.rb

      Plugin类的最后,利用extend方法将PluginSugar模块中的方法变为Plugin的类方法。如下图所示:

WhatWeb源码分析之lib/plugins.rb

      283句指定插件中所有可能出现的项。加载完插件的所以项,到最后一句完成一个插件的注册,跳出,回到load_plugin函数中。

WhatWeb源码分析之lib/plugins.rb

      最后,完成所以插件的注册。继续往下执行,是对插件数目的判断。

WhatWeb源码分析之lib/plugins.rb

      接着往下,有一个插件优化函数:

WhatWeb源码分析之lib/plugins.rb

      跟进去看看:

WhatWeb源码分析之lib/plugins.rb

      这里主要是对之前加载的plugin中的正则表达式字符串进行预编译。通过Regexp.new来返回一个正则表达式对象,并且把这个对象存入thismatch中。

      继续往下执行,就到了获取target返回值之后,来进行指纹匹配和判断的函数。

WhatWeb源码分析之lib/plugins.rb

      跟进去看一下:

WhatWeb源码分析之lib/plugins.rb

      首先,从plugins_to_use中循环取项name和plugin,然后判断plugin是否锁定,先把plugin锁定,然后进行一个plugin的初始化操作。

WhatWeb源码分析之lib/plugins.rb

      跟进init函数看看:

WhatWeb源码分析之lib/plugins.rb

      从代码实现上可以看到,这里是把target的各项值分别存入plugin的对应实例变量中。这里的target是一个Target类的实例对象。初始化完成之后,进入plugin.x这个函数,跟进去看看:(截取了部分代码)

WhatWeb源码分析之lib/plugins.rb

      从代码上看,这是执行具体的匹配过程。跟进到make_matches函数,这个是执行匹配的主要函数,跟进去看看:(代码比较长,截取部分代码)

WhatWeb源码分析之lib/plugins.rb

      首先有一段根据match中:search键值的判断:

WhatWeb源码分析之lib/plugins.rb

      $1是获取正则匹配的第一个结果,也就是第一个小括号里面的值。这一段匹配之后,接下来有一段根据各项值进行判断的代码块:

WhatWeb源码分析之lib/plugins.rb

      我调试的第一个插件这一段跳过了,暂时我也忽略,继续往下执行。进入一个匹配代码块:

WhatWeb源码分析之lib/plugins.rb

      这里去用预编译好的正则表达式在特定项中(如vesion、os等)中进行匹配,如果匹配成功会把匹配的结果最后整合到一个array中,并且追加到r后面。然后有一句判断r是否为空,如果为空直接就返回了。我这里调试r返回值为空,后续的代码跳过了。只好读源码领会意思了。

      下面就是根据返回的状态码和url来进行匹配,其中对url的判断又分了四种情况,是完整的url地址还是相对url地址,以及是否带查询部分。(截图不完整)

WhatWeb源码分析之lib/plugins.rb

      接下来就是判断是否返回一个匹配:

WhatWeb源码分析之lib/plugins.rb

      也是分成了四种情况,对之前那一段代码赋值得到的match[:status]和match[:url]进行判断,根据结果决定是否是将match追加到结果数组的后面。

      跳出make_matches函数,如果对于matches中每个项都已经遍历完成,那么就继续往下执行:

WhatWeb源码分析之lib/plugins.rb

      判断插件里面是否有passive method,暂时调试的插件里没有这个,跳过。

      继续往下:

WhatWeb源码分析之lib/plugins.rb

      根据AGGRESSION的值判断是否采取 aggressive方式。后面那一段代码是寻找matches中的url地址,然后与原url拼接生成一个新的url,对新url地址进行插件匹配。

      最后有一小段代码:

WhatWeb源码分析之lib/plugins.rb

      遍历结果每一项,如果键:certainty的值不为空,则赋值100。这是确定插件匹配度。

      对plugins.rb暂时分析到这里。还有几个函数没有分析,主要是与自定义插件相关。后续继续分析。