suricata
detect-bytejump.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2010 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 "debug.h"
28 #include "decode.h"
29 #include "detect.h"
30 #include "detect-parse.h"
31 #include "detect-engine.h"
32 #include "app-layer.h"
33 
34 #include "detect-bytejump.h"
35 #include "detect-byte-extract.h"
36 #include "detect-content.h"
37 #include "detect-uricontent.h"
38 
39 #include "util-byte.h"
40 #include "util-unittest.h"
41 #include "util-debug.h"
42 #include "detect-pcre.h"
43 
44 /**
45  * \brief Regex for parsing our options
46  */
47 #define PARSE_REGEX "^\\s*" \
48  "([^\\s,]+\\s*,\\s*[^\\s,]+)" \
49  "(?:\\s*,\\s*((?:multiplier|post_offset)\\s+[^\\s,]+|[^\\s,]+))?" \
50  "(?:\\s*,\\s*((?:multiplier|post_offset)\\s+[^\\s,]+|[^\\s,]+))?" \
51  "(?:\\s*,\\s*((?:multiplier|post_offset)\\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*$"
59 
60 static pcre *parse_regex;
61 static pcre_extra *parse_regex_study;
62 
63 static int DetectBytejumpMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
64  Packet *p, const Signature *s, const SigMatchCtx *ctx);
65 static DetectBytejumpData *DetectBytejumpParse(const char *optstr, char **offset);
66 static int DetectBytejumpSetup(DetectEngineCtx *de_ctx, Signature *s, const char *optstr);
67 static void DetectBytejumpFree(void *ptr);
68 static void DetectBytejumpRegisterTests(void);
69 
71 {
72  sigmatch_table[DETECT_BYTEJUMP].name = "byte_jump";
73  sigmatch_table[DETECT_BYTEJUMP].Match = DetectBytejumpMatch;
74  sigmatch_table[DETECT_BYTEJUMP].Setup = DetectBytejumpSetup;
75  sigmatch_table[DETECT_BYTEJUMP].Free = DetectBytejumpFree;
76  sigmatch_table[DETECT_BYTEJUMP].RegisterTests = DetectBytejumpRegisterTests;
77 
78  DetectSetupParseRegexes(PARSE_REGEX, &parse_regex, &parse_regex_study);
79 }
80 
81 /** \brief Byte jump match function
82  * \param det_ctx thread detect engine ctx
83  * \param s signature
84  * \param m byte jump sigmatch
85  * \param payload ptr to the payload
86  * \param payload_len length of the payload
87  * \retval 1 match
88  * \retval 0 no match
89  */
91  const SigMatchCtx *ctx, uint8_t *payload, uint32_t payload_len,
92  uint8_t flags, int32_t offset)
93 {
94  SCEnter();
95 
96  const DetectBytejumpData *data = (const DetectBytejumpData *)ctx;
97  uint8_t *ptr = NULL;
98  uint8_t *jumpptr = NULL;
99  int32_t len = 0;
100  uint64_t val = 0;
101  int extbytes;
102 
103  if (payload_len == 0) {
104  SCReturnInt(0);
105  }
106 
107  /* Calculate the ptr value for the bytejump and length remaining in
108  * the packet from that point.
109  */
110  if (flags & DETECT_BYTEJUMP_RELATIVE) {
111  ptr = payload + det_ctx->buffer_offset;
112  len = payload_len - det_ctx->buffer_offset;
113 
114  ptr += offset;
115  len -= offset;
116 
117  /* No match if there is no relative base */
118  if (ptr == NULL || len <= 0) {
119  SCReturnInt(0);
120  }
121  }
122  else {
123  ptr = payload + offset;
124  len = payload_len - offset;
125  }
126 
127  /* Verify the to-be-extracted data is within the packet */
128  if (ptr < payload || data->nbytes > len) {
129  SCLogDebug("Data not within payload "
130  "pkt=%p, ptr=%p, len=%d, nbytes=%d",
131  payload, ptr, len, data->nbytes);
132  SCReturnInt(0);
133  }
134 
135  /* Extract the byte data */
136  if (flags & DETECT_BYTEJUMP_STRING) {
137  extbytes = ByteExtractStringUint64(&val, data->base,
138  data->nbytes, (const char *)ptr);
139  if(extbytes <= 0) {
140  SCLogDebug("error extracting %d bytes of string data: %d",
141  data->nbytes, extbytes);
142  SCReturnInt(0);
143  }
144  }
145  else {
146  int endianness = (flags & DETECT_BYTEJUMP_LITTLE) ? BYTE_LITTLE_ENDIAN : BYTE_BIG_ENDIAN;
147  extbytes = ByteExtractUint64(&val, endianness, data->nbytes, ptr);
148  if (extbytes != data->nbytes) {
149  SCLogDebug("error extracting %d bytes of numeric data: %d",
150  data->nbytes, extbytes);
151  SCReturnInt(0);
152  }
153  }
154 
155  //printf("VAL: (%" PRIu64 " x %" PRIu32 ") + %d + %" PRId32 "\n", val, data->multiplier, extbytes, data->post_offset);
156 
157  /* Adjust the jump value based on flags */
158  val *= data->multiplier;
159  if (flags & DETECT_BYTEJUMP_ALIGN) {
160  if ((val % 4) != 0) {
161  val += 4 - (val % 4);
162  }
163  }
164  val += data->post_offset;
165 
166  /* Calculate the jump location */
167  if (flags & DETECT_BYTEJUMP_BEGIN) {
168  jumpptr = payload + val;
169  //printf("NEWVAL: payload %p + %ld = %p\n", p->payload, val, jumpptr);
170  }
171  else {
172  val += extbytes;
173  jumpptr = ptr + val;
174  //printf("NEWVAL: ptr %p + %ld = %p\n", ptr, val, jumpptr);
175  }
176 
177 
178  /* Validate that the jump location is still in the packet
179  * \todo Should this validate it is still in the *payload*?
180  */
181  if ((jumpptr < payload) || (jumpptr >= payload + payload_len)) {
182  SCLogDebug("Jump location (%p) is not within "
183  "payload (%p-%p)", jumpptr, payload, payload + payload_len - 1);
184  SCReturnInt(0);
185  }
186 
187 #ifdef DEBUG
188  if (SCLogDebugEnabled()) {
189  uint8_t *sptr = (flags & DETECT_BYTEJUMP_BEGIN) ? payload : ptr;
190  SCLogDebug("jumping %" PRId64 " bytes from %p (%08x) to %p (%08x)",
191  val, sptr, (int)(sptr - payload),
192  jumpptr, (int)(jumpptr - payload));
193  }
194 #endif /* DEBUG */
195 
196  /* Adjust the detection context to the jump location. */
197  det_ctx->buffer_offset = jumpptr - payload;
198 
199  SCReturnInt(1);
200 }
201 
202 static int DetectBytejumpMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
203  Packet *p, const Signature *s, const SigMatchCtx *ctx)
204 {
205  const DetectBytejumpData *data = (const DetectBytejumpData *)ctx;
206  uint8_t *ptr = NULL;
207  uint8_t *jumpptr = NULL;
208  uint16_t len = 0;
209  uint64_t val = 0;
210  int extbytes;
211 
212  if (p->payload_len == 0) {
213  return 0;
214  }
215 
216  /* Calculate the ptr value for the bytejump and length remaining in
217  * the packet from that point.
218  */
219  if (data->flags & DETECT_BYTEJUMP_RELATIVE) {
220  ptr = p->payload + det_ctx->buffer_offset;
221  len = p->payload_len - det_ctx->buffer_offset;
222 
223  /* No match if there is no relative base */
224  if (ptr == NULL || len == 0) {
225  return 0;
226  }
227 
228  ptr += data->offset;
229  len -= data->offset;
230  }
231  else {
232  ptr = p->payload + data->offset;
233  len = p->payload_len - data->offset;
234  }
235 
236  /* Verify the to-be-extracted data is within the packet */
237  if (ptr < p->payload || data->nbytes > len) {
238  SCLogDebug("Data not within packet "
239  "payload=%p, ptr=%p, len=%d, nbytes=%d",
240  p->payload, ptr, len, data->nbytes);
241  return 0;
242  }
243 
244  /* Extract the byte data */
245  if (data->flags & DETECT_BYTEJUMP_STRING) {
246  extbytes = ByteExtractStringUint64(&val, data->base,
247  data->nbytes, (const char *)ptr);
248  if(extbytes <= 0) {
249  SCLogError(SC_ERR_BYTE_EXTRACT_FAILED,"Error extracting %d bytes "
250  "of string data: %d", data->nbytes, extbytes);
251  return -1;
252  }
253  }
254  else {
255  int endianness = (data->flags & DETECT_BYTEJUMP_LITTLE) ? BYTE_LITTLE_ENDIAN : BYTE_BIG_ENDIAN;
256  extbytes = ByteExtractUint64(&val, endianness, data->nbytes, ptr);
257  if (extbytes != data->nbytes) {
258  SCLogError(SC_ERR_BYTE_EXTRACT_FAILED,"Error extracting %d bytes "
259  "of numeric data: %d", data->nbytes, extbytes);
260  return -1;
261  }
262  }
263 
264  //printf("VAL: (%" PRIu64 " x %" PRIu32 ") + %d + %" PRId32 "\n", val, data->multiplier, extbytes, data->post_offset);
265 
266  /* Adjust the jump value based on flags */
267  val *= data->multiplier;
268  if (data->flags & DETECT_BYTEJUMP_ALIGN) {
269  if ((val % 4) != 0) {
270  val += 4 - (val % 4);
271  }
272  }
273  val += data->post_offset;
274 
275  /* Calculate the jump location */
276  if (data->flags & DETECT_BYTEJUMP_BEGIN) {
277  jumpptr = p->payload + val;
278  //printf("NEWVAL: payload %p + %ld = %p\n", p->payload, val, jumpptr);
279  }
280  else {
281  val += extbytes;
282  jumpptr = ptr + val;
283  //printf("NEWVAL: ptr %p + %ld = %p\n", ptr, val, jumpptr);
284  }
285 
286 
287  /* Validate that the jump location is still in the packet
288  * \todo Should this validate it is still in the *payload*?
289  */
290  if ((jumpptr < p->payload) || (jumpptr >= p->payload + p->payload_len)) {
291  SCLogDebug("Jump location (%p) is not within "
292  "packet (%p-%p)", jumpptr, p->payload, p->payload + p->payload_len - 1);
293  return 0;
294  }
295 
296 #ifdef DEBUG
297  if (SCLogDebugEnabled()) {
298  uint8_t *sptr = (data->flags & DETECT_BYTEJUMP_BEGIN) ? p->payload
299  : ptr;
300  SCLogDebug("jumping %" PRId64 " bytes from %p (%08x) to %p (%08x)",
301  val, sptr, (int)(sptr - p->payload),
302  jumpptr, (int)(jumpptr - p->payload));
303  }
304 #endif /* DEBUG */
305 
306  /* Adjust the detection context to the jump location. */
307  det_ctx->buffer_offset = jumpptr - p->payload;
308 
309  return 1;
310 }
311 
312 static DetectBytejumpData *DetectBytejumpParse(const char *optstr, char **offset)
313 {
314  DetectBytejumpData *data = NULL;
315  char args[10][64];
316 #define MAX_SUBSTRINGS 30
317  int ret = 0, res = 0;
318  int ov[MAX_SUBSTRINGS];
319  int numargs = 0;
320  int i = 0;
321  uint32_t nbytes;
322  char *str_ptr;
323  char *end_ptr;
324 
325  memset(args, 0x00, sizeof(args));
326 
327  /* Execute the regex and populate args with captures. */
328  ret = pcre_exec(parse_regex, parse_regex_study, optstr,
329  strlen(optstr), 0, 0, ov, MAX_SUBSTRINGS);
330  if (ret < 2 || ret > 10) {
331  SCLogError(SC_ERR_PCRE_PARSE,"parse error, ret %" PRId32
332  ", string \"%s\"", ret, optstr);
333  goto error;
334  }
335 
336  /* The first two arguments are stashed in the first PCRE substring.
337  * This is because byte_jump can take 10 arguments, but PCRE only
338  * supports 9 substrings, sigh.
339  */
340  char str[512] = "";
341  res = pcre_copy_substring((char *)optstr, ov,
342  MAX_SUBSTRINGS, 1, str, sizeof(str));
343  if (res < 0) {
344  SCLogError(SC_ERR_PCRE_GET_SUBSTRING,"pcre_copy_substring failed "
345  "for arg 1");
346  goto error;
347  }
348 
349  /* Break up first substring into two parameters
350  *
351  * NOTE: Because of this, we cannot free args[1] as it is part of args[0],
352  * and *yes* this *is* ugly.
353  */
354  end_ptr = str;
355  while (!(isspace((unsigned char)*end_ptr) || (*end_ptr == ','))) end_ptr++;
356  *(end_ptr++) = '\0';
357  strlcpy(args[0], str, sizeof(args[0]));
358  numargs++;
359 
360  str_ptr = end_ptr;
361  while (isspace((unsigned char)*str_ptr) || (*str_ptr == ',')) str_ptr++;
362  end_ptr = str_ptr;
363  while (!(isspace((unsigned char)*end_ptr) || (*end_ptr == ',')) && (*end_ptr != '\0'))
364  end_ptr++;
365  *(end_ptr++) = '\0';
366  strlcpy(args[1], str_ptr, sizeof(args[1]));
367  numargs++;
368 
369  /* The remaining args are directly from PCRE substrings */
370  for (i = 1; i < (ret - 1); i++) {
371  res = pcre_copy_substring((char *)optstr, ov, MAX_SUBSTRINGS, i + 1, args[i+1], sizeof(args[0]));
372  if (res < 0) {
373  SCLogError(SC_ERR_PCRE_GET_SUBSTRING,"pcre_copy_substring failed for arg %d", i + 1);
374  goto error;
375  }
376  numargs++;
377  }
378 
379  /* Initialize the data */
380  data = SCMalloc(sizeof(DetectBytejumpData));
381  if (unlikely(data == NULL))
382  goto error;
384  data->flags = 0;
385  data->multiplier = 1;
386  data->post_offset = 0;
387 
388  /*
389  * The first two options are required and positional. The
390  * remaining arguments are flags and are not positional.
391  */
392 
393  /* Number of bytes */
394  if (ByteExtractStringUint32(&nbytes, 10, strlen(args[0]), args[0]) <= 0) {
395  SCLogError(SC_ERR_INVALID_VALUE, "Malformed number of bytes: %s", optstr);
396  goto error;
397  }
398 
399  /* Offset */
400  if (args[1][0] != '-' && isalpha((unsigned char)args[1][0])) {
401  if (offset == NULL) {
402  SCLogError(SC_ERR_INVALID_ARGUMENT, "byte_jump supplied with "
403  "var name for offset. \"value\" argument supplied to "
404  "this function has to be non-NULL");
405  goto error;
406  }
407  *offset = SCStrdup(args[1]);
408  if (*offset == NULL)
409  goto error;
410  } else {
411  if (ByteExtractStringInt32(&data->offset, 0, strlen(args[1]), args[1]) <= 0) {
412  SCLogError(SC_ERR_INVALID_VALUE, "Malformed offset: %s", optstr);
413  goto error;
414  }
415  }
416 
417  /* The remaining options are flags. */
418  /** \todo Error on dups? */
419  for (i = 2; i < numargs; i++) {
420  if (strcmp("relative", args[i]) == 0) {
422  } else if (strcasecmp("string", args[i]) == 0) {
423  data->flags |= DETECT_BYTEJUMP_STRING;
424  } else if (strcasecmp("dec", args[i]) == 0) {
426  } else if (strcasecmp("hex", args[i]) == 0) {
428  } else if (strcasecmp("oct", args[i]) == 0) {
430  } else if (strcasecmp("big", args[i]) == 0) {
431  if (data->flags & DETECT_BYTEJUMP_LITTLE) {
432  data->flags ^= DETECT_BYTEJUMP_LITTLE;
433  }
434  data->flags |= DETECT_BYTEJUMP_BIG;
435  } else if (strcasecmp("little", args[i]) == 0) {
436  data->flags |= DETECT_BYTEJUMP_LITTLE;
437  } else if (strcasecmp("from_beginning", args[i]) == 0) {
438  data->flags |= DETECT_BYTEJUMP_BEGIN;
439  } else if (strcasecmp("align", args[i]) == 0) {
440  data->flags |= DETECT_BYTEJUMP_ALIGN;
441  } else if (strncasecmp("multiplier ", args[i], 11) == 0) {
442  if (ByteExtractStringUint32(&data->multiplier, 10,
443  strlen(args[i]) - 11,
444  args[i] + 11) <= 0)
445  {
446  SCLogError(SC_ERR_INVALID_VALUE, "Malformed multiplier: %s", optstr);
447  goto error;
448  }
449  } else if (strncasecmp("post_offset ", args[i], 12) == 0) {
450  if (ByteExtractStringInt32(&data->post_offset, 10,
451  strlen(args[i]) - 12,
452  args[i] + 12) <= 0)
453  {
454  SCLogError(SC_ERR_INVALID_VALUE, "Malformed post_offset: %s", optstr);
455  goto error;
456  }
457  } else if (strcasecmp("dce", args[i]) == 0) {
458  data->flags |= DETECT_BYTEJUMP_DCE;
459  } else {
460  SCLogError(SC_ERR_INVALID_VALUE, "Unknown option: \"%s\"", args[i]);
461  goto error;
462  }
463  }
464 
465  if (data->flags & DETECT_BYTEJUMP_STRING) {
466  /* 23 - This is the largest string (octal, with a zero prefix) that
467  * will not overflow uint64_t. The only way this length
468  * could be over 23 and still not overflow is if it were zero
469  * prefixed and we only support 1 byte of zero prefix for octal.
470  *
471  * "01777777777777777777777" = 0xffffffffffffffff
472  */
473  if (nbytes > 23) {
474  SCLogError(SC_ERR_INVALID_VALUE, "Cannot test more than 23 bytes "
475  "with \"string\": %s", optstr);
476  goto error;
477  }
478  } else {
479  if (nbytes > 8) {
480  SCLogError(SC_ERR_INVALID_VALUE, "Cannot test more than 8 bytes "
481  "without \"string\": %s\n", optstr);
482  goto error;
483  }
484  if (data->base != DETECT_BYTEJUMP_BASE_UNSET) {
485  SCLogError(SC_ERR_INVALID_VALUE, "Cannot use a base "
486  "without \"string\": %s", optstr);
487  goto error;
488  }
489  }
490 
491  /* This is max 23 so it will fit in a byte (see above) */
492  data->nbytes = (uint8_t)nbytes;
493 
494  return data;
495 
496 error:
497  if (offset != NULL && *offset != NULL) {
498  SCFree(*offset);
499  *offset = NULL;
500  }
501  if (data != NULL)
502  DetectBytejumpFree(data);
503  return NULL;
504 }
505 
506 static int DetectBytejumpSetup(DetectEngineCtx *de_ctx, Signature *s, const char *optstr)
507 {
508  SigMatch *sm = NULL;
509  SigMatch *prev_pm = NULL;
510  DetectBytejumpData *data = NULL;
511  char *offset = NULL;
512  int ret = -1;
513 
514  data = DetectBytejumpParse(optstr, &offset);
515  if (data == NULL)
516  goto error;
517 
518  int sm_list;
519  if (s->init_data->list != DETECT_SM_LIST_NOTSET) {
520  if (DetectBufferGetActiveList(de_ctx, s) == -1)
521  goto error;
522 
523  sm_list = s->init_data->list;
524 
525  if (data->flags & DETECT_BYTEJUMP_RELATIVE) {
527  }
528  } else if (data->flags & DETECT_BYTEJUMP_DCE) {
529  if (data->flags & DETECT_BYTEJUMP_RELATIVE) {
530  prev_pm = DetectGetLastSMFromLists(s,
533  DETECT_ISDATAAT, -1);
534  if (prev_pm == NULL) {
535  sm_list = DETECT_SM_LIST_PMATCH;
536  } else {
537  sm_list = SigMatchListSMBelongsTo(s, prev_pm);
538  if (sm_list < 0)
539  goto error;
540  }
541  } else {
542  sm_list = DETECT_SM_LIST_PMATCH;
543  }
544 
546  goto error;
547 
548  } else if (data->flags & DETECT_BYTEJUMP_RELATIVE) {
549  prev_pm = DetectGetLastSMFromLists(s,
552  DETECT_ISDATAAT, -1);
553  if (prev_pm == NULL) {
554  sm_list = DETECT_SM_LIST_PMATCH;
555  } else {
556  sm_list = SigMatchListSMBelongsTo(s, prev_pm);
557  if (sm_list < 0)
558  goto error;
559  }
560 
561  } else {
562  sm_list = DETECT_SM_LIST_PMATCH;
563  }
564 
565  if (data->flags & DETECT_BYTEJUMP_DCE) {
566  if ((data->flags & DETECT_BYTEJUMP_STRING) ||
567  (data->flags & DETECT_BYTEJUMP_LITTLE) ||
568  (data->flags & DETECT_BYTEJUMP_BIG) ||
569  (data->flags & DETECT_BYTEJUMP_BEGIN) ||
570  (data->base == DETECT_BYTEJUMP_BASE_DEC) ||
571  (data->base == DETECT_BYTEJUMP_BASE_HEX) ||
572  (data->base == DETECT_BYTEJUMP_BASE_OCT) ) {
573  SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "Invalid option. "
574  "A byte_jump keyword with dce holds other invalid modifiers.");
575  goto error;
576  }
577  }
578 
579  if (offset != NULL) {
580  SigMatch *bed_sm = DetectByteExtractRetrieveSMVar(offset, s);
581  if (bed_sm == NULL) {
582  SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var "
583  "seen in byte_jump - %s\n", offset);
584  goto error;
585  }
586  data->offset = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
588  SCFree(offset);
589  }
590 
591  sm = SigMatchAlloc();
592  if (sm == NULL)
593  goto error;
594  sm->type = DETECT_BYTEJUMP;
595  sm->ctx = (SigMatchCtx *)data;
596  SigMatchAppendSMToList(s, sm, sm_list);
597 
598  if (!(data->flags & DETECT_BYTEJUMP_RELATIVE))
599  goto okay;
600 
601  if (prev_pm == NULL)
602  goto okay;
603 
604  if (prev_pm->type == DETECT_CONTENT) {
605  DetectContentData *cd = (DetectContentData *)prev_pm->ctx;
607  } else if (prev_pm->type == DETECT_PCRE) {
608  DetectPcreData *pd = (DetectPcreData *)prev_pm->ctx;
610  }
611 
612  okay:
613  ret = 0;
614  return ret;
615  error:
616  DetectBytejumpFree(data);
617  return ret;
618 }
619 
620 /**
621  * \brief this function will free memory associated with DetectBytejumpData
622  *
623  * \param data pointer to DetectBytejumpData
624  */
625 static void DetectBytejumpFree(void *ptr)
626 {
627  if (ptr == NULL)
628  return;
629 
630  DetectBytejumpData *data = (DetectBytejumpData *)ptr;
631  SCFree(data);
632 }
633 
634 
635 /* UNITTESTS */
636 #ifdef UNITTESTS
637 #include "util-unittest-helper.h"
638 static int g_file_data_buffer_id = 0;
639 static int g_dce_stub_data_buffer_id = 0;
640 
641 /**
642  * \test DetectBytejumpTestParse01 is a test to make sure that we return
643  * "something" when given valid bytejump opt
644  */
645 static int DetectBytejumpTestParse01(void)
646 {
647  int result = 0;
648  DetectBytejumpData *data = NULL;
649  data = DetectBytejumpParse("4,0", NULL);
650  if (data != NULL) {
651  DetectBytejumpFree(data);
652  result = 1;
653  }
654 
655  return result;
656 }
657 
658 /**
659  * \test DetectBytejumpTestParse02 is a test for setting the required opts
660  */
661 static int DetectBytejumpTestParse02(void)
662 {
663  int result = 0;
664  DetectBytejumpData *data = NULL;
665  data = DetectBytejumpParse("4, 0", NULL);
666  if (data != NULL) {
667  if ( (data->nbytes == 4)
668  && (data->offset == 0)
669  && (data->multiplier == 1)
670  && (data->post_offset == 0)
671  && (data->flags == 0)
672  && (data->base == DETECT_BYTEJUMP_BASE_UNSET))
673  {
674  result = 1;
675  }
676  DetectBytejumpFree(data);
677  }
678 
679  return result;
680 }
681 
682 /**
683  * \test DetectBytejumpTestParse03 is a test for setting the optional flags
684  */
685 static int DetectBytejumpTestParse03(void)
686 {
687  int result = 0;
688  DetectBytejumpData *data = NULL;
689  data = DetectBytejumpParse(" 4,0 , relative , little, string, "
690  "dec, align, from_beginning", NULL);
691  if (data != NULL) {
692  if ( (data->nbytes == 4)
693  && (data->offset == 0)
694  && (data->multiplier == 1)
695  && (data->post_offset == 0)
696  && (data->flags == ( DETECT_BYTEJUMP_RELATIVE
701  && (data->base == DETECT_BYTEJUMP_BASE_DEC))
702  {
703  result = 1;
704  }
705  DetectBytejumpFree(data);
706  }
707 
708  return result;
709 }
710 
711 /**
712  * \test DetectBytejumpTestParse04 is a test for setting the optional flags
713  * with parameters
714  *
715  * \todo This fails becuase we can only have 9 captures and there are 10.
716  */
717 static int DetectBytejumpTestParse04(void)
718 {
719  int result = 0;
720  DetectBytejumpData *data = NULL;
721  data = DetectBytejumpParse(" 4,0 , relative , little, string, "
722  "dec, align, from_beginning , "
723  "multiplier 2 , post_offset -16 ", NULL);
724  if (data != NULL) {
725  if ( (data->nbytes == 4)
726  && (data->offset == 0)
727  && (data->multiplier == 2)
728  && (data->post_offset == -16)
729  && (data->flags == ( DETECT_BYTEJUMP_RELATIVE
734  && (data->base == DETECT_BYTEJUMP_BASE_DEC))
735  {
736  result = 1;
737  }
738  DetectBytejumpFree(data);
739  }
740 
741  return result;
742 }
743 
744 /**
745  * \test DetectBytejumpTestParse05 is a test for setting base without string
746  */
747 static int DetectBytejumpTestParse05(void)
748 {
749  int result = 0;
750  DetectBytejumpData *data = NULL;
751  data = DetectBytejumpParse(" 4,0 , relative , little, dec, "
752  "align, from_beginning", NULL);
753  if (data == NULL) {
754  result = 1;
755  }
756 
757  return result;
758 }
759 
760 /**
761  * \test DetectBytejumpTestParse06 is a test for too many bytes to extract
762  */
763 static int DetectBytejumpTestParse06(void)
764 {
765  int result = 0;
766  DetectBytejumpData *data = NULL;
767  data = DetectBytejumpParse("9, 0", NULL);
768  if (data == NULL) {
769  result = 1;
770  }
771 
772  return result;
773 }
774 
775 /**
776  * \test DetectBytejumpTestParse07 is a test for too many string bytes to extract
777  */
778 static int DetectBytejumpTestParse07(void)
779 {
780  int result = 0;
781  DetectBytejumpData *data = NULL;
782  data = DetectBytejumpParse("24, 0, string, dec", NULL);
783  if (data == NULL) {
784  result = 1;
785  }
786 
787  return result;
788 }
789 
790 /**
791  * \test DetectBytejumpTestParse08 is a test for offset too big
792  */
793 static int DetectBytejumpTestParse08(void)
794 {
795  int result = 0;
796  DetectBytejumpData *data = NULL;
797  data = DetectBytejumpParse("4, 0xffffffffffffffff", NULL);
798  if (data == NULL) {
799  result = 1;
800  }
801 
802  return result;
803 }
804 
805 /**
806  * \test Test dce option.
807  */
808 static int DetectBytejumpTestParse09(void)
809 {
810  Signature *s = SigAlloc();
811  if (s == NULL)
812  return 0;
813 
814  int result = 1;
815 
816  s->alproto = ALPROTO_DCERPC;
817 
818  result &= (DetectBytejumpSetup(NULL, s, "4,0, align, multiplier 2, "
819  "post_offset -16,dce") == 0);
820  result &= (DetectBytejumpSetup(NULL, s, "4,0, multiplier 2, "
821  "post_offset -16,dce") == 0);
822  result &= (DetectBytejumpSetup(NULL, s, "4,0,post_offset -16,dce") == 0);
823  result &= (DetectBytejumpSetup(NULL, s, "4,0,dce") == 0);
824  result &= (DetectBytejumpSetup(NULL, s, "4,0,dce") == 0);
825  result &= (DetectBytejumpSetup(NULL, s, "4,0, string, dce") == -1);
826  result &= (DetectBytejumpSetup(NULL, s, "4,0, big, dce") == -1);
827  result &= (DetectBytejumpSetup(NULL, s, "4,0, little, dce") == -1);
828  result &= (DetectBytejumpSetup(NULL, s, "4,0, string, dec, dce") == -1);
829  result &= (DetectBytejumpSetup(NULL, s, "4,0, string, oct, dce") == -1);
830  result &= (DetectBytejumpSetup(NULL, s, "4,0, string, hex, dce") == -1);
831  result &= (DetectBytejumpSetup(NULL, s, "4,0, from_beginning, dce") == -1);
832  result &= (s->sm_lists[g_dce_stub_data_buffer_id] == NULL && s->sm_lists[DETECT_SM_LIST_PMATCH] != NULL);
833 
834  SigFree(s);
835  return result;
836 }
837 
838 /**
839  * \test Test dce option.
840  */
841 static int DetectBytejumpTestParse10(void)
842 {
843  DetectEngineCtx *de_ctx = NULL;
844  int result = 1;
845  Signature *s = NULL;
846  DetectBytejumpData *bd = NULL;
847 
848  de_ctx = DetectEngineCtxInit();
849  if (de_ctx == NULL)
850  goto end;
851 
852  de_ctx->flags |= DE_QUIET;
853  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
854  "(msg:\"Testing bytejump_body\"; "
855  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
856  "dce_stub_data; "
857  "content:\"one\"; distance:0; "
858  "byte_jump:4,0,align,multiplier 2, "
859  "post_offset -16,relative,dce; sid:1;)");
860  if (de_ctx->sig_list == NULL) {
861  result = 0;
862  goto end;
863  }
864  s = de_ctx->sig_list;
865  if (s->sm_lists_tail[g_dce_stub_data_buffer_id] == NULL) {
866  result = 0;
867  goto end;
868  }
869  result &= (s->sm_lists_tail[g_dce_stub_data_buffer_id]->type == DETECT_BYTEJUMP);
870  bd = (DetectBytejumpData *)s->sm_lists_tail[g_dce_stub_data_buffer_id]->ctx;
871  if (!(bd->flags & DETECT_BYTEJUMP_DCE) &&
872  !(bd->flags & DETECT_BYTEJUMP_RELATIVE) &&
873  (bd->flags & DETECT_BYTEJUMP_STRING) &&
874  (bd->flags & DETECT_BYTEJUMP_BIG) &&
875  (bd->flags & DETECT_BYTEJUMP_LITTLE) ) {
876  result = 0;
877  goto end;
878  }
879 
880  s->next = SigInit(de_ctx, "alert tcp any any -> any any "
881  "(msg:\"Testing bytejump_body\"; "
882  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
883  "dce_stub_data; "
884  "content:\"one\"; distance:0; "
885  "byte_jump:4,0,align,multiplier 2, "
886  "post_offset -16,relative,dce; sid:1;)");
887  if (s->next == NULL) {
888  result = 0;
889  goto end;
890  }
891  s = s->next;
892  if (s->sm_lists_tail[g_dce_stub_data_buffer_id] == NULL) {
893  result = 0;
894  goto end;
895  }
896  result &= (s->sm_lists_tail[g_dce_stub_data_buffer_id]->type == DETECT_BYTEJUMP);
897  bd = (DetectBytejumpData *)s->sm_lists_tail[g_dce_stub_data_buffer_id]->ctx;
898  if (!(bd->flags & DETECT_BYTEJUMP_DCE) &&
899  !(bd->flags & DETECT_BYTEJUMP_RELATIVE) &&
900  (bd->flags & DETECT_BYTEJUMP_STRING) &&
901  (bd->flags & DETECT_BYTEJUMP_BIG) &&
902  (bd->flags & DETECT_BYTEJUMP_LITTLE) ) {
903  result = 0;
904  goto end;
905  }
906 
907  s->next = 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\"; distance:0; "
912  "byte_jump:4,0,align,multiplier 2, "
913  "post_offset -16,relative; sid:1;)");
914  if (s->next == NULL) {
915  result = 0;
916  goto end;
917  }
918  s = s->next;
919  if (s->sm_lists_tail[g_dce_stub_data_buffer_id] == NULL) {
920  result = 0;
921  goto end;
922  }
923  result &= (s->sm_lists_tail[g_dce_stub_data_buffer_id]->type == DETECT_BYTEJUMP);
924  bd = (DetectBytejumpData *)s->sm_lists_tail[g_dce_stub_data_buffer_id]->ctx;
925  if ((bd->flags & DETECT_BYTEJUMP_DCE) &&
926  !(bd->flags & DETECT_BYTEJUMP_RELATIVE) &&
927  (bd->flags & DETECT_BYTEJUMP_STRING) &&
928  (bd->flags & DETECT_BYTEJUMP_BIG) &&
929  (bd->flags & DETECT_BYTEJUMP_LITTLE) ) {
930  result = 0;
931  goto end;
932  }
933 
934  end:
935  SigGroupCleanup(de_ctx);
936  SigCleanSignatures(de_ctx);
937  DetectEngineCtxFree(de_ctx);
938 
939  return result;
940 }
941 
942 /**
943  * \test Test dce option.
944  */
945 static int DetectBytejumpTestParse11(void)
946 {
947  DetectEngineCtx *de_ctx = NULL;
948  int result = 1;
949  Signature *s = NULL;
950 
951  de_ctx = DetectEngineCtxInit();
952  if (de_ctx == NULL)
953  goto end;
954 
955  de_ctx->flags |= DE_QUIET;
956  s = SigInit(de_ctx, "alert tcp any any -> any any "
957  "(msg:\"Testing bytejump_body\"; "
958  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
959  "dce_stub_data; "
960  "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
961  "post_offset -16,string,dce; sid:1;)");
962  if (s != NULL) {
963  result = 0;
964  goto end;
965  }
966 
967  s = SigInit(de_ctx, "alert tcp any any -> any any "
968  "(msg:\"Testing bytejump_body\"; "
969  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
970  "dce_sub_data; "
971  "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
972  "post_offset -16,big,dce; sid:1;)");
973  if (s != NULL) {
974  result = 0;
975  goto end;
976  }
977 
978  s = SigInit(de_ctx, "alert tcp any any -> any any "
979  "(msg:\"Testing bytejump_body\"; "
980  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
981  "dce_stub_data; "
982  "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
983  "post_offset -16,little,dce; sid:1;)");
984  if (s != NULL) {
985  result = 0;
986  goto end;
987  }
988 
989  s = SigInit(de_ctx, "alert tcp any any -> any any "
990  "(msg:\"Testing bytejump_body\"; "
991  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
992  "dce_stub_data; "
993  "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
994  "post_offset -16,string,hex,dce; sid:1;)");
995  if (s != NULL) {
996  result = 0;
997  goto end;
998  }
999 
1000  s = SigInit(de_ctx, "alert tcp any any -> any any "
1001  "(msg:\"Testing bytejump_body\"; "
1002  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1003  "dce_stub_data; "
1004  "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
1005  "post_offset -16,string,dec,dce; sid:1;)");
1006  if (s != NULL) {
1007  result = 0;
1008  goto end;
1009  }
1010 
1011  s = SigInit(de_ctx, "alert tcp any any -> any any "
1012  "(msg:\"Testing bytejump_body\"; "
1013  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1014  "dce_stub_data; "
1015  "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
1016  "post_offset -16,string,oct,dce; sid:1;)");
1017  if (s != NULL) {
1018  result = 0;
1019  goto end;
1020  }
1021 
1022  s = SigInit(de_ctx, "alert tcp any any -> any any "
1023  "(msg:\"Testing bytejump_body\"; "
1024  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1025  "dce_stub_data; "
1026  "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
1027  "post_offset -16,from_beginning,dce; sid:1;)");
1028  if (s != NULL) {
1029  result = 0;
1030  goto end;
1031  }
1032 
1033  end:
1034  SigGroupCleanup(de_ctx);
1035  SigCleanSignatures(de_ctx);
1036  DetectEngineCtxFree(de_ctx);
1037 
1038  return result;
1039 }
1040 
1041 /**
1042  * \test Test file_data
1043  */
1044 static int DetectBytejumpTestParse12(void)
1045 {
1046  DetectEngineCtx *de_ctx = NULL;
1047  int result = 0;
1048  Signature *s = NULL;
1049  DetectBytejumpData *bd = NULL;
1050 
1051  de_ctx = DetectEngineCtxInit();
1052  if (de_ctx == NULL)
1053  goto end;
1054 
1055  de_ctx->flags |= DE_QUIET;
1056  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
1057  "(file_data; byte_jump:4,0,align,multiplier 2, "
1058  "post_offset -16,relative; sid:1;)");
1059  if (de_ctx->sig_list == NULL) {
1060  goto end;
1061  }
1062 
1063  s = de_ctx->sig_list;
1064  if (s->sm_lists_tail[g_file_data_buffer_id] == NULL) {
1065  goto end;
1066  }
1067 
1068  if (s->sm_lists_tail[g_file_data_buffer_id]->type != DETECT_BYTEJUMP) {
1069  goto end;
1070  }
1071 
1072  bd = (DetectBytejumpData *)s->sm_lists_tail[g_file_data_buffer_id]->ctx;
1073  if ((bd->flags & DETECT_BYTEJUMP_DCE) &&
1074  (bd->flags & DETECT_BYTEJUMP_RELATIVE) &&
1075  (bd->flags & DETECT_BYTEJUMP_STRING) &&
1076  (bd->flags & DETECT_BYTEJUMP_BIG) &&
1077  (bd->flags & DETECT_BYTEJUMP_LITTLE) ) {
1078  result = 0;
1079  goto end;
1080  }
1081 
1082  result = 1;
1083  end:
1084  SigGroupCleanup(de_ctx);
1085  SigCleanSignatures(de_ctx);
1086  DetectEngineCtxFree(de_ctx);
1087 
1088  return result;
1089 }
1090 
1091 /**
1092  * \test DetectByteJumpTestPacket01 is a test to check matches of
1093  * byte_jump and byte_jump relative works if the previous keyword is pcre
1094  * (bug 142)
1095  */
1096 static int DetectByteJumpTestPacket01 (void)
1097 {
1098  int result = 0;
1099  uint8_t *buf = (uint8_t *)"GET /AllWorkAndNoPlayMakesWillADullBoy HTTP/1.0"
1100  "User-Agent: Wget/1.11.4"
1101  "Accept: */*"
1102  "Host: www.google.com"
1103  "Connection: Keep-Alive"
1104  "Date: Mon, 04 Jan 2010 17:29:39 GMT";
1105  uint16_t buflen = strlen((char *)buf);
1106  Packet *p;
1107  p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
1108 
1109  if (p == NULL)
1110  goto end;
1111 
1112  char sig[] = "alert tcp any any -> any any (msg:\"pcre + byte_test + "
1113  "relative\"; pcre:\"/AllWorkAndNoPlayMakesWillADullBoy/\"; byte_jump:1,6,"
1114  "relative,string,dec; content:\"0\"; sid:134; rev:1;)";
1115 
1116  result = UTHPacketMatchSig(p, sig);
1117 
1118  UTHFreePacket(p);
1119 end:
1120  return result;
1121 }
1122 
1123 /**
1124  * \test DetectByteJumpTestPacket02 is a test to check matches of
1125  * byte_jump and byte_jump relative works if the previous keyword is byte_jump
1126  * (bug 165)
1127  */
1128 static int DetectByteJumpTestPacket02 (void)
1129 {
1130  int result = 0;
1131  uint8_t buf[] = { 0x00, 0x00, 0x00, 0x77, 0xff, 0x53,
1132  0x4d, 0x42, 0x2f, 0x00, 0x00, 0x00, 0x00, 0x18,
1133  0x01, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1134  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
1135  0x92, 0xa4, 0x01, 0x08, 0x17, 0x5c, 0x0e, 0xff,
1136  0x00, 0x00, 0x00, 0x01, 0x40, 0x48, 0x00, 0x00,
1137  0x00, 0xff };
1138  uint16_t buflen = sizeof(buf);
1139  Packet *p;
1140  p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
1141 
1142  if (p == NULL)
1143  goto end;
1144 
1145  char sig[] = "alert tcp any any -> any any (msg:\"byte_jump with byte_jump"
1146  " + relative\"; byte_jump:1,13; byte_jump:4,0,relative; "
1147  "content:\"|48 00 00|\"; within:3; sid:144; rev:1;)";
1148 
1149  result = UTHPacketMatchSig(p, sig);
1150 
1151  UTHFreePacket(p);
1152 end:
1153  return result;
1154 }
1155 
1156 static int DetectByteJumpTestPacket03(void)
1157 {
1158  int result = 0;
1159  uint8_t *buf = NULL;
1160  uint16_t buflen = 0;
1161  buf = SCMalloc(4);
1162  if (unlikely(buf == NULL)) {
1163  printf("malloc failed\n");
1164  exit(EXIT_FAILURE);
1165  }
1166  memcpy(buf, "boom", 4);
1167  buflen = 4;
1168 
1169  Packet *p;
1170  p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
1171 
1172  if (p == NULL)
1173  goto end;
1174 
1175  char sig[] = "alert tcp any any -> any any (msg:\"byte_jump\"; "
1176  "byte_jump:1,214748364; sid:1; rev:1;)";
1177 
1178  result = !UTHPacketMatchSig(p, sig);
1179 
1180  UTHFreePacket(p);
1181 
1182 end:
1183  if (buf != NULL)
1184  SCFree(buf);
1185  return result;
1186 }
1187 
1188 /**
1189  * \test check matches of with from_beginning (bug 626/627)
1190  */
1191 static int DetectByteJumpTestPacket04 (void)
1192 {
1193  int result = 0;
1194  uint8_t *buf = (uint8_t *)"XYZ04abcdABCD";
1195  uint16_t buflen = strlen((char *)buf);
1196  Packet *p;
1197  p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
1198 
1199  if (p == NULL)
1200  goto end;
1201 
1202  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;)";
1203 
1204  result = UTHPacketMatchSig(p, sig);
1205 
1206  UTHFreePacket(p);
1207 end:
1208  return result;
1209 }
1210 
1211 /**
1212  * \test check matches of with from_beginning (bug 626/627)
1213  */
1214 static int DetectByteJumpTestPacket05 (void)
1215 {
1216  int result = 0;
1217  uint8_t *buf = (uint8_t *)"XYZ04abcdABCD";
1218  uint16_t buflen = strlen((char *)buf);
1219  Packet *p;
1220  p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
1221 
1222  if (p == NULL)
1223  goto end;
1224 
1225  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;)";
1226 
1227  result = UTHPacketMatchSig(p, sig) ? 0 : 1;
1228 
1229  UTHFreePacket(p);
1230 end:
1231  return result;
1232 }
1233 
1234 /**
1235  * \test check matches of with from_beginning (bug 626/627)
1236  */
1237 static int DetectByteJumpTestPacket06 (void)
1238 {
1239  int result = 0;
1240  uint8_t *buf = (uint8_t *)"XX04abcdABCD";
1241  uint16_t buflen = strlen((char *)buf);
1242  Packet *p;
1243  p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
1244 
1245  if (p == NULL)
1246  goto end;
1247 
1248  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;)";
1249 
1250  result = UTHPacketMatchSig(p, sig);
1251 
1252  UTHFreePacket(p);
1253 end:
1254  return result;
1255 }
1256 
1257 /**
1258  * \test check matches of with from_beginning (bug 626/627)
1259  */
1260 static int DetectByteJumpTestPacket07 (void)
1261 {
1262  int result = 0;
1263  uint8_t *buf = (uint8_t *)"XX04abcdABCD";
1264  uint16_t buflen = strlen((char *)buf);
1265  Packet *p;
1266  p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
1267 
1268  if (p == NULL)
1269  goto end;
1270 
1271  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;)";
1272 
1273  result = UTHPacketMatchSig(p, sig) ? 1 : 0;
1274 
1275  UTHFreePacket(p);
1276 end:
1277  return result;
1278 }
1279 
1280 #endif /* UNITTESTS */
1281 
1282 
1283 /**
1284  * \brief this function registers unit tests for DetectBytejump
1285  */
1286 static void DetectBytejumpRegisterTests(void)
1287 {
1288 #ifdef UNITTESTS
1289  g_file_data_buffer_id = DetectBufferTypeGetByName("file_data");
1290  g_dce_stub_data_buffer_id = DetectBufferTypeGetByName("dce_stub_data");
1291 
1292  UtRegisterTest("DetectBytejumpTestParse01", DetectBytejumpTestParse01);
1293  UtRegisterTest("DetectBytejumpTestParse02", DetectBytejumpTestParse02);
1294  UtRegisterTest("DetectBytejumpTestParse03", DetectBytejumpTestParse03);
1295  UtRegisterTest("DetectBytejumpTestParse04", DetectBytejumpTestParse04);
1296  UtRegisterTest("DetectBytejumpTestParse05", DetectBytejumpTestParse05);
1297  UtRegisterTest("DetectBytejumpTestParse06", DetectBytejumpTestParse06);
1298  UtRegisterTest("DetectBytejumpTestParse07", DetectBytejumpTestParse07);
1299  UtRegisterTest("DetectBytejumpTestParse08", DetectBytejumpTestParse08);
1300  UtRegisterTest("DetectBytejumpTestParse09", DetectBytejumpTestParse09);
1301  UtRegisterTest("DetectBytejumpTestParse10", DetectBytejumpTestParse10);
1302  UtRegisterTest("DetectBytejumpTestParse11", DetectBytejumpTestParse11);
1303  UtRegisterTest("DetectBytejumpTestParse12", DetectBytejumpTestParse12);
1304 
1305  UtRegisterTest("DetectByteJumpTestPacket01", DetectByteJumpTestPacket01);
1306  UtRegisterTest("DetectByteJumpTestPacket02", DetectByteJumpTestPacket02);
1307  UtRegisterTest("DetectByteJumpTestPacket03", DetectByteJumpTestPacket03);
1308  UtRegisterTest("DetectByteJumpTestPacket04", DetectByteJumpTestPacket04);
1309  UtRegisterTest("DetectByteJumpTestPacket05", DetectByteJumpTestPacket05);
1310  UtRegisterTest("DetectByteJumpTestPacket06", DetectByteJumpTestPacket06);
1311  UtRegisterTest("DetectByteJumpTestPacket07", DetectByteJumpTestPacket07);
1312 #endif /* UNITTESTS */
1313 }
1314 
#define DETECT_BYTEJUMP_BEGIN
SigTableElmt sigmatch_table[DETECT_TBLSIZE]
Definition: detect.h:1403
SignatureInitData * init_data
Definition: detect.h:560
uint16_t flags
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1146
#define SCLogDebug(...)
Definition: util-debug.h:335
#define DETECT_BYTEJUMP_BASE_UNSET
int DetectSignatureSetAppProto(Signature *s, AppProto alproto)
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: util-strlcpyu.c:43
int ByteExtractStringInt32(int32_t *res, int base, uint16_t len, const char *str)
Definition: util-byte.c:315
#define unlikely(expr)
Definition: util-optimize.h:35
Signature * SigInit(DetectEngineCtx *, const char *)
Parses a signature and adds it to the Detection Engine Context.
Signature * sig_list
Definition: detect.h:726
uint64_t offset
void SigCleanSignatures(DetectEngineCtx *de_ctx)
#define DETECT_BYTEJUMP_LITTLE
int ByteExtractStringUint32(uint32_t *res, int base, uint16_t len, const char *str)
Definition: util-byte.c:196
uint32_t buffer_offset
Definition: detect.h:991
const char * name
Definition: detect.h:1160
Signature container.
Definition: detect.h:492
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition: detect.h:319
uint16_t flags
Definition: detect-pcre.h:42
main detection engine ctx
Definition: detect.h:720
int SCLogDebugEnabled(void)
Returns whether debug messages are enabled to be logged or not.
Definition: util-debug.c:631
int DetectBufferGetActiveList(DetectEngineCtx *de_ctx, Signature *s)
int ByteExtractStringUint64(uint64_t *res, int base, uint16_t len, const char *str)
Definition: util-byte.c:191
#define DE_QUIET
Definition: detect.h:298
int DetectBufferTypeGetByName(const char *name)
#define str(s)
uint8_t flags
Definition: detect.h:721
#define DETECT_BYTEJUMP_BASE_DEC
void(* Free)(void *)
Definition: detect.h:1151
int UTHPacketMatchSig(Packet *p, const char *sig)
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:294
void SigFree(Signature *)
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
void DetectSetupParseRegexes(const char *parse_str, pcre **parse_regex, pcre_extra **parse_regex_study)
#define SCEnter(...)
Definition: util-debug.h:337
#define DETECT_SM_LIST_NOTSET
Definition: detect.h:118
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.
void DetectBytejumpRegister(void)
AppProto alproto
Definition: detect.h:496
#define BYTE_BIG_ENDIAN
Definition: util-byte.h:29
int SigGroupCleanup(DetectEngineCtx *de_ctx)
struct Signature_ * next
Definition: detect.h:563
uint8_t type
Definition: detect.h:325
#define SCReturnInt(x)
Definition: util-debug.h:341
int DetectBytejumpDoMatch(DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchCtx *ctx, uint8_t *payload, uint32_t payload_len, uint8_t flags, int32_t offset)
Byte jump match function.
#define DETECT_BYTEJUMP_BIG
#define BYTE_LITTLE_ENDIAN
Definition: util-byte.h:30
void SigMatchAppendSMToList(Signature *s, SigMatch *new, int list)
Append a SigMatch to the list type.
Definition: detect-parse.c:282
Signature * SigAlloc(void)
SigMatch * DetectByteExtractRetrieveSMVar(const char *arg, const Signature *s)
Lookup the SigMatch for a named byte_extract variable.
SigMatchCtx * ctx
Definition: detect.h:327
#define SCMalloc(a)
Definition: util-mem.h:174
#define DETECT_BYTEJUMP_RELATIVE
uint16_t payload_len
#define SCFree(a)
Definition: util-mem.h:236
PoolThreadReserved res
int(* Match)(ThreadVars *, DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1129
SigMatch * DetectGetLastSMFromLists(const Signature *s,...)
Returns the sm with the largest index (added latest) from the lists passed to us. ...
Definition: detect-parse.c:401
int ByteExtractUint64(uint64_t *res, int e, uint16_t len, const uint8_t *bytes)
Definition: util-byte.c:74
void UTHFreePacket(Packet *p)
UTHFreePacket: function to release the allocated data from UTHBuildPacket and the packet itself...
#define MAX_SUBSTRINGS
#define SCStrdup(a)
Definition: util-mem.h:220
#define PARSE_REGEX
Regex for parsing our options.
#define DETECT_PCRE_RELATIVE_NEXT
Definition: detect-pcre.h:32
#define DETECT_CONTENT_RELATIVE_NEXT
SigMatch * SigMatchAlloc(void)
Definition: detect-parse.c:226
uint8_t len
Per thread variable structure.
Definition: threadvars.h:57
#define DETECT_BYTEJUMP_BASE_HEX
#define DETECT_BYTEJUMP_BASE_OCT
Holds data related to byte_extract keyword.
#define DETECT_BYTEJUMP_OFFSET_BE
int SigMatchListSMBelongsTo(const Signature *s, const SigMatch *key_sm)
Definition: detect-parse.c:555
uint16_t payload_len
Definition: decode.h:546
#define DETECT_BYTEJUMP_ALIGN
#define DETECT_BYTEJUMP_DCE
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
uint8_t * payload
Definition: decode.h:545
void(* RegisterTests)(void)
Definition: detect.h:1152
a single match condition for a signature
Definition: detect.h:324
#define DETECT_BYTEJUMP_STRING
DetectEngineCtx * DetectEngineCtxInit(void)