This repository has been archived by the owner on Jun 24, 2023. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathgef.py
221 lines (177 loc) · 6.17 KB
/
gef.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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
import copy
import inspect
from binaryninja import (
core_version,
log_info,
highlight,
)
from .constants import (
PAGE_SIZE,
DEBUG,
HL_NO_COLOR,
HL_BP_COLOR,
HL_CUR_INSN_COLOR,
)
from .helpers import (
info,
err,
dbg,
expose,
is_exposed,
ishex,
)
from xmlrpc.server import (
SimpleXMLRPCRequestHandler,
SimpleXMLRPCServer,
list_public_methods
)
class Gef:
"""
Top-level XMLPRC class where exposed methods are declared.
"""
def __init__(self, server, bv, *args, **kwargs):
self.server = server
self.view = bv
self.base = bv.entry_point & ~(PAGE_SIZE-1)
self._version = ("Binary Ninja", core_version())
self.__old_bps = set()
self.__breakpoints = set()
if "Breakpoints" in bv.tag_types:
tag_type = bv.tag_types["Breakpoints"]
else:
tag_type = bv.create_tag_type("Breakpoint", "🛑")
self.__bp_tag = bv.create_tag(tag_type, "GEF Breakpoint", True)
self.__current_instruction = 0
return
def _dispatch(self, method, params):
"""
Plugin dispatcher
"""
func = getattr(self, method)
if not is_exposed(func):
raise NotImplementedError('Method "%s" is not exposed' % method)
dbg("Executing %s(%s)" % (method, params))
return func(*params)
def _listMethods(self):
"""
Class method listing (required for introspection API).
"""
m = []
for x in list_public_methods(self):
if x.startswith("_"): continue
if not is_exposed( getattr(self, x) ): continue
m.append(x)
return m
def _methodHelp(self, method):
"""
Method help (required for introspection API).
"""
f = getattr(self, method)
return inspect.getdoc(f)
@expose
def shutdown(self):
""" shutdown() => None
Cleanly shutdown the XML-RPC service.
Example: binaryninja shutdown
"""
self.server.server_close()
log_info("[+] XMLRPC server stopped")
setattr(self.server, "shutdown", True)
return 0
@expose
def version(self):
""" version() => None
Return a tuple containing the tool used and its version
Example: binaryninja version
"""
return self._version
@expose
def jump(self, address):
""" jump(int addr) => None
Move the EA pointer to the address pointed by `addr`.
Example: binaryninja jump 0x4049de
"""
try:
addr = int(address, 0)
self.view.offset = addr
return True
except:
pass
return False
@expose
def makecomm(self, address, comment):
""" makecomm(int addr, string comment) => None
Add a comment at the location `address`.
Example: binaryninja makecomm 0x40000 "Important call here!"
"""
addr = int(address, 0)
start_addr = self.view.get_previous_function_start_before(addr)
func = self.view.get_function_at(start_addr)
return func.set_comment(addr, comment)
@expose
def setcolor(self, address, color='0xff0000'):
""" setcolor(int addr [, int color]) => None
Set the location pointed by `address` with `color`.
Example: binaryninja setcolor 0x40000 0xff0000
"""
addr = int(address, 0)
color = int(color, 0)
R,G,B = (color >> 16)&0xff, (color >> 8)&0xff, (color&0xff)
color = highlight.HighlightColor(red=R, blue=G, green=B)
return self.highlight(addr, color)
@expose
def sync(self, off, added, removed):
""" sync(off, added, removed) => None
Synchronize debug info with gef. This is an internal function. It is not recommended using it from the command line.
Example: binaryninja sync
"""
off = int(off, 0)
pc = self.base + off
dbg("current_pc=%#x , old_pc=%#x" % (pc, self.__current_instruction))
# unhighlight the _current_instruction
if self.__current_instruction > 0:
self.highlight(self.__current_instruction, HL_NO_COLOR)
self.highlight(pc, HL_CUR_INSN_COLOR)
# update the _current_instruction
self.__current_instruction = pc
self.jump(self.__current_instruction)
dbg("pre-gdb-add-breakpoints: %s" % (added,))
dbg("pre-gdb-del-breakpoints: %s" % (removed,))
dbg("pre-binja-breakpoints: %s" % (self.__breakpoints))
bn_added = [ x-self.base for x in self.__breakpoints if x not in self.__old_bps ]
bn_removed = [ x-self.base for x in self.__old_bps if x not in self.__breakpoints ]
for bp in added:
self.add_breakpoint(self.view, self.base + bp)
for bp in removed:
self.delete_breakpoint(self.view, self.base + bp)
self.__old_bps = copy.deepcopy(self.__breakpoints)
dbg("post-gdb-add-breakpoints: %s" % (bn_added,))
dbg("post-gdb-del-breakpoints: %s" % (bn_removed,))
dbg("post-binja-breakpoints: %s" % (self.__breakpoints,))
return [bn_added, bn_removed]
def highlight(self, addr, color):
dbg("hl(%#x, %s)" % (addr, color))
start_addr = self.view.get_previous_function_start_before(addr)
func = self.view.get_function_at(start_addr)
if func is None:
return
func.set_user_instr_highlight(addr, color)
return
def add_breakpoint(self, bv, addr):
if addr in self.__breakpoints:
return False
self.__breakpoints.add(addr)
info("Breakpoint {:#x} added".format(addr))
self.highlight(addr, HL_BP_COLOR)
self.view.add_user_data_tag(addr, self.__bp_tag)
return True
def delete_breakpoint(self, bv, addr):
if addr not in self.__breakpoints:
return False
self.__breakpoints.discard(addr)
info("Breakpoint {:#x} removed".format(addr))
self.highlight(addr, HL_NO_COLOR)
self.view.remove_user_data_tag(addr, self.__bp_tag)
return True
class BinjaGefRequestHandler(SimpleXMLRPCRequestHandler):
rpc_paths = ("/RPC2",)