예제 #1
0
    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
예제 #2
0
    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