📄 sp_pattern_match.c
字号:
/* we want to check only depth bytes anyway */ int sub_depth = dlen - pmd->offset; if((sub_depth > 0) && (sub_depth >= (int)pmd->pattern_size)) { return sub_depth; } else { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Pattern Match failed -- sub_depth: %d < " "(int)pmd->pattern_size: %d!\n", sub_depth, (int)pmd->pattern_size);); return -1; } } else { if(pmd->depth && (dlen - pmd->offset > pmd->depth)) { return pmd->depth; } else { return dlen - pmd->offset; } }}/* * Figure out how deep the into the packet from the base_ptr we can go * * base_ptr = the offset into the payload relative to the last match plus the offset * contained within the current pmd * * dlen = amount of data in the packet from the base_ptr to the end of the packet * * pmd = the patterm match data struct for this test */static inline int computeWithin(int dlen, PatternMatchData *pmd){ /* do we want to check more bytes than there are in the buffer? */ if(pmd->within > dlen) { /* should we just return -1 here since the data might actually be within * the stream but not the current packet's payload? */ /* if the buffer size is greater than the size of the pattern to match */ if(dlen >= (int)pmd->pattern_size) { /* return the size of the buffer */ return dlen; } else { /* failed, pattern size is greater than number of bytes in the buffer */ return -1; } } /* the within vaule is in range of the number of buffer bytes */ return pmd->within;}static int uniSearchREG(char * data, int dlen, PatternMatchData * pmd){ int depth = computeDepth(dlen, pmd); /* int distance_adjustment = 0; * int depth_adjustment = 0; */ int success = 0; if (depth < 0) return 0; /* XXX DESTROY ME */ /*success = mSearchREG(data + pmd->offset + distance_adjustment, depth_adjustment!=0?depth_adjustment:depth, pmd->pattern_buf, pmd->pattern_size, pmd->skip_stride, pmd->shift_stride);*/ return success;}/* * case sensitive search * * data = ptr to buffer to search * dlen = distance to the back of the buffer being tested, validated * against offset + depth before function entry (not distance/within) * pmd = pointer to pattern match data struct */static int uniSearch(char *data, int dlen, PatternMatchData *pmd){ return uniSearchReal(data, dlen, pmd, 0);}/* * case insensitive search * * data = ptr to buffer to search * dlen = distance to the back of the buffer being tested, validated * against offset + depth before function entry (not distance/within) * pmd = pointer to pattern match data struct */static int uniSearchCI(char *data, int dlen, PatternMatchData *pmd){ return uniSearchReal(data, dlen, pmd, 1);}/* * single search function. * * data = ptr to buffer to search * dlen = distance to the back of the buffer being tested, validated * against offset + depth before function entry (not distance/within) * pmd = pointer to pattern match data struct * nocase = 0 means case sensitve, 1 means case insensitive */ static int uniSearchReal(char *data, int dlen, PatternMatchData *pmd, int nocase){ /* * in theory computeDepth doesn't need to be called because the * depth + offset adjustments have been made by the calling function */ int depth = dlen; int old_depth = dlen; int success = 0; char *start_ptr = data; char *end_ptr = data + dlen; char *base_ptr = start_ptr; DEBUG_WRAP(char *hexbuf;); if(pmd->use_doe != 1) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "NOT Using Doe Ptr\n");); doe_ptr = NULL; /* get rid of all our pattern match state */ } /* check to see if we've got a stateful start point */ if(doe_ptr) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Using Doe Ptr\n");); base_ptr = doe_ptr; depth = dlen - ((char *) doe_ptr - data); } else { base_ptr = start_ptr; depth = dlen; } /* if we're using a distance call */ if(pmd->distance) { /* set the base pointer up for the distance */ base_ptr += pmd->distance; depth -= pmd->distance; } else /* otherwise just use the offset (validated by calling function) */ { base_ptr += pmd->offset; depth -= pmd->offset; } if(pmd->within != 0) { /* * calculate the "real" depth based on the current base and available * number of bytes in the buffer * * this should account for the current base_ptr as it relates to * the back of the buffer being tested */ old_depth = depth; depth = computeWithin(depth, pmd); DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Changing Depth from %d to %d\n", old_depth, depth);); } /* make sure we and in range */ if(!inBounds(start_ptr, end_ptr, base_ptr)) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "returning because base_ptr" " is out of bounds start_ptr: %p end: %p base: %p\n", start_ptr, end_ptr, base_ptr);); return 0; } if(depth < 0) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "returning because depth is negative (%d)\n", depth);); return 0; } if(depth > dlen) { /* if offsets are negative but somehow before the start of the packet, let's make sure that we get everything going straight */ depth = dlen; } if((pmd->depth > 0) && (depth > pmd->depth)) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Setting new depth to %d from %d\n", pmd->depth, depth);); depth = pmd->depth; } /* make sure we and in range */ if(!inBounds(start_ptr, end_ptr, base_ptr + depth - 1)) { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "returning because base_ptr + depth - 1" " is out of bounds start_ptr: %p end: %p base: %p\n", start_ptr, end_ptr, base_ptr);); return 0; }#ifdef DEBUG assert(depth <= old_depth); DebugMessage(DEBUG_PATTERN_MATCH, "uniSearchReal:\n "); hexbuf = hex(pmd->pattern_buf, pmd->pattern_size); DebugMessage(DEBUG_PATTERN_MATCH, " p->data: %p\n doe_ptr: %p\n " "base_ptr: %p\n depth: %d\n searching for: %s\n", data, doe_ptr, base_ptr, depth, hexbuf); free(hexbuf);#endif /* DEBUG */ if(nocase) { success = mSearchCI(base_ptr, depth, pmd->pattern_buf, pmd->pattern_size, pmd->skip_stride, pmd->shift_stride); } else { success = mSearch(base_ptr, depth, pmd->pattern_buf, pmd->pattern_size, pmd->skip_stride, pmd->shift_stride); }#ifdef DEBUG if(success) { DebugMessage(DEBUG_PATTERN_MATCH, "matched, doe_ptr: %p (%d)\n", doe_ptr, ((char *)doe_ptr - data)); }#endif return success;}static void make_precomp(PatternMatchData * idx){ free(idx->skip_stride); free(idx->shift_stride); idx->skip_stride = make_skip(idx->pattern_buf, idx->pattern_size); idx->shift_stride = make_shift(idx->pattern_buf, idx->pattern_size);}void PayloadSearchListInit(char *data, OptTreeNode * otn, int protocol){ char *sptr; char *eptr; lastType = PLUGIN_PATTERN_MATCH_OR; DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "In PayloadSearchListInit()\n");); /* get the path/file name from the data */ while(isspace((int) *data)) data++; /* grab everything between the starting " and the end one */ sptr = index(data, '"'); eptr = strrchr(data, '"'); if(sptr != NULL && eptr != NULL) { /* increment past the first quote */ sptr++; /* zero out the second one */ *eptr = 0; } else { sptr = data; } /* read the content keywords from the list file */ ParseContentListFile(sptr, otn, protocol); /* link the plugin function in to the current OTN */ AddOptFuncToList(CheckORPatternMatch, otn); return;}void PayloadSearchInit(char *data, OptTreeNode * otn, int protocol){ OptFpList *fpl; PatternMatchData *pmd; lastType = PLUGIN_PATTERN_MATCH; DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "In PayloadSearchInit()\n");); /* whack a new node onto the list */ pmd = NewNode(otn, PLUGIN_PATTERN_MATCH); /* set up the pattern buffer */ ParsePattern(data, otn, PLUGIN_PATTERN_MATCH); /* link the plugin function in to the current OTN */ fpl = AddOptFuncToList(CheckANDPatternMatch, otn); fpl->context = pmd; DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "OTN function PatternMatch Added to rule!\n"););}void PayloadSearchUri(char *data, OptTreeNode * otn, int protocol){ PatternMatchData * pmd; OptFpList *fpl; lastType = PLUGIN_PATTERN_MATCH_URI; DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "In PayloadSearchUri()\n");); /* whack a new node onto the list */ pmd = NewNode(otn, PLUGIN_PATTERN_MATCH_URI); /* set up the pattern buffer */ ParsePattern(data, otn, PLUGIN_PATTERN_MATCH_URI);#ifdef PATTERN_FAST pmd->search = uniSearch; make_precomp(pmd);#endif /* link the plugin function in to the current OTN */ fpl = AddOptFuncToList(CheckUriPatternMatch, otn); fpl->context = pmd; DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "OTN function PatternMatch Added to rule!\n"););}void PayloadSearchOffset(char *data, OptTreeNode * otn, int protocol){ PatternMatchData *idx; DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "In PayloadSearch()\n");); idx = otn->ds_list[lastType]; if(idx == NULL) { FatalError("%s(%d) => Please place \"content\" rules before " "depth, nocase or offset modifiers.\n", file_name, file_line); } while(idx->next != NULL) idx = idx->next; while(isspace((int) *data)) data++; errno = 0; idx->offset = strtol(data, NULL, 10); if(errno == ERANGE) { FatalError("ERROR %s Line %d => Range problem on offset value\n", file_name, file_line); } if(idx->offset > 65535 || idx->offset < -65535) { FatalError("ERROR %s Line %d => Offset greater than max Ipv4 " "packet size\n", file_name, file_line); } DEBUG_WRAP(DebugMessage(DEBUG_PARSER, "Pattern offset = %d\n", idx->offset);); return;}void PayloadSearchDepth(char *data, OptTreeNode * otn, int protocol){ PatternMatchData *idx; idx = (PatternMatchData *) otn->ds_list[lastType]; if(idx == NULL) { FatalError("ERROR %s Line %d => Please place \"content\" rules " "before depth, nocase or offset modifiers.\n", file_name, file_line); } while(idx->next != NULL) idx = idx->next; while(isspace((int) *data)) data++; errno = 0; idx->depth = strtol(data, NULL, 10); if(errno == ERANGE) { FatalError("ERROR %s Line %d => Range problem on depth value\n", file_name, file_line); } if(idx->depth > 65535 || idx->depth < -65535) { FatalError("ERROR %s Line %d => Depth greater than max Ipv4 " "packet size\n", file_name, file_line); } /* check to make sure that this the depth allows this rule to fire */ if(idx->depth != 0 && idx->depth < (int)idx->pattern_size) { FatalError("%s(%d) => The depth(%d) is less than the size of the content(%u)!\n", file_name, file_line, idx->depth, idx->pattern_size); } DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Pattern depth = %d\n", idx->depth);); return;}void PayloadSearchNocase(char *data, OptTreeNode * otn, int protocol){ PatternMatchData *idx; int i; idx = (PatternMatchData *) otn->ds_list[lastType]; if(idx == NULL) { FatalError("(%s)%d => Please place \"content\" rules before" " depth, nocase or offset modifiers.\n", file_name, file_line); } while(idx->next != NULL) idx = idx->next; i = idx->pattern_size;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -