Example #1
0
    def processExit(self, event):
        # Get the Fusil process agent
        fusil_process = self.getFusilProcess(event.process)

        # Create exit status
        if event.signum is not None:
            status = -event.signum
        elif event.exitcode is not None:
            status = event.exitcode
        else:
            status = ABNORMAL_STATUS

        # Display the exit status?
        if fusil_process.show_exit:
            message = str(event)
            if event.signum or (event.exitcode is None):
                # killed by a signal or abnormal exit
                log = self.error
            elif event.exitcode:
                log = self.warning
            else:
                log = self.info
            log(message)
            if event.exitcode:
                fusil_process.send('session_rename',
                                   'exitcode%s' % event.exitcode)
            elif event.signum:
                name = signalName(event.signum)
                name = name.lower()
                fusil_process.send('session_rename', name)
            fusil_process.send("process_exit", fusil_process, status)
        return status
Example #2
0
 def syscall(self, signum=0):
     message = "Break process %s at next syscall" % self.pid
     if signum:
         message += ": continue with %s" % signalName(signum)
     info(message)
     ptrace_syscall(self.pid, signum)
     self.is_stopped = False
Example #3
0
 def syscall(self, signum=0):
     message = "Break process %s at next syscall" % self.pid
     if signum:
         message += ": continue with %s" % signalName(signum)
     info(message)
     ptrace_syscall(self.pid, signum)
     self.is_stopped = False
Example #4
0
    def processExit(self, event):
        # Get the Fusil process agent
        fusil_process = self.getFusilProcess(event.process)

        # Create exit status
        if event.signum is not None:
            status = -event.signum
        elif event.exitcode is not None:
            status = event.exitcode
        else:
            status = ABNORMAL_STATUS

        # Display the exit status?
        if fusil_process.show_exit:
            message = str(event)
            if event.signum or (event.exitcode is None):
                # killed by a signal or abnormal exit
                log = self.error
            elif event.exitcode:
                log = self.warning
            else:
                log = self.info
            log(message)
            if event.exitcode:
                fusil_process.send('session_rename', 'exitcode%s' % event.exitcode)
            elif event.signum:
                name = signalName(event.signum)
                name = name.lower()
                fusil_process.send('session_rename', name)
            fusil_process.send("process_exit", fusil_process, status)
        return status
Example #5
0
    def createText(self):
        value = self.value
        argtype = self.type
        name = self.name
        if not argtype or not name:
            return formatWordHex(self.value)

        syscall = self.function.name

        # Special cases
        try:
            return SYSCALL_ARG_DICT[syscall][name][value]
        except KeyError:
            pass
        try:
            callback = ARGUMENT_CALLBACK[syscall][name]
        except KeyError:
            callback = None
        if callback:
            return callback(value)
        if syscall == "execve":
            if name in ("argv", "envp"):
                return self.readCStringArray(value)
        if syscall == "socketcall":
            if name == "call":
                try:
                    return SOCKETCALL[value][0]
                except KeyError:
                    return str(value)
            if name == "args":
                func_call = FunctionCall("socketcall", self.options)
                setupSocketCall(func_call, self.function.process,
                                self.function[0], self.value)
                text = "<%s>" % func_call.format()
                return self.formatPointer(text, self.value)
        if syscall == "write" and name == "buf":
            fd = self.function[0].value
            if fd < 3:
                length = self.function[2].value
                return self.readString(value, length)
        if name == "signum":
            return signalName(value)
        if name in FILENAME_ARGUMENTS:
            return self.readCString(value)

        # Remove "const " prefix
        if argtype.startswith("const "):
            argtype = argtype[6:]

        # Format depending on the type
        if argtype.endswith("*"):
            try:
                text = self.formatValuePointer(argtype[:-1])
                if text:
                    return text
            except PTRACE_ERRORS, err:
                writeError(getLogger(), err, "Format argument value error")
                value = None
            return formatAddress(self.value)
Example #6
0
 def cont(self, signum=0):
     if signum:
         info("Continue process %s (send signal %s)" % (
             self.pid, signalName(signum)))
     else:
         info("Continue process %s" % self.pid)
     ptrace_cont(self.pid, signum)
     self.is_stopped = False
Example #7
0
 def cont(self, signum=0):
     if signum:
         info("Continue process %s (send signal %s)" %
              (self.pid, signalName(signum)))
     else:
         info("Continue process %s" % self.pid)
     ptrace_cont(self.pid, signum)
     self.is_stopped = False
def formatProcessStatus(status, title="Process"):
    if WIFSTOPPED(status):
        signum = WSTOPSIG(status)
        return "%s stopped by signal %s" % (title, signalName(signum))

    if WIFSIGNALED(status):
        signum = WTERMSIG(status)
        return "%s killed by signal %s" % (title, signalName(signum))

    if not WIFEXITED(status):
        raise ValueError("Invalid status: %r" % status)

    exitcode = WEXITSTATUS(status)
    if exitcode:
        return "%s exited with code %s" % (title, exitcode)
    else:
        return "%s exited normally" % title
    def createText(self):
        value = self.value
        argtype = self.type
        name = self.name
        if not argtype or not name:
            return formatWordHex(self.value)

        syscall = self.function.name

        # Special cases
        try:
            return SYSCALL_ARG_DICT[syscall][name][value]
        except KeyError:
            pass
        try:
            callback = ARGUMENT_CALLBACK[syscall][name]
        except KeyError:
            callback = None
        if callback:
            return callback(value)
        if syscall == "execve":
            if name in ("argv", "envp"):
                return self.readCStringArray(value)
        if syscall == "socketcall":
            if name == "call":
                try:
                    return SOCKETCALL[value][0]
                except KeyError:
                    return str(value)
            if name == "args":
                func_call = FunctionCall("socketcall", self.options)
                setupSocketCall(func_call, self.function.process, self.function[0], self.value)
                text = "<%s>" % func_call.format()
                return self.formatPointer(text, self.value)
        if syscall == "write" and name == "buf":
            fd = self.function[0].value
            if fd < 3:
                length = self.function[2].value
                return self.readString(value, length)
        if name == "signum":
            return signalName(value)
        if name in FILENAME_ARGUMENTS:
            return self.readCString(value)

        # Remove "const " prefix
        if argtype.startswith("const "):
            argtype = argtype[6:]

        # Format depending on the type
        if argtype.endswith("*"):
            try:
                text = self.formatValuePointer(argtype[:-1])
                if text:
                    return text
            except PTRACE_ERRORS, err:
                writeError(getLogger(), err, "Format argument value error")
                value = None
            return formatAddress(self.value)
Example #10
0
def displayProcessStatus(logger, status, prefix="Process"):
    if status == 0:
        logger.info("%s exited normally" % prefix)
    elif status < 0:
        signum = -status
        logger.error("%s killed by signal %s" %
            (prefix, signalName(signum)))
    else:
        logger.warning("%s exited with error code: %s" % (prefix, status))
Example #11
0
def formatCloneFlags(flags):
    bits = readBits(flags, CLONE_FLAGS_BITMASK)
    signum = flags & 0xFF
    if signum:
        bits.insert(0, signalName(signum))
    if bits:
        bits = "%s" % ("|".join(bits))
        return "<%s> (%s)" % (bits, str(flags))
    else:
        return str(flags)
Example #12
0
def formatCloneFlags(argument):
    flags = argument.value
    bits = readBits(flags, CLONE_FLAGS_BITMASK)
    signum = flags & 0xFF
    if signum:
        bits.insert(0, signalName(signum))
    if bits:
        bits = "%s" % ("|".join(bits))
        return "<%s> (%s)" % (bits, str(flags))
    else:
        return str(flags)
Example #13
0
 def renameSession(self, status):
     if status < 0:
         signum = -status
         name = signalName(signum)
         name = name.lower()
     elif 0 < status:
         name = "exitcode%s" % status
     else:
         # nul exitcode: don't rename the session
         return
     self.send('session_rename', name)
Example #14
0
    def _continueProcess(self, process, signum=None):
        if not signum and process in self.last_signal:
            signum = self.last_signal[process]

        if signum:
            error("Send %s to %s" % (signalName(signum), process))
            process.cont(signum)
            try:
                del self.last_signal[process]
            except KeyError:
                pass
        else:
            process.cont()
Example #15
0
def formatProcessStatus(status, title="Process"):
    """
    Format a process status (integer) as a string.
    """
    if WIFSTOPPED(status):
        signum = WSTOPSIG(status)
        text = "%s stopped by signal %s" % (title, signalName(signum))
    elif WIFSIGNALED(status):
        signum = WTERMSIG(status)
        text = "%s killed by signal %s" % (title, signalName(signum))
    else:
        if not WIFEXITED(status):
            raise ValueError("Invalid status: %r" % status)

        exitcode = WEXITSTATUS(status)
        if exitcode:
            text = "%s exited with code %s" % (title, exitcode)
        else:
            text = "%s exited normally" % title
    if WCOREDUMP(status):
        text += " (core dumped)"
    return text
Example #16
0
    def _continueProcess(self, process, signum=None):
        if not signum and process in self.last_signal:
            signum = self.last_signal[process]

        if signum:
            error("Send %s to %s" % (signalName(signum), process))
            process.cont(signum)
            try:
                del self.last_signal[process]
            except KeyError:
                pass
        else:
            process.cont()
Example #17
0
def runCommand(logger, command, stdin=False, stdout=True, options=None):
    """
    Run specified command:
     - logger is an object with a info() method
     - command: a string or a list of strings (eg. 'uname' or ['gcc', 'printf.c'])
     - stdin: if value is False, use null device as stdin (default: no stdin)
     - stdout: if value is False, use null device as stdout and stderr
       (default: keep stdout)

    Raise RuntimeError on failure: if the exit code is not nul
    or if the process is killed by a signal.
    """
    if isinstance(command, (str, unicode)):
        command_str = repr(command)
    else:
        command_str = ' '.join(command)
        command_str = repr(command_str)
    logger.info("Run the command: %s" % command_str)
    if not options:
        options = {}
    if not stdin:
        stdin_file =  open(devnull, 'r')
        options['stdin'] = stdin_file
    else:
        stdin_file = None
    stdout_file = None
    if not stdout:
        stdout_file = open(devnull, 'wb')
        options['stdout'] = stdout_file
        options['stderr'] = STDOUT
    elif stdout is not True:
        options['stdout'] = stdout
        options['stderr'] = STDOUT
    if ('close_fds' not in options) \
    and (not RUNNING_WINDOWS):
        options['close_fds'] = True

    process = Popen(command, **options)
    status = process.wait()
    if stdin_file:
        stdin_file.close()
    if stdout_file:
        stdout_file.close()
    if not status:
        return
    if status < 0:
        errmsg = 'process killed by signal %s' % signalName(-status)
    else:
        errmsg = 'exit code %s' % status
    raise RuntimeError("Unable to run the command %s: %s" % (
        command_str, errmsg))
Example #18
0
def formatProcessStatus(status, title="Process"):
    """
    Format a process status (integer) as a string.
    """
    if RUNNING_WINDOWS:
        raise NotImplementedError()
    if WIFSTOPPED(status):
        signum = WSTOPSIG(status)
        text = "%s stopped by signal %s" % (title, signalName(signum))
    elif WIFSIGNALED(status):
        signum = WTERMSIG(status)
        text = "%s killed by signal %s" % (title, signalName(signum))
    else:
        if not WIFEXITED(status):
            raise ValueError("Invalid status: %r" % status)

        exitcode = WEXITSTATUS(status)
        if exitcode:
            text = "%s exited with code %s" % (title, exitcode)
        else:
            text = "%s exited normally" % title
    if WCOREDUMP(status):
        text += " (core dumped)"
    return text
Example #19
0
 def __init__(self, process, signum=None, exitcode=None):
     pid = process.pid
     if signum:
         message = "Process %s killed by signal %s" % (
             pid, signalName(signum))
     elif exitcode is not None:
         if not exitcode:
             message = "Process %s exited normally" % pid
         else:
             message = "Process %s exited with code %s" % (pid, exitcode)
     else:
         message = "Process %s terminated abnormally" % pid
     ProcessEvent.__init__(self, process, message)
     self.signum = signum
     self.exitcode = exitcode
 def __init__(self, process, signum=None, exitcode=None):
     pid = process.pid
     if signum:
         message = "Process %s killed by signal %s" % (
             pid, signalName(signum))
     elif exitcode is not None:
         if not exitcode:
             message = "Process %s exited normally" % pid
         else:
             message = "Process %s exited with code %s" % (pid, exitcode)
     else:
         message = "Process %s terminated abnormally" % pid
     ProcessEvent.__init__(self, process, message)
     self.signum = signum
     self.exitcode = exitcode
Example #21
0
    def waitSignals(self, *signals, **kw):
        """
        No signal means "any signal"
        """
        pid = kw.get('pid', None)

        message = "Wait "
        if pid:
            message += "process %s for " % pid
        if signals:
            message += "signals (%s)" % ", ".join(
                signalName(signum)
                for signum in signals)
        else:
            message += "any signal"
        info(message)
        while True:
            event = self._wait(pid)
            if event.__class__ != ProcessSignal:
                raise event
            signum = event.signum
            if signum in signals or not signals:
                return event
            raise event
Example #22
0
 def processSignal(self, signum):
     debug("%s received signal %s" % (self, signalName(signum)))
     self.is_stopped = True
     return ProcessSignal(signum, self)
Example #23
0
 def kill(self, signum):
     debug("Send %s to %s" % (signalName(signum), self))
     kill(self.pid, signum)
Example #24
0
 def processKilled(self, signum):
     debug("%s killed by signal %s" % (self, signalName(signum)))
     self._notRunning()
     return ProcessExit(self, signum=signum)
Example #25
0
 def processKilled(self, signum):
     debug("%s killed by signal %s" % (self, signalName(signum)))
     self._notRunning()
     return ProcessExit(self, signum=signum)
    def createText(self):
        value = self.value
        argtype = self.type
        name = self.name
        if not argtype or not name:
            return formatWordHex(self.value)

        syscall = self.function.name

        # Special cases
        try:
            return SYSCALL_ARG_DICT[syscall][name][value]
        except KeyError:
            pass
        try:
            callback = ARGUMENT_CALLBACK[syscall][name]
        except KeyError:
            callback = None
        if callback:
            return callback(self)
        if syscall == "execve":
            if name in ("argv", "envp"):
                return self.readCStringArray(value)
        if syscall == "socketcall":
            if name == "call":
                try:
                    return SOCKETCALL[value]
                except KeyError:
                    return str(value)
            if name == "args":
                func_call = FunctionCall("socketcall", self.options)
                setupSocketCall(func_call, self.function.process, self.function[0], self.value)
                text = "<%s>" % func_call.format()
                return self.formatPointer(text, self.value)
        if syscall == "write" and name == "buf":
            fd = self.function[0].value
            if fd < 3:
                length = self.function[2].value
                return self.readString(value, length)
        if name == "signum":
            return signalName(value)
        if name in DIRFD_ARGUMENTS and argtype == "int":
            return formatDirFd(uint2int(value))

        # Remove "const " prefix
        if argtype.startswith("const "):
            argtype = argtype[6:]

        if name in FILENAME_ARGUMENTS and argtype == "char *":
            return self.readCString(value)

        # Format depending on the type
        if argtype.endswith("*"):
            try:
                text = self.formatValuePointer(argtype[:-1])
                if text:
                    return text
            except PTRACE_ERRORS as err:
                writeError(getLogger(), err, "Warning: Format %r value error" % self, log_level=INFO)
            return formatAddress(self.value)

        # Array like "int[2]"
        match = re.match("(.*)\[([0-9])+\]", argtype)
        if match:
            basetype = match.group(1)
            count = int(match.group(2))
            if basetype == "int":
                return self.readArray(self.value, c_int, count)

        # Simple types
        if argtype in ("unsigned int", "unsigned long", "u32"):
            return str(self.value)
        if argtype in INTEGER_TYPES:
            return str(uint2int(self.value))

        # Default formatter: hexadecimal
        return formatWordHex(self.value)
    def createText(self):
        value = self.value
        argtype = self.type
        name = self.name
        if not argtype or not name:
            return formatWordHex(self.value)

        syscall = self.function.name

        # Special cases
        try:
            return SYSCALL_ARG_DICT[syscall][name][value]
        except KeyError:
            pass
        try:
            callback = ARGUMENT_CALLBACK[syscall][name]
        except KeyError:
            callback = None
        if callback:
            return callback(self)
        if syscall == "execve":
            if name in ("argv", "envp"):
                return self.readCStringArray(value)
        if syscall == "socketcall":
            if name == "call":
                try:
                    return SOCKETCALL[value]
                except KeyError:
                    return str(value)
            if name == "args":
                func_call = FunctionCall("socketcall", self.options)
                setupSocketCall(func_call, self.function.process,
                                self.function[0], self.value)
                text = "<%s>" % func_call.format()
                return self.formatPointer(text, self.value)
        if syscall == "write" and name == "buf":
            fd = self.function[0].value
            if fd < 3:
                length = self.function[2].value
                return self.readString(value, length)
        if name == "signum":
            return signalName(value)
        if name in DIRFD_ARGUMENTS and argtype == "int":
            return formatDirFd(uint2int(value))

        # Remove "const " prefix
        if argtype.startswith("const "):
            argtype = argtype[6:]

        if name in FILENAME_ARGUMENTS and argtype == "char *":
            return self.readCString(value)

        # Format depending on the type
        if argtype.endswith("*"):
            try:
                text = self.formatValuePointer(argtype[:-1])
                if text:
                    return text
            except PTRACE_ERRORS as err:
                writeError(getLogger(),
                           err,
                           "Warning: Format %r value error" % self,
                           log_level=INFO)
            return formatAddress(self.value)

        # Array like "int[2]"
        match = re.match("(.*)\[([0-9])+\]", argtype)
        if match:
            basetype = match.group(1)
            count = int(match.group(2))
            if basetype == "int":
                return self.readArray(self.value, c_int, count)

        # Simple types
        if argtype in ("unsigned int", "unsigned long", "u32"):
            return str(self.value)
        if argtype in INTEGER_TYPES:
            return str(uint2int(self.value))

        # Default formatter: hexadecimal
        return formatWordHex(self.value)
 def formatter(key):
     key += 1
     return signalName(key)
Example #29
0
 def processSignal(self, signum):
     debug("%s received signal %s" % (self, signalName(signum)))
     self.is_stopped = True
     return ProcessSignal(signum, self)
Example #30
0
 def kill(self, signum):
     debug("Send %s to %s" % (signalName(signum), self))
     kill(self.pid, signum)
Example #31
0
 def formatter(key):
     key += 1
     return signalName(key)