1 #include <palacios/vmm_mem.h>
2 #include <palacios/vmm.h>
3 #include <palacios/vmcb.h>
4 #include <palacios/vmm_decoder.h>
5 #include <palacios/vm_guest_mem.h>
6 #include <palacios/vmm_ctrl_regs.h>
10 extern void SerialMemDump(unsigned char *start, int n);
13 /* Segmentation is a problem here...
15 * When we get a memory operand, presumably we use the default segment (which is?)
16 * unless an alternate segment was specfied in the prefix...
22 #define PrintDebug(fmt, args...)
25 int handle_cr0_write(struct guest_info * info) {
29 switch (info->cpu_mode) {
35 PrintDebug("Real Mode write to CR0 at linear guest pa 0x%x\n",get_addr_linear(info,info->rip,&(info->segments.cs)));
37 //PrintV3Segments(info);
39 // The real rip address is actually a combination of the rip + CS base
40 ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
42 // I think we should inject a GPF into the guest
43 PrintDebug("Could not read instruction (ret=%d)\n", ret);
48 struct x86_instr dec_instr;
49 v3_decode(info, (addr_t)instr, &dec_instr);
54 while (is_prefix_byte(instr[index])) {
55 switch(instr[index]) {
56 case PREFIX_CS_OVERRIDE:
57 case PREFIX_SS_OVERRIDE:
58 case PREFIX_DS_OVERRIDE:
59 case PREFIX_ES_OVERRIDE:
60 case PREFIX_FS_OVERRIDE:
61 case PREFIX_GS_OVERRIDE:
62 PrintDebug("Segment Override!!\n");
71 if ((instr[index] == cr_access_byte) &&
72 (instr[index + 1] == lmsw_byte) &&
73 (MODRM_REG(instr[index + 2]) == lmsw_reg_byte)) {
76 addr_t second_operand;
77 struct cr0_real *real_cr0;
78 struct cr0_real *new_cr0;
79 operand_type_t addr_type;
85 real_cr0 = (struct cr0_real*)&(info->ctrl_regs.cr0);
87 addr_type = decode_operands16(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG16);
90 if (addr_type == REG_OPERAND) {
91 new_cr0 = (struct cr0_real *)first_operand;
92 } else if (addr_type == MEM_OPERAND) {
95 if (guest_pa_to_host_va(info, first_operand + (info->segments.ds.base << 4), &host_addr) == -1) {
100 new_cr0 = (struct cr0_real *)host_addr;
103 // error... don't know what to do
107 if ((new_cr0->pe == 1) && (real_cr0->pe == 0)) {
108 info->cpu_mode = PROTECTED;
109 } else if ((new_cr0->pe == 0) && (real_cr0->pe == 1)) {
110 info->cpu_mode = REAL;
113 new_cr0_val = (*(char*)(new_cr0)) & 0x0f;
116 if (info->shdw_pg_mode == SHADOW_PAGING) {
117 struct cr0_real * shadow_cr0 = (struct cr0_real*)&(info->shdw_pg_state.guest_cr0);
119 PrintDebug("Old CR0=%x, Old Shadow CR0=%x\n", *real_cr0, *shadow_cr0);
120 /* struct cr0_real is only 4 bits wide,
121 * so we can overwrite the real_cr0 without worrying about the shadow fields
123 *(char*)real_cr0 &= 0xf0;
124 *(char*)real_cr0 |= new_cr0_val;
126 *(char*)shadow_cr0 &= 0xf0;
127 *(char*)shadow_cr0 |= new_cr0_val;
130 PrintDebug("New CR0=%x, New Shadow CR0=%x\n", *real_cr0, *shadow_cr0);
132 PrintDebug("Old CR0=%x\n", *real_cr0);
133 // for now we just pass through....
134 *(char*)real_cr0 &= 0xf0;
135 *(char*)real_cr0 |= new_cr0_val;
137 PrintDebug("New CR0=%x\n", *real_cr0);
143 } else if ((instr[index] == cr_access_byte) &&
144 (instr[index + 1] == clts_byte)) {
146 PrintDebug("CLTS unhandled in CR0 write\n");
149 } else if ((instr[index] == cr_access_byte) &&
150 (instr[index + 1] = mov_to_cr_byte)) {
151 addr_t first_operand;
152 addr_t second_operand;
153 struct cr0_32 *real_cr0;
154 struct cr0_32 *new_cr0;
155 operand_type_t addr_type;
160 real_cr0 = (struct cr0_32*)&(info->ctrl_regs.cr0);
162 addr_type = decode_operands16(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
164 if (addr_type != REG_OPERAND) {
165 PrintDebug("Moving to CR0 from non-register operand in CR0 write\n");
166 /* Mov to CR0 Can only be a 32 bit register */
171 new_cr0 = (struct cr0_32 *)first_operand;
173 if (new_cr0->pe == 1) {
174 PrintDebug("Entering Protected Mode\n");
175 info->cpu_mode = PROTECTED;
178 if (new_cr0->pe == 0) {
179 PrintDebug("Entering Real Mode\n");
180 info->cpu_mode = REAL;
185 if ((new_cr0->pg == 1) && (new_cr0->pe == 1)) {
186 PrintDebug("Paging is already turned on in switch to protected mode in CR0 write\n");
188 // Actually This appears to be Ok.
189 // Why shouldn't windows be allowed to switch to real mode whenever it wants to modify its page tables?
191 info->mem_mode = VIRTUAL_MEM;
195 } else if ((new_cr0->pg == 1) && (new_cr0->pe == 0)) {
196 PrintDebug("Will the madness Never End??\n");
201 if (info->shdw_pg_mode == SHADOW_PAGING) {
202 struct cr0_32 * shadow_cr0 = (struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
204 PrintDebug("Old CR0=%x, Old Shadow CR0=%x\n", *real_cr0, *shadow_cr0);
205 *real_cr0 = *new_cr0;
209 *shadow_cr0 = *new_cr0;
212 // Setup the page tables...???
213 if (info->mem_mode == VIRTUAL_MEM) {
214 // If we aren't in paged mode then we have to preserve the identity mapped CR3
215 info->ctrl_regs.cr3 = *(addr_t*)&(info->shdw_pg_state.shadow_cr3);
218 PrintDebug("New CR0=%x, New Shadow CR0=%x\n", *real_cr0, *shadow_cr0);
220 PrintDebug("Old CR0=%x\n", *real_cr0);
221 *real_cr0 = *new_cr0;
222 PrintDebug("New CR0=%x\n", *real_cr0);
228 PrintDebug("Unsupported Instruction\n");
229 // unsupported instruction, UD the guest
242 PrintDebug("Protected %s Mode write to CR0 at guest %s linear rip 0x%x\n",
243 info->mem_mode == VIRTUAL_MEM ? "Paged" : "",
244 info->mem_mode == VIRTUAL_MEM ? "virtual" : "",
245 get_addr_linear(info, info->rip, &(info->segments.cs)));
247 // OK, now we will read the instruction
248 // The only difference between PROTECTED and PROTECTED_PG is whether we read
249 // from guest_pa or guest_va
250 if (info->mem_mode == PHYSICAL_MEM) {
251 // The real rip address is actually a combination of the rip + CS base
252 ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
254 ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
259 // I think we should inject a GPF into the guest
260 PrintDebug("Could not read instruction (ret=%d)\n", ret);
265 while (is_prefix_byte(instr[index])) {
266 switch(instr[index]) {
267 case PREFIX_CS_OVERRIDE:
268 case PREFIX_SS_OVERRIDE:
269 case PREFIX_DS_OVERRIDE:
270 case PREFIX_ES_OVERRIDE:
271 case PREFIX_FS_OVERRIDE:
272 case PREFIX_GS_OVERRIDE:
273 PrintDebug("Segment Override!!\n");
283 while (is_prefix_byte(instr[index])) {
288 struct cr0_32 * shadow_cr0 = (struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
290 struct cr0_32 * real_cr0 = (struct cr0_32*)&(info->ctrl_regs.cr0);
292 if ((instr[index] == cr_access_byte) &&
293 (instr[index + 1] == mov_to_cr_byte)) {
297 addr_t first_operand;
298 addr_t second_operand;
299 struct cr0_32 *new_cr0;
300 operand_type_t addr_type;
305 PrintDebug("MovToCR0 instr:\n");
306 PrintTraceMemDump(instr, 15);
307 PrintDebug("EAX=%x\n", *(uint_t*)&(info->vm_regs.rax));
309 addr_type = decode_operands32(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
311 if (addr_type != REG_OPERAND) {
312 PrintDebug("Non-register operand in write to CR0\n");
316 new_cr0 = (struct cr0_32 *)first_operand;
318 //PrintDebug("first operand=%x\n", *(uint_t *)first_operand);
320 if (info->shdw_pg_mode == SHADOW_PAGING) {
321 struct cr0_32 * shadow_cr0 = (struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
323 if (new_cr0->pg == 1){
324 // This should be new_cr0->pg && !(old_cr->pg), right?
325 // and then a case for turning paging off?
327 struct cr3_32 * shadow_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.shadow_cr3);
329 info->mem_mode = VIRTUAL_MEM;
331 *shadow_cr0 = *new_cr0;
332 *real_cr0 = *new_cr0;
337 // Activate Shadow Paging
339 PrintDebug("Turning on paging in the guest\n");
341 info->ctrl_regs.cr3 = *(addr_t*)shadow_cr3;
344 } else if (new_cr0->pe == 0) {
345 info->cpu_mode = REAL;
346 info->mem_mode = PHYSICAL_MEM;
347 PrintDebug("Entering Real Mode\n");
349 //PrintV3CtrlRegs(info);
350 // reinstate the identity mapped paged tables
351 // But keep the shadow tables around to handle TLB issues.... UGH...
352 //info->shdw_pg_state.shadow_cr3 &= 0x00000fff;
353 //info->shdw_pg_state.shadow_cr3 |= ((addr_t)create_passthrough_pde32_pts(info) & ~0xfff);
355 //info->ctrl_regs.cr3 = info->shdw_pg_state.shadow_cr3;
356 info->ctrl_regs.cr3 = *(addr_t*)&(info->direct_map_pt);
358 *shadow_cr0 = *new_cr0;
359 *real_cr0 = *new_cr0;
364 //PrintV3CtrlRegs(info);
370 if (new_cr0->pg == 1) {
371 info->mem_mode = VIRTUAL_MEM;
372 } else if (new_cr0->pg == 0) {
373 info->cpu_mode = REAL;
374 info->mem_mode = PHYSICAL_MEM;
377 *real_cr0 = *new_cr0;
381 } else if ((instr[index] == cr_access_byte) &&
382 (instr[index + 1] == lmsw_byte) &&
383 (MODRM_REG(instr[index + 2]) == lmsw_reg_byte)) {
384 addr_t first_operand;
385 addr_t second_operand;
386 struct cr0_real *real_cr0;
387 struct cr0_real *new_cr0;
388 operand_type_t addr_type;
389 char new_cr0_val = 0;
393 real_cr0 = (struct cr0_real*)&(info->ctrl_regs.cr0);
395 addr_type = decode_operands16(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG16);
397 if (addr_type == REG_OPERAND) {
398 new_cr0 = (struct cr0_real *)first_operand;
399 } else if (addr_type == MEM_OPERAND) {
401 // check segment descriptors....
403 /* TODO, TODO, TODO: Lookup segment overrides */
404 struct v3_segment *lmsw_segment = &(info->segments.ds);
406 if (info->mem_mode == PHYSICAL_MEM) {
407 if (guest_pa_to_host_va(info, get_addr_linear(info, first_operand, lmsw_segment), &host_addr) == -1) {
411 if (guest_va_to_host_va(info, get_addr_linear(info, first_operand, lmsw_segment), &host_addr) == -1) {
416 new_cr0 = (struct cr0_real *)host_addr;
422 if (new_cr0->pe == 0) {
423 // According to the intel manual this it is illegal to use
424 // lmsw to turn _off_ Protected mode
425 PrintDebug("Cannot switch to real mode with LMSW, unclear what to do\n");
429 new_cr0_val = (*(char *)(new_cr0)) & 0x0f;
432 if (info->shdw_pg_mode == SHADOW_PAGING) {
433 struct cr0_real * shadow_cr0 = (struct cr0_real*)&(info->shdw_pg_state.guest_cr0);
435 PrintDebug("Old CR0=%x, Old Shadow CR0=%x\n", *real_cr0, *shadow_cr0);
436 /* struct cr0_real is only 4 bits wide,
437 * so we can overwrite the real_cr0 without worrying about the shadow fields
439 *(char*)real_cr0 &= 0xf0;
440 *(char*)real_cr0 |= new_cr0_val;
442 *(char*)shadow_cr0 &= 0xf0;
443 *(char*)shadow_cr0 |= new_cr0_val;
446 PrintDebug("New CR0=%x, New Shadow CR0=%x\n", *real_cr0, *shadow_cr0);
448 PrintDebug("Old CR0=%x\n", *real_cr0);
449 // for now we just pass through....
450 *(char*)real_cr0 &= 0xf0;
451 *(char*)real_cr0 |= new_cr0_val;
453 PrintDebug("New CR0=%x\n", *real_cr0);
459 } else if ((instr[index] == 0x0f) &&
460 (instr[index + 1] == 0x06)) {
462 PrintDebug("CLTS instruction - clearing TS flag of real and shadow CR0\n");
471 PrintDebug("Unkown instruction: \n");
472 SerialMemDump(instr,15);
479 PrintDebug("Protected PAE Mode write to CR0 is UNIMPLEMENTED\n");
483 PrintDebug("Protected Long Mode write to CR0 is UNIMPLEMENTED\n");
488 PrintDebug("Unknown Mode write to CR0 (info->cpu_mode=0x%x\n)",info->cpu_mode);
499 int handle_cr0_read(struct guest_info * info) {
502 switch (info->cpu_mode) {
510 PrintDebug("Real Mode read from CR0 at linear guest pa 0x%x\n",get_addr_linear(info,info->rip,&(info->segments.cs)));
511 //PrintV3Segments(info);
513 // The real rip address is actually a combination of the rip + CS base
514 ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
516 // I think we should inject a GPF into the guest
517 PrintDebug("Could not read Real Mode instruction (ret=%d)\n", ret);
522 while (is_prefix_byte(instr[index])) {
523 switch(instr[index]) {
524 case PREFIX_CS_OVERRIDE:
525 case PREFIX_SS_OVERRIDE:
526 case PREFIX_DS_OVERRIDE:
527 case PREFIX_ES_OVERRIDE:
528 case PREFIX_FS_OVERRIDE:
529 case PREFIX_GS_OVERRIDE:
530 PrintDebug("Segment Override!!\n");
540 while (is_prefix_byte(instr[index])) {
545 if ((instr[index] == cr_access_byte) &&
546 (instr[index + 1] == smsw_byte) &&
547 (MODRM_REG(instr[index + 2]) == smsw_reg_byte)) {
549 // SMSW (store machine status word)
551 addr_t first_operand;
552 addr_t second_operand;
553 struct cr0_real *cr0;
554 operand_type_t addr_type;
559 cr0 = (struct cr0_real*)&(info->ctrl_regs.cr0);
562 addr_type = decode_operands16(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG16);
564 if (addr_type == MEM_OPERAND) {
567 if (guest_pa_to_host_va(info, first_operand + (info->segments.ds.base << 4), &host_addr) == -1) {
569 PrintDebug("Could not convert guest physical address to host virtual address\n");
573 first_operand = host_addr;
579 cr0_val = *(char*)cr0 & 0x0f;
581 *(char *)first_operand &= 0xf0;
582 *(char *)first_operand |= cr0_val;
584 PrintDebug("index = %d, rip = %x\n", index, (ulong_t)(info->rip));
586 PrintDebug("new_rip = %x\n", (ulong_t)(info->rip));
589 } else if ((instr[index] == cr_access_byte) &&
590 (instr[index+1] == mov_from_cr_byte)) {
592 * This can only take a 32 bit register argument in anything less than 64 bit mode.
594 addr_t first_operand;
595 addr_t second_operand;
596 operand_type_t addr_type;
598 struct cr0_32 * real_cr0 = (struct cr0_32 *)&(info->ctrl_regs.cr0);
602 addr_type = decode_operands16(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
604 struct cr0_32 * virt_cr0 = (struct cr0_32 *)first_operand;
606 if (addr_type != REG_OPERAND) {
607 // invalid opcode to guest
608 PrintDebug("Invalid operand type in mov from CR0\n");
612 if (info->shdw_pg_mode == SHADOW_PAGING) {
613 *virt_cr0 = *(struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
615 *virt_cr0 = *real_cr0;
621 PrintDebug("Unknown read instr from CR0\n");
635 PrintDebug("Protected %s Mode read from CR0 at guest %s linear rip 0x%x\n",
636 info->mem_mode == VIRTUAL_MEM ? "Paged" : "",
637 info->mem_mode == VIRTUAL_MEM ? "virtual" : "",
638 get_addr_linear(info, info->rip, &(info->segments.cs)));
640 // We need to read the instruction, which is at CS:IP, but that
641 // linear address is guest physical without PG and guest virtual with PG
642 if (info->cpu_mode == PHYSICAL_MEM) {
643 // The real rip address is actually a combination of the rip + CS base
644 ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
646 // The real rip address is actually a combination of the rip + CS base
647 ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
652 PrintDebug("Instr (15 bytes) at %x:\n", instr);
653 PrintTraceMemDump((char*)instr, 15);
657 // I think we should inject a GPF into the guest
658 PrintDebug("Could not read Protected %s mode instruction (ret=%d)\n",
659 info->cpu_mode == VIRTUAL_MEM ? "Paged" : "", ret);
664 while (is_prefix_byte(instr[index])) {
665 switch(instr[index]) {
666 case PREFIX_CS_OVERRIDE:
667 case PREFIX_SS_OVERRIDE:
668 case PREFIX_DS_OVERRIDE:
669 case PREFIX_ES_OVERRIDE:
670 case PREFIX_FS_OVERRIDE:
671 case PREFIX_GS_OVERRIDE:
672 PrintDebug("Segment Override!!\n");
683 while (is_prefix_byte(instr[index])) {
688 if ((instr[index] == cr_access_byte) &&
689 (instr[index+1] == mov_from_cr_byte)) {
691 // MOV from CR0 to register
693 addr_t first_operand;
694 addr_t second_operand;
695 operand_type_t addr_type;
696 struct cr0_32 * virt_cr0;
697 struct cr0_32 * real_cr0 = (struct cr0_32 *)&(info->ctrl_regs.cr0);
701 addr_type = decode_operands32(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
703 if (addr_type != REG_OPERAND) {
704 PrintDebug("Invalid operand type in mov from CR0\n");
708 virt_cr0 = (struct cr0_32 *)first_operand;
710 if (info->shdw_pg_mode == SHADOW_PAGING) {
711 *virt_cr0 = *(struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
713 if (info->mem_mode == PHYSICAL_MEM) {
714 virt_cr0->pg = 0; // clear the pg bit because guest doesn't think it's on
718 *virt_cr0 = *real_cr0;
721 PrintDebug("real CR0: %x\n", *(uint_t*)real_cr0);
722 PrintDebug("returned CR0: %x\n", *(uint_t*)virt_cr0);
727 PrintDebug("Unknown read instruction from CR0\n");
734 PrintDebug("Protected PAE Mode read to CR0 is UNIMPLEMENTED\n");
738 PrintDebug("Protected Long Mode read to CR0 is UNIMPLEMENTED\n");
744 PrintDebug("Unknown Mode read from CR0 (info->cpu_mode=0x%x)\n",info->cpu_mode);
757 int handle_cr3_write(struct guest_info * info) {
758 if (info->cpu_mode == REAL) {
759 // WHAT THE HELL DOES THIS EVEN MEAN?????
765 PrintDebug("Real Mode Write to CR3.\n");
766 // We need to read the instruction, which is at CS:IP, but that
767 // linear address is guest physical without PG and guest virtual with PG
769 ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
772 PrintDebug("Could not read instruction (ret=%d)\n", ret);
776 while (is_prefix_byte(instr[index])) {
777 switch(instr[index]) {
778 case PREFIX_CS_OVERRIDE:
779 case PREFIX_SS_OVERRIDE:
780 case PREFIX_DS_OVERRIDE:
781 case PREFIX_ES_OVERRIDE:
782 case PREFIX_FS_OVERRIDE:
783 case PREFIX_GS_OVERRIDE:
784 PrintDebug("Segment Override!!\n");
794 if ((instr[index] == cr_access_byte) &&
795 (instr[index + 1] == mov_to_cr_byte)) {
797 addr_t first_operand;
798 addr_t second_operand;
799 struct cr3_32 * new_cr3;
800 // struct cr3_32 * real_cr3;
801 operand_type_t addr_type;
805 addr_type = decode_operands16(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
807 if (addr_type != REG_OPERAND) {
808 /* Mov to CR3 can only be a 32 bit register */
812 new_cr3 = (struct cr3_32 *)first_operand;
814 if (info->shdw_pg_mode == SHADOW_PAGING) {
816 struct cr3_32 * shadow_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.shadow_cr3);
817 struct cr3_32 * guest_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.guest_cr3);
821 if (CR3_TO_PDE32(*(uint_t*)shadow_cr3) != 0) {
822 PrintDebug("Shadow Page Table\n");
823 PrintDebugPageTables((pde32_t *)CR3_TO_PDE32(*(uint_t*)shadow_cr3));
827 /* Delete the current Page Tables */
828 delete_page_tables_pde32((pde32_t *)CR3_TO_PDE32(*(uint_t*)shadow_cr3));
830 PrintDebug("Old Shadow CR3=%x; Old Guest CR3=%x\n",
831 *(uint_t*)shadow_cr3, *(uint_t*)guest_cr3);
834 *guest_cr3 = *new_cr3;
838 // Something like this
839 shadow_pt = create_new_shadow_pt32(info);
840 //shadow_pt = setup_shadow_pt32(info, CR3_TO_PDE32(*(addr_t *)new_cr3));
842 /* Copy Various flags */
843 *shadow_cr3 = *new_cr3;
848 guest_pa_to_host_va(info, ((*(uint_t*)guest_cr3) & 0xfffff000), &tmp_addr);
849 PrintDebug("Guest PD\n");
850 PrintPD32((pde32_t *)tmp_addr);
856 shadow_cr3->pdt_base_addr = PD32_BASE_ADDR(shadow_pt);
858 PrintDebug("New Shadow CR3=%x; New Guest CR3=%x\n",
859 *(uint_t*)shadow_cr3, *(uint_t*)guest_cr3);
868 PrintDebug("Unknown Instruction\n");
869 SerialMemDump(instr,15);
875 } else if (info->cpu_mode == PROTECTED) {
880 PrintDebug("Protected %s mode write to CR3 at %s 0x%x\n",
881 info->cpu_mode==PROTECTED ? "" : "Paged",
882 info->cpu_mode==PROTECTED ? "guest physical" : "guest virtual",
883 get_addr_linear(info,info->rip,&(info->segments.cs)));
885 // We need to read the instruction, which is at CS:IP, but that
886 // linear address is guest physical without PG and guest virtual with PG
887 if (info->mem_mode == PHYSICAL_MEM) {
888 // The real rip address is actually a combination of the rip + CS base
889 //PrintDebug("Writing Guest CR3 Write (Physical Address)\n");
890 ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
892 //PrintDebug("Writing Guest CR3 Write (Virtual Address)\n");
893 // The real rip address is actually a combination of the rip + CS base
894 ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
898 PrintDebug("Could not read instruction (ret=%d)\n", ret);
902 while (is_prefix_byte(instr[index])) {
903 switch(instr[index]) {
904 case PREFIX_CS_OVERRIDE:
905 case PREFIX_SS_OVERRIDE:
906 case PREFIX_DS_OVERRIDE:
907 case PREFIX_ES_OVERRIDE:
908 case PREFIX_FS_OVERRIDE:
909 case PREFIX_GS_OVERRIDE:
910 PrintDebug("Segment Override!!\n");
920 while (is_prefix_byte(instr[index])) {
925 if ((instr[index] == cr_access_byte) &&
926 (instr[index + 1] == mov_to_cr_byte)) {
928 addr_t first_operand;
929 addr_t second_operand;
930 struct cr3_32 * new_cr3;
931 // struct cr3_32 * real_cr3;
932 operand_type_t addr_type;
936 addr_type = decode_operands32(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
938 if (addr_type != REG_OPERAND) {
939 /* Mov to CR3 can only be a 32 bit register */
943 new_cr3 = (struct cr3_32 *)first_operand;
945 if (info->shdw_pg_mode == SHADOW_PAGING) {
947 struct cr3_32 * shadow_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.shadow_cr3);
948 struct cr3_32 * guest_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.guest_cr3);
952 if (CR3_TO_PDE32(*(uint_t*)shadow_cr3) != 0) {
953 PrintDebug("Shadow Page Table\n");
954 PrintDebugPageTables((pde32_t *)CR3_TO_PDE32(*(uint_t*)shadow_cr3));
958 /* Delete the current Page Tables */
959 delete_page_tables_pde32((pde32_t *)CR3_TO_PDE32(*(uint_t*)shadow_cr3));
961 PrintDebug("Old Shadow CR3=%x; Old Guest CR3=%x\n",
962 *(uint_t*)shadow_cr3, *(uint_t*)guest_cr3);
965 *guest_cr3 = *new_cr3;
969 // Something like this
970 shadow_pt = create_new_shadow_pt32(info);
971 //shadow_pt = setup_shadow_pt32(info, CR3_TO_PDE32(*(addr_t *)new_cr3));
973 /* Copy Various flags */
974 *shadow_cr3 = *new_cr3;
979 guest_pa_to_host_va(info, ((*(uint_t*)guest_cr3) & 0xfffff000), &tmp_addr);
980 PrintDebug("Guest PD\n");
981 PrintPD32((pde32_t *)tmp_addr);
987 shadow_cr3->pdt_base_addr = PD32_BASE_ADDR(shadow_pt);
989 PrintDebug("New Shadow CR3=%x; New Guest CR3=%x\n",
990 *(uint_t*)shadow_cr3, *(uint_t*)guest_cr3);
994 if (info->mem_mode == VIRTUAL_MEM) {
995 // If we aren't in paged mode then we have to preserve the identity mapped CR3
996 info->ctrl_regs.cr3 = *(addr_t*)shadow_cr3;
1003 PrintDebug("Unknown Instruction\n");
1004 SerialMemDump(instr,15);
1008 PrintDebug("Invalid operating Mode (0x%x)\n", info->cpu_mode);
1018 int handle_cr3_read(struct guest_info * info) {
1020 if (info->cpu_mode == REAL) {
1024 addr_t linear_addr = 0;
1026 linear_addr = get_addr_linear(info, info->rip, &(info->segments.cs));
1029 //PrintDebug("RIP Linear: %x\n", linear_addr);
1030 //PrintV3Segments(info);
1032 ret = read_guest_pa_memory(info, linear_addr, 15, instr);
1035 PrintDebug("Could not read instruction (ret=%d)\n", ret);
1039 while (is_prefix_byte(instr[index])) {
1040 switch(instr[index]) {
1041 case PREFIX_CS_OVERRIDE:
1042 case PREFIX_SS_OVERRIDE:
1043 case PREFIX_DS_OVERRIDE:
1044 case PREFIX_ES_OVERRIDE:
1045 case PREFIX_FS_OVERRIDE:
1046 case PREFIX_GS_OVERRIDE:
1047 PrintDebug("Segment Override!!\n");
1057 if ((instr[index] == cr_access_byte) &&
1058 (instr[index + 1] == mov_from_cr_byte)) {
1059 addr_t first_operand;
1060 addr_t second_operand;
1061 struct cr3_32 * virt_cr3;
1062 struct cr3_32 * real_cr3 = (struct cr3_32 *)&(info->ctrl_regs.cr3);
1063 operand_type_t addr_type;
1067 addr_type = decode_operands16(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
1069 if (addr_type != REG_OPERAND) {
1070 /* Mov to CR3 can only be a 32 bit register */
1074 virt_cr3 = (struct cr3_32 *)first_operand;
1076 if (info->shdw_pg_mode == SHADOW_PAGING) {
1077 *virt_cr3 = *(struct cr3_32 *)&(info->shdw_pg_state.guest_cr3);
1079 *virt_cr3 = *real_cr3;
1084 PrintDebug("Unknown Instruction\n");
1085 SerialMemDump(instr,15);
1091 } else if (info->cpu_mode == PROTECTED) {
1098 // We need to read the instruction, which is at CS:IP, but that
1099 // linear address is guest physical without PG and guest virtual with PG
1100 if (info->cpu_mode == PHYSICAL_MEM) {
1101 // The real rip address is actually a combination of the rip + CS base
1102 ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
1104 // The real rip address is actually a combination of the rip + CS base
1105 ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
1109 PrintDebug("Could not read instruction (ret=%d)\n", ret);
1113 while (is_prefix_byte(instr[index])) {
1114 switch(instr[index]) {
1115 case PREFIX_CS_OVERRIDE:
1116 case PREFIX_SS_OVERRIDE:
1117 case PREFIX_DS_OVERRIDE:
1118 case PREFIX_ES_OVERRIDE:
1119 case PREFIX_FS_OVERRIDE:
1120 case PREFIX_GS_OVERRIDE:
1121 PrintDebug("Segment Override!!\n");
1131 while (is_prefix_byte(instr[index])) {
1136 if ((instr[index] == cr_access_byte) &&
1137 (instr[index + 1] == mov_from_cr_byte)) {
1138 addr_t first_operand;
1139 addr_t second_operand;
1140 struct cr3_32 * virt_cr3;
1141 struct cr3_32 * real_cr3 = (struct cr3_32 *)&(info->ctrl_regs.cr3);
1142 operand_type_t addr_type;
1146 addr_type = decode_operands32(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
1148 if (addr_type != REG_OPERAND) {
1149 /* Mov to CR3 can only be a 32 bit register */
1153 virt_cr3 = (struct cr3_32 *)first_operand;
1155 if (info->shdw_pg_mode == SHADOW_PAGING) {
1156 *virt_cr3 = *(struct cr3_32 *)&(info->shdw_pg_state.guest_cr3);
1158 *virt_cr3 = *real_cr3;
1163 PrintDebug("Unknown Instruction\n");
1164 SerialMemDump(instr,15);
1168 PrintDebug("Invalid operating Mode (0x%x), control registers follow\n", info->cpu_mode);
1169 PrintV3CtrlRegs(info);