From 8c5206f984ba082056a041297ab2d9e0b6bfc11c Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 16 Feb 2021 02:21:38 +0000 Subject: [PATCH 01/17] Update README.md --- README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4b4be43..743ad2f 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,14 @@ # Bluepill Bluepill is an Intel type-2 research hypervisor. This project is purely for educational purposes and is designed to run on Windows 10 systems. -This project uses WDK and thus Windows Kernel functions to facilitate vmxlaunch. +This project uses WDK and thus Windows Kernel functions to facilitate vmxlaunch. + +### Why Write A Hypervisor? + +Why write a hypervisor? "To learn" is the typical response, but to learn what? To learn VMX instructions? To learn how to write a windows kernel driver? To learn how to use windbg? Although all of the prior reasons to write a hypervisor are important, learning how to read highly technical documents and extract what you need from the reading material is much more valuable than all of the other stuff one might learn while writing a hypervisor. This is best summed up as the old saying goes: + +“Give a man a fish and you feed him for a day. Teach a man to fish and you feed him for a lifetime” + ### VMCS From 2b936e1247738253eac3518cf845e4772f5379f9 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 16 Feb 2021 02:22:13 +0000 Subject: [PATCH 02/17] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 743ad2f..f67605e 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ This project uses WDK and thus Windows Kernel functions to facilitate vmxlaunch. ### Why Write A Hypervisor? -Why write a hypervisor? "To learn" is the typical response, but to learn what? To learn VMX instructions? To learn how to write a windows kernel driver? To learn how to use windbg? Although all of the prior reasons to write a hypervisor are important, learning how to read highly technical documents and extract what you need from the reading material is much more valuable than all of the other stuff one might learn while writing a hypervisor. This is best summed up as the old saying goes: +Why write a type-2 Intel hypervisor? "To learn" is the typical response, but to learn what? To learn VMX instructions? To learn how to write a windows kernel driver? To learn how to use windbg? Although all of the prior reasons to write a hypervisor are important, learning how to read highly technical documents and extract what you need from the reading material is much more valuable than all of the other stuff one might learn while writing a hypervisor. This is best summed up as the old saying goes: “Give a man a fish and you feed him for a day. Teach a man to fish and you feed him for a lifetime” From 7e2691dd74864ca0e04dbf7ceeebf087df0a7b0f Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 16 Feb 2021 02:23:36 +0000 Subject: [PATCH 03/17] Update README.md --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f67605e..2bccf62 100644 --- a/README.md +++ b/README.md @@ -10,9 +10,10 @@ This project uses WDK and thus Windows Kernel functions to facilitate vmxlaunch. ### Why Write A Hypervisor? -Why write a type-2 Intel hypervisor? "To learn" is the typical response, but to learn what? To learn VMX instructions? To learn how to write a windows kernel driver? To learn how to use windbg? Although all of the prior reasons to write a hypervisor are important, learning how to read highly technical documents and extract what you need from the reading material is much more valuable than all of the other stuff one might learn while writing a hypervisor. This is best summed up as the old saying goes: +Why write a hypervisor? "To learn" is the typical response, but to learn what? To learn VMX instructions? To learn how to write a windows kernel driver? To learn how to use windbg? Although all of the prior reasons to write a hypervisor are important, learning how to read technical documents and extract what you need from the reading material is much more valuable than all of the other stuff one might learn while writing a hypervisor. This is best summed up as the old saying goes: + +> “Give a man a fish and you feed him for a day. Teach a man to fish and you feed him for a lifetime” -“Give a man a fish and you feed him for a day. Teach a man to fish and you feed him for a lifetime” ### VMCS From eabdf7c1319e13a948e28c2d5429cdecda404eef Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 16 Feb 2021 02:24:17 +0000 Subject: [PATCH 04/17] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2bccf62..a0f4a47 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ This project uses WDK and thus Windows Kernel functions to facilitate vmxlaunch. ### Why Write A Hypervisor? -Why write a hypervisor? "To learn" is the typical response, but to learn what? To learn VMX instructions? To learn how to write a windows kernel driver? To learn how to use windbg? Although all of the prior reasons to write a hypervisor are important, learning how to read technical documents and extract what you need from the reading material is much more valuable than all of the other stuff one might learn while writing a hypervisor. This is best summed up as the old saying goes: +Why write a type-2 (Intel or AMD) hypervisor? "To learn" is the typical response, but to learn what? To learn VMX instructions? To learn how to write a windows kernel driver? To learn how to use windbg? Although all of the prior reasons to write a hypervisor are important, learning how to read technical documents and extract what you need from the reading material is much more valuable than all of the other stuff one might learn while writing a hypervisor. This is best summed up as the old saying goes: > “Give a man a fish and you feed him for a day. Teach a man to fish and you feed him for a lifetime” From 9fc83dc20ca4b4b0cd96269f93484de1a9b94edc Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 16 Feb 2021 02:35:32 +0000 Subject: [PATCH 05/17] Update README.md --- README.md | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a0f4a47..abd1a99 100644 --- a/README.md +++ b/README.md @@ -14,8 +14,6 @@ Why write a type-2 (Intel or AMD) hypervisor? "To learn" is the typical response > “Give a man a fish and you feed him for a day. Teach a man to fish and you feed him for a lifetime” - - ### VMCS This section of the readme just contains notes and a list of things I stumbled on and took me a while to figure out and fix. @@ -32,4 +30,29 @@ see exactly what the MSR masks are, and what VMCS field's are enabled after you * After getting my first vmexit the exit reason was 0x80000021 (invalid guest state). I thought it was segmentation code since I've never done anything with segments before but after a few days of checking every single segment check in chapter 26 section 3, I continued reading the guest requirements in chapter 24 section 4, part 2 goes over non-register states and I was not setting `VMCS_GUEST_ACTIVITY_STATE` to zero. -Dump of VMCS guest fields can be found [here](https://githacks.org/_xeroxz/bluepill/-/blob/master/VMCS-GUEST.md). \ No newline at end of file +Dump of VMCS guest fields can be found [here](https://githacks.org/_xeroxz/bluepill/-/blob/master/VMCS-GUEST.md). + +### Host State Information + +Bluepill has its "own" GDT, TSS, IDT, and address space. However, in order to allow for windbg usage, some interrupt handlers +forward to guest controlled interrupt handlers such as #DB and interrupt handler three. The host GDT also contains a unique TR base (TSS), which contains three new interrupt stacks. +These stacks are used by bluepills interrupt routines. This is not required at all but I felt I should go the extra mile here and setup dedicated stacks for my interrupt handlers in the +off chance that RSP contains an invalid address when a page fault, division error, or general protection error happens. + +##### GDT + +The host GDT is 1:1 with the guest GDT except firstly, a different, host controlled page is used for each cores GDT. Secondly the TR segment base address is updated to reflect +the new TSS (which is also 1:1 with the guest TSS but on a new page). + +```cpp +segment_descriptor_register_64 gdt_value; +_sgdt(&gdt_value); + +// the GDT can be 65536 bytes large +// but on windows its less then a single page (4kb) +// ... +// also note each logical processor gets its own GDT... +memcpy(vcpu->gdt, (void*)gdt_value.base_address, PAGE_SIZE); +``` + +##### TSS \ No newline at end of file From f37b615dd644f82ea1f12dd5b7303b6fff5866cd Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 16 Feb 2021 02:50:33 +0000 Subject: [PATCH 06/17] Update README.md --- README.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index abd1a99..37513c7 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ forward to guest controlled interrupt handlers such as #DB and interrupt handler These stacks are used by bluepills interrupt routines. This is not required at all but I felt I should go the extra mile here and setup dedicated stacks for my interrupt handlers in the off chance that RSP contains an invalid address when a page fault, division error, or general protection error happens. -##### GDT +##### GDT - Global Descriptor Table The host GDT is 1:1 with the guest GDT except firstly, a different, host controlled page is used for each cores GDT. Secondly the TR segment base address is updated to reflect the new TSS (which is also 1:1 with the guest TSS but on a new page). @@ -55,4 +55,12 @@ _sgdt(&gdt_value); memcpy(vcpu->gdt, (void*)gdt_value.base_address, PAGE_SIZE); ``` -##### TSS \ No newline at end of file +##### TSS - Task State Segment + +The host TSS is 1:1 with the guest TSS except that there are additional interrupt stack table entries. When an exception happens and execution is redirected to an interrupt handler, the address +in RSP cannot ***always*** be trusted. Therefore, ***especially*** on privilege level changes, RSP will be changed with a predetermined valid stack (which is located in the TSS). However if an exception happens and there is no privilege change (say you have an exception in ring-0), +RSP ***might not*** need to be changed as there is not a risk of privilege escalation. An OS (and type-2 hypervisor) designer can determine how they want RSP to be handled by the CPU by configuring interrupt descriptor table entries accordingly. In an interrupt descriptor table entry there is a bit field for interrupt stack table index. + +###### IST - Interrupt Stack Table +This interrupt stack table is located inside of the TSS. Bluepill interrupt routines have their own stack, this is the only change done to the TSS. IST entries zero through three are used by windows interrupt routines and entries four through six are used by Bluepill. + From e640573a773eebb5aab4e925c938a19677536042 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 16 Feb 2021 02:53:11 +0000 Subject: [PATCH 07/17] Update README.md --- README.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/README.md b/README.md index 37513c7..90c8f26 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,35 @@ The host TSS is 1:1 with the guest TSS except that there are additional interrup in RSP cannot ***always*** be trusted. Therefore, ***especially*** on privilege level changes, RSP will be changed with a predetermined valid stack (which is located in the TSS). However if an exception happens and there is no privilege change (say you have an exception in ring-0), RSP ***might not*** need to be changed as there is not a risk of privilege escalation. An OS (and type-2 hypervisor) designer can determine how they want RSP to be handled by the CPU by configuring interrupt descriptor table entries accordingly. In an interrupt descriptor table entry there is a bit field for interrupt stack table index. +```cpp +segment_descriptor_register_64 gdt_value; +_sgdt(&gdt_value); + +const auto [tr_descriptor, tr_rights, tr_limit, tr_base] = + gdt::get_info(gdt_value, segment_selector{ readtr() }); + +// copy windows TSS into new TSS... +memcpy(&vcpu->tss, (void*)tr_base, sizeof hv::tss64); +``` + ###### IST - Interrupt Stack Table This interrupt stack table is located inside of the TSS. Bluepill interrupt routines have their own stack, this is the only change done to the TSS. IST entries zero through three are used by windows interrupt routines and entries four through six are used by Bluepill. +```cpp +vcpu->tss.interrupt_stack_table[idt::ist_idx::pf] = + reinterpret_cast(ExAllocatePool(NonPagedPool, + PAGE_SIZE * HOST_STACK_PAGES)) + (PAGE_SIZE * HOST_STACK_PAGES); + +vcpu->tss.interrupt_stack_table[idt::ist_idx::gp] = + reinterpret_cast(ExAllocatePool(NonPagedPool, + PAGE_SIZE * HOST_STACK_PAGES)) + (PAGE_SIZE * HOST_STACK_PAGES); + +vcpu->tss.interrupt_stack_table[idt::ist_idx::de] = + reinterpret_cast(ExAllocatePool(NonPagedPool, + PAGE_SIZE * HOST_STACK_PAGES)) + (PAGE_SIZE * HOST_STACK_PAGES); + +vcpu->gdt[segment_selector{ readtr() }.idx].base_address_upper = tss.upper; +vcpu->gdt[segment_selector{ readtr() }.idx].base_address_high = tss.high; +vcpu->gdt[segment_selector{ readtr() }.idx].base_address_middle = tss.middle; +vcpu->gdt[segment_selector{ readtr() }.idx].base_address_low = tss.low; +``` \ No newline at end of file From f2a58cf04eb4f24cdf39fd678d83ba24144f3913 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 16 Feb 2021 02:54:16 +0000 Subject: [PATCH 08/17] Update README.md --- README.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 90c8f26..6f8899c 100644 --- a/README.md +++ b/README.md @@ -76,20 +76,18 @@ memcpy(&vcpu->tss, (void*)tr_base, sizeof hv::tss64); This interrupt stack table is located inside of the TSS. Bluepill interrupt routines have their own stack, this is the only change done to the TSS. IST entries zero through three are used by windows interrupt routines and entries four through six are used by Bluepill. ```cpp +// host page fault interrupt stack... vcpu->tss.interrupt_stack_table[idt::ist_idx::pf] = reinterpret_cast(ExAllocatePool(NonPagedPool, PAGE_SIZE * HOST_STACK_PAGES)) + (PAGE_SIZE * HOST_STACK_PAGES); +// host general protection interrupt stack... vcpu->tss.interrupt_stack_table[idt::ist_idx::gp] = reinterpret_cast(ExAllocatePool(NonPagedPool, PAGE_SIZE * HOST_STACK_PAGES)) + (PAGE_SIZE * HOST_STACK_PAGES); +// host division error interrupt stack... vcpu->tss.interrupt_stack_table[idt::ist_idx::de] = reinterpret_cast(ExAllocatePool(NonPagedPool, PAGE_SIZE * HOST_STACK_PAGES)) + (PAGE_SIZE * HOST_STACK_PAGES); - -vcpu->gdt[segment_selector{ readtr() }.idx].base_address_upper = tss.upper; -vcpu->gdt[segment_selector{ readtr() }.idx].base_address_high = tss.high; -vcpu->gdt[segment_selector{ readtr() }.idx].base_address_middle = tss.middle; -vcpu->gdt[segment_selector{ readtr() }.idx].base_address_low = tss.low; ``` \ No newline at end of file From f1314b67786e94c3840a979b25b62611b7100bdc Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 16 Feb 2021 02:58:08 +0000 Subject: [PATCH 09/17] Update README.md --- README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6f8899c..c6a242b 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ forward to guest controlled interrupt handlers such as #DB and interrupt handler These stacks are used by bluepills interrupt routines. This is not required at all but I felt I should go the extra mile here and setup dedicated stacks for my interrupt handlers in the off chance that RSP contains an invalid address when a page fault, division error, or general protection error happens. -##### GDT - Global Descriptor Table +#### GDT - Global Descriptor Table The host GDT is 1:1 with the guest GDT except firstly, a different, host controlled page is used for each cores GDT. Secondly the TR segment base address is updated to reflect the new TSS (which is also 1:1 with the guest TSS but on a new page). @@ -55,7 +55,7 @@ _sgdt(&gdt_value); memcpy(vcpu->gdt, (void*)gdt_value.base_address, PAGE_SIZE); ``` -##### TSS - Task State Segment +###### TSS - Task State Segment The host TSS is 1:1 with the guest TSS except that there are additional interrupt stack table entries. When an exception happens and execution is redirected to an interrupt handler, the address in RSP cannot ***always*** be trusted. Therefore, ***especially*** on privilege level changes, RSP will be changed with a predetermined valid stack (which is located in the TSS). However if an exception happens and there is no privilege change (say you have an exception in ring-0), @@ -90,4 +90,6 @@ vcpu->tss.interrupt_stack_table[idt::ist_idx::gp] = vcpu->tss.interrupt_stack_table[idt::ist_idx::de] = reinterpret_cast(ExAllocatePool(NonPagedPool, PAGE_SIZE * HOST_STACK_PAGES)) + (PAGE_SIZE * HOST_STACK_PAGES); -``` \ No newline at end of file +``` + +#### IDT - Interrupt Descriptor Table \ No newline at end of file From fdf55cec959e624dfd27089bc005459223bd195a Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 16 Feb 2021 03:00:02 +0000 Subject: [PATCH 10/17] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c6a242b..061c24f 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ This project uses WDK and thus Windows Kernel functions to facilitate vmxlaunch. Why write a type-2 (Intel or AMD) hypervisor? "To learn" is the typical response, but to learn what? To learn VMX instructions? To learn how to write a windows kernel driver? To learn how to use windbg? Although all of the prior reasons to write a hypervisor are important, learning how to read technical documents and extract what you need from the reading material is much more valuable than all of the other stuff one might learn while writing a hypervisor. This is best summed up as the old saying goes: -> “Give a man a fish and you feed him for a day. Teach a man to fish and you feed him for a lifetime” +> “give a man a fish, he will feed himself for a day, teach a man to read the manual and he will make a hypervisor” - or something like that... ### VMCS From ff4677c59596fb92e1b08f05e2973a7939db5011 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 16 Feb 2021 03:00:24 +0000 Subject: [PATCH 11/17] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 061c24f..c4133a5 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ This project uses WDK and thus Windows Kernel functions to facilitate vmxlaunch. Why write a type-2 (Intel or AMD) hypervisor? "To learn" is the typical response, but to learn what? To learn VMX instructions? To learn how to write a windows kernel driver? To learn how to use windbg? Although all of the prior reasons to write a hypervisor are important, learning how to read technical documents and extract what you need from the reading material is much more valuable than all of the other stuff one might learn while writing a hypervisor. This is best summed up as the old saying goes: -> “give a man a fish, he will feed himself for a day, teach a man to read the manual and he will make a hypervisor” - or something like that... +> “give a man a fish, he will feed himself for a day, teach a man to read the manual and he will make a hypervisor” ### VMCS From 76debbfcb5702c79f1bb8ed93ae92521cf6eb77d Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 16 Feb 2021 03:20:16 +0000 Subject: [PATCH 12/17] Update README.md --- README.md | 46 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index c4133a5..2c86e47 100644 --- a/README.md +++ b/README.md @@ -59,17 +59,45 @@ memcpy(vcpu->gdt, (void*)gdt_value.base_address, PAGE_SIZE); The host TSS is 1:1 with the guest TSS except that there are additional interrupt stack table entries. When an exception happens and execution is redirected to an interrupt handler, the address in RSP cannot ***always*** be trusted. Therefore, ***especially*** on privilege level changes, RSP will be changed with a predetermined valid stack (which is located in the TSS). However if an exception happens and there is no privilege change (say you have an exception in ring-0), -RSP ***might not*** need to be changed as there is not a risk of privilege escalation. An OS (and type-2 hypervisor) designer can determine how they want RSP to be handled by the CPU by configuring interrupt descriptor table entries accordingly. In an interrupt descriptor table entry there is a bit field for interrupt stack table index. +RSP ***might not*** need to be changed as there is not a risk of privilege escalation. An OS (and type-2 hypervisor) designer can determine how they want RSP to be handled by the CPU by configuring interrupt descriptor table entries accordingly. +In an interrupt descriptor table entry there is a bit field for interrupt stack table index. ```cpp -segment_descriptor_register_64 gdt_value; -_sgdt(&gdt_value); - -const auto [tr_descriptor, tr_rights, tr_limit, tr_base] = - gdt::get_info(gdt_value, segment_selector{ readtr() }); - -// copy windows TSS into new TSS... -memcpy(&vcpu->tss, (void*)tr_base, sizeof hv::tss64); +typedef struct _tss64 +{ + u32 reserved; + + // if you dont use an IST entry and there is a privilage change, + // rsp will be swapped with an address in this array... + u64 privilege_stacks[3]; + + u64 reserved_1; + u64 interrupt_stack_table[7]; + u16 reserved_2; + u16 iomap_base; +} tss64, *ptss64; + +typedef union _idt_entry_t +{ + u128 flags; + struct + { + u64 offset_low : 16; + u64 segment_selector : 16; + + // if this is zero IST isnt used, if there is no privilage change then RSP wont be changed at all, + // and if there is a privilage change then RSP is swapped with an address in the TSS (rsp0). + u64 ist_index : 3; + + u64 reserved_0 : 5; + u64 gate_type : 5; + u64 dpl : 2; + u64 present : 1; + u64 offset_middle : 16; + u64 offset_high : 32; + u64 reserved_1 : 32; + }; +} idt_entry_t, *pidt_entry_t; ``` ###### IST - Interrupt Stack Table From 7e6fdcc86b75fe5fae7f8d592ccf997298fca97c Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 16 Feb 2021 03:25:03 +0000 Subject: [PATCH 13/17] Update README.md --- README.md | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2c86e47..f001d3a 100644 --- a/README.md +++ b/README.md @@ -120,4 +120,22 @@ vcpu->tss.interrupt_stack_table[idt::ist_idx::de] = PAGE_SIZE * HOST_STACK_PAGES)) + (PAGE_SIZE * HOST_STACK_PAGES); ``` -#### IDT - Interrupt Descriptor Table \ No newline at end of file +#### IDT - Interrupt Descriptor Table + +The host IDT is 1:1 to the guest IDT except for three interrupt handlers, #PF, #DE, and #GP. These three different interrupt handlers all route to the same SEH handler function +which just changes RIP to the catch block of whatever try/except the exception happened in. This allows for page faults, general protection faults and division errors to not be handled +by guest controlled interrupt handlers. + +```cpp +// setup IDT for host.... +segment_descriptor_register_64 idt_value; +__sidt(&idt_value); + +// copy the guest IDT entries... +memcpy(idt::table, (void*)idt_value.base_address, idt_value.limit); + +// change gp, pf, and de to vmxroot handlers... +idt::table[general_protection] = idt::create_entry(hv::idt_addr_t{ __gp_handler }, idt::ist_idx::gp); +idt::table[page_fault] = idt::create_entry(hv::idt_addr_t{ __pf_handler }, idt::ist_idx::pf); +idt::table[divide_error] = idt::create_entry(hv::idt_addr_t{ __de_handler }, idt::ist_idx::de); +``` From bafdb88d3b9cd0e3a54668db397c3227ea602d60 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 16 Feb 2021 03:41:10 +0000 Subject: [PATCH 14/17] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index f001d3a..c749b0f 100644 --- a/README.md +++ b/README.md @@ -84,11 +84,11 @@ typedef union _idt_entry_t { u64 offset_low : 16; u64 segment_selector : 16; - + // if this is zero IST isnt used, if there is no privilage change then RSP wont be changed at all, // and if there is a privilage change then RSP is swapped with an address in the TSS (rsp0). - u64 ist_index : 3; - + u64 ist_index : 3; + u64 reserved_0 : 5; u64 gate_type : 5; u64 dpl : 2; @@ -97,7 +97,7 @@ typedef union _idt_entry_t u64 offset_high : 32; u64 reserved_1 : 32; }; -} idt_entry_t, *pidt_entry_t; +} idt_entry_t, * pidt_entry_t; ``` ###### IST - Interrupt Stack Table From eba172ca768959195268660775731b383d8577fb Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 16 Feb 2021 03:44:01 +0000 Subject: [PATCH 15/17] Update README.md --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index c749b0f..7171d50 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,13 @@ Bluepill is an Intel type-2 research hypervisor. This project is purely for educational purposes and is designed to run on Windows 10 systems. This project uses WDK and thus Windows Kernel functions to facilitate vmxlaunch. +##### Features + +* No EPT! +* Integration with VDM +* Hypervisor has its own GDT, TSS, IDT, and address space +* Read/Write Virtual memory example. + ### Why Write A Hypervisor? Why write a type-2 (Intel or AMD) hypervisor? "To learn" is the typical response, but to learn what? To learn VMX instructions? To learn how to write a windows kernel driver? To learn how to use windbg? Although all of the prior reasons to write a hypervisor are important, learning how to read technical documents and extract what you need from the reading material is much more valuable than all of the other stuff one might learn while writing a hypervisor. This is best summed up as the old saying goes: From 067fb972382fd6c5674678adaa90b084d55af569 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 16 Feb 2021 03:45:38 +0000 Subject: [PATCH 16/17] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 7171d50..f6ac3ff 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ This project uses WDK and thus Windows Kernel functions to facilitate vmxlaunch. * Integration with VDM * Hypervisor has its own GDT, TSS, IDT, and address space * Read/Write Virtual memory example. +* SEH in vmxroot handled by hypervisor interrupt handlers and not by guest... ### Why Write A Hypervisor? From 41367473e6c8a93a7c3351e43c61f6d58bb868d6 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 16 Feb 2021 03:46:21 +0000 Subject: [PATCH 17/17] Update README.md --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index f6ac3ff..13a79b9 100644 --- a/README.md +++ b/README.md @@ -10,11 +10,11 @@ This project uses WDK and thus Windows Kernel functions to facilitate vmxlaunch. ##### Features -* No EPT! -* Integration with VDM -* Hypervisor has its own GDT, TSS, IDT, and address space -* Read/Write Virtual memory example. -* SEH in vmxroot handled by hypervisor interrupt handlers and not by guest... +* Integration with VDM... +* Hypervisor has its own GDT, TSS, IDT, and address space... +* Read/Write Virtual memory example... +* SEH in vmxroot handled by hypervisor interrupt handlers... +* SEH works reguardless if manually mapped or loaded normally... ### Why Write A Hypervisor?