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);
47 while (is_prefix_byte(instr[index])) {
48 switch(instr[index]) {
49 case PREFIX_CS_OVERRIDE:
50 case PREFIX_SS_OVERRIDE:
51 case PREFIX_DS_OVERRIDE:
52 case PREFIX_ES_OVERRIDE:
53 case PREFIX_FS_OVERRIDE:
54 case PREFIX_GS_OVERRIDE:
55 PrintDebug("Segment Override!!\n");
64 if ((instr[index] == cr_access_byte) &&
65 (instr[index + 1] == lmsw_byte) &&
66 (MODRM_REG(instr[index + 2]) == lmsw_reg_byte)) {
69 addr_t second_operand;
70 struct cr0_real *real_cr0;
71 struct cr0_real *new_cr0;
72 operand_type_t addr_type;
78 real_cr0 = (struct cr0_real*)&(info->ctrl_regs.cr0);
80 addr_type = decode_operands16(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG16);
83 if (addr_type == REG_OPERAND) {
84 new_cr0 = (struct cr0_real *)first_operand;
85 } else if (addr_type == MEM_OPERAND) {
88 if (guest_pa_to_host_va(info, first_operand + (info->segments.ds.base << 4), &host_addr) == -1) {
93 new_cr0 = (struct cr0_real *)host_addr;
96 // error... don't know what to do
100 if ((new_cr0->pe == 1) && (real_cr0->pe == 0)) {
101 info->cpu_mode = PROTECTED;
102 } else if ((new_cr0->pe == 0) && (real_cr0->pe == 1)) {
103 info->cpu_mode = REAL;
106 new_cr0_val = (*(char*)(new_cr0)) & 0x0f;
109 if (info->shdw_pg_mode == SHADOW_PAGING) {
110 struct cr0_real * shadow_cr0 = (struct cr0_real*)&(info->shdw_pg_state.guest_cr0);
112 PrintDebug("Old CR0=%x, Old Shadow CR0=%x\n", *real_cr0, *shadow_cr0);
113 /* struct cr0_real is only 4 bits wide,
114 * so we can overwrite the real_cr0 without worrying about the shadow fields
116 *(char*)real_cr0 &= 0xf0;
117 *(char*)real_cr0 |= new_cr0_val;
119 *(char*)shadow_cr0 &= 0xf0;
120 *(char*)shadow_cr0 |= new_cr0_val;
123 PrintDebug("New CR0=%x, New Shadow CR0=%x\n", *real_cr0, *shadow_cr0);
125 PrintDebug("Old CR0=%x\n", *real_cr0);
126 // for now we just pass through....
127 *(char*)real_cr0 &= 0xf0;
128 *(char*)real_cr0 |= new_cr0_val;
130 PrintDebug("New CR0=%x\n", *real_cr0);
136 } else if ((instr[index] == cr_access_byte) &&
137 (instr[index + 1] == clts_byte)) {
139 PrintDebug("CLTS unhandled in CR0 write\n");
142 } else if ((instr[index] == cr_access_byte) &&
143 (instr[index + 1] = mov_to_cr_byte)) {
144 addr_t first_operand;
145 addr_t second_operand;
146 struct cr0_32 *real_cr0;
147 struct cr0_32 *new_cr0;
148 operand_type_t addr_type;
153 real_cr0 = (struct cr0_32*)&(info->ctrl_regs.cr0);
155 addr_type = decode_operands16(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
157 if (addr_type != REG_OPERAND) {
158 PrintDebug("Moving to CR0 from non-register operand in CR0 write\n");
159 /* Mov to CR0 Can only be a 32 bit register */
164 new_cr0 = (struct cr0_32 *)first_operand;
166 if (new_cr0->pe == 1) {
167 PrintDebug("Entering Protected Mode\n");
168 info->cpu_mode = PROTECTED;
171 if (new_cr0->pe == 0) {
172 PrintDebug("Entering Real Mode\n");
173 info->cpu_mode = REAL;
178 if ((new_cr0->pg == 1) && (new_cr0->pe == 1)) {
179 PrintDebug("Paging is already turned on in switch to protected mode in CR0 write\n");
181 // Actually This appears to be Ok.
182 // Why shouldn't windows be allowed to switch to real mode whenever it wants to modify its page tables?
184 info->mem_mode = VIRTUAL_MEM;
188 } else if ((new_cr0->pg == 1) && (new_cr0->pe == 0)) {
189 PrintDebug("Will the madness Never End??\n");
194 if (info->shdw_pg_mode == SHADOW_PAGING) {
195 struct cr0_32 * shadow_cr0 = (struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
197 PrintDebug("Old CR0=%x, Old Shadow CR0=%x\n", *real_cr0, *shadow_cr0);
198 *real_cr0 = *new_cr0;
202 *shadow_cr0 = *new_cr0;
205 // Setup the page tables...???
206 if (info->mem_mode == VIRTUAL_MEM) {
207 // If we aren't in paged mode then we have to preserve the identity mapped CR3
208 info->ctrl_regs.cr3 = *(addr_t*)&(info->shdw_pg_state.shadow_cr3);
211 PrintDebug("New CR0=%x, New Shadow CR0=%x\n", *real_cr0, *shadow_cr0);
213 PrintDebug("Old CR0=%x\n", *real_cr0);
214 *real_cr0 = *new_cr0;
215 PrintDebug("New CR0=%x\n", *real_cr0);
221 PrintDebug("Unsupported Instruction\n");
222 // unsupported instruction, UD the guest
235 PrintDebug("Protected %s Mode write to CR0 at guest %s linear rip 0x%x\n",
236 info->mem_mode == VIRTUAL_MEM ? "Paged" : "",
237 info->mem_mode == VIRTUAL_MEM ? "virtual" : "",
238 get_addr_linear(info, info->rip, &(info->segments.cs)));
240 // OK, now we will read the instruction
241 // The only difference between PROTECTED and PROTECTED_PG is whether we read
242 // from guest_pa or guest_va
243 if (info->mem_mode == PHYSICAL_MEM) {
244 // The real rip address is actually a combination of the rip + CS base
245 ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
247 ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
252 // I think we should inject a GPF into the guest
253 PrintDebug("Could not read instruction (ret=%d)\n", ret);
258 while (is_prefix_byte(instr[index])) {
259 switch(instr[index]) {
260 case PREFIX_CS_OVERRIDE:
261 case PREFIX_SS_OVERRIDE:
262 case PREFIX_DS_OVERRIDE:
263 case PREFIX_ES_OVERRIDE:
264 case PREFIX_FS_OVERRIDE:
265 case PREFIX_GS_OVERRIDE:
266 PrintDebug("Segment Override!!\n");
276 while (is_prefix_byte(instr[index])) {
281 struct cr0_32 * shadow_cr0 = (struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
283 struct cr0_32 * real_cr0 = (struct cr0_32*)&(info->ctrl_regs.cr0);
285 if ((instr[index] == cr_access_byte) &&
286 (instr[index + 1] == mov_to_cr_byte)) {
290 addr_t first_operand;
291 addr_t second_operand;
292 struct cr0_32 *new_cr0;
293 operand_type_t addr_type;
298 PrintDebug("MovToCR0 instr:\n");
299 PrintTraceMemDump(instr, 15);
300 PrintDebug("EAX=%x\n", *(uint_t*)&(info->vm_regs.rax));
302 addr_type = decode_operands32(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
304 if (addr_type != REG_OPERAND) {
305 PrintDebug("Non-register operand in write to CR0\n");
309 new_cr0 = (struct cr0_32 *)first_operand;
311 //PrintDebug("first operand=%x\n", *(uint_t *)first_operand);
313 if (info->shdw_pg_mode == SHADOW_PAGING) {
314 struct cr0_32 * shadow_cr0 = (struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
316 if (new_cr0->pg == 1){
317 // This should be new_cr0->pg && !(old_cr->pg), right?
318 // and then a case for turning paging off?
320 struct cr3_32 * shadow_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.shadow_cr3);
322 info->mem_mode = VIRTUAL_MEM;
324 *shadow_cr0 = *new_cr0;
325 *real_cr0 = *new_cr0;
330 // Activate Shadow Paging
332 PrintDebug("Turning on paging in the guest\n");
334 info->ctrl_regs.cr3 = *(addr_t*)shadow_cr3;
337 } else if (new_cr0->pe == 0) {
338 info->cpu_mode = REAL;
339 info->mem_mode = PHYSICAL_MEM;
340 PrintDebug("Entering Real Mode\n");
342 //PrintV3CtrlRegs(info);
343 // reinstate the identity mapped paged tables
344 // But keep the shadow tables around to handle TLB issues.... UGH...
345 //info->shdw_pg_state.shadow_cr3 &= 0x00000fff;
346 //info->shdw_pg_state.shadow_cr3 |= ((addr_t)create_passthrough_pde32_pts(info) & ~0xfff);
348 //info->ctrl_regs.cr3 = info->shdw_pg_state.shadow_cr3;
349 info->ctrl_regs.cr3 = *(addr_t*)&(info->direct_map_pt);
351 *shadow_cr0 = *new_cr0;
352 *real_cr0 = *new_cr0;
357 //PrintV3CtrlRegs(info);
363 if (new_cr0->pg == 1) {
364 info->mem_mode = VIRTUAL_MEM;
365 } else if (new_cr0->pg == 0) {
366 info->cpu_mode = REAL;
367 info->mem_mode = PHYSICAL_MEM;
370 *real_cr0 = *new_cr0;
374 } else if ((instr[index] == cr_access_byte) &&
375 (instr[index + 1] == lmsw_byte) &&
376 (MODRM_REG(instr[index + 2]) == lmsw_reg_byte)) {
377 addr_t first_operand;
378 addr_t second_operand;
379 struct cr0_real *real_cr0;
380 struct cr0_real *new_cr0;
381 operand_type_t addr_type;
382 char new_cr0_val = 0;
386 real_cr0 = (struct cr0_real*)&(info->ctrl_regs.cr0);
388 addr_type = decode_operands16(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG16);
390 if (addr_type == REG_OPERAND) {
391 new_cr0 = (struct cr0_real *)first_operand;
392 } else if (addr_type == MEM_OPERAND) {
394 // check segment descriptors....
396 /* TODO, TODO, TODO: Lookup segment overrides */
397 struct v3_segment *lmsw_segment = &(info->segments.ds);
399 if (info->mem_mode == PHYSICAL_MEM) {
400 if (guest_pa_to_host_va(info, get_addr_linear(info, first_operand, lmsw_segment), &host_addr) == -1) {
404 if (guest_va_to_host_va(info, get_addr_linear(info, first_operand, lmsw_segment), &host_addr) == -1) {
409 new_cr0 = (struct cr0_real *)host_addr;
415 if (new_cr0->pe == 0) {
416 // According to the intel manual this it is illegal to use
417 // lmsw to turn _off_ Protected mode
418 PrintDebug("Cannot switch to real mode with LMSW, unclear what to do\n");
422 new_cr0_val = (*(char *)(new_cr0)) & 0x0f;
425 if (info->shdw_pg_mode == SHADOW_PAGING) {
426 struct cr0_real * shadow_cr0 = (struct cr0_real*)&(info->shdw_pg_state.guest_cr0);
428 PrintDebug("Old CR0=%x, Old Shadow CR0=%x\n", *real_cr0, *shadow_cr0);
429 /* struct cr0_real is only 4 bits wide,
430 * so we can overwrite the real_cr0 without worrying about the shadow fields
432 *(char*)real_cr0 &= 0xf0;
433 *(char*)real_cr0 |= new_cr0_val;
435 *(char*)shadow_cr0 &= 0xf0;
436 *(char*)shadow_cr0 |= new_cr0_val;
439 PrintDebug("New CR0=%x, New Shadow CR0=%x\n", *real_cr0, *shadow_cr0);
441 PrintDebug("Old CR0=%x\n", *real_cr0);
442 // for now we just pass through....
443 *(char*)real_cr0 &= 0xf0;
444 *(char*)real_cr0 |= new_cr0_val;
446 PrintDebug("New CR0=%x\n", *real_cr0);
452 } else if ((instr[index] == 0x0f) &&
453 (instr[index + 1] == 0x06)) {
455 PrintDebug("CLTS instruction - clearing TS flag of real and shadow CR0\n");
464 PrintDebug("Unkown instruction: \n");
465 SerialMemDump(instr,15);
472 PrintDebug("Protected PAE Mode write to CR0 is UNIMPLEMENTED\n");
476 PrintDebug("Protected Long Mode write to CR0 is UNIMPLEMENTED\n");
481 PrintDebug("Unknown Mode write to CR0 (info->cpu_mode=0x%x\n)",info->cpu_mode);
492 int handle_cr0_read(struct guest_info * info) {
495 switch (info->cpu_mode) {
503 PrintDebug("Real Mode read from CR0 at linear guest pa 0x%x\n",get_addr_linear(info,info->rip,&(info->segments.cs)));
504 //PrintV3Segments(info);
506 // The real rip address is actually a combination of the rip + CS base
507 ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
509 // I think we should inject a GPF into the guest
510 PrintDebug("Could not read Real Mode instruction (ret=%d)\n", ret);
515 while (is_prefix_byte(instr[index])) {
516 switch(instr[index]) {
517 case PREFIX_CS_OVERRIDE:
518 case PREFIX_SS_OVERRIDE:
519 case PREFIX_DS_OVERRIDE:
520 case PREFIX_ES_OVERRIDE:
521 case PREFIX_FS_OVERRIDE:
522 case PREFIX_GS_OVERRIDE:
523 PrintDebug("Segment Override!!\n");
533 while (is_prefix_byte(instr[index])) {
538 if ((instr[index] == cr_access_byte) &&
539 (instr[index + 1] == smsw_byte) &&
540 (MODRM_REG(instr[index + 2]) == smsw_reg_byte)) {
542 // SMSW (store machine status word)
544 addr_t first_operand;
545 addr_t second_operand;
546 struct cr0_real *cr0;
547 operand_type_t addr_type;
552 cr0 = (struct cr0_real*)&(info->ctrl_regs.cr0);
555 addr_type = decode_operands16(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG16);
557 if (addr_type == MEM_OPERAND) {
560 if (guest_pa_to_host_va(info, first_operand + (info->segments.ds.base << 4), &host_addr) == -1) {
562 PrintDebug("Could not convert guest physical address to host virtual address\n");
566 first_operand = host_addr;
572 cr0_val = *(char*)cr0 & 0x0f;
574 *(char *)first_operand &= 0xf0;
575 *(char *)first_operand |= cr0_val;
577 PrintDebug("index = %d, rip = %x\n", index, (ulong_t)(info->rip));
579 PrintDebug("new_rip = %x\n", (ulong_t)(info->rip));
582 } else if ((instr[index] == cr_access_byte) &&
583 (instr[index+1] == mov_from_cr_byte)) {
585 * This can only take a 32 bit register argument in anything less than 64 bit mode.
587 addr_t first_operand;
588 addr_t second_operand;
589 operand_type_t addr_type;
591 struct cr0_32 * real_cr0 = (struct cr0_32 *)&(info->ctrl_regs.cr0);
595 addr_type = decode_operands16(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
597 struct cr0_32 * virt_cr0 = (struct cr0_32 *)first_operand;
599 if (addr_type != REG_OPERAND) {
600 // invalid opcode to guest
601 PrintDebug("Invalid operand type in mov from CR0\n");
605 if (info->shdw_pg_mode == SHADOW_PAGING) {
606 *virt_cr0 = *(struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
608 *virt_cr0 = *real_cr0;
614 PrintDebug("Unknown read instr from CR0\n");
628 PrintDebug("Protected %s Mode read from CR0 at guest %s linear rip 0x%x\n",
629 info->mem_mode == VIRTUAL_MEM ? "Paged" : "",
630 info->mem_mode == VIRTUAL_MEM ? "virtual" : "",
631 get_addr_linear(info, info->rip, &(info->segments.cs)));
633 // We need to read the instruction, which is at CS:IP, but that
634 // linear address is guest physical without PG and guest virtual with PG
635 if (info->cpu_mode == PHYSICAL_MEM) {
636 // The real rip address is actually a combination of the rip + CS base
637 ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
639 // The real rip address is actually a combination of the rip + CS base
640 ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
645 PrintDebug("Instr (15 bytes) at %x:\n", instr);
646 PrintTraceMemDump((char*)instr, 15);
650 // I think we should inject a GPF into the guest
651 PrintDebug("Could not read Protected %s mode instruction (ret=%d)\n",
652 info->cpu_mode == VIRTUAL_MEM ? "Paged" : "", ret);
657 while (is_prefix_byte(instr[index])) {
658 switch(instr[index]) {
659 case PREFIX_CS_OVERRIDE:
660 case PREFIX_SS_OVERRIDE:
661 case PREFIX_DS_OVERRIDE:
662 case PREFIX_ES_OVERRIDE:
663 case PREFIX_FS_OVERRIDE:
664 case PREFIX_GS_OVERRIDE:
665 PrintDebug("Segment Override!!\n");
676 while (is_prefix_byte(instr[index])) {
681 if ((instr[index] == cr_access_byte) &&
682 (instr[index+1] == mov_from_cr_byte)) {
684 // MOV from CR0 to register
686 addr_t first_operand;
687 addr_t second_operand;
688 operand_type_t addr_type;
689 struct cr0_32 * virt_cr0;
690 struct cr0_32 * real_cr0 = (struct cr0_32 *)&(info->ctrl_regs.cr0);
694 addr_type = decode_operands32(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
696 if (addr_type != REG_OPERAND) {
697 PrintDebug("Invalid operand type in mov from CR0\n");
701 virt_cr0 = (struct cr0_32 *)first_operand;
703 if (info->shdw_pg_mode == SHADOW_PAGING) {
704 *virt_cr0 = *(struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
706 if (info->mem_mode == PHYSICAL_MEM) {
707 virt_cr0->pg = 0; // clear the pg bit because guest doesn't think it's on
711 *virt_cr0 = *real_cr0;
714 PrintDebug("real CR0: %x\n", *(uint_t*)real_cr0);
715 PrintDebug("returned CR0: %x\n", *(uint_t*)virt_cr0);
720 PrintDebug("Unknown read instruction from CR0\n");
727 PrintDebug("Protected PAE Mode read to CR0 is UNIMPLEMENTED\n");
731 PrintDebug("Protected Long Mode read to CR0 is UNIMPLEMENTED\n");
737 PrintDebug("Unknown Mode read from CR0 (info->cpu_mode=0x%x)\n",info->cpu_mode);
750 int handle_cr3_write(struct guest_info * info) {
751 if (info->cpu_mode == REAL) {
752 // WHAT THE HELL DOES THIS EVEN MEAN?????
758 PrintDebug("Real Mode Write to CR3.\n");
759 // We need to read the instruction, which is at CS:IP, but that
760 // linear address is guest physical without PG and guest virtual with PG
762 ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
765 PrintDebug("Could not read instruction (ret=%d)\n", ret);
769 while (is_prefix_byte(instr[index])) {
770 switch(instr[index]) {
771 case PREFIX_CS_OVERRIDE:
772 case PREFIX_SS_OVERRIDE:
773 case PREFIX_DS_OVERRIDE:
774 case PREFIX_ES_OVERRIDE:
775 case PREFIX_FS_OVERRIDE:
776 case PREFIX_GS_OVERRIDE:
777 PrintDebug("Segment Override!!\n");
787 if ((instr[index] == cr_access_byte) &&
788 (instr[index + 1] == mov_to_cr_byte)) {
790 addr_t first_operand;
791 addr_t second_operand;
792 struct cr3_32 * new_cr3;
793 // struct cr3_32 * real_cr3;
794 operand_type_t addr_type;
798 addr_type = decode_operands16(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
800 if (addr_type != REG_OPERAND) {
801 /* Mov to CR3 can only be a 32 bit register */
805 new_cr3 = (struct cr3_32 *)first_operand;
807 if (info->shdw_pg_mode == SHADOW_PAGING) {
809 struct cr3_32 * shadow_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.shadow_cr3);
810 struct cr3_32 * guest_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.guest_cr3);
814 if (CR3_TO_PDE32(*(uint_t*)shadow_cr3) != 0) {
815 PrintDebug("Shadow Page Table\n");
816 PrintDebugPageTables((pde32_t *)CR3_TO_PDE32(*(uint_t*)shadow_cr3));
820 /* Delete the current Page Tables */
821 delete_page_tables_pde32((pde32_t *)CR3_TO_PDE32(*(uint_t*)shadow_cr3));
823 PrintDebug("Old Shadow CR3=%x; Old Guest CR3=%x\n",
824 *(uint_t*)shadow_cr3, *(uint_t*)guest_cr3);
827 *guest_cr3 = *new_cr3;
831 // Something like this
832 shadow_pt = create_new_shadow_pt32(info);
833 //shadow_pt = setup_shadow_pt32(info, CR3_TO_PDE32(*(addr_t *)new_cr3));
835 /* Copy Various flags */
836 *shadow_cr3 = *new_cr3;
841 guest_pa_to_host_va(info, ((*(uint_t*)guest_cr3) & 0xfffff000), &tmp_addr);
842 PrintDebug("Guest PD\n");
843 PrintPD32((pde32_t *)tmp_addr);
849 shadow_cr3->pdt_base_addr = PD32_BASE_ADDR(shadow_pt);
851 PrintDebug("New Shadow CR3=%x; New Guest CR3=%x\n",
852 *(uint_t*)shadow_cr3, *(uint_t*)guest_cr3);
861 PrintDebug("Unknown Instruction\n");
862 SerialMemDump(instr,15);
868 } else if (info->cpu_mode == PROTECTED) {
873 PrintDebug("Protected %s mode write to CR3 at %s 0x%x\n",
874 info->cpu_mode==PROTECTED ? "" : "Paged",
875 info->cpu_mode==PROTECTED ? "guest physical" : "guest virtual",
876 get_addr_linear(info,info->rip,&(info->segments.cs)));
878 // We need to read the instruction, which is at CS:IP, but that
879 // linear address is guest physical without PG and guest virtual with PG
880 if (info->mem_mode == PHYSICAL_MEM) {
881 // The real rip address is actually a combination of the rip + CS base
882 //PrintDebug("Writing Guest CR3 Write (Physical Address)\n");
883 ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
885 //PrintDebug("Writing Guest CR3 Write (Virtual Address)\n");
886 // The real rip address is actually a combination of the rip + CS base
887 ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
891 PrintDebug("Could not read instruction (ret=%d)\n", ret);
895 while (is_prefix_byte(instr[index])) {
896 switch(instr[index]) {
897 case PREFIX_CS_OVERRIDE:
898 case PREFIX_SS_OVERRIDE:
899 case PREFIX_DS_OVERRIDE:
900 case PREFIX_ES_OVERRIDE:
901 case PREFIX_FS_OVERRIDE:
902 case PREFIX_GS_OVERRIDE:
903 PrintDebug("Segment Override!!\n");
913 while (is_prefix_byte(instr[index])) {
918 if ((instr[index] == cr_access_byte) &&
919 (instr[index + 1] == mov_to_cr_byte)) {
921 addr_t first_operand;
922 addr_t second_operand;
923 struct cr3_32 * new_cr3;
924 // struct cr3_32 * real_cr3;
925 operand_type_t addr_type;
929 addr_type = decode_operands32(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
931 if (addr_type != REG_OPERAND) {
932 /* Mov to CR3 can only be a 32 bit register */
936 new_cr3 = (struct cr3_32 *)first_operand;
938 if (info->shdw_pg_mode == SHADOW_PAGING) {
940 struct cr3_32 * shadow_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.shadow_cr3);
941 struct cr3_32 * guest_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.guest_cr3);
945 if (CR3_TO_PDE32(*(uint_t*)shadow_cr3) != 0) {
946 PrintDebug("Shadow Page Table\n");
947 PrintDebugPageTables((pde32_t *)CR3_TO_PDE32(*(uint_t*)shadow_cr3));
951 /* Delete the current Page Tables */
952 delete_page_tables_pde32((pde32_t *)CR3_TO_PDE32(*(uint_t*)shadow_cr3));
954 PrintDebug("Old Shadow CR3=%x; Old Guest CR3=%x\n",
955 *(uint_t*)shadow_cr3, *(uint_t*)guest_cr3);
958 *guest_cr3 = *new_cr3;
962 // Something like this
963 shadow_pt = create_new_shadow_pt32(info);
964 //shadow_pt = setup_shadow_pt32(info, CR3_TO_PDE32(*(addr_t *)new_cr3));
966 /* Copy Various flags */
967 *shadow_cr3 = *new_cr3;
972 guest_pa_to_host_va(info, ((*(uint_t*)guest_cr3) & 0xfffff000), &tmp_addr);
973 PrintDebug("Guest PD\n");
974 PrintPD32((pde32_t *)tmp_addr);
980 shadow_cr3->pdt_base_addr = PD32_BASE_ADDR(shadow_pt);
982 PrintDebug("New Shadow CR3=%x; New Guest CR3=%x\n",
983 *(uint_t*)shadow_cr3, *(uint_t*)guest_cr3);
987 if (info->mem_mode == VIRTUAL_MEM) {
988 // If we aren't in paged mode then we have to preserve the identity mapped CR3
989 info->ctrl_regs.cr3 = *(addr_t*)shadow_cr3;
996 PrintDebug("Unknown Instruction\n");
997 SerialMemDump(instr,15);
1001 PrintDebug("Invalid operating Mode (0x%x)\n", info->cpu_mode);
1011 int handle_cr3_read(struct guest_info * info) {
1013 if (info->cpu_mode == REAL) {
1017 addr_t linear_addr = 0;
1019 linear_addr = get_addr_linear(info, info->rip, &(info->segments.cs));
1022 //PrintDebug("RIP Linear: %x\n", linear_addr);
1023 //PrintV3Segments(info);
1025 ret = read_guest_pa_memory(info, linear_addr, 15, instr);
1028 PrintDebug("Could not read instruction (ret=%d)\n", ret);
1032 while (is_prefix_byte(instr[index])) {
1033 switch(instr[index]) {
1034 case PREFIX_CS_OVERRIDE:
1035 case PREFIX_SS_OVERRIDE:
1036 case PREFIX_DS_OVERRIDE:
1037 case PREFIX_ES_OVERRIDE:
1038 case PREFIX_FS_OVERRIDE:
1039 case PREFIX_GS_OVERRIDE:
1040 PrintDebug("Segment Override!!\n");
1050 if ((instr[index] == cr_access_byte) &&
1051 (instr[index + 1] == mov_from_cr_byte)) {
1052 addr_t first_operand;
1053 addr_t second_operand;
1054 struct cr3_32 * virt_cr3;
1055 struct cr3_32 * real_cr3 = (struct cr3_32 *)&(info->ctrl_regs.cr3);
1056 operand_type_t addr_type;
1060 addr_type = decode_operands16(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
1062 if (addr_type != REG_OPERAND) {
1063 /* Mov to CR3 can only be a 32 bit register */
1067 virt_cr3 = (struct cr3_32 *)first_operand;
1069 if (info->shdw_pg_mode == SHADOW_PAGING) {
1070 *virt_cr3 = *(struct cr3_32 *)&(info->shdw_pg_state.guest_cr3);
1072 *virt_cr3 = *real_cr3;
1077 PrintDebug("Unknown Instruction\n");
1078 SerialMemDump(instr,15);
1084 } else if (info->cpu_mode == PROTECTED) {
1091 // We need to read the instruction, which is at CS:IP, but that
1092 // linear address is guest physical without PG and guest virtual with PG
1093 if (info->cpu_mode == PHYSICAL_MEM) {
1094 // The real rip address is actually a combination of the rip + CS base
1095 ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
1097 // The real rip address is actually a combination of the rip + CS base
1098 ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
1102 PrintDebug("Could not read instruction (ret=%d)\n", ret);
1106 while (is_prefix_byte(instr[index])) {
1107 switch(instr[index]) {
1108 case PREFIX_CS_OVERRIDE:
1109 case PREFIX_SS_OVERRIDE:
1110 case PREFIX_DS_OVERRIDE:
1111 case PREFIX_ES_OVERRIDE:
1112 case PREFIX_FS_OVERRIDE:
1113 case PREFIX_GS_OVERRIDE:
1114 PrintDebug("Segment Override!!\n");
1124 while (is_prefix_byte(instr[index])) {
1129 if ((instr[index] == cr_access_byte) &&
1130 (instr[index + 1] == mov_from_cr_byte)) {
1131 addr_t first_operand;
1132 addr_t second_operand;
1133 struct cr3_32 * virt_cr3;
1134 struct cr3_32 * real_cr3 = (struct cr3_32 *)&(info->ctrl_regs.cr3);
1135 operand_type_t addr_type;
1139 addr_type = decode_operands32(&(info->vm_regs), instr + index, &index, &first_operand, &second_operand, REG32);
1141 if (addr_type != REG_OPERAND) {
1142 /* Mov to CR3 can only be a 32 bit register */
1146 virt_cr3 = (struct cr3_32 *)first_operand;
1148 if (info->shdw_pg_mode == SHADOW_PAGING) {
1149 *virt_cr3 = *(struct cr3_32 *)&(info->shdw_pg_state.guest_cr3);
1151 *virt_cr3 = *real_cr3;
1156 PrintDebug("Unknown Instruction\n");
1157 SerialMemDump(instr,15);
1161 PrintDebug("Invalid operating Mode (0x%x), control registers follow\n", info->cpu_mode);
1162 PrintV3CtrlRegs(info);