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'))
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)
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)
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))
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 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)
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)
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)
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
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)
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')
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)
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)
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)