Exemple #1
0
def rt_sigaction_entry_debug_printer(pid, orig_eax, syscall_object):
    signum = cint.peek_register(pid, cint.EBX)
    newact_addr = cint.peek_register(pid, cint.ECX)
    oldact_addr = cint.peek_register(pid, cint.EDX)
    ret = cint.peek_register(pid, cint.EAX)
    logging.debug("This call has signum: %s", SIGNAL_INT_TO_SIG[signum])
    logging.debug("New act address: 0x%x", newact_addr & 0xffffffff)
    logging.debug("Old act address: 0x%x", oldact_addr & 0xffffffff)
    logging.debug("Return value: %d, ret")
def connect_exit_handler(syscall_id, syscall_object, pid):
    ret_val_from_trace = syscall_object.ret[0]
    ret_val_from_execution = cint.peek_register(pid, cint.EAX)
    if ret_val_from_execution != ret_val_from_trace:
        raise ReplayDeltaError('Return value from execution ({}) differs '
                               'from return value from trace ({})'.format(
                                   ret_val_from_execution, ret_val_from_trace))
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]])
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'))
Exemple #5
0
def _brk_debug_print_regs(pid):
    print('ORIG_EAX: ', cint.peek_register(pid, cint.ORIG_EAX))
    print('EAX: ', cint.peek_register(pid, cint.EAX))
    print('EBX: ', cint.peek_register(pid, cint.EBX))
    print('ECX: ', cint.peek_register(pid, cint.ECX))
    print('EDX: ', cint.peek_register(pid, cint.EDX))
    print('ESI: ', cint.peek_register(pid, cint.ESI))
    print('EDI: ', cint.peek_register(pid, cint.EDI))
    print('EBP: ', cint.peek_register(pid, cint.EBP))
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)
Exemple #7
0
def _forge_mmap_with_backing_file(pid, syscall_object, bf):
    # Preserve the registers mmap uses for parameters
    map_start_addr = int(syscall_object.ret[0], 16)
    logging.debug('Map start address: %x', map_start_addr & 0xffffffff)
    map_size = int(syscall_object.args[1].value)
    logging.debug('Map size: %d', map_size)
    prot = cint.peek_register(pid, cint.EDX)
    # We must make the mapping writable so we can populate it
    prot = prot | 0x2
    flags = cint.peek_register(pid, cint.ESI)
    flags = flags | 0x20  # MAP_ANONYMOUS
    flags = flags | 0x10  # MAP_FIXED
    fd = -1
    offset = 0

    save_EBX = cint.peek_register(pid, cint.EBX)
    save_ECX = cint.peek_register(pid, cint.ECX)
    save_EDX = cint.peek_register(pid, cint.EDX)
    save_ESI = cint.peek_register(pid, cint.ESI)
    save_EDI = cint.peek_register(pid, cint.EDI)
    save_EBP = cint.peek_register(pid, cint.EBP)

    cint.poke_register_unsigned(pid, cint.EBX, map_start_addr)
    # How big of a mapping do we want
    cint.poke_register_unsigned(pid, cint.ECX, map_size)
    # PROT options
    cint.poke_register_unsigned(pid, cint.EDX, prot)
    # Flags options
    cint.poke_register_unsigned(pid, cint.ESI, flags)
    # fd
    cint.poke_register(pid, cint.EDI, fd)
    # offset
    cint.poke_register(pid, cint.EBP, offset)

    # Advance to our crafted mmap's exit
    cint.syscall(pid, 0)
    next_syscall()

    # Copy contents of file into new mapping
    f = open(bf, 'rb')
    data = f.read()
    if len(data) > map_size:
        raise NotImplementedError('Cannot handle cases where backing file is '
                                  'larger than mapping!')
    cint.copy_bytes_into_child_process(pid, map_start_addr, data)

    # restore registers
    cint.poke_register(pid, cint.EBX, save_EBX)
    cint.poke_register(pid, cint.ECX, save_ECX)
    cint.poke_register(pid, cint.EDX, save_EDX)
    cint.poke_register(pid, cint.ESI, save_ESI)
    cint.poke_register(pid, cint.EDI, save_EDI)
    cint.poke_register(pid, cint.EBP, save_EBP)

    # HACK HACK HACK: apply_return_conditions can't handle large addresses
    cint.poke_register_unsigned(pid, cint.EAX, map_start_addr)
    cint.entering_syscall = False
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)
Exemple #9
0
def futex_exit_handler(syscall_id, syscall_object, pid):
    logging.debug('Entering futex exit handler')
    ret_val_from_trace = syscall_object.ret[0]
    ret_val_from_execution = cint.peek_register(pid, cint.EAX) & 0xffffffff
    if ret_val_from_trace != ret_val_from_execution:
        raise ReplayDeltaError('Return value from trace ({}) does not match '
                               'return value from execution ({})'.format(
                                   ret_val_from_trace, ret_val_from_execution))
Exemple #10
0
def ioctl_entry_handler(syscall_id, syscall_object, pid):
    """Always replay.
    Checks:
    0: int fd: the file descriptor being operated on
    Sets:
    The return value

    Special Action:
    does a variety of things depending on the supplied action


    """
    logging.debug('Entering ioctl handler')
    validate_integer_argument(pid, syscall_object, 0, 0)
    trace_fd = int(syscall_object.args[0].value)
    edx = cint.peek_register(pid, cint.EDX)
    logging.debug('edx: %x', edx & 0xffffffff)
    addr = edx
    noop_current_syscall(pid)
    if syscall_object.ret[0] != -1:
        cmd = syscall_object.args[1].value
        cmd_from_exe = cint.peek_register(pid, cint.ECX)
        _validate_ioctl_cmd(cmd, cmd_from_exe)

        # Alan: optimized ioctl handler
        ioctl_handlers = {
            'TCGETS': _tcgets_handler,
            'FIONREAD': _fionread_handler,
            'FIONBIO': _fionbio_handler,
            'TIOCGWINSZ': _tiocgwinsz_handler,
            'TIOCGPGRP': _tiocgpgrp_handler
            #'TCSETSW', _tcsetsw_handler),
            #'TIOCSWINSZ', _tiocswinsz_handler),
            #'TCSETSF', _tcsetsf_handler),
            #'TCSETS', _tcsets_handler),
            #'FIOCLEX', _fioclex_handler)
        }

        # transfer to handler
        try:
            ioctl_handlers[cmd](pid, addr, syscall_object)
        except KeyError:
            raise NotImplementedError("Unsupport ioctl call with %s flag", cmd)

    apply_return_conditions(pid, syscall_object)
Exemple #11
0
def futex_entry_handler(syscall_id, syscall_object, pid):
    logging.debug('Entering futex entry handler')
    addr_from_trace = int('0x' + syscall_object.args[0].value, 16)
    addr_from_execution = cint.peek_register(pid, cint.EBX) & 0xffffffff
    logging.debug('Address from trace: %x', addr_from_trace)
    logging.debug('Address from execution: %x', addr_from_execution)
    if addr_from_trace != addr_from_execution:
        raise ReplayDeltaError('Address from trace ({}) does not match '
                               'address from execution ({})'.format(
                                   addr_from_trace, addr_from_execution))
def accept_exit_handler(syscall_id, syscall_object, pid):
    logging.debug('Entering accept exit handler')
    fd_from_execution = cint.peek_register(pid, cint.EAX)
    fd_from_trace = int(syscall_object.ret[0])
    if offset_file_descriptor(fd_from_trace) != fd_from_execution:
        raise ReplayDeltaError('File descriptor from execution ({}) '
                               'differs from file descriptor from '
                               'trace ({})'.format(fd_from_execution,
                                                   fd_from_trace))
    if fd_from_execution >= 0:
        add_os_fd_mapping(fd_from_execution, fd_from_trace)
    cint.poke_register(pid, cint.EAX, fd_from_trace)
Exemple #13
0
def set_tid_address_entry_handler(syscall_id, syscall_object, pid):
    logging.debug('Entering set_tid_address_entry_handler')
    # POSIX-omni-parser treats this argument as a hex string with no 0x
    # We have to do manual cleanup here
    addr_from_trace = int('0x' + syscall_object.args[0].value, 16)
    addr_from_execution = cint.peek_register(pid, cint.EBX) & 0xffffffff
    logging.debug('Address from trace: %x', addr_from_trace)
    logging.debug('Address from execution: %x', addr_from_execution)
    if addr_from_trace != addr_from_execution:
        raise ReplayDeltaError('Address from trace ({}) does not match '
                               'address from execution ({})'.format(
                                   addr_from_trace, addr_from_execution))
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)
Exemple #15
0
def getresgid_entry_handler(syscall_id, syscall_object, pid):
    logging.debug('Entering getresgid entry handler')
    ruid = int(syscall_object.args[0].value.strip('[]'))
    euid = int(syscall_object.args[0].value.strip('[]'))
    suid = int(syscall_object.args[0].value.strip('[]'))
    ruid_addr = cint.peek_register(pid, cint.EBX)
    euid_addr = cint.peek_register(pid, cint.ECX)
    suid_addr = cint.peek_register(pid, cint.EDX)

    logging.debug('ruid: %d', ruid)
    logging.debug('euid: %d', euid)
    logging.debug('suid: %d', suid)

    logging.debug('ruid addr: %x', ruid_addr & 0xffffffff)
    logging.debug('ruid addr: %x', euid_addr & 0xffffffff)
    logging.debug('ruid addr: %x', suid_addr & 0xffffffff)
    noop_current_syscall(pid)

    cint.populate_unsigned_int(pid, ruid_addr, ruid)
    cint.populate_unsigned_int(pid, euid_addr, euid)
    cint.populate_unsigned_int(pid, suid_addr, suid)
    apply_return_conditions(pid, syscall_object)
Exemple #16
0
def mmap2_exit_handler(syscall_id, syscall_object, pid):
    logging.debug('Entering mmap2 exit handler')
    ret_from_execution = cint.peek_register(pid, cint.EAX)
    ret_from_trace = cleanup_return_value(syscall_object.ret[0])
    logging.debug('Return value from execution %x', ret_from_execution)
    logging.debug('Return value from trace %x', ret_from_trace)
    if ret_from_execution < 0:
        ret_from_execution &= 0xffffffff
    if ret_from_execution != ret_from_trace:
        logging.debug('Return value from execution (%d, %x) differs '
                      'from return value from trace (%d, %x)',
                      ret_from_execution,
                      ret_from_execution,
                      ret_from_trace,
                      ret_from_trace)
def socketcall_debug_printer(pid, orig_eax, syscall_object):
    subcall_debug_printers = {
        1: socket_debug_printer,
        9: send_debug_printer,
        13: shutdown_debug_printer
    }
    subcall_id = cint.peek_register(pid, cint.EBX)
    logging.debug('Got subcall {} {}'.format(subcall_id,
                                             SOCKET_SUBCALLS[subcall_id]))
    try:
        subcall_debug_printers[subcall_id](pid, syscall_object)
    except KeyError as e:
        logging.warning(
            'This subcall ({}) has no debug printer'.format(subcall_id))
        raise e
Exemple #18
0
def uname_entry_handler(syscall_id, syscall_object, pid):
    logging.debug('Entering uname handler')
    args = {
        x.value.split('=')[0]: x.value.split('=')[1]
        for x in syscall_object.args
    }
    args = {x.strip('{}'): y.strip('"{}') for x, y in args.iteritems()}
    logging.debug(args)
    address = cint.peek_register(pid, cint.EBX)
    noop_current_syscall(pid)
    cint.populate_uname_structure(pid, address, args['sysname'],
                                  args['nodename'], args['release'],
                                  args['version'], args['machine'],
                                  args['domainname'])
    apply_return_conditions(pid, syscall_object)
Exemple #19
0
def sched_getaffinity_entry_handler(syscall_id, syscall_object, pid):
    logging.debug('Entering sched_getaffinity entry handler')
    # We don't validate the first argument because the PID,
    # which is different for some reason?
    validate_integer_argument(pid, syscall_object, 1, 1)
    try:
        cpu_set_val = int(syscall_object.args[2].value.strip('{}'))
    except ValueError:
        raise NotImplementedError('handler cannot deal with multi-value '
                                  'cpu_sets: {}'
                                  .format(syscall_object.args[2]))
    cpu_set_addr = cint.peek_register(pid, cint.EDX)
    logging.debug('cpu_set value: %d', cpu_set_val)
    logging.debug('cpu_set address: %d', cpu_set_addr)
    noop_current_syscall(pid)
    cint.populate_cpu_set(pid, cpu_set_addr, cpu_set_val)
    apply_return_conditions(pid, syscall_object)
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)
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')
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)
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)
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)
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)
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')
Exemple #27
0
def getrlimit_entry_handler(syscall_id, syscall_object, pid):
    logging.debug('Entering getrlimit handler')
    cmd = syscall_object.args[0].value[0]
    if cmd != 'RLIMIT_STACK':
        raise Exception('Unimplemented getrlimit command {}'.format(cmd))
    addr = cint.peek_register(pid, cint.ECX)
    rlim_cur = syscall_object.args[1].value.strip('{')
    rlim_cur = rlim_cur.split('=')[1]
    if rlim_cur.find('*') == -1:
        raise Exception('Unimplemented rlim_cur format {}'.format(rlim_cur))
    rlim_cur = int(rlim_cur.split('*')[0]) * int(rlim_cur.split('*')[1])
    rlim_max = syscall_object.args[2].value.strip('}')
    rlim_max = rlim_max.split('=')[1]
    if rlim_max != 'RLIM_INFINITY':
        raise Exception('Unlimited rlim_max format {}'.format(rlim_max))
    rlim_max = 0x7fffffffffffffff
    logging.debug('rlim_cur: %s', rlim_cur)
    logging.debug('rlim_max: %x', rlim_max)
    logging.debug('Address: %s', addr)
    noop_current_syscall(pid)
    cint.populate_rlimit_structure(pid, addr, rlim_cur, rlim_max)
    apply_return_conditions(pid, syscall_object)
Exemple #28
0
def prlimit64_entry_handler(syscall_id, syscall_object, pid):
    logging.debug('Entering prlimit64 entry handler')
    validate_integer_argument(pid, syscall_object, 0, 0)
    have_new_limit = False
    have_old_limit = False
    if(syscall_object.args[2].value != 'NULL'
       and syscall_object.args[3].value != 'NULL'
       and syscall_object.args[4].value == 'NULL'):
            logging.debug('We have a new limit')
            have_new_limit = True
    elif(syscall_object.args[2].value == 'NULL'
         and syscall_object.args[3].value != 'NULL'
         and syscall_object.args[4].value != 'NULL'):
        logging.debug('We have an old limit')
        have_old_limit = True
    if have_new_limit and not have_old_limit:
        if syscall_object.args[1].value != 'RLIMIT_CORE':
            raise NotImplementedError('prlimit commands with a new limit only '
                                      'support RLIMIT_CORE')
        noop_current_syscall(pid)
        apply_return_conditions(pid, syscall_object)
    elif not have_new_limit and have_old_limit:
        if syscall_object.args[1].value != 'RLIMIT_NOFILE':
            raise NotImplementedError('prlimit commands other than '
                                      'RLIMIT_NOFILE are not supported')
        rlim_cur = int(syscall_object.args[3].value.split('=')[1])
        logging.debug('rlim_cur: %d', rlim_cur)
        rlim_max = syscall_object.args[4].value.split('=')[1]
        rlim_max = rlim_max.split('*')
        rlim_max = int(rlim_max[0]) * int(rlim_max[1].strip('}'))
        logging.debug('rlim_max: %d', rlim_max)
        addr = cint.peek_register(pid, cint.ESI)
        logging.debug('addr: %x', addr & 0xFFFFFFFF)
        noop_current_syscall(pid)
        cint.populate_rlimit_structure(pid, addr, rlim_cur, rlim_max)
        apply_return_conditions(pid, syscall_object)
    else:
        raise NotImplementedError('prlimit64 calls with both a new and old '
                                  'limit are not supported')
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)
Exemple #30
0
def mmap2_exit_handler(syscall_id, syscall_object, pid):
    """Never replay
    Checks:
    return value: The address of the new memory map
    Sets:
    nothing

    Not Implemented:
    * Determine if there are special cases we should replay

    """
    logging.debug('Entering mmap2 exit handler')
    ret_from_execution = cint.peek_register(pid, cint.EAX)
    ret_from_trace = cleanup_return_value(syscall_object.ret[0])
    logging.debug('Return value from execution %x', ret_from_execution)
    logging.debug('Return value from trace %x', ret_from_trace)
    if ret_from_execution < 0:
        ret_from_execution &= 0xffffffff
    if ret_from_execution != ret_from_trace:
        logging.debug(
            'Return value from execution (%d, %x) differs '
            'from return value from trace (%d, %x)', ret_from_execution,
            ret_from_execution, ret_from_trace, ret_from_trace)