Repository: mandiant/capa
File: capa/main.py (Python)

Code before:
            sigs_path = Path(args.signatures)
            logger.debug("using signatures path: %s", sigs_path)

        args.signatures = sigs_path


def last_resort_exception_handler(args, exctype=None, value=None, traceback=None):
    """
    custom exception handler to replace the default sys.excepthook,
    prints traceback in debug mode, otherwise prints helpful message

    using "nonlocal" keyword and closure code construct enables
    last_resort_exception_handler args to first be initialized and
    then be updated if the function needs to handle an exception

    args:
      args (argparse.Namespace): parsed command-line arguments
      exctype (Exception): exception class
      value (str): exception instance
      traceback (TracebackType): a traceback object
    """

    def handle_exception_information(args):
        try:
            nonlocal exctype, value, traceback
            if "-d" or "--debug" in args:
                return sys.__excepthook__(exctype, value, traceback)
            else:
                print(
                    f"Unexpected exception raised: {exctype}. Please run capa in debug mode (-d/--debug) "
                    + "to see the stack trace. Please also report your issue on the capa GitHub page so we "
                    + "can improve the code! (https://github.com/mandiant/capa/issues)"
                )

        except Exception as e:  # pylint: disable=broad-except
            logger.error("%s", str(e))
            return  # should this return an object like some other capa try-except statements, e.g., E_CORRUPT_FILE or E_INVALID_FILE_TYPE?

    return handle_exception_information


def main(argv: Optional[List[str]] = None):
    if sys.version_info < (3, 8):
        raise UnsupportedRuntimeError("This version of capa can only be used with Python 3.8+")

    if argv is None:
        argv = sys.argv[1:]

    desc = "The FLARE team's open-source tool to identify capabilities in executable files."
    epilog = textwrap.dedent(
        """

Review comment (bug):
is args parsed at this point, so can we do `args.debug`?

Code after:
        else:
            sigs_path = Path(args.signatures)
            logger.debug("using signatures path: %s", sigs_path)

        args.signatures = sigs_path


def simple_message_exception_handler(exctype, value: BaseException, traceback: TracebackType):
    """
    prints friendly message on unexpected exceptions to regular users (debug mode shows regular stack trace)

    args:
      # TODO(aaronatp): Once capa drops support for Python 3.8, move the exctype type annotation to
      # the function parameters and remove the "# type: ignore[assignment]" from the relevant place
      # in the main function, see (https://github.com/mandiant/capa/issues/1896)
      exctype (type[BaseException]): exception class
    """

    if exctype is KeyboardInterrupt:
        print("KeyboardInterrupt detected, program terminated")
    else:
        print(
            f"Unexpected exception raised: {exctype}. Please run capa in debug mode (-d/--debug) "
            + "to see the stack trace. Please also report your issue on the capa GitHub page so we "
            + "can improve the code! (https://github.com/mandiant/capa/issues)"
        )


def main(argv: Optional[List[str]] = None):
    if sys.version_info < (3, 8):
        raise UnsupportedRuntimeError("This version of capa can only be used with Python 3.8+")

    if argv is None:
        argv = sys.argv[1:]

    desc = "The FLARE team's open-source tool to identify capabilities in executable files."
    epilog = textwrap.dedent(
        """
        By default, capa uses a default set of embedded rules.
        You can see the rule set here:
          https://github.com/mandiant/capa-rules

        To provide your own rule set, use the `-r` flag:
          capa  --rules /path/to/rules  suspicious.exe
          capa  -r      /path/to/rules  suspicious.exe

        examples:
          identify capabilities in a binary
            capa suspicious.exe

          identify capabilities in 32-bit shellcode, see `-f` for all supported formats