Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fileextractor: prepare for linux #1787

Merged
merged 1 commit into from
Apr 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/plugins/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ if PLUGIN_FILEEXTRACTOR
sources += fileextractor/fileextractor.cpp
sources += fileextractor/fileextractor.h
sources += fileextractor/private.h
sources += fileextractor/win.cpp
sources += fileextractor/win.h
endif

if PLUGIN_OBJMON
Expand Down
2,402 changes: 116 additions & 2,286 deletions src/plugins/fileextractor/fileextractor.cpp

Large diffs are not rendered by default.

165 changes: 5 additions & 160 deletions src/plugins/fileextractor/fileextractor.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,175 +105,20 @@
#ifndef FILEEXTRACTOR_H
#define FILEEXTRACTOR_H

#include "plugins/plugins.h"
#include "plugins/plugins_ex.h"
#include "helpers/exclude_matcher.h"
#include "private.h"
#include "win.h"

#include <map>
#include <utility>
#include <cstdint>
#include <memory>

using namespace fileextractor_ns;

struct fileextractor_config
{
uint32_t timeout;
const char* dump_folder;
uint64_t hash_size;
uint64_t extract_size;
const char* exclude_file;
};

class fileextractor: public pluginex
class fileextractor : public pluginex
{
public:
std::unique_ptr<win_fileextractor> wf;

fileextractor(drakvuf_t drakvuf, const fileextractor_config* config, output_format_t output);
fileextractor(const fileextractor&) = delete;
fileextractor& operator=(const fileextractor&) = delete;
~fileextractor() = default;

virtual bool stop_impl() override;

private:
enum class error
{
success,
none,
error,
zero_size,
};

/* Prevent injections on timeout after stop plugin begin. */
uint32_t timeout{0};
uint32_t begin_stop_at{0};
/* Internal data */
std::unordered_map<task_id, std::unique_ptr<task_t>> tasks;
bool is32bit{false};
// Maps virtual address of buffer to free flag:
// * `true` means pools is free;
// * `false` otherwise.
std::map<addr_t, bool> pools;

std::array<size_t, fileextractor_ns::__OFFSET_MAX> offsets;
size_t control_area_size = 0;
size_t mmpte_size = 0;

const char* dump_folder;
uint64_t hash_size{0};
uint64_t extract_size{0};
const exclude_matcher exclude;
output_format_t format;

int sequence_number = 0;

/* Hooks */
std::unique_ptr<libhook::SyscallHook> setinformation_hook;
std::unique_ptr<libhook::SyscallHook> writefile_hook;
std::unique_ptr<libhook::SyscallHook> close_hook;
std::unique_ptr<libhook::SyscallHook> createsection_hook;
std::unique_ptr<libhook::SyscallHook> createfile_hook;
std::unique_ptr<libhook::SyscallHook> openfile_hook;
std::map<uint64_t, std::unique_ptr<libhook::ReturnHook>> createfile_ret_hooks;
std::map<uint64_t, std::unique_ptr<libhook::ReturnHook>> writefile_ret_hooks;

/* VA of functions to be injected */
addr_t queryvolumeinfo_va = 0;
addr_t queryinfo_va = 0;
addr_t createsection_va = 0;
addr_t close_handle_va = 0;
addr_t mapview_va = 0;
addr_t unmapview_va = 0;
addr_t readfile_va = 0;
addr_t waitobject_va = 0;
addr_t exallocatepool_va = 0;
addr_t exfreepool_va = 0;
addr_t memcpy_va = 0;

/* Hook handlers */
event_response_t setinformation_cb(drakvuf_t, drakvuf_trap_info_t*);
event_response_t writefile_cb(drakvuf_t, drakvuf_trap_info_t*);
event_response_t writefile_ret_cb(drakvuf_t, drakvuf_trap_info_t*);
event_response_t close_cb(drakvuf_t, drakvuf_trap_info_t*);
event_response_t createsection_cb (drakvuf_t, drakvuf_trap_info_t*);
event_response_t createfile_cb (drakvuf_t, drakvuf_trap_info_t*);
event_response_t openfile_cb (drakvuf_t, drakvuf_trap_info_t*);
event_response_t createfile_ret_cb(drakvuf_t, drakvuf_trap_info_t*);
void createfile_cb_impl(drakvuf_t, drakvuf_trap_info_t*, addr_t handle, bool, bool);

/* Dispatchers */
// TODO Maybe remove "response" in flavor of "error"?
error dispatch_task(vmi_instance_t, drakvuf_trap_info_t*, task_t&);
error dispatch_pending(vmi_instance_t, drakvuf_trap_info_t*, task_t&);
error dispatch_queryvolumeinfo(vmi_instance_t, drakvuf_trap_info_t*, task_t&);
error dispatch_queryinfo(vmi_instance_t, drakvuf_trap_info_t*, task_t&);
error dispatch_createsection(vmi_instance_t, drakvuf_trap_info_t*, task_t&);
error dispatch_mapview(vmi_instance_t, drakvuf_trap_info_t*, task_t&);
error dispatch_allocate_pool(vmi_instance_t, drakvuf_trap_info_t*, task_t&);
error dispatch_memcpy(vmi_instance_t, drakvuf_trap_info_t*, task_t&);
error dispatch_unmapview(vmi_instance_t, drakvuf_trap_info_t*, task_t&);
error dispatch_close_handle(vmi_instance_t, drakvuf_trap_info_t*, task_t&);

/* Injection helpers */
bool inject_queryvolumeinfo(drakvuf_trap_info_t*, vmi_instance_t, task_t&);
bool inject_queryinfo(drakvuf_trap_info_t*, vmi_instance_t, task_t&);
bool inject_createsection(drakvuf_trap_info_t*, vmi_instance_t, task_t&);
bool inject_mapview(drakvuf_trap_info_t*, vmi_instance_t, task_t&);
bool inject_allocate_pool(drakvuf_trap_info_t*, vmi_instance_t, task_t&);
bool inject_memcpy(drakvuf_trap_info_t*, vmi_instance_t, task_t&);
bool inject_unmapview(drakvuf_trap_info_t*, vmi_instance_t, task_t&);
bool inject_close_handle(drakvuf_trap_info_t*, vmi_instance_t, task_t&);

/* Routines */
bool get_file_object_handle_count(drakvuf_trap_info_t*,
handle_t,
uint64_t* handle_count);

bool get_file_object_flags(drakvuf_trap_info_t*,
vmi_instance_t,
handle_t,
uint64_t* flags);
std::string get_file_name(vmi_instance_t,
drakvuf_trap_info_t*,
addr_t handle,
addr_t* out_file,
addr_t* out_filetype);
bool get_file_object_currentbyteoffset(vmi_instance_t, drakvuf_trap_info_t*, handle_t, uint64_t*);
bool get_write_offset(vmi_instance_t, drakvuf_trap_info_t*, addr_t, uint64_t*);
void calc_checksum(task_t&);
void save_file_metadata(drakvuf_trap_info_t*, addr_t control_area, task_t&);
void update_file_metadata(drakvuf_trap_info_t*, task_t&);
bool save_file_chunk(int file_sequence_number,
void* buffer,
size_t size);
bool save_file_chunk_rb(int file_sequence_number, uint64_t currentoffset,
void* buffer,
size_t size);
void dump_mem_to_file(uint64_t cr3, addr_t str, int idx, uint64_t offset, size_t size);
uint64_t make_hook_id(drakvuf_trap_info_t*);
uint64_t make_task_id(vmi_pid_t pid, handle_t handle);
uint64_t make_task_id(task_t&);
void free_pool(addr_t va);
addr_t find_pool();
void free_resources(drakvuf_trap_info_t*, task_t&);
void remove_task(drakvuf_trap_info_t*, task_t&,
const char* fail_msg = nullptr, bool restore_registers = true);
void read_vm(vmi_instance_t, drakvuf_trap_info_t*, task_t&);

bool is_handle_valid(handle_t);
void check_stack_marker(drakvuf_trap_info_t*, vmi_lock_guard&, task_t*);

void print_file_information(drakvuf_trap_info_t*, task_t&);
void print_plugin_close_information(drakvuf_trap_info_t*, task_t&);
void print_extraction_failure(drakvuf_trap_info_t* info, const std::string& filename, const std::string& message);
void print_extraction_exclusion(drakvuf_trap_info_t* info, const std::string& filename);

task_t* close_cb_get_task(drakvuf_trap_info_t*);
task_t* setinformation_cb_get_task(drakvuf_trap_info_t*);
task_t* writefile_cb_get_task(drakvuf_trap_info_t*);

void close_cb_handle_unextracted(drakvuf_trap_info_t*, task_t*);
void close_cb_handle_extracted(drakvuf_trap_info_t*, task_t*);
};

#endif
9 changes: 9 additions & 0 deletions src/plugins/fileextractor/private.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,15 @@

#include "../plugin_utils.h"

struct fileextractor_config
{
uint32_t timeout;
const char* dump_folder;
uint64_t hash_size;
uint64_t extract_size;
const char* exclude_file;
};

namespace fileextractor_ns
{
#define FILE_DISPOSITION_INFORMATION 13
Expand Down
Loading