import
idaapi
from
.hookers
import
global_hooker_manager
from
typing
import
Optional
class
ActionManager(
object
):
def
__init__(
self
):
self
.__actions
=
[]
def
register(
self
, action):
self
.__actions.append(action)
idaapi.register_action(
idaapi.action_desc_t(action.name, action.description, action, action.hotkey)
)
if
isinstance
(action, HexRaysPopupAction):
global_hooker_manager.register(HexRaysPopupRequestHandler(action))
def
initialize(
self
):
pass
def
finalize(
self
):
for
action
in
self
.__actions:
idaapi.unregister_action(action.name)
action_manager
=
ActionManager()
class
Action(idaapi.action_handler_t):
description: Optional[
str
]
=
None
hotkey: Optional[
str
]
=
None
def
__init__(
self
):
super
(Action,
self
).__init__()
@property
def
name(
self
):
return
"HexRaysPyTools:"
+
type
(
self
).__name__
def
activate(
self
, ctx: idaapi.action_ctx_base_t):
raise
NotImplementedError
def
update(
self
, ctx: idaapi.action_ctx_base_t):
raise
NotImplementedError
class
HexRaysPopupAction(Action):
def
__init__(
self
):
super
(HexRaysPopupAction,
self
).__init__()
def
activate(
self
, ctx: idaapi.action_ctx_base_t):
raise
NotImplementedError
def
check(
self
, hx_view):
raise
NotImplementedError
def
update(
self
, ctx: idaapi.action_ctx_base_t):
if
ctx.widget_type
=
=
idaapi.BWN_PSEUDOCODE:
return
idaapi.AST_ENABLE_FOR_WIDGET
return
idaapi.AST_DISABLE_FOR_WIDGET
class
HexRaysPopupRequestHandler(idaapi.Hexrays_Hooks):
def
__init__(
self
, action):
super
().__init__()
self
.__action
=
action
def
populating_popup(
self
, widget, popup_handle, vu):
if
self
.__action.check(vu):
idaapi.attach_action_to_popup(widget, popup_handle,
self
.__action.name,
None
)
return
0