diff --git a/bluepill.vcxproj b/bluepill.vcxproj
index e663bbd..cde56dc 100644
--- a/bluepill.vcxproj
+++ b/bluepill.vcxproj
@@ -83,6 +83,7 @@
+
@@ -93,6 +94,7 @@
+
diff --git a/bluepill.vcxproj.filters b/bluepill.vcxproj.filters
index 84c41df..ca468fc 100644
--- a/bluepill.vcxproj.filters
+++ b/bluepill.vcxproj.filters
@@ -35,6 +35,9 @@
Source Files
+
+ Source Files
+
@@ -70,6 +73,9 @@
Header Files
+
+ Header Files
+
diff --git a/debug.cpp b/debug.cpp
new file mode 100644
index 0000000..2048744
--- /dev/null
+++ b/debug.cpp
@@ -0,0 +1,69 @@
+#include "debug.hpp"
+
+auto dbg::debug_print_decimal(long long number) -> void
+{
+ if (number < 0)
+ {
+ __outbyte(PORT_NUM, '-');
+ number = -number;
+ }
+
+ for (auto d = 1000000000000000000; d != 0; d /= 10)
+ if ((number / d) != 0)
+ __outbyte(PORT_NUM, alphabet[(number / d) % 10]);
+}
+
+auto dbg::debug_print_hex(u64 number, const bool show_zeros) -> void
+{
+ for (auto d = 0x1000000000000000; d != 0; d /= 0x10)
+ if (show_zeros || (number / d) != 0)
+ __outbyte(PORT_NUM, alphabet[(number / d) % 0x10]);
+}
+
+auto dbg::print(const char* format, ...) -> void
+{
+ va_list args;
+ va_start(args, format);
+
+ while (format[0])
+ {
+ if (format[0] == '%')
+ {
+ switch (format[1])
+ {
+ case 'd':
+ debug_print_decimal(va_arg(args, int));
+ format += 2;
+ continue;
+ case 'x':
+ debug_print_hex(va_arg(args, u32), false);
+ format += 2;
+ continue;
+ case 'l':
+ if (format[2] == 'l')
+ {
+ switch (format[3])
+ {
+ case 'd':
+ debug_print_decimal(va_arg(args, u64));
+ format += 4;
+ continue;
+ case 'x':
+ debug_print_hex(va_arg(args, u64), false);
+ format += 4;
+ continue;
+ }
+ }
+ break;
+ case 'p':
+ debug_print_hex(va_arg(args, u64), true);
+ format += 2;
+ continue;
+ }
+ }
+
+ __outbyte(PORT_NUM, format[0]);
+ ++format;
+ }
+ va_end(args);
+}
\ No newline at end of file
diff --git a/debug.hpp b/debug.hpp
new file mode 100644
index 0000000..08e801c
--- /dev/null
+++ b/debug.hpp
@@ -0,0 +1,13 @@
+#pragma once
+#include
+#include
+#include "hv_types.hpp"
+#define PORT_NUM 0x3E8
+
+namespace dbg
+{
+ constexpr char alphabet[] = "0123456789ABCDEF";
+ auto debug_print_decimal(long long number) -> void;
+ auto debug_print_hex(u64 number, const bool show_zeros) -> void;
+ auto print(const char* format, ...) -> void;
+}
\ No newline at end of file
diff --git a/drv_entry.cpp b/drv_entry.cpp
index 2b3e1d9..5416da2 100644
--- a/drv_entry.cpp
+++ b/drv_entry.cpp
@@ -5,7 +5,7 @@ auto driver_unload(
PDRIVER_OBJECT driver_object
) -> void
{
- // no unloading this hv... restart! lol
+ // no unloading this hv... restart...
__debugbreak();
}
@@ -62,16 +62,6 @@ auto driver_entry(
idt::table[page_fault] = create_entry(hv::idt_addr_t{ __pf_handler }, idt::ist_idx::pf);
idt::table[divide_error] = create_entry(hv::idt_addr_t{ __de_handler }, idt::ist_idx::de);
- // change the segment selector to work with vmxroot gdt...
- for (auto idx = 0u; idx < 255; ++idx)
- {
- segment_selector cs{};
- cs.idx = gdt::idx::cs;
- cs.request_privilege_level = NULL;
- cs.table = NULL;
- idt::table[idx].segment_selector = cs.flags;
- }
-
// used for SEH in vmxroot fault handler...
idt::image_base = driver_object->DriverStart;
diff --git a/exit_handler.cpp b/exit_handler.cpp
index 1620c0b..803e8bc 100644
--- a/exit_handler.cpp
+++ b/exit_handler.cpp
@@ -12,7 +12,7 @@ auto exit_handler(hv::pguest_registers regs) -> void
if (regs->rcx == 0xC0FFEE)
{
regs->rax = 0xC0FFEE;
- __debugbreak();
+ *(u8*)0x0 = 0xDE;
}
else
{
diff --git a/idt.cpp b/idt.cpp
index 70d30e2..43f2f0f 100644
--- a/idt.cpp
+++ b/idt.cpp
@@ -1,10 +1,45 @@
#include "idt.hpp"
-void seh_handler(hv::pidt_regs_t regs)
+auto seh_handler(hv::pidt_regs_t regs) -> void
{
- // probably not going to work since software interrupts are disabled?
__debugbreak();
- return;
+
+ /*const auto rva = regs->rip - reinterpret_cast(idt::image_base);
+
+ IMAGE_NT_HEADERS64* nt = (IMAGE_NT_HEADERS64*)(reinterpret_cast(idt::image_base) +
+ reinterpret_cast(idt::image_base).e_lfanew);
+
+ IMAGE_DATA_DIRECTORY* exception =
+ &nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION];
+
+ RUNTIME_FUNCTION* functions =
+ (RUNTIME_FUNCTION*)((UINT64)&__ImageBase + exception->VirtualAddress);
+
+ for (UINT32 i = 0; i < exception->Size / sizeof(RUNTIME_FUNCTION); ++i) {
+ RUNTIME_FUNCTION* function = &functions[i];
+ if (!(rva >= function->BeginAddress && rva < function->EndAddress)) {
+ continue;
+ }
+
+ UNWIND_INFO* unwindInfo = (UNWIND_INFO*)((UINT64)&__ImageBase + function->UnwindData);
+ if (!(unwindInfo->Flags & UNW_FLAG_EHANDLER)) {
+ continue;
+ }
+
+ SCOPE_TABLE* scopeTable =
+ (SCOPE_TABLE*)((UINT64)&unwindInfo->UnwindCode[(unwindInfo->CountOfCodes + 1) & ~1] +
+ sizeof(UINT32));
+
+ for (UINT32 e = 0; e < scopeTable->Count; ++e) {
+ SCOPE_RECORD* scopeRecord = &scopeTable->ScopeRecords[e];
+
+ if (rva >= scopeRecord->BeginAddress && rva < scopeRecord->EndAddress) {
+ *rip = (UINT64)&__ImageBase + scopeRecord->JumpTarget;
+ return;
+ }
+ }
+ }
+ */
}
namespace idt
@@ -15,7 +50,7 @@ namespace idt
result.segment_selector = readcs();
result.gate_type = SEGMENT_DESCRIPTOR_TYPE_INTERRUPT_GATE;
result.present = true;
- result.ist_index = ist_index;
+ result.ist_index = NULL;
result.dpl = 0;
result.offset_high = idt_handler.offset_high;
diff --git a/idt.hpp b/idt.hpp
index 15c12c4..7aec693 100644
--- a/idt.hpp
+++ b/idt.hpp
@@ -1,8 +1,9 @@
#pragma once
#include "hv_types.hpp"
#include "segment_intrin.h"
-#pragma section(".idt", read, write)
+#include "debug.hpp"
+#pragma section(".idt", read, write)
extern "C" void __gp_handler(void);
extern "C" void __pf_handler(void);
extern "C" void __de_handler(void);
@@ -14,5 +15,6 @@ namespace idt
inline hv::idt_entry_t table[256];
inline void* image_base = nullptr; // used for SEH...
enum ist_idx : u8 { gp = 5, pf = 6, de = 7};
+
auto create_entry(hv::idt_addr_t idt_handler, u8 ist_index) -> hv::idt_entry_t;
}
\ No newline at end of file
diff --git a/idt_handlers.asm b/idt_handlers.asm
index 96019e3..ff0c7b9 100644
--- a/idt_handlers.asm
+++ b/idt_handlers.asm
@@ -4,7 +4,6 @@ extern seh_handler : proc
__pf_handler proc
__de_handler proc
__gp_handler proc
- int 3
push rax
push rbx
push rcx
diff --git a/vmcs.cpp b/vmcs.cpp
index c6060a2..492f208 100644
--- a/vmcs.cpp
+++ b/vmcs.cpp
@@ -17,7 +17,7 @@ namespace vmcs
const auto current_vcpu =
vmxon::g_vmx_ctx->vcpus[KeGetCurrentProcessorNumber()];
- __vmx_vmwrite(VMCS_HOST_GDTR_BASE, reinterpret_cast(current_vcpu->gdt));
+ __vmx_vmwrite(VMCS_HOST_GDTR_BASE, gdt_value.base_address);
__vmx_vmwrite(VMCS_HOST_IDTR_BASE, reinterpret_cast(idt::table));
segment_selector es{ reades() };
diff --git a/vmxexit_handler.h b/vmxexit_handler.h
index 5a818b3..e5b5ae3 100644
--- a/vmxexit_handler.h
+++ b/vmxexit_handler.h
@@ -1,5 +1,6 @@
#pragma once
#include "hv_types.hpp"
+#include "debug.hpp"
#include "invd.hpp"
extern "C" auto vmxexit_handler() -> void;