Handle illegal instructions (#43)

This commit is contained in:
Maurice Heumann
2025-01-04 11:27:14 +01:00
committed by GitHub
2 changed files with 69 additions and 5 deletions

View File

@@ -234,7 +234,7 @@ bool test_exceptions()
}
}
void throw_native_exception()
void throw_access_violation()
{
if (do_the_task)
{
@@ -242,19 +242,55 @@ void throw_native_exception()
}
}
bool test_native_exceptions()
bool test_access_violation_exception()
{
__try
{
throw_native_exception();
throw_access_violation();
return false;
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
return true;
return GetExceptionCode() == STATUS_ACCESS_VIOLATION;
}
}
bool test_ud2_exception(void* address)
{
__try
{
static_cast<void(*)()>(address)();
return false;
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
return GetExceptionCode() == STATUS_ILLEGAL_INSTRUCTION;
}
}
bool test_illegal_instruction_exception()
{
const auto address = VirtualAlloc(nullptr, 0x1000, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (!address)
{
return false;
}
memcpy(address, "\x0F\x0B", 2); // ud2
const auto res = test_ud2_exception(address);
VirtualFree(address, 0x1000, MEM_RELEASE);
return res;
}
bool test_native_exceptions()
{
return test_access_violation_exception()
&& test_illegal_instruction_exception();
}
void print_time()
{
const auto epoch_time = std::chrono::system_clock::now().time_since_epoch();

View File

@@ -425,6 +425,27 @@ namespace
dispatch_exception_pointers(emu, dispatcher, pointers);
}
void dispatch_illegal_instruction_violation(x64_emulator& emu, const uint64_t dispatcher)
{
CONTEXT ctx{};
ctx.ContextFlags = CONTEXT_ALL;
context_frame::save(emu, ctx);
EXCEPTION_RECORD record{};
memset(&record, 0, sizeof(record));
record.ExceptionCode = static_cast<DWORD>(STATUS_ILLEGAL_INSTRUCTION);
record.ExceptionFlags = 0;
record.ExceptionRecord = nullptr;
record.ExceptionAddress = reinterpret_cast<void*>(emu.read_instruction_pointer());
record.NumberParameters = 0;
EXCEPTION_POINTERS pointers{};
pointers.ContextRecord = &ctx;
pointers.ExceptionRecord = &record;
dispatch_exception_pointers(emu, dispatcher, pointers);
}
void perform_context_switch_work(windows_emulator& win_emu)
{
auto& devices = win_emu.process().devices;
@@ -462,7 +483,7 @@ namespace
if (active_thread)
{
win_emu.logger.print(color::green, "Performing thread switch...\n");
win_emu.logger.print(color::dark_gray, "Performing thread switch...\n");
active_thread->save(emu);
}
@@ -812,11 +833,18 @@ void windows_emulator::setup_hooks()
{
const auto ip = this->emu().read_instruction_pointer();
printf("Invalid instruction at: 0x%llX\n", ip);
return instruction_hook_continuation::skip_instruction;
});
this->emu().hook_interrupt([&](const int interrupt)
{
if (interrupt == 6)
{
dispatch_illegal_instruction_violation(this->emu(), this->process().ki_user_exception_dispatcher);
return;
}
const auto rip = this->emu().read_instruction_pointer();
printf("Interrupt: %i 0x%llX\n", interrupt, rip);