コード例 #1
0
def handle_socketcall(syscall_id, syscall_object, entering, pid):
    """
  <Purpose>
    Validate the subcall (NOT SYSCALL!) id of the socket subcall against
    the subcall name we expect based on the current system call object.  Then,
    hand off responsibility to the appropriate subcall handler.

  <Returns>
    None

  """
    subcall_handlers = {
        ('socket', True):
        socket_handlers.socket_entry_handler,
        #('socket', False): socket_exit_handler,
        ('accept', True):
        socket_handlers.accept_subcall_entry_handler,
        ('accept4', True):
        socket_handlers.accept_subcall_entry_handler,
        #('accept', False): accept_subcall_entry_handler,
        ('bind', True):
        socket_handlers.bind_entry_handler,
        #('bind', False): bind_exit_handler,
        ('listen', True):
        socket_handlers.listen_entry_handler,
        #('listen', False): listen_exit_handler,
        ('recv', True):
        recv_handlers.recv_subcall_entry_handler,
        #('recvfrom', True): recvfrom_subcall_entry_handler,
        ('setsockopt', True):
        socket_handlers.setsockopt_entry_handler,
        ('send', True):
        send_handlers.send_entry_handler,
        #('send', False): send_exit_handler,
        ('connect', True):
        socket_handlers.connect_entry_handler,
        #('connect', False): connect_exit_handler,
        ('getsockopt', True):
        socket_handlers.getsockopt_entry_handler,
        ## ('sendmmsg', True): sendmmsg_entry_handler,
        #('sendto', True): sendto_entry_handler,
        #('sendto', False): sendto_exit_handler,
        ('shutdown', True):
        socket_handlers.shutdown_subcall_entry_handler,
        #('recvmsg', True): recvmsg_entry_handler,
        #('recvmsg', False): recvmsg_exit_handler,
        ('getsockname', True):
        socket_handlers.getsockname_entry_handler,
        ('getpeername', True):
        socket_handlers.getpeername_entry_handler
    }
    # The subcall id of the socket subcall is located in the EBX register
    # according to our Linux's convention.
    subcall_id = syscallreplay.peek_register(pid, syscallreplay.EBX)
    util.validate_subcall(subcall_id, syscall_object)
    try:
        subcall_handlers[(syscall_object.name, entering)](syscall_id,
                                                          syscall_object, pid)
    except KeyError:
        raise NotImplementedError('No handler for socket subcall %s %s',
                                  syscall_object.name,
                                  'entry' if entering else 'exit')
コード例 #2
0
def main():
    # initialize parser
    parser = argparse.ArgumentParser()
    parser.add_argument('config',
                        metavar='config',
                        nargs=1,
                        type=str,
                        help="path to configuration file")
    parser.add_argument('-v',
                        '--verbosity',
                        dest='loglevel',
                        type=int,
                        default=40,
                        help='flag for displaying debug information')

    # parser arguments
    args = parser.parse_args()

    # Add simple logging for verbosity
    logger.setLevel(level=args.loglevel)
    if int(args.loglevel) == 10:
        syscallreplay.enable_debug_output(10)

    # Sets up syscallreplay.injected_state['config']
    config = "".join(args.config)
    consume_configuration(config)

    # Configure various locals from the config section of our injected state
    config_dict = syscallreplay.injected_state
    pid = int(config_dict['pid'])
    rec_pid = config_dict['rec_pid']
    event_number = config_dict['event']
    apply_mmap_backing_files()

    # create trace object
    pickle_file = consts.DEFAULT_CONFIG_PATH + "syscall_definitions.pickle"
    trace = Trace.Trace(config_dict['trace_file'], pickle_file)
    syscallreplay.syscalls = trace.syscalls
    syscallreplay.syscall_index = int(config_dict['trace_start'])
    syscallreplay.syscall_index_end = int(config_dict['trace_end'])

    # Set up checker and mutator
    checker = None
    mutator = None

    # pylint: disable=eval-used
    if 'checker' in syscallreplay.injected_state:
        checker = eval(syscallreplay.injected_state['checker'])
    if 'mutator' in syscallreplay.injected_state:
        mutator = eval(syscallreplay.injected_state['mutator'])
        mutator.mutate_syscalls(syscallreplay.syscalls)


# pylint: enable=eval-used

# Requires kernel.yama.ptrace_scope = 0
# in /etc/sysctl.d/10-ptrace.conf
# on modern Ubuntu
    logger.debug('Injecting %d', pid)
    syscallreplay.attach(pid)
    _, status = os.waitpid(pid, 0)
    logger.debug('Attached %d', pid)

    logger.debug('Requesting stop at next system call entry using SIGCONT')
    syscallreplay.syscall(pid, signal.SIGCONT)
    _, status = os.waitpid(pid, 0)

    # We need an additional call to PTRACE_SYSCALL here in order to skip
    # past an rr syscall buffering related injected system call
    logger.debug('Second sigcont %d', pid)
    syscallreplay.syscall(pid, 0)
    _, status = os.waitpid(pid, 0)

    # main system call handling loop
    logger.debug('Entering system call handling loop')
    syscallreplay.entering_syscall = True
    while not os.WIFEXITED(status):
        syscall_object = syscallreplay.syscalls[syscallreplay.syscall_index]
        try:
            syscall_id = syscallreplay.peek_register(pid,
                                                     syscallreplay.ORIG_EAX)
            debug_handle_syscall(pid, syscall_id, syscall_object,
                                 syscallreplay.entering_syscall)
        except:
            exit_with_status(pid, 1, str(mutator), event_number,
                             syscallreplay.syscall_index)

        # call transition() if checker is implemented
        if checker:
            checker.transition(syscall_object)

        # incremenent syscall_index if not entering
        if not syscallreplay.entering_syscall:
            syscallreplay.syscall_index += 1

        syscallreplay.entering_syscall = not syscallreplay.entering_syscall
        syscallreplay.syscall(pid, 0)
        _, status = os.waitpid(pid, 0)

        if syscallreplay.syscall_index == syscallreplay.syscall_index_end:
            if checker:
                print('####    Checker Status    ####')
                if checker.is_accepting():
                    print('{} accepted'.format(checker))
                else:
                    print('{} not accepted'.format(checker))
                print('####  End Checker Status  ####')
            exit_with_status(pid, 0, str(mutator), event_number)