Coverage Report

Created: 2026-08-31 06:09

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
7.30k
#define MEM_SIZE YR_MAX_LOOP_NESTING*(YR_MAX_LOOP_VARS + YR_INTERNAL_LOOP_VARS)
53
54
#define push(x)                         \
55
36.5k
  if (stack.sp < stack.capacity)        \
56
36.5k
  {                                     \
57
36.5k
    stack.items[stack.sp++] = (x);      \
58
36.5k
  }                                     \
59
36.5k
  else                                  \
60
36.5k
  {                                     \
61
0
    result = ERROR_EXEC_STACK_OVERFLOW; \
62
0
    stop = true;                        \
63
0
    break;                              \
64
0
  }
65
66
#define pop(x)                   \
67
36.5k
  {                              \
68
36.5k
    assert(stack.sp > 0);        \
69
36.5k
    x = stack.items[--stack.sp]; \
70
36.5k
  }
71
72
36.5k
#define is_undef(x) IS_UNDEFINED((x).i)
73
74
#define ensure_defined(x) \
75
29.2k
  if (is_undef(x))        \
76
29.2k
  {                       \
77
6.80k
    r1.i = YR_UNDEFINED;  \
78
6.80k
    push(r1);             \
79
6.80k
    break;                \
80
6.80k
  }
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.5k
  {                                                               \
93
36.5k
    YR_ARENA_REF ref;                                             \
94
36.5k
    if (yr_arena_ptr_to_ref(context->rules->arena, x, &ref) == 0) \
95
36.5k
    {                                                             \
96
0
      stop = true;                                                \
97
0
      result = ERROR_INTERNAL_FATAL_ERROR;                        \
98
0
      break;                                                      \
99
0
    }                                                             \
100
36.5k
  }
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
65.7k
  if ((x) < code_start || (x) >= code_end) \
108
65.7k
  {                                        \
109
0
    stop = true;                           \
110
0
    result = ERROR_INTERNAL_FATAL_ERROR;   \
111
0
    break;                                 \
112
0
  }
113
114
#define check_object_canary(o)           \
115
7.30k
  if (o->canary != context->canary)      \
116
7.30k
  {                                      \
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
7.30k
{
174
7.30k
  int32_t off = 0;
175
176
7.30k
  if (condition)
177
0
  {
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
0
    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
0
    off -= 1;
189
0
  }
190
7.30k
  else
191
7.30k
  {
192
    // The condition is false, the execution flow proceeds with the instruction
193
    // right after the jump.
194
7.30k
    off = sizeof(int32_t);
195
7.30k
  }
196
197
7.30k
  return ip + off;
198
7.30k
}
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
7.30k
{
433
7.30k
  YR_DEBUG_FPRINTF(2, stderr, "+ %s() {\n", __FUNCTION__);
434
435
7.30k
  const uint8_t* code_start = context->rules->code_start;
436
7.30k
  const uint8_t* ip = code_start;
437
438
7.30k
#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
7.30k
  const uint8_t* code_end = code_start +
442
7.30k
                            yr_arena_get_current_offset(
443
7.30k
                                context->rules->arena, YR_CODE_SECTION);
444
7.30k
#endif
445
446
7.30k
  YR_VALUE mem[MEM_SIZE];
447
7.30k
  YR_VALUE args[YR_MAX_FUNCTION_ARGS];
448
7.30k
  YR_VALUE r1;
449
7.30k
  YR_VALUE r2;
450
7.30k
  YR_VALUE r3;
451
7.30k
  YR_VALUE r4;
452
453
7.30k
  YR_VALUE_STACK stack;
454
455
7.30k
  uint64_t elapsed_time;
456
457
#ifdef YR_PROFILING_ENABLED
458
  uint64_t start_time;
459
#endif
460
461
7.30k
  uint32_t current_rule_idx = 0;
462
7.30k
  YR_RULE* current_rule = NULL;
463
7.30k
  YR_RULE* rule;
464
7.30k
  YR_MATCH* match;
465
7.30k
  YR_OBJECT_FUNCTION* function;
466
7.30k
  YR_OBJECT** obj_ptr;
467
7.30k
  YR_ARENA* obj_arena;
468
7.30k
  YR_NOTEBOOK* it_notebook;
469
470
7.30k
  char* identifier;
471
7.30k
  char* args_fmt;
472
473
7.30k
  int found;
474
7.30k
  int count;
475
7.30k
  int result = ERROR_SUCCESS;
476
7.30k
  int cycle = 0;
477
7.30k
  int obj_count = 0;
478
479
7.30k
  bool stop = false;
480
481
7.30k
  uint8_t opcode;
482
483
7.30k
  yr_get_configuration_uint32(YR_CONFIG_STACK_SIZE, &stack.capacity);
484
485
7.30k
  stack.sp = 0;
486
7.30k
  stack.items = (YR_VALUE*) yr_malloc(stack.capacity * sizeof(YR_VALUE));
487
488
7.30k
  if (stack.items == NULL)
489
0
    return ERROR_INSUFFICIENT_MEMORY;
490
491
7.30k
  FAIL_ON_ERROR_WITH_CLEANUP(
492
7.30k
      yr_arena_create(1, 512 * sizeof(YR_OBJECT*), &obj_arena),
493
7.30k
      yr_free(stack.items));
494
495
7.30k
  FAIL_ON_ERROR_WITH_CLEANUP(
496
7.30k
      yr_notebook_create(512 * sizeof(YR_ITERATOR), &it_notebook),
497
7.30k
      yr_arena_release(obj_arena);
498
7.30k
      yr_free(stack.items));
499
500
#ifdef YR_PROFILING_ENABLED
501
  start_time = yr_stopwatch_elapsed_ns(&context->stopwatch);
502
#endif
503
504
7.30k
#if YR_PARANOID_EXEC
505
7.30k
  memset(mem, 0, MEM_SIZE * sizeof(mem[0]));
506
7.30k
#endif
507
508
73.0k
  while (!stop)
509
65.7k
  {
510
65.7k
#if YR_PARANOID_EXEC
511
65.7k
    ensure_within_code(ip);
512
65.7k
#endif
513
514
    // Read the opcode from the address indicated by the instruction pointer.
515
65.7k
    opcode = *ip;
516
517
    // Advance the instruction pointer, which now points past the opcode.
518
65.7k
    ip++;
519
520
65.7k
    switch (opcode)
521
65.7k
    {
522
0
    case OP_NOP:
523
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_NOP: // %s()\n", __FUNCTION__);
524
0
      break;
525
526
7.30k
    case OP_HALT:
527
7.30k
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_HALT: // %s()\n", __FUNCTION__);
528
7.30k
      assert(stack.sp == 0);  // When HALT is reached the stack should be empty.
529
7.30k
      stop = true;
530
7.30k
      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
7.30k
    case OP_PUSH:
829
7.30k
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_PUSH: // %s()\n", __FUNCTION__);
830
7.30k
      r1.i = yr_unaligned_u64(ip);
831
7.30k
      ip += sizeof(uint64_t);
832
7.30k
      push(r1);
833
7.30k
      break;
834
835
0
    case OP_PUSH_8:
836
0
      r1.i = *ip;
837
0
      YR_DEBUG_FPRINTF(
838
0
          2,
839
0
          stderr,
840
0
          "- case OP_PUSH_8: r1.i=%" PRId64 " // %s()\n",
841
0
          r1.i,
842
0
          __FUNCTION__);
843
0
      ip += sizeof(uint8_t);
844
0
      push(r1);
845
0
      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
0
    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
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_JFALSE: // %s()\n", __FUNCTION__);
1026
0
      pop(r1);
1027
0
      push(r1);
1028
0
      ip = jmp_if(!is_undef(r1) && !r1.i, ip);
1029
0
      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
0
    case OP_AND:
1057
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_AND: // %s()\n", __FUNCTION__);
1058
0
      pop(r2);
1059
0
      pop(r1);
1060
1061
0
      if (is_undef(r1))
1062
0
        r1.i = 0;
1063
1064
0
      if (is_undef(r2))
1065
0
        r2.i = 0;
1066
1067
0
      r1.i = r1.i && r2.i;
1068
0
      push(r1);
1069
0
      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
7.30k
    case OP_INIT_RULE:
1219
7.30k
      YR_DEBUG_FPRINTF(
1220
7.30k
          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
7.30k
      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
7.30k
      assert(current_rule_idx < context->rules->num_rules);
1228
1229
7.30k
      current_rule = &context->rules->rules_table[current_rule_idx];
1230
1231
7.30k
#if YR_PARANOID_EXEC
1232
7.30k
      ensure_within_rules_arena(current_rule);
1233
7.30k
#endif
1234
1235
      // If the rule is disabled, let's skip its code.
1236
7.30k
      bool skip_rule = RULE_IS_DISABLED(current_rule);
1237
1238
      // The rule is also skipped if it is not required to be evaluated.
1239
7.30k
      skip_rule |= yr_bitmask_is_not_set(
1240
7.30k
          context->required_eval, current_rule_idx);
1241
1242
7.30k
      ip = jmp_if(skip_rule, ip);
1243
1244
7.30k
      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
7.30k
      else
1252
7.30k
      {
1253
        // If not taking the jump, skip the bytes corresponding to the
1254
        // rule's index.
1255
7.30k
        ip += sizeof(uint32_t);
1256
7.30k
      }
1257
1258
7.30k
      break;
1259
1260
7.30k
    case OP_MATCH_RULE:
1261
7.30k
      YR_DEBUG_FPRINTF(
1262
7.30k
          2, stderr, "- case OP_MATCH_RULE: // %s()\n", __FUNCTION__);
1263
7.30k
      pop(r1);
1264
1265
7.30k
      r2.i = yr_unaligned_u64(ip);
1266
7.30k
      ip += sizeof(uint64_t);
1267
1268
7.30k
      rule = &context->rules->rules_table[r2.i];
1269
1270
7.30k
#if YR_PARANOID_EXEC
1271
7.30k
      ensure_within_rules_arena(rule);
1272
7.30k
#endif
1273
1274
7.30k
      if (!is_undef(r1) && r1.i)
1275
0
        yr_bitmask_set(context->rule_matches_flags, r2.i);
1276
7.30k
      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
7.30k
      assert(stack.sp == 0);  // at this point the stack should be empty.
1286
7.30k
      break;
1287
1288
7.30k
    case OP_OBJ_LOAD:
1289
7.30k
      YR_DEBUG_FPRINTF(
1290
7.30k
          2, stderr, "- case OP_OBJ_LOAD: // %s()\n", __FUNCTION__);
1291
1292
7.30k
      identifier = yr_unaligned_char_ptr(ip);
1293
7.30k
      ip += sizeof(uint64_t);
1294
1295
7.30k
#if YR_PARANOID_EXEC
1296
7.30k
      ensure_within_rules_arena(identifier);
1297
7.30k
#endif
1298
1299
7.30k
      r1.o = (YR_OBJECT*) yr_hash_table_lookup(
1300
7.30k
          context->objects_table, identifier, NULL);
1301
1302
7.30k
      assert(r1.o != NULL);
1303
7.30k
      push(r1);
1304
7.30k
      break;
1305
1306
7.30k
    case OP_OBJ_FIELD:
1307
7.30k
      YR_DEBUG_FPRINTF(
1308
7.30k
          2, stderr, "- case OP_OBJ_FIELD: // %s()\n", __FUNCTION__);
1309
1310
7.30k
      identifier = yr_unaligned_char_ptr(ip);
1311
7.30k
      ip += sizeof(uint64_t);
1312
1313
7.30k
#if YR_PARANOID_EXEC
1314
7.30k
      ensure_within_rules_arena(identifier);
1315
7.30k
#endif
1316
1317
7.30k
      pop(r1);
1318
7.30k
      ensure_defined(r1);
1319
1320
7.30k
      r1.o = yr_object_lookup_field(r1.o, identifier);
1321
1322
7.30k
      if (r1.o == NULL)
1323
0
      {
1324
0
        result = ERROR_INVALID_FIELD_NAME;
1325
0
        stop = true;
1326
0
        break;
1327
0
      }
1328
1329
7.30k
      push(r1);
1330
7.30k
      break;
1331
1332
7.30k
    case OP_OBJ_VALUE:
1333
7.30k
      YR_DEBUG_FPRINTF(
1334
7.30k
          2, stderr, "- case OP_OBJ_VALUE: // %s()\n", __FUNCTION__);
1335
7.30k
      pop(r1);
1336
7.30k
      ensure_defined(r1);
1337
1338
7.30k
#if YR_PARANOID_EXEC
1339
7.30k
      check_object_canary(r1.o);
1340
7.30k
#endif
1341
1342
7.30k
      switch (r1.o->type)
1343
7.30k
      {
1344
0
      case OBJECT_TYPE_INTEGER:
1345
0
        r1.i = r1.o->value.i;
1346
0
        break;
1347
1348
0
      case OBJECT_TYPE_FLOAT:
1349
0
        if (yr_isnan(r1.o->value.d))
1350
0
          r1.i = YR_UNDEFINED;
1351
0
        else
1352
0
          r1.d = r1.o->value.d;
1353
0
        break;
1354
1355
7.30k
      case OBJECT_TYPE_STRING:
1356
7.30k
        if (r1.o->value.ss == NULL)
1357
6.80k
          r1.i = YR_UNDEFINED;
1358
499
        else
1359
499
          r1.ss = r1.o->value.ss;
1360
7.30k
        break;
1361
1362
0
      default:
1363
0
        assert(false);
1364
7.30k
      }
1365
1366
7.30k
      push(r1);
1367
7.30k
      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
0
    case OP_CALL:
1416
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_CALL: // %s()\n", __FUNCTION__);
1417
1418
0
      args_fmt = yr_unaligned_char_ptr(ip);
1419
0
      ip += sizeof(uint64_t);
1420
1421
0
      int i = (int) strlen(args_fmt);
1422
0
      count = 0;
1423
1424
0
#if YR_PARANOID_EXEC
1425
0
      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
0
#endif
1432
1433
      // pop arguments from stack and copy them to args array
1434
1435
0
      while (i > 0)
1436
0
      {
1437
0
        pop(r1);
1438
1439
0
        if (is_undef(r1))  // count the number of undefined args
1440
0
          count++;
1441
1442
0
        args[i - 1] = r1;
1443
0
        i--;
1444
0
      }
1445
1446
0
      pop(r2);
1447
0
      ensure_defined(r2);
1448
1449
0
#if YR_PARANOID_EXEC
1450
0
      check_object_canary(r2.o);
1451
0
#endif
1452
1453
0
      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
0
      function = object_as_function(r2.o);
1464
0
      result = ERROR_INTERNAL_FATAL_ERROR;
1465
1466
0
      for (i = 0; i < YR_MAX_OVERLOADED_FUNCTIONS; i++)
1467
0
      {
1468
0
        if (function->prototypes[i].arguments_fmt == NULL)
1469
0
          break;
1470
1471
0
        if (strcmp(function->prototypes[i].arguments_fmt, args_fmt) == 0)
1472
0
        {
1473
0
          result = function->prototypes[i].code(args, context, function);
1474
0
          break;
1475
0
        }
1476
0
      }
1477
1478
      // If i == YR_MAX_OVERLOADED_FUNCTIONS at this point no matching
1479
      // prototype was found, but this shouldn't happen.
1480
0
      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
0
      if (result == ERROR_SUCCESS)
1486
0
        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
0
      if (result == ERROR_SUCCESS)
1492
0
      {
1493
0
        result = yr_arena_write_data(obj_arena, 0, &r1.o, sizeof(r1.o), NULL);
1494
0
        obj_count++;
1495
0
      }
1496
0
      else
1497
0
      {
1498
0
        r1.i = YR_UNDEFINED;
1499
0
      }
1500
1501
0
      stop = (result != ERROR_SUCCESS);
1502
0
      push(r1);
1503
0
      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
0
    case OP_FILESIZE:
1908
0
      r1.i = context->file_size;
1909
0
      YR_DEBUG_FPRINTF(
1910
0
          2,
1911
0
          stderr,
1912
0
          "- case OP_FILESIZE: r1.i=%" PRId64 "%s // %s()\n",
1913
0
          r1.i,
1914
0
          r1.i == YR_UNDEFINED ? " AKA YR_UNDEFINED" : "",
1915
0
          __FUNCTION__);
1916
0
      push(r1);
1917
0
      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
7.30k
    case OP_IMPORT:
2013
7.30k
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_IMPORT: // %s()\n", __FUNCTION__);
2014
7.30k
      r1.i = yr_unaligned_u64(ip);
2015
7.30k
      ip += sizeof(uint64_t);
2016
2017
7.30k
#if YR_PARANOID_EXEC
2018
7.30k
      ensure_within_rules_arena(r1.p);
2019
7.30k
#endif
2020
2021
7.30k
      result = yr_modules_load((char*) r1.p, context);
2022
2023
7.30k
      if (result != ERROR_SUCCESS)
2024
0
        stop = true;
2025
2026
7.30k
      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
0
    case OP_INT_TO_DBL:
2055
0
      YR_DEBUG_FPRINTF(
2056
0
          2, stderr, "- case OP_INT_TO_DBL: // %s()\n", __FUNCTION__);
2057
0
      r1.i = yr_unaligned_u64(ip);
2058
0
      ip += sizeof(uint64_t);
2059
2060
0
#if YR_PARANOID_EXEC
2061
0
      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
0
#endif
2068
2069
0
      r2 = stack.items[stack.sp - r1.i];
2070
2071
0
      if (is_undef(r2))
2072
0
        stack.items[stack.sp - r1.i].i = YR_UNDEFINED;
2073
0
      else
2074
0
        stack.items[stack.sp - r1.i].d = (double) r2.i;
2075
0
      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
0
    case OP_INT_GE:
2137
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_INT_GE: // %s()\n", __FUNCTION__);
2138
0
      pop(r2);
2139
0
      pop(r1);
2140
0
      ensure_defined(r2);
2141
0
      ensure_defined(r1);
2142
0
      r1.i = r1.i >= r2.i;
2143
0
      push(r1);
2144
0
      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
0
    case OP_DBL_GE:
2232
0
      YR_DEBUG_FPRINTF(2, stderr, "- case OP_DBL_GE: // %s()\n", __FUNCTION__);
2233
0
      pop(r2);
2234
0
      pop(r1);
2235
0
      ensure_defined(r2);
2236
0
      ensure_defined(r1);
2237
0
      r1.i = r1.d >= r2.d;
2238
0
      push(r1);
2239
0
      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
7.30k
    case OP_STR_EQ:
2311
7.30k
    case OP_STR_NEQ:
2312
7.30k
    case OP_STR_LT:
2313
7.30k
    case OP_STR_LE:
2314
7.30k
    case OP_STR_GT:
2315
7.30k
    case OP_STR_GE:
2316
7.30k
      pop(r2);
2317
7.30k
      pop(r1);
2318
2319
7.30k
      ensure_defined(r2);
2320
7.30k
      ensure_defined(r1);
2321
2322
499
      switch (opcode)
2323
499
      {
2324
499
      case OP_STR_EQ:
2325
499
        YR_DEBUG_FPRINTF(
2326
499
            2, stderr, "- case OP_STR_EQ: // %s()\n", __FUNCTION__);
2327
499
        r1.i = (ss_compare(r1.ss, r2.ss) == 0);
2328
499
        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
499
      }
2355
2356
499
      push(r1);
2357
499
      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
65.7k
    }
2420
2421
    // Check for timeout every 100 instruction cycles. If timeout == 0 it means
2422
    // no timeout at all.
2423
2424
65.7k
    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
65.7k
  }
2441
2442
7.30k
  obj_ptr = yr_arena_get_ptr(obj_arena, 0, 0);
2443
2444
7.30k
  for (int i = 0; i < obj_count; i++) yr_object_destroy(obj_ptr[i]);
2445
2446
7.30k
  yr_arena_release(obj_arena);
2447
7.30k
  yr_notebook_destroy(it_notebook);
2448
7.30k
  yr_modules_unload_all(context);
2449
7.30k
  yr_free(stack.items);
2450
2451
7.30k
  YR_DEBUG_FPRINTF(
2452
7.30k
      2,
2453
7.30k
      stderr,
2454
7.30k
      "} = %d AKA %s // %s()\n",
2455
7.30k
      result,
2456
7.30k
      yr_debug_error_as_string(result),
2457
7.30k
      __FUNCTION__);
2458
2459
7.30k
  return result;
2460
7.30k
}