mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-18 19:23:56 +00:00
Extract more analysis logic
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
#include "analysis.hpp"
|
||||
#include "windows_emulator.hpp"
|
||||
#include "utils/lazy_object.hpp"
|
||||
|
||||
#define STR_VIEW_VA(str) static_cast<int>((str).size()), (str).data()
|
||||
|
||||
@@ -20,6 +21,96 @@ namespace
|
||||
win_emu.log.print(color::pink, "Suspicious: %.*s (0x%" PRIx64 ")\n", STR_VIEW_VA(details), rip);
|
||||
}
|
||||
|
||||
void handle_instruction(windows_emulator& win_emu, const uint64_t address)
|
||||
{
|
||||
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 binary = utils::make_lazy([&] {
|
||||
if (is_main_exe)
|
||||
{
|
||||
return win_emu.mod_manager.executable;
|
||||
}
|
||||
|
||||
return win_emu.mod_manager.find_by_address(address); //
|
||||
});
|
||||
|
||||
const auto previous_binary = utils::make_lazy([&] {
|
||||
if (is_previous_main_exe)
|
||||
{
|
||||
return win_emu.mod_manager.executable;
|
||||
}
|
||||
|
||||
return win_emu.mod_manager.find_by_address(win_emu.process.previous_ip); //
|
||||
});
|
||||
|
||||
const auto is_in_interesting_module = [&] {
|
||||
if (win_emu.modules_.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return (binary && win_emu.modules_.contains(binary->name)) ||
|
||||
(previous_binary && win_emu.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)
|
||||
{
|
||||
win_emu.silent_until_main_ = false;
|
||||
win_emu.log.disable_output(false);
|
||||
}
|
||||
|
||||
if (!win_emu.verbose && !win_emu.verbose_calls && !is_interesting_call)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (binary)
|
||||
{
|
||||
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();
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
if (!win_emu.verbose)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
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,
|
||||
const std::string_view syscall_name)
|
||||
{
|
||||
@@ -66,5 +157,6 @@ void register_analysis_callbacks(windows_emulator& win_emu)
|
||||
auto& cb = 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);
|
||||
}
|
||||
|
||||
@@ -418,89 +418,7 @@ void windows_emulator::on_instruction_execution(const uint64_t address)
|
||||
this->process.previous_ip = this->process.current_ip;
|
||||
this->process.current_ip = this->emu().read_instruction_pointer();
|
||||
|
||||
const auto is_main_exe = this->mod_manager.executable->is_within(address);
|
||||
const auto is_previous_main_exe = this->mod_manager.executable->is_within(this->process.previous_ip);
|
||||
|
||||
const auto binary = utils::make_lazy([&] {
|
||||
if (is_main_exe)
|
||||
{
|
||||
return this->mod_manager.executable;
|
||||
}
|
||||
|
||||
return this->mod_manager.find_by_address(address); //
|
||||
});
|
||||
|
||||
const auto previous_binary = utils::make_lazy([&] {
|
||||
if (is_previous_main_exe)
|
||||
{
|
||||
return this->mod_manager.executable;
|
||||
}
|
||||
|
||||
return this->mod_manager.find_by_address(this->process.previous_ip); //
|
||||
});
|
||||
|
||||
const auto is_in_interesting_module = [&] {
|
||||
if (this->modules_.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return (binary && this->modules_.contains(binary->name)) ||
|
||||
(previous_binary && this->modules_.contains(previous_binary->name));
|
||||
};
|
||||
|
||||
const auto is_interesting_call = is_previous_main_exe //
|
||||
|| is_main_exe //
|
||||
|| is_in_interesting_module();
|
||||
|
||||
if (this->silent_until_main_ && is_main_exe)
|
||||
{
|
||||
this->silent_until_main_ = false;
|
||||
this->log.disable_output(false);
|
||||
}
|
||||
|
||||
if (!this->verbose && !this->verbose_calls && !is_interesting_call)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (binary)
|
||||
{
|
||||
const auto export_entry = binary->address_names.find(address);
|
||||
if (export_entry != binary->address_names.end() && !this->ignored_functions_.contains(export_entry->second))
|
||||
{
|
||||
const auto rsp = this->emu().read_stack_pointer();
|
||||
|
||||
uint64_t return_address{};
|
||||
this->emu().try_read_memory(rsp, &return_address, sizeof(return_address));
|
||||
|
||||
const auto* mod_name = this->mod_manager.find_name(return_address);
|
||||
|
||||
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)
|
||||
{
|
||||
log.print(is_interesting_call ? color::yellow : color::gray, "Executing entry point: %s (0x%" PRIx64 ")\n",
|
||||
binary->name.c_str(), address);
|
||||
}
|
||||
}
|
||||
|
||||
if (!this->verbose)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto& emu = this->emu();
|
||||
|
||||
// TODO: Remove or cleanup
|
||||
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>");
|
||||
this->callbacks.on_instruction(address);
|
||||
}
|
||||
|
||||
void windows_emulator::setup_hooks()
|
||||
|
||||
@@ -20,6 +20,7 @@ struct emulator_callbacks : module_manager::callbacks, process_context::callback
|
||||
utils::optional_function<continuation(uint32_t syscall_id, std::string_view syscall_name)> on_syscall{};
|
||||
utils::optional_function<void(std::string_view data)> on_stdout{};
|
||||
utils::optional_function<void(std::string_view description)> on_suspicious_activity{};
|
||||
utils::optional_function<void(uint64_t address)> on_instruction{};
|
||||
};
|
||||
|
||||
struct application_settings
|
||||
@@ -176,25 +177,28 @@ class windows_emulator
|
||||
}
|
||||
}
|
||||
|
||||
bool verbose{false};
|
||||
bool verbose_calls{false};
|
||||
bool buffer_stdout{false};
|
||||
// TODO: Remove
|
||||
bool fuzzing{false};
|
||||
|
||||
void yield_thread(bool alertable = false);
|
||||
bool perform_thread_switch();
|
||||
bool activate_thread(uint32_t id);
|
||||
|
||||
// TODO: Move to analyzer
|
||||
bool verbose{false};
|
||||
bool verbose_calls{false};
|
||||
bool buffer_stdout{false};
|
||||
bool silent_until_main_{false};
|
||||
std::set<std::string, std::less<>> modules_{};
|
||||
std::set<std::string, std::less<>> ignored_functions_{};
|
||||
|
||||
private:
|
||||
bool switch_thread_{false};
|
||||
bool use_relative_time_{false};
|
||||
bool silent_until_main_{false};
|
||||
std::atomic_bool should_stop{false};
|
||||
|
||||
std::unordered_map<uint16_t, uint16_t> port_mappings_{};
|
||||
|
||||
std::set<std::string, std::less<>> modules_{};
|
||||
std::set<std::string, std::less<>> ignored_functions_{};
|
||||
std::vector<std::byte> process_snapshot_{};
|
||||
// std::optional<process_context> process_snapshot_{};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user