コード例 #1
0
ファイル: util.c プロジェクト: nsxz/yara
YR_RULES* compile_rule(
    char* string)
{
  YR_COMPILER* compiler = NULL;
  YR_RULES* rules = NULL;

  compile_error[0] = '\0';

  if (yr_compiler_create(&compiler) != ERROR_SUCCESS)
  {
    perror("yr_compiler_create");
    goto _exit;
  }

  yr_compiler_set_callback(compiler, callback_function, NULL);

  if (yr_compiler_add_string(compiler, string, NULL) != 0)
  {
    goto _exit;
  }

  if (yr_compiler_get_rules(compiler, &rules) != ERROR_SUCCESS)
  {
    goto _exit;
  }

 _exit:
  yr_compiler_destroy(compiler);
  return rules;
}
コード例 #2
0
ファイル: util.c プロジェクト: elmelik/yara
int compile_rule(
    char* string,
    YR_RULES** rules)
{
  YR_COMPILER* compiler = NULL;
  int result = ERROR_SUCCESS;

  compile_error[0] = '\0';

  if (yr_compiler_create(&compiler) != ERROR_SUCCESS)
  {
    perror("yr_compiler_create");
    goto _exit;
  }

  yr_compiler_set_callback(compiler, callback_function, NULL);

  if (yr_compiler_add_string(compiler, string, NULL) != 0)
  {
    result = compiler->last_error;
    goto _exit;
  }

  result = yr_compiler_get_rules(compiler, rules);

_exit:
  yr_compiler_destroy(compiler);
  return result;
}
コード例 #3
0
ファイル: yara_utils.cpp プロジェクト: dotnetstation/osquery
/**
 * Compile a single rule file and load it into rule pointer.
 */
Status compileSingleFile(const std::string& file, YR_RULES** rules) {
  YR_COMPILER *compiler = nullptr;
  int result = yr_compiler_create(&compiler);
  if (result != ERROR_SUCCESS) {
    VLOG(1) << "Could not create compiler: " + std::to_string(result);
    return Status(1, "Could not create compiler: " + std::to_string(result));
  }

  yr_compiler_set_callback(compiler, YARACompilerCallback, nullptr);

  bool compiled = false;
  YR_RULES *tmp_rules;
  VLOG(1) << "Loading " << file;

  // First attempt to load the file, in case it is saved (pre-compiled)
  // rules.
  //
  // If you want to use saved rule files you must have them all in a single
  // file. This is easy to accomplish with yarac(1).
  result = yr_rules_load(file.c_str(), &tmp_rules);
  if (result != ERROR_SUCCESS && result != ERROR_INVALID_FILE) {
    yr_compiler_destroy(compiler);
    return Status(1, "Error loading YARA rules: " + std::to_string(result));
  } else if (result == ERROR_SUCCESS) {
    *rules = tmp_rules;
  } else {
    compiled = true;
    // Try to compile the rules.
    FILE *rule_file = fopen(file.c_str(), "r");

    if (rule_file == nullptr) {
      yr_compiler_destroy(compiler);
      return Status(1, "Could not open file: " + file);
    }

    int errors =
        yr_compiler_add_file(compiler, rule_file, nullptr, file.c_str());

    fclose(rule_file);
    rule_file = nullptr;

    if (errors > 0) {
      yr_compiler_destroy(compiler);
      // Errors printed via callback.
      return Status(1, "Compilation errors");
    }
  }

  if (compiled) {
    // All the rules for this category have been compiled, save them in the map.
    result = yr_compiler_get_rules(compiler, *(&rules));

    if (result != ERROR_SUCCESS) {
      yr_compiler_destroy(compiler);
      return Status(1, "Insufficient memory to get YARA rules");
    }
  }

  if (compiler != nullptr) {
    yr_compiler_destroy(compiler);
    compiler = nullptr;
  }

  return Status(0, "OK");
}
コード例 #4
0
ファイル: yara_utils.cpp プロジェクト: dotnetstation/osquery
/**
 * Given a vector of strings, attempt to compile them and store the result
 * in the map under the given category.
 */
Status handleRuleFiles(const std::string& category,
                       const pt::ptree& rule_files,
                       std::map<std::string, YR_RULES*>* rules) {
  YR_COMPILER *compiler = nullptr;
  int result = yr_compiler_create(&compiler);
  if (result != ERROR_SUCCESS) {
    VLOG(1) << "Could not create compiler: " + std::to_string(result);
    return Status(1, "Could not create compiler: " + std::to_string(result));
  }

  yr_compiler_set_callback(compiler, YARACompilerCallback, nullptr);

  bool compiled = false;
  for (const auto& item : rule_files) {
    YR_RULES *tmp_rules;
    const auto rule = item.second.get("", "");
    VLOG(1) << "Loading " << rule;

    std::string full_path;
    if (rule[0] != '/') {
      full_path = std::string("/etc/osquery/yara/") + rule;
    } else {
      full_path = rule;
    }

    // First attempt to load the file, in case it is saved (pre-compiled)
    // rules. Sadly there is no way to load multiple compiled rules in
    // succession. This means that:
    //
    // saved1, saved2
    // results in saved2 being the only file used.
    //
    // Also, mixing source and saved rules results in the saved rules being
    // overridden by the combination of the source rules once compiled, e.g.:
    //
    // file1, saved1
    // result in file1 being the only file used.
    //
    // If you want to use saved rule files you must have them all in a single
    // file. This is easy to accomplish with yarac(1).
    result = yr_rules_load(full_path.c_str(), &tmp_rules);
    if (result != ERROR_SUCCESS && result != ERROR_INVALID_FILE) {
      yr_compiler_destroy(compiler);
      return Status(1, "Error loading YARA rules: " + std::to_string(result));
    } else if (result == ERROR_SUCCESS) {
      // If there are already rules there, destroy them and put new ones in.
      if (rules->count(category) > 0) {
        yr_rules_destroy((*rules)[category]);
      }
      (*rules)[category] = tmp_rules;
    } else {
      compiled = true;
      // Try to compile the rules.
      FILE *rule_file = fopen(full_path.c_str(), "r");

      if (rule_file == nullptr) {
        yr_compiler_destroy(compiler);
        return Status(1, "Could not open file: " + full_path);
      }

      int errors =
          yr_compiler_add_file(compiler, rule_file, nullptr, full_path.c_str());

      fclose(rule_file);
      rule_file = nullptr;

      if (errors > 0) {
        yr_compiler_destroy(compiler);
        // Errors printed via callback.
        return Status(1, "Compilation errors");
      }
    }
  }

  if (compiled) {
    // All the rules for this category have been compiled, save them in the map.
    result = yr_compiler_get_rules(compiler, &((*rules)[category]));

    if (result != ERROR_SUCCESS) {
      yr_compiler_destroy(compiler);
      return Status(1, "Insufficient memory to get YARA rules");
    }
  }

  if (compiler != nullptr) {
    yr_compiler_destroy(compiler);
    compiler = nullptr;
  }

  return Status(0, "OK");
}
コード例 #5
0
ファイル: yarac.c プロジェクト: elmelik/yara
int main(
    int argc,
    const char** argv)
{
  COMPILER_RESULTS cr;

  YR_COMPILER* compiler = NULL;
  YR_RULES* rules = NULL;

  int result;

  argc = args_parse(options, argc, argv);

  if (show_version)
  {
    printf("%s\n", YR_VERSION);
    return EXIT_SUCCESS;
  }

  if (show_help)
  {
    printf("%s\n\n", USAGE_STRING);

    args_print_usage(options, 35);
    printf("\nSend bug reports and suggestions to: [email protected]\n");

    return EXIT_SUCCESS;
  }

  if (argc < 2)
  {
    fprintf(stderr, "yarac: wrong number of arguments\n");
    fprintf(stderr, "%s\n\n", USAGE_STRING);
    fprintf(stderr, "Try `--help` for more options\n");

    exit_with_code(EXIT_FAILURE);
  }

  result = yr_initialize();

  if (result != ERROR_SUCCESS)
    exit_with_code(EXIT_FAILURE);

  if (yr_compiler_create(&compiler) != ERROR_SUCCESS)
    exit_with_code(EXIT_FAILURE);

  if (!define_external_variables(compiler))
    exit_with_code(EXIT_FAILURE);

  cr.errors = 0;
  cr.warnings = 0;

  yr_set_configuration(YR_CONFIG_MAX_STRINGS_PER_RULE, &max_strings_per_rule);
  yr_compiler_set_callback(compiler, report_error, &cr);

  if (!compile_files(compiler, argc, argv))
    exit_with_code(EXIT_FAILURE);

  if (cr.errors > 0)
    exit_with_code(EXIT_FAILURE);

  if (fail_on_warnings && cr.warnings > 0)
    exit_with_code(EXIT_FAILURE);

  result = yr_compiler_get_rules(compiler, &rules);

  if (result != ERROR_SUCCESS)
  {
    fprintf(stderr, "error: %d\n", result);
    exit_with_code(EXIT_FAILURE);
  }

  result = yr_rules_save(rules, argv[argc - 1]);

  if (result != ERROR_SUCCESS)
  {
    fprintf(stderr, "error: %d\n", result);
    exit_with_code(EXIT_FAILURE);
  }

  result = EXIT_SUCCESS;

_exit:

  if (compiler != NULL)
    yr_compiler_destroy(compiler);

  if (rules != NULL)
    yr_rules_destroy(rules);

  yr_finalize();

  return result;
}
コード例 #6
0
bool Yara::load_rules(const std::string& rule_filename)
{
	if (_current_rules == rule_filename) {
		return true;
	}
	else { // The previous rules and compiler have to be freed manually.
		_clean_compiler_and_rules();
	}

	bool res = false;
	int retval;

	// Look for a compiled version of the rule file first.
	if (boost::filesystem::exists(rule_filename + "c")) { // File extension is .yarac instead of .yara.
		retval = yr_rules_load((rule_filename + "c").c_str(), &_rules);
	}
	else {
		retval = yr_rules_load(rule_filename.c_str(), &_rules);
	}

	// Yara rules compiled with a previous Yara version. Delete and recompile.
	if (retval == ERROR_UNSUPPORTED_FILE_VERSION) {
		boost::filesystem::remove(rule_filename + "c");
	}

	if (retval != ERROR_SUCCESS && retval != ERROR_INVALID_FILE && retval != ERROR_UNSUPPORTED_FILE_VERSION)
	{
		PRINT_ERROR << "Could not load yara rules (" << translate_error(retval) << ")." << std::endl;
		return false;
	}

	if (retval == ERROR_SUCCESS) {
		return true;
	}
	else if (retval == ERROR_INVALID_FILE || retval == ERROR_UNSUPPORTED_FILE_VERSION) // Uncompiled rules
	{
		if (yr_compiler_create(&_compiler) != ERROR_SUCCESS) {
			return false;
		}
		yr_compiler_set_callback(_compiler, compiler_callback, nullptr);
		FILE* rule_file = fopen(rule_filename.c_str(), "r");
		if (rule_file == nullptr) {
			return false;
		}
		retval = yr_compiler_add_file(_compiler, rule_file, nullptr, rule_filename.c_str());
		if (retval != 0)
		{
			PRINT_ERROR << "Could not compile yara rules (" << retval << " error(s))." << std::endl;
			goto END;
		}
		retval = yr_compiler_get_rules(_compiler, &_rules);
		if (retval != ERROR_SUCCESS) {
			goto END;
		}

		// Save the compiled rules to improve load times.
		// /!\ The compiled rules will have to be deleted if the original (readable) rule file is updated!
		// TODO: Compare timestamps and recompile automatically.
		retval = yr_rules_save(_rules, (rule_filename + "c").c_str());
		if (retval != ERROR_SUCCESS) {
			goto END;
		}

		res = true;
		_current_rules = rule_filename;
		END:
		if (rule_file != nullptr) {
			fclose(rule_file);
		}
	}
	return res;
}
コード例 #7
0
ファイル: yarac.c プロジェクト: digideskio/yara
int main(
    int argc,
    const char** argv)
{
  YR_COMPILER* compiler = NULL;
  YR_RULES* rules = NULL;

  int result;

  argc = args_parse(options, argc, argv);

  if (show_version)
  {
    printf("%s\n", PACKAGE_STRING);
    printf("\nSend bug reports and suggestions to: %s.\n", PACKAGE_BUGREPORT);

    return EXIT_FAILURE;
  }

  if (show_help)
  {
    printf("%s\n\n", USAGE_STRING);

    args_print_usage(options, 25);
    printf("\nSend bug reports and suggestions to: %s.\n", PACKAGE_BUGREPORT);

    return EXIT_FAILURE;
  }

  if (argc < 2)
  {
    fprintf(stderr, "yarac: wrong number of arguments\n");
    fprintf(stderr, "%s\n\n", USAGE_STRING);
    fprintf(stderr, "Try `--help` for more options\n");

    exit_with_code(EXIT_FAILURE);
  }

  result = yr_initialize();

  if (result != ERROR_SUCCESS)
    exit_with_code(EXIT_FAILURE);

  if (yr_compiler_create(&compiler) != ERROR_SUCCESS)
    exit_with_code(EXIT_FAILURE);

  if (!define_external_variables(compiler))
    exit_with_code(EXIT_FAILURE);

  yr_compiler_set_callback(compiler, report_error, NULL);

  for (int i = 0; i < argc - 1; i++)
  {
    const char* ns;
    const char* file_name;
    char* colon = (char*) strchr(argv[i], ':');

    if (colon)
    {
      file_name = colon + 1;
      *colon = '\0';
      ns = argv[i];
    }
    else
    {
      file_name = argv[i];
      ns = NULL;
    }

    FILE* rule_file = fopen(file_name, "r");

    if (rule_file != NULL)
    {
      int errors = yr_compiler_add_file(
          compiler, rule_file, ns, file_name);

      fclose(rule_file);

      if (errors) // errors during compilation
        exit_with_code(EXIT_FAILURE);
    }
    else
    {
      fprintf(stderr, "error: could not open file: %s\n", file_name);
    }
  }

  result = yr_compiler_get_rules(compiler, &rules);

  if (result != ERROR_SUCCESS)
  {
    fprintf(stderr, "error: %d\n", result);
    exit_with_code(EXIT_FAILURE);
  }

  result = yr_rules_save(rules, argv[argc - 1]);

  if (result != ERROR_SUCCESS)
  {
    fprintf(stderr, "error: %d\n", result);
    exit_with_code(EXIT_FAILURE);
  }

  result = EXIT_SUCCESS;

_exit:

  if (compiler != NULL)
    yr_compiler_destroy(compiler);

  if (rules != NULL)
    yr_rules_destroy(rules);

  yr_finalize();

  return result;
}
コード例 #8
0
ファイル: yara.c プロジェクト: kris-kaspersky/yara
int main(
    int argc,
    char const* argv[])
{
  YR_COMPILER* compiler;
  YR_RULES* rules;
  FILE* rule_file;
  EXTERNAL* external;

  int pid;
  int i;
  int errors;
  int result;

  THREAD thread[MAX_THREADS];

  if (!process_cmd_line(argc, argv))
    return EXIT_FAILURE;

  if (argc == 1 || optind == argc)
  {
    show_help();
    cleanup();
    return EXIT_FAILURE;
  }

  yr_initialize();

  result = yr_rules_load(argv[optind], &rules);

  if (result != ERROR_SUCCESS &&
      result != ERROR_INVALID_FILE)
  {
    print_scanner_error(result);
    yr_finalize();
    cleanup();
    return EXIT_FAILURE;
  }

  if (result == ERROR_SUCCESS)
  {
    external = externals_list;

    while (external != NULL)
    {
      switch (external->type)
      {
        case EXTERNAL_TYPE_INTEGER:
          yr_rules_define_integer_variable(
              rules,
              external->name,
              external->integer);
          break;

        case EXTERNAL_TYPE_BOOLEAN:
          yr_rules_define_boolean_variable(
              rules,
              external->name,
              external->boolean);
          break;

        case EXTERNAL_TYPE_STRING:
          yr_rules_define_string_variable(
              rules,
              external->name,
              external->string);
          break;
      }
      external = external->next;
    }
  }
  else
  {
    if (yr_compiler_create(&compiler) != ERROR_SUCCESS)
    {
      yr_finalize();
      cleanup();
      return EXIT_FAILURE;
    }

    external = externals_list;

    while (external != NULL)
    {
      switch (external->type)
      {
        case EXTERNAL_TYPE_INTEGER:
          yr_compiler_define_integer_variable(
              compiler,
              external->name,
              external->integer);
          break;

        case EXTERNAL_TYPE_BOOLEAN:
          yr_compiler_define_boolean_variable(
              compiler,
              external->name,
              external->boolean);
          break;

        case EXTERNAL_TYPE_STRING:
          yr_compiler_define_string_variable(
              compiler,
              external->name,
              external->string);
          break;
      }
      external = external->next;
    }

    yr_compiler_set_callback(compiler, print_compiler_error);

    rule_file = fopen(argv[optind], "r");

    if (rule_file == NULL)
    {
      fprintf(stderr, "could not open file: %s\n", argv[optind]);
      yr_compiler_destroy(compiler);
      yr_finalize();
      cleanup();
      return EXIT_FAILURE;
    }

    errors = yr_compiler_add_file(compiler, rule_file, NULL, argv[optind]);

    fclose(rule_file);

    if (errors > 0)
    {
      yr_compiler_destroy(compiler);
      yr_finalize();
      cleanup();
      return EXIT_FAILURE;
    }

    result = yr_compiler_get_rules(compiler, &rules);

    yr_compiler_destroy(compiler);

    if (result != ERROR_SUCCESS)
    {
      yr_finalize();
      cleanup();
      return EXIT_FAILURE;
    }
  }

  mutex_init(&output_mutex);

  if (is_numeric(argv[argc - 1]))
  {
    pid = atoi(argv[argc - 1]);
    result = yr_rules_scan_proc(
        rules,
        pid,
        callback,
        (void*) argv[argc - 1],
        fast_scan,
        timeout);

    if (result != ERROR_SUCCESS)
      print_scanner_error(result);
  }
  else if (is_directory(argv[argc - 1]))
  {
    if (file_queue_init() != 0)
      print_scanner_error(ERROR_INTERNAL_FATAL_ERROR);

    for (i = 0; i < threads; i++)
    {
      if (create_thread(&thread[i], scanning_thread, (void*) rules) != 0)
      {
        print_scanner_error(ERROR_COULD_NOT_CREATE_THREAD);
        return EXIT_FAILURE;
      }
    }

    scan_dir(
        argv[argc - 1],
        recursive_search,
        rules,
        callback);

    file_queue_finish();

    // Wait for scan threads to finish
    for (i = 0; i < threads; i++)
      thread_join(&thread[i]);

    file_queue_destroy();
  }
  else
  {
    result = yr_rules_scan_file(
        rules,
        argv[argc - 1],
        callback,
        (void*) argv[argc - 1],
        fast_scan,
        timeout);

    if (result != ERROR_SUCCESS)
    {
      fprintf(stderr, "Error scanning %s: ", argv[argc - 1]);
      print_scanner_error(result);
    }
  }

  #ifdef PROFILING_ENABLED
  yr_rules_print_profiling_info(rules);
  #endif

  yr_rules_destroy(rules);
  yr_finalize();

  mutex_destroy(&output_mutex);
  cleanup();

  return EXIT_SUCCESS;
}