Repository URL to install this package:
|
Version:
9.1~250226-1.fc41 ▾
|
import ida_idaapi
import ida_auto
import ida_loader
import ida_kernwin
dependencies_loaded = True
failed_dependency = []
try:
from feeds import env
from feeds.ui.view import FeedsView
from feeds.ui.controller import Manager
except ImportError as e:
dependencies_loaded = False # Set flag if a dependency fails
failed_dependency.append(e.name) # Store the name of the missing dependency
class Plugin(ida_idaapi.plugin_t):
flags = ida_idaapi.PLUGIN_FIX
comment = "Hex-Rays IDA Feeds Plugin"
help = "Massively Analyze Signatures"
wanted_name = "IDA Feeds"
wanted_hotkey = "Ctrl-Shift-F5"
def __init__(self):
super().__init__()
self.arg = None
self.form = None
self.hooks = None
self.popup_hooks = None
self.mgr = None
# Define the custom action
self.action_name = "my:ida_feeds_popup_action"
self.action_desc = ida_kernwin.action_desc_t(
self.action_name, # The internal action name
"Open IDA Feeds", # Label shown in the context menu
PopupActionHandler(self), # The action handler
None, # Shortcut (None if no shortcut)
"IDA Feeds Plugin", # Tooltip
-1 # Icon ID (-1 means no icon)
)
def init(self):
ida_kernwin.register_action(self.action_desc)
if self.popup_hooks is None:
self.popup_hooks = ActionPopupHooks()
self.popup_hooks.hook()
return ida_idaapi.PLUGIN_KEEP
def run(self, arg):
if not dependencies_loaded:
ida_kernwin.warning(f"IDA Feeds plugin cannot run due to missing dependencies: {failed_dependency}.")
return
if not ida_auto.auto_is_ok():
ida_kernwin.warning("IDA Feeds plugin cannot be launched until auto-analysis is complete. Please wait.")
return
if not ida_loader.get_path(ida_loader.PATH_TYPE_IDB):
ida_kernwin.warning("IDA Feeds plugin requires a binary to be loaded before launching. Please open a binary first.")
return
# Hook for handling the UI populating_widget_popup and undo/redo
try:
if self.mgr is None:
self.mgr = Manager(env.IDB_PATH)
self.mgr.populate_model()
if self.form is None:
self.form = PluginView(mgr=self.mgr)
if self.hooks is None:
self.hooks = PluginHooks(mgr=self.mgr, plugin_instance=self)
self.hooks.hook()
self.form.Show('IDA Feeds')
except Exception as e:
ida_kernwin.msg(f"IDA Feeds plugin, exception {e} trying to run plugin.")
def term(self):
try:
ida_kernwin.unregister_action(self.action_name)
if self.popup_hooks is not None:
self.popup_hooks.unhook()
self.popup_hooks = None
if self.hooks is not None:
self.hooks.unhook()
self.hooks = None
except Exception as e:
ida_kernwin.msg(f"IDA Feeds plugin, exception {e} trying to unhook hooks.")
self.hooks = None
self.mgr = None
self.form = None
def test(self):
pass
def PLUGIN_ENTRY():
return Plugin()
class PopupActionHandler(ida_kernwin.action_handler_t):
def __init__(self, plugin_instance):
ida_kernwin.action_handler_t.__init__(self)
self.plugin_instance = plugin_instance
def activate(self, ctx):
self.plugin_instance.run(self.plugin_instance.arg)
return 1
def update(self, ctx):
# Enable this action only if the context allows (always enabled for now)
return ida_kernwin.AST_ENABLE_ALWAYS
class ActionPopupHooks(ida_kernwin.UI_Hooks):
def __init__(self):
ida_kernwin.UI_Hooks.__init__(self)
def populating_widget_popup(self, widget, popup, ctx):
if ida_kernwin.get_widget_type(widget) == ida_kernwin.BWN_SIGNS:
# Attach the custom action to the context menu
ida_kernwin.attach_action_to_popup(widget, popup, "my:ida_feeds_popup_action", None, ida_kernwin.SETMENU_FIRST | ida_kernwin.SETMENU_ENSURE_SEP)
return super().populating_widget_popup(widget, popup, ctx)
def hook(self):
return ida_kernwin.UI_Hooks.hook(self)
def unhook(self):
return ida_kernwin.UI_Hooks.unhook(self)
class PluginHooks(ida_kernwin.UI_Hooks):
REFRESH_TIME = 500
def __init__(self, mgr, plugin_instance):
ida_kernwin.UI_Hooks.__init__(self)
self.idle_callback = None
self.mgr = mgr
self.plugin_instance = plugin_instance
def on_refresh_timer(self):
# ida_kernwin.is_refresh_requested(ida_kernwin.IWID_SIGNS) cannot be used,
# refresh flags may be reset by ida before running the callback;
if self.mgr is not None:
self.mgr.refresh_content()
return self.REFRESH_TIME
def database_inited(self, is_new_database, idc_script):
self.plugin_instance.mgr.clear_data()
self.plugin_instance.mgr.populate_model()
def widget_visible(self, widget):
if widget == self.plugin_instance.form.parent:
if self.idle_callback is None:
self.idle_callback = ida_kernwin.register_timer(self.REFRESH_TIME, self.on_refresh_timer)
def widget_closing(self, widget):
if widget == self.plugin_instance.form.parent:
if self.idle_callback is not None:
ida_kernwin.unregister_timer(self.idle_callback)
self.idle_callback = None
def hook(self):
return ida_kernwin.UI_Hooks.hook(self)
def unhook(self):
return ida_kernwin.UI_Hooks.unhook(self)
class PluginView(ida_kernwin.PluginForm):
WINDOW_TITLE = 'IDA Feeds'
def __init__(self, mgr):
super(PluginView, self).__init__()
self.parent = None
self.mgr = mgr
_temp_widget = ida_kernwin.create_empty_widget(self.WINDOW_TITLE)
self.temp_widget = ida_kernwin.PluginForm.TWidgetToPyQtWidget(_temp_widget)
def OnCreate(self, form):
self.parent = self.FormToPyQtWidget(form)
if self.mgr is not None:
self.parent.setLayout(self.mgr.view.layout)
self.mgr.refresh_content(force_refresh=True)
def OnClose(self, form):
if self.temp_widget is not None:
self.temp_widget.setLayout(self.mgr.view.layout)
def Show(self, caption):
ida_kernwin.PluginForm.Show(self, self.WINDOW_TITLE, options=ida_kernwin.PluginForm.WOPN_TAB)