-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathpyclassinformer_plugin.py
151 lines (117 loc) · 4.86 KB
/
pyclassinformer_plugin.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
import ida_idaapi
import ida_kernwin
import os
import sys
dirpath = os.path.dirname(os.path.abspath(__file__))
script_dir = os.path.join(dirpath, "pyclassinformer")
if not os.path.isdir(script_dir):
script_dir = os.path.join(dirpath, "..", "pyclassinformer")
ida_idaapi.require("pyclassinformer")
ida_idaapi.require("pyclassinformer.qtutils")
# for IDA 7.4 or earlier
try:
g_flags = ida_idaapi.PLUGIN_MULTI
except AttributeError:
g_flags = ida_idaapi.PLUGIN_DRAW
# for IDA 7.4 or earlier
try:
g_obj = ida_idaapi.plugmod_t
except AttributeError:
g_obj = object
g_plugmod_flag = False
if g_flags != ida_idaapi.PLUGIN_DRAW and g_obj != object:
g_plugmod_flag = True
class pci_plugin_t(ida_idaapi.plugin_t):
flags = g_flags
comment = "Yet Another RTTI Parser"
wanted_name = "PyClassInformer"
wanted_hotkey = "Alt-Shift-L"
help = "Press '" + wanted_hotkey + "' to display the " + wanted_name + " result."
toolbar_displayed_name = wanted_name
toolbar_name = toolbar_displayed_name + 'Toolbar'
action_name = "pyclassinformer:execute"
menu_path = "Edit/Plugins/"
icon_data = open(os.path.join(script_dir, "pci_icon.png"), "rb").read()
act_icon = ida_kernwin.load_custom_icon(data=icon_data, format="png")
class exec_pci_action(ida_kernwin.action_handler_t):
def __init__(self, plugin):
ida_kernwin.action_handler_t.__init__(self)
import weakref
self.v = weakref.ref(plugin)
def activate(self, ctx):
self.v().plugin_mod.run(None)
def update(self, ctx):
return ida_kernwin.AST_ENABLE_ALWAYS
def attach_to_menu_and_toolbar(self):
# insert the action
ida_kernwin.register_action(
ida_kernwin.action_desc_t(
self.action_name,
self.comment,
self.exec_pci_action(self),
None,
self.wanted_name,
self.act_icon))
# attach the action to menu
ida_kernwin.attach_action_to_menu(
self.menu_path,
self.action_name,
ida_kernwin.SETMENU_APP)
# create the toolbar and attach the action to the toolbar
ida_kernwin.create_toolbar(self.toolbar_name, self.toolbar_displayed_name)
ida_kernwin.attach_action_to_toolbar(self.toolbar_name, self.action_name)
# install ui hook to enable toolbar later
self.ph = pyclassinformer.qtutils.enable_toolbar_t(self.toolbar_name)
@staticmethod
class register_icon(ida_kernwin.UI_Hooks):
def updated_actions(self):
if ida_kernwin.update_action_icon(pci_plugin_t.menu_path + pci_plugin_t.wanted_name, pci_plugin_t.act_icon):
# unhook this if it's successful
self.unhook()
def init(self):
ida_kernwin.msg("############### %s (%s) ###############%s" % (self.wanted_name, self.comment, os.linesep))
ida_kernwin.msg("%s%s" % (self.help, os.linesep))
# attach action to menu and toolbar
self.attach_to_menu_and_toolbar()
r = self.flags
self.plugin_mod = pci_plugmod_t()
if g_plugmod_flag:
r = self.plugin_mod
return r
# for old IDA til 7.6
def run(self, arg):
self.plugin_mod.run(arg)
# for old IDA til 7.6
def term(self):
self.plugin_mod.term()
class pci_plugmod_t(g_obj):
toolbar_name = pci_plugin_t.toolbar_name
menu_path = pci_plugin_t.menu_path
action_name = pci_plugin_t.action_name
act_icon = pci_plugin_t.act_icon
def __del__(self):
self.term()
def run(self, arg):
pci_plugmod_t.run_pci(icon=self.act_icon)
def term(self):
self.detatch_from_menu_and_toolbar()
def detatch_from_menu_and_toolbar(self):
ida_kernwin.detach_action_from_toolbar(self.toolbar_name, self.action_name)
ida_kernwin.delete_toolbar(self.toolbar_name)
ida_kernwin.detach_action_from_menu(self.menu_path, self.action_name)
ida_kernwin.free_custom_icon(self.act_icon)
ida_kernwin.unregister_action(self.action_name)
@staticmethod
def run_pci(icon=-1):
ida_idaapi.require("pyclassinformer.pci_config_form")
config = pyclassinformer.pci_config_form.pci_form_t.show()
if config is not None:
ida_idaapi.require("pyclassinformer.pyclassinformer")
pyclassinformer.pyclassinformer.run_pci(config=config, icon=icon)
else:
print("PyClassInformer: Canceled")
def PLUGIN_ENTRY():
return pci_plugin_t()
# install a UI hook to add icon in the plugin menu
ri = pci_plugin_t.register_icon()
ri.hook()