Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Minor improvements to main_window #1299

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 36 additions & 60 deletions angrmanagement/ui/main_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,12 @@
from angrmanagement.config import IMG_LOCATION, Conf, save_config
from angrmanagement.daemon import daemon_conn, daemon_exists, run_daemon_process
from angrmanagement.daemon.client import ClientService
from angrmanagement.data.jobs import DependencyAnalysisJob
from angrmanagement.data.jobs.loading import LoadAngrDBJob, LoadBinaryJob, LoadTargetJob
from angrmanagement.data.library_docs import LibraryDocs
from angrmanagement.errors import InvalidURLError, UnexpectedStatusCodeError
from angrmanagement.logic import GlobalInfo
from angrmanagement.logic.commands import BasicCommand
from angrmanagement.logic.threads import ExecuteCodeEvent
from angrmanagement.ui.views import DisassemblyView
from angrmanagement.utils.env import app_root, is_pyinstaller
from angrmanagement.utils.io import download_url, isurl

Expand Down Expand Up @@ -141,6 +139,30 @@ class MainWindow(QMainWindow):
The main window of angr management.
"""

initialized: bool
app: QApplication | None
workspace: Workspace
dock_manager: QtAds.CDockManager
toolbar_manager: ToolbarManager

# Status and Progress
_progress_stopwatch_start_time: float
_progress_message: str
_progress_percentage: float
_progress_update_timer: QTimer
_status_label: QLabel
_stopwatch_label: QIconLabel
_interrupt_job_button: QIconLabel
_progress_label: QLabel
_progress_bar: QProgressBar
_progress_dialog: QProgressDialog

_file_menu: FileMenu
_analyze_menu: AnalyzeMenu
_view_menu: ViewMenu
_help_menu: HelpMenu
_plugin_menu: PluginMenu

def __init__(
self, app: QApplication | None = None, parent=None, show: bool = True, use_daemon: bool = False
) -> None:
Expand All @@ -157,41 +179,31 @@ def __init__(
# initialization
self.setMinimumSize(QSize(400, 400))

self.app: QApplication | None = app
self.workspace: Workspace = None
self.dock_manager: QtAds.CDockManager
self.app = app
self._dock_shortcut_event_filter = DockShortcutEventFilter(self)

self._shift_shift_event_filter = ShiftShiftEventFilter(self)
if app:
if self.app is not None:
self.app.installEventFilter(self._shift_shift_event_filter)

self.toolbar_manager: ToolbarManager = ToolbarManager(self)
self.toolbar_manager = ToolbarManager(self)

self._progress_stopwatch_start_time: float = 0.0
self._progress_message: str = ""
self._progress_percentage: float = 0
self._progress_update_timer: QTimer = QTimer()
self._progress_stopwatch_start_time = 0.0
self._progress_message = ""
self._progress_percentage = 0
self._progress_update_timer = QTimer()
self._progress_update_timer.setSingleShot(False)
self._progress_update_timer.setInterval(1000)
self._progress_update_timer.timeout.connect(self._on_progress_update_timer_timeout)

self.defaultWindowFlags = None

# menus
self._file_menu = None # FileMenu
self._analyze_menu = None
self._view_menu = None
self._help_menu = None
self._plugin_menu = None

self._init_statusbar()
self._init_workspace()
self._init_statusbar()
self._init_toolbars()
self._init_menus()
self._init_plugins()
self.workspace.plugins.discover_and_initialize_plugins()
self._init_library_docs()
# self._init_url_scheme_handler()

self._register_commands()

Expand Down Expand Up @@ -423,13 +435,6 @@ def init_shortcuts_on_dock(self, dock_widget) -> None:
"""
dock_widget.installEventFilter(self._dock_shortcut_event_filter)

#
# Plugins
#

def _init_plugins(self) -> None:
self.workspace.plugins.discover_and_initialize_plugins()

#
# FLIRT Signatures
#
Expand Down Expand Up @@ -544,9 +549,9 @@ def _register_commands(self) -> None:
[
BasicCommand(action.__name__, caption, action)
for caption, action in [
("Analyze: Decompile", self.decompile_current_function),
("Analyze: Interact", self.interact),
("Analyze: Run Analysis...", self.run_analysis),
("Analyze: Decompile", self.workspace.decompile_current_function),
("Analyze: Interact", self.workspace.interact_program),
("Analyze: Run Analysis...", self.workspace.run_analysis),
("File: Exit", self.quit),
("File: Load a new binary...", self.open_file_button),
("File: Load a new docker target...", self.open_docker_button),
Expand Down Expand Up @@ -848,35 +853,6 @@ def preferences(self) -> None:
def quit(self) -> None:
self.close()

def run_variable_recovery(self) -> None:
self.workspace._get_or_create_view("disassembly", DisassemblyView).variable_recovery_flavor = "accurate"

def run_induction_variable_analysis(self) -> None:
self.workspace._get_or_create_view("disassembly", DisassemblyView).run_induction_variable_analysis()

def run_dependency_analysis(self, func_addr: int | None = None, func_arg_idx: int | None = None) -> None:
if self.workspace is None or self.workspace.main_instance is None:
return
dep_analysis_job = DependencyAnalysisJob(
self.workspace.main_instance, func_addr=func_addr, func_arg_idx=func_arg_idx
)
self.workspace.job_manager.add_job(dep_analysis_job)

def run_analysis(self) -> None:
if self.workspace:
self.workspace.run_analysis()

def decompile_current_function(self) -> None:
if self.workspace is not None:
self.workspace.decompile_current_function()

def view_proximity_for_current_function(self) -> None:
if self.workspace is not None:
self.workspace.view_proximity_for_current_function()

def interact(self) -> None:
self.workspace.interact_program(self.workspace.main_instance.img_name)

def show_command_palette(self, parent=None) -> None:
dlg = CommandPaletteDialog(self.workspace, parent=(parent or self))
dlg.setModal(True)
Expand Down
8 changes: 4 additions & 4 deletions angrmanagement/ui/menus/analyze_menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,22 @@ def __init__(self, main_window: MainWindow) -> None:
[
MenuEntry(
"&Run Analysis...",
main_window.run_analysis,
main_window.workspace.run_analysis,
shortcut=QKeySequence(Qt.Key.Key_F4),
icon=icon("run-analysis"),
),
MenuSeparator(),
MenuEntry(
"&Decompile",
main_window.decompile_current_function,
main_window.workspace.decompile_current_function,
shortcut=QKeySequence(Qt.Key.Key_F5),
icon=icon("pseudocode-view"),
),
MenuEntry(
"View in Proximity &Browser",
main_window.view_proximity_for_current_function,
main_window.workspace.view_proximity_for_current_function,
shortcut=QKeySequence("Ctrl+B"),
),
MenuEntry("&Interact", main_window.interact, shortcut=QKeySequence(Qt.Key.Key_F6)),
MenuEntry("&Interact", main_window.workspace.interact_program, shortcut=QKeySequence(Qt.Key.Key_F6)),
],
)
2 changes: 1 addition & 1 deletion angrmanagement/ui/menus/view_menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ def __init__(self, main_window: MainWindow) -> None:
),
MenuSeparator(),
MenuEntry("&Hex", main_window.workspace.show_hex_view, icon=icon("hex-view")),
MenuEntry("Pro&ximity", main_window.view_proximity_for_current_function),
MenuEntry("Pro&ximity", main_window.workspace.view_proximity_for_current_function),
MenuEntry("Pseudo&code", main_window.workspace.show_pseudocode_view, icon=icon("pseudocode-view")),
MenuEntry("&Strings", main_window.workspace.show_strings_view, icon=icon("strings-view")),
MenuEntry("&Patches", main_window.workspace.show_patches_view, icon=icon("patches-view")),
Expand Down
2 changes: 1 addition & 1 deletion angrmanagement/ui/views/disassembly_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -542,7 +542,7 @@ def popup_dependson_dialog(self, addr: int | None = None, use_operand: bool = Fa

if dependson.location is not None and dependson.arg is not None:
# track function argument
self.workspace._main_window.run_dependency_analysis(
self.workspace.run_dependency_analysis(
func_addr=addr,
func_arg_idx=dependson.arg,
)
Expand Down
4 changes: 1 addition & 3 deletions angrmanagement/ui/widgets/qccode_edit.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
from angrmanagement.ui.dialogs.xref import XRefDialog
from angrmanagement.ui.documents.qcodedocument import QCodeDocument
from angrmanagement.ui.menus.menu import Menu
from angrmanagement.ui.views.disassembly_view import DisassemblyView
from angrmanagement.ui.widgets.qccode_highlighter import FORMATS, QCCodeHighlighter

if TYPE_CHECKING:
Expand Down Expand Up @@ -309,7 +308,6 @@ def xref_node(self, *args, node=None) -> None: # pylint: disable=unused-argumen
if not isinstance(n, CVariable | CFunction | CFunctionCall):
return

disasm_view = self._code_view.workspace._get_or_create_view("disassembly", DisassemblyView)
if isinstance(n, CFunction | CFunctionCall):
addr = n.addr if isinstance(n, CFunction) else n.callee_func.addr
dialog = XRefDialog(
Expand All @@ -324,7 +322,7 @@ def xref_node(self, *args, node=None) -> None: # pylint: disable=unused-argumen
addr = self.get_closest_insaddr(n)
dialog = XRefDialog(
addr=addr,
variable_manager=disasm_view.variable_manager,
variable_manager=self.instance.project.kb.variables,
variable=n.variable,
instance=self.instance,
disassembly_view=self._code_view,
Expand Down
10 changes: 9 additions & 1 deletion angrmanagement/ui/workspace.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
PrototypeFindingJob,
VariableRecoveryJob,
)
from angrmanagement.data.jobs.dependency_analysis import DependencyAnalysisJob
from angrmanagement.data.jobs.loading import LoadBinaryJob
from angrmanagement.data.trace import BintraceTrace, Trace
from angrmanagement.logic.commands import CommandManager
Expand Down Expand Up @@ -607,6 +608,11 @@ def run_analysis(self, prompt_for_configuration: bool = True) -> None:

self.generate_cfg(cfg_options)

def run_dependency_analysis(self, func_addr: int | None = None, func_arg_idx: int | None = None) -> None:
self.job_manager.add_job(
DependencyAnalysisJob(self.main_instance, func_addr=func_addr, func_arg_idx=func_arg_idx)
)

def decompile_current_function(self) -> None:
current = self.view_manager.current_tab
if isinstance(current, CodeView):
Expand Down Expand Up @@ -741,7 +747,9 @@ def create_project_from_trace(self, trace: Trace, on_complete: Callable) -> None
job = LoadBinaryJob(self.main_instance, thing, load_options=load_options, on_finish=on_complete)
self.job_manager.add_job(job)

def interact_program(self, img_name: str, view=None) -> None:
def interact_program(self, img_name: str | None = None, view=None) -> None:
if img_name is None:
img_name = self.main_instance.img_name
if view is None or view.category != "interaction":
view = self._get_or_create_view("interaction", InteractionView)
view.initialize(img_name)
Expand Down
Loading