/* * NTSTATUS ZwSetInformationFile( * HANDLE FileHandle, * PIO_STATUS_BLOCK IoStatusBlock, * PVOID FileInformation, * ULONG Length, * FILE_INFORMATION_CLASS FileInformationClass * ); * * When FileInformationClass is FileDispositionInformation then FileInformation points to * struct _FILE_DISPOSITION_INFORMATION { * BOOLEAN DeleteFile; * } */ static event_response_t setinformation_cb(drakvuf_t drakvuf, drakvuf_trap_info_t* info) { filedelete* f = (filedelete*)info->trap->data; vmi_instance_t vmi = drakvuf_lock_and_get_vmi(drakvuf); addr_t handle = drakvuf_get_function_argument(drakvuf, info, 1); addr_t fileinfo = drakvuf_get_function_argument(drakvuf, info, 3); uint32_t fileinfoclass = drakvuf_get_function_argument(drakvuf, info, 5); event_response_t response = 0; if (fileinfoclass == FILE_DISPOSITION_INFORMATION) { uint8_t del = 0; access_context_t ctx; ctx.translate_mechanism = VMI_TM_PROCESS_DTB; ctx.dtb = info->regs->cr3; ctx.addr = fileinfo; if ( VMI_FAILURE == vmi_read_8(vmi, &ctx, &del) ) goto done; if (del) { auto filename = get_file_name(f, drakvuf, vmi, info, handle, nullptr, nullptr); if (filename.empty()) filename = "<UNKNOWN>"; f->files[std::make_pair(info->proc_data.pid, handle)] = filename; } } done: drakvuf_release_vmi(drakvuf); return response; }
static std::string get_file_name(filedelete* f, drakvuf_t drakvuf, vmi_instance_t vmi, drakvuf_trap_info_t* info, addr_t handle, addr_t* out_file, addr_t* out_filetype) { // TODO: verify that the dtb in the _EPROCESS is the same as the cr3? if (!info->proc_data.base_addr) return {}; addr_t obj = drakvuf_get_obj_by_handle(drakvuf, info->proc_data.base_addr, handle); if (!obj) return {}; addr_t file = obj + f->offsets[OBJECT_HEADER_BODY]; addr_t filename = file + f->offsets[FILE_OBJECT_FILENAME]; addr_t filetype = file + f->offsets[FILE_OBJECT_TYPE]; if (out_file) *out_file = file; if (out_filetype) *out_filetype = filetype; access_context_t ctx; ctx.translate_mechanism = VMI_TM_PROCESS_DTB; ctx.addr = filetype; ctx.dtb = info->regs->cr3; uint8_t type = 0; if (VMI_FAILURE == vmi_read_8(vmi, &ctx, &type)) return {}; if (type != 5) return {}; unicode_string_t* filename_us = drakvuf_read_unicode(drakvuf, info, filename); if (!filename_us) return {}; std::string ret = {(const char*)filename_us->contents}; vmi_free_unicode_str(filename_us); return ret; }
bool drakvuf_is_eprocess( drakvuf_t drakvuf, addr_t dtb, addr_t eprocess_addr ) { dispatcher_object_t dispatcher_type = 0; access_context_t ctx = { .translate_mechanism = VMI_TM_PROCESS_DTB, .dtb = dtb, }; ctx.addr = eprocess_addr + drakvuf->offsets[ EPROCESS_PCB ] + drakvuf->offsets[ KPROCESS_HEADER ] + drakvuf->offsets[ DISPATCHER_TYPE ] ; if ( vmi_read_8( drakvuf->vmi, &ctx, (uint8_t *)&dispatcher_type ) == VMI_SUCCESS ) { if ( dispatcher_type == DISPATCHER_PROCESS_OBJECT ) return true ; } return false ; }