Coverage Report

Created: 2026-07-10 06:40

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/yara/libyara/exec.c
Line
Count
Source
1
/*
2
Copyright (c) 2013-2014. The YARA Authors. All Rights Reserved.
3
4
Redistribution and use in source and binary forms, with or without modification,
5
are permitted provided that the following conditions are met:
6
7
1. Redistributions of source code must retain the above copyright notice, this
8
list of conditions and the following disclaimer.
9
10
2. Redistributions in binary form must reproduce the above copyright notice,
11
this list of conditions and the following disclaimer in the documentation and/or
12
other materials provided with the distribution.
13
14
3. Neither the name of the copyright holder nor the names of its contributors
15
may be used to endorse or promote products derived from this software without
16
specific prior written permission.
17
18
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
22
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
*/
29
30
#include <assert.h>
31
#include <float.h>
32
#include <math.h>
33
#include <string.h>
34
#include <yara.h>
35
#include <yara/arena.h>
36
#include <yara/endian.h>
37
#include <yara/error.h>
38
#include <yara/exec.h>
39
#include <yara/globals.h>
40
#include <yara/limits.h>
41
#include <yara/mem.h>
42
#include <yara/modules.h>
43
#include <yara/object.h>
44
#include <yara/re.h>
45
#include <yara/sizedstr.h>
46
#include <yara/stopwatch.h>
47
#include <yara/strutils.h>
48
#include <yara/unaligned.h>
49
#include <yara/utils.h>
50
51
16.5k
#define MEM_SIZE YR_MAX_LOOP_NESTING*(YR_MAX_LOOP_VARS + YR_INTERNAL_LOOP_VARS)
52
53
#define push(x)                         \
54
187k
  if (stack.sp < stack.capacity)        \
55
187k
  {                                     \
56
187k
    stack.items[stack.sp++] = (x);      \
57
187k
  }                                     \
58
187k
  else                                  \
59
187k
  {                                     \
60
0
    result = ERROR_EXEC_STACK_OVERFLOW; \
61
0
    stop = true;                        \
62
0
    break;                              \
63
0
  }
64
65
#define pop(x)                   \
66
187k
  {                              \
67
187k
    assert(stack.sp > 0);        \
68
187k
    x = stack.items[--stack.sp]; \
69
187k
  }
70
71
198k
#define is_undef(x) IS_UNDEFINED((x).i)
72
73
#define ensure_defined(x) \
74
103k
  if (is_undef(x))        \
75
103k
  {                       \
76
6.80k
    r1.i = YR_UNDEFINED;  \
77
6.80k
    push(r1);             \
78
6.80k
    break;                \
79
6.80k
  }
80
81
#define ensure_within_mem(x)             \
82
0
  if (x < 0 || x >= MEM_SIZE)            \
83
0
  {                                      \
84
0
    stop = true;                         \
85
0
    result = ERROR_INTERNAL_FATAL_ERROR; \
86
0
    break;                               \
87
0
  }
88
89
// Make sure that the string pointer is within the rules arena.
90
#define ensure_within_rules_arena(x)                              \
91
70.0k
  {                                                               \
92
70.0k
    YR_ARENA_REF ref;                                             \
93
70.0k
    if (yr_arena_ptr_to_ref(context->rules->arena, x, &ref) == 0) \
94
70.0k
    {                                                             \
95
0
      stop = true;                                                \
96
0
      result = ERROR_INTERNAL_FATAL_ERROR;                        \
97
0
      break;                                                      \
98
0
    }                                                             \
99
70.0k
  }
100
101
#define check_object_canary(o)           \
102
37.1k
  if (o->canary != context->canary)      \
103
37.1k
  {                                      \
104
0
    stop = true;                         \
105
0
    result = ERROR_INTERNAL_FATAL_ERROR; \
106
0
    break;                               \
107
0
  }
108
109
0
#define little_endian_uint8_t(x)  (x)
110
0
#define little_endian_int8_t(x)   (x)
111
0
#define little_endian_uint16_t(x) yr_le16toh(x)
112
0
#define little_endian_int16_t(x)  yr_le16toh(x)
113
0
#define little_endian_uint32_t(x) yr_le32toh(x)
114
0
#define little_endian_int32_t(x)  yr_le32toh(x)
115
116
0
#define big_endian_uint8_t(x)  (x)
117
0
#define big_endian_int8_t(x)   (x)
118
0
#define big_endian_uint16_t(x) yr_be16toh(x)
119
0
#define big_endian_int16_t(x)  yr_be16toh(x)
120
0
#define big_endian_uint32_t(x) yr_be32toh(x)
121
0
#define big_endian_int32_t(x)  yr_be32toh(x)
122
123
#define function_read(type, endianess)                            \
124
  int64_t read_##type##_##endianess(                              \
125
      YR_MEMORY_BLOCK_ITERATOR* iterator, size_t offset)          \
126
0
  {                                                               \
127
0
    YR_MEMORY_BLOCK* block = iterator->first(iterator);           \
128
0
    while (block != NULL)                                         \
129
0
    {                                                             \
130
0
      if (offset >= block->base && block->size >= sizeof(type) && \
131
0
          offset <= block->base + block->size - sizeof(type))     \
132
0
      {                                                           \
133
0
        type result;                                              \
134
0
        const uint8_t* data = yr_fetch_block_data(block);         \
135
0
        if (data == NULL)                                         \
136
0
          return YR_UNDEFINED;                                    \
137
0
        result = *(type*) (data + offset - block->base);          \
138
0
        result = endianess##_##type(result);                      \
139
0
        return result;                                            \
140
0
      }                                                           \
141
0
      block = iterator->next(iterator);                           \
142
0
    }                                                             \
143
0
    return YR_UNDEFINED;                                          \
144
0
  };
145
146
0
function_read(uint8_t, little_endian);
147
0
function_read(uint16_t, little_endian);
148
0
function_read(uint32_t, little_endian);
149
0
function_read(int8_t, little_endian);
150
0
function_read(int16_t, little_endian);
151
0
function_read(int32_t, little_endian);
152
0
function_read(uint8_t, big_endian);
153
0
function_read(uint16_t, big_endian);
154
0
function_read(uint32_t, big_endian);
155
0
function_read(int8_t, big_endian);
156
0
function_read(int16_t, big_endian);
157
0
function_read(int32_t, big_endian);
158
159
static const uint8_t* jmp_if(int condition, const uint8_t* ip)
160
22.7k
{
161
22.7k
  int32_t off = 0;
162
163
22.7k
  if (condition)
164
470
  {
165
    // The condition is true, the instruction pointer (ip) is incremented in
166
    // the amount specified by the jump's offset, which is a int32_t following
167
    // the jump opcode. The ip is currently past the opcode and pointing to
168
    // the offset.
169
170
    // Copy the offset from the instruction stream to a local variable.
171
470
    off = yr_unaligned_u32(ip);
172
173
    // The offset is relative to the jump opcode, but now the ip is one byte
174
    // past the opcode, so we need to decrement it by one.
175
470
    off -= 1;
176
470
  }
177
22.2k
  else
178
22.2k
  {
179
    // The condition is false, the execution flow proceeds with the instruction
180
    // right after the jump.
181
22.2k
    off = sizeof(int32_t);
182
22.2k
  }
183
184
22.7k
  return ip + off;
185
22.7k
}
186
187
static int iter_array_next(YR_ITERATOR* self, YR_VALUE_STACK* stack)
188
0
{
189
  // Check that there's two available slots in the stack, one for the next
190
  // item returned by the iterator and another one for the boolean that
191
  // indicates if there are more items.
192
0
  if (stack->sp + 1 >= stack->capacity)
193
0
    return ERROR_EXEC_STACK_OVERFLOW;
194
195
  // If the array that must be iterated is undefined stop the iteration right
196
  // aways, as if the array would be empty.
197
0
  if (IS_UNDEFINED(self->array_it.array))
198
0
    goto _stop_iter;
199
200
  // If the current index is equal or larger than array's length the iterator
201
  // has reached the end of the array.
202
0
  if (self->array_it.index >= yr_object_array_length(self->array_it.array))
203
0
    goto _stop_iter;
204
205
  // Push the false value that indicates that the iterator is not exhausted.
206
0
  stack->items[stack->sp++].i = 0;
207
208
0
  YR_OBJECT* obj = yr_object_array_get_item(
209
0
      self->array_it.array, 0, self->array_it.index);
210
211
0
  if (obj != NULL)
212
0
    stack->items[stack->sp++].o = obj;
213
0
  else
214
0
    stack->items[stack->sp++].i = YR_UNDEFINED;
215
216
0
  self->array_it.index++;
217
218
0
  return ERROR_SUCCESS;
219
220
0
_stop_iter:
221
222
  // Push true for indicating the iterator has been exhausted.
223
0
  stack->items[stack->sp++].i = 1;
224
  // Push YR_UNDEFINED as a placeholder for the next item.
225
0
  stack->items[stack->sp++].i = YR_UNDEFINED;
226
227
0
  return ERROR_SUCCESS;
228
0
}
229
230
static int iter_dict_next(YR_ITERATOR* self, YR_VALUE_STACK* stack)
231
0
{
232
  // Check that there's three available slots in the stack, two for the next
233
  // item returned by the iterator and its key, and another one for the boolean
234
  // that indicates if there are more items.
235
0
  if (stack->sp + 2 >= stack->capacity)
236
0
    return ERROR_EXEC_STACK_OVERFLOW;
237
238
  // If the dictionary that must be iterated is undefined, stop the iteration
239
  // right away, as if the dictionary would be empty.
240
0
  if (IS_UNDEFINED(self->dict_it.dict))
241
0
    goto _stop_iter;
242
243
0
  YR_DICTIONARY_ITEMS* items = object_as_dictionary(self->dict_it.dict)->items;
244
245
  // If the dictionary has no items or the iterator reached the last item, abort
246
  // the iteration, if not push the next key and value.
247
0
  if (items == NULL || self->dict_it.index == items->used)
248
0
    goto _stop_iter;
249
250
  // Push the false value that indicates that the iterator is not exhausted.
251
0
  stack->items[stack->sp++].i = 0;
252
253
0
  if (items->objects[self->dict_it.index].obj != NULL)
254
0
  {
255
0
    stack->items[stack->sp++].o = items->objects[self->dict_it.index].obj;
256
0
    stack->items[stack->sp++].p = items->objects[self->dict_it.index].key;
257
0
  }
258
0
  else
259
0
  {
260
0
    stack->items[stack->sp++].i = YR_UNDEFINED;
261
0
    stack->items[stack->sp++].i = YR_UNDEFINED;
262
0
  }
263
264
0
  self->dict_it.index++;
265
266
0
  return ERROR_SUCCESS;
267
268
0
_stop_iter:
269
270
  // Push true for indicating the iterator has been exhausted.
271
0
  stack->items[stack->sp++].i = 1;
272
  // Push YR_UNDEFINED as a placeholder for the next key and value.
273
0
  stack->items[stack->sp++].i = YR_UNDEFINED;
274
0
  stack->items[stack->sp++].i = YR_UNDEFINED;
275
276
0
  return ERROR_SUCCESS;
277
0
}
278
279
static int iter_int_range_next(YR_ITERATOR* self, YR_VALUE_STACK* stack)
280
0
{
281
  // Check that there's two available slots in the stack, one for the next
282
  // item returned by the iterator and another one for the boolean that
283
  // indicates if there are more items.
284
0
  if (stack->sp + 1 >= stack->capacity)
285
0
    return ERROR_EXEC_STACK_OVERFLOW;
286
287
0
  if (!IS_UNDEFINED(self->int_range_it.next) &&
288
0
      !IS_UNDEFINED(self->int_range_it.last) &&
289
0
      self->int_range_it.next <= self->int_range_it.last)
290
0
  {
291
    // Push the false value that indicates that the iterator is not exhausted.
292
0
    stack->items[stack->sp++].i = 0;
293
0
    stack->items[stack->sp++].i = self->int_range_it.next;
294
0
    self->int_range_it.next++;
295
0
  }
296
0
  else
297
0
  {
298
    // Push true for indicating the iterator has been exhausted.
299
0
    stack->items[stack->sp++].i = 1;
300
    // Push YR_UNDEFINED as a placeholder for the next item.
301
0
    stack->items[stack->sp++].i = YR_UNDEFINED;
302
0
  }
303
304
0
  return ERROR_SUCCESS;
305
0
}
306
307
static int iter_int_enum_next(YR_ITERATOR* self, YR_VALUE_STACK* stack)
308
0
{
309
  // Check that there's two available slots in the stack, one for the next
310
  // item returned by the iterator and another one for the boolean that
311
  // indicates if there are more items.
312
0
  if (stack->sp + 1 >= stack->capacity)
313
0
    return ERROR_EXEC_STACK_OVERFLOW;
314
315
0
  if (!IS_UNDEFINED(self->int_enum_it.next) &&
316
0
      !IS_UNDEFINED(self->int_enum_it.count) &&
317
0
      self->int_enum_it.next < self->int_enum_it.count)
318
0
  {
319
    // Push the false value that indicates that the iterator is not exhausted.
320
0
    stack->items[stack->sp++].i = 0;
321
0
    stack->items[stack->sp++].i =
322
0
        self->int_enum_it.items[self->int_enum_it.next];
323
0
    self->int_enum_it.next++;
324
0
  }
325
0
  else
326
0
  {
327
    // Push true for indicating the iterator has been exhausted.
328
0
    stack->items[stack->sp++].i = 1;
329
    // Push YR_UNDEFINED as a placeholder for the next item.
330
0
    stack->items[stack->sp++].i = YR_UNDEFINED;
331
0
  }
332
333
0
  return ERROR_SUCCESS;
334
0
}
335
336
static int iter_string_set_next(YR_ITERATOR* self, YR_VALUE_STACK* stack)
337
0
{
338
  // Check that there's two available slots in the stack, one for the next
339
  // item returned by the iterator and another one for the boolean that
340
  // indicates if there are more items.
341
0
  if (stack->sp + 1 >= stack->capacity)
342
0
    return ERROR_EXEC_STACK_OVERFLOW;
343
344
  // If the current index is equal or larger than array's length the iterator
345
  // has reached the end of the array.
346
0
  if (self->string_set_it.index >= self->string_set_it.count)
347
0
    goto _stop_iter;
348
349
  // Push the false value that indicates that the iterator is not exhausted.
350
0
  stack->items[stack->sp++].i = 0;
351
0
  stack->items[stack->sp++].s =
352
0
      self->string_set_it.strings[self->string_set_it.index];
353
0
  self->string_set_it.index++;
354
355
0
  return ERROR_SUCCESS;
356
357
0
_stop_iter:
358
359
  // Push true for indicating the iterator has been exhausted.
360
0
  stack->items[stack->sp++].i = 1;
361
  // Push YR_UNDEFINED as a placeholder for the next item.
362
0
  stack->items[stack->sp++].i = YR_UNDEFINED;
363
364
0
  return ERROR_SUCCESS;
365
0
}
366
367
static int iter_text_string_set_next(YR_ITERATOR* self, YR_VALUE_STACK* stack)
368
0
{
369
  // Check that there's two available slots in the stack, one for the next
370
  // item returned by the iterator and another one for the boolean that
371
  // indicates if there are more items.
372
0
  if (stack->sp + 1 >= stack->capacity)
373
0
    return ERROR_EXEC_STACK_OVERFLOW;
374
375
  // If the current index is equal or larger than array's length the iterator
376
  // has reached the end of the array.
377
0
  if (self->text_string_set_it.index >= self->text_string_set_it.count)
378
0
    goto _stop_iter;
379
380
  // Push the false value that indicates that the iterator is not exhausted.
381
0
  stack->items[stack->sp++].i = 0;
382
0
  stack->items[stack->sp++].ss =
383
0
      self->text_string_set_it.strings[self->text_string_set_it.index];
384
0
  self->text_string_set_it.index++;
385
386
0
  return ERROR_SUCCESS;
387
388
0
_stop_iter:
389
390
  // Push true for indicating the iterator has been exhausted.
391
0
  stack->items[stack->sp++].i = 1;
392
  // Push YR_UNDEFINED as a placeholder for the next item.
393
0
  stack->items[stack->sp++].i = YR_UNDEFINED;
394
395
0
  return ERROR_SUCCESS;
396
0
}
397
398
// Global table that contains the "next" function for different types of
399
// iterators. The reason for using this table is to avoid storing pointers
400
// in the YARA's VM stack. Instead of the pointers we store an index within
401
// this table.
402
static YR_ITERATOR_NEXT_FUNC iter_next_func_table[] = {
403
    iter_array_next,
404
    iter_dict_next,
405
    iter_int_range_next,
406
    iter_int_enum_next,
407
    iter_string_set_next,
408
    iter_text_string_set_next,
409
};
410
411
0
#define ITER_NEXT_ARRAY           0
412
0
#define ITER_NEXT_DICT            1
413
0
#define ITER_NEXT_INT_RANGE       2
414
0
#define ITER_NEXT_INT_ENUM        3
415
0
#define ITER_NEXT_STRING_SET      4
416
0
#define ITER_NEXT_TEXT_STRING_SET 5
417
418
int yr_execute_code(YR_SCAN_CONTEXT* context)
419
16.5k
{
420
16.5k
  YR_DEBUG_FPRINTF(2, stderr, "+ %s() {\n", __FUNCTION__);
421
422
16.5k
  const uint8_t* ip = context->rules->code_start;
423
424
16.5k
  YR_VALUE mem[MEM_SIZE];
425
16.5k
  YR_VALUE args[YR_MAX_FUNCTION_ARGS];
426
16.5k
  YR_VALUE r1;
427
16.5k
  YR_VALUE r2;
428
16.5k
  YR_VALUE r3;
429
16.5k
  YR_VALUE r4;
430
431
16.5k
  YR_VALUE_STACK stack;
432
433
16.5k
  uint64_t elapsed_time;
434
435
#ifdef YR_PROFILING_ENABLED
436
  uint64_t start_time;
437
#endif
438
439
16.5k
  uint32_t current_rule_idx = 0;
440
16.5k
  YR_RULE* current_rule = NULL;
441
16.5k
  YR_RULE* rule;
442
16.5k
  YR_MATCH* match;
443
16.5k
  YR_OBJECT_FUNCTION* function;
444
16.5k
  YR_OBJECT** obj_ptr;
445
16.5k
  YR_ARENA* obj_arena;
446
16.5k
  YR_NOTEBOOK* it_notebook;
447
448
16.5k
  char* identifier;
449
16.5k
  char* args_fmt;
450
451
16.5k
  int found;
452
16.5k
  int count;
453
16.5k
  int result = ERROR_SUCCESS;
454
16.5k
  int cycle = 0;
455
16.5k
  int obj_count = 0;
456
457
16.5k
  bool stop = false;
458
459
16.5k
  uint8_t opcode;
460
461
16.5k
  yr_get_configuration_uint32(YR_CONFIG_STACK_SIZE, &stack.capacity);
462
463
16.5k
  stack.sp = 0;
464
16.5k
  stack.items = (YR_VALUE*) yr_malloc(stack.capacity * sizeof(YR_VALUE));
465
466
16.5k
  if (stack.items == NULL)
467
0
    return ERROR_INSUFFICIENT_MEMORY;
468
469
16.5k
  FAIL_ON_ERROR_WITH_CLEANUP(
470
16.5k
      yr_arena_create(1, 512 * sizeof(YR_OBJECT*), &obj_arena),
471
16.5k
      yr_free(stack.items));
472
473
16.5k
  FAIL_ON_ERROR_WITH_CLEANUP(
474
16.5k
      yr_notebook_create(512 * sizeof(YR_ITERATOR), &it_notebook),
475
16.5k
      yr_arena_release(obj_arena);
476
16.5k
      yr_free(stack.items));
477
478
#ifdef YR_PROFILING_ENABLED
479
  start_time = yr_stopwatch_elapsed_ns(&context->stopwatch);
480
#endif
481
482
16.5k
#if YR_PARANOID_EXEC
483
16.5k
  memset(mem, 0, MEM_SIZE * sizeof(mem[0]));
484
16.5k
#endif
485
486
265k
  while (!stop)
487
249k
  {
488
    // Read the opcode from the address indicated by the instruction pointer.
489
249k
    opcode = *ip;
490
491
    // Advance the instruction pointer, which now points past the opcode.
492
249k
    ip++;
493
494
249k
    switch (opcode)
495
249k
    {
496
0
    case OP_NOP:
497
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_NOP: // %s()\n", __FUNCTION__);
498
0
      break;
499
500
16.5k
    case OP_HALT:
501
16.5k
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_HALT: // %s()\n", __FUNCTION__);
502
16.5k
      assert(stack.sp == 0);  // When HALT is reached the stack should be empty.
503
16.5k
      stop = true;
504
16.5k
      break;
505
506
0
    case OP_ITER_START_ARRAY:
507
0
      YR_DEBUG_FPRINTF(
508
0
          2, stderr, "- case OP_ITER_START_ARRAY: // %s()\n", __FUNCTION__);
509
0
      r2.p = yr_notebook_alloc(it_notebook, sizeof(YR_ITERATOR));
510
511
0
      if (r2.p == NULL)
512
0
      {
513
0
        result = ERROR_INSUFFICIENT_MEMORY;
514
0
      }
515
0
      else
516
0
      {
517
0
        pop(r1);
518
0
        r2.it->array_it.array = r1.o;
519
0
        r2.it->array_it.index = 0;
520
0
        r2.it->next_func_idx = ITER_NEXT_ARRAY;
521
0
        push(r2);
522
0
      }
523
524
0
      stop = (result != ERROR_SUCCESS);
525
0
      break;
526
527
0
    case OP_ITER_START_DICT:
528
0
      YR_DEBUG_FPRINTF(
529
0
          2, stderr, "- case OP_ITER_START_DICT: // %s()\n", __FUNCTION__);
530
0
      r2.p = yr_notebook_alloc(it_notebook, sizeof(YR_ITERATOR));
531
532
0
      if (r2.p == NULL)
533
0
      {
534
0
        result = ERROR_INSUFFICIENT_MEMORY;
535
0
      }
536
0
      else
537
0
      {
538
0
        pop(r1);
539
0
        r2.it->dict_it.dict = r1.o;
540
0
        r2.it->dict_it.index = 0;
541
0
        r2.it->next_func_idx = ITER_NEXT_DICT;
542
0
        push(r2);
543
0
      }
544
545
0
      stop = (result != ERROR_SUCCESS);
546
0
      break;
547
548
0
    case OP_ITER_START_INT_RANGE:
549
0
      YR_DEBUG_FPRINTF(
550
0
          2, stderr, "- case OP_ITER_START_INT_RANGE: // %s()\n", __FUNCTION__);
551
      // Creates an iterator for an integer range. The higher bound of the
552
      // range is at the top of the stack followed by the lower bound.
553
0
      r3.p = yr_notebook_alloc(it_notebook, sizeof(YR_ITERATOR));
554
555
0
      if (r3.p == NULL)
556
0
      {
557
0
        result = ERROR_INSUFFICIENT_MEMORY;
558
0
      }
559
0
      else
560
0
      {
561
0
        pop(r2);
562
0
        pop(r1);
563
0
        r3.it->int_range_it.next = r1.i;
564
0
        r3.it->int_range_it.last = r2.i;
565
0
        r3.it->next_func_idx = ITER_NEXT_INT_RANGE;
566
0
        push(r3);
567
0
      }
568
569
0
      stop = (result != ERROR_SUCCESS);
570
0
      break;
571
572
0
    case OP_ITER_START_INT_ENUM:
573
0
      YR_DEBUG_FPRINTF(
574
0
          2, stderr, "- case OP_ITER_START_INT_ENUM: // %s()\n", __FUNCTION__);
575
      // Creates an iterator for an integer enumeration. The number of items
576
      // in the enumeration is at the top of the stack, followed by the
577
      // items in reverse order.
578
0
      pop(r1);
579
580
      // The count comes from the compiled rules and a hand-crafted file can
581
      // set it to a value that overflows the allocation size below or makes
582
      // the loop pop past the stack. It can't be larger than the number of
583
      // items currently on the stack.
584
0
      if (r1.i < 0 || (uint64_t) r1.i > stack.sp)
585
0
      {
586
0
        result = ERROR_INTERNAL_FATAL_ERROR;
587
0
        stop = true;
588
0
        break;
589
0
      }
590
591
0
      r3.p = yr_notebook_alloc(
592
0
          it_notebook, sizeof(YR_ITERATOR) + sizeof(uint64_t) * (size_t) r1.i);
593
594
0
      if (r3.p == NULL)
595
0
      {
596
0
        result = ERROR_INSUFFICIENT_MEMORY;
597
0
      }
598
0
      else
599
0
      {
600
0
        r3.it->int_enum_it.count = r1.i;
601
0
        r3.it->int_enum_it.next = 0;
602
0
        r3.it->next_func_idx = ITER_NEXT_INT_ENUM;
603
604
0
        for (int64_t i = r1.i; i > 0; i--)
605
0
        {
606
0
          pop(r2);
607
0
          r3.it->int_enum_it.items[i - 1] = r2.i;
608
0
        }
609
610
0
        push(r3);
611
0
      }
612
613
0
      stop = (result != ERROR_SUCCESS);
614
0
      break;
615
616
0
    case OP_ITER_START_STRING_SET:
617
0
      YR_DEBUG_FPRINTF(
618
0
          2,
619
0
          stderr,
620
0
          "- case OP_ITER_START_STRING_SET: // %s()\n",
621
0
          __FUNCTION__);
622
623
0
      pop(r1);
624
625
      // One extra value (the undefined string) is popped below, so the count
626
      // must be strictly smaller than the number of items on the stack. A
627
      // hand-crafted count would otherwise overflow the allocation or pop past
628
      // the stack.
629
0
      if (r1.i < 0 || (uint64_t) r1.i >= stack.sp)
630
0
      {
631
0
        result = ERROR_INTERNAL_FATAL_ERROR;
632
0
        stop = true;
633
0
        break;
634
0
      }
635
636
0
      r3.p = yr_notebook_alloc(
637
0
          it_notebook,
638
0
          sizeof(YR_ITERATOR) + sizeof(YR_STRING*) * (size_t) r1.i);
639
640
0
      if (r3.p == NULL)
641
0
      {
642
0
        result = ERROR_INSUFFICIENT_MEMORY;
643
0
      }
644
0
      else
645
0
      {
646
0
        r3.it->string_set_it.count = r1.i;
647
0
        r3.it->string_set_it.index = 0;
648
0
        r3.it->next_func_idx = ITER_NEXT_STRING_SET;
649
650
0
        for (int64_t i = r1.i; i > 0; i--)
651
0
        {
652
0
          pop(r2);
653
0
          r3.it->string_set_it.strings[i - 1] = r2.s;
654
0
        }
655
656
        // One last pop of the UNDEFINED string
657
0
        pop(r2);
658
0
        push(r3);
659
0
      }
660
661
0
      stop = (result != ERROR_SUCCESS);
662
0
      break;
663
664
0
    case OP_ITER_START_TEXT_STRING_SET:
665
0
      YR_DEBUG_FPRINTF(
666
0
          2,
667
0
          stderr,
668
0
          "- case OP_ITER_START_TEXT_STRING_SET: // %s()\n",
669
0
          __FUNCTION__);
670
671
0
      pop(r1);
672
673
      // The count comes from the compiled rules and can't be larger than the
674
      // number of items on the stack, otherwise the allocation below overflows
675
      // or the loop pops past the stack.
676
0
      if (r1.i < 0 || (uint64_t) r1.i > stack.sp)
677
0
      {
678
0
        result = ERROR_INTERNAL_FATAL_ERROR;
679
0
        stop = true;
680
0
        break;
681
0
      }
682
683
0
      r3.p = yr_notebook_alloc(
684
0
          it_notebook,
685
0
          sizeof(YR_ITERATOR) + sizeof(SIZED_STRING*) * (size_t) r1.i);
686
687
0
      if (r3.p == NULL)
688
0
      {
689
0
        result = ERROR_INSUFFICIENT_MEMORY;
690
0
      }
691
0
      else
692
0
      {
693
0
        r3.it->text_string_set_it.count = r1.i;
694
0
        r3.it->text_string_set_it.index = 0;
695
0
        r3.it->next_func_idx = ITER_NEXT_TEXT_STRING_SET;
696
697
0
        for (int64_t i = r1.i; i > 0; i--)
698
0
        {
699
0
          pop(r2);
700
0
          r3.it->text_string_set_it.strings[i - 1] = r2.ss;
701
0
        }
702
703
0
        push(r3);
704
0
      }
705
706
0
      stop = (result != ERROR_SUCCESS);
707
0
      break;
708
709
0
    case OP_ITER_NEXT:
710
0
      YR_DEBUG_FPRINTF(
711
0
          2, stderr, "- case OP_ITER_NEXT: // %s()\n", __FUNCTION__);
712
      // Loads the iterator in r1, but leaves the iterator in the stack.
713
0
      pop(r1);
714
0
      push(r1);
715
716
0
      if (r1.it->next_func_idx <
717
0
          sizeof(iter_next_func_table) / sizeof(YR_ITERATOR_NEXT_FUNC))
718
0
      {
719
        // The iterator's next function is responsible for pushing the next
720
        // item in the stack, and a boolean indicating if there are more items
721
        // to retrieve. The boolean will be at the top of the stack after
722
        // calling "next".
723
0
        result = iter_next_func_table[r1.it->next_func_idx](r1.it, &stack);
724
0
      }
725
0
      else
726
0
      {
727
        // next_func_idx is outside the valid range, this should not happend.
728
0
        result = ERROR_INTERNAL_FATAL_ERROR;
729
0
      }
730
731
0
      stop = (result != ERROR_SUCCESS);
732
0
      break;
733
734
0
    case OP_ITER_CONDITION:
735
0
      YR_DEBUG_FPRINTF(
736
0
          2, stderr, "- case OP_ITER_CONDITION: // %s()\n", __FUNCTION__);
737
738
      // Evaluate the iteration condition of the loop. This instruction
739
      // evaluates to 1 if the loop should continue and 0 if it shouldn't
740
      // (due to short-circuit evaluation).
741
742
0
      pop(r2);  // min. expression - all, any, none, integer
743
0
      pop(r3);  // number of true expressions
744
0
      pop(r4);  // last expression result
745
746
      // In case of 'all' loop, end once we the body failed
747
0
      if (is_undef(r2))
748
0
      {
749
0
        r1.i = r4.i != 0 ? 1 : 0;
750
0
      }
751
      // In case of 'none' loop, end once the body succeed
752
0
      else if (r2.i == 0)
753
0
      {
754
0
        r1.i = r4.i != 1 ? 1 : 0;
755
0
      }
756
      // In case of other loops, end once we satified min. expr.
757
0
      else
758
0
      {
759
0
        r1.i = r3.i + r4.i < r2.i ? 1 : 0;
760
0
      }
761
762
      // Push whether loop should continue and repush
763
      // the last expression result
764
0
      push(r1);
765
0
      push(r4);
766
0
      break;
767
768
0
    case OP_ITER_END:
769
0
      YR_DEBUG_FPRINTF(
770
0
          2, stderr, "- case OP_ITER_END: // %s()\n", __FUNCTION__);
771
772
      // Evaluate the whole loop. Whether it was successful or not
773
      // and whether it satisfied it's quantifier.
774
775
0
      pop(r2);  // min. expression - all, any, none, integer
776
0
      pop(r3);  // number of true expressions
777
0
      pop(r4);  // number of total iterations
778
779
      // If there was 0 iterations in total, it doesn't
780
      // matter what other numbers show. We can't evaluate
781
      // the loop as true.
782
0
      if (r4.i == 0)
783
0
      {
784
0
        r1.i = 0;
785
0
      }
786
0
      else if (is_undef(r2))
787
0
      {
788
0
        r1.i = r3.i == r4.i ? 1 : 0;
789
0
      }
790
0
      else if (r2.i == 0)
791
0
      {
792
0
        r1.i = r3.i == 0 ? 1 : 0;
793
0
      }
794
0
      else
795
0
      {
796
0
        r1.i = r3.i >= r2.i ? 1 : 0;
797
0
      }
798
799
0
      push(r1);
800
0
      break;
801
802
9.01k
    case OP_PUSH:
803
9.01k
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_PUSH: // %s()\n", __FUNCTION__);
804
9.01k
      r1.i = yr_unaligned_u64(ip);
805
9.01k
      ip += sizeof(uint64_t);
806
9.01k
      push(r1);
807
9.01k
      break;
808
809
33.1k
    case OP_PUSH_8:
810
33.1k
      r1.i = *ip;
811
33.1k
      YR_DEBUG_FPRINTF(
812
33.1k
          2,
813
33.1k
          stderr,
814
33.1k
          "- case OP_PUSH_8: r1.i=%" PRId64 " // %s()\n",
815
33.1k
          r1.i,
816
33.1k
          __FUNCTION__);
817
33.1k
      ip += sizeof(uint8_t);
818
33.1k
      push(r1);
819
33.1k
      break;
820
821
0
    case OP_PUSH_16:
822
0
      r1.i = yr_unaligned_u16(ip);
823
0
      YR_DEBUG_FPRINTF(
824
0
          2,
825
0
          stderr,
826
0
          "- case OP_PUSH_16: r1.i=%" PRId64 " // %s()\n",
827
0
          r1.i,
828
0
          __FUNCTION__);
829
0
      ip += sizeof(uint16_t);
830
0
      push(r1);
831
0
      break;
832
833
0
    case OP_PUSH_32:
834
0
      r1.i = yr_unaligned_u32(ip);
835
0
      YR_DEBUG_FPRINTF(
836
0
          2,
837
0
          stderr,
838
0
          "- case OP_PUSH_32: r1.i=%" PRId64 " // %s()\n",
839
0
          r1.i,
840
0
          __FUNCTION__);
841
0
      ip += sizeof(uint32_t);
842
0
      push(r1);
843
0
      break;
844
845
0
    case OP_PUSH_U:
846
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_PUSH_U: // %s()\n", __FUNCTION__);
847
0
      r1.i = YR_UNDEFINED;
848
0
      push(r1);
849
0
      break;
850
851
0
    case OP_POP:
852
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_POP: // %s()\n", __FUNCTION__);
853
0
      pop(r1);
854
0
      break;
855
856
0
    case OP_CLEAR_M:
857
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_CLEAR_M: // %s()\n", __FUNCTION__);
858
0
      r1.i = yr_unaligned_u64(ip);
859
0
      ip += sizeof(uint64_t);
860
0
#if YR_PARANOID_EXEC
861
0
      ensure_within_mem(r1.i);
862
0
#endif
863
0
      mem[r1.i].i = 0;
864
0
      break;
865
866
0
    case OP_ADD_M:
867
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_ADD_M: // %s()\n", __FUNCTION__);
868
0
      r1.i = yr_unaligned_u64(ip);
869
0
      ip += sizeof(uint64_t);
870
0
#if YR_PARANOID_EXEC
871
0
      ensure_within_mem(r1.i);
872
0
#endif
873
0
      pop(r2);
874
0
      if (!is_undef(r2))
875
0
        mem[r1.i].i += r2.i;
876
0
      break;
877
878
0
    case OP_INCR_M:
879
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_INCR_M: // %s()\n", __FUNCTION__);
880
0
      r1.i = yr_unaligned_u64(ip);
881
0
      ip += sizeof(uint64_t);
882
0
#if YR_PARANOID_EXEC
883
0
      ensure_within_mem(r1.i);
884
0
#endif
885
0
      mem[r1.i].i++;
886
0
      break;
887
888
0
    case OP_PUSH_M:
889
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_PUSH_M: // %s()\n", __FUNCTION__);
890
0
      r1.i = yr_unaligned_u64(ip);
891
0
      ip += sizeof(uint64_t);
892
0
#if YR_PARANOID_EXEC
893
0
      ensure_within_mem(r1.i);
894
0
#endif
895
0
      r1 = mem[r1.i];
896
0
      push(r1);
897
0
      break;
898
899
0
    case OP_POP_M:
900
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_POP_M: // %s()\n", __FUNCTION__);
901
0
      r1.i = yr_unaligned_u64(ip);
902
0
      ip += sizeof(uint64_t);
903
0
#if YR_PARANOID_EXEC
904
0
      ensure_within_mem(r1.i);
905
0
#endif
906
0
      pop(r2);
907
0
      mem[r1.i] = r2;
908
0
      break;
909
910
0
    case OP_SET_M:
911
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_SET_M: // %s()\n", __FUNCTION__);
912
0
      r1.i = yr_unaligned_u64(ip);
913
0
      ip += sizeof(uint64_t);
914
0
#if YR_PARANOID_EXEC
915
0
      ensure_within_mem(r1.i);
916
0
#endif
917
0
      pop(r2);
918
0
      push(r2);
919
0
      if (!is_undef(r2))
920
0
        mem[r1.i] = r2;
921
0
      break;
922
923
0
    case OP_SWAPUNDEF:
924
0
      YR_DEBUG_FPRINTF(
925
0
          2, stderr, "- case OP_SWAPUNDEF: // %s()\n", __FUNCTION__);
926
0
      r1.i = yr_unaligned_u64(ip);
927
0
      ip += sizeof(uint64_t);
928
0
#if YR_PARANOID_EXEC
929
0
      ensure_within_mem(r1.i);
930
0
#endif
931
0
      pop(r2);
932
933
0
      if (is_undef(r2))
934
0
      {
935
0
        r1 = mem[r1.i];
936
0
        push(r1);
937
0
      }
938
0
      else
939
0
      {
940
0
        push(r2);
941
0
      }
942
0
      break;
943
944
0
    case OP_JNUNDEF:
945
      // Jump if the top the stack is not undefined without modifying the stack.
946
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_JNUNDEF: // %s()\n", __FUNCTION__);
947
0
      pop(r1);
948
0
      push(r1);
949
0
      ip = jmp_if(!is_undef(r1), ip);
950
0
      break;
951
952
0
    case OP_JUNDEF_P:
953
      // Removes a value from the top of the stack and jump if the value is not
954
      // undefined.
955
0
      YR_DEBUG_FPRINTF(
956
0
          2, stderr, "- case OP_JUNDEF_P: // %s()\n", __FUNCTION__);
957
0
      pop(r1);
958
0
      ip = jmp_if(is_undef(r1), ip);
959
0
      break;
960
961
0
    case OP_JL_P:
962
      // Pops two values A and B from the stack and jump if A < B. B is popped
963
      // first, and then A.
964
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_JL_P: // %s()\n", __FUNCTION__);
965
0
      pop(r2);
966
0
      pop(r1);
967
0
      ip = jmp_if(r1.i < r2.i, ip);
968
0
      break;
969
970
0
    case OP_JLE_P:
971
      // Pops two values A and B from the stack and jump if A <= B. B is popped
972
      // first, and then A.
973
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_JLE_P: // %s()\n", __FUNCTION__);
974
0
      pop(r2);
975
0
      pop(r1);
976
0
      ip = jmp_if(r1.i <= r2.i, ip);
977
0
      break;
978
979
0
    case OP_JTRUE:
980
      // Jump if the top of the stack is true without modifying the stack. If
981
      // the top of the stack is undefined the jump is not taken.
982
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_JTRUE: // %s()\n", __FUNCTION__);
983
0
      pop(r1);
984
0
      push(r1);
985
0
      ip = jmp_if(!is_undef(r1) && r1.i, ip);
986
0
      break;
987
988
0
    case OP_JTRUE_P:
989
      // Removes a value from the stack and jump if it is true. If the value
990
      // is undefined the jump is not taken.
991
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_JTRUE_P: // %s()\n", __FUNCTION__);
992
0
      pop(r1);
993
0
      ip = jmp_if(!is_undef(r1) && r1.i, ip);
994
0
      break;
995
996
13.7k
    case OP_JFALSE:
997
      // Jump if the top of the stack is false without modifying the stack. If
998
      // the top of the stack is undefined the jump is not taken.
999
13.7k
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_JFALSE: // %s()\n", __FUNCTION__);
1000
13.7k
      pop(r1);
1001
13.7k
      push(r1);
1002
13.7k
      ip = jmp_if(!is_undef(r1) && !r1.i, ip);
1003
13.7k
      break;
1004
1005
0
    case OP_JFALSE_P:
1006
      // Removes a value from the stack and jump if it is false. If the value
1007
      // is undefined the jump is not taken.
1008
0
      YR_DEBUG_FPRINTF(
1009
0
          2, stderr, "- case OP_JFALSE_P: // %s()\n", __FUNCTION__);
1010
0
      pop(r1);
1011
0
      ip = jmp_if(!is_undef(r1) && !r1.i, ip);
1012
0
      break;
1013
1014
0
    case OP_JZ:
1015
      // Jump if the value at the top of the stack is 0 without modifying the
1016
      // stack.
1017
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_JZ: // %s()\n", __FUNCTION__);
1018
0
      pop(r1);
1019
0
      push(r1);
1020
0
      ip = jmp_if(r1.i == 0, ip);
1021
0
      break;
1022
1023
0
    case OP_JZ_P:
1024
      // Removes a value from the stack and jump if the value is 0.
1025
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_JZ_P: // %s()\n", __FUNCTION__);
1026
0
      pop(r1);
1027
0
      ip = jmp_if(r1.i == 0, ip);
1028
0
      break;
1029
1030
13.2k
    case OP_AND:
1031
13.2k
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_AND: // %s()\n", __FUNCTION__);
1032
13.2k
      pop(r2);
1033
13.2k
      pop(r1);
1034
1035
13.2k
      if (is_undef(r1))
1036
0
        r1.i = 0;
1037
1038
13.2k
      if (is_undef(r2))
1039
5
        r2.i = 0;
1040
1041
13.2k
      r1.i = r1.i && r2.i;
1042
13.2k
      push(r1);
1043
13.2k
      break;
1044
1045
0
    case OP_OR:
1046
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_OR: // %s()\n", __FUNCTION__);
1047
0
      pop(r2);
1048
0
      pop(r1);
1049
1050
0
      if (is_undef(r1))
1051
0
        r1.i = 0;
1052
1053
0
      if (is_undef(r2))
1054
0
        r2.i = 0;
1055
1056
0
      r1.i = r1.i || r2.i;
1057
0
      push(r1);
1058
0
      break;
1059
1060
0
    case OP_NOT:
1061
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_NOT: // %s()\n", __FUNCTION__);
1062
0
      pop(r1);
1063
1064
0
      if (is_undef(r1))
1065
0
        r1.i = YR_UNDEFINED;
1066
0
      else
1067
0
        r1.i = !r1.i;
1068
1069
0
      push(r1);
1070
0
      break;
1071
1072
0
    case OP_DEFINED:
1073
0
      pop(r1);
1074
0
      r1.i = !is_undef(r1);
1075
0
      push(r1);
1076
0
      break;
1077
1078
0
    case OP_MOD:
1079
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_MOD: // %s()\n", __FUNCTION__);
1080
0
      pop(r2);
1081
0
      pop(r1);
1082
0
      ensure_defined(r2);
1083
0
      ensure_defined(r1);
1084
      // If divisor is zero the result is undefined. It's also undefined
1085
      // when dividing INT64_MIN by -1.
1086
0
      if (r2.i == 0 || (r1.i == INT64_MIN && r2.i == -1))
1087
0
        r1.i = YR_UNDEFINED;
1088
0
      else
1089
0
        r1.i = r1.i % r2.i;
1090
0
      push(r1);
1091
0
      break;
1092
1093
0
    case OP_SHR:
1094
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_SHR: // %s()\n", __FUNCTION__);
1095
0
      pop(r2);
1096
0
      pop(r1);
1097
0
      ensure_defined(r2);
1098
0
      ensure_defined(r1);
1099
0
      if (r2.i < 0)
1100
0
        r1.i = YR_UNDEFINED;
1101
0
      else if (r2.i < 64)
1102
0
        r1.i = r1.i >> r2.i;
1103
0
      else
1104
0
        r1.i = 0;
1105
0
      push(r1);
1106
0
      break;
1107
1108
0
    case OP_SHL:
1109
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_SHL: // %s()\n", __FUNCTION__);
1110
0
      pop(r2);
1111
0
      pop(r1);
1112
0
      ensure_defined(r2);
1113
0
      ensure_defined(r1);
1114
0
      if (r2.i < 0)
1115
0
        r1.i = YR_UNDEFINED;
1116
0
      else if (r2.i < 64)
1117
0
        r1.i = r1.i << r2.i;
1118
0
      else
1119
0
        r1.i = 0;
1120
0
      push(r1);
1121
0
      break;
1122
1123
0
    case OP_BITWISE_NOT:
1124
0
      YR_DEBUG_FPRINTF(
1125
0
          2, stderr, "- case OP_BITWISE_NOT: // %s()\n", __FUNCTION__);
1126
0
      pop(r1);
1127
0
      ensure_defined(r1);
1128
0
      r1.i = ~r1.i;
1129
0
      push(r1);
1130
0
      break;
1131
1132
0
    case OP_BITWISE_AND:
1133
0
      YR_DEBUG_FPRINTF(
1134
0
          2, stderr, "- case OP_BITWISE_AND: // %s()\n", __FUNCTION__);
1135
0
      pop(r2);
1136
0
      pop(r1);
1137
0
      ensure_defined(r2);
1138
0
      ensure_defined(r1);
1139
0
      r1.i = r1.i & r2.i;
1140
0
      push(r1);
1141
0
      break;
1142
1143
0
    case OP_BITWISE_OR:
1144
0
      YR_DEBUG_FPRINTF(
1145
0
          2, stderr, "- case OP_BITWISE_OR: // %s()\n", __FUNCTION__);
1146
0
      pop(r2);
1147
0
      pop(r1);
1148
0
      ensure_defined(r2);
1149
0
      ensure_defined(r1);
1150
0
      r1.i = r1.i | r2.i;
1151
0
      push(r1);
1152
0
      break;
1153
1154
0
    case OP_BITWISE_XOR:
1155
0
      YR_DEBUG_FPRINTF(
1156
0
          2, stderr, "- case OP_BITWISE_XOR: // %s()\n", __FUNCTION__);
1157
0
      pop(r2);
1158
0
      pop(r1);
1159
0
      ensure_defined(r2);
1160
0
      ensure_defined(r1);
1161
0
      r1.i = r1.i ^ r2.i;
1162
0
      push(r1);
1163
0
      break;
1164
1165
0
    case OP_PUSH_RULE:
1166
0
      YR_DEBUG_FPRINTF(
1167
0
          2, stderr, "- case OP_PUSH_RULE: // %s()\n", __FUNCTION__);
1168
0
      r1.i = yr_unaligned_u64(ip);
1169
0
      ip += sizeof(uint64_t);
1170
1171
0
      rule = &context->rules->rules_table[r1.i];
1172
1173
0
      if (RULE_IS_DISABLED(rule))
1174
0
      {
1175
0
        r2.i = YR_UNDEFINED;
1176
0
      }
1177
0
      else
1178
0
      {
1179
0
        if (yr_bitmask_is_set(context->rule_matches_flags, r1.i))
1180
0
          r2.i = 1;
1181
0
        else
1182
0
          r2.i = 0;
1183
0
      }
1184
1185
0
      push(r2);
1186
0
      break;
1187
1188
9.01k
    case OP_INIT_RULE:
1189
9.01k
      YR_DEBUG_FPRINTF(
1190
9.01k
          2, stderr, "- case OP_INIT_RULE: // %s()\n", __FUNCTION__);
1191
1192
      // After the opcode there's an int32_t corresponding to the jump's
1193
      // offset and an uint32_t corresponding to the rule's index.
1194
9.01k
      current_rule_idx = yr_unaligned_u32(ip + sizeof(int32_t));
1195
1196
      // The curent rule index can't be larger than the number of rules.
1197
9.01k
      assert(current_rule_idx < context->rules->num_rules);
1198
1199
9.01k
      current_rule = &context->rules->rules_table[current_rule_idx];
1200
1201
      // If the rule is disabled, let's skip its code.
1202
9.01k
      bool skip_rule = RULE_IS_DISABLED(current_rule);
1203
1204
      // The rule is also skipped if it is not required to be evaluated.
1205
9.01k
      skip_rule |= yr_bitmask_is_not_set(
1206
9.01k
          context->required_eval, current_rule_idx);
1207
1208
9.01k
      ip = jmp_if(skip_rule, ip);
1209
1210
9.01k
      if (skip_rule)
1211
0
      {
1212
        // If the rule is skipped it is false, and if a global rule is false
1213
        // we must mark its namespace as unsatisfied.
1214
0
        if (RULE_IS_GLOBAL(current_rule))
1215
0
          yr_bitmask_set(context->ns_unsatisfied_flags, current_rule->ns->idx);
1216
0
      }
1217
9.01k
      else
1218
9.01k
      {
1219
        // If not taking the jump, skip the bytes corresponding to the
1220
        // rule's index.
1221
9.01k
        ip += sizeof(uint32_t);
1222
9.01k
      }
1223
1224
9.01k
      break;
1225
1226
9.01k
    case OP_MATCH_RULE:
1227
9.01k
      YR_DEBUG_FPRINTF(
1228
9.01k
          2, stderr, "- case OP_MATCH_RULE: // %s()\n", __FUNCTION__);
1229
9.01k
      pop(r1);
1230
1231
9.01k
      r2.i = yr_unaligned_u64(ip);
1232
9.01k
      ip += sizeof(uint64_t);
1233
1234
9.01k
      rule = &context->rules->rules_table[r2.i];
1235
1236
9.01k
#if YR_PARANOID_EXEC
1237
9.01k
      ensure_within_rules_arena(rule);
1238
9.01k
#endif
1239
1240
9.01k
      if (!is_undef(r1) && r1.i)
1241
1.61k
        yr_bitmask_set(context->rule_matches_flags, r2.i);
1242
7.39k
      else if (RULE_IS_GLOBAL(rule))
1243
0
        yr_bitmask_set(context->ns_unsatisfied_flags, rule->ns->idx);
1244
1245
#ifdef YR_PROFILING_ENABLED
1246
      elapsed_time = yr_stopwatch_elapsed_ns(&context->stopwatch);
1247
      context->profiling_info[r2.i].exec_time += (elapsed_time - start_time);
1248
      start_time = elapsed_time;
1249
#endif
1250
1251
9.01k
      assert(stack.sp == 0);  // at this point the stack should be empty.
1252
9.01k
      break;
1253
1254
22.2k
    case OP_OBJ_LOAD:
1255
22.2k
      YR_DEBUG_FPRINTF(
1256
22.2k
          2, stderr, "- case OP_OBJ_LOAD: // %s()\n", __FUNCTION__);
1257
1258
22.2k
      identifier = yr_unaligned_char_ptr(ip);
1259
22.2k
      ip += sizeof(uint64_t);
1260
1261
22.2k
#if YR_PARANOID_EXEC
1262
22.2k
      ensure_within_rules_arena(identifier);
1263
22.2k
#endif
1264
1265
22.2k
      r1.o = (YR_OBJECT*) yr_hash_table_lookup(
1266
22.2k
          context->objects_table, identifier, NULL);
1267
1268
22.2k
      assert(r1.o != NULL);
1269
22.2k
      push(r1);
1270
22.2k
      break;
1271
1272
22.2k
    case OP_OBJ_FIELD:
1273
22.2k
      YR_DEBUG_FPRINTF(
1274
22.2k
          2, stderr, "- case OP_OBJ_FIELD: // %s()\n", __FUNCTION__);
1275
1276
22.2k
      identifier = yr_unaligned_char_ptr(ip);
1277
22.2k
      ip += sizeof(uint64_t);
1278
1279
22.2k
#if YR_PARANOID_EXEC
1280
22.2k
      ensure_within_rules_arena(identifier);
1281
22.2k
#endif
1282
1283
22.2k
      pop(r1);
1284
22.2k
      ensure_defined(r1);
1285
1286
22.2k
      r1.o = yr_object_lookup_field(r1.o, identifier);
1287
1288
22.2k
      if (r1.o == NULL)
1289
0
      {
1290
0
        result = ERROR_INVALID_FIELD_NAME;
1291
0
        stop = true;
1292
0
        break;
1293
0
      }
1294
1295
22.2k
      push(r1);
1296
22.2k
      break;
1297
1298
22.2k
    case OP_OBJ_VALUE:
1299
22.2k
      YR_DEBUG_FPRINTF(
1300
22.2k
          2, stderr, "- case OP_OBJ_VALUE: // %s()\n", __FUNCTION__);
1301
22.2k
      pop(r1);
1302
22.2k
      ensure_defined(r1);
1303
1304
22.2k
#if YR_PARANOID_EXEC
1305
22.2k
      check_object_canary(r1.o);
1306
22.2k
#endif
1307
1308
22.2k
      switch (r1.o->type)
1309
22.2k
      {
1310
4.85k
      case OBJECT_TYPE_INTEGER:
1311
4.85k
        r1.i = r1.o->value.i;
1312
4.85k
        break;
1313
1314
10.0k
      case OBJECT_TYPE_FLOAT:
1315
10.0k
        if (yr_isnan(r1.o->value.d))
1316
5
          r1.i = YR_UNDEFINED;
1317
10.0k
        else
1318
10.0k
          r1.d = r1.o->value.d;
1319
10.0k
        break;
1320
1321
7.30k
      case OBJECT_TYPE_STRING:
1322
7.30k
        if (r1.o->value.ss == NULL)
1323
6.80k
          r1.i = YR_UNDEFINED;
1324
501
        else
1325
501
          r1.ss = r1.o->value.ss;
1326
7.30k
        break;
1327
1328
0
      default:
1329
0
        assert(false);
1330
22.2k
      }
1331
1332
22.2k
      push(r1);
1333
22.2k
      break;
1334
1335
0
    case OP_INDEX_ARRAY:
1336
0
      YR_DEBUG_FPRINTF(
1337
0
          2, stderr, "- case OP_INDEX_ARRAY: // %s()\n", __FUNCTION__);
1338
0
      pop(r1);  // index
1339
0
      pop(r2);  // array
1340
1341
0
      ensure_defined(r1);
1342
0
      ensure_defined(r2);
1343
1344
0
      assert(r2.o->type == OBJECT_TYPE_ARRAY);
1345
1346
0
#if YR_PARANOID_EXEC
1347
0
      check_object_canary(r2.o);
1348
0
#endif
1349
1350
0
      r1.o = yr_object_array_get_item(r2.o, 0, (int) r1.i);
1351
1352
0
      if (r1.o == NULL)
1353
0
        r1.i = YR_UNDEFINED;
1354
1355
0
      push(r1);
1356
0
      break;
1357
1358
0
    case OP_LOOKUP_DICT:
1359
0
      YR_DEBUG_FPRINTF(
1360
0
          2, stderr, "- case OP_LOOKUP_DICT: // %s()\n", __FUNCTION__);
1361
0
      pop(r1);  // key
1362
0
      pop(r2);  // dictionary
1363
1364
0
      ensure_defined(r1);
1365
0
      ensure_defined(r2);
1366
1367
0
      assert(r2.o->type == OBJECT_TYPE_DICTIONARY);
1368
1369
0
#if YR_PARANOID_EXEC
1370
0
      check_object_canary(r2.o);
1371
0
#endif
1372
1373
0
      r1.o = yr_object_dict_get_item(r2.o, 0, r1.ss->c_string);
1374
1375
0
      if (r1.o == NULL)
1376
0
        r1.i = YR_UNDEFINED;
1377
1378
0
      push(r1);
1379
0
      break;
1380
1381
14.9k
    case OP_CALL:
1382
14.9k
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_CALL: // %s()\n", __FUNCTION__);
1383
1384
14.9k
      args_fmt = yr_unaligned_char_ptr(ip);
1385
14.9k
      ip += sizeof(uint64_t);
1386
1387
14.9k
      int i = (int) strlen(args_fmt);
1388
14.9k
      count = 0;
1389
1390
14.9k
#if YR_PARANOID_EXEC
1391
14.9k
      if (i > YR_MAX_FUNCTION_ARGS)
1392
0
      {
1393
0
        stop = true;
1394
0
        result = ERROR_INTERNAL_FATAL_ERROR;
1395
0
        break;
1396
0
      }
1397
14.9k
#endif
1398
1399
      // pop arguments from stack and copy them to args array
1400
1401
49.7k
      while (i > 0)
1402
34.8k
      {
1403
34.8k
        pop(r1);
1404
1405
34.8k
        if (is_undef(r1))  // count the number of undefined args
1406
0
          count++;
1407
1408
34.8k
        args[i - 1] = r1;
1409
34.8k
        i--;
1410
34.8k
      }
1411
1412
29.8k
      pop(r2);
1413
29.8k
      ensure_defined(r2);
1414
1415
14.9k
#if YR_PARANOID_EXEC
1416
14.9k
      check_object_canary(r2.o);
1417
14.9k
#endif
1418
1419
14.9k
      if (count > 0)
1420
0
      {
1421
        // If there are undefined args, result for function call
1422
        // is undefined as well.
1423
1424
0
        r1.i = YR_UNDEFINED;
1425
0
        push(r1);
1426
0
        break;
1427
0
      }
1428
1429
14.9k
      function = object_as_function(r2.o);
1430
14.9k
      result = ERROR_INTERNAL_FATAL_ERROR;
1431
1432
14.9k
      for (i = 0; i < YR_MAX_OVERLOADED_FUNCTIONS; i++)
1433
14.9k
      {
1434
14.9k
        if (function->prototypes[i].arguments_fmt == NULL)
1435
0
          break;
1436
1437
14.9k
        if (strcmp(function->prototypes[i].arguments_fmt, args_fmt) == 0)
1438
14.9k
        {
1439
14.9k
          result = function->prototypes[i].code(args, context, function);
1440
14.9k
          break;
1441
14.9k
        }
1442
14.9k
      }
1443
1444
      // If i == YR_MAX_OVERLOADED_FUNCTIONS at this point no matching
1445
      // prototype was found, but this shouldn't happen.
1446
14.9k
      assert(i < YR_MAX_OVERLOADED_FUNCTIONS);
1447
1448
      // Make a copy of the returned object and push the copy into the stack,
1449
      // function->return_obj can't be pushed because it can change in
1450
      // subsequent calls to the same function.
1451
14.9k
      if (result == ERROR_SUCCESS)
1452
14.9k
        result = yr_object_copy(function->return_obj, &r1.o);
1453
1454
      // A pointer to the copied object is stored in a arena in order to
1455
      // free the object before exiting yr_execute_code, obj_count tracks
1456
      // the number of objects written.
1457
14.9k
      if (result == ERROR_SUCCESS)
1458
14.9k
      {
1459
14.9k
        result = yr_arena_write_data(obj_arena, 0, &r1.o, sizeof(r1.o), NULL);
1460
14.9k
        obj_count++;
1461
14.9k
      }
1462
0
      else
1463
0
      {
1464
0
        r1.i = YR_UNDEFINED;
1465
0
      }
1466
1467
14.9k
      stop = (result != ERROR_SUCCESS);
1468
14.9k
      push(r1);
1469
14.9k
      break;
1470
1471
0
    case OP_FOUND:
1472
0
      pop(r1);
1473
0
      r2.i = context->matches[r1.s->idx].tail != NULL ? 1 : 0;
1474
0
      YR_DEBUG_FPRINTF(
1475
0
          2,
1476
0
          stderr,
1477
0
          "- case OP_FOUND: r2.i=%" PRId64 " // %s()\n",
1478
0
          r2.i,
1479
0
          __FUNCTION__);
1480
0
      push(r2);
1481
0
      break;
1482
1483
0
    case OP_FOUND_AT:
1484
0
      YR_DEBUG_FPRINTF(
1485
0
          2, stderr, "- case OP_FOUND_AT: // %s()\n", __FUNCTION__);
1486
0
      pop(r2);
1487
0
      pop(r1);
1488
1489
0
      ensure_defined(r1);
1490
1491
0
#if YR_PARANOID_EXEC
1492
0
      ensure_within_rules_arena(r2.p);
1493
0
#endif
1494
1495
0
      match = context->matches[r2.s->idx].head;
1496
0
      r3.i = false;
1497
1498
0
      while (match != NULL)
1499
0
      {
1500
0
        if (r1.i == match->base + match->offset)
1501
0
        {
1502
0
          r3.i = true;
1503
0
          break;
1504
0
        }
1505
1506
0
        if (r1.i < match->base + match->offset)
1507
0
          break;
1508
1509
0
        match = match->next;
1510
0
      }
1511
1512
0
      push(r3);
1513
0
      break;
1514
1515
0
    case OP_FOUND_IN:
1516
0
      YR_DEBUG_FPRINTF(
1517
0
          2, stderr, "- case OP_FOUND_IN: // %s()\n", __FUNCTION__);
1518
0
      pop(r3);
1519
0
      pop(r2);
1520
0
      pop(r1);
1521
1522
0
      ensure_defined(r1);
1523
0
      ensure_defined(r2);
1524
1525
0
#if YR_PARANOID_EXEC
1526
0
      ensure_within_rules_arena(r3.p);
1527
0
#endif
1528
1529
0
      match = context->matches[r3.s->idx].head;
1530
0
      r4.i = false;
1531
1532
0
      while (match != NULL && !r4.i)
1533
0
      {
1534
0
        if (match->base + match->offset >= r1.i &&
1535
0
            match->base + match->offset <= r2.i)
1536
0
        {
1537
0
          r4.i = true;
1538
0
        }
1539
1540
0
        if (match->base + match->offset > r2.i)
1541
0
          break;
1542
1543
0
        match = match->next;
1544
0
      }
1545
1546
0
      push(r4);
1547
0
      break;
1548
1549
0
    case OP_COUNT:
1550
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_COUNT: // %s()\n", __FUNCTION__);
1551
0
      pop(r1);
1552
1553
0
#if YR_PARANOID_EXEC
1554
0
      ensure_within_rules_arena(r1.p);
1555
0
#endif
1556
1557
0
      r2.i = context->matches[r1.s->idx].count;
1558
0
      push(r2);
1559
0
      break;
1560
1561
0
    case OP_COUNT_IN:
1562
0
      YR_DEBUG_FPRINTF(
1563
0
          2, stderr, "- case OP_COUNT_IN: // %s()\n", __FUNCTION__);
1564
0
      pop(r3);
1565
0
      pop(r2);
1566
0
      pop(r1);
1567
1568
0
      ensure_defined(r1);
1569
0
      ensure_defined(r2);
1570
1571
0
#if YR_PARANOID_EXEC
1572
0
      ensure_within_rules_arena(r3.p);
1573
0
#endif
1574
1575
0
      match = context->matches[r3.s->idx].head;
1576
0
      r4.i = 0;
1577
1578
0
      while (match != NULL)
1579
0
      {
1580
0
        if (match->base + match->offset >= r1.i &&
1581
0
            match->base + match->offset <= r2.i)
1582
0
        {
1583
0
          r4.i++;
1584
0
        }
1585
1586
0
        if (match->base + match->offset > r2.i)
1587
0
          break;
1588
1589
0
        match = match->next;
1590
0
      }
1591
1592
0
      push(r4);
1593
0
      break;
1594
1595
0
    case OP_OFFSET:
1596
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_OFFSET: // %s()\n", __FUNCTION__);
1597
0
      pop(r2);
1598
0
      pop(r1);
1599
1600
0
      ensure_defined(r1);
1601
1602
0
#if YR_PARANOID_EXEC
1603
0
      ensure_within_rules_arena(r2.p);
1604
0
#endif
1605
1606
0
      match = context->matches[r2.s->idx].head;
1607
1608
0
      i = 1;
1609
0
      r3.i = YR_UNDEFINED;
1610
1611
0
      while (match != NULL && r3.i == YR_UNDEFINED)
1612
0
      {
1613
0
        if (r1.i == i)
1614
0
          r3.i = match->base + match->offset;
1615
1616
0
        i++;
1617
0
        match = match->next;
1618
0
      }
1619
1620
0
      push(r3);
1621
0
      break;
1622
1623
0
    case OP_LENGTH:
1624
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_LENGTH: // %s()\n", __FUNCTION__);
1625
0
      pop(r2);
1626
0
      pop(r1);
1627
1628
0
      ensure_defined(r1);
1629
1630
0
#if YR_PARANOID_EXEC
1631
0
      ensure_within_rules_arena(r2.p);
1632
0
#endif
1633
1634
0
      match = context->matches[r2.s->idx].head;
1635
1636
0
      i = 1;
1637
0
      r3.i = YR_UNDEFINED;
1638
1639
0
      while (match != NULL && r3.i == YR_UNDEFINED)
1640
0
      {
1641
0
        if (r1.i == i)
1642
0
          r3.i = match->match_length;
1643
1644
0
        i++;
1645
0
        match = match->next;
1646
0
      }
1647
1648
0
      push(r3);
1649
0
      break;
1650
1651
0
    case OP_OF:
1652
0
    case OP_OF_PERCENT:
1653
0
      r2.i = yr_unaligned_u64(ip);
1654
0
      ip += sizeof(uint64_t);
1655
0
      assert(r2.i == OF_STRING_SET || r2.i == OF_RULE_SET);
1656
0
      found = 0;
1657
0
      count = 0;
1658
0
      pop(r1);
1659
1660
0
      while (!is_undef(r1))
1661
0
      {
1662
0
        if (r2.i == OF_STRING_SET)
1663
0
        {
1664
0
          if (context->matches[r1.s->idx].tail != NULL)
1665
0
          {
1666
0
            found++;
1667
0
          }
1668
0
        }
1669
0
        else
1670
0
        {
1671
          // r1.i is 1 if the rule has already matched and zero otherwise.
1672
0
          found += r1.i;
1673
0
        }
1674
0
        count++;
1675
0
        pop(r1);
1676
0
      }
1677
1678
0
      pop(r2);
1679
1680
0
      if (opcode == OP_OF)
1681
0
      {
1682
0
        YR_DEBUG_FPRINTF(2, stderr, "- case OP_OF: // %s()\n", __FUNCTION__);
1683
1684
        // Quantifier is "all"
1685
0
        if (is_undef(r2))
1686
0
        {
1687
0
          r1.i = found >= count ? 1 : 0;
1688
0
        }
1689
        // Quantifier is 0 or none. This is a special case in which we want
1690
        // exactly 0 strings matching. More information at:
1691
        // https://github.com/VirusTotal/yara/issues/1695
1692
0
        else if (r2.i == 0)
1693
0
        {
1694
0
          r1.i = found == 0 ? 1 : 0;
1695
0
        }
1696
        // In all other cases the number of strings matching should be at
1697
        // least the amount specified by the quantifier.
1698
0
        else
1699
0
        {
1700
0
          r1.i = found >= r2.i ? 1 : 0;
1701
0
        }
1702
0
      }
1703
0
      else  // OP_OF_PERCENT
1704
0
      {
1705
0
        YR_DEBUG_FPRINTF(
1706
0
            2, stderr, "- case OP_OF_PERCENT: // %s()\n", __FUNCTION__);
1707
1708
        // If, by some weird reason, we manage to get an undefined string
1709
        // reference as the first thing on the stack then count would be zero.
1710
        // I don't know how this could ever happen but better to check for it.
1711
0
        if (is_undef(r2) || count == 0)
1712
0
          r1.i = YR_UNDEFINED;
1713
0
        else
1714
0
          r1.i = (((double) found / count) * 100) >= r2.i ? 1 : 0;
1715
0
      }
1716
1717
0
      push(r1);
1718
0
      break;
1719
1720
0
    case OP_OF_FOUND_IN:
1721
0
      YR_DEBUG_FPRINTF(
1722
0
          2, stderr, "- case OP_OF_FOUND_IN: // %s()\n", __FUNCTION__);
1723
1724
0
      found = 0;
1725
0
      count = 0;
1726
1727
0
      pop(r2);  // Offset range end
1728
0
      pop(r1);  // Offset range start
1729
0
      pop(r3);  // First string
1730
1731
      // If any of the range boundaries are undefined the result is also
1732
      // undefined, be we need to unwind the stack first.
1733
0
      if (is_undef(r1) || is_undef(r2))
1734
0
      {
1735
        // Remove all the strings.
1736
0
        while (!is_undef(r3)) pop(r3);
1737
        // Remove the quantifier at the bottom of the stack.
1738
0
        pop(r3);
1739
0
        r1.i = YR_UNDEFINED;
1740
0
        push(r1);
1741
0
        break;
1742
0
      }
1743
1744
0
      while (!is_undef(r3))
1745
0
      {
1746
0
#if YR_PARANOID_EXEC
1747
0
        ensure_within_rules_arena(r3.p);
1748
0
#endif
1749
0
        match = context->matches[r3.s->idx].head;
1750
1751
0
        while (match != NULL)
1752
0
        {
1753
          // String match within range start and range end?
1754
0
          if (match->base + match->offset >= r1.i &&
1755
0
              match->base + match->offset <= r2.i)
1756
0
          {
1757
0
            found++;
1758
0
            break;
1759
0
          }
1760
1761
          // If current match is past range end, we can stop as matches
1762
          // are sorted by offset in increasing order, so all remaining
1763
          // matches are part the range end too.
1764
0
          if (match->base + match->offset > r1.i)
1765
0
            break;
1766
1767
0
          match = match->next;
1768
0
        }
1769
1770
0
        count++;
1771
0
        pop(r3);
1772
0
      }
1773
1774
0
      pop(r2);  // Quantifier X in expressions like "X of string_set in range"
1775
1776
      // Quantifier is "all".
1777
0
      if (is_undef(r2))
1778
0
      {
1779
0
        r1.i = found >= count ? 1 : 0;
1780
0
      }
1781
      // Quantifier is 0 or none. This is a special case in which we want
1782
      // exactly 0 strings matching. More information at:
1783
      // https://github.com/VirusTotal/yara/issues/1695
1784
0
      else if (r2.i == 0)
1785
0
      {
1786
0
        r1.i = found == 0 ? 1 : 0;
1787
0
      }
1788
      // In all other cases the number of strings matching should be at least
1789
      // the amount specified by the quantifier.
1790
0
      else
1791
0
      {
1792
0
        r1.i = found >= r2.i ? 1 : 0;
1793
0
      }
1794
1795
0
      push(r1);
1796
0
      break;
1797
1798
0
    case OP_OF_FOUND_AT:
1799
0
      YR_DEBUG_FPRINTF(
1800
0
          2, stderr, "- case OP_OF_FOUND_AT: // %s()\n", __FUNCTION__);
1801
1802
0
      found = 0;
1803
0
      count = 0;
1804
1805
0
      pop(r2);  // Match location
1806
0
      pop(r1);  // First string
1807
1808
      // Match location must be defined.
1809
0
      if (is_undef(r2))
1810
0
      {
1811
        // Remove all the strings.
1812
0
        while (!is_undef(r1)) pop(r1);
1813
        // Remove the quantifier at the bottom of the stack.
1814
0
        pop(r1);
1815
0
        r1.i = YR_UNDEFINED;
1816
0
        push(r1);
1817
0
        break;
1818
0
      }
1819
1820
0
      while (!is_undef(r1))
1821
0
      {
1822
0
#if YR_PARANOID_EXEC
1823
0
        ensure_within_rules_arena(r1.p);
1824
0
#endif
1825
0
        match = context->matches[r1.s->idx].head;
1826
1827
0
        while (match != NULL)
1828
0
        {
1829
          // String match at the desired location?
1830
0
          if (match->base + match->offset == r2.i)
1831
0
          {
1832
0
            found++;
1833
0
            break;
1834
0
          }
1835
1836
          // If current match is past desired location, we can stop as matches
1837
          // are sorted by offset in increasing order, so all remaining
1838
          // matches are past it.
1839
0
          if (match->base + match->offset > r2.i)
1840
0
            break;
1841
1842
0
          match = match->next;
1843
0
        }
1844
1845
0
        count++;
1846
0
        pop(r1);
1847
0
      }
1848
1849
0
      pop(r2);  // Quantifier X in expressions like "X of string_set in range"
1850
1851
      // Quantifier is "all".
1852
0
      if (is_undef(r2))
1853
0
      {
1854
0
        r1.i = found >= count ? 1 : 0;
1855
0
      }
1856
      // Quantifier is 0 or none. This is a special case in which we want
1857
      // exactly 0 strings matching. More information at:
1858
      // https://github.com/VirusTotal/yara/issues/1695
1859
0
      else if (r2.i == 0)
1860
0
      {
1861
0
        r1.i = found == 0 ? 1 : 0;
1862
0
      }
1863
      // In all other cases the number of strings matching should be at least
1864
      // the amount specified by the quantifier.
1865
0
      else
1866
0
      {
1867
0
        r1.i = found >= r2.i ? 1 : 0;
1868
0
      }
1869
1870
0
      push(r1);
1871
0
      break;
1872
1873
14.9k
    case OP_FILESIZE:
1874
14.9k
      r1.i = context->file_size;
1875
14.9k
      YR_DEBUG_FPRINTF(
1876
14.9k
          2,
1877
14.9k
          stderr,
1878
14.9k
          "- case OP_FILESIZE: r1.i=%" PRId64 "%s // %s()\n",
1879
14.9k
          r1.i,
1880
14.9k
          r1.i == YR_UNDEFINED ? " AKA YR_UNDEFINED" : "",
1881
14.9k
          __FUNCTION__);
1882
14.9k
      push(r1);
1883
14.9k
      break;
1884
1885
0
    case OP_ENTRYPOINT:
1886
0
      YR_DEBUG_FPRINTF(
1887
0
          2, stderr, "- case OP_ENTRYPOINT: // %s()\n", __FUNCTION__);
1888
0
      r1.i = context->entry_point;
1889
0
      push(r1);
1890
0
      break;
1891
1892
0
    case OP_INT8:
1893
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_INT8: // %s()\n", __FUNCTION__);
1894
0
      pop(r1);
1895
0
      r1.i = read_int8_t_little_endian(context->iterator, (size_t) r1.i);
1896
0
      push(r1);
1897
0
      break;
1898
1899
0
    case OP_INT16:
1900
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_INT16: // %s()\n", __FUNCTION__);
1901
0
      pop(r1);
1902
0
      r1.i = read_int16_t_little_endian(context->iterator, (size_t) r1.i);
1903
0
      push(r1);
1904
0
      break;
1905
1906
0
    case OP_INT32:
1907
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_INT32: // %s()\n", __FUNCTION__);
1908
0
      pop(r1);
1909
0
      r1.i = read_int32_t_little_endian(context->iterator, (size_t) r1.i);
1910
0
      push(r1);
1911
0
      break;
1912
1913
0
    case OP_UINT8:
1914
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_UINT8: // %s()\n", __FUNCTION__);
1915
0
      pop(r1);
1916
0
      r1.i = read_uint8_t_little_endian(context->iterator, (size_t) r1.i);
1917
0
      push(r1);
1918
0
      break;
1919
1920
0
    case OP_UINT16:
1921
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_UINT16: // %s()\n", __FUNCTION__);
1922
0
      pop(r1);
1923
0
      r1.i = read_uint16_t_little_endian(context->iterator, (size_t) r1.i);
1924
0
      push(r1);
1925
0
      break;
1926
1927
0
    case OP_UINT32:
1928
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_UINT32: // %s()\n", __FUNCTION__);
1929
0
      pop(r1);
1930
0
      r1.i = read_uint32_t_little_endian(context->iterator, (size_t) r1.i);
1931
0
      push(r1);
1932
0
      break;
1933
1934
0
    case OP_INT8BE:
1935
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_INT8BE: // %s()\n", __FUNCTION__);
1936
0
      pop(r1);
1937
0
      r1.i = read_int8_t_big_endian(context->iterator, (size_t) r1.i);
1938
0
      push(r1);
1939
0
      break;
1940
1941
0
    case OP_INT16BE:
1942
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_INT16BE: // %s()\n", __FUNCTION__);
1943
0
      pop(r1);
1944
0
      r1.i = read_int16_t_big_endian(context->iterator, (size_t) r1.i);
1945
0
      push(r1);
1946
0
      break;
1947
1948
0
    case OP_INT32BE:
1949
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_INT32BE: // %s()\n", __FUNCTION__);
1950
0
      pop(r1);
1951
0
      r1.i = read_int32_t_big_endian(context->iterator, (size_t) r1.i);
1952
0
      push(r1);
1953
0
      break;
1954
1955
0
    case OP_UINT8BE:
1956
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_UINT8BE: // %s()\n", __FUNCTION__);
1957
0
      pop(r1);
1958
0
      r1.i = read_uint8_t_big_endian(context->iterator, (size_t) r1.i);
1959
0
      push(r1);
1960
0
      break;
1961
1962
0
    case OP_UINT16BE:
1963
0
      YR_DEBUG_FPRINTF(
1964
0
          2, stderr, "- case OP_UINT16BE: // %s()\n", __FUNCTION__);
1965
0
      pop(r1);
1966
0
      r1.i = read_uint16_t_big_endian(context->iterator, (size_t) r1.i);
1967
0
      push(r1);
1968
0
      break;
1969
1970
0
    case OP_UINT32BE:
1971
0
      YR_DEBUG_FPRINTF(
1972
0
          2, stderr, "- case OP_UINT32BE: // %s()\n", __FUNCTION__);
1973
0
      pop(r1);
1974
0
      r1.i = read_uint32_t_big_endian(context->iterator, (size_t) r1.i);
1975
0
      push(r1);
1976
0
      break;
1977
1978
16.5k
    case OP_IMPORT:
1979
16.5k
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_IMPORT: // %s()\n", __FUNCTION__);
1980
16.5k
      r1.i = yr_unaligned_u64(ip);
1981
16.5k
      ip += sizeof(uint64_t);
1982
1983
16.5k
#if YR_PARANOID_EXEC
1984
16.5k
      ensure_within_rules_arena(r1.p);
1985
16.5k
#endif
1986
1987
16.5k
      result = yr_modules_load((char*) r1.p, context);
1988
1989
16.5k
      if (result != ERROR_SUCCESS)
1990
0
        stop = true;
1991
1992
16.5k
      break;
1993
1994
0
    case OP_MATCHES:
1995
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_MATCHES: // %s()\n", __FUNCTION__);
1996
0
      pop(r2);
1997
0
      pop(r1);
1998
1999
0
      ensure_defined(r2);
2000
0
      ensure_defined(r1);
2001
2002
0
      result = yr_re_exec(
2003
0
          context,
2004
0
          (uint8_t*) r2.re->code,
2005
0
          (uint8_t*) r1.ss->c_string,
2006
0
          r1.ss->length,
2007
0
          0,
2008
0
          r2.re->flags | RE_FLAGS_SCAN,
2009
0
          NULL,
2010
0
          NULL,
2011
0
          &found);
2012
2013
0
      if (result != ERROR_SUCCESS)
2014
0
        stop = true;
2015
2016
0
      r1.i = found >= 0;
2017
0
      push(r1);
2018
0
      break;
2019
2020
10.0k
    case OP_INT_TO_DBL:
2021
10.0k
      YR_DEBUG_FPRINTF(
2022
10.0k
          2, stderr, "- case OP_INT_TO_DBL: // %s()\n", __FUNCTION__);
2023
10.0k
      r1.i = yr_unaligned_u64(ip);
2024
10.0k
      ip += sizeof(uint64_t);
2025
2026
10.0k
#if YR_PARANOID_EXEC
2027
10.0k
      if (r1.i > stack.sp || stack.sp - r1.i >= stack.capacity)
2028
0
      {
2029
0
        stop = true;
2030
0
        result = ERROR_INTERNAL_FATAL_ERROR;
2031
0
        break;
2032
0
      }
2033
10.0k
#endif
2034
2035
10.0k
      r2 = stack.items[stack.sp - r1.i];
2036
2037
10.0k
      if (is_undef(r2))
2038
0
        stack.items[stack.sp - r1.i].i = YR_UNDEFINED;
2039
10.0k
      else
2040
10.0k
        stack.items[stack.sp - r1.i].d = (double) r2.i;
2041
10.0k
      break;
2042
2043
0
    case OP_STR_TO_BOOL:
2044
0
      YR_DEBUG_FPRINTF(
2045
0
          2, stderr, "- case OP_STR_TO_BOOL: // %s()\n", __FUNCTION__);
2046
0
      pop(r1);
2047
0
      ensure_defined(r1);
2048
0
      r1.i = r1.ss->length > 0;
2049
0
      push(r1);
2050
0
      break;
2051
2052
0
    case OP_INT_EQ:
2053
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_INT_EQ: // %s()\n", __FUNCTION__);
2054
0
      pop(r2);
2055
0
      pop(r1);
2056
0
      ensure_defined(r2);
2057
0
      ensure_defined(r1);
2058
0
      r1.i = r1.i == r2.i;
2059
0
      push(r1);
2060
0
      break;
2061
2062
0
    case OP_INT_NEQ:
2063
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_INT_NEQ: // %s()\n", __FUNCTION__);
2064
0
      pop(r2);
2065
0
      pop(r1);
2066
0
      ensure_defined(r2);
2067
0
      ensure_defined(r1);
2068
0
      r1.i = r1.i != r2.i;
2069
0
      push(r1);
2070
0
      break;
2071
2072
0
    case OP_INT_LT:
2073
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_INT_LT: // %s()\n", __FUNCTION__);
2074
0
      pop(r2);
2075
0
      pop(r1);
2076
0
      ensure_defined(r2);
2077
0
      ensure_defined(r1);
2078
0
      r1.i = r1.i < r2.i;
2079
0
      push(r1);
2080
0
      break;
2081
2082
0
    case OP_INT_GT:
2083
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_INT_GT: // %s()\n", __FUNCTION__);
2084
0
      pop(r2);
2085
0
      pop(r1);
2086
0
      ensure_defined(r2);
2087
0
      ensure_defined(r1);
2088
0
      r1.i = r1.i > r2.i;
2089
0
      push(r1);
2090
0
      break;
2091
2092
0
    case OP_INT_LE:
2093
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_INT_LE: // %s()\n", __FUNCTION__);
2094
0
      pop(r2);
2095
0
      pop(r1);
2096
0
      ensure_defined(r2);
2097
0
      ensure_defined(r1);
2098
0
      r1.i = r1.i <= r2.i;
2099
0
      push(r1);
2100
0
      break;
2101
2102
4.85k
    case OP_INT_GE:
2103
4.85k
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_INT_GE: // %s()\n", __FUNCTION__);
2104
4.85k
      pop(r2);
2105
4.85k
      pop(r1);
2106
4.85k
      ensure_defined(r2);
2107
4.85k
      ensure_defined(r1);
2108
4.85k
      r1.i = r1.i >= r2.i;
2109
4.85k
      push(r1);
2110
4.85k
      break;
2111
2112
0
    case OP_INT_ADD:
2113
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_INT_ADD: // %s()\n", __FUNCTION__);
2114
0
      pop(r2);
2115
0
      pop(r1);
2116
0
      ensure_defined(r2);
2117
0
      ensure_defined(r1);
2118
0
      r1.i = r1.i + r2.i;
2119
0
      push(r1);
2120
0
      break;
2121
2122
0
    case OP_INT_SUB:
2123
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_INT_SUB: // %s()\n", __FUNCTION__);
2124
0
      pop(r2);
2125
0
      pop(r1);
2126
0
      ensure_defined(r2);
2127
0
      ensure_defined(r1);
2128
0
      r1.i = r1.i - r2.i;
2129
0
      push(r1);
2130
0
      break;
2131
2132
0
    case OP_INT_MUL:
2133
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_INT_MUL: // %s()\n", __FUNCTION__);
2134
0
      pop(r2);
2135
0
      pop(r1);
2136
0
      ensure_defined(r2);
2137
0
      ensure_defined(r1);
2138
0
      r1.i = r1.i * r2.i;
2139
0
      push(r1);
2140
0
      break;
2141
2142
0
    case OP_INT_DIV:
2143
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_INT_DIV: // %s()\n", __FUNCTION__);
2144
0
      pop(r2);
2145
0
      pop(r1);
2146
0
      ensure_defined(r2);
2147
0
      ensure_defined(r1);
2148
      // If divisor is zero the result is undefined. It's also undefined
2149
      // when dividing INT64_MIN by -1.
2150
0
      if (r2.i == 0 || (r1.i == INT64_MIN && r2.i == -1))
2151
0
        r1.i = YR_UNDEFINED;
2152
0
      else
2153
0
        r1.i = r1.i / r2.i;
2154
0
      push(r1);
2155
0
      break;
2156
2157
0
    case OP_INT_MINUS:
2158
0
      YR_DEBUG_FPRINTF(
2159
0
          2, stderr, "- case OP_INT_MINUS: // %s()\n", __FUNCTION__);
2160
0
      pop(r1);
2161
0
      ensure_defined(r1);
2162
0
      r1.i = -r1.i;
2163
0
      push(r1);
2164
0
      break;
2165
2166
0
    case OP_DBL_LT:
2167
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_DBL_LT: // %s()\n", __FUNCTION__);
2168
0
      pop(r2);
2169
0
      pop(r1);
2170
0
      if (is_undef(r1) || is_undef(r2))
2171
0
        r1.i = false;
2172
0
      else
2173
0
        r1.i = r1.d < r2.d;
2174
0
      push(r1);
2175
0
      break;
2176
2177
0
    case OP_DBL_GT:
2178
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_DBL_GT: // %s()\n", __FUNCTION__);
2179
0
      pop(r2);
2180
0
      pop(r1);
2181
0
      ensure_defined(r2);
2182
0
      ensure_defined(r1);
2183
0
      r1.i = r1.d > r2.d;
2184
0
      push(r1);
2185
0
      break;
2186
2187
0
    case OP_DBL_LE:
2188
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_DBL_LE: // %s()\n", __FUNCTION__);
2189
0
      pop(r2);
2190
0
      pop(r1);
2191
0
      ensure_defined(r2);
2192
0
      ensure_defined(r1);
2193
0
      r1.i = r1.d <= r2.d;
2194
0
      push(r1);
2195
0
      break;
2196
2197
10.0k
    case OP_DBL_GE:
2198
10.0k
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_DBL_GE: // %s()\n", __FUNCTION__);
2199
10.0k
      pop(r2);
2200
10.0k
      pop(r1);
2201
10.0k
      ensure_defined(r2);
2202
10.0k
      ensure_defined(r1);
2203
10.0k
      r1.i = r1.d >= r2.d;
2204
10.0k
      push(r1);
2205
10.0k
      break;
2206
2207
0
    case OP_DBL_EQ:
2208
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_DBL_EQ: // %s()\n", __FUNCTION__);
2209
0
      pop(r2);
2210
0
      pop(r1);
2211
0
      ensure_defined(r2);
2212
0
      ensure_defined(r1);
2213
0
      r1.i = fabs(r1.d - r2.d) < DBL_EPSILON;
2214
0
      push(r1);
2215
0
      break;
2216
2217
0
    case OP_DBL_NEQ:
2218
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_DBL_NEQ: // %s()\n", __FUNCTION__);
2219
0
      pop(r2);
2220
0
      pop(r1);
2221
0
      ensure_defined(r2);
2222
0
      ensure_defined(r1);
2223
0
      r1.i = fabs(r1.d - r2.d) >= DBL_EPSILON;
2224
0
      push(r1);
2225
0
      break;
2226
2227
0
    case OP_DBL_ADD:
2228
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_DBL_ADD: // %s()\n", __FUNCTION__);
2229
0
      pop(r2);
2230
0
      pop(r1);
2231
0
      ensure_defined(r2);
2232
0
      ensure_defined(r1);
2233
0
      r1.d = r1.d + r2.d;
2234
0
      push(r1);
2235
0
      break;
2236
2237
0
    case OP_DBL_SUB:
2238
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_DBL_SUB: // %s()\n", __FUNCTION__);
2239
0
      pop(r2);
2240
0
      pop(r1);
2241
0
      ensure_defined(r2);
2242
0
      ensure_defined(r1);
2243
0
      r1.d = r1.d - r2.d;
2244
0
      push(r1);
2245
0
      break;
2246
2247
0
    case OP_DBL_MUL:
2248
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_DBL_MUL: // %s()\n", __FUNCTION__);
2249
0
      pop(r2);
2250
0
      pop(r1);
2251
0
      ensure_defined(r2);
2252
0
      ensure_defined(r1);
2253
0
      r1.d = r1.d * r2.d;
2254
0
      push(r1);
2255
0
      break;
2256
2257
0
    case OP_DBL_DIV:
2258
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_DBL_DIV: // %s()\n", __FUNCTION__);
2259
0
      pop(r2);
2260
0
      pop(r1);
2261
0
      ensure_defined(r2);
2262
0
      ensure_defined(r1);
2263
0
      r1.d = r1.d / r2.d;
2264
0
      push(r1);
2265
0
      break;
2266
2267
0
    case OP_DBL_MINUS:
2268
0
      YR_DEBUG_FPRINTF(
2269
0
          2, stderr, "- case OP_DBL_MINUS: // %s()\n", __FUNCTION__);
2270
0
      pop(r1);
2271
0
      ensure_defined(r1);
2272
0
      r1.d = -r1.d;
2273
0
      push(r1);
2274
0
      break;
2275
2276
7.30k
    case OP_STR_EQ:
2277
7.30k
    case OP_STR_NEQ:
2278
7.30k
    case OP_STR_LT:
2279
7.30k
    case OP_STR_LE:
2280
7.30k
    case OP_STR_GT:
2281
7.30k
    case OP_STR_GE:
2282
7.30k
      pop(r2);
2283
7.30k
      pop(r1);
2284
2285
7.30k
      ensure_defined(r2);
2286
7.30k
      ensure_defined(r1);
2287
2288
501
      switch (opcode)
2289
501
      {
2290
501
      case OP_STR_EQ:
2291
501
        YR_DEBUG_FPRINTF(
2292
501
            2, stderr, "- case OP_STR_EQ: // %s()\n", __FUNCTION__);
2293
501
        r1.i = (ss_compare(r1.ss, r2.ss) == 0);
2294
501
        break;
2295
0
      case OP_STR_NEQ:
2296
0
        YR_DEBUG_FPRINTF(
2297
0
            2, stderr, "- case OP_STR_NEQ: // %s()\n", __FUNCTION__);
2298
0
        r1.i = (ss_compare(r1.ss, r2.ss) != 0);
2299
0
        break;
2300
0
      case OP_STR_LT:
2301
0
        YR_DEBUG_FPRINTF(
2302
0
            2, stderr, "- case OP_STR_LT: // %s()\n", __FUNCTION__);
2303
0
        r1.i = (ss_compare(r1.ss, r2.ss) < 0);
2304
0
        break;
2305
0
      case OP_STR_LE:
2306
0
        YR_DEBUG_FPRINTF(
2307
0
            2, stderr, "- case OP_STR_LE: // %s()\n", __FUNCTION__);
2308
0
        r1.i = (ss_compare(r1.ss, r2.ss) <= 0);
2309
0
        break;
2310
0
      case OP_STR_GT:
2311
0
        YR_DEBUG_FPRINTF(
2312
0
            2, stderr, "- case OP_STR_GT: // %s()\n", __FUNCTION__);
2313
0
        r1.i = (ss_compare(r1.ss, r2.ss) > 0);
2314
0
        break;
2315
0
      case OP_STR_GE:
2316
0
        YR_DEBUG_FPRINTF(
2317
0
            2, stderr, "- case OP_STR_GE: // %s()\n", __FUNCTION__);
2318
0
        r1.i = (ss_compare(r1.ss, r2.ss) >= 0);
2319
0
        break;
2320
501
      }
2321
2322
501
      push(r1);
2323
501
      break;
2324
2325
0
    case OP_CONTAINS:
2326
0
    case OP_ICONTAINS:
2327
0
    case OP_STARTSWITH:
2328
0
    case OP_ISTARTSWITH:
2329
0
    case OP_ENDSWITH:
2330
0
    case OP_IENDSWITH:
2331
0
    case OP_IEQUALS:
2332
0
      pop(r2);
2333
0
      pop(r1);
2334
2335
0
      ensure_defined(r1);
2336
0
      ensure_defined(r2);
2337
2338
0
      switch (opcode)
2339
0
      {
2340
0
      case OP_CONTAINS:
2341
0
        YR_DEBUG_FPRINTF(
2342
0
            2, stderr, "- case OP_CONTAINS: // %s()\n", __FUNCTION__);
2343
0
        r1.i = ss_contains(r1.ss, r2.ss);
2344
0
        break;
2345
0
      case OP_ICONTAINS:
2346
0
        YR_DEBUG_FPRINTF(
2347
0
            2, stderr, "- case OP_ICONTAINS: // %s()\n", __FUNCTION__);
2348
0
        r1.i = ss_icontains(r1.ss, r2.ss);
2349
0
        break;
2350
0
      case OP_STARTSWITH:
2351
0
        YR_DEBUG_FPRINTF(
2352
0
            2, stderr, "- case OP_STARTSWITH: // %s()\n", __FUNCTION__);
2353
0
        r1.i = ss_startswith(r1.ss, r2.ss);
2354
0
        break;
2355
0
      case OP_ISTARTSWITH:
2356
0
        YR_DEBUG_FPRINTF(
2357
0
            2, stderr, "- case OP_ISTARTSWITH: // %s()\n", __FUNCTION__);
2358
0
        r1.i = ss_istartswith(r1.ss, r2.ss);
2359
0
        break;
2360
0
      case OP_ENDSWITH:
2361
0
        YR_DEBUG_FPRINTF(
2362
0
            2, stderr, "- case OP_ENDSWITH: // %s()\n", __FUNCTION__);
2363
0
        r1.i = ss_endswith(r1.ss, r2.ss);
2364
0
        break;
2365
0
      case OP_IENDSWITH:
2366
0
        YR_DEBUG_FPRINTF(
2367
0
            2, stderr, "- case OP_IENDSWITH: // %s()\n", __FUNCTION__);
2368
0
        r1.i = ss_iendswith(r1.ss, r2.ss);
2369
0
        break;
2370
0
      case OP_IEQUALS:
2371
0
        YR_DEBUG_FPRINTF(
2372
0
            2, stderr, "- case OP_IEQUALS: // %s()\n", __FUNCTION__);
2373
0
        r1.i = ss_icompare(r1.ss, r2.ss) == 0;
2374
0
        break;
2375
0
      }
2376
2377
0
      push(r1);
2378
0
      break;
2379
2380
0
    default:
2381
0
      YR_DEBUG_FPRINTF(
2382
0
          2, stderr, "- case <unknown instruction>: // %s()\n", __FUNCTION__);
2383
      // Unknown instruction, this shouldn't happen.
2384
0
      assert(false);
2385
249k
    }
2386
2387
    // Check for timeout every 100 instruction cycles. If timeout == 0 it means
2388
    // no timeout at all.
2389
2390
249k
    if (context->timeout > 0ULL && ++cycle == 100)
2391
0
    {
2392
0
      elapsed_time = yr_stopwatch_elapsed_ns(&context->stopwatch);
2393
2394
0
      if (elapsed_time > context->timeout)
2395
0
      {
2396
#ifdef YR_PROFILING_ENABLED
2397
        context->profiling_info[current_rule_idx].exec_time +=
2398
            (elapsed_time - start_time);
2399
#endif
2400
0
        result = ERROR_SCAN_TIMEOUT;
2401
0
        stop = true;
2402
0
      }
2403
2404
0
      cycle = 0;
2405
0
    }
2406
249k
  }
2407
2408
16.5k
  obj_ptr = yr_arena_get_ptr(obj_arena, 0, 0);
2409
2410
31.5k
  for (int i = 0; i < obj_count; i++) yr_object_destroy(obj_ptr[i]);
2411
2412
16.5k
  yr_arena_release(obj_arena);
2413
16.5k
  yr_notebook_destroy(it_notebook);
2414
16.5k
  yr_modules_unload_all(context);
2415
16.5k
  yr_free(stack.items);
2416
2417
16.5k
  YR_DEBUG_FPRINTF(
2418
16.5k
      2,
2419
16.5k
      stderr,
2420
16.5k
      "} = %d AKA %s // %s()\n",
2421
16.5k
      result,
2422
16.5k
      yr_debug_error_as_string(result),
2423
16.5k
      __FUNCTION__);
2424
2425
16.5k
  return result;
2426
16.5k
}