Shofel2_T124_python/venv/lib/python3.10/site-packages/pyhidra/gui.py

145 lines
4.3 KiB
Python

import argparse
import io
import os
from pathlib import Path
import platform
import sys
import traceback
from typing import NoReturn
import warnings
import pyhidra
class _GuiOutput(io.StringIO):
def __init__(self, title: str, *args, **kwargs):
super().__init__(*args, **kwargs)
self.title = title
def close(self):
import tkinter.messagebox
tkinter.messagebox.showinfo(self.title, self.getvalue())
super().close()
class _GuiArgumentParser(argparse.ArgumentParser):
def exit(self, status=0, *_):
sys.exit(status)
def print_usage(self, file=None):
if file is None:
file = _GuiOutput("Usage")
self._print_message(self.format_usage(), file)
def print_help(self, file=None):
if file is None:
file = _GuiOutput("Help")
self._print_message(self.format_help(), file)
def _gui_mac() -> NoReturn:
args = _parse_args()
install_dir = args.install_dir
path = Path(sys.base_exec_prefix) / "Resources/Python.app/Contents/MacOS/Python"
if path.exists():
# the python launcher app will correctly start the venv if sys.executable is in a venv
argv = [sys.executable, "-m", "pyhidra", "-g"]
if install_dir is not None:
argv += ["--install-dir", str(install_dir)]
actions = ((os.POSIX_SPAWN_CLOSE, 0), (os.POSIX_SPAWN_CLOSE, 1), (os.POSIX_SPAWN_CLOSE, 2))
os.posix_spawn(str(path), argv, os.environ, file_actions=actions)
else:
print("could not find the Python.app path, launch failed")
sys.exit(0)
def _parse_args():
parser = _GuiArgumentParser(prog="pyhidraw")
parser.add_argument(
"--install-dir",
type=Path,
default=None,
dest="install_dir",
metavar="",
help="Path to Ghidra installation. "\
"(defaults to the GHIDRA_INSTALL_DIR environment variable)"
)
return parser.parse_args()
def _gui_default(install_dir: Path):
pid = os.fork()
if pid != 0:
# original process can exit
return
fd = os.open(os.devnull, os.O_RDWR)
# redirect stdin, stdout and stderr to /dev/null so the jvm can't use the terminal
# this also prevents errors from attempting to write to a closed sys.stdout #21
os.dup2(fd, sys.stdin.fileno(), inheritable=False)
os.dup2(fd, sys.stdout.fileno(), inheritable=False)
os.dup2(fd, sys.stderr.fileno(), inheritable=False)
# run the application
gui(install_dir)
def _gui():
# this is the entry from the gui script
# there may or may not be an attached terminal
# depending on the current operating system
if platform.system() == "Darwin":
_gui_mac()
# This check handles the edge case of having a corrupt Python installation
# where tkinter can't be imported. Since there may not be an attached
# terminal, the problem still needs to be reported somehow.
try:
import tkinter.messagebox as _
except ImportError as e:
if platform.system() == "Windows":
# there is no console/terminal to report the error
import ctypes
MessageBox = ctypes.windll.user32.MessageBoxW
MessageBox(None, str(e), "Import Error", 0)
sys.exit(1)
# report this before detaching from the console or no
# errors will be reported if they occur
raise
try:
args = _parse_args()
install_dir = args.install_dir
except Exception as e:
import tkinter.messagebox
msg = "".join(traceback.format_exception(type(e), value=e, tb=e.__traceback__))
tkinter.messagebox.showerror(type(e), msg)
sys.exit(1)
if platform.system() == 'Windows':
# gui_script works like it is supposed to on windows
gui(install_dir)
else:
_gui_default(install_dir)
def gui(install_dir: Path = None):
"""
Starts the Ghidra GUI
:param install_dir: The path to the Ghidra installation directory.
(Defaults to the GHIDRA_INSTALL_DIR environment variable)
"""
pyhidra.GuiPyhidraLauncher(install_dir=install_dir).start()
def get_current_interpreter():
warnings.warn(
"get_current_interpreter has been moved. Please use pyhidra.get_current_interpreter",
DeprecationWarning
)
return pyhidra.get_current_interpreter()