Exemplo n.º 1
0
int yr_parser_emit_with_arg_reloc(
    yyscan_t yyscanner,
    int8_t instruction,
    int64_t argument,
    int8_t** instruction_address)
{
  void* ptr;

  int result = yr_arena_write_data(
      yyget_extra(yyscanner)->code_arena,
      &instruction,
      sizeof(int8_t),
      (void**) instruction_address);

  if (result == ERROR_SUCCESS)
    result = yr_arena_write_data(
        yyget_extra(yyscanner)->code_arena,
        &argument,
        sizeof(int64_t),
        &ptr);

  if (result == ERROR_SUCCESS)
    result = yr_arena_make_relocatable(
        yyget_extra(yyscanner)->code_arena,
        ptr,
        0,
        EOL);

  return result;
}
Exemplo n.º 2
0
int yr_parser_emit_with_arg_reloc(
    yyscan_t yyscanner,
    uint8_t instruction,
    void* argument,
    uint8_t** instruction_address,
    void** argument_address)
{
  int64_t* ptr = NULL;
  int result;

  DECLARE_REFERENCE(void*, ptr) arg;

  memset(&arg, 0, sizeof(arg));
  arg.ptr = argument;

  result = yr_arena_write_data(
      yyget_extra(yyscanner)->code_arena,
      &instruction,
      sizeof(uint8_t),
      (void**) instruction_address);

  if (result == ERROR_SUCCESS)
    result = yr_arena_write_data(
        yyget_extra(yyscanner)->code_arena,
        &arg,
        sizeof(arg),
        (void**) &ptr);

  if (result == ERROR_SUCCESS)
    result = yr_arena_make_relocatable(
        yyget_extra(yyscanner)->code_arena,
        ptr,
        0,
        EOL);

  if (argument_address != NULL)
    *argument_address = (void*) ptr;

  return result;
}
Exemplo n.º 3
0
int yr_arena_load_stream(
    YR_STREAM* stream,
    YR_ARENA** arena)
{
  YR_ARENA_PAGE* page;
  YR_ARENA* new_arena;
  ARENA_FILE_HEADER header;

  uint32_t reloc_offset;
  uint8_t** reloc_address;
  uint8_t* reloc_target;

  int result;

  if (yr_stream_read(&header, sizeof(header), 1, stream) != 1)
    return ERROR_INVALID_FILE;

  if (header.magic[0] != 'Y' ||
      header.magic[1] != 'A' ||
      header.magic[2] != 'R' ||
      header.magic[3] != 'A')
  {
    return ERROR_INVALID_FILE;
  }

  if (header.size < 2048)       // compiled rules are always larger than 2KB
    return ERROR_CORRUPT_FILE;

  if (header.version != ARENA_FILE_VERSION)
    return ERROR_UNSUPPORTED_FILE_VERSION;

  result = yr_arena_create(header.size, 0, &new_arena);

  if (result != ERROR_SUCCESS)
    return result;

  page = new_arena->current_page;

  if (yr_stream_read(page->address, header.size, 1, stream) != 1)
  {
    yr_arena_destroy(new_arena);
    return ERROR_CORRUPT_FILE;
  }

  page->used = header.size;

  if (yr_stream_read(&reloc_offset, sizeof(reloc_offset), 1, stream) != 1)
  {
    yr_arena_destroy(new_arena);
    return ERROR_CORRUPT_FILE;
  }

  while (reloc_offset != 0xFFFFFFFF)
  {
    if (reloc_offset > header.size - sizeof(uint8_t*))
    {
      yr_arena_destroy(new_arena);
      return ERROR_CORRUPT_FILE;
    }

    yr_arena_make_relocatable(new_arena, page->address, reloc_offset, EOL);

    reloc_address = (uint8_t**) (page->address + reloc_offset);
    reloc_target = *reloc_address;

    if (reloc_target != (uint8_t*) (size_t) 0xFFFABADA)
      *reloc_address += (size_t) page->address;
    else
      *reloc_address = 0;

    if (yr_stream_read(&reloc_offset, sizeof(reloc_offset), 1, stream) != 1)
    {
      yr_arena_destroy(new_arena);
      return ERROR_CORRUPT_FILE;
    }
  }

  *arena = new_arena;

  return ERROR_SUCCESS;
}
Exemplo n.º 4
0
int yr_arena_load(
    const char* filename,
    YR_ARENA** arena)
{
  FILE* fh;
  YR_ARENA_PAGE* page;
  YR_ARENA* new_arena;
  ARENA_FILE_HEADER header;

  int32_t reloc_offset;
  uint8_t** reloc_address;
  uint8_t* reloc_target;

  long file_size;
  int result;

  fh = fopen(filename, "rb");

  if (fh == NULL)
    return ERROR_COULD_NOT_OPEN_FILE;

  fseek(fh, 0, SEEK_END);
  file_size = ftell(fh);
  fseek(fh, 0, SEEK_SET);

  if (fread(&header, sizeof(header), 1, fh) != 1)
  {
    fclose(fh);
    return ERROR_INVALID_FILE;
  }

  if (header.magic[0] != 'Y' ||
      header.magic[1] != 'A' ||
      header.magic[2] != 'R' ||
      header.magic[3] != 'A')
  {
    fclose(fh);
    return ERROR_INVALID_FILE;
  }

  if (header.size >= (uint32_t)file_size)
  {
    fclose(fh);
    return ERROR_CORRUPT_FILE;
  }

  if (header.version > ARENA_FILE_VERSION)
  {
    fclose(fh);
    return ERROR_UNSUPPORTED_FILE_VERSION;
  }

  result = yr_arena_create(header.size, 0, &new_arena);

  if (result != ERROR_SUCCESS)
  {
    fclose(fh);
    return result;
  }

  page = new_arena->current_page;

  if (fread(page->address, header.size, 1, fh) != 1)
  {
    fclose(fh);
    yr_arena_destroy(new_arena);
    return ERROR_CORRUPT_FILE;
  }

  page->used = header.size;

  if (fread(&reloc_offset, sizeof(reloc_offset), 1, fh) != 1)
  {
    fclose(fh);
    yr_arena_destroy(new_arena);
    return ERROR_CORRUPT_FILE;
  }

  while (reloc_offset != -1)
  {
    yr_arena_make_relocatable(new_arena, page->address, reloc_offset, EOL);

    reloc_address = (uint8_t**) (page->address + reloc_offset);
    reloc_target = *reloc_address;

    if (reloc_target != (uint8_t*) (size_t) 0xFFFABADA)
      *reloc_address += (size_t) page->address;
    else
      *reloc_address = 0;

    if (fread(&reloc_offset, sizeof(reloc_offset), 1, fh) != 1)
    {
      fclose(fh);
      yr_arena_destroy(new_arena);
      return ERROR_CORRUPT_FILE;
    }
  }

  fclose(fh);

  *arena = new_arena;

  return ERROR_SUCCESS;
}
Exemplo n.º 5
0
YR_AC_STATE* _yr_ac_create_state(
    YR_ARENA* arena,
    YR_AC_STATE* state,
    uint8_t input)
{
  int result;
  YR_AC_STATE* new_state;
  YR_AC_LIST_BASED_STATE* list_based_state;
  YR_AC_TABLE_BASED_STATE* table_based_state;
  YR_AC_STATE_TRANSITION* new_transition;

  if (state->depth < MAX_TABLE_BASED_STATES_DEPTH)
  {
    result = yr_arena_allocate_struct(
        arena,
        sizeof(YR_AC_TABLE_BASED_STATE),
        (void**) &new_state,
        offsetof(YR_AC_TABLE_BASED_STATE, failure),
        offsetof(YR_AC_TABLE_BASED_STATE, matches),
        EOL);
  }
  else
  {
    result = yr_arena_allocate_struct(
        arena,
        sizeof(YR_AC_LIST_BASED_STATE),
        (void**) &new_state,
        offsetof(YR_AC_LIST_BASED_STATE, failure),
        offsetof(YR_AC_LIST_BASED_STATE, matches),
        offsetof(YR_AC_LIST_BASED_STATE, transitions),
        EOL);
  }

  if (result != ERROR_SUCCESS)
    return NULL;

  if (state->depth <= MAX_TABLE_BASED_STATES_DEPTH)
  {
    result = yr_arena_make_relocatable(
        arena,
        state,
        offsetof(YR_AC_TABLE_BASED_STATE, transitions[input]),
        EOL);

    if (result != ERROR_SUCCESS)
      return NULL;

    table_based_state = (YR_AC_TABLE_BASED_STATE*) state;
    table_based_state->transitions[input].state = new_state;
  }
  else
  {
    result = yr_arena_allocate_struct(
        arena,
        sizeof(YR_AC_STATE_TRANSITION),
        (void**) &new_transition,
        offsetof(YR_AC_STATE_TRANSITION, state),
        offsetof(YR_AC_STATE_TRANSITION, next),
        EOL);

    if (result != ERROR_SUCCESS)
      return NULL;

    list_based_state = (YR_AC_LIST_BASED_STATE*) state;

    new_transition->input = input;
    new_transition->state = new_state;
    new_transition->next = list_based_state->transitions;
    list_based_state->transitions = new_transition;
  }

  new_state->depth = state->depth + 1;

  return new_state;
}
Exemplo n.º 6
0
int yr_ac_compile(
    YR_AC_AUTOMATON* automaton,
    YR_ARENA* arena,
    YR_AC_TABLES* tables)
{
  uint32_t i;

  FAIL_ON_ERROR(_yr_ac_create_failure_links(automaton));
  FAIL_ON_ERROR(_yr_ac_optimize_failure_links(automaton));
  FAIL_ON_ERROR(_yr_ac_build_transition_table(automaton));

  FAIL_ON_ERROR(yr_arena_reserve_memory(
      arena,
      automaton->tables_size * sizeof(tables->transitions[0]) +
      automaton->tables_size * sizeof(tables->matches[0])));

  FAIL_ON_ERROR(yr_arena_write_data(
      arena,
      automaton->t_table,
      sizeof(YR_AC_TRANSITION),
      (void**) &tables->transitions));

  for (i = 1; i < automaton->tables_size; i++)
  {
    FAIL_ON_ERROR(yr_arena_write_data(
        arena,
        automaton->t_table + i,
        sizeof(YR_AC_TRANSITION),
        NULL));
  }

  FAIL_ON_ERROR(yr_arena_write_data(
      arena,
      automaton->m_table,
      sizeof(YR_AC_MATCH_TABLE_ENTRY),
      (void**) &tables->matches));

  FAIL_ON_ERROR(yr_arena_make_relocatable(
      arena,
      tables->matches,
      offsetof(YR_AC_MATCH_TABLE_ENTRY, match),
      EOL));

  for (i = 1; i < automaton->tables_size; i++)
  {
    void* ptr;

    FAIL_ON_ERROR(yr_arena_write_data(
        arena,
        automaton->m_table + i,
        sizeof(YR_AC_MATCH_TABLE_ENTRY),
        (void**) &ptr));

    FAIL_ON_ERROR(yr_arena_make_relocatable(
        arena,
        ptr,
        offsetof(YR_AC_MATCH_TABLE_ENTRY, match),
        EOL));
  }

  return ERROR_SUCCESS;
}