new_cr0_val = *(char*)(new_cr0) & 0x0f;
- if (info->page_mode == SHADOW_PAGING) {
+ if (info->shdw_pg_mode == SHADOW_PAGING) {
struct cr0_real * shadow_cr0 = (struct cr0_real*)&(info->shdw_pg_state.guest_cr0);
PrintDebug("Old CR0=%x, Old Shadow CR0=%x\n", *real_cr0, *shadow_cr0);
info->cpu_mode = PROTECTED;
}
+ if (new_cr0->pe == 0) {
+ PrintDebug("Entering Real Mode\n");
+ info->cpu_mode = REAL;
+ }
+
+
if (new_cr0->pg == 1) {
PrintDebug("Paging is already turned on in switch to protected mode in CR0 write\n");
return -1;
}
- if (info->page_mode == SHADOW_PAGING) {
+ if (info->shdw_pg_mode == SHADOW_PAGING) {
struct cr0_32 * shadow_cr0 = (struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
PrintDebug("Old CR0=%x, Old Shadow CR0=%x\n", *real_cr0, *shadow_cr0);
break;
case PROTECTED:
- case PROTECTED_PG:
{
int index = 0;
int ret;
PrintDebug("Protected %s Mode write to CR0 at guest %s linear rip 0x%x\n",
- info->cpu_mode==PROTECTED_PG ? "Paged" : "",
- info->cpu_mode==PROTECTED_PG ? "virtual" : "",
- get_addr_linear(info,info->rip,&(info->segments.cs)));
+ info->mem_mode == VIRTUAL_MEM ? "Paged" : "",
+ info->mem_mode == VIRTUAL_MEM ? "virtual" : "",
+ get_addr_linear(info, info->rip, &(info->segments.cs)));
// OK, now we will read the instruction
// The only difference between PROTECTED and PROTECTED_PG is whether we read
// from guest_pa or guest_va
- if (info->cpu_mode==PROTECTED) {
+ if (info->mem_mode == PHYSICAL_MEM) {
// The real rip address is actually a combination of the rip + CS base
ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
- } else { //PROTECTED_PG
+ } else {
ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
}
+
if (ret != 15) {
// I think we should inject a GPF into the guest
PrintDebug("Could not read instruction (ret=%d)\n", ret);
- if (info->page_mode == SHADOW_PAGING) {
+ if (info->shdw_pg_mode == SHADOW_PAGING) {
struct cr0_32 * shadow_cr0 = (struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
if (new_cr0->pg == 1){
struct cr3_32 * shadow_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.shadow_cr3);
- info->cpu_mode = PROTECTED_PG;
+ info->mem_mode = VIRTUAL_MEM;
*shadow_cr0 = *new_cr0;
*real_cr0 = *new_cr0;
PrintDebug("Protected PAE Mode write to CR0 is UNIMPLEMENTED\n");
return -1;
- case PROTECTED_PAE_PG:
- PrintDebug("Protected PAE Paged Mode write to CR0 is UNIMPLEMENTED\n");
- return -1;
-
case LONG:
PrintDebug("Protected Long Mode write to CR0 is UNIMPLEMENTED\n");
return -1;
- case LONG_PG:
- PrintDebug("Protected Long Paged Mode write to CR0 is UNIMPLEMENTED\n");
- return -1;
-
default:
{
PrintDebug("Unknown Mode write to CR0 (info->cpu_mode=0x%x\n)",info->cpu_mode);
return -1;
}
- if (info->page_mode == SHADOW_PAGING) {
+ if (info->shdw_pg_mode == SHADOW_PAGING) {
*virt_cr0 = *(struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
} else {
*virt_cr0 = *real_cr0;
break;
case PROTECTED:
- case PROTECTED_PG:
{
int index = 0;
int ret;
PrintDebug("Protected %s Mode read from CR0 at guest %s linear rip 0x%x\n",
- info->cpu_mode==PROTECTED_PG ? "Paged" : "",
- info->cpu_mode==PROTECTED_PG ? "virtual" : "",
- get_addr_linear(info,info->rip,&(info->segments.cs)));
+ info->mem_mode == VIRTUAL_MEM ? "Paged" : "",
+ info->mem_mode == VIRTUAL_MEM ? "virtual" : "",
+ get_addr_linear(info, info->rip, &(info->segments.cs)));
// We need to read the instruction, which is at CS:IP, but that
// linear address is guest physical without PG and guest virtual with PG
- if (info->cpu_mode==PROTECTED) {
+ if (info->cpu_mode == PHYSICAL_MEM) {
// The real rip address is actually a combination of the rip + CS base
ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
- } else { // PROTECTED_PG
+ } else {
// The real rip address is actually a combination of the rip + CS base
ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
}
if (ret != 15) {
// I think we should inject a GPF into the guest
PrintDebug("Could not read Protected %s mode instruction (ret=%d)\n",
- info->cpu_mode==PROTECTED_PG ? "Paged" : "", ret);
+ info->cpu_mode == VIRTUAL_MEM ? "Paged" : "", ret);
return -1;
}
virt_cr0 = (struct cr0_32 *)first_operand;
- if (info->page_mode == SHADOW_PAGING) {
+ if (info->shdw_pg_mode == SHADOW_PAGING) {
*virt_cr0 = *(struct cr0_32 *)&(info->shdw_pg_state.guest_cr0);
+ if (info->cpu_mode==PROTECTED) {
+ virt_cr0->pg=0; // clear the pg bit because guest doesn't think it's on
+ }
} else {
*virt_cr0 = *real_cr0;
}
PrintDebug("Protected PAE Mode read to CR0 is UNIMPLEMENTED\n");
return -1;
- case PROTECTED_PAE_PG:
- PrintDebug("Protected PAE Paged Mode read to CR0 is UNIMPLEMENTED\n");
- return -1;
-
case LONG:
PrintDebug("Protected Long Mode read to CR0 is UNIMPLEMENTED\n");
return -1;
- case LONG_PG:
- PrintDebug("Protected Long Paged Mode read to CR0 is UNIMPLEMENTED\n");
- return -1;
+
default:
{
PrintDebug("Unknown Mode read from CR0 (info->cpu_mode=0x%x)\n",info->cpu_mode);
int handle_cr3_write(struct guest_info * info) {
- if ((info->cpu_mode == PROTECTED) || (info->cpu_mode == PROTECTED_PG)) {
+ if (info->cpu_mode == PROTECTED) {
int index = 0;
int ret;
char instr[15];
+ PrintDebug("Protected %s mode write to CR3 at %s 0x%x\n",
+ info->cpu_mode==PROTECTED ? "" : "Paged",
+ info->cpu_mode==PROTECTED ? "guest physical" : "guest virtual",
+ get_addr_linear(info,info->rip,&(info->segments.cs)));
+
+ // We need to read the instruction, which is at CS:IP, but that
+ // linear address is guest physical without PG and guest virtual with PG
+ if (info->mem_mode == PHYSICAL_MEM) {
+ // The real rip address is actually a combination of the rip + CS base
+ PrintDebug("Writing Guest CR3 Write (Physical Address)\n");
+ ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
+ } else {
+ PrintDebug("Writing Guest CR3 Write (Virtual Address)\n");
+ // The real rip address is actually a combination of the rip + CS base
+ ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
+ }
- /* Isn't the RIP a Guest Virtual Address???????? */
- ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
if (ret != 15) {
PrintDebug("Could not read instruction (ret=%d)\n", ret);
return -1;
new_cr3 = (struct cr3_32 *)first_operand;
- if (info->page_mode == SHADOW_PAGING) {
+ if (info->shdw_pg_mode == SHADOW_PAGING) {
addr_t shadow_pt;
struct cr3_32 * shadow_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.shadow_cr3);
struct cr3_32 * guest_cr3 = (struct cr3_32 *)&(info->shdw_pg_state.guest_cr3);
- PrintDebug("fooo1\n");
/* Delete the current Page Tables */
delete_page_tables_pde32((pde32_t *)CR3_TO_PDE32(*(uint_t*)shadow_cr3));
- PrintDebug("fooo2\n");
+ PrintDebug("Old Shadow CR3=%x; Old Guest CR3=%x\n",
+ *(uint_t*)shadow_cr3, *(uint_t*)guest_cr3);
+
+
*guest_cr3 = *new_cr3;
+
+
// Something like this
shadow_pt = create_new_shadow_pt32(info);
//shadow_pt = setup_shadow_pt32(info, CR3_TO_PDE32(*(addr_t *)new_cr3));
-
/* Copy Various flags */
*shadow_cr3 = *new_cr3;
+
+
shadow_cr3->pdt_base_addr = PD32_BASE_ADDR(shadow_pt);
- if (info->cpu_mode == PROTECTED_PG) {
+ PrintDebug("New Shadow CR3=%x; New Guest CR3=%x\n",
+ *(uint_t*)shadow_cr3, *(uint_t*)guest_cr3);
+
+
+
+ if (info->mem_mode == VIRTUAL_MEM) {
// If we aren't in paged mode then we have to preserve the identity mapped CR3
info->ctrl_regs.cr3 = *(addr_t*)shadow_cr3;
}
} else {
PrintDebug("Unknown Instruction\n");
+ SerialMemDump(instr,15);
return -1;
}
} else {
- PrintDebug("Invalid operating Mode\n");
+ PrintDebug("Invalid operating Mode (0x%x)\n", info->cpu_mode);
return -1;
}
int handle_cr3_read(struct guest_info * info) {
- if ((info->cpu_mode == PROTECTED) || (info->cpu_mode == PROTECTED_PG)) {
+ if (info->cpu_mode == PROTECTED) {
int index = 0;
int ret;
char instr[15];
- ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
+
+ // We need to read the instruction, which is at CS:IP, but that
+ // linear address is guest physical without PG and guest virtual with PG
+ if (info->cpu_mode == PHYSICAL_MEM) {
+ // The real rip address is actually a combination of the rip + CS base
+ ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
+ } else {
+ // The real rip address is actually a combination of the rip + CS base
+ ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 15, instr);
+ }
+
if (ret != 15) {
PrintDebug("Could not read instruction (ret=%d)\n", ret);
return -1;
virt_cr3 = (struct cr3_32 *)first_operand;
- if (info->page_mode == SHADOW_PAGING) {
+ if (info->shdw_pg_mode == SHADOW_PAGING) {
*virt_cr3 = *(struct cr3_32 *)&(info->shdw_pg_state.guest_cr3);
} else {
*virt_cr3 = *real_cr3;
info->rip += index;
} else {
PrintDebug("Unknown Instruction\n");
+ SerialMemDump(instr,15);
return -1;
}
} else {
- PrintDebug("Invalid operating Mode\n");
+ PrintDebug("Invalid operating Mode (0x%x)\n", info->cpu_mode);
return -1;
}