addr_t hva;
int ret = 0;
- PrintDebug("\t ARG%d: INT - %ld\n", argnum, (long) reg);
+ PrintDebug(core->vm_info, core, "\t ARG%d: INT - %ld\n", argnum, (long) reg);
if (core->mem_mode == PHYSICAL_MEM) {
ret = v3_gpa_to_hva(core, get_addr_linear(core, reg, &(core->segments.ds)), &hva);
ret = v3_gva_to_hva(core, get_addr_linear(core, reg, &(core->segments.ds)), &hva);
}
- PrintDebug("\t STR - ");
+ PrintDebug(core->vm_info, core, "\t STR - ");
if (ret == -1) {
- PrintDebug("\n");
+ PrintDebug(core->vm_info, core, "\n");
return;
}
uint32_t c = max(MAX_CHARS, 4096 - (hva % 4096));
int i = 0;
for (; i < c && *((char*)(hva + i)) != 0; i++) {
- PrintDebug("%c", *((char*)(hva + i)));
+ PrintDebug(core->vm_info, core, "%c", *((char*)(hva + i)));
}
- PrintDebug("\n");
+ PrintDebug(core->vm_info, core, "\n");
}
static void print_syscall (uint8_t is64, struct guest_info * core) {
if (is64) {
- PrintDebug("Syscall #%ld: \"%s\"\n", (long)core->vm_regs.rax, get_linux_syscall_name64(core->vm_regs.rax));
+ PrintDebug(core->vm_info, core, "Syscall #%ld: \"%s\"\n", (long)core->vm_regs.rax, get_linux_syscall_name64(core->vm_regs.rax));
} else {
- PrintDebug("Syscall #%ld: \"%s\"\n", (long)core->vm_regs.rax, get_linux_syscall_name32(core->vm_regs.rax));
+ PrintDebug(core->vm_info, core, "Syscall #%ld: \"%s\"\n", (long)core->vm_regs.rax, get_linux_syscall_name32(core->vm_regs.rax));
}
print_arg(core, core->vm_regs.rbx, 1);
core->rip = syscall_info.target_addr;
#endif
-#ifdef V3_CONFIG_EXT_SELECTIVE_SYSCALL_EXIT
- PrintDebug("In v3_syscall_handler: syscall_nr - %d\n", syscall_nr);
-#endif
-
-
if (hook == NULL) {
#ifdef V3_CONFIG_EXT_SYSCALL_PASSTHROUGH
if (v3_hook_passthrough_syscall(core, syscall_nr) == -1) {
- PrintDebug("Error hooking passthrough syscall\n");
+ PrintDebug(core->vm_info, core, "Error hooking passthrough syscall\n");
return -1;
}
hook = syscall_hooks[syscall_nr];
inject_node);
if (inject == NULL) {
- PrintError("Problem getting inject from inject list\n");
+ PrintError(core->vm_info, core, "Problem getting inject from inject list\n");
return -1;
}
// do the inject and don't fall over if there's an inject already in
// progress
if ((ret = v3_handle_guest_inject(core, (void*)inject)) == -1) {
- PrintError("Could not run code injection: v3_syscall_handler\n");
+ PrintError(core->vm_info, core, "Could not run code injection: v3_syscall_handler\n");
return 0;
} else {
return ret;
err = hook->handler(core, syscall_nr, hook->priv_data);
if (err == -1) {
- PrintDebug("V3 Syscall Handler: Error in syscall hook\n");
+ PrintDebug(core->vm_info, core, "V3 Syscall Handler: Error in syscall hook\n");
return -1;
}
static int v3_handle_lstar_write (struct guest_info * core, uint_t msr, struct v3_msr src, void * priv_data) {
syscall_info.target_addr = (uint64_t) ((((uint64_t)src.hi) << 32) | src.lo);
- PrintDebug("LSTAR Write: %p\n", (void*)syscall_info.target_addr);
- core->ctrl_regs.lstar = syscall_info.target_addr;
+ PrintDebug(core->vm_info, core, "LSTAR Write: %p\n", (void*)syscall_info.target_addr);
+ core->msrs.lstar = syscall_info.target_addr;
return 0;
}
// virtualize the lstar
static int v3_handle_lstar_read (struct guest_info * core, uint_t msr, struct v3_msr * dst, void * priv_data) {
- PrintDebug("LSTAR Read\n");
+ PrintDebug(core->vm_info, core, "LSTAR Read\n");
dst->value = syscall_info.target_addr;
return 0;
}
static int syscall_setup (struct guest_info * core, unsigned int hcall_id, void * priv_data) {
- addr_t syscall_stub, syscall_map, ssa;
+ addr_t syscall_stub, syscall_map_gva, syscall_map_hva, ssa_gva, ssa_hva;
syscall_stub = (addr_t)core->vm_regs.rbx;
- syscall_map = (addr_t)core->vm_regs.rcx;
- ssa = (addr_t)core->vm_regs.rdx;
+ syscall_map_gva = (addr_t)core->vm_regs.rcx;
+ ssa_gva = (addr_t)core->vm_regs.rdx;
- PrintDebug("made it to syscall setup hypercall\n");
- PrintDebug("\t&syscall_stub (rbx): %p\n\t&syscall_map (rcx): %p\n", (void*)syscall_stub, (void*)syscall_map);
- PrintDebug("\t&ssa (rdx): %p\n", (void*)ssa);
+ PrintDebug(core->vm_info, core, "syscall setup hypercall:\n");
+ PrintDebug(core->vm_info, core, "\t&syscall_stub (rbx): %p\n\t&syscall_map (rcx): %p\n", (void*)syscall_stub, (void*)syscall_map_gva);
+ PrintDebug(core->vm_info, core, "\t&ssa (rdx): %p\n", (void*)ssa_gva);
+ // the guest vitual address of the asm syscall handling routine
syscall_info.syscall_stub = syscall_stub;
- syscall_info.syscall_map = (uint8_t*)syscall_map;
- syscall_info.ssa = ssa;
+
+
+ // now get the hva of the system call map so we can manipulate it in the VMM
+ if (v3_gva_to_hva(core, get_addr_linear(core, syscall_map_gva, &(core->segments.ds)), &syscall_map_hva) == 1) {
+ PrintError(core->vm_info, core, "Problem translating gva to hva for syscall map\n");
+ return -1;
+ }
+
+ if (v3_gva_to_hva(core, get_addr_linear(core, ssa_gva, &(core->segments.ds)), &ssa_hva) == 1) {
+ PrintError(core->vm_info, core, "Problem translating gva to hva for syscall map\n");
+ return -1;
+ }
+
+ PrintDebug(core->vm_info, core, "\t&syscall_map (hva): %p\n", (void*) syscall_map_hva);
+ PrintDebug(core->vm_info, core, "\t&ssa (hva): %p\n", (void*) ssa_hva);
+
+ syscall_info.syscall_map = (uint8_t*)syscall_map_hva;
+ syscall_info.ssa = ssa_hva;
/* return the original syscall entry point */
core->vm_regs.rax = syscall_info.target_addr;
/* redirect syscalls henceforth */
- core->ctrl_regs.lstar = syscall_stub;
+ core->msrs.lstar = syscall_stub;
return 0;
}
static int syscall_cleanup (struct guest_info * core, unsigned int hcall_id, void * priv_data) {
- core->ctrl_regs.lstar = syscall_info.target_addr;
- PrintDebug("original syscall entry point restored\n");
+ core->msrs.lstar = syscall_info.target_addr;
+ PrintDebug(core->vm_info, core, "original syscall entry point restored\n");
return 0;
}
static int sel_syscall_handle (struct guest_info * core, unsigned int hcall_id, void * priv_data) {
- int ret;
- addr_t hva;
struct v3_gprs regs;
- PrintDebug("caught a selectively exited syscall!\n");
- ret = v3_gva_to_hva(core, get_addr_linear(core, syscall_info.ssa, &(core->segments.ds)), &hva);
- if (ret == -1) {
- PrintError("Problem translating state save area address in sel_syscall_handle\n");
- return -1;
- }
+ PrintDebug(core->vm_info, core, "caught a selectively exited syscall\n");
/* setup registers for handler routines. They should be in the same state
* as when the system call was originally invoked */
memcpy((void*)®s, (void*)&core->vm_regs, sizeof(struct v3_gprs));
- memcpy((void*)&core->vm_regs, (void*)hva, sizeof(struct v3_gprs));
+ memcpy((void*)&core->vm_regs, (void*)syscall_info.ssa, sizeof(struct v3_gprs));
- v3_print_guest_state(core);
-
- // TODO: call syscall-independent handler
+ //v3_print_guest_state(core);
+ v3_syscall_handler(core, 0, NULL);
- memcpy((void*)hva, (void*)&core->vm_regs, sizeof(struct v3_gprs));
+ memcpy((void*)syscall_info.ssa, (void*)&core->vm_regs, sizeof(struct v3_gprs));
memcpy((void*)&core->vm_regs, (void*)®s,sizeof(struct v3_gprs));
return 0;
}
+// TODO: make these three functions guest-dependent
+int v3_syscall_on (void * ginfo, uint8_t syscall_nr) {
+ PrintDebug(VM_NONE, VCORE_NONE, "Enabling exiting for syscall #%d\n", syscall_nr);
+ syscall_info.syscall_map[syscall_nr] = 1;
+ return 0;
+}
+
+
+int v3_syscall_off (void * ginfo, uint8_t syscall_nr) {
+ PrintDebug(VM_NONE, VCORE_NONE, "Disabling exiting for syscall #%d\n", syscall_nr);
+ syscall_info.syscall_map[syscall_nr] = 0;
+ return 0;
+}
+
+
+int v3_syscall_stat (void * ginfo, uint8_t syscall_nr) {
+ return syscall_info.syscall_map[syscall_nr];
+}
+
#endif
static int init_syscall_hijack (struct v3_vm_info * vm, v3_cfg_tree_t * cfg, void ** priv_data) {
+
#ifdef V3_CONFIG_EXT_SELECTIVE_SYSCALL_EXIT
- v3_register_hypercall(vm, 0x5CA11, sel_syscall_handle, NULL);
- v3_register_hypercall(vm, 0x5CA12, syscall_setup, NULL);
- v3_register_hypercall(vm, 0x5CA13, syscall_cleanup, NULL);
+ v3_register_hypercall(vm, SYSCALL_HANDLE_HCALL, sel_syscall_handle, NULL);
+ v3_register_hypercall(vm, SYSCALL_SETUP_HCALL, syscall_setup, NULL);
+ v3_register_hypercall(vm, SYSCALL_CLEANUP_HCALL, syscall_cleanup, NULL);
#endif
+
return 0;
}
#ifdef V3_CONFIG_EXT_SYSCALL_INSTR
static int v3_handle_lstar_write (struct guest_info * core, uint_t msr, struct v3_msr src, void * priv_data) {
- PrintDebug("KCH: LSTAR Write\n");
- //PrintDebug("\tvalue: 0x%x%x\n", src.hi, src.lo);
+ PrintDebug(core->vm_info, core, "KCH: LSTAR Write\n");
+ //PrintDebug(core->vm_info, core, "\tvalue: 0x%x%x\n", src.hi, src.lo);
syscall_info.target_addr = (uint64_t) ((((uint64_t)src.hi) << 32) | src.lo);
// Set LSTAR value seen by hardware while the guest is running
- PrintDebug("replacing with %lx\n", SYSCALL_MAGIC_ADDR);
- core->ctrl_regs.lstar = SYSCALL_MAGIC_ADDR;
+ PrintDebug(core->vm_info, core, "replacing with %lx\n", SYSCALL_MAGIC_ADDR);
+ core->msrs.lstar = SYSCALL_MAGIC_ADDR;
return 0;
}
static int v3_handle_lstar_read (struct guest_info * core, uint_t msr, struct v3_msr * dst, void * priv_data) {
- PrintDebug("KCH: LSTAR Read\n");
+ PrintDebug(core->vm_info, core, "KCH: LSTAR Read\n");
dst->value = syscall_info.target_addr;
return 0;
}
#endif
-static int init_syscall_hijack_core (struct guest_info * core, void * priv_data) {
+static int init_syscall_hijack_core (struct guest_info * core, void * priv_data, void ** core_data) {
#ifdef V3_CONFIG_EXT_SW_INTERRUPTS
v3_hook_swintr(core, SYSCALL_INT_VECTOR, v3_syscall_handler, NULL);
static struct v3_extension_impl syscall_impl = {
.name = "syscall_intercept",
- .init = init_syscall_hijack,
- .deinit = deinit_syscall_hijack,
+ .vm_init = init_syscall_hijack,
+ .vm_deinit = deinit_syscall_hijack,
.core_init = init_syscall_hijack_core,
.core_deinit = NULL,
.on_entry = NULL,
if (hook == NULL) {
+ PrintError(core->vm_info, core, "Cannot allocate for syscall hook\n");
return -1;
}
if (get_syscall_hook(core, syscall_nr) != NULL) {
- PrintError("System Call #%d already hooked\n", syscall_nr);
+ PrintError(core->vm_info, core, "System Call #%d already hooked\n", syscall_nr);
return -1;
}
syscall_hooks[syscall_nr] = hook;
- PrintDebug("Hooked Syscall #%d\n", syscall_nr);
+ PrintDebug(core->vm_info, core, "Hooked Syscall #%d\n", syscall_nr);
return 0;
}
int rc = v3_hook_syscall(core, syscall_nr, passthrough_syscall_handler, NULL);
if (rc) {
- PrintError("failed to hook syscall 0x%x for passthrough (guest=0x%p)\n", syscall_nr, (void *)core);
+ PrintError(core->vm_info, core, "failed to hook syscall 0x%x for passthrough (guest=0x%p)\n", syscall_nr, (void *)core);
return -1;
} else {
- PrintDebug("hooked syscall 0x%x for passthrough (guest=0x%p)\n", syscall_nr, (void *)core);
+ PrintDebug(core->vm_info, core, "hooked syscall 0x%x for passthrough (guest=0x%p)\n", syscall_nr, (void *)core);
return 0;
}