You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

62 lines
2.1 KiB

#include "idt.hpp"
auto seh_handler(hv::pidt_regs_t regs) -> void
{
const auto rva = regs->rip - reinterpret_cast<u64>(idt::image_base);
const auto nt_headers = reinterpret_cast<IMAGE_NT_HEADERS64*>(
reinterpret_cast<u64>(idt::image_base) +
reinterpret_cast<IMAGE_DOS_HEADER*>(idt::image_base)->e_lfanew);
const auto exception =
&nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION];
const auto functions =
reinterpret_cast<RUNTIME_FUNCTION*>(
reinterpret_cast<u64>(idt::image_base) + exception->VirtualAddress);
for (auto idx = 0; idx < exception->Size / sizeof(RUNTIME_FUNCTION); ++idx)
{
const auto function = &functions[idx];
if (!(rva >= function->BeginAddress && rva < function->EndAddress))
continue;
const auto unwind_info =
reinterpret_cast<UNWIND_INFO*>(
reinterpret_cast<u64>(idt::image_base) + function->UnwindData);
if (!(unwind_info->Flags & UNW_FLAG_EHANDLER))
continue;
const auto scope_table =
reinterpret_cast<SCOPE_TABLE*>(
reinterpret_cast<u64>(&unwind_info->UnwindCode[
(unwind_info->CountOfCodes + 1) & ~1]) + sizeof(u32));
for (auto entry = 0; entry < scope_table->Count; ++entry)
{
const auto scope_record = &scope_table->ScopeRecords[entry];
if (rva >= scope_record->BeginAddress && rva < scope_record->EndAddress)
{
regs->rip = reinterpret_cast<u64>(idt::image_base) + scope_record->JumpTarget;
return;
}
}
}
}
namespace idt
{
auto create_entry(hv::idt_addr_t idt_handler, u8 ist_index) -> hv::idt_entry_t
{
hv::idt_entry_t result{};
result.segment_selector = readcs();
result.gate_type = SEGMENT_DESCRIPTOR_TYPE_INTERRUPT_GATE;
result.present = true;
//result.ist_index = ist_index;
result.offset_high = idt_handler.offset_high;
result.offset_middle = idt_handler.offset_middle;
result.offset_low = idt_handler.offset_low;
return result;
}
}