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 (SCSigMatchAppendSMToList(de_ctx, s, DETECT_BYTEJUMP, (SigMatchCtx *)data, sm_list) ==
573  NULL) {
574  goto error;
575  }
576 
577  if (!(data->flags & DETECT_BYTEJUMP_RELATIVE))
578  goto okay;
579 
580  if (prev_pm == NULL)
581  goto okay;
582 
583  if (prev_pm->type == DETECT_CONTENT) {
584  DetectContentData *cd = (DetectContentData *)prev_pm->ctx;
586  } else if (prev_pm->type == DETECT_PCRE) {
587  DetectPcreData *pd = (DetectPcreData *)prev_pm->ctx;
589  }
590 
591  okay:
592  ret = 0;
593  return ret;
594 
595  error:
596  if (nbytes != NULL) {
597  SCFree(nbytes);
598  }
599  if (offset != NULL) {
600  SCFree(offset);
601  }
602  DetectBytejumpFree(de_ctx, data);
603  return ret;
604 }
605 
606 /**
607  * \brief this function will free memory associated with DetectBytejumpData
608  *
609  * \param data pointer to DetectBytejumpData
610  */
611 static void DetectBytejumpFree(DetectEngineCtx *de_ctx, void *ptr)
612 {
613  if (ptr == NULL)
614  return;
615 
616  DetectBytejumpData *data = (DetectBytejumpData *)ptr;
617  SCFree(data);
618 }
619 
620 
621 /* UNITTESTS */
622 #ifdef UNITTESTS
623 #include "util-unittest-helper.h"
624 static int g_file_data_buffer_id = 0;
625 static int g_dce_stub_data_buffer_id = 0;
626 
627 /**
628  * \test DetectBytejumpTestParse01 is a test to make sure that we return
629  * "something" when given valid bytejump opt
630  */
631 static int DetectBytejumpTestParse01(void)
632 {
633  DetectBytejumpData *data = NULL;
634  data = DetectBytejumpParse(NULL, "4,0", NULL, NULL);
635  FAIL_IF_NULL(data);
636 
637  DetectBytejumpFree(NULL, data);
638  PASS;
639 }
640 
641 /**
642  * \test DetectBytejumpTestParse02 is a test for setting the required opts
643  */
644 static int DetectBytejumpTestParse02(void)
645 {
646  DetectBytejumpData *data = NULL;
647  data = DetectBytejumpParse(NULL, "4, 0", NULL, NULL);
648  FAIL_IF_NULL(data);
649  FAIL_IF_NOT(data->nbytes == 4);
650  FAIL_IF_NOT(data->offset == 0);
651  FAIL_IF_NOT(data->multiplier == 1);
652  FAIL_IF_NOT(data->post_offset == 0);
653  FAIL_IF_NOT(data->flags == 0);
655 
656  DetectBytejumpFree(NULL, data);
657  PASS;
658 }
659 
660 /**
661  * \test DetectBytejumpTestParse03 is a test for setting the optional flags
662  */
663 static int DetectBytejumpTestParse03(void)
664 {
665  DetectBytejumpData *data = NULL;
666  data = DetectBytejumpParse(NULL,
667  " 4,0 , relative , little, string, "
668  "dec, align, from_beginning",
669  NULL, NULL);
670  FAIL_IF_NULL(data);
671  FAIL_IF_NOT(data->nbytes == 4);
672  FAIL_IF_NOT(data->offset == 0);
673  FAIL_IF_NOT(data->multiplier == 1);
674  FAIL_IF_NOT(data->post_offset == 0);
675  FAIL_IF_NOT(data->flags ==
679 
680  DetectBytejumpFree(NULL, data);
681  PASS;
682 }
683 
684 /**
685  * \test DetectBytejumpTestParse04 is a test for setting the optional flags
686  * with parameters
687  *
688  * \todo This fails because we can only have 9 captures and there are 10.
689  */
690 static int DetectBytejumpTestParse04(void)
691 {
692  DetectBytejumpData *data = NULL;
693  data = DetectBytejumpParse(NULL,
694  " 4,0 , relative , little, string, "
695  "dec, align, from_beginning , "
696  "multiplier 2 , post_offset -16 ",
697  NULL, NULL);
698  FAIL_IF_NULL(data);
699  FAIL_IF_NOT(data->nbytes == 4);
700  FAIL_IF_NOT(data->offset == 0);
701  FAIL_IF_NOT(data->multiplier == 2);
702  FAIL_IF_NOT(data->post_offset == -16);
703  FAIL_IF_NOT(data->flags ==
707 
708  DetectBytejumpFree(NULL, data);
709  PASS;
710 }
711 
712 /**
713  * \test DetectBytejumpTestParse05 is a test for setting base without string
714  */
715 static int DetectBytejumpTestParse05(void)
716 {
717  DetectBytejumpData *data = NULL;
718  data = DetectBytejumpParse(NULL,
719  " 4,0 , relative , little, dec, "
720  "align, from_beginning",
721  NULL, NULL);
722  FAIL_IF_NOT_NULL(data);
723 
724  PASS;
725 }
726 
727 /**
728  * \test DetectBytejumpTestParse06 is a test for too many bytes to extract
729  */
730 static int DetectBytejumpTestParse06(void)
731 {
732  DetectBytejumpData *data = NULL;
733  data = DetectBytejumpParse(NULL, "9, 0", NULL, NULL);
734  FAIL_IF_NOT_NULL(data);
735 
736  PASS;
737 }
738 
739 /**
740  * \test DetectBytejumpTestParse07 is a test for too many string bytes to extract
741  */
742 static int DetectBytejumpTestParse07(void)
743 {
744  DetectBytejumpData *data = NULL;
745  data = DetectBytejumpParse(NULL, "24, 0, string, dec", NULL, NULL);
746  FAIL_IF_NOT_NULL(data);
747 
748  PASS;
749 }
750 
751 /**
752  * \test DetectBytejumpTestParse08 is a test for offset too big
753  */
754 static int DetectBytejumpTestParse08(void)
755 {
756  DetectBytejumpData *data = NULL;
757  data = DetectBytejumpParse(NULL, "4, 0xffffffffffffffff", NULL, NULL);
758  FAIL_IF_NOT_NULL(data);
759 
760  PASS;
761 }
762 
763 /**
764  * \test Test dce option.
765  */
766 static int DetectBytejumpTestParse09(void)
767 {
768  Signature *s = SigAlloc();
769  FAIL_IF_NULL(s);
770 
772 
773  FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
774  "4,0, align, multiplier 2, "
775  "post_offset -16,dce") == 0);
776  FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
777  "4,0, multiplier 2, "
778  "post_offset -16,dce") == 0);
779  FAIL_IF_NOT(DetectBytejumpSetup(NULL, s, "4,0,post_offset -16,dce") == 0);
780  FAIL_IF_NOT(DetectBytejumpSetup(NULL, s, "4,0,dce") == 0);
781  FAIL_IF_NOT(DetectBytejumpSetup(NULL, s, "4,0,dce") == 0);
782  FAIL_IF_NOT(DetectBytejumpSetup(NULL, s, "4,0, string, dce") == -1);
783  FAIL_IF_NOT(DetectBytejumpSetup(NULL, s, "4,0, big, dce") == -1);
784  FAIL_IF_NOT(DetectBytejumpSetup(NULL, s, "4,0, little, dce") == -1);
785  FAIL_IF_NOT(DetectBytejumpSetup(NULL, s, "4,0, string, dec, dce") == -1);
786  FAIL_IF_NOT(DetectBytejumpSetup(NULL, s, "4,0, string, oct, dce") == -1);
787  FAIL_IF_NOT(DetectBytejumpSetup(NULL, s, "4,0, string, hex, dce") == -1);
788  FAIL_IF_NOT(DetectBytejumpSetup(NULL, s, "4,0, from_beginning, dce") == -1);
789 
791  SigMatch *sm = DetectBufferGetFirstSigMatch(s, g_dce_stub_data_buffer_id);
792  FAIL_IF_NOT_NULL(sm);
793 
794  SigFree(NULL, s);
795  PASS;
796 }
797 
798 /**
799  * \test Test dce option.
800  */
801 static int DetectBytejumpTestParse10(void)
802 {
805  de_ctx->flags |= DE_QUIET;
806 
807  Signature *s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
808  "(msg:\"Testing bytejump_body\"; "
809  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
810  "dce_stub_data; "
811  "content:\"one\"; distance:0; "
812  "byte_jump:4,0,align,multiplier 2, "
813  "post_offset -16,relative,dce; sid:1;)");
814  FAIL_IF_NULL(s);
815  SigMatch *sm = DetectBufferGetFirstSigMatch(s, g_dce_stub_data_buffer_id);
816  FAIL_IF_NULL(sm);
818  FAIL_IF_NULL(sm->next);
819  sm = sm->next;
821 
828 
829  s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
830  "(msg:\"Testing bytejump_body\"; "
831  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
832  "dce_stub_data; "
833  "content:\"one\"; distance:0; "
834  "byte_jump:4,0,align,multiplier 2, "
835  "post_offset -16,relative,dce; sid:2;)");
836  FAIL_IF_NULL(s);
837  sm = DetectBufferGetFirstSigMatch(s, g_dce_stub_data_buffer_id);
838  FAIL_IF_NULL(sm);
839 
841  FAIL_IF_NULL(sm->next);
842  sm = sm->next;
844 
845  bd = (DetectBytejumpData *)sm->ctx;
851 
852  s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
853  "(msg:\"Testing bytejump_body\"; "
854  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
855  "dce_stub_data; "
856  "content:\"one\"; distance:0; "
857  "byte_jump:4,0,align,multiplier 2, "
858  "post_offset -16,relative; sid:3;)");
859  FAIL_IF_NULL(s);
860  sm = DetectBufferGetFirstSigMatch(s, g_dce_stub_data_buffer_id);
861  FAIL_IF_NULL(sm);
862 
864  FAIL_IF_NULL(sm->next);
865  sm = sm->next;
867 
868  bd = (DetectBytejumpData *)sm->ctx;
874 
876  PASS;
877 }
878 
879 /**
880  * \test Test dce option.
881  */
882 static int DetectBytejumpTestParse11(void)
883 {
884  DetectEngineCtx *de_ctx = NULL;
885  Signature *s = NULL;
886 
889 
890  de_ctx->flags |= DE_QUIET;
891  s = SigInit(de_ctx, "alert tcp any any -> any any "
892  "(msg:\"Testing bytejump_body\"; "
893  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
894  "dce_stub_data; "
895  "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
896  "post_offset -16,string,dce; sid:1;)");
897  FAIL_IF_NOT_NULL(s);
898 
899  s = SigInit(de_ctx, "alert tcp any any -> any any "
900  "(msg:\"Testing bytejump_body\"; "
901  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
902  "dce_sub_data; "
903  "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
904  "post_offset -16,big,dce; sid:1;)");
905  FAIL_IF_NOT_NULL(s);
906 
907  s = SigInit(de_ctx, "alert tcp any any -> any any "
908  "(msg:\"Testing bytejump_body\"; "
909  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
910  "dce_stub_data; "
911  "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
912  "post_offset -16,little,dce; sid:1;)");
913  FAIL_IF_NOT_NULL(s);
914 
915  s = SigInit(de_ctx, "alert tcp any any -> any any "
916  "(msg:\"Testing bytejump_body\"; "
917  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
918  "dce_stub_data; "
919  "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
920  "post_offset -16,string,hex,dce; sid:1;)");
921  FAIL_IF_NOT_NULL(s);
922 
923  s = SigInit(de_ctx, "alert tcp any any -> any any "
924  "(msg:\"Testing bytejump_body\"; "
925  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
926  "dce_stub_data; "
927  "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
928  "post_offset -16,string,dec,dce; sid:1;)");
929  FAIL_IF_NOT_NULL(s);
930 
931  s = SigInit(de_ctx, "alert tcp any any -> any any "
932  "(msg:\"Testing bytejump_body\"; "
933  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
934  "dce_stub_data; "
935  "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
936  "post_offset -16,string,oct,dce; sid:1;)");
937  FAIL_IF_NOT_NULL(s);
938 
939  s = SigInit(de_ctx, "alert tcp any any -> any any "
940  "(msg:\"Testing bytejump_body\"; "
941  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
942  "dce_stub_data; "
943  "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
944  "post_offset -16,from_beginning,dce; sid:1;)");
945  FAIL_IF_NOT_NULL(s);
946 
950  PASS;
951 }
952 
953 /**
954  * \test Test file_data
955  */
956 static int DetectBytejumpTestParse12(void)
957 {
960  de_ctx->flags |= DE_QUIET;
961 
962  Signature *s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
963  "(file_data; byte_jump:4,0,align,multiplier 2, "
964  "post_offset -16,relative; sid:1;)");
965  FAIL_IF_NULL(s);
966 
967  SigMatch *sm = DetectBufferGetFirstSigMatch(s, g_file_data_buffer_id);
968  FAIL_IF_NULL(sm);
970 
973  FAIL_IF((bd->flags &
976 
978  PASS;
979 }
980 
981 static int DetectBytejumpTestParse13(void)
982 {
983  DetectBytejumpData *data = DetectBytejumpParse(NULL,
984  " 4,0 , relative , little, string, dec, "
985  "align, from_end",
986  NULL, NULL);
987  FAIL_IF_NULL(data);
989 
990  DetectBytejumpFree(NULL, data);
991 
992  PASS;
993 }
994 
995 static int DetectBytejumpTestParse14(void)
996 {
997  DetectBytejumpData *data = DetectBytejumpParse(NULL,
998  " 4,0 , relative , little, string, dec, "
999  "align, from_beginning, from_end",
1000  NULL, NULL);
1001 
1002  FAIL_IF_NOT_NULL(data);
1003 
1004  PASS;
1005 }
1006 
1007 /**
1008  * \test DetectByteJumpTestPacket01 is a test to check matches of
1009  * byte_jump and byte_jump relative works if the previous keyword is pcre
1010  * (bug 142)
1011  */
1012 static int DetectByteJumpTestPacket01 (void)
1013 {
1014  uint8_t *buf = (uint8_t *)"GET /AllWorkAndNoPlayMakesWillADullBoy HTTP/1.0"
1015  "User-Agent: Wget/1.11.4"
1016  "Accept: */*"
1017  "Host: www.google.com"
1018  "Connection: Keep-Alive"
1019  "Date: Mon, 04 Jan 2010 17:29:39 GMT";
1020  uint16_t buflen = strlen((char *)buf);
1021  Packet *p;
1022  p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
1023 
1024  FAIL_IF_NULL(p);
1025 
1026  char sig[] = "alert tcp any any -> any any (msg:\"pcre + byte_test + "
1027  "relative\"; pcre:\"/AllWorkAndNoPlayMakesWillADullBoy/\"; byte_jump:1,6,"
1028  "relative,string,dec; content:\"0\"; sid:134; rev:1;)";
1029 
1030  FAIL_IF_NOT(UTHPacketMatchSig(p, sig));
1031 
1032  UTHFreePacket(p);
1033  PASS;
1034 }
1035 
1036 /**
1037  * \test DetectByteJumpTestPacket02 is a test to check matches of
1038  * byte_jump and byte_jump relative works if the previous keyword is byte_jump
1039  * (bug 165)
1040  */
1041 static int DetectByteJumpTestPacket02 (void)
1042 {
1043  uint8_t buf[] = { 0x00, 0x00, 0x00, 0x77, 0xff, 0x53,
1044  0x4d, 0x42, 0x2f, 0x00, 0x00, 0x00, 0x00, 0x18,
1045  0x01, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1046  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
1047  0x92, 0xa4, 0x01, 0x08, 0x17, 0x5c, 0x0e, 0xff,
1048  0x00, 0x00, 0x00, 0x01, 0x40, 0x48, 0x00, 0x00,
1049  0x00, 0xff };
1050  uint16_t buflen = sizeof(buf);
1051  Packet *p;
1052  p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
1053 
1054  FAIL_IF_NULL(p);
1055 
1056  char sig[] = "alert tcp any any -> any any (msg:\"byte_jump with byte_jump"
1057  " + relative\"; byte_jump:1,13; byte_jump:4,0,relative; "
1058  "content:\"|48 00 00|\"; within:3; sid:144; rev:1;)";
1059 
1060  FAIL_IF_NOT(UTHPacketMatchSig(p, sig));
1061 
1062  UTHFreePacket(p);
1063  PASS;
1064 }
1065 
1066 static int DetectByteJumpTestPacket03(void)
1067 {
1068  uint8_t *buf = NULL;
1069  uint16_t buflen = 0;
1070  buf = SCMalloc(4);
1071  if (unlikely(buf == NULL)) {
1072  printf("malloc failed\n");
1073  exit(EXIT_FAILURE);
1074  }
1075  memcpy(buf, "boom", 4);
1076  buflen = 4;
1077 
1078  Packet *p;
1079  p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
1080 
1081  FAIL_IF_NULL(p);
1082 
1083  char sig[] = "alert tcp any any -> any any (msg:\"byte_jump\"; "
1084  "byte_jump:1,214748364; sid:1; rev:1;)";
1085 
1086  FAIL_IF(UTHPacketMatchSig(p, sig));
1087 
1088  UTHFreePacket(p);
1089  FAIL_IF_NULL(buf);
1090 
1091  SCFree(buf);
1092  PASS;
1093 }
1094 
1095 /**
1096  * \test check matches of with from_beginning (bug 626/627)
1097  */
1098 static int DetectByteJumpTestPacket04 (void)
1099 {
1100  uint8_t *buf = (uint8_t *)"XYZ04abcdABCD";
1101  uint16_t buflen = strlen((char *)buf);
1102  Packet *p;
1103  p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
1104 
1105  FAIL_IF_NULL(p);
1106 
1107  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;)";
1108 
1109  FAIL_IF_NOT(UTHPacketMatchSig(p, sig));
1110 
1111  UTHFreePacket(p);
1112  PASS;
1113 }
1114 
1115 /**
1116  * \test check matches of with from_beginning (bug 626/627)
1117  */
1118 static int DetectByteJumpTestPacket05 (void)
1119 {
1120  uint8_t *buf = (uint8_t *)"XYZ04abcdABCD";
1121  uint16_t buflen = strlen((char *)buf);
1122  Packet *p;
1123  p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
1124 
1125  FAIL_IF_NULL(p);
1126 
1127  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;)";
1128 
1129  FAIL_IF_NOT(UTHPacketMatchSig(p, sig) ? 0 : 1);
1130 
1131  UTHFreePacket(p);
1132  PASS;
1133 }
1134 
1135 /**
1136  * \test check matches of with from_beginning (bug 626/627)
1137  */
1138 static int DetectByteJumpTestPacket06 (void)
1139 {
1140  uint8_t *buf = (uint8_t *)"XX04abcdABCD";
1141  uint16_t buflen = strlen((char *)buf);
1142  Packet *p;
1143  p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
1144 
1145  FAIL_IF_NULL(p);
1146 
1147  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;)";
1148 
1149  FAIL_IF_NOT(UTHPacketMatchSig(p, sig));
1150 
1151  UTHFreePacket(p);
1152  PASS;
1153 }
1154 
1155 /**
1156  * \test check matches of with from_beginning (bug 626/627)
1157  */
1158 static int DetectByteJumpTestPacket07 (void)
1159 {
1160  uint8_t *buf = (uint8_t *)"XX04abcdABCD";
1161  uint16_t buflen = strlen((char *)buf);
1162  Packet *p;
1163  p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
1164 
1165  FAIL_IF_NULL(p);
1166 
1167  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;)";
1168 
1169  FAIL_IF_NOT(UTHPacketMatchSig(p, sig) ? 1 : 0);
1170 
1171  UTHFreePacket(p);
1172  PASS;
1173 }
1174 
1175 /**
1176  * \test check matches of with from_end
1177  */
1178 static int DetectByteJumpTestPacket08 (void)
1179 {
1180  uint8_t *buf = (uint8_t *)"XX04abcdABCD";
1181  uint16_t buflen = strlen((char *)buf);
1182  Packet *p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
1183 
1184  FAIL_IF_NULL(p);
1185 
1186  char sig[] = "alert tcp any any -> any any (content:\"XX\"; byte_jump:2,0,"
1187  "relative,string,dec,from_end, post_offset -8; content:\"ABCD\"; sid:1; rev:1;)";
1188 
1189  FAIL_IF_NOT(UTHPacketMatchSig(p, sig));
1190 
1191  UTHFreePacket(p);
1192 
1193  PASS;
1194 }
1195 
1196 /**
1197  * \brief this function registers unit tests for DetectBytejump
1198  */
1199 static void DetectBytejumpRegisterTests(void)
1200 {
1201  g_file_data_buffer_id = DetectBufferTypeGetByName("file_data");
1202  g_dce_stub_data_buffer_id = DetectBufferTypeGetByName("dce_stub_data");
1203 
1204  UtRegisterTest("DetectBytejumpTestParse01", DetectBytejumpTestParse01);
1205  UtRegisterTest("DetectBytejumpTestParse02", DetectBytejumpTestParse02);
1206  UtRegisterTest("DetectBytejumpTestParse03", DetectBytejumpTestParse03);
1207  UtRegisterTest("DetectBytejumpTestParse04", DetectBytejumpTestParse04);
1208  UtRegisterTest("DetectBytejumpTestParse05", DetectBytejumpTestParse05);
1209  UtRegisterTest("DetectBytejumpTestParse06", DetectBytejumpTestParse06);
1210  UtRegisterTest("DetectBytejumpTestParse07", DetectBytejumpTestParse07);
1211  UtRegisterTest("DetectBytejumpTestParse08", DetectBytejumpTestParse08);
1212  UtRegisterTest("DetectBytejumpTestParse09", DetectBytejumpTestParse09);
1213  UtRegisterTest("DetectBytejumpTestParse10", DetectBytejumpTestParse10);
1214  UtRegisterTest("DetectBytejumpTestParse11", DetectBytejumpTestParse11);
1215  UtRegisterTest("DetectBytejumpTestParse12", DetectBytejumpTestParse12);
1216  UtRegisterTest("DetectBytejumpTestParse13", DetectBytejumpTestParse13);
1217  UtRegisterTest("DetectBytejumpTestParse14", DetectBytejumpTestParse14);
1218 
1219  UtRegisterTest("DetectByteJumpTestPacket01", DetectByteJumpTestPacket01);
1220  UtRegisterTest("DetectByteJumpTestPacket02", DetectByteJumpTestPacket02);
1221  UtRegisterTest("DetectByteJumpTestPacket03", DetectByteJumpTestPacket03);
1222  UtRegisterTest("DetectByteJumpTestPacket04", DetectByteJumpTestPacket04);
1223  UtRegisterTest("DetectByteJumpTestPacket05", DetectByteJumpTestPacket05);
1224  UtRegisterTest("DetectByteJumpTestPacket06", DetectByteJumpTestPacket06);
1225  UtRegisterTest("DetectByteJumpTestPacket07", DetectByteJumpTestPacket07);
1226  UtRegisterTest("DetectByteJumpTestPacket08", DetectByteJumpTestPacket08);
1227 }
1228 #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:1422
DETECT_CONTENT_RELATIVE_NEXT
#define DETECT_CONTENT_RELATIVE_NEXT
Definition: detect-content.h:66
detect-content.h
len
uint8_t len
Definition: app-layer-dnp3.h:2
DetectEngineThreadCtx_::buffer_offset
uint32_t buffer_offset
Definition: detect.h:1235
detect-engine.h
DETECT_SM_LIST_PMATCH
@ DETECT_SM_LIST_PMATCH
Definition: detect.h:119
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:631
SigTableElmt_::desc
const char * desc
Definition: detect.h:1421
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:79
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:1409
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:93
SigTableElmt_::name
const char * name
Definition: detect.h:1419
DETECT_BYTEJUMP
@ DETECT_BYTEJUMP
Definition: detect-engine-register.h:83
SigFree
void SigFree(DetectEngineCtx *, Signature *)
Definition: detect-parse.c:2040
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:270
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:919
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2624
DE_QUIET
#define DE_QUIET
Definition: detect.h:330
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:3392
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
SCDetectSignatureSetAppProto
int SCDetectSignatureSetAppProto(Signature *s, AppProto alproto)
Definition: detect-parse.c:2212
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:3338
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:1404
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:1256
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:290
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:1211
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:3518
DETECT_BYTEJUMP_END
#define DETECT_BYTEJUMP_END
Definition: detect-bytejump.h:42
SignatureInitData_::list
int list
Definition: detect.h:617
SCEnter
#define SCEnter(...)
Definition: util-debug.h:272
SCSigMatchAppendSMToList
SigMatch * SCSigMatchAppendSMToList(DetectEngineCtx *de_ctx, Signature *s, uint16_t type, SigMatchCtx *ctx, const int list)
Append a SigMatch to the list type.
Definition: detect-parse.c:388
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:361
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:2996
SigMatch_::ctx
SigMatchCtx * ctx
Definition: detect.h:360
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:2201
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:736
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1384
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:352
DETECT_SM_LIST_NOTSET
#define DETECT_SM_LIST_NOTSET
Definition: detect.h:144
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:358
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:262
SigMatchListSMBelongsTo
int SigMatchListSMBelongsTo(const Signature *s, const SigMatch *key_sm)
Definition: detect-parse.c:763
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:657
SigMatch_
a single match condition for a signature
Definition: detect.h:357
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:2585
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:564
DETECT_BYTEJUMP_BEGIN
#define DETECT_BYTEJUMP_BEGIN
Definition: detect-bytejump.h:34
DetectEngineCtx_::flags
uint8_t flags
Definition: detect.h:921
SigAlloc
Signature * SigAlloc(void)
Definition: detect-parse.c:1920
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:1411
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