示例#1
0
void _yr_ac_print_automaton_state(
  YR_AC_STATE* state)
{
  int i;
  int child_count;

  YR_AC_STATE_TRANSITION transition;
  YR_AC_MATCH* match;
  YR_AC_STATE* child_state;

  for (i = 0; i < state->depth; i++)
    printf(" ");

  child_state = _yr_ac_first_transition(state, &transition);
  child_count = 0;

  while(child_state != NULL)
  {
    child_count++;
    child_state = _yr_ac_next_transition(state, &transition);
  }

  printf("%p childs:%d depth:%d failure:%p",
         state, child_count, state->depth, state->failure);

  match = state->matches;

  while (match != NULL)
  {
    printf("\n");

    for (i = 0; i < state->depth + 1; i++)
      printf(" ");

    printf("%s = ", match->string->identifier);

    if (STRING_IS_HEX(match->string))
    {
      printf("{ ");

      for (i = 0; i < min(match->string->length, 10); i++)
        printf("%02x ", match->string->string[i]);

      printf("}");
    }
    else if (STRING_IS_REGEXP(match->string))
    {
      printf("/");

      for (i = 0; i < min(match->string->length, 10); i++)
        printf("%c", match->string->string[i]);

      printf("/");
    }
    else
    {
      printf("\"");

      for (i = 0; i < min(match->string->length, 10); i++)
        printf("%c", match->string->string[i]);

      printf("\"");
    }

    match = match->next;
  }

  printf("\n");

  child_state = _yr_ac_first_transition(state, &transition);

  while(child_state != NULL)
  {
    _yr_ac_print_automaton_state(child_state);
    child_state = _yr_ac_next_transition(state, &transition);
  }
}
示例#2
0
int get_match_data(int message, void* message_data, void* data)
{
	matches target;
	YR_META* meta;
	YR_STRING* s;
	YR_RULE* rule;
	pMatch m;
	YR_MODULE_IMPORT* mi; // Used for the CALLBACK_MSG_IMPORT_MODULE message.
	pcallback_data* cb_data = (pcallback_data*) data;
	if (!cb_data)
	{
		PRINT_ERROR << "Yara wrapper callback called with no data!" << std::endl;
		return ERROR_CALLBACK_ERROR;
	}

	switch (message)
	{
		case CALLBACK_MSG_RULE_MATCHING:
			rule = (YR_RULE*) message_data;
			target = cb_data->get()->yara_matches;
			meta = rule->metas;
			s = rule->strings;
			m = boost::make_shared<Match>();

			while (!META_IS_NULL(meta))
			{
				m->add_metadata(std::string(meta->identifier), meta->string);
				++meta;
			}
			while (!STRING_IS_NULL(s))
			{
				if (STRING_FOUND(s))
				{
					YR_MATCH* match = STRING_MATCHES(s).head;
					while (match != nullptr)
					{
						if (!STRING_IS_HEX(s))
						{
							std::string found((char*) match->data, match->length);
							// Yara inserts null bytes when it matches unicode strings. Dirty fix to remove them all.
							found.erase(std::remove(found.begin(), found.end(), '\0'), found.end());
							m->add_found_string(found);
						}
						else
						{
							std::stringstream ss;
							ss << std::hex;
							for (int i = 0; i < std::min(20, match->length); i++) {
								ss << static_cast<unsigned int>(match->data[i]) << " "; // Don't interpret as a char
							}
							if (match->length > 20) {
								ss << "...";
							}
							m->add_found_string(ss.str());
						}
						match = match->next;
					}
				}
				++s;
			}

			target->push_back(m);
			return CALLBACK_CONTINUE; // Don't stop on the first matching rule.

		case CALLBACK_MSG_RULE_NOT_MATCHING:
			return CALLBACK_CONTINUE;

		// Detect when the ManaPE module is loaded
		case CALLBACK_MSG_IMPORT_MODULE:
			mi = (YR_MODULE_IMPORT*) message_data;
			if (std::string(mi->module_name) == "manape")
			{
				if (!cb_data || cb_data->get()->pe_info == nullptr)
				{
					PRINT_ERROR << "Yara rule imports the ManaPE module, but no ManaPE data was given!" << std::endl;
					return ERROR_CALLBACK_ERROR;
				}
				else if (!cb_data)
				{
					PRINT_ERROR << "No data given to the callback to store results!" << std::endl;
					return ERROR_CALLBACK_ERROR;
				}
				mi->module_data = &*(cb_data->get()->pe_info);
			}
			return ERROR_SUCCESS;

		case CALLBACK_MSG_SCAN_FINISHED:
			return ERROR_SUCCESS;

		default:
			PRINT_WARNING << "Yara callback received an unhandled message (" << message << ")." << std::endl;
			return ERROR_SUCCESS;
	}
}
示例#3
0
int handle_message(int message, YR_RULE* rule, void* data)
{
  TAG* tag;
  IDENTIFIER* identifier;
  YR_STRING* string;
  YR_MATCH* match;
  YR_META* meta;

  char* tag_name;
  size_t tag_length;
  int is_matching;
  int string_found;
  int show = TRUE;

  if (show_specified_tags)
  {
    show = FALSE;
    tag = specified_tags_list;

    while (tag != NULL)
    {
      tag_name = rule->tags;
      tag_length = tag_name != NULL ? strlen(tag_name) : 0;

      while (tag_length > 0)
      {
        if (strcmp(tag_name, tag->identifier) == 0)
        {
          show = TRUE;
          break;
        }

        tag_name += tag_length + 1;
        tag_length = strlen(tag_name);
      }

      tag = tag->next;
    }
  }

  if (show_specified_rules)
  {
    show = FALSE;
    identifier = specified_rules_list;

    while (identifier != NULL)
    {
      if (strcmp(identifier->name, rule->identifier) == 0)
      {
        show = TRUE;
        break;
      }

      identifier = identifier->next;
    }
  }

  is_matching = (message == CALLBACK_MSG_RULE_MATCHING);

  show = show && ((!negate && is_matching) || (negate && !is_matching));

  if (show)
  {
    mutex_lock(&output_mutex);
    printf("%s ", rule->identifier);

    if (show_tags)
    {
      printf("[");

      tag_name = rule->tags;
      tag_length = tag_name != NULL ? strlen(tag_name) : 0;

      while (tag_length > 0)
      {
        printf("%s", tag_name);
        tag_name += tag_length + 1;
        tag_length = strlen(tag_name);

        if (tag_length > 0)
          printf(",");
      }

      printf("] ");
    }

    // Show meta-data.

    if (show_meta)
    {
      meta = rule->metas;

      printf("[");

      while(!META_IS_NULL(meta))
      {
        if (meta->type == META_TYPE_INTEGER)
          printf("%s=%d", meta->identifier, meta->integer);
        else if (meta->type == META_TYPE_BOOLEAN)
          printf("%s=%s", meta->identifier, meta->integer ? "true" : "false");
        else
          printf("%s=\"%s\"", meta->identifier, meta->string);

        meta++;

        if (!META_IS_NULL(meta))
          printf(",");
      }

      printf("] ");
    }

    printf("%s\n", (char*) data);

    // Show matched strings.

    if (show_strings)
    {
      string = rule->strings;

      while (!STRING_IS_NULL(string))
      {
        string_found = STRING_FOUND(string);

        if (string_found)
        {
          match = STRING_MATCHES(string).head;

          while (match != NULL)
          {
            printf("0x%" PRIx64 ":%s: ", match->first_offset, string->identifier);

            if (STRING_IS_HEX(string))
            {
              print_hex_string(match->data, match->length);
            }
            else
            {
              print_string(match->data, match->length);
            }

            match = match->next;
          }
        }

        string++;
      }
    }

    mutex_unlock(&output_mutex);
  }

  if (is_matching)
    count++;

  if (limit != 0 && count >= limit)
    return CALLBACK_ABORT;

  return CALLBACK_CONTINUE;
}
示例#4
0
文件: rules.c 项目: dodng/yara
int _yr_scan_verify_re_match(
    YR_AC_MATCH* ac_match,
    uint8_t* data,
    size_t data_size,
    size_t offset,
    YR_ARENA* matches_arena)
{
  CALLBACK_ARGS callback_args;
  RE_EXEC_FUNC exec;

  int forward_matches = -1;
  int backward_matches = -1;
  int flags = 0;

  if (STRING_IS_FAST_HEX_REGEXP(ac_match->string))
    exec = _yr_scan_fast_hex_re_exec;
  else
    exec = yr_re_exec;

  if (STRING_IS_NO_CASE(ac_match->string))
    flags |= RE_FLAGS_NO_CASE;

  if (STRING_IS_HEX(ac_match->string) ||
      STRING_IS_REGEXP_DOT_ALL(ac_match->string))
    flags |= RE_FLAGS_DOT_ALL;

  if (STRING_IS_ASCII(ac_match->string))
  {
    forward_matches = exec(
        ac_match->forward_code,
        data + offset,
        data_size - offset,
        flags,
        NULL,
        NULL);
  }

  if (STRING_IS_WIDE(ac_match->string) && forward_matches == -1)
  {
    flags |= RE_FLAGS_WIDE;
    forward_matches = exec(
        ac_match->forward_code,
        data + offset,
        data_size - offset,
        flags,
        NULL,
        NULL);
  }

  switch(forward_matches)
  {
    case -1:
      return ERROR_SUCCESS;
    case -2:
      return ERROR_INSUFICIENT_MEMORY;
    case -3:
      return ERROR_INTERNAL_FATAL_ERROR;
  }

  if (forward_matches == 0 && ac_match->backward_code == NULL)
    return ERROR_SUCCESS;

  callback_args.string = ac_match->string;
  callback_args.data = data;
  callback_args.data_size = data_size;
  callback_args.matches_arena = matches_arena;
  callback_args.forward_matches = forward_matches;
  callback_args.full_word = STRING_IS_FULL_WORD(ac_match->string);
  callback_args.tidx = yr_get_tidx();

  if (ac_match->backward_code != NULL)
  {
    backward_matches = exec(
        ac_match->backward_code,
        data + offset,
        offset,
        flags | RE_FLAGS_BACKWARDS | RE_FLAGS_EXHAUSTIVE,
        _yr_scan_match_callback,
        (void*) &callback_args);

    if (backward_matches == -2)
      return ERROR_INSUFICIENT_MEMORY;

    if (backward_matches == -3)
      return ERROR_INTERNAL_FATAL_ERROR;
  }
  else
  {
    FAIL_ON_ERROR(_yr_scan_match_callback(
        data + offset, 0, flags, &callback_args));
  }

  return ERROR_SUCCESS;
}