FcdVmxDriverEntry Initialize the fake debug registers using the current state of the guest's debug registers. We must perform this initialization after the processor executes the VMON instruction, but before the processor executes the VMXLAUNCH instruction. If the facade is initialized outside of this window then there is a race between the initilization of the facade debug registers and any Mov
| 176 | // MovDr VM exit. |
| 177 | // |
| 178 | _Use_decl_annotations_ |
| 179 | VOID |
| 180 | FcdVmxDriverEntry() |
| 181 | { |
| 182 | // |
| 183 | // Use the CR4 of the host in case the guest CR4 is being virtualized. |
| 184 | // |
| 185 | Cr4 HostCr4 = {UtilVmRead(VmcsField::kHostCr4)}; |
| 186 | ULONG CurrentProcessor = KeGetCurrentProcessorNumberEx(NULL); |
| 187 | PFCD_PROCESSOR_STATE pFacade = NULL; |
| 188 | |
| 189 | pFacade = &g_FacadeManager.Processors[CurrentProcessor]; |
| 190 | |
| 191 | pFacade->DebugRegisters[0] = __readdr(0); |
| 192 | pFacade->DebugRegisters[1] = __readdr(1); |
| 193 | pFacade->DebugRegisters[2] = __readdr(2); |
| 194 | pFacade->DebugRegisters[3] = __readdr(3); |
| 195 | |
| 196 | // TODO Refactor this code to reflect the updates to VmmpHandleDrAccess. |
| 197 | |
| 198 | // |
| 199 | // If debug extensions are enabled (CR4.DE = 1), accessing DR4 and/or DR5 |
| 200 | // cause an invalid-opcode exception. |
| 201 | // |
| 202 | if (HostCr4.fields.de) |
| 203 | { |
| 204 | pFacade->DebugRegisters[4] = 0; |
| 205 | pFacade->DebugRegisters[5] = 0; |
| 206 | } |
| 207 | else |
| 208 | { |
| 209 | pFacade->DebugRegisters[4] = __readdr(4); |
| 210 | pFacade->DebugRegisters[5] = __readdr(5); |
| 211 | } |
| 212 | |
| 213 | pFacade->DebugRegisters[6] = __readdr(6); |
| 214 | pFacade->DebugRegisters[7] = UtilVmRead(VmcsField::kGuestDr7); |
| 215 | |
| 216 | pFacade->Initialized = TRUE; |
| 217 | } |
| 218 | |
| 219 | |
| 220 | // |
no test coverage detected