Пример #1
0
def send_debug_printer(pid, syscall_object):
    p = cint.peek_register(pid, cint.ECX)
    params = extract_socketcall_parameters(pid, p, 4)
    addr = params[1]
    size = params[2]
    data = cint.copy_address_range(pid, addr, addr + size)
    logging.debug('This call tried to send: %s', data.encode('string-escape'))
Пример #2
0
def recvmsg_entry_handler(syscall_id, syscall_object, pid):
    """
  <Purpose>
    recvmsg call entry handler that optionally replays based
    on fd. It does several things:
    1. Retrieve parameters of socketcall from ECX register
    2. Validate sockfd argument
    3. Determine replay based on file descriptor from trace
    TODO: implement features

    Checks:
    0: int sockfd: socket file descriptor

    Sets:
    return value
    errno

  <Returns>
    None

  """
    logging.debug('Entering recvmsg entry handler')
    p = util.cint.peek_register(pid, util.cint.ECX)
    params = util.extract_socketcall_parameters(pid, p, 1)
    util.validate_integer_argument(pid, syscall_object, 0, 0, params)
    fd_from_trace = int(syscall_object.args[0].value)
    if should_replay_based_on_fd(fd_from_trace):
        raise NotImplementedError('recvmsg entry handler not '
                                  'implemented for tracked sockets')
    else:
        logging.debug('Not replaying this system call')
        swap_trace_fd_to_execution_fd(pid, 0, syscall_object, params_addr=p)
Пример #3
0
def shutdown_debug_printer(pid, syscall_object):
    p = cint.peek_register(pid, cint.ECX)
    params = extract_socketcall_parameters(pid, p, 2)
    fd = params[0]
    cmd = params[1]
    logging.debug('This call tried to shutdown: %d', fd)
    logging.debug('Command: %d: %s', cmd, SHUTDOWN_INT_TO_CMD[params[1]])
Пример #4
0
def send_entry_handler(syscall_id, syscall_object, pid):
    """
  <Purpose>
    Send call entry handler that always replays. It does several 
    things:
    1. Peek ECX register for system call parametrs
    2. Validate sockfd and message length
    3. Noop out the current syscall
    4. Set return value

    Checks:
    0: int sockfd: file descriptor or sending socket
    2: size_t len: length of const void *buf

    Sets:

  <Returns>
    None

  """
    logging.debug('Entering send entry handler')
    ecx = util.cint.peek_register(pid, util.cint.ECX)
    params = util.extract_socketcall_parameters(pid, ecx, 3)
    util.validate_integer_argument(pid, syscall_object, 0, 0, params=params)
    util.validate_integer_argument(pid, syscall_object, 2, 2, params=params)
    trace_fd = int(syscall_object.args[0].value)
    # TODO: compare trace fd against execution fd????
    util.noop_current_syscall(pid)
    util.apply_return_conditions(pid, syscall_object)
Пример #5
0
def sendto_entry_handler(syscall_id, syscall_object, pid):
    """
  <Purpose>
    sendto call entry handler that replays based on fd from trace.
    It does several things:
    1. Peek ECX for system call parameters
    2. Validate sockfd and message length
    3. Check if replay is necessary based on fd from trace

    Checks:
    0: int sockfd 
    2: size_t len

  <Returns>
    None
  """
    logging.debug('Entering sendto entry handler')
    p = util.cint.peek_register(pid, util.cint.ECX)
    params = util.extract_socketcall_parameters(pid, p, 3)
    fd_from_trace = int(syscall_object.args[0].value)
    util.validate_integer_argument(pid, syscall_object, 0, 0, params=params)
    util.validate_integer_argument(pid, syscall_object, 2, 2, params=params)
    if should_replay_based_on_fd(fd_from_trace):
        logging.debug('Replaying this system call')
        subcall_return_success_handler(syscall_id, syscall_object, pid)
    else:
        logging.debug('Not replaying this call')
        swap_trace_fd_to_execution_fd(pid, 0, syscall_object, params_addr=p)
Пример #6
0
def listen_entry_handler(syscall_id, syscall_object, pid):
    logging.debug('Entering listen entry handler')
    p = cint.peek_register(pid, cint.ECX)
    params = extract_socketcall_parameters(pid, p, 1)
    fd_from_trace = int(syscall_object.args[0].value)
    validate_integer_argument(pid, syscall_object, 0, 0, params=params)
    logging.debug('Replaying this system call')
    subcall_return_success_handler(syscall_id, syscall_object, pid)
Пример #7
0
def sendmmsg_entry_handler(syscall_id, syscall_object, pid):
    """
  <Purpose>
    sendmmsg call entry handler that replays based on trace sockfd.
    It does several things:
    1. Validate sockfd
    2. Determine replay based on trace sockfd
    3. Noop out the current system call if replay is necessary
    4. Check return value to be successful when replaying, and retrieve
    messages
    5. Extract socketcall parameters, and retrieve address
    6. TODO

    Checks:
    0: int sockfd: file descriptor of transmitting file descriptor

    Sets:
    return value
    errno

  <Returns>
    None
  
  """
    logging.debug('Entering sendmmsg entry handler')
    sockfd_from_trace = syscall_object.args[0].value
    util.validate_integer_argument(pid, syscall_object, 0, 0)
    if should_replay_based_on_fd(sockfd_from_trace):
        logging.debug('Replaying this sytem call')
        util.noop_current_syscall(pid)
        if syscall_object.ret[0] != -1:
            logging.debug('Got successful sendmmsg call')
            number_of_messages = syscall_object.ret[0]
            if syscall_id == 102:
                p = util.cint.peek_register(pid, util.cint.ECX)
                params = util.extract_socketcall_parameters(pid, p, 4)
                addr = params[1]
            else:
                addr = util.cint.peek_register(pid, util.cint.ECX)
            logging.debug('Number of messages %d', number_of_messages)
            logging.debug('Address of buffer %x', addr & 0xffffffff)
            lengths = [
                int(syscall_object.args[x].value.rstrip('}'))
                for x in range(6, (number_of_messages * 6) + 1, 6)
            ]
            logging.debug('Lengths: %s', lengths)
            util.cint.write_sendmmsg_lengths(pid, addr, number_of_messages,
                                             lengths)
        else:
            logging.debug('Got unsuccessful sendmmsg call')
        util.apply_return_conditions(pid, syscall_object)
    else:
        logging.debug('Not replaying this system call')
        swap_trace_fd_to_execution_fd(pid, 0, syscall_object)
Пример #8
0
def recvmsg_entry_handler(syscall_id, syscall_object, pid):
    logging.debug('Entering recvmsg entry handler')
    p = cint.peek_register(pid, cint.ECX)
    params = extract_socketcall_parameters(pid, p, 1)
    fd_from_trace = int(syscall_object.args[0].value)
    validate_integer_argument(pid, syscall_object, 0, 0, params)
    if should_replay_based_on_fd(fd_from_trace):
        raise NotImplementedError('recvmsg entry handler not '
                                  'implemented for tracked sockets')
    else:
        logging.debug('Not replaying this system call')
        swap_trace_fd_to_execution_fd(pid, 0, syscall_object, params_addr=p)
Пример #9
0
def recv_subcall_entry_handler(syscall_id, syscall_object, pid):
    """
  <Purpose>
    recv subcall entry handler that replays based on fd. It does several 
    things:
    1. Retrieve parameters of socketcall from ECX register 
    2. Validate sockfd and length arguments.
    3. Determine if replay is necessary by fd from trace
    If replay: 
      4. Noop the current system call
      5. Retrieve buffer pointer address and cleaned up
         data in the buffer
      6. Use buffer address and retrieved data to populate the buffer
      7. Sets the return value
    If not replayed:
      4. Swap trace fd to execution

  Checks:
  0: int sockfd
  2: size_t len

  Sets:
  1: void *buf: buffer representing data received
  return value
  errno

  <Returns>
    None
  """
    p = util.cint.peek_register(pid, util.cint.ECX)
    params = util.extract_socketcall_parameters(pid, p, 4)
    # We don't check params[1] because it is the address of an empty buffer
    # We don't check params[3] because it is a flags field
    util.validate_integer_argument(pid, syscall_object, 0, 0, params)
    util.validate_integer_argument(pid, syscall_object, 2, 2, params)
    # Decide if we want to replay this system call
    fd_from_trace = syscall_object.args[0].value
    if should_replay_based_on_fd(fd_from_trace):
        logging.info('Replaying this system call')
        util.noop_current_syscall(pid)
        buffer_address = params[1]
        data = util.cleanup_quotes(syscall_object.args[1].value)
        data = data.decode('string_escape')
        util.cint.populate_char_buffer(pid, buffer_address, data)
        util.apply_return_conditions(pid, syscall_object)
    else:
        logging.info("Not replaying this system call")
        swap_trace_fd_to_execution_fd(pid, 0, syscall_object, params_addr=p)
Пример #10
0
def recvfrom_subcall_entry_handler(syscall_id, syscall_object, pid):
    p = cint.peek_register(pid, cint.ECX)
    params = extract_socketcall_parameters(pid, p, 6)
    validate_integer_argument(pid, syscall_object, 0, 0, params)
    validate_integer_argument(pid, syscall_object, 2, 2, params)
    # We don't check params[1] because it is the address of an empty buffer
    # We don't check params[3] because it is a flags field
    # We don't check params[4] because it is the address of an empty buffer
    # We don't check params[5] because it is the address of a length
    data_buf_addr_e = params[1]
    data_buf_length_e = params[2]
    sockaddr_addr_e = params[4]
    sockaddr_length_addr_e = params[5]

    fd_t = syscall_object.args[0].value
    data = syscall_object.args[1].value
    data = cleanup_quotes(data)
    data = data.decode('string_escape')
    sockfields = syscall_object.args[4].value
    port = int(sockfields[1].value)
    ip = sockfields[2].value
    sockaddr_length_t = int(syscall_object.args[5].value.strip('[]'))

    ret_val = int(syscall_object.ret[0])

    # Decide if we want to replay this system call
    if should_replay_based_on_fd(fd_t):
        logging.info('Replaying this system call')
        noop_current_syscall(pid)
        if len(data) != ret_val:
            raise ReplayDeltaError('Decoded bytes length ({}) does not equal '
                                   'return value from trace ({})'.format(
                                       len(data), ret_val))
        cint.populate_char_buffer(pid, data_buf_addr_e, data)
        cint.populate_af_inet_sockaddr(pid, sockaddr_addr_e, port, ip,
                                       sockaddr_length_addr_e,
                                       sockaddr_length_t)
        buf = cint.copy_address_range(pid, data_buf_addr_e,
                                      data_buf_addr_e + data_buf_length_e)
        if buf[:ret_val] != data:
            raise ReplayDeltaError('Data copied by read() handler doesn\'t '
                                   'match after copy')
        apply_return_conditions(pid, syscall_object)
        print(cint.peek_register(pid, cint.EAX))
    else:
        logging.info('Not replaying this system call')
        swap_trace_fd_to_execution_fd(pid, 0, syscall_object, params_addr=p)
Пример #11
0
def getsockname_entry_handler(syscall_id, syscall_object, pid):
    """Replay Always
    Checks:
    0: The socket file descriptor
    Sets:
    addr: a struct sockaddr populated with the requested information
    addrlen: length of the sockaddr struct being populated
    return value: 0 (success) or -1 (failure)
    errno

    Not Implemented:
    * Use address validator to check the addresses
    """
    logging.debug('Entering getsockname handler')
    # Pull out the info that we can check
    ecx = cint.peek_register(pid, cint.ECX)
    params = extract_socketcall_parameters(pid, ecx, 3)
    # We don't compare params[1] because it is the address of an empty buffer
    # We don't compare params[2] because it is the address of an out parameter
    # Get values from trace for comparison
    fd_from_trace = syscall_object.args[0].value
    validate_integer_argument(pid, syscall_object, 0, 0, params=params)
    # Decide if this is a file descriptor we want to deal with
    noop_current_syscall(pid)
    if syscall_object.ret[0] != -1:
        logging.debug('Got successful getsockname call')
        addr = params[1]
        length_addr = params[2]
        length = int(syscall_object.args[2].value.strip('[]'))
        logging.debug('Addr: %d', addr & 0xffffffff)
        logging.debug('Length addr: %d', length_addr & 0xffffffff)
        logging.debug('Length: %d', length)
        sockfields = syscall_object.args[1].value
        family = sockfields[0].value
        port = int(sockfields[1].value)
        ip = sockfields[2].value
        logging.debug('Family: %s', family)
        logging.debug('Port: %d', port)
        logging.debug('Ip: %s', ip)
        if family != 'AF_INET':
            raise NotImplementedError('getsockname only supports ' 'AF_INET')
        cint.populate_af_inet_sockaddr(pid, addr, port, ip, length_addr,
                                       length)
    else:
        logging.debug('Got unsuccessful getsockname call')
    apply_return_conditions(pid, syscall_object)
Пример #12
0
def socket_entry_handler(syscall_id, syscall_object, pid):
    """Replay Always
    Checks:
    0: The domain of the socket
    Sets:
    return value: file descriptor of the new socket -1 (error)
        (added as replay file descriptor)
    errno

    Not Implemented:
    * Determine what is not implemented
    """
    logging.debug('Entering socket subcall entry handler')

    ecx = cint.peek_register(pid, cint.ECX)
    params = extract_socketcall_parameters(pid, ecx, 3)
    # Only PF_INET and PF_LOCAL socket calls are handled
    execution_is_PF_INET = (params[0] == cint.PF_INET)
    trace_is_PF_INET = (str(syscall_object.args[0]) == '[\'PF_INET\']')
    execution_is_PF_LOCAL = (params[0] == 1)  # define PF_LOCAL 1
    trace_is_PF_LOCAL = (str(syscall_object.args[0]) == '[\'PF_LOCAL\']')
    logging.debug('Execution is PF_INET: %s', execution_is_PF_INET)
    logging.debug('Trace is PF_INET: %s', trace_is_PF_INET)
    logging.debug('Exeuction is PF_LOCAL: %s', execution_is_PF_LOCAL)
    logging.debug('Trace is PF_LOCAL: %s', trace_is_PF_LOCAL)
    if execution_is_PF_INET != trace_is_PF_INET:
        raise ReplayDeltaError(
            'Encountered socket subcall with mismatch between '
            'execution protocol family and trace protocol family')
    if execution_is_PF_LOCAL != trace_is_PF_LOCAL:
        raise ReplayDeltaError(
            'Encountered socket subcall with mismatch between '
            'execution protocol family and trace protocol family')
    # Decide if we want to deal with this socket call or not
    if trace_is_PF_INET or \
       execution_is_PF_INET or \
       trace_is_PF_LOCAL or \
       execution_is_PF_LOCAL:
        noop_current_syscall(pid)
        fd = int(syscall_object.ret[0])
        logging.debug('File Descriptor from trace: %s', fd)
        apply_return_conditions(pid, syscall_object)
    else:
        logging.info('Ignoring non-PF_INET call to socket')
Пример #13
0
def accept_subcall_entry_handler(syscall_id, syscall_object, pid):
    """Replay Always
    Checks:
    0: sockfd: the socket file descriptor
    Sets:
    return value: The file descriptor -1 (error)
    errno

    Not Implemented:
    * Implement a function to check null terminated strings to clean up this
      mess of checking
    """
    logging.debug('Checking if line from trace is interrupted accept')
    if syscall_object.ret[0] == '?':
        raise NotImplementedError('Interrupted accept()s not implemented')
    ecx = cint.peek_register(pid, cint.ECX)
    params = extract_socketcall_parameters(pid, ecx, 3)
    sockaddr_addr = params[1]
    sockaddr_len_addr = params[2]
    fd_from_trace = syscall_object.args[0].value
    validate_integer_argument(pid, syscall_object, 0, 0, params=params)
    # Decide if this is a system call we want to replay
    noop_current_syscall(pid)
    if syscall_object.ret[0] != -1 and syscall_object.args[1].value != 'NULL':
        sockfields = syscall_object.args[1].value
        family = sockfields[0].value
        port = int(sockfields[1].value)
        ip = sockfields[2].value
        sockaddr_length = int(syscall_object.args[2].value.strip('[]'))
        logging.debug('Family: %s', family)
        logging.debug('Port: %s', port)
        logging.debug('IP: %s', ip)
        logging.debug('sockaddr Length: %s', sockaddr_length)
        logging.debug('sockaddr addr: %x', sockaddr_addr & 0xffffffff)
        logging.debug('sockaddr length addr: %x',
                      sockaddr_len_addr & 0xffffffff)
        logging.debug('pid: %s', pid)
        cint.populate_af_inet_sockaddr(pid, sockaddr_addr, port, ip,
                                       sockaddr_len_addr, sockaddr_length)
    if syscall_object.ret[0] != -1:
        ret = syscall_object.ret[0]
    apply_return_conditions(pid, syscall_object)
Пример #14
0
def shutdown_subcall_entry_handler(syscall_id, syscall_object, pid):
    """Replay Always
    Checks:
    0: sockfd: the socket file descriptor
    Sets:
    return value: 0 (success) or -1 (error)
    errno

    """
    logging.debug('Entering shutdown entry handler')
    # Pull out the info we can check
    ecx = cint.peek_register(pid, cint.ECX)
    params = extract_socketcall_parameters(pid, ecx, 2)
    fd_from_trace = syscall_object.args[0].value
    validate_integer_argument(pid, syscall_object, 0, 0, params=params)
    # TODO: We need to check the 'how' parameter here
    # Check to make sure everything is the same
    # Decide if we want to replay this system call
    noop_current_syscall(pid)
    apply_return_conditions(pid, syscall_object)
Пример #15
0
def connect_entry_handler(syscall_id, syscall_object, pid):
    """Replay Always
    Checks:
    0: The socket file descriptor
    2: The length of the sockaddr structure pointed to by 1
    Sets:
    return value: file descriptor of the new socket -1 (error)
    errno

    Not Implemented:
    * Determine what is not implemented
    """

    logging.debug('Entering connect entry handler')
    ecx = cint.peek_register(pid, cint.ECX)
    params = extract_socketcall_parameters(pid, ecx, 3)
    validate_integer_argument(pid, syscall_object, 0, 0, params=params)
    validate_integer_argument(pid, syscall_object, 2, 2, params=params)
    trace_fd = int(syscall_object.args[0].value)
    noop_current_syscall(pid)
    apply_return_conditions(pid, syscall_object)
Пример #16
0
def getpeername_entry_handler(syscall_id, syscall_object, pid):
    logging.debug('Entering getpeername handler')
    # Pull out the info that we can check
    ecx = cint.peek_register(pid, cint.ECX)
    params = extract_socketcall_parameters(pid, ecx, 3)
    fd = params[0]
    # We don't compare params[1] because it is the address of an empty buffer
    # We don't compare params[2] because it is the address of an out parameter
    # Get values from trace for comparison
    fd_from_trace = syscall_object.args[0].value
    # Check to make sure everything is the same
    if fd != int(fd_from_trace):
        raise ReplayDeltaError(
            'File descriptor from execution ({}) '
            'does not match file descriptor from trace ({})'.format(
                fd, fd_from_trace))
    # Decide if this is a file descriptor we want to deal with
    noop_current_syscall(pid)
    if syscall_object.ret[0] != -1:
        logging.debug('Got successful getpeername call')
        addr = params[1]
        length_addr = params[2]
        length = int(syscall_object.args[2].value.strip('[]'))
        logging.debug('Addr: %d', addr)
        logging.debug('Length addr: %d', length_addr)
        logging.debug('Length: %d', length)
        sockfields = syscall_object.args[1].value
        family = sockfields[0].value
        port = int(sockfields[1].value)
        ip = sockfields[2].value
        logging.debug('Family: %s', family)
        logging.debug('Port: %d', port)
        logging.debug('Ip: %s', ip)
        if family != 'AF_INET':
            raise NotImplementedError('getpeername only ' 'supports AF_INET')
        cint.populate_af_inet_sockaddr(pid, addr, port, ip, length_addr,
                                       length)
    else:
        logging.debug('Got unsuccessful getpeername call')
    apply_return_conditions(pid, syscall_object)
Пример #17
0
def setsockopt_entry_handler(syscall_id, syscall_object, pid):
    """Replay Always
    Checks:
    0: sockfd: the socket file descriptor
    Sets:
    optval: out parameter
    return value: 0 (success) or -1 (error)
    errno

    Not Implemented: More checking

    """
    logging.debug('Entering setsockopt handler')
    ecx = cint.peek_register(pid, cint.ECX)
    params = extract_socketcall_parameters(pid, ecx, 5)
    fd_from_trace = int(syscall_object.args[0].value)
    optval_addr = params[3]
    # We don't check param[3] because it is an address of an empty buffer
    # We don't check param[4] because it is an address of an empty length
    validate_integer_argument(pid, syscall_object, 0, 0, params=params)
    noop_current_syscall(pid)
    apply_return_conditions(pid, syscall_object)
Пример #18
0
def recv_subcall_entry_handler(syscall_id, syscall_object, pid):
    p = cint.peek_register(pid, cint.ECX)
    params = extract_socketcall_parameters(pid, p, 4)
    # Pull out everything we can check
    fd_from_trace = syscall_object.args[0].value
    # We don't check params[1] because it is the address of an empty buffer
    # We don't check params[3] because it is a flags field
    # Check to make everything is the same
    validate_integer_argument(pid, syscall_object, 0, 0, params)
    validate_integer_argument(pid, syscall_object, 2, 2, params)
    # Decide if we want to replay this system call
    if should_replay_based_on_fd(fd_from_trace):
        logging.info('Replaying this system call')
        noop_current_syscall(pid)
        buffer_address = params[1]
        data = cleanup_quotes(syscall_object.args[1].value)
        data = data.decode('string_escape')
        cint.populate_char_buffer(pid, buffer_address, data)
        apply_return_conditions(pid, syscall_object)
    else:
        swap_trace_fd_to_execution_fd(pid, 0, syscall_object, params_addr=p)
        logging.info('Not replaying this system call')
Пример #19
0
def getsockopt_entry_handler(syscall_id, syscall_object, pid):
    """Replay Always
    Checks:
    0: The socket file descriptor
    Sets:
    optval: The value being retrieved
    optval_len: The length of the value being retrieved
    return value: 0 (success) or 1 (failure)
    errno

    Not Implemented:
    * Use the address validator to check addresses
    """
    logging.debug('Entering getsockopt handler')
    # Pull out what we can compare
    ecx = cint.peek_register(pid, cint.ECX)
    params = extract_socketcall_parameters(pid, ecx, 5)
    fd_from_trace = int(syscall_object.args[0].value)
    optval_addr = params[3]
    optval_len_addr = params[4]
    validate_integer_argument(pid, syscall_object, 0, 0, params=params)
    # This if is sufficient for now for the implemented options
    if params[1] != 1 or params[2] != 4:
        raise NotImplementedError('Unimplemented getsockopt level or optname')
    optval_len = int(syscall_object.args[4].value.strip('[]'))
    if optval_len != 4:
        raise NotImplementedError('getsockopt() not implemented for '
                                  'optval sizes other than 4')
    optval = int(syscall_object.args[3].value.strip('[]'))
    logging.debug('Optval: %s', optval)
    logging.debug('Optval Length: %s', optval_len)
    logging.debug('Optval addr: %x', optval_addr & 0xffffffff)
    logging.debug('Optval Lenght addr: %d', optval_len_addr & 0xffffffff)
    noop_current_syscall(pid)
    cint.populate_int(pid, optval_addr, optval)
    cint.populate_int(pid, optval_len_addr, 4)
    apply_return_conditions(pid, syscall_object)
Пример #20
0
def socket_debug_printer(pid, syscall_object):
    p = cint.peek_register(pid, cint.ECX)
    params = extract_socketcall_parameters(pid, p, 3)
    logging.debug('Domain: %s', ADDRFAM_INT_TO_FAM[params[0]])
    logging.debug('Type: %s', SOCKTYPE_INT_TO_TYPE[params[1]])
    logging.debug('Protocol: %s', PROTOFAM_INT_TO_FAM[params[2]])
Пример #21
0
def recvfrom_subcall_entry_handler(syscall_id, syscall_object, pid):
    """
  <Purpose>
    recvfrom subcall entry handler that replays based on fd. It does
    several things:
    1. Retrieve parameters of socketcall from ECX register
    2. Validate sockfd and length argument
    3. Retrieve buffer address, length, and sockadrr struct address
    4. From sockaddr src_addr, retrieve attributes
    5. Determine if replay is necessary based on fd
    If replay:
      6. Noop out the current system call
      7. Raise error if length of data is not requal to return value
      8. Populate *buf argument of given length and data
      from retrieved values
      9. Populate the sockaddr *addr parameter.
      10. Check if data in buffer at trace and execution match
      11. Sets return value
    If not replay:
      6. Swap trace fd to execution

    Checks:
    0: int sockfd
    2: size_t len

    Sets:
    1: void *buf: buffer representing message being received
    4: struct sockaddr *src_addr: 
          attributes of sockaddr representing source address
    return value
    errno

  <Returns>
    None

  """
    p = util.cint.peek_register(pid, util.cint.ECX)
    params = util.extract_socketcall_parameters(pid, p, 6)
    util.validate_integer_argument(pid, syscall_object, 0, 0, params)
    util.validate_integer_argument(pid, syscall_object, 2, 2, params)
    # We don't check params[1] because it is the address of an empty buffer
    # We don't check params[3] because it is a flags field
    # We don't check params[4] because it is the address of an empty buffer
    # We don't check params[5] because it is the address of a length
    data_buf_addr_e = params[1]
    data_buf_length_e = params[2]
    sockaddr_addr_e = params[4]
    sockaddr_length_addr_e = params[5]

    fd_t = syscall_object.args[0].value
    data = syscall_object.args[1].value
    data = util.cleanup_quotes(data)
    data = data.decode('string_escape')
    sockfields = syscall_object.args[4].value
    port = int(sockfields[1].value)
    ip = sockfields[2].value
    sockaddr_length_t = int(syscall_object.args[5].value.strip('[]'))

    ret_val = int(syscall_object.ret[0])

    # Decide if we want to replay this system call
    if should_replay_based_on_fd(fd_t):
        logging.info('Replaying this system call')
        util.noop_current_syscall(pid)
        if len(data) != ret_val:
            raise util.ReplayDeltaError(
                'Decoded bytes length ({}) does not equal '
                'return value from trace ({})'.format(len(data), ret_val))
        util.cint.populate_char_buffer(pid, data_buf_addr_e, data)
        util.cint.populate_af_inet_sockaddr(pid, sockaddr_addr_e, port, ip,
                                            sockaddr_length_addr_e,
                                            sockaddr_length_t)
        buf = util.cint.copy_address_range(pid, data_buf_addr_e,
                                           data_buf_addr_e + data_buf_length_e)
        if buf[:ret_val] != data:
            raise util.ReplayDeltaError(
                'Data copied by read() handler doesn\'t '
                'match after copy')
        util.apply_return_conditions(pid, syscall_object)
        print(util.cint.peek_register(pid, util.cint.EAX))
    else:
        logging.info('Not replaying this system call')
        swap_trace_fd_to_execution_fd(pid, 0, syscall_object, params_addr=p)