Isolate more analysis into analyzer

This commit is contained in:
momo5502
2025-06-05 18:59:27 +02:00
parent f046246740
commit f2e0e91630
9 changed files with 130 additions and 137 deletions

View File

@@ -7,24 +7,34 @@
namespace
{
template <typename Return, typename... Args>
std::function<Return(Args...)> make_callback(windows_emulator& win_emu,
Return (*callback)(windows_emulator&, Args...))
std::function<Return(Args...)> make_callback(analysis_context& c, Return (*callback)(analysis_context&, Args...))
{
return [&win_emu, callback](Args... args) {
return callback(win_emu, std::forward<Args>(args)...); //
return [&c, callback](Args... args) {
return callback(c, std::forward<Args>(args)...); //
};
}
void handle_suspicious_activity(windows_emulator& win_emu, const std::string_view details)
template <typename Return, typename... Args>
std::function<Return(Args...)> make_callback(analysis_context& c,
Return (*callback)(const analysis_context&, Args...))
{
const auto rip = win_emu.emu().read_instruction_pointer();
win_emu.log.print(color::pink, "Suspicious: %.*s (0x%" PRIx64 ")\n", STR_VIEW_VA(details), rip);
return [&c, callback](Args... args) {
return callback(c, std::forward<Args>(args)...); //
};
}
void handle_instruction(windows_emulator& win_emu, const uint64_t address)
void handle_suspicious_activity(const analysis_context& c, const std::string_view details)
{
const auto rip = c.win_emu->emu().read_instruction_pointer();
c.win_emu->log.print(color::pink, "Suspicious: %.*s (0x%" PRIx64 ")\n", STR_VIEW_VA(details), rip);
}
void handle_instruction(analysis_context& c, const uint64_t address)
{
auto& win_emu = *c.win_emu;
const auto is_main_exe = win_emu.mod_manager.executable->is_within(address);
const auto is_previous_main_exe = win_emu.mod_manager.executable->is_within(win_emu.process.previous_ip);
const auto is_previous_main_exe = win_emu.mod_manager.executable->is_within(c.win_emu->process.previous_ip);
const auto binary = utils::make_lazy([&] {
if (is_main_exe)
@@ -45,75 +55,56 @@ namespace
});
const auto is_in_interesting_module = [&] {
if (win_emu.modules_.empty())
if (c.settings->modules.empty())
{
return false;
}
return (binary && win_emu.modules_.contains(binary->name)) ||
(previous_binary && win_emu.modules_.contains(previous_binary->name));
return (binary && c.settings->modules.contains(binary->name)) ||
(previous_binary && c.settings->modules.contains(previous_binary->name));
};
const auto is_interesting_call = is_previous_main_exe //
|| is_main_exe //
|| is_in_interesting_module();
if (win_emu.silent_until_main_ && is_main_exe)
if (!c.has_reached_main && c.settings->concise_logging && !c.settings->silent && is_main_exe)
{
win_emu.silent_until_main_ = false;
c.has_reached_main = true;
win_emu.log.disable_output(false);
}
if (!win_emu.verbose && !win_emu.verbose_calls && !is_interesting_call)
if ((!c.settings->verbose_logging && !is_interesting_call) || !binary)
{
return;
}
if (binary)
const auto export_entry = binary->address_names.find(address);
if (export_entry != binary->address_names.end() &&
!c.settings->ignored_functions.contains(export_entry->second))
{
const auto export_entry = binary->address_names.find(address);
if (export_entry != binary->address_names.end() &&
!win_emu.ignored_functions_.contains(export_entry->second))
{
const auto rsp = win_emu.emu().read_stack_pointer();
const auto rsp = win_emu.emu().read_stack_pointer();
uint64_t return_address{};
win_emu.emu().try_read_memory(rsp, &return_address, sizeof(return_address));
uint64_t return_address{};
win_emu.emu().try_read_memory(rsp, &return_address, sizeof(return_address));
const auto* mod_name = win_emu.mod_manager.find_name(return_address);
const auto* mod_name = win_emu.mod_manager.find_name(return_address);
win_emu.log.print(is_interesting_call ? color::yellow : color::dark_gray,
"Executing function: %s - %s (0x%" PRIx64 ") via (0x%" PRIx64 ") %s\n",
binary->name.c_str(), export_entry->second.c_str(), address, return_address,
mod_name);
}
else if (address == binary->entry_point)
{
win_emu.log.print(is_interesting_call ? color::yellow : color::gray,
"Executing entry point: %s (0x%" PRIx64 ")\n", binary->name.c_str(), address);
}
win_emu.log.print(is_interesting_call ? color::yellow : color::dark_gray,
"Executing function: %s - %s (0x%" PRIx64 ") via (0x%" PRIx64 ") %s\n",
binary->name.c_str(), export_entry->second.c_str(), address, return_address, mod_name);
}
if (!win_emu.verbose)
else if (address == binary->entry_point)
{
return;
win_emu.log.print(is_interesting_call ? color::yellow : color::gray,
"Executing entry point: %s (0x%" PRIx64 ")\n", binary->name.c_str(), address);
}
auto& emu = win_emu.emu();
// TODO: Remove or cleanup
win_emu.log.print(
color::gray,
"Inst: %16" PRIx64 " - RAX: %16" PRIx64 " - RBX: %16" PRIx64 " - RCX: %16" PRIx64 " - RDX: %16" PRIx64
" - R8: %16" PRIx64 " - R9: %16" PRIx64 " - RDI: %16" PRIx64 " - RSI: %16" PRIx64 " - %s\n",
address, emu.reg(x86_register::rax), emu.reg(x86_register::rbx), emu.reg(x86_register::rcx),
emu.reg(x86_register::rdx), emu.reg(x86_register::r8), emu.reg(x86_register::r9),
emu.reg(x86_register::rdi), emu.reg(x86_register::rsi), binary ? binary->name.c_str() : "<N/A>");
}
emulator_callbacks::continuation handle_syscall(windows_emulator& win_emu, const uint32_t syscall_id,
emulator_callbacks::continuation handle_syscall(const analysis_context& c, const uint32_t syscall_id,
const std::string_view syscall_name)
{
auto& win_emu = *c.win_emu;
auto& emu = win_emu.emu();
const auto address = emu.read_instruction_pointer();
@@ -150,13 +141,30 @@ namespace
return instruction_hook_continuation::run_instruction;
}
void handle_stdout(analysis_context& c, const std::string_view data)
{
if (c.settings->silent)
{
(void)fwrite(data.data(), 1, data.size(), stdout);
}
else if (c.settings->buffer_stdout)
{
c.output.append(data);
}
else
{
c.win_emu->log.info("%.*s%s", static_cast<int>(data.size()), data.data(), data.ends_with("\n") ? "" : "\n");
}
}
}
void register_analysis_callbacks(windows_emulator& win_emu)
void register_analysis_callbacks(analysis_context& c)
{
auto& cb = win_emu.callbacks;
auto& cb = c.win_emu->callbacks;
cb.on_syscall = make_callback(win_emu, handle_syscall);
cb.on_instruction = make_callback(win_emu, handle_instruction);
cb.on_suspicious_activity = make_callback(win_emu, handle_suspicious_activity);
cb.on_stdout = make_callback(c, handle_stdout);
cb.on_syscall = make_callback(c, handle_syscall);
cb.on_instruction = make_callback(c, handle_instruction);
cb.on_suspicious_activity = make_callback(c, handle_suspicious_activity);
}