Beispiel #1
0
 def callafter(self, pid, call, result, state):
     if call == 'rt_sigaction' or call == 'sigaction' or call == 'signal':
         if state != None and not (-1024 < result < 0):
             sig = state[0]
             f = self.allflags[pid]
             handler = state[1]
             if sig == signal.SIGCHLD:
                 sa_flags = ptrace.peekdata(pid, handler + 4)
                 f['SA_NOCLDSTOP'] = sa_flags & 0x1 # SA_NOCLDSTOP
             else:
                 if call != 'signal':
                     handler = ptrace.peekdata(pid, handler)
                 f[signalmap.lookup_name(sig)] = handler
     elif call == 'wait4' or call == 'waitpid':
         f = self.allflags[pid]
         if f.has_key('waitresult'):
             wpid, statusptr, status = f['waitresult']
             del f['waitresult']
             del f['waiting']
             if statusptr != 0:
                 try:
                     ptrace.pokedata(pid, statusptr, status)
                 except OSError, e:
                     if e.errno != errno.ESRCH:
                         # FIX
                         assert 0, "wait status pointer bad? (%s)" % e
                     else:
                         print 'waiter dead or not stopped' # XXX
             return wpid
         # XXX: is this actually correct and useful?
         if result == -errno_internal.ERESTARTNOHAND: # like pause
             return -errno_internal.ERESTARTSYS # like wait
Beispiel #2
0
    def poke(self, address, data, fortrick=None):
        if fortrick:
            self.save.insert(0, (fortrick, address, self.peek(address, len(data))))
            # XXX: could check whether poke is a noop here

        # This fails since write access to mem has been disabled in 2.4 kernels
        # _memseek(self.m, address)
        # r = os.write(self.m, data)
        # assert r == len(data)           # FIX

        # a better implementation may be possible here
        if len(data) > 0:
            address1 = address + len(data)
            pa0 = address / 4 * 4
            pa1 = (address1 - 1) / 4 * 4 + 4
            for pa in xrange(pa0, pa1, 4):
                a = pa - address
                if address <= pa and pa + 4 <= address1:
                    s = data[a : a + 4]
                else:
                    s = list(self.peek(pa, 4))
                    for i in xrange(4):
                        if address <= pa + i < address1:
                            s[i] = data[a + i]
                    s = string.join(s, "")
                ptrace.pokedata(self.pid, pa, struct.unpack("=l", s)[0])
Beispiel #3
0
    def poke(self, address, data, fortrick=None):
        if fortrick:
            self.save.insert(0, (fortrick, address,
                                 self.peek(address, len(data))))
            # XXX: could check whether poke is a noop here

        # This fails since write access to mem has been disabled in 2.4 kernels
        # _memseek(self.m, address)
        #r = os.write(self.m, data)
        #assert r == len(data)           # FIX

        # a better implementation may be possible here
        if len(data) > 0:
            address1 = address + len(data)
            pa0 = address / 4 * 4
            pa1 = (address1 - 1) / 4 * 4 + 4
            for pa in xrange(pa0, pa1, 4):
                a = pa - address
                if address <= pa and pa + 4 <= address1:
                    s = data[a:a+4]
                else:
                    s = list(self.peek(pa, 4))
                    for i in xrange(4):
                        if address <= pa + i < address1:
                            s[i] = data[a+i]
                    s = string.join(s, '')
                ptrace.pokedata(self.pid, pa, struct.unpack('=l', s)[0])
Beispiel #4
0
 def _callbefore_wait(self, pid, args, flags):
     r = self.do_wait(pid, args, flags)
     wpid = r[1]
     if wpid and wpid > 0:
         statuspair = r[0]
         statusptr, status = statuspair
         if statusptr:
             try:
                 ptrace.pokedata(pid, statusptr, status)
             except OSError, e:
                 if e.errno != errno.ESRCH:
                     # FIX
                     assert 0, "wait status pointer bad? (%s)" % e
                 else:
                     print 'waiter dead or not stopped' # XXX
Beispiel #5
0
 def callafter(self, pid, call, result, state):
     now = time.time()
     delta_t = now - self.start_t
     now_w = self.start_t + delta_t * self.w + self.delta
     if call == 'time':
         now_wi = int(now_w)
         if state:
             # FIX: might throw exception
             ptrace.pokedata(pid, state, now_wi)
         return now_wi
     elif call == 'gettimeofday' and result != -1:
         _put_timeval(pid, state, now_w)
     elif call == 'select' and result != -1 and state:
         _warp_timeval(pid, 1.0 / self.w, state)
     elif call == 'nanosleep':
         oldtimeval, args = state
         if args[1]:
             _warp_timeval(pid, 1.0 / self.w, args[1], 1000)
             # save and restore it so it doesn't get stepped on
             remaining = _get_timeval_2(pid, args[1])
         _put_timeval_2(pid, args[0], oldtimeval)  # here
         if args[1]:
             _put_timeval_2(pid, args[1], remaining)
 def callafter(self, pid, call, result, state):
     now = time.time()
     delta_t = now - self.start_t
     now_w = self.start_t + delta_t * self.w + self.delta
     if call == 'time':
         now_wi = int(now_w)
         if state:
             # FIX: might throw exception
             ptrace.pokedata(pid, state, now_wi)
         return now_wi
     elif call == 'gettimeofday' and result != -1:
         _put_timeval(pid, state, now_w)
     elif call == 'select' and result != -1 and state:
         _warp_timeval(pid, 1.0 / self.w, state)
     elif call == 'nanosleep':
         oldtimeval, args = state
         if args[1]:
             _warp_timeval(pid, 1.0 / self.w, args[1], 1000)
             # save and restore it so it doesn't get stepped on
             remaining = _get_timeval_2(pid, args[1])
         _put_timeval_2(pid, args[0], oldtimeval) # here
         if args[1]:
             _put_timeval_2(pid, args[1], remaining)
Beispiel #7
0
    def poke(self, addr, data):
	self.attach()
	ptrace.pokedata(self.pid, addr, data)
	self.detach()
Beispiel #8
0
    def callbefore(self, pid, call, args):
        #		print pid, call, args
        def doreadwrite(callt, args):
            #			print 'doreadwrite',call,callt,args,
            fd = args[0]
            pfd = pid, fd
            fdinfo = self.__do_fail.get(pfd, None)
            #			if fdinfo:
            #				print fdinfo
            if fdinfo and callt in fdinfo.modes:
                if callt == 'r':
                    #after = self.afterr
                    if not fdinfo.rerrs:
                        return
                    after = min([err.after for err in fdinfo.rerrs])
                    failinfo = fdinfo.r
                else:
                    #after = self.afterw
                    if not fdinfo.werrs:
                        return
                    after = min([err.after for err in fdinfo.werrs])
                    failinfo = fdinfo.w
                failcount, bytes = failinfo.failed, failinfo.bytes

                if failcount > 5:
                    print 'exiting on %ith failed %s of %i' % (failcount,
                                                               callt, pfd)
                    import sys
                    sys.exit(1)

                if bytes < after:
                    size = args[2]
                    if bytes + size > after:
                        size = after - bytes
                    print pfd, callt, (fd, args[1], size), 'was', args
                    return (pfd, None, None, (fd, args[1], size))

                failinfo.failed += 1
                print pid, 'failing', call, callt, '#%i' % failcount, 'for fd', fd
                return (pfd, -errno.EIO, None, None)
#			else:
#				print 'allowing',call,'for',args[0]

        if call == 'read':
            return doreadwrite('r', args)
        elif call == 'write':
            return doreadwrite('w', args)
        elif call == 'close':
            fd = args[0]
            pfd = pid, fd
            fdinfo = self.__do_fail.get(pfd, None)
            #			print pfd, call, args, fdinfo
            if fdinfo and fdinfo.cerrs:
                return (pfd, -errno.EIO, None, None)
            return (pfd, None, None, None)

        elif call == 'dup' or call == 'dup2':
            return (args[0], None, None, None)
        elif call == 'open':
            getarg = Memory.getMemory(pid).get_string
            fn = getarg(args[0])
            #			print pid,call,[fn]+args[1:],args[1]&O_ACCMODE
            fes = []
            m = ''
            flags = args[1] & O_ACCMODE
            for fe in self.ferrs:
                if (flags == os.O_RDWR
                        or (flags == os.O_WRONLY and 'w' in fe.modes)
                        or (flags == os.O_RDONLY and 'r' in fe.modes)):
                    if fe.match.search(fn):
                        fes.append(fe)
            if fes:
                fdinfo = FDInfo(fes)
                #if flags == FCNTL.O_WRONLY:
                #	after = min([err.after for err in fdinfo.werrs])
                #elif flags == FCNTL.O_RDONLY:
                #	after = min([err.after for err in fdinfo.rerrs])
                #else: #elif flags == FCNTL.O_RDWR:
                after = min([err.after for err in fdinfo.errs])
                if after < 0:
                    print pid, 'failing', call, [fn] + args[1:]
                    return (None, -errno.EIO, None, None)
                return (fdinfo, None, None, None)

        elif call == 'socketcall':
            #			print pid, call, args
            subcall = args[0]
            do = 0
            if subcall == 1:  # socket
                # FIX: might fail
                if ptrace.peekdata(pid, args[1]) in (socket.AF_INET,
                                                     socket.AF_INET6):
                    do = -2
            elif subcall == 3:  # connect
                do = -1
            elif subcall == 4:  # listen
                do = -1
            elif subcall == 5:  # accept
                do = -1
            elif subcall in (9, 10):  # send/recv
                if subcall == 9:  # send
                    r = doreadwrite('w', (ptrace.peekdata(
                        pid, args[1]), ptrace.peekdata(pid, args[1] + 4),
                                          ptrace.peekdata(pid, args[1] + 8)))
                    subcalln = 'write'
                elif subcall == 10:  # recv
                    r = doreadwrite('r', (ptrace.peekdata(
                        pid, args[1]), ptrace.peekdata(pid, args[1] + 4),
                                          ptrace.peekdata(pid, args[1] + 8)))
                    subcalln = 'read'
                if not r or r[
                        1]:  # if default return or error, we can return it with no probs.
                    return r
                #otherwise we have to convert from doreadwrite return which is in read()/write() format to socketcall format
                ptrace.pokedata(args[1] + 8,
                                r[3][2])  # set new recv/write size
                return ((subcalln, r[0]), r[1], r[2], args)

            if do:
                #ses = []
                #for se in self.serrs:
                after = min([err.after for err in self.serrs])
                if after == do:
                    print pid, 'failing', call, args
                    return (None, -errno.EIO, None, None)
                errs = [err for err in self.serrs if err.after >= 0]
                if errs:
                    fdinfo = FDInfo(errs)
                    return (('open', fdinfo), None, None, None)

        elif call == 'rename':
            getarg = Memory.getMemory(pid).get_string
            sfn = getarg(args[0])
            dfn = getarg(args[1])
            #			print pid,call,sfn,dfn
            for rene in self.renameerrs:
                if rene.srcmatch.search(sfn) and rene.dstmatch.search(dfn):
                    print pid, 'failing', call, sfn, dfn
                    return (None, -errno.EIO, None, None)
Beispiel #9
0
def _put_timeval_2(pid, addr, pair):
    ptrace.pokedata(pid, addr, pair[0])
    ptrace.pokedata(pid, addr + 4, pair[1])
def _put_timeval_2(pid, addr, pair):
    ptrace.pokedata(pid, addr, pair[0])
    ptrace.pokedata(pid, addr + 4, pair[1])
Beispiel #11
0
 def poke(self, addr, data):
     self.attach()
     ptrace.pokedata(self.pid, addr, data)
     self.detach()