Пример #1
0
status_t
vmi_init_complete_custom(
    vmi_instance_t *vmi,
    uint32_t flags,
    vmi_config_t config)
{
    if (!vmi)
        return VMI_FAILURE;

    flags |= VMI_INIT_COMPLETE | (*vmi)->mode;

    if ( flags & VMI_CONFIG_STRING ) {
        char *name = NULL;

        if (VMI_FILE == (*vmi)->mode) {
            name = strdup((*vmi)->image_type_complete);
        } else {
            name = strdup((*vmi)->image_type);
        }

        vmi_destroy(*vmi);
        return vmi_init_private(vmi,
                                flags,
                                VMI_INVALID_DOMID,
                                name,
                                (vmi_config_t)config);
    }

    vmi_destroy(*vmi);
    return vmi_init_custom(vmi, flags, config);
}
Пример #2
0
void resume_vm(vmi_instance_t *vmi)
{
    /* resume the vm */
    /* cleanup any memory associated with the LibVMI instance */
    vmi_resume_vm(*vmi);
    vmi_destroy(*vmi);
}
Пример #3
0
END_TEST

#if ENABLE_KVM == 1
/* test vmi_get_dgvma */
// we use vmi_read_va() to verify vmi_get_dgvma()
START_TEST (test_vmi_get_dgvma)
{
    vmi_instance_t vmi = NULL;
    vmi_init(&vmi, VMI_AUTO | VMI_INIT_COMPLETE, get_testvm());
    vmi_shm_snapshot_create(vmi);

    addr_t va = 0x0;
    size_t count = 4096;
    unsigned long max_size = 0xffff;
    void *buf_readva = malloc(count);
    void *buf_dgvma = NULL;
    for (; va + count <= max_size; va += count) {
        size_t read_va = vmi_read_va(vmi, va, 0, buf_readva, count);
        size_t read_dgvma = vmi_get_dgvma(vmi, va, 0, &buf_dgvma, count);
        fail_unless(read_va == read_dgvma, "vmi_get_dgvma(0x%"PRIx64
            ") read size %d dosn't conform to %d of vmi_read_va()",
            va, read_dgvma, read_va);

        int cmp = memcmp(buf_readva, buf_dgvma, read_va);
        fail_unless(0 == cmp, "vmi_get_dgvma(0x%"PRIx64
            ") contents dosn't conform to vmi_read_va()", va);
    }
    free(buf_readva);

    vmi_shm_snapshot_destroy(vmi);
    vmi_destroy(vmi);
}
Пример #4
0
END_TEST

/* test vmi_translate_uv2p */
//TODO figure out how to test this
//START_TEST (test_libvmi_uv2p)
//{
//    vmi_translate_uv2p(vmi, vaddr, pid)
//}
//END_TEST

/* test vmi_translate_ksym2v */
START_TEST (test_libvmi_ksym2v)
{
    vmi_instance_t vmi = NULL;
    vmi_init(&vmi, VMI_AUTO | VMI_INIT_COMPLETE, get_testvm());
    addr_t va = 0;
    if (VMI_OS_WINDOWS == vmi_get_ostype(vmi)){
        va = vmi_translate_ksym2v(vmi, "PsInitialSystemProcess");
    }
    else if (VMI_OS_LINUX == vmi_get_ostype(vmi)){
        va = vmi_translate_ksym2v(vmi, "init_task");
    }
    else{
        fail_unless(0, "vmi set to invalid os type");
    }
    fail_unless(va != 0, "ksym2v translation failed");
    vmi_destroy(vmi);
}
Пример #5
0
int main (int argc, char **argv)
{
    vmi_instance_t vmi;
    char *memory = (char *) malloc(PAGE_SIZE);

    /* this is the VM or file that we are looking at */
    char *name = argv[1];

    /* this is the symbol to map */
    char *symbol = argv[2];

    /* initialize the libvmi library */
    if (vmi_init(&vmi, VMI_AUTO | VMI_INIT_COMPLETE, name) == VMI_FAILURE){
        printf("Failed to init LibVMI library.\n");
        goto error_exit;
    }

    /* get memory starting at symbol for the next PAGE_SIZE bytes */
    if (PAGE_SIZE != vmi_read_ksym(vmi, symbol, memory, PAGE_SIZE)){
        printf("failed to get symbol's memory.\n");
        goto error_exit;
    }
    vmi_print_hex(memory, PAGE_SIZE);

error_exit:
    if (memory) free(memory);

    /* cleanup any memory associated with the libvmi instance */
    vmi_destroy(vmi);

    return 0;
}
Пример #6
0
status_t
vmi_init_complete(
    vmi_instance_t *vmi,
    const char *config)
{
    uint32_t flags = VMI_INIT_COMPLETE | (*vmi)->mode;

    char *name = NULL;

    if (VMI_FILE == (*vmi)->mode) {
        name = strdup((*vmi)->image_type_complete);
    }
    else {
        name = strdup((*vmi)->image_type);
    }

    if(config) {
        flags |= VMI_CONFIG_STRING;
    } else if(name && ((*vmi)->config_mode & VMI_CONFIG_GLOBAL_FILE_ENTRY)) {
        flags |= VMI_CONFIG_GLOBAL_FILE_ENTRY;
    } else {
        flags |= VMI_CONFIG_NONE;
    }

    if (((*vmi)->flags) & VMI_INIT_EVENTS) {
        flags |= VMI_INIT_EVENTS;
    }

    vmi_destroy(*vmi);
    return vmi_init_private(vmi,
                            flags,
                            VMI_INVALID_DOMID,
                            name,
                            (vmi_config_t)config);
}
Пример #7
0
int main(int argc, char **argv) {

    vmi_instance_t vmi;

    /* this is the VM that we are looking at */
    if (argc != 3) {
        printf("Usage: %s name|domid <domain name|domain id>\n", argv[0]);
        return 1;
    }   // if

    uint32_t domid = VMI_INVALID_DOMID;
    GHashTable *config = g_hash_table_new(g_str_hash, g_str_equal);

    if(strcmp(argv[1],"name")==0) {
        g_hash_table_insert(config, "name", argv[2]);
    } else
    if(strcmp(argv[1],"domid")==0) {
        domid = atoi(argv[2]);
        g_hash_table_insert(config, "domid", &domid);
    } else {
        printf("You have to specify either name or domid!\n");
        return 1;
    }

    /* partialy initialize the libvmi library */
    if (vmi_init_custom(&vmi, VMI_AUTO | VMI_INIT_PARTIAL | VMI_CONFIG_GHASHTABLE, config) == VMI_FAILURE) {
        printf("Failed to init LibVMI library.\n");
        g_hash_table_destroy(config);
        return 1;
    }
    g_hash_table_destroy(config);

    /* the nice thing about the windows kernel is that it's page aligned */
    uint32_t i;
    uint32_t found = 0;
    for(i = 0; i < MAX_SEARCH_SIZE; i += PAGE_SIZE) {

        uint8_t pe[MAX_HEADER_SIZE];

        if(VMI_SUCCESS == peparse_get_image_phys(vmi, i, MAX_HEADER_SIZE, pe)) {
            if(VMI_SUCCESS == is_WINDOWS_KERNEL(vmi, i, pe)) {

                printf("Windows Kernel found @ 0x%"PRIx32"\n", i);
                print_os_version(vmi, i, pe);
                print_guid(vmi, i, pe);
                print_pe_header(vmi, i, pe);
                found=1;
                break;
            }
        }
    }

    /* cleanup any memory associated with the LibVMI instance */
    vmi_destroy(vmi);

    if(found) return 0;
    return 1;
}
Пример #8
0
int main(int argc, char **argv) {

	vmi_instance_t vmi;
	addr_t start_address;
	struct timeval ktv_start;
	struct timeval ktv_end;

	char *vm = argv[1];
	int buf_size = atoi(argv[2]);
	int loops = atoi(argv[3]);
	int mode = atoi(argv[4]);
	unsigned char *buf = malloc(buf_size);

	int i = 0;
	long int diff;
	long int *data = malloc(loops * sizeof(long int));

	int j = 0;
	uint32_t value = 0;

	if (mode != 1 && mode != 2) {
		printf("invalid mode\n");
		return 1;
	}

	/* initialize the xen access library */
	vmi_init(&vmi, VMI_AUTO | VMI_INIT_COMPLETE, vm);

	/* find address to work from */
	start_address = vmi_translate_ksym2v(vmi, "PsInitialSystemProcess");
	start_address = vmi_translate_kv2p(vmi, start_address);

	for (i = 0; i < loops; ++i) {
		if (mode == 1) {
			gettimeofday(&ktv_start, 0);
			vmi_read_pa(vmi, start_address, buf, buf_size);
			gettimeofday(&ktv_end, 0);
		} else {
			gettimeofday(&ktv_start, 0);
			for (j = 0; j < buf_size / 4; ++j) {
				vmi_read_32_pa(vmi, start_address + j * 4, &value);
			}
			gettimeofday(&ktv_end, 0);
		}

		print_measurement(ktv_start, ktv_end, &diff);
		data[i] = diff;
		memset(buf, 0, buf_size);
		sleep(1);
	}

	avg_measurement(data, loops);

	vmi_destroy(vmi);
	free(buf);
	return 0;
}
Пример #9
0
status_t
vmi_init_complete_custom(
    vmi_instance_t *vmi,
    uint32_t flags,
    vmi_config_t config)
{
    flags |= VMI_INIT_COMPLETE | (*vmi)->mode;
    vmi_destroy(*vmi);
    return vmi_init_custom(vmi, flags, config);
}
Пример #10
0
END_TEST

/* test auto complete init */
START_TEST (test_libvmi_init1)
{
    vmi_instance_t vmi = NULL;
    status_t ret = vmi_init(&vmi, VMI_AUTO | VMI_INIT_COMPLETE, get_testvm());
    fail_unless(ret == VMI_SUCCESS,
                "vmi_init failed with AUTO | COMPLETE");
    fail_unless(vmi != NULL,
                "vmi_init failed to initialize vmi instance struct");
    vmi_destroy(vmi);
}
Пример #11
0
int main (int argc, char **argv) {
    vmi_instance_t vmi;
    struct sigaction act;
    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);

    char *name = NULL;

    if(argc < 2){
        fprintf(stderr, "Usage: interrupt_events_example <name of VM>\n");
        exit(1);
    }

    // Arg 1 is the VM name.
    name = argv[1];

    // Initialize the libvmi library.
    if (vmi_init(&vmi, VMI_XEN | VMI_INIT_PARTIAL | VMI_INIT_EVENTS, name) == VMI_FAILURE){
        printf("Failed to init LibVMI library.\n");
        return 1;
    }
    else{
        printf("LibVMI init succeeded!\n");
    }

    /* Register event to track INT3 interrupts */
    memset(&interrupt_event, 0, sizeof(vmi_event_t));
    interrupt_event.type = VMI_EVENT_INTERRUPT;
    interrupt_event.interrupt_event.enabled = 1;
    interrupt_event.interrupt_event.reinject = 1;
    interrupt_event.callback = int3_cb;

    vmi_register_event(vmi, &interrupt_event);

    printf("Waiting for events...\n");
    while(!interrupted){
        vmi_events_listen(vmi,500);
    }
    printf("Finished with test.\n");

leave:
    // cleanup any memory associated with the libvmi instance
    vmi_destroy(vmi);

    return 0;
}
Пример #12
0
END_TEST

/* test auto complete init */
START_TEST (test_libvmi_init1)
{
    vmi_instance_t vmi = NULL;
    status_t ret = vmi_init_complete(&vmi, (void*)get_testvm(), VMI_INIT_DOMAINNAME, NULL,
                                     VMI_CONFIG_GLOBAL_FILE_ENTRY, NULL, NULL);
    fail_unless(ret == VMI_SUCCESS,
                "vmi_init failed with VMI_INIT_DOMAINNAME and global config");
    fail_unless(vmi != NULL,
                "vmi_init failed to initialize vmi instance struct");
    vmi_destroy(vmi);
}
Пример #13
0
END_TEST

/* test determine mode and init function */
START_TEST (test_libvmi_init2)
{
    vmi_instance_t vmi = NULL;
    vmi_mode_t mode;
    status_t ret = vmi_get_access_mode(vmi, (void*)get_testvm(), VMI_INIT_DOMAINNAME, NULL, &mode);
    fail_unless(ret == VMI_SUCCESS,
                "vmi_get_access_mode failed to identify the hypervisor");
    ret = vmi_init(&vmi, mode, (void*)get_testvm(), VMI_INIT_DOMAINNAME, NULL, NULL);
    fail_unless(ret == VMI_SUCCESS,
                "vmi_init failed");
    fail_unless(vmi != NULL,
                "vmi_init failed to initialize vmi instance struct");
    vmi_destroy(vmi);
}
Пример #14
0
Файл: hvm.c Проект: allewwaly/HI
int main(int argc, char **argv)
{
        vmi_instance_t vmi = NULL;
        status_t status = VMI_SUCCESS;
        if (argc != 2) {
                printf("Usage: %s <vmname>\n", argv[0]);
                return 1;
        }
        char *name=argv[1];
	//vmi_pid_t pid=atoi(argv[3]);
        if (vmi_init(&vmi, VMI_AUTO | VMI_INIT_COMPLETE | VMI_INIT_EVENTS, name) == VMI_FAILURE) {
                printf("Failed to init LibVMI library.\n");
                return 1;
        }
        printf("success to init LibVMI\n");
	int i;
	vmi_pause_vm(vmi);
	for (i = 0; i < num; i++) {
		char *vaddr_str=hypercall_address[i][1];
		char *hypercall_name=hypercall_address[i][0];
	        vaddr[i] =(addr_t) strtoul(vaddr_str, NULL, 16);
		printf("virtual address is:%lx\n",vaddr[i]);
		//printf("pid is: %d\n",pid);
        	paddr[i] = vmi_translate_kv2p(vmi,vaddr[i]);
	        printf("physical address is::%lx\n",paddr[i]);
		mm_event[i].mem_event.gla2 = vaddr[i];//add comparing gla to memory event structure
		mm_event[i].mem_event.hypercall=hypercall_name;
		printf("Preparing memory event to catch HYPERCALL %s at PA 0x%lx, page 0x%lx\n\n",
	            hypercall_name, paddr[i], paddr[i] >> 12);
		SETUP_MEM_EVENT(&mm_event[i], paddr[i], VMI_MEMEVENT_PAGE,
        	            VMI_MEMACCESS_RWX, mm_callback);
		vmi_register_event(vmi,&mm_event[i]);
	}
	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");
        vmi_destroy(vmi);
        return 1;
}
Пример #15
0
END_TEST

/* test partial init and init_complete function */
START_TEST (test_libvmi_init2)
{
    vmi_instance_t vmi = NULL;
    status_t ret = vmi_init(&vmi, VMI_AUTO | VMI_INIT_PARTIAL, get_testvm());
    fail_unless(ret == VMI_SUCCESS,
                "vmi_init failed with AUTO | PARTIAL");
    fail_unless(vmi != NULL,
                "vmi_init failed to initialize vmi instance struct");
    ret = vmi_init_complete(&vmi, NULL);
    fail_unless(ret == VMI_SUCCESS,
                "vmi_init_complete failed");
    fail_unless(vmi != NULL,
                "vmi_init_complete failed to initialize vmi instance struct");
    vmi_destroy(vmi);
}
Пример #16
0
int
main(
    int argc,
    char **argv)
{
    if ( argc != 3 )
        return 1;

    vmi_instance_t vmi;
    unsigned char *memory = malloc(PAGE_SIZE);

    /* this is the VM or file that we are looking at */
    char *name = argv[1];

    /* this is the address to map */
    char *addr_str = argv[2];
    addr_t addr = (addr_t) strtoul(addr_str, NULL, 16);

    /* initialize the libvmi library */
    if (VMI_FAILURE ==
        vmi_init_complete(&vmi, name, VMI_INIT_DOMAINNAME, NULL,
                          VMI_CONFIG_GLOBAL_FILE_ENTRY, NULL, NULL))
    {
        printf("Failed to init LibVMI library.\n");
        goto error_exit;
    }

    /* get the symbol's memory page */
    if (VMI_FAILURE == vmi_read_va(vmi, addr, 0, PAGE_SIZE, memory, NULL)) {
        printf("failed to map memory.\n");
        goto error_exit;
    }
    vmi_print_hex(memory, PAGE_SIZE);

error_exit:
    if (memory)
        free(memory);

    /* cleanup any memory associated with the libvmi instance */
    vmi_destroy(vmi);

    return 0;
}
Пример #17
0
int main(int argc, char **argv) {

    vmi_instance_t vmi;

    /* this is the VM that we are looking at */
    if (argc != 2) {
        printf("Usage: %s <domain name>\n", argv[0]);
        return 1;
    }   // if

    /* partialy initialize the libvmi library */
    if (vmi_init(&vmi, VMI_AUTO | VMI_INIT_PARTIAL, argv[1]) == VMI_FAILURE) {
        printf("Failed to init LibVMI library.\n");
        return 1;
    }

    /* the nice thing about the windows kernel is that it's page aligned */
    uint32_t i;
    uint32_t found = 0;
    for(i = 0; i < MAX_SEARCH_SIZE; i += PAGE_SIZE) {

        uint8_t pe[MAX_HEADER_SIZE];

        if(VMI_SUCCESS == peparse_get_image_phys(vmi, i, MAX_HEADER_SIZE, pe)) {
            if(VMI_SUCCESS == is_WINDOWS_KERNEL(vmi, i, pe)) {

                printf("Windows Kernel found @ 0x%"PRIx32"\n", i);
                print_os_version(vmi, i, pe);
                print_guid(vmi, i, pe);
                print_pe_header(vmi, i, pe);
                found=1;
                break;
            }
        }
    }

    /* cleanup any memory associated with the LibVMI instance */
    vmi_destroy(vmi);

    if(found) return 0;
    return 1;
}
Пример #18
0
int mit_main (int argc, char **argv)
{
    vmi_instance_t vmi;
    unsigned char *memory = NULL;
    uint32_t offset;
    addr_t list_head = 0, current_list_entry = 0, next_list_entry = 0;
    addr_t current_process = 0;
    addr_t tmp_next = 0;
    char *procname = NULL;
    uint32_t pid = 0;
    unsigned long tasks_offset, pid_offset, name_offset;
    status_t status;
    int i;

    /* initialize the libvmi library */
    vmi_init(&vmi, VMI_AUTO | VMI_INIT_COMPLETE, argv[1]);
    vmi_destroy(vmi);

    return 0;
}
Пример #19
0
END_TEST

START_TEST (test_vmi_get_memsize_max_phys_addr)
{
    vmi_instance_t vmi = NULL;
    uint64_t memsize = 0;
    addr_t max_physical_addr = 0;

    vmi_init_complete(&vmi, (void*)get_testvm(), VMI_INIT_DOMAINNAME, NULL,
                      VMI_CONFIG_GLOBAL_FILE_ENTRY, NULL, NULL);

    memsize = vmi_get_memsize(vmi);
    max_physical_addr = vmi_get_max_physical_address(vmi);

    fail_unless(memsize > 0, "guest ram size is 0");
    fail_unless(max_physical_addr > 0, "max physical address is 0");

    fail_unless(max_physical_addr >= memsize, "max physical address is less than memsize");

    vmi_destroy(vmi);
}
Пример #20
0
END_TEST

/* test vmi_translate_kv2p */
START_TEST (test_libvmi_kv2p)
{
    vmi_instance_t vmi = NULL;
    vmi_init(&vmi, VMI_AUTO | VMI_INIT_COMPLETE, get_testvm());
    addr_t va = 0;
    if (VMI_OS_WINDOWS == vmi_get_ostype(vmi)){
        va = vmi_translate_ksym2v(vmi, "PsInitialSystemProcess");
    }
    else if (VMI_OS_LINUX == vmi_get_ostype(vmi)){
        va = vmi_translate_ksym2v(vmi, "init_task");
    }
    else{
        fail_unless(0, "vmi set to invalid os type");
    }
    addr_t pa = vmi_translate_kv2p(vmi, va);
    fail_unless(pa != 0, "kv2p translation failed");
    vmi_destroy(vmi);
}
Пример #21
0
int main(int argc, char **argv) {

	vmi_instance_t vmi;
	addr_t vaddr;
	struct timeval ktv_start;
	struct timeval ktv_end;

	char *vm = argv[1];
	int loops = atoi(argv[2]);
	int i = 0;
	long int diff;
	long int *data = malloc(loops * sizeof(long int));

	/* initialize the xen access library */
	vmi_init(&vmi, VMI_AUTO | VMI_INIT_COMPLETE, vm);

	for (i = 0; i < loops; ++i) {
		gettimeofday(&ktv_start, 0);
		vaddr = vmi_translate_ksym2v(vmi, "PsGetCurrentThread");
		gettimeofday(&ktv_end, 0);

		if (0 == vaddr) {
			perror("failed to lookup kernel symbol");
			goto error_exit;
		}

		print_measurement(ktv_start, ktv_end, &diff);
		data[i] = diff;
		sleep(2);
	}

	avg_measurement(data, loops);

	error_exit: vmi_destroy(vmi);
	free(data);
	return 0;
}
Пример #22
0
END_TEST

/* test vmi_get_dgpma */
// we use vmi_read_pa() to verify vmi_get_dgpma()
START_TEST (test_vmi_get_dgpma)
{
    vmi_instance_t vmi = NULL;
    vmi_init(&vmi, VMI_AUTO | VMI_INIT_COMPLETE, get_testvm());
    vmi_shm_snapshot_create(vmi);

    addr_t pa = 0x1000; // just because vmi_read_page() deny to fetch frame 0.
    size_t count = 4096;
    unsigned long max_size = vmi_get_max_physical_address(vmi);
    void *buf_readpa = malloc(count);
    void *buf_dgpma = NULL;
    for (; pa + count <= max_size; pa += count) {
        size_t read_pa = vmi_read_pa(vmi, pa, buf_readpa, count);
        size_t read_dgpma = vmi_get_dgpma(vmi, pa, &buf_dgpma, count);

        if (read_pa == 0 && read_dgpma == 0) {
            continue;
        }

        fail_unless(read_pa == read_dgpma, "vmi_get_dgpma(0x%"PRIx64
            ") read size %d dosn't conform to %d of vmi_read_pa()",
            pa, read_dgpma, read_pa);

        int cmp = memcmp(buf_readpa, buf_dgpma, read_pa);
        fail_unless(0 == cmp, "vmi_get_dgpma(0x%"PRIx64
            ") contents dosn't conform to vmi_read_pa()", pa);
    }
    free(buf_readpa);

    vmi_shm_snapshot_destroy(vmi);
    vmi_destroy(vmi);
}
Пример #23
0
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;
}
Пример #24
0
void vmifs_destroy() {
    vmi_destroy(vmi);
}
Пример #25
0
int introspect_process_list (char *name) {
    vmi_instance_t vmi;
    addr_t list_head = 0, next_list_entry = 0, current_process = 0;
    vmi_pid_t pid = 0;
    char *procname = NULL;

    if (vmi_init(&vmi, VMI_XEN | VMI_INIT_COMPLETE, name) == VMI_FAILURE) {
        printf("Failed to init LibVMI library.\n");
        return 1;
    }

    vmi_pause_vm(vmi);

    /**
     * get offsets of the kernel data structures
     * get the head of the task_struct 
     */

    switch(vmi_get_ostype(vmi)) {
        case VMI_OS_LINUX:
            tasks_offset = vmi_get_offset(vmi, "linux_tasks");
            name_offset = vmi_get_offset(vmi, "linux_name");
            pid_offset = vmi_get_offset(vmi, "linux_pid");

            list_head = vmi_translate_ksym2v(vmi, "init_task") + tasks_offset;

            break;
        case VMI_OS_WINDOWS:
            tasks_offset = vmi_get_offset(vmi, "win_tasks");
            name_offset = vmi_get_offset(vmi, "win_pname");
            pid_offset = vmi_get_offset(vmi, "win_pid");

            list_head = vmi_translate_ksym2v(vmi, "PsActiveProcessHead");

            break;
        default:
            goto exit;
    }


    if (tasks_offset == 0 || pid_offset == 0 || name_offset == 0) {
        printf("Failed to find offsets\n");
        goto exit;
    }

    next_list_entry = list_head;

    /** 
     * traverse the task lists and print out each process 
     */
    do {
        current_process = next_list_entry - tasks_offset;
        vmi_read_32_va(vmi, current_process + pid_offset, 0, (uint32_t*)&pid);
        procname = vmi_read_str_va(vmi, current_process + name_offset, 0);
        if (!procname) {
            printf("Failed to find procname\n");
            goto exit;
        }

        printf("[%5d] %s\n", pid, procname);

        free(procname);
        procname = NULL;

        if (vmi_read_addr_va(vmi, next_list_entry, 0, &next_list_entry) == VMI_FAILURE) {
            printf("Failed to read next pointer in loop at %"PRIx64"\n", next_list_entry);
            goto exit;
        }

    } while(next_list_entry != list_head);

exit:
    vmi_resume_vm(vmi);
    vmi_destroy(vmi);

    return 0;
}
Пример #26
0
int main (int argc, char **argv)
{
    vmi_instance_t vmi = NULL;
    status_t status = VMI_SUCCESS;

    struct sigaction act;

    reg_t lstar = 0;
    addr_t phys_lstar = 0;
    reg_t cstar = 0;
    addr_t phys_cstar = 0;
    reg_t sysenter_ip = 0;
    addr_t phys_sysenter_ip = 0;

    addr_t ia32_sysenter_target = 0;
    addr_t phys_ia32_sysenter_target = 0;
    addr_t vsyscall = 0;
    addr_t phys_vsyscall = 0;

    char *name = NULL;
    vmi_pid_t pid = -1;

    if(argc < 2){
        fprintf(stderr, "Usage: events_example <name of VM> <PID of process to track {optional}>\n");
        exit(1);
    }

    // Arg 1 is the VM name.
    name = argv[1];

    // Arg 2 is the pid of the process to track.
    if(argc == 3)
        pid = (int) strtoul(argv[2], NULL, 0);

    /* 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");
    }

    // Get the cr3 for this process.
    /*
addr_t vmi_pid_to_dtb (vmi_instance_t vmi, vmi_pid_t pid)
Given a pid, this function returns the virtual address of the directory table base for this process' address space. 
This value is effectively what would be in the CR3 register while this process is running.

Parameters

[in] vmi LibVMI instance
[in] pid Desired process id to lookup
Returns

OrderedDict([(u'emphasis', u'pid'), ('#text', u'The directory table base virtual address for')])
    */
    if(pid != -1) {
        cr3 = vmi_pid_to_dtb(vmi, pid);  //虚拟机句柄和进程id  进程基地址
        printf("CR3 for process (%d) == %llx\n", pid, (unsigned long long)cr3);
    }

    // Get the value of lstar and cstar for the system.
    // NOTE: all vCPUs have the same value for these registers
    //status_t vmi_get_vcpureg (vmi_instance_t vmi, reg_t *value, registers_t reg, unsigned long vcpu)
  
  //获取特定寄存器值
    vmi_get_vcpureg(vmi, &lstar, MSR_LSTAR, 0); 
    vmi_get_vcpureg(vmi, &cstar, MSR_CSTAR, 0);
    vmi_get_vcpureg(vmi, &sysenter_ip, SYSENTER_EIP, 0);
  
  //在调用SYSENTER指令前,软件必须通过下面的MSR寄存器,指定0层的代码段和代码指针,0层的堆栈段和堆栈指针:
    printf("vcpu 0 MSR_LSTAR == %llx\n", (unsigned long long)lstar);
    printf("vcpu 0 MSR_CSTAR == %llx\n", (unsigned long long)cstar);
    printf("vcpu 0 MSR_SYSENTER_IP == %llx\n", (unsigned long long)sysenter_ip);

/*
addr_t vmi_translate_ksym2v (vmi_instance_t vmi, const char *symbol)
Performs the translation from a kernel symbol to a virtual address.

Parameters

[in] vmi LibVMI instance
[in] symbol Desired kernel symbol to translate
Returns

Virtual address, or zero on error
*/
    ia32_sysenter_target = vmi_translate_ksym2v(vmi, "ia32_sysenter_target");
    printf("ksym ia32_sysenter_target == %llx\n", (unsigned long long)ia32_sysenter_target);
//??? 返回结果为0 岂不是发生了error


    /* Per Linux ABI, this VA represents the start of the vsyscall page 
     *  If vsyscall support is enabled (deprecated or disabled on many newer 
     *  3.0+ kernels), it is accessible at this address in every process.
     */ 
    vsyscall = 0xffffffffff600000;

    // Translate to a physical address.
    phys_lstar= vmi_translate_kv2p(vmi, lstar);
    printf("Physical LSTAR == %llx0\n", (unsigned long long)phys_lstar);

    phys_cstar= vmi_translate_kv2p(vmi, cstar);
    printf("Physical CSTAR == %llx\n", (unsigned long long)phys_cstar);

    phys_sysenter_ip= vmi_translate_kv2p(vmi, sysenter_ip);
    printf("Physical SYSENTER_IP == %llx\n", (unsigned long long)phys_sysenter_ip);

    phys_ia32_sysenter_target = vmi_translate_kv2p(vmi,ia32_sysenter_target);
    printf("Physical ia32_sysenter_target == %llx\n", (unsigned long long)ia32_sysenter_target);
    /*
http://www.longene.org/forum/viewtopic.php?f=5&t=8851
在x86结构中,较新的CPU都提供了sysenter/sysexit指令,专门用于系统调用的进入和退出,由于去掉了一些不必要的检查,它的速度比以前的int指令要快。
因此在新的Linux系统中,大部分系统调用都采用了sysenter代替原来的int 80。除了一些比较慢的系统调用,如clone、execve等少数几个,因为对于这种系统调用,
进入/退出内核空间所费的时钟周期,相对于其处理时间,几乎可以忽略不计。
考虑到和glibc的对接问题,现在glibc中不直接调用int 80或者sysenter。而是采用vdso方式,在内核中生成一个页面,用于系统调用,
叫做vsyscall,在load_elf_binary时,会将其映射到用户空间,glibc直接调用其中的函数。

关于sysenter的一些资料,可以看这里http://www.cnblogs.com/yangnas/archive/2010/04/28/1723232.html
    */
    phys_vsyscall = vmi_translate_kv2p(vmi,vsyscall);
    printf("Physical phys_vsyscall == %llx\n", (unsigned long long)phys_vsyscall);


    // Get only the page that the handler starts.
    printf("LSTAR Physical PFN == %llx\n", (unsigned long long)(phys_lstar >> 12));
    printf("CSTAR Physical PFN == %llx\n", (unsigned long long)(phys_cstar >> 12));
    printf("SYSENTER_IP Physical PFN == %llx\n", (unsigned long long)(phys_sysenter_ip >> 12));
    printf("phys_vsyscall Physical PFN == %llx\n", (unsigned long long)(phys_vsyscall >> 12));
    printf("phys_ia32_sysenter_target Physical PFN == %llx\n", (unsigned long long)(phys_ia32_sysenter_target >> 12));

    /* 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)
     */
    memset(&cr3_event, 0, sizeof(vmi_event_t));
    cr3_event.type = VMI_EVENT_REGISTER;
    cr3_event.reg_event.reg = CR3;

    /* Observe only write events to the given register. 
     *   NOTE: read events are unsupported at this time.
     */
    cr3_event.reg_event.in_access = VMI_REGACCESS_W;

    /* Optional (default = 0): Trigger on change 
     *  Causes events to be delivered by the hypervisor to this monitoring
     *   program if and only if the register value differs from that previously 
     *   observed.
     *  Usage: cr3_event.reg_event.onchange = 1;
     *
     * Optional (default = 0): Asynchronous event delivery
     *  Causes events to be delivered by the hypervisor to this monitoring
     *   program if and only if the register value differs from that previously
     *   observed.
     *  Usage: cr3_event.reg_event.async =1;
     */


//重要 注册事件 回调函数
    if(pid == -1){  //如果没加参数  就为-1
        cr3_event.callback = cr3_all_tasks_callback;
        vmi_register_event(vmi, &cr3_event);
    }
    else {
        cr3_event.callback = cr3_one_task_callback;
        /* This acts as a filter: if the CR3 value at time of event == the CR3
         *  we wish to inspect, then the callback will be invoked. Otherwise,
         *  no action is taken.
         */
         //只有当事件发生时,cr3的值等于我们一开始注册的进程的cr3值,才会调用回调函数
        cr3_event.reg_event.equal = cr3;            //保存原始的cr3的值
        vmi_register_event(vmi, &cr3_event);
    }


//设置内存事件,在cr3的事件处理函数中进行绑定
    // Setup a default event for tracking memory at the syscall handler.
    // But don't install it; that will be done by the cr3 handler.
    memset(&msr_syscall_sysenter_event, 0, sizeof(vmi_event_t));
    msr_syscall_sysenter_event.type = VMI_EVENT_MEMORY; 
    msr_syscall_sysenter_event.mem_event.physical_address = phys_sysenter_ip;
    msr_syscall_sysenter_event.mem_event.npages = 1;
    msr_syscall_sysenter_event.mem_event.granularity=VMI_MEMEVENT_PAGE;

    memset(&kernel_sysenter_target_event, 0, sizeof(vmi_event_t));
    kernel_sysenter_target_event.type = VMI_EVENT_MEMORY;
    kernel_sysenter_target_event.mem_event.physical_address = phys_ia32_sysenter_target;
    kernel_sysenter_target_event.mem_event.npages = 1;
    kernel_sysenter_target_event.mem_event.granularity=VMI_MEMEVENT_PAGE;

    memset(&kernel_vsyscall_event, 0, sizeof(vmi_event_t));
    kernel_vsyscall_event.type = VMI_EVENT_MEMORY;
    kernel_vsyscall_event.mem_event.physical_address = phys_vsyscall;
    kernel_vsyscall_event.mem_event.npages = 1;
    kernel_vsyscall_event.mem_event.granularity=VMI_MEMEVENT_PAGE;

    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");

leave:
    // cleanup any memory associated with the libvmi instance
    vmi_destroy(vmi);

    return 0;
}
Пример #27
0
int main (int argc, char **argv)
{
    vmi_instance_t vmi;
    unsigned char *memory = NULL;
    uint32_t offset;
    addr_t list_head = 0, next_list_entry = 0;
    addr_t current_process = 0;
    addr_t tmp_next = 0;
    char *procname = NULL;
    vmi_pid_t pid = 0;
    unsigned long tasks_offset = 0, pid_offset = 0, name_offset = 0;
    status_t status;

    /* this is the VM or file that we are looking at */
    if (argc != 2) {
        printf("Usage: %s <vmname>\n", argv[0]);
        return 1;
    } // if

    char *name = argv[1];

    /* initialize the libvmi library */
    if (vmi_init(&vmi, VMI_AUTO | VMI_INIT_COMPLETE, name) == VMI_FAILURE) {
        printf("Failed to init LibVMI library.\n");
        return 1;
    }

    /* init the offset values */
    if (VMI_OS_LINUX == vmi_get_ostype(vmi)) {
        tasks_offset = vmi_get_offset(vmi, "linux_tasks");
        name_offset = vmi_get_offset(vmi, "linux_name");
        pid_offset = vmi_get_offset(vmi, "linux_pid");
    }
    else if (VMI_OS_WINDOWS == vmi_get_ostype(vmi)) {
        tasks_offset = vmi_get_offset(vmi, "win_tasks");
        name_offset = vmi_get_offset(vmi, "win_pname");
        pid_offset = vmi_get_offset(vmi, "win_pid");
    }

    if (0 == tasks_offset) {
        printf("Failed to find win_tasks\n");
        goto error_exit;
    }
    if (0 == pid_offset) {
        printf("Failed to find win_pid\n");
        goto error_exit;
    }
    if (0 == name_offset) {
        printf("Failed to find win_pname\n");
        goto error_exit;
    }

    /* pause the vm for consistent memory access */
    if (vmi_pause_vm(vmi) != VMI_SUCCESS) {
        printf("Failed to pause VM\n");
        goto error_exit;
    } // if

    /* demonstrate name and id accessors */
    char *name2 = vmi_get_name(vmi);

    if (VMI_FILE != vmi_get_access_mode(vmi)) {
        unsigned long id = vmi_get_vmid(vmi);

        printf("Process listing for VM %s (id=%lu)\n", name2, id);
    }
    else {
        printf("Process listing for file %s\n", name2);
    }
    free(name2);

    /* get the head of the list */
    if (VMI_OS_LINUX == vmi_get_ostype(vmi)) {
        /* Begin at PID 0, the 'swapper' task. It's not typically shown by OS
         *  utilities, but it is indeed part of the task list and useful to
         *  display as such.
         */
        list_head = vmi_translate_ksym2v(vmi, "init_task") + tasks_offset;
    }
    else if (VMI_OS_WINDOWS == vmi_get_ostype(vmi)) {

        // find PEPROCESS PsInitialSystemProcess
        if(VMI_FAILURE == vmi_read_addr_ksym(vmi, "PsActiveProcessHead", &list_head)) {
            printf("Failed to find PsActiveProcessHead\n");
            goto error_exit;
        }
    }

    next_list_entry = list_head;

    /* walk the task list */
    do {

        current_process = next_list_entry - tasks_offset;

        /* Note: the task_struct that we are looking at has a lot of
         * information.  However, the process name and id are burried
         * nice and deep.  Instead of doing something sane like mapping
         * this data to a task_struct, I'm just jumping to the location
         * with the info that I want.  This helps to make the example
         * code cleaner, if not more fragile.  In a real app, you'd
         * want to do this a little more robust :-)  See
         * include/linux/sched.h for mode details */

        /* NOTE: _EPROCESS.UniqueProcessId is a really VOID*, but is never > 32 bits,
         * so this is safe enough for x64 Windows for example purposes */
        vmi_read_32_va(vmi, current_process + pid_offset, 0, (uint32_t*)&pid);

        procname = vmi_read_str_va(vmi, current_process + name_offset, 0);

        if (!procname) {
            printf("Failed to find procname\n");
            goto error_exit;
        }

        /* print out the process name */
        printf("[%5d] %s (struct addr:%"PRIx64")\n", pid, procname, current_process);
        if (procname) {
            free(procname);
            procname = NULL;
        }

        /* follow the next pointer */

        status = vmi_read_addr_va(vmi, next_list_entry, 0, &next_list_entry);
        if (status == VMI_FAILURE) {
            printf("Failed to read next pointer in loop at %"PRIx64"\n", next_list_entry);
            goto error_exit;
        }

    } while(next_list_entry != list_head);

error_exit:
    /* resume the vm */
    vmi_resume_vm(vmi);

    /* cleanup any memory associated with the LibVMI instance */
    vmi_destroy(vmi);

    return 0;
}
Пример #28
0
int main (int argc, char **argv)
{
    /* this is the VM or file that we are looking at */
    if (argc != 2) {
        printf("Usage: %s <vmname>\n", argv[0]);
        return 1;
    }

#if ENABLE_SHM_SNAPSHOT == 1
    vmi_instance_t vmi;
    addr_t list_head = 0, current_list_entry = 0, next_list_entry = 0;
    addr_t current_process = 0;
    char *procname = NULL;
    vmi_pid_t pid = 0;
    unsigned long tasks_offset, pid_offset, name_offset;

    char *name = argv[1];

    /* initialize the libvmi library */
    if (vmi_init(&vmi, VMI_AUTO | VMI_INIT_COMPLETE, name) == VMI_FAILURE) {
        printf("Failed to init LibVMI library.\n");
        return 1;
    }

    /* init the offset values */
    if (VMI_OS_LINUX == vmi_get_ostype(vmi)) {
        tasks_offset = vmi_get_offset(vmi, "linux_tasks");
        name_offset = vmi_get_offset(vmi, "linux_name");
        pid_offset = vmi_get_offset(vmi, "linux_pid");

        /* NOTE: 
         *  name_offset is no longer hard-coded. Rather, it is now set 
         *  via libvmi.conf.
         */
    }
    else if (VMI_OS_WINDOWS == vmi_get_ostype(vmi)) {
        tasks_offset = vmi_get_offset(vmi, "win_tasks");
        if (0 == tasks_offset) {
            printf("Failed to find win_tasks\n");
            goto error_exit;
        }
        name_offset = vmi_get_offset(vmi, "win_pname");
        if (0 == name_offset) {
            printf("Failed to find win_pname\n");
            goto error_exit;
        }
        pid_offset = vmi_get_offset(vmi, "win_pid");
        if (0 == pid_offset) {
            printf("Failed to find win_pid\n");
            goto error_exit;
        }
    }

    /* create a shm-snapshot */
    if (vmi_shm_snapshot_create(vmi) != VMI_SUCCESS) {
        printf("Failed to shm-snapshot VM\n");
        goto error_exit;
    }

    /* demonstrate name and id accessors */
    list_processes(vmi, current_process, list_head, tasks_offset,
        current_list_entry, next_list_entry, pid_offset, pid,
        procname, name_offset);

    error_exit: if (procname)
        free(procname);

    /* destroy the shm-snapshot, and return live mode */
    vmi_shm_snapshot_destroy(vmi);

    /* cleanup any memory associated with the LibVMI instance */
    vmi_destroy(vmi);

    return 0;
#else
    printf("Error : this example should only run after ./configure --enable-shm-snapshot.\n");
    return 1; // error
#endif

}
Пример #29
0
/*根据data,执行vmi函数,并发送返回值*/
int rvmi_handle_data(int fd, char *buf)
{
    int vmiFunNum;
    int i=0;
    char delims[] = " ";
    char *vmiFunArg[5] = {NULL,NULL,NULL,NULL};
    char returnBuf[100];
    char * returnVal =NULL;

    vmiFunArg[i] = strtok(buf, delims );
    while( vmiFunArg[i] != NULL )
    {
        i++;
        vmiFunArg[i] = strtok( NULL, delims );
    }


    vmiFunNum = atoi(vmiFunArg[0]);
    //printf("vmifun %d\n",vmiFunNum);
    switch(vmiFunNum)
    {
        case 1: break;
        case 2: break;
        case 3:
        {
            int vmiID=atoi(vmiFunArg[1]);
            sprintf(returnBuf, "%d\0", vmi_destroy(vmiArr[vmiID]) );
            vmiFlagArr[vmiID]=0;
            returnVal = returnBuf;
        }
        break;
        case 13:
        {
            sprintf(returnBuf, "%lu\0", vmi_get_offset(vmiArr[atoi(vmiFunArg[1])], vmiFunArg[2]) );
            returnVal = returnBuf;
        }

        break;
        case 23:
        {
            for(i=0;i<MAX_DOMU_PER_MACHINE;i++)
            {
                if(0 == vmiFlagArr[i])
                    break;
            }
            vmi_init(&vmiArr[i], atoi(vmiFunArg[1]), vmiFunArg[2]);
            vmiFlagArr[i]=1;
            sprintf(returnBuf,"%d\0",i);
            returnVal = returnBuf;
        }
        break;

        case 38:
        {
            uint16_t tmp;
            vmi_read_16_va(vmiArr[atoi(vmiFunArg[1])], atol(vmiFunArg[2]), atoi(vmiFunArg[3]), &tmp);
            sprintf(returnBuf, "%hu\0", tmp);
            returnVal = returnBuf;
        }
        break;

        case 40:
        {
            uint32_t tmp;
            vmi_read_32_va(vmiArr[atoi(vmiFunArg[1])], atol(vmiFunArg[2]), atoi(vmiFunArg[3]), &tmp);
            sprintf(returnBuf, "%u\0", tmp);
            returnVal = returnBuf;
        }
        break;


        case 44:
        {
            uint64_t tmp;
            vmi_read_64_va(vmiArr[atoi(vmiFunArg[1])], atol(vmiFunArg[2]), atoi(vmiFunArg[3]), &tmp);
            sprintf(returnBuf, "%lu\0", tmp);
            returnVal = returnBuf;
        }
        break;



        case 50:
        {
            addr_t tmp;
            vmi_read_addr_va(vmiArr[atoi(vmiFunArg[1])], atol(vmiFunArg[2]), atoi(vmiFunArg[3]), &tmp);
            sprintf(returnBuf, "%lu\0", tmp);
            returnVal = returnBuf;
        }
        break;
        case 55:
        {
            sprintf(returnBuf, "%s\0", vmi_read_str_va(vmiArr[atoi(vmiFunArg[1])], atol(vmiFunArg[2]), atoi(vmiFunArg[3]) ));
            returnVal = returnBuf;
        }
        break;
        case 67:
        {
            sprintf(returnBuf, "%lu\0", vmi_translate_ksym2v(vmiArr[atoi(vmiFunArg[1])], vmiFunArg[2]) );
            returnVal = returnBuf;
        }
        break;
        default:break;
    }

    write (fd, returnVal, 100);


    return 1;

}
Пример #30
0
int main (int argc, char **argv)
{
    vmi_instance_t vmi = NULL;
    status_t status = VMI_SUCCESS;

    struct sigaction act;

    reg_t lstar = 0;
    addr_t phys_lstar = 0;
    reg_t cstar = 0;
    addr_t phys_cstar = 0;
    reg_t sysenter_ip = 0;
    addr_t phys_sysenter_ip = 0;

    addr_t ia32_sysenter_target = 0;
    addr_t phys_ia32_sysenter_target = 0;
    addr_t vsyscall = 0;
    addr_t phys_vsyscall = 0;

    char *name = NULL;
    vmi_pid_t pid = -1;

    if(argc < 2){
        fprintf(stderr, "Usage: events_example <name of VM> <PID of process to track {optional}>\n");
        exit(1);
    }

    // Arg 1 is the VM name.
    name = argv[1];

    // Arg 2 is the pid of the process to track.
    if(argc == 3)
        pid = (int) strtoul(argv[2], NULL, 0);

    /* 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");
    }

    // Get the cr3 for this process.
    if(pid != -1) {
        cr3 = vmi_pid_to_dtb(vmi, pid);
        printf("CR3 for process (%d) == %llx\n", pid, (unsigned long long)cr3);
    }

    // Get the value of lstar and cstar for the system.
    // NOTE: all vCPUs have the same value for these registers
    vmi_get_vcpureg(vmi, &lstar, MSR_LSTAR, 0);
    vmi_get_vcpureg(vmi, &cstar, MSR_CSTAR, 0);
    vmi_get_vcpureg(vmi, &sysenter_ip, SYSENTER_EIP, 0);
    printf("vcpu 0 MSR_LSTAR == %llx\n", (unsigned long long)lstar);
    printf("vcpu 0 MSR_CSTAR == %llx\n", (unsigned long long)cstar);
    printf("vcpu 0 MSR_SYSENTER_IP == %llx\n", (unsigned long long)sysenter_ip);

    ia32_sysenter_target = vmi_translate_ksym2v(vmi, "ia32_sysenter_target");
    printf("ksym ia32_sysenter_target == %llx\n", (unsigned long long)ia32_sysenter_target);

    /* Per Linux ABI, this VA represents the start of the vsyscall page 
     *  If vsyscall support is enabled (deprecated or disabled on many newer 
     *  3.0+ kernels), it is accessible at this address in every process.
     */ 
    vsyscall = 0xffffffffff600000;

    // Translate to a physical address.
    phys_lstar= vmi_translate_kv2p(vmi, lstar);
    printf("Physical LSTAR == %llx\n", (unsigned long long)phys_lstar);

    phys_cstar= vmi_translate_kv2p(vmi, cstar);
    printf("Physical CSTAR == %llx\n", (unsigned long long)phys_cstar);

    phys_sysenter_ip= vmi_translate_kv2p(vmi, sysenter_ip);
    printf("Physical SYSENTER_IP == %llx\n", (unsigned long long)phys_sysenter_ip);

    phys_ia32_sysenter_target = vmi_translate_kv2p(vmi,ia32_sysenter_target);
    printf("Physical ia32_sysenter_target == %llx\n", (unsigned long long)ia32_sysenter_target);
    phys_vsyscall = vmi_translate_kv2p(vmi,vsyscall);
    printf("Physical phys_vsyscall == %llx\n", (unsigned long long)phys_vsyscall);


    // Get only the page that the handler starts.
    printf("LSTAR Physical PFN == %llx\n", (unsigned long long)(phys_lstar >> 12));
    printf("CSTAR Physical PFN == %llx\n", (unsigned long long)(phys_cstar >> 12));
    printf("SYSENTER_IP Physical PFN == %llx\n", (unsigned long long)(phys_sysenter_ip >> 12));
    printf("phys_vsyscall Physical PFN == %llx\n", (unsigned long long)(phys_vsyscall >> 12));
    printf("phys_ia32_sysenter_target Physical PFN == %llx\n", (unsigned long long)(phys_ia32_sysenter_target >> 12));

    /* 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)
     */
    memset(&cr3_event, 0, sizeof(vmi_event_t));
    cr3_event.type = VMI_EVENT_REGISTER;
    cr3_event.reg_event.reg = CR3;

    /* Observe only write events to the given register. 
     *   NOTE: read events are unsupported at this time.
     */
    cr3_event.reg_event.in_access = VMI_REGACCESS_W;

    /* Optional (default = 0): Trigger on change 
     *  Causes events to be delivered by the hypervisor to this monitoring
     *   program if and only if the register value differs from that previously 
     *   observed.
     *  Usage: cr3_event.reg_event.onchange = 1;
     *
     * Optional (default = 0): Asynchronous event delivery
     *  Causes events to be delivered by the hypervisor to this monitoring
     *   program if and only if the register value differs from that previously
     *   observed.
     *  Usage: cr3_event.reg_event.async =1;
     */

    if(pid == -1){
        cr3_event.callback = cr3_all_tasks_callback;
        vmi_register_event(vmi, &cr3_event);
    } else {
        cr3_event.callback = cr3_one_task_callback;
        /* This acts as a filter: if the CR3 value at time of event == the CR3
         *  we wish to inspect, then the callback will be invoked. Otherwise,
         *  no action is taken.
         */
        cr3_event.reg_event.equal = cr3;
        vmi_register_event(vmi, &cr3_event);
    }

    // Setup a default event for tracking memory at the syscall handler.
    // But don't install it; that will be done by the cr3 handler.
    memset(&msr_syscall_sysenter_event, 0, sizeof(vmi_event_t));
    msr_syscall_sysenter_event.type = VMI_EVENT_MEMORY;
    msr_syscall_sysenter_event.mem_event.physical_address = phys_sysenter_ip;
    msr_syscall_sysenter_event.mem_event.npages = 1;
    msr_syscall_sysenter_event.mem_event.granularity=VMI_MEMEVENT_PAGE;

    memset(&kernel_sysenter_target_event, 0, sizeof(vmi_event_t));
    kernel_sysenter_target_event.type = VMI_EVENT_MEMORY;
    kernel_sysenter_target_event.mem_event.physical_address = phys_ia32_sysenter_target;
    kernel_sysenter_target_event.mem_event.npages = 1;
    kernel_sysenter_target_event.mem_event.granularity=VMI_MEMEVENT_PAGE;

    memset(&kernel_vsyscall_event, 0, sizeof(vmi_event_t));
    kernel_vsyscall_event.type = VMI_EVENT_MEMORY;
    kernel_vsyscall_event.mem_event.physical_address = phys_vsyscall;
    kernel_vsyscall_event.mem_event.npages = 1;
    kernel_vsyscall_event.mem_event.granularity=VMI_MEMEVENT_PAGE;

    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");

leave:
    // cleanup any memory associated with the libvmi instance
    vmi_destroy(vmi);

    return 0;
}