diff options
author | Martin Mathieson <martin.r.mathieson@googlemail.com> | 2017-02-19 02:32:04 -0800 |
---|---|---|
committer | Martin Mathieson <martin.r.mathieson@googlemail.com> | 2017-02-21 20:03:45 +0000 |
commit | b9851c740836760ab36c4862f82f3f8cc83fde27 (patch) | |
tree | b07689270ab5202b657d3bdfd1a4de6c443377d7 /epan/dissectors/packet-snort.c | |
parent | 012a179785abada629fa324652755c6acb51be74 (diff) |
Snort: use GRegex to find pcre matches
Change-Id: Ie08bc1f3139ebe5564365e662f89257ad8d5b129
Reviewed-on: https://code.wireshark.org/review/20177
Petri-Dish: Martin Mathieson <martin.r.mathieson@googlemail.com>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Martin Mathieson <martin.r.mathieson@googlemail.com>
Diffstat (limited to 'epan/dissectors/packet-snort.c')
-rw-r--r-- | epan/dissectors/packet-snort.c | 65 |
1 files changed, 61 insertions, 4 deletions
diff --git a/epan/dissectors/packet-snort.c b/epan/dissectors/packet-snort.c index 567c9d0f5c..991895c6cb 100644 --- a/epan/dissectors/packet-snort.c +++ b/epan/dissectors/packet-snort.c @@ -289,6 +289,57 @@ static gboolean content_compare_case_insensitive(const guint8* memory, const cha } +/* Move through the bytes of the tvbuff, looking for a match against the + * regexp from the given content. + */ +static gboolean look_for_pcre(content_t *content, tvbuff_t *tvb _U_, guint start_offset _U_, guint *match_offset _U_, guint *match_length _U_) +{ + /* Create a regex object for the pcre in the content. */ + GRegex *regex; + GMatchInfo *match_info; + gboolean match_found = FALSE; + + /* Make sure pcre string is ready for regex library. */ + if (!content_convert_pcre_for_regex(content)) { + return FALSE; + } + + /* Copy remaining bytes into NULL-terminated string. */ + int length_remaining = tvb_captured_length_remaining(tvb, start_offset); + gchar *string = (gchar*)g_malloc(length_remaining + 1); + tvb_memcpy(tvb, (void*)string, start_offset, length_remaining); + string[length_remaining] = '\0'; + + /* Create regex */ + /* For pcre, translated_str already has / /[modifiers] removed.. */ + regex = g_regex_new(content->translated_str, + content->pcre_case_insensitive ? G_REGEX_CASELESS : (GRegexCompileFlags)0, + (GRegexMatchFlags)0, NULL); + + /* Lookup PCRE match */ + g_regex_match(regex, string, (GRegexMatchFlags)0, &match_info); + /* Only first match needed */ + /* TODO: need to restart at any NULL before the final end? */ + if (g_match_info_matches(match_info)) { + gint start_pos, end_pos; + + /* Find out where the match is */ + g_match_info_fetch_pos(match_info, + 0, /* match_num */ + &start_pos, &end_pos); + + *match_offset = start_offset + start_pos; + *match_length = end_pos - start_pos; + match_found = TRUE; + } + + g_match_info_free(match_info); + g_regex_unref(regex); + g_free(string); + + return match_found; +} + /* Move through the bytes of the tvbuff, looking for a match against the expanded binary contents of this content object. */ @@ -303,14 +354,14 @@ static gboolean look_for_content(content_t *content, tvbuff_t *tvb, guint start_ for (guint m=start_offset; m <= (tvb_len-converted_content_length); m++) { const guint8 *ptr = tvb_get_ptr(tvb, m, converted_content_length); if (content->nocase) { - if (content_compare_case_insensitive(ptr, content->binary_str, content->translated_length)) { + if (content_compare_case_insensitive(ptr, content->translated_str, content->translated_length)) { *match_offset = m; *match_length = content->translated_length; return TRUE; } } else { - if (content_compare_case_sensitive(ptr, content->binary_str, content->translated_length)) { + if (content_compare_case_sensitive(ptr, content->translated_str, content->translated_length)) { *match_offset = m; *match_length = content->translated_length; return TRUE; @@ -342,7 +393,12 @@ static gboolean get_content_match(Alert_t *alert, guint content_idx, content = &(rule->contents[content_idx]); /* Look for content match in the packet */ - return look_for_content(content, tvb, content_start_match, match_offset, match_length); + if (content->content_type == Pcre) { + return look_for_pcre(content, tvb, content_start_match, match_offset, match_length); + } + else { + return look_for_content(content, tvb, content_start_match, match_offset, match_length); + } } @@ -843,7 +899,7 @@ static void snort_show_alert(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo case Pcre: content_hf_item = hf_snort_pcre; content_text_template = "Pcre: \"%s\""; - attempt_match = FALSE; + attempt_match = TRUE; break; default: continue; @@ -864,6 +920,7 @@ static void snort_show_alert(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo offset_to_add = (content_last_match_end-content_start_match) + rule->contents[n].distance; } + /* Now actually look for match from calculated position */ /* TODO: could take 'depth' and 'within' into account to limit extent of search, but OK if just trying to verify what Snort already found. */ |