Coverage Report

Created: 2023-03-26 07:37

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