本文共 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/