YR_API int yr_rules_define_boolean_variable( YR_RULES* rules, const char* identifier, int value) { YR_EXTERNAL_VARIABLE* external; if (identifier == NULL) return ERROR_INVALID_ARGUMENT; external = rules->externals_list_head; while (!EXTERNAL_VARIABLE_IS_NULL(external)) { if (strcmp(external->identifier, identifier) == 0) { if (external->type != EXTERNAL_VARIABLE_TYPE_BOOLEAN) return ERROR_INVALID_EXTERNAL_VARIABLE_TYPE; external->value.i = value; return ERROR_SUCCESS; } external++; } return ERROR_INVALID_ARGUMENT; }
int yr_rules_define_string_variable( YR_RULES* rules, const char* identifier, const char* value) { YR_EXTERNAL_VARIABLE* external; external = rules->externals_list_head; while (!EXTERNAL_VARIABLE_IS_NULL(external)) { if (strcmp(external->identifier, identifier) == 0) { if (external->type == EXTERNAL_VARIABLE_TYPE_MALLOC_STRING && external->string != NULL) { yr_free(external->string); } external->type = EXTERNAL_VARIABLE_TYPE_MALLOC_STRING; external->string = yr_strdup(value); if (external->string == NULL) return ERROR_INSUFICIENT_MEMORY; else return ERROR_SUCCESS; } external++; } return ERROR_SUCCESS; }
int yr_rules_destroy( YR_RULES* rules) { YR_EXTERNAL_VARIABLE* external; external = rules->externals_list_head; while (!EXTERNAL_VARIABLE_IS_NULL(external)) { if (external->type == EXTERNAL_VARIABLE_TYPE_MALLOC_STRING) yr_free(external->string); external++; } #if WIN32 CloseHandle(rules->mutex); #else pthread_mutex_destroy(&rules->mutex); #endif yr_arena_destroy(rules->arena); yr_free(rules); return ERROR_SUCCESS; }
int yr_rules_define_boolean_variable( YR_RULES* rules, const char* identifier, int value) { YR_EXTERNAL_VARIABLE* external; external = rules->externals_list_head; while (!EXTERNAL_VARIABLE_IS_NULL(external)) { if (strcmp(external->identifier, identifier) == 0) { external->integer = value; break; } external++; } return ERROR_SUCCESS; }
int yr_rules_scan_mem_blocks( YR_RULES* rules, YR_MEMORY_BLOCK* block, int flags, YR_CALLBACK_FUNC callback, void* user_data, int timeout) { YR_SCAN_CONTEXT context; YR_RULE* rule; YR_OBJECT* object; YR_EXTERNAL_VARIABLE* external; YR_ARENA* matches_arena = NULL; time_t start_time; tidx_mask_t bit; int message; int tidx = 0; int result = ERROR_SUCCESS; if (block == NULL) return ERROR_SUCCESS; context.flags = flags; context.callback = callback; context.user_data = user_data; context.file_size = block->size; context.mem_block = block; context.entry_point = UNDEFINED; context.objects_table = NULL; _yr_rules_lock(rules); bit = 1; while (rules->tidx_mask & bit) { tidx++; bit <<= 1; } if (tidx < MAX_THREADS) rules->tidx_mask |= bit; else result = ERROR_TOO_MANY_SCAN_THREADS; _yr_rules_unlock(rules); if (result != ERROR_SUCCESS) return result; yr_set_tidx(tidx); result = yr_arena_create(1024, 0, &matches_arena); if (result != ERROR_SUCCESS) goto _exit; result = yr_hash_table_create(64, &context.objects_table); if (result != ERROR_SUCCESS) goto _exit; external = rules->externals_list_head; while (!EXTERNAL_VARIABLE_IS_NULL(external)) { result = yr_object_from_external_variable( external, &object); if (result == ERROR_SUCCESS) result = yr_hash_table_add( context.objects_table, external->identifier, NULL, (void*) object); if (result != ERROR_SUCCESS) goto _exit; external++; } start_time = time(NULL); while (block != NULL) { if (context.entry_point == UNDEFINED) { if (flags & SCAN_FLAGS_PROCESS_MEMORY) context.entry_point = yr_get_entry_point_address( block->data, block->size, block->base); else context.entry_point = yr_get_entry_point_offset( block->data, block->size); } result = yr_rules_scan_mem_block( rules, block, flags, timeout, start_time, matches_arena); if (result != ERROR_SUCCESS) goto _exit; block = block->next; } result = yr_execute_code( rules, &context, timeout, start_time); if (result != ERROR_SUCCESS) goto _exit; rule = rules->rules_list_head; while (!RULE_IS_NULL(rule)) { if (RULE_IS_GLOBAL(rule) && !(rule->t_flags[tidx] & RULE_TFLAGS_MATCH)) { rule->ns->t_flags[tidx] |= NAMESPACE_TFLAGS_UNSATISFIED_GLOBAL; } rule++; } rule = rules->rules_list_head; while (!RULE_IS_NULL(rule)) { if (rule->t_flags[tidx] & RULE_TFLAGS_MATCH && !(rule->ns->t_flags[tidx] & NAMESPACE_TFLAGS_UNSATISFIED_GLOBAL)) { message = CALLBACK_MSG_RULE_MATCHING; } else { message = CALLBACK_MSG_RULE_NOT_MATCHING; } if (!RULE_IS_PRIVATE(rule)) { switch (callback(message, rule, user_data)) { case CALLBACK_ABORT: result = ERROR_SUCCESS; goto _exit; case CALLBACK_ERROR: result = ERROR_CALLBACK_ERROR; goto _exit; } } rule++; } callback(CALLBACK_MSG_SCAN_FINISHED, NULL, user_data); _exit: yr_modules_unload_all(&context); _yr_rules_clean_matches(rules); if (matches_arena != NULL) yr_arena_destroy(matches_arena); if (context.objects_table != NULL) yr_hash_table_destroy( context.objects_table, (YR_HASH_TABLE_FREE_VALUE_FUNC) yr_object_destroy); _yr_rules_lock(rules); rules->tidx_mask &= ~(1 << tidx); _yr_rules_unlock(rules); yr_set_tidx(-1); return result; }