mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-25 14:41:02 +00:00
Cleanup exception callbacks
This commit is contained in:
@@ -32,7 +32,8 @@ namespace
|
||||
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);
|
||||
c.win_emu->log.print(color::pink, "Suspicious: %.*s at 0x%" PRIx64 " (via 0x%" PRIx64 ")\n",
|
||||
STR_VIEW_VA(details), rip, c.win_emu->process.previous_ip);
|
||||
}
|
||||
|
||||
void handle_generic_activity(const analysis_context& c, const std::string_view details)
|
||||
|
||||
@@ -45,7 +45,7 @@ struct arm_emulator : arch_emulator<Traits>
|
||||
|
||||
enum class x86_hookable_instructions
|
||||
{
|
||||
invalid,
|
||||
invalid, // TODO: Get rid of that
|
||||
syscall,
|
||||
cpuid,
|
||||
rdtsc,
|
||||
|
||||
@@ -28,12 +28,22 @@ namespace
|
||||
|
||||
void run_emulation(windows_emulator& win_emu)
|
||||
{
|
||||
bool has_exception = false;
|
||||
const auto _ = utils::finally([&] {
|
||||
win_emu.callbacks.on_exception = {}; //
|
||||
});
|
||||
|
||||
try
|
||||
{
|
||||
win_emu.callbacks.on_exception = [&] {
|
||||
has_exception = true;
|
||||
win_emu.stop();
|
||||
};
|
||||
|
||||
win_emu.log.disable_output(true);
|
||||
win_emu.start();
|
||||
|
||||
if (win_emu.process.exception_rip.has_value())
|
||||
if (has_exception)
|
||||
{
|
||||
throw std::runtime_error("Exception!");
|
||||
}
|
||||
@@ -68,7 +78,6 @@ namespace
|
||||
fuzzer_executer(const std::span<const std::byte> data)
|
||||
: emulator_data(data)
|
||||
{
|
||||
emu.fuzzing = true;
|
||||
emu.emu().hook_basic_block([&](const basic_block& block) {
|
||||
if (this->handler && visited_blocks.emplace(block.address).second)
|
||||
{
|
||||
|
||||
@@ -251,7 +251,6 @@ void process_context::serialize(utils::buffer_serializer& buffer) const
|
||||
buffer.write(this->shared_section_size);
|
||||
buffer.write(this->dbwin_buffer);
|
||||
buffer.write(this->dbwin_buffer_size);
|
||||
buffer.write_optional(this->exception_rip);
|
||||
buffer.write_optional(this->exit_status);
|
||||
buffer.write(this->base_allocator);
|
||||
buffer.write(this->peb);
|
||||
@@ -291,7 +290,6 @@ void process_context::deserialize(utils::buffer_deserializer& buffer)
|
||||
buffer.read(this->shared_section_size);
|
||||
buffer.read(this->dbwin_buffer);
|
||||
buffer.read(this->dbwin_buffer_size);
|
||||
buffer.read_optional(this->exception_rip);
|
||||
buffer.read_optional(this->exit_status);
|
||||
buffer.read(this->base_allocator);
|
||||
buffer.read(this->peb);
|
||||
|
||||
@@ -93,7 +93,6 @@ struct process_context
|
||||
uint64_t dbwin_buffer{0};
|
||||
uint64_t dbwin_buffer_size{0};
|
||||
|
||||
std::optional<uint64_t> exception_rip{};
|
||||
std::optional<NTSTATUS> exit_status{};
|
||||
|
||||
emulator_allocator base_allocator;
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace syscalls
|
||||
}
|
||||
|
||||
c.proc.exit_status = error_status;
|
||||
c.proc.exception_rip = c.emu.read_instruction_pointer();
|
||||
c.win_emu.callbacks.on_exception();
|
||||
c.emu.stop();
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
@@ -27,7 +27,7 @@ namespace syscalls
|
||||
NTSTATUS handle_NtRaiseException(
|
||||
const syscall_context& c,
|
||||
const emulator_object<EMU_EXCEPTION_RECORD<EmulatorTraits<Emu64>>> /*exception_record*/,
|
||||
const emulator_object<CONTEXT64> thread_context, const BOOLEAN handle_exception)
|
||||
const emulator_object<CONTEXT64> /*thread_context*/, const BOOLEAN handle_exception)
|
||||
{
|
||||
if (handle_exception)
|
||||
{
|
||||
@@ -36,9 +36,9 @@ namespace syscalls
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
c.proc.exception_rip = thread_context.read().Rip;
|
||||
c.win_emu.callbacks.on_exception();
|
||||
c.emu.stop();
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -328,7 +328,7 @@ namespace syscalls
|
||||
{
|
||||
if (lock.value())
|
||||
{
|
||||
c.win_emu.log.warn("NtAlertThreadByThreadIdEx with lock not supported yet!");
|
||||
c.win_emu.log.warn("NtAlertThreadByThreadIdEx with lock not supported yet!\n");
|
||||
// c.emu.stop();
|
||||
// return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
@@ -452,17 +452,13 @@ void windows_emulator::setup_hooks()
|
||||
return instruction_hook_continuation::skip_instruction;
|
||||
});
|
||||
|
||||
// TODO: Unicorn needs this - This should be handled in the backend
|
||||
this->emu().hook_instruction(x86_hookable_instructions::invalid, [&] {
|
||||
const auto ip = this->emu().read_instruction_pointer();
|
||||
|
||||
this->log.print(color::gray, "Invalid instruction at: 0x%" PRIx64 " (via 0x%" PRIx64 ")\n", ip,
|
||||
this->process.previous_ip);
|
||||
|
||||
return instruction_hook_continuation::skip_instruction;
|
||||
return instruction_hook_continuation::skip_instruction; //
|
||||
});
|
||||
|
||||
this->emu().hook_interrupt([&](const int interrupt) {
|
||||
const auto rip = this->emu().read_instruction_pointer();
|
||||
this->callbacks.on_exception();
|
||||
const auto eflags = this->emu().reg<uint32_t>(x86_register::eflags);
|
||||
|
||||
switch (interrupt)
|
||||
@@ -473,13 +469,10 @@ void windows_emulator::setup_hooks()
|
||||
case 1:
|
||||
if ((eflags & 0x100) != 0)
|
||||
{
|
||||
this->callbacks.on_suspicious_activity("Singlestep (Trap Flag)");
|
||||
this->emu().reg(x86_register::eflags, eflags & ~0x100);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->callbacks.on_suspicious_activity("Singlestep");
|
||||
}
|
||||
|
||||
this->callbacks.on_suspicious_activity("Singlestep");
|
||||
dispatch_single_step(this->emu(), this->process);
|
||||
return;
|
||||
case 3:
|
||||
@@ -487,6 +480,7 @@ void windows_emulator::setup_hooks()
|
||||
dispatch_breakpoint(this->emu(), this->process);
|
||||
return;
|
||||
case 6:
|
||||
this->callbacks.on_suspicious_activity("Illegal instruction");
|
||||
dispatch_illegal_instruction_violation(this->emu(), this->process);
|
||||
return;
|
||||
case 45:
|
||||
@@ -494,16 +488,13 @@ void windows_emulator::setup_hooks()
|
||||
dispatch_breakpoint(this->emu(), this->process);
|
||||
return;
|
||||
default:
|
||||
if (this->callbacks.on_generic_activity)
|
||||
{
|
||||
this->callbacks.on_generic_activity("Interrupt " + std::to_string(interrupt));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
this->log.print(color::gray, "Interrupt: %i 0x%" PRIx64 "\n", interrupt, rip);
|
||||
|
||||
if (this->fuzzing || true) // TODO: Fix
|
||||
{
|
||||
this->process.exception_rip = rip;
|
||||
this->emu().stop();
|
||||
}
|
||||
});
|
||||
|
||||
this->emu().hook_memory_violation([&](const uint64_t address, const size_t size, const memory_operation operation,
|
||||
@@ -523,13 +514,6 @@ void windows_emulator::setup_hooks()
|
||||
size, permission.c_str(), ip, name);
|
||||
}
|
||||
|
||||
if (this->fuzzing)
|
||||
{
|
||||
this->process.exception_rip = ip;
|
||||
this->emu().stop();
|
||||
return memory_violation_continuation::stop;
|
||||
}
|
||||
|
||||
dispatch_access_violation(this->emu(), this->process, address, operation);
|
||||
return memory_violation_continuation::resume;
|
||||
});
|
||||
|
||||
@@ -21,6 +21,8 @@ struct emulator_callbacks : module_manager::callbacks, process_context::callback
|
||||
{
|
||||
using continuation = instruction_hook_continuation;
|
||||
|
||||
opt_func<void()> on_exception{};
|
||||
|
||||
opt_func<void(uint64_t address, uint64_t length, memory_permission)> on_memory_protect{};
|
||||
opt_func<void(uint64_t address, uint64_t length, memory_permission, bool commit)> on_memory_allocate{};
|
||||
|
||||
@@ -200,9 +202,6 @@ class windows_emulator
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Remove
|
||||
bool fuzzing{false};
|
||||
|
||||
void yield_thread(bool alertable = false);
|
||||
bool perform_thread_switch();
|
||||
bool activate_thread(uint32_t id);
|
||||
|
||||
Reference in New Issue
Block a user