这回是如何高效地判断出迅雷的FTP指令序列。
这里所说的FTP指令序列是指,一个FTP会话从连接开始,到开始下载文件前,发送给服务器的FTP指令的序列。另外,指令参数是不算入指令序列里面的。
一个典型的FTP指令序列就是:USER->PASS->SIZE->PASV->RETR。
在最早版本的GSSXI中,我采用的方法非常糟糕,每收到一个指令,就把这个指令用strcat函数加到一个用来保存指令序列的字符串去,并在每个指令之间以*区分。于是上面的指令序列在我的字符串里就是:USER*PASS*SIZE*PASV*RETR*
然后,每修改一次用来保存指令序列的字符串后,我就用strcmp函数将当前的指令序列字符串和预先定义好的迅雷的指令序列做比较。这样每收到一个指令都要进行一次字符串比较,这个效率显然是不怎么样的。
于是现在我就想出了一个高效的办法。
基本的思想是,建立一个单向链表,链表的节点依次保存指令序列的一个指令。为每个FTP会话创建一个指针,连接创建时这个指针指向链表头。
接下来,每接收到一个FTP指令,就把这个指令和当前会话指针指向的链表节点中的FTP指令做比较。如果指令相同,则指针指向下一个节点,并等待下一个指令;如果指令不相同,则可以判定这个会话不是由迅雷发起的会话。而最后,如果指针指到了链表尾,就说明这个会话所发送的指令序列和链表中的指令序列是一致的,于是就可以判定这个会话是由迅雷发起的了。接下来,就断开这个链接,想封IP的话就封IP,或者严重一点的,给迅雷发送脏数据吧。
虽然这样做已经可以达到比较高的效率了,但是迅雷的指令序列不止一个,这样就要同时维护几个链表。虽然说维护多个链表并不会对效率有多大影响,但是感觉不怎么方便的样子。同时为了进一步提高效率,我弄出了一个比较像二叉树的数据结构。好吧我不知道这个数据结构之前有没有用出现过,或者说已经出现过了,但是偶不知道这个数据结构叫做什么东西。
这个数据结构是这样的,首先其基本结构就是一棵二叉树。叶子节点保存一个FTP指令和一个标志,该标志用于确定当前会话是否是迅雷,有三种状态,分别是“是迅雷”和“不是迅雷”以及“未知”。
在会话建立时,还是和链表的情况相似,给每个会话分配一个指针,指向根节点。接着,在接收到FTP指令的时候,将接收到的指令和当前指针指向的叶子节点中保存的指令相比较。对比较结果的处理就和链表的数据结构有点不同了。如果指令相同,就把会话指针指向右边的孩子;如果指令不同,就把会话指针指向左边的孩子,并继续按照此规则,将当前的FTP指令和左孩子的FTP指令相比较,直到指令相符,或者会话指针指向的叶子节点的标志位为“是迅雷”或“不是迅雷”为止。
当会话指针指向的节点的标志位为“是迅雷”或者“不是迅雷”后,就可以确定这个会话是不是迅雷的会话了。
这样设计以后,创建一个FTP指令序列的二叉树就是,右孩子是当前叶子指令的下一条指令,左孩子是状态为“不是迅雷”的空指令,然后给最后一个右孩子加上一个右孩子,设置其标记为“是迅雷”。
接着,设计出几个指令序列的二叉树以后,只要把其中一颗树的根节点作为另一棵树的根节点的左子树,组合得到一棵新的树,然后再将这棵新的树作为另一棵树的根节点的左子树,以此类推,直到所有的树都组合成一棵树,这棵树就是我们需要的FTP指令序列树了。
实际上对于迅雷的指令序列来说,现在只有两套指令序列,而且非常相似。两套指令序列相比只是有一套指令序列比另一套指令序列多了一条指令,其他部分相同。对于这样的情况,我们可以先创建指令树比较多的那套指令序列的指令树,然后把那条多出来的指令的左孩子指向右孩子,就可以用这棵指令树判断两套指令序列了。
无图无真相,无图理解困难,过几天画了图再放上来。
相关文章:
F-22's Trace
greensea 的个人主页
sky-city
极夜奁
小樱之町
没事,下学期我们又不学编译原理,拖到10月底不会破坏“提前自学”这一条件
= =v
那就10月底发给你好了
那东西多大?
cosechy@gmail.com
别想了,在桂林那,偶灭带回来
你要的话得等到10月底
貌似实际上偶很容易就在网上找到了的说,你应该也能找到。
不过质量很差就是了,就是那种低质量的原书直接扫描成pdf的那种,看起来痛苦啊
不过从前面十几页来看,那本书写得还算可以的说
居然还等到上完一遍之后才绝望。。
你以为中国的大学是学东西的地方啊?
不过话说我一直打算提前自学编译原理,就是一直没什么时间(的同时一直浪费时间)囧
哎呀因为之前灭有对天朝大学有个感性认识的说
话说偶前个学期也下载了本编译原理,不过看了十几页以后就闲置到一边去了……
顺便乱给它取个名字,trie的链表版。。。
那本数据结构上面明明还有广义表啊,教你计算复杂度啊,这些东西都是一笔带过,真怨念。对了还顺便讲了一下最基本的B树。
偶已经可以预见到编译原理能教给我们的东西有多少了,上课自己看课本吧不用听老师了
这个。。。您在研究出这个前一天才开始学算法吗。。
这不是废话。。。。
而实际上除了在那糟糕大学里上“数据结构”时候老师讲过一点链表和哈希表以及字符串比较(KMP老师声称太难了不讲)以外灭有系统地学过算法和数据结构的说。
对这大学的计算机本科教育绝望了,摊手,下学期因为受实习影响只有11周的上课时间,而那变态学校竟然把《编译原理》安排到这只有11周的时间去上,真哔——