Skip to content

Commit e92e096

Browse files
committed
allow parsers to modify original fmt args. add linux parsers
1 parent db5bb94 commit e92e096

File tree

5 files changed

+76
-13
lines changed

5 files changed

+76
-13
lines changed

src/plugins/syscalls/linux.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,47 @@ bool linux_syscalls::trap_syscall_table_entries(drakvuf_t drakvuf)
402402
return check;
403403
}
404404

405+
void linux_syscalls::register_parsers()
406+
{
407+
syscalls_base::register_parsers();
408+
409+
m_type_parsers[linux_intmask_prot_]= [this](
410+
syscalls_base* base, fmt_args_t& original_args, fmt_args_t& extra_args, const syscalls_ns::syscall_t* sc,
411+
const syscalls_ns::arg_t& arg, drakvuf_trap_info_t* info, uint64_t value,
412+
const std::vector<uint64_t>& all_args)
413+
{
414+
if (value == 0)
415+
{
416+
find_replace_arg(original_args, std::string(arg.name), fmt::Qstr("PROT_NONE"));
417+
}
418+
else
419+
{
420+
find_replace_arg(original_args, std::string(arg.name), fmt::Qstr(parse_flags(value, mmap_prot, m_output_format)));
421+
}
422+
};
423+
424+
m_type_parsers[linux_intopt_pr_]= [](
425+
syscalls_base* base, fmt_args_t& original_args, fmt_args_t& extra_args, const syscalls_ns::syscall_t* sc,
426+
const syscalls_ns::arg_t& arg, drakvuf_trap_info_t* info, uint64_t value,
427+
const std::vector<uint64_t>& all_args)
428+
{
429+
if (prctl_option.find(value) != prctl_option.end())
430+
{
431+
find_replace_arg(original_args, std::string(arg.name), fmt::Qstr(prctl_option.at(value)));
432+
}
433+
};
434+
435+
m_type_parsers[linux_intopt_arch_]= [](
436+
syscalls_base* base, fmt_args_t& original_args, fmt_args_t& extra_args, const syscalls_ns::syscall_t* sc,
437+
const syscalls_ns::arg_t& arg, drakvuf_trap_info_t* info, uint64_t value,
438+
const std::vector<uint64_t>& all_args)
439+
{
440+
if (arch_prctl_code.find(value) != arch_prctl_code.end())
441+
{
442+
find_replace_arg(original_args, std::string(arg.name), fmt::Qstr(arch_prctl_code.at(value)));
443+
}
444+
};
445+
}
405446

406447
linux_syscalls::linux_syscalls(drakvuf_t drakvuf, const syscalls_config* config, output_format_t output) : syscalls_base(drakvuf, config, output)
407448
{
@@ -413,4 +454,6 @@ linux_syscalls::linux_syscalls(drakvuf_t drakvuf, const syscalls_config* config,
413454

414455
if (!this->trap_syscall_table_entries(drakvuf))
415456
PRINT_DEBUG("[SYSCALLS] Failed to set breakpoints on some syscalls.\n");
457+
458+
register_parsers();
416459
}

src/plugins/syscalls/linux.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,9 @@ class linux_syscalls : public syscalls_base
130130
bool trap_syscall_table_entries(drakvuf_t drakvuf);
131131

132132
linux_syscalls(drakvuf_t drakvuf, const syscalls_config* config, output_format_t output);
133+
134+
protected:
135+
void register_parsers() override;
133136
};
134137
namespace syscalls_ns
135138
{

src/plugins/syscalls/private_2.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ class syscalls_base : public pluginex
144144

145145
using arg_parser_t = std::function<void(
146146
syscalls_base* base,
147+
fmt_args_t& original_args,
147148
fmt_args_t& extra_args,
148149
const syscalls_ns::syscall_t* sc,
149150
const syscalls_ns::arg_t& arg_to_parse,
@@ -155,6 +156,7 @@ class syscalls_base : public pluginex
155156
void print_sysret(drakvuf_t drakvuf, drakvuf_trap_info_t* info, int nr, const char* extra_info = nullptr);
156157
uint64_t value_from_uint64(syscalls_ns::arg_type_t type, uint64_t val);
157158
bool read_syscalls_list(const char* syscall_list_file);
159+
static void find_replace_arg(std::vector<std::pair<std::string, fmt::Aarg>>& vec, const std::string& key, const fmt::Aarg& newValue);
158160

159161
static std::optional<uint64_t> get_arg_value_by_name(
160162
const syscalls_ns::syscall_t* sc,

src/plugins/syscalls/syscalls.cpp

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ void syscalls_base::fill_fmt_args(
214214

215215
if (parser)
216216
{
217-
parser(this, extra_args, sc, arg_to_parse, info, value_to_parse, args);
217+
parser(this, original_args, extra_args, sc, arg_to_parse, info, value_to_parse, args);
218218
}
219219
else if (dereferenced_value)
220220
{
@@ -249,6 +249,21 @@ static std::string rstrip(std::string s)
249249
return s;
250250
}
251251

252+
void syscalls_base::find_replace_arg(std::vector<std::pair<std::string, fmt::Aarg>>& vec, const std::string& key, const fmt::Aarg& newValue)
253+
{
254+
auto it = std::find_if(vec.begin(), vec.end(),
255+
[&key](const std::pair<std::string, fmt::Aarg>& element)
256+
{
257+
return element.first == key;
258+
}
259+
);
260+
261+
if (it != vec.end())
262+
{
263+
it->second = newValue;
264+
}
265+
}
266+
252267
bool syscalls_base::read_syscalls_list(const char* syscall_list_file)
253268
{
254269
std::ifstream file(syscall_list_file);
@@ -285,7 +300,7 @@ bool syscalls_base::read_syscalls_list(const char* syscall_list_file)
285300
void syscalls_base::register_parsers()
286301
{
287302
auto ascii_string_parser = [](
288-
syscalls_base* base, fmt_args_t& extra_args, const syscalls_ns::syscall_t* sc,
303+
syscalls_base* base, fmt_args_t& original_args, fmt_args_t& extra_args, const syscalls_ns::syscall_t* sc,
289304
const syscalls_ns::arg_t& arg, drakvuf_trap_info_t* info, uint64_t value,
290305
const std::vector<uint64_t>& all_args)
291306
{
@@ -294,7 +309,7 @@ void syscalls_base::register_parsers()
294309
char* cstr = drakvuf_read_ascii_str(base->drakvuf, info, value);
295310
if (cstr)
296311
{
297-
extra_args.push_back(keyval(std::string(arg.name), fmt::Estr(std::string(cstr))));
312+
find_replace_arg(original_args, std::string(arg.name), fmt::Estr(std::string(cstr)));
298313
g_free(cstr);
299314
}
300315
};

src/plugins/syscalls/win.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -869,7 +869,7 @@ void win_syscalls::register_parsers()
869869

870870
// name based parsers
871871
m_name_parsers["ProcessHandle"] = [](
872-
syscalls_base* base, fmt_args_t& extra_args, const syscalls_ns::syscall_t* sc,
872+
syscalls_base* base, fmt_args_t& original_args, fmt_args_t& extra_args, const syscalls_ns::syscall_t* sc,
873873
const syscalls_ns::arg_t& arg, drakvuf_trap_info_t* info, uint64_t value,
874874
const std::vector<uint64_t>& all_args)
875875
{
@@ -897,7 +897,7 @@ void win_syscalls::register_parsers()
897897
};
898898

899899
m_name_parsers["ThreadHandle"] = [](
900-
syscalls_base* base, fmt_args_t& extra_args, const syscalls_ns::syscall_t* sc,
900+
syscalls_base* base, fmt_args_t& original_args, fmt_args_t& extra_args, const syscalls_ns::syscall_t* sc,
901901
const syscalls_ns::arg_t& arg, drakvuf_trap_info_t* info, uint64_t value,
902902
const std::vector<uint64_t>& all_args)
903903
{
@@ -929,48 +929,48 @@ void win_syscalls::register_parsers()
929929
};
930930

931931
m_name_parsers["FileHandle"] = [](
932-
syscalls_base* base, fmt_args_t& extra_args, const auto* sc,
932+
syscalls_base* base, fmt_args_t& original_args, fmt_args_t& extra_args, const auto* sc,
933933
const auto& arg, auto* info, uint64_t value, const auto& all_args)
934934
{
935935
if (value == 0) return;
936936
char* cstr = drakvuf_get_filename_from_handle(base->drakvuf, info, value);
937937
if (cstr)
938938
{
939-
extra_args.push_back(keyval(std::string(arg.name) + "_Path", fmt::Estr(std::string(cstr))));
939+
find_replace_arg(original_args, std::string(arg.name), fmt::Estr(std::string(cstr)));
940940
g_free(cstr);
941941
}
942942
};
943943

944944
// type based parsers
945945
m_type_parsers[PUNICODE_STRING] = [](
946-
syscalls_base* base, fmt_args_t& extra_args, const auto* sc,
946+
syscalls_base* base, fmt_args_t& original_args, fmt_args_t& extra_args, const auto* sc,
947947
const auto& arg, auto* info, uint64_t value, const auto& all_args)
948948
{
949949
if (value == 0) return;
950950
unicode_string_t* us = drakvuf_read_unicode(base->drakvuf, info, value);
951951
if (us)
952952
{
953-
extra_args.push_back(keyval(std::string(arg.name), fmt::Estr(std::string((char*)us->contents))));
953+
find_replace_arg(original_args, std::string(arg.name), fmt::Estr(std::string((char*)us->contents)));
954954
vmi_free_unicode_str(us);
955955
}
956956
};
957957

958958
m_type_parsers[POBJECT_ATTRIBUTES] = [](
959-
syscalls_base* base, fmt_args_t& extra_args, const auto* sc,
959+
syscalls_base* base, fmt_args_t& original_args, fmt_args_t& extra_args, const auto* sc,
960960
const auto& arg, auto* info, uint64_t value, const auto& all_args)
961961
{
962962
if (value == 0) return;
963963
char* cstr = drakvuf_get_filename_from_object_attributes(base->drakvuf, info, value);
964964
if (cstr)
965965
{
966-
extra_args.push_back(keyval(std::string(arg.name), fmt::Estr(std::string(cstr))));
966+
find_replace_arg(original_args, std::string(arg.name), fmt::Estr(std::string(cstr)));
967967
g_free(cstr);
968968
}
969969
};
970970

971971
// resolve registers commonly used in process injection from context parameter
972972
m_type_parsers[PCONTEXT] = [](
973-
syscalls_base* base, fmt_args_t& extra_args, const auto* sc,
973+
syscalls_base* base, fmt_args_t& original_args, fmt_args_t& extra_args, const auto* sc,
974974
const auto& arg, auto* info, uint64_t value, const auto& all_args)
975975
{
976976
if (value == 0) return;
@@ -1005,7 +1005,7 @@ void win_syscalls::register_parsers()
10051005
// syscall name + arg name based parsers
10061006
m_syscall_arg_parsers[ {"NtSetInformationThread", "ThreadInformation"}] =
10071007
[](
1008-
syscalls_base* base, fmt_args_t& extra_args, const syscalls_ns::syscall_t* sc,
1008+
syscalls_base* base, fmt_args_t& original_args, fmt_args_t& extra_args, const syscalls_ns::syscall_t* sc,
10091009
const syscalls_ns::arg_t& arg_to_parse, drakvuf_trap_info_t* info,
10101010
uint64_t value_to_parse, const std::vector<uint64_t>& all_args)
10111011
{

0 commit comments

Comments
 (0)