HyperDbg Debugger
Loading...
Searching...
No Matches
IdtEmulation.c File Reference

Handlers of Guest's IDT Emulator. More...

#include "pch.h"

Functions

VOID IdtEmulationCreateInterruptGate (PVOID Handler, SEGMENT_DESCRIPTOR_INTERRUPT_GATE_64 *Entry)
 Create an interrupt gate that points to the supplied interrupt handler.
 
VOID IdtEmulationPrepareHostIdt (_Inout_ VIRTUAL_MACHINE_STATE *VCpu)
 Prepare Host IDT.
 
VOID IdtEmulationhandleHostInterrupt (_Inout_ INTERRUPT_TRAP_FRAME *IntrTrapFrame)
 Handle Page-fault exception bitmap VM-exits.
 
VOID IdtEmulationHandlePageFaults (_Inout_ VIRTUAL_MACHINE_STATE *VCpu, _In_ VMEXIT_INTERRUPT_INFORMATION InterruptExit)
 Handle Page-fault exception bitmap VM-exits.
 
VOID IdtEmulationHandleExceptionAndNmi (_Inout_ VIRTUAL_MACHINE_STATE *VCpu, _In_ VMEXIT_INTERRUPT_INFORMATION InterruptExit)
 Handle NMI and exception vm-exits.
 
BOOLEAN IdtEmulationInjectInterruptWhenInterruptWindowIsOpen (_Inout_ VIRTUAL_MACHINE_STATE *VCpu, _In_ VMEXIT_INTERRUPT_INFORMATION InterruptExit)
 if the guest is not interruptible, then we save the details of each interrupt so we can re-inject them to the guest whenever the interrupt window is open
 
VOID IdtEmulationHandleExternalInterrupt (_Inout_ VIRTUAL_MACHINE_STATE *VCpu, _In_ VMEXIT_INTERRUPT_INFORMATION InterruptExit)
 external-interrupt vm-exit handler
 
VOID IdtEmulationHandleNmiWindowExiting (_Inout_ VIRTUAL_MACHINE_STATE *VCpu)
 Handle NMI-window exitings.
 
BOOLEAN IdtEmulationInjectPageFaultWhenInterruptWindowsIsOpen (_Inout_ VIRTUAL_MACHINE_STATE *VCpu)
 Injects a page-fault when interrupt window is open.
 
VOID IdtEmulationHandleInterruptWindowExiting (_Inout_ VIRTUAL_MACHINE_STATE *VCpu)
 Handle interrupt-window exitings.
 

Detailed Description

Handlers of Guest's IDT Emulator.

Author
Sina Karvandi (sina@.nosp@m.hype.nosp@m.rdbg..nosp@m.org)
Version
0.1
Date
2020-06-10

Function Documentation

◆ IdtEmulationCreateInterruptGate()

VOID IdtEmulationCreateInterruptGate ( PVOID Handler,
SEGMENT_DESCRIPTOR_INTERRUPT_GATE_64 * Entry )

Create an interrupt gate that points to the supplied interrupt handler.

Parameters
VCpuThe virtual processor's state
Entry
Returns
VOID
24{
25 // SEGMENT_SELECTOR HostCsSelector = {0, 0, 1};
26 //
27 // Entry->InterruptStackTable = 0;
28 // Entry->SegmentSelector = HostCsSelector.AsUInt;
29 // Entry->MustBeZero0 = 0;
30 // Entry->Type = SEGMENT_DESCRIPTOR_TYPE_INTERRUPT_GATE;
31 // Entry->MustBeZero1 = 0;
32 // Entry->DescriptorPrivilegeLevel = 0;
33 // Entry->Present = 1;
34 // Entry->Reserved = 0;
35
36 UINT64 Offset = (UINT64)Handler;
37 Entry->OffsetLow = (Offset >> 0) & 0xFFFF;
38 Entry->OffsetMiddle = (Offset >> 16) & 0xFFFF;
39 Entry->OffsetHigh = (Offset >> 32) & 0xFFFFFFFF;
40
41#if USE_INTERRUPT_STACK_TABLE == TRUE
42
43 //
44 // Use first index (IST1)
45 //
46 Entry->InterruptStackTable = 1;
47
48#else
49
50 //
51 // Make sure to unset IST since we didn't use a separate stack pointer
52 // on TSS entry at GDT
53 //
54 Entry->InterruptStackTable = 0;
55
56#endif // USE_INTERRUPT_STACK_TABLE == TRUE
57}
unsigned __int64 UINT64
Definition BasicTypes.h:21

◆ IdtEmulationHandleExceptionAndNmi()

VOID IdtEmulationHandleExceptionAndNmi ( _Inout_ VIRTUAL_MACHINE_STATE * VCpu,
_In_ VMEXIT_INTERRUPT_INFORMATION InterruptExit )

Handle NMI and exception vm-exits.

Parameters
VCpuThe virtual processor's state
InterruptExitinterrupt exit information
Returns
VOID
259{
260 //
261 // Exception or non-maskable interrupt (NMI). Either:
262 // 1: Guest software caused an exception and the bit in the exception bitmap associated with exception's vector was set to 1
263 // 2: An NMI was delivered to the logical processor and the "NMI exiting" VM-execution control was 1.
264 //
265 // VMCS_VMEXIT_INTERRUPTION_INFORMATION shows the exit information about event that occurred and causes this exit
266 // Don't forget to read VMCS_VMEXIT_INTERRUPTION_ERROR_CODE in the case of re-injectiong event
267 //
268
269 switch (InterruptExit.Vector)
270 {
272
273 //
274 // Handle software breakpoints
275 //
276 {
277 UINT64 GuestRip = NULL64_ZERO;
278 BYTE TargetMem = NULL_ZERO;
279
280 __vmx_vmread(VMCS_GUEST_RIP, &GuestRip);
281 MemoryMapperReadMemorySafe(GuestRip, &TargetMem, sizeof(BYTE));
282 if (!EptCheckAndHandleBreakpoint(VCpu) || TargetMem == 0xcc)
283 {
285 {
286 //
287 // Don't increment rip
288 //
290
291 //
292 // Kernel debugger (debugger-mode) is not attached, re-inject the breakpoint
293 //
295 }
296 }
297 }
298
299 break;
300
302
303 //
304 // Handle the #UD, checking if this exception was intentional.
305 //
306 if (!SyscallHookHandleUD(VCpu))
307 {
308 //
309 // If this #UD was found to be unintentional, inject a #UD interruption into the guest.
310 //
312 }
313
314 break;
315
317
318 //
319 // Handle page-faults (#PFs)
320 //
321 IdtEmulationHandlePageFaults(VCpu, InterruptExit);
322
323 break;
324
326
328 {
329 //
330 // It's not because of thread change detection, so re-inject it
331 //
332 EventInjectInterruptOrException(InterruptExit);
333 }
334
335 break;
336
338
339 if (VCpu->EnableExternalInterruptsOnContinue ||
340 VCpu->EnableExternalInterruptsOnContinueMtf ||
341 VCpu->RegisterBreakOnMtf)
342 {
343 //
344 // Ignore the nmi
345 //
346 }
347 else
348 {
349 //
350 // Re-inject the interrupt/exception because it doesn't relate to us
351 //
352 EventInjectInterruptOrException(InterruptExit);
353 }
354
355 break;
356
357 default:
358
359 //
360 // Re-inject the interrupt/exception, nothing special to handle
361 //
362 EventInjectInterruptOrException(InterruptExit);
363
364 break;
365 }
366}
#define NULL_ZERO
Definition BasicTypes.h:51
unsigned char BYTE
Definition BasicTypes.h:24
#define NULL64_ZERO
Definition BasicTypes.h:52
BOOLEAN DebuggingCallbackHandleDebugBreakpointException(UINT32 CoreId)
routine callback to handle debug breakpoint exception
Definition Callback.c:360
BOOLEAN DebuggingCallbackHandleBreakpointException(UINT32 CoreId)
routine callback to handle breakpoint exception
Definition Callback.c:339
_Use_decl_annotations_ BOOLEAN SyscallHookHandleUD(VIRTUAL_MACHINE_STATE *VCpu)
Detect whether the #UD was because of Syscall or Sysret or not.
Definition EferHook.c:228
BOOLEAN EptCheckAndHandleBreakpoint(VIRTUAL_MACHINE_STATE *VCpu)
Check if the breakpoint vm-exit relates to EPT hook or not.
Definition Ept.c:1211
VOID EventInjectInterruptOrException(_In_ VMEXIT_INTERRUPT_INFORMATION InterruptExit)
re-inject interrupt or exception to the guest
Definition Events.c:155
VOID EventInjectUndefinedOpcode(VIRTUAL_MACHINE_STATE *VCpu)
Inject #UD to the guest (Invalid Opcode - Undefined Opcode)
Definition Events.c:79
VOID EventInjectBreakpoint()
Inject #BP to the guest (Event Injection)
Definition Events.c:46
VOID HvSuppressRipIncrement(VIRTUAL_MACHINE_STATE *VCpu)
Suppress the incrementation of RIP.
Definition Hv.c:324
VOID IdtEmulationHandlePageFaults(_Inout_ VIRTUAL_MACHINE_STATE *VCpu, _In_ VMEXIT_INTERRUPT_INFORMATION InterruptExit)
Handle Page-fault exception bitmap VM-exits.
Definition IdtEmulation.c:209
_Use_decl_annotations_ BOOLEAN MemoryMapperReadMemorySafe(UINT64 VaAddressToRead, PVOID BufferToSaveMemory, SIZE_T SizeToRead)
Read memory safely by mapping the buffer (It's a wrapper)
Definition MemoryMapper.c:1101
@ EXCEPTION_VECTOR_UNDEFINED_OPCODE
Definition Events.h:30
@ EXCEPTION_VECTOR_NMI
Definition Events.h:26
@ EXCEPTION_VECTOR_DEBUG_BREAKPOINT
Definition Events.h:25
@ EXCEPTION_VECTOR_PAGE_FAULT
Definition Events.h:38
@ EXCEPTION_VECTOR_BREAKPOINT
Definition Events.h:27

◆ IdtEmulationHandleExternalInterrupt()

VOID IdtEmulationHandleExternalInterrupt ( _Inout_ VIRTUAL_MACHINE_STATE * VCpu,
_In_ VMEXIT_INTERRUPT_INFORMATION InterruptExit )

external-interrupt vm-exit handler

Parameters
VCpuThe virtual processor's state
InterruptExitinterrupt info from vm-exit
Returns
VOID
417{
418 BOOLEAN Interruptible = TRUE;
419 VMX_INTERRUPTIBILITY_STATE InterruptibilityState = {0};
420 RFLAGS GuestRflags = {0};
421
422 //
423 // In order to enable External Interrupt Exiting we have to set
424 // PIN_BASED_VM_EXECUTION_CONTROLS_EXTERNAL_INTERRUPT in vmx
425 // pin-based controls (PIN_BASED_VM_EXEC_CONTROL) and also
426 // we should enable VM_EXIT_ACK_INTR_ON_EXIT on vmx vm-exit
427 // controls (VMCS_CTRL_VMEXIT_CONTROLS), also this function might not
428 // always be successful if the guest is not in the interruptible
429 // state so it wait for and interrupt-window exiting to re-inject
430 // the interrupt into the guest
431 //
432 if (VCpu->EnableExternalInterruptsOnContinue ||
433 VCpu->EnableExternalInterruptsOnContinueMtf)
434 {
435 //
436 // Ignore the interrupt as it's suppressed because of instrumentation step-in
437 //
438
439 //
440 // During developing HyperDbg, we realized that if we just ignore the interrupts completely
441 // while we are waiting on 'i' instrumentation step-in command, then the serial device becomes
442 // unresponsive, to solve this issue we hold the details of interrupts so we can re-inject
443 // and process them when we decide to continue the debuggee (guest interrupt windows is open)
444 // this way, the serial device works normally and won't become unresponsive
445 //
447
448 //
449 // avoid incrementing rip
450 //
452 }
453
454 else if (InterruptExit.Valid && InterruptExit.InterruptionType == INTERRUPT_TYPE_EXTERNAL_INTERRUPT)
455 {
456 VmxVmread64P(VMCS_GUEST_RFLAGS, &GuestRflags.AsUInt);
457 VmxVmread32P(VMCS_GUEST_INTERRUPTIBILITY_STATE, &InterruptibilityState.AsUInt);
458
459 //
460 // External interrupts cannot be injected into the
461 // guest if guest isn't interruptible (e.g.: guest
462 // is blocked by "mov ss", or EFLAGS.IF == 0).
463 //
464 Interruptible = GuestRflags.InterruptEnableFlag && !InterruptibilityState.BlockingByMovSs;
465
466 if (Interruptible)
467 {
468 //
469 // Re-inject the interrupt/exception
470 //
471 EventInjectInterruptOrException(InterruptExit);
472 }
473 else
474 {
475 //
476 // We can't inject interrupt because the guest's state is not interruptible
477 // we have to queue it an re-inject it when the interrupt window is opened!
478 //
480
481 //
482 // Enable Interrupt-window exiting.
483 //
485 }
486
487 //
488 // avoid incrementing rip
489 //
491 }
492 else
493 {
494 Interruptible = FALSE;
495
496 LogError("Err, why we are here? it's a vm-exit due to the external"
497 "interrupt and its type is not external interrupt? weird!");
498 }
499}
UCHAR BOOLEAN
Definition BasicTypes.h:39
#define TRUE
Definition BasicTypes.h:55
#define FALSE
Definition BasicTypes.h:54
VOID HvSetInterruptWindowExiting(BOOLEAN Set)
Set Interrupt-window exiting.
Definition Hv.c:606
#define LogError(format,...)
Log in the case of error.
Definition HyperDbgHyperLogIntrinsics.h:113
BOOLEAN IdtEmulationInjectInterruptWhenInterruptWindowIsOpen(_Inout_ VIRTUAL_MACHINE_STATE *VCpu, _In_ VMEXIT_INTERRUPT_INFORMATION InterruptExit)
if the guest is not interruptible, then we save the details of each interrupt so we can re-inject the...
Definition IdtEmulation.c:378
UCHAR VmxVmread64P(size_t Field, UINT64 *FieldValue)
VMX VMREAD instruction (64-bit)
Definition Vmx.c:72
UCHAR VmxVmread32P(size_t Field, UINT32 *FieldValue)
VMX VMREAD instruction (32-bit)
Definition Vmx.c:86
@ INTERRUPT_TYPE_EXTERNAL_INTERRUPT
Definition Events.h:50

◆ IdtEmulationhandleHostInterrupt()

VOID IdtEmulationhandleHostInterrupt ( _Inout_ INTERRUPT_TRAP_FRAME * IntrTrapFrame)

Handle Page-fault exception bitmap VM-exits.

Parameters
VCpuThe virtual processor's state
InterruptExitinterrupt exit information
Returns
VOID
140{
141 UINT64 PageFaultCr2;
142 ULONG CurrentCore;
143 CurrentCore = KeGetCurrentProcessorNumberEx(NULL);
144 VIRTUAL_MACHINE_STATE * VCpu = &g_GuestState[CurrentCore];
145
146 //
147 // Store the latest exception vector
148 //
149 VCpu->LastExceptionOccuredInHost = IntrTrapFrame->vector;
150
151 switch (IntrTrapFrame->vector)
152 {
154
155 //
156 // host NMIs
157 //
158 // LogInfo("NMI received!");
159
160 //
161 // Check if NMI needs to be injected back to the guest or not
162 // Trap frame is sent because as this function unreference this
163 // parameter, NULL cannot be sent
164 //
165 if (!VmxBroadcastHandleNmiCallback((PVOID)IntrTrapFrame, FALSE))
166 {
167 //
168 // Inject NMI when the NMI Window opened
169 //
171 }
172
173 break;
174
176
177 //
178 // host page-fault
179 //
180 PageFaultCr2 = __readcr2();
181
182 LogInfo("Page-fault received, CR2: %llx", PageFaultCr2);
183
184 break;
185
186 default:
187
188 //
189 // host exceptions
190 //
191 LogInfo("Host exception, RIP=%llx, RSP=%llx, Vector=%x",
192 IntrTrapFrame->rip,
193 IntrTrapFrame->rsp,
194 IntrTrapFrame->vector);
195
196 break;
197 }
198}
unsigned long ULONG
Definition BasicTypes.h:37
VIRTUAL_MACHINE_STATE * g_GuestState
Save the state and variables related to virtualization on each to logical core.
Definition GlobalVariables.h:38
VOID HvSetNmiWindowExiting(BOOLEAN Set)
Set NMI-window exiting.
Definition Hv.c:714
#define LogInfo(format,...)
Define log variables.
Definition HyperDbgHyperLogIntrinsics.h:71
BOOLEAN VmxBroadcastHandleNmiCallback(PVOID Context, BOOLEAN Handled)
Handles NMIs in kernel-mode.
Definition VmxBroadcast.c:92
The status of each core after and before VMX.
Definition State.h:290
UINT8 LastExceptionOccuredInHost
Definition State.h:332

◆ IdtEmulationHandleInterruptWindowExiting()

VOID IdtEmulationHandleInterruptWindowExiting ( _Inout_ VIRTUAL_MACHINE_STATE * VCpu)

Handle interrupt-window exitings.

Parameters
VCpuThe virtual processor's state
Returns
VOID
566{
567 VMEXIT_INTERRUPT_INFORMATION InterruptExit = {0};
568 BOOLEAN InjectPageFault = FALSE;
569
570 //
571 // Check if page-fault needs to be injected or not
572 //
574 {
576 }
577
578 //
579 // Check if another interrupt (page-fault) needed to injected or not
580 //
581 if (!InjectPageFault)
582 {
583 for (size_t i = 0; i < PENDING_INTERRUPTS_BUFFER_CAPACITY; i++)
584 {
585 //
586 // Find an empty space
587 //
588 if (VCpu->PendingExternalInterrupts[i] != NULL_ZERO)
589 {
590 //
591 // Save it for re-injection (interrupt-window exiting)
592 //
593 InterruptExit.AsUInt = VCpu->PendingExternalInterrupts[i];
594
595 //
596 // Free the entry
597 //
598 VCpu->PendingExternalInterrupts[i] = NULL_ZERO;
599 break;
600 }
601 }
602
603 if (InterruptExit.AsUInt == 0)
604 {
605 //
606 // Nothing left in pending state, let's disable the interrupt window exiting
607 //
609 }
610 else
611 {
612 //
613 // Inject the interrupt/exception
614 //
615
616 EventInjectInterruptOrException(InterruptExit);
617 }
618 }
619
620 //
621 // avoid incrementing rip
622 //
624}
BOOLEAN g_WaitingForInterruptWindowToInjectPageFault
Shows whether the the VMM is waiting to inject a page-fault or not.
Definition GlobalVariables.h:179
BOOLEAN IdtEmulationInjectPageFaultWhenInterruptWindowsIsOpen(_Inout_ VIRTUAL_MACHINE_STATE *VCpu)
Injects a page-fault when interrupt window is open.
Definition IdtEmulation.c:528
#define PENDING_INTERRUPTS_BUFFER_CAPACITY
Pending External Interrupts Buffer Capacity.
Definition State.h:32

◆ IdtEmulationHandleNmiWindowExiting()

VOID IdtEmulationHandleNmiWindowExiting ( _Inout_ VIRTUAL_MACHINE_STATE * VCpu)

Handle NMI-window exitings.

Parameters
VCpuThe virtual processor's state
Returns
VOID
509{
510 //
511 // Inject the NMI into the guest
512 //
513 EventInjectNmi(VCpu);
514
515 //
516 // Disable NMI-window exiting since we have no more NMIs to inject
517 //
519}
VOID EventInjectNmi(VIRTUAL_MACHINE_STATE *VCpu)
Inject NMI to the guest (Event Injection)
Definition Events.c:96

◆ IdtEmulationHandlePageFaults()

VOID IdtEmulationHandlePageFaults ( _Inout_ VIRTUAL_MACHINE_STATE * VCpu,
_In_ VMEXIT_INTERRUPT_INFORMATION InterruptExit )

Handle Page-fault exception bitmap VM-exits.

Parameters
VCpuThe virtual processor's state
InterruptExitinterrupt exit information
Returns
VOID
211{
212 UINT32 ErrorCode = 0;
213 PAGE_FAULT_EXCEPTION PageFaultErrorCode = {0};
214 UINT64 PageFaultAddress = 0;
215
216 //
217 // Read the error code and exiting address
218 //
219 VmxVmread32P(VMCS_VMEXIT_INTERRUPTION_ERROR_CODE, &ErrorCode);
220 PageFaultErrorCode.AsUInt = ErrorCode;
221
222 //
223 // Read the page-fault address
224 //
225 __vmx_vmread(VMCS_EXIT_QUALIFICATION, &PageFaultAddress);
226
227 // LogInfo("#PF Fault = %016llx, Page Fault Code = 0x%x | %s%s%s%s",
228 // PageFaultAddress,
229 // PageFaultErrorCode.AsUInt,
230 // PageFaultErrorCode.Present ? "p" : "",
231 // PageFaultErrorCode.Write ? "w" : "",
232 // PageFaultErrorCode.UserModeAccess ? "u" : "",
233 // PageFaultErrorCode.Execute ? "f" : "");
234
235 // Handle page-faults
236 // Check page-fault with user-debugger
237 // The page-fault is handled through the user debugger, no need further action
238 // NOTE: THE ADDRESS SHOULD BE NULL HERE
239 //
240 if (!DebuggingCallbackConditionalPageFaultException(VCpu->CoreId, PageFaultAddress, PageFaultErrorCode.AsUInt))
241 {
242 //
243 // The #pf is not related to the debugger, re-inject it
244 //
245 EventInjectPageFaults(VCpu, InterruptExit, PageFaultAddress, PageFaultErrorCode);
246 }
247}
unsigned int UINT32
Definition BasicTypes.h:48
BOOLEAN DebuggingCallbackConditionalPageFaultException(UINT32 CoreId, UINT64 Address, UINT32 PageFaultErrorCode)
routine callback to handle conditional page-fault exception
Definition Callback.c:383
VOID EventInjectPageFaults(_Inout_ VIRTUAL_MACHINE_STATE *VCpu, _In_ VMEXIT_INTERRUPT_INFORMATION InterruptExit, _In_ UINT64 PageFaultAddress, _In_ PAGE_FAULT_EXCEPTION PageFaultCode)
inject #PFs to the guest
Definition Events.c:192

◆ IdtEmulationInjectInterruptWhenInterruptWindowIsOpen()

BOOLEAN IdtEmulationInjectInterruptWhenInterruptWindowIsOpen ( _Inout_ VIRTUAL_MACHINE_STATE * VCpu,
_In_ VMEXIT_INTERRUPT_INFORMATION InterruptExit )

if the guest is not interruptible, then we save the details of each interrupt so we can re-inject them to the guest whenever the interrupt window is open

Parameters
VCpuThe virtual processor's state
InterruptExitinterrupt info from vm-exit
Returns
BOOLEAN
380{
381 BOOLEAN FoundAPlaceForFutureInjection = FALSE;
382
383 //
384 // We can't inject interrupt because the guest's state is not interruptible
385 // we have to queue it an re-inject it when the interrupt window is opened !
386 //
387 for (size_t i = 0; i < PENDING_INTERRUPTS_BUFFER_CAPACITY; i++)
388 {
389 //
390 // Find an empty space
391 //
392 if (VCpu->PendingExternalInterrupts[i] == NULL_ZERO)
393 {
394 //
395 // Save it for future re-injection (interrupt-window exiting)
396 //
397 VCpu->PendingExternalInterrupts[i] = InterruptExit.AsUInt;
398 FoundAPlaceForFutureInjection = TRUE;
399 break;
400 }
401 }
402
403 return FoundAPlaceForFutureInjection;
404}

◆ IdtEmulationInjectPageFaultWhenInterruptWindowsIsOpen()

BOOLEAN IdtEmulationInjectPageFaultWhenInterruptWindowsIsOpen ( _Inout_ VIRTUAL_MACHINE_STATE * VCpu)

Injects a page-fault when interrupt window is open.

Parameters
VCpuThe virtual processor's state
Returns
BOOLEAN
529{
530 //
531 // Check if all the injections are done or not
532 //
534 {
536 return FALSE;
537 }
538
539 //
540 // Inject the page-fault (by cr2)
541 //
545
547 {
549 }
550 else
551 {
553 }
554
555 return TRUE;
556}
#define SIZE_2_MB
Integer 2MB.
Definition Ept.h:31
VOID EventInjectPageFaultWithCr2(VIRTUAL_MACHINE_STATE *VCpu, UINT64 Address, UINT32 PageFaultCode)
Inject page-fault with an address as cr2.
Definition Events.c:281
UINT64 g_PageFaultInjectionAddressTo
The (to) address for page-fault injection.
Definition GlobalVariables.h:191
UINT64 g_PageFaultInjectionAddressFrom
The (from) address for page-fault injection.
Definition GlobalVariables.h:185
UINT32 g_PageFaultInjectionErrorCode
The error code for page-fault injection.
Definition GlobalVariables.h:197
_Use_decl_annotations_ BOOLEAN MemoryMapperCheckIfPdeIsLargePageOnTargetProcess(PVOID Va)
This function checks target process to see if the PDE is a large page or not.
Definition MemoryMapper.c:525
#define PAGE_SIZE
Size of each page (4096 bytes)
Definition common.h:69

◆ IdtEmulationPrepareHostIdt()

VOID IdtEmulationPrepareHostIdt ( _Inout_ VIRTUAL_MACHINE_STATE * VCpu)

Prepare Host IDT.

Parameters
VCpuThe virtual processor's state
Returns
VOID
68{
69 SEGMENT_DESCRIPTOR_INTERRUPT_GATE_64 * VmxHostIdt = (SEGMENT_DESCRIPTOR_INTERRUPT_GATE_64 *)VCpu->HostIdt;
70 SEGMENT_DESCRIPTOR_INTERRUPT_GATE_64 * WindowsIdt = (SEGMENT_DESCRIPTOR_INTERRUPT_GATE_64 *)AsmGetIdtBase();
71
72 //
73 // Zero the memory
74 //
75 RtlZeroMemory(VmxHostIdt, HOST_IDT_DESCRIPTOR_COUNT * sizeof(SEGMENT_DESCRIPTOR_INTERRUPT_GATE_64));
76
77 //
78 // Copy OS interrupt (IDT) entries
79 //
80 RtlCopyBytes(VmxHostIdt,
81 WindowsIdt,
82 HOST_IDT_DESCRIPTOR_COUNT * sizeof(SEGMENT_DESCRIPTOR_INTERRUPT_GATE_64));
83
84 /*
85 for (size_t i = 0; i < HOST_IDT_DESCRIPTOR_COUNT; i++)
86 {
87 SEGMENT_DESCRIPTOR_INTERRUPT_GATE_64 CurrentEntry = WindowsIdt[i];
88
89 UINT64 Offset = 0;
90 Offset |= ((UINT64)CurrentEntry.OffsetLow) << 0;
91 Offset |= ((UINT64)CurrentEntry.OffsetMiddle) << 16;
92 Offset |= ((UINT64)CurrentEntry.OffsetHigh) << 32;
93
94 // LogInfo("IDT Entry [%d] at: %llx", i, Offset);
95
96 IdtEmulationCreateInterruptGate((PVOID)Offset, &VmxHostIdt[i]);
97 }
98 */
99
100 //
101 // Function related to handling host IDT are a modified version of the following project:
102 // https://github.com/jonomango/hv/blob/main/hv
103 //
104
105 //
106 // Add customize interrupt handlers
107 //
109 // IdtEmulationCreateInterruptGate((PVOID)InterruptHandler1, &VmxHostIdt[1]); // #DB
111 // IdtEmulationCreateInterruptGate((PVOID)InterruptHandler3, &VmxHostIdt[3]); // #BP
121 IdtEmulationCreateInterruptGate((PVOID)InterruptHandler14, &VmxHostIdt[14]); // #PF
128}
VOID IdtEmulationCreateInterruptGate(PVOID Handler, SEGMENT_DESCRIPTOR_INTERRUPT_GATE_64 *Entry)
Create an interrupt gate that points to the supplied interrupt handler.
Definition IdtEmulation.c:23
#define HOST_IDT_DESCRIPTOR_COUNT
Maximum number of interrupt entries in IDT.
Definition IdtEmulation.h:29
void InterruptHandler11()
The 11th entry in IDT.
void InterruptHandler7()
The 7th entry in IDT.
void InterruptHandler8()
The 8th entry in IDT.
void InterruptHandler13()
The 13th entry in IDT.
unsigned long long AsmGetIdtBase()
Get IDT base.
void InterruptHandler14()
The 14th entry in IDT.
void InterruptHandler4()
The 4th entry in IDT.
void InterruptHandler30()
The 30th entry in IDT.
void InterruptHandler5()
The 5th entry in IDT.
void InterruptHandler0()
The 0th entry in IDT.
void InterruptHandler18()
The 18th entry in IDT.
void InterruptHandler20()
The 20th entry in IDT.
void InterruptHandler16()
The 16th entry in IDT.
void InterruptHandler10()
The 10th entry in IDT.
void InterruptHandler6()
The 6th entry in IDT.
void InterruptHandler19()
The 19th entry in IDT.
void InterruptHandler2()
The 2nd entry in IDT.
void InterruptHandler17()
The 17th entry in IDT.
void InterruptHandler12()
The 12th entry in IDT.