mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-18 11:13:57 +00:00
Handle illegal instructions (#43)
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user