def doSockets(self, exit_info, eax, pid): trace_msg = '' if exit_info.callnum == self.task_utils.syscallNumber('socketcall', exit_info.compat32): socket_callname = exit_info.socket_callname socket_syscall = self.top.getSyscall(self.cell_name, 'socketcall') else: socket_callname = self.task_utils.syscallName(exit_info.callnum, exit_info.compat32) socket_syscall = self.top.getSyscall(self.cell_name, socket_callname) if socket_callname == "socket" and eax >= 0: if pid in self.trace_procs: self.traceProcs.socket(pid, eax) trace_msg = ('\treturn from socketcall SOCKET pid:%d, FD: %d\n' % (pid, eax)) elif socket_callname == "connect": if eax < 0: trace_msg = ('\texception from socketcall CONNECT pid:%d FD: %d, eax %s addr: 0x%x\n' % (pid, exit_info.sock_struct.fd, eax, exit_info.sock_struct.addr)) else: ss = exit_info.sock_struct if pid in self.trace_procs: self.traceProcs.connect(pid, ss.fd, ss.getName()) trace_msg = ('\treturn from socketcall CONNECT pid:%d, %s addr: 0x%x\n' % (pid, ss.getString(), exit_info.sock_struct.addr)) elif socket_callname == "bind": if eax < 0: trace_msg = ('\texception from socketcall BIND eax:%d, %s\n' % (pid, eax)) else: ss = exit_info.sock_struct if pid in self.trace_procs: self.traceProcs.bind(pid, ss.fd, ss.getName()) prog_name = self.traceProcs.getProg(pid) if socket_syscall is not None: binders = socket_syscall.getBinders() if binders is not None: binders.add(pid, prog_name, ss.dottedIP(), ss.port) trace_msg = ('\treturn from socketcall BIND pid:%d, %s\n' % (pid, ss.getString())) elif socket_callname == "getsockname": ss = net.SockStruct(self.cpu, exit_info.sock_struct.addr, self.mem_utils, exit_info.sock_struct.fd) trace_msg = ('\t return from getsockname pid:%d %s\n' % (pid, ss.getString())) elif socket_callname == "accept": new_fd = eax if new_fd < 0: return if exit_info.sock_struct.addr != 0: ss = net.SockStruct(self.cpu, exit_info.sock_struct.addr, self.mem_utils, fd=new_fd) if ss.sa_family == 1: if pid in self.trace_procs: self.traceProcs.accept(pid, exit_info.sock_struct.fd, new_fd, None) trace_msg = ('\treturn from socketcall ACCEPT pid:%d, sock_fd: %d new_fd: %d sa_family: %s name: %s\n' % (pid, exit_info.sock_struct.fd, new_fd, ss.famName(), ss.getName())) elif ss.sa_family == 2: if pid in self.trace_procs: self.traceProcs.accept(pid, exit_info.sock_struct.fd, new_fd, ss.getName()) trace_msg = ('\treturn from socketcall ACCEPT pid:%d, sock_fd: %d new_fd: %d sa_family: %s addr: %s\n' % (pid, exit_info.sock_struct.fd, new_fd, ss.famName(), ss.getName())) else: trace_msg = ('\treturn from socketcall ACCEPT pid:%d, sock_fd: %d new_fd: %d sa_family: %s SA Family not handled\n' % (pid, exit_info.sock_struct.fd, new_fd, ss.famName())) else: trace_msg = ('\treturn from socketcall ACCEPT pid:%d, sock_fd: %d new_fd: %d NULL addr\n' % (pid, exit_info.sock_struct.fd, new_fd)) elif socket_callname == "socketpair": fd1 = self.mem_utils.readWord32(self.cpu, exit_info.retval_addr) fd2 = self.mem_utils.readWord32(self.cpu, exit_info.retval_addr+4) if pid in self.trace_procs: self.traceProcs.socketpair(pid, fd1, fd2) trace_msg = ('\treturn from socketcall SOCKETPAIR pid:%d, fd1: %d fd2: %d\n' % (pid, fd1, fd2)) #self.lgr.debug('\treturn from socketcall SOCKETPAIR pid:%d, fd1: %d fd2: %d' % (pid, fd1, fd2)) elif socket_callname == "send" or socket_callname == "sendto" or \ socket_callname == "sendmsg": if eax >= 0: nbytes = min(eax, 256) byte_string, byte_array = self.mem_utils.getBytes(self.cpu, nbytes, exit_info.retval_addr) s = ''.join(map(chr,byte_array)) trace_msg = ('\treturn from socketcall %s pid:%d, FD: %d, count: %d\n%s\n' % (socket_callname, pid, exit_info.old_fd, eax, s)) else: trace_msg = ('\terror return from socketcall %s pid:%d, FD: %d, exception: %d\n' % (socket_callname, pid, exit_info.old_fd, eax)) if exit_info.call_params is not None and type(exit_info.call_params.match_param) is str and eax > 0: byte_string, byte_array = self.mem_utils.getBytes(self.cpu, eax, exit_info.retval_addr) s = ''.join(map(chr,byte_array)) self.lgr.debug('sharedSyscall SEND check string %s against %s' % (s, exit_info.call_params.match_param)) if exit_info.call_params.match_param not in s: ''' no match, set call_param to none ''' exit_info.call_params = None elif socket_callname == "recv" or socket_callname == "recvfrom": if eax >= 0: nbytes = min(eax, 256) byte_string, byte_array = self.mem_utils.getBytes(self.cpu, nbytes, exit_info.retval_addr) s = ''.join(map(chr,byte_array)) src = '' if exit_info.fname_addr is not None: ''' obscure use of fname_addr to store source of recvfrom ''' src_ss = net.SockStruct(self.cpu, exit_info.fname_addr, self.mem_utils, fd=-1) src = 'from: %s' % src_ss.getString() trace_msg = ('\treturn from socketcall %s pid:%d, FD: %d, count: %d into 0x%x %s\n%s\n' % (socket_callname, pid, exit_info.old_fd, eax, exit_info.retval_addr, src, s)) else: trace_msg = ('\terror return from socketcall %s pid:%d, FD: %d, exception: %d into 0x%x\n' % (socket_callname, pid, exit_info.old_fd, eax, exit_info.retval_addr)) if exit_info.call_params is not None and exit_info.call_params.break_simulation and self.dataWatch is not None: ''' in case we want to break on a read of this data ''' self.dataWatch.setRange(exit_info.retval_addr, eax) elif socket_callname == "recvmsg": msghdr = net.Msghdr(self.cpu, self.mem_utils, exit_info.retval_addr) trace_msg = ('\treturn from socketcall %s pid:%d FD: %d count: %d %s\n' % (socket_callname, pid, exit_info.old_fd, eax, msghdr.getString())) if eax < 0: trace_msg = ('\error treturn from socketcall %s pid:%d FD: %d exception: %d %s\n' % (socket_callname, pid, exit_info.old_fd, eax, msghdr.getString())) else: trace_msg = ('\treturn from socketcall %s pid:%d FD: %d count: %d %s' % (socket_callname, pid, exit_info.old_fd, eax, msghdr.getString())) if pid in self.trace_procs: if self.traceProcs.isExternal(pid, exit_info.old_fd): trace_msg = trace_msg +' EXTERNAL' trace_msg = trace_msg + '\n' msg_iov = msghdr.getIovec() nbytes = min(eax, 256) byte_string, byte_array = self.mem_utils.getBytes(self.cpu, nbytes, msg_iov[0].base) s = ''.join(map(chr,byte_array)) trace_msg = trace_msg+'\t'+s+'\n' if exit_info.call_params is not None and exit_info.call_params.break_simulation and self.dataWatch is not None: ''' in case we want to break on a read of this data ''' self.dataWatch.setRange(msg_iov[0].base, eax) elif socket_callname == "getpeername": ss = net.SockStruct(self.cpu, exit_info.sock_struct.addr, self.mem_utils) trace_msg = ('\treturn from socketcall GETPEERNAME pid:%d, %s eax: 0x%x\n' % (pid, ss.getString(), eax)) elif socket_callname == 'setsockopt': trace_msg = ('\treturn from socketcall SETSOCKOPT pid:%d eax: 0x%x\n' % (pid, eax)) elif socket_callname == 'getsockopt': optval_val = '' if exit_info.retval_addr != 0 and eax == 0: ''' note exit_info.count is ptr to returned count ''' count = self.mem_utils.readWord32(self.cpu, exit_info.count) rcount = min(count, 80) thebytes, dumb = self.mem_utils.getBytes(self.cpu, rcount, exit_info.retval_addr) optval_val = 'optlen: %d option: %s' % (count, thebytes) trace_msg = ('\treturn from getsockopt %s result %d\n' % (optval_val, eax)) else: #fd = self.mem_utils.readWord32(self.cpu, params) #addr = self.mem_utils.readWord32(self.cpu, params+4) #trace_msg = ('\treturn from socketcall %s pid:%d FD: %d addr:0x%x eax: 0x%x\n' % (socket_callname, pid, fd, addr, eax)) if exit_info.sock_struct is not None: trace_msg = ('\treturn from socketcall %s pid:%d FD: %d addr:0x%x eax: 0x%x\n' % (socket_callname, pid, exit_info.sock_struct.fd, exit_info.sock_struct.addr, eax)) elif socket_callname != 'socket': self.lgr.error('sharedSyscall pid:%d %s missing sock_struct' % (pid, socket_callname)) return trace_msg
def doSockets(self, exit_info, eax, pid): trace_msg = '' if exit_info.callnum == self.task_utils.syscallNumber( 'socketcall', exit_info.compat32): socket_callname = exit_info.socket_callname socket_syscall = self.top.getSyscall(self.cell_name, 'socketcall') else: socket_callname = self.task_utils.syscallName( exit_info.callnum, exit_info.compat32) socket_syscall = self.top.getSyscall(self.cell_name, socket_callname) if socket_callname == "socket" and eax >= 0: if pid in self.trace_procs: self.traceProcs.socket(pid, eax) trace_msg = ('\treturn from socketcall SOCKET pid:%d, FD: %d\n' % (pid, eax)) elif socket_callname == "connect": if eax < 0: trace_msg = ( '\texception from socketcall CONNECT pid:%d FD: %d, eax %s addr: 0x%x\n' % (pid, exit_info.sock_struct.fd, eax, exit_info.sock_struct.addr)) else: ss = exit_info.sock_struct if pid in self.trace_procs: self.traceProcs.connect(pid, ss.fd, ss.getName()) trace_msg = ( '\treturn from socketcall CONNECT pid:%d, %s addr: 0x%x\n' % (pid, ss.getString(), exit_info.sock_struct.addr)) elif socket_callname == "bind": if eax < 0: trace_msg = ('\texception from socketcall BIND eax:%d, %s\n' % (pid, eax)) else: ss = exit_info.sock_struct if pid in self.trace_procs: self.traceProcs.bind(pid, ss.fd, ss.getName()) prog_name = self.traceProcs.getProg(pid) if socket_syscall is not None: binders = socket_syscall.getBinders() if binders is not None: binders.add(pid, prog_name, ss.dottedIP(), ss.port) trace_msg = ('\treturn from socketcall BIND pid:%d, %s\n' % (pid, ss.getString())) elif socket_callname == "getsockname": ss = net.SockStruct(self.cpu, exit_info.sock_struct.addr, self.mem_utils, exit_info.sock_struct.fd) trace_msg = ('\t return from getsockname pid:%d %s\n' % (pid, ss.getString())) elif socket_callname == "accept": new_fd = eax if new_fd < 0: trace_msg = ( '\terror return from socketcall ACCEPT pid:%d, error: %d\n' % (pid, eax)) elif exit_info.sock_struct.addr != 0: in_ss = exit_info.sock_struct addr_len = self.mem_utils.readWord32(self.cpu, in_ss.length) self.lgr.debug('accept addr 0x%x len_addr 0x%x, len %d' % (in_ss.addr, in_ss.length, addr_len)) ss = net.SockStruct(self.cpu, exit_info.sock_struct.addr, self.mem_utils, fd=new_fd) if ss.sa_family == 1: if pid in self.trace_procs: self.traceProcs.accept(pid, exit_info.sock_struct.fd, new_fd, None) trace_msg = ( '\treturn from socketcall ACCEPT pid:%d, sock_fd: %d new_fd: %d sa_family: %s name: %s\n' % (pid, exit_info.sock_struct.fd, new_fd, ss.famName(), ss.getName())) elif ss.sa_family == 2: if pid in self.trace_procs: self.traceProcs.accept(pid, exit_info.sock_struct.fd, new_fd, ss.getName()) trace_msg = ( '\treturn from socketcall ACCEPT pid:%d, sock_fd: %d new_fd: %d sa_family: %s addr: %s\n' % (pid, exit_info.sock_struct.fd, new_fd, ss.famName(), ss.getName())) else: trace_msg = ( '\treturn from socketcall ACCEPT pid:%d, sock_fd: %d new_fd: %d sa_family: %s SA Family not handled addr: 0x%x\n' % (pid, exit_info.sock_struct.fd, new_fd, ss.famName(), exit_info.sock_struct.addr)) #SIM_break_simulation(trace_msg) my_syscall = exit_info.syscall_instance if exit_info.call_params is not None and ( exit_info.call_params.break_simulation or my_syscall.linger) and self.dataWatch is not None: ''' in case we want to break on a read of address data ''' self.dataWatch.setRange(in_ss.addr, addr_len, trace_msg, back_stop=False) #if my_syscall.linger: ''' TBD better way to distinguish linger from trackIO ''' if not self.dataWatch.wouldBreakSimulation(): self.dataWatch.stopWatch() #self.dataWatch.watch(break_simulation=False) self.lgr.debug( 'sharedSyscall accept call dataWatch watch') self.dataWatch.watch(break_simulation=exit_info. call_params.break_simulation) else: trace_msg = ( '\treturn from socketcall ACCEPT pid:%d, sock_fd: %d new_fd: %d NULL addr\n' % (pid, exit_info.sock_struct.fd, new_fd)) elif socket_callname == "socketpair": if exit_info.retval_addr is None: self.lgr.error('sharedSyscall socketpair got null retval addr') return 'socketpair bad retval addr?' fd1 = self.mem_utils.readWord32(self.cpu, exit_info.retval_addr) fd2 = self.mem_utils.readWord32(self.cpu, exit_info.retval_addr + 4) if pid in self.trace_procs: self.traceProcs.socketpair(pid, fd1, fd2) trace_msg = ( '\treturn from socketcall SOCKETPAIR pid:%d, fd1: %s fd2: %s\n' % (pid, str(fd1), str(fd2))) #self.lgr.debug('\treturn from socketcall SOCKETPAIR pid:%d, fd1: %d fd2: %d' % (pid, fd1, fd2)) elif socket_callname == "send" or socket_callname == "sendto" or \ socket_callname == "sendmsg": if eax >= 0: nbytes = min(eax, 256) byte_string, byte_array = self.mem_utils.getBytes( self.cpu, nbytes, exit_info.retval_addr) if byte_array is not None: s = ''.join(map(chr, byte_array)) else: s = '<< NOT MAPPED >>' trace_msg = ( '\treturn from socketcall %s pid:%d, FD: %d, count: %d from 0x%x\n%s\n' % (socket_callname, pid, exit_info.old_fd, eax, exit_info.retval_addr, s)) else: trace_msg = ( '\terror return from socketcall %s pid:%d, FD: %d, exception: %d\n' % (socket_callname, pid, exit_info.old_fd, eax)) if exit_info.call_params is not None: if syscall.DEST_PORT in exit_info.call_params.param_flags: self.lgr.debug( 'sharedSyscall sendto found dest port match.') elif type( exit_info.call_params.match_param) is str and eax > 0: self.lgr.debug( 'sharedSyscall SEND check string %s against %s' % (s, exit_info.call_params.match_param)) if exit_info.call_params.match_param not in s: ''' no match, set call_param to none ''' exit_info.call_params = None elif socket_callname == "recv" or socket_callname == "recvfrom": if eax >= 0: nbytes = min(eax, 256) byte_string, byte_array = self.mem_utils.getBytes( self.cpu, nbytes, exit_info.retval_addr) if byte_array is not None: s = ''.join(map(chr, byte_array)) else: s = '<< NOT MAPPED >>' src = '' if exit_info.fname_addr is not None: ''' obscure use of fname_addr to store source of recvfrom ''' src_ss = net.SockStruct(self.cpu, exit_info.fname_addr, self.mem_utils, fd=-1) src = 'from: %s' % src_ss.getString() trace_msg = ( '\treturn from socketcall %s pid:%d, FD: %d, len: %d count: %d into 0x%x %s\n%s\n' % (socket_callname, pid, exit_info.old_fd, exit_info.sock_struct.length, eax, exit_info.retval_addr, src, s)) my_syscall = exit_info.syscall_instance if exit_info.call_params is not None and ( exit_info.call_params.break_simulation or my_syscall.linger) and self.dataWatch is not None: ''' in case we want to break on a read of this data. NOTE: length is the given length ''' self.dataWatch.setRange( exit_info.retval_addr, exit_info.sock_struct.length, msg=trace_msg, max_len=exit_info.sock_struct.length) if exit_info.fname_addr is not None: count = self.mem_utils.readWord32( self.cpu, exit_info.count) msg = 'recvfrom source for above, addr 0x%x %d bytes' % ( exit_info.fname_addr, count) self.dataWatch.setRange(exit_info.fname_addr, count, msg) if my_syscall.linger: self.dataWatch.stopWatch() self.dataWatch.watch(break_simulation=False) else: trace_msg = ( '\terror return from socketcall %s pid:%d, FD: %d, exception: %d into 0x%x\n' % (socket_callname, pid, exit_info.old_fd, eax, exit_info.retval_addr)) elif socket_callname == "recvmsg": self.lgr.debug('doSockets recvmsg') if eax < 0: trace_msg = ( '\terror return from socketcall %s pid:%d FD: %d exception: %d \n' % (socket_callname, pid, exit_info.old_fd, eax)) exit_info.call_params = None else: msghdr = net.Msghdr(self.cpu, self.mem_utils, exit_info.retval_addr) trace_msg = ( '\treturn from socketcall %s pid:%d FD: %d count: %d %s' % (socket_callname, pid, exit_info.old_fd, eax, msghdr.getString())) if pid in self.trace_procs: if self.traceProcs.isExternal(pid, exit_info.old_fd): trace_msg = trace_msg + ' EXTERNAL' trace_msg = trace_msg + '\n' msg_iov = msghdr.getIovec() nbytes = min(eax, 256) byte_string, byte_array = self.mem_utils.getBytes( self.cpu, nbytes, msg_iov[0].base) if byte_array is not None: s = ''.join(map(chr, byte_array)) else: s = '<< NOT MAPPED >>' trace_msg = trace_msg + '\t' + s + '\n' if exit_info.call_params is not None: if exit_info.call_params.break_simulation and self.dataWatch is not None: ''' in case we want to break on a read of this data. NOTE: length is the given length ''' self.dataWatch.setRange(msg_iov[0].base, exit_info.sock_struct.length, trace_msg) self.lgr.debug('recvmsg set dataWatch') if type(exit_info.call_params.match_param) is str: self.lgr.debug( 'sharedSyscall recvmsg check string %s against %s' % (s, exit_info.call_params.match_param)) if exit_info.call_params.match_param not in s: exit_info.call_params = None else: self.lgr.error( 'sharedSyscall unhandled call_param %s' % (exit_info.call_params)) exit_info.call_params = None elif socket_callname == "getpeername": ss = net.SockStruct(self.cpu, exit_info.sock_struct.addr, self.mem_utils) trace_msg = ( '\treturn from socketcall GETPEERNAME pid:%d, %s eax: 0x%x\n' % (pid, ss.getString(), eax)) elif socket_callname == 'setsockopt': trace_msg = ( '\treturn from socketcall SETSOCKOPT pid:%d eax: 0x%x\n' % (pid, eax)) elif socket_callname == 'getsockopt': optval_val = '' if exit_info.retval_addr != 0 and eax == 0: ''' note exit_info.count is ptr to returned count ''' count = self.mem_utils.readWord32(self.cpu, exit_info.count) rcount = min(count, 80) thebytes, dumb = self.mem_utils.getBytes( self.cpu, rcount, exit_info.retval_addr) optval_val = 'optlen: %d option: %s' % (count, thebytes) trace_msg = ('\treturn from getsockopt %s result %d\n' % (optval_val, eax)) else: #fd = self.mem_utils.readWord32(self.cpu, params) #addr = self.mem_utils.readWord32(self.cpu, params+4) #trace_msg = ('\treturn from socketcall %s pid:%d FD: %d addr:0x%x eax: 0x%x\n' % (socket_callname, pid, fd, addr, eax)) if exit_info.sock_struct is not None: trace_msg = ( '\treturn from socketcall %s pid:%d FD: %d addr:0x%x eax: 0x%x\n' % (socket_callname, pid, exit_info.sock_struct.fd, exit_info.sock_struct.addr, eax)) elif socket_callname != 'socket': self.lgr.error('sharedSyscall pid:%d %s missing sock_struct' % (pid, socket_callname)) return trace_msg