Coverage Report

Created: 2026-09-01 06:13

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