int yr_ac_automaton_create( YR_AC_AUTOMATON** automaton) { YR_AC_AUTOMATON* new_automaton; YR_AC_STATE* root_state; new_automaton = (YR_AC_AUTOMATON*) yr_malloc(sizeof(YR_AC_AUTOMATON)); root_state = (YR_AC_STATE*) yr_malloc(sizeof(YR_AC_STATE)); if (new_automaton == NULL || root_state == NULL) { yr_free(new_automaton); yr_free(root_state); return ERROR_INSUFFICIENT_MEMORY; } root_state->depth = 0; root_state->matches = NULL; root_state->failure = NULL; root_state->first_child = NULL; root_state->siblings = NULL; root_state->t_table_slot = 0; new_automaton->root = root_state; new_automaton->m_table = NULL; new_automaton->t_table = NULL; new_automaton->tables_size = 0; *automaton = new_automaton; return ERROR_SUCCESS; }
YR_ARENA_PAGE* _yr_arena_new_page( size_t size) { YR_ARENA_PAGE* new_page; new_page = (YR_ARENA_PAGE*) yr_malloc(sizeof(YR_ARENA_PAGE)); if (new_page == NULL) return NULL; new_page->address = (uint8_t*) yr_malloc(size); if (new_page->address == NULL) { yr_free(new_page); return NULL; } new_page->size = size; new_page->used = 0; new_page->next = NULL; new_page->prev = NULL; new_page->reloc_list_head = NULL; new_page->reloc_list_tail = NULL; return new_page; }
YR_API int yr_hash_table_add_raw_key( YR_HASH_TABLE* table, const void* key, size_t key_length, const char* ns, void* value) { YR_HASH_TABLE_ENTRY* entry; uint32_t bucket_index; entry = (YR_HASH_TABLE_ENTRY*) yr_malloc(sizeof(YR_HASH_TABLE_ENTRY)); if (entry == NULL) return ERROR_INSUFICIENT_MEMORY; entry->key = yr_malloc(key_length); if (entry->key == NULL) { yr_free(entry); return ERROR_INSUFICIENT_MEMORY; } if (ns != NULL) { entry->ns = yr_strdup(ns); if (entry->ns == NULL) { yr_free(entry->key); yr_free(entry); return ERROR_INSUFICIENT_MEMORY; } } else { entry->ns = NULL; } entry->key_length = key_length; entry->value = value; memcpy(entry->key, key, key_length); bucket_index = hash(0, key, key_length); if (ns != NULL) bucket_index = hash(bucket_index, (uint8_t*) ns, strlen(ns)); bucket_index = bucket_index % table->size; entry->next = table->buckets[bucket_index]; table->buckets[bucket_index] = entry; return ERROR_SUCCESS; }
int new_string_identifier(int type, STRING* defined_strings, char* identifier, TERM_STRING** term) { TERM_STRING* new_term = NULL; STRING* string; int result = ERROR_SUCCESS; if (strcmp(identifier, "$") != 0) /* non-anonymous strings */ { string = lookup_string(defined_strings, identifier); if (string != NULL) { /* the string has been used in an expression, mark it as referenced */ string->flags |= STRING_FLAGS_REFERENCED; /* in these cases we can't not use the fast-matching mode */ if (type == TERM_TYPE_STRING_COUNT || type == TERM_TYPE_STRING_AT || type == TERM_TYPE_STRING_IN_RANGE || type == TERM_TYPE_STRING_OFFSET) { string->flags &= ~STRING_FLAGS_FAST_MATCH; } new_term = (TERM_STRING*) yr_malloc(sizeof(TERM_STRING)); if (new_term != NULL) { new_term->type = type; new_term->string = string; new_term->next = NULL; } } else { result = ERROR_UNDEFINED_STRING; } } else /* anonymous strings */ { new_term = (TERM_STRING*) yr_malloc(sizeof(TERM_STRING)); if (new_term != NULL) { new_term->type = type; new_term->string = NULL; new_term->next = NULL; } } *term = new_term; return result; }
RE_FIBER* _yr_re_fiber_create( RE_FIBER_LIST* fiber_pool) { RE_FIBER* fiber; if (fiber_pool->head != NULL) { fiber = fiber_pool->head; fiber_pool->head = fiber->next; if (fiber_pool->tail == fiber) fiber_pool->tail = NULL; } else { fiber = yr_malloc(sizeof(RE_FIBER)); } if (fiber != NULL) { fiber->ip = NULL; fiber->sp = -1; fiber->next = NULL; fiber->prev = NULL; } return fiber; }
uint8_t* _yr_fetch_block_data( YR_MEMORY_BLOCK* block) { YR_PROC_ITERATOR_CTX* context = (YR_PROC_ITERATOR_CTX*) block->context; if (context->buffer_size < block->size) { if (context->buffer != NULL) yr_free(context->buffer); context->buffer = yr_malloc(block->size); if (context->buffer != NULL) { context->buffer_size = block->size; } else { context->buffer_size = 0; return NULL; } } if (pread(context->mem_fd, context->buffer, block->size, block->base) == -1) { return NULL; } return context->buffer; }
int yr_arena_create( size_t initial_size, int flags, YR_ARENA** arena) { YR_ARENA* new_arena; YR_ARENA_PAGE* new_page; *arena = NULL; new_arena = (YR_ARENA*) yr_malloc(sizeof(YR_ARENA)); if (new_arena == NULL) return ERROR_INSUFFICIENT_MEMORY; new_page = _yr_arena_new_page(initial_size); if (new_page == NULL) { yr_free(new_arena); return ERROR_INSUFFICIENT_MEMORY; } new_arena->page_list_head = new_page; new_arena->current_page = new_page; new_arena->flags = flags | ARENA_FLAGS_COALESCED; *arena = new_arena; return ERROR_SUCCESS; }
int new_range(TERM* min, TERM* max, TERM_RANGE** term) { TERM_RANGE* new_term = NULL; int result = ERROR_SUCCESS; new_term = (TERM_RANGE*) yr_malloc(sizeof(TERM_RANGE)); if (new_term != NULL) { new_term->type = TERM_TYPE_RANGE; new_term->first = range_first; new_term->next = range_next; new_term->min = min; new_term->max = max; result = new_constant(0, &new_term->current); } else { result = ERROR_INSUFICIENT_MEMORY; } *term = new_term; return result; }
char* yr_strdup(const char *s) { size_t len = strlen(s); char *r = yr_malloc(len + 1); strcpy(r, s); return r; }
YR_API const uint8_t* yr_process_fetch_memory_block_data( YR_MEMORY_BLOCK* block) { YR_PROC_ITERATOR_CTX* context = (YR_PROC_ITERATOR_CTX*) block->context; YR_PROC_INFO* proc_info = (YR_PROC_INFO*) context->proc_info; if (context->buffer_size < block->size) { if (context->buffer != NULL) yr_free((void*) context->buffer); context->buffer = (const uint8_t*) yr_malloc(block->size); if (context->buffer != NULL) { context->buffer_size = block->size; } else { context->buffer_size = 0; return NULL; } } if (pread(proc_info->mem_fd, (void *) context->buffer, block->size, block->base) == -1) { return NULL; } return context->buffer; }
int new_variable(YARA_CONTEXT* context, char* identifier, TERM_VARIABLE** term) { TERM_VARIABLE* new_term = NULL; VARIABLE* variable; int result = ERROR_SUCCESS; variable = lookup_variable(context->variables, identifier); if (variable != NULL) /* external variable should be defined */ { new_term = (TERM_VARIABLE*) yr_malloc(sizeof(TERM_VARIABLE)); if (new_term != NULL) { new_term->type = TERM_TYPE_VARIABLE; new_term->variable = variable; } else { result = ERROR_INSUFICIENT_MEMORY; } } else { strncpy(context->last_error_extra_info, identifier, sizeof(context->last_error_extra_info)); context->last_error_extra_info[sizeof(context->last_error_extra_info)-1] = 0; result = ERROR_UNDEFINED_IDENTIFIER; } *term = new_term; return result; }
int _yr_re_alloc_storage( RE_THREAD_STORAGE** storage) { #ifdef _WIN32 *storage = (RE_THREAD_STORAGE*) TlsGetValue(thread_storage_key); #else *storage = (RE_THREAD_STORAGE*) pthread_getspecific(thread_storage_key); #endif if (*storage == NULL) { *storage = (RE_THREAD_STORAGE*) yr_malloc(sizeof(RE_THREAD_STORAGE)); if (*storage == NULL) return ERROR_INSUFICIENT_MEMORY; (*storage)->fiber_pool.head = NULL; (*storage)->fiber_pool.tail = NULL; #ifdef _WIN32 TlsSetValue(thread_storage_key, *storage); #else pthread_setspecific(thread_storage_key, *storage); #endif } return ERROR_SUCCESS; }
static int _yr_atoms_case_insensitive( YR_ATOM_LIST_ITEM* atoms, YR_ATOM_LIST_ITEM** case_insensitive_atoms) { YR_ATOM_LIST_ITEM* atom; YR_ATOM_LIST_ITEM* new_atom; uint8_t buffer[CASE_COMBINATIONS_BUFFER_SIZE]; uint8_t atom_length; uint8_t* atoms_cursor; int i; *case_insensitive_atoms = NULL; atom = atoms; while (atom != NULL) { _yr_atoms_case_combinations( atom->atom.bytes, atom->atom.length, 0, buffer); atoms_cursor = buffer; atom_length = *atoms_cursor; atoms_cursor++; while (atom_length != 0) { new_atom = (YR_ATOM_LIST_ITEM*) yr_malloc(sizeof(YR_ATOM_LIST_ITEM)); if (new_atom == NULL) return ERROR_INSUFFICIENT_MEMORY; for (i = 0; i < atom_length; i++) { new_atom->atom.bytes[i] = atoms_cursor[i]; new_atom->atom.mask[i] = 0xFF; } new_atom->atom.length = atom_length; new_atom->forward_code = atom->forward_code; new_atom->backward_code = atom->backward_code; new_atom->backtrack = atom->backtrack; new_atom->next = *case_insensitive_atoms; *case_insensitive_atoms = new_atom; atoms_cursor += atom_length; atom_length = *atoms_cursor; atoms_cursor++; } atom = atom->next; } return ERROR_SUCCESS; }
char* yr_strdup(const char *str) { size_t len = strlen(str) + 1; void *dup = yr_malloc(len); if (dup != NULL) memcpy(dup, str, len); return (char*) dup; }
SIZED_STRING* yr_re_extract_literal( RE* re) { SIZED_STRING* string; RE_NODE* node = re->root_node; int i, length = 0; char tmp; while (node != NULL) { length++; if (node->type == RE_NODE_LITERAL) break; if (node->type != RE_NODE_CONCAT) return NULL; if (node->right == NULL || node->right->type != RE_NODE_LITERAL) return NULL; node = node->left; } string = (SIZED_STRING*) yr_malloc(sizeof(SIZED_STRING) + length); if (string == NULL) return NULL; string->length = 0; node = re->root_node; while (node->type == RE_NODE_CONCAT) { string->c_string[string->length++] = node->right->value; node = node->left; } string->c_string[string->length++] = node->value; // The string ends up reversed. Reverse it back to its original value. for (i = 0; i < length / 2; i++) { tmp = string->c_string[i]; string->c_string[i] = string->c_string[length - i - 1]; string->c_string[length - i - 1] = tmp; } return string; }
char* yr_strdup(const char *str) { size_t len = strlen(str); void *dup = yr_malloc(len + 1); if (dup == NULL) return NULL; memcpy(dup, str, len); dup[len] = '\0'; return (char*) dup; }
char* yr_strndup(const char *str, size_t n) { size_t len = strnlen(str, n); char *dup = (char*) yr_malloc(len + 1); if (dup == NULL) return NULL; memcpy(dup, str, len); dup[len] = '\0'; return (char *) dup; }
static YR_ATOM_LIST_ITEM* _yr_atoms_clone_list_item( YR_ATOM_LIST_ITEM* item) { YR_ATOM_LIST_ITEM* clone = (YR_ATOM_LIST_ITEM*) yr_malloc( sizeof(YR_ATOM_LIST_ITEM)); if (clone == NULL) return NULL; memcpy(clone, item, sizeof(YR_ATOM_LIST_ITEM)); return clone; }
int _yr_process_attach( int pid, YR_PROC_ITERATOR_CTX* context) { TOKEN_PRIVILEGES tokenPriv; LUID luidDebug; HANDLE hToken = NULL; YR_PROC_INFO* proc_info = (YR_PROC_INFO*) yr_malloc(sizeof(YR_PROC_INFO)); if (proc_info == NULL) return ERROR_INSUFFICIENT_MEMORY; if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken) && LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luidDebug)) { tokenPriv.PrivilegeCount = 1; tokenPriv.Privileges[0].Luid = luidDebug; tokenPriv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; AdjustTokenPrivileges( hToken, FALSE, &tokenPriv, sizeof(tokenPriv), NULL, NULL); } if (hToken != NULL) CloseHandle(hToken); proc_info->hProcess = OpenProcess( PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, FALSE, pid); if (proc_info->hProcess == NULL) { yr_free(proc_info); return ERROR_COULD_NOT_ATTACH_TO_PROCESS; } GetSystemInfo(&proc_info->si); context->proc_info = proc_info; return ERROR_SUCCESS; }
int yr_re_create( RE** re) { *re = (RE*) yr_malloc(sizeof(RE)); if (*re == NULL) return ERROR_INSUFICIENT_MEMORY; (*re)->flags = 0; (*re)->root_node = NULL; (*re)->error_message = NULL; (*re)->error_code = ERROR_SUCCESS; return ERROR_SUCCESS; }
ATOM_TREE_NODE* _yr_atoms_tree_node_create( uint8_t type) { ATOM_TREE_NODE* new_node; new_node = (ATOM_TREE_NODE*) yr_malloc(sizeof(ATOM_TREE_NODE)); new_node->type = type; new_node->atom_length = 0; new_node->next_sibling = NULL; new_node->children_head = NULL; new_node->children_tail = NULL; new_node->forward_code = NULL; new_node->backward_code = NULL; return new_node; }
int yr_rules_load( const char* filename, YR_RULES** rules) { YR_RULES* new_rules; YARA_RULES_FILE_HEADER* header; YR_RULE* rule; int result; new_rules = yr_malloc(sizeof(YR_RULES)); if (new_rules == NULL) return ERROR_INSUFICIENT_MEMORY; result = yr_arena_load(filename, &new_rules->arena); if (result != ERROR_SUCCESS) { yr_free(new_rules); return result; } header = (YARA_RULES_FILE_HEADER*) yr_arena_base_address(new_rules->arena); new_rules->automaton = header->automaton; new_rules->code_start = header->code_start; new_rules->externals_list_head = header->externals_list_head; new_rules->rules_list_head = header->rules_list_head; new_rules->tidx_mask = 0; #if WIN32 new_rules->mutex = CreateMutex(NULL, FALSE, NULL); if (new_rules->mutex == NULL) return ERROR_INTERNAL_FATAL_ERROR; #else result = pthread_mutex_init(&new_rules->mutex, NULL); if (result != 0) return ERROR_INTERNAL_FATAL_ERROR; #endif rule = new_rules->rules_list_head; *rules = new_rules; return ERROR_SUCCESS; }
static int _yr_atoms_wide( YR_ATOM_LIST_ITEM* atoms, YR_ATOM_LIST_ITEM** wide_atoms) { YR_ATOM_LIST_ITEM* atom; YR_ATOM_LIST_ITEM* new_atom; int i; *wide_atoms = NULL; atom = atoms; while (atom != NULL) { new_atom = (YR_ATOM_LIST_ITEM*) yr_malloc(sizeof(YR_ATOM_LIST_ITEM)); if (new_atom == NULL) return ERROR_INSUFFICIENT_MEMORY; for (i = 0; i < YR_MAX_ATOM_LENGTH; i++) { new_atom->atom.bytes[i] = 0; new_atom->atom.mask[i] = 0xFF; } for (i = 0; i < atom->atom.length; i++) { if (i * 2 < YR_MAX_ATOM_LENGTH) new_atom->atom.bytes[i * 2] = atom->atom.bytes[i]; else break; } new_atom->atom.length = yr_min(atom->atom.length * 2, YR_MAX_ATOM_LENGTH); new_atom->forward_code = atom->forward_code; new_atom->backward_code = atom->backward_code; new_atom->backtrack = atom->backtrack * 2; new_atom->next = *wide_atoms; *wide_atoms = new_atom; atom = atom->next; } return ERROR_SUCCESS; }
static YR_ATOM_TREE_NODE* _yr_atoms_tree_node_create( uint8_t type) { YR_ATOM_TREE_NODE* new_node = (YR_ATOM_TREE_NODE*) \ yr_malloc(sizeof(YR_ATOM_TREE_NODE)); if (new_node != NULL) { new_node->type = type; new_node->atom.length = 0; new_node->next_sibling = NULL; new_node->children_head = NULL; new_node->children_tail = NULL; } return new_node; }
int new_text_string( YARA_CONTEXT* context, SIZED_STRING* charstr, int flags, unsigned char** hexstr, REGEXP* re, unsigned int* length) { char *error; int erroffset; int options; int result = ERROR_SUCCESS; //assert(charstr && hexstr && regexp && length); *length = charstr->length; *hexstr = yr_malloc(charstr->length); if (*hexstr == NULL) { return ERROR_INSUFICIENT_MEMORY; } memcpy(*hexstr, charstr->c_string, charstr->length); if (flags & STRING_FLAGS_REGEXP) { if (regex_compile(re, // REGEXP * charstr->c_string, // Regex pattern flags & STRING_FLAGS_NO_CASE, // If TRUE then case insensitive search context->last_error_extra_info, // Error message sizeof(context->last_error_extra_info), // Size of error buffer &erroffset) <= 0) // Offset into regex pattern if error detected { result = ERROR_INVALID_REGULAR_EXPRESSION; } } else { // re contains multiple pointers now, if we're // not doing a regex, make sure all are NULL. memset(re, '\0', sizeof(REGEXP)); } return result; }
int _yr_arena_make_relocatable( YR_ARENA* arena, void* base, va_list offsets) { YR_RELOC* reloc; YR_ARENA_PAGE* page; size_t offset; size_t base_offset; int result = ERROR_SUCCESS; page = _yr_arena_page_for_address(arena, base); assert(page != NULL); base_offset = (uint8_t*) base - page->address; offset = va_arg(offsets, size_t); while (offset != -1) { assert(page->used >= sizeof(int64_t)); assert(base_offset + offset <= page->used - sizeof(int64_t)); reloc = (YR_RELOC*) yr_malloc(sizeof(YR_RELOC)); if (reloc == NULL) return ERROR_INSUFFICIENT_MEMORY; reloc->offset = (uint32_t) (base_offset + offset); reloc->next = NULL; if (page->reloc_list_head == NULL) page->reloc_list_head = reloc; if (page->reloc_list_tail != NULL) page->reloc_list_tail->next = reloc; page->reloc_list_tail = reloc; offset = va_arg(offsets, size_t); } return result; }
int new_string( YARA_CONTEXT* context, char* identifier, SIZED_STRING* charstr, int flags, STRING** string) { STRING* new_string; int result = ERROR_SUCCESS; new_string = (STRING*) yr_malloc(sizeof(STRING)); if(new_string != NULL) { if (!(flags & STRING_FLAGS_WIDE)) flags |= STRING_FLAGS_ASCII; new_string->identifier = identifier; new_string->flags = flags; new_string->next = NULL; new_string->matches_head = NULL; new_string->matches_tail = NULL; if (flags & STRING_FLAGS_HEXADECIMAL) { result = new_hex_string(context, charstr, &new_string->string, &new_string->mask, &new_string->length); } else { result = new_text_string(context, charstr, flags, &new_string->string, &new_string->re, &new_string->length); } if (result != ERROR_SUCCESS) { yr_free(new_string); new_string = NULL; } } else { result = ERROR_INSUFICIENT_MEMORY; } *string = new_string; return result; }
RE_NODE* yr_re_node_create( int type, RE_NODE* left, RE_NODE* right) { RE_NODE* result = yr_malloc(sizeof(RE_NODE)); if (result != NULL) { result->type = type; result->left = left; result->right = right; result->greedy = TRUE; result->forward_code = NULL; result->backward_code = NULL; } return result; }
int new_simple_term(int type, TERM** term) { TERM* new_term; int result = ERROR_SUCCESS; new_term = (TERM*) yr_malloc(sizeof(TERM)); if (new_term != NULL) { new_term->type = type; } else { result = ERROR_INSUFICIENT_MEMORY; } *term = new_term; return result; }
int yr_atoms_extract_from_re( YR_ATOMS_CONFIG* config, RE_AST* re_ast, int flags, YR_ATOM_LIST_ITEM** atoms, int* min_atom_quality) { YR_ATOM_TREE* atom_tree = (YR_ATOM_TREE*) yr_malloc(sizeof(YR_ATOM_TREE)); YR_ATOM_LIST_ITEM* wide_atoms; YR_ATOM_LIST_ITEM* case_insensitive_atoms; if (atom_tree == NULL) return ERROR_INSUFFICIENT_MEMORY; atom_tree->root_node = _yr_atoms_tree_node_create(ATOM_TREE_OR); if (atom_tree->root_node == NULL) { _yr_atoms_tree_destroy(atom_tree); return ERROR_INSUFFICIENT_MEMORY; } FAIL_ON_ERROR_WITH_CLEANUP( _yr_atoms_extract_from_re(config, re_ast, atom_tree->root_node), _yr_atoms_tree_destroy(atom_tree)); // Initialize atom list *atoms = NULL; // Choose the atoms that will be used. FAIL_ON_ERROR_WITH_CLEANUP( _yr_atoms_choose(config, atom_tree->root_node, atoms, min_atom_quality), _yr_atoms_tree_destroy(atom_tree)); _yr_atoms_tree_destroy(atom_tree); FAIL_ON_ERROR_WITH_CLEANUP( _yr_atoms_expand_wildcards(*atoms), { yr_atoms_list_destroy(*atoms); *atoms = NULL; });