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);
}
예제 #2
0
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 );
	}
}
예제 #3
0
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;
}
예제 #4
0
void reserve( uintptr_t physical_addr )
{
	auto pool = find_pool( physical_addr );
	if( pool )
		pool->reserve( physical_addr );
}