mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-19 11:43:56 +00:00
Isolate more analysis into analyzer
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user