4.2 函数调用

每一个动态模块必须定义一套函数和相关数据结构在Snort框架中运行。

4.2.1预处理

每个预处理插件都必须顶一个一下元素。而且这些元素必须要定义在全局范围中(例:spp_example.c)。

  • const int MAJOR VERSION

    预处理插件的主版本号

  • const int MINOR VERSION

    预处理插件的小版本号

  • const int BUILD VERSION

    预处理插件的编译版号

  • const char *PREPROC NAME

    预处理插件的名称

  • void DYNAMIC PREPROC SETUP(void)

    这是一个函数注册接口,用例注册预处理插件的处理函数,比如:插件名称、init,Reload,ReladVerify,ReloadSwap,ReloadSwapFree。 预处理插件必须编译成和它内部宏定义的同名库,这样,在Snort才能正确连接相应的插件。 Snort编译选项中有一项关于包配置的选项,可以通过命令PKG_CONFIG_PATH=来访问。

  • pkg-config -–cflags snort_preproc

    返回预编译处理插件的宏定义和头文件路径。

  • pkg-config –-libs snort_preproc

    返回连接预处理插件的库路径

4.2.2 检测引擎

每一个检查引擎都需要定义下面的接口

  • int LibVersion(DynamicPluginMeta*)

    返回插件的元数据

  • int InitializeEngineLib(DynamicEngineData*)

    检测引擎用来初始数据结构体的接口

以下是一些在动态规则插件中定义的和引擎插件使用的相同接口。

  • int RegisterRules(Rule **)

    该接口通过遍历规则链表,为内容匹配和正则匹配做准备,并注册字节流。

  • int DumpRules(char ,Rule *)

    该接口通过遍历规则列表中的每一条规则并且写入一下规则行为,而Snort使用它来控制规则的行为(alert,log,drop等)。

  • int ruleMatch(void p, Rule rule)

    如果一个规则没有定义自己的匹配接口,则默认使用该接口来匹配。该接口使用以下个别接口来针对不同的规则选项进行匹配和循环处理。下面的每一个函数, 如果当前数据命中规则,都会返回RULE_MATCH。

– int contentMatch(void*p, ContentInfo* content, u int8 t **cursor)
该接口用来匹配数据包的内容,检测的数据内容由ContentInfo和cursor两个参数限定。当前检测位置在递增并由
*cursor返     回。对于一个文本规则来说,with选项对应于长度,distance选项对应于偏移量。
– int checkFlow(void *p, FlowFlags *flowflags)
这个接口用来检测包的流量。
– int extractValue(void *p, ByteExtract *byteExtract, u int8 t *cursor)
该接口用来从数据包中提取字节,提取的字节起始位置由cursor指定,值保存在ByteExtract的memoryLocation字段中。
– int processFlowbits(void *p, FlowBitsInfo *flowbits)
该接口用来检测游标是否越界
– int checkValue(void *p, ByteData *byteData, u int32 t value, u int8 t *cursor)
该接口用来做字节比较
– int byteTest(void *p, ByteData *byteData, u int8 t *cursor)
它是extractValue和checkValue的包裹函数
– int byteJump(void *p, ByteData *byteData, u int8 t **cursor)
它是extractValue和setCursor的包裹函数
– int pcreMatch(void *p, PCREInfo *pcre, u int8 t **cursor)
该接口用来做内容的正则匹配,运行后,游标位置会更新
– int detectAsn1(void *p, Asn1Context *asn1, u int8 t *cursor)
该接口用来检测Asn1内容
– int checkHdrOpt(void *p, HdrOptCheck *optData)
包头检测
– int loopEval(void *p, LoopInfo *loop, u int8 t **cursor)
该接口遍历LoopInfo中的SubRule字段,同时游标位置会更新
– int preprocOptionEval(void*p, PreprocessorOption *preprocOpt, u int8 t **cursor)
该接口用来匹配预处理插件中定义的选项,同时游标位置会更新
– void setTempCursor(u int8 t **temp cursor, u int8 t **cursor)
用来保存临时游标位置,以便使用后恢复
– void revertTempCursor(u int8 t **temp cursor, u int8 t **cursor)
恢复游标位置


注意:如果你在手动写自己的规则匹配引擎的话,你会经常发现规则匹配失败。这时要多留意下规则匹配模式。这在内容和正匹配中很常见。

4.2.3 规则