void concurrent_growable_pool::deallocate(void* pointer) { concurrent_pool* pool = find_pool(pointer); if (!pool) throw std::exception("deallocate called on a dangling pointer from a chunk that has probably been shrink()'ed"); last_deallocate = pool; // racy but only an optimization hint pool->deallocate(pointer); }
void mm::physical::free( uintptr_t physical_addr, unsigned int pages ) { for( unsigned int i = 0; i < pages; ++i ) { uintptr_t addr = physical_addr + i * PAGE_SIZE; auto pool = find_pool( addr ); if( pool ) pool->free( addr ); } }
event_response_t queryobject_cb(drakvuf_t drakvuf, drakvuf_trap_info_t* info) { wrapper_t* injector = (wrapper_t*)info->trap->data; auto response = 0; uint32_t thread_id = 0; if (info->regs->cr3 != injector->target_cr3) return 0; if ( !drakvuf_get_current_thread_id(drakvuf, info, &thread_id) || !injector->target_thread_id || thread_id != injector->target_thread_id ) return 0; vmi_instance_t vmi = drakvuf_lock_and_get_vmi(drakvuf); if (info->regs->rax) goto handled; else { access_context_t ctx = { .translate_mechanism = VMI_TM_PROCESS_DTB, .dtb = info->regs->cr3, .addr = injector->ntqueryobject_info.out, }; struct FILE_FS_DEVICE_INFORMATION dev_info = { 0 }; if ((VMI_FAILURE == vmi_read(vmi, &ctx, sizeof(struct FILE_FS_DEVICE_INFORMATION), &dev_info, NULL))) { PRINT_DEBUG("[FILEDELETE2] [QueryObject] Failed to read FsDeviceInformation\n"); goto err; } if (7 != dev_info.device_type) // FILE_DEVICE_DISK goto handled; injector->ntreadfile_info.bytes_read = 0UL; addr_t pool = find_pool(injector->f->pools); if (!pool) { if (inject_allocate_pool(drakvuf, info, vmi, injector)) { response = VMI_EVENT_RESPONSE_SET_REGISTERS; goto done; } } else { injector->pool = pool; if (inject_readfile(drakvuf, info, vmi, injector)) { response = VMI_EVENT_RESPONSE_SET_REGISTERS; goto done; } } } err: PRINT_DEBUG("[FILEDELETE2] [QueryObject] Error. Stop processing (CR3 0x%lx, TID %d).\n", info->regs->cr3, thread_id); handled: response = finish_readfile(drakvuf, info, vmi, false); done: drakvuf_release_vmi(drakvuf); return response; } /* * Drakvuf must be locked/unlocked in the caller */ static bool start_readfile(drakvuf_t drakvuf, drakvuf_trap_info_t* info, vmi_instance_t vmi, handle_t handle, const char* filename, event_response_t* response) { *response = VMI_EVENT_RESPONSE_NONE; filedelete* f = (filedelete*)info->trap->data; uint64_t fo_flags = 0; if (!get_file_object_flags(drakvuf, info, vmi, f, handle, &fo_flags)) return 0; bool is_synchronous = (fo_flags & FO_SYNCHRONOUS_IO); if (!is_synchronous) return 0; if ( 0 == info->proc_data.base_addr ) { PRINT_DEBUG("[FILEDELETE2] Failed to get process base on vCPU 0x%d\n", info->vcpu); return 0; } uint32_t target_thread_id = 0; if ( !drakvuf_get_current_thread_id(drakvuf, info, &target_thread_id) || !target_thread_id ) { PRINT_DEBUG("[FILEDELETE2] Failed to get Thread ID\n"); return 0; } /* * Check if process/thread is being processed. If so skip it. Add it into * regestry otherwise. */ auto thread = std::make_pair(info->regs->cr3, target_thread_id); auto thread_it = f->closing_handles.find(thread); auto map_end = f->closing_handles.end(); if (map_end != thread_it) { bool handled = thread_it->second; if (handled) { f->files.erase(std::make_pair(info->proc_data.pid, handle)); f->closing_handles.erase(thread); } return 0; } else f->closing_handles[thread] = false; /* * Real function body. * * Now we are sure this is new call to NtClose (not result of function injection) and * the Handle have been modified in NtWriteFile. So we should save it on the host. */ wrapper_t* injector = (wrapper_t*)g_malloc0(sizeof(wrapper_t)); if (!injector) return 0; injector->bp = (drakvuf_trap_t*)g_malloc0(sizeof(drakvuf_trap_t)); if (!injector->bp) { g_free(injector); return 0; } injector->f = f; injector->bp->name = info->trap->name; injector->handle = handle; injector->fo_flags = fo_flags; injector->is32bit = (f->pm != VMI_PM_IA32E); injector->target_cr3 = info->regs->cr3; injector->curr_sequence_number = -1; injector->eprocess_base = info->proc_data.base_addr; injector->target_thread_id = target_thread_id; memcpy(&injector->saved_regs, info->regs, sizeof(x86_registers_t)); if (inject_queryobject(drakvuf, info, vmi, injector)) { *response = VMI_EVENT_RESPONSE_SET_REGISTERS; return 1; } memcpy(info->regs, &injector->saved_regs, sizeof(x86_registers_t)); return 0; }
void reserve( uintptr_t physical_addr ) { auto pool = find_pool( physical_addr ); if( pool ) pool->reserve( physical_addr ); }