int main (int argc, char **argv) { vmi_instance_t vmi = NULL; status_t status = VMI_SUCCESS; struct sigaction act; mm_enabled=0; char *name = NULL; if(argc < 2){ fprintf(stderr, "Usage: %s <name of VM>\n", argv[0]); exit(1); } // Arg 1 is the VM name. name = argv[1]; /* for a clean exit */ act.sa_handler = close_handler; act.sa_flags = 0; sigemptyset(&act.sa_mask); sigaction(SIGHUP, &act, NULL); sigaction(SIGTERM, &act, NULL); sigaction(SIGINT, &act, NULL); sigaction(SIGALRM, &act, NULL); // Initialize the libvmi library. if (vmi_init(&vmi, VMI_XEN | VMI_INIT_COMPLETE | VMI_INIT_EVENTS, name) == VMI_FAILURE){ printf("Failed to init LibVMI library.\n"); if (vmi != NULL ) { vmi_destroy(vmi); } return 1; } else{ printf("LibVMI init succeeded!\n"); } vmi_pause_vm(vmi); SETUP_REG_EVENT(&cr3_event, CR3, VMI_REGACCESS_W, 0, cr3_callback); vmi_register_event(vmi, &cr3_event); // Setup a mem event for tracking memory at the current instruction's page // But don't install it; that will be done by the cr3 handler. vmi_get_vcpureg(vmi, &rip, RIP, 0); vmi_get_vcpureg(vmi, &cr3, CR3, 0); printf("Current value of RIP is 0x%lx\n", rip); rip -= 0x1; pid = vmi_dtb_to_pid(vmi, cr3); if(pid==4) { rip_pa = vmi_translate_uv2p(vmi, rip, pid); } else { rip_pa = vmi_translate_kv2p(vmi, rip); } printf("Preparing memory event to catch next RIP 0x%lx, PA 0x%lx, page 0x%lx for PID %u\n", rip, rip_pa, rip_pa >> 12, pid); SETUP_MEM_EVENT(&mm_event, rip_pa, VMI_MEMEVENT_PAGE, VMI_MEMACCESS_X, mm_callback); vmi_resume_vm(vmi); while(!interrupted){ status = vmi_events_listen(vmi,500); if (status != VMI_SUCCESS) { printf("Error waiting for events, quitting...\n"); interrupted = -1; } } printf("Finished with test.\n"); leave: // cleanup any memory associated with the libvmi instance vmi_destroy(vmi); return 0; }
event_response_t cr3_callback(vmi_instance_t vmi, vmi_event_t *event) { va_pages = vmi_get_va_pages(vmi, event->reg_event.value); GSList *loop = va_pages; while(loop) { page_info_t *page = loop->data; // Demonstrate using access_context_t access_context_t ctx = { .translate_mechanism = VMI_TM_PROCESS_DTB, .addr = page->vaddr, .dtb = event->reg_event.value, }; uint64_t test; if(VMI_FAILURE == vmi_read_64(vmi, &ctx, &test)) { printf("Page in virtual address space of DTB 0x%"PRIx64" unaccessible: 0x%"PRIx64".\t" "Size: 0x%"PRIx64"\n", ctx.dtb, page->vaddr, (uint64_t)page->size); } loop=loop->next; } free_va_pages(); return 0; } int main (int argc, char **argv) { vmi_instance_t vmi = NULL; status_t status = VMI_SUCCESS; struct sigaction act; char *name = NULL; va_pages = NULL; if(argc < 2) { fprintf(stderr, "Usage: events_example <name of VM>\n"); exit(1); } // Arg 1 is the VM name. name = argv[1]; /* for a clean exit */ act.sa_handler = close_handler; act.sa_flags = 0; sigemptyset(&act.sa_mask); sigaction(SIGHUP, &act, NULL); sigaction(SIGTERM, &act, NULL); sigaction(SIGINT, &act, NULL); sigaction(SIGALRM, &act, NULL); // Initialize the libvmi library. if (vmi_init(&vmi, VMI_XEN | VMI_INIT_COMPLETE | VMI_INIT_EVENTS, name) == VMI_FAILURE) { printf("Failed to init LibVMI library.\n"); if (vmi != NULL ) { vmi_destroy(vmi); } return 1; } else { printf("LibVMI init succeeded!\n"); } /* Configure an event to track when the process is running. * (The CR3 register is updated on task context switch, allowing * us to follow as various tasks are scheduled and run upon the CPU) */ SETUP_REG_EVENT(&cr3_event, CR3, VMI_REGACCESS_W, 0, cr3_callback); vmi_register_event(vmi, &cr3_event); while(!interrupted) { printf("Waiting for events...\n"); status = vmi_events_listen(vmi,500); if (status != VMI_SUCCESS) { printf("Error waiting for events, quitting...\n"); interrupted = -1; } } printf("Finished with test.\n"); free_va_pages(); // cleanup any memory associated with the libvmi instance vmi_destroy(vmi); return 0; }