📄 sp_pattern_match.c
字号:
while(--i >= 0) idx->pattern_buf[i] = toupper((unsigned char) idx->pattern_buf[i]); idx->nocase = 1;#ifdef PATTERN_FAST idx->search = setSearch;#else idx->search = uniSearchCI; make_precomp(idx);#endif return;}void PayloadSearchRawbytes(char *data, OptTreeNode * otn, int protocol){ PatternMatchData *idx; idx = (PatternMatchData *) otn->ds_list[lastType]; if(idx == NULL) { FatalError("ERROR Line %d => Please place \"content\" rules before" " rawbytes, depth, nocase or offset modifiers.\n", file_line); } while(idx->next != NULL) idx = idx->next; /* mark this as inspecting a raw pattern match rather than a decoded application buffer */ idx->rawbytes = 1; return;}void PayloadSearchDistance(char *data, OptTreeNode *otn, int protocol){ PatternMatchData *idx; idx = (PatternMatchData *) otn->ds_list[lastType]; if(idx == NULL) { FatalError("Error %s(%d) => Distance without context, please place " "\"content\" keywords before distance modifiers\n", file_name, file_line); } while(idx->next != NULL) idx = idx->next; while(isspace((int) *data)) data++; errno = 0; idx->distance = strtol(data, NULL, 10); if(errno == ERANGE) { FatalError("ERROR %s Line %d => Range problem on distance value\n", file_name, file_line); } if(idx->distance > 65535 || idx->distance < -65535) { FatalError("ERROR %s Line %d => Distance greater than max Ipv4 " "packet size\n", file_name, file_line); } DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Pattern distance = %d\n", idx->distance);); if(!SetUseDoePtr(otn)) { FatalError("%s Line %d => Unable to initialize doe_ptr\n", file_name, file_line); } return;}void PayloadSearchWithin(char *data, OptTreeNode *otn, int protocol){ PatternMatchData *idx; idx = (PatternMatchData *) otn->ds_list[lastType]; if(idx == NULL) { FatalError("Error %s(%d) => Distance without context, please place " "\"content\" keywords before distance modifiers\n", file_name, file_line); } while(idx->next != NULL) idx = idx->next; while(isspace((int) *data)) data++; errno = 0; idx->within = strtol(data, NULL, 10); if(errno == ERANGE) { FatalError("ERROR %s Line %d => Range problem on within value\n", file_name, file_line); } if(idx->within > 65535 || idx->within < -65535) { FatalError("ERROR %s Line %d => Within greater than max Ipv4 " "packet size\n", file_name, file_line); } DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Pattern within = %d\n", idx->within);); if(!SetUseDoePtr(otn)) { FatalError("%s Line %d => Unable to initialize doe_ptr\n", file_name, file_line); } return;}void PayloadSearchRegex(char *data, OptTreeNode * otn, int protocol){ PatternMatchData *idx; int i; FatalError("%s(%d) => Sorry, regex isn't supported at this time. " "This isn't new.", file_name,file_line); idx = (PatternMatchData *) otn->ds_list[lastType]; if(idx == NULL) { FatalError("%s(%d) => Please place \"content\" rules " "before regex modifiers.\n", file_name, file_line); } while(idx->next != NULL) idx = idx->next; idx->search = uniSearchREG; i = idx->pattern_size; make_precomp(idx); return;}static PatternMatchData * NewNode(OptTreeNode * otn, int type){ PatternMatchData *idx; idx = (PatternMatchData *) otn->ds_list[type]; if(idx == NULL) { if((otn->ds_list[type] = (PatternMatchData *) calloc(sizeof(PatternMatchData), sizeof(char))) == NULL) { FatalError("sp_pattern_match NewNode() calloc failed!\n"); } return otn->ds_list[type]; } else { idx = otn->ds_list[type]; while(idx->next != NULL) idx = idx->next; if((idx->next = (PatternMatchData *) calloc(sizeof(PatternMatchData), sizeof(char))) == NULL) { FatalError("sp_pattern_match NewNode() calloc failed!\n"); } return idx->next; }}/* This is an exported function that sets * PatternMatchData->use_doe so that when * * distance, within, byte_jump, byte_test are used, they can make the * pattern matching functions "keep state" WRT the current packet. */int SetUseDoePtr(OptTreeNode * otn){ PatternMatchData *idx; idx = (PatternMatchData *) otn->ds_list[PLUGIN_PATTERN_MATCH]; if(idx == NULL) {/* Visual C++ 6.0 is -supposed- to have a __FUNCTION__, however * it was just causing compile errors here. So, hack around it. */#ifdef WIN32#define __FUNCTION__ "SetUseDoePtr"#endif LogMessage("%s: No pattern match data found\n", __FUNCTION__);#ifdef WIN32#undef __FUNCTION__#endif return 0; } else { /* Walk the linked list of content checks */ while(idx->next != NULL) { idx = idx->next; } idx->use_doe = 1; return 1; }}/**************************************************************************** * * Function: GetMaxJumpSize(char *, int) * * Purpose: Find the maximum number of characters we can jump ahead * from the current offset when checking for this pattern again. * * Arguments: data => the pattern string * data_len => length of pattern string * * Returns: int => number of bytes before pattern repeats within itself * ***************************************************************************/static unsigned int GetMaxJumpSize(char *data, int data_len){ int i, j; j = 0; for ( i = 1; i < data_len; i++ ) { if ( data[j] != data[i] ) { j = 0; continue; } if ( i == (data_len - 1) ) { return (data_len - j - 1); } j++; } return data_len;}/**************************************************************************** * * Function: ParsePattern(char *) * * Purpose: Process the application layer patterns and attach them to the * appropriate rule. My god this is ugly code. * * Arguments: rule => the pattern string * * Returns: void function * ***************************************************************************/static void ParsePattern(char *rule, OptTreeNode * otn, int type){ unsigned char tmp_buf[2048]; /* got enough ptrs for you? */ char *start_ptr; char *end_ptr; char *idx; char *dummy_idx; char *dummy_end; char *tmp; char hex_buf[3]; u_int dummy_size = 0; int size; int hexmode = 0; int hexsize = 0; int pending = 0; int cnt = 0; int literal = 0; int exception_flag = 0; PatternMatchData *ds_idx; /* clear out the temp buffer */ bzero(tmp_buf, 2048); if(rule == NULL) { FatalError("%s(%d) => ParsePattern Got Null " "enclosed in quotation marks (\")!\n", file_name, file_line); } while(isspace((int)*rule)) rule++; if(*rule == '!') { exception_flag = 1; } /* find the start of the data */ start_ptr = index(rule, '"'); if(start_ptr == NULL) { FatalError("%s(%d) => Content data needs to be " "enclosed in quotation marks (\")!\n", file_name, file_line); } /* move the start up from the beggining quotes */ start_ptr++; /* find the end of the data */ end_ptr = strrchr(start_ptr, '"'); if(end_ptr == NULL) { FatalError("%s(%d) => Content data needs to be enclosed " "in quotation marks (\")!\n", file_name, file_line); } /* Move the null termination up a bit more */ *end_ptr = '\0'; /* Is there anything other than whitespace after the trailing * double quote? */ tmp = end_ptr + 1; while (*tmp != '\0' && isspace ((int)*tmp)) tmp++; if (strlen (tmp) > 0) { FatalError("%s(%d) => Bad data (possibly due to missing semicolon) " "after trailing double quote.", file_name, file_line, end_ptr + 1); } /* how big is it?? */ size = end_ptr - start_ptr; /* uh, this shouldn't happen */ if(size <= 0) { FatalError("%s(%d) => Bad pattern length!\n", file_name, file_line); } /* set all the pointers to the appropriate places... */ idx = start_ptr; /* set the indexes into the temp buffer */ dummy_idx = tmp_buf; dummy_end = (dummy_idx + size); /* why is this buffer so small? */ bzero(hex_buf, 3); memset(hex_buf, '0', 2); /* BEGIN BAD JUJU..... */ while(idx < end_ptr) { DEBUG_WRAP(DebugMessage(DEBUG_PARSER, "processing char: %c\n", *idx);); switch(*idx) { case '|': DEBUG_WRAP(DebugMessage(DEBUG_PARSER, "Got bar... ");); if(!literal) { DEBUG_WRAP(DebugMessage(DEBUG_PARSER, "not in literal mode... ");); if(!hexmode) { DEBUG_WRAP(DebugMessage(DEBUG_PARSER, "Entering hexmode\n");); hexmode = 1; } else { DEBUG_WRAP(DebugMessage(DEBUG_PARSER, "Exiting hexmode\n");); /* ** Hexmode is not even. */ if(!hexsize || hexsize % 2) { FatalError("%s(%d) => Content hexmode argument has invalid " "number of hex digits. The argument '%s' must " "contain a full even byte string.\n", file_name, file_line, start_ptr); } hexmode = 0; pending = 0; } if(hexmode) hexsize = 0; } else { DEBUG_WRAP(DebugMessage(DEBUG_PARSER, "literal set, Clearing\n");); literal = 0; tmp_buf[dummy_size] = start_ptr[cnt]; dummy_size++; } break; case '\\': DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Got literal char... ");); if(!literal) { /* Make sure the next char makes this a valid * escape sequence. */ if (idx [1] != '\0' && strchr ("\\\":;", idx [1]) == NULL) { FatalError("%s(%d) => bad escape sequence starting " "with \"%s\". ", file_name, file_line, idx); } DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Setting literal\n");); literal = 1; } else { DEBUG_WRAP(DebugMessage(DEBUG_PATTERN_MATCH, "Clearing literal\n");); tmp_buf[dummy_size] = start_ptr[cnt]; literal = 0; dummy_size++; } break; case '"': if (!literal) { FatalError("%s(%d) => Non-escaped " " '\"' character!\n", file_name, file_line); } /* otherwise process the character as default */ default: if(hexmode) { if(isxdigit((int) *idx)) { hexsize++; if(!pending) { hex_buf[0] = *idx; pending++; } else { hex_buf[1] = *idx; pending--; if(dummy_idx < dummy_end) { tmp_buf[dummy_size] = (u_char) strtol(hex_buf, (char **) NULL, 16)&0xFF; dummy_size++; bzero(hex_buf, 3); memset(hex_buf, '0', 2); } else { FatalError("ParsePattern() dummy " "buffer overflow, make a smaller " "pattern please! (Max size = 2048)\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -