mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-24 14:11:02 +00:00
Fix formatting
This commit is contained in:
@@ -289,38 +289,38 @@ namespace
|
||||
return create_application_emulator(options, args);
|
||||
}
|
||||
|
||||
bool run(const analysis_options& options, const std::span<const std::string_view> args)
|
||||
{
|
||||
analysis_context context{
|
||||
.settings = &options,
|
||||
};
|
||||
|
||||
const auto win_emu = setup_emulator(options, args);
|
||||
win_emu->log.disable_output(options.concise_logging || options.silent);
|
||||
context.win_emu = win_emu.get();
|
||||
|
||||
win_emu->log.log("Using emulator: %s\n", win_emu->emu().get_name().c_str());
|
||||
|
||||
// Enable TenetTracer and assign it to the context.
|
||||
std::unique_ptr<TenetTracer> tenet_tracer;
|
||||
if (options.tenet_trace)
|
||||
bool run(const analysis_options& options, const std::span<const std::string_view> args)
|
||||
{
|
||||
win_emu->log.log("Tenet Tracer enabled. Output: tenet_trace.log\n");
|
||||
tenet_tracer = std::make_unique<TenetTracer>(*win_emu, "tenet_trace.log");
|
||||
analysis_context context{
|
||||
.settings = &options,
|
||||
};
|
||||
|
||||
// Set up the hook to call the tracer for each instruction.
|
||||
win_emu->emu().hook_memory_execution([&](uint64_t address) {
|
||||
if (tenet_tracer)
|
||||
{
|
||||
tenet_tracer->process_instruction(address);
|
||||
}
|
||||
});
|
||||
}
|
||||
const auto win_emu = setup_emulator(options, args);
|
||||
win_emu->log.disable_output(options.concise_logging || options.silent);
|
||||
context.win_emu = win_emu.get();
|
||||
|
||||
register_analysis_callbacks(context);
|
||||
watch_system_objects(*win_emu, options.modules, options.verbose_logging);
|
||||
win_emu->log.log("Using emulator: %s\n", win_emu->emu().get_name().c_str());
|
||||
|
||||
const auto& exe = *win_emu->mod_manager.executable;
|
||||
// Enable TenetTracer and assign it to the context.
|
||||
std::unique_ptr<TenetTracer> tenet_tracer;
|
||||
if (options.tenet_trace)
|
||||
{
|
||||
win_emu->log.log("Tenet Tracer enabled. Output: tenet_trace.log\n");
|
||||
tenet_tracer = std::make_unique<TenetTracer>(*win_emu, "tenet_trace.log");
|
||||
|
||||
// Set up the hook to call the tracer for each instruction.
|
||||
win_emu->emu().hook_memory_execution([&](uint64_t address) {
|
||||
if (tenet_tracer)
|
||||
{
|
||||
tenet_tracer->process_instruction(address);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
register_analysis_callbacks(context);
|
||||
watch_system_objects(*win_emu, options.modules, options.verbose_logging);
|
||||
|
||||
const auto& exe = *win_emu->mod_manager.executable;
|
||||
|
||||
const auto concise_logging = !options.verbose_logging;
|
||||
|
||||
@@ -434,7 +434,6 @@ bool run(const analysis_options& options, const std::span<const std::string_view
|
||||
printf(" analyzer -v -e path/to/root myapp.exe\n");
|
||||
printf(" analyzer -e path/to/root -p c:/analysis-sample.exe /path/to/sample.exe c:/analysis-sample.exe\n");
|
||||
}
|
||||
|
||||
|
||||
analysis_options parse_options(std::vector<std::string_view>& args)
|
||||
{
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
#include <map>
|
||||
|
||||
TenetTracer::TenetTracer(windows_emulator& win_emu, const std::string& log_filename)
|
||||
: m_win_emu(win_emu), m_log_file(log_filename)
|
||||
: m_win_emu(win_emu),
|
||||
m_log_file(log_filename)
|
||||
{
|
||||
if (!m_log_file.is_open())
|
||||
{
|
||||
@@ -11,19 +12,19 @@ TenetTracer::TenetTracer(windows_emulator& win_emu, const std::string& log_filen
|
||||
}
|
||||
// Set up memory hooks.
|
||||
auto& emu = m_win_emu.emu();
|
||||
m_read_hook = emu.hook_memory_read(0, 0xFFFFFFFFFFFFFFFF, [this](uint64_t a, const void* d, size_t s) {
|
||||
this->log_memory_read(a, d, s);
|
||||
});
|
||||
m_write_hook = emu.hook_memory_write(0, 0xFFFFFFFFFFFFFFFF, [this](uint64_t a, const void* d, size_t s) {
|
||||
this->log_memory_write(a, d, s);
|
||||
});
|
||||
m_read_hook = emu.hook_memory_read(0, 0xFFFFFFFFFFFFFFFF,
|
||||
[this](uint64_t a, const void* d, size_t s) { this->log_memory_read(a, d, s); });
|
||||
m_write_hook = emu.hook_memory_write(
|
||||
0, 0xFFFFFFFFFFFFFFFF, [this](uint64_t a, const void* d, size_t s) { this->log_memory_write(a, d, s); });
|
||||
}
|
||||
|
||||
TenetTracer::~TenetTracer()
|
||||
{
|
||||
auto& emu = m_win_emu.emu();
|
||||
if (m_read_hook) emu.delete_hook(m_read_hook);
|
||||
if (m_write_hook) emu.delete_hook(m_write_hook);
|
||||
if (m_read_hook)
|
||||
emu.delete_hook(m_read_hook);
|
||||
if (m_write_hook)
|
||||
emu.delete_hook(m_write_hook);
|
||||
|
||||
// Filter and write the buffer when the program ends.
|
||||
filter_and_write_buffer();
|
||||
@@ -89,9 +90,10 @@ void TenetTracer::filter_and_write_buffer()
|
||||
for (size_t i = 1; i < m_raw_log_buffer.size(); ++i)
|
||||
{
|
||||
const auto& line = m_raw_log_buffer[i];
|
||||
|
||||
|
||||
size_t rip_pos = line.find("rip=0x");
|
||||
if (rip_pos == std::string::npos) continue;
|
||||
if (rip_pos == std::string::npos)
|
||||
continue;
|
||||
|
||||
char* end_ptr;
|
||||
uint64_t address = std::strtoull(line.c_str() + rip_pos + 6, &end_ptr, 16);
|
||||
@@ -121,15 +123,17 @@ void TenetTracer::filter_and_write_buffer()
|
||||
|
||||
for (const auto& pair : accumulated_changes)
|
||||
{
|
||||
if (!first) summary_line << ",";
|
||||
if (!first)
|
||||
summary_line << ",";
|
||||
summary_line << pair.first << "=" << pair.second;
|
||||
first = false;
|
||||
}
|
||||
|
||||
|
||||
// Add the last known rip at the end.
|
||||
if (!last_rip.empty())
|
||||
{
|
||||
if (!first) summary_line << ",";
|
||||
if (!first)
|
||||
summary_line << ",";
|
||||
summary_line << "rip=" << last_rip;
|
||||
}
|
||||
|
||||
@@ -154,7 +158,6 @@ void TenetTracer::filter_and_write_buffer()
|
||||
m_raw_log_buffer.clear();
|
||||
}
|
||||
|
||||
|
||||
std::string TenetTracer::format_hex(uint64_t value)
|
||||
{
|
||||
std::stringstream ss;
|
||||
@@ -203,7 +206,8 @@ void TenetTracer::process_instruction(uint64_t address)
|
||||
|
||||
bool first_entry = true;
|
||||
auto append_separator = [&]() {
|
||||
if (!first_entry) {
|
||||
if (!first_entry)
|
||||
{
|
||||
trace_line << ",";
|
||||
}
|
||||
first_entry = false;
|
||||
@@ -234,16 +238,18 @@ void TenetTracer::process_instruction(uint64_t address)
|
||||
trace_line << "rip=" << format_hex(address);
|
||||
|
||||
std::string mem_reads = m_mem_read_log.str();
|
||||
if (!mem_reads.empty()) {
|
||||
if (!mem_reads.empty())
|
||||
{
|
||||
append_separator();
|
||||
trace_line << "mr=" << mem_reads;
|
||||
}
|
||||
std::string mem_writes = m_mem_write_log.str();
|
||||
if (!mem_writes.empty()) {
|
||||
if (!mem_writes.empty())
|
||||
{
|
||||
append_separator();
|
||||
trace_line << "mw=" << mem_writes;
|
||||
}
|
||||
|
||||
|
||||
// Add the data to the buffer instead of writing directly to the file.
|
||||
m_raw_log_buffer.push_back(trace_line.str());
|
||||
|
||||
|
||||
@@ -10,18 +10,30 @@
|
||||
#include <string_view>
|
||||
|
||||
// List of registers to trace for the x64 architecture.
|
||||
constexpr std::array<std::pair<x86_register, std::string_view>, 16> GPRs_TO_TRACE = {{
|
||||
{x86_register::rax, "rax"}, {x86_register::rbx, "rbx"}, {x86_register::rcx, "rcx"},
|
||||
{x86_register::rdx, "rdx"}, {x86_register::rsi, "rsi"}, {x86_register::rdi, "rdi"},
|
||||
{x86_register::rbp, "rbp"}, {x86_register::rsp, "rsp"}, {x86_register::r8, "r8"},
|
||||
{x86_register::r9, "r9"}, {x86_register::r10, "r10"}, {x86_register::r11, "r11"},
|
||||
{x86_register::r12, "r12"}, {x86_register::r13, "r13"}, {x86_register::r14, "r14"},
|
||||
{x86_register::r15, "r15"}
|
||||
}};
|
||||
constexpr std::array<std::pair<x86_register, std::string_view>, 16> GPRs_TO_TRACE = {
|
||||
{
|
||||
{x86_register::rax, "rax"},
|
||||
{x86_register::rbx, "rbx"},
|
||||
{x86_register::rcx, "rcx"},
|
||||
{x86_register::rdx, "rdx"},
|
||||
{x86_register::rsi, "rsi"},
|
||||
{x86_register::rdi, "rdi"},
|
||||
{x86_register::rbp, "rbp"},
|
||||
{x86_register::rsp, "rsp"},
|
||||
{x86_register::r8, "r8"},
|
||||
{x86_register::r9, "r9"},
|
||||
{x86_register::r10, "r10"},
|
||||
{x86_register::r11, "r11"},
|
||||
{x86_register::r12, "r12"},
|
||||
{x86_register::r13, "r13"},
|
||||
{x86_register::r14, "r14"},
|
||||
{x86_register::r15, "r15"},
|
||||
},
|
||||
};
|
||||
|
||||
class TenetTracer
|
||||
{
|
||||
public:
|
||||
public:
|
||||
TenetTracer(windows_emulator& win_emu, const std::string& log_filename);
|
||||
~TenetTracer();
|
||||
|
||||
@@ -32,7 +44,7 @@ public:
|
||||
TenetTracer(const TenetTracer&) = delete;
|
||||
TenetTracer& operator=(const TenetTracer&) = delete;
|
||||
|
||||
private:
|
||||
private:
|
||||
void filter_and_write_buffer();
|
||||
void log_memory_read(uint64_t address, const void* data, size_t size);
|
||||
void log_memory_write(uint64_t address, const void* data, size_t size);
|
||||
@@ -45,7 +57,7 @@ private:
|
||||
|
||||
// In-memory buffering for performance.
|
||||
std::vector<std::string> m_raw_log_buffer;
|
||||
|
||||
|
||||
// Use an array instead of a map to store the register state of the previous instruction.
|
||||
std::array<uint64_t, GPRs_TO_TRACE.size()> m_previous_regs{};
|
||||
bool m_is_first_instruction = true;
|
||||
|
||||
Reference in New Issue
Block a user