Exemple #1
0
Fichier : re.c Projet : mikalv/yara
void _yr_re_fiber_sync(
    RE_FIBER_LIST* fiber_list,
    RE_FIBER_LIST* fiber_pool,
    RE_FIBER* fiber_to_sync)
{
  RE_FIBER* fiber;
  RE_FIBER* last;
  RE_FIBER* prev;
  RE_FIBER* new_fiber;

  fiber = fiber_to_sync;
  prev = fiber_to_sync->prev;
  last = fiber_to_sync->next;

  while(fiber != last)
  {
    switch(*fiber->ip)
    {
      case RE_OPCODE_SPLIT_A:
        new_fiber = _yr_re_fiber_split(fiber, fiber_list, fiber_pool);
        new_fiber->ip += *(int16_t*)(fiber->ip + 1);
        fiber->ip += 3;
        break;

      case RE_OPCODE_SPLIT_B:
        new_fiber = _yr_re_fiber_split(fiber, fiber_list, fiber_pool);
        new_fiber->ip += 3;
        fiber->ip += *(int16_t*)(fiber->ip + 1);
        break;

      case RE_OPCODE_JUMP:
        fiber->ip += *(int16_t*)(fiber->ip + 1);
        break;

      case RE_OPCODE_JNZ:
        fiber->stack[fiber->sp]--;
        if (fiber->stack[fiber->sp] > 0)
          fiber->ip += *(int16_t*)(fiber->ip + 1);
        else
          fiber->ip += 3;
        break;

      case RE_OPCODE_PUSH:
        fiber->stack[++fiber->sp] = *(uint16_t*)(fiber->ip + 1);
        fiber->ip += 3;
        break;

      case RE_OPCODE_POP:
        fiber->sp--;
        fiber->ip++;
        break;

      default:
        if (_yr_re_fiber_exists(fiber_list, fiber, prev))
          fiber = _yr_re_fiber_kill(fiber_list, fiber_pool, fiber);
        else
          fiber = fiber->next;
    }
  }
}
Exemple #2
0
Fichier : re.c Projet : ewil/yara
int _yr_re_fiber_sync(
    RE_FIBER_LIST* fiber_list,
    RE_FIBER_POOL* fiber_pool,
    RE_FIBER* fiber_to_sync)
{
  // A array for keeping track of which split instructions has been already
  // executed. Each split instruction within a regexp has an associated ID
  // between 0 and RE_MAX_SPLIT_ID. Keeping track of executed splits is
  // required to avoid infinite loops in regexps like (a*)* or (a|)*

  RE_SPLIT_ID_TYPE splits_executed[RE_MAX_SPLIT_ID];
  RE_SPLIT_ID_TYPE splits_executed_count = 0;
  RE_SPLIT_ID_TYPE split_id, splits_executed_idx;

  int split_already_executed;

  RE_FIBER* fiber;
  RE_FIBER* last;
  RE_FIBER* prev;
  RE_FIBER* new_fiber;

  fiber = fiber_to_sync;
  prev = fiber_to_sync->prev;
  last = fiber_to_sync->next;

  while(fiber != last)
  {
    switch(*fiber->ip)
    {
      case RE_OPCODE_SPLIT_A:
      case RE_OPCODE_SPLIT_B:

        split_id = *(RE_SPLIT_ID_TYPE*)(fiber->ip + 1);
        split_already_executed = FALSE;

        for (splits_executed_idx = 0;
             splits_executed_idx < splits_executed_count;
             splits_executed_idx++)
        {
          if (split_id == splits_executed[splits_executed_idx])
          {
            split_already_executed = TRUE;
            break;
          }
        }

        if (split_already_executed)
        {
          fiber = _yr_re_fiber_kill(fiber_list, fiber_pool, fiber);
        }
        else
        {
          FAIL_ON_ERROR(_yr_re_fiber_split(
              fiber, fiber_list, fiber_pool, &new_fiber));

          if (*fiber->ip == RE_OPCODE_SPLIT_A)
          {
            new_fiber->ip += *(int16_t*)(
              fiber->ip
              + 1  // opcode size
              + sizeof(RE_SPLIT_ID_TYPE));

            fiber->ip += (sizeof(RE_SPLIT_ID_TYPE) + 3);
          }
          else
          {
            fiber->ip += *(int16_t*)(
              fiber->ip
              + 1  // opcode size
              + sizeof(RE_SPLIT_ID_TYPE));

            new_fiber->ip += (sizeof(RE_SPLIT_ID_TYPE) + 3);
          }

          splits_executed[splits_executed_count] = split_id;
          splits_executed_count++;
        }

        break;

      case RE_OPCODE_JUMP:
        fiber->ip += *(int16_t*)(fiber->ip + 1);
        break;

      case RE_OPCODE_JNZ:
        fiber->stack[fiber->sp]--;
        if (fiber->stack[fiber->sp] > 0)
          fiber->ip += *(int16_t*)(fiber->ip + 1);
        else
          fiber->ip += 3;
        break;

      case RE_OPCODE_PUSH:
        fiber->stack[++fiber->sp] = *(uint16_t*)(fiber->ip + 1);
        fiber->ip += 3;
        break;

      case RE_OPCODE_POP:
        fiber->sp--;
        fiber->ip++;
        break;

      default:
        if (_yr_re_fiber_exists(fiber_list, fiber, prev))
          fiber = _yr_re_fiber_kill(fiber_list, fiber_pool, fiber);
        else
          fiber = fiber->next;
    }
  }

  return ERROR_SUCCESS;
}