-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsearch_from_ida.py
111 lines (86 loc) · 3.32 KB
/
search_from_ida.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
import os
import webbrowser
try: # Python 3
from urllib.parse import urlparse, quote
except ImportError: # Python 2
from urlparse import urlparse
from urllib import quote
import ida_idaapi
import ida_kernwin
QUERY_URL_FORMAT = 'https://google.com/search?q="{}"'
PLUGIN_NAME = ACTION_NAME = 'Search from IDA'
ACTION_LABEL_FORMAT = 'Search for "{}"'
ACTION_HOTKEY = 'Ctrl-Shift-Q'
ICONS_DIRECTORY_NAME = 'icons'
ICON_FILE_EXTENSION = '.png'
SUPPORTED_BUILTIN_WINDOWS = (ida_kernwin.BWN_DISASM, ida_kernwin.BWN_PSEUDOCODE)
def _get_highlight(widget):
highlight = ida_kernwin.get_highlight(widget)
if highlight:
return highlight[0]
else:
return ''
def _should_enable_action(widget):
if ida_kernwin.get_widget_type(widget) not in SUPPORTED_BUILTIN_WINDOWS:
return False
if not _get_highlight(widget):
return False
return True
class SearchHandler(ida_kernwin.action_handler_t):
def activate(self, ctx):
quoted_highlight = quote(_get_highlight(ctx.widget))
webbrowser.open_new_tab(QUERY_URL_FORMAT.format(quoted_highlight))
def update(self, ctx):
if _should_enable_action(ctx.widget):
return ida_kernwin.AST_ENABLE
else:
return ida_kernwin.AST_DISABLE
class ContextMenuHooks(ida_kernwin.UI_Hooks):
def finish_populating_widget_popup(self, widget, popup_handle):
if _should_enable_action(widget):
highlight = _get_highlight(widget)
ida_kernwin.update_action_label(ACTION_NAME, ACTION_LABEL_FORMAT.format(highlight))
ida_kernwin.attach_action_to_popup(widget, popup_handle, ACTION_NAME, None)
class SearchFromIda(ida_idaapi.plugin_t):
flags = ida_idaapi.PLUGIN_HIDE
comment = PLUGIN_NAME
help = ''
wanted_name = PLUGIN_NAME
wanted_hotkey = ''
_hooks = ContextMenuHooks()
@staticmethod
def _get_icon_path():
fqdn = urlparse(QUERY_URL_FORMAT).netloc
icon_filename = os.path.join(ICONS_DIRECTORY_NAME, fqdn + ICON_FILE_EXTENSION)
icon_path = os.path.join(os.path.dirname(__file__), icon_filename)
return icon_path
def _update_action_icon(self):
"""
If you think this function is awkward, you are not mistaken.
This helps circumventing certain bugs in the icons API.
"""
icon_path = self._get_icon_path()
if not os.path.exists(icon_path):
print('[{}] File {} does not exist.'.format(PLUGIN_NAME, icon_path))
self._action_icon = 0
else:
self._action_icon = ida_kernwin.load_custom_icon(icon_path)
if self._action_icon:
ida_kernwin.update_action_icon(ACTION_NAME, self._action_icon)
def init(self):
action_desc = ida_kernwin.action_desc_t(ACTION_NAME,
ACTION_NAME,
SearchHandler(),
ACTION_HOTKEY)
ida_kernwin.register_action(action_desc)
self._update_action_icon()
self._hooks.hook()
return ida_idaapi.PLUGIN_KEEP
def run(self):
pass
def term(self):
self._hooks.unhook()
if self._action_icon:
ida_kernwin.free_custom_icon(self._action_icon)
def PLUGIN_ENTRY():
return SearchFromIda()