コード例 #1
0
def main():
    '''
    Once the socket is bound the client is handled in another thread to
    allow for asynchronous input
    '''
    print "Press ctrl-c to stop server..."
    listener_socket = SocketWrapper()
    #Serving local clients only for efficiancy purposes
    try:
        listener_socket.port_number = int(sys.argv[1])
    except:
        print "Usage: mudserver.py PORT"
        sys.exit(1)   

    #change hostname to inet address of computer the server is run on
    listener_socket.host_name = ''
    listener_socket.queue_size = 2
    listener_socket.buffer_size = 4096

    listener_socket.startListening()

    while 1:
        communication_socket = \
            SocketWrapper("<<EOC", listener_socket.awaitConnection())
        thread.start_new_thread(threadHandler, (communication_socket,))
        
    listener_socket.closeConnection()
コード例 #2
0
ファイル: streamserver.py プロジェクト: zhihuishuwp/emma
    def __init__(self, conf):
        self.conf = conf
        self.queue = Queue()

        if self.conf.online:
            settings = configparser.RawConfigParser()
            settings.read('settings.conf')
            interface = settings.get("Datasets", "stream_interface")
            ip_address = get_ip_address(interface)
            addr_tuple = (ip_address, 3885)

            self.server = SocketWrapper(
                socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM),
                addr_tuple, self._cb_server)
            self.server.start()

            print("Listening for sample streams at %s" % str(addr_tuple))
コード例 #3
0
 def __init__(self, loop):
     self.loop = loop
     self.loop.add_coroutine(self.run_server_forever())
     # create socket
     s = socket.socket()
     s.bind(("127.0.0.1", 8999))
     s.listen()
     self.listen_socket = SocketWrapper(s, loop)
コード例 #4
0
ファイル: controller.py プロジェクト: msurkovsky/aislinn
 def connect(self):
     self.server_socket.settimeout(5.0)
     try:
         sock, addr = self.server_socket.accept()
     except socket.timeout:
         logging.error("Aislinn client was not started")
         return False
     self.socket = SocketWrapper(sock)
     self.socket.set_no_delay()
     self.server_socket.close()
     self.server_socket = None
     return True
コード例 #5
0
ファイル: streamserver.py プロジェクト: zhihuishuwp/emma
class StreamServer():
    def __init__(self, conf):
        self.conf = conf
        self.queue = Queue()

        if self.conf.online:
            settings = configparser.RawConfigParser()
            settings.read('settings.conf')
            interface = settings.get("Datasets", "stream_interface")
            ip_address = get_ip_address(interface)
            addr_tuple = (ip_address, 3885)

            self.server = SocketWrapper(
                socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM),
                addr_tuple, self._cb_server)
            self.server.start()

            print("Listening for sample streams at %s" % str(addr_tuple))

    def _cb_server(self, client_socket, client_address, data):
        if len(data) < 5:
            # Not enough for TLV
            return 0
        else:
            pkt_type, payload_len = struct.unpack(">BI", data[0:5])
            payload = data[5:]
            if len(payload) < payload_len:
                return 0  # Not enough for payload
            else:
                # Depickle and add to queue
                # TODO: Check for correctness. EMcap is Python2 (because it needs to)
                # use GNU Radio. Therefore the pickling format is different, which
                # we need to make sure doesn't cause any differences.
                trace_set = pickle.loads(payload,
                                         encoding='latin1',
                                         fix_imports=True)
                logger.debug("Stream: got %d traces" % len(trace_set.traces))

                self.queue.put(trace_set)
                return payload_len + 5
コード例 #6
0
if __name__ == '__main__':
    app = QApplication(sys.argv)
    main_window = QWidget()
    main_window.setWindowTitle('lab 1 task 4')
    main_window.setLayout(QVBoxLayout())

    server_ip = IPWidget("Server IP:", main_window)

    receiver_ip = IPWidget("Receiver IP:", main_window)

    instance_panel = QWidget()
    instance_panel.setLayout(QHBoxLayout())

    port_field = QLineEdit()

    server_socket = SocketWrapper(server_ip, receiver_ip, port_field)
    server_socket.start()

    conn_panel = QWidget()
    conn_panel.setLayout(QHBoxLayout())

    conn_btn = QPushButton("Connect")
    conn_btn.clicked.connect(server_socket.sock_init)

    disconnect_btn = QPushButton("Disconnect")
    disconnect_btn.clicked.connect(server_socket.close)

    user_list_btn = QPushButton("User list")
    user_list_btn.clicked.connect(lambda x: server_socket.msg_send("", True))

    status_label = QLabel("not connected")
コード例 #7
0
ファイル: emcap.py プロジェクト: zhihuishuwp/emma
    def process_ctrl_packet(self, pkt_type, payload):
        if pkt_type == CtrlPacketType.SIGNAL_START:
            logger.debug("Starting for payload: %s" % binary_to_hex(payload))
            self.parse_ies(payload)
            self.sdr.start()

            # Spinlock until data
            timeout = 3
            current_time = 0.0
            while len(self.stored_data) <= self.wait_num_chunks:
                sleep(0.0001)
                current_time += 0.0001
                if current_time >= timeout:
                    logger.warning("Timeout while waiting for data. Did the SDR crash? Reinstantiating...")
                    del self.sdr
                    self.data_socket.socket.close()
                    self.data_socket = SocketWrapper(socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM), ('127.0.0.1', 3884), self.cb_data)
                    self.data_socket.start()
                    self.sdr = SDR(**self.cap_kwargs)
                    self.process_ctrl_packet(pkt_type, payload)
        elif pkt_type == CtrlPacketType.SIGNAL_END:
            # self.sdr.sdr_source.stop()
            self.sdr.stop()
            self.sdr.wait()

            logger.debug("Stopped after receiving %d chunks" % len(self.stored_data))
            #sleep(0.5)
            #logger.debug("After sleep we have %d chunks" % len(self.stored_data))

            # Successful capture (no errors or timeouts)
            if len(self.stored_data) > 0:  # We have more than 1 chunk
                # Data to file
                np_data = np.fromstring(b"".join(self.stored_data), dtype=np.complex64)
                self.trace_set.append(np_data)
                self.plaintexts.append(self.stored_plaintext)
                self.keys.append(self.stored_key)

                if len(self.trace_set) >= self.kwargs['traces_per_set']:
                    assert(len(self.trace_set) == len(self.plaintexts))
                    assert(len(self.trace_set) == len(self.keys))

                    np_trace_set = np.array(self.trace_set)
                    np_plaintexts = np.array(self.plaintexts, dtype=np.uint8)
                    np_keys = np.array(self.keys, dtype=np.uint8)

                    if not self.online is None: # Stream online
                        ts = TraceSet(name="online %d" % self.online_counter, traces=np_trace_set, plaintexts=np_plaintexts, ciphertexts=None, keys=np_keys)
                        logger.info("Pickling")
                        ts_p = pickle.dumps(ts)
                        logger.info("Size is %d" % len(ts_p))
                        stream_payload = ts_p
                        stream_payload_len = len(stream_payload)
                        logger.info("Streaming trace set of %d bytes to server" % stream_payload_len)
                        stream_hdr = struct.pack(">BI", 0, stream_payload_len)
                        self.emma_client.send(stream_hdr + stream_payload)
                        self.online_counter += 1
                    else: # Save to disk
                        if not self.kwargs['dry']:
                            # Write metadata to sigmf file
                            # if sigmf
                            #with open(test_meta_path, 'w') as f:
                            #    test_sigmf = SigMFFile(data_file=test_data_path, global_info=copy.deepcopy(self.global_meta))
                            #    test_sigmf.add_capture(0, metadata=capture_meta)
                            #    test_sigmf.dump(f, pretty=True)
                            # elif chipwhisperer:
                            logger.info("Dumping %d traces to file" % len(self.trace_set))
                            filename = str(datetime.utcnow()).replace(" ","_").replace(".","_")
                            output_dir = self.kwargs['output_dir']
                            np.save(os.path.join(output_dir, "%s_traces.npy" % filename), np_trace_set)  # TODO abstract this in trace_set class
                            np.save(os.path.join(output_dir, "%s_textin.npy" % filename), np_plaintexts)
                            np.save(os.path.join(output_dir, "%s_knownkey.npy" % filename), np_keys)
                            if self.compress:
                                logger.info("Calling emcap-compress...")
                                subprocess.call(['/usr/bin/python', 'emcap-compress.py', os.path.join(output_dir, "%s_traces.npy" % filename)])

                        self.limit_counter += len(self.trace_set)
                        if self.limit_counter >= self.limit:
                            print("Done")
                            exit(0)

                    # Clear results
                    self.trace_set = []
                    self.plaintexts = []
                    self.keys = []

                # Clear
                self.stored_data = []
                self.stored_plaintext = []
コード例 #8
0
ファイル: emcap.py プロジェクト: zhihuishuwp/emma
    def __init__(self, cap_kwargs={}, kwargs={}, ctrl_socket_type=None):
        # Set up data socket
        self.data_socket = SocketWrapper(socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM), ('127.0.0.1', 3884), self.cb_data)
        self.online = kwargs['online']

        # Set up sockets
        self.ctrl_socket_type = ctrl_socket_type
        if ctrl_socket_type == CtrlType.DOMAIN:
            unix_domain_socket = '/tmp/emma.socket'
            self.clear_domain_socket(unix_domain_socket)
            self.ctrl_socket = SocketWrapper(socket.socket(family=socket.AF_UNIX, type=socket.SOCK_STREAM), unix_domain_socket, self.cb_ctrl)
        elif ctrl_socket_type == CtrlType.UDP:
            self.ctrl_socket = SocketWrapper(socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM), ('172.18.15.21', 3884), self.cb_ctrl)
        elif ctrl_socket_type == CtrlType.SERIAL:
            self.ctrl_socket = TTYWrapper("/dev/ttyUSB0", self.cb_ctrl)
        else:
            logger.error("Unknown ctrl_socket_type")
            exit(1)

        if not self.online is None:
            try:
                self.emma_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                self.emma_client.connect((self.online, 3885))
            except Exception as e:
                print(e)
                exit(1)

        self.sdr = SDR(**cap_kwargs)
        self.cap_kwargs = cap_kwargs
        self.kwargs = kwargs
        self.store = False
        self.stored_plaintext = []
        self.stored_key = []
        self.stored_data = []
        self.trace_set = []
        self.plaintexts = []
        self.keys = []
        self.online_counter = 0
        self.limit_counter = 0
        self.limit = kwargs['limit']
        #self.manifest = kwargs['manifest']
        self.compress = kwargs['compress']
        if self.sdr.hw == 'usrp':
            self.wait_num_chunks = 0
        else:
            self.wait_num_chunks = 50  # Bug in rtl-sdr?

        self.global_meta = {
            "core:datatype": "cf32_le",
            "core:version": "0.0.1",
            "core:license": "CC0",
            "core:hw": self.sdr.hw,
            "core:sample_rate": self.sdr.samp_rate,
            "core:author": "Pieter Robyns"
        }

        self.capture_meta = {
            "core:sample_start": 0,
            "core:frequency": self.sdr.freq,
            "core:datetime": str(datetime.utcnow()),
        }
コード例 #9
0
ファイル: emcap.py プロジェクト: zhihuishuwp/emma
class EMCap():
    def __init__(self, cap_kwargs={}, kwargs={}, ctrl_socket_type=None):
        # Set up data socket
        self.data_socket = SocketWrapper(socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM), ('127.0.0.1', 3884), self.cb_data)
        self.online = kwargs['online']

        # Set up sockets
        self.ctrl_socket_type = ctrl_socket_type
        if ctrl_socket_type == CtrlType.DOMAIN:
            unix_domain_socket = '/tmp/emma.socket'
            self.clear_domain_socket(unix_domain_socket)
            self.ctrl_socket = SocketWrapper(socket.socket(family=socket.AF_UNIX, type=socket.SOCK_STREAM), unix_domain_socket, self.cb_ctrl)
        elif ctrl_socket_type == CtrlType.UDP:
            self.ctrl_socket = SocketWrapper(socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM), ('172.18.15.21', 3884), self.cb_ctrl)
        elif ctrl_socket_type == CtrlType.SERIAL:
            self.ctrl_socket = TTYWrapper("/dev/ttyUSB0", self.cb_ctrl)
        else:
            logger.error("Unknown ctrl_socket_type")
            exit(1)

        if not self.online is None:
            try:
                self.emma_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                self.emma_client.connect((self.online, 3885))
            except Exception as e:
                print(e)
                exit(1)

        self.sdr = SDR(**cap_kwargs)
        self.cap_kwargs = cap_kwargs
        self.kwargs = kwargs
        self.store = False
        self.stored_plaintext = []
        self.stored_key = []
        self.stored_data = []
        self.trace_set = []
        self.plaintexts = []
        self.keys = []
        self.online_counter = 0
        self.limit_counter = 0
        self.limit = kwargs['limit']
        #self.manifest = kwargs['manifest']
        self.compress = kwargs['compress']
        if self.sdr.hw == 'usrp':
            self.wait_num_chunks = 0
        else:
            self.wait_num_chunks = 50  # Bug in rtl-sdr?

        self.global_meta = {
            "core:datatype": "cf32_le",
            "core:version": "0.0.1",
            "core:license": "CC0",
            "core:hw": self.sdr.hw,
            "core:sample_rate": self.sdr.samp_rate,
            "core:author": "Pieter Robyns"
        }

        self.capture_meta = {
            "core:sample_start": 0,
            "core:frequency": self.sdr.freq,
            "core:datetime": str(datetime.utcnow()),
        }

    def clear_domain_socket(self, address):
        try:
            os.unlink(address)
        except OSError:
            if os.path.exists(address):
                raise

    def cb_timeout(self):
        logger.warning("Timeout on capture, skipping...")
        self.sdr.stop()

    def cb_data(self, client_socket, client_address, data):
        self.stored_data.append(data)
        return len(data)

    def cb_ctrl(self, client_socket, client_address, data):
        logger.log(logging.NOTSET, "Control packet: %s" % binary_to_hex(data))
        if len(data) < 5:
            # Not enough for TLV
            return 0
        else:
            pkt_type, payload_len = struct.unpack(">BI", data[0:5])
            payload = data[5:]
            if len(payload) < payload_len:
                return 0  # Not enough for payload
            else:
                self.process_ctrl_packet(pkt_type, payload)
                # Send ack
                if self.ctrl_socket_type == CtrlType.SERIAL:
                    client_socket.write(b"k")
                else:
                    client_socket.sendall("k")
                return payload_len + 5

    def parse_ies(self, payload):
        while len(payload) >= 5:
            # Extract IE header
            ie_type, ie_len = struct.unpack(">BI", payload[0:5])
            payload = payload[5:]

            # Extract IE data
            ie = payload[0:ie_len]
            payload = payload[ie_len:]
            logger.debug("IE type %d of len %d: %s" % (ie_type, ie_len, binary_to_hex(ie)))

            # Determine what to do with IE
            if ie_type == InformationElementType.PLAINTEXT:
                self.stored_plaintext = [ord(c) for c in ie]
            elif ie_type == InformationElementType.KEY:
                self.stored_key = [ord(c) for c in ie]
            else:
                logger.warning("Unknown IE type: %d" % ie_type)

    def process_ctrl_packet(self, pkt_type, payload):
        if pkt_type == CtrlPacketType.SIGNAL_START:
            logger.debug("Starting for payload: %s" % binary_to_hex(payload))
            self.parse_ies(payload)
            self.sdr.start()

            # Spinlock until data
            timeout = 3
            current_time = 0.0
            while len(self.stored_data) <= self.wait_num_chunks:
                sleep(0.0001)
                current_time += 0.0001
                if current_time >= timeout:
                    logger.warning("Timeout while waiting for data. Did the SDR crash? Reinstantiating...")
                    del self.sdr
                    self.data_socket.socket.close()
                    self.data_socket = SocketWrapper(socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM), ('127.0.0.1', 3884), self.cb_data)
                    self.data_socket.start()
                    self.sdr = SDR(**self.cap_kwargs)
                    self.process_ctrl_packet(pkt_type, payload)
        elif pkt_type == CtrlPacketType.SIGNAL_END:
            # self.sdr.sdr_source.stop()
            self.sdr.stop()
            self.sdr.wait()

            logger.debug("Stopped after receiving %d chunks" % len(self.stored_data))
            #sleep(0.5)
            #logger.debug("After sleep we have %d chunks" % len(self.stored_data))

            # Successful capture (no errors or timeouts)
            if len(self.stored_data) > 0:  # We have more than 1 chunk
                # Data to file
                np_data = np.fromstring(b"".join(self.stored_data), dtype=np.complex64)
                self.trace_set.append(np_data)
                self.plaintexts.append(self.stored_plaintext)
                self.keys.append(self.stored_key)

                if len(self.trace_set) >= self.kwargs['traces_per_set']:
                    assert(len(self.trace_set) == len(self.plaintexts))
                    assert(len(self.trace_set) == len(self.keys))

                    np_trace_set = np.array(self.trace_set)
                    np_plaintexts = np.array(self.plaintexts, dtype=np.uint8)
                    np_keys = np.array(self.keys, dtype=np.uint8)

                    if not self.online is None: # Stream online
                        ts = TraceSet(name="online %d" % self.online_counter, traces=np_trace_set, plaintexts=np_plaintexts, ciphertexts=None, keys=np_keys)
                        logger.info("Pickling")
                        ts_p = pickle.dumps(ts)
                        logger.info("Size is %d" % len(ts_p))
                        stream_payload = ts_p
                        stream_payload_len = len(stream_payload)
                        logger.info("Streaming trace set of %d bytes to server" % stream_payload_len)
                        stream_hdr = struct.pack(">BI", 0, stream_payload_len)
                        self.emma_client.send(stream_hdr + stream_payload)
                        self.online_counter += 1
                    else: # Save to disk
                        if not self.kwargs['dry']:
                            # Write metadata to sigmf file
                            # if sigmf
                            #with open(test_meta_path, 'w') as f:
                            #    test_sigmf = SigMFFile(data_file=test_data_path, global_info=copy.deepcopy(self.global_meta))
                            #    test_sigmf.add_capture(0, metadata=capture_meta)
                            #    test_sigmf.dump(f, pretty=True)
                            # elif chipwhisperer:
                            logger.info("Dumping %d traces to file" % len(self.trace_set))
                            filename = str(datetime.utcnow()).replace(" ","_").replace(".","_")
                            output_dir = self.kwargs['output_dir']
                            np.save(os.path.join(output_dir, "%s_traces.npy" % filename), np_trace_set)  # TODO abstract this in trace_set class
                            np.save(os.path.join(output_dir, "%s_textin.npy" % filename), np_plaintexts)
                            np.save(os.path.join(output_dir, "%s_knownkey.npy" % filename), np_keys)
                            if self.compress:
                                logger.info("Calling emcap-compress...")
                                subprocess.call(['/usr/bin/python', 'emcap-compress.py', os.path.join(output_dir, "%s_traces.npy" % filename)])

                        self.limit_counter += len(self.trace_set)
                        if self.limit_counter >= self.limit:
                            print("Done")
                            exit(0)

                    # Clear results
                    self.trace_set = []
                    self.plaintexts = []
                    self.keys = []

                # Clear
                self.stored_data = []
                self.stored_plaintext = []

    def capture(self, to_skip=0, timeout=1.0):
        # Start listening for signals
        self.data_socket.start()
        self.ctrl_socket.start()

        # Wait until supplicant signals end of acquisition
        while self.ctrl_socket.is_alive():
            self.ctrl_socket.join(timeout=1.0)

        logging.info("Supplicant disconnected on control channel. Stopping...")
コード例 #10
0
def main():
    client_socket = SocketWrapper('<<EOC')

    try:
        client_socket.host_name = sys.argv[1]
        client_socket.port_number = int(sys.argv[2])
    except:
        print "Usage: mudclient.py HOSTNAME PORT"
        sys.exit(1)

    client_socket.buffer_size = 4096
    #servers bind clients connect
    client_socket.connectToServer()
    #recieve and print intro message
    print client_socket.recieveData()

    while(1):
        message = raw_input("Enter Command: ")
        message += '<<EOC'
        client_socket.sendMessage(message)
        data = client_socket.recieveData()
        if message.lower() == "quit<<eoc": 
            break
        print data

    client_socket.closeConnection()
コード例 #11
0
ファイル: controller.py プロジェクト: spirali/aislinn
class Controller:
    """ The main class for controlling AVT - Aislinn Valgrind Tool

        Terminology:
        client - a verified process
        client's memory - a memory visible to a verified process
        buffer - a memory allocated in AVT by controller; invisible to client
    """


    # TODO: Universal architecture detection
    POINTER_SIZE = 8
    INT_SIZE = 4

    FUNCTION_INT = 0
    FUNCTION_4_POINTER = 1
    FUNCTION_2_INT_2_POINTER = 2
    FUNCTION_2_INT_4_POINTER = 3

    debug = False
    debug_by_valgrind_tool = None

    stdout_file = None
    stderr_file = None
    profile = False
    extra_env = None

    heap_size = None
    redzone_size = None
    verbose = None

    name = ""  # For debug purpose

    def __init__(self, valgrind_bin, args, cwd=None):
        self.process = None
        self.socket = None
        self.recv_buffer = ""
        self.args = tuple(args)
        self.cwd = cwd
        self.server_socket = None
        self.running = False
        self.valgrind_bin = valgrind_bin

    def start(self, capture_syscalls=()):
        """ Start Valgrind with Aislinn plugin (AVT)
        and initilizes connection """
        assert self.process is None  # Nothing is running
        assert self.socket is None

        self.server_socket = self._start_server()
        port = self.server_socket.getsockname()[1]
        self._start_valgrind(port, capture_syscalls)

    def connect(self):
        """ Connect to AVT """
        self.server_socket.settimeout(5.0)
        try:
            sock, addr = self.server_socket.accept()
        except socket.timeout:
            logging.error("Aislinn client was not started")
            return False
        self.socket = SocketWrapper(sock)
        self.socket.set_no_delay()
        self.server_socket.close()
        self.server_socket = None
        return True
        # User has to call receive_line after calling this method
        # But it may take some time to initialize vgclient, hence
        # it is not build in in connect to allow polling

    def start_and_connect(self, *args, **kw):
        """ Calls 'start' and 'connect' and receives the first line,
        returns None if connection failed"""
        self.start(*args, **kw)
        if not self.connect():
            return None
        return self.receive_line()

    def kill(self):
        """ Kills running AVT """
        if self.process and self.process.poll() is None:
            self.process.kill()
            self.process = None

    def set_capture_syscall(self, syscall, value):
        """ Switches on/off a capturing a syscall """
        self.send_and_receive_ok(
            "SET syscall {0} {1}\n".format(syscall, "on" if value else "off"))

    def save_state(self):
        """ Save a current process state """
        return self.send_and_receive_int("SAVE\n")

    def restore_state(self, state_id):
        """ Restores a saved process state """
        self.send_and_receive_ok("RESTORE {0}\n".format(state_id))

    def free_state(self, state_id):
        """ Frees a saved state """
        self.send_command("FREE {0}\n".format(state_id))

    def run_process(self):
        """ Resumes the paused process and wait until new event,
        then returns the event """
        return self.send_and_receive("RUN\n")

    def run_drop_syscall(self, return_value):
        """ When process is paused in syscall,
        it skips the syscall and then behaves as 'run' """
        return self.send_and_receive(
            "RUN_DROP_SYSCALL {0}\n".format(return_value))

    def run_process_async(self):
        """ Asynchronous version of 'run'. It does not wait for the
           next event and returns immediately """
        self.running = True
        self.send_command("RUN\n")

    def run_drop_syscall_async(self, return_value):
        """ Asynchornous version of 'run_drop_syscall'. It does not wait
           for the next event and retusn immediately. """
        self.running = True
        self.send_command("RUN_DROP_SYSCALL {0}\n".format(return_value))

    def finish_async(self):
        """ Finishes an asynchronous call """
        assert self.running
        self.running = False
        return self.receive_line()

    def run_function(self, fn_pointer, fn_type, *args):
        """ Executes a function in client """
        command = "RUN_FUNCTION {0} {1} {2} {3} \n".format(
                  fn_pointer, fn_type, len(args), " ".join(map(str, args)))
        return self.send_and_receive(command)

    def client_malloc(self, size):
        """ Calls "malloc" in client, i.e. allocate a memory
            that is visible for the verified process """
        return self.send_and_receive_int("CLIENT_MALLOC {0}\n".format(size))

    def client_free(self, mem):
        """ Calls "free" in client (an opposite function to client_malloc) """
        self.send_and_receive_ok("CLIENT_FREE {0}\n".format(mem))

    def client_malloc_from_buffer(self, buffer_id):
        """ Allocate a client's memory with the same size as buffer and
            copy buffer into this memory. """
        return self.send_and_receive_int(
            "CLIENT_MALLOC_FROM_BUFFER {0}\n".format(buffer_id))

    def memcpy(self, addr, source, size, check=True):
        """ Copies a non-overlapping block memory """
        self.send_and_receive_ok("WRITE {0} {1} addr {2} {3}\n"
                                 .format(check_str(check), addr, source, size))

    def write_into_buffer(self, buffer_id, index, addr, size):
        """ Writes a client memory into a buffer """
        # Copy a memory from client addres to the buffer
        self.send_and_receive_ok("WRITE_BUFFER {0} {1} {2} {3}\n"
                                 .format(buffer_id, index, addr, size))

    def write_data(self, addr, data, check=True):
        """ Writes data (str) into client's memory """
        size = len(data)
        if size == 0:
            return
        # TODO: the following constant should be benchmarked
        if size < 8192:
            command = "WRITE {0} {1} mem {2}\n{3}" \
                .format(check_str(check), addr, len(data), data)
            self.send_data_and_receive_ok(command)
        else:
            command = "WRITE {0} {1} mem {2}" \
                .format(check_str(check), addr, len(data))
            self.send_command(command)
            self.send_data_and_receive_ok(data)

    def write_data_into_buffer(self, buffer_addr, index, data):
        """ Writes data (str) into buffer """
        size = len(data)
        if size == 0:
            return
        # TODO: the following constant should be benchmarked
        if size < 8192:
            self.send_data_and_receive_ok(
                "WRITE_BUFFER_DATA {0} {1} {2}\n{3}"
                .format(buffer_addr, index, len(data), data))
        else:
            self.send_command("WRITE_BUFFER_DATA {0} {1} {2}\n"
                              .format(buffer_addr, index, len(data)))
            self.send_data_and_receive_ok(data)

    def write_buffer(self, addr, buffer_addr,
                     index=None, size=None, check=True):
        """ Copies a buffer into client's memory """
        if index is None or size is None:
            self.send_and_receive_ok(
                "WRITE {0} {1} buffer {2}\n"
                .format(check_str(check), addr, buffer_addr))
        else:
            assert size is not None
            if size == 0:
                return
            self.send_and_receive_ok(
                "WRITE {0} {1} buffer-part {2} {3} {4}\n"
                .format(check_str(check), addr, buffer_addr, index, size))

    def write_int(self, addr, value, check=True):
        """ Writes int into client's memory """
        self.send_and_receive_ok("WRITE {0} {1} int {2}\n"
                                 .format(check_str(check), addr, value))

    def write_string(self, addr, value, check=True):
        """ Writes string into client's memory """
        self.send_and_receive_ok("WRITE {0} {1} string {2}\n"
                                 .format(check_str(check), addr, value))

    def write_pointer(self, addr, value, check=True):
        """ Writes pointer into client's memory """
        self.send_and_receive_ok("WRITE {0} {1} pointer {2}\n"
                                 .format(check_str(check), addr, value))

    def write_ints(self, addr, values, check=True):
        """ Writes an array of ints into client's memory """
        self.send_and_receive_ok(
            "WRITE {0} {1} ints {2} {3}\n"
            .format(check_str(check),
                    addr,
                    len(values),
                    " ".join(map(str, values))))

    def read_mem(self, addr, size):
        """ Reads client's memory """
        return self.send_and_receive_data("READ {0} mem {1}\n"
                                          .format(addr, size))

    def read_int(self, addr):
        """ Reads int from client's memory """
        return self.send_and_receive_int("READ {0} int\n".format(addr))

    def read_pointer(self, addr):
        """ Reads pointer from client's memory """
        return self.send_and_receive_int("READ {0} pointer\n".format(addr))

    def read_ints(self, addr, count):
        """ Reads an array of ints from client's memory """
        line = self.send_and_receive("READ {0} ints {1}\n".format(addr, count))
        results = map(int, line.split())
        assert len(results) == count
        return results

    def read_pointers(self, addr, count):
        """ Reads an array of pointers from client's memory """
        line = self.send_and_receive("READ {0} pointers {1}\n"
                                     .format(addr, count))
        results = map(int, line.split())
        assert len(results) == count
        return results

    def read_string(self, addr):
        """ Reads a string from client's memory """
        return self.send_and_receive_data("READ {0} string\n".format(addr))

    def read_buffer(self, buffer_id):
        """ Reads a buffer """
        return self.send_and_receive_data("READ_BUFFER {0}\n"
                                          .format(buffer_id))

    def hash_state(self):
        """ Hashes current process state """
        h = self.send_and_receive("HASH\n")
        return h

    def hash_buffer(self, buffer_id):
        """ Hashes a buffer """
        return self.send_and_receive("HASH_BUFFER {0}\n".format(buffer_id))

    def get_stacktrace(self):
        """ Returns stack trace (each item separeted by ';') """
        return self.send_and_receive("STACKTRACE\n")

    def get_stats(self):
        """ Gets internal statistic from client
           (number of states, buffers, etc ...) """
        self.send_command("STATS\n")
        result = {}
        for entry in self.receive_line().split("|"):
            name, value = entry.split()
            result[name] = int(value)
        return result

    def is_writable(self, addr, size):
        """ Returns True if an client's address is writable """
        return self.send_and_receive("CHECK write {0} {1}\n"
                                     .format(addr, size))

    def is_readable(self, addr, size):
        """ Returns True if an client's address is readable """
        return self.send_and_receive("CHECK read {0} {1}\n".format(addr, size))

    def lock_memory(self, addr, size):
        """ Marks a client's memory as read only """
        self.send_and_receive_ok("LOCK {0} {1}\n".format(addr, size))

    def unlock_memory(self, addr, size):
        """ Marks a client's memory as defined """
        self.send_and_receive_ok("UNLOCK {0} {1}\n".format(addr, size))

    def get_allocations(self):
        """ Get list of client's allocations on heap """
        return self.send_and_receive("ALLOCATIONS\n")

    def interconn_listen(self):
        """ Clients start to listen for a connection on a free port,
            that is returned from the method.
            This blocks AVT but not controller.
            Method 'interconn_listen_finish' has to be called
            after this method """
        port = self.send_and_receive_int("CONN_LISTEN\n")
        self.running = True
        return port

    def interconn_listen_finish(self):
        """ This has to be called after interconn_listen.
            It blocks until the client is not connected and then
            returns socket id """
        return int(self.finish_async())

    def interconn_connect(self, host):
        """ Initializes a connection to another AVT that is listening by
            'interconn_listen'. This has be followed by
            'interconn_connect_finish'. """
        self.running = True
        return self.send_command("CONN_CONNECT {0}\n".format(host))

    def interconn_connect_finish(self):
        """ This method has to follow 'interconn_connect'.
            Blocks until connection is not finished.
            Returns socket id."""
        return int(self.finish_async())

    def push_state(self, socket, state_id):
        """ Send a state through an AVT interconnection """
        self.send_command("CONN_PUSH_STATE {0} {1}\n".format(socket, state_id))

    def pull_state(self, socket):
        """ Receives a state through an AVT interconnection """
        return self.send_and_receive_int("CONN_PULL_STATE {0}\n"
                                         .format(socket))

    def send_command(self, command):
        """ Send a command to AVT """
        assert command[-1] == "\n", "Command does not end with new line"
        self.socket.send_data(command)

    def send_data(self, data):
        """ Send data to AVT """
        self.socket.send_data(data)

    def receive_line(self):
        """ Receives a line (string) from AVT """
        line = self.socket.read_line()
        if line.startswith("Error:"):
            raise Exception("Received line: " + line)
        return line

    def receive_data(self):
        """ Receives a data from AVT """
        args = self.socket.read_line().split()
        return self.socket.read_data(int(args[1]))

    def send_and_receive(self, command):
        """ Sends a command and waits for the answer."""
        self.send_command(command)
        assert not self.running
        return self.receive_line()

    def send_and_receive_data(self, command):
        """ Sends a command and waits for the answer as data."""
        self.send_command(command)
        assert not self.running
        return self.receive_data()

    def send_and_receive_ok(self, command):
        """ Sends a command and waits for its confirmation (string "Ok\n") """
        self.send_command(command)
        assert not self.running
        r = self.receive_line()
        if r != "Ok":
            raise self.on_unexpected_output(r)

    def send_data_and_receive_ok(self, data):
        """ Sends data and waits for its confirmation (string "Ok\n") """
        self.send_data(data)
        assert not self.running
        r = self.receive_line()
        if r != "Ok":
            raise self.on_unexpected_output(r)

    def on_unexpected_output(self, line):
        """ This method is called when unexpected output is received,
            by default it throws UnexpectedOutput exception"""
        raise UnexpectedOutput(line)

    def receive_until_ok(self):
        """ Receives lines until "Ok" is not received """
        result = []
        line = self.receive_line()
        while line != "Ok":
            result.append(line)
            line = self.receive_line()
        return result

    def send_and_receive_int(self, command):
        """ Sends a command and waits for int """
        return int(self.send_and_receive(command))

    def debug_compare(self, state_id1, state_id2):
        """ Compares two saved states in AVT """
        self.send_and_receive_ok("DEBUG_COMPARE {0} {1}\n"
                                 .format(state_id1, state_id2))

    def debug_dump_state(self, state_id):
        """ Dumps a saved state on stderr """
        self.send_and_receive_ok("DEBUG_DUMP_STATE {0}\n"
                                 .format(state_id))

    def make_buffer(self, buffer_id, size):
        """ Creates a new buffer """
        self.send_and_receive_ok("NEW_BUFFER {0} {1}\n"
                                 .format(buffer_id, size))

    def free_buffer(self, buffer_id):
        """ Frees a buffer """
        self.send_command("FREE_BUFFER {0}\n".format(buffer_id))

    def _start_valgrind(self, port, capture_syscalls):
        args = (
            self.valgrind_bin,
            "-q",
            "--tool=aislinn",
            "--port={0}".format(port),
            "--identification={0}".format(self.name),
        ) + tuple(["--capture-syscall=" + name for name in capture_syscalls])

        if self.profile:
            args += ("--profile=yes",)

        if self.heap_size is not None:
            args += ("--heap-size={0}".format(self.heap_size),)

        if self.redzone_size is not None:
            args += ("--alloc-redzone-size={0}".format(self.redzone_size),)

        if self.verbose is not None:
            args += ("--verbose={0}".format(self.verbose),)

        args += self.args

        if self.debug_by_valgrind_tool:
            args = (
                "valgrind",
                "--tool=" + self.debug_by_valgrind_tool,
                "--sim-hints=enable-outer",
                "--trace-children=yes",
                "--smc-check=all-non-file",
                "--run-libc-freeres=no") + args

        logging.debug("Starting valgrind with %s", args)

        if self.extra_env:
            env = os.environ.copy()
            for v in self.extra_env:
                env[v] = self.extra_env[v]
        else:
            env = None
        self.process = subprocess.Popen(
            args, cwd=self.cwd, env=env,
            stdout=self.stdout_file, stderr=self.stderr_file)

    def _start_server(self):
        HOST = "127.0.0.1"  # Connection only from localhost
        PORT = 0  # Alloc arbirary empty port
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.bind((HOST, PORT))
        s.listen(1)
        return s

    def __repr__(self):
        return "<Controller '{0}'>".format(self.name)
コード例 #12
0
ファイル: controller.py プロジェクト: msurkovsky/aislinn
class Controller:

    # TODO: Universal architecture detection
    POINTER_SIZE = 8
    INT_SIZE = 4

    FUNCTION_INT = 0
    FUNCTION_4_POINTER = 1
    FUNCTION_2_INT_2_POINTER = 2
    FUNCTION_2_INT_4_POINTER = 3

    debug_by_valgrind_tool = None

    stdout_arg = None
    buffer_server_port = None
    profile = False

    name = "" # For debug purpose

    def __init__(self, args, cwd=None):
        self.process = None
        self.socket = None
        self.recv_buffer = ""
        self.args = tuple(args)
        self.cwd = cwd
        self.valgrind_args = ()
        self.server_socket = None
        self.running = False

    def start(self, capture_syscalls=()):
        assert self.process is None # Nothing is running
        assert self.socket is None

        self.server_socket = self._start_server()
        port = self.server_socket.getsockname()[1]
        self._start_valgrind(port, capture_syscalls)

    def start_and_connect(self, *args, **kw):
        self.start(*args, **kw)
        self.connect()
        return self.receive_line()

    def connect(self):
        self.server_socket.settimeout(5.0)
        try:
            sock, addr = self.server_socket.accept()
        except socket.timeout:
            logging.error("Aislinn client was not started")
            return False
        self.socket = SocketWrapper(sock)
        self.socket.set_no_delay()
        self.server_socket.close()
        self.server_socket = None
        return True
        # User has to call receive_line after calling this method
        # But it may take some time to initialize vgclient, hence
        # it is not build in in connect to allow polling

    def kill(self):
        if self.process and self.process.poll() is None:
            self.process.kill()
            self.process = None

    def run_process(self):
        return self.send_and_receive("RUN\n")

    def run_drop_syscall(self):
        return self.send_and_receive("RUN_DROP_SYSCALL\n")

    def run_process_async(self):
        self.running = True
        self.send_command("RUN\n")

    def run_drop_syscall_async(self):
        self.running = True
        self.send_command("RUN_DROP_SYSCALL\n")

    def run_function(self, fn_pointer, fn_type, *args):
        command = "RUN_FUNCTION {0} {1} {2} {3} \n".format(
                fn_pointer, fn_type, len(args), " ".join(map(str, args)))
        return self.send_and_receive(command)

    def client_malloc(self, size):
        return self.send_and_receive_int("CLIENT_MALLOC {0}\n".format(size))

    def client_free(self, mem):
        self.send_and_receive_ok("CLIENT_FREE {0}\n".format(mem))

    def client_malloc_from_buffer(self, buffer_id):
        return self.send_and_receive_int(
                "CLIENT_MALLOC_FROM_BUFFER {0}\n".format(buffer_id))

    def memcpy(self, addr, source, size, check=True):
        self.send_and_receive_ok("WRITE {0} {1} addr {2} {3}\n" \
                .format(check_str(check), addr, source, size))

    def write_into_buffer(self, buffer_addr, index, addr, size):
        # Copy a memory from client addres to the buffer
        self.send_and_receive_ok("WRITE_BUFFER {0} {1} {2} {3}\n" \
                    .format(buffer_addr, index, addr, size))

    def write_data_into_buffer(self, buffer_addr, index, data):
        # Write a literal data into the buffer
        size = len(data)
        if size == 0:
            return
        # TODO: the following constant should be benchmarked
        if size < 8192:
            self.send_data_and_receive_ok(
                    "WRITE_BUFFER_DATA {0} {1} {2}\n{3}" \
                            .format(buffer_addr, index, len(data), data))
        else:
            self.send_command("WRITE_BUFFER_DATA {0} {1} {2}\n" \
                        .format(buffer_addr, index, len(data)))
            self.send_data_and_receive_ok(data)

    def write_buffer(self, addr, buffer_addr,
                     index=None, size=None, check=True):
        if index is None or size is None:
            self.send_and_receive_ok("WRITE {0} {1} buffer {2}\n" \
                    .format(check_str(check), addr, buffer_addr))
        else:
            assert size is not None
            if size == 0:
                return
            self.send_and_receive_ok("WRITE {0} {1} buffer-part {2} {3} {4}\n" \
                    .format(check_str(check), addr, buffer_addr, index, size))

    def write_int(self, addr, value, check=True):
        self.send_and_receive_ok("WRITE {0} {1} int {2}\n" \
                .format(check_str(check), addr, value))

    def write_string(self, addr, value, check=True):
        self.send_and_receive_ok("WRITE {0} {1} string {2}\n" \
                .format(check_str(check), addr, value))


    def write_pointer(self, addr, value, check=True):
        self.send_and_receive_ok("WRITE {0} {1} pointer {2}\n" \
                .format(check_str(check), addr, value))

    def write_ints(self, addr, values, check=True):
        self.send_and_receive_ok("WRITE {0} {1} ints {2} {3}\n" \
                .format(check_str(check), addr, len(values), " ".join(map(str, values))))

    def read_mem(self, addr, size):
        return self.send_and_receive_data("READ {0} mem {1}\n" \
                .format(addr, size))

    def read_int(self, addr):
        return self.send_and_receive_int("READ {0} int\n".format(addr))

    def read_pointer(self, addr):
        return self.send_and_receive_int("READ {0} pointer\n".format(addr))

    def read_ints(self, addr, count):
        line = self.send_and_receive("READ {0} ints {1}\n".format(addr, count))
        results = map(int, line.split())
        assert len(results) == count
        return results

    def read_pointers(self, addr, count):
        line = self.send_and_receive("READ {0} pointers {1}\n" \
                .format(addr, count))
        results = map(int, line.split())
        assert len(results) == count
        return results

    def read_string(self, addr):
        return self.send_and_receive_data("READ {0} string\n".format(addr))

    def hash_state(self):
        #s = time.time()
        h = self.send_and_receive("HASH\n")
        #e = time.time()
        #print e - s
        return h

    def hash_buffer(self, buffer_id):
        return self.send_and_receive("HASH_BUFFER {0}\n".format(buffer_id))

    def get_stacktrace(self):
        return self.send_and_receive("STACKTRACE\n")

    def get_stats(self):
        self.send_command("STATS\n")
        result = {}
        for entry in self.receive_line().split("|"):
            name, value = entry.split()
            result[name] = int(value)
        return result

    def is_writable(self, addr, size):
        return self.send_and_receive("CHECK write {0} {1}\n".format(addr, size))

    def is_readable(self, addr, size):
        return self.send_and_receive("CHECK read {0} {1}\n".format(addr, size))

    def lock_memory(self, addr, size):
        self.send_and_receive_ok("LOCK {0} {1}\n".format(addr, size))

    def unlock_memory(self, addr, size):
        self.send_and_receive_ok("UNLOCK {0} {1}\n".format(addr, size))

    def get_allocations(self):
        return self.send_and_receive("ALLOCATIONS\n");

    ### Semi-internal functions

    def send_command(self, command):
        assert command[-1] == "\n", "Command does not end with new line"
        self.socket.send_data(command)

    def send_data(self, data):
       self.socket.send_data(data)

    def receive_line(self):
        line = self.socket.read_line()
        if line.startswith("Error:"):
            raise Exception("Received line: " + line)
        return line

    def finish_async(self):
        assert self.running
        self.running = False
        return self.receive_line()

    def receive_data(self):
        args = self.socket.read_line().split()
        return self.socket.read_data(int(args[1]))

    def send_and_receive(self, command):
        self.send_command(command)
        assert not self.running
        return self.receive_line()

    def send_and_receive_data(self, command):
        self.send_command(command)
        assert not self.running
        return self.receive_data()

    def send_and_receive_ok(self, command):
        self.send_command(command)
        assert not self.running
        r = self.receive_line()
        if r != "Ok":
            raise self.on_unexpected_output(r)

    def send_data_and_receive_ok(self, data):
        self.send_data(data)
        assert not self.running
        r = self.receive_line()
        if r != "Ok":
            raise self.on_unexpected_output(r)

    def on_unexpected_output(self, line):
        raise UnexpectedOutput(line)

    def receive_until_ok(self):
        result = []
        line = self.receive_line()
        while line != "Ok":
            result.append(line)
            line = self.receive_line()
        return result

    def send_and_receive_int(self, command):
        return int(self.send_and_receive(command))

    def debug_compare(self, state_id1, state_id2):
        self.send_and_receive_ok(
             "DEBUG_COMPARE {0} {1}\n".format(state_id1, state_id2))

    def set_capture_syscall(self, syscall, value):
        self.send_and_receive_ok(
             "SET syscall {0} {1}\n".format(syscall, "on" if value else "off"))

    def save_state(self):
        return self.send_and_receive_int("SAVE\n")

    def restore_state(self, state_id):
        self.send_and_receive_ok("RESTORE {0}\n".format(state_id))

    def make_buffer(self, buffer_id, size):
        self.send_and_receive_ok(
             "NEW_BUFFER {0} {1}\n".format(buffer_id, size))

    def start_remote_buffer(self, buffer_id):
        self.send_command("START_REMOTE_BUFFER {0}\n".format(buffer_id))

    def finish_remote_buffer(self):
        self.send_and_receive_ok("FINISH_REMOTE_BUFFER\n")

    def remote_buffer_upload(self, addr, size):
        self.send_command("UPLOAD {0} {1}\n".format(addr, size))

    def remote_buffer_download(self, buffer_id):
        self.send_command("DOWNLOAD {0}\n".format(buffer_id))

    def free_state(self, state_id):
        self.send_command("FREE {0}\n".format(state_id))

    def free_buffer(self, buffer_id):
        self.send_command("FREE_BUFFER {0}\n".format(buffer_id))

    def _start_valgrind(self, port, capture_syscalls):
        args = (
            paths.VALGRIND_BIN,
            "-q",
            "--tool=aislinn",
            "--port={0}".format(port),
            "--identification={0}".format(self.name),
        ) + tuple([ "--capture-syscall=" + name for name in capture_syscalls ])

        if self.buffer_server_port is not None:
            args += ("--bs-port={0}".format(self.buffer_server_port),)

        if self.profile:
            args += ("--profile=yes",)

        args += tuple(self.valgrind_args) + tuple(self.args)

        if self.debug_by_valgrind_tool:
            args = (
                "valgrind",
                "--tool=" + self.debug_by_valgrind_tool,
                "--sim-hints=enable-outer",
                "--trace-children=yes",
                "--smc-check=all-non-file",
                "--run-libc-freeres=no") + args

        logging.debug("Starting valgrind with %s", args)
        self.process = subprocess.Popen(
            args, cwd=self.cwd, stdout=self.stdout_arg)

    def _start_server(self):
        HOST = "127.0.0.1" # Connection only from localhost
        PORT = 0 # Alloc arbirary empty port
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.bind((HOST, PORT))
        s.listen(1)
        return s

    def __repr__(self):
        return "<Controller '{0}'>".format(self.name)