Store previous IP per thread

This commit is contained in:
momo5502
2025-08-17 07:32:26 +02:00
parent b2eef2bf46
commit 584b770def
6 changed files with 22 additions and 22 deletions

View File

@@ -66,7 +66,7 @@ namespace
}
c.win_emu->log.print(color::pink, "Suspicious: %.*s%.*s at 0x%" PRIx64 " (via 0x%" PRIx64 ")\n", STR_VIEW_VA(details),
STR_VIEW_VA(addition), rip, c.win_emu->process.previous_ip);
STR_VIEW_VA(addition), rip, c.win_emu->current_thread().previous_ip);
}
void handle_debug_string(const analysis_context& c, const std::string_view details)
@@ -289,8 +289,9 @@ namespace
}
#endif
const auto previous_ip = c.win_emu->current_thread().previous_ip;
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(c.win_emu->process.previous_ip);
const auto is_previous_main_exe = win_emu.mod_manager.executable->is_within(previous_ip);
const auto binary = utils::make_lazy([&] {
if (is_main_exe)
@@ -307,7 +308,7 @@ namespace
return win_emu.mod_manager.executable;
}
return win_emu.mod_manager.find_by_address(win_emu.process.previous_ip); //
return win_emu.mod_manager.find_by_address(previous_ip); //
});
const auto is_in_interesting_module = [&] {
@@ -343,8 +344,7 @@ namespace
{
win_emu.log.print(is_interesting_call ? color::yellow : color::dark_gray,
"Executing function: %s (%s) (0x%" PRIx64 ") via (0x%" PRIx64 ") %s\n", export_entry->second.c_str(),
binary->name.c_str(), address, win_emu.process.previous_ip,
previous_binary ? previous_binary->name.c_str() : "<N/A>");
binary->name.c_str(), address, previous_ip, previous_binary ? previous_binary->name.c_str() : "<N/A>");
if (is_interesting_call)
{
@@ -357,7 +357,7 @@ namespace
win_emu.log.print(is_interesting_call ? color::yellow : color::gray, "Executing entry point: %s (0x%" PRIx64 ")\n",
binary->name.c_str(), address);
}
else if (is_previous_main_exe && binary != previous_binary && !is_return(c.win_emu->emu(), win_emu.process.previous_ip))
else if (is_previous_main_exe && binary != previous_binary && !is_return(c.win_emu->emu(), previous_ip))
{
auto nearest_entry = binary->address_names.upper_bound(address);
if (nearest_entry == binary->address_names.begin())
@@ -369,8 +369,8 @@ namespace
win_emu.log.print(is_interesting_call ? color::yellow : color::dark_gray,
"Transition to foreign code: %s+0x%" PRIx64 " (%s) (0x%" PRIx64 ") via (0x%" PRIx64 ") %s\n",
nearest_entry->second.c_str(), address - nearest_entry->first, binary->name.c_str(), address,
win_emu.process.previous_ip, previous_binary ? previous_binary->name.c_str() : "<N/A>");
nearest_entry->second.c_str(), address - nearest_entry->first, binary->name.c_str(), address, previous_ip,
previous_binary ? previous_binary->name.c_str() : "<N/A>");
}
}
@@ -416,13 +416,14 @@ namespace
const auto address = emu.read_instruction_pointer();
const auto* mod = win_emu.mod_manager.find_by_address(address);
const auto is_sus_module = mod != win_emu.mod_manager.ntdll && mod != win_emu.mod_manager.win32u;
const auto previous_ip = win_emu.current_thread().previous_ip;
if (is_sus_module)
{
win_emu.log.print(color::blue, "Executing inline syscall: %.*s (0x%X) at 0x%" PRIx64 " (%s)\n", STR_VIEW_VA(syscall_name),
syscall_id, address, mod ? mod->name.c_str() : "<N/A>");
}
else if (mod->is_within(win_emu.process.previous_ip))
else if (mod->is_within(previous_ip))
{
const auto rsp = emu.read_stack_pointer();
@@ -436,11 +437,11 @@ namespace
}
else
{
const auto* previous_mod = win_emu.mod_manager.find_by_address(win_emu.process.previous_ip);
const auto* previous_mod = win_emu.mod_manager.find_by_address(previous_ip);
win_emu.log.print(color::blue, "Crafted out-of-line syscall: %.*s (0x%X) at 0x%" PRIx64 " (%s) via 0x%" PRIx64 " (%s)\n",
STR_VIEW_VA(syscall_name), syscall_id, address, mod ? mod->name.c_str() : "<N/A>",
win_emu.process.previous_ip, previous_mod ? previous_mod->name.c_str() : "<N/A>");
STR_VIEW_VA(syscall_name), syscall_id, address, mod ? mod->name.c_str() : "<N/A>", previous_ip,
previous_mod ? previous_mod->name.c_str() : "<N/A>");
}
return instruction_hook_continuation::run_instruction;

View File

@@ -74,6 +74,9 @@ class emulator_thread : public ref_counted_object
uint32_t id{};
uint64_t current_ip{0};
uint64_t previous_ip{0};
std::u16string name{};
std::optional<NTSTATUS> exit_status{};
@@ -144,6 +147,8 @@ class emulator_thread : public ref_counted_object
buffer.write(this->argument);
buffer.write(this->executed_instructions);
buffer.write(this->id);
buffer.write(this->current_ip);
buffer.write(this->previous_ip);
buffer.write_string(this->name);
@@ -182,6 +187,8 @@ class emulator_thread : public ref_counted_object
buffer.read(this->argument);
buffer.read(this->executed_instructions);
buffer.read(this->id);
buffer.read(this->current_ip);
buffer.read(this->previous_ip);
buffer.read_string(this->name);

View File

@@ -654,7 +654,6 @@ namespace minidump_loader
return;
}
win_emu.process.current_ip = exception_info->exception_record.exception_address;
win_emu.log.info("Exception context: address=0x%" PRIx64 ", code=0x%08X, thread=%u\n",
exception_info->exception_record.exception_address, exception_info->exception_record.exception_code,
exception_info->thread_id);

View File

@@ -248,8 +248,6 @@ void process_context::setup(x86_64_emulator& emu, memory_manager& memory, regist
void process_context::serialize(utils::buffer_serializer& buffer) const
{
buffer.write(this->current_ip);
buffer.write(this->previous_ip);
buffer.write(this->shared_section_address);
buffer.write(this->shared_section_size);
buffer.write(this->dbwin_buffer);
@@ -287,8 +285,6 @@ void process_context::serialize(utils::buffer_serializer& buffer) const
void process_context::deserialize(utils::buffer_deserializer& buffer)
{
buffer.read(this->current_ip);
buffer.read(this->previous_ip);
buffer.read(this->shared_section_address);
buffer.read(this->shared_section_size);
buffer.read(this->dbwin_buffer);

View File

@@ -83,9 +83,6 @@ struct process_context
callbacks* callbacks_{};
uint64_t current_ip{0};
uint64_t previous_ip{0};
uint64_t shared_section_address{0};
uint64_t shared_section_size{0};
uint64_t dbwin_buffer{0};

View File

@@ -420,8 +420,8 @@ void windows_emulator::on_instruction_execution(const uint64_t address)
this->yield_thread();
}
this->process.previous_ip = this->process.current_ip;
this->process.current_ip = this->emu().read_instruction_pointer();
thread.previous_ip = thread.current_ip;
thread.current_ip = this->emu().read_instruction_pointer();
this->callbacks.on_instruction(address);
}