From fc21585f6f95e93803fa6859ddc56ef2b3458c90 Mon Sep 17 00:00:00 2001 From: Alexey <30408771+delvinru@users.noreply.github.com> Date: Tue, 26 Sep 2023 00:39:05 +0300 Subject: [PATCH] procmon: fix fexecve handle (#1716) --- src/plugins/procmon/linux.cpp | 34 +++++++++++++++++++++++++++++++++- src/plugins/procmon/private.h | 3 +++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/plugins/procmon/linux.cpp b/src/plugins/procmon/linux.cpp index e5caa2dbd..e45700309 100644 --- a/src/plugins/procmon/linux.cpp +++ b/src/plugins/procmon/linux.cpp @@ -237,6 +237,33 @@ static std::map parse_environment(drakvuf_t drakvuf, d return envp_map; } +/* + * extract filename from arguments (do_execveat_common) + */ +static std::string get_filename_from_execve(drakvuf_t drakvuf, drakvuf_trap_info_t* info) +{ + auto vmi = vmi_lock_guard(drakvuf); + ACCESS_CONTEXT(ctx, + .translate_mechanism = VMI_TM_PROCESS_DTB, + .dtb = info->regs->cr3, + .addr = drakvuf_get_function_argument(drakvuf, info, 2) + ); + + addr_t addr; + if (VMI_FAILURE == vmi_read_addr(vmi, &ctx, &addr)) + return {}; + + ctx.addr = addr; + char* tmp = vmi_read_str(vmi, &ctx); + if (!tmp) + return {}; + + std::string filename(tmp); + g_free(tmp); + + return filename; +} + void linux_procmon::configure_filter(const procmon_config* cfg) { if (cfg->procmon_filter_file) @@ -331,6 +358,10 @@ event_response_t linux_procmon::do_open_execat_ret_cb(drakvuf_t drakvuf, drakvuf char* tmp = drakvuf_get_filepath_from_dentry(drakvuf, dentry_addr); params->image_path_name = tmp ?: ""; g_free(tmp); + + // some fexecve calls pass with the AT_FDCWD parameter, so handle it + if (params->image_path_name.empty()) + params->image_path_name = params->filename; } else PRINT_DEBUG("[PROCMON] Failed to read ImagePathName.\n"); @@ -341,7 +372,7 @@ event_response_t linux_procmon::do_open_execat_ret_cb(drakvuf_t drakvuf, drakvuf * based on the behavior of the kernel * source: https://elixir.bootlin.com/linux/v5.10.183/source/fs/exec.c#L1494 */ - params->image_path_name = "/dev/fd/" + std::to_string(params->fd); + params->image_path_name = "/proc/self/fd/" + std::to_string(params->fd); } } @@ -434,6 +465,7 @@ event_response_t linux_procmon::do_execveat_common_cb(drakvuf_t drakvuf, drakvuf auto params = libhook::GetTrapParams(hook->trap_); params->fd = drakvuf_get_function_argument(drakvuf, info, 1); + params->filename = get_filename_from_execve(drakvuf, info); params->pid = info->proc_data.pid; params->tid = info->proc_data.tid; // Save original process name diff --git a/src/plugins/procmon/private.h b/src/plugins/procmon/private.h index fa8c1fbd2..90cd3893f 100644 --- a/src/plugins/procmon/private.h +++ b/src/plugins/procmon/private.h @@ -121,6 +121,8 @@ struct execve_data : PluginResult , execat_rsp() , cr3() , fd() + , process_name() + , filename() , thread_name() , image_path_name() , command_line() @@ -138,6 +140,7 @@ struct execve_data : PluginResult int fd; std::string process_name; + std::string filename; std::string thread_name; std::string image_path_name; std::string command_line;