# Path: nitro/nitro.py
# class Nitro:
# 
#     def __init__(self, domain, introspection=True, syscall_filtering=True):
#         self.listener = Listener(domain)
#         self.introspection = introspection
#         self.backend = None
#         if self.introspection:
#             self.backend = get_backend(domain, self.listener, syscall_filtering)
# 
#     def listen(self):
#         yield from self.listener.listen()
# 
#     def __enter__(self):
#         return self
# 
#     def __exit__(self, *args, **kwargs):
#         self.stop()
# 
#     def stop(self, synchronous=True):
#         self.listener.stop(synchronous)
# 
# Path: nitro/event.py
# class SyscallDirection(Enum):
#     """System call direction"""
#     enter = 0
#     exit = 1
# 
# Path: nitro/backends/backend.py
# class Backend:
#     """
#     Base class for Backends. ``Backend`` provides functionality for dispatching
#     hooks and keeping statistics about processed events.
#     """
# 
#     __slots__ = (
#         "domain",
#         "libvmi",
#         "hooks",
#         "stats",
#         "listener",
#         "syscall_filtering"
#     )
# 
#     def __init__(self, domain, libvmi, listener, syscall_filtering=True):
#         """Create a new ``Backend``"""
# 
#         #: libvirt domain associated with the backend
#         self.domain = domain
#         #: handle to libvmi
#         self.libvmi = libvmi
#         #: ``Listener`` associated with the ``Backend``
#         self.listener = listener
#         #: Is system call filtering enabled for the backend
#         self.syscall_filtering = syscall_filtering
#         #: Event hooks
#         self.hooks = {
#             SyscallDirection.enter: {},
#             SyscallDirection.exit: {}
#         }
#         #: Statistics about the backend
#         self.stats = defaultdict(int)
# 
#     def dispatch_hooks(self, syscall):
#         # TODO: don't dispatch if the process is None
#         if syscall.process is None:
#             return
# 
#         try:
#             hook = self.hooks[syscall.event.direction][syscall.name]
#         except KeyError:
#             pass
#         else:
#             try:
#                 logging.debug('Processing hook %s - %s',
#                               syscall.event.direction.name, hook.__name__)
#                 hook(syscall, self)
#             # FIXME: There should be a way for OS specific backends to report these
#             # except InconsistentMemoryError: #
#             #     self.stats['memory_access_error'] += 1
#             #     logging.exception('Memory access error')
#             except LibvmiError:
#                 self.stats['libvmi_failure'] += 1
#                 logging.exception('VMI_FAILURE')
#             # misc failures
#             except ValueError:
#                 self.stats['misc_error'] += 1
#                 logging.exception('Misc error')
#             except Exception:
#                 logging.exception('Unknown error while processing hook')
#             else:
#                 self.stats['hooks_completed'] += 1
#             finally:
#                 self.stats['hooks_processed'] += 1
# 
#     def define_hook(self, name, callback, direction=SyscallDirection.enter):
#         """
#         Register a new system call hook with the ``Backend``.
#         
#         :param str name: Name of the system call to hook.
#         :param callable callback: Callable to call when the hook is fired.
#         :param SyscallDirection direction: Should the hook fire when system call is entered or exited.
#         """
#         logging.info('Defining %s hook on %s', direction.name, name)
#         self.hooks[direction][name] = callback
# 
#     def undefine_hook(self, name, direction=SyscallDirection.enter):
#         """
#         Unregister a hook.
#         """
#         logging.info('Removing hook on %s', name)
#         self.hooks[direction].pop(name)
# 
#     def __enter__(self):
#         return self
# 
#     def __exit__(self, *args):
#         self.stop()
# 
#     def stop(self):
#         """Stop the backend"""
#         logging.info(json.dumps(self.stats, indent=4))
#         self.libvmi.destroy()


import os
import sys
import logging
import time
import libvirt
import socket
import datetime
import xml.etree.ElementTree as tree
from functools import partial
from threading import Thread, Event
from nitro.nitro import Nitro
from nitro.libvmi import LibvmiError
from nitro.event import SyscallDirection
from nitro.backends.backend import Backend
from cdrom import WindowsCDROM, LinuxCDROM
            break
        elif state != 0 and not opened:
            logging.info("Monitored service on port %d went down", port)
            break
        time.sleep(sleep)

wait_winrm = partial(wait_socket, 5985)
wait_sshd = partial(wait_socket, 22)

class NitroThread(Thread):

    def __init__(self, domain, analyze=False, enter_hooks=None, exit_hooks=None, ready_event=None):
        super().__init__()
        self.domain = domain
        self.analyze_enabled = analyze
        self.enter_hooks = enter_hooks or {}
        self.exit_hooks = exit_hooks or {}
        self.stop_request = Event()
        self.total_time = None
        self.events = []
        self.ready_event = ready_event
        self.nitro = Nitro(self.domain, self.analyze_enabled)

    def run(self):
        # start timer
        start_time = datetime.datetime.now()
        if self.analyze_enabled:
            for name, callback in self.enter_hooks.items():
                self.nitro.backend.define_hook(name, callback, direction=SyscallDirection.enter)
            for name, callback in self.exit_hooks.items():

# Path: nitro/nitro.py
# class Nitro:
# 
#     def __init__(self, domain, introspection=True, syscall_filtering=True):
#         self.listener = Listener(domain)
#         self.introspection = introspection
#         self.backend = None
#         if self.introspection:
#             self.backend = get_backend(domain, self.listener, syscall_filtering)
# 
#     def listen(self):
#         yield from self.listener.listen()
# 
#     def __enter__(self):
#         return self
# 
#     def __exit__(self, *args, **kwargs):
#         self.stop()
# 
#     def stop(self, synchronous=True):
#         self.listener.stop(synchronous)
# 
# Path: nitro/event.py
# class SyscallDirection(Enum):
#     """System call direction"""
#     enter = 0
#     exit = 1
# 
# Path: nitro/backends/backend.py
# class Backend:
#     """
#     Base class for Backends. ``Backend`` provides functionality for dispatching
#     hooks and keeping statistics about processed events.
#     """
# 
#     __slots__ = (
#         "domain",
#         "libvmi",
#         "hooks",
#         "stats",
#         "listener",
#         "syscall_filtering"
#     )
# 
#     def __init__(self, domain, libvmi, listener, syscall_filtering=True):
#         """Create a new ``Backend``"""
# 
#         #: libvirt domain associated with the backend
#         self.domain = domain
#         #: handle to libvmi
#         self.libvmi = libvmi
#         #: ``Listener`` associated with the ``Backend``
#         self.listener = listener
#         #: Is system call filtering enabled for the backend
#         self.syscall_filtering = syscall_filtering
#         #: Event hooks
#         self.hooks = {
#             SyscallDirection.enter: {},
#             SyscallDirection.exit: {}
#         }
#         #: Statistics about the backend
#         self.stats = defaultdict(int)
# 
#     def dispatch_hooks(self, syscall):
#         # TODO: don't dispatch if the process is None
#         if syscall.process is None:
#             return
# 
#         try:
#             hook = self.hooks[syscall.event.direction][syscall.name]
#         except KeyError:
#             pass
#         else:
#             try:
#                 logging.debug('Processing hook %s - %s',
#                               syscall.event.direction.name, hook.__name__)
#                 hook(syscall, self)
#             # FIXME: There should be a way for OS specific backends to report these
#             # except InconsistentMemoryError: #
#             #     self.stats['memory_access_error'] += 1
#             #     logging.exception('Memory access error')
#             except LibvmiError:
#                 self.stats['libvmi_failure'] += 1
#                 logging.exception('VMI_FAILURE')
#             # misc failures
#             except ValueError:
#                 self.stats['misc_error'] += 1
#                 logging.exception('Misc error')
#             except Exception:
#                 logging.exception('Unknown error while processing hook')
#             else:
#                 self.stats['hooks_completed'] += 1
#             finally:
#                 self.stats['hooks_processed'] += 1
# 
#     def define_hook(self, name, callback, direction=SyscallDirection.enter):
#         """
#         Register a new system call hook with the ``Backend``.
#         
#         :param str name: Name of the system call to hook.
#         :param callable callback: Callable to call when the hook is fired.
#         :param SyscallDirection direction: Should the hook fire when system call is entered or exited.
#         """
#         logging.info('Defining %s hook on %s', direction.name, name)
#         self.hooks[direction][name] = callback
# 
#     def undefine_hook(self, name, direction=SyscallDirection.enter):
#         """
#         Unregister a hook.
#         """
#         logging.info('Removing hook on %s', name)
#         self.hooks[direction].pop(name)
# 
#     def __enter__(self):
#         return self
# 
#     def __exit__(self, *args):
#         self.stop()
# 
#     def stop(self):
#         """Stop the backend"""
#         logging.info(json.dumps(self.stats, indent=4))
#         self.libvmi.destroy()


# Path: tests/vmtest_helper.py
import os
import sys
import logging
import time
import libvirt
import socket
import datetime
import xml.etree.ElementTree as tree
from functools import partial
from threading import Thread, Event
from nitro.nitro import Nitro
from nitro.libvmi import LibvmiError
from nitro.event import SyscallDirection
from nitro.backends.backend import Backend
from cdrom import WindowsCDROM, LinuxCDROM

            break
        elif state != 0 and not opened:
            logging.info("Monitored service on port %d went down", port)
            break
        time.sleep(sleep)

wait_winrm = partial(wait_socket, 5985)
wait_sshd = partial(wait_socket, 22)

class NitroThread(Thread):

    def __init__(self, domain, analyze=False, enter_hooks=None, exit_hooks=None, ready_event=None):
        super().__init__()
        self.domain = domain
        self.analyze_enabled = analyze
        self.enter_hooks = enter_hooks or {}
        self.exit_hooks = exit_hooks or {}
        self.stop_request = Event()
        self.total_time = None
        self.events = []
        self.ready_event = ready_event
        self.nitro = Nitro(self.domain, self.analyze_enabled)

    def run(self):
        # start timer
        start_time = datetime.datetime.now()
        if self.analyze_enabled:
            for name, callback in self.enter_hooks.items():
                self.nitro.backend.define_hook(name, callback, direction=SyscallDirection.enter)
            for name, callback in self.exit_hooks.items():

                self.nitro.backend.define_hook(name, callback, direction=SyscallDirection.exit)