博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
snort 源码分析之 模式匹配引擎接口 SearchAPI 源码分析(AC算法)
阅读量:2792 次
发布时间:2019-05-13

本文共 5302 字,大约阅读时间需要 17 分钟。

/* *  基于snort-2.9.5的源码进行分析 *  src/preprocessors/str_search.h|.c *//* * t_search 结构用于管理SearchAPI对象 */typedef struct tag_search{    /*     * mpse 由mpseNew函数创建     */    void *mpse;    /*     *  所有模式串中最长串的长度     */    unsigned int max_len;    /*     * 该引擎在创建时就默认设置为1     */    int in_use;} t_search;typedef struct _search_api{    int (*search_init)(unsigned int);    int (*search_reinit)(unsigned int);    void (*search_free)(void);    void (*search_add)(unsigned int, const char *, unsigned int, int);    void (*search_prep)(unsigned int);    int (*search_find)(unsigned int, const char *, unsigned int, int, MatchFunction);     /* 6/1/06*/    void (*search_free_id)(unsigned id);        int (*search_get_handle)(void);    int (*search_put_handle)(unsigned int);    /*     * 创建多模式匹配引擎接口函数       */    void * (*search_instance_new)(void);    /*     * 释放多模式匹配引擎接口函数       */    void   (*search_instance_free)(void * instance);    /*     * 增加模式串接口函数       */    void   (*search_instance_add) (void * instance, const char *s, unsigned int s_len, int s_id);    /*     * 模式串预处理接口函数   :比如 创建trie 和构建自动机     */    void   (*search_instance_prep)(void * instance );    /*     * 匹配函数   :MatchFunction:匹配成功后的回调函数,可执行一些相关操作     */    int    (*search_instance_find)(void * instance, const char *s, unsigned int s_len, int confine, MatchFunction);     } SearchAPI;
/* API exported by this module */SearchAPI searchAPI ={    SearchInit,    SearchReInit,    SearchFree,    SearchAdd,    SearchPrepPatterns,    SearchFindString,    SearchFreeId,    SearchGetHandle,    SearchPutHandle,    /*     * 创建引擎的函数     */    SearchInstanceNew,    /*     * 释放引擎的函数     */    SearchInstanceFree,    /*     * 增加模式串函数     */    SearchInstanceAdd,    /*     * 引擎预处理函数:构建trie 自动机     */    SearchInstancePrepPatterns,    /*     * 搜索函数     */    SearchInstanceFindString,};SearchAPI *search_api = &searchAPI;

 

接下来分析上面提及的那几个函数的实现

1:创建对象

/* * 创建mpse管理对象和mpse对象 */void *  SearchInstanceNew(void){    /* 创建管理对象 */    t_search * search = malloc(sizeof(t_search));    if( !search )        return NULL;    /* 创建mpse对象, 通过MPSE_AC_BNFA宏设置,多模式匹配使用的算法*/    search->mpse  = mpseNew(MPSE_AC_BNFA, MPSE_DONT_INCREMENT_GLOBAL_COUNT,                            NULL, NULL, NULL);    if (search-> mpse == NULL )    {        free(search);        return NULL;    }    search->in_use=1;    search->max_len=0;    return search;}

2:释放对象

void SearchInstanceFree( void * instance ){    t_search * search = (t_search*)instance;    if( instance )    {        mpseFree( search->mpse );        free( instance );    }}

3:增加模式串

/* *  instance : 管理对象 *  pat : 模式串 *  pat_len : 模式串长度 *  id : 模式串所在模式串数组中的索引,例如 html_patterns */void SearchInstanceAdd( void*instance, const char *pat, unsigned int pat_len, int id){    t_search * search = (t_search*)instance;    /* 添加模式串至mpse引擎中*/    if( search && search->mpse )        mpseAddPattern( search->mpse, (void *)pat, pat_len, 1, 0, 0, 0, (void *)(long) id, 0);    /* 更新模式串的最大长度*/    if ( search && pat_len > search->max_len )         search->max_len = pat_len;}

4:预处理模式串(生成自动机)

/* * instance : 管理对象 */void SearchInstancePrepPatterns(void * instance){    t_search * search = (t_search*)instance;    if( search && search->mpse )    {        /* 在调用完SearchInstanceAdd后,调用本函数进行模式预处理编译*/        mpsePrepPatterns( search->mpse, NULL, NULL);    }}

5:搜索查找

/* * 搜索函数 * instance : 管理对象 * str :源串 * str_len : 源串长度 * confine : 1 表示更新模式串的最大长度 * Match : 匹配成功后的回调函数 */int  SearchInstanceFindString(void * instance,                              const char *str,                              unsigned int str_len,                              int confine,                              int (*Match) (void *, void *, int, void *, void *)){    int num;    int start_state = 0;    t_search * search = (t_search*)instance;    if ( confine && (search->max_len > 0) )    {        if ( search->max_len < str_len )        {            str_len = search->max_len;        }    }    num = mpseSearch( search->mpse, (unsigned char*)str, str_len, Match, (void *) str,            &start_state);    return num;}

 

以上介绍了模式匹配引擎接口的几个关键函数。接下来结合snort源代码分析如何使用这些接口

以html_patterns为例进行分析:

/* * 结构定义  */typedef struct _HiSearchToken               {       /* 模式串*/    char *name;    /* 串长度*/    int   name_len;    /* 串所在数组中的索引*/    int   search_id;} HiSearchToken;

a:创建管理对象,并添加串数组,编译

/* 管理对象*/void *hi_htmltype_search_mpse = NULL;...void HI_SearchInit(void){...    /* 创建 管理对象 实际调用SearchInstanceNew*/    hi_htmltype_search_mpse = search_api->search_instance_new();    if (hi_htmltype_search_mpse == NULL)    {        FatalError("%s(%d) Could not allocate memory for HTTP 

b:搜索

int hi_server_norm(HI_SESSION *Session, HttpSessionData *hsd){...     /* 查找过程, 如果成功调用HI_SearchStrFound 善后处理*/            script_found = search_api->search_instance_find(hi_htmltype_search_mpse, (const char *)js_start, (angle_bracket-js_start), 0 , HI_SearchStrFound); ...}/*  返回1 表示 搜索成功*/int HI_SearchStrFound(void *id, void *unused, int index, void *data, void *unused2){    int search_id = (int)(uintptr_t)id;    hi_search_info.id = search_id;    hi_search_info.index = index;    hi_search_info.length = hi_current_search[search_id].name_len;    /* Returning non-zero stops search, which is okay since we only look for one at a time */    return 1;}

以上就分析完了snort的模式匹配引擎接口的使用

可以参考中的进行编写自己的测试程序进行使用

转载地址:http://xvtmd.baihongyu.com/

你可能感兴趣的文章
面试题11:数值的整数次方
查看>>
面试题12:打印1到最大的N位数
查看>>
面试题13:在O(1)时间删除链表结点
查看>>
面试题14 :调整数组顺序使奇数位于偶数前面
查看>>
面试题15 :链表中倒数第k个结点
查看>>
面试题16 :反转链表
查看>>
二、JSP之JSP内置对象
查看>>
排序之冒泡排序
查看>>
面试题34:丑数
查看>>
类加载机制
查看>>
浮点数的秘密
查看>>
类型转换
查看>>
变量与函数的综合示例
查看>>
开发中的辅助工具
查看>>
ARM相关
查看>>
ARM体系结构要点
查看>>
GDB简介
查看>>
ARM的37个寄存器
查看>>
网络层服务
查看>>
协处理器和协处理器指令
查看>>