import virtualbox
import os
import time
import threading
import logging

logging.basicConfig(level=logging.DEBUG,
                    format='(%(threadName)-10s) %(message)s',)


class Sandbox(object):
    def __init__(self, name):
        vbox = virtualbox.VirtualBox()
        self.vm = vbox.find_machine(name)
        self.session = None
        self.gs = None
        self.malware_name = None

    def start(self):
        logging.info("Starting the VM")
        session = virtualbox.Session()
        power_up_process = self.vm.launch_vm_process(session, 'gui', '')
        power_up_process.wait_for_completion()
        session.unlock_machine()

    def power_off(self):
        logging.info("Shutdown the VM")
        self.gs.close()
        power_down_process = self.session.console.power_down()
        power_down_process.wait_for_completion()
        time.sleep(5)

    def restore_snapshot(self, point):
        logging.info("Restored the VM")
        session = self.vm.create_session()
        origin_point = session.machine.find_snapshot(point)
        restore_process = session.console.restore_snapshot(origin_point)
        restore_process.wait_for_completion()
        session.unlock_machine()

    def take_snapshot(self, point):
        logging.info("Take the snapshoot on %s" % (point))
        session = self.vm.create_session()
        localtime = time.asctime(time.localtime(time.time()))
        snapshot_process = self.session.console.take_snapshot(point, localtime)
        snapshot_process.wait_for_completion()
        session.unlock_machine()

    def delete_snapshot(self, point):
        logging.info("Delete the snapshoot %s" % (point))
        session = self.vm.create_session()
        origin_point = session.machine.find_snapshot(point)
        delete_process = session.console.delete_snapshot(origin_point.id_p)
        delete_process.wait_for_completion()
        session.unlock_machine()

    def capture_traffic(self, wait_sec, interface=0):
        if not os.path.isdir('PCAPLog'):
            os.mkdir('PCAPLog')
        logging.debug('Capture the network traffic')
        session = self.vm.create_session()
        adapter = session.machine.get_network_adapter(interface)
        adapter.trace_file = os.path.abspath('./PCAPLog/%s.pcap'
                                             % self.malware_name)
        adapter.trace_enabled = True
        time.sleep(wait_sec)
        adapter.trace_enabled = False
        session.unlock_machine()
        logging.debug('Exiting')


class Win32Sandbox(Sandbox):
    def __init__(self, name):
        super(Win32Sandbox, self).__init__(name)

    def __forward_timer(self, output, forward_hour):
        # output[0] == process; output[1] == stdout; output[2] == stderr
        current_time = output[1][5:-2]
        hour = int(current_time[0:2])
        hour = hour + forward_hour
        new_time = '{hh}:{mm}'.format(hh=str(hour), mm=current_time[3:5])
        logging.debug('Correct the time: ' + new_time)
        return new_time

    def login(self, account, password):
        logging.info("Login to Windows XP")
        self.session = self.vm.create_session()
        self.gs = self.session.console.guest.create_session('john', 'john')
        time.sleep(10)
        try:
            self.gs.execute('C:\\Windows\\System32\\cmd.exe',
                            ['/C', 'tasklist'])
        except:
            logging.info("Waiting for logins to complete")
            time.sleep(15)

    def copy_malware_in(self, name):
        self.malware_name = name
        logging.info("Copy malware %s into sandbox" % (name))
        copy_to_process = self.gs.copy_to('./malware_bin/%s' % (name),
                                          'C:\\%s.exe' % (name))
        copy_to_process.wait_for_completion()

    def active_malware(self, name, timeout=5000):
        logging.debug('Activate the malware')
        try:
            process, stdout, stderr = self.gs.execute('C:\\%s.exe' % (name),
                                                      timeout_ms=timeout)
        except:
            f = open("./cannot_exec.out", "a")
            f.write(name + '\n')
            f.close()
            logging.info('Execute Error')
            return

        output = self.gs.execute('C:\\Windows\\System32\\cmd.exe',
                                 ['/C', 'time', '/T'], timeout_ms=timeout)

        new_time = self.__forward_timer(output, 1)

        self.gs.execute('C:\\Windows\\System32\\cmd.exe',
                        ['/C', 'time', new_time], timeout_ms=timeout)

        output = self.gs.execute('C:\\Windows\\System32\\cmd.exe',
                                 ['/C', 'time', '/T'], timeout_ms=timeout)

        logging.debug('Now Time: ' + str(output[1][5:-2]))
        logging.debug('Exiting')

    def capture_traffic(self, wait_sec, interface=0):
        super(Win32Sandbox, self).capture_traffic(wait_sec, interface)

    def active_capture_parallel(self, time):
        capture_worker = threading.Thread(name='Capture Traffic',
                                          target=self.capture_traffic,
                                          args=(time, ))
        active_worker = threading.Thread(name='Active Malware',
                                         target=self.active_malware,
                                         args=(self.malware_name, ))
        capture_worker.start()
        active_worker.start()
        capture_worker.join()
        active_worker.join(5)


class LinuxSandbox(Sandbox):
    def __init__(self, name):
        super(LinuxSandbox, self).__init__(name)


if __name__ == "__main__":
    pass

@@ -2822,16 +2822,78 @@
 e%5B0:2%5D)%0A
+        if hour == 23:%0A            hour = 0%0A        else:%0A    
         
@@ -3032,16 +3032,19 @@
 the time
+ to
 : ' + ne
@@ -4268,16 +4268,53 @@
 Error')%0A
+            logging.debug('Exiting')%0A
         
@@ -4796,67 +4796,8 @@
 t)%0A%0A
-        logging.debug('Now Time: ' + str(output%5B1%5D%5B5:-2%5D))%0A
     

Fix forward to 24:00 bug