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)
def utimensat_entry_handler(syscall_id, syscall_object, pid): """ <Purpose> utimensat call entry handler that always replays. It does several things: 1. Check if AT_FDCWD flag was passed, if not, validate flag passed 2. Noop out the current system call TODO: replay execution behavior <Returns> None """ logging.debug('Entering utimensat entry handler') if syscall_object.args[0].value != 'AT_FDCWD': util.validate_integer_argument(pid, syscall_object, 0, 0) util.noop_current_syscall(pid) logging.debug('Replaying this system call') # This code is commented out because I don't think these are out addresses. # That is, the kernel doesn't modify anything in the array. This is a # "return success" situation. #timespec0_addr = util.cint.peek_register_unsigned(pid, util.cint.EDX) #timespec1_addr = timespec0_addr + 8 #logging.debug('Timespec 0 addr: %x', timespec0_addr) #logging.debug('Timespec 1 addr: %x', timespec1_addr) #timespec0_seconds = syscall_object.args[2].value #timespec0_seconds = int(timespec0_seconds.strip('[]{}')) #timespec0_nseconds = syscall_object.args[3].value[0] #timespec0_nseconds = int(timespec0_nseconds.rstrip('[]{}')) #logging.debug('Timespec0 seconds: %d nseconds: %d', # timespec0_seconds, # timespec0_nseconds) #timespec1_seconds = syscall_object.args[4].value #timespec1_seconds = int(timespec1_seconds.strip('[]{}')) #timespec1_nseconds = syscall_object.args[5].value #timespec1_nseconds = int(timespec1_nseconds.rstrip('[]{}')) #logging.debug('Timespec1 seconds: %d nseconds: %d', # timespec1_seconds, # timespec1_nseconds) #util.cint.populate_timespec_structure(pid, # timespec0_addr, # timespec0_seconds, # timespec0_nseconds) #util.cint.populate_timespec_structure(pid, # timespec1_addr, # timespec1_seconds, # timespec1_nseconds) util.apply_return_conditions(pid, syscall_object)
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)
def mmap2_entry_handler(syscall_id, syscall_object, pid): """Never replay Checks: 0: int fd: the file descriptor being operated on Sets: nothing Not Implemented: * Determine if there are special cases we should replay """ logging.debug('Entering mmap2 entry handler') validate_integer_argument(pid, syscall_object, 1, 1) validate_integer_argument(pid, syscall_object, 4, 4) fd = syscall_object.args[4].value if fd != -1: logging.debug('Got non-anonymous mapping') print(cint.injected_state['config']['mmap_backing_files']) backing_file = cint.injected_state['config']['mmap_backing_files'][str( cint.syscall_index)] logging.debug('Selected backing file: %s', backing_file) _forge_mmap_with_backing_file(pid, syscall_object, backing_file)
def sendfile_entry_handler(syscall_id, syscall_object, pid): """ <Purpose> sendfile call entry handler that always replays. It does several things: 1. Validate the out and in fds, and the byte count 2. Noop out the current system call 3. Check offset argument 4. If offset is NULL, check 5. Set return value Checks: 0: int out_fd - file descriptor for reading 1: int in_fd - file descriptor writing 3: size_t count - bytes written Sets: return value errno <Returns> None """ logging.debug('Entering sendfile entry handler') # validate file descriptors and count arg util.validate_integer_argument(pid, syscall_object, 0, 0) util.validate_integer_argument(pid, syscall_object, 1, 1) util.validate_integer_argument(pid, syscall_object, 3, 3) offset = syscall_object.args[2].value util.noop_current_syscall(pid) if offset != 'NULL': offset_addr = util.cint.peek_register_unsigned(pid, util.cint.EDX) util.cint.populate_int(pid, offset_addr, int(offset)) util.apply_return_conditions(pid, syscall_object)