Fix formatting

This commit is contained in:
Maurice Heumann
2025-07-17 18:30:00 +02:00
parent 079d367792
commit 8caf724c95
3 changed files with 76 additions and 59 deletions

View File

@@ -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)
{

View File

@@ -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());

View File

@@ -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;