{"action":"opened","issue":{"url":"https://api.github.com/repos/libvmi/libvmi/issues/417","repository_url":"https://api.github.com/repos/libvmi/libvmi","labels_url":"https://api.github.com/repos/libvmi/libvmi/issues/417/labels{/name}","comments_url":"https://api.github.com/repos/libvmi/libvmi/issues/417/comments","events_url":"https://api.github.com/repos/libvmi/libvmi/issues/417/events","html_url":"https://github.com/libvmi/libvmi/issues/417","id":193567644,"number":417,"title":"LibVMI doesn't clear memory events properly in callback","user":{"login":"mattshockl","id":5934002,"avatar_url":"https://avatars.githubusercontent.com/u/5934002?v=3","gravatar_id":"","url":"https://api.github.com/users/mattshockl","html_url":"https://github.com/mattshockl","followers_url":"https://api.github.com/users/mattshockl/followers","following_url":"https://api.github.com/users/mattshockl/following{/other_user}","gists_url":"https://api.github.com/users/mattshockl/gists{/gist_id}","starred_url":"https://api.github.com/users/mattshockl/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mattshockl/subscriptions","organizations_url":"https://api.github.com/users/mattshockl/orgs","repos_url":"https://api.github.com/users/mattshockl/repos","events_url":"https://api.github.com/users/mattshockl/events{/privacy}","received_events_url":"https://api.github.com/users/mattshockl/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2016-12-05T17:58:53Z","updated_at":"2016-12-05T17:58:53Z","closed_at":null,"body":"This may just be my lack of knowledge with LibVMI internals, but I can't seem to find a way to clear a memory event without entering into an infinite loop.  I modified the msr_event_example to simply create an event that signals when the page that the SYSENTER_LSTAR register points to executes, print something, then clear the event.  The expected output of this program should be one print statement, then continued execution of the kernel since, per the API, clear_event should reset the page permissions and continue on the current instruction.  However, even though I clear the event, once the kernel begins executing again, it signals the event again.  This just creates a loop that freezes the guest completely and it seems there is no way to break out of it.  Even running the example code given in the examples directory can't print out the system calls without freezing the guest and entering into an infinite loop.  I'm using a Windows 7-64 bit guest running on Xen if that matters.  The poc code is below:\r\n\r\n```\r\n#include <stdlib.h>\r\n#include <string.h>\r\n#include <errno.h>\r\n#include <sys/mman.h>\r\n#include <stdio.h>\r\n#include <inttypes.h>\r\n#include <signal.h>\r\n\r\n#include <libvmi/libvmi.h>\r\n#include <libvmi/events.h>\r\n\r\nvmi_event_t syscall_event;\r\n\r\nevent_response_t syscall_event_callback(vmi_instance_t vmi, vmi_event_t *event) {\r\n    fprintf(stderr, \"%s\\n\", \"Syscall Reached\");\r\n    vmi_clear_event(vmi, event, NULL);\r\n    return 0;\r\n}\r\n\r\nstatic int interrupted = 0;\r\nstatic void close_handler(int sig){\r\n    interrupted = sig;\r\n}\r\n\r\nint main (int argc, char **argv) {\r\n    status_t status = VMI_SUCCESS;\r\n    vmi_instance_t vmi;\r\n    struct sigaction act;\r\n    act.sa_handler = close_handler;\r\n    act.sa_flags = 0;\r\n    sigemptyset(&act.sa_mask);\r\n    sigaction(SIGHUP,  &act, NULL);\r\n    sigaction(SIGTERM, &act, NULL);\r\n    sigaction(SIGINT,  &act, NULL);\r\n    sigaction(SIGALRM, &act, NULL);\r\n\r\n    char *name = NULL;\r\n\r\n    if(argc < 2){\r\n        fprintf(stderr, \"Usage: syscall_events_example <name of VM>\\n\");\r\n        exit(1);\r\n    }\r\n\r\n    // Arg 1 is the VM name.\r\n    name = argv[1];\r\n\r\n    // Initialize the libvmi library.\r\n    if (vmi_init(&vmi, VMI_XEN | VMI_INIT_COMPLETE | VMI_INIT_EVENTS, name) == VMI_FAILURE){\r\n        printf(\"Failed to init LibVMI library.\\n\");\r\n        if (vmi != NULL ) {\r\n            vmi_destroy(vmi);\r\n        }\r\n        return 1;\r\n    }\r\n    else{\r\n        printf(\"LibVMI init succeeded!\\n\");\r\n    }\r\n\r\n    vmi_pause_vm(vmi);\r\n\r\n    reg_t lstar = 0;\r\n    addr_t phys_lstar = 0;\r\n\r\n    vmi_get_vcpureg(vmi, &lstar, MSR_LSTAR, 0);\r\n    phys_lstar = vmi_translate_kv2p(vmi, lstar);\r\n\r\n    /* Register event to track any writes to a MSR. */\r\n    memset(&syscall_event, 0, sizeof(vmi_event_t));\r\n    SETUP_MEM_EVENT(&syscall_event, phys_lstar, VMI_MEMACCESS_X, syscall_event_callback, 0);\r\n    syscall_event.mem_event.generic = 0;\r\n\r\n    vmi_register_event(vmi, &syscall_event);\r\n\r\n    vmi_resume_vm(vmi);\r\n\r\n    printf(\"Waiting for events...\\n\");\r\n\r\n    while(!interrupted){\r\n        status = vmi_events_listen(vmi,500);\r\n        if (status != VMI_SUCCESS) {\r\n            printf(\"Error waiting for events, quitting...\\n\");\r\n            interrupted = -1;\r\n        }\r\n    }\r\n\r\n    printf(\"Finished with test.\\n\");\r\n\r\n    // cleanup any memory associated with the libvmi instanc\r\n    vmi_destroy(vmi);\r\n\r\n    return 0;\r\n}```"}}
{"actor":{"display_login":"mattshockl"}}