suricata
detect-bytejump.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2020 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \file
20  *
21  * \author Brian Rectanus <brectanu@gmail.com>
22  *
23  * Implements byte_jump keyword.
24  */
25 
26 #include "suricata-common.h"
27 #include "decode.h"
28 #include "detect.h"
29 #include "detect-parse.h"
30 #include "detect-engine.h"
31 #include "detect-engine-buffer.h"
32 #include "app-layer.h"
33 
34 #include "detect-byte.h"
35 #include "detect-byte-extract.h"
36 #include "detect-bytejump.h"
37 #include "detect-content.h"
38 #include "detect-uricontent.h"
39 
40 #include "util-byte.h"
41 #include "util-unittest.h"
42 #include "util-debug.h"
43 #include "util-validate.h"
44 #include "detect-pcre.h"
45 #include "detect-engine-build.h"
46 
47 /**
48  * \brief Regex for parsing our options
49  */
50 #define PARSE_REGEX "^\\s*" \
51  "([^\\s,]+\\s*,\\s*[^\\s,]+)" \
52  "(?:\\s*,\\s*((?:multiplier|post_offset)\\s+[^\\s,]+|[^\\s,]+))?" \
53  "(?:\\s*,\\s*((?:multiplier|post_offset)\\s+[^\\s,]+|[^\\s,]+))?" \
54  "(?:\\s*,\\s*((?:multiplier|post_offset)\\s+[^\\s,]+|[^\\s,]+))?" \
55  "(?:\\s*,\\s*((?:multiplier|post_offset)\\s+[^\\s,]+|[^\\s,]+))?" \
56  "(?:\\s*,\\s*((?:multiplier|post_offset)\\s+[^\\s,]+|[^\\s,]+))?" \
57  "(?:\\s*,\\s*((?:multiplier|post_offset)\\s+[^\\s,]+|[^\\s,]+))?" \
58  "(?:\\s*,\\s*((?:multiplier|post_offset)\\s+[^\\s,]+|[^\\s,]+))?" \
59  "(?:\\s*,\\s*((?:multiplier|post_offset)\\s+[^\\s,]+|[^\\s,]+))?" \
60  "(?:\\s*,\\s*((?:multiplier|post_offset)\\s+[^\\s,]+|[^\\s,]+))?" \
61  "\\s*$"
62 
63 static DetectParseRegex parse_regex;
64 
65 static DetectBytejumpData *DetectBytejumpParse(
66  DetectEngineCtx *de_ctx, const char *optstr, char **nbytes, char **offset);
67 static int DetectBytejumpSetup(DetectEngineCtx *de_ctx, Signature *s, const char *optstr);
68 static void DetectBytejumpFree(DetectEngineCtx*, void *ptr);
69 #ifdef UNITTESTS
70 static void DetectBytejumpRegisterTests(void);
71 #endif
72 
74 {
75  sigmatch_table[DETECT_BYTEJUMP].name = "byte_jump";
76  sigmatch_table[DETECT_BYTEJUMP].desc = "allow the ability to select a <num of bytes> from an <offset> and move the detection pointer to that position";
77  sigmatch_table[DETECT_BYTEJUMP].url = "/rules/payload-keywords.html#byte-jump";
79  sigmatch_table[DETECT_BYTEJUMP].Setup = DetectBytejumpSetup;
80  sigmatch_table[DETECT_BYTEJUMP].Free = DetectBytejumpFree;
81 #ifdef UNITTESTS
82  sigmatch_table[DETECT_BYTEJUMP].RegisterTests = DetectBytejumpRegisterTests;
83 #endif
84  DetectSetupParseRegexes(PARSE_REGEX, &parse_regex);
85 }
86 
87 /* 23 - This is the largest string (octal, with a zero prefix) that
88  * will not overflow uint64_t. The only way this length
89  * could be over 23 and still not overflow is if it were zero
90  * prefixed and we only support 1 byte of zero prefix for octal.
91  *
92  * "01777777777777777777777" = 0xffffffffffffffff
93  *
94  * 8 - Without string, the maximum byte extract count is 8.
95  */
96 static inline bool DetectBytejumpValidateNbytesOnly(const DetectBytejumpData *data, int32_t nbytes)
97 {
98  return (data->flags & DETECT_BYTEJUMP_STRING && nbytes <= 23) || (nbytes <= 8);
99 }
100 
101 static bool DetectBytejumpValidateNbytes(const DetectBytejumpData *data, int32_t nbytes)
102 {
103  if (!DetectBytejumpValidateNbytesOnly(data, nbytes)) {
104  if (data->flags & DETECT_BYTEJUMP_STRING) {
105  /* 23 - This is the largest string (octal, with a zero prefix) that
106  * will not overflow uint64_t. The only way this length
107  * could be over 23 and still not overflow is if it were zero
108  * prefixed and we only support 1 byte of zero prefix for octal.
109  *
110  * "01777777777777777777777" = 0xffffffffffffffff
111  */
112  if (nbytes > 23) {
113  SCLogError("Cannot test more than 23 bytes "
114  "with \"string\"");
115  }
116  } else {
117  if (nbytes > 8) {
118  SCLogError("Cannot test more than 8 bytes "
119  "without \"string\"");
120  }
121  }
122  return false;
123  }
124 
125  return true;
126 }
127 
128 /** \brief Byte jump match function
129  * \param det_ctx thread detect engine ctx
130  * \param s signature
131  * \param m byte jump sigmatch
132  * \param payload ptr to the payload
133  * \param payload_len length of the payload
134  * \retval true match
135  * \retval false no match
136  */
138  const SigMatchCtx *ctx, const uint8_t *payload, uint32_t payload_len, uint16_t flags,
139  int32_t nbytes, int32_t offset)
140 {
141  SCEnter();
142 
143  const DetectBytejumpData *data = (const DetectBytejumpData *)ctx;
144  const uint8_t *ptr = NULL;
145  int32_t len = 0;
146  uint64_t val = 0;
147  int extbytes;
148 
149  if (payload_len == 0) {
150  SCReturnBool(false);
151  }
152 
153  /* Validate the number of bytes we are testing
154  * If the validation is successful, we know that
155  * it contains a value <= 23. Thus, we can
156  * safely cast it when extracting bytes
157  */
158  if (data->flags & DETECT_BYTEJUMP_NBYTES_VAR) {
159  if (!DetectBytejumpValidateNbytesOnly(data, nbytes)) {
160  SCLogDebug("Invalid byte_jump nbytes "
161  "seen in byte_jump - %d",
162  nbytes);
163  SCReturnBool(false);
164  }
165  }
166 
167  /* Calculate the ptr value for the bytejump and length remaining in
168  * the packet from that point.
169  */
170  ptr = payload + offset;
171  len = payload_len - offset;
173  ptr += det_ctx->buffer_offset;
174  len -= det_ctx->buffer_offset;
175 
176  SCLogDebug("[relative] after: ptr %p [len %d]", ptr, len);
177 
178  /* No match if there is no relative base */
179  if (ptr == NULL || (nbytes && len <= 0)) {
180  SCReturnBool(false);
181  }
182  }
183 
184  /* Verify the to-be-extracted data is within the packet */
185  if (ptr < payload || nbytes > len) {
186  SCLogDebug("Data not within payload "
187  "pkt=%p, ptr=%p, len=%" PRIi32 ", nbytes=%" PRIi32,
188  payload, ptr, len, nbytes);
189  SCReturnBool(false);
190  }
191 
192  /* Extract the byte data */
194  extbytes = ByteExtractStringUint64(&val, data->base, nbytes, (const char *)ptr);
195  if(extbytes <= 0) {
196  SCLogDebug("error extracting %d bytes of string data: %d", nbytes, extbytes);
197  SCReturnBool(false);
198  }
199  }
200  else {
202  extbytes = ByteExtractUint64(&val, endianness, (uint16_t)nbytes, ptr);
203  if (extbytes != nbytes) {
204  SCLogDebug("error extracting %d bytes of numeric data: %d", nbytes, extbytes);
205  SCReturnBool(false);
206  }
207  }
208 
209  SCLogDebug("VAL: (%" PRIu64 " x %" PRIu32 ") + %" PRIi32 " + %" PRId32, val, data->multiplier,
210  extbytes, data->post_offset);
211 
212  /* Adjust the jump value based on flags */
213  val *= data->multiplier;
215  if ((val % 4) != 0) {
216  val += 4 - (val % 4);
217  }
218  }
219  val += data->post_offset;
220  SCLogDebug("val: %" PRIi64 " post_offset: %" PRIi32, val, data->post_offset);
221 
222  const uint8_t *jumpptr;
223  /* Calculate the jump location */
225  jumpptr = payload + (int64_t)val;
226  SCLogDebug("NEWVAL: payload %p + %" PRIi64 " = %p", payload, (int64_t)val, jumpptr + val);
227  } else if (flags & DETECT_BYTEJUMP_END) {
228  jumpptr = payload + payload_len + (int64_t)val;
229  SCLogDebug(
230  "NEWVAL: payload %p + %" PRIu32 " + %" PRIi64, payload, payload_len, (int64_t)val);
231  } else {
232  jumpptr = ptr + (int64_t)val + extbytes;
233  SCLogDebug("NEWVAL: ptr %p + %" PRIi64 " = %p", ptr, val, jumpptr);
234  }
235 
236  /* Validate that the jump location is still in the packet
237  * \todo Should this validate it is still in the *payload*?
238  */
239  if (jumpptr < payload) {
240  jumpptr = payload;
241  SCLogDebug("jump location is before buffer start; resetting to buffer start");
242  } else if (jumpptr > (payload + payload_len)) {
243  SCLogDebug("Jump location (%" PRIu64 ") is not within payload (%" PRIu32 ")",
244  payload_len + val, payload_len);
245  SCReturnBool(false);
246  }
247 
248 #ifdef DEBUG
249  if (SCLogDebugEnabled()) {
250  const uint8_t *sptr = (flags & DETECT_BYTEJUMP_BEGIN) ? payload : ptr;
251  SCLogDebug("jumping %" PRId64 " bytes from %p (%08x)", val, sptr, (int)(sptr - payload));
252  }
253 #endif /* DEBUG */
254 
255  /* Adjust the detection context to the jump location. */
256  DEBUG_VALIDATE_BUG_ON(jumpptr < payload);
257  det_ctx->buffer_offset = (uint32_t)(jumpptr - payload);
258 
259  SCReturnBool(true);
260 }
261 
262 static DetectBytejumpData *DetectBytejumpParse(
263  DetectEngineCtx *de_ctx, const char *optstr, char **nbytes_str, char **offset)
264 {
265  DetectBytejumpData *data = NULL;
266  char args[10][64];
267  int res = 0;
268  size_t pcre2len;
269  int numargs = 0;
270  int i = 0;
271  uint32_t nbytes = 0;
272  char *str_ptr;
273  char *end_ptr;
274  pcre2_match_data *match = NULL;
275 
276  memset(args, 0x00, sizeof(args));
277 
278  /* Execute the regex and populate args with captures. */
279  int ret = DetectParsePcreExec(&parse_regex, &match, optstr, 0, 0);
280  if (ret < 2 || ret > 10) {
281  SCLogError("parse error, ret %" PRId32 ", string \"%s\"", ret, optstr);
282  goto error;
283  }
284 
285  /* The first two arguments are stashed in the first PCRE substring.
286  * This is because byte_jump can take 10 arguments, but PCRE only
287  * supports 9 substrings, sigh.
288  */
289  char str[512] = "";
290  pcre2len = sizeof(str);
291  res = pcre2_substring_copy_bynumber(match, 1, (PCRE2_UCHAR8 *)str, &pcre2len);
292  if (res < 0) {
293  SCLogError("pcre2_substring_copy_bynumber failed "
294  "for arg 1");
295  goto error;
296  }
297 
298  /* Break up first substring into two parameters
299  *
300  * NOTE: Because of this, we cannot free args[1] as it is part of args[0],
301  * and *yes* this *is* ugly.
302  */
303  end_ptr = str;
304  while (!(isspace((unsigned char)*end_ptr) || (*end_ptr == ','))) end_ptr++;
305  *(end_ptr++) = '\0';
306  strlcpy(args[0], str, sizeof(args[0]));
307  numargs++;
308 
309  str_ptr = end_ptr;
310  while (isspace((unsigned char)*str_ptr) || (*str_ptr == ',')) str_ptr++;
311  end_ptr = str_ptr;
312  while (!(isspace((unsigned char)*end_ptr) || (*end_ptr == ',')) && (*end_ptr != '\0'))
313  end_ptr++;
314  *(end_ptr++) = '\0';
315  strlcpy(args[1], str_ptr, sizeof(args[1]));
316  numargs++;
317 
318  /* The remaining args are directly from PCRE substrings */
319  for (i = 1; i < (ret - 1); i++) {
320  pcre2len = sizeof(args[0]);
321  res = pcre2_substring_copy_bynumber(match, i + 1, (PCRE2_UCHAR8 *)args[i + 1], &pcre2len);
322  if (res < 0) {
323  SCLogError("pcre2_substring_copy_bynumber failed for arg %d", i + 1);
324  goto error;
325  }
326  numargs++;
327  }
328 
329  /* Initialize the data */
330  data = SCMalloc(sizeof(DetectBytejumpData));
331  if (unlikely(data == NULL))
332  goto error;
334  data->flags = 0;
335  data->multiplier = 1;
336  data->post_offset = 0;
337 
338  /*
339  * The first two options are required and positional. The
340  * remaining arguments are flags and are not positional.
341  */
342 
343  /* Number of bytes */
344  if (args[0][0] != '-' && isalpha((unsigned char)args[0][0])) {
345  if (nbytes_str == NULL) {
346  SCLogError("byte_jump supplied with "
347  "var name for nbytes. \"value\" argument supplied to "
348  "this function has to be non-NULL");
349  goto error;
350  }
351  *nbytes_str = SCStrdup(args[0]);
352  if (*nbytes_str == NULL)
353  goto error;
355  } else {
356  if (StringParseUint32(&nbytes, 10, (uint16_t)strlen(args[0]), args[0]) <= 0) {
357  SCLogError("Malformed number of bytes: %s", optstr);
358  goto error;
359  }
360  }
361 
362  /* Offset */
363  if (args[1][0] != '-' && isalpha((unsigned char)args[1][0])) {
364  if (offset == NULL) {
365  SCLogError("byte_jump supplied with "
366  "var name for offset. \"value\" argument supplied to "
367  "this function has to be non-NULL");
368  goto error;
369  }
370  *offset = SCStrdup(args[1]);
371  if (*offset == NULL)
372  goto error;
373  } else {
375  &data->offset, 10, (uint16_t)strlen(args[1]), args[1], -65535, 65535) <= 0) {
376  SCLogError("Malformed offset: %s", optstr);
377  goto error;
378  }
379  }
380 
381  /* The remaining options are flags. */
382  /** \todo Error on dups? */
383  for (i = 2; i < numargs; i++) {
384  if (strcmp("relative", args[i]) == 0) {
386  } else if (strcasecmp("string", args[i]) == 0) {
387  data->flags |= DETECT_BYTEJUMP_STRING;
388  } else if (strcasecmp("dec", args[i]) == 0) {
390  } else if (strcasecmp("hex", args[i]) == 0) {
392  } else if (strcasecmp("oct", args[i]) == 0) {
394  } else if (strcasecmp("big", args[i]) == 0) {
395  if (data->flags & DETECT_BYTEJUMP_LITTLE) {
396  data->flags ^= DETECT_BYTEJUMP_LITTLE;
397  }
398  data->flags |= DETECT_BYTEJUMP_BIG;
399  } else if (strcasecmp("little", args[i]) == 0) {
400  data->flags |= DETECT_BYTEJUMP_LITTLE;
401  } else if (strcasecmp("from_beginning", args[i]) == 0) {
402  data->flags |= DETECT_BYTEJUMP_BEGIN;
403  } else if (strcasecmp("from_end", args[i]) == 0) {
404  data->flags |= DETECT_BYTEJUMP_END;
405  } else if (strcasecmp("align", args[i]) == 0) {
406  data->flags |= DETECT_BYTEJUMP_ALIGN;
407  } else if (strncasecmp("multiplier ", args[i], 11) == 0) {
408  if (StringParseU16RangeCheck(&data->multiplier, 10, (uint16_t)strlen(args[i]) - 11,
409  args[i] + 11, 1, 65535) <= 0) {
410  SCLogError("Malformed multiplier: %s", optstr);
411  goto error;
412  }
413  } else if (strncasecmp("post_offset ", args[i], 12) == 0) {
414  if (StringParseI32RangeCheck(&data->post_offset, 10, (uint16_t)strlen(args[i]) - 12,
415  args[i] + 12, -65535, 65535) <= 0) {
416  SCLogError("Malformed post_offset: %s", optstr);
417  goto error;
418  }
419  SCLogDebug("post_offset: %s [%d]", optstr, data->post_offset);
420  } else if (strcasecmp("dce", args[i]) == 0) {
421  data->flags |= DETECT_BYTEJUMP_DCE;
422  } else {
423  SCLogError("Unknown option: \"%s\"", args[i]);
424  goto error;
425  }
426  }
427 
428  if ((data->flags & DETECT_BYTEJUMP_END) && (data->flags & DETECT_BYTEJUMP_BEGIN)) {
429  SCLogError("'from_end' and 'from_beginning' "
430  "cannot be used in the same byte_jump statement");
431  goto error;
432  }
433 
434  if (!(data->flags & DETECT_BYTEJUMP_NBYTES_VAR)) {
435  if (!DetectBytejumpValidateNbytes(data, nbytes)) {
436  goto error;
437  }
438 
439  /* This is max 23 so it will fit in a byte (see validation function) */
440  data->nbytes = (uint8_t)nbytes;
441  }
442  if (!(data->flags & DETECT_BYTEJUMP_STRING)) {
443  if (data->base != DETECT_BYTEJUMP_BASE_UNSET) {
444  SCLogError("Cannot use a base "
445  "without \"string\": %s",
446  optstr);
447  goto error;
448  }
449  }
450 
451  pcre2_match_data_free(match);
452  return data;
453 
454 error:
455  if (offset != NULL && *offset != NULL) {
456  SCFree(*offset);
457  *offset = NULL;
458  }
459  if (nbytes_str != NULL && *nbytes_str != NULL) {
460  SCFree(*nbytes_str);
461  *nbytes_str = NULL;
462  }
463  if (data != NULL)
464  DetectBytejumpFree(de_ctx, data);
465  if (match) {
466  pcre2_match_data_free(match);
467  }
468  return NULL;
469 }
470 
471 static int DetectBytejumpSetup(DetectEngineCtx *de_ctx, Signature *s, const char *optstr)
472 {
473  SigMatch *prev_pm = NULL;
474  DetectBytejumpData *data = NULL;
475  char *offset = NULL;
476  char *nbytes = NULL;
477  int ret = -1;
478 
479  data = DetectBytejumpParse(de_ctx, optstr, &nbytes, &offset);
480  if (data == NULL)
481  goto error;
482 
483  int sm_list;
484  if (s->init_data->list != DETECT_SM_LIST_NOTSET) {
485  if (DetectBufferGetActiveList(de_ctx, s) == -1)
486  goto error;
487 
488  sm_list = s->init_data->list;
489 
490  if (data->flags & DETECT_BYTEJUMP_RELATIVE) {
492  }
493  } else if (data->flags & DETECT_BYTEJUMP_DCE) {
494  if (data->flags & DETECT_BYTEJUMP_RELATIVE) {
495  prev_pm = DetectGetLastSMFromLists(s,
499  if (prev_pm == NULL) {
500  sm_list = DETECT_SM_LIST_PMATCH;
501  } else {
502  sm_list = SigMatchListSMBelongsTo(s, prev_pm);
503  if (sm_list < 0)
504  goto error;
505  }
506  } else {
507  sm_list = DETECT_SM_LIST_PMATCH;
508  }
509 
511  goto error;
512 
513  } else if (data->flags & DETECT_BYTEJUMP_RELATIVE) {
514  prev_pm = DetectGetLastSMFromLists(s,
518  if (prev_pm == NULL) {
519  sm_list = DETECT_SM_LIST_PMATCH;
520  } else {
521  sm_list = SigMatchListSMBelongsTo(s, prev_pm);
522  if (sm_list < 0)
523  goto error;
524  }
525 
526  } else {
527  sm_list = DETECT_SM_LIST_PMATCH;
528  }
529 
530  if (data->flags & DETECT_BYTEJUMP_DCE) {
531  if ((data->flags & DETECT_BYTEJUMP_STRING) ||
532  (data->flags & DETECT_BYTEJUMP_LITTLE) ||
533  (data->flags & DETECT_BYTEJUMP_BIG) ||
534  (data->flags & DETECT_BYTEJUMP_BEGIN) ||
535  (data->flags & DETECT_BYTEJUMP_END) ||
536  (data->base == DETECT_BYTEJUMP_BASE_DEC) ||
537  (data->base == DETECT_BYTEJUMP_BASE_HEX) ||
538  (data->base == DETECT_BYTEJUMP_BASE_OCT) ) {
539  SCLogError("Invalid option. "
540  "A byte_jump keyword with dce holds other invalid modifiers.");
541  goto error;
542  }
543  }
544 
545  if (nbytes != NULL) {
546  DetectByteIndexType index;
547  if (!DetectByteRetrieveSMVar(nbytes, s, &index)) {
548  SCLogError("Unknown byte_extract var "
549  "seen in byte_jump - %s",
550  nbytes);
551  goto error;
552  }
553  data->nbytes = index;
554  SCFree(nbytes);
555  nbytes = NULL;
556  }
557 
558  if (offset != NULL) {
559  DetectByteIndexType index;
560  if (!DetectByteRetrieveSMVar(offset, s, &index)) {
561  SCLogError("Unknown byte_extract var "
562  "seen in byte_jump - %s",
563  offset);
564  goto error;
565  }
566  data->offset = index;
568  SCFree(offset);
569  offset = NULL;
570  }
571 
572  if (SigMatchAppendSMToList(de_ctx, s, DETECT_BYTEJUMP, (SigMatchCtx *)data, sm_list) == NULL) {
573  goto error;
574  }
575 
576  if (!(data->flags & DETECT_BYTEJUMP_RELATIVE))
577  goto okay;
578 
579  if (prev_pm == NULL)
580  goto okay;
581 
582  if (prev_pm->type == DETECT_CONTENT) {
583  DetectContentData *cd = (DetectContentData *)prev_pm->ctx;
585  } else if (prev_pm->type == DETECT_PCRE) {
586  DetectPcreData *pd = (DetectPcreData *)prev_pm->ctx;
588  }
589 
590  okay:
591  ret = 0;
592  return ret;
593 
594  error:
595  if (nbytes != NULL) {
596  SCFree(nbytes);
597  }
598  if (offset != NULL) {
599  SCFree(offset);
600  }
601  DetectBytejumpFree(de_ctx, data);
602  return ret;
603 }
604 
605 /**
606  * \brief this function will free memory associated with DetectBytejumpData
607  *
608  * \param data pointer to DetectBytejumpData
609  */
610 static void DetectBytejumpFree(DetectEngineCtx *de_ctx, void *ptr)
611 {
612  if (ptr == NULL)
613  return;
614 
615  DetectBytejumpData *data = (DetectBytejumpData *)ptr;
616  SCFree(data);
617 }
618 
619 
620 /* UNITTESTS */
621 #ifdef UNITTESTS
622 #include "util-unittest-helper.h"
623 static int g_file_data_buffer_id = 0;
624 static int g_dce_stub_data_buffer_id = 0;
625 
626 /**
627  * \test DetectBytejumpTestParse01 is a test to make sure that we return
628  * "something" when given valid bytejump opt
629  */
630 static int DetectBytejumpTestParse01(void)
631 {
632  DetectBytejumpData *data = NULL;
633  data = DetectBytejumpParse(NULL, "4,0", NULL, NULL);
634  FAIL_IF_NULL(data);
635 
636  DetectBytejumpFree(NULL, data);
637  PASS;
638 }
639 
640 /**
641  * \test DetectBytejumpTestParse02 is a test for setting the required opts
642  */
643 static int DetectBytejumpTestParse02(void)
644 {
645  DetectBytejumpData *data = NULL;
646  data = DetectBytejumpParse(NULL, "4, 0", NULL, NULL);
647  FAIL_IF_NULL(data);
648  FAIL_IF_NOT(data->nbytes == 4);
649  FAIL_IF_NOT(data->offset == 0);
650  FAIL_IF_NOT(data->multiplier == 1);
651  FAIL_IF_NOT(data->post_offset == 0);
652  FAIL_IF_NOT(data->flags == 0);
654 
655  DetectBytejumpFree(NULL, data);
656  PASS;
657 }
658 
659 /**
660  * \test DetectBytejumpTestParse03 is a test for setting the optional flags
661  */
662 static int DetectBytejumpTestParse03(void)
663 {
664  DetectBytejumpData *data = NULL;
665  data = DetectBytejumpParse(NULL,
666  " 4,0 , relative , little, string, "
667  "dec, align, from_beginning",
668  NULL, NULL);
669  FAIL_IF_NULL(data);
670  FAIL_IF_NOT(data->nbytes == 4);
671  FAIL_IF_NOT(data->offset == 0);
672  FAIL_IF_NOT(data->multiplier == 1);
673  FAIL_IF_NOT(data->post_offset == 0);
674  FAIL_IF_NOT(data->flags ==
678 
679  DetectBytejumpFree(NULL, data);
680  PASS;
681 }
682 
683 /**
684  * \test DetectBytejumpTestParse04 is a test for setting the optional flags
685  * with parameters
686  *
687  * \todo This fails because we can only have 9 captures and there are 10.
688  */
689 static int DetectBytejumpTestParse04(void)
690 {
691  DetectBytejumpData *data = NULL;
692  data = DetectBytejumpParse(NULL,
693  " 4,0 , relative , little, string, "
694  "dec, align, from_beginning , "
695  "multiplier 2 , post_offset -16 ",
696  NULL, NULL);
697  FAIL_IF_NULL(data);
698  FAIL_IF_NOT(data->nbytes == 4);
699  FAIL_IF_NOT(data->offset == 0);
700  FAIL_IF_NOT(data->multiplier == 2);
701  FAIL_IF_NOT(data->post_offset == -16);
702  FAIL_IF_NOT(data->flags ==
706 
707  DetectBytejumpFree(NULL, data);
708  PASS;
709 }
710 
711 /**
712  * \test DetectBytejumpTestParse05 is a test for setting base without string
713  */
714 static int DetectBytejumpTestParse05(void)
715 {
716  DetectBytejumpData *data = NULL;
717  data = DetectBytejumpParse(NULL,
718  " 4,0 , relative , little, dec, "
719  "align, from_beginning",
720  NULL, NULL);
721  FAIL_IF_NOT_NULL(data);
722 
723  PASS;
724 }
725 
726 /**
727  * \test DetectBytejumpTestParse06 is a test for too many bytes to extract
728  */
729 static int DetectBytejumpTestParse06(void)
730 {
731  DetectBytejumpData *data = NULL;
732  data = DetectBytejumpParse(NULL, "9, 0", NULL, NULL);
733  FAIL_IF_NOT_NULL(data);
734 
735  PASS;
736 }
737 
738 /**
739  * \test DetectBytejumpTestParse07 is a test for too many string bytes to extract
740  */
741 static int DetectBytejumpTestParse07(void)
742 {
743  DetectBytejumpData *data = NULL;
744  data = DetectBytejumpParse(NULL, "24, 0, string, dec", NULL, NULL);
745  FAIL_IF_NOT_NULL(data);
746 
747  PASS;
748 }
749 
750 /**
751  * \test DetectBytejumpTestParse08 is a test for offset too big
752  */
753 static int DetectBytejumpTestParse08(void)
754 {
755  DetectBytejumpData *data = NULL;
756  data = DetectBytejumpParse(NULL, "4, 0xffffffffffffffff", NULL, NULL);
757  FAIL_IF_NOT_NULL(data);
758 
759  PASS;
760 }
761 
762 /**
763  * \test Test dce option.
764  */
765 static int DetectBytejumpTestParse09(void)
766 {
767  Signature *s = SigAlloc();
768  FAIL_IF_NULL(s);
769 
771 
772  FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
773  "4,0, align, multiplier 2, "
774  "post_offset -16,dce") == 0);
775  FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
776  "4,0, multiplier 2, "
777  "post_offset -16,dce") == 0);
778  FAIL_IF_NOT(DetectBytejumpSetup(NULL, s, "4,0,post_offset -16,dce") == 0);
779  FAIL_IF_NOT(DetectBytejumpSetup(NULL, s, "4,0,dce") == 0);
780  FAIL_IF_NOT(DetectBytejumpSetup(NULL, s, "4,0,dce") == 0);
781  FAIL_IF_NOT(DetectBytejumpSetup(NULL, s, "4,0, string, dce") == -1);
782  FAIL_IF_NOT(DetectBytejumpSetup(NULL, s, "4,0, big, dce") == -1);
783  FAIL_IF_NOT(DetectBytejumpSetup(NULL, s, "4,0, little, dce") == -1);
784  FAIL_IF_NOT(DetectBytejumpSetup(NULL, s, "4,0, string, dec, dce") == -1);
785  FAIL_IF_NOT(DetectBytejumpSetup(NULL, s, "4,0, string, oct, dce") == -1);
786  FAIL_IF_NOT(DetectBytejumpSetup(NULL, s, "4,0, string, hex, dce") == -1);
787  FAIL_IF_NOT(DetectBytejumpSetup(NULL, s, "4,0, from_beginning, dce") == -1);
788 
790  SigMatch *sm = DetectBufferGetFirstSigMatch(s, g_dce_stub_data_buffer_id);
791  FAIL_IF_NOT_NULL(sm);
792 
793  SigFree(NULL, s);
794  PASS;
795 }
796 
797 /**
798  * \test Test dce option.
799  */
800 static int DetectBytejumpTestParse10(void)
801 {
804  de_ctx->flags |= DE_QUIET;
805 
806  Signature *s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
807  "(msg:\"Testing bytejump_body\"; "
808  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
809  "dce_stub_data; "
810  "content:\"one\"; distance:0; "
811  "byte_jump:4,0,align,multiplier 2, "
812  "post_offset -16,relative,dce; sid:1;)");
813  FAIL_IF_NULL(s);
814  SigMatch *sm = DetectBufferGetFirstSigMatch(s, g_dce_stub_data_buffer_id);
815  FAIL_IF_NULL(sm);
817  FAIL_IF_NULL(sm->next);
818  sm = sm->next;
820 
827 
828  s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
829  "(msg:\"Testing bytejump_body\"; "
830  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
831  "dce_stub_data; "
832  "content:\"one\"; distance:0; "
833  "byte_jump:4,0,align,multiplier 2, "
834  "post_offset -16,relative,dce; sid:2;)");
835  FAIL_IF_NULL(s);
836  sm = DetectBufferGetFirstSigMatch(s, g_dce_stub_data_buffer_id);
837  FAIL_IF_NULL(sm);
838 
840  FAIL_IF_NULL(sm->next);
841  sm = sm->next;
843 
844  bd = (DetectBytejumpData *)sm->ctx;
850 
851  s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
852  "(msg:\"Testing bytejump_body\"; "
853  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
854  "dce_stub_data; "
855  "content:\"one\"; distance:0; "
856  "byte_jump:4,0,align,multiplier 2, "
857  "post_offset -16,relative; sid:3;)");
858  FAIL_IF_NULL(s);
859  sm = DetectBufferGetFirstSigMatch(s, g_dce_stub_data_buffer_id);
860  FAIL_IF_NULL(sm);
861 
863  FAIL_IF_NULL(sm->next);
864  sm = sm->next;
866 
867  bd = (DetectBytejumpData *)sm->ctx;
873 
875  PASS;
876 }
877 
878 /**
879  * \test Test dce option.
880  */
881 static int DetectBytejumpTestParse11(void)
882 {
883  DetectEngineCtx *de_ctx = NULL;
884  Signature *s = NULL;
885 
888 
889  de_ctx->flags |= DE_QUIET;
890  s = SigInit(de_ctx, "alert tcp any any -> any any "
891  "(msg:\"Testing bytejump_body\"; "
892  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
893  "dce_stub_data; "
894  "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
895  "post_offset -16,string,dce; sid:1;)");
896  FAIL_IF_NOT_NULL(s);
897 
898  s = SigInit(de_ctx, "alert tcp any any -> any any "
899  "(msg:\"Testing bytejump_body\"; "
900  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
901  "dce_sub_data; "
902  "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
903  "post_offset -16,big,dce; sid:1;)");
904  FAIL_IF_NOT_NULL(s);
905 
906  s = SigInit(de_ctx, "alert tcp any any -> any any "
907  "(msg:\"Testing bytejump_body\"; "
908  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
909  "dce_stub_data; "
910  "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
911  "post_offset -16,little,dce; sid:1;)");
912  FAIL_IF_NOT_NULL(s);
913 
914  s = SigInit(de_ctx, "alert tcp any any -> any any "
915  "(msg:\"Testing bytejump_body\"; "
916  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
917  "dce_stub_data; "
918  "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
919  "post_offset -16,string,hex,dce; sid:1;)");
920  FAIL_IF_NOT_NULL(s);
921 
922  s = SigInit(de_ctx, "alert tcp any any -> any any "
923  "(msg:\"Testing bytejump_body\"; "
924  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
925  "dce_stub_data; "
926  "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
927  "post_offset -16,string,dec,dce; sid:1;)");
928  FAIL_IF_NOT_NULL(s);
929 
930  s = SigInit(de_ctx, "alert tcp any any -> any any "
931  "(msg:\"Testing bytejump_body\"; "
932  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
933  "dce_stub_data; "
934  "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
935  "post_offset -16,string,oct,dce; sid:1;)");
936  FAIL_IF_NOT_NULL(s);
937 
938  s = SigInit(de_ctx, "alert tcp any any -> any any "
939  "(msg:\"Testing bytejump_body\"; "
940  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
941  "dce_stub_data; "
942  "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
943  "post_offset -16,from_beginning,dce; sid:1;)");
944  FAIL_IF_NOT_NULL(s);
945 
949  PASS;
950 }
951 
952 /**
953  * \test Test file_data
954  */
955 static int DetectBytejumpTestParse12(void)
956 {
959  de_ctx->flags |= DE_QUIET;
960 
961  Signature *s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
962  "(file_data; byte_jump:4,0,align,multiplier 2, "
963  "post_offset -16,relative; sid:1;)");
964  FAIL_IF_NULL(s);
965 
966  SigMatch *sm = DetectBufferGetFirstSigMatch(s, g_file_data_buffer_id);
967  FAIL_IF_NULL(sm);
969 
972  FAIL_IF((bd->flags &
975 
977  PASS;
978 }
979 
980 static int DetectBytejumpTestParse13(void)
981 {
982  DetectBytejumpData *data = DetectBytejumpParse(NULL,
983  " 4,0 , relative , little, string, dec, "
984  "align, from_end",
985  NULL, NULL);
986  FAIL_IF_NULL(data);
988 
989  DetectBytejumpFree(NULL, data);
990 
991  PASS;
992 }
993 
994 static int DetectBytejumpTestParse14(void)
995 {
996  DetectBytejumpData *data = DetectBytejumpParse(NULL,
997  " 4,0 , relative , little, string, dec, "
998  "align, from_beginning, from_end",
999  NULL, NULL);
1000 
1001  FAIL_IF_NOT_NULL(data);
1002 
1003  PASS;
1004 }
1005 
1006 /**
1007  * \test DetectByteJumpTestPacket01 is a test to check matches of
1008  * byte_jump and byte_jump relative works if the previous keyword is pcre
1009  * (bug 142)
1010  */
1011 static int DetectByteJumpTestPacket01 (void)
1012 {
1013  uint8_t *buf = (uint8_t *)"GET /AllWorkAndNoPlayMakesWillADullBoy HTTP/1.0"
1014  "User-Agent: Wget/1.11.4"
1015  "Accept: */*"
1016  "Host: www.google.com"
1017  "Connection: Keep-Alive"
1018  "Date: Mon, 04 Jan 2010 17:29:39 GMT";
1019  uint16_t buflen = strlen((char *)buf);
1020  Packet *p;
1021  p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
1022 
1023  FAIL_IF_NULL(p);
1024 
1025  char sig[] = "alert tcp any any -> any any (msg:\"pcre + byte_test + "
1026  "relative\"; pcre:\"/AllWorkAndNoPlayMakesWillADullBoy/\"; byte_jump:1,6,"
1027  "relative,string,dec; content:\"0\"; sid:134; rev:1;)";
1028 
1029  FAIL_IF_NOT(UTHPacketMatchSig(p, sig));
1030 
1031  UTHFreePacket(p);
1032  PASS;
1033 }
1034 
1035 /**
1036  * \test DetectByteJumpTestPacket02 is a test to check matches of
1037  * byte_jump and byte_jump relative works if the previous keyword is byte_jump
1038  * (bug 165)
1039  */
1040 static int DetectByteJumpTestPacket02 (void)
1041 {
1042  uint8_t buf[] = { 0x00, 0x00, 0x00, 0x77, 0xff, 0x53,
1043  0x4d, 0x42, 0x2f, 0x00, 0x00, 0x00, 0x00, 0x18,
1044  0x01, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1045  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
1046  0x92, 0xa4, 0x01, 0x08, 0x17, 0x5c, 0x0e, 0xff,
1047  0x00, 0x00, 0x00, 0x01, 0x40, 0x48, 0x00, 0x00,
1048  0x00, 0xff };
1049  uint16_t buflen = sizeof(buf);
1050  Packet *p;
1051  p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
1052 
1053  FAIL_IF_NULL(p);
1054 
1055  char sig[] = "alert tcp any any -> any any (msg:\"byte_jump with byte_jump"
1056  " + relative\"; byte_jump:1,13; byte_jump:4,0,relative; "
1057  "content:\"|48 00 00|\"; within:3; sid:144; rev:1;)";
1058 
1059  FAIL_IF_NOT(UTHPacketMatchSig(p, sig));
1060 
1061  UTHFreePacket(p);
1062  PASS;
1063 }
1064 
1065 static int DetectByteJumpTestPacket03(void)
1066 {
1067  uint8_t *buf = NULL;
1068  uint16_t buflen = 0;
1069  buf = SCMalloc(4);
1070  if (unlikely(buf == NULL)) {
1071  printf("malloc failed\n");
1072  exit(EXIT_FAILURE);
1073  }
1074  memcpy(buf, "boom", 4);
1075  buflen = 4;
1076 
1077  Packet *p;
1078  p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
1079 
1080  FAIL_IF_NULL(p);
1081 
1082  char sig[] = "alert tcp any any -> any any (msg:\"byte_jump\"; "
1083  "byte_jump:1,214748364; sid:1; rev:1;)";
1084 
1085  FAIL_IF(UTHPacketMatchSig(p, sig));
1086 
1087  UTHFreePacket(p);
1088  FAIL_IF_NULL(buf);
1089 
1090  SCFree(buf);
1091  PASS;
1092 }
1093 
1094 /**
1095  * \test check matches of with from_beginning (bug 626/627)
1096  */
1097 static int DetectByteJumpTestPacket04 (void)
1098 {
1099  uint8_t *buf = (uint8_t *)"XYZ04abcdABCD";
1100  uint16_t buflen = strlen((char *)buf);
1101  Packet *p;
1102  p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
1103 
1104  FAIL_IF_NULL(p);
1105 
1106  char sig[] = "alert tcp any any -> any any (content:\"XYZ\"; byte_jump:2,0,relative,string,dec; content:\"ABCD\"; distance:0; within:4; sid:1; rev:1;)";
1107 
1108  FAIL_IF_NOT(UTHPacketMatchSig(p, sig));
1109 
1110  UTHFreePacket(p);
1111  PASS;
1112 }
1113 
1114 /**
1115  * \test check matches of with from_beginning (bug 626/627)
1116  */
1117 static int DetectByteJumpTestPacket05 (void)
1118 {
1119  uint8_t *buf = (uint8_t *)"XYZ04abcdABCD";
1120  uint16_t buflen = strlen((char *)buf);
1121  Packet *p;
1122  p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
1123 
1124  FAIL_IF_NULL(p);
1125 
1126  char sig[] = "alert tcp any any -> any any (content:\"XYZ\"; byte_jump:2,0,relative,string,dec; content:\"cdABCD\"; within:6; sid:1; rev:1;)";
1127 
1128  FAIL_IF_NOT(UTHPacketMatchSig(p, sig) ? 0 : 1);
1129 
1130  UTHFreePacket(p);
1131  PASS;
1132 }
1133 
1134 /**
1135  * \test check matches of with from_beginning (bug 626/627)
1136  */
1137 static int DetectByteJumpTestPacket06 (void)
1138 {
1139  uint8_t *buf = (uint8_t *)"XX04abcdABCD";
1140  uint16_t buflen = strlen((char *)buf);
1141  Packet *p;
1142  p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
1143 
1144  FAIL_IF_NULL(p);
1145 
1146  char sig[] = "alert tcp any any -> any any (content:\"XX\"; byte_jump:2,0,relative,string,dec,from_beginning; content:\"ABCD\"; distance:4; within:4; sid:1; rev:1;)";
1147 
1148  FAIL_IF_NOT(UTHPacketMatchSig(p, sig));
1149 
1150  UTHFreePacket(p);
1151  PASS;
1152 }
1153 
1154 /**
1155  * \test check matches of with from_beginning (bug 626/627)
1156  */
1157 static int DetectByteJumpTestPacket07 (void)
1158 {
1159  uint8_t *buf = (uint8_t *)"XX04abcdABCD";
1160  uint16_t buflen = strlen((char *)buf);
1161  Packet *p;
1162  p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
1163 
1164  FAIL_IF_NULL(p);
1165 
1166  char sig[] = "alert tcp any any -> any any (content:\"XX\"; byte_jump:2,0,relative,string,dec,from_beginning; content:\"abcdABCD\"; distance:0; within:8; sid:1; rev:1;)";
1167 
1168  FAIL_IF_NOT(UTHPacketMatchSig(p, sig) ? 1 : 0);
1169 
1170  UTHFreePacket(p);
1171  PASS;
1172 }
1173 
1174 /**
1175  * \test check matches of with from_end
1176  */
1177 static int DetectByteJumpTestPacket08 (void)
1178 {
1179  uint8_t *buf = (uint8_t *)"XX04abcdABCD";
1180  uint16_t buflen = strlen((char *)buf);
1181  Packet *p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
1182 
1183  FAIL_IF_NULL(p);
1184 
1185  char sig[] = "alert tcp any any -> any any (content:\"XX\"; byte_jump:2,0,"
1186  "relative,string,dec,from_end, post_offset -8; content:\"ABCD\"; sid:1; rev:1;)";
1187 
1188  FAIL_IF_NOT(UTHPacketMatchSig(p, sig));
1189 
1190  UTHFreePacket(p);
1191 
1192  PASS;
1193 }
1194 
1195 /**
1196  * \brief this function registers unit tests for DetectBytejump
1197  */
1198 static void DetectBytejumpRegisterTests(void)
1199 {
1200  g_file_data_buffer_id = DetectBufferTypeGetByName("file_data");
1201  g_dce_stub_data_buffer_id = DetectBufferTypeGetByName("dce_stub_data");
1202 
1203  UtRegisterTest("DetectBytejumpTestParse01", DetectBytejumpTestParse01);
1204  UtRegisterTest("DetectBytejumpTestParse02", DetectBytejumpTestParse02);
1205  UtRegisterTest("DetectBytejumpTestParse03", DetectBytejumpTestParse03);
1206  UtRegisterTest("DetectBytejumpTestParse04", DetectBytejumpTestParse04);
1207  UtRegisterTest("DetectBytejumpTestParse05", DetectBytejumpTestParse05);
1208  UtRegisterTest("DetectBytejumpTestParse06", DetectBytejumpTestParse06);
1209  UtRegisterTest("DetectBytejumpTestParse07", DetectBytejumpTestParse07);
1210  UtRegisterTest("DetectBytejumpTestParse08", DetectBytejumpTestParse08);
1211  UtRegisterTest("DetectBytejumpTestParse09", DetectBytejumpTestParse09);
1212  UtRegisterTest("DetectBytejumpTestParse10", DetectBytejumpTestParse10);
1213  UtRegisterTest("DetectBytejumpTestParse11", DetectBytejumpTestParse11);
1214  UtRegisterTest("DetectBytejumpTestParse12", DetectBytejumpTestParse12);
1215  UtRegisterTest("DetectBytejumpTestParse13", DetectBytejumpTestParse13);
1216  UtRegisterTest("DetectBytejumpTestParse14", DetectBytejumpTestParse14);
1217 
1218  UtRegisterTest("DetectByteJumpTestPacket01", DetectByteJumpTestPacket01);
1219  UtRegisterTest("DetectByteJumpTestPacket02", DetectByteJumpTestPacket02);
1220  UtRegisterTest("DetectByteJumpTestPacket03", DetectByteJumpTestPacket03);
1221  UtRegisterTest("DetectByteJumpTestPacket04", DetectByteJumpTestPacket04);
1222  UtRegisterTest("DetectByteJumpTestPacket05", DetectByteJumpTestPacket05);
1223  UtRegisterTest("DetectByteJumpTestPacket06", DetectByteJumpTestPacket06);
1224  UtRegisterTest("DetectByteJumpTestPacket07", DetectByteJumpTestPacket07);
1225  UtRegisterTest("DetectByteJumpTestPacket08", DetectByteJumpTestPacket08);
1226 }
1227 #endif /* UNITTESTS */
DetectBytejumpData_::post_offset
int32_t post_offset
Definition: detect-bytejump.h:51
util-byte.h
SigTableElmt_::url
const char * url
Definition: detect.h:1431
DETECT_CONTENT_RELATIVE_NEXT
#define DETECT_CONTENT_RELATIVE_NEXT
Definition: detect-content.h:66
DetectSignatureSetAppProto
int DetectSignatureSetAppProto(Signature *s, AppProto alproto)
Definition: detect-parse.c:2313
detect-content.h
len
uint8_t len
Definition: app-layer-dnp3.h:2
DetectEngineThreadCtx_::buffer_offset
uint32_t buffer_offset
Definition: detect.h:1247
detect-engine.h
DETECT_SM_LIST_PMATCH
@ DETECT_SM_LIST_PMATCH
Definition: detect.h:118
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
SignatureInitData_::smlists
struct SigMatch_ * smlists[DETECT_SM_LIST_MAX]
Definition: detect.h:644
SigTableElmt_::desc
const char * desc
Definition: detect.h:1430
ByteExtractUint64
int ByteExtractUint64(uint64_t *res, int e, uint16_t len, const uint8_t *bytes)
Definition: util-byte.c:122
sigmatch_table
SigTableElmt * sigmatch_table
Definition: detect-parse.c:155
offset
uint64_t offset
Definition: util-streaming-buffer.h:0
ALPROTO_DCERPC
@ ALPROTO_DCERPC
Definition: app-layer-protos.h:44
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1418
PARSE_REGEX
#define PARSE_REGEX
Regex for parsing our options.
Definition: detect-bytejump.c:50
DetectBufferGetFirstSigMatch
SigMatch * DetectBufferGetFirstSigMatch(const Signature *s, const uint32_t buf_id)
Definition: detect-engine-buffer.c:157
DetectParseRegex
Definition: detect-parse.h:62
SigTableElmt_::name
const char * name
Definition: detect.h:1428
DETECT_BYTEJUMP
@ DETECT_BYTEJUMP
Definition: detect-engine-register.h:83
SigFree
void SigFree(DetectEngineCtx *, Signature *)
Definition: detect-parse.c:2116
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
DETECT_BYTEJUMP_LITTLE
#define DETECT_BYTEJUMP_LITTLE
Definition: detect-bytejump.h:35
DETECT_CONTENT
@ DETECT_CONTENT
Definition: detect-engine-register.h:69
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
DETECT_BYTEJUMP_NBYTES_VAR
#define DETECT_BYTEJUMP_NBYTES_VAR
Definition: detect-bytejump.h:43
ctx
struct Thresholds ctx
DETECT_BYTEJUMP_BASE_OCT
#define DETECT_BYTEJUMP_BASE_OCT
Definition: detect-bytejump.h:29
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:931
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2674
DE_QUIET
#define DE_QUIET
Definition: detect.h:329
UTHPacketMatchSig
int UTHPacketMatchSig(Packet *p, const char *sig)
Definition: util-unittest-helper.c:810
DETECT_BYTEJUMP_DCE
#define DETECT_BYTEJUMP_DCE
Definition: detect-bytejump.h:40
UTHBuildPacket
Packet * UTHBuildPacket(uint8_t *payload, uint16_t payload_len, uint8_t ipproto)
UTHBuildPacket is a wrapper that build packets with default ip and port fields.
Definition: util-unittest-helper.c:365
DetectParsePcreExec
int DetectParsePcreExec(DetectParseRegex *parse_regex, pcre2_match_data **match, const char *str, int start_offset, int options)
Definition: detect-parse.c:3493
DetectContentData_
Definition: detect-content.h:93
DetectPcreData_::flags
uint16_t flags
Definition: detect-pcre.h:51
SigCleanSignatures
void SigCleanSignatures(DetectEngineCtx *de_ctx)
Definition: detect-engine-build.c:55
ByteExtractStringUint64
int ByteExtractStringUint64(uint64_t *res, int base, size_t len, const char *str)
Definition: util-byte.c:234
DetectEngineAppendSig
Signature * DetectEngineAppendSig(DetectEngineCtx *, const char *)
Parse and append a Signature into the Detection Engine Context signature list.
Definition: detect-parse.c:3439
DETECT_BYTEJUMP_BIG
#define DETECT_BYTEJUMP_BIG
Definition: detect-bytejump.h:36
DetectBytejumpData_::base
uint8_t base
Definition: detect-bytejump.h:48
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1413
detect-pcre.h
DetectBytejumpData_
Definition: detect-bytejump.h:46
DetectByteIndexType
uint8_t DetectByteIndexType
Definition: detect-byte.h:28
util-unittest.h
DetectBytejumpData_::offset
int32_t offset
Definition: detect-bytejump.h:50
util-unittest-helper.h
FAIL_IF_NOT
#define FAIL_IF_NOT(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:82
DetectBytejumpData_::multiplier
uint16_t multiplier
Definition: detect-bytejump.h:52
DetectBufferTypeGetByName
int DetectBufferTypeGetByName(const char *name)
Definition: detect-engine.c:1157
strlcpy
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: util-strlcpyu.c:43
SCReturnBool
#define SCReturnBool(x)
Definition: util-debug.h:289
DetectBytejumpRegister
void DetectBytejumpRegister(void)
Definition: detect-bytejump.c:73
decode.h
FAIL_IF_NOT_NULL
#define FAIL_IF_NOT_NULL(expr)
Fail a test if expression evaluates to non-NULL.
Definition: util-unittest.h:96
util-debug.h
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:18
DetectEngineThreadCtx_
Definition: detect.h:1223
DETECT_BYTEJUMP_ALIGN
#define DETECT_BYTEJUMP_ALIGN
Definition: detect-bytejump.h:39
StringParseI32RangeCheck
int StringParseI32RangeCheck(int32_t *res, int base, size_t len, const char *str, int32_t min, int32_t max)
Definition: util-byte.c:716
DetectSetupParseRegexes
void DetectSetupParseRegexes(const char *parse_str, DetectParseRegex *detect_parse)
Definition: detect-parse.c:3619
DETECT_BYTEJUMP_END
#define DETECT_BYTEJUMP_END
Definition: detect-bytejump.h:42
SignatureInitData_::list
int list
Definition: detect.h:630
SCEnter
#define SCEnter(...)
Definition: util-debug.h:271
detect.h
StringParseU16RangeCheck
int StringParseU16RangeCheck(uint16_t *res, int base, size_t len, const char *str, uint16_t min, uint16_t max)
Definition: util-byte.c:433
SigMatch_::next
struct SigMatch_ * next
Definition: detect.h:360
StringParseUint32
int StringParseUint32(uint32_t *res, int base, size_t len, const char *str)
Definition: util-byte.c:313
SigInit
Signature * SigInit(DetectEngineCtx *de_ctx, const char *sigstr)
Parses a signature and adds it to the Detection Engine Context.
Definition: detect-parse.c:3097
SigMatch_::ctx
SigMatchCtx * ctx
Definition: detect.h:359
BYTE_BIG_ENDIAN
#define BYTE_BIG_ENDIAN
Definition: util-byte.h:29
DetectBytejumpDoMatch
bool DetectBytejumpDoMatch(DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchCtx *ctx, const uint8_t *payload, uint32_t payload_len, uint16_t flags, int32_t nbytes, int32_t offset)
Byte jump match function.
Definition: detect-bytejump.c:137
SigGroupCleanup
int SigGroupCleanup(DetectEngineCtx *de_ctx)
Definition: detect-engine-build.c:2200
Packet_
Definition: decode.h:492
detect-engine-build.h
detect-bytejump.h
DetectContentData_::flags
uint32_t flags
Definition: detect-content.h:104
DETECT_BYTEJUMP_BASE_UNSET
#define DETECT_BYTEJUMP_BASE_UNSET
Definition: detect-bytejump.h:28
Signature_::init_data
SignatureInitData * init_data
Definition: detect.h:749
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1396
detect-byte.h
DETECT_BYTEJUMP_BASE_HEX
#define DETECT_BYTEJUMP_BASE_HEX
Definition: detect-bytejump.h:31
DETECT_PCRE
@ DETECT_PCRE
Definition: detect-engine-register.h:71
SigMatchCtx_
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition: detect.h:351
DETECT_SM_LIST_NOTSET
#define DETECT_SM_LIST_NOTSET
Definition: detect.h:143
DETECT_BYTETEST
@ DETECT_BYTETEST
Definition: detect-engine-register.h:82
BYTE_LITTLE_ENDIAN
#define BYTE_LITTLE_ENDIAN
Definition: util-byte.h:30
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
Definition: util-unittest.h:71
DetectByteRetrieveSMVar
bool DetectByteRetrieveSMVar(const char *arg, const Signature *s, DetectByteIndexType *index)
Used to retrieve args from BM.
Definition: detect-byte.c:40
flags
uint8_t flags
Definition: decode-gre.h:0
suricata-common.h
SigMatch_::type
uint16_t type
Definition: detect.h:357
detect-byte-extract.h
DetectBytejumpData_::nbytes
uint8_t nbytes
Definition: detect-bytejump.h:47
detect-engine-buffer.h
SCStrdup
#define SCStrdup(s)
Definition: util-mem.h:56
DETECT_BYTEJUMP_BASE_DEC
#define DETECT_BYTEJUMP_BASE_DEC
Definition: detect-bytejump.h:30
util-validate.h
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
str
#define str(s)
Definition: suricata-common.h:308
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:261
SigMatchListSMBelongsTo
int SigMatchListSMBelongsTo(const Signature *s, const SigMatch *key_sm)
Definition: detect-parse.c:839
SCFree
#define SCFree(p)
Definition: util-mem.h:61
UTHFreePacket
void UTHFreePacket(Packet *p)
UTHFreePacket: function to release the allocated data from UTHBuildPacket and the packet itself.
Definition: util-unittest-helper.c:473
DETECT_BYTE_EXTRACT
@ DETECT_BYTE_EXTRACT
Definition: detect-engine-register.h:85
detect-parse.h
Signature_
Signature container.
Definition: detect.h:670
SigMatch_
a single match condition for a signature
Definition: detect.h:356
payload_len
uint16_t payload_len
Definition: stream-tcp-private.h:1
DETECT_ISDATAAT
@ DETECT_ISDATAAT
Definition: detect-engine-register.h:93
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2635
DETECT_PCRE_RELATIVE_NEXT
#define DETECT_PCRE_RELATIVE_NEXT
Definition: detect-pcre.h:34
DetectPcreData_
Definition: detect-pcre.h:47
DETECT_BYTEMATH
@ DETECT_BYTEMATH
Definition: detect-engine-register.h:84
DETECT_BYTEJUMP_STRING
#define DETECT_BYTEJUMP_STRING
Definition: detect-bytejump.h:37
detect-uricontent.h
DetectGetLastSMFromLists
SigMatch * DetectGetLastSMFromLists(const Signature *s,...)
Returns the sm with the largest index (added latest) from the lists passed to us.
Definition: detect-parse.c:640
SigMatchAppendSMToList
SigMatch * SigMatchAppendSMToList(DetectEngineCtx *de_ctx, Signature *s, uint16_t type, SigMatchCtx *ctx, const int list)
Append a SigMatch to the list type.
Definition: detect-parse.c:464
DETECT_BYTEJUMP_BEGIN
#define DETECT_BYTEJUMP_BEGIN
Definition: detect-bytejump.h:34
DetectEngineCtx_::flags
uint8_t flags
Definition: detect.h:933
SigAlloc
Signature * SigAlloc(void)
Definition: detect-parse.c:1996
DetectBufferGetActiveList
int DetectBufferGetActiveList(DetectEngineCtx *de_ctx, Signature *s)
Definition: detect-engine-buffer.c:109
SCLogDebugEnabled
int SCLogDebugEnabled(void)
Returns whether debug messages are enabled to be logged or not.
Definition: util-debug.c:767
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:102
DETECT_BYTEJUMP_RELATIVE
#define DETECT_BYTEJUMP_RELATIVE
Definition: detect-bytejump.h:38
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1420
DETECT_BYTEJUMP_OFFSET_VAR
#define DETECT_BYTEJUMP_OFFSET_VAR
Definition: detect-bytejump.h:44
DetectBytejumpData_::flags
uint16_t flags
Definition: detect-bytejump.h:49
app-layer.h